切换导航条
此项目
正在载入...
登录
何书鹏
/
recruit
·
提交
转到一个项目
GitLab
转到仪表盘
项目
活动
文件
提交
管道
0
构建
0
图表
里程碑
问题
0
合并请求
0
成员
标记
维基
派生
网络
创建新的问题
下载为
邮件补丁
差异文件
浏览文件
作者
Karson
7 years ago
提交
39ad7c97a282321a4b47bfca9624863ccbb11973
1 个父辈
2ecae60d
新增Token多种存储方式
新增fieldlist自定义模板功能 新增关闭会员中心接口 优化Token存储,采用加密存储方式
隐藏空白字符变更
内嵌
并排对比
正在显示
14 个修改的文件
包含
346 行增加
和
176 行删除
application/admin/controller/Index.php
application/admin/controller/general/Config.php
application/admin/view/general/config/index.html
application/common/library/Token.php
application/common/model/Token.php
application/config.php
application/index/controller/Index.php
application/index/controller/User.php
application/index/lang/zh-cn.php
application/index/lang/zh-cn/user.php
application/index/view/index/index.html
public/assets/js/require-backend.min.js
public/assets/js/require-form.js
public/install.php
application/admin/controller/Index.php
查看文件 @
39ad7c9
...
...
@@ -105,7 +105,8 @@ class Index extends Backend
{
$this
->
redirect
(
$url
);
}
$background
=
cdnurl
(
Config
::
get
(
'fastadmin.login_background'
));
$background
=
Config
::
get
(
'fastadmin.login_background'
);
$background
=
stripos
(
$background
,
'http'
)
===
0
?
$background
:
config
(
'site.cdnurl'
)
.
$background
;
$this
->
view
->
assign
(
'background'
,
$background
);
$this
->
view
->
assign
(
'title'
,
__
(
'Login'
));
Hook
::
listen
(
"login_init"
,
$this
->
request
);
...
...
application/admin/controller/general/Config.php
查看文件 @
39ad7c9
...
...
@@ -25,6 +25,9 @@ class Config extends Backend
$this
->
model
=
model
(
'Config'
);
}
/**
* 查看
*/
public
function
index
()
{
$siteList
=
[];
...
...
@@ -48,10 +51,6 @@ class Config extends Backend
{
$value
[
'value'
]
=
explode
(
','
,
$value
[
'value'
]);
}
if
(
$value
[
'type'
]
==
'array'
)
{
$value
[
'value'
]
=
(
array
)
json_decode
(
$value
[
'value'
],
TRUE
);
}
$value
[
'content'
]
=
json_decode
(
$value
[
'content'
],
TRUE
);
$siteList
[
$v
[
'group'
]][
'list'
][]
=
$value
;
}
...
...
@@ -119,6 +118,10 @@ class Config extends Backend
return
$this
->
view
->
fetch
();
}
/**
* 编辑
* @param null $ids
*/
public
function
edit
(
$ids
=
NULL
)
{
if
(
$this
->
request
->
isPost
())
...
...
application/admin/view/general/config/index.html
查看文件 @
39ad7c9
...
...
@@ -54,20 +54,13 @@
<textarea
name=
"row[{$item.name}]"
class=
"form-control editor"
data-rule=
"{$item.rule}"
rows=
"5"
data-tip=
"{$item.tip}"
{$
item
.
extend
}
>
{$item.value}
</textarea>
{/case}
{case array}
<dl
class=
"fieldlist"
rel=
"{$item.value|count}"
data-name=
"row[{$item.name}]"
>
<dl
class=
"fieldlist"
data-name=
"row[{$item.name}]"
>
<dd>
<ins>
{:__('Array key')}
</ins>
<ins>
{:__('Array value')}
</ins>
</dd>
{foreach $item.value as $key => $vo}
<dd
class=
"form-inline"
>
<input
type=
"text"
name=
"row[{$item.name}][field][{$key}]"
class=
"form-control"
value=
"{$key}"
size=
"10"
/>
<input
type=
"text"
name=
"row[{$item.name}][value][{$key}]"
class=
"form-control"
value=
"{$vo}"
size=
"40"
/>
<span
class=
"btn btn-sm btn-danger btn-remove"
><i
class=
"fa fa-times"
></i></span>
<span
class=
"btn btn-sm btn-primary btn-dragsort"
><i
class=
"fa fa-arrows"
></i></span>
</dd>
{/foreach}
<dd><a
href=
"javascript:;"
class=
"append btn btn-sm btn-success"
><i
class=
"fa fa-plus"
></i>
{:__('Append')}
</a></dd>
<dd><a
href=
"javascript:;"
class=
"btn btn-sm btn-success btn-append"
><i
class=
"fa fa-plus"
></i>
{:__('Append')}
</a></dd>
<textarea
name=
"row[{$item.name}]"
class=
"form-control hide"
cols=
"30"
rows=
"5"
>
{$item.value}
</textarea>
</dl>
{/case}
{case datetime}
...
...
application/common/library/Token.php
查看文件 @
39ad7c9
...
...
@@ -2,84 +2,158 @@
namespace
app\common\library
;
use
app\common\library\token\Driver
;
use
think\App
;
use
think\Config
;
use
think\Log
;
/**
* Token操作类
*/
class
Token
{
/**
* @var array Token的实例
*/
public
static
$instance
=
[];
/**
* @var object 操作句柄
*/
public
static
$handler
;
/**
* 存储Token
* @param string $token Token
* @param int $user_id 会员ID
* @param int $expire 过期时长,0表示无限,单位秒
* 连接Token驱动
* @access public
* @param array $options 配置数组
* @param bool|string $name Token连接标识 true 强制重新连接
* @return Driver
*/
public
static
function
set
(
$token
,
$user_id
,
$expire
=
0
)
public
static
function
connect
(
array
$options
=
[],
$name
=
false
)
{
$expiretime
=
$expire
?
time
()
+
$expire
:
0
;
\app\common\model\Token
::
create
([
'token'
=>
$token
,
'user_id'
=>
$user_id
,
'expiretime'
=>
$expiretime
]);
return
TRUE
;
$type
=
!
empty
(
$options
[
'type'
])
?
$options
[
'type'
]
:
'File'
;
if
(
false
===
$name
)
{
$name
=
md5
(
serialize
(
$options
));
}
if
(
true
===
$name
||
!
isset
(
self
::
$instance
[
$name
]))
{
$class
=
false
===
strpos
(
$type
,
'\\'
)
?
'\\app\\common\\library\\token\\driver\\'
.
ucwords
(
$type
)
:
$type
;
// 记录初始化信息
App
::
$debug
&&
Log
::
record
(
'[ TOKEN ] INIT '
.
$type
,
'info'
);
if
(
true
===
$name
)
{
return
new
$class
(
$options
);
}
self
::
$instance
[
$name
]
=
new
$class
(
$options
);
}
return
self
::
$instance
[
$name
];
}
/**
* 获取Token内的信息
* @param string $token
* @return array
* 自动初始化Token
* @access public
* @param array $options 配置数组
* @return Driver
*/
public
static
function
get
(
$token
)
public
static
function
init
(
array
$options
=
[]
)
{
$data
=
\app\common\model\Token
::
get
(
$token
);
if
(
$data
)
{
if
(
!
$data
[
'expiretime'
]
||
$data
[
'expiretime'
]
>
time
())
{
return
$data
;
}
else
{
self
::
delete
(
$token
);
if
(
is_null
(
self
::
$handler
))
{
if
(
empty
(
$options
)
&&
'complex'
==
Config
::
get
(
'token.type'
))
{
$default
=
Config
::
get
(
'token.default'
);
// 获取默认Token配置,并连接
$options
=
Config
::
get
(
'token.'
.
$default
[
'type'
])
?:
$default
;
}
elseif
(
empty
(
$options
))
{
$options
=
Config
::
get
(
'token'
);
}
self
::
$handler
=
self
::
connect
(
$options
);
}
return
[];
return
self
::
$handler
;
}
/**
* 判断Token是否可用(check别名)
* @access public
* @param string $token Token标识
* @return bool
*/
public
static
function
has
(
$token
,
$user_id
)
{
return
self
::
check
(
$token
,
$user_id
);
}
/**
* 判断Token是否可用
* @param string $token Token
* @param int $user_id 会员ID
* @return boolean
* @param string $token Token标识
* @return bool
*/
public
static
function
check
(
$token
,
$user_id
)
{
$data
=
self
::
get
(
$token
);
return
$data
&&
$data
[
'user_id'
]
==
$user_id
?
true
:
false
;
return
self
::
init
()
->
check
(
$token
,
$user_id
);
}
/**
* 读取Token
* @access public
* @param string $token Token标识
* @param mixed $default 默认值
* @return mixed
*/
public
static
function
get
(
$token
,
$default
=
false
)
{
return
self
::
init
()
->
get
(
$token
,
$default
);
}
/**
* 写入Token
* @access public
* @param string $token Token标识
* @param mixed $user_id 存储数据
* @param int|null $expire 有效时间 0为永久
* @return boolean
*/
public
static
function
set
(
$token
,
$user_id
,
$expire
=
null
)
{
return
self
::
init
()
->
set
(
$token
,
$user_id
,
$expire
);
}
/**
* 删除Token(delete别名)
* @access public
* @param string $token Token标识
* @return boolean
*/
public
static
function
rm
(
$token
)
{
return
self
::
delete
(
$token
);
}
/**
* 删除Token
* @param string $token
* @return boolean
* @param string $token 标签名
* @return bool
*/
public
static
function
delete
(
$token
)
{
$data
=
\app\common\model\Token
::
get
(
$token
);
if
(
$data
)
{
$data
->
delete
();
return
true
;
}
return
false
;
return
self
::
init
()
->
delete
(
$token
);
}
/**
* 删除指定用户的所有Token
* @param int $user_id
* @return boolean
* 清除Token
* @access public
* @param string $token Token标记
* @return boolean
*/
public
static
function
clear
(
$user_id
)
public
static
function
clear
(
$user_id
=
null
)
{
\app\common\model\Token
::
where
(
'user_id'
,
$user_id
)
->
delete
();
return
true
;
return
self
::
init
()
->
clear
(
$user_id
);
}
}
...
...
application/common/model/Token.php
已删除
100644 → 0
查看文件 @
2ecae60
<?php
namespace
app\common\model
;
use
think\Model
;
/**
* Token模型
*/
class
Token
Extends
Model
{
// 表名
protected
$name
=
'user_token'
;
// 开启自动写入时间戳字段
protected
$autoWriteTimestamp
=
'int'
;
// 定义时间戳字段名
protected
$createTime
=
'createtime'
;
protected
$updateTime
=
false
;
// 定义主键
protected
$pk
=
'token'
;
// 追加属性
protected
$append
=
[
'expires_in'
];
/**
* 获取Token剩余有效期
* @return int
*/
public
function
getExpiresInAttr
(
$value
,
$data
)
{
return
$data
[
'expiretime'
]
?
max
(
0
,
$data
[
'expiretime'
]
-
time
())
:
365
*
86400
;
}
}
application/config.php
查看文件 @
39ad7c9
...
...
@@ -242,8 +242,23 @@ return [
// 验证成功后是否重置
'reset'
=>
true
],
// +----------------------------------------------------------------------
// | Token设置
// +----------------------------------------------------------------------
'token'
=>
[
// 驱动方式
'type'
=>
'Redis'
,
// 缓存前缀
'key'
=>
'i3d6o32wo8fvs1fvdpwens'
,
// 加密方式
'hashalgo'
=>
'ripemd160'
,
// 缓存有效期 0表示永久缓存
'expire'
=>
0
,
],
//FastAdmin配置
'fastadmin'
=>
[
//是否开启前台会员中心
'usercenter'
=>
true
,
//登录验证码
'login_captcha'
=>
false
,
//是否同一账号同一时间只能在一个地方登录
...
...
@@ -253,7 +268,8 @@ return [
//自动检测更新
'checkupdate'
=>
false
,
//版本号
'version'
=>
'1.0.0.20180327_beta'
,
'version'
=>
'1.0.0.20180401_beta'
,
//API接口地址
'api_url'
=>
'https://api.fastadmin.net'
,
],
];
...
...
application/index/controller/Index.php
查看文件 @
39ad7c9
...
...
@@ -3,6 +3,7 @@
namespace
app\index\controller
;
use
app\common\controller\Frontend
;
use
app\common\library\Token
;
class
Index
extends
Frontend
{
...
...
application/index/controller/User.php
查看文件 @
39ad7c9
...
...
@@ -3,6 +3,7 @@
namespace
app\index\controller
;
use
app\common\controller\Frontend
;
use
think\Config
;
use
think\Cookie
;
use
think\Hook
;
use
think\Session
;
...
...
@@ -23,27 +24,30 @@ class User extends Frontend
parent
::
_initialize
();
$auth
=
$this
->
auth
;
if
(
!
Config
::
get
(
'fastadmin.usercenter'
))
{
$this
->
error
(
__
(
'User center already closed'
));
}
$ucenter
=
get_addon_info
(
'ucenter'
);
if
(
$ucenter
&&
$ucenter
[
'state'
])
{
if
(
$ucenter
&&
$ucenter
[
'state'
])
{
include
ADDON_PATH
.
'ucenter'
.
DS
.
'uc.php'
;
}
//监听注册登录注销的事件
Hook
::
add
(
'user_login_successed'
,
function
(
$user
)
use
(
$auth
)
{
Hook
::
add
(
'user_login_successed'
,
function
(
$user
)
use
(
$auth
)
{
$expire
=
input
(
'post.keeplogin'
)
?
30
*
86400
:
0
;
Cookie
::
set
(
'uid'
,
$user
->
id
,
$expire
);
Cookie
::
set
(
'token'
,
$auth
->
getToken
(),
$expire
);
});
Hook
::
add
(
'user_register_successed'
,
function
(
$user
)
use
(
$auth
)
{
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
)
{
Hook
::
add
(
'user_delete_successed'
,
function
(
$user
)
use
(
$auth
)
{
Cookie
::
delete
(
'uid'
);
Cookie
::
delete
(
'token'
);
});
Hook
::
add
(
'user_logout_successed'
,
function
(
$user
)
use
(
$auth
)
{
Hook
::
add
(
'user_logout_successed'
,
function
(
$user
)
use
(
$auth
)
{
Cookie
::
delete
(
'uid'
);
Cookie
::
delete
(
'token'
);
});
...
...
@@ -66,8 +70,7 @@ class User extends Frontend
$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
())
{
if
(
$this
->
request
->
isPost
())
{
$username
=
$this
->
request
->
post
(
'username'
);
$password
=
$this
->
request
->
post
(
'password'
);
$email
=
$this
->
request
->
post
(
'email'
);
...
...
@@ -103,23 +106,18 @@ class User extends Frontend
];
$validate
=
new
Validate
(
$rule
,
$msg
);
$result
=
$validate
->
check
(
$data
);
if
(
!
$result
)
{
if
(
!
$result
)
{
$this
->
error
(
__
(
$validate
->
getError
()));
}
if
(
$this
->
auth
->
register
(
$username
,
$password
,
$email
,
$mobile
))
{
if
(
$this
->
auth
->
register
(
$username
,
$password
,
$email
,
$mobile
))
{
$synchtml
=
''
;
////////////////同步到Ucenter////////////////
if
(
defined
(
'UC_STATUS'
)
&&
UC_STATUS
)
{
if
(
defined
(
'UC_STATUS'
)
&&
UC_STATUS
)
{
$uc
=
new
\addons\ucenter\library\client\Client
();
$synchtml
=
$uc
->
uc_user_synregister
(
$this
->
auth
->
id
,
$password
);
}
$this
->
success
(
__
(
'Sign up successful'
)
.
$synchtml
,
$url
);
}
else
{
}
else
{
$this
->
error
(
$this
->
auth
->
getError
());
}
}
...
...
@@ -136,11 +134,10 @@ class User extends Frontend
$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
())
{
if
(
$this
->
request
->
isPost
())
{
$account
=
$this
->
request
->
post
(
'account'
);
$password
=
$this
->
request
->
post
(
'password'
);
$keeplogin
=
(
int
)
$this
->
request
->
post
(
'keeplogin'
);
$keeplogin
=
(
int
)
$this
->
request
->
post
(
'keeplogin'
);
$token
=
$this
->
request
->
post
(
'__token__'
);
$rule
=
[
'account'
=>
'require|length:3,50'
,
...
...
@@ -161,24 +158,19 @@ class User extends Frontend
];
$validate
=
new
Validate
(
$rule
,
$msg
);
$result
=
$validate
->
check
(
$data
);
if
(
!
$result
)
{
if
(
!
$result
)
{
$this
->
error
(
__
(
$validate
->
getError
()));
return
FALSE
;
}
if
(
$this
->
auth
->
login
(
$account
,
$password
))
{
if
(
$this
->
auth
->
login
(
$account
,
$password
))
{
$synchtml
=
''
;
////////////////同步到Ucenter////////////////
if
(
defined
(
'UC_STATUS'
)
&&
UC_STATUS
)
{
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
{
}
else
{
$this
->
error
(
$this
->
auth
->
getError
());
}
}
...
...
@@ -195,8 +187,7 @@ class User extends Frontend
$this
->
auth
->
logout
();
$synchtml
=
''
;
////////////////同步到Ucenter////////////////
if
(
defined
(
'UC_STATUS'
)
&&
UC_STATUS
)
{
if
(
defined
(
'UC_STATUS'
)
&&
UC_STATUS
)
{
$uc
=
new
\addons\ucenter\library\client\Client
();
$synchtml
=
$uc
->
uc_user_synlogout
();
}
...
...
@@ -217,8 +208,7 @@ class User extends Frontend
*/
public
function
changepwd
()
{
if
(
$this
->
request
->
isPost
())
{
if
(
$this
->
request
->
isPost
())
{
$oldpassword
=
$this
->
request
->
post
(
"oldpassword"
);
$newpassword
=
$this
->
request
->
post
(
"newpassword"
);
$renewpassword
=
$this
->
request
->
post
(
"renewpassword"
);
...
...
@@ -245,26 +235,21 @@ class User extends Frontend
];
$validate
=
new
Validate
(
$rule
,
$msg
,
$field
);
$result
=
$validate
->
check
(
$data
);
if
(
!
$result
)
{
if
(
!
$result
)
{
$this
->
error
(
__
(
$validate
->
getError
()));
return
FALSE
;
}
$ret
=
$this
->
auth
->
changepwd
(
$newpassword
,
$oldpassword
);
if
(
$ret
)
{
if
(
$ret
)
{
$synchtml
=
''
;
////////////////同步到Ucenter////////////////
if
(
defined
(
'UC_STATUS'
)
&&
UC_STATUS
)
{
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
{
}
else
{
$this
->
error
(
$this
->
auth
->
getError
());
}
}
...
...
application/index/lang/zh-cn.php
查看文件 @
39ad7c9
...
...
@@ -81,6 +81,7 @@ return [
'Github'
=>
'Github'
,
'QQ group'
=>
'QQ群'
,
'Go to Dashboard'
=>
'登录后台'
,
'Go to Member center'
=>
'会员中心'
,
'Contribution'
=>
'为FastAdmin贡献代码!'
,
'Copyrights'
=>
'版权所有'
,
'Responsive'
=>
'响应式开发'
,
...
...
application/index/lang/zh-cn/user.php
查看文件 @
39ad7c9
...
...
@@ -59,6 +59,7 @@ return [
'Sign up successful'
=>
'注册成功'
,
'Logged in successful'
=>
'登录成功'
,
'Logout successful'
=>
'注销成功'
,
'User center already closed'
=>
'会员中心已经关闭'
,
'Operation failed'
=>
'操作失败'
,
'Invalid parameters'
=>
'参数不正确'
,
'Change password failure'
=>
'修改密码失败'
,
...
...
application/index/view/index/index.html
查看文件 @
39ad7c9
...
...
@@ -62,7 +62,8 @@
<div
class=
"header-content-inner"
>
<h1>
FastAdmin
</h1>
<h3>
{:__('The fastest framework based on ThinkPHP5 and Bootstrap')}
</h3>
<a
href=
"{:url('admin/index/login')}"
class=
"btn btn-outline btn-xl page-scroll"
>
{:__('Go to Dashboard')}
</a>
<a
href=
"{:url('admin/index/login')}"
class=
"btn btn-warning btn-xl page-scroll"
>
{:__('Go to Dashboard')}
</a>
<a
href=
"{:url('index/user/index')}"
class=
"btn btn-outline btn-xl page-scroll"
>
{:__('Go to Member center')}
</a>
</div>
</div>
</div>
...
...
public/assets/js/require-backend.min.js
查看文件 @
39ad7c9
...
...
@@ -11148,6 +11148,7 @@ define('validator',['validator-core', 'validator-lang'], function (Validator, un
define
(
'form'
,[
'jquery'
,
'bootstrap'
,
'upload'
,
'validator'
],
function
(
$
,
undefined
,
Upload
,
Validator
)
{
var
Form
=
{
config
:
{
fieldlisttpl
:
'<dd class="form-inline"><input type="text" name="<%=name%>[<%=index%>][key]" class="form-control" value="<%=row.key%>" size="10" /> <input type="text" name="<%=name%>[<%=index%>][value]" class="form-control" value="<%=row.value%>" size="40" /> <span class="btn btn-sm btn-danger btn-remove"><i class="fa fa-times"></i></span> <span class="btn btn-sm btn-primary btn-dragsort"><i class="fa fa-arrows"></i></span></dd>'
},
events
:
{
validator
:
function
(
form
,
success
,
error
,
submit
)
{
...
...
@@ -11173,7 +11174,7 @@ define('form',['jquery', 'bootstrap', 'upload', 'validator'], function ($, undef
},
target
:
function
(
input
)
{
var
$formitem
=
$
(
input
).
closest
(
'.form-group'
),
$msgbox
=
$formitem
.
find
(
'span.msg-box'
);
$msgbox
=
$formitem
.
find
(
'span.msg-box'
);
if
(
!
$msgbox
.
length
)
{
return
[];
}
...
...
@@ -11269,7 +11270,8 @@ define('form',['jquery', 'bootstrap', 'upload', 'validator'], function ($, undef
citypicker
:
function
(
form
)
{
//绑定城市远程插件
if
(
$
(
"[data-toggle='city-picker']"
,
form
).
size
()
>
0
)
{
require
([
'citypicker'
],
function
()
{});
require
([
'citypicker'
],
function
()
{
});
}
},
datetimepicker
:
function
(
form
)
{
...
...
@@ -11387,27 +11389,90 @@ define('form',['jquery', 'bootstrap', 'upload', 'validator'], function ($, undef
}
},
fieldlist
:
function
(
form
)
{
//绑定fieldlist
if
(
$
(
".fieldlist"
,
form
).
size
()
>
0
)
{
$
(
".fieldlist"
,
form
).
on
(
"click"
,
".append"
,
function
()
{
var
rel
=
parseInt
(
$
(
this
).
closest
(
"dl"
).
attr
(
"rel"
))
+
1
;
var
name
=
$
(
this
).
closest
(
"dl"
).
data
(
"name"
);
$
(
this
).
closest
(
"dl"
).
attr
(
"rel"
,
rel
);
$
(
'<dd class="form-inline"><input type="text" name="'
+
name
+
'[field]['
+
rel
+
']" class="form-control" value="" size="10" /> <input type="text" name="'
+
name
+
'[value]['
+
rel
+
']" class="form-control" value="" size="40" /> <span class="btn btn-sm btn-danger btn-remove"><i class="fa fa-times"></i></span> <span class="btn btn-sm btn-primary btn-dragsort"><i class="fa fa-arrows"></i></span></dd>'
).
insertBefore
(
$
(
this
).
parent
());
});
$
(
".fieldlist"
,
form
).
on
(
"click"
,
"dd .btn-remove"
,
function
()
{
$
(
this
).
parent
().
remove
();
});
//拖拽排序
require
([
'dragsort'
],
function
()
{
//绑定拖动排序
require
([
'dragsort'
,
'template'
],
function
(
undefined
,
Template
)
{
//刷新隐藏textarea的值
var
refresh
=
function
(
name
)
{
var
data
=
{};
var
textarea
=
$
(
"textarea[name='"
+
name
+
"']"
,
form
);
var
container
=
textarea
.
closest
(
"dl"
);
var
template
=
container
.
data
(
"template"
);
console
.
log
(
name
,
container
);
$
.
each
(
$
(
"input,select"
,
container
).
serializeArray
(),
function
(
i
,
j
)
{
var
reg
=
/
\[(\w
+
)\]\[(\w
+
)\]
$/g
;
var
match
=
reg
.
exec
(
j
.
name
);
if
(
!
match
)
return
true
;
match
[
1
]
=
"x"
+
parseInt
(
match
[
1
]);
if
(
typeof
data
[
match
[
1
]]
==
'undefined'
)
{
data
[
match
[
1
]]
=
{};
}
data
[
match
[
1
]][
match
[
2
]]
=
j
.
value
;
});
var
result
=
template
?
[]
:
{};
$
.
each
(
data
,
function
(
i
,
j
)
{
if
(
j
)
{
if
(
!
template
)
{
if
(
j
.
key
!=
''
)
{
result
[
j
.
key
]
=
j
.
value
;
}
}
else
{
result
.
push
(
j
);
}
}
});
textarea
.
val
(
JSON
.
stringify
(
result
));
};
//监听文本框改变事件
$
(
document
).
on
(
'change keyup'
,
".fieldlist input,.fieldlist textarea,.fieldlist select"
,
function
()
{
refresh
(
$
(
this
).
closest
(
"dl"
).
data
(
"name"
));
});
//追加控制
$
(
".fieldlist"
,
form
).
on
(
"click"
,
".btn-append"
,
function
(
e
,
row
)
{
var
container
=
$
(
this
).
closest
(
"dl"
);
var
index
=
container
.
data
(
"index"
);
var
name
=
container
.
data
(
"name"
);
var
template
=
container
.
data
(
"template"
);
var
data
=
container
.
data
();
index
=
index
?
parseInt
(
index
)
:
0
;
container
.
data
(
"index"
,
index
+
1
);
var
row
=
row
?
row
:
{};
var
vars
=
{
index
:
index
,
name
:
name
,
data
:
data
,
row
:
row
};
var
html
=
template
?
Template
(
template
,
vars
)
:
Template
.
render
(
Form
.
config
.
fieldlisttpl
,
vars
);
$
(
html
).
insertBefore
(
$
(
this
).
closest
(
"dd"
));
$
(
this
).
trigger
(
"fa.event.appendfieldlist"
,
$
(
this
).
closest
(
"dd"
).
prev
());
});
//移除控制
$
(
".fieldlist"
,
form
).
on
(
"click"
,
"dd .btn-remove"
,
function
()
{
var
container
=
$
(
this
).
closest
(
"dl"
);
$
(
this
).
closest
(
"dd"
).
remove
();
refresh
(
container
.
data
(
"name"
));
});
//拖拽排序
$
(
"dl.fieldlist"
,
form
).
dragsort
({
itemSelector
:
'dd'
,
dragSelector
:
".btn-dragsort"
,
dragSelector
:
".btn-
f
dragsort"
,
dragEnd
:
function
()
{
refresh
(
$
(
this
).
closest
(
"dl"
).
data
(
"name"
));
},
placeHolderTemplate
:
"<dd></dd>"
});
//渲染数据
$
(
".fieldlist"
,
form
).
each
(
function
()
{
var
container
=
this
;
var
textarea
=
$
(
"textarea[name='"
+
$
(
this
).
data
(
"name"
)
+
"']"
,
form
);
if
(
textarea
.
val
()
==
''
)
{
return
true
;
}
var
template
=
$
(
this
).
data
(
"template"
);
$
.
each
(
JSON
.
parse
(
textarea
.
val
()),
function
(
i
,
j
)
{
$
(
".btn-append"
,
container
).
trigger
(
'click'
,
template
?
j
:
{
key
:
i
,
value
:
j
});
});
});
});
}
},
...
...
public/assets/js/require-form.js
查看文件 @
39ad7c9
define
([
'jquery'
,
'bootstrap'
,
'upload'
,
'validator'
],
function
(
$
,
undefined
,
Upload
,
Validator
)
{
var
Form
=
{
config
:
{
fieldlisttpl
:
'<dd class="form-inline"><input type="text" name="<%=name%>[<%=index%>][key]" class="form-control" value="<%=row.key%>" size="10" /> <input type="text" name="<%=name%>[<%=index%>][value]" class="form-control" value="<%=row.value%>" size="40" /> <span class="btn btn-sm btn-danger btn-remove"><i class="fa fa-times"></i></span> <span class="btn btn-sm btn-primary btn-dragsort"><i class="fa fa-arrows"></i></span></dd>'
},
events
:
{
validator
:
function
(
form
,
success
,
error
,
submit
)
{
...
...
@@ -26,7 +27,7 @@ define(['jquery', 'bootstrap', 'upload', 'validator'], function ($, undefined, U
},
target
:
function
(
input
)
{
var
$formitem
=
$
(
input
).
closest
(
'.form-group'
),
$msgbox
=
$formitem
.
find
(
'span.msg-box'
);
$msgbox
=
$formitem
.
find
(
'span.msg-box'
);
if
(
!
$msgbox
.
length
)
{
return
[];
}
...
...
@@ -122,7 +123,8 @@ define(['jquery', 'bootstrap', 'upload', 'validator'], function ($, undefined, U
citypicker
:
function
(
form
)
{
//绑定城市远程插件
if
(
$
(
"[data-toggle='city-picker']"
,
form
).
size
()
>
0
)
{
require
([
'citypicker'
],
function
()
{});
require
([
'citypicker'
],
function
()
{
});
}
},
datetimepicker
:
function
(
form
)
{
...
...
@@ -240,27 +242,90 @@ define(['jquery', 'bootstrap', 'upload', 'validator'], function ($, undefined, U
}
},
fieldlist
:
function
(
form
)
{
//绑定fieldlist
if
(
$
(
".fieldlist"
,
form
).
size
()
>
0
)
{
$
(
".fieldlist"
,
form
).
on
(
"click"
,
".append"
,
function
()
{
var
rel
=
parseInt
(
$
(
this
).
closest
(
"dl"
).
attr
(
"rel"
))
+
1
;
var
name
=
$
(
this
).
closest
(
"dl"
).
data
(
"name"
);
$
(
this
).
closest
(
"dl"
).
attr
(
"rel"
,
rel
);
$
(
'<dd class="form-inline"><input type="text" name="'
+
name
+
'[field]['
+
rel
+
']" class="form-control" value="" size="10" /> <input type="text" name="'
+
name
+
'[value]['
+
rel
+
']" class="form-control" value="" size="40" /> <span class="btn btn-sm btn-danger btn-remove"><i class="fa fa-times"></i></span> <span class="btn btn-sm btn-primary btn-dragsort"><i class="fa fa-arrows"></i></span></dd>'
).
insertBefore
(
$
(
this
).
parent
());
});
$
(
".fieldlist"
,
form
).
on
(
"click"
,
"dd .btn-remove"
,
function
()
{
$
(
this
).
parent
().
remove
();
});
//拖拽排序
require
([
'dragsort'
],
function
()
{
//绑定拖动排序
require
([
'dragsort'
,
'template'
],
function
(
undefined
,
Template
)
{
//刷新隐藏textarea的值
var
refresh
=
function
(
name
)
{
var
data
=
{};
var
textarea
=
$
(
"textarea[name='"
+
name
+
"']"
,
form
);
var
container
=
textarea
.
closest
(
"dl"
);
var
template
=
container
.
data
(
"template"
);
console
.
log
(
name
,
container
);
$
.
each
(
$
(
"input,select"
,
container
).
serializeArray
(),
function
(
i
,
j
)
{
var
reg
=
/
\[(\w
+
)\]\[(\w
+
)\]
$/g
;
var
match
=
reg
.
exec
(
j
.
name
);
if
(
!
match
)
return
true
;
match
[
1
]
=
"x"
+
parseInt
(
match
[
1
]);
if
(
typeof
data
[
match
[
1
]]
==
'undefined'
)
{
data
[
match
[
1
]]
=
{};
}
data
[
match
[
1
]][
match
[
2
]]
=
j
.
value
;
});
var
result
=
template
?
[]
:
{};
$
.
each
(
data
,
function
(
i
,
j
)
{
if
(
j
)
{
if
(
!
template
)
{
if
(
j
.
key
!=
''
)
{
result
[
j
.
key
]
=
j
.
value
;
}
}
else
{
result
.
push
(
j
);
}
}
});
textarea
.
val
(
JSON
.
stringify
(
result
));
};
//监听文本框改变事件
$
(
document
).
on
(
'change keyup'
,
".fieldlist input,.fieldlist textarea,.fieldlist select"
,
function
()
{
refresh
(
$
(
this
).
closest
(
"dl"
).
data
(
"name"
));
});
//追加控制
$
(
".fieldlist"
,
form
).
on
(
"click"
,
".btn-append"
,
function
(
e
,
row
)
{
var
container
=
$
(
this
).
closest
(
"dl"
);
var
index
=
container
.
data
(
"index"
);
var
name
=
container
.
data
(
"name"
);
var
template
=
container
.
data
(
"template"
);
var
data
=
container
.
data
();
index
=
index
?
parseInt
(
index
)
:
0
;
container
.
data
(
"index"
,
index
+
1
);
var
row
=
row
?
row
:
{};
var
vars
=
{
index
:
index
,
name
:
name
,
data
:
data
,
row
:
row
};
var
html
=
template
?
Template
(
template
,
vars
)
:
Template
.
render
(
Form
.
config
.
fieldlisttpl
,
vars
);
$
(
html
).
insertBefore
(
$
(
this
).
closest
(
"dd"
));
$
(
this
).
trigger
(
"fa.event.appendfieldlist"
,
$
(
this
).
closest
(
"dd"
).
prev
());
});
//移除控制
$
(
".fieldlist"
,
form
).
on
(
"click"
,
"dd .btn-remove"
,
function
()
{
var
container
=
$
(
this
).
closest
(
"dl"
);
$
(
this
).
closest
(
"dd"
).
remove
();
refresh
(
container
.
data
(
"name"
));
});
//拖拽排序
$
(
"dl.fieldlist"
,
form
).
dragsort
({
itemSelector
:
'dd'
,
dragSelector
:
".btn-dragsort"
,
dragSelector
:
".btn-
f
dragsort"
,
dragEnd
:
function
()
{
refresh
(
$
(
this
).
closest
(
"dl"
).
data
(
"name"
));
},
placeHolderTemplate
:
"<dd></dd>"
});
//渲染数据
$
(
".fieldlist"
,
form
).
each
(
function
()
{
var
container
=
this
;
var
textarea
=
$
(
"textarea[name='"
+
$
(
this
).
data
(
"name"
)
+
"']"
,
form
);
if
(
textarea
.
val
()
==
''
)
{
return
true
;
}
var
template
=
$
(
this
).
data
(
"template"
);
$
.
each
(
JSON
.
parse
(
textarea
.
val
()),
function
(
i
,
j
)
{
$
(
".btn-append"
,
container
).
trigger
(
'click'
,
template
?
j
:
{
key
:
i
,
value
:
j
});
});
});
});
}
},
...
...
public/install.php
查看文件 @
39ad7c9
...
...
@@ -4,7 +4,7 @@
*
* 安装完成后建议删除此文件
* @author Karson
* @website http://www.fastadmin.net
* @website http
s
://www.fastadmin.net
*/
// error_reporting(E_ERROR | E_WARNING | E_PARSE | E_NOTICE);
// ini_set('display_errors', '1');
...
...
@@ -41,9 +41,9 @@ $sitename = "FastAdmin";
$link
=
array
(
'qqun'
=>
"https://jq.qq.com/?_wv=1027&k=487PNBb"
,
'gitee'
=>
'https://gitee.com/karson/fastadmin/attach_files'
,
'home'
=>
'http://www.fastadmin.net?ref=install'
,
'forum'
=>
'http://forum.fastadmin.net?ref=install'
,
'doc'
=>
'http://doc.fastadmin.net?ref=install'
,
'home'
=>
'https://www.fastadmin.net?ref=install'
,
'forum'
=>
'https://forum.fastadmin.net?ref=install'
,
'doc'
=>
'https://doc.fastadmin.net?ref=install'
,
);
// 检测目录是否存在
...
...
@@ -77,7 +77,7 @@ else if (!extension_loaded("PDO"))
}
else
if
(
!
is_really_writable
(
$dbConfigFile
))
{
$errInfo
=
'当前权限不足,无法写入配置文件application/database.php<br><a href="http://forum.fastadmin.net/?q=%E6%9D%83%E9%99%90%E4%B8%8D%E8%B6%B3" target="_blank">点击查看解决办法</a>'
;
$errInfo
=
'当前权限不足,无法写入配置文件application/database.php<br><a href="http
s
://forum.fastadmin.net/?q=%E6%9D%83%E9%99%90%E4%B8%8D%E8%B6%B3" target="_blank">点击查看解决办法</a>'
;
}
else
{
...
...
@@ -86,7 +86,7 @@ else
{
if
(
!
is_dir
(
ROOT_PATH
.
$v
))
{
$errInfo
=
'当前代码仅包含核心代码,请前往官网下载完整包或资源包覆盖后再尝试安装,<a href="http://www.fastadmin.net/download.html?ref=install" target="_blank">立即前往下载</a>'
;
$errInfo
=
'当前代码仅包含核心代码,请前往官网下载完整包或资源包覆盖后再尝试安装,<a href="http
s
://www.fastadmin.net/download.html?ref=install" target="_blank">立即前往下载</a>'
;
break
;
}
}
...
...
请
注册
或
登录
后发表评论