Initial commit

This commit is contained in:
Luthics 2023-08-30 16:25:41 +08:00
commit 9cdedd63aa
1554 changed files with 203728 additions and 0 deletions

30
.env.example Executable file
View File

@ -0,0 +1,30 @@
APP_ENV=local
APP_DEBUG=
APP_MAINTENANCE=
DB_CONNECTION=
DB_HOST=
DB_PORT=
DB_DATABASE=
DB_USERNAME=
DB_PASSWORD=
DB_PREFIX=
ELASTICSEARCH_HOSTS=
ALIOSS_ACCESS_KEY_ID=
ALIOSS_ACCESS_KEY_SECRET=
IMAGEPROXY_URL=
IMAGEPROXY_REMOTE=
# 阿里云点播服务
VOD_ACCESS_KEY=
VOD_ACCESS_SECRET=
UPLOADER_ROLE_RAN=
PLAY_ROLE_RAN=
FULL_ROLE_RAN=
# 微信公众号
WX_APPID=
WX_APPSECRET=

16
.gitignore vendored Executable file
View File

@ -0,0 +1,16 @@
/nbproject/
/.idea
/js-src
/.vscode
/vendor
/.tmp
.env
/package
/www/Public/libs
/www/Uploads
/app/Runtime
/lara/storage
/lara/vendor/composer/installed.json
/node_modules
.phpunit.result.cache

1
.htaccess Executable file
View File

@ -0,0 +1 @@

7
404.html Executable file
View File

@ -0,0 +1,7 @@
<html>
<head><title>404 Not Found</title></head>
<body>
<center><h1>404 Not Found</h1></center>
<hr><center>nginx</center>
</body>
</html>

8
FrameSelector.php Executable file
View File

@ -0,0 +1,8 @@
<?php
class FrameSelector{
public static function load(){
require __DIR__ . '/tp.php';
}
}

201
LICENSE Executable file
View File

@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

46
LICENSE.996ICU Executable file
View File

@ -0,0 +1,46 @@
Copyright (c) <2019> <tiderjian>
996 License Version 1.0
Permission is hereby granted to any individual or legal entity
obtaining a copy of this licensed work (including the source code,
documentation and/or related items, hereinafter collectively referred
to as the "licensed work"), free of charge, to deal with the licensed
work for any purpose, including without limitation, the rights to use,
reproduce, prepare derivative works of, distribute and sublicense the
licensed work, subject to the following conditions:
1. The individual or the legal entity must conspicuously display,
without modification, this License on each redistributed or derivative
copy of the Licensed Work.
2. The individual or the legal entity must strictly comply with all
applicable laws, regulations, rules and standards of the jurisdiction
relating to labor and employment where the individual is physically
located or where the individual was born or naturalized; or where the
legal entity is registered or is operating (whichever is stricter). In
case that the jurisdiction has no such laws, regulations, rules and
standards or its laws, regulations, rules and standards are
unenforceable, the individual or the legal entity are required to
comply with Core International Labor Standards.
3. The individual or the legal entity shall not induce or force its
employee(s), whether full-time or part-time, or its independent
contractor(s), in any methods, to agree in oral or written form, to
directly or indirectly restrict, weaken or relinquish his or her
rights or remedies under such laws, regulations, rules and standards
relating to labor and employment as mentioned above, no matter whether
such written or oral agreement are enforceable under the laws of the
said jurisdiction, nor shall such individual or the legal entity
limit, in any methods, the rights of its employee(s) or independent
contractor(s) from reporting or complaining to the copyright holder or
relevant authorities monitoring the compliance of the license about
its violation(s) of the said license.
THE LICENSED WORK IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM, OUT OF OR IN ANY WAY CONNECTION WITH THE
LICENSED WORK OR THE USE OR OTHER DEALINGS IN THE LICENSED WORK.

21
LICENSE.MIT Executable file
View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2019 tiderjian
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

2
PackageConfig.php Executable file
View File

@ -0,0 +1,2 @@
<?php
return [];

684
README.md Executable file
View File

@ -0,0 +1,684 @@
# qscmf
![lincense](https://img.shields.io/badge/license-MIT-blue.svg?style=flat-square)
[![LICENSE](https://img.shields.io/badge/license-Anti%20996-blue.svg)](https://github.com/996icu/996.ICU/blob/master/LICENSE)
![Pull request welcome](https://img.shields.io/badge/pr-welcome-green.svg?style=flat-square)
## 介绍
快速搭建信息管理类系统的框架。基于tp3.2开发,在其基础上添加了许多功能特性。tp3.2已经停止更新,该框架源码也对核心源码做了部分改动。
## 特性
+ 支持composer依赖管理
+ 支持phpunit及laravel dusk自动化测试
+ 集成laravel数据库管理工具及依赖注入容器
+ 支持ListBuilder、FormBuilder后台管理界面模块化开发
+ 插件系统
+ 简单易用,可自定义的配置管理
+ 消息队列系统
+ 集成Elasticsearch、可自定义索引重建自制实现数据库记录与搜索引擎索引同步变动
## 截图
<img src="https://user-images.githubusercontent.com/1665649/55472251-36458e80-563e-11e9-87c0-10c386d5bd78.png" />
## 安装
第一种安装方法
```
git clone https://github.com/tiderjian/qs_cmf.git
```
代码拉取完成后执行composer安装
```
composer install
```
第二种安装方法composer create project
```php
composer create-project tiderjian/qscmf qscmf
```
完成第一种或者第二种安装后
1. 复制.env.example并重命名为.env配置数据库参数
2. 执行migrate数据库迁移命令。
```
php artisan migrate
```
将web服务器搭起来后后台登录地址 协议://域名:端口/admin 账号:admin 密码:Qs123!@#
## 维护模式
在.env将 APP_MAINTENANCE 设成true系统进入维护状态所有请求都只会提示系统维护中。如需要在维护模式下执行升级脚本可传递"maintenance"给第三个参数
```php
php index.php Qscmf/UpgradeFix/v300FixSchedule/queue/default maintenance
```
## Elasticsearch
框架为集成Elasticsearch提供了方便的方法, 假设使用者已经具备elasticsearch使用的相关知识。
1. 添加 "elasticsearch/elasticsearch": "~6.0" 到composer.json文件执行composer update 命令安装扩展包。
2. 安装elasticsearch, 具体安装方法自行查找推荐使用laradock作为开发环境直接集成了elasticsearch的docker安装环境。
3. 安装ik插件安装查找elasticsearch官方文档。
4. 在.env下添加 ELASTICSEARCH_HOSTS值设置为elasticsearch的启动ip和端口如laradock的默认设置为10.0.75.1:9200需要配置一组地址可用“,”隔开。
5. 设置需要使用elastic的model和字段
以ChapterModel添加title和summary到全文索引为例
```php
// ChapterModel类必须继承接口
class ChapterModel extends \Gy_Library\GyListModel implements \Qscmf\Lib\Elasticsearch\ElasticsearchModelContract{
// ElasticsearchHelper已经实现了一些帮助函数
use \Qscmf\Lib\Elasticsearch\ElasticsearchHelper;
// 初始化全文索引时需要指定该Model要添加的索引记录
public function elasticsearchIndexList()
{
// 如这里chapter表与course表关联只有当course及chapter状态都为可用且非描述类chapter(pid = 0为描述类chapter)才会添加全文索引
return $this->alias('ch')->join('__COURSE__ c ON c.id=ch.course_id and c.status = ' . DBCont::NORMAL_STATUS)->where(['ch.status' => DBCont::NORMAL_STATUS, 'ch.pid' => ['neq', 0]])->field('ch.*')->select();
}
// chapter进行增删查改时同时会更新索引内容该方法是指定什么状态的记录才会进行索引更改
// 返回false为无需索引的记录true则会进行索引更新
public function isElasticsearchIndex($ent){
if($ent['status'] != DBCont::NORMAL_STATUS || $ent['pid'] == 0){
return false;
}
$course_ent = D('Course')->find($ent['course_id']);
if($course_ent['status'] == DBCont::NORMAL_STATUS){
return true;
}
else{
return false;
}
}
// 程序会自动生成索引的配置参数,此处是定义生成参数的规则
// 以:开头的字母表示该处会自动替换成相应字段的实际值
// {}表示里面的字符会与替换后的:字段值进行连接,如:id{_chapter}, id实际值为 12则该处会替换成 12_chapter
// | 表示可以将字段的实际值传递给指定的函数进行处理转换成想要的值。如description字段是富文本内容我们将html标签进行索引可以在model方法里自定义一个叫deleteHtmlTag的方法进行处理当然也可以定义为全局函数程序会先查找全局是否存在该函数如果没有再去对象里查找有无该方法
// index和type的值在建立初始化全文索引时指定具体查看全文索引初始化说明
public function elasticsearchAddDataParams()
{
return [
'index' => 'global_search',
'type' => 'content',
'id' => ':id{_chapter}',
'body' => [
'title' => ':title',
'desc' => ':description|html_entity_decode'
]
];
}
}
```
6. 初始化全文索引
打开Home/Controller/ElasticController.class.php文件, 修改index方法里的$params变量根据你的需要来设置
7. 执行索引初始化,程序会自动检索数据库全部数据表,为需要添加索引的表和字段进行索引添加操作。
```
//进入app目录下面有个makeIndex.php文件
php makeIndex.php
```
8. 可通过在config文件设置 "ELASTIC_ALLOW_EXCEPTION" 来禁止抛出异常,即使搜索引擎关闭,也不会影响原来的业务操作。
9. 更新操作的索引重建仅会在索引字段发生变化时才会触发。
## Controller
[传送门](https://github.com/quansitech/qs_cmf/blob/master/docs/Controller.md)
## Model
[传送门](https://github.com/quansitech/qs_cmf/blob/master/docs/Model.md)
## 数据库迁移
扩展了laravel的迁移功能, 可在执行迁移前后插入一些操作。
```php
class CreateTestTable extends Migration
{
public function beforeCmmUp()
{
echo "执行前置命令" . PHP_EOL;
}
public function beforeCmmDown()
{
echo "执行前置回滚命令" . PHP_EOL;
}
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('test', function (Blueprint $table) {
$table->bigIncrements('id');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('test');
}
public function afterCmmUp()
{
echo "执行后置命令" . PHP_EOL;
}
public function afterCmmDown()
{
echo "执行后置回滚命令" . PHP_EOL;
}
}
```
运用场景:
迁移文件是为了方便我们对数据库结构进行变更管理。那么是所有的数据库变更都会放到迁移文件处理吗?当然不是,像一些跟业务逻辑有关的数据处理就不应该放到迁移文件,否则这部分代码跟
业务数据捆绑,很容易导致执行迁移时出错。而只有那些跟业务数据无关,用于构造系统数据存储结构的变更操作才应该放到迁移中。但一个业务系统维护久了,难免必须处理一些数据后才能正常
执行数据库结构变更,例如唯一索引的创建往往就需要我们清理掉一些重复的业务数据。这时就有了不能放在迁移里的业务数据维护脚本的管理需求。
依托上面的场景,就有了在迁移文件中加入了前后置的操作点的构思。默认情况下,只要设置了前后置操作点,执行迁移时就会自动执行一遍,回滚类同。
那么如果只是想执行迁移而不执行前后置操作怎么办呢(例如执行自动测试脚本前,我们会自动构建系统的数据库)。只需在命令后面加入 --no-cmd即可
下面是支持加入--no-cmd操作的命令
```php
php artisan migrate --no-cmd
php artisan migrate:rollback --no-cmd
php artisan migrate:fresh --no-cmd
php artisan migrate:refresh --no-cmd
php artisan migrate:reset --no-cmd
```
+ CmmProcess
该类是为了方便在迁移中调用tp的脚本
> 用法:
>
> ```php
> $process = new \Larafortp\CmmMigrate\CmmProcess();
> //timeout为程序的超时退出时间默认60秒
> $process->setTimeOut(100)->callTp('/var/www/move/www/index.php', '/home/index/test');
> ```
+ ConfigGenerator
迁移中处理系统配置的工具类
addGroup($name) //添加配置分组
deleteGroup($name) //删除配置分组
updateGroup($config_name, $group_name) //将配置转移到指定分组
以下为新增配置项的操作函数
> $name 配置名
>
> $title 配置标题
>
> $value 配置值
>
> $remark 配置说明
>
> $group 配置分组
>
> $sort 排序
addNum($name, $title, $value, $remark = '', $group = 1, $sort = 0) //新增数字类型配置值
addText($name, $title, $value, $remark = '', $group = 1, $sort = 0) //新增字符类型配置值
addArray($name, $title, $value, $remark = '', $group = 1, $sort = 0) //新增数组类型配置值
addPicture($name, $title, $value, $remark = '', $group = 1, $sort = 0) //新增图片类型配置值
addUeditor($name, $title, $value, $remark = '', $group = 1, $sort = 0) //新增富文本类型配置值
addSelect($name, $title, $value, $options, $remark = '', $group = 1, $sort = 0) //新增下拉选择配置值 $options 是下拉配置数组
add($name, $type, $title, $group, $extra, $remark, $value, $sort) //新增配置方法,未预设的第三方组件可使用该函数
delete($name) //删除配置
## 后台JS
[传送门](https://github.com/quansitech/qs_cmf/blob/master/docs/BackendJs.md)
## ListBuilder
[传送门](https://github.com/quansitech/qs_cmf/blob/master/docs/ListBuilder.md)
## FormBuilder
[传送门](https://github.com/quansitech/qs_cmf/blob/master/docs/FormBuilder.md)
## CompareBuilder
[传送门](https://github.com/quansitech/qs_cmf/blob/master/docs/CompareBuilder.md)
## Builder
[传送门](https://github.com/quansitech/qs_cmf/blob/master/docs/Builder.md)
## Cache
[传送门](https://github.com/quansitech/qs_cmf/blob/master/docs/Cache.md)
## 前台js错误收集
#### 用法
在前端head中引入log.js后调用frontLog方法
```php
<script src="__PUBLIC__/libs/log.js"></script>
<script>
frontLog({
url:'/api/jsLog/index'
});
</script>
```
## 数据库帮助函数
generator
> 低内存消耗迭代函数
>
> 参数
>
> 1. $map 查询参数 默认为空数组
> 2. $count 一次查询的数据量,越大占用的内存会大,但运行效率会更高,根据情况灵活调整 默认为 1
>
> 举例
>
> ```php
> foreach(D("Content")->generator([], 200) as $ent){
> var_dump($ent);
> }
> ```
## 权限功能
[传送门](https://github.com/quansitech/qs_cmf/blob/master/docs/Auth.md)
## 微信登录
为解决第三方平台网站应用的PC扫码后openid不可操作问题统一对PC端微信扫码以及微信端登录进行封装。
* 从[微信公众平台](https://mp.weixin.qq.com/)中获取公众号的app_id和app_secret并进行相关配置放入.env文件
```dotenv
# 微信公众号
WX_APPID=
WX_APPSECRET=
```
* PC扫码页面在需要显示二维码的地方加入iframe
```html
<iframe src="{:U('qscmf/weixinLogin/scan')}"></iframe>
```
PS:
1. 构造iframe的src时可通过goto_url参数来指定PC端扫码后跳转的地址默认为首页
2. 构造iframe的src时可通过mobile_goto_url参数来指定微信端扫码后跳转的地址默认为首页
* 微信端获取登录信息
```php
$wx_info=Qscmf\Lib\WeixinLogin::getInstance()->getInfoForMobile();
```
* 运行/扫码后可用``` session('wx_info') ```获取微信登录信息
* 若'wx_info'的session值已设置可通过设置config.php中的'WX_INFO_SESSION_KEY'来改变
### 场景模拟
一、 PC端实现扫码登录/注册
* 扫码页面(扫码后需要跳转到'/home/index/wxLogin'
```html
<!-- 其它代码 -->
<!-- 此处是放入二维码的位置 -->
<iframe id="scan" src="{:U('qscmf/weixinLogin/scan',['goto_url'=>urlencode('/home/index/wxLogin')])}"></iframe>
<!-- 其它代码 -->
```
* 登录/注册业务处理(对应上一步的"/home/index/wxLogin"
```php
$wx_info=json_decode(session('wx_info'),true);
// 若用户表为member表
$member=D('Member')->where(['openid'=>$wx_info['id']])->find();
if ($member){
//登录
session('mid',$member['id']);
}else{
//注册
$ent=[
'openid'=>$wx_info['id'],
'nickname'=>$wx_info['nickname']
];
$r=D('Member')->createAdd($ent);
if ($r===false){
E(D('Member')->getError());
}
session('mid',$r);
}
redirect(U('home/user/index'));
```
二、 微信端实现授权登录/注册
1. 授权页面 (授权后需要跳转到'/home/index/wxLogin'
```php
$wx_info=Qscmf\Lib\WeixinLogin::getInstance()->getInfoForMobile();
if ($wx_info){
redirect(U('/home/index/wxLogin'));
}
```
2. 登录/注册业务处理(对应上一步的"/home/index/wxLogin"
```php
// 与PC端扫码后登录/注册业务处理一致
```
## 全局函数
[传送门](https://github.com/quansitech/qs_cmf/blob/master/docs/Helper.md)
## js组件
### selectAddr
```blade
select框的地址选择器
参数
addressLevel: array 省/市/县的select框默认值默认为['选择省','选择市','选择区']
level: int 1|2|3 地址的等级:省/市/区默认为3
url: array 分别获取地址的接口url默认为['/api/area/getProvince.html','/api/area/getCityByProvince.html','/api/area/getDistrictByCity.html']
onSelected: function (val,changeEle){} 每个select框选择地址后执行自定义functionval 隐藏域的值 changeEle 触发事件的select
```
代码示例
```php
<input type="hidden" id="hidden_position" name="city_id" value="{$city_id}">
<block name="script">
<script type="text/javascript" src="__PUBLIC__/libs/addrSelect/selectAddr.js"></script>
<script>
jQuery(document).ready(function() {
$('#hidden_position').selectAddr({
addressLevel: ['省','市','区'],
level: 3,
onSelected: function (val,changeEle){
log(val);
}
});
function log(str) {
console.log(str+"-111");
}
});
</script>
</block>
```
## 常量
DOMAIN 域名可通过env去改写默认采用$_SERVER["HTTP_HOST"]
ROOT 指定子目录,默认为空, 可通过env改写如子路径 ROOT=/move
SITE_URL 包含子目录的网站根地址
HTTP_PROTOCOL 返回http或者https协议字符串, 可通过env指定
REQUEST_URI 获取方向代理前的REQUEST_URI值
## 扩展
[传送门](https://github.com/quansitech/qs_cmf/blob/master/docs/Extends.md)
## 消息队列
[传送门](https://github.com/quansitech/qs_cmf/blob/master/docs/Resque.md)
## 测试
在看以下文档时建议结合qscmf自带的测试用例代码阅读。
#### http测试
http测试实则是模拟接口请求测试接口逻辑是否与预期一致。
qscmf使用phpunit作为测试框架在lara\tests下创建测试类http测试类需要继承Lara\Tests\TestCase类。
```php
<?php
namespace Lara\Tests\Feature;
use Lara\Tests\TestCase;
class AuthTest extends TestCase {
}
```
构造get请求
```php
/**
* @uri 请求url
* @header 自定义请求头 数组类型 例如: ['x-header' => 'value']
* @return 返回请求结果
**/
$this->get($uri, $header);
样例代码 lara/tests/Feature/AuthTest.php
```
构造post请求
```php
/**
* @uri 请求url
* @data 需发送的数据 数组类型 例如: [ 'uid' => 'admin', 'pwd' => '123456']
* 可存放上传文件 例如: [ 'file' => $file ] $file类型必须为SymfonyUploadedFile类型
* @header 自定义请求头 数组类型 例如: ['x-header' => 'value']
* @return 返回请求结果
**/
$this->post($uri, $data, $header);
样例代码 lara/tests/Feature/AuthTest.php
```
模拟超级管理员登录
```php
$this->loginSuperAdmin();
```
模拟普通后台用户登录
```php
/**
* $uid 用户id
**/
$this->loginUser($uid);
```
测试上传文件
```php
//构造的SymfonyUploadedFile类文件对象
$data = [
'file' => UploadedFile::fake()->image('test.jpg', 100, 100)
];
$content = $this->post('api/upload/uploadImage', $data);
```
测试数据库是否存在记录
```php
/**
* $tablename 表名
* $where 查询条件 例如: [ 'name' => 'admin', 'status' => '1' ]
**/
$this->assertDatabaseHas($tablename, $where);
样例代码 lara/tests/Feature/UploadTest.php
```
测试数据库是否不存在记录
```php
/**
* $tablename 表名
* $where 查询条件 例如: [ 'name' => 'admin', 'status' => '1' ]
**/
$this->assertDatabaseMissing($tablename, $where);
样例代码 lara/tests/Feature/UserTest.php
```
#### 创建Mock类
如果代码需要请求第三方接口或者触发一些我们不想在测试里执行的的代码可以采用Mock类模仿该部分的逻辑达到只测试接口的目的。
mock类的创建使用phpunit提供的方法
```php
//Foo为需模仿的类,phpunit会自动给我们生成模拟类方法没有指定返回值默认返回null
$stub = $this->createMock(Foo::class);
//也可以指定方法的返回值
$stub->method('say')->willReturn(1);
//给Foo类指定Mock实例
app()->instance(Foo::class, $stub);
·
·
·
//业务代码的设计需可测试如Mock模仿的代码必须封装成类定义接口解耦逻辑
//用laravel的依赖容器自动构造Foo实例这样可达到测试实例用Mock实例替换实际业务类的目的
$foo = app()->make(Foo::class);
//该接口方法在测试执行时,会返回我们指定返回的值
$foo->say();
样例代码: lara/tests/Feature/MockTest.php
```
#### Dusk测试
Dusk 是laravel的浏览器自动化测试 工具 qscmf将其稍微封装了一下只需继承Lara\Tests\DuskTestCase类即可使用具体的使用方法可查看[laravel文档](https://learnku.com/docs/laravel/5.8/dusk/3943)。
样例代码: lara/tests/LoginTest.php
#### 命令行测试
在Testing\TestCase下增加了 cli的命令行模拟执行
```php
$content = $this->cli('app/cliMode', 'Home', 'Controller', 'action', '参数1', '参数2'...);
//content为返回的输出结果
```
#### 在phpunit里调用tp的代码片段
使用runTp方法参数接收一个匿名函数匿名函数可调用tp里的代码return后可在phpunit接收
```php
$test_ent = $this->runTp(function (){
return D('Test')->find(1);
});
$this->assertTrue($test_ent['name'] == '测试');
```
可用该方法测试Tp的代码但如果只是要验证数据库值建议还是使用 assertDatabaseHas等测试方法性能更佳。
#### 压缩前端js代码
压缩办法很多,这里提供一种配置简单的方式,[传送门](https://gist.github.com/gaearon/42a2ffa41b8319948f9be4076286e1f3)
### HEIC格式图片转JPG格式
```
为解决部分组件暂不支持展示heic格式图片将其转换为jpg
上传到阿里云oss的图片已处理
```
+ 使用
+ 复制数据迁移文件*2022_07_18_014941_alter_file_pic_add_mime_type.php*qs_file_pic添加字段 mime_type
+ 扩展包需自行注册并实现heic_to_jpg行为
+ 定义行为
```php
class HeicToJpgBehavior{
public function run(&$params)
{
// $params为qs_file_pic的一条数据
// 具体逻辑
$params['url'] = 'your new url';
}
}
```
+ 注册行为
```php
\Think\Hook::add('heic_to_jpg', 'xxx\\HeicToJpgBehavior');
```
## 文档
由于工作量大,文档会逐步补全。
## lincense
[MIT License](https://github.com/tiderjian/lara-for-tp/blob/master/LICENSE.MIT) AND [996ICU License](https://github.com/tiderjian/lara-for-tp/blob/master/LICENSE.996ICU)

161
Upgrade.md Executable file
View File

@ -0,0 +1,161 @@
```php
1. (升级至composer版本)修改原来buider类的命名空间, 修改Common/Conf/config.php里的相关配置
检查根目录与www目录下的文件差异升级至最新文件
从最新代码移植lara文件夹到根目录
升级Common/Common/function.php
2. (升级至v2.0.0版本)修改AppInitBehavior 队列相关类的命名空间修改Common/Conf/config.php 跟队列有关的设置从env读取
修改Common/Model/QueueModel类的队列命名空间升级后注意计划任务相关的键值前缀旧版队列的前缀会和新版队列的前缀会不一样新版计划任务前缀会根据设置的值而定旧版则不受设定前缀影响
修改app/resque文件
检查queue数据表是否缺少schedule字段添加schedule表
3. (升级至v2.0.0版本)如该项目之前有使用ElasticsearchController, 修改Home/Controller/ElasticsearchController的Elasticsearch类的命名空间修改Model里跟Elasticsearch相关的命名空间
修改app/makeIndex.php文件
4. (升级至v2.0.1版本) 修改Admin/Controller/QueueController、Behaviors/AppInitBehavior、Common/Model/QueueModel、用到Job状态的DBCont的命名空间
删除Gy_Library/DBcont与Job状态有关的代码
5. (升级至v2.0.5版本)修改CateHelperTrait和ContentHelperTrait的命名空间,移除Gy_library里的文件
修改CusUpload的命名空间,移除Gy_library里的文件
修改GyController和GyListController分别继承QsController和QsListController删除同名方法
修改GyModel和GyListModel分别继承QsModel和QsListModel删除同名方法
删掉Common\function.php里的genSelectByTree、isAdminLogin、list_to_tree函数
删除Common\Lib 的Flash和FlashError
修改GyRbac的命名空间,更名为QsRbac
GyPage更名为QsPage,原GyPage继承QsPage,删除Common/Conf/config 里的 VAR_PAGE
6.(升级到v3.0.0以上版本)检查有无使用队列的计划任务功能,如使用了,可用升级脚本进行升级
项目根目录/www# php index.php Qscmf/UpgradeFix/v300FixSchedule/queue/[计划队列名] maintenance
如用到七牛云的音视频上传功能注意qs_file_pic的字段有无缺失对比qs_cmf的迁移文件里的qs_file_pic表的定义
修改app/resque文件 修改绑定模块将Home改为绑定到Qscmf
7.(升级到v4.0.0以上版本)检查app/Behaviors/AppInitBehavior.class.php有无DOMAIN、SITE_URL、HTTP_PROTOCOL的常量定义如有将代码删除即可
8.(升级到v5.0.0以上版本)检查有无引用Org\Util\String类如有将命名空间改为Org\Util\StringHelper并将类名String修改为StringHelper。
9.(升级到v6.0.0以上版本)检查有无在www/Public/views/Admin/common/common.js和www/Public/views/common.css中自定义客制化代码如有
将代码迁移处理。上述两文件将移植核心库。并在app/Admin/View/default/common/dashboard_layout.html中将以上两文件的引用分别指向
__PUBLIC__/libs/admin/common.js和__PUBLIC__/libs/admin/common.css。
10.(升级到v7.0.0以上版本)7.0版本移除了位于Qscmf/Lib下的QsExcel代码检查有无使用该类如果使用了请安装使用https://github.com/quansitech/qs-excel。
11.(升级到v8.0.0以上版本)8.0提供了许多扩展机制部分原来继承在框架里的功能都移到了独立的composer扩展。
因此升级到该版本,必须注意业务系统有无使用了已经移除的组件功能,如果有,则需要查看组件的安装方法,安装后才会不影响原有的功能
移除的组件有以下内容
1formbuilder formitem的vedio_vod类型 (https://github.com/quansitech/qscmf-formitem-vod)
(2) formbuilder formitem的qiniu_video和qiniu_audio类型 (https://github.com/quansitech/qscmf-formitem-qiniu)
(3) listbuilder topbutton的 download类型 (https://github.com/quansitech/qscmf-topbutton-download)
(4) listbuilder topbutton的 export类型 (https://github.com/quansitech/qscmf-topbutton-export)
(5) formbuilder formitem的 audio_oss、audios_oss、file_oss、files_oss、picture_oss、pictures_oss、picture_oss_intercept、pictures_oss_intercept (https://github.com/quansitech/qscmf-formitem-aliyun-oss)
在项目的composer.json文件的scripts设置项修改为
"scripts": {
"post-root-package-install": [
"@php -r \"file_exists('.env') || copy('.env.example', '.env');\""
],
"post-autoload-dump": [
"./vendor/bin/qsinstall",
"./vendor/bin/qsautoload",
"@php artisan package:discover --ansi",
"@php artisan qscmf:discover --ansi",
"@php ./www/index.php /qscmf/createSymlink"
]
}
删除app/Behaviors文件架下的InitHookBehavior.class.php、LoadDBConfigBehavior.class.php
删除app/Common/Conf/tags.php 中 InitHook 和 LoadDBConfig的设置
检查根目录下的tp.php文件有无LARA_DIR 和 ROOT_PATH的常量定义没有则添加
defined('LARA_DIR') || define('LARA_DIR', __DIR__ . '/lara');
defined('ROOT_PATH') || define('ROOT_PATH', __DIR__);
检查composer.json文件并添加以下内容
"require-dev": {
"phpunit/phpunit": "^8.0",
"laravel/dusk": "^5.0",
"mockery/mockery": "^1.2",
"fzaninotto/faker": "^1.4"
},
"autoload-dev": {
"psr-4": {
"Lara\\Tests\\":"lara\/tests"
}
},
如果是采用swoole-webhook的部署方式拉取下最新的镜像
12.(升级到v9.0.0以上版本)
----------------------------------
defined('LARA_DIR') || define('LARA_DIR', __DIR__ . '/lara');
\Bootstrap\Context::providerRegister(true);
\Larafortp\ArtisanHack::init($app);
----------------------------------
1. 将上面的代码复制到根目录下的artisan | $kernel = $app->make(Illuminate\Contracts\Console\Kernel::class); | 前
2. 检查 app/Admin/View/default/common/head.html 中的 <div class="navbar-left"> 元素前面有没包裹 <div class="navbar-container"> ,没有则加上
在app/Admin/View/default/common/dashboard_layout.html 加入
<link href="__PUBLIC__/libs/perfect-scrollbar/perfect-scrollbar.css" rel="stylesheet" type="text/css" />
<script src="__PUBLIC__/libs/perfect-scrollbar/perfect-scrollbar.min.js" type="text/javascript"></script>
3. 删除tp.php 里内容,替换成以下的
--------------------------------
<?php
// 应用入口文件
ini_set('display_errors', '0');
if(!function_exists('show_bug')){
function show_bug($object){
echo "<pre style='color:red'>";
var_dump($object);
echo "</pre>";
}
}
//require __DIR__ . '/vendor/tiderjian/think-core/src/Common/functions.php';
//require __DIR__ . '/app/Common/Common/function.php';
require_once __DIR__ . '/vendor/autoload.php';
$dotenv = \Dotenv\Dotenv::create(__DIR__ );
$dotenv->load();
// 引入ThinkPHP入口文件
require 'vendor/tiderjian/think-core/src/ThinkPHP.php';
-----------------------------------
4. 检查composer.json的scripts, 将"post-root-package-install" 里的执行脚本移到"post-autoload-dump"第一行,如下
-----------------------------------
"scripts": {
"post-autoload-dump": [
"@php -r \"file_exists('.env') || copy('.env.example', '.env');\"",
"./vendor/bin/qsinstall",
"./vendor/bin/qsautoload",
"@php artisan package:discover --ansi",
"@php artisan qscmf:discover --ansi",
"php ./www/index.php /qscmf/CreateSymlink"
]
}
-----------------------------------
13.(升级到v10.0.0以上版本)(该版本仅做升级过渡,勿使用,命令行运行模式存在重大缺陷)
全局搜索有无使用ListBuilder->alterTableData 方法,如果有,则将里面的变量占位符{$字段名} 改为 __字段名__
lara/server.php 文件,找到$uri的定义在其后面加上以下代码
----------------------------------
$_SERVER['DUSK_TEST'] = true;
----------------------------------
14.(升级到v11以上版本)
在v10版本先完成以下操作
数据库执行sql
--------------------------------
alter table migrations add column `after` tinyint(1) not null default 0 after migration
alter table migrations add column `run` tinyint(1) not null default 0 after migration
alter table migrations add column `before` tinyint(1) not null default 0 after migration
update migrations set `after`=1,`run`=1,`before`=1
--------------------------------
```
v11->v12升级步骤[点击查看](https://github.com/quansitech/qs_cmf/blob/master/docs/UpgradeTo12.md)
##### v13修改计划
- [ ] CompareBuilder FormBuilder ListBuilder 删除display方法
- [ ] 重构ButtonType save的保存提交算法 原因是SubTableBuilder也可能会采用该方法来设置 column 的class当同时作为listBuilder的modal使用时就会被错误的一并save提交先采用全局变量来开发重置能力但全局变量容易存在冲突并不是一种好的解决方案仅作过渡使用合理的做法应该让ListBuilder或者SubTableBuilder来决定Column 的TargetForm避免互相影响。
- [ ] showFileUrl不再处理除本地文件存储外的功能例如oss的处理

222
app/Addons/Addon.class.php Executable file
View File

@ -0,0 +1,222 @@
<?php
namespace Addons;
abstract class Addon{
protected $view = null;
public $info = array();
public $addon_path = '';
public $config_file = '';
public $custom_config = '';
public $admin_list = array();
public $custom_adminlist = '';
public $access_url = array();
protected $_error;
public function __construct(){
$this->view = \Think\Think::instance('Think\View');
$this->addon_path = ADDON_PATH.$this->getName().'/';
$TMPL_PARSE_STRING = C('TMPL_PARSE_STRING');
$TMPL_PARSE_STRING['__ADDONS__'] = APP_PATH . '/Addons/'.$this->getName();
C('TMPL_PARSE_STRING', $TMPL_PARSE_STRING);
if(is_file($this->addon_path.'config.php')){
$this->config_file = $this->addon_path.'config.php';
}
}
final public function getError(){
return $this->_error;
}
final public function setAdminFunctionList($function_name){
array_push($this->_admin_function_list, $function_name);
}
final public function getAdminFunctionList(){
return $this->_admin_function_list;
}
/**
* 模板主题设置
* @access protected
* @param string $theme 模版主题
* @return Action
*/
final protected function theme($theme){
$this->view->theme($theme);
return $this;
}
//显示方法
final protected function display($template=''){
if($template == '')
$template = CONTROLLER_NAME;
echo ($this->fetch($template));
}
/**
* 模板变量赋值
* @access protected
* @param mixed $name 要显示的模板变量
* @param mixed $value 变量的值
* @return Action
*/
final protected function assign($name,$value='') {
$this->view->assign($name,$value);
return $this;
}
//用于显示模板的方法
final protected function fetch($templateFile = CONTROLLER_NAME){
if(!is_file($templateFile)){
$templateFile = $this->addon_path.$templateFile.C('TMPL_TEMPLATE_SUFFIX');
if(!is_file($templateFile)){
throw new \Exception("模板不存在:$templateFile");
}
}
return $this->view->fetch($templateFile);
}
final public function getName(){
$class = get_class($this);
return substr($class,strrpos($class, '\\')+1, -5);
}
final public function checkInfo(){
$info_check_keys = array('name','title','description','status','author','version');
foreach ($info_check_keys as $value) {
if(!array_key_exists($value, $this->info))
return FALSE;
}
return TRUE;
}
final public function createHook($hook_name, $desc){
$hook_ent = D('Hooks')->where(array('name' => $hook_name))->find();
if(!$hook_ent){
$data['name'] = $hook_name;
$data['desc'] = $desc;
$data['update_date'] = time();
$data['status'] = 1;
D('Hooks')->add($data);
}
}
final public function delHook($hook_name){
D('Hooks')->where(array('name' => $hook_name))->delete();
}
/**
* 获取插件的配置数组
*/
final public function getConfig($name=''){
static $_config = array();
if(empty($name)){
$name = $this->getName();
}
if(isset($_config[$name])){
return $_config[$name];
}
$config = array();
$map['name'] = $name;
$map['status'] = 1;
$config = M('Addons')->where($map)->getField('config');
if($config){
$config = json_decode($config, true);
}else{
$temp_arr = include $this->config_file;
foreach ($temp_arr as $key => $value) {
if($value['type'] == 'group'){
foreach ($value['options'] as $gkey => $gvalue) {
foreach ($gvalue['options'] as $ikey => $ivalue) {
$config[$ikey] = $ivalue['value'];
}
}
}else{
$config[$key] = $temp_arr[$key]['value'];
}
}
}
$_config[$name] = $config;
return $config;
}
/**
* 解析数据库语句函数
* @param string $sql sql语句 带默认前缀的
* @param string $tablepre 自己的前缀
* @return multitype:string 返回最终需要的sql语句
*/
public function sql_split($sql, $tablepre){
if ($tablepre != "onethink_")
$sql = str_replace("onethink_", $tablepre, $sql);
$sql = preg_replace("/TYPE=(InnoDB|MyISAM|MEMORY)( DEFAULT CHARSET=[^; ]+)?/", "ENGINE=\\1 DEFAULT CHARSET=utf8", $sql);
if ($r_tablepre != $s_tablepre)
$sql = str_replace($s_tablepre, $r_tablepre, $sql);
$sql = str_replace("\r", "\n", $sql);
$ret = array();
$num = 0;
$queriesarray = explode(";\n", trim($sql));
unset($sql);
foreach ($queriesarray as $query) {
$ret[$num] = '';
$queries = explode("\n", trim($query));
$queries = array_filter($queries);
foreach ($queries as $query) {
$str1 = substr($query, 0, 1);
if ($str1 != '#' && $str1 != '-')
$ret[$num] .= $query;
}
$num++;
}
return $ret;
}
/**
* 获取插件所需的钩子是否存在,没有则新增
* @param string $str 钩子名称
* @param string $addons 插件名称
* @param string $addons 插件简介
*/
public function getisHook($str, $addons, $msg=''){
$hook_mod = M('Hooks');
$where['name'] = $str;
$gethook = $hook_mod->where($where)->find();
if(!$gethook || empty($gethook) || !is_array($gethook)){
$data['name'] = $str;
$data['description'] = $msg;
$data['type'] = 1;
$data['update_time'] = NOW_TIME;
$data['addons'] = $addons;
if( false !== $hook_mod->create($data) ){
$hook_mod->add();
}
}
}
/**
* 删除钩子
* @param string $hook 钩子名称
*/
public function deleteHook($hook){
$model = M('hooks');
$condition = array( 'name' => $hook, );
$model->where($condition)->delete();
}
//必须实现安装
abstract public function install();
//必须卸载插件方法
abstract public function uninstall();
//abstract public function displayConfig();
}

View File

@ -0,0 +1,61 @@
<?php
namespace Addons\AutoCrop;
use Addons\Addon;
class AutoCropAddon extends Addon{
public $info = array(
'name' => 'AutoCrop',
'title' => '图片自动裁剪',
'description' => '自动裁剪上传至网站的图片',
'status' => 1,
'author' => 'tider',
'version' => '0.1'
);
public $custom_config = 'setting';
public function install(){
$this->createHook('afterUpload', '文件上传后');
return true;
}
public function uninstall(){
$this->delHook('afterUpload');
return true;
}
// public function displayConfig(){
// $this->assign('meta_title', '设置插件-' . $this->info['title']);
// $this->display($this->custom_config);
// }
//IMAGE_THUMB_SCALE = 1 ; //等比例缩放类型
//IMAGE_THUMB_FILLED = 2 ; //缩放后填充类型
//IMAGE_THUMB_CENTER = 3 ; //居中裁剪类型
//IMAGE_THUMB_NORTHWEST = 4 ; //左上角裁剪类型
//IMAGE_THUMB_SOUTHEAST = 5 ; //右下角裁剪类型
//IMAGE_THUMB_FIXED = 6 ; //固定尺寸缩放类型
public function afterUpload(&$para){
$save_path = $para[0];
$file_name = $para[1];
$config = $this->getConfig();
$config['config'] = json_decode(html_entity_decode($config['config']), true);
$image = new \Think\Image();
$img_file = $save_path . $file_name;
if(!isImage($img_file)){
return false;
}
foreach ($config['config'] as $k => $v){
$thumb_dir = $save_path . $k . '_' . $file_name;
$result[] = $image->open($img_file)->thumb($v[0], $v[1], $v[2])->save($thumb_dir);
}
return $result;
}
}

28
app/Addons/AutoCrop/config.php Executable file
View File

@ -0,0 +1,28 @@
<?php
// +----------------------------------------------------------------------
// | OneThink [ WE CAN DO IT JUST THINK IT ]
// +----------------------------------------------------------------------
// | Copyright (c) 2013 http://www.onethink.cn All rights reserved.
// +----------------------------------------------------------------------
// | Author: yangweijie <yangweijiester@gmail.com> <code-tech.diandian.com>
// +----------------------------------------------------------------------
return array(
'config' => array(
'title' => '设置值:',
'type' => 'textarea',
'value' => ''
),
'desc' => array(
'title' => '备注:',
'type' => 'textarea',
'value' => '缩略图生成规则
IMAGE_THUMB_SCALE = 1 ; //等比例缩放类型
IMAGE_THUMB_FILLED = 2 ; //缩放后填充类型
IMAGE_THUMB_CENTER = 3 ; //居中裁剪类型
IMAGE_THUMB_NORTHWEST = 4 ; //左上角裁剪类型
IMAGE_THUMB_SOUTHEAST = 5 ; //右下角裁剪类型
IMAGE_THUMB_FIXED = 6 ; //固定尺寸缩放类型',
)
);

View File

@ -0,0 +1,244 @@
<?php
namespace Addons\C123;
use Addons\Addon;
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
/**
* Description of C123Addon
*
* @author 英乐
*/
class C123Addon extends Addon{
//put your code here
public $open_api_url = 'http://smsapi.c123.cn/OpenPlatform/OpenApi';
public $data_api_url = 'http://smsapi.c123.cn/DataPlatform/DataApi';
public $info = array(
'name' => 'C123',
'title' => '中国短信网短信接口',
'description' => '中国短信网短信发送接口集',
'status' => 1,
'author' => 'tider',
'version' => '0.1'
);
private $_error_code = array(
0 => "帐户格式不正确(正确的格式为:员工编号@企业编号)",
-1 => "服务器拒绝(速度过快、限时或绑定IP不对等)如遇速度过快可延时再发",
-2 => "密钥不正确",
-3 => "密钥已锁定",
-4 => "参数不正确(内容和号码不能为空,手机号码数过多,发送时间错误等)",
-5 => "无此帐户",
-6 => "帐户已锁定或已过期",
-7 => "帐户未开启接口发送",
-8 => "不可使用该通道组",
-9 => "帐户余额不足",
-10 => "内部错误",
-11 => "扣费失败"
);
private $_return_code = array(
'DELIVRD' => '短消息转发成功',
'EXPIRED' => '短消息超过有效期',
'DELETED' => '短消息已经被删除',
'UNDELIV' => '短消息是不可达的',
'ACCEPTD' => '短消息在等待发送中',
'UNKNOWN' => '未知短消息状态',
'REJECTD' => '短消息被短信中心拒绝',
'DTBLACK' => '目的号码是黑名单号码',
'DTWORDS' => '发送内容被过滤',
'DTFAILD' => '发送失败原因未明',
'ERRBUSY' => '运营商系统忙状态未知'
);
public function install(){
$this->createHook('sendSmsOnce', '发送单条短信');
$this->createHook('sendSmsBatch', '发送批量短信');
$this->createHook('getSmsBalance', '获取短信账号余额');
$this->createHook('getSmsStatus', '获取短信状态');
$this->createHook('getSmsRely', '获取短信回复');
return true;
}
public function uninstall(){
$this->delHook('sendSmsOnce');
$this->delHook('sendSmsBatch');
$this->delHook('getSmsBalance');
$this->delHook('getSmsStatus');
$this->delHook('getSmsRely');
return true;
}
public function getSmsBalance(&$para){
$config = $this->getConfig();
$data = array(
'action'=>'getBalance', //发送类型 可以有sendOnce短信发送sendBatch一对一发送sendParam 动态参数短信接口
'ac'=> C('C123_ac'), //用户账号
'authkey'=> C('C123_authkey'), //认证密钥
);
$xml= Util\C123::postSMS($this->open_api_url,$data); //POST方式提交
$re=simplexml_load_string(utf8_encode($xml));
if(trim($re['result'])==1){
foreach ($re->Item as $item){
$stat['remain']=trim((string)$item['remain']);
$stat_arr[]=$stat;
}
$return['status'] = 1;
$return['data'] = $stat_arr;
}
else{
$return['status'] = 0;
$return['err_msg'] = $this->_error_code[trim($re['result'])];
}
$para['return'] = $return;
}
public function sendSmsBatch(&$para){
$config = $this->getConfig();
$content = $para['content'];
$mobile = $para['mobile'];
$data = array(
'action'=>'sendBatch', //发送类型 可以有sendOnce短信发送sendBatch一对一发送sendParam 动态参数短信接口
'ac'=>C('C123_ac'), //用户账号
'authkey'=>C('C123_authkey'), //认证密钥
'cgid'=>C('C123_cgid'), //通道组编号
'm'=>$mobile, //号码,多个号码用逗号隔开
'c'=>$content, //如果页面是gbk编码则转成utf-8编码如果是页面是utf-8编码则不需要转码
'csid'=>C('C123_csid'), //签名编号 ,可以为空,为空时使用系统默认的签名编号
't'=> '' //定时发送,为空时表示立即发送
);
$xml= Util\C123::postSMS($this->open_api_url,$data); //POST方式提交
$re=simplexml_load_string(utf8_encode($xml));
if(trim($re['result'])==1){
foreach ($re->Item as $item){
$stat['msgid'] =trim((string)$item['msgid']);
$stat['total']=trim((string)$item['total']);
$stat['price']=trim((string)$item['price']);
$stat['remain']=trim((string)$item['remain']);
$stat_arr[]=$stat;
}
$return['status'] = 1;
$return['data'] = $stat_arr;
}
else{
$return['status'] = 0;
$return['err_msg'] = $this->_error_code[trim($re['result'])];
}
$para['return'] = $return;
}
public function sendSmsOnce(&$para){
$config = $this->getConfig();
$content = $para['content'];
$mobile = $para['mobile'];
$data = array(
'action'=>'sendOnce', //发送类型 可以有sendOnce短信发送sendBatch一对一发送sendParam 动态参数短信接口
'ac'=>$config['ac'], //用户账号
'authkey'=>$config['authkey'], //认证密钥
'cgid'=>$config['cgid'], //通道组编号
'm'=>$mobile, //号码,多个号码用逗号隔开
'c'=>$content, //如果页面是gbk编码则转成utf-8编码如果是页面是utf-8编码则不需要转码
'csid'=>$config['csid'], //签名编号 ,可以为空,为空时使用系统默认的签名编号
't'=> '' //定时发送,为空时表示立即发送
);
$xml= Util\C123::postSMS($this->open_api_url,$data); //POST方式提交
$re=simplexml_load_string(utf8_encode($xml));
if(trim($re['result'])==1){
foreach ($re->Item as $item){
$stat['msgid'] =trim((string)$item['msgid']);
$stat['total']=trim((string)$item['total']);
$stat['price']=trim((string)$item['price']);
$stat['remain']=trim((string)$item['remain']);
$stat_arr[]=$stat;
}
$return['status'] = 1;
$return['data'] = $stat_arr;
}
else{
$return['status'] = 0;
$return['err_msg'] = $this->_error_code[trim($re['result'])];
}
$para['return'] = $return;
}
public function getSmsStatus(&$para){
$config = $this->getConfig();
$data = array(
'action'=>'getSendState', //发送类型 可以有sendOnce短信发送sendBatch一对一发送sendParam 动态参数短信接口
'ac'=>C('C123_ac'), //用户账号
'authkey'=>C('C123_authkey'), //认证密钥
);
$xml= Util\C123::postSMS($this->data_api_url,$data); //POST方式提交
$re=simplexml_load_string(utf8_encode($xml));
if(trim($re['result'])==1){
foreach ($re->Item as $item){
$stat['result'] = trim((string)$item['result']);
$stat['msgid'] = trim((string)$item['msgid']);
$stat['msg'] = $this->_return_code[trim((string)$item['return'])];
$stat_arr[]=$stat;
}
$return['status'] = 1;
$return['data'] = $stat_arr;
}
else{
$return['status'] = 0;
$return['err_msg'] = $this->_error_code[$re['result']];
}
$para['return'] = $return;
}
public function getSmsRely(&$para){
$config = $this->getConfig();
$data = array(
'action'=>'getReply', //发送类型 可以有sendOnce短信发送sendBatch一对一发送sendParam 动态参数短信接口
'ac'=>C('C123_ac'), //用户账号
'authkey'=>C('C123_authkey'), //认证密钥
);
$xml= Util\C123::postSMS($this->data_api_url,$data); //POST方式提交
$re=simplexml_load_string($xml);
if(trim($re['result'])==1){
foreach ($re->Item as $item){
$stat['msgid'] = trim((string)$item['msgid']);
$stat['content'] = trim((string)$item['content']);
$stat_arr[]=$stat;
}
$return['status'] = 1;
$return['data'] = $stat_arr;
}
else{
$return['status'] = 0;
$return['err_msg'] = $this->_error_code[$re['result']];
}
$para['return'] = $return;
}
}

View File

@ -0,0 +1,50 @@
<?php
namespace Addons\C123\Util;
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
/**
* Description of C123
*
* @author 英乐
*/
class C123 {
//put your code here
public static function postSMS($url,$data=''){
$row = parse_url($url);
$host = $row['host'];
$port = $row['port'] ? $row['port']:80;
$file = $row['path'];
foreach ($data as $k=>$v)
{
$post .= rawurlencode($k)."=".rawurlencode($v)."&"; //转URL标准码
}
$post = substr( $post , 0 , -1 );
$len = strlen($post);
$fp = @fsockopen( $host ,$port, $errno, $errstr, 10);
if (!$fp) {
return "$errstr ($errno)\n";
} else {
$receive = '';
$out = "POST $file HTTP/1.0\r\n";
$out .= "Host: $host\r\n";
$out .= "Content-type: application/x-www-form-urlencoded\r\n";
$out .= "Connection: Close\r\n";
$out .= "Content-Length: $len\r\n\r\n";
$out .= $post;
fwrite($fp, $out);
while (!feof($fp)) {
$receive .= fgets($fp, 128);
}
fclose($fp);
$receive = explode("\r\n\r\n",$receive);
unset($receive[0]);
return implode("",$receive);
}
}
}

31
app/Addons/C123/config.php Executable file
View File

@ -0,0 +1,31 @@
<?php
// +----------------------------------------------------------------------
// | OneThink [ WE CAN DO IT JUST THINK IT ]
// +----------------------------------------------------------------------
// | Copyright (c) 2013 http://www.onethink.cn All rights reserved.
// +----------------------------------------------------------------------
// | Author: yangweijie <yangweijiester@gmail.com> <code-tech.diandian.com>
// +----------------------------------------------------------------------
return array(
'ac' => array(
'title' => '用户账号:',
'type' => 'text',
'value' => ''
),
'authkey' => array(
'title' => '认证密钥:',
'type' => 'text',
'value' => '',
),
'cgid' => array(
'title' => '通道组:',
'type' => 'text',
'value' => '',
),
'csid' => array(
'title' => '签名编号:',
'type' => 'text',
'value' => '',
),
);

View File

@ -0,0 +1,93 @@
<?php
namespace Addons\SiteSearch;
use Addons\Addon;
class SiteSearchAddon extends Addon{
public $info = array(
'name' => 'SiteSearch',
'title' => '全站搜索',
'description' => '全站搜索功能',
'status' => 1,
'author' => 'tider',
'version' => '0.1'
);
public function install(){
$this->createHook('siteSearch', '全站搜索');
return true;
}
public function uninstall(){
$this->delHook('siteSearch');
return true;
}
public function siteSearch($query){
$config = $this->getConfig();
$model_attr = parse_config_attr($config['model']);
$model_name_attr = parse_config_attr($config['model_name']);
$url_attr = parse_config_attr($config['url']);
$search_fields_attr = parse_config_attr($config['search_fields']);
$field_map_attr = parse_config_attr($config['field_map']);
$parm = array();
for($i=0;$i<count($model_attr);$i++){
$tmp['model'] = $model_attr[$i];
$tmp['model_name'] = $model_name_attr[$i];
$tmp['url'] = $url_attr[$i];
$tmp['search_fields'] = $search_fields_attr[$i];
$tmp['field_map'] = $field_map_attr[$i];
$parm[] = $tmp;
}
$data_list = array();
foreach($parm as $p){
$map = array();
$map[$p['search_fields']] = array('like', '%' . $query . '%');
$ents = D($p['model'])->where($map)->select();
foreach($ents as $ent){
$ent['url'] = $this->_parseUrl($p['url'], $ent);
$field_map_arr = explode('|', $p['field_map']);
$ent['model_name'] = $p['model_name'];
foreach($field_map_arr as $m){
list($key, $value) = explode('=', $m);
if(strlen($ent[$value])>0){
$ent[$key] = $ent[$value];
}
}
$data_list[] = $ent;
}
}
usort($data_list, function($a, $b){
if($a['date'] == $b['date'])
return 0;
else
return $a['date'] > $b['date'] ? -1 : 1;
});
$count = count($data_list);
$per_page = C('HOME_PER_PAGE_NUM', null, false);
//构建分页链接
if($per_page === false){
$page = new \Gy_Library\GyPage($count);
}
else{
$page = new \Gy_Library\GyPage($count, $per_page);
}
$data_list = array_slice($data_list, ($page->nowPage - 1) * $page->listRows, $page->listRows);
$this->assign('query', $query);
$this->assign('pagination', $page->show());
$this->assign('data_list', $data_list);
$this->display(T('Addons://SiteSearch@default/search_result'));
}
private function _parseUrl($url, $ent){
while(preg_match('/__(.+?)__/', $url, $matches)){
$url = str_replace($matches[0], $ent[$matches[1]], $url);
}
return $url;
}
}

View File

@ -0,0 +1,22 @@
<div class="content-header">
<h1 class="content-title">“{$query}”的搜索结果</h1>
</div>
<div class="content-body search-result">
<div class="pure-g">
<div class="pure-u-3-4">
<ul>
<volist name="data_list" id="data">
<li>
<a href="{$data.url}" target="_blank"><h2>{$data.title}</h2></a>
<div class="cate_name"><span>{$data.model_name}</span></div>
<present name='data.date'>
<span>{:date('Y-m-d H:i:s', $data['date'])}</span>
</present>
<p>{:cutLength(strip_tags(showHtmlContent($data['summary'])),150)}</p>
</li>
</volist>
</ul>
<include file="../app/Admin/View/default/common/pagination.html" />
</div>
</div>
</div>

View File

@ -0,0 +1,51 @@
<?php
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
return array(
'description'=>array(
'title'=>'插件说明:',
'type'=>'textarea',
'value'=>'设置的值必须配对出现,如model设置了2组则后面所有都必须是2组值,换行作为组分隔符,url 格式如:/Home/DonateActivity/detail/id/__id__, 其中__id__代表该处将被数据表的id字段取代, url中可出现多个待替代值, search_fields的字段用"|"分隔,field_map格式为title=title|date=publish_date|summary=summary',
),
'description1'=>array(
'title'=>'补充说明:',
'type'=>'textarea',
'value'=>'field_map特殊处理手法,有些文章可能有summary,有些可能有content,这种情况可以使用 summary=summary|summary=content的方法来保证获取到摘要,程序已经做了非空处理,保证值不会被空字符串覆盖',
),
'model' => array(
'title'=>'model:',
'type' => 'textarea',
'value' => '',
),
'model_name' => array(
'title' => 'model_name',
'type'=> 'textarea',
'value' => '',
),
'url' => array(
'title' => 'url',
'type' => 'textarea',
'value' => '',
),
'search_fields' => array(
'title' => 'search_fields',
'type' => 'textarea',
'value' => '',
),
'field_map' => array(
'title' => 'field_map',
'type' => 'textarea',
'value' => '',
),
);

18
app/Admin/Common/function.php Executable file
View File

@ -0,0 +1,18 @@
<?php
//获取配置类型ID对应的名称
function get_config_type($type=0){
$list = C('CONFIG_TYPE_LIST');
return $list[$type];
}
//获取配置分组ID对应的名称
function get_config_group($group=''){
$list = C('CONFIG_GROUP_LIST');
return $list[$group];
}
//获取后台的网页标题
function webSiteTitle(){
$node_name = D('Node')->getNodeName(MODULE_NAME, CONTROLLER_NAME, ACTION_NAME);
return $node_name == '' ? C('WEB_SITE_TITLE') : $node_name. ' - ' . C('WEB_SITE_TITLE');
}

1
app/Admin/Common/index.html Executable file
View File

@ -0,0 +1 @@

12
app/Admin/Conf/config.php Executable file
View File

@ -0,0 +1,12 @@
<?php
return array(
// 'REQUIRE_AUTH_MODULE' => '', //需要认证模块
// 'NOT_AUTH_MODULE' => 'Public', //无需认证模块
// 'REQUIRE_AUTH_ACTION' => '',
// 'NOT_AUTH_ACTION' => 'verify',
// 'USER_AUTH_GATEWAY' => '/Admin/Public/login', //认证网关
// 'DEFAULT_THEME' => 'default', // 默认模板主题名称
// 'TMPL_DETECT_THEME' => true, // 自动侦测模板主题
// 'THEME_LIST' => 'default,custom', // 支持的模板主题项
);

1
app/Admin/Conf/index.html Executable file
View File

@ -0,0 +1 @@

5
app/Admin/Conf/tags.php Executable file
View File

@ -0,0 +1,5 @@
<?php
return array(
);

View File

@ -0,0 +1,247 @@
<?php
namespace Admin\Controller;
use Common\Model\MenuModel;
use Gy_Library\DBCont;
use Gy_Library\GyListController;
use ExportExcelByXlsx;
use Qscmf\Builder\FormBuilder;
use Qscmf\Builder\ListBuilder;
//新闻
class AboutUsController extends GyListController
{
public function index()
{
$this->_filter($map);
$model = D('AboutUs');
$count = $model->getListForCount($map);
$per_page = C('ADMIN_PER_PAGE_NUM', null, false);
if ($per_page === false) {
$page = new \Gy_Library\GyPage($count);
} else {
$page = new \Gy_Library\GyPage($count, $per_page);
}
$get_data = I('get.');
$order = 'sort asc,create_date desc,id desc';
$data_list = $model->getListForPage($map, $page->nowPage, $page->listRows, $order);
//时间戳的转换
foreach ($data_list as &$value) {
$value['title'] = cutLength($value['title'],20);
$value['author'] = cutLength($value['author'],10);
$value['create_date'] = date('Y-m-d', $value['create_date']);
}
// 使用Builder快速建立列表页面。
$builder = new ListBuilder();
$builder->addTopButton('addnew');
$builder->addTopButton('save', array('title' => '保存排序'))
->addTopButton('forbid')
->addTopButton('resume')
->setNIDByNode(MODULE_NAME, CONTROLLER_NAME, 'index');
$builder = $builder->setMetaTitle('内容管理');// 设置页面标题
// }
$builder
->addSearchItem('title', 'select_text', '单行输入', array('title' => '标题'))
->addTableColumn('title', '标题')
->addTableColumn('sort', '排序','','',true)
->addTableColumn('status', '状态', 'status', '', false)
->addTableColumn('right_button', '操作', 'btn');
$builder
->setTableDataList($data_list)// 数据列表
->setTableDataPage($page->show())// 数据列表分页
->addRightButton('edit',array('href' => U('edit',['page'=>I('get.page'),'id'=>'__data_id__']),'data-id' => '__data_id__'))// 添加编辑按钮
->addRightButton('delete')// 添加删除按钮
->addRightButton('forbid')// 添加禁用按钮
->display();
}
public function add()
{
if (IS_POST) {
parent::autoCheckToken();
$data = I('post.');
$model = D('AboutUs');
$r = $model->createAdd($data);
if ($r === false) {
$this->error($model->getError());
} else {
$this->success(l('add') . l('success'), U(CONTROLLER_NAME . '/index'));
}
} else {
// 使用FormBuilder快速建立表单页面。
$builder = new FormBuilder();
$data_list = array(
"status" => 1,
);
if ($data_list) {
$builder->setFormData($data_list);
}
//
$builder->setMetaTitle('添加内容')//设置页面标题
->setNIDByNode(MODULE_NAME, CONTROLLER_NAME, 'index')
->setPostUrl(U('add'))//设置表单提交地址
->addFormItem('title', 'text', '*标题')
->addFormItem('sort', 'num', '排序')
->addFormItem('status', 'select', '状态', '', DBCont::getStatusList())
->addFormItem('content', 'ueditor', '*内容详情')
->display();
}
}
public function save(){
if(IS_POST){
$data = I('post.');
foreach($data['id'] as $k=>$v){
$save_data['sort'] = $data['sort'][$k];
D('AboutUs')->where('id=' . $v)->save($save_data);
}
$this->success('保存成功', U('index'));
}
}
private function _filter(&$map){
$map = [];
$get_data = I('get.');
if (isset($get_data['key']) && $get_data['word'] && $get_data['key']!=='keyword') {
$map[$get_data['key']] = array('like', '%' . $get_data['word'] . '%');
}
}
public function edit($id)
{
if (IS_POST) {
parent::autoCheckToken();
$m_id = I('post.id');
$data = I('post.');
$model = D('AboutUs');
if (!$m_id) {
E('缺少内容ID');
}
$ent = $model->getOne($m_id);
if (!$ent) {
E('不存在内容');
}
$ent['title'] = $data['title'];
$ent['content'] = $data['content'];
$ent['sort'] = $data['sort'];
$ent['status'] = $data['status'];
if ($model->createSave($ent) === false) {
$this->error($model->getError());
} else {
$this->success('修改成功', U('index',['page'=>$data['page']]));
}
} else {
$info = D('AboutUs')->getOne($id);
$builder = new FormBuilder();
$info['page'] =!empty(I('get.page'))?I('get.page'):1;
$subBuilder = new \Qscmf\Builder\SubTableBuilder();
$builder->setMetaTitle('编辑'.$info['title'])
->setPostUrl(U('edit'))
// ->setExtraHtml($this->fetch('News/detail'))
->setNIDByNode(MODULE_NAME, CONTROLLER_NAME, 'index')
->addFormItem('id', 'hidden', 'ID')
->addFormItem('page', 'hidden', 'PAGE','',$info['page'])
->addFormItem('title', 'text', '*标题')
->addFormItem('sort', 'num', '排序')
->addFormItem('status', 'select', '状态', '', DBCont::getStatusList())
->addFormItem('content', 'ueditor', '*内容详情')
->setFormData($info)
->display();
}
}
public function forbid()
{
$ids = I('ids');
if (!$ids) {
$this->error('请选择要禁用的数据');
}
$r = parent::_forbid($ids);
if ($r !== false) {
// sysLogs('新闻分类id: ' . $ids . ' 禁用');
$this->success('禁用成功', U(CONTROLLER_NAME . '/index'));
} else {
$this->error($this->_getError());
}
}
public function resume()
{
$ids = I('ids');
if (!$ids) {
$this->error('请选择要启用的数据');
}
$r = parent::_resume($ids);
if ($r !== false) {
$this->success('启用成功', U(CONTROLLER_NAME . '/index'));
} else {
$this->error($this->_getError());
}
}
public function delete()
{
$ids = I('ids');
if (!$ids) {
$this->error('请选择要删除的数据');
}
$r = parent::_del($ids);
if ($r === false) {
$this->error($this->_getError());
} else {
$this->success('删除成功', U(MODULE_NAME . '/' . CONTROLLER_NAME . '/index'));
}
}
}

View File

@ -0,0 +1,234 @@
<?php
namespace Admin\Controller;
use Gy_Library\GyListController;
use Qscmf\Core\QsRbac;;
class AddonsController extends GyListController{
public function index(){
$addons_model = D('Addons');
$list = $addons_model->getAllAddonsList();
int_to_string($list, array('status'=>array(-1=>'损坏', 0=>'禁用', 1=>'启用', -2=>'未安装')));
if($list === false){
$this->error($addons_model->getError());
}
$count = $list? count($list) : 1 ;
$per_page = C('ADMIN_PER_PAGE_NUM', null, false);
if($per_page === false){
$page = new \Gy_Library\GyPage($count);
}
else{
$page = new \Gy_Library\GyPage($count, $per_page);
}
$data_list = array_slice($list, $page->firstRow, $page->listRows);
$builder = new \Qscmf\Builder\ListBuilder();
$builder->setMetaTitle('插件列表')
->setNID(307)
->setCheckBox(false)
->addTableColumn('title', '名称')
->addTableColumn('name', '标识')
->addTableColumn('description', '描述')
->addTableColumn('status_text', '状态')
->addTableColumn('author', '作者')
->addTableColumn('version', '版本')
->addTableColumn('right_button', '操作', 'btn')
->setTableDataList($data_list)
->setTableDataPage($page->show()) // 数据列表分页
->addRightButton('self', array('title' => '设置', 'href' => U('config', array('id' => '__data_id__')), 'class' => 'label label-primary', '{key}' => 'config', '{condition}' => 'neq', '{value}' => 'null'))
->addRightButton('forbid')
->addRightButton('self', array('title' => '卸载', 'href' => U('uninstall', array('id' => '__data_id__')), 'class' => 'label label-danger'))
->alterTableData( // 修改列表数据
array('key' => 'uninstall', 'value' => 1),
array('right_button' => '<a class="label label-warning" href="' . U('/admin/addons/install/addon_name/__name__') . '">安装</a>')
)
->display();
}
public function install($addon_name){
parent::autoCheckToken();
$class = get_addon_class($addon_name);
if (!class_exists($class)) {
$this->error('插件不存在');
}
$addons = new $class;
$info = $addons->info;
$hooks = $addons->hooks;
// 检测信息的正确性
if (!$info || !$addons->checkInfo()){
$this->error('插件信息缺失');
}
$install_flag = $addons->install();
if (!$install_flag) {
$this->error('执行插件预安装操作失败'.$addons->getError());
}
if(is_array($addons->admin_list) && $addons->admin_list !== array()){
$info['has_adminlist'] = 1;
}else{
$info['has_adminlist'] = 0;
}
$addons_model = D('Addons');
$r = $addons_model->createAdd($info);
if($r === false){
$this->error($addons_model->getError());
}
$config = array('config'=>json_encode($addons->getConfig()));
$addons_model->where("name='{$addon_name}'")->save($config);
$this->success('安装成功');
}
public function uninstall($id){
$addons_ent = D('Addons')->find($id);
if(!$addons_ent){
E('数据不存在');
}
$class = get_addon_class($addons_ent['name']);
if(!class_exists($class)){
E('插件不存在');
}
$addons = new $class;
$r = $addons->uninstall();
if($r === false){
$this->error($addons->getError());
}
$r = D('Addons')->where("name='{$addons_ent['name']}'")->delete();
if($r === false){
$this->error('卸载插件失败');
}
else{
$this->success('卸载成功');
}
}
public function config($id){
if(IS_POST){
parent::autoCheckToken();
$config = I('post.config');
$flag = D('Addons')->where("id={$id}")->setField('config',json_encode($config));
if($flag !== false){
$this->success('保存成功', U('index'));
}else{
$this->error('保存失败');
}
}
else{
$addons_ent = D('Addons')->find($id);
$addon_class = get_addon_class($addons_ent['name']);
if(!$addons_ent || !class_exists($addon_class)){
E('插件不存在');
}
$data = new $addon_class;
$addons_ent['addon_path'] = $data->addon_path;
$addons_ent['custom_config'] = $data->custom_config;
$db_config = $addons_ent['config'];
$db_config = json_decode($db_config, true);
$addons_ent['config'] = include $data->config_file;
$builder = new \Qscmf\Builder\FormBuilder();
$builder->setMetaTitle('设置插件-' . $data->info['title'])
->setNID(307);
// if($addons_ent['custom_config']){
// $data->displayConfig();
// return;
// }
foreach($addons_ent['config'] as $key => $value){
if($value['type'] == 'group'){
foreach($value['options'] as $k => &$v){
foreach($v['options'] as $kk => &$vv){
$vv['name'] = 'config[' . $kk . ']';
$vv['value'] = $db_config[$kk];
}
}
}
$builder->addFormItem('config[' . $key . ']', $value['type'], $value['title'], $value['remark'], $value['options']);
}
foreach($db_config as $ck => $cv){
$db_config['config[' . $ck . ']'] = $cv;
}
$builder->setFormData($db_config)
->setPostUrl(U('config', array('id' => $id))) // 设置表单提交地址
->display();
}
}
// public function adminList($addon_name, $controller, $action){
//
// }
public function forbid(){
$ids = I('ids');
if(!$ids){
$this->error('请选择要禁用的数据');
}
$r = parent::_forbid($ids);
if($r !== false){
$map['id'] = array('in', explode(',', $ids));
$names = M('Addons')->where($map)->getField('name', true);
syslogs('禁用插件:' . implode(',', $names));
$this->success('禁用成功');
}
else{
$this->error($this->_getError());
}
}
public function resume(){
$ids = I('ids');
if(!$ids){
$this->error('请选择要启用的数据');
}
$r = parent::_resume($ids);
if($r !== false){
$map['id'] = array('in', explode(',', $ids));
$names = M('Addons')->where($map)->getField('name', true);
syslogs('启用插件:' . implode(',', $names));
$this->success('启用成功');
}
else{
$this->error($this->_getError());
}
}
public function execute($_addons = null, $_controller = null, $_action = null){
if(!QsRbac::AccessDecision('admin', $_controller, $_action)){
E(l('no_auth'));
}
if(C('URL_CASE_INSENSITIVE')){
$_addons = ucfirst(parse_name($_addons, 1));
$_controller = parse_name($_controller,1);
}
$TMPL_PARSE_STRING = C('TMPL_PARSE_STRING');
$TMPL_PARSE_STRING['__ADDONROOT__'] = __ROOT__ . "/Addons/{$_addons}";
C('TMPL_PARSE_STRING', $TMPL_PARSE_STRING);
if(!empty($_addons) && !empty($_controller) && !empty($_action)){
$Addons = A("Addons://{$_addons}/{$_controller}")->$_action();
} else {
$this->error('没有指定插件名称,控制器或操作!');
}
}
}

View File

@ -0,0 +1,112 @@
<?php
namespace Admin\Controller;
use Gy_Library\GyListController;
class CoderController extends GyListController{
public function index(){
$proxy = new \Common\Coder\CoderProxy();
$object_list = $proxy->getObjectList();
$data_list = array();
foreach($object_list as $object){
$data['id'] = $object->getCoderName();
$data['name'] = $object->getName();
$data['desc'] = $object->getDesc();
$data['images'] = $this->_parseImg($object->getImages());
$data_list[] = $data;
}
$builder = new \Qscmf\Builder\ListBuilder();
$builder->setMetaTitle('代码生成器列表')
->setNID(301)
->setCheckBox(false)
->addTableColumn('name', '名称')
->addTableColumn('desc', '描述')
->addTableColumn('images', '效果图')
->addTableColumn('right_button', '操作', 'btn')
->setTableDataList($data_list)
->addRightButton('self', array('title' => '生成器', 'href' => U('generate', array('id' => '__data_id__')) , 'data-id' => '__data_id__', 'class' => 'label label-primary'))
->display();
}
private function _parseImg($file_paths){
$return = '';
foreach ($file_paths as $file){
$return .= getImgByFilePath($file);
}
return $return;
}
public function generate($id){
$proxy = new \Common\Coder\CoderProxy();
if(IS_POST){
$data = I('post.');
$coder_object = $proxy->getObject($data['id']);
$coder_object->generate();
}
else{
$coder_object = $proxy->getObject($id);
$coder_object->displayVew();
}
}
public function save(){
$proxy = new \Common\Coder\CoderProxy();
if(IS_POST){
$data = I('post.');
$coder_object = $proxy->getObject($data['id']);
$coder_object->generate(1);
}
}
public function delete($ids){
if(!$ids){
$this->error('请选择要删除的项');
}
$this->dbname = 'CoderLog';
$r = parent::_del($ids);
if($r !== false){
$this->success('删除成功', U(CONTROLLER_NAME . '/index'));
}else{
$this->error($this->_getError());
}
}
public function coderLog($id){
$proxy = new \Common\Coder\CoderProxy();
$coder_object = $proxy->getObject($id);
$coder_object->logList();
}
public function edit($id){
$ent = D('CoderLog')->getOne($id);
$proxy = new \Common\Coder\CoderProxy();
$coder_object = $proxy->getObject($ent['coder_name']);
$coder_object->displayVew($id);
}
// public function test(){
// $list = D('User')->field('id,nick_name')->select();
// }
//
// public function test1(){
// //show_bug(D("Cate")->where(array('status' => \Gy_Library\DBCont::NORMAL_STATUS))->getField('id,name'));
// $data['id'] = 1;
// $data['name'] = '不知道';
//
// $string = '<a class="label label-warning" href="/admin/coder/id/{$name}/key/{$id}/uk/{$unknow}">超级管理员无需操作</a>';
//
// while(preg_match('/.+\{\$(.+)\}.+/i', $string, $matches)){
// $string = str_replace('{$' . $matches[1] . '}', $data[$matches[1]], $string);
// }
//
// echo $string;
// }
}

View File

@ -0,0 +1,297 @@
<?php
namespace Admin\Controller;
use Gy_Library\GyListController;
use Gy_Library\DBCont;
use Qscmf\Builder\FormBuilder;
use Qscmf\Builder\ListBuilder;
use Qscmf\Builder\TSubBuilder;
/*
* 关键词
*/
class CommentController extends GyListController
{
use TSubBuilder;
private $belong_to = ['报道媒体', '报道类型'];
private $news_index = "qs_news_id";
public function index()
{
$map = [];
$get_data = I('get.');
if (isset($get_data['key']) && $get_data['word']) {
$map[$get_data['key']] = array('like', '%' . $get_data['word'] . '%');
}
$model = D('CommentsInfo');
$count = $model->getListForCount($map);
$per_page = C('ADMIN_PER_PAGE_NUM', null, false);
if ($per_page === false) {
$page = new \Gy_Library\GyPage($count);
} else {
$page = new \Gy_Library\GyPage($count, $per_page);
}
$order = 'id desc';
$data_list = $model->getListForPage($map, $page->nowPage, $page->listRows, $order);
foreach ($data_list as &$data) {
// dd($data);
$data['news_name'] = $model->getNewsName($data[$this->news_index]);
$data['from_user_name'] = $model->getUserName($data['from_id']);
if (strlen($data['from_user_name']) == 0) $data['from_user_name'] = $data['from_name'] . " (已删除)";
}
// 使用Builder快速建立列表页面。
$builder = new ListBuilder();
$builder = $builder->setMetaTitle('评论管理'); // 设置页面标题
$builder->addTopButton('addnew');
// $builder->addTopButton('save', array('title' => '保存排序'));
$builder
->setNIDByNode(MODULE_NAME, CONTROLLER_NAME, 'index')
->addSearchItem('news_name', 'select_text', '单行输入', array('name' => '名称'))
->addTableColumn('news_name', '名称')
->addTableColumn('from_user_name', '发表者')
->addTableColumn('like_num', '点赞数')
->addTableColumn('content', '评论内容')
->addTableColumn('create_time', '创建时间', 'time')
->addTableColumn('right_button', '操作', 'btn')
->setTableDataList($data_list) // 数据列表
->setTableDataPage($page->show()) // 数据列表分页
->addRightButton('edit') // 添加编辑按钮
->addRightButton('delete') // 添加删除按钮
->addRightButton('forbid') // 添加禁用按钮
// ->addRightButton('self', ['title' => '查看相关文章', 'href' => U('News/index', ['key' => 'keyword', 'word' => '__name__']), 'class' => 'label label-success'])
->display();
}
public function add()
{
if (IS_POST) {
parent::autoCheckToken();
$data = I('post.');
$data['name'] = trim($data['name']);
$data['belong_to'] = $this->belong_to[$data['belong_to']];
$model = D('SecondaryTitle');
$n_model = D('SecondaryNews');
$keyword_ids = D('Keywords')->checkKeywords($data['keywords_id'] ? $data['keywords_id'] : []);
if ($keyword_ids === false) {
$this->error(D('Keywords')->getError());
}
$data['keywords_id'] = implode(',', $keyword_ids ? $keyword_ids : []);
$data['news_id'] = implode(',', $data['news_id'] ? $data['news_id'] : []);
$data['cate_id'] = implode(',', $data['cate_id'] ? $data['cate_id'] : []);
$r = $model->createAdd($data);
if ($r === false) {
$this->error($model->getError());
} else {
$data['secondary_id'] = $r;
$n_r = $n_model->createAdd($data);
if ($n_r === false) {
$this->error($n_model->getError());
}
sysLogs('新增关键词id:' . $r);
$this->success(l('add') . l('success'), U(CONTROLLER_NAME . '/index'));
}
} else {
// 使用FormBuilder快速建立表单页面。
$builder = new FormBuilder();
$data_list = array(
"status" => 1,
"sort" => 0,
);
if ($data_list) {
$builder->setFormData($data_list);
}
$keywordBuilder = new \Qscmf\Builder\SubTableBuilder();
$keywordBuilder->addTableHeader('关键词', '30%', '输入关键词可以搜索添加现有关键词,输入@+关键词可以新增');
$keywordBuilder->addFormItem('keywords_id', 'select2', [
'tags' => true,
'options' => D('Keywords')->order('id desc')->getField('id, name', true)
]);
$newsBuilder = new \Qscmf\Builder\SubTableBuilder();
$newsBuilder->addTableHeader('新闻列表', '30%', '输入新闻可以搜索添加现有新闻');
$newsBuilder->addFormItem('news_id', 'select2', [
'tags' => true,
'options' => D('News')->order('id desc')->getField('id, title', true)
]);
$cates = D('NewsCate')->order('id asc')->getField('id, name', true);
$builder->setMetaTitle('添加关键词') //设置页面标题
->setNIDByNode(MODULE_NAME, CONTROLLER_NAME, 'index')
->setPostUrl(U('add'))
->addFormItem('belong_to', 'radio', '选项', '', $this->belong_to)
->addFormItem('name', 'text', '名称*')
->addFormItem('news_id', 'self', '新闻列表', '', $newsBuilder->makeHtml())
->addFormItem('keywords_id', 'self', '关键词', '', $keywordBuilder->makeHtml())
->addFormItem('cate_id', 'checkbox', '分类', '', $cates)
->addFormItem('sort', 'num', '排序')
->addFormItem('status', 'select', '状态', '', DBCont::getStatusList())
->display();
}
}
public function save()
{
if (IS_POST) {
$data = I('post.');
foreach ($data['id'] as $k => $v) {
$save_data['sort'] = $data['sort'][$k];
D('Keywords')->where('id=' . $v)->save($save_data);
}
$this->success('保存成功', U('index'));
}
}
public function edit($id)
{
if (IS_POST) {
parent::autoCheckToken();
$m_id = I('post.id');
$data = I('post.');
$data['name'] = trim($data['name']);
$data['belong_to'] = $this->belong_to[$data['belong_to']];
$model = D('SecondaryTitle');
if (!$m_id) {
E('缺少内容ID');
}
$ent = $model->getOne($m_id);
if (!$ent) {
E('不存在内容');
}
$keyword_ids = D('Keywords')->checkKeywords($data['keywords_id'] ? $data['keywords_id'] : []);
if ($keyword_ids === false) {
$this->error(D('Keywords')->getError());
}
$data['keywords_id'] = implode(',', $keyword_ids ? $keyword_ids : []);
$data['news_id'] = implode(',', $data['news_id'] ? $data['news_id'] : []);
$data['cate_id'] = implode(',', $data['cate_id'] ? $data['cate_id'] : []);
$n_model = D('SecondaryNews');
$news_ent = $n_model->where(['secondary_id' => $data['id']])->find();
// todo 保存关联表
// dd($data, $data['id'], $ent['id'], $news_ent);
if ($data['keywords_id']) {
$news_ent['keywords_id'] = $data['keywords_id'];
}
if ($data['news_id']) {
$news_ent['news_id'] = $data['news_id'];
}
if ($data['cate_id']) {
$news_ent['cate_id'] = $data['cate_id'];
}
$ent['name'] = $data['name'];
$ent['sort'] = $data['sort'];
$ent['belong_to'] = $data['belong_to'];
$ent['status'] = $data['status'];
if ($model->createSave($ent) === false || $n_model->createSave($news_ent) === false) {
$this->error($model->getError());
} else {
$this->success('修改成功', U('index'));
}
} else {
$model = D('SecondaryTitle');
$info = $model->getOne($id);
$is_belong_to_in_list = in_array($info['belong_to'], $this->belong_to);
$info['belong_to'] = array_search($info['belong_to'], $this->belong_to);
$s_news = $model->getConditionList($info['id']);
if ($s_news) {
$info['news_id'] = $s_news['news_id'];
$info['keywords_id'] = $s_news['keywords_id'];
$info['cate_id'] = $s_news['cate_id'];
}
$keywordBuilder = new \Qscmf\Builder\SubTableBuilder();
$keywordBuilder->setData(D('Keywords')->genKeywordId($info['keywords_id']));
$keywordBuilder->addTableHeader('关键词', '30%', '输入关键词可以搜索添加现有关键词,输入@+关键词可以新增');
$keywordBuilder->addFormItem('keywords_id', 'select2', [
'tags' => true,
'options' => D('Keywords')->order('id desc')->getField('id, name', true)
]);
$newsBuilder = new \Qscmf\Builder\SubTableBuilder();
$newsBuilder->setData(D('News')->genNewsId($info['news_id']));
$newsBuilder->addTableHeader('新闻列表', '30%', '输入新闻可以搜索添加现有新闻');
$newsBuilder->addFormItem('news_id', 'select2', [
'tags' => true,
'options' => D('News')->order('id desc')->getField('id, title', true)
]);
$cates = D('NewsCate')->order('id asc')->getField('id, name', true);
$builder = new FormBuilder();
$builder->setMetaTitle('编辑关键词')
->setPostUrl(U('edit'))
// ->setExtraHtml($this->fetch('Keywords/detail'))
->setNIDByNode(MODULE_NAME, CONTROLLER_NAME, 'index')
->addFormItem('id', 'hidden', 'ID');
if ($is_belong_to_in_list) {
$builder
->addFormItem('belong_to', 'radio', '选项', '', $this->belong_to)
->addFormItem('name', 'text', '名称')
->addFormItem('news_id', 'self', '新闻列表', '', $newsBuilder->makeHtml())
->addFormItem('keywords_id', 'self', '关键词', '', $keywordBuilder->makeHtml())
->addFormItem('cate_id', 'checkbox', '分类', '', $cates);
}
$builder
->addFormItem('sort', 'num', '排序', '', $info['sort'])
->addFormItem('status', 'select', '状态', '', DBCont::getStatusList())
->setFormData($info)
->display();
}
}
public function forbid()
{
$ids = I('ids');
if (!$ids) {
$this->error('请选择要禁用的数据');
}
$r = parent::_forbid($ids);
if ($r !== false) {
// sysLogs('新闻分类id: ' . $ids . ' 禁用');
$this->success('禁用成功', U(CONTROLLER_NAME . '/index'));
} else {
$this->error($this->_getError());
}
}
public function resume()
{
$ids = I('ids');
if (!$ids) {
$this->error('请选择要启用的数据');
}
$r = parent::_resume($ids);
if ($r !== false) {
$this->success('启用成功', U(CONTROLLER_NAME . '/index'));
} else {
$this->error($this->_getError());
}
}
public function delete()
{
$ids = I('ids');
if (!$ids) {
$this->error('请选择要删除的数据');
}
$r = parent::_del($ids);
if ($r === false) {
$this->error($this->_getError());
} else {
$this->success('删除成功', U(MODULE_NAME . '/' . CONTROLLER_NAME . '/index'));
}
}
}

View File

@ -0,0 +1,280 @@
<?php
namespace Admin\Controller;
use Gy_Library\GyListController;
use Gy_Library\DBCont;
class ConfigController extends GyListController{
public function index($status = DBCont::NORMAL_STATUS){
// 搜索
$keyword = I('keyword', '', 'string');
$condition = array('like','%'.$keyword.'%');
$group_list = C('CONFIG_GROUP_LIST');
if(in_array($keyword, $group_list)){
$flip_group_list = array_flip($group_list);
$map['name|title|group'] = array(
$condition,
$condition,
$flip_group_list[$keyword],
'_multi'=>true
);
}
else{
$map['name|title'] = array(
$condition,
$condition,
'_multi'=>true
);
}
$map['status'] = $status;
$config_model = D('Config');
$count = $config_model->getListForCount($map);
$per_page = C('ADMIN_PER_PAGE_NUM', null, false);
if($per_page === false){
$page = new \Gy_Library\GyPage($count);
}
else{
$page = new \Gy_Library\GyPage($count, $per_page);
}
$data_list = $config_model->getListForPage($map, $page->nowPage, $page->listRows, 'sort desc');
$form_type = C('FORM_ITEM_TYPE');
foreach ($data_list as &$v){
$v['group'] = $group_list[$v['group']];
$v['type'] = $form_type[$v['type']][0];
}
// 设置Tab导航数据列表
$user_status_list = DBCont::getStatusList();
foreach ($user_status_list as $key => $val) {
$tab_list[$key]['title'] = $val;
$tab_list[$key]['href'] = U('index', array('status' => $key));
}
// 使用Builder快速建立列表页面。
$builder = new \Qscmf\Builder\ListBuilder();
$builder = $builder->setMetaTitle('配置管理') // 设置页面标题
->addTopButton('addnew'); // 添加新增按钮
switch($status){
case DBCont::NORMAL_STATUS;
$builder = $builder->addTopButton('forbid'); // 添加禁用按钮
break;
case DBCont::FORBIDDEN_STATUS;
$builder = $builder->addTopButton('resume'); // 添加启用按钮
break;
default:
break;
}
$builder->addTopButton('delete') // 添加删除按钮
->setNID(61)
->setTabNav($tab_list, $status) // 设置页面Tab导航
->addTableColumn('id', 'ID')
->addTableColumn('name', '配置名称')
->addTableColumn('title', '标题')
->addTableColumn('group', '分组')
->addTableColumn('type', '类型')
->addTableColumn('right_button', '操作', 'btn')
->setTableDataList($data_list) // 数据列表
->setTableDataPage($page->show()) // 数据列表分页
->addRightButton('edit') // 添加编辑按钮
->addRightButton('forbid') // 添加禁用/启用按钮
->addRightButton('delete') // 添加删除按钮
->display();
}
public function forbid(){
$ids = I('ids');
if(!$ids){
$this->error('请选择要禁用的数据');
}
$r = parent::_forbid($ids);
if($r !== false){
sysLogs('配置项id: ' . $ids . ' 禁用');
S('DB_CONFIG_DATA', null);
$this->success('禁用成功', U(CONTROLLER_NAME . '/index'));
}
else{
$this->error($this->_getError());
}
}
public function resume(){
$ids = I('ids');
if(!$ids){
$this->error('请选择要启用的数据');
}
$r = parent::_resume($ids);
if($r !== false){
sysLogs('配置项id: ' . $ids . ' 启用');
S('DB_CONFIG_DATA', null);
$this->success('启用成功', U(CONTROLLER_NAME . '/index'));
}
else{
$this->error($this->_getError());
}
}
public function delete(){
$ids = I('ids');
if(!$ids){
$this->error('请选择要删除的数据');
}
$r = parent::_del($ids);
if($r === false){
$this->error($this->_getError());
}
else{
sysLogs('删除配置项id' . $ids);
S('DB_CONFIG_DATA', null);
$this->success('删除成功', U(MODULE_NAME . '/' . CONTROLLER_NAME . '/index'));
}
}
public function add(){
if (IS_POST) {
parent::autoCheckToken();
$data = I('post.');
$config_model = D('Config');
$r = $config_model->createAdd($data);
if($r === false){
$this->error($config_model->getError());
}
else{
sysLogs('新增配置项ID:' . $r);
S('DB_CONFIG_DATA', null);
$this->success('新增成功', U(CONTROLLER_NAME . '/index'));
}
}
else {
// 使用FormBuilder快速建立表单页面。
$type_list = C('FORM_ITEM_TYPE');
foreach($type_list as $key => $type){
$type_options[$key] = $type[0];
}
$group_options = C('CONFIG_GROUP_LIST');
$builder = new \Qscmf\Builder\FormBuilder();
$builder->setMetaTitle('新增配置') //设置页面标题
->setNID(61)
->setPostUrl(U('add')) //设置表单提交地址
->addFormItem('name', 'text', '配置名称', '用于C函数调用只能使用英文+下划线且不能重复')
->addFormItem('title', 'text', '配置标题', '用于后台显示的配置标题')
->addFormItem('sort', 'text', '排序', '显示顺序')
->addFormItem('type', 'select', '配置类型', '系统会根据不同类型解析配置值', $type_options)
->addFormItem('group', 'select', '配置分组', '配置信息的分组|不分组则不会显示该配置项', $group_options)
->addFormItem('value', 'textarea', '配置值')
->addFormItem('extra', 'textarea', '配置项', '只有当配置类型为复选框、下拉框、单选按钮时需要填写')
->addFormItem('remark', 'textarea', 'tips', '配置项说明提示')
->display();
}
}
public function edit($id){
if (IS_POST) {
parent::autoCheckToken();
$data = I('post.');
$config_model = D('Config');
$r = $config_model->createSave($data);
if($r === false){
$this->error($config_model->getError());
}
else{
sysLogs('修改配置项ID:' . $id);
S('DB_CONFIG_DATA', null);
$this->success('修改成功', U('index'));
}
} else {
// 使用FormBuilder快速建立表单页面。
$type_list = C('FORM_ITEM_TYPE');
foreach($type_list as $key => $type){
$type_options[$key] = $type[0];
}
$group_options = C('CONFIG_GROUP_LIST');
$form_data = D('Config')->getOne($id);
$builder = new \Qscmf\Builder\FormBuilder();
$builder->setMetaTitle('编辑配置') //设置页面标题
->setNID(61)
->setPostUrl(U('edit')) //设置表单提交地址
->addFormItem('id', 'hidden', 'ID')
->addFormItem('name', 'text', '配置名称', '用于C函数调用只能使用英文+下划线且不能重复')
->addFormItem('title', 'text', '配置标题', '用于后台显示的配置标题')
->addFormItem('sort', 'text', '排序', '显示顺序')
->addFormItem('type', 'select', '配置类型', '系统会根据不同类型解析配置值', $type_options)
->addFormItem('group', 'select', '配置分组', '配置信息的分组|不分组则不会显示该配置项', $group_options)
->addFormItem('value', 'textarea', '配置值')
->addFormItem('extra', 'textarea', '配置项', '只有当配置类型为复选框、下拉框、单选按钮时需要填写')
->addFormItem('remark', 'textarea', 'tips', '配置项说明提示')
->setFormData($form_data)
->display();
}
}
public function setting($group = 1){
$config = new \Common\Model\ConfigModel();
if(!empty($_POST)){
$conf_arr = I('config');
if($conf_arr && is_array($conf_arr)){
foreach ($conf_arr as $name => $value) {
$r = $config->updateConfig($name, $value);
if($r === false){
$this->error($config->getError());
}
}
S('DB_CONFIG_DATA', null);
sysLogs('修改系统配置');
$this->success('修改配置成功', U(CONTROLLER_NAME . '/setting'));
}
}else{
$group_list = C('CONFIG_GROUP_LIST');
foreach($group_list as $key => $val){
$tab_list[$key]['title'] = $val;
$tab_list[$key]['href'] = U('setting', array('group' => $key));
}
$map['status'] = DBCont::NORMAL_STATUS;
$map['group'] = $group;
$data_list = $config->getConfigList($map);
// 使用FormBuilder快速建立表单页面。
$builder = new \Qscmf\Builder\FormBuilder();
$form_data = array();
foreach($data_list as $data){
if(in_array($data['type'], ['file', 'ueditor'])){
$builder->addFormItem('config[' . $data['name'] . ']', $data['type'], $data['title'], $data['remark'], '', '', $data['extra']);
}
else{
$builder->addFormItem('config[' . $data['name'] . ']', $data['type'], $data['title'], $data['remark'], parse_config_attr($data['extra']));
}
$form_data['config[' . $data['name'] . ']'] = $data['value'];
}
$builder->setMetaTitle('系统设置') // 设置页面标题
->setNID(69)
->SetTabNav($tab_list, $group) // 设置Tab按钮列表
->setFormData($form_data)
->setPostUrl(U('setting')) // 设置表单提交地址
//->setExtraItems($data_list) // 直接设置表单数据
->display();
}
}
}

View File

@ -0,0 +1,13 @@
<?php
namespace Admin\Controller;
use Gy_Library\GyController;
class DashboardController extends GyController{
public function index(){
$this->assign('meta_title','网站概况');
$this->display();
}
}

View File

@ -0,0 +1,237 @@
<?php
namespace Admin\Controller;
use Common\Model\MenuModel;
use Gy_Library\DBCont;
use Gy_Library\GyListController;
use Qscmf\Builder\FormBuilder;
use Qscmf\Builder\ListBuilder;
//公众号关注
class FocusController extends GyListController
{
public function index()
{
$map = [];
$get_data = I('get.');
if (isset($get_data['key']) && $get_data['word']) {
$map[$get_data['key']] = array('like', '%' . $get_data['word'] . '%');
}
$model = D('Focus');
$count = $model->getListForCount($map);
$per_page = C('ADMIN_PER_PAGE_NUM', null, false);
if ($per_page === false) {
$page = new \Gy_Library\GyPage($count);
} else {
$page = new \Gy_Library\GyPage($count, $per_page);
}
$data_list = $model->getListForPage($map, $page->nowPage, $page->listRows, 'sort asc,id desc');
// 使用Builder快速建立列表页面。
$builder = new ListBuilder();
$builder = $builder->setMetaTitle('公众号管理');// 设置页面标题
$builder->addTopButton('addnew');
$builder->addTopButton('save', array('title' => '保存排序'));
$builder
->setNIDByNode(MODULE_NAME, CONTROLLER_NAME, 'index')
->addSearchItem('title', 'select_text', '单行输入', array('name' => '名称'))
->addTableColumn('name', '名称')
->addTableColumn('sort', '排序','','',true)
->addTableColumn('status', '状态', 'status', '', false)
->addTableColumn('right_button', '操作', 'btn')
->setTableDataList($data_list)// 数据列表
->setTableDataPage($page->show())// 数据列表分页
->addRightButton('edit')// 添加编辑按钮
->addRightButton('delete')// 添加删除按钮
->addRightButton('forbid')// 添加禁用按钮
->display();
}
public function add()
{
if (IS_POST) {
parent::autoCheckToken();
$data = I('post.');
$model = D('Focus');
$r = $model->checkQrCodeOrUrl($data);
if ($r === false) {
$this->error($model->getError());
}
$r = $model->createAdd($data);
if ($r === false) {
$this->error($model->getError());
} else {
// sysLogs('新增内容id:' . $r);
$this->success(l('add') . l('success'), U(CONTROLLER_NAME . '/index'));
}
} else {
// 使用FormBuilder快速建立表单页面。
$builder = new FormBuilder();
$data_list = array(
"status" => 1,
);
if ($data_list) {
$builder->setFormData($data_list);
}
$builder->setMetaTitle('添加公众号')//设置页面标题
->setNIDByNode(MODULE_NAME, CONTROLLER_NAME, 'index')
->setPostUrl(U('add'))//设置表单提交地址
->addFormItem('name', 'text', '名称')
->addFormItem('logo', 'picture', 'LOGO图','尺寸为33*27px,格式JPG、PNG、JPEG')
->addFormItem('code_name', 'text', '二维码标题')
->addFormItem('qr_code', 'picture', '二维码','200*200px,格式JPG、PNG、JPEG')
->addFormItem('url', 'text', '链接地址' ,'地址请以https://或http://开头(非必填,如不填则不跳转)')
->addFormItem('sort', 'num', '排序')
->addFormItem('status', 'select', '状态', '', DBCont::getStatusList())
->display();
}
}
public function save(){
if(IS_POST){
$data = I('post.');
foreach($data['id'] as $k=>$v){
$save_data['sort'] = $data['sort'][$k];
D('Focus')->where('id=' . $v)->save($save_data);
}
$this->success('保存成功', U('index'));
}
}
public function edit($id)
{
if (IS_POST) {
parent::autoCheckToken();
$m_id = I('post.id');
$data = I('post.');
$model = D('Focus');
$r = $model->checkQrCodeOrUrl($data);
if ($r === false) {
$this->error($model->getError());
}
if (!$m_id) {
E('缺少内容ID');
}
$ent = $model->getOne($m_id);
if (!$ent) {
E('不存在内容');
}
$ent['name'] = $data['name'];
$ent['logo'] = $data['logo'];
$ent['qr_code'] = $data['qr_code'];
$ent['code_name'] = $data['code_name'];
$ent['url'] = $data['url'];
$ent['sort'] = $data['sort'];
$ent['status'] = $data['status'];
if ($model->createSave($ent) === false) {
$this->error($model->getError());
} else {
$this->success('修改成功', U('index'));
}
} else {
$info = D('Focus')->getOne($id);
$builder = new FormBuilder();
$builder->setMetaTitle('编辑'.$info['name'])
->setPostUrl(U('edit'))
// ->setExtraHtml($this->fetch('Focus/detail'))
->setNIDByNode(MODULE_NAME, CONTROLLER_NAME, 'index')
->addFormItem('id', 'hidden', 'ID')
->addFormItem('name', 'text', '名称')
->addFormItem('logo', 'picture', 'LOGO图','尺寸为33*27px,格式JPG、PNG、JPEG')
->addFormItem('code_name', 'text', '二维码标题')
->addFormItem('qr_code', 'picture', '二维码','尺寸为200*200px,格式JPG、PNG、JPEG')
->addFormItem('url', 'text', '链接地址' ,'地址请以https://或http://开头(非必填,如不填则不跳转)')
->addFormItem('sort', 'num', '排序')
->addFormItem('status', 'select', '状态', '', DBCont::getStatusList())
->setFormData($info)
->display();
}
}
public function forbid()
{
$ids = I('ids');
if (!$ids) {
$this->error('请选择要禁用的数据');
}
$r = parent::_forbid($ids);
if ($r !== false) {
// sysLogs('新闻分类id: ' . $ids . ' 禁用');
$this->success('禁用成功', U(CONTROLLER_NAME . '/index'));
} else {
$this->error($this->_getError());
}
}
public function resume()
{
$ids = I('ids');
if (!$ids) {
$this->error('请选择要启用的数据');
}
$r = parent::_resume($ids);
if ($r !== false) {
$this->success('启用成功', U(CONTROLLER_NAME . '/index'));
} else {
$this->error($this->_getError());
}
}
public function delete()
{
$ids = I('ids');
if (!$ids) {
$this->error('请选择要删除的数据');
}
$r = parent::_del($ids);
if ($r === false) {
$this->error($this->_getError());
} else {
$this->success('删除成功', U(MODULE_NAME . '/' . CONTROLLER_NAME . '/index'));
}
}
}

View File

@ -0,0 +1,178 @@
<?php
namespace Admin\Controller;
use Gy_Library\DBCont;
class HooksController extends \Gy_Library\GyListController{
public function index($status = DBCont::NORMAL_STATUS){
$map['status'] = $status;
$hooks_model = D('Hooks');
$count = $hooks_model->getListForCount($map);
$per_page = C('ADMIN_PER_PAGE_NUM', null, false);
if($per_page === false){
$page = new \Gy_Library\GyPage($count);
}
else{
$page = new \Gy_Library\GyPage($count, $per_page);
}
$data_list = $hooks_model->getListForPage($map, $page->nowPage, $page->listRows, 'id desc');
foreach($data_list as $key => $hook){
$addons = getHookAddons($hook['name']);
$hook['addons'] = implode(',', $addons);
$data_list[$key] = $hook;
}
// 设置Tab导航数据列表
$status_list = DBCont::getStatusList();
foreach ($status_list as $key => $val) {
$tab_list[$key]['title'] = $val;
$tab_list[$key]['href'] = U('index', array('status' => $key));
}
// 使用Builder快速建立列表页面。
$builder = new \Qscmf\Builder\ListBuilder();
$builder = $builder->setMetaTitle('钩子列表') // 设置页面标题
->addTopButton('addnew'); // 添加新增按钮
switch($status){
case DBCont::NORMAL_STATUS;
$builder = $builder->addTopButton('forbid'); // 添加禁用按钮
break;
case DBCont::FORBIDDEN_STATUS;
$builder = $builder->addTopButton('resume'); // 添加启用按钮
break;
default:
break;
}
$builder->addTopButton('delete') // 添加删除按钮
->setNID(122)
->setTabNav($tab_list, $status) // 设置页面Tab导航
->addTableColumn('name', '名称')
->addTableColumn('desc', '描述')
->addTableColumn('addons', '挂载插件')
->addTableColumn('right_button', '操作', 'btn')
->setTableDataList($data_list) // 数据列表
->setTableDataPage($page->show()) // 数据列表分页
->addRightButton('edit') // 添加编辑按钮
->addRightButton('forbid') // 添加禁用/启用按钮
->addRightButton('delete') // 添加删除按钮
->display();
}
public function add(){
if (IS_POST) {
parent::autoCheckToken();
$data = I('post.');
$hooks_model = D('Hooks');
$r = $hooks_model->createAdd($data);
if($r === false){
$this->error($hooks_model->getError());
}
else{
$hooks_ent = D('Hooks')->find($r);
sysLogs('新增钩子:' . $hooks_ent['name']);
$this->success(l('add') . l('success'), U(CONTROLLER_NAME . '/index'));
}
}
else {
// 使用FormBuilder快速建立表单页面。
$builder = new \Qscmf\Builder\FormBuilder();
$builder->setMetaTitle('新增钩子') //设置页面标题
->setNID(122)
->setPostUrl(U('add')) //设置表单提交地址
->addFormItem('name', 'text', '钩子名称')
->addFormItem('desc', 'text', '钩子描述')
->display();
}
}
public function edit($id){
if (IS_POST) {
parent::autoCheckToken();
$data = I('post.');
$hooks_model = D('Hooks');
$r = $hooks_model->createSave($data);
if($r === false){
$this->error($hooks_model->getError());
}
sysLogs('修改钩子id:' . $data['id']);
$this->success('修改成功', U(CONTROLLER_NAME . '/index'));
} else {
// 获取账号信息
$info = D('Hooks')->getOne($id);
// 使用FormBuilder快速建立表单页面。
$builder = new \Qscmf\Builder\FormBuilder();
$builder->setMetaTitle('编辑钩子') //设置页面标题
->setNID(122)
->setPostUrl(U('edit')) //设置表单提交地址
->addFormItem('id', 'hidden', 'ID')
->addFormItem('name', 'text', '钩子名称')
->addFormItem('desc', 'text', '钩子描述')
->setFormData($info)
->display();
}
}
public function forbid(){
$ids = I('ids');
if(!$ids){
$this->error('请选择要禁用的数据');
}
$r = parent::_forbid($ids);
if($r !== false){
$map['id'] = array('in', explode(',', $ids));
$names = M('hooks')->where($map)->getField('name', true);
syslogs('禁用钩子:' . implode(',', $names));
$this->success('禁用成功');
}
else{
$this->error($this->_getError());
}
}
public function resume(){
$ids = I('ids');
if(!$ids){
$this->error('请选择要启用的数据');
}
$r = parent::_resume($ids);
if($r !== false){
$map['id'] = array('in', explode(',', $ids));
$names = M('hooks')->where($map)->getField('name', true);
syslogs('启用钩子:' . implode(',', $names));
$this->success('启用成功');
}
else{
$this->error($this->_getError());
}
}
public function delete(){
$ids = I('ids');
if(!$ids){
$this->error('请选择要删除的数据');
}
$r = parent::_del($ids);
if($r === false){
$this->error($this->_getError());
}
else{
$map['id'] = array('in', explode(',', $ids));
$names = M('hooks')->where($map)->getField('name', true);
syslogs('删除钩子:' . implode(',', $names));
$this->success('删除成功');
}
}
}

View File

@ -0,0 +1,271 @@
<?php
namespace Admin\Controller;
use Common\Model\MenuModel;
use Gy_Library\DBCont;
use Gy_Library\GyListController;
use Qscmf\Builder\FormBuilder;
use Qscmf\Builder\ListBuilder;
//首页轮播图
class IndexBannerController extends GyListController
{
public function index()
{
$map = [];
$get_data = I('get.');
if (isset($get_data['key']) && $get_data['word']) {
$map[$get_data['key']] = array('like', '%' . $get_data['word'] . '%');
}
$model = D('IndexBanner');
$count = $model->getListForCount($map);
$per_page = C('ADMIN_PER_PAGE_NUM', null, false);
if ($per_page === false) {
$page = new \Gy_Library\GyPage($count);
} else {
$page = new \Gy_Library\GyPage($count, $per_page);
}
$data_list = $model->getListForPage($map, $page->nowPage, $page->listRows, 'sort asc,id desc');
//时间戳的转换
foreach ($data_list as &$value) {
$value['create_date'] = date('Y-m-d H:i:s', $value['create_date']);
}
// 使用Builder快速建立列表页面。
$builder = new ListBuilder();
$builder = $builder->setMetaTitle('首页轮播图');// 设置页面标题
$builder->addTopButton('addnew');
$builder->addTopButton('save', array('title' => '保存排序'));
$builder
->setNIDByNode(MODULE_NAME, CONTROLLER_NAME, 'index')
->addSearchItem('title', 'select_text', '单行输入', array('name' => '标题'))
->addTableColumn('name', '标题')
->addTableColumn('sort', '排序','','',true)
->addTableColumn('status', '状态', 'status', '', false)
->addTableColumn('right_button', '操作', 'btn')
->setTableDataList($data_list)// 数据列表
->setTableDataPage($page->show())// 数据列表分页
->addRightButton('edit')// 添加编辑按钮
->addRightButton('delete')// 添加删除按钮
->addRightButton('forbid')// 添加禁用按钮
->display();
}
public function add()
{
if (IS_POST) {
parent::autoCheckToken();
$data = I('post.');
$model = D('IndexBanner');
$r = $model->createAdd($data);
if ($r === false) {
$this->error($model->getError());
} else {
// sysLogs('新增内容id:' . $r);
$this->success(l('add') . l('success'), U(CONTROLLER_NAME . '/index'));
}
} else {
// 使用FormBuilder快速建立表单页面。
$menu_model = new MenuModel();
$menu_list = $menu_model->getMenuListGroupByType();
$this->assign('menu_list_json', json_encode($menu_list));
$builder = new FormBuilder();
$data_list = array(
"status" => 1,
);
if ($data_list) {
$builder->setFormData($data_list);
}
$builder->setMetaTitle('添加首页轮播图')//设置页面标题
->setNIDByNode(MODULE_NAME, CONTROLLER_NAME, 'index')
->setPostUrl(U('add'))//设置表单提交地址
->addFormItem('name', 'text', '*标题')
->addFormItem('cover_id', 'picture', '*轮播图','尺寸为711*400px,格式JPG、PNG、JPEG')
->addFormItem('url', 'text', '链接地址' ,'地址请以https://或http://开头(非必填,如不填则不跳转)')
->addFormItem('sort', 'num', '排序')
->addFormItem('status', 'select', '状态', '', DBCont::getStatusList())
->display();
}
}
public function save(){
if(IS_POST){
$data = I('post.');
foreach($data['id'] as $k=>$v){
$save_data['sort'] = $data['sort'][$k];
D('IndexBanner')->where('id=' . $v)->save($save_data);
}
$this->success('保存成功', U('index'));
}
}
public function edit($id)
{
if (IS_POST) {
parent::autoCheckToken();
$m_id = I('post.id');
$data = I('post.');
$model = D('IndexBanner');
if (!$m_id) {
E('缺少内容ID');
}
$ent = $model->getOne($m_id);
if (!$ent) {
E('不存在内容');
}
$ent['name'] = $data['name'];
$ent['cover_id'] = $data['cover_id'];
$ent['url'] = $data['url'];
$ent['sort'] = $data['sort'];
$ent['status'] = $data['status'];
// $ent['status'] = $data['status'];
if ($model->createSave($ent) === false) {
$this->error($model->getError());
} else {
$this->success('修改成功', U('index'));
}
} else {
$info = D('IndexBanner')->getOne($id);
$builder = new FormBuilder();
$builder->setMetaTitle('编辑首页轮播图'.$info['name'])
->setPostUrl(U('edit'))
// ->setExtraHtml($this->fetch('IndexBanner/detail'))
->setNIDByNode(MODULE_NAME, CONTROLLER_NAME, 'index')
->addFormItem('id', 'hidden', 'ID')
->addFormItem('name', 'text', '*标题')
->addFormItem('cover_id', 'picture', '*轮播图','尺寸为711*400px,格式JPG、PNG、JPEG')
->addFormItem('url', 'text', '链接地址' ,'地址请以https://或http://开头(非必填,如不填则不跳转)')
->addFormItem('sort', 'num', '排序')
->addFormItem('status', 'select', '状态', '', DBCont::getStatusList())
->setFormData($info)
->display();
}
}
public function forbid()
{
$ids = I('ids');
if (!$ids) {
$this->error('请选择要禁用的数据');
}
$r = parent::_forbid($ids);
if ($r !== false) {
// sysLogs('新闻分类id: ' . $ids . ' 禁用');
$this->success('禁用成功', U(CONTROLLER_NAME . '/index'));
} else {
$this->error($this->_getError());
}
}
public function resume()
{
$ids = I('ids');
if (!$ids) {
$this->error('请选择要启用的数据');
}
$r = parent::_resume($ids);
if ($r !== false) {
$this->success('启用成功', U(CONTROLLER_NAME . '/index'));
} else {
$this->error($this->_getError());
}
}
public function delete()
{
$ids = I('ids');
if (!$ids) {
$this->error('请选择要删除的数据');
}
$r = parent::_del($ids);
if ($r === false) {
$this->error($this->_getError());
} else {
$this->success('删除成功', U(MODULE_NAME . '/' . CONTROLLER_NAME . '/index'));
}
}
public function extractNumberGetName($strs, $countarr)
{
$patterns = "/\d+/";
$str = '';
preg_match_all($patterns, $strs, $arr);
$i = 0;
foreach ($arr[0] as $key => $value) {
if ($i == 0) {
$str .= $countarr[$value];
} else {
$str .= '、' . $countarr[$value];
}
$i++;
}
return $str;
}
public function toolbars()
{
return ['toolbars' => [
[
'undo', 'redo',
'bold', 'italic', 'underline', 'fontborder', 'strikethrough', 'superscript', 'subscript', 'removeformat', 'formatmatch', 'autotypeset', 'blockquote', 'pasteplain', '|', 'forecolor', 'backcolor', 'insertorderedlist', 'insertunorderedlist', 'selectall', 'cleardoc', '|',
'rowspacingtop', 'rowspacingbottom', 'lineheight', '|',
'customstyle', 'paragraph', 'fontfamily', 'fontsize', '|',
'indent', '|', 'justifyleft', 'justifycenter', 'justifyright', 'justifyjustify', '|',
'link', 'unlink', 'anchor', '|', 'imagenone', 'imageleft', 'imageright', 'imagecenter', '|',
'simpleupload', 'insertimage', '|', 'horizontal', 'spechars', 'wordimage', '|',
'inserttable', 'deletetable', 'insertparagraphbeforetable', 'insertrow', 'deleterow', 'insertcol', 'deletecol', 'mergecells', 'mergeright', 'mergedown', 'splittocells', 'splittorows', 'splittocols', 'charts',
'|', 'fullscreen', 'source', '|', 'attachment'
]
]
];
}
}

View File

@ -0,0 +1,11 @@
<?php
namespace Admin\Controller;
class IndexController extends \Gy_Library\GyController{
public function index(){
$this->redirect(C('USER_AUTH_GATEWAY'));
}
}

View File

@ -0,0 +1,81 @@
<?php
/**
* Created by PhpStorm.
* User: 95869
* Date: 2019/3/12
* Time: 9:51
*/
namespace Admin\Controller;
use Qscmf\Builder\FormBuilder;
use Qscmf\Builder\ListBuilder;
use Gy_Library\GyListController;
class JsErrLogController extends GyListController
{
private function _filter(&$map=[]){
$get_data=I('get.');
isset($get_data['url']) && $map['url']=['like','%'.$get_data['url'].'%'];
if (isset($get_data['create_date']) && $get_data['create_date']){
$date=explode('-',$get_data['create_date']);
$map['create_date']=[
['lt',strtotime($date[1])],
['gt',strtotime($date[0])]
];
}
}
public function index(){
$this->_filter($map);
$model=D('JsErrlog');
$count = $model->getListForCount($map);
$per_page = C('ADMIN_PER_PAGE_NUM', null, false);
if($per_page === false){
$page = new \Gy_Library\GyPage($count);
}
else{
$page = new \Gy_Library\GyPage($count, $per_page);
}
$data_list = $model->getListForPage($map, $page->nowPage, $page->listRows, 'create_date desc');
$builder=new ListBuilder();
$builder->setMetaTitle('前台js异常')
->setNID(990)
->setTableDataList($data_list)
->setTableDataPage($page->show())
->addSearchItem('create_date','date_range','出现时间')
->addSearchItem('url','text','url')
->addTableColumn('url','url')
->addTableColumn('msg','异常信息')
->addTableColumn('file','异常文件')
->addTableColumn('browser','浏览器')
->addTableColumn('create_date','出现时间','time')
->addTableColumn('right_button', '操作', 'btn')
->addRightButton('edit',['title'=>'查看'])
->display();
}
public function edit($id){
$data=D('JsErrlog')->getOne($id);
$builder=new FormBuilder();
$builder->setMetaTitle('前台js异常详情')
->setNID(990)
->addFormItem('url','text','url','',[],[],'disabled')
->addFormItem('browser','text','浏览器','',[],[],'disabled')
->addFormItem('msg','text','异常信息','',[],[],'disabled')
->addFormItem('file','text','异常文件','',[],[],'disabled')
->addFormItem('line_no','text','行号','',[],[],'disabled')
->addFormItem('col_no','text','列号','',[],[],'disabled')
->addFormItem('stack','textarea','堆栈','',[],[],'disabled')
->addFormItem('user_agent','textarea','UA','',[],[],'disabled')
->addFormItem('create_date','datetime','出现时间','',[],[],'disabled')
->setFormData($data)
->setExtraHtml($this->fetch('edit_extra'))
->display();
}
}

View File

@ -0,0 +1,215 @@
<?php
namespace Admin\Controller;
use Gy_Library\GyListController;
use Gy_Library\DBCont;
use Qscmf\Builder\FormBuilder;
use Qscmf\Builder\ListBuilder;
/*
* 关键词
*/
class KeywordsController extends GyListController
{
public function index()
{
$map = [];
$get_data = I('get.');
if (isset($get_data['key']) && $get_data['word']) {
$map[$get_data['key']] = array('like', '%' . $get_data['word'] . '%');
}
$model = D('Keywords');
$count = $model->getListForCount($map);
$per_page = C('ADMIN_PER_PAGE_NUM', null, false);
if ($per_page === false) {
$page = new \Gy_Library\GyPage($count);
} else {
$page = new \Gy_Library\GyPage($count, $per_page);
}
$order = 'sort asc,id desc';
if (!empty($get_data['click_time']) && $get_data['click_time']==='asc') {
$order = 'total_time asc';
}elseif (!empty($get_data['click_time']) && $get_data['click_time']==='desc'){
$order = 'total_time desc';
}
$data_list = $model->getListForPage($map, $page->nowPage, $page->listRows, $order);
// 使用Builder快速建立列表页面。
$builder = new ListBuilder();
$builder = $builder->setMetaTitle('关键词管理');// 设置页面标题
$builder->addTopButton('addnew');
// $builder->addTopButton('save', array('title' => '保存排序'));
$builder
->addSearchItem('click_time', 'select', '点击量排序', array('asc' => '点击量正序','desc'=>'点击量倒序'))
->setNIDByNode(MODULE_NAME, CONTROLLER_NAME, 'index')
->addSearchItem('title', 'select_text', '单行输入', array('name' => '名称'))
->addTableColumn('name', '名称')
->addTableColumn('total_time', '点击量','','',false)
->addTableColumn('status', '状态', 'status', '', false)
->addTableColumn('right_button', '操作', 'btn')
->setTableDataList($data_list)// 数据列表
->setTableDataPage($page->show())// 数据列表分页
->addRightButton('edit')// 添加编辑按钮
->addRightButton('delete')// 添加删除按钮
->addRightButton('forbid')// 添加禁用按钮
->addRightButton('self', ['title' => '查看相关文章', 'href' => U('News/index', ['key' => 'keyword','word'=>'__name__']), 'class' => 'label label-success'])
->display();
}
public function add()
{
if (IS_POST) {
parent::autoCheckToken();
$data = I('post.');
$data['name'] = trim($data['name']);
$model = D('Keywords');
$r = $model->createAdd($data);
if ($r === false) {
$this->error($model->getError());
} else {
sysLogs('新增关键词id:' . $r);
$this->success(l('add') . l('success'), U(CONTROLLER_NAME . '/index'));
}
} else {
// 使用FormBuilder快速建立表单页面。
$builder = new FormBuilder();
$data_list = array(
"status" => 1,
"sort" => 0,
);
if ($data_list) {
$builder->setFormData($data_list);
}
$builder->setMetaTitle('添加关键词')//设置页面标题
->setNIDByNode(MODULE_NAME, CONTROLLER_NAME, 'index')
->setPostUrl(U('add'))//设置表单提交地址
->addFormItem('name', 'text', '名称')
->addFormItem('sort', 'hidden', '排序')
->addFormItem('status', 'select', '状态', '', DBCont::getStatusList())
->display();
}
}
public function save(){
if(IS_POST){
$data = I('post.');
foreach($data['id'] as $k=>$v){
$save_data['sort'] = $data['sort'][$k];
D('Keywords')->where('id=' . $v)->save($save_data);
}
$this->success('保存成功', U('index'));
}
}
public function edit($id)
{
if (IS_POST) {
parent::autoCheckToken();
$m_id = I('post.id');
$data = I('post.');
$data['name'] = trim($data['name']);
$model = D('Keywords');
if (!$m_id) {
E('缺少内容ID');
}
$ent = $model->getOne($m_id);
if (!$ent) {
E('不存在内容');
}
$ent['name'] = $data['name'];
$ent['sort'] = $data['sort'];
$ent['status'] = $data['status'];
if ($model->createSave($ent) === false) {
$this->error($model->getError());
} else {
$this->success('修改成功', U('index'));
}
} else {
$info = D('Keywords')->getOne($id);
$builder = new FormBuilder();
$builder->setMetaTitle('编辑关键词')
->setPostUrl(U('edit'))
// ->setExtraHtml($this->fetch('Keywords/detail'))
->setNIDByNode(MODULE_NAME, CONTROLLER_NAME, 'index')
->addFormItem('id', 'hidden', 'ID')
->addFormItem('name', 'text', '名称')
->addFormItem('sort', 'hidden', '排序','',$info['sort'])
->addFormItem('status', 'select', '状态', '', DBCont::getStatusList())
->setFormData($info)
->display();
}
}
public function forbid()
{
$ids = I('ids');
if (!$ids) {
$this->error('请选择要禁用的数据');
}
$r = parent::_forbid($ids);
if ($r !== false) {
// sysLogs('新闻分类id: ' . $ids . ' 禁用');
$this->success('禁用成功', U(CONTROLLER_NAME . '/index'));
} else {
$this->error($this->_getError());
}
}
public function resume()
{
$ids = I('ids');
if (!$ids) {
$this->error('请选择要启用的数据');
}
$r = parent::_resume($ids);
if ($r !== false) {
$this->success('启用成功', U(CONTROLLER_NAME . '/index'));
} else {
$this->error($this->_getError());
}
}
public function delete()
{
$ids = I('ids');
if (!$ids) {
$this->error('请选择要删除的数据');
}
$r = parent::_del($ids);
if ($r === false) {
$this->error($this->_getError());
} else {
$this->success('删除成功', U(MODULE_NAME . '/' . CONTROLLER_NAME . '/index'));
}
}
public function getKeyword(){
$result = D('Keywords')->field('id, name')->where(['status'=>DBCont::YES_BOOL_STATUS])->order('sort asc, id asc')->select();
$this->ajaxReturn($result);
}
public function addKeyword($labelName){
C('TOKEN_ON', false);
$data['name'] = $labelName;
$model = D('Keywords');
$r = $model->createAdd($data);
if($r === false){
$this->error($model->getError());
}else{
$new_keyword = $model->where(['id' => $r])->field('id,name')->select();
$this->ajaxReturn($new_keyword);
}
}
public function delKeyword($id){
$r = D('Keywords')->del($id);
$this->ajaxReturn($r);
}
}

View File

@ -0,0 +1,264 @@
<?php
namespace Admin\Controller;
use Common\Model\MenuModel;
use Gy_Library\DBCont;
use Gy_Library\GyListController;
use Qscmf\Builder\FormBuilder;
use Qscmf\Builder\ListBuilder;
//友情链接
class LinksController extends GyListController
{
public function index()
{
$map = [];
$get_data = I('get.');
if (isset($get_data['key']) && $get_data['word']) {
$map[$get_data['key']] = array('like', '%' . $get_data['word'] . '%');
}
$model = D('Links');
$count = $model->getListForCount($map);
$per_page = C('ADMIN_PER_PAGE_NUM', null, false);
if ($per_page === false) {
$page = new \Gy_Library\GyPage($count);
} else {
$page = new \Gy_Library\GyPage($count, $per_page);
}
$data_list = $model->getListForPage($map, $page->nowPage, $page->listRows, 'sort asc,id desc');
//时间戳的转换
foreach ($data_list as &$value) {
$value['create_date'] = date('Y-m-d H:i:s', $value['create_date']);
}
// 使用Builder快速建立列表页面。
$builder = new ListBuilder();
$builder = $builder->setMetaTitle('友情链接');// 设置页面标题
$builder->addTopButton('addnew');
$builder->addTopButton('save', array('title' => '保存排序'));
$builder
->setNIDByNode(MODULE_NAME, CONTROLLER_NAME, 'index')
->addSearchItem('title', 'select_text', '单行输入', array('name' => '链接名称'))
->addTableColumn('name', '链接名称')
->addTableColumn('sort', '排序','','',true)
->addTableColumn('status', '状态', 'status', '', false)
->addTableColumn('right_button', '操作', 'btn')
->setTableDataList($data_list)// 数据列表
->setTableDataPage($page->show())// 数据列表分页
->addRightButton('edit')// 添加编辑按钮
->addRightButton('delete')// 添加删除按钮
->addRightButton('forbid')// 添加禁用按钮
->display();
}
public function add()
{
if (IS_POST) {
parent::autoCheckToken();
$data = I('post.');
$model = D('Links');
$r = $model->createAdd($data);
if ($r === false) {
$this->error($model->getError());
} else {
// sysLogs('新增内容id:' . $r);
$this->success(l('add') . l('success'), U(CONTROLLER_NAME . '/index'));
}
} else {
// 使用FormBuilder快速建立表单页面。
$builder = new FormBuilder();
$data_list = array(
"status" => 1,
);
if ($data_list) {
$builder->setFormData($data_list);
}
$builder->setMetaTitle('添加友情链接')//设置页面标题
->setNIDByNode(MODULE_NAME, CONTROLLER_NAME, 'index')
->setPostUrl(U('add'))//设置表单提交地址
->addFormItem('name', 'text', '*链接名称')
->addFormItem('url', 'text', '*链接地址' ,'地址请以https://或http://开头')
->addFormItem('sort', 'num', '排序')
->addFormItem('status', 'select', '状态', '', DBCont::getStatusList())
->display();
}
}
public function save(){
if(IS_POST){
$data = I('post.');
foreach($data['id'] as $k=>$v){
$save_data['sort'] = $data['sort'][$k];
D('Links')->where('id=' . $v)->save($save_data);
}
$this->success('保存成功', U('index'));
}
}
public function edit($id)
{
if (IS_POST) {
parent::autoCheckToken();
$m_id = I('post.id');
$data = I('post.');
$model = D('Links');
if (!$m_id) {
E('缺少内容ID');
}
$ent = $model->getOne($m_id);
if (!$ent) {
E('不存在内容');
}
$ent['name'] = $data['name'];
$ent['url'] = $data['url'];
$ent['sort'] = $data['sort'];
$ent['status'] = $data['status'];
// $ent['status'] = $data['status'];
if ($model->createSave($ent) === false) {
$this->error($model->getError());
} else {
$this->success('修改成功', U('index'));
}
} else {
$info = D('Links')->getOne($id);
$builder = new FormBuilder();
$builder->setMetaTitle('编辑'.$info['name'])
->setPostUrl(U('edit'))
// ->setExtraHtml($this->fetch('Links/detail'))
->setNIDByNode(MODULE_NAME, CONTROLLER_NAME, 'index')
->addFormItem('id', 'hidden', 'ID')
->addFormItem('name', 'text', '*链接名称')
->addFormItem('url', 'text', '*链接地址' ,'地址请以https://或http://开头')
->addFormItem('sort', 'num', '排序')
->addFormItem('status', 'select', '状态', '', DBCont::getStatusList())
->setFormData($info)
->display();
}
}
public function forbid()
{
$ids = I('ids');
if (!$ids) {
$this->error('请选择要禁用的数据');
}
$r = parent::_forbid($ids);
if ($r !== false) {
// sysLogs('新闻分类id: ' . $ids . ' 禁用');
$this->success('禁用成功', U(CONTROLLER_NAME . '/index'));
} else {
$this->error($this->_getError());
}
}
public function resume()
{
$ids = I('ids');
if (!$ids) {
$this->error('请选择要启用的数据');
}
$r = parent::_resume($ids);
if ($r !== false) {
$this->success('启用成功', U(CONTROLLER_NAME . '/index'));
} else {
$this->error($this->_getError());
}
}
public function delete()
{
$ids = I('ids');
if (!$ids) {
$this->error('请选择要删除的数据');
}
$r = parent::_del($ids);
if ($r === false) {
$this->error($this->_getError());
} else {
$this->success('删除成功', U(MODULE_NAME . '/' . CONTROLLER_NAME . '/index'));
}
}
public function extractNumberGetName($strs, $countarr)
{
$patterns = "/\d+/";
$str = '';
preg_match_all($patterns, $strs, $arr);
$i = 0;
foreach ($arr[0] as $key => $value) {
if ($i == 0) {
$str .= $countarr[$value];
} else {
$str .= '、' . $countarr[$value];
}
$i++;
}
return $str;
}
public function toolbars()
{
return ['toolbars' => [
[
'undo', 'redo',
'bold', 'italic', 'underline', 'fontborder', 'strikethrough', 'superscript', 'subscript', 'removeformat', 'formatmatch', 'autotypeset', 'blockquote', 'pasteplain', '|', 'forecolor', 'backcolor', 'insertorderedlist', 'insertunorderedlist', 'selectall', 'cleardoc', '|',
'rowspacingtop', 'rowspacingbottom', 'lineheight', '|',
'customstyle', 'paragraph', 'fontfamily', 'fontsize', '|',
'indent', '|', 'justifyleft', 'justifycenter', 'justifyright', 'justifyjustify', '|',
'link', 'unlink', 'anchor', '|', 'imagenone', 'imageleft', 'imageright', 'imagecenter', '|',
'simpleupload', 'insertimage', '|', 'horizontal', 'spechars', 'wordimage', '|',
'inserttable', 'deletetable', 'insertparagraphbeforetable', 'insertrow', 'deleterow', 'insertcol', 'deletecol', 'mergecells', 'mergeright', 'mergedown', 'splittocells', 'splittorows', 'splittocols', 'charts',
'|', 'fullscreen', 'source', '|', 'attachment'
]
]
];
}
}

View File

@ -0,0 +1,222 @@
<?php
namespace Admin\Controller;
use Gy_Library\GyListController;
use Gy_Library\DBCont;
class MenuController extends GyListController{
public function index($status = DBCont::NORMAL_STATUS){
$map['status'] = $status;
$menu_model = D('Menu');
$count = $menu_model->getListForCount($map);
$per_page = C('ADMIN_PER_PAGE_NUM', null, false);
if($per_page === false){
$page = new \Gy_Library\GyPage($count);
}
else{
$page = new \Gy_Library\GyPage($count, $per_page);
}
$data_list = $menu_model->getListForPage($map, $page->nowPage, $page->listRows, 'type desc, sort asc');
// 设置Tab导航数据列表
$status_list = DBCont::getStatusList();
foreach ($status_list as $key => $val) {
$tab_list[$key]['title'] = $val;
$tab_list[$key]['href'] = U('index', array('status' => $key));
}
// 使用Builder快速建立列表页面。
$builder = new \Qscmf\Builder\ListBuilder();
$builder = $builder->setMetaTitle('菜单管理') // 设置页面标题
->addTopButton('addnew'); // 添加新增按钮
switch($status){
case DBCont::NORMAL_STATUS;
$builder = $builder->addTopButton('forbid'); // 添加禁用按钮
break;
case DBCont::FORBIDDEN_STATUS;
$builder = $builder->addTopButton('resume'); // 添加启用按钮
break;
default:
break;
}
$builder->addTopButton('delete') // 添加删除按钮
->addTopButton('save')
->setNID(24)
->setTabNav($tab_list, $status) // 设置页面Tab导航
->addTableColumn('id', 'ID')
->addTableColumn('title', '菜单名')
->addTableColumn('sort', '排序', '', '', true)
->addTableColumn('type', '分类')
->addTableColumn('right_button', '操作', 'btn')
->setTableDataList($data_list) // 数据列表
->setTableDataPage($page->show()) // 数据列表分页
->addRightButton('edit') // 添加编辑按钮
->addRightButton('forbid') // 添加禁用/启用按钮
->addRightButton('delete') // 添加删除按钮
->display();
}
public function add(){
if (IS_POST) {
parent::autoCheckToken();
$data = I('post.');
if($data['pid'] == 0){
$data['level'] = 1;
}
else{
$p_data = D('Menu')->find($data['pid']);
$data['level'] = $p_data['level'] + 1;
}
$menu_model = D('Menu');
$r = $menu_model->createAdd($data);
if($r === false){
$this->error($menu_model->getError());
}
$menu_ent = D('menu')->find($r);
sysLogs('新增菜单:' . $menu_ent['title']);
$this->success(l('add') . l('success'), U(CONTROLLER_NAME . '/index'));
}
else {
// 使用FormBuilder快速建立表单页面。
$menu_model = new \Common\Model\MenuModel();
// $map['status'] = DBCont::NORMAL_STATUS;
// $menu_list = $menu_model->where($map)->getField('id,title');
$menu_list = $menu_model->getParentOptions("id","title");
$builder = new \Qscmf\Builder\FormBuilder();
$builder->setMetaTitle('新增菜单') //设置页面标题
->setNID(24)
->setPostUrl(U('add')) //设置表单提交地址
->addFormItem('title', 'text', '标题')
->addFormItem('sort', 'text', '排序')
->addFormItem('icon', 'text', 'icon')
->addFormItem('type', 'text', '类型')
->addFormItem('url', 'text', 'url')
->addFormItem('pid', 'select', '父菜单', '', $menu_list)
->addFormItem('module', 'text', '绑定模块')
->addFormItem('status', 'select', '状态', '', DBCont::getStatusList())
->display();
}
}
public function edit($id){
if (IS_POST) {
parent::autoCheckToken();
$data = I('post.');
if(empty($data['pid'])){
$data['pid'] = 0;
}
if($data['pid'] == 0){
$data['level'] = 1;
}
else{
$p_data = D('Menu')->find($data['pid']);
$data['level'] = $p_data['level'] + 1;
}
$menu_model = D('Menu');
$r = $menu_model->createSave($data);
if($r === false){
$this->error($menu_model->getError());
}
sysLogs('修改菜单id:' . $data['id']);
$this->success('修改成功', U(CONTROLLER_NAME . '/index'));
} else {
$menu_ent = D('Menu')->where(array('status' => DBCont::NORMAL_STATUS, 'id' => $id))->find();
if(!$menu_ent){
E('菜单不存在');
}
// $map['status'] = DBCont::NORMAL_STATUS;
// $map['id'] = array('neq', $id);
// $menu_list = D('Menu')->where($map)->getField('id,title');
$menu_list = D('Menu')->getParentOptions("id","title", $id);
// 使用FormBuilder快速建立表单页面。
$builder = new \Qscmf\Builder\FormBuilder();
$builder->setMetaTitle('编辑菜单') // 设置页面标题
->setNID(24)
->setPostUrl(U('edit')) //设置表单提交地址
->addFormItem('id', 'hidden', 'ID')
->addFormItem('title', 'text', '标题')
->addFormItem('sort', 'text', '排序')
->addFormItem('icon', 'text', 'icon')
->addFormItem('type', 'text', '类型')
->addFormItem('url', 'text', 'url')
->addFormItem('pid', 'select', '父菜单', '', $menu_list)
->addFormItem('module', 'text', '绑定模块')
->addFormItem('status', 'select', '状态', '', DBCont::getStatusList())
->setFormData($menu_ent)
->display();
}
}
public function forbid(){
$ids = I('ids');
if(!$ids){
$this->error('请选择要禁用的数据');
}
$r = parent::_forbid($ids);
if($r !== false){
sysLogs('菜单 id: ' . $ids . ' 禁用');
$this->success('禁用成功', U(CONTROLLER_NAME . '/index'));
}
else{
$this->error($this->_getError());
}
}
public function save(){
if(IS_POST){
$data = I('post.');
foreach($data['id'] as $k=>$v){
$save_data['sort'] = $data['sort'][$k]; D('Menu')->where('id=' . $v)->save($save_data);
}
$this->success('保存成功', U('index'));
}
}
public function resume(){
$ids = I('ids');
if(!$ids){
$this->error('请选择要启用的数据');
}
$r = parent::_resume($ids);
if($r !== false){
sysLogs('菜单 id: ' . $ids . ' 启用');
$this->success('启用成功', U(CONTROLLER_NAME . '/index'));
}
else{
$this->error($this->_getError());
}
}
public function delete(){
$ids = I('ids');
if(!$ids){
$this->error('请选择要删除的数据');
}
$r = parent::_del($ids);
if($r === false){
$this->error($this->_getError());
}
else{
sysLogs('菜单 id: ' . $ids . ' 删除');
$this->success('删除成功', U(MODULE_NAME . '/' . CONTROLLER_NAME . '/index'));
}
}
}

View File

@ -0,0 +1,215 @@
<?php
namespace Admin\Controller;
use Common\Model\MenuModel;
use Gy_Library\DBCont;
use Gy_Library\GyListController;
use Qscmf\Builder\FormBuilder;
use Qscmf\Builder\ListBuilder;
//新闻分类
class NewsCateController extends GyListController
{
public function index()
{
$map = [];
$get_data = I('get.');
if (isset($get_data['key']) && $get_data['word']) {
$map[$get_data['key']] = array('like', '%' . $get_data['word'] . '%');
}
$model = D('NewsCate');
$count = $model->getListForCount($map);
$per_page = C('ADMIN_PER_PAGE_NUM', null, false);
if ($per_page === false) {
$page = new \Gy_Library\GyPage($count);
} else {
$page = new \Gy_Library\GyPage($count, $per_page);
}
$data_list = $model->getListForPage($map, $page->nowPage, $page->listRows, 'sort asc,id asc');
//时间戳的转换
foreach ($data_list as &$value) {
$value['create_date'] = date('Y-m-d H:i:s', $value['create_date']);
}
// 使用Builder快速建立列表页面。
$builder = new ListBuilder();
$builder = $builder->setMetaTitle('分类管理'); // 设置页面标题
$builder->addTopButton('addnew');
$builder->addTopButton('save', array('title' => '保存排序'));
$builder
->setNIDByNode(MODULE_NAME, CONTROLLER_NAME, 'index')
->addSearchItem('name', 'select_text', '单行输入', array('name' => '名称'))
->addTableColumn('name', '分类名称')
->addTableColumn('sort', '排序', '', '', true)
->addTableColumn('status', '状态', 'status', '', false)
->addTableColumn('right_button', '操作', 'btn')
->setTableDataList($data_list) // 数据列表
->setTableDataPage($page->show()) // 数据列表分页
->addRightButton('edit') // 添加编辑按钮
->addRightButton('delete') // 添加删除按钮
->addRightButton('forbid') // 添加禁用按钮
->display();
}
public function add()
{
if (IS_POST) {
parent::autoCheckToken();
$data = I('post.');
$model = D('NewsCate');
$data['name'] = trim($data['name']);
$r = $model->createAdd($data);
if ($r === false) {
$this->error($model->getError());
} else {
// sysLogs('新增内容id:' . $r);
$this->success(l('add') . l('success'), U(CONTROLLER_NAME . '/index'));
}
} else {
// 使用FormBuilder快速建立表单页面。
$menu_model = new MenuModel();
$menu_list = $menu_model->getMenuListGroupByType();
$this->assign('menu_list_json', json_encode($menu_list));
$builder = new FormBuilder();
$data_list = array(
"status" => 1,
);
if ($data_list) {
$builder->setFormData($data_list);
}
$builder->setMetaTitle('添加分类管理') //设置页面标题
->setNIDByNode(MODULE_NAME, CONTROLLER_NAME, 'index')
->setPostUrl(U('add')) //设置表单提交地址
->addFormItem('name', 'text', '分类名称')
->addFormItem('sort', 'num', '排序')
->addFormItem('status', 'select', '状态', '', DBCont::getStatusList())
->display();
}
}
public function save()
{
if (IS_POST) {
$data = I('post.');
foreach ($data['id'] as $k => $v) {
$save_data['sort'] = $data['sort'][$k];
D('NewsCate')->where('id=' . $v)->save($save_data);
}
$this->success('保存成功', U('index'));
}
}
public function edit($id)
{
if (IS_POST) {
parent::autoCheckToken();
$m_id = I('post.id');
$data = I('post.');
$data['name'] = trim($data['name']);
$model = D('NewsCate');
if (!$m_id) {
E('缺少内容ID');
}
$ent = $model->getOne($m_id);
if (!$ent) {
E('不存在内容');
}
$ent['name'] = $data['name'];
$ent['sort'] = $data['sort'];
$ent['status'] = $data['status'];
if ($model->createSave($ent) === false) {
$this->error($model->getError());
} else {
$this->success('修改成功', U('index'));
}
} else {
$info = D('NewsCate')->getOne($id);
$builder = new FormBuilder();
$builder->setMetaTitle('编辑分类管理')
->setPostUrl(U('edit'))
// ->setExtraHtml($this->fetch('NewsCate/detail'))
->setNIDByNode(MODULE_NAME, CONTROLLER_NAME, 'index')
->addFormItem('id', 'hidden', 'ID')
->addFormItem('name', 'text', '分类名称')
->addFormItem('sort', 'num', '排序')
->addFormItem('status', 'select', '状态', '', DBCont::getStatusList())
->setFormData($info)
->display();
}
}
public function forbid()
{
$ids = I('ids');
if (!$ids) {
$this->error('请选择要禁用的数据');
}
$r = parent::_forbid($ids);
if ($r !== false) {
// sysLogs('新闻分类id: ' . $ids . ' 禁用');
$this->success('禁用成功', U(CONTROLLER_NAME . '/index'));
} else {
$this->error($this->_getError());
}
}
public function resume()
{
$ids = I('ids');
if (!$ids) {
$this->error('请选择要启用的数据');
}
$r = parent::_resume($ids);
if ($r !== false) {
$this->success('启用成功', U(CONTROLLER_NAME . '/index'));
} else {
$this->error($this->_getError());
}
}
public function delete()
{
$ids = I('ids');
$map['_string'] = "FIND_IN_SET({$ids},cate_id)";
if (D('News')->where($map)->count('id')) {
$this->error('请先删除该分组下的数据');
}
if (!$ids) {
$this->error('请选择要删除的数据');
}
$r = parent::_del($ids);
if ($r === false) {
$this->error($this->_getError());
} else {
$this->success('删除成功', U(MODULE_NAME . '/' . CONTROLLER_NAME . '/index'));
}
}
public function extractNumberGetName($strs, $countarr)
{
$patterns = "/\d+/";
$str = '';
preg_match_all($patterns, $strs, $arr);
$i = 0;
foreach ($arr[0] as $key => $value) {
if ($i == 0) {
$str .= $countarr[$value];
} else {
$str .= '、' . $countarr[$value];
}
$i++;
}
return $str;
}
}

View File

@ -0,0 +1,413 @@
<?php
namespace Admin\Controller;
use Common\Model\MenuModel;
use Gy_Library\DBCont;
use Gy_Library\GyListController;
use ExportExcelByXlsx;
use Qscmf\Builder\FormBuilder;
use Qscmf\Builder\ListBuilder;
use Qscmf\Builder\TSubBuilder;
//新闻
class NewsController extends GyListController
{
use TSubBuilder;
public function index()
{
$this->_filter($map);
$model = D('News');
$count = $model->getListForCount($map);
$per_page = C('ADMIN_PER_PAGE_NUM', null, false);
if ($per_page === false) {
$page = new \Gy_Library\GyPage($count);
} else {
$page = new \Gy_Library\GyPage($count, $per_page);
}
$get_data = I('get.');
$topic_id = $get_data['topic_id'];
$order = 'sort asc,start_date desc,id desc';
if (!empty($get_data['click_time']) && $get_data['click_time'] === 'asc') {
$order = 'click_time asc,sort asc,start_date desc';
} elseif (!empty($get_data['click_time']) && $get_data['click_time'] === 'desc') {
$order = 'click_time desc,sort asc,start_date desc';
}
$data_list = $model->getListForPage($map, $page->nowPage, $page->listRows, $order);
//时间戳的转换
foreach ($data_list as &$value) {
$value['title'] = cutLength($value['title'], 20);
$value['author'] = cutLength($value['author'], 10);
$value['in_date'] = date('Y-m-d', $value['in_date']);
$value['start_date'] = date('Y-m-d', $value['start_date']);
$value['cate_name'] = $model->extractNumberGetName($value['cate_id'], D('NewsCate')->where(['status' => DBCont::YES_BOOL_STATUS])->order('sort asc,id desc')->getField('id,name', true));
$value['keywords'] = cutLength($model->extractNumberGetNameForCondition($value['keywords_id'], 'Keywords', 'id', 'name'), 25);
}
// 使用Builder快速建立列表页面。
$builder = new ListBuilder();
if (!empty($topic_id)) {
$builder->addTopButton('self', array('title' => '勾选提交', 'class' => 'btn btn-success ajax-post confirm', 'href' => U('chooseNews', ['topic_id' => $topic_id])));
if ($topic_id === 'month') {
$builder->addTopButton('self', array('title' => '返回', 'class' => 'btn btn-info', 'href' => U('Month/index')))
->setMetaTitle('请勾选月榜所需新闻')->setSearchUrl(U('', ['topic_id' => $topic_id]))
->setNIDByNode(MODULE_NAME, 'Month', 'index');
} elseif ($topic_id === 'season') {
$builder->addTopButton('self', array('title' => '返回', 'class' => 'btn btn-info', 'href' => U('Season/index')))
->setMetaTitle('请勾选季度榜所需新闻')->setSearchUrl(U('', ['topic_id' => $topic_id]))
->setNIDByNode(MODULE_NAME, 'Season', 'index');
} else {
$builder->addTopButton('self', array('title' => '返回', 'class' => 'btn btn-info', 'href' => U('TopicFromNews/index', ['topic_id' => $topic_id])))
->setMetaTitle('请勾选榜所需新闻')->setSearchUrl(U('', ['topic_id' => $topic_id]))
->setNIDByNode(MODULE_NAME, 'Topic', 'index');
}
} else {
$builder->addTopButton('addnew');
$builder->addTopButton('save', array('title' => '保存排序'))
->addTopButton('export', ['title' => '导出新闻列表', 'data-url' => U('export'), 'data-filename' => "新闻列表", 'data-streamrownum' => "500"])
->addTopButton('forbid')
->addTopButton('resume')
->setExtraHtml($this->fetch('News/index_extra'))
->setNIDByNode(MODULE_NAME, CONTROLLER_NAME, 'index');
$builder = $builder->setMetaTitle('内容管理'); // 设置页面标题
}
$builder
->addSearchItem('click_time', 'select', '点击量排序', array('asc' => '点击量正序', 'desc' => '点击量倒序'))
->addSearchItem('cate_id', 'select', '所属分类', D('NewsCate')->where(['status' => DBCont::YES_BOOL_STATUS])->getField('id,name', true))
->addSearchItem('title', 'select_text', '单行输入', array('title' => '标题', 'author' => '作者', 'keyword' => '关键词'))
->addTableColumn('title', '标题')
->addTableColumn('cate_name', '所属分类')
->addTableColumn('keywords', '关键词')
->addTableColumn('author', '作者')
// ->addTableColumn('start_date', '首发时间')
->addTableColumn('click_time', '点击量');
if (empty($topic_id)) {
$builder->addTableColumn('sort', '排序', '', '', true);
}
$builder->addTableColumn('status', '状态', 'status', '', false);
if (empty($topic_id)) {
$builder->addTableColumn('right_button', '操作', 'btn');
}
$builder
->setTableDataList($data_list) // 数据列表
->setTableDataPage($page->show()) // 数据列表分页
->addRightButton('edit', array('href' => U('edit', ['page' => I('get.page'), 'id' => '__data_id__']), 'data-id' => '__data_id__')) // 添加编辑按钮
->addRightButton('delete') // 添加删除按钮
->addRightButton('forbid') // 添加禁用按钮
->display();
}
public function add()
{
if (IS_POST) {
parent::autoCheckToken();
$data = I('post.');
$data['in_date'] = !empty($data['in_date']) ? $data['in_date'] : date('Y-m-d', time());
$data['start_date'] = !empty($data['start_date']) ? $data['start_date'] : date('Y-m-d', time());
$data['content_res'] = strip_tags(htmlspecialchars_decode($data['content']));
$keyword_ids = D('Keywords')->checkKeywords($data['keywords_id'] ? $data['keywords_id'] : []);
if ($keyword_ids === false) {
$this->error(D('Keywords')->getError());
}
$data['keywords_id'] = implode(',', $keyword_ids ? $keyword_ids : []);
$data['cate_id'] = implode(',', $data['cate_id'] ? $data['cate_id'] : []);
$model = D('News');
$r = $model->createAdd($data);
if ($r === false) {
$this->error($model->getError());
} else {
// sysLogs('新增内容id:' . $r);
$this->success(l('add') . l('success'), U(CONTROLLER_NAME . '/index'));
}
} else {
// 使用FormBuilder快速建立表单页面。
$builder = new FormBuilder();
$data_list = array(
"status" => 1,
);
if ($data_list) {
$builder->setFormData($data_list);
}
$subBuilder = new \Qscmf\Builder\SubTableBuilder();
$subBuilder = $subBuilder->addTableHeader('关键词', '30%', '输入关键词可以搜索添加现有关键词,输入@+关键词可以新增')
->addFormItem('keywords_id', 'select2', [
'tags' => true,
'options' => D('Keywords')->order('id desc')->getField('id, name', true),
]);
$builder->setMetaTitle('添加内容') //设置页面标题
->setNIDByNode(MODULE_NAME, CONTROLLER_NAME, 'index')
->setPostUrl(U('add')) //设置表单提交地址
->addFormItem('title', 'text', '*标题')
->addFormItem('cate_id', 'checkbox', '*选择文章分类', '', D('NewsCate')->getField('id,name', true))
->addFormItem('cover_id', 'picture', '*封面图', '尺寸为240*135px,格式JPG、PNG、JPEG')
->addFormItem('author', 'text', '*作者')
->addFormItem('keywords_id', 'self', '关键词', '', $subBuilder->makeHtml())
->addFormItem('sort', 'num', '排序')
->addFormItem('status', 'select', '状态', '', DBCont::getStatusList())
->addFormItem('in_date', 'date', '入库时间')
->addFormItem('start_date', 'date', '首发时间')
->addFormItem('url', 'text', '原文链接')
->addFormItem('recommendation', 'textarea', '*入库推荐语')
->addFormItem('content', 'ueditor', '内容详情')
->display();
}
}
public function save()
{
if (IS_POST) {
$data = I('post.');
foreach ($data['id'] as $k => $v) {
$save_data['sort'] = $data['sort'][$k];
D('News')->where('id=' . $v)->save($save_data);
}
$this->success('保存成功', U('index'));
}
}
public function export()
{
$this->_filter($map);
$ids = I('get.ids');
if (!empty($ids)) {
$map['id'] = ['in', $ids];
}
$page = I('get.page');
$rownum = I('get.rownum');
$excel_list = D('News')->getExportList($map, $page, $rownum);
$this->ajaxReturn($excel_list);
}
private function _filter(&$map)
{
$map = [];
$get_data = I('get.');
if (isset($get_data['key']) && $get_data['word'] && $get_data['key'] !== 'keyword') {
$map[$get_data['key']] = array('like', '%' . $get_data['word'] . '%');
}
if (!empty($get_data['word']) && $get_data['key'] === 'cate_name') {
$map1['name'] = array('like', '%' . $get_data['word'] . '%');
$map['cate_id'] = D('NewsCate')->where($map1)->getField('id');
}
if (!empty($get_data['cate_id'])) {
$map['_string'] = "FIND_IN_SET({$get_data['cate_id']},cate_id)";
}
if (!empty($get_data['word']) && $get_data['key'] === 'keyword') {
$map1['name'] = array('like', '%' . $get_data['word'] . '%');
$keywords_ids = D('Keywords')->where($map1)->getField('id', true);
$r = '';
foreach ($keywords_ids as $k => $ent) {
if (empty($k)) {
$r = "(,{$ent},)";
} else {
$r .= "|(,{$ent},)";
}
}
if ($keywords_ids) {
$map['_string'] && $map['_string'] .= " AND keywords_id REGEXP '{$r}'";
!$map['_string'] && $map['_string'] = "keywords_id REGEXP '{$r}'";
} else {
$map['_string'] = '1=0';
}
}
$topic_id = $get_data['topic_id'];
if (!empty($topic_id) && $topic_id === 'month') {
$news_id = D('Month')->where(['status' => DBCont::YES_BOOL_STATUS])->getField('news_id', true);
} elseif (!empty($topic_id) && $topic_id === 'season') {
$news_id = D('Season')->where(['status' => DBCont::YES_BOOL_STATUS])->getField('news_id', true);
} elseif (!empty($topic_id)) {
$news_id = D('TopicFromNews')->where(['topic_id' => $topic_id, 'status' => DBCont::YES_BOOL_STATUS])->getField('news_id', true);
}
if (!empty($news_id)) {
$map['id'] = ['NOT IN', $news_id];
}
}
public function edit($id)
{
if (IS_POST) {
parent::autoCheckToken();
$m_id = I('post.id');
$data = I('post.');
$keyword_ids = D('Keywords')->checkKeywords($data['keywords_id'] ? $data['keywords_id'] : []);
if ($keyword_ids === false) {
$this->error(D('Keywords')->getError());
}
$data['keywords_id'] = implode(',', $keyword_ids ? $keyword_ids : []);
$data['cate_id'] = implode(',', $data['cate_id'] ? $data['cate_id'] : []);
$data['content_res'] = strip_tags(htmlspecialchars_decode($data['content']));
$model = D('News');
if (!$m_id) {
E('缺少内容ID');
}
$ent = $model->getOne($m_id);
if (!$ent) {
E('不存在内容');
}
$ent['title'] = $data['title'];
$ent['cate_id'] = $data['cate_id'];
$ent['cover_id'] = $data['cover_id'];
$ent['author'] = $data['author'];
$ent['content'] = $data['content'];
$ent['content_res'] = $data['content_res'];
$ent['keywords_id'] = $data['keywords_id'];
$ent['sort'] = $data['sort'];
$ent['status'] = $data['status'];
$ent['in_date'] = $data['in_date'];
$ent['start_date'] = $data['start_date'];
$ent['url'] = $data['url'];
$ent['recommendation'] = $data['recommendation'];
if ($model->createSave($ent) === false) {
$this->error($model->getError());
} else {
$this->success('修改成功', U('index', ['page' => $data['page']]));
}
} else {
$info = D('News')->getOne($id);
$builder = new FormBuilder();
$info['page'] = !empty(I('get.page')) ? I('get.page') : 1;
$info['keywords_id'] = explode(',', $info['keywords_id']);
$subBuilder = new \Qscmf\Builder\SubTableBuilder();
$subBuilder->setData(D('Keywords')->genKeywordId($info['keywords_id']));
$subBuilder->addTableHeader('关键词', '30%', '输入关键词可以搜索添加现有关键词,输入@+关键词可以新增');
$subBuilder->addFormItem('keywords_id', 'select2', [
'tags' => true,
'options' => D('Keywords')->order('id desc')->getField('id, name', true)
]);
$builder->setMetaTitle('编辑' . $info['title'])
->setPostUrl(U('edit'))
// ->setExtraHtml($this->fetch('News/detail'))
->setNIDByNode(MODULE_NAME, CONTROLLER_NAME, 'index')
->addFormItem('id', 'hidden', 'ID')
->addFormItem('page', 'hidden', 'PAGE', '', $info['page'])
->addFormItem('title', 'text', '*标题')
->addFormItem('cate_id', 'checkbox', '*选择文章分类', '', D('NewsCate')->getField('id,name', true))
// ->addFormItem('cover_id', 'picture_intercept', '封面图','尺寸为750*450px,格式JPG、PNG、JPEG', ['width' => 750, 'height' => 450])
->addFormItem('cover_id', 'picture', '*封面图', '尺寸为240*135px,格式JPG、PNG、JPEG')
// ->addFormItem('content', 'ueditor', '内容详情','',$this->toolbars(), '', 'data-forcecatchremote="true"')
->addFormItem('author', 'text', '*作者')
->addFormItem('keywords_id', 'self', '关键词', '', $subBuilder->makeHtml())
// ->addFormItem('keywords_id', 'tags', '关键词','',$keyword_options)
->addFormItem('sort', 'num', '排序')
->addFormItem('status', 'select', '状态', '', DBCont::getStatusList())
->addFormItem('in_date', 'date', '入库时间')
->addFormItem('start_date', 'date', '首发时间')
->addFormItem('url', 'text', '原文链接')
->addFormItem('recommendation', 'textarea', '*入库推荐语')
->addFormItem('content', 'ueditor', '内容详情')
->setFormData($info)
->display();
}
}
public function forbid()
{
$ids = I('ids');
if (!$ids) {
$this->error('请选择要禁用的数据');
}
$r = parent::_forbid($ids);
if ($r !== false) {
D('TopicFromNews')->where(['news_id' => ['in', $ids]])->setField('status', DBCont::NO_BOOL_STATUS);
// sysLogs('新闻分类id: ' . $ids . ' 禁用');
$this->success('禁用成功', U(CONTROLLER_NAME . '/index'));
} else {
$this->error($this->_getError());
}
}
public function resume()
{
$ids = I('ids');
if (!$ids) {
$this->error('请选择要启用的数据');
}
$r = parent::_resume($ids);
if ($r !== false) {
D('TopicFromNews')->where(['news_id' => ['in', $ids]])->setField('status', DBCont::YES_BOOL_STATUS);
$this->success('启用成功', U(CONTROLLER_NAME . '/index'));
} else {
$this->error($this->_getError());
}
}
public function delete()
{
$ids = I('ids');
if (!$ids) {
$this->error('请选择要删除的数据');
}
$r = parent::_del($ids);
$tf_ids = D('TopicFromNews')->where(['news_id' => ['in', $ids]])->getField('id', true);
D('TopicFromNews')->del($tf_ids);
$m_ids = D('Month')->where(['news_id' => ['in', $ids]])->getField('id', true);
D('Month')->del($m_ids);
$s_ids = D('Season')->where(['news_id' => ['in', $ids]])->getField('id', true);
D('Season')->del($s_ids);
if ($r === false) {
$this->error($this->_getError());
} else {
$this->success('删除成功', U(MODULE_NAME . '/' . CONTROLLER_NAME . '/index'));
}
}
public function toolbars()
{
return [
'toolbars' => [
[
'undo', 'redo',
'bold', 'italic', 'underline', 'fontborder', 'strikethrough', 'superscript', 'subscript', 'removeformat', 'formatmatch', 'autotypeset', 'blockquote', 'pasteplain', '|', 'forecolor', 'backcolor', 'insertorderedlist', 'insertunorderedlist', 'selectall', 'cleardoc', '|',
'rowspacingtop', 'rowspacingbottom', 'lineheight', '|',
'customstyle', 'paragraph', 'fontfamily', 'fontsize', '|',
'indent', '|', 'justifyleft', 'justifycenter', 'justifyright', 'justifyjustify', '|',
'link', 'unlink', 'anchor', '|', 'imagenone', 'imageleft', 'imageright', 'imagecenter', '|',
'simpleupload', 'insertimage', '|', 'horizontal', 'spechars', 'wordimage', '|',
'inserttable', 'deletetable', 'insertparagraphbeforetable', 'insertrow', 'deleterow', 'insertcol', 'deletecol', 'mergecells', 'mergeright', 'mergedown', 'splittocells', 'splittorows', 'splittocols', 'charts',
'|', 'fullscreen', 'source', '|', 'attachment'
]
]
];
}
public function chooseNews($topic_id)
{
$ids = I('ids');
if (!$ids) {
$this->error('请选择要勾选的新闻');
}
if ($topic_id === 'month') {
$r = D('Month')->addNews($ids);
if ($r === false) {
$this->error(D('Month')->getError());
} else {
$this->success('添加月榜成功', U('Month/index'));
}
} elseif ($topic_id === 'season') {
$r = D('Season')->addNews($ids);
if ($r === false) {
$this->error(D('Season')->getError());
} else {
$this->success('添加季度榜成功', U('Season/index'));
}
} else {
$r = D('TopicFromNews')->addNews($topic_id, $ids);
if ($r === false) {
$this->error(D('TopicFromNews')->getError());
} else {
$this->success('添加成功', U('TopicFromNews/index', ['topic_id' => $topic_id]));
}
}
}
}

View File

@ -0,0 +1,382 @@
<?php
namespace Admin\Controller;
use Gy_Library\GyListController;
use Gy_Library\DBCont;
class NodeController extends GyListController {
public function index($status = DBCont::NORMAL_STATUS, $level = DBCont::LEVEL_ACTION){
// 搜索
$keyword = I('keyword', '', 'string');
if(!empty($keyword)){
$node_ent = D('Node')->getByName($keyword);
$map['pid'] = $node_ent['id'];
}
$get_data = I('get.');
if(isset($get_data['key']) && $get_data['word']){
switch($get_data['key']){
case 'controller':
$s_map['level'] = DBCont::LEVEL_CONTROLLER;
$s_map['name'] = $get_data['word'];
$s_map['status'] = DBCont::NORMAL_STATUS;
$pids = D('Node')->where($s_map)->getField('id', true);
$map['pid'] = array('in', $pids);
break;
default:
$map[$get_data['key']] = array('like', '%' . $get_data['word'] . '%');
break;
}
}
$map['level'] = $level;
$map['status'] = $status;
$node_model = D('Node');
$count = $node_model->getListForCount($map);
$per_page = C('ADMIN_PER_PAGE_NUM', null, false);
if($per_page === false){
$page = new \Gy_Library\GyPage($count);
}
else{
$page = new \Gy_Library\GyPage($count, $per_page);
}
$data_list = $node_model->getListForPage($map, $page->nowPage, $page->listRows, 'id desc');
foreach($data_list as &$v){
$menu_ent = D('Menu')->getOne($v['menu_id']);
$v['menu'] = $menu_ent['title'];
$controller_ent = D('Node')->getOne($v['pid']);
$v['controller'] = $controller_ent['name'];
$module_ent = D('Node')->getOne($controller_ent['pid']);
$v['module'] = $module_ent['name'];
}
// 设置Tab导航数据列表
$status_list = DBCont::getStatusList();
foreach ($status_list as $key => $val) {
$tab_list[$key]['title'] = $val;
$tab_list[$key]['href'] = U('index', array('status' => $key));
}
// 使用Builder快速建立列表页面。
$builder = new \Qscmf\Builder\ListBuilder();
$builder = $builder->setMetaTitle('节点管理') // 设置页面标题
->addTopButton('addnew') // 添加新增按钮
->addTopButton('self', array('title' => '权限点检查', 'href' => U('authCheck')));
switch($status){
case DBCont::NORMAL_STATUS;
$builder = $builder->addTopButton('forbid'); // 添加禁用按钮
break;
case DBCont::FORBIDDEN_STATUS;
$builder = $builder->addTopButton('resume'); // 添加启用按钮
break;
default:
break;
}
$builder->addTopButton('delete') // 添加删除按钮
->addSearchItem('', 'select_text', '搜索内容', array('name'=>'节点名称', 'controller' => '控制器', 'title' => '节点标题'))
->setNID(28)
->setTabNav($tab_list, $status) // 设置页面Tab导航
->addTableColumn('id', 'ID')
->addTableColumn('name', '节点名称')
->addTableColumn('title', '节点标题')
->addTableColumn('sort', '排序')
->addTableColumn('menu', '菜单')
->addTableColumn('controller', '控制器')
->addTableColumn('module', '模块')
->addTableColumn('right_button', '操作', 'btn')
->setTableDataList($data_list) // 数据列表
->setTableDataPage($page->show()) // 数据列表分页
->addRightButton('edit') // 添加编辑按钮
->addRightButton('forbid') // 添加禁用/启用按钮
->addRightButton('delete') // 添加删除按钮
->display();
}
public function add(){
if (IS_POST) {
parent::autoCheckToken();
$data = I('post.');
$pid = $this->_handleController();
$data['pid'] = $pid;
$data['level'] = DBCont::LEVEL_ACTION;
$node_model = D('Node');
if(!$node_model->create($data)){
$this->error($node_model->getError());
}
$r = $node_model->add();
if($r !== false){
sysLogs('新增节点ID:' . $r);
$this->success(l('add') . l('success'), U(CONTROLLER_NAME . '/index'));
}
else{
$this->error($node_model->getError());
}
}
else {
// 使用FormBuilder快速建立表单页面。
$menu_model = new \Common\Model\MenuModel();
$menu_list = $menu_model->getMenuListGroupByType();
$this->assign('menu_list_json', json_encode($menu_list));
$builder = new \Qscmf\Builder\FormBuilder();
$data_list = array(
"status"=>1, );
if($data_list){
$builder->setFormData($data_list);
}
$builder->setMetaTitle('新增节点') //设置页面标题
->setNID(28)
->setPostUrl(U('add')) //设置表单提交地址
->addFormItem('name', 'text', '名称')
->addFormItem('title', 'text', '标题')
->addFormItem('sort', 'text', '排序')
->addFormItem('icon', 'text', 'icon')
->addFormItem('remark', 'text', '备注')
->addFormItem('controller', 'text', '控制器')
->addFormItem('module', 'text', '模块')
->addFormItem('menu_type', 'select', '菜单类型', '', array(), '', 'id=cmbType')
->addFormItem('menu_id', 'select', '菜单', '', array(), '', 'id=cmbMenu')
->addFormItem('status', 'select', '状态', '', DBCont::getStatusList())
->setExtraHtml($this->fetch('Node/add_script'))
->display();
}
}
public function edit($id){
if (IS_POST) {
parent::autoCheckToken();
$data = I('post.');
$node_model = new \Common\Model\NodeModel();
$node_ent = $node_model->getOne($data['id']);
$data = array_merge($node_ent, $data);
$pid = $this->_handleController();
$data['pid'] = $pid;
if(!$node_model->create($data)){
$this->error($node_model->getError());
}
$r = $node_model->edit();
if($r !== false){
sysLogs('修改节点ID:' . $data['post.id']);
$this->success('修改成功', U(CONTROLLER_NAME . '/index'));
}
else{
$this->error($node_model->getError());
}
} else {
$node_ent = D('Node')->getOne($id);
$controller_ent = D('Node')->getOne($node_ent['pid']);
$module_ent = D('Node')->getOne($controller_ent['pid']);
$node_ent['controller'] = $controller_ent['name'];
$node_ent['module'] = $module_ent['name'];
$menu_model = new \Common\Model\MenuModel();
$cur_menu = $menu_model->find($node_ent['menu_id']);
$menu_list = $menu_model->getMenuListGroupByType();
$this->assign('menu_list_json', json_encode($menu_list));
$this->assign('cur_menu', $cur_menu);
// 使用FormBuilder快速建立表单页面。
$builder = new \Qscmf\Builder\FormBuilder();
$builder->setMetaTitle('编辑用户') // 设置页面标题
->setNID(28)
->setPostUrl(U('edit')) //设置表单提交地址
->addFormItem('id', 'hidden', 'ID')
->addFormItem('name', 'text', '名称')
->addFormItem('title', 'text', '标题')
->addFormItem('sort', 'text', '排序')
->addFormItem('icon', 'text', 'icon')
->addFormItem('remark', 'text', '备注')
->addFormItem('controller', 'text', '控制器')
->addFormItem('module', 'text', '模块')
->addFormItem('menu_type', 'select', '菜单类型', '', array(), '', 'id=cmbType')
->addFormItem('menu_id', 'select', '菜单', '', array(), '', 'id=cmbMenu')
->addFormItem('status', 'select', '状态', '', DBCont::getStatusList())
->setFormData($node_ent)
->setExtraHtml($this->fetch('Node/edit_script'))
->display();
}
}
public function forbid(){
$ids = I('ids');
if(!$ids){
$this->error('请选择要禁用的数据');
}
$r = parent::_forbid($ids);
if($r !== false){
sysLogs('Node id: ' . $ids . ' 禁用');
$this->success('禁用成功', U(CONTROLLER_NAME . '/index'));
}
else{
$this->error($this->_getError());
}
}
public function resume(){
$ids = I('ids');
if(!$ids){
$this->error('请选择要启用的数据');
}
$r = parent::_resume($ids);
if($r !== false){
sysLogs('Node id: ' . $ids . ' 启用');
$this->success('启用成功', U(CONTROLLER_NAME . '/index'));
}
else{
$this->error($this->_getError());
}
}
public function delete(){
$ids = I('ids');
if(!$ids){
$this->error('请选择要删除的数据');
}
$r = parent::_del($ids);
if($r === false){
$this->error($this->_getError());
}
else{
sysLogs('Node id: ' . $ids . ' 删除');
$this->success('删除成功', U(MODULE_NAME . '/' . CONTROLLER_NAME . '/index'));
}
}
private function _handleController(){
//控制器必填
if(!I('post.controller')){
$this->error('控制器不能为空');
}
$controller = I('post.controller');
if(!isEnglish($controller)){
$this->error('必须填写英文');
}
$node = new \Common\Model\NodeModel();
$controller_map = array();
$controller_map['name'] = $controller;
$controller_map['level'] = DBCont::LEVEL_CONTROLLER;
$controller_node = $node->getNode($controller_map);
if(!$controller_node){
//控制器不存在,自动完成代码添加,并检查模块,如没有也一并添加
//检查是否有输入模块名
if(!I('post.module')){
$this->error('新建控制器时,必须填写模块名!');
}
$module = I('post.module');
if(!isEnglish($module)){
$this->error('必须填写英文');
}
$module_map = array();
$module_map['name'] = $module;
$module_map['level'] = DBCont::LEVEL_MODULE;
$module_node = $node->getNode($module_map);
if(!$module_node){
//模块不存在,自动创建模块代码
$module_node['id'] = $this->_insertModule($module);
}
$controller_node['id'] = $this->_insertController($module, $module_node['id'], $controller);
}
return $controller_node['id'];
}
private function _insertModule($module){
//GyBuild::buildAppDir(ucfirst($module));
$node = new \Common\Model\NodeModel();
$module_node = array();
$module_node['name'] = $module;
$module_node['title'] = $module;
$module_node['status'] = DBCont::NORMAL_STATUS;
$module_node['pid'] = 0;
$module_node['level'] = DBCont::LEVEL_MODULE;
if(!$node->create($module_node)){
$this->error($node->getError());
}
$module_node['id'] = $node->add();
if(!$module_node['id']){
$this->error($node->getError());
}
else{
return $module_node['id'];
}
}
private function _insertController($module, $module_id, $controller){
//GyBuild::buildController(ucfirst($module), ucfirst($controller));
$node = new \Common\Model\NodeModel();
$controller_node = array();
$controller_node['name'] = $controller;
$controller_node['title'] = $controller;
$controller_node['status'] = DBCont::NORMAL_STATUS;
$controller_node['pid'] = $module_id;
$controller_node['level'] = DBCont::LEVEL_CONTROLLER;
if(!$node->create($controller_node)){
$this->error($node->getError());
}
$controller_node['id'] = $node->add();
if(!$controller_node['id']){
$this->error($node->getError());
}
else{
return $controller_node['id'];
}
}
public function authCheck(){
if(IS_POST){
$check_module = I('post.module');
$this->assign('check_module', $check_module);
}
$module_list = D('Node')->getModuleList();
$this->assign('module_list', $module_list);
$this->display();
}
}

View File

@ -0,0 +1,197 @@
<?php
namespace Admin\Controller;
use Gy_Library\GyListController;
use Gy_Library\DBCont;
use Qscmf\Lib\Cms\CateHelperTrait;
//自动生成代码
class PostCateController extends GyListController{
use CateHelperTrait;
protected $option = [
5 => [
'hidden' => [
'pid','type','introduction','img_id','cover_id','pic_id','summary','sort'
]
],
1 => [
'show' => ['cover_id', 'introduction']
],
6=> [
'except_self' => true,
'show' => ['summary'],
'hidden' => ['introduction'],
]
];
public function index(){
$get_data = I('get.');
$map = array();
if(isset($get_data['status'])){
$map['status'] = $get_data['status'];
}
if(isset($get_data['key']) && $get_data['word']){
$map[$get_data['key']] = array('like', '%' . $get_data['word'] . '%');
} $model = D('PostCate');
$data_list = $model->getList($map, 'sort asc');
$tree = list_to_tree($data_list);
$data_list = genSelectByTree($tree);
foreach($data_list as $k=>$v){
$title_prefix = str_repeat("&nbsp;", $v['level']*4);
$title_prefix .= empty($title_prefix) ? '' : "";
$v["name"] = $title_prefix . $v["name"];
$data_list[$k] = $v;
}
$builder = new \Qscmf\Builder\ListBuilder();
$builder = $builder->setMetaTitle('分类管理')
->addSearchItem('status', 'select', '所有状态', DBCont::getStatusList()) ->addSearchItem('', 'select_text', '搜索内容', array('name'=>'分类'))
->addTopButton('addnew')
->addTopButton('forbid')
->addTopButton('resume')
->addTopButton('delete');
$builder->addTopButton('save', array('title' => '保存排序'));
$builder->setNID(933)
->addTableColumn('name', '分类', '', '', false)->addTableColumn('sort', '排序', '', '', true)->addTableColumn('status', '状态', 'status', '', false) ->addTableColumn('right_button', '操作', 'btn')
->setTableDataList($data_list)
->addRightButton('edit')
->addRightButton('forbid')
->addRightButton('delete')
->display();
}
public function save(){
if(IS_POST){
$data = I('post.');
foreach($data['id'] as $k=>$v){
$save_data['sort'] = $data['sort'][$k]; D('PostCate')->where('id=' . $v)->save($save_data);
}
$this->success('保存成功', U('index'));
}
}
public function add(){
if (IS_POST) {
parent::autoCheckToken();
$data = I('post.');
$model = D('PostCate');
$r = $model->createAdd($data);
if($r === false){
$this->error($model->getError());
}
else{
sysLogs('新增分类id:' . $r);
$this->success(l('add') . l('success'), U(CONTROLLER_NAME . '/index'));
}
}
else {
$builder = new \Qscmf\Builder\FormBuilder();
$data_list = array(
"status"=>1, );
if($data_list){
$builder->setFormData($data_list);
}
$builder->setMetaTitle('新增分类')
->setNID(933)
->setPostUrl(U('add'))
->addFormItem('name', 'text', '分类','', '')->addFormItem('pid', 'select', '上级分类','', D("PostCate")->getParentOptions("id","name",$id))->addFormItem('summary', 'textarea', '摘要','', '')->addFormItem('cover_id', 'picture', '分类封面','', '')->addFormItem('sort', 'num', '排序','', '')->addFormItem('url', 'text', 'url','', '')->addFormItem('content', 'ueditor', '分类详情','', '')->addFormItem('status', 'select', '状态','', DBCont::getStatusList()) ->display();
}
}
public function edit($id){
if (IS_POST) {
parent::autoCheckToken();
$m_id = I('post.id');
$data = I('post.');
$model = D('PostCate');
if(!$m_id){
E('缺少分类ID');
}
$ent = $model->getOne($m_id);
if(!$ent){
E('不存在分类');
}
$ent['name'] = $data['name'];$ent['pid'] = $data['pid'];$ent['summary'] = $data['summary'];$ent['cover_id'] = $data['cover_id'];$ent['sort'] = $data['sort'];$ent['url'] = $data['url'];$ent['content'] = $data['content'];$ent['status'] = $data['status'];
if($model->createSave($ent) === false){
$this->error($model->getError());
}
else{
sysLogs('修改分类id:' . $m_id);
$this->success('修改成功', U('index'));
}
} else {
$info = D('PostCate')->getOne($id);
$builder = new \Qscmf\Builder\FormBuilder();
$builder->setMetaTitle('编辑分类')
->setPostUrl(U('edit'))
->setNID(933)
->addFormItem('id', 'hidden', 'ID')
->addFormItem('name', 'text', '分类', '', '')->addFormItem('pid', 'select', '上级分类', '', D("PostCate")->getParentOptions("id","name",$id))->addFormItem('summary', 'textarea', '摘要', '', '')->addFormItem('cover_id', 'picture', '分类封面', '', '')->addFormItem('sort', 'num', '排序', '', '')->addFormItem('url', 'text', 'url', '', '')->addFormItem('content', 'ueditor', '分类详情', '', '')->addFormItem('status', 'select', '状态', '', DBCont::getStatusList()) ->setFormData($info)
->setFormItemFilter($this->formItemFilter($this->option))
->display();
}
}
public function forbid(){
$ids = I('ids');
if(!$ids){
$this->error('请选择要禁用的数据');
}
$r = parent::_forbid($ids);
if($r !== false){
sysLogs('分类id: ' . $ids . ' 禁用');
$this->success('禁用成功', U(CONTROLLER_NAME . '/index'));
}
else{
$this->error($this->_getError());
}
}
public function resume(){
$ids = I('ids');
if(!$ids){
$this->error('请选择要启用的数据');
}
$r = parent::_resume($ids);
if($r !== false){
sysLogs('分类id: ' . $ids . ' 启用');
$this->success('启用成功', U(CONTROLLER_NAME . '/index'));
}
else{
$this->error($this->_getError());
}
}
public function delete(){
$ids = I('ids');
if(!$ids){
$this->error('请选择要删除的数据');
}
$r = parent::_del($ids);
if($r === false){
$this->error($this->_getError());
}
else{
sysLogs('分类id: ' . $ids . ' 删除');
$this->success('删除成功', U(MODULE_NAME . '/' . CONTROLLER_NAME . '/index'));
}
}
}

View File

@ -0,0 +1,214 @@
<?php
namespace Admin\Controller;
use Gy_Library\GyListController;
use Gy_Library\DBCont;
use Qscmf\Lib\Cms\ContentHelperTrait;
//自动生成代码
class PostController extends GyListController{
use ContentHelperTrait;
protected $content_option = [
6 => [
'hidden' => ['author'],
],
7 => [
'hidden' => ['author','source']
],
8 => [
'hidden' => ['author','source', 'summary', 'url']
]
];
public function index(){
$get_data = I('get.');
$map = array();
if(isset($get_data['cate_id'])){
$map['cate_id'] = $get_data['cate_id'];
}if(isset($get_data['status'])){
$map['status'] = $get_data['status'];
}
if(isset($get_data['key']) && $get_data['word']){
$map[$get_data['key']] = array('like', '%' . $get_data['word'] . '%');
} $model = D('Post');
$count = $model->getListForCount($map);
$per_page = C('ADMIN_PER_PAGE_NUM', null, false);
if($per_page === false){
$page = new \Gy_Library\GyPage($count);
}
else{
$page = new \Gy_Library\GyPage($count, $per_page);
}
$data_list = $model->getListForPage($map, $page->nowPage, $page->listRows, 'sort asc');
$builder = new \Qscmf\Builder\ListBuilder();
$builder = $builder->setMetaTitle('内容管理')
->addSearchItem('cate_id', 'select', '所有分类', D("PostCate")->getParentOptions("id","name"))->addSearchItem('status', 'select', '所有状态', DBCont::getStatusList()) ->addSearchItem('', 'select_text', '搜索内容', array('title'=>'标题'))
->addTopButton('addnew')
->addTopButton('forbid')
->addTopButton('resume')
->addTopButton('delete');
$builder->addTopButton('save', array('title' => '保存排序'));
$builder->setNID(969)
->addTableColumn('title', '标题', '', '', false)
->addTableColumn('cate_id', '所属分类', 'fun', 'D("PostCate")->getOneField(__data_id__,"name")', false)->addTableColumn('sort', '排序', '', '', true)->addTableColumn('publish_date', '发布时间', 'fun', 'date("Y-m-d",__data_id__)', false)->addTableColumn('status', '状态', 'status', '', false) ->addTableColumn('right_button', '操作', 'btn')
->setTableDataList($data_list)
->setTableDataPage($page->show())
->addRightButton('edit')
->addRightButton('forbid')
->addRightButton('delete')
->display();
}
public function save(){
if(IS_POST){
$data = I('post.');
foreach($data['id'] as $k=>$v){
$save_data['sort'] = $data['sort'][$k]; D('Post')->where('id=' . $v)->save($save_data);
}
$this->success('保存成功', U('index'));
}
}
public function add(){
if (IS_POST) {
parent::autoCheckToken();
$data = I('post.');
$model = D('Post');
$r = $model->createAdd($data);
if($r === false){
$this->error($model->getError());
}
else{
sysLogs('新增内容id:' . $r);
$this->success(l('add') . l('success'), U(CONTROLLER_NAME . '/index'));
}
}
else {
$builder = new \Qscmf\Builder\FormBuilder();
$data_list = array(
"status"=>1,
"publish_date" => time()
);
if($data_list){
$builder->setFormData($data_list);
}
$builder->setMetaTitle('新增内容')
->setNID(969)
->setPostUrl(U('add'))
->addFormItem('title', 'text', '标题','', '')
->addFormItem('english_name', 'text', '英文标题','', '')
->addFormItem('cate_id', 'select', '所属分类','', D("PostCate")->getParentOptions("id","name"))->addFormItem('summary', 'textarea', '摘要','', '')->addFormItem('cover_id', 'picture', '封面','', '')->addFormItem('sort', 'num', '排序','', '')->addFormItem('publish_date', 'date', '发布时间','', '')->addFormItem('author', 'text', '作者','', '')->addFormItem('url', 'text', 'url','', '')->addFormItem('content', 'ueditor', '正文内容','', '')->addFormItem('video', 'text', '视频','添加优酷视频分享代码,请使用通用代码', '')->addFormItem('images', 'pictures', '图片','', '')->addFormItem('attach', 'files', '附件','', '')->addFormItem('status', 'select', '状态','', DBCont::getStatusList())
->addFormItem('up','radio','置顶','', DBCont::getBoolStatusList())
->display();
}
}
public function edit($id){
if (IS_POST) {
parent::autoCheckToken();
$m_id = I('post.id');
$data = I('post.');
$model = D('Post');
if(!$m_id){
E('缺少内容ID');
}
$ent = $model->getOne($m_id);
if(!$ent){
E('不存在内容');
}
$ent['up'] = $data['up'];
$ent['title'] = $data['title'];
$ent['cate_id'] = $data['cate_id'];
$ent['summary'] = $data['summary'];
$ent['cover_id'] = $data['cover_id'];
$ent['sort'] = $data['sort'];
$ent['english_name'] = $data['english_name'];
$ent['publish_date'] = $data['publish_date'];
$ent['author'] = $data['author'];$ent['url'] = $data['url'];$ent['content'] = $data['content'];$ent['video'] = $data['video'];$ent['images'] = $data['images'];$ent['attach'] = $data['attach'];$ent['status'] = $data['status'];
if($model->createSave($ent) === false){
$this->error($model->getError());
}
else{
sysLogs('修改内容id:' . $m_id);
$this->success('修改成功', U('index'));
}
} else {
$info = D('Post')->getOne($id);
$builder = new \Qscmf\Builder\FormBuilder();
$builder->setMetaTitle('编辑内容')
->setPostUrl(U('edit'))
->setNID(969)
->addFormItem('id', 'hidden', 'ID')
->addFormItem('title', 'text', '标题', '', '')
->addFormItem('english_name', 'text', '英文标题','', '')
->addFormItem('cate_id', 'select', '所属分类', '', D("PostCate")->getParentOptions("id","name"))->addFormItem('summary', 'textarea', '摘要', '', '')->addFormItem('cover_id', 'picture', '封面', '', '')->addFormItem('sort', 'num', '排序', '', '')->addFormItem('publish_date', 'date', '发布时间', '', '')->addFormItem('author', 'text', '作者', '', '')->addFormItem('url', 'text', 'url', '', '')->addFormItem('content', 'ueditor', '正文内容', '', '')->addFormItem('video', 'text', '视频','添加优酷视频分享代码,请使用通用代码', '')->addFormItem('images', 'pictures', '图片', '', '')->addFormItem('attach', 'files', '附件', '', '')->addFormItem('status', 'select', '状态', '', DBCont::getStatusList())
->addFormItem('up','radio','置顶','', DBCont::getBoolStatusList())
->setFormData($info)
->setFormItemFilter($this->formItemFilter($this->content_option))
->display();
}
}
public function forbid(){
$ids = I('ids');
if(!$ids){
$this->error('请选择要禁用的数据');
}
$r = parent::_forbid($ids);
if($r !== false){
sysLogs('内容id: ' . $ids . ' 禁用');
$this->success('禁用成功', U(CONTROLLER_NAME . '/index'));
}
else{
$this->error($this->_getError());
}
}
public function resume(){
$ids = I('ids');
if(!$ids){
$this->error('请选择要启用的数据');
}
$r = parent::_resume($ids);
if($r !== false){
sysLogs('内容id: ' . $ids . ' 启用');
$this->success('启用成功', U(CONTROLLER_NAME . '/index'));
}
else{
$this->error($this->_getError());
}
}
public function delete(){
$ids = I('ids');
if(!$ids){
$this->error('请选择要删除的数据');
}
$r = parent::_del($ids);
if($r === false){
$this->error($this->_getError());
}
else{
sysLogs('内容id: ' . $ids . ' 删除');
$this->success('删除成功', U(MODULE_NAME . '/' . CONTROLLER_NAME . '/index'));
}
}
}

View File

@ -0,0 +1,271 @@
<?php
namespace Admin\Controller;
use Common\Model\MenuModel;
use Gy_Library\DBCont;
use Gy_Library\GyListController;
use Qscmf\Builder\FormBuilder;
use Qscmf\Builder\ListBuilder;
//公益广告
class PublicAdvertisementController extends GyListController
{
public function index()
{
$map = [];
$get_data = I('get.');
if (isset($get_data['key']) && $get_data['word']) {
$map[$get_data['key']] = array('like', '%' . $get_data['word'] . '%');
}
$model = D('PublicAdvertisement');
$count = $model->getListForCount($map);
$per_page = C('ADMIN_PER_PAGE_NUM', null, false);
if ($per_page === false) {
$page = new \Gy_Library\GyPage($count);
} else {
$page = new \Gy_Library\GyPage($count, $per_page);
}
$data_list = $model->getListForPage($map, $page->nowPage, $page->listRows, 'sort asc,id desc');
//时间戳的转换
foreach ($data_list as &$value) {
$value['create_date'] = date('Y-m-d H:i:s', $value['create_date']);
}
// 使用Builder快速建立列表页面。
$builder = new ListBuilder();
$builder = $builder->setMetaTitle('公益广告');// 设置页面标题
$builder->addTopButton('addnew');
$builder->addTopButton('save', array('title' => '保存排序'));
$builder
->setNIDByNode(MODULE_NAME, CONTROLLER_NAME, 'index')
->addSearchItem('title', 'select_text', '单行输入', array('name' => '标题'))
->addTableColumn('title', '标题')
->addTableColumn('sort', '排序','','',true)
->addTableColumn('status', '状态', 'status', '', false)
->addTableColumn('right_button', '操作', 'btn')
->setTableDataList($data_list)// 数据列表
->setTableDataPage($page->show())// 数据列表分页
->addRightButton('edit')// 添加编辑按钮
->addRightButton('delete')// 添加删除按钮
->addRightButton('forbid')// 添加禁用按钮
->display();
}
public function add()
{
if (IS_POST) {
parent::autoCheckToken();
$data = I('post.');
$model = D('PublicAdvertisement');
$r = $model->createAdd($data);
if ($r === false) {
$this->error($model->getError());
} else {
// sysLogs('新增内容id:' . $r);
$this->success(l('add') . l('success'), U(CONTROLLER_NAME . '/index'));
}
} else {
// 使用FormBuilder快速建立表单页面。
$menu_model = new MenuModel();
$menu_list = $menu_model->getMenuListGroupByType();
$this->assign('menu_list_json', json_encode($menu_list));
$builder = new FormBuilder();
$data_list = array(
"status" => 1,
);
if ($data_list) {
$builder->setFormData($data_list);
}
$builder->setMetaTitle('添加公益广告')//设置页面标题
->setNIDByNode(MODULE_NAME, CONTROLLER_NAME, 'index')
->setPostUrl(U('add'))//设置表单提交地址
->addFormItem('title', 'text', '*标题')
->addFormItem('cover_id', 'picture', '*轮播图','尺寸为334*188px,格式JPG、PNG、JPEG')
->addFormItem('url', 'text', '链接地址' ,'地址请以https://或http://开头(非必填,如不填则不跳转)')
->addFormItem('sort', 'num', '排序')
->addFormItem('status', 'select', '状态', '', DBCont::getStatusList())
->display();
}
}
public function save(){
if(IS_POST){
$data = I('post.');
foreach($data['id'] as $k=>$v){
$save_data['sort'] = $data['sort'][$k];
D('PublicAdvertisement')->where('id=' . $v)->save($save_data);
}
$this->success('保存成功', U('index'));
}
}
public function edit($id)
{
if (IS_POST) {
parent::autoCheckToken();
$m_id = I('post.id');
$data = I('post.');
$model = D('PublicAdvertisement');
if (!$m_id) {
E('缺少内容ID');
}
$ent = $model->getOne($m_id);
if (!$ent) {
E('不存在内容');
}
$ent['title'] = $data['title'];
$ent['cover_id'] = $data['cover_id'];
$ent['url'] = $data['url'];
$ent['sort'] = $data['sort'];
$ent['status'] = $data['status'];
// $ent['status'] = $data['status'];
if ($model->createSave($ent) === false) {
$this->error($model->getError());
} else {
$this->success('修改成功', U('index'));
}
} else {
$info = D('PublicAdvertisement')->getOne($id);
$builder = new FormBuilder();
$builder->setMetaTitle('编辑公益广告'.$info['name'])
->setPostUrl(U('edit'))
// ->setExtraHtml($this->fetch('PublicAdvertisement/detail'))
->setNIDByNode(MODULE_NAME, CONTROLLER_NAME, 'index')
->addFormItem('id', 'hidden', 'ID')
->addFormItem('title', 'text', '*标题')
->addFormItem('cover_id', 'picture', '*轮播图','尺寸为334*188px,格式JPG、PNG、JPEG')
->addFormItem('url', 'text', '链接地址' ,'地址请以https://或http://开头(非必填,如不填则不跳转)')
->addFormItem('sort', 'num', '排序')
->addFormItem('status', 'select', '状态', '', DBCont::getStatusList())
->setFormData($info)
->display();
}
}
public function forbid()
{
$ids = I('ids');
if (!$ids) {
$this->error('请选择要禁用的数据');
}
$r = parent::_forbid($ids);
if ($r !== false) {
// sysLogs('新闻分类id: ' . $ids . ' 禁用');
$this->success('禁用成功', U(CONTROLLER_NAME . '/index'));
} else {
$this->error($this->_getError());
}
}
public function resume()
{
$ids = I('ids');
if (!$ids) {
$this->error('请选择要启用的数据');
}
$r = parent::_resume($ids);
if ($r !== false) {
$this->success('启用成功', U(CONTROLLER_NAME . '/index'));
} else {
$this->error($this->_getError());
}
}
public function delete()
{
$ids = I('ids');
if (!$ids) {
$this->error('请选择要删除的数据');
}
$r = parent::_del($ids);
if ($r === false) {
$this->error($this->_getError());
} else {
$this->success('删除成功', U(MODULE_NAME . '/' . CONTROLLER_NAME . '/index'));
}
}
public function extractNumberGetName($strs, $countarr)
{
$patterns = "/\d+/";
$str = '';
preg_match_all($patterns, $strs, $arr);
$i = 0;
foreach ($arr[0] as $key => $value) {
if ($i == 0) {
$str .= $countarr[$value];
} else {
$str .= '、' . $countarr[$value];
}
$i++;
}
return $str;
}
public function toolbars()
{
return ['toolbars' => [
[
'undo', 'redo',
'bold', 'italic', 'underline', 'fontborder', 'strikethrough', 'superscript', 'subscript', 'removeformat', 'formatmatch', 'autotypeset', 'blockquote', 'pasteplain', '|', 'forecolor', 'backcolor', 'insertorderedlist', 'insertunorderedlist', 'selectall', 'cleardoc', '|',
'rowspacingtop', 'rowspacingbottom', 'lineheight', '|',
'customstyle', 'paragraph', 'fontfamily', 'fontsize', '|',
'indent', '|', 'justifyleft', 'justifycenter', 'justifyright', 'justifyjustify', '|',
'link', 'unlink', 'anchor', '|', 'imagenone', 'imageleft', 'imageright', 'imagecenter', '|',
'simpleupload', 'insertimage', '|', 'horizontal', 'spechars', 'wordimage', '|',
'inserttable', 'deletetable', 'insertparagraphbeforetable', 'insertrow', 'deleterow', 'insertcol', 'deletecol', 'mergecells', 'mergeright', 'mergedown', 'splittocells', 'splittorows', 'splittocols', 'charts',
'|', 'fullscreen', 'source', '|', 'attachment'
]
]
];
}
}

View File

@ -0,0 +1,138 @@
<?php
namespace Admin\Controller;
use Think\Controller;
class PublicController extends Controller {
private $_error;
public function getError(){
return $this->_error;
}
//生成验证码图片
public function verify($length=4,$imageW=290,$imageH=90,$fontSize=40) {
$verify = new \Think\Verify();
//规定验证码的长度和宽度
$verify->length = $length;
$verify->imageW = $imageW;
$verify->imageH = $imageH;
$verify->fontSize = $fontSize;
$verify->entry();
}
//验证验证码是否正确
public function checkVerify($code, $id = '') {
$verify = new \Think\Verify();
return $verify->check($code, $id);
}
//后台登录
public function login() {
// \Think\Log::write('login 分析');
// \Think\Log::write(json_encode($_SERVER));
// \Think\Log::write('login 分析');
if(IS_POST){
$r = $this->adminLogin(I('post.uid'), I('post.pwd'));
if($r === false){
$this->error($this->getError(), U('Public/login'), array('verify_show'=> isShowVerify()));
}
else{
$this->success(l('login success'), U('Dashboard/index'));
}
}
else{
if (!isAdminLogin()) {
//是否显示验证码
if (isShowVerify()) {
$this->assign('verify_show', true);
}
$this->display();
} else {
$this->redirect('Dashboard/index');
}
}
}
//后台退出
public function logout() {
if (isAdminLogin()) {
cleanRbacKey();
\Qscmf\Core\AuthChain::cleanAuthFilterKey();
session(C('ADMIN_AUTH_KEY'), null);
session(C('USER_AUTH_KEY'), null);
session('ADMIN_LOGIN', null);
sysLogs('后台登出');
}
$this->redirect('Public/login');
}
//后台登录检测
public function adminLogin($uid, $pwd) {
if (isShowVerify()) {
//如果有验证码 则验证
$verify = I('post.verify');
if (!$this->checkVerify($verify)) {
$this->loginErr(l('verify_code_error'));
return false;
}
}
$user_model = D('User');
$user_ent = $user_model->getUserByEmailOrNickName($uid);
$r = $user_model->adminLogin($uid, $user_model->hashPwd($pwd, $user_ent['salt']));
if ($r === false) {
$this->loginErr($user_model->getError());
return false;
}
return true;
}
//$third_login 第三方登录标记
public function homeLogin($uid, $pwd, $third_login = false){
//第三方登录不需验证码
if (!$third_login && isShowVerify()) {
//如果有验证码 则验证
$verify = I('post.verify');
if (!$this->checkVerify($verify)) {
$this->loginErr(l('verify_code_error'));
return false;
}
}
$user_model = D('User');
$user_ent = $user_model->getUserByEmailOrNickName($uid);
$r = $user_model->homeLogin($uid, $user_model->hashPwd($pwd, $user_ent['salt']), $third_login);
if ($r === false) {
$this->loginErr($user_model->getError());
return false;
}
return true;
}
//登录错误处理函数
private function loginErr($msg) {
loginFail();
$this->_error = $msg;
//$this->error($msg, U('login'));
}
}

View File

@ -0,0 +1,104 @@
<?php
namespace Admin\Controller;
use Gy_Library\GyListController;
use Qscmf\Lib\DBCont;
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
class QueueController extends GyListController {
public function index(){
$get_data = I('get.');
$map = array();
if(isset($get_data['schedule'])){
$map['schedule'] = $get_data['schedule'];
}
if(isset($get_data['status'])){
$map['status'] = $get_data['status'];
}
if(isset($get_data['key']) && $get_data['word']){
$map[$get_data['key']] = array('like', '%' . $get_data['word'] . '%');
} $model = D('Queue');
$count = $model->getListForCount($map);
$per_page = C('ADMIN_PER_PAGE_NUM', null, false);
if($per_page === false){
$page = new \Gy_Library\GyPage($count);
}
else{
$page = new \Gy_Library\GyPage($count, $per_page);
}
$data_list = $model->getListForPage($map, $page->nowPage, $page->listRows, 'create_date desc');
foreach($data_list as &$v){
if($v['status'] != DBCont::JOB_STATUS_COMPLETE){
$model->refreshStatusOne($v['id']);
}
if($v['status'] == DBCont::JOB_STATUS_FAILED || $v['status'] == DBCont::JOB_STATUS_RUNNING){
$v['show_reset'] = 1;
}
if($v['schedule']){
$v['schedule'] = '是';
}
else{
$v['schedule'] = '否';
}
}
$builder = new \Qscmf\Builder\ListBuilder();
$builder = $builder->setMetaTitle('队列任务')->setCheckBox(false)
->addSearchItem('schedule', 'select', '是否计划任务', DBCont::getBoolStatusList())
->addSearchItem('status', 'select', '所有状态', DBCont::getJobStatusList())->addSearchItem('', 'select_text', '搜索内容', array('description'=>'描述'));
$builder->addTopButton('self', array('title' => '重启全部失败任务', 'href' => U('rebuildAllFail'), 'class' => 'btn btn-primary ajax-get confirm'))
->addTopButton('self', array('title' => '刷新所有等待', 'href' => U('refreshWait'), 'class' => 'btn btn-primary ajax-get confirm'));
$builder->setNIDByNode()
->addTableColumn('id', 'Job_id', '', '', false)
->addTableColumn('job', 'job','','', false)
->addTableColumn('description', '说明', '', '', false)->addTableColumn('status', '状态', 'fun', 'Qscmf\Lib\DBCont::getJobStatus(__data_id__)', false)
->addTableColumn('schedule', '计划任务', '', '', false)
->addTableColumn('create_date', '创建时间', 'fun', 'date("Y-m-d H:i:s", __data_id__)')
->addTableColumn('right_button', '操作', 'btn')
->setTableDataList($data_list)
->setTableDataPage($page->show())
->addRightButton('self', array('title' => '重启任务', 'href' => U('/admin/queue/rebuild', array('id' => '__data_id__')), 'class' => 'label label-success ajax-get confirm', '{key}' => 'show_reset', '{condition}' => 'eq', '{value}' => '1'))
->display();
}
public function refreshWait(){
$map['status'] = DBCont::JOB_STATUS_WAITING;
$data_list = D('Queue')->getList($map);
foreach($data_list as $data){
D('Queue')->refreshStatusOne($data['id']);
}
$this->success("刷新完毕", U('admin/queue/index'));
}
public function rebuild(){
$job_id = I('get.id');
$r = D('Queue')->rebuildJobOne($job_id);
if($r === false){
$this->error(D("Queue")->getError());
}
else{
$this->success("重启成功", U('admin/queue/index'));
}
}
public function rebuildAllFail(){
$map['status'] = DBCont::JOB_STATUS_FAILED;
$queue_list = D('Queue')->where($map)->select();
foreach($queue_list as $q){
D('Queue')->rebuildJobOne($q['id']);
}
$this->success('重启完毕', U('admin/queue/index'));
}
}

View File

@ -0,0 +1,242 @@
<?php
namespace Admin\Controller;
use Gy_Library\GyListController;
use Gy_Library\DBCont;
class RoleController extends GyListController {
public function index(){
$keyword = I('keyword', '', 'string');
$condition = array('like','%'.$keyword.'%');
$map['name'] = $condition;
$role_model = D('Role');
$count = $role_model->getListForCount($map);
$per_page = C('ADMIN_PER_PAGE_NUM', null, false);
if($per_page === false){
$page = new \Gy_Library\GyPage($count);
}
else{
$page = new \Gy_Library\GyPage($count, $per_page);
}
$data_list = $role_model->getListForPage($map, $page->nowPage, $page->listRows, 'status desc, id desc');
// 使用Builder快速建立列表页面。
$builder = new \Qscmf\Builder\ListBuilder();
$builder = $builder->setMetaTitle('用户组列表') // 设置页面标题
->addTopButton('addnew') // 添加新增按钮
->addTopButton('delete') // 添加删除按钮
// ->setSearch(
// '名称',
// U('index')
// )
->setNID(36)
->addTableColumn('id', 'ID')
->addTableColumn('name', '名称')
->addTableColumn('status', '状态', "status")
->addTableColumn('remark', '备注')
->addTableColumn('right_button', '操作', 'btn')
->setTableDataList($data_list) // 数据列表
->setTableDataPage($page->show()) // 数据列表分页
->addRightButton('edit') // 添加编辑按钮
->addRightButton('forbid') // 添加禁用/启用按钮
->addRightButton('delete') // 添加删除按钮
->display();
}
private function _genAccessList(){
$node = new \Common\Model\NodeModel();
$map['level'] = DBCont::LEVEL_MODULE;
$map['status'] = DBCont::NORMAL_STATUS;
$module_list = $node->getNodeList($map);
$map = array();
$map['level'] = DBCont::LEVEL_CONTROLLER;
$map['status'] = DBCont::NORMAL_STATUS;
$controller_list = $node->getNodeList($map);
$map = array();
$map['level'] = DBCont::LEVEL_ACTION;
$map['status'] = DBCont::NORMAL_STATUS;
$action_list = $node->getNodeList($map);
$this->assign('action_list', $action_list);
$this->assign('module_list', $module_list);
$this->assign('controller_list', $controller_list);
}
private function _createAccessList($role_id){
$auth = I('post.auth');
$access = new \Common\Model\AccessModel();
$map['role_id'] = $role_id;
$r = $access->delAccess($map);
if($r === false){
$this->error('删除数据时出错');
}
$node = new \Common\Model\NodeModel();
$node_arr = array();
$access_arr = array();
foreach($auth as $v){
$access_arr = $this->getParentNode($v, $role_id, $node_arr);
}
if(!empty($access_arr)){
$r = $access->addAll($access_arr);
if($r === false){
$this->error($access->getError());
}
}
}
//组装要插入gy_access的数组
private function getParentNode($node_id, $role_id, &$node_arr){
static $data_arr = array();
$node = new \Common\Model\NodeModel();
$map['id'] = $node_id;
$data = $node->getNode($map);
if(!in_array($data['id'], $node_arr)){
$data_arr[] = array('role_id' => $role_id, 'node_id' => $data['id'], 'level' => $data['level'], 'module' => $data['name']);
$node_arr[] = $data['id'];
}
if($data['pid'] != 0){
$this->getParentNode($data['pid'], $role_id, $node_arr);
}
return $data_arr;
}
public function add(){
//重复提交处理
parent::autoCheckToken();
if(!empty($_POST)){
if($data == ''){
$data = I('post.');
}
$model = D($this->dbname);
if(!$model->create($data)){
$this->error($model->getError());
}
$r = $model->add();
if($r !== false){
$this->_createAccessList($r);
sysLogs('新增用户组id: ' . $r);
$this->success(l('add') . l('success'), U(CONTROLLER_NAME . '/index'));
}
else{
$this->error($model->getError());
}
}
else{
$this->_genAccessList();
$this->display();
}
}
public function edit($id){
parent::autoCheckToken();
if(!empty($_POST)){
$data = I('post.');
$model = D($this->dbname);
if(!$model->create($data)){
$this->error($model->getError());
}
$r = $model->edit();
if($r !== false){
$this->_createAccessList($id);
sysLogs('修改用户组id: ' . $id);
$this->success('修改成功', U(CONTROLLER_NAME . '/index'));
}
else{
$this->error($model->getError());
}
}
else{
$model = D($this->dbname);
$vo = $model->find($id);
if(empty($vo)){
$this->error('数据不存在');
}
$this->_genAccessList();
$access = new \Common\Model\AccessModel();
$map['role_id'] = $vo['id'];
$map['level'] = DBCont::LEVEL_ACTION;
$access_list = $access->getAccessList($map);
foreach($access_list as $v){
$vo['auth'][] = $v['node_id'];
}
$this->assign('vo', $vo);
$this->display();
}
}
public function forbid(){
$ids = I('ids');
if(!$ids){
$this->error('请选择要禁用的数据');
}
$r = parent::_forbid($ids);
if($r !== false){
sysLogs('用户组id: ' . $ids . ' 禁用');
$this->success('禁用成功', U(CONTROLLER_NAME . '/index'));
}
else{
$this->error($this->_getError());
}
}
public function resume(){
$ids = I('ids');
if(!$ids){
$this->error('请选择要启用的数据');
}
$r = parent::_resume($ids);
if($r !== false){
sysLogs('用户组id: ' . $ids . ' 启用');
$this->success('启用成功', U(CONTROLLER_NAME . '/index'));
}
else{
$this->error($this->_getError());
}
}
public function delete(){
$ids = I('ids');
if(!$ids){
$this->error('请选择要删除的数据');
}
$r = parent::_del($ids);
if($r === false){
$this->error($this->_getError());
}
else{
sysLogs('用户组id: ' . $ids . ' 删除');
$this->success('删除成功', U(MODULE_NAME . '/' . CONTROLLER_NAME . '/index'));
}
}
}

View File

@ -0,0 +1,300 @@
<?php
namespace Admin\Controller;
use Gy_Library\GyListController;
use Gy_Library\DBCont;
use Qscmf\Builder\FormBuilder;
use Qscmf\Builder\ListBuilder;
use Qscmf\Builder\TSubBuilder;
/*
* 关键词
*/
class SecondaryTitleController extends GyListController
{
use TSubBuilder;
private $belong_to = ['报道媒体', '报道类型'];
public function index()
{
$map = [];
$get_data = I('get.');
if (isset($get_data['key']) && $get_data['word']) {
$map[$get_data['key']] = array('like', '%' . $get_data['word'] . '%');
}
$model = D('SecondaryTitle');
$count = $model->getListForCount($map);
$per_page = C('ADMIN_PER_PAGE_NUM', null, false);
if ($per_page === false) {
$page = new \Gy_Library\GyPage($count);
} else {
$page = new \Gy_Library\GyPage($count, $per_page);
}
$order = 'sort asc,id desc';
$data_list = $model->getListForPage($map, $page->nowPage, $page->listRows, $order);
foreach ($data_list as &$data) {
$s_news = $model->getConditionList($data['id']);
if ($s_news) {
$data['news'] = empty(trim($s_news['news_id'])) ? "" : "" . count(explode(',', $s_news['news_id'])) . "";
$data['keywords'] = cutLength($model->extraKeyword($s_news['keywords_id']), 25);
$data['cates'] = cutLength($model->extraCate($s_news['cate_id']), 25);
}
}
// 使用Builder快速建立列表页面。
$builder = new ListBuilder();
$builder = $builder->setMetaTitle('搜索关键词管理'); // 设置页面标题
$builder->addTopButton('addnew');
// $builder->addTopButton('save', array('title' => '保存排序'));
$builder
->setNIDByNode(MODULE_NAME, CONTROLLER_NAME, 'index')
->addSearchItem('title', 'select_text', '单行输入', array('name' => '名称'))
->addTableColumn('belong_to', '选项')
->addTableColumn('name', '名称')
->addTableColumn('news', '新闻列表')
->addTableColumn('keywords', '关键词列表')
->addTableColumn('cates', '分类列表')
->addTableColumn('sort', '排序', '', '', false)
->addTableColumn('status', '状态', 'status', '', false)
->addTableColumn('right_button', '操作', 'btn')
->setTableDataList($data_list) // 数据列表
->setTableDataPage($page->show()) // 数据列表分页
->addRightButton('edit') // 添加编辑按钮
->addRightButton('delete') // 添加删除按钮
->addRightButton('forbid') // 添加禁用按钮
// ->addRightButton('self', ['title' => '查看相关文章', 'href' => U('News/index', ['key' => 'keyword', 'word' => '__name__']), 'class' => 'label label-success'])
->display();
}
public function add()
{
if (IS_POST) {
parent::autoCheckToken();
$data = I('post.');
$data['name'] = trim($data['name']);
$data['belong_to'] = $this->belong_to[$data['belong_to']];
$model = D('SecondaryTitle');
$n_model = D('SecondaryNews');
$keyword_ids = D('Keywords')->checkKeywords($data['keywords_id'] ? $data['keywords_id'] : []);
if ($keyword_ids === false) {
$this->error(D('Keywords')->getError());
}
$data['keywords_id'] = implode(',', $keyword_ids ? $keyword_ids : []);
$data['news_id'] = implode(',', $data['news_id'] ? $data['news_id'] : []);
$data['cate_id'] = implode(',', $data['cate_id'] ? $data['cate_id'] : []);
$r = $model->createAdd($data);
if ($r === false) {
$this->error($model->getError());
} else {
$data['secondary_id'] = $r;
$n_r = $n_model->createAdd($data);
if ($n_r === false) {
$this->error($n_model->getError());
}
sysLogs('新增关键词id:' . $r);
$this->success(l('add') . l('success'), U(CONTROLLER_NAME . '/index'));
}
} else {
// 使用FormBuilder快速建立表单页面。
$builder = new FormBuilder();
$data_list = array(
"status" => 1,
"sort" => 0,
);
if ($data_list) {
$builder->setFormData($data_list);
}
$keywordBuilder = new \Qscmf\Builder\SubTableBuilder();
$keywordBuilder->addTableHeader('关键词', '30%', '输入关键词可以搜索添加现有关键词,输入@+关键词可以新增');
$keywordBuilder->addFormItem('keywords_id', 'select2', [
'tags' => true,
'options' => D('Keywords')->order('id desc')->getField('id, name', true)
]);
$newsBuilder = new \Qscmf\Builder\SubTableBuilder();
$newsBuilder->addTableHeader('新闻列表', '30%', '输入新闻可以搜索添加现有新闻');
$newsBuilder->addFormItem('news_id', 'select2', [
'tags' => true,
'options' => D('News')->order('id desc')->getField('id, title', true)
]);
$cates = D('NewsCate')->order('id asc')->getField('id, name', true);
$builder->setMetaTitle('添加关键词') //设置页面标题
->setNIDByNode(MODULE_NAME, CONTROLLER_NAME, 'index')
->setPostUrl(U('add'))
->addFormItem('belong_to', 'radio', '选项', '', $this->belong_to)
->addFormItem('name', 'text', '名称*')
->addFormItem('news_id', 'self', '新闻列表', '', $newsBuilder->makeHtml())
->addFormItem('keywords_id', 'self', '关键词', '', $keywordBuilder->makeHtml())
->addFormItem('cate_id', 'checkbox', '分类', '', $cates)
->addFormItem('sort', 'num', '排序')
->addFormItem('status', 'select', '状态', '', DBCont::getStatusList())
->display();
}
}
public function save()
{
if (IS_POST) {
$data = I('post.');
foreach ($data['id'] as $k => $v) {
$save_data['sort'] = $data['sort'][$k];
D('Keywords')->where('id=' . $v)->save($save_data);
}
$this->success('保存成功', U('index'));
}
}
public function edit($id)
{
if (IS_POST) {
parent::autoCheckToken();
$m_id = I('post.id');
$data = I('post.');
$data['name'] = trim($data['name']);
$data['belong_to'] = $this->belong_to[$data['belong_to']];
$model = D('SecondaryTitle');
if (!$m_id) {
E('缺少内容ID');
}
$ent = $model->getOne($m_id);
if (!$ent) {
E('不存在内容');
}
$keyword_ids = D('Keywords')->checkKeywords($data['keywords_id'] ? $data['keywords_id'] : []);
if ($keyword_ids === false) {
$this->error(D('Keywords')->getError());
}
$data['keywords_id'] = implode(',', $keyword_ids ? $keyword_ids : []);
$data['news_id'] = implode(',', $data['news_id'] ? $data['news_id'] : []);
$data['cate_id'] = implode(',', $data['cate_id'] ? $data['cate_id'] : []);
$n_model = D('SecondaryNews');
$news_ent = $n_model->where(['secondary_id' => $data['id']])->find();
// todo 保存关联表
// dd($data, $data['id'], $ent['id'], $news_ent);
if ($data['keywords_id']) {
$news_ent['keywords_id'] = $data['keywords_id'];
}
if ($data['news_id']) {
$news_ent['news_id'] = $data['news_id'];
}
if ($data['cate_id']) {
$news_ent['cate_id'] = $data['cate_id'];
}
$ent['name'] = $data['name'];
$ent['sort'] = $data['sort'];
$ent['belong_to'] = $data['belong_to'];
$ent['status'] = $data['status'];
if ($model->createSave($ent) === false || $n_model->createSave($news_ent) === false) {
$this->error($model->getError());
} else {
$this->success('修改成功', U('index'));
}
} else {
$model = D('SecondaryTitle');
$info = $model->getOne($id);
$is_belong_to_in_list = in_array($info['belong_to'], $this->belong_to);
$info['belong_to'] = array_search($info['belong_to'], $this->belong_to);
$s_news = $model->getConditionList($info['id']);
if ($s_news) {
$info['news_id'] = $s_news['news_id'];
$info['keywords_id'] = $s_news['keywords_id'];
$info['cate_id'] = $s_news['cate_id'];
}
$keywordBuilder = new \Qscmf\Builder\SubTableBuilder();
$keywordBuilder->setData(D('Keywords')->genKeywordId($info['keywords_id']));
$keywordBuilder->addTableHeader('关键词', '30%', '输入关键词可以搜索添加现有关键词,输入@+关键词可以新增');
$keywordBuilder->addFormItem('keywords_id', 'select2', [
'tags' => true,
'options' => D('Keywords')->order('id desc')->getField('id, name', true)
]);
$newsBuilder = new \Qscmf\Builder\SubTableBuilder();
$newsBuilder->setData(D('News')->genNewsId($info['news_id']));
$newsBuilder->addTableHeader('新闻列表', '30%', '输入新闻可以搜索添加现有新闻');
$newsBuilder->addFormItem('news_id', 'select2', [
'tags' => true,
'options' => D('News')->order('id desc')->getField('id, title', true)
]);
$cates = D('NewsCate')->order('id asc')->getField('id, name', true);
$builder = new FormBuilder();
$builder->setMetaTitle('编辑关键词')
->setPostUrl(U('edit'))
// ->setExtraHtml($this->fetch('Keywords/detail'))
->setNIDByNode(MODULE_NAME, CONTROLLER_NAME, 'index')
->addFormItem('id', 'hidden', 'ID');
if ($is_belong_to_in_list) {
$builder
->addFormItem('belong_to', 'radio', '选项', '', $this->belong_to)
->addFormItem('name', 'text', '名称')
->addFormItem('news_id', 'self', '新闻列表', '', $newsBuilder->makeHtml())
->addFormItem('keywords_id', 'self', '关键词', '', $keywordBuilder->makeHtml())
->addFormItem('cate_id', 'checkbox', '分类', '', $cates);
}
$builder
->addFormItem('sort', 'num', '排序', '', $info['sort'])
->addFormItem('status', 'select', '状态', '', DBCont::getStatusList())
->setFormData($info)
->display();
}
}
public function forbid()
{
$ids = I('ids');
if (!$ids) {
$this->error('请选择要禁用的数据');
}
$r = parent::_forbid($ids);
if ($r !== false) {
// sysLogs('新闻分类id: ' . $ids . ' 禁用');
$this->success('禁用成功', U(CONTROLLER_NAME . '/index'));
} else {
$this->error($this->_getError());
}
}
public function resume()
{
$ids = I('ids');
if (!$ids) {
$this->error('请选择要启用的数据');
}
$r = parent::_resume($ids);
if ($r !== false) {
$this->success('启用成功', U(CONTROLLER_NAME . '/index'));
} else {
$this->error($this->_getError());
}
}
public function delete()
{
$ids = I('ids');
if (!$ids) {
$this->error('请选择要删除的数据');
}
$r = parent::_del($ids);
if ($r === false) {
$this->error($this->_getError());
} else {
$this->success('删除成功', U(MODULE_NAME . '/' . CONTROLLER_NAME . '/index'));
}
}
}

View File

@ -0,0 +1,75 @@
<?php
namespace Admin\Controller;
use Gy_Library\GyListController;
class SyslogsController extends GyListController{
public function index(){
$syslog_model = D('Syslogs');
$count = $syslog_model->getListForCount();
$per_page = C('ADMIN_PER_PAGE_NUM', null, false);
if($per_page === false){
$page = new \Gy_Library\GyPage($count);
}
else{
$page = new \Gy_Library\GyPage($count, $per_page);
}
$data_list = $syslog_model->getListForPage('', $page->nowPage, $page->listRows, 'create_time desc');
// 使用Builder快速建立列表页面。
$builder = new \Qscmf\Builder\ListBuilder();
$builder = $builder->setMetaTitle('系统日志') // 设置页面标题
->setNIDByNode()
->addTableColumn('modulename', '模块名称')
->addTableColumn('actionname', '方法名称')
->addTableColumn('message', '消息')
->addTableColumn('userid', '用户ID')
->addTableColumn('userip', '用户IP')
->addTableColumn('create_time', '操作时间', 'fun', 'date("Y-m-d H:i:s",__data_id__)')
->addTableColumn('opname', '操作记录')
->setTableDataList($data_list) // 数据列表
->setTableDataPage($page->show()) // 数据列表分页
->display();
}
}

View File

@ -0,0 +1,283 @@
<?php
namespace Admin\Controller;
use Common\Model\MenuModel;
use Gy_Library\DBCont;
use Gy_Library\GyListController;
use Qscmf\Builder\FormBuilder;
use Qscmf\Builder\ListBuilder;
use Qscmf\Builder\SubTableBuilder;
//专题
class TopicController extends GyListController
{
public function index()
{
$map = [];
$get_data = I('get.');
if (isset($get_data['key']) && $get_data['word']) {
$map[$get_data['key']] = array('like', '%' . $get_data['word'] . '%');
}
$model = D('Topic');
$count = $model->getListForCount($map);
$per_page = C('ADMIN_PER_PAGE_NUM', null, false);
if ($per_page === false) {
$page = new \Gy_Library\GyPage($count);
} else {
$page = new \Gy_Library\GyPage($count, $per_page);
}
$order = 'sort asc,id asc';
if (!empty($get_data['click_time']) && $get_data['click_time']==='asc') {
$order = 'click_time asc';
}elseif (!empty($get_data['click_time']) && $get_data['click_time']==='desc'){
$order = 'click_time desc';
}
$data_list = $model->getListForPage($map, $page->nowPage, $page->listRows, $order);
//时间戳的转换
foreach ($data_list as &$value) {
$value['create_date'] = date('Y-m-d H:i:s', $value['create_date']);
}
// 使用Builder快速建立列表页面。
$builder = new ListBuilder();
$builder = $builder->setMetaTitle('专题内容管理');// 设置页面标题
$builder->addTopButton('addnew');
$builder->addTopButton('save', array('title' => '保存排序'));
$builder
->setNIDByNode(MODULE_NAME, CONTROLLER_NAME, 'index')
->addSearchItem('click_time', 'select', '点击量排序', array('asc' => '点击量正序','desc'=>'点击量倒序'))
->addSearchItem('', 'select_text', '单行输入', array('name' => '专题名称'))
->addTableColumn('name', '专题标题')
->addTableColumn('click_time', '点击次数')
->addTableColumn('sort', '排序','','',true)
->addTableColumn('status', '状态', 'status', '', false)
->addTableColumn('right_button', '操作', 'btn')
->setTableDataList($data_list)// 数据列表
->setTableDataPage($page->show())// 数据列表分页
->addRightButton('edit',array('href' => U('edit',['page'=>I('get.page'),'id'=>'__data_id__']),'data-id' => '__data_id__'))// 添加编辑按钮
->addRightButton('delete')// 添加删除按钮
->addRightButton('forbid')// 添加禁用按钮
->addRightButton('self', ['title' => '文章列表', 'href' => U('TopicFromNews/index', ['topic_id' => '__data_id__']), 'class' => 'label label-success', '{key}' => '', '{condition}' => '', '{value}' =>''])
->display();
}
public function add()
{
if (IS_POST) {
parent::autoCheckToken();
$data = I('post.');
$model = D('Topic');
$r = $model->createAdd($data);
if ($r === false) {
$this->error($model->getError());
} else {
// sysLogs('新增内容id:' . $r);
$this->success(l('add') . l('success'), U(CONTROLLER_NAME . '/index'));
}
} else {
// 使用FormBuilder快速建立表单页面。
$builder = new FormBuilder();
$data_list = array(
"status" => 1,
);
if ($data_list) {
$builder->setFormData($data_list);
}
$builder->setMetaTitle('添加专题名称')//设置页面标题
->setNIDByNode(MODULE_NAME, CONTROLLER_NAME, 'index')
->setPostUrl(U('add'))//设置表单提交地址
->addFormItem('name', 'text', '*专题标题')
->addFormItem('cover_id', 'picture', '*封面图','尺寸为334*188px,格式JPG、PNG、JPEG')
// ->addFormItem('title', 'text', '专题标题')
->addFormItem('summary', 'textarea', '*专题简介','')
->addFormItem('banner_cover_id', 'picture', '横幅图','尺寸为910*320px,格式JPG、PNG、JPEG')
->addFormItem('sort', 'num', '排序')
->addFormItem('status', 'select', '状态', '', DBCont::getStatusList())
->display();
}
}
public function save(){
if(IS_POST){
$data = I('post.');
foreach($data['id'] as $k=>$v){
$save_data['sort'] = $data['sort'][$k];
D('Topic')->where('id=' . $v)->save($save_data);
}
$this->success('保存成功', U('index'));
}
}
public function edit($id)
{
if (IS_POST) {
parent::autoCheckToken();
$m_id = I('post.id');
$data = I('post.');
$model = D('Topic');
if (!$m_id) {
E('缺少内容ID');
}
$ent = $model->getOne($m_id);
if (!$ent) {
E('不存在内容');
}
$ent['name'] = $data['name'];
$ent['cover_id'] = $data['cover_id'];
// $ent['title'] = $data['title'];
$ent['summary'] = $data['summary'];
$ent['banner_cover_id'] = $data['banner_cover_id'];
$ent['sort'] = $data['sort'];
$ent['status'] = $data['status'];
if ($model->createSave($ent) === false) {
$this->error($model->getError());
} else {
$this->success('修改成功', U('index',['page'=>$data['page']]));
}
} else {
$info = D('Topic')->getOne($id);
$info['page'] =!empty(I('get.page'))?I('get.page'):1;
$builder = new FormBuilder();
$builder->setMetaTitle('编辑专题名称')
->setPostUrl(U('edit'))
->setNIDByNode(MODULE_NAME, CONTROLLER_NAME, 'index')
->addFormItem('id', 'hidden', 'ID')
->addFormItem('page', 'hidden', 'PAGE','',$info['page'])
->addFormItem('name', 'text', '*专题标题')
->addFormItem('cover_id', 'picture', '*封面图','尺寸为334*188px,格式JPG、PNG、JPEG')
// ->addFormItem('title', 'text', '专题标题')
->addFormItem('summary', 'textarea', '*专题简介','')
->addFormItem('banner_cover_id', 'picture', '横幅图','尺寸为910*320px,格式JPG、PNG、JPEG')
->addFormItem('sort', 'num', '排序')
->addFormItem('status', 'select', '状态', '', DBCont::getStatusList())
->setFormData($info)
->display();
}
}
public function forbid()
{
$ids = I('ids');
if (!$ids) {
$this->error('请选择要禁用的数据');
}
$r = parent::_forbid($ids);
if ($r !== false) {
// sysLogs('新闻分类id: ' . $ids . ' 禁用');
$this->success('禁用成功', U(CONTROLLER_NAME . '/index'));
} else {
$this->error($this->_getError());
}
}
public function resume()
{
$ids = I('ids');
if (!$ids) {
$this->error('请选择要启用的数据');
}
$r = parent::_resume($ids);
if ($r !== false) {
$this->success('启用成功', U(CONTROLLER_NAME . '/index'));
} else {
$this->error($this->_getError());
}
}
public function delete()
{
$ids = I('ids');
if (!$ids) {
$this->error('请选择要删除的数据');
}
$r = parent::_del($ids);
if ($r === false) {
$this->error($this->_getError());
} else {
$this->success('删除成功', U(MODULE_NAME . '/' . CONTROLLER_NAME . '/index'));
}
}
public function extractNumberGetName($strs, $countarr)
{
$patterns = "/\d+/";
$str = '';
preg_match_all($patterns, $strs, $arr);
$i = 0;
foreach ($arr[0] as $key => $value) {
if ($i == 0) {
$str .= $countarr[$value];
} else {
$str .= '、' . $countarr[$value];
}
$i++;
}
return $str;
}
public function toolbars()
{
return ['toolbars' => [
[
'undo', 'redo',
'bold', 'italic', 'underline', 'fontborder', 'strikethrough', 'superscript', 'subscript', 'removeformat', 'formatmatch', 'autotypeset', 'blockquote', 'pasteplain', '|', 'forecolor', 'backcolor', 'insertorderedlist', 'insertunorderedlist', 'selectall', 'cleardoc', '|',
'rowspacingtop', 'rowspacingbottom', 'lineheight', '|',
'customstyle', 'paragraph', 'fontfamily', 'fontsize', '|',
'indent', '|', 'justifyleft', 'justifycenter', 'justifyright', 'justifyjustify', '|',
'link', 'unlink', 'anchor', '|', 'imagenone', 'imageleft', 'imageright', 'imagecenter', '|',
'simpleupload', 'insertimage', '|', 'horizontal', 'spechars', 'wordimage', '|',
'inserttable', 'deletetable', 'insertparagraphbeforetable', 'insertrow', 'deleterow', 'insertcol', 'deletecol', 'mergecells', 'mergeright', 'mergedown', 'splittocells', 'splittorows', 'splittocols', 'charts',
'|', 'fullscreen', 'source', '|', 'attachment'
]
]
];
}
}

View File

@ -0,0 +1,131 @@
<?php
namespace Admin\Controller;
use Common\Model\MenuModel;
use Gy_Library\DBCont;
use Gy_Library\GyListController;
use Qscmf\Builder\FormBuilder;
use Qscmf\Builder\ListBuilder;
class TopicFromNewsController extends GyListController
{
public function index($topic_id)
{
$news_ids = D('TopicFromNews')->where(['topic_id'=>$topic_id])->getField('news_id',true);
$topic_name = D('Topic')->where(['id'=>$topic_id])->getField('name');
if(!empty($news_ids)){
$map['news_id']= ['IN',$news_ids];
$map['topic_id']= $topic_id;
}else{
$map['_string'] = '1=0';
}
$get_data = I('get.');
if (!empty($get_data['word']) && $get_data['key'] === 'title') {
$map1['title'] = array('like', '%' . $get_data['word'] . '%');
$map['news_id'] = D('News')->where($map1)->getField('id');
}
$map['status']= DBCont::YES_BOOL_STATUS;
$model = D('TopicFromNews');
$count = $model->getListForCount($map);
$per_page = C('ADMIN_PER_PAGE_NUM', null, false);
if ($per_page === false) {
$page = new \Gy_Library\GyPage($count);
} else {
$page = new \Gy_Library\GyPage($count, $per_page);
}
$news_list = $model->getListForPage($map, $page->nowPage, $page->listRows, 'sort asc,id asc');
foreach ($news_list as &$value) {
$value['title'] = D('News')->where(['id'=>$value['news_id']])->getField('title');
}
// 使用Builder快速建立列表页面。
$builder = new ListBuilder();
$builder = $builder->setMetaTitle($topic_name.'的新闻列表');// 设置页面标题
$builder->addTopButton('self', array('title' => '添加新闻', 'href' => U('News/index',['topic_id'=>$topic_id]), 'class' => 'btn btn-primary'));
$builder->addTopButton('save', array('title' => '保存排序','href' => U('saveTopic',['topic_id'=>$topic_id]), 'class' => 'btn btn-primary ajax-post confirm'));
$builder
->setSearchUrl(U('',['topic_id'=>$topic_id]))
->setNIDByNode(MODULE_NAME, 'Topic', 'index')
->addSearchItem('', 'select_text', '单行输入', array('title' => '新闻标题'))
->addTableColumn('title', '新闻标题')
->addTableColumn('sort', '排序','','',true)
->addTableColumn('right_button', '操作', 'btn')
->addRightButton('self', array('title' => '删除', 'href' => U('delete',['topic_id'=>$topic_id,'ids'=>'__data_id__']), 'class' => 'label label-danger ajax-get confirm'))// 添加删除按钮
->setTableDataList($news_list)// 数据列表
->setTableDataPage($page->show())// 数据列表分页
->display();
// $news_list = D('TopicFromNews')->where($map)->select();
}
public function saveTopic($topic_id){
if(IS_POST){
$data = I('post.');
foreach($data['id'] as $k=>$v){
$save_data['sort'] = $data['sort'][$k];
D('TopicFromNews')->where('id=' . $v)->save($save_data);
}
$this->success('保存成功',U('index',['topic_id'=>$topic_id]));
}
}
public function delete($topic_id)
{
$ids = I('ids');
if (!$ids) {
$this->error('请选择要删除的数据');
}
$r = parent::_del($ids);
if ($r === false) {
$this->error($this->_getError());
} else {
$this->success('删除成功', U('index',['topic_id'=>$topic_id]));
}
}
}

View File

@ -0,0 +1,418 @@
<?php
namespace Admin\Controller;
use Gy_Library\GyListController;
use Gy_Library\DBCont;
class UserController extends GyListController
{
public function test()
{
D('TeamMember')->isMember(136, 2);
}
public function index($status = DBCont::NORMAL_STATUS)
{
// 搜索
$keyword = I('keyword', '', 'string');
$condition = array('like', '%' . $keyword . '%');
$map['id|nick_name|email|telephone'] = array(
$condition,
$condition,
$condition,
$condition,
'_multi' => true
);
$map['status'] = $status;
$map['user_type'] = 'system';
$user_model = D('User');
$count = $user_model->getListForCount($map);
$per_page = C('ADMIN_PER_PAGE_NUM', null, false);
if ($per_page === false) {
$page = new \Gy_Library\GyPage($count);
} else {
$page = new \Gy_Library\GyPage($count, $per_page);
}
$data_list = $user_model->getListForPage($map, $page->nowPage, $page->listRows, 'register_date desc');
foreach ($data_list as &$data) {
$role_ids = D('RoleUser')->where('user_id=' . $data['id'])->getField('role_id', true);
if ($role_ids) {
$role_map['id'] = array('in', $role_ids);
$role_map['status'] = DBCont::NORMAL_STATUS;
$data['role'] = D('Role')->where($role_map)->getField('name', true);
$data['role'] = implode(',', (array)$data['role']);
}
$user_avatar = $user_model->getUserAvatar($data['id']);
if ($user_avatar) {
$data['avatar'] = $user_avatar['avatar'];
$data['address'] = $user_avatar['address'];
$data['career'] = $user_avatar['career'];
}
}
// 设置Tab导航数据列表
$user_status_list = DBCont::getUserStatusList();
foreach ($user_status_list as $key => $val) {
$tab_list[$key]['title'] = $val;
$tab_list[$key]['href'] = U('index', array('status' => $key));
}
// 使用Builder快速建立列表页面。
$builder = new \Qscmf\Builder\ListBuilder();
$builder = $builder->setMetaTitle('账号列表') // 设置页面标题
->addTopButton('addnew') // 添加新增按钮
->addSearchItem('keyword', 'text', 'id/昵称/email/手机号');
switch ($status) {
case DBCont::NORMAL_STATUS;
$builder = $builder->addTopButton('forbid'); // 添加禁用按钮
break;
case DBCont::FORBIDDEN_STATUS;
$builder = $builder->addTopButton('resume'); // 添加启用按钮
break;
default:
break;
}
$builder->addTopButton('delete') // 添加删除按钮
->setNID(5)
->setTabNav($tab_list, $status) // 设置页面Tab导航
->addTableColumn('id', 'ID')
->addTableColumn('nick_name', '用户名')
->addTableColumn('email', '邮箱')
->addTableColumn('telephone', '手机')
->addTableColumn('role', '用户组')
->addTableColumn('avatar', '头像', 'picture')
->addTableColumn('address', '地址')
->addTableColumn('career', '职业')
->addTableColumn('right_button', '操作', 'btn')
->setTableDataList($data_list) // 数据列表
->setTableDataPage($page->show()) // 数据列表分页
->addRightButton('edit') // 添加编辑按钮
->addRightButton('self', array('title' => '修改密码', 'href' => '#', 'data-id' => '__data_id__', 'class' => 'label label-default repwd-btn', 'data-toggle' => 'modal', 'data-target' => '#changepassword'))
->addRightButton('self', array('title' => '激活', 'href' => U('active', array('ids' => '__data_id__')), 'class' => 'label label-primary', '{key}' => 'status', '{condition}' => 'eq', '{value}' => '2'))
->addRightButton('forbid') // 添加禁用/启用按钮
->addRightButton('delete') // 添加删除按钮
->setExtraHtml($this->fetch('User/repwd'))
->display();
}
public function add()
{
if (IS_POST) {
parent::autoCheckToken();
$data = I('post.');
if ($data['pwd'] != $data['pwd1']) {
$this->error('密码不一致');
}
$data['status'] = DBCont::NORMAL_STATUS;
$data['user_type'] = 'system';
$data['last_expire_time'] = date('Y-m-d H:i:s', strtotime('+1 day'));
// dd($data);
$user_model = D('User');
$user_id = $user_model->newUser($data);
if ($user_id === false) {
$this->error($user_model->getError());
} else {
//插入用户组信息
$this->_addRole($user_id);
$avatar_model = D('UserAvatar');
$avatar_id = $avatar_model->newAvatar($data, $user_id);
sysLogs('新增用户id:' . $user_id);
$this->success(l('add') . l('success'), U(CONTROLLER_NAME . '/index'));
}
} else {
// 使用FormBuilder快速建立表单页面。
$role = new \Common\Model\RoleModel();
$map['status'] = DBCont::NORMAL_STATUS;
$role_list = $role->getRoleList($map);
foreach ($role_list as $role) {
$role_options[$role['id']] = $role['name'];
}
$builder = new \Qscmf\Builder\FormBuilder();
$builder->setMetaTitle('新增用户') //设置页面标题
->setNID(5)
->setPostUrl(U('add')) //设置表单提交地址
->addFormItem('nick_name', 'text', '用户名*')
->addFormItem('email', 'text', '电子邮箱*')
->addFormItem('telephone', 'text', '手机')
->addFormItem('pwd', 'password', '密码*')
->addFormItem('pwd1', 'password', '重复密码*')
->addFormItem('address', 'text', '地址')
->addFormItem('career', 'text', '职业')
->addFormItem('avatar', 'picture', '头像', '格式JPG、PNG、JPEG')
->addFormItem('role', 'select', '用户组', '', $role_options)
->display();
}
}
public function edit($id)
{
if (IS_POST) {
parent::autoCheckToken();
$user_id = I('post.id');
$data = I('post.');
$user_model = D('User');
if (!$user_id) {
E('缺少user_id');
}
$user_ent = $user_model->getOne($user_id);
if (!$user_ent) {
E('不存在用户');
}
//需要更新的fields
$user_ent['nick_name'] = $data['nick_name'];
$user_ent['email'] = $data['email'];
$user_ent['telephone'] = $data['telephone'];
$user_ent['portrait'] = $data['portrait'];
if ($user_model->createSave($user_ent) === false) {
$this->error($user_model->getError());
} else {
$this->_addRole($user_id);
$avatar_model = D('UserAvatar');
$avatar_id = $avatar_model->updateAvatar($data, $user_id);
sysLogs('修改用户id:' . $user_id);
$this->success('修改成功', U('index'));
}
} else {
// 获取账号信息
$info = D('User')->getOne($id);
$role_user_ent = D('RoleUser')->getByUser_id($id);
$info['role'] = $role_user_ent['role_id'];
$avatar = D('User')->getUserAvatar($id);
if ($avatar) {
$info['avatar'] = $avatar['avatar'];
$info['address'] = $avatar['address'];
$info['career'] = $avatar['career'];
}
$role = new \Common\Model\RoleModel();
$map['status'] = DBCont::NORMAL_STATUS;
$role_list = $role->getRoleList($map);
foreach ($role_list as $role) {
$role_options[$role['id']] = $role['name'];
}
// 使用FormBuilder快速建立表单页面。
$builder = new \Qscmf\Builder\FormBuilder();
$builder->setMetaTitle('编辑用户') // 设置页面标题
->setPostUrl(U('edit')) // 设置表单提交地址
->setNID(5)
->addFormItem('id', 'hidden', 'ID')
->addFormItem('nick_name', 'text', '用户名*')
->addFormItem('email', 'text', '电子邮箱*')
->addFormItem('telephone', 'text', '手机')
->addFormItem('address', 'text', '地址')
->addFormItem('career', 'text', '职业')
->addFormItem('avatar', 'picture', '头像', '格式JPG、PNG、JPEG')
->addFormItem('role', 'select', '用户组', '', $role_options)
->setFormData($info)
->display();
}
}
//插入用户组信息
private function _addRole($user_id)
{
$role_id = I('role');
$role_user = D('RoleUser');
$data_arr = array();
$data_arr[] = array('role_id' => $role_id, 'user_id' => $user_id);
$r = $role_user->where(array('user_id' => $user_id))->delete();
if ($r === false) {
$this->error($role_user->getError());
}
if (!empty($data_arr)) {
$r = $role_user->addAll($data_arr);
if ($r === false) {
$this->error($role_user->getError());
}
}
}
private function _addAvatar($user_id)
{
$avatar_id = I('avatar');
dd($avatar_id);
$avatar_user = D('UserAvatar');
}
//激活用户
public function active()
{
$ids = I('ids');
if (!$ids) {
$this->error('请选择要激活的用户');
}
$user_model = D('User');
$map['id'] = array('in', $ids);
$r = $user_model->where($map)->setField('status', DBCont::NORMAL_STATUS);
//设置默认分组
$default_ent = D('DefaultRole')->find();
if ($default_ent) {
$user_ents = $user_model->where($map)->select();
foreach ($user_ents as $v) {
D('RoleUser')->where('user_id=' . $v['id'] . ' and role_id=' . $default_ent['role_id'])->delete();
D('RoleUser')->add(array('role_id' => $default_ent['role_id'], 'user_id' => $v['id']));
}
}
if ($r === false) {
$this->error($user_model->getError());
} else {
sysLogs('用户id: ' . $ids . ' 激活');
$this->success('激活成功', U(CONTROLLER_NAME . '/index'));
}
}
public function forbid()
{
$ids = I('ids');
if (!$ids) {
$this->error('请选择要禁用的数据');
}
$r = parent::_forbid($ids);
if ($r !== false) {
sysLogs('用户id: ' . $ids . ' 禁用');
$this->success('禁用成功', U(CONTROLLER_NAME . '/index'));
} else {
$this->error($this->_getError());
}
}
public function resume()
{
$ids = I('ids');
if (!$ids) {
$this->error('请选择要启用的数据');
}
$r = parent::_resume($ids);
if ($r !== false) {
sysLogs('用户id: ' . $ids . ' 启用');
$this->success('启用成功', U(CONTROLLER_NAME . '/index'));
} else {
$this->error($this->_getError());
}
}
public function delete()
{
$ids = I('ids');
if (!$ids) {
$this->error('请选择要删除的数据');
}
$r = parent::_del($ids);
if ($r === false) {
$this->error($this->_getError());
} else {
sysLogs('用户id: ' . $ids . ' 删除');
$this->success('删除成功', U(MODULE_NAME . '/' . CONTROLLER_NAME . '/index'));
}
}
public function repwd()
{
if (IS_POST) {
parent::autoCheckToken();
$user_model = new \Common\Model\UserModel();
if (I('post.pwd') != I('post.pwd1')) {
$this->error('密码不一致');
}
$user_ent = $user_model->getOne(I('post.id'));
if (!$user_ent) {
$this->error('用户不存在');
}
$r = $user_model->modifyPwdByAdmin(I('post.id'), I('post.pwd'));
if ($r === false) {
$this->error($user_model->getError());
} else {
syslogs('修改密码, 用户id:' . I('id'));
$this->success('修改密码成功');
}
}
}
/**
* 登陆者编辑自己的资料
*/
public function editUser()
{
$id = session('auth_id');
if (IS_POST) {
parent::autoCheckToken();
$data = I('post.');
if ($data['pwd'] != $data['pwd1']) {
$this->error('密码不一致');
}
$user_model = D('User');
$user_ent = $user_model->getOne($id);
if (!$user_ent) {
E('不存在用户');
}
$user_model->startTrans();
try {
$save = [
'id' => $id,
'nick_name' => $data['nick_name'],
'email' => $data['email'],
'telephone' => $data['telephone'],
];
if ($user_model->createSave($save) === false) {
E($user_model->getError());
}
if (!empty($data['pwd'])) {
if ($user_model->modifyPwdByAdmin($id, $data['pwd']) === false) {
E($user_model->getError());
}
}
$user_model->commit();
} catch (\Exception $e) {
$user_model->rollback();
$this->error($e->getMessage());
}
if (empty($data['referer'])) {
$this->success('修改成功', U('admin/dashboard/index'));
} else {
$this->success('修改成功', $data['referer']);
}
} else {
// 获取账号信息
$info = D('User')->getOne($id);
unset($info['pwd']);
$info['referer'] = $_SERVER['HTTP_REFERER'];
$builder = new \Qscmf\Builder\FormBuilder();
$builder->setMetaTitle('编辑用户') // 设置页面标题
->setPostUrl(U(''))
->addFormItem('nick_name', 'text', '用户名*')
->addFormItem('email', 'text', '电子邮箱')
->addFormItem('telephone', 'text', '手机')
->addFormItem('pwd', 'password', '密码')
->addFormItem('pwd1', 'password', '重复密码')
->addFormItem('referer', 'hidden', '跳转地址')
->setFormData($info)
->display();
}
}
}

View File

@ -0,0 +1 @@

1
app/Admin/Model/index.html Executable file
View File

@ -0,0 +1 @@

View File

@ -0,0 +1,14 @@
<extend name="Admin@default/common/dashboard_layout" />
<block name="content">
<!-- Content Header (Page header) -->
<section class="content-header clearfix">
<h1>
平台概况
</h1>
</section>
<!-- Main content -->
<section class="content">
</section>
<!-- /.content -->
</block>

View File

@ -0,0 +1,9 @@
<layout name="Admin@default/common/dashboard_layout" />
<section class="content" n-id="122">
<form action="" id='login_form' method="post">
钩子名称<input type='text' name='name'/><br/>
钩子描述<input type='text' name='desc'/><br/>
<input type="submit" value="提交" />
</form>
</section>

View File

@ -0,0 +1,10 @@
<layout name="Admin@default/common/dashboard_layout" />
<section class="content" n-id="122">
<form action="" id='login_form' method="post">
<input type="hidden" name="id" value="{$vo.id}"/>
钩子名称<input type='text' name='name' value="{$vo.name}"/><br/>
钩子描述<input type='text' name='desc' value="{$vo.desc}"/><br/>
<input type="submit" value="提交" />
</form>
</section>

View File

@ -0,0 +1,125 @@
<layout name="Admin@default/common/dashboard_layout" />
<taglib name="Common\TagLib\Gy" />
<!-- Content Header (Page header) -->
<section class="content-header clearfix">
<h1 class="pull-left">钩子列表</h1>
<div class="pull-right">
<Gy:auth node="admin.hooks.add"><a href="{:U('Hooks/add')}" class="btn btn-primary btn-sm"><i class="icon icon-plus"></i> 新增钩子</a></gy:auth>
</div>
</section>
<!-- Main content -->
<section class="content" n-id="122">
<div class="row mb-20">
<div class="col-md-5">
<div class="form-inline">
<if condition="($map.status eq 1)">
<Gy:auth node="admin.hooks.forbid"><button data-msg-title="提示" data-msg-content="是否禁用所选择的内容?" data-msg-buttons="yes,no" class="btn btn-danger btn-sm btn-list-disable"><i class="icon icon-forbid"></i> 禁用</button></Gy:auth>
<elseif condition="($map.status eq 0)"/>
<Gy:auth node="admin.hooks.resume"><button data-msg-title="提示" data-msg-content="是否启用所选择的内容?" data-msg-buttons="yes,no" class="btn btn-primary btn-sm btn-list-enable"><i class="icon icon-plus"></i> 启用</button></Gy:auth>
</if>
<Gy:auth node="admin.hooks.delete"><button data-msg-title="提示" data-msg-content="是否删除所选择的内容?" data-msg-buttons="yes,no" class="btn btn-danger btn-sm btn-list-del"><i class="glyphicon glyphicon-remove"></i> 删除</button></Gy:auth>
</div>
</div>
</div>
<div class="box box-solid">
<div class="box-body no-padding">
<div class="nav-tabs-custom">
<ul class="nav nav-tabs">
<volist name="statusList" id="vo">
<if condition="($map.status eq $vo[id])">
<li class='active'><a href="#">{$vo.name}</a></li>
<else />
<li><a href="__URL__/index/status/{$vo.id}">{$vo.name}</a></li>
</if>
</volist>
</ul>
<div class="tab-content no-padding mt-10">
<table class="table table-hover">
<thead>
<tr>
<th width="35"><input type="checkbox" name="menulist" data-fun="check-all-or-none" data-target="group-of-checkbox"></th>
<th>名称</th>
<th>描述</th>
<th>挂载规则</th>
<th width="160">操作</th>
</tr>
</thead>
<tbody>
<volist name="list" id="hooks">
<tr>
<th><input type="checkbox" name="menulist" data-group="table-group" data-target="group-of-checkbox" value="{$hooks.id}"></th>
<td>{$hooks.name}</td>
<td>{$hooks.desc}</td>
<td>{$hooks.rule}</td>
<td>
<Gy:auth node="admin.hooks.edit"><a href="__URL__/edit/id/{$hooks.id}" class="btn btn-primary btn-xs">编辑</a></gy:auth>
<if condition="($hooks.status eq 1)">
<Gy:auth node="admin.hooks.forbid"><a href="__URL__/forbid/id/{$hooks.id}" class="btn btn-primary btn-xs ajax-submit">禁用</a></gy:auth>
<else />
<Gy:auth node="admin.hooks.resume"><a href="__URL__/resume/id/{$hooks.id}" class="btn btn-primary btn-xs ajax-submit">启用</a></gy:auth>
</if>
<Gy:auth node="admin.hooks.delete"><a href="__URL__/delete/id/{$hooks.id}" class="btn btn-danger btn-xs ajax-submit">删除</a></gy:auth>
</td>
</td>
</tr>
</volist>
</tbody>
</table>
</div><!-- /.tab-content -->
</div>
</div><!-- /.box-body -->
</div><!-- /.box -->
<div class="row">
<div class="col-md-5">
<div class="form-inline">
<if condition="($map.status eq 1)">
<Gy:auth node="admin.hooks.forbid"><button data-msg-title="提示" data-msg-content="是否禁用所选择的内容?" data-msg-buttons="yes,no" class="btn btn-danger btn-sm btn-list-disable"><i class="icon icon-forbid"></i> 禁用</button></Gy:auth>
<elseif condition="($map.status eq 0)"/>
<Gy:auth node="admin.hooks.resume"><button data-msg-title="提示" data-msg-content="是否启用所选择的内容?" data-msg-buttons="yes,no" class="btn btn-primary btn-sm btn-list-enable"><i class="icon icon-plus"></i> 启用</button></gy:auth>
</if>
<Gy:auth node="admin.hooks.delete"><button data-msg-title="提示" data-msg-content="是否删除所选择的内容?" data-msg-buttons="yes,no" class="btn btn-danger btn-sm btn-list-del"><i class="glyphicon glyphicon-remove"></i> 删除</button></Gy:auth>
</div>
</div>
<div class="col-md-7">
<div class="pull-right">
<include file="common/pagination" />
</div>
</div>
</div>
</section><!-- /.content -->
@section:script{%
<script type="text/javascript" src="__PUBLIC__/libs/jquery.group-of-checkbox/jquery.group-of-checkbox.js"></script>
<script type="text/javascript" src="__PUBLIC__/libs/bootstrap-messagebox/bootstrap-messagebox.js"></script>
<script type="text/javascript">
jQuery(document).ready(function($){
$('.btn-list-disable').bs_messagebox({success:function(status){
if(status=="cancel") return;
if(status=="yes"){
var checkboxGroup = $('[data-target=group-of-checkbox]').data('checkboxGroup');
ajaxlink($(this),"__URL__/forbid/id/" + checkboxGroup.getCheckedValue());
//location.href = "__URL__/forbid/id/" + checkboxGroup.getCheckedValue();
}
}});
$('.btn-list-enable').bs_messagebox({success:function(status){
if(status=="cancel") return;
if(status=="yes"){
var checkboxGroup = $('[data-target=group-of-checkbox]').data('checkboxGroup');
ajaxlink($(this),"__URL__/resume/id/" + checkboxGroup.getCheckedValue());
//location.href = "__URL__/resume/id/" + checkboxGroup.getCheckedValue();
}
}});
$('.btn-list-del').bs_messagebox({success:function(status){
if(status=="cancel") return;
if(status=="yes"){
var checkboxGroup = $('[data-target=group-of-checkbox]').data('checkboxGroup');
ajaxlink($(this),"__URL__/delete/id/" + checkboxGroup.getCheckedValue());
//location.href = "__URL__/delete/id/" + checkboxGroup.getCheckedValue();
}
}});
});
</script>
%}

View File

@ -0,0 +1,5 @@
<style>
.submit{
display: none;
}
</style>

View File

@ -0,0 +1,347 @@
<style>
.daterangepicker.dropdown-menu {
margin-top: 55px;
}
.export-col {
float: left;
margin-left: 30px;
}
</style>
<style>
ul {
list-style: none;
padding-left: 0;
}
</style>
<script>
$('.show-export').on('click', function () {
$('#showExportModal').modal('show');
});
$(function () {
$('.autoBind').on('click', function () {
$('#auto_bind_modal').modal('show');
});
var pageSize = 500;
var loadData = [];
var queue;
var count;
var pageNum;
var currentPiece;
var isInit;
var lastLoaded;
var totalPiece;
var error = false;
var folderArr = [];
var zip;
var downloadPhoto = {};
$('.export_letter').on('click', function () {
varInit();
$('#myModalLabel').text('下载队列');
var query = getQueryData();
var selectIds = getSelectIds();
getLetterCount(query, selectIds);
if (totalPiece == 0) {
noData();
return false;
}
letterExport(query, selectIds);
initDownloadBar();
$('#comm-file-export-modal').modal('show').data('show', true);
showCloseBtn();
});
$('#cancel-download-queue').on('click', function () {
queue.close();
});
function getQueryData() {
var query = $('.builder .search-input').serialize();
query = query.replace(/(&|^)(\w*?\d*?\-*?_*?)*?=?((?=&)|(?=$))/g, '');
query = query.replace(/(^&)|(\+)/g, '');
return query;
}
function varInit() {
queue = null;
count = 0;
pageNum = 1;
currentPiece = 0;
lastLoaded = 0;
isInit = true;
totalPiece = 0;
loadData = [];
folderArr = [];
zip = new JSZip();
downloadPhoto = {};
}
function noData() {
showCloseBtn();
alert('暂无数据');
}
function showCloseBtn() {
$('#cancel-download-queue').removeClass('hidden');
$('#download-complete').addClass('hidden');
}
function getLetterCount(data, selectIds) {
var data = data + '&selectIds=' + selectIds;
$.ajax({
type: 'get',
async: false,
url: "{:U('admin/communication/getLetterCount')}",
data: data,
success: function (res) {
count = res;
totalPiece = Math.ceil(count / pageSize);
}
});
}
function letterExport(query, selectIds) {
var data = query + '&pageNum=' + pageNum + '&pageSize=' + pageSize + '&selectIds=' + selectIds;
$.ajax({
type: 'get',
async: false,
url: "{:U('admin/communication/letterExport')}",
data: data,
success: function (res) {
pageNum++;
if (count === 0 && pageNum == 1) {
noData();
return false;
}
currentPiece++;
getImageData(res);
queueInit();
},
fail: function () {
alert('下载失败');
}
});
}
function initDownloadBar() {
$('.progress-bar').css({
width: 0
});
$('.progrss-num').text('0%');
}
function queueInit() {
queue = new createjs.LoadQueue(true);
queue.loadManifest(loadData);
queue.on("complete", handleComplete, this);
queue.on("fileload", handleFileLoad, this);
queue.on("progress", handleProgress, this);
}
function getImageData(res) {
res.forEach(function (val) {
val.url.forEach(function (v) {
// v = '__PUBLIC__/img/index/btn-circle.png';
var loadDataItem = {
cid: val.cid,
id: val.id,
cname: val.cname,
vname: val.vname,
create_date: val.create_date,
src: v,
crossOrigin: true,
type: createjs.AbstractLoader.IMAGE
};
loadData.push(loadDataItem);
});
});
}
function handleProgress(a) {
//算法: 总模块的进度-1 + 当前模块进度的百分比
var loaded = (currentPiece - 1) / totalPiece * 100 + a.loaded * 100 / totalPiece;
loaded = parseInt(loaded);
$('.progress-bar').css({
width: loaded + '%'
});
$('.progrss-num').text(loaded + '%');
}
function handleFileLoad(e) {
appendFile2Zip(e.item);
}
function handleComplete() {
if (totalPiece > currentPiece) {
//继续下载
if ($('#comm-file-export-modal').data('show')) {
getDownloadData();
}
} else {
// //下载结束
createZip();
$('#cancel-download-queue').addClass('hidden');
$('#download-complete').removeClass('hidden');
}
}
function getPhotoOrder(fileName) {
if (typeof downloadPhoto[fileName] == 'number') {
++downloadPhoto[fileName];
} else {
downloadPhoto[fileName] = 1;
}
return downloadPhoto[fileName];
}
function appendFile2Zip(v) {
// loadData.forEach(function (v) {
var img = queue.getResult(v.id, true);
if (!img) {
error = true;
return false;
}
if (typeof v.ext != 'string') {
v.ext = '';
}
if (!v.ext) {
v.ext = 'jpg';
}
//创建文件夹
// folder = zip.folder(v.name + '_' + v.cid);
// folder.file(v.create_date + '_' + v.m[0],img, {blob: true});
var imgFileName = v.cid + '-' + v.cname + '-' + v.vname + '-' + v.create_date;
zip.file(imgFileName + '_' + getPhotoOrder(imgFileName) + '.' + v.ext.toLowerCase(), img);
// });
}
function createZip(zipName) {
if (typeof zipName != 'string') {
var zipName = 'download.zip';
}
if (zipName.lastIndexOf('zip') != zipName.length - 3) {
zipName = 'download.zip';
}
$('#myModalLabel').text('生成压缩包');
var $progressBar = $('.progress-bar'),
$progressNum = $('.progrss-num');
$progressBar.css({
transition: 'none',
width: '0%'
});
$progressNum.text('0%');
zip.generateAsync({type: "blob", streamFiles: true}, function (metadata) {
var loaded = metadata.percent.toFixed(2);
$progressBar.css({
width: loaded + '%'
});
$progressNum.text(loaded + '%');
})
.then(function (content) {
saveAs(content, zipName);
});
}
});
</script>
<script>
$('body').on('click', '.export_communication', function () {
var url = $(this).data('url');
var stream_rownum = $(this).data('streamrownum');
var filename = $(this).data('filename');
var query = $('.builder-list-box .search-input').serialize();
query = query.replace(/(&|^)(\w*?\d*?\-*?_*?)*?=?((?=&)|(?=$))/g, '');
query = query.replace(/(^&)|(\+)/g, '');
if (url.indexOf('?') > 0) {
url += '&' + query;
} else {
url += '?' + query;
}
var btn = this;
var title = $(this).text();
var opt = {
'url': url + '&ids=' + getSelectIds(),
'fileName': filename,
'before': function () {
$(btn).attr('disabled', 'true');
$(btn).text('导出中');
//$('.export_loading').show();
},
'reqType': 'POST',
'reqBody': $('#selectCol').serialize(),
'after': function () {
$(btn).removeAttr('disabled');
$(btn).text(title);
//$('.export_loading').hide();
},
'progress': function (progress) {
$(btn).text(progress);
}
}
var excel = new ExportExcel(opt);
if (parseInt(stream_rownum) > 0) {
excel.streamExport(stream_rownum);
} else {
excel.export();
}
});
$(function () {
var focusInputName;
$('.search-form input').on('focus', function () {
focusInputName = $(this).attr('name');
});
$('body').on('click','.daterangepicker .cancelBtn', function () {
$('.search-form input[name=' + focusInputName + ']').val('');
});
$('body').on('click','.daterangepicker .applyBtn', function () {
$('#search').trigger('click')
});
$('body').on('click','.daterangepicker .cancelBtn', function () {
$('#search').trigger('click')
});
});
</script>
<!-- <link rel="stylesheet" href="__PUBLIC__/libs/daterangepicker/daterangepicker-bs3.css">
<script type="text/javascript" src="__PUBLIC__/libs/daterangepicker/daterangepicker.js"></script>
<script type="text/javascript" src="__PUBLIC__/libs/daterangepicker/lang/zh-cn.js"></script>
<script type="text/javascript">
jQuery(document).ready(function ($) {
$('input[name=publish_date]').attr('readonly','readonly').daterangepicker({
format: 'YYYY/MM/DD',
applyClass : 'btn btn-primary btn-flat btn-sm',
cancelClass : 'btn btn-primary btn-flat btn-sm',
clearBtn: true,
timePicker : false,
timePicker12Hour : false,//是否使用12小时制来显示时间
timePickerIncrement : 1, //时间的增量,单位为分钟
autoUpdateInput : false,
locale: {
applyLabel: '应用',
cancelLabel: '重置',
fromLabel: '从',
toLabel: '到',
weekLabel: '周',
customRangeLabel: '自定义范围',
daysOfWeek: moment()._lang._weekdaysMin.slice(),
monthNames: moment()._lang._monthsShort.slice(),
firstDay: 0
}
});
});
</script> -->

View File

@ -0,0 +1,53 @@
<block name="script">
<script type="text/javascript">
var menu_list = <?php echo $menu_list_json ?>;
var menuInit = function(_cmbType, _cmbMenu, defaultType)
{
var cmbType = document.getElementById(_cmbType);
var cmbMenu = document.getElementById(_cmbMenu);
function cmbSelect(cmb, str)
{
for(var i=0; i<cmb.options.length; i++)
{
if(cmb.options[i].value == str)
{
cmb.selectedIndex = i;
return;
}
}
}
function cmbAddOption(cmb, key, str, obj)
{
var option = document.createElement("OPTION");
cmb.options.add(option);
option.innerHTML = str;
option.value = key;
option.obj = obj;
}
function changeType()
{
cmbMenu.options.length = 0;
cmbMenu.onchange = null;
if(cmbType.selectedIndex == -1 || cmbType.selectedIndex == 0)return;
var item = cmbType.options[cmbType.selectedIndex].obj;
for(var i=0; i<item.length; i++)
{
cmbAddOption(cmbMenu, item[i].id, item[i].title, null);
}
}
for(var key in menu_list)
{
cmbAddOption(cmbType, key, key, menu_list[key]);
}
cmbSelect(cmbType, defaultType);
changeType();
cmbType.onchange = changeType;
}
menuInit('cmbType', 'cmbMenu', '无');
</script>
</block>

View File

@ -0,0 +1,40 @@
<extend name="Admin@default/common/dashboard_layout"/>
<block name='content'>
<section class="content" n-id="28">
<form method="post" action="" >
<div class='row'>
<div class='col-xs-9'>
<div class="nav-tabs-custom">
<div class="tab-content">
<div class="tab-pane active" id="base-inf" >
<div class="form-group">
<label for="module">检查模块</label>
<select name="module" class="form-control js-data-example-ajax" style="width:500px">
<volist name="module_list" id="module">
<option value="{$module.name}" <eq name="check_module" value="$module['name']">selected='selected'</eq>>{$module.name}</option>
</volist>
</select>
</div>
</div>
</div><!-- /.tab-content -->
</div><!-- /.nav-tabs-custom -->
</div><!-- /.col -->
<div class="col-xs-3">
<div class="pull-right">
<button class="btn btn-primary" type="submit">检查</button>
</div>
</div>
</div><!-- /.row -->
<div class='row'>
<div class='col-xs-9'>
<present name='check_module'>
{:W('Admin/AuthCheck/index', array('module' => $check_module))}
</present>
</div>
</div>
</form>
</section>
</block>

View File

@ -0,0 +1,57 @@
<block name='script'>
<script type="text/javascript">
var menu_list = <?php echo $menu_list_json ?>;
var menuInit = function(_cmbType, _cmbMenu, defaultType, defaultMenu)
{
var cmbType = document.getElementById(_cmbType);
var cmbMenu = document.getElementById(_cmbMenu);
function cmbSelect(cmb, str)
{
for(var i=0; i<cmb.options.length; i++)
{
if(cmb.options[i].value == str)
{
cmb.selectedIndex = i;
return;
}
}
}
function cmbAddOption(cmb, key, str, obj)
{
var option = document.createElement("OPTION");
cmb.options.add(option);
option.innerHTML = str;
option.value = key;
option.obj = obj;
}
function changeType()
{
cmbMenu.options.length = 0;
cmbMenu.onchange = null;
if(cmbType.selectedIndex == -1 || cmbType.selectedIndex == 0){
cmbAddOption(cmbMenu, 0, '无', null);
return;
}
var item = cmbType.options[cmbType.selectedIndex].obj;
for(var i=0; i<item.length; i++)
{
cmbAddOption(cmbMenu, item[i].id, item[i].title, null);
}
cmbSelect(cmbMenu, defaultMenu);
}
for(var key in menu_list)
{
cmbAddOption(cmbType, key, key, menu_list[key]);
}
cmbSelect(cmbType, defaultType);
changeType();
cmbType.onchange = changeType;
}
menuInit('cmbType', 'cmbMenu', "<?php echo $cur_menu['type'];?>", "<?php echo $cur_menu['id']; ?>");
</script>
</block>

View File

@ -0,0 +1 @@

View File

@ -0,0 +1,567 @@
<layout name="common/layout" />
<script>
function fontRem() {
var html = document.getElementsByTagName('html')[0];
var winW = html.offsetWidth;
var designW = winW > 768 ? 1920: 720;
html.style.fontSize = (winW / designW) * 100 + 'px';
}
fontRem();
window.onresize = fontRem;
</script>
<div class="background"></div>
<div class="login-page">
<div class="inner-login-page">
<div class="container">
<div class="row">
<div class="col-md-6 col-sm-6 login-bg hidden-xs">
</div>
<div class="col-md-6 col-sm-6 col-xs-12 login-box">
<div class="login-form-box" id="login-box">
<div class="header">{:C('WEB_SITE_TITLE')}</div>
<form id='' method="post" class="ajax-form">
<div class="form-group">
<img class="login-form-icon icon-login-user hidden-xs" src="__PUBLIC__/img/icon-login-user.png" alt="">
<img class="login-form-icon icon-login-user-mobile hidden-md hidden-lg hidden-sm" src="__PUBLIC__/img/icon-login-user-mobile.png" alt="">
<input autofocus type="text" name="uid" class="form-control" placeholder="{:L('username')}/{:L('email')}" />
</div>
<div class="form-group">
<img class="login-form-icon icon-login-lock hidden-xs" src="__PUBLIC__/img/icon-login-lock.png" alt="">
<img class="login-form-icon icon-login-lock-mobile hidden-md hidden-lg hidden-sm" src="__PUBLIC__/img/icon-login-lock-mobile.png" alt="">
<input type="password" name="pwd" class="form-control" placeholder="******" />
</div>
<present name='verify_show'>
<div class="form-group">
<div class="row">
<div class="col-xs-6">
<input type="text" name='verify' class="form-control" placeholder="{:L('verify_code')}" />
</div>
<div class="col-xs-6">
<a href="#" class="validate-img"><img src="{:U('verify')}" /></a>
</div>
</div>
</div>
</present>
<button type="submit" class="btn btn-mtx btn-block" data-loading-text="登录中...">登录</button>
<div class="error-info"></div>
</form>
<!-- <hr>-->
<p class="text-center tech-provider"><a target="_blank" href="http://quansitech.com">挑战者网</a>技术驱动</p>
</div>
</div>
</div>
</div>
</div>
</div>
@section:script{%
<script type="text/javascript">
jQuery(document).ready(function($) {
// $('html').addClass('bg-login');
// $(document.body).addClass('bg-login');
$('.form-box').fadeIn(800);
$('a.validate-img').click(function() {
//重新加载验证码
$('#loadingimg').show();
var img = $("<img />").attr('src', "<?php echo U('verify') ?>")
.load(function() {
if (!this.complete || typeof this.naturalWidth == "undefined" || this.naturalWidth == 0) {
alert('验证码图片加载出错,请刷新');
} else {
$(".validate-img").html('').append(img);
}
});
return false;
});
$('#login_form').submit(function(e) {
e.preventDefault();
var formValues = $(this).serialize();
$.ajax({
url: $(this).attr('action') ? $(this).attr('action') : document.URL,
type: $(this).attr('method'),
data: formValues,
beforeSend: function() {
$('button[type=submit]').button('loading');
return true;
},
success: function(data) {
//成功状态,下面的是服务器返回的,数据库操作的状态
var type;
if (data.status === 1) {
type = "success";
} else {
type = "error";
//在登录按钮下面显示错误信息,并清空验证码字段
$('.error-info').text(data.info);
if ($('a.validate-img').length) {
$('input[name="verify"]').val('');
}
}
if (type === 'success') {
//成功则跳转到返回的网址
setTimeout(function() {
window.location = data.url;
});
} else {
//如果type=error则不能执行跳转需重新填写重新启用提交按钮
$('button[type=submit]').button('reset');
//如果超过三次需要验证码,而验证码域未建立,则刷新页面以显示验证码
if (data.verify_show && !$('a.validate-img').length) {
location.reload(true);
}
//若验证码域已存在,则重新载入新的验证码
if ($('a.validate-img').length) {
$('a.validate-img').trigger('click');
}
}
},
error: function() {
$('.error-info').text('提交出错,请检查网络或浏览器设置');
},
});
});
});
</script>
%} @section:css{%
<style>
html,
body {
height: 100%;
font-family: "SimSun","Microsoft Yahei";
}
.background {
position: fixed;
width: 100%;
height: 100%;
background: url('__PUBLIC__/img/admin-login-bg.jpg') no-repeat center;
background-size: cover;
}
.login-page {
height: 100%;
margin: 0 auto;
display: table;
position: relative;
z-index: 1000;
}
#login_form {
margin: 20px 0 30px;
}
a.validate-img img{
width: 100%;
height: auto;
}
.error-info{
margin-top: 10px;
text-align: center;
}
.inner-login-page {
display: table-cell;
vertical-align: middle;
}
.slogan p {
font-size: 28px;
color: #fff;
margin-bottom: 10px;
text-shadow: 1px 1px 1px #000;
}
.login-form-box {
background-color: #fff;
border-radius: 5px;
padding: 20px 35px
}
.login-form-box .header {
padding: 10px;
text-align: center;
font-size: 22px;
font-weight: normal;
}
/*input{*/
/* border-radius: 0!important;*/
/*}*/
.login-form-box .body,
.login-form-box .footer {
padding: 10px 20px;
color: #444;
}
.login-form-box .body > .form-group,
.login-form-box .footer > .form-group {
margin-top: 20px;
}
.login-form-box .body > .form-group > input,
.login-form-box .footer > .form-group > input {
border: #fff;
}
.login-form-box .body > .btn,
.login-form-box .footer > .btn {
margin-bottom: 10px;
}
.login-form-box .footer {}
.btn-mtx {
background-color: #017ffc;
color: #ffffff;
border-radius: 0;
}
.btn.btn-mtx:focus,
.btn.btn-mtx:hover,
.btn.btn-mtx:active,
.btn.btn-mtx.hover {
background-color: #0167f0;
color: #ffffff;
}
/*new styles start*/
.background{
background-image: unset;
background-color: #f0f8ff;
}
.inner-login-page>.container{
border-radius: 9px;
max-width: 970px;
overflow: hidden;
}
.login-form-box{
margin-left: 45px;
position: relative;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
border-radius: 0;
}
.login-form-box .header{
font-size: 28px;
color: #333;
font-weight: bold;
margin-bottom: 28px;
padding: 0 10px;
overflow : hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
line-height: 1.2;
}
.login-form-box form{
width: 100%;
}
.login-form-box .form-group{
position: relative;
margin-bottom: 30px;
}
.login-form-box .form-group input[name=verify]{
padding-left: 20px;
}
.login-form-box .form-group .validate-img{
line-height: 60px;
}
.login-form-box .login-form-icon{
position: absolute;
top: 50%;
left: 30px;
}
.login-form-box .icon-login-user{
margin-top: -10px;
}
.login-form-box .icon-login-lock{
margin-top: -12px;
}
.login-form-box input[type=text],
.login-form-box input[type=password]{
border-radius: 50px;
padding-left: 60px;
font-size: 16px;
}
.login-form-box input[type=text],
.login-form-box input[type=password],
.login-form-box .btn-mtx{
height: 55px;
}
.login-form-box .btn-mtx{
font-size: 18px;
border-radius: 50px;
margin-top: 40px;
background-image: -moz-linear-gradient( 90deg, rgb(11,156,221) 0%, rgb(32,135,253) 100%);
background-image: -webkit-linear-gradient( 90deg, rgb(11,156,221) 0%, rgb(32,135,253) 100%);
background-image: -ms-linear-gradient( 90deg, rgb(11,156,221) 0%, rgb(32,135,253) 100%);
background-image: linear-gradient( 90deg, rgb(11,156,221) 0%, rgb(32,135,253) 100%);
box-shadow: 0 12px 60px 0 rgba(119, 117, 183, 0.2);
}
.login-form-box .btn-mtx:focus{
outline: none;
}
.tech-provider{
position: absolute;
bottom: 20px;
width: 100%;
left: 0;
color: #939499;
font-size: 16px;
margin-bottom: 0;
line-height: 1.5;
}
.tech-provider a{
color: #0f98e4;
}
@media screen and (min-width: 768px) {
.inner-login-page>.container{
box-shadow: 0 12px 60px 0 rgba(114, 110, 212, 0.2);
}
.inner-login-page>.container>.row{
background: rgb(255, 255, 255);
border-radius: 4px;
background-image: url('__PUBLIC__/img/admin-login.png');
background-size: auto 100%;
background-repeat: no-repeat;
}
.login-form-box{
height: 550px;
max-width: 360px;
padding: 0;
}
.login-form-box input[type=text],
.login-form-box input[type=password]{
border: 1px solid #ebecf0;
background-color: #f2f4fc;
box-shadow: unset;
}
}
@media (min-width: 768px) and (max-width: 991px) {
.login-form-box{
height: 450px;
padding: 0 30px;
}
.login-form-box .header{
font-size: 26px;
margin-bottom: 20px;
}
.login-form-box form{
width: 100%;
}
.login-form-box .form-group{
position: relative;
margin-bottom: 25px;
}
.login-form-box .form-group input[name=verify]{
padding-left: 15px;
}
.login-form-box .form-group .validate-img{
line-height: 45px;
}
.login-form-box .login-form-icon{
position: absolute;
top: 50%;
left: 15px;
}
.login-form-box input[type=text],
.login-form-box input[type=password],
.login-form-box .btn-mtx{
height: 45px;
}
.login-form-box input[type=text],
.login-form-box input[type=password]{
padding-left: 40px;
}
.login-form-box .btn-mtx{
margin-top: 35px;
}
.tech-provider{
font-size: 14px;
bottom: 10px;
}
}
@media screen and (max-width: 767px) {
.login-page{
padding-top: 2.35rem;
width: 5.6rem;
}
.login-page .inner-login-page{
display: block;
}
.login-page .inner-login-page .container{
}
.login-page .inner-login-page .login-bg{
display: none !important;
}
.login-form-box {
margin-left: auto;
margin-right: auto;
background-color: transparent;
}
.login-form-box .form-group{
margin-bottom: .4rem;
}
.background{
background-color: #fff;
background-image: url(__PUBLIC__/img/bg-admin-login-mobile.png);
background-repeat: no-repeat;
background-size: 100% auto;
background-position: center bottom;
}
.login-form-box{
height: calc(100vh - 2.35rem);
justify-content: flex-start;
padding: 0;
}
.login-form-box .header{
font-size: .42rem;
line-height: 1.5;
margin-bottom: .7rem;
}
.login-form-box .login-form-icon{
left: .3rem;
}
.icon-login-user-mobile{
width: .34rem;
height: .36rem;
margin-top: -.18rem;
}
.icon-login-lock-mobile{
width: .33rem;
height: .41rem;
margin-top: -.2rem;
}
.login-form-box input[type=text],
.login-form-box input[type=password],
.login-form-box .btn-mtx{
height: .9rem;
}
.login-form-box .form-group .validate-img{
line-height: .9rem;
}
.login-form-box input[type=text],
.login-form-box input[type=password]{
padding-left: .85rem;
height: .9rem;
font-size: .28rem;
}
.login-form-box .btn-mtx{
margin-top: .65rem;
box-shadow: 0 6px 9px 0 rgba(20, 46, 185, 0.16);
}
.login-form-box .form-group .validate-img{
display: block;
}
.tech-provider{
font-size: .24rem;
bottom: .35rem;
}
}
@media (min-width: 489px) and (max-width: 767px) {
.login-page{
padding-top: 1.4rem;
width: 4.6rem;
}
.login-form-box{
height: calc(100vh - 1.4rem);
}
.login-form-box .header{
font-size: .32rem;
}
.login-form-box .form-group{
margin-bottom: .3rem;
}
.login-form-box input[type=text],
.login-form-box input[type=password],
.login-form-box .btn-mtx{
height: .6rem;
}
.login-form-box input[type=text],
.login-form-box input[type=password]{
font-size: .24rem;
padding-left: .7rem;
}
.login-form-box .form-group .validate-img{
line-height: .6rem;
}
.login-form-box .login-form-icon{
height: .3rem;
margin-top: -.15rem;
width: auto;
}
.login-form-box .btn-mtx{
margin-top: .45rem;
}
.tech-provider{
bottom: .2rem;
}
}
/*new styles end*/
</style>
%}

View File

@ -0,0 +1,80 @@
<extend name="Admin@default/common/dashboard_layout"/>
<block name="content">
<form class="ajax-form" action="" method="post">
<!-- Content Header (Page header) -->
<section class="content-header clearfix">
<h1 class="pull-left">新增用户组</h1>
<div class="pull-right">
<button class="btn btn-primary btn-sm" type="submit"><i class="fa fa-save"></i> 提交</button>
</div>
</section>
<!-- Main content -->
<section class="content" n-id="36">
<div class="box box-solid">
<div class="box-body">
<div class="form-group">
<label for="name">用户组名称<span class="required"></span></label>
<input type="text" class="form-control" name="name" id="name" required max="12" min="1">
</div>
<div class="form-group">
<label for="remark">备注:</label>
<textarea class="form-control" name="remark" id="remark"></textarea>
</div>
<div class="form-group">
<label for="">用户组权限:</label>
<volist name='module_list' id='module'>
<p>{$module.title}</p>
<volist name='controller_list' id='controller'>
<if condition="($controller['pid'] eq $module['id'])">
<table class="table table-bordered action_list">
<tr>
<th><input type="checkbox" class="checkall"> {$controller.title}</th>
</tr>
<tr>
<td>
<volist name='action_list' id='action' >
<if condition="($action['pid'] eq $controller['id'])">
<label class="margin action-item" for="auth_{$action.id}"><input class="action_item" id="auth_{$action.id}" name="auth[]" value="{$action.id}" type="checkbox"> {$action.title}</label>
</if>
</volist>
</td>
</tr>
</table>
</if>
</volist>
</volist>
</div>
</div><!-- /.box-body -->
</div>
</section><!-- /.content -->
</form>
</block>
<block name="script">
<script type="text/javascript" src="__PUBLIC__/libs/bootstrap-validator/validator.js"></script>
<script type="text/javascript" src="__PUBLIC__/libs/bootstrap-validator/bootstrap-validator.js"></script>
<script type="text/javascript">
jQuery(document).ready(function($){
$('input,select,textarea').bs_validator();
$('table.action_list').each(function(){
var $allItems = $(this).find('input.action_item');
var $allItemsChecked = $allItems.filter(':checked');
if($allItems.length!=0 && ($allItems.length == $allItemsChecked.length)){
$(this).find('input.checkall').prop('checked',true);
}
});
$('input.checkall').on('change',function(){
var $allItems = $(this).parents('table.action_list').find('input.action_item');
if($(this).prop('checked')){
$allItems.prop('checked',true);
}
else{
$allItems.prop('checked',false);
}
});
});
</script>
</block>

View File

@ -0,0 +1,80 @@
<extend name="Admin@default/common/dashboard_layout"/>
<block name="content">
<form class="ajax-form" action="" method="post">
<!-- Content Header (Page header) -->
<section class="content-header clearfix">
<h1 class="pull-left">修改用户组</h1>
<div class="pull-right">
<button class="btn btn-primary btn-sm" type="submit"><i class="fa fa-save"></i> 提交</button>
</div>
</section>
<!-- Main content -->
<section class="content" n-id="36">
<div class="box box-solid">
<input type="hidden" name="id" value="{$vo.id}" />
<div class="box-body">
<div class="form-group">
<label for="name">用户组名称<span class="required"></span></label>
<input type="text" class="form-control" id="name" name="name" required max="12" min="1" value="{$vo.name}">
</div>
<div class="form-group">
<label for="remark">备注:</label><br />
<textarea class="form-control" name="remark" id="remark">{$vo.remark}</textarea>
</div>
<div class="form-group">
<label for="">用户组权限:</label>
<volist name='module_list' id='module'>
<p>{$module.title}</p>
<volist name='controller_list' id='controller'>
<if condition="($controller['pid'] eq $module['id'])">
<table class="table table-bordered action_list">
<tr>
<th><input type="checkbox" class="checkall"> {$controller.title}</th>
</tr>
<tr>
<td>
<volist name='action_list' id='action' >
<if condition="($action['pid'] eq $controller['id'])">
<label class="margin action-item" for="auth_{$action.id}"><input class="action_item" id="auth_{$action.id}" name="auth[]" value="{$action.id}" type="checkbox" <in name="action.id" value="$vo.auth">checked="true"</in> /> {$action.title}</label>
</if>
</volist>
</td>
</tr>
</table>
</if>
</volist>
</volist>
</div>
</div><!-- /.box-body -->
</div>
</section><!-- /.content -->
</form>
</block>
<block name="script">
<script type="text/javascript" src="__PUBLIC__/libs/bootstrap-validator/validator.js"></script>
<script type="text/javascript" src="__PUBLIC__/libs/bootstrap-validator/bootstrap-validator.js"></script>
<script type="text/javascript">
jQuery(document).ready(function($){
$('input,select,textarea').bs_validator();
$('table.action_list').each(function(){
var $allItems = $(this).find('input.action_item');
var $allItemsChecked = $allItems.filter(':checked');
if($allItems.length!=0 && ($allItems.length == $allItemsChecked.length)){
$(this).find('input.checkall').prop('checked',true);
}
});
$('input.checkall').on('change',function(){
var $allItems = $(this).parents('table.action_list').find('input.action_item');
if($(this).prop('checked')){
$allItems.prop('checked',true);
}
else{
$allItems.prop('checked',false);
}
});
});
</script>
</block>

View File

@ -0,0 +1,77 @@
<layout name="Admin@default/common/dashboard_layout" />
<taglib name="Common\TagLib\Gy" />
<!-- Content Header (Page header) -->
<section class="content-header clearfix">
<h1>系统日志</h1>
</section>
<!-- Main content -->
<section class="content" n-id="86">
<div class="row mb-20">
<div class="col-md-5">
</div>
<div class="col-md-7">
<form action="" class="pull-right">
<div class="input-group">
<input type="text" name="search_value" class="form-control input-sm pull-right" style="width: 150px;" value="{:I('get.search_value')}" placeholder="搜索">
<select name="search_key" id="" class="pull-right form-control input-sm" style="width: 120px;">
<option value="act" <eq name='I("get.search_key")' value='act'>selected</eq> >操作方法
</option>
<option value="uid" <eq name='I("get.search_key")' value='uid'>selected</eq> >用户ID
</option>
</select>
<div class="input-group-btn">
<button class="btn btn-sm btn-default"><i class="fa fa-search"></i></button>
</div>
</div>
</form>
</div>
</div>
<div class="box box-solid">
<div class="box-body no-padding">
<table class="table table-hover">
<thead>
<tr>
<th>模块名称</th>
<th>方法名称</th>
<th>消息</th>
<th>用户ID</th>
<th>用户IP</th>
<th>操作时间</th>
<th width="120">操作记录</th>
</tr>
</thead>
<tbody>
<volist name="list" id="log">
<tr>
<td>{$log.modulename}</td>
<td>{$log.actionname}</td>
<td>{$log.message}</td>
<td>{$log.userid}</td>
<td>{$log.userip}</td>
<td>{$log.create_time|date='Y-m-d H:i:s',###}</td>
<td>{$log.opname}</td>
</td>
</tr>
</volist>
</tbody>
</table>
</div><!-- /.box-body -->
</div><!-- /.box -->
<div class="row mt-20">
<div class="col-md-5">
<div class="form-inline">
</div>
</div>
<div class="col-md-7">
<div class="pull-right">
<include file="common/pagination" />
</div>
</div>
</div>
</section><!-- /.content -->

View File

@ -0,0 +1,22 @@
<div class="form-group">
<label>真实姓名:</label>
<p>{$profile.real_name}</p>
<label>邮箱:</label>
<p>{$profile.email}</p>
<label>手机:</label>
<p>{$profile.telephone}</p>
<label>性别:</label>
<p>{$profile.gender}</p>
<label>所在公司/学校:</label>
<p>{$profile.company}</p>
<label>是否参加过EV举办的活动:</label>
<p>{$profile.join_activity}</p>
<label>注册原因:</label>
<p>{$profile.reason}</p>
</div>

View File

@ -0,0 +1,60 @@
<div class="modal fade" id="changepassword" tabindex="-1" role="dialog" aria-labelledby="rePwdModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;</span><span class="sr-only">Close</span></button>
<h4 class="modal-title" id="rePwdModalLabel">修改密码</h4>
</div>
<div class="modal-body">
<form class="ajax-form modal-form" action="{:U('/admin/user/repwd')}" method="post">
<div class="form-group">
<label for="newpassword">新密码</label>
<input type="password" class="form-control mb-10" id="newpassword" name="pwd" placeholder="输入新密码" required min="6" max="12">
<input type="password" class="form-control" id="reNewPassword" name="pwd1" placeholder="请再输入一次" required data-validation-equals="pwd">
<input type="hidden" name="id" id='repwd_user_id' />
</div>
<input type="submit" class="btn btn-primary" value="保存">
<button class="btn btn-default" data-dismiss="modal">取消</button>
</form>
</div>
</div>
</div>
</div>
<div class="modal fade" id="browse" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;</span><span class="sr-only">Close</span></button>
<h4 class="modal-title" id="myModalLabel">用户资料</h4>
</div>
<div class="modal-body">
</div>
</div>
</div>
</div>
<script type="text/javascript">
jQuery(document).ready(function ($) {
$('#changepassword').on('hidden.bs.modal',function(){
$(this).find('input[name=pwd],input[name=pwd1]').val('');
$(this).find('input#agreement').attr('checked',false);
});
$('.repwd-btn').on('click', function () {
var id = $(this).data('id');
$('#repwd_user_id').attr('value', id);
});
$('.browse-btn').on('click', function(){
var uid = $(this).data('id');
$('#browse').find('.modal-body').load("{:U('/admin/user/browse')}" + "?uid=" + uid);
});
});
</script>

View File

@ -0,0 +1,379 @@
<header class="header">
<a href="index.html" class="logo">
<!-- Add the class icon to your logo image or logo icon to add the margining -->
AdminLTE
</a>
<!-- Header Navbar: style can be found in header.less -->
<nav class="navbar navbar-static-top" role="navigation">
<!-- Sidebar toggle button-->
<a href="#" class="navbar-btn sidebar-toggle" data-toggle="offcanvas" role="button">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</a>
<div class="navbar-right">
<ul class="nav navbar-nav">
<!-- Messages: style can be found in dropdown.less-->
<li class="dropdown messages-menu">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
<i class="fa fa-envelope"></i>
<span class="label label-success">4</span>
</a>
<ul class="dropdown-menu">
<li class="header">You have 4 messages</li>
<li>
<!-- inner menu: contains the actual data -->
<ul class="menu">
<li><!-- start message -->
<a href="#">
<div class="pull-left">
<img src="/common/img/avatar3.png" class="img-circle" alt="User Image"/>
</div>
<h4>
Support Team
<small><i class="fa fa-clock-o"></i> 5 mins</small>
</h4>
<p>Why not buy a new awesome theme?</p>
</a>
</li><!-- end message -->
<li>
<a href="#">
<div class="pull-left">
<img src="/common/img/avatar2.png" class="img-circle" alt="user image"/>
</div>
<h4>
AdminLTE Design Team
<small><i class="fa fa-clock-o"></i> 2 hours</small>
</h4>
<p>Why not buy a new awesome theme?</p>
</a>
</li>
<li>
<a href="#">
<div class="pull-left">
<img src="/common/img/avatar.png" class="img-circle" alt="user image"/>
</div>
<h4>
Developers
<small><i class="fa fa-clock-o"></i> Today</small>
</h4>
<p>Why not buy a new awesome theme?</p>
</a>
</li>
<li>
<a href="#">
<div class="pull-left">
<img src="/common/img/avatar2.png" class="img-circle" alt="user image"/>
</div>
<h4>
Sales Department
<small><i class="fa fa-clock-o"></i> Yesterday</small>
</h4>
<p>Why not buy a new awesome theme?</p>
</a>
</li>
<li>
<a href="#">
<div class="pull-left">
<img src="/common/img/avatar.png" class="img-circle" alt="user image"/>
</div>
<h4>
Reviewers
<small><i class="fa fa-clock-o"></i> 2 days</small>
</h4>
<p>Why not buy a new awesome theme?</p>
</a>
</li>
</ul>
</li>
<li class="footer"><a href="#">See All Messages</a></li>
</ul>
</li>
<!-- Notifications: style can be found in dropdown.less -->
<li class="dropdown notifications-menu">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
<i class="fa fa-warning"></i>
<span class="label label-warning">10</span>
</a>
<ul class="dropdown-menu">
<li class="header">You have 10 notifications</li>
<li>
<!-- inner menu: contains the actual data -->
<ul class="menu">
<li>
<a href="#">
<i class="ion ion-ios7-people info"></i> 5 new members joined today
</a>
</li>
<li>
<a href="#">
<i class="fa fa-warning danger"></i> Very long description here that may not fit into the page and may cause design problems
</a>
</li>
<li>
<a href="#">
<i class="fa fa-users warning"></i> 5 new members joined
</a>
</li>
<li>
<a href="#">
<i class="ion ion-ios7-cart success"></i> 25 sales made
</a>
</li>
<li>
<a href="#">
<i class="ion ion-ios7-person danger"></i> You changed your username
</a>
</li>
</ul>
</li>
<li class="footer"><a href="#">View all</a></li>
</ul>
</li>
<!-- Tasks: style can be found in dropdown.less -->
<li class="dropdown tasks-menu">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
<i class="fa fa-tasks"></i>
<span class="label label-danger">9</span>
</a>
<ul class="dropdown-menu">
<li class="header">You have 9 tasks</li>
<li>
<!-- inner menu: contains the actual data -->
<ul class="menu">
<li><!-- Task item -->
<a href="#">
<h3>
Design some buttons
<small class="pull-right">20%</small>
</h3>
<div class="progress xs">
<div class="progress-bar progress-bar-aqua" style="width: 20%" role="progressbar" aria-valuenow="20" aria-valuemin="0" aria-valuemax="100">
<span class="sr-only">20% Complete</span>
</div>
</div>
</a>
</li><!-- end task item -->
<li><!-- Task item -->
<a href="#">
<h3>
Create a nice theme
<small class="pull-right">40%</small>
</h3>
<div class="progress xs">
<div class="progress-bar progress-bar-green" style="width: 40%" role="progressbar" aria-valuenow="20" aria-valuemin="0" aria-valuemax="100">
<span class="sr-only">40% Complete</span>
</div>
</div>
</a>
</li><!-- end task item -->
<li><!-- Task item -->
<a href="#">
<h3>
Some task I need to do
<small class="pull-right">60%</small>
</h3>
<div class="progress xs">
<div class="progress-bar progress-bar-red" style="width: 60%" role="progressbar" aria-valuenow="20" aria-valuemin="0" aria-valuemax="100">
<span class="sr-only">60% Complete</span>
</div>
</div>
</a>
</li><!-- end task item -->
<li><!-- Task item -->
<a href="#">
<h3>
Make beautiful transitions
<small class="pull-right">80%</small>
</h3>
<div class="progress xs">
<div class="progress-bar progress-bar-yellow" style="width: 80%" role="progressbar" aria-valuenow="20" aria-valuemin="0" aria-valuemax="100">
<span class="sr-only">80% Complete</span>
</div>
</div>
</a>
</li><!-- end task item -->
</ul>
</li>
<li class="footer">
<a href="#">View all tasks</a>
</li>
</ul>
</li>
<!-- User Account: style can be found in dropdown.less -->
<li class="dropdown user user-menu">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
<i class="glyphicon glyphicon-user"></i>
<span>Jane Doe <i class="caret"></i></span>
</a>
<ul class="dropdown-menu">
<!-- User image -->
<li class="user-header bg-light-blue">
<img src="/common/img/avatar3.png" class="img-circle" alt="User Image" />
<p>
Jane Doe - Web Developer
<small>Member since Nov. 2012</small>
</p>
</li>
<!-- Menu Body -->
<li class="user-body">
<div class="col-xs-4 text-center">
<a href="#">Followers</a>
</div>
<div class="col-xs-4 text-center">
<a href="#">Sales</a>
</div>
<div class="col-xs-4 text-center">
<a href="#">Friends</a>
</div>
</li>
<!-- Menu Footer-->
<li class="user-footer">
<div class="pull-left">
<a href="#" class="btn btn-default btn-flat">Profile</a>
</div>
<div class="pull-right">
<a href="#" class="btn btn-default btn-flat">Sign out</a>
</div>
</li>
</ul>
</li>
</ul>
</div>
</nav>
</header>
<div class="wrapper row-offcanvas row-offcanvas-left">
<!-- Left side column. contains the logo and sidebar -->
<aside class="left-side sidebar-offcanvas">
<!-- sidebar: style can be found in sidebar.less -->
<section class="sidebar">
<!-- Sidebar user panel -->
<div class="user-panel">
<div class="pull-left image">
<img src="/common/img/avatar3.png" class="img-circle" alt="User Image" />
</div>
<div class="pull-left info">
<p>Hello, Jane</p>
<a href="#"><i class="fa fa-circle text-success"></i> Online</a>
</div>
</div>
<!-- search form -->
<form action="#" method="get" class="sidebar-form">
<div class="input-group">
<input type="text" name="q" class="form-control" placeholder="Search..."/>
<span class="input-group-btn">
<button type='submit' name='seach' id='search-btn' class="btn btn-flat"><i class="fa fa-search"></i></button>
</span>
</div>
</form>
<!-- /.search form -->
<!-- sidebar menu: : style can be found in sidebar.less -->
<ul class="sidebar-menu">
<li class="active">
<a href="index.html">
<i class="fa fa-dashboard"></i> <span>Dashboard</span>
</a>
</li>
<li>
<a href="pages/widgets.html">
<i class="fa fa-th"></i> <span>Widgets</span> <small class="badge pull-right bg-green">new</small>
</a>
</li>
<li class="treeview">
<a href="#">
<i class="fa fa-bar-chart-o"></i>
<span>Charts</span>
<i class="fa fa-angle-left pull-right"></i>
</a>
<ul class="treeview-menu">
<li><a href="pages/charts/morris.html"><i class="fa fa-angle-double-right"></i> Morris</a></li>
<li><a href="pages/charts/flot.html"><i class="fa fa-angle-double-right"></i> Flot</a></li>
<li><a href="pages/charts/inline.html"><i class="fa fa-angle-double-right"></i> Inline charts</a></li>
</ul>
</li>
<li class="treeview">
<a href="#">
<i class="fa fa-laptop"></i>
<span>UI Elements</span>
<i class="fa fa-angle-left pull-right"></i>
</a>
<ul class="treeview-menu">
<li><a href="pages/UI/general.html"><i class="fa fa-angle-double-right"></i> General</a></li>
<li><a href="pages/UI/icons.html"><i class="fa fa-angle-double-right"></i> Icons</a></li>
<li><a href="pages/UI/buttons.html"><i class="fa fa-angle-double-right"></i> Buttons</a></li>
<li><a href="pages/UI/sliders.html"><i class="fa fa-angle-double-right"></i> Sliders</a></li>
<li><a href="pages/UI/timeline.html"><i class="fa fa-angle-double-right"></i> Timeline</a></li>
</ul>
</li>
<li class="treeview">
<a href="#">
<i class="fa fa-edit"></i> <span>Forms</span>
<i class="fa fa-angle-left pull-right"></i>
</a>
<ul class="treeview-menu">
<li><a href="pages/forms/general.html"><i class="fa fa-angle-double-right"></i> General Elements</a></li>
<li><a href="pages/forms/advanced.html"><i class="fa fa-angle-double-right"></i> Advanced Elements</a></li>
<li><a href="pages/forms/editors.html"><i class="fa fa-angle-double-right"></i> Editors</a></li>
</ul>
</li>
<li class="treeview">
<a href="#">
<i class="fa fa-table"></i> <span>Tables</span>
<i class="fa fa-angle-left pull-right"></i>
</a>
<ul class="treeview-menu">
<li><a href="pages/tables/simple.html"><i class="fa fa-angle-double-right"></i> Simple tables</a></li>
<li><a href="pages/tables/data.html"><i class="fa fa-angle-double-right"></i> Data tables</a></li>
</ul>
</li>
<li>
<a href="pages/calendar.html">
<i class="fa fa-calendar"></i> <span>Calendar</span>
<small class="badge pull-right bg-red">3</small>
</a>
</li>
<li>
<a href="pages/mailbox.html">
<i class="fa fa-envelope"></i> <span>Mailbox</span>
<small class="badge pull-right bg-yellow">12</small>
</a>
</li>
<li class="treeview">
<a href="#">
<i class="fa fa-folder"></i> <span>Examples</span>
<i class="fa fa-angle-left pull-right"></i>
</a>
<ul class="treeview-menu">
<li><a href="pages/examples/invoice.html"><i class="fa fa-angle-double-right"></i> Invoice</a></li>
<li><a href="pages/examples/login.html"><i class="fa fa-angle-double-right"></i> Login</a></li>
<li><a href="pages/examples/register.html"><i class="fa fa-angle-double-right"></i> Register</a></li>
<li><a href="pages/examples/lockscreen.html"><i class="fa fa-angle-double-right"></i> Lockscreen</a></li>
<li><a href="pages/examples/404.html"><i class="fa fa-angle-double-right"></i> 404 Error</a></li>
<li><a href="pages/examples/500.html"><i class="fa fa-angle-double-right"></i> 500 Error</a></li>
<li><a href="pages/examples/blank.html"><i class="fa fa-angle-double-right"></i> Blank Page</a></li>
</ul>
</li>
</ul>
</section>
<!-- /.sidebar -->
</aside>
<!-- Right side column. Contains the navbar and content of the page -->
<aside class="right-side">
<!-- Content Header (Page header) -->
<section class="content-header clearfix">
<h1>
<%-title%>
<small><%-smallTitle%></small>
</h1>
</section>
<!-- Main content -->
<section class="content"><%=content%></section><!-- /.content -->
</aside><!-- /.right-side -->
</div><!-- ./wrapper -->

View File

@ -0,0 +1,56 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="renderer" content="webkit">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>{$meta_title}{:C('WEB_SITE_TITLE')}后台管理</title>
<meta content='width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no' name='viewport'>
<link href="__PUBLIC__/libs/bootstrap/bootstrap.css" rel="stylesheet" type="text/css" />
<link href="__PUBLIC__/libs/font-awesome/font-awesome.css" rel="stylesheet" type="text/css" />
<link href="__PUBLIC__/libs/icomoon/icomoon.css" rel="stylesheet" type="text/css" />
<link href="__PUBLIC__/libs/ionicons/ionicons.css" rel="stylesheet" type="text/css" />
<link href="__PUBLIC__/libs/messenger/messenger.css" rel="stylesheet" type="text/css" />
<link href="__PUBLIC__/libs/messenger/messenger-theme-block.css" rel="stylesheet" type="text/css" />
<link href="__PUBLIC__/libs/toastr/toastr.css" rel="stylesheet" type="text/css" />
<link href="__PUBLIC__/libs/perfect-scrollbar/perfect-scrollbar.css" rel="stylesheet" type="text/css" />
<link href="__PUBLIC__/libs/admin/common.css" rel="stylesheet" type="text/css" />
<link rel="stylesheet" type="text/css" href="__PUBLIC__/libs/cui/cui.extend.min.css">
<script type="text/javascript" src="__PUBLIC__/libs/mod.js"></script>
<!-- jQuery 2.0.2 -->
<script src="__PUBLIC__/libs/jquery/jquery.js"></script>
<script src="__PUBLIC__/libs/perfect-scrollbar/perfect-scrollbar.min.js" type="text/javascript"></script>
<script src="__PUBLIC__/libs/underscore/underscore.js" type="text/javascript"></script>
<!-- Bootstrap -->
<script src="__PUBLIC__/libs/bootstrap/bootstrap.js" type="text/javascript"></script>
<script src="__PUBLIC__/libs/icheck/icheck.js" type="text/javascript"></script>
<script src="__PUBLIC__/libs/messenger/messenger.min.js" type="text/javascript"></script>
<script type="text/javascript" src="__PUBLIC__/libs/bootstrap-messagebox/bootstrap-messagebox.js"></script>
<script src="__PUBLIC__/libs/toastr/toastr.min.js" type="text/javascript"></script>
<!-- AdminLTE App -->
<script src="__PUBLIC__/libs/admin/common.js" type="text/javascript"></script>
<!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!--[if lt IE 9]>
<script src="/libs/html5shiv.js"></script>
<script src="__PUBLIC__/libs/respond.min.js"></script>
<![endif]-->
<block name="style"></block>
</head>
<body class="skin-blue fixed">
<include file="Admin@default/common/head" />
<div class="wrapper row-offcanvas row-offcanvas-left">
<include file="Admin@default/common/sidebar" />
<!-- Right side column. Contains the navbar and content of the page -->
<aside class="right-side">
<block name="content"></block>
</aside><!-- /.right-side -->
</div><!-- ./wrapper -->
<block name="script"></block>
</body>
</html>

View File

@ -0,0 +1,41 @@
<header class="header">
<a class="logo">
<!-- Add the class icon to your logo image or logo icon to add the margining -->
{:C('WEB_SITE_TITLE')}
</a>
<!-- Header Navbar: style can be found in header.less -->
<nav class="navbar navbar-static-top" role="navigation">
<!-- Sidebar toggle button-->
<a href="#" class="navbar-btn sidebar-toggle" data-toggle="offcanvas" role="button">
<span class="sr-only">Toggle navigation</span>
<span class="toggle-bar"></span>
<span class="toggle-bar"></span>
<span class="toggle-bar"></span>
</a>
<div class="navbar-container">
<div class="navbar-left">
<volist name="top_menu" id="top">
<div class="navbar-nav <eq name='current_module' value='$top["module"]'>on</eq>"><a href="{$top.url}" class="menu">{$top.title}</a></div>
</volist>
</div>
</div>
<div class="navbar-right">
<ul class="nav navbar-nav">
<!-- User Account: style can be found in dropdown.less -->
<li class="dropdown user user-menu">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
<i class="glyphicon glyphicon-user"></i>
<span>{:getUserName(session(C('USER_AUTH_KEY')))} <i class="caret"></i></span>
</a>
<ul class="dropdown-menu">
<li><a target="_blank" href="{:U('home/index/index')}"><i class="fa fa-home"></i>网站首页</a></li>
<li><a href="{:U('user/editUser')}"><i class="fa fa-edit"></i>修改资料</a></li>
<li><a href="{:U('public/logout')}"><i class="fa fa-power-off"></i>退出</a></li>
</ul>
</li>
</ul>
</div>
</nav>
</header>

View File

@ -0,0 +1 @@

View File

@ -0,0 +1,21 @@
<style>
.error-page{margin:20px auto;}
</style>
<div class="error-page">
<h2 class="headline text-info"> 404</h2>
<div class="error-content">
<h3><i class="fa fa-warning text-yellow"></i> Oops! Page not found.</h3>
<p>
We could not find the page you were looking for.
Meanwhile, you may <a href='../../index.html'>return to dashboard</a> or try using the search form.
</p>
<form class='search-form'>
<div class='input-group'>
<input type="text" name="search" class='form-control' placeholder="Search"/>
<div class="input-group-btn">
<button type="submit" name="submit" class="btn btn-primary"><i class="fa fa-search"></i></button>
</div>
</div><!-- /.input-group -->
</form>
</div><!-- /.error-content -->
</div><!-- /.error-page -->

View File

@ -0,0 +1,28 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="renderer" content="webkit">
<meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1" >
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1.0">
<title>登录 - {:C('WEB_SITE_TITLE')}</title>
<link href="__PUBLIC__/libs/bootstrap/bootstrap.css" rel="stylesheet" type="text/css" />
<link href="__PUBLIC__/libs/toastr/toastr.css" rel="stylesheet" type="text/css" />
<!-- jQuery 2.0.2 -->
<script src="__PUBLIC__/libs/jquery/jquery.js"></script>
<script src="__PUBLIC__/libs/underscore/underscore.js" type="text/javascript"></script>
<script src="__PUBLIC__/libs/bootstrap/bootstrap.js" type="text/javascript"></script>
<script src="__PUBLIC__/libs/toastr/toastr.min.js" type="text/javascript"></script>
<script src="__PUBLIC__/libs/bootstrap-messagebox/bootstrap-messagebox.js" type="text/javascript"></script>
<script src="__PUBLIC__/libs/admin/common.js" type="text/javascript"></script>
{%section:css%}
</head>
<body class="skin-blue">
{__CONTENT__}
{%section:script%}
</body>
</html>

View File

@ -0,0 +1,35 @@
<eq name="pagination.show" value="1">
<ul class="pagination pagination-sm">
<notempty name="pagination.first">
<li><a class="btn {:$pagination['first']['url']=='javascript:;'?'disabled':''}" title="{$pagination['first']['title']}" href="{$pagination['first']['url']}"><!-- <i class="fa fa-angle-double-left"></i> -->
首页
</a></li><!--{$pagination['first']['title']}-->
</notempty>
<notempty name="pagination.prev">
<li><a class="btn {:$pagination['prev']['url']=='javascript:;'?'disabled':''}" title="{$pagination['prev']['title']}" href="{$pagination['prev']['url']}"><!-- <i class="fa fa-angle-left"></i> -->
<!--上一页-->
&lt;
</a></li><!--{$pagination['prev']['title']}-->
</notempty>
<notempty name="pagination.linkPage">
<volist name="pagination.linkPage" id="item">
<li class="{:$item['current']?'active':''}"><a href="{$item.url}">{$item.title}</a></li>
</volist>
<else/>
<li class="active"><a href="__SELF__">1</a></li>
</notempty>
<notempty name="pagination.next">
<li><a class="btn {:$pagination['next']['url']=='javascript:;'?'disabled':''}" title="{$pagination['next']['title']}" href="{$pagination['next']['url']}"><!-- <i class="fa fa-angle-right"></i> -->
<!--下一页-->
&gt;
</a></li><!--{$pagination['next']['title']}-->
</notempty>
<notempty name="pagination.last">
<li><a class="btn {:$pagination['last']['url']=='javascript:;'?'disabled':''}" title="{$pagination['last']['title']}" href="{$pagination['last']['url']}"><!-- <i class="fa fa-angle-double-right"></i> -->
尾页
</a></li><!--{$pagination['last']['title']}-->
</notempty>
<li><span>共{$pagination.totalRows}条数据</span></li>
</ul>
</eq>

View File

@ -0,0 +1,37 @@
<!-- Left side column. contains the logo and sidebar -->
<aside class="left-side sidebar-offcanvas">
<!-- sidebar: style can be found in sidebar.less -->
<section class="sidebar">
<!-- Sidebar user panel -->
<include file="Admin@default/common/user-panel" />
<!-- search form -->
<!-- <form action="#" method="get" class="sidebar-form">
<div class="input-group">
<input type="text" name="q" class="form-control" placeholder="搜索..."/>
<span class="input-group-btn">
<button type='submit' name='seach' id='search-btn' class="btn btn-flat"><i class="fa fa-search"></i></button>
</span>
</div>
</form>-->
<!-- /.search form -->
<!-- sidebar menu: : style can be found in sidebar.less -->
<ul class="sidebar-menu">
<php>\Think\Hook::listen('adminMenuBefore', $menu_list);</php>
<volist name="menu_list" id="menu">
<li class="treeview">
<a href="#">
<i class="fa {$menu.icon}"></i> <span>{$menu.title}</span>
<i class="fa fa-angle-left pull-right"></i>
</a>
<ul class="treeview-menu">
<volist name="menu['node_list']" id="node">
<li n-id="{$node.id}"><a href="{$node.url}"><i class="fa fa-angle-double-right"></i> {$node.title}</a></li>
</volist>
</ul>
</li>
</volist>
</ul>
</section>
<!-- /.sidebar -->
</aside>

View File

@ -0,0 +1,8 @@
<div class="user-panel">
<div class="image">
<a href="{:U('/admin/dashboard/index')}"><img src="{:showFileUrl(C('CONFIG_WEBSITE_LOGO'))}"></a>
</div>
<!-- <div class="info">
<p>{:C('WEB_SITE_TITLE')}</p>
</div>-->
</div>

1
app/Admin/View/index.html Executable file
View File

@ -0,0 +1 @@

View File

@ -0,0 +1,55 @@
<?php
namespace Admin\Widget;
use Think\Controller;
class AuthCheckWidget extends Controller{
private $_controller_public_methods;
public function index($module){
echo ob_get_clean();
$this->_controller_public_methods = $this->_getControllerPublicMethods();
flushWebContent('开始检测 ' . $module . '权限点<br /><br />');
flushWebContent('脱离权限控制的访问入口如下:<br /><br />');
$files = array();
searchDir(APP_PATH . ucfirst($module) . '/' . C('DEFAULT_C_LAYER'), $files);
foreach($files as $file){
if(preg_match('/(\w+)Controller.class.php$/', basename($file), $matches)){
$controller_name = $matches[1];
flushWebContent('<p style="color:red">' . $controller_name . ':</p>');
$class = new \ReflectionClass(parse_res_name($controller_name, C('DEFAULT_C_LAYER'), C('CONTROLLER_LEVEL')));
$methods = $class->getMethods();
foreach($methods as $method){
$method_name = $method->getName();
if($method->isPublic() && $method->isUserDefined() && !in_array($method_name, $this->_controller_public_methods)){
if(!D('Node')->isExistsNode($module, $controller_name, $method_name)){
flushWebContent($method_name . '<br />');
}
}
}
flushWebContent('<br />');
}
}
}
private function _getControllerPublicMethods(){
$class = new \ReflectionClass('\Think\Controller');
$methods = $class->getMethods();
$public_methods = array();
foreach($methods as $method){
$method_name = $method->getName();
if($method->isPublic()){
$public_methods[] = $method_name;
}
}
return $public_methods;
}
}

1
app/Admin/Widget/index.html Executable file
View File

@ -0,0 +1 @@

1
app/Admin/index.html Executable file
View File

@ -0,0 +1 @@

View File

@ -0,0 +1,36 @@
<?php
namespace Api\Controller;
use Think\Controller;
class AreaController extends Controller{
public function getArea(){
$area = M('Area');
$area_ents = $area->select();
echo json_encode($area_ents);
}
public function getProvince(){
$map['level'] = 1;
$province_list = D('Area')->where($map)->field('id,cname')->select();
$this->ajaxReturn($province_list);
}
public function getCityByProvince($province_id){
$map['upid'] = $province_id;
$map['level'] = 2;
$city_list = D('Area')->where($map)->field('id,cname1')->select();
$this->ajaxReturn($city_list);
}
public function getDistrictByCity($city_id){
$map['upid'] = $city_id;
$map['level'] = 3;
$district_list = D('Area')->where($map)->field('id,cname')->select();
$this->ajaxReturn($district_list);
}
}

View File

@ -0,0 +1,25 @@
<?php
/**
* Created by PhpStorm.
* User: 95869
* Date: 2019/3/12
* Time: 9:27
*/
namespace Api\Controller;
use Think\Controller;
class JsLogController extends Controller
{
public function index(){
if (C('JS_ERROR_LOG')){
$data=I('get.');
C('TOKEN_ON',false);
$r=D('JsErrlog')->createAdd($data);
$r===false && $this->error(D('JsErrlog')->getError());
}
echo '';
}
}

View File

@ -0,0 +1,161 @@
<?php
namespace Api\Controller;
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
/**
* @deprecated oss上传功能已在扩展包quansitech/qscmf-formitem-aliyun-oss中实现
**/
class OssUploadController extends \Think\Controller{
public function callBack(){
$r = $this->_verify($body);
if($r === false){
exit();
}
parse_str($body, $body_arr);
$config = C('UPLOAD_TYPE_' . strtoupper($body_arr['upload_type']));
if(!$config){
E('获取不到文件规则config设置');
}
if(!empty($config['mimes'])){
$mimes = explode(',', $config['mimes']);
if(!in_array(strtolower($body_arr['mimeType']), $mimes)){
$this->ajaxReturn(array('err_msg' => '请上传图片'));
}
}
$file_data['url'] = $config['oss_host'] . '/' . $body_arr['filename'] . ($config['oss_style'] ? $config['oss_style'] : '');
$file_data['size'] = $body_arr['size'];
$file_data['cate'] = $body_arr['upload_type'];
$file_data['security'] = $config['security'] ? 1 : 0;
C('TOKEN_ON',false);
$r = D('FilePic')->createAdd($file_data);
if($r === false){
E(D('FilePic')->getError());
}
else{
if($file_data['security'] == 1){
$ali_oss = new \Common\Util\AliOss();
$file_data['url'] = $ali_oss->getOssClient($body_arr['upload_type'])->signUrl($body_arr['filename'], 60);
}
$this->ajaxReturn(array('file_id' => $r, 'file_url' => $file_data['url']));
}
}
public function policyGet($type){
$callbackUrl = HTTP_PROTOCOL . '://' . SITE_URL . '/api/OssUpload/callBack';
$callback_param = array('callbackUrl'=>$callbackUrl,
'callbackBody'=>'filename=${object}&size=${size}&mimeType=${mimeType}&upload_type=${x:upload_type}',
'callbackBodyType'=>"application/x-www-form-urlencoded");
$callback_string = json_encode($callback_param);
$base64_callback_body = base64_encode($callback_string);
$now = time();
$expire = 10;
$end = $now + $expire;
$expiration = gmt_iso8601($end);
$config = C('UPLOAD_TYPE_' . strtoupper($type));
// $sub_name = $this->_getName($config['subName']);
// $pre_path = $config['rootPath'] . $config['savePath'] . $sub_name .'/';
// $save_name = $this->_getName($config['saveName']);
//
// $dir = trim(trim($pre_path . $save_name, '.'), '/');
$dir = \Common\Util\AliOss::genOssObjectName($config);
$condition = array(0=>'content-length-range', 1=>0, 2=> $config['maxSize']);
$conditions[] = $condition;
$start = array(0=>'starts-with', 1=>'$key', 2=>$dir);
$conditions[] = $start;
$arr = array('expiration'=>$expiration,'conditions'=>$conditions);
$policy = json_encode($arr);
$base64_policy = base64_encode($policy);
$string_to_sign = $base64_policy;
$signature = base64_encode(hash_hmac('sha1', $string_to_sign, C('ALIOSS_ACCESS_KEY_SECRET'), true));
$callback_var = json_encode(array('x:upload_type' => $type));
$response = array();
$response['accessid'] = C('ALIOSS_ACCESS_KEY_ID');
$response['host'] = $config['oss_host'];
$response['policy'] = $base64_policy;
$response['signature'] = $signature;
$response['expire'] = $end;
$response['callback'] = $base64_callback_body;
$response['callback_var'] = $callback_var;
if($config['oss_meta']){
$response['oss_meta'] = json_encode($config['oss_meta']);
}
//这个参数是设置用户上传指定的前缀
$response['dir'] = $dir;
$this->ajaxReturn($response);
}
private function _verify(&$body){
$authorizationBase64 = "";
$pubKeyUrlBase64 = "";
if (isset($_SERVER['HTTP_AUTHORIZATION']))
{
$authorizationBase64 = $_SERVER['HTTP_AUTHORIZATION'];
}
if (isset($_SERVER['HTTP_X_OSS_PUB_KEY_URL']))
{
$pubKeyUrlBase64 = $_SERVER['HTTP_X_OSS_PUB_KEY_URL'];
}
if ($authorizationBase64 == '' || $pubKeyUrlBase64 == '')
{
return false;
}
$authorization = base64_decode($authorizationBase64);
$pubKeyUrl = base64_decode($pubKeyUrlBase64);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $pubKeyUrl);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
$pubKey = curl_exec($ch);
if ($pubKey == "")
{
return false;
}
$body = file_get_contents('php://input');
$authStr = '';
$path = $_SERVER['REQUEST_URI'];
$pos = strpos($path, '?');
if ($pos === false)
{
$authStr = urldecode($path)."\n".$body;
}
else
{
$authStr = urldecode(substr($path, 0, $pos)).substr($path, $pos, strlen($path) - $pos)."\n".$body;
}
$ok = openssl_verify($authStr, $authorization, $pubKey, OPENSSL_ALGO_MD5);
if ($ok == 1)
{
return true;
}
else
{
return false;
}
}
}

View File

@ -0,0 +1,153 @@
<?php
namespace Api\Controller;
use Qscmf\Lib\CusUpload;
class UploadController extends \Think\Controller{
// private function uploadBase64($cate){
// $post_key = I('get.post_key');
// $post_data = I('post.');
// $base64_string = $post_data[$post_key];
// $key = 'UPLOAD_TYPE_' . strtoupper($cate);
//
// if(C($key, null, '') == ''){
// $ajax = array(
// 'Status' => 0,
// 'info' => '没有该类型的上传项',
// 'Time_stamp' => time(),
// 'Data' => null
// );
// $this->ajaxReturn($ajax);
// }
//
// $savename = uniqid().'.png';//localResizeIMG压缩后的图片都是jpeg格式
// $image = base64_to_img( $base64_string, $savename );
// $this->ajaxReturn($savename);
// }
private function upload($cate, $owner = 0){
//IMAGE_THUMB_SCALE = 1 ; //等比例缩放类型
//IMAGE_THUMB_FILLED = 2 ; //缩放后填充类型
//IMAGE_THUMB_CENTER = 3 ; //居中裁剪类型
//IMAGE_THUMB_NORTHWEST = 4 ; //左上角裁剪类型
//IMAGE_THUMB_SOUTHEAST = 5 ; //右下角裁剪类型
//IMAGE_THUMB_FIXED = 6 ; //固定尺寸缩放类型
$gets = I('get.');
foreach($gets as $k => $v){
$$k = $v;
}
$key = 'UPLOAD_TYPE_' . strtoupper($cate);
if(C($key, null, '') == ''){
$ajax = array(
'status' => 0,
'info' => '没有该类型的上传项',
'Time_stamp' => time(),
'Data' => null
);
$this->ajaxReturn($ajax);
}
$upload = new CusUpload(C($key));
$info = $upload->upload();
if (!$info) {
$this->error($upload->getError());
} else {
$upload_config = C($key);
$file = array_pop($info);
$file_pic = D('FilePic');
$data['file'] = $file['savepath'] . $file['savename'];
$data['title'] = $file['name'];
$data['size'] = $file['size'];
$data['cate'] = $cate;
$data['mime_type'] = $file['type'];
$data['security'] = isset($upload_config['security']) ? 1 : 0;
$data['owner'] = isset($upload_config['security']) ? ($owner != 0 ? $owner : session(C('USER_AUTH_KEY'))) : 0;
//文件获取失败
if(!$data['file']){
$this->error('文件获取失败,请重新上传');
}
C("TOKEN_ON", false);
$id = $file_pic->createAdd($data);
if ($id === false) {
$this->error($file_pic->getError());
} else {
$para = array($upload_config['rootPath'].$file['savepath'] , $file['savename']);
\Think\Hook::listen('afterUpload', $para);
$file_url = showFileUrl($id);
$data['file_id'] = $id;
$data['url'] = $file_url;
$data['size'] = format_filesize($data['size']);
$ajax = array(
'status' => 1,
'info' => 'success',
'Time_stamp' => time(),
);
$ajax = array_merge($ajax, $data);
$this->ajaxReturn($ajax);
}
}
}
public function __call($method,$args) {
// if(strpos($method, '_') !== false){
// $method_arr = explode('_', $method);
// $type = $method_arr[1];
// if($type == 'base64' && strtolower(substr($method_arr[0],0,6))=='upload'){
// $cate = strtolower(substr($method_arr[0], 6));
// $this->uploadBase64($cate);
// return;
// }
// }
if(strtolower(substr($method,0,6))=='upload') {
$cate = strtolower(substr($method, 6));
$this->upload($cate);
return;
}
parent::__call($method, $args);
}
public function load($file_id){
$file_pic = M('FilePic');
$file_pic_ent = $file_pic->where(array('id' => $file_id))->find();
//检查访问权限
if(session('file_auth_key') != $file_pic_ent['owner']){
header('Content-Type:text/html; charset=utf-8');
exit('非法访问');
}
$imginfo = getimagesize(SECURITY_UPLOAD_DIR. '/' . $file_pic_ent['file']);
if(empty($imginfo)){
forceDownload(SECURITY_UPLOAD_DIR. '/' . $file_pic_ent['file'], $file_pic_ent['title']);
}
else{
showImageByHttp(SECURITY_UPLOAD_DIR. '/' . $file_pic_ent['file']);
}
}
//下载非安全控制文件
public function downloadFile($file_id){
$file_pic = M('FilePic');
$file_pic_ent = $file_pic->where(array('id' => $file_id))->find();
if($file_pic_ent['security'] == 1){
E('非法访问');
}
//统计下载次数
$param = array(\Addons\Stat\StatCont::FILE_DOWNLOAD, 1, $file_id, 'FilePic');
\Think\Hook::listen('stat', $param);
forceDownload(UPLOAD_DIR. '/' . $file_pic_ent['file'], $file_pic_ent['title']);
}
}

1
app/Api/Controller/index.html Executable file
View File

@ -0,0 +1 @@

View File

@ -0,0 +1,115 @@
<?php
namespace Behaviors;
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
use Qscmf\Lib\DBCont;
use Qscmf\Lib\Tp3Resque\Resque;
use Qscmf\Lib\Tp3Resque\Resque\RedisCluster;
use Qscmf\Lib\Tp3Resque\Resque\Event;
class AppInitBehavior extends \Think\Behavior
{
private function _setDBConfigWhileTesting(){
//测试模式数据库配置指向phpunit设置
if(php_sapi_name() == 'cli-server' && file_exists(APP_DIR . '/../phpunit.xml')){
//关闭伪静态才能正确获取PATH_INFO
C('URL_HTML_SUFFIX', '');
$content = file_get_contents(APP_DIR . '/../phpunit.xml');
$phpunit_xml = simplexml_load_string($content);
if($phpunit_xml) {
foreach($phpunit_xml->php->env as $env){
switch($env['name']){
case 'DB_CONNECTION':
C('DB_TYPE', (string)$env['value']);
break;
case 'DB_HOST':
C('DB_HOST', (string)$env['value']);
break;
case 'DB_PORT':
C('DB_PORT', (string)$env['value']);
break;
case 'DB_DATABASE':
C('DB_NAME', (string)$env['value']);
break;
case 'DB_USERNAME':
C('DB_USER', (string)$env['value']);
break;
case 'DB_PASSWORD':
C('DB_PWD', (string)$env['value']);
break;
}
}
}
}
}
public function run(&$parm){
//header安全
header("X-XSS-Protection: 1; mode=block");
header("X-Content-Type-Options: nosniff");
header("Strict-Transport-Security: max-age=31536000; includeSubDomains");
$this->_setDBConfigWhileTesting();
// 处理队列配置
$config = C('QUEUE');
if ($config) {
// 初始化队列服务,使用database(1)
Resque::setBackend(['redis' => $config], $config['database_index']);
// 初始化缓存前缀
if(isset($config['prefix']) && !empty($config['prefix']))
RedisCluster::prefix($config['prefix']);
Event::listen('afterScheduleRun', function($args){
$job_id = $args['job_id'];
$job_desc = $args['job_desc'];
$job = $args['job'];
$param = $args['job_args'];
$queue = $args['queue'];
$schedule_id = $args['schedule_id'];
$data['id'] = $job_id;
$data['job'] = $job;
$data['args'] = json_encode($param);
$data['description'] = $job_desc;
$data['status'] = DBCont::JOB_STATUS_WAITING;
$data['create_date'] = time();
$data['schedule'] = $schedule_id;
$data['queue'] = $queue;
D('Queue')->add($data);
});
Event::listen('addSchedule', function($args){
$id = $args['id'];
$run_time = $args['run_time'];
$preload = $args['preload'];
$data['id'] = $id;
$data['run_time'] = $run_time;
$data['desc'] = $preload['desc'];
$data['preload'] = json_encode($preload);
$data['delete_status'] = DBCont::NO_BOOL_STATUS;
$data['create_date'] = time();
D('Schedule')->add($data);
});
Event::listen('removeSchedule', function($args){
$id = $args['id'];
$ent = D("Schedule")->where(["id" => $id])->find();
$ent["delete_status"] = DBCont::YES_BOOL_STATUS;
D('Schedule')->save($ent);
});
}
}
}

View File

@ -0,0 +1,62 @@
<?php
namespace Behaviors;
use Org\Util\Rbac;
class AuthFilterBehavior extends \Think\Behavior{
private $auth_bundle_regex = '/<(\w+) [^<]+?(auth_bundle=(?:\'|")([^<]+?)(?:\'|"))[^<]*?(\/>|>)/';
private $tag_regex_tpl = '/<{tag}[^<]*?>(?:(?:(?!<div).)*?)<\/{tag}>/';
//查找auth_bundle如找到则提取出tag名称及auth_bundle的值,放入解析函数
public function run(&$param){
$content = preg_replace("/[\t\n\r]+/","",$param);
while(preg_match($this->regex,$content,$matches)){
$content = $this->analyzeAuthValue($content, $matches);
}
}
//解析auth_bundle的值,并返回替换后的$content
private function analyzeAuthValue($content, $matches){
$auth = $matches[3];
if($this->checkAuth($auth)){
return str_replace($matches[2], '', $content);
}
else{
$tag = $matches[1];
$tag_regex = str_replace('{tag}', $tag, $this->tag_regex_tpl);
while(preg_match($tag_regex, $content, $tag_matches)){
}
}
}
private function filterNestedTag($content ){
}
//检查用户有无该权限, 有则返回true, 没有则返回false;
private function checkAuth($auth){
$auth_id = session(C('USER_AUTH_KEY'));
if(!isSession($auth_id)){
return false;
}
list($module_name, $controller_name, $action_name) = split('.', $auth);
$access_list = Rbac::getAccessList($auth_id);
if(isset($access_list[strtoupper($module_name)][strtoupper($controller_name)][strtoupper($action_name)])){
return true;
}
else{
return false;
}
}
}

View File

@ -0,0 +1,27 @@
<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006-2013 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: liu21st <liu21st@gmail.com>
// +----------------------------------------------------------------------
namespace Behaviors;
use Think\Behavior;
// 初始化钩子信息
class CheckThemeBehavior extends Behavior {
// 行为扩展的执行入口必须是run
public function run(&$content){
$mobile_detect = new \Common\Util\Mobile_Detect();
if(!$mobile_detect->isTablet() && $mobile_detect->isMobile() && MODULE_NAME != 'Admin'){
C('DEFAULT_THEME', 'mobile');
}
else{
C('DEFAULT_THEME', 'default');
}
}
}

View File

@ -0,0 +1,50 @@
<?php
namespace Behaviors;
class TemplateSectionBehavior extends \Think\Behavior{
protected $config = array();
protected $section = array();
public function __construct(){
$this->config['tmpl_section'] = C('TMPL_SECTION')?C('TMPL_SECTION'):'/\@section\:(.+?)\{%(.+?)%\}/is';
$this->config['tmpl_section_register'] = C('TMPL_SECTION_REGISTER')?C('TMPL_SECTION_REGISTER'):'/\{\%section:(.+?)\%\}/is';
}
//行为执行入口
public function run(&$param){
// dump($param);
$param = $this->parseSection($param);
$param = $this->parseSectionRegister($param);
// dump($param);
}
protected function parseSectionRegister($content){
// dump($this->section);
$find = preg_match_all($this->config['tmpl_section_register'],$content,$matches);
// dump($matches);
if(!$find) return $content;
for ($i=0; $i < count($matches[0]); $i++) {
if($count = count($this->section[$matches[1][$i]]))
for ($j=0; $j < $count; $j++) {
$content = str_replace($matches[0][$i],$this->section[$matches[1][$i]][$j],$content);
}
else
$content = str_replace($matches[0][$i],'',$content);
}
return $content;
}
// 解析模板中的布局标签
protected function parseSection($content) {
// 读取模板中的布局标签
$find = preg_match_all($this->config['tmpl_section'],$content,$matches);
// dump($matches);
if(!$find) return $content;
//替换Layout标签
for ($i=0; $i < count($matches[0]); $i++) {
$content = str_replace($matches[0][$i],'',$content);
if(!is_array($this->section[$matches[1][$i]])) $this->section[$matches[1][$i]]=array();
array_push($this->section[$matches[1][$i]],$matches[2][$i]);
}
return $content;
}
}

1
app/Behaviors/index.html Executable file
View File

@ -0,0 +1 @@

1
app/Common/Api/index.html Executable file
View File

@ -0,0 +1 @@

View File

@ -0,0 +1,266 @@
<?php
namespace Common\Coder\ADE;
use Common\Coder\Coder;
class ADECoder extends Coder{
public function __construct() {
parent::__construct();
$this->_name = '增删查改快速生成器';
$this->_desc = '可快速生成带有新增删除修改启用禁用的列表功能';
$this->_namespace = str_replace('\\', '/', __NAMESPACE__);
$this->_view = CODER_DIR . '/ADE/View/index.html';
}
public function displayVew($log_id = ''){
$this->assign('meta_title', $this->getName());
$this->assign('id', 'ADE');
if($log_id){
$ent = D('CoderLog')->getOne($log_id);
$this->assign('coder_log', json_decode($ent['content'], true));
$this->assign('log_id', $log_id);
}
$this->display($this->getView());
}
public function logList(){
$model = D('CoderLog');
$map['coder_name'] = 'ADE';
$count = $model->getListForCount($map);
$per_page = C('ADMIN_PER_PAGE_NUM', null, false);
if($per_page === false){
$page = new \Gy_Library\GyPage($count);
}
else{
$page = new \Gy_Library\GyPage($count, $per_page);
}
$data_list = $model->getListForPage($map, $page->nowPage, $page->listRows, 'id desc');
$builder = new \Qscmf\Builder\ListBuilder();
$builder = $builder->setMetaTitle($this->_name . '生成记录')
->addTopButton('delete');
$builder->setNID(301)
->addTableColumn('name', '控制器名称', '', '', false)->addTableColumn('create_date', '创建时间', 'fun', 'date("Y-m-d H:i:s",__data_id__)', false) ->addTableColumn('right_button', '操作', 'btn')
->setTableDataList($data_list)
->setTableDataPage($page->show())
->addRightButton('edit')
->addRightButton('delete')
->display();
}
public function generate($save_flag = ''){
$this->dbname = '';
if(IS_POST){
parent::autoCheckToken();
$data = I('post.');
if($data['log_id']){
$log_data = D('CoderLog')->getOne($data['log_id']);
}
$log_data['coder_name'] = 'ADE';
$log_data['content'] = json_encode($data);
$log_data['create_date'] = time();
$log_data['name'] = $data['controller_name'];
if(isset($log_data['id'])){
D('CoderLog')->save($log_data);
}
else{
D('CoderLog')->add($log_data);
}
if($save_flag){
$this->success('保存成功', U('admin/coder/coderLog', array('id' => 'ADE')));
return;
}
//创建表 begin
$table_maker = new \Gy_Library\TableMaker();
$table_maker->setTableName($data['table_name']);
$show_columns = array();
$add_columns = array();
$select_search = array();
$like_search = array();
$columns = array();
$add_n = 0;
$list_n = 0;
foreach($data['column_name'] as $k => $v){
$column['name'] = $v;
$column['column_type'] = $data['column_type'][$k];
$column['comment'] = $data['comment'][$k];
$column['require'] = $data['require'][$k];
$table_maker->addColumns($column);
$columns[] = $column;
if($data['list_show'][$k] == 1){
$show_columns[] = array(
'name' => $v,
'type' => $data['list_show_type'][$list_n],
'title' => $data['comment'][$k],
'fun' => $data['list_show_fun'][$list_n],
'edit' => ($data['list_edit'][$list_n] == 1)
);
if($data['list_show_select_search'][$list_n] == 1){
$select_search[] = array(
'title' => $data['comment'][$k],
'name' => $v,
'fun' => $data['list_show_select_options_fun'][$list_n]
);
}
if($data['list_show_like_search'][$list_n] == 1){
$like_search[$v] = $data['comment'][$k];
}
$list_n++;
}
if($data['add_show'][$k] == 1){
$add_columns[] = array(
'name' => $v,
'type' => $data['add_show_type'][$add_n],
'title' => $data['comment'][$k],
'options_fun' => $data['add_show_options_fun'][$add_n],
'extra_attr' => $data[$prefix . 'add_show_extra_attr'][$add_n],
'default' => $data[$prefix . 'add_show_default'][$add_n],
'tips' => $data[$prefix. 'add_show_tips'][$add_n]
);
$add_n++;
}
}
if($table_maker->make() === false){
$this->error($table_maker->getError());
}
//创建表 end
//创建model begin
$view = new \Think\View();
$view->assign('table_name', parse_name($data['table_name'], 1));
$view->assign('add_columns', $add_columns);
$view->assign('columns', $columns);
$content = $view->fetch(CODER_DIR . '/ADE/tpl/model.tpl');
$content = "<?php
{$content}";
$file = APP_PATH . 'Common/Model/' . parse_name($data['table_name'], 1) . 'Model' . EXT;
file_put_contents($file,$content);
//创建model end
$nid = $this->_createNode($data);
//创建controller begin
$controller_view = new \Think\View();
$controller_view->assign('controller_name', ucfirst($data['controller_name']));
$controller_view->assign('model_name', parse_name($data['table_name'], 1));
$controller_view->assign('list_title', $data['list_title']);
$controller_view->assign('nid', $nid);
$controller_view->assign('action', array_flip($data['action']));
$controller_view->assign('show_columns', $show_columns);
$controller_view->assign('add_columns', $add_columns);
$controller_view->assign('select_search', $select_search);
$like_search_arr = array();
foreach($like_search as $k=>$v){
$like_search_arr[] = "'{$k}'=>'{$v}'";
}
if($like_search_arr){
$like_search_str = implode(',', $like_search_arr);
$like_search_str = "array({$like_search_str})";
}
$controller_view->assign('like_search', $like_search_str);
$controller_content = $controller_view->fetch(CODER_DIR . '/ADE/tpl/controller.tpl');
$controller_content = "<?php
{$controller_content}";
$file = APP_PATH . 'Admin/Controller/' . ucfirst($data['controller_name']) . 'Controller' . EXT;
file_put_contents($file,$controller_content);
//创建controller end
$this->success('成功');
}
}
private function _createNode($data){
$controller_node_data['name'] = $data['controller_name'];
$controller_node_data['title'] = $data['list_title'] . '管理';
$controller_node_data['status'] = \Gy_Library\DBCont::NORMAL_STATUS;
$controller_node_data['pid'] = 1;
$controller_node_data['level'] = \Gy_Library\DBCont::LEVEL_CONTROLLER;
$controller_id = D('Node')->add($controller_node_data);
$action_node_data['name'] = 'index';
$action_node_data['title'] = $data['list_title'] . '列表';
$action_node_data['status'] = \Gy_Library\DBCont::NORMAL_STATUS;
$action_node_data['sort'] = 0;
$action_node_data['pid'] = $controller_id;
$action_node_data['level'] = \Gy_Library\DBCont::LEVEL_ACTION;
$action_node_data['menu_id'] = $data['menu_id'];
$action_id = D('Node')->add($action_node_data);
if(in_array('add', $data['action'])){
$add_data['name'] = 'add';
$add_data['title'] = '新增';
$add_data['status'] = \Gy_Library\DBCont::NORMAL_STATUS;
$add_data['pid'] = $controller_id;
$add_data['level'] = \Gy_Library\DBCont::LEVEL_ACTION;
D('Node')->add($add_data);
}
if(in_array('edit', $data['action'])){
$edit_data['name'] = 'edit';
$edit_data['title'] = '修改';
$edit_data['status'] = \Gy_Library\DBCont::NORMAL_STATUS;
$edit_data['pid'] = $controller_id;
$edit_data['level'] = \Gy_Library\DBCont::LEVEL_ACTION;
D('Node')->add($edit_data);
}
if(in_array('delete', $data['action'])){
$del_data['name'] = 'delete';
$del_data['title'] = '删除';
$del_data['status'] = \Gy_Library\DBCont::NORMAL_STATUS;
$del_data['pid'] = $controller_id;
$del_data['level'] = \Gy_Library\DBCont::LEVEL_ACTION;
D('Node')->add($del_data);
}
if(in_array('forbid_resume', $data['action'])){
$forbid_data['name'] = 'forbid';
$forbid_data['title'] = '禁用';
$forbid_data['status'] = \Gy_Library\DBCont::NORMAL_STATUS;
$forbid_data['pid'] = $controller_id;
$forbid_data['level'] = \Gy_Library\DBCont::LEVEL_ACTION;
D('Node')->add($forbid_data);
$resume_data['name'] = 'resume';
$resume_data['title'] = '启用';
$resume_data['status'] = \Gy_Library\DBCont::NORMAL_STATUS;
$resume_data['pid'] = $controller_id;
$resume_data['level'] = \Gy_Library\DBCont::LEVEL_ACTION;
D('Node')->add($resume_data);
}
if(in_array('save', $data['action'])){
$save_data['name'] = 'save';
$save_data['title'] = '保存';
$save_data['status'] = \Gy_Library\DBCont::NORMAL_STATUS;
$save_data['pid'] = $controller_id;
$save_data['level'] = \Gy_Library\DBCont::LEVEL_ACTION;
D('Node')->add($save_data);
}
return $action_id;
}
}

View File

@ -0,0 +1,421 @@
<extend name="../app/Admin/View/default/common/dashboard_layout.html"/>
<block name="content">
<form action="/admin/coder/generate/id/ADE" method="post" id="form" class="form-horizontal form builder-form">
<input type="hidden" name="id" value="{$id}"/>
<section class="content-header clearfix">
<h1 class="pull-left">{$meta_title}</h1>
<div class="pull-right">
<a class="btn btn-primary btn-sm" href="{:U('/admin/coder/coderLog', array('id' => 'ADE'))}">生成记录</a>
<button type="button" id="save_btn" class="btn btn-primary btn-sm">保存记录</button>
<button type="submit" class="btn btn-primary btn-sm"><i class="fa fa-save"></i> 生成代码</button>
</div>
</section>
<div class="builder builder-form-box panel-body content" n-id="301">
<input type="hidden" name="log_id" value="{$log_id}" />
<div class="builder-container builder-form-container">
<div class="row">
<div class="col-xs-12">
<div class='form-group'>
<label class="left control-label">控制器名:</label>
<div class="right">
<input type='text' class="form-control input text" name='controller_name' value='{$coder_log.controller_name}' />
</div>
</div>
</div>
<div class="col-xs-12">
<div class='form-group'>
<label class="left control-label">列表标题:</label>
<div class="right">
<input type='text' class="form-control input text" name='list_title' value='{$coder_log.list_title}'/>
</div>
</div>
</div>
<div class="col-xs-12">
<div class='form-group'>
<label class="left control-label">menu_id</label>
<div class="right">
<input type='text' class="form-control input text" name='menu_id' value='{$coder_log.menu_id}' />
</div>
</div>
</div>
<div class="col-xs-12">
<div class='form-group'>
<label class="left control-label">表名:</label>
<div class="right">
<input type='text' class="form-control input text" name='table_name' value='{$coder_log.table_name}'/>
</div>
</div>
</div>
<div class="col-xs-12">
<div class='form-group'>
<input type='checkbox' name='action[]' <php>if(in_array('add', $coder_log['action'])) echo 'checked="true"';</php> value='add'>增
<input type='checkbox' name='action[]' <php>if(in_array('delete', $coder_log['action'])) echo 'checked="true"';</php> value='delete'>删
<input type='checkbox' name='action[]' <php>if(in_array('edit', $coder_log['action'])) echo 'checked="true"';</php> value='edit'>改
<input type='checkbox' name='action[]' <php>if(in_array('forbid_resume', $coder_log['action'])) echo 'checked="true"';</php> value='forbid_resume'>禁/启
<input type='checkbox' name='action[]' <php>if(in_array('save', $coder_log['action'])) echo 'checked="true"';</php> value='save'>保存
</div>
</div>
</div>
<h1>自定义字段:</h1>
<php>$list_show_num = 0;</php>
<php>$add_show_num = 0;</php>
<php>for($cus_i=0;$cus_i<count($coder_log['column_name']);$cus_i++){</php>
<div class='row box box-solid'>
<div class="col-xs-12">
<div class='form-group'>
<label class="left control-label">字段名:</label>
<div class="right">
<input type='text' class="form-control input text" name='column_name[]' value='<php> echo $coder_log["column_name"][$cus_i];</php>' />
</div>
</div>
</div>
<div class="col-xs-12">
<div class='form-group'>
<label class="left control-label">字段类型:</label>
<div class="right">
<input type='text' class="form-control input text" name='column_type[]' value='<php> echo $coder_log["column_type"][$cus_i];</php>'/>
</div>
</div>
</div>
<div class="col-xs-12">
<div class='form-group'>
<label class="left control-label">必填:</label>
<div class="right">
<select name='require[]'>
<option value='1' <php>if($coder_log['require'][$cus_i] == "1") echo 'selected="true"';</php>>是</option>
<option value='0' <php>if($coder_log['require'][$cus_i] == "0") echo 'selected="true"';</php>>否</option>
</select>
</div>
</div>
</div>
<div class="col-xs-12">
<div class='form-group'>
<label class="left control-label">注释:</label>
<div class="right">
<input type='text' class="form-control input text" name='comment[]' value='<php> echo $coder_log["comment"][$cus_i];</php>'/>
</div>
</div>
</div>
<div class="col-xs-12 list_show_div">
<div class='form-group'>
<label class="left control-label">list show?</label>
<div class="right">
<select name='list_show[]' class='list_show'>
<option value='1' <php>if($coder_log['list_show'][$cus_i] == "1") echo 'selected="true"';</php>>是</option>
<option value='0' <php>if($coder_log['list_show'][$cus_i] == "0") echo 'selected="true"';</php>>否</option>
</select>
</div>
</div>
</div>
<php>if($coder_log['list_show'][$cus_i] == "1"){</php>
<div class="col-xs-12 list_show_type_div">
<div class='form-group'>
<label class="left control-label">调用类型:</label>
<div class="right">
<select name="list_show_type[]">
<option value='' <php>if($coder_log['list_show_type'][$list_show_num] == "") echo 'selected="true"';</php>>无</option>
<option value='picture' <php>if($coder_log['list_show_type'][$list_show_num] == "picture") echo 'selected="true"';</php>>图片</option>
<option value='fun' <php>if($coder_log['list_show_type'][$list_show_num] == "fun") echo 'selected="true"';</php>>函数</option>
<option value='status' <php>if($coder_log['list_show_type'][$list_show_num] == "status") echo 'selected="true"';</php>>状态</option>
</select>
</div>
</div>
<div class='form-group'>
<label class="left control-label">调用函数:(只有函数类型需要填写)</label>
<div class="right">
<input type='text' name="list_show_fun[]" value='<php> echo $coder_log["list_show_fun"][$list_show_num];</php>'>
</div>
</div>
<div class='form-group'>
<label class="left control-label">可修改?</label>
<div class="right">
<select name="list_edit[]">
<option value='' <php>if($coder_log['list_edit'][$list_show_num] == "") echo 'selected="true"';</php>>否</option>
<option value='1' <php>if($coder_log['list_edit'][$list_show_num] == "1") echo 'selected="true"';</php>>是</option>
</select>
</div>
</div>
<div class='form-group'>
<label class="left control-label">下拉查询?</label>
<div class="right">
<select name="list_show_select_search[]">
<option value='' <php>if($coder_log['list_show_select_search'][$list_show_num] == "") echo 'selected="true"';</php>>否</option>
<option value='1' <php>if($coder_log['list_show_select_search'][$list_show_num] == "1") echo 'selected="true"';</php>>是</option>
</select>
</div>
</div>
<div class='form-group'>
<label class="left control-label">下拉查询函数?</label>
<div class="right">
<input type='text' name="list_show_select_options_fun[]" value='<php> echo $coder_log["list_show_select_options_fun"][$list_show_num];</php>' />
</div>
</div>
<div class='form-group'>
<label class="left control-label">模糊查询?</label>
<div class="right">
<select name="list_show_like_search[]">
<option value='' <php>if($coder_log['list_show_like_search'][$list_show_num] == "") echo 'selected="true"';</php>>否</option>
<option value='1' <php>if($coder_log['list_show_like_search'][$list_show_num] == "1") echo 'selected="true"';</php>>是</option>
</select>
</div>
</div>
</div>
<php>$list_show_num++;</php>
<php>}</php>
<div class="col-xs-12 add_show_div">
<div class='form-group'>
<label class="left control-label">add show?</label>
<div class="right">
<select name='add_show[]' class='add_show'>
<option value='1' <php>if($coder_log['add_show'][$cus_i] == "1") echo 'selected="true"';</php>>是</option>
<option value='0' <php>if($coder_log['add_show'][$cus_i] == "0") echo 'selected="true"';</php>>否</option>
</select>
</div>
</div>
</div>
<php>if($coder_log['add_show'][$cus_i] == "1"){</php>
<div class="col-xs-12 add_show_type_div">
<div class='form-group'>
<label class="left control-label">字段类型:</label>
<div class="right">
<select name="add_show_type[]">
<volist name=":C('FORM_ITEM_TYPE')" id="type">
<option value='{$key}' <php>if($coder_log['add_show_type'][$add_show_num] == $key) echo 'selected="true"';</php> >{$type.0}</option>
</volist>
</select>
</div>
</div>
<div class='form-group'>
<label class="left control-label">调用函数:(只有checkbox 或者 select等类型需要填写)</label>
<div class="right">
<input type='text' name="add_show_options_fun[]" value='<php> echo $coder_log["add_show_options_fun"][$add_show_num];</php>'>
</div>
</div>
<div class='form-group'>
<label class="left control-label">extra_attr</label>
<div class="right">
<input type='text' name="add_show_extra_attr[]" value='<php> echo $coder_log["add_show_extra_attr"][$add_show_num];</php>'>
</div>
</div>
<div class='form-group'>
<label class="left control-label">默认值</label>
<div class="right">
<input type='text' name="add_show_default[]" value='<php> echo $coder_log["add_show_default"][$add_show_num];</php>'>
</div>
</div>
<div class='form-group'>
<label class="left control-label">tips:</label>
<div class="right">
<input type='text' name="add_show_tips[]" value='<php> echo $coder_log["add_show_tips"][$add_show_num];</php>'>
</div>
</div>
</div>
<php>$add_show_num++;</php>
<php>}</php>
<div class="col-xs-12">
<button type="button" class="btn btn-danger btn-xs pull-right" onclick="$(this).parents('.box').remove();">删除</button>
</div>
</div>
<php>}</php>
<div class='row' id='add-panel'>
<button type="button" class="btn btn-sm btn-default " id="addField">增加一行</button>
</div>
</div>
</div>
</form>
</block>
<block name='script'>
<script id="field" type="text/template">
<div class='row box box-solid'>
<div class="col-xs-12">
<div class='form-group'>
<label class="left control-label">字段名:</label>
<div class="right">
<input type='text' class="form-control input text" name='column_name[]' />
</div>
</div>
</div>
<div class="col-xs-12">
<div class='form-group'>
<label class="left control-label">字段类型:</label>
<div class="right">
<input type='text' class="form-control input text" name='column_type[]' />
</div>
</div>
</div>
<div class="col-xs-12">
<div class='form-group'>
<label class="left control-label">必填:</label>
<div class="right">
<select name='require[]'>
<option value='1'></option>
<option value='0' selected='true'></option>
</select>
</div>
</div>
</div>
<div class="col-xs-12">
<div class='form-group'>
<label class="left control-label">注释:</label>
<div class="right">
<input type='text' class="form-control input text" name='comment[]' />
</div>
</div>
</div>
<div class="col-xs-12 list_show_div">
<div class='form-group'>
<label class="left control-label">list show?</label>
<div class='right'>
<select name='list_show[]' class='list_show'>
<option value='1'></option>
<option value='0' selected='true'></option>
</select>
</div>
</div>
</div>
<div class="col-xs-12 add_show_div">
<div class='form-group'>
<label class="left control-label">add show?</label>
<div class="right">
<select name='add_show[]' class='add_show'>
<option value='1'></option>
<option value='0' selected='true'></option>
</select>
</div>
</div>
</div>
<div class="col-xs-12">
<button type="button" class="btn btn-danger btn-xs pull-right" onclick="$(this).parents('.box').remove();">删除</button>
</div>
</div>
</script>
<script id="add_type_select_field" type="text/template">
<div class="col-xs-12 add_show_type_div">
<div class='form-group'>
<label class="left control-label">字段类型:</label>
<div class="right">
<select name="add_show_type[]">
<volist name=":C('FORM_ITEM_TYPE')" id="type">
<option value='{$key}'>{$type.0}</option>
</volist>
</select>
</div>
</div>
<div class='form-group'>
<label class="left control-label">调用函数:(只有checkbox 或者 select等类型需要填写)</label>
<div class="right">
<input type='text' name="add_show_options_fun[]">
</div>
</div>
<div class='form-group'>
<label class="left control-label">extra_attr</label>
<div class="right">
<input type='text' name="add_show_extra_attr[]">
</div>
</div>
<div class='form-group'>
<label class="left control-label">默认值</label>
<div class="right">
<input type='text' name="add_show_default[]">
</div>
</div>
<div class='form-group'>
<label class="left control-label">tips:</label>
<div class="right">
<input type='text' name="add_show_tips[]">
</div>
</div>
</div>
</script>
<script id="list_type_select_field" type="text/template">
<div class="col-xs-12 list_show_type_div">
<div class='form-group'>
<label class="left control-label">调用类型:</label>
<div class="right">
<select name="list_show_type[]">
<option value=''></option>
<option value='picture'>图片</option>
<option value='fun'>函数</option>
<option value='status'>状态</option>
</select>
</div>
</div>
<div class='form-group'>
<label class="left control-label">调用函数:(只有函数类型需要填写)</label>
<div class="right">
<input type='text' name="list_show_fun[]">
</div>
</div>
<div class='form-group'>
<label class="left control-label">可修改?</label>
<div class="right">
<select name="list_edit[]">
<option value=''></option>
<option value='1'></option>
</select>
</div>
</div>
<div class='form-group'>
<label class="left control-label">下拉查询?</label>
<div class="right">
<select name="list_show_select_search[]">
<option value=''></option>
<option value='1'></option>
</select>
</div>
</div>
<div class='form-group'>
<label class="left control-label">下拉查询函数?</label>
<div class="right">
<input type='text' name="list_show_select_options_fun[]" />
</div>
</div>
<div class='form-group'>
<label class="left control-label">模糊查询?</label>
<div class="right">
<select name="list_show_like_search[]">
<option value=''></option>
<option value='1'></option>
</select>
</div>
</div>
</div>
</script>
<script type="text/javascript">
jQuery(document).ready(function ($) {
$('#save_btn').click(function(){
$('#form').attr('action','/admin/coder/save');
$('#form').submit();
});
$('#addField').click(function () {
$($('#field').clone().html()).insertBefore('#add-panel');
});
$('.builder').on('change', '.add_show', function(){
if($(this).val() == 1){
$(this).parents('.add_show_div').after($('#add_type_select_field').clone().html());
}
else{
$(this).parents('.add_show_div').next().remove();
}
});
$('.builder').on('change', '.list_show', function(){
if($(this).val() == 1){
$(this).parents('.list_show_div').after($('#list_type_select_field').clone().html());
}
else{
$(this).parents('.list_show_div').next().remove();
}
});
});
</script>
</block>

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

View File

@ -0,0 +1,235 @@
namespace Admin\Controller;
use Gy_Library\GyListController;
use Gy_Library\DBCont;
//自动生成代码
class {$controller_name}Controller extends GyListController{
public function index(){
$get_data = I('get.');
$map = array();
<volist name="select_search" id="select">
if(isset($get_data['{$select.name}'])){
$map['{$select.name}'] = $get_data['{$select.name}'];
}
</volist>
<notempty name="like_search" id="like">
if(isset($get_data['key']) && $get_data['word']){
$map[$get_data['key']] = array('like', '%' . $get_data['word'] . '%');
}
</notempty>
$model = D('{$model_name}');
$count = $model->getListForCount($map);
$per_page = C('ADMIN_PER_PAGE_NUM', null, false);
if($per_page === false){
$page = new \Gy_Library\GyPage($count);
}
else{
$page = new \Gy_Library\GyPage($count, $per_page);
}
$data_list = $model->getListForPage($map, $page->nowPage, $page->listRows, 'id desc');
$builder = new \Qscmf\Builder\ListBuilder();
$builder = $builder->setMetaTitle('{$list_title}管理');
<volist name='select_search' id='select'>
$builder->addSearchItem('{$select.name}', 'select', '所有{$select.title}', {:showHtmlContent($select['fun'])});
</volist>
<notempty name='like_search'>
$builder->addSearchItem('', 'select_text', '搜索内容', {$like_search});
</notempty>
<present name='action.add'>
$builder->addTopButton('addnew');
</present>
<present name='action.forbid_resume'>
$builder->addTopButton('forbid')
->addTopButton('resume');
</present>
<present name='action.delete'>
$builder->addTopButton('delete');
</present>
<present name='action.save'>
$builder->addTopButton('save');
</present>
$builder->setNID({$nid})
<volist name='show_columns' id='column'>
->addTableColumn('{$column.name}', '{$column.title}', '{$column.type}', '{:showHtmlContent(str_replace("'", '"', $column["fun"]))}', <eq name='column.edit' value='true'>true<else/>false</eq>)
</volist>
->addTableColumn('right_button', '操作', 'btn')
->setTableDataList($data_list)
->setTableDataPage($page->show())
<present name='action.edit'>
->addRightButton('edit')
</present>
<present name='action.forbid_resume'>
->addRightButton('forbid')
</present>
<present name='action.delete'>
->addRightButton('delete')
</present>
->display();
}
<present name='action.save'>
public function save(){
if(IS_POST){
$data = I('post.');
foreach($data['id'] as $k=>$v){
<volist name='show_columns' id='column'>
<eq name='column.edit' value='true'>
$save_data['{$column.name}'] = $data['{$column.name}'][$k];
</eq>
</volist>
D('{$model_name}')->where('id=' . $v)->save($save_data);
}
$this->success('保存成功', U('index'));
}
}
</present>
<present name='action.add'>
public function add(){
if (IS_POST) {
parent::autoCheckToken();
$data = I('post.');
$model = D('{$model_name}');
$r = $model->createAdd($data);
if($r === false){
$this->error($model->getError());
}
else{
sysLogs('新增{$list_title}id:' . $r);
$this->success(l('add') . l('success'), U(CONTROLLER_NAME . '/index'));
}
}
else {
$builder = new \Qscmf\Builder\FormBuilder();
$data_list = array(
<volist name="add_columns" id="column">
<neq name="column.default" value="">
"{$column.name}"=>{$column.default},
</neq>
</volist>
);
if($data_list){
$builder->setFormData($data_list);
}
$builder->setMetaTitle('新增{$list_title}')
->setNID({$nid})
->setPostUrl(U('add'))
<volist name='add_columns' id='column'>
->addFormItem('{$column.name}', '{$column.type}', '{$column.title}','{$column.tips}', <empty name='column.options_fun'>''<else/>{:showHtmlContent($column["options_fun"])}</empty><notempty name="column.extra_attr">,'',"{:showHtmlContent(str_replace('"', "'", $column["extra_attr"]))}"</notempty>)
</volist>
->display();
}
}
</present>
<present name='action.edit'>
public function edit($id){
if (IS_POST) {
parent::autoCheckToken();
$m_id = I('post.id');
$data = I('post.');
$model = D('{$model_name}');
if(!$m_id){
E('缺少{$list_title}ID');
}
$ent = $model->getOne($m_id);
if(!$ent){
E('不存在{$list_title}');
}
<volist name='add_columns' id='column'>
$ent['{$column.name}'] = $data['{$column.name}'];
</volist>
if($model->createSave($ent) === false){
$this->error($model->getError());
}
else{
sysLogs('修改{$list_title}id:' . $m_id);
$this->success('修改成功', U('index'));
}
} else {
$info = D('{$model_name}')->getOne($id);
$builder = new \Qscmf\Builder\FormBuilder();
$builder->setMetaTitle('编辑{$list_title}')
->setPostUrl(U('edit'))
->setNID({$nid})
->addFormItem('id', 'hidden', 'ID')
<volist name='add_columns' id='column'>
->addFormItem('{$column.name}', '{$column.type}', '{$column.title}', '{$column.tips}', <empty name='column.options_fun'>''<else/>{:showHtmlContent($column["options_fun"])}</empty><notempty name="column.extra_attr">,'',"{:showHtmlContent(str_replace('"', "'", $column["extra_attr"]))}"</notempty>)
</volist>
->setFormData($info)
->display();
}
}
</present>
<present name='action.forbid_resume'>
public function forbid(){
$ids = I('ids');
if(!$ids){
$this->error('请选择要禁用的数据');
}
$r = parent::_forbid($ids);
if($r !== false){
sysLogs('{$list_title}id: ' . $ids . ' 禁用');
$this->success('禁用成功', U(CONTROLLER_NAME . '/index'));
}
else{
$this->error($this->_getError());
}
}
public function resume(){
$ids = I('ids');
if(!$ids){
$this->error('请选择要启用的数据');
}
$r = parent::_resume($ids);
if($r !== false){
sysLogs('{$list_title}id: ' . $ids . ' 启用');
$this->success('启用成功', U(CONTROLLER_NAME . '/index'));
}
else{
$this->error($this->_getError());
}
}
</present>
<present name='action.delete'>
public function delete(){
$ids = I('ids');
if(!$ids){
$this->error('请选择要删除的数据');
}
$r = parent::_del($ids);
if($r === false){
$this->error($this->_getError());
}
else{
sysLogs('{$list_title}id: ' . $ids . ' 删除');
$this->success('删除成功', U(MODULE_NAME . '/' . CONTROLLER_NAME . '/index'));
}
}
</present>
}

View File

@ -0,0 +1,26 @@
namespace Common\Model;
//自动生成代码
class {$table_name}Model extends \Gy_Library\GyListModel{
protected $_validate = array(
<volist name='columns' id='col'>
<eq name="col.require" value="1">
array('{$col.name}', 'require', '{$col.comment}必填'),
</eq>
</volist>
);
protected $_auto = array(
<volist name='add_columns' id='column'>
<eq name="column.type" value="date">
array('{$column.name}', 'strtotime', parent::MODEL_BOTH, 'function'),
<else/>
<eq name="column.type" value="datetime">
array('{$column.name}', 'strtotime', parent::MODEL_BOTH, 'function'),
</eq>
</eq>
</volist>
);
}

Some files were not shown because too many files have changed in this diff Show More