Compare commits

..

30 Commits

Author SHA1 Message Date
Karson c74b9dc24a 修复会员表结构字段
优化版本依赖
2024-09-06 11:05:48 +08:00
Karson 5188621e9c 优化语言包加载 2024-09-04 12:10:37 +08:00
Karson 7238632f14 更新版本号 2024-09-03 17:51:45 +08:00
Karson 4329b47c56 更新phpoffice/phpspreadsheet依赖版本 2024-09-03 17:48:46 +08:00
Karson 418d93f448 打包JS 2024-09-03 15:24:23 +08:00
Karson 8e88e1c9dc 优化格式化输出时文本编码
# Conflicts:
#	public/assets/js/require-table.js
2024-09-03 15:21:22 +08:00
Karson 592a42fcc5 优化后台参数传递 2024-09-03 15:17:29 +08:00
Simon a532001e7b 修复添加时,权重传值不生效 2024-09-03 15:15:44 +08:00
苏小马 9876dc22db update application/admin/command/Crud.php.
问题:删除模式时不需要强制读取数据表,如果在删除前已手动删除数据表,将抛出异常“table not found”导致删除失败

修复:增加删除模式判断,如果是删除模式,无需读取数据表

Signed-off-by: 苏小马 <179906767@qq.com>
2024-09-03 15:15:22 +08:00
AriFe.Liu 37c18d4e92 修复iframe打开窗口时链接内问号重复的问题
如果在添加菜单时, 在规则或URL中追加了 ? , 则会导致在刷新这个标签页时, 请求链接中使用了两个问号导致参数取出错误, 此处原本追加的?addtabs=1未做判断.

Signed-off-by: AriFe.Liu <88468560@qq.com>
2024-09-03 15:14:52 +08:00
AriFe.Liu 5c9c6ef89c 修复附件选择组件因没有id导致无法响应事件的bug
该问题曾导致附件选择组件在没有添加ID时造成无法正常响应回调事件
官方文档: https://doc.fastadmin.net/doc/183.html 附件选择 中, 示例及文档均未提及添加了faselect的组件必须添加id
如非bug而有意为之, 请修改官方文档说明, 告知用户添加了faselect的标签必须同时添加ID才能正确处理回调.
2024-09-03 15:14:52 +08:00
Karson 03ccce86f0 修复autocomplete选中后未触发验证的问题
修复Table.api.formatter.file无法渲染的问题
2024-09-03 15:10:11 +08:00
小和 18a661fb22 !465 修改字段错误问题
* 修复字段错误
2024-09-03 15:09:46 +08:00
AriFe.Liu c01628a914 修复sidebar左侧菜单因大小写问题导致的菜单列表不能正确显示问题
当手动添加菜单规则时, 规则字段未提示和处理用户录入的字符
在application/admin/library/Auth.php -> getSidebar方法中, 会对当前用户所拥有的权限节点做校验移除不相关的权限
当判断当前菜单规则是否在$userRule中时, 原本的$v['name']为直接从数据库中取出未做处理, $userRule则是通过$this->getRuleList方法获取, 方法内已经对字符串做了转小写处理, 假如用户填写了大小写混合的规则, 则此处将会被错误的移除掉; 导致左侧菜单无法正常展示该菜单规则;

Signed-off-by: AriFe.Liu <88468560@qq.com>
2024-09-03 15:08:20 +08:00
Karson 996fa27d62 优化数据表结构 2024-09-03 15:05:53 +08:00
Karson b13a1ca7b5 优化冗余参数 2024-09-03 10:53:19 +08:00
Karson c78b3aecc5 优化API资源URL 2024-09-03 10:53:19 +08:00
Karson 54d6e0904b 优化安装脚本资源加载 2024-09-03 10:53:19 +08:00
Karson 6d4aaf5ea8 优化邮箱验证码发送参数验证
# Conflicts:
#	application/api/controller/Ems.php
2024-09-03 10:50:29 +08:00
Karson 4a97bdaf19 Merge branch '1.x' of gitee.com:karson/fastadmin into 1.x 2024-09-03 10:28:37 +08:00
Karson 028a0b5f22 Fieldlist新增使用数组保存和保留空数据选项 2024-09-03 10:27:56 +08:00
Karson 7f54960449 优化PHP版本依赖 2024-09-03 10:27:24 +08:00
Karson e7c1922cf3 优化前台会员登录 2024-09-03 10:23:19 +08:00
Karson c5285b8fdd 优化多语言加载 2024-09-03 10:22:34 +08:00
Karson 5400c6ff2a 优化视图变量输出 2024-09-03 10:20:59 +08:00
建伟F4nniu 090381a1a2
!462 按照注释规则修改API模块下控制器方法的注解
Merge pull request !462 from Henry/fix_phpdoc
2024-07-03 08:03:46 +00:00
Karson 8f7a55928c 修复列表多个分组按钮显示优化 2024-04-01 15:08:03 +08:00
Karson e8a804afad 优化后台编辑默认加载模型 2024-03-28 12:03:14 +08:00
Henry ee0be09841 style: 去掉多余的空格 2024-02-26 22:34:06 +08:00
Henry c8c1573c27 docs: 按照注释规则修改API模块下控制器方法的注解 2024-02-26 22:22:59 +08:00
38 changed files with 259 additions and 170 deletions

View File

