正在显示
57 个修改的文件
包含
4707 行增加
和
0 行删除
.bowerrc
0 → 100755
.env.sample
0 → 100755
.gitignore
0 → 100755
1 | +/nbproject/ | ||
2 | +/runtime/* | ||
3 | +/public/uploads/* | ||
4 | +.idea | ||
5 | +composer.lock | ||
6 | +*.log | ||
7 | +*.css.map | ||
8 | +!.gitkeep | ||
9 | +.env | ||
10 | +/application/database.php | ||
11 | +.svn | ||
12 | +.vscode | ||
13 | +node_modules | ||
14 | +public/.htaccess | ||
15 | +public/.user.ini | ||
16 | +public/nginx.htaccess | ||
17 | +.htaccess | ||
18 | +public/.well-known/ | ||
19 | +public/ccc.txt | ||
20 | +public/kevin_face_check.log |
LICENSE
0 → 100755
1 | +Apache License | ||
2 | +Version 2.0, January 2004 | ||
3 | +http://www.apache.org/licenses/ | ||
4 | + | ||
5 | +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION | ||
6 | + | ||
7 | +1. Definitions. | ||
8 | + | ||
9 | +"License" shall mean the terms and conditions for use, reproduction, and | ||
10 | +distribution as defined by Sections 1 through 9 of this document. | ||
11 | + | ||
12 | +"Licensor" shall mean the copyright owner or entity authorized by the copyright | ||
13 | +owner that is granting the License. | ||
14 | + | ||
15 | +"Legal Entity" shall mean the union of the acting entity and all other entities | ||
16 | +that control, are controlled by, or are under common control with that entity. | ||
17 | +For the purposes of this definition, "control" means (i) the power, direct or | ||
18 | +indirect, to cause the direction or management of such entity, whether by | ||
19 | +contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the | ||
20 | +outstanding shares, or (iii) beneficial ownership of such entity. | ||
21 | + | ||
22 | +"You" (or "Your") shall mean an individual or Legal Entity exercising | ||
23 | +permissions granted by this License. | ||
24 | + | ||
25 | +"Source" form shall mean the preferred form for making modifications, including | ||
26 | +but not limited to software source code, documentation source, and configuration | ||
27 | +files. | ||
28 | + | ||
29 | +"Object" form shall mean any form resulting from mechanical transformation or | ||
30 | +translation of a Source form, including but not limited to compiled object code, | ||
31 | +generated documentation, and conversions to other media types. | ||
32 | + | ||
33 | +"Work" shall mean the work of authorship, whether in Source or Object form, made | ||
34 | +available under the License, as indicated by a copyright notice that is included | ||
35 | +in or attached to the work (an example is provided in the Appendix below). | ||
36 | + | ||
37 | +"Derivative Works" shall mean any work, whether in Source or Object form, that | ||
38 | +is based on (or derived from) the Work and for which the editorial revisions, | ||
39 | +annotations, elaborations, or other modifications represent, as a whole, an | ||
40 | +original work of authorship. For the purposes of this License, Derivative Works | ||
41 | +shall not include works that remain separable from, or merely link (or bind by | ||
42 | +name) to the interfaces of, the Work and Derivative Works thereof. | ||
43 | + | ||
44 | +"Contribution" shall mean any work of authorship, including the original version | ||
45 | +of the Work and any modifications or additions to that Work or Derivative Works | ||
46 | +thereof, that is intentionally submitted to Licensor for inclusion in the Work | ||
47 | +by the copyright owner or by an individual or Legal Entity authorized to submit | ||
48 | +on behalf of the copyright owner. For the purposes of this definition, | ||
49 | +"submitted" means any form of electronic, verbal, or written communication sent | ||
50 | +to the Licensor or its representatives, including but not limited to | ||
51 | +communication on electronic mailing lists, source code control systems, and | ||
52 | +issue tracking systems that are managed by, or on behalf of, the Licensor for | ||
53 | +the purpose of discussing and improving the Work, but excluding communication | ||
54 | +that is conspicuously marked or otherwise designated in writing by the copyright | ||
55 | +owner as "Not a Contribution." | ||
56 | + | ||
57 | +"Contributor" shall mean Licensor and any individual or Legal Entity on behalf | ||
58 | +of whom a Contribution has been received by Licensor and subsequently | ||
59 | +incorporated within the Work. | ||
60 | + | ||
61 | +2. Grant of Copyright License. | ||
62 | + | ||
63 | +Subject to the terms and conditions of this License, each Contributor hereby | ||
64 | +grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, | ||
65 | +irrevocable copyright license to reproduce, prepare Derivative Works of, | ||
66 | +publicly display, publicly perform, sublicense, and distribute the Work and such | ||
67 | +Derivative Works in Source or Object form. | ||
68 | + | ||
69 | +3. Grant of Patent License. | ||
70 | + | ||
71 | +Subject to the terms and conditions of this License, each Contributor hereby | ||
72 | +grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, | ||
73 | +irrevocable (except as stated in this section) patent license to make, have | ||
74 | +made, use, offer to sell, sell, import, and otherwise transfer the Work, where | ||
75 | +such license applies only to those patent claims licensable by such Contributor | ||
76 | +that are necessarily infringed by their Contribution(s) alone or by combination | ||
77 | +of their Contribution(s) with the Work to which such Contribution(s) was | ||
78 | +submitted. If You institute patent litigation against any entity (including a | ||
79 | +cross-claim or counterclaim in a lawsuit) alleging that the Work or a | ||
80 | +Contribution incorporated within the Work constitutes direct or contributory | ||
81 | +patent infringement, then any patent licenses granted to You under this License | ||
82 | +for that Work shall terminate as of the date such litigation is filed. | ||
83 | + | ||
84 | +4. Redistribution. | ||
85 | + | ||
86 | +You may reproduce and distribute copies of the Work or Derivative Works thereof | ||
87 | +in any medium, with or without modifications, and in Source or Object form, | ||
88 | +provided that You meet the following conditions: | ||
89 | + | ||
90 | +You must give any other recipients of the Work or Derivative Works a copy of | ||
91 | +this License; and | ||
92 | +You must cause any modified files to carry prominent notices stating that You | ||
93 | +changed the files; and | ||
94 | +You must retain, in the Source form of any Derivative Works that You distribute, | ||
95 | +all copyright, patent, trademark, and attribution notices from the Source form | ||
96 | +of the Work, excluding those notices that do not pertain to any part of the | ||
97 | +Derivative Works; and | ||
98 | +If the Work includes a "NOTICE" text file as part of its distribution, then any | ||
99 | +Derivative Works that You distribute must include a readable copy of the | ||
100 | +attribution notices contained within such NOTICE file, excluding those notices | ||
101 | +that do not pertain to any part of the Derivative Works, in at least one of the | ||
102 | +following places: within a NOTICE text file distributed as part of the | ||
103 | +Derivative Works; within the Source form or documentation, if provided along | ||
104 | +with the Derivative Works; or, within a display generated by the Derivative | ||
105 | +Works, if and wherever such third-party notices normally appear. The contents of | ||
106 | +the NOTICE file are for informational purposes only and do not modify the | ||
107 | +License. You may add Your own attribution notices within Derivative Works that | ||
108 | +You distribute, alongside or as an addendum to the NOTICE text from the Work, | ||
109 | +provided that such additional attribution notices cannot be construed as | ||
110 | +modifying the License. | ||
111 | +You may add Your own copyright statement to Your modifications and may provide | ||
112 | +additional or different license terms and conditions for use, reproduction, or | ||
113 | +distribution of Your modifications, or for any such Derivative Works as a whole, | ||
114 | +provided Your use, reproduction, and distribution of the Work otherwise complies | ||
115 | +with the conditions stated in this License. | ||
116 | + | ||
117 | +5. Submission of Contributions. | ||
118 | + | ||
119 | +Unless You explicitly state otherwise, any Contribution intentionally submitted | ||
120 | +for inclusion in the Work by You to the Licensor shall be under the terms and | ||
121 | +conditions of this License, without any additional terms or conditions. | ||
122 | +Notwithstanding the above, nothing herein shall supersede or modify the terms of | ||
123 | +any separate license agreement you may have executed with Licensor regarding | ||
124 | +such Contributions. | ||
125 | + | ||
126 | +6. Trademarks. | ||
127 | + | ||
128 | +This License does not grant permission to use the trade names, trademarks, | ||
129 | +service marks, or product names of the Licensor, except as required for | ||
130 | +reasonable and customary use in describing the origin of the Work and | ||
131 | +reproducing the content of the NOTICE file. | ||
132 | + | ||
133 | +7. Disclaimer of Warranty. | ||
134 | + | ||
135 | +Unless required by applicable law or agreed to in writing, Licensor provides the | ||
136 | +Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, | ||
137 | +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, | ||
138 | +including, without limitation, any warranties or conditions of TITLE, | ||
139 | +NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are | ||
140 | +solely responsible for determining the appropriateness of using or | ||
141 | +redistributing the Work and assume any risks associated with Your exercise of | ||
142 | +permissions under this License. | ||
143 | + | ||
144 | +8. Limitation of Liability. | ||
145 | + | ||
146 | +In no event and under no legal theory, whether in tort (including negligence), | ||
147 | +contract, or otherwise, unless required by applicable law (such as deliberate | ||
148 | +and grossly negligent acts) or agreed to in writing, shall any Contributor be | ||
149 | +liable to You for damages, including any direct, indirect, special, incidental, | ||
150 | +or consequential damages of any character arising as a result of this License or | ||
151 | +out of the use or inability to use the Work (including but not limited to | ||
152 | +damages for loss of goodwill, work stoppage, computer failure or malfunction, or | ||
153 | +any and all other commercial damages or losses), even if such Contributor has | ||
154 | +been advised of the possibility of such damages. | ||
155 | + | ||
156 | +9. Accepting Warranty or Additional Liability. | ||
157 | + | ||
158 | +While redistributing the Work or Derivative Works thereof, You may choose to | ||
159 | +offer, and charge a fee for, acceptance of support, warranty, indemnity, or | ||
160 | +other liability obligations and/or rights consistent with this License. However, | ||
161 | +in accepting such obligations, You may act only on Your own behalf and on Your | ||
162 | +sole responsibility, not on behalf of any other Contributor, and only if You | ||
163 | +agree to indemnify, defend, and hold each Contributor harmless for any liability | ||
164 | +incurred by, or claims asserted against, such Contributor by reason of your | ||
165 | +accepting any such warranty or additional liability. | ||
166 | + | ||
167 | +END OF TERMS AND CONDITIONS | ||
168 | + | ||
169 | +APPENDIX: How to apply the Apache License to your work | ||
170 | + | ||
171 | +To apply the Apache License to your work, attach the following boilerplate | ||
172 | +notice, with the fields enclosed by brackets "{}" replaced with your own | ||
173 | +identifying information. (Don't include the brackets!) The text should be | ||
174 | +enclosed in the appropriate comment syntax for the file format. We also | ||
175 | +recommend that a file or class name and description of purpose be included on | ||
176 | +the same "printed page" as the copyright notice for easier identification within | ||
177 | +third-party archives. | ||
178 | + | ||
179 | + Copyright 2017 Karson | ||
180 | + | ||
181 | + Licensed under the Apache License, Version 2.0 (the "License"); | ||
182 | + you may not use this file except in compliance with the License. | ||
183 | + You may obtain a copy of the License at | ||
184 | + | ||
185 | + http://www.apache.org/licenses/LICENSE-2.0 | ||
186 | + | ||
187 | + Unless required by applicable law or agreed to in writing, software | ||
188 | + distributed under the License is distributed on an "AS IS" BASIS, | ||
189 | + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
190 | + See the License for the specific language governing permissions and | ||
191 | + limitations under the License. |
README.md
0 → 100755
1 | +FastAdmin是一款基于ThinkPHP+Bootstrap的极速后台开发框架。 | ||
2 | + | ||
3 | + | ||
4 | +## 主要特性 | ||
5 | + | ||
6 | +* 基于`Auth`验证的权限管理系统 | ||
7 | + * 支持无限级父子级权限继承,父级的管理员可任意增删改子级管理员及权限设置 | ||
8 | + * 支持单管理员多角色 | ||
9 | + * 支持管理子级数据或个人数据 | ||
10 | +* 强大的一键生成功能 | ||
11 | + * 一键生成CRUD,包括控制器、模型、视图、JS、语言包、菜单、回收站等 | ||
12 | + * 一键压缩打包JS和CSS文件,一键CDN静态资源部署 | ||
13 | + * 一键生成控制器菜单和规则 | ||
14 | + * 一键生成API接口文档 | ||
15 | +* 完善的前端功能组件开发 | ||
16 | + * 基于`AdminLTE`二次开发 | ||
17 | + * 基于`Bootstrap`开发,自适应手机、平板、PC | ||
18 | + * 基于`RequireJS`进行JS模块管理,按需加载 | ||
19 | + * 基于`Less`进行样式开发 | ||
20 | +* 强大的插件扩展功能,在线安装卸载升级插件 | ||
21 | +* 通用的会员模块和API模块 | ||
22 | +* 共用同一账号体系的Web端会员中心权限验证和API接口会员权限验证 | ||
23 | +* 二级域名部署支持,同时域名支持绑定到应用插件 | ||
24 | +* 多语言支持,服务端及客户端支持 | ||
25 | +* 支持大文件分片上传、剪切板粘贴上传、拖拽上传,进度条显示,图片上传前压缩 | ||
26 | +* 支持表格固定列、固定表头、跨页选择、Excel导出、模板渲染等功能 | ||
27 | +* 强大的第三方应用模块支持([CMS](https://www.fastadmin.net/store/cms.html)、[博客](https://www.fastadmin.net/store/blog.html)、[知识付费问答](https://www.fastadmin.net/store/ask.html)、[在线投票系统](https://www.fastadmin.net/store/vote.html)、[B2C商城](https://www.fastadmin.net/store/shopro.html)、[B2B2C商城](https://www.fastadmin.net/store/wanlshop.html)) | ||
28 | +* 支持CMS、博客、知识付费问答无缝整合[Xunsearch全文搜索](https://www.fastadmin.net/store/xunsearch.html) | ||
29 | +* 第三方小程序支持([CMS小程序](https://www.fastadmin.net/store/cms.html)、[预订小程序](https://www.fastadmin.net/store/ball.html)、[问答小程序](https://www.fastadmin.net/store/ask.html)、[点餐小程序](https://www.fastadmin.net/store/unidrink.html)、[B2C小程序](https://www.fastadmin.net/store/shopro.html)、[B2B2C小程序](https://www.fastadmin.net/store/wanlshop.html)、[博客小程序](https://www.fastadmin.net/store/blog.html)) | ||
30 | +* 整合第三方短信接口(阿里云、腾讯云短信) | ||
31 | +* 无缝整合第三方云存储(七牛云、阿里云OSS、又拍云)功能,支持云储存分片上传 | ||
32 | +* 第三方富文本编辑器支持(Summernote、Kindeditor、百度编辑器) | ||
33 | +* 第三方登录(QQ、微信、微博)整合 | ||
34 | +* 第三方支付(微信、支付宝)无缝整合,微信支持PC端扫码支付 | ||
35 | +* 丰富的插件应用市场 | ||
36 | + | ||
37 | +## 安装使用 | ||
38 | + | ||
39 | +https://doc.fastadmin.net | ||
40 | + | ||
41 | +## 在线演示 | ||
42 | + | ||
43 | +https://demo.fastadmin.net | ||
44 | + | ||
45 | +用户名:admin | ||
46 | + | ||
47 | +密 码:123456 | ||
48 | + | ||
49 | +提 示:演示站数据无法进行修改,请下载源码安装体验全部功能 | ||
50 | + | ||
51 | +## 界面截图 | ||
52 | + | ||
53 | + | ||
54 | +## 问题反馈 | ||
55 | + | ||
56 | +在使用中有任何问题,请使用以下联系方式联系我们 | ||
57 | + | ||
58 | +交流社区: https://ask.fastadmin.net | ||
59 | + | ||
60 | +QQ 1 群(满)、QQ 2 群(满)、QQ 3 群(满)、QQ 4 群(满)、QQ 5 群(满)、QQ 6 群(满)、[QQ 7 群](https://www.fastadmin.net/goto/qun)。 | ||
61 | + | ||
62 | +Github: https://github.com/karsonzhang/fastadmin | ||
63 | + | ||
64 | +Gitee: https://gitee.com/karson/fastadmin | ||
65 | + | ||
66 | +## 特别鸣谢 | ||
67 | + | ||
68 | +感谢以下的项目,排名不分先后 | ||
69 | + | ||
70 | +ThinkPHP:http://www.thinkphp.cn | ||
71 | + | ||
72 | +AdminLTE:https://adminlte.io | ||
73 | + | ||
74 | +Bootstrap:http://getbootstrap.com | ||
75 | + | ||
76 | +jQuery:http://jquery.com | ||
77 | + | ||
78 | +Bootstrap-table:https://github.com/wenzhixin/bootstrap-table | ||
79 | + | ||
80 | +Nice-validator: https://validator.niceue.com | ||
81 | + | ||
82 | +SelectPage: https://github.com/TerryZ/SelectPage | ||
83 | + | ||
84 | +Layer: https://layuion.com/layer/ | ||
85 | + | ||
86 | +DropzoneJS: https://www.dropzonejs.com | ||
87 | + | ||
88 | + | ||
89 | +## 版权信息 | ||
90 | + | ||
91 | +FastAdmin遵循Apache2开源协议发布,并提供免费使用。 | ||
92 | + | ||
93 | +本项目包含的第三方源码和二进制文件之版权信息另行标注。 | ||
94 | + | ||
95 | +版权所有Copyright © 2017-2022 by FastAdmin (https://www.fastadmin.net) | ||
96 | + | ||
97 | +All rights reserved。 |
addons/.gitkeep
0 → 100755
1 | + |
addons/address/.addonrc
0 → 100755
1 | +{"files":[],"license":"regular","licenseto":"15629","licensekey":"38jTdqf4pm6XoSwz mqjMxWqQU9Je1XcOZtI6Yg==","domains":["cardverification.com"],"licensecodes":[],"validations":["867a7ee97b89c3a1f31235c70da23ecf"]} |
addons/address/Address.php
0 → 100755
1 | +<?php | ||
2 | + | ||
3 | +namespace addons\address; | ||
4 | + | ||
5 | +use think\Addons; | ||
6 | + | ||
7 | +/** | ||
8 | + * 地址选择 | ||
9 | + * @author [MiniLing] <[laozheyouxiang@163.com]> | ||
10 | + */ | ||
11 | +class Address extends Addons | ||
12 | +{ | ||
13 | + | ||
14 | + /** | ||
15 | + * 插件安装方法 | ||
16 | + * @return bool | ||
17 | + */ | ||
18 | + public function install() | ||
19 | + { | ||
20 | + return true; | ||
21 | + } | ||
22 | + | ||
23 | + /** | ||
24 | + * 插件卸载方法 | ||
25 | + * @return bool | ||
26 | + */ | ||
27 | + public function uninstall() | ||
28 | + { | ||
29 | + return true; | ||
30 | + } | ||
31 | + | ||
32 | +} |
addons/address/bootstrap.js
0 → 100755
1 | +require([], function () { | ||
2 | + //绑定data-toggle=addresspicker属性点击事件 | ||
3 | + | ||
4 | + $(document).on('click', "[data-toggle='addresspicker']", function () { | ||
5 | + var that = this; | ||
6 | + var callback = $(that).data('callback'); | ||
7 | + var input_id = $(that).data("input-id") ? $(that).data("input-id") : ""; | ||
8 | + var lat_id = $(that).data("lat-id") ? $(that).data("lat-id") : ""; | ||
9 | + var lng_id = $(that).data("lng-id") ? $(that).data("lng-id") : ""; | ||
10 | + var lat = lat_id ? $("#" + lat_id).val() : ''; | ||
11 | + var lng = lng_id ? $("#" + lng_id).val() : ''; | ||
12 | + var url = "/addons/address/index/select"; | ||
13 | + url += (lat && lng) ? '?lat=' + lat + '&lng=' + lng : ''; | ||
14 | + Fast.api.open(url, '位置选择', { | ||
15 | + callback: function (res) { | ||
16 | + input_id && $("#" + input_id).val(res.address).trigger("change"); | ||
17 | + lat_id && $("#" + lat_id).val(res.lat).trigger("change"); | ||
18 | + lng_id && $("#" + lng_id).val(res.lng).trigger("change"); | ||
19 | + try { | ||
20 | + //执行回调函数 | ||
21 | + if (typeof callback === 'function') { | ||
22 | + callback.call(that, res); | ||
23 | + } | ||
24 | + } catch (e) { | ||
25 | + | ||
26 | + } | ||
27 | + } | ||
28 | + }); | ||
29 | + }); | ||
30 | +}); |
addons/address/config.php
0 → 100755
1 | +<?php | ||
2 | + | ||
3 | +return [ | ||
4 | + [ | ||
5 | + 'name' => 'maptype', | ||
6 | + 'title' => '默认地图类型', | ||
7 | + 'type' => 'radio', | ||
8 | + 'content' => [ | ||
9 | + 'baidu' => '百度地图', | ||
10 | + 'amap' => '高德地图', | ||
11 | + 'tencent' => '腾讯地图', | ||
12 | + ], | ||
13 | + 'value' => 'tencent', | ||
14 | + 'rule' => 'required', | ||
15 | + 'msg' => '', | ||
16 | + 'tip' => '', | ||
17 | + 'ok' => '', | ||
18 | + 'extend' => '', | ||
19 | + ], | ||
20 | + [ | ||
21 | + 'name' => 'zoom', | ||
22 | + 'title' => '默认缩放级别', | ||
23 | + 'type' => 'string', | ||
24 | + 'content' => [], | ||
25 | + 'value' => '11', | ||
26 | + 'rule' => 'required', | ||
27 | + 'msg' => '', | ||
28 | + 'tip' => '', | ||
29 | + 'ok' => '', | ||
30 | + 'extend' => '', | ||
31 | + ], | ||
32 | + [ | ||
33 | + 'name' => 'lat', | ||
34 | + 'title' => '默认Lat', | ||
35 | + 'type' => 'string', | ||
36 | + 'content' => [], | ||
37 | + 'value' => '39.919990', | ||
38 | + 'rule' => 'required', | ||
39 | + 'msg' => '', | ||
40 | + 'tip' => '', | ||
41 | + 'ok' => '', | ||
42 | + 'extend' => '', | ||
43 | + ], | ||
44 | + [ | ||
45 | + 'name' => 'lng', | ||
46 | + 'title' => '默认Lng', | ||
47 | + 'type' => 'string', | ||
48 | + 'content' => [], | ||
49 | + 'value' => '116.456270', | ||
50 | + 'rule' => 'required', | ||
51 | + 'msg' => '', | ||
52 | + 'tip' => '', | ||
53 | + 'ok' => '', | ||
54 | + 'extend' => '', | ||
55 | + ], | ||
56 | + [ | ||
57 | + 'name' => 'baidukey', | ||
58 | + 'title' => '百度地图KEY', | ||
59 | + 'type' => 'string', | ||
60 | + 'content' => [], | ||
61 | + 'value' => '', | ||
62 | + 'rule' => '', | ||
63 | + 'msg' => '', | ||
64 | + 'tip' => '', | ||
65 | + 'ok' => '', | ||
66 | + 'extend' => '', | ||
67 | + ], | ||
68 | + [ | ||
69 | + 'name' => 'amapkey', | ||
70 | + 'title' => '高德地图KEY', | ||
71 | + 'type' => 'string', | ||
72 | + 'content' => [], | ||
73 | + 'value' => '', | ||
74 | + 'rule' => '', | ||
75 | + 'msg' => '', | ||
76 | + 'tip' => '', | ||
77 | + 'ok' => '', | ||
78 | + 'extend' => '', | ||
79 | + ], | ||
80 | + [ | ||
81 | + 'name' => 'amapsecurityjscode', | ||
82 | + 'title' => '高德地图安全密钥', | ||
83 | + 'type' => 'string', | ||
84 | + 'content' => [], | ||
85 | + 'value' => '', | ||
86 | + 'rule' => '', | ||
87 | + 'msg' => '', | ||
88 | + 'tip' => '', | ||
89 | + 'ok' => '', | ||
90 | + 'extend' => '', | ||
91 | + ], | ||
92 | + [ | ||
93 | + 'name' => 'tencentkey', | ||
94 | + 'title' => '腾讯地图KEY', | ||
95 | + 'type' => 'string', | ||
96 | + 'content' => [], | ||
97 | + 'value' => 'D4KBZ-6YNCZ-5QKXK-ZMP65-TEC7V-DTBGT', | ||
98 | + 'rule' => '', | ||
99 | + 'msg' => '', | ||
100 | + 'tip' => '', | ||
101 | + 'ok' => '', | ||
102 | + 'extend' => '', | ||
103 | + ], | ||
104 | + [ | ||
105 | + 'name' => '__tips__', | ||
106 | + 'title' => '温馨提示', | ||
107 | + 'type' => '', | ||
108 | + 'content' => [], | ||
109 | + 'value' => '请先申请对应地图的Key,配置后再使用', | ||
110 | + 'rule' => '', | ||
111 | + 'msg' => '', | ||
112 | + 'tip' => '', | ||
113 | + 'ok' => '', | ||
114 | + 'extend' => 'alert-danger-light', | ||
115 | + ], | ||
116 | +]; |
addons/address/controller/Index.php
0 → 100755
1 | +<?php | ||
2 | + | ||
3 | +namespace addons\address\controller; | ||
4 | + | ||
5 | +use think\addons\Controller; | ||
6 | +use think\Config; | ||
7 | +use think\Hook; | ||
8 | + | ||
9 | +class Index extends Controller | ||
10 | +{ | ||
11 | + | ||
12 | + // 首页 | ||
13 | + public function index() | ||
14 | + { | ||
15 | + // 语言检测 | ||
16 | + $lang = $this->request->langset(); | ||
17 | + $lang = preg_match("/^([a-zA-Z\-_]{2,10})\$/i", $lang) ? $lang : 'zh-cn'; | ||
18 | + | ||
19 | + $site = Config::get("site"); | ||
20 | + | ||
21 | + // 配置信息 | ||
22 | + $config = [ | ||
23 | + 'site' => array_intersect_key($site, array_flip(['name', 'cdnurl', 'version', 'timezone', 'languages'])), | ||
24 | + 'upload' => null, | ||
25 | + 'modulename' => 'addons', | ||
26 | + 'controllername' => 'index', | ||
27 | + 'actionname' => 'index', | ||
28 | + 'jsname' => 'addons/address', | ||
29 | + 'moduleurl' => '', | ||
30 | + 'language' => $lang | ||
31 | + ]; | ||
32 | + $config = array_merge($config, Config::get("view_replace_str")); | ||
33 | + | ||
34 | + // 配置信息后 | ||
35 | + Hook::listen("config_init", $config); | ||
36 | + // 加载当前控制器语言包 | ||
37 | + $this->view->assign('site', $site); | ||
38 | + $this->view->assign('config', $config); | ||
39 | + | ||
40 | + return $this->view->fetch(); | ||
41 | + } | ||
42 | + | ||
43 | + // 选择地址 | ||
44 | + public function select() | ||
45 | + { | ||
46 | + $config = get_addon_config('address'); | ||
47 | + $lng = $this->request->get('lng'); | ||
48 | + $lat = $this->request->get('lat'); | ||
49 | + $lng = $lng ? $lng : $config['lng']; | ||
50 | + $lat = $lat ? $lat : $config['lat']; | ||
51 | + $this->view->assign('lng', $lng); | ||
52 | + $this->view->assign('lat', $lat); | ||
53 | + $maptype = $config['maptype']; | ||
54 | + if (!isset($config[$maptype . 'key']) || !$config[$maptype . 'key']) { | ||
55 | + $this->error("请在配置中配置对应类型地图的密钥"); | ||
56 | + } | ||
57 | + return $this->view->fetch('index/' . $maptype); | ||
58 | + } | ||
59 | + | ||
60 | +} |
addons/address/info.ini
0 → 100755
addons/address/view/index/amap.html
0 → 100755
1 | +<!DOCTYPE html> | ||
2 | +<html> | ||
3 | +<head> | ||
4 | + <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"> | ||
5 | + <title>地址选择器</title> | ||
6 | + <link rel="stylesheet" href="__CDN__/assets/css/frontend.min.css"/> | ||
7 | + <link rel="stylesheet" href="__CDN__/assets/libs/font-awesome/css/font-awesome.min.css"/> | ||
8 | + <style type="text/css"> | ||
9 | + body { | ||
10 | + margin: 0; | ||
11 | + padding: 0; | ||
12 | + } | ||
13 | + | ||
14 | + #container { | ||
15 | + position: absolute; | ||
16 | + left: 0; | ||
17 | + top: 0; | ||
18 | + right: 0; | ||
19 | + bottom: 0; | ||
20 | + } | ||
21 | + | ||
22 | + .confirm { | ||
23 | + position: absolute; | ||
24 | + bottom: 30px; | ||
25 | + right: 4%; | ||
26 | + z-index: 99; | ||
27 | + height: 50px; | ||
28 | + width: 50px; | ||
29 | + line-height: 50px; | ||
30 | + font-size: 15px; | ||
31 | + text-align: center; | ||
32 | + background-color: white; | ||
33 | + background: #1ABC9C; | ||
34 | + color: white; | ||
35 | + border: none; | ||
36 | + cursor: pointer; | ||
37 | + border-radius: 50%; | ||
38 | + } | ||
39 | + | ||
40 | + .search { | ||
41 | + position: absolute; | ||
42 | + width: 400px; | ||
43 | + top: 0; | ||
44 | + left: 50%; | ||
45 | + padding: 5px; | ||
46 | + margin-left: -200px; | ||
47 | + } | ||
48 | + | ||
49 | + .amap-marker-label { | ||
50 | + border: 0; | ||
51 | + background-color: transparent; | ||
52 | + } | ||
53 | + | ||
54 | + .info { | ||
55 | + padding: .75rem 1.25rem; | ||
56 | + margin-bottom: 1rem; | ||
57 | + border-radius: .25rem; | ||
58 | + position: fixed; | ||
59 | + top: 2rem; | ||
60 | + background-color: white; | ||
61 | + width: auto; | ||
62 | + min-width: 22rem; | ||
63 | + border-width: 0; | ||
64 | + left: 1.8rem; | ||
65 | + box-shadow: 0 2px 6px 0 rgba(114, 124, 245, .5); | ||
66 | + } | ||
67 | + </style> | ||
68 | +</head> | ||
69 | +<body> | ||
70 | +<div class="search"> | ||
71 | + <div class="input-group"> | ||
72 | + <input type="text" id="place" name="q" class="form-control" placeholder="输入地点"/> | ||
73 | + <span class="input-group-btn"> | ||
74 | + <button type="submit" name="search" id="search-btn" class="btn btn-success"> | ||
75 | + <i class="fa fa-search"></i> | ||
76 | + </button> | ||
77 | + </span> | ||
78 | + </div> | ||
79 | +</div> | ||
80 | +<div class="confirm">确定</div> | ||
81 | +<div id="container"></div> | ||
82 | +<script type="text/javascript"> | ||
83 | + window._AMapSecurityConfig = { | ||
84 | + securityJsCode: "{$config.amapsecurityjscode|default=''}", | ||
85 | + } | ||
86 | +</script> | ||
87 | +<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> | ||
88 | +<!-- UI组件库 1.0 --> | ||
89 | +<script src="//webapi.amap.com/ui/1.0/main.js?v=1.0.11"></script> | ||
90 | +<script src="__CDN__/assets/libs/jquery/dist/jquery.min.js"></script> | ||
91 | +<script type="text/javascript"> | ||
92 | + $(function () { | ||
93 | + var as, address, map, lat, lng, geocoder; | ||
94 | + var init = function () { | ||
95 | + AMapUI.loadUI(['misc/PositionPicker', 'misc/PoiPicker'], function (PositionPicker, PoiPicker) { | ||
96 | + //加载PositionPicker,loadUI的路径参数为模块名中 'ui/' 之后的部分 | ||
97 | + map = new AMap.Map('container', { | ||
98 | + zoom: parseInt('{$config.zoom}') | ||
99 | + }); | ||
100 | + geocoder = new AMap.Geocoder({ | ||
101 | + radius: 1000 //范围,默认:500 | ||
102 | + }); | ||
103 | + var positionPicker = new PositionPicker({ | ||
104 | + mode: 'dragMarker',//设定为拖拽地图模式,可选'dragMap'、'dragMarker',默认为'dragMap' | ||
105 | + map: map//依赖地图对象 | ||
106 | + }); | ||
107 | + //输入提示 | ||
108 | + var autoOptions = { | ||
109 | + input: "place" | ||
110 | + }; | ||
111 | + | ||
112 | + var relocation = function (lnglat) { | ||
113 | + lng = lnglat.lng; | ||
114 | + lat = lnglat.lat; | ||
115 | + map.panTo([lng, lat]); | ||
116 | + positionPicker.start(lnglat); | ||
117 | + geocoder.getAddress(lng + ',' + lat, function (status, result) { | ||
118 | + if (status === 'complete' && result.regeocode) { | ||
119 | + var address = result.regeocode.formattedAddress; | ||
120 | + var label = '<div class="info">地址:' + address + '<br>经度:' + lng + '<br>纬度:' + lat + '</div>'; | ||
121 | + positionPicker.marker.setLabel({ | ||
122 | + content: label //显示内容 | ||
123 | + }); | ||
124 | + } else { | ||
125 | + console.log(JSON.stringify(result)); | ||
126 | + } | ||
127 | + }); | ||
128 | + }; | ||
129 | + var auto = new AMap.Autocomplete(autoOptions); | ||
130 | + | ||
131 | + //构造地点查询类 | ||
132 | + var placeSearch = new AMap.PlaceSearch({ | ||
133 | + map: map | ||
134 | + }); | ||
135 | + //注册监听,当选中某条记录时会触发 | ||
136 | + AMap.event.addListener(auto, "select", function (e) { | ||
137 | + placeSearch.setCity(e.poi.adcode); | ||
138 | + placeSearch.search(e.poi.name); //关键字查询查询 | ||
139 | + }); | ||
140 | + AMap.event.addListener(map, 'click', function (e) { | ||
141 | + relocation(e.lnglat); | ||
142 | + }); | ||
143 | + | ||
144 | + //加载工具条 | ||
145 | + var tool = new AMap.ToolBar(); | ||
146 | + map.addControl(tool); | ||
147 | + | ||
148 | + var poiPicker = new PoiPicker({ | ||
149 | + input: 'place', | ||
150 | + placeSearchOptions: { | ||
151 | + map: map, | ||
152 | + pageSize: 6 //关联搜索分页 | ||
153 | + } | ||
154 | + }); | ||
155 | + poiPicker.on('poiPicked', function (poiResult) { | ||
156 | + poiPicker.hideSearchResults(); | ||
157 | + $('.poi .nearpoi').text(poiResult.item.name); | ||
158 | + $('.address .info').text(poiResult.item.address); | ||
159 | + $('#address').val(poiResult.item.address); | ||
160 | + $("#place").val(poiResult.item.name); | ||
161 | + | ||
162 | + relocation(poiResult.item.location); | ||
163 | + }); | ||
164 | + | ||
165 | + positionPicker.on('success', function (positionResult) { | ||
166 | + as = positionResult.position; | ||
167 | + address = positionResult.address; | ||
168 | + lat = as.lat; | ||
169 | + lng = as.lng; | ||
170 | + }); | ||
171 | + positionPicker.on('fail', function (positionResult) { | ||
172 | + address = ''; | ||
173 | + }); | ||
174 | + positionPicker.start(); | ||
175 | + | ||
176 | + var defaultLng = {$lng}, defaultLat = {$lat}; | ||
177 | + if (defaultLng && defaultLat) { | ||
178 | + relocation(new AMap.LngLat(Number(defaultLng), Number(defaultLat))); | ||
179 | + } | ||
180 | + }); | ||
181 | + }; | ||
182 | + | ||
183 | + //点击确定后执行回调赋值 | ||
184 | + var close = function (data) { | ||
185 | + var index = parent.Layer.getFrameIndex(window.name); | ||
186 | + var callback = parent.$("#layui-layer" + index).data("callback"); | ||
187 | + //再执行关闭 | ||
188 | + parent.Layer.close(index); | ||
189 | + //再调用回传函数 | ||
190 | + if (typeof callback === 'function') { | ||
191 | + callback.call(undefined, data); | ||
192 | + } | ||
193 | + }; | ||
194 | + | ||
195 | + var getParam = function (name, url) { | ||
196 | + url = url || location.href; | ||
197 | + return url.match(new RegExp('[?&]' + name + '=([^?&]+)', 'i')) ? decodeURIComponent(RegExp.$1) : ''; | ||
198 | + }; | ||
199 | + | ||
200 | + //点击搜索按钮 | ||
201 | + $(document).on('click', '.confirm', function () { | ||
202 | + var zoom = map.getZoom(); | ||
203 | + var data = {lat: lat, lng: lng, zoom: zoom, address: address}; | ||
204 | + close(data); | ||
205 | + }); | ||
206 | + init(); | ||
207 | + }); | ||
208 | +</script> | ||
209 | +</body> | ||
210 | +</html> |
addons/address/view/index/baidu.html
0 → 100755
1 | +<!DOCTYPE html> | ||
2 | +<html> | ||
3 | +<head> | ||
4 | + <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"> | ||
5 | + <title>地址选择器</title> | ||
6 | + <link rel="stylesheet" href="__CDN__/assets/css/frontend.min.css"/> | ||
7 | + <link rel="stylesheet" href="__CDN__/assets/libs/font-awesome/css/font-awesome.min.css"/> | ||
8 | + <style type="text/css"> | ||
9 | + body { | ||
10 | + margin: 0; | ||
11 | + padding: 0; | ||
12 | + } | ||
13 | + | ||
14 | + #container { | ||
15 | + position: absolute; | ||
16 | + left: 0; | ||
17 | + top: 0; | ||
18 | + right: 0; | ||
19 | + bottom: 0; | ||
20 | + } | ||
21 | + | ||
22 | + .confirm { | ||
23 | + position: absolute; | ||
24 | + bottom: 30px; | ||
25 | + right: 4%; | ||
26 | + z-index: 99; | ||
27 | + height: 50px; | ||
28 | + width: 50px; | ||
29 | + line-height: 50px; | ||
30 | + font-size: 15px; | ||
31 | + text-align: center; | ||
32 | + background-color: white; | ||
33 | + background: #1ABC9C; | ||
34 | + color: white; | ||
35 | + border: none; | ||
36 | + cursor: pointer; | ||
37 | + border-radius: 50%; | ||
38 | + } | ||
39 | + | ||
40 | + .search { | ||
41 | + position: absolute; | ||
42 | + width: 400px; | ||
43 | + top: 0; | ||
44 | + left: 50%; | ||
45 | + padding: 5px; | ||
46 | + margin-left: -200px; | ||
47 | + } | ||
48 | + | ||
49 | + label.BMapLabel { | ||
50 | + max-width: inherit; | ||
51 | + padding: .75rem 1.25rem; | ||
52 | + margin-bottom: 1rem; | ||
53 | + background-color: white; | ||
54 | + width: auto; | ||
55 | + min-width: 22rem; | ||
56 | + border: none; | ||
57 | + box-shadow: 0 2px 6px 0 rgba(114, 124, 245, .5); | ||
58 | + } | ||
59 | + | ||
60 | + </style> | ||
61 | +</head> | ||
62 | +<body> | ||
63 | +<div class="search"> | ||
64 | + <div class="input-group"> | ||
65 | + <input type="text" id="place" name="q" class="form-control" placeholder="输入地点"/> | ||
66 | + <div id="searchResultPanel" style="border:1px solid #C0C0C0;width:150px;height:auto; display:none;"></div> | ||
67 | + <span class="input-group-btn"> | ||
68 | + <button type="button" name="search" id="address" class="btn btn-success"> | ||
69 | + <i class="fa fa-search"></i> | ||
70 | + </button> | ||
71 | + </span> | ||
72 | + </div> | ||
73 | +</div> | ||
74 | +<div class="confirm">确定</div> | ||
75 | +<div id="container"></div> | ||
76 | +<script type="text/javascript" src="//api.map.baidu.com/api?v=2.0&ak={$config.baidukey|default=''}"></script> | ||
77 | +<script src="__CDN__/assets/libs/jquery/dist/jquery.min.js"></script> | ||
78 | +<script type="text/javascript"> | ||
79 | + $(function () { | ||
80 | + // 百度地图API功能 | ||
81 | + function G(id) { | ||
82 | + return document.getElementById(id); | ||
83 | + } | ||
84 | + | ||
85 | + var map, marker, searchService, address = null, lng, lat; | ||
86 | + | ||
87 | + var init = function () { | ||
88 | + map = new BMap.Map("container"); // 创建地图实例 | ||
89 | + var point = new BMap.Point({$lng}, {$lat}); // 创建点坐标 | ||
90 | + map.enableScrollWheelZoom(true); //开启鼠标滚轮缩放 | ||
91 | + map.centerAndZoom(point, parseInt("{$config.zoom}")); // 初始化地图,设置中心点坐标和地图级别 | ||
92 | + | ||
93 | + var size = new BMap.Size(10, 20); | ||
94 | + map.addControl(new BMap.CityListControl({ | ||
95 | + anchor: BMAP_ANCHOR_TOP_LEFT, | ||
96 | + offset: size, | ||
97 | + })); | ||
98 | + | ||
99 | + var geoc = new BMap.Geocoder(); | ||
100 | + | ||
101 | + var addpoint = function (point) { | ||
102 | + //通过点击百度地图,可以获取到对应的point, 由point的lng、lat属性就可以获取对应的经度纬度 | ||
103 | + var pt = point; | ||
104 | + geoc.getLocation(pt, function (rs) { | ||
105 | + //对象可以获取到详细的地址信息 | ||
106 | + address = rs.address; | ||
107 | + deletePoint(); | ||
108 | + var mk = new BMap.Marker(pt); | ||
109 | + map.addOverlay(mk); | ||
110 | + map.panTo(pt); | ||
111 | + var label = new BMap.Label('<div class="info">地址:' + address + '<br>经度:' + pt.lng + '<br>纬度:' + pt.lat + '</div>', {offset: new BMap.Size(16, 20)}); | ||
112 | + label.setStyle({ | ||
113 | + border: 'none', | ||
114 | + padding: '.75rem 1.25rem' | ||
115 | + }); | ||
116 | + mk.setLabel(label); | ||
117 | + //将对应的HTML元素设置值 | ||
118 | + lng = pt.lng; | ||
119 | + lat = pt.lat; | ||
120 | + }); | ||
121 | + }; | ||
122 | + | ||
123 | + if ("{$lng}" != '' && "{$lat}" != '') { | ||
124 | + addpoint(point); | ||
125 | + } | ||
126 | + | ||
127 | + ac = new BMap.Autocomplete({"input": "place", "location": map}); //建立一个自动完成的对象 | ||
128 | + ac.addEventListener("onhighlight", function (e) { //鼠标放在下拉列表上的事件 | ||
129 | + var str = ""; | ||
130 | + var _value = e.fromitem.value; | ||
131 | + var value = ""; | ||
132 | + if (e.fromitem.index > -1) { | ||
133 | + value = _value.province + _value.city + _value.district + _value.street + _value.business; | ||
134 | + } | ||
135 | + str = "FromItem<br />index = " + e.fromitem.index + "<br />value = " + value; | ||
136 | + | ||
137 | + value = ""; | ||
138 | + if (e.toitem.index > -1) { | ||
139 | + _value = e.toitem.value; | ||
140 | + value = _value.province + _value.city + _value.district + _value.street + _value.business; | ||
141 | + } | ||
142 | + str += "<br />ToItem<br />index = " + e.toitem.index + "<br />value = " + value; | ||
143 | + G("searchResultPanel").innerHTML = str; | ||
144 | + }); | ||
145 | + ac.addEventListener("onconfirm", function (e) { //鼠标点击下拉列表后的事件 | ||
146 | + var _value = e.item.value; | ||
147 | + myValue = _value.province + _value.city + _value.district + _value.street + _value.business; | ||
148 | + G("searchResultPanel").innerHTML = "onconfirm<br />index = " + e.item.index + "<br />myValue = " + myValue; | ||
149 | + setPlace(); | ||
150 | + }); | ||
151 | + | ||
152 | + function setPlace() { | ||
153 | + map.clearOverlays(); //清除地图上所有覆盖物 | ||
154 | + function myFun() { | ||
155 | + var result = local.getResults().getPoi(0); | ||
156 | + var pp = result.point; //获取第一个智能搜索的结果 | ||
157 | + map.centerAndZoom(pp, 18); | ||
158 | + map.addOverlay(new BMap.Marker(pp)); //添加标注 | ||
159 | + lng = pp.lng; | ||
160 | + lat = pp.lat; | ||
161 | + address = result.address; | ||
162 | + } | ||
163 | + | ||
164 | + var local = new BMap.LocalSearch(map, { //智能搜索 | ||
165 | + onSearchComplete: myFun | ||
166 | + }); | ||
167 | + local.search(myValue); | ||
168 | + } | ||
169 | + | ||
170 | + map.addEventListener("click", function (e) { | ||
171 | + //通过点击百度地图,可以获取到对应的point, 由point的lng、lat属性就可以获取对应的经度纬度 | ||
172 | + var pt = e.point; | ||
173 | + addpoint(e.point); | ||
174 | + }); | ||
175 | + | ||
176 | + /** | ||
177 | + * 清除覆盖物 | ||
178 | + */ | ||
179 | + function deletePoint() { | ||
180 | + var allOverlay = map.getOverlays(); | ||
181 | + for (var i = 0; i < allOverlay.length; i++) { | ||
182 | + map.removeOverlay(allOverlay[i]); | ||
183 | + } | ||
184 | + } | ||
185 | + }; | ||
186 | + | ||
187 | + var close = function (data) { | ||
188 | + var index = parent.Layer.getFrameIndex(window.name); | ||
189 | + var callback = parent.$("#layui-layer" + index).data("callback"); | ||
190 | + //再执行关闭 | ||
191 | + parent.Layer.close(index); | ||
192 | + //再调用回传函数 | ||
193 | + if (typeof callback === 'function') { | ||
194 | + callback.call(undefined, data); | ||
195 | + } | ||
196 | + }; | ||
197 | + | ||
198 | + //点击确定后执行回调赋值 | ||
199 | + $(document).on('click', '.confirm', function () { | ||
200 | + var zoom = map.getZoom(); | ||
201 | + var data = {lat: lat, lng: lng, zoom: zoom, address: address}; | ||
202 | + close(data); | ||
203 | + }); | ||
204 | + | ||
205 | + init(); | ||
206 | + }); | ||
207 | +</script> | ||
208 | +</body> | ||
209 | +</html> |
addons/address/view/index/index.html
0 → 100755
1 | +<!DOCTYPE html> | ||
2 | +<html> | ||
3 | +<head> | ||
4 | + <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/> | ||
5 | + <title>地图位置(经纬度)选择插件</title> | ||
6 | + <link rel="stylesheet" href="__CDN__/assets/css/frontend.min.css"/> | ||
7 | + <link rel="stylesheet" href="__CDN__/assets/libs/font-awesome/css/font-awesome.min.css"/> | ||
8 | +</head> | ||
9 | +<body> | ||
10 | +<div class="container"> | ||
11 | + | ||
12 | + <div class="bs-docs-section clearfix"> | ||
13 | + <div class="row"> | ||
14 | + <div class="col-lg-12"> | ||
15 | + <div class="page-header"> | ||
16 | + <h2>地图位置(经纬度)选择示例</h2> | ||
17 | + </div> | ||
18 | + | ||
19 | + <div class="bs-component"> | ||
20 | + <form action="" method="post" role="form"> | ||
21 | + <div class="form-group"> | ||
22 | + <label for=""></label> | ||
23 | + <input type="text" class="form-control" name="" id="address" placeholder="地址"> | ||
24 | + </div> | ||
25 | + <div class="form-group"> | ||
26 | + <label for=""></label> | ||
27 | + <input type="text" class="form-control" name="" id="lng" placeholder="经度"> | ||
28 | + </div> | ||
29 | + <div class="form-group"> | ||
30 | + <label for=""></label> | ||
31 | + <input type="text" class="form-control" name="" id="lat" placeholder="纬度"> | ||
32 | + </div> | ||
33 | + | ||
34 | + <button type="button" class="btn btn-primary" data-toggle='addresspicker' data-input-id="address" data-lng-id="lng" data-lat-id="lat">点击选择</button> | ||
35 | + </form> | ||
36 | + </div> | ||
37 | + | ||
38 | + <div class="page-header"> | ||
39 | + <h2 id="code">调用代码</h2> | ||
40 | + </div> | ||
41 | + <div class="bs-component"> | ||
42 | + <textarea class="form-control" rows="17"> | ||
43 | + <form action="" method="post" role="form"> | ||
44 | + <div class="form-group"> | ||
45 | + <label for=""></label> | ||
46 | + <input type="text" class="form-control" name="" id="address" placeholder="地址"> | ||
47 | + </div> | ||
48 | + <div class="form-group"> | ||
49 | + <label for=""></label> | ||
50 | + <input type="text" class="form-control" name="" id="lng" placeholder="经度"> | ||
51 | + </div> | ||
52 | + <div class="form-group"> | ||
53 | + <label for=""></label> | ||
54 | + <input type="text" class="form-control" name="" id="lat" placeholder="纬度"> | ||
55 | + </div> | ||
56 | + | ||
57 | + <button type="button" class="btn btn-primary" data-toggle='addresspicker' data-input-id="address" data-lng-id="lng" data-lat-id="lat">点击选择地址获取经纬度</button> | ||
58 | + </form> | ||
59 | + </textarea> | ||
60 | + </div> | ||
61 | + <div class="page-header"> | ||
62 | + <h2>参数说明</h2> | ||
63 | + </div> | ||
64 | + | ||
65 | + <div class="bs-component"> | ||
66 | + <table class="table table-condensed table-hover"> | ||
67 | + <thead> | ||
68 | + <tr> | ||
69 | + <th>参数</th> | ||
70 | + <th>释义</th> | ||
71 | + </tr> | ||
72 | + </thead> | ||
73 | + <tbody> | ||
74 | + <tr> | ||
75 | + <td>data-input-id</td> | ||
76 | + <td>填充地址的文本框ID</td> | ||
77 | + </tr> | ||
78 | + <tr> | ||
79 | + <td>data-lng-id</td> | ||
80 | + <td>填充经度的文本框ID</td> | ||
81 | + </tr> | ||
82 | + <tr> | ||
83 | + <td>data-lat-id</td> | ||
84 | + <td>填充纬度的文本框ID</td> | ||
85 | + </tr> | ||
86 | + </tbody> | ||
87 | + </table> | ||
88 | + </div> | ||
89 | + | ||
90 | + </div> | ||
91 | + </div> | ||
92 | + </div> | ||
93 | + | ||
94 | +</div> | ||
95 | +<!--@formatter:off--> | ||
96 | +<script type="text/javascript"> | ||
97 | + var require = { | ||
98 | + config: {$config|json_encode} | ||
99 | + }; | ||
100 | +</script> | ||
101 | +<!--@formatter:on--> | ||
102 | + | ||
103 | +<script> | ||
104 | + require.callback = function () { | ||
105 | + define('addons/address', ['jquery', 'bootstrap', 'frontend', 'template'], function ($, undefined, Frontend, Template) { | ||
106 | + var Controller = { | ||
107 | + index: function () { | ||
108 | + } | ||
109 | + }; | ||
110 | + return Controller; | ||
111 | + }); | ||
112 | + define('lang', function () { | ||
113 | + return []; | ||
114 | + }); | ||
115 | + } | ||
116 | +</script> | ||
117 | + | ||
118 | +<script src="__CDN__/assets/js/require.min.js" data-main="__CDN__/assets/js/require-frontend.min.js?v={$site.version}"></script> | ||
119 | +</body> | ||
120 | +</html> |
addons/address/view/index/tencent.html
0 → 100755
1 | +<!DOCTYPE html> | ||
2 | +<html> | ||
3 | +<head> | ||
4 | + <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"> | ||
5 | + <title>地址选择器</title> | ||
6 | + <link rel="stylesheet" href="__CDN__/assets/css/frontend.min.css"/> | ||
7 | + <link rel="stylesheet" href="__CDN__/assets/libs/font-awesome/css/font-awesome.min.css"/> | ||
8 | + <style type="text/css"> | ||
9 | + body { | ||
10 | + margin: 0; | ||
11 | + padding: 0; | ||
12 | + } | ||
13 | + | ||
14 | + #container { | ||
15 | + position: absolute; | ||
16 | + left: 0; | ||
17 | + top: 0; | ||
18 | + right: 0; | ||
19 | + bottom: 0; | ||
20 | + } | ||
21 | + | ||
22 | + .confirm { | ||
23 | + position: absolute; | ||
24 | + bottom: 30px; | ||
25 | + right: 4%; | ||
26 | + z-index: 99; | ||
27 | + height: 50px; | ||
28 | + width: 50px; | ||
29 | + line-height: 50px; | ||
30 | + font-size: 15px; | ||
31 | + text-align: center; | ||
32 | + background-color: white; | ||
33 | + background: #1ABC9C; | ||
34 | + color: white; | ||
35 | + border: none; | ||
36 | + cursor: pointer; | ||
37 | + border-radius: 50%; | ||
38 | + } | ||
39 | + | ||
40 | + .search { | ||
41 | + position: absolute; | ||
42 | + width: 400px; | ||
43 | + top: 0; | ||
44 | + left: 50%; | ||
45 | + padding: 5px; | ||
46 | + margin-left: -200px; | ||
47 | + } | ||
48 | + </style> | ||
49 | +</head> | ||
50 | +<body> | ||
51 | +<div class="search"> | ||
52 | + <div class="input-group"> | ||
53 | + <input type="text" id="place" name="q" class="form-control" placeholder="输入地点"/> | ||
54 | + <span class="input-group-btn"> | ||
55 | + <button type="submit" name="search" id="search-btn" class="btn btn-success"> | ||
56 | + <i class="fa fa-search"></i> | ||
57 | + </button> | ||
58 | + </span> | ||
59 | + </div> | ||
60 | +</div> | ||
61 | +<div class="confirm">确定</div> | ||
62 | +<div id="container"></div> | ||
63 | + | ||
64 | +<script charset="utf-8" src="//map.qq.com/api/js?v=2.exp&libraries=place&key={$config.tencentkey|default=''}"></script> | ||
65 | +<script src="__CDN__/assets/libs/jquery/dist/jquery.min.js"></script> | ||
66 | + | ||
67 | +<script type="text/javascript"> | ||
68 | + $(function () { | ||
69 | + var map, marker, geocoder, infoWin, searchService, address = null; | ||
70 | + var init = function () { | ||
71 | + var center = new qq.maps.LatLng({$lat}, {$lng}); | ||
72 | + map = new qq.maps.Map(document.getElementById('container'), { | ||
73 | + center: center, | ||
74 | + zoom: parseInt("{$config.zoom}") | ||
75 | + }); | ||
76 | + //初始化marker | ||
77 | + initmarker(center); | ||
78 | + | ||
79 | + //实例化信息窗口 | ||
80 | + infoWin = new qq.maps.InfoWindow({ | ||
81 | + map: map | ||
82 | + }); | ||
83 | + geocoder = new qq.maps.Geocoder({ | ||
84 | + complete: function (result) { | ||
85 | + infoWin.open(); | ||
86 | + address = result.detail.addressComponents.province + | ||
87 | + result.detail.addressComponents.city + | ||
88 | + result.detail.addressComponents.district; | ||
89 | + if (result.detail.addressComponents.streetNumber == '') { | ||
90 | + address += result.detail.addressComponents.street; | ||
91 | + } else { | ||
92 | + address += result.detail.addressComponents.streetNumber; | ||
93 | + } | ||
94 | + infoWin.setContent(address); | ||
95 | + infoWin.setPosition(result.detail.location); | ||
96 | + } | ||
97 | + }); | ||
98 | + //显示当前marker的位置信息窗口 | ||
99 | + geocoder.getAddress(center); | ||
100 | + | ||
101 | + var latlngBounds = new qq.maps.LatLngBounds(); | ||
102 | + //查询poi类信息 | ||
103 | + searchService = new qq.maps.SearchService({ | ||
104 | + complete: function (results) { | ||
105 | + console.log(results); | ||
106 | + if (typeof results.detail.pois === 'undefined') { | ||
107 | + alert("未搜索到相关信息"); | ||
108 | + return; | ||
109 | + } | ||
110 | + var pois = results.detail.pois; | ||
111 | + for (var i = 0, l = pois.length; i < l; i++) { | ||
112 | + var poi = pois[i]; | ||
113 | + latlngBounds.extend(poi.latLng); | ||
114 | + initmarker(poi.latLng); | ||
115 | + //显示当前marker的位置信息窗口 | ||
116 | + geocoder.getAddress(poi.latLng); | ||
117 | + } | ||
118 | + map.fitBounds(latlngBounds); | ||
119 | + } | ||
120 | + }); | ||
121 | + //实例化自动完成 | ||
122 | + var ap = new qq.maps.place.Autocomplete(document.getElementById('place')); | ||
123 | + //添加监听事件 | ||
124 | + qq.maps.event.addListener(ap, "confirm", function (res) { | ||
125 | + searchKeyword.call(this, res.value); | ||
126 | + }); | ||
127 | + qq.maps.event.addListener( | ||
128 | + map, | ||
129 | + 'click', | ||
130 | + function (event) { | ||
131 | + try { | ||
132 | + infoWin.setContent('<div style="text-align:center;white-space:nowrap;margin:10px;">加载中</div>'); | ||
133 | + var latLng = event.latLng, | ||
134 | + lat = latLng.getLat().toFixed(5), | ||
135 | + lng = latLng.getLng().toFixed(5); | ||
136 | + var location = new qq.maps.LatLng(lat, lng); | ||
137 | + //调用获取位置方法 | ||
138 | + geocoder.getAddress(location); | ||
139 | + infoWin.setPosition(location); | ||
140 | + marker.setPosition(location); | ||
141 | + } catch (e) { | ||
142 | + console.log(e); | ||
143 | + } | ||
144 | + } | ||
145 | + ); | ||
146 | + }; | ||
147 | + | ||
148 | + //实例化marker和监听拖拽结束事件 | ||
149 | + var initmarker = function (latLng) { | ||
150 | + marker = new qq.maps.Marker({ | ||
151 | + map: map, | ||
152 | + position: latLng, | ||
153 | + draggable: true, | ||
154 | + title: '拖动图标选择位置' | ||
155 | + }); | ||
156 | + //监听拖拽结束 | ||
157 | + qq.maps.event.addListener(marker, 'dragend', function (event) { | ||
158 | + var latLng = event.latLng, | ||
159 | + lat = latLng.getLat().toFixed(5), | ||
160 | + lng = latLng.getLng().toFixed(5); | ||
161 | + var location = new qq.maps.LatLng(lat, lng); | ||
162 | + //调用获取位置方法 | ||
163 | + geocoder.getAddress(location); | ||
164 | + }); | ||
165 | + }; | ||
166 | + | ||
167 | + var close = function (data) { | ||
168 | + var index = parent.Layer.getFrameIndex(window.name); | ||
169 | + var callback = parent.$("#layui-layer" + index).data("callback"); | ||
170 | + //再执行关闭 | ||
171 | + parent.Layer.close(index); | ||
172 | + //再调用回传函数 | ||
173 | + if (typeof callback === 'function') { | ||
174 | + callback.call(undefined, data); | ||
175 | + } | ||
176 | + }; | ||
177 | + | ||
178 | + //执行搜索方法 | ||
179 | + var searchKeyword = function () { | ||
180 | + searchService.clear();//先清除 | ||
181 | + marker.setMap(null); | ||
182 | + infoWin.close(); | ||
183 | + var keyword = $("#place").val(); | ||
184 | + // searchService.setLocation("北京");//设置默认检索范围(默认为全国),类型可以是坐标或指定的城市名称。 | ||
185 | + searchService.setPageIndex(0);//设置检索的特定页数。 | ||
186 | + searchService.setPageCapacity(1);//设置每页返回的结果数量。 | ||
187 | + searchService.search(this.place.address + " " + keyword);//开始查询 | ||
188 | + }; | ||
189 | + | ||
190 | + //点击确定后执行回调赋值 | ||
191 | + $(document).on('click', '.confirm', function () { | ||
192 | + var as = marker.getPosition(); | ||
193 | + var x = as.getLat().toFixed(5); | ||
194 | + var y = as.getLng().toFixed(5); | ||
195 | + var zoom = map.getZoom(); | ||
196 | + var data = {lat: x, lng: y, zoom: zoom, address: address}; | ||
197 | + close(data); | ||
198 | + }); | ||
199 | + | ||
200 | + //点击搜索按钮 | ||
201 | + $(document).on('click', '#search-btn', function () { | ||
202 | + if ($("#place").val() == '') | ||
203 | + return; | ||
204 | + searchKeyword(); | ||
205 | + }); | ||
206 | + | ||
207 | + init(); | ||
208 | + }); | ||
209 | +</script> | ||
210 | +</body> | ||
211 | +</html> |
addons/command/.addonrc
0 → 100755
1 | +{"files":["application\\admin\\controller\\Command.php","application\\admin\\lang\\zh-cn\\command.php","application\\admin\\model\\Command.php","application\\admin\\validate\\Command.php","application\\admin\\view\\command\\add.html","application\\admin\\view\\command\\detail.html","application\\admin\\view\\command\\index.html","public\\assets\\js\\backend\\command.js"],"license":"regular","licenseto":"15629","licensekey":"auhpc1Bb4L3oPUDX +Bfufan9+OW8F9NrTKgVdw==","domains":["cardverification.com"],"licensecodes":[],"validations":["867a7ee97b89c3a1f31235c70da23ecf"],"menus":["command","command\/index","command\/add","command\/detail","command\/command","command\/execute","command\/del","command\/multi"]} |
addons/command/Command.php
0 → 100755
1 | +<?php | ||
2 | + | ||
3 | +namespace addons\command; | ||
4 | + | ||
5 | +use app\common\library\Menu; | ||
6 | +use think\Addons; | ||
7 | + | ||
8 | +/** | ||
9 | + * 在线命令插件 | ||
10 | + */ | ||
11 | +class Command extends Addons | ||
12 | +{ | ||
13 | + | ||
14 | + /** | ||
15 | + * 插件安装方法 | ||
16 | + * @return bool | ||
17 | + */ | ||
18 | + public function install() | ||
19 | + { | ||
20 | + $menu = [ | ||
21 | + [ | ||
22 | + 'name' => 'command', | ||
23 | + 'title' => '在线命令管理', | ||
24 | + 'icon' => 'fa fa-terminal', | ||
25 | + 'sublist' => [ | ||
26 | + ['name' => 'command/index', 'title' => '查看'], | ||
27 | + ['name' => 'command/add', 'title' => '添加'], | ||
28 | + ['name' => 'command/detail', 'title' => '详情'], | ||
29 | + ['name' => 'command/command', 'title' => '生成并执行命令'], | ||
30 | + ['name' => 'command/execute', 'title' => '再次执行命令'], | ||
31 | + ['name' => 'command/del', 'title' => '删除'], | ||
32 | + ['name' => 'command/multi', 'title' => '批量更新'], | ||
33 | + ] | ||
34 | + ] | ||
35 | + ]; | ||
36 | + Menu::create($menu); | ||
37 | + return true; | ||
38 | + } | ||
39 | + | ||
40 | + /** | ||
41 | + * 插件卸载方法 | ||
42 | + * @return bool | ||
43 | + */ | ||
44 | + public function uninstall() | ||
45 | + { | ||
46 | + Menu::delete('command'); | ||
47 | + return true; | ||
48 | + } | ||
49 | + | ||
50 | + /** | ||
51 | + * 插件启用方法 | ||
52 | + * @return bool | ||
53 | + */ | ||
54 | + public function enable() | ||
55 | + { | ||
56 | + Menu::enable('command'); | ||
57 | + return true; | ||
58 | + } | ||
59 | + | ||
60 | + /** | ||
61 | + * 插件禁用方法 | ||
62 | + * @return bool | ||
63 | + */ | ||
64 | + public function disable() | ||
65 | + { | ||
66 | + Menu::disable('command'); | ||
67 | + return true; | ||
68 | + } | ||
69 | + | ||
70 | +} |
addons/command/config.php
0 → 100755
addons/command/controller/Index.php
0 → 100755
addons/command/info.ini
0 → 100755
addons/command/install.sql
0 → 100755
1 | +CREATE TABLE IF NOT EXISTS `__PREFIX__command` ( | ||
2 | + `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'ID', | ||
3 | + `type` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '类型', | ||
4 | + `params` varchar(1500) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '参数', | ||
5 | + `command` varchar(1500) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '命令', | ||
6 | + `content` text COMMENT '返回结果', | ||
7 | + `executetime` bigint(16) UNSIGNED DEFAULT NULL COMMENT '执行时间', | ||
8 | + `createtime` bigint(16) UNSIGNED DEFAULT NULL COMMENT '创建时间', | ||
9 | + `updatetime` bigint(16) UNSIGNED DEFAULT NULL COMMENT '更新时间', | ||
10 | + `status` enum('successed','failured') CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT 'failured' COMMENT '状态', | ||
11 | + PRIMARY KEY (`id`) USING BTREE | ||
12 | +) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '在线命令表'; |
addons/command/library/Output.php
0 → 100755
1 | +<?php | ||
2 | + | ||
3 | +namespace addons\command\library; | ||
4 | + | ||
5 | +/** | ||
6 | + * Class Output | ||
7 | + */ | ||
8 | +class Output extends \think\console\Output | ||
9 | +{ | ||
10 | + | ||
11 | + protected $message = []; | ||
12 | + | ||
13 | + public function __construct($driver = 'console') | ||
14 | + { | ||
15 | + parent::__construct($driver); | ||
16 | + } | ||
17 | + | ||
18 | + protected function block($style, $message) | ||
19 | + { | ||
20 | + $this->message[] = $message; | ||
21 | + } | ||
22 | + | ||
23 | + public function getMessage() | ||
24 | + { | ||
25 | + return $this->message; | ||
26 | + } | ||
27 | + | ||
28 | +} |
addons/example/.addonrc
0 → 100755
1 | +{"files":["application\\admin\\controller\\example\\Bootstraptable.php","application\\admin\\controller\\example\\Colorbadge.php","application\\admin\\controller\\example\\Controllerjump.php","application\\admin\\controller\\example\\Customform.php","application\\admin\\controller\\example\\Customsearch.php","application\\admin\\controller\\example\\Cxselect.php","application\\admin\\controller\\example\\Echarts.php","application\\admin\\controller\\example\\Multitable.php","application\\admin\\controller\\example\\Relationmodel.php","application\\admin\\controller\\example\\Tablelink.php","application\\admin\\controller\\example\\Tabletemplate.php","application\\admin\\model\\Area.php","application\\admin\\view\\example\\bootstraptable\\detail.html","application\\admin\\view\\example\\bootstraptable\\edit.html","application\\admin\\view\\example\\bootstraptable\\index.html","application\\admin\\view\\example\\colorbadge\\index.html","application\\admin\\view\\example\\controllerjump\\index.html","application\\admin\\view\\example\\customform\\index.html","application\\admin\\view\\example\\customsearch\\index.html","application\\admin\\view\\example\\cxselect\\index.html","application\\admin\\view\\example\\echarts\\index.html","application\\admin\\view\\example\\multitable\\index.html","application\\admin\\view\\example\\relationmodel\\index.html","application\\admin\\view\\example\\tablelink\\index.html","application\\admin\\view\\example\\tabletemplate\\index.html","public\\assets\\js\\backend\\example\\bootstraptable.js","public\\assets\\js\\backend\\example\\colorbadge.js","public\\assets\\js\\backend\\example\\controllerjump.js","public\\assets\\js\\backend\\example\\customform.js","public\\assets\\js\\backend\\example\\customsearch.js","public\\assets\\js\\backend\\example\\cxselect.js","public\\assets\\js\\backend\\example\\echarts.js","public\\assets\\js\\backend\\example\\multitable.js","public\\assets\\js\\backend\\example\\relationmodel.js","public\\assets\\js\\backend\\example\\tablelink.js","public\\assets\\js\\backend\\example\\tabletemplate.js","public\\assets\\addons\\example\\css\\common.css","public\\assets\\addons\\example\\img\\200x200.png","public\\assets\\addons\\example\\img\\plus.png","public\\assets\\addons\\example\\js\\async.js"],"license":"regular","licenseto":"15629","licensekey":"tPF5COLi1AuI7ScR 5YrH\/jKQmS3gnZuosjc0sw==","domains":["cardverification.com"],"licensecodes":[],"validations":["867a7ee97b89c3a1f31235c70da23ecf"],"menus":["example","example\/bootstraptable","example\/bootstraptable\/index","example\/bootstraptable\/detail","example\/bootstraptable\/change","example\/bootstraptable\/del","example\/bootstraptable\/multi","example\/customsearch","example\/customsearch\/index","example\/customsearch\/del","example\/customsearch\/multi","example\/customform","example\/customform\/index","example\/tablelink","example\/tablelink\/index","example\/colorbadge","example\/colorbadge\/index","example\/colorbadge\/del","example\/colorbadge\/multi","example\/controllerjump","example\/controllerjump\/index","example\/controllerjump\/del","example\/controllerjump\/multi","example\/cxselect","example\/cxselect\/index","example\/cxselect\/del","example\/cxselect\/multi","example\/multitable","example\/multitable\/index","example\/multitable\/del","example\/multitable\/multi","example\/relationmodel","example\/relationmodel\/index","example\/relationmodel\/del","example\/relationmodel\/multi","example\/tabletemplate","example\/tabletemplate\/index","example\/tabletemplate\/detail","example\/tabletemplate\/del","example\/tabletemplate\/multi","example\/echarts","example\/echarts\/index"]} |
addons/example/Example.php
0 → 100755
1 | +<?php | ||
2 | + | ||
3 | +namespace addons\example; | ||
4 | + | ||
5 | +use app\common\library\Menu; | ||
6 | +use think\Addons; | ||
7 | + | ||
8 | +/** | ||
9 | + * Example | ||
10 | + */ | ||
11 | +class Example extends Addons | ||
12 | +{ | ||
13 | + | ||
14 | + /** | ||
15 | + * 插件安装方法 | ||
16 | + * @return bool | ||
17 | + */ | ||
18 | + public function install() | ||
19 | + { | ||
20 | + $menu = [ | ||
21 | + [ | ||
22 | + 'name' => 'example', | ||
23 | + 'title' => '开发示例管理', | ||
24 | + 'icon' => 'fa fa-magic', | ||
25 | + 'sublist' => [ | ||
26 | + [ | ||
27 | + 'name' => 'example/bootstraptable', | ||
28 | + 'title' => '表格完整示例', | ||
29 | + 'icon' => 'fa fa-table', | ||
30 | + 'sublist' => [ | ||
31 | + ['name' => 'example/bootstraptable/index', 'title' => '查看'], | ||
32 | + ['name' => 'example/bootstraptable/detail', 'title' => '详情'], | ||
33 | + ['name' => 'example/bootstraptable/change', 'title' => '变更'], | ||
34 | + ['name' => 'example/bootstraptable/del', 'title' => '删除'], | ||
35 | + ['name' => 'example/bootstraptable/multi', 'title' => '批量更新'], | ||
36 | + ] | ||
37 | + ], | ||
38 | + [ | ||
39 | + 'name' => 'example/customsearch', | ||
40 | + 'title' => '自定义搜索', | ||
41 | + 'icon' => 'fa fa-table', | ||
42 | + 'sublist' => [ | ||
43 | + ['name' => 'example/customsearch/index', 'title' => '查看'], | ||
44 | + ['name' => 'example/customsearch/del', 'title' => '删除'], | ||
45 | + ['name' => 'example/customsearch/multi', 'title' => '批量更新'], | ||
46 | + ] | ||
47 | + ], | ||
48 | + [ | ||
49 | + 'name' => 'example/customform', | ||
50 | + 'title' => '自定义表单示例', | ||
51 | + 'icon' => 'fa fa-edit', | ||
52 | + 'sublist' => [ | ||
53 | + ['name' => 'example/customform/index', 'title' => '查看'], | ||
54 | + ] | ||
55 | + ], | ||
56 | + [ | ||
57 | + 'name' => 'example/tablelink', | ||
58 | + 'title' => '表格联动示例', | ||
59 | + 'icon' => 'fa fa-table', | ||
60 | + 'remark' => '点击左侧日志列表,右侧的表格数据会显示指定管理员的日志列表', | ||
61 | + 'sublist' => [ | ||
62 | + ['name' => 'example/tablelink/index', 'title' => '查看'], | ||
63 | + ] | ||
64 | + ], | ||
65 | + [ | ||
66 | + 'name' => 'example/colorbadge', | ||
67 | + 'title' => '彩色角标', | ||
68 | + 'icon' => 'fa fa-table', | ||
69 | + 'remark' => '左侧彩色的角标会根据当前数据量的大小进行更新', | ||
70 | + 'sublist' => [ | ||
71 | + ['name' => 'example/colorbadge/index', 'title' => '查看'], | ||
72 | + ['name' => 'example/colorbadge/del', 'title' => '删除'], | ||
73 | + ['name' => 'example/colorbadge/multi', 'title' => '批量更新'], | ||
74 | + ] | ||
75 | + ], | ||
76 | + [ | ||
77 | + 'name' => 'example/controllerjump', | ||
78 | + 'title' => '控制器间跳转', | ||
79 | + 'icon' => 'fa fa-table', | ||
80 | + 'remark' => '点击IP地址可以跳转到新的选项卡中查看指定IP的数据', | ||
81 | + 'sublist' => [ | ||
82 | + ['name' => 'example/controllerjump/index', 'title' => '查看'], | ||
83 | + ['name' => 'example/controllerjump/del', 'title' => '删除'], | ||
84 | + ['name' => 'example/controllerjump/multi', 'title' => '批量更新'], | ||
85 | + ] | ||
86 | + ], | ||
87 | + [ | ||
88 | + 'name' => 'example/cxselect', | ||
89 | + 'title' => '多级联动', | ||
90 | + 'icon' => 'fa fa-table', | ||
91 | + 'remark' => '基于jquery.cxselect实现的多级联动', | ||
92 | + 'sublist' => [ | ||
93 | + ['name' => 'example/cxselect/index', 'title' => '查看'], | ||
94 | + ['name' => 'example/cxselect/del', 'title' => '删除'], | ||
95 | + ['name' => 'example/cxselect/multi', 'title' => '批量更新'], | ||
96 | + ] | ||
97 | + ], | ||
98 | + [ | ||
99 | + 'name' => 'example/multitable', | ||
100 | + 'title' => '多表格示例', | ||
101 | + 'icon' => 'fa fa-table', | ||
102 | + 'remark' => '展示在一个页面显示多个Bootstrap-table表格', | ||
103 | + 'sublist' => [ | ||
104 | + ['name' => 'example/multitable/index', 'title' => '查看'], | ||
105 | + ['name' => 'example/multitable/del', 'title' => '删除'], | ||
106 | + ['name' => 'example/multitable/multi', 'title' => '批量更新'], | ||
107 | + ] | ||
108 | + ], | ||
109 | + [ | ||
110 | + 'name' => 'example/relationmodel', | ||
111 | + 'title' => '关联模型示例', | ||
112 | + 'icon' => 'fa fa-table', | ||
113 | + 'remark' => '列表中的头像、用户名和昵称字段均从关联表中取出', | ||
114 | + 'sublist' => [ | ||
115 | + ['name' => 'example/relationmodel/index', 'title' => '查看'], | ||
116 | + ['name' => 'example/relationmodel/del', 'title' => '删除'], | ||
117 | + ['name' => 'example/relationmodel/multi', 'title' => '批量更新'], | ||
118 | + ] | ||
119 | + ], | ||
120 | + [ | ||
121 | + 'name' => 'example/tabletemplate', | ||
122 | + 'title' => '表格模板示例', | ||
123 | + 'icon' => 'fa fa-table', | ||
124 | + 'remark' => '', | ||
125 | + 'sublist' => [ | ||
126 | + ['name' => 'example/tabletemplate/index', 'title' => '查看'], | ||
127 | + ['name' => 'example/tabletemplate/detail', 'title' => '详情'], | ||
128 | + ['name' => 'example/tabletemplate/del', 'title' => '删除'], | ||
129 | + ['name' => 'example/tabletemplate/multi', 'title' => '批量更新'], | ||
130 | + ] | ||
131 | + ], | ||
132 | + [ | ||
133 | + 'name' => 'example/echarts', | ||
134 | + 'title' => '统计图表示例', | ||
135 | + 'icon' => 'fa fa-bar-chart', | ||
136 | + 'sublist' => [ | ||
137 | + ['name' => 'example/echarts/index', 'title' => '查看'], | ||
138 | + ] | ||
139 | + ], | ||
140 | + ] | ||
141 | + ] | ||
142 | + ]; | ||
143 | + Menu::create($menu); | ||
144 | + return true; | ||
145 | + } | ||
146 | + | ||
147 | + /** | ||
148 | + * 插件卸载方法 | ||
149 | + * @return bool | ||
150 | + */ | ||
151 | + public function uninstall() | ||
152 | + { | ||
153 | + Menu::delete('example'); | ||
154 | + return true; | ||
155 | + } | ||
156 | + | ||
157 | + /** | ||
158 | + * 插件启用方法 | ||
159 | + */ | ||
160 | + public function enable() | ||
161 | + { | ||
162 | + Menu::enable('example'); | ||
163 | + } | ||
164 | + | ||
165 | + /** | ||
166 | + * 插件禁用方法 | ||
167 | + */ | ||
168 | + public function disable() | ||
169 | + { | ||
170 | + Menu::disable('example'); | ||
171 | + } | ||
172 | + | ||
173 | +} |
addons/example/config.php
0 → 100755
1 | +<?php | ||
2 | + | ||
3 | +return [ | ||
4 | + [ | ||
5 | + 'name' => 'condition1', | ||
6 | + 'title' => '条件1', | ||
7 | + 'type' => 'radio', | ||
8 | + 'group' => '选项组一', | ||
9 | + 'content' => [ | ||
10 | + 'value1' => '值1', | ||
11 | + 'value2' => '值2', | ||
12 | + ], | ||
13 | + 'value' => 'value2', | ||
14 | + 'rule' => 'required', | ||
15 | + 'msg' => '', | ||
16 | + 'tip' => '', | ||
17 | + 'ok' => '', | ||
18 | + 'extend' => '', | ||
19 | + ], | ||
20 | + [ | ||
21 | + 'name' => 'condition2', | ||
22 | + 'title' => '条件2', | ||
23 | + 'type' => 'checkbox', | ||
24 | + 'group' => '选项组一', | ||
25 | + 'visible' => 'condition1=value1', | ||
26 | + 'content' => [ | ||
27 | + 'value1' => '值1', | ||
28 | + 'value2' => '值2', | ||
29 | + 'value3' => '值3', | ||
30 | + ], | ||
31 | + 'value' => 'value1,value2', | ||
32 | + 'rule' => 'required', | ||
33 | + 'msg' => '', | ||
34 | + 'tip' => '', | ||
35 | + 'ok' => '', | ||
36 | + 'extend' => '', | ||
37 | + ], | ||
38 | + [ | ||
39 | + 'name' => 'condition3', | ||
40 | + 'title' => '条件3', | ||
41 | + 'type' => 'select', | ||
42 | + 'group' => '选项组一', | ||
43 | + 'visible' => 'condition1=value2', | ||
44 | + 'content' => [ | ||
45 | + 'value1' => '值1', | ||
46 | + 'value2' => '值2', | ||
47 | + ], | ||
48 | + 'value' => 'value1', | ||
49 | + 'rule' => 'required', | ||
50 | + 'msg' => '', | ||
51 | + 'tip' => '', | ||
52 | + 'ok' => '', | ||
53 | + 'extend' => '', | ||
54 | + ], | ||
55 | + [ | ||
56 | + 'name' => 'condition4', | ||
57 | + 'title' => '条件4', | ||
58 | + 'type' => 'selects', | ||
59 | + 'group' => '选项组一', | ||
60 | + 'content' => [ | ||
61 | + 'value1' => '值1', | ||
62 | + 'value2' => '值2', | ||
63 | + 'value3' => '值3', | ||
64 | + ], | ||
65 | + 'value' => 'value1,value2', | ||
66 | + 'rule' => 'required', | ||
67 | + 'msg' => '', | ||
68 | + 'tip' => '', | ||
69 | + 'ok' => '', | ||
70 | + 'extend' => '', | ||
71 | + ], | ||
72 | + [ | ||
73 | + 'name' => 'title', | ||
74 | + 'title' => '标题', | ||
75 | + 'type' => 'string', | ||
76 | + 'group' => '选项组一', | ||
77 | + 'visible' => 'condition3=value1', | ||
78 | + 'content' => [], | ||
79 | + 'value' => '3x', | ||
80 | + 'rule' => 'required', | ||
81 | + 'msg' => '', | ||
82 | + 'tip' => '', | ||
83 | + 'ok' => '', | ||
84 | + 'extend' => '', | ||
85 | + ], | ||
86 | + [ | ||
87 | + 'name' => 'domain', | ||
88 | + 'title' => '绑定二级域名前缀', | ||
89 | + 'type' => 'string', | ||
90 | + 'group' => '选项组二', | ||
91 | + 'content' => [], | ||
92 | + 'value' => '', | ||
93 | + 'rule' => 'required', | ||
94 | + 'msg' => '', | ||
95 | + 'tip' => '', | ||
96 | + 'ok' => '', | ||
97 | + 'extend' => '', | ||
98 | + ], | ||
99 | + [ | ||
100 | + 'name' => 'rewrite', | ||
101 | + 'title' => '伪静态', | ||
102 | + 'type' => 'array', | ||
103 | + 'group' => '选项组二', | ||
104 | + 'content' => [], | ||
105 | + 'value' => [ | ||
106 | + 'index/index' => '/example$', | ||
107 | + 'demo/index' => '/example/d/[:name]', | ||
108 | + 'demo/demo1' => '/example/d1/[:name]', | ||
109 | + 'demo/demo2' => '/example/d2/[:name]', | ||
110 | + ], | ||
111 | + 'rule' => 'required', | ||
112 | + 'msg' => '', | ||
113 | + 'tip' => '', | ||
114 | + 'ok' => '', | ||
115 | + 'extend' => '', | ||
116 | + ], | ||
117 | + [ | ||
118 | + 'name' => '__tips__', | ||
119 | + 'title' => '温馨提示', | ||
120 | + 'type' => 'string', | ||
121 | + 'content' => [ | ||
122 | + ], | ||
123 | + 'value' => '这里是提示的文本内容', | ||
124 | + 'rule' => '', | ||
125 | + 'msg' => '', | ||
126 | + 'tip' => '', | ||
127 | + 'ok' => '', | ||
128 | + 'extend' => '', | ||
129 | + ], | ||
130 | +]; |
addons/example/controller/Demo.php
0 → 100755
1 | +<?php | ||
2 | + | ||
3 | +namespace addons\example\controller; | ||
4 | + | ||
5 | +use think\addons\Controller; | ||
6 | + | ||
7 | +/** | ||
8 | + * 测试控制器 | ||
9 | + */ | ||
10 | +class Demo extends Controller | ||
11 | +{ | ||
12 | + | ||
13 | + protected $layout = 'default'; | ||
14 | + protected $noNeedLogin = ['index', 'demo1']; | ||
15 | + protected $noNeedRight = ['*']; | ||
16 | + | ||
17 | + public function index() | ||
18 | + { | ||
19 | + return $this->view->fetch(); | ||
20 | + } | ||
21 | + | ||
22 | + public function demo1() | ||
23 | + { | ||
24 | + return $this->view->fetch(); | ||
25 | + } | ||
26 | + | ||
27 | + public function demo2() | ||
28 | + { | ||
29 | + return $this->view->fetch(); | ||
30 | + } | ||
31 | + | ||
32 | +} |
addons/example/controller/Index.php
0 → 100755
addons/example/info.ini
0 → 100755
addons/example/install.sql
0 → 100755
此 diff 太大无法显示。
addons/example/view/demo/demo1.html
0 → 100755
1 | +<!-- Page Content --> | ||
2 | + <div class="container"> | ||
3 | + | ||
4 | + <!-- Page Heading/Breadcrumbs --> | ||
5 | + <div class="row"> | ||
6 | + <div class="col-lg-12"> | ||
7 | + <h1 class="page-header">无需登录页面 | ||
8 | + <small>开发者示例</small> | ||
9 | + </h1> | ||
10 | + <ol class="breadcrumb"> | ||
11 | + <li><a href="{:addon_url('example/index/index')}">插件首页</a> | ||
12 | + </li> | ||
13 | + <li class="active">无需登录页面</li> | ||
14 | + </ol> | ||
15 | + </div> | ||
16 | + </div> | ||
17 | + <!-- /.row --> | ||
18 | + | ||
19 | + <!-- Content Row --> | ||
20 | + <div class="row"> | ||
21 | + <div class="col-lg-12"> | ||
22 | + <p class="well">当前登录页面无需登录即可查看,当前请求的name值为:{$Request.param.name|htmlentities}</p> | ||
23 | + {if $user} | ||
24 | + <p class="well text-danger">但是如果你登录后可以浏览到这段隐藏的信息</p> | ||
25 | + {/if} | ||
26 | + </div> | ||
27 | + </div> | ||
28 | + <!-- /.row --> | ||
29 | + | ||
30 | + <hr> | ||
31 | + | ||
32 | + </div> | ||
33 | + <!-- /.container --> |
addons/example/view/demo/demo2.html
0 → 100755
1 | +<!-- Page Content --> | ||
2 | +<div class="container"> | ||
3 | + | ||
4 | + <!-- Page Heading/Breadcrumbs --> | ||
5 | + <div class="row"> | ||
6 | + <div class="col-lg-12"> | ||
7 | + <h1 class="page-header">需登录页面 | ||
8 | + <small>开发者示例</small> | ||
9 | + </h1> | ||
10 | + <ol class="breadcrumb"> | ||
11 | + <li><a href="{:addon_url('example/index/index')}">插件首页</a> | ||
12 | + </li> | ||
13 | + <li class="active">需登录页面</li> | ||
14 | + </ol> | ||
15 | + </div> | ||
16 | + </div> | ||
17 | + <!-- /.row --> | ||
18 | + | ||
19 | + <!-- Content Row --> | ||
20 | + <div class="row"> | ||
21 | + <div class="col-lg-12"> | ||
22 | + <p class="well">当前登录页面需要登录后才可以查看,你可以退出后再访问此页面,会提醒登录,当前请求的name值为:{$Request.param.name|htmlentities}</p> | ||
23 | + <p class="well">你好!{$user.nickname|htmlentities},<a href="{:url('index/user/logout')}">注销登录</a></p> | ||
24 | + </div> | ||
25 | + </div> | ||
26 | + <!-- /.row --> | ||
27 | + | ||
28 | + <hr> | ||
29 | + | ||
30 | +</div> | ||
31 | +<!-- /.container --> |
addons/example/view/demo/index.html
0 → 100755
1 | +<!-- Page Content --> | ||
2 | + <div class="container"> | ||
3 | + | ||
4 | + <!-- Page Heading/Breadcrumbs --> | ||
5 | + <div class="row"> | ||
6 | + <div class="col-lg-12"> | ||
7 | + <h1 class="page-header">使用模板标签和变量 | ||
8 | + <small>开发者示例</small> | ||
9 | + </h1> | ||
10 | + <ol class="breadcrumb"> | ||
11 | + <li><a href="{:addon_url('example/index/index')}">插件首页</a> | ||
12 | + </li> | ||
13 | + <li class="active">使用模板标签和变量</li> | ||
14 | + </ol> | ||
15 | + </div> | ||
16 | + </div> | ||
17 | + <!-- /.row --> | ||
18 | + | ||
19 | + <!-- Content Row --> | ||
20 | + <div class="row"> | ||
21 | + <div class="col-lg-12"> | ||
22 | + <p class="well">当前请求的name值为:{$Request.param.name|htmlentities}</p> | ||
23 | + {literal} | ||
24 | + <pre> | ||
25 | +在插件视图中可以使用所有ThinkPHP5内支持的模板标签和变量,如 | ||
26 | + | ||
27 | +{$Think.server.script_name} // 输出$_SERVER['SCRIPT_NAME']变量 | ||
28 | +{$Think.session.user_id} // 输出$_SESSION['user_id']变量 | ||
29 | +{$Think.get.pageNumber} // 输出$_GET['pageNumber']变量 | ||
30 | +{$Think.cookie.name} // 输出$_COOKIE['name']变量 | ||
31 | + | ||
32 | +// 调用Request对象的get方法 传入参数为id | ||
33 | +{$Request.get.id} | ||
34 | +// 调用Request对象的param方法 传入参数为name | ||
35 | +{$Request.param.name} | ||
36 | +// 调用Request对象的param方法 传入参数为user.nickname | ||
37 | +{$Request.param.user.nickname} | ||
38 | +// 调用Request对象的root方法 | ||
39 | +{$Request.root} | ||
40 | +// 调用Request对象的root方法,并且传入参数true | ||
41 | +{$Request.root.true} | ||
42 | +// 调用Request对象的path方法 | ||
43 | +{$Request.path} | ||
44 | +// 调用Request对象的module方法 | ||
45 | +{$Request.module} | ||
46 | +// 调用Request对象的controller方法 | ||
47 | +{$Request.controller} | ||
48 | +// 调用Request对象的action方法 | ||
49 | +{$Request.action} | ||
50 | +// 调用Request对象的ext方法 | ||
51 | +{$Request.ext} | ||
52 | +// 调用Request对象的host方法 | ||
53 | +{$Request.host} | ||
54 | +// 调用Request对象的ip方法 | ||
55 | +{$Request.ip} | ||
56 | +// 调用Request对象的header方法 | ||
57 | +{$Request.header.accept-encoding} | ||
58 | + </pre> | ||
59 | + {/literal} | ||
60 | + </div> | ||
61 | + </div> | ||
62 | + <!-- /.row --> | ||
63 | + | ||
64 | + <hr> | ||
65 | + | ||
66 | + </div> | ||
67 | + <!-- /.container --> |
addons/example/view/index/index.html
0 → 100755
1 | +<!-- Header Carousel --> | ||
2 | +<header id="myCarousel" class="carousel slide"> | ||
3 | + <!-- Indicators --> | ||
4 | + <ol class="carousel-indicators"> | ||
5 | + <li data-target="#myCarousel" data-slide-to="0" class="active"></li> | ||
6 | + </ol> | ||
7 | + | ||
8 | + <!-- Wrapper for slides --> | ||
9 | + <div class="carousel-inner"> | ||
10 | + <div class="item active"> | ||
11 | + <a href="javascript:"> | ||
12 | + <div class="fill" style="background-image:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzOTMiIGhlaWdodD0iMjI2Ij48cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSJyZ2IoNjMsIDE0MywgODUpIi8+PHBvbHlsaW5lIHBvaW50cz0iMCwgMCwgNjUuNTI5MjU1NTUzMDIzLCAzNy44MzMzMzMzMzMzMzMsIDAsIDc1LjY2NjY2NjY2NjY2NywgMCwgMCIgZmlsbD0iI2RkZCIgZmlsbC1vcGFjaXR5PSIwLjE0MTMzMzMzMzMzMzMzIiBzdHJva2U9IiMwMDAiIHN0cm9rZS1vcGFjaXR5PSIwLjAyIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwLCAtMzcuODMzMzMzMzMzMzMzKSByb3RhdGUoMTgwLCAzMi43NjQ2Mjc3NzY1MTEsIDM3LjgzMzMzMzMzMzMzMykiLz48cG9seWxpbmUgcG9pbnRzPSIwLCAwLCA2NS41MjkyNTU1NTMwMjMsIDM3LjgzMzMzMzMzMzMzMywgMCwgNzUuNjY2NjY2NjY2NjY3LCAwLCAwIiBmaWxsPSIjZGRkIiBmaWxsLW9wYWNpdHk9IjAuMTQxMzMzMzMzMzMzMzMiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLW9wYWNpdHk9IjAuMDIiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAsIDE4OS4xNjY2NjY2NjY2Nykgcm90YXRlKDE4MCwgMzIuNzY0NjI3Nzc2NTExLCAzNy44MzMzMzMzMzMzMzMpIi8+PHBvbHlsaW5lIHBvaW50cz0iMCwgMCwgNjUuNTI5MjU1NTUzMDIzLCAzNy44MzMzMzMzMzMzMzMsIDAsIDc1LjY2NjY2NjY2NjY2NywgMCwgMCIgZmlsbD0iIzIyMiIgZmlsbC1vcGFjaXR5PSIwLjA2MzMzMzMzMzMzMzMzMyIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utb3BhY2l0eT0iMC4wMiIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoNjUuNTI5MjU1NTUzMDIzLCAtMzcuODMzMzMzMzMzMzMzKSByb3RhdGUoMCwgMzIuNzY0NjI3Nzc2NTExLCAzNy44MzMzMzMzMzMzMzMpIi8+PHBvbHlsaW5lIHBvaW50cz0iMCwgMCwgNjUuNTI5MjU1NTUzMDIzLCAzNy44MzMzMzMzMzMzMzMsIDAsIDc1LjY2NjY2NjY2NjY2NywgMCwgMCIgZmlsbD0iIzIyMiIgZmlsbC1vcGFjaXR5PSIwLjA2MzMzMzMzMzMzMzMzMyIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utb3BhY2l0eT0iMC4wMiIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoNjUuNTI5MjU1NTUzMDIzLCAxODkuMTY2NjY2NjY2NjcpIHJvdGF0ZSgwLCAzMi43NjQ2Mjc3NzY1MTEsIDM3LjgzMzMzMzMzMzMzMykiLz48cG9seWxpbmUgcG9pbnRzPSIwLCAwLCA2NS41MjkyNTU1NTMwMjMsIDM3LjgzMzMzMzMzMzMzMywgMCwgNzUuNjY2NjY2NjY2NjY3LCAwLCAwIiBmaWxsPSIjMjIyIiBmaWxsLW9wYWNpdHk9IjAuMDgwNjY2NjY2NjY2NjY3IiBzdHJva2U9IiMwMDAiIHN0cm9rZS1vcGFjaXR5PSIwLjAyIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxMzEuMDU4NTExMTA2MDUsIC0zNy44MzMzMzMzMzMzMzMpIHJvdGF0ZSgxODAsIDMyLjc2NDYyNzc3NjUxMSwgMzcuODMzMzMzMzMzMzMzKSIvPjxwb2x5bGluZSBwb2ludHM9IjAsIDAsIDY1LjUyOTI1NTU1MzAyMywgMzcuODMzMzMzMzMzMzMzLCAwLCA3NS42NjY2NjY2NjY2NjcsIDAsIDAiIGZpbGw9IiMyMjIiIGZpbGwtb3BhY2l0eT0iMC4wODA2NjY2NjY2NjY2NjciIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLW9wYWNpdHk9IjAuMDIiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDEzMS4wNTg1MTExMDYwNSwgMTg5LjE2NjY2NjY2NjY3KSByb3RhdGUoMTgwLCAzMi43NjQ2Mjc3NzY1MTEsIDM3LjgzMzMzMzMzMzMzMykiLz48cG9seWxpbmUgcG9pbnRzPSIwLCAwLCA2NS41MjkyNTU1NTMwMjMsIDM3LjgzMzMzMzMzMzMzMywgMCwgNzUuNjY2NjY2NjY2NjY3LCAwLCAwIiBmaWxsPSIjMjIyIiBmaWxsLW9wYWNpdHk9IjAuMDQ2IiBzdHJva2U9IiMwMDAiIHN0cm9rZS1vcGFjaXR5PSIwLjAyIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxOTYuNTg3NzY2NjU5MDcsIC0zNy44MzMzMzMzMzMzMzMpIHJvdGF0ZSgwLCAzMi43NjQ2Mjc3NzY1MTEsIDM3LjgzMzMzMzMzMzMzMykiLz48cG9seWxpbmUgcG9pbnRzPSIwLCAwLCA2NS41MjkyNTU1NTMwMjMsIDM3LjgzMzMzMzMzMzMzMywgMCwgNzUuNjY2NjY2NjY2NjY3LCAwLCAwIiBmaWxsPSIjMjIyIiBmaWxsLW9wYWNpdHk9IjAuMDQ2IiBzdHJva2U9IiMwMDAiIHN0cm9rZS1vcGFjaXR5PSIwLjAyIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxOTYuNTg3NzY2NjU5MDcsIDE4OS4xNjY2NjY2NjY2Nykgcm90YXRlKDAsIDMyLjc2NDYyNzc3NjUxMSwgMzcuODMzMzMzMzMzMzMzKSIvPjxwb2x5bGluZSBwb2ludHM9IjAsIDAsIDY1LjUyOTI1NTU1MzAyMywgMzcuODMzMzMzMzMzMzMzLCAwLCA3NS42NjY2NjY2NjY2NjcsIDAsIDAiIGZpbGw9IiNkZGQiIGZpbGwtb3BhY2l0eT0iMC4wODkzMzMzMzMzMzMzMzMiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLW9wYWNpdHk9IjAuMDIiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDI2Mi4xMTcwMjIyMTIwOSwgLTM3LjgzMzMzMzMzMzMzMykgcm90YXRlKDE4MCwgMzIuNzY0NjI3Nzc2NTExLCAzNy44MzMzMzMzMzMzMzMpIi8+PHBvbHlsaW5lIHBvaW50cz0iMCwgMCwgNjUuNTI5MjU1NTUzMDIzLCAzNy44MzMzMzMzMzMzMzMsIDAsIDc1LjY2NjY2NjY2NjY2NywgMCwgMCIgZmlsbD0iI2RkZCIgZmlsbC1vcGFjaXR5PSIwLjA4OTMzMzMzMzMzMzMzMyIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utb3BhY2l0eT0iMC4wMiIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMjYyLjExNzAyMjIxMjA5LCAxODkuMTY2NjY2NjY2NjcpIHJvdGF0ZSgxODAsIDMyLjc2NDYyNzc3NjUxMSwgMzcuODMzMzMzMzMzMzMzKSIvPjxwb2x5bGluZSBwb2ludHM9IjAsIDAsIDY1LjUyOTI1NTU1MzAyMywgMzcuODMzMzMzMzMzMzMzLCAwLCA3NS42NjY2NjY2NjY2NjcsIDAsIDAiIGZpbGw9IiNkZGQiIGZpbGwtb3BhY2l0eT0iMC4xNDEzMzMzMzMzMzMzMyIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utb3BhY2l0eT0iMC4wMiIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMzI3LjY0NjI3Nzc2NTExLCAtMzcuODMzMzMzMzMzMzMzKSByb3RhdGUoMCwgMzIuNzY0NjI3Nzc2NTExLCAzNy44MzMzMzMzMzMzMzMpIi8+PHBvbHlsaW5lIHBvaW50cz0iMCwgMCwgNjUuNTI5MjU1NTUzMDIzLCAzNy44MzMzMzMzMzMzMzMsIDAsIDc1LjY2NjY2NjY2NjY2NywgMCwgMCIgZmlsbD0iI2RkZCIgZmlsbC1vcGFjaXR5PSIwLjE0MTMzMzMzMzMzMzMzIiBzdHJva2U9IiMwMDAiIHN0cm9rZS1vcGFjaXR5PSIwLjAyIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgzMjcuNjQ2Mjc3NzY1MTEsIDE4OS4xNjY2NjY2NjY2Nykgcm90YXRlKDAsIDMyLjc2NDYyNzc3NjUxMSwgMzcuODMzMzMzMzMzMzMzKSIvPjxwb2x5bGluZSBwb2ludHM9IjAsIDAsIDY1LjUyOTI1NTU1MzAyMywgMzcuODMzMzMzMzMzMzMzLCAwLCA3NS42NjY2NjY2NjY2NjcsIDAsIDAiIGZpbGw9IiNkZGQiIGZpbGwtb3BhY2l0eT0iMC4wMiIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utb3BhY2l0eT0iMC4wMiIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCwgMCkgcm90YXRlKDAsIDMyLjc2NDYyNzc3NjUxMSwgMzcuODMzMzMzMzMzMzMzKSIvPjxwb2x5bGluZSBwb2ludHM9IjAsIDAsIDY1LjUyOTI1NTU1MzAyMywgMzcuODMzMzMzMzMzMzMzLCAwLCA3NS42NjY2NjY2NjY2NjcsIDAsIDAiIGZpbGw9IiMyMjIiIGZpbGwtb3BhY2l0eT0iMC4wMjg2NjY2NjY2NjY2NjciIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLW9wYWNpdHk9IjAuMDIiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDY1LjUyOTI1NTU1MzAyMywgMCkgcm90YXRlKDE4MCwgMzIuNzY0NjI3Nzc2NTExLCAzNy44MzMzMzMzMzMzMzMpIi8+PHBvbHlsaW5lIHBvaW50cz0iMCwgMCwgNjUuNTI5MjU1NTUzMDIzLCAzNy44MzMzMzMzMzMzMzMsIDAsIDc1LjY2NjY2NjY2NjY2NywgMCwgMCIgZmlsbD0iIzIyMiIgZmlsbC1vcGFjaXR5PSIwLjExNTMzMzMzMzMzMzMzIiBzdHJva2U9IiMwMDAiIHN0cm9rZS1vcGFjaXR5PSIwLjAyIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxMzEuMDU4NTExMTA2MDUsIDApIHJvdGF0ZSgwLCAzMi43NjQ2Mjc3NzY1MTEsIDM3LjgzMzMzMzMzMzMzMykiLz48cG9seWxpbmUgcG9pbnRzPSIwLCAwLCA2NS41MjkyNTU1NTMwMjMsIDM3LjgzMzMzMzMzMzMzMywgMCwgNzUuNjY2NjY2NjY2NjY3LCAwLCAwIiBmaWxsPSIjMjIyIiBmaWxsLW9wYWNpdHk9IjAuMDgwNjY2NjY2NjY2NjY3IiBzdHJva2U9IiMwMDAiIHN0cm9rZS1vcGFjaXR5PSIwLjAyIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxOTYuNTg3NzY2NjU5MDcsIDApIHJvdGF0ZSgxODAsIDMyLjc2NDYyNzc3NjUxMSwgMzcuODMzMzMzMzMzMzMzKSIvPjxwb2x5bGluZSBwb2ludHM9IjAsIDAsIDY1LjUyOTI1NTU1MzAyMywgMzcuODMzMzMzMzMzMzMzLCAwLCA3NS42NjY2NjY2NjY2NjcsIDAsIDAiIGZpbGw9IiMyMjIiIGZpbGwtb3BhY2l0eT0iMC4wODA2NjY2NjY2NjY2NjciIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLW9wYWNpdHk9IjAuMDIiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDI2Mi4xMTcwMjIyMTIwOSwgMCkgcm90YXRlKDAsIDMyLjc2NDYyNzc3NjUxMSwgMzcuODMzMzMzMzMzMzMzKSIvPjxwb2x5bGluZSBwb2ludHM9IjAsIDAsIDY1LjUyOTI1NTU1MzAyMywgMzcuODMzMzMzMzMzMzMzLCAwLCA3NS42NjY2NjY2NjY2NjcsIDAsIDAiIGZpbGw9IiNkZGQiIGZpbGwtb3BhY2l0eT0iMC4wMiIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utb3BhY2l0eT0iMC4wMiIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMzI3LjY0NjI3Nzc2NTExLCAwKSByb3RhdGUoMTgwLCAzMi43NjQ2Mjc3NzY1MTEsIDM3LjgzMzMzMzMzMzMzMykiLz48cG9seWxpbmUgcG9pbnRzPSIwLCAwLCA2NS41MjkyNTU1NTMwMjMsIDM3LjgzMzMzMzMzMzMzMywgMCwgNzUuNjY2NjY2NjY2NjY3LCAwLCAwIiBmaWxsPSIjMjIyIiBmaWxsLW9wYWNpdHk9IjAuMDgwNjY2NjY2NjY2NjY3IiBzdHJva2U9IiMwMDAiIHN0cm9rZS1vcGFjaXR5PSIwLjAyIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwLCAzNy44MzMzMzMzMzMzMzMpIHJvdGF0ZSgxODAsIDMyLjc2NDYyNzc3NjUxMSwgMzcuODMzMzMzMzMzMzMzKSIvPjxwb2x5bGluZSBwb2ludHM9IjAsIDAsIDY1LjUyOTI1NTU1MzAyMywgMzcuODMzMzMzMzMzMzMzLCAwLCA3NS42NjY2NjY2NjY2NjcsIDAsIDAiIGZpbGw9IiNkZGQiIGZpbGwtb3BhY2l0eT0iMC4wMiIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utb3BhY2l0eT0iMC4wMiIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoNjUuNTI5MjU1NTUzMDIzLCAzNy44MzMzMzMzMzMzMzMpIHJvdGF0ZSgwLCAzMi43NjQ2Mjc3NzY1MTEsIDM3LjgzMzMzMzMzMzMzMykiLz48cG9seWxpbmUgcG9pbnRzPSIwLCAwLCA2NS41MjkyNTU1NTMwMjMsIDM3LjgzMzMzMzMzMzMzMywgMCwgNzUuNjY2NjY2NjY2NjY3LCAwLCAwIiBmaWxsPSIjMjIyIiBmaWxsLW9wYWNpdHk9IjAuMDk4IiBzdHJva2U9IiMwMDAiIHN0cm9rZS1vcGFjaXR5PSIwLjAyIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxMzEuMDU4NTExMTA2MDUsIDM3LjgzMzMzMzMzMzMzMykgcm90YXRlKDE4MCwgMzIuNzY0NjI3Nzc2NTExLCAzNy44MzMzMzMzMzMzMzMpIi8+PHBvbHlsaW5lIHBvaW50cz0iMCwgMCwgNjUuNTI5MjU1NTUzMDIzLCAzNy44MzMzMzMzMzMzMzMsIDAsIDc1LjY2NjY2NjY2NjY2NywgMCwgMCIgZmlsbD0iIzIyMiIgZmlsbC1vcGFjaXR5PSIwLjE1IiBzdHJva2U9IiMwMDAiIHN0cm9rZS1vcGFjaXR5PSIwLjAyIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxOTYuNTg3NzY2NjU5MDcsIDM3LjgzMzMzMzMzMzMzMykgcm90YXRlKDAsIDMyLjc2NDYyNzc3NjUxMSwgMzcuODMzMzMzMzMzMzMzKSIvPjxwb2x5bGluZSBwb2ludHM9IjAsIDAsIDY1LjUyOTI1NTU1MzAyMywgMzcuODMzMzMzMzMzMzMzLCAwLCA3NS42NjY2NjY2NjY2NjcsIDAsIDAiIGZpbGw9IiMyMjIiIGZpbGwtb3BhY2l0eT0iMC4wMjg2NjY2NjY2NjY2NjciIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLW9wYWNpdHk9IjAuMDIiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDI2Mi4xMTcwMjIyMTIwOSwgMzcuODMzMzMzMzMzMzMzKSByb3RhdGUoMTgwLCAzMi43NjQ2Mjc3NzY1MTEsIDM3LjgzMzMzMzMzMzMzMykiLz48cG9seWxpbmUgcG9pbnRzPSIwLCAwLCA2NS41MjkyNTU1NTMwMjMsIDM3LjgzMzMzMzMzMzMzMywgMCwgNzUuNjY2NjY2NjY2NjY3LCAwLCAwIiBmaWxsPSIjMjIyIiBmaWxsLW9wYWNpdHk9IjAuMDQ2IiBzdHJva2U9IiMwMDAiIHN0cm9rZS1vcGFjaXR5PSIwLjAyIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgzMjcuNjQ2Mjc3NzY1MTEsIDM3LjgzMzMzMzMzMzMzMykgcm90YXRlKDAsIDMyLjc2NDYyNzc3NjUxMSwgMzcuODMzMzMzMzMzMzMzKSIvPjxwb2x5bGluZSBwb2ludHM9IjAsIDAsIDY1LjUyOTI1NTU1MzAyMywgMzcuODMzMzMzMzMzMzMzLCAwLCA3NS42NjY2NjY2NjY2NjcsIDAsIDAiIGZpbGw9IiNkZGQiIGZpbGwtb3BhY2l0eT0iMC4wMzczMzMzMzMzMzMzMzMiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLW9wYWNpdHk9IjAuMDIiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAsIDc1LjY2NjY2NjY2NjY2Nykgcm90YXRlKDAsIDMyLjc2NDYyNzc3NjUxMSwgMzcuODMzMzMzMzMzMzMzKSIvPjxwb2x5bGluZSBwb2ludHM9IjAsIDAsIDY1LjUyOTI1NTU1MzAyMywgMzcuODMzMzMzMzMzMzMzLCAwLCA3NS42NjY2NjY2NjY2NjcsIDAsIDAiIGZpbGw9IiNkZGQiIGZpbGwtb3BhY2l0eT0iMC4wMiIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utb3BhY2l0eT0iMC4wMiIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoNjUuNTI5MjU1NTUzMDIzLCA3NS42NjY2NjY2NjY2NjcpIHJvdGF0ZSgxODAsIDMyLjc2NDYyNzc3NjUxMSwgMzcuODMzMzMzMzMzMzMzKSIvPjxwb2x5bGluZSBwb2ludHM9IjAsIDAsIDY1LjUyOTI1NTU1MzAyMywgMzcuODMzMzMzMzMzMzMzLCAwLCA3NS42NjY2NjY2NjY2NjcsIDAsIDAiIGZpbGw9IiMyMjIiIGZpbGwtb3BhY2l0eT0iMC4xNSIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utb3BhY2l0eT0iMC4wMiIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMTMxLjA1ODUxMTEwNjA1LCA3NS42NjY2NjY2NjY2NjcpIHJvdGF0ZSgwLCAzMi43NjQ2Mjc3NzY1MTEsIDM3LjgzMzMzMzMzMzMzMykiLz48cG9seWxpbmUgcG9pbnRzPSIwLCAwLCA2NS41MjkyNTU1NTMwMjMsIDM3LjgzMzMzMzMzMzMzMywgMCwgNzUuNjY2NjY2NjY2NjY3LCAwLCAwIiBmaWxsPSIjZGRkIiBmaWxsLW9wYWNpdHk9IjAuMDIiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLW9wYWNpdHk9IjAuMDIiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDE5Ni41ODc3NjY2NTkwNywgNzUuNjY2NjY2NjY2NjY3KSByb3RhdGUoMTgwLCAzMi43NjQ2Mjc3NzY1MTEsIDM3LjgzMzMzMzMzMzMzMykiLz48cG9seWxpbmUgcG9pbnRzPSIwLCAwLCA2NS41MjkyNTU1NTMwMjMsIDM3LjgzMzMzMzMzMzMzMywgMCwgNzUuNjY2NjY2NjY2NjY3LCAwLCAwIiBmaWxsPSIjMjIyIiBmaWxsLW9wYWNpdHk9IjAuMDk4IiBzdHJva2U9IiMwMDAiIHN0cm9rZS1vcGFjaXR5PSIwLjAyIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgyNjIuMTE3MDIyMjEyMDksIDc1LjY2NjY2NjY2NjY2Nykgcm90YXRlKDAsIDMyLjc2NDYyNzc3NjUxMSwgMzcuODMzMzMzMzMzMzMzKSIvPjxwb2x5bGluZSBwb2ludHM9IjAsIDAsIDY1LjUyOTI1NTU1MzAyMywgMzcuODMzMzMzMzMzMzMzLCAwLCA3NS42NjY2NjY2NjY2NjcsIDAsIDAiIGZpbGw9IiMyMjIiIGZpbGwtb3BhY2l0eT0iMC4wNjMzMzMzMzMzMzMzMzMiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLW9wYWNpdHk9IjAuMDIiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDMyNy42NDYyNzc3NjUxMSwgNzUuNjY2NjY2NjY2NjY3KSByb3RhdGUoMTgwLCAzMi43NjQ2Mjc3NzY1MTEsIDM3LjgzMzMzMzMzMzMzMykiLz48cG9seWxpbmUgcG9pbnRzPSIwLCAwLCA2NS41MjkyNTU1NTMwMjMsIDM3LjgzMzMzMzMzMzMzMywgMCwgNzUuNjY2NjY2NjY2NjY3LCAwLCAwIiBmaWxsPSIjZGRkIiBmaWxsLW9wYWNpdHk9IjAuMTI0IiBzdHJva2U9IiMwMDAiIHN0cm9rZS1vcGFjaXR5PSIwLjAyIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwLCAxMTMuNSkgcm90YXRlKDE4MCwgMzIuNzY0NjI3Nzc2NTExLCAzNy44MzMzMzMzMzMzMzMpIi8+PHBvbHlsaW5lIHBvaW50cz0iMCwgMCwgNjUuNTI5MjU1NTUzMDIzLCAzNy44MzMzMzMzMzMzMzMsIDAsIDc1LjY2NjY2NjY2NjY2NywgMCwgMCIgZmlsbD0iIzIyMiIgZmlsbC1vcGFjaXR5PSIwLjE1IiBzdHJva2U9IiMwMDAiIHN0cm9rZS1vcGFjaXR5PSIwLjAyIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSg2NS41MjkyNTU1NTMwMjMsIDExMy41KSByb3RhdGUoMCwgMzIuNzY0NjI3Nzc2NTExLCAzNy44MzMzMzMzMzMzMzMpIi8+PHBvbHlsaW5lIHBvaW50cz0iMCwgMCwgNjUuNTI5MjU1NTUzMDIzLCAzNy44MzMzMzMzMzMzMzMsIDAsIDc1LjY2NjY2NjY2NjY2NywgMCwgMCIgZmlsbD0iI2RkZCIgZmlsbC1vcGFjaXR5PSIwLjEyNCIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utb3BhY2l0eT0iMC4wMiIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMTMxLjA1ODUxMTEwNjA1LCAxMTMuNSkgcm90YXRlKDE4MCwgMzIuNzY0NjI3Nzc2NTExLCAzNy44MzMzMzMzMzMzMzMpIi8+PHBvbHlsaW5lIHBvaW50cz0iMCwgMCwgNjUuNTI5MjU1NTUzMDIzLCAzNy44MzMzMzMzMzMzMzMsIDAsIDc1LjY2NjY2NjY2NjY2NywgMCwgMCIgZmlsbD0iI2RkZCIgZmlsbC1vcGFjaXR5PSIwLjEwNjY2NjY2NjY2NjY3IiBzdHJva2U9IiMwMDAiIHN0cm9rZS1vcGFjaXR5PSIwLjAyIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxOTYuNTg3NzY2NjU5MDcsIDExMy41KSByb3RhdGUoMCwgMzIuNzY0NjI3Nzc2NTExLCAzNy44MzMzMzMzMzMzMzMpIi8+PHBvbHlsaW5lIHBvaW50cz0iMCwgMCwgNjUuNTI5MjU1NTUzMDIzLCAzNy44MzMzMzMzMzMzMzMsIDAsIDc1LjY2NjY2NjY2NjY2NywgMCwgMCIgZmlsbD0iI2RkZCIgZmlsbC1vcGFjaXR5PSIwLjEyNCIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utb3BhY2l0eT0iMC4wMiIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMjYyLjExNzAyMjIxMjA5LCAxMTMuNSkgcm90YXRlKDE4MCwgMzIuNzY0NjI3Nzc2NTExLCAzNy44MzMzMzMzMzMzMzMpIi8+PHBvbHlsaW5lIHBvaW50cz0iMCwgMCwgNjUuNTI5MjU1NTUzMDIzLCAzNy44MzMzMzMzMzMzMzMsIDAsIDc1LjY2NjY2NjY2NjY2NywgMCwgMCIgZmlsbD0iIzIyMiIgZmlsbC1vcGFjaXR5PSIwLjEzMjY2NjY2NjY2NjY3IiBzdHJva2U9IiMwMDAiIHN0cm9rZS1vcGFjaXR5PSIwLjAyIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgzMjcuNjQ2Mjc3NzY1MTEsIDExMy41KSByb3RhdGUoMCwgMzIuNzY0NjI3Nzc2NTExLCAzNy44MzMzMzMzMzMzMzMpIi8+PHBvbHlsaW5lIHBvaW50cz0iMCwgMCwgNjUuNTI5MjU1NTUzMDIzLCAzNy44MzMzMzMzMzMzMzMsIDAsIDc1LjY2NjY2NjY2NjY2NywgMCwgMCIgZmlsbD0iI2RkZCIgZmlsbC1vcGFjaXR5PSIwLjEwNjY2NjY2NjY2NjY3IiBzdHJva2U9IiMwMDAiIHN0cm9rZS1vcGFjaXR5PSIwLjAyIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwLCAxNTEuMzMzMzMzMzMzMzMpIHJvdGF0ZSgwLCAzMi43NjQ2Mjc3NzY1MTEsIDM3LjgzMzMzMzMzMzMzMykiLz48cG9seWxpbmUgcG9pbnRzPSIwLCAwLCA2NS41MjkyNTU1NTMwMjMsIDM3LjgzMzMzMzMzMzMzMywgMCwgNzUuNjY2NjY2NjY2NjY3LCAwLCAwIiBmaWxsPSIjMjIyIiBmaWxsLW9wYWNpdHk9IjAuMDYzMzMzMzMzMzMzMzMzIiBzdHJva2U9IiMwMDAiIHN0cm9rZS1vcGFjaXR5PSIwLjAyIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSg2NS41MjkyNTU1NTMwMjMsIDE1MS4zMzMzMzMzMzMzMykgcm90YXRlKDE4MCwgMzIuNzY0NjI3Nzc2NTExLCAzNy44MzMzMzMzMzMzMzMpIi8+PHBvbHlsaW5lIHBvaW50cz0iMCwgMCwgNjUuNTI5MjU1NTUzMDIzLCAzNy44MzMzMzMzMzMzMzMsIDAsIDc1LjY2NjY2NjY2NjY2NywgMCwgMCIgZmlsbD0iIzIyMiIgZmlsbC1vcGFjaXR5PSIwLjA4MDY2NjY2NjY2NjY2NyIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utb3BhY2l0eT0iMC4wMiIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMTMxLjA1ODUxMTEwNjA1LCAxNTEuMzMzMzMzMzMzMzMpIHJvdGF0ZSgwLCAzMi43NjQ2Mjc3NzY1MTEsIDM3LjgzMzMzMzMzMzMzMykiLz48cG9seWxpbmUgcG9pbnRzPSIwLCAwLCA2NS41MjkyNTU1NTMwMjMsIDM3LjgzMzMzMzMzMzMzMywgMCwgNzUuNjY2NjY2NjY2NjY3LCAwLCAwIiBmaWxsPSIjZGRkIiBmaWxsLW9wYWNpdHk9IjAuMDIiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLW9wYWNpdHk9IjAuMDIiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDE5Ni41ODc3NjY2NTkwNywgMTUxLjMzMzMzMzMzMzMzKSByb3RhdGUoMTgwLCAzMi43NjQ2Mjc3NzY1MTEsIDM3LjgzMzMzMzMzMzMzMykiLz48cG9seWxpbmUgcG9pbnRzPSIwLCAwLCA2NS41MjkyNTU1NTMwMjMsIDM3LjgzMzMzMzMzMzMzMywgMCwgNzUuNjY2NjY2NjY2NjY3LCAwLCAwIiBmaWxsPSIjMjIyIiBmaWxsLW9wYWNpdHk9IjAuMDk4IiBzdHJva2U9IiMwMDAiIHN0cm9rZS1vcGFjaXR5PSIwLjAyIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgyNjIuMTE3MDIyMjEyMDksIDE1MS4zMzMzMzMzMzMzMykgcm90YXRlKDAsIDMyLjc2NDYyNzc3NjUxMSwgMzcuODMzMzMzMzMzMzMzKSIvPjxwb2x5bGluZSBwb2ludHM9IjAsIDAsIDY1LjUyOTI1NTU1MzAyMywgMzcuODMzMzMzMzMzMzMzLCAwLCA3NS42NjY2NjY2NjY2NjcsIDAsIDAiIGZpbGw9IiNkZGQiIGZpbGwtb3BhY2l0eT0iMC4xMjQiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLW9wYWNpdHk9IjAuMDIiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDMyNy42NDYyNzc3NjUxMSwgMTUxLjMzMzMzMzMzMzMzKSByb3RhdGUoMTgwLCAzMi43NjQ2Mjc3NzY1MTEsIDM3LjgzMzMzMzMzMzMzMykiLz48L3N2Zz4=');"></div> | ||
13 | + <div class="carousel-body"> | ||
14 | + <div class="container"> | ||
15 | + <h1 class="display-1 text-white">开发示例</h1> | ||
16 | + <h2 class="display-4 text-white">表格、登录相关示例</h2> | ||
17 | + </div> | ||
18 | + </div> | ||
19 | + </a> | ||
20 | + </div> | ||
21 | + </div> | ||
22 | +</header> | ||
23 | + | ||
24 | +<!-- Page Content --> | ||
25 | +<div class="container"> | ||
26 | + | ||
27 | + <!-- Marketing Icons Section --> | ||
28 | + <div class="row"> | ||
29 | + <div class="col-lg-12"> | ||
30 | + <h2 class="page-header"> | ||
31 | + 基础模块 | ||
32 | + </h2> | ||
33 | + </div> | ||
34 | + <div class="col-md-4"> | ||
35 | + <div class="panel panel-default"> | ||
36 | + <div class="panel-heading"> | ||
37 | + <h4><i class="fa fa-fw fa-user"></i> 前台模块</h4> | ||
38 | + </div> | ||
39 | + <div class="panel-body"> | ||
40 | + <p>前台模块中包含基础的会员模块,前台模块中的会员账号和API模块中的会员账号是同一账号体系</p> | ||
41 | + <a href="{:url('index/index/index')}" target="_blank" class="btn btn-primary">立即访问</a> | ||
42 | + <a href="{:url('index/user/index')}" target="_blank" class="btn btn-default">会员中心</a> | ||
43 | + </div> | ||
44 | + </div> | ||
45 | + </div> | ||
46 | + <div class="col-md-4"> | ||
47 | + <div class="panel panel-default"> | ||
48 | + <div class="panel-heading"> | ||
49 | + <h4><i class="fa fa-fw fa-gift"></i> API模块</h4> | ||
50 | + </div> | ||
51 | + <div class="panel-body"> | ||
52 | + <p>API模块中包含基础的会员模块,初始化模块、短信发送模块、验证模块</p> | ||
53 | + <a href="{:url('api/index/index')}" target="_blank" class="btn btn-primary">立即访问</a> | ||
54 | + <a href="{:url('api/common/init')}?version=1.0.0" target="_blank" class="btn btn-default">初始化接口</a> | ||
55 | + </div> | ||
56 | + </div> | ||
57 | + </div> | ||
58 | + <div class="col-md-4"> | ||
59 | + <div class="panel panel-default"> | ||
60 | + <div class="panel-heading"> | ||
61 | + <h4><i class="fa fa-fw fa-compass"></i> API文档</h4> | ||
62 | + </div> | ||
63 | + <div class="panel-body"> | ||
64 | + <p>当写完API接口以后,可通过执行php think api一键生成我们所需要的API文档,并且可以直接在线测试</p> | ||
65 | + <a href="{:url('/')}api.html" target="_blank" class="btn btn-primary">立即访问</a> | ||
66 | + </div> | ||
67 | + </div> | ||
68 | + </div> | ||
69 | + </div> | ||
70 | + <div class="row"> | ||
71 | + <div class="col-lg-12"> | ||
72 | + <h2 class="page-header"> | ||
73 | + 功能示例 | ||
74 | + </h2> | ||
75 | + </div> | ||
76 | + <div class="col-md-4"> | ||
77 | + <div class="panel panel-default"> | ||
78 | + <div class="panel-heading"> | ||
79 | + <h4><i class="fa fa-fw fa-check"></i> 使用模板标签和变量</h4> | ||
80 | + </div> | ||
81 | + <div class="panel-body"> | ||
82 | + <a href="{:addon_url('example/demo/index',[':name'=>'s1'])}" class="btn btn-success">查看示例</a> | ||
83 | + </div> | ||
84 | + </div> | ||
85 | + </div> | ||
86 | + <div class="col-md-4"> | ||
87 | + <div class="panel panel-default"> | ||
88 | + <div class="panel-heading"> | ||
89 | + <h4><i class="fa fa-fw fa-gift"></i> 访问不需要登录的页面</h4> | ||
90 | + </div> | ||
91 | + <div class="panel-body"> | ||
92 | + <a href="{:addon_url('example/demo/demo1',[':name'=>'s2'])}" class="btn btn-success">立即访问</a> | ||
93 | + </div> | ||
94 | + </div> | ||
95 | + </div> | ||
96 | + <div class="col-md-4"> | ||
97 | + <div class="panel panel-default"> | ||
98 | + <div class="panel-heading"> | ||
99 | + <h4><i class="fa fa-fw fa-compass"></i> 访问需要登录的页面</h4> | ||
100 | + </div> | ||
101 | + <div class="panel-body"> | ||
102 | + <a href="{:addon_url('example/demo/demo2',[':name'=>'s3'])}" class="btn btn-success">立即访问</a> | ||
103 | + </div> | ||
104 | + </div> | ||
105 | + </div> | ||
106 | + </div> | ||
107 | + <!-- /.row --> | ||
108 | + | ||
109 | + <hr> | ||
110 | + | ||
111 | +</div> |
addons/example/view/layout/default.html
0 → 100755
1 | +<!DOCTYPE html> | ||
2 | +<html lang="en"> | ||
3 | + | ||
4 | + <head> | ||
5 | + | ||
6 | + <meta charset="utf-8"> | ||
7 | + <meta http-equiv="X-UA-Compatible" content="IE=edge"> | ||
8 | + <meta name="viewport" content="width=device-width, initial-scale=1"> | ||
9 | + <meta name="description" content=""> | ||
10 | + <meta name="author" content=""> | ||
11 | + | ||
12 | + <title>开发示例 - {$site.name|htmlentities}</title> | ||
13 | + | ||
14 | + <!-- Bootstrap Core CSS --> | ||
15 | + <link href="__CDN__/assets/libs/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet"> | ||
16 | + | ||
17 | + <!-- Custom CSS --> | ||
18 | + <link href="__ADDON__/css/common.css" rel="stylesheet"> | ||
19 | + | ||
20 | + <!-- Custom Fonts --> | ||
21 | + <link href="__CDN__/assets/libs/font-awesome/css/font-awesome.min.css" rel="stylesheet"> | ||
22 | + | ||
23 | + <!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries --> | ||
24 | + <!-- WARNING: Respond.js doesn't work if you view the page via file:// --> | ||
25 | + <!--[if lt IE 9]> | ||
26 | + <script src="https://cdn.bootcdn.net/ajax/libs/html5shiv/3.7.0/html5shiv.min.js"></script> | ||
27 | + <script src="https://cdn.bootcdn.net/ajax/libs/respond.js/1.4.2/respond.min.js"></script> | ||
28 | + <![endif]--> | ||
29 | + | ||
30 | + </head> | ||
31 | + | ||
32 | + <body> | ||
33 | + | ||
34 | + <!-- Navigation --> | ||
35 | + <nav class="navbar navbar-inverse navbar-fixed-top" role="navigation"> | ||
36 | + <div class="container"> | ||
37 | + <!-- Brand and toggle get grouped for better mobile display --> | ||
38 | + <div class="navbar-header"> | ||
39 | + <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1"> | ||
40 | + <span class="sr-only">Toggle navigation</span> | ||
41 | + <span class="icon-bar"></span> | ||
42 | + <span class="icon-bar"></span> | ||
43 | + <span class="icon-bar"></span> | ||
44 | + </button> | ||
45 | + <a class="navbar-brand" href="{:addon_url('example/index/index')}">{$site.name|htmlentities}</a> | ||
46 | + </div> | ||
47 | + <!-- Collect the nav links, forms, and other content for toggling --> | ||
48 | + <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1"> | ||
49 | + <ul class="nav navbar-nav navbar-right"> | ||
50 | + <li> | ||
51 | + <a href="{:addon_url('example/index/index')}">插件首页</a> | ||
52 | + </li> | ||
53 | + <li> | ||
54 | + <a href="{:addon_url('example/demo/demo1', [':name'=>'s1'])}">无需登录页面</a> | ||
55 | + </li> | ||
56 | + <li> | ||
57 | + <a href="{:addon_url('example/demo/demo2', [':name'=>'s2'])}">需登录页面</a> | ||
58 | + </li> | ||
59 | + {if $user} | ||
60 | + <li class="dropdown"> | ||
61 | + <a href="#" class="dropdown-toggle" data-toggle="dropdown">欢迎你! {$user.nickname|htmlentities}<b class="caret"></b></a> | ||
62 | + <ul class="dropdown-menu"> | ||
63 | + <li> | ||
64 | + <a href="{:url('index/user/index')}">会员中心</a> | ||
65 | + </li> | ||
66 | + <li> | ||
67 | + <a href="{:url('index/user/profile')}">个人资料</a> | ||
68 | + </li> | ||
69 | + <li> | ||
70 | + <a href="{:url('index/user/logout')}">退出登录</a> | ||
71 | + </li> | ||
72 | + </ul> | ||
73 | + </li> | ||
74 | + {else /} | ||
75 | + <li class="dropdown"> | ||
76 | + <a href="#" class="dropdown-toggle" data-toggle="dropdown">会员中心 <b class="caret"></b></a> | ||
77 | + <ul class="dropdown-menu"> | ||
78 | + <li> | ||
79 | + <a href="{:url('index/user/login')}">登录</a> | ||
80 | + </li> | ||
81 | + <li> | ||
82 | + <a href="{:url('index/user/register')}">注册</a> | ||
83 | + </li> | ||
84 | + </ul> | ||
85 | + </li> | ||
86 | + {/if} | ||
87 | + </ul> | ||
88 | + </div> | ||
89 | + <!-- /.navbar-collapse --> | ||
90 | + </div> | ||
91 | + <!-- /.container --> | ||
92 | + </nav> | ||
93 | + | ||
94 | + {__CONTENT__} | ||
95 | + | ||
96 | + <div class="container"> | ||
97 | + <!-- Footer --> | ||
98 | + <footer> | ||
99 | + <div class="row"> | ||
100 | + <div class="col-lg-12"> | ||
101 | + <p>Copyright © {$site.name|htmlentities} 2022</p> | ||
102 | + </div> | ||
103 | + </div> | ||
104 | + </footer> | ||
105 | + | ||
106 | + </div> | ||
107 | + <!-- /.container --> | ||
108 | + | ||
109 | + <!-- jQuery --> | ||
110 | + <script src="__CDN__/assets/libs/jquery/dist/jquery.min.js"></script> | ||
111 | + | ||
112 | + <!-- Bootstrap Core JavaScript --> | ||
113 | + <script src="__CDN__/assets/libs/bootstrap/dist/js/bootstrap.min.js"></script> | ||
114 | + | ||
115 | + <!-- Script to Activate the Carousel --> | ||
116 | + <script> | ||
117 | + $('.carousel').carousel({ | ||
118 | + interval: 5000 //changes the speed | ||
119 | + }) | ||
120 | + </script> | ||
121 | + | ||
122 | + </body> | ||
123 | + | ||
124 | +</html> |
addons/simditor/.addonrc
0 → 100755
1 | +{"files":["public\\assets\\addons\\simditor\\css\\simditor.min.css","public\\assets\\addons\\simditor\\images\\image.png","public\\assets\\addons\\simditor\\js\\simditor.min.js"],"license":"regular","licenseto":"15629","licensekey":"0bng3VGoD9JSQWKx i7JCSMq8KNNUA9vhGkgbYQ==","domains":["cardverification.com"],"licensecodes":[],"validations":["867a7ee97b89c3a1f31235c70da23ecf"]} |
addons/simditor/Simditor.php
0 → 100755
1 | +<?php | ||
2 | + | ||
3 | +namespace addons\simditor; | ||
4 | + | ||
5 | +use app\common\library\Menu; | ||
6 | +use think\Addons; | ||
7 | + | ||
8 | +/** | ||
9 | + * 插件 | ||
10 | + */ | ||
11 | +class Simditor extends Addons | ||
12 | +{ | ||
13 | + | ||
14 | + /** | ||
15 | + * 插件安装方法 | ||
16 | + * @return bool | ||
17 | + */ | ||
18 | + public function install() | ||
19 | + { | ||
20 | + return true; | ||
21 | + } | ||
22 | + | ||
23 | + /** | ||
24 | + * 插件卸载方法 | ||
25 | + * @return bool | ||
26 | + */ | ||
27 | + public function uninstall() | ||
28 | + { | ||
29 | + return true; | ||
30 | + } | ||
31 | + | ||
32 | + public function upgrade() | ||
33 | + { | ||
34 | + return true; | ||
35 | + } | ||
36 | + | ||
37 | + /** | ||
38 | + * @param $params | ||
39 | + */ | ||
40 | + public function configInit(&$params) | ||
41 | + { | ||
42 | + $config = $this->getConfig(); | ||
43 | + $params['simditor'] = ['classname' => $config['classname'] ?? '.editor']; | ||
44 | + } | ||
45 | + | ||
46 | +} |
addons/simditor/bootstrap.js
0 → 100755
1 | +require.config({ | ||
2 | + paths: { | ||
3 | + 'simditor': '../addons/simditor/js/simditor.min', | ||
4 | + }, | ||
5 | + shim: { | ||
6 | + 'simditor': [ | ||
7 | + 'css!../addons/simditor/css/simditor.min.css', | ||
8 | + ] | ||
9 | + } | ||
10 | +}); | ||
11 | +require(['form'], function (Form) { | ||
12 | + var _bindevent = Form.events.bindevent; | ||
13 | + Form.events.bindevent = function (form) { | ||
14 | + _bindevent.apply(this, [form]); | ||
15 | + if ($(Config.simditor.classname || '.editor', form).size() > 0) { | ||
16 | + //修改上传的接口调用 | ||
17 | + require(['upload', 'simditor'], function (Upload, Simditor) { | ||
18 | + var editor, mobileToolbar, toolbar; | ||
19 | + Simditor.locale = 'zh-CN'; | ||
20 | + Simditor.list = {}; | ||
21 | + toolbar = ['title', 'bold', 'italic', 'underline', 'strikethrough', 'fontScale', 'color', '|', 'ol', 'ul', 'blockquote', 'code', 'table', '|', 'link', 'image', 'hr', '|', 'indent', 'outdent', 'alignment']; | ||
22 | + mobileToolbar = ["bold", "underline", "strikethrough", "color", "ul", "ol"]; | ||
23 | + $(Config.simditor.classname || '.editor', form).each(function () { | ||
24 | + var id = $(this).attr("id"); | ||
25 | + editor = new Simditor({ | ||
26 | + textarea: this, | ||
27 | + toolbarFloat: false, | ||
28 | + toolbar: toolbar, | ||
29 | + pasteImage: true, | ||
30 | + defaultImage: Config.__CDN__ + '/assets/addons/simditor/images/image.png', | ||
31 | + upload: {url: '/'}, | ||
32 | + allowedTags: ['div', 'br', 'span', 'a', 'img', 'b', 'strong', 'i', 'strike', 'u', 'font', 'p', 'ul', 'ol', 'li', 'blockquote', 'pre', 'code', 'h1', 'h2', 'h3', 'h4', 'hr'], | ||
33 | + allowedAttributes: { | ||
34 | + div: ['data-tpl', 'data-source', 'data-id'], | ||
35 | + span: ['data-id'] | ||
36 | + }, | ||
37 | + allowedStyles: { | ||
38 | + div: ['width', 'height', 'padding', 'background', 'color', 'display', 'justify-content', 'border', 'box-sizing', 'max-width', 'min-width', 'position', 'margin-left', 'bottom', 'left', 'margin', 'float'], | ||
39 | + p: ['margin', 'color', 'height', 'line-height', 'position', 'width', 'border', 'bottom', 'float'], | ||
40 | + span: ['text-decoration', 'color', 'margin-left', 'float', 'background', 'padding', 'margin-right', 'border-radius', 'font-size', 'border', 'float'], | ||
41 | + img: ['vertical-align', 'width', 'height', 'object-fit', 'float', 'margin', 'float'], | ||
42 | + a: ['text-decoration'] | ||
43 | + } | ||
44 | + }); | ||
45 | + editor.uploader.on('beforeupload', function (e, file) { | ||
46 | + Upload.api.send(file.obj, function (data) { | ||
47 | + var url = Fast.api.cdnurl(data.url); | ||
48 | + editor.uploader.trigger("uploadsuccess", [file, {success: true, file_path: url}]); | ||
49 | + }); | ||
50 | + return false; | ||
51 | + }); | ||
52 | + editor.on("blur", function () { | ||
53 | + this.textarea.trigger("blur"); | ||
54 | + }); | ||
55 | + Simditor.list[id] = editor; | ||
56 | + }); | ||
57 | + }); | ||
58 | + } | ||
59 | + } | ||
60 | +}); |
addons/simditor/build/build.sh
0 → 100755
addons/simditor/build/css.js
0 → 100755
addons/simditor/build/js.js
0 → 100755
addons/simditor/build/r.js
0 → 100755
此 diff 太大无法显示。
addons/simditor/config.php
0 → 100755
addons/simditor/info.ini
0 → 100755
addons/simditor/src/css/mobile.css
0 → 100755
1 | +@media screen and (max-device-width: 240px) and (min-device-width: 220px) { | ||
2 | + body { | ||
3 | + width: 240px; | ||
4 | + margin: 0 auto; | ||
5 | + } | ||
6 | + body .wrapper { | ||
7 | + width: 100%; | ||
8 | + } | ||
9 | + body .wrapper header { | ||
10 | + padding: 30px 0 20px; | ||
11 | + } | ||
12 | + body .wrapper header h1 { | ||
13 | + background-size: 200px auto; | ||
14 | + background-position: 50px 0; | ||
15 | + padding-top: 90px; | ||
16 | + height: 45px; | ||
17 | + } | ||
18 | + body .wrapper header h1 a { | ||
19 | + background-size: 160px auto; | ||
20 | + background-position: 10px 0; | ||
21 | + } | ||
22 | + body .wrapper header p.desc { | ||
23 | + font-size: 16px; | ||
24 | + } | ||
25 | + body .wrapper footer { | ||
26 | + margin: 20px 0; | ||
27 | + } | ||
28 | + body .wrapper #page-demo { | ||
29 | + width: 96%; | ||
30 | + margin: 0 2%; | ||
31 | + } | ||
32 | + body .wrapper #link-fork { | ||
33 | + z-index: -1; | ||
34 | + width: 80px; | ||
35 | + height: auto; | ||
36 | + } | ||
37 | + body .wrapper #link-fork img { | ||
38 | + max-width: 80px; | ||
39 | + height: auto; | ||
40 | + } | ||
41 | + | ||
42 | + nav { | ||
43 | + display: none; | ||
44 | + } | ||
45 | +} | ||
46 | +@media screen and (max-device-width: 320px) and (min-device-width: 300px) { | ||
47 | + body { | ||
48 | + width: 320px; | ||
49 | + margin: 0 auto; | ||
50 | + } | ||
51 | + body .wrapper { | ||
52 | + width: 100%; | ||
53 | + } | ||
54 | + body .wrapper header { | ||
55 | + padding: 30px 0 20px; | ||
56 | + } | ||
57 | + body .wrapper header h1 { | ||
58 | + background-size: 200px auto; | ||
59 | + background-position: 50px 0; | ||
60 | + padding-top: 90px; | ||
61 | + height: 45px; | ||
62 | + } | ||
63 | + body .wrapper header h1 a { | ||
64 | + background-size: 160px auto; | ||
65 | + background-position: 10px 0; | ||
66 | + } | ||
67 | + body .wrapper header p.desc { | ||
68 | + font-size: 16px; | ||
69 | + } | ||
70 | + body .wrapper footer { | ||
71 | + margin: 20px 0; | ||
72 | + } | ||
73 | + body .wrapper #page-demo { | ||
74 | + width: 96%; | ||
75 | + margin: 0 2%; | ||
76 | + } | ||
77 | + body .wrapper #link-fork { | ||
78 | + z-index: -1; | ||
79 | + width: 80px; | ||
80 | + height: auto; | ||
81 | + } | ||
82 | + body .wrapper #link-fork img { | ||
83 | + max-width: 80px; | ||
84 | + height: auto; | ||
85 | + } | ||
86 | + | ||
87 | + nav { | ||
88 | + display: none; | ||
89 | + } | ||
90 | +} | ||
91 | +@media screen and (max-device-width: 360px) and (min-device-width: 340px) { | ||
92 | + body { | ||
93 | + width: 360px; | ||
94 | + margin: 0 auto; | ||
95 | + } | ||
96 | + body .wrapper { | ||
97 | + width: 100%; | ||
98 | + } | ||
99 | + body .wrapper header { | ||
100 | + padding: 30px 0 20px; | ||
101 | + } | ||
102 | + body .wrapper header h1 { | ||
103 | + background-size: 200px auto; | ||
104 | + background-position: 50px 0; | ||
105 | + padding-top: 90px; | ||
106 | + height: 45px; | ||
107 | + } | ||
108 | + body .wrapper header h1 a { | ||
109 | + background-size: 160px auto; | ||
110 | + background-position: 10px 0; | ||
111 | + } | ||
112 | + body .wrapper header p.desc { | ||
113 | + font-size: 16px; | ||
114 | + } | ||
115 | + body .wrapper footer { | ||
116 | + margin: 20px 0; | ||
117 | + } | ||
118 | + body .wrapper #page-demo { | ||
119 | + width: 96%; | ||
120 | + margin: 0 2%; | ||
121 | + } | ||
122 | + body .wrapper #link-fork { | ||
123 | + z-index: -1; | ||
124 | + width: 80px; | ||
125 | + height: auto; | ||
126 | + } | ||
127 | + body .wrapper #link-fork img { | ||
128 | + max-width: 80px; | ||
129 | + height: auto; | ||
130 | + } | ||
131 | + | ||
132 | + nav { | ||
133 | + display: none; | ||
134 | + } | ||
135 | +} | ||
136 | +@media screen and (max-device-width: 480px) and (min-device-width: 460px) { | ||
137 | + body { | ||
138 | + width: 480px; | ||
139 | + margin: 0 auto; | ||
140 | + } | ||
141 | + body .wrapper { | ||
142 | + width: 100%; | ||
143 | + } | ||
144 | + body .wrapper header { | ||
145 | + padding: 30px 0 20px; | ||
146 | + } | ||
147 | + body .wrapper header h1 { | ||
148 | + background-size: 200px auto; | ||
149 | + background-position: 50px 0; | ||
150 | + padding-top: 90px; | ||
151 | + height: 45px; | ||
152 | + } | ||
153 | + body .wrapper header h1 a { | ||
154 | + background-size: 160px auto; | ||
155 | + background-position: 10px 0; | ||
156 | + } | ||
157 | + body .wrapper header p.desc { | ||
158 | + font-size: 16px; | ||
159 | + } | ||
160 | + body .wrapper footer { | ||
161 | + margin: 20px 0; | ||
162 | + } | ||
163 | + body .wrapper #page-demo { | ||
164 | + width: 96%; | ||
165 | + margin: 0 2%; | ||
166 | + } | ||
167 | + body .wrapper #link-fork { | ||
168 | + z-index: -1; | ||
169 | + width: 80px; | ||
170 | + height: auto; | ||
171 | + } | ||
172 | + body .wrapper #link-fork img { | ||
173 | + max-width: 80px; | ||
174 | + height: auto; | ||
175 | + } | ||
176 | + | ||
177 | + nav { | ||
178 | + display: none; | ||
179 | + } | ||
180 | +} | ||
181 | +@media screen and (max-device-width: 640px) and (min-device-width: 620px) { | ||
182 | + body { | ||
183 | + width: 320px; | ||
184 | + margin: 0 auto; | ||
185 | + } | ||
186 | + body .wrapper { | ||
187 | + width: 100%; | ||
188 | + } | ||
189 | + body .wrapper header { | ||
190 | + padding: 30px 0 20px; | ||
191 | + } | ||
192 | + body .wrapper header h1 { | ||
193 | + background-size: 200px auto; | ||
194 | + background-position: 50px 0; | ||
195 | + padding-top: 90px; | ||
196 | + height: 45px; | ||
197 | + } | ||
198 | + body .wrapper header h1 a { | ||
199 | + background-size: 160px auto; | ||
200 | + background-position: 10px 0; | ||
201 | + } | ||
202 | + body .wrapper header p.desc { | ||
203 | + font-size: 16px; | ||
204 | + } | ||
205 | + body .wrapper footer { | ||
206 | + margin: 20px 0; | ||
207 | + } | ||
208 | + body .wrapper #page-demo { | ||
209 | + width: 96%; | ||
210 | + margin: 0 2%; | ||
211 | + } | ||
212 | + body .wrapper #link-fork { | ||
213 | + z-index: -1; | ||
214 | + width: 80px; | ||
215 | + height: auto; | ||
216 | + } | ||
217 | + body .wrapper #link-fork img { | ||
218 | + max-width: 80px; | ||
219 | + height: auto; | ||
220 | + } | ||
221 | + | ||
222 | + nav { | ||
223 | + display: none; | ||
224 | + } | ||
225 | +} | ||
226 | +@media screen and (max-device-width: 720px) and (min-device-width: 700px) { | ||
227 | + body { | ||
228 | + width: 360px; | ||
229 | + margin: 0 auto; | ||
230 | + } | ||
231 | + body .wrapper { | ||
232 | + width: 100%; | ||
233 | + } | ||
234 | + body .wrapper header { | ||
235 | + padding: 30px 0 20px; | ||
236 | + } | ||
237 | + body .wrapper header h1 { | ||
238 | + background-size: 200px auto; | ||
239 | + background-position: 50px 0; | ||
240 | + padding-top: 90px; | ||
241 | + height: 45px; | ||
242 | + } | ||
243 | + body .wrapper header h1 a { | ||
244 | + background-size: 160px auto; | ||
245 | + background-position: 10px 0; | ||
246 | + } | ||
247 | + body .wrapper header p.desc { | ||
248 | + font-size: 16px; | ||
249 | + } | ||
250 | + body .wrapper footer { | ||
251 | + margin: 20px 0; | ||
252 | + } | ||
253 | + body .wrapper #page-demo { | ||
254 | + width: 96%; | ||
255 | + margin: 0 2%; | ||
256 | + } | ||
257 | + body .wrapper #link-fork { | ||
258 | + z-index: -1; | ||
259 | + width: 80px; | ||
260 | + height: auto; | ||
261 | + } | ||
262 | + body .wrapper #link-fork img { | ||
263 | + max-width: 80px; | ||
264 | + height: auto; | ||
265 | + } | ||
266 | + | ||
267 | + nav { | ||
268 | + display: none; | ||
269 | + } | ||
270 | +} | ||
271 | +@media screen and (max-device-width: 800px) and (min-device-width: 780px) { | ||
272 | + body { | ||
273 | + width: 400px; | ||
274 | + margin: 0 auto; | ||
275 | + } | ||
276 | + body .wrapper { | ||
277 | + width: 100%; | ||
278 | + } | ||
279 | + body .wrapper header { | ||
280 | + padding: 30px 0 20px; | ||
281 | + } | ||
282 | + body .wrapper header h1 { | ||
283 | + background-size: 200px auto; | ||
284 | + background-position: 50px 0; | ||
285 | + padding-top: 90px; | ||
286 | + height: 45px; | ||
287 | + } | ||
288 | + body .wrapper header h1 a { | ||
289 | + background-size: 160px auto; | ||
290 | + background-position: 10px 0; | ||
291 | + } | ||
292 | + body .wrapper header p.desc { | ||
293 | + font-size: 16px; | ||
294 | + } | ||
295 | + body .wrapper footer { | ||
296 | + margin: 20px 0; | ||
297 | + } | ||
298 | + body .wrapper #page-demo { | ||
299 | + width: 96%; | ||
300 | + margin: 0 2%; | ||
301 | + } | ||
302 | + body .wrapper #link-fork { | ||
303 | + z-index: -1; | ||
304 | + width: 88.8888888889px; | ||
305 | + height: auto; | ||
306 | + } | ||
307 | + body .wrapper #link-fork img { | ||
308 | + max-width: 88.8888888889px; | ||
309 | + height: auto; | ||
310 | + } | ||
311 | + | ||
312 | + nav { | ||
313 | + display: none; | ||
314 | + } | ||
315 | +} | ||
316 | +@media screen and (max-device-width: 960px) and (min-device-width: 940px) { | ||
317 | + body { | ||
318 | + width: 480px; | ||
319 | + margin: 0 auto; | ||
320 | + } | ||
321 | + body .wrapper { | ||
322 | + width: 100%; | ||
323 | + } | ||
324 | + body .wrapper header { | ||
325 | + padding: 30px 0 20px; | ||
326 | + } | ||
327 | + body .wrapper header h1 { | ||
328 | + background-size: 200px auto; | ||
329 | + background-position: 50px 0; | ||
330 | + padding-top: 90px; | ||
331 | + height: 45px; | ||
332 | + } | ||
333 | + body .wrapper header h1 a { | ||
334 | + background-size: 160px auto; | ||
335 | + background-position: 10px 0; | ||
336 | + } | ||
337 | + body .wrapper header p.desc { | ||
338 | + font-size: 16px; | ||
339 | + } | ||
340 | + body .wrapper footer { | ||
341 | + margin: 20px 0; | ||
342 | + } | ||
343 | + body .wrapper #page-demo { | ||
344 | + width: 96%; | ||
345 | + margin: 0 2%; | ||
346 | + } | ||
347 | + body .wrapper #link-fork { | ||
348 | + z-index: -1; | ||
349 | + width: 100px; | ||
350 | + height: auto; | ||
351 | + } | ||
352 | + body .wrapper #link-fork img { | ||
353 | + max-width: 100px; | ||
354 | + height: auto; | ||
355 | + } | ||
356 | + | ||
357 | + nav { | ||
358 | + display: none; | ||
359 | + } | ||
360 | +} | ||
361 | +@media screen and (max-device-width: 1024px) and (min-device-width: 1004px) { | ||
362 | + body { | ||
363 | + width: 512px; | ||
364 | + margin: 0 auto; | ||
365 | + } | ||
366 | + body .wrapper { | ||
367 | + width: 100%; | ||
368 | + } | ||
369 | + body .wrapper header { | ||
370 | + padding: 30px 0 20px; | ||
371 | + } | ||
372 | + body .wrapper header h1 { | ||
373 | + background-size: 200px auto; | ||
374 | + background-position: 50px 0; | ||
375 | + padding-top: 90px; | ||
376 | + height: 45px; | ||
377 | + } | ||
378 | + body .wrapper header h1 a { | ||
379 | + background-size: 160px auto; | ||
380 | + background-position: 10px 0; | ||
381 | + } | ||
382 | + body .wrapper header p.desc { | ||
383 | + font-size: 16px; | ||
384 | + } | ||
385 | + body .wrapper footer { | ||
386 | + margin: 20px 0; | ||
387 | + } | ||
388 | + body .wrapper #page-demo { | ||
389 | + width: 96%; | ||
390 | + margin: 0 2%; | ||
391 | + } | ||
392 | + body .wrapper #link-fork { | ||
393 | + z-index: -1; | ||
394 | + width: 100px; | ||
395 | + height: auto; | ||
396 | + } | ||
397 | + body .wrapper #link-fork img { | ||
398 | + max-width: 100px; | ||
399 | + height: auto; | ||
400 | + } | ||
401 | + | ||
402 | + nav { | ||
403 | + display: none; | ||
404 | + } | ||
405 | +} | ||
406 | +@media screen and (max-device-width: 1280px) and (min-device-width: 1260px) { | ||
407 | + body { | ||
408 | + width: 640px; | ||
409 | + margin: 0 auto; | ||
410 | + } | ||
411 | + body .wrapper { | ||
412 | + width: 100%; | ||
413 | + } | ||
414 | + body .wrapper header { | ||
415 | + padding: 30px 0 20px; | ||
416 | + } | ||
417 | + body .wrapper header h1 { | ||
418 | + background-size: 200px auto; | ||
419 | + background-position: 50px 0; | ||
420 | + padding-top: 90px; | ||
421 | + height: 45px; | ||
422 | + } | ||
423 | + body .wrapper header h1 a { | ||
424 | + background-size: 160px auto; | ||
425 | + background-position: 10px 0; | ||
426 | + } | ||
427 | + body .wrapper header p.desc { | ||
428 | + font-size: 16px; | ||
429 | + } | ||
430 | + body .wrapper footer { | ||
431 | + margin: 20px 0; | ||
432 | + } | ||
433 | + body .wrapper #page-demo { | ||
434 | + width: 96%; | ||
435 | + margin: 0 2%; | ||
436 | + } | ||
437 | + body .wrapper #link-fork { | ||
438 | + z-index: -1; | ||
439 | + width: 100px; | ||
440 | + height: auto; | ||
441 | + } | ||
442 | + body .wrapper #link-fork img { | ||
443 | + max-width: 100px; | ||
444 | + height: auto; | ||
445 | + } | ||
446 | + | ||
447 | + nav { | ||
448 | + display: none; | ||
449 | + } | ||
450 | +} | ||
451 | +@media screen and (device-aspect-ratio: 40 / 71) and (orientation: landscape) { | ||
452 | + body { | ||
453 | + width: 568px; | ||
454 | + } | ||
455 | +} | ||
456 | +@media screen and (device-aspect-ratio: 2 / 3) and (orientation: landscape) { | ||
457 | + body { | ||
458 | + width: 480px; | ||
459 | + } | ||
460 | +} |
addons/simditor/src/css/simditor.css
0 → 100755
1 | +@font-face { | ||
2 | + font-family: 'Simditor'; | ||
3 | + src: url(data:application/font-woff;charset=utf-8;base64,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) format("woff"); | ||
4 | + font-weight: normal; | ||
5 | + font-style: normal; | ||
6 | +} | ||
7 | +.simditor-icon { | ||
8 | + display: inline-block; | ||
9 | + font: normal normal normal 14px/1 'Simditor'; | ||
10 | + font-size: inherit; | ||
11 | + text-rendering: auto; | ||
12 | + -webkit-font-smoothing: antialiased; | ||
13 | + -moz-osx-font-smoothing: grayscale; | ||
14 | + transform: translate(0, 0); | ||
15 | +} | ||
16 | + | ||
17 | +.simditor-icon-code:before { | ||
18 | + content: '\f000'; | ||
19 | +} | ||
20 | + | ||
21 | +.simditor-icon-bold:before { | ||
22 | + content: '\f001'; | ||
23 | +} | ||
24 | + | ||
25 | +.simditor-icon-italic:before { | ||
26 | + content: '\f002'; | ||
27 | +} | ||
28 | + | ||
29 | +.simditor-icon-underline:before { | ||
30 | + content: '\f003'; | ||
31 | +} | ||
32 | + | ||
33 | +.simditor-icon-times:before { | ||
34 | + content: '\f004'; | ||
35 | +} | ||
36 | + | ||
37 | +.simditor-icon-strikethrough:before { | ||
38 | + content: '\f005'; | ||
39 | +} | ||
40 | + | ||
41 | +.simditor-icon-list-ol:before { | ||
42 | + content: '\f006'; | ||
43 | +} | ||
44 | + | ||
45 | +.simditor-icon-list-ul:before { | ||
46 | + content: '\f007'; | ||
47 | +} | ||
48 | + | ||
49 | +.simditor-icon-quote-left:before { | ||
50 | + content: '\f008'; | ||
51 | +} | ||
52 | + | ||
53 | +.simditor-icon-table:before { | ||
54 | + content: '\f009'; | ||
55 | +} | ||
56 | + | ||
57 | +.simditor-icon-link:before { | ||
58 | + content: '\f00a'; | ||
59 | +} | ||
60 | + | ||
61 | +.simditor-icon-picture-o:before { | ||
62 | + content: '\f00b'; | ||
63 | +} | ||
64 | + | ||
65 | +.simditor-icon-minus:before { | ||
66 | + content: '\f00c'; | ||
67 | +} | ||
68 | + | ||
69 | +.simditor-icon-indent:before { | ||
70 | + content: '\f00d'; | ||
71 | +} | ||
72 | + | ||
73 | +.simditor-icon-outdent:before { | ||
74 | + content: '\f00e'; | ||
75 | +} | ||
76 | + | ||
77 | +.simditor-icon-unlink:before { | ||
78 | + content: '\f00f'; | ||
79 | +} | ||
80 | + | ||
81 | +.simditor-icon-caret-down:before { | ||
82 | + content: '\f010'; | ||
83 | +} | ||
84 | + | ||
85 | +.simditor-icon-caret-right:before { | ||
86 | + content: '\f011'; | ||
87 | +} | ||
88 | + | ||
89 | +.simditor-icon-upload:before { | ||
90 | + content: '\f012'; | ||
91 | +} | ||
92 | + | ||
93 | +.simditor-icon-undo:before { | ||
94 | + content: '\f013'; | ||
95 | +} | ||
96 | + | ||
97 | +.simditor-icon-smile-o:before { | ||
98 | + content: '\f014'; | ||
99 | +} | ||
100 | + | ||
101 | +.simditor-icon-tint:before { | ||
102 | + content: '\f015'; | ||
103 | +} | ||
104 | + | ||
105 | +.simditor-icon-font:before { | ||
106 | + content: '\f016'; | ||
107 | +} | ||
108 | + | ||
109 | +.simditor-icon-html5:before { | ||
110 | + content: '\f017'; | ||
111 | +} | ||
112 | + | ||
113 | +.simditor-icon-mark:before { | ||
114 | + content: '\f018'; | ||
115 | +} | ||
116 | + | ||
117 | +.simditor-icon-align-center:before { | ||
118 | + content: '\f019'; | ||
119 | +} | ||
120 | + | ||
121 | +.simditor-icon-align-left:before { | ||
122 | + content: '\f01a'; | ||
123 | +} | ||
124 | + | ||
125 | +.simditor-icon-align-right:before { | ||
126 | + content: '\f01b'; | ||
127 | +} | ||
128 | + | ||
129 | +.simditor-icon-font-minus:before { | ||
130 | + content: '\f01c'; | ||
131 | +} | ||
132 | + | ||
133 | +.simditor-icon-markdown:before { | ||
134 | + content: '\f01d'; | ||
135 | +} | ||
136 | + | ||
137 | +.simditor-icon-checklist:before { | ||
138 | + content: '\f01e'; | ||
139 | +} | ||
140 | + | ||
141 | +.simditor { | ||
142 | + position: relative; | ||
143 | + border: 1px solid #c9d8db; | ||
144 | +} | ||
145 | +.simditor .simditor-wrapper { | ||
146 | + position: relative; | ||
147 | + background: #ffffff; | ||
148 | +} | ||
149 | +.simditor .simditor-wrapper > textarea { | ||
150 | + display: none !important; | ||
151 | + width: 100%; | ||
152 | + box-sizing: border-box; | ||
153 | + font-family: monaco; | ||
154 | + font-size: 14px; | ||
155 | + line-height: 1.6; | ||
156 | + border: none; | ||
157 | + padding: 22px 15px 36px; | ||
158 | + min-height: 300px; | ||
159 | + outline: none; | ||
160 | + background: transparent; | ||
161 | + resize: none; | ||
162 | +} | ||
163 | +.simditor .simditor-wrapper .simditor-placeholder { | ||
164 | + display: none; | ||
165 | + position: absolute; | ||
166 | + left: 0; | ||
167 | + z-index: 0; | ||
168 | + padding: 22px 15px; | ||
169 | + font-size: 16px; | ||
170 | + font-family: arial, sans-serif; | ||
171 | + line-height: 1.5; | ||
172 | + color: #999999; | ||
173 | + background: transparent; | ||
174 | +} | ||
175 | +.simditor .simditor-wrapper.toolbar-floating .simditor-toolbar { | ||
176 | + position: fixed; | ||
177 | + top: 0; | ||
178 | + z-index: 10; | ||
179 | + box-shadow: 0 0 6px rgba(0, 0, 0, 0.1); | ||
180 | +} | ||
181 | +.simditor .simditor-wrapper .simditor-image-loading { | ||
182 | + width: 100%; | ||
183 | + height: 100%; | ||
184 | + position: absolute; | ||
185 | + top: 0; | ||
186 | + left: 0; | ||
187 | + z-index: 2; | ||
188 | +} | ||
189 | +.simditor .simditor-wrapper .simditor-image-loading .progress { | ||
190 | + width: 100%; | ||
191 | + height: 100%; | ||
192 | + background: rgba(0, 0, 0, 0.4); | ||
193 | + position: absolute; | ||
194 | + bottom: 0; | ||
195 | + left: 0; | ||
196 | +} | ||
197 | +.simditor .simditor-body { | ||
198 | + padding: 10px; | ||
199 | + min-height: 300px; | ||
200 | + outline: none; | ||
201 | + cursor: text; | ||
202 | + position: relative; | ||
203 | + z-index: 1; | ||
204 | + background: transparent; | ||
205 | + width:100%; | ||
206 | +} | ||
207 | +.simditor .simditor-body a.selected { | ||
208 | + background: #b3d4fd; | ||
209 | +} | ||
210 | +.simditor .simditor-body a.simditor-mention { | ||
211 | + cursor: pointer; | ||
212 | +} | ||
213 | +.simditor .simditor-body .simditor-table { | ||
214 | + position: relative; | ||
215 | +} | ||
216 | +.simditor .simditor-body .simditor-table.resizing { | ||
217 | + cursor: col-resize; | ||
218 | +} | ||
219 | +.simditor .simditor-body .simditor-table .simditor-resize-handle { | ||
220 | + position: absolute; | ||
221 | + left: 0; | ||
222 | + top: 0; | ||
223 | + width: 10px; | ||
224 | + height: 100%; | ||
225 | + cursor: col-resize; | ||
226 | +} | ||
227 | +.simditor .simditor-body pre { | ||
228 | + /*min-height: 28px;*/ | ||
229 | + box-sizing: border-box; | ||
230 | + -moz-box-sizing: border-box; | ||
231 | + word-wrap: break-word !important; | ||
232 | + white-space: pre-wrap !important; | ||
233 | +} | ||
234 | +.simditor .simditor-body img { | ||
235 | + cursor: pointer; | ||
236 | +} | ||
237 | +.simditor .simditor-body img.selected { | ||
238 | + box-shadow: 0 0 0 4px #cccccc; | ||
239 | +} | ||
240 | +.simditor .simditor-paste-bin { | ||
241 | + position: fixed; | ||
242 | + bottom: 10px; | ||
243 | + right: 10px; | ||
244 | + width: 1px; | ||
245 | + height: 20px; | ||
246 | + font-size: 1px; | ||
247 | + line-height: 1px; | ||
248 | + overflow: hidden; | ||
249 | + padding: 0; | ||
250 | + margin: 0; | ||
251 | + opacity: 0; | ||
252 | + -webkit-user-select: text; | ||
253 | +} | ||
254 | +.simditor .simditor-toolbar { | ||
255 | + border-bottom: 1px solid #eeeeee; | ||
256 | + background: #ffffff; | ||
257 | + width: 100%; | ||
258 | +} | ||
259 | +.simditor .simditor-toolbar > ul { | ||
260 | + margin: 0; | ||
261 | + padding: 0 0 0 6px; | ||
262 | + list-style: none; | ||
263 | +} | ||
264 | +.simditor .simditor-toolbar > ul > li { | ||
265 | + position: relative; | ||
266 | + display: inline-block; | ||
267 | + font-size: 0; | ||
268 | +} | ||
269 | +.simditor .simditor-toolbar > ul > li > span.separator { | ||
270 | + display: inline-block; | ||
271 | + background: #cfcfcf; | ||
272 | + width: 1px; | ||
273 | + height: 18px; | ||
274 | + margin: 11px 15px; | ||
275 | + vertical-align: middle; | ||
276 | +} | ||
277 | +.simditor .simditor-toolbar > ul > li > .toolbar-item { | ||
278 | + display: inline-block; | ||
279 | + width: 36px; | ||
280 | + height: 36px; | ||
281 | + outline: none; | ||
282 | + color: #333333; | ||
283 | + font-size: 15px; | ||
284 | + line-height: 36px; | ||
285 | + vertical-align: middle; | ||
286 | + text-align: center; | ||
287 | + text-decoration: none; | ||
288 | +} | ||
289 | +.simditor .simditor-toolbar > ul > li > .toolbar-item span { | ||
290 | + opacity: 0.6; | ||
291 | +} | ||
292 | +.simditor .simditor-toolbar > ul > li > .toolbar-item span.simditor-icon { | ||
293 | + display: inline; | ||
294 | + line-height: normal; | ||
295 | +} | ||
296 | +.simditor .simditor-toolbar > ul > li > .toolbar-item:hover span { | ||
297 | + opacity: 1; | ||
298 | +} | ||
299 | +.simditor .simditor-toolbar > ul > li > .toolbar-item.active { | ||
300 | + background: #eeeeee; | ||
301 | +} | ||
302 | +.simditor .simditor-toolbar > ul > li > .toolbar-item.active span { | ||
303 | + opacity: 1; | ||
304 | +} | ||
305 | +.simditor .simditor-toolbar > ul > li > .toolbar-item.disabled { | ||
306 | + cursor: default; | ||
307 | +} | ||
308 | +.simditor .simditor-toolbar > ul > li > .toolbar-item.disabled span { | ||
309 | + opacity: 0.3; | ||
310 | +} | ||
311 | +.simditor .simditor-toolbar > ul > li > .toolbar-item.toolbar-item-title span:before { | ||
312 | + content: "H"; | ||
313 | + font-size: 19px; | ||
314 | + font-weight: bold; | ||
315 | + font-family: 'Times New Roman'; | ||
316 | +} | ||
317 | +.simditor .simditor-toolbar > ul > li > .toolbar-item.toolbar-item-title.active-h1 span:before { | ||
318 | + content: 'H1'; | ||
319 | + font-size: 18px; | ||
320 | +} | ||
321 | +.simditor .simditor-toolbar > ul > li > .toolbar-item.toolbar-item-title.active-h2 span:before { | ||
322 | + content: 'H2'; | ||
323 | + font-size: 18px; | ||
324 | +} | ||
325 | +.simditor .simditor-toolbar > ul > li > .toolbar-item.toolbar-item-title.active-h3 span:before { | ||
326 | + content: 'H3'; | ||
327 | + font-size: 18px; | ||
328 | +} | ||
329 | +.simditor .simditor-toolbar > ul > li > .toolbar-item.toolbar-item-image { | ||
330 | + position: relative; | ||
331 | + overflow: hidden; | ||
332 | +} | ||
333 | +.simditor .simditor-toolbar > ul > li > .toolbar-item.toolbar-item-image > input[type=file] { | ||
334 | + position: absolute; | ||
335 | + right: 0px; | ||
336 | + top: 0px; | ||
337 | + opacity: 0; | ||
338 | + font-size: 100px; | ||
339 | + cursor: pointer; | ||
340 | +} | ||
341 | +.simditor .simditor-toolbar > ul > li.menu-on .toolbar-item { | ||
342 | + position: relative; | ||
343 | + z-index: 20; | ||
344 | + background: #ffffff; | ||
345 | + box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3); | ||
346 | +} | ||
347 | +.simditor .simditor-toolbar > ul > li.menu-on .toolbar-item span { | ||
348 | + opacity: 1; | ||
349 | +} | ||
350 | +.simditor .simditor-toolbar > ul > li.menu-on .toolbar-menu { | ||
351 | + display: block; | ||
352 | +} | ||
353 | +.simditor .simditor-toolbar .toolbar-menu { | ||
354 | + display: none; | ||
355 | + position: absolute; | ||
356 | + top: 36px; | ||
357 | + left: 0; | ||
358 | + z-index: 21; | ||
359 | + background: #ffffff; | ||
360 | + text-align: left; | ||
361 | + box-shadow: 0 0 4px rgba(0, 0, 0, 0.3); | ||
362 | +} | ||
363 | +.simditor .simditor-toolbar .toolbar-menu:before { | ||
364 | + content: ''; | ||
365 | + display: block; | ||
366 | + width: 36px; | ||
367 | + height: 4px; | ||
368 | + background: #ffffff; | ||
369 | + position: absolute; | ||
370 | + top: -3px; | ||
371 | + left: 0; | ||
372 | +} | ||
373 | +.simditor .simditor-toolbar .toolbar-menu ul { | ||
374 | + min-width: 160px; | ||
375 | + list-style: none; | ||
376 | + margin: 0; | ||
377 | + padding: 10px 1px; | ||
378 | +} | ||
379 | +.simditor .simditor-toolbar .toolbar-menu ul > li .menu-item { | ||
380 | + display: block; | ||
381 | + font-size: 14px; | ||
382 | + line-height: 2em; | ||
383 | + padding: 0 10px; | ||
384 | + text-decoration: none; | ||
385 | + color: #666666; | ||
386 | +} | ||
387 | +.simditor .simditor-toolbar .toolbar-menu ul > li .menu-item:hover { | ||
388 | + background: #f6f6f6; | ||
389 | +} | ||
390 | +.simditor .simditor-toolbar .toolbar-menu ul > li .menu-item.menu-item-h1 { | ||
391 | + font-size: 24px; | ||
392 | + color: #333333; | ||
393 | +} | ||
394 | +.simditor .simditor-toolbar .toolbar-menu ul > li .menu-item.menu-item-h2 { | ||
395 | + font-size: 22px; | ||
396 | + color: #333333; | ||
397 | +} | ||
398 | +.simditor .simditor-toolbar .toolbar-menu ul > li .menu-item.menu-item-h3 { | ||
399 | + font-size: 20px; | ||
400 | + color: #333333; | ||
401 | +} | ||
402 | +.simditor .simditor-toolbar .toolbar-menu ul > li .menu-item.menu-item-h4 { | ||
403 | + font-size: 18px; | ||
404 | + color: #333333; | ||
405 | +} | ||
406 | +.simditor .simditor-toolbar .toolbar-menu ul > li .menu-item.menu-item-h5 { | ||
407 | + font-size: 16px; | ||
408 | + color: #333333; | ||
409 | +} | ||
410 | +.simditor .simditor-toolbar .toolbar-menu ul > li .separator { | ||
411 | + display: block; | ||
412 | + border-top: 1px solid #cccccc; | ||
413 | + height: 0; | ||
414 | + line-height: 0; | ||
415 | + font-size: 0; | ||
416 | + margin: 6px 0; | ||
417 | +} | ||
418 | +.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-color { | ||
419 | + width: 96px; | ||
420 | +} | ||
421 | +.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-color .color-list { | ||
422 | + height: 36px; | ||
423 | + margin: 10px 6px 6px 10px; | ||
424 | + padding: 0; | ||
425 | + min-width: 0; | ||
426 | +} | ||
427 | +.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-color .color-list li { | ||
428 | + float: left; | ||
429 | + margin: 0 4px 4px 0; | ||
430 | +} | ||
431 | +.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-color .color-list li .font-color { | ||
432 | + display: block; | ||
433 | + width: 16px; | ||
434 | + height: 16px; | ||
435 | + background: #dfdfdf; | ||
436 | + border-radius: 2px; | ||
437 | +} | ||
438 | +.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-color .color-list li .font-color:hover { | ||
439 | + opacity: 0.8; | ||
440 | +} | ||
441 | +.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-color .color-list li .font-color.font-color-default { | ||
442 | + background: #333333; | ||
443 | +} | ||
444 | +.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-color .color-list li .font-color-1 { | ||
445 | + background: #E33737; | ||
446 | +} | ||
447 | +.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-color .color-list li .font-color-2 { | ||
448 | + background: #e28b41; | ||
449 | +} | ||
450 | +.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-color .color-list li .font-color-3 { | ||
451 | + background: #c8a732; | ||
452 | +} | ||
453 | +.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-color .color-list li .font-color-4 { | ||
454 | + background: #209361; | ||
455 | +} | ||
456 | +.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-color .color-list li .font-color-5 { | ||
457 | + background: #418caf; | ||
458 | +} | ||
459 | +.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-color .color-list li .font-color-6 { | ||
460 | + background: #aa8773; | ||
461 | +} | ||
462 | +.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-color .color-list li .font-color-7 { | ||
463 | + background: #999999; | ||
464 | +} | ||
465 | +.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-table .menu-create-table { | ||
466 | + background: #ffffff; | ||
467 | + padding: 1px; | ||
468 | +} | ||
469 | +.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-table .menu-create-table table { | ||
470 | + border: none; | ||
471 | + border-collapse: collapse; | ||
472 | + border-spacing: 0; | ||
473 | + table-layout: fixed; | ||
474 | +} | ||
475 | +.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-table .menu-create-table table td { | ||
476 | + padding: 0; | ||
477 | + cursor: pointer; | ||
478 | +} | ||
479 | +.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-table .menu-create-table table td:before { | ||
480 | + width: 16px; | ||
481 | + height: 16px; | ||
482 | + border: 1px solid #ffffff; | ||
483 | + background: #f3f3f3; | ||
484 | + display: block; | ||
485 | + content: ""; | ||
486 | +} | ||
487 | +.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-table .menu-create-table table td.selected:before { | ||
488 | + background: #cfcfcf; | ||
489 | +} | ||
490 | +.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-table .menu-edit-table { | ||
491 | + display: none; | ||
492 | +} | ||
493 | +.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-table .menu-edit-table ul li { | ||
494 | + white-space: nowrap; | ||
495 | +} | ||
496 | +.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-image .menu-item-upload-image { | ||
497 | + position: relative; | ||
498 | + overflow: hidden; | ||
499 | +} | ||
500 | +.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-image .menu-item-upload-image input[type=file] { | ||
501 | + position: absolute; | ||
502 | + right: 0px; | ||
503 | + top: 0px; | ||
504 | + opacity: 0; | ||
505 | + font-size: 100px; | ||
506 | + cursor: pointer; | ||
507 | +} | ||
508 | +.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-alignment { | ||
509 | + width: 100%; | ||
510 | +} | ||
511 | +.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-alignment ul { | ||
512 | + min-width: 100%; | ||
513 | +} | ||
514 | +.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-alignment .menu-item { | ||
515 | + text-align: center; | ||
516 | +} | ||
517 | +.simditor .simditor-popover { | ||
518 | + display: none; | ||
519 | + padding: 5px 8px 0; | ||
520 | + background: #ffffff; | ||
521 | + box-shadow: 0 1px 4px rgba(0, 0, 0, 0.4); | ||
522 | + border-radius: 2px; | ||
523 | + position: absolute; | ||
524 | + z-index: 2; | ||
525 | +} | ||
526 | +.simditor .simditor-popover .settings-field { | ||
527 | + margin: 0 0 5px 0; | ||
528 | + font-size: 12px; | ||
529 | + height: 25px; | ||
530 | + line-height: 25px; | ||
531 | +} | ||
532 | +.simditor .simditor-popover .settings-field label { | ||
533 | + display: inline-block; | ||
534 | + margin: 0 5px 0 0; | ||
535 | +} | ||
536 | +.simditor .simditor-popover .settings-field input[type=text] { | ||
537 | + display: inline-block; | ||
538 | + width: 200px; | ||
539 | + box-sizing: border-box; | ||
540 | + font-size: 12px; | ||
541 | +} | ||
542 | +.simditor .simditor-popover .settings-field input[type=text].image-size { | ||
543 | + width: 83px; | ||
544 | +} | ||
545 | +.simditor .simditor-popover .settings-field .times { | ||
546 | + display: inline-block; | ||
547 | + width: 26px; | ||
548 | + font-size: 12px; | ||
549 | + text-align: center; | ||
550 | +} | ||
551 | +.simditor .simditor-popover.link-popover .btn-unlink, .simditor .simditor-popover.image-popover .btn-upload, .simditor .simditor-popover.image-popover .btn-restore { | ||
552 | + display: inline-block; | ||
553 | + margin: 0 0 0 5px; | ||
554 | + color: #333333; | ||
555 | + font-size: 14px; | ||
556 | + outline: 0; | ||
557 | +} | ||
558 | +.simditor .simditor-popover.link-popover .btn-unlink span, .simditor .simditor-popover.image-popover .btn-upload span, .simditor .simditor-popover.image-popover .btn-restore span { | ||
559 | + opacity: 0.6; | ||
560 | +} | ||
561 | +.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 { | ||
562 | + opacity: 1; | ||
563 | +} | ||
564 | +.simditor .simditor-popover.image-popover .btn-upload { | ||
565 | + position: relative; | ||
566 | + display: inline-block; | ||
567 | + overflow: hidden; | ||
568 | + vertical-align: middle; | ||
569 | +} | ||
570 | +.simditor .simditor-popover.image-popover .btn-upload input[type=file] { | ||
571 | + position: absolute; | ||
572 | + right: 0px; | ||
573 | + top: 0px; | ||
574 | + opacity: 0; | ||
575 | + height: 100%; | ||
576 | + width: 28px; | ||
577 | +} | ||
578 | +.simditor.simditor-mobile .simditor-wrapper.toolbar-floating .simditor-toolbar { | ||
579 | + position: absolute; | ||
580 | + top: 0; | ||
581 | + z-index: 10; | ||
582 | + box-shadow: 0 0 6px rgba(0, 0, 0, 0.1); | ||
583 | +} | ||
584 | + | ||
585 | +.simditor .simditor-body, .editor-style { | ||
586 | + font-size: 14px; | ||
587 | + font-family: arial, sans-serif; | ||
588 | + line-height: 1.6; | ||
589 | + color: #333; | ||
590 | + outline: none; | ||
591 | + word-wrap: break-word; | ||
592 | +} | ||
593 | +.simditor .simditor-body > :first-child, .editor-style > :first-child { | ||
594 | + margin-top: 0 !important; | ||
595 | +} | ||
596 | +.simditor .simditor-body a, .editor-style a { | ||
597 | + color: #4298BA; | ||
598 | + text-decoration: none; | ||
599 | + word-break: break-all; | ||
600 | +} | ||
601 | +.simditor .simditor-body a:visited, .editor-style a:visited { | ||
602 | + color: #4298BA; | ||
603 | +} | ||
604 | +.simditor .simditor-body a:hover, .editor-style a:hover { | ||
605 | + color: #0F769F; | ||
606 | +} | ||
607 | +.simditor .simditor-body a:active, .editor-style a:active { | ||
608 | + color: #9E792E; | ||
609 | +} | ||
610 | +.simditor .simditor-body a:hover, .simditor .simditor-body a:active, .editor-style a:hover, .editor-style a:active { | ||
611 | + outline: 0; | ||
612 | +} | ||
613 | +.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 { | ||
614 | + font-weight: normal; | ||
615 | + margin: 36px 0 20px; | ||
616 | + color: #000000; | ||
617 | +} | ||
618 | +.simditor .simditor-body h1, .editor-style h1 { | ||
619 | + font-size: 24px; | ||
620 | +} | ||
621 | +.simditor .simditor-body h2, .editor-style h2 { | ||
622 | + font-size: 22px; | ||
623 | +} | ||
624 | +.simditor .simditor-body h3, .editor-style h3 { | ||
625 | + font-size: 20px; | ||
626 | +} | ||
627 | +.simditor .simditor-body h4, .editor-style h4 { | ||
628 | + font-size: 18px; | ||
629 | +} | ||
630 | +.simditor .simditor-body h5, .editor-style h5 { | ||
631 | + font-size: 16px; | ||
632 | +} | ||
633 | +.simditor .simditor-body h6, .editor-style h6 { | ||
634 | + font-size: 16px; | ||
635 | +} | ||
636 | +.simditor .simditor-body p, .simditor .simditor-body div, .editor-style p, .editor-style div { | ||
637 | + word-wrap: break-word; | ||
638 | + margin: 0 0 10px 0; | ||
639 | + color: #333; | ||
640 | + word-wrap: break-word; | ||
641 | +} | ||
642 | +.simditor .simditor-body b, .simditor .simditor-body strong, .editor-style b, .editor-style strong { | ||
643 | + font-weight: bold; | ||
644 | +} | ||
645 | +.simditor .simditor-body i, .simditor .simditor-body em, .editor-style i, .editor-style em { | ||
646 | + font-style: italic; | ||
647 | +} | ||
648 | +.simditor .simditor-body u, .editor-style u { | ||
649 | + text-decoration: underline; | ||
650 | +} | ||
651 | +.simditor .simditor-body strike, .simditor .simditor-body del, .editor-style strike, .editor-style del { | ||
652 | + text-decoration: line-through; | ||
653 | +} | ||
654 | +.simditor .simditor-body ul, .simditor .simditor-body ol, .editor-style ul, .editor-style ol { | ||
655 | + list-style: disc outside none; | ||
656 | + margin: 15px 0; | ||
657 | + padding: 0 0 0 36px; | ||
658 | + line-height: 1.6; | ||
659 | +} | ||
660 | +.simditor .simditor-body ul li, .simditor .simditor-body ol li, .editor-style ul li, .editor-style ol li { | ||
661 | + list-style-type: inherit; | ||
662 | +} | ||
663 | +.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 { | ||
664 | + padding-left: 30px; | ||
665 | +} | ||
666 | +.simditor .simditor-body ul ul, .simditor .simditor-body ol ul, .editor-style ul ul, .editor-style ol ul { | ||
667 | + list-style: circle outside none; | ||
668 | +} | ||
669 | +.simditor .simditor-body ul ul ul, .simditor .simditor-body ol ul ul, .editor-style ul ul ul, .editor-style ol ul ul { | ||
670 | + list-style: square outside none; | ||
671 | +} | ||
672 | +.simditor .simditor-body ol, .editor-style ol { | ||
673 | + list-style: decimal; | ||
674 | +} | ||
675 | +.simditor .simditor-body blockquote, .editor-style blockquote { | ||
676 | + border-left: 6px solid #ddd; | ||
677 | + padding: 5px 0 5px 10px; | ||
678 | + margin: 15px 0 15px 15px; | ||
679 | +} | ||
680 | +.simditor .simditor-body blockquote > :first-child, .editor-style blockquote > :first-child { | ||
681 | + margin-top: 0; | ||
682 | +} | ||
683 | +.simditor .simditor-body code, .editor-style code { | ||
684 | + display: inline-block; | ||
685 | + padding: 0 4px; | ||
686 | + margin: 0 5px; | ||
687 | + background: #eeeeee; | ||
688 | + border-radius: 3px; | ||
689 | + font-size: 13px; | ||
690 | + font-family: 'monaco', 'Consolas', "Liberation Mono", Courier, monospace; | ||
691 | +} | ||
692 | +.simditor .simditor-body pre, .editor-style pre { | ||
693 | + padding: 10px 5px 10px 10px; | ||
694 | + margin: 15px 0; | ||
695 | + display: block; | ||
696 | + line-height: 18px; | ||
697 | + background: #F0F0F0; | ||
698 | + border-radius: 3px; | ||
699 | + font-size: 13px; | ||
700 | + font-family: 'monaco', 'Consolas', "Liberation Mono", Courier, monospace; | ||
701 | + white-space: pre; | ||
702 | + word-wrap: normal; | ||
703 | + overflow-x: auto; | ||
704 | +} | ||
705 | +.simditor .simditor-body pre code, .editor-style pre code { | ||
706 | + display: block; | ||
707 | + padding: 0; | ||
708 | + margin: 0; | ||
709 | + background: none; | ||
710 | + border-radius: 0; | ||
711 | +} | ||
712 | +.simditor .simditor-body hr, .editor-style hr { | ||
713 | + display: block; | ||
714 | + height: 0px; | ||
715 | + border: 0; | ||
716 | + border-top: 1px solid #ccc; | ||
717 | + margin: 15px 0; | ||
718 | + padding: 0; | ||
719 | +} | ||
720 | +.simditor .simditor-body table, .editor-style table { | ||
721 | + width: 100%; | ||
722 | + table-layout: fixed; | ||
723 | + border-collapse: collapse; | ||
724 | + border-spacing: 0; | ||
725 | + margin: 15px 0; | ||
726 | +} | ||
727 | +.simditor .simditor-body table thead, .editor-style table thead { | ||
728 | + background-color: #f9f9f9; | ||
729 | +} | ||
730 | +.simditor .simditor-body table td, .simditor .simditor-body table th, .editor-style table td, .editor-style table th { | ||
731 | + min-width: 36px; | ||
732 | + height: 30px; | ||
733 | + border: 1px solid #ccc; | ||
734 | + vertical-align: top; | ||
735 | + padding: 2px 4px; | ||
736 | + text-align: left; | ||
737 | + box-sizing: border-box; | ||
738 | +} | ||
739 | +.simditor .simditor-body table td.active, .simditor .simditor-body table th.active, .editor-style table td.active, .editor-style table th.active { | ||
740 | + background-color: #ffffee; | ||
741 | +} | ||
742 | +.simditor .simditor-body img, .editor-style img { | ||
743 | + margin: 0 5px; | ||
744 | + vertical-align: middle; | ||
745 | +} |
addons/simditor/src/images/image.png
0 → 100755

10.5 KB
addons/simditor/src/js/hotkeys.js
0 → 100755
1 | +(function (root, factory) { | ||
2 | + if (typeof define === 'function' && define.amd) { | ||
3 | + // AMD. Register as an anonymous module unless amdModuleId is set | ||
4 | + define('simple-hotkeys', ["jquery","simple-module"], function ($, SimpleModule) { | ||
5 | + return (root['hotkeys'] = factory($, SimpleModule)); | ||
6 | + }); | ||
7 | + } else if (typeof exports === 'object') { | ||
8 | + // Node. Does not work with strict CommonJS, but | ||
9 | + // only CommonJS-like environments that support module.exports, | ||
10 | + // like Node. | ||
11 | + module.exports = factory(require("jquery"),require("simple-module")); | ||
12 | + } else { | ||
13 | + root.simple = root.simple || {}; | ||
14 | + root.simple['hotkeys'] = factory(jQuery,SimpleModule); | ||
15 | + } | ||
16 | +}(this, function ($, SimpleModule) { | ||
17 | + | ||
18 | +var Hotkeys, hotkeys, | ||
19 | + 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; }, | ||
20 | + hasProp = {}.hasOwnProperty; | ||
21 | + | ||
22 | +Hotkeys = (function(superClass) { | ||
23 | + extend(Hotkeys, superClass); | ||
24 | + | ||
25 | + function Hotkeys() { | ||
26 | + return Hotkeys.__super__.constructor.apply(this, arguments); | ||
27 | + } | ||
28 | + | ||
29 | + Hotkeys.count = 0; | ||
30 | + | ||
31 | + Hotkeys.keyNameMap = { | ||
32 | + 8: "Backspace", | ||
33 | + 9: "Tab", | ||
34 | + 13: "Enter", | ||
35 | + 16: "Shift", | ||
36 | + 17: "Control", | ||
37 | + 18: "Alt", | ||
38 | + 19: "Pause", | ||
39 | + 20: "CapsLock", | ||
40 | + 27: "Esc", | ||
41 | + 32: "Spacebar", | ||
42 | + 33: "PageUp", | ||
43 | + 34: "PageDown", | ||
44 | + 35: "End", | ||
45 | + 36: "Home", | ||
46 | + 37: "Left", | ||
47 | + 38: "Up", | ||
48 | + 39: "Right", | ||
49 | + 40: "Down", | ||
50 | + 45: "Insert", | ||
51 | + 46: "Del", | ||
52 | + 91: "Meta", | ||
53 | + 93: "Meta", | ||
54 | + 48: "0", | ||
55 | + 49: "1", | ||
56 | + 50: "2", | ||
57 | + 51: "3", | ||
58 | + 52: "4", | ||
59 | + 53: "5", | ||
60 | + 54: "6", | ||
61 | + 55: "7", | ||
62 | + 56: "8", | ||
63 | + 57: "9", | ||
64 | + 65: "A", | ||
65 | + 66: "B", | ||
66 | + 67: "C", | ||
67 | + 68: "D", | ||
68 | + 69: "E", | ||
69 | + 70: "F", | ||
70 | + 71: "G", | ||
71 | + 72: "H", | ||
72 | + 73: "I", | ||
73 | + 74: "J", | ||
74 | + 75: "K", | ||
75 | + 76: "L", | ||
76 | + 77: "M", | ||
77 | + 78: "N", | ||
78 | + 79: "O", | ||
79 | + 80: "P", | ||
80 | + 81: "Q", | ||
81 | + 82: "R", | ||
82 | + 83: "S", | ||
83 | + 84: "T", | ||
84 | + 85: "U", | ||
85 | + 86: "V", | ||
86 | + 87: "W", | ||
87 | + 88: "X", | ||
88 | + 89: "Y", | ||
89 | + 90: "Z", | ||
90 | + 96: "0", | ||
91 | + 97: "1", | ||
92 | + 98: "2", | ||
93 | + 99: "3", | ||
94 | + 100: "4", | ||
95 | + 101: "5", | ||
96 | + 102: "6", | ||
97 | + 103: "7", | ||
98 | + 104: "8", | ||
99 | + 105: "9", | ||
100 | + 106: "Multiply", | ||
101 | + 107: "Add", | ||
102 | + 109: "Subtract", | ||
103 | + 110: "Decimal", | ||
104 | + 111: "Divide", | ||
105 | + 112: "F1", | ||
106 | + 113: "F2", | ||
107 | + 114: "F3", | ||
108 | + 115: "F4", | ||
109 | + 116: "F5", | ||
110 | + 117: "F6", | ||
111 | + 118: "F7", | ||
112 | + 119: "F8", | ||
113 | + 120: "F9", | ||
114 | + 121: "F10", | ||
115 | + 122: "F11", | ||
116 | + 123: "F12", | ||
117 | + 124: "F13", | ||
118 | + 125: "F14", | ||
119 | + 126: "F15", | ||
120 | + 127: "F16", | ||
121 | + 128: "F17", | ||
122 | + 129: "F18", | ||
123 | + 130: "F19", | ||
124 | + 131: "F20", | ||
125 | + 132: "F21", | ||
126 | + 133: "F22", | ||
127 | + 134: "F23", | ||
128 | + 135: "F24", | ||
129 | + 59: ";", | ||
130 | + 61: "=", | ||
131 | + 186: ";", | ||
132 | + 187: "=", | ||
133 | + 188: ",", | ||
134 | + 190: ".", | ||
135 | + 191: "/", | ||
136 | + 192: "`", | ||
137 | + 219: "[", | ||
138 | + 220: "\\", | ||
139 | + 221: "]", | ||
140 | + 222: "'" | ||
141 | + }; | ||
142 | + | ||
143 | + Hotkeys.aliases = { | ||
144 | + "escape": "esc", | ||
145 | + "delete": "del", | ||
146 | + "return": "enter", | ||
147 | + "ctrl": "control", | ||
148 | + "space": "spacebar", | ||
149 | + "ins": "insert", | ||
150 | + "cmd": "meta", | ||
151 | + "command": "meta", | ||
152 | + "wins": "meta", | ||
153 | + "windows": "meta" | ||
154 | + }; | ||
155 | + | ||
156 | + Hotkeys.normalize = function(shortcut) { | ||
157 | + var i, j, key, keyname, keys, len; | ||
158 | + keys = shortcut.toLowerCase().replace(/\s+/gi, "").split("+"); | ||
159 | + for (i = j = 0, len = keys.length; j < len; i = ++j) { | ||
160 | + key = keys[i]; | ||
161 | + keys[i] = this.aliases[key] || key; | ||
162 | + } | ||
163 | + keyname = keys.pop(); | ||
164 | + keys.sort().push(keyname); | ||
165 | + return keys.join("_"); | ||
166 | + }; | ||
167 | + | ||
168 | + Hotkeys.prototype.opts = { | ||
169 | + el: document | ||
170 | + }; | ||
171 | + | ||
172 | + Hotkeys.prototype._init = function() { | ||
173 | + this.id = ++this.constructor.count; | ||
174 | + this._map = {}; | ||
175 | + this._delegate = typeof this.opts.el === "string" ? document : this.opts.el; | ||
176 | + return $(this._delegate).on("keydown.simple-hotkeys-" + this.id, this.opts.el, (function(_this) { | ||
177 | + return function(e) { | ||
178 | + var ref; | ||
179 | + return (ref = _this._getHander(e)) != null ? ref.call(_this, e) : void 0; | ||
180 | + }; | ||
181 | + })(this)); | ||
182 | + }; | ||
183 | + | ||
184 | + Hotkeys.prototype._getHander = function(e) { | ||
185 | + var keyname, shortcut; | ||
186 | + if (!(keyname = this.constructor.keyNameMap[e.which])) { | ||
187 | + return; | ||
188 | + } | ||
189 | + shortcut = ""; | ||
190 | + if (e.altKey) { | ||
191 | + shortcut += "alt_"; | ||
192 | + } | ||
193 | + if (e.ctrlKey) { | ||
194 | + shortcut += "control_"; | ||
195 | + } | ||
196 | + if (e.metaKey) { | ||
197 | + shortcut += "meta_"; | ||
198 | + } | ||
199 | + if (e.shiftKey) { | ||
200 | + shortcut += "shift_"; | ||
201 | + } | ||
202 | + shortcut += keyname.toLowerCase(); | ||
203 | + return this._map[shortcut]; | ||
204 | + }; | ||
205 | + | ||
206 | + Hotkeys.prototype.respondTo = function(subject) { | ||
207 | + if (typeof subject === 'string') { | ||
208 | + return this._map[this.constructor.normalize(subject)] != null; | ||
209 | + } else { | ||
210 | + return this._getHander(subject) != null; | ||
211 | + } | ||
212 | + }; | ||
213 | + | ||
214 | + Hotkeys.prototype.add = function(shortcut, handler) { | ||
215 | + this._map[this.constructor.normalize(shortcut)] = handler; | ||
216 | + return this; | ||
217 | + }; | ||
218 | + | ||
219 | + Hotkeys.prototype.remove = function(shortcut) { | ||
220 | + delete this._map[this.constructor.normalize(shortcut)]; | ||
221 | + return this; | ||
222 | + }; | ||
223 | + | ||
224 | + Hotkeys.prototype.destroy = function() { | ||
225 | + $(this._delegate).off(".simple-hotkeys-" + this.id); | ||
226 | + this._map = {}; | ||
227 | + return this; | ||
228 | + }; | ||
229 | + | ||
230 | + return Hotkeys; | ||
231 | + | ||
232 | +})(SimpleModule); | ||
233 | + | ||
234 | +hotkeys = function(opts) { | ||
235 | + return new Hotkeys(opts); | ||
236 | +}; | ||
237 | + | ||
238 | +return hotkeys; | ||
239 | + | ||
240 | +})); | ||
241 | + |
addons/simditor/src/js/module.js
0 → 100755
1 | +(function (root, factory) { | ||
2 | + if (typeof define === 'function' && define.amd) { | ||
3 | + // AMD. Register as an anonymous module unless amdModuleId is set | ||
4 | + define('simple-module', ["jquery"], function (a0) { | ||
5 | + return (root['Module'] = factory(a0)); | ||
6 | + }); | ||
7 | + } else if (typeof exports === 'object') { | ||
8 | + // Node. Does not work with strict CommonJS, but | ||
9 | + // only CommonJS-like environments that support module.exports, | ||
10 | + // like Node. | ||
11 | + module.exports = factory(require("jquery")); | ||
12 | + } else { | ||
13 | + root['SimpleModule'] = factory(jQuery); | ||
14 | + } | ||
15 | +}(this, function ($) { | ||
16 | + | ||
17 | +var Module, | ||
18 | + slice = [].slice; | ||
19 | + | ||
20 | +Module = (function() { | ||
21 | + Module.extend = function(obj) { | ||
22 | + var key, ref, val; | ||
23 | + if (!((obj != null) && typeof obj === 'object')) { | ||
24 | + return; | ||
25 | + } | ||
26 | + for (key in obj) { | ||
27 | + val = obj[key]; | ||
28 | + if (key !== 'included' && key !== 'extended') { | ||
29 | + this[key] = val; | ||
30 | + } | ||
31 | + } | ||
32 | + return (ref = obj.extended) != null ? ref.call(this) : void 0; | ||
33 | + }; | ||
34 | + | ||
35 | + Module.include = function(obj) { | ||
36 | + var key, ref, val; | ||
37 | + if (!((obj != null) && typeof obj === 'object')) { | ||
38 | + return; | ||
39 | + } | ||
40 | + for (key in obj) { | ||
41 | + val = obj[key]; | ||
42 | + if (key !== 'included' && key !== 'extended') { | ||
43 | + this.prototype[key] = val; | ||
44 | + } | ||
45 | + } | ||
46 | + return (ref = obj.included) != null ? ref.call(this) : void 0; | ||
47 | + }; | ||
48 | + | ||
49 | + Module.connect = function(cls) { | ||
50 | + if (typeof cls !== 'function') { | ||
51 | + return; | ||
52 | + } | ||
53 | + if (!cls.pluginName) { | ||
54 | + throw new Error('Module.connect: cannot connect plugin without pluginName'); | ||
55 | + return; | ||
56 | + } | ||
57 | + cls.prototype._connected = true; | ||
58 | + if (!this._connectedClasses) { | ||
59 | + this._connectedClasses = []; | ||
60 | + } | ||
61 | + this._connectedClasses.push(cls); | ||
62 | + if (cls.pluginName) { | ||
63 | + return this[cls.pluginName] = cls; | ||
64 | + } | ||
65 | + }; | ||
66 | + | ||
67 | + Module.prototype.opts = {}; | ||
68 | + | ||
69 | + function Module(opts) { | ||
70 | + var base, cls, i, instance, instances, len, name; | ||
71 | + this.opts = $.extend({}, this.opts, opts); | ||
72 | + (base = this.constructor)._connectedClasses || (base._connectedClasses = []); | ||
73 | + instances = (function() { | ||
74 | + var i, len, ref, results; | ||
75 | + ref = this.constructor._connectedClasses; | ||
76 | + results = []; | ||
77 | + for (i = 0, len = ref.length; i < len; i++) { | ||
78 | + cls = ref[i]; | ||
79 | + name = cls.pluginName.charAt(0).toLowerCase() + cls.pluginName.slice(1); | ||
80 | + if (cls.prototype._connected) { | ||
81 | + cls.prototype._module = this; | ||
82 | + } | ||
83 | + results.push(this[name] = new cls()); | ||
84 | + } | ||
85 | + return results; | ||
86 | + }).call(this); | ||
87 | + if (this._connected) { | ||
88 | + this.opts = $.extend({}, this.opts, this._module.opts); | ||
89 | + } else { | ||
90 | + this._init(); | ||
91 | + for (i = 0, len = instances.length; i < len; i++) { | ||
92 | + instance = instances[i]; | ||
93 | + if (typeof instance._init === "function") { | ||
94 | + instance._init(); | ||
95 | + } | ||
96 | + } | ||
97 | + } | ||
98 | + this.trigger('initialized'); | ||
99 | + } | ||
100 | + | ||
101 | + Module.prototype._init = function() {}; | ||
102 | + | ||
103 | + Module.prototype.on = function() { | ||
104 | + var args, ref; | ||
105 | + args = 1 <= arguments.length ? slice.call(arguments, 0) : []; | ||
106 | + (ref = $(this)).on.apply(ref, args); | ||
107 | + return this; | ||
108 | + }; | ||
109 | + | ||
110 | + Module.prototype.one = function() { | ||
111 | + var args, ref; | ||
112 | + args = 1 <= arguments.length ? slice.call(arguments, 0) : []; | ||
113 | + (ref = $(this)).one.apply(ref, args); | ||
114 | + return this; | ||
115 | + }; | ||
116 | + | ||
117 | + Module.prototype.off = function() { | ||
118 | + var args, ref; | ||
119 | + args = 1 <= arguments.length ? slice.call(arguments, 0) : []; | ||
120 | + (ref = $(this)).off.apply(ref, args); | ||
121 | + return this; | ||
122 | + }; | ||
123 | + | ||
124 | + Module.prototype.trigger = function() { | ||
125 | + var args, ref; | ||
126 | + args = 1 <= arguments.length ? slice.call(arguments, 0) : []; | ||
127 | + (ref = $(this)).trigger.apply(ref, args); | ||
128 | + return this; | ||
129 | + }; | ||
130 | + | ||
131 | + Module.prototype.triggerHandler = function() { | ||
132 | + var args, ref; | ||
133 | + args = 1 <= arguments.length ? slice.call(arguments, 0) : []; | ||
134 | + return (ref = $(this)).triggerHandler.apply(ref, args); | ||
135 | + }; | ||
136 | + | ||
137 | + Module.prototype._t = function() { | ||
138 | + var args, ref; | ||
139 | + args = 1 <= arguments.length ? slice.call(arguments, 0) : []; | ||
140 | + return (ref = this.constructor)._t.apply(ref, args); | ||
141 | + }; | ||
142 | + | ||
143 | + Module._t = function() { | ||
144 | + var args, key, ref, result; | ||
145 | + key = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : []; | ||
146 | + result = ((ref = this.i18n[this.locale]) != null ? ref[key] : void 0) || ''; | ||
147 | + if (!(args.length > 0)) { | ||
148 | + return result; | ||
149 | + } | ||
150 | + result = result.replace(/([^%]|^)%(?:(\d+)\$)?s/g, function(p0, p, position) { | ||
151 | + if (position) { | ||
152 | + return p + args[parseInt(position) - 1]; | ||
153 | + } else { | ||
154 | + return p + args.shift(); | ||
155 | + } | ||
156 | + }); | ||
157 | + return result.replace(/%%s/g, '%s'); | ||
158 | + }; | ||
159 | + | ||
160 | + Module.i18n = { | ||
161 | + 'zh-CN': {} | ||
162 | + }; | ||
163 | + | ||
164 | + Module.locale = 'zh-CN'; | ||
165 | + | ||
166 | + return Module; | ||
167 | + | ||
168 | +})(); | ||
169 | + | ||
170 | +return Module; | ||
171 | + | ||
172 | +})); |
addons/simditor/src/js/simditor.js
0 → 100755
此 diff 太大无法显示。
addons/simditor/src/js/uploader.js
0 → 100755
1 | +(function (root, factory) { | ||
2 | + if (typeof define === 'function' && define.amd) { | ||
3 | + // AMD. Register as an anonymous module unless amdModuleId is set | ||
4 | + define('simple-uploader', ["jquery","simple-module"], function ($, SimpleModule) { | ||
5 | + return (root['uploader'] = factory($, SimpleModule)); | ||
6 | + }); | ||
7 | + } else if (typeof exports === 'object') { | ||
8 | + // Node. Does not work with strict CommonJS, but | ||
9 | + // only CommonJS-like environments that support module.exports, | ||
10 | + // like Node. | ||
11 | + module.exports = factory(require("jquery"),require("simple-module")); | ||
12 | + } else { | ||
13 | + root.simple = root.simple || {}; | ||
14 | + root.simple['uploader'] = factory(jQuery,SimpleModule); | ||
15 | + } | ||
16 | +}(this, function ($, SimpleModule) { | ||
17 | + | ||
18 | +var Uploader, uploader, | ||
19 | + 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; }, | ||
20 | + hasProp = {}.hasOwnProperty; | ||
21 | + | ||
22 | +Uploader = (function(superClass) { | ||
23 | + extend(Uploader, superClass); | ||
24 | + | ||
25 | + function Uploader() { | ||
26 | + return Uploader.__super__.constructor.apply(this, arguments); | ||
27 | + } | ||
28 | + | ||
29 | + Uploader.count = 0; | ||
30 | + | ||
31 | + Uploader.prototype.opts = { | ||
32 | + url: '', | ||
33 | + params: null, | ||
34 | + fileKey: 'upload_file', | ||
35 | + connectionCount: 3 | ||
36 | + }; | ||
37 | + | ||
38 | + Uploader.prototype._init = function() { | ||
39 | + this.files = []; | ||
40 | + this.queue = []; | ||
41 | + this.id = ++Uploader.count; | ||
42 | + this.on('uploadcomplete', (function(_this) { | ||
43 | + return function(e, file) { | ||
44 | + _this.files.splice($.inArray(file, _this.files), 1); | ||
45 | + if (_this.queue.length > 0 && _this.files.length < _this.opts.connectionCount) { | ||
46 | + return _this.upload(_this.queue.shift()); | ||
47 | + } else if (_this.files.length === 0) { | ||
48 | + return _this.uploading = false; | ||
49 | + } | ||
50 | + }; | ||
51 | + })(this)); | ||
52 | + return $(window).on('beforeunload.uploader-' + this.id, (function(_this) { | ||
53 | + return function(e) { | ||
54 | + if (!_this.uploading) { | ||
55 | + return; | ||
56 | + } | ||
57 | + e.originalEvent.returnValue = _this._t('leaveConfirm'); | ||
58 | + return _this._t('leaveConfirm'); | ||
59 | + }; | ||
60 | + })(this)); | ||
61 | + }; | ||
62 | + | ||
63 | + Uploader.prototype.generateId = (function() { | ||
64 | + var id; | ||
65 | + id = 0; | ||
66 | + return function() { | ||
67 | + return id += 1; | ||
68 | + }; | ||
69 | + })(); | ||
70 | + | ||
71 | + Uploader.prototype.upload = function(file, opts) { | ||
72 | + var f, i, key, len; | ||
73 | + if (opts == null) { | ||
74 | + opts = {}; | ||
75 | + } | ||
76 | + if (file == null) { | ||
77 | + return; | ||
78 | + } | ||
79 | + if ($.isArray(file) || file instanceof FileList) { | ||
80 | + for (i = 0, len = file.length; i < len; i++) { | ||
81 | + f = file[i]; | ||
82 | + this.upload(f, opts); | ||
83 | + } | ||
84 | + } else if ($(file).is('input:file')) { | ||
85 | + key = $(file).attr('name'); | ||
86 | + if (key) { | ||
87 | + opts.fileKey = key; | ||
88 | + } | ||
89 | + this.upload($.makeArray($(file)[0].files), opts); | ||
90 | + } else if (!file.id || !file.obj) { | ||
91 | + file = this.getFile(file); | ||
92 | + } | ||
93 | + if (!(file && file.obj)) { | ||
94 | + return; | ||
95 | + } | ||
96 | + $.extend(file, opts); | ||
97 | + if (this.files.length >= this.opts.connectionCount) { | ||
98 | + this.queue.push(file); | ||
99 | + return; | ||
100 | + } | ||
101 | + if (this.triggerHandler('beforeupload', [file]) === false) { | ||
102 | + return; | ||
103 | + } | ||
104 | + this.files.push(file); | ||
105 | + this._xhrUpload(file); | ||
106 | + return this.uploading = true; | ||
107 | + }; | ||
108 | + | ||
109 | + Uploader.prototype.getFile = function(fileObj) { | ||
110 | + var name, ref, ref1; | ||
111 | + if (fileObj instanceof window.File || fileObj instanceof window.Blob) { | ||
112 | + name = (ref = fileObj.fileName) != null ? ref : fileObj.name; | ||
113 | + } else { | ||
114 | + return null; | ||
115 | + } | ||
116 | + return { | ||
117 | + id: this.generateId(), | ||
118 | + url: this.opts.url, | ||
119 | + params: this.opts.params, | ||
120 | + fileKey: this.opts.fileKey, | ||
121 | + name: name, | ||
122 | + size: (ref1 = fileObj.fileSize) != null ? ref1 : fileObj.size, | ||
123 | + ext: name ? name.split('.').pop().toLowerCase() : '', | ||
124 | + obj: fileObj | ||
125 | + }; | ||
126 | + }; | ||
127 | + | ||
128 | + Uploader.prototype._xhrUpload = function(file) { | ||
129 | + var formData, k, ref, v; | ||
130 | + formData = new FormData(); | ||
131 | + formData.append(file.fileKey, file.obj); | ||
132 | + formData.append("original_filename", file.name); | ||
133 | + if (file.params) { | ||
134 | + ref = file.params; | ||
135 | + for (k in ref) { | ||
136 | + v = ref[k]; | ||
137 | + formData.append(k, v); | ||
138 | + } | ||
139 | + } | ||
140 | + return file.xhr = $.ajax({ | ||
141 | + url: file.url, | ||
142 | + data: formData, | ||
143 | + processData: false, | ||
144 | + contentType: false, | ||
145 | + type: 'POST', | ||
146 | + headers: { | ||
147 | + 'X-File-Name': encodeURIComponent(file.name) | ||
148 | + }, | ||
149 | + xhr: function() { | ||
150 | + var req; | ||
151 | + req = $.ajaxSettings.xhr(); | ||
152 | + if (req) { | ||
153 | + req.upload.onprogress = (function(_this) { | ||
154 | + return function(e) { | ||
155 | + return _this.progress(e); | ||
156 | + }; | ||
157 | + })(this); | ||
158 | + } | ||
159 | + return req; | ||
160 | + }, | ||
161 | + progress: (function(_this) { | ||
162 | + return function(e) { | ||
163 | + if (!e.lengthComputable) { | ||
164 | + return; | ||
165 | + } | ||
166 | + return _this.trigger('uploadprogress', [file, e.loaded, e.total]); | ||
167 | + }; | ||
168 | + })(this), | ||
169 | + error: (function(_this) { | ||
170 | + return function(xhr, status, err) { | ||
171 | + return _this.trigger('uploaderror', [file, xhr, status]); | ||
172 | + }; | ||
173 | + })(this), | ||
174 | + success: (function(_this) { | ||
175 | + return function(result) { | ||
176 | + _this.trigger('uploadprogress', [file, file.size, file.size]); | ||
177 | + _this.trigger('uploadsuccess', [file, result]); | ||
178 | + return $(document).trigger('uploadsuccess', [file, result, _this]); | ||
179 | + }; | ||
180 | + })(this), | ||
181 | + complete: (function(_this) { | ||
182 | + return function(xhr, status) { | ||
183 | + return _this.trigger('uploadcomplete', [file, xhr.responseText]); | ||
184 | + }; | ||
185 | + })(this) | ||
186 | + }); | ||
187 | + }; | ||
188 | + | ||
189 | + Uploader.prototype.cancel = function(file) { | ||
190 | + var f, i, len, ref; | ||
191 | + if (!file.id) { | ||
192 | + ref = this.files; | ||
193 | + for (i = 0, len = ref.length; i < len; i++) { | ||
194 | + f = ref[i]; | ||
195 | + if (f.id === file * 1) { | ||
196 | + file = f; | ||
197 | + break; | ||
198 | + } | ||
199 | + } | ||
200 | + } | ||
201 | + this.trigger('uploadcancel', [file]); | ||
202 | + if (file.xhr) { | ||
203 | + file.xhr.abort(); | ||
204 | + } | ||
205 | + return file.xhr = null; | ||
206 | + }; | ||
207 | + | ||
208 | + Uploader.prototype.readImageFile = function(fileObj, callback) { | ||
209 | + var fileReader, img; | ||
210 | + if (!$.isFunction(callback)) { | ||
211 | + return; | ||
212 | + } | ||
213 | + img = new Image(); | ||
214 | + img.onload = function() { | ||
215 | + return callback(img); | ||
216 | + }; | ||
217 | + img.onerror = function() { | ||
218 | + return callback(); | ||
219 | + }; | ||
220 | + if (window.FileReader && FileReader.prototype.readAsDataURL && /^image/.test(fileObj.type)) { | ||
221 | + fileReader = new FileReader(); | ||
222 | + fileReader.onload = function(e) { | ||
223 | + return img.src = e.target.result; | ||
224 | + }; | ||
225 | + return fileReader.readAsDataURL(fileObj); | ||
226 | + } else { | ||
227 | + return callback(); | ||
228 | + } | ||
229 | + }; | ||
230 | + | ||
231 | + Uploader.prototype.destroy = function() { | ||
232 | + var file, i, len, ref; | ||
233 | + this.queue.length = 0; | ||
234 | + ref = this.files; | ||
235 | + for (i = 0, len = ref.length; i < len; i++) { | ||
236 | + file = ref[i]; | ||
237 | + this.cancel(file); | ||
238 | + } | ||
239 | + $(window).off('.uploader-' + this.id); | ||
240 | + return $(document).off('.uploader-' + this.id); | ||
241 | + }; | ||
242 | + | ||
243 | + Uploader.i18n = { | ||
244 | + 'zh-CN': { | ||
245 | + leaveConfirm: '正在上传文件,如果离开上传会自动取消' | ||
246 | + } | ||
247 | + }; | ||
248 | + | ||
249 | + Uploader.locale = 'zh-CN'; | ||
250 | + | ||
251 | + return Uploader; | ||
252 | + | ||
253 | +})(SimpleModule); | ||
254 | + | ||
255 | +uploader = function(opts) { | ||
256 | + return new Uploader(opts); | ||
257 | +}; | ||
258 | + | ||
259 | +return uploader; | ||
260 | + | ||
261 | +})); |
application/admin/behavior/AdminLog.php
0 → 100755
application/admin/command/Addon.php
0 → 100755
1 | +<?php | ||
2 | + | ||
3 | +namespace app\admin\command; | ||
4 | + | ||
5 | +use think\addons\AddonException; | ||
6 | +use think\addons\Service; | ||
7 | +use think\Config; | ||
8 | +use think\console\Command; | ||
9 | +use think\console\Input; | ||
10 | +use think\console\input\Option; | ||
11 | +use think\console\Output; | ||
12 | +use think\Db; | ||
13 | +use think\Exception; | ||
14 | +use think\exception\PDOException; | ||
15 | + | ||
16 | +class Addon extends Command | ||
17 | +{ | ||
18 | + | ||
19 | + protected function configure() | ||
20 | + { | ||
21 | + $this | ||
22 | + ->setName('addon') | ||
23 | + ->addOption('name', 'a', Option::VALUE_REQUIRED, 'addon name', null) | ||
24 | + ->addOption('action', 'c', Option::VALUE_REQUIRED, 'action(create/enable/disable/uninstall/refresh/package/move)', 'create') | ||
25 | + ->addOption('force', 'f', Option::VALUE_OPTIONAL, 'force override', null) | ||
26 | + ->addOption('release', 'r', Option::VALUE_OPTIONAL, 'addon release version', null) | ||
27 | + ->addOption('uid', 'u', Option::VALUE_OPTIONAL, 'fastadmin uid', null) | ||
28 | + ->addOption('token', 't', Option::VALUE_OPTIONAL, 'fastadmin token', null) | ||
29 | + ->addOption('domain', 'd', Option::VALUE_OPTIONAL, 'domain', null) | ||
30 | + ->addOption('local', 'l', Option::VALUE_OPTIONAL, 'local package', null) | ||
31 | + ->setDescription('Addon manager'); | ||
32 | + } | ||
33 | + | ||
34 | + protected function execute(Input $input, Output $output) | ||
35 | + { | ||
36 | + $name = $input->getOption('name') ?: ''; | ||
37 | + $action = $input->getOption('action') ?: ''; | ||
38 | + if (stripos($name, 'addons' . DS) !== false) { | ||
39 | + $name = explode(DS, $name)[1]; | ||
40 | + } | ||
41 | + //强制覆盖 | ||
42 | + $force = $input->getOption('force'); | ||
43 | + //版本 | ||
44 | + $release = $input->getOption('release') ?: ''; | ||
45 | + //uid | ||
46 | + $uid = $input->getOption('uid') ?: ''; | ||
47 | + //token | ||
48 | + $token = $input->getOption('token') ?: ''; | ||
49 | + | ||
50 | + include dirname(__DIR__) . DS . 'common.php'; | ||
51 | + | ||
52 | + if (!$name && !in_array($action, ['refresh'])) { | ||
53 | + throw new Exception('Addon name could not be empty'); | ||
54 | + } | ||
55 | + if (!$action || !in_array($action, ['create', 'disable', 'enable', 'install', 'uninstall', 'refresh', 'upgrade', 'package', 'move'])) { | ||
56 | + throw new Exception('Please input correct action name'); | ||
57 | + } | ||
58 | + | ||
59 | + // 查询一次SQL,判断连接是否正常 | ||
60 | + Db::execute("SELECT 1"); | ||
61 | + | ||
62 | + $addonDir = ADDON_PATH . $name . DS; | ||
63 | + switch ($action) { | ||
64 | + case 'create': | ||
65 | + //非覆盖模式时如果存在则报错 | ||
66 | + if (is_dir($addonDir) && !$force) { | ||
67 | + throw new Exception("addon already exists!\nIf you need to create again, use the parameter --force=true "); | ||
68 | + } | ||
69 | + //如果存在先移除 | ||
70 | + if (is_dir($addonDir)) { | ||
71 | + rmdirs($addonDir); | ||
72 | + } | ||
73 | + mkdir($addonDir, 0755, true); | ||
74 | + mkdir($addonDir . DS . 'controller', 0755, true); | ||
75 | + $menuList = \app\common\library\Menu::export($name); | ||
76 | + $createMenu = $this->getCreateMenu($menuList); | ||
77 | + $prefix = Config::get('database.prefix'); | ||
78 | + $createTableSql = ''; | ||
79 | + try { | ||
80 | + $result = Db::query("SHOW CREATE TABLE `" . $prefix . $name . "`;"); | ||
81 | + if (isset($result[0]) && isset($result[0]['Create Table'])) { | ||
82 | + $createTableSql = $result[0]['Create Table']; | ||
83 | + } | ||
84 | + } catch (PDOException $e) { | ||
85 | + | ||
86 | + } | ||
87 | + | ||
88 | + $data = [ | ||
89 | + 'name' => $name, | ||
90 | + 'addon' => $name, | ||
91 | + 'addonClassName' => ucfirst($name), | ||
92 | + 'addonInstallMenu' => $createMenu ? "\$menu = " . var_export_short($createMenu) . ";\n\tMenu::create(\$menu);" : '', | ||
93 | + 'addonUninstallMenu' => $menuList ? 'Menu::delete("' . $name . '");' : '', | ||
94 | + 'addonEnableMenu' => $menuList ? 'Menu::enable("' . $name . '");' : '', | ||
95 | + 'addonDisableMenu' => $menuList ? 'Menu::disable("' . $name . '");' : '', | ||
96 | + ]; | ||
97 | + $this->writeToFile("addon", $data, $addonDir . ucfirst($name) . '.php'); | ||
98 | + $this->writeToFile("config", $data, $addonDir . 'config.php'); | ||
99 | + $this->writeToFile("info", $data, $addonDir . 'info.ini'); | ||
100 | + $this->writeToFile("controller", $data, $addonDir . 'controller' . DS . 'Index.php'); | ||
101 | + if ($createTableSql) { | ||
102 | + $createTableSql = str_replace("`" . $prefix, '`__PREFIX__', $createTableSql); | ||
103 | + file_put_contents($addonDir . 'install.sql', $createTableSql); | ||
104 | + } | ||
105 | + | ||
106 | + $output->info("Create Successed!"); | ||
107 | + break; | ||
108 | + case 'disable': | ||
109 | + case 'enable': | ||
110 | + try { | ||
111 | + //调用启用、禁用的方法 | ||
112 | + Service::$action($name, 0); | ||
113 | + } catch (AddonException $e) { | ||
114 | + if ($e->getCode() != -3) { | ||
115 | + throw new Exception($e->getMessage()); | ||
116 | + } | ||
117 | + if (!$force) { | ||
118 | + //如果有冲突文件则提醒 | ||
119 | + $data = $e->getData(); | ||
120 | + foreach ($data['conflictlist'] as $k => $v) { | ||
121 | + $output->warning($v); | ||
122 | + } | ||
123 | + $output->info("Are you sure you want to " . ($action == 'enable' ? 'override' : 'delete') . " all those files? Type 'yes' to continue: "); | ||
124 | + $line = fgets(defined('STDIN') ? STDIN : fopen('php://stdin', 'r')); | ||
125 | + if (trim($line) != 'yes') { | ||
126 | + throw new Exception("Operation is aborted!"); | ||
127 | + } | ||
128 | + } | ||
129 | + //调用启用、禁用的方法 | ||
130 | + Service::$action($name, 1); | ||
131 | + } catch (Exception $e) { | ||
132 | + throw new Exception($e->getMessage()); | ||
133 | + } | ||
134 | + $output->info(ucfirst($action) . " Successed!"); | ||
135 | + break; | ||
136 | + case 'uninstall': | ||
137 | + //非覆盖模式时如果存在则报错 | ||
138 | + if (!$force) { | ||
139 | + throw new Exception("If you need to uninstall addon, use the parameter --force=true "); | ||
140 | + } | ||
141 | + try { | ||
142 | + Service::uninstall($name, 0); | ||
143 | + } catch (AddonException $e) { | ||
144 | + if ($e->getCode() != -3) { | ||
145 | + throw new Exception($e->getMessage()); | ||
146 | + } | ||
147 | + if (!$force) { | ||
148 | + //如果有冲突文件则提醒 | ||
149 | + $data = $e->getData(); | ||
150 | + foreach ($data['conflictlist'] as $k => $v) { | ||
151 | + $output->warning($v); | ||
152 | + } | ||
153 | + $output->info("Are you sure you want to delete all those files? Type 'yes' to continue: "); | ||
154 | + $line = fgets(defined('STDIN') ? STDIN : fopen('php://stdin', 'r')); | ||
155 | + if (trim($line) != 'yes') { | ||
156 | + throw new Exception("Operation is aborted!"); | ||
157 | + } | ||
158 | + } | ||
159 | + Service::uninstall($name, 1); | ||
160 | + } catch (Exception $e) { | ||
161 | + throw new Exception($e->getMessage()); | ||
162 | + } | ||
163 | + | ||
164 | + $output->info("Uninstall Successed!"); | ||
165 | + break; | ||
166 | + case 'refresh': | ||
167 | + Service::refresh(); | ||
168 | + $output->info("Refresh Successed!"); | ||
169 | + break; | ||
170 | + case 'package': | ||
171 | + $infoFile = $addonDir . 'info.ini'; | ||
172 | + if (!is_file($infoFile)) { | ||
173 | + throw new Exception(__('Addon info file was not found')); | ||
174 | + } | ||
175 | + | ||
176 | + $info = get_addon_info($name); | ||
177 | + if (!$info) { | ||
178 | + throw new Exception(__('Addon info file data incorrect')); | ||
179 | + } | ||
180 | + $infoname = isset($info['name']) ? $info['name'] : ''; | ||
181 | + if (!$infoname || !preg_match("/^[a-z]+$/i", $infoname) || $infoname != $name) { | ||
182 | + throw new Exception(__('Addon info name incorrect')); | ||
183 | + } | ||
184 | + | ||
185 | + $infoversion = isset($info['version']) ? $info['version'] : ''; | ||
186 | + if (!$infoversion || !preg_match("/^\d+\.\d+\.\d+$/i", $infoversion)) { | ||
187 | + throw new Exception(__('Addon info version incorrect')); | ||
188 | + } | ||
189 | + | ||
190 | + $addonTmpDir = RUNTIME_PATH . 'addons' . DS; | ||
191 | + if (!is_dir($addonTmpDir)) { | ||
192 | + @mkdir($addonTmpDir, 0755, true); | ||
193 | + } | ||
194 | + $addonFile = $addonTmpDir . $infoname . '-' . $infoversion . '.zip'; | ||
195 | + if (!class_exists('ZipArchive')) { | ||
196 | + throw new Exception(__('ZinArchive not install')); | ||
197 | + } | ||
198 | + $zip = new \ZipArchive; | ||
199 | + $zip->open($addonFile, \ZipArchive::CREATE | \ZipArchive::OVERWRITE); | ||
200 | + | ||
201 | + $files = new \RecursiveIteratorIterator( | ||
202 | + new \RecursiveDirectoryIterator($addonDir), \RecursiveIteratorIterator::LEAVES_ONLY | ||
203 | + ); | ||
204 | + | ||
205 | + foreach ($files as $name => $file) { | ||
206 | + if (!$file->isDir()) { | ||
207 | + $filePath = $file->getRealPath(); | ||
208 | + $relativePath = str_replace(DS, '/', substr($filePath, strlen($addonDir))); | ||
209 | + if (!in_array($file->getFilename(), ['.git', '.DS_Store', 'Thumbs.db'])) { | ||
210 | + $zip->addFile($filePath, $relativePath); | ||
211 | + } | ||
212 | + } | ||
213 | + } | ||
214 | + $zip->close(); | ||
215 | + $output->info("Package Successed!"); | ||
216 | + break; | ||
217 | + case 'move': | ||
218 | + $movePath = [ | ||
219 | + 'adminOnlySelfDir' => ['admin/behavior', 'admin/controller', 'admin/library', 'admin/model', 'admin/validate', 'admin/view'], | ||
220 | + 'adminAllSubDir' => ['admin/lang'], | ||
221 | + 'publicDir' => ['public/assets/addons', 'public/assets/js/backend'] | ||
222 | + ]; | ||
223 | + $paths = []; | ||
224 | + $appPath = str_replace('/', DS, APP_PATH); | ||
225 | + $rootPath = str_replace('/', DS, ROOT_PATH); | ||
226 | + foreach ($movePath as $k => $items) { | ||
227 | + switch ($k) { | ||
228 | + case 'adminOnlySelfDir': | ||
229 | + foreach ($items as $v) { | ||
230 | + $v = str_replace('/', DS, $v); | ||
231 | + $oldPath = $appPath . $v . DS . $name; | ||
232 | + $newPath = $rootPath . "addons" . DS . $name . DS . "application" . DS . $v . DS . $name; | ||
233 | + $paths[$oldPath] = $newPath; | ||
234 | + } | ||
235 | + break; | ||
236 | + case 'adminAllSubDir': | ||
237 | + foreach ($items as $v) { | ||
238 | + $v = str_replace('/', DS, $v); | ||
239 | + $vPath = $appPath . $v; | ||
240 | + $list = scandir($vPath); | ||
241 | + foreach ($list as $_v) { | ||
242 | + if (!in_array($_v, ['.', '..']) && is_dir($vPath . DS . $_v)) { | ||
243 | + $oldPath = $appPath . $v . DS . $_v . DS . $name; | ||
244 | + $newPath = $rootPath . "addons" . DS . $name . DS . "application" . DS . $v . DS . $_v . DS . $name; | ||
245 | + $paths[$oldPath] = $newPath; | ||
246 | + } | ||
247 | + } | ||
248 | + } | ||
249 | + break; | ||
250 | + case 'publicDir': | ||
251 | + foreach ($items as $v) { | ||
252 | + $v = str_replace('/', DS, $v); | ||
253 | + $oldPath = $rootPath . $v . DS . $name; | ||
254 | + $newPath = $rootPath . 'addons' . DS . $name . DS . $v . DS . $name; | ||
255 | + $paths[$oldPath] = $newPath; | ||
256 | + } | ||
257 | + break; | ||
258 | + } | ||
259 | + } | ||
260 | + foreach ($paths as $oldPath => $newPath) { | ||
261 | + if (is_dir($oldPath)) { | ||
262 | + if ($force) { | ||
263 | + if (is_dir($newPath)) { | ||
264 | + $list = scandir($newPath); | ||
265 | + foreach ($list as $_v) { | ||
266 | + if (!in_array($_v, ['.', '..'])) { | ||
267 | + $file = $newPath . DS . $_v; | ||
268 | + @chmod($file, 0777); | ||
269 | + @unlink($file); | ||
270 | + } | ||
271 | + } | ||
272 | + @rmdir($newPath); | ||
273 | + } | ||
274 | + } | ||
275 | + copydirs($oldPath, $newPath); | ||
276 | + } | ||
277 | + } | ||
278 | + break; | ||
279 | + default: | ||
280 | + break; | ||
281 | + } | ||
282 | + } | ||
283 | + | ||
284 | + /** | ||
285 | + * 获取创建菜单的数组 | ||
286 | + * @param array $menu | ||
287 | + * @return array | ||
288 | + */ | ||
289 | + protected function getCreateMenu($menu) | ||
290 | + { | ||
291 | + $result = []; | ||
292 | + foreach ($menu as $k => & $v) { | ||
293 | + $arr = [ | ||
294 | + 'name' => $v['name'], | ||
295 | + 'title' => $v['title'], | ||
296 | + ]; | ||
297 | + if ($v['icon'] != 'fa fa-circle-o') { | ||
298 | + $arr['icon'] = $v['icon']; | ||
299 | + } | ||
300 | + if ($v['ismenu']) { | ||
301 | + $arr['ismenu'] = $v['ismenu']; | ||
302 | + } | ||
303 | + if (isset($v['childlist']) && $v['childlist']) { | ||
304 | + $arr['sublist'] = $this->getCreateMenu($v['childlist']); | ||
305 | + } | ||
306 | + $result[] = $arr; | ||
307 | + } | ||
308 | + return $result; | ||
309 | + } | ||
310 | + | ||
311 | + /** | ||
312 | + * 写入到文件 | ||
313 | + * @param string $name | ||
314 | + * @param array $data | ||
315 | + * @param string $pathname | ||
316 | + * @return mixed | ||
317 | + */ | ||
318 | + protected function writeToFile($name, $data, $pathname) | ||
319 | + { | ||
320 | + $search = $replace = []; | ||
321 | + foreach ($data as $k => $v) { | ||
322 | + $search[] = "{%{$k}%}"; | ||
323 | + $replace[] = $v; | ||
324 | + } | ||
325 | + $stub = file_get_contents($this->getStub($name)); | ||
326 | + $content = str_replace($search, $replace, $stub); | ||
327 | + | ||
328 | + if (!is_dir(dirname($pathname))) { | ||
329 | + mkdir(strtolower(dirname($pathname)), 0755, true); | ||
330 | + } | ||
331 | + return file_put_contents($pathname, $content); | ||
332 | + } | ||
333 | + | ||
334 | + /** | ||
335 | + * 获取基础模板 | ||
336 | + * @param string $name | ||
337 | + * @return string | ||
338 | + */ | ||
339 | + protected function getStub($name) | ||
340 | + { | ||
341 | + return __DIR__ . '/Addon/stubs/' . $name . '.stub'; | ||
342 | + } | ||
343 | + | ||
344 | +} |
1 | +<?php | ||
2 | + | ||
3 | +namespace addons\{%name%}; | ||
4 | + | ||
5 | +use app\common\library\Menu; | ||
6 | +use think\Addons; | ||
7 | + | ||
8 | +/** | ||
9 | + * 插件 | ||
10 | + */ | ||
11 | +class {%addonClassName%} extends Addons | ||
12 | +{ | ||
13 | + | ||
14 | + /** | ||
15 | + * 插件安装方法 | ||
16 | + * @return bool | ||
17 | + */ | ||
18 | + public function install() | ||
19 | + { | ||
20 | + {%addonInstallMenu%} | ||
21 | + return true; | ||
22 | + } | ||
23 | + | ||
24 | + /** | ||
25 | + * 插件卸载方法 | ||
26 | + * @return bool | ||
27 | + */ | ||
28 | + public function uninstall() | ||
29 | + { | ||
30 | + {%addonUninstallMenu%} | ||
31 | + return true; | ||
32 | + } | ||
33 | + | ||
34 | + /** | ||
35 | + * 插件启用方法 | ||
36 | + * @return bool | ||
37 | + */ | ||
38 | + public function enable() | ||
39 | + { | ||
40 | + {%addonEnableMenu%} | ||
41 | + return true; | ||
42 | + } | ||
43 | + | ||
44 | + /** | ||
45 | + * 插件禁用方法 | ||
46 | + * @return bool | ||
47 | + */ | ||
48 | + public function disable() | ||
49 | + { | ||
50 | + {%addonDisableMenu%} | ||
51 | + return true; | ||
52 | + } | ||
53 | + | ||
54 | +} |
1 | +<?php | ||
2 | + | ||
3 | +return [ | ||
4 | + [ | ||
5 | + //配置唯一标识 | ||
6 | + 'name' => 'usernmae', | ||
7 | + //显示的标题 | ||
8 | + 'title' => '用户名', | ||
9 | + //类型 | ||
10 | + 'type' => 'string', | ||
11 | + //分组 | ||
12 | + 'group' => '', | ||
13 | + //动态显示 | ||
14 | + 'visible' => '', | ||
15 | + //数据字典 | ||
16 | + 'content' => [ | ||
17 | + ], | ||
18 | + //值 | ||
19 | + 'value' => '', | ||
20 | + //验证规则 | ||
21 | + 'rule' => 'required', | ||
22 | + //错误消息 | ||
23 | + 'msg' => '', | ||
24 | + //提示消息 | ||
25 | + 'tip' => '', | ||
26 | + //成功消息 | ||
27 | + 'ok' => '', | ||
28 | + //扩展信息 | ||
29 | + 'extend' => '' | ||
30 | + ], | ||
31 | + [ | ||
32 | + 'name' => 'password', | ||
33 | + 'title' => '密码', | ||
34 | + 'type' => 'string', | ||
35 | + 'content' => [ | ||
36 | + ], | ||
37 | + 'value' => '', | ||
38 | + 'rule' => 'required', | ||
39 | + 'msg' => '', | ||
40 | + 'tip' => '', | ||
41 | + 'ok' => '', | ||
42 | + 'extend' => '' | ||
43 | + ], | ||
44 | +]; |
-
请 注册 或 登录 后发表评论