作者 HID丨emotion
提交者 Gitee

Merge branch 'master' of gitee.com:karson/fastadmin into adv_multi_order

正在显示 55 个修改的文件 包含 2123 行增加673 行删除

要显示太多修改。

为保证性能只显示 55 of 55+ 个文件。

... ... @@ -211,7 +211,7 @@ class Crud extends Command
//关联表
$relation = $input->getOption('relation');
//自定义关联表模型
$relationModel = $input->getOption('relationmodel');
$relationModels = $input->getOption('relationmodel');
//模式
$relationMode = $mode = $input->getOption('relationmode');
//外键
... ... @@ -337,7 +337,7 @@ class Crud extends Command
}
}
$relationTableInfo = $relationTableInfo[0];
$relationModel = isset($relationModel[$index]) ? $relationModel[$index] : '';
$relationModel = isset($relationModels[$index]) ? $relationModels[$index] : '';
list($relationNamespace, $relationName, $relationFile) = $this->getModelData($modelModuleName, $relationModel, $relationName);
... ... @@ -1449,6 +1449,15 @@ EOD;
if ($itemArr) {
$html .= ", searchList: " . $searchList;
}
// 文件、图片、权重等字段默认不加入搜索栏,字符串类型默认LIKE
$noSearchFiles = ['file$', 'files$', 'image$', 'images$', '^weigh$'];
if(preg_match("/" . implode('|', $noSearchFiles) . "/i", $field)){
$html .= ", operate: false";
}else if(in_array($datatype, ['varchar'])) {
$html .= ", operate: 'LIKE'";
}
if (in_array($datatype, ['date', 'datetime']) || $formatter === 'datetime') {
$html .= ", operate:'RANGE', addclass:'datetimerange'";
} elseif (in_array($datatype, ['float', 'double', 'decimal'])) {
... ...
... ... @@ -2,9 +2,9 @@
<div class="panel-heading">
{:build_heading(null,FALSE)}
<ul class="nav nav-tabs" data-field="{%field%}">
<li class="active"><a href="#t-all" data-value="" data-toggle="tab">{:__('All')}</a></li>
<li class="{:$Think.get.{%field%} === null ? 'active' : ''}"><a href="#t-all" data-value="" data-toggle="tab">{:__('All')}</a></li>
{foreach name="{%fieldName%}List" item="vo"}
<li><a href="#t-{$key}" data-value="{$key}" data-toggle="tab">{$vo}</a></li>
<li class="{:$Think.get.{%field%} === (string)$key ? 'active' : ''}"><a href="#t-{$key}" data-value="{$key}" data-toggle="tab">{$vo}</a></li>
{/foreach}
</ul>
</div>
... ...
... ... @@ -11,18 +11,18 @@ SET FOREIGN_KEY_CHECKS = 0;
DROP TABLE IF EXISTS `fa_admin`;
CREATE TABLE `fa_admin` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID',
`username` varchar(20) NOT NULL DEFAULT '' COMMENT '用户名',
`nickname` varchar(50) NOT NULL DEFAULT '' COMMENT '昵称',
`password` varchar(32) NOT NULL DEFAULT '' COMMENT '密码',
`salt` varchar(30) NOT NULL DEFAULT '' COMMENT '密码盐',
`avatar` varchar(255) NOT NULL DEFAULT '' COMMENT '头像',
`email` varchar(100) NOT NULL DEFAULT '' COMMENT '电子邮箱',
`username` varchar(20) DEFAULT '' COMMENT '用户名',
`nickname` varchar(50) DEFAULT '' COMMENT '昵称',
`password` varchar(32) DEFAULT '' COMMENT '密码',
`salt` varchar(30) DEFAULT '' COMMENT '密码盐',
`avatar` varchar(255) DEFAULT '' COMMENT '头像',
`email` varchar(100) DEFAULT '' COMMENT '电子邮箱',
`loginfailure` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT '失败次数',
`logintime` int(10) DEFAULT NULL COMMENT '登录时间',
`loginip` varchar(50) DEFAULT NULL COMMENT '登录IP',
`createtime` int(10) DEFAULT NULL COMMENT '创建时间',
`updatetime` int(10) DEFAULT NULL COMMENT '更新时间',
`token` varchar(59) NOT NULL DEFAULT '' COMMENT 'Session标识',
`token` varchar(59) DEFAULT '' COMMENT 'Session标识',
`status` varchar(30) NOT NULL DEFAULT 'normal' COMMENT '状态',
PRIMARY KEY (`id`),
UNIQUE KEY `username` (`username`) USING BTREE
... ... @@ -42,12 +42,12 @@ DROP TABLE IF EXISTS `fa_admin_log`;
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(1500) NOT NULL DEFAULT '' COMMENT '操作页面',
`title` varchar(100) NOT NULL DEFAULT '' COMMENT '日志标题',
`username` varchar(30) DEFAULT '' COMMENT '管理员名字',
`url` varchar(1500) DEFAULT '' COMMENT '操作页面',
`title` varchar(100) DEFAULT '' COMMENT '日志标题',
`content` text NOT NULL COMMENT '内容',
`ip` varchar(50) NOT NULL DEFAULT '' COMMENT 'IP',
`useragent` varchar(255) NOT NULL DEFAULT '' COMMENT 'User-Agent',
`ip` varchar(50) DEFAULT '' COMMENT 'IP',
`useragent` varchar(255) DEFAULT '' COMMENT 'User-Agent',
`createtime` int(10) DEFAULT NULL COMMENT '操作时间',
PRIMARY KEY (`id`),
KEY `name` (`username`)
... ... @@ -82,20 +82,20 @@ 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 '高度',
`imagetype` varchar(30) NOT NULL DEFAULT '' COMMENT '图片类型',
`url` varchar(255) DEFAULT '' COMMENT '物理路径',
`imagewidth` varchar(30) DEFAULT '' COMMENT '宽度',
`imageheight` varchar(30) DEFAULT '' COMMENT '高度',
`imagetype` varchar(30) DEFAULT '' COMMENT '图片类型',
`imageframes` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '图片帧数',
`filename` varchar(100) NOT NULL DEFAULT '' COMMENT '文件名称',
`filename` varchar(100) DEFAULT '' COMMENT '文件名称',
`filesize` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '文件大小',
`mimetype` varchar(100) NOT NULL DEFAULT '' COMMENT 'mime类型',
`extparam` varchar(255) NOT NULL DEFAULT '' COMMENT '透传数据',
`mimetype` varchar(100) DEFAULT '' COMMENT 'mime类型',
`extparam` varchar(255) DEFAULT '' COMMENT '透传数据',
`createtime` int(10) DEFAULT NULL COMMENT '创建日期',
`updatetime` int(10) DEFAULT NULL COMMENT '更新时间',
`uploadtime` int(10) DEFAULT NULL COMMENT '上传时间',
`storage` varchar(100) NOT NULL DEFAULT 'local' COMMENT '存储位置',
`sha1` varchar(40) NOT NULL DEFAULT '' COMMENT '文件 sha1编码',
`sha1` varchar(40) DEFAULT '' COMMENT '文件 sha1编码',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_unicode_ci COMMENT='附件表';
... ... @@ -113,11 +113,11 @@ DROP TABLE IF EXISTS `fa_auth_group`;
CREATE TABLE `fa_auth_group` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`pid` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '父组别',
`name` varchar(100) NOT NULL DEFAULT '' COMMENT '组名',
`name` varchar(100) DEFAULT '' COMMENT '组名',
`rules` text NOT NULL COMMENT '规则ID',
`createtime` int(10) DEFAULT NULL COMMENT '创建时间',
`updatetime` int(10) DEFAULT NULL COMMENT '更新时间',
`status` varchar(30) NOT NULL DEFAULT '' COMMENT '状态',
`status` varchar(30) DEFAULT '' COMMENT '状态',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_unicode_ci COMMENT='分组表';
... ... @@ -159,16 +159,16 @@ CREATE TABLE `fa_auth_rule` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`type` enum('menu','file') NOT NULL DEFAULT 'file' COMMENT 'menu为菜单,file为权限节点',
`pid` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '父ID',
`name` varchar(100) NOT NULL DEFAULT '' COMMENT '规则名称',
`title` varchar(50) NOT NULL DEFAULT '' COMMENT '规则名称',
`icon` varchar(50) NOT NULL DEFAULT '' COMMENT '图标',
`condition` varchar(255) NOT NULL DEFAULT '' COMMENT '条件',
`remark` varchar(255) NOT NULL DEFAULT '' COMMENT '备注',
`name` varchar(100) DEFAULT '' COMMENT '规则名称',
`title` varchar(50) DEFAULT '' COMMENT '规则名称',
`icon` varchar(50) DEFAULT '' COMMENT '图标',
`condition` varchar(255) DEFAULT '' COMMENT '条件',
`remark` varchar(255) DEFAULT '' COMMENT '备注',
`ismenu` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT '是否为菜单',
`createtime` int(10) DEFAULT NULL COMMENT '创建时间',
`updatetime` int(10) DEFAULT NULL COMMENT '更新时间',
`weigh` int(10) NOT NULL DEFAULT '0' COMMENT '权重',
`status` varchar(30) NOT NULL DEFAULT '' COMMENT '状态',
`status` varchar(30) DEFAULT '' COMMENT '状态',
PRIMARY KEY (`id`),
UNIQUE KEY `name` (`name`) USING BTREE,
KEY `pid` (`pid`),
... ... @@ -270,18 +270,18 @@ DROP TABLE IF EXISTS `fa_category`;
CREATE TABLE `fa_category` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`pid` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '父ID',
`type` varchar(30) NOT NULL DEFAULT '' COMMENT '栏目类型',
`name` varchar(30) NOT NULL DEFAULT '',
`nickname` varchar(50) NOT NULL DEFAULT '',
`flag` set('hot','index','recommend') NOT NULL DEFAULT '',
`image` varchar(100) NOT NULL DEFAULT '' COMMENT '图片',
`keywords` varchar(255) NOT NULL DEFAULT '' COMMENT '关键字',
`description` varchar(255) NOT NULL DEFAULT '' COMMENT '描述',
`diyname` varchar(30) NOT NULL DEFAULT '' COMMENT '自定义名称',
`type` varchar(30) DEFAULT '' COMMENT '栏目类型',
`name` varchar(30) DEFAULT '',
`nickname` varchar(50) DEFAULT '',
`flag` set('hot','index','recommend') DEFAULT '',
`image` varchar(100) DEFAULT '' COMMENT '图片',
`keywords` varchar(255) DEFAULT '' COMMENT '关键字',
`description` varchar(255) DEFAULT '' COMMENT '描述',
`diyname` varchar(30) DEFAULT '' COMMENT '自定义名称',
`createtime` int(10) DEFAULT NULL COMMENT '创建时间',
`updatetime` int(10) DEFAULT NULL COMMENT '更新时间',
`weigh` int(10) NOT NULL DEFAULT '0' COMMENT '权重',
`status` varchar(30) NOT NULL DEFAULT '' COMMENT '状态',
`status` varchar(30) DEFAULT '' COMMENT '状态',
PRIMARY KEY (`id`),
KEY `weigh` (`weigh`,`id`),
KEY `pid` (`pid`)
... ... @@ -312,15 +312,16 @@ COMMIT;
DROP TABLE IF EXISTS `fa_config`;
CREATE TABLE `fa_config` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(30) NOT NULL DEFAULT '' COMMENT '变量名',
`group` varchar(30) NOT NULL DEFAULT '' COMMENT '分组',
`title` varchar(100) NOT NULL DEFAULT '' COMMENT '变量标题',
`tip` varchar(100) NOT NULL DEFAULT '' COMMENT '变量描述',
`type` varchar(30) NOT NULL DEFAULT '' COMMENT '类型:string,text,int,bool,array,datetime,date,file',
`value` text NOT NULL COMMENT '变量值',
`content` text NOT NULL COMMENT '变量字典数据',
`rule` varchar(100) NOT NULL DEFAULT '' COMMENT '验证规则',
`extend` varchar(255) NOT NULL DEFAULT '' COMMENT '扩展属性',
`name` varchar(30) DEFAULT '' COMMENT '变量名',
`group` varchar(30) DEFAULT '' COMMENT '分组',
`title` varchar(100) DEFAULT '' COMMENT '变量标题',
`tip` varchar(100) DEFAULT '' COMMENT '变量描述',
`type` varchar(30) DEFAULT '' COMMENT '类型:string,text,int,bool,array,datetime,date,file',
`value` text COMMENT '变量值',
`content` text COMMENT '变量字典数据',
`rule` varchar(100) DEFAULT '' COMMENT '验证规则',
`extend` varchar(255) DEFAULT '' COMMENT '扩展属性',
`setting` varchar(255) DEFAULT '' COMMENT '配置',
PRIMARY KEY (`id`),
UNIQUE KEY `name` (`name`)
) ENGINE=InnoDB AUTO_INCREMENT=18 DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_unicode_ci COMMENT='系统配置';
... ... @@ -329,23 +330,23 @@ CREATE TABLE `fa_config` (
-- Records of fa_config
-- ----------------------------
BEGIN;
INSERT INTO `fa_config` VALUES (1, 'name', 'basic', 'Site name', '请填写站点名称', 'string', '我的网站', '', 'required', '');
INSERT INTO `fa_config` VALUES (2, 'beian', 'basic', 'Beian', '粤ICP备15000000号-1', 'string', '', '', '', '');
INSERT INTO `fa_config` VALUES (3, 'cdnurl', 'basic', 'Cdn url', '如果静态资源使用第三方云储存请配置该值', 'string', '', '', '', '');
INSERT INTO `fa_config` VALUES (4, 'version', 'basic', 'Version', '如果静态资源有变动请重新配置该值', 'string', '1.0.1', '', 'required', '');
INSERT INTO `fa_config` VALUES (5, 'timezone', 'basic', 'Timezone', '', 'string', 'Asia/Shanghai', '', 'required', '');
INSERT INTO `fa_config` VALUES (6, 'forbiddenip', 'basic', 'Forbidden ip', '一行一条记录', 'text', '', '', '', '');
INSERT INTO `fa_config` VALUES (7, 'languages', 'basic', 'Languages', '', 'array', '{\"backend\":\"zh-cn\",\"frontend\":\"zh-cn\"}', '', 'required', '');
INSERT INTO `fa_config` VALUES (8, 'fixedpage', 'basic', 'Fixed page', '请尽量输入左侧菜单栏存在的链接', 'string', 'dashboard', '', 'required', '');
INSERT INTO `fa_config` VALUES (9, 'categorytype', 'dictionary', 'Category type', '', 'array', '{\"default\":\"Default\",\"page\":\"Page\",\"article\":\"Article\",\"test\":\"Test\"}', '', '', '');
INSERT INTO `fa_config` VALUES (10, 'configgroup', 'dictionary', 'Config group', '', 'array', '{\"basic\":\"Basic\",\"email\":\"Email\",\"dictionary\":\"Dictionary\",\"user\":\"User\",\"example\":\"Example\"}', '', '', '');
INSERT INTO `fa_config` VALUES (11, 'mail_type', 'email', 'Mail type', '选择邮件发送方式', 'select', '1', '[\"Please select\",\"SMTP\",\"Mail\"]', '', '');
INSERT INTO `fa_config` VALUES (12, 'mail_smtp_host', 'email', 'Mail smtp host', '错误的配置发送邮件会导致服务器超时', 'string', 'smtp.qq.com', '', '', '');
INSERT INTO `fa_config` VALUES (13, 'mail_smtp_port', 'email', 'Mail smtp port', '(不加密默认25,SSL默认465,TLS默认587)', 'string', '465', '', '', '');
INSERT INTO `fa_config` VALUES (14, 'mail_smtp_user', 'email', 'Mail smtp user', '(填写完整用户名)', 'string', '10000', '', '', '');
INSERT INTO `fa_config` VALUES (15, 'mail_smtp_pass', 'email', 'Mail smtp password', '(填写您的密码)', 'string', 'password', '', '', '');
INSERT INTO `fa_config` VALUES (16, 'mail_verify_type', 'email', 'Mail vertify type', '(SMTP验证方式[推荐SSL])', 'select', '2', '[\"None\",\"TLS\",\"SSL\"]', '', '');
INSERT INTO `fa_config` VALUES (17, 'mail_from', 'email', 'Mail from', '', 'string', '10000@qq.com', '', '', '');
INSERT INTO `fa_config` VALUES (1, 'name', 'basic', 'Site name', '请填写站点名称', 'string', '我的网站', '', 'required', '', '');
INSERT INTO `fa_config` VALUES (2, 'beian', 'basic', 'Beian', '粤ICP备15000000号-1', 'string', '', '', '', '', '');
INSERT INTO `fa_config` VALUES (3, 'cdnurl', 'basic', 'Cdn url', '如果全站静态资源使用第三方云储存请配置该值', 'string', '', '', '', '', '');
INSERT INTO `fa_config` VALUES (4, 'version', 'basic', 'Version', '如果静态资源有变动请重新配置该值', 'string', '1.0.1', '', 'required', '', '');
INSERT INTO `fa_config` VALUES (5, 'timezone', 'basic', 'Timezone', '', 'string', 'Asia/Shanghai', '', 'required', '', '');
INSERT INTO `fa_config` VALUES (6, 'forbiddenip', 'basic', 'Forbidden ip', '一行一条记录', 'text', '', '', '', '', '');
INSERT INTO `fa_config` VALUES (7, 'languages', 'basic', 'Languages', '', 'array', '{\"backend\":\"zh-cn\",\"frontend\":\"zh-cn\"}', '', 'required', '', '');
INSERT INTO `fa_config` VALUES (8, 'fixedpage', 'basic', 'Fixed page', '请尽量输入左侧菜单栏存在的链接', 'string', 'dashboard', '', 'required', '', '');
INSERT INTO `fa_config` VALUES (9, 'categorytype', 'dictionary', 'Category type', '', 'array', '{\"default\":\"Default\",\"page\":\"Page\",\"article\":\"Article\",\"test\":\"Test\"}', '', '', '', '');
INSERT INTO `fa_config` VALUES (10, 'configgroup', 'dictionary', 'Config group', '', 'array', '{\"basic\":\"Basic\",\"email\":\"Email\",\"dictionary\":\"Dictionary\",\"user\":\"User\",\"example\":\"Example\"}', '', '', '', '');
INSERT INTO `fa_config` VALUES (11, 'mail_type', 'email', 'Mail type', '选择邮件发送方式', 'select', '1', '[\"请选择\",\"SMTP\",\"Mail\"]', '', '', '');
INSERT INTO `fa_config` VALUES (12, 'mail_smtp_host', 'email', 'Mail smtp host', '错误的配置发送邮件会导致服务器超时', 'string', 'smtp.qq.com', '', '', '', '');
INSERT INTO `fa_config` VALUES (13, 'mail_smtp_port', 'email', 'Mail smtp port', '(不加密默认25,SSL默认465,TLS默认587)', 'string', '465', '', '', '', '');
INSERT INTO `fa_config` VALUES (14, 'mail_smtp_user', 'email', 'Mail smtp user', '(填写完整用户名)', 'string', '10000', '', '', '', '');
INSERT INTO `fa_config` VALUES (15, 'mail_smtp_pass', 'email', 'Mail smtp password', '(填写您的密码)', 'string', 'password', '', '', '', '');
INSERT INTO `fa_config` VALUES (16, 'mail_verify_type', 'email', 'Mail vertify type', '(SMTP验证方式[推荐SSL])', 'select', '2', '[\"\",\"TLS\",\"SSL\"]', '', '', '');
INSERT INTO `fa_config` VALUES (17, 'mail_from', 'email', 'Mail from', '', 'string', '10000@qq.com', '', '', '', '');
COMMIT;
-- ----------------------------
... ... @@ -354,11 +355,11 @@ COMMIT;
DROP TABLE IF EXISTS `fa_ems`;
CREATE TABLE `fa_ems` (
`id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'ID',
`event` varchar(30) NOT NULL DEFAULT '' COMMENT '事件',
`email` varchar(100) NOT NULL DEFAULT '' COMMENT '邮箱',
`code` varchar(10) NOT NULL DEFAULT '' COMMENT '验证码',
`event` varchar(30) DEFAULT '' COMMENT '事件',
`email` varchar(100) DEFAULT '' COMMENT '邮箱',
`code` varchar(10) DEFAULT '' COMMENT '验证码',
`times` int(10) UNSIGNED NOT NULL DEFAULT 0 COMMENT '验证次数',
`ip` varchar(30) NOT NULL DEFAULT '' COMMENT 'IP',
`ip` varchar(30) DEFAULT '' COMMENT 'IP',
`createtime` int(10) DEFAULT NULL COMMENT '创建时间',
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_unicode_ci COMMENT='邮箱验证码表';
... ... @@ -369,11 +370,11 @@ CREATE TABLE `fa_ems` (
DROP TABLE IF EXISTS `fa_sms`;
CREATE TABLE `fa_sms` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID',
`event` varchar(30) NOT NULL DEFAULT '' COMMENT '事件',
`mobile` varchar(20) NOT NULL DEFAULT '' COMMENT '手机号',
`code` varchar(10) NOT NULL DEFAULT '' COMMENT '验证码',
`event` varchar(30) DEFAULT '' COMMENT '事件',
`mobile` varchar(20) DEFAULT '' COMMENT '手机号',
`code` varchar(10) DEFAULT '' COMMENT '验证码',
`times` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '验证次数',
`ip` varchar(30) NOT NULL DEFAULT '' COMMENT 'IP',
`ip` varchar(30) DEFAULT '' COMMENT 'IP',
`createtime` int(10) unsigned DEFAULT '0' COMMENT '创建时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_unicode_ci COMMENT='短信验证码表';
... ... @@ -388,17 +389,17 @@ CREATE TABLE `fa_test` (
`category_id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '分类ID(单选)',
`category_ids` varchar(100) NOT NULL COMMENT '分类ID(多选)',
`week` enum('monday','tuesday','wednesday') NOT NULL COMMENT '星期(单选):monday=星期一,tuesday=星期二,wednesday=星期三',
`flag` set('hot','index','recommend') NOT NULL DEFAULT '' COMMENT '标志(多选):hot=热门,index=首页,recommend=推荐',
`flag` set('hot','index','recommend') DEFAULT '' COMMENT '标志(多选):hot=热门,index=首页,recommend=推荐',
`genderdata` enum('male','female') NOT NULL DEFAULT 'male' COMMENT '性别(单选):male=男,female=女',
`hobbydata` set('music','reading','swimming') NOT NULL COMMENT '爱好(多选):music=音乐,reading=读书,swimming=游泳',
`title` varchar(50) NOT NULL DEFAULT '' COMMENT '标题',
`title` varchar(50) DEFAULT '' COMMENT '标题',
`content` text NOT NULL COMMENT '内容',
`image` varchar(100) NOT NULL DEFAULT '' COMMENT '图片',
`images` varchar(1500) NOT NULL DEFAULT '' COMMENT '图片组',
`attachfile` varchar(100) NOT NULL DEFAULT '' COMMENT '附件',
`keywords` varchar(100) NOT NULL DEFAULT '' COMMENT '关键字',
`description` varchar(255) NOT NULL DEFAULT '' COMMENT '描述',
`city` varchar(100) NOT NULL DEFAULT '' COMMENT '省市',
`image` varchar(100) DEFAULT '' COMMENT '图片',
`images` varchar(1500) DEFAULT '' COMMENT '图片组',
`attachfile` varchar(100) DEFAULT '' COMMENT '附件',
`keywords` varchar(100) DEFAULT '' COMMENT '关键字',
`description` varchar(255) DEFAULT '' COMMENT '描述',
`city` varchar(100) DEFAULT '' COMMENT '省市',
`json` varchar(255) DEFAULT NULL COMMENT '配置:key=名称,value=值',
`price` float(10,2) unsigned NOT NULL DEFAULT '0.00' COMMENT '价格',
`views` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '点击',
... ... @@ -431,32 +432,32 @@ DROP TABLE IF EXISTS `fa_user`;
CREATE TABLE `fa_user` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID',
`group_id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '组别ID',
`username` varchar(32) NOT NULL DEFAULT '' COMMENT '用户名',
`nickname` varchar(50) NOT NULL DEFAULT '' COMMENT '昵称',
`password` varchar(32) NOT NULL DEFAULT '' COMMENT '密码',
`salt` varchar(30) NOT NULL DEFAULT '' COMMENT '密码盐',
`email` varchar(100) NOT NULL DEFAULT '' COMMENT '电子邮箱',
`mobile` varchar(11) NOT NULL DEFAULT '' COMMENT '手机号',
`avatar` varchar(255) NOT NULL DEFAULT '' COMMENT '头像',
`username` varchar(32) DEFAULT '' COMMENT '用户名',
`nickname` varchar(50) DEFAULT '' COMMENT '昵称',
`password` varchar(32) DEFAULT '' COMMENT '密码',
`salt` varchar(30) DEFAULT '' COMMENT '密码盐',
`email` varchar(100) DEFAULT '' COMMENT '电子邮箱',
`mobile` varchar(11) DEFAULT '' COMMENT '手机号',
`avatar` varchar(255) DEFAULT '' COMMENT '头像',
`level` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT '等级',
`gender` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT '性别',
`birthday` date DEFAULT NULL COMMENT '生日',
`bio` varchar(100) NOT NULL DEFAULT '' COMMENT '格言',
`bio` varchar(100) DEFAULT '' COMMENT '格言',
`money` decimal(10,2) NOT NULL DEFAULT '0.00' COMMENT '余额',
`score` int(10) NOT NULL DEFAULT '0' COMMENT '积分',
`successions` int(10) unsigned NOT NULL DEFAULT '1' COMMENT '连续登录天数',
`maxsuccessions` int(10) unsigned NOT NULL DEFAULT '1' COMMENT '最大连续登录天数',
`prevtime` int(10) DEFAULT NULL COMMENT '上次登录时间',
`logintime` int(10) DEFAULT NULL COMMENT '登录时间',
`loginip` varchar(50) NOT NULL DEFAULT '' COMMENT '登录IP',
`loginip` varchar(50) DEFAULT '' COMMENT '登录IP',
`loginfailure` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT '失败次数',
`joinip` varchar(50) NOT NULL DEFAULT '' COMMENT '加入IP',
`joinip` varchar(50) DEFAULT '' COMMENT '加入IP',
`jointime` int(10) DEFAULT NULL COMMENT '加入时间',
`createtime` int(10) DEFAULT NULL COMMENT '创建时间',
`updatetime` int(10) DEFAULT NULL COMMENT '更新时间',
`token` varchar(50) NOT NULL DEFAULT '' COMMENT 'Token',
`status` varchar(30) NOT NULL DEFAULT '' COMMENT '状态',
`verification` varchar(255) NOT NULL DEFAULT '' COMMENT '验证',
`token` varchar(50) DEFAULT '' COMMENT 'Token',
`status` varchar(30) DEFAULT '' COMMENT '状态',
`verification` varchar(255) DEFAULT '' COMMENT '验证',
PRIMARY KEY (`id`),
KEY `username` (`username`),
KEY `email` (`email`),
... ... @@ -501,7 +502,7 @@ CREATE TABLE `fa_user_money_log` (
`money` decimal(10,2) NOT NULL DEFAULT '0.00' COMMENT '变更余额',
`before` decimal(10,2) NOT NULL DEFAULT '0.00' COMMENT '变更前余额',
`after` decimal(10,2) NOT NULL DEFAULT '0.00' COMMENT '变更后余额',
`memo` varchar(255) NOT NULL DEFAULT '' COMMENT '备注',
`memo` varchar(255) DEFAULT '' COMMENT '备注',
`createtime` int(10) DEFAULT NULL COMMENT '创建时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_unicode_ci COMMENT='会员余额变动表';
... ... @@ -552,7 +553,7 @@ CREATE TABLE `fa_user_score_log` (
`score` int(10) NOT NULL DEFAULT '0' COMMENT '变更积分',
`before` int(10) NOT NULL DEFAULT '0' COMMENT '变更前积分',
`after` int(10) NOT NULL DEFAULT '0' COMMENT '变更后积分',
`memo` varchar(255) NOT NULL DEFAULT '' COMMENT '备注',
`memo` varchar(255) DEFAULT '' COMMENT '备注',
`createtime` int(10) DEFAULT NULL COMMENT '创建时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_unicode_ci COMMENT='会员积分变动表';
... ... @@ -575,16 +576,16 @@ CREATE TABLE `fa_user_token` (
DROP TABLE IF EXISTS `fa_version`;
CREATE TABLE `fa_version` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID',
`oldversion` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '旧版本号',
`newversion` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '新版本号',
`packagesize` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '包大小',
`content` varchar(500) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '升级内容',
`downloadurl` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '下载地址',
`oldversion` varchar(30) DEFAULT '' COMMENT '旧版本号',
`newversion` varchar(30) DEFAULT '' COMMENT '新版本号',
`packagesize` varchar(30) DEFAULT '' COMMENT '包大小',
`content` varchar(500) DEFAULT '' COMMENT '升级内容',
`downloadurl` varchar(255) DEFAULT '' COMMENT '下载地址',
`enforce` tinyint(1) UNSIGNED NOT NULL DEFAULT 0 COMMENT '强制更新',
`createtime` int(10) DEFAULT NULL COMMENT '创建时间',
`updatetime` int(10) DEFAULT NULL COMMENT '更新时间',
`weigh` int(10) NOT NULL DEFAULT 0 COMMENT '权重',
`status` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '状态',
`status` varchar(30) DEFAULT '' COMMENT '状态',
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_unicode_ci COMMENT='版本表';
... ...
... ... @@ -8,6 +8,7 @@ use think\addons\AddonException;
use think\addons\Service;
use think\Cache;
use think\Config;
use think\Db;
use think\Exception;
/**
... ... @@ -19,6 +20,7 @@ use think\Exception;
class Addon extends Backend
{
protected $model = null;
protected $noNeedRight = ['get_table_list'];
public function _initialize()
{
... ... @@ -144,14 +146,31 @@ class Addon extends Backend
{
$name = $this->request->post("name");
$force = (int)$this->request->post("force");
$droptables = (int)$this->request->post("droptables");
if (!$name) {
$this->error(__('Parameter %s can not be empty', 'name'));
}
if (!preg_match("/^[a-zA-Z0-9]+$/", $name)) {
$this->error(__('Addon name incorrect'));
}
//只有开启调试且为超级管理员才允许删除相关数据库
$tables = [];
if ($droptables && Config::get("app_debug") && $this->auth->isSuperAdmin()) {
$tables = get_addon_tables($name);
}
try {
Service::uninstall($name, $force);
if ($tables) {
$prefix = Config::get('database.prefix');
//删除插件关联表
foreach ($tables as $index => $table) {
//忽略非插件标识的表名
if (!preg_match("/^{$prefix}{$name}/", $table)) {
continue;
}
Db::execute("DROP TABLE IF EXISTS `{$table}`");
}
}
$this->success(__('Uninstall successful'));
} catch (AddonException $e) {
$this->result($e->getData(), $e->getCode(), __($e->getMessage()));
... ... @@ -314,7 +333,7 @@ class Addon extends Backend
$search = $this->request->get("search");
$search = htmlspecialchars(strip_tags($search));
$onlineaddons = Cache::get("onlineaddons");
if (!is_array($onlineaddons)) {
if (!is_array($onlineaddons) && config('fastadmin.api_url')) {
$onlineaddons = [];
$result = Http::sendRequest(config('fastadmin.api_url') . '/addon/index', [], 'GET', [
CURLOPT_HTTPHEADER => ['Accept-Encoding:gzip'],
... ... @@ -367,4 +386,22 @@ class Addon extends Backend
$callback = $this->request->get('callback') ? "jsonp" : "json";
return $callback($result);
}
/**
* 获取插件相关表
*/
public function get_table_list()
{
$name = $this->request->post("name");
$tables = get_addon_tables($name);
$prefix = Config::get('database.prefix');
foreach ($tables as $index => $table) {
//忽略非插件标识的表名
if (!preg_match("/^{$prefix}{$name}/", $table)) {
unset($tables[$index]);
}
}
$tables = array_values($tables);
$this->success('', null, ['tables' => $tables]);
}
}
... ...
... ... @@ -56,6 +56,8 @@ class Ajax extends Backend
public function upload()
{
Config::set('default_return_type', 'json');
//必须设定cdnurl为空,否则cdnurl函数计算错误
Config::set('upload.cdnurl', '');
$chunkid = $this->request->post("chunkid");
if ($chunkid) {
if (!Config::get('upload.chunking')) {
... ... @@ -75,7 +77,7 @@ class Ajax extends Backend
} catch (UploadException $e) {
$this->error($e->getMessage());
}
$this->success(__('Uploaded successful'), '', ['url' => $attachment->url]);
$this->success(__('Uploaded successful'), '', ['url' => $attachment->url, 'fullurl' => cdnurl($attachment->url, true)]);
} elseif ($method == 'clean') {
//删除冗余的分片文件
try {
... ... @@ -108,7 +110,7 @@ class Ajax extends Backend
$this->error($e->getMessage());
}
$this->success(__('Uploaded successful'), '', ['url' => $attachment->url]);
$this->success(__('Uploaded successful'), '', ['url' => $attachment->url, 'fullurl' => cdnurl($attachment->url, true)]);
}
}
... ... @@ -171,6 +173,9 @@ class Ajax extends Backend
$offset = isset($temp[$m - 1]) ? $temp[$m - 1] : $sour_id;
}
}
if (!isset($weighdata[$offset])) {
continue;
}
$weighids[$n] = $weighdata[$offset];
Db::name($table)->where($prikey, $n)->update([$field => $weighdata[$offset]]);
}
... ...
... ... @@ -22,6 +22,8 @@ class Admin extends Backend
* @var \app\admin\model\Admin
*/
protected $model = null;
protected $selectpageFields = 'id,username,nickname,avatar';
protected $searchFields = 'id,username,nickname';
protected $childrenGroupIds = [];
protected $childrenAdminIds = [];
... ... @@ -218,6 +220,10 @@ class Admin extends Backend
*/
public function del($ids = "")
{
if (!$this->request->isPost()) {
$this->error(__("Invalid parameters"));
}
$ids = $ids ? $ids : $this->request->post("ids");
if ($ids) {
$ids = array_intersect($this->childrenAdminIds, array_filter(explode(',', $ids)));
// 避免越权删除管理员
... ...
... ... @@ -8,7 +8,7 @@ use app\common\controller\Backend;
/**
* 管理员日志
*
* @icon fa fa-users
* @icon fa fa-users
* @remark 管理员可以查看自己所拥有的权限的管理员日志
*/
class Adminlog extends Backend
... ... @@ -30,7 +30,7 @@ class Adminlog extends Backend
$this->childrenGroupIds = $this->auth->getChildrenGroupIds($this->auth->isSuperAdmin() ? true : false);
$groupName = AuthGroup::where('id', 'in', $this->childrenGroupIds)
->column('id,name');
->column('id,name');
$this->view->assign('groupdata', $groupName);
}
... ... @@ -40,21 +40,20 @@ class Adminlog extends Backend
*/
public function index()
{
if ($this->request->isAjax())
{
if ($this->request->isAjax()) {
list($where, $sort, $order, $offset, $limit) = $this->buildparams();
$total = $this->model
->where($where)
->where('admin_id', 'in', $this->childrenAdminIds)
->order($sort, $order)
->count();
->where($where)
->where('admin_id', 'in', $this->childrenAdminIds)
->order($sort, $order)
->count();
$list = $this->model
->where($where)
->where('admin_id', 'in', $this->childrenAdminIds)
->order($sort, $order)
->limit($offset, $limit)
->select();
->where($where)
->where('admin_id', 'in', $this->childrenAdminIds)
->order($sort, $order)
->limit($offset, $limit)
->select();
$result = array("total" => $total, "rows" => $list);
return json($result);
... ... @@ -68,8 +67,9 @@ class Adminlog extends Backend
public function detail($ids)
{
$row = $this->model->get(['id' => $ids]);
if (!$row)
if (!$row) {
$this->error(__('No Results were found'));
}
$this->view->assign("row", $row->toArray());
return $this->view->fetch();
}
... ... @@ -87,7 +87,7 @@ class Adminlog extends Backend
* 编辑
* @internal
*/
public function edit($ids = NULL)
public function edit($ids = null)
{
$this->error();
}
... ... @@ -97,21 +97,21 @@ class Adminlog extends Backend
*/
public function del($ids = "")
{
if ($ids)
{
if (!$this->request->isPost()) {
$this->error(__("Invalid parameters"));
}
$ids = $ids ? $ids : $this->request->post("ids");
if ($ids) {
$childrenGroupIds = $this->childrenGroupIds;
$adminList = $this->model->where('id', 'in', $ids)->where('admin_id', 'in', function($query) use($childrenGroupIds) {
$query->name('auth_group_access')->field('uid');
})->select();
if ($adminList)
{
$adminList = $this->model->where('id', 'in', $ids)->where('admin_id', 'in', function ($query) use ($childrenGroupIds) {
$query->name('auth_group_access')->field('uid');
})->select();
if ($adminList) {
$deleteIds = [];
foreach ($adminList as $k => $v)
{
foreach ($adminList as $k => $v) {
$deleteIds[] = $v->id;
}
if ($deleteIds)
{
if ($deleteIds) {
$this->model->destroy($deleteIds);
$this->success();
}
... ... @@ -129,10 +129,9 @@ class Adminlog extends Backend
// 管理员禁止批量操作
$this->error();
}
public function selectpage()
{
return parent::selectpage();
}
}
... ...
... ... @@ -11,7 +11,7 @@ use think\Exception;
/**
* 角色组
*
* @icon fa fa-group
* @icon fa fa-group
* @remark 角色组可以有多个,角色有上下级层级关系,如果子角色有角色组和管理员的权限则可以派生属于自己组别下级的角色组或管理员
*/
class Group extends Backend
... ... @@ -140,7 +140,7 @@ class Group extends Backend
$this->error(__('The parent group exceeds permission limit'));
}
// 父节点不能是它自身的子节点或自己本身
if (in_array($params['pid'], Tree::instance()->getChildrenIds($row->id,true))){
if (in_array($params['pid'], Tree::instance()->getChildrenIds($row->id, true))) {
$this->error(__('The parent group can not be its own child or itself'));
}
$params['rules'] = explode(',', $params['rules']);
... ... @@ -163,16 +163,16 @@ class Group extends Backend
Db::startTrans();
try {
$row->save($params);
$children_auth_groups = model("AuthGroup")->all(['id'=>['in',implode(',',(Tree::instance()->getChildrenIds($row->id)))]]);
$children_auth_groups = model("AuthGroup")->all(['id' => ['in', implode(',', (Tree::instance()->getChildrenIds($row->id)))]]);
$childparams = [];
foreach ($children_auth_groups as $key=>$children_auth_group) {
foreach ($children_auth_groups as $key => $children_auth_group) {
$childparams[$key]['id'] = $children_auth_group->id;
$childparams[$key]['rules'] = implode(',', array_intersect(explode(',', $children_auth_group->rules), $rules));
}
model("AuthGroup")->saveAll($childparams);
Db::commit();
$this->success();
}catch (Exception $e){
} catch (Exception $e) {
Db::rollback();
$this->error($e->getMessage());
}
... ... @@ -189,6 +189,10 @@ class Group extends Backend
*/
public function del($ids = "")
{
if (!$this->request->isPost()) {
$this->error(__("Invalid parameters"));
}
$ids = $ids ? $ids : $this->request->post("ids");
if ($ids) {
$ids = explode(',', $ids);
$grouplist = $this->auth->getGroups();
... ...
... ... @@ -134,6 +134,10 @@ class Rule extends Backend
*/
public function del($ids = "")
{
if (!$this->request->isPost()) {
$this->error(__("Invalid parameters"));
}
$ids = $ids ? $ids : $this->request->post("ids");
if ($ids) {
$delIds = [];
foreach (explode(',', $ids) as $k => $v) {
... ...
... ... @@ -103,6 +103,10 @@ class Attachment extends Backend
*/
public function del($ids = "")
{
if (!$this->request->isPost()) {
$this->error(__("Invalid parameters"));
}
$ids = $ids ? $ids : $this->request->post("ids");
if ($ids) {
\think\Hook::add('upload_delete', function ($params) {
if ($params['storage'] == 'local') {
... ...
... ... @@ -5,6 +5,8 @@ namespace app\admin\controller\general;
use app\common\controller\Backend;
use app\common\library\Email;
use app\common\model\Config as ConfigModel;
use think\Cache;
use think\Db;
use think\Exception;
use think\Validate;
... ... @@ -21,7 +23,7 @@ class Config extends Backend
* @var \app\common\model\Config
*/
protected $model = null;
protected $noNeedRight = ['check', 'rulelist'];
protected $noNeedRight = ['check', 'rulelist', 'selectpage', 'get_fields_list'];
public function _initialize()
{
... ... @@ -82,7 +84,7 @@ class Config extends Backend
$params = $this->request->post("row/a", [], 'trim');
if ($params) {
foreach ($params as $k => &$v) {
$v = is_array($v) ? implode(',', $v) : $v;
$v = is_array($v) && $k !== 'setting' ? implode(',', $v) : $v;
}
if (in_array($params['type'], ['select', 'selects', 'checkbox', 'radio', 'array'])) {
$params['content'] = json_encode(ConfigModel::decode($params['content']), JSON_UNESCAPED_UNICODE);
... ... @@ -202,12 +204,12 @@ class Config extends Backend
if ($params) {
$config = $this->model->get($params);
if (!$config) {
return $this->success();
$this->success();
} else {
return $this->error(__('Name already exist'));
$this->error(__('Name already exist'));
}
} else {
return $this->error(__('Invalid parameters'));
$this->error(__('Invalid parameters'));
}
}
... ... @@ -262,7 +264,51 @@ class Config extends Backend
$this->error($email->getError());
}
} else {
return $this->error(__('Invalid parameters'));
$this->error(__('Invalid parameters'));
}
}
public function selectpage()
{
$id = $this->request->get("id/d");
$config = \app\common\model\Config::get($id);
if (!$config) {
$this->error(__('Invalid parameters'));
}
$setting = $config['setting'];
//自定义条件
$custom = isset($setting['conditions']) ? (array)json_decode($setting['conditions'], true) : [];
$custom = array_filter($custom);
$this->request->request(['showField' => $setting['field'], 'keyField' => $setting['primarykey'], 'custom' => $custom, 'searchField' => [$setting['field'], $setting['primarykey']]]);
$this->model = \think\Db::connect()->setTable($setting['table']);
return parent::selectpage();
}
/**
* 获取表列表
* @internal
*/
public function get_table_list()
{
$tableList = [];
$dbname = \think\Config::get('database.database');
$tableList = \think\Db::query("SELECT `TABLE_NAME` AS `name`,`TABLE_COMMENT` AS `title` FROM `information_schema`.`TABLES` where `TABLE_SCHEMA` = '{$dbname}';");
$this->success('', null, ['tableList' => $tableList]);
}
/**
* 获取表字段列表
* @internal
*/
public function get_fields_list()
{
$table = $this->request->request('table');
$dbname = \think\Config::get('database.database');
//从数据库中获取表字段信息
$sql = "SELECT `COLUMN_NAME` AS `name`,`COLUMN_COMMENT` AS `title`,`DATA_TYPE` AS `type` FROM `information_schema`.`columns` WHERE TABLE_SCHEMA = ? AND TABLE_NAME = ? ORDER BY ORDINAL_POSITION";
//加载主表的列
$fieldList = Db::query($sql, [$dbname, $table]);
$this->success("", null, ['fieldList' => $fieldList]);
}
}
... ...
... ... @@ -87,6 +87,10 @@ class Rule extends Backend
*/
public function del($ids = "")
{
if (!$this->request->isPost()) {
$this->error(__("Invalid parameters"));
}
$ids = $ids ? $ids : $this->request->post("ids");
if ($ids) {
$delIds = [];
foreach (explode(',', $ids) as $k => $v) {
... ...
... ... @@ -52,6 +52,7 @@ class User extends Backend
->limit($offset, $limit)
->select();
foreach ($list as $k => $v) {
$v->avatar = $v->avatar ? cdnurl($v->avatar, true) : letter_avatar($v->nickname);
$v->hidden(['password', 'salt']);
}
$result = array("total" => $total, "rows" => $list);
... ... @@ -94,6 +95,10 @@ class User extends Backend
*/
public function del($ids = "")
{
if (!$this->request->isPost()) {
$this->error(__("Invalid parameters"));
}
$ids = $ids ? $ids : $this->request->post("ids");
$row = $this->model->get($ids);
$this->modelValidate = true;
if (!$row) {
... ...
... ... @@ -96,6 +96,9 @@ return [
'End time' => '结束时间',
'Create time' => '创建时间',
'Update time' => '更新时间',
'Createtime' => '创建时间',
'Updatetime' => '更新时间',
'Deletetime' => '删除时间',
'Flag' => '标志',
'Drag to sort' => '拖动进行排序',
'Redirect now' => '立即跳转',
... ... @@ -164,7 +167,7 @@ return [
'An unexpected error occurred' => '发生了一个意外错误,程序猿正在紧急处理中',
'This page will be re-directed in %s seconds' => '页面将在 %s 秒后自动跳转',
'Click to uncheck all' => '点击取消全部',
'Multiple selection mode: %s checked' => '跨页选择模式,已选 %s 项',
'Multiple selection mode: %s checked' => '跨页选择模式,已选 %s 项',
//菜单
'Dashboard' => '控制台',
'General' => '常规管理',
... ...
<?php
return [
'Id' => 'ID',
'Title' => '插件名称',
'Value' => '配置值',
'Array key' => '键',
'Array value' => '值',
'File' => '文件',
'Donate' => '打赏作者',
'Warmtips' => '温馨提示',
'Pay now' => '立即支付',
'Offline install' => '离线安装',
'Refresh addon cache' => '刷新插件缓存',
'Userinfo' => '会员信息',
'Online store' => '在线商店',
'Local addon' => '本地插件',
'Conflict tips' => '此插件中发现和现有系统中部分文件发现冲突!以下文件将会被影响,请备份好相关文件后再继续操作',
'Login tips' => '此处登录账号为<a href="https://www.fastadmin.net" target="_blank">FastAdmin官网账号</a>',
'Logined tips' => '你好!%s<br />当前你已经登录,将同步保存你的购买记录',
'Pay tips' => '扫码支付后如果仍然无法立即下载,请不要重复支付,请稍后再重试安装!',
'Pay click tips' => '请点击这里在新窗口中进行支付!',
'Pay new window tips' => '请在新弹出的窗口中进行支付,支付完成后再重新点击安装按钮进行安装!',
'Uninstall tips' => '确认卸载<b>[%s]</b>?<p class="text-danger">卸载将会删除所有插件文件且不可找回!!! 插件如果有创建数据库表请手动删除!!!</p>如有重要数据请备份后再操作!',
'Upgrade tips' => '确认升级<b>[%s]</b>?<p class="text-danger">升级后可能出现部分冗余数据记录,请根据需要移除即可!!!</p>如有重要数据请备份后再操作!',
'Offline installed tips' => '插件安装成功!清除浏览器缓存和框架缓存后生效!',
'Online installed tips' => '插件安装成功!清除浏览器缓存和框架缓存后生效!',
'Not login tips' => '你当前未登录FastAdmin,登录后将同步已购买的记录,下载时无需二次付费!',
'Not installed tips' => '请安装后再访问插件前台页面!',
'Not enabled tips' => '插件已经禁用,请启用后再访问插件前台页面!',
'New version tips' => '发现新版本:%s 点击查看更新日志',
'Store now available tips' => '插件市场暂不可用,是否切换到本地插件?',
'Switch to the local' => '切换到本地插件',
'try to reload' => '重新尝试加载',
'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' => '点击与插件开发者取得联系',
'My addons' => '我购买的插件',
'My posts' => '我发布的插件',
'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' => '演示',
'Feedback' => '反馈BUG',
'Install' => '安装',
'Uninstall' => '卸载',
'Upgrade' => '升级',
'Setting' => '配置',
'Disable' => '禁用',
'Enable' => '启用',
'Your username or email' => '你的手机号、用户名或邮箱',
'Your password' => '你的密码',
'Login FastAdmin' => '登录',
'Login' => '登录',
'Logout' => '退出登录',
'Register' => '注册账号',
'You\'re not login' => '当前未登录',
'Continue uninstall' => '继续卸载',
'Continue operate' => '继续操作',
'Install successful' => '安装成功',
'Uninstall successful' => '卸载成功',
'Operate successful' => '操作成功',
'Addon name incorrect' => '插件名称不正确',
'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文件',
'Id' => 'ID',
'Title' => '名称',
'Value' => '配置值',
'Array key' => '键',
'Array value' => '值',
'File' => '文件',
'Donate' => '打赏作者',
'Warmtips' => '温馨提示',
'Pay now' => '立即支付',
'Offline install' => '离线安装',
'Refresh addon cache' => '刷新插件缓存',
'Userinfo' => '会员信息',
'Online store' => '在线商店',
'Local addon' => '本地插件',
'Conflict tips' => '此插件中发现和现有系统中部分文件发现冲突!以下文件将会被影响,请备份好相关文件后再继续操作',
'Login tips' => '此处登录账号为<a href="https://www.fastadmin.net" target="_blank">FastAdmin官网账号</a>',
'Logined tips' => '你好!%s<br />当前你已经登录,将同步保存你的购买记录',
'Pay tips' => '扫码支付后如果仍然无法立即下载,请不要重复支付,请稍后再重试安装!',
'Pay click tips' => '请点击这里在新窗口中进行支付!',
'Pay new window tips' => '请在新弹出的窗口中进行支付,支付完成后再重新点击安装按钮进行安装!',
'Upgrade tips' => '确认升级<b>[%s]</b>?<p class="text-danger">升级后可能出现部分冗余数据记录,请根据需要移除即可!!!</p>如有重要数据请备份后再操作!',
'Offline installed tips' => '插件安装成功!清除浏览器缓存和框架缓存后生效!',
'Online installed tips' => '插件安装成功!清除浏览器缓存和框架缓存后生效!',
'Not login tips' => '你当前未登录FastAdmin,登录后将同步已购买的记录,下载时无需二次付费!',
'Not installed tips' => '请安装后再访问插件前台页面!',
'Not enabled tips' => '插件已经禁用,请启用后再访问插件前台页面!',
'New version tips' => '发现新版本:%s 点击查看更新日志',
'Store now available tips' => '插件市场暂不可用,是否切换到本地插件?',
'Switch to the local' => '切换到本地插件',
'try to reload' => '重新尝试加载',
'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' => '点击与插件开发者取得联系',
'My addons' => '我购买的插件',
'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' => '演示',
'Feedback' => '反馈BUG',
'Install' => '安装',
'Uninstall' => '卸载',
'Upgrade' => '升级',
'Setting' => '配置',
'Disable' => '禁用',
'Enable' => '启用',
'Your username or email' => '你的手机号、用户名或邮箱',
'Your password' => '你的密码',
'Login FastAdmin' => '登录',
'Login' => '登录',
'Logout' => '退出登录',
'Register' => '注册账号',
'You\'re not login' => '当前未登录',
'Continue uninstall' => '继续卸载',
'Continue operate' => '继续操作',
'Install successful' => '安装成功',
'Uninstall successful' => '卸载成功',
'Operate successful' => '操作成功',
'Addon name incorrect' => '插件名称不正确',
'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文件',
'Are you sure you want to unstall %s?' => '确认卸载插件《%s》?',
'Delete all the addon file and cannot be recovered!' => '卸载将会删除所有插件文件且不可找回!!!',
'Delete all the addon database and cannot be recovered!' => '删除所有插件相关数据表且不可找回!!!',
'Please backup important data manually before uninstall!' => '如有重要数据请备份后再操作!!!',
'The following data tables will be deleted' => '以下插件数据表将会被删除',
'The Addon did not create a data table' => '插件未创建任何数据表',
];
... ...
... ... @@ -13,6 +13,12 @@ return [
'Filename' => '文件名',
'Filesize' => '文件大小',
'Mimetype' => 'Mime类型',
'Image' => '图片',
'Audio' => '音频',
'Video' => '视频',
'Text' => '文档',
'Application' => '应用',
'Zip' => '压缩包',
'Extparam' => '透传数据',
'Createtime' => '创建日期',
'Uploadtime' => '上传时间',
... ...
... ... @@ -21,6 +21,7 @@ return [
'Date' => '日期',
'Time' => '时间',
'Datetime' => '日期时间',
'Datetimerange' => '日期时间区间',
'Image' => '图片',
'Images' => '图片(多)',
'File' => '文件',
... ... @@ -33,7 +34,17 @@ return [
'Array' => '数组',
'Array key' => '键名',
'Array value' => '键值',
'City' => '城市地区',
'Selectpage' => '关联表',
'Selectpages' => '关联表(多选)',
'Custom' => '自定义',
'Please select table' => '关联表',
'Selectpage table' => '关联表',
'Selectpage primarykey' => '存储字段',
'Selectpage field' => '显示字段',
'Selectpage conditions' => '筛选条件',
'Field title' => '字段名',
'Field value' => '字段值',
'Content' => '数据列表',
'Rule' => '校验规则',
'Site name' => '站点名称',
... ...
... ... @@ -200,7 +200,10 @@ trait Backend
*/
public function del($ids = "")
{
$ids = $this->request->post("ids");
if (!$this->request->isPost()) {
$this->error(__("Invalid parameters"));
}
$ids = $ids ? $ids : $this->request->post("ids");
if ($ids) {
$pk = $this->model->getPk();
$adminIds = $this->getDataLimitAdminIds();
... ... @@ -237,6 +240,10 @@ trait Backend
*/
public function destroy($ids = "")
{
if (!$this->request->isPost()) {
$this->error(__("Invalid parameters"));
}
$ids = $ids ? $ids : $this->request->post("ids");
$pk = $this->model->getPk();
$adminIds = $this->getDataLimitAdminIds();
if (is_array($adminIds)) {
... ... @@ -273,6 +280,10 @@ trait Backend
*/
public function restore($ids = "")
{
if (!$this->request->isPost()) {
$this->error(__("Invalid parameters"));
}
$ids = $ids ? $ids : $this->request->post("ids");
$pk = $this->model->getPk();
$adminIds = $this->getDataLimitAdminIds();
if (is_array($adminIds)) {
... ... @@ -307,8 +318,10 @@ trait Backend
*/
public function multi($ids = "")
{
$ids = $ids ? $ids : $this->request->param("ids");
$ids = $this->request->param("ids");
if (!$this->request->isPost()) {
$this->error(__("Invalid parameters"));
}
$ids = $ids ? $ids : $this->request->post("ids");
if ($ids) {
if ($this->request->has('params')) {
parse_str($this->request->post("params"), $values);
... ...
... ... @@ -53,11 +53,13 @@
position: absolute;
box-shadow: 0px 0px 2px #f11414;
}
.form-userinfo .breadcrumb {
margin-bottom:10px;
margin-bottom: 10px;
}
.btn-toggle {
padding:0;
padding: 0;
}
</style>
<div class="panel panel-default panel-intro">
... ... @@ -77,7 +79,7 @@
<div class="widget-body no-padding">
<div id="toolbar" class="toolbar">
{:build_toolbar('refresh')}
<button type="button" id="faupload-addon" class="btn btn-danger faupload" data-url="addon/local" data-mimetype="zip" data-multiple="false"><i class="fa fa-upload"></i>
<button type="button" id="faupload-addon" class="btn btn-danger faupload" data-url="addon/local" data-chunking="false" data-mimetype="zip" data-multiple="false"><i class="fa fa-upload"></i>
{:__('Offline install')}
</button>
{if $Think.config.fastadmin.api_url}
... ... @@ -170,8 +172,8 @@
<div class="col-lg-12">
<div class="input-group">
<span class="input-group-addon"><i class="fa fa-lock"></i></span>
<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>
</div>
... ... @@ -189,7 +191,6 @@
</div>
</fieldset>
<div class="breadcrumb"><a href="https://www.fastadmin.net/user/myaddon.html" target="_blank"><i class="fa fa-money"></i> {:__('My addons')}</a></div>
<div class="breadcrumb"><a href="https://www.fastadmin.net/user/addon.html" target="_blank"><i class="fa fa-upload"></i> {:__('My posts')}</a></div>
</form>
</div>
</script>
... ... @@ -205,6 +206,17 @@
<%}%>
</div>
</script>
<script id="uninstalltpl" type="text/html">
<div class="">
<div class=""><%=__("Are you sure you want to unstall %s?", addon['title'])%>
<p class="text-danger">{:__('Delete all the addon file and cannot be recovered!')} </p>
{if config('app_debug')}
<p class="text-danger"><input type="checkbox" name="droptables" id="droptables" data-name="<%=addon['name']%>"/> {:__('Delete all the addon database and cannot be recovered!')} </p>
{/if}
<p class="text-danger">{:__('Please backup important data manually before uninstall!')}</p>
</div>
</div>
</script>
<script id="conflicttpl" type="text/html">
<div class="alert alert-dismissable alert-danger">
<button type="button" class="close" data-dismiss="alert">×</button>
... ... @@ -251,7 +263,7 @@
<% } %>
</ul>
</span>
<% }else{%>
<% }else if(typeof item.releaselist !="undefined" && item.releaselist.length>0){%>
<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>
... ... @@ -262,6 +274,12 @@
<i class="fa fa-flash"></i> {:__('Demo')}
</a>
<% } %>
<% if(item.button){ %>
<a href="<%=item.url%>" class="btn btn-xs btn-primary btn-info" target="_blank">
<%=item.button%>
</a>
<% } %>
<% } else {%>
<% if(addon.version!=item.version){%>
<% if(typeof item.releaselist !="undefined" && item.releaselist.length>1){%>
... ...
... ... @@ -5,6 +5,10 @@
.skin-list li a{
display: block; box-shadow: 0 0 3px rgba(0,0,0,0.4);
}
.skin-list li a span{
display: block;
float:left;
}
</style>
<!-- Control Sidebar -->
<aside class="control-sidebar control-sidebar-dark">
... ... @@ -29,18 +33,26 @@
<div class="form-group"><label class="control-sidebar-subheading"><input type="checkbox" data-sidebarskin="toggle" class="pull-right"> {:__('Toggle Right Sidebar Skin')}</label><p>{:__('Toggle between dark and light skins for the right sidebar')}</p></div>
<h4 class="control-sidebar-heading">{:__('Skins')}</h4>
<ul class="list-unstyled clearfix skin-list">
<li><a href="javascript:;" data-skin="skin-blue" style="" class="clearfix full-opacity-hover"><div><span style="display:block; width: 20%; float: left; height: 7px; background: #367fa9;"></span><span class="bg-light-blue" style="display:block; width: 80%; float: left; height: 7px;"></span></div><div><span style="display:block; width: 20%; float: left; height: 20px; background: #222d32;"></span><span style="display:block; width: 80%; float: left; height: 20px; background: #f4f5f7;"></span></div></a><p class="text-center no-margin">Blue</p></li>
<li><a href="javascript:;" data-skin="skin-white" class="clearfix full-opacity-hover"><div style="box-shadow: 0 0 2px rgba(0,0,0,0.1)" class="clearfix"><span style="display:block; width: 20%; float: left; height: 7px; background: #fefefe;"></span><span style="display:block; width: 80%; float: left; height: 7px; background: #fefefe;"></span></div><div><span style="display:block; width: 20%; float: left; height: 20px; background: #222;"></span><span style="display:block; width: 80%; float: left; height: 20px; background: #f4f5f7;"></span></div></a><p class="text-center no-margin">White</p></li>
<li><a href="javascript:;" data-skin="skin-purple" class="clearfix full-opacity-hover"><div><span style="display:block; width: 20%; float: left; height: 7px;" class="bg-purple-active"></span><span class="bg-purple" style="display:block; width: 80%; float: left; height: 7px;"></span></div><div><span style="display:block; width: 20%; float: left; height: 20px; background: #222d32;"></span><span style="display:block; width: 80%; float: left; height: 20px; background: #f4f5f7;"></span></div></a><p class="text-center no-margin">Purple</p></li>
<li><a href="javascript:;" data-skin="skin-green" class="clearfix full-opacity-hover"><div><span style="display:block; width: 20%; float: left; height: 7px;" class="bg-green-active"></span><span class="bg-green" style="display:block; width: 80%; float: left; height: 7px;"></span></div><div><span style="display:block; width: 20%; float: left; height: 20px; background: #222d32;"></span><span style="display:block; width: 80%; float: left; height: 20px; background: #f4f5f7;"></span></div></a><p class="text-center no-margin">Green</p></li>
<li><a href="javascript:;" data-skin="skin-red" class="clearfix full-opacity-hover"><div><span style="display:block; width: 20%; float: left; height: 7px;" class="bg-red-active"></span><span class="bg-red" style="display:block; width: 80%; float: left; height: 7px;"></span></div><div><span style="display:block; width: 20%; float: left; height: 20px; background: #222d32;"></span><span style="display:block; width: 80%; float: left; height: 20px; background: #f4f5f7;"></span></div></a><p class="text-center no-margin">Red</p></li>
<li><a href="javascript:;" data-skin="skin-yellow" class="clearfix full-opacity-hover"><div><span style="display:block; width: 20%; float: left; height: 7px;" class="bg-yellow-active"></span><span class="bg-yellow" style="display:block; width: 80%; float: left; height: 7px;"></span></div><div><span style="display:block; width: 20%; float: left; height: 20px; background: #222d32;"></span><span style="display:block; width: 80%; float: left; height: 20px; background: #f4f5f7;"></span></div></a><p class="text-center no-margin">Yellow</p></li>
<li><a href="javascript:;" data-skin="skin-blue-light" class="clearfix full-opacity-hover"><div><span style="display:block; width: 20%; float: left; height: 7px; background: #367fa9;"></span><span class="bg-light-blue" style="display:block; width: 80%; float: left; height: 7px;"></span></div><div><span style="display:block; width: 20%; float: left; height: 20px; background: #f9fafc;"></span><span style="display:block; width: 80%; float: left; height: 20px; background: #f4f5f7;"></span></div></a><p class="text-center no-margin" style="font-size: 12px">Blue Light</p></li>
<li><a href="javascript:;" data-skin="skin-white-light" class="clearfix full-opacity-hover"><div style="box-shadow: 0 0 2px rgba(0,0,0,0.1)" class="clearfix"><span style="display:block; width: 20%; float: left; height: 7px; background: #fefefe;"></span><span style="display:block; width: 80%; float: left; height: 7px; background: #fefefe;"></span></div><div><span style="display:block; width: 20%; float: left; height: 20px; background: #f9fafc;"></span><span style="display:block; width: 80%; float: left; height: 20px; background: #f4f5f7;"></span></div></a><p class="text-center no-margin" style="font-size: 12px">White Light</p></li>
<li><a href="javascript:;" data-skin="skin-purple-light" class="clearfix full-opacity-hover"><div><span style="display:block; width: 20%; float: left; height: 7px;" class="bg-purple-active"></span><span class="bg-purple" style="display:block; width: 80%; float: left; height: 7px;"></span></div><div><span style="display:block; width: 20%; float: left; height: 20px; background: #f9fafc;"></span><span style="display:block; width: 80%; float: left; height: 20px; background: #f4f5f7;"></span></div></a><p class="text-center no-margin" style="font-size: 12px">Purple Light</p></li>
<li><a href="javascript:;" data-skin="skin-green-light" class="clearfix full-opacity-hover"><div><span style="display:block; width: 20%; float: left; height: 7px;" class="bg-green-active"></span><span class="bg-green" style="display:block; width: 80%; float: left; height: 7px;"></span></div><div><span style="display:block; width: 20%; float: left; height: 20px; background: #f9fafc;"></span><span style="display:block; width: 80%; float: left; height: 20px; background: #f4f5f7;"></span></div></a><p class="text-center no-margin" style="font-size: 12px">Green Light</p></li>
<li><a href="javascript:;" data-skin="skin-red-light" class="clearfix full-opacity-hover"><div><span style="display:block; width: 20%; float: left; height: 7px;" class="bg-red-active"></span><span class="bg-red" style="display:block; width: 80%; float: left; height: 7px;"></span></div><div><span style="display:block; width: 20%; float: left; height: 20px; background: #f9fafc;"></span><span style="display:block; width: 80%; float: left; height: 20px; background: #f4f5f7;"></span></div></a><p class="text-center no-margin" style="font-size: 12px">Red Light</p></li>
<li><a href="javascript:;" data-skin="skin-yellow-light" class="clearfix full-opacity-hover"><div><span style="display:block; width: 20%; float: left; height: 7px;" class="bg-yellow-active"></span><span class="bg-yellow" style="display:block; width: 80%; float: left; height: 7px;"></span></div><div><span style="display:block; width: 20%; float: left; height: 20px; background: #f9fafc;"></span><span style="display:block; width: 80%; float: left; height: 20px; background: #f4f5f7;"></span></div></a><p class="text-center no-margin" style="font-size: 12px;">Yellow Light</p></li>
<li><a href="javascript:;" data-skin="skin-blue" class="clearfix full-opacity-hover"><div><span style="width: 20%; height: 27px; background: #4e73df;"></span><span style="width: 80%; height: 27px; background: #f4f5f7;"></span></div></a><p class="text-center no-margin">Blue</p></li>
<li><a href="javascript:;" data-skin="skin-black" class="clearfix full-opacity-hover"><div><span style="width: 20%; height: 27px; background: #000;"></span><span style="width: 80%; height: 27px; background: #f4f5f7;"></span></div></a><p class="text-center no-margin">Black</p></li>
<li><a href="javascript:;" data-skin="skin-purple" class="clearfix full-opacity-hover"><div><span style="width: 20%; height: 27px; background: #605ca8;"></span><span style="width: 80%; height: 27px; background: #f4f5f7;"></span></div></a><p class="text-center no-margin">Purple</p></li>
<li><a href="javascript:;" data-skin="skin-green" class="clearfix full-opacity-hover"><div><span style="width: 20%; height: 7px;" class="bg-green-active"></span><span class="bg-green" style="width: 80%; height: 7px;"></span></div><div><span style="width: 20%; height: 20px; background: #000;"></span><span style="width: 80%; height: 20px; background: #f4f5f7;"></span></div></a><p class="text-center no-margin">Green</p></li>
<li><a href="javascript:;" data-skin="skin-red" class="clearfix full-opacity-hover"><div><span style="width: 20%; height: 7px;" class="bg-red-active"></span><span class="bg-red" style="width: 80%; height: 7px;"></span></div><div><span style="width: 20%; height: 20px; background: #000;"></span><span style="width: 80%; height: 20px; background: #f4f5f7;"></span></div></a><p class="text-center no-margin">Red</p></li>
<li><a href="javascript:;" data-skin="skin-yellow" class="clearfix full-opacity-hover"><div><span style="width: 20%; height: 7px;" class="bg-yellow-active"></span><span class="bg-yellow" style="width: 80%; height: 7px;"></span></div><div><span style="width: 20%; height: 20px; background: #000;"></span><span style="width: 80%; height: 20px; background: #f4f5f7;"></span></div></a><p class="text-center no-margin">Yellow</p></li>
<li><a href="javascript:;" data-skin="skin-blue-light" class="clearfix full-opacity-hover"><div><span style="width: 100%; height: 7px; background: #4e73df;"></span></div><div><span style="width: 100%; height: 20px; background: #f9fafc;"></span></div></a><p class="text-center no-margin" style="font-size: 12px">Blue Light</p></li>
<li><a href="javascript:;" data-skin="skin-black-light" class="clearfix full-opacity-hover"><div><span style="width: 100%; height: 7px; background: #000;"></span></div><div><span style="width: 100%; height: 20px; background: #f9fafc;"></span></div></a><p class="text-center no-margin" style="font-size: 12px">Black Light</p></li>
<li><a href="javascript:;" data-skin="skin-purple-light" class="clearfix full-opacity-hover"><div><span style="width: 100%; height: 7px; background: #605ca8;"></span></div><div><span style="width: 100%; height: 20px; background: #f9fafc;"></span></div></a><p class="text-center no-margin" style="font-size: 12px">Purple Light</p></li>
<li><a href="javascript:;" data-skin="skin-green-light" class="clearfix full-opacity-hover"><div><span style="width: 100%; height: 7px;" class="bg-green"></span></div><div><span style="width: 100%; height: 20px; background: #f9fafc;"></span></div></a><p class="text-center no-margin" style="font-size: 12px">Green Light</p></li>
<li><a href="javascript:;" data-skin="skin-red-light" class="clearfix full-opacity-hover"><div><span style="width: 100%; height: 7px;" class="bg-red"></span></div><div><span style="width: 100%; height: 20px; background: #f9fafc;"></span></div></a><p class="text-center no-margin" style="font-size: 12px">Red Light</p></li>
<li><a href="javascript:;" data-skin="skin-yellow-light" class="clearfix full-opacity-hover"><div><span style="width: 100%; height: 7px;" class="bg-yellow"></span></div><div><span style="width: 100%; height: 20px; background: #f9fafc;"></span></div></a><p class="text-center no-margin" style="font-size: 12px">Yellow Light</p></li>
<li><a href="javascript:;" data-skin="skin-black-blue" class="clearfix full-opacity-hover"><div><span style="width: 20%; height: 27px; background: #000;"><span style="width: 100%; height: 3px; margin-top:10px; background: #4e73df;"></span></span><span style="width: 80%; height: 27px; background: #f4f5f7;"></span></div></a><p class="text-center no-margin">Black Blue</p></li>
<li><a href="javascript:;" data-skin="skin-black-purple" class="clearfix full-opacity-hover"><div><span style="width: 20%; height: 27px; background: #000;"><span style="width: 100%; height: 3px; margin-top:10px; background: #605ca8;"></span></span><span style="width: 80%; height: 27px; background: #f4f5f7;"></span></div></a><p class="text-center no-margin">Black Purple</p></li>
<li><a href="javascript:;" data-skin="skin-black-green" class="clearfix full-opacity-hover"><div><span style="width: 20%; height: 27px; background: #000;"><span style="width: 100%; height: 3px; margin-top:10px;" class="bg-green"></span></span><span style="width: 80%; height: 27px; background: #f4f5f7;"></span></div></a><p class="text-center no-margin">Black Green</p></li>
<li><a href="javascript:;" data-skin="skin-black-red" class="clearfix full-opacity-hover"><div><span style="width: 20%; height: 27px; background: #000;"><span style="width: 100%; height: 3px; margin-top:10px;" class="bg-red"></span></span><span style="width: 80%; height: 27px; background: #f4f5f7;"></span></div></a><p class="text-center no-margin">Black Red</p></li>
<li><a href="javascript:;" data-skin="skin-black-yellow" class="clearfix full-opacity-hover"><div><span style="width: 20%; height: 27px; background: #000;"><span style="width: 100%; height: 3px; margin-top:10px;" class="bg-yellow"></span></span><span style="width: 80%; height: 27px; background: #f4f5f7;"></span></div></a><p class="text-center no-margin">Black Yellow</p></li>
<li><a href="javascript:;" data-skin="skin-black-pink" class="clearfix full-opacity-hover"><div><span style="width: 20%; height: 27px; background: #000;"><span style="width: 100%; height: 3px; margin-top:10px; background: #f5549f;"></span></span><span style="width: 80%; height: 27px; background: #f4f5f7;"></span></div></a><p class="text-center no-margin">Black Pink</p></li>
</ul>
</div>
<!-- /.tab-pane -->
... ... @@ -56,4 +68,4 @@
<!-- /.tab-pane -->
</div>
</aside>
<!-- /.control-sidebar -->
\ No newline at end of file
<!-- /.control-sidebar -->
... ...
... ... @@ -3,7 +3,7 @@
<!-- 迷你模式下Logo的大小为50X50 -->
<span class="logo-mini">{$site.name|mb_substr=0,4,'utf-8'|mb_strtoupper='utf-8'|htmlentities}</span>
<!-- 普通模式下Logo -->
<span class="logo-lg"><b>{$site.name|mb_substr=0,4,'utf-8'|htmlentities}</b>{$site.name|mb_substr=4,null,'utf-8'|htmlentities}</span>
<span class="logo-lg">{$site.name|htmlentities}</span>
</a>
<!-- 顶部通栏样式 -->
... ...
... ... @@ -8,6 +8,10 @@
<!-- Loading Bootstrap -->
<link href="__CDN__/assets/css/backend{$Think.config.app_debug?'':'.min'}.css?v={$Think.config.site.version}" rel="stylesheet">
{if $Think.config.fastadmin.adminskin}
<link href="__CDN__/assets/css/skins/{$Think.config.fastadmin.adminskin}.css?v={$Think.config.site.version}" rel="stylesheet">
{/if}
<!-- HTML5 shim, for IE6-8 support of HTML5 elements. All other JS at the end of file. -->
<!--[if lt IE 9]>
<script src="__CDN__/assets/js/html5shiv.js"></script>
... ...
... ... @@ -149,6 +149,16 @@
.item {
padding: 30px 0;
}
#statistics .panel {
min-height: 150px;
}
#statistics .panel h5 {
font-size: 13px;
}
</style>
<div class="panel panel-default panel-intro">
<div class="panel-heading">
... ... @@ -275,15 +285,15 @@
</div>
</div>
<div class="row" style="margin-top:15px;">
<div class="row" style="margin-top:15px;" id="statistics">
<div class="col-lg-12">
</div>
<div class="col-xs-6 col-md-3">
<div class="panel bg-blue">
<div class="panel bg-blue-gradient no-border">
<div class="panel-body">
<div class="panel-title">
<span class="label label-success pull-right">{:__('Real time')}</span>
<span class="label label-primary pull-right">{:__('Real time')}</span>
<h5>{:__('Category count')}</h5>
</div>
<div class="panel-content">
... ... @@ -295,10 +305,10 @@
</div>
</div>
<div class="col-xs-6 col-md-3">
<div class="panel bg-aqua-gradient">
<div class="panel bg-aqua-gradient no-border">
<div class="panel-body">
<div class="ibox-title">
<span class="label label-info pull-right">{:__('Real time')}</span>
<span class="label label-primary pull-right">{:__('Real time')}</span>
<h5>{:__('Attachment count')}</h5>
</div>
<div class="ibox-content">
... ... @@ -311,7 +321,7 @@
</div>
<div class="col-xs-6 col-md-3">
<div class="panel bg-purple-gradient">
<div class="panel bg-purple-gradient no-border">
<div class="panel-body">
<div class="ibox-title">
<span class="label label-primary pull-right">{:__('Real time')}</span>
... ... @@ -338,7 +348,7 @@
</div>
</div>
<div class="col-xs-6 col-md-3">
<div class="panel bg-green-gradient">
<div class="panel bg-green-gradient no-border">
<div class="panel-body">
<div class="ibox-title">
<span class="label label-primary pull-right">{:__('Real time')}</span>
... ... @@ -376,10 +386,12 @@
</div>
</div>
</div>
<!--@formatter:off-->
<script>
var Orderdata = {
column: {:json_encode(array_keys($paylist))},
paydata: {:json_encode(array_values($paylist))},
createdata: {:json_encode(array_values($createlist))},
};
</script>
\ No newline at end of file
</script>
<!--@formatter:on-->
... ...
... ... @@ -11,6 +11,9 @@
<label for="c-third" class="control-label col-xs-12 col-sm-2"></label>
<div class="col-xs-12 col-sm-8">
<button type="button" id="faupload-third" class="btn btn-danger faupload" data-multiple="true" data-input-id="c-third" ><i class="fa fa-upload"></i> {:__("Upload to third")}</button>
{if $config.upload.chunking}
<button type="button" id="faupload-third-chunking" class="btn btn-danger faupload" data-chunking="true" data-maxsize="1gb" data-multiple="true" data-input-id="c-third" ><i class="fa fa-upload"></i> {:__("Upload to third by chunk")}</button>
{/if}
</div>
</div>
{/if}
... ... @@ -26,6 +29,9 @@
<label for="c-local" class="control-label col-xs-12 col-sm-2"></label>
<div class="col-xs-12 col-sm-8">
<button type="button" id="faupload-local" class="btn btn-primary faupload" data-input-id="c-local" data-url="{:url('ajax/upload')}"><i class="fa fa-upload"></i> {:__("Upload to local")}</button>
{if $config.upload.chunking}
<button type="button" id="faupload-local-chunking" class="btn btn-primary faupload" data-chunking="true" data-maxsize="1gb" data-input-id="c-local" data-url="{:url('ajax/upload')}"><i class="fa fa-upload"></i> {:__("Upload to local by chunk")}</button>
{/if}
</div>
</div>
... ...
... ... @@ -11,7 +11,7 @@
</div>
{/if}
<div class="panel-body">
<div class="panel-body no-padding">
<div id="myTabContent" class="tab-content">
<div class="tab-pane fade active in" id="one">
<div class="widget-body no-padding">
... ...
... ... @@ -59,49 +59,56 @@
<div class="col-sm-8 col-xs-12">
{switch $item.type}
{case string}
<input {$item.extend} type="text" name="row[{$item.name}]" value="{$item.value|htmlentities}" class="form-control" data-rule="{$item.rule}" data-tip="{$item.tip}"/>
<input {$item.extend_html} type="text" name="row[{$item.name}]" value="{$item.value|htmlentities}" class="form-control" data-rule="{$item.rule}" data-tip="{$item.tip}"/>
{/case}
{case text}
<textarea {$item.extend} name="row[{$item.name}]" class="form-control" data-rule="{$item.rule}" rows="5" data-tip="{$item.tip}">{$item.value|htmlentities}</textarea>
<textarea {$item.extend_html} name="row[{$item.name}]" class="form-control" data-rule="{$item.rule}" rows="5" data-tip="{$item.tip}">{$item.value|htmlentities}</textarea>
{/case}
{case editor}
<textarea {$item.extend} name="row[{$item.name}]" id="editor-{$item.name}" class="form-control editor" data-rule="{$item.rule}" rows="5" data-tip="{$item.tip}">{$item.value|htmlentities}</textarea>
<textarea {$item.extend_html} name="row[{$item.name}]" id="editor-{$item.name}" class="form-control editor" data-rule="{$item.rule}" rows="5" data-tip="{$item.tip}">{$item.value|htmlentities}</textarea>
{/case}
{case array}
<dl class="fieldlist" data-name="row[{$item.name}]">
<dl {$item.extend_html} class="fieldlist" data-name="row[{$item.name}]">
<dd>
<ins>{:__('Array key')}</ins>
<ins>{:__('Array value')}</ins>
<ins>{:isset($item["setting"]["key"])&&$item["setting"]["key"]?$item["setting"]["key"]:__('Array key')}</ins>
<ins>{:isset($item["setting"]["value"])&&$item["setting"]["value"]?$item["setting"]["value"]:__('Array value')}</ins>
</dd>
<dd><a href="javascript:;" class="btn btn-sm btn-success btn-append"><i class="fa fa-plus"></i> {:__('Append')}</a></dd>
<textarea name="row[{$item.name}]" class="form-control hide" cols="30" rows="5">{$item.value|htmlentities}</textarea>
</dl>
{/case}
{case date}
<input {$item.extend} type="text" name="row[{$item.name}]" value="{$item.value}" class="form-control datetimepicker" data-date-format="YYYY-MM-DD" data-tip="{$item.tip}" data-rule="{$item.rule}"/>
<input {$item.extend_html} type="text" name="row[{$item.name}]" value="{$item.value|htmlentities}" class="form-control datetimepicker" data-date-format="YYYY-MM-DD" data-tip="{$item.tip}" data-rule="{$item.rule}"/>
{/case}
{case time}
<input {$item.extend} type="text" name="row[{$item.name}]" value="{$item.value}" class="form-control datetimepicker" data-date-format="HH:mm:ss" data-tip="{$item.tip}" data-rule="{$item.rule}"/>
<input {$item.extend_html} type="text" name="row[{$item.name}]" value="{$item.value|htmlentities}" class="form-control datetimepicker" data-date-format="HH:mm:ss" data-tip="{$item.tip}" data-rule="{$item.rule}"/>
{/case}
{case datetime}
<input {$item.extend} type="text" name="row[{$item.name}]" value="{$item.value}" class="form-control datetimepicker" data-date-format="YYYY-MM-DD HH:mm:ss" data-tip="{$item.tip}" data-rule="{$item.rule}"/>
<input {$item.extend_html} type="text" name="row[{$item.name}]" value="{$item.value|htmlentities}" class="form-control datetimepicker" data-date-format="YYYY-MM-DD HH:mm:ss" data-tip="{$item.tip}" data-rule="{$item.rule}"/>
{/case}
{case datetimerange}
<input {$item.extend_html} type="text" name="row[{$item.name}]" value="{$item.value|htmlentities}" class="form-control datetimerange" data-tip="{$item.tip}" data-rule="{$item.rule}"/>
{/case}
{case number}
<input {$item.extend} type="number" name="row[{$item.name}]" value="{$item.value}" class="form-control" data-tip="{$item.tip}" data-rule="{$item.rule}"/>
<input {$item.extend_html} type="number" name="row[{$item.name}]" value="{$item.value|htmlentities}" class="form-control" data-tip="{$item.tip}" data-rule="{$item.rule}"/>
{/case}
{case checkbox}
<div class="checkbox">
{foreach name="item.content" item="vo"}
<label for="row[{$item.name}][]-{$key}"><input id="row[{$item.name}][]-{$key}" name="row[{$item.name}][]" type="checkbox" value="{$key}" data-tip="{$item.tip}" {in name="key" value="$item.value" }checked{/in} /> {$vo}</label>
{/foreach}
</div>
{/case}
{case radio}
<div class="radio">
{foreach name="item.content" item="vo"}
<label for="row[{$item.name}]-{$key}"><input id="row[{$item.name}]-{$key}" name="row[{$item.name}]" type="radio" value="{$key}" data-tip="{$item.tip}" {in name="key" value="$item.value" }checked{/in} /> {$vo}</label>
{/foreach}
</div>
{/case}
{case value="select" break="0"}{/case}
{case value="selects"}
<select {$item.extend} name="row[{$item.name}]{$item.type=='selects'?'[]':''}" class="form-control selectpicker" data-tip="{$item.tip}" {$item.type=='selects'?'multiple':''}>
<select {$item.extend_html} name="row[{$item.name}]{$item.type=='selects'?'[]':''}" class="form-control selectpicker" data-tip="{$item.tip}" {$item.type=='selects'?'multiple':''}>
{foreach name="item.content" item="vo"}
<option value="{$key}" {in name="key" value="$item.value" }selected{/in}>{$vo}</option>
{/foreach}
... ... @@ -136,6 +143,15 @@
<label for="row[{$item.name}]-yes"><input id="row[{$item.name}]-yes" name="row[{$item.name}]" type="radio" value="1" {$item.value?'checked':''} data-tip="{$item.tip}" /> {:__('Yes')}</label>
<label for="row[{$item.name}]-no"><input id="row[{$item.name}]-no" name="row[{$item.name}]" type="radio" value="0" {$item.value?'':'checked'} data-tip="{$item.tip}" /> {:__('No')}</label>
{/case}
{case city}
<div style="position:relative">
<input {$item.extend_html} type="text" name="row[{$item.name}]" id="c-{$item.name}" value="{$item.value|htmlentities}" class="form-control" data-toggle="city-picker" data-tip="{$item.tip}" data-rule="{$item.rule}" />
</div>
{/case}
{case value="selectpage" break="0"}{/case}
{case value="selectpages"}
<input {$item.extend_html} type="text" name="row[{$item.name}]" id="c-{$item.name}" value="{$item.value|htmlentities}" class="form-control selectpage" data-source="{:url('general/config/selectpage')}?id={$item.id}" data-primary-key="{$item.setting.primarykey}" data-field="{$item.setting.field}" data-multiple="{$item.type=='selectpage'?'false':'true'}" data-tip="{$item.tip}" data-rule="{$item.rule}" />
{/case}
{case custom}
{$item.extend_html}
{/case}
... ... @@ -170,21 +186,21 @@
<form id="add-form" class="form-horizontal" role="form" data-toggle="validator" method="POST" action="{:url('general.config/add')}">
{:token()}
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Type')}:</label>
<label class="control-label col-xs-12 col-sm-2">{:__('Group')}:</label>
<div class="col-xs-12 col-sm-4">
<select name="row[type]" class="form-control selectpicker">
{foreach name="typeList" item="vo"}
<option value="{$key}" {in name="key" value="string" }selected{/in}>{$vo}</option>
<select name="row[group]" class="form-control selectpicker">
{foreach name="groupList" item="vo"}
<option value="{$key}" {in name="key" value="basic" }selected{/in}>{$vo}</option>
{/foreach}
</select>
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Group')}:</label>
<label class="control-label col-xs-12 col-sm-2">{:__('Type')}:</label>
<div class="col-xs-12 col-sm-4">
<select name="row[group]" class="form-control selectpicker">
{foreach name="groupList" item="vo"}
<option value="{$key}" {in name="key" value="basic" }selected{/in}>{$vo}</option>
<select name="row[type]" id="c-type" class="form-control selectpicker">
{foreach name="typeList" item="vo"}
<option value="{$key}" {in name="key" value="string" }selected{/in}>{$vo}</option>
{/foreach}
</select>
</div>
... ... @@ -201,6 +217,52 @@
<input type="text" class="form-control" id="title" name="row[title]" value="" data-rule="required"/>
</div>
</div>
<div class="form-group hidden tf tf-selectpage tf-selectpages">
<label for="c-selectpage-table" class="control-label col-xs-12 col-sm-2">{:__('Selectpage table')}:</label>
<div class="col-xs-12 col-sm-4">
<select id="c-selectpage-table" name="row[setting][table]" class="form-control selectpicker" data-live-search="true">
<option value="">{:__('Please select table')}</option>
</select>
</div>
</div>
<div class="form-group hidden tf tf-selectpage tf-selectpages">
<label for="c-selectpage-primarykey" class="control-label col-xs-12 col-sm-2">{:__('Selectpage primarykey')}:</label>
<div class="col-xs-12 col-sm-4">
<select name="row[setting][primarykey]" class="form-control selectpicker" id="c-selectpage-primarykey"></select>
</div>
</div>
<div class="form-group hidden tf tf-selectpage tf-selectpages">
<label for="c-selectpage-field" class="control-label col-xs-12 col-sm-2">{:__('Selectpage field')}:</label>
<div class="col-xs-12 col-sm-4">
<select name="row[setting][field]" class="form-control selectpicker" id="c-selectpage-field"></select>
</div>
</div>
<div class="form-group hidden tf tf-selectpage tf-selectpages">
<label class="control-label col-xs-12 col-sm-2">{:__('Selectpage conditions')}:</label>
<div class="col-xs-12 col-sm-8">
<dl class="fieldlist" data-name="row[setting][conditions]">
<dd>
<ins>{:__('Field title')}</ins>
<ins>{:__('Field value')}</ins>
</dd>
<dd><a href="javascript:;" class="append btn btn-sm btn-success"><i class="fa fa-plus"></i> {:__('Append')}</a></dd>
<textarea name="row[setting][conditions]" class="form-control hide" cols="30" rows="5"></textarea>
</dl>
</div>
</div>
<div class="form-group hidden tf tf-array">
<label for="c-array-key" class="control-label col-xs-12 col-sm-2">{:__('Array key')}:</label>
<div class="col-xs-12 col-sm-4">
<input type="text" name="row[setting][key]" class="form-control" id="c-array-key">
</div>
</div>
<div class="form-group hidden tf tf-array">
<label for="c-array-value" class="control-label col-xs-12 col-sm-2">{:__('Array value')}:</label>
<div class="col-xs-12 col-sm-4">
<input type="text" name="row[setting][value]" class="form-control" id="c-array-value">
</div>
</div>
<div class="form-group">
<label for="value" class="control-label col-xs-12 col-sm-2">{:__('Value')}:</label>
<div class="col-xs-12 col-sm-4">
... ...
... ... @@ -4,13 +4,13 @@
<!-- 加载样式及META信息 -->
{include file="common/meta" /}
</head>
<body class="hold-transition skin-green sidebar-mini fixed {if $Think.config.fastadmin.multiplenav}multiplenav{/if}" id="tabs">
<body class="hold-transition skin-green {$Think.config.fastadmin.adminskin} sidebar-mini fixed {:$Think.config.fastadmin.multipletab?'multipletab':''} {:$Think.config.fastadmin.multiplenav?'multiplenav':''}" id="tabs">
<div class="wrapper">
<!-- 头部区域 -->
<header id="header" class="main-header">
{if preg_match('/\/admin\/|admin\.php|admin_d75KABNWt\.php/i', url())}
{if preg_match('/\/admin\/|\/admin\.php|\/admin_d75KABNWt\.php/i', url())}
<div class="alert alert-danger-light text-center" style="margin-bottom:0;border:none;">
{:__('Security tips')}
</div>
... ...
<!DOCTYPE html>
<html lang="{$config.language}">
<head>
{include file="common/meta" /}
<style type="text/css">
body {
color:#999;
background:url('{$background}');
background-size:cover;
}
a {
color:#fff;
}
.login-panel{margin-top:150px;}
.login-screen {
max-width:400px;
padding:0;
margin:100px auto 0 auto;
<head>
{include file="common/meta" /}
}
.login-screen .well {
border-radius: 3px;
-webkit-box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
background: rgba(255,255,255, 0.2);
}
.login-screen .copyright {
text-align: center;
}
@media(max-width:767px) {
.login-screen {
padding:0 20px;
}
}
.profile-img-card {
width: 100px;
height: 100px;
margin: 10px auto;
display: block;
-moz-border-radius: 50%;
-webkit-border-radius: 50%;
border-radius: 50%;
}
.profile-name-card {
text-align: center;
}
<style type="text/css">
body {
color: #999;
background: url('{$background}');
background-size: cover;
}
#login-form {
margin-top:20px;
}
#login-form .input-group {
margin-bottom:15px;
a {
color: #fff;
}
.login-panel {
margin-top: 150px;
}
.login-screen {
max-width: 400px;
padding: 0;
margin: 100px auto 0 auto;
}
.login-screen .well {
border-radius: 3px;
-webkit-box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
box-shadow: 0 0 15px rgba(0, 0, 0, 0.1);
background: rgba(255, 255, 255, 0.2);
border: 1px solid rgba(227, 227, 227, 0.4);
}
.login-screen .input-group .input-group-addon, .login-screen input.form-control {
/*border-color: transparent;*/
}
.login-screen .copyright {
text-align: center;
}
@media (max-width: 767px) {
.login-screen {
padding: 0 20px;
}
}
.profile-img-card {
width: 100px;
height: 100px;
margin: 10px auto;
display: block;
-moz-border-radius: 50%;
-webkit-border-radius: 50%;
border-radius: 50%;
}
.profile-name-card {
text-align: center;
}
#login-form {
margin-top: 20px;
}
</style>
</head>
<body>
<div class="container">
<div class="login-wrapper">
<div class="login-screen">
<div class="well">
<div class="login-form">
<img id="profile-img" class="profile-img-card" src="__CDN__/assets/img/avatar.png" />
<p id="profile-name" class="profile-name-card"></p>
<form action="" method="post" id="login-form">
<div id="errtips" class="hide"></div>
{:token()}
<div class="input-group">
<div class="input-group-addon"><span class="glyphicon glyphicon-user" aria-hidden="true"></span></div>
<input type="text" class="form-control" id="pd-form-username" placeholder="{:__('Username')}" name="username" autocomplete="off" value="" data-rule="{:__('Username')}:required;username" />
</div>
<div class="input-group">
<div class="input-group-addon"><span class="glyphicon glyphicon-lock" aria-hidden="true"></span></div>
<input type="password" class="form-control" id="pd-form-password" placeholder="{:__('Password')}" name="password" autocomplete="off" value="" data-rule="{:__('Password')}:required;password" />
</div>
{if $Think.config.fastadmin.login_captcha}
<div class="input-group">
<div class="input-group-addon"><span class="glyphicon glyphicon-option-horizontal" aria-hidden="true"></span></div>
<input type="text" name="captcha" class="form-control" placeholder="{:__('Captcha')}" data-rule="{:__('Captcha')}:required;length(4)" />
<span class="input-group-addon" style="padding:0;border:none;cursor:pointer;">
#login-form .input-group {
margin-bottom: 15px;
}
</style>
</head>
<body>
<div class="container">
<div class="login-wrapper">
<div class="login-screen">
<div class="well">
<div class="login-form">
<img id="profile-img" class="profile-img-card" src="__CDN__/assets/img/avatar.png"/>
<p id="profile-name" class="profile-name-card"></p>
<form action="" method="post" id="login-form">
<div id="errtips" class="hide"></div>
{:token()}
<div class="input-group">
<div class="input-group-addon"><span class="glyphicon glyphicon-user" aria-hidden="true"></span></div>
<input type="text" class="form-control" id="pd-form-username" placeholder="{:__('Username')}" name="username" autocomplete="off" value="" data-rule="{:__('Username')}:required;username"/>
</div>
<div class="input-group">
<div class="input-group-addon"><span class="glyphicon glyphicon-lock" aria-hidden="true"></span></div>
<input type="password" class="form-control" id="pd-form-password" placeholder="{:__('Password')}" name="password" autocomplete="off" value="" data-rule="{:__('Password')}:required;password"/>
</div>
{if $Think.config.fastadmin.login_captcha}
<div class="input-group">
<div class="input-group-addon"><span class="glyphicon glyphicon-option-horizontal" aria-hidden="true"></span></div>
<input type="text" name="captcha" class="form-control" placeholder="{:__('Captcha')}" data-rule="{:__('Captcha')}:required;length(4)"/>
<span class="input-group-addon" style="padding:0;border:none;cursor:pointer;">
<img src="{:rtrim('__PUBLIC__', '/')}/index.php?s=/captcha" width="100" height="30" onclick="this.src = '{:rtrim('__PUBLIC__', '/')}/index.php?s=/captcha&r=' + Math.random();"/>
</span>
</div>
{/if}
<div class="form-group checkbox">
<label class="inline" for="keeplogin">
<input type="checkbox" name="keeplogin" id="keeplogin" value="1" />
{:__('Keep login')}
</label>
</div>
<div class="form-group">
<button type="submit" class="btn btn-success btn-lg btn-block">{:__('Sign in')}</button>
</div>
</form>
</div>
</div>
{/if}
<div class="form-group checkbox">
<label class="inline" for="keeplogin">
<input type="checkbox" name="keeplogin" id="keeplogin" value="1"/>
{:__('Keep login')}
</label>
</div>
<div class="form-group">
<button type="submit" class="btn btn-success btn-lg btn-block">{:__('Sign in')}</button>
</div>
</form>
</div>
</div>
</div>
{include file="common/script" /}
</body>
</div>
</div>
{include file="common/script" /}
</body>
</html>
... ...
... ... @@ -16,7 +16,7 @@
<small>{:__('Control panel')}</small>
</h1>
</section>
{if !IS_DIALOG && !$Think.config.fastadmin.multiplenav}
{if !IS_DIALOG && !$Think.config.fastadmin.multiplenav && $Think.config.fastadmin.breadcrumb}
<!-- RIBBON -->
<div id="ribbon">
<ol class="breadcrumb pull-left">
... ... @@ -42,4 +42,4 @@
</div>
{include file="common/script" /}
</body>
</html>
\ No newline at end of file
</html>
... ...
... ... @@ -50,6 +50,8 @@ class Common extends Api
public function upload()
{
Config::set('default_return_type', 'json');
//必须设定cdnurl为空,否则cdnurl函数计算错误
Config::set('upload.cdnurl', '');
$chunkid = $this->request->post("chunkid");
if ($chunkid) {
if (!Config::get('upload.chunking')) {
... ... @@ -69,7 +71,7 @@ class Common extends Api
} catch (UploadException $e) {
$this->error($e->getMessage());
}
$this->success(__('Uploaded successful'), ['url' => $attachment->url]);
$this->success(__('Uploaded successful'), ['url' => $attachment->url, 'fullurl' => cdnurl($attachment->url, true)]);
} elseif ($method == 'clean') {
//删除冗余的分片文件
try {
... ... @@ -102,7 +104,7 @@ class Common extends Api
$this->error($e->getMessage());
}
$this->success(__('Uploaded successful'), ['url' => $attachment->url]);
$this->success(__('Uploaded successful'), ['url' => $attachment->url, 'fullurl' => cdnurl($attachment->url, true)]);
}
}
... ...
... ... @@ -97,7 +97,7 @@ if (!function_exists('is_really_writable')) {
/**
* 判断文件或文件夹是否可写
* @param string $file 文件或目录
* @param string $file 文件或目录
* @return bool
*/
function is_really_writable($file)
... ... @@ -362,3 +362,59 @@ if (!function_exists('hsv2rgb')) {
];
}
}
if (!function_exists('check_nav_active')) {
/**
* 检测会员中心导航是否高亮
*/
function check_nav_active($url, $classname = 'active')
{
$auth = \app\common\library\Auth::instance();
$requestUrl = $auth->getRequestUri();
$url = ltrim($url, '/');
return $requestUrl === str_replace(".", "/", $url) ? $classname : '';
}
}
if (!function_exists('check_cors_request')) {
/**
* 跨域检测
*/
function check_cors_request()
{
if (isset($_SERVER['HTTP_ORIGIN']) && $_SERVER['HTTP_ORIGIN']) {
$info = parse_url($_SERVER['HTTP_ORIGIN']);
$domainArr = explode(',', config('fastadmin.cors_request_domain'));
$domainArr[] = request()->host();
if (in_array("*", $domainArr) || in_array($_SERVER['HTTP_ORIGIN'], $domainArr) || (isset($info['host']) && in_array($info['host'], $domainArr))) {
header("Access-Control-Allow-Origin: " . $_SERVER['HTTP_ORIGIN']);
} else {
header('HTTP/1.1 403 Forbidden');
exit;
}
header('Access-Control-Allow-Credentials: true');
header('Access-Control-Max-Age: 86400');
if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD'])) {
header("Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS");
}
if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS'])) {
header("Access-Control-Allow-Headers: {$_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']}");
}
exit;
}
}
}
}
if (!function_exists('xss_clean')) {
/**
* 清理XSS
*/
function xss_clean($content, $is_image = false)
{
return \app\common\library\Security::instance()->xss_clean($content, $is_image);
}
}
... ...
... ... @@ -12,6 +12,7 @@ use think\Loader;
use think\Request;
use think\Response;
use think\Route;
use think\Validate;
/**
* API控制器基类
... ... @@ -91,24 +92,8 @@ class Api
*/
protected function _initialize()
{
if (Config::get('url_domain_deploy')) {
$domain = Route::rules('domain');
if (isset($domain['api'])) {
if (isset($_SERVER['HTTP_ORIGIN'])) {
header("Access-Control-Allow-Origin: " . $this->request->server('HTTP_ORIGIN'));
header('Access-Control-Allow-Credentials: true');
header('Access-Control-Max-Age: 86400');
}
if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD'])) {
header("Access-Control-Allow-Methods: GET, POST, OPTIONS");
}
if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS'])) {
header("Access-Control-Allow-Headers: {$_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']}");
}
}
}
}
//跨域请求检测
check_cors_request();
//移除HTML标签
$this->request->filter('trim,strip_tags,htmlspecialchars');
... ... @@ -164,7 +149,7 @@ class Api
*/
protected function loadlang($name)
{
$name = Loader::parseName($name);
$name = Loader::parseName($name);
Lang::load(APP_PATH . $this->request->module() . '/lang/' . $this->request->langset() . '/' . str_replace('.', '/', $name) . '.php');
}
... ... @@ -230,8 +215,8 @@ class Api
/**
* 前置操作
* @access protected
* @param string $method 前置操作方法名
* @param array $options 调用参数 ['only'=>[...]] 或者 ['except'=>[...]]
* @param string $method 前置操作方法名
* @param array $options 调用参数 ['only'=>[...]] 或者 ['except'=>[...]]
* @return void
*/
protected function beforeAction($method, $options = [])
... ... @@ -273,11 +258,11 @@ class Api
/**
* 验证数据
* @access protected
* @param array $data 数据
* @param string|array $validate 验证器名或者验证规则数组
* @param array $message 提示信息
* @param bool $batch 是否批量验证
* @param mixed $callback 回调方法(闭包)
* @param array $data 数据
* @param string|array $validate 验证器名或者验证规则数组
* @param array $message 提示信息
* @param bool $batch 是否批量验证
* @param mixed $callback 回调方法(闭包)
* @return array|string|true
* @throws ValidateException
*/
... ... @@ -320,4 +305,20 @@ class Api
return true;
}
/**
* 刷新Token
*/
protected function token()
{
$token = $this->request->param('__token__');
//验证Token
if (!Validate::make()->check(['__token__' => $token], ['__token__' => 'require|token'])) {
$this->error(__('Token verification error'), ['__token__' => $this->request->token()]);
}
//刷新Token
$this->request->token();
}
}
... ...
... ... @@ -8,6 +8,7 @@ use think\Controller;
use think\Hook;
use think\Lang;
use think\Loader;
use think\Model;
use think\Session;
use fast\Tree;
use think\Validate;
... ... @@ -149,7 +150,7 @@ class Backend extends Controller
}
// 判断是否需要验证权限
if (!$this->auth->match($this->noNeedRight)) {
// 判断控制器和方法判断是否有对应权限
// 判断控制器和方法是否有对应权限
if (!$this->auth->check($path)) {
Hook::listen('admin_nopermission', $this);
$this->error(__('You have no permission'), '');
... ... @@ -173,8 +174,11 @@ class Backend extends Controller
}
// 设置面包屑导航数据
$breadcrumb = $this->auth->getBreadCrumb($path);
array_pop($breadcrumb);
$breadcrumb = [];
if (!IS_DIALOG && !config('fastadmin.multiplenav') && config('fastadmin.breadcrumb')) {
$breadcrumb = $this->auth->getBreadCrumb($path);
array_pop($breadcrumb);
}
$this->view->breadcrumb = $breadcrumb;
// 如果有使用模板布局
... ... @@ -266,7 +270,6 @@ class Backend extends Controller
$tableName = '';
if ($relationSearch) {
if (!empty($this->model)) {
$name = \think\Loader::parseName(basename(str_replace('\\', '/', get_class($this->model))));
$name = $this->model->getTable();
$tableName = $name . '.';
}
... ... @@ -290,6 +293,9 @@ class Backend extends Controller
$where[] = [implode("|", $searcharr), "LIKE", "%{$search}%"];
}
foreach ($filter as $k => $v) {
if (!preg_match('/^[a-zA-Z0-9_\-\.]+$/', $k)) {
continue;
}
$sym = isset($op[$k]) ? $op[$k] : '=';
if (stripos($k, ".") === false) {
$k = $tableName . $k;
... ... @@ -327,7 +333,12 @@ class Backend extends Controller
case 'FINDIN':
case 'FINDINSET':
case 'FIND_IN_SET':
$where[] = "FIND_IN_SET('{$v}', " . ($relationSearch ? $k : '`' . str_replace('.', '`.`', $k) . '`') . ")";
$v = is_array($v) ? $v : explode(',', str_replace(' ', ',', $v));
foreach ($v as $index => $item) {
$item = str_replace([' ', ',', "'"], '', $item);
$item = addslashes(htmlentities(strip_tags($item)));
$where[] = "FIND_IN_SET('{$item}', `" . ($relationSearch ? str_replace('.', '`.`', $k) : $k) . "`)";
}
break;
case 'IN':
case 'IN(...)':
... ... @@ -368,10 +379,6 @@ class Backend extends Controller
}
$where[] = [$k, str_replace('RANGE', 'BETWEEN', $sym) . ' time', $arr];
break;
case 'LIKE':
case 'LIKE %...%':
$where[] = [$k, 'LIKE', "%{$v}%"];
break;
case 'NULL':
case 'IS NULL':
case 'NOT NULL':
... ... @@ -424,7 +431,7 @@ class Backend extends Controller
protected function selectpage()
{
//设置过滤方法
$this->request->filter(['strip_tags', 'htmlspecialchars']);
$this->request->filter(['trim', 'strip_tags', 'htmlspecialchars']);
//搜索关键词,客户端输入以空格分开,这里接收为数组
$word = (array)$this->request->request("q_word/a");
... ... @@ -467,11 +474,18 @@ class Backend extends Controller
$where = function ($query) use ($word, $andor, $field, $searchfield, $custom) {
$logic = $andor == 'AND' ? '&' : '|';
$searchfield = is_array($searchfield) ? implode($logic, $searchfield) : $searchfield;
$word = array_filter($word);
if ($word) {
foreach ($word as $k => $v) {
$query->where(str_replace(',', $logic, $searchfield), "like", "%{$v}%");
}
$searchfield = str_replace(',', $logic, $searchfield);
$word = array_filter(array_unique($word));
if (count($word) == 1) {
$query->where($searchfield, "like", "%" . reset($word) . "%");
} else {
$query->where(function ($query) use ($word, $searchfield) {
foreach ($word as $index => $item) {
$query->whereOr(function ($query) use ($item, $searchfield) {
$query->where($searchfield, "like", "%{$item}%");
});
}
});
}
if ($custom && is_array($custom)) {
foreach ($custom as $k => $v) {
... ... @@ -494,6 +508,9 @@ class Backend extends Controller
if (is_array($adminIds)) {
$this->model->where($this->dataLimitField, 'in', $adminIds);
}
$fields = is_array($this->selectpageFields) ? $this->selectpageFields : ($this->selectpageFields && $this->selectpageFields != '*' ? explode(',', $this->selectpageFields) : []);
//如果有primaryvalue,说明当前是初始化传值,按照选择顺序排序
if ($primaryvalue !== null) {
$primaryvalue = array_unique(is_array($primaryvalue) ? $primaryvalue : explode(',', $primaryvalue));
... ... @@ -514,11 +531,16 @@ class Backend extends Controller
foreach ($datalist as $index => $item) {
unset($item['password'], $item['salt']);
$list[] = [
$primarykey => isset($item[$primarykey]) ? $item[$primarykey] : '',
$field => isset($item[$field]) ? $item[$field] : '',
'pid' => isset($item['pid']) ? $item['pid'] : 0
];
if ($this->selectpageFields == '*') {
$result = [
$primarykey => isset($item[$primarykey]) ? $item[$primarykey] : '',
$field => isset($item[$field]) ? $item[$field] : '',
];
} else {
$result = array_intersect_key(($item instanceof Model ? $item->toArray() : (array)$item), array_flip($fields));
}
$result['pid'] = isset($item['pid']) ? $item['pid'] : (isset($item['parent_id']) ? $item['parent_id'] : 0);
$list[] = $result;
}
if ($istree && !$primaryvalue) {
$tree = Tree::instance();
... ... @@ -541,7 +563,7 @@ class Backend extends Controller
*/
protected function token()
{
$token = $this->request->post('__token__');
$token = $this->request->param('__token__');
//验证Token
if (!Validate::make()->check(['__token__' => $token], ['__token__' => 'require|token'])) {
... ...
... ... @@ -142,7 +142,7 @@ class Frontend extends Controller
*/
protected function token()
{
$token = $this->request->post('__token__');
$token = $this->request->param('__token__');
//验证Token
if (!Validate::make()->check(['__token__' => $token], ['__token__' => 'require|token'])) {
... ...
... ... @@ -179,6 +179,9 @@ class Auth
$this->_token = Random::uuid();
Token::set($this->_token, $user->id, $this->keeptime);
//设置登录状态
$this->_logined = true;
//注册成功的事件
Hook::listen("user_register_successed", $this->_user, $data);
Db::commit();
... ...
<?php
namespace app\common\library;
use Exception;
/**
* 安全过滤类
*
* @category Security
* @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/)
* @copyright Copyright (c) 2014 - 2019, British Columbia Institute of Technology (https://bcit.ca/)
* @license https://opensource.org/licenses/MIT MIT License
* @link https://codeigniter.com
* @author EllisLab Dev Team
*/
class Security
{
protected static $instance = null;
/**
* List of sanitize filename strings
*
* @var array
*/
public $filename_bad_chars = array(
'../',
'<!--',
'-->',
'<',
'>',
"'",
'"',
'&',
'$',
'#',
'{',
'}',
'[',
']',
'=',
';',
'?',
'%20',
'%22',
'%3c', // <
'%253c', // <
'%3e', // >
'%0e', // >
'%28', // (
'%29', // )
'%2528', // (
'%26', // &
'%24', // $
'%3f', // ?
'%3b', // ;
'%3d' // =
);
/**
* Character set
*
* Will be overridden by the constructor.
*
* @var string
*/
public $charset = 'UTF-8';
/**
* XSS Hash
*
* Random Hash for protecting URLs.
*
* @var string
*/
protected $_xss_hash;
/**
* List of never allowed strings
*
* @var array
*/
protected $_never_allowed_str = array(
'document.cookie' => '[removed]',
'(document).cookie' => '[removed]',
'document.write' => '[removed]',
'(document).write' => '[removed]',
'.parentNode' => '[removed]',
'.innerHTML' => '[removed]',
'-moz-binding' => '[removed]',
'<!--' => '&lt;!--',
'-->' => '--&gt;',
'<![CDATA[' => '&lt;![CDATA[',
'<comment>' => '&lt;comment&gt;',
'<%' => '&lt;&#37;'
);
/**
* List of never allowed regex replacements
*
* @var array
*/
protected $_never_allowed_regex = array(
'javascript\s*:',
'(\(?document\)?|\(?window\)?(\.document)?)\.(location|on\w*)',
'expression\s*(\(|&\#40;)', // CSS and IE
'vbscript\s*:', // IE, surprise!
'wscript\s*:', // IE
'jscript\s*:', // IE
'vbs\s*:', // IE
'Redirect\s+30\d',
"([\"'])?data\s*:[^\\1]*?base64[^\\1]*?,[^\\1]*?\\1?"
);
protected $options = [
'placeholder' => '[removed]'
];
/**
* Class constructor
*
* @return void
*/
public function __construct($options = [])
{
$this->options = array_merge($this->options, $options);
foreach ($this->_never_allowed_str as $index => &$item) {
$item = str_replace('[removed]', $this->options['placeholder'], $item);
}
}
/**
*
* @param array $options 参数
* @return Security
*/
public static function instance($options = [])
{
if (is_null(self::$instance)) {
self::$instance = new static($options);
}
return self::$instance;
}
/**
* XSS Clean
*
* Sanitizes data so that Cross Site Scripting Hacks can be
* prevented. This method does a fair amount of work but
* it is extremely thorough, designed to prevent even the
* most obscure XSS attempts. Nothing is ever 100% foolproof,
* of course, but I haven't been able to get anything passed
* the filter.
*
* Note: Should only be used to deal with data upon submission.
* It's not something that should be used for general
* runtime processing.
*
* @link http://channel.bitflux.ch/wiki/XSS_Prevention
* Based in part on some code and ideas from Bitflux.
*
* @link http://ha.ckers.org/xss.html
* To help develop this script I used this great list of
* vulnerabilities along with a few other hacks I've
* harvested from examining vulnerabilities in other programs.
*
* @param string|string[] $str Input data
* @param bool $is_image Whether the input is an image
* @return string
*/
public function xss_clean($str, $is_image = false)
{
// Is the string an array?
if (is_array($str)) {
foreach ($str as $key => &$value) {
$str[$key] = $this->xss_clean($value);
}
return $str;
}
// Remove Invisible Characters
$str = $this->remove_invisible_characters($str);
/*
* URL Decode
*
* Just in case stuff like this is submitted:
*
* <a href="http://%77%77%77%2E%67%6F%6F%67%6C%65%2E%63%6F%6D">Google</a>
*
* Note: Use rawurldecode() so it does not remove plus signs
*/
if (stripos($str, '%') !== false) {
do {
$oldstr = $str;
$str = rawurldecode($str);
$str = preg_replace_callback('#%(?:\s*[0-9a-f]){2,}#i', array($this, '_urldecodespaces'), $str);
} while ($oldstr !== $str);
unset($oldstr);
}
/*
* Convert character entities to ASCII
*
* This permits our tests below to work reliably.
* We only convert entities that are within tags since
* these are the ones that will pose security problems.
*/
$str = preg_replace_callback("/[^a-z0-9>]+[a-z0-9]+=([\'\"]).*?\\1/si", array($this, '_convert_attribute'), $str);
$str = preg_replace_callback('/<\w+.*/si', array($this, '_decode_entity'), $str);
// Remove Invisible Characters Again!
$str = $this->remove_invisible_characters($str);
/*
* Convert all tabs to spaces
*
* This prevents strings like this: ja vascript
* NOTE: we deal with spaces between characters later.
* NOTE: preg_replace was found to be amazingly slow here on
* large blocks of data, so we use str_replace.
*/
$str = str_replace("\t", ' ', $str);
// Capture converted string for later comparison
$converted_string = $str;
// Remove Strings that are never allowed
$str = $this->_do_never_allowed($str);
/*
* Makes PHP tags safe
*
* Note: XML tags are inadvertently replaced too:
*
* <?xml
*
* But it doesn't seem to pose a problem.
*/
if ($is_image === true) {
// Images have a tendency to have the PHP short opening and
// closing tags every so often so we skip those and only
// do the long opening tags.
$str = preg_replace('/<\?(php)/i', '&lt;?\\1', $str);
} else {
$str = str_replace(array('<?', '?' . '>'), array('&lt;?', '?&gt;'), $str);
}
/*
* Compact any exploded words
*
* This corrects words like: j a v a s c r i p t
* These words are compacted back to their correct state.
*/
$words = array(
'javascript',
'expression',
'vbscript',
'jscript',
'wscript',
'vbs',
'script',
'base64',
'applet',
'alert',
'document',
'write',
'cookie',
'window',
'confirm',
'prompt',
'eval'
);
foreach ($words as $word) {
$word = implode('\s*', str_split($word)) . '\s*';
// We only want to do this when it is followed by a non-word character
// That way valid stuff like "dealer to" does not become "dealerto"
$str = preg_replace_callback('#(' . substr($word, 0, -3) . ')(\W)#is', array($this, '_compact_exploded_words'), $str);
}
/*
* Remove disallowed Javascript in links or img tags
* We used to do some version comparisons and use of stripos(),
* but it is dog slow compared to these simplified non-capturing
* preg_match(), especially if the pattern exists in the string
*
* Note: It was reported that not only space characters, but all in
* the following pattern can be parsed as separators between a tag name
* and its attributes: [\d\s"\'`;,\/\=\(\x00\x0B\x09\x0C]
* ... however, $this->remove_invisible_characters() above already strips the
* hex-encoded ones, so we'll skip them below.
*/
do {
$original = $str;
if (preg_match('/<a/i', $str)) {
$str = preg_replace_callback('#<a(?:rea)?[^a-z0-9>]+([^>]*?)(?:>|$)#si', array($this, '_js_link_removal'), $str);
}
if (preg_match('/<img/i', $str)) {
$str = preg_replace_callback('#<img[^a-z0-9]+([^>]*?)(?:\s?/?>|$)#si', array($this, '_js_img_removal'), $str);
}
if (preg_match('/script|xss/i', $str)) {
$str = preg_replace('#</*(?:script|xss).*?>#si', $this->options['placeholder'], $str);
}
} while ($original !== $str);
unset($original);
/*
* Sanitize naughty HTML elements
*
* If a tag containing any of the words in the list
* below is found, the tag gets converted to entities.
*
* So this: <blink>
* Becomes: &lt;blink&gt;
*/
$pattern = '#'
. '<((?<slash>/*\s*)((?<tagName>[a-z0-9]+)(?=[^a-z0-9]|$)|.+)' // tag start and name, followed by a non-tag character
. '[^\s\042\047a-z0-9>/=]*' // a valid attribute character immediately after the tag would count as a separator
// optional attributes
. '(?<attributes>(?:[\s\042\047/=]*' // non-attribute characters, excluding > (tag close) for obvious reasons
. '[^\s\042\047>/=]+' // attribute characters
// optional attribute-value
. '(?:\s*=' // attribute-value separator
. '(?:[^\s\042\047=><`]+|\s*\042[^\042]*\042|\s*\047[^\047]*\047|\s*(?U:[^\s\042\047=><`]*))' // single, double or non-quoted value
. ')?' // end optional attribute-value group
. ')*)' // end optional attributes group
. '[^>]*)(?<closeTag>\>)?#isS';
// Note: It would be nice to optimize this for speed, BUT
// only matching the naughty elements here results in
// false positives and in turn - vulnerabilities!
do {
$old_str = $str;
$str = preg_replace_callback($pattern, array($this, '_sanitize_naughty_html'), $str);
} while ($old_str !== $str);
unset($old_str);
/*
* Sanitize naughty scripting elements
*
* Similar to above, only instead of looking for
* tags it looks for PHP and JavaScript commands
* that are disallowed. Rather than removing the
* code, it simply converts the parenthesis to entities
* rendering the code un-executable.
*
* For example: eval('some code')
* Becomes: eval&#40;'some code'&#41;
*/
$str = preg_replace(
'#(alert|prompt|confirm|cmd|passthru|eval|exec|expression|system|fopen|fsockopen|file|file_get_contents|readfile|unlink)(\s*)\((.*?)\)#si',
'\\1\\2&#40;\\3&#41;',
$str
);
// Same thing, but for "tag functions" (e.g. eval`some code`)
$str = preg_replace(
'#(alert|prompt|confirm|cmd|passthru|eval|exec|expression|system|fopen|fsockopen|file|file_get_contents|readfile|unlink)(\s*)`(.*?)`#si',
'\\1\\2&#96;\\3&#96;',
$str
);
// Final clean up
// This adds a bit of extra precaution in case
// something got through the above filters
$str = $this->_do_never_allowed($str);
/*
* Images are Handled in a Special Way
* - Essentially, we want to know that after all of the character
* conversion is done whether any unwanted, likely XSS, code was found.
* If not, we return TRUE, as the image is clean.
* However, if the string post-conversion does not matched the
* string post-removal of XSS, then it fails, as there was unwanted XSS
* code found and removed/changed during processing.
*/
if ($is_image === true) {
return ($str === $converted_string);
}
return $str;
}
// --------------------------------------------------------------------
/**
* XSS Hash
*
* Generates the XSS hash if needed and returns it.
*
* @return string XSS hash
*/
public function xss_hash()
{
if ($this->_xss_hash === null) {
$rand = $this->get_random_bytes(16);
$this->_xss_hash = ($rand === false)
? md5(uniqid(mt_rand(), true))
: bin2hex($rand);
}
return $this->_xss_hash;
}
// --------------------------------------------------------------------
/**
* Get random bytes
*
* @param int $length Output length
* @return string
*/
public function get_random_bytes($length)
{
if (empty($length) OR !ctype_digit((string)$length)) {
return false;
}
if (function_exists('random_bytes')) {
try {
// The cast is required to avoid TypeError
return random_bytes((int)$length);
} catch (Exception $e) {
// If random_bytes() can't do the job, we can't either ...
// There's no point in using fallbacks.
return false;
}
}
// Unfortunately, none of the following PRNGs is guaranteed to exist ...
if (defined('MCRYPT_DEV_URANDOM') && ($output = mcrypt_create_iv($length, MCRYPT_DEV_URANDOM)) !== false) {
return $output;
}
if (is_readable('/dev/urandom') && ($fp = fopen('/dev/urandom', 'rb')) !== false) {
// Try not to waste entropy ...
stream_set_chunk_size($fp, $length);
$output = fread($fp, $length);
fclose($fp);
if ($output !== false) {
return $output;
}
}
if (function_exists('openssl_random_pseudo_bytes')) {
return openssl_random_pseudo_bytes($length);
}
return false;
}
// --------------------------------------------------------------------
/**
* HTML Entities Decode
*
* A replacement for html_entity_decode()
*
* The reason we are not using html_entity_decode() by itself is because
* while it is not technically correct to leave out the semicolon
* at the end of an entity most browsers will still interpret the entity
* correctly. html_entity_decode() does not convert entities without
* semicolons, so we are left with our own little solution here. Bummer.
*
* @link https://secure.php.net/html-entity-decode
*
* @param string $str Input
* @param string $charset Character set
* @return string
*/
public function entity_decode($str, $charset = null)
{
if (strpos($str, '&') === false) {
return $str;
}
static $_entities;
isset($charset) OR $charset = $this->charset;
isset($_entities) OR $_entities = array_map('strtolower', get_html_translation_table(HTML_ENTITIES, ENT_COMPAT | ENT_HTML5, $charset));
do {
$str_compare = $str;
// Decode standard entities, avoiding false positives
if (preg_match_all('/&[a-z]{2,}(?![a-z;])/i', $str, $matches)) {
$replace = array();
$matches = array_unique(array_map('strtolower', $matches[0]));
foreach ($matches as &$match) {
if (($char = array_search($match . ';', $_entities, true)) !== false) {
$replace[$match] = $char;
}
}
$str = str_replace(array_keys($replace), array_values($replace), $str);
}
// Decode numeric & UTF16 two byte entities
$str = html_entity_decode(
preg_replace('/(&#(?:x0*[0-9a-f]{2,5}(?![0-9a-f;])|(?:0*\d{2,4}(?![0-9;]))))/iS', '$1;', $str),
ENT_COMPAT | ENT_HTML5,
$charset
);
} while ($str_compare !== $str);
return $str;
}
// --------------------------------------------------------------------
/**
* Sanitize Filename
*
* @param string $str Input file name
* @param bool $relative_path Whether to preserve paths
* @return string
*/
public function sanitize_filename($str, $relative_path = false)
{
$bad = $this->filename_bad_chars;
if (!$relative_path) {
$bad[] = './';
$bad[] = '/';
}
$str = $this->remove_invisible_characters($str, false);
do {
$old = $str;
$str = str_replace($bad, '', $str);
} while ($old !== $str);
return stripslashes($str);
}
// ----------------------------------------------------------------
/**
* Strip Image Tags
*
* @param string $str
* @return string
*/
public function strip_image_tags($str)
{
return preg_replace(
array(
'#<img[\s/]+.*?src\s*=\s*(["\'])([^\\1]+?)\\1.*?\>#i',
'#<img[\s/]+.*?src\s*=\s*?(([^\s"\'=<>`]+)).*?\>#i'
),
'\\2',
$str
);
}
// ----------------------------------------------------------------
/**
* URL-decode taking spaces into account
*
* @param array $matches
* @return string
*/
protected function _urldecodespaces($matches)
{
$input = $matches[0];
$nospaces = preg_replace('#\s+#', '', $input);
return ($nospaces === $input)
? $input
: rawurldecode($nospaces);
}
// ----------------------------------------------------------------
/**
* Compact Exploded Words
*
* Callback method for xss_clean() to remove whitespace from
* things like 'j a v a s c r i p t'.
*
* @param array $matches
* @return string
*/
protected function _compact_exploded_words($matches)
{
return preg_replace('/\s+/s', '', $matches[1]) . $matches[2];
}
// --------------------------------------------------------------------
/**
* Sanitize Naughty HTML
*
* Callback method for xss_clean() to remove naughty HTML elements.
*
* @param array $matches
* @return string
*/
protected function _sanitize_naughty_html($matches)
{
static $naughty_tags = array(
'alert',
'area',
'prompt',
'confirm',
'applet',
'audio',
'basefont',
'base',
'behavior',
'bgsound',
'blink',
'body',
'embed',
'expression',
'form',
'frameset',
'frame',
'head',
'html',
'ilayer',
'iframe',
'input',
'button',
'select',
'isindex',
'layer',
'link',
'meta',
'keygen',
'object',
'plaintext',
'style',
'script',
'textarea',
'title',
'math',
'video',
'svg',
'xml',
'xss'
);
static $evil_attributes = array(
'on\w+',
'style',
'xmlns',
'formaction',
'form',
'xlink:href',
'FSCommand',
'seekSegmentTime'
);
// First, escape unclosed tags
if (empty($matches['closeTag'])) {
return '&lt;' . $matches[1];
} // Is the element that we caught naughty? If so, escape it
elseif (in_array(strtolower($matches['tagName']), $naughty_tags, true)) {
return '&lt;' . $matches[1] . '&gt;';
} // For other tags, see if their attributes are "evil" and strip those
elseif (isset($matches['attributes'])) {
// We'll store the already filtered attributes here
$attributes = array();
// Attribute-catching pattern
$attributes_pattern = '#'
. '(?<name>[^\s\042\047>/=]+)' // attribute characters
// optional attribute-value
. '(?:\s*=(?<value>[^\s\042\047=><`]+|\s*\042[^\042]*\042|\s*\047[^\047]*\047|\s*(?U:[^\s\042\047=><`]*)))' // attribute-value separator
. '#i';
// Blacklist pattern for evil attribute names
$is_evil_pattern = '#^(' . implode('|', $evil_attributes) . ')$#i';
// Each iteration filters a single attribute
do {
// Strip any non-alpha characters that may precede an attribute.
// Browsers often parse these incorrectly and that has been a
// of numerous XSS issues we've had.
$matches['attributes'] = preg_replace('#^[^a-z]+#i', '', $matches['attributes']);
if (!preg_match($attributes_pattern, $matches['attributes'], $attribute, PREG_OFFSET_CAPTURE)) {
// No (valid) attribute found? Discard everything else inside the tag
break;
}
if (
// Is it indeed an "evil" attribute?
preg_match($is_evil_pattern, $attribute['name'][0])
// Or does it have an equals sign, but no value and not quoted? Strip that too!
OR (trim($attribute['value'][0]) === '')
) {
$attributes[] = 'xss=removed';
} else {
$attributes[] = $attribute[0][0];
}
$matches['attributes'] = substr($matches['attributes'], $attribute[0][1] + strlen($attribute[0][0]));
} while ($matches['attributes'] !== '');
$attributes = empty($attributes)
? ''
: ' ' . implode(' ', $attributes);
return '<' . $matches['slash'] . $matches['tagName'] . $attributes . '>';
}
return $matches[0];
}
// --------------------------------------------------------------------
/**
* JS Link Removal
*
* Callback method for xss_clean() to sanitize links.
*
* This limits the PCRE backtracks, making it more performance friendly
* and prevents PREG_BACKTRACK_LIMIT_ERROR from being triggered in
* PHP 5.2+ on link-heavy strings.
*
* @param array $match
* @return string
*/
protected function _js_link_removal($match)
{
return str_replace(
$match[1],
preg_replace(
'#href=.*?(?:(?:alert|prompt|confirm)(?:\(|&\#40;|`|&\#96;)|javascript:|livescript:|mocha:|charset=|window\.|\(?document\)?\.|\.cookie|<script|<xss|d\s*a\s*t\s*a\s*:)#si',
'',
$this->_filter_attributes($match[1])
),
$match[0]
);
}
// --------------------------------------------------------------------
/**
* JS Image Removal
*
* Callback method for xss_clean() to sanitize image tags.
*
* This limits the PCRE backtracks, making it more performance friendly
* and prevents PREG_BACKTRACK_LIMIT_ERROR from being triggered in
* PHP 5.2+ on image tag heavy strings.
*
* @param array $match
* @return string
*/
protected function _js_img_removal($match)
{
return str_replace(
$match[1],
preg_replace(
'#src=.*?(?:(?:alert|prompt|confirm|eval)(?:\(|&\#40;|`|&\#96;)|javascript:|livescript:|mocha:|charset=|window\.|\(?document\)?\.|\.cookie|<script|<xss|base64\s*,)#si',
'',
$this->_filter_attributes($match[1])
),
$match[0]
);
}
// --------------------------------------------------------------------
/**
* Attribute Conversion
*
* @param array $match
* @return string
*/
protected function _convert_attribute($match)
{
return str_replace(array('>', '<', '\\'), array('&gt;', '&lt;', '\\\\'), $match[0]);
}
// --------------------------------------------------------------------
/**
* Filter Attributes
*
* Filters tag attributes for consistency and safety.
*
* @param string $str
* @return string
*/
protected function _filter_attributes($str)
{
$out = '';
if (preg_match_all('#\s*[a-z\-]+\s*=\s*(\042|\047)([^\\1]*?)\\1#is', $str, $matches)) {
foreach ($matches[0] as $match) {
$out .= preg_replace('#/\*.*?\*/#s', '', $match);
}
}
return $out;
}
// --------------------------------------------------------------------
/**
* HTML Entity Decode Callback
*
* @param array $match
* @return string
*/
protected function _decode_entity($match)
{
// Protect GET variables in URLs
// 901119URL5918AMP18930PROTECT8198
$match = preg_replace('|\&([a-z\_0-9\-]+)\=([a-z\_0-9\-/]+)|i', $this->xss_hash() . '\\1=\\2', $match[0]);
// Decode, then un-protect URL GET vars
return str_replace(
$this->xss_hash(),
'&',
$this->entity_decode($match, $this->charset)
);
}
// --------------------------------------------------------------------
/**
* Do Never Allowed
*
* @param string
* @return string
*/
protected function _do_never_allowed($str)
{
$str = str_replace(array_keys($this->_never_allowed_str), $this->_never_allowed_str, $str);
foreach ($this->_never_allowed_regex as $regex) {
$str = preg_replace('#' . $regex . '#is', $this->options['placeholder'], $str);
}
return $str;
}
/**
* Remove Invisible Characters
*/
public function remove_invisible_characters($str, $url_encoded = true)
{
$non_displayables = array();
// every control character except newline (dec 10),
// carriage return (dec 13) and horizontal tab (dec 09)
if ($url_encoded) {
$non_displayables[] = '/%0[0-8bcef]/i'; // url encoded 00-08, 11, 12, 14, 15
$non_displayables[] = '/%1[0-9a-f]/i'; // url encoded 16-31
$non_displayables[] = '/%7f/i'; // url encoded 127
}
$non_displayables[] = '/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]+/S'; // 00-08, 11, 12, 14-31, 127
do {
$str = preg_replace($non_displayables, '', $str, -1, $count);
} while ($count);
return $str;
}
}
... ...
... ... @@ -28,6 +28,8 @@ class Upload
*/
protected static $maxCheckNums = 10;
protected $merging = false;
protected $chunkDir = null;
protected $config = [];
... ... @@ -171,7 +173,11 @@ class Upload
{
$iterator = new \GlobIterator($this->chunkDir . DS . $chunkid . '-*', FilesystemIterator::KEY_AS_FILENAME);
$array = iterator_to_array($iterator);
var_dump($array);
foreach ($array as $index => &$item) {
$sourceFile = $item->getRealPath() ?: $item->getPathname();
$item = null;
@unlink($sourceFile);
}
}
/**
... ... @@ -195,6 +201,7 @@ class Upload
}
}
if (!$completed) {
$this->clean($chunkid);
throw new UploadException(__('Chunk file info error'));
}
... ... @@ -202,6 +209,7 @@ class Upload
$uploadPath = $filePath;
if (!$destFile = @fopen($uploadPath, "wb")) {
$this->clean($chunkid);
throw new UploadException(__('Chunk file merge error'));
}
if (flock($destFile, LOCK_EX)) { // 进行排他型锁定
... ... @@ -229,12 +237,15 @@ class Upload
'error' => 0,
'size' => $file->getSize()
];
$file->setUploadInfo($info);
$file->setSaveName($filename)->setUploadInfo($info);
$file->isTest(true);
//重新设置文件
$this->setFile($file);
unset($file);
$this->merging = true;
//允许大文件
$this->config['maxsize'] = "1024G";
... ... @@ -287,14 +298,28 @@ class Upload
$uploadDir = substr($savekey, 0, strripos($savekey, '/') + 1);
$fileName = substr($savekey, strripos($savekey, '/') + 1);
$destDir = ROOT_PATH . 'public' . $uploadDir;
$destDir = ROOT_PATH . 'public' . str_replace('/', DS, $uploadDir);
$sha1 = $this->file->hash();
$file = $this->file->move($destDir, $fileName);
if (!$file) {
// 上传失败获取错误信息
throw new UploadException($this->file->getError());
//如果是合并文件
if ($this->merging) {
if (!$this->file->check()) {
throw new UploadException($this->file->getError());
}
$destFile = $destDir . $fileName;
$sourceFile = $this->file->getRealPath() ?: $this->file->getPathname();
$info = $this->file->getInfo();
$this->file = null;
rename($sourceFile, $destFile);
$file = new File($destFile);
$file->setSaveName($fileName)->setUploadInfo($info);
} else {
$file = $this->file->move($destDir, $fileName);
if (!$file) {
// 上传失败获取错误信息
throw new UploadException($this->file->getError());
}
}
$this->file = $file;
$params = array(
... ...
... ... @@ -24,12 +24,12 @@ class Attachment extends Model
public static function getMimetypeList()
{
$data = [
"image/*" => "图片",
"audio/*" => "音频",
"video/*" => "视频",
"text/*" => "文档",
"application/*" => "应用",
"zip,rar,7z,tar" => "压缩包",
"image/*" => __("Image"),
"audio/*" => __("Audio"),
"video/*" => __("Video"),
"text/*" => __("Text"),
"application/*" => __("Application"),
"zip,rar,7z,tar" => __("Zip"),
];
return $data;
}
... ...
... ... @@ -21,6 +21,9 @@ class Config extends Model
protected $append = [
'extend_html'
];
protected $type = [
'setting' => 'json',
];
/**
* 读取配置类型
... ... @@ -29,27 +32,28 @@ class Config extends Model
public static function getTypeList()
{
$typeList = [
'string' => __('String'),
'text' => __('Text'),
'editor' => __('Editor'),
'number' => __('Number'),
'date' => __('Date'),
'time' => __('Time'),
'datetime' => __('Datetime'),
'select' => __('Select'),
'selects' => __('Selects'),
'image' => __('Image'),
'images' => __('Images'),
'file' => __('File'),
'files' => __('Files'),
'switch' => __('Switch'),
'checkbox' => __('Checkbox'),
'radio' => __('Radio'),
'city' => __('City'),
'selectpage' => __('Selectpage'),
'selectpages' => __('Selectpages'),
'array' => __('Array'),
'custom' => __('Custom'),
'string' => __('String'),
'text' => __('Text'),
'editor' => __('Editor'),
'number' => __('Number'),
'date' => __('Date'),
'time' => __('Time'),
'datetime' => __('Datetime'),
'datetimerange' => __('Datetimerange'),
'select' => __('Select'),
'selects' => __('Selects'),
'image' => __('Image'),
'images' => __('Images'),
'file' => __('File'),
'files' => __('Files'),
'switch' => __('Switch'),
'checkbox' => __('Checkbox'),
'radio' => __('Radio'),
'city' => __('City'),
'selectpage' => __('Selectpage'),
'selectpages' => __('Selectpages'),
'array' => __('Array'),
'custom' => __('Custom'),
];
return $typeList;
}
... ... @@ -165,9 +169,12 @@ class Config extends Model
{
$uploadcfg = config('upload');
$uploadurl = request()->module() ? $uploadcfg['uploadurl'] : ($uploadcfg['uploadurl'] === 'ajax/upload' ? 'index/' . $uploadcfg['uploadurl'] : $uploadcfg['uploadurl']);
$uploadurl = url($uploadurl, '', false, true);
$upload = [
'cdnurl' => $uploadcfg['cdnurl'],
'uploadurl' => $uploadcfg['uploadurl'],
'uploadurl' => $uploadurl,
'bucket' => 'local',
'maxsize' => $uploadcfg['maxsize'],
'mimetype' => $uploadcfg['mimetype'],
... ... @@ -175,6 +182,7 @@ class Config extends Model
'chunksize' => $uploadcfg['chunksize'],
'multipart' => [],
'multiple' => $uploadcfg['multiple'],
'storage' => 'local'
];
return $upload;
}
... ...
<?php
$cdnurl = function_exists('config') ? config('view_replace_str.__CDN__') : '';
$publicurl = function_exists('config') ? config('view_replace_str.__PUBLIC__') : '/';
$publicurl = function_exists('config') ? (config('view_replace_str.__PUBLIC__')?:'/') : '/';
$debug = function_exists('config') ? config('app_debug') : false;
$lang = [
... ... @@ -98,4 +98,4 @@ $langSet == 'en' && $lang = array_combine(array_keys($lang), array_keys($lang));
</div>
</div>
</body>
</html>
\ No newline at end of file
</html>
... ...
... ... @@ -273,8 +273,14 @@ return [
'login_background' => "/assets/img/loginbg.jpg",
//是否启用多级菜单导航
'multiplenav' => false,
//自动检测更新
'checkupdate' => false,
//是否开启多选项卡(仅在开启多级菜单时起作用)
'multipletab' => true,
//后台皮肤,为空时表示使用skin-green
'adminskin' => '',
//后台是否启用面包屑
'breadcrumb' => false,
//允许跨域的域名,多个以,分隔
'cors_request_domain' => 'localhost,127.0.0.1',
//版本号
'version' => '1.2.0',
//API接口地址
... ...
... ... @@ -12,7 +12,7 @@ use think\Lang;
class Ajax extends Frontend
{
protected $noNeedLogin = ['lang'];
protected $noNeedLogin = ['lang', 'upload'];
protected $noNeedRight = ['*'];
protected $layout = '';
... ...
... ... @@ -6,6 +6,7 @@ use addons\wechat\model\WechatCaptcha;
use app\common\controller\Frontend;
use app\common\library\Ems;
use app\common\library\Sms;
use app\common\model\Attachment;
use think\Config;
use think\Cookie;
use think\Hook;
... ... @@ -272,4 +273,53 @@ class User extends Frontend
$this->view->assign('title', __('Change password'));
return $this->view->fetch();
}
public function attachment()
{
//设置过滤方法
$this->request->filter(['strip_tags']);
if ($this->request->isAjax()) {
$mimetypeQuery = [];
$filter = $this->request->request('filter');
$filterArr = (array)json_decode($filter, true);
if (isset($filterArr['mimetype']) && preg_match("/[]\,|\*]/", $filterArr['mimetype'])) {
$this->request->get(['filter' => json_encode(array_diff_key($filterArr, ['mimetype' => '']))]);
$mimetypeQuery = function ($query) use ($filterArr) {
$mimetypeArr = explode(',', $filterArr['mimetype']);
foreach ($mimetypeArr as $index => $item) {
if (stripos($item, "/*") !== false) {
$query->whereOr('mimetype', 'like', str_replace("/*", "/", $item) . '%');
} else {
$query->whereOr('mimetype', 'like', '%' . $item . '%');
}
}
};
}
$model = new Attachment();
$offset = $this->request->get("offset", 0);
$limit = $this->request->get("limit", 0);
$total = $model
->where($mimetypeQuery)
->where('user_id', $this->auth->id)
->order("id", "DESC")
->count();
$list = $model
->where($mimetypeQuery)
->where('user_id', $this->auth->id)
->order("id", "DESC")
->limit($offset, $limit)
->select();
$cdnurl = preg_replace("/\/(\w+)\.php$/i", '', $this->request->root());
foreach ($list as $k => &$v) {
$v['fullurl'] = ($v['storage'] == 'local' ? $cdnurl : $this->view->config['upload']['cdnurl']) . $v['url'];
}
unset($v);
$result = array("total" => $total, "rows" => $list);
return json($result);
}
$this->view->assign("mimetypeList", \app\common\model\Attachment::getMimetypeList());
return $this->view->fetch();
}
}
... ...
... ... @@ -61,4 +61,24 @@ return [
'Operation failed' => '操作失败',
'Invalid parameters' => '参数不正确',
'Change password failure' => '修改密码失败',
'All' => '全部',
'Url' => '物理路径',
'Imagewidth' => '宽度',
'Imageheight' => '高度',
'Imagetype' => '图片类型',
'Imageframes' => '图片帧数',
'Preview' => '预览',
'Filename' => '文件名',
'Filesize' => '文件大小',
'Mimetype' => 'Mime类型',
'Image' => '图片',
'Audio' => '音频',
'Video' => '视频',
'Text' => '文档',
'Application' => '应用',
'Zip' => '压缩包',
'Extparam' => '透传数据',
'Createtime' => '创建日期',
'Uploadtime' => '上传时间',
'Storage' => '存储引擎',
];
... ...
<div class="sidenav">
<div class="sidebar-toggle"><i class="fa fa-bars"></i></div>
<div class="sidenav" id="sidebar-nav">
{:hook('user_sidenav_before')}
<ul class="list-group">
<li class="list-group-heading">{:__('Member center')}</li>
<li class="list-group-item {:$config['actionname']=='index'?'active':''}"> <a href="{:url('user/index')}"><i class="fa fa-user-circle fa-fw"></i> {:__('User center')}</a> </li>
<li class="list-group-item {:$config['actionname']=='profile'?'active':''}"> <a href="{:url('user/profile')}"><i class="fa fa-user-o fa-fw"></i> {:__('Profile')}</a> </li>
<li class="list-group-item {:$config['actionname']=='changepwd'?'active':''}"> <a href="{:url('user/changepwd')}"><i class="fa fa-key fa-fw"></i> {:__('Change password')}</a> </li>
<li class="list-group-item {:$config['actionname']=='logout'?'active':''}"> <a href="{:url('user/logout')}"><i class="fa fa-sign-out fa-fw"></i> {:__('Sign out')}</a> </li>
<li class="list-group-item {:check_nav_active('user/index')}"> <a href="{:url('user/index')}"><i class="fa fa-user-circle fa-fw"></i> {:__('User center')}</a> </li>
<li class="list-group-item {:check_nav_active('user/profile')}"> <a href="{:url('user/profile')}"><i class="fa fa-user-o fa-fw"></i> {:__('Profile')}</a> </li>
<li class="list-group-item {:check_nav_active('user/changepwd')}"> <a href="{:url('user/changepwd')}"><i class="fa fa-key fa-fw"></i> {:__('Change password')}</a> </li>
<li class="list-group-item {:check_nav_active('user/logout')}"> <a href="{:url('user/logout')}"><i class="fa fa-sign-out fa-fw"></i> {:__('Sign out')}</a> </li>
</ul>
{:hook('user_sidenav_after')}
</div>
\ No newline at end of file
</div>
... ...
... ... @@ -12,13 +12,9 @@
<title>{$site.name}</title>
<link rel="shortcut icon" href="__CDN__/assets/img/favicon.ico" />
<!-- Bootstrap Core CSS -->
<link href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
<link href="__CDN__/assets/libs/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="__CDN__/assets/css/index.css" rel="stylesheet">
<!-- Plugin CSS -->
<link href="https://cdn.staticfile.org/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet">
<link href="https://cdn.staticfile.org/simple-line-icons/2.4.1/css/simple-line-icons.min.css" rel="stylesheet">
<!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!--[if lt IE 9]>
<script src="https://cdn.staticfile.org/html5shiv/3.7.3/html5shiv.min.js"></script>
... ... @@ -32,7 +28,10 @@
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar-collapse-menu">
<span class="sr-only">Toggle navigation</span><i class="fa fa-bars"></i>
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand page-scroll" href="#page-top">{$site.name}</a>
</div>
... ... @@ -48,25 +47,40 @@
<!-- /.container-fluid -->
</nav>
<header>
<main id="mainbody">
<div class="container">
<div class="row">
<div class="col-sm-12">
<div class="header-content">
<div class="header-content-inner">
<div class="col-sm-5">
<div class="index-text">
<div>
<h1>{$site.name}</h1>
<p style="color:#adb9e0;line-height:30px;">网站(Website)是指在因特网上根据一定的规则,使用HTML(标准通用标记语言)等工具制作的用于展示特定内容相关网页的集合。简单地说,网站是一种沟通工具,人们可以通过网站来发布自己想要公开的资讯,或者利用网站来提供相关的网络服务。</p>
<div>
<a href="{:url('index/user/index')}" class="btn bg-primary btn-xl btn-round-lg">会员中心</a>
</div>
</div>
</div>
</div>
<div class="col-sm-7">
<div class="index-gallery">
<div>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" id="gallery-svg" data-name="Gallery" width="100%" viewBox="0 0 1130.08 738.14"><defs><linearGradient id="a340ed46-1652-4aba-8925-cf57be9109ca-84" x1="421.41" y1="548.67" x2="423.73" y2="548.67" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="gray" stop-opacity="0.25"></stop><stop offset="0.54" stop-color="gray" stop-opacity="0.12"></stop><stop offset="1" stop-color="gray" stop-opacity="0.1"></stop></linearGradient></defs><title>pair programming</title><path d="M619.44,213.68c-71.37,12.06-142.64,6.89-211.2-.63s-136.95-17.34-208.35-14.38c-45.93,1.9-97.08,11-129.15,37.45C39.87,261.56,35.06,295.89,35,326.88c-.08,23.31,1.94,47.43,18.46,66,11.48,12.88,29.15,22.11,42.46,34,46.31,41.3,32.23,106.33,1.84,161.62-14.26,25.94-31.7,51.45-41.41,78s-11,55,6.38,76.65c17.22,21.47,50.53,33.57,85.26,39.84,70.54,12.74,149.13,4.83,225.17-5.89C541.45,753.29,708,716.17,874.19,679.14c61.49-13.71,123.25-27.48,182.49-47.24,32.9-11,66.4-24.69,87.65-46,27-27,27.68-63.93,1.66-86-43.66-37-142.48-28.79-176.25-71.09-18.58-23.29-10.49-54.92,4.3-82.86,31.71-59.92,93-119.12,85.06-178.86-5.48-41-47.29-74.93-103.33-83.77-58.74-9.26-134.18,8.3-168,49.56C753,175.39,682.46,203,619.44,213.68Z" transform="translate(-34.96 -80.93)" fill="#94acef" opacity="0.1"></path><rect x="360" y="359.24" width="283.43" height="65.63" fill="#565661"></rect><rect x="360" y="359.24" width="283.43" height="65.63" opacity="0.1"></rect><polygon points="393.91 427.03 395.9 602.24 368.64 671.06 366.53 427.03 393.91 427.03" fill="#bcbec9"></polygon><polygon points="362.99 371.84 638.94 373.5 638.94 422.38 362.99 422.38 362.99 371.84" fill="#565661"></polygon><polygon points="615.33 427.03 638.94 430.36 638.94 668.4 615.33 595.59 615.33 427.03" fill="#bcbec9"></polygon><rect x="647.91" y="361.87" width="132.99" height="282.6" fill="#efeff0"></rect><rect x="658.55" y="369.72" width="111.71" height="217.23" fill="#565661"></rect><rect x="658.55" y="369.72" width="111.71" height="217.23" opacity="0.1"></rect><rect x="658.55" y="374.17" width="111.71" height="48.21" fill="#565661"></rect><rect x="658.55" y="427.03" width="111.71" height="102.4" fill="#565661"></rect><rect x="658.55" y="535.75" width="111.71" height="102.4" fill="#565661"></rect><rect x="658.55" y="535.75" width="111.71" height="102.4" opacity="0.1"></rect><ellipse cx="663.21" cy="653.67" rx="7.2" ry="9.2" fill="#565661"></ellipse><ellipse cx="763.06" cy="654.11" rx="7.2" ry="9.2" fill="#565661"></ellipse><polygon points="359 671.06 368.64 671.06 365.99 364.32 351.35 364.32 359 671.06" fill="#efeff0"></polygon><polygon points="638.94 361.87 638.94 668.4 647.91 668.4 647.91 364.32 638.94 361.87" fill="#efeff0"></polygon><polygon points="366.46 419.38 366.46 430.36 638.94 430.36 638.94 422.38 366.46 419.38" fill="#efeff0"></polygon><polygon points="384.93 341.26 730.37 341.26 780.57 357.88 780.57 367.52 349.69 364.2 349.69 354.39 384.93 341.26" fill="#fff"></polygon><polygon points="349.69 354.39 780.57 357.88 780.57 367.52 349.69 364.2 349.69 354.39" fill="#bcbec9"></polygon><path d="M423.68,549.64l-2-.3c0-.09,0-.17,0-.25-.06-.47-.13-.93-.2-1.4.82.65,1.6,1.3,2.32,1.95Z" transform="translate(-34.96 -80.93)" fill="url(#a340ed46-1652-4aba-8925-cf57be9109ca-84)"></path><path d="M380.22,704.05c1.3-.3,2.62-.55,3.94-.73a47.42,47.42,0,0,1,26.62,3.92c-.84,6.18-1.67,12.57.11,18.54,1.24,4.2,3.73,8,4.26,12.38a7.3,7.3,0,0,1,5.75,5.08,11.05,11.05,0,0,1,.57,3.56,19,19,0,0,1-.56,4.44,4.48,4.48,0,0,1-4.8,4c-7.74.88-15.33-2.17-22.53-5.16l-14-5.82c-1.64-.68-3.29-1.37-4.86-2.21a26.63,26.63,0,0,1-7.79-6.37A3.55,3.55,0,0,1,366,734c-.26-1.76,1.8-2.81,3.11-4a6.23,6.23,0,0,0,1-1.22c1.55-2.34,1.7-5.57,2.63-8.33,2.2-6.55,9-10.77,11.4-17.16.13-.35.25-.7.35-1.06" transform="translate(-34.96 -80.93)" fill="#a26565"></path><path d="M421.47,746.8a19,19,0,0,1-.56,4.44,4.48,4.48,0,0,1-4.8,4c-7.74.88-15.33-2.17-22.53-5.16l-14-5.82c-1.64-.68-3.29-1.37-4.86-2.21a26.63,26.63,0,0,1-7.79-6.37A3.55,3.55,0,0,1,366,734c-.26-1.76,1.8-2.81,3.11-4a6.23,6.23,0,0,0,1-1.22c3.86.83,8.65,3.26,11.6,4.2a35.22,35.22,0,0,1,8.44,3.53c3.68,2.36,6.33,6,9.45,9s7.15,5.73,11.5,5.36a19,19,0,0,0,6.54-2.26Z" transform="translate(-34.96 -80.93)" opacity="0.1"></path><path d="M405.08,604.69a4.63,4.63,0,0,1-1.7,5c-1.31.81-3,.7-4.3,1.58-1.61,1.13-1.84,3.37-2.12,5.31-1,6.67-4.31,12.72-7.14,18.85s-5.22,12.82-4.18,19.48c.71,4.52,2.93,9.34.85,13.41-.51,1-1.27,1.89-1.85,2.86-2.85,4.76-1.23,10.79-1.34,16.33a3.23,3.23,0,0,1-.39,1.77,4.89,4.89,0,0,1-1.58,1.22,8.38,8.38,0,0,0-3.41,6.43,24.57,24.57,0,0,0,.9,7.46,4.44,4.44,0,0,0,1.23,2.6,4.6,4.6,0,0,0,2.69.76A59.84,59.84,0,0,1,401,712.19c3.79,1.58,7.47,3.56,11.5,4.32a3,3,0,0,0,2.36-.25,3.25,3.25,0,0,0,1-1.73c1.55-5.1,3.12-10.36,2.59-15.66-.23-2.28-.84-4.51-1-6.79-.7-9,5.39-17.12,7.32-26,.87-4,.87-8.14,1.49-12.18,1.68-11.07,7.78-21,10.13-31.95a34.73,34.73,0,0,1,1.52-6c1.75-4.24,5.8-7.68,5.89-12.27a4.78,4.78,0,0,0-.76-2.86,6.48,6.48,0,0,0-3.57-2,121.87,121.87,0,0,0-16.55-3.34,31.35,31.35,0,0,0-7.78-.54,22.9,22.9,0,0,0-9.52,3.36C401.76,600.68,404.24,601.25,405.08,604.69Z" transform="translate(-34.96 -80.93)" fill="#454b69"></path><path d="M405.08,604.69a4.63,4.63,0,0,1-1.7,5c-1.31.81-3,.7-4.3,1.58-1.61,1.13-1.84,3.37-2.12,5.31-1,6.67-4.31,12.72-7.14,18.85s-5.22,12.82-4.18,19.48c.71,4.52,2.93,9.34.85,13.41-.51,1-1.27,1.89-1.85,2.86-2.85,4.76-1.23,10.79-1.34,16.33a3.23,3.23,0,0,1-.39,1.77,4.89,4.89,0,0,1-1.58,1.22,8.38,8.38,0,0,0-3.41,6.43,24.57,24.57,0,0,0,.9,7.46,4.44,4.44,0,0,0,1.23,2.6,4.6,4.6,0,0,0,2.69.76A59.84,59.84,0,0,1,401,712.19c3.79,1.58,7.47,3.56,11.5,4.32a3,3,0,0,0,2.36-.25,3.25,3.25,0,0,0,1-1.73c1.55-5.1,3.12-10.36,2.59-15.66-.23-2.28-.84-4.51-1-6.79-.7-9,5.39-17.12,7.32-26,.87-4,.87-8.14,1.49-12.18,1.68-11.07,7.78-21,10.13-31.95a34.73,34.73,0,0,1,1.52-6c1.75-4.24,5.8-7.68,5.89-12.27a4.78,4.78,0,0,0-.76-2.86,6.48,6.48,0,0,0-3.57-2,121.87,121.87,0,0,0-16.55-3.34,31.35,31.35,0,0,0-7.78-.54,22.9,22.9,0,0,0-9.52,3.36C401.76,600.68,404.24,601.25,405.08,604.69Z" transform="translate(-34.96 -80.93)" opacity="0.05"></path><polygon points="350.55 674.47 342.02 674.47 336.44 559.83 336.05 553.31 343.3 550.76 343.79 557.69 350.55 674.47" fill="#565661"></polygon><polygon points="343.79 557.69 336.44 559.83 336.05 553.31 343.3 550.76 343.79 557.69" opacity="0.1"></polygon><polygon points="457.58 698.72 443.51 700.42 378.69 553.31 361.21 552.03 330.51 560.99 324.54 736.14 310.47 736.14 316.01 554.59 282.32 555.45 222.2 705.11 209.41 705.11 272.64 530.2 275.08 523.46 369.31 520.23 392.8 533.4 393.1 534.16 457.58 698.72" fill="#565661"></polygon><path d="M428.06,615.09c-20.25,6.1-41.27,12.76-41.27,12.76s-19.17,6.69-27.29,0a12.27,12.27,0,0,0-3.39-1.87,16.7,16.7,0,0,0,3.39,1.87l-51.9-16.73,2.43-6.73,94.24-3.23,23.49,13.17Z" transform="translate(-34.96 -80.93)" opacity="0.1"></path><path d="M332.21,586.06l38.37-8.53s91.68,17.06,98.5,23.88c0,0-73.34,14.92-81.44,20S331.35,632.11,332.21,586.06Z" transform="translate(-34.96 -80.93)" fill="#fff"></path><path d="M315.71,490.17c-3,9.51-11.19,18.08-21.16,18.49a3.69,3.69,0,0,1-2.11-.38c-1.25-.78-1.28-2.61-.77-4s1.4-2.64,1.54-4.1a2.68,2.68,0,0,0-.06-.89c-.26-1.19-1.23-2.25-2.37-2a4,4,0,0,0,.85-5.31,12,12,0,0,1-1.22-1.64c-.83-1.7.46-3.61,1-5.43,1.11-4-1.71-8-1.94-12.17-.2-3.73,1.69-7.24,2.16-10.94.75-6-2.23-11.75-2.58-17.74-.24-4.18.79-8.32,1.94-12.35,1-3.6,2.13-7.24,2.2-11,0-2.73-.47-5.43-.6-8.15a14.19,14.19,0,0,1,1.31-7.24,5.79,5.79,0,0,1,3.29-2.81c3.28-1.1,5.43.61,5.91,3.72.8,5.29.34,10.69,1.39,16a75,75,0,0,0,4.39,14.49c1.77,4.22,3.92,8.3,5.28,12.67a69.8,69.8,0,0,1,2.19,11C317.69,470.38,318.74,480.66,315.71,490.17Z" transform="translate(-34.96 -80.93)" fill="#94acef"></path><path d="M543.47,732.21a15.51,15.51,0,0,1-10.93,6.44c-4.34.54-8.85-.55-13.06.64a4,4,0,0,0-3,2.31,24.54,24.54,0,0,0-.19,2.45c-.49,2.67-4,3.27-6.73,3.25l-11.26-.07c-2.34,0-4.93-.13-6.61-1.75a4.92,4.92,0,0,1-.1-6.48,4.07,4.07,0,0,1,1.26-1,4,4,0,0,1-2.7-3.21,11.94,11.94,0,0,1,.21-4.41c0-4.18,1-11.18,3.94-14.45,3.61-4.07,9.87-9.33,15.32-10.42A12,12,0,0,1,520,708.46c2.58,2.4,4.46,6.16,8,6.58,1.93.24,3.79-.67,5.7-1a10.61,10.61,0,0,1,10.81,5.71,11.26,11.26,0,0,1,1,3.13A13,13,0,0,1,543.47,732.21Z" transform="translate(-34.96 -80.93)" fill="#a26565"></path><path d="M543.47,732.21a15.51,15.51,0,0,1-10.93,6.44c-4.34.54-8.85-.55-13.06.64a4,4,0,0,0-3,2.31,24.54,24.54,0,0,0-.19,2.45c-.49,2.67-4,3.27-6.73,3.25l-11.26-.07c-2.34,0-4.93-.13-6.61-1.75a4.92,4.92,0,0,1-.1-6.48c6.5-.27,12.89,0,19.37-1.34,2.63-.53,5.22-1.23,7.88-1.6,5.76-.82,11.89-.12,17.18-2.56,4.41-2,7.57-6.07,9.44-10.61A13,13,0,0,1,543.47,732.21Z" transform="translate(-34.96 -80.93)" opacity="0.1"></path><path d="M513.76,716.4c-4,3.1-8.69,5.52-13.73,5.78s-10.39-2-12.86-6.38c-3.61-6.43-.41-15.37-4.83-21.27-1.38-1.85-3.37-3.16-4.83-4.95s-2.3-4.48-1-6.38c-1.57.6-3.23-.92-3.69-2.54s-.17-3.36-.45-5c-.73-4.35-5-7.14-7.05-11s-1.77-8.87-2-13.44a51,51,0,0,0-11.8-30.35c-1.36-1.62-3.1-3.27-5.22-3.19.37-3.66-2.07-7.16-5.23-9s-6.92-2.46-10.58-2.82c-36.93-3.64-75.41,10.09-110.67-1.46-9.81-3.21-19.27-8.58-25.27-17a29.72,29.72,0,0,1-5.29-22.48l0-.14c1.39-7.1,5.14-8.85,11.35-12.09A136.24,136.24,0,0,1,323,543.3c15-4.69,31.15-6.38,46.63-2.94,7.23,1.62,14.2,4.3,21.44,5.87,2.85.62,5.72,1.06,8.61,1.43,4.49.56,9,.93,13.52,1.45a204.53,204.53,0,0,1,42.46,9.55c5.13,1.74,10.26,3.73,14.67,6.88A32.5,32.5,0,0,1,483.37,587c.42,2.94.43,6,1.07,8.85a45,45,0,0,0,2.4,7,465.63,465.63,0,0,1,20.89,65,15.79,15.79,0,0,0,1.67,4.7c1.28,2.07,3.48,3.46,4.77,5.53,3,4.88.11,11.69,2.77,16.77.92,1.76,2.45,3.15,3.37,4.91C523.31,705.53,518.88,712.43,513.76,716.4Z" transform="translate(-34.96 -80.93)" fill="#454b69"></path><path d="M462.66,601.5a16.5,16.5,0,0,0,3.63-4,7.46,7.46,0,0,0,1.1-5.17,14.79,14.79,0,0,1-3.89,12.72c-2.51,2.57-7.22,5.09-10.89,4.21C453.13,606.32,460.33,603.48,462.66,601.5Z" transform="translate(-34.96 -80.93)" opacity="0.1"></path><path d="M400.18,551.66a6.71,6.71,0,0,1-4.44,4.58,18.5,18.5,0,0,1-6.59.77l-2,0c-26.24-.58-52.76-6.4-78.39-.85a56.76,56.76,0,0,0-9.06,2.67,40.9,40.9,0,0,0-10.41,6l0-.14c1.39-7.1,5.14-8.85,11.35-12.09A136.24,136.24,0,0,1,323,543.3c15-4.69,31.15-6.38,46.63-2.94,7.23,1.62,14.2,4.3,21.44,5.87,2.85.62,5.72,1.06,8.61,1.43A6.91,6.91,0,0,1,400.18,551.66Z" transform="translate(-34.96 -80.93)" opacity="0.1"></path><path d="M400.18,550.23a6.7,6.7,0,0,1-4.44,4.59,18.27,18.27,0,0,1-6.59.76l-2,0c-26.24-.58-52.76-6.4-78.39-.85a57.78,57.78,0,0,0-9.06,2.66,41.2,41.2,0,0,0-10.85,6.4q-1.15-3.16-2.29-6.33c-.92-2.52,2-3.08,2.56-5.34.37-1.53-.26-3.27-.58-4.9a8.55,8.55,0,0,1-.16-1.21c-.18-3.61,1.11-5.69,4.07-7.64,8.78-5.8,19.49-9.78,29.51-12.77a73,73,0,0,1,16.4-3.18c7.88-.46,15.75,1,23.42,2.85,9.43,2.33,18.76,5.41,27.12,10.34C393,538,397,541,399.21,545.26A7.6,7.6,0,0,1,400.18,550.23Z" transform="translate(-34.96 -80.93)" fill="#a26565"></path><path d="M315.71,490.17c-3,9.51-11.19,18.08-21.16,18.49a3.69,3.69,0,0,1-2.11-.38c-1.25-.78-1.28-2.61-.77-4s1.4-2.64,1.54-4.1a2.68,2.68,0,0,0-.06-.89c5.29-7.46,10.42-15,12.45-23.83a12.74,12.74,0,0,0,.37-4.67c-.27-1.8-1.18-3.43-1.68-5.17-.88-3.08-.47-6.34-.22-9.53A88,88,0,0,0,297.23,415c-1.35-3.12-2.89-6.28-3.36-9.61a5.79,5.79,0,0,1,3.29-2.81c3.28-1.1,5.43.61,5.91,3.72.8,5.29.34,10.69,1.39,16a75,75,0,0,0,4.39,14.49c1.77,4.22,3.92,8.3,5.28,12.67a69.8,69.8,0,0,1,2.19,11C317.69,470.38,318.74,480.66,315.71,490.17Z" transform="translate(-34.96 -80.93)" opacity="0.1"></path><path d="M400.18,550.23a6.7,6.7,0,0,1-4.44,4.59,18.27,18.27,0,0,1-6.59.76l-2,0a43.57,43.57,0,0,0-29-7c-3.26.39-6.52,1.15-9.78.85-6.59-.6-11.93-5.34-17.8-8.37a37.38,37.38,0,0,0-41.43,5.62l-.57.5a8.55,8.55,0,0,1-.16-1.21c-.18-3.61,1.11-5.69,4.07-7.64,8.78-5.8,19.49-9.78,29.51-12.77a73,73,0,0,1,16.4-3.18c7.88-.46,15.75,1,23.42,2.85,9.43,2.33,18.76,5.41,27.12,10.34C393,538,397,541,399.21,545.26A7.6,7.6,0,0,1,400.18,550.23Z" transform="translate(-34.96 -80.93)" opacity="0.1"></path><path d="M422.61,440.69l-.14.36c-2.24,5.81-6.36,10.72-9,16.38-3.33,7.17-4.15,15.21-4.89,23.09-.64,6.75-1.27,13.54-.76,20.31,1.28,16.68,9.43,32.5,11.61,48.86a54.31,54.31,0,0,1,.41,11.41c-.18,2.41-.62,5-2.22,6.78s-4.71,2.48-6.43.77c.77-1.47,1.55-2.93,2.33-4.4-4.57-3.55-11.45-1-16.79-3.22-2.35-1-4.23-2.8-6.2-4.41a43.48,43.48,0,0,0-32.39-9.46c-3.26.4-6.52,1.16-9.78.86-6.59-.61-11.93-5.34-17.8-8.37a37.4,37.4,0,0,0-41.43,5.61c-1.4,1.3-3.28,2.82-5,2a4.16,4.16,0,0,1-1.55-1.69c-6.55-11.19-1.73-25.62,5.27-36.52S304.12,488.1,307,475.47a12.53,12.53,0,0,0,.37-4.67c-.27-1.8-1.18-3.43-1.68-5.17-.88-3.08-.47-6.34-.22-9.53A88,88,0,0,0,298.65,415c-1.6-3.73-3.5-7.51-3.5-11.56,0-6.38,4.57-11.67,8.35-16.8,4.35-5.9,8-12.43,13.51-17.28,5.22-4.61,12.78-7.43,19.24-5.09A119.94,119.94,0,0,1,369.81,361c3.9.18,7.93.59,11.35,2.48,3.66,2,6.29,5.56,9.89,7.69,2.63,1.57,5.66,2.31,8.52,3.41A35.21,35.21,0,0,1,417.93,391c4,7.75,5,16.66,5.88,25.34C424.65,424.51,425.45,433,422.61,440.69Z" transform="translate(-34.96 -80.93)" fill="#94acef"></path><path d="M407.82,500.83c1.28,16.68,9.43,32.5,11.61,48.86C415.07,546,409,542.29,408.19,538c-.9-4.64-3.78-10.72-4.26-15.41s2.81-10.42-.64-13.64c-1.68-1.57,2.79-1.13,1.15-2.74-3.69-3.59-4.6-9.12-4.83-14.25-.39-9.08.76-18.26-.91-27.19-1-5.51-3.09-10.76-4.76-16.11-1.94-6.23-3.34-12.61-4.74-19a133.12,133.12,0,0,1-3-17.26c-.43-5-.23-10.3,2-14.86s6.74-8.26,11.8-8.19c16.92.22,14,23.16,17.72,33.76,1.49,4.22,3.5,8.3,4.31,12.7a33.66,33.66,0,0,1,.48,5.22c-2.24,5.81-6.36,10.72-9,16.38-3.33,7.17-4.15,15.21-4.89,23.09C407.94,487.27,407.31,494.06,407.82,500.83Z" transform="translate(-34.96 -80.93)" opacity="0.1"></path><path d="M418.82,422.85c1.49,4.22,3.5,8.3,4.31,12.7,1.35,7.37-.74,15.2,1.53,22.34a38.92,38.92,0,0,1,1.48,4.67c.39,2.27-.06,4.59-.06,6.9,0,3.72,1.17,7.32,2.21,10.89a194.63,194.63,0,0,1,6.95,37.16,46.59,46.59,0,0,0,1.59,10,33.21,33.21,0,0,1,1.08,3.38,17.48,17.48,0,0,1,.19,4.63c-.27,4.9-.82,9.82-.27,14.7s2.33,9.83,6,13.1c-3.28.71-6.75,1.42-9.95.37-4.5-1.47-7.2-6-9.49-10.12-2.9-5.26-13.92-10-15.06-15.91-.89-4.63-3.77-10.71-4.25-15.41s2.8-10.41-.65-13.63c-1.67-1.57,2.8-1.14,1.15-2.74-3.68-3.59-4.59-9.12-4.82-14.26-.39-9.07.75-18.25-.91-27.18-1-5.51-3.09-10.76-4.76-16.12-1.94-6.22-3.34-12.6-4.74-19a131.73,131.73,0,0,1-3-17.26c-.43-5-.24-10.31,2-14.87s6.75-8.25,11.8-8.19C418,389.3,415.1,412.25,418.82,422.85Z" transform="translate(-34.96 -80.93)" fill="#94acef"></path><path d="M370.6,426.76c1.58,1.85,3.61,3.88,6,3.52a1.3,1.3,0,0,1-1.77.42,3.8,3.8,0,0,1-1.33-1.53l-3.42-5.77c-.45-.75-3.55-5.12-4.31-2.6C365.47,421.87,369.83,425.86,370.6,426.76Z" transform="translate(-34.96 -80.93)" opacity="0.1"></path><path d="M368.76,441.15a7.62,7.62,0,0,0-2.23-5,12.5,12.5,0,0,0-4.13-2.49c-3.75-1.54-8.19-2.78-12.26-2.58,1.48,2.16,6.23,3.45,8.61,4.67Q363.81,438.36,368.76,441.15Z" transform="translate(-34.96 -80.93)" opacity="0.1"></path><path d="M379.41,482.11c-.69,5.12-4.88,9-9.12,12s-9,5.58-11.77,9.92c-1.92,3-2.78,6.48-4.41,9.61-1.8,3.45-4.49,6.35-6.64,9.59s-3.83,7.11-3.17,10.95a1.29,1.29,0,0,0,.46.92,1.31,1.31,0,0,0,1.27-.14c4.36-2.28,6.08-7.49,7.91-12a138.65,138.65,0,0,1,6.48-13.32c1.08-2,2.27-4.18,4.28-5.29a37.55,37.55,0,0,1,4.22-1.47,14.19,14.19,0,0,0,5.21-4.09,34.34,34.34,0,0,0,8-23.31c-.06-1.79-.16-10.41-2.85-7.75S379.87,478.63,379.41,482.11Z" transform="translate(-34.96 -80.93)" opacity="0.1"></path><path d="M386,285.74c8.6,3.75,16,12,15.73,21.35-.23,9.82-8.45,19.07-5.62,28.48,1.64,5.46,6.58,9.12,10.49,13.27,14.89,15.76,14.86,43.27-.08,59-5.72,6-13.07,10.27-19.12,16-21.33,20.1-22.24,54.87-10.82,81.86a133.14,133.14,0,0,1-26.62,3c-4.19,0-9.32-.71-10.84-4.62-1.4-3.61,1-8.49-1.76-11.16-1.3-1.25-3.25-1.42-5-1.71-11.26-1.82-20.5-10.81-24.72-21.4s-4-22.51-1.58-33.65c1.72-8.05,4.41-16.91.42-24.11-5-9.06-19.38-12.88-19.16-23.24.18-8.49,10.19-12.62,15.87-18.93,10.48-11.62,5.49-29.65,5.47-45.31,0-13.78,4.82-28,15.08-37.18C339,273.62,368.39,278.09,386,285.74Z" transform="translate(-34.96 -80.93)" fill="#a26565"></path><g opacity="0.1"><path d="M308.12,401.78c-4.39-7.92-15.92-11.84-18.6-19.63a11.09,11.09,0,0,0-2.16,6.26c-.22,10.36,14.14,14.18,19.16,23.25a18.89,18.89,0,0,1,2,10.42C310.1,415.12,311.49,407.86,308.12,401.78Z" transform="translate(-34.96 -80.93)"></path><path d="M397.26,322.75c1.8-5.25,4.41-10.55,4.54-16a15,15,0,0,0-.05-1.77C399.74,311,396.66,316.84,397.26,322.75Z" transform="translate(-34.96 -80.93)"></path><path d="M309.84,350.72c3.44-10.87.47-24.35.46-36.41,0-1.46.06-2.93.17-4.39a57.74,57.74,0,0,0-1.78,14.26C308.71,332.79,310.22,342.13,309.84,350.72Z" transform="translate(-34.96 -80.93)"></path><path d="M408.19,397.61c-5.72,6-13.07,10.27-19.12,16-10.8,10.17-16.35,24.1-17.74,38.87,2.58-11,7.79-21.13,16.14-29,6-5.7,13.4-9.95,19.12-16a42.49,42.49,0,0,0,11.15-27.06A40.61,40.61,0,0,1,408.19,397.61Z" transform="translate(-34.96 -80.93)"></path><path d="M351.63,498.44c-4.19,0-9.32-.72-10.84-4.63-1.4-3.6,1-8.48-1.76-11.16-1.3-1.25-3.26-1.42-5-1.71-11.25-1.81-20.49-10.81-24.71-21.39-3.11-7.82-3.78-16.35-3-24.77-.08.33-.15.66-.22,1-2.38,11.14-2.63,23.07,1.58,33.66s13.46,19.58,24.71,21.39c1.78.29,3.74.47,5,1.71,2.79,2.68.36,7.56,1.76,11.16,1.52,3.91,6.65,4.68,10.84,4.63a133.23,133.23,0,0,0,26.62-3,89.38,89.38,0,0,1-3.23-8.93A132.74,132.74,0,0,1,351.63,498.44Z" transform="translate(-34.96 -80.93)"></path></g><path d="M384.38,454.83c2.47,1.86,5.15-5.23,3.62-7C387.59,448.29,384,454.57,384.38,454.83Z" transform="translate(-34.96 -80.93)" opacity="0.1"></path><path d="M394.91,583.17c2.91-1,6-2,7.9-4.4,1.57-1.93,2.86-9.59-.46-5.92C399.53,576,398.2,580.15,394.91,583.17Z" transform="translate(-34.96 -80.93)" opacity="0.1"></path><path d="M424.54,575.14c-.35,2.36-1,4.81-2.67,6.51-.31.32-1,.52-1.09.09a25.29,25.29,0,0,0,5.16-3.64c3.38-3.35,3.84-11.6-1.31-13.79C424.58,567.93,425.09,571.46,424.54,575.14Z" transform="translate(-34.96 -80.93)" opacity="0.1"></path><path d="M460.11,560.27s-28.38-11.15-38.64-10,11.62,17.32,11.62,17.32l13.08,8.82s8-3,8.53-3.23S460.11,560.27,460.11,560.27Z" transform="translate(-34.96 -80.93)" fill="#454b69"></path><path d="M264.84,440.65s21.32-12.36,49.46,3,32.83,105.75,32.83,105.75S335.62,641.49,380,621c0,0,81-25.15,89.11-19.61,0,0,7.68,0-7.67,3.41S386.79,627,386.79,627s-19.17,6.7-27.29,0-31.13.86-34.12-45.2a801,801,0,0,0-10.66-86.56l-7.91-23.45Z" transform="translate(-34.96 -80.93)" fill="#565661"></path><path d="M262.28,583.07s9.38-93.38-6-127.07c-13.38-29.36,38.36-15.63,51.86-11.63a9.83,9.83,0,0,1,5.18,3.7c8,11.25,36.7,56.34,28.24,116.67,0,0-3.41,53.73,17.91,62.25l-65.69-21.16c-5.33-1.72-10.74-3.15-16.2-4.39C270.62,599.86,259.28,595.37,262.28,583.07Z" transform="translate(-34.96 -80.93)" fill="#fff"></path><polygon points="694.53 676.47 703.06 676.47 708.65 561.83 709.03 555.31 701.78 552.76 701.3 559.69 694.53 676.47" fill="#565661"></polygon><polygon points="701.3 559.69 708.65 561.83 709.03 555.31 701.78 552.76 701.3 559.69" opacity="0.1"></polygon><path d="M658.27,713.13a19.23,19.23,0,0,1-1.2,4.58,8.09,8.09,0,0,1-3.65,4.56,9.64,9.64,0,0,1-3.69.73c-4.71.28-9.69.21-13.74-2.19a25,25,0,0,1-4.71-3.93,214.9,214.9,0,0,1-24.72-29.4c-1.23-1.77-2.5-3.86-1.95-6a93.21,93.21,0,0,0,26.77-12.25,12.92,12.92,0,0,1,3.76-2,20.43,20.43,0,0,1,7.06-.26c2.27.37,2.37.44,3.24,3,1.44,4.33,1.2,9,2.82,13.33a41.3,41.3,0,0,0,3.74,6.84C656.18,697.13,659.39,705.38,658.27,713.13Z" transform="translate(-34.96 -80.93)" fill="#a26565"></path><path d="M658.27,713.13a19.23,19.23,0,0,1-1.2,4.58,8.09,8.09,0,0,1-3.65,4.56,9.64,9.64,0,0,1-3.69.73c-4.71.28-9.69.21-13.74-2.19a25,25,0,0,1-4.71-3.93,214.9,214.9,0,0,1-24.72-29.4c-1.23-1.77-2.5-3.86-1.95-6a92.81,92.81,0,0,0,9.16-3.06l.15.11c3.07,2.19,5.3,5.33,7.47,8.41l7,9.85a29,29,0,0,0,4.39,5.3,29.38,29.38,0,0,0,6.79,4.08c3.29,1.59,6.58,3.18,10,4.46C651.78,711.52,655.52,711.87,658.27,713.13Z" transform="translate(-34.96 -80.93)" opacity="0.1"></path><path d="M664.73,606.34a30.1,30.1,0,0,1-2.5,4.77A204.16,204.16,0,0,0,640.91,661c-1.38-.31-2.16,1.57-2.15,3s0,3.23-1.32,3.75c-.39.15-.83.15-1.21.32-.84.38-1.08,1.45-1.2,2.37l-1.18,8.66c-.41,3-.77,6.25.7,8.9a14.23,14.23,0,0,0,3.87,4l19.52,15.4c.8.63,1.79,1.3,2.75.95,2.19-.8.25-4.72,2-6.31,1.16-1.09,3-.27,4.61-.4,2.1-.16,3.69-2.09,4.22-4.12a19.59,19.59,0,0,0,.11-6.26,5.68,5.68,0,0,1,.32-2.81,6.82,6.82,0,0,1,2.39-2.29,25.66,25.66,0,0,0,10.51-21.64,12,12,0,0,1,.14-3.83,10.09,10.09,0,0,1,1.81-3.16c7.09-9.59,13-20,18.87-30.39,3.38-6,6.82-12.09,8-18.85a1.75,1.75,0,0,0-1.44-2.4,68,68,0,0,0-8.94-2.14c-9.19-1.86-18.06-4.73-27-7.49S667.42,599.12,664.73,606.34Z" transform="translate(-34.96 -80.93)" fill="#454b69"></path><polygon points="587.5 700.72 601.58 702.42 666.39 555.31 683.87 554.03 714.58 562.99 720.54 738.14 734.61 738.14 729.07 556.59 762.76 557.45 822.88 707.11 835.67 707.11 772.44 532.2 770.01 525.46 675.77 522.23 652.28 535.4 651.98 536.16 587.5 700.72" fill="#565661"></polygon><path d="M686.94,617.09c20.25,6.1,41.27,12.76,41.27,12.76s19.17,6.69,27.29,0a12.27,12.27,0,0,1,3.39-1.87,16.7,16.7,0,0,1-3.39,1.87l51.9-16.73L805,606.39l-94.24-3.23-23.49,13.17Z" transform="translate(-34.96 -80.93)" opacity="0.1"></path><path d="M782.79,588.06l-38.37-8.53s-91.68,17.06-98.5,23.88c0,0,73.34,14.92,81.44,20S783.65,634.11,782.79,588.06Z" transform="translate(-34.96 -80.93)" fill="#fff"></path><path d="M640.41,725.14c-2.31,4.4-8,5.64-13,5.71a54.89,54.89,0,0,1-20.32-3.63c-3.7-1.42-7.25-3.25-11.07-4.29-5.69-1.56-12-1.43-17-4.56a20,20,0,0,1-6.39-6.93c-.29-.49-.57-1-.83-1.52-2.39-4.65-3.5-10.06-2.17-15.08s6.16-10.55,11.76-10.47c6.65.1,14.58,3.25,21,4.88,8,2,16,4.31,23.07,8.54,5.92,3.56,11.15,8.67,13.94,14.91a25.27,25.27,0,0,1,1.32,3.72C641.59,719.3,641.79,722.51,640.41,725.14Z" transform="translate(-34.96 -80.93)" fill="#a26565"></path><path d="M640.41,725.14c-2.31,4.4-8,5.64-13,5.71a54.89,54.89,0,0,1-20.32-3.63c-3.7-1.42-7.25-3.25-11.07-4.29-5.69-1.56-12-1.43-17-4.56a20,20,0,0,1-6.39-6.93c-.29-.49-.57-1-.83-1.52,1,.08,1.92.18,2.42.23,6.14.59,12,2.83,17.86,4.52a100.32,100.32,0,0,0,25,3.9c6,.17,12.26-.27,17.5-3.2a45.91,45.91,0,0,1,4.86-2.67,25.27,25.27,0,0,1,1.32,3.72C641.59,719.3,641.79,722.51,640.41,725.14Z" transform="translate(-34.96 -80.93)" opacity="0.1"></path><path d="M683.38,535c-13-2.13-26.24-2.65-39.42-3.17l-16.12-.64a7.31,7.31,0,0,0-3.39.41,22.09,22.09,0,0,0-2.65,2c-1.62,1.1-3.69,1.22-5.64,1.33A280.77,280.77,0,0,0,575,540.27c-7,1.43-14.27,3.3-19.53,8.13-5.56,5.11-8,12.9-8.19,20.44s1.79,14.95,3.88,22.19a101.09,101.09,0,0,1,4.37,26.86,50.25,50.25,0,0,0,.29,7.57,36.22,36.22,0,0,0,2.11,7l7.36,19.65c.65,1.72,1.29,3.43,2,5.11s1.39,3,2,4.58c.9,2.16,1.61,4.4,2.32,6.63l4.9,15.39.64,2c1.77,5.54,3.58,11.18,6.92,15.94s8.51,8.6,14.32,8.89a43.86,43.86,0,0,1,5.62.15,22.72,22.72,0,0,1,4.61,1.67,35.17,35.17,0,0,0,13.77,2.69c4.35,0,9.18-1.21,11.54-4.87,1.3-2,1.64-4.46,2-6.82.63-4.74,1.24-9.69-.37-14.19-1-2.69-2.68-5-3.84-7.65-1.62-3.61-2.15-7.6-3.2-11.41a43.58,43.58,0,0,0-13.3-21.16,208.58,208.58,0,0,1-5-27.38,24.09,24.09,0,0,0-1.21-6c-1.17-3-3.54-5.43-4.53-8.49-.93-2.84-.65-6.12-2.34-8.57,14.07,3.87,28,3,42.61,2.77a116.42,116.42,0,0,0,14-.8,44,44,0,0,1,6.56-.7c4.52,0,8.76,2,12.91,3.76,11.73,5,24.09,8.93,36.83,9.47,13.15.55,26.15-2.54,39-5.6,5.65-1.35,11.52-2.81,16-6.52s7-10.4,4.24-15.49c-2.1-3.83-6.45-5.71-10.51-7.31-11.24-4.44-22.54-8.77-33.37-14.14C713.87,556,701.5,538,683.38,535Z" transform="translate(-34.96 -80.93)" fill="#454b69"></path><path d="M660.2,489.76c-1.57,3.4-4.21,6.18-6.16,9.38a23.77,23.77,0,0,0-3,17.65,20.08,20.08,0,0,0,11.25,13.69,28.23,28.23,0,0,0,7.8,1.88c3.52.43,7.27.52,10.38-1.18A15.16,15.16,0,0,0,686,525.4c2.69-4.5,4.22-9.57,5.62-14.62,2.59-9.32,4.8-18.88,4.48-28.55-.11-3.33-.77-7.08-3.53-9a11.87,11.87,0,0,0-4.64-1.52l-13.19-2.36c-2.55-.46-7-2.33-9.21-.49s-2.38,7.28-2.76,9.83C662.17,482.46,661.8,486.29,660.2,489.76Z" transform="translate(-34.96 -80.93)" fill="#a1616a"></path><path d="M820.53,451.08,817.08,480a133,133,0,0,0-1.23,15.56c0,2.9.09,6.12-1.83,8.29a7.56,7.56,0,0,1-3.44,2.07c-4.19,1.3-8.76.14-12.76-1.65-2.34-1-4.73-2.45-5.79-4.78a11.88,11.88,0,0,1-.75-5.07c0-17.25,1.63-35.24,10.64-49.94a10.89,10.89,0,0,1,3.17-3.66c2.5-1.6,5.77-1.15,8.6-.28,1.74.53,6.44,1.12,7.55,2.67S820.77,449.09,820.53,451.08Z" transform="translate(-34.96 -80.93)" fill="#a1616a"></path><circle cx="694.04" cy="229.57" r="36" fill="#a1616a"></circle><path d="M719.37,364.15a18.57,18.57,0,0,1-2.23,8q27.57-4.2,55-9.36a25.83,25.83,0,0,1-12.76-15,42.36,42.36,0,0,1-1.62-10.69,123.57,123.57,0,0,1,.33-17.21c-6.4.67-12.46,3.07-18.56,5.13a183,183,0,0,1-18.69,5.23c-3.05.68-6.12,1.26-9.2,1.8-3.6.64-5.33.63-2.83,3.79C715.52,344.28,720.31,352.86,719.37,364.15Z" transform="translate(-34.96 -80.93)" fill="#a1616a"></path><path d="M730.43,359.34c-4.75.71-9.73,1.51-13.52,4.45a51,51,0,0,0-4.11,3.95c-7.53,7.31-18.16,10.25-27.3,15.41a12,12,0,0,0-3.88,3.05c-1,1.39-1.51,3.16-2.56,4.54-1.22,1.6-3.15,2.6-4.1,4.37s-.74,3.65-.84,5.53c-.23,4.13-1.79,8.05-3,12-5.55,18.91-2.51,40-10.91,57.86a8.13,8.13,0,0,0,4.42,4.62,25.1,25.1,0,0,0,6.56,1.41l18.61,2.31c2.66.33,5.48.64,7.91-.47a92.94,92.94,0,0,0-4.69,18.93,94.28,94.28,0,0,1-2.1,11.72c-2.56,8.8-9,16.13-16.63,21.14a6.15,6.15,0,0,0-2.35,2.17c-1,2,.48,4.24,1.53,6.2,3.05,5.68,2.63,12.5,2.59,18.94s.61,13.51,5.11,18.13c2.66,2.73,6.3,4.21,9.84,5.62l29.11,11.63a101.45,101.45,0,0,0,14.82,5c7.67,1.75,15.64,1.68,23.51,1.34q7.8-.33,15.58-1a12.12,12.12,0,0,0,5.89-1.55,11,11,0,0,0,3.45-4.68c4.05-8.81,5.41-19.09,11.69-26.47,4.31-5.07,11-9.12,11.49-15.75.23-3.3-1.24-6.51-1.26-9.82,0-4.07,2.13-7.94,2-12-.27-6.61-6.5-11.65-7.49-18.19-2.52-16.58,5.9-33.14,11.07-49.09.93-2.85,2.13-6,4.87-7.22s6.6-.58,7.58-3.28c2.47-6.78,3.06-14.73,2.74-21.94-.18-4.17-1.66-8.25-1.49-12.43.12-2.94,1.06-5.8,1.31-8.73.38-4.43-.79-8.83-2-13.11a20.54,20.54,0,0,0-1.56-4.42,21,21,0,0,0-2.6-3.57l-4.87-5.79c-2.28-2.71-4.69-5.52-8-6.89-1.07-2.65-4.49-4.48-6.94-5.94a71.12,71.12,0,0,0-7.64-3.75l-27.54-12.16a11.28,11.28,0,0,0-3.27-1.06,10.59,10.59,0,0,0-4.86,1C748.2,354.68,739.43,358,730.43,359.34Z" transform="translate(-34.96 -80.93)" fill="#94acef"></path><path d="M701.26,316.76c-1.06-3.73-3.77-6.95-4.18-10.81-.37-3.43,1.14-6.75,2-10.09s.83-7.42-1.82-9.64c-.44-.38-1-.72-1.16-1.28-.32-1,.69-1.91,1-2.92.57-2-1.9-4.21-1-6.13.51-1.05,1.79-1.42,2.91-1.75,4.28-1.27,8.62-4.09,9.55-8.46,3.35,1.4,6.92-1.23,9.49-3.78s5.73-5.46,9.27-4.69l-.79,1.61a25.6,25.6,0,0,1,16.93-.19l-1.68,0a23.22,23.22,0,0,1,13.39,4.53c-.43,0-.47.64-.3,1,1.4,3.27,5,5,8.47,5.81,2.09.5,4.36.86,5.89,2.36s1.56,4.63-.46,5.35a52.6,52.6,0,0,1,11.61,6.3c1,.73,2.13,1.72,2,3a9.76,9.76,0,0,1-.62,1.87,6.47,6.47,0,0,0,.21,3.2l1.11,4.58c1.22,5.09,2.18,11.22-1.53,14.91a13.69,13.69,0,0,1-2.41,16.16,6.66,6.66,0,0,1-5,8.61c1.23,1.92.1,4.66-1.84,5.86s-4.38,1.21-6.64,1-4.55-.72-6.81-.38c-3.29.51-6.51,2.75-9.68,1.75a21.73,21.73,0,0,1-3.39-1.82c-2.22-1.19-4.8-1.46-7.26-2a33.54,33.54,0,0,1-11.73-5,13.75,13.75,0,0,1-5.39-6c-2.2-5.56,1.5-12.85-2.39-17.38-2.28-2.64-6.8-2.68-9.35-.42-1.27,1.13-1.44,3.51-2.76,4.36A17.45,17.45,0,0,1,701.26,316.76Z" transform="translate(-34.96 -80.93)" fill="#464353"></path><path d="M652.34,603.5a16.5,16.5,0,0,1-3.63-4,7.46,7.46,0,0,1-1.1-5.17,14.79,14.79,0,0,0,3.89,12.72c2.51,2.57,7.22,5.09,10.89,4.21C661.87,608.32,654.67,605.48,652.34,603.5Z" transform="translate(-34.96 -80.93)" opacity="0.1"></path><path d="M850.16,442.65s-21.32-12.36-49.46,3-32.83,105.75-32.83,105.75S779.38,643.49,735,623c0,0-81-25.15-89.11-19.61,0,0-7.68,0,7.67,3.41S728.21,629,728.21,629s19.17,6.7,27.29,0,31.13.86,34.12-45.2a801,801,0,0,1,10.66-86.56l7.91-23.45Z" transform="translate(-34.96 -80.93)" fill="#565661"></path><path d="M852.72,585.07s-9.38-93.38,6-127.07c13.38-29.36-38.36-15.63-51.86-11.63a9.83,9.83,0,0,0-5.18,3.7c-8,11.25-36.7,56.34-28.24,116.67,0,0,3.41,53.73-17.91,62.25l65.69-21.16c5.33-1.72,10.74-3.15,16.2-4.39C844.38,601.86,855.72,597.37,852.72,585.07Z" transform="translate(-34.96 -80.93)" fill="#fff"></path><ellipse cx="989.97" cy="670.07" rx="97.44" ry="15.65" fill="#94acef" opacity="0.1"></ellipse><rect x="986.83" y="370.26" width="6.27" height="141.17" fill="#535461"></rect><path d="M1067.47,591.93l-.39,6.36-.56,9-.23,3.74-.55,9-.24,3.74-.56,9-6.32,102.07A17.3,17.3,0,0,1,1041.36,751h-32.87a17.28,17.28,0,0,1-17.24-16.22L984.91,632.7l-.55-9-.23-3.74-.57-9-.23-3.74-.55-9-.4-6.36a9,9,0,0,1,8.94-9.51h67.22A9,9,0,0,1,1067.47,591.93Z" transform="translate(-34.96 -80.93)" fill="#565661"></path><polygon points="1032.12 517.36 1031.56 526.33 948.38 526.33 947.82 517.36 1032.12 517.36" fill="#9d9cb5"></polygon><polygon points="1031.33 530.08 1030.78 539.06 949.17 539.06 948.61 530.08 1031.33 530.08" fill="#9d9cb5"></polygon><polygon points="1030.54 542.8 1029.98 551.77 949.96 551.77 949.4 542.8 1030.54 542.8" fill="#9d9cb5"></polygon><path d="M973.2,504.1c36.52,26.42,51.73,67.74,51.73,67.74s-44-1.51-80.53-27.93-51.72-67.73-51.72-67.73S936.69,477.69,973.2,504.1Z" transform="translate(-34.96 -80.93)" fill="#94acef"></path><path d="M892.68,476.18s45.67,25.35,60.33,46.34,71.92,49.32,71.92,49.32" transform="translate(-34.96 -80.93)" fill="none" stroke="#535461" stroke-miterlimit="10" stroke-width="2"></path><path d="M996.77,450.88c19.88,14.37,28.16,36.87,28.16,36.87s-24-.83-43.83-15.2S953,435.68,953,435.68,976.9,436.5,996.77,450.88Z" transform="translate(-34.96 -80.93)" fill="#94acef"></path><path d="M953,435.68s24.86,13.8,32.83,25.22,39.15,26.85,39.15,26.85" transform="translate(-34.96 -80.93)" fill="none" stroke="#535461" stroke-miterlimit="10" stroke-width="2"></path><path d="M1053.81,486.6c-22.83,25.09-27.66,57.88-27.66,57.88s32.19-7.9,55-33,27.66-57.88,27.66-57.88S1076.64,461.51,1053.81,486.6Z" transform="translate(-34.96 -80.93)" fill="#94acef"></path><path d="M1108.83,453.61s-29.74,25.72-37.3,43.44-45.38,47.43-45.38,47.43" transform="translate(-34.96 -80.93)" fill="none" stroke="#535461" stroke-miterlimit="10" stroke-width="2"></path><path d="M591.94,426.2v2.28H524.33v-1.85a22.72,22.72,0,0,0,5.22-2.78,22.21,22.21,0,0,0,9.28-18.06,21.92,21.92,0,0,0-.69-5.47,22.23,22.23,0,0,0-12.28-14.73h65.62a22.23,22.23,0,0,0-12.28,14.73,21.92,21.92,0,0,0-.68,5.47,22.2,22.2,0,0,0,9.27,18.06A22.87,22.87,0,0,0,591.94,426.2Z" transform="translate(-34.96 -80.93)" fill="#dfe6f5"></path><path d="M591.48,385.59a22.23,22.23,0,0,0-12.28,14.73H538.14a22.23,22.23,0,0,0-12.28-14.73Z" transform="translate(-34.96 -80.93)" opacity="0.1"></path><path d="M446.92,373.94v12.84c0,7.08,5.18,12.83,11.58,12.83H657.41c6.4,0,11.59-5.75,11.59-12.83V373.94Z" transform="translate(-34.96 -80.93)" fill="#dfe6f5"></path><path d="M591.94,426.2v2.28H524.33v-1.85a22.72,22.72,0,0,0,5.22-2.78h58.24A22.87,22.87,0,0,0,591.94,426.2Z" transform="translate(-34.96 -80.93)" opacity="0.1"></path><rect x="467.03" y="343.63" width="112.29" height="6.77" rx="3.39" fill="#dfe6f5"></rect><path d="M669,233.31a11.58,11.58,0,0,0-11.59-11.58H458.5a11.57,11.57,0,0,0-11.58,11.58V376.44H669Z" transform="translate(-34.96 -80.93)" fill="#474157"></path><path d="M662.94,238.48v123a5.7,5.7,0,0,1-5.7,5.71H458.68a5.7,5.7,0,0,1-5.7-5.71v-123a5.62,5.62,0,0,1,.76-2.85,5.7,5.7,0,0,1,4.94-2.85H657.24A5.7,5.7,0,0,1,662.94,238.48Z" transform="translate(-34.96 -80.93)" fill="#4c4c78"></path><circle cx="523" cy="146.32" r="2.67" fill="#fff"></circle><circle cx="523" cy="306.38" r="6.59" fill="#fff"></circle><path d="M662.94,238.48H453a5.7,5.7,0,0,1,5.7-5.7H657.24A5.7,5.7,0,0,1,662.94,238.48Z" transform="translate(-34.96 -80.93)" fill="#c8cad7"></path><circle cx="423.72" cy="154.7" r="1.43" fill="#ededf4"></circle><circle cx="428" cy="154.7" r="1.43" fill="#ededf4"></circle><circle cx="432.28" cy="154.7" r="1.43" fill="#ededf4"></circle></svg>
</div>
</div>
</div>
</div>
</div>
</header>
</main>
<footer>
<div class="container">
<p>Copyright @ 2017~2020 版权所有</p>
</div>
</footer>
<!-- jQuery -->
<script src="https://cdn.staticfile.org/jquery/2.1.4/jquery.min.js"></script>
<script src="__CDN__/assets/libs/jquery/dist/jquery.min.js"></script>
<!-- Bootstrap Core JavaScript -->
<script src="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script src="__CDN__/assets/libs/bootstrap/dist/js/bootstrap.min.js"></script>
</body>
</html>
... ...
<link rel="stylesheet" href="__CDN__/assets/libs/bootstrap-table/dist/bootstrap-table.min.css">
{if $Think.get.dialog}
<style>
body {
padding-top: 0;
background: #fff;
}
nav.navbar-fixed-top, footer.footer {
display: none;
}
main.content {
padding: 0;
}
.fixed-table-container {
border: none;
}
.panel-heading .nav-tabs {
padding: 0 15px;
}
.panel-heading .nav-tabs li {
font-size: 14px;
}
</style>
{/if}
<div class="panel panel-default panel-intro" style="padding:0;">
{if !$Think.get.mimetype||$Think.get.mimetype=='*'}
<div class="panel-heading">
<ul class="nav nav-tabs" data-field="mimetype">
<li class="active"><a href="#t-all" data-value="" data-toggle="tab">{:__('All')}</a></li>
{foreach name="mimetypeList" item="vo"}
<li><a href="#t-{$key}" data-value="{$key}" data-toggle="tab">{$vo}</a></li>
{/foreach}
</ul>
</div>
{/if}
<div class="panel-body">
<div id="myTabContent" class="tab-content">
<div class="tab-pane fade active in" id="one">
<div class="widget-body no-padding">
<div id="toolbar" class="toolbar">
<a href="javascript:;" class="btn btn-primary btn-refresh" title="刷新"><i class="fa fa-refresh"></i> </a>
<span><button type="button" id="faupload-image" class="btn btn-success faupload" data-mimetype="{$Think.get.mimetype|default=''}" data-multiple="true"><i class="fa fa-upload"></i> {:__('Upload')}</button></span>
{if request()->get('multiple') == 'true'}
<a class="btn btn-danger btn-choose-multi"><i class="fa fa-check"></i> {:__('Choose')}</a>
{/if}
</div>
<table id="table" class="table table-bordered table-hover" width="100%">
</table>
</div>
</div>
</div>
</div>
</div>
... ...
... ... @@ -17,7 +17,7 @@
{include file="common/sidenav" /}
</div>
<div class="col-md-9">
<div class="panel panel-default ">
<div class="panel panel-default">
<div class="panel-body">
<h2 class="page-header">
{:__('Member center')}
... ... @@ -42,6 +42,12 @@
</a>
</p>
<!-- Success -->
</div>
</div>
<div class="col-md-9 col-sm-9 col-xs-12">
<!-- Content -->
<div class="ui-content">
<div class="basicinfo">
<div class="row">
<div class="col-xs-4 col-md-2">{:__('Money')}</div>
... ... @@ -68,9 +74,10 @@
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
\ No newline at end of file
</div>
... ...
... ... @@ -3,7 +3,7 @@
namespace fast;
/**
* 字符串
* Http 请求
*/
class Http
{
... ...
... ... @@ -11,13 +11,12 @@
// +----------------------------------------------------------------------
// [ 后台入口文件 ]
// 使用此文件可以达到隐藏admin模块的效果
// 建议将admin.php改成其它任意的文件名,同时修改config.php中的'deny_module_list',把admin模块也添加进去
// 为了你的安全,强烈不建议将此文件名修改成admin.php
// 定义应用目录
define('APP_PATH', __DIR__ . '/../application/');
// 判断是否安装
if (!is_file(APP_PATH . 'admin/command/Install/install.lock'))
{
if (!is_file(APP_PATH . 'admin/command/Install/install.lock')) {
header("location:./install.php");
exit;
}
... ...
... ... @@ -28,13 +28,6 @@ body.is-dialog {
border: 1px solid #8B9;
background-color: #BEC;
}
.main-header .logo,
.main-header .navbar {
-webkit-transition: none;
-moz-transition: none;
-o-transition: none;
transition: none;
}
.main-header .navbar {
position: relative;
}
... ... @@ -52,9 +45,6 @@ html.ios-fix body {
.wrapper {
height: 100%;
}
#header {
background: #fff;
}
.content-wrapper {
position: relative;
height: 100%;
... ... @@ -336,7 +326,7 @@ form.form-horizontal .control-label {
.nav-addtabs > li > a:focus {
border: none;
color: #2c3e50;
border-right: 1px solid rgba(0, 0, 0, 0.05);
border-right: 1px solid rgba(0, 0, 0, 0.02);
}
.nav-addtabs > li.active > a {
height: 50px;
... ... @@ -344,7 +334,7 @@ form.form-horizontal .control-label {
padding: 0 15px;
border-radius: 0;
border: none;
border-right: 1px solid rgba(0, 0, 0, 0.05);
border-right: 1px solid rgba(0, 0, 0, 0.02);
background: #f1f4f6;
color: #2c3e50;
overflow: hidden;
... ... @@ -354,7 +344,7 @@ form.form-horizontal .control-label {
border: none;
color: #2c3e50;
background: #f1f4f6;
border-right: 1px solid rgba(0, 0, 0, 0.05);
border-right: 1px solid rgba(0, 0, 0, 0.02);
}
.nav-addtabs > li .close-tab {
font-size: 10px;
... ... @@ -385,13 +375,6 @@ form.form-horizontal .control-label {
.nav-addtabs li:hover > .close-tab {
display: block;
}
.multiplenav .content-wrapper,
.multiplenav .right-side {
padding-top: 94px;
}
.multiplenav #firstnav .nav-addtabs {
padding-right: 450px;
}
#firstnav {
height: 50px;
border-bottom: 1px solid transparent;
... ... @@ -420,6 +403,7 @@ form.form-horizontal .control-label {
}
/*次栏菜单栏*/
#secondnav {
display: none;
height: 44px;
position: absolute;
top: 50px;
... ... @@ -495,6 +479,20 @@ form.form-horizontal .control-label {
border-color: #222e32;
color: #222e32;
}
.multiplenav .content-wrapper,
.multiplenav .right-side {
padding-top: 50px;
}
.multiplenav #firstnav .nav-addtabs {
padding-right: 450px;
}
.multipletab #secondnav {
display: block;
}
.multipletab.multiplenav .content-wrapper,
.multipletab.multiplenav .right-side {
padding-top: 94px;
}
.main-sidebar .sidebar-form {
overflow: visible;
}
... ... @@ -541,7 +539,7 @@ form.form-horizontal .control-label {
}
@media (min-width: 768px) {
.sidebar-mini.sidebar-collapse .sidebar-menu > li:hover > .treeview-menu {
top: 41px;
top: 42px;
}
.sidebar-mini.sidebar-collapse .sidebar-menu > li:hover > a > .pull-right-container {
top: 7px !important;
... ... @@ -640,6 +638,9 @@ form.form-horizontal .control-label {
.fixed-table-container tbody .selected td {
background-color: rgba(216, 224, 230, 0.5);
}
.fixed-table-container .bs-checkbox {
min-width: 36px;
}
/*修复nice-validator新版下的一处BUG*/
.nice-validator input,
.nice-validator select,
... ... @@ -972,9 +973,7 @@ table.table-nowrap thead > tr > th {
}
/*平板样式*/
@media (max-width: 767px) {
body .wrapper .main-header .logo {
background: none;
color: #fff;
.wrapper .main-header .logo {
border-bottom: 0 solid transparent;
position: absolute;
top: 0;
... ... @@ -983,32 +982,32 @@ table.table-nowrap thead > tr > th {
left: 50%;
margin-left: -65px;
}
body .sidebar .mobilenav a.btn-app {
.sidebar .mobilenav a.btn-app {
color: #444;
width: 100px;
height: 70px;
font-size: 13px;
}
body .sidebar .mobilenav a.btn-app i.fa {
.sidebar .mobilenav a.btn-app i.fa {
font-size: 24px;
}
body .sidebar .mobilenav a.btn-app span {
.sidebar .mobilenav a.btn-app span {
margin-top: 5px;
display: block;
}
body .sidebar .mobilenav a.btn-app.active {
.sidebar .mobilenav a.btn-app.active {
color: #222d32;
}
body .wrapper .main-header .navbar .dropdown-menu li > a {
.wrapper .main-header .navbar .dropdown-menu li > a {
color: #333;
}
body .wrapper .main-header .navbar .dropdown-menu li > a:hover {
.wrapper .main-header .navbar .dropdown-menu li > a:hover {
background: #eee;
}
body .wrapper .main-header .navbar .dropdown-menu li.active > a {
.wrapper .main-header .navbar .dropdown-menu li.active > a {
color: #fff;
}
body .wrapper .main-header .navbar .dropdown-menu li.active > a:hover {
.wrapper .main-header .navbar .dropdown-menu li.active > a:hover {
background: #222d32;
}
.main-sidebar,
... ... @@ -1058,6 +1057,43 @@ table.table-nowrap thead > tr > th {
text-align: center;
display: inline-block;
}
.fixed-columns,
.fixed-columns-right {
position: absolute;
top: 0;
height: 100%;
min-height: 41px;
background-color: #fff;
box-sizing: border-box;
z-index: 1;
box-shadow: 0 -1px 8px rgba(0, 0, 0, 0.08);
}
.fixed-columns .fixed-table-body,
.fixed-columns-right .fixed-table-body {
min-height: 41px;
overflow-x: hidden !important;
}
.fixed-columns {
left: 0;
}
.fixed-columns-right {
right: 0;
box-shadow: -1px 0 8px rgba(0, 0, 0, 0.08);
}
.fix-sticky {
position: fixed;
z-index: 100;
}
.fix-sticky thead {
background: #fff;
}
.fix-sticky thead th,
.fix-sticky thead th:first-child {
border-left: 0;
border-right: 0;
border-bottom: 1px solid #eee;
border-radius: 0;
}
.sidebar-menu li.treeview-open > a > .fa-angle-left,
.sidebar-menu li.treeview-open > a > .pull-right-container > .fa-angle-left {
-webkit-transform: rotate(-90deg);
... ...
... ... @@ -4,8 +4,13 @@
@import url("../libs/font-awesome/css/font-awesome.min.css");
@import url("../libs/toastr/toastr.min.css");
@import url("../libs/fastadmin-layer/dist/theme/default/layer.css");
@import url("../libs/bootstrap-table/dist/bootstrap-table.min.css");
@import url("../libs/eonasdan-bootstrap-datetimepicker/build/css/bootstrap-datetimepicker.min.css");
@import url("../libs/bootstrap-daterangepicker/daterangepicker.css");
@import url("../libs/nice-validator/dist/jquery.validator.css");
@import url("../libs/bootstrap-select/dist/css/bootstrap-select.min.css");
@import url("../libs/fastadmin-selectpage/selectpage.css");
@import url("../libs/bootstrap-slider/slider.css");
html,
body {
height: 100%;
... ... @@ -13,6 +18,7 @@ body {
body {
padding-top: 50px;
font-size: 13px;
background: #f4f6f8;
}
.dropdown:hover .dropdown-menu {
display: block;
... ... @@ -24,6 +30,10 @@ body {
.navbar-nav > li > a {
font-size: 14px;
}
.navbar-nav ul.dropdown-menu > li > a {
padding: 5px 20px;
font-size: 13px;
}
.toast-top-center {
top: 50px;
}
... ... @@ -96,7 +106,10 @@ form.form-horizontal .control-label {
}
.panel-default {
padding: 0 15px;
border-color: #e4ecf3;
border: none;
-webkit-box-shadow: none;
-moz-box-shadow: none;
box-shadow: none;
}
.panel-default > .panel-heading {
position: relative;
... ... @@ -105,6 +118,14 @@ form.form-horizontal .control-label {
background: #fff;
border-bottom: 1px solid #f5f5f5;
}
.panel-default h2.page-header {
margin-top: 0;
height: 50px;
line-height: 31px;
font-size: 18px;
padding: 10px 0;
border-bottom: 1px solid #f5f5f5;
}
.panel-default > .panel-heading .panel-title {
color: #313131;
}
... ... @@ -316,7 +337,6 @@ footer.footer .copyright a:hover {
-moz-background-clip: padding;
border-radius: 4px;
background-clip: padding-box;
border: 1px solid #e4ecf3;
}
.login-section {
margin: 50px auto;
... ... @@ -342,7 +362,7 @@ footer.footer .copyright a:hover {
font-size: 16px;
text-align: center;
color: #616161;
background-color: #f5f5f5;
background-color: #ececec;
-webkit-transition: all 0.3s ease;
-moz-transition: all 0.3s ease;
-o-transition: all 0.3s ease;
... ... @@ -396,13 +416,6 @@ main.content {
padding: 20px 0 10px 0;
margin-bottom: 20px;
background-color: #fff;
-webkit-border-radius: 4px;
-webkit-background-clip: padding-box;
-moz-border-radius: 4px;
-moz-background-clip: padding;
border-radius: 4px;
background-clip: padding-box;
border: 1px solid #e4ecf3;
}
.sidenav .list-group:last-child {
margin-bottom: 0;
... ... @@ -435,7 +448,8 @@ main.content {
background-clip: padding-box;
}
.sidenav .list-group .list-group-item:hover {
background-color: #f5f5f5;
border-left: 2px solid rgba(245, 245, 245, 0.38);
background-color: rgba(245, 245, 245, 0.38);
}
.sidenav .list-group .list-group-item > a {
display: block;
... ... @@ -444,7 +458,7 @@ main.content {
}
.sidenav .list-group .list-group-item.active {
border-left: 2px solid #46c37b;
background: none;
background-color: rgba(245, 245, 245, 0.38);
}
.sidenav .list-group .list-group-item.active > a {
color: #46c37b;
... ...
... ... @@ -3,31 +3,37 @@ body {
height: 100%;
width: 100%;
}
body {
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
font-family: "Roboto", "SF Pro SC", "SF Pro Display", "SF Pro Icons", "PingFang SC", BlinkMacSystemFont, -apple-system, "Segoe UI", "Microsoft Yahei", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", "Helvetica", "Arial", sans-serif;
font-weight: 400;
}
a {
-webkit-transition: all 0.35s;
-moz-transition: all 0.35s;
transition: all 0.35s;
color: #fdcc52;
color: #474157;
}
a:hover,
a:focus {
color: #fcbd20;
color: #474157;
}
hr {
max-width: 100px;
margin: 25px auto 0;
border-width: 1px;
border-color: rgba(34, 34, 34, 0.1);
}
hr.light {
border-color: white;
}
h1,
h2,
h3,
... ... @@ -37,207 +43,161 @@ h6 {
font-weight: 200;
letter-spacing: 1px;
}
p {
font-size: 16px;
line-height: 1.5;
margin-bottom: 20px;
}
.navbar-default {
font-family: 'Catamaran', 'Helvetica', 'Arial', 'sans-serif';
font-weight: 200;
letter-spacing: 1px;
}
.navbar-default .navbar-header .navbar-brand {
font-family: 'Catamaran', 'Helvetica', 'Arial', 'sans-serif';
font-weight: 200;
letter-spacing: 1px;
color: #474157;
}
.navbar-default .navbar-header .navbar-brand:hover,
.navbar-default .navbar-header .navbar-brand:focus {
color: #fcbd20;
color: #474157;
}
.navbar-default .navbar-header .navbar-toggle {
font-size: 12px;
color: #222222;
color: #474157;
padding: 8px 10px;
}
.navbar-default .nav > li > a {
text-transform: uppercase;
letter-spacing: 2px;
font-size: 14px;
color: #7a798c;
}
.navbar-default .nav > li > a:hover,
.navbar-default .nav > li > a:focus:hover {
color: #fdcc52;
color: #474157;
}
.navbar-default .nav > li.active > a,
.navbar-default .nav > li.active > a:focus {
color: #fdcc52 !important;
color: #474157 !important;
background-color: transparent;
}
.navbar-default .nav > li.active > a:hover,
.navbar-default .nav > li.active > a:focus:hover {
background-color: transparent;
}
@media (min-width: 768px) {
.navbar-default {
background-color: transparent;
border-color: transparent;
}
.navbar-default .navbar-header .navbar-brand {
color: rgba(255, 255, 255, 0.7);
}
.navbar-default .navbar-header .navbar-brand:hover,
.navbar-default .navbar-header .navbar-brand:focus {
color: white;
}
.navbar-default .nav > li > a,
.navbar-default .nav > li > a:focus {
color: rgba(255, 255, 255, 0.7);
}
.navbar-default .nav > li > a:hover,
.navbar-default .nav > li > a:focus:hover {
color: white;
}
}
header {
#mainbody {
position: relative;
width: 100%;
min-height: auto;
overflow-y: hidden;
background: url("../img/bg-pattern.png"), #247cdc;
/* fallback for old browsers */
background: url("../img/bg-pattern.png"), -webkit-linear-gradient(to left, #328944, #247cdc);
/* Chrome 10-25, Safari 5.1-6 */
background: url("../img/bg-pattern.png"), linear-gradient(to left, #328944, #247cdc);
/* W3C, IE 10+/ Edge, Firefox 16+, Chrome 26+, Opera 12+, Safari 7+ */
color: white;
}
header .header-content {
text-align: center;
padding: 150px 0 50px;
position: relative;
background: #f1f6fd;
color: #474157;
height: calc(100vh - 61px);
}
header .header-content .header-content-inner {
#mainbody .index-text {
text-align: center;
padding: 250px 0 50px;
position: relative;
margin: 0 auto;
height: 100vh;
}
header .header-content .header-content-inner h1 {
margin-top: 0;
margin-bottom: 30px;
font-size: 80px;
}
header .header-content .header-content-inner .list-badges {
margin-bottom: 25px;
}
header .header-content .header-content-inner .list-badges img {
height: 50px;
margin-bottom: 25px;
#mainbody .index-text h1 {
font-size: 50px;
font-weight: bold;
color: #171347
}
header .device-container {
max-width: 300px;
margin: 0 auto 100px;
#mainbody .index-gallery {
text-align: center;
padding: 200px 0 50px;
position: relative;
}
header .device-container .screen img {
border-radius: 3px;
@media (max-height: 500px) {
#mainbody {
height: inherit;
}
}
@media (min-width: 768px) {
header {
min-height: 100%;
.navbar-default {
background-color: transparent;
border-color: transparent;
}
header .header-content {
text-align: center;
padding: 0;
height: 100vh;
#mainbody .index-text {
text-align: left;
}
header .header-content .header-content-inner {
width:100%;
margin: 0;
position: absolute;
top: 50%;
transform: translateY(-50%);
}
@media (max-width: 767px) {
.navbar-default {
background-color: #f1f6fd;
border-color: #f1f6fd;
}
header .header-content .header-content-inner h1 {
font-size: 35px;
.navbar-default .navbar-collapse {
background: #f1f6fd;
box-shadow: 5px 9px 5px rgba(0, 0, 0, 0.07);
}
header .device-container {
max-width: none;
max-height: calc(0vh);
margin: 100px auto 0;
#mainbody {
height: unset;
}
}
@media (min-width: 992px) {
header .header-content .header-content-inner h1 {
font-size: 80px;
#mainbody .index-text {
padding: 130px 0 0 0;
height: calc(100vh - 261px);
}
}
@media (max-width: 767px) {
header .header-content .header-content-inner h1 {
#mainbody .index-gallery {
padding: 30px 0 50px 0;
}
#mainbody .index-text h1 {
font-size: 50px;
margin-bottom: 20px;
}
}
section {
padding: 100px 0;
}
section h2 {
font-size: 50px;
}
footer {
background-color: #222222;
padding: 25px 0;
padding: 20px 0;
color: rgba(255, 255, 255, 0.3);
text-align: center;
}
footer p {
font-size: 12px;
font-size: 14px;
margin: 0;
}
footer ul {
margin-bottom: 0;
}
footer ul li a {
font-size: 12px;
color: rgba(255, 255, 255, 0.3);
}
footer ul li a:hover,
footer ul li a:focus,
footer ul li a:active,
footer ul li a.active {
text-decoration: none;
}
.bg-primary {
background: #fdcc52;
background: -webkit-linear-gradient(#fdcc52, #fdc539);
background: linear-gradient(#fdcc52, #fdc539);
}
.text-primary {
color: #fdcc52;
}
.no-gutter > [class*='col-'] {
padding-right: 0;
padding-left: 0;
}
.btn-outline {
color: white;
border-color: white;
border: 1px solid;
}
.btn-outline:hover,
.btn-outline:focus,
.btn-outline:active,
.btn-outline.active {
color: white;
background-color: #fdcc52;
border-color: #fdcc52;
}
.btn {
text-transform: uppercase;
letter-spacing: 2px;
border-radius: 300px;
}
.btn-xl {
margin-top:20px;
margin-top: 20px;
padding: 10px 45px;
font-size: 14px;
}
... ...