@ -24,12 +24,10 @@ FastAdmin是一款基于ThinkPHP+Bootstrap的极速后台开发框架。
* 多语言支持,服务端及客户端支持
* 支持大文件分片上传、剪切板粘贴上传、拖拽上传,进度条显示,图片上传前压缩
* 支持表格固定列、固定表头、跨页选择、Excel导出、模板渲染等功能
* 强大的第三方应用模块支持([CMS](https://www.fastadmin.net/store/cms.html)、[博客](https://www.fastadmin.net/store/blog.html)、[知识付费问答](https://www.fastadmin.net/store/ask.html)、[在线投票系统](https://www.fastadmin.net/store/vote.html)、[B2C商城](https://www.fastadmin.net/store/shopro.html)、[B2B2C商城](https://www.fastadmin.net/store/wanlshop.html))
* 支持CMS、博客、知识付费问答无缝整合[Xunsearch全文搜索](https://www.fastadmin.net/store/xunsearch.html)
* 第三方小程序支持([CMS小程序](https://www.fastadmin.net/store/cms.html)、[预订小程序](https://www.fastadmin.net/store/ball.html)、[问答小程序](https://www.fastadmin.net/store/ask.html)、[点餐小程序](https://www.fastadmin.net/store/unidrink.html)、[B2C小程序](https://www.fastadmin.net/store/shopro.html)、[B2B2C小程序](https://www.fastadmin.net/store/wanlshop.html)、[博客小程序](https://www.fastadmin.net/store/blog.html))
* 强大的第三方应用模块支持([CMS](https://www.fastadmin.net/store/cms.html)、[CRM](https://www.fastadmin.net/store/facrm.html)、[企业网站管理系统](https://www.fastadmin.net/store/ldcms.html)、[知识库文档系统](https://www.fastadmin.net/store/knowbase.html)、[在线投票系统](https://www.fastadmin.net/store/vote.html)、[B2C商城](https://www.fastadmin.net/store/shopro.html)、[B2B2C商城](https://www.fastadmin.net/store/wanlshop.html))
* 整合第三方短信接口(阿里云、腾讯云短信)
* 无缝整合第三方云存储(七牛云、阿里云OSS、又拍云)功能,支持云储存分片上传
* 第三方富文本编辑器支持(Summernote、Kindeditor、百度编辑器)
* 无缝整合第三方云存储(七牛云、阿里云OSS、腾讯云存储、又拍云)功能,支持云储存分片上传
* 第三方富文本编辑器支持(Summernote、百度编辑器)
* 第三方登录(QQ、微信、微博)整合
* 第三方支付(微信、支付宝)无缝整合微信支持PC端扫码支付
* 丰富的插件应用市场
@ -55,8 +53,7 @@ https://demo.fastadmin.net
在使用中有任何问题,请使用以下联系方式联系我们
交流社区: https://ask.fastadmin.net
问答社区: https://ask.fastadmin.net
Github: https://github.com/karsonzhang/fastadmin

View File

@ -8,15 +8,15 @@
<title>{$config.title}</title>
<!-- Bootstrap Core CSS -->
<link href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
<link href="https://lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/twitter-bootstrap/3.4.1/css/bootstrap.min.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://lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/font-awesome/4.7.0/css/font-awesome.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>
<script src="https://cdn.staticfile.org/respond.js/1.4.2/respond.min.js"></script>
<script src="https://lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/html5shiv/3.7.3/html5shiv.min.js"></script>
<script src="https://lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/respond.js/1.4.2/respond.min.js"></script>
<![endif]-->
<style type="text/css">
@ -401,10 +401,10 @@
</div> <!-- /container -->
<!-- jQuery -->
<script src="https://cdn.staticfile.org/jquery/2.1.4/jquery.min.js"></script>
<script src="https://lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/jquery/3.6.0/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="https://lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
<script type="text/javascript">
function syntaxHighlight(json) {

View File

@ -435,16 +435,19 @@ class Crud extends Command
$modelName = $table = stripos($table, $prefix) === 0 ? substr($table, strlen($prefix)) : $table;
$modelTableType = 'table';
$modelTableTypeName = $modelTableName = $modelName;
$modelTableInfo = $dbconnect->query("SHOW TABLE STATUS LIKE '{$modelTableName}'", [], true);
if (!$modelTableInfo) {
$modelTableType = 'name';
$modelTableName = $prefix . $modelName;
$modelTableInfo = null;
if (!$input->getOption('delete')) {
$modelTableInfo = $dbconnect->query("SHOW TABLE STATUS LIKE '{$modelTableName}'", [], true);
if (!$modelTableInfo) {
throw new Exception("table not found");
$modelTableType = 'name';
$modelTableName = $prefix . $modelName;
$modelTableInfo = $dbconnect->query("SHOW TABLE STATUS LIKE '{$modelTableName}'", [], true);
if (!$modelTableInfo) {
throw new Exception("table not found");
}
}
$modelTableInfo = $modelTableInfo[0];
}
$modelTableInfo = $modelTableInfo[0];
$relations = [];
//检查关联表
@ -1081,7 +1084,7 @@ class Crud extends Command
}
//表注释
$tableComment = $modelTableInfo['Comment'];
$tableComment = $modelTableInfo ? $modelTableInfo['Comment'] : '';
$tableComment = mb_substr($tableComment, -1) == '表' ? mb_substr($tableComment, 0, -1) . '管理' : $tableComment;
$modelInit = '';

View File

@ -2,7 +2,9 @@
protected static function init()
{
self::afterInsert(function ($row) {
$pk = $row->getPk();
$row->getQuery()->where($pk, $row[$pk])->update(['{%order%}' => $row[$pk]]);
if (!$row['{%order%}']) {
$pk = $row->getPk();
$row->getQuery()->where($pk, $row[$pk])->update(['{%order%}' => $row[$pk]]);
}
});
}

View File

@ -70,7 +70,7 @@ class Install extends Command
$adminName = $this->installation($hostname, $hostport, $database, $username, $password, $prefix, $adminUsername, $adminPassword, $adminEmail, $siteName);
if ($adminName) {
$output->highlight("Admin url:http://www.yoursite.com/{$adminName}");
$output->highlight("Admin url:http://www.example.com/{$adminName}");
}
$output->highlight("Admin username:{$adminUsername}");
@ -86,7 +86,7 @@ class Install extends Command
*/
public function index()
{
$this->view = View::instance(Config::get('template'), Config::get('view_replace_str'));
$this->view = View::instance(array_merge(Config::get('template'), ['tpl_cache' => false]));
$this->request = Request::instance();
define('INSTALL_PATH', APP_PATH . 'admin' . DS . 'command' . DS . 'Install' . DS);
@ -309,8 +309,8 @@ class Install extends Command
//数据库配置文件
$dbConfigFile = APP_PATH . 'database.php';
if (version_compare(PHP_VERSION, '7.2.0', '<')) {
throw new Exception(__("The current version %s is too low, please use PHP 7.2 or higher", PHP_VERSION));
if (version_compare(PHP_VERSION, '7.4.0', '<')) {
throw new Exception(__("The current version %s is too low, please use PHP 7.4 or higher", PHP_VERSION));
}
if (!extension_loaded("PDO")) {
throw new Exception(__("PDO is not currently installed and cannot be installed"));

View File

@ -1,6 +1,6 @@
/*
FastAdmin Install SQL
Date: 2023-06-07 15:17:57
Date: 2024-09-03 15:05:25
*/
SET FOREIGN_KEY_CHECKS = 0;
@ -32,7 +32,7 @@ CREATE TABLE `fa_admin` (
-- Records of fa_admin
-- ----------------------------
BEGIN;
INSERT INTO `fa_admin` VALUES (1, 'admin', 'Admin', '', '', '/assets/img/avatar.png', 'admin@admin.com', '', 0, 1491635035, '127.0.0.1',1491635035, 1491635035, '', 'normal');
INSERT INTO `fa_admin` VALUES (1, 'admin', 'Admin', '', '', '/assets/img/avatar.png', 'admin@example.com', '', 0, 1491635035, '127.0.0.1',1491635035, 1491635035, '', 'normal');
COMMIT;
-- ----------------------------
@ -81,8 +81,8 @@ CREATE TABLE `fa_attachment` (
`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) DEFAULT '' COMMENT '物理路径',
`imagewidth` varchar(30) DEFAULT '' COMMENT '宽度',
`imageheight` varchar(30) DEFAULT '' COMMENT '高度',
`imagewidth` int(10) unsigned DEFAULT 0 COMMENT '宽度',
`imageheight` int(10) unsigned DEFAULT 0 COMMENT '高度',
`imagetype` varchar(30) DEFAULT '' COMMENT '图片类型',
`imageframes` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '图片帧数',
`filename` varchar(100) DEFAULT '' COMMENT '文件名称',
@ -452,6 +452,7 @@ CREATE TABLE `fa_user` (
`logintime` bigint(16) DEFAULT NULL COMMENT '登录时间',
`loginip` varchar(50) DEFAULT '' COMMENT '登录IP',
`loginfailure` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT '失败次数',
`loginfailuretime` bigint(16) DEFAULT NULL COMMENT '最后登录失败时间',
`joinip` varchar(50) DEFAULT '' COMMENT '加入IP',
`jointime` bigint(16) DEFAULT NULL COMMENT '加入时间',
`createtime` bigint(16) DEFAULT NULL COMMENT '创建时间',
@ -469,7 +470,7 @@ CREATE TABLE `fa_user` (
-- Records of fa_user
-- ----------------------------
BEGIN;
INSERT INTO `fa_user` VALUES (1, 1, 'admin', 'admin', '', '', 'admin@163.com', '13000000000', '', 0, 0, '2017-04-08', '', 0, 0, 1, 1, 1491635035, 1491635035, '127.0.0.1', 0, '127.0.0.1', 1491635035, 0, 1491635035, '', 'normal','');
INSERT INTO `fa_user` VALUES (1, 1, 'admin', 'admin', '', '', 'admin@163.com', '13000000000', '', 0, 0, '2017-04-08', '', 0, 0, 1, 1, 1491635035, 1491635035, '127.0.0.1', 0, 1491635035,'127.0.0.1', 1491635035, 0, 1491635035, '', 'normal','');
COMMIT;
-- ----------------------------

View File

@ -254,7 +254,7 @@
</form>
<!-- jQuery -->
<script src="https://cdn.staticfile.org/jquery/2.1.4/jquery.min.js"></script>
<script src="__ROOT__/assets/libs/jquery/dist/jquery.min.js"></script>
<script>
$(function () {

View File

@ -20,14 +20,14 @@ return [
'Dashboard' => '进入后台',
'Go back' => '返回上一页',
'Install Successed' => '安装成功!',
'Security tips' => '温馨提示:请将以下后台登录入口添加到你的收藏夹,为了你的安全,不要泄漏或发送给他人!如有泄漏请及时修改!',
'Security tips' => '温馨提示:请将以下后台登录入口添加到你的收藏夹,为了你的站点安全,不要泄漏或发送给他人!如有泄漏请及时修改!',
'Please input correct database' => '请输入正确的数据库名',
'Please input correct username' => '用户名只能由3-30位数字、字母、下划线组合',
'Please input correct password' => '密码长度必须在6-30位之间不能包含空格',
'Password is too weak' => '密码太简单,请重新输入',
'The two passwords you entered did not match' => '两次输入的密码不一致',
'Please input correct website' => '网站名称输入不正确',
'The current version %s is too low, please use PHP 7.1 or higher' => '当前版本%s过低请使用PHP7.1以上版本',
'The current version %s is too low, please use PHP 7.4 or higher' => '当前版本%s过低请使用PHP7.4及以上版本',
'PDO is not currently installed and cannot be installed' => '当前未开启PDO无法进行安装',
'The current permissions are insufficient to write the file %s' => '当前权限不足,无法写入文件%s',
'Please go to the official website to download the full package or resource package and try to install' => '当前代码仅包含核心代码,请前往官网下载完整包或资源包覆盖后再尝试安装',

View File

@ -11,6 +11,7 @@ use think\Cache;
use think\Config;
use think\Db;
use think\Lang;
use think\Loader;
use think\Response;
use think\Validate;
@ -47,9 +48,20 @@ class Ajax extends Backend
$header['Expires'] = gmdate("D, d M Y H:i:s", time() + $offset) . " GMT";
}
$controllername = $this->request->get('controllername');
$lang = $this->request->get('lang');
if (!$lang || !in_array($lang, config('allow_lang_list')) || !$controllername || !preg_match("/^[a-z0-9_\.]+$/i", $controllername)) {
return jsonp(['errmsg' => '参数错误'], 200, [], ['json_encode_param' => JSON_FORCE_OBJECT | JSON_UNESCAPED_UNICODE]);
}
$controllername = input("controllername");
//默认只加载了控制器对应的语言名,你还根据控制器名来加载额外的语言包
$this->loadlang($controllername);
$className = Loader::parseClass($this->request->module(), 'controller', $controllername, false);
//存在对应的类才加载
if (class_exists($className)) {
$this->loadlang($controllername);
}
return jsonp(Lang::get(), 200, $header, ['json_encode_param' => JSON_FORCE_OBJECT | JSON_UNESCAPED_UNICODE]);
}

View File

@ -24,7 +24,7 @@ class User extends Backend
public function _initialize()
{
parent::_initialize();
$this->model = model('User');
$this->model = new \app\admin\model\User;
}
/**

View File

@ -2,7 +2,7 @@
return [
'Url' => '链接',
'Userame' => '用户名',
'Username' => '用户名',
'Createtime' => '操作时间',
'Click to edit' => '点击编辑',
'Admin log' => '操作日志',

View File

@ -472,7 +472,7 @@ class Auth extends \fast\Auth
->column('name,pid');
$pidArr = array_unique(array_filter(array_column($ruleList, 'pid')));
foreach ($ruleList as $k => &$v) {
if (!in_array($v['name'], $userRule)) {
if (!in_array(strtolower($v['name']), $userRule)) {
unset($ruleList[$k]);
continue;
}

View File

@ -23,8 +23,10 @@ class UserRule extends Model
protected static function init()
{
self::afterInsert(function ($row) {
$pk = $row->getPk();
$row->getQuery()->where($pk, $row[$pk])->update(['weigh' => $row[$pk]]);
if (!$row['weigh']) {
$pk = $row->getPk();
$row->getQuery()->where($pk, $row[$pk])->update(['weigh' => $row[$pk]]);
}
});
}

View File

@ -39,7 +39,7 @@
<div class="form-group">
<label for="loginfailure" class="control-label col-xs-12 col-sm-2">{:__('Loginfailure')}:</label>
<div class="col-xs-12 col-sm-8">
<input type="number" class="form-control" id="loginfailure" name="row[loginfailure]" value="{$row.loginfailure}" data-rule="required" />
<input type="number" class="form-control" id="loginfailure" name="row[loginfailure]" value="{$row.loginfailure|htmlentities}" data-rule="required" />
</div>
</div>
<div class="form-group">

View File

@ -34,8 +34,8 @@
<label for="icon" class="control-label col-xs-12 col-sm-2">{:__('Icon')}:</label>
<div class="col-xs-12 col-sm-8">
<div class="input-group input-groupp-md">
<span class="input-group-addon"><i class="{$row.icon}" id="icon-style"></i></span>
<input type="text" class="form-control" id="icon" name="row[icon]" value="{$row.icon}" />
<span class="input-group-addon"><i class="{$row.icon|htmlentities}" id="icon-style"></i></span>
<input type="text" class="form-control" id="icon" name="row[icon]" value="{$row.icon|htmlentities}" />
<a href="javascript:;" class="btn-search-icon input-group-addon">{:__('Search icon')}</a>
</div>
</div>
@ -67,7 +67,7 @@
<div class="form-group">
<label for="weigh" class="control-label col-xs-12 col-sm-2">{:__('Weigh')}:</label>
<div class="col-xs-12 col-sm-8">
<input type="text" class="form-control" id="weigh" name="row[weigh]" value="{$row.weigh}" data-rule="required" />
<input type="text" class="form-control" id="weigh" name="row[weigh]" value="{$row.weigh|htmlentities}" data-rule="required" />
</div>
</div>
<div class="form-group">

View File

@ -52,7 +52,7 @@
<label for="c-image" class="control-label col-xs-12 col-sm-2">{:__('Image')}:</label>
<div class="col-xs-12 col-sm-8">
<div class="input-group">
<input id="c-image" class="form-control" size="35" name="row[image]" type="text" value="{$row.image}">
<input id="c-image" class="form-control" size="35" name="row[image]" type="text" value="{$row.image|htmlentities}">
<div class="input-group-addon no-border no-padding">
<span><button type="button" id="faupload-image" class="btn btn-danger faupload" data-input-id="c-image" data-mimetype="image/gif,image/jpeg,image/png,image/jpg,image/bmp" data-multiple="false" data-preview-id="p-image"><i class="fa fa-upload"></i> {:__('Upload')}</button></span>
<span><button type="button" id="fachoose-image" class="btn btn-primary fachoose" data-input-id="c-image" data-mimetype="image/*" data-multiple="false"><i class="fa fa-list"></i> {:__('Choose')}</button></span>
@ -77,7 +77,7 @@
<div class="form-group">
<label for="c-weigh" class="control-label col-xs-12 col-sm-2">{:__('Weigh')}:</label>
<div class="col-xs-12 col-sm-8">
<input id="c-weigh" class="form-control" name="row[weigh]" type="number" value="{$row.weigh}">
<input id="c-weigh" class="form-control" name="row[weigh]" type="number" value="{$row.weigh|htmlentities}">
</div>
</div>
<div class="form-group">

View File

@ -22,13 +22,13 @@
<div class="form-group">
<label for="c-imagewidth" class="control-label col-xs-12 col-sm-2">{:__('Imagewidth')}:</label>
<div class="col-xs-12 col-sm-8">
<input type="text" name="row[imagewidth]" value="{$row.imagewidth}" id="c-imagewidth" class="form-control" required />
<input type="text" name="row[imagewidth]" value="{$row.imagewidth|htmlentities}" id="c-imagewidth" class="form-control" required />
</div>
</div>
<div class="form-group">
<label for="c-imageheight" class="control-label col-xs-12 col-sm-2">{:__('Imageheight')}:</label>
<div class="col-xs-12 col-sm-8">
<input type="text" name="row[imageheight]" value="{$row.imageheight}" id="c-imageheight" class="form-control" required />
<input type="text" name="row[imageheight]" value="{$row.imageheight|htmlentities}" id="c-imageheight" class="form-control" required />
</div>
</div>
<div class="form-group">
@ -40,7 +40,7 @@
<div class="form-group">
<label for="c-imageframes" class="control-label col-xs-12 col-sm-2">{:__('Imageframes')}:</label>
<div class="col-xs-12 col-sm-8">
<input type="number" name="row[imageframes]" value="{$row.imageframes}" id="c-imageframes" class="form-control" />
<input type="number" name="row[imageframes]" value="{$row.imageframes|htmlentities}" id="c-imageframes" class="form-control" />
</div>
</div>
<div class="form-group">
@ -52,7 +52,7 @@
<div class="form-group">
<label for="c-filesize" class="control-label col-xs-12 col-sm-2">{:__('Filesize')}:</label>
<div class="col-xs-12 col-sm-8">
<input type="number" name="row[filesize]" value="{$row.filesize}" id="c-filesize" class="form-control" />
<input type="number" name="row[filesize]" value="{$row.filesize|htmlentities}" id="c-filesize" class="form-control" />
</div>
</div>
<div class="form-group">
@ -76,7 +76,7 @@
<div class="form-group">
<label for="c-storage" class="control-label col-xs-12 col-sm-2">{:__('Storage')}:</label>
<div class="col-xs-12 col-sm-8">
<input type="text" name="row[storage]" value="{$row.storage}" id="c-storage" class="form-control" />
<input type="text" name="row[storage]" value="{$row.storage|htmlentities}" id="c-storage" class="form-control" />
</div>
</div>
<div class="form-group hide layer-footer">

View File

@ -28,12 +28,12 @@
<div class="content-wrapper tab-content tab-addtabs">
{if $fixedmenu}
<div role="tabpanel" class="tab-pane {:$referermenu?'':'active'}" id="con_{$fixedmenu.id}">
<iframe src="{$fixedmenu.url}?addtabs=1" width="100%" height="100%" frameborder="no" border="0" marginwidth="0" marginheight="0" scrolling-x="no" scrolling-y="auto" allowtransparency="yes"></iframe>
<iframe src="{$fixedmenu.url}{:stripos($fixedmenu.url, '?') !== false ? '&' : '?'}addtabs=1" width="100%" height="100%" frameborder="no" border="0" marginwidth="0" marginheight="0" scrolling-x="no" scrolling-y="auto" allowtransparency="yes"></iframe>
</div>
{/if}
{if $referermenu}
<div role="tabpanel" class="tab-pane active" id="con_{$referermenu.id}">
<iframe src="{$referermenu.url}?addtabs=1" width="100%" height="100%" frameborder="no" border="0" marginwidth="0" marginheight="0" scrolling-x="no" scrolling-y="auto" allowtransparency="yes"></iframe>
<iframe src="{$referermenu.url}{:stripos($referermenu.url, '?') !== false ? '&' : '?'}addtabs=1" width="100%" height="100%" frameborder="no" border="0" marginwidth="0" marginheight="0" scrolling-x="no" scrolling-y="auto" allowtransparency="yes"></iframe>
</div>
{/if}
</div>

View File

@ -1,6 +1,6 @@
<form id="edit-form" class="form-horizontal" role="form" data-toggle="validator" method="POST" action="">
{:token()}
<input type="hidden" name="row[rules]" value="{$row.rules}" />
<input type="hidden" name="row[rules]" value="{$row.rules|htmlentities}" />
<div class="form-group">
<label for="c-name" class="control-label col-xs-12 col-sm-2">{:__('Name')}:</label>
<div class="col-xs-12 col-sm-8">

View File

@ -33,7 +33,7 @@
<div class="form-group">
<label for="c-weigh" class="control-label col-xs-12 col-sm-2">{:__('Weigh')}:</label>
<div class="col-xs-12 col-sm-8">
<input id="c-weigh" class="form-control" name="row[weigh]" type="number" value="{$row.weigh}">
<input id="c-weigh" class="form-control" name="row[weigh]" type="number" value="{$row.weigh|htmlentities}">
</div>
</div>
<div class="form-group">

View File

@ -1,6 +1,6 @@
<form id="edit-form" class="form-horizontal" role="form" data-toggle="validator" method="POST" action="">
{:token()}
<input type="hidden" name="row[id]" value="{$row.id}">
<input type="hidden" name="row[id]" value="{$row.id|htmlentities}">
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Group')}:</label>
<div class="col-xs-12 col-sm-4">
@ -41,7 +41,7 @@
<label for="c-avatar" class="control-label col-xs-12 col-sm-2">{:__('Avatar')}:</label>
<div class="col-xs-12 col-sm-8">
<div class="input-group">
<input id="c-avatar" data-rule="" class="form-control" size="50" name="row[avatar]" type="text" value="{$row.avatar}">
<input id="c-avatar" data-rule="" class="form-control" size="50" name="row[avatar]" type="text" value="{$row.avatar|htmlentities}">
<div class="input-group-addon no-border no-padding">
<span><button type="button" id="faupload-avatar" class="btn btn-danger faupload" data-input-id="c-avatar" data-mimetype="image/gif,image/jpeg,image/png,image/jpg,image/bmp" data-multiple="false" data-preview-id="p-avatar"><i class="fa fa-upload"></i> {:__('Upload')}</button></span>
<span><button type="button" id="fachoose-avatar" class="btn btn-primary fachoose" data-input-id="c-avatar" data-mimetype="image/*" data-multiple="false"><i class="fa fa-list"></i> {:__('Choose')}</button></span>
@ -54,7 +54,7 @@
<div class="form-group">
<label for="c-level" class="control-label col-xs-12 col-sm-2">{:__('Level')}:</label>
<div class="col-xs-12 col-sm-4">
<input id="c-level" data-rule="required" class="form-control" name="row[level]" type="number" value="{$row.level}">
<input id="c-level" data-rule="required" class="form-control" name="row[level]" type="number" value="{$row.level|htmlentities}">
</div>
</div>
<div class="form-group">
@ -66,7 +66,7 @@
<div class="form-group">
<label for="c-birthday" class="control-label col-xs-12 col-sm-2">{:__('Birthday')}:</label>
<div class="col-xs-12 col-sm-4">
<input id="c-birthday" data-rule="" class="form-control datetimepicker" data-date-format="YYYY-MM-DD" data-use-current="true" name="row[birthday]" type="text" value="{$row.birthday}">
<input id="c-birthday" data-rule="" class="form-control datetimepicker" data-date-format="YYYY-MM-DD" data-use-current="true" name="row[birthday]" type="text" value="{$row.birthday|htmlentities}">
</div>
</div>
<div class="form-group">
@ -78,25 +78,25 @@
<div class="form-group">
<label for="c-money" class="control-label col-xs-12 col-sm-2">{:__('Money')}:</label>
<div class="col-xs-12 col-sm-4">
<input id="c-money" data-rule="required" class="form-control" name="row[money]" type="number" value="{$row.money}">
<input id="c-money" data-rule="required" class="form-control" name="row[money]" type="number" value="{$row.money|htmlentities}">
</div>
</div>
<div class="form-group">
<label for="c-score" class="control-label col-xs-12 col-sm-2">{:__('Score')}:</label>
<div class="col-xs-12 col-sm-4">
<input id="c-score" data-rule="required" class="form-control" name="row[score]" type="number" value="{$row.score}">
<input id="c-score" data-rule="required" class="form-control" name="row[score]" type="number" value="{$row.score|htmlentities}">
</div>
</div>
<div class="form-group">
<label for="c-successions" class="control-label col-xs-12 col-sm-2">{:__('Successions')}:</label>
<div class="col-xs-12 col-sm-4">
<input id="c-successions" data-rule="required" class="form-control" name="row[successions]" type="number" value="{$row.successions}">
<input id="c-successions" data-rule="required" class="form-control" name="row[successions]" type="number" value="{$row.successions|htmlentities}">
</div>
</div>
<div class="form-group">
<label for="c-maxsuccessions" class="control-label col-xs-12 col-sm-2">{:__('Maxsuccessions')}:</label>
<div class="col-xs-12 col-sm-4">
<input id="c-maxsuccessions" data-rule="required" class="form-control" name="row[maxsuccessions]" type="number" value="{$row.maxsuccessions}">
<input id="c-maxsuccessions" data-rule="required" class="form-control" name="row[maxsuccessions]" type="number" value="{$row.maxsuccessions|htmlentities}">
</div>
</div>
<div class="form-group">
@ -114,19 +114,19 @@
<div class="form-group">
<label for="c-loginip" class="control-label col-xs-12 col-sm-2">{:__('Loginip')}:</label>
<div class="col-xs-12 col-sm-4">
<input id="c-loginip" data-rule="required" class="form-control" name="row[loginip]" type="text" value="{$row.loginip}">
<input id="c-loginip" data-rule="required" class="form-control" name="row[loginip]" type="text" value="{$row.loginip|htmlentities}">
</div>
</div>
<div class="form-group">
<label for="c-loginfailure" class="control-label col-xs-12 col-sm-2">{:__('Loginfailure')}:</label>
<div class="col-xs-12 col-sm-4">
<input id="c-loginfailure" data-rule="required" class="form-control" name="row[loginfailure]" type="number" value="{$row.loginfailure}">
<input id="c-loginfailure" data-rule="required" class="form-control" name="row[loginfailure]" type="number" value="{$row.loginfailure|htmlentities}">
</div>
</div>
<div class="form-group">
<label for="c-joinip" class="control-label col-xs-12 col-sm-2">{:__('Joinip')}:</label>
<div class="col-xs-12 col-sm-4">
<input id="c-joinip" data-rule="required" class="form-control" name="row[joinip]" type="text" value="{$row.joinip}">
<input id="c-joinip" data-rule="required" class="form-control" name="row[joinip]" type="text" value="{$row.joinip|htmlentities}">
</div>
</div>
<div class="form-group">

View File

@ -38,9 +38,9 @@ class Common extends Api
/**
* 加载初始化
*
* @param string $version 版本号
* @param string $lng 经度
* @param string $lat 纬度
* @ApiParams (name="version", type="string", required=true, description="版本号")
* @ApiParams (name="lng", type="string", required=true, description="经度")
* @ApiParams (name="lat", type="string", required=true, description="纬度")
*/
public function init()
{
@ -80,7 +80,7 @@ class Common extends Api
/**
* 上传文件
* @ApiMethod (POST)
* @param File $file 文件流
* @ApiParams (name="file", type="File", required=true, description="文件流")
*/
public function upload()
{
@ -148,7 +148,7 @@ class Common extends Api
/**
* 验证码
* @param $id
* @ApiParams (name="id", type="string", required=true, description="要生成验证码的标识")
* @return \think\Response
*/
public function captcha($id = "")

View File

@ -24,8 +24,8 @@ class Ems extends Api
* 发送验证码
*
* @ApiMethod (POST)
* @param string $email 邮箱
* @param string $event 事件名称
* @ApiParams (name="email", type="string", required=true, description="邮箱")
* @ApiParams (name="event", type="string", required=true, description="事件名称")
*/
public function send()
{
@ -33,6 +33,25 @@ class Ems extends Api
$event = $this->request->post("event");
$event = $event ? $event : 'register';
if (!$email || !filter_var($email, FILTER_VALIDATE_EMAIL)) {
$this->error(__('邮箱格式错误'));
}
if (!preg_match("/^[a-z0-9_\-]{3,30}\$/i", $event)) {
$this->error(__('事件名称错误'));
}
//发送前验证码
if (config('fastadmin.user_api_captcha')) {
if (!preg_match("/^[a-z0-9]{4,6}\$/i", $captcha)) {
$this->error(__('验证码格式错误'));
}
if (!\think\Validate::is($captcha, 'captcha')) {
$this->error("验证码不正确");
}
}
$last = Emslib::get($email, $event);
if ($last && time() - $last['createtime'] < 60) {
$this->error(__('发送频繁'));
@ -68,9 +87,9 @@ class Ems extends Api
* 检测验证码
*
* @ApiMethod (POST)
* @param string $email 邮箱
* @param string $event 事件名称
* @param string $captcha 验证码
* @ApiParams (name="email", type="string", required=true, description="邮箱")
* @ApiParams (name="event", type="string", required=true, description="事件名称")
* @ApiParams (name="captcha", type="string", required=true, description="验证码")
*/
public function check()
{
@ -79,6 +98,17 @@ class Ems extends Api
$event = $event ? $event : 'register';
$captcha = $this->request->post("captcha");
if (!$email || !filter_var($email, FILTER_VALIDATE_EMAIL)) {
$this->error(__('邮箱格式错误'));
}
if (!preg_match("/^[a-z0-9_\-]{3,30}\$/i", $event)) {
$this->error(__('事件名称错误'));
}
if (!preg_match("/^[a-z0-9]{4,6}\$/i", $captcha)) {
$this->error(__('验证码格式错误'));
}
if ($event) {
$userinfo = User::getByEmail($email);
if ($event == 'register' && $userinfo) {

View File

@ -19,8 +19,8 @@ class Sms extends Api
* 发送验证码
*
* @ApiMethod (POST)
* @param string $mobile 手机号
* @param string $event 事件名称
* @ApiParams (name="mobile", type="string", required=true, description="手机号")
* @ApiParams (name="event", type="string", required=true, description="事件名称")
*/
public function send()
{
@ -67,9 +67,9 @@ class Sms extends Api
* 检测验证码
*
* @ApiMethod (POST)
* @param string $mobile 手机号
* @param string $event 事件名称
* @param string $captcha 验证码
* @ApiParams (name="mobile", type="string", required=true, description="手机号")
* @ApiParams (name="event", type="string", required=true, description="事件名称")
* @ApiParams (name="captcha", type="string", required=true, description="验证码")
*/
public function check()
{

View File

@ -39,8 +39,8 @@ class User extends Api
* 会员登录
*
* @ApiMethod (POST)
* @param string $account 账号
* @param string $password 密码
* @ApiParams (name="account", type="string", required=true, description="账号")
* @ApiParams (name="password", type="string", required=true, description="密码")
*/
public function login()
{
@ -62,8 +62,8 @@ class User extends Api
* 手机验证码登录
*
* @ApiMethod (POST)
* @param string $mobile 手机号
* @param string $captcha 验证码
* @ApiParams (name="mobile", type="string", required=true, description="手机号")
* @ApiParams (name="captcha", type="string", required=true, description="验证码")
*/
public function mobilelogin()
{
@ -101,11 +101,11 @@ class User extends Api
* 注册会员
*
* @ApiMethod (POST)
* @param string $username 用户名
* @param string $password 密码
* @param string $email 邮箱
* @param string $mobile 手机号
* @param string $code 验证码
* @ApiParams (name="username", type="string", required=true, description="用户名")
* @ApiParams (name="password", type="string", required=true, description="密码")
* @ApiParams (name="email", type="string", required=true, description="邮箱")
* @ApiParams (name="mobile", type="string", required=true, description="手机号")
* @ApiParams (name="code", type="string", required=true, description="验证码")
*/
public function register()
{
@ -153,10 +153,10 @@ class User extends Api
* 修改会员个人信息
*
* @ApiMethod (POST)
* @param string $avatar 头像地址
* @param string $username 用户名
* @param string $nickname 昵称
* @param string $bio 个人简介
* @ApiParams (name="avatar", type="string", required=true, description="头像地址")
* @ApiParams (name="username", type="string", required=true, description="用户名")
* @ApiParams (name="nickname", type="string", required=true, description="昵称")
* @ApiParams (name="bio", type="string", required=true, description="个人简介")
*/
public function profile()
{
@ -189,8 +189,8 @@ class User extends Api
* 修改邮箱
*
* @ApiMethod (POST)
* @param string $email 邮箱
* @param string $captcha 验证码
* @ApiParams (name="email", type="string", required=true, description="邮箱")
* @ApiParams (name="captcha", type="string", required=true, description="验证码")
*/
public function changeemail()
{
@ -224,8 +224,8 @@ class User extends Api
* 修改手机号
*
* @ApiMethod (POST)
* @param string $mobile 手机号
* @param string $captcha 验证码
* @ApiParams (name="mobile", type="string", required=true, description="手机号")
* @ApiParams (name="captcha", type="string", required=true, description="验证码")
*/
public function changemobile()
{
@ -259,8 +259,8 @@ class User extends Api
* 第三方登录
*
* @ApiMethod (POST)
* @param string $platform 平台名称
* @param string $code Code码
* @ApiParams (name="platform", type="string", required=true, description="平台名称")
* @ApiParams (name="code", type="string", required=true, description="Code码")
*/
public function third()
{
@ -291,9 +291,9 @@ class User extends Api
* 重置密码
*
* @ApiMethod (POST)
* @param string $mobile 手机号
* @param string $newpassword 新密码
* @param string $captcha 验证码
* @ApiParams (name="mobile", type="string", required=true, description="手机号")
* @ApiParams (name="newpassword", type="string", required=true, description="新密码")
* @ApiParams (name="captcha", type="string", required=true, description="验证码")
*/
public function resetpwd()
{

View File

@ -23,8 +23,8 @@ class Validate extends Api
* 检测邮箱
*
* @ApiMethod (POST)
* @param string $email 邮箱
* @param string $id 排除会员ID
* @ApiParams (name="email", type="string", required=true, description="邮箱")
* @ApiParams (name="id", type="string", required=true, description="排除会员ID")
*/
public function check_email_available()
{
@ -41,8 +41,8 @@ class Validate extends Api
* 检测用户名
*
* @ApiMethod (POST)
* @param string $username 用户名
* @param string $id 排除会员ID
* @ApiParams (name="username", type="string", required=true, description="用户名")
* @ApiParams (name="id", type="string", required=true, description="排除会员ID")
*/
public function check_username_available()
{
@ -59,8 +59,8 @@ class Validate extends Api
* 检测昵称
*
* @ApiMethod (POST)
* @param string $nickname 昵称
* @param string $id 排除会员ID
* @ApiParams (name="nickname", type="string", required=true, description="昵称")
* @ApiParams (name="id", type="string", required=true, description="排除会员ID")
*/
public function check_nickname_available()
{
@ -77,8 +77,8 @@ class Validate extends Api
* 检测手机
*
* @ApiMethod (POST)
* @param string $mobile 手机号
* @param string $id 排除会员ID
* @ApiParams (name="mobile", type="string", required=true, description="手机号")
* @ApiParams (name="id", type="string", required=true, description="排除会员ID")
*/
public function check_mobile_available()
{
@ -95,7 +95,7 @@ class Validate extends Api
* 检测手机
*
* @ApiMethod (POST)
* @param string $mobile 手机号
* @ApiParams (name="mobile", type="string", required=true, description="手机号")
*/
public function check_mobile_exist()
{
@ -111,7 +111,7 @@ class Validate extends Api
* 检测邮箱
*
* @ApiMethod (POST)
* @param string $mobile 邮箱
* @ApiParams (name="email", type="string", required=true, description="邮箱")
*/
public function check_email_exist()
{
@ -127,9 +127,9 @@ class Validate extends Api
* 检测手机验证码
*
* @ApiMethod (POST)
* @param string $mobile 手机号
* @param string $captcha 验证码
* @param string $event 事件
* @ApiParams (name="mobile", type="string", required=true, description="手机号")
* @ApiParams (name="captcha", type="string", required=true, description="验证码")
* @ApiParams (name="event", type="string", required=true, description="事件")
*/
public function check_sms_correct()
{
@ -146,9 +146,9 @@ class Validate extends Api
* 检测邮箱验证码
*
* @ApiMethod (POST)
* @param string $email 邮箱
* @param string $captcha 验证码
* @param string $event 事件
* @ApiParams (name="email", type="string", required=true, description="邮箱")
* @ApiParams (name="captcha", type="string", required=true, description="验证码")
* @ApiParams (name="event", type="string", required=true, description="事件")
*/
public function check_ems_correct()
{

View File

@ -268,13 +268,13 @@ class Backend extends Controller
$op = $this->request->get("op", '', 'trim');
$sort = $this->request->get("sort", !empty($this->model) && $this->model->getPk() ? $this->model->getPk() : 'id');
$order = $this->request->get("order", "DESC");
$offset = $this->request->get("offset/d", 0);
$limit = $this->request->get("limit/d", 0);
$offset = max(0, $this->request->get("offset/d", 0));
$limit = max(0, $this->request->get("limit/d", 0));
$limit = $limit ?: 999999;
//新增自动计算页码
$page = $limit ? intval($offset / $limit) + 1 : 1;
if ($this->request->has("page")) {
$page = $this->request->get("page/d", 1);
$page = max(0, $this->request->get("page/d", 1));
}
$this->request->get([config('paginate.var_page') => $page]);
$filter = (array)json_decode($filter, true);

View File

@ -221,7 +221,13 @@ class Auth
$this->setError('Account is locked');
return false;
}
if ($user->loginfailure >= 10 && time() - $user->loginfailuretime < 86400) {
$this->setError('Please try again after 1 day');
}
if ($user->password != $this->getEncryptPassword($password, $user->salt)) {
$user->save(['loginfailure' => $user->loginfailure + 1, 'loginfailuretime' => time()]);
$this->setError('Password is incorrect');
return false;
}

View File

@ -24,7 +24,9 @@ class Category extends Model
protected static function init()
{
self::afterInsert(function ($row) {
$row->save(['weigh' => $row['id']]);
if (!$row['weigh']) {
$row->save(['weigh' => $row['id']]);
}
});
}

View File

@ -302,7 +302,7 @@ return [
//允许跨域的域名,多个以,分隔
'cors_request_domain' => 'localhost,127.0.0.1',
//版本号
'version' => '1.5.0.20240328',
'version' => '1.5.2.20240906',
//API接口地址
'api_url' => 'https://api.fastadmin.net',
],

View File

@ -4,6 +4,7 @@ namespace app\index\controller;
use app\common\controller\Frontend;
use think\Lang;
use think\Loader;
use think\Response;
/**
@ -31,8 +32,20 @@ class Ajax extends Frontend
$header['Expires'] = gmdate("D, d M Y H:i:s", time() + $offset) . " GMT";
}
$controllername = $this->request->get('controllername');
$lang = $this->request->get('lang');
if (!$lang || !in_array($lang, config('allow_lang_list')) || !$controllername || !preg_match("/^[a-z0-9_\.]+$/i", $controllername)) {
return jsonp(['errmsg' => '参数错误'], 200, [], ['json_encode_param' => JSON_FORCE_OBJECT | JSON_UNESCAPED_UNICODE]);
}
$controllername = input("controllername");
$this->loadlang($controllername);
$className = Loader::parseClass($this->request->module(), 'controller', $controllername, false);
//存在对应的类才加载
if (class_exists($className)) {
$this->loadlang($controllername);
}
//强制输出JSON Object
return jsonp(Lang::get(), 200, $header, ['json_encode_param' => JSON_FORCE_OBJECT | JSON_UNESCAPED_UNICODE]);
}

View File

@ -15,7 +15,7 @@
}
],
"require": {
"php": ">=7.2.0",
"php": ">=7.4.0",
"topthink/framework": "dev-master",
"topthink/think-captcha": "^1.0.9",
"topthink/think-installer": "^1.0.14",
@ -23,7 +23,7 @@
"topthink/think-helper": "^1.0.7",
"karsonzhang/fastadmin-addons": "~1.4.0",
"overtrue/pinyin": "^3.0",
"phpoffice/phpspreadsheet": "1.19",
"phpoffice/phpspreadsheet": "^1.29.1",
"overtrue/wechat": "^4.6",
"ext-json": "*",
"ext-curl": "*",
@ -38,6 +38,11 @@
"easywechat-composer/easywechat-composer": true
}
},
"autoload": {
"psr-4": {
"addons\\": "addons/"
}
},
"repositories": [
{
"type": "git",

View File

@ -130,7 +130,7 @@ require(['jquery', 'bootstrap'], function ($, undefined) {
window.Config = Config;
// 配置语言包的路径
var paths = {};
paths['lang'] = Config.moduleurl + '/ajax/lang?callback=define&controllername=' + Config.controllername + '&lang=' + Config.language + '&v=' + Config.site.version;
paths['lang'] = Config.moduleurl + '/ajax/lang?callback=define&controllername=' + Config.controllername + '&lang=' + Config.language;
// 避免目录冲突
paths['backend/'] = 'backend/';
require.config({paths: paths});

File diff suppressed because one or more lines are too long

View File

@ -264,7 +264,7 @@ define(['jquery', 'bootstrap', 'upload', 'validator', 'validator-lang'], functio
var url = $(this).data("url") ? $(this).data("url") : (typeof Backend !== 'undefined' ? "general/attachment/select" : "user/attachment");
parent.Fast.api.open(url + "?element_id=" + $(this).attr("id") + "&multiple=" + multiple + "&mimetype=" + mimetype + "&admin_id=" + admin_id + "&user_id=" + user_id, __('Choose'), {
callback: function (data) {
var button = $("#" + $(that).attr("id"));
var button = $(that);
var maxcount = $(button).data("maxcount");
var input_id = $(button).data("input-id") ? $(button).data("input-id") : "";
maxcount = typeof maxcount !== "undefined" ? maxcount : 0;
@ -321,16 +321,28 @@ define(['jquery', 'bootstrap', 'upload', 'validator', 'validator-lang'], functio
}
data[match[1]][match[2]] = j.value;
});
var result = template ? [] : {};
//使用数组保存
var usearray = container.data("usearray") || false;
//保留空数据
var keepempty = container.data("keepempty") || false;
var result = template || usearray ? [] : {};
var keys = Object.keys(Object.values(data)[0] || {});
var isassociative = !usearray && keys.indexOf("value") > -1 && (keys.length === 1 || (keys.length === 2 && keys.indexOf("key") > -1));
if(isassociative && keys.length ===2){
result = {};
}
$.each(data, function (i, j) {
if (j) {
var keys = Object.keys(j);
if (keys.indexOf("value") > -1 && (keys.length === 1 || (keys.length === 2 && keys.indexOf("key") > -1))) {
if (isassociative) {
if (keys.length === 2) {
if (j.key != '') {
if (j.key != '' || keepempty) {
result['__PLACEHOLDKEY__' + j.key] = j.value;
}
} else {
//一维数组
result.push(j.value);
}
} else {
@ -509,7 +521,11 @@ define(['jquery', 'bootstrap', 'upload', 'validator', 'validator-lang'], functio
autocomplete: function (form) {
if ($("[data-role='autocomplete']", form).length > 0) {
require(['autocomplete'], function () {
$("[data-role='autocomplete']").autocomplete();
$("[data-role='autocomplete']").autocomplete({
onSelect: function () {
$(this).trigger('change').trigger('validate');
}
});
});
}
},

View File

@ -129,7 +129,7 @@ require(['jquery', 'bootstrap'], function ($, undefined) {
window.Config = Config;
// 配置语言包的路径
var paths = {};
paths['lang'] = Config.moduleurl + '/ajax/lang?callback=define&controllername=' + Config.controllername + '&lang=' + Config.language + '&v=' + Config.site.version;
paths['lang'] = Config.moduleurl + '/ajax/lang?callback=define&controllername=' + Config.controllername + '&lang=' + Config.language;
// 避免目录冲突
paths['frontend/'] = 'frontend/';
require.config({paths: paths});

File diff suppressed because one or more lines are too long

View File

@ -751,7 +751,7 @@ define(['jquery', 'bootstrap', 'moment', 'moment/locale/zh-cn', 'bootstrap-table
return html.join(' ');
},
file: function (value, row, index) {
Table.api.formatter.files.call(this, value, row, index);
return Table.api.formatter.files.call(this, value, row, index);
},
files: function (value, row, index) {
value = value == null || value.length === 0 ? '' : value.toString();
@ -831,8 +831,11 @@ define(['jquery', 'bootstrap', 'moment', 'moment/locale/zh-cn', 'bootstrap-table
},
search: function (value, row, index) {
var field = this.field;
if (typeof this.customField !== 'undefined' && typeof row[this.customField] !== 'undefined') {
value = row[this.customField];
if (typeof this.customField !== 'undefined') {
var customValue = this.customField.split('.').reduce(function (obj, key) {
return obj === null || obj === undefined ? '' : obj[key];
}, row);
value = Fast.api.escape(customValue);
field = this.customField;
}
return '<a href="javascript:;" class="searchit" data-toggle="tooltip" title="' + __('Click to search %s', value) + '" data-field="' + field + '" data-value="' + value + '">' + value + '</a>';
@ -856,8 +859,11 @@ define(['jquery', 'bootstrap', 'moment', 'moment/locale/zh-cn', 'bootstrap-table
colorArr = $.extend(colorArr, this.custom);
}
var field = this.field;
if (typeof this.customField !== 'undefined' && typeof row[this.customField] !== 'undefined') {
value = row[this.customField];
if (typeof this.customField !== 'undefined') {
var customValue = this.customField.split('.').reduce(function (obj, key) {
return obj === null || obj === undefined ? '' : obj[key];
}, row);
value = Fast.api.escape(customValue);
field = this.customField;
}
if (typeof that.searchList === 'object' && typeof that.custom === 'undefined') {
@ -992,7 +998,7 @@ define(['jquery', 'bootstrap', 'moment', 'moment/locale/zh-cn', 'bootstrap-table
$.each(dropdowns, function (i, j) {
dropdownHtml.push('<div class="btn-group"><button type="button" class="btn btn-primary dropdown-toggle btn-xs" data-toggle="dropdown">' + i + '</button><button type="button" class="btn btn-primary dropdown-toggle btn-xs" data-toggle="dropdown"><span class="caret"></span></button><ul class="dropdown-menu dropdown-menu-right"><li>' + j.join('</li><li>') + '</li></ul></div>');
});
html.unshift(dropdownHtml);
html.unshift(dropdownHtml.join(' '));
}
return html.join(' ');
},
@ -1007,17 +1013,11 @@ define(['jquery', 'bootstrap', 'moment', 'moment/locale/zh-cn', 'bootstrap-table
url + (url.match(/(\?|&)+/) ? "&ids=" : "/ids/") + '{ids}' : url;
url = url.replace(/\{(.*?)\}/gi, function (matched) {
matched = matched.substring(1, matched.length - 1);
if (matched.indexOf(".") !== -1) {
var temp = row;
var arr = matched.split(/\./);
for (var i = 0; i < arr.length; i++) {
if (typeof temp[arr[i]] !== 'undefined') {
temp = temp[arr[i]];
}
}
return typeof temp === 'object' ? '' : temp;
}
return row[matched];
var temp = matched.split('.').reduce(function (obj, key) {
return obj === null || obj === undefined ? '' : obj[key];
}, row);
temp = Fast.api.escape(temp);
return temp;
});
return url;
},