- {:build_toolbar()}
+
+
{:__('Add')}
+
{:__('Edit')}
+
{:__('Delete')}
+
{:__('Import')}
+
+
\ No newline at end of file
diff --git a/application/admin/view/user/group/edit.html b/application/admin/view/user/group/edit.html
new file mode 100644
index 00000000..f11eb483
--- /dev/null
+++ b/application/admin/view/user/group/edit.html
@@ -0,0 +1,40 @@
+
+
diff --git a/application/admin/view/user/group/index.html b/application/admin/view/user/group/index.html
new file mode 100644
index 00000000..88c40619
--- /dev/null
+++ b/application/admin/view/user/group/index.html
@@ -0,0 +1,28 @@
+
+ {:build_heading()}
+
+
+
diff --git a/application/admin/view/user/rule/add.html b/application/admin/view/user/rule/add.html
new file mode 100644
index 00000000..9393e971
--- /dev/null
+++ b/application/admin/view/user/rule/add.html
@@ -0,0 +1,52 @@
+
diff --git a/application/admin/view/user/rule/edit.html b/application/admin/view/user/rule/edit.html
new file mode 100644
index 00000000..345b9672
--- /dev/null
+++ b/application/admin/view/user/rule/edit.html
@@ -0,0 +1,52 @@
+
diff --git a/application/admin/view/user/rule/index.html b/application/admin/view/user/rule/index.html
new file mode 100644
index 00000000..ed91b6ef
--- /dev/null
+++ b/application/admin/view/user/rule/index.html
@@ -0,0 +1,28 @@
+
+ {:build_heading()}
+
+
+
diff --git a/application/admin/view/user/user/edit.html b/application/admin/view/user/user/edit.html
new file mode 100644
index 00000000..a50ed2da
--- /dev/null
+++ b/application/admin/view/user/user/edit.html
@@ -0,0 +1,144 @@
+
diff --git a/application/admin/view/user/user/index.html b/application/admin/view/user/user/index.html
new file mode 100644
index 00000000..00308e8d
--- /dev/null
+++ b/application/admin/view/user/user/index.html
@@ -0,0 +1,28 @@
+
+ {:build_heading()}
+
+
+
diff --git a/application/api/controller/Common.php b/application/api/controller/Common.php
index cbdc33df..31d30e69 100644
--- a/application/api/controller/Common.php
+++ b/application/api/controller/Common.php
@@ -5,6 +5,7 @@ namespace app\api\controller;
use app\api\model\Area;
use app\common\controller\Api;
use fast\Version;
+use fast\Random;
use think\Config;
/**
@@ -13,7 +14,7 @@ use think\Config;
class Common extends Api
{
- protected $noNeedLogin = '*';
+ protected $noNeedLogin = ['init'];
protected $noNeedRight = '*';
public function _initialize()
@@ -24,8 +25,9 @@ class Common extends Api
/**
* 加载初始化
*
- * 必选参数:version
- * 可选参数:lng,lat
+ * @param string $version 版本号
+ * @param string $lng 经度
+ * @param string $lat 纬度
*/
public function init()
{
@@ -47,4 +49,94 @@ class Common extends Api
}
}
+ /**
+ * 上传文件
+ *
+ * @param File $file 文件流
+ */
+ public function upload()
+ {
+ $file = $this->request->file('file');
+ if (empty($file))
+ {
+ $this->error(__('No file upload or server upload limit exceeded'));
+ }
+
+ //判断是否已经存在附件
+ $sha1 = $file->hash();
+
+ $upload = Config::get('upload');
+
+ preg_match('/(\d+)(\w+)/', $upload['maxsize'], $matches);
+ $type = strtolower($matches[2]);
+ $typeDict = ['b' => 0, 'k' => 1, 'kb' => 1, 'm' => 2, 'mb' => 2, 'gb' => 3, 'g' => 3];
+ $size = (int) $upload['maxsize'] * pow(1024, isset($typeDict[$type]) ? $typeDict[$type] : 0);
+ $fileInfo = $file->getInfo();
+ $suffix = strtolower(pathinfo($fileInfo['name'], PATHINFO_EXTENSION));
+ $suffix = $suffix ? $suffix : 'file';
+
+ $mimetypeArr = explode(',', $upload['mimetype']);
+ $typeArr = explode('/', $fileInfo['type']);
+ //验证文件后缀
+ if ($upload['mimetype'] !== '*' && !in_array($suffix, $mimetypeArr) && !in_array($fileInfo['type'], $mimetypeArr) && !in_array($typeArr[0] . '/*', $mimetypeArr))
+ {
+ $this->error(__('Uploaded file format is limited'));
+ }
+ $replaceArr = [
+ '{year}' => date("Y"),
+ '{mon}' => date("m"),
+ '{day}' => date("d"),
+ '{hour}' => date("H"),
+ '{min}' => date("i"),
+ '{sec}' => date("s"),
+ '{random}' => Random::alnum(16),
+ '{random32}' => Random::alnum(32),
+ '{filename}' => $suffix ? substr($fileInfo['name'], 0, strripos($fileInfo['name'], '.')) : $fileInfo['name'],
+ '{suffix}' => $suffix,
+ '{.suffix}' => $suffix ? '.' . $suffix : '',
+ '{filemd5}' => md5_file($fileInfo['tmp_name']),
+ ];
+ $savekey = $upload['savekey'];
+ $savekey = str_replace(array_keys($replaceArr), array_values($replaceArr), $savekey);
+
+ $uploadDir = substr($savekey, 0, strripos($savekey, '/') + 1);
+ $fileName = substr($savekey, strripos($savekey, '/') + 1);
+ //
+ $splInfo = $file->validate(['size' => $size])->move(ROOT_PATH . '/public' . $uploadDir, $fileName);
+ if ($splInfo)
+ {
+ $imagewidth = $imageheight = 0;
+ if (in_array($suffix, ['gif', 'jpg', 'jpeg', 'bmp', 'png', 'swf']))
+ {
+ $imgInfo = getimagesize($splInfo->getPathname());
+ $imagewidth = isset($imgInfo[0]) ? $imgInfo[0] : $imagewidth;
+ $imageheight = isset($imgInfo[1]) ? $imgInfo[1] : $imageheight;
+ }
+ $params = array(
+ 'filesize' => $fileInfo['size'],
+ 'imagewidth' => $imagewidth,
+ 'imageheight' => $imageheight,
+ 'imagetype' => $suffix,
+ 'imageframes' => 0,
+ 'mimetype' => $fileInfo['type'],
+ 'url' => $uploadDir . $splInfo->getSaveName(),
+ 'uploadtime' => time(),
+ 'storage' => 'local',
+ 'sha1' => $sha1,
+ );
+ $attachment = model("attachment");
+ $attachment->data(array_filter($params));
+ $attachment->save();
+ \think\Hook::listen("upload_after", $attachment);
+ $this->success(__('Upload successful'), [
+ 'url' => $uploadDir . $splInfo->getSaveName()
+ ]);
+ }
+ else
+ {
+ // 上传失败获取错误信息
+ $this->error($file->getError());
+ }
+ }
+
}
diff --git a/application/api/controller/Demo.php b/application/api/controller/Demo.php
index 160fe58b..7af13512 100644
--- a/application/api/controller/Demo.php
+++ b/application/api/controller/Demo.php
@@ -22,8 +22,6 @@ class Demo extends Api
/**
* 无需登录的接口
*
- * 必选参数:无
- * 可选参数:无
*/
public function test1()
{
@@ -33,8 +31,6 @@ class Demo extends Api
/**
* 需要登录的接口
*
- * 必选参数:token
- * 可选参数:无
*/
public function test2()
{
@@ -44,8 +40,6 @@ class Demo extends Api
/**
* 需要登录且需要验证有相应组的权限
*
- * 必选参数:token
- * 可选参数:无
*/
public function test3()
{
diff --git a/application/api/controller/Index.php b/application/api/controller/Index.php
index ecc0fd96..0bc9d9af 100644
--- a/application/api/controller/Index.php
+++ b/application/api/controller/Index.php
@@ -16,8 +16,6 @@ class Index extends Api
/**
* 首页
*
- * 必选参数:无
- * 可选参数:lng,lat
*/
public function index()
{
diff --git a/application/api/controller/Sms.php b/application/api/controller/Sms.php
index 1be29b92..99c7deb4 100644
--- a/application/api/controller/Sms.php
+++ b/application/api/controller/Sms.php
@@ -23,35 +23,40 @@ class Sms extends Api
/**
* 发送验证码
*
- * 必选参数:mobile,type
- * 可选参数:无
+ * @param string $mobile 手机号
+ * @param string $event 事件名称
*/
public function send()
{
$mobile = $this->request->request("mobile");
- $type = $this->request->request("type");
- $type = $type ? $type : 'register';
+ $event = $this->request->request("event");
+ $event = $event ? $event : 'register';
- $last = Smslib::get($mobile, $type);
+ $last = Smslib::get($mobile, $event);
if ($last && time() - $last['createtime'] < 60)
{
$this->error(__('发送频繁'));
}
- if ($type)
+ if ($event)
{
$userinfo = User::getByMobile($mobile);
- if ($type == 'register' && $userinfo)
+ if ($event == 'register' && $userinfo)
{
//已被注册
$this->error(__('已被注册'));
}
- else if (in_array($type, ['changepwd', 'resetpwd']) && !$userinfo)
+ else if (in_array($event, ['changemobile']) && $userinfo)
+ {
+ //被占用
+ $this->error(__('已被占用'));
+ }
+ else if (in_array($event, ['changepwd', 'resetpwd']) && !$userinfo)
{
//未注册
$this->error(__('未注册'));
}
}
- $ret = Smslib::send($mobile, '', $type);
+ $ret = Smslib::send($mobile, NULL, $event);
if ($ret)
{
$this->success(__('发送成功'));
@@ -65,31 +70,37 @@ class Sms extends Api
/**
* 检测验证码
*
- * 必选参数:mobile,type,captcha
- * 可选参数:无
+ * @param string $mobile 手机号
+ * @param string $event 事件名称
+ * @param string $captcha 验证码
*/
public function check()
{
$mobile = $this->request->request("mobile");
- $type = $this->request->request("type");
- $type = $type ? $type : 'register';
+ $event = $this->request->request("event");
+ $event = $event ? $event : 'register';
$captcha = $this->request->request("captcha");
- if ($type)
+ if ($event)
{
$userinfo = User::getByMobile($mobile);
- if ($type == 'register' && $userinfo)
+ if ($event == 'register' && $userinfo)
{
//已被注册
$this->error(__('已被注册'));
}
- else if (in_array($type, ['changepwd', 'resetpwd']) && !$userinfo)
+ else if (in_array($event, ['changemobile']) && $userinfo)
+ {
+ //被占用
+ $this->error(__('已被占用'));
+ }
+ else if (in_array($event, ['changepwd', 'resetpwd']) && !$userinfo)
{
//未注册
$this->error(__('未注册'));
}
}
- $ret = Smslib::check($mobile, $captcha, $type);
+ $ret = Smslib::check($mobile, $captcha, $event);
if ($ret)
{
$this->success(__('成功'));
diff --git a/application/api/controller/User.php b/application/api/controller/User.php
new file mode 100644
index 00000000..b3a63451
--- /dev/null
+++ b/application/api/controller/User.php
@@ -0,0 +1,330 @@
+success('', ['welcome' => $this->auth->nickname]);
+ }
+
+ /**
+ * 会员登录
+ *
+ * @param string $account 账号
+ * @param string $password 密码
+ */
+ public function login()
+ {
+ $account = $this->request->request('account');
+ $password = $this->request->request('password');
+ if (!$account || !$password)
+ {
+ $this->error(__('Invalid parameters'));
+ }
+ $ret = $this->auth->login($account, $password);
+ if ($ret)
+ {
+ $data = ['userinfo' => $this->auth->getUserinfo()];
+ $this->success(__('Logged in successful'), $data);
+ }
+ else
+ {
+ $this->error($this->auth->getError());
+ }
+ }
+
+ /**
+ * 手机验证码登录
+ *
+ * @param string $mobile 手机号
+ * @param string $captcha 验证码
+ */
+ public function mobilelogin()
+ {
+ $mobile = $this->request->request('mobile');
+ $captcha = $this->request->request('captcha');
+ if (!$mobile || !$captcha)
+ {
+ $this->error(__('Invalid parameters'));
+ }
+ if (!Validate::regex($mobile, "^1\d{10}$"))
+ {
+ $this->error(__('Mobile incorrect'));
+ }
+ if (!Sms::check($mobile, $captcha, 'mobilelogin'))
+ {
+ $this->error(__('Captcha invalid'));
+ }
+ $user = \app\common\model\User::getByMobile($mobile);
+ if ($user)
+ {
+ //如果已经有账号则直接登录
+ $ret = $this->auth->direct($user->id);
+ }
+ else
+ {
+ $ret = $this->auth->register($mobile, Random::alnum(), '', $mobile, []);
+ }
+ if ($ret)
+ {
+ Sms::flush($mobile, 'mobilelogin');
+ $data = ['userinfo' => $this->auth->getUserinfo()];
+ $this->success(__('Logged in successful'), $data);
+ }
+ else
+ {
+ $this->error($this->auth->getError());
+ }
+ }
+
+ /**
+ * 注册会员
+ *
+ * @param string $username 用户名
+ * @param string $password 密码
+ * @param string $email 邮箱
+ * @param string $mobile 手机号
+ */
+ public function register()
+ {
+ $username = $this->request->request('username');
+ $password = $this->request->request('password');
+ $email = $this->request->request('email');
+ $mobile = $this->request->request('mobile');
+ if (!$username || !$password)
+ {
+ $this->error(__('Invalid parameters'));
+ }
+ if ($email && !Validate::is($email, "email"))
+ {
+ $this->error(__('Email incorrect'));
+ }
+ if ($mobile && !Validate::regex($mobile, "^1\d{10}$"))
+ {
+ $this->error(__('Mobile incorrect'));
+ }
+ $ret = $this->auth->register($username, $password, $email, $mobile, []);
+ if ($ret)
+ {
+ $data = ['userinfo' => $this->auth->getUserinfo()];
+ $this->success(__('Sign up successful'), $data);
+ }
+ else
+ {
+ $this->error($this->auth->getError());
+ }
+ }
+
+ /**
+ * 注销登录
+ */
+ public function logout()
+ {
+ $this->auth->logout();
+ $this->success(__('Logout successful'));
+ }
+
+ /**
+ * 修改会员个人信息
+ *
+ * @param string $avatar 头像地址
+ * @param string $username 用户名
+ * @param string $nickname 昵称
+ * @param string $bio 个人简介
+ */
+ public function profile()
+ {
+ $user = $this->auth->getUser();
+ $username = $this->request->request('username');
+ $nickname = $this->request->request('nickname');
+ $bio = $this->request->request('bio');
+ $avatar = $this->request->request('avatar');
+ $exists = \app\common\model\User::where('username', $username)->where('id', '<>', $this->auth->id)->find();
+ if ($exists)
+ {
+ $this->error(__('Username already exists'));
+ }
+ $user->username = $username;
+ $user->nickname = $nickname;
+ $user->bio = $bio;
+ $user->avatar = $avatar;
+ $user->save();
+ $this->success();
+ }
+
+ /**
+ * 修改邮箱
+ *
+ * @param string $email 邮箱
+ */
+ public function changeemail()
+ {
+ $user = $this->auth->getUser();
+ $email = $this->request->post('email');
+ if (!$email)
+ {
+ $this->error(__('Invalid parameters'));
+ }
+ if (!Validate::is($email, "email"))
+ {
+ $this->error(__('Mobile incorrect'));
+ }
+ if (\app\common\model\User::where('email', $email)->where('id', '<>', $user->id)->find())
+ {
+ $this->error(__('Email already exists'));
+ }
+ $verification = $user->verification;
+ $verification->email = 0;
+ $user->verification = $verification;
+ $user->email = $email;
+ $user->save();
+ $time = time();
+ $code = ['id' => $user->id, 'time' => $time, 'key' => md5(md5($user->id . $user->email . $time) . $user->salt)];
+ $code = base64_encode(http_build_query($code));
+ $url = url("index/user/activeemail", ['code' => $code], true, true);
+ $message = __('Verify email') . ":
{$url} ";
+ Email::instance()->to($email)->subject(__('Verify email'))->message($message)->send();
+ $this->success();
+ }
+
+ /**
+ * 修改手机号
+ *
+ * @param string $email 手机号
+ * @param string $captcha 验证码
+ */
+ public function changemobile()
+ {
+ $user = $this->auth->getUser();
+ $mobile = $this->request->request('mobile');
+ $captcha = $this->request->request('captcha');
+ if (!$mobile || !$captcha)
+ {
+ $this->error(__('Invalid parameters'));
+ }
+ if (!Validate::regex($mobile, "^1\d{10}$"))
+ {
+ $this->error(__('Mobile incorrect'));
+ }
+ if (\app\common\model\User::where('mobile', $mobile)->where('id', '<>', $user->id)->find())
+ {
+ $this->error(__('Mobile already exists'));
+ }
+ $result = Sms::check($mobile, $captcha, 'changemobile');
+ if (!$result)
+ {
+ $this->error(__('Captcha invalid'));
+ }
+ $verification = $user->verification;
+ $verification->mobile = 1;
+ $user->verification = $verification;
+ $user->mobile = $mobile;
+ $user->save();
+
+ Sms::flush($mobile, 'changemobile');
+ $this->success();
+ }
+
+ /**
+ * 第三方登录
+ *
+ * @param string $platform 平台名称
+ * @param string $code Code码
+ */
+ public function third()
+ {
+ $url = url('user/index');
+ $platform = $this->request->request("platform");
+ $code = $this->request->request("code");
+ $config = get_addon_config('third');
+ if (!$config || !isset($config[$platform]))
+ {
+ $this->error(__('Invalid parameters'));
+ }
+ $app = new \addons\third\library\Application($config);
+ //通过code换access_token和绑定会员
+ $result = $app->{$platform}->getUserInfo(['code' => $code]);
+ if ($result)
+ {
+ $loginret = \addons\third\library\Service::connect($platform, $result);
+ if ($loginret)
+ {
+ $data = [
+ 'userinfo' => $this->auth->getUserinfo(),
+ 'thirdinfo' => $result
+ ];
+ $this->success(__('Logged in successful'), $data);
+ }
+ }
+ $this->error(__('Operation failed'), $url);
+ }
+
+ /**
+ * 重置密码
+ *
+ * @param string $mobile 手机号
+ * @param string $newpassword 新密码
+ * @param string $captcha 验证码
+ */
+ public function resetpwd()
+ {
+ $mobile = $this->request->request("mobile");
+ $newpassword = $this->request->request("newpassword");
+ $captcha = $this->request->request("captcha");
+ if (!$mobile || !$newpassword || !$captcha)
+ {
+ $this->error(__('Invalid parameters'));
+ }
+ if ($mobile && !Validate::regex($mobile, "^1\d{10}$"))
+ {
+ $this->error(__('Mobile incorrect'));
+ }
+ $user = \app\common\model\User::getByMobile($mobile);
+ if (!$user)
+ {
+ $this->error(__('User not found'));
+ }
+ $ret = Sms::check($mobile, $captcha, 'resetpwd');
+ if (!$ret)
+ {
+ $this->error(__('Captcha invalid'));
+ }
+ Sms::flush($mobile, 'resetpwd');
+
+ //模拟一次登录
+ $this->auth->direct($user->id);
+ $ret = $this->auth->changepwd($newpassword, '', true);
+ if ($ret)
+ {
+ $this->success(__('Reset password successful'));
+ }
+ else
+ {
+ $this->error($this->auth->getError());
+ }
+ }
+
+}
diff --git a/application/api/controller/Validate.php b/application/api/controller/Validate.php
new file mode 100644
index 00000000..c8a7a017
--- /dev/null
+++ b/application/api/controller/Validate.php
@@ -0,0 +1,112 @@
+request->request('email');
+ $id = (int) $this->request->request('id');
+ $count = User::where('email', '=', $email)->where('id', '<>', $id)->count();
+ if ($count > 0)
+ {
+ $this->error(__('邮箱已经被占用'));
+ }
+ $this->success();
+ }
+
+ /**
+ * 检测用户名
+ *
+ * @param string $username 用户名
+ * @param string $id 会员ID
+ */
+ public function check_username_available()
+ {
+ $email = $this->request->request('username');
+ $id = (int) $this->request->request('id');
+ $count = User::where('username', '=', $email)->where('id', '<>', $id)->count();
+ if ($count > 0)
+ {
+ $this->error(__('用户名已经被占用'));
+ }
+ $this->success();
+ }
+
+ /**
+ * 检测手机
+ *
+ * @param string $mobile 手机号
+ * @param string $id 会员ID
+ */
+ public function check_mobile_available()
+ {
+ $email = $this->request->request('mobile');
+ $id = (int) $this->request->request('id');
+ $count = User::where('mobile', '=', $email)->where('id', '<>', $id)->count();
+ if ($count > 0)
+ {
+ $this->error(__('已经使用该手机号注册'));
+ }
+ $this->success();
+ }
+
+ /**
+ * 检测手机
+ *
+ * @param string $mobile 手机号
+ */
+ public function check_mobile_exist()
+ {
+ $email = $this->request->request('mobile');
+ $count = User::where('mobile', '=', $email)->count();
+ if (!$count)
+ {
+ $this->error(__('手机号不存在'));
+ }
+ $this->success();
+ }
+
+ /**
+ * 检测验证码
+ *
+ * @param string $mobile 手机号
+ * @param string $captcha 验证码
+ * @param string $event 事件
+ */
+ public function check_sms_correct()
+ {
+ $mobile = $this->request->request('mobile');
+ $captcha = $this->request->request('captcha');
+ $event = $this->request->request('event');
+ if (!\app\common\library\Sms::check($mobile, $captcha, $event))
+ {
+ $this->error(__('验证码不正确'));
+ }
+ $this->success();
+ }
+
+}
diff --git a/application/api/lang/zh-cn/common.php b/application/api/lang/zh-cn/common.php
new file mode 100644
index 00000000..fb78e7c1
--- /dev/null
+++ b/application/api/lang/zh-cn/common.php
@@ -0,0 +1,7 @@
+ '未上传文件或超出服务器上传限制',
+ 'Uploaded file format is limited' => '上传文件格式受限制',
+ 'Upload successful' => '上传成功',
+];
diff --git a/application/api/lang/zh-cn/user.php b/application/api/lang/zh-cn/user.php
new file mode 100644
index 00000000..db7fd11b
--- /dev/null
+++ b/application/api/lang/zh-cn/user.php
@@ -0,0 +1,40 @@
+ '会员中心',
+ 'Register' => '注册',
+ 'Login' => '登录',
+ 'Sign up successful' => '注册成功',
+ 'Username can not be empty' => '用户名不能为空',
+ 'Username must be 6 to 30 characters' => '用户名必须6-30个字符',
+ 'Password can not be empty' => '密码不能为空',
+ 'Password must be 6 to 30 characters' => '密码必须6-30个字符',
+ 'Email is incorrect' => '邮箱格式不正确',
+ 'Mobile is incorrect' => '手机格式不正确',
+ 'Username already exist' => '用户名已经存在',
+ 'Email already exist' => '邮箱已经存在',
+ 'Mobile already exist' => '手机号已经存在',
+ 'Username is incorrect' => '用户名不正确',
+ 'Email is incorrect' => '邮箱不正确',
+ 'Account is locked' => '账户已经被锁定',
+ 'Password is incorrect' => '密码不正确',
+ 'Account is incorrect' => '账户不正确',
+ 'Account not exist' => '账户不存在',
+ 'Account can not be empty' => '账户不能为空',
+ 'Username or password is incorrect' => '用户名或密码不正确',
+ 'You are not logged in' => '你当前还未登录',
+ 'You\'ve logged in, do not login again' => '你已经存在,请不要重复登录',
+ 'Profile' => '个人资料',
+ 'Verify email' => '邮箱验证',
+ 'Change password' => '修改密码',
+ 'Change password successful' => '修改密码成功',
+ 'Captcha is incorrect' => '验证码不正确',
+ 'Sign up successful' => '注册成功',
+ 'Logged in successful' => '登录成功',
+ 'Logout successful' => '注销成功',
+ 'Operation failed' => '操作失败',
+ 'Invalid parameters' => '参数不正确',
+ 'Change password failure' => '修改密码失败',
+ 'Change password successful' => '修改密码成功',
+ 'Reset password successful' => '重置密码成功',
+];
diff --git a/application/common/controller/Api.php b/application/common/controller/Api.php
index b2591417..b6dde880 100644
--- a/application/common/controller/Api.php
+++ b/application/common/controller/Api.php
@@ -47,7 +47,7 @@ class Api
* @var array
*/
protected $noNeedRight = [];
-
+
/**
* 权限Auth
* @var Auth
@@ -89,9 +89,9 @@ class Api
$modulename = $this->request->module();
$controllername = strtolower($this->request->controller());
$actionname = strtolower($this->request->action());
-
+
// token
- $token = $this->request->request('token');
+ $token = $this->request->request('token') ?: $this->request->cookie('token');
$path = str_replace('.', '/', $controllername) . '/' . $actionname;
// 设置当前请求的URI
diff --git a/application/common/library/Auth.php b/application/common/library/Auth.php
index f102ade7..b1259252 100644
--- a/application/common/library/Auth.php
+++ b/application/common/library/Auth.php
@@ -320,6 +320,8 @@ class Auth
$this->_token = Random::uuid();
Token::set($this->_token, $user->id);
+
+ $this->_logined = TRUE;
//登录成功的事件
Hook::listen("user_login_successed", $this->_user);
diff --git a/application/common/library/Email.php b/application/common/library/Email.php
index 39bd3023..0881e26e 100644
--- a/application/common/library/Email.php
+++ b/application/common/library/Email.php
@@ -127,12 +127,17 @@ class Email
/**
* 获取最后产生的错误
+ * @return string
*/
public function getError()
{
return $this->_error;
}
+ /**
+ * 设置错误
+ * @param string $error 信息信息
+ */
protected function setError($error)
{
$this->_error = $error;
diff --git a/application/common/library/Sms.php b/application/common/library/Sms.php
index ace4e25a..aa1e2c9f 100644
--- a/application/common/library/Sms.php
+++ b/application/common/library/Sms.php
@@ -2,9 +2,11 @@
namespace app\common\library;
-use addons\alisms\library\Alisms;
-use app\common\model\MobileCode;
+use think\Hook;
+/**
+ * 验证码类
+ */
class Sms
{
@@ -23,94 +25,89 @@ class Sms
/**
* 获取最后一次手机发送的数据
*
- * @param int $mobile 手机号
- * @param string $type 类型
- * @return array
+ * @param int $mobile 手机号
+ * @param string $event 事件
+ * @return Sms
*/
- public static function get($mobile, $type = 'default')
+ public static function get($mobile, $event = 'default')
{
- return MobileCode::
- where(['mobile' => $mobile, 'type' => $type])
- ->order('id', 'DESC')
- ->find();
+ $sms = \app\common\model\Sms::
+ where(['mobile' => $mobile, 'event' => $event])
+ ->order('id', 'DESC')
+ ->find();
+ $result = Hook::listen('sms_get', $sms);
+ return $result ? $result : NULL;
}
/**
* 发送验证码
*
- * @param int $mobile 手机号
- * @param int $code 验证码
- * @param string $type 类型
- * @return array
+ * @param int $mobile 手机号
+ * @param int $code 验证码,为空时将自动生成4位数字
+ * @param string $event 事件
+ * @return boolean
*/
- public static function send($mobile, $code = '', $type = 'default')
+ public static function send($mobile, $code = NULL, $event = 'default')
{
- $config = get_addon_config('alisms');
- $code = !$code ? mt_rand(1000, 9999) : $code;
- $alisms = new Alisms();
- $ret = $alisms->mobile($mobile)
- ->template($config['template'][$type])
- ->param(['code' => $code])
- ->send();
- if ($ret)
- {
- $time = time();
- MobileCode::create(['type' => $type, 'mobile' => $mobile, 'code' => $code, 'createtime' => $time]);
- return TRUE;
- }
- else
+ $code = is_null($code) ? mt_rand(1000, 9999) : $code;
+ $time = time();
+ $sms = \app\common\model\Sms::create(['event' => $event, 'mobile' => $mobile, 'code' => $code, 'createtime' => $time]);
+ $result = Hook::listen('sms_send', $sms);
+ if (!$result)
{
+ $sms->delete();
return FALSE;
}
+ return TRUE;
}
/**
* 发送通知
- * @param int $mobile 手机号
- * @param string $template 模板ID
+ *
* @param array $params 参数
* @return boolean
*/
- public static function notice($mobile, $template, $params = [])
+ public static function notice($params = [])
{
- $alisms = Alisms::instance();
- $ret = $alisms->mobile($mobile)
- ->template($template)
- ->param($params)
- ->send();
- return $ret ? TRUE : FALSE;
+ $result = Hook::listen('sms_notice', $params);
+ return $result ? TRUE : FALSE;
}
/**
* 校验验证码
*
- * @param int $mobile 手机号
- * @param int $code 验证码
- * @param string $type 类型
- * @return boolean
+ * @param int $mobile 手机号
+ * @param int $code 验证码
+ * @param string $event 事件
+ * @return boolean
*/
- public static function check($mobile, $code, $type = 'default')
+ public static function check($mobile, $code, $event = 'default')
{
$time = time() - self::$expire;
- $obj = MobileCode::where(['mobile' => $mobile, 'type' => $type])
+ $sms = \app\common\model\Sms::where(['mobile' => $mobile, 'event' => $event])
->order('id', 'DESC')
->find();
- if ($obj)
+ if ($sms)
{
- if ($obj['createtime'] > $time && $obj['times'] <= self::$maxCheckNums)
+ if ($sms['createtime'] > $time && $sms['times'] <= self::$maxCheckNums)
{
- $correct = $code == $obj['code'];
+ $correct = $code == $sms['code'];
if (!$correct)
{
- $obj->times = $obj->times + 1;
- $obj->save();
+ $sms->times = $sms->times + 1;
+ $sms->save();
+ return FALSE;
+ }
+ else
+ {
+ $result = Hook::listen('sms_check', $sms);
+ return $result;
}
- return $correct;
}
else
{
// 过期则清空该手机验证码
- self::flush($mobile, $type);
+ self::flush($mobile, $event);
return FALSE;
}
}
@@ -123,15 +120,16 @@ class Sms
/**
* 清空指定手机号验证码
*
- * @param int $mobile 手机号
- * @param string $type 类型
- * @return boolean
+ * @param int $mobile 手机号
+ * @param string $event 事件
+ * @return boolean
*/
- public static function flush($mobile, $type = 'default')
+ public static function flush($mobile, $event = 'default')
{
- MobileCode::
- where(['mobile' => $mobile, 'type' => $type])
+ \app\common\model\Sms::
+ where(['mobile' => $mobile, 'event' => $event])
->delete();
+ Hook::listen('sms_flush');
return TRUE;
}
diff --git a/application/common/library/Token.php b/application/common/library/Token.php
index 42b3f11b..d42679cf 100644
--- a/application/common/library/Token.php
+++ b/application/common/library/Token.php
@@ -10,20 +10,21 @@ class Token
/**
* 存储Token
- * @param string $token Token
- * @param int $user_id 会员ID
- * @param int $expire 过期时长,0表示无限,单位秒
+ * @param string $token Token
+ * @param int $user_id 会员ID
+ * @param int $expire 过期时长,0表示无限,单位秒
*/
public static function set($token, $user_id, $expire = 0)
{
$expiretime = $expire ? time() + $expire : 0;
\app\common\model\Token::create(['token' => $token, 'user_id' => $user_id, 'expiretime' => $expiretime]);
+ return TRUE;
}
/**
* 获取Token内的信息
- * @param string $token
- * @return array
+ * @param string $token
+ * @return array
*/
public static function get($token)
{
@@ -44,9 +45,9 @@ class Token
/**
* 判断Token是否可用
- * @param string $token Token
- * @param int $user_id 会员ID
- * @return boolean
+ * @param string $token Token
+ * @param int $user_id 会员ID
+ * @return boolean
*/
public static function check($token, $user_id)
{
@@ -56,8 +57,8 @@ class Token
/**
* 删除Token
- * @param string $token
- * @return boolean
+ * @param string $token
+ * @return boolean
*/
public static function delete($token)
{
@@ -72,8 +73,8 @@ class Token
/**
* 删除指定用户的所有Token
- * @param int $user_id
- * @return boolean
+ * @param int $user_id
+ * @return boolean
*/
public static function clear($user_id)
{
diff --git a/application/common/model/ScoreLog.php b/application/common/model/ScoreLog.php
new file mode 100644
index 00000000..63b5e864
--- /dev/null
+++ b/application/common/model/ScoreLog.php
@@ -0,0 +1,23 @@
+ 0, 'mobile' => 0], $value);
+ return (object) $value;
+ }
+
+ /**
+ * 设置验证字段
+ * @param mixed $value
+ * @return string
+ */
+ public function setVerificationAttr($value)
+ {
+ $value = is_object($value) || is_array($value) ? json_encode($value) : $value;
+ return $value;
+ }
+
+ /**
+ * 变更会员积分
+ * @param int $score 积分
+ * @param int $user_id 会员ID
+ * @param string $memo 备注
+ */
+ public static function score($score, $user_id, $memo)
+ {
+ $user = self::get($user_id);
+ if ($user)
+ {
+ $before = $user->score;
+ $after = $user->score + $score;
+ $level = self::nextlevel($after);
+ //更新会员信息
+ $user->save(['score' => $after, 'level' => $level]);
+ //写入日志
+ ScoreLog::create(['user_id' => $user_id, 'score' => $score, 'before' => $before, 'after' => $after, 'memo' => $memo]);
+ }
+ }
+
+ /**
+ * 根据积分获取等级
+ * @param int $score 积分
+ * @return int
+ */
+ public static function nextlevel($score = 0)
+ {
+ $lv = array(1 => 0, 2 => 30, 3 => 100, 4 => 500, 5 => 1000, 6 => 2000, 7 => 3000, 8 => 5000, 9 => 8000, 10 => 10000);
+ $level = 1;
+ foreach ($lv as $key => $value)
+ {
+ if ($score >= $value)
+ {
+ $level = $key;
+ }
+ }
+ return $level;
+ }
+
+}
diff --git a/application/common/model/UserGroup.php b/application/common/model/UserGroup.php
new file mode 100644
index 00000000..4646845d
--- /dev/null
+++ b/application/common/model/UserGroup.php
@@ -0,0 +1,21 @@
+ false,
//登录页默认背景图
'login_background' => "/assets/img/loginbg.jpg",
+ //自动检测更新
+ 'checkupdate' => false,
//版本号
- 'version' => '1.0.0.20180117_beta',
- 'api_url' => 'http://api.fastadmin.net',
+ 'version' => '1.0.0.20180119_beta',
+ 'api_url' => '//api.fastadmin.net',
],
];
diff --git a/application/index/controller/Ajax.php b/application/index/controller/Ajax.php
index 3c68fca4..c4e2e865 100644
--- a/application/index/controller/Ajax.php
+++ b/application/index/controller/Ajax.php
@@ -3,8 +3,6 @@
namespace app\index\controller;
use app\common\controller\Frontend;
-use fast\Random;
-use think\Config;
use think\Lang;
/**
@@ -31,94 +29,13 @@ class Ajax extends Frontend
$result = 'define(' . json_encode(Lang::get(), JSON_FORCE_OBJECT | JSON_UNESCAPED_UNICODE) . ');';
return $result;
}
-
+
/**
* 上传文件
*/
public function upload()
{
- Config::set('default_return_type', 'json');
- $file = $this->request->file('file');
- if (empty($file))
- {
- $this->error(__('No file upload or server upload limit exceeded'));
- }
-
- //判断是否已经存在附件
- $sha1 = $file->hash();
-
- $upload = Config::get('upload');
-
- preg_match('/(\d+)(\w+)/', $upload['maxsize'], $matches);
- $type = strtolower($matches[2]);
- $typeDict = ['b' => 0, 'k' => 1, 'kb' => 1, 'm' => 2, 'mb' => 2, 'gb' => 3, 'g' => 3];
- $size = (int) $upload['maxsize'] * pow(1024, isset($typeDict[$type]) ? $typeDict[$type] : 0);
- $fileInfo = $file->getInfo();
- $suffix = strtolower(pathinfo($fileInfo['name'], PATHINFO_EXTENSION));
- $suffix = $suffix ? $suffix : 'file';
-
- $mimetypeArr = explode(',', $upload['mimetype']);
- $typeArr = explode('/', $fileInfo['type']);
- //验证文件后缀
- if ($upload['mimetype'] !== '*' && !in_array($suffix, $mimetypeArr) && !in_array($fileInfo['type'], $mimetypeArr) && !in_array($typeArr[0] . '/*', $mimetypeArr))
- {
- $this->error(__('Uploaded file format is limited'));
- }
- $replaceArr = [
- '{year}' => date("Y"),
- '{mon}' => date("m"),
- '{day}' => date("d"),
- '{hour}' => date("H"),
- '{min}' => date("i"),
- '{sec}' => date("s"),
- '{random}' => Random::alnum(16),
- '{random32}' => Random::alnum(32),
- '{filename}' => $suffix ? substr($fileInfo['name'], 0, strripos($fileInfo['name'], '.')) : $fileInfo['name'],
- '{suffix}' => $suffix,
- '{.suffix}' => $suffix ? '.' . $suffix : '',
- '{filemd5}' => md5_file($fileInfo['tmp_name']),
- ];
- $savekey = $upload['savekey'];
- $savekey = str_replace(array_keys($replaceArr), array_values($replaceArr), $savekey);
-
- $uploadDir = substr($savekey, 0, strripos($savekey, '/') + 1);
- $fileName = substr($savekey, strripos($savekey, '/') + 1);
- //
- $splInfo = $file->validate(['size' => $size])->move(ROOT_PATH . '/public' . $uploadDir, $fileName);
- if ($splInfo)
- {
- $imagewidth = $imageheight = 0;
- if (in_array($suffix, ['gif', 'jpg', 'jpeg', 'bmp', 'png', 'swf']))
- {
- $imgInfo = getimagesize($splInfo->getPathname());
- $imagewidth = isset($imgInfo[0]) ? $imgInfo[0] : $imagewidth;
- $imageheight = isset($imgInfo[1]) ? $imgInfo[1] : $imageheight;
- }
- $params = array(
- 'filesize' => $fileInfo['size'],
- 'imagewidth' => $imagewidth,
- 'imageheight' => $imageheight,
- 'imagetype' => $suffix,
- 'imageframes' => 0,
- 'mimetype' => $fileInfo['type'],
- 'url' => $uploadDir . $splInfo->getSaveName(),
- 'uploadtime' => time(),
- 'storage' => 'local',
- 'sha1' => $sha1,
- );
- $attachment = model("attachment");
- $attachment->data(array_filter($params));
- $attachment->save();
- \think\Hook::listen("upload_after", $attachment);
- $this->success(__('Upload successful'), null, [
- 'url' => $uploadDir . $splInfo->getSaveName()
- ]);
- }
- else
- {
- // 上传失败获取错误信息
- $this->error($file->getError());
- }
+ return action('api/common/upload');
}
}
diff --git a/application/index/controller/User.php b/application/index/controller/User.php
new file mode 100644
index 00000000..6b5d49ce
--- /dev/null
+++ b/application/index/controller/User.php
@@ -0,0 +1,353 @@
+auth;
+
+ //监听注册登录注销的事件
+ Hook::add('user_login_successed', function($user) use($auth) {
+ Cookie::set('uid', $user->id);
+ Cookie::set('token', $auth->getToken());
+ });
+ Hook::add('user_register_successed', function($user) use($auth) {
+ Cookie::set('uid', $user->id);
+ Cookie::set('token', $auth->getToken());
+ });
+ Hook::add('user_delete_successed', function($user) use($auth) {
+ Cookie::delete('uid');
+ Cookie::delete('token');
+ });
+ Hook::add('user_logout_successed', function($user) use($auth) {
+ Cookie::delete('uid');
+ Cookie::delete('token');
+ });
+ }
+
+ /**
+ * 会员中心
+ */
+ public function index()
+ {
+ $this->view->assign('title', __('User center'));
+ return $this->view->fetch();
+ }
+
+ /**
+ * 注册会员
+ */
+ public function register()
+ {
+ $url = $this->request->request('url', url('user/index'));
+ if ($this->auth->id)
+ $this->success(__('You\'ve logged in, do not login again'), $url);
+ if ($this->request->isPost())
+ {
+ $username = $this->request->post('username');
+ $password = $this->request->post('password');
+ $email = $this->request->post('email');
+ $mobile = $this->request->post('mobile', '');
+ $captcha = $this->request->post('captcha');
+ $token = $this->request->post('__token__');
+ $rule = [
+ 'username' => 'require|length:3,30',
+ 'password' => 'require|length:6,30',
+ 'email' => 'require|email',
+ 'mobile' => 'regex:/^1\d{10}$/',
+ 'captcha' => 'require|captcha',
+ '__token__' => 'token',
+ ];
+
+ $msg = [
+ 'username.require' => 'Username can not be empty',
+ 'username.length' => 'Username must be 3 to 30 characters',
+ 'password.require' => 'Password can not be empty',
+ 'password.length' => 'Password must be 6 to 30 characters',
+ 'captcha.require' => 'Captcha can not be empty',
+ 'captcha.captcha' => 'Captcha is incorrect',
+ 'email' => 'Email is incorrect',
+ 'mobile' => 'Mobile is incorrect',
+ ];
+ $data = [
+ 'username' => $username,
+ 'password' => $password,
+ 'email' => $email,
+ 'mobile' => $mobile,
+ 'captcha' => $captcha,
+ '__token__' => $token,
+ ];
+ $validate = new Validate($rule, $msg);
+ $result = $validate->check($data);
+ if (!$result)
+ {
+ $this->error(__($validate->getError()));
+ }
+ if ($this->auth->register($username, $password, $email, $mobile))
+ {
+ $synchtml = '';
+ ////////////////同步到Ucenter////////////////
+ if (defined('UC_STATUS') && UC_STATUS)
+ {
+ $uc = new \addons\ucenter\library\client\Client();
+ $synchtml = $uc->uc_user_synregister($this->auth->id, $password);
+ }
+ $referer = Cookie::get('referer_url');
+ $this->success(__('Sign up successful') . $synchtml, $referer);
+ }
+ else
+ {
+ $this->error($this->auth->getError());
+ }
+ }
+ Session::set('redirect_url', $url);
+ $this->view->assign('title', __('Register'));
+ return $this->view->fetch();
+ }
+
+ /**
+ * 会员登录
+ */
+ public function login()
+ {
+ $url = $this->request->request('url', url('user/index'));
+ if ($this->auth->id)
+ $this->success(__('You\'ve logged in, do not login again'), $url);
+ if ($this->request->isPost())
+ {
+ $account = $this->request->post('account');
+ $password = $this->request->post('password');
+ $keeptime = (int) $this->request->post('keeptime');
+ $token = $this->request->post('__token__');
+ $rule = [
+ 'account' => 'require|length:3,50',
+ 'password' => 'require|length:6,30',
+ '__token__' => 'token',
+ ];
+
+ $msg = [
+ 'account.require' => 'Account can not be empty',
+ 'account.length' => 'Account must be 3 to 50 characters',
+ 'password.require' => 'Password can not be empty',
+ 'password.length' => 'Password must be 6 to 30 characters',
+ ];
+ $data = [
+ 'account' => $account,
+ 'password' => $password,
+ '__token__' => $token,
+ ];
+ $validate = new Validate($rule, $msg);
+ $result = $validate->check($data);
+ if (!$result)
+ {
+ $this->error(__($validate->getError()));
+ return FALSE;
+ }
+ if ($this->auth->login($account, $password, $keeptime))
+ {
+ $synchtml = '';
+ ////////////////同步到Ucenter////////////////
+ if (defined('UC_STATUS') && UC_STATUS)
+ {
+ $uc = new \addons\ucenter\library\client\Client();
+ $synchtml = $uc->uc_user_synlogin($this->auth->id);
+ }
+ $this->success(__('Logged in successful') . $synchtml, $url);
+ }
+ else
+ {
+ $this->error($this->auth->getError());
+ }
+ }
+ $this->view->assign('title', __('Login'));
+ return $this->view->fetch();
+ }
+
+ /**
+ * 注销登录
+ */
+ function logout()
+ {
+ //注销本站
+ $this->auth->logout();
+ $synchtml = '';
+ ////////////////同步到Ucenter////////////////
+ if (defined('UC_STATUS') && UC_STATUS)
+ {
+ $uc = new \addons\ucenter\library\client\Client();
+ $synchtml = $uc->uc_user_synlogout();
+ }
+ $this->success(__('Logout successful') . $synchtml, url('user/index'));
+ }
+
+ /**
+ * 第三方登录跳转和回调处理
+ */
+ public function third()
+ {
+ $url = url('user/index');
+ $action = $this->request->param('action');
+ $platform = $this->request->param('platform');
+ $config = get_addon_config('third');
+ if (!$config || !isset($config[$platform]))
+ {
+ $this->error(__('Invalid parameters'));
+ }
+ foreach ($config as $k => &$v)
+ {
+ $v['callback'] = url('user/third', ['action' => 'callback', 'platform' => $k], false, true);
+ }
+ unset($v);
+ $app = new \addons\third\library\Application($config);
+ if ($action == 'redirect')
+ {
+ // 跳转到登录授权页面
+ $this->redirect($app->{$platform}->getAuthorizeUrl());
+ }
+ else if ($action == 'callback')
+ {
+ // 授权成功后的回调
+ $result = $app->{$platform}->getUserInfo();
+ if ($result)
+ {
+ $loginret = \addons\third\library\Service::connect($platform, $result);
+ if ($loginret)
+ {
+ $synchtml = '';
+ ////////////////同步到Ucenter////////////////
+ if (defined('UC_STATUS') && UC_STATUS)
+ {
+ $uc = new \addons\ucenter\library\client\Client();
+ $synchtml = $uc->uc_user_synlogin($this->auth->id);
+ }
+ $this->success(__('Logged in successful') . $synchtml, $url);
+ }
+ }
+ $this->error(__('Operation failed'), $url);
+ }
+ else
+ {
+ $this->error(__('Invalid parameters'));
+ }
+ }
+
+ /**
+ * 个人信息
+ */
+ public function profile()
+ {
+ $this->view->assign('title', __('Profile'));
+ return $this->view->fetch();
+ }
+
+ /**
+ * 激活邮箱
+ */
+ public function activeemail()
+ {
+ $code = $this->request->request('code');
+ $code = base64_decode($code);
+ parse_str($code, $params);
+ if (!isset($params['id']) || !isset($params['time']) || !isset($params['key']))
+ {
+ $this->error(__('Invalid parameters'));
+ }
+ $user = \app\common\model\User::get($params['id']);
+ if (!$user)
+ {
+ $this->error(__('User not found'));
+ }
+ if ($user->verification->email)
+ {
+ $this->error(__('Email already activation'));
+ }
+ if ($key !== md5(md5($user->id . $user->email . $time) . $user->salt) || time() - $params['time'] > 1800)
+ {
+ $this->error(__('Secrity code already invalid'));
+ }
+ $verification = $user->verification;
+ $verification->email = 1;
+ $user->verification = $verification;
+ $user->save();
+ $this->success(__('Active email successful'), url('user/index'));
+ return;
+ }
+
+ /**
+ * 修改密码
+ */
+ public function changepwd()
+ {
+ if ($this->request->isPost())
+ {
+ $oldpassword = $this->request->post("oldpassword");
+ $newpassword = $this->request->post("newpassword");
+ $renewpassword = $this->request->post("renewpassword");
+ $token = $this->request->post('__token__');
+ $rule = [
+ 'oldpassword' => 'require|length:6,30',
+ 'newpassword' => 'require|length:6,30',
+ 'renewpassword' => 'require|length:6,30|confirm:newpassword',
+ '__token__' => 'token',
+ ];
+
+ $msg = [
+ ];
+ $data = [
+ 'oldpassword' => $oldpassword,
+ 'newpassword' => $newpassword,
+ 'renewpassword' => $renewpassword,
+ '__token__' => $token,
+ ];
+ $field = [
+ 'oldpassword' => __('Old password'),
+ 'newpassword' => __('New password'),
+ 'renewpassword' => __('Renew password')
+ ];
+ $validate = new Validate($rule, $msg, $field);
+ $result = $validate->check($data);
+ if (!$result)
+ {
+ $this->error(__($validate->getError()));
+ return FALSE;
+ }
+
+ $ret = $this->auth->changepwd($newpassword, $oldpassword);
+ if ($ret)
+ {
+ $synchtml = '';
+ ////////////////同步到Ucenter////////////////
+ if (defined('UC_STATUS') && UC_STATUS)
+ {
+ $uc = new \addons\ucenter\library\client\Client();
+ $synchtml = $uc->uc_user_synlogout();
+ }
+ $this->success(__('Reset password successful') . $synchtml, url('user/login'));
+ }
+ else
+ {
+ $this->error($this->auth->getError());
+ }
+ }
+ $this->view->assign('title', __('Change password'));
+ return $this->view->fetch();
+ }
+
+}
diff --git a/application/index/lang/zh-cn.php b/application/index/lang/zh-cn.php
index 69ff6cf1..fd4cb9ec 100644
--- a/application/index/lang/zh-cn.php
+++ b/application/index/lang/zh-cn.php
@@ -1,90 +1,112 @@
'保持会话',
- 'Sign in' => '登入',
- 'Username' => '用户名',
- 'User id' => '会员ID',
- 'Username' => '用户名',
- 'Nickname' => '昵称',
- 'Password' => '密码',
- 'Sign up' => '注 册',
- 'Sign in' => '登 录',
- 'Sign out' => '注 销',
- 'Keep login' => '保持会话',
- 'Guest' => '游客',
- 'Welcome' => '%s,你好!',
- 'Add' => '添加',
- 'Edit' => '编辑',
- 'Delete' => '删除',
- 'Move' => '移动',
- 'Name' => '名称',
- 'Status' => '状态',
- 'Weigh' => '权重',
- 'Operate' => '操作',
- 'Warning' => '温馨提示',
- 'Default' => '默认',
- 'Article' => '文章',
- 'Page' => '单页',
- 'OK' => '确定',
- 'Cancel' => '取消',
- 'Loading' => '加载中',
- 'More' => '更多',
- 'Normal' => '正常',
- 'Hidden' => '隐藏',
- 'Submit' => '提交',
- 'Reset' => '重置',
- 'Execute' => '执行',
- 'Close' => '关闭',
- 'Search' => '搜索',
- 'Refresh' => '刷新',
- 'First' => '首页',
- 'Previous' => '上一页',
- 'Next' => '下一页',
- 'Last' => '末页',
- 'None' => '无',
- 'Home' => '主页',
- 'Online' => '在线',
- 'Logout' => '注销',
- 'Profile' => '个人资料',
- 'Index' => '首页',
- 'Hot' => '热门',
- 'Recommend' => '推荐',
- 'Dashboard' => '控制台',
- 'Code' => '编号',
- 'Message' => '内容',
- 'Line' => '行号',
- 'File' => '文件',
- 'Menu' => '菜单',
- 'Name' => '名称',
- 'Weigh' => '权重',
- 'Type' => '类型',
- 'Title' => '标题',
- 'Content' => '内容',
- 'Status' => '状态',
- 'Operate' => '操作',
- 'Append' => '追加',
- 'Memo' => '备注',
- 'Parent' => '父级',
- 'Params' => '参数',
- 'Permission' => '权限',
- 'Advance search' => '高级搜索',
- 'Check all' => '选中全部',
- 'Expand all' => '展开全部',
- 'Begin time' => '开始时间',
- 'End time' => '结束时间',
- 'Create time' => '创建时间',
- 'Flag' => '标志',
- 'Redirect now' => '立即跳转',
- 'Operation completed' => '操作成功!',
- 'Operation failed' => '操作失败!',
- 'Unknown data format' => '未知的数据格式!',
- 'Network error' => '网络错误!',
- 'Advanced search' => '高级搜索',
- 'Invalid parameters' => '未知参数',
- 'No results were found' => '记录未找到',
- 'Parameter %s can not be empty' => '参数%s不能为空',
- 'You have no permission' => '你没有权限访问',
- 'An unexpected error occurred' => '发生了一个意外错误,程序猿正在紧急处理中',
- 'This page will be re-directed in %s seconds' => '页面将在 %s 秒后自动跳转',
+ 'Keep login' => '保持会话',
+ 'Forgot password' => '忘记密码?',
+ 'Sign in' => '登入',
+ 'Username' => '用户名',
+ 'User id' => '会员ID',
+ 'Username' => '用户名',
+ 'Nickname' => '昵称',
+ 'Password' => '密码',
+ 'Sign up' => '注 册',
+ 'Sign in' => '登 录',
+ 'Sign out' => '注 销',
+ 'Guest' => '游客',
+ 'Welcome' => '%s,你好!',
+ 'Add' => '添加',
+ 'Edit' => '编辑',
+ 'Delete' => '删除',
+ 'Move' => '移动',
+ 'Name' => '名称',
+ 'Status' => '状态',
+ 'Weigh' => '权重',
+ 'Operate' => '操作',
+ 'Warning' => '温馨提示',
+ 'Default' => '默认',
+ 'Article' => '文章',
+ 'Page' => '单页',
+ 'OK' => '确定',
+ 'Cancel' => '取消',
+ 'Loading' => '加载中',
+ 'More' => '更多',
+ 'Normal' => '正常',
+ 'Hidden' => '隐藏',
+ 'Submit' => '提交',
+ 'Reset' => '重置',
+ 'Execute' => '执行',
+ 'Close' => '关闭',
+ 'Search' => '搜索',
+ 'Refresh' => '刷新',
+ 'First' => '首页',
+ 'Previous' => '上一页',
+ 'Next' => '下一页',
+ 'Last' => '末页',
+ 'None' => '无',
+ 'Home' => '主页',
+ 'Online' => '在线',
+ 'Logout' => '注销',
+ 'Profile' => '个人资料',
+ 'Index' => '首页',
+ 'Hot' => '热门',
+ 'Recommend' => '推荐',
+ 'Dashboard' => '控制台',
+ 'Code' => '编号',
+ 'Message' => '内容',
+ 'Line' => '行号',
+ 'File' => '文件',
+ 'Menu' => '菜单',
+ 'Name' => '名称',
+ 'Weigh' => '权重',
+ 'Type' => '类型',
+ 'Title' => '标题',
+ 'Content' => '内容',
+ 'Status' => '状态',
+ 'Operate' => '操作',
+ 'Append' => '追加',
+ 'Memo' => '备注',
+ 'Parent' => '父级',
+ 'Params' => '参数',
+ 'Permission' => '权限',
+ 'Advance search' => '高级搜索',
+ 'Check all' => '选中全部',
+ 'Expand all' => '展开全部',
+ 'Begin time' => '开始时间',
+ 'End time' => '结束时间',
+ 'Create time' => '创建时间',
+ 'Flag' => '标志',
+ 'Gitee' => '码云',
+ 'Github' => 'Github',
+ 'QQ group' => 'QQ群',
+ 'Go to Dashboard' => '登录后台',
+ 'Contribution' => '为FastAdmin贡献代码!',
+ 'Copyrights' => '版权所有',
+ 'Responsive' => '响应式开发',
+ 'Languages' => '多语言',
+ 'Module' => '模块化开发',
+ 'Extension' => '自由可扩展',
+ 'Auth' => '权限管理',
+ 'The fastest framework based on ThinkPHP5 and Bootstrap' => '基于ThinkPHP5和Bootstrap的极速后台开发框架',
+ 'Features' => '功能特性',
+ 'Home' => '首页',
+ 'Store' => '插件市场',
+ 'Services' => '服务',
+ 'Download' => '下载',
+ 'Demo' => '演示',
+ 'Donation' => '捐赠',
+ 'Forum' => '社区',
+ 'Docs' => '文档',
+ 'Send verification code' => '发磅验证码',
+ 'Redirect now' => '立即跳转',
+ 'Operation completed' => '操作成功!',
+ 'Operation failed' => '操作失败!',
+ 'Unknown data format' => '未知的数据格式!',
+ 'Network error' => '网络错误!',
+ 'Advanced search' => '高级搜索',
+ 'Invalid parameters' => '未知参数',
+ 'No results were found' => '记录未找到',
+ 'Parameter %s can not be empty' => '参数%s不能为空',
+ 'You have no permission' => '你没有权限访问',
+ 'An unexpected error occurred' => '发生了一个意外错误,程序猿正在紧急处理中',
+ 'This page will be re-directed in %s seconds' => '页面将在 %s 秒后自动跳转',
];
diff --git a/application/index/lang/zh-cn/user.php b/application/index/lang/zh-cn/user.php
new file mode 100644
index 00000000..cda5d167
--- /dev/null
+++ b/application/index/lang/zh-cn/user.php
@@ -0,0 +1,59 @@
+ '会员中心',
+ 'Register' => '注册',
+ 'Login' => '登录',
+ 'Account' => '账号',
+ 'Mobile' => '手机号',
+ 'Email' => '邮箱',
+ 'Captcha' => '验证码',
+ 'Lv' => 'Lv',
+ 'Score' => '积分',
+ 'Day' => '天',
+ 'Intro' => '个人介绍',
+ 'Successions' => '连续登录',
+ 'Maxsuccessions' => '最长连续登录',
+ 'Logintime' => '登录时间',
+ 'Prevtime' => '最后登录',
+ 'Change' => '修改',
+ 'Click to edit' => '点击编辑',
+ 'Email/Mobile/Username' => '邮箱/手机/用户名',
+ 'Sign up successful' => '注册成功',
+ 'Email active successful' => '邮箱激活成功',
+ 'Username can not be empty' => '用户名不能为空',
+ 'Username must be 6 to 30 characters' => '用户名必须6-30个字符',
+ 'Password can not be empty' => '密码不能为空',
+ 'Password must be 6 to 30 characters' => '密码必须6-30个字符',
+ 'Email is incorrect' => '邮箱格式不正确',
+ 'Mobile is incorrect' => '手机格式不正确',
+ 'Username already exist' => '用户名已经存在',
+ 'Email already exist' => '邮箱已经存在',
+ 'Mobile already exist' => '手机号已经存在',
+ 'Username is incorrect' => '用户名不正确',
+ 'Email is incorrect' => '邮箱不正确',
+ 'Account is locked' => '账户已经被锁定',
+ 'Password is incorrect' => '密码不正确',
+ 'Account is incorrect' => '账户不正确',
+ 'Account not exist' => '账户不存在',
+ 'Account can not be empty' => '账户不能为空',
+ 'Username or password is incorrect' => '用户名或密码不正确',
+ 'You are not logged in' => '你当前还未登录',
+ 'You\'ve logged in, do not login again' => '你已经存在,请不要重复登录',
+ 'Profile' => '个人资料',
+ 'Old password' => '旧密码',
+ 'New password' => '新密码',
+ 'Renew password' => '确认新密码',
+ 'Change password' => '修改密码',
+ 'New email' => '新邮箱',
+ 'New mobile' => '新手机号',
+ 'Change password successful' => '修改密码成功',
+ 'Captcha is incorrect' => '验证码不正确',
+ 'Sign up successful' => '注册成功',
+ 'Logged in successful' => '登录成功',
+ 'Logout successful' => '注销成功',
+ 'Operation failed' => '操作失败',
+ 'Invalid parameters' => '参数不正确',
+ 'Change password failure' => '修改密码失败',
+ 'Change password successful' => '修改密码成功',
+];
diff --git a/application/index/view/common/meta.html b/application/index/view/common/meta.html
new file mode 100644
index 00000000..d75406ff
--- /dev/null
+++ b/application/index/view/common/meta.html
@@ -0,0 +1,27 @@
+
+
{$title|default=''} – {:__('The fastest framework based on ThinkPHP5 and Bootstrap')}
+
+
+
+{if isset($keywords)}
+
+{/if}
+{if isset($description)}
+
+{/if}
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/application/index/view/common/script.html b/application/index/view/common/script.html
new file mode 100644
index 00000000..060e0a40
--- /dev/null
+++ b/application/index/view/common/script.html
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/application/index/view/common/sidenav.html b/application/index/view/common/sidenav.html
new file mode 100644
index 00000000..d258d351
--- /dev/null
+++ b/application/index/view/common/sidenav.html
@@ -0,0 +1,9 @@
+
\ No newline at end of file
diff --git a/application/index/view/index/index.html b/application/index/view/index/index.html
index e75a11ee..a75f8527 100644
--- a/application/index/view/index/index.html
+++ b/application/index/view/index/index.html
@@ -9,7 +9,7 @@
-
FastAdmin - 基于ThinkPHP5和Bootstrap的极速后台开发框架
+
FastAdmin - {:__('The fastest framework based on ThinkPHP5 and Bootstrap')}
@@ -39,14 +39,14 @@
@@ -61,8 +61,8 @@
© 2017 FastAdmin. All Rights Reserved.