mirror of https://gitee.com/karson/fastadmin.git
新增附件记录上传会员和上传管理员ID
新增后台管理员admin_login_after和admin_logout_after的行为 新增tooltip和popover 优化和改版插件管理功能 优化多个Layer弹窗的切换体验 优化弹窗高度大于视察高度的操作体验 优化系统配置中发送测试邮件的逻辑 修复生成关联模型时未判断selectpage的BUG 修复表单前置返回失败未释放锁定的BUG 修复API文档生成时采用了GET方法的BUGpull/59/head v1.0.0.20180506_beta
parent
924e52b5e5
commit
e57171dea9
|
|
@ -33,6 +33,9 @@ class Addon extends Command
|
|||
{
|
||||
$name = $input->getOption('name') ?: '';
|
||||
$action = $input->getOption('action') ?: '';
|
||||
if(stripos($name, 'addons/')!==false){
|
||||
$name = explode('/', $name)[1];
|
||||
}
|
||||
//强制覆盖
|
||||
$force = $input->getOption('force');
|
||||
//版本
|
||||
|
|
@ -65,8 +68,8 @@ class Addon extends Command
|
|||
if (is_dir($addonDir)) {
|
||||
rmdirs($addonDir);
|
||||
}
|
||||
mkdir($addonDir);
|
||||
mkdir($addonDir . DS . 'controller');
|
||||
mkdir($addonDir, 0755, true);
|
||||
mkdir($addonDir . DS . 'controller', 0755, true);
|
||||
$menuList = \app\common\library\Menu::export($name);
|
||||
$createMenu = $this->getCreateMenu($menuList);
|
||||
$prefix = Config::get('database.prefix');
|
||||
|
|
|
|||
|
|
@ -437,8 +437,8 @@
|
|||
|
||||
$.ajax({
|
||||
url: $('#apiUrl').val() + url,
|
||||
data: $(form).attr('method') == 'get' ? $(form).serialize() : formData,
|
||||
type: $(form).attr('method') + '',
|
||||
data: $(form).prop('method').toLowerCase() == 'get' ? $(form).serialize() : formData,
|
||||
type: $(form).prop('method') + '',
|
||||
dataType: 'json',
|
||||
contentType: false,
|
||||
processData: false,
|
||||
|
|
|
|||
|
|
@ -1137,7 +1137,7 @@ EOD;
|
|||
$langField = mb_ucfirst($field);
|
||||
return <<<EOD
|
||||
<div class="form-group">
|
||||
<label for="c-{$field}" class="control-label col-xs-12 col-sm-2">{:__('{$langField}')}:</label>
|
||||
<label class="control-label col-xs-12 col-sm-2">{:__('{$langField}')}:</label>
|
||||
<div class="col-xs-12 col-sm-8">
|
||||
{$content}
|
||||
</div>
|
||||
|
|
@ -1149,7 +1149,7 @@ EOD;
|
|||
* 获取图片模板数据
|
||||
* @param string $field
|
||||
* @param string $content
|
||||
* @return array
|
||||
* @return string
|
||||
*/
|
||||
protected function getImageUpload($field, $content)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ class {%controllerName%} extends Backend
|
|||
|
||||
/**
|
||||
* {%modelName%}模型对象
|
||||
* @var \{%modelNamespace%}\{%modelName%}
|
||||
*/
|
||||
protected $model = null;
|
||||
|
||||
|
|
|
|||
|
|
@ -10,6 +10,11 @@
|
|||
$this->request->filter(['strip_tags']);
|
||||
if ($this->request->isAjax())
|
||||
{
|
||||
//如果发送的来源是Selectpage,则转发到Selectpage
|
||||
if ($this->request->request('keyField'))
|
||||
{
|
||||
return $this->selectpage();
|
||||
}
|
||||
list($where, $sort, $order, $offset, $limit) = $this->buildparams();
|
||||
$total = $this->model
|
||||
{%relationWithList%}
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ CREATE TABLE `fa_admin_log` (
|
|||
`id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID',
|
||||
`admin_id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '管理员ID',
|
||||
`username` varchar(30) NOT NULL DEFAULT '' COMMENT '管理员名字',
|
||||
`url` varchar(255) NOT NULL DEFAULT '' COMMENT '操作页面',
|
||||
`url` varchar(1500) NOT NULL DEFAULT '' COMMENT '操作页面',
|
||||
`title` varchar(100) NOT NULL DEFAULT '' COMMENT '日志标题',
|
||||
`content` text NOT NULL COMMENT '内容',
|
||||
`ip` varchar(50) NOT NULL DEFAULT '' COMMENT 'IP',
|
||||
|
|
@ -66,6 +66,8 @@ CREATE TABLE `fa_admin_log` (
|
|||
DROP TABLE IF EXISTS `fa_attachment`;
|
||||
CREATE TABLE `fa_attachment` (
|
||||
`id` int(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID',
|
||||
`admin_id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '管理员ID',
|
||||
`user_id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '会员ID',
|
||||
`url` varchar(255) NOT NULL DEFAULT '' COMMENT '物理路径',
|
||||
`imagewidth` varchar(30) NOT NULL DEFAULT '' COMMENT '宽度',
|
||||
`imageheight` varchar(30) NOT NULL DEFAULT '' COMMENT '高度',
|
||||
|
|
@ -77,7 +79,7 @@ CREATE TABLE `fa_attachment` (
|
|||
`createtime` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '创建日期',
|
||||
`updatetime` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '更新时间',
|
||||
`uploadtime` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '上传时间',
|
||||
`storage` enum('local','upyun','qiniu') NOT NULL DEFAULT 'local' COMMENT '存储位置',
|
||||
`storage` varchar(100) NOT NULL DEFAULT 'local' COMMENT '存储位置',
|
||||
`sha1` varchar(40) NOT NULL DEFAULT '' COMMENT '文件 sha1编码',
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='附件表';
|
||||
|
|
@ -86,7 +88,7 @@ CREATE TABLE `fa_attachment` (
|
|||
-- Records of fa_attachment
|
||||
-- ----------------------------
|
||||
BEGIN;
|
||||
INSERT INTO `fa_attachment` VALUES (1, '/assets/img/qrcode.png', '150', '150', 'png', 0, 21859, 'image/png', '', 1499681848, 1499681848, 1499681848, 'local', '17163603d0263e4838b9387ff2cd4877e8b018f6');
|
||||
INSERT INTO `fa_attachment` VALUES (1, 1, 0, '/assets/img/qrcode.png', '150', '150', 'png', 0, 21859, 'image/png', '', 1499681848, 1499681848, 1499681848, 'local', '17163603d0263e4838b9387ff2cd4877e8b018f6');
|
||||
COMMIT;
|
||||
|
||||
-- ----------------------------
|
||||
|
|
@ -344,7 +346,7 @@ DROP TABLE IF EXISTS `fa_ems`;
|
|||
CREATE TABLE `fa_ems` (
|
||||
`id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'ID',
|
||||
`event` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '事件',
|
||||
`email` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '邮箱',
|
||||
`email` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '邮箱',
|
||||
`code` varchar(10) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '验证码',
|
||||
`times` int(10) UNSIGNED NOT NULL DEFAULT 0 COMMENT '验证次数',
|
||||
`ip` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT 'IP',
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ class Addon extends Backend
|
|||
Service::refresh();
|
||||
$this->success();
|
||||
} catch (Exception $e) {
|
||||
$this->error($e->getMessage());
|
||||
$this->error(__($e->getMessage()));
|
||||
}
|
||||
}
|
||||
$this->error(__('Parameter %s can not be empty', ''));
|
||||
|
|
@ -112,9 +112,9 @@ class Addon extends Backend
|
|||
$info['state'] = 1;
|
||||
$this->success(__('Install successful'), null, ['addon' => $info]);
|
||||
} catch (AddonException $e) {
|
||||
$this->result($e->getData(), $e->getCode(), $e->getMessage());
|
||||
$this->result($e->getData(), $e->getCode(), __($e->getMessage()));
|
||||
} catch (Exception $e) {
|
||||
$this->error($e->getMessage(), $e->getCode());
|
||||
$this->error(__($e->getMessage()), $e->getCode());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -132,9 +132,9 @@ class Addon extends Backend
|
|||
Service::uninstall($name, $force);
|
||||
$this->success(__('Uninstall successful'));
|
||||
} catch (AddonException $e) {
|
||||
$this->result($e->getData(), $e->getCode(), $e->getMessage());
|
||||
$this->result($e->getData(), $e->getCode(), __($e->getMessage()));
|
||||
} catch (Exception $e) {
|
||||
$this->error($e->getMessage());
|
||||
$this->error(__($e->getMessage()));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -156,9 +156,9 @@ class Addon extends Backend
|
|||
Cache::rm('__menu__');
|
||||
$this->success(__('Operate successful'));
|
||||
} catch (AddonException $e) {
|
||||
$this->result($e->getData(), $e->getCode(), $e->getMessage());
|
||||
$this->result($e->getData(), $e->getCode(), __($e->getMessage()));
|
||||
} catch (Exception $e) {
|
||||
$this->error($e->getMessage());
|
||||
$this->error(__($e->getMessage()));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -222,16 +222,16 @@ class Addon extends Backend
|
|||
$this->success(__('Offline installed tips'), null, ['addon' => $info]);
|
||||
} catch (Exception $e) {
|
||||
@rmdirs($newAddonDir);
|
||||
throw new Exception($e->getMessage());
|
||||
throw new Exception(__($e->getMessage()));
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
@unlink($tmpFile);
|
||||
@rmdirs($tmpAddonDir);
|
||||
$this->error($e->getMessage());
|
||||
$this->error(__($e->getMessage()));
|
||||
}
|
||||
} else {
|
||||
// 上传失败获取错误信息
|
||||
$this->error($file->getError());
|
||||
$this->error(__($file->getError()));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -260,9 +260,9 @@ class Addon extends Backend
|
|||
Cache::rm('__menu__');
|
||||
$this->success(__('Operate successful'));
|
||||
} catch (AddonException $e) {
|
||||
$this->result($e->getData(), $e->getCode(), $e->getMessage());
|
||||
$this->result($e->getData(), $e->getCode(), __($e->getMessage()));
|
||||
} catch (Exception $e) {
|
||||
$this->error($e->getMessage());
|
||||
$this->error(__($e->getMessage()));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -297,7 +297,7 @@ class Addon extends Backend
|
|||
continue;
|
||||
|
||||
if (isset($onlineaddons[$v['name']])) {
|
||||
$v = array_merge($onlineaddons[$v['name']], $v);
|
||||
$v = array_merge($v, $onlineaddons[$v['name']]);
|
||||
} else {
|
||||
$v['category_id'] = 0;
|
||||
$v['flag'] = '';
|
||||
|
|
@ -306,6 +306,8 @@ class Addon extends Backend
|
|||
$v['donateimage'] = '';
|
||||
$v['demourl'] = '';
|
||||
$v['price'] = '0.00';
|
||||
$v['screenshots'] = [];
|
||||
$v['releaselist'] = [];
|
||||
}
|
||||
$v['url'] = addon_url($v['name']);
|
||||
$v['createtime'] = filemtime(ADDON_PATH . $v['name']);
|
||||
|
|
|
|||
|
|
@ -106,6 +106,8 @@ class Ajax extends Backend
|
|||
$imageheight = isset($imgInfo[1]) ? $imgInfo[1] : $imageheight;
|
||||
}
|
||||
$params = array(
|
||||
'admin_id' => (int)$this->auth->id,
|
||||
'user_id' => 0,
|
||||
'filesize' => $fileInfo['size'],
|
||||
'imagewidth' => $imagewidth,
|
||||
'imageheight' => $imageheight,
|
||||
|
|
|
|||
|
|
@ -90,6 +90,7 @@ class Index extends Backend
|
|||
$result = $this->auth->login($username, $password, $keeplogin ? 86400 : 0);
|
||||
if ($result === true)
|
||||
{
|
||||
Hook::listen("admin_login_after", $this->request);
|
||||
$this->success(__('Login successful'), $url, ['url' => $url, 'id' => $this->auth->id, 'username' => $username, 'avatar' => $this->auth->avatar]);
|
||||
}
|
||||
else
|
||||
|
|
@ -109,7 +110,7 @@ class Index extends Backend
|
|||
$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);
|
||||
Hook::listen("admin_login_init", $this->request);
|
||||
return $this->view->fetch();
|
||||
}
|
||||
|
||||
|
|
@ -119,6 +120,7 @@ class Index extends Backend
|
|||
public function logout()
|
||||
{
|
||||
$this->auth->logout();
|
||||
Hook::listen("admin_logout_after", $this->request);
|
||||
$this->success(__('Logout successful'), 'index/login');
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ use think\Exception;
|
|||
/**
|
||||
* 系统配置
|
||||
*
|
||||
* @icon fa fa-circle-o
|
||||
* @icon fa fa-cogs
|
||||
* @remark 可以在此增改系统的变量和分组,也可以自定义分组和变量,如果需要删除请从数据库中删除
|
||||
*/
|
||||
class Config extends Backend
|
||||
|
|
@ -32,31 +32,26 @@ class Config extends Backend
|
|||
{
|
||||
$siteList = [];
|
||||
$groupList = ConfigModel::getGroupList();
|
||||
foreach ($groupList as $k => $v)
|
||||
{
|
||||
foreach ($groupList as $k => $v) {
|
||||
$siteList[$k]['name'] = $k;
|
||||
$siteList[$k]['title'] = $v;
|
||||
$siteList[$k]['list'] = [];
|
||||
}
|
||||
|
||||
foreach ($this->model->all() as $k => $v)
|
||||
{
|
||||
if (!isset($siteList[$v['group']]))
|
||||
{
|
||||
foreach ($this->model->all() as $k => $v) {
|
||||
if (!isset($siteList[$v['group']])) {
|
||||
continue;
|
||||
}
|
||||
$value = $v->toArray();
|
||||
$value['title'] = __($value['title']);
|
||||
if (in_array($value['type'], ['select', 'selects', 'checkbox', 'radio']))
|
||||
{
|
||||
if (in_array($value['type'], ['select', 'selects', 'checkbox', 'radio'])) {
|
||||
$value['value'] = explode(',', $value['value']);
|
||||
}
|
||||
$value['content'] = json_decode($value['content'], TRUE);
|
||||
$siteList[$v['group']]['list'][] = $value;
|
||||
}
|
||||
$index = 0;
|
||||
foreach ($siteList as $k => &$v)
|
||||
{
|
||||
foreach ($siteList as $k => &$v) {
|
||||
$v['active'] = !$index ? true : false;
|
||||
$index++;
|
||||
}
|
||||
|
|
@ -71,45 +66,30 @@ class Config extends Backend
|
|||
*/
|
||||
public function add()
|
||||
{
|
||||
if ($this->request->isPost())
|
||||
{
|
||||
if ($this->request->isPost()) {
|
||||
$params = $this->request->post("row/a");
|
||||
if ($params)
|
||||
{
|
||||
foreach ($params as $k => &$v)
|
||||
{
|
||||
if ($params) {
|
||||
foreach ($params as $k => &$v) {
|
||||
$v = is_array($v) ? implode(',', $v) : $v;
|
||||
}
|
||||
try
|
||||
{
|
||||
if (in_array($params['type'], ['select', 'selects', 'checkbox', 'radio', 'array']))
|
||||
{
|
||||
try {
|
||||
if (in_array($params['type'], ['select', 'selects', 'checkbox', 'radio', 'array'])) {
|
||||
$params['content'] = json_encode(ConfigModel::decode($params['content']), JSON_UNESCAPED_UNICODE);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$params['content'] = '';
|
||||
}
|
||||
$result = $this->model->create($params);
|
||||
if ($result !== false)
|
||||
{
|
||||
try
|
||||
{
|
||||
if ($result !== false) {
|
||||
try {
|
||||
$this->refreshFile();
|
||||
$this->success();
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
} catch (Exception $e) {
|
||||
$this->error($e->getMessage());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$this->error($this->model->getError());
|
||||
}
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
} catch (Exception $e) {
|
||||
$this->error($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
|
@ -124,23 +104,16 @@ class Config extends Backend
|
|||
*/
|
||||
public function edit($ids = NULL)
|
||||
{
|
||||
if ($this->request->isPost())
|
||||
{
|
||||
if ($this->request->isPost()) {
|
||||
$row = $this->request->post("row/a");
|
||||
if ($row)
|
||||
{
|
||||
if ($row) {
|
||||
$configList = [];
|
||||
foreach ($this->model->all() as $v)
|
||||
{
|
||||
if (isset($row[$v['name']]))
|
||||
{
|
||||
foreach ($this->model->all() as $v) {
|
||||
if (isset($row[$v['name']])) {
|
||||
$value = $row[$v['name']];
|
||||
if (is_array($value) && isset($value['field']))
|
||||
{
|
||||
if (is_array($value) && isset($value['field'])) {
|
||||
$value = json_encode(ConfigModel::getArrayData($value), JSON_UNESCAPED_UNICODE);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$value = is_array($value) ? implode(',', $value) : $value;
|
||||
}
|
||||
$v['value'] = $value;
|
||||
|
|
@ -148,13 +121,10 @@ class Config extends Backend
|
|||
}
|
||||
}
|
||||
$this->model->allowField(true)->saveAll($configList);
|
||||
try
|
||||
{
|
||||
try {
|
||||
$this->refreshFile();
|
||||
$this->success();
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
} catch (Exception $e) {
|
||||
$this->error($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
|
@ -162,20 +132,20 @@ class Config extends Backend
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 刷新配置文件
|
||||
*/
|
||||
protected function refreshFile()
|
||||
{
|
||||
$config = [];
|
||||
foreach ($this->model->all() as $k => $v)
|
||||
{
|
||||
foreach ($this->model->all() as $k => $v) {
|
||||
|
||||
$value = $v->toArray();
|
||||
if (in_array($value['type'], ['selects', 'checkbox', 'images', 'files']))
|
||||
{
|
||||
if (in_array($value['type'], ['selects', 'checkbox', 'images', 'files'])) {
|
||||
$value['value'] = explode(',', $value['value']);
|
||||
}
|
||||
if ($value['type'] == 'array')
|
||||
{
|
||||
$value['value'] = (array) json_decode($value['value'], TRUE);
|
||||
if ($value['type'] == 'array') {
|
||||
$value['value'] = (array)json_decode($value['value'], TRUE);
|
||||
}
|
||||
$config[$value['name']] = $value['value'];
|
||||
}
|
||||
|
|
@ -183,26 +153,21 @@ class Config extends Backend
|
|||
}
|
||||
|
||||
/**
|
||||
* 检测配置项是否存在
|
||||
* @internal
|
||||
*/
|
||||
public function check()
|
||||
{
|
||||
$params = $this->request->post("row/a");
|
||||
if ($params)
|
||||
{
|
||||
if ($params) {
|
||||
|
||||
$config = $this->model->get($params);
|
||||
if (!$config)
|
||||
{
|
||||
if (!$config) {
|
||||
return $this->success();
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
return $this->error(__('Name already exist'));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
return $this->error(__('Invalid parameters'));
|
||||
}
|
||||
}
|
||||
|
|
@ -213,19 +178,18 @@ class Config extends Backend
|
|||
*/
|
||||
public function emailtest()
|
||||
{
|
||||
$row = $this->request->post('row/a');
|
||||
\think\Config::set('site', array_merge(\think\Config::get('site'), $row));
|
||||
$receiver = $this->request->request("receiver");
|
||||
$email = new Email;
|
||||
$result = $email
|
||||
->to($receiver)
|
||||
->subject(__("This is a test mail"))
|
||||
->message('<div style="min-height:550px; padding: 100px 55px 200px;">' . __('This is a test mail content') . '</div>')
|
||||
->send();
|
||||
if ($result)
|
||||
{
|
||||
->to($receiver)
|
||||
->subject(__("This is a test mail"))
|
||||
->message('<div style="min-height:550px; padding: 100px 55px 200px;">' . __('This is a test mail content') . '</div>')
|
||||
->send();
|
||||
if ($result) {
|
||||
$this->success();
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$this->error($email->getError());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -53,8 +53,7 @@ class User extends Backend
|
|||
->select();
|
||||
foreach ($list as $k => $v)
|
||||
{
|
||||
$v->password = '';
|
||||
$v->salt = '';
|
||||
$v->hidden(['password', 'salt']);
|
||||
}
|
||||
$result = array("total" => $total, "rows" => $list);
|
||||
|
||||
|
|
|
|||
|
|
@ -34,7 +34,6 @@ return [
|
|||
'Cancel' => '取消',
|
||||
'Clear' => '清空',
|
||||
'Custom Range' => '自定义',
|
||||
'Cancel' => '取消',
|
||||
'Today' => '今天',
|
||||
'Yesterday' => '昨天',
|
||||
'Last 7 days' => '最近7天',
|
||||
|
|
@ -78,13 +77,9 @@ return [
|
|||
'Line' => '行号',
|
||||
'File' => '文件',
|
||||
'Menu' => '菜单',
|
||||
'Name' => '名称',
|
||||
'Weigh' => '权重',
|
||||
'Type' => '类型',
|
||||
'Title' => '标题',
|
||||
'Content' => '内容',
|
||||
'Status' => '状态',
|
||||
'Operate' => '操作',
|
||||
'Append' => '追加',
|
||||
'Select' => '选择',
|
||||
'Memo' => '备注',
|
||||
|
|
@ -115,6 +110,7 @@ return [
|
|||
//提示
|
||||
'Go back' => '返回首页',
|
||||
'Jump now' => '立即跳转',
|
||||
'Click to search %s' => '点击搜索 %s',
|
||||
'Operation completed' => '操作成功!',
|
||||
'Operation failed' => '操作失败!',
|
||||
'Unknown data format' => '未知的数据格式!',
|
||||
|
|
@ -147,7 +143,7 @@ return [
|
|||
'Admin' => '管理员管理',
|
||||
'Admin log' => '管理员日志',
|
||||
'Group' => '角色组',
|
||||
'Rule' => '规则管理',
|
||||
'Rule' => '菜单规则',
|
||||
'User' => '会员管理',
|
||||
'User group' => '会员分组',
|
||||
'User rule' => '会员规则',
|
||||
|
|
|
|||
|
|
@ -2,13 +2,14 @@
|
|||
|
||||
return [
|
||||
'Id' => 'ID',
|
||||
'Title' => '标题',
|
||||
'Title' => '插件名称',
|
||||
'Value' => '配置值',
|
||||
'Array key' => '键',
|
||||
'Array value' => '值',
|
||||
'File' => '文件',
|
||||
'Donate' => '打赏作者',
|
||||
'Warmtips' => '温馨提示',
|
||||
'Pay now' => '立即支付',
|
||||
'Offline install' => '离线安装',
|
||||
'Refresh addon cache' => '刷新插件缓存',
|
||||
'Userinfo' => '会员信息',
|
||||
|
|
@ -17,38 +18,47 @@ return [
|
|||
'Conflict tips' => '此插件中发现和现有系统中部分文件发现冲突!以下文件将会被影响,请备份好相关文件后再继续操作',
|
||||
'Login tips' => '此处登录账号为<a href="https://www.fastadmin.net" target="_blank">FastAdmin官网账号</a>',
|
||||
'Logined tips' => '你好!%s<br />当前你已经登录,将同步保存你的购买记录',
|
||||
'Pay tips' => '支付完成后请稍等1~5分钟后再尝试安装,请不要重复支付,如果仍然无法安装,请加<a href="https://jq.qq.com/?_wv=1027&k=487PNBb" target="_blank">QQ群:636393962</a>向管理员反馈',
|
||||
'Pay tips' => '扫码支付后如果仍然无法立即下载,请不要重复支付,请加<a href="https://jq.qq.com/?_wv=1027&k=487PNBb" target="_blank">QQ群:636393962</a>向管理员反馈',
|
||||
'Pay click tips' => '请点击这里在新窗口中进行支付!',
|
||||
'Pay new window tips' => '请在新弹出的窗口中进行支付,支付完成后再重新点击安装按钮进行安装!',
|
||||
'Uninstall tips' => '确认卸载插件?<p class="text-danger">卸载将会删除所有插件文件且不可找回!!! 插件如果有创建数据库表请手动删除!!!</p>如有重要数据请备份后再操作!',
|
||||
'Upgrade tips' => '确认升级插件?<p class="text-danger">如果之前购买插件时未登录,此次升级可能出现购买后才可以下载的提示!!!<br>升级后可能出现部分冗余数据记录,请根据需要移除即可!!!</p>如有重要数据请备份后再操作!',
|
||||
'Offline installed tips' => '插件安装成功!清除插件缓存和框架缓存后生效!',
|
||||
'Online installed tips' => '插件安装成功!清除插件缓存和框架缓存后生效!',
|
||||
'Offline installed tips' => '插件安装成功!清除浏览器缓存和框架缓存后生效!',
|
||||
'Online installed tips' => '插件安装成功!清除浏览器缓存和框架缓存后生效!',
|
||||
'Not login tips' => '你当前未登录FastAdmin,登录后将同步已购买的记录,下载时无需二次付费!',
|
||||
'Not installed tips' => '请安装后再访问插件前台页面!',
|
||||
'Not enabled tips' => '插件已经禁用,请启用后再访问插件前台页面!',
|
||||
'Please disable addon first' => '请先禁用插件再进行升级',
|
||||
'Login now' => '立即登录',
|
||||
'Continue install' => '不登录,继续安装',
|
||||
'View addon home page' => '查看插件介绍和帮助',
|
||||
'View addon index page' => '查看插件前台首页',
|
||||
'View addon screenshots' => '点击查看插件截图',
|
||||
'Click to toggle status' => '点击切换插件状态',
|
||||
'Click to contact developer' => '点击与插件开发者取得联系',
|
||||
'Index' => '前台',
|
||||
'All' => '全部',
|
||||
'Uncategoried' => '未归类',
|
||||
'Recommend' => '推荐',
|
||||
'Hot' => '热门',
|
||||
'New' => '新',
|
||||
'Paying' => '付费',
|
||||
'Free' => '免费',
|
||||
'Sale' => '折扣',
|
||||
'No image' => '暂无缩略图',
|
||||
'Price' => '价格',
|
||||
'Downloads' => '下载',
|
||||
'Author' => '作者',
|
||||
'Identify' => '标识',
|
||||
'Homepage' => '主页',
|
||||
'Intro' => '介绍',
|
||||
'Version' => '版本',
|
||||
'New version' => '新版本',
|
||||
'Createtime' => '添加时间',
|
||||
'Releasetime' => '更新时间',
|
||||
'Detail' => '插件详情',
|
||||
'Document' => '文档',
|
||||
'Demo' => '在线演示',
|
||||
'Demo' => '演示',
|
||||
'Feedback' => '反馈BUG',
|
||||
'Install' => '安装',
|
||||
'Uninstall' => '卸载',
|
||||
|
|
@ -63,9 +73,7 @@ return [
|
|||
'Logout' => '退出登录',
|
||||
'Register' => '注册账号',
|
||||
'You\'re not login' => '当前未登录',
|
||||
'Pay now' => '立即支付',
|
||||
'Continue install' => '继续安装',
|
||||
'Continue uninstall' => '继续安装',
|
||||
'Continue uninstall' => '继续卸载',
|
||||
'Continue operate' => '继续操作',
|
||||
'Install successful' => '安装成功',
|
||||
'Uninstall successful' => '卸载成功',
|
||||
|
|
@ -73,4 +81,6 @@ return [
|
|||
'Addon info file was not found' => '插件配置文件未找到',
|
||||
'Addon info file data incorrect' => '插件配置信息不正确',
|
||||
'Addon already exists' => '上传的插件已经存在',
|
||||
'Unable to open the zip file' => '无法打开ZIP文件',
|
||||
'Unable to extract the file' => '无法解压ZIP文件',
|
||||
];
|
||||
|
|
|
|||
|
|
@ -10,9 +10,10 @@ return [
|
|||
'Controller/Action' => '控制器名/方法名',
|
||||
'Ismenu' => '菜单',
|
||||
'Search icon' => '搜索图标',
|
||||
'Menu tips' => '规则任意,不可重复,仅做层级显示,无需匹配控制器和方法',
|
||||
'Node tips' => '控制器/方法名',
|
||||
'Toggle menu visible' => '点击切换菜单显示',
|
||||
'Toggle sub menu' => '点击切换子菜单',
|
||||
'Menu tips' => '父级菜单无需匹配控制器和方法,子级菜单请使用控制器名',
|
||||
'Node tips' => '控制器/方法名,如果有目录请使用 目录名/控制器名/方法名',
|
||||
'The non-menu rule must have parent' => '非菜单规则节点必须有父级',
|
||||
'If not necessary, use the command line to build rule' => '非必要情况下请直接使用命令行<a href="https://doc.fastadmin.net/docs/command.html#一键生成菜单" target="_blank">php think menu</a>来生成',
|
||||
'Name only supports letters, numbers, underscore and slash' => 'URL规则只能是小写字母、数字、下划线和/组成',
|
||||
];
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
'Id' => 'ID',
|
||||
'Url' => '物理路径',
|
||||
'Imagewidth' => '宽度',
|
||||
'Imageheight' => '宽度',
|
||||
'Imageheight' => '高度',
|
||||
'Imagetype' => '图片类型',
|
||||
'Imageframes' => '图片帧数',
|
||||
'Preview' => '预览',
|
||||
|
|
|
|||
|
|
@ -53,6 +53,7 @@ return [
|
|||
'Mail from' => '发件人邮箱',
|
||||
'Name already exist' => '变量名称已经存在',
|
||||
'Send a test message' => '发送测试邮件',
|
||||
'This is a test mail content' => '这是一封测试邮件,用于测试邮件配置是否正常!',
|
||||
'This is a test mail' => '这是一封测试邮件',
|
||||
'This is a test mail content' => '这是一封来自FastAdmin校验邮件,用于校验邮件配置是否正常!',
|
||||
'This is a test mail' => '这是一封来自FastAdmin的邮件',
|
||||
'Please input your email' => '请输入测试接收者邮箱',
|
||||
];
|
||||
|
|
|
|||
|
|
@ -1,22 +0,0 @@
|
|||
<form id="add-form" class="form-horizontal" role="form" data-toggle="validator" method="POST" action="">
|
||||
|
||||
<div class="form-group">
|
||||
<label for="c-name" class="control-label col-xs-12 col-sm-2">{:__('Name')}:</label>
|
||||
<div class="col-xs-12 col-sm-8">
|
||||
<button type="button" id="plupload-addon" class="btn btn-danger plupload" data-url="addon/local" data-mimetype="application/zip" data-multiple="false"><i class="fa fa-upload"></i> {:__('请选择一个安装包')}</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="c-nickname" class="control-label col-xs-12 col-sm-2">{:__('Nickname')}:</label>
|
||||
<div class="col-xs-12 col-sm-8">
|
||||
<input id="c-nickname" data-rule="required" class="form-control" name="row[nickname]" type="text" value="">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group layer-footer">
|
||||
<label class="control-label col-xs-12 col-sm-2"></label>
|
||||
<div class="col-xs-12 col-sm-8">
|
||||
<button type="submit" class="btn btn-success btn-embossed disabled">{:__('OK')}</button>
|
||||
<button type="reset" class="btn btn-default btn-embossed">{:__('Reset')}</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
|
@ -1,38 +1,57 @@
|
|||
<style type="text/css">
|
||||
.noimage {width:100%;text-align: center;background:#18bc9c;color:#fff;padding-bottom:66.66%;position:relative;}
|
||||
.noimage > div {position: absolute;top:48%;width:100%;text-align:center;}
|
||||
.addon {position: relative;border-color:#e4e4e4;}
|
||||
.addon > span {position:absolute;left:15px;top:15px;z-index:9;}
|
||||
.addon > span a{opacity: 0.5;border:none;color:#fff;}
|
||||
.layui-layer-pay .layui-layer-content {padding:0;height:600px!important;}
|
||||
.layui-layer-pay {border:none;}
|
||||
.payimg{position:relative;width:800px;height:600px;}
|
||||
.payimg .alipaycode {position:absolute;left:265px;top:442px;}
|
||||
.payimg .wechatcode {position:absolute;left:660px;top:442px;}
|
||||
.thumbnail img{width:100%;}
|
||||
.layui-layer-pay .layui-layer-content {
|
||||
padding: 0;
|
||||
height: 600px !important;
|
||||
}
|
||||
|
||||
.layui-layer-pay {
|
||||
border: none;
|
||||
}
|
||||
|
||||
.payimg {
|
||||
position: relative;
|
||||
width: 800px;
|
||||
height: 600px;
|
||||
}
|
||||
|
||||
.payimg .alipaycode {
|
||||
position: absolute;
|
||||
left: 265px;
|
||||
top: 442px;
|
||||
}
|
||||
|
||||
.payimg .wechatcode {
|
||||
position: absolute;
|
||||
left: 660px;
|
||||
top: 442px;
|
||||
}
|
||||
|
||||
.thumbnail img {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.fixed-table-toolbar .pull-right.search {
|
||||
min-width: 300px;
|
||||
}
|
||||
.status-disabled .noimage {
|
||||
background:#d2d6de;
|
||||
|
||||
a.title {
|
||||
color: #444;
|
||||
}
|
||||
@media (min-width: 992px) {
|
||||
.addon {
|
||||
-webkit-transition:all 0.3s ease;
|
||||
-moz-transition: all 0.3s ease;
|
||||
-o-transition: all 0.3s ease;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
.addon:hover {
|
||||
border-color: #dddddd;
|
||||
-webkit-box-shadow: 0 26px 40px -24px rgba(0,36,100,0.3);
|
||||
-moz-box-shadow: 0 26px 40px -24px rgba(0,36,100,0.3);
|
||||
box-shadow: 0 26px 40px -24px rgba(0,36,100,0.3);
|
||||
-webkit-transition: all 0.3s ease;
|
||||
-moz-transition: all 0.3s ease;
|
||||
-o-transition: all 0.3s ease;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.releasetips {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.releasetips i {
|
||||
display: block;
|
||||
background: #f00;
|
||||
border-radius: 50%;
|
||||
width: 0.3em;
|
||||
height: 0.3em;
|
||||
top: 0px;
|
||||
right: -8px;
|
||||
position: absolute;
|
||||
box-shadow: 0px 0px 2px #f11414;
|
||||
}
|
||||
</style>
|
||||
<div class="panel panel-default panel-intro">
|
||||
|
|
@ -51,16 +70,27 @@
|
|||
<div class="widget-body no-padding">
|
||||
<div id="toolbar" class="toolbar">
|
||||
{:build_toolbar('refresh')}
|
||||
<button type="button" id="plupload-addon" class="btn btn-danger plupload" data-url="addon/local" data-mimetype="application/zip" data-multiple="false"><i class="fa fa-upload"></i> {:__('Offline install')}</button>
|
||||
<button type="button" id="plupload-addon" class="btn btn-danger plupload" data-url="addon/local"
|
||||
data-mimetype="application/zip" data-multiple="false"><i class="fa fa-upload"></i>
|
||||
{:__('Offline install')}
|
||||
</button>
|
||||
<div class="btn-group">
|
||||
<a href="#" class="btn btn-info btn-switch active" data-type="all" data-url="{$config.fastadmin.api_url}/addon/index"><i class="fa fa-list"></i> {:__('全部')}</a>
|
||||
<a href="#" class="btn btn-info btn-switch" data-type="free" data-url="{$config.fastadmin.api_url}/addon/index"><i class="fa fa-gift"></i> {:__('免费')}</a>
|
||||
<a href="#" class="btn btn-info btn-switch" data-type="price" data-url="{$config.fastadmin.api_url}/addon/index"><i class="fa fa-rmb"></i> {:__('付费')}</a>
|
||||
<a href="#" class="btn btn-info btn-switch" data-type="local" data-url="addon/downloaded"><i class="fa fa-laptop"></i> {:__('Local addon')}</a>
|
||||
<a href="#" class="btn btn-info btn-switch active" data-type="all"
|
||||
data-url="{$config.fastadmin.api_url}/addon/index"><i class="fa fa-list"></i>
|
||||
{:__('All')}</a>
|
||||
<a href="#" class="btn btn-info btn-switch" data-type="free"
|
||||
data-url="{$config.fastadmin.api_url}/addon/index"><i class="fa fa-gift"></i>
|
||||
{:__('Free')}</a>
|
||||
<a href="#" class="btn btn-info btn-switch" data-type="price"
|
||||
data-url="{$config.fastadmin.api_url}/addon/index"><i class="fa fa-rmb"></i>
|
||||
{:__('Paying')}</a>
|
||||
<a href="#" class="btn btn-info btn-switch" data-type="local" data-url="addon/downloaded"><i
|
||||
class="fa fa-laptop"></i> {:__('Local addon')}</a>
|
||||
</div>
|
||||
<a class="btn btn-primary btn-userinfo" href="javascript:;"><i class="fa fa-user"></i> {:__('Userinfo')}</a>
|
||||
<a class="btn btn-primary btn-userinfo" href="javascript:;"><i class="fa fa-user"></i>
|
||||
{:__('Userinfo')}</a>
|
||||
</div>
|
||||
<table id="table" class="table table-striped table-hover" width="100%">
|
||||
<table id="table" class="table table-striped table-bordered table-hover" width="100%">
|
||||
|
||||
</table>
|
||||
|
||||
|
|
@ -76,28 +106,28 @@
|
|||
<div class="row">
|
||||
<div class="col-xs-12 col-sm-6 col-md-3">
|
||||
<div class="form-group">
|
||||
<label class="control-label">标题</label>
|
||||
<label class="control-label">{:__('Title')}</label>
|
||||
<input class="operate" type="hidden" data-name="title" value="like"/>
|
||||
<input class="form-control" type="text" name="title" placeholder="请输入查找的标题" value=""/>
|
||||
<input class="form-control" type="text" name="title" placeholder="" value=""/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-xs-12 col-sm-6 col-md-3">
|
||||
<div class="form-group">
|
||||
<label class="control-label">类型</label>
|
||||
<label class="control-label">{:__('Type')}</label>
|
||||
<input class="operate" type="hidden" data-name="type" value="="/>
|
||||
<input class="form-control" type="text" name="type" placeholder="all" value=""/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-xs-12 col-sm-6 col-md-3">
|
||||
<div class="form-group">
|
||||
<label class="control-label">分类</label>
|
||||
<label class="control-label">{:__('Category')}</label>
|
||||
<input type="hidden" class="operate" data-name="category_id" value="="/>
|
||||
<input class="form-control" name="category_id" type="text" value="">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-xs-12 col-sm-6 col-md-3">
|
||||
<div class="form-group">
|
||||
<label class="control-label">版本号</label>
|
||||
<label class="control-label">{:__('Version')}</label>
|
||||
<input type="hidden" class="operate" data-name="faversion" value="="/>
|
||||
<input class="form-control" name="faversion" type="text" value="{$config.fastadmin.version}">
|
||||
</div>
|
||||
|
|
@ -107,10 +137,10 @@
|
|||
<label class="control-label"></label>
|
||||
<div class="row">
|
||||
<div class="col-xs-6">
|
||||
<input type="submit" class="btn btn-success btn-block" value="提交"/>
|
||||
<input type="submit" class="btn btn-success btn-block" value="{:__('Submit')}"/>
|
||||
</div>
|
||||
<div class="col-xs-6">
|
||||
<input type="reset" class="btn btn-primary btn-block" value="重置"/>
|
||||
<input type="reset" class="btn btn-primary btn-block" value="{:__('Reset')}"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -125,18 +155,20 @@
|
|||
<fieldset>
|
||||
<div class="alert alert-dismissable alert-danger">
|
||||
<button type="button" class="close" data-dismiss="alert">×</button>
|
||||
<strong>{:__('Warning')}</strong><br />{:__('Login tips')}
|
||||
<strong>{:__('Warning')}</strong><br/>{:__('Login tips')}
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="inputAccount" class="col-lg-3 control-label">{:__('Username')}</label>
|
||||
<div class="col-lg-9">
|
||||
<input type="text" class="form-control" id="inputAccount" value="" placeholder="{:__('Your username or email')}">
|
||||
<input type="text" class="form-control" id="inputAccount" value=""
|
||||
placeholder="{:__('Your username or email')}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="inputPassword" class="col-lg-3 control-label">{:__('Password')}</label>
|
||||
<div class="col-lg-9">
|
||||
<input type="password" class="form-control" id="inputPassword" value="" placeholder="{:__('Your password')}">
|
||||
<input type="password" class="form-control" id="inputPassword" value=""
|
||||
placeholder="{:__('Your password')}">
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
|
|
@ -149,57 +181,12 @@
|
|||
<fieldset>
|
||||
<div class="alert alert-dismissable alert-success">
|
||||
<button type="button" class="close" data-dismiss="alert">×</button>
|
||||
<strong>{:__('Warning')}</strong><br />{:__('Logined tips', '<%=username%>')}
|
||||
<strong>{:__('Warning')}</strong><br/>{:__('Logined tips', '<%=username%>')}
|
||||
</div>
|
||||
</fieldset>
|
||||
</form>
|
||||
</div>
|
||||
</script>
|
||||
<script id="addoninfotpl" type="text/html">
|
||||
<div style="font-size:13px;">
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th colspan="2"><h4><%=item.title%></h4></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th scope="row">{:__('Price')}</th>
|
||||
<td><div class="text-<%=item.price>0?'danger':'success'%>"><b>¥<%=item.price%></b></div></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">{:__('Author')}</th>
|
||||
<td><a href="<%=item.url?item.url:'javascript:;'%>" target="_blank"><%=item.author%></a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">{:__('Identify')}</th>
|
||||
<td><%=item.name%></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">{:__('Homepage')}</th>
|
||||
<td><a href="https://www.fastadmin.net/store/<%=item.name%>.html" target="_blank">https://www.fastadmin.net/store/<%=item.name%>.html</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">{:__('Intro')}</th>
|
||||
<td><%=item.intro%></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">{:__('Version')}</th>
|
||||
<td><%=# addon && item && addon.version!=item.version?'<span class="label label-danger">'+addon.version+'</span> -> <span class="label label-success">'+item.version+'</span>':item.version%></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">{:__('Createtime')}</th>
|
||||
<td><%=Moment(item.createtime*1000).format("YYYY-MM-DD HH:mm:ss")%></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">{:__('Releasetime')}</th>
|
||||
<td><%=Moment(item.releasetime*1000).format("YYYY-MM-DD HH:mm:ss")%></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</script>
|
||||
<script id="paytpl" type="text/html">
|
||||
<div class="payimg" style="background:url('<%=payimg%>') 0 0 no-repeat;background-size:cover;">
|
||||
<%if(paycode){%>
|
||||
|
|
@ -219,118 +206,85 @@
|
|||
</div>
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>#</th>
|
||||
<th>{:__('File')}</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>#</th>
|
||||
<th>{:__('File')}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<%for(var i=0;i < conflictlist.length;i++){%>
|
||||
<tr>
|
||||
<th scope="row"><%=i+1%></th>
|
||||
<td><%=conflictlist[i]%></td>
|
||||
</tr>
|
||||
<%}%>
|
||||
<%for(var i=0;i < conflictlist.length;i++){%>
|
||||
<tr>
|
||||
<th scope="row"><%=i+1%></th>
|
||||
<td><%=conflictlist[i]%></td>
|
||||
</tr>
|
||||
<%}%>
|
||||
</tbody>
|
||||
</table>
|
||||
</script>
|
||||
<script id="itemtpl" type="text/html">
|
||||
<script id="operatetpl" type="text/html">
|
||||
<% var labelarr = ['primary', 'success', 'info', 'danger', 'warning']; %>
|
||||
<% var label = labelarr[item.id % 5]; %>
|
||||
<% var addon = typeof addons[item.name]!= 'undefined' ? addons[item.name] : null; %>
|
||||
<div class="col-xs-12 col-sm-6 col-md-4 col-lg-3 mt-4 status-<%=addon ? (addon.state==1?'enabled':'disabled') : 'uninstalled'%>">
|
||||
<div class="thumbnail addon">
|
||||
<%if(addon){%>
|
||||
<span>
|
||||
<a href="<%=addon.url%>" target="_blank" class="btn btn-xs">
|
||||
<i class="fa fa-home"></i>
|
||||
<% var addon = item.addon; %>
|
||||
|
||||
<div class="operate" data-id="<%=item.id%>" data-name="<%=item.name%>">
|
||||
<% if(!addon){ %>
|
||||
<% if(typeof item.releaselist !="undefined" && item.releaselist.length>1){%>
|
||||
<span class="btn-group">
|
||||
<a href="javascript:;" class="btn btn-xs btn-primary btn-success btn-install"
|
||||
data-type="<%=item.price<=0?'free':'price';%>" data-donateimage="<%=item.donateimage%>"
|
||||
data-version="<%=item.version%>"><i class="fa fa-cloud-download"></i> {:__('Install')}</a>
|
||||
<a class="btn btn-xs btn-success dropdown-toggle" data-toggle="dropdown" href="javascript:;">
|
||||
<span class="fa fa-caret-down"></span>
|
||||
</a>
|
||||
<ul class="dropdown-menu">
|
||||
<% for(var j=0;j< item.releaselist.length;j++){ %>
|
||||
<li><a href="javascript:;" class="btn-install" data-type="<%=item.price<=0?'free':'price';%>"
|
||||
data-donateimage="<%=item.donateimage%>"
|
||||
data-version="<%=item.releaselist[j].version%>"><%=item.releaselist[j].version%></a></li>
|
||||
<% } %>
|
||||
</ul>
|
||||
</span>
|
||||
<%}%>
|
||||
<a href="<%=item.url%>" class="btn-addonindex" target="_blank">
|
||||
<%if(item.image){%>
|
||||
<img src="<%=item.image%>" class="img-responsive" alt="<%=item.title%>">
|
||||
<%}else{%>
|
||||
<div class="noimage"><div>{:__('No image')}</div></div>
|
||||
<%}%>
|
||||
</a>
|
||||
<div class="caption">
|
||||
<h4><%=item.title?item.title:'{:__('None')}'%>
|
||||
<% if(item.flag.indexOf("recommend")>-1){%>
|
||||
<span class="label label-success">{:__('Recommend')}</span>
|
||||
<% } %>
|
||||
<% if(item.flag.indexOf("hot")>-1){%>
|
||||
<span class="label label-danger">{:__('Hot')}</span>
|
||||
<% } %>
|
||||
<% if(item.flag.indexOf("free")>-1){%>
|
||||
<span class="label label-info">{:__('Free')}</span>
|
||||
<% } %>
|
||||
<% if(item.flag.indexOf("sale")>-1){%>
|
||||
<span class="label label-warning">{:__('Sale')}</span>
|
||||
<% } %>
|
||||
</h4>
|
||||
<p class="text-<%=item.price>0?'danger':'success'%>"><b>¥<%=item.price%></b></p>
|
||||
<p class="text-muted">{:__('Author')}: <a href="<%=item.url?item.url:'javascript:;'%>" target="_blank"><%=item.author%></a></p>
|
||||
<p class="text-muted">{:__('Intro')}: <%=item.intro%></p>
|
||||
<p class="text-muted">{:__('Version')}: <%=# addon && item && addon.version!=item.version?'<span class="label label-danger">'+addon.version+'</span> -> <span class="label label-success">'+item.version+'</span>':item.version%></p>
|
||||
<p class="text-muted">{:__('Createtime')}: <%=Moment(item.createtime*1000).format("YYYY-MM-DD HH:mm:ss")%></p>
|
||||
<div class="operate" data-id="<%=item.id%>" data-name="<%=item.name%>">
|
||||
<% if(!addon){ %>
|
||||
<% if(typeof item.releaselist !="undefined" && item.releaselist.length>1){%>
|
||||
<span class="btn-group">
|
||||
<a href="javascript:;" class="btn btn-primary btn-success btn-install" data-type="<%=item.price<=0?'free':'price';%>" data-donateimage="<%=item.donateimage%>" data-version="<%=item.version%>"><i class="fa fa-cloud-download"></i> {:__('Install')}</a>
|
||||
<a class="btn btn-success dropdown-toggle" data-toggle="dropdown" href="javascript:;">
|
||||
<span class="fa fa-caret-down"></span>
|
||||
</a>
|
||||
<ul class="dropdown-menu">
|
||||
<% for(var j=0;j< item.releaselist.length;j++){ %>
|
||||
<li><a href="javascript:;" class="btn-install" data-type="<%=item.price<=0?'free':'price';%>" data-donateimage="<%=item.donateimage%>" data-version="<%=item.releaselist[j].version%>"><%=item.releaselist[j].version%></a></li>
|
||||
<% } %>
|
||||
</ul>
|
||||
</span>
|
||||
<% }else{%>
|
||||
<a href="javascript:;" class="btn btn-primary btn-success btn-install" data-type="<%=item.price<=0?'free':'price';%>" data-donateimage="<%=item.donateimage%>" data-version="<%=item.version%>"><i class="fa fa-cloud-download"></i> {:__('Install')}</a>
|
||||
<% } %>
|
||||
<% if(item.demourl){ %>
|
||||
<a href="<%=item.demourl%>" class="btn btn-primary btn-info btn-demo" target="_blank"><i class="fa fa-flash"></i> {:__('Demo')}</a>
|
||||
<% } %>
|
||||
<% } %>
|
||||
<% }else{%>
|
||||
<a href="javascript:;" class="btn btn-xs btn-primary btn-success btn-install"
|
||||
data-type="<%=item.price<=0?'free':'price';%>" data-donateimage="<%=item.donateimage%>"
|
||||
data-version="<%=item.version%>"><i class="fa fa-cloud-download"></i> {:__('Install')}</a>
|
||||
<% } %>
|
||||
|
||||
<% if(addon){ %>
|
||||
<% if(addon.config){ %>
|
||||
<a href="javascript:;" class="btn btn-primary btn-config"><i class="fa fa-pencil"></i> {:__('Setting')}</a>
|
||||
<% } %>
|
||||
<% if(addon.state == "1"){ %>
|
||||
<a href="javascript:;" class="btn btn-warning btn-disable" data-action="disable"><i class="fa fa-times"></i> {:__('Disable')}</a>
|
||||
<% }else{ %>
|
||||
<a href="javascript:;" class="btn btn-success btn-enable" data-action="enable"><i class="fa fa-check"></i> {:__('Enable')}</a>
|
||||
<a href="javascript:;" class="btn btn-danger btn-uninstall"><i class="fa fa-times"></i> {:__('Uninstall')}</a>
|
||||
<% } %>
|
||||
<% } %>
|
||||
<% if(addon && item && addon.version!=item.version){%>
|
||||
<% if(typeof item.releaselist !="undefined" && item.releaselist.length>1){%>
|
||||
<span class="btn-group">
|
||||
<a href="javascript:;" class="btn btn-info btn-success btn-upgrade" data-version="<%=item.version%>"><i class="fa fa-cloud"></i> {:__('Upgrade')}</a>
|
||||
<a class="btn btn-info dropdown-toggle" data-toggle="dropdown" href="javascript:;">
|
||||
<span class="fa fa-caret-down"></span>
|
||||
</a>
|
||||
<ul class="dropdown-menu">
|
||||
<% for(var j=0;j< item.releaselist.length;j++){ %>
|
||||
<li><a href="javascript:;" class="btn-upgrade" data-version="<%=item.releaselist[j].version%>"><%=item.releaselist[j].version%></a></li>
|
||||
<% } %>
|
||||
</ul>
|
||||
</span>
|
||||
<% }else{%>
|
||||
<a href="javascript:;" class="btn btn-info btn-upgrade" data-version="<%=item.version%>"><i class="fa fa-cloud"></i> {:__('Upgrade')}</a>
|
||||
<% }%>
|
||||
<% }%>
|
||||
<% if(item.demourl){ %>
|
||||
<a href="<%=item.demourl%>" class="btn btn-xs btn-primary btn-info btn-demo" target="_blank">
|
||||
<i class="fa fa-flash"></i> {:__('Demo')}
|
||||
</a>
|
||||
<% } %>
|
||||
<% } else {%>
|
||||
<% if(addon.version!=item.version){%>
|
||||
<% if(typeof item.releaselist !="undefined" && item.releaselist.length>1){%>
|
||||
<span class="btn-group">
|
||||
<a href="javascript:;" class="btn btn-xs btn-info btn-success btn-upgrade"
|
||||
data-version="<%=item.version%>"><i class="fa fa-cloud"></i> {:__('Upgrade')}</a>
|
||||
<a class="btn btn-xs btn-info dropdown-toggle" data-toggle="dropdown"
|
||||
href="javascript:;">
|
||||
<span class="fa fa-caret-down"></span>
|
||||
</a>
|
||||
<ul class="dropdown-menu">
|
||||
<% for(var j=0;j< item.releaselist.length;j++){ %>
|
||||
<li><a href="javascript:;" class="btn-upgrade"
|
||||
data-version="<%=item.releaselist[j].version%>"><%=item.releaselist[j].version%></a></li>
|
||||
<% } %>
|
||||
</ul>
|
||||
</span>
|
||||
<% }else{%>
|
||||
<a href="javascript:;" class="btn btn-xs btn-info btn-upgrade" data-version="<%=item.version%>"><i
|
||||
class="fa fa-cloud"></i> {:__('Upgrade')}</a>
|
||||
<% }%>
|
||||
<% }%>
|
||||
<% if(addon.config){ %>
|
||||
<a href="javascript:;" class="btn btn-xs btn-primary btn-config"><i class="fa fa-pencil"></i>
|
||||
{:__('Setting')}</a>
|
||||
<% } %>
|
||||
<a href="javascript:;" class="btn btn-xs btn-danger btn-uninstall"><i class="fa fa-times"></i>
|
||||
{:__('Uninstall')}</a>
|
||||
<% } %>
|
||||
|
||||
<span class="pull-right" style="margin-top:10px;">
|
||||
<a href="javascript:;" class="btn-addoninfo text-gray" data-index="<%=i%>" title="<%=item.title?item.title:'{:__('None')}'%>"><i class="fa fa-bars"></i></a>
|
||||
</span>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</script>
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
<form id="add-form" class="form-horizontal form-ajax" role="form" data-toggle="validator" method="POST" action="">
|
||||
<div class="form-group">
|
||||
<label for="role_id" class="control-label col-xs-12 col-sm-2">{:__('Group')}:</label>
|
||||
<label class="control-label col-xs-12 col-sm-2">{:__('Group')}:</label>
|
||||
<div class="col-xs-12 col-sm-8">
|
||||
{:build_select('group[]', $groupdata, null, ['class'=>'form-control selectpicker', 'multiple'=>'', 'data-rule'=>'required'])}
|
||||
</div>
|
||||
|
|
@ -30,7 +30,7 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="content" class="control-label col-xs-12 col-sm-2">{:__('Status')}:</label>
|
||||
<label class="control-label col-xs-12 col-sm-2">{:__('Status')}:</label>
|
||||
<div class="col-xs-12 col-sm-8">
|
||||
{:build_radios('row[status]', ['normal'=>__('Normal'), 'hidden'=>__('Hidden')])}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<form id="edit-form" class="form-horizontal form-ajax" role="form" data-toggle="validator" method="POST" action="">
|
||||
<div class="form-group">
|
||||
<label for="role_id" class="control-label col-xs-12 col-sm-2">{:__('Group')}:</label>
|
||||
<label class="control-label col-xs-12 col-sm-2">{:__('Group')}:</label>
|
||||
<div class="col-xs-12 col-sm-8">
|
||||
{:build_select('group[]', $groupdata, $groupids, ['class'=>'form-control selectpicker', 'multiple'=>'', 'data-rule'=>'required'])}
|
||||
</div>
|
||||
|
|
@ -36,7 +36,7 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="content" class="control-label col-xs-12 col-sm-2">{:__('Status')}:</label>
|
||||
<label class="control-label col-xs-12 col-sm-2">{:__('Status')}:</label>
|
||||
<div class="col-xs-12 col-sm-8">
|
||||
{:build_radios('row[status]', ['normal'=>__('Normal'), 'hidden'=>__('Hidden')], $row['status'])}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,19 +1,19 @@
|
|||
<form id="add-form" class="form-horizontal form-ajax" role="form" data-toggle="validator" method="POST" action="">
|
||||
<input type="hidden" name="row[rules]" value="" />
|
||||
<div class="form-group">
|
||||
<label for="pid" class="control-label col-xs-12 col-sm-2">{:__('Parent')}:</label>
|
||||
<label class="control-label col-xs-12 col-sm-2">{:__('Parent')}:</label>
|
||||
<div class="col-xs-12 col-sm-8">
|
||||
{:build_select('row[pid]', $groupdata, null, ['class'=>'form-control selectpicker', 'data-rule'=>'required'])}
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="username" class="control-label col-xs-12 col-sm-2">{:__('Name')}:</label>
|
||||
<label class="control-label col-xs-12 col-sm-2">{:__('Name')}:</label>
|
||||
<div class="col-xs-12 col-sm-8">
|
||||
<input type="text" class="form-control" id="name" name="row[name]" value="" data-rule="required" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="nickname" class="control-label col-xs-12 col-sm-2">{:__('Permission')}:</label>
|
||||
<label class="control-label col-xs-12 col-sm-2">{:__('Permission')}:</label>
|
||||
<div class="col-xs-12 col-sm-8">
|
||||
<span class="text-muted"><input type="checkbox" name="" id="checkall" /> <label for="checkall"><small>{:__('Check all')}</small></label></span>
|
||||
<span class="text-muted"><input type="checkbox" name="" id="expandall" /> <label for="expandall"><small>{:__('Expand all')}</small></label></span>
|
||||
|
|
@ -22,7 +22,7 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="content" class="control-label col-xs-12 col-sm-2">{:__('Status')}:</label>
|
||||
<label class="control-label col-xs-12 col-sm-2">{:__('Status')}:</label>
|
||||
<div class="col-xs-12 col-sm-8">
|
||||
{:build_radios('row[status]', ['normal'=>__('Normal'), 'hidden'=>__('Hidden')])}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,19 +1,19 @@
|
|||
<form id="edit-form" class="form-horizontal form-ajax" role="form" method="POST" action="">
|
||||
<input type="hidden" name="row[rules]" value="" />
|
||||
<div class="form-group">
|
||||
<label for="pid" class="control-label col-xs-12 col-sm-2">{:__('Parent')}:</label>
|
||||
<label class="control-label col-xs-12 col-sm-2">{:__('Parent')}:</label>
|
||||
<div class="col-xs-12 col-sm-8">
|
||||
{:build_select('row[pid]', $groupdata, $row['pid'], ['class'=>'form-control selectpicker', 'data-rule'=>'required', 'data-id'=>$row['id'], 'data-pid'=>$row['pid']])}
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="username" class="control-label col-xs-12 col-sm-2">{:__('Name')}:</label>
|
||||
<label class="control-label col-xs-12 col-sm-2">{:__('Name')}:</label>
|
||||
<div class="col-xs-12 col-sm-8">
|
||||
<input type="text" class="form-control" id="name" name="row[name]" value="{$row.name}" data-rule="required" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="nickname" class="control-label col-xs-12 col-sm-2">{:__('Permission')}:</label>
|
||||
<label class="control-label col-xs-12 col-sm-2">{:__('Permission')}:</label>
|
||||
<div class="col-xs-12 col-sm-8">
|
||||
<span class="text-muted"><input type="checkbox" name="" id="checkall" /> <label for="checkall"><small>{:__('Check all')}</small></label></span>
|
||||
<span class="text-muted"><input type="checkbox" name="" id="expandall" /> <label for="expandall"><small>{:__('Expand all')}</small></label></span>
|
||||
|
|
@ -22,7 +22,7 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="content" class="control-label col-xs-12 col-sm-2">{:__('Status')}:</label>
|
||||
<label class="control-label col-xs-12 col-sm-2">{:__('Status')}:</label>
|
||||
<div class="col-xs-12 col-sm-8">
|
||||
{:build_radios('row[status]', ['normal'=>__('Normal'), 'hidden'=>__('Hidden')], $row['status'])}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,16 +1,12 @@
|
|||
<div class="callout callout-info">
|
||||
<h4>{:__('Alert')}!</h4>
|
||||
{:__('If not necessary, use the command line to build rule')}
|
||||
</div>
|
||||
<form id="add-form" class="form-horizontal form-ajax" role="form" data-toggle="validator" method="POST" action="">
|
||||
<div class="form-group">
|
||||
<label for="content" class="control-label col-xs-12 col-sm-2">{:__('Ismenu')}:</label>
|
||||
<label class="control-label col-xs-12 col-sm-2">{:__('Ismenu')}:</label>
|
||||
<div class="col-xs-12 col-sm-8">
|
||||
{:build_radios('row[ismenu]', ['1'=>__('Yes'), '0'=>__('No')])}
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="pid" class="control-label col-xs-12 col-sm-2">{:__('Parent')}:</label>
|
||||
<label class="control-label col-xs-12 col-sm-2">{:__('Parent')}:</label>
|
||||
<div class="col-xs-12 col-sm-8">
|
||||
{:build_select('row[pid]', $ruledata, null, ['class'=>'form-control', 'required'=>''])}
|
||||
</div>
|
||||
|
|
@ -18,11 +14,12 @@
|
|||
<div class="form-group">
|
||||
<label for="name" class="control-label col-xs-12 col-sm-2">{:__('Name')}:</label>
|
||||
<div class="col-xs-12 col-sm-8">
|
||||
<a href="javascript:;" data-toggle="tooltip" title="提示">测试</a>
|
||||
<input type="text" class="form-control" id="name" name="row[name]" data-placeholder-node="{:__('Node tips')}" data-placeholder-menu="{:__('Menu tips')}" value="" data-rule="required" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="module" class="control-label col-xs-12 col-sm-2">{:__('Title')}:</label>
|
||||
<label class="control-label col-xs-12 col-sm-2">{:__('Title')}:</label>
|
||||
<div class="col-xs-12 col-sm-8">
|
||||
<input type="text" class="form-control" id="title" name="row[title]" value="" data-rule="required" />
|
||||
</div>
|
||||
|
|
@ -55,7 +52,7 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="content" class="control-label col-xs-12 col-sm-2">{:__('Status')}:</label>
|
||||
<label class="control-label col-xs-12 col-sm-2">{:__('Status')}:</label>
|
||||
<div class="col-xs-12 col-sm-8">
|
||||
{:build_radios('row[status]', ['normal'=>__('Normal'), 'hidden'=>__('Hidden')])}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
<form id="edit-form" class="form-horizontal form-ajax" role="form" method="POST" action="">
|
||||
<div class="form-group">
|
||||
<label for="content" class="control-label col-xs-12 col-sm-2">{:__('Ismenu')}:</label>
|
||||
<label class="control-label col-xs-12 col-sm-2">{:__('Ismenu')}:</label>
|
||||
<div class="col-xs-12 col-sm-8">
|
||||
{:build_radios('row[ismenu]', ['1'=>__('Yes'), '0'=>__('No')], $row['ismenu'])}
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="pid" class="control-label col-xs-12 col-sm-2">{:__('Parent')}:</label>
|
||||
<label class="control-label col-xs-12 col-sm-2">{:__('Parent')}:</label>
|
||||
<div class="col-xs-12 col-sm-8">
|
||||
{:build_select('row[pid]', $ruledata, $row['pid'], ['class'=>'form-control', 'required'=>''])}
|
||||
</div>
|
||||
|
|
@ -18,7 +18,7 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="action" class="control-label col-xs-12 col-sm-2">{:__('Title')}:</label>
|
||||
<label class="control-label col-xs-12 col-sm-2">{:__('Title')}:</label>
|
||||
<div class="col-xs-12 col-sm-8">
|
||||
<input type="text" class="form-control" id="title" name="row[title]" value="{$row.title}" data-rule="required" />
|
||||
</div>
|
||||
|
|
@ -51,7 +51,7 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="content" class="control-label col-xs-12 col-sm-2">{:__('Status')}:</label>
|
||||
<label class="control-label col-xs-12 col-sm-2">{:__('Status')}:</label>
|
||||
<div class="col-xs-12 col-sm-8">
|
||||
{:build_radios('row[status]', ['normal'=>__('Normal'), 'hidden'=>__('Hidden')], $row['status'])}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -6,12 +6,13 @@
|
|||
margin:5px 0 0 0;
|
||||
}
|
||||
#chooseicon ul li{
|
||||
width:30px;height:30px;
|
||||
line-height:30px;
|
||||
border:1px solid #ddd;
|
||||
width:41px;height:42px;
|
||||
line-height:42px;
|
||||
border:1px solid #efefef;
|
||||
padding:1px;
|
||||
margin:1px;
|
||||
text-align: center;
|
||||
font-size:18px;
|
||||
}
|
||||
#chooseicon ul li:hover{
|
||||
border:1px solid #2c3e50;
|
||||
|
|
@ -31,7 +32,7 @@
|
|||
<div>
|
||||
<ul class="list-inline">
|
||||
<% for(var i=0; i<iconlist.length; i++){ %>
|
||||
<li data-font="<%=iconlist[i]%>" title="<%=iconlist[i]%>">
|
||||
<li data-font="<%=iconlist[i]%>" data-toggle="tooltip" title="<%=iconlist[i]%>">
|
||||
<i class="fa fa-<%=iconlist[i]%>"></i>
|
||||
</li>
|
||||
<% } %>
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="c-status" class="control-label col-xs-12 col-sm-2">{:__('Status')}:</label>
|
||||
<label class="control-label col-xs-12 col-sm-2">{:__('Status')}:</label>
|
||||
<div class="col-xs-12 col-sm-8">
|
||||
{:build_radios('row[status]', ['normal'=>__('Normal'), 'hidden'=>__('Hidden')])}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="c-status" class="control-label col-xs-12 col-sm-2">{:__('Status')}:</label>
|
||||
<label class="control-label col-xs-12 col-sm-2">{:__('Status')}:</label>
|
||||
<div class="col-xs-12 col-sm-8">
|
||||
{:build_radios('row[status]', ['normal'=>__('Normal'), 'hidden'=>__('Hidden')], $row['status'])}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -54,6 +54,7 @@
|
|||
</a>
|
||||
<ul class="dropdown-menu wipecache">
|
||||
<li><a href="javascript:;" data-type="all"><i class="fa fa-trash"></i> {:__('Wipe all cache')}</a></li>
|
||||
<li class="divider"></li>
|
||||
<li><a href="javascript:;" data-type="content"><i class="fa fa-file-text"></i> {:__('Wipe content cache')}</a></li>
|
||||
<li><a href="javascript:;" data-type="template"><i class="fa fa-file-image-o"></i> {:__('Wipe template cache')}</a></li>
|
||||
<li><a href="javascript:;" data-type="addons"><i class="fa fa-rocket"></i> {:__('Wipe addons cache')}</a></li>
|
||||
|
|
|
|||
|
|
@ -24,15 +24,14 @@ class Common extends Api
|
|||
|
||||
/**
|
||||
* 加载初始化
|
||||
*
|
||||
*
|
||||
* @param string $version 版本号
|
||||
* @param string $lng 经度
|
||||
* @param string $lat 纬度
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
if ($version = $this->request->request('version'))
|
||||
{
|
||||
if ($version = $this->request->request('version')) {
|
||||
$lng = $this->request->request('lng');
|
||||
$lat = $this->request->request('lat');
|
||||
$content = [
|
||||
|
|
@ -42,23 +41,20 @@ class Common extends Api
|
|||
'coverdata' => Config::get("cover"),
|
||||
];
|
||||
$this->success('', $content);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$this->error(__('Invalid parameters'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传文件
|
||||
*
|
||||
*
|
||||
* @param File $file 文件流
|
||||
*/
|
||||
public function upload()
|
||||
{
|
||||
$file = $this->request->file('file');
|
||||
if (empty($file))
|
||||
{
|
||||
if (empty($file)) {
|
||||
$this->error(__('No file upload or server upload limit exceeded'));
|
||||
}
|
||||
|
||||
|
|
@ -70,7 +66,7 @@ class Common extends Api
|
|||
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);
|
||||
$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';
|
||||
|
|
@ -108,16 +104,16 @@ class Common extends Api
|
|||
$fileName = substr($savekey, strripos($savekey, '/') + 1);
|
||||
//
|
||||
$splInfo = $file->validate(['size' => $size])->move(ROOT_PATH . '/public' . $uploadDir, $fileName);
|
||||
if ($splInfo)
|
||||
{
|
||||
if ($splInfo) {
|
||||
$imagewidth = $imageheight = 0;
|
||||
if (in_array($suffix, ['gif', 'jpg', 'jpeg', 'bmp', 'png', 'swf']))
|
||||
{
|
||||
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(
|
||||
'admin_id' => 0,
|
||||
'user_id' => (int)$this->auth->id,
|
||||
'filesize' => $fileInfo['size'],
|
||||
'imagewidth' => $imagewidth,
|
||||
'imageheight' => $imageheight,
|
||||
|
|
@ -136,9 +132,7 @@ class Common extends Api
|
|||
$this->success(__('Upload successful'), [
|
||||
'url' => $uploadDir . $splInfo->getSaveName()
|
||||
]);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
// 上传失败获取错误信息
|
||||
$this->error($file->getError());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,22 +2,20 @@
|
|||
|
||||
// 公共助手函数
|
||||
|
||||
if (!function_exists('__'))
|
||||
{
|
||||
if (!function_exists('__')) {
|
||||
|
||||
/**
|
||||
* 获取语言变量值
|
||||
* @param string $name 语言变量名
|
||||
* @param array $vars 动态变量值
|
||||
* @param string $lang 语言
|
||||
* @param string $name 语言变量名
|
||||
* @param array $vars 动态变量值
|
||||
* @param string $lang 语言
|
||||
* @return mixed
|
||||
*/
|
||||
function __($name, $vars = [], $lang = '')
|
||||
{
|
||||
if (is_numeric($name) || !$name)
|
||||
return $name;
|
||||
if (!is_array($vars))
|
||||
{
|
||||
if (!is_array($vars)) {
|
||||
$vars = func_get_args();
|
||||
array_shift($vars);
|
||||
$lang = '';
|
||||
|
|
@ -27,8 +25,7 @@ if (!function_exists('__'))
|
|||
|
||||
}
|
||||
|
||||
if (!function_exists('format_bytes'))
|
||||
{
|
||||
if (!function_exists('format_bytes')) {
|
||||
|
||||
/**
|
||||
* 将字节转换为可读文本
|
||||
|
|
@ -46,8 +43,7 @@ if (!function_exists('format_bytes'))
|
|||
|
||||
}
|
||||
|
||||
if (!function_exists('datetime'))
|
||||
{
|
||||
if (!function_exists('datetime')) {
|
||||
|
||||
/**
|
||||
* 将时间戳转换为日期时间
|
||||
|
|
@ -63,8 +59,7 @@ if (!function_exists('datetime'))
|
|||
|
||||
}
|
||||
|
||||
if (!function_exists('human_date'))
|
||||
{
|
||||
if (!function_exists('human_date')) {
|
||||
|
||||
/**
|
||||
* 获取语义化时间
|
||||
|
|
@ -79,50 +74,56 @@ if (!function_exists('human_date'))
|
|||
|
||||
}
|
||||
|
||||
if (!function_exists('cdnurl'))
|
||||
{
|
||||
if (!function_exists('cdnurl')) {
|
||||
|
||||
/**
|
||||
* 获取上传资源的CDN的地址
|
||||
* @param string $url 资源相对地址
|
||||
* @param boolean $domain 是否显示域名 或者直接传入域名
|
||||
* @return string
|
||||
*/
|
||||
function cdnurl($url)
|
||||
function cdnurl($url, $domain = false)
|
||||
{
|
||||
return preg_match("/^https?:\/\/(.*)/i", $url) ? $url : \think\Config::get('upload.cdnurl') . $url;
|
||||
$url = preg_match("/^https?:\/\/(.*)/i", $url) ? $url : \think\Config::get('upload.cdnurl') . $url;
|
||||
if ($domain && !preg_match("/^(http:\/\/|https:\/\/)/i", $url)) {
|
||||
if (is_bool($domain)) {
|
||||
$public = \think\Config::get('view_replace_str.__PUBLIC__');
|
||||
$url = rtrim($public, '/') . $url;
|
||||
if (!preg_match("/^(http:\/\/|https:\/\/)/i", $url)) {
|
||||
$url = request()->domain() . $url;
|
||||
}
|
||||
} else {
|
||||
$url = $domain . $url;
|
||||
}
|
||||
}
|
||||
return $url;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (!function_exists('is_really_writable'))
|
||||
{
|
||||
if (!function_exists('is_really_writable')) {
|
||||
|
||||
/**
|
||||
* 判断文件或文件夹是否可写
|
||||
* @param string $file 文件或目录
|
||||
* @return bool
|
||||
* @param string $file 文件或目录
|
||||
* @return bool
|
||||
*/
|
||||
function is_really_writable($file)
|
||||
{
|
||||
if (DIRECTORY_SEPARATOR === '/')
|
||||
{
|
||||
if (DIRECTORY_SEPARATOR === '/') {
|
||||
return is_writable($file);
|
||||
}
|
||||
if (is_dir($file))
|
||||
{
|
||||
if (is_dir($file)) {
|
||||
$file = rtrim($file, '/') . '/' . md5(mt_rand());
|
||||
if (($fp = @fopen($file, 'ab')) === FALSE)
|
||||
{
|
||||
if (($fp = @fopen($file, 'ab')) === FALSE) {
|
||||
return FALSE;
|
||||
}
|
||||
fclose($fp);
|
||||
@chmod($file, 0777);
|
||||
@unlink($file);
|
||||
return TRUE;
|
||||
}
|
||||
elseif (!is_file($file) OR ( $fp = @fopen($file, 'ab')) === FALSE)
|
||||
{
|
||||
} elseif (!is_file($file) OR ($fp = @fopen($file, 'ab')) === FALSE) {
|
||||
return FALSE;
|
||||
}
|
||||
fclose($fp);
|
||||
|
|
@ -131,8 +132,7 @@ if (!function_exists('is_really_writable'))
|
|||
|
||||
}
|
||||
|
||||
if (!function_exists('rmdirs'))
|
||||
{
|
||||
if (!function_exists('rmdirs')) {
|
||||
|
||||
/**
|
||||
* 删除文件夹
|
||||
|
|
@ -145,16 +145,14 @@ if (!function_exists('rmdirs'))
|
|||
if (!is_dir($dirname))
|
||||
return false;
|
||||
$files = new RecursiveIteratorIterator(
|
||||
new RecursiveDirectoryIterator($dirname, RecursiveDirectoryIterator::SKIP_DOTS), RecursiveIteratorIterator::CHILD_FIRST
|
||||
new RecursiveDirectoryIterator($dirname, RecursiveDirectoryIterator::SKIP_DOTS), RecursiveIteratorIterator::CHILD_FIRST
|
||||
);
|
||||
|
||||
foreach ($files as $fileinfo)
|
||||
{
|
||||
foreach ($files as $fileinfo) {
|
||||
$todo = ($fileinfo->isDir() ? 'rmdir' : 'unlink');
|
||||
$todo($fileinfo->getRealPath());
|
||||
}
|
||||
if ($withself)
|
||||
{
|
||||
if ($withself) {
|
||||
@rmdir($dirname);
|
||||
}
|
||||
return true;
|
||||
|
|
@ -162,8 +160,7 @@ if (!function_exists('rmdirs'))
|
|||
|
||||
}
|
||||
|
||||
if (!function_exists('copydirs'))
|
||||
{
|
||||
if (!function_exists('copydirs')) {
|
||||
|
||||
/**
|
||||
* 复制文件夹
|
||||
|
|
@ -172,25 +169,19 @@ if (!function_exists('copydirs'))
|
|||
*/
|
||||
function copydirs($source, $dest)
|
||||
{
|
||||
if (!is_dir($dest))
|
||||
{
|
||||
mkdir($dest, 0755);
|
||||
if (!is_dir($dest)) {
|
||||
mkdir($dest, 0755, true);
|
||||
}
|
||||
foreach (
|
||||
$iterator = new RecursiveIteratorIterator(
|
||||
new RecursiveDirectoryIterator($source, RecursiveDirectoryIterator::SKIP_DOTS), RecursiveIteratorIterator::SELF_FIRST) as $item
|
||||
)
|
||||
{
|
||||
if ($item->isDir())
|
||||
{
|
||||
$iterator = new RecursiveIteratorIterator(
|
||||
new RecursiveDirectoryIterator($source, RecursiveDirectoryIterator::SKIP_DOTS), RecursiveIteratorIterator::SELF_FIRST) as $item
|
||||
) {
|
||||
if ($item->isDir()) {
|
||||
$sontDir = $dest . DS . $iterator->getSubPathName();
|
||||
if (!is_dir($sontDir))
|
||||
{
|
||||
mkdir($sontDir);
|
||||
if (!is_dir($sontDir)) {
|
||||
mkdir($sontDir, 0755, true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
copy($item, $dest . DS . $iterator->getSubPathName());
|
||||
}
|
||||
}
|
||||
|
|
@ -198,8 +189,7 @@ if (!function_exists('copydirs'))
|
|||
|
||||
}
|
||||
|
||||
if (!function_exists('mb_ucfirst'))
|
||||
{
|
||||
if (!function_exists('mb_ucfirst')) {
|
||||
|
||||
function mb_ucfirst($string)
|
||||
{
|
||||
|
|
@ -208,8 +198,7 @@ if (!function_exists('mb_ucfirst'))
|
|||
|
||||
}
|
||||
|
||||
if (!function_exists('addtion'))
|
||||
{
|
||||
if (!function_exists('addtion')) {
|
||||
|
||||
/**
|
||||
* 附加关联字段数据
|
||||
|
|
@ -222,31 +211,22 @@ if (!function_exists('addtion'))
|
|||
if (!$items || !$fields)
|
||||
return $items;
|
||||
$fieldsArr = [];
|
||||
if (!is_array($fields))
|
||||
{
|
||||
if (!is_array($fields)) {
|
||||
$arr = explode(',', $fields);
|
||||
foreach ($arr as $k => $v)
|
||||
{
|
||||
foreach ($arr as $k => $v) {
|
||||
$fieldsArr[$v] = ['field' => $v];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach ($fields as $k => $v)
|
||||
{
|
||||
if (is_array($v))
|
||||
{
|
||||
} else {
|
||||
foreach ($fields as $k => $v) {
|
||||
if (is_array($v)) {
|
||||
$v['field'] = isset($v['field']) ? $v['field'] : $k;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$v = ['field' => $v];
|
||||
}
|
||||
$fieldsArr[$v['field']] = $v;
|
||||
}
|
||||
}
|
||||
foreach ($fieldsArr as $k => &$v)
|
||||
{
|
||||
foreach ($fieldsArr as $k => &$v) {
|
||||
$v = is_array($v) ? $v : ['field' => $v];
|
||||
$v['display'] = isset($v['display']) ? $v['display'] : str_replace(['_ids', '_id'], ['_names', '_name'], $v['field']);
|
||||
$v['primary'] = isset($v['primary']) ? $v['primary'] : '';
|
||||
|
|
@ -258,37 +238,27 @@ if (!function_exists('addtion'))
|
|||
unset($v);
|
||||
$ids = [];
|
||||
$fields = array_keys($fieldsArr);
|
||||
foreach ($items as $k => $v)
|
||||
{
|
||||
foreach ($fields as $m => $n)
|
||||
{
|
||||
if (isset($v[$n]))
|
||||
{
|
||||
foreach ($items as $k => $v) {
|
||||
foreach ($fields as $m => $n) {
|
||||
if (isset($v[$n])) {
|
||||
$ids[$n] = array_merge(isset($ids[$n]) && is_array($ids[$n]) ? $ids[$n] : [], explode(',', $v[$n]));
|
||||
}
|
||||
}
|
||||
}
|
||||
$result = [];
|
||||
foreach ($fieldsArr as $k => $v)
|
||||
{
|
||||
if ($v['model'])
|
||||
{
|
||||
foreach ($fieldsArr as $k => $v) {
|
||||
if ($v['model']) {
|
||||
$model = new $v['model'];
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$model = $v['name'] ? \think\Db::name($v['name']) : \think\Db::table($v['table']);
|
||||
}
|
||||
$primary = $v['primary'] ? $v['primary'] : $model->getPk();
|
||||
$result[$v['field']] = $model->where($primary, 'in', $ids[$v['field']])->column("{$primary},{$v['column']}");
|
||||
}
|
||||
|
||||
foreach ($items as $k => &$v)
|
||||
{
|
||||
foreach ($fields as $m => $n)
|
||||
{
|
||||
if (isset($v[$n]))
|
||||
{
|
||||
foreach ($items as $k => &$v) {
|
||||
foreach ($fields as $m => $n) {
|
||||
if (isset($v[$n])) {
|
||||
$curr = array_flip(explode(',', $v[$n]));
|
||||
|
||||
$v[$fieldsArr[$n]['display']] = implode(',', array_intersect_key($result[$n], $curr));
|
||||
|
|
@ -300,29 +270,26 @@ if (!function_exists('addtion'))
|
|||
|
||||
}
|
||||
|
||||
if (!function_exists('var_export_short'))
|
||||
{
|
||||
if (!function_exists('var_export_short')) {
|
||||
|
||||
/**
|
||||
* 返回打印数组结构
|
||||
* @param string $var 数组
|
||||
* @param string $var 数组
|
||||
* @param string $indent 缩进字符
|
||||
* @return string
|
||||
*/
|
||||
function var_export_short($var, $indent = "")
|
||||
{
|
||||
switch (gettype($var))
|
||||
{
|
||||
switch (gettype($var)) {
|
||||
case "string":
|
||||
return '"' . addcslashes($var, "\\\$\"\r\n\t\v\f") . '"';
|
||||
case "array":
|
||||
$indexed = array_keys($var) === range(0, count($var) - 1);
|
||||
$r = [];
|
||||
foreach ($var as $key => $value)
|
||||
{
|
||||
foreach ($var as $key => $value) {
|
||||
$r[] = "$indent "
|
||||
. ($indexed ? "" : var_export_short($key) . " => ")
|
||||
. var_export_short($value, "$indent ");
|
||||
. ($indexed ? "" : var_export_short($key) . " => ")
|
||||
. var_export_short($value, "$indent ");
|
||||
}
|
||||
return "[\n" . implode(",\n", $r) . "\n" . $indent . "]";
|
||||
case "boolean":
|
||||
|
|
|
|||
|
|
@ -270,7 +270,7 @@ return [
|
|||
//自动检测更新
|
||||
'checkupdate' => false,
|
||||
//版本号
|
||||
'version' => '1.0.0.20180417_beta',
|
||||
'version' => '1.0.0.20180506_beta',
|
||||
//API接口地址
|
||||
'api_url' => 'https://api.fastadmin.net',
|
||||
],
|
||||
|
|
|
|||
|
|
@ -107,7 +107,7 @@ class User extends Frontend
|
|||
$validate = new Validate($rule, $msg);
|
||||
$result = $validate->check($data);
|
||||
if (!$result) {
|
||||
$this->error(__($validate->getError()));
|
||||
$this->error(__($validate->getError()), null, ['token' => $this->request->token()]);
|
||||
}
|
||||
if ($this->auth->register($username, $password, $email, $mobile)) {
|
||||
$synchtml = '';
|
||||
|
|
@ -118,7 +118,7 @@ class User extends Frontend
|
|||
}
|
||||
$this->success(__('Sign up successful') . $synchtml, $url ? $url : url('user/index'));
|
||||
} else {
|
||||
$this->error($this->auth->getError());
|
||||
$this->error($this->auth->getError(), null, ['token' => $this->request->token()]);
|
||||
}
|
||||
}
|
||||
//判断来源
|
||||
|
|
@ -165,7 +165,7 @@ class User extends Frontend
|
|||
$validate = new Validate($rule, $msg);
|
||||
$result = $validate->check($data);
|
||||
if (!$result) {
|
||||
$this->error(__($validate->getError()));
|
||||
$this->error(__($validate->getError()), null, ['token' => $this->request->token()]);
|
||||
return FALSE;
|
||||
}
|
||||
if ($this->auth->login($account, $password)) {
|
||||
|
|
@ -177,7 +177,7 @@ class User extends Frontend
|
|||
}
|
||||
$this->success(__('Logged in successful') . $synchtml, $url ? $url : url('user/index'));
|
||||
} else {
|
||||
$this->error($this->auth->getError());
|
||||
$this->error($this->auth->getError(), null, ['token' => $this->request->token()]);
|
||||
}
|
||||
}
|
||||
//判断来源
|
||||
|
|
@ -249,7 +249,7 @@ class User extends Frontend
|
|||
$validate = new Validate($rule, $msg, $field);
|
||||
$result = $validate->check($data);
|
||||
if (!$result) {
|
||||
$this->error(__($validate->getError()));
|
||||
$this->error(__($validate->getError()), null, ['token' => $this->request->token()]);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
|
@ -263,7 +263,7 @@ class User extends Frontend
|
|||
}
|
||||
$this->success(__('Reset password successful') . $synchtml, url('user/login'));
|
||||
} else {
|
||||
$this->error($this->auth->getError());
|
||||
$this->error($this->auth->getError(), null, ['token' => $this->request->token()]);
|
||||
}
|
||||
}
|
||||
$this->view->assign('title', __('Change password'));
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
<div class="login-main">
|
||||
<form name="form" id="login-form" class="form-vertical" method="POST" action="">
|
||||
<input type="hidden" name="url" value="{$url}" />
|
||||
{:token()}
|
||||
<div class="form-group">
|
||||
<label class="control-label" for="account">{:__('Account')}</label>
|
||||
<div class="controls">
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
<form name="form1" id="register-form" class="form-vertical" method="POST" action="">
|
||||
<input type="hidden" name="invite_user_id" value="0" />
|
||||
<input type="hidden" name="url" value="{$url}" />
|
||||
{:token()}
|
||||
<div class="form-group">
|
||||
<label class="control-label required">{:__('Email')}<span class="text-success"></span></label>
|
||||
<div class="controls">
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@
|
|||
"topthink/think-captcha": "^1.0",
|
||||
"mtdowling/cron-expression": "^1.2",
|
||||
"phpmailer/phpmailer": "^5.2",
|
||||
"karsonzhang/fastadmin-addons": "~1.1.0",
|
||||
"karsonzhang/fastadmin-addons": "~1.1.4",
|
||||
"overtrue/pinyin": "~3.0",
|
||||
"phpoffice/phpexcel": "^1.8"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -356,7 +356,7 @@
|
|||
<div class="panel panel-default">
|
||||
<div class="panel-heading"><strong>参数</strong></div>
|
||||
<div class="panel-body">
|
||||
<form enctype="application/x-www-form-urlencoded" role="form" action="/api/demo/test1" method="get" name="form2" id="form2">
|
||||
<form enctype="application/x-www-form-urlencoded" role="form" action="/api/demo/test1" method="GET" name="form2" id="form2">
|
||||
<div class="form-group">
|
||||
无
|
||||
</div>
|
||||
|
|
@ -3359,7 +3359,7 @@
|
|||
|
||||
<div class="row mt0 footer">
|
||||
<div class="col-md-6" align="left">
|
||||
Generated on 2018-04-06 19:15:01 </div>
|
||||
Generated on 2018-05-04 11:06:48 </div>
|
||||
<div class="col-md-6" align="right">
|
||||
<a href="https://www.fastadmin.net" target="_blank">FastAdmin</a>
|
||||
</div>
|
||||
|
|
@ -3531,8 +3531,8 @@
|
|||
|
||||
$.ajax({
|
||||
url: $('#apiUrl').val() + url,
|
||||
data: $(form).attr('method') == 'get' ? $(form).serialize() : formData,
|
||||
type: $(form).attr('method') + '',
|
||||
data: $(form).prop('method').toLowerCase() == 'get' ? $(form).serialize() : formData,
|
||||
type: $(form).prop('method') + '',
|
||||
dataType: 'json',
|
||||
contentType: false,
|
||||
processData: false,
|
||||
|
|
|
|||
|
|
@ -559,6 +559,9 @@ form.form-horizontal .control-label {
|
|||
.bootstrap-table td.bs-checkbox {
|
||||
vertical-align: middle;
|
||||
}
|
||||
.fixed-table-container thead th .sortable {
|
||||
padding-right: 0;
|
||||
}
|
||||
.dropdown-submenu {
|
||||
position: relative;
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -103,20 +103,8 @@ define(['fast', 'template', 'moment'], function (Fast, Template, Moment) {
|
|||
},
|
||||
refreshmenu: function () {
|
||||
top.window.$(".sidebar-menu").trigger("refresh");
|
||||
}
|
||||
},
|
||||
init: function () {
|
||||
//公共代码
|
||||
//添加ios-fix兼容iOS下的iframe
|
||||
if (/iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream) {
|
||||
$("html").addClass("ios-fix");
|
||||
}
|
||||
//配置Toastr的参数
|
||||
Toastr.options.positionClass = Config.controllername === 'index' ? "toast-top-right-index" : "toast-top-right";
|
||||
//点击包含.btn-dialog的元素时弹出dialog
|
||||
$(document).on('click', '.btn-dialog,.dialogit', function (e) {
|
||||
var that = this;
|
||||
var options = $.extend({}, $(that).data() || {});
|
||||
},
|
||||
gettablecolumnbutton: function(options){
|
||||
if (typeof options.tableId !== 'undefined' && typeof options.fieldIndex !== 'undefined' && typeof options.buttonIndex !== 'undefined') {
|
||||
var tableOptions = $("#" + options.tableId).bootstrapTable('getOptions');
|
||||
if (tableOptions) {
|
||||
|
|
@ -133,20 +121,38 @@ define(['fast', 'template', 'moment'], function (Fast, Template, Moment) {
|
|||
}
|
||||
});
|
||||
if (columnObj) {
|
||||
var button = columnObj['buttons'][options.buttonIndex];
|
||||
if (button && typeof button.callback === 'function') {
|
||||
options.callback = button.callback;
|
||||
}
|
||||
return columnObj['buttons'][options.buttonIndex];
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
},
|
||||
},
|
||||
init: function () {
|
||||
//公共代码
|
||||
//添加ios-fix兼容iOS下的iframe
|
||||
if (/iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream) {
|
||||
$("html").addClass("ios-fix");
|
||||
}
|
||||
//配置Toastr的参数
|
||||
Toastr.options.positionClass = Config.controllername === 'index' ? "toast-top-right-index" : "toast-top-right";
|
||||
//点击包含.btn-dialog的元素时弹出dialog
|
||||
$(document).on('click', '.btn-dialog,.dialogit', function (e) {
|
||||
var that = this;
|
||||
var options = $.extend({}, $(that).data() || {});
|
||||
var url = Backend.api.replaceids(that, $(that).attr('href'));
|
||||
var title = $(that).attr("title") || $(that).data("title") || $(that).data('original-title');
|
||||
var button = Backend.api.gettablecolumnbutton(options);
|
||||
if (button && typeof button.callback === 'function') {
|
||||
options.callback = button.callback;
|
||||
}
|
||||
if (typeof options.confirm !== 'undefined') {
|
||||
Layer.confirm(options.confirm, function (index) {
|
||||
Backend.api.open(Backend.api.replaceids(that, $(that).attr('href')), $(that).attr('title'), options);
|
||||
Backend.api.open(url, title, options);
|
||||
Layer.close(index);
|
||||
});
|
||||
} else {
|
||||
Backend.api.open(Backend.api.replaceids(that, $(that).attr('href')), $(that).attr('title'), options);
|
||||
Backend.api.open(url, title, options);
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
|
@ -154,15 +160,16 @@ define(['fast', 'template', 'moment'], function (Fast, Template, Moment) {
|
|||
$(document).on('click', '.btn-addtabs,.addtabsit', function (e) {
|
||||
var that = this;
|
||||
var options = $.extend({}, $(that).data() || {});
|
||||
var url = Backend.api.replaceids(that, $(that).attr('href'));
|
||||
var title = $(that).attr("title") || $(that).data("title") || $(that).data('original-title');
|
||||
if (typeof options.confirm !== 'undefined') {
|
||||
Layer.confirm(options.confirm, function (index) {
|
||||
Backend.api.addtabs(Backend.api.replaceids(that, $(that).attr('href')), $(that).attr("title"));
|
||||
Backend.api.addtabs(url, title);
|
||||
Layer.close(index);
|
||||
});
|
||||
} else {
|
||||
Backend.api.addtabs(Backend.api.replaceids(that, $(that).attr('href')), $(that).attr("title"));
|
||||
Backend.api.addtabs(url, title);
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
//点击包含.btn-ajax的元素时发送Ajax请求
|
||||
|
|
@ -177,30 +184,13 @@ define(['fast', 'template', 'moment'], function (Fast, Template, Moment) {
|
|||
var error = typeof options.error === 'function' ? options.error : null;
|
||||
delete options.success;
|
||||
delete options.error;
|
||||
if (typeof options.tableId !== 'undefined' && typeof options.fieldIndex !== 'undefined' && typeof options.buttonIndex !== 'undefined') {
|
||||
var tableOptions = $("#" + options.tableId).bootstrapTable('getOptions');
|
||||
if (tableOptions) {
|
||||
var columnObj = null;
|
||||
$.each(tableOptions.columns, function (i, columns) {
|
||||
$.each(columns, function (j, column) {
|
||||
if (typeof column.fieldIndex !== 'undefined' && column.fieldIndex === options.fieldIndex) {
|
||||
columnObj = column;
|
||||
return false;
|
||||
}
|
||||
});
|
||||
if (columnObj) {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
if (columnObj) {
|
||||
var button = columnObj['buttons'][options.buttonIndex];
|
||||
if (button && typeof button.success === 'function') {
|
||||
success = button.success;
|
||||
}
|
||||
if (button && typeof button.error === 'function') {
|
||||
error = button.error;
|
||||
}
|
||||
}
|
||||
var button = Backend.api.gettablecolumnbutton(options);
|
||||
if (button) {
|
||||
if (typeof button.success === 'function') {
|
||||
success = button.success;
|
||||
}
|
||||
if (typeof button.error === 'function') {
|
||||
error = button.error;
|
||||
}
|
||||
}
|
||||
//如果未设备成功的回调,设定了自动刷新的情况下自动进行刷新
|
||||
|
|
@ -225,6 +215,19 @@ define(['fast', 'template', 'moment'], function (Fast, Template, Moment) {
|
|||
if ($(".layer-footer").size() > 0 && self === top) {
|
||||
$(".layer-footer").show();
|
||||
}
|
||||
//优化在多个弹窗下点击不能切换的操作体验
|
||||
if (Fast.api.query("dialog") == "1" && self != top && self.frameElement && self.frameElement.tagName == "IFRAME") {
|
||||
$(window).on('click', function () {
|
||||
var layero = self.frameElement.parentNode.parentElement;
|
||||
if (parent.Layer.zIndex != parseInt(parent.window.$(layero).css("z-index"))) {
|
||||
parent.window.$(layero).trigger("mousedown");
|
||||
parent.Layer.zIndex = parseInt(parent.window.$(layero).css("z-index"));
|
||||
}
|
||||
});
|
||||
}
|
||||
//tooltip和popover
|
||||
$('body').tooltip({selector: '[data-toggle="tooltip"]'});
|
||||
$('body').tooltip({selector: '[data-toggle="popover"]'});
|
||||
}
|
||||
};
|
||||
Backend.api = $.extend(Fast.api, Backend.api);
|
||||
|
|
|
|||
|
|
@ -49,13 +49,78 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'template'], function
|
|||
url: $.fn.bootstrapTable.defaults.extend.index_url,
|
||||
columns: [
|
||||
[
|
||||
{field: 'id', title: 'ID', operate: false},
|
||||
{field: 'name', title: __('Name'), operate: false},
|
||||
{field: 'title', title: __('Title'), operate: 'LIKE'}
|
||||
{field: 'id', title: 'ID', operate: false, visible: false},
|
||||
{
|
||||
field: 'home',
|
||||
title: __('Index'),
|
||||
width: '50px',
|
||||
formatter: Controller.api.formatter.home
|
||||
},
|
||||
{field: 'name', title: __('Name'), operate: false, visible: false, width: '120px'},
|
||||
{
|
||||
field: 'title',
|
||||
title: __('Title'),
|
||||
operate: 'LIKE',
|
||||
align: 'left',
|
||||
formatter: Controller.api.formatter.title
|
||||
},
|
||||
{field: 'intro', title: __('Intro'), operate: 'LIKE', align: 'left', class:'visible-lg'},
|
||||
{
|
||||
field: 'author',
|
||||
title: __('Author'),
|
||||
operate: 'LIKE',
|
||||
width: '100px',
|
||||
formatter: Controller.api.formatter.author
|
||||
},
|
||||
{
|
||||
field: 'price',
|
||||
title: __('Price'),
|
||||
operate: 'LIKE',
|
||||
width: '100px',
|
||||
align: 'center',
|
||||
formatter: Controller.api.formatter.price
|
||||
},
|
||||
{
|
||||
field: 'downloads',
|
||||
title: __('Downloads'),
|
||||
operate: 'LIKE',
|
||||
width: '100px',
|
||||
align: 'center',
|
||||
formatter: Controller.api.formatter.downloads
|
||||
},
|
||||
{
|
||||
field: 'version',
|
||||
title: __('Version'),
|
||||
operate: 'LIKE',
|
||||
width: '100px',
|
||||
align: 'center',
|
||||
formatter: Controller.api.formatter.version
|
||||
},
|
||||
{
|
||||
field: 'toggle',
|
||||
title: __('Status'),
|
||||
width: '100px',
|
||||
formatter: Controller.api.formatter.toggle
|
||||
},
|
||||
{
|
||||
field: 'id',
|
||||
title: __('Operate'),
|
||||
align: 'center',
|
||||
table: table,
|
||||
formatter: Controller.api.formatter.operate,
|
||||
align: 'right'
|
||||
},
|
||||
]
|
||||
],
|
||||
responseHandler: function (res) {
|
||||
$.each(res.rows, function (i, j) {
|
||||
j.addon = typeof Config.addons[j.name] != 'undefined' ? Config.addons[j.name] : null;
|
||||
});
|
||||
return res;
|
||||
},
|
||||
dataType: 'jsonp',
|
||||
templateView: true,
|
||||
templateView: false,
|
||||
clickToSelect: false,
|
||||
search: true,
|
||||
showColumns: false,
|
||||
showToggle: false,
|
||||
|
|
@ -71,41 +136,6 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'template'], function
|
|||
// 为表格绑定事件
|
||||
Table.api.bindevent(table);
|
||||
|
||||
table.on('click', '.btn-addoninfo', function (event) {
|
||||
var index = parseInt($(this).data("index"));
|
||||
var data = table.bootstrapTable("getData");
|
||||
var item = data[index];
|
||||
var addon = typeof Config.addons[item.name] != 'undefined' ? Config.addons[item.name] : null;
|
||||
Layer.alert(Template("addoninfotpl", {item: item, addon: addon}), {
|
||||
btn: [__('OK'), __('Donate'), __('Feedback'), __('Document')],
|
||||
title: __('Detail'),
|
||||
area: ['450px', '490px'],
|
||||
btn2: function () {
|
||||
//打赏
|
||||
Layer.open({
|
||||
content: Template("paytpl", {payimg: item.donateimage}),
|
||||
shade: 0.8,
|
||||
area: ['800px', '600px'],
|
||||
skin: 'layui-layer-msg layui-layer-pay',
|
||||
title: false,
|
||||
closeBtn: true,
|
||||
btn: false,
|
||||
resize: false,
|
||||
});
|
||||
},
|
||||
btn3: function () {
|
||||
return false;
|
||||
},
|
||||
btn4: function () {
|
||||
return false;
|
||||
},
|
||||
success: function (layero, index) {
|
||||
$(".layui-layer-btn2", layero).attr("href", "http://forum.fastadmin.net/t/bug?ref=addon&name=" + item.name).attr("target", "_blank");
|
||||
$(".layui-layer-btn3", layero).attr("href", "http://www.fastadmin.net/store/" + item.name + ".html?ref=addon").attr("target", "_blank");
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// 离线安装
|
||||
require(['upload'], function (Upload) {
|
||||
Upload.api.plupload("#plupload-addon", function (data, ret) {
|
||||
|
|
@ -224,22 +254,9 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'template'], function
|
|||
Layer.closeAll();
|
||||
Config['addons'][data.addon.name] = ret.data.addon;
|
||||
Layer.alert(__('Online installed tips'), {
|
||||
btn: [__('OK'), __('Donate')],
|
||||
btn: [__('OK')],
|
||||
title: __('Warning'),
|
||||
icon: 1,
|
||||
btn2: function () {
|
||||
//打赏
|
||||
Layer.open({
|
||||
content: Template("paytpl", {payimg: $(that).data("donateimage")}),
|
||||
shade: 0.8,
|
||||
area: ['800px', '600px'],
|
||||
skin: 'layui-layer-msg layui-layer-pay',
|
||||
title: false,
|
||||
closeBtn: true,
|
||||
btn: false,
|
||||
resize: false,
|
||||
});
|
||||
}
|
||||
icon: 1
|
||||
});
|
||||
$('.btn-refresh').trigger('click');
|
||||
Fast.api.refreshmenu();
|
||||
|
|
@ -261,17 +278,12 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'template'], function
|
|||
}
|
||||
});
|
||||
} else if (ret && ret.code === -2) {
|
||||
//跳转支付
|
||||
Layer.alert(__('Pay click tips'), {
|
||||
btn: [__('Pay now'), __('Cancel')],
|
||||
icon: 0,
|
||||
success: function (layero) {
|
||||
$(".layui-layer-btn0", layero).attr("href", ret.data.payurl).attr("target", "_blank");
|
||||
Fast.api.open(ret.data.payurl, __('Pay now'), {
|
||||
area: ["650px", "700px"],
|
||||
end: function () {
|
||||
Layer.alert(__('Pay tips'));
|
||||
}
|
||||
}, function () {
|
||||
Layer.alert(__('Pay new window tips'), {icon: 0});
|
||||
});
|
||||
|
||||
} else if (ret && ret.code === -3) {
|
||||
//插件目录发现影响全局的文件
|
||||
Layer.open({
|
||||
|
|
@ -408,7 +420,11 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'template'], function
|
|||
|
||||
// 点击卸载
|
||||
$(document).on("click", ".btn-uninstall", function () {
|
||||
var name = $(this).closest(".operate").data("name");
|
||||
var name = $(this).closest(".operate").data('name');
|
||||
if (Config['addons'][name].state == 1) {
|
||||
Layer.alert(__('Please disable addon first'), {icon: 7});
|
||||
return false;
|
||||
}
|
||||
Layer.confirm(__('Uninstall tips'), function () {
|
||||
uninstall(name, false);
|
||||
});
|
||||
|
|
@ -422,18 +438,18 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'template'], function
|
|||
|
||||
// 点击启用/禁用
|
||||
$(document).on("click", ".btn-enable,.btn-disable", function () {
|
||||
var name = $(this).closest(".operate").data("name");
|
||||
var name = $(this).data("name");
|
||||
var action = $(this).data("action");
|
||||
operate(name, action, false);
|
||||
});
|
||||
|
||||
// 点击升级
|
||||
$(document).on("click", ".btn-upgrade", function () {
|
||||
if ($(this).closest(".operate").find("a.btn-disable").size() > 0) {
|
||||
var name = $(this).closest(".operate").data('name');
|
||||
if (Config['addons'][name].state == 1) {
|
||||
Layer.alert(__('Please disable addon first'), {icon: 7});
|
||||
return false;
|
||||
}
|
||||
var name = $(this).closest(".operate").data("name");
|
||||
var version = $(this).data("version");
|
||||
|
||||
Layer.confirm(__('Upgrade tips'), function () {
|
||||
|
|
@ -444,6 +460,21 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'template'], function
|
|||
$(document).on("click", ".operate .btn-group .dropdown-toggle", function () {
|
||||
$(this).closest(".btn-group").toggleClass("dropup", $(document).height() - $(this).offset().top <= 200);
|
||||
});
|
||||
|
||||
$(document).on("click", ".view-screenshots", function () {
|
||||
var row = Table.api.getrowbyindex(table, parseInt($(this).data("index")));
|
||||
var data = [];
|
||||
$.each(row.screenshots, function (i, j) {
|
||||
data.push({
|
||||
"src": "http://www.fh.com" + j
|
||||
});
|
||||
});
|
||||
var json = {
|
||||
"title": row.title,
|
||||
"data": data
|
||||
};
|
||||
top.Layer.photos(top.JSON.parse(JSON.stringify({photos: json})));
|
||||
});
|
||||
},
|
||||
add: function () {
|
||||
Controller.api.bindevent();
|
||||
|
|
@ -452,6 +483,39 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'template'], function
|
|||
Controller.api.bindevent();
|
||||
},
|
||||
api: {
|
||||
formatter: {
|
||||
title: function (value, row, index) {
|
||||
var title = '<a class="title" href="' + row.url + '" data-toggle="tooltip" title="' + __('View addon home page') + '" target="_blank">' + value + '</a>';
|
||||
if (row.screenshots.length > 0) {
|
||||
title += ' <a href="javascript:;" data-index="' + index + '" class="view-screenshots text-success" title="' + __('View addon screenshots') + '" data-toggle="tooltip"><i class="fa fa-image"></i></a>';
|
||||
}
|
||||
return title;
|
||||
},
|
||||
operate: function (value, row, index) {
|
||||
return Template("operatetpl", {item: row, index: index});
|
||||
},
|
||||
toggle: function (value, row, index) {
|
||||
if (!row.addon) {
|
||||
return '';
|
||||
}
|
||||
return '<a href="javascript:;" data-toggle="tooltip" title="' + __('Click to toggle status') + '" class="btn-' + (row.addon.state == 1 ? "disable" : "enable") + '" data-action="' + (row.addon.state == 1 ? "disable" : "enable") + '" data-name="' + row.name + '"><i class="fa ' + (row.addon.state == 0 ? 'fa-toggle-on fa-rotate-180 text-gray' : 'fa-toggle-on text-success') + ' fa-2x"></i></a>';
|
||||
},
|
||||
author: function (value, row, index) {
|
||||
return '<a href="https://wpa.qq.com/msgrd?v=3&uin=' + row.qq + '&site=fastadmin.net&menu=yes" target="_blank" data-toggle="tooltip" title="'+__('Click to contact developer')+'" class="text-primary">' + value + '</a>';
|
||||
},
|
||||
price: function (value, row, index) {
|
||||
return parseFloat(value) == 0 ? '<span class="text-success">' + __('Free') + '</span>' : '<span class="text-danger">¥' + value + '</span>';
|
||||
},
|
||||
downloads: function (value, row, index) {
|
||||
return value;
|
||||
},
|
||||
version: function (value, row, index) {
|
||||
return row.addon && row.addon.version != row.version ? '<span class="releasetips" data-toggle="tooltip" title="' + __('New version') + ':' + row.version + '">' + row.addon.version + '<i></i></span>' : row.version;
|
||||
},
|
||||
home: function (value, row, index) {
|
||||
return row.addon ? '<a href="' + row.addon.url + '" data-toggle="tooltip" title="' + __('View addon index page') + '" target="_blank"><i class="fa fa-home text-primary"></i></a>' : '<a href="javascript:;"><i class="fa fa-home text-gray"></i></a>';
|
||||
},
|
||||
},
|
||||
bindevent: function () {
|
||||
Form.api.bindevent($("form[role=form]"));
|
||||
},
|
||||
|
|
|
|||
|
|
@ -15,6 +15,15 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
|
|||
|
||||
var table = $("#table");
|
||||
|
||||
//在表格内容渲染完成后回调的事件
|
||||
table.on('post-body.bs.table', function (e, json) {
|
||||
$("tbody tr[data-index]", this).each(function () {
|
||||
if (parseInt($("td:eq(1)", this).text()) == Config.admin.id) {
|
||||
$("input[type=checkbox]", this).prop("disabled", true);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// 初始化表格
|
||||
table.bootstrapTable({
|
||||
url: $.fn.bootstrapTable.defaults.extend.index_url,
|
||||
|
|
@ -27,7 +36,7 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
|
|||
{field: 'groups_text', title: __('Group'), operate:false, formatter: Table.api.formatter.label},
|
||||
{field: 'email', title: __('Email')},
|
||||
{field: 'status', title: __("Status"), formatter: Table.api.formatter.status},
|
||||
{field: 'logintime', title: __('Login time'), formatter: Table.api.formatter.datetime},
|
||||
{field: 'logintime', title: __('Login time'), formatter: Table.api.formatter.datetime, operate: 'RANGE', addclass: 'datetimerange', sortable: true},
|
||||
{field: 'operate', title: __('Operate'), table: table, events: Table.api.events.operate, formatter: function (value, row, index) {
|
||||
if(row.id == Config.admin.id){
|
||||
return '';
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
|
|||
{field: 'url', title: __('Url'), align: 'left', formatter: Table.api.formatter.url},
|
||||
{field: 'ip', title: __('IP'), events: Table.api.events.ip, formatter: Table.api.formatter.search},
|
||||
{field: 'browser', title: __('Browser'), operate: false, formatter: Controller.api.formatter.browser},
|
||||
{field: 'createtime', title: __('Create time'), formatter: Table.api.formatter.datetime, operate: 'BETWEEN', type: 'datetime', addclass: 'datetimepicker', data: 'data-date-format="YYYY-MM-DD HH:mm:ss"'},
|
||||
{field: 'createtime', title: __('Create time'), formatter: Table.api.formatter.datetime, operate: 'RANGE', addclass: 'datetimerange', sortable: true},
|
||||
{field: 'operate', title: __('Operate'), table: table,
|
||||
events: Table.api.events.operate,
|
||||
buttons: [{
|
||||
|
|
|
|||
|
|
@ -30,6 +30,15 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'jstree'], function (
|
|||
|
||||
var table = $("#table");
|
||||
|
||||
//在表格内容渲染完成后回调的事件
|
||||
table.on('post-body.bs.table', function (e, json) {
|
||||
$("tbody tr[data-index]", this).each(function () {
|
||||
if (Config.admin.group_ids.indexOf(parseInt(parseInt($("td:eq(1)", this).text()))) > -1) {
|
||||
$("input[type=checkbox]", this).prop("disabled", true);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// 初始化表格
|
||||
table.bootstrapTable({
|
||||
url: $.fn.bootstrapTable.defaults.extend.index_url,
|
||||
|
|
|
|||
|
|
@ -23,16 +23,32 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'template'], function
|
|||
escape: false,
|
||||
columns: [
|
||||
[
|
||||
{field: 'state', checkbox: true, },
|
||||
{field: 'state', checkbox: true,},
|
||||
{field: 'id', title: 'ID'},
|
||||
{field: 'title', title: __('Title'), align: 'left', formatter: Controller.api.formatter.title},
|
||||
{field: 'icon', title: __('Icon'), formatter: Controller.api.formatter.icon},
|
||||
{field: 'name', title: __('Name'), align: 'left', formatter: Controller.api.formatter.name},
|
||||
{field: 'weigh', title: __('Weigh')},
|
||||
{field: 'status', title: __('Status'), formatter: Table.api.formatter.status},
|
||||
{field: 'ismenu', title: __('Ismenu'), align: 'center', formatter: Controller.api.formatter.menu},
|
||||
{field: 'id', title: '<a href="javascript:;" class="btn btn-success btn-xs btn-toggle"><i class="fa fa-chevron-up"></i></a>', operate: false, formatter: Controller.api.formatter.subnode},
|
||||
{field: 'operate', title: __('Operate'), table: table, events: Table.api.events.operate, formatter: Table.api.formatter.operate}
|
||||
{
|
||||
field: 'ismenu',
|
||||
title: __('Ismenu'),
|
||||
align: 'center',
|
||||
formatter: Controller.api.formatter.menu
|
||||
},
|
||||
{
|
||||
field: 'id',
|
||||
title: '<a href="javascript:;" class="btn btn-success btn-xs btn-toggle"><i class="fa fa-chevron-up"></i></a>',
|
||||
operate: false,
|
||||
formatter: Controller.api.formatter.subnode
|
||||
},
|
||||
{
|
||||
field: 'operate',
|
||||
title: __('Operate'),
|
||||
table: table,
|
||||
events: Table.api.events.operate,
|
||||
formatter: Table.api.formatter.operate
|
||||
}
|
||||
]
|
||||
],
|
||||
pagination: false,
|
||||
|
|
@ -102,15 +118,15 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'template'], function
|
|||
return !row.ismenu || row.status == 'hidden' ? "<span class='text-muted'>" + value + "</span>" : value;
|
||||
},
|
||||
menu: function (value, row, index) {
|
||||
return "<a href='javascript:;' class='btn btn-" + (value ? "info" : "default") + " btn-xs btn-change' data-id='"
|
||||
+ row.id + "' data-params='ismenu=" + (value ? 0 : 1) + "'>" + (value ? __('Yes') : __('No')) + "</a>";
|
||||
return "<a href='javascript:;' data-toggle='tooltip' title='" + __('Toggle menu visible') + "' class='btn btn-" + (value ? "info" : "default") + " btn-xs btn-change' data-id='"
|
||||
+ row.id + "' data-params='ismenu=" + (value ? 0 : 1) + "'>" + (value ? __('Yes') : __('No')) + "</a>";
|
||||
},
|
||||
icon: function (value, row, index) {
|
||||
return '<span class="' + (!row.ismenu || row.status == 'hidden' ? 'text-muted' : '') + '"><i class="' + value + '"></i></span>';
|
||||
},
|
||||
subnode: function (value, row, index) {
|
||||
return '<a href="javascript:;" data-id="' + row.id + '" data-pid="' + row.pid + '" class="btn btn-xs '
|
||||
+ (row.haschild == 1 || row.ismenu == 1 ? 'btn-success' : 'btn-default disabled') + ' btn-node-sub"><i class="fa fa-sitemap"></i></a>';
|
||||
return '<a href="javascript:;" data-toggle="tooltip" title="' + __('Toggle sub menu') + '" data-id="' + row.id + '" data-pid="' + row.pid + '" class="btn btn-xs '
|
||||
+ (row.haschild == 1 || row.ismenu == 1 ? 'btn-success' : 'btn-default disabled') + ' btn-node-sub"><i class="fa fa-sitemap"></i></a>';
|
||||
}
|
||||
},
|
||||
bindevent: function () {
|
||||
|
|
@ -121,6 +137,13 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'template'], function
|
|||
$("input[name='row[ismenu]']:checked").trigger("click");
|
||||
|
||||
var iconlist = [];
|
||||
var iconfunc = function () {
|
||||
Layer.open({
|
||||
type: 1,
|
||||
area: ['99%', '98%'], //宽高
|
||||
content: Template('chooseicontpl', {iconlist: iconlist})
|
||||
});
|
||||
};
|
||||
Form.api.bindevent($("form[role=form]"), function (data) {
|
||||
Fast.api.refreshmenu();
|
||||
});
|
||||
|
|
@ -132,18 +155,10 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'template'], function
|
|||
while ((result = exp.exec(ret)) != null) {
|
||||
iconlist.push(result[1]);
|
||||
}
|
||||
Layer.open({
|
||||
type: 1,
|
||||
area: ['460px', '300px'], //宽高
|
||||
content: Template('chooseicontpl', {iconlist: iconlist})
|
||||
});
|
||||
iconfunc();
|
||||
});
|
||||
} else {
|
||||
Layer.open({
|
||||
type: 1,
|
||||
area: ['460px', '300px'], //宽高
|
||||
content: Template('chooseicontpl', {iconlist: iconlist})
|
||||
});
|
||||
iconfunc();
|
||||
}
|
||||
});
|
||||
$(document).on('click', '#chooseicon ul li', function () {
|
||||
|
|
|
|||
|
|
@ -22,18 +22,31 @@ define(['jquery', 'bootstrap', 'backend', 'form', 'table'], function ($, undefin
|
|||
sortName: 'id',
|
||||
columns: [
|
||||
[
|
||||
{field: 'state', checkbox: true, },
|
||||
{field: 'state', checkbox: true,},
|
||||
{field: 'id', title: __('Id')},
|
||||
{field: 'url', title: __('Preview'), formatter: Controller.api.formatter.thumb},
|
||||
{field: 'url', title: __('Preview'), formatter: Controller.api.formatter.thumb, operate: false},
|
||||
{field: 'url', title: __('Url'), formatter: Controller.api.formatter.url},
|
||||
{field: 'imagewidth', title: __('Imagewidth')},
|
||||
{field: 'imageheight', title: __('Imageheight')},
|
||||
{field: 'imagetype', title: __('Imagetype')},
|
||||
{field: 'storage', title: __('Storage')},
|
||||
{field: 'filesize', title: __('Filesize')},
|
||||
{field: 'mimetype', title: __('Mimetype')},
|
||||
{field: 'createtime', title: __('Createtime'), formatter: Table.api.formatter.datetime},
|
||||
{field: 'operate', title: __('Operate'), table: table, events: Table.api.events.operate, formatter: Table.api.formatter.operate}
|
||||
{field: 'imagewidth', title: __('Imagewidth'), sortable: true},
|
||||
{field: 'imageheight', title: __('Imageheight'), sortable: true},
|
||||
{field: 'imagetype', title: __('Imagetype'), formatter:Table.api.formatter.search},
|
||||
{field: 'storage', title: __('Storage'), formatter: Table.api.formatter.search},
|
||||
{field: 'filesize', title: __('Filesize'), operate: 'BETWEEN', sortable: true},
|
||||
{field: 'mimetype', title: __('Mimetype'), formatter:Table.api.formatter.search},
|
||||
{
|
||||
field: 'createtime',
|
||||
title: __('Createtime'),
|
||||
formatter: Table.api.formatter.datetime,
|
||||
operate: 'RANGE',
|
||||
addclass: 'datetimerange',
|
||||
sortable: true
|
||||
},
|
||||
{
|
||||
field: 'operate',
|
||||
title: __('Operate'),
|
||||
table: table,
|
||||
events: Table.api.events.operate,
|
||||
formatter: Table.api.formatter.operate
|
||||
}
|
||||
]
|
||||
],
|
||||
});
|
||||
|
|
@ -58,17 +71,20 @@ define(['jquery', 'bootstrap', 'backend', 'form', 'table'], function ($, undefin
|
|||
sortName: 'id',
|
||||
columns: [
|
||||
[
|
||||
{field: 'state', checkbox: true, },
|
||||
{field: 'state', checkbox: true,},
|
||||
{field: 'id', title: __('Id')},
|
||||
{field: 'url', title: __('Preview'), formatter: Controller.api.formatter.thumb},
|
||||
{field: 'imagewidth', title: __('Imagewidth')},
|
||||
{field: 'imageheight', title: __('Imageheight')},
|
||||
{field: 'mimetype', title: __('Mimetype'), operate: 'LIKE %...%',
|
||||
{
|
||||
field: 'mimetype', title: __('Mimetype'), operate: 'LIKE %...%',
|
||||
process: function (value, arg) {
|
||||
return value.replace(/\*/g, '%');
|
||||
}},
|
||||
{field: 'createtime', title: __('Createtime'), formatter: Table.api.formatter.datetime},
|
||||
{field: 'operate', title: __('Operate'), events: {
|
||||
}
|
||||
},
|
||||
{field: 'createtime', title: __('Createtime'), formatter: Table.api.formatter.datetime, operate: 'RANGE', addclass: 'datetimerange', sortable: true},
|
||||
{
|
||||
field: 'operate', title: __('Operate'), events: {
|
||||
'click .btn-chooseone': function (e, value, row, index) {
|
||||
var multiple = Backend.api.query('multiple');
|
||||
multiple = multiple == 'true' ? true : false;
|
||||
|
|
@ -76,7 +92,8 @@ define(['jquery', 'bootstrap', 'backend', 'form', 'table'], function ($, undefin
|
|||
},
|
||||
}, formatter: function () {
|
||||
return '<a href="javascript:;" class="btn btn-danger btn-chooseone btn-xs"><i class="fa fa-check"></i> ' + __('Choose') + '</a>';
|
||||
}}
|
||||
}
|
||||
}
|
||||
]
|
||||
]
|
||||
});
|
||||
|
|
|
|||
|
|
@ -29,7 +29,13 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
|
|||
{field: 'intro', title: __('Intro')},
|
||||
{field: 'group', title: __('Group')},
|
||||
{field: 'type', title: __('Type')},
|
||||
{field: 'operate', title: __('Operate'), table: table, events: Table.api.events.operate, formatter: Table.api.formatter.operate}
|
||||
{
|
||||
field: 'operate',
|
||||
title: __('Operate'),
|
||||
table: table,
|
||||
events: Table.api.events.operate,
|
||||
formatter: Table.api.formatter.operate
|
||||
}
|
||||
]
|
||||
]
|
||||
});
|
||||
|
|
@ -58,7 +64,14 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
|
|||
//添加向发件人发送测试邮件按钮和方法
|
||||
$('input[name="row[mail_from]"]').parent().next().append('<a class="btn btn-info testmail">' + __('Send a test message') + '</a>');
|
||||
$(document).on("click", ".testmail", function () {
|
||||
Backend.api.ajax({url: "general/config/emailtest", data: {receiver: $('input[name="row[mail_from]"]').val()}});
|
||||
var that = this;
|
||||
Layer.prompt({title: __('Please input your email'), formType: 0}, function (value, index) {
|
||||
Backend.api.ajax({
|
||||
url: "general/config/emailtest?receiver=" + value,
|
||||
data: $(that).closest("form").serialize()
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
},
|
||||
add: function () {
|
||||
|
|
|
|||
|
|
@ -27,8 +27,8 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'upload'], function (
|
|||
{field: 'id', title: 'ID'},
|
||||
{field: 'title', title: __('Title')},
|
||||
{field: 'url', title: __('Url'), align: 'left', formatter: Table.api.formatter.url},
|
||||
{field: 'ip', title: __('ip')},
|
||||
{field: 'createtime', title: __('Createtime'), formatter: Table.api.formatter.datetime},
|
||||
{field: 'ip', title: __('ip'), formatter:Table.api.formatter.search},
|
||||
{field: 'createtime', title: __('Createtime'), formatter: Table.api.formatter.datetime, operate: 'RANGE', addclass: 'datetimerange', sortable: true},
|
||||
]
|
||||
],
|
||||
commonSearch: false
|
||||
|
|
|
|||
|
|
@ -41,8 +41,8 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'jstree'], function (
|
|||
{checkbox: true},
|
||||
{field: 'id', title: __('Id')},
|
||||
{field: 'name', title: __('Name')},
|
||||
{field: 'createtime', title: __('Createtime'), formatter: Table.api.formatter.datetime},
|
||||
{field: 'updatetime', title: __('Updatetime'), formatter: Table.api.formatter.datetime},
|
||||
{field: 'createtime', title: __('Createtime'), formatter: Table.api.formatter.datetime, operate: 'RANGE', addclass: 'datetimerange', sortable: true},
|
||||
{field: 'updatetime', title: __('Updatetime'), formatter: Table.api.formatter.datetime, operate: 'RANGE', addclass: 'datetimerange', sortable: true},
|
||||
{field: 'status', title: __('Status'), formatter: Table.api.formatter.status},
|
||||
{field: 'operate', title: __('Operate'), table: table, events: Table.api.events.operate, formatter: Table.api.formatter.operate}
|
||||
]
|
||||
|
|
|
|||
|
|
@ -31,8 +31,8 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
|
|||
{field: 'name', title: __('Name'), align: 'left'},
|
||||
{field: 'remark', title: __('Remark')},
|
||||
{field: 'ismenu', title: __('Ismenu'), formatter: Controller.api.formatter.toggle},
|
||||
{field: 'createtime', title: __('Createtime'), formatter: Table.api.formatter.datetime, visible: false},
|
||||
{field: 'updatetime', title: __('Updatetime'), formatter: Table.api.formatter.datetime, visible: false},
|
||||
{field: 'createtime', title: __('Createtime'), formatter: Table.api.formatter.datetime, operate: 'RANGE', addclass: 'datetimerange', sortable: true, visible: false},
|
||||
{field: 'updatetime', title: __('Updatetime'), formatter: Table.api.formatter.datetime, operate: 'RANGE', addclass: 'datetimerange', sortable: true, visible: false},
|
||||
{field: 'weigh', title: __('Weigh')},
|
||||
{field: 'status', title: __('Status'), formatter: Table.api.formatter.status},
|
||||
{field: 'operate', title: __('Operate'), table: table, events: Table.api.events.operate, formatter: Table.api.formatter.operate}
|
||||
|
|
|
|||
|
|
@ -105,7 +105,7 @@ define(['jquery', 'bootstrap', 'toastr', 'layer', 'lang'], function ($, undefine
|
|||
}
|
||||
name = name.replace(/[\[\]]/g, "\\$&");
|
||||
var regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"),
|
||||
results = regex.exec(url);
|
||||
results = regex.exec(url);
|
||||
if (!results)
|
||||
return null;
|
||||
if (!results[2])
|
||||
|
|
@ -134,31 +134,42 @@ define(['jquery', 'bootstrap', 'toastr', 'layer', 'lang'], function ($, undefine
|
|||
$(layero).data("callback", that.callback);
|
||||
//$(layero).removeClass("layui-layer-border");
|
||||
Layer.setTop(layero);
|
||||
var frame = Layer.getChildFrame('html', index);
|
||||
var layerfooter = frame.find(".layer-footer");
|
||||
Fast.api.layerfooter(layero, index, that);
|
||||
try {
|
||||
var frame = Layer.getChildFrame('html', index);
|
||||
var layerfooter = frame.find(".layer-footer");
|
||||
Fast.api.layerfooter(layero, index, that);
|
||||
|
||||
//绑定事件
|
||||
if (layerfooter.size() > 0) {
|
||||
// 监听窗口内的元素及属性变化
|
||||
// Firefox和Chrome早期版本中带有前缀
|
||||
var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver;
|
||||
if (MutationObserver) {
|
||||
// 选择目标节点
|
||||
var target = layerfooter[0];
|
||||
// 创建观察者对象
|
||||
var observer = new MutationObserver(function (mutations) {
|
||||
Fast.api.layerfooter(layero, index, that);
|
||||
mutations.forEach(function (mutation) {
|
||||
//绑定事件
|
||||
if (layerfooter.size() > 0) {
|
||||
// 监听窗口内的元素及属性变化
|
||||
// Firefox和Chrome早期版本中带有前缀
|
||||
var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver;
|
||||
if (MutationObserver) {
|
||||
// 选择目标节点
|
||||
var target = layerfooter[0];
|
||||
// 创建观察者对象
|
||||
var observer = new MutationObserver(function (mutations) {
|
||||
Fast.api.layerfooter(layero, index, that);
|
||||
mutations.forEach(function (mutation) {
|
||||
});
|
||||
});
|
||||
});
|
||||
// 配置观察选项:
|
||||
var config = {attributes: true, childList: true, characterData: true, subtree: true}
|
||||
// 传入目标节点和观察选项
|
||||
observer.observe(target, config);
|
||||
// 随后,你还可以停止观察
|
||||
// observer.disconnect();
|
||||
// 配置观察选项:
|
||||
var config = {attributes: true, childList: true, characterData: true, subtree: true}
|
||||
// 传入目标节点和观察选项
|
||||
observer.observe(target, config);
|
||||
// 随后,你还可以停止观察
|
||||
// observer.disconnect();
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
|
||||
}
|
||||
if ($(layero).height() > $(window).height()) {
|
||||
//当弹出窗口大于浏览器可视高度时,重定位
|
||||
Layer.style(index, {
|
||||
top: 0,
|
||||
height: $(window).height()
|
||||
});
|
||||
}
|
||||
}
|
||||
}, options ? options : {});
|
||||
|
|
@ -234,8 +245,8 @@ define(['jquery', 'bootstrap', 'toastr', 'layer', 'lang'], function ($, undefine
|
|||
},
|
||||
lang: function () {
|
||||
var args = arguments,
|
||||
string = args[0],
|
||||
i = 1;
|
||||
string = args[0],
|
||||
i = 1;
|
||||
string = string.toLowerCase();
|
||||
//string = typeof Lang[string] != 'undefined' ? Lang[string] : string;
|
||||
if (typeof Lang[string] != 'undefined') {
|
||||
|
|
|
|||
|
|
@ -49,7 +49,9 @@ define(['fast', 'template'], function (Fast, Template) {
|
|||
|
||||
return false;
|
||||
});
|
||||
|
||||
//tooltip和popover
|
||||
$('body').tooltip({selector: '[data-toggle="tooltip"]'});
|
||||
$('body').tooltip({selector: '[data-toggle="popover"]'});
|
||||
}
|
||||
};
|
||||
Frontend.api = $.extend(Fast.api, Frontend.api);
|
||||
|
|
|
|||
|
|
@ -759,7 +759,7 @@ define('fast',['jquery', 'bootstrap', 'toastr', 'layer', 'lang'], function ($, u
|
|||
}
|
||||
name = name.replace(/[\[\]]/g, "\\$&");
|
||||
var regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"),
|
||||
results = regex.exec(url);
|
||||
results = regex.exec(url);
|
||||
if (!results)
|
||||
return null;
|
||||
if (!results[2])
|
||||
|
|
@ -788,31 +788,42 @@ define('fast',['jquery', 'bootstrap', 'toastr', 'layer', 'lang'], function ($, u
|
|||
$(layero).data("callback", that.callback);
|
||||
//$(layero).removeClass("layui-layer-border");
|
||||
Layer.setTop(layero);
|
||||
var frame = Layer.getChildFrame('html', index);
|
||||
var layerfooter = frame.find(".layer-footer");
|
||||
Fast.api.layerfooter(layero, index, that);
|
||||
try {
|
||||
var frame = Layer.getChildFrame('html', index);
|
||||
var layerfooter = frame.find(".layer-footer");
|
||||
Fast.api.layerfooter(layero, index, that);
|
||||
|
||||
//绑定事件
|
||||
if (layerfooter.size() > 0) {
|
||||
// 监听窗口内的元素及属性变化
|
||||
// Firefox和Chrome早期版本中带有前缀
|
||||
var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver;
|
||||
if (MutationObserver) {
|
||||
// 选择目标节点
|
||||
var target = layerfooter[0];
|
||||
// 创建观察者对象
|
||||
var observer = new MutationObserver(function (mutations) {
|
||||
Fast.api.layerfooter(layero, index, that);
|
||||
mutations.forEach(function (mutation) {
|
||||
//绑定事件
|
||||
if (layerfooter.size() > 0) {
|
||||
// 监听窗口内的元素及属性变化
|
||||
// Firefox和Chrome早期版本中带有前缀
|
||||
var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver;
|
||||
if (MutationObserver) {
|
||||
// 选择目标节点
|
||||
var target = layerfooter[0];
|
||||
// 创建观察者对象
|
||||
var observer = new MutationObserver(function (mutations) {
|
||||
Fast.api.layerfooter(layero, index, that);
|
||||
mutations.forEach(function (mutation) {
|
||||
});
|
||||
});
|
||||
});
|
||||
// 配置观察选项:
|
||||
var config = {attributes: true, childList: true, characterData: true, subtree: true}
|
||||
// 传入目标节点和观察选项
|
||||
observer.observe(target, config);
|
||||
// 随后,你还可以停止观察
|
||||
// observer.disconnect();
|
||||
// 配置观察选项:
|
||||
var config = {attributes: true, childList: true, characterData: true, subtree: true}
|
||||
// 传入目标节点和观察选项
|
||||
observer.observe(target, config);
|
||||
// 随后,你还可以停止观察
|
||||
// observer.disconnect();
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
|
||||
}
|
||||
if ($(layero).height() > $(window).height()) {
|
||||
//当弹出窗口大于浏览器可视高度时,重定位
|
||||
Layer.style(index, {
|
||||
top: 0,
|
||||
height: $(window).height()
|
||||
});
|
||||
}
|
||||
}
|
||||
}, options ? options : {});
|
||||
|
|
@ -888,8 +899,8 @@ define('fast',['jquery', 'bootstrap', 'toastr', 'layer', 'lang'], function ($, u
|
|||
},
|
||||
lang: function () {
|
||||
var args = arguments,
|
||||
string = args[0],
|
||||
i = 1;
|
||||
string = args[0],
|
||||
i = 1;
|
||||
string = string.toLowerCase();
|
||||
//string = typeof Lang[string] != 'undefined' ? Lang[string] : string;
|
||||
if (typeof Lang[string] != 'undefined') {
|
||||
|
|
@ -5318,20 +5329,8 @@ define('backend',['fast', 'template', 'moment'], function (Fast, Template, Momen
|
|||
},
|
||||
refreshmenu: function () {
|
||||
top.window.$(".sidebar-menu").trigger("refresh");
|
||||
}
|
||||
},
|
||||
init: function () {
|
||||
//公共代码
|
||||
//添加ios-fix兼容iOS下的iframe
|
||||
if (/iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream) {
|
||||
$("html").addClass("ios-fix");
|
||||
}
|
||||
//配置Toastr的参数
|
||||
Toastr.options.positionClass = Config.controllername === 'index' ? "toast-top-right-index" : "toast-top-right";
|
||||
//点击包含.btn-dialog的元素时弹出dialog
|
||||
$(document).on('click', '.btn-dialog,.dialogit', function (e) {
|
||||
var that = this;
|
||||
var options = $.extend({}, $(that).data() || {});
|
||||
},
|
||||
gettablecolumnbutton: function(options){
|
||||
if (typeof options.tableId !== 'undefined' && typeof options.fieldIndex !== 'undefined' && typeof options.buttonIndex !== 'undefined') {
|
||||
var tableOptions = $("#" + options.tableId).bootstrapTable('getOptions');
|
||||
if (tableOptions) {
|
||||
|
|
@ -5348,20 +5347,38 @@ define('backend',['fast', 'template', 'moment'], function (Fast, Template, Momen
|
|||
}
|
||||
});
|
||||
if (columnObj) {
|
||||
var button = columnObj['buttons'][options.buttonIndex];
|
||||
if (button && typeof button.callback === 'function') {
|
||||
options.callback = button.callback;
|
||||
}
|
||||
return columnObj['buttons'][options.buttonIndex];
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
},
|
||||
},
|
||||
init: function () {
|
||||
//公共代码
|
||||
//添加ios-fix兼容iOS下的iframe
|
||||
if (/iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream) {
|
||||
$("html").addClass("ios-fix");
|
||||
}
|
||||
//配置Toastr的参数
|
||||
Toastr.options.positionClass = Config.controllername === 'index' ? "toast-top-right-index" : "toast-top-right";
|
||||
//点击包含.btn-dialog的元素时弹出dialog
|
||||
$(document).on('click', '.btn-dialog,.dialogit', function (e) {
|
||||
var that = this;
|
||||
var options = $.extend({}, $(that).data() || {});
|
||||
var url = Backend.api.replaceids(that, $(that).attr('href'));
|
||||
var title = $(that).attr("title") || $(that).data("title") || $(that).data('original-title');
|
||||
var button = Backend.api.gettablecolumnbutton(options);
|
||||
if (button && typeof button.callback === 'function') {
|
||||
options.callback = button.callback;
|
||||
}
|
||||
if (typeof options.confirm !== 'undefined') {
|
||||
Layer.confirm(options.confirm, function (index) {
|
||||
Backend.api.open(Backend.api.replaceids(that, $(that).attr('href')), $(that).attr('title'), options);
|
||||
Backend.api.open(url, title, options);
|
||||
Layer.close(index);
|
||||
});
|
||||
} else {
|
||||
Backend.api.open(Backend.api.replaceids(that, $(that).attr('href')), $(that).attr('title'), options);
|
||||
Backend.api.open(url, title, options);
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
|
@ -5369,15 +5386,16 @@ define('backend',['fast', 'template', 'moment'], function (Fast, Template, Momen
|
|||
$(document).on('click', '.btn-addtabs,.addtabsit', function (e) {
|
||||
var that = this;
|
||||
var options = $.extend({}, $(that).data() || {});
|
||||
var url = Backend.api.replaceids(that, $(that).attr('href'));
|
||||
var title = $(that).attr("title") || $(that).data("title") || $(that).data('original-title');
|
||||
if (typeof options.confirm !== 'undefined') {
|
||||
Layer.confirm(options.confirm, function (index) {
|
||||
Backend.api.addtabs(Backend.api.replaceids(that, $(that).attr('href')), $(that).attr("title"));
|
||||
Backend.api.addtabs(url, title);
|
||||
Layer.close(index);
|
||||
});
|
||||
} else {
|
||||
Backend.api.addtabs(Backend.api.replaceids(that, $(that).attr('href')), $(that).attr("title"));
|
||||
Backend.api.addtabs(url, title);
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
//点击包含.btn-ajax的元素时发送Ajax请求
|
||||
|
|
@ -5392,30 +5410,13 @@ define('backend',['fast', 'template', 'moment'], function (Fast, Template, Momen
|
|||
var error = typeof options.error === 'function' ? options.error : null;
|
||||
delete options.success;
|
||||
delete options.error;
|
||||
if (typeof options.tableId !== 'undefined' && typeof options.fieldIndex !== 'undefined' && typeof options.buttonIndex !== 'undefined') {
|
||||
var tableOptions = $("#" + options.tableId).bootstrapTable('getOptions');
|
||||
if (tableOptions) {
|
||||
var columnObj = null;
|
||||
$.each(tableOptions.columns, function (i, columns) {
|
||||
$.each(columns, function (j, column) {
|
||||
if (typeof column.fieldIndex !== 'undefined' && column.fieldIndex === options.fieldIndex) {
|
||||
columnObj = column;
|
||||
return false;
|
||||
}
|
||||
});
|
||||
if (columnObj) {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
if (columnObj) {
|
||||
var button = columnObj['buttons'][options.buttonIndex];
|
||||
if (button && typeof button.success === 'function') {
|
||||
success = button.success;
|
||||
}
|
||||
if (button && typeof button.error === 'function') {
|
||||
error = button.error;
|
||||
}
|
||||
}
|
||||
var button = Backend.api.gettablecolumnbutton(options);
|
||||
if (button) {
|
||||
if (typeof button.success === 'function') {
|
||||
success = button.success;
|
||||
}
|
||||
if (typeof button.error === 'function') {
|
||||
error = button.error;
|
||||
}
|
||||
}
|
||||
//如果未设备成功的回调,设定了自动刷新的情况下自动进行刷新
|
||||
|
|
@ -5440,6 +5441,19 @@ define('backend',['fast', 'template', 'moment'], function (Fast, Template, Momen
|
|||
if ($(".layer-footer").size() > 0 && self === top) {
|
||||
$(".layer-footer").show();
|
||||
}
|
||||
//优化在多个弹窗下点击不能切换的操作体验
|
||||
if (Fast.api.query("dialog") == "1" && self != top && self.frameElement && self.frameElement.tagName == "IFRAME") {
|
||||
$(window).on('click', function () {
|
||||
var layero = self.frameElement.parentNode.parentElement;
|
||||
if (parent.Layer.zIndex != parseInt(parent.window.$(layero).css("z-index"))) {
|
||||
parent.window.$(layero).trigger("mousedown");
|
||||
parent.Layer.zIndex = parseInt(parent.window.$(layero).css("z-index"));
|
||||
}
|
||||
});
|
||||
}
|
||||
//tooltip和popover
|
||||
$('body').tooltip({selector: '[data-toggle="tooltip"]'});
|
||||
$('body').tooltip({selector: '[data-toggle="popover"]'});
|
||||
}
|
||||
};
|
||||
Backend.api = $.extend(Fast.api, Backend.api);
|
||||
|
|
@ -8434,10 +8448,10 @@ define('form',['jquery', 'bootstrap', 'upload', 'validator'], function ($, undef
|
|||
},
|
||||
valid: function (ret) {
|
||||
var that = this, submitBtn = $(".layer-footer [type=submit]", form);
|
||||
that.holdSubmit();
|
||||
$(".layer-footer [type=submit]", form).addClass("disabled");
|
||||
that.holdSubmit(true);
|
||||
submitBtn.addClass("disabled");
|
||||
//验证通过提交表单
|
||||
Form.api.submit($(ret), function (data, ret) {
|
||||
var submitResult = Form.api.submit($(ret), function (data, ret) {
|
||||
that.holdSubmit(false);
|
||||
submitBtn.removeClass("disabled");
|
||||
if (false === $(this).triggerHandler("success.form", [data, ret])) {
|
||||
|
|
@ -8467,6 +8481,11 @@ define('form',['jquery', 'bootstrap', 'upload', 'validator'], function ($, undef
|
|||
}
|
||||
}
|
||||
}, submit);
|
||||
//如果提交失败则释放锁定
|
||||
if (!submitResult) {
|
||||
that.holdSubmit(false);
|
||||
submitBtn.removeClass("disabled");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}, form.data("validator-options") || {}));
|
||||
|
|
@ -8650,7 +8669,6 @@ define('form',['jquery', 'bootstrap', 'upload', 'validator'], function ($, undef
|
|||
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);
|
||||
|
|
@ -8739,10 +8757,12 @@ define('form',['jquery', 'bootstrap', 'upload', 'validator'], function ($, undef
|
|||
},
|
||||
api: {
|
||||
submit: function (form, success, error, submit) {
|
||||
if (form.size() === 0)
|
||||
return Toastr.error("表单未初始化完成,无法提交");
|
||||
if (form.size() === 0) {
|
||||
Toastr.error("表单未初始化完成,无法提交");
|
||||
return false;
|
||||
}
|
||||
if (typeof submit === 'function') {
|
||||
if (false === submit.call(form)) {
|
||||
if (false === submit.call(form, success, error)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -8802,7 +8822,7 @@ define('form',['jquery', 'bootstrap', 'upload', 'validator'], function ($, undef
|
|||
}
|
||||
}
|
||||
});
|
||||
return false;
|
||||
return true;
|
||||
},
|
||||
bindevent: function (form, success, error, submit) {
|
||||
|
||||
|
|
@ -9326,6 +9346,7 @@ define('table',['jquery', 'bootstrap', 'moment', 'moment/locale/zh-cn', 'bootstr
|
|||
pageList: [10, 25, 50, 'All'],
|
||||
pagination: true,
|
||||
clickToSelect: true, //是否启用点击选中
|
||||
dblClickToEdit: true, //是否启用双击编辑
|
||||
singleSelect: false, //是否启用单选
|
||||
showRefresh: false,
|
||||
locale: 'zh-CN',
|
||||
|
|
@ -9420,10 +9441,12 @@ define('table',['jquery', 'bootstrap', 'moment', 'moment/locale/zh-cn', 'bootstr
|
|||
table.on('refresh.bs.table', function (e, settings, data) {
|
||||
$(Table.config.refreshbtn, toolbar).find(".fa").addClass("fa-spin");
|
||||
});
|
||||
//当双击单元格时
|
||||
table.on('dbl-click-row.bs.table', function (e, row, element, field) {
|
||||
$(Table.config.editonebtn, element).trigger("click");
|
||||
});
|
||||
if (options.dblClickToEdit) {
|
||||
//当双击单元格时
|
||||
table.on('dbl-click-row.bs.table', function (e, row, element, field) {
|
||||
$(Table.config.editonebtn, element).trigger("click");
|
||||
});
|
||||
}
|
||||
//当内容渲染完成后
|
||||
table.on('post-body.bs.table', function (e, settings, json, xhr) {
|
||||
$(Table.config.refreshbtn, toolbar).find(".fa").removeClass("fa-spin");
|
||||
|
|
@ -9706,7 +9729,7 @@ define('table',['jquery', 'bootstrap', 'moment', 'moment/locale/zh-cn', 'bootstr
|
|||
return '<div class="input-group input-group-sm" style="width:250px;margin:0 auto;"><input type="text" class="form-control input-sm" value="' + value + '"><span class="input-group-btn input-group-sm"><a href="' + value + '" target="_blank" class="btn btn-default btn-sm"><i class="fa fa-link"></i></a></span></div>';
|
||||
},
|
||||
search: function (value, row, index) {
|
||||
return '<a href="javascript:;" class="searchit" data-field="' + this.field + '" data-value="' + value + '">' + value + '</a>';
|
||||
return '<a href="javascript:;" class="searchit" data-toggle="tooltip" title="' + __('Click to search %s', value) + '" data-field="' + this.field + '" data-value="' + value + '">' + value + '</a>';
|
||||
},
|
||||
addtabs: function (value, row, index) {
|
||||
var url = Table.api.replaceurl(this.url, row, this.table);
|
||||
|
|
@ -9759,6 +9782,7 @@ define('table',['jquery', 'bootstrap', 'moment', 'moment/locale/zh-cn', 'bootstr
|
|||
name: 'dragsort',
|
||||
icon: 'fa fa-arrows',
|
||||
title: __('Drag to sort'),
|
||||
extend: 'data-toggle="tooltip"',
|
||||
classname: 'btn btn-xs btn-primary btn-dragsort'
|
||||
});
|
||||
}
|
||||
|
|
@ -9767,6 +9791,7 @@ define('table',['jquery', 'bootstrap', 'moment', 'moment/locale/zh-cn', 'bootstr
|
|||
name: 'edit',
|
||||
icon: 'fa fa-pencil',
|
||||
title: __('Edit'),
|
||||
extend: 'data-toggle="tooltip"',
|
||||
classname: 'btn btn-xs btn-success btn-editone',
|
||||
url: options.extend.edit_url
|
||||
});
|
||||
|
|
@ -9776,6 +9801,7 @@ define('table',['jquery', 'bootstrap', 'moment', 'moment/locale/zh-cn', 'bootstr
|
|||
name: 'del',
|
||||
icon: 'fa fa-trash',
|
||||
title: __('Del'),
|
||||
extend: 'data-toggle="tooltip"',
|
||||
classname: 'btn btn-xs btn-danger btn-delone'
|
||||
});
|
||||
}
|
||||
|
|
@ -10338,7 +10364,11 @@ $.fn.addtabs = function (options) {
|
|||
document.title = title;
|
||||
if (history.pushState && !$(this).data("pushstate")) {
|
||||
var pushurl = url.indexOf("ref=addtabs") == -1 ? (url + (url.indexOf("?") > -1 ? "&" : "?") + "ref=addtabs") : url;
|
||||
window.history.pushState(state, title, pushurl);
|
||||
try {
|
||||
window.history.pushState(state, title, pushurl);
|
||||
}catch(e){
|
||||
|
||||
}
|
||||
}
|
||||
$(this).data("pushstate", null);
|
||||
_add.call(this, {
|
||||
|
|
|
|||
|
|
@ -39,10 +39,10 @@ define(['jquery', 'bootstrap', 'upload', 'validator'], function ($, undefined, U
|
|||
},
|
||||
valid: function (ret) {
|
||||
var that = this, submitBtn = $(".layer-footer [type=submit]", form);
|
||||
that.holdSubmit();
|
||||
$(".layer-footer [type=submit]", form).addClass("disabled");
|
||||
that.holdSubmit(true);
|
||||
submitBtn.addClass("disabled");
|
||||
//验证通过提交表单
|
||||
Form.api.submit($(ret), function (data, ret) {
|
||||
var submitResult = Form.api.submit($(ret), function (data, ret) {
|
||||
that.holdSubmit(false);
|
||||
submitBtn.removeClass("disabled");
|
||||
if (false === $(this).triggerHandler("success.form", [data, ret])) {
|
||||
|
|
@ -72,6 +72,11 @@ define(['jquery', 'bootstrap', 'upload', 'validator'], function ($, undefined, U
|
|||
}
|
||||
}
|
||||
}, submit);
|
||||
//如果提交失败则释放锁定
|
||||
if (!submitResult) {
|
||||
that.holdSubmit(false);
|
||||
submitBtn.removeClass("disabled");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}, form.data("validator-options") || {}));
|
||||
|
|
@ -255,7 +260,6 @@ define(['jquery', 'bootstrap', 'upload', 'validator'], function ($, undefined, U
|
|||
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);
|
||||
|
|
@ -344,10 +348,12 @@ define(['jquery', 'bootstrap', 'upload', 'validator'], function ($, undefined, U
|
|||
},
|
||||
api: {
|
||||
submit: function (form, success, error, submit) {
|
||||
if (form.size() === 0)
|
||||
return Toastr.error("表单未初始化完成,无法提交");
|
||||
if (form.size() === 0) {
|
||||
Toastr.error("表单未初始化完成,无法提交");
|
||||
return false;
|
||||
}
|
||||
if (typeof submit === 'function') {
|
||||
if (false === submit.call(form)) {
|
||||
if (false === submit.call(form, success, error)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -407,7 +413,7 @@ define(['jquery', 'bootstrap', 'upload', 'validator'], function ($, undefined, U
|
|||
}
|
||||
}
|
||||
});
|
||||
return false;
|
||||
return true;
|
||||
},
|
||||
bindevent: function (form, success, error, submit) {
|
||||
|
||||
|
|
|
|||
|
|
@ -759,7 +759,7 @@ define('fast',['jquery', 'bootstrap', 'toastr', 'layer', 'lang'], function ($, u
|
|||
}
|
||||
name = name.replace(/[\[\]]/g, "\\$&");
|
||||
var regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"),
|
||||
results = regex.exec(url);
|
||||
results = regex.exec(url);
|
||||
if (!results)
|
||||
return null;
|
||||
if (!results[2])
|
||||
|
|
@ -788,31 +788,42 @@ define('fast',['jquery', 'bootstrap', 'toastr', 'layer', 'lang'], function ($, u
|
|||
$(layero).data("callback", that.callback);
|
||||
//$(layero).removeClass("layui-layer-border");
|
||||
Layer.setTop(layero);
|
||||
var frame = Layer.getChildFrame('html', index);
|
||||
var layerfooter = frame.find(".layer-footer");
|
||||
Fast.api.layerfooter(layero, index, that);
|
||||
try {
|
||||
var frame = Layer.getChildFrame('html', index);
|
||||
var layerfooter = frame.find(".layer-footer");
|
||||
Fast.api.layerfooter(layero, index, that);
|
||||
|
||||
//绑定事件
|
||||
if (layerfooter.size() > 0) {
|
||||
// 监听窗口内的元素及属性变化
|
||||
// Firefox和Chrome早期版本中带有前缀
|
||||
var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver;
|
||||
if (MutationObserver) {
|
||||
// 选择目标节点
|
||||
var target = layerfooter[0];
|
||||
// 创建观察者对象
|
||||
var observer = new MutationObserver(function (mutations) {
|
||||
Fast.api.layerfooter(layero, index, that);
|
||||
mutations.forEach(function (mutation) {
|
||||
//绑定事件
|
||||
if (layerfooter.size() > 0) {
|
||||
// 监听窗口内的元素及属性变化
|
||||
// Firefox和Chrome早期版本中带有前缀
|
||||
var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver;
|
||||
if (MutationObserver) {
|
||||
// 选择目标节点
|
||||
var target = layerfooter[0];
|
||||
// 创建观察者对象
|
||||
var observer = new MutationObserver(function (mutations) {
|
||||
Fast.api.layerfooter(layero, index, that);
|
||||
mutations.forEach(function (mutation) {
|
||||
});
|
||||
});
|
||||
});
|
||||
// 配置观察选项:
|
||||
var config = {attributes: true, childList: true, characterData: true, subtree: true}
|
||||
// 传入目标节点和观察选项
|
||||
observer.observe(target, config);
|
||||
// 随后,你还可以停止观察
|
||||
// observer.disconnect();
|
||||
// 配置观察选项:
|
||||
var config = {attributes: true, childList: true, characterData: true, subtree: true}
|
||||
// 传入目标节点和观察选项
|
||||
observer.observe(target, config);
|
||||
// 随后,你还可以停止观察
|
||||
// observer.disconnect();
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
|
||||
}
|
||||
if ($(layero).height() > $(window).height()) {
|
||||
//当弹出窗口大于浏览器可视高度时,重定位
|
||||
Layer.style(index, {
|
||||
top: 0,
|
||||
height: $(window).height()
|
||||
});
|
||||
}
|
||||
}
|
||||
}, options ? options : {});
|
||||
|
|
@ -888,8 +899,8 @@ define('fast',['jquery', 'bootstrap', 'toastr', 'layer', 'lang'], function ($, u
|
|||
},
|
||||
lang: function () {
|
||||
var args = arguments,
|
||||
string = args[0],
|
||||
i = 1;
|
||||
string = args[0],
|
||||
i = 1;
|
||||
string = string.toLowerCase();
|
||||
//string = typeof Lang[string] != 'undefined' ? Lang[string] : string;
|
||||
if (typeof Lang[string] != 'undefined') {
|
||||
|
|
@ -1028,7 +1039,9 @@ define('frontend',['fast', 'template'], function (Fast, Template) {
|
|||
|
||||
return false;
|
||||
});
|
||||
|
||||
//tooltip和popover
|
||||
$('body').tooltip({selector: '[data-toggle="tooltip"]'});
|
||||
$('body').tooltip({selector: '[data-toggle="popover"]'});
|
||||
}
|
||||
};
|
||||
Frontend.api = $.extend(Fast.api, Frontend.api);
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ define(['jquery', 'bootstrap', 'moment', 'moment/locale/zh-cn', 'bootstrap-table
|
|||
pageList: [10, 25, 50, 'All'],
|
||||
pagination: true,
|
||||
clickToSelect: true, //是否启用点击选中
|
||||
dblClickToEdit: true, //是否启用双击编辑
|
||||
singleSelect: false, //是否启用单选
|
||||
showRefresh: false,
|
||||
locale: 'zh-CN',
|
||||
|
|
@ -114,10 +115,12 @@ define(['jquery', 'bootstrap', 'moment', 'moment/locale/zh-cn', 'bootstrap-table
|
|||
table.on('refresh.bs.table', function (e, settings, data) {
|
||||
$(Table.config.refreshbtn, toolbar).find(".fa").addClass("fa-spin");
|
||||
});
|
||||
//当双击单元格时
|
||||
table.on('dbl-click-row.bs.table', function (e, row, element, field) {
|
||||
$(Table.config.editonebtn, element).trigger("click");
|
||||
});
|
||||
if (options.dblClickToEdit) {
|
||||
//当双击单元格时
|
||||
table.on('dbl-click-row.bs.table', function (e, row, element, field) {
|
||||
$(Table.config.editonebtn, element).trigger("click");
|
||||
});
|
||||
}
|
||||
//当内容渲染完成后
|
||||
table.on('post-body.bs.table', function (e, settings, json, xhr) {
|
||||
$(Table.config.refreshbtn, toolbar).find(".fa").removeClass("fa-spin");
|
||||
|
|
@ -400,7 +403,7 @@ define(['jquery', 'bootstrap', 'moment', 'moment/locale/zh-cn', 'bootstrap-table
|
|||
return '<div class="input-group input-group-sm" style="width:250px;margin:0 auto;"><input type="text" class="form-control input-sm" value="' + value + '"><span class="input-group-btn input-group-sm"><a href="' + value + '" target="_blank" class="btn btn-default btn-sm"><i class="fa fa-link"></i></a></span></div>';
|
||||
},
|
||||
search: function (value, row, index) {
|
||||
return '<a href="javascript:;" class="searchit" data-field="' + this.field + '" data-value="' + value + '">' + value + '</a>';
|
||||
return '<a href="javascript:;" class="searchit" data-toggle="tooltip" title="' + __('Click to search %s', value) + '" data-field="' + this.field + '" data-value="' + value + '">' + value + '</a>';
|
||||
},
|
||||
addtabs: function (value, row, index) {
|
||||
var url = Table.api.replaceurl(this.url, row, this.table);
|
||||
|
|
@ -453,6 +456,7 @@ define(['jquery', 'bootstrap', 'moment', 'moment/locale/zh-cn', 'bootstrap-table
|
|||
name: 'dragsort',
|
||||
icon: 'fa fa-arrows',
|
||||
title: __('Drag to sort'),
|
||||
extend: 'data-toggle="tooltip"',
|
||||
classname: 'btn btn-xs btn-primary btn-dragsort'
|
||||
});
|
||||
}
|
||||
|
|
@ -461,6 +465,7 @@ define(['jquery', 'bootstrap', 'moment', 'moment/locale/zh-cn', 'bootstrap-table
|
|||
name: 'edit',
|
||||
icon: 'fa fa-pencil',
|
||||
title: __('Edit'),
|
||||
extend: 'data-toggle="tooltip"',
|
||||
classname: 'btn btn-xs btn-success btn-editone',
|
||||
url: options.extend.edit_url
|
||||
});
|
||||
|
|
@ -470,6 +475,7 @@ define(['jquery', 'bootstrap', 'moment', 'moment/locale/zh-cn', 'bootstrap-table
|
|||
name: 'del',
|
||||
icon: 'fa fa-trash',
|
||||
title: __('Del'),
|
||||
extend: 'data-toggle="tooltip"',
|
||||
classname: 'btn btn-xs btn-danger btn-delone'
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -591,6 +591,9 @@ form.form-horizontal .control-label {
|
|||
.bootstrap-table td.bs-checkbox {
|
||||
vertical-align: middle;
|
||||
}
|
||||
.fixed-table-container thead th .sortable{
|
||||
padding-right:0;
|
||||
}
|
||||
.dropdown-submenu {
|
||||
position: relative;
|
||||
>.dropdown-menu {
|
||||
|
|
|
|||
Loading…
Reference in New Issue