作者 Karson

新增CRUD多项字段和表名识别,可自动生成下拉列表、筛选框、单选框、分类列表、日期时间型等等

新增启用nice-validator表单验证功能
新增后台增改时对数组和日期字段的处理
新增test表用于开发测试
新增表单生成禁用字符编码的方法
禁用开发模式的客户端JS和CSS缓存
修复微信支付初始化变量的错误
修复php think min在Win下的错误提示
修复不同语言下HTML的语言标识错误
@@ -68,7 +68,7 @@ class Crud extends Command @@ -68,7 +68,7 @@ class Crud extends Command
68 //非覆盖模式时如果存在控制器文件则报错 68 //非覆盖模式时如果存在控制器文件则报错
69 if (is_file($controllerFile) && !$force) 69 if (is_file($controllerFile) && !$force)
70 { 70 {
71 - throw new Exception('controller already exists'); 71 + throw new Exception('controller already exists!\nIf you need to rebuild again, use the parameter --force=true ');
72 } 72 }
73 73
74 //模型默认以表名进行处理,以下划线进行分隔,如果需要自定义则需要传入model,不支持目录层级 74 //模型默认以表名进行处理,以下划线进行分隔,如果需要自定义则需要传入model,不支持目录层级
@@ -89,9 +89,11 @@ class Crud extends Command @@ -89,9 +89,11 @@ class Crud extends Command
89 //非覆盖模式时如果存在模型文件则报错 89 //非覆盖模式时如果存在模型文件则报错
90 if (is_file($modelFile) && !$force) 90 if (is_file($modelFile) && !$force)
91 { 91 {
92 - throw new Exception('model already exists'); 92 + throw new Exception('model already exists!\nIf you need to rebuild again, use the parameter --force=true ');
93 } 93 }
94 94
  95 + require $adminPath . 'common.php';
  96 +
95 //从数据库中获取表字段信息 97 //从数据库中获取表字段信息
96 $columnList = Db::query("SELECT * FROM `information_schema`.`columns` WHERE TABLE_SCHEMA = ? AND table_name = ? ORDER BY ORDINAL_POSITION", [$dbname, $tableName]); 98 $columnList = Db::query("SELECT * FROM `information_schema`.`columns` WHERE TABLE_SCHEMA = ? AND table_name = ? ORDER BY ORDINAL_POSITION", [$dbname, $tableName]);
97 $fields = []; 99 $fields = [];
@@ -106,194 +108,256 @@ class Crud extends Command @@ -106,194 +108,256 @@ class Crud extends Command
106 $langList = []; 108 $langList = [];
107 $field = 'id'; 109 $field = 'id';
108 $order = 'id'; 110 $order = 'id';
  111 + $priDefined = FALSE;
