Pre Merge pull request !71 from PPPSCN/master

pull/71/MERGE
PPPSCN 2018-08-13 13:33:12 +08:00
commit 0b7a2ca9ef
36 changed files with 4181 additions and 1628 deletions

1
.gitignore vendored
View File

@ -13,3 +13,4 @@ composer.lock
*.css.map
!.gitkeep
.env
/.svn

View File

@ -115,6 +115,11 @@ class Crud extends Command
*/
protected $editorClass = 'editor';
/**
* langList的key最长字节数
*/
protected $fieldMaxLen = 0;
protected function configure()
{
$this
@ -483,6 +488,7 @@ class Crud extends Command
//循环所有字段,开始构造视图的HTML和JS信息
foreach ($columnList as $k => $v) {
$field = $v['COLUMN_NAME'];
$langField = mb_ucfirst($field);
$itemArr = [];
// 这里构建Enum和Set类型的列表数据
if (in_array($v['DATA_TYPE'], ['enum', 'set', 'tinyint'])) {
@ -540,6 +546,7 @@ class Crud extends Command
$formEditElement = $this->getReplacedStub('html/select', ['field' => $field, 'fieldName' => $fieldName, 'fieldList' => $this->getFieldListName($field), 'attrStr' => Form::attributes($attrArr), 'selectedValue' => "\$row.{$field}"]);
} else if ($inputType == 'datetime') {
$cssClassArr[] = 'datetimepicker';
$attrArr['placeholder'] = "{:__('Please select')}{:__('{$langField}')}";
$attrArr['class'] = implode(' ', $cssClassArr);
$format = "YYYY-MM-DD HH:mm:ss";
$phpFormat = "Y-m-d H:i:s";
@ -595,6 +602,7 @@ class Crud extends Command
$formEditElement = $this->getReplacedStub('html/' . $inputType, ['field' => $field, 'fieldName' => $fieldName, 'fieldList' => $this->getFieldListName($field), 'attrStr' => Form::attributes($attrArr), 'selectedValue' => "\$row.{$field}"]);
} else if ($inputType == 'textarea') {
$cssClassArr[] = $this->isMatchSuffix($field, $this->editorSuffix) ? $this->editorClass : '';
$attrArr['placeholder'] = "{:__('Please input')}{:__('{$langField}')}";
$attrArr['class'] = implode(' ', $cssClassArr);
$attrArr['rows'] = 5;
$formAddElement = Form::textarea($fieldName, $defaultValue, $attrArr);
@ -615,17 +623,20 @@ class Crud extends Command
$formAddElement = $this->getReplacedStub('html/' . $inputType, ['field' => $field, 'fieldName' => $fieldName, 'fieldYes' => $yes, 'fieldNo' => $no, 'attrStr' => Form::attributes($attrArr), 'fieldValue' => $defaultValue, 'fieldSwitchClass' => $defaultValue == $no ? $stateNoClass : '']);
$formEditElement = $this->getReplacedStub('html/' . $inputType, ['field' => $field, 'fieldName' => $fieldName, 'fieldYes' => $yes, 'fieldNo' => $no, 'attrStr' => Form::attributes($attrArr), 'fieldValue' => "{\$row.{$field}}", 'fieldSwitchClass' => "{eq name=\"\$row.{$field}\" value=\"{$no}\"}fa-flip-horizontal text-gray{/eq}"]);
} else if ($inputType == 'citypicker') {
$attrArr['placeholder'] = "{:__('Please select')}{:__('{$langField}')}";
$attrArr['class'] = implode(' ', $cssClassArr);
$attrArr['data-toggle'] = "city-picker";
$formAddElement = sprintf("<div class='control-relative'>%s</div>", Form::input('text', $fieldName, $defaultValue, $attrArr));
$formEditElement = sprintf("<div class='control-relative'>%s</div>", Form::input('text', $fieldName, $editValue, $attrArr));
} else {
$attrArr['placeholder'] = "{:__('Please input')}{:__('{$langField}')}";
$search = $replace = '';
//特殊字段为关联搜索
if ($this->isMatchSuffix($field, $this->selectpageSuffix)) {
$inputType = 'text';
$defaultValue = '';
$attrArr['data-rule'] = 'required';
$attrArr['placeholder'] = "{:__('Please select')}{:__('{$langField}')}";
$cssClassArr[] = 'selectpage';
$selectpageController = str_replace('_', '/', substr($field, 0, strripos($field, '_')));
$attrArr['data-source'] = $selectpageController . "/index";
@ -731,9 +742,19 @@ class Crud extends Command
$editList = implode("\n", array_filter($editList));
$javascriptList = implode(",\n", array_filter($javascriptList));
$langList = implode(",\n", array_filter($langList));
//数组等号对齐
$langList = array_filter(explode(",\n", $langList . ",\n"));
foreach ($langList as &$line) {
if (preg_match("/^\s+'([^']+)'\s*=>\s*'([^']+)'\s*/is", $line, $matches)) {
$line = " '{$matches[1]}'" . str_pad('=>', ($this->fieldMaxLen - strlen($matches[1]) + 3), ' ', STR_PAD_LEFT) . " '{$matches[2]}'";
}
}
unset($line);
$langList = implode(",\n", array_filter($langList)). ",";
//表注释
$tableComment = $modelTableInfo['Comment'];
$tableCNName = mb_substr($tableComment, -1) == '表' ? mb_substr($tableComment, 0, -1) : $tableComment;
$tableComment = mb_substr($tableComment, -1) == '表' ? mb_substr($tableComment, 0, -1) . '管理' : $tableComment;
$modelInit = '';
@ -755,6 +776,7 @@ class Crud extends Command
'modelTableTypeName' => $modelTableTypeName,
'validateName' => $validateName,
'tableComment' => $tableComment,
'tableCNName' => $tableCNName,
'iconName' => $iconName,
'pk' => $priKey,
'order' => $order,
@ -1074,6 +1096,7 @@ EOD;
{
if ($content || !Lang::has($field)) {
$itemArr = [];
$this->fieldMaxLen = strlen($field) > $this->fieldMaxLen ? strlen($field) : $this->fieldMaxLen;
$content = str_replace('', ',', $content);
if (stripos($content, ':') !== false && stripos($content, ',') && stripos($content, '=') !== false) {
list($fieldLang, $item) = explode(':', $content);
@ -1083,6 +1106,7 @@ EOD;
if (count($valArr) == 2) {
list($key, $value) = $valArr;
$itemArr[$field . ' ' . $key] = $value;
$this->fieldMaxLen = strlen($field . ' ' . $key) > $this->fieldMaxLen ? strlen($field . ' ' . $key) : $this->fieldMaxLen;
}
}
} else {
@ -1090,7 +1114,7 @@ EOD;
}
$resultArr = [];
foreach ($itemArr as $k => $v) {
$resultArr[] = " '" . mb_ucfirst($k) . "' => '{$v}'";
$resultArr[] = " '" . mb_ucfirst($k) . "' => '{$v}'";
}
return implode(",\n", $resultArr);
} else {
@ -1131,7 +1155,7 @@ EOD;
}
$stringArr[] = "'" . $k . "' => " . ($is_var ? $v : "'{$v}'");
}
return implode(",", $stringArr);
return implode(", ", $stringArr);
}
protected function getItemArray($item, $field, $comment)
@ -1245,8 +1269,8 @@ EOD;
$langField = mb_ucfirst($field);
return <<<EOD
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('{$langField}')}:</label>
<div class="col-xs-12 col-sm-8">
<label for="c-{$field}" class="control-label">{:__('{$langField}')}:</label>
<div class="pp_container">
{$content}
</div>
</div>
@ -1272,11 +1296,11 @@ EOD;
return <<<EOD
<div class="input-group">
{$content}
<span class="msg-box n-top" for="c-{$field}"></span>
<div class="input-group-addon no-border no-padding">
<span><button type="button" id="plupload-{$field}" class="btn btn-danger plupload" data-input-id="c-{$field}"{$uploadfilter}{$multiple}{$preview}><i class="fa fa-upload"></i> {:__('Upload')}</button></span>
<span><button type="button" id="fachoose-{$field}" class="btn btn-primary fachoose" data-input-id="c-{$field}"{$selectfilter}{$multiple}><i class="fa fa-list"></i> {:__('Choose')}</button></span>
</div>
<span class="msg-box n-right" for="c-{$field}"></span>
</div>
{$previewcontainer}
EOD;

View File

@ -1,11 +1,9 @@
<form id="add-form" class="form-horizontal" role="form" data-toggle="validator" method="POST" action="">
<form id="add-form" role="form" data-toggle="validator" method="POST" action="">
{%addList%}
<div class="form-group layer-footer">
<label class="control-label col-xs-12 col-sm-2"></label>
<div class="col-xs-12 col-sm-8">
<div class="pp_container text-center">
<button type="submit" class="btn btn-success btn-embossed disabled">{:__('OK')}</button>
<button type="reset" class="btn btn-default btn-embossed">{:__('Reset')}</button>
</div>
</div>
</form>
</form>

View File

@ -11,7 +11,7 @@ use app\common\controller\Backend;
*/
class {%controllerName%} extends Backend
{
/**
* {%modelName%}模型对象
* @var \{%modelNamespace%}\{%modelName%}
@ -24,12 +24,22 @@ class {%controllerName%} extends Backend
$this->model = new \{%modelNamespace%}\{%modelName%};
{%controllerAssignList%}
}
/**
* 默认生成的控制器所继承的父类中有index/add/edit/del/multi五个基础方法、destroy/restore/recyclebin三个回收站方法
* 因此在当前控制器中可不用编写增删改查的代码,除非需要自己控制这部分逻辑
* 需要将application/admin/library/traits/Backend.php中对应的方法复制到当前控制器,然后进行修改
*/
/**
* 导入
*/
/*
public function import()
{
return parent::import();
}
*/
{%controllerIndex%}
}

View File

@ -1,11 +1,9 @@
<form id="edit-form" class="form-horizontal" role="form" data-toggle="validator" method="POST" action="">
<form id="edit-form" role="form" data-toggle="validator" method="POST" action="">
{%editList%}
<div class="form-group layer-footer">
<label class="control-label col-xs-12 col-sm-2"></label>
<div class="col-xs-12 col-sm-8">
<div class="pp_container text-center">
<button type="submit" class="btn btn-success btn-embossed disabled">{:__('OK')}</button>
<button type="reset" class="btn btn-default btn-embossed">{:__('Reset')}</button>
</div>
</div>
</form>
</form>

View File

@ -1,6 +1,5 @@
<div class="radio">
<div class="radio" id="c-{%field%}">
{foreach name="{%fieldList%}" item="vo"}
<label for="{%fieldName%}-{$key}"><input id="{%fieldName%}-{$key}" name="{%fieldName%}" type="radio" value="{$key}" {in name="key" value="{%selectedValue%}"}checked{/in} /> {$vo}</label>
{/foreach}
</div>
</div>

View File

@ -1,6 +1,5 @@
<select {%attrStr%}>
<select {%attrStr%}>
{foreach name="{%fieldList%}" item="vo"}
<option value="{$key}" {in name="key" value="{%selectedValue%}"}selected{/in}>{$vo}</option>
{/foreach}
</select>
</select>

View File

@ -9,23 +9,45 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
add_url: '{%controllerUrl%}/add',
edit_url: '{%controllerUrl%}/edit',
del_url: '{%controllerUrl%}/del',
//import_url: '{%controllerUrl%}/import',
multi_url: '{%controllerUrl%}/multi',
table: '{%table%}',
}
});
var table = $("#table");
var date = new Date();
//在表格内容渲染完成后回调的事件
table.on('post-body.bs.table', function (e, settings, json, xhr) {
$(".btn-add").data("area", ["1000px", "95%"]).data("title", '添加{%tableCNName%}');
$(".btn-editone").data("area", ["1000px", "95%"]).data("title", '编辑{%tableCNName%}');
$(".btn-edit").data("area", ["1000px", "95%"]).data("title", '编辑{%tableCNName%}');
});
// 初始化表格
table.bootstrapTable({
url: $.fn.bootstrapTable.defaults.extend.index_url,
pk: '{%pk%}',
sortName: '{%order%}',
exportTypes: ['csv', 'excel'],
exportOptions: {
fileName: '{%modelTableTypeName%}_' + [date.getFullYear(), date.getMonth() + 1, date.getDate()].join('-'),
ignoreColumn: [0, 'operate'], //默认不导出第一列(checkbox)与操作(operate)列
},
columns: [
[
{%javascriptList%}
]
]
],
//禁用默认搜索
search: false,
//启用普通表单搜索
commonSearch: true,
//可以控制是否默认显示搜索单表,false则隐藏,默认为false
searchFormVisible: false,
showColumns: false,
showToggle: false,
});
{%headingJs%}

