作者 王智

'源码'

正在显示 48 个修改的文件 包含 4492 行增加0 行删除

要显示太多修改。

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

{
"directory": "public/assets/libs",
"ignoredDependencies": [
"es6-promise",
"file-saver",
"html2canvas",
"jspdf",
"jspdf-autotable"
]
}
\ No newline at end of file
... ...
[app]
debug = false
trace = false
[database]
hostname = 127.0.0.1
database = fastadmin
username = root
password = root
hostport = 3306
prefix = fa_
... ...
database.php
/nbproject/
/runtime/*
/public/uploads/*
.idea
composer.lock
*.log
*.css.map
!.gitkeep
.env
.svn
.vscode
... ...
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction, and
distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by the copyright
owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all other entities
that control, are controlled by, or are under common control with that entity.
For the purposes of this definition, "control" means (i) the power, direct or
indirect, to cause the direction or management of such entity, whether by
contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity exercising
permissions granted by this License.
"Source" form shall mean the preferred form for making modifications, including
but not limited to software source code, documentation source, and configuration
files.
"Object" form shall mean any form resulting from mechanical transformation or
translation of a Source form, including but not limited to compiled object code,
generated documentation, and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or Object form, made
available under the License, as indicated by a copyright notice that is included
in or attached to the work (an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object form, that
is based on (or derived from) the Work and for which the editorial revisions,
annotations, elaborations, or other modifications represent, as a whole, an
original work of authorship. For the purposes of this License, Derivative Works
shall not include works that remain separable from, or merely link (or bind by
name) to the interfaces of, the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including the original version
of the Work and any modifications or additions to that Work or Derivative Works
thereof, that is intentionally submitted to Licensor for inclusion in the Work
by the copyright owner or by an individual or Legal Entity authorized to submit
on behalf of the copyright owner. For the purposes of this definition,
"submitted" means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems, and
issue tracking systems that are managed by, or on behalf of, the Licensor for
the purpose of discussing and improving the Work, but excluding communication
that is conspicuously marked or otherwise designated in writing by the copyright
owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity on behalf
of whom a Contribution has been received by Licensor and subsequently
incorporated within the Work.
2. Grant of Copyright License.
Subject to the terms and conditions of this License, each Contributor hereby
grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
irrevocable copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the Work and such
Derivative Works in Source or Object form.
3. Grant of Patent License.
Subject to the terms and conditions of this License, each Contributor hereby
grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
irrevocable (except as stated in this section) patent license to make, have
made, use, offer to sell, sell, import, and otherwise transfer the Work, where
such license applies only to those patent claims licensable by such Contributor
that are necessarily infringed by their Contribution(s) alone or by combination
of their Contribution(s) with the Work to which such Contribution(s) was
submitted. If You institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work or a
Contribution incorporated within the Work constitutes direct or contributory
patent infringement, then any patent licenses granted to You under this License
for that Work shall terminate as of the date such litigation is filed.
4. Redistribution.
You may reproduce and distribute copies of the Work or Derivative Works thereof
in any medium, with or without modifications, and in Source or Object form,
provided that You meet the following conditions:
You must give any other recipients of the Work or Derivative Works a copy of
this License; and
You must cause any modified files to carry prominent notices stating that You
changed the files; and
You must retain, in the Source form of any Derivative Works that You distribute,
all copyright, patent, trademark, and attribution notices from the Source form
of the Work, excluding those notices that do not pertain to any part of the
Derivative Works; and
If the Work includes a "NOTICE" text file as part of its distribution, then any
Derivative Works that You distribute must include a readable copy of the
attribution notices contained within such NOTICE file, excluding those notices
that do not pertain to any part of the Derivative Works, in at least one of the
following places: within a NOTICE text file distributed as part of the
Derivative Works; within the Source form or documentation, if provided along
with the Derivative Works; or, within a display generated by the Derivative
Works, if and wherever such third-party notices normally appear. The contents of
the NOTICE file are for informational purposes only and do not modify the
License. You may add Your own attribution notices within Derivative Works that
You distribute, alongside or as an addendum to the NOTICE text from the Work,
provided that such additional attribution notices cannot be construed as
modifying the License.
You may add Your own copyright statement to Your modifications and may provide
additional or different license terms and conditions for use, reproduction, or
distribution of Your modifications, or for any such Derivative Works as a whole,
provided Your use, reproduction, and distribution of the Work otherwise complies
with the conditions stated in this License.
5. Submission of Contributions.
Unless You explicitly state otherwise, any Contribution intentionally submitted
for inclusion in the Work by You to the Licensor shall be under the terms and
conditions of this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify the terms of
any separate license agreement you may have executed with Licensor regarding
such Contributions.
6. Trademarks.
This License does not grant permission to use the trade names, trademarks,
service marks, or product names of the Licensor, except as required for
reasonable and customary use in describing the origin of the Work and
reproducing the content of the NOTICE file.
7. Disclaimer of Warranty.
Unless required by applicable law or agreed to in writing, Licensor provides the
Work (and each Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
including, without limitation, any warranties or conditions of TITLE,
NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are
solely responsible for determining the appropriateness of using or
redistributing the Work and assume any risks associated with Your exercise of
permissions under this License.
8. Limitation of Liability.
In no event and under no legal theory, whether in tort (including negligence),
contract, or otherwise, unless required by applicable law (such as deliberate
and grossly negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special, incidental,
or consequential damages of any character arising as a result of this License or
out of the use or inability to use the Work (including but not limited to
damages for loss of goodwill, work stoppage, computer failure or malfunction, or
any and all other commercial damages or losses), even if such Contributor has
been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability.
While redistributing the Work or Derivative Works thereof, You may choose to
offer, and charge a fee for, acceptance of support, warranty, indemnity, or
other liability obligations and/or rights consistent with this License. However,
in accepting such obligations, You may act only on Your own behalf and on Your
sole responsibility, not on behalf of any other Contributor, and only if You
agree to indemnify, defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason of your
accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work
To apply the Apache License to your work, attach the following boilerplate
notice, with the fields enclosed by brackets "{}" replaced with your own
identifying information. (Don't include the brackets!) The text should be
enclosed in the appropriate comment syntax for the file format. We also
recommend that a file or class name and description of purpose be included on
the same "printed page" as the copyright notice for easier identification within
third-party archives.
Copyright 2017 Karson
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
\ No newline at end of file
... ...
FastAdmin是一款基于ThinkPHP5+Bootstrap的极速后台开发框架。
## 主要特性
* 基于`Auth`验证的权限管理系统
* 支持无限级父子级权限继承,父级的管理员可任意增删改子级管理员及权限设置
* 支持单管理员多角色
* 支持管理子级数据或个人数据
* 强大的一键生成功能
* 一键生成CRUD,包括控制器、模型、视图、JS、语言包、菜单、回收站等
* 一键压缩打包JS和CSS文件,一键CDN静态资源部署
* 一键生成控制器菜单和规则
* 一键生成API接口文档
* 完善的前端功能组件开发
* 基于`AdminLTE`二次开发
* 基于`Bootstrap`开发,自适应手机、平板、PC
* 基于`RequireJS`进行JS模块管理,按需加载
* 基于`Less`进行样式开发
* 基于`Bower`进行前端组件包管理
* 强大的插件扩展功能,在线安装卸载升级插件
* 通用的会员模块和API模块
* 共用同一账号体系的Web端会员中心权限验证和API接口会员权限验证
* 二级域名部署支持,同时域名支持绑定到插件
* 多语言支持,服务端及客户端支持
* 强大的第三方模块支持([CMS](https://www.fastadmin.net/store/cms.html)[博客](https://www.fastadmin.net/store/blog.html)[知识付费问答](https://www.fastadmin.net/store/ask.html)[在线投票系统](https://www.fastadmin.net/store/vote.html))
* 支持CMS、博客、知识付费问答无缝整合[Xunsearch全文搜索](https://www.fastadmin.net/store/xunsearch.html)
* 第三方小程序支持([预订小程序](https://www.fastadmin.net/store/ball.html)[问答小程序](https://www.fastadmin.net/store/questions.html)[活动报名小程序](https://www.fastadmin.net/store/huodong.html)[商城小程序](https://www.fastadmin.net/store/xshop.html)[博客小程序](https://www.fastadmin.net/store/blog.html))
* 整合第三方短信接口(阿里云、腾讯云短信)
* 无缝整合第三方云存储(七牛、阿里云OSS、又拍云)功能
* 第三方富文本编辑器支持(Summernote、Kindeditor、百度编辑器)
* 第三方登录(QQ、微信、微博)整合
* 第三方支付(微信、支付宝)无缝整合,微信支持PC端扫码支付
* 丰富的插件应用市场
## 安装使用
https://doc.fastadmin.net
## 在线演示
https://demo.fastadmin.net
用户名:admin
密 码:123456
提 示:演示站数据无法进行修改,请下载源码安装体验全部功能
## 界面截图
![控制台](https://gitee.com/uploads/images/2017/0411/113717_e99ff3e7_10933.png "控制台")
## 问题反馈
在使用中有任何问题,请使用以下联系方式联系我们
交流社区: https://ask.fastadmin.net
QQ群: [636393962](https://jq.qq.com/?_wv=1027&k=487PNBb)() [708784003](https://jq.qq.com/?_wv=1027&k=5ObjtwM)(满) [964776039](https://jq.qq.com/?_wv=1027&k=59qjU2P)(3群) [749803490](https://jq.qq.com/?_wv=1027&k=5tczi88)(满) [767103006](https://jq.qq.com/?_wv=1027&k=5Z1U751)() [675115483](https://jq.qq.com/?_wv=1027&k=54I6mts)(6群)
Github: https://github.com/karsonzhang/fastadmin
Gitee: https://gitee.com/karson/fastadmin
## 特别鸣谢
感谢以下的项目,排名不分先后
ThinkPHP:http://www.thinkphp.cn
AdminLTE:https://adminlte.io
Bootstrap:http://getbootstrap.com
jQuery:http://jquery.com
Bootstrap-table:https://github.com/wenzhixin/bootstrap-table
Nice-validator: https://validator.niceue.com
SelectPage: https://github.com/TerryZ/SelectPage
## 版权信息
FastAdmin遵循Apache2开源协议发布,并提供免费使用。
本项目包含的第三方源码和二进制文件之版权信息另行标注。
版权所有Copyright © 2017-2020 by FastAdmin (https://www.fastadmin.net)
All rights reserved。
... ...
<?php
namespace addons\address;
use think\Addons;
/**
* 地址选择
* @author [MiniLing] <[laozheyouxiang@163.com]>
*/
class Address extends Addons
{
/**
* 插件安装方法
* @return bool
*/
public function install()
{
return true;
}
/**
* 插件卸载方法
* @return bool
*/
public function uninstall()
{
return true;
}
}
... ...
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) {
}
}
});
});
});
... ...
<?php
return array(
array(
'name' => 'maptype',
'title' => '默认地图类型',
'type' => 'radio',
'content' =>
array(
'baidu' => '百度地图',
'amap' => '高德地图',
'tencent' => '腾讯地图',
),
'value' => 'baidu',
'rule' => 'required',
'msg' => '',
'tip' => '',
'ok' => '',
'extend' => '',
),
array(
'name' => 'location',
'title' => '默认检索城市',
'type' => 'string',
'content' =>
array(),
'value' => '北京',
'rule' => 'required',
'msg' => '',
'tip' => '',
'ok' => '',
'extend' => '',
),
array(
'name' => 'zoom',
'title' => '默认缩放级别',
'type' => 'string',
'content' =>
array(),
'value' => '12',
'rule' => 'required',
'msg' => '',
'tip' => '',
'ok' => '',
'extend' => '',
),
array(
'name' => 'lat',
'title' => '默认Lat',
'type' => 'string',
'content' =>
array(),
'value' => '39.919990',
'rule' => 'required',
'msg' => '',
'tip' => '',
'ok' => '',
'extend' => '',
),
array(
'name' => 'lng',
'title' => '默认Lng',
'type' => 'string',
'content' =>
array(),
'value' => '116.456270',
'rule' => 'required',
'msg' => '',
'tip' => '',
'ok' => '',
'extend' => '',
),
array(
'name' => 'baidukey',
'title' => '百度地图KEY',
'type' => 'string',
'content' =>
array(),
'value' => 'hAeMFHmpyHa2ZjaCH9VVridl',
'rule' => 'required',
'msg' => '',
'tip' => '',
'ok' => '',
'extend' => '',
),
array(
'name' => 'amapkey',
'title' => '高德地图KEY',
'type' => 'string',
'content' =>
array(),
'value' => '608d75903d29ad471362f8c58c550daf',
'rule' => 'required',
'msg' => '',
'tip' => '',
'ok' => '',
'extend' => '',
),
array(
'name' => 'tencentkey',
'title' => '腾讯地图KEY',
'type' => 'string',
'content' =>
array(),
'value' => '608d75903d29ad471362f8c58c550daf',
'rule' => 'required',
'msg' => '',
'tip' => '',
'ok' => '',
'extend' => '',
),
array(
'name' => '__tips__',
'title' => '温馨提示',
'type' => '',
'content' =>
array(),
'value' => '请先申请对应地图的Key,配置后再使用',
'rule' => '',
'msg' => '',
'tip' => '',
'ok' => '',
'extend' => 'alert-danger-light',
),
);
... ...
<?php
namespace addons\address\controller;
use think\addons\Controller;
use think\Config;
use think\Hook;
class Index extends Controller
{
public function index()
{
// 语言检测
$lang = strip_tags($this->request->langset());
$site = Config::get("site");
// 配置信息
$config = [
'site' => array_intersect_key($site, array_flip(['name', 'cdnurl', 'version', 'timezone', 'languages'])),
'upload' => null,
'modulename' => 'addons',
'controllername' => 'index',
'actionname' => 'index',
'jsname' => 'addons/address',
'moduleurl' => '',
'language' => $lang
];
$config = array_merge($config, Config::get("view_replace_str"));
// 配置信息后
Hook::listen("config_init", $config);
// 加载当前控制器语言包
$this->view->assign('site', $site);
$this->view->assign('config', $config);
return $this->view->fetch();
}
/**
* 选择地址
* @return string
* @throws \think\Exception
*/
public function select()
{
$config = get_addon_config('address');
$lat = $this->request->get('lat', $config['lat']);
$lng = $this->request->get('lng', $config['lng']);
$this->view->assign('lat', $lat);
$this->view->assign('lng', $lng);
$this->view->assign('location', $config['location']);
return $this->view->fetch('index/' . $config['maptype']);
}
}
... ...
name = address
title = 地址选择
intro = 地图位置选择插件,可返回地址和经纬度
author = Karson
website = http://www.fastadmin.net
version = 1.0.4
state = 1
url = /addons/address.html
... ...
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<title>地址选择器</title>
<link rel="stylesheet" href="__CDN__/assets/css/bootstrap.min.css"/>
<link rel="stylesheet" href="__CDN__/assets/css/fastadmin.min.css"/>
<link rel="stylesheet" href="__CDN__/assets/libs/font-awesome/css/font-awesome.min.css"/>
<style type="text/css">
body {
margin: 0;
padding: 0;
}
#container {
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
}
.confirm {
position: absolute;
bottom: 30px;
right: 4%;
z-index: 99;
height: 50px;
width: 50px;
line-height: 50px;
font-size: 15px;
text-align: center;
background-color: white;
background: #1ABC9C;
color: white;
border: none;
cursor: pointer;
border-radius: 50%;
}
.search {
position: absolute;
width: 400px;
top: 0;
left: 50%;
padding: 5px;
margin-left: -200px;
}
.amap-marker-label {
border: 0;
background-color: transparent;
}
.info {
padding: .75rem 1.25rem;
margin-bottom: 1rem;
border-radius: .25rem;
position: fixed;
top: 2rem;
background-color: white;
width: auto;
min-width: 22rem;
border-width: 0;
left: 1.8rem;
box-shadow: 0 2px 6px 0 rgba(114, 124, 245, .5);
}
</style>
</head>
<body>
<div class="search">
<div class="input-group">
<input type="text" id="place" name="q" class="form-control" placeholder="输入地点"/>
<span class="input-group-btn">
<button type="submit" name="search" id="search-btn" class="btn btn-success">
<i class="fa fa-search"></i>
</button>
</span>
</div>
</div>
<div class="confirm">确定</div>
<div id="container"></div>
<script type="text/javascript" src="//webapi.amap.com/maps?v=1.4.11&key={$config.amapkey|default=''}&plugin=AMap.ToolBar,AMap.Autocomplete,AMap.PlaceSearch,AMap.Geocoder"></script>
<!-- UI组件库 1.0 -->
<script src="//webapi.amap.com/ui/1.0/main.js?v=1.0.11"></script>
<script src="__CDN__/assets/libs/jquery/dist/jquery.min.js"></script>
<script type="text/javascript">
$(function () {
var as, address, map, lat, lng, geocoder;
var init = function () {
AMapUI.loadUI(['misc/PositionPicker', 'misc/PoiPicker'], function (PositionPicker, PoiPicker) {
//加载PositionPicker,loadUI的路径参数为模块名中 'ui/' 之后的部分
map = new AMap.Map('container', {
zoom: parseInt('{$config.zoom}')
});
geocoder = new AMap.Geocoder({
radius: 1000 //范围,默认:500
});
var positionPicker = new PositionPicker({
mode: 'dragMarker',//设定为拖拽地图模式,可选'dragMap'、'dragMarker',默认为'dragMap'
map: map//依赖地图对象
});
//输入提示
var autoOptions = {
input: "place"
};
var relocation = function (lnglat) {
lng = lnglat.lng;
lat = lnglat.lat;
map.panTo([lng, lat]);
positionPicker.start(lnglat);
geocoder.getAddress(lng + ',' + lat, function (status, result) {
if (status === 'complete' && result.regeocode) {
var address = result.regeocode.formattedAddress;
var label = '<div class="info">地址:' + address + '<br>经度:' + lng + '<br>纬度:' + lat + '</div>';
positionPicker.marker.setLabel({
content: label //显示内容
});
} else {
console.log(JSON.stringify(result));
}
});
};
var auto = new AMap.Autocomplete(autoOptions);
//构造地点查询类
var placeSearch = new AMap.PlaceSearch({
map: map
});
//注册监听,当选中某条记录时会触发
AMap.event.addListener(auto, "select", function (e) {
placeSearch.setCity(e.poi.adcode);
placeSearch.search(e.poi.name); //关键字查询查询
});
AMap.event.addListener(map, 'click', function (e) {
relocation(e.lnglat);
});
//加载工具条
var tool = new AMap.ToolBar();
map.addControl(tool);
var poiPicker = new PoiPicker({
input: 'place',
placeSearchOptions: {
map: map,
pageSize: 6 //关联搜索分页
}
});
poiPicker.on('poiPicked', function (poiResult) {
poiPicker.hideSearchResults();
$('.poi .nearpoi').text(poiResult.item.name);
$('.address .info').text(poiResult.item.address);
$('#address').val(poiResult.item.address);
$("#place").val(poiResult.item.name);
relocation(poiResult.item.location);
});
positionPicker.on('success', function (positionResult) {
as = positionResult.position;
address = positionResult.address;
lat = as.lat;
lng = as.lng;
});
positionPicker.on('fail', function (positionResult) {
address = '';
});
positionPicker.start();
});
};
//点击确定后执行回调赋值
var close = function (data) {
var index = parent.Layer.getFrameIndex(window.name);
var callback = parent.$("#layui-layer" + index).data("callback");
//再执行关闭
parent.Layer.close(index);
//再调用回传函数
if (typeof callback === 'function') {
callback.call(undefined, data);
}
};
//点击搜索按钮
$(document).on('click', '.confirm', function () {
var zoom = map.getZoom();
var data = {lat: lat, lng: lng, zoom: zoom, address: address};
close(data);
});
init();
});
</script>
</body>
</html>
\ No newline at end of file
... ...
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<title>地址选择器</title>
<link rel="stylesheet" href="__CDN__/assets/css/bootstrap.min.css"/>
<link rel="stylesheet" href="__CDN__/assets/css/fastadmin.min.css"/>
<link rel="stylesheet" href="__CDN__/assets/libs/font-awesome/css/font-awesome.min.css"/>
<style type="text/css">
body {
margin: 0;
padding: 0;
}
#container {
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
}
.confirm {
position: absolute;
bottom: 30px;
right: 4%;
z-index: 99;
height: 50px;
width: 50px;
line-height: 50px;
font-size: 15px;
text-align: center;
background-color: white;
background: #1ABC9C;
color: white;
border: none;
cursor: pointer;
border-radius: 50%;
}
.search {
position: absolute;
width: 400px;
top: 0;
left: 50%;
padding: 5px;
margin-left: -200px;
}
label.BMapLabel {
max-width: inherit;
padding: .75rem 1.25rem;
margin-bottom: 1rem;
background-color: white;
width: auto;
min-width: 22rem;
border: none;
box-shadow: 0 2px 6px 0 rgba(114, 124, 245, .5);
}
</style>
</head>
<body>
<div class="search">
<div class="input-group">
<input type="text" id="place" name="q" class="form-control" placeholder="输入地点"/>
<div id="searchResultPanel" style="border:1px solid #C0C0C0;width:150px;height:auto; display:none;"></div>
<span class="input-group-btn">
<button type="button" name="search" id="address" class="btn btn-success">
<i class="fa fa-search"></i>
</button>
</span>
</div>
</div>
<div class="confirm">确定</div>
<div id="container"></div>
<script type="text/javascript" src="//api.map.baidu.com/api?v=2.0&ak={$config.baidukey|default=''}"></script>
<script src="__CDN__/assets/libs/jquery/dist/jquery.min.js"></script>
<script type="text/javascript">
$(function () {
// 百度地图API功能
function G(id) {
return document.getElementById(id);
}
var map, marker, searchService, address = null, lng, lat;
var init = function () {
map = new BMap.Map("container"); // 创建地图实例
var point = new BMap.Point({$lng}, {$lat}); // 创建点坐标
map.enableScrollWheelZoom(true); //开启鼠标滚轮缩放
map.centerAndZoom(point, parseInt("{$config.zoom}")); // 初始化地图,设置中心点坐标和地图级别
var size = new BMap.Size(10, 20);
map.addControl(new BMap.CityListControl({
anchor: BMAP_ANCHOR_TOP_LEFT,
offset: size,
}));
var geoc = new BMap.Geocoder();
var addpoint = function (point) {
//通过点击百度地图,可以获取到对应的point, 由point的lng、lat属性就可以获取对应的经度纬度
var pt = point;
geoc.getLocation(pt, function (rs) {
//对象可以获取到详细的地址信息
address = rs.address;
deletePoint();
var mk = new BMap.Marker(pt);
map.addOverlay(mk);
map.panTo(pt);
var label = new BMap.Label('<div class="info">地址:' + address + '<br>经度:' + pt.lng + '<br>纬度:' + pt.lat + '</div>', {offset: new BMap.Size(16, 20)});
label.setStyle({
border: 'none',
padding: '.75rem 1.25rem'
});
mk.setLabel(label);
//将对应的HTML元素设置值
lng = pt.lng;
lat = pt.lat;
});
};
if ("{$lng}" != '' && "{$lat}" != '') {
addpoint(point);
}
ac = new BMap.Autocomplete({"input": "place", "location": map}); //建立一个自动完成的对象
ac.addEventListener("onhighlight", function (e) { //鼠标放在下拉列表上的事件
var str = "";
var _value = e.fromitem.value;
var value = "";
if (e.fromitem.index > -1) {
value = _value.province + _value.city + _value.district + _value.street + _value.business;
}
str = "FromItem<br />index = " + e.fromitem.index + "<br />value = " + value;
value = "";
if (e.toitem.index > -1) {
_value = e.toitem.value;
value = _value.province + _value.city + _value.district + _value.street + _value.business;
}
str += "<br />ToItem<br />index = " + e.toitem.index + "<br />value = " + value;
G("searchResultPanel").innerHTML = str;
});
ac.addEventListener("onconfirm", function (e) { //鼠标点击下拉列表后的事件
var _value = e.item.value;
myValue = _value.province + _value.city + _value.district + _value.street + _value.business;
G("searchResultPanel").innerHTML = "onconfirm<br />index = " + e.item.index + "<br />myValue = " + myValue;
setPlace();
});
function setPlace() {
map.clearOverlays(); //清除地图上所有覆盖物
function myFun() {
var result = local.getResults().getPoi(0);
var pp = result.point; //获取第一个智能搜索的结果
map.centerAndZoom(pp, 18);
map.addOverlay(new BMap.Marker(pp)); //添加标注
lng = pp.lng;
lat = pp.lat;
address = result.address;
}
var local = new BMap.LocalSearch(map, { //智能搜索
onSearchComplete: myFun
});
local.search(myValue);
}
map.addEventListener("click", function (e) {
//通过点击百度地图,可以获取到对应的point, 由point的lng、lat属性就可以获取对应的经度纬度
var pt = e.point;
addpoint(e.point);
});
/**
* 清除覆盖物
*/
function deletePoint() {
var allOverlay = map.getOverlays();
for (var i = 0; i < allOverlay.length; i++) {
map.removeOverlay(allOverlay[i]);
}
}
};
var close = function (data) {
var index = parent.Layer.getFrameIndex(window.name);
var callback = parent.$("#layui-layer" + index).data("callback");
//再执行关闭
parent.Layer.close(index);
//再调用回传函数
if (typeof callback === 'function') {
callback.call(undefined, data);
}
};
//点击确定后执行回调赋值
$(document).on('click', '.confirm', function () {
var zoom = map.getZoom();
var data = {lat: lat, lng: lng, zoom: zoom, address: address};
close(data);
});
init();
});
</script>
</body>
</html>
\ No newline at end of file
... ...
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/>
<title>地图位置(经纬度)选择插件 - FastAdmin</title>
<!-- Bootstrap Core CSS -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" rel="stylesheet">
<!-- Custom CSS -->
<link href="https://cdn.demo.fastadmin.net/assets/css/frontend.css" rel="stylesheet">
<!-- Plugin CSS -->
<link href="https://cdn.jsdelivr.net/npm/font-awesome@4.7.0/css/font-awesome.min.css" rel="stylesheet">
<!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!--[if lt IE 9]>
<script src="https://cdn.jsdelivr.net/npm/html5shiv@3.7.3/dist/html5shiv.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/respond.js@1.4.2/dest/respond.min.js"></script>
<![endif]-->
</head>
<body>
<div class="container">
<div class="bs-docs-section clearfix">
<div class="row">
<div class="col-lg-12">
<div class="page-header">
<h2 id="navbar">地图位置(经纬度)选择示例</h2>
</div>
<div class="bs-component">
<form action="" method="post" role="form">
<div class="form-group">
<label for=""></label>
<input type="text" class="form-control" name="" id="address" placeholder="地址">
</div>
<div class="form-group">
<label for=""></label>
<input type="text" class="form-control" name="" id="lng" placeholder="经度">
</div>
<div class="form-group">
<label for=""></label>
<input type="text" class="form-control" name="" id="lat" placeholder="纬度">
</div>
<button type="button" class="btn btn-primary" data-toggle='addresspicker' data-input-id="address" data-lng-id="lng" data-lat-id="lat">点击选择地址获取经纬度</button>
</form>
</div>
<div class="page-header">
<h2 id="code">调用代码</h2>
</div>
<div class="bs-component">
<textarea class="form-control" rows="17">
<form action="" method="post" role="form">
<div class="form-group">
<label for=""></label>
<input type="text" class="form-control" name="" id="address" placeholder="地址">
</div>
<div class="form-group">
<label for=""></label>
<input type="text" class="form-control" name="" id="lng" placeholder="经度">
</div>
<div class="form-group">
<label for=""></label>
<input type="text" class="form-control" name="" id="lat" placeholder="纬度">
</div>
<button type="button" class="btn btn-primary" data-toggle='addresspicker' data-input-id="address" data-lng-id="lng" data-lat-id="lat">点击选择地址获取经纬度</button>
</form>
</textarea>
</div>
<div class="page-header">
<h2 id="navbar">参数说明</h2>
</div>
<div class="bs-component">
<table class="table table-condensed table-hover">
<thead>
<tr>
<th>参数</th>
<th>释义</th>
</tr>
</thead>
<tbody>
<tr>
<td>data-input-id</td>
<td>填充地址的文本框ID</td>
</tr>
<tr>
<td>data-lng-id</td>
<td>填充经度的文本框ID</td>
</tr>
<tr>
<td>data-lat-id</td>
<td>填充纬度的文本框ID</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
<script type="text/javascript">
var require = {
config: {$config | json_encode
}
}
;
</script>
<script>
require.callback = function () {
define('addons/address', ['jquery', 'bootstrap', 'frontend', 'template'], function ($, undefined, Frontend, Template) {
var Controller = {
index: function () {
;
}
};
return Controller;
});
define('lang', function () {
return [];
});
}
</script>
<script src="__CDN__/assets/js/require.min.js" data-main="__CDN__/assets/js/require-frontend.min.js?v={$site.version}"></script>
</body>
</html>
\ No newline at end of file
... ...
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<title>地址选择器</title>
<link rel="stylesheet" href="__CDN__/assets/css/bootstrap.min.css"/>
<link rel="stylesheet" href="__CDN__/assets/css/fastadmin.min.css"/>
<link rel="stylesheet" href="__CDN__/assets/libs/font-awesome/css/font-awesome.min.css"/>
<style type="text/css">
body {
margin: 0;
padding: 0;
}
#container {
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
}
.confirm {
position: absolute;
bottom: 30px;
right: 4%;
z-index: 99;
height: 50px;
width: 50px;
line-height: 50px;
font-size: 15px;
text-align: center;
background-color: white;
background: #1ABC9C;
color: white;
border: none;
cursor: pointer;
border-radius: 50%;
}
.search {
position: absolute;
width: 400px;
top: 0;
left: 50%;
padding: 5px;
margin-left: -200px;
}
</style>
</head>
<body>
<div class="search">
<div class="input-group">
<input type="text" id="place" name="q" class="form-control" placeholder="输入地点"/>
<span class="input-group-btn">
<button type="submit" name="search" id="search-btn" class="btn btn-success">
<i class="fa fa-search"></i>
</button>
</span>
</div>
</div>
<div class="confirm">确定</div>
<div id="container"></div>
<script charset="utf-8" src="//map.qq.com/api/js?v=2.exp&libraries=place&key={$config.tencentkey|default=''}"></script>
<script src="__CDN__/assets/libs/jquery/dist/jquery.min.js"></script>
<script type="text/javascript">
$(function () {
var map, marker, geocoder, infoWin, searchService, address = null;
var init = function () {
var center = new qq.maps.LatLng({$lat}, {$lng});
map = new qq.maps.Map(document.getElementById('container'), {
center: center,
zoom: parseInt("{$config.zoom}")
});
//初始化marker
initmarker(center);
//实例化信息窗口
infoWin = new qq.maps.InfoWindow({
map: map
});
geocoder = new qq.maps.Geocoder({
complete: function (result) {
infoWin.open();
address = result.detail.addressComponents.province +
result.detail.addressComponents.city +
result.detail.addressComponents.district;
if (result.detail.addressComponents.streetNumber == '') {
address += result.detail.addressComponents.street;
} else {
address += result.detail.addressComponents.streetNumber;
}
infoWin.setContent(address);
infoWin.setPosition(result.detail.location);
}
});
//显示当前marker的位置信息窗口
geocoder.getAddress(center);
var latlngBounds = new qq.maps.LatLngBounds();
//查询poi类信息
searchService = new qq.maps.SearchService({
complete: function (results) {
var pois = results.detail.pois;
for (var i = 0, l = pois.length; i < l; i++) {
var poi = pois[i];
latlngBounds.extend(poi.latLng);
initmarker(poi.latLng);
//显示当前marker的位置信息窗口
geocoder.getAddress(poi.latLng);
}
map.fitBounds(latlngBounds);
}
});
//实例化自动完成
var ap = new qq.maps.place.Autocomplete(document.getElementById('place'));
//添加监听事件
qq.maps.event.addListener(ap, "confirm", function (res) {
searchKeyword();
});
qq.maps.event.addListener(
map,
'click',
function (event) {
try {
infoWin.setContent('<div style="text-align:center;white-space:nowrap;margin:10px;">加载中</div>');
var latLng = event.latLng,
lat = latLng.getLat().toFixed(5),
lng = latLng.getLng().toFixed(5);
var location = new qq.maps.LatLng(lat, lng);
//调用获取位置方法
geocoder.getAddress(location);
infoWin.setPosition(location);
marker.setPosition(location);
} catch (e) {
console.log(e);
}
}
);
};
//实例化marker和监听拖拽结束事件
var initmarker = function (latLng) {
marker = new qq.maps.Marker({
map: map,
position: latLng,
draggable: true,
title: '拖动图标选择位置'
});
//监听拖拽结束
qq.maps.event.addListener(marker, 'dragend', function (event) {
var latLng = event.latLng,
lat = latLng.getLat().toFixed(5),
lng = latLng.getLng().toFixed(5);
var location = new qq.maps.LatLng(lat, lng);
//调用获取位置方法
geocoder.getAddress(location);
});
};
var close = function (data) {
var index = parent.Layer.getFrameIndex(window.name);
var callback = parent.$("#layui-layer" + index).data("callback");
//再执行关闭
parent.Layer.close(index);
//再调用回传函数
if (typeof callback === 'function') {
callback.call(undefined, data);
}
};
//执行搜索方法
var searchKeyword = function () {
searchService.clear();//先清除
marker.setMap(null);
infoWin.close();
var keyword = $("#place").val();
searchService.setLocation("{$location}");//设置默认检索范围(默认为全国),类型可以是坐标或指定的城市名称。
searchService.setPageIndex(0);//设置检索的特定页数。
searchService.setPageCapacity(1);//设置每页返回的结果数量。
searchService.search(keyword);//开始查询
};
//点击确定后执行回调赋值
$(document).on('click', '.confirm', function () {
var as = marker.getPosition();
var x = as.getLat().toFixed(5);
var y = as.getLng().toFixed(5);
var zoom = map.getZoom();
var data = {lat: x, lng: y, zoom: zoom, address: address};
close(data);
});
//点击搜索按钮
$(document).on('click', '#search-btn', function () {
if ($("#place").val() == '')
return;
searchKeyword();
});
init();
});
</script>
</body>
</html>
\ No newline at end of file
... ...
<?php
namespace addons\command;
use app\common\library\Menu;
use think\Addons;
/**
* 在线命令插件
*/
class Command extends Addons
{
/**
* 插件安装方法
* @return bool
*/
public function install()
{
$menu = [
[
'name' => 'command',
'title' => '在线命令管理',
'icon' => 'fa fa-terminal',
'sublist' => [
['name' => 'command/index', 'title' => '查看'],
['name' => 'command/add', 'title' => '添加'],
['name' => 'command/detail', 'title' => '详情'],
['name' => 'command/execute', 'title' => '运行'],
['name' => 'command/del', 'title' => '删除'],
['name' => 'command/multi', 'title' => '批量更新'],
]
]
];
Menu::create($menu);
return true;
}
/**
* 插件卸载方法
* @return bool
*/
public function uninstall()
{
Menu::delete('command');
return true;
}
/**
* 插件启用方法
* @return bool
*/
public function enable()
{
Menu::enable('command');
return true;
}
/**
* 插件禁用方法
* @return bool
*/
public function disable()
{
Menu::disable('command');
return true;
}
}
... ...
<?php
namespace app\admin\controller;
use app\common\controller\Backend;
use think\Config;
use think\console\Input;
use think\Db;
use think\Exception;
/**
* 在线命令管理
*
* @icon fa fa-circle-o
*/
class Command extends Backend
{
/**
* Command模型对象
*/
protected $model = null;
protected $noNeedRight = ['get_controller_list', 'get_field_list'];
public function _initialize()
{
parent::_initialize();
$this->model = model('Command');
$this->view->assign("statusList", $this->model->getStatusList());
}
/**
* 添加
*/
public function add()
{
$tableList = [];
$list = \think\Db::query("SHOW TABLES");
foreach ($list as $key => $row) {
$tableList[reset($row)] = reset($row);
}
$this->view->assign("tableList", $tableList);
return $this->view->fetch();
}
/**
* 获取字段列表
* @internal
*/
public function get_field_list()
{
$dbname = Config::get('database.database');
$prefix = Config::get('database.prefix');
$table = $this->request->request('table');
//从数据库中获取表字段信息
$sql = "SELECT * FROM `information_schema`.`columns` "
. "WHERE TABLE_SCHEMA = ? AND table_name = ? "
. "ORDER BY ORDINAL_POSITION";
//加载主表的列
$columnList = Db::query($sql, [$dbname, $table]);
$fieldlist = [];
foreach ($columnList as $index => $item) {
$fieldlist[] = $item['COLUMN_NAME'];
}
$this->success("", null, ['fieldlist' => $fieldlist]);
}
/**
* 获取控制器列表
* @internal
*/
public function get_controller_list()
{
//搜索关键词,客户端输入以空格分开,这里接收为数组
$word = (array)$this->request->request("q_word/a");
$word = implode('', $word);
$adminPath = dirname(__DIR__) . DS;
$controllerDir = $adminPath . 'controller' . DS;
$files = new \RecursiveIteratorIterator(
new \RecursiveDirectoryIterator($controllerDir), \RecursiveIteratorIterator::LEAVES_ONLY
);
$list = [];
foreach ($files as $name => $file) {
if (!$file->isDir()) {
$filePath = $file->getRealPath();
$name = str_replace($controllerDir, '', $filePath);
$name = str_replace(DS, "/", $name);
if (!preg_match("/(.*)\.php\$/", $name)) {
continue;
}
if (!$word || stripos($name, $word) !== false) {
$list[] = ['id' => $name, 'name' => $name];
}
}
}
$pageNumber = $this->request->request("pageNumber");
$pageSize = $this->request->request("pageSize");
return json(['list' => array_slice($list, ($pageNumber - 1) * $pageSize, $pageSize), 'total' => count($list)]);
}
/**
* 详情
*/
public function detail($ids)
{
$row = $this->model->get($ids);
if (!$row) {
$this->error(__('No Results were found'));
}
$this->view->assign("row", $row);
return $this->view->fetch();
}
/**
* 执行
*/
public function execute($ids)
{
$row = $this->model->get($ids);
if (!$row) {
$this->error(__('No Results were found'));
}
$result = $this->doexecute($row['type'], json_decode($row['params'], true));
$this->success("", null, ['result' => $result]);
}
/**
* 执行命令
*/
public function command($action = '')
{
$commandtype = $this->request->request("commandtype");
$params = $this->request->request();
$allowfields = [
'crud' => 'table,controller,model,fields,force,local,delete,menu',
'menu' => 'controller,delete',
'min' => 'module,resource,optimize',
'api' => 'url,module,output,template,force,title,author,class,language',
];
$argv = [];
$allowfields = isset($allowfields[$commandtype]) ? explode(',', $allowfields[$commandtype]) : [];
$allowfields = array_filter(array_intersect_key($params, array_flip($allowfields)));
if (isset($params['local']) && !$params['local']) {
$allowfields['local'] = $params['local'];
} else {
unset($allowfields['local']);
}
foreach ($allowfields as $key => $param) {
$argv[] = "--{$key}=" . (is_array($param) ? implode(',', $param) : $param);
}
if ($commandtype == 'crud') {
$extend = 'setcheckboxsuffix,enumradiosuffix,imagefield,filefield,intdatesuffix,switchsuffix,citysuffix,selectpagesuffix,selectpagessuffix,ignorefields,sortfield,editorsuffix,headingfilterfield';
$extendArr = explode(',', $extend);
foreach ($params as $index => $item) {
if (in_array($index, $extendArr)) {
foreach (explode(',', $item) as $key => $value) {
if ($value) {
$argv[] = "--{$index}={$value}";
}
}
}
}
$isrelation = (int)$this->request->request('isrelation');
if ($isrelation && isset($params['relation'])) {
foreach ($params['relation'] as $index => $relation) {
foreach ($relation as $key => $value) {
$argv[] = "--{$key}=" . (is_array($value) ? implode(',', $value) : $value);
}
}
}
} else {
if ($commandtype == 'menu') {
if (isset($params['allcontroller']) && $params['allcontroller']) {
$argv[] = "--controller=all-controller";
} else {
foreach (explode(',', $params['controllerfile']) as $index => $param) {
if ($param) {
$argv[] = "--controller=" . substr($param, 0, -4);
}
}
}
} else {
if ($commandtype == 'min') {
} else {
if ($commandtype == 'api') {
} else {
}
}
}
}
if ($action == 'execute') {
$result = $this->doexecute($commandtype, $argv);
$this->success("", null, ['result' => $result]);
} else {
$this->success("", null, ['command' => "php think {$commandtype} " . implode(' ', $argv)]);
}
return;
}
protected function doexecute($commandtype, $argv)
{
$commandName = "\\app\\admin\\command\\" . ucfirst($commandtype);
$input = new Input($argv);
$output = new \addons\command\library\Output();
$command = new $commandName($commandtype);
$data = [
'type' => $commandtype,
'params' => json_encode($argv),
'command' => "php think {$commandtype} " . implode(' ', $argv),
'executetime' => time(),
];
$this->model->save($data);
try {
$command->run($input, $output);
$result = implode("\n", $output->getMessage());
$this->model->status = 'successed';
} catch (Exception $e) {
$result = implode("\n", $output->getMessage()) . "\n";
$result .= $e->getMessage();
$this->model->status = 'failured';
}
$result = trim($result);
$this->model->content = $result;
$this->model->save();
return $result;
}
}
... ...
<?php
return [
'Id' => 'ID',
'Type' => '类型',
'Params' => '参数',
'Command' => '命令',
'Content' => '返回结果',
'Executetime' => '执行时间',
'Createtime' => '创建时间',
'Updatetime' => '更新时间',
'Execute again' => '再次执行',
'Successed' => '成功',
'Failured' => '失败',
'Status' => '状态'
];
... ...
<?php
namespace app\admin\model;
use think\Model;
class Command extends Model
{
// 表名
protected $name = 'command';
// 自动写入时间戳字段
protected $autoWriteTimestamp = 'int';
// 定义时间戳字段名
protected $createTime = 'createtime';
protected $updateTime = 'updatetime';
// 追加属性
protected $append = [
'executetime_text',
'type_text',
'status_text'
];
public function getStatusList()
{
return ['successed' => __('Successed'), 'failured' => __('Failured')];
}
public function getExecutetimeTextAttr($value, $data)
{
$value = $value ? $value : $data['executetime'];
return is_numeric($value) ? date("Y-m-d H:i:s", $value) : $value;
}
public function getTypeTextAttr($value, $data)
{
$value = $value ? $value : $data['type'];
$list = ['crud' => '一键生成CRUD', 'menu' => '一键生成菜单', 'min' => '一键压缩打包', 'api' => '一键生成文档'];
return isset($list[$value]) ? $list[$value] : '';
}
public function getStatusTextAttr($value, $data)
{
$value = $value ? $value : $data['status'];
$list = $this->getStatusList();
return isset($list[$value]) ? $list[$value] : '';
}
protected function setExecutetimeAttr($value)
{
return $value && !is_numeric($value) ? strtotime($value) : $value;
}
}
... ...
<?php
namespace app\admin\validate;
use think\Validate;
class Command extends Validate
{
/**
* 验证规则
*/
protected $rule = [
];
/**
* 提示消息
*/
protected $message = [
];
/**
* 验证场景
*/
protected $scene = [
'add' => [],
'edit' => [],
];
}
... ...
<style>
.relation-item {margin-top:10px;}
legend {padding-bottom:5px;font-size:14px;font-weight:600;}
label {font-weight:normal;}
.form-control{padding:6px 8px;}
#extend-zone .col-xs-2 {margin-top:10px;padding-right:0;}
#extend-zone .col-xs-2:nth-child(6n+0) {padding-right:15px;}
</style>
<div class="panel panel-default panel-intro">
<div class="panel-heading">
<ul class="nav nav-tabs">
<li class="active"><a href="#crud" data-toggle="tab">{:__('一键生成CRUD')}</a></li>
<li><a href="#menu" data-toggle="tab">{:__('一键生成菜单')}</a></li>
<li><a href="#min" data-toggle="tab">{:__('一键压缩打包')}</a></li>
<li><a href="#api" data-toggle="tab">{:__('一键生成API文档')}</a></li>
</ul>
</div>
<div class="panel-body">
<div id="myTabContent" class="tab-content">
<div class="tab-pane fade active in" id="crud">
<div class="row">
<div class="col-xs-12">
<form role="form">
<input type="hidden" name="commandtype" value="crud" />
<div class="form-group">
<div class="row">
<div class="col-xs-3">
<input checked="" name="isrelation" type="hidden" value="0">
<label class="control-label" data-toggle="tooltip" title="当前只支持生成1对1关联模型,选中后请配置关联表和字段">
<input name="isrelation" type="checkbox" value="1">
关联模型
</label>
</div>
<div class="col-xs-3">
<input checked="" name="local" type="hidden" value="1">
<label class="control-label" data-toggle="tooltip" title="默认模型生成在application/admin/model目录下,选中后将生成在application/common/model目录下">
<input name="local" type="checkbox" value="0"> 全局模型类
</label>
</div>
<div class="col-xs-3">
<input checked="" name="delete" type="hidden" value="0">
<label class="control-label" data-toggle="tooltip" title="删除CRUD生成的相关文件">
<input name="delete" type="checkbox" value="1"> 删除模式
</label>
</div>
<div class="col-xs-3">
<input checked="" name="force" type="hidden" value="0">
<label class="control-label" data-toggle="tooltip" title="选中后,如果已经存在同名文件将被覆盖。如果是删除将不再提醒">
<input name="force" type="checkbox" value="1">
强制覆盖模式
</label>
</div>
<!--
<div class="col-xs-3">
<input checked="" name="menu" type="hidden" value="0">
<label class="control-label" data-toggle="tooltip" title="选中后,将同时生成后台菜单规则">
<input name="menu" type="checkbox" value="1">
生成菜单
</label>
</div>
-->
</div>
</div>
<div class="form-group">
<legend>主表设置</legend>
<div class="row">
<div class="col-xs-3">
<label>请选择主表</label>
{:build_select('table',$tableList,null,['class'=>'form-control selectpicker', 'data-live-search'=>'true']);}
</div>
<div class="col-xs-3">
<label>自定义控制器名</label>
<input type="text" class="form-control" name="controller" data-toggle="tooltip" title="默认根据表名自动生成,如果需要放在二级目录请手动填写" placeholder="支持目录层级,以/分隔">
</div>
<div class="col-xs-3">
<label>自定义模型名</label>
<input type="text" class="form-control" name="model" data-toggle="tooltip" title="默认根据表名自动生成" placeholder="不支持目录层级">
</div>
<div class="col-xs-3">
<label>请选择显示字段(默认全部)</label>
<select name="fields[]" id="fields" multiple style="height:30px;" class="form-control selectpicker"></select>
</div>
</div>
</div>
<div class="form-group hide" id="relation-zone">
<legend>关联表设置</legend>
<div class="row" style="margin-top:15px;">
<div class="col-xs-12">
<a href="javascript:;" class="btn btn-primary btn-sm btn-newrelation" data-index="1">追加关联模型</a>
</div>
</div>
</div>
<hr>
<div class="form-group" id="extend-zone">
<legend>字段识别设置 <span style="font-size:12px;font-weight: normal;">(与之匹配的字段都将生成相应组件)</span></legend>
<div class="row">
<div class="col-xs-2">
<label>复选框后缀</label>
<input type="text" class="form-control" name="setcheckboxsuffix" placeholder="默认为set类型" />
</div>
<div class="col-xs-2">
<label>单选框后缀</label>
<input type="text" class="form-control" name="enumradiosuffix" placeholder="默认为enum类型" />
</div>
<div class="col-xs-2">
<label>图片类型后缀</label>
<input type="text" class="form-control" name="imagefield" placeholder="默认为image,images,avatar,avatars" />
</div>
<div class="col-xs-2">
<label>文件类型后缀</label>
<input type="text" class="form-control" name="filefield" placeholder="默认为file,files" />
</div>
<div class="col-xs-2">
<label>日期时间后缀</label>
<input type="text" class="form-control" name="intdatesuffix" placeholder="默认为time" />
</div>
<div class="col-xs-2">
<label>开关后缀</label>
<input type="text" class="form-control" name="switchsuffix" placeholder="默认为switch" />
</div>
<div class="col-xs-2">
<label>城市选择后缀</label>
<input type="text" class="form-control" name="citysuffix" placeholder="默认为city" />
</div>
<div class="col-xs-2">
<label>动态下拉后缀(单)</label>
<input type="text" class="form-control" name="selectpagesuffix" placeholder="默认为_id" />
</div>
<div class="col-xs-2">
<label>动态下拉后缀(多)</label>
<input type="text" class="form-control" name="selectpagessuffix" placeholder="默认为_ids" />
</div>
<div class="col-xs-2">
<label>忽略的字段</label>
<input type="text" class="form-control" name="ignorefields" placeholder="默认无" />
</div>
<div class="col-xs-2">
<label>排序字段</label>
<input type="text" class="form-control" name="sortfield" placeholder="默认为weigh" />
</div>
<div class="col-xs-2">
<label>富文本编辑器</label>
<input type="text" class="form-control" name="editorsuffix" placeholder="默认为content" />
</div>
<div class="col-xs-2">
<label>选项卡过滤字段</label>
<input type="text" class="form-control" name="headingfilterfield" placeholder="默认为status" />
</div>
</div>
</div>
<div class="form-group">
<legend>生成命令行</legend>
<textarea class="form-control" data-toggle="tooltip" title="如果在线执行命令失败,可以将命令复制到命令行进行执行" rel="command" rows="1" placeholder="请点击生成命令行"></textarea>
</div>
<div class="form-group">
<legend>返回结果</legend>
<textarea class="form-control" rel="result" rows="5" placeholder="请点击立即执行"></textarea>
</div>
<div class="form-group">
<button type="button" class="btn btn-info btn-embossed btn-command">{:__('生成命令行')}</button>
<button type="button" class="btn btn-success btn-embossed btn-execute">{:__('立即执行')}</button>
</div>
</form>
</div>
</div>
</div>
<div class="tab-pane fade" id="menu">
<div class="row">
<div class="col-xs-12">
<form role="form">
<input type="hidden" name="commandtype" value="menu" />
<div class="form-group">
<div class="row">
<div class="col-xs-3">
<input checked="" name="allcontroller" type="hidden" value="0">
<label class="control-label">
<input name="allcontroller" data-toggle="collapse" data-target="#controller" type="checkbox" value="1"> 一键生成全部控制器
</label>
</div>
<div class="col-xs-3">
<input checked="" name="delete" type="hidden" value="0">
<label class="control-label">
<input name="delete" type="checkbox" value="1"> 删除模式
</label>
</div>
<div class="col-xs-3">
<input checked="" name="force" type="hidden" value="0">
<label class="control-label">
<input name="force" type="checkbox" value="1"> 强制覆盖模式
</label>
</div>
</div>
</div>
<div class="form-group in" id="controller">
<legend>控制器设置</legend>
<div class="row" style="margin-top:15px;">
<div class="col-xs-12">
<input type="text" name="controllerfile" class="form-control selectpage" style="width:720px;" data-source="command/get_controller_list" data-multiple="true" name="controller" placeholder="请选择控制器" />
</div>
</div>
</div>
<div class="form-group">
<legend>生成命令行</legend>
<textarea class="form-control" rel="command" rows="1" placeholder="请点击生成命令行"></textarea>
</div>
<div class="form-group">
<legend>返回结果</legend>
<textarea class="form-control" rel="result" rows="5" placeholder="请点击立即执行"></textarea>
</div>
<div class="form-group">
<button type="button" class="btn btn-info btn-embossed btn-command">{:__('生成命令行')}</button>
<button type="button" class="btn btn-success btn-embossed btn-execute">{:__('立即执行')}</button>
</div>
</form>
</div>
</div>
</div>
<div class="tab-pane fade" id="min">
<div class="row">
<div class="col-xs-12">
<form role="form">
<input type="hidden" name="commandtype" value="min" />
<div class="form-group">
<legend>基础设置</legend>
<div class="row">
<div class="col-xs-3">
<label>请选择压缩模块</label>
<select name="module" class="form-control selectpicker">
<option value="all" selected>全部</option>
<option value="backend">后台Backend</option>
<option value="frontend">前台Frontend</option>
</select>
</div>
<div class="col-xs-3">
<label>请选择压缩资源</label>
<select name="resource" class="form-control selectpicker">
<option value="all" selected>全部</option>
<option value="js">JS</option>
<option value="css">CSS</option>
</select>
</div>
<div class="col-xs-3">
<label>请选择压缩模式</label>
<select name="optimize" class="form-control selectpicker">
<option value=""></option>
<option value="uglify">uglify</option>
<option value="closure">closure</option>
</select>
</div>
</div>
</div>
<div class="form-group in">
<legend>控制器设置</legend>
<div class="row" style="margin-top:15px;">
<div class="col-xs-12">
</div>
</div>
</div>
<div class="form-group">
<legend>生成命令行</legend>
<textarea class="form-control" rel="command" rows="1" placeholder="请点击生成命令行"></textarea>
</div>
<div class="form-group">
<legend>返回结果</legend>
<textarea class="form-control" rel="result" rows="5" placeholder="请点击立即执行"></textarea>
</div>
<div class="form-group">
<button type="button" class="btn btn-info btn-embossed btn-command">{:__('生成命令行')}</button>
<button type="button" class="btn btn-success btn-embossed btn-execute">{:__('立即执行')}</button>
</div>
</form>
</div>
</div>
</div>
<div class="tab-pane fade" id="api">
<div class="row">
<div class="col-xs-12">
<form role="form">
<input type="hidden" name="commandtype" value="api" />
<div class="form-group">
<div class="row">
<div class="col-xs-3">
<input checked="" name="force" type="hidden" value="0">
<label class="control-label">
<input name="force" type="checkbox" value="1">
覆盖模式
</label>
</div>
</div>
</div>
<div class="form-group">
<legend>文档设置</legend>
<div class="row">
<div class="col-xs-3">
<label>请输入接口URL</label>
<input type="text" name="url" class="form-control" placeholder="API URL,可留空" />
</div>
<div class="col-xs-3">
<label>接口生成文件</label>
<input type="text" name="output" class="form-control" placeholder="留空则使用api.html" />
</div>
<div class="col-xs-3">
<label>模板文件</label>
<input type="text" name="template" class="form-control" placeholder="如果不清楚请留空" />
</div>
</div>
<div class="row" style="margin-top:10px;">
<div class="col-xs-3">
<label>文档标题</label>
<input type="text" name="title" class="form-control" placeholder="默认为FastAdmin" />
</div>
<div class="col-xs-3">
<label>文档作者</label>
<input type="text" name="author" class="form-control" placeholder="默认为FastAdmin" />
</div>
<div class="col-xs-3">
<label>文档语言</label>
<select name="language" class="form-control">
<option value="" selected>请选择语言</option>
<option value="zh-cn">中文</option>
<option value="en">英文</option>
</select>
</div>
</div>
</div>
<div class="form-group">
<legend>生成命令行</legend>
<textarea class="form-control" rel="command" rows="1" placeholder="请点击生成命令行"></textarea>
</div>
<div class="form-group">
<legend>返回结果</legend>
<textarea class="form-control" rel="result" rows="5" placeholder="请点击立即执行"></textarea>
</div>
<div class="form-group">
<button type="button" class="btn btn-info btn-embossed btn-command">{:__('生成命令行')}</button>
<button type="button" class="btn btn-success btn-embossed btn-execute">{:__('立即执行')}</button>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
<script id="relationtpl" type="text/html">
<div class="row relation-item">
<div class="col-xs-2">
<label>请选择关联表</label>
<select name="relation[<%=index%>][relation]" class="form-control relationtable" data-live-search="true"></select>
</div>
<div class="col-xs-2">
<label>请选择关联类型</label>
<select name="relation[<%=index%>][relationmode]" class="form-control relationmode"></select>
</div>
<div class="col-xs-2">
<label>关联外键</label>
<select name="relation[<%=index%>][relationforeignkey]" class="form-control relationforeignkey"></select>
</div>
<div class="col-xs-2">
<label>关联主键</label>
<select name="relation[<%=index%>][relationprimarykey]" class="form-control relationprimarykey"></select>
</div>
<div class="col-xs-2">
<label>请选择显示字段</label>
<select name="relation[<%=index%>][relationfields][]" multiple class="form-control relationfields"></select>
</div>
<div class="col-xs-2">
<label>&nbsp;</label>
<a href="javascript:;" class="btn btn-danger btn-block btn-removerelation">移除</a>
</div>
</div>
</script>
... ...
<table class="table table-striped">
<thead>
<tr>
<th>{:__('Title')}</th>
<th>{:__('Content')}</th>
</tr>
</thead>
<tbody>
<tr>
<td>{:__('Type')}</td>
<td>{$row.type}({$row.type_text})</td>
</tr>
<tr>
<td>{:__('Params')}</td>
<td>{$row.params}</td>
</tr>
<tr>
<td>{:__('Command')}</td>
<td>{$row.command}</td>
</tr>
<tr>
<td>{:__('Content')}</td>
<td>
<textarea class="form-control" name="" id="" cols="60" rows="10">{$row.content}</textarea>
</td>
</tr>
<tr>
<td>{:__('Executetime')}</td>
<td>{$row.executetime|datetime}</td>
</tr>
<tr>
<td>{:__('Status')}</td>
<td>{$row.status_text}</td>
</tr>
</tbody>
</table>
<div class="hide layer-footer">
<label class="control-label col-xs-12 col-sm-2"></label>
<div class="col-xs-12 col-sm-8">
<button type="reset" class="btn btn-primary btn-embossed btn-close" onclick="Layer.closeAll();">{:__('Close')}</button>
</div>
</div>
\ No newline at end of file
... ...
<div class="panel panel-default panel-intro">
{:build_heading()}
<div class="panel-body">
<div id="myTabContent" class="tab-content">
<div class="tab-pane fade active in" id="one">
<div class="widget-body no-padding">
<div id="toolbar" class="toolbar">
<a href="javascript:;" class="btn btn-primary btn-refresh" title="{:__('Refresh')}" ><i class="fa fa-refresh"></i> </a>
<a href="javascript:;" class="btn btn-success btn-add {:$auth->check('command/add')?'':'hide'}" title="{:__('Add')}" ><i class="fa fa-plus"></i> {:__('Add')}</a>
<a href="javascript:;" class="btn btn-danger btn-del btn-disabled disabled {:$auth->check('command/del')?'':'hide'}" title="{:__('Delete')}" ><i class="fa fa-trash"></i> {:__('Delete')}</a>
</div>
<table id="table" class="table table-striped table-bordered table-hover"
data-operate-detail="{:$auth->check('command/detail')}"
data-operate-execute="{:$auth->check('command/execute')}"
data-operate-del="{:$auth->check('command/del')}"
width="100%">
</table>
</div>
</div>
</div>
</div>
</div>
... ...
<?php
return [
];
... ...
<?php
namespace addons\command\controller;
use think\addons\Controller;
class Index extends Controller
{
public function index()
{
$this->error("当前插件暂无前台页面");
}
}
... ...
name = command
title = 在线命令
intro = 可在线执行FastAdmin的命令行相关命令
author = Karson
website = https://www.fastadmin.net
version = 1.0.6
state = 1
url = /addons/command
... ...
CREATE TABLE IF NOT EXISTS `__PREFIX__command` (
`id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'ID',
`type` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '类型',
`params` varchar(1500) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '参数',
`command` varchar(1500) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '命令',
`content` text COMMENT '返回结果',
`executetime` int(10) UNSIGNED DEFAULT NULL COMMENT '执行时间',
`createtime` int(10) UNSIGNED DEFAULT NULL COMMENT '创建时间',
`updatetime` int(10) UNSIGNED DEFAULT NULL COMMENT '更新时间',
`status` enum('successed','failured') CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT 'failured' COMMENT '状态',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '在线命令表';
... ...
<?php
namespace addons\command\library;
/**
* Class Output
*/
class Output extends \think\console\Output
{
protected $message = [];
public function __construct($driver = 'console')
{
parent::__construct($driver);
}
protected function block($style, $message)
{
$this->message[] = $message;
}
public function getMessage()
{
return $this->message;
}
}
... ...
define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'template'], function ($, undefined, Backend, Table, Form, Template) {
var Controller = {
index: function () {
// 初始化表格参数配置
Table.api.init({
extend: {
index_url: 'command/index',
add_url: 'command/add',
edit_url: '',
del_url: 'command/del',
multi_url: 'command/multi',
table: 'command',
}
});
var table = $("#table");
// 初始化表格
table.bootstrapTable({
url: $.fn.bootstrapTable.defaults.extend.index_url,
pk: 'id',
sortName: 'id',
columns: [
[
{checkbox: true},
{field: 'id', title: __('Id')},
{field: 'type', title: __('Type'), formatter: Table.api.formatter.search},
{field: 'type_text', title: __('Type')},
{
field: 'command', title: __('Command'), formatter: function (value, row, index) {
return '<input type="text" class="form-control" value="' + value + '">';
}
},
{
field: 'executetime',
title: __('Executetime'),
operate: 'RANGE',
addclass: 'datetimerange',
formatter: Table.api.formatter.datetime
},
{
field: 'createtime',
title: __('Createtime'),
operate: 'RANGE',
addclass: 'datetimerange',
formatter: Table.api.formatter.datetime
},
{
field: 'updatetime',
title: __('Updatetime'),
operate: 'RANGE',
addclass: 'datetimerange',
formatter: Table.api.formatter.datetime
},
{
field: 'status',
title: __('Status'),
table: table,
custom: {"successed": 'success', "failured": 'danger'},
searchList: {"successed": __('Successed'), "failured": __('Failured')},
formatter: Table.api.formatter.status
},
{
field: 'operate',
title: __('Operate'),
buttons: [
{
name: 'execute',
title: __('Execute again'),
text: __('Execute again'),
url: 'command/execute',
icon: 'fa fa-repeat',
classname: 'btn btn-success btn-xs btn-execute btn-ajax',
success: function (data) {
Layer.alert("<textarea class='form-control' cols='60' rows='5'>" + data.result + "</textarea>", {
title: __("执行结果"),
shadeClose: true
});
table.bootstrapTable('refresh');
return false;
}
},
{
name: 'execute',
title: __('Detail'),
text: __('Detail'),
url: 'command/detail',
icon: 'fa fa-list',
classname: 'btn btn-info btn-xs btn-execute btn-dialog'
}
],
table: table,
events: Table.api.events.operate,
formatter: Table.api.formatter.operate
}
]
]
});
// 为表格绑定事件
Table.api.bindevent(table);
},
add: function () {
require(['bootstrap-select', 'bootstrap-select-lang']);
var mainfields = [];
var relationfields = {};
var maintable = [];
var relationtable = [];
var relationmode = ["belongsto", "hasone"];
var renderselect = function (select, data) {
var html = [];
for (var i = 0; i < data.length; i++) {
html.push("<option value='" + data[i] + "'>" + data[i] + "</option>");
}
$(select).html(html.join(""));
select.trigger("change");
if (select.data("selectpicker")) {
select.selectpicker('refresh');
}
return select;
};
$("select[name=table] option").each(function () {
maintable.push($(this).val());
});
$(document).on('change', "input[name='isrelation']", function () {
$("#relation-zone").toggleClass("hide", !$(this).prop("checked"));
});
$(document).on('change', "select[name='table']", function () {
var that = this;
Fast.api.ajax({
url: "command/get_field_list",
data: {table: $(that).val()},
}, function (data, ret) {
mainfields = data.fieldlist;
$("#relation-zone .relation-item").remove();
renderselect($("#fields"), mainfields);
return false;
});
return false;
});
$(document).on('click', "a.btn-newrelation", function () {
var that = this;
var index = parseInt($(that).data("index")) + 1;
var content = Template("relationtpl", {index: index});
content = $(content.replace(/\[index\]/, index));
$(this).data("index", index);
$(content).insertBefore($(that).closest(".row"));
$('select', content).selectpicker();
var exists = [$("select[name='table']").val()];
$("select.relationtable").each(function () {
exists.push($(this).val());
});
relationtable = [];
$.each(maintable, function (i, j) {
if ($.inArray(j, exists) < 0) {
relationtable.push(j);
}
});
renderselect($("select.relationtable", content), relationtable);
$("select.relationtable", content).trigger("change");
});
$(document).on('click', "a.btn-removerelation", function () {
$(this).closest(".row").remove();
});
$(document).on('change', "#relation-zone select.relationmode", function () {
var table = $("select.relationtable", $(this).closest(".row")).val();
var that = this;
Fast.api.ajax({
url: "command/get_field_list",
data: {table: table},
}, function (data, ret) {
renderselect($(that).closest(".row").find("select.relationprimarykey"), $(that).val() == 'belongsto' ? data.fieldlist : mainfields);
renderselect($(that).closest(".row").find("select.relationforeignkey"), $(that).val() == 'hasone' ? data.fieldlist : mainfields);
return false;
});
});
$(document).on('change', "#relation-zone select.relationtable", function () {
var that = this;
Fast.api.ajax({
url: "command/get_field_list",
data: {table: $(that).val()},
}, function (data, ret) {
renderselect($(that).closest(".row").find("select.relationmode"), relationmode);
renderselect($(that).closest(".row").find("select.relationfields"), mainfields)
renderselect($(that).closest(".row").find("select.relationforeignkey"), data.fieldlist)
renderselect($(that).closest(".row").find("select.relationfields"), data.fieldlist)
return false;
});
});
$(document).on('click', ".btn-command", function () {
var form = $(this).closest("form");
var textarea = $("textarea[rel=command]", form);
textarea.val('');
Fast.api.ajax({
url: "command/command/action/command",
data: form.serialize(),
}, function (data, ret) {
textarea.val(data.command);
return false;
});
});
$(document).on('click', ".btn-execute", function () {
var form = $(this).closest("form");
var textarea = $("textarea[rel=result]", form);
textarea.val('');
Fast.api.ajax({
url: "command/command/action/execute",
data: form.serialize(),
}, function (data, ret) {
textarea.val(data.result);
window.parent.$(".toolbar .btn-refresh").trigger('click');
top.window.Fast.api.refreshmenu();
return false;
}, function () {
window.parent.$(".toolbar .btn-refresh").trigger('click');
});
});
$("select[name='table']").trigger("change");
Controller.api.bindevent();
},
edit: function () {
Controller.api.bindevent();
},
api: {
bindevent: function () {
Form.api.bindevent($("form[role=form]"));
}
}
};
return Controller;
});
... ...
<?php
namespace addons\simditor;
use think\Addons;
/**
* 插件
*/
class Simditor extends Addons
{
/**
* 插件安装方法
* @return bool
*/
public function install()
{
return true;
}
/**
* 插件卸载方法
* @return bool
*/
public function uninstall()
{
return true;
}
}
... ...
@font-face{font-family:'Simditor';src:url(data:application/font-woff;charset=utf-8;base64,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) format("woff");font-weight:normal;font-style:normal;}.simditor-icon{display:inline-block;font:normal normal normal 14px/1 'Simditor';font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;transform:translate(0,0);}.simditor-icon-code:before{content:'\f000';}.simditor-icon-bold:before{content:'\f001';}.simditor-icon-italic:before{content:'\f002';}.simditor-icon-underline:before{content:'\f003';}.simditor-icon-times:before{content:'\f004';}.simditor-icon-strikethrough:before{content:'\f005';}.simditor-icon-list-ol:before{content:'\f006';}.simditor-icon-list-ul:before{content:'\f007';}.simditor-icon-quote-left:before{content:'\f008';}.simditor-icon-table:before{content:'\f009';}.simditor-icon-link:before{content:'\f00a';}.simditor-icon-picture-o:before{content:'\f00b';}.simditor-icon-minus:before{content:'\f00c';}.simditor-icon-indent:before{content:'\f00d';}.simditor-icon-outdent:before{content:'\f00e';}.simditor-icon-unlink:before{content:'\f00f';}.simditor-icon-caret-down:before{content:'\f010';}.simditor-icon-caret-right:before{content:'\f011';}.simditor-icon-upload:before{content:'\f012';}.simditor-icon-undo:before{content:'\f013';}.simditor-icon-smile-o:before{content:'\f014';}.simditor-icon-tint:before{content:'\f015';}.simditor-icon-font:before{content:'\f016';}.simditor-icon-html5:before{content:'\f017';}.simditor-icon-mark:before{content:'\f018';}.simditor-icon-align-center:before{content:'\f019';}.simditor-icon-align-left:before{content:'\f01a';}.simditor-icon-align-right:before{content:'\f01b';}.simditor-icon-font-minus:before{content:'\f01c';}.simditor-icon-markdown:before{content:'\f01d';}.simditor-icon-checklist:before{content:'\f01e';}.simditor{position:relative;border:1px solid #c9d8db;}.simditor .simditor-wrapper{position:relative;background:#ffffff;}.simditor .simditor-wrapper > textarea{display:none !important;width:100%;box-sizing:border-box;font-family:monaco;font-size:14px;line-height:1.6;border:none;padding:22px 15px 36px;min-height:300px;outline:none;background:transparent;resize:none;}.simditor .simditor-wrapper .simditor-placeholder{display:none;position:absolute;left:0;z-index:0;padding:22px 15px;font-size:16px;font-family:arial,sans-serif;line-height:1.5;color:#999999;background:transparent;}.simditor .simditor-wrapper.toolbar-floating .simditor-toolbar{position:fixed;top:0;z-index:10;box-shadow:0 0 6px rgba(0,0,0,0.1);}.simditor .simditor-wrapper .simditor-image-loading{width:100%;height:100%;position:absolute;top:0;left:0;z-index:2;}.simditor .simditor-wrapper .simditor-image-loading .progress{width:100%;height:100%;background:rgba(0,0,0,0.4);position:absolute;bottom:0;left:0;}.simditor .simditor-body{padding:10px;min-height:300px;outline:none;cursor:text;position:relative;z-index:1;background:transparent;width:100%;}.simditor .simditor-body a.selected{background:#b3d4fd;}.simditor .simditor-body a.simditor-mention{cursor:pointer;}.simditor .simditor-body .simditor-table{position:relative;}.simditor .simditor-body .simditor-table.resizing{cursor:col-resize;}.simditor .simditor-body .simditor-table .simditor-resize-handle{position:absolute;left:0;top:0;width:10px;height:100%;cursor:col-resize;}.simditor .simditor-body pre{box-sizing:border-box;-moz-box-sizing:border-box;word-wrap:break-word !important;white-space:pre-wrap !important;}.simditor .simditor-body img{cursor:pointer;}.simditor .simditor-body img.selected{box-shadow:0 0 0 4px #cccccc;}.simditor .simditor-paste-bin{position:fixed;bottom:10px;right:10px;width:1px;height:20px;font-size:1px;line-height:1px;overflow:hidden;padding:0;margin:0;opacity:0;-webkit-user-select:text;}.simditor .simditor-toolbar{border-bottom:1px solid #eeeeee;background:#ffffff;width:100%;}.simditor .simditor-toolbar > ul{margin:0;padding:0 0 0 6px;list-style:none;}.simditor .simditor-toolbar > ul > li{position:relative;display:inline-block;font-size:0;}.simditor .simditor-toolbar > ul > li > span.separator{display:inline-block;background:#cfcfcf;width:1px;height:18px;margin:11px 15px;vertical-align:middle;}.simditor .simditor-toolbar > ul > li > .toolbar-item{display:inline-block;width:36px;height:36px;outline:none;color:#333333;font-size:15px;line-height:36px;vertical-align:middle;text-align:center;text-decoration:none;}.simditor .simditor-toolbar > ul > li > .toolbar-item span{opacity:0.6;}.simditor .simditor-toolbar > ul > li > .toolbar-item span.simditor-icon{display:inline;line-height:normal;}.simditor .simditor-toolbar > ul > li > .toolbar-item:hover span{opacity:1;}.simditor .simditor-toolbar > ul > li > .toolbar-item.active{background:#eeeeee;}.simditor .simditor-toolbar > ul > li > .toolbar-item.active span{opacity:1;}.simditor .simditor-toolbar > ul > li > .toolbar-item.disabled{cursor:default;}.simditor .simditor-toolbar > ul > li > .toolbar-item.disabled span{opacity:0.3;}.simditor .simditor-toolbar > ul > li > .toolbar-item.toolbar-item-title span:before{content:"H";font-size:19px;font-weight:bold;font-family:'Times New Roman';}.simditor .simditor-toolbar > ul > li > .toolbar-item.toolbar-item-title.active-h1 span:before{content:'H1';font-size:18px;}.simditor .simditor-toolbar > ul > li > .toolbar-item.toolbar-item-title.active-h2 span:before{content:'H2';font-size:18px;}.simditor .simditor-toolbar > ul > li > .toolbar-item.toolbar-item-title.active-h3 span:before{content:'H3';font-size:18px;}.simditor .simditor-toolbar > ul > li > .toolbar-item.toolbar-item-image{position:relative;overflow:hidden;}.simditor .simditor-toolbar > ul > li > .toolbar-item.toolbar-item-image > input[type=file]{position:absolute;right:0px;top:0px;opacity:0;font-size:100px;cursor:pointer;}.simditor .simditor-toolbar > ul > li.menu-on .toolbar-item{position:relative;z-index:20;background:#ffffff;box-shadow:0 1px 4px rgba(0,0,0,0.3);}.simditor .simditor-toolbar > ul > li.menu-on .toolbar-item span{opacity:1;}.simditor .simditor-toolbar > ul > li.menu-on .toolbar-menu{display:block;}.simditor .simditor-toolbar .toolbar-menu{display:none;position:absolute;top:36px;left:0;z-index:21;background:#ffffff;text-align:left;box-shadow:0 0 4px rgba(0,0,0,0.3);}.simditor .simditor-toolbar .toolbar-menu:before{content:'';display:block;width:36px;height:4px;background:#ffffff;position:absolute;top:-3px;left:0;}.simditor .simditor-toolbar .toolbar-menu ul{min-width:160px;list-style:none;margin:0;padding:10px 1px;}.simditor .simditor-toolbar .toolbar-menu ul > li .menu-item{display:block;font-size:14px;line-height:2em;padding:0 10px;text-decoration:none;color:#666666;}.simditor .simditor-toolbar .toolbar-menu ul > li .menu-item:hover{background:#f6f6f6;}.simditor .simditor-toolbar .toolbar-menu ul > li .menu-item.menu-item-h1{font-size:24px;color:#333333;}.simditor .simditor-toolbar .toolbar-menu ul > li .menu-item.menu-item-h2{font-size:22px;color:#333333;}.simditor .simditor-toolbar .toolbar-menu ul > li .menu-item.menu-item-h3{font-size:20px;color:#333333;}.simditor .simditor-toolbar .toolbar-menu ul > li .menu-item.menu-item-h4{font-size:18px;color:#333333;}.simditor .simditor-toolbar .toolbar-menu ul > li .menu-item.menu-item-h5{font-size:16px;color:#333333;}.simditor .simditor-toolbar .toolbar-menu ul > li .separator{display:block;border-top:1px solid #cccccc;height:0;line-height:0;font-size:0;margin:6px 0;}.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-color{width:96px;}.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-color .color-list{height:36px;margin:10px 6px 6px 10px;padding:0;min-width:0;}.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-color .color-list li{float:left;margin:0 4px 4px 0;}.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-color .color-list li .font-color{display:block;width:16px;height:16px;background:#dfdfdf;border-radius:2px;}.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-color .color-list li .font-color:hover{opacity:0.8;}.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-color .color-list li .font-color.font-color-default{background:#333333;}.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-color .color-list li .font-color-1{background:#E33737;}.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-color .color-list li .font-color-2{background:#e28b41;}.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-color .color-list li .font-color-3{background:#c8a732;}.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-color .color-list li .font-color-4{background:#209361;}.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-color .color-list li .font-color-5{background:#418caf;}.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-color .color-list li .font-color-6{background:#aa8773;}.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-color .color-list li .font-color-7{background:#999999;}.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-table .menu-create-table{background:#ffffff;padding:1px;}.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-table .menu-create-table table{border:none;border-collapse:collapse;border-spacing:0;table-layout:fixed;}.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-table .menu-create-table table td{padding:0;cursor:pointer;}.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-table .menu-create-table table td:before{width:16px;height:16px;border:1px solid #ffffff;background:#f3f3f3;display:block;content:"";}.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-table .menu-create-table table td.selected:before{background:#cfcfcf;}.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-table .menu-edit-table{display:none;}.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-table .menu-edit-table ul li{white-space:nowrap;}.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-image .menu-item-upload-image{position:relative;overflow:hidden;}.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-image .menu-item-upload-image input[type=file]{position:absolute;right:0px;top:0px;opacity:0;font-size:100px;cursor:pointer;}.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-alignment{width:100%;}.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-alignment ul{min-width:100%;}.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-alignment .menu-item{text-align:center;}.simditor .simditor-popover{display:none;padding:5px 8px 0;background:#ffffff;box-shadow:0 1px 4px rgba(0,0,0,0.4);border-radius:2px;position:absolute;z-index:2;}.simditor .simditor-popover .settings-field{margin:0 0 5px 0;font-size:12px;height:25px;line-height:25px;}.simditor .simditor-popover .settings-field label{display:inline-block;margin:0 5px 0 0;}.simditor .simditor-popover .settings-field input[type=text]{display:inline-block;width:200px;box-sizing:border-box;font-size:12px;}.simditor .simditor-popover .settings-field input[type=text].image-size{width:83px;}.simditor .simditor-popover .settings-field .times{display:inline-block;width:26px;font-size:12px;text-align:center;}.simditor .simditor-popover.link-popover .btn-unlink,.simditor .simditor-popover.image-popover .btn-upload,.simditor .simditor-popover.image-popover .btn-restore{display:inline-block;margin:0 0 0 5px;color:#333333;font-size:14px;outline:0;}.simditor .simditor-popover.link-popover .btn-unlink span,.simditor .simditor-popover.image-popover .btn-upload span,.simditor .simditor-popover.image-popover .btn-restore span{opacity:0.6;}.simditor .simditor-popover.link-popover .btn-unlink:hover span,.simditor .simditor-popover.image-popover .btn-upload:hover span,.simditor .simditor-popover.image-popover .btn-restore:hover span{opacity:1;}.simditor .simditor-popover.image-popover .btn-upload{position:relative;display:inline-block;overflow:hidden;vertical-align:middle;}.simditor .simditor-popover.image-popover .btn-upload input[type=file]{position:absolute;right:0px;top:0px;opacity:0;height:100%;width:28px;}.simditor.simditor-mobile .simditor-wrapper.toolbar-floating .simditor-toolbar{position:absolute;top:0;z-index:10;box-shadow:0 0 6px rgba(0,0,0,0.1);}.simditor .simditor-body,.editor-style{font-size:14px;font-family:arial,sans-serif;line-height:1.6;color:#333;outline:none;word-wrap:break-word;}.simditor .simditor-body > :first-child,.editor-style > :first-child{margin-top:0 !important;}.simditor .simditor-body a,.editor-style a{color:#4298BA;text-decoration:none;word-break:break-all;}.simditor .simditor-body a:visited,.editor-style a:visited{color:#4298BA;}.simditor .simditor-body a:hover,.editor-style a:hover{color:#0F769F;}.simditor .simditor-body a:active,.editor-style a:active{color:#9E792E;}.simditor .simditor-body a:hover,.simditor .simditor-body a:active,.editor-style a:hover,.editor-style a:active{outline:0;}.simditor .simditor-body h1,.simditor .simditor-body h2,.simditor .simditor-body h3,.simditor .simditor-body h4,.simditor .simditor-body h5,.simditor .simditor-body h6,.editor-style h1,.editor-style h2,.editor-style h3,.editor-style h4,.editor-style h5,.editor-style h6{font-weight:normal;margin:36px 0 20px;color:#000000;}.simditor .simditor-body h1,.editor-style h1{font-size:24px;}.simditor .simditor-body h2,.editor-style h2{font-size:22px;}.simditor .simditor-body h3,.editor-style h3{font-size:20px;}.simditor .simditor-body h4,.editor-style h4{font-size:18px;}.simditor .simditor-body h5,.editor-style h5{font-size:16px;}.simditor .simditor-body h6,.editor-style h6{font-size:16px;}.simditor .simditor-body p,.simditor .simditor-body div,.editor-style p,.editor-style div{word-wrap:break-word;margin:0 0 10px 0;color:#333;word-wrap:break-word;}.simditor .simditor-body b,.simditor .simditor-body strong,.editor-style b,.editor-style strong{font-weight:bold;}.simditor .simditor-body i,.simditor .simditor-body em,.editor-style i,.editor-style em{font-style:italic;}.simditor .simditor-body u,.editor-style u{text-decoration:underline;}.simditor .simditor-body strike,.simditor .simditor-body del,.editor-style strike,.editor-style del{text-decoration:line-through;}.simditor .simditor-body ul,.simditor .simditor-body ol,.editor-style ul,.editor-style ol{list-style:disc outside none;margin:15px 0;padding:0 0 0 36px;line-height:1.6;}.simditor .simditor-body ul li,.simditor .simditor-body ol li,.editor-style ul li,.editor-style ol li{list-style-type:inherit;}.simditor .simditor-body ul ul,.simditor .simditor-body ul ol,.simditor .simditor-body ol ul,.simditor .simditor-body ol ol,.editor-style ul ul,.editor-style ul ol,.editor-style ol ul,.editor-style ol ol{padding-left:30px;}.simditor .simditor-body ul ul,.simditor .simditor-body ol ul,.editor-style ul ul,.editor-style ol ul{list-style:circle outside none;}.simditor .simditor-body ul ul ul,.simditor .simditor-body ol ul ul,.editor-style ul ul ul,.editor-style ol ul ul{list-style:square outside none;}.simditor .simditor-body ol,.editor-style ol{list-style:decimal;}.simditor .simditor-body blockquote,.editor-style blockquote{border-left:6px solid #ddd;padding:5px 0 5px 10px;margin:15px 0 15px 15px;}.simditor .simditor-body blockquote > :first-child,.editor-style blockquote > :first-child{margin-top:0;}.simditor .simditor-body code,.editor-style code{display:inline-block;padding:0 4px;margin:0 5px;background:#eeeeee;border-radius:3px;font-size:13px;font-family:'monaco','Consolas',"Liberation Mono",Courier,monospace;}.simditor .simditor-body pre,.editor-style pre{padding:10px 5px 10px 10px;margin:15px 0;display:block;line-height:18px;background:#F0F0F0;border-radius:3px;font-size:13px;font-family:'monaco','Consolas',"Liberation Mono",Courier,monospace;white-space:pre;word-wrap:normal;overflow-x:auto;}.simditor .simditor-body pre code,.editor-style pre code{display:block;padding:0;margin:0;background:none;border-radius:0;}.simditor .simditor-body hr,.editor-style hr{display:block;height:0px;border:0;border-top:1px solid #ccc;margin:15px 0;padding:0;}.simditor .simditor-body table,.editor-style table{width:100%;table-layout:fixed;border-collapse:collapse;border-spacing:0;margin:15px 0;}.simditor .simditor-body table thead,.editor-style table thead{background-color:#f9f9f9;}.simditor .simditor-body table td,.simditor .simditor-body table th,.editor-style table td,.editor-style table th{min-width:36px;height:30px;border:1px solid #ccc;vertical-align:top;padding:2px 4px;text-align:left;box-sizing:border-box;}.simditor .simditor-body table td.active,.simditor .simditor-body table th.active,.editor-style table td.active,.editor-style table th.active{background-color:#ffffee;}.simditor .simditor-body img,.editor-style img{margin:0 5px;vertical-align:middle;}
\ No newline at end of file
... ...
此 diff 太大无法显示。
require.config({
paths: {
'simditor': '../addons/simditor/js/simditor.min',
},
shim: {
'simditor': [
'css!../addons/simditor/css/simditor.min.css'
]
}
});
require(['form'], function (Form) {
var _bindevent = Form.events.bindevent;
Form.events.bindevent = function (form) {
_bindevent.apply(this, [form]);
if ($(".editor", form).size() > 0) {
//修改上传的接口调用
require(['upload', 'simditor'], function (Upload, Simditor) {
var editor, mobileToolbar, toolbar;
Simditor.locale = 'zh-CN';
Simditor.list = {};
toolbar = ['title', 'bold', 'italic', 'underline', 'strikethrough', 'fontScale', 'color', '|', 'ol', 'ul', 'blockquote', 'code', 'table', '|', 'link', 'image', 'hr', '|', 'indent', 'outdent', 'alignment'];
mobileToolbar = ["bold", "underline", "strikethrough", "color", "ul", "ol"];
$(".editor", form).each(function () {
var id = $(this).attr("id");
editor = new Simditor({
textarea: this,
toolbarFloat: false,
toolbar: toolbar,
pasteImage: true,
defaultImage: Config.__CDN__ + '/assets/addons/simditor/images/image.png',
upload: {url: '/'}
});
editor.uploader.on('beforeupload', function (e, file) {
Upload.api.send(file.obj, function (data) {
var url = Fast.api.cdnurl(data.url);
editor.uploader.trigger("uploadsuccess", [file, {success: true, file_path: url}]);
});
return false;
});
editor.on("blur", function () {
this.textarea.trigger("blur");
});
Simditor.list[id] = editor;
});
});
}
}
});
\ No newline at end of file
... ...
#!/bin/bash
/usr/local/bin/node r.js -o ./js.js name=simditor baseUrl=../src/js out=../assets/js/simditor.min.js
/usr/local/bin/node r.js -o ./css.js cssIn=../src/css/simditor.css out=../assets/css/simditor.min.css
... ...
({
optimizeCss: "default",
optimize: "uglify"
})
\ No newline at end of file
... ...
({
name: "simditor",
paths: {
'jquery': 'empty:',
'simditor': 'simditor',
'simple-module': 'module',
'simple-uploader': 'uploader',
'simple-hotkeys': 'hotkeys',
},
});
\ No newline at end of file
... ...
此 diff 太大无法显示。
<?php
return [
];
... ...
name = simditor
title = Simditor
intro = 简洁清晰的富文本插件
author = Karson
website = http://www.fastadmin.net
version = 1.0.5
state = 1
url = /addons/simditor
... ...
@media screen and (max-device-width: 240px) and (min-device-width: 220px) {
body {
width: 240px;
margin: 0 auto;
}
body .wrapper {
width: 100%;
}
body .wrapper header {
padding: 30px 0 20px;
}
body .wrapper header h1 {
background-size: 200px auto;
background-position: 50px 0;
padding-top: 90px;
height: 45px;
}
body .wrapper header h1 a {
background-size: 160px auto;
background-position: 10px 0;
}
body .wrapper header p.desc {
font-size: 16px;
}
body .wrapper footer {
margin: 20px 0;
}
body .wrapper #page-demo {
width: 96%;
margin: 0 2%;
}
body .wrapper #link-fork {
z-index: -1;
width: 80px;
height: auto;
}
body .wrapper #link-fork img {
max-width: 80px;
height: auto;
}
nav {
display: none;
}
}
@media screen and (max-device-width: 320px) and (min-device-width: 300px) {
body {
width: 320px;
margin: 0 auto;
}
body .wrapper {
width: 100%;
}
body .wrapper header {
padding: 30px 0 20px;
}
body .wrapper header h1 {
background-size: 200px auto;
background-position: 50px 0;
padding-top: 90px;
height: 45px;
}
body .wrapper header h1 a {
background-size: 160px auto;
background-position: 10px 0;
}
body .wrapper header p.desc {
font-size: 16px;
}
body .wrapper footer {
margin: 20px 0;
}
body .wrapper #page-demo {
width: 96%;
margin: 0 2%;
}
body .wrapper #link-fork {
z-index: -1;
width: 80px;
height: auto;
}
body .wrapper #link-fork img {
max-width: 80px;
height: auto;
}
nav {
display: none;
}
}
@media screen and (max-device-width: 360px) and (min-device-width: 340px) {
body {
width: 360px;
margin: 0 auto;
}
body .wrapper {
width: 100%;
}
body .wrapper header {
padding: 30px 0 20px;
}
body .wrapper header h1 {
background-size: 200px auto;
background-position: 50px 0;
padding-top: 90px;
height: 45px;
}
body .wrapper header h1 a {
background-size: 160px auto;
background-position: 10px 0;
}
body .wrapper header p.desc {
font-size: 16px;
}
body .wrapper footer {
margin: 20px 0;
}
body .wrapper #page-demo {
width: 96%;
margin: 0 2%;
}
body .wrapper #link-fork {
z-index: -1;
width: 80px;
height: auto;
}
body .wrapper #link-fork img {
max-width: 80px;
height: auto;
}
nav {
display: none;
}
}
@media screen and (max-device-width: 480px) and (min-device-width: 460px) {
body {
width: 480px;
margin: 0 auto;
}
body .wrapper {
width: 100%;
}
body .wrapper header {
padding: 30px 0 20px;
}
body .wrapper header h1 {
background-size: 200px auto;
background-position: 50px 0;
padding-top: 90px;
height: 45px;
}
body .wrapper header h1 a {
background-size: 160px auto;
background-position: 10px 0;
}
body .wrapper header p.desc {
font-size: 16px;
}
body .wrapper footer {
margin: 20px 0;
}
body .wrapper #page-demo {
width: 96%;
margin: 0 2%;
}
body .wrapper #link-fork {
z-index: -1;
width: 80px;
height: auto;
}
body .wrapper #link-fork img {
max-width: 80px;
height: auto;
}
nav {
display: none;
}
}
@media screen and (max-device-width: 640px) and (min-device-width: 620px) {
body {
width: 320px;
margin: 0 auto;
}
body .wrapper {
width: 100%;
}
body .wrapper header {
padding: 30px 0 20px;
}
body .wrapper header h1 {
background-size: 200px auto;
background-position: 50px 0;
padding-top: 90px;
height: 45px;
}
body .wrapper header h1 a {
background-size: 160px auto;
background-position: 10px 0;
}
body .wrapper header p.desc {
font-size: 16px;
}
body .wrapper footer {
margin: 20px 0;
}
body .wrapper #page-demo {
width: 96%;
margin: 0 2%;
}
body .wrapper #link-fork {
z-index: -1;
width: 80px;
height: auto;
}
body .wrapper #link-fork img {
max-width: 80px;
height: auto;
}
nav {
display: none;
}
}
@media screen and (max-device-width: 720px) and (min-device-width: 700px) {
body {
width: 360px;
margin: 0 auto;
}
body .wrapper {
width: 100%;
}
body .wrapper header {
padding: 30px 0 20px;
}
body .wrapper header h1 {
background-size: 200px auto;
background-position: 50px 0;
padding-top: 90px;
height: 45px;
}
body .wrapper header h1 a {
background-size: 160px auto;
background-position: 10px 0;
}
body .wrapper header p.desc {
font-size: 16px;
}
body .wrapper footer {
margin: 20px 0;
}
body .wrapper #page-demo {
width: 96%;
margin: 0 2%;
}
body .wrapper #link-fork {
z-index: -1;
width: 80px;
height: auto;
}
body .wrapper #link-fork img {
max-width: 80px;
height: auto;
}
nav {
display: none;
}
}
@media screen and (max-device-width: 800px) and (min-device-width: 780px) {
body {
width: 400px;
margin: 0 auto;
}
body .wrapper {
width: 100%;
}
body .wrapper header {
padding: 30px 0 20px;
}
body .wrapper header h1 {
background-size: 200px auto;
background-position: 50px 0;
padding-top: 90px;
height: 45px;
}
body .wrapper header h1 a {
background-size: 160px auto;
background-position: 10px 0;
}
body .wrapper header p.desc {
font-size: 16px;
}
body .wrapper footer {
margin: 20px 0;
}
body .wrapper #page-demo {
width: 96%;
margin: 0 2%;
}
body .wrapper #link-fork {
z-index: -1;
width: 88.8888888889px;
height: auto;
}
body .wrapper #link-fork img {
max-width: 88.8888888889px;
height: auto;
}
nav {
display: none;
}
}
@media screen and (max-device-width: 960px) and (min-device-width: 940px) {
body {
width: 480px;
margin: 0 auto;
}
body .wrapper {
width: 100%;
}
body .wrapper header {
padding: 30px 0 20px;
}
body .wrapper header h1 {
background-size: 200px auto;
background-position: 50px 0;
padding-top: 90px;
height: 45px;
}
body .wrapper header h1 a {
background-size: 160px auto;
background-position: 10px 0;
}
body .wrapper header p.desc {
font-size: 16px;
}
body .wrapper footer {
margin: 20px 0;
}
body .wrapper #page-demo {
width: 96%;
margin: 0 2%;
}
body .wrapper #link-fork {
z-index: -1;
width: 100px;
height: auto;
}
body .wrapper #link-fork img {
max-width: 100px;
height: auto;
}
nav {
display: none;
}
}
@media screen and (max-device-width: 1024px) and (min-device-width: 1004px) {
body {
width: 512px;
margin: 0 auto;
}
body .wrapper {
width: 100%;
}
body .wrapper header {
padding: 30px 0 20px;
}
body .wrapper header h1 {
background-size: 200px auto;
background-position: 50px 0;
padding-top: 90px;
height: 45px;
}
body .wrapper header h1 a {
background-size: 160px auto;
background-position: 10px 0;
}
body .wrapper header p.desc {
font-size: 16px;
}
body .wrapper footer {
margin: 20px 0;
}
body .wrapper #page-demo {
width: 96%;
margin: 0 2%;
}
body .wrapper #link-fork {
z-index: -1;
width: 100px;
height: auto;
}
body .wrapper #link-fork img {
max-width: 100px;
height: auto;
}
nav {
display: none;
}
}
@media screen and (max-device-width: 1280px) and (min-device-width: 1260px) {
body {
width: 640px;
margin: 0 auto;
}
body .wrapper {
width: 100%;
}
body .wrapper header {
padding: 30px 0 20px;
}
body .wrapper header h1 {
background-size: 200px auto;
background-position: 50px 0;
padding-top: 90px;
height: 45px;
}
body .wrapper header h1 a {
background-size: 160px auto;
background-position: 10px 0;
}
body .wrapper header p.desc {
font-size: 16px;
}
body .wrapper footer {
margin: 20px 0;
}
body .wrapper #page-demo {
width: 96%;
margin: 0 2%;
}
body .wrapper #link-fork {
z-index: -1;
width: 100px;
height: auto;
}
body .wrapper #link-fork img {
max-width: 100px;
height: auto;
}
nav {
display: none;
}
}
@media screen and (device-aspect-ratio: 40 / 71) and (orientation: landscape) {
body {
width: 568px;
}
}
@media screen and (device-aspect-ratio: 2 / 3) and (orientation: landscape) {
body {
width: 480px;
}
}
... ...
@font-face {
font-family: 'Simditor';
src: url(data:application/font-woff;charset=utf-8;base64,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) format("woff");
font-weight: normal;
font-style: normal;
}
.simditor-icon {
display: inline-block;
font: normal normal normal 14px/1 'Simditor';
font-size: inherit;
text-rendering: auto;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
transform: translate(0, 0);
}
.simditor-icon-code:before {
content: '\f000';
}
.simditor-icon-bold:before {
content: '\f001';
}
.simditor-icon-italic:before {
content: '\f002';
}
.simditor-icon-underline:before {
content: '\f003';
}
.simditor-icon-times:before {
content: '\f004';
}
.simditor-icon-strikethrough:before {
content: '\f005';
}
.simditor-icon-list-ol:before {
content: '\f006';
}
.simditor-icon-list-ul:before {
content: '\f007';
}
.simditor-icon-quote-left:before {
content: '\f008';
}
.simditor-icon-table:before {
content: '\f009';
}
.simditor-icon-link:before {
content: '\f00a';
}
.simditor-icon-picture-o:before {
content: '\f00b';
}
.simditor-icon-minus:before {
content: '\f00c';
}
.simditor-icon-indent:before {
content: '\f00d';
}
.simditor-icon-outdent:before {
content: '\f00e';
}
.simditor-icon-unlink:before {
content: '\f00f';
}
.simditor-icon-caret-down:before {
content: '\f010';
}
.simditor-icon-caret-right:before {
content: '\f011';
}
.simditor-icon-upload:before {
content: '\f012';
}
.simditor-icon-undo:before {
content: '\f013';
}
.simditor-icon-smile-o:before {
content: '\f014';
}
.simditor-icon-tint:before {
content: '\f015';
}
.simditor-icon-font:before {
content: '\f016';
}
.simditor-icon-html5:before {
content: '\f017';
}
.simditor-icon-mark:before {
content: '\f018';
}
.simditor-icon-align-center:before {
content: '\f019';
}
.simditor-icon-align-left:before {
content: '\f01a';
}
.simditor-icon-align-right:before {
content: '\f01b';
}
.simditor-icon-font-minus:before {
content: '\f01c';
}
.simditor-icon-markdown:before {
content: '\f01d';
}
.simditor-icon-checklist:before {
content: '\f01e';
}
.simditor {
position: relative;
border: 1px solid #c9d8db;
}
.simditor .simditor-wrapper {
position: relative;
background: #ffffff;
}
.simditor .simditor-wrapper > textarea {
display: none !important;
width: 100%;
box-sizing: border-box;
font-family: monaco;
font-size: 14px;
line-height: 1.6;
border: none;
padding: 22px 15px 36px;
min-height: 300px;
outline: none;
background: transparent;
resize: none;
}
.simditor .simditor-wrapper .simditor-placeholder {
display: none;
position: absolute;
left: 0;
z-index: 0;
padding: 22px 15px;
font-size: 16px;
font-family: arial, sans-serif;
line-height: 1.5;
color: #999999;
background: transparent;
}
.simditor .simditor-wrapper.toolbar-floating .simditor-toolbar {
position: fixed;
top: 0;
z-index: 10;
box-shadow: 0 0 6px rgba(0, 0, 0, 0.1);
}
.simditor .simditor-wrapper .simditor-image-loading {
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
z-index: 2;
}
.simditor .simditor-wrapper .simditor-image-loading .progress {
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.4);
position: absolute;
bottom: 0;
left: 0;
}
.simditor .simditor-body {
padding: 10px;
min-height: 300px;
outline: none;
cursor: text;
position: relative;
z-index: 1;
background: transparent;
width:100%;
}
.simditor .simditor-body a.selected {
background: #b3d4fd;
}
.simditor .simditor-body a.simditor-mention {
cursor: pointer;
}
.simditor .simditor-body .simditor-table {
position: relative;
}
.simditor .simditor-body .simditor-table.resizing {
cursor: col-resize;
}
.simditor .simditor-body .simditor-table .simditor-resize-handle {
position: absolute;
left: 0;
top: 0;
width: 10px;
height: 100%;
cursor: col-resize;
}
.simditor .simditor-body pre {
/*min-height: 28px;*/
box-sizing: border-box;
-moz-box-sizing: border-box;
word-wrap: break-word !important;
white-space: pre-wrap !important;
}
.simditor .simditor-body img {
cursor: pointer;
}
.simditor .simditor-body img.selected {
box-shadow: 0 0 0 4px #cccccc;
}
.simditor .simditor-paste-bin {
position: fixed;
bottom: 10px;
right: 10px;
width: 1px;
height: 20px;
font-size: 1px;
line-height: 1px;
overflow: hidden;
padding: 0;
margin: 0;
opacity: 0;
-webkit-user-select: text;
}
.simditor .simditor-toolbar {
border-bottom: 1px solid #eeeeee;
background: #ffffff;
width: 100%;
}
.simditor .simditor-toolbar > ul {
margin: 0;
padding: 0 0 0 6px;
list-style: none;
}
.simditor .simditor-toolbar > ul > li {
position: relative;
display: inline-block;
font-size: 0;
}
.simditor .simditor-toolbar > ul > li > span.separator {
display: inline-block;
background: #cfcfcf;
width: 1px;
height: 18px;
margin: 11px 15px;
vertical-align: middle;
}
.simditor .simditor-toolbar > ul > li > .toolbar-item {
display: inline-block;
width: 36px;
height: 36px;
outline: none;
color: #333333;
font-size: 15px;
line-height: 36px;
vertical-align: middle;
text-align: center;
text-decoration: none;
}
.simditor .simditor-toolbar > ul > li > .toolbar-item span {
opacity: 0.6;
}
.simditor .simditor-toolbar > ul > li > .toolbar-item span.simditor-icon {
display: inline;
line-height: normal;
}
.simditor .simditor-toolbar > ul > li > .toolbar-item:hover span {
opacity: 1;
}
.simditor .simditor-toolbar > ul > li > .toolbar-item.active {
background: #eeeeee;
}
.simditor .simditor-toolbar > ul > li > .toolbar-item.active span {
opacity: 1;
}
.simditor .simditor-toolbar > ul > li > .toolbar-item.disabled {
cursor: default;
}
.simditor .simditor-toolbar > ul > li > .toolbar-item.disabled span {
opacity: 0.3;
}
.simditor .simditor-toolbar > ul > li > .toolbar-item.toolbar-item-title span:before {
content: "H";
font-size: 19px;
font-weight: bold;
font-family: 'Times New Roman';
}
.simditor .simditor-toolbar > ul > li > .toolbar-item.toolbar-item-title.active-h1 span:before {
content: 'H1';
font-size: 18px;
}
.simditor .simditor-toolbar > ul > li > .toolbar-item.toolbar-item-title.active-h2 span:before {
content: 'H2';
font-size: 18px;
}
.simditor .simditor-toolbar > ul > li > .toolbar-item.toolbar-item-title.active-h3 span:before {
content: 'H3';
font-size: 18px;
}
.simditor .simditor-toolbar > ul > li > .toolbar-item.toolbar-item-image {
position: relative;
overflow: hidden;
}
.simditor .simditor-toolbar > ul > li > .toolbar-item.toolbar-item-image > input[type=file] {
position: absolute;
right: 0px;
top: 0px;
opacity: 0;
font-size: 100px;
cursor: pointer;
}
.simditor .simditor-toolbar > ul > li.menu-on .toolbar-item {
position: relative;
z-index: 20;
background: #ffffff;
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3);
}
.simditor .simditor-toolbar > ul > li.menu-on .toolbar-item span {
opacity: 1;
}
.simditor .simditor-toolbar > ul > li.menu-on .toolbar-menu {
display: block;
}
.simditor .simditor-toolbar .toolbar-menu {
display: none;
position: absolute;
top: 36px;
left: 0;
z-index: 21;
background: #ffffff;
text-align: left;
box-shadow: 0 0 4px rgba(0, 0, 0, 0.3);
}
.simditor .simditor-toolbar .toolbar-menu:before {
content: '';
display: block;
width: 36px;
height: 4px;
background: #ffffff;
position: absolute;
top: -3px;
left: 0;
}
.simditor .simditor-toolbar .toolbar-menu ul {
min-width: 160px;
list-style: none;
margin: 0;
padding: 10px 1px;
}
.simditor .simditor-toolbar .toolbar-menu ul > li .menu-item {
display: block;
font-size: 14px;
line-height: 2em;
padding: 0 10px;
text-decoration: none;
color: #666666;
}
.simditor .simditor-toolbar .toolbar-menu ul > li .menu-item:hover {
background: #f6f6f6;
}
.simditor .simditor-toolbar .toolbar-menu ul > li .menu-item.menu-item-h1 {
font-size: 24px;
color: #333333;
}
.simditor .simditor-toolbar .toolbar-menu ul > li .menu-item.menu-item-h2 {
font-size: 22px;
color: #333333;
}
.simditor .simditor-toolbar .toolbar-menu ul > li .menu-item.menu-item-h3 {
font-size: 20px;
color: #333333;
}
.simditor .simditor-toolbar .toolbar-menu ul > li .menu-item.menu-item-h4 {
font-size: 18px;
color: #333333;
}
.simditor .simditor-toolbar .toolbar-menu ul > li .menu-item.menu-item-h5 {
font-size: 16px;
color: #333333;
}
.simditor .simditor-toolbar .toolbar-menu ul > li .separator {
display: block;
border-top: 1px solid #cccccc;
height: 0;
line-height: 0;
font-size: 0;
margin: 6px 0;
}
.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-color {
width: 96px;
}
.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-color .color-list {
height: 36px;
margin: 10px 6px 6px 10px;
padding: 0;
min-width: 0;
}
.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-color .color-list li {
float: left;
margin: 0 4px 4px 0;
}
.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-color .color-list li .font-color {
display: block;
width: 16px;
height: 16px;
background: #dfdfdf;
border-radius: 2px;
}
.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-color .color-list li .font-color:hover {
opacity: 0.8;
}
.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-color .color-list li .font-color.font-color-default {
background: #333333;
}
.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-color .color-list li .font-color-1 {
background: #E33737;
}
.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-color .color-list li .font-color-2 {
background: #e28b41;
}
.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-color .color-list li .font-color-3 {
background: #c8a732;
}
.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-color .color-list li .font-color-4 {
background: #209361;
}
.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-color .color-list li .font-color-5 {
background: #418caf;
}
.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-color .color-list li .font-color-6 {
background: #aa8773;
}
.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-color .color-list li .font-color-7 {
background: #999999;
}
.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-table .menu-create-table {
background: #ffffff;
padding: 1px;
}
.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-table .menu-create-table table {
border: none;
border-collapse: collapse;
border-spacing: 0;
table-layout: fixed;
}
.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-table .menu-create-table table td {
padding: 0;
cursor: pointer;
}
.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-table .menu-create-table table td:before {
width: 16px;
height: 16px;
border: 1px solid #ffffff;
background: #f3f3f3;
display: block;
content: "";
}
.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-table .menu-create-table table td.selected:before {
background: #cfcfcf;
}
.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-table .menu-edit-table {
display: none;
}
.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-table .menu-edit-table ul li {
white-space: nowrap;
}
.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-image .menu-item-upload-image {
position: relative;
overflow: hidden;
}
.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-image .menu-item-upload-image input[type=file] {
position: absolute;
right: 0px;
top: 0px;
opacity: 0;
font-size: 100px;
cursor: pointer;
}
.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-alignment {
width: 100%;
}
.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-alignment ul {
min-width: 100%;
}
.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-alignment .menu-item {
text-align: center;
}
.simditor .simditor-popover {
display: none;
padding: 5px 8px 0;
background: #ffffff;
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.4);
border-radius: 2px;
position: absolute;
z-index: 2;
}
.simditor .simditor-popover .settings-field {
margin: 0 0 5px 0;
font-size: 12px;
height: 25px;
line-height: 25px;
}
.simditor .simditor-popover .settings-field label {
display: inline-block;
margin: 0 5px 0 0;
}
.simditor .simditor-popover .settings-field input[type=text] {
display: inline-block;
width: 200px;
box-sizing: border-box;
font-size: 12px;
}
.simditor .simditor-popover .settings-field input[type=text].image-size {
width: 83px;
}
.simditor .simditor-popover .settings-field .times {
display: inline-block;
width: 26px;
font-size: 12px;
text-align: center;
}
.simditor .simditor-popover.link-popover .btn-unlink, .simditor .simditor-popover.image-popover .btn-upload, .simditor .simditor-popover.image-popover .btn-restore {
display: inline-block;
margin: 0 0 0 5px;
color: #333333;
font-size: 14px;
outline: 0;
}
.simditor .simditor-popover.link-popover .btn-unlink span, .simditor .simditor-popover.image-popover .btn-upload span, .simditor .simditor-popover.image-popover .btn-restore span {
opacity: 0.6;
}
.simditor .simditor-popover.link-popover .btn-unlink:hover span, .simditor .simditor-popover.image-popover .btn-upload:hover span, .simditor .simditor-popover.image-popover .btn-restore:hover span {
opacity: 1;
}
.simditor .simditor-popover.image-popover .btn-upload {
position: relative;
display: inline-block;
overflow: hidden;
vertical-align: middle;
}
.simditor .simditor-popover.image-popover .btn-upload input[type=file] {
position: absolute;
right: 0px;
top: 0px;
opacity: 0;
height: 100%;
width: 28px;
}
.simditor.simditor-mobile .simditor-wrapper.toolbar-floating .simditor-toolbar {
position: absolute;
top: 0;
z-index: 10;
box-shadow: 0 0 6px rgba(0, 0, 0, 0.1);
}
.simditor .simditor-body, .editor-style {
font-size: 14px;
font-family: arial, sans-serif;
line-height: 1.6;
color: #333;
outline: none;
word-wrap: break-word;
}
.simditor .simditor-body > :first-child, .editor-style > :first-child {
margin-top: 0 !important;
}
.simditor .simditor-body a, .editor-style a {
color: #4298BA;
text-decoration: none;
word-break: break-all;
}
.simditor .simditor-body a:visited, .editor-style a:visited {
color: #4298BA;
}
.simditor .simditor-body a:hover, .editor-style a:hover {
color: #0F769F;
}
.simditor .simditor-body a:active, .editor-style a:active {
color: #9E792E;
}
.simditor .simditor-body a:hover, .simditor .simditor-body a:active, .editor-style a:hover, .editor-style a:active {
outline: 0;
}
.simditor .simditor-body h1, .simditor .simditor-body h2, .simditor .simditor-body h3, .simditor .simditor-body h4, .simditor .simditor-body h5, .simditor .simditor-body h6, .editor-style h1, .editor-style h2, .editor-style h3, .editor-style h4, .editor-style h5, .editor-style h6 {
font-weight: normal;
margin: 36px 0 20px;
color: #000000;
}
.simditor .simditor-body h1, .editor-style h1 {
font-size: 24px;
}
.simditor .simditor-body h2, .editor-style h2 {
font-size: 22px;
}
.simditor .simditor-body h3, .editor-style h3 {
font-size: 20px;
}
.simditor .simditor-body h4, .editor-style h4 {
font-size: 18px;
}
.simditor .simditor-body h5, .editor-style h5 {
font-size: 16px;
}
.simditor .simditor-body h6, .editor-style h6 {
font-size: 16px;
}
.simditor .simditor-body p, .simditor .simditor-body div, .editor-style p, .editor-style div {
word-wrap: break-word;
margin: 0 0 10px 0;
color: #333;
word-wrap: break-word;
}
.simditor .simditor-body b, .simditor .simditor-body strong, .editor-style b, .editor-style strong {
font-weight: bold;
}
.simditor .simditor-body i, .simditor .simditor-body em, .editor-style i, .editor-style em {
font-style: italic;
}
.simditor .simditor-body u, .editor-style u {
text-decoration: underline;
}
.simditor .simditor-body strike, .simditor .simditor-body del, .editor-style strike, .editor-style del {
text-decoration: line-through;
}
.simditor .simditor-body ul, .simditor .simditor-body ol, .editor-style ul, .editor-style ol {
list-style: disc outside none;
margin: 15px 0;
padding: 0 0 0 36px;
line-height: 1.6;
}
.simditor .simditor-body ul li, .simditor .simditor-body ol li, .editor-style ul li, .editor-style ol li {
list-style-type: inherit;
}
.simditor .simditor-body ul ul, .simditor .simditor-body ul ol, .simditor .simditor-body ol ul, .simditor .simditor-body ol ol, .editor-style ul ul, .editor-style ul ol, .editor-style ol ul, .editor-style ol ol {
padding-left: 30px;
}
.simditor .simditor-body ul ul, .simditor .simditor-body ol ul, .editor-style ul ul, .editor-style ol ul {
list-style: circle outside none;
}
.simditor .simditor-body ul ul ul, .simditor .simditor-body ol ul ul, .editor-style ul ul ul, .editor-style ol ul ul {
list-style: square outside none;
}
.simditor .simditor-body ol, .editor-style ol {
list-style: decimal;
}
.simditor .simditor-body blockquote, .editor-style blockquote {
border-left: 6px solid #ddd;
padding: 5px 0 5px 10px;
margin: 15px 0 15px 15px;
}
.simditor .simditor-body blockquote > :first-child, .editor-style blockquote > :first-child {
margin-top: 0;
}
.simditor .simditor-body code, .editor-style code {
display: inline-block;
padding: 0 4px;
margin: 0 5px;
background: #eeeeee;
border-radius: 3px;
font-size: 13px;
font-family: 'monaco', 'Consolas', "Liberation Mono", Courier, monospace;
}
.simditor .simditor-body pre, .editor-style pre {
padding: 10px 5px 10px 10px;
margin: 15px 0;
display: block;
line-height: 18px;
background: #F0F0F0;
border-radius: 3px;
font-size: 13px;
font-family: 'monaco', 'Consolas', "Liberation Mono", Courier, monospace;
white-space: pre;
word-wrap: normal;
overflow-x: auto;
}
.simditor .simditor-body pre code, .editor-style pre code {
display: block;
padding: 0;
margin: 0;
background: none;
border-radius: 0;
}
.simditor .simditor-body hr, .editor-style hr {
display: block;
height: 0px;
border: 0;
border-top: 1px solid #ccc;
margin: 15px 0;
padding: 0;
}
.simditor .simditor-body table, .editor-style table {
width: 100%;
table-layout: fixed;
border-collapse: collapse;
border-spacing: 0;
margin: 15px 0;
}
.simditor .simditor-body table thead, .editor-style table thead {
background-color: #f9f9f9;
}
.simditor .simditor-body table td, .simditor .simditor-body table th, .editor-style table td, .editor-style table th {
min-width: 36px;
height: 30px;
border: 1px solid #ccc;
vertical-align: top;
padding: 2px 4px;
text-align: left;
box-sizing: border-box;
}
.simditor .simditor-body table td.active, .simditor .simditor-body table th.active, .editor-style table td.active, .editor-style table th.active {
background-color: #ffffee;
}
.simditor .simditor-body img, .editor-style img {
margin: 0 5px;
vertical-align: middle;
}
... ...
(function (root, factory) {
if (typeof define === 'function' && define.amd) {
// AMD. Register as an anonymous module unless amdModuleId is set
define('simple-hotkeys', ["jquery","simple-module"], function ($, SimpleModule) {
return (root['hotkeys'] = factory($, SimpleModule));
});
} else if (typeof exports === 'object') {
// Node. Does not work with strict CommonJS, but
// only CommonJS-like environments that support module.exports,
// like Node.
module.exports = factory(require("jquery"),require("simple-module"));
} else {
root.simple = root.simple || {};
root.simple['hotkeys'] = factory(jQuery,SimpleModule);
}
}(this, function ($, SimpleModule) {
var Hotkeys, hotkeys,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
Hotkeys = (function(superClass) {
extend(Hotkeys, superClass);
function Hotkeys() {
return Hotkeys.__super__.constructor.apply(this, arguments);
}
Hotkeys.count = 0;
Hotkeys.keyNameMap = {
8: "Backspace",
9: "Tab",
13: "Enter",
16: "Shift",
17: "Control",
18: "Alt",
19: "Pause",
20: "CapsLock",
27: "Esc",
32: "Spacebar",
33: "PageUp",
34: "PageDown",
35: "End",
36: "Home",
37: "Left",
38: "Up",
39: "Right",
40: "Down",
45: "Insert",
46: "Del",
91: "Meta",
93: "Meta",
48: "0",
49: "1",
50: "2",
51: "3",
52: "4",
53: "5",
54: "6",
55: "7",
56: "8",
57: "9",
65: "A",
66: "B",
67: "C",
68: "D",
69: "E",
70: "F",
71: "G",
72: "H",
73: "I",
74: "J",
75: "K",
76: "L",
77: "M",
78: "N",
79: "O",
80: "P",
81: "Q",
82: "R",
83: "S",
84: "T",
85: "U",
86: "V",
87: "W",
88: "X",
89: "Y",
90: "Z",
96: "0",
97: "1",
98: "2",
99: "3",
100: "4",
101: "5",
102: "6",
103: "7",
104: "8",
105: "9",
106: "Multiply",
107: "Add",
109: "Subtract",
110: "Decimal",
111: "Divide",
112: "F1",
113: "F2",
114: "F3",
115: "F4",
116: "F5",
117: "F6",
118: "F7",
119: "F8",
120: "F9",
121: "F10",
122: "F11",
123: "F12",
124: "F13",
125: "F14",
126: "F15",
127: "F16",
128: "F17",
129: "F18",
130: "F19",
131: "F20",
132: "F21",
133: "F22",
134: "F23",
135: "F24",
59: ";",
61: "=",
186: ";",
187: "=",
188: ",",
190: ".",
191: "/",
192: "`",
219: "[",
220: "\\",
221: "]",
222: "'"
};
Hotkeys.aliases = {
"escape": "esc",
"delete": "del",
"return": "enter",
"ctrl": "control",
"space": "spacebar",
"ins": "insert",
"cmd": "meta",
"command": "meta",
"wins": "meta",
"windows": "meta"
};
Hotkeys.normalize = function(shortcut) {
var i, j, key, keyname, keys, len;
keys = shortcut.toLowerCase().replace(/\s+/gi, "").split("+");
for (i = j = 0, len = keys.length; j < len; i = ++j) {
key = keys[i];
keys[i] = this.aliases[key] || key;
}
keyname = keys.pop();
keys.sort().push(keyname);
return keys.join("_");
};
Hotkeys.prototype.opts = {
el: document
};
Hotkeys.prototype._init = function() {
this.id = ++this.constructor.count;
this._map = {};
this._delegate = typeof this.opts.el === "string" ? document : this.opts.el;
return $(this._delegate).on("keydown.simple-hotkeys-" + this.id, this.opts.el, (function(_this) {
return function(e) {
var ref;
return (ref = _this._getHander(e)) != null ? ref.call(_this, e) : void 0;
};
})(this));
};
Hotkeys.prototype._getHander = function(e) {
var keyname, shortcut;
if (!(keyname = this.constructor.keyNameMap[e.which])) {
return;
}
shortcut = "";
if (e.altKey) {
shortcut += "alt_";
}
if (e.ctrlKey) {
shortcut += "control_";
}
if (e.metaKey) {
shortcut += "meta_";
}
if (e.shiftKey) {
shortcut += "shift_";
}
shortcut += keyname.toLowerCase();
return this._map[shortcut];
};
Hotkeys.prototype.respondTo = function(subject) {
if (typeof subject === 'string') {
return this._map[this.constructor.normalize(subject)] != null;
} else {
return this._getHander(subject) != null;
}
};
Hotkeys.prototype.add = function(shortcut, handler) {
this._map[this.constructor.normalize(shortcut)] = handler;
return this;
};
Hotkeys.prototype.remove = function(shortcut) {
delete this._map[this.constructor.normalize(shortcut)];
return this;
};
Hotkeys.prototype.destroy = function() {
$(this._delegate).off(".simple-hotkeys-" + this.id);
this._map = {};
return this;
};
return Hotkeys;
})(SimpleModule);
hotkeys = function(opts) {
return new Hotkeys(opts);
};
return hotkeys;
}));
... ...
(function (root, factory) {
if (typeof define === 'function' && define.amd) {
// AMD. Register as an anonymous module unless amdModuleId is set
define('simple-module', ["jquery"], function (a0) {
return (root['Module'] = factory(a0));
});
} else if (typeof exports === 'object') {
// Node. Does not work with strict CommonJS, but
// only CommonJS-like environments that support module.exports,
// like Node.
module.exports = factory(require("jquery"));
} else {
root['SimpleModule'] = factory(jQuery);
}
}(this, function ($) {
var Module,
slice = [].slice;
Module = (function() {
Module.extend = function(obj) {
var key, ref, val;
if (!((obj != null) && typeof obj === 'object')) {
return;
}
for (key in obj) {
val = obj[key];
if (key !== 'included' && key !== 'extended') {
this[key] = val;
}
}
return (ref = obj.extended) != null ? ref.call(this) : void 0;
};
Module.include = function(obj) {
var key, ref, val;
if (!((obj != null) && typeof obj === 'object')) {
return;
}
for (key in obj) {
val = obj[key];
if (key !== 'included' && key !== 'extended') {
this.prototype[key] = val;
}
}
return (ref = obj.included) != null ? ref.call(this) : void 0;
};
Module.connect = function(cls) {
if (typeof cls !== 'function') {
return;
}
if (!cls.pluginName) {
throw new Error('Module.connect: cannot connect plugin without pluginName');
return;
}
cls.prototype._connected = true;
if (!this._connectedClasses) {
this._connectedClasses = [];
}
this._connectedClasses.push(cls);
if (cls.pluginName) {
return this[cls.pluginName] = cls;
}
};
Module.prototype.opts = {};
function Module(opts) {
var base, cls, i, instance, instances, len, name;
this.opts = $.extend({}, this.opts, opts);
(base = this.constructor)._connectedClasses || (base._connectedClasses = []);
instances = (function() {
var i, len, ref, results;
ref = this.constructor._connectedClasses;
results = [];
for (i = 0, len = ref.length; i < len; i++) {
cls = ref[i];
name = cls.pluginName.charAt(0).toLowerCase() + cls.pluginName.slice(1);
if (cls.prototype._connected) {
cls.prototype._module = this;
}
results.push(this[name] = new cls());
}
return results;
}).call(this);
if (this._connected) {
this.opts = $.extend({}, this.opts, this._module.opts);
} else {
this._init();
for (i = 0, len = instances.length; i < len; i++) {
instance = instances[i];
if (typeof instance._init === "function") {
instance._init();
}
}
}
this.trigger('initialized');
}
Module.prototype._init = function() {};
Module.prototype.on = function() {
var args, ref;
args = 1 <= arguments.length ? slice.call(arguments, 0) : [];
(ref = $(this)).on.apply(ref, args);
return this;
};
Module.prototype.one = function() {
var args, ref;
args = 1 <= arguments.length ? slice.call(arguments, 0) : [];
(ref = $(this)).one.apply(ref, args);
return this;
};
Module.prototype.off = function() {
var args, ref;
args = 1 <= arguments.length ? slice.call(arguments, 0) : [];
(ref = $(this)).off.apply(ref, args);
return this;
};
Module.prototype.trigger = function() {
var args, ref;
args = 1 <= arguments.length ? slice.call(arguments, 0) : [];
(ref = $(this)).trigger.apply(ref, args);
return this;
};
Module.prototype.triggerHandler = function() {
var args, ref;
args = 1 <= arguments.length ? slice.call(arguments, 0) : [];
return (ref = $(this)).triggerHandler.apply(ref, args);
};
Module.prototype._t = function() {
var args, ref;
args = 1 <= arguments.length ? slice.call(arguments, 0) : [];
return (ref = this.constructor)._t.apply(ref, args);
};
Module._t = function() {
var args, key, ref, result;
key = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : [];
result = ((ref = this.i18n[this.locale]) != null ? ref[key] : void 0) || '';
if (!(args.length > 0)) {
return result;
}
result = result.replace(/([^%]|^)%(?:(\d+)\$)?s/g, function(p0, p, position) {
if (position) {
return p + args[parseInt(position) - 1];
} else {
return p + args.shift();
}
});
return result.replace(/%%s/g, '%s');
};
Module.i18n = {
'zh-CN': {}
};
Module.locale = 'zh-CN';
return Module;
})();
return Module;
}));
... ...
此 diff 太大无法显示。
(function (root, factory) {
if (typeof define === 'function' && define.amd) {
// AMD. Register as an anonymous module unless amdModuleId is set
define('simple-uploader', ["jquery","simple-module"], function ($, SimpleModule) {
return (root['uploader'] = factory($, SimpleModule));
});
} else if (typeof exports === 'object') {
// Node. Does not work with strict CommonJS, but
// only CommonJS-like environments that support module.exports,
// like Node.
module.exports = factory(require("jquery"),require("simple-module"));
} else {
root.simple = root.simple || {};
root.simple['uploader'] = factory(jQuery,SimpleModule);
}
}(this, function ($, SimpleModule) {
var Uploader, uploader,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
Uploader = (function(superClass) {
extend(Uploader, superClass);
function Uploader() {
return Uploader.__super__.constructor.apply(this, arguments);
}
Uploader.count = 0;
Uploader.prototype.opts = {
url: '',
params: null,
fileKey: 'upload_file',
connectionCount: 3
};
Uploader.prototype._init = function() {
this.files = [];
this.queue = [];
this.id = ++Uploader.count;
this.on('uploadcomplete', (function(_this) {
return function(e, file) {
_this.files.splice($.inArray(file, _this.files), 1);
if (_this.queue.length > 0 && _this.files.length < _this.opts.connectionCount) {
return _this.upload(_this.queue.shift());
} else if (_this.files.length === 0) {
return _this.uploading = false;
}
};
})(this));
return $(window).on('beforeunload.uploader-' + this.id, (function(_this) {
return function(e) {
if (!_this.uploading) {
return;
}
e.originalEvent.returnValue = _this._t('leaveConfirm');
return _this._t('leaveConfirm');
};
})(this));
};
Uploader.prototype.generateId = (function() {
var id;
id = 0;
return function() {
return id += 1;
};
})();
Uploader.prototype.upload = function(file, opts) {
var f, i, key, len;
if (opts == null) {
opts = {};
}
if (file == null) {
return;
}
if ($.isArray(file) || file instanceof FileList) {
for (i = 0, len = file.length; i < len; i++) {
f = file[i];
this.upload(f, opts);
}
} else if ($(file).is('input:file')) {
key = $(file).attr('name');
if (key) {
opts.fileKey = key;
}
this.upload($.makeArray($(file)[0].files), opts);
} else if (!file.id || !file.obj) {
file = this.getFile(file);
}
if (!(file && file.obj)) {
return;
}
$.extend(file, opts);
if (this.files.length >= this.opts.connectionCount) {
this.queue.push(file);
return;
}
if (this.triggerHandler('beforeupload', [file]) === false) {
return;
}
this.files.push(file);
this._xhrUpload(file);
return this.uploading = true;
};
Uploader.prototype.getFile = function(fileObj) {
var name, ref, ref1;
if (fileObj instanceof window.File || fileObj instanceof window.Blob) {
name = (ref = fileObj.fileName) != null ? ref : fileObj.name;
} else {
return null;
}
return {
id: this.generateId(),
url: this.opts.url,
params: this.opts.params,
fileKey: this.opts.fileKey,
name: name,
size: (ref1 = fileObj.fileSize) != null ? ref1 : fileObj.size,
ext: name ? name.split('.').pop().toLowerCase() : '',
obj: fileObj
};
};
Uploader.prototype._xhrUpload = function(file) {
var formData, k, ref, v;
formData = new FormData();
formData.append(file.fileKey, file.obj);
formData.append("original_filename", file.name);
if (file.params) {
ref = file.params;
for (k in ref) {
v = ref[k];
formData.append(k, v);
}
}
return file.xhr = $.ajax({
url: file.url,
data: formData,
processData: false,
contentType: false,
type: 'POST',
headers: {
'X-File-Name': encodeURIComponent(file.name)
},
xhr: function() {
var req;
req = $.ajaxSettings.xhr();
if (req) {
req.upload.onprogress = (function(_this) {
return function(e) {
return _this.progress(e);
};
})(this);
}
return req;
},
progress: (function(_this) {
return function(e) {
if (!e.lengthComputable) {
return;
}
return _this.trigger('uploadprogress', [file, e.loaded, e.total]);
};
})(this),
error: (function(_this) {
return function(xhr, status, err) {
return _this.trigger('uploaderror', [file, xhr, status]);
};
})(this),
success: (function(_this) {
return function(result) {
_this.trigger('uploadprogress', [file, file.size, file.size]);
_this.trigger('uploadsuccess', [file, result]);
return $(document).trigger('uploadsuccess', [file, result, _this]);
};
})(this),
complete: (function(_this) {
return function(xhr, status) {
return _this.trigger('uploadcomplete', [file, xhr.responseText]);
};
})(this)
});
};
Uploader.prototype.cancel = function(file) {
var f, i, len, ref;
if (!file.id) {
ref = this.files;
for (i = 0, len = ref.length; i < len; i++) {
f = ref[i];
if (f.id === file * 1) {
file = f;
break;
}
}
}
this.trigger('uploadcancel', [file]);
if (file.xhr) {
file.xhr.abort();
}
return file.xhr = null;
};
Uploader.prototype.readImageFile = function(fileObj, callback) {
var fileReader, img;
if (!$.isFunction(callback)) {
return;
}
img = new Image();
img.onload = function() {
return callback(img);
};
img.onerror = function() {
return callback();
};
if (window.FileReader && FileReader.prototype.readAsDataURL && /^image/.test(fileObj.type)) {
fileReader = new FileReader();
fileReader.onload = function(e) {
return img.src = e.target.result;
};
return fileReader.readAsDataURL(fileObj);
} else {
return callback();
}
};
Uploader.prototype.destroy = function() {
var file, i, len, ref;
this.queue.length = 0;
ref = this.files;
for (i = 0, len = ref.length; i < len; i++) {
file = ref[i];
this.cancel(file);
}
$(window).off('.uploader-' + this.id);
return $(document).off('.uploader-' + this.id);
};
Uploader.i18n = {
'zh-CN': {
leaveConfirm: '正在上传文件,如果离开上传会自动取消'
}
};
Uploader.locale = 'zh-CN';
return Uploader;
})(SimpleModule);
uploader = function(opts) {
return new Uploader(opts);
};
return uploader;
}));
... ...
deny from all
\ No newline at end of file
... ...
<?php
namespace app\admin\behavior;
class AdminLog
{
public function run(&$params)
{
if (request()->isPost()) {
\app\admin\model\AdminLog::record();
}
}
}
... ...