109 112
110 - //循环所有字段,开始构造视图的HTML和JS信息  
111 - foreach ($columnList as $k => $v) 113 + try
112 { 114 {
113 - $field = $v['COLUMN_NAME'];  
114 - $fieldLang = ucfirst($field);  
115 - // 语言列表  
116 - if ($v['COLUMN_COMMENT'] != '')  
117 - {  
118 - $langList[] = $this->getLangItem($field, $v['COLUMN_COMMENT']);  
119 - }  
120 - if ($v['COLUMN_KEY'] != 'PRI') 115 + Form::setEscapeHtml(false);
  116 +
  117 + //循环所有字段,开始构造视图的HTML和JS信息
  118 + foreach ($columnList as $k => $v)
121 { 119 {
122 - $inputType = 'text';  
123 - $step = 0;  
124 - switch ($v['DATA_TYPE']) 120 + $field = $v['COLUMN_NAME'];
  121 + $itemArr = [];
  122 + // 这里构建Enum和Set类型的列表数据
  123 + if (in_array($v['DATA_TYPE'], ['enum', 'set']))
125 { 124 {
126 - case 'bigint':  
127 - case 'int':  
128 - case 'mediumint':  
129 - case 'smallint':  
130 - case 'tinyint':  
131 - $inputType = 'number';  
132 - break;  
133 - case 'enum':  
134 - case 'set':  
135 - $inputType = 'select';  
136 - break;  
137 - case 'decimal':  
138 - case 'double':  
139 - case 'float':  
140 - $inputType = 'number';  
141 - $step = "0." . str_repeat(0, $v['NUMERIC_SCALE'] - 1) . "1";  
142 - case 'text':  
143 - $inputType = 'textarea';  
144 - default:  
145 - break; 125 + $itemArr = substr($v['COLUMN_TYPE'], strlen($v['DATA_TYPE']) + 1, -1);
  126 + $itemArr = explode(',', str_replace("'", '', $itemArr));
146 } 127 }
147 - if (substr($field, -4) == 'time') 128 + // 语言列表
  129 + if ($v['COLUMN_COMMENT'] != '')
148 { 130 {
149 - $inputType = 'datetime'; 131 + $langList[] = $this->getLangItem($field, $v['COLUMN_COMMENT']);
150 } 132 }
151 -  
152 - if ($inputType == 'select') 133 + //createtime和updatetime是保留字段不能修改和添加
  134 + if ($v['COLUMN_KEY'] != 'PRI' && !in_array($field, ['createtime', 'updatetime']))
153 { 135 {
154 - $itemlist = substr($v['COLUMN_TYPE'], strlen($v['DATA_TYPE']) + 1, -1);  
155 - $itemlist = str_replace("'", '', $itemlist);  
156 - $attr = "'id'=>'c-$field','class'=>'form-control selectpicker'";  
157 - if ($v['DATA_TYPE'] == 'enum') 136 + $inputType = $this->getFieldType($v);
  137 +
  138 + // 如果是number类型时增加一个步长
  139 + $step = $inputType == 'number' && $v['NUMERIC_SCALE'] > 0 ? "0." . str_repeat(0, $v['NUMERIC_SCALE'] - 1) . "1" : 0;
  140 +
  141 + $attrArr = ['id' => "c-{$field}"];
  142 + $cssClassArr = ['form-control'];
  143 + $fieldName = "row[{$field}]";
  144 + $defaultValue = $v['COLUMN_DEFAULT'];
  145 + $editValue = "{\$row.{$field}}";
  146 + // 如果默认值为空,则是一个必选项
  147 + if ($v['COLUMN_DEFAULT'] == '')
158 { 148 {
159 - $attr .= ",'multiple'=>''"; 149 + $attrArr['required'] = '';
160 } 150 }
161 - if ($v['COLUMN_DEFAULT'] == '') 151 + if ($field == 'status' && in_array($inputType, ['text', 'number']))
162 { 152 {
163 - $attr .= ",'required'=>''"; 153 + //如果状态类型不是enum或set
  154 + $itemArr = !$itemArr ? ['normal', 'hidden'] : $itemArr;
  155 + $inputType = 'radio';
164 } 156 }
165 - $formAddElement = "{:build_select('row[$field]', '{$itemlist}', null, [{$attr}])}";  
166 - $formEditElement = "{:build_select('row[$field]', '{$itemlist}', \$row['$field'], [{$attr}])}";  
167 - }  
168 - else  
169 - {  
170 - //CSS类名  
171 - $cssClass = ['form-control'];  
172 - $cssClass[] = substr($field, -4) == 'time' ? 'datetimepicker' : '';  
173 - $cssClass[] = $v['DATA_TYPE'] == 'text' ? 'summernote' : '';  
174 - $cssClass[] = substr($field, -3) == '_id' ? 'typeahead' : '';  
175 - $cssClass[] = substr($field, -4) == '_ids' ? 'tagsinput' : '';  
176 - $cssClass = array_filter($cssClass);  
177 - //因为有自动完成可输入其它内容  
178 - if (array_intersect($cssClass, ['typeahead', 'tagsinput'])) 157 + if ($inputType == 'select')
179 { 158 {
180 - $inputType = 'text';  
181 - $step = 0; 159 + $cssClassArr[] = 'selectpicker';
  160 + $attrArr['class'] = implode(' ', $cssClassArr);
  161 + if ($v['DATA_TYPE'] == 'set')
  162 + {
  163 + $attrArr['multiple'] = '';
  164 + $fieldName.="[]";
  165 + }
  166 + $attrStr = $this->getArrayString($attrArr);
  167 + $itemArr = $this->getLangArray($itemArr, FALSE);
  168 + $itemString = $this->getArrayString($itemArr);
  169 + $formAddElement = "{:build_select('{$fieldName}', [{$itemString}], '{$defaultValue}', [{$attrStr}])}";
  170 + $formEditElement = "{:build_select('{$fieldName}', [{$itemString}], \$row.{$field}, [{$attrStr}])}";
182 } 171 }
183 - $attr = ['id' => "c-{$field}", 'class' => implode(' ', $cssClass)];  
184 - if ($step) 172 + else if ($inputType == 'datetime')
185 { 173 {
186 - $attr['step'] = $step; 174 + $cssClassArr[] = 'datetimepicker';
  175 + $attrArr['class'] = implode(' ', $cssClassArr);
  176 + $format = "YYYY-MM-DD HH:mm:ss";
  177 + $phpFormat = "Y-m-d H:i:s";
  178 + $fieldFunc = '';
  179 + switch ($v['DATA_TYPE'])
  180 + {
  181 + case 'year';
  182 + $format = "YYYY";
  183 + $phpFormat = 'Y';
  184 + break;
  185 + case 'date';
  186 + $format = "YYYY-MM-DD";
  187 + $phpFormat = 'Y-m-d';
  188 + break;
  189 + case 'time';
  190 + $format = "HH:mm:ss";
  191 + $phpFormat = 'H:i:s';
  192 + break;
  193 + case 'timestamp';
  194 + $fieldFunc = 'datetime';
  195 + case 'datetime';
  196 + $format = "YYYY-MM-DD HH:mm:ss";
  197 + $phpFormat = 'Y-m-d H:i:s';
  198 + break;
  199 + default:
  200 + $fieldFunc = 'datetime';
  201 + break;
  202 + }
  203 + $defaultDateTime = "{:date('{$phpFormat}')}";
  204 + $attrArr['data-date-format'] = $format;
  205 + $attrArr['data-use-current'] = "true";
  206 + $fieldFunc = $fieldFunc ? "|{$fieldFunc}" : "";
  207 + $formAddElement = Form::text($fieldName, $defaultDateTime, $attrArr);
  208 + $formEditElement = Form::text($fieldName, "{\$row.{$field}{$fieldFunc}}", $attrArr);
187 } 209 }
188 - //如果是图片则额外附加  
189 - if (substr($field, -5) == 'image' || substr($field, -6) == 'avatar') 210 + else if ($inputType == 'checkbox')
190 { 211 {
191 - //$attr['data-plupload-id'] = "plupload-{$field}-text";  
192 - $attr['size'] = 50; 212 + $fieldName.="[]";
  213 + $itemArr = $this->getLangArray($itemArr, FALSE);
  214 + $itemString = $this->getArrayString($itemArr);
  215 + $formAddElement = "{:build_checkboxs('{$fieldName}', [{$itemString}], '{$defaultValue}')}";
  216 + $formEditElement = "{:build_checkboxs('{$fieldName}', [{$itemString}], \$row.{$field})}";
193 } 217 }
194 - $fieldFunc = substr($field, -4) == 'time' ? "|datetime" : "";  
195 - if ($inputType == 'textarea') 218 + else if ($inputType == 'radio')
196 { 219 {
197 - $formAddElement = Form::textarea("row[{$field}]", $v['COLUMN_DEFAULT'], $attr);  
198 - $formEditElement = Form::textarea("row[{$field}]", "{\$row.{$field}{$fieldFunc}}", $attr); 220 + $itemArr = $this->getLangArray($itemArr, FALSE);
  221 + $itemString = $this->getArrayString($itemArr);
  222 + $defaultValue = $defaultValue ? $defaultValue : key($itemArr);
  223 + $formAddElement = "{:build_radios('{$fieldName}', [{$itemString}], '{$defaultValue}')}";
  224 + $formEditElement = "{:build_radios('{$fieldName}', [{$itemString}], \$row.{$field})}";
199 } 225 }
200 - else 226 + else if ($inputType == 'textarea' || ($inputType == 'text' && $v['CHARACTER_MAXIMUM_LENGTH'] >= 255))
201 { 227 {
202 - $formAddElement = Form::input($inputType, "row[{$field}]", $v['COLUMN_DEFAULT'], $attr);  
203 - $formEditElement = Form::input($inputType, "row[{$field}]", "{\$row.{$field}{$fieldFunc}}", $attr); 228 + $cssClassArr[] = substr($field, -7) == 'content' ? 'summernote' : '';
  229 + $attrArr['class'] = implode(' ', $cssClassArr);
  230 + $attrArr['rows'] = 5;
  231 + $formAddElement = Form::textarea($fieldName, $defaultValue, $attrArr);
  232 + $formEditElement = Form::textarea($fieldName, $editValue, $attrArr);
204 } 233 }
205 -  
206 - if (substr($field, -5) == 'image' || substr($field, -6) == 'avatar') 234 + else if ($field == 'category_id' || $field == 'category_ids')
207 { 235 {
208 - //如果是图片或头像  
209 - $formAddElement = $this->getImageUpload($field, $formAddElement);  
210 - $formEditElement = $this->getImageUpload($field, $formEditElement); 236 + $type = $table;
  237 + if ($field == 'category_ids')
  238 + {
  239 + $attrArr['multiple'] = '';
  240 + }
  241 + $attrStr = $this->getArrayString($attrArr);
  242 + $formAddElement = "{:build_category_select('{$fieldName}', '{$type}', '{$defaultValue}', [{$attrStr}])}";
  243 + $formEditElement = "{:build_category_select('{$fieldName}', '{$type}', \$row.{$field}, [{$attrStr}])}";
211 } 244 }
212 - else if ($field == 'status') 245 + else
213 { 246 {
214 - //如果是状态字段  
215 - $formAddElement = "{:build_radios('row[status]', ['normal'=>__('Normal'), 'hidden'=>__('Hidden')])}";  
216 - $formEditElement = "{:build_radios('row[status]', ['normal'=>__('Normal'), 'hidden'=>__('Hidden')], \$row['status'])}"; 247 + //CSS类名
  248 + $cssClassArr[] = substr($field, -3) == '_id' ? 'typeahead' : '';
  249 + $cssClassArr[] = substr($field, -4) == '_ids' ? 'tagsinput' : '';
  250 + $cssClassArr = array_filter($cssClassArr);
  251 + //因为有自动完成可输入其它内容
  252 + $step = array_intersect($cssClassArr, ['typeahead', 'tagsinput']) ? 0 : $step;
  253 + $attrArr['class'] = implode(' ', $cssClassArr);
  254 +
  255 + $isUpload = substr($field, -4) == 'file' || substr($field, -5) == 'image' || substr($field, -6) == 'avatar' ? TRUE : FALSE;
  256 + //如果是步长则加上步长
  257 + if ($step)
  258 + {
  259 + $attrArr['step'] = $step;
  260 + }
  261 + //如果是图片加上个size
  262 + if ($isUpload)
  263 + {
  264 + $attrArr['size'] = 50;
  265 + }
  266 +
  267 + $formAddElement = Form::input($inputType, $fieldName, $defaultValue, $attrArr);
  268 + $formEditElement = Form::input($inputType, $fieldName, $editValue, $attrArr);
  269 +
  270 + //如果是图片或文件
  271 + if ($isUpload)
  272 + {
  273 + $formAddElement = $this->getImageUpload($field, $formAddElement);
  274 + $formEditElement = $this->getImageUpload($field, $formEditElement);
  275 + }
217 } 276 }
  277 + //构造添加和编辑HTML信息
  278 + $addList[] = $this->getFormGroup($field, $formAddElement);
  279 + $editList[] = $this->getFormGroup($field, $formEditElement);
218 } 280 }
219 - //构造添加和编辑HTML信息  
220 - $addList[] = $this->getFormGroup($field, $formAddElement);  
221 - $editList[] = $this->getFormGroup($field, $formEditElement);  
222 - }  
223 281
224 - //过滤text类型字段  
225 - if ($v['DATA_TYPE'] != 'text')  
226 - {  
227 - //主键  
228 - if ($v['COLUMN_KEY'] == 'PRI') 282 + //过滤text类型字段
  283 + if ($v['DATA_TYPE'] != 'text')
229 { 284 {
230 - $javascriptList[] = "{field: 'state', checkbox: true}"; 285 + //主键
  286 + if ($v['COLUMN_KEY'] == 'PRI' && !$priDefined)
  287 + {
  288 + $priDefined = TRUE;
  289 + $javascriptList[] = "{field: 'state', checkbox: true}";
  290 + }
  291 + //构造JS列信息
  292 + $javascriptList[] = $this->getJsColumn($field);
  293 + //排序方式,如果有weigh则按weigh,否则按主键排序
  294 + $order = $field == 'weigh' ? 'weigh' : $order;
231 } 295 }
232 - //构造JS列信息  
233 - $javascriptList[] = $this->getJsColumn($field);  
234 - //排序方式,如果有weigh则按weigh,否则按主键排序  
235 - $order = $field == 'weigh' ? 'weigh' : $order; 296 + }
  297 + //JS最后一列加上操作列
  298 + $javascriptList[] = str_repeat(" ", 24) . "{field: 'operate', title: __('Operate'), events: Table.api.events.operate, formatter: Table.api.formatter.operate}";
  299 + $addList = implode("\n", array_filter($addList));
  300 + $editList = implode("\n", array_filter($editList));
  301 + $javascriptList = implode(",\n", array_filter($javascriptList));
  302 + $langList = implode(",\n", array_filter($langList));
  303 +
  304 + //表注释
  305 + $tableComment = $tableInfo['Comment'];
  306 + $tableComment = mb_substr($tableComment, -1) == '表' ? mb_substr($tableComment, 0, -1) . '管理' : $tableComment;
  307 +
  308 + //最终将生成的文件路径
  309 + $controllerFile = $adminPath . 'controller' . DS . $controllerFile;
  310 + $javascriptFile = ROOT_PATH . 'public' . DS . 'assets' . DS . 'js' . DS . 'backend' . DS . $controllerUrl . '.js';
  311 + $addFile = $adminPath . 'view' . DS . $controllerUrl . DS . 'add.html';
  312 + $editFile = $adminPath . 'view' . DS . $controllerUrl . DS . 'edit.html';
  313 + $indexFile = $adminPath . 'view' . DS . $controllerUrl . DS . 'index.html';
  314 + $langFile = $adminPath . 'lang' . DS . Lang::detect() . DS . $controllerUrl . '.php';
  315 +
  316 + $appNamespace = Config::get('app_namespace');
  317 + $moduleName = 'admin';
  318 + $controllerNamespace = "{$appNamespace}\\{$moduleName}\\controller" . ($controllerDir ? "\\" : "") . str_replace('/', "\\", $controllerDir);
  319 + $modelNamespace = "{$appNamespace}\\" . ($local ? $moduleName : "common") . "\\model";
  320 +
  321 + $data = [
  322 + 'controllerNamespace' => $controllerNamespace,
  323 + 'modelNamespace' => $modelNamespace,
  324 + 'controllerUrl' => $controllerUrl,
  325 + 'controllerDir' => $controllerDir,
  326 + 'controllerName' => $controllerName,
  327 + 'modelName' => $modelName,
  328 + 'tableComment' => $tableComment,
  329 + 'iconName' => $iconName,
  330 + 'order' => $order,
  331 + 'table' => $table,
  332 + 'tableName' => $tableName,
  333 + 'addList' => $addList,
  334 + 'editList' => $editList,
  335 + 'javascriptList' => $javascriptList,
  336 + 'langList' => $langList,
  337 + 'modelAutoWriteTimestamp' => in_array('createtime', $fields) || in_array('updatetime', $fields) ? "'int'" : 'false',
  338 + 'createTime' => in_array('createtime', $fields) ? "'createtime'" : 'false',
  339 + 'updateTime' => in_array('updatetime', $fields) ? "'updatetime'" : 'false',
  340 + ];
  341 +
  342 + // 生成控制器文件
  343 + $result = $this->writeToFile('controller', $data, $controllerFile);
  344 + // 生成模型文件
  345 + $result = $this->writeToFile('model', $data, $modelFile);
  346 + // 生成视图文件
  347 + $result = $this->writeToFile('add', $data, $addFile);
  348 + $result = $this->writeToFile('edit', $data, $editFile);
  349 + $result = $this->writeToFile('index', $data, $indexFile);
  350 + // 生成JS文件
  351 + $result = $this->writeToFile('javascript', $data, $javascriptFile);
  352 + // 生成语言文件
  353 + if ($langList)
  354 + {
  355 + $result = $this->writeToFile('lang', $data, $langFile);
236 } 356 }
237 } 357 }
238 - //JS最后一列加上操作列  
239 - $javascriptList[] = str_repeat(" ", 24) . "{field: 'operate', title: __('Operate'), events: Table.api.events.operate, formatter: Table.api.formatter.operate}";  
240 - $addList = implode("\n", array_filter($addList));  
241 - $editList = implode("\n", array_filter($editList));  
242 - $javascriptList = implode(",\n", array_filter($javascriptList));  
243 - $langList = implode(",\n", array_filter($langList));  
244 -  
245 - //表注释  
246 - $tableComment = $tableInfo['Comment'];  
247 - $tableComment = mb_substr($tableComment, -1) == '表' ? mb_substr($tableComment, 0, -1) . '管理' : $tableComment;  
248 -  
249 - //最终将生成的文件路径  
250 - $controllerFile = $adminPath . 'controller' . DS . $controllerFile;  
251 - $javascriptFile = ROOT_PATH . 'public' . DS . 'assets' . DS . 'js' . DS . 'backend' . DS . $controllerUrl . '.js';  
252 - $addFile = $adminPath . 'view' . DS . $controllerUrl . DS . 'add.html';  
253 - $editFile = $adminPath . 'view' . DS . $controllerUrl . DS . 'edit.html';  
254 - $indexFile = $adminPath . 'view' . DS . $controllerUrl . DS . 'index.html';  
255 - $langFile = $adminPath . 'lang' . DS . Lang::detect() . DS . $controllerUrl . '.php';  
256 -  
257 - $appNamespace = Config::get('app_namespace');  
258 - $moduleName = 'admin';  
259 - $controllerNamespace = "{$appNamespace}\\{$moduleName}\\controller" . ($controllerDir ? "\\" : "") . str_replace('/', "\\", $controllerDir);  
260 - $modelNamespace = "{$appNamespace}\\" . ($local ? $moduleName : "common") . "\\model";  
261 -  
262 - $data = [  
263 - 'controllerNamespace' => $controllerNamespace,  
264 - 'modelNamespace' => $modelNamespace,  
265 - 'controllerUrl' => $controllerUrl,  
266 - 'controllerDir' => $controllerDir,  
267 - 'controllerName' => $controllerName,  
268 - 'modelName' => $modelName,  
269 - 'tableComment' => $tableComment,  
270 - 'iconName' => $iconName,  
271 - 'order' => $order,  
272 - 'table' => $table,  
273 - 'tableName' => $tableName,  
274 - 'addList' => $addList,  
275 - 'editList' => $editList,  
276 - 'javascriptList' => $javascriptList,  
277 - 'langList' => $langList,  
278 - 'modelAutoWriteTimestamp' => in_array('createtime', $fields) || in_array('updatetime', $fields) ? "'int'" : 'false',  
279 - 'createTime' => in_array('createtime', $fields) ? "'createtime'" : 'false',  
280 - 'updateTime' => in_array('updatetime', $fields) ? "'updatetime'" : 'false',  
281 - ];  
282 -  
283 - // 生成控制器文件  
284 - $result = $this->writeToFile('controller', $data, $controllerFile);  
285 - // 生成模型文件  
286 - $result = $this->writeToFile('model', $data, $modelFile);  
287 - // 生成视图文件  
288 - $result = $this->writeToFile('add', $data, $addFile);  
289 - $result = $this->writeToFile('edit', $data, $editFile);  
290 - $result = $this->writeToFile('index', $data, $indexFile);  
291 - // 生成JS文件  
292 - $result = $this->writeToFile('javascript', $data, $javascriptFile);  
293 - // 生成语言文件  
294 - if ($langList) 358 + catch (\think\exception\ErrorException $e)
295 { 359 {
296 - $result = $this->writeToFile('lang', $data, $langFile); 360 + print_r($e);
297 } 361 }
298 $output->writeln("<info>Build Successed</info>"); 362 $output->writeln("<info>Build Successed</info>");
299 } 363 }
@@ -348,6 +412,99 @@ EOD; @@ -348,6 +412,99 @@ EOD;
348 } 412 }
349 413
350 /** 414 /**
  415 + * 读取数据和语言数组列表
  416 + * @param array $arr
  417 + * @return array
  418 + */
  419 + protected function getLangArray($arr, $withTpl = TRUE)
  420 + {
  421 + $langArr = [];
  422 + foreach ($arr as $k => $v)
  423 + {
  424 + $langArr[(is_numeric($k) ? $v : $k)] = is_numeric($k) ? ($withTpl ? "{:" : "") . "__('" . ucfirst($v) . "')" . ($withTpl ? "}" : "") : $v;
  425 + }
  426 + return $langArr;
  427 + }
  428 +
  429 + /**
  430 + * 将数据转换成带字符串
  431 + * @param array $arr
  432 + * @return string
  433 + */
  434 + protected function getArrayString($arr)
  435 + {
  436 + $stringArr = [];
  437 + foreach ($arr as $k => $v)
  438 + {
  439 + $is_var = in_array(substr($v, 0, 1), ['$', '_']);
  440 + if (!$is_var)
  441 + {
  442 + $v = str_replace("'", "\'", $v);
  443 + $k = str_replace("'", "\'", $k);
  444 + }
  445 + $stringArr[] = "'" . (is_numeric($k) ? $v : $k) . "' => " . (is_numeric($k) ? "__('" . ucfirst($k) . "')" : $is_var ? $v : "'{$v}'");
  446 + }
  447 + return implode(",", $stringArr);
  448 + }
  449 +
  450 + protected function getFieldType(& $v)
  451 + {
  452 + $inputType = 'text';
  453 + switch ($v['DATA_TYPE'])
  454 + {
  455 + case 'bigint':
  456 + case 'int':
  457 + case 'mediumint':
  458 + case 'smallint':
  459 + case 'tinyint':
  460 + $inputType = 'number';
  461 + break;
  462 + case 'enum':
  463 + case 'set':
  464 + $inputType = 'select';
  465 + break;
  466 + case 'decimal':
  467 + case 'double':
  468 + case 'float':
  469 + $inputType = 'number';
  470 + break;
  471 + case 'longtext':
  472 + case 'text':
  473 + case 'mediumtext':
  474 + case 'smalltext':
  475 + case 'tinytext':
  476 + $inputType = 'textarea';
  477 + break;
  478 + case 'year';
  479 + case 'date';
  480 + case 'time';
  481 + case 'datetime';
  482 + case 'timestamp';
  483 + $inputType = 'datetime';
  484 + break;
  485 + default:
  486 + break;
  487 + }
  488 + $fieldsName = $v['COLUMN_NAME'];
  489 + // 如果后缀以time结尾说明也是个时间字段
  490 + if (substr($fieldsName, -4) == 'time')
  491 + {
  492 + $inputType = 'datetime';
  493 + }
  494 + // 如果后缀以data结尾且类型为enum,说明是个单选框
  495 + if (substr($fieldsName, -4) == 'data' && $v['DATA_TYPE'] == 'enum')
  496 + {
  497 + $inputType = "radio";
  498 + }
  499 + // 如果后缀以data结尾且类型为set,说明是个复选框
  500 + if (substr($fieldsName, -4) == 'data' && $v['DATA_TYPE'] == 'set')
  501 + {
  502 + $inputType = "checkbox";
  503 + }
  504 + return $inputType;
  505 + }
  506 +
  507 + /**
351 * 获取表单分组数据 508 * 获取表单分组数据
352 * @param string $field 509 * @param string $field
353 * @param string $content 510 * @param string $content
@@ -374,10 +531,11 @@ EOD; @@ -374,10 +531,11 @@ EOD;
374 */ 531 */
375 protected function getImageUpload($field, $content) 532 protected function getImageUpload($field, $content)
376 { 533 {
  534 + $filter = substr($field, -4) == 'avatar' || substr($field, -5) == 'image' ? 'data-mimetype="image/*"' : "";
377 return <<<EOD 535 return <<<EOD
378 <div class="form-inline"> 536 <div class="form-inline">
379 {$content} 537 {$content}
380 - <span><button id="plupload-{$field}" class="btn btn-danger plupload" data-input-id="c-{$field}"><i class="fa fa-upload"></i> {:__('Upload')}</button></span> 538 + <span><button id="plupload-{$field}" class="btn btn-danger plupload" data-input-id="c-{$field}"{$filter}><i class="fa fa-upload"></i> {:__('Upload')}</button></span>
381 </div> 539 </div>
382 EOD; 540 EOD;
383 } 541 }
@@ -262,6 +262,40 @@ CREATE TABLE `fa_page` ( @@ -262,6 +262,40 @@ CREATE TABLE `fa_page` (
262 ) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='单页表'; 262 ) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='单页表';
263 263
264 -- ---------------------------- 264 -- ----------------------------
  265 +-- Table structure for `fa_test`
  266 +-- ----------------------------
  267 +DROP TABLE IF EXISTS `fa_test`;
  268 +CREATE TABLE `fa_test` (
  269 + `id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID',
  270 + `category_id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '分类ID(单选)',
  271 + `category_ids` varchar(100) NOT NULL DEFAULT '' COMMENT '分类ID(多选)',
  272 + `user_id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '会员ID',
  273 + `user_ids` varchar(100) NOT NULL DEFAULT '' COMMENT '多会员ID',
  274 + `week` enum('monday','tuesday','wednesday') NOT NULL COMMENT '星期(单选)',
  275 + `flag` set('hot','index','recommend') NOT NULL DEFAULT '' COMMENT '标志(多选)',
  276 + `genderdata` enum('male','female') NOT NULL DEFAULT 'male' COMMENT '性别(单选)',
  277 + `hobbydata` set('music','reading','swimming') NOT NULL COMMENT '爱好(多选)',
  278 + `title` varchar(50) NOT NULL DEFAULT '' COMMENT '标题',
  279 + `content` text NOT NULL COMMENT '内容',
  280 + `image` varchar(100) NOT NULL DEFAULT '' COMMENT '图片',
  281 + `attachfile` varchar(100) NOT NULL DEFAULT '' COMMENT '附件',
  282 + `keywords` varchar(100) NOT NULL DEFAULT '' COMMENT '关键字',
  283 + `description` varchar(255) NOT NULL DEFAULT '' COMMENT '描述',
  284 + `price` float(10,2) unsigned NOT NULL DEFAULT '0.00' COMMENT '价格',
  285 + `views` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '点击',
  286 + `startdate` date DEFAULT NULL COMMENT '开始日期',
  287 + `activitydate` datetime DEFAULT NULL COMMENT '活动时间(datetime)',
  288 + `year` year(4) DEFAULT NULL COMMENT '年',
  289 + `times` time DEFAULT NULL COMMENT '时间',
  290 + `refreshtime` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '刷新时间(int)',
  291 + `createtime` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '创建时间',
  292 + `updatetime` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '更新时间',
  293 + `weigh` int(10) NOT NULL DEFAULT '0' COMMENT '权重',
  294 + `status` varchar(30) NOT NULL DEFAULT '' COMMENT '状态',
  295 + PRIMARY KEY (`id`)
  296 +) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='测试表';
  297 +
  298 +-- ----------------------------
265 -- Table structure for `fa_user` 299 -- Table structure for `fa_user`
266 -- ---------------------------- 300 -- ----------------------------
267 DROP TABLE IF EXISTS `fa_user`; 301 DROP TABLE IF EXISTS `fa_user`;
@@ -51,17 +51,28 @@ class Min extends Command @@ -51,17 +51,28 @@ class Min extends Command
51 $publicPath = ROOT_PATH . 'public' . DS; 51 $publicPath = ROOT_PATH . 'public' . DS;
52 $tempFile = $minPath . 'temp.js'; 52 $tempFile = $minPath . 'temp.js';
53 53
54 - try 54 + // Winsows下请手动配置配置该值
  55 + $nodeExec = "";
  56 +
  57 + if (!$nodeExec)
55 { 58 {
56 - $nodeExec = exec("which node");  
57 - if (!$nodeExec) 59 + if (IS_WIN)
58 { 60 {
59 - throw new Exception("node environment not found!please install node first!"); 61 + throw new Exception("node environment require nodejs!please check http://doc.fastadmin.net/322813 !");
  62 + }
  63 +
  64 + try
  65 + {
  66 + $nodeExec = exec("which node");
  67 + if (!$nodeExec)
  68 + {
  69 + throw new Exception("node environment not found!please install node first!");
  70 + }
  71 + }
  72 + catch (Exception $e)
  73 + {
  74 + throw new Exception($e->getMessage());
60 } 75 }
61 - }  
62 - catch (Exception $e)  
63 - {  
64 - throw new Exception($e->getMessage());  
65 } 76 }
66 77
67 foreach ($moduleArr as $mod) 78 foreach ($moduleArr as $mod)
1 <?php 1 <?php
2 2
3 use app\admin\library\Auth; 3 use app\admin\library\Auth;
  4 +use app\common\model\Category;
4 use app\common\model\Configvalue; 5 use app\common\model\Configvalue;
5 use fast\Form; 6 use fast\Form;
  7 +use fast\Tree;
6 use think\Db; 8 use think\Db;
7 9
8 -function get_upload_multipart($savekey = '', $mimetype = '', $maxsize = '') 10 +/**
  11 + * 重新生成上传的参数配置
  12 + * @return type
  13 + */
  14 +function get_upload_multipart($params = [])
9 { 15 {
10 // 加载配置 16 // 加载配置
11 $configvalue = new Configvalue; 17 $configvalue = new Configvalue;
12 // 上传参数配置配置 18 // 上传参数配置配置
13 - $uploadcfg = $configvalue->upload($savekey, $mimetype, $maxsize); 19 + $uploadcfg = $configvalue->upload($params);
14 20
15 - return json_encode(['policy' => $uploadcfg['policy'], 'signature' => $uploadcfg['signature']]);  
16 -}  
17 -  
18 -function get_flag_list()  
19 -{  
20 - return [  
21 - 'h' => __('Hot'),  
22 - 'i' => __('Index'),  
23 - 'r' => __('Recommend'),  
24 - ]; 21 + return json_encode(isset($uploadcfg['multipart']) ? $uploadcfg['multipart'] : []);
25 } 22 }
26 23
27 /** 24 /**
@@ -50,9 +47,10 @@ function build_radios($name, $list = [], $selected = null) @@ -50,9 +47,10 @@ function build_radios($name, $list = [], $selected = null)
50 { 47 {
51 $html = []; 48 $html = [];
52 $selected = is_null($selected) ? key($list) : $selected; 49 $selected = is_null($selected) ? key($list) : $selected;
  50 + $selected = is_array($selected) ? $selected : explode(',', $selected);
53 foreach ($list as $k => $v) 51 foreach ($list as $k => $v)
54 { 52 {
55 - $html[] = sprintf(Form::label("{$name}-{$k}", "%s {$v}"), Form::radio($name, $k, $k == $selected, ['id' => "{$name}-{$k}"])); 53 + $html[] = sprintf(Form::label("{$name}-{$k}", "%s {$v}"), Form::radio($name, $k, in_array($k, $selected), ['id' => "{$name}-{$k}"]));
56 } 54 }
57 return implode(' ', $html); 55 return implode(' ', $html);
58 } 56 }
@@ -68,14 +66,37 @@ function build_checkboxs($name, $list = [], $selected = null) @@ -68,14 +66,37 @@ function build_checkboxs($name, $list = [], $selected = null)
68 { 66 {
69 $html = []; 67 $html = [];
70 $selected = is_null($selected) ? [] : $selected; 68 $selected = is_null($selected) ? [] : $selected;
  69 + $selected = is_array($selected) ? $selected : explode(',', $selected);
71 foreach ($list as $k => $v) 70 foreach ($list as $k => $v)
72 { 71 {
73 - $html[] = sprintf(Form::label("{$name}-{$k}", "%s {$v}"), Form::checkbox($name, $k, $k == $selected, ['id' => "{$name}-{$k}"])); 72 + $html[] = sprintf(Form::label("{$name}-{$k}", "%s {$v}"), Form::checkbox($name, $k, in_array($k, $selected), ['id' => "{$name}-{$k}"]));
74 } 73 }
75 return implode(' ', $html); 74 return implode(' ', $html);
76 } 75 }
77 76
78 /** 77 /**
  78 + * 生成分类下拉列表框
  79 + * @param string $name
  80 + * @param string $type
  81 + * @param mixed $selected
  82 + * @param array $attr
  83 + * @return string
  84 + */
  85 +function build_category_select($name, $type, $selected = null, $attr = [])
  86 +{
  87 + $tree = Tree::instance();
  88 + $tree->init(Category::getCategoryArray($type), 'pid');
  89 + $categorylist = $tree->getTreeList($tree->getTreeArray(0), 'name');
  90 + $categorydata = [0 => __('None')];
  91 + foreach ($categorylist as $k => $v)
  92 + {
  93 + $categorydata[$v['id']] = $v['name'];
  94 + }
  95 + $attr = array_merge(['id' => "c-{$name}", 'class' => 'form-control selectpicker'], $attr);
  96 + return build_select($name, $categorydata, $selected, $attr);
  97 +}
  98 +
  99 +/**
79 * 生成表格操作按钮栏 100 * 生成表格操作按钮栏
80 * @param array $btns 101 * @param array $btns
81 * @return string 102 * @return string
@@ -43,6 +43,11 @@ trait Backend @@ -43,6 +43,11 @@ trait Backend
43 $params = $this->request->post("row/a"); 43 $params = $this->request->post("row/a");
44 if ($params) 44 if ($params)
45 { 45 {
  46 + foreach ($params as $k => &$v)
  47 + {
  48 + $v = is_array($v) ? implode(',', $v) : $v;
  49 + $v = substr($k, -4) == 'time' && !is_numeric($v) ? strtotime($v) : $v;
  50 + }
46 $this->model->create($params); 51 $this->model->create($params);
47 AdminLog::record(__('Add'), $this->model->getLastInsID()); 52 AdminLog::record(__('Add'), $this->model->getLastInsID());
48 $this->code = 1; 53 $this->code = 1;
@@ -67,6 +72,11 @@ trait Backend @@ -67,6 +72,11 @@ trait Backend
67 $params = $this->request->post("row/a"); 72 $params = $this->request->post("row/a");
68 if ($params) 73 if ($params)
69 { 74 {
  75 + foreach ($params as $k => &$v)
  76 + {
  77 + $v = is_array($v) ? implode(',', $v) : $v;
  78 + $v = substr($k, -4) == 'time' && !is_numeric($v) ? strtotime($v) : $v;
  79 + }
70 $row->save($params); 80 $row->save($params);
71 AdminLog::record(__('Edit'), $ids); 81 AdminLog::record(__('Edit'), $ids);
72 $this->code = 1; 82 $this->code = 1;
1 <!DOCTYPE html> 1 <!DOCTYPE html>
2 -<html lang="en"> 2 +<html lang="{$config.language}">
3 <head> 3 <head>
4 {include file="common/meta" /} 4 {include file="common/meta" /}
5 </head> 5 </head>
1 <form id="add-form" class="form-horizontal form-ajax" role="form" data-toggle="validator" method="POST" action=""> 1 <form id="add-form" class="form-horizontal form-ajax" role="form" data-toggle="validator" method="POST" action="">
2 -  
3 <div class="form-group"> 2 <div class="form-group">
4 <label for="c-category_id" class="control-label col-xs-12 col-sm-2">{:__('Category_id')}:</label> 3 <label for="c-category_id" class="control-label col-xs-12 col-sm-2">{:__('Category_id')}:</label>
5 <div class="col-xs-12 col-sm-8"> 4 <div class="col-xs-12 col-sm-8">
@@ -48,7 +47,7 @@ @@ -48,7 +47,7 @@
48 <div class="form-group"> 47 <div class="form-group">
49 <label for="c-views" class="control-label col-xs-12 col-sm-2">{:__('Views')}:</label> 48 <label for="c-views" class="control-label col-xs-12 col-sm-2">{:__('Views')}:</label>
50 <div class="col-xs-12 col-sm-8"> 49 <div class="col-xs-12 col-sm-8">
51 - <input id="c-views" class="form-control" name="row[views]" type="number" value="0"> 50 + <input id="c-views" class="form-control" name="row[views]" type="text" value="0">
52 </div> 51 </div>
53 </div> 52 </div>
54 <div class="form-group"> 53 <div class="form-group">
@@ -20,6 +20,11 @@ class Common @@ -20,6 +20,11 @@ class Common
20 { 20 {
21 Config::set('site.cdnurl', $cdnurl); 21 Config::set('site.cdnurl', $cdnurl);
22 } 22 }
  23 + // 如果是调试模式将version置为当前的时间戳可避免缓存
  24 + if (!Config::get('app_debug'))
  25 + {
  26 + Config::set('site.version', time());
  27 + }
23 } 28 }
24 29
25 } 30 }
@@ -89,6 +89,12 @@ class FormBuilder @@ -89,6 +89,12 @@ class FormBuilder
89 * @var array 89 * @var array
90 */ 90 */
91 protected $skipValueTypes = array('file', 'password', 'checkbox', 'radio'); 91 protected $skipValueTypes = array('file', 'password', 'checkbox', 'radio');
  92 +
  93 + /**
  94 + * Escape html
  95 + * @var boolean
  96 + */
  97 + protected $escapeHtml = true;
92 protected static $instance; 98 protected static $instance;
93 99
94 /** 100 /**
@@ -180,6 +186,32 @@ class FormBuilder @@ -180,6 +186,32 @@ class FormBuilder
180 } 186 }
181 187
182 /** 188 /**
  189 + * Set the escape html mode
  190 + * @param boolean $escape
  191 + */
  192 + public function setEscapeHtml($escape)
  193 + {
  194 + $this->escapeHtml = $escape;
  195 + }
  196 +
  197 + /**
  198 + * Escape HTML special characters in a string.
  199 + * @return string
  200 + */
  201 + public function escape($value)
  202 + {
  203 + if (!$this->escapeHtml)
  204 + {
  205 + return $value;
  206 + }
  207 + if (is_array($value))
  208 + {
  209 + $value = json_encode($value, JSON_UNESCAPED_UNICODE);
  210 + }
  211 + return htmlspecialchars($value, ENT_QUOTES, 'UTF-8', false);
  212 + }
  213 +
  214 + /**
183 * Close the current form. 215 * Close the current form.
184 * 216 *
185 * @return string 217 * @return string
@@ -222,7 +254,7 @@ class FormBuilder @@ -222,7 +254,7 @@ class FormBuilder
222 254
223 $options = $this->attributes($options); 255 $options = $this->attributes($options);
224 256
225 - $value = e($this->formatLabel($name, $value)); 257 + $value = $this->escape($this->formatLabel($name, $value));
226 258
227 return '<label for="' . $name . '"' . $options . '>' . $value . '</label>'; 259 return '<label for="' . $name . '"' . $options . '>' . $value . '</label>';
228 } 260 }
@@ -378,7 +410,7 @@ class FormBuilder @@ -378,7 +410,7 @@ class FormBuilder
378 // the element. Then we'll create the final textarea elements HTML for us. 410 // the element. Then we'll create the final textarea elements HTML for us.
379 $options = $this->attributes($options); 411 $options = $this->attributes($options);
380 412
381 - return '<textarea' . $options . '>' . e($value) . '</textarea>'; 413 + return '<textarea' . $options . '>' . $this->escape($value) . '</textarea>';
382 } 414 }
383 415
384 /** 416 /**
@@ -547,7 +579,7 @@ class FormBuilder @@ -547,7 +579,7 @@ class FormBuilder
547 $html[] = $this->option($display, $value, $selected); 579 $html[] = $this->option($display, $value, $selected);
548 } 580 }
549 581
550 - return '<optgroup label="' . e($label) . '">' . implode('', $html) . '</optgroup>'; 582 + return '<optgroup label="' . $this->escape($label) . '">' . implode('', $html) . '</optgroup>';
551 } 583 }
552 584
553 /** 585 /**
@@ -562,9 +594,9 @@ class FormBuilder @@ -562,9 +594,9 @@ class FormBuilder
562 { 594 {
563 $selected = $this->getSelectedValue($value, $selected); 595 $selected = $this->getSelectedValue($value, $selected);
564 596
565 - $options = array('value' => e($value), 'selected' => $selected); 597 + $options = array('value' => $this->escape($value), 'selected' => $selected);
566 598
567 - return '<option' . $this->attributes($options) . '>' . e($display) . '</option>'; 599 + return '<option' . $this->attributes($options) . '>' . $this->escape($display) . '</option>';
568 } 600 }
569 601
570 /** 602 /**
@@ -50,7 +50,7 @@ class Wechat @@ -50,7 +50,7 @@ class Wechat
50 { 50 {
51 if ($config = Config::get('payment.wechat')) 51 if ($config = Config::get('payment.wechat'))
52 { 52 {
53 - $this->config = array_merge($this->config, $config); 53 + $this->_config = array_merge($this->_config, $config);
54 } 54 }
55 $this->_config = array_merge($this->_config, is_array($options) ? $options : []); 55 $this->_config = array_merge($this->_config, is_array($options) ? $options : []);
56 } 56 }
@@ -287,6 +287,9 @@ body { @@ -287,6 +287,9 @@ body {
287 .fixed-table-container { 287 .fixed-table-container {
288 border: none!important; 288 border: none!important;
289 } 289 }
  290 +.note-editor .note-editing-area .note-editable {
  291 + display: block !important;
  292 +}
290 .pjax-loader-bar .progress { 293 .pjax-loader-bar .progress {
291 position: fixed; 294 position: fixed;
292 top: 0; 295 top: 0;
@@ -54,6 +54,27 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin @@ -54,6 +54,27 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
54 }, 54 },
55 api: { 55 api: {
56 bindevent: function () { 56 bindevent: function () {
  57 + $("form[role=form]").validator({
  58 + rules: {
  59 + mobile: [/^1[3-9]\d{9}$/, "请填写有效的手机号"],
  60 + chinese: [/^[\u0391-\uFFE5]+$/, "请填写中文字符"],
  61 + // 使用函数定义规则
  62 + phone: function (elem, param) {
  63 + return /^1[3458]\d{9}$/.test($(elem).val()) || '请检查手机号格式';
  64 + },
  65 + image: function (elem, param) {
  66 + return /^\/(.*)\.(jpg|jpeg|png|gif)$/.test($(elem).val()) || '请上传有并行的图片文件';
  67 + }
  68 + },
  69 + messages: {
  70 + },
  71 + fields: {
  72 + 'row[title]': "required;length(3~16)",
  73 + 'row[image]': "required;image",
  74 + 'row[views]': "required;range[0~100]",
  75 + 'row[content]': "required"
  76 + },
  77 + });
57 Form.api.bindevent($("form[role=form]")); 78 Form.api.bindevent($("form[role=form]"));
58 } 79 }
59 } 80 }
1 -define(['jquery', 'bootstrap', 'backend', 'config', 'toastr', 'upload', 'bootstrap-validator', 'bootstrap-checkbox', 'bootstrap-radio', 'bootstrap-switch'], function ($, undefined, Backend, Config, Toastr, Upload, undefined) { 1 +define(['jquery', 'bootstrap', 'backend', 'config', 'toastr', 'upload', 'validator'], function ($, undefined, Backend, Config, Toastr, Upload, Validator) {
2 var Form = { 2 var Form = {
3 config: { 3 config: {
4 }, 4 },
@@ -64,11 +64,14 @@ define(['jquery', 'bootstrap', 'backend', 'config', 'toastr', 'upload', 'bootstr @@ -64,11 +64,14 @@ define(['jquery', 'bootstrap', 'backend', 'config', 'toastr', 'upload', 'bootstr
64 return false; 64 return false;
65 }, 65 },
66 bindevent: function (form, onBeforeSubmit, onAfterSubmit) { 66 bindevent: function (form, onBeforeSubmit, onAfterSubmit) {
67 - form.validator().on('submit', function (e) {  
68 - if (e.isDefaultPrevented()) {  
69 - //验证不通过  
70 - Toastr.error("验证失败,请检查表单输入是否正确");  
71 - } else { 67 + form.validator({
  68 + validClass: 'has-success',
  69 + invalidClass: 'has-error',
  70 + bindClassTo: '.form-group',
  71 + formClass: 'n-default n-bootstrap',
  72 + msgClass: 'n-right',
  73 + stopOnError: true,
  74 + valid: function (ret) {
72 //验证通过提交表单 75 //验证通过提交表单
73 Form.api.submit(form, onBeforeSubmit, function (data) { 76 Form.api.submit(form, onBeforeSubmit, function (data) {
74 if (typeof onAfterSubmit == 'function') { 77 if (typeof onAfterSubmit == 'function') {
@@ -86,16 +89,6 @@ define(['jquery', 'bootstrap', 'backend', 'config', 'toastr', 'upload', 'bootstr @@ -86,16 +89,6 @@ define(['jquery', 'bootstrap', 'backend', 'config', 'toastr', 'upload', 'bootstr
86 } 89 }
87 }); 90 });
88 91
89 - // Activate the switches with icons  
90 - if ($('.switch').length != 0) {  
91 - $('.switch')['bootstrapSwitch']();  
92 - }  
93 -  
94 - // Activate regular switches  
95 - if ($("[data-toggle='switch']").length != 0) {  
96 - $("[data-toggle='switch']").wrap('<div class="switch" />').parent().bootstrapSwitch();  
97 - }  
98 -  
99 //绑定select元素事件 92 //绑定select元素事件
100 if ($(".selectpicker", form).size() > 0) { 93 if ($(".selectpicker", form).size() > 0) {
101 require(['bootstrap-select'], function () { 94 require(['bootstrap-select'], function () {
@@ -208,7 +208,7 @@ define('../libs/require-css/css.min',[],function(){if("undefined"==typeof window @@ -208,7 +208,7 @@ define('../libs/require-css/css.min',[],function(){if("undefined"==typeof window
208 @Author:贤心 208 @Author:贤心
209 @Site:http://layer.layui.com 209 @Site:http://layer.layui.com
210 @License:LGPL 210 @License:LGPL
211 - 211 +
212 */ 212 */
213 213
214 ;!function(window, undefined){ 214 ;!function(window, undefined){
@@ -244,39 +244,39 @@ var layer = { @@ -244,39 +244,39 @@ var layer = {
244 layer.cache = ready.config = $.extend({}, ready.config, options); 244 layer.cache = ready.config = $.extend({}, ready.config, options);
245 layer.path = ready.config.path || layer.path; 245 layer.path = ready.config.path || layer.path;
246 typeof options.extend === 'string' && (options.extend = [options.extend]); 246 typeof options.extend === 'string' && (options.extend = [options.extend]);
247 - 247 +
248 if(ready.config.path) layer.ready(); 248 if(ready.config.path) layer.ready();
249 - 249 +
250 if(!options.extend) return this; 250 if(!options.extend) return this;
251 -  
252 - isLayui 251 +
  252 + isLayui
253 ? layui.addcss('modules/layer/' + options.extend) 253 ? layui.addcss('modules/layer/' + options.extend)
254 : layer.link('skin/' + options.extend); 254 : layer.link('skin/' + options.extend);
255 - 255 +
256 return this; 256 return this;
257 }, 257 },
258 - 258 +
259 //载入CSS配件 259 //载入CSS配件
260 link: function(href, fn, cssname){ 260 link: function(href, fn, cssname){
261 - 261 +
262 //未设置路径,则不主动加载css 262 //未设置路径,则不主动加载css
263 if(!layer.path) return; 263 if(!layer.path) return;
264 - 264 +
265 var head = $('head')[0], link = document.createElement('link'); 265 var head = $('head')[0], link = document.createElement('link');
266 if(typeof fn === 'string') cssname = fn; 266 if(typeof fn === 'string') cssname = fn;
267 var app = (cssname || href).replace(/\.|\//g, ''); 267 var app = (cssname || href).replace(/\.|\//g, '');
268 var id = 'layuicss-'+app, timeout = 0; 268 var id = 'layuicss-'+app, timeout = 0;
269 - 269 +
270 link.rel = 'stylesheet'; 270 link.rel = 'stylesheet';
271 link.href = layer.path + href; 271 link.href = layer.path + href;
272 link.id = id; 272 link.id = id;
273 - 273 +
274 if(!$('#'+ id)[0]){ 274 if(!$('#'+ id)[0]){
275 head.appendChild(link); 275 head.appendChild(link);
276 } 276 }
277 - 277 +
278 if(typeof fn !== 'function') return; 278 if(typeof fn !== 'function') return;
279 - 279 +
280 //轮询css是否加载完毕 280 //轮询css是否加载完毕
281 (function poll() { 281 (function poll() {
282 if(++timeout > 8 * 1000 / 100){ 282 if(++timeout > 8 * 1000 / 100){
@@ -285,14 +285,14 @@ var layer = { @@ -285,14 +285,14 @@ var layer = {
285 parseInt($('#'+id).css('width')) === 1989 ? fn() : setTimeout(poll, 100); 285 parseInt($('#'+id).css('width')) === 1989 ? fn() : setTimeout(poll, 100);
286 }()); 286 }());
287 }, 287 },
288 - 288 +
289 ready: function(callback){ 289 ready: function(callback){
290 var cssname = 'skinlayercss', ver = '1110'; 290 var cssname = 'skinlayercss', ver = '1110';
291 isLayui ? layui.addcss('modules/layer/default/layer.css?v='+layer.v+ver, callback, cssname) 291 isLayui ? layui.addcss('modules/layer/default/layer.css?v='+layer.v+ver, callback, cssname)
292 : layer.link('skin/default/layer.css?v='+layer.v+ver, callback, cssname); 292 : layer.link('skin/default/layer.css?v='+layer.v+ver, callback, cssname);
293 return this; 293 return this;
294 }, 294 },
295 - 295 +
296 //各种快捷引用 296 //各种快捷引用
297 alert: function(content, options, yes){ 297 alert: function(content, options, yes){
298 var type = typeof options === 'function'; 298 var type = typeof options === 'function';
@@ -301,9 +301,9 @@ var layer = { @@ -301,9 +301,9 @@ var layer = {
301 content: content, 301 content: content,
302 yes: yes 302 yes: yes
303 }, type ? {} : options)); 303 }, type ? {} : options));
304 - },  
305 -  
306 - confirm: function(content, options, yes, cancel){ 304 + },
  305 +
  306 + confirm: function(content, options, yes, cancel){
307 var type = typeof options === 'function'; 307 var type = typeof options === 'function';
308 if(type){ 308 if(type){
309 cancel = yes; 309 cancel = yes;
@@ -316,7 +316,7 @@ var layer = { @@ -316,7 +316,7 @@ var layer = {
316 btn2: cancel 316 btn2: cancel
317 }, type ? {} : options)); 317 }, type ? {} : options));
318 }, 318 },
319 - 319 +
320 msg: function(content, options, end){ //最常用提示层 320 msg: function(content, options, end){ //最常用提示层
321 var type = typeof options === 'function', rskin = ready.config.skin; 321 var type = typeof options === 'function', rskin = ready.config.skin;
322 var skin = (rskin ? rskin + ' ' + rskin + '-msg' : '')||'layui-layer-msg'; 322 var skin = (rskin ? rskin + ' ' + rskin + '-msg' : '')||'layui-layer-msg';
@@ -341,9 +341,9 @@ var layer = { @@ -341,9 +341,9 @@ var layer = {
341 options.skin = skin + ' ' + (options.skin||'layui-layer-hui'); 341 options.skin = skin + ' ' + (options.skin||'layui-layer-hui');
342 } 342 }
343 return options; 343 return options;
344 - }())); 344 + }()));
345 }, 345 },
346 - 346 +
347 load: function(icon, options){ 347 load: function(icon, options){
348 return layer.open($.extend({ 348 return layer.open($.extend({
349 type: 3, 349 type: 3,
@@ -351,8 +351,8 @@ var layer = { @@ -351,8 +351,8 @@ var layer = {
351 resize: false, 351 resize: false,
352 shade: 0.01 352 shade: 0.01
353 }, options)); 353 }, options));
354 - },  
355 - 354 + },
  355 +
356 tips: function(content, follow, options){ 356 tips: function(content, follow, options){
357 return layer.open($.extend({ 357 return layer.open($.extend({
358 type: 4, 358 type: 4,
@@ -367,7 +367,7 @@ var layer = { @@ -367,7 +367,7 @@ var layer = {
367 } 367 }
368 }; 368 };
369 369
370 -var Class = function(setings){ 370 +var Class = function(setings){
371 var that = this; 371 var that = this;
372 that.index = ++layer.index; 372 that.index = ++layer.index;
373 that.config = $.extend({}, that.config, ready.config, setings); 373 that.config = $.extend({}, that.config, ready.config, setings);
@@ -393,7 +393,7 @@ Class.pt.config = { @@ -393,7 +393,7 @@ Class.pt.config = {
393 area: 'auto', 393 area: 'auto',
394 closeBtn: 1, 394 closeBtn: 1,
395 time: 0, //0表示不自动关闭 395 time: 0, //0表示不自动关闭
396 - zIndex: 19891014, 396 + zIndex: 19891014,
397 maxWidth: 360, 397 maxWidth: 360,
398 anim: 0, 398 anim: 0,
399 icon: -1, 399 icon: -1,
@@ -408,15 +408,15 @@ Class.pt.vessel = function(conType, callback){ @@ -408,15 +408,15 @@ Class.pt.vessel = function(conType, callback){
408 var that = this, times = that.index, config = that.config; 408 var that = this, times = that.index, config = that.config;
409 var zIndex = config.zIndex + times, titype = typeof config.title === 'object'; 409 var zIndex = config.zIndex + times, titype = typeof config.title === 'object';
410 var ismax = config.maxmin && (config.type === 1 || config.type === 2); 410 var ismax = config.maxmin && (config.type === 1 || config.type === 2);
411 - var titleHTML = (config.title ? '<div class="layui-layer-title" style="'+ (titype ? config.title[1] : '') +'">'  
412 - + (titype ? config.title[0] : config.title) 411 + var titleHTML = (config.title ? '<div class="layui-layer-title" style="'+ (titype ? config.title[1] : '') +'">'
  412 + + (titype ? config.title[0] : config.title)
413 + '</div>' : ''); 413 + '</div>' : '');
414 - 414 +
415 config.zIndex = zIndex; 415 config.zIndex = zIndex;
416 callback([ 416 callback([
417 //遮罩 417 //遮罩
418 config.shade ? ('<div class="layui-layer-shade" id="layui-layer-shade'+ times +'" times="'+ times +'" style="'+ ('z-index:'+ (zIndex-1) +'; background-color:'+ (config.shade[1]||'#000') +'; opacity:'+ (config.shade[0]||config.shade) +'; filter:alpha(opacity='+ (config.shade[0]*100||config.shade*100) +');') +'"></div>') : '', 418 config.shade ? ('<div class="layui-layer-shade" id="layui-layer-shade'+ times +'" times="'+ times +'" style="'+ ('z-index:'+ (zIndex-1) +'; background-color:'+ (config.shade[1]||'#000') +'; opacity:'+ (config.shade[0]||config.shade) +'; filter:alpha(opacity='+ (config.shade[0]*100||config.shade*100) +');') +'"></div>') : '',
419 - 419 +
420 //主体 420 //主体
421 '<div class="'+ doms[0] + (' layui-layer-'+ready.type[config.type]) + (((config.type == 0 || config.type == 2) && !config.shade) ? ' layui-layer-border' : '') + ' ' + (config.skin||'') +'" id="'+ doms[0] + times +'" type="'+ ready.type[config.type] +'" times="'+ times +'" showtime="'+ config.time +'" conType="'+ (conType ? 'object' : 'string') +'" style="z-index: '+ zIndex +'; width:'+ config.area[0] + ';height:' + config.area[1] + (config.fixed ? '' : ';position:absolute;') +'">' 421 '<div class="'+ doms[0] + (' layui-layer-'+ready.type[config.type]) + (((config.type == 0 || config.type == 2) && !config.shade) ? ' layui-layer-border' : '') + ' ' + (config.skin||'') +'" id="'+ doms[0] + times +'" type="'+ ready.type[config.type] +'" times="'+ times +'" showtime="'+ config.time +'" conType="'+ (conType ? 'object' : 'string') +'" style="z-index: '+ zIndex +'; width:'+ config.area[0] + ';height:' + config.area[1] + (config.fixed ? '' : ';position:absolute;') +'">'
422 + (conType && config.type != 2 ? '' : titleHTML) 422 + (conType && config.type != 2 ? '' : titleHTML)
@@ -451,22 +451,22 @@ Class.pt.creat = function(){ @@ -451,22 +451,22 @@ Class.pt.creat = function(){
451 ,content = config.content 451 ,content = config.content
452 ,conType = typeof content === 'object' 452 ,conType = typeof content === 'object'
453 ,body = $('body'); 453 ,body = $('body');
454 - 454 +
455 if($('#'+config.id)[0]) return; 455 if($('#'+config.id)[0]) return;
456 456
457 if(typeof config.area === 'string'){ 457 if(typeof config.area === 'string'){
458 config.area = config.area === 'auto' ? ['', ''] : [config.area, '']; 458 config.area = config.area === 'auto' ? ['', ''] : [config.area, ''];
459 } 459 }
460 - 460 +
461 //anim兼容旧版shift 461 //anim兼容旧版shift
462 if(config.shift){ 462 if(config.shift){
463 config.anim = config.shift; 463 config.anim = config.shift;
464 } 464 }
465 - 465 +
466 if(layer.ie == 6){ 466 if(layer.ie == 6){
467 config.fixed = false; 467 config.fixed = false;
468 } 468 }
469 - 469 +
470 switch(config.type){ 470 switch(config.type){
471 case 0: 471 case 0:
472 config.btn = ('btn' in config) ? config.btn : ready.btn[0]; 472 config.btn = ('btn' in config) ? config.btn : ready.btn[0];
@@ -491,7 +491,7 @@ Class.pt.creat = function(){ @@ -491,7 +491,7 @@ Class.pt.creat = function(){
491 config.tipsMore || layer.closeAll('tips'); 491 config.tipsMore || layer.closeAll('tips');
492 break; 492 break;
493 } 493 }
494 - 494 +
495 //建立容器 495 //建立容器
496 that.vessel(conType, function(html, titleHTML, moveElem){ 496 that.vessel(conType, function(html, titleHTML, moveElem){
497 body.append(html[0]); 497 body.append(html[0]);
@@ -521,12 +521,12 @@ Class.pt.creat = function(){ @@ -521,12 +521,12 @@ Class.pt.creat = function(){
521 config.type == 4 && that.tips(); 521 config.type == 4 && that.tips();
522 }); 522 });
523 } 523 }
524 - 524 +
525 config.time <= 0 || setTimeout(function(){ 525 config.time <= 0 || setTimeout(function(){
526 layer.close(that.index) 526 layer.close(that.index)
527 }, config.time); 527 }, config.time);
528 that.move().callback(); 528 that.move().callback();
529 - 529 +
530 //为兼容jQuery3.0的css动画影响元素尺寸计算 530 //为兼容jQuery3.0的css动画影响元素尺寸计算
531 if(doms.anim[config.anim]){ 531 if(doms.anim[config.anim]){
532 that.layero.addClass(doms.anim[config.anim]).data('anim', true); 532 that.layero.addClass(doms.anim[config.anim]).data('anim', true);
@@ -551,7 +551,7 @@ Class.pt.auto = function(index){ @@ -551,7 +551,7 @@ Class.pt.auto = function(index){
551 elem.height(area[1] - titHeight - btnHeight - 2*(parseFloat(elem.css('padding'))|0)); 551 elem.height(area[1] - titHeight - btnHeight - 2*(parseFloat(elem.css('padding'))|0));
552 } 552 }
553 switch(config.type){ 553 switch(config.type){
554 - case 2: 554 + case 2:
555 setHeight('iframe'); 555 setHeight('iframe');
556 break; 556 break;
557 default: 557 default:
@@ -575,12 +575,12 @@ Class.pt.offset = function(){ @@ -575,12 +575,12 @@ Class.pt.offset = function(){
575 var type = typeof config.offset === 'object'; 575 var type = typeof config.offset === 'object';
576 that.offsetTop = (win.height() - area[1])/2; 576 that.offsetTop = (win.height() - area[1])/2;
577 that.offsetLeft = (win.width() - area[0])/2; 577 that.offsetLeft = (win.width() - area[0])/2;
578 - 578 +
579 if(type){ 579 if(type){
580 that.offsetTop = config.offset[0]; 580 that.offsetTop = config.offset[0];
581 that.offsetLeft = config.offset[1]||that.offsetLeft; 581 that.offsetLeft = config.offset[1]||that.offsetLeft;
582 } else if(config.offset !== 'auto'){ 582 } else if(config.offset !== 'auto'){
583 - 583 +
584 if(config.offset === 't'){ //上 584 if(config.offset === 't'){ //上
585 that.offsetTop = 0; 585 that.offsetTop = 0;
586 } else if(config.offset === 'r'){ //右 586 } else if(config.offset === 'r'){ //右
@@ -604,20 +604,20 @@ Class.pt.offset = function(){ @@ -604,20 +604,20 @@ Class.pt.offset = function(){
604 } else { 604 } else {
605 that.offsetTop = config.offset; 605 that.offsetTop = config.offset;
606 } 606 }
607 - 607 +
608 } 608 }
609 - 609 +
610 if(!config.fixed){ 610 if(!config.fixed){
611 - that.offsetTop = /%$/.test(that.offsetTop) ? 611 + that.offsetTop = /%$/.test(that.offsetTop) ?
612 win.height()*parseFloat(that.offsetTop)/100 612 win.height()*parseFloat(that.offsetTop)/100
613 : parseFloat(that.offsetTop); 613 : parseFloat(that.offsetTop);
614 - that.offsetLeft = /%$/.test(that.offsetLeft) ? 614 + that.offsetLeft = /%$/.test(that.offsetLeft) ?
615 win.width()*parseFloat(that.offsetLeft)/100 615 win.width()*parseFloat(that.offsetLeft)/100
616 : parseFloat(that.offsetLeft); 616 : parseFloat(that.offsetLeft);
617 that.offsetTop += win.scrollTop(); 617 that.offsetTop += win.scrollTop();
618 that.offsetLeft += win.scrollLeft(); 618 that.offsetLeft += win.scrollLeft();
619 } 619 }
620 - 620 +
621 if(layero.attr('minLeft')){ 621 if(layero.attr('minLeft')){
622 that.offsetTop = win.height() - (layero.find(doms[1]).outerHeight() || 0); 622 that.offsetTop = win.height() - (layero.find(doms[1]).outerHeight() || 0);
623 that.offsetLeft = layero.css('left'); 623 that.offsetLeft = layero.css('left');
@@ -637,10 +637,10 @@ Class.pt.tips = function(){ @@ -637,10 +637,10 @@ Class.pt.tips = function(){
637 top: follow.offset().top, 637 top: follow.offset().top,
638 left: follow.offset().left 638 left: follow.offset().left
639 }, tipsG = layero.find('.layui-layer-TipsG'); 639 }, tipsG = layero.find('.layui-layer-TipsG');
640 - 640 +
641 var guide = config.tips[0]; 641 var guide = config.tips[0];
642 config.tips[1] || tipsG.remove(); 642 config.tips[1] || tipsG.remove();
643 - 643 +
644 goal.autoLeft = function(){ 644 goal.autoLeft = function(){
645 if(goal.left + layArea[0] - win.width() > 0){ 645 if(goal.left + layArea[0] - win.width() > 0){
646 goal.tipLeft = goal.left + goal.width - layArea[0]; 646 goal.tipLeft = goal.left + goal.width - layArea[0];
@@ -649,16 +649,16 @@ Class.pt.tips = function(){ @@ -649,16 +649,16 @@ Class.pt.tips = function(){
649 goal.tipLeft = goal.left; 649 goal.tipLeft = goal.left;
650 }; 650 };
651 }; 651 };
652 - 652 +
653 //辨别tips的方位 653 //辨别tips的方位
654 - goal.where = [function(){ //上 654 + goal.where = [function(){ //上
655 goal.autoLeft(); 655 goal.autoLeft();
656 goal.tipTop = goal.top - layArea[1] - 10; 656 goal.tipTop = goal.top - layArea[1] - 10;
657 tipsG.removeClass('layui-layer-TipsB').addClass('layui-layer-TipsT').css('border-right-color', config.tips[1]); 657 tipsG.removeClass('layui-layer-TipsB').addClass('layui-layer-TipsT').css('border-right-color', config.tips[1]);
658 }, function(){ //右 658 }, function(){ //右
659 goal.tipLeft = goal.left + goal.width + 10; 659 goal.tipLeft = goal.left + goal.width + 10;
660 goal.tipTop = goal.top; 660 goal.tipTop = goal.top;
661 - tipsG.removeClass('layui-layer-TipsL').addClass('layui-layer-TipsR').css('border-bottom-color', config.tips[1]); 661 + tipsG.removeClass('layui-layer-TipsL').addClass('layui-layer-TipsR').css('border-bottom-color', config.tips[1]);
662 }, function(){ //下 662 }, function(){ //下
663 goal.autoLeft(); 663 goal.autoLeft();
664 goal.tipTop = goal.top + goal.height + 10; 664 goal.tipTop = goal.top + goal.height + 10;
@@ -669,7 +669,7 @@ Class.pt.tips = function(){ @@ -669,7 +669,7 @@ Class.pt.tips = function(){
669 tipsG.removeClass('layui-layer-TipsR').addClass('layui-layer-TipsL').css('border-bottom-color', config.tips[1]); 669 tipsG.removeClass('layui-layer-TipsR').addClass('layui-layer-TipsL').css('border-bottom-color', config.tips[1]);
670 }]; 670 }];
671 goal.where[guide-1](); 671 goal.where[guide-1]();
672 - 672 +
673 /* 8*2为小三角形占据的空间 */ 673 /* 8*2为小三角形占据的空间 */
674 if(guide === 1){ 674 if(guide === 1){
675 goal.top - (win.scrollTop() + layArea[1] + 8*2) < 0 && goal.where[2](); 675 goal.top - (win.scrollTop() + layArea[1] + 8*2) < 0 && goal.where[2]();
@@ -682,11 +682,11 @@ Class.pt.tips = function(){ @@ -682,11 +682,11 @@ Class.pt.tips = function(){
682 } 682 }
683 683
684 layero.find('.'+doms[5]).css({ 684 layero.find('.'+doms[5]).css({
685 - 'background-color': config.tips[1], 685 + 'background-color': config.tips[1],
686 'padding-right': (config.closeBtn ? '30px' : '') 686 'padding-right': (config.closeBtn ? '30px' : '')
687 }); 687 });
688 layero.css({ 688 layero.css({
689 - left: goal.tipLeft - (config.fixed ? win.scrollLeft() : 0), 689 + left: goal.tipLeft - (config.fixed ? win.scrollLeft() : 0),
690 top: goal.tipTop - (config.fixed ? win.scrollTop() : 0) 690 top: goal.tipTop - (config.fixed ? win.scrollTop() : 0)
691 }); 691 });
692 } 692 }
@@ -700,7 +700,7 @@ Class.pt.move = function(){ @@ -700,7 +700,7 @@ Class.pt.move = function(){
700 ,moveElem = layero.find(config.move) 700 ,moveElem = layero.find(config.move)
701 ,resizeElem = layero.find('.layui-layer-resize') 701 ,resizeElem = layero.find('.layui-layer-resize')
702 ,dict = {}; 702 ,dict = {};
703 - 703 +
704 if(config.move){ 704 if(config.move){
705 moveElem.css('cursor', 'move'); 705 moveElem.css('cursor', 'move');
706 } 706 }
@@ -716,7 +716,7 @@ Class.pt.move = function(){ @@ -716,7 +716,7 @@ Class.pt.move = function(){
716 ready.moveElem.css('cursor', 'move').show(); 716 ready.moveElem.css('cursor', 'move').show();
717 } 717 }
718 }); 718 });
719 - 719 +
720 resizeElem.on('mousedown', function(e){ 720 resizeElem.on('mousedown', function(e){
721 e.preventDefault(); 721 e.preventDefault();
722 dict.resizeStart = true; 722 dict.resizeStart = true;
@@ -727,7 +727,7 @@ Class.pt.move = function(){ @@ -727,7 +727,7 @@ Class.pt.move = function(){
727 ]; 727 ];
728 ready.moveElem.css('cursor', 'se-resize').show(); 728 ready.moveElem.css('cursor', 'se-resize').show();
729 }); 729 });
730 - 730 +
731 _DOC.on('mousemove', function(e){ 731 _DOC.on('mousemove', function(e){
732 732
733 //拖拽移动 733 //拖拽移动
@@ -735,35 +735,35 @@ Class.pt.move = function(){ @@ -735,35 +735,35 @@ Class.pt.move = function(){
735 var X = e.clientX - dict.offset[0] 735 var X = e.clientX - dict.offset[0]
736 ,Y = e.clientY - dict.offset[1] 736 ,Y = e.clientY - dict.offset[1]
737 ,fixed = layero.css('position') === 'fixed'; 737 ,fixed = layero.css('position') === 'fixed';
738 - 738 +
739 e.preventDefault(); 739 e.preventDefault();
740 - 740 +
741 dict.stX = fixed ? 0 : win.scrollLeft(); 741 dict.stX = fixed ? 0 : win.scrollLeft();
742 dict.stY = fixed ? 0 : win.scrollTop(); 742 dict.stY = fixed ? 0 : win.scrollTop();
743 743
744 //控制元素不被拖出窗口外 744 //控制元素不被拖出窗口外
745 if(!config.moveOut){ 745 if(!config.moveOut){
746 var setRig = win.width() - layero.outerWidth() + dict.stX 746 var setRig = win.width() - layero.outerWidth() + dict.stX
747 - ,setBot = win.height() - layero.outerHeight() + dict.stY; 747 + ,setBot = win.height() - layero.outerHeight() + dict.stY;
748 X < dict.stX && (X = dict.stX); 748 X < dict.stX && (X = dict.stX);
749 - X > setRig && (X = setRig); 749 + X > setRig && (X = setRig);
750 Y < dict.stY && (Y = dict.stY); 750 Y < dict.stY && (Y = dict.stY);
751 Y > setBot && (Y = setBot); 751 Y > setBot && (Y = setBot);
752 } 752 }
753 - 753 +
754 layero.css({ 754 layero.css({
755 left: X 755 left: X
756 ,top: Y 756 ,top: Y
757 }); 757 });
758 } 758 }
759 - 759 +
760 //Resize 760 //Resize
761 if(config.resize && dict.resizeStart){ 761 if(config.resize && dict.resizeStart){
762 var X = e.clientX - dict.offset[0] 762 var X = e.clientX - dict.offset[0]
763 ,Y = e.clientY - dict.offset[1]; 763 ,Y = e.clientY - dict.offset[1];
764 - 764 +
765 e.preventDefault(); 765 e.preventDefault();
766 - 766 +
767 layer.style(that.index, { 767 layer.style(that.index, {
768 width: dict.area[0] + X 768 width: dict.area[0] + X
769 ,height: dict.area[1] + Y 769 ,height: dict.area[1] + Y
@@ -781,7 +781,7 @@ Class.pt.move = function(){ @@ -781,7 +781,7 @@ Class.pt.move = function(){
781 ready.moveElem.hide(); 781 ready.moveElem.hide();
782 } 782 }
783 }); 783 });
784 - 784 +
785 return that; 785 return that;
786 }; 786 };
787 787
@@ -798,7 +798,7 @@ Class.pt.callback = function(){ @@ -798,7 +798,7 @@ Class.pt.callback = function(){
798 } 798 }
799 } 799 }
800 layer.ie == 6 && that.IE6(layero); 800 layer.ie == 6 && that.IE6(layero);
801 - 801 +
802 //按钮 802 //按钮
803 layero.find('.'+ doms[6]).children('a').on('click', function(){ 803 layero.find('.'+ doms[6]).children('a').on('click', function(){
804 var index = $(this).index(); 804 var index = $(this).index();
@@ -815,29 +815,29 @@ Class.pt.callback = function(){ @@ -815,29 +815,29 @@ Class.pt.callback = function(){
815 close === false || layer.close(that.index); 815 close === false || layer.close(that.index);
816 } 816 }
817 }); 817 });
818 - 818 +
819 //取消 819 //取消
820 function cancel(){ 820 function cancel(){
821 var close = config.cancel && config.cancel(that.index, layero); 821 var close = config.cancel && config.cancel(that.index, layero);
822 close === false || layer.close(that.index); 822 close === false || layer.close(that.index);
823 } 823 }
824 - 824 +
825 //右上角关闭回调 825 //右上角关闭回调
826 layero.find('.'+ doms[7]).on('click', cancel); 826 layero.find('.'+ doms[7]).on('click', cancel);
827 - 827 +
828 //点遮罩关闭 828 //点遮罩关闭
829 if(config.shadeClose){ 829 if(config.shadeClose){
830 $('#layui-layer-shade'+ that.index).on('click', function(){ 830 $('#layui-layer-shade'+ that.index).on('click', function(){
831 layer.close(that.index); 831 layer.close(that.index);
832 }); 832 });
833 - }  
834 - 833 + }
  834 +
835 //最小化 835 //最小化
836 layero.find('.layui-layer-min').on('click', function(){ 836 layero.find('.layui-layer-min').on('click', function(){
837 var min = config.min && config.min(layero); 837 var min = config.min && config.min(layero);
838 - min === false || layer.min(that.index, config); 838 + min === false || layer.min(that.index, config);
839 }); 839 });
840 - 840 +
841 //全屏/还原 841 //全屏/还原
842 layero.find('.layui-layer-max').on('click', function(){ 842 layero.find('.layui-layer-max').on('click', function(){
843 if($(this).hasClass('layui-layer-maxmin')){ 843 if($(this).hasClass('layui-layer-maxmin')){
@@ -859,11 +859,11 @@ ready.reselect = function(){ @@ -859,11 +859,11 @@ ready.reselect = function(){
859 $.each($('select'), function(index , value){ 859 $.each($('select'), function(index , value){
860 var sthis = $(this); 860 var sthis = $(this);
861 if(!sthis.parents('.'+doms[0])[0]){ 861 if(!sthis.parents('.'+doms[0])[0]){
862 - (sthis.attr('layer') == 1 && $('.'+doms[0]).length < 1) && sthis.removeAttr('layer').show(); 862 + (sthis.attr('layer') == 1 && $('.'+doms[0]).length < 1) && sthis.removeAttr('layer').show();
863 } 863 }
864 sthis = null; 864 sthis = null;
865 }); 865 });
866 -}; 866 +};
867 867
868 Class.pt.IE6 = function(layero){ 868 Class.pt.IE6 = function(layero){
869 //隐藏select 869 //隐藏select
@@ -879,7 +879,7 @@ Class.pt.IE6 = function(layero){ @@ -879,7 +879,7 @@ Class.pt.IE6 = function(layero){
879 //需依赖原型的对外方法 879 //需依赖原型的对外方法
880 Class.pt.openLayer = function(){ 880 Class.pt.openLayer = function(){
881 var that = this; 881 var that = this;
882 - 882 +
883 //置顶当前窗口 883 //置顶当前窗口
884 layer.zIndex = that.config.zIndex; 884 layer.zIndex = that.config.zIndex;
885 layer.setTop = function(layero){ 885 layer.setTop = function(layero){
@@ -897,7 +897,7 @@ ready.record = function(layero){ @@ -897,7 +897,7 @@ ready.record = function(layero){
897 var area = [ 897 var area = [
898 layero.width(), 898 layero.width(),
899 layero.height(), 899 layero.height(),
900 - layero.position().top, 900 + layero.position().top,
901 layero.position().left + parseFloat(layero.css('margin-left')) 901 layero.position().left + parseFloat(layero.css('margin-left'))
902 ]; 902 ];
903 layero.find('.layui-layer-max').addClass('layui-layer-maxmin'); 903 layero.find('.layui-layer-max').addClass('layui-layer-maxmin');
@@ -922,7 +922,7 @@ window.layer = layer; @@ -922,7 +922,7 @@ window.layer = layer;
922 //获取子iframe的DOM 922 //获取子iframe的DOM
923 layer.getChildFrame = function(selector, index){ 923 layer.getChildFrame = function(selector, index){
924 index = index || $('.'+doms[4]).attr('times'); 924 index = index || $('.'+doms[4]).attr('times');
925 - return $('#'+ doms[0] + index).find('iframe').contents().find(selector); 925 + return $('#'+ doms[0] + index).find('iframe').contents().find(selector);
926 }; 926 };
927 927
928 //得到当前iframe层的索引,子iframe时使用 928 //得到当前iframe层的索引,子iframe时使用
@@ -954,24 +954,24 @@ layer.style = function(index, options, limit){ @@ -954,24 +954,24 @@ layer.style = function(index, options, limit){
954 ,titHeight = layero.find(doms[1]).outerHeight() || 0 954 ,titHeight = layero.find(doms[1]).outerHeight() || 0
955 ,btnHeight = layero.find('.'+doms[6]).outerHeight() || 0 955 ,btnHeight = layero.find('.'+doms[6]).outerHeight() || 0
956 ,minLeft = layero.attr('minLeft'); 956 ,minLeft = layero.attr('minLeft');
957 - 957 +
958 if(type === ready.type[3] || type === ready.type[4]){ 958 if(type === ready.type[3] || type === ready.type[4]){
959 return; 959 return;
960 } 960 }
961 - 961 +
962 if(!limit){ 962 if(!limit){
963 if(parseFloat(options.width) <= 260){ 963 if(parseFloat(options.width) <= 260){
964 options.width = 260; 964 options.width = 260;
965 }; 965 };
966 - 966 +
967 if(parseFloat(options.height) - titHeight - btnHeight <= 64){ 967 if(parseFloat(options.height) - titHeight - btnHeight <= 64){
968 options.height = 64 + titHeight + btnHeight; 968 options.height = 64 + titHeight + btnHeight;
969 }; 969 };
970 } 970 }
971 - 971 +
972 layero.css(options); 972 layero.css(options);
973 btnHeight = layero.find('.'+doms[6]).outerHeight(); 973 btnHeight = layero.find('.'+doms[6]).outerHeight();
974 - 974 +
975 if(type === ready.type[2]){ 975 if(type === ready.type[2]){
976 layero.find('iframe').css({ 976 layero.find('iframe').css({
977 height: parseFloat(options.height) - titHeight - btnHeight 977 height: parseFloat(options.height) - titHeight - btnHeight
@@ -991,16 +991,16 @@ layer.min = function(index, options){ @@ -991,16 +991,16 @@ layer.min = function(index, options){
991 ,titHeight = layero.find(doms[1]).outerHeight() || 0 991 ,titHeight = layero.find(doms[1]).outerHeight() || 0
992 ,left = layero.attr('minLeft') || (181*ready.minIndex)+'px' 992 ,left = layero.attr('minLeft') || (181*ready.minIndex)+'px'
993 ,position = layero.css('position'); 993 ,position = layero.css('position');
994 - 994 +
995 ready.record(layero); 995 ready.record(layero);
996 - 996 +
997 if(ready.minLeft[0]){ 997 if(ready.minLeft[0]){
998 left = ready.minLeft[0]; 998 left = ready.minLeft[0];
999 ready.minLeft.shift(); 999 ready.minLeft.shift();
1000 } 1000 }
1001 - 1001 +
1002 layero.attr('position', position); 1002 layero.attr('position', position);
1003 - 1003 +
1004 layer.style(index, { 1004 layer.style(index, {
1005 width: 180 1005 width: 180
1006 ,height: titHeight 1006 ,height: titHeight
@@ -1013,7 +1013,7 @@ layer.min = function(index, options){ @@ -1013,7 +1013,7 @@ layer.min = function(index, options){
1013 layero.find('.layui-layer-min').hide(); 1013 layero.find('.layui-layer-min').hide();
1014 layero.attr('type') === 'page' && layero.find(doms[4]).hide(); 1014 layero.attr('type') === 'page' && layero.find(doms[4]).hide();
1015 ready.rescollbar(index); 1015 ready.rescollbar(index);
1016 - 1016 +
1017 if(!layero.attr('minLeft')){ 1017 if(!layero.attr('minLeft')){
1018 ready.minIndex++; 1018 ready.minIndex++;
1019 } 1019 }
@@ -1025,9 +1025,9 @@ layer.restore = function(index){ @@ -1025,9 +1025,9 @@ layer.restore = function(index){
1025 var layero = $('#'+ doms[0] + index), area = layero.attr('area').split(','); 1025 var layero = $('#'+ doms[0] + index), area = layero.attr('area').split(',');
1026 var type = layero.attr('type'); 1026 var type = layero.attr('type');
1027 layer.style(index, { 1027 layer.style(index, {
1028 - width: parseFloat(area[0]),  
1029 - height: parseFloat(area[1]),  
1030 - top: parseFloat(area[2]), 1028 + width: parseFloat(area[0]),
  1029 + height: parseFloat(area[1]),
  1030 + top: parseFloat(area[2]),
1031 left: parseFloat(area[3]), 1031 left: parseFloat(area[3]),
1032 position: layero.attr('position'), 1032 position: layero.attr('position'),
1033 overflow: 'visible' 1033 overflow: 'visible'
@@ -1090,16 +1090,16 @@ layer.close = function(index){ @@ -1090,16 +1090,16 @@ layer.close = function(index){
1090 layero.remove(); 1090 layero.remove();
1091 } 1091 }
1092 }; 1092 };
1093 - 1093 +
1094 if(layero.data('anim')){ 1094 if(layero.data('anim')){
1095 layero.addClass(closeAnim); 1095 layero.addClass(closeAnim);
1096 } 1096 }
1097 - 1097 +
1098 $('#layui-layer-moves, #layui-layer-shade' + index).remove(); 1098 $('#layui-layer-moves, #layui-layer-shade' + index).remove();
1099 layer.ie == 6 && ready.reselect(); 1099 layer.ie == 6 && ready.reselect();
1100 ready.rescollbar(index); 1100 ready.rescollbar(index);
1101 typeof ready.end[index] === 'function' && ready.end[index](); 1101 typeof ready.end[index] === 'function' && ready.end[index]();
1102 - delete ready.end[index]; 1102 + delete ready.end[index];
1103 if(layero.attr('minLeft')){ 1103 if(layero.attr('minLeft')){
1104 ready.minIndex--; 1104 ready.minIndex--;
1105 ready.minLeft.push(layero.attr('minLeft')); 1105 ready.minLeft.push(layero.attr('minLeft'));
@@ -1119,7 +1119,7 @@ layer.closeAll = function(type){ @@ -1119,7 +1119,7 @@ layer.closeAll = function(type){
1119 }); 1119 });
1120 }; 1120 };
1121 1121
1122 -/** 1122 +/**
1123 1123
1124 拓展模块,layui开始合并在一起 1124 拓展模块,layui开始合并在一起
1125 1125
@@ -1127,15 +1127,15 @@ layer.closeAll = function(type){ @@ -1127,15 +1127,15 @@ layer.closeAll = function(type){
1127 1127
1128 var cache = layer.cache||{}, skin = function(type){ 1128 var cache = layer.cache||{}, skin = function(type){
1129 return (cache.skin ? (' ' + cache.skin + ' ' + cache.skin + '-'+type) : ''); 1129 return (cache.skin ? (' ' + cache.skin + ' ' + cache.skin + '-'+type) : '');
1130 -};  
1131 - 1130 +};
  1131 +
1132 //仿系统prompt 1132 //仿系统prompt
1133 layer.prompt = function(options, yes){ 1133 layer.prompt = function(options, yes){
1134 var style = ''; 1134 var style = '';
1135 options = options || {}; 1135 options = options || {};
1136 - 1136 +
1137 if(typeof options === 'function') yes = options; 1137 if(typeof options === 'function') yes = options;
1138 - 1138 +
1139 if(options.area){ 1139 if(options.area){
1140 var area = options.area; 1140 var area = options.area;
1141 style = 'style="width: '+ area[0] +'; height: '+ area[1] + ';"'; 1141 style = 'style="width: '+ area[0] +'; height: '+ area[1] + ';"';
@@ -1144,7 +1144,7 @@ layer.prompt = function(options, yes){ @@ -1144,7 +1144,7 @@ layer.prompt = function(options, yes){
1144 var prompt, content = options.formType == 2 ? '<textarea class="layui-layer-input"' + style +'>' + (options.value||'') +'</textarea>' : function(){ 1144 var prompt, content = options.formType == 2 ? '<textarea class="layui-layer-input"' + style +'>' + (options.value||'') +'</textarea>' : function(){
1145 return '<input type="'+ (options.formType == 1 ? 'password' : 'text') +'" class="layui-layer-input" value="'+ (options.value||'') +'">'; 1145 return '<input type="'+ (options.formType == 1 ? 'password' : 'text') +'" class="layui-layer-input" value="'+ (options.value||'') +'">';
1146 }(); 1146 }();
1147 - 1147 +
1148 return layer.open($.extend({ 1148 return layer.open($.extend({
1149 type: 1 1149 type: 1
1150 ,btn: ['&#x786E;&#x5B9A;','&#x53D6;&#x6D88;'] 1150 ,btn: ['&#x786E;&#x5B9A;','&#x53D6;&#x6D88;']
@@ -1220,7 +1220,7 @@ layer.photos = function(options, loop, key){ @@ -1220,7 +1220,7 @@ layer.photos = function(options, loop, key){
1220 var photos = type ? options.photos : {}, data = photos.data || []; 1220 var photos = type ? options.photos : {}, data = photos.data || [];
1221 var start = photos.start || 0; 1221 var start = photos.start || 0;
1222 dict.imgIndex = (start|0) + 1; 1222 dict.imgIndex = (start|0) + 1;
1223 - 1223 +
1224 options.img = options.img || 'img'; 1224 options.img = options.img || 'img';
1225 1225
1226 if(!type){ //页面直接获取 1226 if(!type){ //页面直接获取
@@ -1237,13 +1237,13 @@ layer.photos = function(options, loop, key){ @@ -1237,13 +1237,13 @@ layer.photos = function(options, loop, key){
1237 }); 1237 });
1238 }) 1238 })
1239 }; 1239 };
1240 - 1240 +
1241 pushData(); 1241 pushData();
1242 - 1242 +
1243 if (data.length === 0) return; 1243 if (data.length === 0) return;
1244 - 1244 +
1245 loop || parent.on('click', options.img, function(){ 1245 loop || parent.on('click', options.img, function(){
1246 - var othis = $(this), index = othis.attr('layer-index'); 1246 + var othis = $(this), index = othis.attr('layer-index');
1247 layer.photos($.extend(options, { 1247 layer.photos($.extend(options, {
1248 photos: { 1248 photos: {
1249 start: index, 1249 start: index,
@@ -1254,14 +1254,14 @@ layer.photos = function(options, loop, key){ @@ -1254,14 +1254,14 @@ layer.photos = function(options, loop, key){
1254 }), true); 1254 }), true);
1255 pushData(); 1255 pushData();
1256 }) 1256 })
1257 - 1257 +
1258 //不直接弹出 1258 //不直接弹出
1259 if(!loop) return; 1259 if(!loop) return;
1260 - 1260 +
1261 } else if (data.length === 0){ 1261 } else if (data.length === 0){
1262 return layer.msg('&#x6CA1;&#x6709;&#x56FE;&#x7247;'); 1262 return layer.msg('&#x6CA1;&#x6709;&#x56FE;&#x7247;');
1263 } 1263 }
1264 - 1264 +
1265 //上一张 1265 //上一张
1266 dict.imgprev = function(key){ 1266 dict.imgprev = function(key){
1267 dict.imgIndex--; 1267 dict.imgIndex--;
@@ -1270,7 +1270,7 @@ layer.photos = function(options, loop, key){ @@ -1270,7 +1270,7 @@ layer.photos = function(options, loop, key){
1270 } 1270 }
1271 dict.tabimg(key); 1271 dict.tabimg(key);
1272 }; 1272 };
1273 - 1273 +
1274 //下一张 1274 //下一张
1275 dict.imgnext = function(key,errorMsg){ 1275 dict.imgnext = function(key,errorMsg){
1276 dict.imgIndex++; 1276 dict.imgIndex++;
@@ -1280,7 +1280,7 @@ layer.photos = function(options, loop, key){ @@ -1280,7 +1280,7 @@ layer.photos = function(options, loop, key){
1280 } 1280 }
1281 dict.tabimg(key) 1281 dict.tabimg(key)
1282 }; 1282 };
1283 - 1283 +
1284 //方向键 1284 //方向键
1285 dict.keyup = function(event){ 1285 dict.keyup = function(event){
1286 if(!dict.end){ 1286 if(!dict.end){
@@ -1295,7 +1295,7 @@ layer.photos = function(options, loop, key){ @@ -1295,7 +1295,7 @@ layer.photos = function(options, loop, key){
1295 } 1295 }
1296 } 1296 }
1297 } 1297 }
1298 - 1298 +
1299 //切换 1299 //切换
1300 dict.tabimg = function(key){ 1300 dict.tabimg = function(key){
1301 if(data.length <= 1) return; 1301 if(data.length <= 1) return;
@@ -1303,7 +1303,7 @@ layer.photos = function(options, loop, key){ @@ -1303,7 +1303,7 @@ layer.photos = function(options, loop, key){
1303 layer.close(dict.index); 1303 layer.close(dict.index);
1304 layer.photos(options, true, key); 1304 layer.photos(options, true, key);
1305 } 1305 }
1306 - 1306 +
1307 //一些动作 1307 //一些动作
1308 dict.event = function(){ 1308 dict.event = function(){
1309 dict.bigimg.hover(function(){ 1309 dict.bigimg.hover(function(){
@@ -1311,24 +1311,24 @@ layer.photos = function(options, loop, key){ @@ -1311,24 +1311,24 @@ layer.photos = function(options, loop, key){
1311 }, function(){ 1311 }, function(){
1312 dict.imgsee.hide(); 1312 dict.imgsee.hide();
1313 }); 1313 });
1314 - 1314 +
1315 dict.bigimg.find('.layui-layer-imgprev').on('click', function(event){ 1315 dict.bigimg.find('.layui-layer-imgprev').on('click', function(event){
1316 event.preventDefault(); 1316 event.preventDefault();
1317 dict.imgprev(); 1317 dict.imgprev();
1318 - });  
1319 -  
1320 - dict.bigimg.find('.layui-layer-imgnext').on('click', function(event){ 1318 + });
  1319 +
  1320 + dict.bigimg.find('.layui-layer-imgnext').on('click', function(event){
1321 event.preventDefault(); 1321 event.preventDefault();
1322 dict.imgnext(); 1322 dict.imgnext();
1323 }); 1323 });
1324 - 1324 +
1325 $(document).on('keyup', dict.keyup); 1325 $(document).on('keyup', dict.keyup);
1326 }; 1326 };
1327 - 1327 +
1328 //图片预加载 1328 //图片预加载
1329 - function loadImage(url, callback, error) { 1329 + function loadImage(url, callback, error) {
1330 var img = new Image(); 1330 var img = new Image();
1331 - img.src = url; 1331 + img.src = url;
1332 if(img.complete){ 1332 if(img.complete){
1333 return callback(img); 1333 return callback(img);
1334 } 1334 }
@@ -1339,9 +1339,9 @@ layer.photos = function(options, loop, key){ @@ -1339,9 +1339,9 @@ layer.photos = function(options, loop, key){
1339 img.onerror = function(e){ 1339 img.onerror = function(e){
1340 img.onerror = null; 1340 img.onerror = null;
1341 error(e); 1341 error(e);
1342 - }; 1342 + };
1343 }; 1343 };
1344 - 1344 +
1345 dict.loadi = layer.load(1, { 1345 dict.loadi = layer.load(1, {
1346 shade: 'shade' in options ? false : 0.9, 1346 shade: 'shade' in options ? false : 0.9,
1347 scrollbar: false 1347 scrollbar: false
@@ -1353,7 +1353,7 @@ layer.photos = function(options, loop, key){ @@ -1353,7 +1353,7 @@ layer.photos = function(options, loop, key){
1353 area: function(){ 1353 area: function(){
1354 var imgarea = [img.width, img.height]; 1354 var imgarea = [img.width, img.height];
1355 var winarea = [$(window).width() - 100, $(window).height() - 100]; 1355 var winarea = [$(window).width() - 100, $(window).height() - 100];
1356 - 1356 +
1357 //如果 实际图片的宽或者高比 屏幕大(那么进行缩放) 1357 //如果 实际图片的宽或者高比 屏幕大(那么进行缩放)
1358 if(!options.full && (imgarea[0]>winarea[0]||imgarea[1]>winarea[1])){ 1358 if(!options.full && (imgarea[0]>winarea[0]||imgarea[1]>winarea[1])){
1359 var wh = [imgarea[0]/winarea[0],imgarea[1]/winarea[1]];//取宽度缩放比例、高度缩放比例 1359 var wh = [imgarea[0]/winarea[0],imgarea[1]/winarea[1]];//取宽度缩放比例、高度缩放比例
@@ -1365,8 +1365,8 @@ layer.photos = function(options, loop, key){ @@ -1365,8 +1365,8 @@ layer.photos = function(options, loop, key){
1365 imgarea[1] = imgarea[1]/wh[1]; 1365 imgarea[1] = imgarea[1]/wh[1];
1366 } 1366 }
1367 } 1367 }
1368 -  
1369 - return [imgarea[0]+'px', imgarea[1]+'px']; 1368 +
  1369 + return [imgarea[0]+'px', imgarea[1]+'px'];
1370 }(), 1370 }(),
1371 title: false, 1371 title: false,
1372 shade: 0.9, 1372 shade: 0.9,
@@ -1398,8 +1398,8 @@ layer.photos = function(options, loop, key){ @@ -1398,8 +1398,8 @@ layer.photos = function(options, loop, key){
1398 }, function(){ 1398 }, function(){
1399 layer.close(dict.loadi); 1399 layer.close(dict.loadi);
1400 layer.msg('&#x5F53;&#x524D;&#x56FE;&#x7247;&#x5730;&#x5740;&#x5F02;&#x5E38;<br>&#x662F;&#x5426;&#x7EE7;&#x7EED;&#x67E5;&#x770B;&#x4E0B;&#x4E00;&#x5F20;&#xFF1F;', { 1400 layer.msg('&#x5F53;&#x524D;&#x56FE;&#x7247;&#x5730;&#x5740;&#x5F02;&#x5E38;<br>&#x662F;&#x5426;&#x7EE7;&#x7EED;&#x67E5;&#x770B;&#x4E0B;&#x4E00;&#x5F20;&#xFF1F;', {
1401 - time: 30000,  
1402 - btn: ['&#x4E0B;&#x4E00;&#x5F20;', '&#x4E0D;&#x770B;&#x4E86;'], 1401 + time: 30000,
  1402 + btn: ['&#x4E0B;&#x4E00;&#x5F20;', '&#x4E0D;&#x770B;&#x4E86;'],
1403 yes: function(){ 1403 yes: function(){
1404 data.length > 1 && dict.imgnext(true,true); 1404 data.length > 1 && dict.imgnext(true,true);
1405 } 1405 }
@@ -317,6 +317,10 @@ body { @@ -317,6 +317,10 @@ body {
317 border:none!important; 317 border:none!important;
318 } 318 }
319 319
  320 +.note-editor .note-editing-area .note-editable{
  321 + display: block !important;
  322 +}
  323 +
320 .pjax-loader-bar .progress { 324 .pjax-loader-bar .progress {
321 position: fixed; 325 position: fixed;
322 top: 0; 326 top: 0;