View File

@ -1,6 +1,6 @@
public function {%methodName%}($value, $data)
{
{
$value = $value ? $value : (isset($data['{%field%}']) ? $data['{%field%}'] : '');
$list = $this->{%listMethodName%}();
return isset($list[$value]) ? $list[$value] : '';

View File

@ -1,6 +1,6 @@
public function {%methodName%}($value, $data)
{
{
$value = $value ? $value : (isset($data['{%field%}']) ? $data['{%field%}'] : '');
$list = $this->{%listMethodName%}();
return isset($list[$value]) ? $list[$value] : '';

View File

@ -8,21 +8,21 @@ class {%modelName%} extends Model
{
// 表名
protected ${%modelTableType%} = '{%modelTableTypeName%}';
// 自动写入时间戳字段
protected $autoWriteTimestamp = {%modelAutoWriteTimestamp%};
// 定义时间戳字段名
protected $createTime = {%createTime%};
protected $updateTime = {%updateTime%};
// 追加属性
protected $append = [
{%appendAttrList%}
];
{%modelInit%}
{%getEnumList%}
{%getAttrList%}

View File

@ -196,6 +196,13 @@ class Menu extends Command
if (in_array('trashed', get_class_methods($model))) {
$withSofeDelete = true;
}
} else {
preg_match_all("/\\\$this\->model\s*=\s*new\s+([a-zA-Z\\\]+);/", $classContent, $matches);
\think\Request::instance()->module('admin');
$model = new $matches[1][0];
if (in_array('trashed', get_class_methods($model))) {
$withSofeDelete = true;
}
}
//忽略的类
if (stripos($classComment, "@internal") !== FALSE) {

View File

@ -54,6 +54,7 @@ class Ajax extends Backend
//判断是否已经存在附件
$sha1 = $file->hash();
$extparam = $this->request->post();
$upload = Config::get('upload');
@ -118,6 +119,7 @@ class Ajax extends Backend
'uploadtime' => time(),
'storage' => 'local',
'sha1' => $sha1,
'extparam' => json_encode($extparam),
);
$attachment = model("attachment");
$attachment->data(array_filter($params));
@ -207,6 +209,10 @@ class Ajax extends Backend
rmdirs(TEMP_PATH, false);
if ($type == 'template')
break;
case 'log' || 'all':
rmdirs(LOG_PATH, false);
if ($type == 'log')
break;
case 'addons' || 'all':
Service::refresh();
if ($type == 'addons')
@ -244,8 +250,14 @@ class Ajax extends Backend
*/
public function area()
{
$province = $this->request->get('province');
$city = $this->request->get('city');
$params = $this->request->get("row/a");
if (!empty($params)) {
$province = isset($params['province']) ? $params['province'] : '';
$city = isset($params['city']) ? $params['city'] : null;
} else {
$province = $this->request->get('province');
$city = $this->request->get('city');
}
$where = ['pid' => 0, 'level' => 1];
$provincelist = null;
if ($province !== '') {

View File

@ -265,7 +265,7 @@ class Admin extends Backend
/**
* 下拉搜索
*/
protected function selectpage()
public function selectpage()
{
$this->dataLimit = 'auth';
$this->dataLimitField = 'id';

View File

@ -111,6 +111,7 @@ return [
'%d year%s ago' => '%d年前',
'Set to normal' => '设为正常',
'Set to hidden' => '设为隐藏',
'Set to recommend' => '设为推荐',
//提示
'Go back' => '返回首页',
'Jump now' => '立即跳转',
@ -170,4 +171,8 @@ return [
'Admin log tips' => '管理员可以查看自己所拥有的权限的管理员日志',
'Group tips' => '角色组可以有多个,角色有上下级层级关系,如果子角色有角色组和管理员的权限则可以派生属于自己组别的下级角色组或管理员',
'Rule tips' => '规则通常对应一个控制器的方法,同时左侧的菜单栏数据也从规则中体现,通常建议通过命令行进行生成规则节点',
'Test' => '测试',
'All' => '全部',
'Please input' => '请填写',
'Please select' => '请选择',
];

View File

@ -16,5 +16,8 @@ return [
'Storage' => '存储引擎',
'Upload to third' => '上传到第三方',
'Upload to local' => '上传到本地',
'Upload from editor' => '从编辑器上传'
'Upload from editor' => '从编辑器上传',
'No file upload or server upload limit exceeded' => '未上传文件或超出服务器上传限制',
'Uploaded file format is limited' => '上传文件格式受限制',
'Upload successful' => '上传成功',
];

View File

@ -2,6 +2,12 @@
namespace app\admin\library\traits;
use app\admin\library\Auth;
use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
use PhpOffice\PhpSpreadsheet\Reader\Xlsx;
use PhpOffice\PhpSpreadsheet\Reader\Xls;
use PhpOffice\PhpSpreadsheet\Reader\Csv;
trait Backend
{
@ -74,6 +80,8 @@ trait Backend
if ($this->request->isPost()) {
$params = $this->request->post("row/a");
if ($params) {
$auth = Auth::instance();
$params['admin_id'] = $auth->isLogin() ? $auth->id : 0;
if ($this->dataLimit && $this->dataLimitFieldAutoFill) {
$params[$this->dataLimitField] = $this->auth->id;
}
@ -91,7 +99,11 @@ trait Backend
$this->error($this->model->getError());
}
} catch (\think\exception\PDOException $e) {
$this->error($e->getMessage());
$msg = $e->getMessage();
if (preg_match("/.+Integrity constraint violation: 1062 Duplicate entry '(.+)' for key '(.+)'/is", $msg, $matches)) {
$msg = "添加失败!【{$matches[1]}】的记录已存在";
};
$this->error($msg);
} catch (\think\Exception $e) {
$this->error($e->getMessage());
}
@ -132,7 +144,11 @@ trait Backend
$this->error($row->getError());
}
} catch (\think\exception\PDOException $e) {
$this->error($e->getMessage());
$msg = $e->getMessage();
if (preg_match("/.+Integrity constraint violation: 1062 Duplicate entry '(.+)' for key '(.+)'/is", $msg, $matches)) {
$msg = "编辑失败!【{$matches[1]}】的记录已存在";
};
$this->error($msg);
} catch (\think\Exception $e) {
$this->error($e->getMessage());
}
@ -264,15 +280,36 @@ trait Backend
if (!is_file($filePath)) {
$this->error(__('No results were found'));
}
$PHPReader = new \PHPExcel_Reader_Excel2007();
if (!$PHPReader->canRead($filePath)) {
$PHPReader = new \PHPExcel_Reader_Excel5();
if (!$PHPReader->canRead($filePath)) {
$PHPReader = new \PHPExcel_Reader_CSV();
if (!$PHPReader->canRead($filePath)) {
$this->error(__('Unknown data format'));
//实例化reader
$ext = pathinfo($filePath, PATHINFO_EXTENSION);
if (!in_array($ext, ['csv', 'xls', 'xlsx'])) {
$this->error(__('Unknown data format'));
}
if ($ext === 'csv') {
$file = fopen($filePath, 'r');
$filePath = tempnam(sys_get_temp_dir(), 'import_csv');
$fp = fopen($filePath, "w");
$n = 0;
while ($line = fgets($file)) {
$line = rtrim($line, "\n\r\0");
$encoding = mb_detect_encoding($line, ['utf-8', 'gbk', 'latin1', 'big5']);
if ($encoding != 'utf-8') {
$line = mb_convert_encoding($line, 'utf-8', $encoding);
}
if ($n == 0 || preg_match('/^".*"$/', $line)) {
fwrite($fp, $line . "\n");
} else {
fwrite($fp, '"' . str_replace(['"', ','], ['""', '","'], $line) . "\"\n");
}
$n++;
}
fclose($file) || fclose($fp);
$reader = new Csv();
} elseif ($ext === 'xls') {
$reader = new Xls();
} else {
$reader = new Xlsx();
}
//导入文件首行类型,默认是注释,如果需要使用字段名称请使用name
@ -290,42 +327,55 @@ trait Backend
}
}
$PHPExcel = $PHPReader->load($filePath); //加载文件
$currentSheet = $PHPExcel->getSheet(0); //读取文件中的第一个工作表
$allColumn = $currentSheet->getHighestDataColumn(); //取得最大的列号
$allRow = $currentSheet->getHighestRow(); //取得一共有多少行
$maxColumnNumber = \PHPExcel_Cell::columnIndexFromString($allColumn);
for ($currentRow = 1; $currentRow <= 1; $currentRow++) {
for ($currentColumn = 0; $currentColumn < $maxColumnNumber; $currentColumn++) {
$val = $currentSheet->getCellByColumnAndRow($currentColumn, $currentRow)->getValue();
$fields[] = $val;
//加载文件
try {
if (!$PHPExcel = $reader->load($filePath)) {
$this->error(__('Unknown data format'));
}
}
$insert = [];
for ($currentRow = 2; $currentRow <= $allRow; $currentRow++) {
$values = [];
for ($currentColumn = 0; $currentColumn < $maxColumnNumber; $currentColumn++) {
$val = $currentSheet->getCellByColumnAndRow($currentColumn, $currentRow)->getValue();
$values[] = is_null($val) ? '' : $val;
}
$row = [];
$temp = array_combine($fields, $values);
foreach ($temp as $k => $v) {
if (isset($fieldArr[$k]) && $k !== '') {
$row[$fieldArr[$k]] = $v;
$currentSheet = $PHPExcel->getSheet(0); //读取文件中的第一个工作表
$allColumn = $currentSheet->getHighestDataColumn(); //取得最大的列号
$allRow = $currentSheet->getHighestRow(); //取得一共有多少行
$maxColumnNumber = Coordinate::columnIndexFromString($allColumn);
for ($currentRow = 1; $currentRow <= 1; $currentRow++) {
for ($currentColumn = 0; $currentColumn < $maxColumnNumber; $currentColumn++) {
$val = $currentSheet->getCellByColumnAndRow($currentColumn, $currentRow)->getValue();
$fields[] = $val;
}
}
if ($row) {
$insert[] = $row;
$insert = [];
for ($currentRow = 2; $currentRow <= $allRow; $currentRow++) {
$values = [];
for ($currentColumn = 0; $currentColumn < $maxColumnNumber; $currentColumn++) {
$val = $currentSheet->getCellByColumnAndRow($currentColumn, $currentRow)->getValue();
$values[] = is_null($val) ? '' : $val;
}
$row = [];
$temp = array_combine($fields, $values);
foreach ($temp as $k => $v) {
if (isset($fieldArr[$k]) && $k !== '') {
$row[$fieldArr[$k]] = $v;
}
}
if ($row) {
$insert[] = $row;
}
}
} catch (Exception $exception) {
$this->error($exception->getMessage());
}
if (!$insert) {
$this->error(__('No rows were updated'));
}
try {
$this->model->saveAll($insert);
} catch (\think\exception\PDOException $exception) {
$this->error($exception->getMessage());
$msg = $exception->getMessage();
if (preg_match("/.+Integrity constraint violation: 1062 Duplicate entry '(.+)' for key '(.+)'/is", $msg, $matches)) {
$msg = "导入失败,包含【{$matches[1]}】的记录已存在";
};
$this->error($msg);
} catch (\Exception $e) {
$this->error($e->getMessage());
}

View File

@ -4,7 +4,7 @@
<!-- 加载样式及META信息 -->
{include file="common/meta" /}
</head>
<body class="hold-transition skin-green sidebar-mini fixed {if $config.fastadmin.multiplenav}multiplenav{/if}" id="tabs">
<body class="hold-transition skin-blue sidebar-mini fixed {if $config.fastadmin.multiplenav}multiplenav{/if}" id="tabs">
<div class="wrapper">
<!-- 头部区域 -->

View File

@ -8,6 +8,7 @@ use think\Controller;
use think\Hook;
use think\Lang;
use think\Session;
use fast\Tree;
/**
* 后台控制器基类
@ -133,6 +134,10 @@ class Backend extends Controller
Hook::listen('admin_nologin', $this);
$url = Session::get('referer');
$url = $url ? $url : $this->request->url();
if ($url == '/') {
$this->redirect('index/login', [], 302, ['referer' => $url]);
exit;
}
$this->error(__('Please login first'), url('index/login', ['url' => $url]));
}
// 判断是否需要验证权限
@ -420,6 +425,12 @@ class Backend extends Controller
$searchfield = (array)$this->request->request("searchField/a");
//自定义搜索条件
$custom = (array)$this->request->request("custom/a");
//是否返回树形结构
$istree = $this->request->request("isTree", 0);
if($istree) {
$word = [];
$pagesize = 99999;
}
$order = [];
foreach ($orderby as $k => $v) {
$order[$v[0]] = $v[1];
@ -465,6 +476,15 @@ class Backend extends Controller
$field => isset($item[$field]) ? $item[$field] : ''
];
}
if($istree) {
$tree = Tree::instance();
$tree->init(collection($list)->toArray(), 'pid');
$list = $tree->getTreeList($tree->getTreeArray(0), 'name');
foreach ($list as &$item) {
$item = str_replace('&nbsp;', ' ', $item);
}
unset($item);
}
}
//这里一定要返回有list这个字段,total是可选的,如果total<=list的数量,则会隐藏分页按钮
return json(['list' => $list, 'total' => $total]);

View File

@ -26,7 +26,7 @@ return [
// 是否支持多模块
'app_multi_module' => true,
// 入口自动绑定模块
'auto_bind_module' => false,
'auto_bind_module' => true,
// 注册的根命名空间
'root_namespace' => [],
// 扩展函数文件

View File

@ -18,11 +18,11 @@ return [
// 服务器地址
'hostname' => Env::get('database.hostname', '127.0.0.1'),
// 数据库名
'database' => Env::get('database.database', 'fastadmin'),
'database' => Env::get('database.database', 'fa_com'),
// 用户名
'username' => Env::get('database.username', 'root'),
// 密码
'password' => Env::get('database.password', ''),
'password' => Env::get('database.password', 'root'),
// 端口
'hostport' => Env::get('database.hostport', ''),
// 连接dsn

View File

@ -4,8 +4,47 @@ return array (
'autoload' => false,
'hooks' =>
array (
'sms_send' =>
array (
0 => 'alisms',
),
'sms_notice' =>
array (
0 => 'alisms',
),
'sms_check' =>
array (
0 => 'alisms',
),
'addon_after_upgrade' =>
array (
0 => 'cms',
),
'app_init' =>
array (
0 => 'epay',
),
'login_init' =>
array (
0 => 'loginbg',
),
),
'route' =>
array (
'/cms$' => 'cms/index/index',
'/cms/c/[:diyname]' => 'cms/channel/index',
'/cms/t/[:name]' => 'cms/tags/index',
'/cms/a/[:diyname]' => 'cms/archives/index',
'/cms/p/[:diyname]' => 'cms/page/index',
'/cms/s' => 'cms/search/index',
'/docs/api' => 'docs/index/api',
'/docs/[:name]' => 'docs/index/index',
'/example$' => 'example/index/index',
'/example/d/[:name]' => 'example/demo/index',
'/example/d1/[:name]' => 'example/demo/demo1',
'/example/d2/[:name]' => 'example/demo/demo2',
'/third$' => 'third/index/index',
'/third/connect/[:platform]' => 'third/index/connect',
'/third/callback/[:platform]' => 'third/index/callback',
),
);

View File

@ -32,6 +32,7 @@
"fastadmin-dragsort": "~1.0.0",
"fastadmin-addtabs": "~1.0.3",
"fastadmin-selectpage": "~1.0.0",
"fastadmin-layer": "~3.1.2"
"fastadmin-layer": "~3.1.2",
"bootstrap-slider": "*"
}
}

View File

@ -24,7 +24,8 @@
"phpmailer/phpmailer": "^5.2",
"karsonzhang/fastadmin-addons": "~1.1.4",
"overtrue/pinyin": "~3.0",
"phpoffice/phpexcel": "^1.8"
"phpoffice/phpspreadsheet": "^1.2",
"phpoffice/phpword": "^0.14.0"
},
"config": {
"preferred-install": "dist"

View File

@ -9,9 +9,7 @@
// +----------------------------------------------------------------------
// | Author: liu21st <liu21st@gmail.com>
// +----------------------------------------------------------------------
// [ 后台入口文件 ]
// 使用此文件可以达到隐藏admin模块的效果
// 建议将admin.php改成其它任意的文件名同时修改config.php中的'deny_module_list',把admin模块也添加进去
// [ 应用入口文件 ]
// 定义应用目录
define('APP_PATH', __DIR__ . '/../application/');
@ -23,16 +21,4 @@ if (!is_file(APP_PATH . 'admin/command/Install/install.lock'))
}
// 加载框架引导文件
require __DIR__ . '/../thinkphp/base.php';
// 绑定到admin模块
\think\Route::bind('admin');
// 关闭路由
\think\App::route(false);
// 设置根url
\think\Url::root('');
// 执行应用
\think\App::run()->send();
require __DIR__ . '/../thinkphp/start.php';

View File

@ -0,0 +1,38 @@
<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006-2016 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: liu21st <liu21st@gmail.com>
// +----------------------------------------------------------------------
// [ 后台入口文件 ]
// 使用此文件可以达到隐藏admin模块的效果
// 建议将admin.php改成其它任意的文件名同时修改config.php中的'deny_module_list',把admin模块也添加进去
// 定义应用目录
define('APP_PATH', __DIR__ . '/../application/');
// 判断是否安装FastAdmin
if (!is_file(APP_PATH . 'admin/command/Install/install.lock'))
{
header("location:./install.php");
exit;
}
// 加载框架引导文件
require __DIR__ . '/../thinkphp/base.php';
// 绑定到admin模块
\think\Route::bind('admin');
// 关闭路由
\think\App::route(false);
// 设置根url
\think\Url::root('');
// 执行应用
\think\App::run()->send();

View File

@ -1,6 +1,6 @@
@import url("../css/bootstrap.css");
@import url("../css/fastadmin.css");
@import url("../css/skins/skin-green.css");
@import url("../css/skins/skin-blue.css");
@import url("../css/iconfont.css");
@import url("../libs/font-awesome/css/font-awesome.min.css");
@import url("../libs/toastr/toastr.min.css");
@ -11,6 +11,7 @@
@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%;
@ -113,9 +114,16 @@ html.ios-fix body {
table.table-template {
overflow: hidden;
}
.sp_container .msg-box {
.pp_container {
border: none;
margin: 0;
padding: 0;
position: relative;
vertical-align: middle;
}
.sp_container .msg-box,.pp_container .msg-box {
position: absolute;
right: 0;
left: 0;
top: 0;
}
.toast-top-right-index {
@ -988,6 +996,59 @@ table.table-nowrap thead > tr > th {
.wipecache li a {
color: #444444 !important;
}
.col-md-1-5 {
width: 20% !important;
float: left;
}
.col-xs-1-5,.col-sm-1-5,.col-md-1-5,.col-lg-1-5 {
min-height: 1px;
padding-left: 15px;
padding-right: 15px;
position: relative;
}
@media (min-width: 768px) {
.col-sm-1-5 {
width: 20%;
float: left;
}
}
@media (min-width: 992px) {
.col-md-1-5 {
width: 20%;
float: left;
}
}
@media (min-width: 1200px) {
.col-lg-1-5 {
width: 20%;
float: left;
}
}
div.pre {
display: block;
padding: 5px;
margin: 0 0 5px;
font-size: 11px;
line-height: 1.42857143;
word-break: break-all;
word-wrap: break-word;
color: #333333;
background-color: #f5f5f5;
border: 1px solid #ccc;
border-radius: 3px;
text-align: left;
}
#add-form .panel-body,#edit-form .panel-body{
padding-bottom:0;
}
/*修正开关关闭下的颜色值*/
.btn-switcher.disabled {
opacity: .6;

File diff suppressed because one or more lines are too long

View File

@ -1,3 +1,217 @@
define([], function () {
require([], function () {
//绑定data-toggle=addresspicker属性点击事件
$(document).on('click', "[data-toggle='addresspicker']", function () {
var that = this;
var callback = $(that).data('callback');
var input_id = $(that).data("input-id") ? $(that).data("input-id") : "";
var lat_id = $(that).data("lat-id") ? $(that).data("lat-id") : "";
var lng_id = $(that).data("lng-id") ? $(that).data("lng-id") : "";
var lat = lat_id ? $("#" + lat_id).val() : '';
var lng = lng_id ? $("#" + lng_id).val() : '';
var url = "/addons/address/index/select";
url += (lat && lng) ? '?lat=' + lat + '&lng=' + lng : '';
Fast.api.open(url, '位置选择', {
callback: function (res) {
input_id && $("#" + input_id).val(res.address);
lat_id && $("#" + lat_id).val(res.lat);
lng_id && $("#" + lng_id).val(res.lng);
try {
//执行回调函数
if (typeof callback === 'function') {
callback.call(that, res);
}
} catch (e) {
}
}
});
});
});
require.config({
paths: {
'fullcalendar': '../libs/fullcalendar/dist/fullcalendar',
'fullcalendar-lang': '../libs/fullcalendar/dist/locale/zh-cn',
},
// shim依赖配置
shim: {
'fullcalendar-lang': ['fullcalendar'],
},
});
require.config({
paths: {
'async': '../addons/example/js/async',
'BMap': ['//api.map.baidu.com/api?v=2.0&ak=mXijumfojHnAaN2VxpBGoqHM'],
},
shim: {
'BMap': {
deps: ['jquery'],
exports: 'BMap'
}
}
});
//修改验证码为检验验证
require.config({
paths: {
'geet': '../addons/geet/js/gt'
}
});
require(['geet'], function (Geet) {
var geetInit = false;
$("input[name='captcha']").each(function () {
var obj = $(this);
var form = obj.closest('form');
$("<input type='hidden' name='geeturl' value='" + (form.attr("action") ? form.attr("action") : location.pathname + location.search) + "' />").appendTo(form);
$("<input type='hidden' name='geetmodule' value='" + Config.modulename + "' />").appendTo(form);
$("<input type='hidden' name='geetmoduleurl' value='" + Config.moduleurl + "' />").appendTo(form);
form.attr('action', Fast.api.fixurl('/addons/geet/index/check'));
obj.parent().removeClass('input-group').addClass('form-group').html('<div id="embed-captcha"><input type="hidden" name="captcha" class="form-control" data-rule="请完成验证码,验证码:required;" /> </div> <p id="wait" class="show">正在加载验证码......</p>');
var handlerEmbed = function (captchaObj) {
// 将验证码加到id为captcha的元素里同时会有三个input的值geetest_challenge, geetest_validate, geetest_seccode
geetInit = captchaObj;
captchaObj.appendTo("#embed-captcha");
captchaObj.onReady(function () {
$("#wait")[0].className = "hide";
});
captchaObj.onSuccess(function () {
var result = captchaObj.getValidate();
if (result) {
$('#embed-captcha input[name="captcha"]').val('ok');
}
});
// 更多接口参考http://www.geetest.com/install/sections/idx-client-sdk.html
};
Fast.api.ajax("/addons/geet/index/start", function (data) {
// 更多配置参数请参见http://www.geetest.com/install/sections/idx-client-sdk.html#config
// 使用initGeetest接口
// 参数1配置参数
// 参数2回调回调的第一个参数验证码对象之后可以使用它做appendTo之类的事件
initGeetest({
gt: data.gt,
challenge: data.challenge,
new_captcha: data.new_captcha,
product: "embed", // 产品形式包括floatembedpopup。注意只对PC版验证码有效
width: '100%',
offline: !data.success // 表示用户后台检测极验服务器是否宕机,一般不需要关注
}, handlerEmbed);
form.on("error.form", function (e, data) {
geetInit.reset();
});
return false;
});
});
});
window.UMEDITOR_HOME_URL = Config.__CDN__ + "/assets/addons/umeditor/";
require.config({
paths: {
'umeditor': '../addons/umeditor/umeditor.min',
'umeditor.config': '../addons/umeditor/umeditor.config',
'umeditor.lang': '../addons/umeditor/lang/zh-cn/zh-cn',
},
shim: {
'umeditor': {
deps: [
'umeditor.config',
'css!../addons/umeditor/themes/default/css/umeditor.css'
],
exports: 'UM',
},
'umeditor.lang': ['umeditor']
}
});
//修改上传的接口调用
require(['upload', 'umeditor', 'umeditor.lang'], function (Upload, UME, undefined) {
//监听上传文本框的事件
$(document).on("edui.file.change", ".edui-image-file", function (e, up, me, input, callback) {
for (var i = 0; i < this.files.length; i++) {
Upload.api.send(this.files[i], function (data) {
var url = data.url;
me.uploadComplete(JSON.stringify({url: url, state: "SUCCESS"}));
});
}
up.updateInput(input);
me.toggleMask("Loading....");
callback && callback();
});
//重写编辑器加载
UME.plugins['autoupload'] = function () {
var me = this;
me.setOpt('pasteImageEnabled', true);
me.setOpt('dropFileEnabled', true);
var sendAndInsertImage = function (file, editor) {
try {
Upload.api.send(file, function (data) {
var url = data.url;
editor.execCommand('insertimage', {
src: url,
_src: url
});
});
} catch (er) {
}
};
function getPasteImage(e) {
return e.clipboardData && e.clipboardData.items && e.clipboardData.items.length == 1 && /^image\//.test(e.clipboardData.items[0].type) ? e.clipboardData.items : null;
}
function getDropImage(e) {
return e.dataTransfer && e.dataTransfer.files ? e.dataTransfer.files : null;
}
me.addListener('ready', function () {
if (window.FormData && window.FileReader) {
var autoUploadHandler = function (e) {
var hasImg = false,
items;
//获取粘贴板文件列表或者拖放文件列表
items = e.type == 'paste' ? getPasteImage(e.originalEvent) : getDropImage(e.originalEvent);
if (items) {
var len = items.length,
file;
while (len--) {
file = items[len];
if (file.getAsFile)
file = file.getAsFile();
if (file && file.size > 0 && /image\/\w+/i.test(file.type)) {
sendAndInsertImage(file, me);
hasImg = true;
}
}
if (hasImg)
return false;
}
};
me.getOpt('pasteImageEnabled') && me.$body.on('paste', autoUploadHandler);
me.getOpt('dropFileEnabled') && me.$body.on('drop', autoUploadHandler);
//取消拖放图片时出现的文字光标位置提示
me.$body.on('dragover', function (e) {
if (e.originalEvent.dataTransfer.types[0] == 'Files') {
return false;
}
});
}
});
};
$(".editor").each(function () {
var id = $(this).attr("id");
$(this).removeClass('form-control');
UME.list[id] = UME.getEditor(id, {
serverUrl: Fast.api.fixurl('/addons/umeditor/api/'),
initialFrameWidth: '100%',
zIndex: 90,
xssFilterRules: false,
outputXssFilter: false,
inputXssFilter: false,
imageUrl: '',
imagePath: Config.upload.cdnurl
});
});
});
});

View File

@ -18,12 +18,17 @@
var initCommonSearch = function (pColumns, that) {
var vFormCommon = createFormCommon(pColumns, that);
var vModal = sprintf("<div class=\"commonsearch-table %s\">", that.options.searchFormVisible ? "" : "hidden");
var vModal = "<div class=\"commonsearch-table\">";
vModal += vFormCommon;
vModal += "</div>";
that.$container.prepend($(vModal));
that.$commonsearch = $(".commonsearch-table", that.$container);
var form = $("form.form-commonsearch", that.$commonsearch);
if(!that.options.searchFormVisible){
setTimeout(function () {
that.$commonsearch.addClass('hidden');
},100);
}
require(['form'], function (Form) {
Form.api.bindevent(form);
@ -51,7 +56,7 @@
return Template(that.options.searchFormTemplate, {columns: pColumns, table: that});
}
var htmlForm = [];
htmlForm.push(sprintf('<form class="form-horizontal form-commonsearch" novalidate method="post" action="%s" >', that.options.actionForm));
htmlForm.push(sprintf('<form class="%s" novalidate method="post" action="%s">', that.options.searchFormCss.form, that.options.actionForm));
htmlForm.push('<fieldset>');
if (that.options.titleForm.length > 0)
htmlForm.push(sprintf("<legend>%s</legend>", that.options.titleForm));
@ -66,9 +71,9 @@
vObjCol.operate = that.options.renderDefault && operate ? operate : (typeof vObjCol.operate === 'undefined' ? '=' : vObjCol.operate);
ColumnsForSearch.push(vObjCol);
htmlForm.push('<div class="form-group col-xs-12 col-sm-6 col-md-4 col-lg-3">');
htmlForm.push(sprintf('<label for="%s" class="control-label col-xs-4">%s</label>', vObjCol.field, vObjCol.title));
htmlForm.push('<div class="col-xs-8">');
htmlForm.push(sprintf('<div class="%s">', that.options.searchFormCss.form_group));
htmlForm.push(sprintf('<label for="%s" class="%s">%s</label>', vObjCol.field, that.options.searchFormCss.label, vObjCol.title));
htmlForm.push(sprintf('<div class="%s">', that.options.searchFormCss.container));
vObjCol.operate = vObjCol.operate ? vObjCol.operate.toUpperCase() : '=';
htmlForm.push(sprintf('<input type="hidden" class="form-control operate" name="%s-operate" data-name="%s" value="%s" readonly>', vObjCol.field, vObjCol.field, vObjCol.operate));
@ -120,7 +125,8 @@
htmlForm.push('</div>');
}
}
htmlForm.push('<div class="form-group col-xs-12 col-sm-6 col-md-4 col-lg-3">');
htmlForm.push(sprintf('<div class="%s">', that.options.searchFormCss.form_group));
htmlForm.push(sprintf('<label class="%s">&nbsp;</label>', that.options.searchFormCss.label_btn));
htmlForm.push(createFormBtn(that).join(''));
htmlForm.push('</div>');
htmlForm.push('</div>');
@ -134,7 +140,7 @@
var htmlBtn = [];
var searchSubmit = that.options.formatCommonSubmitButton();
var searchReset = that.options.formatCommonResetButton();
htmlBtn.push('<div class="col-sm-8 col-xs-offset-4">');
htmlBtn.push(sprintf('<div class="%s">', that.options.searchFormCss.container));
htmlBtn.push(sprintf('<button type="submit" class="btn btn-success" formnovalidate>%s</button> ', searchSubmit));
htmlBtn.push(sprintf('<button type="reset" class="btn btn-default" >%s</button> ', searchReset));
htmlBtn.push('</div>');
@ -379,8 +385,8 @@
[value, item, i], value);
if (!($.inArray(key, that.header.fields) !== -1 &&
(typeof value === 'string' || typeof value === 'number') &&
(value + '').toLowerCase().indexOf(fval) !== -1)) {
(typeof value === 'string' || typeof value === 'number') &&
(value + '').toLowerCase().indexOf(fval) !== -1)) {
return false;
}
}

View File

@ -1,4 +1,4 @@
define(['jquery', 'bootstrap', 'toastr', 'layer', 'lang'], function ($, undefined, Toastr, Layer, Lang) {
define(['jquery', 'bootstrap', 'toastr', 'layer', 'lang', 'slimscroll'], function ($, undefined, Toastr, Layer, Lang, slimScroll) {
var Fast = {
config: {
//toastr默认配置
@ -6,7 +6,7 @@ define(['jquery', 'bootstrap', 'toastr', 'layer', 'lang'], function ($, undefine
"closeButton": true,
"debug": false,
"newestOnTop": false,
"progressBar": false,
"progressBar": true,
"positionClass": "toast-top-center",
"preventDuplicates": false,
"onclick": null,
@ -114,7 +114,7 @@ define(['jquery', 'bootstrap', 'toastr', 'layer', 'lang'], function ($, undefine
},
//打开一个弹出窗口
open: function (url, title, options) {
title = title ? title : "";
title = options.title ? options.title : (title ? title : "");
url = Fast.api.fixurl(url);
url = url + (url.indexOf("?") > -1 ? "&" : "?") + "dialog=1";
var area = [$(window).width() > 800 ? '800px' : '95%', $(window).height() > 600 ? '600px' : '95%'];
@ -314,6 +314,17 @@ define(['jquery', 'bootstrap', 'toastr', 'layer', 'lang'], function ($, undefine
});
//公共代码
$(function ($) {
if (self === top) {
$('div[role="main"]').slimScroll({height: $(window).height() + 'px'});
} else {
var ScrollHeight = $('iframe', parent.document).height();
if (!ScrollHeight || ScrollHeight === 100) {
ScrollHeight = $('.content-wrapper', parent.document).height();
}
$('div[role="main"]').slimScroll({height: ScrollHeight + 'px'});
}
});
//配置Toastr的参数
Toastr.options = Fast.config.toastr;
}

View File

@ -33,6 +33,7 @@ require.config({
'bootstrap-table-export': '../libs/bootstrap-table/dist/extensions/export/bootstrap-table-export.min',
'bootstrap-table-mobile': '../libs/bootstrap-table/dist/extensions/mobile/bootstrap-table-mobile',
'bootstrap-table-lang': '../libs/bootstrap-table/dist/locale/bootstrap-table-zh-CN',
'bootstrap-slider': '../libs/bootstrap-slider/bootstrap-slider',
'tableexport': '../libs/tableExport.jquery.plugin/tableExport.min',
'dragsort': '../libs/fastadmin-dragsort/jquery.dragsort',
'sortable': '../libs/Sortable/Sortable.min',

File diff suppressed because it is too large Load Diff

View File

@ -12,9 +12,244 @@ define(['jquery', 'bootstrap', 'upload', 'validator'], function ($, undefined, U
validClass: 'has-success',
invalidClass: 'has-error',
bindClassTo: '.form-group',
formClass: 'n-default n-bootstrap',
msgClass: 'n-right',
formClass: 'n-yellow n-bootstrap',
msgClass: 'n-top',
theme: 'yellow_top',
stopOnError: true,
rules: {
mobile: [/^1[3-9]\d{9}$/, "请填写有效的手机号"],
email: [/^[0-9A-Za-z][\.-_0-9A-Za-z]*@[0-9A-Za-z]+(\.[0-9A-Za-z]+)+$/, "请填写有效的邮箱地址"],
chinese: [/^[\u0391-\uFFE5]+$/, "请填写中文字符"],
money: [/^(?:0|[1-9]\d*)(?:\.\d{1,2})?$/, "请填写有效的金额"],
ip: [/^((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[0-9]{1,2})\.){3}(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[0-9]{1,2})$/i, '请填写有效的 IP 地址'],
// 身份证
idcard: function (element) {
var value = element.value,
isValid = true;
var cityCode = {11: "北京", 12: "天津", 13: "河北", 14: "山西", 15: "内蒙古", 21: "辽宁", 22: "吉林", 23: "黑龙江 ", 31: "上海", 32: "江苏", 33: "浙江", 34: "安徽", 35: "福建", 36: "江西", 37: "山东", 41: "河南", 42: "湖北 ", 43: "湖南", 44: "广东", 45: "广西", 46: "海南", 50: "重庆", 51: "四川", 52: "贵州", 53: "云南", 54: "西藏 ", 61: "陕西", 62: "甘肃", 63: "青海", 64: "宁夏", 65: "新疆", 71: "台湾", 81: "香港", 82: "澳门", 91: "国外 "};
/* 15 (dddddd yymmdd xx g) g
* 18位校验规则 (dddddd yyyymmdd xxx p) xxx奇数为男偶数为女p校验位
校验位公式C17 = C[ MOD( (Ci*Wi), 11) ]
i----表示号码字符从由至左包括校验码在内的位置序号
Wi 7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4 2 1
Ci 1 0 X 9 8 7 6 5 4 3 2
*/
var rFormat = /^\d{6}(19|20)\d{2}(0[1-9]|1[012])(0[1-9]|[12]\d|3[01])\d{3}(\d|X)$|^\d{6}\d{2}(0[1-9]|1[012])(0[1-9]|[12]\d|3[01])\d{3}$/; // 格式验证
if (!rFormat.test(value) || !cityCode[value.substr(0, 2)]) {
isValid = false;
}
// 18位身份证需要验证最后一位校验位
else if (value.length === 18) {
var Wi = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2, 1]; // 加权因子
var Ci = "10X98765432"; // 校验字符
// 加权求和
var sum = 0;
for (var i = 0; i < 17; i++) {
sum += value.charAt(i) * Wi[i];
}
// 计算校验值
var C17 = Ci.charAt(sum % 11);
// 与校验位比对
if (C17 !== value.charAt(17)) {
isValid = false;
}
}
return isValid || "请填写正确的身份证号码";
},
// 银行卡(借记卡、贷记卡)
bankcard: function (element) {
var value = element.value.replace(/\s/g, ''),
isValid = true,
rFormat = /^[\d]{12,19}$/;
if (!rFormat.test(value)) {
isValid = false;
} else {
var arr = value.split('').reverse(),
i = arr.length,
temp,
sum = 0;
while (i--) {
if (i % 2 === 0) {
sum += +arr[i];
} else {
temp = +arr[i] * 2;
sum += temp % 10;
if (temp > 9) sum += 1;
}
}
if (sum % 10 !== 0) {
isValid = false;
}
}
return isValid || "请填写有效的银行卡号";
},
// 信用卡
creditcard: function (element, params) {
var value = element.value,
validTypes = 0x0000,
types = {
mastercard: 0x0001,
visa: 0x0002,
amex: 0x0004,
dinersclub: 0x0008,
enroute: 0x0010,
discover: 0x0020,
jcb: 0x0040,
unknown: 0x0080
};
if (/[^0-9\-]+/.test(value)) {
return false;
}
value = value.replace(/\D/g, "");
if (!params) {
validTypes = 0x0001 | 0x0002 | 0x0004 | 0x0008 | 0x0010 | 0x0020 | 0x0040 | 0x0080;
} else {
for (var i = 0; i < parmas.length; i++) {
validTypes |= types[params[i]];
}
}
if (validTypes & 0x0001 && /^(5[12345])/.test(value)) { //mastercard
return value.length === 16;
}
if (validTypes & 0x0002 && /^(4)/.test(value)) { //visa
return value.length === 16;
}
if (validTypes & 0x0004 && /^(3[47])/.test(value)) { //amex
return value.length === 15;
}
if (validTypes & 0x0008 && /^(3(0[012345]|[68]))/.test(value)) { //dinersclub
return value.length === 14;
}
if (validTypes & 0x0010 && /^(2(014|149))/.test(value)) { //enroute
return value.length === 15;
}
if (validTypes & 0x0020 && /^(6011)/.test(value)) { //discover
return value.length === 16;
}
if (validTypes & 0x0040 && /^(3)/.test(value)) { //jcb
return value.length === 16;
}
if (validTypes & 0x0040 && /^(2131|1800)/.test(value)) { //jcb
return value.length === 15;
}
if (validTypes & 0x0080) { //unknown
return true;
}
return "请填写有效的信用卡号";
},
// 组织机构代码证
orgcode: function (element) {
var value = element.value,
isValid = true,
rFormat = /^[A-Z\d]{8}-[X\d]/;
if (!rFormat.test(value)) {
isValid = false;
} else {
var Wi = [3, 7, 9, 10, 5, 8, 4, 2];
var Ci = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
// 加权求和
var sum = 0;
for (var i = 0; i < 8; i++) {
sum += Ci.indexOf(value.charAt(i)) * Wi[i];
}
// 计算校验值: C9 = 11 - MOD ( ∑(Ci*Wi), 11 )
var C9 = 11 - (sum % 11);
if (C9 === 10) C9 = 'X';
else if (C9 === 11) C9 = 0;
C9 = '' + C9;
// 与校验位比对
if (C9 !== value.charAt(9)) {
isValid = false;
}
}
return isValid || "请填写正确的组织机构代码";
},
// 营业执照号
bizcode: function (element) {
var value = element.value,
isValid = true,
rFormat = /^[1-6]\d{14}$/;
// 共15位6位首次登记机关代码 + 8位顺序码 + 校验位
if (!rFormat.test(value)) {
isValid = false;
} else {
var s = [],
p = [10];
for (var i = 0; i < 15; i++) {
s[i] = (p[i] % 11) + (+value.charAt(i));
p[i + 1] = (s[i] % 10 || 10) * 2;
}
if (1 !== s[14] % 10) {
isValid = false;
}
}
return isValid || "请填写正确的营业执照号";
},
// 统一社会信用代码
unicode: function (element) {
var value = element.value.replace(/^\s*|\s*$/g, ''),
isValid = true,
rFormat = /^[1-9A-GV][1239][1-9]\d{5}[A-Z\d]{8}[X\d][Y\d]/;
if (!rFormat.test(value)) {
isValid = false;
} else {
var code, Wi, Ci, sum, C9, C18;
// 计算组织机构代码校验位C9 = 11 - MOD ( ∑(Ci*Wi), 11 )
code = value.slice(9, 17);
Wi = [3, 7, 9, 10, 5, 8, 4, 2];
Ci = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
// 加权求和
sum = 0;
for (var i = 0; i < Wi.length; i++) {
sum += Ci.indexOf(code.charAt(i)) * Wi[i];
}
C9 = 11 - (sum % 11);
if (C9 === 10) C9 = 'X';
else if (C9 === 11) C9 = 0;
C9 = '' + C9;
// 与校验位比对
if (C9 !== code.charAt(9)) {
isValid = false;
}
if (isValid) {
// 计算最后校验位C18 = 31 - MOD ( ∑(Ci*Wi), 31 )
code = value.slice(0, 17);
Wi = [1, 3, 9, 27, 19, 26, 16, 17, 20, 29, 25, 13, 8, 24, 10, 30, 28];
Ci = "0123456789ABCDEFGHJKLMNPQRTUWXY";
// 加权求和
sum = 0;
for (var i = 0; i < Wi.length; i++) {
sum += Ci.indexOf(code.charAt(i)) * Wi[i];
}
C18 = 31 - (sum % 31);
if (C18 === 30) C18 = 'Y';
else if (C18 === 31) C18 = 0;
C18 = '' + C18;
// 与校验位比对
if (C18 !== code.charAt(18)) {
isValid = false;
}
}
}
return isValid || "请填写正确的统一社会信用代码";
}
},
display: function (elem) {
return $(elem).closest('.form-group').find(".control-label").text().replace(/\:/, '');
},
@ -366,6 +601,20 @@ define(['jquery', 'bootstrap', 'upload', 'validator'], function ($, undefined, U
},
bindevent: function (form) {
},
slider: function (form) {
if ($(".slider", form).size() > 0) {
require(['bootstrap-slider'], function () {
$('.slider').removeClass('hidden').css('width', function (index, value) {
return $(this).parents('.form-control').width();
}).slider().on('slide', function (ev) {
var data = $(this).data();
if (typeof data.unit !== 'undefined') {
$(this).parents('.form-control').siblings('.value').text(ev.value + data.unit);
}
});
});
}
}
},
api: {
@ -465,6 +714,8 @@ define(['jquery', 'bootstrap', 'upload', 'validator'], function ($, undefined, U
events.fieldlist(form);
events.slider(form);
events.switcher(form);
},
custom: {}

File diff suppressed because it is too large Load Diff

View File

@ -44,6 +44,13 @@ define(['jquery', 'bootstrap', 'moment', 'moment/locale/zh-cn', 'bootstrap-table
import_url: '',
multi_url: '',
dragsort_url: 'ajax/weigh',
},
searchFormCss: {
form: 'form-commonsearch',
form_group: 'form-group col-xs-12 col-sm-6 col-md-4 col-lg-3',
label: 'control-label',
label_btn: 'control-label hidden-xs',
container: 'pp_container',
}
},
// Bootstrap-table 列配置
@ -123,6 +130,9 @@ define(['jquery', 'bootstrap', 'moment', 'moment/locale/zh-cn', 'bootstrap-table
}
//当内容渲染完成后
table.on('post-body.bs.table', function (e, settings, json, xhr) {
var ScrollHeight = self == top ? $(window).height() : $('.content-wrapper', parent.document).height();
table.closest('#main').height(ScrollHeight);
table.closest('.slimScrollDiv').height(ScrollHeight);
$(Table.config.refreshbtn, toolbar).find(".fa").removeClass("fa-spin");
$(Table.config.disabledbtn, toolbar).toggleClass('disabled', true);
if ($(Table.config.firsttd, table).find("input[type='checkbox'][data-index]").size() > 0) {
@ -152,6 +162,11 @@ define(['jquery', 'bootstrap', 'moment', 'moment/locale/zh-cn', 'bootstrap-table
});
});
}
if (table.find("div.pre").size() > 0) {
require(['slimscroll'], function () {
$('div.pre').slimScroll({width: '300px', height: '50px'});
});
}
});
// 处理选中筛选框后按钮的状态统一变更
table.on('check.bs.table uncheck.bs.table check-all.bs.table uncheck-all.bs.table', function () {