韵味同城API接口
parent
5338e29167
commit
151dd9fdd3
|
@ -0,0 +1,42 @@
|
|||
sudo: false
|
||||
|
||||
language: php
|
||||
|
||||
branches:
|
||||
only:
|
||||
- stable
|
||||
|
||||
cache:
|
||||
directories:
|
||||
- $HOME/.composer/cache
|
||||
|
||||
before_install:
|
||||
- composer self-update
|
||||
|
||||
install:
|
||||
- composer install --no-dev --no-interaction --ignore-platform-reqs
|
||||
- zip -r --exclude='*.git*' --exclude='*.zip' --exclude='*.travis.yml' ThinkPHP_Core.zip .
|
||||
- composer require --update-no-dev --no-interaction "topthink/think-image:^1.0"
|
||||
- composer require --update-no-dev --no-interaction "topthink/think-migration:^1.0"
|
||||
- composer require --update-no-dev --no-interaction "topthink/think-captcha:^1.0"
|
||||
- composer require --update-no-dev --no-interaction "topthink/think-mongo:^1.0"
|
||||
- composer require --update-no-dev --no-interaction "topthink/think-worker:^1.0"
|
||||
- composer require --update-no-dev --no-interaction "topthink/think-helper:^1.0"
|
||||
- composer require --update-no-dev --no-interaction "topthink/think-queue:^1.0"
|
||||
- composer require --update-no-dev --no-interaction "topthink/think-angular:^1.0"
|
||||
- composer require --dev --update-no-dev --no-interaction "topthink/think-testing:^1.0"
|
||||
- zip -r --exclude='*.git*' --exclude='*.zip' --exclude='*.travis.yml' ThinkPHP_Full.zip .
|
||||
|
||||
script:
|
||||
- php think unit
|
||||
|
||||
deploy:
|
||||
provider: releases
|
||||
api_key:
|
||||
secure: TSF6bnl2JYN72UQOORAJYL+CqIryP2gHVKt6grfveQ7d9rleAEoxlq6PWxbvTI4jZ5nrPpUcBUpWIJHNgVcs+bzLFtyh5THaLqm39uCgBbrW7M8rI26L8sBh/6nsdtGgdeQrO/cLu31QoTzbwuz1WfAVoCdCkOSZeXyT/CclH99qV6RYyQYqaD2wpRjrhA5O4fSsEkiPVuk0GaOogFlrQHx+C+lHnf6pa1KxEoN1A0UxxVfGX6K4y5g4WQDO5zT4bLeubkWOXK0G51XSvACDOZVIyLdjApaOFTwamPcD3S1tfvuxRWWvsCD5ljFvb2kSmx5BIBNwN80MzuBmrGIC27XLGOxyMerwKxB6DskNUO9PflKHDPI61DRq0FTy1fv70SFMSiAtUv9aJRT41NQh9iJJ0vC8dl+xcxrWIjU1GG6+l/ZcRqVx9V1VuGQsLKndGhja7SQ+X1slHl76fRq223sMOql7MFCd0vvvxVQ2V39CcFKao/LB1aPH3VhODDEyxwx6aXoTznvC/QPepgWsHOWQzKj9ftsgDbsNiyFlXL4cu8DWUty6rQy8zT2b4O8b1xjcwSUCsy+auEjBamzQkMJFNlZAIUrukL/NbUhQU37TAbwsFyz7X0E/u/VMle/nBCNAzgkMwAUjiHM6FqrKKBRWFbPrSIixjfjkCnrMEPw=
|
||||
file:
|
||||
- ThinkPHP_Core.zip
|
||||
- ThinkPHP_Full.zip
|
||||
skip_cleanup: true
|
||||
on:
|
||||
tags: true
|
|
@ -0,0 +1,838 @@
|
|||
|
||||
## V5.1.34 LTS(2019-1-30)
|
||||
|
||||
本次更新为常规更新,修正了一些反馈的问题。
|
||||
|
||||
* 改进Request类的`has`方法,支持`patch`
|
||||
* 改进`unique`验证的多条件支持
|
||||
* 修复自定义上传验证,检测文件大小
|
||||
* 改进`in`查询支持表达式
|
||||
* 改进路由的`getBind`方法
|
||||
* 改进验证类的错误信息获取
|
||||
* 改进`response`助手函数默认值
|
||||
* 修正mysql的`regexp`查询
|
||||
* 改进模型类型强制转换写入对`Expression`对象的支持
|
||||
|
||||
## V5.1.33 LTS(2019-1-16)
|
||||
|
||||
* 修复路由中存在多个相同替换的正则BUG
|
||||
* 修正whereLike查询
|
||||
* join方法支持参数绑定
|
||||
* 改进union方法
|
||||
* 修正多对多关联的attach方法
|
||||
* 改进验证类的正则规则自定义
|
||||
* 改进Request类method方法
|
||||
* 改进File日志类型的CLI日志写入
|
||||
* 改进文件日志time_format配置对JSON格式的支持
|
||||
|
||||
## V5.1.32 LTS(2018-12-24)
|
||||
|
||||
本次主要为常规更新,修正了一些反馈的问题。
|
||||
|
||||
|
||||
* 改进多对多关联的`attach`方法
|
||||
* 改进聚合查询的`field`处理
|
||||
* 改进关联的`save`方法
|
||||
* 修正模型`exists`方法返回值
|
||||
* 改进时间字段写入和输出
|
||||
* 改进控制器中间件的调用
|
||||
* 改进路由变量替换的性能
|
||||
* 改进缓存标签的处理机制
|
||||
|
||||
## V5.1.31 LTS (2018-12-9)
|
||||
|
||||
本次版本包含一个安全更新,建议升级。
|
||||
|
||||
* 改进`field`方法
|
||||
* 改进`count`方法返回类型
|
||||
* `download`函数增加在浏览器中显示文件功能
|
||||
* 修正多对多模型的中间表数据写入
|
||||
* 改进`sqlsrv`驱动支持多个Schemas模式查询
|
||||
* 统一助手函数与\think\response\Download函数文件过期时间
|
||||
* 完善关联模型的`save`方法 增加`make`方法仅创建对象不保存
|
||||
* 修改条件表达式对静态变量的支持
|
||||
* 修正控制器名获取
|
||||
* 改进view方法的`field`解析
|
||||
|
||||
## V5.1.30 LTS(2018-11-30)
|
||||
|
||||
该版本为常规更新,修正了一些社区反馈的问题。
|
||||
|
||||
主要更新如下:
|
||||
|
||||
* 改进查询类的`execute`方法
|
||||
* 判断路由规则定义添加对请求类型的判断
|
||||
* 修复`orderRaw`异常
|
||||
* 修正 `optimize:autoload`指令
|
||||
* 改进软删除的`destroy`方法造成重复执行事件的问题
|
||||
* 改进验证类对扩展验证规则 始终验证 不管是否`require`
|
||||
* 修复自定义验证`remove`所有规则的异常
|
||||
* 改进时间字段的自动写入支持微秒数据
|
||||
* 改进`Connection`类的`getrealsql`方法
|
||||
* 修正`https`地址的URL生成
|
||||
* 修复 `array_walk_recursive` 在低于PHP7.1消耗内部指针问题
|
||||
* 改进手动参数绑定使用
|
||||
* 改进聚合查询方法的`field`参数支持`Expression`
|
||||
|
||||
## V5.1.29 LTS(2018-11-11)
|
||||
|
||||
该版本主要改进了参数绑定的解析问题和提升性能,并修正了一些反馈的问题。
|
||||
|
||||
* 改进手动参数绑定
|
||||
* 修正MISS路由的分组参数无效问题
|
||||
* 行为支持对象的方法
|
||||
* 修正全局查询范围
|
||||
* 改进`belongsto`关联的`has`方法
|
||||
* 改进`hasMany`关联
|
||||
* 改进模型观察者多次注册的问题
|
||||
* 改进`query`类的默认查询参数处理
|
||||
* 修正`parseBetween`解析方法
|
||||
* 改进路由地址生成的本地域名支持
|
||||
* 改进参数绑定的实际URL解析性能
|
||||
* 改进`Env`类的`getEnv`和`get`方法
|
||||
* 改进模板缓存的生成优化
|
||||
* 修复验证类的多语言支持
|
||||
* 修复自定义场景验证`remove`规则异常
|
||||
* File类添加是否自动补全扩展名的选项
|
||||
* 改进`strpos`对子串是否存在的判断
|
||||
* 修复`choice`无法用值选择第一个选项问题
|
||||
* 验证器支持多维数组取值验证
|
||||
* 改进解析`extend`和`block`标签的正则
|
||||
|
||||
## V5.1.28 LTS(2018-10-29)
|
||||
|
||||
该版本主要修正了上一个版本存在的一些问题,并改进了关联查询
|
||||
|
||||
* 改进聚合查询方法的字段支持DISTINCT
|
||||
* 改进定义路由后url函数的端口生成
|
||||
* 改进控制器中间件对`swoole`等的支持
|
||||
* 改进Log类`save`方法
|
||||
* 改进验证类的闭包验证参数
|
||||
* 多对多关联支持指定中间表数据的名称
|
||||
* 关联聚合查询支持闭包方式指定聚合字段
|
||||
* 改进Lang类`get`方法
|
||||
* 多对多关联增加判断关联数据是否存在的方法
|
||||
* 改进关联查询使用`fetchsql`的情况
|
||||
* 改进修改器的是否已经执行判断
|
||||
* 增加`afterWith`和`beforeWith`验证规则 用于比较日期字段
|
||||
|
||||
## V5.1.27 LTS(2018-10-22)
|
||||
|
||||
该版本主要修正了路由绑定的参数,改进了修改器的执行多次问题,并正式宣布为LTS版本!
|
||||
|
||||
|
||||
* 修正路由绑定的参数丢失问题
|
||||
* 修正路由别名的参数获取
|
||||
* 改进修改器会执行多次的问题
|
||||
|
||||
## V5.1.26(2018-10-12)
|
||||
|
||||
该版本主要修正了上一个版本的一些问题,并改进了全局查询范围的支持,同时包含了一个安全更新。
|
||||
|
||||
|
||||
* 修正单一模块下注解路由无效的问题
|
||||
* 改进数据库的聚合查询的字段处理
|
||||
* 模型类增加`globalScope`属性定义 用于指定全局的查询范围
|
||||
* 模型的`useGlobalScope`方法支持传入数组 用于指定当前查询需要使用的全局查询范围
|
||||
* 改进数据集的`order`方法对数字类型的支持
|
||||
* 修正上一个版本`order`方法解析的一处BUG
|
||||
* 排序字段不合法或者错误的时候抛出异常
|
||||
* 改进`Request`类的`file`方法对上传文件的错误判断
|
||||
|
||||
## V5.1.25(2018-9-21)
|
||||
|
||||
该版本主要改进了查询参数绑定的性能和对浮点型的支持,以及一些细节的完善。
|
||||
|
||||
* 修正一处命令行问题
|
||||
* 改进`Socketlog`日志驱动,支持自定义默认展开日志类别
|
||||
* 修正`MorphMany`一处bug
|
||||
* 跳转到上次记住的url,并支持默认值
|
||||
* 改进模型的异常提示
|
||||
* 改进参数绑定对浮点型的支持
|
||||
* 改进`order`方法解析
|
||||
* 改进`json`字段数据的自动编码
|
||||
* 改进日志`log_write`可能造成的日志写入死循环
|
||||
* Log类增加`log_level`行为标签位置,用于对某个类型的日志进行处理
|
||||
* Route类增加`clear`方法清空路由规则
|
||||
* 分布式数据库配置支持使用数组
|
||||
* 单日志文件也支持`max_files`参数
|
||||
* 改进查询参数绑定的性能
|
||||
* 改进别名路由的URL后缀参数检测
|
||||
* 控制器前置方法和控制器中间件的`only`和`except`定义不区分大小写
|
||||
|
||||
## V5.1.24(2018-9-5)
|
||||
|
||||
该版本主要增加了命令行的表格输出功能,并增加了查看路由定义的指令,以及修正了社区的一些反馈问题。
|
||||
|
||||
* 修正`Request`类的`file`方法
|
||||
* 修正路由的`cache`方法
|
||||
* 修正路由缓存的一处问题
|
||||
* 改进上传文件获取的异常处理
|
||||
* 改进`fetchCollection`方法支持传入数据集类名
|
||||
* 修正多级控制器的注解路由生成
|
||||
* 改进`Middleware`类`clear`方法
|
||||
* 增加`route:list`指令用于[查看定义的路由](752690) 并支持排序
|
||||
* 命令行增加`Table`输出类
|
||||
* `Command`类增加`table`方法用于输出表格
|
||||
* 改进搜索器查询方法支持别名定义
|
||||
* 命令行配置增加`auto_path`参数用于定义自动载入的命令类路径
|
||||
* 增加`make:command`指令用于[快速生成指令](354146)
|
||||
* 改进`make:controller`指令对操作方法后缀的支持
|
||||
* 改进命令行的定义文件支持索引数组 用于指令对象的惰性加载
|
||||
* 改进`value`和`column`方法对后续查询结果的影响
|
||||
* 改进`RuleName`类的`setRule`方法
|
||||
|
||||
## V5.1.23(2018-8-23)
|
||||
|
||||
该版本主要改进了数据集对象的处理,增加了`findOrEmpty`方法,并且修正了一些社区反馈的BUG。
|
||||
|
||||
* 数据集类增加`diff`/`intersect`方法用于获取差集和交集(默认根据主键值比较)
|
||||
* 数据集类增加`order`方法支持指定字段排序
|
||||
* 数据集类增加`map`方法使用回调函数处理数据并返回新的数据集对象
|
||||
* Db增加`allowEmpty`方法允许`find`方法在没有数据的时候返回空数组或者空模型对象而不是null
|
||||
* Db增加`findOrEmpty`方法
|
||||
* Db增加`fetchCollection`方法用于指定查询返回数据集对象
|
||||
* 改进`order`方法的数组方式解析,增强安全性
|
||||
* 改进`withSearch`方法,支持第三个参数传入字段前缀标识,用于多表查询字段搜索
|
||||
* 修正`optimize:route`指令开启类库后缀后的注解路由生成
|
||||
* 修正redis缓存及session驱动
|
||||
* 支持指定`Yaconf`的独立配置文件
|
||||
* 增加`yaconf`助手函数用于配置文件
|
||||
|
||||
|
||||
## V5.1.22(2018-8-9)
|
||||
|
||||
该版本主要增加了模型搜索器和`withJoin`方法,完善了模型输出和对`Yaconf`的支持,修正了一些社区反馈的BUG。
|
||||
|
||||
* 改进一对一关联的`table`识别问题
|
||||
* 改进内置`Facade`类
|
||||
* 增加`withJoin`方法支持`join`方式的[一对一关联](一对一关联.md)查询
|
||||
* 改进`join`预载入查询的空数据问题
|
||||
* 改进`Config`类的`load`方法支持快速加载配置文件
|
||||
* 改进`execute`方法和事务的断线重连
|
||||
* 改进`memcache`驱动的`has`方法
|
||||
* 模型类支持定义[搜索器](搜索器.md)方法
|
||||
* 完善`Config`类对`Yaconf`的支持
|
||||
* 改进模型的`hidden/visible/append/withAttr`方法,支持在[查询前后调用](数组访问.md),以及支持数据集对象
|
||||
* 数据集对象增加`where`方法根据字段或者关联数据[过滤数据](模型数据集.md)
|
||||
* 改进AJAX请求的`204`判断
|
||||
|
||||
|
||||
## V5.1.21(2018-8-2)
|
||||
|
||||
该版本主要增加了下载响应对象和数组查询对象的支持,并修正了一些社区反馈的问题。
|
||||
|
||||
* 改进核心对象的无用信息调试输出
|
||||
* 改进模型的`isRelationAttr`方法判断
|
||||
* 模型类的`get`和`all`方法并入Db类
|
||||
* 增加[下载响应对象](文件下载.md)和`download`助手函数
|
||||
* 修正别名路由配置定义读取
|
||||
* 改进`resultToModel`方法
|
||||
* 修正开启类库后缀后的注解路由生成
|
||||
* `Response`类增加`noCache`快捷方法
|
||||
* 改进路由对象在`Swoole`/`Workerman`下面参数多次合并问题
|
||||
* 修正路由`ajax`/`pjax`参数后路由变量无法正确获取的问题
|
||||
* 增加清除中间件的方法
|
||||
* 改进依赖注入的参数规范自动识别(便于对接前端小写+下划线规范)
|
||||
* 改进`hasWhere`的数组条件的字段判断
|
||||
* 增加[数组查询对象](高级查询.md)`Where`支持(喜欢数组查询的福音)
|
||||
* 改进多对多关联的闭包支持
|
||||
|
||||
## V5.1.20(2018-7-25)
|
||||
|
||||
该版本主要增加了Db和模型的动态获取器的支持,并修正了一些已知问题。
|
||||
|
||||
* Db类添加[获取器支持](703981)
|
||||
* 支持模型及关联模型字段[动态定义获取器](354046)
|
||||
* 动态获取器支持`JSON`字段
|
||||
* 改进路由的`before`行为执行(匹配后执行)
|
||||
* `Config`类支持`Yaconf`
|
||||
* 改进Url生成的端口问题
|
||||
* Request类增加`setUrl`和`setBaseUrl`方法
|
||||
* 改进页面trace的信息显示
|
||||
* 修正`MorphOne`关联
|
||||
* 命令行添加[查看版本指令](703994)
|
||||
|
||||
## V5.1.19 (2018-7-13)
|
||||
|
||||
该版本是一个小幅改进版本,针对`Swoole`和`Workerman`的`Cookie`支持做了一些改进,并修正了一些已知的问题。
|
||||
|
||||
|
||||
* 改进query类`delete`方法对软删除条件判断
|
||||
* 修正分表查询的软删除问题
|
||||
* 模型查询的时候同时传入`table`和`name`属性
|
||||
* 容器类增加`IteratorAggregate`和`Countable`接口支持
|
||||
* 路由分组支持对下面的资源路由统一设置`only/except/vars`参数
|
||||
* 改进Cookie类更好支持扩展
|
||||
* 改进Request类`post`方法
|
||||
* 改进模型自关联的自动识别
|
||||
* 改进Request类对`php://input`数据的处理
|
||||
|
||||
|
||||
## V5.1.18 (2018-6-30)
|
||||
|
||||
该版本主要完善了对`Swoole`和`Workerman`的`HttpServer`运行支持,改进`Request`类,并修正了一些已知的问题。
|
||||
|
||||
* 改进关联`append`方法的处理
|
||||
* 路由初始化和检测方法分离
|
||||
* 修正`destroy`方法强制删除
|
||||
* `app_init`钩子位置移入`run`方法
|
||||
* `think-swoole`扩展更新到2.0版本
|
||||
* `think-worker`扩展更新到2.0版本
|
||||
* 改进Url生成的域名自动识别
|
||||
* `Request`类增加`setPathinfo`方法和`setHost`方法
|
||||
* `Request`类增加`withGet`/`withPost`/`withHeader`/`withServer`/`withCookie`/`withEnv`方法进行赋值操作
|
||||
* Route类改进`host`属性的获取
|
||||
* 解决注解路由配置不生效的问题
|
||||
* 取消Test日志驱动,改为使用`close`设置关闭全局日志写入
|
||||
* 修正路由的`response`参数
|
||||
* 修正204响应输出的判断
|
||||
|
||||
## V5.1.17 (2018-6-18)
|
||||
|
||||
该版本主要增加了控制器中间件的支持,改进了路由功能,并且修正了社区反馈的一些问题。
|
||||
|
||||
* 修正软删除的`delete`方法
|
||||
* 修正Query类`Count`方法
|
||||
* 改进多对多`detach`方法
|
||||
* 改进Request类`Session`方法
|
||||
* 增加控制器中间件支持
|
||||
* 模型类增加`jsonAssoc`属性用于定义json数据是否返回数组
|
||||
* 修正Request类`method`方法的请求伪装
|
||||
* 改进静态路由的匹配
|
||||
* 分组首页路由自动完整匹配
|
||||
* 改进sqlsrv的`column`方法
|
||||
* 日志类的`apart_level`配置支持true自动生成对应类型的日志文件
|
||||
* 改进`204`输出判断
|
||||
* 修正cli下页面输出的BUG
|
||||
* 验证类使用更高效的`ctype`验证机制
|
||||
* 改进Request类`cookie`方法
|
||||
* 修正软删除的`withTrashed`方法
|
||||
* 改进多态一对多的预载入查询
|
||||
* 改进Query类`column`方法的缓存读取
|
||||
* Query类增加`whereBetweenTimeField`方法
|
||||
* 改进分组下多个相同路由规则的合并匹配问题
|
||||
* 路由类增加`getRule`/`getRuleList`方法获取定义的路由
|
||||
|
||||
## V5.1.16 (2018-6-7)
|
||||
|
||||
该版本主要修正了社区反馈的一些问题,并对Request类做了进一步规范和优化。
|
||||
|
||||
* 改进Session类的`boot`方法
|
||||
* App类的初始化方法可以单独执行
|
||||
* 改进Request类的`param`方法
|
||||
* 改进资源路由的变量替换
|
||||
* Request类增加`__isset`方法
|
||||
* 改进`useGlobalScope`方法对软删除的影响
|
||||
* 修正命令行调用
|
||||
* 改进Cookie类`init`方法
|
||||
* 改进多对多关联删除的返回值
|
||||
* 一对多关联写入支持`replace`
|
||||
* 路由增加`filter`检测方法,用于通过请求参数检测路由是否匹配
|
||||
* 取消Request类`session/env/server`方法的`filter`参数
|
||||
* 改进关联的指定属性输出
|
||||
* 模型删除操作删除后不清空对象数据仅作标记
|
||||
* 调整模型的`save`方法返回值为布尔值
|
||||
* 修正Request类`isAjax`方法
|
||||
* 修正中间件的模块配置读取
|
||||
* 取消Request类的请求变量的设置功能
|
||||
* 取消请求变量获取的默认修饰符
|
||||
* Request类增加`setAction/setModule/setController`方法
|
||||
* 关联模型的`delete`方法调用Query类
|
||||
* 改进URL生成的域名识别
|
||||
* 改进URL检测对已定义路由的域名判断
|
||||
* 模型类增加`isExists`和`isForce`方法
|
||||
* 软删除的`destroy`和`restore`方法返回值调整为布尔值
|
||||
|
||||
## V5.1.15 (2018-6-1)
|
||||
|
||||
该版本主要改进了路由缓存的性能和缓存方式设置,增加了JSON格式文件日志的支持,并修正了社区反馈的一些问题。
|
||||
|
||||
* 容器类增加`exists`方法 仅判断是否存在对象实例
|
||||
* 取消配置类的`autoload`方法
|
||||
* 改进路由缓存大小提高性能
|
||||
* 改进Dispatch类`init`方法
|
||||
* 增加`make:validate`指令生成验证器类
|
||||
* Config类`get`方法支持默认值参数
|
||||
* 修正字段缓存指令
|
||||
* 改进App类对`null`数据的返回
|
||||
* 改进模型类的`__isset`方法判断
|
||||
* 修正`Query`类的`withAggregate`方法
|
||||
* 改进`RuleItem`类的`setRuleName`方法
|
||||
* 修正依赖注入和参数的冲突问题
|
||||
* 修正Db类对第三方驱动的支持
|
||||
* 修正模型类查询对象问题
|
||||
* 修正File缓存驱动的`has`方法
|
||||
* 修正资源路由嵌套
|
||||
* 改进Request类对`$_SERVER`变量的读取
|
||||
* 改进请求缓存处理
|
||||
* 路由缓存支持指定单独的缓存方式和参数
|
||||
* 修正资源路由的中间件多次执行问题
|
||||
* 修正`optimize:config`指令
|
||||
* 文件日志支持`JSON`格式日志保存
|
||||
* 修正Db类`connect`方法
|
||||
* 改进Log类`write`方法不会自动写入之前日志
|
||||
* 模型的关联操作默认启用事务
|
||||
* 改进软删除的事件响应
|
||||
|
||||
## V5.1.14 (2018-5-18)
|
||||
|
||||
该版本主要对底层容器进行了一些优化改进,并增加了路由缓存功能,可以进一步提升路由性能。
|
||||
|
||||
* 依赖注入的对象参数传入改进
|
||||
* 改进核心类的容器实例化
|
||||
* 改进日期字段的读取
|
||||
* 改进验证类的`getScene`方法
|
||||
* 模型的`create`方法和`save`方法支持`replace`操作
|
||||
* 改进`Db`类的调用机制
|
||||
* App类调整为容器类
|
||||
* 改进容器默认绑定
|
||||
* `Loader`类增加工厂类的实例化方法
|
||||
* 增加路由变量默认规则配置参数
|
||||
* 增加路由缓存设计
|
||||
* 错误处理机制改进
|
||||
* 增加清空路由缓存指令
|
||||
|
||||
|
||||
## V5.1.13 (2018-5-11)
|
||||
|
||||
该版本主要增加了MySQL的XA事务支持,模型事件支持观察者,以及对Facade类的改进。
|
||||
|
||||
* 改进自动缓存
|
||||
* 改进Url生成
|
||||
* 修正数据缓存
|
||||
* 修正`value`方法的缓存
|
||||
* `join`方法和`view`方法的条件支持使用`Expression`对象
|
||||
* 改进驱动的`parseKey`方法
|
||||
* 改进Request类`host`方法和`domain`方法对端口的处理
|
||||
* 模型增加`withEvent`方法用于控制当前操作是否需要执行模型事件
|
||||
* 模型`setInc/setDec`方法支持更新事件
|
||||
* 模型添加`before_restore/after_restore`事件
|
||||
* 增加模型事件观察者
|
||||
* 路由增加`mobile`方法设置是否允许手机访问
|
||||
* 数据库XA事务支持
|
||||
* 改进索引数组查询对`IN`查询的支持
|
||||
* 修正`invokeMethod`方法
|
||||
* 修正空数据写入返回值的BUG
|
||||
* redis驱动支持`predis`
|
||||
* 改进`parseData`方法
|
||||
* 改进模块加载
|
||||
* App类初始化方法调整
|
||||
* 改进数组查询对表达式`Expression`对象支持
|
||||
* 改进闭包的依赖注入调用
|
||||
* 改进多对多关联的中间表模型更新
|
||||
* 增加容器中对象的自定义实例化
|
||||
|
||||
## V5.1.12 (2018-4-25)
|
||||
|
||||
该版本主要改进了主从查询的及时性,并支持动态设置请求数据。
|
||||
|
||||
* 支持动态设置请求数据
|
||||
* 改进`comment`方法解析
|
||||
* 修正App类`__unset`方法
|
||||
* 改进url生成的域名绑定
|
||||
* 改进主从查询的及时性
|
||||
* 修正`value`的数据缓存功能
|
||||
* 改进分页类的集合对象方法调用
|
||||
* 改进Db类的代码提示
|
||||
* SQL日志增加主从标记
|
||||
|
||||
## V5.1.11 (2018-4-19)
|
||||
|
||||
该版本为安全和修正版本,改进了JSON查询的参数绑定问题和容器类对象实例获取,并包含一处可能的安全隐患,建议更新。
|
||||
|
||||
* 支持指定JSON数据查询的字段类型
|
||||
* 修正`selectInsert`方法
|
||||
* `whereColumn`方法支持数组方式
|
||||
* 改进容器类`make`方法
|
||||
* 容器类`delete`方法支持数组
|
||||
* 改进`composer`自动加载
|
||||
* 改进模板引擎
|
||||
* 修正`like`查询的一处安全隐患
|
||||
|
||||
## V5.1.10 (2018-4-16)
|
||||
|
||||
该版本为修正版本,修正上一个版本的一些BUG,并增强了`think clear`指令。
|
||||
|
||||
* 改进`orderField`方法
|
||||
* 改进`exists`查询
|
||||
* 修改cli模式入口文件位置计算
|
||||
* 修正`null`查询
|
||||
* 改进`parseTime`方法
|
||||
* 修正关联预载入查询
|
||||
* 改进`mysql`驱动
|
||||
* 改进`think clear`指令 支持 `-c -l -r `选项
|
||||
* 改进路由规则对`/`结尾的支持
|
||||
|
||||
## V5.1.9 (2018-4-12)
|
||||
|
||||
该版本主要是一些改进和修正,并包含一个安全更新,是一个推荐更新版本。
|
||||
|
||||
* 默认模板渲染规则支持配置保持操作方法名
|
||||
* 改进`Request`类的`ip`方法
|
||||
* 支持模型软删除字段的默认值定义
|
||||
* 改进路由变量规则对中文的支持
|
||||
* 使用闭包查询的时候使用`cache(true)` 抛出异常提示
|
||||
* 改进`Loader`类`loadComposerAutoloadFiles`方法
|
||||
* 改进查询方法安全性
|
||||
* 修正路由地址中控制器名驼峰问题
|
||||
* 调整上一个版本的`module_init`和`app_begin`的钩子顺序问题
|
||||
* 改进CLI命令行执行的问题
|
||||
* 修正社区反馈的其它问题
|
||||
|
||||
## V5.1.8 (2018-4-5)
|
||||
|
||||
该版本主要改进了中间件的域名和模块支持,并同时修正了几个已知问题。
|
||||
|
||||
* 增加`template.auto_rule` 参数设置默认模板渲染的操作名自动转换规则
|
||||
* 默认模板渲染规则改由视图驱动实现
|
||||
* 修正路由标识定义
|
||||
* 修正控制器路由方法
|
||||
* 改进Request类`ip`方法支持自定义代理IP参数
|
||||
* 路由注册中间件支持数组方式别名
|
||||
* 改进命令行执行下的`composer`自动加载
|
||||
* 添加域名中间件注册支持
|
||||
* 全局中间件支持模块定义文件
|
||||
* Log日志配置支持`close`参数可以全局关闭日志写入
|
||||
* 中间件方法中捕获`HttpResponseException`异常
|
||||
* 改进中间件的闭包参数传入
|
||||
* 改进分组路由的延迟解析
|
||||
* 改进URL生成对域名绑定的支持
|
||||
* 改进文件缓存和文件日志驱动的并发支持
|
||||
|
||||
## V5.1.7 (2018-3-28)
|
||||
|
||||
该版本主要修正了路由的一些问题,并改进了查询的安全性。
|
||||
|
||||
* 支持`middleware`配置文件预先定义中间件别名方便路由调用
|
||||
* 修正资源路由
|
||||
* 改进`field`方法 自动识别`fieldRaw`
|
||||
* 增加`Expression`类
|
||||
* Query类增加`raw`方法
|
||||
* Query类的`field`/ `order` 和` where`方法都支持使用`raw`表达式查询
|
||||
* 改进`inc/dec`查询 支持批量更新
|
||||
* 改进路由分组
|
||||
* 改进Response类`create`方法
|
||||
* 改进composer自动加载
|
||||
* 修正域名路由的`append`方法
|
||||
* 修正操作方法的初始化方法获取不到问题
|
||||
|
||||
## V5.1.6 (2018-3-26)
|
||||
|
||||
该版本主要改进了路由规则的匹配算法,大幅提升了路由性能。并正式引入了中间件的支持,可以在路由中定义或者全局定义。另外包含了一个安全更新,是一个建议更新版本。
|
||||
|
||||
* 改进URL生成对路由`ext`方法的支持
|
||||
* 改进查询缓存对不同数据库相同表名的支持
|
||||
* 改进composer自动加载的性能
|
||||
* 改进空路由变量对默认参数的影响
|
||||
* mysql的`json`字段查询支持多级
|
||||
* Query类增加`option`方法
|
||||
* 优化路由匹配
|
||||
* 修复验证规则数字键名丢失问题
|
||||
* 改进路由Url生成
|
||||
* 改进一对一关联预载入查询
|
||||
* Request类增加`rootDomain`方法
|
||||
* 支持API资源控制器生成 `make:controller --api`
|
||||
* 优化Template类的标签解析
|
||||
* 容器类增加删除和清除对象实例的方法
|
||||
* 修正MorphMany关联的`eagerlyMorphToMany`方法一处错误
|
||||
* Container类的异常捕获改进
|
||||
* Domain对象支持`bind`方法
|
||||
* 修正分页参数
|
||||
* 默认模板的输出规则不受URL影响
|
||||
* 注解路由支持多级控制器
|
||||
* Query类增加`getNumRows`方法获取前次操作影响的记录数
|
||||
* 改进查询条件的性能
|
||||
* 改进模型类`readTransform`方法对序列化类型的处理
|
||||
* Log类增加`close`方法可以临时关闭当前请求的日志写入
|
||||
* 文件日志方式增加自动清理功能(设置`max_files`参数)
|
||||
* 修正Query类的`getPk`方法
|
||||
* 修正模板缓存的布局开关问题
|
||||
* 修正Query类`select`方法的缓存
|
||||
* 改进input助手函数
|
||||
* 改进断线重连的信息判断
|
||||
* 改进正则验证方法
|
||||
* 调整语言包的加载顺序 放到`app_init`之前
|
||||
* controller类`fetch`方法改为`final`
|
||||
* 路由地址中的变量支持使用`<var>`方式
|
||||
* 改进XMLResponse 支持传入编码过的xml内容
|
||||
* 修正Query类`view`方法的数组表名支持
|
||||
* 改进路由的模型闭包绑定
|
||||
* 改进分组变量规则的继承
|
||||
* 改进`cli-server`模式下的`composer`自动加载
|
||||
* 路由变量规则异常捕获
|
||||
* 引入中间件支持
|
||||
* 路由定义增加`middleware`方法
|
||||
* 增加生成中间件指令`make:middleware`
|
||||
* 增加全局中间件定义支持
|
||||
* 改进`optimize:config`指令对全局中间件的支持
|
||||
* 改进config类`has`方法
|
||||
* 改进时间查询的参数绑定
|
||||
* 改进`inc/dec/exp`查询的安全性
|
||||
|
||||
|
||||
## V5.1.5 (2018-1-31)
|
||||
|
||||
该版本主要增强了数据库的JSON查询,并支持JSON字段的聚合查询,改进了一些性能问题,修正了路由的一些BUG,主要更新如下:
|
||||
|
||||
* 改进数据集查询对`JSON`数据的支持
|
||||
* 改进聚合查询对`JSON`字段的支持
|
||||
* 模型类增加`getOrFail`方法
|
||||
* 改进数据库驱动的`parseKey`方法
|
||||
* 改进Query类`join`方法的自关联查询
|
||||
* 改进数据查询不存在不生成查询缓存
|
||||
* 增加`run`命令行指令启动内置服务器
|
||||
* `Request`类`pathinfo`方法改进对`cli-server`支持
|
||||
* `Session`类增加`use_lock`配置参数设置是否启用锁机制
|
||||
* 优化`File`缓存自动生成空目录的问题
|
||||
* 域名及分组路由支持`append`方法传递隐式参数
|
||||
* 改进日志的并发写入问题
|
||||
* 改进`Query`类的`where`方法支持传入`Query`对象
|
||||
* 支持设置单个日志文件的文件名
|
||||
* 修正路由规则的域名条件约束
|
||||
* `Request`类增加`subDomain`方法用于获取当前子域名
|
||||
* `Response`类增加`allowCache`方法控制是否允许请求缓存
|
||||
* `Request`类增加`sendData`方法便于扩展
|
||||
* 改进`Env`类不依赖`putenv`方法
|
||||
* 改进控制台`trace`显示错误
|
||||
* 改进`MorphTo`关联
|
||||
* 改进完整路由匹配后带斜线访问出错的情况
|
||||
* 改进路由的多级分组问题
|
||||
* 路由url地址生成支持多级分组
|
||||
* 改进路由Url生成的`url_convert`参数的影响
|
||||
* 改进`miss`和`auto`路由内部解析
|
||||
* 取消预载入关联查询缓存功能
|
||||
|
||||
## V5.1.4 (2018-1-19)
|
||||
|
||||
该版本主要增强了数据库和模型操作,主要更新如下:
|
||||
|
||||
* 支持设置 `deleteTime`属性为`false` 关闭软删除
|
||||
* 模型增加`getError`方法
|
||||
* 改进Query类的`getTableFields`/`getFieldsType`方法 支持表名自动获取
|
||||
* 模型类`toCollection`方法增加参数指定数据集类
|
||||
* 改进`union`查询
|
||||
* 关联预载入`with`方法增加缓存参数
|
||||
* 改进模型类的`get`和`all`方法的缓存 支持关联缓存
|
||||
* 支持`order by field`操作
|
||||
* 改进`insertAll`分批写入
|
||||
* 改进`json`字段数据支持
|
||||
* 增加JSON数据的模型对象化操作
|
||||
* 改进路由`ext`参数检测
|
||||
* 修正`rule`方法的`method`参数使用 `get|post` 方式注册路由的问题
|
||||
|
||||
## V5.1.3 (2018-1-12)
|
||||
|
||||
该版本主要改进了路由及调整函数加载顺序,主要更新如下:
|
||||
|
||||
* 增加`env`助手函数;
|
||||
* 增加`route`助手函数;
|
||||
* 增加视图路由方法;
|
||||
* 增加路由重定向方法;
|
||||
* 路由默认区分最后的目录斜杆(支持设置不区分);
|
||||
* 调整公共文件和配置文件的加载顺序(可以在配置文件中直接使用助手函数);
|
||||
* 视图类增加`filter`方法设置输出过滤;
|
||||
* `view`助手函数增加`filter`参数;
|
||||
* 改进缓存生成指令;
|
||||
* Session类的`get`方法支持获取多级;
|
||||
* Request类`only`方法支持指定默认值;
|
||||
* 改进路由分组;
|
||||
* 修正使用闭包查询的时候自动数据缓存出错的情况;
|
||||
* 废除`view_filter`钩子位置;
|
||||
* 修正分组下面的资源路由;
|
||||
* 改进session驱动;
|
||||
|
||||
## V5.1.2 (2018-1-8)
|
||||
|
||||
该版本改进了配置类及数据库类,主要更新如下:
|
||||
|
||||
* 修正嵌套路由分组;
|
||||
* 修正自定义模板标签界定符后表达式语法出错的情况;
|
||||
* 修正自关联的多次调用问题;
|
||||
* 修正数组查询的`null`条件查询;
|
||||
* 修正Query类的`order`及`field`的一处可能的BUG;
|
||||
* 配置参数设置支持三级;
|
||||
* 配置对象支持`ArrayAccess`;
|
||||
* App类增加`path`方法用于设置应用目录;
|
||||
* 关联定义增加`selfRelation`方法用于设置是否为自关联;
|
||||
|
||||
## V5.1.1 (2018-1-3)
|
||||
|
||||
修正一些反馈的BUG,包括:
|
||||
|
||||
* 修正Cookie类存取数组的问题
|
||||
* 修正Controller的`fetch`方法
|
||||
* 改进跨域请求
|
||||
* 修正`insertAll`方法
|
||||
* 修正`chunk`方法
|
||||
|
||||
## V5.1.0 (2018-1-1)
|
||||
|
||||
主要更新如下:
|
||||
|
||||
* 增加注解路由支持
|
||||
* 路由支持跨域请求设置
|
||||
* 增加`app_dispatch`钩子位置
|
||||
* 修正多对多关联的`detach`方法
|
||||
* 修正软删除的`destroy`方法
|
||||
* Cookie类`httponly`参数默认为false
|
||||
* 日志File驱动增加`single`参数配置记录同一个文件(不按日期生成)
|
||||
* 路由的`ext`和`denyExt`方法支持不传任何参数
|
||||
* 改进模型的`save`方法对`oracle`的支持
|
||||
* Query类的`insertall`方法支持配合`data`和`limit`方法
|
||||
* 增加`whereOr`动态查询支持
|
||||
* 日志的ip地址记录改进
|
||||
* 模型`saveAll`方法支持`isUpdate`方法
|
||||
* 改进`Pivot`模型的实例化操作
|
||||
* 改进Model类的`data`方法
|
||||
* 改进多对多中间表模型类
|
||||
* 模型增加`force`方法强制更新所有数据
|
||||
* Hook类支持设置入口方法名称
|
||||
* 改进验证类
|
||||
* 改进`hasWhere`查询的数据重复问题
|
||||
* 模型的`saveall`方法返回数据集对象
|
||||
* 改进File缓存的`clear`方法
|
||||
* 缓存添加统一的序列化机制
|
||||
* 改进泛三级域名的绑定
|
||||
* 改进泛域名的传值和取值
|
||||
* Request类增加`panDomain`方法
|
||||
* 改进废弃字段判断
|
||||
* App类增加`create`方法用于实例化应用类库
|
||||
* 容器类增加`has`方法
|
||||
* 改进多数据库切换连接
|
||||
* 改进断线重连的异常捕获
|
||||
* 改进模型类`buildQuery`方法
|
||||
* Query类增加`unionAll`方法
|
||||
* 关联统计功能增强(支持Sum/Max/Min/Avg)
|
||||
* 修正延迟写入
|
||||
* chunk方法支持复合主键
|
||||
* 改进JSON类型的写入
|
||||
* 改进Mysql的insertAll方法
|
||||
* Model类`save`方法改进复合主键包含自增的情况
|
||||
* 改进Query类`inc`和`dec`方法的关键字处理
|
||||
* File缓存inc和dec方法保持原来的有效期
|
||||
* 改进redis缓存的有效期判断
|
||||
* 增加checkRule方法用于单独数据的多个验证规则
|
||||
* 修正setDec方法的延迟写入
|
||||
* max和min方法增加force参数
|
||||
* 二级配置参数区分大小写
|
||||
* 改进join方法自关联的问题
|
||||
* 修正关联模型自定义表名的情况
|
||||
* Query类增加getFieldsType和getTableFields方法
|
||||
* 取消视图替换功能及view_replace_str配置参数
|
||||
* 改进域名绑定模块后的额外路由规则问题
|
||||
* 改进mysql的insertAll方法
|
||||
* 改进insertAll方法写入json字段数据的支持
|
||||
* 改进redis长连接多编号库的情况
|
||||
|
||||
## RC3版本(2017-11-6)
|
||||
|
||||
主要更新如下:
|
||||
|
||||
* 改进redis驱动的`get`方法
|
||||
* 修正Query类的`alias`方法
|
||||
* `File`类错误信息支持多语言
|
||||
* 修正路由的额外参数解析
|
||||
* 改进`whereTime`方法
|
||||
* 改进Model类`getAttr`方法
|
||||
* 改进App类的`controller`和`validate`方法支持多层
|
||||
* 改进`HasManyThrough`类
|
||||
* 修正软删除的`restore`方法
|
||||
* 改进`MorpthTo`关联
|
||||
* 改进数据库驱动类的`parseKey`方法
|
||||
* 增加`whereField`动态查询方法
|
||||
* 模型增加废弃字段功能
|
||||
* 改进路由的`after`行为检查和`before`行为机制
|
||||
* 改进路由分组的检查
|
||||
* 修正mysql的`json`字段查询
|
||||
* 取消Connection类的`quote`方法
|
||||
* 改进命令行的支持
|
||||
* 验证信息支持多语言
|
||||
* 修正路由模型绑定
|
||||
* 改进参数绑定类型对枚举类型的支持
|
||||
* 修正模板的`{$Think.version} `输出
|
||||
* 改进模板`date`函数解析
|
||||
* 改进`insertAll`方法支持分批执行
|
||||
* Request类`host`方法支持反向代理
|
||||
* 改进`JumpResponse`支持区分成功和错误模板
|
||||
* 改进开启类库后缀后的关联外键自动识别问题
|
||||
* 修正一对一关联的JOIN方式预载入查询问题
|
||||
* Query类增加`hidden`方法
|
||||
|
||||
## RC2版本(2017-10-17)
|
||||
|
||||
主要更新如下:
|
||||
|
||||
* 修正视图查询
|
||||
* 修正资源路由
|
||||
* 修正`HasMany`关联 修正`where`方法的闭包查询
|
||||
* 一对一关联绑定属性到父模型后 关联属性不再保留
|
||||
* 修正应用的命令行配置文件读取
|
||||
* 改进`Connection`类的`getCacheKey`方法
|
||||
* 改进文件上传的非法图像异常
|
||||
* 改进验证类的`unique`规则
|
||||
* Config类`get`方法支持获取一级配置
|
||||
* 修正count方法对`fetchSql`的支持
|
||||
* 修正mysql驱动对`socket`支持
|
||||
* 改进Connection类的`getRealSql`方法
|
||||
* 修正`view`助手函数
|
||||
* Query类增加`leftJoin` `rightJoin` 和 `fullJoin`方法
|
||||
* 改进app_namespace的获取
|
||||
* 改进`append`方法对一对一`bind`属性的支持
|
||||
* 改进关联的`saveall`方法的返回值
|
||||
* 路由标识设置异常修复
|
||||
* 改进Route类`rule`方法
|
||||
* 改进模型的`table`属性设置
|
||||
* 改进composer autofile的加载顺序
|
||||
* 改进`exception_handle`配置对闭包的支持
|
||||
* 改进app助手函数增加参数
|
||||
* 改进composer的加载路径判断
|
||||
* 修正路由组合变量的URL生成
|
||||
* 修正路由URL生成
|
||||
* 改进`whereTime`查询并支持扩展规则
|
||||
* File类的`move`方法第二个参数支持`false`
|
||||
* 改进Config类
|
||||
* 改进缓存类`remember`方法
|
||||
* 惯例配置文件调整 Url类当普通模式参数的时候不做`urlencode`处理
|
||||
* 取消`ROOT_PATH`和`APP_PATH`常量定义 如需更改应用目录 自己重新定义入口文件
|
||||
* 增加`app_debug`的`Env`获取
|
||||
* 修正泛域名绑定
|
||||
* 改进查询表达式的解析机制
|
||||
* mysql增加`regexp`查询表达式 支持正则查询
|
||||
* 改进查询表达式的异常判断
|
||||
* 改进model类的`destroy`方法
|
||||
* 改进Builder类 取消`parseValue`方法
|
||||
* 修正like查询的参数绑定问题
|
||||
* console和start文件移出核心纳入应用库
|
||||
* 改进Db类主键删除方法
|
||||
* 改进泛域名绑定模块
|
||||
* 取消`BIND_MODULE`常量 改为在入口文件使用`bind`方法设置
|
||||
* 改进数组查询
|
||||
* 改进模板渲染的异常处理
|
||||
* 改进控制器基类的架构方法参数
|
||||
* 改进Controller类的`success`和`error`方法
|
||||
* 改进对浏览器`JSON-Handle`插件的支持
|
||||
* 优化跳转模板的移动端显示
|
||||
* 修正模型查询的`chunk`方法对时间字段的支持
|
||||
* 改进trace驱动
|
||||
* Collection类增加`push`方法
|
||||
* 改进Redis Session驱动
|
||||
* 增加JumpResponse驱动
|
||||
|
||||
|
||||
## RC1(2017-9-8)
|
||||
|
||||
主要新特性为:
|
||||
|
||||
* 引入容器和Facade支持
|
||||
* 依赖注入完善和支持更多场景
|
||||
* 重构的(对象化)路由
|
||||
* 配置和路由目录独立
|
||||
* 取消系统常量
|
||||
* 助手函数增强
|
||||
* 类库别名机制
|
||||
* 模型和数据库增强
|
||||
* 验证类增强
|
||||
* 模板引擎改进
|
||||
* 支持PSR-3日志规范
|
||||
* RC1版本取消了5.0多个字段批量数组查询的方式
|
|
@ -0,0 +1,27 @@
|
|||
版权所有 (c) 2016~2017,河源市卓锐科技有限公司保留所有权利。
|
||||
|
||||
DolphinPHP 用户协议
|
||||
|
||||
版权所有 (c) 2016~2017,河源市卓锐科技有限公司保留所有权利。
|
||||
|
||||
感谢您选择DolphinPHP,希望我们的努力能为您提供一个极简极致极速的PHP快速开发解决方案。
|
||||
|
||||
用户须知:本协议是您与河源市卓锐科技有限公司(以下简称卓锐公司)之间关于您使用DolphinPHP产品及服务的法律协议。无论您是个人或组织、盈利与否、用途如何(包括以学习和研究为目的),均需仔细阅读本协议,包括免除或者限制卓锐公司责任的免责条款及对您的权利限制。请您审阅并接受或不接受本服务条款。如您不同意本服务条款及/或卓锐公司随时对其的修改,您应不使用或主动取消DolphinPHP产品。否则,您的任何对DolphinPHP的相关服务的注册、登陆、下载、查看等使用行为将被视为您对本服务条款全部的完全接受,包括接受卓锐公司对服务条款随时所做的任何修改。
|
||||
|
||||
本服务条款一旦发生变更, 卓锐公司将在产品官网上公布修改内容。修改后的服务条款一旦在网站公布即有效代替原来的服务条款。您可随时登陆官网查阅最新版服务条款。如果您选择接受本条款,即表示您同意接受协议各项条件的约束。如果您不同意本服务条款,则不能获得使用本服务的权利。您若有违反本条款规定,卓锐公司有权随时中止或终止您对DolphinPHP产品的使用资格并保留追究相关法律责任的权利。
|
||||
|
||||
在理解、同意、并遵守本协议的全部条款后,方可开始使用DolphinPHP产品。您也可能与卓锐公司直接签订另一书面协议,以补充或者取代本协议的全部或者任何部分。
|
||||
|
||||
卓锐公司拥有DolphinPHP的全部知识产权,包括商标和著作权。本软件只供许可协议,并非出售。卓锐公司只允许您在遵守本协议各项条款的情况下复制、下载、安装、使用或者以其他方式受益于本软件的功能或者知识产权。
|
||||
|
||||
个人非商业用途可免费使用(但不包括其衍生产品、插件或者服务),也可以根据个人实际情况选择是否购买授权。
|
||||
|
||||
非个人用户(泛指非个人的团体,如企业、政府单位、教育机构、协会团体、厂矿、工作室等)必须购买软件授权后方可使用。
|
||||
|
||||
您可以在协议规定的约束和限制范围内修改DolphinPHP以适应您的网站要求,但免费版必须保留软件版本信息的正常显示及相关连接正常。
|
||||
|
||||
禁止去除DolphinPHP源码里的版权信息,商业授权版本可去除后台界面及前台界面的相关版权信息。
|
||||
|
||||
禁止在DolphinPHP整体或任何部分基础上发展任何派生版本、修改版本或第三方版本用于重新分发。
|
||||
|
||||
未经官方许可,不得对本软件或与之关联的商业授权进行出租、出售、抵押或发放子许可证。
|
Binary file not shown.
|
@ -0,0 +1 @@
|
|||
deny from all
|
|
@ -0,0 +1,191 @@
|
|||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006-2016 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: yunwuxin <448901948@qq.com>
|
||||
// +----------------------------------------------------------------------
|
||||
namespace app\activity\admin;
|
||||
|
||||
use think\Db;
|
||||
use app\admin\controller\Admin;
|
||||
use app\common\builder\ZBuilder;
|
||||
use app\activity\model\Award as AwardModel;
|
||||
use app\member\model\Member as MemberModel;
|
||||
|
||||
|
||||
class Award extends Admin
|
||||
{
|
||||
//主播列表
|
||||
public function index(){
|
||||
// 获取查询条件
|
||||
$map = $this->getMap();
|
||||
|
||||
// 排序
|
||||
$order = $this->getOrder('sort asc');
|
||||
|
||||
// 数据列表
|
||||
$map[] = ['id','neq',9];
|
||||
$data_list = AwardModel::where($map)->order($order)->paginate();
|
||||
|
||||
//加载模板
|
||||
return ZBuilder::make('table')
|
||||
->setPageTitle('奖品设置')// 设置页面标题
|
||||
->setTableName('award')
|
||||
->addOrder('create_time') // 添加排序
|
||||
->addColumns([ // 批量添加列
|
||||
['sort', '排序(升序排序)','text.edit'],
|
||||
['thumb', '奖品图片','picture'],
|
||||
['title', '奖品名称'],
|
||||
['jp_number', '开奖累计次数'],
|
||||
['open_num', '已开奖次数'],
|
||||
['right_button', '操作', 'btn']
|
||||
])
|
||||
//->addTopButton('add',['class'=>'btn btn-primary','icon' => 'fa fa-plus-circle','title'=>'新增', 'href' => url('add')],['area' => ['600px', '60%']])
|
||||
->addTopButton('export',[
|
||||
'title' => '设置抽奖扣除金币数量',
|
||||
'icon' => 'fa fa-fw fa-minus',
|
||||
'class' => 'btn btn-info export confirm',
|
||||
'href' => url('setgoldcoin'),
|
||||
'data-url' => url('setgoldcoin')
|
||||
],['area' => ['600px', '60%']]) // 导出
|
||||
->addRightButton('edit',['title'=>'編輯','icon'=>'fa fa-pencil','href'=>url('edit',['id' => '__id__'])],['area' => ['600px', '60%']])
|
||||
//->addRightButton('delete', ['title' => '删除', 'icon' => 'fa fa-remove', 'href' => url('delete', ['id' => '__id__'])])
|
||||
->setRowList($data_list)// 设置表格数据
|
||||
->fetch(); // 渲染模板
|
||||
}
|
||||
|
||||
public function setgoldcoin(){
|
||||
if($this->request->isPost()){
|
||||
$data = $this->request->post();
|
||||
|
||||
if(empty($data['jp_number'])){
|
||||
return $this->error('请输入需要扣除的金币');
|
||||
}
|
||||
|
||||
$data['update_time'] = time();
|
||||
$result = AwardModel::update($data);
|
||||
if($result){
|
||||
$this->success('修改成功', url('index'),'_parent_reload');
|
||||
}else{
|
||||
$this->error('修改失败');
|
||||
}
|
||||
} else {
|
||||
$info = AwardModel::where('id',9)->find();
|
||||
return ZBuilder::make('form')
|
||||
->addFormItems([//批量添加表单项
|
||||
['hidden', 'id'],
|
||||
['text', 'jp_number', '扣除金币'],
|
||||
])
|
||||
->setFormData($info)
|
||||
->fetch();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//添加
|
||||
public function add(){
|
||||
if($this->request->isPost()){
|
||||
$data = $this->request->post();
|
||||
|
||||
if(empty($data['title'])){
|
||||
return $this->error('奖品名称不能为空');
|
||||
}
|
||||
|
||||
$result = AwardModel::create($data);
|
||||
if($result){
|
||||
$this->success('新增成功', url('index'),'_parent_reload');
|
||||
}else{
|
||||
$this->error('新增失败');
|
||||
}
|
||||
}else{
|
||||
return ZBuilder::make('form')
|
||||
->addFormItems([//批量添加表单项
|
||||
['image', 'thumb', '奖品图片', '<code>必上传</code>'],
|
||||
['text', 'title', '奖品名称'],
|
||||
['text', 'jp_number', '开奖累计次数'],
|
||||
['text', 'sort', '排序(升序排序)','',9999],
|
||||
])
|
||||
->fetch();
|
||||
}
|
||||
}
|
||||
|
||||
//编辑
|
||||
public function edit($id=null){
|
||||
if ($id === null) return $this->error('缺少参数');
|
||||
|
||||
if($this->request->isPost()){
|
||||
$data = $this->request->post();
|
||||
|
||||
if(empty($data['title'])){
|
||||
return $this->error('奖品名称不能为空');
|
||||
}
|
||||
$data['update_time'] = time();
|
||||
$result = AwardModel::update($data);
|
||||
if($result){
|
||||
$this->success('修改成功', url('index'),'_parent_reload');
|
||||
}else{
|
||||
$this->error('修改失败');
|
||||
}
|
||||
} else {
|
||||
$info = AwardModel::get($id);
|
||||
|
||||
if($id==1){
|
||||
$formitems = [
|
||||
['hidden', 'id'],
|
||||
['image', 'thumb', '奖品图片', '<code>必上传</code>'],
|
||||
['text', 'title', '奖品名称'],
|
||||
['text', 'jp_number', '开奖累计次数(谢谢参与中奖次数)'],
|
||||
['text', 'sort', '排序(升序排序)','',9999],
|
||||
];
|
||||
}
|
||||
|
||||
if($id==2 || $id==3 || $id==4){
|
||||
$formitems = [
|
||||
['hidden', 'id'],
|
||||
['image', 'thumb', '奖品图片', '<code>必上传</code>'],
|
||||
['text', 'title', '奖品名称'],
|
||||
['text', 'sort', '排序(升序排序)','',9999],
|
||||
];
|
||||
}
|
||||
|
||||
if($id==5 || $id==6 || $id==7 || $id==8){
|
||||
$formitems = [
|
||||
['hidden', 'id'],
|
||||
['image', 'thumb', '奖品图片', '<code>必上传</code>'],
|
||||
['text', 'title', '奖品名称'],
|
||||
['text', 'jp_number', '开奖累计次数(抽奖累次次数)'],
|
||||
['text', 'sort', '排序(升序排序)','',9999],
|
||||
];
|
||||
}
|
||||
|
||||
return ZBuilder::make('form')
|
||||
->addFormItems($formitems)
|
||||
->setFormData($info)
|
||||
->fetch();
|
||||
}
|
||||
}
|
||||
|
||||
//删除
|
||||
public function delete($id = null)
|
||||
{
|
||||
if ($id === null) {
|
||||
$this->error('缺少参数');
|
||||
}
|
||||
|
||||
$data = AwardModel::where('id',$id)->find();
|
||||
if (empty($data)) {$this->error('删除成功!'); }
|
||||
|
||||
$result = AwardModel::where('id',$id)->delete();
|
||||
if($result) {
|
||||
return $this->success('删除成功!');
|
||||
}else{
|
||||
return $this->error('删除失败!');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,125 @@
|
|||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006-2016 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: yunwuxin <448901948@qq.com>
|
||||
// +----------------------------------------------------------------------
|
||||
namespace app\activity\admin;
|
||||
|
||||
use think\Db;
|
||||
use app\admin\controller\Admin;
|
||||
use app\common\builder\ZBuilder;
|
||||
use app\activity\model\AwardMessage as AwardMessageModel;
|
||||
use app\member\model\Member as MemberModel;
|
||||
|
||||
|
||||
class Awardmessage extends Admin
|
||||
{
|
||||
//列表
|
||||
public function index(){
|
||||
// 获取查询条件
|
||||
$map = $this->getMap();
|
||||
|
||||
// 排序
|
||||
$order = $this->getOrder('create_time dasc');
|
||||
|
||||
// 数据列表
|
||||
$data_list = AwardMessageModel::where($map)->order($order)->paginate();
|
||||
|
||||
//加载模板
|
||||
return ZBuilder::make('table')
|
||||
->setSearchArea([
|
||||
['daterange', 'create_time', '添加时间', 'between'],
|
||||
])
|
||||
->setPageTitle('中奖信息列表')// 设置页面标题
|
||||
->setTableName('award_message')
|
||||
->addOrder('create_time') // 添加排序
|
||||
->addColumns([ // 批量添加列
|
||||
['title', '中奖信息'],
|
||||
['create_time', '添加时间','datetime'],
|
||||
['right_button', '操作', 'btn']
|
||||
])
|
||||
->addTopButton('add',['class'=>'btn btn-primary','icon' => 'fa fa-plus-circle','title'=>'新增', 'href' => url('add')],['area' => ['700px', '60%']])
|
||||
->addRightButton('edit',['title'=>'編輯','icon'=>'fa fa-pencil','href'=>url('edit',['id' => '__id__'])],['area' => ['700px', '60%']])
|
||||
->addRightButton('delete', ['title' => '删除', 'icon' => 'fa fa-remove', 'href' => url('delete', ['id' => '__id__'])])
|
||||
->setRowList($data_list)// 设置表格数据
|
||||
->fetch(); // 渲染模板
|
||||
}
|
||||
|
||||
//添加主播
|
||||
public function add(){
|
||||
if($this->request->isPost()){
|
||||
$data = $this->request->post();
|
||||
|
||||
if(empty($data['title'])){
|
||||
return $this->error('中奖信息不能为空');
|
||||
}
|
||||
|
||||
$result = AwardMessageModel::create($data);
|
||||
if($result){
|
||||
$this->success('新增成功', url('index'),'_parent_reload');
|
||||
}else{
|
||||
$this->error('新增失败');
|
||||
}
|
||||
}else{
|
||||
return ZBuilder::make('form')
|
||||
->addFormItems([//批量添加表单项
|
||||
['textarea', 'title', '中奖信息'],
|
||||
])
|
||||
->fetch();
|
||||
}
|
||||
}
|
||||
|
||||
//编辑主播
|
||||
public function edit($id=null){
|
||||
if ($id === null) return $this->error('缺少参数');
|
||||
|
||||
if($this->request->isPost()){
|
||||
$data = $this->request->post();
|
||||
|
||||
if(empty($data['title'])){
|
||||
return $this->error('中奖信息不能为空');
|
||||
}
|
||||
$data['update_time'] = time();
|
||||
$result = AwardMessageModel::update($data);
|
||||
if($result){
|
||||
$this->success('修改成功', url('index'),'_parent_reload');
|
||||
}else{
|
||||
$this->error('修改失败');
|
||||
}
|
||||
} else {
|
||||
$info = AwardMessageModel::get($id);
|
||||
return ZBuilder::make('form')
|
||||
->addFormItems([//批量添加表单项
|
||||
['hidden', 'id'],
|
||||
['textarea', 'title', '中奖信息'],
|
||||
])
|
||||
->setFormData($info)
|
||||
->fetch();
|
||||
}
|
||||
}
|
||||
|
||||
//删除主播
|
||||
public function delete($id = null)
|
||||
{
|
||||
if ($id === null) {
|
||||
$this->error('缺少参数');
|
||||
}
|
||||
|
||||
$data = AwardMessageModel::where('id',$id)->find();
|
||||
if (empty($data)) {$this->error('删除成功!'); }
|
||||
|
||||
$result = AwardMessageModel::where('id',$id)->delete();
|
||||
if($result) {
|
||||
return $this->success('删除成功!');
|
||||
}else{
|
||||
return $this->error('删除失败!');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,83 @@
|
|||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006-2016 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: yunwuxin <448901948@qq.com>
|
||||
// +----------------------------------------------------------------------
|
||||
namespace app\activity\admin;
|
||||
|
||||
use think\Db;
|
||||
use app\admin\controller\Admin;
|
||||
use app\common\builder\ZBuilder;
|
||||
use app\activity\model\AwardWinnings as AwardWinningsModel;
|
||||
use app\activity\model\Award as AwardModel;
|
||||
use app\member\model\Member as MemberModel;
|
||||
|
||||
|
||||
class Awardwinnings extends Admin
|
||||
{
|
||||
public function index(){
|
||||
// 获取
|
||||
$map = $this->getMap();
|
||||
// 排序
|
||||
$order = $this->getOrder('id desc');
|
||||
//数据
|
||||
$data_list = AwardWinningsModel::where($map)->order($order)->paginate();
|
||||
if(!empty($data_list)){
|
||||
foreach ($data_list as $key=>$val){
|
||||
|
||||
$uinfo = MemberModel::where('id',$val['uid'])->find();
|
||||
$is_vip = '普通会员';
|
||||
switch ($uinfo['is_vip']) {
|
||||
case 1:
|
||||
$is_vip = '铜牌会员';
|
||||
break;
|
||||
case 2:
|
||||
$is_vip = '银牌会员';
|
||||
break;
|
||||
case 3:
|
||||
$is_vip = '金牌会员';
|
||||
break;
|
||||
}
|
||||
$data_list[$key]['nickname'] = $uinfo['nickname'].'('.$is_vip.')';
|
||||
if(!empty($val['address'])){
|
||||
$data_list[$key]['address'] = "姓名:".$val['name']."</br>电话:".$val['phone']."</br>邮寄地址:".$val['address'];
|
||||
}else{
|
||||
$data_list[$key]['address'] = "暂无";
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
// 分页数据
|
||||
$page = $data_list->render();
|
||||
|
||||
//加载模板
|
||||
return ZBuilder::make('table')
|
||||
->setSearchArea([
|
||||
['select', 'uid', '所属用户', 'eq', '', MemberModel::where('is_delete',0)->column('id,nickname')],
|
||||
['select', 'award_id', '所属奖品', 'eq', '', AwardModel::column('id,title')],
|
||||
['text', 'name', '姓名', 'like'],
|
||||
['text', 'phone', '电话', 'like'],
|
||||
['text', 'address', '邮寄地址', 'like'],
|
||||
['daterange','create_time','抽奖时间','between'],
|
||||
])
|
||||
->setPageTitle('金币产出记录') // 设置页面标题
|
||||
->setTableName('member')
|
||||
->addOrder('create_time') // 添加排序
|
||||
->addColumns([ // 批量添加列
|
||||
['nickname', '所属用户','text'],
|
||||
['award_title', '奖品','text'],
|
||||
['award_thumb', '奖品图片','picture'],
|
||||
['usegoldcoin', '消耗金币','text'],
|
||||
['create_time', '抽奖时间','datetime'],
|
||||
['address', '邮寄地址','text'],
|
||||
])
|
||||
->setRowList($data_list) // 设置表格数据
|
||||
->setPages($page) // 设置分页数据
|
||||
->fetch(); // 渲染模板
|
||||
}
|
||||
}
|
|
@ -0,0 +1,131 @@
|
|||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006-2016 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: yunwuxin <448901948@qq.com>
|
||||
// +----------------------------------------------------------------------
|
||||
namespace app\activity\admin;
|
||||
|
||||
use think\Db;
|
||||
use app\admin\controller\Admin;
|
||||
use app\common\builder\ZBuilder;
|
||||
use app\activity\model\DriftBottle as DriftBottleModel;
|
||||
use app\member\model\Member as MemberModel;
|
||||
use app\member\model\MemberService as MemberServiceModel;
|
||||
|
||||
|
||||
class Driftbottle extends Admin
|
||||
{
|
||||
//主播列表
|
||||
public function index(){
|
||||
// 获取查询条件
|
||||
$map = $this->getMap();
|
||||
|
||||
// 排序
|
||||
$order = $this->getOrder('create_time desc');
|
||||
|
||||
// 数据列表
|
||||
//数据
|
||||
$data_list = DriftBottleModel::where($map)->order($order)->paginate();
|
||||
if(!empty($data_list)){
|
||||
foreach ($data_list as $key=>$val){
|
||||
|
||||
$uinfo = MemberModel::where('id',$val['uid'])->find();
|
||||
$is_vip = '普通会员';
|
||||
switch ($uinfo['is_vip']) {
|
||||
case 1:
|
||||
$is_vip = '铜牌会员';
|
||||
break;
|
||||
case 2:
|
||||
$is_vip = '银牌会员';
|
||||
break;
|
||||
case 3:
|
||||
$is_vip = '金牌会员';
|
||||
break;
|
||||
}
|
||||
$data_list[$key]['nickname'] = $uinfo['nickname'].'('.$is_vip.')';
|
||||
}
|
||||
}
|
||||
|
||||
//加载模板
|
||||
return ZBuilder::make('table')
|
||||
->setSearchArea([
|
||||
['select', 'uid', '所属用户', 'eq', '', MemberModel::where('is_delete',0)->column('id,nickname')],
|
||||
['text', 'message', '漂流瓶信息', 'like'],
|
||||
['daterange','create_time','发布时间','between'],
|
||||
])
|
||||
->setPageTitle('漂流瓶信息列表')// 设置页面标题
|
||||
->setTableName('member_driftbottle')
|
||||
->addOrder('create_time') // 添加排序
|
||||
->addColumns([ // 批量添加列
|
||||
['nickname', '所属用户','text'],
|
||||
['message', '漂流瓶信息'],
|
||||
['create_time', '发布时间','datetime'],
|
||||
['right_button', '操作', 'btn']
|
||||
])
|
||||
->addRightButton('delete', ['title' => '删除', 'icon' => 'fa fa-remove', 'href' => url('delete', ['id' => '__id__'])])
|
||||
->setRowList($data_list)// 设置表格数据
|
||||
->fetch(); // 渲染模板
|
||||
}
|
||||
|
||||
//删除
|
||||
public function delete($id = null)
|
||||
{
|
||||
if ($id === null) {
|
||||
$this->error('缺少参数');
|
||||
}
|
||||
|
||||
$data = DriftBottleModel::where('id',$id)->find();
|
||||
if (empty($data)) {$this->error('删除成功!'); }
|
||||
|
||||
$result = DriftBottleModel::where('id',$id)->delete();
|
||||
if($result) {
|
||||
return $this->success('删除成功!');
|
||||
}else{
|
||||
return $this->error('删除失败!');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function portraitphotography(){
|
||||
if($this->request->isPost()){
|
||||
$data = $this->request->post();
|
||||
|
||||
if(empty($data['title'])){
|
||||
return $this->error('标题不能为空');
|
||||
}
|
||||
$data['update_time'] = time();
|
||||
$data['create_time'] = !empty($data['create_time'])?strtotime($data['create_time']):time();
|
||||
|
||||
$result = MemberServiceModel::update($data);
|
||||
if($result){
|
||||
$this->success('修改成功', url('portraitphotography'),'_parent_reload');
|
||||
}else{
|
||||
$this->error('修改失败');
|
||||
}
|
||||
} else {
|
||||
$info = MemberServiceModel::get(12);
|
||||
|
||||
return ZBuilder::make('form')
|
||||
->addFormItems([//批量添加表单项
|
||||
['hidden', 'id'],
|
||||
['image', 'thumb', '封面图', '<code>必上传</code>'],
|
||||
['text:6', 'title', '标题'],
|
||||
['text:6', 'price', '购买金额'],
|
||||
['textarea:4', 'box_url', '网盘地址'],
|
||||
['textarea:4', 'box_psw', '网盘密码(没有密码则不填写)'],
|
||||
['textarea:4', 'summary', '写真描述'],
|
||||
['datetime', 'create_time', '发布时间'],
|
||||
['ueditor', 'message', '写真详情说明'],
|
||||
])
|
||||
->setFormData($info)
|
||||
->fetch();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,222 @@
|
|||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006-2016 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: yunwuxin <448901948@qq.com>
|
||||
// +----------------------------------------------------------------------
|
||||
namespace app\activity\admin;
|
||||
|
||||
use think\Db;
|
||||
use app\admin\controller\Admin;
|
||||
use app\common\builder\ZBuilder;
|
||||
use app\activity\model\MoneyTree as MoneyTreeModel;
|
||||
use app\activity\model\MoneyTreeLogs as MMoneyTreeLogsModel;
|
||||
use app\member\model\Member as MemberModel;
|
||||
|
||||
|
||||
class Moneytree extends Admin
|
||||
{
|
||||
//主播列表
|
||||
public function index(){
|
||||
// 获取查询条件
|
||||
$map = $this->getMap();
|
||||
|
||||
// 排序
|
||||
$order = $this->getOrder('tree_grade asc');
|
||||
|
||||
// 数据列表
|
||||
$data_list = MoneyTreeModel::where($map)->order($order)->paginate();
|
||||
|
||||
//加载模板
|
||||
return ZBuilder::make('table')
|
||||
->setSearchArea([
|
||||
['daterange', 'create_time', '添加时间', 'between'],
|
||||
])
|
||||
->setPageTitle('摇钱树等级')// 设置页面标题
|
||||
->setTableName('moneytree')
|
||||
->addOrder('create_time') // 添加排序
|
||||
->addColumns([ // 批量添加列
|
||||
['thumb', '摇钱树图片','picture'],
|
||||
['tree_grade', '等级'],
|
||||
['integral_num', '24小时产生的金币'],
|
||||
['share_num', '分享人数'],
|
||||
['create_time', '添加时间','datetime'],
|
||||
['right_button', '操作', 'btn']
|
||||
])
|
||||
->addTopButton('add',['class'=>'btn btn-primary','icon' => 'fa fa-plus-circle','title'=>'新增', 'href' => url('add')],['area' => ['600px', '60%']])
|
||||
->addTopButton('export',[
|
||||
'title' => '摇钱树规则说明',
|
||||
'icon' => 'fa fa-fw fa-file-text-o',
|
||||
'class' => 'btn btn-info export confirm',
|
||||
'href' => url('moneytreeequity'),
|
||||
'data-url' => url('moneytreeequity')
|
||||
],['area' => ['800px', '80%']]) // 导出
|
||||
->addRightButton('edit',['title'=>'編輯','icon'=>'fa fa-pencil','href'=>url('edit',['id' => '__id__'])],['area' => ['600px', '60%']])
|
||||
->addRightButton('delete', ['title' => '删除', 'icon' => 'fa fa-remove', 'href' => url('delete', ['id' => '__id__'])])
|
||||
->setRowList($data_list)// 设置表格数据
|
||||
->fetch(); // 渲染模板
|
||||
}
|
||||
|
||||
//摇钱树规则说明
|
||||
public function moneytreeequity(){
|
||||
if($this->request->isPost()){
|
||||
$data = $this->request->post();
|
||||
|
||||
if(empty($data['message'])){
|
||||
return $this->error('摇钱树规则说明不能为空');
|
||||
}
|
||||
|
||||
$data['update_time'] = time();
|
||||
$result = MMoneyTreeLogsModel::update($data);
|
||||
if($result){
|
||||
$this->success('修改成功', url('index'),'_parent_reload');
|
||||
}else{
|
||||
$this->error('修改失败');
|
||||
}
|
||||
} else {
|
||||
$info = MMoneyTreeLogsModel::where('id',1)->find();
|
||||
return ZBuilder::make('form')
|
||||
->addFormItems([//批量添加表单项
|
||||
['hidden', 'id'],
|
||||
['ueditor', 'message', '摇钱树规则说明'],
|
||||
])
|
||||
->setFormData($info)
|
||||
->fetch();
|
||||
}
|
||||
}
|
||||
|
||||
//添加主播
|
||||
public function add(){
|
||||
if($this->request->isPost()){
|
||||
$data = $this->request->post();
|
||||
|
||||
if(empty($data['tree_grade'])){
|
||||
return $this->error('等级不能为空');
|
||||
}
|
||||
|
||||
$result = MoneyTreeModel::create($data);
|
||||
if($result){
|
||||
$this->success('新增成功', url('index'),'_parent_reload');
|
||||
}else{
|
||||
$this->error('新增失败');
|
||||
}
|
||||
}else{
|
||||
return ZBuilder::make('form')
|
||||
->addFormItems([//批量添加表单项
|
||||
['image', 'thumb', '摇钱树图片', '<code>必上传</code>'],
|
||||
['text', 'tree_grade', '等级'],
|
||||
['text', 'integral_num', '24小时产生的金币'],
|
||||
['text', 'share_num', '分享人数'],
|
||||
])
|
||||
->fetch();
|
||||
}
|
||||
}
|
||||
|
||||
//编辑主播
|
||||
public function edit($id=null){
|
||||
if ($id === null) return $this->error('缺少参数');
|
||||
|
||||
if($this->request->isPost()){
|
||||
$data = $this->request->post();
|
||||
|
||||
if(empty($data['tree_grade'])){
|
||||
return $this->error('等级不能为空');
|
||||
}
|
||||
$data['update_time'] = time();
|
||||
$result = MoneyTreeModel::update($data);
|
||||
if($result){
|
||||
$this->success('修改成功', url('index'),'_parent_reload');
|
||||
}else{
|
||||
$this->error('修改失败');
|
||||
}
|
||||
} else {
|
||||
$info = MoneyTreeModel::get($id);
|
||||
return ZBuilder::make('form')
|
||||
->addFormItems([//批量添加表单项
|
||||
['hidden', 'id'],
|
||||
['image', 'thumb', '摇钱树图片', '<code>必上传</code>'],
|
||||
['text', 'tree_grade', '等级'],
|
||||
['text', 'integral_num', '24小时产生的金币'],
|
||||
['text', 'share_num', '分享人数'],
|
||||
])
|
||||
->setFormData($info)
|
||||
->fetch();
|
||||
}
|
||||
}
|
||||
|
||||
//删除主播
|
||||
public function delete($id = null)
|
||||
{
|
||||
if ($id === null) {
|
||||
$this->error('缺少参数');
|
||||
}
|
||||
|
||||
$data = MoneyTreeModel::where('id',$id)->find();
|
||||
if (empty($data)) {$this->error('删除成功!'); }
|
||||
|
||||
$result = MoneyTreeModel::where('id',$id)->delete();
|
||||
if($result) {
|
||||
return $this->success('删除成功!');
|
||||
}else{
|
||||
return $this->error('删除失败!');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function moneytreelogs(){
|
||||
// 获取
|
||||
$map = $this->getMap();
|
||||
// 排序
|
||||
$order = $this->getOrder('id desc');
|
||||
$map[] = ['id','neq',1];
|
||||
//数据
|
||||
$data_list = MMoneyTreeLogsModel::where($map)->order($order)->paginate();
|
||||
if(!empty($data_list)){
|
||||
foreach ($data_list as $key=>$val){
|
||||
|
||||
$uinfo = MemberModel::where('id',$val['uid'])->find();
|
||||
$is_vip = '普通会员';
|
||||
switch ($uinfo['is_vip']) {
|
||||
case 1:
|
||||
$is_vip = '铜牌会员';
|
||||
break;
|
||||
case 2:
|
||||
$is_vip = '银牌会员';
|
||||
break;
|
||||
case 3:
|
||||
$is_vip = '金牌会员';
|
||||
break;
|
||||
}
|
||||
$data_list[$key]['nickname'] = $uinfo['nickname'].'('.$is_vip.')';
|
||||
}
|
||||
}
|
||||
// 分页数据
|
||||
$page = $data_list->render();
|
||||
|
||||
//加载模板
|
||||
return ZBuilder::make('table')
|
||||
->setSearchArea([
|
||||
['select', 'uid', '所属用户', 'eq', '', MemberModel::where('is_delete',0)->column('id,nickname')],
|
||||
['daterange','create_time','时间','between'],
|
||||
])
|
||||
->setPageTitle('金币产出记录') // 设置页面标题
|
||||
->setTableName('member')
|
||||
->addOrder('create_time') // 添加排序
|
||||
->addColumns([ // 批量添加列
|
||||
['uid', 'UID','text'],
|
||||
['nickname', '所属用户','text'],
|
||||
['tree_grade', '摇钱树等级','text'],
|
||||
['integral_num', '产出金币','text'],
|
||||
['create_time', '产出时间','datetime'],
|
||||
['status', '状态','text','',[1=>'待领取',2=>'已领取']],
|
||||
])
|
||||
->setRowList($data_list) // 设置表格数据
|
||||
->setPages($page) // 设置分页数据
|
||||
->fetch(); // 渲染模板
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | 海豚PHP框架 [ DolphinPHP ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 版权所有 2016~2017 河源市卓锐科技有限公司 [ http://www.zrthink.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网站: http://dolphinphp.com
|
||||
// +----------------------------------------------------------------------
|
||||
// | 开源协议 ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
// 门户模块公共函数库
|
||||
use think\Db;
|
|
@ -0,0 +1,56 @@
|
|||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | 海豚PHP框架 [ DolphinPHP ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 版权所有 2016~2017 河源市卓锐科技有限公司 [ http://www.zrthink.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网站: http://dolphinphp.com
|
||||
// +----------------------------------------------------------------------
|
||||
// | 开源协议 ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
|
||||
/**
|
||||
* 模块信息
|
||||
*/
|
||||
return [
|
||||
//模块名[必填]
|
||||
'name' => 'activity',
|
||||
// 模块标题[必填]
|
||||
'title' => '活动',
|
||||
// 模块唯一标识[必填],格式:模块名.开发者标识.module
|
||||
'identifier' => 'activity.maurylee.module',
|
||||
// 模块图标[选填]
|
||||
'icon' => 'fa fa-fw fa-font',
|
||||
// 模块描述[选填]
|
||||
'description' => '活动模块',
|
||||
// 开发者[必填]
|
||||
'author' => 'maurylee',
|
||||
// 开发者网址[选填]
|
||||
'author_url' => '',
|
||||
// 版本[必填],格式采用三段式:主版本号.次版本号.修订版本号
|
||||
'version' => '1.0.0',
|
||||
// 模块依赖[可选],格式[[模块名, 模块唯一标识, 依赖版本, 对比方式]]
|
||||
'need_module' => [],
|
||||
// 插件依赖[可选],格式[[插件名, 插件唯一标识, 依赖版本, 对比方式]]
|
||||
'need_plugin' => [],
|
||||
// 数据表[有数据库表时必填]
|
||||
'tables' => [],
|
||||
// 原始数据库表前缀
|
||||
// 用于在导入模块sql时,将原有的表前缀转换成系统的表前缀
|
||||
// 一般模块自带sql文件时才需要配置
|
||||
'database_prefix' => '',
|
||||
|
||||
|
||||
//模块参数配置
|
||||
'config' => [],
|
||||
|
||||
|
||||
// 行为配置
|
||||
'action' => [],
|
||||
|
||||
|
||||
// 授权配置
|
||||
'access' => [],
|
||||
];
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | 海豚PHP框架 [ DolphinPHP ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 版权所有 2016~2017 河源市卓锐科技有限公司 [ http://www.zrthink.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网站: http://dolphinphp.com
|
||||
// +----------------------------------------------------------------------
|
||||
// | 开源协议 ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
|
||||
/**
|
||||
* 菜单信息
|
||||
*/
|
||||
return [
|
||||
[
|
||||
'title' => '活动',
|
||||
'icon' => 'fa fa-fw fa-font',
|
||||
'url_type' => 'module_admin',
|
||||
'url_value' => 'activity/index/index',
|
||||
'url_target' => '_self',
|
||||
'online_hide' => 0,
|
||||
'sort' => 100,
|
||||
'child' => [],
|
||||
],
|
||||
|
||||
];
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | 海豚PHP框架 [ DolphinPHP ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 版权所有 2016~2019 广东卓锐软件有限公司 [ http://www.zrthink.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网站: http://dolphinphp.com
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace app\activity\model;
|
||||
|
||||
use think\Model as ThinkModel;
|
||||
|
||||
/**
|
||||
* 广告模型
|
||||
* @package app\cms\model
|
||||
*/
|
||||
class Award extends ThinkModel
|
||||
{
|
||||
// 设置当前模型对应的完整数据表名称
|
||||
protected $name = 'award';
|
||||
|
||||
// 自动写入时间戳
|
||||
protected $autoWriteTimestamp = true;
|
||||
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | 海豚PHP框架 [ DolphinPHP ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 版权所有 2016~2019 广东卓锐软件有限公司 [ http://www.zrthink.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网站: http://dolphinphp.com
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace app\activity\model;
|
||||
|
||||
use think\Model as ThinkModel;
|
||||
|
||||
/**
|
||||
* 广告模型
|
||||
* @package app\cms\model
|
||||
*/
|
||||
class AwardMessage extends ThinkModel
|
||||
{
|
||||
// 设置当前模型对应的完整数据表名称
|
||||
protected $name = 'award_message';
|
||||
|
||||
// 自动写入时间戳
|
||||
protected $autoWriteTimestamp = true;
|
||||
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | 海豚PHP框架 [ DolphinPHP ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 版权所有 2016~2019 广东卓锐软件有限公司 [ http://www.zrthink.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网站: http://dolphinphp.com
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace app\activity\model;
|
||||
|
||||
use think\Model as ThinkModel;
|
||||
|
||||
/**
|
||||
* 广告模型
|
||||
* @package app\cms\model
|
||||
*/
|
||||
class AwardWinnings extends ThinkModel
|
||||
{
|
||||
// 设置当前模型对应的完整数据表名称
|
||||
protected $name = 'award_winnings';
|
||||
|
||||
// 自动写入时间戳
|
||||
protected $autoWriteTimestamp = true;
|
||||
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | 海豚PHP框架 [ DolphinPHP ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 版权所有 2016~2019 广东卓锐软件有限公司 [ http://www.zrthink.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网站: http://dolphinphp.com
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace app\activity\model;
|
||||
|
||||
use think\Model as ThinkModel;
|
||||
|
||||
/**
|
||||
* 广告模型
|
||||
* @package app\cms\model
|
||||
*/
|
||||
class DriftBottle extends ThinkModel
|
||||
{
|
||||
// 设置当前模型对应的完整数据表名称
|
||||
protected $name = 'member_driftbottle';
|
||||
|
||||
// 自动写入时间戳
|
||||
protected $autoWriteTimestamp = true;
|
||||
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | 海豚PHP框架 [ DolphinPHP ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 版权所有 2016~2019 广东卓锐软件有限公司 [ http://www.zrthink.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网站: http://dolphinphp.com
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace app\activity\model;
|
||||
|
||||
use think\Model as ThinkModel;
|
||||
|
||||
/**
|
||||
* 广告模型
|
||||
* @package app\cms\model
|
||||
*/
|
||||
class MoneyTree extends ThinkModel
|
||||
{
|
||||
// 设置当前模型对应的完整数据表名称
|
||||
protected $name = 'moneytree';
|
||||
|
||||
// 自动写入时间戳
|
||||
protected $autoWriteTimestamp = true;
|
||||
|
||||
//根据用户分享人数,获得对应积分
|
||||
public static function getintegralnum($sharenum){
|
||||
|
||||
$integralnum = 0;
|
||||
|
||||
$list = self::order('tree_grade asc')->select();
|
||||
if(!empty($list)){
|
||||
foreach ($list as $k=>$v){
|
||||
$share_num = intval($v['share_num']);
|
||||
if($sharenum >= $share_num){
|
||||
$integralnum = $v['integral_num'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $integralnum;
|
||||
}
|
||||
|
||||
//根据用户分享人数,获得摇钱树等级
|
||||
public static function gettreegrade($sharenum){
|
||||
$treegrade = 0;
|
||||
|
||||
$list = self::order('tree_grade asc')->select();
|
||||
if(!empty($list)){
|
||||
foreach ($list as $k=>$v){
|
||||
$share_num = intval($v['share_num']);
|
||||
if($sharenum >= $share_num){
|
||||
$treegrade = $v['tree_grade'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $treegrade;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | 海豚PHP框架 [ DolphinPHP ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 版权所有 2016~2019 广东卓锐软件有限公司 [ http://www.zrthink.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网站: http://dolphinphp.com
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace app\activity\model;
|
||||
|
||||
use think\Model as ThinkModel;
|
||||
|
||||
/**
|
||||
* 广告模型
|
||||
* @package app\cms\model
|
||||
*/
|
||||
class MoneyTreeLogs extends ThinkModel
|
||||
{
|
||||
// 设置当前模型对应的完整数据表名称
|
||||
protected $name = 'moneytree_logs';
|
||||
|
||||
// 自动写入时间戳
|
||||
protected $autoWriteTimestamp = true;
|
||||
|
||||
/**
|
||||
* 插入金币记录
|
||||
* @param int $uid 所属用户
|
||||
* @param int $tree_grade 树等级
|
||||
* @param int $integral_num 产生的金币
|
||||
* @author lily<lilyforworks@163.com>
|
||||
*/
|
||||
public static function addGetLog($uid,$tree_grade,$integral_num){
|
||||
$res = self::create([
|
||||
'uid'=>$uid,
|
||||
'tree_grade'=>$tree_grade,
|
||||
'integral_num'=>$integral_num,
|
||||
'create_time'=>time(),
|
||||
'update_time'=>time(),
|
||||
]);
|
||||
return $res;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006-2016 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: yunwuxin <448901948@qq.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace app\other\validate;
|
||||
|
||||
use think\Validate;
|
||||
|
||||
/**
|
||||
* 商品分类
|
||||
* @author 王海鑫
|
||||
*/
|
||||
class Category extends Validate
|
||||
{
|
||||
//定义验证规则
|
||||
protected $rule = [
|
||||
'title|分类名称' => 'require'
|
||||
];
|
||||
|
||||
protected $message = [
|
||||
'title.require' => '分类名称不能为空',
|
||||
];
|
||||
|
||||
}
|
|
@ -0,0 +1,207 @@
|
|||
{extend name="$_admin_base_layout" /}
|
||||
|
||||
{block name="plugins-css"}
|
||||
<link href="__LIBS__/jquery-nestable/jquery.nestable.css" rel="stylesheet" type="text/css" />
|
||||
{/block}
|
||||
|
||||
{block name="content"}
|
||||
<div class="alert alert-warning alert-dismissable">
|
||||
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
|
||||
<p><strong><i class="fa fa-fw fa-info-circle"></i> 提示:</strong></br>1:按住表头可拖动类别,调整后点击【保存类别】。</br>2:类别只沿用到二级类别。</p>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="block">
|
||||
{notempty name="tab_nav"}
|
||||
<ul class="nav nav-tabs">
|
||||
{volist name="tab_nav['tab_list']" id="tab"}
|
||||
<li {eq name="tab_nav.curr_tab" value="$key"}class="active"{/eq}>
|
||||
<a href="{$tab.url}">{$tab.title}</a>
|
||||
</li>
|
||||
{/volist}
|
||||
<li {eq name="tab_nav.curr_tab" value="module-sort"}class="active"{/eq}>
|
||||
<a href="{:url('', ['group' => 'module-sort'])}">模块排序</a>
|
||||
</li>
|
||||
<li class="pull-right">
|
||||
<ul class="block-options push-10-t push-10-r">
|
||||
<li>
|
||||
<button type="button" data-toggle="block-option" data-action="fullscreen_toggle"></button>
|
||||
</li>
|
||||
<li>
|
||||
<button type="button" data-toggle="block-option" data-action="refresh_toggle" data-action-mode="demo"><i class="si si-refresh"></i></button>
|
||||
</li>
|
||||
<li>
|
||||
<button type="button" data-toggle="block-option" data-action="content_toggle"></button>
|
||||
</li>
|
||||
<li>
|
||||
<button type="button" data-toggle="block-option" data-action="close"><i class="si si-close"></i></button>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
{else/}
|
||||
<div class="block-header bg-gray-lighter">
|
||||
<ul class="block-options">
|
||||
<li>
|
||||
<button type="button" data-toggle="block-option" data-action="fullscreen_toggle"></button>
|
||||
</li>
|
||||
<li>
|
||||
<button type="button" data-toggle="block-option" data-action="refresh_toggle" data-action-mode="demo"><i class="si si-refresh"></i></button>
|
||||
</li>
|
||||
<li>
|
||||
<button type="button" data-toggle="block-option" data-action="content_toggle"></button>
|
||||
</li>
|
||||
<li>
|
||||
<button type="button" data-toggle="block-option" data-action="close"><i class="si si-close"></i></button>
|
||||
</li>
|
||||
</ul>
|
||||
<h3 class="block-title">{$page_title}</h3>
|
||||
</div>
|
||||
{/notempty}
|
||||
<div class="block-content tab-content">
|
||||
<div class="tab-pane active">
|
||||
{notempty name="menus"}
|
||||
<div class="row data-table-toolbar">
|
||||
<div class="col-sm-12">
|
||||
<form action="{$Request.url}" method="get">
|
||||
<div class="toolbar-btn-action">
|
||||
<a title="新增" class="btn btn-primary" href="{:url('add', ['module' => $Request.param.group])}"><i class="fa fa-plus-circle"></i> 新增</a>
|
||||
<button title="保存" type="button" class="btn btn-default disabled" id="save" disabled><i class="fa fa-check-circle-o"></i> 保存类别</button>
|
||||
<button title="隐藏禁用类别" type="button" class="btn btn-danger" id="hide_disable"><i class="fa fa-eye-slash"></i> 隐藏禁用类别</button>
|
||||
<button title="显示禁用类别" type="button" class="btn btn-info" id="show_disable"><i class="fa fa-eye"></i> 显示禁用类别</button>
|
||||
<button title="展开所有类别" type="button" class="btn btn-success" id="expand-all"><i class="fa fa-plus"></i> 展开所有类别</button>
|
||||
<button title="收起所有类别" type="button" class="btn btn-warning" id="collapse-all"><i class="fa fa-minus"></i> 收起所有类别</button>
|
||||
<span class="form-inline">
|
||||
<input class="form-control" type="text" name="max" value="{$Request.get.max|default=''}" placeholder="显示层数">
|
||||
</span>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="dd" id="menu_list">
|
||||
<ol class="dd-list dd-collapsed">{$menus|raw}</ol>
|
||||
</div>
|
||||
{/notempty}
|
||||
|
||||
{notempty name="modules"}
|
||||
<form action="{:url('')}" method="post" name="sort-form" class="sort-form">
|
||||
<button title="保存" type="submit" class="btn btn-success push-10 ajax-post" target-form="sort-form">保存排序</button>
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div id="sortable" class="connectedSortable push-20">
|
||||
{volist name="modules" id="module"}
|
||||
<div class="sortable-item pull-left">
|
||||
<input type="hidden" name="sort[]" value="{$key}">
|
||||
<i class="{$module.icon}"></i> {$module.title}
|
||||
</div>
|
||||
{/volist}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
{/notempty}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/block}
|
||||
|
||||
{block name="script"}
|
||||
<script src="__LIBS__/jquery-nestable/jquery.nestable.js?v={:config('js_version')}"></script>
|
||||
<script src="__LIBS__/jquery-ui/jquery-ui.min.js?v={:config('js_version')}"></script>
|
||||
<script>
|
||||
$(document).ready(function(){
|
||||
// 模块拖拽
|
||||
$( "#sortable" ).sortable({
|
||||
connectWith: ".connectedSortable"
|
||||
}).disableSelection();
|
||||
|
||||
// 保存类别
|
||||
$('#save').click(function(){
|
||||
Dolphin.loading();
|
||||
$.post("{:url('save')}", {menus: $('#menu_list').nestable('serialize')}, function(data) {
|
||||
Dolphin.loading('hide');
|
||||
if (data.code) {
|
||||
$('#save').removeClass('btn-success').addClass('btn-default disabled');
|
||||
Dolphin.notify(data.msg, 'success');
|
||||
} else {
|
||||
Dolphin.notify(data.msg, 'danger');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// 初始化类别拖拽
|
||||
$('#menu_list').nestable({maxDepth:4}).on('change', function(){
|
||||
$('#save').removeAttr("disabled").removeClass('btn-default disabled').addClass('btn-success');
|
||||
});
|
||||
|
||||
// 隐藏禁用类别
|
||||
$('#hide_disable').click(function(){
|
||||
$('.dd-disable').hide();
|
||||
});
|
||||
|
||||
// 显示禁用类别
|
||||
$('#show_disable').click(function(){
|
||||
$('.dd-disable').show();
|
||||
});
|
||||
|
||||
// 展开所有类别
|
||||
$('#expand-all').click(function(){
|
||||
$('#menu_list').nestable('expandAll');
|
||||
});
|
||||
|
||||
// 收起所有类别
|
||||
$('#collapse-all').click(function(){
|
||||
$('#menu_list').nestable('collapseAll');
|
||||
});
|
||||
|
||||
// 禁用类别
|
||||
$('.dd3-content').delegate('.disable', 'click', function(){
|
||||
var self = $(this);
|
||||
var ids = self.data('ids');
|
||||
var ajax_url = '{:url("disable", ["table" => "product_category"])}';
|
||||
Dolphin.loading();
|
||||
$.post(ajax_url, {ids:ids}, function(data) {
|
||||
Dolphin.loading('hide');
|
||||
if (data.code) {
|
||||
self.attr('data-original-title', '启用').removeClass('disable').addClass('enable')
|
||||
.children().removeClass('fa-ban').addClass('fa-check-circle-o')
|
||||
.closest('.dd-item')
|
||||
.addClass('dd-disable');
|
||||
} else {
|
||||
Dolphin.notify(data.msg, 'danger');
|
||||
}
|
||||
});
|
||||
return false;
|
||||
});
|
||||
|
||||
// 启用类别
|
||||
$('.dd3-content').delegate('.enable', 'click', function(){
|
||||
var self = $(this);
|
||||
var ids = self.data('ids');
|
||||
var ajax_url = '{:url("enable", ["table" => "product_category"])}';
|
||||
Dolphin.loading();
|
||||
$.post(ajax_url, {ids:ids}, function(data) {
|
||||
Dolphin.loading('hide');
|
||||
if (data.code) {
|
||||
self.attr('data-original-title', '禁用').removeClass('enable').addClass('disable')
|
||||
.children().removeClass('fa-check-circle-o').addClass('fa-ban')
|
||||
.closest('.dd-item')
|
||||
.removeClass('dd-disable');
|
||||
} else {
|
||||
Dolphin.notify(data.msg, 'danger');
|
||||
}
|
||||
});
|
||||
return false;
|
||||
});
|
||||
|
||||
setTimeout(function(){
|
||||
$('#menu_list').nestable('expandAll');
|
||||
},1);
|
||||
});
|
||||
</script>
|
||||
{/block}
|
|
@ -0,0 +1,438 @@
|
|||
<!DOCTYPE html>
|
||||
<!--[if IE 9]> <html class="ie9 no-focus" lang="zh"> <![endif]-->
|
||||
<!--[if gt IE 9]><!--> <html class="no-focus" lang="zh"> <!--<![endif]-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
{block name="page-title"}<title>{$page_title|default='后台'} | {:config('web_site_title')} - CCU</title>{/block}
|
||||
<meta name="description" content="{:config('web_site_description')}">
|
||||
<meta name="author" content="chenmenchen">
|
||||
<meta name="robots" content="noindex, nofollow">
|
||||
<meta name="renderer" content="webkit">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1.0">
|
||||
<link rel="shortcut icon" href="/favicon.ico">
|
||||
<link rel="stylesheet" type="text/css" href="__ADMIN_CSS__/nprogress.css" rel="stylesheet" />
|
||||
<script type="text/javascript" src='__ADMIN_JS__/nprogress.js'></script>
|
||||
<style>
|
||||
#nprogress{
|
||||
position: fixed;
|
||||
z-index: 9999;
|
||||
}
|
||||
</style>
|
||||
<!-- Page JS Plugins CSS -->
|
||||
{notempty name="_css_files"}
|
||||
{eq name="Think.config.minify_status" value="1"}
|
||||
<link rel="stylesheet" href="{:minify('group', $_css_files)}">
|
||||
{else/}
|
||||
{volist name="_css_files" id="css"}
|
||||
{:load_assets($css)}
|
||||
{/volist}
|
||||
{/eq}
|
||||
{/notempty}
|
||||
{block name="plugins-css"}{/block}
|
||||
<!-- Bootstrap and OneUI CSS framework -->
|
||||
{eq name="Think.config.minify_status" value="1"}
|
||||
<link rel="stylesheet" id="css-main" href="{:minify('group', 'libs_css,core_css')}">
|
||||
{else/}
|
||||
<link rel="stylesheet" href="__LIBS__/sweetalert/sweetalert.min.css?v={:config('css_version')}">
|
||||
<link rel="stylesheet" href="__LIBS__/bootstrap3-editable/css/bootstrap-editable.css?v={:config('css_version')}">
|
||||
<link rel="stylesheet" href="__LIBS__/magnific-popup/magnific-popup.min.css?v={:config('css_version')}">
|
||||
<link rel="stylesheet" href="__ADMIN_CSS__/bootstrap.min.css?v={:config('css_version')}">
|
||||
<link rel="stylesheet" href="__LIBS__/select2/select2.css?v={:config('css_version')}">
|
||||
<link rel="stylesheet" href="__ADMIN_CSS__/oneui.css?v={:config('css_version')}">
|
||||
<link rel="stylesheet" href="__ADMIN_CSS__/ccu.css" id="css-main">
|
||||
{/eq}
|
||||
<!--页面css-->
|
||||
{block name="style"}{/block}
|
||||
{notempty name="Think.get._pop"}
|
||||
<style>
|
||||
#page-container.sidebar-l.sidebar-o {
|
||||
padding-left: 0;
|
||||
}
|
||||
.header-navbar-fixed #main-container {
|
||||
padding-top: 0;
|
||||
}
|
||||
</style>
|
||||
{/notempty}
|
||||
<!-- END Stylesheets -->
|
||||
<!--自定义css-->
|
||||
<link rel="stylesheet" href="__ADMIN_CSS__/custom.css?v={:config('css_version')}">
|
||||
<script>
|
||||
// url
|
||||
var ccu = {
|
||||
'top_menu_url': '{:url("admin/ajax/getSidebarMenu")}',
|
||||
'theme_url': '{:url("admin/ajax/setTheme")}',
|
||||
'jcrop_upload_url': '{:url("admin/attachment/upload", ["dir" => "images", "from" => "jcrop", "module" => request()->module()])}',
|
||||
'ueditor_upload_url': '{:url("admin/attachment/upload", ["dir" => "images", "from" => "ueditor", "module" => request()->module()])}',
|
||||
'WebUploader_swf': '__LIBS__/webuploader/Uploader.swf',
|
||||
'get_level_data': '{:url("admin/ajax/getLevelData")}',
|
||||
'quick_edit_url': '{:url("quickEdit")}',
|
||||
'aside_edit_url': '{:url("admin/system/quickEdit")}',
|
||||
'triggers': {$field_triggers|default=[]|json_encode}, // 触发器集合
|
||||
'field_hide': '{$field_hide|default=""}', // 需要隐藏的字段
|
||||
'field_values': '{$field_values|default=""}',
|
||||
'validate': '{$validate|default=""}', // 验证器
|
||||
'validate_fields': '{$validate_fields|default=""}', // 验证字段
|
||||
'search_field': '{:input("param.search_field", "")}', // 搜索字段
|
||||
// 字段过滤
|
||||
'_filter': '{$Request.param._filter ? $Request.param._filter : (isset($_filter) ? $_filter : "")}',
|
||||
'_filter_content': "{$Request.param._filter_content == '' ? (isset($_filter_content) ? $_filter_content : '') : $Request.param._filter_content}",
|
||||
'_field_display': '{$Request.param._field_display ? $Request.param._field_display : (isset($_field_display) ? $_field_display : "")}',
|
||||
'get_filter_list': '{:url("admin/ajax/getFilterList")}',
|
||||
'curr_url': '{:url("", $Request.route)}',
|
||||
'uploadUrl':'{:url("admin/upload/UploadFile")}',
|
||||
'checkUrl':'{:url("admin/upload/CheckHashed")}',
|
||||
'mergeUrl':'{:url("admin/upload/chunksMerge")}',
|
||||
'file_get_url':'<?php echo PUBLIC_PATH ?>',
|
||||
'UID':"{:session('user_auth.uid')}",
|
||||
'MODULE': '<?php $request = new Request(); echo $request::instance()->module() ?>',
|
||||
'layer': {:json_encode(config('zbuilder.pop'))},
|
||||
};
|
||||
</script>
|
||||
</head>
|
||||
<body id="body01">
|
||||
<script>
|
||||
NProgress.start();
|
||||
</script>
|
||||
<div id="page-container" class="sidebar-l sidebar-o side-scroll header-navbar-fixed">
|
||||
<!-- Side Overlay-->
|
||||
{empty name="Think.get._pop"}
|
||||
{block name="aside"}
|
||||
<aside id="side-overlay">
|
||||
<!-- Side Overlay Scroll Container -->
|
||||
<div id="side-overlay-scroll">
|
||||
<!-- Side Header -->
|
||||
<div class="side-header side-content">
|
||||
<!-- Layout API, functionality initialized in App() -> uiLayoutApi() -->
|
||||
<button class="btn btn-default pull-right" type="button" data-toggle="layout" data-action="side_overlay_close">
|
||||
<i class="fa fa-times"></i>
|
||||
</button>
|
||||
<span>
|
||||
<img class="img-avatar img-avatar32" src="{$Think.session.user_auth.avatar|get_avatar}" alt="">
|
||||
<span class="font-w600 push-10-l">{:session('user_auth.username')}</span>
|
||||
</span>
|
||||
</div>
|
||||
<!-- END Side Header -->
|
||||
<!--侧栏-->
|
||||
{include file="../application/common/builder/aside/layout.html" /}
|
||||
</div>
|
||||
<!-- END Side Overlay Scroll Container -->
|
||||
</aside>
|
||||
{/block}
|
||||
{/empty}
|
||||
<!-- END Side Overlay -->
|
||||
|
||||
<!-- Sidebar -->
|
||||
{empty name="Think.get._pop"}
|
||||
{block name="sidebar"}
|
||||
<nav id="sidebar">
|
||||
<!-- Sidebar Scroll Container -->
|
||||
<div id="sidebar-scroll">
|
||||
<!-- Sidebar Content -->
|
||||
<!-- Adding .sidebar-mini-hide to an element will hide it when the sidebar is in mini mode -->
|
||||
<div class="sidebar-content">
|
||||
<!-- Side Header -->
|
||||
<div class="side-header side-content bg-white-op ccu-header">
|
||||
<!-- Layout API, functionality initialized in App() -> uiLayoutApi() -->
|
||||
<button class="btn btn-link text-gray pull-right hidden-md hidden-lg" type="button" data-toggle="layout" data-action="sidebar_close">
|
||||
<i class="fa fa-times"></i>
|
||||
</button>
|
||||
|
||||
<a class="h5 text-white" href="{:url('admin/index/index')}">
|
||||
{notempty name="Think.config.web_site_logo"}
|
||||
<img src="{$Think.config.web_site_logo|get_file_path}" class="logo" alt="{$Think.config.web_site_title|default='CCU PHP'}">
|
||||
{else/}
|
||||
<img src="{$Think.config.public_static_path}admin/img/logo.png" class="logo" alt="CCU PHP">
|
||||
{/notempty}
|
||||
|
||||
{notempty name="Think.config.web_site_logo_text"}
|
||||
<img src="{$Think.config.web_site_logo_text|get_file_path}" class="logo-text sidebar-mini-hide" alt="{$Think.config.web_site_title|default='CCU PHP'}">
|
||||
{else/}
|
||||
<img src="{$Think.config.public_static_path}admin/img/logo-text.png" class="logo-text sidebar-mini-hide" alt="CCU PHP">
|
||||
{/notempty}
|
||||
</a>
|
||||
</div>
|
||||
<!-- END Side Header -->
|
||||
|
||||
<!-- Side Content -->
|
||||
<div class="side-content" id="sidebar-menu">
|
||||
{notempty name="_sidebar_menus"}
|
||||
<ul class="nav-main" id="nav-{$_location[0]['id']}">
|
||||
{volist name="_sidebar_menus" id="menu"}
|
||||
<li {$menu['id'] == $_location[1]["id"]?='class="open"'}>
|
||||
{notempty name="menu.url_value"}
|
||||
<a {if($menu['id'] == $_location[1]["id"])}class="active"{/if} href="{$menu.url_value}" target="{$menu.url_target}"><i class="{$menu.icon}"></i><span class="sidebar-mini-hide">{$menu.title}</span></a>
|
||||
{else/}
|
||||
<a class="nav-submenu nav_cur" data-toggle="nav-submenu" href="javascript:void(0);"><i class="{$menu.icon}"></i><span class="sidebar-mini-hide">{$menu.title}</span></a>
|
||||
{/notempty}
|
||||
{notempty name="menu['child']"}
|
||||
<ul>
|
||||
{volist name="menu['child']" id="submenu"}
|
||||
<li>
|
||||
<a {if(isset($_location[2]) && $submenu['id'] == $_location[2]["id"])}class="active"{/if} href="{$submenu.url_value}" target="{$submenu.url_target}"><i class="{$submenu.icon}"></i>{$submenu.title}</a>
|
||||
</li>
|
||||
{/volist}
|
||||
</ul>
|
||||
{/notempty}
|
||||
</li>
|
||||
{/volist}
|
||||
</ul>
|
||||
{/notempty}
|
||||
</div>
|
||||
<!-- END Side Content -->
|
||||
</div>
|
||||
<!-- Sidebar Content -->
|
||||
</div>
|
||||
<!-- END Sidebar Scroll Container -->
|
||||
</nav>
|
||||
{/block}
|
||||
{/empty}
|
||||
<!-- END Sidebar -->
|
||||
|
||||
<!-- Header -->
|
||||
{empty name="Think.get._pop"}
|
||||
{block name="header"}
|
||||
<header id="header-navbar" class="content-mini content-mini-full head_left">
|
||||
<!-- Header Navigation Right -->
|
||||
<ul class="nav-header pull-right">
|
||||
<li class="dropdown user user-menu username">
|
||||
<a href="javascript:::;" class="dropdown-toggle btn btn-default" data-toggle="dropdown">
|
||||
<img src="{$Think.session.user_auth.avatar|get_avatar}" class="user-image" alt="User Image">
|
||||
<span class="visible-lg-inline-block">{:session('user_auth.username')}</span>
|
||||
</a>
|
||||
<ul class="dropdown-menu">
|
||||
<!-- User image -->
|
||||
<li class="user-header">
|
||||
<img src="{$Think.session.user_auth.avatar|get_avatar}" class="img-circle" alt="User Image">
|
||||
<p>
|
||||
{:session('user_auth.role_name')}
|
||||
</p>
|
||||
</li>
|
||||
<!-- Menu Footer-->
|
||||
<li class="user-footer">
|
||||
<!--<div class="pull-left">
|
||||
<a href="{:url('admin/index/profile')}" class="btn btn-default btn-flat">简况</a>
|
||||
</div>
|
||||
<div class="pull-right">
|
||||
<a href="{:url('user/publics/signout')}" class="btn btn-default btn-flat">退出</a>
|
||||
</div>-->
|
||||
<ul class="user_list">
|
||||
<li>
|
||||
<a href="{:url('admin/index/profile')}"><i class="iconfont icon-ziliao"></i>简况</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="{:url('admin/index/public_cache')}" data-toggle="tooltip" data-placement="bottom" data-original-title="清空缓存"><i class="iconfont icon-shanchu"></i>清空缓存</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="/index.php" target="_blank" data-toggle="tooltip" data-placement="bottom" data-original-title="打开前台"><i class="iconfont icon-dakai"></i>打开前台</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="javascript:::;" data-toggle="layout" data-action="side_overlay_toggle" title="侧边栏"><i class="iconfont icon-bumenguanli"></i>站点开关</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="{:url('user/publics/signout')}"><i class="iconfont icon-tuichu"></i>退出</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<!-- END Header Navigation Right -->
|
||||
|
||||
<!-- Header Navigation Left -->
|
||||
<ul class="nav nav-pills pull-left">
|
||||
<li class="hidden-md hidden-lg">
|
||||
<!-- Layout API, functionality initialized in App() -> uiLayoutApi() -->
|
||||
<a href="javascript:void(0)" data-toggle="layout" data-action="sidebar_toggle"><i class="fa fa-navicon"></i></a>
|
||||
</li>
|
||||
<li class="hidden-xs hidden-sm">
|
||||
<!-- Layout API, functionality initialized in App() -> uiLayoutApi() -->
|
||||
<a href="javascript:void(0)" title="打开/关闭左侧导航" data-toggle="layout" data-action="sidebar_mini_toggle"><i class="fa fa-bars"></i></a>
|
||||
</li>
|
||||
|
||||
{volist name="_top_menus" id="menu"}
|
||||
<li class="hidden-xs hidden-sm {$menu['id'] == $_location[0]['id'] ?= 'active'}">
|
||||
{eq name="menu.url_type" value="module"}
|
||||
<a href="javascript:void(0);" data-module-id="{$menu['id']}" data-module="{$menu['module']}" data-controller="{$menu['controller']}" target="{$menu['url_target']}" class="top-menu"><i class="{$menu.icon}"></i> {$menu.title}</a>
|
||||
{else/}
|
||||
<a href="{$menu['url_value']}" target="{$menu['url_target']}"><i class="{$menu.icon}"></i> {$menu.title}</a>
|
||||
{/eq}
|
||||
</li>
|
||||
{/volist}
|
||||
<li>
|
||||
<!-- Opens the Apps modal found at the bottom of the page, before including JS code -->
|
||||
<a href="#" class="Small_btn" data-toggle="modal" data-target="#apps-modal"><i class="si si-grid"></i></a>
|
||||
</li>
|
||||
</ul>
|
||||
<!-- END Header Navigation Left -->
|
||||
</header>
|
||||
{/block}
|
||||
{/empty}
|
||||
<!-- END Header -->
|
||||
|
||||
<!-- Main Container -->
|
||||
<main id="main-container">
|
||||
<!-- Page Header -->
|
||||
{block name="page-header"}
|
||||
{empty name="Think.get._pop"}
|
||||
<div class="content bg-gray-lighter">
|
||||
<div class="row items-push">
|
||||
<div class="col-sm-7">
|
||||
<ol class="breadcrumb push-10-t">
|
||||
<li><i class="fa fa-map-marker"></i></li>
|
||||
{volist name="_location" id="v"}
|
||||
<li><a class="link-effect" href="{notempty name='$v["url_value"]'}{$v.url_value|url}{else />}javascript:void(0);{/notempty}">{$v.title}</a></li>
|
||||
{/volist}
|
||||
</ol>
|
||||
</div>
|
||||
<div class="col-sm-5 text-right hidden-xs">
|
||||
<!--<h1 class="page-heading">
|
||||
{$page_title|default=''}
|
||||
</h1>-->
|
||||
<span class="go_back" onclick="history.go(-1);" ><i class="fa fa-reply"></i>返回</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/empty}
|
||||
{/block}
|
||||
<!-- END Page Header -->
|
||||
|
||||
<!-- Page Content -->
|
||||
<div class="content">
|
||||
{// 页面提示钩子}
|
||||
{:hook('page_tips')}
|
||||
{:hook('order_notice')}
|
||||
{// 主体内容}
|
||||
{block name="content"}{/block}
|
||||
</div>
|
||||
<!-- END Page Content -->
|
||||
</main>
|
||||
<!-- END Main Container -->
|
||||
</div>
|
||||
<!-- END Page Container -->
|
||||
|
||||
<!-- Apps Modal -->
|
||||
<!-- Opens from the button in the header -->
|
||||
<div class="modal fade" id="apps-modal" tabindex="-1" role="dialog" aria-hidden="true">
|
||||
<div class="modal-dialog modal-dialog-top">
|
||||
<div class="modal-content">
|
||||
<!-- Apps Block -->
|
||||
<div class="block block-themed block-transparent">
|
||||
<div class="block-header bg-primary-dark">
|
||||
<ul class="block-options">
|
||||
<li>
|
||||
<button data-dismiss="modal" type="button"><i class="si si-close"></i></button>
|
||||
</li>
|
||||
</ul>
|
||||
<h3 class="block-title">所有模块</h3>
|
||||
</div>
|
||||
<div class="block-content">
|
||||
<div class="row text-center">
|
||||
{volist name="_top_menus_all" id="menu"}
|
||||
<div class="col-xs-6 col-sm-3">
|
||||
{eq name="menu.url_type" value="module"}
|
||||
<a class="block block-rounded top-menu" href="javascript:void(0);" data-module-id="{$menu['id']}" data-module="{$menu['module']}" data-controller="{$menu['controller']}" target="{$menu['url_target']}">
|
||||
<div class="block-content text-white {$menu['id'] == $_location[0]['id'] ? 'bg-primary' : 'bg-primary-dark'}">
|
||||
<i class="{$menu.icon} fa-2x"></i>
|
||||
<div class="font-w600 push-15-t push-15">{$menu.title}</div>
|
||||
</div>
|
||||
</a>
|
||||
{else/}
|
||||
<a class="block block-rounded" href="{$menu['url_value']}" target="{$menu['url_target']}">
|
||||
<div class="block-content text-white {$menu['id'] == $_location[0]['id'] ? 'bg-primary' : 'bg-primary-dark'}">
|
||||
<i class="{$menu.icon} fa-2x"></i>
|
||||
<div class="font-w600 push-15-t push-15">{$menu.title}</div>
|
||||
</div>
|
||||
</a>
|
||||
{/eq}
|
||||
</div>
|
||||
{/volist}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- END Apps Block -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- END Apps Modal -->
|
||||
<!-- OneUI Core JS: jQuery, Bootstrap, slimScroll, scrollLock, Appear, CountTo, Placeholder, Cookie and App.js -->
|
||||
{eq name="Think.config.minify_status" value="1"}
|
||||
<script src="{:minify('group', 'core_js,libs_js')}"></script>
|
||||
{else/}
|
||||
<script src="__ADMIN_JS__/core/jquery.min.js?v={:config('js_version')}"></script>
|
||||
<script src="__ADMIN_JS__/core/bootstrap.min.js?v={:config('js_version')}"></script>
|
||||
<script src="__ADMIN_JS__/core/jquery.slimscroll.min.js?v={:config('js_version')}"></script>
|
||||
<script src="__ADMIN_JS__/core/jquery.scrollLock.min.js?v={:config('js_version')}"></script>
|
||||
<script src="__ADMIN_JS__/core/jquery.appear.min.js?v={:config('js_version')}"></script>
|
||||
<script src="__ADMIN_JS__/core/jquery.countTo.min.js?v={:config('js_version')}"></script>
|
||||
<script src="__ADMIN_JS__/core/jquery.placeholder.min.js?v={:config('js_version')}"></script>
|
||||
<script src="__ADMIN_JS__/core/js.cookie.min.js?v={:config('js_version')}"></script>
|
||||
<script src="__LIBS__/bootstrap3-editable/js/bootstrap-editable.min.js?v={:config('js_version')}"></script>
|
||||
<script src="__LIBS__/magnific-popup/magnific-popup.min.js?v={:config('js_version')}"></script>
|
||||
<script src="__ADMIN_JS__/app.js?v={:config('js_version')}"></script>
|
||||
<script src="__ADMIN_JS__/ccu.js?v={:config('js_version')}"></script>
|
||||
<script src="__ADMIN_JS__/builder/form.js?v={:config('js_version')}"></script>
|
||||
<script src="__ADMIN_JS__/builder/aside.js?v={:config('js_version')}"></script>
|
||||
<script src="__ADMIN_JS__/builder/table.js?v={:config('js_version')}"></script>
|
||||
<script src="__LIBS__/bootstrap-notify/bootstrap-notify.min.js?v={:config('js_version')}"></script>
|
||||
<script src="__LIBS__/sweetalert/sweetalert.min.js?v={:config('js_version')}"></script>
|
||||
<script src="__LIBS__/colResizable/colResizable-1.6.min.js?v={:config('js_version')}"></script>
|
||||
{/eq}
|
||||
|
||||
<!-- Page JS Plugins -->
|
||||
<script src="__LIBS__/layer/layer.js?v={:config('js_version')}"></script>
|
||||
{notempty name="_js_files"}
|
||||
{eq name="Think.config.minify_status" value="1"}
|
||||
<script src="{:minify('group', $_js_files)}"></script>
|
||||
{else/}
|
||||
{volist name="_js_files" id="js"}
|
||||
{:load_assets($js, 'js')}
|
||||
{/volist}
|
||||
{/eq}
|
||||
{/notempty}
|
||||
|
||||
<script>
|
||||
(function (window) {
|
||||
var theUA = window.navigator.userAgent.toLowerCase();
|
||||
if ((theUA.match(/msie\s\d+/) && theUA.match(/msie\s\d+/)[0]) || (theUA.match(/trident\s?\d+/) && theUA.match(/trident\s?\d+/)[0])) {
|
||||
var ieVersion = theUA.match(/msie\s\d+/)[0].match(/\d+/)[0] || theUA.match(/trident\s?\d+/)[0];
|
||||
if (ieVersion < 9) {
|
||||
var str = "妳的浏览器版本太low了\n已经和时代脱轨了 :(";
|
||||
var str2 = "推荐使用:<a href='https://www.baidu.com/s?ie=UTF-8&wd=%E8%B0%B7%E6%AD%8C%E6%B5%8F%E8%A7%88%E5%99%A8 ' target='_blank' style='color:#cc0'>谷歌</a>," +
|
||||
"<a href='https://www.baidu.com/s?ie=UTF-8&wd=%E7%81%AB%E7%8B%90%E6%B5%8F%E8%A7%88%E5%99%A8 ' target='_blank' style='color:#cc0'>火狐</a>," +
|
||||
"<a href='https://www.baidu.com/s?ie=UTF-8&wd=%E7%8C%8E%E8%B1%B9%E6%B5%8F%E8%A7%88%E5%99%A8 ' target='_blank' style='color:#cc0'>猎豹</a>,其他双核急速模式";
|
||||
document.writeln("<pre style='text-align:center;color:#fff;background-color:#0cc; height:100%;border:0;position:fixed;top:0;left:0;width:100%;z-index:1234'>" +
|
||||
"<h2 style='padding-top:200px;margin:0'><strong>" + str + "<br/></strong></h2><p>" +
|
||||
str2 + "</p><h2 style='margin:0'><strong>如果妳的使用的是双核浏览器,请切换到极速模式访问<br/></strong></h2></pre>");
|
||||
document.execCommand("Stop");
|
||||
document.body.style.height="100%";
|
||||
document.body.style.overflow="hidden";
|
||||
};
|
||||
}
|
||||
})(window);
|
||||
</script>
|
||||
|
||||
<script>
|
||||
jQuery(function () {
|
||||
App.initHelpers(['appear', 'slimscroll', 'magnific-popup', 'table-tools']);
|
||||
{notempty name="_js_init"}
|
||||
App.initHelpers({$_js_init});
|
||||
{/notempty}
|
||||
$(".maxtip").each(function(){
|
||||
if($(this).outerWidth()>300)
|
||||
{
|
||||
$(this).addClass("w300");
|
||||
}
|
||||
});
|
||||
$("table.table").colResizable({resizeMode:'overflow'});
|
||||
});
|
||||
</script>
|
||||
|
||||
<!--页面js-->
|
||||
{block name="script"}{/block}
|
||||
<script>
|
||||
$(function () {
|
||||
NProgress.done();
|
||||
})
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,73 @@
|
|||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | 海豚PHP框架 [ DolphinPHP ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 版权所有 2016~2019 广东卓锐软件有限公司 [ http://www.zrthink.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网站: http://dolphinphp.com
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace app\admin\controller;
|
||||
|
||||
use app\common\builder\ZBuilder;
|
||||
use app\admin\model\Action as ActionModel;
|
||||
use app\admin\model\Module as ModuleModel;
|
||||
|
||||
/**
|
||||
* 行为管理控制器
|
||||
* @package app\admin\controller
|
||||
*/
|
||||
class Action extends Admin
|
||||
{
|
||||
/**
|
||||
* 首页
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return mixed
|
||||
* @throws \think\Exception
|
||||
* @throws \think\exception\DbException
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
// 查询
|
||||
$map = $this->getMap();
|
||||
// 数据列表
|
||||
$data_list = ActionModel::where($map)->order('id desc')->paginate();
|
||||
// 所有模块的名称和标题
|
||||
$list_module = ModuleModel::getModule();
|
||||
|
||||
// 新增或编辑页面的字段
|
||||
$fields = [
|
||||
['hidden', 'id'],
|
||||
['select', 'module', '所属模块', '', $list_module],
|
||||
['text', 'name', '行为标识', '由英文字母和下划线组成'],
|
||||
['text', 'title', '行为名称', ''],
|
||||
['textarea', 'remark', '行为描述'],
|
||||
['textarea', 'rule', '行为规则', '不写则只记录日志'],
|
||||
['textarea', 'log', '日志规则', '记录日志备注时按此规则来生成,支持[变量|函数]。目前变量有:user,time,model,record,data,details'],
|
||||
['radio', 'status', '立即启用', '', ['否', '是'], 1]
|
||||
];
|
||||
|
||||
// 使用ZBuilder快速创建数据表格
|
||||
return ZBuilder::make('table')
|
||||
->setPageTitle('行为管理') // 设置页面标题
|
||||
->setSearch(['name' => '标识', 'title' => '名称']) // 设置搜索框
|
||||
->addColumns([ // 批量添加数据列
|
||||
['id', 'ID'],
|
||||
['name', '标识'],
|
||||
['title', '名称'],
|
||||
['remark', '描述'],
|
||||
['module', '所属模块', 'callback', function($module, $list_module){
|
||||
return isset($list_module[$module]) ? $list_module[$module] : '未知';
|
||||
}, $list_module],
|
||||
['status', '状态', 'switch'],
|
||||
['right_button', '操作', 'btn']
|
||||
])
|
||||
->autoAdd($fields, '', true, true) // 添加自动新增按钮
|
||||
->autoEdit($fields, '', true, true) // 添加自动编辑按钮
|
||||
->addTopButtons('enable,disable,delete') // 批量添加顶部按钮
|
||||
->addRightButtons('delete') // 批量添加右侧按钮
|
||||
->addFilter('module', $list_module)
|
||||
->setRowList($data_list) // 设置表格数据
|
||||
->fetch(); // 渲染模板
|
||||
}
|
||||
}
|
|
@ -0,0 +1,507 @@
|
|||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | 海豚PHP框架 [ DolphinPHP ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 版权所有 2016~2019 广东卓锐软件有限公司 [ http://www.zrthink.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网站: http://dolphinphp.com
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace app\admin\controller;
|
||||
|
||||
use app\common\controller\Common;
|
||||
use app\common\builder\ZBuilder;
|
||||
use app\admin\model\Menu as MenuModel;
|
||||
use app\admin\model\Module as ModuleModel;
|
||||
use app\admin\model\Icon as IconModel;
|
||||
use app\user\model\Role as RoleModel;
|
||||
use app\user\model\Message as MessageModel;
|
||||
use think\facade\Cache;
|
||||
use think\Db;
|
||||
use think\facade\App;
|
||||
use think\helper\Hash;
|
||||
|
||||
/**
|
||||
* 后台公共控制器
|
||||
* @package app\admin\controller
|
||||
*/
|
||||
class Admin extends Common
|
||||
{
|
||||
/**
|
||||
* 初始化
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @throws \think\Exception
|
||||
*/
|
||||
protected function initialize()
|
||||
{
|
||||
parent::initialize();
|
||||
// 是否拒绝ie浏览器访问
|
||||
if (config('system.deny_ie') && get_browser_type() == 'ie') {
|
||||
$this->redirect('admin/ie/index');
|
||||
}
|
||||
|
||||
// 判断是否登录,并定义用户ID常量
|
||||
defined('UID') or define('UID', $this->isLogin());
|
||||
|
||||
// 设置当前角色菜单节点权限
|
||||
role_auth();
|
||||
|
||||
// 检查权限
|
||||
if (!RoleModel::checkAuth()) $this->error('权限不足!');
|
||||
|
||||
// 设置分页参数
|
||||
$this->setPageParam();
|
||||
|
||||
// 如果不是ajax请求,则读取菜单
|
||||
if (!$this->request->isAjax()) {
|
||||
// 读取顶部菜单
|
||||
$this->assign('_top_menus', MenuModel::getTopMenu(config('top_menu_max'), '_top_menus'));
|
||||
// 读取全部顶级菜单
|
||||
$this->assign('_top_menus_all', MenuModel::getTopMenu('', '_top_menus_all'));
|
||||
// 获取侧边栏菜单
|
||||
$this->assign('_sidebar_menus', MenuModel::getSidebarMenu());
|
||||
// 获取面包屑导航
|
||||
$this->assign('_location', MenuModel::getLocation('', true));
|
||||
// 获取当前用户未读消息数量
|
||||
$this->assign('_message', MessageModel::getMessageCount());
|
||||
// 获取自定义图标
|
||||
$this->assign('_icons', IconModel::getUrls());
|
||||
// 构建侧栏
|
||||
$data = [
|
||||
'table' => 'admin_config', // 表名或模型名
|
||||
'prefix' => 1,
|
||||
'module' => 'admin',
|
||||
'controller' => 'system',
|
||||
'action' => 'quickedit',
|
||||
];
|
||||
$table_token = substr(sha1('_aside'), 0, 8);
|
||||
session($table_token, $data);
|
||||
$settings = [
|
||||
[
|
||||
'title' => '站点开关',
|
||||
'tips' => '站点关闭后将不能访问',
|
||||
'checked' => Db::name('admin_config')->where('id', 1)->value('value'),
|
||||
'table' => $table_token,
|
||||
'id' => 1,
|
||||
'field' => 'value'
|
||||
]
|
||||
];
|
||||
ZBuilder::make('aside')
|
||||
->addBlock('switch', '系统设置', $settings);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前操作模型
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return object|\think\db\Query
|
||||
*/
|
||||
final protected function getCurrModel()
|
||||
{
|
||||
$table_token = input('param._t', '');
|
||||
$module = $this->request->module();
|
||||
$controller = parse_name($this->request->controller());
|
||||
|
||||
$table_token == '' && $this->error('缺少参数');
|
||||
!session('?'.$table_token) && $this->error('参数错误');
|
||||
|
||||
$table_data = session($table_token);
|
||||
$table = $table_data['table'];
|
||||
|
||||
$Model = null;
|
||||
if ($table_data['prefix'] == 2) {
|
||||
// 使用模型
|
||||
try {
|
||||
$Model = App::model($table);
|
||||
} catch (\Exception $e) {
|
||||
$this->error('找不到模型:'.$table);
|
||||
}
|
||||
} else {
|
||||
// 使用DB类
|
||||
$table == '' && $this->error('缺少表名');
|
||||
if ($table_data['module'] != $module || $table_data['controller'] != $controller) {
|
||||
$this->error('非法操作');
|
||||
}
|
||||
|
||||
$Model = $table_data['prefix'] == 0 ? Db::table($table) : Db::name($table);
|
||||
}
|
||||
|
||||
return $Model;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置分页参数
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
*/
|
||||
final protected function setPageParam()
|
||||
{
|
||||
_system_check();
|
||||
$list_rows = !empty(input('param.list_rows')) ? input('param.list_rows') : config('list_rows');
|
||||
config('paginate.list_rows', $list_rows);
|
||||
config('paginate.query', input('get.'));
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查是否登录,没有登录则跳转到登录页面
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return int
|
||||
*/
|
||||
final protected function isLogin()
|
||||
{
|
||||
// 判断是否登录
|
||||
if ($uid = is_signin()) {
|
||||
// 已登录
|
||||
return $uid;
|
||||
} else {
|
||||
// 未登录
|
||||
$this->redirect('user/publics/signin');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 禁用
|
||||
* @param array $record 行为日志内容
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @throws \think\Exception
|
||||
* @throws \think\exception\PDOException
|
||||
*/
|
||||
public function disable($record = [])
|
||||
{
|
||||
return $this->setStatus('disable', $record);
|
||||
}
|
||||
|
||||
/**
|
||||
* 启用
|
||||
* @param array $record 行为日志内容
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @throws \think\Exception
|
||||
* @throws \think\exception\PDOException
|
||||
*/
|
||||
public function enable($record = [])
|
||||
{
|
||||
return $this->setStatus('enable', $record);
|
||||
}
|
||||
|
||||
/**
|
||||
* 启用
|
||||
* @param array $record 行为日志内容
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @throws \think\Exception
|
||||
* @throws \think\exception\PDOException
|
||||
*/
|
||||
public function delete($record = [])
|
||||
{
|
||||
return $this->setStatus('delete', $record);
|
||||
}
|
||||
|
||||
/**
|
||||
* 快速编辑
|
||||
* @param array $record 行为日志内容
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
*/
|
||||
public function quickEdit($record = [])
|
||||
{
|
||||
$field = input('post.name', '');
|
||||
$value = input('post.value', '');
|
||||
$type = input('post.type', '');
|
||||
$id = input('post.pk', '');
|
||||
$validate = input('post.validate', '');
|
||||
$validate_fields = input('post.validate_fields', '');
|
||||
|
||||
$field == '' && $this->error('缺少字段名');
|
||||
$id == '' && $this->error('缺少主键值');
|
||||
|
||||
$Model = $this->getCurrModel();
|
||||
$protect_table = [
|
||||
'__ADMIN_USER__',
|
||||
'__ADMIN_ROLE__',
|
||||
config('database.prefix').'admin_user',
|
||||
config('database.prefix').'admin_role',
|
||||
];
|
||||
|
||||
// 验证是否操作管理员
|
||||
if (in_array($Model->getTable(), $protect_table) && $id == 1) {
|
||||
$this->error('禁止操作超级管理员');
|
||||
}
|
||||
|
||||
// 验证器
|
||||
if ($validate != '') {
|
||||
$validate_fields = array_flip(explode(',', $validate_fields));
|
||||
if (isset($validate_fields[$field])) {
|
||||
$result = $this->validate([$field => $value], $validate.'.'.$field);
|
||||
if (true !== $result) $this->error($result);
|
||||
}
|
||||
}
|
||||
|
||||
switch ($type) {
|
||||
// 日期时间需要转为时间戳
|
||||
case 'combodate':
|
||||
$value = strtotime($value);
|
||||
break;
|
||||
// 开关
|
||||
case 'switch':
|
||||
$value = $value == 'true' ? 1 : 0;
|
||||
break;
|
||||
// 开关
|
||||
case 'password':
|
||||
$value = Hash::make((string)$value);
|
||||
break;
|
||||
}
|
||||
|
||||
// 主键名
|
||||
$pk = $Model->getPk();
|
||||
$result = $Model->where($pk, $id)->setField($field, $value);
|
||||
|
||||
cache('hook_plugins', null);
|
||||
cache('system_config', null);
|
||||
cache('access_menus', null);
|
||||
if (false !== $result) {
|
||||
// 记录行为日志
|
||||
if (!empty($record)) {
|
||||
call_user_func_array('action_log', $record);
|
||||
}
|
||||
$this->success('操作成功');
|
||||
} else {
|
||||
$this->error('操作失败');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 自动创建添加页面
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return mixed
|
||||
* @throws \think\Exception
|
||||
*/
|
||||
public function add()
|
||||
{
|
||||
// 获取表单项
|
||||
$cache_name = $this->request->module().'/'.parse_name($this->request->controller()).'/add';
|
||||
$cache_name = strtolower($cache_name);
|
||||
$form = Cache::get($cache_name, []);
|
||||
if (!$form) {
|
||||
$this->error('自动新增数据不存在,请重新打开此页面');
|
||||
}
|
||||
|
||||
// 保存数据
|
||||
if ($this->request->isPost()) {
|
||||
// 表单数据
|
||||
$data = $this->request->post();
|
||||
$_pop = $this->request->get('_pop');
|
||||
|
||||
// 验证
|
||||
if ($form['validate'] != '') {
|
||||
$result = $this->validate($data, $form['validate']);
|
||||
if(true !== $result) $this->error($result);
|
||||
}
|
||||
|
||||
// 是否需要自动插入时间
|
||||
if ($form['auto_time'] != '') {
|
||||
$now_time = $this->request->time();
|
||||
foreach ($form['auto_time'] as $item) {
|
||||
if (strpos($item, '|')) {
|
||||
list($item, $format) = explode('|', $item);
|
||||
$data[$item] = date($format, $now_time);
|
||||
} else {
|
||||
$data[$item] = $form['format'] != '' ? date($form['format'], $now_time) : $now_time;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 插入数据
|
||||
if (Db::name($form['table'])->insert($data)) {
|
||||
if ($_pop == 1) {
|
||||
$this->success('新增成功', null, '_parent_reload');
|
||||
} else {
|
||||
$this->success('新增成功', $form['go_back']);
|
||||
}
|
||||
} else {
|
||||
$this->error('新增失败');
|
||||
}
|
||||
}
|
||||
|
||||
// 显示添加页面
|
||||
return ZBuilder::make('form')
|
||||
->addFormItems($form['items'])
|
||||
->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* 自动创建编辑页面
|
||||
* @param string $id 主键值
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return mixed
|
||||
* @throws \think\Exception
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @throws \think\exception\DbException
|
||||
* @throws \think\exception\PDOException
|
||||
*/
|
||||
public function edit($id = '')
|
||||
{
|
||||
if ($id === '') $this->error('参数错误');
|
||||
|
||||
// 获取表单项
|
||||
$cache_name = $this->request->module().'/'.parse_name($this->request->controller()).'/edit';
|
||||
$cache_name = strtolower($cache_name);
|
||||
$form = Cache::get($cache_name, []);
|
||||
if (!$form) {
|
||||
$this->error('自动编辑数据不存在,请重新打开此页面');
|
||||
}
|
||||
|
||||
// 保存数据
|
||||
if ($this->request->isPost()) {
|
||||
// 表单数据
|
||||
$data = $this->request->post();
|
||||
$_pop = $this->request->get('_pop');
|
||||
|
||||
// 验证
|
||||
if ($form['validate'] != '') {
|
||||
$result = $this->validate($data, $form['validate']);
|
||||
if(true !== $result) $this->error($result);
|
||||
}
|
||||
|
||||
// 是否需要自动插入时间
|
||||
if ($form['auto_time'] != '') {
|
||||
$now_time = $this->request->time();
|
||||
foreach ($form['auto_time'] as $item) {
|
||||
if (strpos($item, '|')) {
|
||||
list($item, $format) = explode('|', $item);
|
||||
$data[$item] = date($format, $now_time);
|
||||
} else {
|
||||
$data[$item] = $form['format'] != '' ? date($form['format'], $now_time) : $now_time;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 更新数据
|
||||
if (false !== Db::name($form['table'])->update($data)) {
|
||||
if ($_pop == 1) {
|
||||
$this->success('编辑成功', null, '_parent_reload');
|
||||
} else {
|
||||
$this->success('编辑成功', $form['go_back']);
|
||||
}
|
||||
} else {
|
||||
$this->error('编辑失败');
|
||||
}
|
||||
}
|
||||
|
||||
// 获取数据
|
||||
$info = Db::name($form['table'])->find($id);
|
||||
|
||||
// 使用ZBuilder快速创建表单
|
||||
return ZBuilder::make('form')
|
||||
->setPageTitle('编辑')
|
||||
->addFormItems($form['items'])
|
||||
->setFormData($info)
|
||||
->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置状态
|
||||
* 禁用、启用、删除都是调用这个内部方法
|
||||
* @param string $type 操作类型:enable,disable,delete
|
||||
* @param array $record 行为日志内容
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @throws \think\Exception
|
||||
* @throws \think\exception\PDOException
|
||||
*/
|
||||
public function setStatus($type = '', $record = [])
|
||||
{
|
||||
$ids = $this->request->isPost() ? input('post.ids/a') : input('param.ids');
|
||||
$ids = (array)$ids;
|
||||
$field = input('param.field', 'status');
|
||||
|
||||
empty($ids) && $this->error('缺少主键');
|
||||
|
||||
$Model = $this->getCurrModel();
|
||||
$protect_table = [
|
||||
'__ADMIN_USER__',
|
||||
'__ADMIN_ROLE__',
|
||||
'__ADMIN_MODULE__',
|
||||
config('database.prefix').'admin_user',
|
||||
config('database.prefix').'admin_role',
|
||||
config('database.prefix').'admin_module',
|
||||
];
|
||||
|
||||
// 禁止操作核心表的主要数据
|
||||
if (in_array($Model->getTable(), $protect_table) && in_array('1', $ids)) {
|
||||
$this->error('禁止操作');
|
||||
}
|
||||
|
||||
// 主键名称
|
||||
$pk = $Model->getPk();
|
||||
$map = [
|
||||
[$pk, 'in', $ids]
|
||||
];
|
||||
|
||||
$result = false;
|
||||
switch ($type) {
|
||||
case 'disable': // 禁用
|
||||
$result = $Model->where($map)->setField($field, 0);
|
||||
break;
|
||||
case 'enable': // 启用
|
||||
$result = $Model->where($map)->setField($field, 1);
|
||||
break;
|
||||
case 'delete': // 删除
|
||||
$result = $Model->where($map)->delete();
|
||||
break;
|
||||
default:
|
||||
$this->error('非法操作');
|
||||
break;
|
||||
}
|
||||
|
||||
if (false !== $result) {
|
||||
Cache::clear();
|
||||
// 记录行为日志
|
||||
if (!empty($record)) {
|
||||
call_user_func_array('action_log', $record);
|
||||
}
|
||||
$this->success('操作成功');
|
||||
} else {
|
||||
$this->error('操作失败');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 模块设置
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return mixed
|
||||
* @throws \think\Exception
|
||||
* @throws \think\exception\PDOException
|
||||
*/
|
||||
public function moduleConfig()
|
||||
{
|
||||
// 当前模块名
|
||||
$module = $this->request->module();
|
||||
|
||||
// 保存
|
||||
if ($this->request->isPost()) {
|
||||
$data = $this->request->post();
|
||||
$data = json_encode($data);
|
||||
|
||||
if (false !== ModuleModel::where('name', $module)->update(['config' => $data])) {
|
||||
cache('module_config_'.$module, null);
|
||||
$this->success('更新成功');
|
||||
} else {
|
||||
$this->error('更新失败');
|
||||
}
|
||||
}
|
||||
|
||||
// 模块配置信息
|
||||
$module_info = ModuleModel::getInfoFromFile($module);
|
||||
$config = $module_info['config'];
|
||||
$trigger = isset($module_info['trigger']) ? $module_info['trigger'] : [];
|
||||
|
||||
// 数据库内的模块信息
|
||||
$db_config = ModuleModel::where('name', $module)->value('config');
|
||||
$db_config = json_decode($db_config, true);
|
||||
|
||||
// 使用ZBuilder快速创建表单
|
||||
return ZBuilder::make('form')
|
||||
->setPageTitle('模块设置')
|
||||
->addFormItems($config)
|
||||
->setFormdata($db_config) // 设置表格数据
|
||||
->setTrigger($trigger) // 设置触发
|
||||
->fetch();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,308 @@
|
|||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | 海豚PHP框架 [ DolphinPHP ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 版权所有 2016~2019 广东卓锐软件有限公司 [ http://www.zrthink.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网站: http://dolphinphp.com
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace app\admin\controller;
|
||||
|
||||
use app\common\controller\Common;
|
||||
use app\admin\model\Menu as MenuModel;
|
||||
use app\admin\model\Attachment as AttachmentModel;
|
||||
use think\facade\Cache;
|
||||
use think\Db;
|
||||
|
||||
/**
|
||||
* 用于处理ajax请求的控制器
|
||||
* @package app\admin\controller
|
||||
*/
|
||||
class Ajax extends Common
|
||||
{
|
||||
/**
|
||||
* 获取联动数据
|
||||
* @param string $token token
|
||||
* @param int $pid 父级ID
|
||||
* @param string $pidkey 父级id字段名
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function getLevelData($token = '', $pid = 0, $pidkey = 'pid')
|
||||
{
|
||||
if ($token == '') {
|
||||
return json(['code' => 0, 'msg' => '缺少Token']);
|
||||
}
|
||||
|
||||
$token_data = session($token);
|
||||
$table = $token_data['table'];
|
||||
$option = $token_data['option'];
|
||||
$key = $token_data['key'];
|
||||
|
||||
$data_list = Db::name($table)->where($pidkey, $pid)->column($option, $key);
|
||||
|
||||
if ($data_list === false) {
|
||||
return json(['code' => 0, 'msg' => '查询失败']);
|
||||
}
|
||||
|
||||
if ($data_list) {
|
||||
$result = [
|
||||
'code' => 1,
|
||||
'msg' => '请求成功',
|
||||
'list' => format_linkage($data_list)
|
||||
];
|
||||
return json($result);
|
||||
} else {
|
||||
return json(['code' => 0, 'msg' => '查询不到数据']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取筛选数据
|
||||
* @param string $token
|
||||
* @param array $map 查询条件
|
||||
* @param string $options 选项,用于显示转换
|
||||
* @param string $list 选项缓存列表名称
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function getFilterList($token = '', $map = [], $options = '', $list = '')
|
||||
{
|
||||
if ($list != '') {
|
||||
$result = [
|
||||
'code' => 1,
|
||||
'msg' => '请求成功',
|
||||
'list' => Cache::get($list)
|
||||
];
|
||||
return json($result);
|
||||
}
|
||||
if ($token == '') {
|
||||
return json(['code' => 0, 'msg' => '缺少Token']);
|
||||
}
|
||||
|
||||
$token_data = session($token);
|
||||
$table = $token_data['table'];
|
||||
$field = $token_data['field'];
|
||||
|
||||
if ($field == '') {
|
||||
return json(['code' => 0, 'msg' => '缺少字段']);
|
||||
}
|
||||
if (!empty($map) && is_array($map)) {
|
||||
foreach ($map as &$item) {
|
||||
if (is_array($item)) {
|
||||
foreach ($item as &$value) {
|
||||
$value = trim($value);
|
||||
}
|
||||
} else {
|
||||
$item = trim($item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (strpos($table, '/')) {
|
||||
$data_list = model($table)->where($map)->group($field)->column($field);
|
||||
} else {
|
||||
$data_list = Db::name($table)->where($map)->group($field)->column($field);
|
||||
}
|
||||
|
||||
if ($data_list === false) {
|
||||
return json(['code' => 0, 'msg' => '查询失败']);
|
||||
}
|
||||
|
||||
if ($data_list) {
|
||||
if ($options != '') {
|
||||
// 从缓存获取选项数据
|
||||
$options = cache($options);
|
||||
if ($options) {
|
||||
$temp_data_list = [];
|
||||
foreach ($data_list as $item) {
|
||||
$temp_data_list[$item] = isset($options[$item]) ? $options[$item] : '';
|
||||
}
|
||||
$data_list = $temp_data_list;
|
||||
} else {
|
||||
$data_list = parse_array($data_list);
|
||||
}
|
||||
} else {
|
||||
$data_list = parse_array($data_list);
|
||||
}
|
||||
|
||||
$result = [
|
||||
'code' => 1,
|
||||
'msg' => '请求成功',
|
||||
'list' => $data_list
|
||||
];
|
||||
return json($result);
|
||||
} else {
|
||||
return json(['code' => 0, 'msg' => '查询不到数据']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定模块的菜单
|
||||
* @param string $module 模块名
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return mixed
|
||||
*/
|
||||
public function getModuleMenus($module = '')
|
||||
{
|
||||
if (!is_signin()) {
|
||||
$this->error('请先登录');
|
||||
}
|
||||
$menus = MenuModel::getMenuTree(0, '', $module);
|
||||
$result = [
|
||||
'code' => 1,
|
||||
'msg' => '请求成功',
|
||||
'list' => format_linkage($menus)
|
||||
];
|
||||
return json($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置配色方案
|
||||
* @param string $theme 配色名称
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
*/
|
||||
public function setTheme($theme = '') {
|
||||
if (!is_signin()) {
|
||||
$this->error('请先登录');
|
||||
}
|
||||
$themes = ['default', 'amethyst', 'city', 'flat', 'modern', 'smooth'];
|
||||
if (!in_array($theme, $themes)) {
|
||||
$this->error('非法操作');
|
||||
}
|
||||
$map['name'] = 'system_color';
|
||||
$map['group'] = 'system';
|
||||
|
||||
if (Db::name('admin_config')->where($map)->setField('value', $theme)) {
|
||||
$this->success('设置成功');
|
||||
} else {
|
||||
$this->error('设置失败,请重试');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取侧栏菜单
|
||||
* @param string $module_id 模块id
|
||||
* @param string $module 模型名
|
||||
* @param string $controller 控制器名
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return string
|
||||
*/
|
||||
public function getSidebarMenu($module_id = '', $module = '', $controller = '')
|
||||
{
|
||||
if (!is_signin()) {
|
||||
$this->error('登录已失效,请重新登录', 'user/publics/signin');
|
||||
}
|
||||
|
||||
role_auth();
|
||||
$menus = MenuModel::getSidebarMenu($module_id, $module, $controller);
|
||||
|
||||
$output = '';
|
||||
foreach ($menus as $key => $menu) {
|
||||
if (!empty($menu['url_value'])) {
|
||||
$output = $menu['url_value'];
|
||||
break;
|
||||
}
|
||||
if (!empty($menu['child'])) {
|
||||
$output = $menu['child'][0]['url_value'];
|
||||
break;
|
||||
}
|
||||
}
|
||||
$this->success('获取成功', null, $output);
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查附件是否存在
|
||||
* @param string $md5 文件md5
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function check($md5 = '')
|
||||
{
|
||||
$md5 == '' && $this->error('参数错误');
|
||||
|
||||
// 判断附件是否已存在
|
||||
if ($file_exists = AttachmentModel::get(['md5' => $md5])) {
|
||||
if ($file_exists['driver'] == 'local') {
|
||||
$file_path = PUBLIC_PATH.$file_exists['path'];
|
||||
} else {
|
||||
$file_path = $file_exists['path'];
|
||||
}
|
||||
return json([
|
||||
'code' => 1,
|
||||
'info' => '上传成功',
|
||||
'class' => 'success',
|
||||
'id' => $file_exists['id'],
|
||||
'path' => $file_path
|
||||
]);
|
||||
} else {
|
||||
$this->error('文件不存在');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取我的角色集合
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @throws \think\exception\DbException
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
*/
|
||||
public function getMyRoles()
|
||||
{
|
||||
if (!is_signin()) {
|
||||
$this->error('请先登录');
|
||||
}
|
||||
|
||||
$user = Db::name('admin_user')->where('id', session('user_auth.uid'))->find();
|
||||
!$user && $this->error('获取失败');
|
||||
|
||||
$roles = [$user['role']];
|
||||
if ($user['roles'] != '') {
|
||||
$roles = array_merge($roles, explode(',', $user['roles']));
|
||||
}
|
||||
$roles = array_unique($roles);
|
||||
$roles = Db::name('admin_role')->where('id', 'in', $roles)->column('id,name');
|
||||
$this->success('获取成功', null, [
|
||||
'curr' => session('user_auth.role'),
|
||||
'roles' => $roles
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置我的当前角色
|
||||
* @param string $id
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @throws \think\exception\DbException
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
*/
|
||||
public function setMyRole($id = '')
|
||||
{
|
||||
if (!is_signin()) {
|
||||
$this->error('请先登录');
|
||||
}
|
||||
|
||||
$id == '' && $this->error('请选择要设置的角色');
|
||||
|
||||
// 读取当前用户能设置的角色
|
||||
$user = Db::name('admin_user')->where('id', session('user_auth.uid'))->find();
|
||||
!$user && $this->error('设置失败');
|
||||
|
||||
$roles = [$user['role']];
|
||||
if ($user['roles'] != '') {
|
||||
$roles = array_merge($roles, explode(',', $user['roles']));
|
||||
}
|
||||
$roles = array_unique($roles);
|
||||
|
||||
if (!in_array($id, $roles)) {
|
||||
$this->error('无法设置当前角色');
|
||||
}
|
||||
|
||||
cache('role_menu_auth_'.session('user_auth.role'), null);
|
||||
session('user_auth.role', $id);
|
||||
session('user_auth.role_name', Db::name('admin_role')->where('id', $id)->value('name'));
|
||||
session('user_auth_sign', data_auth_sign(session('user_auth')));
|
||||
$this->success('设置成功');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,806 @@
|
|||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | 海豚PHP框架 [ DolphinPHP ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 版权所有 2016~2019 广东卓锐软件有限公司 [ http://www.zrthink.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网站: http://dolphinphp.com
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace app\admin\controller;
|
||||
|
||||
use app\admin\model\Attachment as AttachmentModel;
|
||||
use app\common\builder\ZBuilder;
|
||||
use think\Db;
|
||||
use think\facade\Env;
|
||||
use think\facade\Hook;
|
||||
use think\File;
|
||||
use think\Image;
|
||||
|
||||
/**
|
||||
* 附件控制器
|
||||
* @package app\admin\controller
|
||||
*/
|
||||
class Attachment extends Admin {
|
||||
/**
|
||||
* 附件列表
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
*/
|
||||
public function index() {
|
||||
// 查询
|
||||
$map = $this->getMap();
|
||||
|
||||
// 数据列表
|
||||
$data_list = AttachmentModel::where($map)->order('sort asc,id desc')->paginate();
|
||||
foreach ($data_list as $key => &$value) {
|
||||
if (in_array(strtolower($value['ext']), ['jpg', 'jpeg', 'png', 'gif', 'bmp'])) {
|
||||
if ($value['driver'] == 'local') {
|
||||
$thumb = $value['thumb'] != '' ? $value['thumb'] : $value['path'];
|
||||
$value['type'] = '<div class="js-gallery"><img class="image" title="点击查看大图" data-original="' . PUBLIC_PATH . $value['path'] . '" src="' . PUBLIC_PATH . $thumb . '"></div>';
|
||||
} else {
|
||||
$value['type'] = '<div class="js-gallery"><img class="image" title="点击查看大图" data-original="' . $value['path'] . '" src="' . $value['path'] . '"></div>';
|
||||
}
|
||||
} else {
|
||||
if ($value['driver'] == 'local') {
|
||||
$path = PUBLIC_PATH . $value['path'];
|
||||
} else {
|
||||
$path = $value['path'];
|
||||
}
|
||||
if (is_file('.' . config('public_static_path') . 'admin/img/files/' . $value['ext'] . '.png')) {
|
||||
$value['type'] = '<a href="' . $path . '"
|
||||
data-toggle="tooltip" title="点击下载">
|
||||
<img class="image" src="' . config('public_static_path') . 'admin/img/files/' . $value['ext'] . '.png"></a>';
|
||||
} else {
|
||||
$value['type'] = '<a href="' . $path . '"
|
||||
data-toggle="tooltip" title="点击下载">
|
||||
<img class="image" src="' . config('public_static_path') . 'admin/img/files/file.png"></a>';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 使用ZBuilder快速创建数据表格
|
||||
return ZBuilder::make('table')
|
||||
->setSearch(['name' => '名称']) // 设置搜索框
|
||||
->addColumns([ // 批量添加数据列
|
||||
['id', 'ID'],
|
||||
['type', '类型'],
|
||||
['name', '名称'],
|
||||
['size', '大小', 'byte'],
|
||||
['driver', '上传驱动', parse_attr(Db::name('admin_config')->where('name', 'upload_driver')->value('options'))],
|
||||
['create_time', '上传时间', 'datetime'],
|
||||
['status', '状态', 'switch'],
|
||||
['right_button', '操作', 'btn'],
|
||||
])
|
||||
->addTopButtons('enable,disable,delete') // 批量添加顶部按钮
|
||||
->addRightButtons('delete') // 批量添加右侧按钮
|
||||
->setRowList($data_list) // 设置表格数据
|
||||
->fetch(); // 渲染模板
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传附件
|
||||
* @param string $dir 保存的目录:images,files,videos,voices
|
||||
* @param string $from 来源,wangeditor:wangEditor编辑器, ueditor:ueditor编辑器, editormd:editormd编辑器等
|
||||
* @param string $module 来自哪个模块
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return mixed
|
||||
*/
|
||||
public function upload($dir = '', $from = '', $module = '') {
|
||||
// 临时取消执行时间限制
|
||||
set_time_limit(0);
|
||||
if ($dir == '') {
|
||||
$this->error('没有指定上传目录');
|
||||
}
|
||||
|
||||
if ($from == 'ueditor') {
|
||||
return $this->ueditor($module);
|
||||
}
|
||||
|
||||
if ($from == 'jcrop') {
|
||||
return $this->jcrop();
|
||||
}
|
||||
|
||||
return $this->saveFile($dir, $from, $module);
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存附件
|
||||
* @param string $dir 附件存放的目录
|
||||
* @param string $from 来源
|
||||
* @param string $module 来自哪个模块
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return string|\think\response\Json
|
||||
*/
|
||||
private function saveFile($dir = '', $from = '', $module = '') {
|
||||
// 附件大小限制
|
||||
$size_limit = $dir == 'images' ? config('upload_image_size') : config('upload_file_size');
|
||||
$size_limit = $size_limit * 1024;
|
||||
// 附件类型限制
|
||||
$ext_limit = $dir == 'images' ? config('upload_image_ext') : config('upload_file_ext');
|
||||
$ext_limit = $ext_limit != '' ? parse_attr($ext_limit) : '';
|
||||
// 缩略图参数
|
||||
$thumb = $this->request->post('thumb', '');
|
||||
// 水印参数
|
||||
$watermark = $this->request->post('watermark', '');
|
||||
|
||||
// 获取附件数据
|
||||
$callback = '';
|
||||
switch ($from) {
|
||||
case 'editormd':
|
||||
$file_input_name = 'editormd-image-file';
|
||||
break;
|
||||
case 'ckeditor':
|
||||
$file_input_name = 'upload';
|
||||
$callback = $this->request->get('CKEditorFuncNum');
|
||||
break;
|
||||
case 'ueditor_scrawl':
|
||||
return $this->saveScrawl();
|
||||
break;
|
||||
default:
|
||||
$file_input_name = 'file';
|
||||
}
|
||||
$file = $this->request->file($file_input_name);
|
||||
|
||||
// 判断附件是否已存在
|
||||
if ($file_exists = AttachmentModel::get(['md5' => $file->hash('md5')])) {
|
||||
if ($file_exists['driver'] == 'local') {
|
||||
$file_path = PUBLIC_PATH . $file_exists['path'];
|
||||
} else {
|
||||
$file_path = $file_exists['path'];
|
||||
}
|
||||
|
||||
// 附件已存在
|
||||
return $this->uploadSuccess($from, $file_path, $file_exists['name'], $file_exists['id'], $callback);
|
||||
}
|
||||
|
||||
// 判断附件大小是否超过限制
|
||||
if ($size_limit > 0 && ($file->getInfo('size') > $size_limit)) {
|
||||
return $this->uploadError($from, '附件过大', $callback);
|
||||
}
|
||||
|
||||
// 判断附件格式是否符合
|
||||
$file_name = $file->getInfo('name');
|
||||
$file_ext = strtolower(substr($file_name, strrpos($file_name, '.') + 1));
|
||||
$error_msg = '';
|
||||
if ($ext_limit == '') {
|
||||
$error_msg = '获取文件信息失败!';
|
||||
}
|
||||
if ($file->getMime() == 'text/x-php' || $file->getMime() == 'text/html') {
|
||||
$error_msg = '禁止上传非法文件!';
|
||||
}
|
||||
if (preg_grep("/php/i", $ext_limit)) {
|
||||
$error_msg = '禁止上传非法文件!';
|
||||
}
|
||||
if (!preg_grep("/$file_ext/i", $ext_limit)) {
|
||||
$error_msg = '附件类型不正确!';
|
||||
}
|
||||
|
||||
if ($error_msg != '') {
|
||||
// 上传错误
|
||||
return $this->uploadError($from, $error_msg, $callback);
|
||||
}
|
||||
|
||||
// 附件上传钩子,用于第三方文件上传扩展
|
||||
if (config('upload_driver') != 'local') {
|
||||
$hook_result = Hook::listen('upload_attachment', ['file' => $file, 'from' => $from, 'module' => $module], true);
|
||||
if (false !== $hook_result) {
|
||||
return $hook_result;
|
||||
}
|
||||
}
|
||||
|
||||
// 移动到框架应用根目录/uploads/ 目录下
|
||||
$info = $file->move(config('upload_path') . DIRECTORY_SEPARATOR . $dir);
|
||||
if ($info) {
|
||||
// 缩略图路径
|
||||
$thumb_path_name = '';
|
||||
// 图片宽度
|
||||
$img_width = '';
|
||||
// 图片高度
|
||||
$img_height = '';
|
||||
if ($dir == 'images') {
|
||||
$img = Image::open($info);
|
||||
$img_width = $img->width();
|
||||
$img_height = $img->height();
|
||||
// 水印功能
|
||||
if ($watermark == '') {
|
||||
if (config('upload_thumb_water') == 1 && config('upload_thumb_water_pic') > 0) {
|
||||
$this->create_water($info->getRealPath(), config('upload_thumb_water_pic'));
|
||||
}
|
||||
} else {
|
||||
if (strtolower($watermark) != 'close') {
|
||||
list($watermark_img, $watermark_pos, $watermark_alpha) = explode('|', $watermark);
|
||||
$this->create_water($info->getRealPath(), $watermark_img, $watermark_pos, $watermark_alpha);
|
||||
}
|
||||
}
|
||||
|
||||
// 生成缩略图
|
||||
if ($thumb == '') {
|
||||
if (config('upload_image_thumb') != '') {
|
||||
$thumb_path_name = $this->create_thumb($info, $info->getPathInfo()->getfileName(), $info->getFilename());
|
||||
}
|
||||
} else {
|
||||
if (strtolower($thumb) != 'close') {
|
||||
list($thumb_size, $thumb_type) = explode('|', $thumb);
|
||||
$thumb_path_name = $this->create_thumb($info, $info->getPathInfo()->getfileName(), $info->getFilename(), $thumb_size, $thumb_type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 获取附件信息
|
||||
$file_info = [
|
||||
'uid' => session('user_auth.uid'),
|
||||
'name' => $file->getInfo('name'),
|
||||
'mime' => $file->getInfo('type'),
|
||||
'path' => 'uploads/' . $dir . '/' . str_replace('\\', '/', $info->getSaveName()),
|
||||
'ext' => $info->getExtension(),
|
||||
'size' => $info->getSize(),
|
||||
'md5' => $info->hash('md5'),
|
||||
'sha1' => $info->hash('sha1'),
|
||||
'thumb' => $thumb_path_name,
|
||||
'module' => $module,
|
||||
'width' => $img_width,
|
||||
'height' => $img_height,
|
||||
];
|
||||
|
||||
// 写入数据库
|
||||
if ($file_add = AttachmentModel::create($file_info)) {
|
||||
$file_path = PUBLIC_PATH . $file_info['path'];
|
||||
return $this->uploadSuccess($from, $file_path, $file_info['name'], $file_add['id'], $callback);
|
||||
} else {
|
||||
return $this->uploadError($from, '上传失败', $callback);
|
||||
}
|
||||
} else {
|
||||
return $this->uploadError($from, $file->getError(), $callback);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理ueditor上传
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @param string $module 来自哪个模块
|
||||
* @return string|\think\response\Json
|
||||
*/
|
||||
private function ueditor($module = '') {
|
||||
$action = $this->request->get('action');
|
||||
$config_file = './static/libs/ueditor/php/config.json';
|
||||
$config = json_decode(preg_replace("/\/\*[\s\S]+?\*\//", "", file_get_contents($config_file)), true);
|
||||
switch ($action) {
|
||||
/* 获取配置信息 */
|
||||
case 'config':
|
||||
$result = $config;
|
||||
break;
|
||||
|
||||
/* 上传图片 */
|
||||
case 'uploadimage':
|
||||
return $this->saveFile('images', 'ueditor', $module);
|
||||
break;
|
||||
/* 上传涂鸦 */
|
||||
case 'uploadscrawl':
|
||||
return $this->saveFile('images', 'ueditor_scrawl', $module);
|
||||
break;
|
||||
|
||||
/* 上传视频 */
|
||||
case 'uploadvideo':
|
||||
return $this->saveFile('videos', 'ueditor', $module);
|
||||
break;
|
||||
|
||||
/* 上传附件 */
|
||||
case 'uploadfile':
|
||||
return $this->saveFile('files', 'ueditor', $module);
|
||||
break;
|
||||
|
||||
/* 列出图片 */
|
||||
case 'listimage':
|
||||
return $this->showFile('listimage', $config);
|
||||
break;
|
||||
|
||||
/* 列出附件 */
|
||||
case 'listfile':
|
||||
return $this->showFile('listfile', $config);
|
||||
break;
|
||||
|
||||
/* 抓取远程附件 */
|
||||
// case 'catchimage':
|
||||
// $result = include("action_crawler.php");
|
||||
// break;
|
||||
|
||||
default:
|
||||
$result = ['state' => '请求地址出错'];
|
||||
break;
|
||||
}
|
||||
|
||||
/* 输出结果 */
|
||||
if (isset($_GET["callback"])) {
|
||||
if (preg_match("/^[\w_]+$/", $_GET["callback"])) {
|
||||
return htmlspecialchars($_GET["callback"]) . '(' . $result . ')';
|
||||
} else {
|
||||
return json(['state' => 'callback参数不合法']);
|
||||
}
|
||||
} else {
|
||||
return json($result);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存涂鸦(ueditor)
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
private function saveScrawl() {
|
||||
$file = $this->request->post('file');
|
||||
$file_content = base64_decode($file);
|
||||
$file_name = md5($file) . '.jpg';
|
||||
$dir = config('upload_path') . DIRECTORY_SEPARATOR . 'images' . DIRECTORY_SEPARATOR . date('Ymd', $this->request->time());
|
||||
$file_path = $dir . DIRECTORY_SEPARATOR . $file_name;
|
||||
|
||||
if (!is_dir($dir)) {
|
||||
mkdir($dir, 0755, true);
|
||||
}
|
||||
|
||||
if (false === file_put_contents($file_path, $file_content)) {
|
||||
return json(['state' => '涂鸦上传出错']);
|
||||
}
|
||||
|
||||
$file = new File($file_path);
|
||||
$img = Image::open($file);
|
||||
$file_info = [
|
||||
'uid' => session('user_auth.uid'),
|
||||
'name' => $file_name,
|
||||
'mime' => 'image/png',
|
||||
'path' => 'uploads/images/' . date('Ymd', $this->request->time()) . '/' . $file_name,
|
||||
'ext' => 'png',
|
||||
'size' => $file->getSize(),
|
||||
'md5' => $file->hash('md5'),
|
||||
'sha1' => $file->hash('sha1'),
|
||||
'module' => $this->request->param('module', ''),
|
||||
'width' => $img->width(),
|
||||
'height' => $img->height(),
|
||||
];
|
||||
|
||||
if ($file_add = AttachmentModel::create($file_info)) {
|
||||
// 返回成功信息
|
||||
return json([
|
||||
"state" => "SUCCESS", // 上传状态,上传成功时必须返回"SUCCESS"
|
||||
"url" => PUBLIC_PATH . $file_info['path'], // 返回的地址
|
||||
"title" => $file_info['name'], // 附件名
|
||||
]);
|
||||
} else {
|
||||
return json(['state' => '涂鸦上传出错']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 显示附件列表(ueditor)
|
||||
* @param string $type 类型
|
||||
* @param $config
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
private function showFile($type, $config) {
|
||||
/* 判断类型 */
|
||||
switch ($type) {
|
||||
/* 列出附件 */
|
||||
case 'listfile':
|
||||
$allowFiles = $config['fileManagerAllowFiles'];
|
||||
$listSize = $config['fileManagerListSize'];
|
||||
$path = realpath(config('upload_path') . '/files/');
|
||||
break;
|
||||
/* 列出图片 */
|
||||
case 'listimage':
|
||||
default:
|
||||
$allowFiles = $config['imageManagerAllowFiles'];
|
||||
$listSize = $config['imageManagerListSize'];
|
||||
$path = realpath(config('upload_path') . '/images/');
|
||||
}
|
||||
$allowFiles = substr(str_replace(".", "|", join("", $allowFiles)), 1);
|
||||
|
||||
/* 获取参数 */
|
||||
$size = isset($_GET['size']) ? htmlspecialchars($_GET['size']) : $listSize;
|
||||
$start = isset($_GET['start']) ? htmlspecialchars($_GET['start']) : 0;
|
||||
$end = $start + $size;
|
||||
|
||||
/* 获取附件列表 */
|
||||
$files = $this->getfiles($path, $allowFiles);
|
||||
if (!count($files)) {
|
||||
return json(array(
|
||||
"state" => "no match file",
|
||||
"list" => array(),
|
||||
"start" => $start,
|
||||
"total" => count($files),
|
||||
));
|
||||
}
|
||||
|
||||
/* 获取指定范围的列表 */
|
||||
$len = count($files);
|
||||
for ($i = min($end, $len) - 1, $list = array(); $i < $len && $i >= 0 && $i >= $start; $i--) {
|
||||
$list[] = $files[$i];
|
||||
}
|
||||
//倒序
|
||||
//for ($i = $end, $list = array(); $i < $len && $i < $end; $i++){
|
||||
// $list[] = $files[$i];
|
||||
//}
|
||||
|
||||
/* 返回数据 */
|
||||
$result = array(
|
||||
"state" => "SUCCESS",
|
||||
"list" => $list,
|
||||
"start" => $start,
|
||||
"total" => count($files),
|
||||
);
|
||||
|
||||
return json($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理Jcrop图片裁剪
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
*/
|
||||
private function jcrop() {
|
||||
$file_path = $this->request->post('path', '');
|
||||
$cut_info = $this->request->post('cut', '');
|
||||
$thumb = $this->request->post('thumb', '');
|
||||
$watermark = $this->request->post('watermark', '');
|
||||
$module = $this->request->param('module', '');
|
||||
|
||||
// 上传图片
|
||||
if ($file_path == '') {
|
||||
$file = $this->request->file('file');
|
||||
|
||||
// 附件类型限制
|
||||
$ext_limit = config('upload_image_ext');
|
||||
$ext_limit = $ext_limit != '' ? parse_attr($ext_limit) : '';
|
||||
|
||||
// 判断附件格式是否符合
|
||||
$file_name = $file->getInfo('name');
|
||||
$file_ext = strtolower(substr($file_name, strrpos($file_name, '.') + 1));
|
||||
|
||||
if ($ext_limit == '') {
|
||||
$this->error('获取文件信息失败!');
|
||||
}
|
||||
if (strtolower($file_ext) == 'php') {
|
||||
$this->error('禁止上传非法文件!');
|
||||
}
|
||||
if ($file->getMime() == 'text/x-php' || $file->getMime() == 'text/html') {
|
||||
$this->error('禁止上传非法文件!');
|
||||
}
|
||||
if (preg_grep("/php/i", $ext_limit)) {
|
||||
$this->error('禁止上传非法文件!');
|
||||
}
|
||||
if (!preg_grep("/$file_ext/i", $ext_limit)) {
|
||||
$this->error('附件类型不正确!');
|
||||
}
|
||||
|
||||
if (!is_dir(config('upload_temp_path'))) {
|
||||
mkdir(config('upload_temp_path'), 0766, true);
|
||||
}
|
||||
$info = $file->move(config('upload_temp_path'), $file->hash('md5'));
|
||||
if ($info) {
|
||||
return json(['code' => 1, 'src' => PUBLIC_PATH . 'uploads/temp/' . $info->getFilename()]);
|
||||
} else {
|
||||
$this->error('上传失败');
|
||||
}
|
||||
}
|
||||
|
||||
$file_path = config('upload_temp_path') . str_replace(PUBLIC_PATH . 'uploads/temp/', '', $file_path);
|
||||
|
||||
if (is_file($file_path)) {
|
||||
// 获取裁剪信息
|
||||
$cut_info = explode(',', $cut_info);
|
||||
|
||||
// 读取图片
|
||||
$image = Image::open($file_path);
|
||||
|
||||
$dir_name = date('Ymd');
|
||||
$file_dir = config('upload_path') . DIRECTORY_SEPARATOR . 'images/' . $dir_name . '/';
|
||||
if (!is_dir($file_dir)) {
|
||||
mkdir($file_dir, 0766, true);
|
||||
}
|
||||
$file_name = md5(microtime(true)) . '.' . $image->type();
|
||||
$new_file_path = $file_dir . $file_name;
|
||||
|
||||
// 裁剪图片
|
||||
$image->crop($cut_info[0], $cut_info[1], $cut_info[2], $cut_info[3], $cut_info[4], $cut_info[5])->save($new_file_path);
|
||||
|
||||
// 水印功能
|
||||
if ($watermark == '') {
|
||||
if (config('upload_thumb_water') == 1 && config('upload_thumb_water_pic') > 0) {
|
||||
$this->create_water($new_file_path, config('upload_thumb_water_pic'));
|
||||
}
|
||||
} else {
|
||||
if (strtolower($watermark) != 'close') {
|
||||
list($watermark_img, $watermark_pos, $watermark_alpha) = explode('|', $watermark);
|
||||
$this->create_water($new_file_path, $watermark_img, $watermark_pos, $watermark_alpha);
|
||||
}
|
||||
}
|
||||
|
||||
// 是否创建缩略图
|
||||
$thumb_path_name = '';
|
||||
if ($thumb == '') {
|
||||
if (config('upload_image_thumb') != '') {
|
||||
$thumb_path_name = $this->create_thumb($new_file_path, $dir_name, $file_name);
|
||||
}
|
||||
} else {
|
||||
if (strtolower($thumb) != 'close') {
|
||||
list($thumb_size, $thumb_type) = explode('|', $thumb);
|
||||
$thumb_path_name = $this->create_thumb($new_file_path, $dir_name, $file_name, $thumb_size, $thumb_type);
|
||||
}
|
||||
}
|
||||
|
||||
// 保存图片
|
||||
$file = new File($new_file_path);
|
||||
$file_info = [
|
||||
'uid' => session('user_auth.uid'),
|
||||
'name' => $file_name,
|
||||
'mime' => $image->mime(),
|
||||
'path' => 'uploads/images/' . $dir_name . '/' . $file_name,
|
||||
'ext' => $image->type(),
|
||||
'size' => $file->getSize(),
|
||||
'md5' => $file->hash('md5'),
|
||||
'sha1' => $file->hash('sha1'),
|
||||
'thumb' => $thumb_path_name,
|
||||
'module' => $module,
|
||||
'width' => $image->width(),
|
||||
'height' => $image->height(),
|
||||
];
|
||||
|
||||
if ($file_add = AttachmentModel::create($file_info)) {
|
||||
// 删除临时图片
|
||||
unlink($file_path);
|
||||
// 返回成功信息
|
||||
return json([
|
||||
'code' => 1,
|
||||
'id' => $file_add['id'],
|
||||
'src' => PUBLIC_PATH . $file_info['path'],
|
||||
'thumb' => $thumb_path_name == '' ? '' : PUBLIC_PATH . $thumb_path_name,
|
||||
]);
|
||||
} else {
|
||||
$this->error('上传失败');
|
||||
}
|
||||
}
|
||||
$this->error('文件不存在');
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建缩略图
|
||||
* @param string $file 目标文件,可以是文件对象或文件路径
|
||||
* @param string $dir 保存目录,即目标文件所在的目录名
|
||||
* @param string $save_name 缩略图名
|
||||
* @param string $thumb_size 尺寸
|
||||
* @param string $thumb_type 裁剪类型
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return string 缩略图路径
|
||||
*/
|
||||
private function create_thumb($file = '', $dir = '', $save_name = '', $thumb_size = '', $thumb_type = '') {
|
||||
// 获取要生成的缩略图最大宽度和高度
|
||||
$thumb_size = $thumb_size == '' ? config('upload_image_thumb') : $thumb_size;
|
||||
list($thumb_max_width, $thumb_max_height) = explode(',', $thumb_size);
|
||||
// 读取图片
|
||||
$image = Image::open($file);
|
||||
// 生成缩略图
|
||||
$thumb_type = $thumb_type == '' ? config('upload_image_thumb_type') : $thumb_type;
|
||||
$image->thumb($thumb_max_width, $thumb_max_height, $thumb_type);
|
||||
// 保存缩略图
|
||||
$thumb_path = config('upload_path') . DIRECTORY_SEPARATOR . 'images/' . $dir . '/thumb/';
|
||||
if (!is_dir($thumb_path)) {
|
||||
mkdir($thumb_path, 0766, true);
|
||||
}
|
||||
$thumb_path_name = $thumb_path . $save_name;
|
||||
$image->save($thumb_path_name);
|
||||
$thumb_path_name = 'uploads/images/' . $dir . '/thumb/' . $save_name;
|
||||
return $thumb_path_name;
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加水印
|
||||
* @param string $file 要添加水印的文件路径
|
||||
* @param string $watermark_img 水印图片id
|
||||
* @param string $watermark_pos 水印位置
|
||||
* @param string $watermark_alpha 水印透明度
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
*/
|
||||
private function create_water($file = '', $watermark_img = '', $watermark_pos = '', $watermark_alpha = '') {
|
||||
$path = model('admin/attachment')->getFilePath($watermark_img, 1);
|
||||
$thumb_water_pic = realpath(Env::get('root_path') . 'public/' . $path);
|
||||
if (is_file($thumb_water_pic)) {
|
||||
// 读取图片
|
||||
$image = Image::open($file);
|
||||
// 添加水印
|
||||
$watermark_pos = $watermark_pos == '' ? config('upload_thumb_water_position') : $watermark_pos;
|
||||
$watermark_alpha = $watermark_alpha == '' ? config('upload_thumb_water_alpha') : $watermark_alpha;
|
||||
$image->water($thumb_water_pic, $watermark_pos, $watermark_alpha);
|
||||
// 保存水印图片,覆盖原图
|
||||
$image->save($file);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传成功信息
|
||||
* @param $from
|
||||
* @param string $file_path
|
||||
* @param string $file_name
|
||||
* @param string $file_id
|
||||
* @param string $callback
|
||||
* @return string|\think\response\Json
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
*/
|
||||
private function uploadSuccess($from, $file_path = '', $file_name = '', $file_id = '', $callback = '') {
|
||||
switch ($from) {
|
||||
case 'wangeditor':
|
||||
return $file_path;
|
||||
break;
|
||||
case 'ueditor':
|
||||
return json([
|
||||
"state" => "SUCCESS", // 上传状态,上传成功时必须返回"SUCCESS"
|
||||
"url" => $file_path, // 返回的地址
|
||||
"title" => $file_name, // 附件名
|
||||
]);
|
||||
break;
|
||||
case 'editormd':
|
||||
return json([
|
||||
"success" => 1,
|
||||
"message" => '上传成功',
|
||||
"url" => $file_path,
|
||||
]);
|
||||
break;
|
||||
case 'ckeditor':
|
||||
return ck_js($callback, $file_path);
|
||||
break;
|
||||
default:
|
||||
return json([
|
||||
'code' => 1,
|
||||
'info' => '上传成功',
|
||||
'class' => 'success',
|
||||
'id' => $file_id,
|
||||
'path' => $file_path,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传错误信息
|
||||
* @param $from
|
||||
* @param string $msg
|
||||
* @param string $callback
|
||||
* @return string|\think\response\Json
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
*/
|
||||
private function uploadError($from, $msg = '', $callback = '') {
|
||||
switch ($from) {
|
||||
case 'wangeditor':
|
||||
return "error|" . $msg;
|
||||
break;
|
||||
case 'ueditor':
|
||||
return json(['state' => $msg]);
|
||||
break;
|
||||
case 'editormd':
|
||||
return json(["success" => 0, "message" => $msg]);
|
||||
break;
|
||||
case 'ckeditor':
|
||||
return ck_js($callback, '', $msg);
|
||||
break;
|
||||
default:
|
||||
return json([
|
||||
'code' => 0,
|
||||
'class' => 'danger',
|
||||
'info' => $msg,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 遍历获取目录下的指定类型的附件
|
||||
* @param string $path 路径
|
||||
* @param string $allowFiles 允许查看的类型
|
||||
* @param array $files 文件列表
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return array|null
|
||||
*/
|
||||
public function getfiles($path = '', $allowFiles = '', &$files = array()) {
|
||||
if (!is_dir($path)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (substr($path, strlen($path) - 1) != '/') {
|
||||
$path .= '/';
|
||||
}
|
||||
|
||||
$handle = opendir($path);
|
||||
while (false !== ($file = readdir($handle))) {
|
||||
if ($file != '.' && $file != '..') {
|
||||
$path2 = $path . $file;
|
||||
if (is_dir($path2)) {
|
||||
$this->getfiles($path2, $allowFiles, $files);
|
||||
} else {
|
||||
if (preg_match("/\.(" . $allowFiles . ")$/i", $file)) {
|
||||
$files[] = array(
|
||||
'url' => str_replace("\\", "/", substr($path2, strlen($_SERVER['DOCUMENT_ROOT']))),
|
||||
'mtime' => filemtime($path2),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $files;
|
||||
}
|
||||
|
||||
/**
|
||||
* 启用附件
|
||||
* @param array $record 行为日志
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return mixed
|
||||
*/
|
||||
public function enable($record = []) {
|
||||
return $this->setStatus('enable');
|
||||
}
|
||||
|
||||
/**
|
||||
* 禁用附件
|
||||
* @param array $record 行为日志
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return mixed
|
||||
*/
|
||||
public function disable($record = []) {
|
||||
return $this->setStatus('disable');
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置附件状态:删除、禁用、启用
|
||||
* @param string $type 类型:delete/enable/disable
|
||||
* @param array $record
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @throws \think\Exception
|
||||
* @throws \think\exception\PDOException
|
||||
*/
|
||||
public function setStatus($type = '', $record = []) {
|
||||
$ids = $this->request->isPost() ? input('post.ids/a') : input('param.ids');
|
||||
$ids = is_array($ids) ? implode(',', $ids) : $ids;
|
||||
return parent::setStatus($type, ['attachment_' . $type, 'admin_attachment', 0, UID, $ids]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除附件
|
||||
* @param string $ids 附件id
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @throws \think\Exception
|
||||
* @throws \think\exception\PDOException
|
||||
*/
|
||||
public function delete($ids = '') {
|
||||
$ids = $this->request->isPost() ? input('post.ids/a') : input('param.ids');
|
||||
if (empty($ids)) {
|
||||
$this->error('缺少主键');
|
||||
}
|
||||
|
||||
$files_path = AttachmentModel::where('id', 'in', $ids)->column('path,thumb', 'id');
|
||||
|
||||
foreach ($files_path as $value) {
|
||||
$real_path = realpath(config('upload_path') . '/../' . $value['path']);
|
||||
$real_path_thumb = realpath(config('upload_path') . '/../' . $value['thumb']);
|
||||
|
||||
if (is_file($real_path) && !unlink($real_path)) {
|
||||
$this->error('删除失败');
|
||||
}
|
||||
if (is_file($real_path_thumb) && !unlink($real_path_thumb)) {
|
||||
$this->error('删除缩略图失败');
|
||||
}
|
||||
}
|
||||
if (AttachmentModel::where('id', 'in', $ids)->delete()) {
|
||||
// 记录行为
|
||||
$ids = is_array($ids) ? implode(',', $ids) : $ids;
|
||||
action_log('attachment_delete', 'admin_attachment', 0, UID, $ids);
|
||||
$this->success('删除成功');
|
||||
} else {
|
||||
$this->error('删除失败');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 快速编辑
|
||||
* @param array $record 行为日志
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return mixed
|
||||
*/
|
||||
public function quickEdit($record = []) {
|
||||
$id = input('post.pk', '');
|
||||
return parent::quickEdit(['attachment_edit', 'admin_attachment', 0, UID, $id]);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,289 @@
|
|||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | 海豚PHP框架 [ DolphinPHP ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 版权所有 2016~2019 广东卓锐软件有限公司 [ http://www.zrthink.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网站: http://dolphinphp.com
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace app\admin\controller;
|
||||
|
||||
use app\common\builder\ZBuilder;
|
||||
use app\admin\model\Config as ConfigModel;
|
||||
|
||||
/**
|
||||
* 系统配置控制器
|
||||
* @package app\admin\controller
|
||||
*/
|
||||
class Config extends Admin
|
||||
{
|
||||
/**
|
||||
* 配置首页
|
||||
* @param string $group 分组
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return mixed
|
||||
* @throws \think\Exception
|
||||
* @throws \think\exception\DbException
|
||||
*/
|
||||
public function index($group = 'base')
|
||||
{
|
||||
cookie('__forward__', $_SERVER['REQUEST_URI']);
|
||||
|
||||
// 配置分组信息
|
||||
$list_group = config('config_group');
|
||||
$tab_list = [];
|
||||
foreach ($list_group as $key => $value) {
|
||||
$tab_list[$key]['title'] = $value;
|
||||
$tab_list[$key]['url'] = url('index', ['group' => $key]);
|
||||
}
|
||||
|
||||
// 查询
|
||||
$map = $this->getMap();
|
||||
$map[] = ['group', '=', $group];
|
||||
$map[] = ['status', 'egt', 0];
|
||||
|
||||
// 排序
|
||||
$order = $this->getOrder('sort asc,id asc');
|
||||
// 数据列表
|
||||
$data_list = ConfigModel::where($map)->order($order)->paginate();
|
||||
|
||||
// 使用ZBuilder快速创建数据表格
|
||||
return ZBuilder::make('table')
|
||||
->setPageTitle('配置管理') // 设置页面标题
|
||||
->setTabNav($tab_list, $group) // 设置tab分页
|
||||
->setSearch(['name' => '名称', 'title' => '标题']) // 设置搜索框
|
||||
->addColumns([ // 批量添加数据列
|
||||
['name', '名称', 'text.edit'],
|
||||
['title', '标题', 'text.edit'],
|
||||
['type', '类型', 'select', config('form_item_type')],
|
||||
['status', '状态', 'switch'],
|
||||
['sort', '排序', 'text.edit'],
|
||||
['right_button', '操作', 'btn']
|
||||
])
|
||||
->addValidate('Config', 'name,title') // 添加快捷编辑的验证器
|
||||
->addOrder('name,title,status') // 添加标题字段排序
|
||||
->addFilter('name,title') // 添加标题字段筛选
|
||||
->addFilter('type', config('form_item_type')) // 添加标题字段筛选
|
||||
->addFilterMap('name,title', ['group' => $group]) // 添加标题字段筛选条件
|
||||
->addTopButton('add', ['href' => url('add', ['group' => $group])], true) // 添加单个顶部按钮
|
||||
->addTopButtons('enable,disable,delete') // 批量添加顶部按钮
|
||||
->addRightButton('edit', [], true)
|
||||
->addRightButton('delete') // 批量添加右侧按钮
|
||||
->setRowList($data_list) // 设置表格数据
|
||||
->fetch(); // 渲染模板
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增配置项
|
||||
* @param string $group 分组
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return mixed
|
||||
* @throws \think\Exception
|
||||
*/
|
||||
public function add($group = '')
|
||||
{
|
||||
// 保存数据
|
||||
if ($this->request->isPost()) {
|
||||
// 表单数据
|
||||
$data = $this->request->post();
|
||||
|
||||
// 验证
|
||||
$result = $this->validate($data, 'Config');
|
||||
if(true !== $result) $this->error($result);
|
||||
|
||||
// 如果是快速联动
|
||||
if ($data['type'] == 'linkages') {
|
||||
$data['key'] = $data['key'] == '' ? 'id' : $data['key'];
|
||||
$data['pid'] = $data['pid'] == '' ? 'pid' : $data['pid'];
|
||||
$data['level'] = $data['level'] == '' ? '2' : $data['level'];
|
||||
$data['option'] = $data['option'] == '' ? 'name' : $data['option'];
|
||||
}
|
||||
|
||||
if ($config = ConfigModel::create($data)) {
|
||||
cache('system_config', null);
|
||||
$forward = $this->request->param('_pop') == 1 ? null : cookie('__forward__');
|
||||
// 记录行为
|
||||
$details = '详情:分组('.$data['group'].')、类型('.$data['type'].')、标题('.$data['title'].')、名称('.$data['name'].')';
|
||||
action_log('config_add', 'admin_config', $config['id'], UID, $details);
|
||||
$this->success('新增成功', $forward);
|
||||
} else {
|
||||
$this->error('新增失败');
|
||||
}
|
||||
}
|
||||
|
||||
// 使用ZBuilder快速创建表单
|
||||
return ZBuilder::make('form')
|
||||
->setPageTitle('新增')
|
||||
->addRadio('group', '配置分组', '', config('config_group'), $group)
|
||||
->addSelect('type', '配置类型', '', config('form_item_type'))
|
||||
->addText('title', '配置标题', '一般由中文组成,仅用于显示')
|
||||
->addText('name', '配置名称', '由英文字母和下划线组成,如 <code>web_site_title</code>,调用方法:<code>config(\'web_site_title\')</code>')
|
||||
->addTextarea('value', '配置值', '该配置的具体内容')
|
||||
->addTextarea('options', '配置项', '用于单选、多选、下拉、联动等类型')
|
||||
->addText('ajax_url', '异步请求地址', "如请求的地址是 <code>url('ajax/getCity')</code>,那么只需填写 <code>ajax/getCity</code>,或者直接填写以 <code>http</code>开头的url地址")
|
||||
->addText('next_items', '下一级联动下拉框的表单名', "与当前有关联的下级联动下拉框名,多个用逗号隔开,如:area,other")
|
||||
->addText('param', '请求参数名', "联动下拉框请求参数名,默认为配置名称")
|
||||
->addNumber('level', '级别', '需要显示的级别数量,默认为2', 2, 2, 4)
|
||||
->addText('table', '表名', '要查询的表,里面必须含有id、name、pid三个字段,其中id和name字段可在下面重新定义')
|
||||
->addText('pid', '父级id字段名', '即表中的父级ID字段名,如果表中的主键字段名为pid则可不填写')
|
||||
->addText('key', '键字段名', '即表中的主键字段名,如果表中的主键字段名为id则可不填写')
|
||||
->addText('option', '值字段名', '下拉菜单显示的字段名,如果表中的该字段名为name则可不填写')
|
||||
->addText('ak', 'APPKEY', '百度编辑器APPKEY')
|
||||
->addText('format', '格式')
|
||||
->addText('tips', '配置说明', '该配置的具体说明')
|
||||
->addText('sort', '排序', '', 100)
|
||||
->setTrigger('type', 'linkage', 'ajax_url,next_items,param')
|
||||
->setTrigger('type', 'linkages', 'table,pid,level,key,option')
|
||||
->setTrigger('type', 'bmap', 'ak')
|
||||
->setTrigger('type', 'masked,date,time,datetime', 'format')
|
||||
->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑
|
||||
* @param int $id
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return mixed
|
||||
* @throws \think\Exception
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @throws \think\exception\DbException
|
||||
*/
|
||||
public function edit($id = 0)
|
||||
{
|
||||
if ($id === 0) $this->error('参数错误');
|
||||
|
||||
// 保存数据
|
||||
if ($this->request->isPost()) {
|
||||
// 表单数据
|
||||
$data = $this->request->post();
|
||||
|
||||
// 验证
|
||||
$result = $this->validate($data, 'Config');
|
||||
if(true !== $result) $this->error($result);
|
||||
|
||||
// 如果是快速联动
|
||||
if ($data['type'] == 'linkages') {
|
||||
$data['key'] = $data['key'] == '' ? 'id' : $data['key'];
|
||||
$data['pid'] = $data['pid'] == '' ? 'pid' : $data['pid'];
|
||||
$data['level'] = $data['level'] == '' ? '2' : $data['level'];
|
||||
$data['option'] = $data['option'] == '' ? 'name' : $data['option'];
|
||||
}
|
||||
|
||||
// 原配置内容
|
||||
$config = ConfigModel::where('id', $id)->find();
|
||||
$details = '原数据:分组('.$config['group'].')、类型('.$config['type'].')、标题('.$config['title'].')、名称('.$config['name'].')';
|
||||
|
||||
if ($config = ConfigModel::update($data)) {
|
||||
cache('system_config', null);
|
||||
$forward = $this->request->param('_pop') == 1 ? null : cookie('__forward__');
|
||||
// 记录行为
|
||||
action_log('config_edit', 'admin_config', $config['id'], UID, $details);
|
||||
$this->success('编辑成功', $forward, '_parent_reload');
|
||||
} else {
|
||||
$this->error('编辑失败');
|
||||
}
|
||||
}
|
||||
|
||||
// 获取数据
|
||||
$info = ConfigModel::get($id);
|
||||
|
||||
// 使用ZBuilder快速创建表单
|
||||
return ZBuilder::make('form')
|
||||
->setPageTitle('编辑')
|
||||
->addHidden('id')
|
||||
->addRadio('group', '配置分组', '', config('config_group'))
|
||||
->addSelect('type', '配置类型', '', config('form_item_type'))
|
||||
->addText('title', '配置标题', '一般由中文组成,仅用于显示')
|
||||
->addText('name', '配置名称', '由英文字母和下划线组成,如 <code>web_site_title</code>,调用方法:<code>config(\'web_site_title\')</code>')
|
||||
->addTextarea('value', '配置值', '该配置的具体内容')
|
||||
->addTextarea('options', '配置项', '用于单选、多选、下拉、联动等类型')
|
||||
->addText('ajax_url', '异步请求地址', "如请求的地址是 <code>url('ajax/getCity')</code>,那么只需填写 <code>ajax/getCity</code>,或者直接填写以 <code>http</code>开头的url地址")
|
||||
->addText('next_items', '下一级联动下拉框的表单名', "与当前有关联的下级联动下拉框名,多个用逗号隔开,如:area,other")
|
||||
->addText('param', '请求参数名', "联动下拉框请求参数名,默认为配置名称")
|
||||
->addNumber('level', '级别', '需要显示的级别数量,默认为2', 2, 2, 4)
|
||||
->addText('table', '表名', '要查询的表,里面必须含有id、name、pid三个字段,其中id和name字段可在下面重新定义')
|
||||
->addText('pid', '父级id字段名', '即表中的父级ID字段名,如果表中的主键字段名为pid则可不填写')
|
||||
->addText('key', '键字段名', '即表中的主键字段名,如果表中的主键字段名为id则可不填写')
|
||||
->addText('option', '值字段名', '下拉菜单显示的字段名,如果表中的该字段名为name则可不填写')
|
||||
->addText('ak', 'APPKEY', '百度编辑器APPKEY')
|
||||
->addText('format', '格式')
|
||||
->addText('tips', '配置说明', '该配置的具体说明')
|
||||
->addText('sort', '排序', '', 100)
|
||||
->setTrigger('type', 'linkage', 'ajax_url,next_items,param')
|
||||
->setTrigger('type', 'linkages', 'table,pid,level,key,option')
|
||||
->setTrigger('type', 'bmap', 'ak')
|
||||
->setTrigger('type', 'masked,date,time,datetime', 'format')
|
||||
->setFormData($info)
|
||||
->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除配置
|
||||
* @param array $record 行为日志
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @throws \think\Exception
|
||||
* @throws \think\exception\PDOException
|
||||
*/
|
||||
public function delete($record = [])
|
||||
{
|
||||
return $this->setStatus('delete');
|
||||
}
|
||||
|
||||
/**
|
||||
* 启用配置
|
||||
* @param array $record 行为日志
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @throws \think\Exception
|
||||
* @throws \think\exception\PDOException
|
||||
*/
|
||||
public function enable($record = [])
|
||||
{
|
||||
return $this->setStatus('enable');
|
||||
}
|
||||
|
||||
/**
|
||||
* 禁用配置
|
||||
* @param array $record 行为日志
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @throws \think\Exception
|
||||
* @throws \think\exception\PDOException
|
||||
*/
|
||||
public function disable($record = [])
|
||||
{
|
||||
return $this->setStatus('disable');
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置配置状态:删除、禁用、启用
|
||||
* @param string $type 类型:delete/enable/disable
|
||||
* @param array $record
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @throws \think\Exception
|
||||
* @throws \think\exception\PDOException
|
||||
*/
|
||||
public function setStatus($type = '', $record = [])
|
||||
{
|
||||
$ids = $this->request->isPost() ? input('post.ids/a') : input('param.ids');
|
||||
$uid_delete = is_array($ids) ? '' : $ids;
|
||||
$ids = ConfigModel::where('id', 'in', $ids)->column('title');
|
||||
return parent::setStatus($type, ['config_'.$type, 'admin_config', $uid_delete, UID, implode('、', $ids)]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 快速编辑
|
||||
* @param array $record 行为日志
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return mixed
|
||||
*/
|
||||
public function quickEdit($record = [])
|
||||
{
|
||||
$id = input('post.pk', '');
|
||||
$field = input('post.name', '');
|
||||
$value = input('post.value', '');
|
||||
$config = ConfigModel::where('id', $id)->value($field);
|
||||
$details = '字段(' . $field . '),原值(' . $config . '),新值:(' . $value . ')';
|
||||
return parent::quickEdit(['config_edit', 'admin_config', $id, UID, $details]);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,378 @@
|
|||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | 海豚PHP框架 [ DolphinPHP ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 版权所有 2016~2019 广东卓锐软件有限公司 [ http://www.zrthink.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网站: http://dolphinphp.com
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace app\admin\controller;
|
||||
|
||||
use app\common\builder\ZBuilder;
|
||||
use think\Db;
|
||||
use util\Database as DatabaseModel;
|
||||
|
||||
/**
|
||||
* 数据库管理
|
||||
* @package app\admin\controller
|
||||
*/
|
||||
class Database extends Admin
|
||||
{
|
||||
/**
|
||||
* 数据库管理
|
||||
* @param string $group 分组
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return mixed
|
||||
* @throws \think\Exception
|
||||
*/
|
||||
public function index($group = 'export')
|
||||
{
|
||||
// 配置分组信息
|
||||
$list_group = ['export' =>'备份数据库', 'import' => '还原数据库'];
|
||||
$tab_list = [];
|
||||
foreach ($list_group as $key => $value) {
|
||||
$tab_list[$key]['title'] = $value;
|
||||
$tab_list[$key]['url'] = url('index', ['group' => $key]);
|
||||
}
|
||||
|
||||
switch ($group) {
|
||||
case 'export':
|
||||
$data_list = Db::query("SHOW TABLE STATUS");
|
||||
$data_list = array_map('array_change_key_case', $data_list);
|
||||
// 过滤掉视图表
|
||||
$data_list = array_filter($data_list, function($item) {
|
||||
return $item['comment'] !== 'VIEW';
|
||||
});
|
||||
|
||||
// 自定义按钮
|
||||
$btn_export = [
|
||||
'title' => '立即备份',
|
||||
'icon' => 'fa fa-fw fa-copy',
|
||||
'class' => 'btn btn-primary ajax-post confirm',
|
||||
'href' => url('export')
|
||||
];
|
||||
$btn_optimize_all = [
|
||||
'title' => '优化表',
|
||||
'icon' => 'fa fa-fw fa-cogs',
|
||||
'class' => 'btn btn-success ajax-post',
|
||||
'href' => url('optimize')
|
||||
];
|
||||
$btn_repair_all = [
|
||||
'title' => '修复表',
|
||||
'icon' => 'fa fa-fw fa-wrench',
|
||||
'class' => 'btn btn-success ajax-post',
|
||||
'href' => url('repair')
|
||||
];
|
||||
$btn_optimize = [
|
||||
'title' => '优化表',
|
||||
'icon' => 'fa fa-fw fa-cogs',
|
||||
'class' => 'btn btn-xs btn-default ajax-get',
|
||||
'href' => url('optimize', ['ids' => '__id__'])
|
||||
];
|
||||
$btn_repair = [
|
||||
'title' => '修复表',
|
||||
'icon' => 'fa fa-fw fa-wrench',
|
||||
'class' => 'btn btn-xs btn-default ajax-get',
|
||||
'href' => url('repair', ['ids' => '__id__'])
|
||||
];
|
||||
|
||||
// 使用ZBuilder快速创建数据表格
|
||||
return ZBuilder::make('table')
|
||||
->setPageTitle('数据库管理') // 设置页面标题
|
||||
->setPrimaryKey('name')
|
||||
->setTabNav($tab_list, $group) // 设置tab分页
|
||||
->addColumns([ // 批量添加数据列
|
||||
['name', '表名'],
|
||||
['rows', '行数'],
|
||||
['data_length', '大小', 'byte'],
|
||||
['data_free', '冗余', 'byte'],
|
||||
['comment', '备注'],
|
||||
['right_button', '操作', 'btn']
|
||||
])
|
||||
->addTopButton('custom', $btn_export) // 添加单个顶部按钮
|
||||
->addTopButton('custom', $btn_optimize_all) // 添加单个顶部按钮
|
||||
->addTopButton('custom', $btn_repair_all) // 添加单个顶部按钮
|
||||
->addRightButton('custom', $btn_optimize) // 添加右侧按钮
|
||||
->addRightButton('custom', $btn_repair) // 添加右侧按钮
|
||||
->setRowList($data_list) // 设置表格数据
|
||||
->fetch(); // 渲染模板
|
||||
break;
|
||||
case 'import':
|
||||
// 列出备份文件列表
|
||||
$path = config('data_backup_path');
|
||||
if(!is_dir($path)){
|
||||
mkdir($path, 0755, true);
|
||||
}
|
||||
$path = realpath($path);
|
||||
$flag = \FilesystemIterator::KEY_AS_FILENAME;
|
||||
$glob = new \FilesystemIterator($path, $flag);
|
||||
|
||||
$data_list = [];
|
||||
foreach ($glob as $name => $file) {
|
||||
if(preg_match('/^\d{8,8}-\d{6,6}-\d+\.sql(?:\.gz)?$/', $name)){
|
||||
$name = sscanf($name, '%4s%2s%2s-%2s%2s%2s-%d');
|
||||
|
||||
$date = "{$name[0]}-{$name[1]}-{$name[2]}";
|
||||
$time = "{$name[3]}:{$name[4]}:{$name[5]}";
|
||||
$part = $name[6];
|
||||
|
||||
if(isset($data_list["{$date} {$time}"])){
|
||||
$info = $data_list["{$date} {$time}"];
|
||||
$info['part'] = max($info['part'], $part);
|
||||
$info['size'] = $info['size'] + $file->getSize();
|
||||
} else {
|
||||
$info['part'] = $part;
|
||||
$info['size'] = $file->getSize();
|
||||
}
|
||||
$extension = strtoupper(pathinfo($file->getFilename(), PATHINFO_EXTENSION));
|
||||
$info['compress'] = ($extension === 'SQL') ? '-' : $extension;
|
||||
$info['time'] = strtotime("{$date} {$time}");
|
||||
$info['name'] = $info['time'];
|
||||
|
||||
$data_list["{$date} {$time}"] = $info;
|
||||
}
|
||||
}
|
||||
|
||||
$data_list = !empty($data_list) ? array_values($data_list) : $data_list;
|
||||
|
||||
// 自定义按钮
|
||||
$btn_import = [
|
||||
'title' => '还原',
|
||||
'icon' => 'fa fa-fw fa-reply',
|
||||
'class' => 'btn btn-xs btn-default ajax-get confirm',
|
||||
'href' => url('import', ['time' => '__id__'])
|
||||
];
|
||||
|
||||
// 使用ZBuilder快速创建数据表格
|
||||
return ZBuilder::make('table')
|
||||
->setPageTitle('数据库管理') // 设置页面标题
|
||||
->setPrimaryKey('time')
|
||||
->hideCheckbox()
|
||||
->setTabNav($tab_list, $group) // 设置tab分页
|
||||
->addColumns([ // 批量添加数据列
|
||||
['name', '备份名称', 'datetime', '', 'Ymd-His'],
|
||||
['part', '卷数'],
|
||||
['compress', '压缩'],
|
||||
['size', '数据大小', 'byte'],
|
||||
['time', '备份时间', 'datetime', '', 'Y-m-d H:i:s'],
|
||||
['right_button', '操作', 'btn']
|
||||
])
|
||||
->addRightButton('custom', $btn_import) // 添加右侧按钮
|
||||
->addRightButton('delete') // 添加右侧按钮
|
||||
->setRowList($data_list) // 设置表格数据
|
||||
->fetch(); // 渲染模板
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 备份数据库(参考onthink 麦当苗儿 <zuojiazi@vip.qq.com>)
|
||||
* @param null|array $ids 表名
|
||||
* @param integer $start 起始行数
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
*/
|
||||
public function export($ids = null, $start = 0)
|
||||
{
|
||||
$tables = $ids;
|
||||
if ($this->request->isPost() && !empty($tables) && is_array($tables)) {
|
||||
// 初始化
|
||||
$path = config('data_backup_path');
|
||||
if(!is_dir($path)){
|
||||
mkdir($path, 0755, true);
|
||||
}
|
||||
|
||||
// 读取备份配置
|
||||
$config = array(
|
||||
'path' => realpath($path) . DIRECTORY_SEPARATOR,
|
||||
'part' => config('data_backup_part_size'),
|
||||
'compress' => config('data_backup_compress'),
|
||||
'level' => config('data_backup_compress_level'),
|
||||
);
|
||||
|
||||
// 检查是否有正在执行的任务
|
||||
$lock = "{$config['path']}backup.lock";
|
||||
if(is_file($lock)){
|
||||
$this->error('检测到有一个备份任务正在执行,请稍后再试!');
|
||||
} else {
|
||||
// 创建锁文件
|
||||
file_put_contents($lock, $this->request->time());
|
||||
}
|
||||
|
||||
// 检查备份目录是否可写
|
||||
is_writeable($config['path']) || $this->error('备份目录不存在或不可写,请检查后重试!');
|
||||
|
||||
// 生成备份文件信息
|
||||
$file = array(
|
||||
'name' => date('Ymd-His', $this->request->time()),
|
||||
'part' => 1,
|
||||
);
|
||||
|
||||
// 创建备份文件
|
||||
$Database = new DatabaseModel($file, $config);
|
||||
if(false !== $Database->create()){
|
||||
// 备份指定表
|
||||
foreach ($tables as $table) {
|
||||
$start = $Database->backup($table, $start);
|
||||
while (0 !== $start) {
|
||||
if (false === $start) { // 出错
|
||||
$this->error('备份出错!');
|
||||
}
|
||||
$start = $Database->backup($table, $start[0]);
|
||||
}
|
||||
}
|
||||
|
||||
// 备份完成,删除锁定文件
|
||||
unlink($lock);
|
||||
// 记录行为
|
||||
action_log('database_export', 'database', 0, UID, implode(',', $tables));
|
||||
$this->success('备份完成!');
|
||||
} else {
|
||||
$this->error('初始化失败,备份文件创建失败!');
|
||||
}
|
||||
} else {
|
||||
$this->error('参数错误!');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 还原数据库(参考onthink 麦当苗儿 <zuojiazi@vip.qq.com>)
|
||||
* @param int $time 文件时间戳
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
*/
|
||||
public function import($time = 0)
|
||||
{
|
||||
if ($time === 0) $this->error('参数错误!');
|
||||
|
||||
// 初始化
|
||||
$name = date('Ymd-His', $time) . '-*.sql*';
|
||||
$path = realpath(config('data_backup_path')) . DIRECTORY_SEPARATOR . $name;
|
||||
$files = glob($path);
|
||||
$list = array();
|
||||
foreach($files as $name){
|
||||
$basename = basename($name);
|
||||
$match = sscanf($basename, '%4s%2s%2s-%2s%2s%2s-%d');
|
||||
$gz = preg_match('/^\d{8,8}-\d{6,6}-\d+\.sql.gz$/', $basename);
|
||||
$list[$match[6]] = array($match[6], $name, $gz);
|
||||
}
|
||||
ksort($list);
|
||||
|
||||
// 检测文件正确性
|
||||
$last = end($list);
|
||||
if(count($list) === $last[0]){
|
||||
foreach ($list as $item) {
|
||||
$config = [
|
||||
'path' => realpath(config('data_backup_path')) . DIRECTORY_SEPARATOR,
|
||||
'compress' => $item[2]
|
||||
];
|
||||
$Database = new DatabaseModel($item, $config);
|
||||
$start = $Database->import(0);
|
||||
|
||||
// 循环导入数据
|
||||
while (0 !== $start) {
|
||||
if (false === $start) { // 出错
|
||||
$this->error('还原数据出错!');
|
||||
}
|
||||
$start = $Database->import($start[0]);
|
||||
}
|
||||
}
|
||||
// 记录行为
|
||||
action_log('database_import', 'database', 0, UID, date('Ymd-His', $time));
|
||||
$this->success('还原完成!');
|
||||
} else {
|
||||
$this->error('备份文件可能已经损坏,请检查!');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 优化表
|
||||
* @param null|string|array $ids 表名
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
*/
|
||||
public function optimize($ids = null)
|
||||
{
|
||||
$tables = $ids;
|
||||
if($tables) {
|
||||
if(is_array($tables)){
|
||||
$tables = implode('`,`', $tables);
|
||||
$list = Db::query("OPTIMIZE TABLE `{$tables}`");
|
||||
|
||||
if($list){
|
||||
// 记录行为
|
||||
action_log('database_optimize', 'database', 0, UID, "`{$tables}`");
|
||||
$this->success("数据表优化完成!");
|
||||
} else {
|
||||
$this->error("数据表优化出错请重试!");
|
||||
}
|
||||
} else {
|
||||
$list = Db::query("OPTIMIZE TABLE `{$tables}`");
|
||||
if($list){
|
||||
// 记录行为
|
||||
action_log('database_optimize', 'database', 0, UID, $tables);
|
||||
$this->success("数据表'{$tables}'优化完成!");
|
||||
} else {
|
||||
$this->error("数据表'{$tables}'优化出错请重试!");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$this->error("请选择要优化的表!");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 修复表
|
||||
* @param null|string|array $ids 表名
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
*/
|
||||
public function repair($ids = null)
|
||||
{
|
||||
$tables = $ids;
|
||||
if($tables) {
|
||||
if(is_array($tables)){
|
||||
$tables = implode('`,`', $tables);
|
||||
$list = Db::query("REPAIR TABLE `{$tables}`");
|
||||
|
||||
if($list){
|
||||
// 记录行为
|
||||
action_log('database_repair', 'database', 0, UID, "`{$tables}`");
|
||||
$this->success("数据表修复完成!");
|
||||
} else {
|
||||
$this->error("数据表修复出错请重试!");
|
||||
}
|
||||
} else {
|
||||
$list = Db::query("REPAIR TABLE `{$tables}`");
|
||||
if($list){
|
||||
// 记录行为
|
||||
action_log('database_repair', 'database', 0, UID, $tables);
|
||||
$this->success("数据表'{$tables}'修复完成!");
|
||||
} else {
|
||||
$this->error("数据表'{$tables}'修复出错请重试!");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$this->error("请指定要修复的表!");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除备份文件
|
||||
* @param int $ids 备份时间
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return mixed
|
||||
*/
|
||||
public function delete($ids = 0)
|
||||
{
|
||||
if ($ids == 0) $this->error('参数错误!');
|
||||
|
||||
$name = date('Ymd-His', $ids) . '-*.sql*';
|
||||
$path = realpath(config('data_backup_path')) . DIRECTORY_SEPARATOR . $name;
|
||||
array_map("unlink", glob($path));
|
||||
if(count(glob($path))){
|
||||
$this->error('备份文件删除失败,请检查权限!');
|
||||
} else {
|
||||
// 记录行为
|
||||
action_log('database_backup_delete', 'database', 0, UID, date('Ymd-His', $ids));
|
||||
$this->success('备份文件删除成功!');
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,242 @@
|
|||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | 海豚PHP框架 [ DolphinPHP ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 版权所有 2016~2019 广东卓锐软件有限公司 [ http://www.zrthink.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网站: http://dolphinphp.com
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace app\admin\controller;
|
||||
|
||||
use app\admin\model\HookPlugin;
|
||||
use app\common\builder\ZBuilder;
|
||||
use app\admin\model\Hook as HookModel;
|
||||
use app\admin\model\HookPlugin as HookPluginModel;
|
||||
|
||||
/**
|
||||
* 钩子控制器
|
||||
* @package app\admin\controller
|
||||
*/
|
||||
class Hook extends Admin
|
||||
{
|
||||
/**
|
||||
* 钩子管理
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return mixed
|
||||
* @throws \think\Exception
|
||||
* @throws \think\exception\DbException
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$map = $this->getMap();
|
||||
$order = $this->getOrder();
|
||||
|
||||
// 数据列表
|
||||
$data_list = HookModel::where($map)->order($order)->paginate();
|
||||
|
||||
// 分页数据
|
||||
$page = $data_list->render();
|
||||
|
||||
// 使用ZBuilder快速创建数据表格
|
||||
return ZBuilder::make('table')
|
||||
->setPageTitle('钩子管理') // 设置页面标题
|
||||
->setSearch(['name' => '钩子名称']) // 设置搜索框
|
||||
->addColumns([ // 批量添加数据列
|
||||
['name', '名称'],
|
||||
['description', '描述'],
|
||||
['plugin', '所属插件', 'callback', function($plugin){
|
||||
return $plugin == '' ? '系统' : $plugin;
|
||||
}],
|
||||
['system', '系统钩子', 'yesno'],
|
||||
['status', '状态', 'switch'],
|
||||
['right_button', '操作', 'btn']
|
||||
])
|
||||
->addOrder('name,status')
|
||||
->addTopButtons('add,enable,disable,delete') // 批量添加顶部按钮
|
||||
->addRightButtons('edit,delete') // 批量添加右侧按钮
|
||||
->setRowList($data_list) // 设置表格数据
|
||||
->setPages($page) // 设置分页数据
|
||||
->fetch(); // 渲染模板
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
*/
|
||||
public function add()
|
||||
{
|
||||
// 保存数据
|
||||
if ($this->request->isPost()) {
|
||||
// 表单数据
|
||||
$data = $this->request->post();
|
||||
$data['system'] = 1;
|
||||
|
||||
// 验证
|
||||
$result = $this->validate($data, 'Hook');
|
||||
if(true !== $result) $this->error($result);
|
||||
|
||||
if ($hook = HookModel::create($data)) {
|
||||
cache('hook_plugins', null);
|
||||
// 记录行为
|
||||
action_log('hook_add', 'admin_hook', $hook['id'], UID, $data['name']);
|
||||
$this->success('新增成功', 'index');
|
||||
} else {
|
||||
$this->error('新增失败');
|
||||
}
|
||||
}
|
||||
|
||||
// 使用ZBuilder快速创建表单
|
||||
return ZBuilder::make('form')
|
||||
->setPageTitle('新增')
|
||||
->addText('name', '钩子名称', '由字母和下划线组成,如:<code>page_tips</code>')
|
||||
->addText('description', '钩子描述')
|
||||
->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑
|
||||
* @param int $id 钩子id
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return mixed
|
||||
* @throws \think\Exception
|
||||
*/
|
||||
public function edit($id = 0)
|
||||
{
|
||||
if ($id === 0) $this->error('参数错误');
|
||||
|
||||
// 保存数据
|
||||
if ($this->request->isPost()) {
|
||||
$data = $this->request->post();
|
||||
// 验证
|
||||
$result = $this->validate($data, 'Hook');
|
||||
if(true !== $result) $this->error($result);
|
||||
|
||||
if ($hook = HookModel::update($data)) {
|
||||
// 调整插件顺序
|
||||
if ($data['sort'] != '') {
|
||||
HookPluginModel::sort($data['name'], $data['sort']);
|
||||
}
|
||||
cache('hook_plugins', null);
|
||||
// 记录行为
|
||||
action_log('hook_edit', 'admin_hook', $hook['id'], UID, $data['name']);
|
||||
$this->success('编辑成功', 'index');
|
||||
} else {
|
||||
$this->error('编辑失败');
|
||||
}
|
||||
}
|
||||
|
||||
// 获取数据
|
||||
$info = HookModel::get($id);
|
||||
|
||||
// 该钩子的所有插件
|
||||
$hooks = HookPluginModel::where('hook', $info['name'])->order('sort')->column('plugin');
|
||||
$hooks = parse_array($hooks);
|
||||
|
||||
// 使用ZBuilder快速创建表单
|
||||
return ZBuilder::make('form')
|
||||
->setPageTitle('编辑')
|
||||
->addHidden('id')
|
||||
->addText('name', '钩子名称', '由字母和下划线组成,如:<code>page_tips</code>')
|
||||
->addText('description', '钩子描述')
|
||||
->addSort('sort', '插件排序', '', $hooks)
|
||||
->setFormData($info)
|
||||
->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* 快速编辑(启用/禁用)
|
||||
* @param string $status 状态
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return mixed
|
||||
*/
|
||||
public function quickEdit($status = '')
|
||||
{
|
||||
$id = $this->request->post('pk');
|
||||
$status = $this->request->param('value');
|
||||
$hook_name = HookModel::where('id', $id)->value('name');
|
||||
|
||||
if (false === HookPluginModel::where('hook', $hook_name)->setField('status', $status == 'true' ? 1 : 0)) {
|
||||
$this->error('操作失败,请重试');
|
||||
}
|
||||
cache('hook_plugins', null);
|
||||
$details = $status == 'true' ? '启用钩子' : '禁用钩子';
|
||||
return parent::quickEdit(['hook_edit', 'admin_hook', $id, UID, $details]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 启用
|
||||
* @param array $record 行为日志内容
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @throws \think\Exception
|
||||
* @throws \think\exception\PDOException
|
||||
*/
|
||||
public function enable($record = [])
|
||||
{
|
||||
return $this->setStatus('enable');
|
||||
}
|
||||
|
||||
/**
|
||||
* 禁用
|
||||
* @param array $record 行为日志内容
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return mixed
|
||||
*/
|
||||
/**
|
||||
* 禁用
|
||||
* @param array $record 行为日志内容
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @throws \think\Exception
|
||||
* @throws \think\exception\PDOException
|
||||
*/
|
||||
public function disable($record = [])
|
||||
{
|
||||
return $this->setStatus('disable');
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除钩子
|
||||
* @param array $record 行为日志内容
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @throws \think\Exception
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @throws \think\exception\DbException
|
||||
* @throws \think\exception\PDOException
|
||||
*/
|
||||
public function delete($record = [])
|
||||
{
|
||||
$ids = $this->request->isPost() ? input('post.ids/a') : input('param.ids');
|
||||
$map = [
|
||||
['id', 'in', $ids],
|
||||
['system', '=', 1],
|
||||
];
|
||||
if (HookModel::where($map)->find()) {
|
||||
$this->error('禁止删除系统钩子');
|
||||
}
|
||||
return $this->setStatus('delete');
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置状态
|
||||
* @param string $type 类型
|
||||
* @param array $record 行为日志内容
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @throws \think\Exception
|
||||
* @throws \think\exception\PDOException
|
||||
*/
|
||||
public function setStatus($type = '', $record = [])
|
||||
{
|
||||
$ids = $this->request->param('ids/a');
|
||||
foreach ($ids as $id) {
|
||||
$hook_name = HookModel::where('id', $id)->value('name');
|
||||
if (false === HookPluginModel::where('hook', $hook_name)->setField('status', $type == 'enable' ? 1 : 0)) {
|
||||
$this->error('操作失败,请重试');
|
||||
}
|
||||
}
|
||||
cache('hook_plugins', null);
|
||||
$hook_delete = is_array($ids) ? '' : $ids;
|
||||
$hook_names = HookModel::where('id', 'in', $ids)->column('name');
|
||||
return parent::setStatus($type, ['hook_'.$type, 'admin_hook', $hook_delete, UID, implode('、', $hook_names)]);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,268 @@
|
|||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | 海豚PHP框架 [ DolphinPHP ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 版权所有 2016~2019 广东卓锐软件有限公司 [ http://www.zrthink.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网站: http://dolphinphp.com
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace app\admin\controller;
|
||||
|
||||
use app\common\builder\ZBuilder;
|
||||
use app\admin\model\Icon as IconModel;
|
||||
use app\admin\model\IconList as IconListModel;
|
||||
|
||||
/**
|
||||
* 图标控制器
|
||||
* @package app\admin\controller
|
||||
*/
|
||||
class Icon extends Admin
|
||||
{
|
||||
/**
|
||||
* 图标列表
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return mixed
|
||||
* @throws \think\Exception
|
||||
* @throws \think\exception\DbException
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$data_list = IconModel::where($this->getMap())
|
||||
->order($this->getOrder('id DESC'))
|
||||
->paginate();
|
||||
|
||||
return ZBuilder::make('table')
|
||||
->addTopButtons('add,enable,disable,delete')
|
||||
->addRightButton('list', [
|
||||
'title' => '图标列表',
|
||||
'icon' => 'fa fa-list',
|
||||
'href' => url('items', ['id' => '__id__'])
|
||||
])
|
||||
->addRightButton('reload', [
|
||||
'title' => '更新图标',
|
||||
'icon' => 'fa fa-refresh',
|
||||
'class' => 'btn btn-xs btn-default ajax-get confirm',
|
||||
'href' => url('reload', ['id' => '__id__'])
|
||||
])
|
||||
->addRightButton('delete')
|
||||
->setSearch('name')
|
||||
->addColumns([
|
||||
['id', 'ID'],
|
||||
['name', '名称', 'text.edit'],
|
||||
['url', '链接', 'text.edit'],
|
||||
['status', '状态', 'switch'],
|
||||
['create_time', '创建时间', 'datetime'],
|
||||
['right_button', '操作', 'btn'],
|
||||
])
|
||||
->setRowList($data_list)
|
||||
->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return mixed
|
||||
* @throws \think\Exception
|
||||
* @throws \think\exception\PDOException
|
||||
*/
|
||||
public function add()
|
||||
{
|
||||
if ($this->request->isPost()) {
|
||||
$data = $this->request->post('', null, 'trim');
|
||||
$data['name'] == '' && $this->error('请填写名称');
|
||||
$data['url'] == '' && $this->error('请填写链接');
|
||||
$data['create_time'] = $this->request->time();
|
||||
$data['update_time'] = $this->request->time();
|
||||
|
||||
// 组合图标地址
|
||||
$url = substr($data['url'], 0, 4) == 'http' ? $data['url'] : 'http:'.$data['url'];
|
||||
|
||||
// 检查图标url是否合法
|
||||
$result = check_icon_url($url);
|
||||
if (true !== $result) {
|
||||
$this->error($result['msg']);
|
||||
}
|
||||
|
||||
// 获取图标内容
|
||||
try {
|
||||
$content = file_get_contents($url);
|
||||
} catch (\Exception $e) {
|
||||
$this->error('图标获取失败,请确认地址是否正确');
|
||||
}
|
||||
|
||||
// 获取字体名
|
||||
$font_family = '';
|
||||
$pattern = '/font-family: "(.*)";/';
|
||||
if (preg_match($pattern, $content, $match)) {
|
||||
$font_family = $match[1];
|
||||
} else {
|
||||
$this->error('无法获取字体名');
|
||||
}
|
||||
|
||||
$IconModel = new IconModel();
|
||||
if ($id = $IconModel->insertGetId($data)) {
|
||||
// 拉取图标列表
|
||||
$pattern = '/\.(.*):before/';
|
||||
if (preg_match_all($pattern, $content, $matches)) {
|
||||
$icon_list = [];
|
||||
foreach ($matches[1] as $match) {
|
||||
$icon_list[] = [
|
||||
'icon_id' => $id,
|
||||
'title' => $match,
|
||||
'class' => $font_family . ' ' . $match,
|
||||
'code' => $match,
|
||||
];
|
||||
}
|
||||
$IconListModel = new IconListModel();
|
||||
if ($IconListModel->saveAll($icon_list)) {
|
||||
$this->success('新增成功', 'index');
|
||||
} else {
|
||||
$IconModel->where('id', $id)->delete();
|
||||
$this->error('图标添加失败');
|
||||
}
|
||||
}
|
||||
$this->success('新增成功', 'index');
|
||||
} else {
|
||||
$this->error('新增失败');
|
||||
}
|
||||
}
|
||||
|
||||
return ZBuilder::make('form')
|
||||
->addFormItems([
|
||||
['text', 'name', '名称', '可填写中文'],
|
||||
['text', 'url', '链接', '如://at.alicdn.com/t/font_588968_z5hsg7xluoh41jor.css'],
|
||||
])
|
||||
->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* 图标列表
|
||||
* @param string $id
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return mixed
|
||||
* @throws \think\Exception
|
||||
* @throws \think\exception\DbException
|
||||
*/
|
||||
public function items($id = '')
|
||||
{
|
||||
$data_list = IconListModel::where($this->getMap())
|
||||
->order($this->getOrder('id DESC'))
|
||||
->where('icon_id', $id)
|
||||
->paginate();
|
||||
|
||||
return ZBuilder::make('table')
|
||||
->setTableName('admin_icon_list')
|
||||
->addTopButtons('back')
|
||||
->addTopButton('add', [
|
||||
'title' => '更新图标',
|
||||
'icon' => 'fa fa-refresh',
|
||||
'class' => 'btn btn-primary ajax-get confirm',
|
||||
'href' => url('reload', ['id' => $id])
|
||||
])
|
||||
->setSearch('title,code')
|
||||
->addColumns([
|
||||
['icon', '图标', 'callback', function($data){
|
||||
return '<i class="'.$data['class'].'"></i>';
|
||||
}, '__data__'],
|
||||
['title', '图标标题', 'text.edit'],
|
||||
['code', '图标关键词', 'text.edit'],
|
||||
['class', '图标类名'],
|
||||
])
|
||||
->setRowList($data_list)
|
||||
->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新图标
|
||||
* @param string $id
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @throws \think\Exception
|
||||
* @throws \think\exception\PDOException
|
||||
*/
|
||||
public function reload($id = '')
|
||||
{
|
||||
$icon = IconModel::get($id);
|
||||
// 获取图标信息
|
||||
$url = substr($icon['url'], 0, 4) == 'http' ? $icon['url'] : 'http:'.$icon['url'];
|
||||
try {
|
||||
$content = file_get_contents($url);
|
||||
} catch (\Exception $e) {
|
||||
$this->error('图标获取失败,请确认地址是否正确');
|
||||
}
|
||||
|
||||
// 获取字体名
|
||||
$font_family = '';
|
||||
$pattern = '/font-family: "(.*)";/';
|
||||
if (preg_match($pattern, $content, $match)) {
|
||||
$font_family = $match[1];
|
||||
} else {
|
||||
$this->error('无法获取字体名');
|
||||
}
|
||||
|
||||
// 拉取图标列表
|
||||
$pattern = '/\.(.*):before/';
|
||||
if (preg_match_all($pattern, $content, $matches)) {
|
||||
$icon_list = [];
|
||||
foreach ($matches[1] as $match) {
|
||||
$icon_list[] = [
|
||||
'icon_id' => $id,
|
||||
'title' => $match,
|
||||
'class' => $font_family . ' ' . $match,
|
||||
'code' => $match,
|
||||
];
|
||||
}
|
||||
$IconListModel = new IconListModel();
|
||||
$IconListModel->where('icon_id', $id)->delete();
|
||||
if ($IconListModel->saveAll($icon_list)) {
|
||||
$this->success('更新成功');
|
||||
} else {
|
||||
$this->error('图标添加失败');
|
||||
}
|
||||
}
|
||||
$this->success('更新成功');
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除图标库
|
||||
* @param string $ids
|
||||
* @throws \think\Exception
|
||||
* @throws \think\exception\PDOException
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
*/
|
||||
public function delete($ids = '')
|
||||
{
|
||||
$ids == '' && $this->error('请选择要删除的数据');
|
||||
$ids = (array)$ids;
|
||||
|
||||
// 删除图标列表
|
||||
if (false !== IconListModel::where('icon_id', 'in', $ids)->delete()) {
|
||||
// 删除图标库
|
||||
if (false !== IconModel::where('id', 'in', $ids)->delete()) {
|
||||
$this->success('删除成功');
|
||||
}
|
||||
}
|
||||
$this->error('删除失败');
|
||||
}
|
||||
|
||||
/**
|
||||
* 快捷编辑
|
||||
* @param array $record
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
*/
|
||||
public function quickEdit($record = [])
|
||||
{
|
||||
$url = $this->request->param('value', '');
|
||||
$url == '' && $this->error('请填写图标地址');
|
||||
// 组合图标地址
|
||||
$url = substr($url, 0, 4) == 'http' ? $url : 'http:'.$url;
|
||||
|
||||
// 检查图标url是否合法
|
||||
$result = check_icon_url($url);
|
||||
if (true !== $result) {
|
||||
$this->error($result['msg']);
|
||||
}
|
||||
|
||||
parent::quickEdit($record);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | 海豚PHP框架 [ DolphinPHP ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 版权所有 2016~2019 广东卓锐软件有限公司 [ http://www.zrthink.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网站: http://dolphinphp.com
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace app\admin\controller;
|
||||
|
||||
use app\common\controller\Common;
|
||||
|
||||
/**
|
||||
* ie提示页面控制器
|
||||
* @package app\admin\controller
|
||||
*/
|
||||
class Ie extends Common
|
||||
{
|
||||
/**
|
||||
* 显示ie提示
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return mixed
|
||||
*/
|
||||
public function index(){
|
||||
// ie浏览器判断
|
||||
if (get_browser_type() == 'ie') {
|
||||
return $this->fetch();
|
||||
} else {
|
||||
$this->redirect('admin/index/index');
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,165 @@
|
|||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | 海豚PHP框架 [ DolphinPHP ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 版权所有 2016~2019 广东卓锐软件有限公司 [ http://www.zrthink.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网站: http://dolphinphp.com
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace app\admin\controller;
|
||||
|
||||
use think\facade\Cache;
|
||||
use think\facade\Env;
|
||||
use think\helper\Hash;
|
||||
use think\Db;
|
||||
use app\common\builder\ZBuilder;
|
||||
use app\user\model\User as UserModel;
|
||||
|
||||
/**
|
||||
* 后台默认控制器
|
||||
* @package app\admin\controller
|
||||
*/
|
||||
class Index extends Admin
|
||||
{
|
||||
/**
|
||||
* 后台首页
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return string
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$admin_pass = Db::name('admin_user')->where('id', 1)->value('password');
|
||||
|
||||
if (UID == 1 && $admin_pass && Hash::check('admin', $admin_pass)) {
|
||||
$this->assign('default_pass', 1);
|
||||
}
|
||||
return $this->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* 清空系统缓存
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
*/
|
||||
public function wipeCache()
|
||||
{
|
||||
$wipe_cache_type = config('wipe_cache_type');
|
||||
if (!empty($wipe_cache_type)) {
|
||||
foreach ($wipe_cache_type as $item) {
|
||||
switch ($item) {
|
||||
case 'TEMP_PATH':
|
||||
array_map('unlink', glob(Env::get('runtime_path'). 'temp/*.*'));
|
||||
break;
|
||||
case 'LOG_PATH':
|
||||
$dirs = (array) glob(Env::get('runtime_path') . 'log/*');
|
||||
foreach ($dirs as $dir) {
|
||||
array_map('unlink', glob($dir . '/*.log'));
|
||||
}
|
||||
array_map('rmdir', $dirs);
|
||||
break;
|
||||
case 'CACHE_PATH':
|
||||
array_map('unlink', glob(Env::get('runtime_path'). 'cache/*.*'));
|
||||
break;
|
||||
}
|
||||
}
|
||||
Cache::clear();
|
||||
$this->success('清空成功');
|
||||
} else {
|
||||
$this->error('请在系统设置中选择需要清除的缓存类型');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 个人设置
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
*/
|
||||
public function profile()
|
||||
{
|
||||
// 保存数据
|
||||
if ($this->request->isPost()) {
|
||||
$data = $this->request->post();
|
||||
|
||||
$data['nickname'] == '' && $this->error('昵称不能为空');
|
||||
$data['id'] = UID;
|
||||
|
||||
// 如果没有填写密码,则不更新密码
|
||||
if ($data['password'] == '') {
|
||||
unset($data['password']);
|
||||
}
|
||||
|
||||
$UserModel = new UserModel();
|
||||
if ($user = $UserModel->allowField(['nickname', 'email', 'password', 'mobile', 'avatar'])->update($data)) {
|
||||
// 记录行为
|
||||
action_log('user_edit', 'admin_user', UID, UID, get_nickname(UID));
|
||||
$this->success('编辑成功');
|
||||
} else {
|
||||
$this->error('编辑失败');
|
||||
}
|
||||
}
|
||||
|
||||
// 获取数据
|
||||
$info = UserModel::where('id', UID)->field('password', true)->find();
|
||||
|
||||
// 使用ZBuilder快速创建表单
|
||||
return ZBuilder::make('form')
|
||||
->addFormItems([ // 批量添加表单项
|
||||
['static', 'username', '用户名', '不可更改'],
|
||||
['text', 'nickname', '昵称', '可以是中文'],
|
||||
['text', 'email', '邮箱', ''],
|
||||
['password', 'password', '密码', '必填,6-20位'],
|
||||
['text', 'mobile', '手机号'],
|
||||
['image', 'avatar', '头像']
|
||||
])
|
||||
->setFormData($info) // 设置表单数据
|
||||
->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查版本更新
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return \think\response\Json
|
||||
* @throws \think\db\exception\BindParamException
|
||||
* @throws \think\exception\PDOException
|
||||
*/
|
||||
public function checkUpdate()
|
||||
{
|
||||
$params = config('dolphin.');
|
||||
$params['domain'] = request()->domain();
|
||||
$params['website'] = config('web_site_title');
|
||||
$params['ip'] = $_SERVER['SERVER_ADDR'];
|
||||
$params['php_os'] = PHP_OS;
|
||||
$params['php_version'] = PHP_VERSION;
|
||||
$params['mysql_version'] = db()->query('select version() as version')[0]['version'];
|
||||
$params['server_software'] = $_SERVER['SERVER_SOFTWARE'];
|
||||
$params = http_build_query($params);
|
||||
|
||||
$opts = [
|
||||
CURLOPT_TIMEOUT => 20,
|
||||
CURLOPT_RETURNTRANSFER => true,
|
||||
CURLOPT_URL => config('dolphin.product_update'),
|
||||
CURLOPT_USERAGENT => $_SERVER['HTTP_USER_AGENT'],
|
||||
CURLOPT_POST => 1,
|
||||
CURLOPT_POSTFIELDS => $params
|
||||
];
|
||||
|
||||
// 初始化并执行curl请求
|
||||
$ch = curl_init();
|
||||
curl_setopt_array($ch, $opts);
|
||||
$data = curl_exec($ch);
|
||||
curl_close($ch);
|
||||
|
||||
$result = json_decode($data, true);
|
||||
|
||||
if ($result['code'] == 1) {
|
||||
return json([
|
||||
'update' => '<a class="badge badge-primary" href="http://www.dolphinphp.com/download" target="_blank">有新版本:'.$result["version"].'</a>',
|
||||
'auth' => $result['auth']
|
||||
]);
|
||||
} else {
|
||||
return json([
|
||||
'update' => '',
|
||||
'auth' => $result['auth']
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,92 @@
|
|||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | 海豚PHP框架 [ DolphinPHP ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 版权所有 2016~2019 广东卓锐软件有限公司 [ http://www.zrthink.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网站: http://dolphinphp.com
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace app\admin\controller;
|
||||
|
||||
use app\common\builder\ZBuilder;
|
||||
use app\admin\model\Log as LogModel;
|
||||
|
||||
/**
|
||||
* 系统日志控制器
|
||||
* @package app\admin\controller
|
||||
*/
|
||||
class Log extends Admin
|
||||
{
|
||||
/**
|
||||
* 日志列表
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return mixed
|
||||
* @throws \think\Exception
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
// 查询
|
||||
$map = $this->getMap();
|
||||
// 排序
|
||||
$order = $this->getOrder('admin_log.id desc');
|
||||
// 数据列表
|
||||
$data_list = LogModel::getAll($map, $order);
|
||||
// 分页数据
|
||||
$page = $data_list->render();
|
||||
|
||||
// 使用ZBuilder快速创建数据表格
|
||||
return ZBuilder::make('table')
|
||||
->setPageTitle('系统日志') // 设置页面标题
|
||||
->setSearch(['admin_action.title' => '行为名称', 'admin_user.username' => '执行者', 'admin_module.title' => '所属模块']) // 设置搜索框
|
||||
->hideCheckbox()
|
||||
->addColumns([ // 批量添加数据列
|
||||
['id', '编号'],
|
||||
['title', '行为名称'],
|
||||
['username', '执行者'],
|
||||
['action_ip', '执行IP', 'callback', function($value){
|
||||
return long2ip(intval($value));
|
||||
}],
|
||||
['module_title', '所属模块'],
|
||||
['create_time', '执行时间', 'datetime', '', 'Y-m-d H:i:s'],
|
||||
['right_button', '操作', 'btn']
|
||||
])
|
||||
->addOrder(['title' => 'admin_action', 'username' => 'admin_user', 'module_title' => 'admin_module.title'])
|
||||
->addFilter(['admin_action.title', 'admin_user.username', 'module_title' => 'admin_module.title'])
|
||||
->addRightButton('details', ['icon' => 'fa fa-eye', 'title' => '详情', 'href' => url('details', ['id' => '__id__'])])
|
||||
->setRowList($data_list) // 设置表格数据
|
||||
->setPages($page) // 设置分页数据
|
||||
->fetch(); // 渲染模板
|
||||
}
|
||||
|
||||
/**
|
||||
* 日志详情
|
||||
* @param null $id 日志id
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return mixed
|
||||
* @throws \think\Exception
|
||||
*/
|
||||
public function details($id = null)
|
||||
{
|
||||
if ($id === null) $this->error('缺少参数');
|
||||
$info = LogModel::getAll(['admin_log.id' => $id]);
|
||||
$info = $info[0];
|
||||
$info['action_ip'] = long2ip(intval($info['action_ip']));
|
||||
|
||||
// 使用ZBuilder快速创建表单
|
||||
return ZBuilder::make('form')
|
||||
->setPageTitle('编辑') // 设置页面标题
|
||||
->addFormItems([ // 批量添加表单项
|
||||
['hidden', 'id'],
|
||||
['static', 'title', '行为名称'],
|
||||
['static', 'username', '执行者'],
|
||||
['static', 'record_id', '目标ID'],
|
||||
['static', 'action_ip', '执行IP'],
|
||||
['static', 'module_title', '所属模块'],
|
||||
['textarea', 'remark', '备注'],
|
||||
])
|
||||
->hideBtn('submit')
|
||||
->setFormData($info) // 设置表单数据
|
||||
->fetch();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,545 @@
|
|||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | 海豚PHP框架 [ DolphinPHP ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 版权所有 2016~2019 广东卓锐软件有限公司 [ http://www.zrthink.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网站: http://dolphinphp.com
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace app\admin\controller;
|
||||
|
||||
use app\common\builder\ZBuilder;
|
||||
use app\admin\model\Module as ModuleModel;
|
||||
use app\admin\model\Menu as MenuModel;
|
||||
use app\user\model\Role as RoleModel;
|
||||
use think\facade\Cache;
|
||||
|
||||
/**
|
||||
* 节点管理
|
||||
* @package app\admin\controller
|
||||
*/
|
||||
class Menu extends Admin
|
||||
{
|
||||
/**
|
||||
* 节点首页
|
||||
* @param string $group 分组
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return mixed
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function index($group = 'admin')
|
||||
{
|
||||
// 保存模块排序
|
||||
if ($this->request->isPost()) {
|
||||
$modules = $this->request->post('sort/a');
|
||||
if ($modules) {
|
||||
$data = [];
|
||||
foreach ($modules as $key => $module) {
|
||||
$data[] = [
|
||||
'id' => $module,
|
||||
'sort' => $key + 1
|
||||
];
|
||||
}
|
||||
$MenuModel = new MenuModel();
|
||||
if (false !== $MenuModel->saveAll($data)) {
|
||||
$this->success('保存成功');
|
||||
} else {
|
||||
$this->error('保存失败');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cookie('__forward__', $_SERVER['REQUEST_URI']);
|
||||
// 配置分组信息
|
||||
$list_group = MenuModel::getGroup();
|
||||
foreach ($list_group as $key => $value) {
|
||||
$tab_list[$key]['title'] = $value;
|
||||
$tab_list[$key]['url'] = url('index', ['group' => $key]);
|
||||
}
|
||||
|
||||
// 模块排序
|
||||
if ($group == 'module-sort') {
|
||||
$map['status'] = 1;
|
||||
$map['pid'] = 0;
|
||||
$modules = MenuModel::where($map)->order('sort,id')->column('icon,title', 'id');
|
||||
$this->assign('modules', $modules);
|
||||
} else {
|
||||
// 获取节点数据
|
||||
$data_list = MenuModel::getMenusByGroup($group);
|
||||
|
||||
$max_level = $this->request->get('max', 0);
|
||||
|
||||
$this->assign('menus', $this->getNestMenu($data_list, $max_level));
|
||||
}
|
||||
|
||||
$this->assign('tab_nav', ['tab_list' => $tab_list, 'curr_tab' => $group]);
|
||||
$this->assign('page_title', '节点管理');
|
||||
return $this->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增节点
|
||||
* @param string $module 所属模块
|
||||
* @param string $pid 所属节点id
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return mixed
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function add($module = 'admin', $pid = '')
|
||||
{
|
||||
// 保存数据
|
||||
if ($this->request->isPost()) {
|
||||
$data = $this->request->post('', null, 'trim');
|
||||
|
||||
// 验证
|
||||
$result = $this->validate($data, 'Menu');
|
||||
// 验证失败 输出错误信息
|
||||
if(true !== $result) $this->error($result);
|
||||
|
||||
// 顶部节点url检查
|
||||
if ($data['pid'] == 0 && $data['url_value'] == '' && ($data['url_type'] == 'module_admin' || $data['url_type'] == 'module_home')) {
|
||||
$this->error('顶级节点的节点链接不能为空');
|
||||
}
|
||||
|
||||
if ($menu = MenuModel::create($data)) {
|
||||
// 自动创建子节点
|
||||
if ($data['auto_create'] == 1 && !empty($data['child_node'])) {
|
||||
unset($data['icon']);
|
||||
unset($data['params']);
|
||||
$this->createChildNode($data, $menu['id']);
|
||||
}
|
||||
// 添加角色权限
|
||||
if (isset($data['role'])) {
|
||||
$this->setRoleMenu($menu['id'], $data['role']);
|
||||
}
|
||||
Cache::clear();
|
||||
// 记录行为
|
||||
$details = '所属模块('.$data['module'].'),所属节点ID('.$data['pid'].'),节点标题('.$data['title'].'),节点链接('.$data['url_value'].')';
|
||||
action_log('menu_add', 'admin_menu', $menu['id'], UID, $details);
|
||||
$this->success('新增成功', cookie('__forward__'));
|
||||
} else {
|
||||
$this->error('新增失败');
|
||||
}
|
||||
}
|
||||
|
||||
// 使用ZBuilder快速创建表单
|
||||
return ZBuilder::make('form')
|
||||
->setPageTitle('新增节点')
|
||||
->addLinkage('module', '所属模块', '', ModuleModel::getModule(), $module, url('ajax/getModuleMenus'), 'pid')
|
||||
->addFormItems([
|
||||
['select', 'pid', '所属节点', '所属上级节点', MenuModel::getMenuTree(0, '', $module), $pid],
|
||||
['text', 'title', '节点标题'],
|
||||
['radio', 'url_type', '链接类型', '', ['module_admin' => '模块链接(后台)', 'module_home' => '模块链接(前台)', 'link' => '普通链接'], 'module_admin']
|
||||
])
|
||||
->addFormItem(
|
||||
'text',
|
||||
'url_value',
|
||||
'节点链接',
|
||||
"可留空,如果是模块链接,请填写<code>模块/控制器/操作</code>,如:<code>admin/menu/add</code>。如果是普通链接,则直接填写url地址,如:<code>http://www.dolphinphp.com</code>"
|
||||
)
|
||||
->addText('params', '参数', '如:a=1&b=2')
|
||||
->addSelect('role', '角色', '除超级管理员外,拥有该节点权限的角色', RoleModel::where('id', 'neq', 1)->column('id,name'), '', 'multiple')
|
||||
->addRadio('auto_create', '自动添加子节点', '选择【是】则自动添加指定的子节点', ['否', '是'], 0)
|
||||
->addCheckbox('child_node', '子节点', '仅上面选项为【是】时起作用', ['add' => '新增', 'edit' => '编辑', 'delete' => '删除', 'enable' => '启用', 'disable' => '禁用', 'quickedit' => '快速编辑'], 'add,edit,delete,enable,disable,quickedit')
|
||||
->addRadio('url_target', '打开方式', '', ['_self' => '当前窗口', '_blank' => '新窗口'], '_self')
|
||||
->addIcon('icon', '图标', '导航图标')
|
||||
->addRadio('online_hide', '网站上线后隐藏', '关闭开发模式后,则隐藏该菜单节点', ['否', '是'], 0)
|
||||
->addText('sort', '排序', '', 100)
|
||||
->setTrigger('auto_create', '1', 'child_node', false)
|
||||
->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑节点
|
||||
* @param int $id 节点ID
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return mixed
|
||||
* @throws \Exception
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @throws \think\exception\DbException
|
||||
*/
|
||||
public function edit($id = 0)
|
||||
{
|
||||
if ($id === 0) $this->error('缺少参数');
|
||||
|
||||
// 保存数据
|
||||
if ($this->request->isPost()) {
|
||||
$data = $this->request->post('', null, 'trim');
|
||||
|
||||
// 验证
|
||||
$result = $this->validate($data, 'Menu');
|
||||
// 验证失败 输出错误信息
|
||||
if(true !== $result) $this->error($result);
|
||||
|
||||
// 顶部节点url检查
|
||||
if ($data['pid'] == 0 && $data['url_value'] == '' && ($data['url_type'] == 'module_admin' || $data['url_type'] == 'module_home')) {
|
||||
$this->error('顶级节点的节点链接不能为空');
|
||||
}
|
||||
|
||||
// 设置角色权限
|
||||
$this->setRoleMenu($data['id'], isset($data['role']) ? $data['role'] : []);
|
||||
|
||||
// 验证是否更改所属模块,如果是,则该节点的所有子孙节点的模块都要修改
|
||||
$map['id'] = $data['id'];
|
||||
$map['module'] = $data['module'];
|
||||
if (!MenuModel::where($map)->find()) {
|
||||
MenuModel::changeModule($data['id'], $data['module']);
|
||||
}
|
||||
|
||||
if (MenuModel::update($data)) {
|
||||
Cache::clear();
|
||||
// 记录行为
|
||||
$details = '节点ID('.$id.')';
|
||||
action_log('menu_edit', 'admin_menu', $id, UID, $details);
|
||||
$this->success('编辑成功', cookie('__forward__'));
|
||||
} else {
|
||||
$this->error('编辑失败');
|
||||
}
|
||||
}
|
||||
|
||||
// 获取数据
|
||||
$info = MenuModel::get($id);
|
||||
// 拥有该节点权限的角色
|
||||
$info['role'] = RoleModel::getRoleWithMenu($id);
|
||||
|
||||
// 使用ZBuilder快速创建表单
|
||||
return ZBuilder::make('form')
|
||||
->setPageTitle('编辑节点')
|
||||
->addFormItem('hidden', 'id')
|
||||
->addLinkage('module', '所属模块', '', ModuleModel::getModule(), '', url('ajax/getModuleMenus'), 'pid')
|
||||
->addFormItem('select', 'pid', '所属节点', '所属上级节点', MenuModel::getMenuTree(0, '', $info['module']))
|
||||
->addFormItem('text', 'title', '节点标题')
|
||||
->addFormItem('radio', 'url_type', '链接类型', '', ['module_admin' => '模块链接(后台)', 'module_home' => '模块链接(前台)', 'link' => '普通链接'], 'module_admin')
|
||||
->addFormItem(
|
||||
'text',
|
||||
'url_value',
|
||||
'节点链接',
|
||||
"可留空,如果是模块链接,请填写<code>模块/控制器/操作</code>,如:<code>admin/menu/add</code>。如果是普通链接,则直接填写url地址,如:<code>http://www.dolphinphp.com</code>"
|
||||
)
|
||||
->addText('params', '参数', '如:a=1&b=2')
|
||||
->addSelect('role', '角色', '除超级管理员外,拥有该节点权限的角色', RoleModel::where('id', 'neq', 1)->column('id,name'), '', 'multiple')
|
||||
->addRadio('url_target', '打开方式', '', ['_self' => '当前窗口', '_blank' => '新窗口'], '_self')
|
||||
->addIcon('icon', '图标', '导航图标')
|
||||
->addRadio('online_hide', '网站上线后隐藏', '关闭开发模式后,则隐藏该菜单节点', ['否', '是'])
|
||||
->addText('sort', '排序', '', 100)
|
||||
->setFormData($info)
|
||||
->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置角色权限
|
||||
* @param string $role_id 角色id
|
||||
* @param array $roles 角色id
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @throws \Exception
|
||||
*/
|
||||
private function setRoleMenu($role_id = '', $roles = [])
|
||||
{
|
||||
$RoleModel = new RoleModel();
|
||||
|
||||
// 该节点的所有子节点,包括本身节点
|
||||
$menu_child = MenuModel::getChildsId($role_id);
|
||||
$menu_child[] = (int)$role_id;
|
||||
// 该节点的所有上下级节点
|
||||
$menu_all = MenuModel::getLinkIds($role_id);
|
||||
$menu_all = array_map('strval', $menu_all);
|
||||
|
||||
if (!empty($roles)) {
|
||||
// 拥有该节点的所有角色id及节点权限
|
||||
$role_menu_auth = RoleModel::getRoleWithMenu($role_id, true);
|
||||
// 已有该节点权限的角色id
|
||||
$role_exists = array_keys($role_menu_auth);
|
||||
// 新节点权限的角色
|
||||
$role_new = $roles;
|
||||
// 原有权限角色差集
|
||||
$role_diff = array_diff($role_exists, $role_new);
|
||||
// 新权限角色差集
|
||||
$role_diff_new = array_diff($role_new, $role_exists);
|
||||
// 新节点角色权限
|
||||
$role_new_auth = RoleModel::getAuthWithRole($roles);
|
||||
|
||||
// 删除原先角色的该节点权限
|
||||
if ($role_diff) {
|
||||
$role_del_auth = [];
|
||||
foreach ($role_diff as $role) {
|
||||
$auth = json_decode($role_menu_auth[$role], true);
|
||||
$auth_new = array_diff($auth, $menu_child);
|
||||
$role_del_auth[] = [
|
||||
'id' => $role,
|
||||
'menu_auth' => array_values($auth_new)
|
||||
];
|
||||
}
|
||||
if ($role_del_auth) {
|
||||
$RoleModel->saveAll($role_del_auth);
|
||||
}
|
||||
}
|
||||
|
||||
// 新增权限角色
|
||||
if ($role_diff_new) {
|
||||
$role_update_auth = [];
|
||||
foreach ($role_new_auth as $role => $auth) {
|
||||
$auth = json_decode($auth, true);
|
||||
if (in_array($role, $role_diff_new)) {
|
||||
$auth = array_unique(array_merge($auth, $menu_all));
|
||||
}
|
||||
$role_update_auth[] = [
|
||||
'id' => $role,
|
||||
'menu_auth' => array_values($auth)
|
||||
];
|
||||
}
|
||||
if ($role_update_auth) {
|
||||
$RoleModel->saveAll($role_update_auth);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$role_menu_auth = RoleModel::getRoleWithMenu($role_id, true);
|
||||
$role_del_auth = [];
|
||||
foreach ($role_menu_auth as $role => $auth) {
|
||||
$auth = json_decode($auth, true);
|
||||
$auth_new = array_diff($auth, $menu_child);
|
||||
$role_del_auth[] = [
|
||||
'id' => $role,
|
||||
'menu_auth' => array_values($auth_new)
|
||||
];
|
||||
}
|
||||
if ($role_del_auth) {
|
||||
$RoleModel->saveAll($role_del_auth);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除节点
|
||||
* @param array $record 行为日志内容
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @throws \think\exception\DbException
|
||||
*/
|
||||
public function delete($record = [])
|
||||
{
|
||||
$id = $this->request->param('id');
|
||||
$menu = MenuModel::where('id', $id)->find();
|
||||
|
||||
if ($menu['system_menu'] == '1') $this->error('系统节点,禁止删除');
|
||||
|
||||
// 获取该节点的所有后辈节点id
|
||||
$menu_childs = MenuModel::getChildsId($id);
|
||||
|
||||
// 要删除的所有节点id
|
||||
$all_ids = array_merge([(int)$id], $menu_childs);
|
||||
|
||||
// 删除节点
|
||||
if (MenuModel::destroy($all_ids)) {
|
||||
Cache::clear();
|
||||
// 记录行为
|
||||
$details = '节点ID('.$id.'),节点标题('.$menu['title'].'),节点链接('.$menu['url_value'].')';
|
||||
action_log('menu_delete', 'admin_menu', $id, UID, $details);
|
||||
$this->success('删除成功');
|
||||
} else {
|
||||
$this->error('删除失败');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存节点排序
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
*/
|
||||
public function save()
|
||||
{
|
||||
if ($this->request->isPost()) {
|
||||
$data = $this->request->post();
|
||||
if (!empty($data)) {
|
||||
$menus = $this->parseMenu($data['menus']);
|
||||
foreach ($menus as $menu) {
|
||||
if ($menu['pid'] == 0) {
|
||||
continue;
|
||||
}
|
||||
MenuModel::update($menu);
|
||||
}
|
||||
Cache::clear();
|
||||
$this->success('保存成功');
|
||||
} else {
|
||||
$this->error('没有需要保存的节点');
|
||||
}
|
||||
}
|
||||
$this->error('非法请求');
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加子节点
|
||||
* @param array $data 节点数据
|
||||
* @param string $pid 父节点id
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
*/
|
||||
private function createChildNode($data = [], $pid = '')
|
||||
{
|
||||
$url_value = substr($data['url_value'], 0, strrpos($data['url_value'], '/')).'/';
|
||||
$child_node = [];
|
||||
$data['pid'] = $pid;
|
||||
|
||||
foreach ($data['child_node'] as $item) {
|
||||
switch ($item) {
|
||||
case 'add':
|
||||
$data['title'] = '新增';
|
||||
break;
|
||||
case 'edit':
|
||||
$data['title'] = '编辑';
|
||||
break;
|
||||
case 'delete':
|
||||
$data['title'] = '删除';
|
||||
break;
|
||||
case 'enable':
|
||||
$data['title'] = '启用';
|
||||
break;
|
||||
case 'disable':
|
||||
$data['title'] = '禁用';
|
||||
break;
|
||||
case 'quickedit':
|
||||
$data['title'] = '快速编辑';
|
||||
break;
|
||||
}
|
||||
$data['url_value'] = $url_value.$item;
|
||||
$data['create_time'] = $this->request->time();
|
||||
$data['update_time'] = $this->request->time();
|
||||
$child_node[] = $data;
|
||||
}
|
||||
|
||||
if ($child_node) {
|
||||
$MenuModel = new MenuModel();
|
||||
$MenuModel->insertAll($child_node);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 递归解析节点
|
||||
* @param array $menus 节点数据
|
||||
* @param int $pid 上级节点id
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return array 解析成可以写入数据库的格式
|
||||
*/
|
||||
private function parseMenu($menus = [], $pid = 0)
|
||||
{
|
||||
$sort = 1;
|
||||
$result = [];
|
||||
foreach ($menus as $menu) {
|
||||
$result[] = [
|
||||
'id' => (int)$menu['id'],
|
||||
'pid' => (int)$pid,
|
||||
'sort' => $sort,
|
||||
];
|
||||
if (isset($menu['children'])) {
|
||||
$result = array_merge($result, $this->parseMenu($menu['children'], $menu['id']));
|
||||
}
|
||||
$sort ++;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取嵌套式节点
|
||||
* @param array $lists 原始节点数组
|
||||
* @param int $pid 父级id
|
||||
* @param int $max_level 最多返回多少层,0为不限制
|
||||
* @param int $curr_level 当前层数
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return string
|
||||
*/
|
||||
private function getNestMenu($lists = [], $max_level = 0, $pid = 0, $curr_level = 1)
|
||||
{
|
||||
$result = '';
|
||||
foreach ($lists as $key => $value) {
|
||||
if ($value['pid'] == $pid) {
|
||||
$disable = $value['status'] == 0 ? 'dd-disable' : '';
|
||||
|
||||
// 组合节点
|
||||
$result .= '<li class="dd-item dd3-item '.$disable.'" data-id="'.$value['id'].'">';
|
||||
$result .= '<div class="dd-handle dd3-handle">拖拽</div><div class="dd3-content"><i class="'.$value['icon'].'"></i> '.$value['title'];
|
||||
if ($value['url_value'] != '') {
|
||||
$result .= '<span class="link"><i class="fa fa-link"></i> '.$value['url_value'].'</span>';
|
||||
}
|
||||
$result .= '<div class="action">';
|
||||
$result .= '<a href="'.url('add', ['module' => $value['module'], 'pid' => $value['id']]).'" data-toggle="tooltip" data-original-title="新增子节点"><i class="list-icon fa fa-plus fa-fw"></i></a><a href="'.url('edit', ['id' => $value['id']]).'" data-toggle="tooltip" data-original-title="编辑"><i class="list-icon fa fa-pencil fa-fw"></i></a>';
|
||||
if ($value['status'] == 0) {
|
||||
// 启用
|
||||
$result .= '<a href="javascript:void(0);" data-ids="'.$value['id'].'" class="enable" data-toggle="tooltip" data-original-title="启用"><i class="list-icon fa fa-check-circle-o fa-fw"></i></a>';
|
||||
} else {
|
||||
// 禁用
|
||||
$result .= '<a href="javascript:void(0);" data-ids="'.$value['id'].'" class="disable" data-toggle="tooltip" data-original-title="禁用"><i class="list-icon fa fa-ban fa-fw"></i></a>';
|
||||
}
|
||||
$result .= '<a href="'.url('delete', ['id' => $value['id'], 'table' => 'admin_menu']).'" data-toggle="tooltip" data-original-title="删除" class="ajax-get confirm"><i class="list-icon fa fa-times fa-fw"></i></a></div>';
|
||||
$result .= '</div>';
|
||||
|
||||
if ($max_level == 0 || $curr_level != $max_level) {
|
||||
unset($lists[$key]);
|
||||
// 下级节点
|
||||
$children = $this->getNestMenu($lists, $max_level, $value['id'], $curr_level + 1);
|
||||
if ($children != '') {
|
||||
$result .= '<ol class="dd-list">'.$children.'</ol>';
|
||||
}
|
||||
}
|
||||
|
||||
$result .= '</li>';
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 启用节点
|
||||
* @param array $record 行为日志
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @throws \think\exception\DbException
|
||||
*/
|
||||
public function enable($record = [])
|
||||
{
|
||||
$id = input('param.ids');
|
||||
$menu = MenuModel::where('id', $id)->find();
|
||||
$details = '节点ID('.$id.'),节点标题('.$menu['title'].'),节点链接('.$menu['url_value'].')';
|
||||
$this->setStatus('enable', ['menu_enable', 'admin_menu', $id, UID, $details]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 禁用节点
|
||||
* @param array $record 行为日志
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @throws \think\exception\DbException
|
||||
*/
|
||||
public function disable($record = [])
|
||||
{
|
||||
$id = input('param.ids');
|
||||
$menu = MenuModel::where('id', $id)->find();
|
||||
$details = '节点ID('.$id.'),节点标题('.$menu['title'].'),节点链接('.$menu['url_value'].')';
|
||||
$this->setStatus('disable', ['menu_disable', 'admin_menu', $id, UID, $details]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置状态
|
||||
* @param string $type 类型
|
||||
* @param array $record 行为日志
|
||||
* @author 小乌 <82950492@qq.com>
|
||||
*/
|
||||
public function setStatus($type = '', $record = [])
|
||||
{
|
||||
$id = input('param.ids');
|
||||
|
||||
$status = $type == 'enable' ? 1 : 0;
|
||||
|
||||
if (false !== MenuModel::where('id', $id)->setField('status', $status)) {
|
||||
Cache::clear();
|
||||
// 记录行为日志
|
||||
if (!empty($record)) {
|
||||
call_user_func_array('action_log', $record);
|
||||
}
|
||||
$this->success('操作成功');
|
||||
} else {
|
||||
$this->error('操作失败');
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | 海豚PHP框架 [ DolphinPHP ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 版权所有 2016~2019 广东卓锐软件有限公司 [ http://www.zrthink.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网站: http://dolphinphp.com
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace app\admin\controller;
|
||||
|
||||
use app\common\builder\ZBuilder;
|
||||
use app\user\model\Message as MessageModel;
|
||||
|
||||
/**
|
||||
* 消息控制器
|
||||
* @package app\admin\controller
|
||||
*/
|
||||
class Message extends Admin
|
||||
{
|
||||
/**
|
||||
* 消息中心
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return mixed
|
||||
* @throws \think\Exception
|
||||
* @throws \think\exception\DbException
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$data_list = MessageModel::where($this->getMap())
|
||||
->where('uid_receive', UID)
|
||||
->order($this->getOrder('id DESC'))
|
||||
->paginate();
|
||||
|
||||
return ZBuilder::make('table')
|
||||
->setTableName('admin_message')
|
||||
->addTopButton('enable', ['title' => '设置已阅读'])
|
||||
->addTopButton('delete')
|
||||
->addRightButton('enable', ['title' => '设置已阅读'])
|
||||
->addRightButton('delete')
|
||||
->addColumns([
|
||||
['uid_send', '发送者', 'callback', 'get_nickname'],
|
||||
['type', '分类'],
|
||||
['content', '内容'],
|
||||
['status', '状态', 'status', '', ['未读', '已读']],
|
||||
['create_time', '发送时间', 'datetime'],
|
||||
['read_time', '阅读时间', 'datetime'],
|
||||
['right_button', '操作', 'btn'],
|
||||
])
|
||||
->addFilter('type')
|
||||
->addFilter('status', ['未读', '已读'])
|
||||
->setRowList($data_list)
|
||||
->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置已阅读
|
||||
* @param array $ids
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @throws \think\Exception
|
||||
* @throws \think\exception\PDOException
|
||||
*/
|
||||
public function enable($ids = [])
|
||||
{
|
||||
empty($ids) && $this->error('参数错误');
|
||||
$map = [
|
||||
['uid_receive', '=', UID],
|
||||
['id', 'in', $ids]
|
||||
];
|
||||
$result = MessageModel::where($map)
|
||||
->update(['status' => 1, 'read_time' => $this->request->time()]);
|
||||
if (false !== $result) {
|
||||
$this->success('设置成功');
|
||||
} else {
|
||||
$this->error('设置失败');
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,643 @@
|
|||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | 海豚PHP框架 [ DolphinPHP ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 版权所有 2016~2019 广东卓锐软件有限公司 [ http://www.zrthink.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网站: http://dolphinphp.com
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace app\admin\controller;
|
||||
|
||||
use app\admin\model\Module as ModuleModel;
|
||||
use app\admin\model\Plugin as PluginModel;
|
||||
use app\admin\model\Menu as MenuModel;
|
||||
use app\admin\model\Action as ActionModel;
|
||||
use think\facade\Cache;
|
||||
use util\Database;
|
||||
use util\Sql;
|
||||
use util\File;
|
||||
use util\PHPZip;
|
||||
use util\Tree;
|
||||
use think\Db;
|
||||
use think\facade\Hook;
|
||||
use think\facade\Env;
|
||||
|
||||
/**
|
||||
* 模块管理控制器
|
||||
* @package app\admin\controller
|
||||
*/
|
||||
class Module extends Admin
|
||||
{
|
||||
/**
|
||||
* 模块首页
|
||||
* @param string $group 分组
|
||||
* @param string $type 显示类型
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return mixed
|
||||
*/
|
||||
public function index($group = 'local', $type = '')
|
||||
{
|
||||
// 配置分组信息
|
||||
$list_group = ['local' => '本地模块'];
|
||||
$tab_list = [];
|
||||
foreach ($list_group as $key => $value) {
|
||||
$tab_list[$key]['title'] = $value;
|
||||
$tab_list[$key]['url'] = url('index', ['group' => $key]);
|
||||
}
|
||||
|
||||
// 监听tab钩子
|
||||
Hook::listen('module_index_tab_list', $tab_list);
|
||||
|
||||
switch ($group) {
|
||||
case 'local':
|
||||
// 查询条件
|
||||
$keyword = $this->request->get('keyword', '');
|
||||
|
||||
if (input('?param.status') && input('param.status') != '_all') {
|
||||
$status = input('param.status');
|
||||
} else {
|
||||
$status = '';
|
||||
}
|
||||
|
||||
$ModuleModel = new ModuleModel();
|
||||
$result = $ModuleModel->getAll($keyword, $status);
|
||||
|
||||
if ($result['modules'] === false) {
|
||||
$this->error($ModuleModel->getError());
|
||||
}
|
||||
|
||||
$type_show = Cache::get('module_type_show');
|
||||
$type_show = $type != '' ? $type : ($type_show == false ? 'block' : $type_show);
|
||||
Cache::set('module_type_show', $type_show);
|
||||
$type = $type_show == 'block' ? 'list' : 'block';
|
||||
|
||||
$this->assign('page_title', '模块管理');
|
||||
$this->assign('modules', $result['modules']);
|
||||
$this->assign('total', $result['total']);
|
||||
$this->assign('tab_nav', ['tab_list' => $tab_list, 'curr_tab' => $group]);
|
||||
$this->assign('type', $type);
|
||||
return $this->fetch();
|
||||
break;
|
||||
case 'online':
|
||||
return '<h2>正在建设中...</h2>';
|
||||
break;
|
||||
default:
|
||||
$this->error('非法操作');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 安装模块
|
||||
* @param string $name 模块标识
|
||||
* @param int $confirm 是否确认
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @throws \think\Exception
|
||||
* @throws \think\exception\PDOException
|
||||
*/
|
||||
public function install($name = '', $confirm = 0)
|
||||
{
|
||||
// 设置最大执行时间和内存大小
|
||||
ini_set('max_execution_time', '0');
|
||||
ini_set('memory_limit', '1024M');
|
||||
|
||||
if ($name == '') $this->error('模块不存在!');
|
||||
if ($name == 'admin' || $name == 'user') $this->error('禁止操作系统核心模块!');
|
||||
|
||||
// 模块配置信息
|
||||
$module_info = ModuleModel::getInfoFromFile($name);
|
||||
if (empty($module_info)) {
|
||||
$this->error('模块不存在!');
|
||||
}
|
||||
|
||||
if ($confirm == 0) {
|
||||
$need_module = [];
|
||||
$need_plugin = [];
|
||||
$table_check = [];
|
||||
// 检查模块依赖
|
||||
if (isset($module_info['need_module']) && !empty($module_info['need_module'])) {
|
||||
$need_module = $this->checkDependence('module', $module_info['need_module']);
|
||||
}
|
||||
|
||||
// 检查插件依赖
|
||||
if (isset($module_info['need_plugin']) && !empty($module_info['need_plugin'])) {
|
||||
$need_plugin = $this->checkDependence('plugin', $module_info['need_plugin']);
|
||||
}
|
||||
|
||||
// 检查数据表
|
||||
if (isset($module_info['tables']) && !empty($module_info['tables'])) {
|
||||
foreach ($module_info['tables'] as $table) {
|
||||
if (Db::query("SHOW TABLES LIKE '".config('database.prefix')."{$table}'")) {
|
||||
$table_check[] = [
|
||||
'table' => config('database.prefix')."{$table}",
|
||||
'result' => '<span class="text-danger">存在同名</span>'
|
||||
];
|
||||
} else {
|
||||
$table_check[] = [
|
||||
'table' => config('database.prefix')."{$table}",
|
||||
'result' => '<i class="fa fa-check text-success"></i>'
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->assign('need_module', $need_module);
|
||||
$this->assign('need_plugin', $need_plugin);
|
||||
$this->assign('table_check', $table_check);
|
||||
$this->assign('name', $name);
|
||||
$this->assign('page_title', '安装模块:'. $name);
|
||||
return $this->fetch();
|
||||
}
|
||||
|
||||
// 执行安装文件
|
||||
$install_file = realpath(Env::get('app_path').$name.'/install.php');
|
||||
if (file_exists($install_file)) {
|
||||
@include($install_file);
|
||||
}
|
||||
|
||||
// 执行安装模块sql文件
|
||||
$sql_file = realpath(Env::get('app_path').$name.'/sql/install.sql');
|
||||
if (file_exists($sql_file)) {
|
||||
if (isset($module_info['database_prefix']) && !empty($module_info['database_prefix'])) {
|
||||
$sql_statement = Sql::getSqlFromFile($sql_file, false, [$module_info['database_prefix'] => config('database.prefix')]);
|
||||
} else {
|
||||
$sql_statement = Sql::getSqlFromFile($sql_file);
|
||||
}
|
||||
if (!empty($sql_statement)) {
|
||||
foreach ($sql_statement as $value) {
|
||||
try{
|
||||
Db::execute($value);
|
||||
}catch(\Exception $e){
|
||||
$this->error('导入SQL失败,请检查install.sql的语句是否正确');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 添加菜单
|
||||
$menus = ModuleModel::getMenusFromFile($name);
|
||||
if (is_array($menus) && !empty($menus)) {
|
||||
if (false === $this->addMenus($menus, $name)) {
|
||||
$this->error('菜单添加失败,请重新安装');
|
||||
}
|
||||
}
|
||||
|
||||
// 检查是否有模块设置信息
|
||||
if (isset($module_info['config']) && !empty($module_info['config'])) {
|
||||
$module_info['config'] = json_encode(parse_config($module_info['config']));
|
||||
}
|
||||
|
||||
// 检查是否有模块授权配置
|
||||
if (isset($module_info['access']) && !empty($module_info['access'])) {
|
||||
$module_info['access'] = json_encode($module_info['access']);
|
||||
}
|
||||
|
||||
// 检查是否有行为规则
|
||||
if (isset($module_info['action']) && !empty($module_info['action'])) {
|
||||
$ActionModel = new ActionModel;
|
||||
if (!$ActionModel->saveAll($module_info['action'])) {
|
||||
MenuModel::where('module', $name)->delete();
|
||||
$this->error('行为添加失败,请重新安装');
|
||||
}
|
||||
}
|
||||
|
||||
// 将模块信息写入数据库
|
||||
$ModuleModel = new ModuleModel($module_info);
|
||||
$allowField = ['name','title','icon','description','author','author_url','config','access','version','identifier','status'];
|
||||
|
||||
if ($ModuleModel->allowField($allowField)->save()) {
|
||||
// 复制静态资源目录
|
||||
File::copy_dir(Env::get('app_path'). $name. '/public', Env::get('root_path'). 'public');
|
||||
// 删除静态资源目录
|
||||
File::del_dir(Env::get('app_path'). $name. '/public');
|
||||
cache('modules', null);
|
||||
cache('module_all', null);
|
||||
// 记录行为
|
||||
action_log('module_install', 'admin_module', 0, UID, $module_info['title']);
|
||||
$this->success('模块安装成功', 'index');
|
||||
} else {
|
||||
MenuModel::where('module', $name)->delete();
|
||||
$this->error('模块安装失败');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 卸载模块
|
||||
* @param string $name 模块名
|
||||
* @param int $confirm 是否确认
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return mixed
|
||||
* @throws \think\Exception
|
||||
* @throws \think\exception\PDOException
|
||||
*/
|
||||
public function uninstall($name = '', $confirm = 0)
|
||||
{
|
||||
if ($name == '') $this->error('模块不存在!');
|
||||
if ($name == 'admin') $this->error('禁止操作系统模块!');
|
||||
|
||||
// 模块配置信息
|
||||
$module_info = ModuleModel::getInfoFromFile($name);
|
||||
if (empty($module_info)) {
|
||||
$this->error('模块不存在!');
|
||||
}
|
||||
|
||||
if ($confirm == 0) {
|
||||
$this->assign('name', $name);
|
||||
$this->assign('page_title', '卸载模块:'. $name);
|
||||
return $this->fetch();
|
||||
}
|
||||
|
||||
// 执行卸载文件
|
||||
$uninstall_file = realpath(Env::get('app_path').$name.'/uninstall.php');
|
||||
if (file_exists($uninstall_file)) {
|
||||
@include($uninstall_file);
|
||||
}
|
||||
|
||||
// 执行卸载模块sql文件
|
||||
$clear = $this->request->get('clear');
|
||||
if ($clear == 1) {
|
||||
$sql_file = realpath(Env::get('app_path').$name.'/sql/uninstall.sql');
|
||||
if (file_exists($sql_file)) {
|
||||
if (isset($module_info['database_prefix']) && !empty($module_info['database_prefix'])) {
|
||||
$sql_statement = Sql::getSqlFromFile($sql_file, false, [$module_info['database_prefix'] => config('database.prefix')]);
|
||||
} else {
|
||||
$sql_statement = Sql::getSqlFromFile($sql_file);
|
||||
}
|
||||
|
||||
if (!empty($sql_statement)) {
|
||||
foreach ($sql_statement as $sql) {
|
||||
try{
|
||||
Db::execute($sql);
|
||||
}catch(\Exception $e){
|
||||
$this->error('卸载失败,请检查uninstall.sql的语句是否正确');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 删除菜单
|
||||
if (false === MenuModel::where('module', $name)->delete()) {
|
||||
$this->error('菜单删除失败,请重新卸载');
|
||||
}
|
||||
|
||||
// 删除授权信息
|
||||
if (false === Db::name('admin_access')->where('module', $name)->delete()) {
|
||||
$this->error('删除授权信息失败,请重新卸载');
|
||||
}
|
||||
|
||||
// 删除行为规则
|
||||
if (false === Db::name('admin_action')->where('module', $name)->delete()) {
|
||||
$this->error('删除行为信息失败,请重新卸载');
|
||||
}
|
||||
|
||||
// 删除模块信息
|
||||
if (ModuleModel::where('name', $name)->delete()) {
|
||||
// 复制静态资源目录
|
||||
File::copy_dir(Env::get('root_path'). 'public/static/'. $name, Env::get('app_path').$name.'/public/static/'. $name);
|
||||
// 删除静态资源目录
|
||||
File::del_dir(Env::get('root_path'). 'public/static/'. $name);
|
||||
cache('modules', null);
|
||||
cache('module_all', null);
|
||||
// 记录行为
|
||||
action_log('module_uninstall', 'admin_module', 0, UID, $module_info['title']);
|
||||
$this->success('模块卸载成功', 'index');
|
||||
} else {
|
||||
$this->error('模块卸载失败');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新模块配置
|
||||
* @param string $name 模块名
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
*/
|
||||
public function update($name = '')
|
||||
{
|
||||
$name == '' && $this->error('缺少模块名!');
|
||||
|
||||
$Module = ModuleModel::get(['name' => $name]);
|
||||
!$Module && $this->error('模块不存在,或未安装');
|
||||
|
||||
// 模块配置信息
|
||||
$module_info = ModuleModel::getInfoFromFile($name);
|
||||
unset($module_info['name']);
|
||||
|
||||
// 检查是否有模块设置信息
|
||||
if (isset($module_info['config']) && !empty($module_info['config'])) {
|
||||
$module_info['config'] = json_encode(parse_config($module_info['config']));
|
||||
} else {
|
||||
$module_info['config'] = '';
|
||||
}
|
||||
|
||||
// 检查是否有模块授权配置
|
||||
if (isset($module_info['access']) && !empty($module_info['access'])) {
|
||||
$module_info['access'] = json_encode($module_info['access']);
|
||||
} else {
|
||||
$module_info['access'] = '';
|
||||
}
|
||||
|
||||
// 更新模块信息
|
||||
if (false !== $Module->save($module_info)) {
|
||||
$this->success('模块配置更新成功');
|
||||
} else {
|
||||
$this->error('模块配置更新失败,请重试');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出模块
|
||||
* @param string $name 模块名
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @throws \think\exception\DbException
|
||||
*/
|
||||
public function export($name = '')
|
||||
{
|
||||
if ($name == '') $this->error('缺少模块名');
|
||||
|
||||
$export_data = $this->request->get('export_data', '');
|
||||
if ($export_data == '') {
|
||||
$this->assign('page_title', '导出模块:'. $name);
|
||||
return $this->fetch();
|
||||
}
|
||||
|
||||
// 模块信息
|
||||
$module = ModuleModel::where('name', $name)->find();
|
||||
if (!$module) {
|
||||
$this->error('模块不存在');
|
||||
}
|
||||
|
||||
// 模块导出目录
|
||||
$module_dir = Env::get('root_path'). 'export/module/'. $name;
|
||||
|
||||
// 删除旧的导出数据
|
||||
if (is_dir($module_dir)) {
|
||||
File::del_dir($module_dir);
|
||||
}
|
||||
|
||||
// 复制模块目录到导出目录
|
||||
File::copy_dir(Env::get('app_path'). $name, $module_dir);
|
||||
// 复制静态资源目录
|
||||
File::copy_dir(Env::get('root_path'). 'public/static/'. $name, $module_dir.'/public/static/'. $name);
|
||||
|
||||
// 模块本地配置信息
|
||||
$module_info = ModuleModel::getInfoFromFile($name);
|
||||
|
||||
// 检查是否有模块设置信息
|
||||
if (isset($module_info['config'])) {
|
||||
$db_config = ModuleModel::where('name', $name)->value('config');
|
||||
$db_config = json_decode($db_config, true);
|
||||
// 获取最新的模块设置信息
|
||||
$module_info['config'] = set_config_value($module_info['config'], $db_config);
|
||||
}
|
||||
|
||||
// 检查是否有模块行为信息
|
||||
$action = Db::name('admin_action')->where('module', $name)->field('module,name,title,remark,rule,log,status')->select();
|
||||
if ($action) {
|
||||
$module_info['action'] = $action;
|
||||
}
|
||||
|
||||
// 表前缀
|
||||
$module_info['database_prefix'] = config('database.prefix');
|
||||
|
||||
// 生成配置文件
|
||||
if (false === $this->buildInfoFile($module_info, $name)) {
|
||||
$this->error('模块配置文件创建失败,请重新导出');
|
||||
}
|
||||
|
||||
// 获取模型菜单并导出
|
||||
$fields = 'id,pid,title,icon,url_type,url_value,url_target,online_hide,sort,status';
|
||||
$menus = MenuModel::getMenusByGroup($name, $fields);
|
||||
if (false === $this->buildMenuFile($menus, $name)) {
|
||||
$this->error('模型菜单文件创建失败,请重新导出');
|
||||
}
|
||||
|
||||
// 导出数据库表
|
||||
if (isset($module_info['tables']) && !empty($module_info['tables'])) {
|
||||
if (!is_dir($module_dir. '/sql')) {
|
||||
mkdir($module_dir. '/sql', 644, true);
|
||||
}
|
||||
if (!Database::export($module_info['tables'], $module_dir. '/sql/install.sql', config('database.prefix'), $export_data)) {
|
||||
$this->error('数据库文件创建失败,请重新导出');
|
||||
}
|
||||
if (!Database::exportUninstall($module_info['tables'], $module_dir. '/sql/uninstall.sql', config('database.prefix'))) {
|
||||
$this->error('数据库文件创建失败,请重新导出');
|
||||
}
|
||||
}
|
||||
|
||||
// 记录行为
|
||||
action_log('module_export', 'admin_module', 0, UID, $module_info['title']);
|
||||
|
||||
// 打包下载
|
||||
$archive = new PHPZip;
|
||||
return $archive->ZipAndDownload($module_dir, $name);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建模块菜单文件
|
||||
* @param array $menus 菜单
|
||||
* @param string $name 模块名
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return int
|
||||
*/
|
||||
private function buildMenuFile($menus = [], $name = '')
|
||||
{
|
||||
$menus = Tree::toLayer($menus);
|
||||
|
||||
// 美化数组格式
|
||||
$menus = var_export($menus, true);
|
||||
$menus = preg_replace("/(\d+|'id'|'pid') =>(.*)/", '', $menus);
|
||||
$menus = preg_replace("/'child' => (.*)(\r\n|\r|\n)\s*array/", "'child' => $1array", $menus);
|
||||
$menus = str_replace(['array (', ')'], ['[', ']'], $menus);
|
||||
$menus = preg_replace("/(\s*?\r?\n\s*?)+/", "\n", $menus);
|
||||
|
||||
$content = <<<INFO
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | 海豚PHP框架 [ DolphinPHP ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 版权所有 2016~2019 广东卓锐软件有限公司 [ http://www.zrthink.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网站: http://dolphinphp.com
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* 菜单信息
|
||||
*/
|
||||
return {$menus};
|
||||
|
||||
INFO;
|
||||
// 写入到文件
|
||||
return file_put_contents(Env::get('root_path'). 'export/module/'. $name. '/menus.php', $content);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建模块配置文件
|
||||
* @param array $info 模块配置信息
|
||||
* @param string $name 模块名
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return int
|
||||
*/
|
||||
private function buildInfoFile($info = [], $name = '')
|
||||
{
|
||||
// 美化数组格式
|
||||
$info = var_export($info, true);
|
||||
$info = preg_replace("/'(.*)' => (.*)(\r\n|\r|\n)\s*array/", "'$1' => array", $info);
|
||||
$info = preg_replace("/(\d+) => (\s*)(\r\n|\r|\n)\s*array/", "array", $info);
|
||||
$info = preg_replace("/(\d+ => )/", "", $info);
|
||||
$info = preg_replace("/array \((\r\n|\r|\n)\s*\)/", "[)", $info);
|
||||
$info = preg_replace("/array \(/", "[", $info);
|
||||
$info = preg_replace("/\)/", "]", $info);
|
||||
|
||||
$content = <<<INFO
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | 海豚PHP框架 [ DolphinPHP ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 版权所有 2016~2019 广东卓锐软件有限公司 [ http://www.zrthink.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网站: http://dolphinphp.com
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* 模块信息
|
||||
*/
|
||||
return {$info};
|
||||
|
||||
INFO;
|
||||
// 写入到文件
|
||||
return file_put_contents(Env::get('root_path'). 'export/module/'. $name. '/info.php', $content);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置状态
|
||||
* @param string $type 类型:disable/enable
|
||||
* @param array $record 行为日志内容
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @throws \think\exception\DbException
|
||||
*/
|
||||
public function setStatus($type = '', $record = [])
|
||||
{
|
||||
$ids = input('param.ids');
|
||||
empty($ids) && $this->error('缺少主键');
|
||||
|
||||
$module = ModuleModel::where('id', $ids)->find();
|
||||
$module['system_module'] == 1 && $this->error('禁止操作系统内置模块');
|
||||
|
||||
$status = $type == 'enable' ? 1 : 0;
|
||||
|
||||
// 将模块对应的菜单禁用或启用
|
||||
$map = [
|
||||
'pid' => 0,
|
||||
'module' => $module['name']
|
||||
];
|
||||
MenuModel::where($map)->setField('status', $status);
|
||||
|
||||
if (false !== ModuleModel::where('id', $ids)->setField('status', $status)) {
|
||||
// 记录日志
|
||||
call_user_func_array('action_log', ['module_'.$type, 'admin_module', 0, UID, $module['title']]);
|
||||
$this->success('操作成功');
|
||||
} else {
|
||||
$this->error('操作失败');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 禁用模块
|
||||
* @param array $record 行为日志内容
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @throws \think\exception\DbException
|
||||
*/
|
||||
public function disable($record = [])
|
||||
{
|
||||
$this->setStatus('disable');
|
||||
}
|
||||
|
||||
/**
|
||||
* 启用模块
|
||||
* @param array $record 行为日志内容
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @throws \think\exception\DbException
|
||||
*/
|
||||
public function enable($record = [])
|
||||
{
|
||||
$this->setStatus('enable');
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加模型菜单
|
||||
* @param array $menus 菜单
|
||||
* @param string $module 模型名称
|
||||
* @param int $pid 父级ID
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return bool
|
||||
*/
|
||||
private function addMenus($menus = [], $module = '', $pid = 0)
|
||||
{
|
||||
foreach ($menus as $menu) {
|
||||
$data = [
|
||||
'pid' => $pid,
|
||||
'module' => $module,
|
||||
'title' => $menu['title'],
|
||||
'icon' => isset($menu['icon']) ? $menu['icon'] : 'fa fa-fw fa-puzzle-piece',
|
||||
'url_type' => isset($menu['url_type']) ? $menu['url_type'] : 'module_admin',
|
||||
'url_value' => isset($menu['url_value']) ? $menu['url_value'] : '',
|
||||
'url_target' => isset($menu['url_target']) ? $menu['url_target'] : '_self',
|
||||
'online_hide' => isset($menu['online_hide']) ? $menu['online_hide'] : 0,
|
||||
'status' => isset($menu['status']) ? $menu['status'] : 1
|
||||
];
|
||||
|
||||
$result = MenuModel::create($data);
|
||||
if (!$result) return false;
|
||||
|
||||
if (isset($menu['child'])) {
|
||||
$this->addMenus($menu['child'], $module, $result['id']);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查依赖
|
||||
* @param string $type 类型:module/plugin
|
||||
* @param array $data 检查数据
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return array
|
||||
*/
|
||||
private function checkDependence($type = '', $data = [])
|
||||
{
|
||||
$need = [];
|
||||
foreach ($data as $key => $value) {
|
||||
if (!isset($value[3])) {
|
||||
$value[3] = '=';
|
||||
}
|
||||
// 当前版本
|
||||
if ($type == 'module') {
|
||||
$curr_version = ModuleModel::where('identifier', $value[1])->value('version');
|
||||
} else {
|
||||
$curr_version = PluginModel::where('identifier', $value[1])->value('version');
|
||||
}
|
||||
|
||||
// 比对版本
|
||||
$result = version_compare($curr_version, $value[2], $value[3]);
|
||||
$need[$key] = [
|
||||
$type => $value[0],
|
||||
'identifier' => $value[1],
|
||||
'version' => $curr_version ? $curr_version : '未安装',
|
||||
'version_need' => $value[3].$value[2],
|
||||
'result' => $result ? '<i class="fa fa-check text-success"></i>' : '<i class="fa fa-times text-danger"></i>'
|
||||
];
|
||||
}
|
||||
|
||||
return $need;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,154 @@
|
|||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | 海豚PHP框架 [ DolphinPHP ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 版权所有 2016~2019 广东卓锐软件有限公司 [ http://www.zrthink.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网站: http://dolphinphp.com
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace app\admin\controller;
|
||||
|
||||
use app\common\builder\ZBuilder;
|
||||
use app\admin\model\Packet as PacketModel;
|
||||
|
||||
/**
|
||||
* 数据包控制器
|
||||
* @package app\admin\controller
|
||||
*/
|
||||
class Packet extends Admin
|
||||
{
|
||||
/**
|
||||
* 首页
|
||||
* @param string $group 分组
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return mixed|string
|
||||
* @throws \think\Exception
|
||||
*/
|
||||
public function index($group = 'local')
|
||||
{
|
||||
// 配置分组信息
|
||||
$list_group = ['local' => '本地数据包'];
|
||||
$tab_list = [];
|
||||
foreach ($list_group as $key => $value) {
|
||||
$tab_list[$key]['title'] = $value;
|
||||
$tab_list[$key]['url'] = url('index', ['group' => $key]);
|
||||
}
|
||||
|
||||
$PacketModel = new PacketModel;
|
||||
$data_list = $PacketModel->getAll();
|
||||
foreach ($data_list as &$value) {
|
||||
if (isset($value['author_url']) && !empty($value['author_url'])) {
|
||||
$value['author'] = '<a href="'. $value['author_url']. '" target="_blank">'. $value['author'] .'</a>';
|
||||
}
|
||||
}
|
||||
|
||||
if ($data_list === false) {
|
||||
$this->error($PacketModel->getError());
|
||||
}
|
||||
|
||||
// 自定义按钮
|
||||
$btn_install = [
|
||||
'title' => '安装',
|
||||
'icon' => 'fa fa-fw fa-sign-in',
|
||||
'class' => 'btn btn-xs btn-default ajax-get confirm',
|
||||
'href' => url('install', ['name' => '__id__'])
|
||||
];
|
||||
$btn_uninstall = [
|
||||
'title' => '卸载',
|
||||
'icon' => 'fa fa-fw fa-sign-out',
|
||||
'class' => 'btn btn-xs btn-default ajax-get confirm',
|
||||
'href' => url('uninstall', ['name' => '__id__'])
|
||||
];
|
||||
$btn_install_all = [
|
||||
'title' => '安装',
|
||||
'icon' => 'fa fa-fw fa-sign-in',
|
||||
'class' => 'btn btn-primary ajax-post confirm',
|
||||
'href' => url('install')
|
||||
];
|
||||
$btn_uninstall_all = [
|
||||
'title' => '卸载',
|
||||
'icon' => 'fa fa-fw fa-sign-out',
|
||||
'class' => 'btn btn-danger ajax-post confirm',
|
||||
'href' => url('uninstall')
|
||||
];
|
||||
|
||||
switch ($group) {
|
||||
case 'local':
|
||||
// 使用ZBuilder快速创建数据表格
|
||||
return ZBuilder::make('table')
|
||||
->setPageTitle('数据包管理') // 设置页面标题
|
||||
->setPrimaryKey('name')
|
||||
->setTabNav($tab_list, $group) // 设置tab分页
|
||||
->addColumns([ // 批量添加数据列
|
||||
['name', '名称'],
|
||||
['title', '标题'],
|
||||
['author', '作者'],
|
||||
['version', '版本号'],
|
||||
['status', '是否安装', 'yesno'],
|
||||
['right_button', '操作', 'btn']
|
||||
])
|
||||
->addTopButton('custom', $btn_install_all)
|
||||
->addTopButton('custom', $btn_uninstall_all)
|
||||
->addRightButton('custom', $btn_install) // 添加右侧按钮
|
||||
->addRightButton('custom', $btn_uninstall) // 添加右侧按钮
|
||||
->setRowList($data_list) // 设置表格数据
|
||||
->fetch(); // 渲染模板
|
||||
break;
|
||||
case 'online':
|
||||
return '<h2>正在制作中...</h2>';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 安装
|
||||
* @param string $name 数据包名
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @throws \think\exception\DbException
|
||||
*/
|
||||
public function install($name = '')
|
||||
{
|
||||
$names = $name != '' ? (array)$name : $this->request->param('ids/a');
|
||||
|
||||
foreach ($names as $name) {
|
||||
$result = PacketModel::install($name);
|
||||
if ($result === true) {
|
||||
if (!PacketModel::where('name', $name)->find()) {
|
||||
$data = PacketModel::getInfoFromFile($name);
|
||||
$data['status'] = 1;
|
||||
$data['tables'] = json_encode($data['tables']);
|
||||
PacketModel::create($data);
|
||||
}
|
||||
} else {
|
||||
$this->error('安装失败:'. $result);
|
||||
}
|
||||
}
|
||||
// 记录行为
|
||||
$packet_titles = PacketModel::where('name', 'in', $names)->column('title');
|
||||
action_log('packet_install', 'admin_packet', 0, UID, implode('、', $packet_titles));
|
||||
$this->success('安装成功');
|
||||
}
|
||||
|
||||
/**
|
||||
* 卸载
|
||||
* @param string $name 数据包名
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
*/
|
||||
public function uninstall($name = '')
|
||||
{
|
||||
$names = $name != '' ? (array)$name : $this->request->param('ids/a');
|
||||
|
||||
// 记录行为
|
||||
$packet_titles = PacketModel::where('name', 'in', $names)->column('title');
|
||||
action_log('packet_uninstall', 'admin_packet', 0, UID, implode('、', $packet_titles));
|
||||
|
||||
foreach ($names as $name) {
|
||||
PacketModel::uninstall($name);
|
||||
}
|
||||
|
||||
$this->success('卸载成功');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,620 @@
|
|||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | 海豚PHP框架 [ DolphinPHP ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 版权所有 2016~2019 广东卓锐软件有限公司 [ http://www.zrthink.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网站: http://dolphinphp.com
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace app\admin\controller;
|
||||
|
||||
use app\common\builder\ZBuilder;
|
||||
use app\admin\model\Plugin as PluginModel;
|
||||
use app\admin\model\HookPlugin as HookPluginModel;
|
||||
use think\facade\Cache;
|
||||
use util\Sql;
|
||||
use think\Db;
|
||||
use think\facade\Hook;
|
||||
|
||||
/**
|
||||
* 插件管理控制器
|
||||
* @package app\admin\controller
|
||||
*/
|
||||
class Plugin extends Admin
|
||||
{
|
||||
/**
|
||||
* 首页
|
||||
* @param string $group 分组
|
||||
* @param string $type 显示类型
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return mixed
|
||||
*/
|
||||
public function index($group = 'local', $type = '')
|
||||
{
|
||||
// 配置分组信息
|
||||
$list_group = ['local' => '本地插件'];
|
||||
$tab_list = [];
|
||||
foreach ($list_group as $key => $value) {
|
||||
$tab_list[$key]['title'] = $value;
|
||||
$tab_list[$key]['url'] = url('index', ['group' => $key]);
|
||||
}
|
||||
|
||||
// 监听tab钩子
|
||||
Hook::listen('plugin_index_tab_list', $tab_list);
|
||||
|
||||
switch ($group) {
|
||||
case 'local':
|
||||
// 查询条件
|
||||
$keyword = $this->request->get('keyword', '');
|
||||
|
||||
if (input('?param.status') && input('param.status') != '_all') {
|
||||
$status = input('param.status');
|
||||
} else {
|
||||
$status = '';
|
||||
}
|
||||
|
||||
$PluginModel = new PluginModel;
|
||||
$result = $PluginModel->getAll($keyword, $status);
|
||||
|
||||
if ($result['plugins'] === false) {
|
||||
$this->error($PluginModel->getError());
|
||||
}
|
||||
|
||||
$type_show = Cache::get('plugin_type_show');
|
||||
$type_show = $type != '' ? $type : ($type_show == false ? 'block' : $type_show);
|
||||
Cache::set('plugin_type_show', $type_show);
|
||||
$type = $type_show == 'block' ? 'list' : 'block';
|
||||
|
||||
$this->assign('page_title', '插件管理');
|
||||
$this->assign('plugins', $result['plugins']);
|
||||
$this->assign('total', $result['total']);
|
||||
$this->assign('tab_nav', ['tab_list' => $tab_list, 'curr_tab' => $group]);
|
||||
$this->assign('type', $type);
|
||||
return $this->fetch();
|
||||
break;
|
||||
case 'online':
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 安装插件
|
||||
* @param string $name 插件标识
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
*/
|
||||
public function install($name = '')
|
||||
{
|
||||
// 设置最大执行时间和内存大小
|
||||
ini_set('max_execution_time', '0');
|
||||
ini_set('memory_limit', '1024M');
|
||||
|
||||
$plug_name = trim($name);
|
||||
if ($plug_name == '') $this->error('插件不存在!');
|
||||
|
||||
$plugin_class = get_plugin_class($plug_name);
|
||||
|
||||
if (!class_exists($plugin_class)) {
|
||||
$this->error('插件不存在!');
|
||||
}
|
||||
|
||||
// 实例化插件
|
||||
$plugin = new $plugin_class;
|
||||
// 插件预安装
|
||||
if(!$plugin->install()) {
|
||||
$this->error('插件预安装失败!原因:'. $plugin->getError());
|
||||
}
|
||||
|
||||
// 添加钩子
|
||||
if (isset($plugin->hooks) && !empty($plugin->hooks)) {
|
||||
if (!HookPluginModel::addHooks($plugin->hooks, $name)) {
|
||||
$this->error('安装插件钩子时出现错误,请重新安装');
|
||||
}
|
||||
cache('hook_plugins', null);
|
||||
}
|
||||
|
||||
// 执行安装插件sql文件
|
||||
$sql_file = realpath(config('plugin_path').$name.'/install.sql');
|
||||
if (file_exists($sql_file)) {
|
||||
if (isset($plugin->database_prefix) && $plugin->database_prefix != '') {
|
||||
$sql_statement = Sql::getSqlFromFile($sql_file, false, [$plugin->database_prefix => config('database.prefix')]);
|
||||
} else {
|
||||
$sql_statement = Sql::getSqlFromFile($sql_file);
|
||||
}
|
||||
|
||||
if (!empty($sql_statement)) {
|
||||
foreach ($sql_statement as $value) {
|
||||
Db::execute($value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 插件配置信息
|
||||
$plugin_info = $plugin->info;
|
||||
|
||||
// 验证插件信息
|
||||
$result = $this->validate($plugin_info, 'Plugin');
|
||||
// 验证失败 输出错误信息
|
||||
if(true !== $result) $this->error($result);
|
||||
|
||||
// 并入插件配置值
|
||||
$plugin_info['config'] = $plugin->getConfigValue();
|
||||
|
||||
// 将插件信息写入数据库
|
||||
if (PluginModel::create($plugin_info)) {
|
||||
cache('plugin_all', null);
|
||||
$this->success('插件安装成功');
|
||||
} else {
|
||||
$this->error('插件安装失败');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 卸载插件
|
||||
* @param string $name 插件标识
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @throws \think\Exception
|
||||
* @throws \think\exception\PDOException
|
||||
*/
|
||||
public function uninstall($name = '')
|
||||
{
|
||||
$plug_name = trim($name);
|
||||
if ($plug_name == '') $this->error('插件不存在!');
|
||||
|
||||
$class = get_plugin_class($plug_name);
|
||||
if (!class_exists($class)) {
|
||||
$this->error('插件不存在!');
|
||||
}
|
||||
|
||||
// 实例化插件
|
||||
$plugin = new $class;
|
||||
// 插件预卸
|
||||
if(!$plugin->uninstall()) {
|
||||
$this->error('插件预卸载失败!原因:'. $plugin->getError());
|
||||
}
|
||||
|
||||
// 卸载插件自带钩子
|
||||
if (isset($plugin->hooks) && !empty($plugin->hooks)) {
|
||||
if (false === HookPluginModel::deleteHooks($plug_name)) {
|
||||
$this->error('卸载插件钩子时出现错误,请重新卸载');
|
||||
}
|
||||
cache('hook_plugins', null);
|
||||
}
|
||||
|
||||
// 执行卸载插件sql文件
|
||||
$sql_file = realpath(config('plugin_path').$plug_name.'/uninstall.sql');
|
||||
if (file_exists($sql_file)) {
|
||||
if (isset($plugin->database_prefix) && $plugin->database_prefix != '') {
|
||||
$sql_statement = Sql::getSqlFromFile($sql_file, true, [$plugin->database_prefix => config('database.prefix')]);
|
||||
} else {
|
||||
$sql_statement = Sql::getSqlFromFile($sql_file, true);
|
||||
}
|
||||
|
||||
if (!empty($sql_statement)) {
|
||||
Db::execute($sql_statement);
|
||||
}
|
||||
}
|
||||
|
||||
// 删除插件信息
|
||||
if (PluginModel::where('name', $plug_name)->delete()) {
|
||||
cache('plugin_all', null);
|
||||
$this->success('插件卸载成功');
|
||||
} else {
|
||||
$this->error('插件卸载失败');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 插件管理
|
||||
* @param string $name 插件名
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return mixed
|
||||
* @throws \think\Exception
|
||||
*/
|
||||
public function manage($name = '')
|
||||
{
|
||||
cookie('__forward__', $_SERVER['REQUEST_URI']);
|
||||
|
||||
// 加载自定义后台页面
|
||||
if (plugin_action_exists($name, 'Admin', 'index')) {
|
||||
return plugin_action($name, 'Admin', 'index');
|
||||
}
|
||||
|
||||
// 加载系统的后台页面
|
||||
$class = get_plugin_class($name);
|
||||
if (!class_exists($class)) {
|
||||
$this->error($name.'插件不存在!');
|
||||
}
|
||||
|
||||
// 实例化插件
|
||||
$plugin = new $class;
|
||||
|
||||
// 获取后台字段信息,并分析
|
||||
if (isset($plugin->admin)) {
|
||||
$admin = $this->parseAdmin($plugin->admin);
|
||||
} else {
|
||||
$admin = $this->parseAdmin();
|
||||
}
|
||||
|
||||
if (!plugin_model_exists($name)) {
|
||||
$this->error('插件: '.$name.' 缺少模型文件!');
|
||||
}
|
||||
|
||||
// 获取插件模型实例
|
||||
$PluginModel = get_plugin_model($name);
|
||||
$order = $this->getOrder();
|
||||
$map = $this->getMap();
|
||||
$data_list = $PluginModel->where($map)->order($order)->paginate();
|
||||
$page = $data_list->render();
|
||||
|
||||
// 使用ZBuilder快速创建数据表格
|
||||
$builder = ZBuilder::make('table')
|
||||
->setPageTitle($admin['title']) // 设置页面标题
|
||||
->setPluginName($name)
|
||||
->setTableName($admin['table_name'])
|
||||
->setSearch($admin['search_field'], $admin['search_title']) // 设置搜索框
|
||||
->addOrder($admin['order'])
|
||||
->addTopButton('back', [
|
||||
'title' => '返回插件列表',
|
||||
'icon' => 'fa fa-reply',
|
||||
'href' => url('index')
|
||||
])
|
||||
->addTopButtons($admin['top_buttons']) // 批量添加顶部按钮
|
||||
->addRightButtons($admin['right_buttons']); // 批量添加右侧按钮
|
||||
|
||||
// 自定义顶部按钮
|
||||
if (!empty($admin['custom_top_buttons'])) {
|
||||
foreach ($admin['custom_top_buttons'] as $custom) {
|
||||
$builder->addTopButton('custom', $custom);
|
||||
}
|
||||
}
|
||||
// 自定义右侧按钮
|
||||
if (!empty($admin['custom_right_buttons'])) {
|
||||
foreach ($admin['custom_right_buttons'] as $custom) {
|
||||
$builder->addRightButton('custom', $custom);
|
||||
}
|
||||
}
|
||||
|
||||
// 表头筛选
|
||||
if (is_array($admin['filter'])) {
|
||||
foreach ($admin['filter'] as $column => $params) {
|
||||
$options = isset($params[0]) ? $params[0] : [];
|
||||
$default = isset($params[1]) ? $params[1] : [];
|
||||
$type = isset($params[2]) ? $params[2] : 'checkbox';
|
||||
$builder->addFilter($column, $options, $default, $type);
|
||||
}
|
||||
} else {
|
||||
$builder->addFilter($admin['filter']);
|
||||
}
|
||||
|
||||
return $builder
|
||||
->addColumns($admin['columns']) // 批量添加数据列
|
||||
->setRowList($data_list) // 设置表格数据
|
||||
->setPages($page) // 设置分页数据
|
||||
->fetch(); // 渲染模板
|
||||
}
|
||||
|
||||
/**
|
||||
* 插件新增方法
|
||||
* @param string $plugin_name 插件名称
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return mixed
|
||||
* @throws \think\Exception
|
||||
*/
|
||||
public function add($plugin_name = '')
|
||||
{
|
||||
// 如果存在自定义的新增方法,则优先执行
|
||||
if (plugin_action_exists($plugin_name, 'Admin', 'add')) {
|
||||
$params = $this->request->param();
|
||||
return plugin_action($plugin_name, 'Admin', 'add', $params);
|
||||
}
|
||||
|
||||
// 保存数据
|
||||
if ($this->request->isPost()) {
|
||||
$data = $this->request->post();
|
||||
|
||||
// 执行插件的验证器(如果存在的话)
|
||||
if (plugin_validate_exists($plugin_name)) {
|
||||
$plugin_validate = get_plugin_validate($plugin_name);
|
||||
if (!$plugin_validate->check($data)) {
|
||||
// 验证失败 输出错误信息
|
||||
$this->error($plugin_validate->getError());
|
||||
}
|
||||
}
|
||||
|
||||
// 实例化模型并添加数据
|
||||
$PluginModel = get_plugin_model($plugin_name);
|
||||
if ($PluginModel->data($data)->save()) {
|
||||
$this->success('新增成功', cookie('__forward__'));
|
||||
} else {
|
||||
$this->error('新增失败');
|
||||
}
|
||||
}
|
||||
|
||||
// 获取插件模型
|
||||
$class = get_plugin_class($plugin_name);
|
||||
if (!class_exists($class)) {
|
||||
$this->error('插件不存在!');
|
||||
}
|
||||
|
||||
// 实例化插件
|
||||
$plugin = new $class;
|
||||
if (!isset($plugin->fields)) {
|
||||
$this->error('插件新增、编辑字段不存在!');
|
||||
}
|
||||
|
||||
// 使用ZBuilder快速创建表单
|
||||
return ZBuilder::make('form')
|
||||
->setPageTitle('新增')
|
||||
->addFormItems($plugin->fields)
|
||||
->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑插件方法
|
||||
* @param string $id 数据id
|
||||
* @param string $plugin_name 插件名称
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return mixed
|
||||
* @throws \think\Exception
|
||||
*/
|
||||
public function edit($id = '', $plugin_name = '')
|
||||
{
|
||||
// 如果存在自定义的编辑方法,则优先执行
|
||||
if (plugin_action_exists($plugin_name, 'Admin', 'edit')) {
|
||||
$params = $this->request->param();
|
||||
return plugin_action($plugin_name, 'Admin', 'edit', $params);
|
||||
}
|
||||
|
||||
// 保存数据
|
||||
if ($this->request->isPost()) {
|
||||
$data = $this->request->post();
|
||||
|
||||
// 执行插件的验证器(如果存在的话)
|
||||
if (plugin_validate_exists($plugin_name)) {
|
||||
$plugin_validate = get_plugin_validate($plugin_name);
|
||||
if (!$plugin_validate->check($data)) {
|
||||
// 验证失败 输出错误信息
|
||||
$this->error($plugin_validate->getError());
|
||||
}
|
||||
}
|
||||
|
||||
// 实例化模型并添加数据
|
||||
$PluginModel = get_plugin_model($plugin_name);
|
||||
if (false !== $PluginModel->isUpdate(true)->save($data)) {
|
||||
$this->success('编辑成功', cookie('__forward__'));
|
||||
} else {
|
||||
$this->error('编辑失败');
|
||||
}
|
||||
}
|
||||
|
||||
// 获取插件类名
|
||||
$class = get_plugin_class($plugin_name);
|
||||
if (!class_exists($class)) {
|
||||
$this->error('插件不存在!');
|
||||
}
|
||||
|
||||
// 实例化插件
|
||||
$plugin = new $class;
|
||||
if (!isset($plugin->fields)) {
|
||||
$this->error('插件新增、编辑字段不存在!');
|
||||
}
|
||||
|
||||
// 获取数据
|
||||
$PluginModel = get_plugin_model($plugin_name);
|
||||
$info = $PluginModel->find($id);
|
||||
if (!$info) {
|
||||
$this->error('找不到数据!');
|
||||
}
|
||||
|
||||
// 使用ZBuilder快速创建表单
|
||||
return ZBuilder::make('form')
|
||||
->setPageTitle('编辑')
|
||||
->addHidden('id')
|
||||
->addFormItems($plugin->fields)
|
||||
->setFormData($info)
|
||||
->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* 插件参数设置
|
||||
* @param string $name 插件名称
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return mixed
|
||||
* @throws \think\Exception
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @throws \think\exception\DbException
|
||||
* @throws \think\exception\PDOException
|
||||
*/
|
||||
public function config($name = '')
|
||||
{
|
||||
// 更新配置
|
||||
if ($this->request->isPost()) {
|
||||
$data = $this->request->except(config('zbuilder.form_token_name'), 'post');
|
||||
$data = json_encode($data);
|
||||
|
||||
if (false !== PluginModel::where('name', $name)->update(['config' => $data])) {
|
||||
$this->success('更新成功', 'index');
|
||||
} else {
|
||||
$this->error('更新失败');
|
||||
}
|
||||
}
|
||||
|
||||
$plugin_class = get_plugin_class($name);
|
||||
// 实例化插件
|
||||
$plugin = new $plugin_class;
|
||||
$trigger = isset($plugin->trigger) ? $plugin->trigger : [];
|
||||
|
||||
// 插件配置值
|
||||
$info = PluginModel::where('name', $name)->field('id,name,config')->find();
|
||||
$db_config = json_decode($info['config'], true);
|
||||
|
||||
// 插件配置项
|
||||
$config = include config('plugin_path'). $name. '/config.php';
|
||||
|
||||
// 使用ZBuilder快速创建表单
|
||||
return ZBuilder::make('form')
|
||||
->setPageTitle('插件设置')
|
||||
->addFormItems($config)
|
||||
->setFormData($db_config)
|
||||
->setTrigger($trigger)
|
||||
->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置状态
|
||||
* @param string $type 状态类型:enable/disable
|
||||
* @param array $record 行为日志内容
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @throws \think\Exception
|
||||
* @throws \think\exception\PDOException
|
||||
*/
|
||||
public function setStatus($type = '', $record = [])
|
||||
{
|
||||
$_t = input('param._t', '');
|
||||
$ids = $this->request->isPost() ? input('post.ids/a') : input('param.ids');
|
||||
empty($ids) && $this->error('缺少主键');
|
||||
|
||||
$status = $type == 'enable' ? 1 : 0;
|
||||
|
||||
if ($_t != '') {
|
||||
parent::setStatus($type, $record);
|
||||
} else {
|
||||
$plugins = PluginModel::where('id', 'in', $ids)->value('name');
|
||||
if ($plugins) {
|
||||
HookPluginModel::$type($plugins);
|
||||
}
|
||||
|
||||
if (false !== PluginModel::where('id', 'in', $ids)->setField('status', $status)) {
|
||||
$this->success('操作成功');
|
||||
} else {
|
||||
$this->error('操作失败');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 禁用插件/禁用插件数据
|
||||
* @param array $record 行为日志内容
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @throws \think\Exception
|
||||
* @throws \think\exception\PDOException
|
||||
*/
|
||||
public function disable($record = [])
|
||||
{
|
||||
$this->setStatus('disable');
|
||||
}
|
||||
|
||||
/**
|
||||
* 启用插件/启用插件数据
|
||||
* @param array $record 行为日志内容
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @throws \think\Exception
|
||||
* @throws \think\exception\PDOException
|
||||
*/
|
||||
public function enable($record = [])
|
||||
{
|
||||
$this->setStatus('enable');
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除插件数据
|
||||
* @param array $record
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @throws \think\Exception
|
||||
* @throws \think\exception\PDOException
|
||||
*/
|
||||
public function delete($record = [])
|
||||
{
|
||||
$this->setStatus('delete');
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行插件内部方法
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return mixed
|
||||
*/
|
||||
public function execute()
|
||||
{
|
||||
$plugin = input('param._plugin');
|
||||
$controller = input('param._controller');
|
||||
$action = input('param._action');
|
||||
$params = $this->request->except(['_plugin', '_controller', '_action'], 'param');
|
||||
|
||||
if (empty($plugin) || empty($controller) || empty($action)) {
|
||||
$this->error('没有指定插件名称、控制器名称或操作名称');
|
||||
}
|
||||
|
||||
if (!plugin_action_exists($plugin, $controller, $action)) {
|
||||
$this->error("找不到方法:{$plugin}/{$controller}/{$action}");
|
||||
}
|
||||
return plugin_action($plugin, $controller, $action, $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* 分析后台字段信息
|
||||
* @param array $data 字段信息
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return array
|
||||
*/
|
||||
private function parseAdmin($data = [])
|
||||
{
|
||||
$admin = [
|
||||
'title' => '数据列表',
|
||||
'search_title' => '',
|
||||
'search_field' => [],
|
||||
'order' => '',
|
||||
'filter' => '',
|
||||
'table_name' => '',
|
||||
'columns' => [],
|
||||
'right_buttons' => [],
|
||||
'top_buttons' => [],
|
||||
'customs' => [],
|
||||
];
|
||||
|
||||
if (empty($data)) {
|
||||
return $admin;
|
||||
}
|
||||
|
||||
// 处理工具栏按钮链接
|
||||
if (isset($data['top_buttons']) && !empty($data['top_buttons'])) {
|
||||
$this->parseButton('top_buttons', $data);
|
||||
}
|
||||
|
||||
// 处理右侧按钮链接
|
||||
if (isset($data['right_buttons']) && !empty($data['right_buttons'])) {
|
||||
$this->parseButton('right_buttons', $data);
|
||||
}
|
||||
|
||||
return array_merge($admin, $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析按钮链接
|
||||
* @param string $button 按钮名称
|
||||
* @param array $data 字段信息
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
*/
|
||||
private function parseButton($button, &$data)
|
||||
{
|
||||
foreach ($data[$button] as $key => &$value) {
|
||||
// 处理自定义按钮
|
||||
if ($key === 'customs') {
|
||||
if (!empty($value)) {
|
||||
foreach ($value as &$custom) {
|
||||
if (isset($custom['href']['url']) && $custom['href']['url'] != '') {
|
||||
$params = isset($custom['href']['params']) ? $custom['href']['params'] : [];
|
||||
$custom['href'] = plugin_url($custom['href']['url'], $params);
|
||||
$data['custom_'.$button][] = $custom;
|
||||
}
|
||||
}
|
||||
}
|
||||
unset($data[$button][$key]);
|
||||
}
|
||||
if (!is_numeric($key) && isset($value['href']['url']) && $value['href']['url'] != '') {
|
||||
$value['href'] = plugin_url($value['href']['url']);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,186 @@
|
|||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | 海豚PHP框架 [ DolphinPHP ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 版权所有 2016~2019 广东卓锐软件有限公司 [ http://www.zrthink.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网站: http://dolphinphp.com
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace app\admin\controller;
|
||||
|
||||
use app\common\builder\ZBuilder;
|
||||
use app\admin\model\Config as ConfigModel;
|
||||
use app\admin\model\Module as ModuleModel;
|
||||
|
||||
/**
|
||||
* 系统模块控制器
|
||||
* @package app\admin\controller
|
||||
*/
|
||||
class System extends Admin
|
||||
{
|
||||
/**
|
||||
* 系统设置
|
||||
* @param string $group 分组
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return mixed
|
||||
* @throws \think\Exception
|
||||
* @throws \think\exception\PDOException
|
||||
*/
|
||||
public function index($group = 'base')
|
||||
{
|
||||
// 保存数据
|
||||
if ($this->request->isPost()) {
|
||||
$data = $this->request->post();
|
||||
|
||||
if (isset(config('config_group')[$group])) {
|
||||
// 查询该分组下所有的配置项名和类型
|
||||
$items = ConfigModel::where('group', $group)->where('status', 1)->column('name,type');
|
||||
|
||||
foreach ($items as $name => $type) {
|
||||
if (!isset($data[$name])) {
|
||||
switch ($type) {
|
||||
// 开关
|
||||
case 'switch':
|
||||
$data[$name] = 0;
|
||||
break;
|
||||
case 'checkbox':
|
||||
$data[$name] = '';
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
// 如果值是数组则转换成字符串,适用于复选框等类型
|
||||
if (is_array($data[$name])) {
|
||||
$data[$name] = implode(',', $data[$name]);
|
||||
}
|
||||
switch ($type) {
|
||||
// 开关
|
||||
case 'switch':
|
||||
$data[$name] = 1;
|
||||
break;
|
||||
// 日期时间
|
||||
case 'date':
|
||||
case 'time':
|
||||
case 'datetime':
|
||||
$data[$name] = strtotime($data[$name]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
ConfigModel::where('name', $name)->update(['value' => $data[$name]]);
|
||||
}
|
||||
} else {
|
||||
// 保存模块配置
|
||||
if (false === ModuleModel::where('name', $group)->update(['config' => json_encode($data)])) {
|
||||
$this->error('更新失败');
|
||||
}
|
||||
// 非开发模式,缓存数据
|
||||
if (config('develop_mode') == 0) {
|
||||
cache('module_config_'.$group, $data);
|
||||
}
|
||||
}
|
||||
cache('system_config', null);
|
||||
// 记录行为
|
||||
action_log('system_config_update', 'admin_config', 0, UID, "分组($group)");
|
||||
$this->success('更新成功', url('index', ['group' => $group]));
|
||||
} else {
|
||||
// 配置分组信息
|
||||
$list_group = config('config_group');
|
||||
|
||||
// 读取模型配置
|
||||
$modules = ModuleModel::where('config', 'neq', '')
|
||||
->where('status', 1)
|
||||
->column('config,title,name', 'name');
|
||||
foreach ($modules as $name => $module) {
|
||||
$list_group[$name] = $module['title'];
|
||||
}
|
||||
|
||||
$tab_list = [];
|
||||
foreach ($list_group as $key => $value) {
|
||||
$tab_list[$key]['title'] = $value;
|
||||
$tab_list[$key]['url'] = url('index', ['group' => $key]);
|
||||
}
|
||||
|
||||
if (isset(config('config_group')[$group])) {
|
||||
// 查询条件
|
||||
$map['group'] = $group;
|
||||
$map['status'] = 1;
|
||||
|
||||
// 数据列表
|
||||
$data_list = ConfigModel::where($map)
|
||||
->order('sort asc,id asc')
|
||||
->field('group', true)
|
||||
->select();
|
||||
$data_list = $data_list->toArray();
|
||||
|
||||
foreach ($data_list as &$value) {
|
||||
// 解析options
|
||||
if ($value['options'] != '') {
|
||||
$value['options'] = parse_attr($value['options']);
|
||||
}
|
||||
// 默认模块列表
|
||||
if ($value['name'] == 'home_default_module') {
|
||||
$value['options'] = array_merge(['index' => '默认'], ModuleModel::getModule());
|
||||
}
|
||||
switch ($value['type']) {
|
||||
// 日期时间
|
||||
case 'date':
|
||||
$value['value'] = $value['value'] != '' ? date('Y-m-d', $value['value']) : '';
|
||||
break;
|
||||
case 'time':
|
||||
$value['value'] = $value['value'] != '' ? date('H:i:s', $value['value']) : '';
|
||||
break;
|
||||
case 'datetime':
|
||||
$value['value'] = $value['value'] != '' ? date('Y-m-d H:i:s', $value['value']) : '';
|
||||
break;
|
||||
case 'linkages':
|
||||
$value['token'] = $this->createLinkagesToken($value['table'], $value['option'], $value['key']);
|
||||
break;
|
||||
case 'colorpicker':
|
||||
$value['mode'] = 'rgba';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 使用ZBuilder快速创建表单
|
||||
return ZBuilder::make('form')
|
||||
->setPageTitle('系统设置')
|
||||
->setTabNav($tab_list, $group)
|
||||
->setFormItems($data_list)
|
||||
->fetch();
|
||||
} else {
|
||||
// 模块配置
|
||||
$module_info = ModuleModel::getInfoFromFile($group);
|
||||
$config = $module_info['config'];
|
||||
$trigger = isset($module_info['trigger']) ? $module_info['trigger'] : [];
|
||||
|
||||
// 数据库内的模块信息
|
||||
$db_config = ModuleModel::where('name', $group)->value('config');
|
||||
$db_config = json_decode($db_config, true);
|
||||
|
||||
// 使用ZBuilder快速创建表单
|
||||
return ZBuilder::make('form')
|
||||
->setPageTitle('模块设置')
|
||||
->setTabNav($tab_list, $group)
|
||||
->addFormItems($config)
|
||||
->setFormdata($db_config) // 设置表格数据
|
||||
->setTrigger($trigger) // 设置触发
|
||||
->fetch();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建快速多级联动Token
|
||||
* @param string $table 表名
|
||||
* @param string $option
|
||||
* @param string $key
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return bool|string
|
||||
*/
|
||||
private function createLinkagesToken($table = '', $option = '', $key = '')
|
||||
{
|
||||
$table_token = substr(sha1($table.'-'.$option.'-'.$key.'-'.session('user_auth.last_login_ip').'-'.UID.'-'.session('user_auth.last_login_time')), 0, 8);
|
||||
session($table_token, ['table' => $table, 'option' => $option, 'key' => $key]);
|
||||
return $table_token;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,83 @@
|
|||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | 海豚PHP框架 [ DolphinPHP ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 版权所有 2016~2019 广东卓锐软件有限公司 [ http://www.zrthink.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网站: http://dolphinphp.com
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace app\admin\model;
|
||||
|
||||
use think\Model;
|
||||
use think\facade\Request;
|
||||
|
||||
/**
|
||||
* 统一授权模型
|
||||
* @package app\admin\model
|
||||
*/
|
||||
class Access extends Model
|
||||
{
|
||||
// 设置当前模型对应的完整数据表名称
|
||||
protected $name = 'admin_access';
|
||||
|
||||
/**
|
||||
* 获取用户授权节点
|
||||
* @param int $uid 用户id
|
||||
* @param string $group 权限分组,可以以点分开模型名称和分组名称,如user.group
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return array|bool
|
||||
*/
|
||||
public function getAuthNode($uid = 0, $group = '')
|
||||
{
|
||||
if ($uid == 0 || $group == '') {
|
||||
$this->error = '缺少参数';
|
||||
return false;
|
||||
}
|
||||
|
||||
if (strpos($group, '.')) {
|
||||
list($module, $group) = explode('.', $group);
|
||||
} else {
|
||||
$module = Request::module();
|
||||
}
|
||||
|
||||
$map = [
|
||||
'module' => $module,
|
||||
'group' => $group,
|
||||
'uid' => $uid
|
||||
];
|
||||
|
||||
return $this->where($map)->column('nid');
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查用户的某个节点是否授权
|
||||
* @param int $uid 用户id
|
||||
* @param string $group $group 权限分组,可以以点分开模型名称和分组名称,如user.group
|
||||
* @param int $node 需要检查的节点id
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return bool
|
||||
*/
|
||||
public function checkAuthNode($uid = 0, $group = '', $node = 0)
|
||||
{
|
||||
if ($uid == 0 || $group == '' || $node == 0) {
|
||||
$this->error = '缺少参数';
|
||||
return false;
|
||||
}
|
||||
|
||||
// 获取该用户的所有授权节点
|
||||
$nodes = $this->getAuthNode($uid, $group);
|
||||
if (!$nodes) {
|
||||
$this->error = '该用户没有授权任何节点';
|
||||
return false;
|
||||
}
|
||||
|
||||
$nodes = array_flip($nodes);
|
||||
if (isset($nodes[$node])) {
|
||||
return true;
|
||||
} else {
|
||||
$this->error = '未授权';
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | 海豚PHP框架 [ DolphinPHP ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 版权所有 2016~2019 广东卓锐软件有限公司 [ http://www.zrthink.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网站: http://dolphinphp.com
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace app\admin\model;
|
||||
|
||||
use think\Model;
|
||||
|
||||
/**
|
||||
* 日志模型
|
||||
* @package app\admin\model
|
||||
*/
|
||||
class Action extends Model
|
||||
{
|
||||
// 设置当前模型对应的完整数据表名称
|
||||
protected $name = 'admin_action';
|
||||
|
||||
// 自动写入时间戳
|
||||
protected $autoWriteTimestamp = true;
|
||||
}
|
|
@ -0,0 +1,95 @@
|
|||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | 海豚PHP框架 [ DolphinPHP ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 版权所有 2016~2019 广东卓锐软件有限公司 [ http://www.zrthink.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网站: http://dolphinphp.com
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace app\admin\model;
|
||||
|
||||
use think\Model;
|
||||
|
||||
/**
|
||||
* 附件模型
|
||||
* @package app\admin\model
|
||||
*/
|
||||
class Attachment extends Model
|
||||
{
|
||||
// 设置当前模型对应的完整数据表名称
|
||||
protected $name = 'admin_attachment';
|
||||
|
||||
// 自动写入时间戳
|
||||
protected $autoWriteTimestamp = true;
|
||||
|
||||
/**
|
||||
* 根据附件id获取路径
|
||||
* @param string|array $id 附件id
|
||||
* @param int $type 类型:0-补全目录,1-直接返回数据库记录的地址
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return array|bool|mixed|string
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @throws \think\exception\DbException
|
||||
*/
|
||||
public function getFilePath($id = '', $type = 0)
|
||||
{
|
||||
if (is_array($id)) {
|
||||
$data_list = $this->where('id', 'in', $id)->select();
|
||||
$paths = [];
|
||||
foreach ($data_list as $key => $value) {
|
||||
if ($value['driver'] == 'local') {
|
||||
$paths[$value['id']] = ($type == 0 ? PUBLIC_PATH : '').$value['path'];
|
||||
} else {
|
||||
$paths[$value['id']] = $value['path'];
|
||||
}
|
||||
}
|
||||
return $paths;
|
||||
} else {
|
||||
$data = $this->where('id', $id)->find();
|
||||
if ($data) {
|
||||
if ($data['driver'] == 'local') {
|
||||
return ($type == 0 ? PUBLIC_PATH : '').$data['path'];
|
||||
} else {
|
||||
return $data['path'];
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据图片id获取缩略图路径,如果缩略图不存在,则返回原图路径
|
||||
* @param string $id 图片id
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return array|mixed|string|Model|null
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @throws \think\exception\DbException
|
||||
*/
|
||||
public function getThumbPath($id = '')
|
||||
{
|
||||
$result = $this->where('id', $id)->field('path,driver,thumb')->find();
|
||||
if ($result) {
|
||||
if ($result['driver'] == 'local') {
|
||||
return $result['thumb'] != '' ? PUBLIC_PATH.$result['thumb'] : PUBLIC_PATH.$result['path'];
|
||||
} else {
|
||||
return $result['thumb'] != '' ? $result['thumb'] : $result['path'];
|
||||
}
|
||||
} else {
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据附件id获取名称
|
||||
* @param string $id 附件id
|
||||
* @return string 名称
|
||||
*/
|
||||
public function getFileName($id = '')
|
||||
{
|
||||
return $this->where('id', $id)->value('name');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | 海豚PHP框架 [ DolphinPHP ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 版权所有 2016~2019 广东卓锐软件有限公司 [ http://www.zrthink.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网站: http://dolphinphp.com
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace app\admin\model;
|
||||
|
||||
use think\Model;
|
||||
|
||||
/**
|
||||
* 后台配置模型
|
||||
* @package app\admin\model
|
||||
*/
|
||||
class Config extends Model
|
||||
{
|
||||
// 设置当前模型对应的完整数据表名称
|
||||
protected $name = 'admin_config';
|
||||
|
||||
// 自动写入时间戳
|
||||
protected $autoWriteTimestamp = true;
|
||||
|
||||
/**
|
||||
* 获取配置信息
|
||||
* @param string $name 配置名
|
||||
* @return mixed
|
||||
*/
|
||||
public function getConfig($name = '')
|
||||
{
|
||||
$configs = self::column('value,type', 'name');
|
||||
|
||||
$result = [];
|
||||
foreach ($configs as $config) {
|
||||
switch ($config['type']) {
|
||||
case 'array':
|
||||
$result[$config['name']] = parse_attr($config['value']);
|
||||
break;
|
||||
case 'checkbox':
|
||||
if ($config['value'] != '') {
|
||||
$result[$config['name']] = explode(',', $config['value']);
|
||||
} else {
|
||||
$result[$config['name']] = [];
|
||||
}
|
||||
break;
|
||||
default:
|
||||
$result[$config['name']] = $config['value'];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $name != '' ? $result[$name] : $result;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,80 @@
|
|||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | 海豚PHP框架 [ DolphinPHP ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 版权所有 2016~2019 广东卓锐软件有限公司 [ http://www.zrthink.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网站: http://dolphinphp.com
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace app\admin\model;
|
||||
|
||||
use think\Model;
|
||||
|
||||
/**
|
||||
* 钩子模型
|
||||
* @package app\admin\model
|
||||
*/
|
||||
class Hook extends Model
|
||||
{
|
||||
// 设置当前模型对应的完整数据表名称
|
||||
protected $name = 'admin_hook';
|
||||
|
||||
// 自动写入时间戳
|
||||
protected $autoWriteTimestamp = true;
|
||||
|
||||
/**
|
||||
* 添加钩子
|
||||
* @param array $hooks 钩子
|
||||
* @param string $plugin_name
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return bool
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @throws \think\exception\DbException
|
||||
*/
|
||||
public static function addHooks($hooks = [], $plugin_name = '')
|
||||
{
|
||||
if (!empty($hooks) && is_array($hooks)) {
|
||||
$data = [];
|
||||
foreach ($hooks as $name => $description) {
|
||||
if (is_numeric($name)) {
|
||||
$name = $description;
|
||||
$description = '';
|
||||
}
|
||||
if (self::where('name', $name)->find()) {
|
||||
continue;
|
||||
}
|
||||
$data[] = [
|
||||
'name' => $name,
|
||||
'plugin' => $plugin_name,
|
||||
'description' => $description,
|
||||
'create_time' => request()->time(),
|
||||
'update_time' => request()->time(),
|
||||
];
|
||||
}
|
||||
if (!empty($data) && false === self::insertAll($data)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除钩子
|
||||
* @param string $plugin_name 钩子名称
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return bool
|
||||
* @throws \think\Exception
|
||||
* @throws \think\exception\PDOException
|
||||
*/
|
||||
public static function deleteHooks($plugin_name = '')
|
||||
{
|
||||
if (!empty($plugin_name)) {
|
||||
if (false === self::where('plugin', $plugin_name)->delete()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,130 @@
|
|||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | 海豚PHP框架 [ DolphinPHP ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 版权所有 2016~2019 广东卓锐软件有限公司 [ http://www.zrthink.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网站: http://dolphinphp.com
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace app\admin\model;
|
||||
|
||||
use think\Model;
|
||||
use app\admin\model\Hook as HookModel;
|
||||
|
||||
/**
|
||||
* 钩子-插件模型
|
||||
* @package app\admin\model
|
||||
*/
|
||||
class HookPlugin extends Model
|
||||
{
|
||||
// 设置当前模型对应的完整数据表名称
|
||||
protected $name = 'admin_hook_plugin';
|
||||
|
||||
// 自动写入时间戳
|
||||
protected $autoWriteTimestamp = true;
|
||||
|
||||
/**
|
||||
* 启用插件钩子
|
||||
* @param string $plugin 插件名称
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return bool
|
||||
*/
|
||||
public static function enable($plugin = '')
|
||||
{
|
||||
return self::where('plugin', $plugin)->setField('status', 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* 禁用插件钩子
|
||||
* @param string $plugin 插件名称
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return int
|
||||
*/
|
||||
public static function disable($plugin = '')
|
||||
{
|
||||
return self::where('plugin', $plugin)->setField('status', 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加钩子-插件对照
|
||||
* @param array $hooks 钩子
|
||||
* @param string $plugin_name 插件名称
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return bool|int|string
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @throws \think\exception\DbException
|
||||
*/
|
||||
public static function addHooks($hooks = [], $plugin_name = '')
|
||||
{
|
||||
if (!empty($hooks) && is_array($hooks)) {
|
||||
// 添加钩子
|
||||
if (!HookModel::addHooks($hooks, $plugin_name)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$data = [];
|
||||
foreach ($hooks as $name => $description) {
|
||||
if (is_numeric($name)) {
|
||||
$name = $description;
|
||||
}
|
||||
$data[] = [
|
||||
'hook' => $name,
|
||||
'plugin' => $plugin_name,
|
||||
'create_time' => request()->time(),
|
||||
'update_time' => request()->time(),
|
||||
];
|
||||
}
|
||||
|
||||
return self::insertAll($data);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除钩子
|
||||
* @param string $plugin_name 钩子名称
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return bool
|
||||
* @throws \think\Exception
|
||||
* @throws \think\exception\PDOException
|
||||
*/
|
||||
public static function deleteHooks($plugin_name = '')
|
||||
{
|
||||
if (!empty($plugin_name)) {
|
||||
// 删除钩子
|
||||
if (!HookModel::deleteHooks($plugin_name)) {
|
||||
return false;
|
||||
}
|
||||
if (false === self::where('plugin', $plugin_name)->delete()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 钩子插件排序
|
||||
* @param string $hook 钩子
|
||||
* @param string $plugins 插件名
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return bool
|
||||
*/
|
||||
public static function sort($hook = '', $plugins = '')
|
||||
{
|
||||
if ($hook != '' && $plugins != '') {
|
||||
$plugins = is_array($plugins) ? $plugins : explode(',', $plugins);
|
||||
|
||||
foreach ($plugins as $key => $plugin) {
|
||||
$map = [
|
||||
'hook' => $hook,
|
||||
'plugin' => $plugin
|
||||
];
|
||||
self::where($map)->setField('sort', $key + 1);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | 海豚PHP框架 [ DolphinPHP ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 版权所有 2016~2019 广东卓锐软件有限公司 [ http://www.zrthink.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网站: http://dolphinphp.com
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace app\admin\model;
|
||||
|
||||
use think\Model;
|
||||
|
||||
/**
|
||||
* 图标模型
|
||||
* @package app\admin\model
|
||||
*/
|
||||
class Icon extends Model
|
||||
{
|
||||
// 设置当前模型对应的完整数据表名称
|
||||
protected $name = 'admin_icon';
|
||||
|
||||
// 自动写入时间戳
|
||||
protected $autoWriteTimestamp = true;
|
||||
|
||||
/**
|
||||
* 图标列表
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return \think\model\relation\HasMany
|
||||
*/
|
||||
public function icons()
|
||||
{
|
||||
return $this->hasMany('IconList', 'icon_id')->field('title,class,code');
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取图标css链接
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return array|string|\think\Collection
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @throws \think\exception\DbException
|
||||
*/
|
||||
public static function getUrls()
|
||||
{
|
||||
$list = self::where('status', 1)->select();
|
||||
$list = $list->toArray();
|
||||
if ($list) {
|
||||
foreach ($list as $key => $item) {
|
||||
$url = substr($item['url'], 0, 4) == 'http' ? $item['url'] : 'http:'.$item['url'];
|
||||
// 检查图标url是否合法
|
||||
$result = check_icon_url($url);
|
||||
if (true !== $result) {
|
||||
unset($list[$key]);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (isset($item['icons'])) {
|
||||
$html = '<ul class="js-icon-list items-push-2x text-center">';
|
||||
foreach ($item['icons'] as $icon) {
|
||||
$html .= '<li title="'.$icon['title'].'"><i class="'.$icon['class'].'"></i> <code>'.$icon['code'].'</code></li>';
|
||||
}
|
||||
$html .= '</ul>';
|
||||
} else {
|
||||
$html = '<p class="text-center text-muted">暂无图标</p>';
|
||||
}
|
||||
$list[$key]['html'] = $html;
|
||||
}
|
||||
}
|
||||
return array_values($list);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | 海豚PHP框架 [ DolphinPHP ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 版权所有 2016~2017 河源市卓锐科技有限公司 [ http://www.zrthink.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网站: http://dolphinphp.com
|
||||
// +----------------------------------------------------------------------
|
||||
// | 开源协议 ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace app\admin\model;
|
||||
|
||||
use think\Model;
|
||||
|
||||
/**
|
||||
* 图标列表模型
|
||||
* @package app\admin\model
|
||||
*/
|
||||
class IconList extends Model
|
||||
{
|
||||
// 设置当前模型对应的完整数据表名称
|
||||
protected $name = 'admin_icon_list';
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | 海豚PHP框架 [ DolphinPHP ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 版权所有 2016~2019 广东卓锐软件有限公司 [ http://www.zrthink.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网站: http://dolphinphp.com
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace app\admin\model;
|
||||
|
||||
use think\Model;
|
||||
|
||||
/**
|
||||
* 日志记录模型
|
||||
* @package app\admin\model
|
||||
*/
|
||||
class Log extends Model
|
||||
{
|
||||
// 设置当前模型对应的完整数据表名称
|
||||
protected $name = 'admin_log';
|
||||
|
||||
// 自动写入时间戳
|
||||
protected $autoWriteTimestamp = true;
|
||||
|
||||
/**
|
||||
* 获取所有日志
|
||||
* @param array $map 条件
|
||||
* @param string $order 排序
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return \think\Paginator
|
||||
* @throws \think\exception\DbException
|
||||
*/
|
||||
public static function getAll($map = [], $order = '')
|
||||
{
|
||||
$data_list = self::view('admin_log', true)
|
||||
->view('admin_action', 'title,module', 'admin_action.id=admin_log.action_id', 'left')
|
||||
->view('admin_user', 'username', 'admin_user.id=admin_log.user_id', 'left')
|
||||
->view('admin_module', ['title' => 'module_title'], 'admin_module.name=admin_action.module')
|
||||
->where($map)
|
||||
->order($order)
|
||||
->paginate();
|
||||
return $data_list;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,322 @@
|
|||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | 海豚PHP框架 [ DolphinPHP ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 版权所有 2016~2017 河源市卓锐科技有限公司 [ http://www.zrthink.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网站: http://dolphinphp.com
|
||||
// +----------------------------------------------------------------------
|
||||
// | 开源协议 ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace app\admin\model;
|
||||
|
||||
use app\user\model\Role as RoleModel;
|
||||
use think\Model;
|
||||
use think\Exception;
|
||||
use util\Tree;
|
||||
|
||||
/**
|
||||
* 节点模型
|
||||
* @package app\admin\model
|
||||
*/
|
||||
class Menu extends Model
|
||||
{
|
||||
// 设置当前模型对应的完整数据表名称
|
||||
protected $table = '__ADMIN_MENU__';
|
||||
|
||||
// 自动写入时间戳
|
||||
protected $autoWriteTimestamp = true;
|
||||
|
||||
// 将节点url转为小写
|
||||
public function setUrlValueAttr($value)
|
||||
{
|
||||
return strtolower(trim($value));
|
||||
}
|
||||
|
||||
/**
|
||||
* 递归修改所属模型
|
||||
* @param int $id 父级节点id
|
||||
* @param string $module 模型名称
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return bool
|
||||
*/
|
||||
public static function changeModule($id = 0, $module = '')
|
||||
{
|
||||
if ($id > 0) {
|
||||
$ids = self::where('pid', $id)->column('id');
|
||||
if ($ids) {
|
||||
foreach ($ids as $id) {
|
||||
self::where('id', $id)->setField('module', $module);
|
||||
self::changeModule($id, $module);
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取树形节点
|
||||
* @param int $id 需要隐藏的节点id
|
||||
* @param string $default 默认第一个节点项,默认为“顶级节点”,如果为false则不显示,也可传入其他名称
|
||||
* @param string $module 模型名
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return mixed
|
||||
*/
|
||||
public static function getMenuTree($id = 0, $default = '', $module = '')
|
||||
{
|
||||
$result[0] = '顶级节点';
|
||||
$where = [
|
||||
['status', 'egt', 0]
|
||||
];
|
||||
if ($module != '') {
|
||||
$where[] = ['module', '=', $module];
|
||||
}
|
||||
|
||||
// 排除指定节点及其子节点
|
||||
if ($id !== 0) {
|
||||
$hide_ids = array_merge([$id], self::getChildsId($id));
|
||||
$where[] = ['id', 'not in', $hide_ids];
|
||||
}
|
||||
|
||||
// 获取节点
|
||||
$menus = Tree::toList(self::where($where)->order('pid,id')->column('id,pid,title'));
|
||||
foreach ($menus as $menu) {
|
||||
$result[$menu['id']] = $menu['title_display'];
|
||||
}
|
||||
|
||||
// 设置默认节点项标题
|
||||
if ($default != '') {
|
||||
$result[0] = $default;
|
||||
}
|
||||
|
||||
// 隐藏默认节点项
|
||||
if ($default === false) {
|
||||
unset($result[0]);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取顶部节点
|
||||
* @param string $max 最多返回多少个
|
||||
* @param string $cache_tag 缓存标签
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return array
|
||||
*/
|
||||
public static function getTopMenu($max = '', $cache_tag = '')
|
||||
{
|
||||
$cache_tag .= '_role_'.session('user_auth.role');
|
||||
$menus = cache($cache_tag);
|
||||
if (!$menus) {
|
||||
// 非开发模式,只显示可以显示的菜单
|
||||
if (config('develop_mode') == 0) {
|
||||
$map['online_hide'] = 0;
|
||||
}
|
||||
$map['status'] = 1;
|
||||
$map['pid'] = 0;
|
||||
$list_menu = self::where($map)->order('sort,id')->column('id,pid,module,title,url_value,url_type,url_target,icon,params');
|
||||
$i = 0;
|
||||
$menus = [];
|
||||
foreach ($list_menu as $key => &$menu) {
|
||||
if ($max != '' && $i >= $max) {
|
||||
break;
|
||||
}
|
||||
// 没有访问权限的节点不显示
|
||||
if (!RoleModel::checkAuth($menu['id'])) {
|
||||
continue;
|
||||
}
|
||||
if ($menu['url_value'] != '' && ($menu['url_type'] == 'module_admin' || $menu['url_type'] == 'module_home')) {
|
||||
$url = explode('/', $menu['url_value']);
|
||||
$menu['controller'] = $url[1];
|
||||
$menu['action'] = $url[2];
|
||||
$menu['url_value'] = $menu['url_type'] == 'module_admin' ? admin_url($menu['url_value'], $menu['params']) : home_url($menu['url_value'], $menu['params']);
|
||||
}
|
||||
$menus[$key] = $menu;
|
||||
$i++;
|
||||
}
|
||||
// 非开发模式,缓存菜单
|
||||
if (config('develop_mode') == 0) {
|
||||
cache($cache_tag, $menus);
|
||||
}
|
||||
}
|
||||
return $menus;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取侧栏节点
|
||||
* @param string $id 模块id
|
||||
* @param string $module 模块名
|
||||
* @param string $controller 控制器名
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return array|mixed
|
||||
*/
|
||||
public static function getSidebarMenu($id = '', $module = '', $controller = '')
|
||||
{
|
||||
$module = $module == '' ? request()->module() : $module;
|
||||
$controller = $controller == '' ? request()->controller() : $controller;
|
||||
$cache_tag = strtolower('_sidebar_menus_' . $module . '_' . $controller).'_role_'.session('user_auth.role');
|
||||
$menus = cache($cache_tag);
|
||||
|
||||
if (!$menus) {
|
||||
// 获取当前节点地址
|
||||
$location = self::getLocation($id);
|
||||
// 当前顶级节点id
|
||||
$top_id = $location[0]['id'];
|
||||
// 获取顶级节点下的所有节点
|
||||
$map = [
|
||||
'status' => 1
|
||||
];
|
||||
// 非开发模式,只显示可以显示的菜单
|
||||
if (config('develop_mode') == 0) {
|
||||
$map['online_hide'] = 0;
|
||||
}
|
||||
$menus = self::where($map)->order('sort,id')->column('id,pid,module,title,url_value,url_type,url_target,icon,params');
|
||||
|
||||
// 解析模块链接
|
||||
foreach ($menus as $key => &$menu) {
|
||||
// 没有访问权限的节点不显示
|
||||
if (!RoleModel::checkAuth($menu['id'])) {
|
||||
unset($menus[$key]);
|
||||
continue;
|
||||
}
|
||||
if ($menu['url_value'] != '' && ($menu['url_type'] == 'module_admin' || $menu['url_type'] == 'module_home')) {
|
||||
$menu['url_value'] = $menu['url_type'] == 'module_admin' ? admin_url($menu['url_value'], $menu['params']) : home_url($menu['url_value'], $menu['params']);
|
||||
}
|
||||
}
|
||||
$menus = Tree::toLayer($menus, $top_id, 2);
|
||||
|
||||
// 非开发模式,缓存菜单
|
||||
if (config('develop_mode') == 0) {
|
||||
cache($cache_tag, $menus);
|
||||
}
|
||||
}
|
||||
return $menus;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定节点ID的位置
|
||||
* @param string $id 节点id,如果没有指定,则取当前节点id
|
||||
* @param bool $del_last_url 是否删除最后一个节点的url地址
|
||||
* @param bool $check 检查节点是否存在,不存在则抛出错误
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return array
|
||||
* @throws \think\Exception
|
||||
*/
|
||||
public static function getLocation($id = '', $del_last_url = false, $check = true)
|
||||
{
|
||||
$model = request()->module();
|
||||
$controller = request()->controller();
|
||||
$action = request()->action();
|
||||
|
||||
if ($id != '') {
|
||||
$cache_name = 'location_menu_'.$id;
|
||||
} else {
|
||||
$cache_name = 'location_'.$model.'_'.$controller.'_'.$action;
|
||||
}
|
||||
|
||||
$location = cache($cache_name);
|
||||
|
||||
if (!$location) {
|
||||
$map = [
|
||||
['pid', '<>', 0],
|
||||
['url_value', '=', strtolower($model.'/'.trim(preg_replace("/[A-Z]/", "_\\0", $controller), "_").'/'.$action)]
|
||||
];
|
||||
|
||||
// 当前操作对应的节点ID
|
||||
$curr_id = $id == '' ? self::where($map)->value('id') : $id;
|
||||
|
||||
// 获取节点ID是所有父级节点
|
||||
$location = Tree::getParents(self::column('id,pid,title,url_value,params'), $curr_id);
|
||||
|
||||
if ($check && empty($location)) {
|
||||
throw new Exception('获取不到当前节点地址,可能未添加节点', 9001);
|
||||
}
|
||||
|
||||
// 剔除最后一个节点url
|
||||
if ($del_last_url) {
|
||||
$location[count($location) - 1]['url_value'] = '';
|
||||
}
|
||||
|
||||
// 非开发模式,缓存菜单
|
||||
if (config('develop_mode') == 0) {
|
||||
cache($cache_name, $location);
|
||||
}
|
||||
}
|
||||
|
||||
return $location;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据分组获取节点
|
||||
* @param string $group 分组名称
|
||||
* @param bool|string $fields 要返回的字段
|
||||
* @param array $map 查找条件
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return array
|
||||
*/
|
||||
public static function getMenusByGroup($group = '', $fields = true, $map = [])
|
||||
{
|
||||
$map['module'] = $group;
|
||||
return self::where($map)->order('sort,id')->column($fields, 'id');
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取节点分组
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return array
|
||||
*/
|
||||
public static function getGroup()
|
||||
{
|
||||
$map['status'] = 1;
|
||||
$map['pid'] = 0;
|
||||
$menus = self::where($map)->order('id,sort')->column('module,title');
|
||||
return $menus;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有子节点id
|
||||
* @param int $pid 父级id
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return array
|
||||
*/
|
||||
public static function getChildsId($pid = 0)
|
||||
{
|
||||
$ids = self::where('pid', $pid)->column('id');
|
||||
foreach ($ids as $value) {
|
||||
$ids = array_merge($ids, self::getChildsId($value));
|
||||
}
|
||||
return $ids;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有父节点id
|
||||
* @param int $id 节点id
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return array
|
||||
*/
|
||||
public static function getParentsId($id = 0)
|
||||
{
|
||||
$pid = self::where('id', $id)->value('pid');
|
||||
$pids = [];
|
||||
if ($pid != 0) {
|
||||
$pids[] = $pid;
|
||||
$pids = array_merge($pids, self::getParentsId($pid));
|
||||
}
|
||||
return $pids;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据节点id获取上下级的所有id
|
||||
* @param int $id 节点id
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return array
|
||||
*/
|
||||
public static function getLinkIds($id = 0)
|
||||
{
|
||||
$childs = self::getChildsId($id);
|
||||
$parents = self::getParentsId($id);
|
||||
return array_merge((array)(int)$id, $childs, $parents);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,343 @@
|
|||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | 海豚PHP框架 [ DolphinPHP ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 版权所有 2016~2017 河源市卓锐科技有限公司 [ http://www.zrthink.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网站: http://dolphinphp.com
|
||||
// +----------------------------------------------------------------------
|
||||
// | 开源协议 ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace app\admin\model;
|
||||
|
||||
use think\Model;
|
||||
use think\facade\Env;
|
||||
|
||||
/**
|
||||
* 模块模型
|
||||
* @package app\admin\model
|
||||
*/
|
||||
class Module extends Model
|
||||
{
|
||||
// 设置当前模型对应的完整数据表名称
|
||||
protected $table = '__ADMIN_MODULE__';
|
||||
|
||||
// 自动写入时间戳
|
||||
protected $autoWriteTimestamp = true;
|
||||
|
||||
/**
|
||||
* 获取所有模块的名称和标题
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return mixed
|
||||
*/
|
||||
public static function getModule()
|
||||
{
|
||||
$modules = cache('modules');
|
||||
if (!$modules) {
|
||||
$modules = self::where('status', '>=', 0)->order('id')->column('name,title');
|
||||
// 非开发模式,缓存数据
|
||||
if (config('develop_mode') == 0) {
|
||||
cache('modules', $modules);
|
||||
}
|
||||
}
|
||||
return $modules;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有模块信息
|
||||
* @param string $keyword 查找关键词
|
||||
* @param string $status 查找状态
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return array|bool
|
||||
*/
|
||||
public function getAll($keyword = '', $status = '')
|
||||
{
|
||||
$result = cache('module_all');
|
||||
if (!$result) {
|
||||
$dirs = array_map('basename', glob(Env::get('app_path').'*', GLOB_ONLYDIR));
|
||||
if ($dirs === false || !file_exists(Env::get('app_path'))) {
|
||||
$this->error = '模块目录不可读或者不存在';
|
||||
return false;
|
||||
}
|
||||
|
||||
// 不读取模块信息的目录
|
||||
$except_module = config('system.except_module');
|
||||
// 正常模块(包括已安装和未安装)
|
||||
$dirs = array_diff($dirs, $except_module);
|
||||
|
||||
// 读取数据库模块表
|
||||
$modules = $this->order('sort asc,id desc')->column(true, 'name');
|
||||
|
||||
// 读取未安装的模块
|
||||
foreach ($dirs as $module) {
|
||||
if (!isset($modules[$module])) {
|
||||
// 获取模块信息
|
||||
$info = self::getInfoFromFile($module);
|
||||
|
||||
$modules[$module]['name'] = $module;
|
||||
|
||||
// 模块模块信息缺失
|
||||
if (empty($info)) {
|
||||
$modules[$module]['status'] = '-2';
|
||||
continue;
|
||||
}
|
||||
|
||||
// 模块模块信息不完整
|
||||
if (!$this->checkInfo($info)) {
|
||||
$modules[$module]['status'] = '-3';
|
||||
continue;
|
||||
}
|
||||
|
||||
// 模块未安装
|
||||
$modules[$module] = $info;
|
||||
$modules[$module]['status'] = '-1'; // 模块未安装
|
||||
}
|
||||
}
|
||||
|
||||
// 数量统计
|
||||
$total = [
|
||||
'all' => count($modules), // 所有模块数量
|
||||
'-2' => 0, // 已损坏数量
|
||||
'-1' => 0, // 未安装数量
|
||||
'0' => 0, // 已禁用数量
|
||||
'1' => 0, // 已启用数量
|
||||
];
|
||||
|
||||
// 过滤查询结果和统计数量
|
||||
foreach ($modules as $key => $value) {
|
||||
// 统计数量
|
||||
if (in_array($value['status'], ['-2', '-3'])) {
|
||||
// 已损坏数量
|
||||
$total['-2']++;
|
||||
} else {
|
||||
$total[(string)$value['status']]++;
|
||||
}
|
||||
|
||||
// 过滤查询
|
||||
if ($status != '') {
|
||||
if ($status == '-2') {
|
||||
// 过滤掉非已损坏的模块
|
||||
if (!in_array($value['status'], ['-2', '-3'])) {
|
||||
unset($modules[$key]);
|
||||
continue;
|
||||
}
|
||||
} else if ($value['status'] != $status) {
|
||||
unset($modules[$key]);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if ($keyword != '') {
|
||||
if (stristr($value['name'], $keyword) === false && (!isset($value['title']) || stristr($value['title'], $keyword) === false) && (!isset($value['author']) || stristr($value['author'], $keyword) === false)) {
|
||||
unset($modules[$key]);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 处理状态及模块按钮
|
||||
foreach ($modules as &$module) {
|
||||
// 系统核心模块
|
||||
if (isset($module['system_module']) && $module['system_module'] == '1') {
|
||||
$module['actions'] = '<button class="btn btn-sm btn-noborder btn-danger" type="button" disabled>不可操作</button>';
|
||||
$module['status_class'] = 'text-success';
|
||||
$module['status_info'] = '<i class="fa fa-check"></i> 已启用';
|
||||
$module['bg_color'] = 'success';
|
||||
continue;
|
||||
}
|
||||
|
||||
switch ($module['status']) {
|
||||
case '-3': // 模块信息不完整
|
||||
$module['title'] = '模块信息不完整';
|
||||
$module['bg_color'] = 'danger';
|
||||
$module['status_class'] = 'text-danger';
|
||||
$module['status_info'] = '<i class="fa fa-times"></i> 已损坏';
|
||||
$module['actions'] = '<button class="btn btn-sm btn-noborder btn-danger" type="button" disabled>不可操作</button>';
|
||||
break;
|
||||
case '-2': // 模块信息缺失
|
||||
$module['title'] = '模块信息缺失';
|
||||
$module['bg_color'] = 'danger';
|
||||
$module['status_class'] = 'text-danger';
|
||||
$module['status_info'] = '<i class="fa fa-times"></i> 已损坏';
|
||||
$module['actions'] = '<button class="btn btn-sm btn-noborder btn-danger" type="button" disabled>不可操作</button>';
|
||||
break;
|
||||
case '-1': // 未安装
|
||||
$module['bg_color'] = 'info';
|
||||
$module['actions'] = '<a class="btn btn-sm btn-noborder btn-success" href="'.url('install', ['name' => $module['name']]).'">安装</a>';
|
||||
$module['status_class'] = 'text-info';
|
||||
$module['status_info'] = '<i class="fa fa-fw fa-th-large"></i> 未安装';
|
||||
break;
|
||||
case '0': // 禁用
|
||||
$module['bg_color'] = 'warning';
|
||||
$module['actions'] = '<a class="btn btn-sm btn-noborder btn-success ajax-get confirm" href="'.url('enable', ['ids' => $module['id']]).'">启用</a> ';
|
||||
$module['actions'] .= '<a class="btn btn-sm btn-noborder btn-primary" href="'.url('export', ['name' => $module['name']]).'">导出</a> ';
|
||||
$module['actions'] .= '<a class="btn btn-sm btn-noborder btn-danger" href="'.url('uninstall', ['name' => $module['name']]).'">卸载</a> ';
|
||||
$module['status_class'] = 'text-warning';
|
||||
$module['status_info'] = '<i class="fa fa-ban"></i> 已禁用';
|
||||
break;
|
||||
case '1': // 启用
|
||||
$module['bg_color'] = 'success';
|
||||
$module['actions'] = '<a class="btn btn-sm btn-noborder btn-info ajax-get confirm" href="'.url('update', ['name' => $module['name']]).'">更新</a> ';
|
||||
$module['actions'] .= '<a class="btn btn-sm btn-noborder btn-warning ajax-get confirm" href="'.url('disable', ['ids' => $module['id']]).'">禁用</a> ';
|
||||
$module['actions'] .= '<a class="btn btn-sm btn-noborder btn-primary" href="'.url('export', ['name' => $module['name']]).'">导出</a> ';
|
||||
$module['actions'] .= '<a class="btn btn-sm btn-noborder btn-danger" href="'.url('uninstall', ['name' => $module['name']]).'">卸载</a> ';
|
||||
$module['status_class'] = 'text-success';
|
||||
$module['status_info'] = '<i class="fa fa-check"></i> 已启用';
|
||||
break;
|
||||
default: // 未知
|
||||
$module['title'] = '未知';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$result = ['total' => $total, 'modules' => $modules];
|
||||
// 非开发模式,缓存数据
|
||||
if (config('develop_mode') == 0) {
|
||||
cache('module_all', $result);
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 从文件获取模块信息
|
||||
* @param string $name 模块名称
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return array|mixed
|
||||
*/
|
||||
public static function getInfoFromFile($name = '')
|
||||
{
|
||||
$info = [];
|
||||
if ($name != '') {
|
||||
// 从配置文件获取
|
||||
if (is_file(Env::get('app_path'). $name . '/info.php')) {
|
||||
$info = include Env::get('app_path'). $name . '/info.php';
|
||||
}
|
||||
}
|
||||
return $info;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查模块模块信息是否完整
|
||||
* @param string $info 模块模块信息
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return bool
|
||||
*/
|
||||
private function checkInfo($info = '')
|
||||
{
|
||||
$default_item = ['name','title','author','version'];
|
||||
foreach ($default_item as $item) {
|
||||
if (!isset($info[$item]) || $info[$item] == '') {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取模型配置信息
|
||||
* @param string $name 模型名
|
||||
* @param string $item 指定返回的模块配置项
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return mixed
|
||||
*/
|
||||
public static function getConfig($name = '', $item = '')
|
||||
{
|
||||
$name = $name == '' ? request()->module() : $name;
|
||||
|
||||
$config = cache('module_config_'.$name);
|
||||
if (!$config) {
|
||||
$config = self::where('name', $name)->value('config');
|
||||
if (!$config) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$config = json_decode($config, true);
|
||||
// 非开发模式,缓存数据
|
||||
if (config('develop_mode') == 0) {
|
||||
cache('module_config_'.$name, $config);
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($item)) {
|
||||
$items = explode(',', $item);
|
||||
if (count($items) == 1) {
|
||||
return isset($config[$item]) ? $config[$item] : '';
|
||||
}
|
||||
|
||||
$result = [];
|
||||
foreach ($items as $item) {
|
||||
$result[$item] = isset($config[$item]) ? $config[$item] : '';
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
return $config;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取模型配置信息
|
||||
* @param string $name 插件名.配置名
|
||||
* @param string $value 配置值
|
||||
* @author caiweiming <314013107@qq.com>
|
||||
* @return bool
|
||||
*/
|
||||
public static function setConfig($name = '', $value = '')
|
||||
{
|
||||
$item = '';
|
||||
if (strpos($name, '.')) {
|
||||
list($name, $item) = explode('.', $name);
|
||||
}
|
||||
|
||||
// 获取缓存
|
||||
$config = cache('module_config_'.$name);
|
||||
|
||||
if (!$config) {
|
||||
$config = self::where('name', $name)->value('config');
|
||||
if (!$config) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$config = json_decode($config, true);
|
||||
}
|
||||
|
||||
if ($item === '') {
|
||||
// 批量更新
|
||||
if (!is_array($value) || empty($value)) {
|
||||
// 值的格式错误,必须为数组
|
||||
return false;
|
||||
}
|
||||
|
||||
$config = array_merge($config, $value);
|
||||
} else {
|
||||
// 更新单个值
|
||||
$config[$item] = $value;
|
||||
}
|
||||
|
||||
if (false === self::where('name', $name)->setField('config', json_encode($config))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 非开发模式,缓存数据
|
||||
if (config('develop_mode') == 0) {
|
||||
cache('module_config_'.$name, $config);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 从文件获取模块菜单
|
||||
* @param string $name 模块名称
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return array|mixed
|
||||
*/
|
||||
public static function getMenusFromFile($name = '')
|
||||
{
|
||||
$menus = [];
|
||||
if ($name != '' && is_file(Env::get('app_path'). $name . '/menus.php')) {
|
||||
// 从菜单文件获取
|
||||
$menus = include Env::get('app_path'). $name . '/menus.php';
|
||||
}
|
||||
return $menus;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,125 @@
|
|||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | 海豚PHP框架 [ DolphinPHP ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 版权所有 2016~2019 广东卓锐软件有限公司 [ http://www.zrthink.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网站: http://dolphinphp.com
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace app\admin\model;
|
||||
|
||||
use think\Model;
|
||||
use think\Db;
|
||||
use util\Sql;
|
||||
|
||||
/**
|
||||
* 数据包模型
|
||||
* @package app\admin\model
|
||||
*/
|
||||
class Packet extends Model
|
||||
{
|
||||
// 设置当前模型对应的完整数据表名称
|
||||
protected $name = 'admin_packet';
|
||||
|
||||
// 自动写入时间戳
|
||||
protected $autoWriteTimestamp = true;
|
||||
|
||||
/**
|
||||
* 获取所有数据包列表
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return array|bool
|
||||
*/
|
||||
public function getAll()
|
||||
{
|
||||
// 获取数据包目录下的所有插件目录
|
||||
$dirs = array_map('basename', glob(config('packet_path').'*', GLOB_ONLYDIR));
|
||||
if ($dirs === false || !file_exists(config('packet_path'))) {
|
||||
$this->error = '插件目录不可读或者不存在';
|
||||
return false;
|
||||
}
|
||||
|
||||
// 读取数据库数据包表
|
||||
$packets = $this->column(true, 'name');
|
||||
|
||||
// 读取未安装的数据包
|
||||
foreach ($dirs as $packet) {
|
||||
if (!isset($packets[$packet])) {
|
||||
$info = $this->getInfoFromFile($packet);
|
||||
$info['status'] = 0;
|
||||
$packets[] = $info;
|
||||
}
|
||||
}
|
||||
|
||||
return $packets;
|
||||
}
|
||||
|
||||
/**
|
||||
* 从文件获取数据包信息
|
||||
* @param string $name 数据包名称
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return array|mixed
|
||||
*/
|
||||
public static function getInfoFromFile($name = '')
|
||||
{
|
||||
$info = [];
|
||||
if ($name != '') {
|
||||
// 从配置文件获取
|
||||
if (is_file(config('packet_path'). $name . '/info.php')) {
|
||||
$info = include config('packet_path'). $name . '/info.php';
|
||||
}
|
||||
}
|
||||
return $info;
|
||||
}
|
||||
|
||||
/**
|
||||
* 安装数据包
|
||||
* @param string $name 数据包名
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return bool
|
||||
*/
|
||||
public static function install($name = '')
|
||||
{
|
||||
$info = self::getInfoFromFile($name);
|
||||
|
||||
foreach ($info['tables'] as $table) {
|
||||
$sql_file = realpath(config('packet_path').$name."/{$table}.sql");
|
||||
if (file_exists($sql_file)) {
|
||||
if (isset($info['database_prefix']) && $info['database_prefix'] != '') {
|
||||
$sql_statement = Sql::getSqlFromFile($sql_file, false, [$info['database_prefix'] => config('database.prefix')]);
|
||||
} else {
|
||||
$sql_statement = Sql::getSqlFromFile($sql_file);
|
||||
}
|
||||
|
||||
if (!empty($sql_statement)) {
|
||||
foreach ($sql_statement as $value) {
|
||||
Db::execute($value);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return "【{$table}.sql】文件不存在";
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 卸载数据包
|
||||
* @param string $name 数据包名
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return bool
|
||||
* @throws \think\Exception
|
||||
* @throws \think\exception\PDOException
|
||||
*/
|
||||
public static function uninstall($name = '')
|
||||
{
|
||||
$info = self::getInfoFromFile($name);
|
||||
foreach ($info['tables'] as $table) {
|
||||
$sql = "DROP TABLE IF EXISTS `". config('database.prefix') ."{$table}`;";
|
||||
Db::execute($sql);
|
||||
self::where('name', $name)->delete();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,307 @@
|
|||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | 海豚PHP框架 [ DolphinPHP ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 版权所有 2016~2019 广东卓锐软件有限公司 [ http://www.zrthink.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网站: http://dolphinphp.com
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace app\admin\model;
|
||||
|
||||
use think\Model;
|
||||
|
||||
/**
|
||||
* 插件模型
|
||||
* @package app\admin\model
|
||||
*/
|
||||
class Plugin extends Model
|
||||
{
|
||||
// 设置当前模型对应的完整数据表名称
|
||||
protected $name = 'admin_plugin';
|
||||
|
||||
// 自动写入时间戳
|
||||
protected $autoWriteTimestamp = true;
|
||||
|
||||
// 写入时处理config
|
||||
public function setConfigAttr($value)
|
||||
{
|
||||
return !empty($value) ? json_encode($value) : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有插件信息
|
||||
* @param string $keyword 查找关键词
|
||||
* @param string $status 查找状态
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return array|bool
|
||||
*/
|
||||
public function getAll($keyword = '', $status = '')
|
||||
{
|
||||
$result = cache('plugin_all');
|
||||
if (!$result) {
|
||||
// 获取插件目录下的所有插件目录
|
||||
$dirs = array_map('basename', glob(config('plugin_path').'*', GLOB_ONLYDIR));
|
||||
if ($dirs === false || !file_exists(config('plugin_path'))) {
|
||||
$this->error = '插件目录不可读或者不存在';
|
||||
return false;
|
||||
}
|
||||
|
||||
// 读取数据库插件表
|
||||
$plugins = $this->order('sort asc,id desc')->column(true, 'name');
|
||||
|
||||
// 读取未安装的插件
|
||||
foreach ($dirs as $plugin) {
|
||||
if (!isset($plugins[$plugin])) {
|
||||
$plugins[$plugin]['name'] = $plugin;
|
||||
|
||||
// 获取插件类名
|
||||
$class = get_plugin_class($plugin);
|
||||
|
||||
// 插件类不存在则跳过实例化
|
||||
if (!class_exists($class)) {
|
||||
// 插件的入口文件不存在!
|
||||
$plugins[$plugin]['status'] = '-2';
|
||||
continue;
|
||||
}
|
||||
|
||||
// 实例化插件
|
||||
$obj = new $class;
|
||||
|
||||
// 插件插件信息缺失
|
||||
if (!isset($obj->info) || empty($obj->info)) {
|
||||
// 插件信息缺失!
|
||||
$plugins[$plugin]['status'] = '-3';
|
||||
continue;
|
||||
}
|
||||
|
||||
// 插件插件信息不完整
|
||||
if (!$this->checkInfo($obj->info)) {
|
||||
$plugins[$plugin]['status'] = '-4';
|
||||
continue;
|
||||
}
|
||||
|
||||
// 插件未安装
|
||||
$plugins[$plugin] = $obj->info;
|
||||
$plugins[$plugin]['status'] = '-1';
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// 数量统计
|
||||
$total = [
|
||||
'all' => count($plugins), // 所有插件数量
|
||||
'-2' => 0, // 错误插件数量
|
||||
'-1' => 0, // 未安装数量
|
||||
'0' => 0, // 未启用数量
|
||||
'1' => 0, // 已启用数量
|
||||
];
|
||||
|
||||
// 过滤查询结果和统计数量
|
||||
foreach ($plugins as $key => $value) {
|
||||
// 统计数量
|
||||
if (in_array($value['status'], ['-2', '-3', '-4'])) {
|
||||
// 已损坏数量
|
||||
$total['-2']++;
|
||||
} else {
|
||||
$total[(string)$value['status']]++;
|
||||
}
|
||||
|
||||
// 过滤查询
|
||||
if ($status != '') {
|
||||
if ($status == '-2') {
|
||||
// 过滤掉非已损坏的插件
|
||||
if (!in_array($value['status'], ['-2', '-3', '-4'])) {
|
||||
unset($plugins[$key]);
|
||||
continue;
|
||||
}
|
||||
} else if ($value['status'] != $status) {
|
||||
unset($plugins[$key]);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if ($keyword != '') {
|
||||
if (stristr($value['name'], $keyword) === false && (!isset($value['title']) || stristr($value['title'], $keyword) === false) && (!isset($value['author']) || stristr($value['author'], $keyword) === false)) {
|
||||
unset($plugins[$key]);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 处理状态及插件按钮
|
||||
foreach ($plugins as &$plugin) {
|
||||
switch ($plugin['status']) {
|
||||
case '-4': // 插件信息不完整
|
||||
$plugin['title'] = '插件信息不完整';
|
||||
$plugin['bg_color'] = 'danger';
|
||||
$plugin['status_class'] = 'text-danger';
|
||||
$plugin['status_info'] = '<i class="fa fa-times"></i> 已损坏';
|
||||
$plugin['actions'] = '<button class="btn btn-sm btn-noborder btn-danger" type="button" disabled>不可操作</button>';
|
||||
break;
|
||||
case '-3': // 插件信息缺失
|
||||
$plugin['title'] = '插件信息缺失';
|
||||
$plugin['bg_color'] = 'danger';
|
||||
$plugin['status_class'] = 'text-danger';
|
||||
$plugin['status_info'] = '<i class="fa fa-times"></i> 已损坏';
|
||||
$plugin['actions'] = '<button class="btn btn-sm btn-noborder btn-danger" type="button" disabled>不可操作</button>';
|
||||
break;
|
||||
case '-2': // 入口文件不存在
|
||||
$plugin['title'] = '入口文件不存在';
|
||||
$plugin['bg_color'] = 'danger';
|
||||
$plugin['status_class'] = 'text-danger';
|
||||
$plugin['status_info'] = '<i class="fa fa-times"></i> 已损坏';
|
||||
$plugin['actions'] = '<button class="btn btn-sm btn-noborder btn-danger" type="button" disabled>不可操作</button>';
|
||||
break;
|
||||
case '-1': // 未安装
|
||||
$plugin['bg_color'] = 'info';
|
||||
$plugin['actions'] = '<a class="btn btn-sm btn-noborder btn-success ajax-get confirm" href="'.url('install', ['name' => $plugin['name']]).'">安装</a>';
|
||||
$plugin['status_class'] = 'text-info';
|
||||
$plugin['status_info'] = '<i class="fa fa-fw fa-th-large"></i> 未安装';
|
||||
break;
|
||||
case '0': // 禁用
|
||||
$plugin['bg_color'] = 'warning';
|
||||
$plugin['actions'] = '<a class="btn btn-sm btn-noborder btn-success ajax-get confirm" href="'.url('enable', ['ids' => $plugin['id']]).'">启用</a> ';
|
||||
$plugin['actions'] .= '<a class="btn btn-sm btn-noborder btn-danger ajax-get confirm" data-tips="如果包括数据库,将同时删除数据库!" href="'.url('uninstall', ['name' => $plugin['name']]).'">卸载</a> ';
|
||||
if (isset($plugin['config']) && $plugin['config'] != '') {
|
||||
$plugin['actions'] .= '<a class="btn btn-sm btn-noborder btn-info" href="'.url('config', ['name' => $plugin['name']]).'">设置</a> ';
|
||||
}
|
||||
if ($plugin['admin'] != '0') {
|
||||
$plugin['actions'] .= '<a class="btn btn-sm btn-noborder btn-primary" href="'.url('manage', ['name' => $plugin['name']]).'">管理</a> ';
|
||||
}
|
||||
$plugin['status_class'] = 'text-warning';
|
||||
$plugin['status_info'] = '<i class="fa fa-ban"></i> 已禁用';
|
||||
break;
|
||||
case '1': // 启用
|
||||
$plugin['bg_color'] = 'success';
|
||||
$plugin['actions'] = '<a class="btn btn-sm btn-noborder btn-warning ajax-get confirm" href="'.url('disable', ['ids' => $plugin['id']]).'">禁用</a> ';
|
||||
$plugin['actions'] .= '<a class="btn btn-sm btn-noborder btn-danger ajax-get confirm" data-tips="如果包括数据库,将同时删除数据库!" href="'.url('uninstall', ['name' => $plugin['name']]).'">卸载</a> ';
|
||||
if (isset($plugin['config']) && $plugin['config'] != '') {
|
||||
$plugin['actions'] .= '<a class="btn btn-sm btn-noborder btn-info" href="'.url('config', ['name' => $plugin['name']]).'">设置</a> ';
|
||||
}
|
||||
if ($plugin['admin'] != '0') {
|
||||
$plugin['actions'] .= '<a class="btn btn-sm btn-noborder btn-primary" href="'.url('manage', ['name' => $plugin['name']]).'">管理</a> ';
|
||||
}
|
||||
$plugin['status_class'] = 'text-success';
|
||||
$plugin['status_info'] = '<i class="fa fa-check"></i> 已启用';
|
||||
break;
|
||||
default: // 未知
|
||||
$plugin['title'] = '未知';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$result = ['total' => $total, 'plugins' => $plugins];
|
||||
// 非开发模式,缓存数据
|
||||
if (config('develop_mode') == 0) {
|
||||
cache('plugin_all', $result);
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查插件插件信息是否完整
|
||||
* @param string $info 插件插件信息
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return bool
|
||||
*/
|
||||
private function checkInfo($info = '')
|
||||
{
|
||||
$default_item = ['name','title','author','version'];
|
||||
foreach ($default_item as $item) {
|
||||
if (!isset($info[$item]) || $info[$item] == '') {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取插件配置
|
||||
* @param string $name 插件名称
|
||||
* @param string $item 指定返回的插件配置项
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return array|mixed
|
||||
*/
|
||||
public function getConfig($name = '', $item = '')
|
||||
{
|
||||
$config = cache('plugin_config_'.$name);
|
||||
if (!$config) {
|
||||
$config = $this->where('name', $name)->value('config');
|
||||
if (!$config) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$config = json_decode($config, true);
|
||||
// 非开发模式,缓存数据
|
||||
if (config('develop_mode') == 0) {
|
||||
cache('plugin_config_'.$name, $config);
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($item)) {
|
||||
$items = explode(',', $item);
|
||||
if (count($items) == 1) {
|
||||
return isset($config[$item]) ? $config[$item] : '';
|
||||
}
|
||||
|
||||
$result = [];
|
||||
foreach ($items as $item) {
|
||||
$result[$item] = isset($config[$item]) ? $config[$item] : '';
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
return $config;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置插件配置
|
||||
* @param string $name 插件名.配置名
|
||||
* @param string $value 配置值
|
||||
* @author caiweiming <314013107@qq.com>
|
||||
* @return bool
|
||||
*/
|
||||
public function setConfig($name = '', $value = '')
|
||||
{
|
||||
$item = '';
|
||||
if (strpos($name, '.')) {
|
||||
list($name, $item) = explode('.', $name);
|
||||
}
|
||||
|
||||
// 获取缓存
|
||||
$config = cache('plugin_config_'.$name);
|
||||
|
||||
if (!$config) {
|
||||
$config = $this->where('name', $name)->value('config');
|
||||
if (!$config) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$config = json_decode($config, true);
|
||||
}
|
||||
|
||||
if ($item === '') {
|
||||
// 批量更新
|
||||
if (!is_array($value) || empty($value)) {
|
||||
// 值的格式错误,必须为数组
|
||||
return false;
|
||||
}
|
||||
|
||||
$config = array_merge($config, $value);
|
||||
} else {
|
||||
// 更新单个值
|
||||
$config[$item] = $value;
|
||||
}
|
||||
|
||||
if (false === $this->where('name', $name)->setField('config', json_encode($config))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 非开发模式,缓存数据
|
||||
if (config('develop_mode') == 0) {
|
||||
cache('plugin_config_'.$name, $config);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | 海豚PHP框架 [ DolphinPHP ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 版权所有 2016~2019 广东卓锐软件有限公司 [ http://www.zrthink.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网站: http://dolphinphp.com
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace app\admin\validate;
|
||||
|
||||
use think\Validate;
|
||||
|
||||
/**
|
||||
* 行为验证器
|
||||
* @package app\admin\validate
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
*/
|
||||
class Action extends Validate
|
||||
{
|
||||
//定义验证规则
|
||||
protected $rule = [
|
||||
'module|所属模块' => 'require',
|
||||
'name|行为标识' => 'require|regex:^[a-zA-Z]\w{0,39}$|unique:admin_action,name^module',
|
||||
'title|行为名称' => 'require|length:1,80',
|
||||
'remark|行为描述' => 'require|length:1,128'
|
||||
];
|
||||
|
||||
//定义验证提示
|
||||
protected $message = [
|
||||
'name.regex' => '行为标识由字母和下划线组成',
|
||||
];
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | 海豚PHP框架 [ DolphinPHP ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 版权所有 2016~2019 广东卓锐软件有限公司 [ http://www.zrthink.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网站: http://dolphinphp.com
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace app\admin\validate;
|
||||
|
||||
use think\Validate;
|
||||
|
||||
/**
|
||||
* 配置验证器
|
||||
* @package app\admin\validate
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
*/
|
||||
class Config extends Validate
|
||||
{
|
||||
// 定义验证规则
|
||||
protected $rule = [
|
||||
'group|配置分组' => 'require',
|
||||
'type|配置类型' => 'require',
|
||||
'name|配置名称' => 'require|regex:^[a-zA-Z]\w{0,39}$|unique:admin_config',
|
||||
'title|配置标题' => 'require',
|
||||
];
|
||||
|
||||
// 定义验证提示
|
||||
protected $message = [
|
||||
'name.regex' => '配置名称由字母和下划线组成',
|
||||
];
|
||||
|
||||
// 定义场景,供快捷编辑时验证
|
||||
protected $scene = [
|
||||
'name' => ['name'],
|
||||
'title' => ['title'],
|
||||
];
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | 海豚PHP框架 [ DolphinPHP ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 版权所有 2016~2019 广东卓锐软件有限公司 [ http://www.zrthink.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网站: http://dolphinphp.com
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace app\admin\validate;
|
||||
|
||||
use think\Validate;
|
||||
|
||||
/**
|
||||
* 钩子验证器
|
||||
* @package app\admin\validate
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
*/
|
||||
class Hook extends Validate
|
||||
{
|
||||
//定义验证规则
|
||||
protected $rule = [
|
||||
'name|钩子名称' => 'require|regex:^[a-zA-Z]\w{0,39}$|unique:admin_hook'
|
||||
];
|
||||
|
||||
//定义验证提示
|
||||
protected $message = [
|
||||
'name.regex' => '钩子名称由字母和下划线组成',
|
||||
];
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | 海豚PHP框架 [ DolphinPHP ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 版权所有 2016~2019 广东卓锐软件有限公司 [ http://www.zrthink.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网站: http://dolphinphp.com
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace app\admin\validate;
|
||||
|
||||
use think\Validate;
|
||||
|
||||
/**
|
||||
* 节点验证器
|
||||
* @package app\admin\validate
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
*/
|
||||
class Menu extends Validate
|
||||
{
|
||||
//定义验证规则
|
||||
protected $rule = [
|
||||
'module|所属模块' => 'require',
|
||||
'pid|所属节点' => 'require',
|
||||
'title|节点标题' => 'require',
|
||||
];
|
||||
|
||||
//定义验证提示
|
||||
protected $message = [
|
||||
'module.require' => '请选择所属模块',
|
||||
'pid.require' => '请选择所属节点',
|
||||
];
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | 海豚PHP框架 [ DolphinPHP ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 版权所有 2016~2019 广东卓锐软件有限公司 [ http://www.zrthink.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网站: http://dolphinphp.com
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace app\admin\validate;
|
||||
|
||||
use think\Validate;
|
||||
|
||||
/**
|
||||
* 插件验证器
|
||||
* @package app\admin\validate
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
*/
|
||||
class Plugin extends Validate
|
||||
{
|
||||
//定义验证规则
|
||||
protected $rule = [
|
||||
'name|插件名称' => 'require|unique:admin_plugin',
|
||||
'title|插件标题' => 'require',
|
||||
];
|
||||
}
|
|
@ -0,0 +1,77 @@
|
|||
<!DOCTYPE html>
|
||||
<!--[if IE 9]> <html class="ie9 no-focus" lang="zh"> <![endif]-->
|
||||
<!--[if gt IE 9]><!--> <html class="no-focus" lang="zh"> <!--<![endif]-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
|
||||
<title>跳转提示 | {:config('web_site_title')} - DolphinPHP</title>
|
||||
|
||||
<meta name="robots" content="noindex, nofollow">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1.0">
|
||||
|
||||
<!-- Icons -->
|
||||
<!-- The following icons can be replaced with your own, they are used by desktop and mobile browsers -->
|
||||
<link rel="shortcut icon" href="__STATIC__/img/favicons/favicon.png">
|
||||
<!-- END Icons -->
|
||||
|
||||
<!-- Stylesheets -->
|
||||
<!-- Bootstrap and OneUI CSS framework -->
|
||||
<link rel="stylesheet" href="__ADMIN_CSS__/bootstrap.min.css">
|
||||
<link rel="stylesheet" href="__ADMIN_CSS__/oneui.css">
|
||||
<link rel="stylesheet" href="__ADMIN_CSS__/dolphin.css">
|
||||
<!-- END Stylesheets -->
|
||||
</head>
|
||||
<body>
|
||||
<!-- Error Content -->
|
||||
<div class="content bg-white text-center pulldown overflow-hidden">
|
||||
<div class="row">
|
||||
<div class="col-sm-6 col-sm-offset-3">
|
||||
<!-- Error Titles -->
|
||||
<h1 class="font-w300 {$code? 'text-success' : 'text-city'} push-10 animated flipInX"><i class="fa fa-{$code? 'check' : 'times'}-circle"></i> <?php echo(strip_tags($msg));?></h1>
|
||||
<p class="font-w300 push-20 animated fadeInUp">页面自动 <a id="href" href="<?php echo($url);?>">跳转</a> 等待时间: <b id="wait"><?php echo($wait);?></b>秒</p>
|
||||
<div class="push-50">
|
||||
<a class="btn btn-minw btn-rounded btn-success" href="<?php echo($url);?>"><i class="fa fa-external-link-square"></i> 立即跳转</a>
|
||||
<button class="btn btn-minw btn-rounded btn-warning" type="button" onclick="stop()"><i class="fa fa-ban"></i> 禁止跳转</button>
|
||||
<a class="btn btn-minw btn-rounded btn-default" href="{$Request.baseFile}"><i class="fa fa-home"></i> 返回首页</a>
|
||||
</div>
|
||||
<!-- END Error Titles -->
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- END Error Content -->
|
||||
|
||||
<!-- Error Footer -->
|
||||
<div class="content pulldown text-muted text-center">
|
||||
极简 · 极速 · 极致<br>
|
||||
|
||||
</div>
|
||||
<!-- END Error Footer -->
|
||||
|
||||
<script type="text/javascript">
|
||||
(function(){
|
||||
let wait = document.getElementById('wait'),
|
||||
href = document.getElementById('href').href,
|
||||
pop = '{$Request.param._pop}'; //获取窗口索引
|
||||
|
||||
let interval = setInterval(function(){
|
||||
let time = --wait.innerHTML;
|
||||
if(time <= 0) {
|
||||
if (pop === '1' && parent.layer !== undefined) {
|
||||
let index = parent.layer.getFrameIndex(window.name);
|
||||
parent.layer.close(index);
|
||||
} else {
|
||||
location.href = href;
|
||||
}
|
||||
clearInterval(interval);
|
||||
}
|
||||
}, 1000);
|
||||
|
||||
// 禁止跳转
|
||||
window.stop = function (){
|
||||
clearInterval(interval);
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,74 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="zh-cn">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>页面提示 - {:config('web_site_title')}</title>
|
||||
<link rel=stylesheet type=text/css href="https://wx.gtimg.com/pay/css/common/common.css?v=20170117">
|
||||
<link rel=stylesheet type=text/css href="https://wx.gtimg.com/pay/css/error/error.css?v=20151125">
|
||||
<script src="https://wx.gtimg.com/third/jquery/jquery-1.7.min.js"></script>
|
||||
</head>
|
||||
<body class="browser-tips no-nav no-topbar">
|
||||
<div class="container wrap">
|
||||
<div class="container-bd">
|
||||
<div class="page-msg mini">
|
||||
<div class="inner">
|
||||
<div class="msg-ico"><i class="ico-msg-s warn"></i></div>
|
||||
<div class="msg-cnt">
|
||||
<p>温馨提示:在IE浏览器环境下浏览本系统体验不够友好,建议您使用下方的浏览器访问本系统。</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="browser-list">
|
||||
<a class="browser-item chrome" href="http://xiazai.sogou.com/detail/34/0/6262355089742005676.html?uID=04583CB73B70900A0000000057318502&w=2295" target="_blank">
|
||||
<i class="icon-browser"></i>
|
||||
<p class="browser-name">Chrome浏览器</p>
|
||||
</a>
|
||||
<a class="browser-item qq" href="http://browser.qq.com/" target="_blank">
|
||||
<i class="icon-browser"></i>
|
||||
<p class="browser-name">QQ浏览器</p>
|
||||
</a>
|
||||
<a class="browser-item sogou" href="http://ie.sogou.com/" target="_blank">
|
||||
<i class="icon-browser"></i>
|
||||
<p class="browser-name">搜狗浏览器</p>
|
||||
</a>
|
||||
<a class="browser-item firefox" href="http://www.firefox.com.cn/?igfox" target="_blank">
|
||||
<i class="icon-browser"></i>
|
||||
<p class="browser-name">Firefox浏览器</p>
|
||||
</a>
|
||||
</div>
|
||||
<div class="browser-more">
|
||||
<div class="browser-text">如果你正在使用的是双核浏览器,比如QQ浏览器、搜狗浏览器、猎豹浏览器、世界之窗浏览器、傲游浏览器、360浏览器等,可以使用浏览器的极速模式来继续访问本系统。<a id="access" href="javascript:void(0);">查看详情</a>
|
||||
</div>
|
||||
<div id="tips" class="browser-step" style="display: block;">
|
||||
<ul>
|
||||
<li>方法一,点击浏览器顶部地址栏右侧的浏览器兼容模式图标,<img alt="" src="https://wx.gtimg.com/pay/img/error/ie_s.png">或<img alt="" src="https://wx.gtimg.com/pay/img/error/ie_mode.png">,切换到极速模式
|
||||
<p class="demo"><img alt="" src="https://wx.gtimg.com/pay/img/error/pic_ie01.png"></p>
|
||||
</li>
|
||||
<li>方法二,在当前页面中,点击鼠标右键,选择“切换到极速模式”
|
||||
<p class="demo"><img alt="" src="https://wx.gtimg.com/pay/img/error/pic_ie02.png"></p>
|
||||
</li>
|
||||
<li>方法三,在浏览器菜单栏中选择工具选项,打开“兼容性视图设置”,把设置框底部的“在兼容性视图显示”三个勾选框去掉
|
||||
<p class="demo"><img alt="" src="https://wx.gtimg.com/pay/img/error/pic_ie03.png"></p></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
(function(){
|
||||
var tips = document.getElementById("tips");
|
||||
var access = document.getElementById("access");
|
||||
var isShow = true;
|
||||
access.onclick = function(){
|
||||
if(!isShow){
|
||||
tips.style.display = "block";
|
||||
isShow = true;
|
||||
}else{
|
||||
tips.style.display = "none";
|
||||
isShow = false;
|
||||
}
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,31 @@
|
|||
{extend name="layout" /}
|
||||
|
||||
{block name="page-header"}{/block}
|
||||
|
||||
{block name="content"}
|
||||
{notempty name="default_pass"}
|
||||
<div class="alert alert-danger alert-dismissable">
|
||||
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
|
||||
<h3 class="font-w300 push-15">安全提示</h3>
|
||||
<p>超级管理员默认密码未修改,建议马上 <a class="alert-link link-effect" href="{:url('user/index/edit', ['id' => 1])}">修改</a>。</p>
|
||||
</div>
|
||||
{/notempty}
|
||||
{// 后台首页钩子}
|
||||
<div class="row">
|
||||
{:hook('admin_index')}
|
||||
</div>
|
||||
{/block}
|
||||
|
||||
{block name="script"}
|
||||
<script>
|
||||
$(document).ready(function () {
|
||||
$.ajax({
|
||||
url: '{:url("checkUpdate")}',
|
||||
type: 'GET'
|
||||
}).done(function(data) {
|
||||
$('#product-auth').html(data.auth);
|
||||
$('#product-update').html($('#product-update').text() + ' ' + data.update);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{/block}
|
|
@ -0,0 +1,559 @@
|
|||
<!DOCTYPE html>
|
||||
<!--[if IE 9]> <html class="ie9 no-focus" lang="zh"> <![endif]-->
|
||||
<!--[if gt IE 9]><!--> <html class="no-focus" lang="zh"> <!--<![endif]-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
|
||||
{block name="page-title"}<title>{$page_title|default='后台'} | {:config('web_site_title')} - DolphinPHP</title>{/block}
|
||||
|
||||
<meta name="description" content="{:config('web_site_description')}">
|
||||
<meta name="author" content="caiweiming">
|
||||
<meta name="robots" content="noindex, nofollow">
|
||||
<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,user-scalable=0">
|
||||
|
||||
<!-- Icons -->
|
||||
<!-- The following icons can be replaced with your own, they are used by desktop and mobile browsers -->
|
||||
<link rel="shortcut icon" href="__ADMIN_IMG__/favicons/favicon.ico">
|
||||
|
||||
<!--<link rel="icon" type="image/png" href="__ADMIN_IMG__/favicons/favicon-16x16.png" sizes="16x16">
|
||||
<link rel="icon" type="image/png" href="__ADMIN_IMG__/favicons/favicon-32x32.png" sizes="32x32">
|
||||
<link rel="icon" type="image/png" href="__ADMIN_IMG__/favicons/favicon-96x96.png" sizes="96x96">
|
||||
<link rel="icon" type="image/png" href="__ADMIN_IMG__/favicons/favicon-160x160.png" sizes="160x160">
|
||||
<link rel="icon" type="image/png" href="__ADMIN_IMG__/favicons/favicon-192x192.png" sizes="192x192">
|
||||
|
||||
<link rel="apple-touch-icon" sizes="57x57" href="__ADMIN_IMG__/favicons/apple-touch-icon-57x57.png">
|
||||
<link rel="apple-touch-icon" sizes="60x60" href="__ADMIN_IMG__/favicons/apple-touch-icon-60x60.png">
|
||||
<link rel="apple-touch-icon" sizes="72x72" href="__ADMIN_IMG__/favicons/apple-touch-icon-72x72.png">
|
||||
<link rel="apple-touch-icon" sizes="76x76" href="__ADMIN_IMG__/favicons/apple-touch-icon-76x76.png">
|
||||
<link rel="apple-touch-icon" sizes="114x114" href="__ADMIN_IMG__/favicons/apple-touch-icon-114x114.png">
|
||||
<link rel="apple-touch-icon" sizes="120x120" href="__ADMIN_IMG__/favicons/apple-touch-icon-120x120.png">
|
||||
<link rel="apple-touch-icon" sizes="144x144" href="__ADMIN_IMG__/favicons/apple-touch-icon-144x144.png">
|
||||
<link rel="apple-touch-icon" sizes="152x152" href="__ADMIN_IMG__/favicons/apple-touch-icon-152x152.png">
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="__ADMIN_IMG__/favicons/apple-touch-icon-180x180.png">-->
|
||||
<!-- END Icons -->
|
||||
|
||||
<!-- Stylesheets -->
|
||||
<!-- Page JS Plugins CSS -->
|
||||
{notempty name="_css_files"}
|
||||
{eq name="Think.config.minify_status" value="1"}
|
||||
<link rel="stylesheet" href="{:minify('group', $_css_files)}">
|
||||
{else/}
|
||||
{volist name="_css_files" id="css"}
|
||||
{:load_assets($css)}
|
||||
{/volist}
|
||||
{/eq}
|
||||
{/notempty}
|
||||
|
||||
{notempty name="extend_css_list"}
|
||||
{volist name="extend_css_list" id="vo"}
|
||||
{volist name="vo" id="v"}
|
||||
<link rel="stylesheet" href="{$v}?v={:config('asset_version')}">
|
||||
{/volist}
|
||||
{/volist}
|
||||
{/notempty}
|
||||
|
||||
{notempty name="_icons"}
|
||||
{volist name="_icons" id="icon"}
|
||||
<link rel="stylesheet" href="{$icon.url}">
|
||||
{/volist}
|
||||
{/notempty}
|
||||
|
||||
{block name="plugins-css"}{/block}
|
||||
|
||||
<!-- Bootstrap and OneUI CSS framework -->
|
||||
{eq name="Think.config.minify_status" value="1"}
|
||||
<link rel="stylesheet" id="css-main" href="{:minify('group', 'libs_css,core_css')}">
|
||||
{else/}
|
||||
<link rel="stylesheet" href="__LIBS__/sweetalert/sweetalert.min.css?v={:config('asset_version')}">
|
||||
<link rel="stylesheet" href="__LIBS__/magnific-popup/magnific-popup.min.css?v={:config('asset_version')}">
|
||||
<link rel="stylesheet" href="__ADMIN_CSS__/bootstrap.min.css?v={:config('asset_version')}">
|
||||
<link rel="stylesheet" href="__ADMIN_CSS__/oneui.css?v={:config('asset_version')}">
|
||||
<link rel="stylesheet" href="__ADMIN_CSS__/dolphin.css?v={:config('asset_version')}" id="css-main">
|
||||
<link rel="stylesheet" href="__LIBS__/viewer/viewer.min.css?v={:config('asset_version')}">
|
||||
{/eq}
|
||||
<link rel="stylesheet" id="css-theme" href="__ADMIN_CSS__/themes/{:config('system_color')}.min.css?v={:config('asset_version')}">
|
||||
|
||||
<!--页面css-->
|
||||
{block name="style"}{/block}
|
||||
{notempty name="_pop"}
|
||||
<style>
|
||||
#page-container.sidebar-l.sidebar-o {
|
||||
padding-left: 0;
|
||||
}
|
||||
.header-navbar-fixed #main-container {
|
||||
padding-top: 0;
|
||||
}
|
||||
</style>
|
||||
{/notempty}
|
||||
<!-- END Stylesheets -->
|
||||
|
||||
<!--插件css钩子-->
|
||||
{:hook('page_plugin_css')}
|
||||
|
||||
<!--自定义css-->
|
||||
<link rel="stylesheet" href="__ADMIN_CSS__/custom.css?v={:config('asset_version')}">
|
||||
<script>
|
||||
// url
|
||||
var dolphin = {
|
||||
'top_menu_url': '{:url("admin/ajax/getSidebarMenu")}',
|
||||
'theme_url': '{:url("admin/ajax/setTheme")}',
|
||||
'jcrop_upload_url': '{$jcrop_upload_url ? $jcrop_upload_url : url("admin/attachment/upload", ["dir" => "images", "from" => "jcrop", "module" => request()->module()])}',
|
||||
'editormd_upload_url': '{$editormd_upload_url ? $editormd_upload_url : url("admin/attachment/upload", ["dir" => "images", "from" => "editormd", "module" => request()->module()])}',
|
||||
'editormd_mudule_path': '__LIBS__/editormd/lib/',
|
||||
'ueditor_upload_url': '{$ueditor_upload_url ? $ueditor_upload_url : url("admin/attachment/upload", ["dir" => "images", "from" => "ueditor", "module" => request()->module()])}',
|
||||
'wangeditor_upload_url': '{$wangeditor_upload_url ? $wangeditor_upload_url : url("admin/attachment/upload", ["dir" => "images", "from" => "wangeditor", "module" => request()->module()])}',
|
||||
'wangeditor_emotions': "__LIBS__/wang-editor/emotions.data",
|
||||
'ckeditor_img_upload_url': '{$ckeditor_img_upload_url ? $ckeditor_img_upload_url : url("admin/attachment/upload", ["dir" => "images", "from" => "ckeditor", "module" => request()->module()])}',
|
||||
'WebUploader_swf': '__LIBS__/webuploader/Uploader.swf',
|
||||
'file_upload_url': '{$file_upload_url ? $file_upload_url : url("admin/attachment/upload", ["dir" => "files", "module" => request()->module()])}',
|
||||
'image_upload_url': '{$image_upload_url ? $image_upload_url : url("admin/attachment/upload", ["dir" => "images", "module" => request()->module()])}',
|
||||
'upload_check_url': '{$upload_check_url ? $upload_check_url : url("admin/ajax/check")}',
|
||||
'get_level_data': '{:url("admin/ajax/getLevelData")}',
|
||||
'quick_edit_url': '{$quick_edit_url ? $quick_edit_url : url("quickEdit")}',
|
||||
'aside_edit_url': '{$aside_edit_url ? $aside_edit_url : url("admin/system/quickEdit")}',
|
||||
'triggers': {:json_encode(isset($field_triggers) ? $field_triggers : [])}, // 触发器集合
|
||||
'field_hide': '{$field_hide|default=""}', // 需要隐藏的字段
|
||||
'field_values': '{$field_values|default=""}',
|
||||
'validate': '{$validate|default=""}', // 验证器
|
||||
'validate_fields': '{$validate_fields|default=""}', // 验证字段
|
||||
'search_field': '{:input("param.search_field", "")}', // 搜索字段
|
||||
// 字段过滤
|
||||
'_filter': '{$Request.param._filter ? $Request.param._filter : (isset($_filter) ? $_filter : "")}',
|
||||
'_filter_content': '{$Request.param._filter_content == '' ? (isset($_filter_content) ? $_filter_content : "") : $Request.param._filter_content}',
|
||||
'_field_display': '{$Request.param._field_display ? $Request.param._field_display : (isset($_field_display) ? $_field_display : "")}',
|
||||
'_field_clear': {:json_encode(isset($field_clear) ? $field_clear : [])},
|
||||
'get_filter_list': '{:url("admin/ajax/getFilterList")}',
|
||||
'curr_url': '{:url("", $Request.route)}',
|
||||
'curr_params': {:json_encode($Request.param)},
|
||||
'layer': {:json_encode(config("zbuilder.pop"))}
|
||||
};
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<!-- Page Container -->
|
||||
<div id="page-container" class="sidebar-l sidebar-o side-scroll header-navbar-fixed {empty name="_pop"}{$_COOKIE['sidebarMini'] ?= 'sidebar-mini'}{/empty}">
|
||||
<!-- Side Overlay-->
|
||||
{empty name="_pop"}
|
||||
{block name="aside"}
|
||||
<aside id="side-overlay">
|
||||
<!-- Side Overlay Scroll Container -->
|
||||
<div id="side-overlay-scroll">
|
||||
<!-- Side Header -->
|
||||
<div class="side-header side-content">
|
||||
<!-- Layout API, functionality initialized in App() -> uiLayoutApi() -->
|
||||
<button class="btn btn-default pull-right" type="button" data-toggle="layout" data-action="side_overlay_close">
|
||||
<i class="fa fa-times"></i>
|
||||
</button>
|
||||
<span>
|
||||
<img class="img-avatar img-avatar32" src="{$Think.session.user_auth.uid|get_avatar}" alt="">
|
||||
<span class="font-w600 push-10-l">{:session('user_auth.username')}</span>
|
||||
</span>
|
||||
</div>
|
||||
<!-- END Side Header -->
|
||||
<!--侧栏-->
|
||||
{include file="../application/common/builder/aside/layout.html" /}
|
||||
</div>
|
||||
<!-- END Side Overlay Scroll Container -->
|
||||
</aside>
|
||||
{/block}
|
||||
{/empty}
|
||||
<!-- END Side Overlay -->
|
||||
|
||||
<!-- Sidebar -->
|
||||
{empty name="_pop"}
|
||||
{block name="sidebar"}
|
||||
<nav id="sidebar">
|
||||
<!-- Sidebar Scroll Container -->
|
||||
<div id="sidebar-scroll">
|
||||
<!-- Sidebar Content -->
|
||||
<!-- Adding .sidebar-mini-hide to an element will hide it when the sidebar is in mini mode -->
|
||||
<div class="sidebar-content">
|
||||
<!-- Side Header -->
|
||||
<div class="side-header side-content bg-white-op dolphin-header">
|
||||
<!-- Layout API, functionality initialized in App() -> uiLayoutApi() -->
|
||||
<button class="btn btn-link text-gray pull-right hidden-md hidden-lg" type="button" data-toggle="layout" data-action="sidebar_close">
|
||||
<i class="fa fa-times"></i>
|
||||
</button>
|
||||
<!-- Themes functionality initialized in App() -> uiHandleTheme() -->
|
||||
<div class="btn-group pull-right">
|
||||
<button class="btn btn-link text-gray dropdown-toggle" data-toggle="dropdown" type="button">
|
||||
<i class="si si-drop"></i>
|
||||
</button>
|
||||
<ul class="dropdown-menu dropdown-menu-right font-s13 sidebar-mini-hide">
|
||||
<li {$system_color == 'modern' ?= 'class="active"'}>
|
||||
<a data-toggle="theme" data-theme="modern" data-css="__ADMIN_CSS__/themes/modern.min.css" tabindex="-1" href="javascript:void(0)">
|
||||
<i class="fa fa-circle text-modern pull-right"></i> <span class="font-w600">Modern</span>
|
||||
</a>
|
||||
</li>
|
||||
<li {$system_color == 'amethyst' ?= 'class="active"'}>
|
||||
<a data-toggle="theme" data-theme="amethyst" data-css="__ADMIN_CSS__/themes/amethyst.min.css" tabindex="-1" href="javascript:void(0)">
|
||||
<i class="fa fa-circle text-amethyst pull-right"></i> <span class="font-w600">Amethyst</span>
|
||||
</a>
|
||||
</li>
|
||||
<li {$system_color == 'city' ?= 'class="active"'}>
|
||||
<a data-toggle="theme" data-theme="city" data-css="__ADMIN_CSS__/themes/city.min.css" tabindex="-1" href="javascript:void(0)">
|
||||
<i class="fa fa-circle text-city pull-right"></i> <span class="font-w600">City</span>
|
||||
</a>
|
||||
</li>
|
||||
<li {$system_color == 'flat' ?= 'class="active"'}>
|
||||
<a data-toggle="theme" data-theme="flat" data-css="__ADMIN_CSS__/themes/flat.min.css" tabindex="-1" href="javascript:void(0)">
|
||||
<i class="fa fa-circle text-flat pull-right"></i> <span class="font-w600">Flat</span>
|
||||
</a>
|
||||
</li>
|
||||
<li {$system_color == 'smooth' ?= 'class="active"'}>
|
||||
<a data-toggle="theme" data-theme="smooth" data-css="__ADMIN_CSS__/themes/smooth.min.css" tabindex="-1" href="javascript:void(0)">
|
||||
<i class="fa fa-circle text-smooth pull-right"></i> <span class="font-w600">Smooth</span>
|
||||
</a>
|
||||
</li>
|
||||
<li {$system_color == 'default' ?= 'class="active"'}>
|
||||
<a data-toggle="theme" data-theme="default" tabindex="-1" href="javascript:void(0)">
|
||||
<i class="fa fa-circle text-default pull-right"></i> <span class="font-w600">Default</span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<a class="h5 text-white" href="{:url('admin/index/index')}">
|
||||
{notempty name="Think.config.web_site_logo"}
|
||||
<img style="margin-left: 40px" src="{$Think.config.web_site_logo|get_file_path}" class="logo" alt="{$Think.config.web_site_title|default='Dolphin PHP'}">
|
||||
{else/}
|
||||
<!-- <img src="{$Think.config.public_static_path}admin/img/logo.png" class="logo" alt="Dolphin PHP">-->
|
||||
{/notempty}
|
||||
|
||||
{notempty name="Think.config.web_site_logo_text"}
|
||||
<img src="{$Think.config.web_site_logo_text|get_file_path}" class="logo-text sidebar-mini-hide" alt="{$Think.config.web_site_title|default='Dolphin PHP'}">
|
||||
{else/}
|
||||
<!--<img src="{$Think.config.public_static_path}admin/img/logo-text.png" class="logo-text sidebar-mini-hide" alt="Dolphin PHP">-->
|
||||
{/notempty}
|
||||
</a>
|
||||
</div>
|
||||
<!-- END Side Header -->
|
||||
|
||||
<!-- Side Content -->
|
||||
<div class="side-content" id="sidebar-menu">
|
||||
{notempty name="_sidebar_menus"}
|
||||
<ul class="nav-main" id="nav-{$_location[0]['id']}">
|
||||
{volist name="_sidebar_menus" id="menu"}
|
||||
<li {$menu['id'] == $_location[1]["id"]?='class="open"'}>
|
||||
{notempty name="menu.url_value"}
|
||||
<a {if($menu['id'] == $_location[1]["id"])}class="active"{/if} href="{$menu.url_value}" target="{$menu.url_target}"><i class="{$menu.icon}"></i><span class="sidebar-mini-hide">{$menu.title}</span></a>
|
||||
{else/}
|
||||
<a class="nav-submenu" data-toggle="nav-submenu" href="javascript:void(0);"><i class="{$menu.icon}"></i><span class="sidebar-mini-hide">{$menu.title}</span></a>
|
||||
{notempty name="menu['child']"}
|
||||
<ul>
|
||||
{volist name="menu['child']" id="submenu"}
|
||||
<li>
|
||||
<a {if(isset($_location[2]) && $submenu['id'] == $_location[2]["id"])}class="active"{/if} href="{$submenu.url_value}" target="{$submenu.url_target}"><i class="{$submenu.icon}"></i>{$submenu.title}</a>
|
||||
</li>
|
||||
{/volist}
|
||||
</ul>
|
||||
{/notempty}
|
||||
{/notempty}
|
||||
</li>
|
||||
{/volist}
|
||||
</ul>
|
||||
{/notempty}
|
||||
</div>
|
||||
<!-- END Side Content -->
|
||||
</div>
|
||||
<!-- Sidebar Content -->
|
||||
</div>
|
||||
<!-- END Sidebar Scroll Container -->
|
||||
</nav>
|
||||
{/block}
|
||||
{/empty}
|
||||
<!-- END Sidebar -->
|
||||
|
||||
<!-- Header -->
|
||||
{empty name="_pop"}
|
||||
{block name="header"}
|
||||
<header id="header-navbar" class="content-mini content-mini-full">
|
||||
<!-- Header Navigation Right -->
|
||||
<ul class="nav-header pull-right">
|
||||
<li>
|
||||
<div class="btn-group">
|
||||
<button class="btn btn-default btn-image dropdown-toggle" data-toggle="dropdown" type="button">
|
||||
<img src="{$Think.session.user_auth.uid|get_avatar}" alt="{:session('user_auth.username')}">
|
||||
<span class="caret"></span>
|
||||
{notempty name="_message"}
|
||||
{gt name="_message" value="0"}
|
||||
<i class="fa fa-circle text-danger notice-circle"></i>
|
||||
{/gt}
|
||||
{/notempty}
|
||||
</button>
|
||||
<ul class="dropdown-menu dropdown-menu-right">
|
||||
<li class="dropdown-header">{:session('user_auth.username')} ({:session('user_auth.role_name')})</li>
|
||||
<li>
|
||||
<a tabindex="-1" href="{:url('admin/index/profile')}">
|
||||
<i class="si si-settings pull-right"></i>个人设置
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a tabindex="-1" href="javascript:void(0);" id="js-change-role">
|
||||
<i class="si si-users pull-right"></i>切换角色
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a tabindex="-1" href="{:url('admin/message/index')}">
|
||||
<i class="si si-envelope-open pull-right"></i><span class="badge badge-primary pull-right">{$_message|default=0}</span>消息中心
|
||||
</a>
|
||||
</li>
|
||||
<li class="divider"></li>
|
||||
<li>
|
||||
<a tabindex="-1" href="{:url('user/publics/signout')}">
|
||||
<i class="si si-logout pull-right"></i>退出帐号
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<a class="btn btn-default ajax-get" href="{:url('admin/index/wipeCache')}" data-toggle="tooltip" data-placement="bottom" data-original-title="清空缓存">
|
||||
<i class="fa fa-trash"></i>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="btn btn-default" href="{:rtrim(home_url('/'), '/')}" target="_blank" data-toggle="tooltip" data-placement="bottom" data-original-title="打开前台">
|
||||
<i class="fa fa-external-link-square"></i>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<!-- Layout API, functionality initialized in App() -> uiLayoutApi() -->
|
||||
<button class="btn btn-default" data-toggle="layout" data-action="side_overlay_toggle" title="侧边栏" type="button">
|
||||
<i class="fa fa-tasks"></i>
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
<!-- END Header Navigation Right -->
|
||||
|
||||
<!-- Header Navigation Left -->
|
||||
<ul class="nav nav-pills pull-left">
|
||||
<li class="hidden-md hidden-lg">
|
||||
<!-- Layout API, functionality initialized in App() -> uiLayoutApi() -->
|
||||
<a href="javascript:void(0)" data-toggle="layout" data-action="sidebar_toggle"><i class="fa fa-navicon"></i></a>
|
||||
</li>
|
||||
<li class="hidden-xs hidden-sm">
|
||||
<!-- Layout API, functionality initialized in App() -> uiLayoutApi() -->
|
||||
<a href="javascript:void(0)" title="打开/关闭左侧导航" data-toggle="layout" data-action="sidebar_mini_toggle"><i class="fa fa-bars"></i></a>
|
||||
</li>
|
||||
{notempty name="_top_menus"}
|
||||
{volist name="_top_menus" id="menu"}
|
||||
<li class="hidden-xs hidden-sm {$menu['id'] == $_location[0]['id'] ?= 'active'}">
|
||||
{in name="menu.url_type" value="module_admin,module_home"}
|
||||
<a href="javascript:void(0);" data-module-id="{$menu['id']}" data-module="{$menu['module']}" data-controller="{$menu['controller']}" target="{$menu['url_target']}" class="top-menu"><i class="{$menu.icon}"></i> {$menu.title}</a>
|
||||
{else/}
|
||||
<a href="{$menu['url_value']}" target="{$menu['url_target']}"><i class="{$menu.icon}"></i> {$menu.title}</a>
|
||||
{/in}
|
||||
</li>
|
||||
{/volist}
|
||||
{/notempty}
|
||||
<li>
|
||||
<!-- Opens the Apps modal found at the bottom of the page, before including JS code -->
|
||||
<a href="#" data-toggle="modal" data-target="#apps-modal"><i class="si si-grid"></i></a>
|
||||
</li>
|
||||
</ul>
|
||||
<!-- END Header Navigation Left -->
|
||||
</header>
|
||||
{/block}
|
||||
{/empty}
|
||||
<!-- END Header -->
|
||||
|
||||
<!-- Main Container -->
|
||||
<main id="main-container">
|
||||
<!-- Page Header -->
|
||||
{block name="page-header"}
|
||||
{empty name="_pop"}
|
||||
<div class="bg-gray-lighter">
|
||||
<ol class="breadcrumb">
|
||||
<li><i class="fa fa-map-marker"></i></li>
|
||||
{notempty name="_location"}
|
||||
{volist name="_location" id="v"}
|
||||
<li><a class="link-effect" href="{notempty name='$v["url_value"]'}{:url($v.url_value, $v.params)}{else/}javascript:void(0);{/notempty}">{$v.title}</a></li>
|
||||
{/volist}
|
||||
{/notempty}
|
||||
</ol>
|
||||
</div>
|
||||
{/empty}
|
||||
{/block}
|
||||
<!-- END Page Header -->
|
||||
|
||||
<!-- Page Content -->
|
||||
<div class="content">
|
||||
{// 页面提示钩子}
|
||||
{:hook('page_tips')}
|
||||
{// 主体内容}
|
||||
{block name="content"}{/block}
|
||||
</div>
|
||||
<!-- END Page Content -->
|
||||
</main>
|
||||
<!-- END Main Container -->
|
||||
|
||||
<!-- Footer -->
|
||||
{empty name="_pop"}
|
||||
<footer id="page-footer" class="content-mini content-mini-full font-s12 bg-gray-lighter clearfix">
|
||||
<div class="pull-right">
|
||||
Crafted with <i class="fa fa-heart text-city"></i> by <a class="font-w600" href="{:config('dolphin.company_website')}" target="_blank">{:config('dolphin.company_name')}</a>
|
||||
</div>
|
||||
<div class="pull-left">
|
||||
<a class="font-w600" href="{:config('dolphin.product_website')}" target="_blank">{:config('dolphin.product_name')} {:config('dolphin.product_version')}</a> © <span class="js-year-copy"></span>
|
||||
</div>
|
||||
</footer>
|
||||
{/empty}
|
||||
<!-- END Footer -->
|
||||
</div>
|
||||
<!-- END Page Container -->
|
||||
|
||||
<!-- Apps Modal -->
|
||||
<!-- Opens from the button in the header -->
|
||||
<div class="modal fade" id="apps-modal" tabindex="-1" role="dialog" aria-hidden="true">
|
||||
<div class="modal-dialog modal-dialog-top">
|
||||
<div class="modal-content">
|
||||
<!-- Apps Block -->
|
||||
<div class="block block-themed block-transparent">
|
||||
<div class="block-header bg-primary-dark">
|
||||
<ul class="block-options">
|
||||
<li>
|
||||
<button data-dismiss="modal" type="button"><i class="si si-close"></i></button>
|
||||
</li>
|
||||
</ul>
|
||||
<h3 class="block-title">所有模块</h3>
|
||||
</div>
|
||||
<div class="block-content">
|
||||
<div class="row text-center">
|
||||
{notempty name="_top_menus_all"}
|
||||
{volist name="_top_menus_all" id="menu"}
|
||||
<div class="col-xs-6 col-sm-3">
|
||||
{in name="menu.url_type" value="module_admin,module_home"}
|
||||
<a class="block block-rounded top-menu" href="javascript:void(0);" data-module-id="{$menu['id']}" data-module="{$menu['module']}" data-controller="{$menu['controller']}" target="{$menu['url_target']}">
|
||||
<div class="block-content text-white {$menu['id'] == $_location[0]['id'] ? 'bg-primary' : 'bg-primary-dark'}">
|
||||
<i class="{$menu.icon} fa-2x"></i>
|
||||
<div class="font-w600 push-15-t push-15">{$menu.title}</div>
|
||||
</div>
|
||||
</a>
|
||||
{else/}
|
||||
<a class="block block-rounded" href="{$menu['url_value']}" target="{$menu['url_target']}">
|
||||
<div class="block-content text-white {$menu['id'] == $_location[0]['id'] ? 'bg-primary' : 'bg-primary-dark'}">
|
||||
<i class="{$menu.icon} fa-2x"></i>
|
||||
<div class="font-w600 push-15-t push-15">{$menu.title}</div>
|
||||
</div>
|
||||
</a>
|
||||
{/in}
|
||||
</div>
|
||||
{/volist}
|
||||
{/notempty}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- END Apps Block -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- END Apps Modal -->
|
||||
<!-- OneUI Core JS: jQuery, Bootstrap, slimScroll, scrollLock, Appear, CountTo, Placeholder, Cookie and App.js -->
|
||||
{eq name="Think.config.minify_status" value="1"}
|
||||
<script src="{:minify('group', 'core_js,libs_js')}"></script>
|
||||
{else/}
|
||||
<script src="__ADMIN_JS__/core/jquery.min.js?v={:config('asset_version')}"></script>
|
||||
<script src="__ADMIN_JS__/core/bootstrap.min.js?v={:config('asset_version')}"></script>
|
||||
<script src="__ADMIN_JS__/core/jquery.slimscroll.min.js?v={:config('asset_version')}"></script>
|
||||
<script src="__ADMIN_JS__/core/jquery.scrollLock.min.js?v={:config('asset_version')}"></script>
|
||||
<script src="__ADMIN_JS__/core/jquery.appear.min.js?v={:config('asset_version')}"></script>
|
||||
<script src="__ADMIN_JS__/core/jquery.countTo.min.js?v={:config('asset_version')}"></script>
|
||||
<script src="__ADMIN_JS__/core/jquery.placeholder.min.js?v={:config('asset_version')}"></script>
|
||||
<script src="__ADMIN_JS__/core/js.cookie.min.js?v={:config('asset_version')}"></script>
|
||||
<script src="__LIBS__/magnific-popup/magnific-popup.min.js?v={:config('asset_version')}"></script>
|
||||
<script src="__ADMIN_JS__/app.js?v={:config('asset_version')}"></script>
|
||||
<script src="__ADMIN_JS__/dolphin.js?v={:config('asset_version')}"></script>
|
||||
<script src="__ADMIN_JS__/builder/form.js?v={:config('asset_version')}"></script>
|
||||
<script src="__ADMIN_JS__/builder/aside.js?v={:config('asset_version')}"></script>
|
||||
<script src="__ADMIN_JS__/builder/table.js?v={:config('asset_version')}"></script>
|
||||
<script src="__LIBS__/bootstrap-notify/bootstrap-notify.min.js?v={:config('asset_version')}"></script>
|
||||
<script src="__LIBS__/sweetalert/sweetalert.min.js?v={:config('asset_version')}"></script>
|
||||
<script src="__LIBS__/js-xss/xss.min.js?v={:config('asset_version')}"></script>
|
||||
<script src="__LIBS__/viewer/viewer.min.js?v={:config('asset_version')}"></script>
|
||||
{/eq}
|
||||
|
||||
<!-- Page JS Plugins -->
|
||||
<script src="__LIBS__/layer/layer.js?v={:config('asset_version')}"></script>
|
||||
{notempty name="_js_files"}
|
||||
{eq name="Think.config.minify_status" value="1"}
|
||||
<script src="{:minify('group', $_js_files)}"></script>
|
||||
{else/}
|
||||
{volist name="_js_files" id="js"}
|
||||
{:load_assets($js, 'js')}
|
||||
{/volist}
|
||||
{/eq}
|
||||
{/notempty}
|
||||
|
||||
{notempty name="extend_js_list"}
|
||||
{volist name="extend_js_list" id="vo"}
|
||||
{volist name="vo" id="v"}
|
||||
<script src="{$v}?v={:config('asset_version')}"></script>
|
||||
{/volist}
|
||||
{/volist}
|
||||
{/notempty}
|
||||
|
||||
<script>
|
||||
jQuery(function () {
|
||||
// 切换角色
|
||||
$('#js-change-role').click(function () {
|
||||
Dolphin.loading();
|
||||
$.get('{:url("admin/ajax/getMyRoles")}', function (res) {
|
||||
Dolphin.loading('hide');
|
||||
if (res.code) {
|
||||
let options = '';
|
||||
$.each(res.data.roles, function (index, item) {
|
||||
options += '<option value="'+index+'" '+(res.data.curr == index ? 'selected' : '')+'>'+item+'</option>';
|
||||
});
|
||||
|
||||
layer.open({
|
||||
type: 1,
|
||||
title: '<i class="si si-users"></i> 切换角色',
|
||||
area: ['300px', '180px'],
|
||||
btn: ['确定', '取消'],
|
||||
content: '<div class="form-group push-20-t">\n' +
|
||||
'<label class="col-xs-12" for="contact1-subject">当前角色</label>\n' +
|
||||
'<div class="col-xs-12">\n' +
|
||||
' <select class="form-control" id="role-select" size="1">\n' + options +
|
||||
' </select>\n' +
|
||||
'</div>\n' +
|
||||
'</div>',
|
||||
yes: function(index, layero){
|
||||
let role = $('#role-select').val();
|
||||
let loading = layer.load(2);
|
||||
$.post('{:url("admin/ajax/setMyRole")}', {id:role}, function (res) {
|
||||
layer.close(loading);
|
||||
if (res.code) {
|
||||
layer.close(index);
|
||||
layer.msg(res.msg);
|
||||
setTimeout(function () {
|
||||
location.reload();
|
||||
}, 1500);
|
||||
} else {
|
||||
layer.msg(res.msg)
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
} else {
|
||||
Dolphin.notify(res.msg, 'danger');
|
||||
}
|
||||
});
|
||||
});
|
||||
App.initHelpers(['appear', 'slimscroll', 'magnific-popup', 'table-tools']);
|
||||
{notempty name="_js_init"}
|
||||
App.initHelpers({$_js_init|raw});
|
||||
{/notempty}
|
||||
});
|
||||
</script>
|
||||
|
||||
<!--页面js-->
|
||||
{block name="script"}{/block}
|
||||
|
||||
<!--插件js钩子-->
|
||||
{:hook('page_plugin_js')}
|
||||
|
||||
{// 额外HTML代码 }
|
||||
{$extra_html|raw|default=''}
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,203 @@
|
|||
{extend name="layout" /}
|
||||
|
||||
{block name="plugins-css"}
|
||||
<link href="__LIBS__/jquery-nestable/jquery.nestable.css" rel="stylesheet" type="text/css" />
|
||||
{/block}
|
||||
|
||||
{block name="content"}
|
||||
<div class="alert alert-warning alert-dismissable">
|
||||
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
|
||||
<p><strong><i class="fa fa-fw fa-info-circle"></i> 提示:</strong>按住表头可拖动节点,调整后点击【保存节点】。</p>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="block">
|
||||
{notempty name="tab_nav"}
|
||||
<ul class="nav nav-tabs">
|
||||
{volist name="tab_nav['tab_list']" id="tab"}
|
||||
<li {eq name="tab_nav.curr_tab" value="$key"}class="active"{/eq}>
|
||||
<a href="{$tab.url}">{$tab.title}</a>
|
||||
</li>
|
||||
{/volist}
|
||||
<li {eq name="tab_nav.curr_tab" value="module-sort"}class="active"{/eq}>
|
||||
<a href="{:url('', ['group' => 'module-sort'])}">模块排序</a>
|
||||
</li>
|
||||
<li class="pull-right">
|
||||
<ul class="block-options push-10-t push-10-r">
|
||||
<li>
|
||||
<button type="button" data-toggle="block-option" data-action="fullscreen_toggle"></button>
|
||||
</li>
|
||||
<li>
|
||||
<button type="button" data-toggle="block-option" data-action="refresh_toggle" data-action-mode="demo"><i class="si si-refresh"></i></button>
|
||||
</li>
|
||||
<li>
|
||||
<button type="button" data-toggle="block-option" data-action="content_toggle"></button>
|
||||
</li>
|
||||
<li>
|
||||
<button type="button" data-toggle="block-option" data-action="close"><i class="si si-close"></i></button>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
{else/}
|
||||
<div class="block-header bg-gray-lighter">
|
||||
<ul class="block-options">
|
||||
<li>
|
||||
<button type="button" data-toggle="block-option" data-action="fullscreen_toggle"></button>
|
||||
</li>
|
||||
<li>
|
||||
<button type="button" data-toggle="block-option" data-action="refresh_toggle" data-action-mode="demo"><i class="si si-refresh"></i></button>
|
||||
</li>
|
||||
<li>
|
||||
<button type="button" data-toggle="block-option" data-action="content_toggle"></button>
|
||||
</li>
|
||||
<li>
|
||||
<button type="button" data-toggle="block-option" data-action="close"><i class="si si-close"></i></button>
|
||||
</li>
|
||||
</ul>
|
||||
<h3 class="block-title">{$page_title|raw}</h3>
|
||||
</div>
|
||||
{/notempty}
|
||||
<div class="block-content tab-content">
|
||||
<div class="tab-pane active">
|
||||
{notempty name="menus"}
|
||||
<div class="row data-table-toolbar">
|
||||
<div class="col-sm-12">
|
||||
<form action="{$Request.url}" method="get">
|
||||
<div class="toolbar-btn-action">
|
||||
<a title="新增" class="btn btn-primary" href="{:url('add', ['module' => $Request.param.group])}"><i class="fa fa-plus-circle"></i> 新增</a>
|
||||
<button title="保存" type="button" class="btn btn-default disabled" id="save" disabled><i class="fa fa-check-circle-o"></i> 保存节点</button>
|
||||
<button title="隐藏禁用节点" type="button" class="btn btn-danger" id="hide_disable"><i class="fa fa-eye-slash"></i> 隐藏禁用节点</button>
|
||||
<button title="显示禁用节点" type="button" class="btn btn-info" id="show_disable"><i class="fa fa-eye"></i> 显示禁用节点</button>
|
||||
<button title="展开所有节点" type="button" class="btn btn-success" id="expand-all"><i class="fa fa-plus"></i> 展开所有节点</button>
|
||||
<button title="收起所有节点" type="button" class="btn btn-warning" id="collapse-all"><i class="fa fa-minus"></i> 收起所有节点</button>
|
||||
<span class="form-inline">
|
||||
<input class="form-control" type="text" name="max" value="{$Request.get.max|default=''}" placeholder="显示层数">
|
||||
</span>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="dd" id="menu_list">
|
||||
<ol class="dd-list">{$menus|raw}</ol>
|
||||
</div>
|
||||
{/notempty}
|
||||
|
||||
{notempty name="modules"}
|
||||
<form action="{:url('')}" method="post" name="sort-form" class="sort-form">
|
||||
<button title="保存" type="submit" class="btn btn-success push-10 ajax-post" target-form="sort-form">保存排序</button>
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div id="sortable" class="connectedSortable push-20">
|
||||
{volist name="modules" id="module"}
|
||||
<div class="sortable-item pull-left">
|
||||
<input type="hidden" name="sort[]" value="{$key}">
|
||||
<i class="{$module.icon}"></i> {$module.title}
|
||||
</div>
|
||||
{/volist}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
{/notempty}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/block}
|
||||
|
||||
{block name="script"}
|
||||
<script src="__LIBS__/jquery-nestable/jquery.nestable.js"></script>
|
||||
<script src="__LIBS__/jquery-ui/jquery-ui.min.js"></script>
|
||||
<script>
|
||||
$(document).ready(function(){
|
||||
// 模块拖拽
|
||||
$( "#sortable" ).sortable({
|
||||
connectWith: ".connectedSortable"
|
||||
}).disableSelection();
|
||||
|
||||
// 保存节点
|
||||
$('#save').click(function(){
|
||||
Dolphin.loading();
|
||||
$.post("{:url('save')}", {menus: $('#menu_list').nestable('serialize')}, function(data) {
|
||||
Dolphin.loading('hide');
|
||||
if (data.code) {
|
||||
$('#save').removeClass('btn-success').addClass('btn-default disabled');
|
||||
Dolphin.notify(data.msg, 'success');
|
||||
} else {
|
||||
Dolphin.notify(data.msg, 'danger');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// 初始化节点拖拽
|
||||
$('#menu_list').nestable({maxDepth:4}).on('change', function(){
|
||||
$('#save').removeAttr("disabled").removeClass('btn-default disabled').addClass('btn-success');
|
||||
});
|
||||
|
||||
// 隐藏禁用节点
|
||||
$('#hide_disable').click(function(){
|
||||
$('.dd-disable').hide();
|
||||
});
|
||||
|
||||
// 显示禁用节点
|
||||
$('#show_disable').click(function(){
|
||||
$('.dd-disable').show();
|
||||
});
|
||||
|
||||
// 展开所有节点
|
||||
$('#expand-all').click(function(){
|
||||
$('#menu_list').nestable('expandAll');
|
||||
});
|
||||
|
||||
// 收起所有节点
|
||||
$('#collapse-all').click(function(){
|
||||
$('#menu_list').nestable('collapseAll');
|
||||
});
|
||||
|
||||
// 禁用节点
|
||||
$('.dd3-content').delegate('.disable', 'click', function(){
|
||||
var self = $(this);
|
||||
var ids = self.data('ids');
|
||||
var ajax_url = '{:url("disable", ["table" => "admin_menu"])}';
|
||||
Dolphin.loading();
|
||||
$.post(ajax_url, {ids:ids}, function(data) {
|
||||
Dolphin.loading('hide');
|
||||
if (data.code) {
|
||||
self.attr('data-original-title', '启用').removeClass('disable').addClass('enable')
|
||||
.children().removeClass('fa-ban').addClass('fa-check-circle-o')
|
||||
.closest('.dd-item')
|
||||
.addClass('dd-disable');
|
||||
} else {
|
||||
Dolphin.notify(data.msg, 'danger');
|
||||
}
|
||||
});
|
||||
return false;
|
||||
});
|
||||
|
||||
// 启用节点
|
||||
$('.dd3-content').delegate('.enable', 'click', function(){
|
||||
var self = $(this);
|
||||
var ids = self.data('ids');
|
||||
var ajax_url = '{:url("enable", ["table" => "admin_menu"])}';
|
||||
Dolphin.loading();
|
||||
$.post(ajax_url, {ids:ids}, function(data) {
|
||||
Dolphin.loading('hide');
|
||||
if (data.code) {
|
||||
self.attr('data-original-title', '禁用').removeClass('enable').addClass('disable')
|
||||
.children().removeClass('fa-check-circle-o').addClass('fa-ban')
|
||||
.closest('.dd-item')
|
||||
.removeClass('dd-disable');
|
||||
} else {
|
||||
Dolphin.notify(data.msg, 'danger');
|
||||
}
|
||||
});
|
||||
return false;
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{/block}
|
|
@ -0,0 +1,63 @@
|
|||
{extend name="layout" /}
|
||||
|
||||
{block name="content"}
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="block">
|
||||
<div class="block-header bg-gray-lighter">
|
||||
<ul class="block-options">
|
||||
<li>
|
||||
<button type="button" data-toggle="block-option" data-action="fullscreen_toggle"></button>
|
||||
</li>
|
||||
<li>
|
||||
<button type="button" data-toggle="block-option" data-action="refresh_toggle" data-action-mode="demo"><i class="si si-refresh"></i></button>
|
||||
</li>
|
||||
<li>
|
||||
<button type="button" data-toggle="block-option" data-action="content_toggle"></button>
|
||||
</li>
|
||||
<li>
|
||||
<button type="button" data-toggle="block-option" data-action="close"><i class="si si-close"></i></button>
|
||||
</li>
|
||||
</ul>
|
||||
<h3 class="block-title">{$page_title|default=""}</h3>
|
||||
</div>
|
||||
|
||||
<div class="block-content tab-content">
|
||||
<div class="tab-pane active">
|
||||
<div class="block-content">
|
||||
<form class="form-horizontal form-builder" action="{:url('export')}" method="get">
|
||||
<input type="hidden" name="name" value="{$Request.param.name|default=''}">
|
||||
<div class="form-group " id="form_group_group">
|
||||
<h4 class="col-xs-12 push-10">是否导出数据</h4>
|
||||
<div class="col-xs-9">
|
||||
<label class="css-input css-radio css-radio-primary css-radio-sm push-10-r">
|
||||
<input type="radio" name="export_data" id="clear1" value="0">
|
||||
<span></span> 否
|
||||
</label>
|
||||
<label class="css-input css-radio css-radio-primary css-radio-sm push-10-r">
|
||||
<input type="radio" name="export_data" id="clear2" value="1" checked="">
|
||||
<span></span> 是
|
||||
</label>
|
||||
<div class="help-block">
|
||||
选择“否”,只导出数据表结构。选择“是”,导出该模块的所有数据
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="col-xs-12">
|
||||
<button class="btn btn-minw btn-primary" type="submit" id="uninstall">
|
||||
导出
|
||||
</button>
|
||||
<button class="btn btn-default" type="button" onclick="javascript:history.back(-1);return false;">
|
||||
返回
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/block}
|
|
@ -0,0 +1,163 @@
|
|||
{extend name="layout" /}
|
||||
|
||||
{block name="content"}
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="block">
|
||||
{notempty name="tab_nav"}
|
||||
<ul class="nav nav-tabs">
|
||||
{volist name="tab_nav['tab_list']" id="tab"}
|
||||
<li {eq name="tab_nav.curr_tab" value="$key"}class="active"{/eq}>
|
||||
<a href="{$tab.url}">{$tab.title}</a>
|
||||
</li>
|
||||
{/volist}
|
||||
<li class="pull-right">
|
||||
<ul class="block-options push-10-t push-10-r">
|
||||
<li>
|
||||
<a href="{:url('index', ['type' => $type])}"><i class="si si-{$type=='list' ? 'list' : 'grid'}"></i></a>
|
||||
</li>
|
||||
<li>
|
||||
<button type="button" data-toggle="block-option" data-action="fullscreen_toggle"></button>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
{else/}
|
||||
<div class="block-header bg-gray-lighter">
|
||||
<ul class="block-options">
|
||||
<li>
|
||||
<button type="button" data-toggle="block-option" data-action="fullscreen_toggle"></button>
|
||||
</li>
|
||||
<li>
|
||||
<button type="button" data-toggle="block-option" data-action="refresh_toggle" data-action-mode="demo"><i class="si si-refresh"></i></button>
|
||||
</li>
|
||||
<li>
|
||||
<button type="button" data-toggle="block-option" data-action="content_toggle"></button>
|
||||
</li>
|
||||
<li>
|
||||
<button type="button" data-toggle="block-option" data-action="close"><i class="si si-close"></i></button>
|
||||
</li>
|
||||
</ul>
|
||||
<h3 class="block-title">{$page_title}</h3>
|
||||
</div>
|
||||
{/notempty}
|
||||
<div class="block-content tab-content">
|
||||
<div class="tab-pane active">
|
||||
<div class="row push-20">
|
||||
<div class="col-md-12">
|
||||
<div class="pull-right search-bar">
|
||||
<form class="input-group">
|
||||
<span class="input-group-addon"><i class="fa fa-search"></i></span>
|
||||
<input type="text" class="form-control" value="{:input('get.keyword')}" name="keyword" placeholder="请输入标识/名称/作者">
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="toolbar-btn-action">
|
||||
<a title="全部" class="btn btn-default" href="{:url('index')}">全部({$total.all|default='0'})</a>
|
||||
<a title="已启用" class="btn btn-success" href="{:url('index', ['status' => '1'])}">已启用({$total['1']|default='0'})</a>
|
||||
<a title="已禁用" class="btn btn-warning" href="{:url('index', ['status' => '0'])}">已禁用({$total['0']|default='0'})</a>
|
||||
<a title="未安装" class="btn btn-info" href="{:url('index', ['status' => '-1'])}">未安装({$total['-1']|default='0'})</a>
|
||||
<a title="已损坏" class="btn btn-danger" href="{:url('index', ['status' => '-2'])}" id="hide_disable">已损坏({$total['-2']|default='0'})</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row module-list push-20">
|
||||
{empty name="modules"}
|
||||
<div class="table-empty">
|
||||
<div class="text-center empty-info">
|
||||
<i class="fa fa-database"></i> 暂无数据<br>
|
||||
</div>
|
||||
</div>
|
||||
{/empty}
|
||||
{eq name="type" value="block"}
|
||||
{volist name="modules" id="module"}
|
||||
<div class="col-sm-6 col-md-4 col-lg-3">
|
||||
<div class="block block-rounded">
|
||||
<div class="block-content block-content-full text-center bg-{$module.bg_color|default='danger'} ribbon ribbon-bookmark ribbon-crystal">
|
||||
<div class="ribbon-box font-w600">{$module.version|default='无版本号'}</div>
|
||||
<div class="item item-2x item-circle bg-crystal-op push-20-t push-20 visibility-hidden" data-toggle="appear" data-offset="50" data-class="animated fadeIn">
|
||||
<i class="{$module.icon|default='fa fa-puzzle-piece'} text-white-op"></i>
|
||||
</div>
|
||||
<h3 class="h4 text-white">{$module.title|default='无模块标题'}</h3>
|
||||
<div class="text-white-op">
|
||||
<em>{$module.name|default=''}</em>
|
||||
</div>
|
||||
</div>
|
||||
<div class="block-content bg-gray-lighter">
|
||||
<div class="{$module.status_class} pull-right push-10-l">{$module.status_info|raw}</div>
|
||||
<div class="push-10">
|
||||
<a class="h5" href="{$module.author_url|default=''}" target="_blank"><i class="fa fa-user"></i> {$module.author|default=''}</a>
|
||||
</div>
|
||||
<div class="push-10 mheight-100">
|
||||
<div data-toggle="slimscroll" data-height="110px">
|
||||
<p class="text-gray-dark">{$module.description|raw|default='暂无简介'}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-center push">
|
||||
{$module.actions|raw}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/volist}
|
||||
{else/}
|
||||
{notempty name="modules"}
|
||||
<div class="col-md-12">
|
||||
<div class="builder-table-wrapper" id="builder-table-wrapper">
|
||||
<div class="builder-table" id="builder-table">
|
||||
<table class="table table-builder table-hover table-bordered table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>名称</th>
|
||||
<th>图标</th>
|
||||
<th>版本</th>
|
||||
<th>作者</th>
|
||||
<th>简介</th>
|
||||
<th class="column-right_button">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{volist name="modules" id="module"}
|
||||
<tr>
|
||||
<td>{$module.title|default='无模块标题'}</td>
|
||||
<td><i class="{$module.icon|default='fa fa-puzzle-piece'}"></i></td>
|
||||
<td>{$module.version|default='无版本号'}</td>
|
||||
<td><a href="{$module.author_url|default=''}" target="_blank">{$module.author|default=''}</a></td>
|
||||
<td>{$module.description|raw|default='暂无简介'}</td>
|
||||
<td>{$module.actions|raw}</td>
|
||||
</tr>
|
||||
{/volist}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/notempty}
|
||||
{/eq}
|
||||
</div>
|
||||
<div class="data-table-toolbar">
|
||||
<div class="row">
|
||||
<div class="col-sm-12">
|
||||
{// 分页 }
|
||||
{notempty name="pages"}
|
||||
{$pages}
|
||||
{/notempty}
|
||||
{notempty name="row_list"}
|
||||
<div class="pagination-info pull-right">
|
||||
<form action="" method="get">
|
||||
<input type="text" class="form-control input-sm go-page" name="page" value="{:input('param.page', '1')}">
|
||||
<input type="text" class="form-control input-sm nums" name="list_rows" value="{php}echo input('param.list_rows', '') == '' ? config('list_rows') : input('param.list_rows');{/php}">
|
||||
<input type="submit" class="hidden">
|
||||
/ <strong>{$row_list->lastPage()}</strong> 页,共 <strong>{$row_list->total()}</strong> 条数据,每页显示数量
|
||||
</form>
|
||||
</div>
|
||||
{/notempty}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/block}
|
|
@ -0,0 +1,182 @@
|
|||
{extend name="layout" /}
|
||||
|
||||
{block name="content"}
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="block">
|
||||
<div class="block-header bg-gray-lighter">
|
||||
<ul class="block-options">
|
||||
<li>
|
||||
<button type="button" data-toggle="block-option" data-action="fullscreen_toggle"></button>
|
||||
</li>
|
||||
<li>
|
||||
<button type="button" data-toggle="block-option" data-action="refresh_toggle" data-action-mode="demo"><i class="si si-refresh"></i></button>
|
||||
</li>
|
||||
<li>
|
||||
<button type="button" data-toggle="block-option" data-action="content_toggle"></button>
|
||||
</li>
|
||||
<li>
|
||||
<button type="button" data-toggle="block-option" data-action="close"><i class="si si-close"></i></button>
|
||||
</li>
|
||||
</ul>
|
||||
<h3 class="block-title">{$page_title|default=""}</h3>
|
||||
</div>
|
||||
|
||||
<div class="block-content tab-content">
|
||||
<div class="tab-pane active">
|
||||
<div class="block-content">
|
||||
<form class="form-horizontal form-builder" action="{:url('install')}" method="get">
|
||||
<input type="hidden" name="name" value="{$name|default=''}">
|
||||
<input type="hidden" name="confirm" value="1">
|
||||
<div class="form-group">
|
||||
<h4 class="col-xs-12 push-10">模块依赖检查</h4>
|
||||
<div class="col-sm-5">
|
||||
{empty name="need_module"}
|
||||
<div class="form-control-static">无需依赖其他模块</div>
|
||||
{else/}
|
||||
<table class="table table-bordered table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>模块</th>
|
||||
<th>唯一标识</th>
|
||||
<th style="width: 100px;">当前版本</th>
|
||||
<th style="width: 100px;">所需版本</th>
|
||||
<th class="text-center" style="width: 100px;">检查结果</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{volist name="need_module" id="vo"}
|
||||
<tr>
|
||||
<td>{$vo.module}</td>
|
||||
<td><a href="http://www.dolphinphp.com" target="_blank" data-toggle="tooltip" title="到商城查看该模块">{$vo.identifier}</a></td>
|
||||
<td>{$vo.version}</td>
|
||||
<td>{$vo.version_need}</td>
|
||||
<td class="text-center">
|
||||
{$vo.result|raw}
|
||||
</td>
|
||||
</tr>
|
||||
{/volist}
|
||||
</tbody>
|
||||
</table>
|
||||
{/empty}
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<h4 class="col-xs-12 push-10">插件依赖检查</h4>
|
||||
<div class="col-sm-5">
|
||||
{empty name="need_plugin"}
|
||||
<div class="form-control-static">无需依赖其他插件</div>
|
||||
{else/}
|
||||
<table class="table table-bordered table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>插件</th>
|
||||
<th>唯一标识</th>
|
||||
<th style="width: 100px;">当前版本</th>
|
||||
<th style="width: 100px;">所需版本</th>
|
||||
<th class="text-center" style="width: 100px;">检查结果</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{volist name="need_plugin" id="vo"}
|
||||
<tr>
|
||||
<td>{$vo.plugin}</td>
|
||||
<td><a href="http://www.dolphinphp.com" target="_blank" data-toggle="tooltip" title="到商城查看该插件">{$vo.identifier}</a></td>
|
||||
<td>{$vo.version}</td>
|
||||
<td>{$vo.version_need}</td>
|
||||
<td class="text-center">
|
||||
{$vo.result|raw}
|
||||
</td>
|
||||
</tr>
|
||||
{/volist}
|
||||
</tbody>
|
||||
</table>
|
||||
{/empty}
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<h4 class="col-xs-12 push-10">数据表检查</h4>
|
||||
<div class="col-sm-5">
|
||||
{empty name="table_check"}
|
||||
<div class="form-control-static">该模块不需要数据表</div>
|
||||
{else/}
|
||||
<table class="table table-bordered table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>数据表</th>
|
||||
<th class="text-center" style="width: 100px;">检查结果</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{volist name="table_check" id="vo"}
|
||||
<tr>
|
||||
<td>{$vo.table}</td>
|
||||
<td class="text-center">
|
||||
{$vo.result|raw}
|
||||
</td>
|
||||
</tr>
|
||||
{/volist}
|
||||
</tbody>
|
||||
</table>
|
||||
{/empty}
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group " id="form_group_group">
|
||||
<h4 class="col-xs-12 push-10">是否清除旧数据</h4>
|
||||
<div class="col-xs-9">
|
||||
<label class="css-input css-radio css-radio-primary css-radio-sm push-10-r">
|
||||
<input type="radio" name="clear" id="clear1" value="0" checked="">
|
||||
<span></span> 否
|
||||
</label>
|
||||
<label class="css-input css-radio css-radio-primary css-radio-sm push-10-r">
|
||||
<input type="radio" name="clear" id="clear2" value="1">
|
||||
<span></span> 是
|
||||
</label>
|
||||
<div class="help-block">
|
||||
选择“是”,将删除数据库中已存在的相同数据表
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="col-xs-12">
|
||||
<button class="btn btn-minw btn-primary" type="button" id="install">
|
||||
安装
|
||||
</button>
|
||||
<button class="btn btn-default" type="button" onclick="javascript:history.back(-1);return false;">
|
||||
返回
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/block}
|
||||
|
||||
{block name="script"}
|
||||
<script>
|
||||
$(document).ready(function(){
|
||||
$('#install').click(function () {
|
||||
var table_exists = false;
|
||||
|
||||
if ($('.form-builder i.text-danger').length) {
|
||||
Dolphin.notify('缺少依赖模块或插件', 'danger');
|
||||
return false;
|
||||
}
|
||||
if ($('.form-builder span.text-danger').length) {
|
||||
table_exists = true;
|
||||
}
|
||||
if (table_exists && $('.form-builder input[name=clear]:checked').val() == 0) {
|
||||
Dolphin.notify('数据库表存在冲突,如果需要覆盖原有数据,请选择“清除旧数据”', 'danger');
|
||||
return false;
|
||||
}
|
||||
|
||||
$('.form-builder').submit();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{/block}
|
|
@ -0,0 +1,64 @@
|
|||
{extend name="layout" /}
|
||||
|
||||
{block name="content"}
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="block">
|
||||
<div class="block-header bg-gray-lighter">
|
||||
<ul class="block-options">
|
||||
<li>
|
||||
<button type="button" data-toggle="block-option" data-action="fullscreen_toggle"></button>
|
||||
</li>
|
||||
<li>
|
||||
<button type="button" data-toggle="block-option" data-action="refresh_toggle" data-action-mode="demo"><i class="si si-refresh"></i></button>
|
||||
</li>
|
||||
<li>
|
||||
<button type="button" data-toggle="block-option" data-action="content_toggle"></button>
|
||||
</li>
|
||||
<li>
|
||||
<button type="button" data-toggle="block-option" data-action="close"><i class="si si-close"></i></button>
|
||||
</li>
|
||||
</ul>
|
||||
<h3 class="block-title">{$page_title|default=""}</h3>
|
||||
</div>
|
||||
|
||||
<div class="block-content tab-content">
|
||||
<div class="tab-pane active">
|
||||
<div class="block-content">
|
||||
<form class="form-horizontal form-builder" action="{:url('uninstall')}" method="get">
|
||||
<input type="hidden" name="name" value="{$name|default=''}">
|
||||
<input type="hidden" name="confirm" value="1">
|
||||
<div class="form-group " id="form_group_group">
|
||||
<h4 class="col-xs-12 push-10">是否清除数据</h4>
|
||||
<div class="col-xs-9">
|
||||
<label class="css-input css-radio css-radio-primary css-radio-sm push-10-r">
|
||||
<input type="radio" name="clear" id="clear1" value="0" checked="">
|
||||
<span></span> 否
|
||||
</label>
|
||||
<label class="css-input css-radio css-radio-primary css-radio-sm push-10-r">
|
||||
<input type="radio" name="clear" id="clear2" value="1">
|
||||
<span></span> 是
|
||||
</label>
|
||||
<div class="help-block">
|
||||
选择“是”,将删除数据库中的数据表
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="col-xs-12">
|
||||
<button class="btn btn-minw btn-danger" type="submit" id="uninstall">
|
||||
卸载
|
||||
</button>
|
||||
<button class="btn btn-default" type="button" onclick="javascript:history.back(-1);return false;">
|
||||
返回
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/block}
|
|
@ -0,0 +1,164 @@
|
|||
{extend name="layout" /}
|
||||
|
||||
{block name="content"}
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="block">
|
||||
{notempty name="tab_nav"}
|
||||
<ul class="nav nav-tabs">
|
||||
{volist name="tab_nav['tab_list']" id="tab"}
|
||||
<li {eq name="tab_nav.curr_tab" value="$key"}class="active"{/eq}>
|
||||
<a href="{$tab.url}">{$tab.title}</a>
|
||||
</li>
|
||||
{/volist}
|
||||
<li class="pull-right">
|
||||
<ul class="block-options push-10-t push-10-r">
|
||||
<li>
|
||||
<a href="{:url('index', ['type' => $type])}"><i class="si si-{$type=='list' ? 'list' : 'grid'}"></i></a>
|
||||
</li>
|
||||
<li>
|
||||
<button type="button" data-toggle="block-option" data-action="fullscreen_toggle"></button>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
{else/}
|
||||
<div class="block-header bg-gray-lighter">
|
||||
<ul class="block-options">
|
||||
<li>
|
||||
<button type="button" data-toggle="block-option" data-action="fullscreen_toggle"></button>
|
||||
</li>
|
||||
<li>
|
||||
<button type="button" data-toggle="block-option" data-action="refresh_toggle" data-action-mode="demo"><i class="si si-refresh"></i></button>
|
||||
</li>
|
||||
<li>
|
||||
<button type="button" data-toggle="block-option" data-action="content_toggle"></button>
|
||||
</li>
|
||||
<li>
|
||||
<button type="button" data-toggle="block-option" data-action="close"><i class="si si-close"></i></button>
|
||||
</li>
|
||||
</ul>
|
||||
<h3 class="block-title">{$page_title}</h3>
|
||||
</div>
|
||||
{/notempty}
|
||||
<div class="block-content tab-content">
|
||||
<div class="tab-pane active">
|
||||
<div class="row push-20">
|
||||
<div class="col-md-12">
|
||||
<div class="pull-right search-bar">
|
||||
<form class="input-group">
|
||||
<span class="input-group-addon"><i class="fa fa-search"></i></span>
|
||||
<input type="text" class="form-control" value="{:input('get.keyword')}" name="keyword" placeholder="请输入标识/名称/作者">
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="toolbar-btn-action">
|
||||
<a title="全部" class="btn btn-default" href="{:url('index')}">全部({$total.all|default='0'})</a>
|
||||
<a title="已启用" class="btn btn-success" href="{:url('index', ['status' => '1'])}">已启用({$total['1']|default='0'})</a>
|
||||
<a title="已禁用" class="btn btn-warning" href="{:url('index', ['status' => '0'])}">已禁用({$total['0']|default='0'})</a>
|
||||
<a title="未安装" class="btn btn-info" href="{:url('index', ['status' => '-1'])}">未安装({$total['-1']|default='0'})</a>
|
||||
<a title="已损坏" class="btn btn-danger" href="{:url('index', ['status' => '-2'])}" id="hide_disable">已损坏({$total['-2']|default='0'})</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row module-list push-20">
|
||||
{empty name="plugins"}
|
||||
<div class="table-empty">
|
||||
<div class="text-center empty-info">
|
||||
<i class="fa fa-database"></i> 暂无数据<br>
|
||||
</div>
|
||||
</div>
|
||||
{/empty}
|
||||
{eq name="type" value="block"}
|
||||
{volist name="plugins" id="plugin"}
|
||||
<div class="col-sm-6 col-md-4 col-lg-3">
|
||||
<div class="block block-rounded">
|
||||
<div class="block-content block-content-full text-center bg-{$plugin.bg_color|default='danger'} ribbon ribbon-bookmark ribbon-crystal">
|
||||
<div class="ribbon-box font-w600">{$plugin.version|default='无版本号'}</div>
|
||||
<div class="item item-2x item-circle bg-crystal-op push-20-t push-20 visibility-hidden" data-toggle="appear" data-offset="50" data-class="animated fadeIn">
|
||||
<i class="{$plugin.icon|default='fa fa-puzzle-piece'} text-white-op"></i>
|
||||
</div>
|
||||
<h3 class="h4 text-white">{$plugin.title|default='无插件标题'}</h3>
|
||||
<div class="text-white-op">
|
||||
<em>{$plugin.name|default=''}</em>
|
||||
</div>
|
||||
</div>
|
||||
<div class="block-content bg-gray-lighter">
|
||||
<div class="{$plugin.status_class} pull-right push-10-l">{$plugin.status_info|raw}</div>
|
||||
<div class="push-10">
|
||||
<a class="h5" href="{$plugin.author_url|default=''}" target="_blank"><i class="fa fa-user"></i> {$plugin.author|default=''}</a>
|
||||
</div>
|
||||
<div class="push-10 mheight-100">
|
||||
<div data-toggle="slimscroll" data-height="110px">
|
||||
<p class="text-gray-dark">{$plugin.description|raw|default='暂无简介'}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-center push">
|
||||
{$plugin.actions|raw}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/volist}
|
||||
{else/}
|
||||
{notempty name="plugins"}
|
||||
<div class="col-md-12">
|
||||
<div class="builder-table-wrapper" id="builder-table-wrapper">
|
||||
<div class="builder-table" id="builder-table">
|
||||
<table class="table table-builder table-hover table-bordered table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>名称</th>
|
||||
<th>图标</th>
|
||||
<th>版本</th>
|
||||
<th>作者</th>
|
||||
<th>简介</th>
|
||||
<th class="column-right_button" style="min-width:180px">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{volist name="plugins" id="plugin"}
|
||||
<tr>
|
||||
<td>{$plugin.title|default='无插件标题'}</td>
|
||||
<td><i class="{$plugin.icon|default='fa fa-puzzle-piece'}"></i></td>
|
||||
<td>{$plugin.version|default='无版本号'}</td>
|
||||
<td><a href="{$plugin.author_url|default=''}" target="_blank">{$plugin.author|default=''}</a></td>
|
||||
<td>{$plugin.description|raw|default='暂无简介'}</td>
|
||||
<td>{$plugin.actions|raw}</td>
|
||||
</tr>
|
||||
{/volist}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/notempty}
|
||||
{/eq}
|
||||
|
||||
</div>
|
||||
<div class="data-table-toolbar">
|
||||
<div class="row">
|
||||
<div class="col-sm-12">
|
||||
{// 分页 }
|
||||
{notempty name="pages"}
|
||||
{$pages}
|
||||
{/notempty}
|
||||
{notempty name="row_list"}
|
||||
<div class="pagination-info pull-right">
|
||||
<form action="" method="get">
|
||||
<input type="text" class="form-control input-sm go-page" name="page" value="{:input('param.page', '1')}">
|
||||
<input type="text" class="form-control input-sm nums" name="list_rows" value="{php}echo input('param.list_rows', '') == '' ? config('list_rows') : input('param.list_rows');{/php}">
|
||||
<input type="submit" class="hidden">
|
||||
/ <strong>{$row_list->lastPage()}</strong> 页,共 <strong>{$row_list->total()}</strong> 条数据,每页显示数量
|
||||
</form>
|
||||
</div>
|
||||
{/notempty}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/block}
|
Binary file not shown.
|
@ -0,0 +1,73 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* 接口信息返回方法
|
||||
*/
|
||||
function apiReturn($code = 200, $msg = '', $data = [],$header = []){
|
||||
http_response_code($code); //设置返回头部
|
||||
$return['code'] = (int)$code;
|
||||
$return['msg'] = $msg;
|
||||
$return['result'] = is_array($data) ? $data : ['info'=>$data];
|
||||
// 发送头部信息
|
||||
foreach ($header as $name => $val) {
|
||||
if (is_null($val)) {
|
||||
header($name);
|
||||
} else {
|
||||
header($name . ':' . $val);
|
||||
}
|
||||
}
|
||||
exit(json_encode($return,JSON_UNESCAPED_UNICODE));
|
||||
}
|
||||
|
||||
function checknum($len = 6)
|
||||
{
|
||||
$chars = array(
|
||||
"0",
|
||||
"1",
|
||||
"2",
|
||||
"3",
|
||||
"4",
|
||||
"5",
|
||||
"6",
|
||||
"7",
|
||||
"8",
|
||||
"9"
|
||||
);
|
||||
$charsLen = count($chars) - 1;
|
||||
shuffle($chars); // 将数组打乱
|
||||
$output = "";
|
||||
for ($i = 0; $i < $len; $i ++) {
|
||||
$output .= $chars[mt_rand(0, $charsLen)];
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据身份证号码获取性别
|
||||
*
|
||||
* @param string $string
|
||||
* 身份证号码
|
||||
* @return int $sex 性别 1男 2女 0未知
|
||||
*
|
||||
*/
|
||||
function getsex($idcard)
|
||||
{
|
||||
$sexint = (int) substr($idcard, 16, 1);
|
||||
return $sexint % 2 === 0 ? 2 : 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据身份证号码获取生日
|
||||
*
|
||||
* @param string $string
|
||||
* 身份证号码
|
||||
* @return string
|
||||
*/
|
||||
function getbirthday($idcard)
|
||||
{
|
||||
$bir = substr($idcard, 6, 8);
|
||||
$year = (int) substr($bir, 0, 4);
|
||||
$month = (int) substr($bir, 4, 2);
|
||||
$day = (int) substr($bir, 6, 2);
|
||||
return $year . "-" . $month . "-" . $day;
|
||||
}
|
Binary file not shown.
|
@ -0,0 +1,361 @@
|
|||
<?php
|
||||
|
||||
namespace app\api\controller;
|
||||
|
||||
use app\common\controller\Common;
|
||||
use think\Db;
|
||||
use think\Request;
|
||||
use util\Aes;
|
||||
use app\admin\model\Attachment as AttachmentModel;
|
||||
use app\member\model\Member as MemberModel;
|
||||
|
||||
class Api extends Common
|
||||
{
|
||||
|
||||
protected $params = null; //传参
|
||||
protected $user_id = 0; //登录用户id
|
||||
protected $user_info = 0; //登录用户信息
|
||||
protected $base_url = null; //网站域名
|
||||
|
||||
public function initialize()
|
||||
{
|
||||
header('Content-Type:application/json; charset=utf-8');
|
||||
parent::initialize();
|
||||
|
||||
$this->params = $this->request->param(); //传参
|
||||
$this->base_url = 'https://' . $_SERVER['HTTP_HOST']; //当前域名
|
||||
|
||||
//获取头部信息
|
||||
$header = $this->request->header();
|
||||
|
||||
//非登录模块操作需要验证用户信息
|
||||
if ( $this->request->controller() != 'Login' && $this->request->controller() != 'Uploadfile' && $this->request->controller() != 'Wxpaynotify') {
|
||||
|
||||
if($this->request->action()!='index' && $this->request->action()!='groupdetail' && $this->request->action()!='messageboard'){
|
||||
|
||||
//根据token获取用户信息
|
||||
if (!isset($header['user-token']) || empty($header['user-token'])) {
|
||||
apiReturn(500,'token信息不存在');
|
||||
}
|
||||
|
||||
$user_token = $header['user-token'];
|
||||
|
||||
$this->user_info = MemberModel::where('userToken',$user_token)->find();
|
||||
|
||||
if (!$this->user_info || empty($user_token)) {
|
||||
apiReturn(500,'token参数错误或登录超时');
|
||||
}
|
||||
|
||||
// 检查账号有效性
|
||||
if (!MemberModel::where(['id' => $this->user_info['id'], 'is_delete' => 0])->value('id')) {
|
||||
apiReturn(500,'账号不存在或已被禁用');
|
||||
}
|
||||
|
||||
//登录是否超时(一周登录时间)
|
||||
$time_compa = abs(time() - $this->user_info['lastlogin_time']);
|
||||
if ($time_compa > 604800) {
|
||||
//清空token
|
||||
MemberModel::update(['user_token' => ''], ['id' => $this->user_info['id']]);
|
||||
apiReturn(500,'登录超时');
|
||||
}
|
||||
|
||||
//登录用户id
|
||||
$this->user_id = $this->user_info['id'];
|
||||
|
||||
}else{
|
||||
|
||||
if (isset($header['user-token']) && !empty($header['user-token'])) {
|
||||
$user_token = $header['user-token'];
|
||||
|
||||
$this->user_info = MemberModel::where('userToken',$user_token)->find();
|
||||
|
||||
if (!$this->user_info || empty($user_token)) {
|
||||
apiReturn(500,'token参数错误或登录超时');
|
||||
}
|
||||
|
||||
// 检查账号有效性
|
||||
if (!MemberModel::where(['id' => $this->user_info['id'], 'is_delete' => 0])->value('id')) {
|
||||
apiReturn(500,'账号不存在或已被禁用');
|
||||
}
|
||||
|
||||
//登录是否超时(一周登录时间)
|
||||
$time_compa = abs(time() - $this->user_info['lastlogin_time']);
|
||||
if ($time_compa > 604800) {
|
||||
//清空token
|
||||
MemberModel::update(['user_token' => ''], ['id' => $this->user_info['id']]);
|
||||
apiReturn(500,'登录超时');
|
||||
}
|
||||
|
||||
//登录用户id
|
||||
$this->user_id = $this->user_info['id'];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取附件地址
|
||||
*/
|
||||
public function getFileUrl($attactId = 0)
|
||||
{
|
||||
$url = $this->base_url . get_file_path($attactId);
|
||||
return $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* 产生随机字符串
|
||||
* 产生一个指定长度的随机字符串,并返回给用户
|
||||
* @access public
|
||||
* @param int $len 产生字符串的位数
|
||||
* @return string
|
||||
*/
|
||||
function genNumberString($len = 6)
|
||||
{
|
||||
$chars = array(
|
||||
"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"
|
||||
);
|
||||
$charsLen = count($chars) - 1;
|
||||
shuffle($chars); // 将数组打乱
|
||||
$output = "";
|
||||
for ($i = 0; $i < $len; $i++) {
|
||||
$output .= $chars[mt_rand(0, $charsLen)];
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
|
||||
//非法字符判断
|
||||
public function illegalcharacters($str)
|
||||
{
|
||||
$strarr = array(
|
||||
'"',
|
||||
'<',
|
||||
'>',
|
||||
'<>',
|
||||
'(',
|
||||
')',
|
||||
'()',
|
||||
',',
|
||||
',',
|
||||
'script',
|
||||
'svg',
|
||||
'alert',
|
||||
'confirm',
|
||||
'prompt',
|
||||
'onload',
|
||||
'onmouseover',
|
||||
'onfocus',
|
||||
'onerror',
|
||||
'xss',
|
||||
);
|
||||
if (in_array($str, $strarr)) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//计算两个时间之前存在几个小时
|
||||
public function hours_min($start_time, $end_time)
|
||||
{
|
||||
|
||||
$sec = strtotime($end_time) - strtotime($start_time);
|
||||
$sec = round($sec / 60);
|
||||
$min = str_pad($sec % 60, 2, 0, STR_PAD_LEFT);
|
||||
$hours_min = floor($sec / 60);
|
||||
$min != 0 && $hours_min .= ':' . $min;
|
||||
|
||||
return $hours_min;
|
||||
}
|
||||
|
||||
public function encryptPhone($phone) {
|
||||
$maskedPhone = substr_replace($phone, '****', 3, 4);
|
||||
return $maskedPhone;
|
||||
}
|
||||
|
||||
//更改时间显示
|
||||
protected function format_date($time)
|
||||
{
|
||||
$t = time() - $time;
|
||||
$f = array(
|
||||
//'31536000'=>'年',
|
||||
//'2592000'=>'个月',
|
||||
//'604800'=>'星期',
|
||||
'86400' => '天',
|
||||
'3600' => '小时',
|
||||
'60' => '分钟',
|
||||
'1' => '秒'
|
||||
);
|
||||
foreach ($f as $k => $v) {
|
||||
if (0 != $c = floor($t / (int)$k)) {
|
||||
return $c . $v;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成用户token信息
|
||||
* @param int uid 用户id
|
||||
* @param string secret 盐值信息
|
||||
*/
|
||||
public function getToken($uid, $secret = 'bodybreakthrough'){
|
||||
//将签名密钥拼接到签名字符串最后面
|
||||
$str = $uid . $secret . time();
|
||||
//通过md5算法为签名字符串生成一个md5签名,该签名就是我们要追加的sign参数值
|
||||
return md5($str);
|
||||
}
|
||||
|
||||
public function get_access_token()
|
||||
{
|
||||
$appid = 'wxd5a3c4538c00a549';
|
||||
$secret = '6f3cd9ac49b8501f1db38e2f5f11bfd6';
|
||||
$url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" . $appid . "&secret=" . $secret;
|
||||
$result = file_get_contents($url);
|
||||
|
||||
$data = json_decode($result, true);
|
||||
|
||||
if ($data['access_token']) {
|
||||
return $data['access_token'];
|
||||
} else {
|
||||
return $data['errmsg'];
|
||||
}
|
||||
}
|
||||
|
||||
public function _requestPost($url, $data, $ssl = true)
|
||||
{
|
||||
//curl完成
|
||||
$curl = curl_init();
|
||||
//设置curl选项
|
||||
curl_setopt($curl, CURLOPT_URL, $url); //URL
|
||||
$user_agent = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:38.0) Gecko/20100101 Firefox/38.0 FirePHP/0.7.4';
|
||||
curl_setopt($curl, CURLOPT_USERAGENT, $user_agent); //user_agent,请求代理信息
|
||||
curl_setopt($curl, CURLOPT_AUTOREFERER, true); //referer头,请求来源
|
||||
curl_setopt($curl, CURLOPT_TIMEOUT, 30); //设置超时时间
|
||||
//SSL相关
|
||||
if ($ssl) {
|
||||
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); //禁用后cURL将终止从服务端进行验证
|
||||
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 2); //检查服务器SSL证书中是否存在一个公用名(common name)。
|
||||
}
|
||||
// 处理post相关选项
|
||||
curl_setopt($curl, CURLOPT_POST, true); // 是否为POST请求
|
||||
curl_setopt($curl, CURLOPT_POSTFIELDS, $data); // 处理请求数据
|
||||
// 处理响应结果
|
||||
curl_setopt($curl, CURLOPT_HEADER, false); //是否处理响应头
|
||||
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); //curl_exec()是否返回响应结果
|
||||
// 发出请求
|
||||
$response = curl_exec($curl);
|
||||
if (false === $response) {
|
||||
echo '<br>', curl_error($curl), '<br>';
|
||||
return false;
|
||||
}
|
||||
curl_close($curl);
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断微信图片
|
||||
*/
|
||||
public function judge_wx_pic($id)
|
||||
{
|
||||
$headimg = AttachmentModel::where('id', $id)->value('path');
|
||||
if (!strstr($headimg, 'http')) {
|
||||
$headimg = $this->getFileUrl($id);
|
||||
}
|
||||
return $headimg;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据经纬度和半径计算出范围
|
||||
* @param string $lat 纬度
|
||||
* @param String $lng 经度
|
||||
* @param float $radius 半径(单位米)
|
||||
* @return Array 范围数组
|
||||
*/
|
||||
public function calcScope($lat, $lng, $radius)
|
||||
{
|
||||
$radius = $radius * 1000;
|
||||
$degree = (24901 * 1609) / 360.0;
|
||||
$dpmLat = 1 / $degree;
|
||||
|
||||
$radiusLat = $dpmLat * $radius;
|
||||
$minLat = $lat - $radiusLat; // 最小纬度
|
||||
$maxLat = $lat + $radiusLat; // 最大纬度
|
||||
|
||||
$mpdLng = $degree * cos($lat * (pi() / 180));
|
||||
$dpmLng = 1 / $mpdLng;
|
||||
$radiusLng = $dpmLng * $radius;
|
||||
$minLng = $lng - $radiusLng; // 最小经度
|
||||
$maxLng = $lng + $radiusLng; // 最大经度
|
||||
|
||||
/** 返回范围数组 */
|
||||
$scope = array(
|
||||
'minLat' => $minLat,
|
||||
'maxLat' => $maxLat,
|
||||
'minLng' => $minLng,
|
||||
'maxLng' => $maxLng
|
||||
);
|
||||
return $scope;
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算两个经纬度之间的距离
|
||||
*/
|
||||
function distance($lat1, $lon1, $lat2, $lon2)
|
||||
{
|
||||
$radius = 6378.137;
|
||||
$rad = floatval(M_PI / 180.0);
|
||||
|
||||
$lat1 = floatval($lat1) * $rad;
|
||||
$lon1 = floatval($lon1) * $rad;
|
||||
$lat2 = floatval($lat2) * $rad;
|
||||
$lon2 = floatval($lon2) * $rad;
|
||||
|
||||
$theta = $lon2 - $lon1;
|
||||
|
||||
$dist = acos(sin($lat1) * sin($lat2) + cos($lat1) * cos($lat2) * cos($theta));
|
||||
|
||||
if ($dist < 0) {
|
||||
$dist += M_PI;
|
||||
}
|
||||
return $dist = $dist * $radius;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param $latitude 纬度
|
||||
* @param $longitude 经度
|
||||
* @param $raidus 半径范围(单位:米)
|
||||
* @return multitype:number
|
||||
*/
|
||||
public function getAround($latitude,$longitude,$raidus){
|
||||
$PI = 3.14159265;
|
||||
$degree = (24901*1609)/360.0;
|
||||
$dpmLat = 1/$degree;
|
||||
$radiusLat = $dpmLat*$raidus;
|
||||
$minLat = $latitude - $radiusLat;
|
||||
$maxLat = $latitude + $radiusLat;
|
||||
$mpdLng = $degree*cos($latitude * ($PI/180));
|
||||
$dpmLng = 1 / $mpdLng;
|
||||
$radiusLng = $dpmLng*$raidus;
|
||||
$minLng = $longitude - $radiusLng;
|
||||
$maxLng = $longitude + $radiusLng;
|
||||
|
||||
return [
|
||||
'minLat'=>$minLat,
|
||||
'maxLat'=>$maxLat,
|
||||
'minLng'=>$minLng,
|
||||
'maxLng'=>$maxLng
|
||||
];
|
||||
}
|
||||
|
||||
//根据秒数转换时分秒
|
||||
function secondsToHMS($seconds) {
|
||||
$hours = gmdate("H", $seconds);
|
||||
$minutes = gmdate("i", $seconds);
|
||||
$seconds = gmdate("s", $seconds);
|
||||
|
||||
$hours = !empty(intval($hours))?$hours.'时':null;
|
||||
$minutes = !empty(intval($minutes))?$minutes.'分':null;
|
||||
$seconds = !empty(intval($seconds))?$seconds.'秒':null;
|
||||
|
||||
return $hours.$minutes.$seconds;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,493 @@
|
|||
<?php
|
||||
namespace app\api\controller;
|
||||
|
||||
use think\Db;
|
||||
use \think\Loader;
|
||||
use think\helper\Hash;
|
||||
use Qrcode\Compress;
|
||||
use EasyWeChat\Factory;
|
||||
use EasyWeChat\MiniProgram;
|
||||
use think\facade\Config;
|
||||
use app\admin\model\Attachment as AttachmentModel;
|
||||
use app\member\model\Member as MemberModel;
|
||||
use app\member\model\MemberService as MemberServiceModel;
|
||||
use app\member\model\MemberServiceDetail as MemberServiceDetailModel;
|
||||
use app\other\model\ProductCategory as ProductCategoryModel;
|
||||
use app\other\model\Citys as CitysModel;
|
||||
use app\other\model\Advert as AdvertModel;
|
||||
use app\member\model\MemberShareLogs as MemberShareLogsModel;
|
||||
use app\member\model\MemberServiceOrder as MemberServiceOrderModel;
|
||||
use app\member\model\MemberBalanceLogs as MemberBalanceLogsModel;
|
||||
use app\member\model\MemberMessages as MemberMessagesModel;
|
||||
|
||||
/**
|
||||
* 公共接口
|
||||
* @package app\api\controller
|
||||
*/
|
||||
class Index extends Api
|
||||
{
|
||||
|
||||
//初始化
|
||||
public function initialize(){
|
||||
parent::initialize();
|
||||
}
|
||||
|
||||
/**
|
||||
* 首页
|
||||
* @param $string $keyword 搜索(搜索城市)
|
||||
* @param $int $cityid 城市id
|
||||
* @param int $page 页数(默认为1,每页显示20条数据)
|
||||
* @author loomis<2477365162@qq.com>
|
||||
*/
|
||||
public function index(){
|
||||
//传参数据
|
||||
$data_list = $this->params;
|
||||
|
||||
//首页广告图片
|
||||
$indexadvert = AdvertModel::where(['type'=>1])->field('id,linkurl,thumb')->select()->toArray();
|
||||
if(!empty($indexadvert)){
|
||||
foreach ($indexadvert as $k=>$v){
|
||||
$indexadvert[$k]['thumb'] = $this->getFileUrl($v['thumb']);
|
||||
}
|
||||
}
|
||||
|
||||
//公告
|
||||
$indexnotice = MemberServiceDetailModel::field('id,title')->select()->toArray();
|
||||
|
||||
//城市数据
|
||||
$citylist = CitysModel::where('is_delete',0)->order('sort asc,create_time desc')->field('id,thumb,title')->select()->toArray();
|
||||
if(!empty($citylist)){
|
||||
foreach ($citylist as $k=>$v){
|
||||
$citylist[$k]['thumb'] = $this->getFileUrl($v['thumb']);
|
||||
}
|
||||
}
|
||||
|
||||
//置顶搭子群数据
|
||||
$topgroups = MemberServiceModel::where(['is_index'=>1,'is_delete'=>0])->order('sort asc,create_time desc')->field('id,index_thumb,index_title')->select()->toArray();
|
||||
if(!empty($topgroups)){
|
||||
foreach ($topgroups as $k=>$v){
|
||||
$topgroups[$k]['index_thumb'] = $this->getFileUrl($v['index_thumb']);
|
||||
}
|
||||
}
|
||||
|
||||
//页数
|
||||
$page = 1;
|
||||
if(isset($data_list['page'])){
|
||||
$page = intval($data_list['page']);
|
||||
}
|
||||
$page = ($page-1);
|
||||
$page=$page*20;
|
||||
$limit=$page.',20';
|
||||
|
||||
//搭子群数据
|
||||
$where = [];
|
||||
$where[] = ['is_delete','eq',0];
|
||||
$where[] = ['id','neq',12];
|
||||
if(isset($data_list['keyword']) && !empty($data_list['keyword'])){
|
||||
$keyword = trim($data_list['keyword']);
|
||||
$where2 = [];
|
||||
$where2[] = ['is_delete','eq',0];
|
||||
$where2[] = ['title','like',"%$keyword%"];
|
||||
$ids = CitysModel::where($where2)->column('id');
|
||||
$ids = implode(',',$ids);
|
||||
$where[] = ['cityid','in',$ids];
|
||||
}
|
||||
if(isset($data_list['cityid']) && !empty($data_list['cityid'])){
|
||||
$cityid = intval($data_list['cityid']);
|
||||
$where[] = ['cityid','eq',$cityid];
|
||||
}
|
||||
$groups = MemberServiceModel::where($where)->order('sort asc,create_time desc')->field('id,title,summary,thumb')->limit($limit)->select()->toArray();
|
||||
if(!empty($groups)){
|
||||
foreach ($groups as $k=>$v){
|
||||
$groups[$k]['thumb'] = $this->getFileUrl($v['thumb']);
|
||||
}
|
||||
}
|
||||
|
||||
//浏览数
|
||||
$numberviews = MemberServiceModel::where('is_delete',0)->sum('browse');
|
||||
//发布
|
||||
$sendnum = MemberServiceModel::where('is_delete',0)->count();
|
||||
//用户数
|
||||
$usernum = MemberModel::where('is_delete',0)->count();
|
||||
|
||||
$indexfootadvert = AdvertModel::where(['type'=>4])->field('id,linkurl,thumb')->find();
|
||||
$indexfootadvert['thumb'] = $this->getFileUrl($indexfootadvert['thumb']);
|
||||
|
||||
apiReturn('200', '查询成功',[
|
||||
'indexadvert'=>$indexadvert,
|
||||
'indexnotice'=>$indexnotice,
|
||||
'citylist'=>$citylist,
|
||||
'topgroups'=>$topgroups,
|
||||
'groups'=>$groups,
|
||||
'numberviews'=>$numberviews,//浏览数
|
||||
'sendnum'=>$sendnum,//发布数
|
||||
'usernum'=>$usernum,//用户数
|
||||
'indexfootadvert' => $indexfootadvert,
|
||||
]);
|
||||
}
|
||||
|
||||
public function getindexfootadinfo(){
|
||||
|
||||
$indexfootadvert = AdvertModel::where(['type'=>4])->find();
|
||||
|
||||
$img2arr = explode(',',$indexfootadvert['img2']);
|
||||
$randomElement = $img2arr[array_rand($img2arr)];
|
||||
|
||||
$randomElement = $this->getFileUrl($randomElement);
|
||||
$backgroundimage = $this->getFileUrl($indexfootadvert['img1']);
|
||||
|
||||
apiReturn('200', '查询成功',[
|
||||
'randomElement'=>$randomElement,
|
||||
'backgroundimage'=>$backgroundimage,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 搭子群详情
|
||||
* @param $groupid 群id
|
||||
* @author loomis<2477365162@qq.com>
|
||||
*/
|
||||
public function groupdetail(){
|
||||
//传参数据
|
||||
$data_list = $this->params;
|
||||
|
||||
if(!isset($data_list['groupid']) || empty($data_list['groupid'])){
|
||||
apiReturn('500', '群id不能为空');
|
||||
}
|
||||
|
||||
$groupid = intval($data_list['groupid']);
|
||||
$info = MemberServiceModel::where(['id'=>$groupid,'is_delete'=>0])->find();
|
||||
if(empty($info)){
|
||||
apiReturn('500', '未查询到相关群信息');
|
||||
}
|
||||
|
||||
$type=1;
|
||||
$qrcodeimg = '';
|
||||
if(!empty(MemberServiceOrderModel::where(['service_id'=>$groupid,'uid'=>$this->user_id,'status'=>2])->count())){
|
||||
$type = 2;
|
||||
$qrcodeimg = $info['qrcodeimg'];
|
||||
}
|
||||
|
||||
$strs = 'https://'.$_SERVER['HTTP_HOST'].'/uploads/';
|
||||
$message = str_replace("/uploads/", $strs, $info['message']);
|
||||
|
||||
$info->browse = $info->browse+1;
|
||||
$info->save();
|
||||
|
||||
apiReturn('200', '查询成功',[
|
||||
'id'=>$groupid,
|
||||
'type'=>$type,
|
||||
'qrcodeimg'=>$this->getFileUrl($qrcodeimg),
|
||||
'title'=>$info['title'],
|
||||
'thumb'=>$this->getFileUrl($info['thumb']),
|
||||
'create_time'=>date('Y-m-d H:i:s',$info['create_time']),
|
||||
'summary'=>$info['summary'],
|
||||
'standard'=>$info['standard'],
|
||||
'message'=>$message,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 购买搭子群二维码
|
||||
* @param $groupid 群id
|
||||
* @author loomis<2477365162@qq.com>
|
||||
*/
|
||||
public function buygroup(){
|
||||
//传参数据
|
||||
$data_list = $this->params;
|
||||
|
||||
if(!isset($data_list['groupid']) || empty($data_list['groupid'])){
|
||||
apiReturn('500', '群id不能为空');
|
||||
}
|
||||
|
||||
$groupid = intval($data_list['groupid']);
|
||||
$info = MemberServiceModel::where(['id'=>$groupid,'is_delete'=>0])->find();
|
||||
if(empty($info)){
|
||||
apiReturn('500', '未查询到相关群信息');
|
||||
}
|
||||
|
||||
$orderinfo = MemberServiceOrderModel::where(['type'=>1,'uid'=>$this->user_id,'service_id'=>intval($data_list['groupid']),'status'=>2])->find();
|
||||
if(!empty($orderinfo)){
|
||||
return json(['code' => 500, 'msg' => '此群二维码用户已经购买,请勿重复购买']);
|
||||
}else{
|
||||
//生成订单号
|
||||
$numRes = true;
|
||||
do{
|
||||
$ordernum = 'O'.date('ymd').$this->user_id.rand(100,999);
|
||||
$count = MemberServiceOrderModel::where(['ordernum'=>$ordernum])->count();
|
||||
if(empty($count)) {
|
||||
$numRes=false;
|
||||
}
|
||||
}while($numRes);
|
||||
|
||||
$totalprice = $info['price'];
|
||||
|
||||
$res = MemberServiceOrderModel::create([
|
||||
'type'=>1,
|
||||
'uid'=>$this->user_id,
|
||||
'ordernum'=>$ordernum,
|
||||
'service_id'=>intval($data_list['groupid']),
|
||||
'totalprice'=>$totalprice,
|
||||
'status'=>1,
|
||||
'create_time'=>time(),
|
||||
'timeout_time'=>time()+600,
|
||||
'service_title'=>$info['title'],
|
||||
'service_summary'=>$info['summary'],
|
||||
'service_price'=>$info['price'],
|
||||
'service_thumb'=>$info['qrcodeimg'],
|
||||
]);
|
||||
}
|
||||
|
||||
if($res){
|
||||
//微信小程序支付回调地址
|
||||
$notify_url = 'https://' . $_SERVER['HTTP_HOST'] . url('api/wxpaynotify/index');
|
||||
|
||||
$config = [
|
||||
// 必要配置
|
||||
'app_id' => config('smallprogram_appid'),
|
||||
'mch_id' => config('wxpay_mchid'),
|
||||
'key' => config('wxpay_paykey'), // API v2 密钥 (注意: 是v2密钥 是v2密钥 是v2密钥)
|
||||
|
||||
// 如需使用敏感接口(如退款、发送红包等)需要配置 API 证书路径(登录商户平台下载 API 证书)
|
||||
'cert_path' => get_file_path(config('wxpay_appclient_cert')), // XXX: 绝对路径!!!!
|
||||
'key_path' => get_file_path(config('wxpay_appclient_key')), // XXX: 绝对路径!!!!
|
||||
'notify_url' => $notify_url, // 你也可以在下单时单独设置来覆盖它
|
||||
];
|
||||
|
||||
$total_fee = $totalprice * 100;
|
||||
$app = Factory::payment($config);
|
||||
$jssdk = $app->jssdk;
|
||||
|
||||
if(empty($total_fee)){
|
||||
$total_fee = 1;
|
||||
}
|
||||
|
||||
//下单
|
||||
$result = $app->order->unify([
|
||||
'body' => 'DAZIQUN',
|
||||
'out_trade_no' => $ordernum,
|
||||
'total_fee' => $total_fee,
|
||||
'spbill_create_ip' => '', // 可选,如不传该参数,SDK 将会自动获取相应 IP 地址
|
||||
'notify_url' => $notify_url, // 支付结果通知网址,如果不设置则会使用配置里的默认地址
|
||||
'trade_type' => 'JSAPI', // 请对应换成你的支付方式对应的值类型
|
||||
'openid' => MemberModel::where(['id' => $this->user_id])->value('openid'),
|
||||
]);
|
||||
|
||||
//组合参数
|
||||
$pay = $jssdk->bridgeConfig($result['prepay_id'], false); // 返回数组
|
||||
|
||||
return json(['code' => 200, 'msg' => '微信支付信息','result'=>$pay]);
|
||||
}else{
|
||||
return json(['code' => 500, 'msg' => '服务器繁忙,请稍后再试']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 留言板
|
||||
* @param $int $type 1男生通道 2女生通道
|
||||
* @param int $page 页数(默认为1,每页显示20条数据)
|
||||
* @author loomis<2477365162@qq.com>
|
||||
*/
|
||||
public function messageboard(){
|
||||
//传参数据
|
||||
$data_list = $this->params;
|
||||
|
||||
//页数
|
||||
$page = 1;
|
||||
if(isset($data_list['page'])){
|
||||
$page = intval($data_list['page']);
|
||||
}
|
||||
$page = ($page-1);
|
||||
$page=$page*20;
|
||||
$limit=$page.',20';
|
||||
|
||||
//留言板数据
|
||||
$where = [];
|
||||
$where[] = ['status','eq',1];
|
||||
|
||||
$type=1;
|
||||
if(isset($data_list['type']) && !empty($data_list['type'])){
|
||||
$type = intval($data_list['type']);
|
||||
}
|
||||
$where[] = ['type','eq',$type];
|
||||
$list = MemberMessagesModel::where($where)->order('istop desc,create_time desc')->field('id,uid,message,thumbs,create_time,wechat_number')->limit($limit)->select()->toArray();
|
||||
if(!empty($list)){
|
||||
foreach ($list as $k=>$v){
|
||||
$thumbs = explode(',',$v['thumbs']);
|
||||
foreach ($thumbs as $key=>$val){
|
||||
$thumbs[$key] = $this->getFileUrl($val);
|
||||
}
|
||||
$list[$k]['thumbs'] = $thumbs;
|
||||
|
||||
//用户信息
|
||||
$userinfo = MemberModel::where('id',$v['uid'])->find();
|
||||
$list[$k]['headimg'] = $this->getFileUrl($userinfo['headimg']);
|
||||
$list[$k]['nickname'] = $userinfo['nickname'];
|
||||
|
||||
$list[$k]['create_time'] = date('Y-m-d H:i:s',$v['create_time']);
|
||||
|
||||
//用户是否购买此留言的微信号
|
||||
$isbuy = MemberBalanceLogsModel::where(['uid'=>$this->user_id,'orderid'=>$v['id'],'mark'=>'购买留言板留言信息微信号'])->count();
|
||||
|
||||
if($v['uid']==$this->user_id){
|
||||
$isbuy = 1;
|
||||
}
|
||||
|
||||
$list[$k]['isbuy'] = !empty($isbuy)?1:0;
|
||||
$list[$k]['wechat_number'] = !empty($isbuy)?$v['wechat_number']:"";
|
||||
}
|
||||
}
|
||||
|
||||
//广告图片
|
||||
$advertlist = AdvertModel::where(['type'=>2])->field('id,linkurl,thumb')->select()->toArray();
|
||||
if(!empty($advertlist)){
|
||||
foreach ($advertlist as $k=>$v){
|
||||
$advertlist[$k]['thumb'] = $this->getFileUrl($v['thumb']);
|
||||
}
|
||||
}
|
||||
|
||||
apiReturn('200', '查询成功',[
|
||||
'list'=>$list,
|
||||
'advert'=>$advertlist,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 发布留言-留言板置顶积分
|
||||
* @author loomis<2477365162@qq.com>
|
||||
*/
|
||||
public function gettoppoints(){
|
||||
apiReturn('200', '查询成功',[
|
||||
'levemeesga_points'=>config('levemeesga_points'),
|
||||
'levemessage_toppoints'=>config('levemessage_toppoints'),
|
||||
'levemessage_lookwechnum'=>config('levemessage_lookwechnum'),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 发布留言
|
||||
* @param $int $type 1男生通道 2女生通道
|
||||
* @param string $message 留言信息
|
||||
* @param string $thumbs 图片(多个图片请使用“,”进行拼接)
|
||||
* @param $int $istop 0默认 1置顶
|
||||
* @author loomis<2477365162@qq.com>
|
||||
*/
|
||||
public function sendmessage(){
|
||||
//传参数据
|
||||
$data_list = $this->params;
|
||||
|
||||
if (!isset($data_list['type']) || empty($data_list['type'])) {
|
||||
return json(['code' => 500, 'msg' => '请选择留言通道']);
|
||||
}
|
||||
if (!isset($data_list['message']) || empty($data_list['message'])) {
|
||||
return json(['code' => 500, 'msg' => '留言信息不能为空']);
|
||||
}
|
||||
if (!isset($data_list['thumbs']) || empty($data_list['thumbs'])) {
|
||||
return json(['code' => 500, 'msg' => '图片不能为空']);
|
||||
}
|
||||
if (!isset($data_list['wechat_number']) || empty($data_list['wechat_number'])) {
|
||||
return json(['code' => 500, 'msg' => '微信号不能为空']);
|
||||
}
|
||||
|
||||
$message = trim($data_list['message']);
|
||||
if($this->illegalcharacters($message)){
|
||||
apiReturn('500', '非法参数');
|
||||
}
|
||||
|
||||
$istop = 0;
|
||||
if (isset($data_list['istop']) && !empty($data_list['istop'])) {
|
||||
$istop = intval($data_list['istop']);
|
||||
}
|
||||
|
||||
//用户积分是否足够
|
||||
$userinfo = MemberModel::where('id',$this->user_id)->find();
|
||||
|
||||
$sendpoints = intval(config('levemeesga_points'));
|
||||
if($istop==1){
|
||||
$sendpoints = $sendpoints + intval(config('levemessage_toppoints'));
|
||||
}
|
||||
if($userinfo['balance']<$sendpoints){
|
||||
apiReturn('500', '发布失败,积分不足');
|
||||
}
|
||||
|
||||
$res = MemberMessagesModel::create([
|
||||
'uid'=>$this->user_id,
|
||||
'type'=>intval($data_list['type']),
|
||||
'message'=>trim($data_list['message']),
|
||||
'thumbs'=>trim($data_list['thumbs']),
|
||||
'wechat_number'=>trim($data_list['wechat_number']),
|
||||
'istop'=>$istop,
|
||||
]);
|
||||
|
||||
if ($res) {
|
||||
|
||||
//插入积分记录
|
||||
MemberBalanceLogsModel::addGetLog($this->user_id,2,$sendpoints,$res['id'],'发布留言');
|
||||
|
||||
//扣除积分
|
||||
$userinfo->balance = $userinfo->balance - $sendpoints;
|
||||
$userinfo->save();
|
||||
|
||||
apiReturn('200', '留言信息提交成功,等待平台审核');
|
||||
} else {
|
||||
apiReturn('500', '留言信息提交失败');
|
||||
}
|
||||
}
|
||||
|
||||
//用户购买留言板微信号
|
||||
public function buywechatnumber(){
|
||||
//传参数据
|
||||
$data_list = $this->params;
|
||||
|
||||
if (!isset($data_list['id']) || empty($data_list['id'])) {
|
||||
return json(['code' => 500, 'msg' => '留言id不能为空']);
|
||||
}
|
||||
|
||||
$id = intval($data_list['id']);
|
||||
$info = MemberMessagesModel::where('id',$id)->find();
|
||||
if(empty($info)){
|
||||
apiReturn('500', '未查询到留言板信息');
|
||||
}
|
||||
|
||||
//用户是否购买此留言的微信号
|
||||
$isbuy = MemberBalanceLogsModel::where(['uid'=>$this->user_id,'orderid'=>$id,'mark'=>'查看留言板微信号'])->count();
|
||||
if(!empty($isbuy)){
|
||||
apiReturn('500', '您已购买过此留言的微信号');
|
||||
}
|
||||
|
||||
//扣除积分
|
||||
$userinfo = MemberModel::where('id',$this->user_id)->find();
|
||||
$levemessage_lookwechnum = intval(config('levemessage_lookwechnum'));
|
||||
if($userinfo['balance']<$levemessage_lookwechnum){
|
||||
apiReturn('500', '购买失败,积分不足');
|
||||
}
|
||||
|
||||
//插入积分记录
|
||||
MemberBalanceLogsModel::addGetLog($this->user_id,2,$levemessage_lookwechnum,$id,'购买留言板留言信息微信号');
|
||||
|
||||
//扣除积分
|
||||
$userinfo->balance = $userinfo->balance - $levemessage_lookwechnum;
|
||||
$userinfo->save();
|
||||
|
||||
//反馈积分
|
||||
$fankuio_points_num = $levemessage_lookwechnum * (config('levemessage_lookwechnumfan')/100);
|
||||
$fankuio_points_num = round($fankuio_points_num);
|
||||
if($fankuio_points_num<=0){
|
||||
$fankuio_points_num = 1;
|
||||
}
|
||||
|
||||
$message_userinfo = MemberModel::where('id',$info['uid'])->find();
|
||||
$message_userinfo->balance = $message_userinfo->balance + $fankuio_points_num;
|
||||
$message_userinfo->save();
|
||||
|
||||
//插入积分记录
|
||||
MemberBalanceLogsModel::addGetLog($info['uid'],1,$fankuio_points_num,$id,'留言板微信号反馈积分');
|
||||
|
||||
apiReturn('200', '购买成功');
|
||||
}
|
||||
|
||||
//获取购买微信好需要消耗的积分数
|
||||
public function getbuywxnumjf(){
|
||||
apiReturn('200', '查询成功',['jfnum'=>config('levemessage_lookwechnum')]);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,122 @@
|
|||
<?php
|
||||
namespace app\api\controller;
|
||||
|
||||
use think\Db;
|
||||
use \think\Loader;
|
||||
use think\helper\Hash;
|
||||
use EasyWeChat\Factory;
|
||||
use EasyWeChat\MiniProgram;
|
||||
use think\facade\Config;
|
||||
use app\member\model\Member as MemberModel;
|
||||
|
||||
|
||||
/**
|
||||
* 登录注册接口
|
||||
* @package app\api\controller
|
||||
*/
|
||||
class Login extends Api
|
||||
{
|
||||
|
||||
//初始化
|
||||
public function initialize(){
|
||||
parent::initialize();
|
||||
|
||||
$config = [
|
||||
'app_id' => config('smallprogram_appid'),
|
||||
'secret' => config('smallprogram_appsecret'),
|
||||
];
|
||||
$this->app = Factory::miniProgram($config);
|
||||
}
|
||||
|
||||
/**
|
||||
* 登录凭证校验
|
||||
* @param string $js_code 登录时获取的 code
|
||||
*/
|
||||
public function loginCodeCheck()
|
||||
{
|
||||
//传参数据
|
||||
$data_list = $this->params;
|
||||
|
||||
if (!isset($data_list['js_code']) || empty($data_list['js_code'])) {
|
||||
apiReturn(500,'js_code不能为空');
|
||||
}
|
||||
|
||||
$config = [
|
||||
'app_id' => config('smallprogram_appid'),
|
||||
'secret' => config('smallprogram_appsecret'),
|
||||
// 下面为可选项
|
||||
// 指定 API 调用返回结果的类型:array(default)/collection/object/raw/自定义类名
|
||||
'response_type' => 'array',
|
||||
|
||||
'log' => [
|
||||
'level' => 'debug',
|
||||
'file' => __DIR__ . '/wechat.log',
|
||||
],
|
||||
];
|
||||
$app = Factory::miniProgram($config);
|
||||
$wx_user_info = $app->auth->session($data_list['js_code']);
|
||||
|
||||
$member_info = MemberModel::where(['openid' => $wx_user_info['openid']])->find();
|
||||
|
||||
//新用户
|
||||
if (empty($member_info)) {
|
||||
|
||||
//生成会员编号
|
||||
$numRes = true;
|
||||
do{
|
||||
$finallymember = MemberModel::order('create_time desc')->find();
|
||||
if(!empty($finallymember)){
|
||||
$member_number = $finallymember['member_number']+1;
|
||||
}else{
|
||||
$member_number = 100001;
|
||||
}
|
||||
$count = MemberModel::where(['member_number'=>$member_number])->count();
|
||||
if(empty($count)) {
|
||||
$numRes=false;
|
||||
}
|
||||
}while($numRes);
|
||||
|
||||
//添加数据并返回主键
|
||||
$res = MemberModel::create([
|
||||
'member_number'=>$member_number,
|
||||
'openid' => $wx_user_info['openid'],
|
||||
'lastlogin_time' => time(),
|
||||
'lastlogin_ip' => get_client_ip(0),
|
||||
'login_num' => 1,
|
||||
]);
|
||||
|
||||
//生成token
|
||||
$user_token = $this->getToken($res['id']);
|
||||
|
||||
$res2 = MemberModel::update(['userToken' => $user_token], ['id' => $res['id']]);
|
||||
|
||||
if ($res && $res2) {
|
||||
apiReturn(200,'绑定成功',['user_token' => $user_token]);
|
||||
} else {
|
||||
apiReturn(500,'绑定失败');
|
||||
}
|
||||
} else {
|
||||
if ($member_info['is_delete'] != 0) {
|
||||
apiReturn(500,'此账号被禁用或删除');
|
||||
}
|
||||
|
||||
//登录是否超时(一周登录时间)
|
||||
$time_compa= abs(time() - $member_info['lastlogin_time']);
|
||||
if ($time_compa > 604800) {
|
||||
|
||||
//生成token
|
||||
$user_token = $this->getToken($member_info['id']);
|
||||
// 更新登录信息及token信息
|
||||
$member_info->userToken = $user_token;
|
||||
$member_info->lastlogin_time = time();
|
||||
$member_info->lastlogin_ip = get_client_ip(1);
|
||||
$member_info->login_num = $member_info->login_num + 1;
|
||||
$member_info->save();
|
||||
}else{
|
||||
$user_token = $member_info['userToken'];
|
||||
}
|
||||
|
||||
apiReturn(200,'登录成功',['user_token' => $user_token]);
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,158 @@
|
|||
<?php
|
||||
namespace app\api\controller;
|
||||
|
||||
use think\Db;
|
||||
use \think\Loader;
|
||||
use think\helper\Hash;
|
||||
use Qrcode\Compress;
|
||||
use app\admin\model\Attachment as AttachmentModel;
|
||||
|
||||
/**
|
||||
* 公共接口
|
||||
* @package app\api\controller
|
||||
*/
|
||||
class Uploadfile extends Api
|
||||
{
|
||||
|
||||
//初始化
|
||||
public function initialize(){
|
||||
parent::initialize();
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传图片
|
||||
* @param file $imgfile 图片文件
|
||||
* @author loomis<2477365162@qq.com>
|
||||
*/
|
||||
public function uploadimgfile(){
|
||||
|
||||
$file = request()->file('imgfile');
|
||||
// 移动到框架应用根目录 /public/uploads/ 目录下'size'=>15678,
|
||||
$info = $file->validate(['ext' => 'jpg,png,gif,jpeg'])->move($_SERVER['DOCUMENT_ROOT'] . '/uploads/xcximg');
|
||||
if ($info) {
|
||||
$source = $_SERVER['DOCUMENT_ROOT'] . '/uploads/xcximg/' . date('Ymd') . '/' . $info->getFilename();
|
||||
$percent = 0.5; #缩放比例
|
||||
(new Compress($source, $percent))->compressImg($source); //压缩
|
||||
|
||||
// 成功上传后 获取上传信息
|
||||
$data['uid'] = 0;
|
||||
$data['path'] = 'uploads/xcximg/' . date('Ymd') . '/' . $info->getFilename();
|
||||
$data["md5"] = md5($data['path']);
|
||||
$data["sha1"] = sha1($data['path']);
|
||||
$data['name'] = $info->getFilename();
|
||||
$data['ext'] = $info->getExtension();
|
||||
$data['size'] = $info->getSize();
|
||||
$data['category'] = 2;
|
||||
$data['create_time'] = time();
|
||||
$id = AttachmentModel::create($data);
|
||||
|
||||
return json(['code' => 200, 'msg' => '上传成功', 'result' => [
|
||||
'img_id' => $id['id'],
|
||||
'img_url' => $this->getFileUrl($id['id']),
|
||||
]]);
|
||||
} else {
|
||||
// 上传失败获取信息
|
||||
return json(['code' => 500, 'msg' => $file->getError()]);
|
||||
}
|
||||
}
|
||||
|
||||
//上传视频
|
||||
public function uploadvideofile() {
|
||||
|
||||
$file = request()->file('videofile');
|
||||
// 移动到框架应用根目录/public/uploads/ 目录下'size'=>15678,
|
||||
$info = $file->validate(['ext' => 'mp4'])->move($_SERVER['DOCUMENT_ROOT'] . '/uploads/xcxvideo');
|
||||
if($info){
|
||||
// 成功上传后 获取上传信息
|
||||
$data['uid'] = 0;
|
||||
$data['path'] = 'uploads/xcxvideo/' . date('Ymd') . '/' . $info->getFilename();
|
||||
$data["md5"] = md5($data['path']);
|
||||
$data["sha1"] = sha1($data['path']);
|
||||
$data['name'] = $info->getFilename();
|
||||
$data['ext'] = $info->getExtension();
|
||||
$data['size'] = $info->getSize();
|
||||
$data['category'] = 2;
|
||||
$data['create_time'] = time();
|
||||
$id = AttachmentModel::create($data);
|
||||
|
||||
return json(['code' => 200, 'msg' => '上传成功', 'result' => [
|
||||
'video_id' => $id['id'],
|
||||
'video_url' => $this->getFileUrl($id['id']),
|
||||
]]);
|
||||
} else {
|
||||
// 上传失败获取信息
|
||||
return json(['code' => 500, 'msg' => $file->getError()]);
|
||||
}
|
||||
}
|
||||
|
||||
//接收签名图片
|
||||
public function uploadsigninimgfile(){
|
||||
$filedata = $this->request->param(); //传参
|
||||
$file = $filedata['imgfile'];
|
||||
|
||||
header('Content-type:text/html;charset=utf-8');
|
||||
$base64_image_content = trim($file);
|
||||
//正则匹配出图片的格式
|
||||
if (preg_match('/^(data:\s*image\/(\w+);base64,)/', $base64_image_content, $result)) {
|
||||
$type = $result[2];//图片后缀
|
||||
|
||||
$new_file = $_SERVER['DOCUMENT_ROOT'] . '/uploads/xcximg/'.date('Ymd').'/';
|
||||
|
||||
|
||||
if (!file_exists($new_file)) {
|
||||
//检查是否有该文件夹,如果没有就创建,并给予最高权限
|
||||
mkdir($new_file, 0700);
|
||||
}
|
||||
|
||||
$filename = time() . '_' . uniqid() . ".{$type}"; //文件名
|
||||
$new_file = $new_file . $filename;
|
||||
|
||||
//写入操作
|
||||
if (file_put_contents($new_file, base64_decode(str_replace($result[1], '', $base64_image_content)))) {
|
||||
|
||||
// 成功上传后 获取上传信息
|
||||
$data['uid'] = 0;
|
||||
$data['path'] = 'uploads/xcximg/' . date('Ymd') . '/' . $filename;
|
||||
$data["md5"] = md5($data['path']);
|
||||
$data["sha1"] = sha1($data['path']);
|
||||
$data['name'] = $filename;
|
||||
$data['ext'] = $type;
|
||||
$data['size'] = 0;
|
||||
$data['category'] = 2;
|
||||
$data['create_time'] = time();
|
||||
$id = AttachmentModel::create($data);
|
||||
|
||||
return json(['code' => 200, 'msg' => '上传成功', 'result' => [
|
||||
'img_id' => $id['id'],
|
||||
'img_url' => $this->getFileUrl($id['id']),
|
||||
]]);
|
||||
} else {
|
||||
return json(['code' => 500, 'msg' => '上传失败']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getimg($imgsrc){
|
||||
list($src_w,$src_h,$src_info) = getimagesize($imgsrc);
|
||||
switch ($src_info){
|
||||
case 2:
|
||||
$createtype = 'imagecreatefromjpeg';
|
||||
$headertype = 'imagejpeg';
|
||||
break;
|
||||
case 1:
|
||||
$createtype = 'imagecreatefromgif';
|
||||
$headertype = 'imagegif';
|
||||
break;
|
||||
case 3:
|
||||
$createtype = 'imagecreatefrompng';
|
||||
$headertype = 'imagepng';
|
||||
break;
|
||||
default:
|
||||
$createtype = 'imagecreatefromjpeg';
|
||||
$headertype = 'imagejpeg';
|
||||
break;
|
||||
}
|
||||
$src=$createtype($imgsrc);
|
||||
return $src;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,247 @@
|
|||
<?php
|
||||
|
||||
namespace app\api\controller;
|
||||
|
||||
use think\Db;
|
||||
use \think\Loader;
|
||||
use think\helper\Hash;
|
||||
use Qrcode\Compress;
|
||||
use EasyWeChat\Factory;
|
||||
use app\api\controller\SendMail;
|
||||
use app\member\model\Member as MemberModel;
|
||||
use app\member\model\MemberServiceOrder as MemberServiceOrderModel;
|
||||
use app\member\model\MemberBalanceLogs as MemberBalanceLogsModel;
|
||||
use app\activity\model\MoneyTree as MoneyTreeModel;
|
||||
use app\activity\model\MoneyTreeLogs as MMoneyTreeLogsModel;
|
||||
|
||||
/**
|
||||
* 微信支付回调接口
|
||||
* @package app\api\controller
|
||||
*/
|
||||
class Wxpaynotify extends Api{
|
||||
|
||||
//初始化
|
||||
public function initialize(){
|
||||
parent::initialize();
|
||||
}
|
||||
|
||||
/**
|
||||
* 微信支付异步回调
|
||||
* @author loomis<2477365162@qq.com>
|
||||
*/
|
||||
public function index(){
|
||||
|
||||
$config = [
|
||||
// 必要配置
|
||||
'app_id' => config('smallprogram_appid'),
|
||||
'mch_id' => config('wxpay_mchid'),
|
||||
'key' => config('wxpay_paykey'), // API v2 密钥 (注意: 是v2密钥 是v2密钥 是v2密钥)
|
||||
|
||||
// 如需使用敏感接口(如退款、发送红包等)需要配置 API 证书路径(登录商户平台下载 API 证书)
|
||||
'cert_path' => get_file_path(config('wxpay_appclient_cert')), // XXX: 绝对路径!!!!
|
||||
'key_path' => get_file_path(config('wxpay_appclient_key')), // XXX: 绝对路径!!!!
|
||||
];
|
||||
$app = Factory::payment($config);
|
||||
|
||||
$response = $app->handlePaidNotify(function ($message, $fail) {
|
||||
|
||||
// 使用通知里的 "微信支付订单号" 或者 "商户订单号" 去自己的数据库找到订单
|
||||
$ordernum = $message['out_trade_no'];
|
||||
$order = MemberServiceOrderModel::where(['ordernum'=>$ordernum])->find();
|
||||
if (!$order || $order['status'] == 2) { // 如果订单不存在 或者 订单已经支付过了
|
||||
return true; //已处理
|
||||
}
|
||||
|
||||
//微信:【订单查询】接口,确认已支付
|
||||
$config = [
|
||||
// 必要配置
|
||||
'app_id' => config('smallprogram_appid'),
|
||||
'mch_id' => config('wxpay_mchid'),
|
||||
'key' => config('wxpay_paykey'),
|
||||
];
|
||||
$app = Factory::payment($config);
|
||||
$wx_res = $app->order->queryByTransactionId($message['transaction_id']);
|
||||
|
||||
$weixinquery = serialize($wx_res);
|
||||
|
||||
if ($message['return_code'] === 'SUCCESS') { // return_code 表示通信状态,不代表支付状态
|
||||
//// 用户是否支付成功
|
||||
if (array_key_exists('result_code', $message) && $message['result_code'] === 'SUCCESS') {
|
||||
|
||||
//更新订单状态
|
||||
$orderinfo = MemberServiceOrderModel::where(['ordernum'=>$ordernum,'status'=>1])->find();
|
||||
if (!$orderinfo){
|
||||
return true;
|
||||
}
|
||||
if ($orderinfo['status'] != 1){
|
||||
return true;
|
||||
}
|
||||
|
||||
//购买群二维码
|
||||
if($orderinfo['type']==1){
|
||||
//进行积分发送
|
||||
$memberinfo = MemberModel::where('id',$orderinfo['uid'])->find();
|
||||
if(!empty($memberinfo['invitation_uid'])){
|
||||
|
||||
//一级发送积分
|
||||
if(!empty(config('one_integral'))){
|
||||
$one_invitation_uinfo = MemberModel::where('id',$memberinfo['invitation_uid'])->find();
|
||||
$points_num = $orderinfo['totalprice'] * (config('one_integral')/100);
|
||||
$points_num = round($points_num);
|
||||
if($points_num<=0){
|
||||
$points_num = 1;
|
||||
}
|
||||
MemberModel::where('id',$memberinfo['invitation_uid'])->setInc('balance',$points_num);
|
||||
//插入积分记录、
|
||||
MemberBalanceLogsModel::addGetLog($memberinfo['invitation_uid'],1,$points_num,$orderinfo['ordernum'],'一级分销反馈积分',$orderinfo['uid']);
|
||||
|
||||
//二级发送积分
|
||||
if(!empty($one_invitation_uinfo['invitation_uid']) && !empty(config('two_integral'))){
|
||||
$two_points_num = $orderinfo['totalprice'] * (config('two_integral')/100);
|
||||
$two_points_num = round($two_points_num);
|
||||
if($two_points_num<=0){
|
||||
$two_points_num = 1;
|
||||
}
|
||||
MemberModel::where('id',$one_invitation_uinfo['invitation_uid'])->setInc('balance',$two_points_num);
|
||||
//插入积分记录、
|
||||
MemberBalanceLogsModel::addGetLog($one_invitation_uinfo['invitation_uid'],1,$two_points_num,$orderinfo['ordernum'],'二级分销反馈积分',$orderinfo['uid']);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//积分充值
|
||||
if($orderinfo['type']==2){
|
||||
//充值成功,给用户增加积分
|
||||
MemberModel::where('id',$orderinfo['uid'])->setInc('balance',intval($orderinfo['service_title']));
|
||||
//插入积分记录、
|
||||
MemberBalanceLogsModel::addGetLog($orderinfo['uid'],1,intval($orderinfo['service_title']),$orderinfo['ordernum'],'用户充值积分');
|
||||
}
|
||||
|
||||
//购买vip
|
||||
if($orderinfo['type']==3){
|
||||
MemberModel::where('id',$orderinfo['uid'])->update([
|
||||
'vip_id'=>$orderinfo['service_thumb'],
|
||||
'vip_title'=>$orderinfo['service_title'],
|
||||
]);
|
||||
}
|
||||
|
||||
$res = MemberServiceOrderModel::where(['ordernum'=>$ordernum])->update([
|
||||
'status'=>2,
|
||||
'update_time'=>time(),
|
||||
'pay_time'=>time(),
|
||||
'pay_data' =>$weixinquery,
|
||||
]);
|
||||
|
||||
} elseif (array_key_exists('result_code', $message) && $message['result_code'] === 'FAIL') {
|
||||
// 用户支付失败
|
||||
return $fail('通信失败,请稍后再通知我');
|
||||
}
|
||||
} else {
|
||||
return $fail('通信失败,请稍后再通知我');
|
||||
}
|
||||
|
||||
return true; // 返回处理完成
|
||||
|
||||
});
|
||||
|
||||
$response->send();
|
||||
|
||||
}
|
||||
|
||||
|
||||
//取消超时未支付的订单
|
||||
public function cancelorder(){
|
||||
|
||||
$where = [];
|
||||
$where[] = ['timeout_time','elt',time()];
|
||||
$where[] = ['status','eq',1];
|
||||
|
||||
if(empty(MemberServiceOrderModel::where($where)->count())){
|
||||
return 'ok';
|
||||
}
|
||||
$res = MemberServiceOrderModel::where($where)->update(['status'=>3]);
|
||||
if($res){
|
||||
return 'ok';
|
||||
}else{
|
||||
return 'fail';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//用户协议
|
||||
public function useragreement(){
|
||||
|
||||
$useragreementmsg = config('useragreement');
|
||||
|
||||
//商品详情
|
||||
$strs = 'https://'.$_SERVER['HTTP_HOST'].'/uploads/';
|
||||
$useragreementmsg= str_replace("/uploads/", $strs, $useragreementmsg);
|
||||
|
||||
return json(['code' => 200, 'msg' => '查询成功','result'=>$useragreementmsg]);
|
||||
}
|
||||
|
||||
//隐私政策
|
||||
public function privacypolicy(){
|
||||
|
||||
$useragreementmsg = config('privacypolicy');
|
||||
|
||||
//商品详情
|
||||
$strs = 'https://'.$_SERVER['HTTP_HOST'].'/uploads/';
|
||||
$useragreementmsg= str_replace("/uploads/", $strs, $useragreementmsg);
|
||||
|
||||
return json(['code' => 200, 'msg' => '查询成功','result'=>$useragreementmsg]);
|
||||
}
|
||||
|
||||
//摇钱树产生金币
|
||||
public function moneytree(){
|
||||
$userlist = MemberModel::where('is_delete',0)->select();
|
||||
if(!empty($userlist)){
|
||||
foreach ($userlist as $k=>$v){
|
||||
|
||||
//存在未领取金币用户不持续产生金币
|
||||
$wlqjinbi = MMoneyTreeLogsModel::where(['uid'=>$v['id'],'status'=>1])->count();
|
||||
if(!empty($wlqjinbi)){
|
||||
continue;
|
||||
}
|
||||
|
||||
//无邀请用户的用户不产生金币
|
||||
$invitation_num = MemberModel::where(['invitation_uid'=>$v['id'],'is_delete'=>0])->count();
|
||||
if(empty($invitation_num)){
|
||||
continue;
|
||||
}
|
||||
|
||||
//根据用户分享人数,获得对应积分
|
||||
$integral_num = MoneyTreeModel::getintegralnum($invitation_num);
|
||||
//根据用户分享人数,获得摇钱树等级
|
||||
$tree_grade = MoneyTreeModel::gettreegrade($invitation_num);
|
||||
if(empty($integral_num) || empty($tree_grade)){
|
||||
continue;
|
||||
}
|
||||
|
||||
$is_generate = 0;
|
||||
$create_time = MMoneyTreeLogsModel::where(['uid'=>$v['id']])->order('create_time desc')->value('create_time');
|
||||
if(!empty($create_time)){
|
||||
$create_time = $create_time + 86400;
|
||||
if($create_time<=time()){
|
||||
$is_generate = 1;
|
||||
}
|
||||
}else{
|
||||
$is_generate = 1;
|
||||
}
|
||||
|
||||
if($is_generate==1){
|
||||
MMoneyTreeLogsModel::create([
|
||||
'uid'=>$v['id'],
|
||||
'tree_grade'=>$tree_grade,
|
||||
'integral_num'=>$integral_num,
|
||||
'create_time'=>time(),
|
||||
'update_time'=>time(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
echo 'ok';
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,15 @@
|
|||
<?php
|
||||
/** * 模块信息 */
|
||||
return [
|
||||
// 模块名[必填]
|
||||
'name' => 'api',
|
||||
// 模块标题[必填]
|
||||
'title' => 'API',
|
||||
// 模块唯一标识[必填],格式:模块名.开发者标识.module
|
||||
'identifier' => 'api.ccu.module',
|
||||
// 开发者[必填]
|
||||
'author' => 'Maurylee',
|
||||
// 版本[必填],格式采用三段式:主版本号.次版本号.修订版本号
|
||||
'version' => '1.0.0',
|
||||
// 模块描述[必填]
|
||||
'description' => 'api模块',];
|
|
@ -0,0 +1,306 @@
|
|||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | 海豚PHP框架 [ DolphinPHP ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 版权所有 2016~2019 广东卓锐软件有限公司 [ http://www.zrthink.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网站: http://dolphinphp.com
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace app\cms\admin;
|
||||
|
||||
use app\admin\controller\Admin;
|
||||
use app\common\builder\ZBuilder;
|
||||
use app\cms\model\Advert as AdvertModel;
|
||||
use app\cms\model\AdvertType as AdvertTypeModel;
|
||||
use think\facade\Validate;
|
||||
|
||||
/**
|
||||
* 广告控制器
|
||||
* @package app\cms\admin
|
||||
*/
|
||||
class Advert extends Admin
|
||||
{
|
||||
/**
|
||||
* 广告列表
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return mixed
|
||||
* @throws \think\Exception
|
||||
* @throws \think\exception\DbException
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
// 查询
|
||||
$map = $this->getMap();
|
||||
// 排序
|
||||
$order = $this->getOrder('update_time desc');
|
||||
// 数据列表
|
||||
$data_list = AdvertModel::where($map)->order($order)->paginate();
|
||||
|
||||
$btnType = [
|
||||
'class' => 'btn btn-info',
|
||||
'title' => '广告分类',
|
||||
'icon' => 'fa fa-fw fa-sitemap',
|
||||
'href' => url('advert_type/index')
|
||||
];
|
||||
|
||||
$list_type = AdvertTypeModel::where('status', 1)->column('id,name');
|
||||
array_unshift($list_type, '默认分类');
|
||||
|
||||
// 使用ZBuilder快速创建数据表格
|
||||
return ZBuilder::make('table')
|
||||
->setSearch(['title' => '标题']) // 设置搜索框
|
||||
->addColumns([ // 批量添加数据列
|
||||
['id', 'ID'],
|
||||
['name', '广告名称', 'text.edit'],
|
||||
['typeid', '分类', 'select', $list_type],
|
||||
['ad_type', '类型', 'text', '', ['代码', '文字', '图片', 'flash']],
|
||||
['timeset', '时间限制', 'text', '', ['永不过期', '限时']],
|
||||
['create_time', '创建时间', 'datetime'],
|
||||
['update_time', '更新时间', 'datetime'],
|
||||
['status', '状态', 'switch'],
|
||||
['right_button', '操作', 'btn']
|
||||
])
|
||||
->addTopButtons('add,enable,disable,delete') // 批量添加顶部按钮
|
||||
->addTopButton('custom', $btnType) // 添加顶部按钮
|
||||
->addRightButtons(['edit', 'delete' => ['data-tips' => '删除后无法恢复。']]) // 批量添加右侧按钮
|
||||
->addOrder('id,name,typeid,timeset,ad_type,create_time,update_time')
|
||||
->setRowList($data_list) // 设置表格数据
|
||||
->addValidate('Advert', 'name')
|
||||
->fetch(); // 渲染模板
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return mixed
|
||||
* @throws \think\Exception
|
||||
*/
|
||||
public function add()
|
||||
{
|
||||
// 保存数据
|
||||
if ($this->request->isPost()) {
|
||||
// 表单数据
|
||||
$data = $this->request->post();
|
||||
|
||||
// 验证
|
||||
$result = $this->validate($data, 'Advert');
|
||||
if (true !== $result) $this->error($result);
|
||||
if ($data['ad_type'] != 0) {
|
||||
$data['link'] == '' && $this->error('链接不能为空');
|
||||
Validate::is($data['link'], 'url') === false && $this->error('链接不是有效的url地址'); // true
|
||||
}
|
||||
|
||||
// 广告类型
|
||||
switch ($data['ad_type']) {
|
||||
case 0: // 代码
|
||||
$data['content'] = $data['code'];
|
||||
break;
|
||||
case 1: // 文字
|
||||
$data['content'] = '<a href="'.$data['link'].'" target="_blank" style="';
|
||||
if ($data['size'] != '') {
|
||||
$data['content'] .= 'font-size:'.$data['size'].'px;';
|
||||
}
|
||||
if ($data['color'] != '') {
|
||||
$data['content'] .= 'color:'.$data['color'];
|
||||
}
|
||||
$data['content'] .= '">'.$data['title'].'</a>';
|
||||
break;
|
||||
case 2: // 图片
|
||||
$data['content'] = '<a href="'.$data['link'].'" target="_blank"><img src="'.get_file_path($data['src']).'" style="';
|
||||
if ($data['width'] != '') {
|
||||
$data['content'] .= 'width:'.$data['width'].'px;';
|
||||
}
|
||||
if ($data['height'] != '') {
|
||||
$data['content'] .= 'height:'.$data['height'].'px;';
|
||||
}
|
||||
if ($data['alt'] != '') {
|
||||
$data['content'] .= '" alt="'.$data['alt'];
|
||||
}
|
||||
$data['content'] .= '" /></a>';
|
||||
break;
|
||||
case 3: // flash
|
||||
$data['content'] = '';
|
||||
$data['content'] = '<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"';
|
||||
if ($data['width'] != '') {
|
||||
$data['content'] .= ' width="'.$data['width'].'"';
|
||||
}
|
||||
if ($data['height'] != '') {
|
||||
$data['content'] .= ' height="'.$data['height'].'"';
|
||||
}
|
||||
$data['content'] .= '><param name="quality" value="high" /><param name="movie" value="'.$data['link'].'" /><embed allowfullscreen="true"';
|
||||
if ($data['height'] != '') {
|
||||
$data['content'] .= ' height="'.$data['height'].'"';
|
||||
}
|
||||
$data['content'] .= ' pluginspage="http://www.macromedia.com/go/getflashplayer" quality="high" src="'.$data['link'].'" type="application/x-shockwave-flash"';
|
||||
if ($data['width'] != '') {
|
||||
$data['content'] .= ' width="'.$data['width'].'"';
|
||||
}
|
||||
$data['content'] .= '></embed></object>';
|
||||
break;
|
||||
}
|
||||
|
||||
if ($advert = AdvertModel::create($data)) {
|
||||
// 记录行为
|
||||
action_log('advert_add', 'cms_advert', $advert['id'], UID, $data['name']);
|
||||
$this->success('新增成功', 'index');
|
||||
} else {
|
||||
$this->error('新增失败');
|
||||
}
|
||||
}
|
||||
|
||||
$list_type = AdvertTypeModel::where('status', 1)->column('id,name');
|
||||
array_unshift($list_type, '默认分类');
|
||||
|
||||
// 显示添加页面
|
||||
return ZBuilder::make('form')
|
||||
->setPageTips('如果出现无法添加的情况,可能由于浏览器将本页面当成了广告,请尝试关闭浏览器的广告过滤功能再试。', 'warning')
|
||||
->addFormItems([
|
||||
['select', 'typeid', '广告分类', '', $list_type, 0],
|
||||
['text', 'tagname', '广告位标识', '由小写字母、数字或下划线组成,不能以数字开头'],
|
||||
['text', 'name', '广告位名称'],
|
||||
['radio', 'timeset', '时间限制', '', ['永不过期', '在设内时间内有效'], 0],
|
||||
['daterange', 'start_time,end_time', '开始时间-结束时间'],
|
||||
['radio', 'ad_type', '广告类型', '', ['代码', '文字', '图片', 'flash'], 0],
|
||||
['textarea', 'code', '代码', '<code>必填</code>,支持html代码'],
|
||||
['image', 'src', '图片', '<code>必须</code>'],
|
||||
['text', 'title', '文字内容', '<code>必填</code>'],
|
||||
['text', 'link', '链接', '<code>必填</code>'],
|
||||
['colorpicker', 'color', '文字颜色', '', '', 'rgb'],
|
||||
['text', 'size', '文字大小', '只需填写数字,例如:12,表示12px', '', ['', 'px']],
|
||||
['text', 'width', '宽度', '不用填写单位,只需填写具体数字'],
|
||||
['text', 'height', '高度', '不用填写单位,只需填写具体数字'],
|
||||
['text', 'alt', '图片描述', '即图片alt的值'],
|
||||
['radio', 'status', '立即启用', '', ['否', '是'], 1]
|
||||
])
|
||||
->setTrigger('ad_type', '0', 'code')
|
||||
->setTrigger('ad_type', '1', 'title,color,size')
|
||||
->setTrigger('ad_type', '2', 'src,alt')
|
||||
->setTrigger('ad_type', '2,3', 'width,height')
|
||||
->setTrigger('ad_type', '1,2,3', 'link')
|
||||
->setTrigger('timeset', '1', 'start_time')
|
||||
->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑
|
||||
* @param null $id 广告id
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return mixed
|
||||
* @throws \think\Exception
|
||||
*/
|
||||
public function edit($id = null)
|
||||
{
|
||||
if ($id === null) $this->error('缺少参数');
|
||||
|
||||
// 保存数据
|
||||
if ($this->request->isPost()) {
|
||||
// 表单数据
|
||||
$data = $this->request->post();
|
||||
|
||||
// 验证
|
||||
$result = $this->validate($data, 'Advert');
|
||||
if (true !== $result) $this->error($result);
|
||||
|
||||
if (AdvertModel::update($data)) {
|
||||
// 记录行为
|
||||
action_log('advert_edit', 'cms_advert', $id, UID, $data['name']);
|
||||
$this->success('编辑成功', 'index');
|
||||
} else {
|
||||
$this->error('编辑失败');
|
||||
}
|
||||
}
|
||||
|
||||
$list_type = AdvertTypeModel::where('status', 1)->column('id,name');
|
||||
array_unshift($list_type, '默认分类');
|
||||
|
||||
$info = AdvertModel::get($id);
|
||||
$info['ad_type'] = ['代码', '文字', '图片', 'flash'][$info['ad_type']];
|
||||
|
||||
// 显示编辑页面
|
||||
return ZBuilder::make('form')
|
||||
->setPageTips('如果出现无法添加的情况,可能由于浏览器将本页面当成了广告,请尝试关闭浏览器的广告过滤功能再试。', 'warning')
|
||||
->addFormItems([
|
||||
['hidden', 'id'],
|
||||
['hidden', 'tagname'],
|
||||
['static', 'tagname', '广告位标识'],
|
||||
['static', 'ad_type', '广告类型'],
|
||||
['text', 'name', '广告位名称'],
|
||||
['select', 'typeid', '广告分类', '', $list_type],
|
||||
['radio', 'timeset', '时间限制', '', ['永不过期', '在设内时间内有效']],
|
||||
['daterange', 'start_time,end_time', '开始时间-结束时间'],
|
||||
['textarea', 'content', '广告内容'],
|
||||
['radio', 'status', '立即启用', '', ['否', '是']]
|
||||
])
|
||||
->setTrigger('timeset', '1', 'start_time')
|
||||
->setFormData($info)
|
||||
->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除广告
|
||||
* @param array $record 行为日志
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @throws \think\Exception
|
||||
* @throws \think\exception\PDOException
|
||||
*/
|
||||
public function delete($record = [])
|
||||
{
|
||||
return $this->setStatus('delete');
|
||||
}
|
||||
|
||||
/**
|
||||
* 启用广告
|
||||
* @param array $record 行为日志
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @throws \think\Exception
|
||||
* @throws \think\exception\PDOException
|
||||
*/
|
||||
public function enable($record = [])
|
||||
{
|
||||
return $this->setStatus('enable');
|
||||
}
|
||||
|
||||
/**
|
||||
* 禁用广告
|
||||
* @param array $record 行为日志
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @throws \think\Exception
|
||||
* @throws \think\exception\PDOException
|
||||
*/
|
||||
public function disable($record = [])
|
||||
{
|
||||
return $this->setStatus('disable');
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置广告状态:删除、禁用、启用
|
||||
* @param string $type 类型:delete/enable/disable
|
||||
* @param array $record
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @throws \think\Exception
|
||||
* @throws \think\exception\PDOException
|
||||
*/
|
||||
public function setStatus($type = '', $record = [])
|
||||
{
|
||||
$ids = $this->request->isPost() ? input('post.ids/a') : input('param.ids');
|
||||
$advert_name = AdvertModel::where('id', 'in', $ids)->column('name');
|
||||
return parent::setStatus($type, ['advert_'.$type, 'cms_advert', 0, UID, implode('、', $advert_name)]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 快速编辑
|
||||
* @param array $record 行为日志
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return mixed
|
||||
*/
|
||||
public function quickEdit($record = [])
|
||||
{
|
||||
$id = input('post.pk', '');
|
||||
$field = input('post.name', '');
|
||||
$value = input('post.value', '');
|
||||
$advert = AdvertModel::where('id', $id)->value($field);
|
||||
$details = '字段(' . $field . '),原值(' . $advert . '),新值:(' . $value . ')';
|
||||
return parent::quickEdit(['advert_edit', 'cms_advert', $id, UID, $details]);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,204 @@
|
|||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | 海豚PHP框架 [ DolphinPHP ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 版权所有 2016~2019 广东卓锐软件有限公司 [ http://www.zrthink.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网站: http://dolphinphp.com
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace app\cms\admin;
|
||||
|
||||
use app\admin\controller\Admin;
|
||||
use app\common\builder\ZBuilder;
|
||||
use app\cms\model\AdvertType as AdvertTypeModel;
|
||||
|
||||
/**
|
||||
* 广告分类控制器
|
||||
* @package app\cms\admin
|
||||
*/
|
||||
class AdvertType extends Admin
|
||||
{
|
||||
/**
|
||||
* 广告列表
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return mixed
|
||||
* @throws \think\Exception
|
||||
* @throws \think\exception\DbException
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
// 查询
|
||||
$map = $this->getMap();
|
||||
// 排序
|
||||
$order = $this->getOrder('update_time desc');
|
||||
// 数据列表
|
||||
$data_list = AdvertTypeModel::where($map)->order($order)->paginate();
|
||||
|
||||
// 使用ZBuilder快速创建数据表格
|
||||
return ZBuilder::make('table')
|
||||
->setSearch(['name' => '分类名称']) // 设置搜索框
|
||||
->addColumns([ // 批量添加数据列
|
||||
['id', 'ID'],
|
||||
['name', '分类名称', 'text.edit'],
|
||||
['create_time', '创建时间', 'datetime'],
|
||||
['update_time', '更新时间', 'datetime'],
|
||||
['status', '状态', 'switch'],
|
||||
['right_button', '操作', 'btn']
|
||||
])
|
||||
->setTableName('cms_advert_type')
|
||||
->addTopButton('back', ['href' => url('advert/index')]) // 批量添加顶部按钮
|
||||
->addTopButtons('add,enable,disable,delete') // 批量添加顶部按钮
|
||||
->addRightButtons(['edit', 'delete' => ['data-tips' => '删除后无法恢复。']]) // 批量添加右侧按钮
|
||||
->addOrder('id,name,create_time,update_time')
|
||||
->setRowList($data_list) // 设置表格数据
|
||||
->addValidate('AdvertType', 'name')
|
||||
->fetch(); // 渲染模板
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return mixed
|
||||
* @throws \think\Exception
|
||||
*/
|
||||
public function add()
|
||||
{
|
||||
// 保存数据
|
||||
if ($this->request->isPost()) {
|
||||
// 表单数据
|
||||
$data = $this->request->post();
|
||||
|
||||
// 验证
|
||||
$result = $this->validate($data, 'AdvertType');
|
||||
if(true !== $result) $this->error($result);
|
||||
|
||||
if ($type = AdvertTypeModel::create($data)) {
|
||||
// 记录行为
|
||||
action_log('advert_type_add', 'cms_advert_type', $type['id'], UID, $data['name']);
|
||||
$this->success('新增成功', 'index');
|
||||
} else {
|
||||
$this->error('新增失败');
|
||||
}
|
||||
}
|
||||
|
||||
// 显示添加页面
|
||||
return ZBuilder::make('form')
|
||||
->setPageTips('如果出现无法添加的情况,可能由于浏览器将本页面当成了广告,请尝试关闭浏览器的广告过滤功能再试。', 'warning')
|
||||
->addFormItems([
|
||||
['text', 'name', '分类名称'],
|
||||
['radio', 'status', '立即启用', '', ['否', '是'], 1]
|
||||
])
|
||||
->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑
|
||||
* @param null $id
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return mixed
|
||||
* @throws \think\Exception
|
||||
*/
|
||||
public function edit($id = null)
|
||||
{
|
||||
if ($id === null) $this->error('缺少参数');
|
||||
|
||||
// 保存数据
|
||||
if ($this->request->isPost()) {
|
||||
// 表单数据
|
||||
$data = $this->request->post();
|
||||
|
||||
// 验证
|
||||
$result = $this->validate($data, 'AdvertType');
|
||||
if(true !== $result) $this->error($result);
|
||||
|
||||
if (AdvertTypeModel::update($data)) {
|
||||
// 记录行为
|
||||
action_log('advert_type_edit', 'cms_advert_type', $id, UID, $data['name']);
|
||||
$this->success('编辑成功', 'index');
|
||||
} else {
|
||||
$this->error('编辑失败');
|
||||
}
|
||||
}
|
||||
|
||||
$info = AdvertTypeModel::get($id);
|
||||
|
||||
// 显示编辑页面
|
||||
return ZBuilder::make('form')
|
||||
->setPageTips('如果出现无法编辑的情况,可能由于浏览器将本页面当成了广告,请尝试关闭浏览器的广告过滤功能再试。', 'warning')
|
||||
->addFormItems([
|
||||
['hidden', 'id'],
|
||||
['text', 'name', '分类名称'],
|
||||
['radio', 'status', '立即启用', '', ['否', '是']]
|
||||
])
|
||||
->setFormdata($info)
|
||||
->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除广告分类
|
||||
* @param array $record 行为日志
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @throws \think\Exception
|
||||
* @throws \think\exception\PDOException
|
||||
*/
|
||||
public function delete($record = [])
|
||||
{
|
||||
return $this->setStatus('delete');
|
||||
}
|
||||
|
||||
/**
|
||||
* 启用广告分类
|
||||
* @param array $record 行为日志
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @throws \think\Exception
|
||||
* @throws \think\exception\PDOException
|
||||
*/
|
||||
public function enable($record = [])
|
||||
{
|
||||
return $this->setStatus('enable');
|
||||
}
|
||||
|
||||
/**
|
||||
* 禁用广告分类
|
||||
* @param array $record 行为日志
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @throws \think\Exception
|
||||
* @throws \think\exception\PDOException
|
||||
*/
|
||||
public function disable($record = [])
|
||||
{
|
||||
return $this->setStatus('disable');
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置广告分类状态:删除、禁用、启用
|
||||
* @param string $type 类型:delete/enable/disable
|
||||
* @param array $record 日志记录
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @throws \think\Exception
|
||||
* @throws \think\exception\PDOException
|
||||
*/
|
||||
public function setStatus($type = '', $record = [])
|
||||
{
|
||||
$ids = $this->request->isPost() ? input('post.ids/a') : input('param.ids');
|
||||
$type_name = AdvertTypeModel::where('id', 'in', $ids)->column('name');
|
||||
return parent::setStatus($type, ['advert_type_'.$type, 'cms_advert_type', 0, UID, implode('、', $type_name)]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 快速编辑
|
||||
* @param array $record 行为日志
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return mixed
|
||||
*/
|
||||
public function quickEdit($record = [])
|
||||
{
|
||||
$id = input('post.pk', '');
|
||||
$field = input('post.name', '');
|
||||
$value = input('post.value', '');
|
||||
$type = AdvertTypeModel::where('id', $id)->value($field);
|
||||
$details = '字段(' . $field . '),原值(' . $type . '),新值:(' . $value . ')';
|
||||
return parent::quickEdit(['advert_type_edit', 'cms_advert_type', $id, UID, $details]);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,287 @@
|
|||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | 海豚PHP框架 [ DolphinPHP ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 版权所有 2016~2019 广东卓锐软件有限公司 [ http://www.zrthink.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网站: http://dolphinphp.com
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace app\cms\admin;
|
||||
|
||||
use app\admin\controller\Admin;
|
||||
use app\common\builder\ZBuilder;
|
||||
use app\cms\model\Model as DocumentModel;
|
||||
use app\cms\model\Column as ColumnModel;
|
||||
use app\cms\model\Document;
|
||||
use app\user\model\Role as RoleModel;
|
||||
use util\Tree;
|
||||
use util\File;
|
||||
use think\facade\Env;
|
||||
|
||||
/**
|
||||
* 栏目控制器
|
||||
* @package app\cms\admin
|
||||
*/
|
||||
class Column extends Admin
|
||||
{
|
||||
/**
|
||||
* 栏目列表
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return mixed
|
||||
* @throws \think\Exception
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
// 查询
|
||||
$map = $this->getMap();
|
||||
|
||||
// 数据列表
|
||||
$data_list = ColumnModel::where($map)->column(true);
|
||||
if (empty($map)) {
|
||||
$data_list = Tree::config(['title' => 'name'])->toList($data_list);
|
||||
}
|
||||
|
||||
// 自定义按钮
|
||||
$btnMove = [
|
||||
'class' => 'btn btn-xs btn-default js-move-column',
|
||||
'icon' => 'fa fa-fw fa-arrow-circle-right',
|
||||
'title' => '移动栏目'
|
||||
];
|
||||
$btnAdd = [
|
||||
'class' => 'btn btn-xs btn-default',
|
||||
'icon' => 'fa fa-fw fa-plus',
|
||||
'title' => '新增子栏目',
|
||||
'href' => url('add', ['pid' => '__id__'])
|
||||
];
|
||||
|
||||
// 使用ZBuilder快速创建数据表格
|
||||
return ZBuilder::make('table')
|
||||
->setSearch(['name' => '栏目名称']) // 设置搜索框
|
||||
->addColumns([ // 批量添加数据列
|
||||
['id', 'ID'],
|
||||
['icon', '图标', 'icon'],
|
||||
['name', '栏目名称', 'callback', function($value, $data){
|
||||
return isset($data['title_prefix']) ? $data['title_display'] : $value;
|
||||
}, '__data__'],
|
||||
['model', '内容模型', 'select', DocumentModel::getTitleList()],
|
||||
['rank_auth', '浏览权限', 'select', RoleModel::getTree(null, '开放浏览')],
|
||||
['hide', '是否隐藏', 'yesno'],
|
||||
['post_auth', '支持投稿', 'yesno'],
|
||||
['create_time', '创建时间', 'datetime'],
|
||||
['sort', '排序', 'text.edit'],
|
||||
['status', '状态', 'switch'],
|
||||
['right_button', '操作', 'btn']
|
||||
])
|
||||
->addTopButtons('add,enable,disable') // 批量添加顶部按钮
|
||||
->addRightButton('custom', $btnAdd)
|
||||
->addRightButton('edit') // 添加右侧按钮
|
||||
// ->addRightButton('custom', $btnMove)
|
||||
->addRightButton('delete', ['data-tips' => '删除栏目前,请确保无子栏目和文档!']) // 添加右侧按钮
|
||||
->setRowList($data_list) // 设置表格数据
|
||||
->fetch(); // 渲染模板
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增栏目
|
||||
* @param int $pid 父级id
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return mixed
|
||||
* @throws \think\Exception
|
||||
*/
|
||||
public function add($pid = 0)
|
||||
{
|
||||
// 保存数据
|
||||
if ($this->request->isPost()) {
|
||||
// 表单数据
|
||||
$data = $this->request->post();
|
||||
|
||||
// 验证
|
||||
$result = $this->validate($data, 'Column');
|
||||
if(true !== $result) $this->error($result);
|
||||
|
||||
if ($column = ColumnModel::create($data)) {
|
||||
cache('cms_column_list', null);
|
||||
// 记录行为
|
||||
action_log('column_add', 'cms_column', $column['id'], UID, $data['name']);
|
||||
$this->success('新增成功', 'index');
|
||||
} else {
|
||||
$this->error('新增失败');
|
||||
}
|
||||
}
|
||||
|
||||
$template_list = File::get_dirs(Env::get('app_path').'cms/view/column/')['file'];
|
||||
$template_detail = File::get_dirs(Env::get('app_path').'cms/view/document/')['file'];
|
||||
|
||||
// 显示添加页面
|
||||
return ZBuilder::make('form')
|
||||
->addFormItems([
|
||||
['select', 'pid', '所属栏目', '<span class="text-danger">必选</span>', ColumnModel::getTreeList(), $pid],
|
||||
['text', 'name', '栏目名称', '<span class="text-danger">必填</span>'],
|
||||
['radio', 'model', '内容模型', '<span class="text-danger">必选</span>', DocumentModel::getTitleList()],
|
||||
['radio', 'type', '栏目属性', '', ['最终列表栏目', '外部链接'], 0],
|
||||
['text', 'url', '链接', '可以填写完整的url,如:<code>http://www.dolphinphp.com</code>,也可以填写 <code>模块/控制器/操作</code>,如:<code>cms/index/index</code>'],
|
||||
['radio', 'target', '打开方式', '', ['_self' => '当前窗口', '_blank' => '新窗口'], '_self'],
|
||||
// ['select', 'index_template', '封面页模板', '可选'],
|
||||
['select', 'list_template', '列表页模板', '可选,模板目录: <code>cms/view/column</code>', parse_array($template_list)],
|
||||
['select', 'detail_template', '详情页模板', '可选,模板目录: <code>cms/view/document</code>', parse_array($template_detail)],
|
||||
['ckeditor', 'content', '栏目内容', '可作为单页使用'],
|
||||
['icon', 'icon', '图标'],
|
||||
['radio', 'post_auth', '是否支持投稿', '是否允许前台用户投稿', ['禁止投稿', '允许投稿'], 1],
|
||||
['radio', 'hide', '是否隐藏栏目', '隐藏后前台不可见', ['显示', '隐藏'], 0],
|
||||
['select', 'rank_auth', '浏览权限', '', RoleModel::getTree(null, '开放浏览'), 0],
|
||||
['radio', 'status', '立即启用', '', ['否', '是'], 1],
|
||||
['text', 'sort', '排序', '', 100],
|
||||
])
|
||||
->setTrigger('type', '0,2', 'index_template,list_template,detail_template')
|
||||
->setTrigger('type', '1', 'url,target')
|
||||
->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑栏目
|
||||
* @param string $id 栏目id
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return mixed
|
||||
* @throws \think\Exception
|
||||
*/
|
||||
public function edit($id = '')
|
||||
{
|
||||
if ($id === 0) $this->error('参数错误');
|
||||
|
||||
// 保存数据
|
||||
if ($this->request->isPost()) {
|
||||
$data = $this->request->post();
|
||||
|
||||
// 验证
|
||||
$result = $this->validate($data, 'Column');
|
||||
// 验证失败 输出错误信息
|
||||
if(true !== $result) $this->error($result);
|
||||
|
||||
if (ColumnModel::update($data)) {
|
||||
// 记录行为
|
||||
action_log('column_edit', 'cms_column', $id, UID, $data['name']);
|
||||
$this->success('编辑成功', 'index');
|
||||
} else {
|
||||
$this->error('编辑失败');
|
||||
}
|
||||
}
|
||||
|
||||
// 获取数据
|
||||
$info = ColumnModel::get($id);
|
||||
|
||||
$template_list = File::get_dirs(Env::get('app_path').'cms/view/column/')['file'];
|
||||
$template_detail = File::get_dirs(Env::get('app_path').'cms/view/document/')['file'];
|
||||
|
||||
// 显示编辑页面
|
||||
return ZBuilder::make('form')
|
||||
->addFormItems([
|
||||
['hidden', 'id'],
|
||||
['select', 'pid', '所属栏目', '<span class="text-danger">必选</span>', ColumnModel::getTreeList($id)],
|
||||
['text', 'name', '栏目名称', '<span class="text-danger">必填</span>'],
|
||||
['radio', 'model', '内容模型', '<span class="text-danger">必选</span>', DocumentModel::getTitleList()],
|
||||
['radio', 'type', '栏目属性', '', ['最终列表栏目', '外部链接'], 0],
|
||||
['text', 'url', '链接', '可以填写完整的url,如:<code>http://www.dolphinphp.com</code>,也可以填写 <code>模块/控制器/操作</code>,如:<code>cms/index/index</code>'],
|
||||
['radio', 'target', '打开方式', '', ['_self' => '当前窗口', '_blank' => '新窗口'], '_self'],
|
||||
// ['select', 'index_template', '封面页模板', '可选'],
|
||||
['select', 'list_template', '列表页模板', '可选,模板目录: <code>cms/view/column</code>', parse_array($template_list)],
|
||||
['select', 'detail_template', '详情页模板', '可选,模板目录: <code>cms/view/document</code>', parse_array($template_detail)],
|
||||
['ckeditor', 'content', '栏目内容', '可作为单页使用'],
|
||||
['icon', 'icon', '图标'],
|
||||
['radio', 'post_auth', '是否支持投稿', '是否允许前台用户投稿', ['禁止投稿', '允许投稿']],
|
||||
['radio', 'hide', '是否隐藏栏目', '隐藏后前台不可见', ['显示', '隐藏'], 0],
|
||||
['select', 'rank_auth', '浏览权限', '', RoleModel::getTree(null, '开放浏览')],
|
||||
['radio', 'status', '立即启用', '', ['否', '是']],
|
||||
['text', 'sort', '排序'],
|
||||
])
|
||||
->setTrigger('type', '0,2', 'index_template,list_template,detail_template')
|
||||
->setTrigger('type', '1', 'url,target')
|
||||
->setFormData($info)
|
||||
->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除栏目
|
||||
* @param null $ids 栏目id
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @throws \think\Exception
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @throws \think\exception\DbException
|
||||
* @throws \think\exception\PDOException
|
||||
*/
|
||||
public function delete($ids = null)
|
||||
{
|
||||
if ($ids === null) $this->error('参数错误');
|
||||
|
||||
// 检查是否有子栏目
|
||||
if (ColumnModel::where('pid', $ids)->find()) {
|
||||
$this->error('请先删除或移动该栏目下的子栏目');
|
||||
}
|
||||
|
||||
// 检查是否有文档
|
||||
if (Document::where('cid', $ids)->find()) {
|
||||
$this->error('请先删除或移动该栏目下的所有文档');
|
||||
}
|
||||
|
||||
// 删除并记录日志
|
||||
$column_name = get_column_name($ids);
|
||||
return parent::delete(['column_delete', 'cms_column', 0, UID, $column_name]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 启用栏目
|
||||
* @param array $record 行为日志
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @throws \think\Exception
|
||||
* @throws \think\exception\PDOException
|
||||
*/
|
||||
public function enable($record = [])
|
||||
{
|
||||
return $this->setStatus('enable');
|
||||
}
|
||||
|
||||
/**
|
||||
* 禁用栏目
|
||||
* @param array $record 行为日志
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @throws \think\Exception
|
||||
* @throws \think\exception\PDOException
|
||||
*/
|
||||
public function disable($record = [])
|
||||
{
|
||||
return $this->setStatus('disable');
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置栏目状态:删除、禁用、启用
|
||||
* @param string $type 类型:enable/disable
|
||||
* @param array $record
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @throws \think\Exception
|
||||
* @throws \think\exception\PDOException
|
||||
*/
|
||||
public function setStatus($type = '', $record = [])
|
||||
{
|
||||
$ids = $this->request->isPost() ? input('post.ids/a') : input('param.ids');
|
||||
$column_delete = is_array($ids) ? '' : $ids;
|
||||
$column_names = ColumnModel::where('id', 'in', $ids)->column('name');
|
||||
return parent::setStatus($type, ['column_'.$type, 'cms_column', $column_delete, UID, implode('、', $column_names)]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 快速编辑
|
||||
* @param array $record 行为日志
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return mixed
|
||||
*/
|
||||
public function quickEdit($record = [])
|
||||
{
|
||||
$id = input('post.pk', '');
|
||||
$field = input('post.name', '');
|
||||
$value = input('post.value', '');
|
||||
$column = ColumnModel::where('id', $id)->value($field);
|
||||
$details = '字段(' . $field . '),原值(' . $column . '),新值:(' . $value . ')';
|
||||
return parent::quickEdit(['column_edit', 'cms_column', $id, UID, $details]);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,137 @@
|
|||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | 海豚PHP框架 [ DolphinPHP ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 版权所有 2016~2019 广东卓锐软件有限公司 [ http://www.zrthink.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网站: http://dolphinphp.com
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace app\cms\admin;
|
||||
|
||||
use app\admin\controller\Admin;
|
||||
use app\common\builder\ZBuilder;
|
||||
use app\cms\model\Document;
|
||||
use think\Db;
|
||||
|
||||
/**
|
||||
* 内容控制器
|
||||
* @package app\cms\admin
|
||||
*/
|
||||
class Content extends Admin
|
||||
{
|
||||
/**
|
||||
* 空操作,用于显示各个模型的文档列表
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return mixed
|
||||
* @throws \think\Exception
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @throws \think\exception\DbException
|
||||
*/
|
||||
public function _empty()
|
||||
{
|
||||
cookie('__forward__', $_SERVER['REQUEST_URI']);
|
||||
$model_name = $this->request->action();
|
||||
$model = Db::name('cms_model')->where('name', $model_name)->find();
|
||||
if (!$model) $this->error('找不到该内容');
|
||||
|
||||
// 独立模型
|
||||
if ($model['type'] == 2) {
|
||||
$table_name = substr($model['table'], strlen(config('database.prefix')));
|
||||
|
||||
// 查询
|
||||
$map = $this->getMap();
|
||||
$map[] = ['trash', '=', 0];
|
||||
|
||||
// 排序
|
||||
$order = $this->getOrder('update_time desc');
|
||||
// 数据列表
|
||||
$data_list = Db::view($table_name, true)
|
||||
->view("cms_column", ['name' => 'column_name'], 'cms_column.id='.$table_name.'.cid', 'left')
|
||||
->view("admin_user", 'username', 'admin_user.id='.$table_name.'.uid', 'left')
|
||||
->where($map)
|
||||
->order($order)
|
||||
->paginate();
|
||||
|
||||
$trash_count = Db::table($model['table'])->where('trash', 1)->count();
|
||||
|
||||
// 自定义按钮
|
||||
$btnRecycle = [
|
||||
'title' => '回收站('.$trash_count.')',
|
||||
'icon' => 'fa fa-trash',
|
||||
'class' => 'btn btn-info',
|
||||
'href' => url('recycle/index', ['model' => $model['id']])
|
||||
];
|
||||
$columns = Db::name('cms_column')->where(['model' => $model['id']])->column('id,name');
|
||||
|
||||
// 使用ZBuilder快速创建数据表格
|
||||
return ZBuilder::make('table')
|
||||
->setSearch(['title' => '标题', 'cms_column.name' => '栏目名称']) // 设置搜索框
|
||||
->addColumns([ // 批量添加数据列
|
||||
['id', 'ID'],
|
||||
['title', '标题'],
|
||||
['cid', '栏目名称', 'select', $columns],
|
||||
['view', '点击量'],
|
||||
['username', '发布人'],
|
||||
['update_time', '更新时间', 'datetime'],
|
||||
['sort', '排序', 'text.edit'],
|
||||
['status', '状态', 'switch'],
|
||||
['right_button', '操作', 'btn']
|
||||
])
|
||||
->setTableName($table_name)
|
||||
->addTopButton('add', ['href' => url('document/add', ['model' => $model['id']])]) // 添加顶部按钮
|
||||
->addTopButton('enable', ['href' => url('document/enable', ['table' => $table_name])]) // 添加顶部按钮
|
||||
->addTopButton('disable', ['href' => url('document/disable', ['table' => $table_name])]) // 添加顶部按钮
|
||||
->addTopButton('delete', ['href' => url('document/delete', ['table' => $table_name])]) // 添加顶部按钮
|
||||
->addTopButton('custom', $btnRecycle) // 添加顶部按钮
|
||||
->addRightButton('edit', ['href' => url('document/edit', ['model' => $model['id'], 'id' => '__id__'])]) // 添加右侧按钮
|
||||
->addRightButton('delete', ['href' => url('document/delete', ['ids' => '__id__', 'table' => $table_name])]) // 添加右侧按钮
|
||||
->addOrder('id,title,cid,view,username,update_time')
|
||||
->addFilter('cid', $columns)
|
||||
->addFilter(['username' => 'admin_user'])
|
||||
->addFilterMap(['cid' => ['model' => $model['id']]])
|
||||
->setRowList($data_list) // 设置表格数据
|
||||
->fetch(); // 渲染模板
|
||||
} else {
|
||||
// 查询
|
||||
$map = $this->getMap();
|
||||
$map[] = ['cms_document.trash', '=', 0];
|
||||
$map[] = ['cms_document.model', '=', $model['id']];
|
||||
// 排序
|
||||
$order = $this->getOrder('update_time desc');
|
||||
// 数据列表
|
||||
$data_list = Document::getList($map, $order);
|
||||
|
||||
$columns = Db::name('cms_column')->where(['model' => $model['id']])->column('id,name');
|
||||
|
||||
// 使用ZBuilder快速创建数据表格
|
||||
return ZBuilder::make('table')
|
||||
->setSearch(['title' => '标题', 'cms_column.name' => '栏目名称']) // 设置搜索框
|
||||
->addColumns([ // 批量添加数据列
|
||||
['id', 'ID'],
|
||||
['title', '标题'],
|
||||
['cid', '栏目名称', 'select', $columns],
|
||||
['view', '点击量'],
|
||||
['username', '发布人'],
|
||||
['update_time', '更新时间', 'datetime'],
|
||||
['sort', '排序', 'text.edit'],
|
||||
['status', '状态', 'switch'],
|
||||
['right_button', '操作', 'btn']
|
||||
])
|
||||
->setTableName('cms_document')
|
||||
->addTopButton('add', ['href' => url('document/add', ['model' => $model['id']])]) // 添加顶部按钮
|
||||
->addTopButton('enable', ['href' => url('document/enable', ['table' => 'cms_document'])]) // 添加顶部按钮
|
||||
->addTopButton('disable', ['href' => url('document/disable', ['table' => 'cms_document'])]) // 添加顶部按钮
|
||||
->addTopButton('delete', ['href' => url('document/delete', ['table' => 'cms_document'])]) // 添加顶部按钮
|
||||
->addRightButton('edit', ['href' => url('document/edit', ['id' => '__id__'])]) // 添加右侧按钮
|
||||
->addRightButton('delete', ['href' => url('document/delete', ['ids' => '__id__', 'table' => 'cms_document'])]) // 添加右侧按钮
|
||||
->addOrder('id,title,cid,view,username,update_time')
|
||||
->addFilter('cid', $columns)
|
||||
->addFilter(['username' => 'admin_user'])
|
||||
->addFilterMap(['cid' => ['model' => $model['id']]])
|
||||
->setRowList($data_list) // 设置表格数据
|
||||
->fetch(); // 渲染模板
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,345 @@
|
|||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | 海豚PHP框架 [ DolphinPHP ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 版权所有 2016~2019 广东卓锐软件有限公司 [ http://www.zrthink.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网站: http://dolphinphp.com
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace app\cms\admin;
|
||||
|
||||
use app\admin\controller\Admin;
|
||||
use app\common\builder\ZBuilder;
|
||||
use app\cms\model\Column as ColumnModel;
|
||||
use app\cms\model\Document as DocumentModel;
|
||||
use app\cms\model\Field as FieldModel;
|
||||
use think\Db;
|
||||
use util\Tree;
|
||||
|
||||
/**
|
||||
* 文档控制器
|
||||
* @package app\cms\admin
|
||||
*/
|
||||
class Document extends Admin
|
||||
{
|
||||
/**
|
||||
* 文档列表
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
cookie('__forward__', $_SERVER['REQUEST_URI']);
|
||||
// 查询
|
||||
$map = $this->getMap();
|
||||
$map[] = ['cms_document.trash', '=', 0];
|
||||
// 排序
|
||||
$order = $this->getOrder('update_time desc');
|
||||
// 数据列表
|
||||
$data_list = DocumentModel::getList($map, $order);
|
||||
|
||||
// 使用ZBuilder快速创建数据表格
|
||||
return ZBuilder::make('table')
|
||||
->setSearch(['title' => '标题', 'cms_column.name' => '栏目名称']) // 设置搜索框
|
||||
->addColumns([ // 批量添加数据列
|
||||
['id', 'ID'],
|
||||
['title', '标题'],
|
||||
['column_name', '栏目名称'],
|
||||
['view', '点击量'],
|
||||
['username', '发布人'],
|
||||
['update_time', '更新时间', 'datetime'],
|
||||
['sort', '排序', 'text.edit'],
|
||||
['status', '状态', 'switch'],
|
||||
['right_button', '操作', 'btn']
|
||||
])
|
||||
->addTopButtons('add,enable,disable,delete') // 批量添加顶部按钮
|
||||
->addRightButtons(['edit', 'delete']) // 批量添加右侧按钮
|
||||
->addOrder(['column_name' => 'cms_document.cid'])
|
||||
->addOrder('id,title,view,username,update_time')
|
||||
->addFilter(['column_name' => 'cms_column.name', 'username' => 'admin_user'])
|
||||
->setRowList($data_list) // 设置表格数据
|
||||
->fetch(); // 渲染模板
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加文档
|
||||
* @param int $cid 栏目id
|
||||
* @param string $model 模型id
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return mixed
|
||||
* @throws \think\Exception
|
||||
*/
|
||||
public function add($cid = 0, $model = '')
|
||||
{
|
||||
// 保存文档数据
|
||||
if ($this->request->isAjax()) {
|
||||
$DocumentModel = new DocumentModel();
|
||||
if (false === $DocumentModel->saveData()) {
|
||||
$this->error($DocumentModel->getError());
|
||||
}
|
||||
$this->success('新增成功', cookie('__forward__'));
|
||||
}
|
||||
|
||||
// 第二步,填写文档信息
|
||||
if ($cid > 0) {
|
||||
cookie('__forward__', url('add', ['cid' => $cid]));
|
||||
// 获取栏目数据
|
||||
$column = ColumnModel::getInfo($cid);
|
||||
|
||||
// 独立模型只取该模型的字段,不包含系统字段
|
||||
$where = [];
|
||||
if (get_model_type($column['model']) == 2) {
|
||||
$where[] = ['model', '=', $column['model']];
|
||||
} else {
|
||||
$where[] = ['model', 'in', [0, $column['model']]];
|
||||
}
|
||||
|
||||
// 获取文档模型字段
|
||||
$where[] = ['status', '=', 1];
|
||||
$where[] = ['show', '=', 1];
|
||||
$fields = FieldModel::where($where)->order('sort asc,id asc')->column(true);
|
||||
|
||||
foreach ($fields as &$value) {
|
||||
// 解析options
|
||||
if ($value['options'] != '') {
|
||||
$value['options'] = parse_attr($value['options']);
|
||||
}
|
||||
|
||||
switch ($value['type']) {
|
||||
case 'linkage':// 解析联动下拉框异步请求地址
|
||||
if (!empty($value['ajax_url']) && substr($value['ajax_url'], 0, 4) != 'http') {
|
||||
$value['ajax_url'] = url($value['ajax_url']);
|
||||
}
|
||||
break;
|
||||
case 'date':
|
||||
case 'time':
|
||||
case 'datetime':
|
||||
$value['value'] = '';
|
||||
break;
|
||||
case 'bmap':
|
||||
$value['level'] = $value['level'] == 0 ? 12 : $value['level'];
|
||||
break;
|
||||
case 'colorpicker':
|
||||
$value['mode'] = 'rgba';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 添加额外表单项信息
|
||||
$extra_field = [
|
||||
['name' => 'cid', 'title' => '所属栏目', 'type' => 'static', 'value' => $column['name']],
|
||||
['name' => 'cid', 'type' => 'hidden', 'value' => $cid],
|
||||
['name' => 'model', 'type' => 'hidden', 'value' => $column['model']]
|
||||
];
|
||||
$fields = array_merge($extra_field, $fields);
|
||||
|
||||
// 使用ZBuilder快速创建表单
|
||||
return ZBuilder::make('form')
|
||||
->setFormItems($fields)
|
||||
->hideBtn('back')
|
||||
->fetch();
|
||||
}
|
||||
|
||||
// 第一步,选择栏目
|
||||
if ($model == '') {
|
||||
$columns = ColumnModel::getTreeList(0, false);
|
||||
} else {
|
||||
// 获取相同内容模型的栏目
|
||||
$columns = Db::name('cms_column')->where('model', $model)->order('pid,id')->column('id,name,pid');
|
||||
$columns = Tree::config(['title' => 'name'])->toList($columns, current($columns)['pid']);
|
||||
$result = [];
|
||||
foreach ($columns as $column) {
|
||||
$result[$column['id']] = $column['title_display'];
|
||||
}
|
||||
$columns = $result;
|
||||
}
|
||||
return ZBuilder::make('form')
|
||||
->addFormItem('select', 'cid', '选择栏目', '请选择栏目', $columns)
|
||||
->setBtnTitle('submit', '下一步')
|
||||
->hideBtn('back')
|
||||
->isAjax(false)
|
||||
->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑文档
|
||||
* @param null $id 文档id
|
||||
* @param string $model 模型id
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return mixed
|
||||
* @throws \think\Exception
|
||||
*/
|
||||
public function edit($id = null, $model = '')
|
||||
{
|
||||
if ($id === null) $this->error('参数错误');
|
||||
|
||||
// 保存文档数据
|
||||
if ($this->request->isPost()) {
|
||||
$DocumentModel = new DocumentModel();
|
||||
$result = $DocumentModel->saveData();
|
||||
if (false === $result) {
|
||||
$this->error($DocumentModel->getError());
|
||||
}
|
||||
$this->success('编辑成功', cookie('__forward__'));
|
||||
}
|
||||
|
||||
// 获取数据
|
||||
$info = DocumentModel::getOne($id, $model);
|
||||
|
||||
// 独立模型只取该模型的字段,不包含系统字段
|
||||
$where = [];
|
||||
if ($model != '') {
|
||||
$where[] = ['model', '=', $model];
|
||||
} else {
|
||||
$where[] = ['model', 'in', [0, $info['model']]];
|
||||
}
|
||||
|
||||
// 用于查询内容模型栏目
|
||||
$map = $where;
|
||||
|
||||
// 获取文档模型字段
|
||||
$where[] = ['status', '=', 1];
|
||||
$where[] = ['show', '=', 1];
|
||||
$fields = FieldModel::where($where)->order('sort asc,id asc')->column(true);
|
||||
|
||||
foreach ($fields as $id => &$value) {
|
||||
// 解析options
|
||||
if ($value['options'] != '') {
|
||||
$value['options'] = parse_attr($value['options']);
|
||||
}
|
||||
// 日期时间
|
||||
switch ($value['type']) {
|
||||
case 'date':
|
||||
$info[$value['name']] = format_time($info[$value['name']], 'Y-m-d');
|
||||
break;
|
||||
case 'time':
|
||||
$info[$value['name']] = format_time($info[$value['name']], 'H:i:s');
|
||||
break;
|
||||
case 'datetime':
|
||||
$info[$value['name']] = empty($info[$value['name']]) ? '' : format_time($info[$value['name']]);
|
||||
break;
|
||||
case 'bmap':
|
||||
$value['level'] = $value['level'] == 0 ? 12 : $value['level'];
|
||||
break;
|
||||
case 'colorpicker':
|
||||
$value['mode'] = 'rgba';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 获取相同内容模型的栏目
|
||||
$columns = Db::name('cms_column')->where($map)->whereOr('model', $info['model'])->order('pid,id')->column('id,name,pid');
|
||||
$columns = Tree::config(['title' => 'name'])->toList($columns, current($columns)['pid']);
|
||||
$result = [];
|
||||
foreach ($columns as $column) {
|
||||
$result[$column['id']] = $column['title_display'];
|
||||
}
|
||||
$columns = $result;
|
||||
|
||||
|
||||
// 添加额外表单项信息
|
||||
$extra_field = [
|
||||
['name' => 'id', 'type' => 'hidden'],
|
||||
['name' => 'cid', 'title' => '所属栏目', 'type' => 'select', 'options' => $columns],
|
||||
['name' => 'model', 'type' => 'hidden']
|
||||
];
|
||||
$fields = array_merge($extra_field, $fields);
|
||||
|
||||
// 使用ZBuilder快速创建表单
|
||||
return ZBuilder::make('form')
|
||||
->setFormItems($fields)
|
||||
->setFormData($info)
|
||||
->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除文档(不是彻底删除,而是移动到回收站)
|
||||
* @param null $ids 文档id
|
||||
* @param string $table 数据表
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
*/
|
||||
public function delete($ids = null, $table = '')
|
||||
{
|
||||
if ($ids === null) $this->error('参数错误');
|
||||
|
||||
$document_id = is_array($ids) ? '' : $ids;
|
||||
$document_title = Db::name($table)->where('id', 'in', $ids)->column('title');
|
||||
|
||||
// 移动文档到回收站
|
||||
if (false === Db::name($table)->where('id', 'in', $ids)->setField('trash', 1)) {
|
||||
$this->error('删除失败');
|
||||
}
|
||||
|
||||
// 删除并记录日志
|
||||
action_log('document_trash', $table, $document_id, UID, implode('、', $document_title));
|
||||
$this->success('删除成功');
|
||||
}
|
||||
|
||||
/**
|
||||
* 启用文档
|
||||
* @param array $record 行为日志
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @throws \think\Exception
|
||||
* @throws \think\exception\PDOException
|
||||
*/
|
||||
public function enable($record = [])
|
||||
{
|
||||
return $this->setStatus('enable');
|
||||
}
|
||||
|
||||
/**
|
||||
* 禁用文档
|
||||
* @param array $record 行为日志
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @throws \think\Exception
|
||||
* @throws \think\exception\PDOException
|
||||
*/
|
||||
public function disable($record = [])
|
||||
{
|
||||
return $this->setStatus('disable');
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置文档状态:删除、禁用、启用
|
||||
* @param string $type 类型:enable/disable
|
||||
* @param array $record
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @throws \think\Exception
|
||||
* @throws \think\exception\PDOException
|
||||
*/
|
||||
public function setStatus($type = '', $record = [])
|
||||
{
|
||||
$table_token = input('param._t', '');
|
||||
$table_token == '' && $this->error('缺少参数');
|
||||
!session('?'.$table_token) && $this->error('参数错误');
|
||||
|
||||
$table_data = session($table_token);
|
||||
$table_name = $table_data['table'];
|
||||
$ids = $this->request->isPost() ? input('post.ids/a') : input('param.ids');
|
||||
$document_id = is_array($ids) ? '' : $ids;
|
||||
$document_title = Db::name($table_name)->where('id', 'in', $ids)->column('title');
|
||||
return parent::setStatus($type, ['document_'.$type, 'cms_document', $document_id, UID, implode('、', $document_title)]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 快速编辑
|
||||
* @param array $record 行为日志
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return mixed
|
||||
*/
|
||||
public function quickEdit($record = [])
|
||||
{
|
||||
$table_token = input('param._t', '');
|
||||
$table_token == '' && $this->error('缺少参数');
|
||||
!session('?'.$table_token) && $this->error('参数错误');
|
||||
|
||||
$table_data = session($table_token);
|
||||
$table = $table_data['table'];
|
||||
$id = input('post.pk', '');
|
||||
$field = input('post.name', '');
|
||||
$value = input('post.value', '');
|
||||
$document = Db::name($table)->where('id', $id)->value($field);
|
||||
$details = '表名(' . $table . '),字段(' . $field . '),原值(' . $document . '),新值:(' . $value . ')';
|
||||
return parent::quickEdit(['document_edit', 'cms_document', $id, UID, $details]);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,330 @@
|
|||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | 海豚PHP框架 [ DolphinPHP ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 版权所有 2016~2017 河源市卓锐科技有限公司 [ http://www.zrthink.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网站: http://dolphinphp.com
|
||||
// +----------------------------------------------------------------------
|
||||
// | 开源协议 ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace app\cms\admin;
|
||||
|
||||
use app\admin\controller\Admin;
|
||||
use app\common\builder\ZBuilder;
|
||||
use app\cms\model\Field as FieldModel;
|
||||
use think\Db;
|
||||
|
||||
/**
|
||||
* 字段管理控制器
|
||||
* @package app\cms\admin
|
||||
*/
|
||||
class Field extends Admin
|
||||
{
|
||||
/**
|
||||
* 字段列表
|
||||
* @param null $id 文档模型id
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
*/
|
||||
public function index($id = null)
|
||||
{
|
||||
$id === null && $this->error('参数错误');
|
||||
cookie('__forward__', $_SERVER['REQUEST_URI']);
|
||||
|
||||
// 查询
|
||||
$map = $this->getMap();
|
||||
$map[]=['model','=',$id];
|
||||
// 数据列表
|
||||
$data_list = FieldModel::where($map)->order('id desc')->paginate();
|
||||
|
||||
// 使用ZBuilder快速创建数据表格
|
||||
return ZBuilder::make('table')
|
||||
->setSearch(['name' => '名称', 'title' => '标题']) // 设置搜索框
|
||||
->setPageTips('【显示】表示新增或编辑文档时是否显示该字段<br>【启用】表示前台是否显示')
|
||||
->addColumns([ // 批量添加数据列
|
||||
['id', 'ID'],
|
||||
['name', '名称'],
|
||||
['title', '标题'],
|
||||
['type', '类型', 'text', '', config('form_item_type')],
|
||||
['create_time', '创建时间', 'datetime'],
|
||||
['sort', '排序', 'text.edit'],
|
||||
['show', '显示', 'switch'],
|
||||
['status', '启用', 'switch'],
|
||||
['right_button', '操作', 'btn']
|
||||
])
|
||||
->addTopButton('back', ['href' => url('model/index')]) // 批量添加顶部按钮
|
||||
->addTopButton('add', ['href' => url('add', ['model' => $id])]) // 添加顶部按钮
|
||||
->addTopButtons('enable,disable') // 批量添加顶部按钮
|
||||
->addRightButtons('edit,delete') // 批量添加右侧按钮
|
||||
->replaceRightButton(['fixed' => 1], '<button class="btn btn-danger btn-xs" type="button" disabled>固定字段禁止操作</button>')
|
||||
->setRowList($data_list) // 设置表格数据
|
||||
->fetch(); // 渲染模板
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增字段
|
||||
* @param string $model 文档模型id
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return mixed
|
||||
*/
|
||||
public function add($model = '')
|
||||
{
|
||||
// 内容模型类别[0-系统,1-普通,2-独立]
|
||||
$model_type = get_model_type($model);
|
||||
|
||||
if ($this->request->isPost()) {
|
||||
// 表单数据
|
||||
$data = $this->request->post();
|
||||
|
||||
// 非独立模型需验证字段名称是否为aid
|
||||
if ($model_type != 2) {
|
||||
// 非独立模型需验证新增的字段是否被系统占用
|
||||
if ($data['name'] == 'aid' || is_default_field($data['name'])) {
|
||||
$this->error('字段名称已存在');
|
||||
}
|
||||
}
|
||||
|
||||
$result = $this->validate($data, 'Field');
|
||||
if(true !== $result) $this->error($result);
|
||||
|
||||
// 如果是快速联动
|
||||
switch ($data['type']) {
|
||||
case 'linkages':
|
||||
$data['key'] = $data['key'] == '' ? 'id' : $data['key'];
|
||||
$data['pid'] = $data['pid'] == '' ? 'pid' : $data['pid'];
|
||||
$data['level'] = $data['level'] == '' ? '2' : $data['level'];
|
||||
$data['option'] = $data['option'] == '' ? 'name' : $data['option'];
|
||||
break;
|
||||
case 'number':
|
||||
$data['type'] = 'text';
|
||||
break;
|
||||
case 'bmap':
|
||||
$data['level'] = !$data['level'] ? 12 : $data['level'];
|
||||
break;
|
||||
}
|
||||
|
||||
if ($field = FieldModel::create($data)) {
|
||||
$FieldModel = new FieldModel();
|
||||
// 添加字段
|
||||
if ($FieldModel->newField($data)) {
|
||||
// 记录行为
|
||||
$details = '详情:文档模型('.get_model_title($data['model']).')、字段名称('.$data['name'].')、字段标题('.$data['title'].')、字段类型('.$data['type'].')';
|
||||
action_log('field_add', 'cms_field', $field['id'], UID, $details);
|
||||
// 清除缓存
|
||||
cache('cms_system_fields', null);
|
||||
$this->success('新增成功', cookie('__forward__'));
|
||||
} else {
|
||||
// 添加失败,删除新增的数据
|
||||
FieldModel::destroy($field['id']);
|
||||
$this->error($FieldModel->getError());
|
||||
}
|
||||
} else {
|
||||
$this->error('新增失败');
|
||||
}
|
||||
}
|
||||
|
||||
if ($model_type != 2) {
|
||||
$field_exist = Db::name('cms_field')->where('model', 'in', [0, $model])->column('name');
|
||||
$field_exist[] = 'aid';
|
||||
} else {
|
||||
$field_exist = ['id','cid','uid','title','model','create_time','update_time','sort','status','view','trash'];
|
||||
}
|
||||
|
||||
// 显示添加页面
|
||||
return ZBuilder::make('form')
|
||||
->setPageTips('以下字段名称已存在,请不要建立同名的字段:<br>'. implode('、', $field_exist))
|
||||
->addFormItems([
|
||||
['hidden', 'model', $model],
|
||||
['text', 'name', '字段名称', '由小写英文字母和下划线组成'],
|
||||
['text', 'title', '字段标题', '可填写中文'],
|
||||
['select', 'type', '字段类型', '', config('form_item_type')],
|
||||
['text', 'define', '字段定义', '可根据实际需求自行填写或修改,但必须是正确的sql语法'],
|
||||
['text', 'value', '字段默认值'],
|
||||
['textarea', 'options', '额外选项', '用于单选、多选、下拉、联动等类型'],
|
||||
['text', 'ajax_url', '异步请求地址', "如请求的地址是 <code>url('ajax/getCity')</code>,那么只需填写 <code>ajax/getCity</code>,或者直接填写以 <code>http</code>开头的url地址"],
|
||||
['text', 'next_items', '下一级联动下拉框的表单名', "与当前有关联的下级联动下拉框名,多个用逗号隔开,如:area,other"],
|
||||
['text', 'param', '请求参数名', "联动下拉框请求参数名,默认为配置名称"],
|
||||
['text', 'level', '级别', '如果类型为【快速联动下拉框】则表示需要显示的级别数量,默认为2。如果类型为【百度地图】,则表示地图默认缩放级别,建议设置为12', 2],
|
||||
['text', 'table', '表名', '要查询的表,里面必须含有id、name、pid三个字段,其中id和name字段可在下面重新定义'],
|
||||
['text', 'pid', '父级id字段名', '即表中的父级ID字段名,如果表中的主键字段名为pid则可不填写'],
|
||||
['text', 'key', '键字段名', '即表中的主键字段名,如果表中的主键字段名为id则可不填写'],
|
||||
['text', 'option', '值字段名', '下拉菜单显示的字段名,如果表中的该字段名为name则可不填写'],
|
||||
['text', 'ak', 'APPKEY', '百度编辑器APPKEY'],
|
||||
['text', 'format', '格式'],
|
||||
['textarea', 'tips', '字段说明', '字段补充说明'],
|
||||
['radio', 'fixed', '是否为固定字段', '如果为 <code>固定字段</code> 则添加后不可修改', ['否', '是'], 0],
|
||||
['radio', 'show', '是否显示', '新增或编辑时是否显示该字段', ['否', '是'], 1],
|
||||
['radio', 'status', '立即启用', '', ['否', '是'], 1],
|
||||
['text', 'sort', '排序', '', 100],
|
||||
])
|
||||
->setTrigger('type', 'linkage', 'ajax_url,next_items,param')
|
||||
->setTrigger('type', 'linkages', 'table,pid,key,option')
|
||||
->setTrigger('type', 'bmap', 'ak')
|
||||
->setTrigger('type', 'linkages,bmap', 'level')
|
||||
->setTrigger('type', 'masked,date,time,datetime', 'format')
|
||||
->setTrigger('type', 'checkbox,radio,array,select,linkage,linkages', 'options')
|
||||
->js('field')
|
||||
->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑字段
|
||||
* @param null $id 字段id
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return mixed
|
||||
*/
|
||||
public function edit($id = null)
|
||||
{
|
||||
if ($id === null) $this->error('参数错误');
|
||||
|
||||
// 保存数据
|
||||
if ($this->request->isPost()) {
|
||||
// 表单数据
|
||||
$data = $this->request->post();
|
||||
|
||||
// 验证
|
||||
$result = $this->validate($data, 'Field');
|
||||
if(true !== $result) $this->error($result);
|
||||
|
||||
// 如果是快速联动
|
||||
if ($data['type'] == 'linkages') {
|
||||
$data['key'] = $data['key'] == '' ? 'id' : $data['key'];
|
||||
$data['pid'] = $data['pid'] == '' ? 'pid' : $data['pid'];
|
||||
$data['level'] = $data['level'] == '' ? '2' : $data['level'];
|
||||
$data['option'] = $data['option'] == '' ? 'name' : $data['option'];
|
||||
}
|
||||
// 如果是百度地图
|
||||
if ($data['type'] == 'bmap') {
|
||||
$data['level'] = !$data['level'] ? 12 : $data['level'];
|
||||
}
|
||||
|
||||
// 更新字段信息
|
||||
$FieldModel = new FieldModel();
|
||||
if ($FieldModel->updateField($data)) {
|
||||
if ($FieldModel->isUpdate(true)->save($data)) {
|
||||
// 记录行为
|
||||
action_log('field_edit', 'cms_field', $id, UID, $data['name']);
|
||||
$this->success('字段更新成功', cookie('__forward__'));
|
||||
}
|
||||
}
|
||||
$this->error('字段更新失败');
|
||||
}
|
||||
|
||||
// 获取数据
|
||||
$info = FieldModel::get($id);
|
||||
|
||||
// 显示编辑页面
|
||||
return ZBuilder::make('form')
|
||||
->addFormItems([
|
||||
['hidden', 'id'],
|
||||
['hidden', 'model'],
|
||||
['text', 'name', '字段名称', '由小写英文字母和下划线组成'],
|
||||
['text', 'title', '字段标题', '可填写中文'],
|
||||
['select', 'type', '字段类型', '', config('form_item_type')],
|
||||
['text', 'define', '字段定义', '可根据实际需求自行填写或修改,但必须是正确的sql语法'],
|
||||
['text', 'value', '字段默认值'],
|
||||
['textarea', 'options', '额外选项', '用于单选、多选、下拉、联动等类型'],
|
||||
['text', 'ajax_url', '异步请求地址', "如请求的地址是 <code>url('ajax/getCity')</code>,那么只需填写 <code>ajax/getCity</code>,或者直接填写以 <code>http</code>开头的url地址"],
|
||||
['text', 'next_items', '下一级联动下拉框的表单名', "与当前有关联的下级联动下拉框名,多个用逗号隔开,如:area,other"],
|
||||
['text', 'param', '请求参数名', "联动下拉框请求参数名,默认为配置名称"],
|
||||
['text', 'level', '级别', '如果类型为【快速联动下拉框】则表示需要显示的级别数量,默认为2。如果类型为【百度地图】,则表示地图默认缩放级别,建议设置为12'],
|
||||
['text', 'table', '表名', '要查询的表,里面必须含有id、name、pid三个字段,其中id和name字段可在下面重新定义'],
|
||||
['text', 'pid', '父级id字段名', '即表中的父级ID字段名,如果表中的主键字段名为pid则可不填写'],
|
||||
['text', 'key', '键字段名', '即表中的主键字段名,如果表中的主键字段名为id则可不填写'],
|
||||
['text', 'option', '值字段名', '下拉菜单显示的字段名,如果表中的该字段名为name则可不填写'],
|
||||
['text', 'ak', 'APPKEY', '百度编辑器APPKEY'],
|
||||
['text', 'format', '格式'],
|
||||
['textarea', 'tips', '字段说明', '字段补充说明'],
|
||||
['radio', 'show', '是否显示', '新增或编辑时是否显示该字段', ['否', '是']],
|
||||
['radio', 'status', '立即启用', '', ['否', '是']],
|
||||
['text', 'sort', '排序'],
|
||||
])
|
||||
->setTrigger('type', 'linkage', 'ajax_url,next_items,param')
|
||||
->setTrigger('type', 'linkages', 'table,pid,key,option')
|
||||
->setTrigger('type', 'bmap', 'ak')
|
||||
->setTrigger('type', 'linkages,bmap', 'level')
|
||||
->setTrigger('type', 'masked,date,time,datetime', 'format')
|
||||
->setTrigger('type', 'checkbox,radio,array,select,linkage,linkages', 'options')
|
||||
->js('field')
|
||||
->setFormData($info)
|
||||
->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除字段
|
||||
* @param null $ids 字段id
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return mixed
|
||||
*/
|
||||
public function delete($ids = null)
|
||||
{
|
||||
if ($ids === null) $this->error('参数错误');
|
||||
|
||||
$FieldModel = new FieldModel();
|
||||
$field = $FieldModel->where('id', $ids)->find();
|
||||
|
||||
if ($FieldModel->deleteField($field)) {
|
||||
if ($FieldModel->where('id', $ids)->delete()) {
|
||||
// 记录行为
|
||||
$details = '详情:文档模型('.get_model_title($field['model']).')、字段名称('.$field['name'].')、字段标题('.$field['title'].')、字段类型('.$field['type'].')';
|
||||
action_log('field_delete', 'cms_field', $ids, UID, $details);
|
||||
$this->success('删除成功', cookie('__forward__'));
|
||||
}
|
||||
}
|
||||
return $this->error('删除失败');
|
||||
}
|
||||
|
||||
/**
|
||||
* 启用字段
|
||||
* @param array $record 行为日志
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return mixed
|
||||
*/
|
||||
public function enable($record = [])
|
||||
{
|
||||
return $this->setStatus('enable');
|
||||
}
|
||||
|
||||
/**
|
||||
* 禁用字段
|
||||
* @param array $record 行为日志
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return mixed
|
||||
*/
|
||||
public function disable($record = [])
|
||||
{
|
||||
return $this->setStatus('disable');
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置字段状态:删除、禁用、启用
|
||||
* @param string $type 类型:enable/disable
|
||||
* @param array $record
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return mixed
|
||||
*/
|
||||
public function setStatus($type = '', $record = [])
|
||||
{
|
||||
$ids = $this->request->isPost() ? input('post.ids/a') : input('param.ids');
|
||||
$field_delete = is_array($ids) ? '' : $ids;
|
||||
$field_names = FieldModel::where('id', 'in', $ids)->column('name');
|
||||
return parent::setStatus($type, ['field_'.$type, 'cms_field', $field_delete, UID, implode('、', $field_names)]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 快速编辑
|
||||
* @param array $record 行为日志
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return mixed
|
||||
*/
|
||||
public function quickEdit($record = [])
|
||||
{
|
||||
$id = input('post.pk', '');
|
||||
$field = input('post.name', '');
|
||||
$value = input('post.value', '');
|
||||
$config = FieldModel::where('id', $id)->value($field);
|
||||
$details = '字段(' . $field . '),原值(' . $config . '),新值:(' . $value . ')';
|
||||
return parent::quickEdit(['field_edit', 'cms_field', $id, UID, $details]);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | 海豚PHP框架 [ DolphinPHP ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 版权所有 2016~2019 广东卓锐软件有限公司 [ http://www.zrthink.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网站: http://dolphinphp.com
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace app\cms\admin;
|
||||
|
||||
use app\admin\controller\Admin;
|
||||
use think\Db;
|
||||
|
||||
/**
|
||||
* 仪表盘控制器
|
||||
* @package app\cms\admin
|
||||
*/
|
||||
class Index extends Admin
|
||||
{
|
||||
/**
|
||||
* 首页
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return mixed
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$this->assign('document', Db::name('cms_document')->where('trash', 0)->count());
|
||||
$this->assign('column', Db::name('cms_column')->count());
|
||||
$this->assign('page', Db::name('cms_page')->count());
|
||||
$this->assign('model', Db::name('cms_model')->count());
|
||||
$this->assign('page_title', '仪表盘');
|
||||
return $this->fetch(); // 渲染模板
|
||||
}
|
||||
}
|
|
@ -0,0 +1,216 @@
|
|||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | 海豚PHP框架 [ DolphinPHP ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 版权所有 2016~2019 广东卓锐软件有限公司 [ http://www.zrthink.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网站: http://dolphinphp.com
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace app\cms\admin;
|
||||
|
||||
use app\admin\controller\Admin;
|
||||
use app\common\builder\ZBuilder;
|
||||
use app\cms\model\Link as LinkModel;
|
||||
|
||||
/**
|
||||
* 友情链接控制器
|
||||
* @package app\cms\admin
|
||||
*/
|
||||
class Link extends Admin
|
||||
{
|
||||
/**
|
||||
* 友情链接列表
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return mixed
|
||||
* @throws \think\Exception
|
||||
* @throws \think\exception\DbException
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
// 查询
|
||||
$map = $this->getMap();
|
||||
// 排序
|
||||
$order = $this->getOrder('update_time desc');
|
||||
// 数据列表
|
||||
$data_list = LinkModel::where($map)->order($order)->paginate();
|
||||
|
||||
// 使用ZBuilder快速创建数据表格
|
||||
return ZBuilder::make('table')
|
||||
->setSearch(['title' => '标题']) // 设置搜索框
|
||||
->addColumns([ // 批量添加数据列
|
||||
['id', 'ID'],
|
||||
['title', '标题', 'text.edit'],
|
||||
['url', '链接', 'text.edit'],
|
||||
['type', '类型', 'text', '', [1 => '文字链接', 2 => '图片链接']],
|
||||
['create_time', '创建时间', 'datetime'],
|
||||
['update_time', '更新时间', 'datetime'],
|
||||
['status', '状态', 'switch'],
|
||||
['right_button', '操作', 'btn']
|
||||
])
|
||||
->addTopButtons('add,enable,disable,delete') // 批量添加顶部按钮
|
||||
->addRightButtons(['edit', 'delete' => ['data-tips' => '删除后无法恢复。']]) // 批量添加右侧按钮
|
||||
->addOrder('id,title,type,create_time,update_time')
|
||||
->setRowList($data_list) // 设置表格数据
|
||||
->addValidate('Link', 'title,url')
|
||||
->fetch(); // 渲染模板
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return mixed
|
||||
* @throws \think\Exception
|
||||
*/
|
||||
public function add()
|
||||
{
|
||||
// 保存数据
|
||||
if ($this->request->isPost()) {
|
||||
// 表单数据
|
||||
$data = $this->request->post();
|
||||
|
||||
// 验证
|
||||
$result = $this->validate($data, 'Link');
|
||||
if(true !== $result) $this->error($result);
|
||||
|
||||
if ($link = LinkModel::create($data)) {
|
||||
// 记录行为
|
||||
action_log('link_add', 'cms_link', $link['id'], UID, $data['title']);
|
||||
$this->success('新增成功', 'index');
|
||||
} else {
|
||||
$this->error('新增失败');
|
||||
}
|
||||
}
|
||||
|
||||
// 显示添加页面
|
||||
return ZBuilder::make('form')
|
||||
->addFormItems([
|
||||
['radio', 'type', '链接类型', '', [1 => '文字链接', 2 => '图片链接'], 1],
|
||||
['text', 'title', '链接标题'],
|
||||
['text', 'url', '链接地址', '请以 <code>http</code> 或 <code>https</code>开头'],
|
||||
['image', 'logo', '链接LOGO'],
|
||||
['tags', 'keywords', '关键词'],
|
||||
['textarea', 'contact', '联系方式'],
|
||||
['text', 'sort', '排序', '', 100],
|
||||
['radio', 'status', '立即启用', '', ['否', '是'], 1]
|
||||
])
|
||||
->setTrigger('type', 2, 'logo')
|
||||
->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑
|
||||
* @param null $id 链接id
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return mixed
|
||||
* @throws \think\Exception
|
||||
*/
|
||||
public function edit($id = null)
|
||||
{
|
||||
if ($id === null) $this->error('缺少参数');
|
||||
|
||||
// 保存数据
|
||||
if ($this->request->isPost()) {
|
||||
// 表单数据
|
||||
$data = $this->request->post();
|
||||
|
||||
// 验证
|
||||
$result = $this->validate($data, 'Link');
|
||||
if(true !== $result) $this->error($result);
|
||||
|
||||
if (LinkModel::update($data)) {
|
||||
// 记录行为
|
||||
action_log('link_edit', 'cms_link', $id, UID, $data['title']);
|
||||
$this->success('编辑成功', 'index');
|
||||
} else {
|
||||
$this->error('编辑失败');
|
||||
}
|
||||
}
|
||||
|
||||
$info = LinkModel::get($id);
|
||||
|
||||
// 显示编辑页面
|
||||
return ZBuilder::make('form')
|
||||
->addFormItems([
|
||||
['hidden', 'id'],
|
||||
['radio', 'type', '链接类型', '', [1 => '文字链接', 2 => '图片链接']],
|
||||
['text', 'title', '链接标题'],
|
||||
['text', 'url', '链接地址', '请以 <code>http</code> 或 <code>https</code>开头'],
|
||||
['image', 'logo', '链接LOGO'],
|
||||
['tags', 'keywords', '关键词'],
|
||||
['textarea', 'contact', '联系方式'],
|
||||
['text', 'sort', '排序'],
|
||||
['radio', 'status', '立即启用', '', ['否', '是']]
|
||||
])
|
||||
->setTrigger('type', 2, 'logo')
|
||||
->setFormData($info)
|
||||
->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除友情链接
|
||||
* @param array $record 行为日志
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @throws \think\Exception
|
||||
* @throws \think\exception\PDOException
|
||||
*/
|
||||
public function delete($record = [])
|
||||
{
|
||||
return $this->setStatus('delete');
|
||||
}
|
||||
|
||||
/**
|
||||
* 启用友情链接
|
||||
* @param array $record 行为日志
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @throws \think\Exception
|
||||
* @throws \think\exception\PDOException
|
||||
*/
|
||||
public function enable($record = [])
|
||||
{
|
||||
return $this->setStatus('enable');
|
||||
}
|
||||
|
||||
/**
|
||||
* 禁用友情链接
|
||||
* @param array $record 行为日志
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @throws \think\Exception
|
||||
* @throws \think\exception\PDOException
|
||||
*/
|
||||
public function disable($record = [])
|
||||
{
|
||||
return $this->setStatus('disable');
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置友情链接状态:删除、禁用、启用
|
||||
* @param string $type 类型:delete/enable/disable
|
||||
* @param array $record
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @throws \think\Exception
|
||||
* @throws \think\exception\PDOException
|
||||
*/
|
||||
public function setStatus($type = '', $record = [])
|
||||
{
|
||||
$ids = $this->request->isPost() ? input('post.ids/a') : input('param.ids');
|
||||
$link_title = LinkModel::where('id', 'in', $ids)->column('title');
|
||||
return parent::setStatus($type, ['link_'.$type, 'cms_link', 0, UID, implode('、', $link_title)]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 快速编辑
|
||||
* @param array $record 行为日志
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return mixed
|
||||
*/
|
||||
public function quickEdit($record = [])
|
||||
{
|
||||
$id = input('post.pk', '');
|
||||
$field = input('post.name', '');
|
||||
$value = input('post.value', '');
|
||||
$link = LinkModel::where('id', $id)->value($field);
|
||||
$details = '字段(' . $field . '),原值(' . $link . '),新值:(' . $value . ')';
|
||||
return parent::quickEdit(['link_edit', 'cms_link', $id, UID, $details]);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,263 @@
|
|||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | 海豚PHP框架 [ DolphinPHP ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 版权所有 2016~2019 广东卓锐软件有限公司 [ http://www.zrthink.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网站: http://dolphinphp.com
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace app\cms\admin;
|
||||
|
||||
use app\admin\controller\Admin;
|
||||
use app\common\builder\ZBuilder;
|
||||
use app\cms\model\Menu as MenuModel;
|
||||
use app\cms\model\Column as ColumnModel;
|
||||
use app\cms\model\Page as PageModel;
|
||||
use util\Tree;
|
||||
use think\Db;
|
||||
|
||||
/**
|
||||
* 菜单控制器
|
||||
* @package app\cms\admin
|
||||
*/
|
||||
class Menu extends Admin
|
||||
{
|
||||
/**
|
||||
* 菜单列表
|
||||
* @param null $id 导航id
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return mixed
|
||||
* @throws \think\Exception
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @throws \think\exception\DbException
|
||||
*/
|
||||
public function index($id = null)
|
||||
{
|
||||
if ($id === null) $this->error('缺少参数');
|
||||
// 查询
|
||||
$map = $this->getMap();
|
||||
|
||||
// 数据列表
|
||||
$data_list = Db::view('cms_menu', true)
|
||||
->view('cms_column', ['name' => 'column_name'], 'cms_menu.column=cms_column.id', 'left')
|
||||
->view('cms_page', ['title' => 'page_title'], 'cms_menu.page=cms_page.id', 'left')
|
||||
->where('cms_menu.nid', $id)
|
||||
->order('cms_menu.sort,cms_menu.pid,cms_menu.id')
|
||||
->select();
|
||||
|
||||
foreach ($data_list as &$item) {
|
||||
if ($item['type'] == 0) {
|
||||
$item['title'] = $item['column_name'];
|
||||
} elseif ($item['type'] == 1) {
|
||||
$item['title'] = $item['page_title'];
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($map)) {
|
||||
$data_list = Tree::toList($data_list);
|
||||
}
|
||||
|
||||
$btnAdd = ['icon' => 'fa fa-plus', 'title' => '新增子菜单', 'href' => url('add', ['nid' => $id, 'pid' => '__id__'])];
|
||||
|
||||
// 使用ZBuilder快速创建数据表格
|
||||
return ZBuilder::make('table')
|
||||
->setSearch(['cms_menu.title|cms_column.name|cms_page.title' => '标题'])// 设置搜索框
|
||||
->addColumns([ // 批量添加数据列
|
||||
['id', 'ID'],
|
||||
['title', '标题', 'callback', function($value, $data){
|
||||
return isset($data['title_prefix']) ? $data['title_display'] : $value;
|
||||
}, '__data__'],
|
||||
['type', '类型', 'text', '', ['栏目链接', '单页链接', '自定义链接']],
|
||||
['target', '打开方式', 'select', ['_self' => '当前窗口', '_blank' => '新窗口']],
|
||||
['create_time', '创建时间', 'datetime'],
|
||||
['update_time', '更新时间', 'datetime'],
|
||||
['sort', '排序', 'text.edit'],
|
||||
['status', '状态', 'switch'],
|
||||
['right_button', '操作', 'btn']
|
||||
])
|
||||
->addTopButton('back', ['href' => url('nav/index')])
|
||||
->addTopButton('add', ['href' => url('add', ['nid' => $id])])
|
||||
->addTopButtons('enable,disable')// 批量添加顶部按钮
|
||||
->addRightButton('custom', $btnAdd)
|
||||
->addRightButton('edit')
|
||||
->addRightButton('delete', ['data-tips' => '删除后无法恢复。'])// 批量添加右侧按钮
|
||||
->setRowList($data_list)// 设置表格数据
|
||||
->addValidate('Nav', 'title')
|
||||
->fetch(); // 渲染模板
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增
|
||||
* @param null $nid 导航id
|
||||
* @param int $pid 菜单父级id
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return mixed
|
||||
* @throws \think\Exception
|
||||
*/
|
||||
public function add($nid = null, $pid = 0)
|
||||
{
|
||||
if ($nid === null) $this->error('缺少参数');
|
||||
// 保存数据
|
||||
if ($this->request->isPost()) {
|
||||
// 表单数据
|
||||
$data = $this->request->post();
|
||||
|
||||
// 验证
|
||||
$result = $this->validate($data, 'Menu');
|
||||
if(true !== $result) $this->error($result);
|
||||
|
||||
if ($menu = MenuModel::create($data)) {
|
||||
// 记录行为
|
||||
action_log('menu_add', 'cms_menu', $menu['id'], UID, $data['title']);
|
||||
$this->success('新增成功', url('index', ['id' => $nid]));
|
||||
} else {
|
||||
$this->error('新增失败');
|
||||
}
|
||||
}
|
||||
|
||||
// 显示添加页面
|
||||
return ZBuilder::make('form')
|
||||
->addFormItems([
|
||||
['hidden', 'nid', $nid],
|
||||
['hidden', 'pid', $pid],
|
||||
['radio', 'type', '类型', '', ['栏目链接', '单页链接', '自定义链接'], 0],
|
||||
['select', 'column', '栏目', '<code>必选</code>', ColumnModel::getTreeList(0, false)],
|
||||
['select', 'page', '单页', '<code>必选</code>', PageModel::getTitleList()],
|
||||
['text', 'title', '菜单标题', '<code>必填</code>,只用于区分'],
|
||||
['text', 'url', 'URL', "<code>必填</code>。如果是模块链接,请填写<code>模块/控制器/操作</code>,如:<code>admin/menu/add</code>。如果是普通链接,则直接填写url地址,如:<code>http://www.dolphinphp.com</code>"],
|
||||
['text', 'css', 'CSS类', '可选'],
|
||||
['text', 'rel', '链接关系网(XFN)', '可选,即链接的rel值'],
|
||||
['radio', 'target', '打开方式', '', ['_self' => '当前窗口', '_blank' => '新窗口'], '_self'],
|
||||
['text', 'sort', '排序', '', 100],
|
||||
['radio', 'status', '立即启用', '', ['否', '是'], 1]
|
||||
])
|
||||
->setTrigger('type', '0', 'column')
|
||||
->setTrigger('type', '1', 'page')
|
||||
->setTrigger('type', '2', 'title,url')
|
||||
->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑
|
||||
* @param null $id 菜单id
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return mixed
|
||||
* @throws \think\Exception
|
||||
*/
|
||||
public function edit($id = null)
|
||||
{
|
||||
if ($id === null) $this->error('缺少参数');
|
||||
// 保存数据
|
||||
if ($this->request->isPost()) {
|
||||
// 表单数据
|
||||
$data = $this->request->post();
|
||||
|
||||
// 验证
|
||||
$result = $this->validate($data, 'Menu');
|
||||
if(true !== $result) $this->error($result);
|
||||
|
||||
if (MenuModel::update($data)) {
|
||||
// 记录行为
|
||||
action_log('menu_edit', 'cms_menu', $id, UID, $data['title']);
|
||||
$this->success('编辑成功', url('index', ['id' => $data['nid']]));
|
||||
} else {
|
||||
$this->error('编辑失败');
|
||||
}
|
||||
}
|
||||
|
||||
// 显示添加页面
|
||||
return ZBuilder::make('form')
|
||||
->addFormItems([
|
||||
['hidden', 'id'],
|
||||
['hidden', 'nid'],
|
||||
['radio', 'type', '类型', '', ['栏目链接', '单页链接', '自定义链接']],
|
||||
['select', 'column', '栏目', '<code>必选</code>', ColumnModel::getTreeList(0, false)],
|
||||
['select', 'page', '单页', '<code>必选</code>', PageModel::getTitleList()],
|
||||
['text', 'title', '菜单标题', '<code>必填</code>,只用于区分'],
|
||||
['text', 'url', 'URL', "<code>必填</code>。如果是模块链接,请填写<code>模块/控制器/操作</code>,如:<code>admin/menu/add</code>。如果是普通链接,则直接填写url地址,如:<code>http://www.dolphinphp.com</code>"],
|
||||
['text', 'css', 'CSS类', '可选'],
|
||||
['text', 'rel', '链接关系网(XFN)', '可选,即链接的rel值'],
|
||||
['radio', 'target', '打开方式', '', ['_self' => '当前窗口', '_blank' => '新窗口'], '_self'],
|
||||
['text', 'sort', '排序', '', 100],
|
||||
['radio', 'status', '立即启用', '', ['否', '是'], 1]
|
||||
])
|
||||
->setFormData(MenuModel::get($id))
|
||||
->setTrigger('type', '0', 'column')
|
||||
->setTrigger('type', '1', 'page')
|
||||
->setTrigger('type', '2', 'title,url')
|
||||
->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除菜单
|
||||
* @param null $ids 菜单id
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @throws \think\Exception
|
||||
* @throws \think\exception\PDOException
|
||||
*/
|
||||
public function delete($ids = null)
|
||||
{
|
||||
// 检查是否有子菜单
|
||||
if (MenuModel::where('pid', $ids)->find()) {
|
||||
$this->error('请先删除或移动该菜单下的子菜单');
|
||||
}
|
||||
return $this->setStatus('delete');
|
||||
}
|
||||
|
||||
/**
|
||||
* 启用菜单
|
||||
* @param array $record 行为日志
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @throws \think\Exception
|
||||
* @throws \think\exception\PDOException
|
||||
*/
|
||||
public function enable($record = [])
|
||||
{
|
||||
return $this->setStatus('enable');
|
||||
}
|
||||
|
||||
/**
|
||||
* 禁用菜单
|
||||
* @param array $record 行为日志
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @throws \think\Exception
|
||||
* @throws \think\exception\PDOException
|
||||
*/
|
||||
public function disable($record = [])
|
||||
{
|
||||
return $this->setStatus('disable');
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置菜单状态:删除、禁用、启用
|
||||
* @param string $type 类型:delete/enable/disable
|
||||
* @param array $record
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @throws \think\Exception
|
||||
* @throws \think\exception\PDOException
|
||||
*/
|
||||
public function setStatus($type = '', $record = [])
|
||||
{
|
||||
$ids = $this->request->isPost() ? input('post.ids/a') : input('param.ids');
|
||||
$menu_title = MenuModel::where('id', 'in', $ids)->column('title');
|
||||
return parent::setStatus($type, ['menu_'.$type, 'cms_menu', 0, UID, implode('、', $menu_title)]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 快速编辑
|
||||
* @param array $record 行为日志
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return mixed
|
||||
*/
|
||||
public function quickEdit($record = [])
|
||||
{
|
||||
$id = input('post.pk', '');
|
||||
$field = input('post.name', '');
|
||||
$value = input('post.value', '');
|
||||
$menu = MenuModel::where('id', $id)->value($field);
|
||||
$details = '字段(' . $field . '),原值(' . $menu . '),新值:(' . $value . ')';
|
||||
return parent::quickEdit(['menu_edit', 'cms_menu', $id, UID, $details]);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,236 @@
|
|||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | 海豚PHP框架 [ DolphinPHP ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 版权所有 2016~2019 广东卓锐软件有限公司 [ http://www.zrthink.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网站: http://dolphinphp.com
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace app\cms\admin;
|
||||
|
||||
use app\admin\controller\Admin;
|
||||
use app\common\builder\ZBuilder;
|
||||
use app\cms\model\Model as DocumentModel;
|
||||
use app\admin\model\Menu as MenuModel;
|
||||
use think\Db;
|
||||
use think\facade\Cache;
|
||||
|
||||
/**
|
||||
* 内容模型控制器
|
||||
* @package app\cms\admin
|
||||
*/
|
||||
class Model extends Admin
|
||||
{
|
||||
/**
|
||||
* 内容模型列表
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
// 查询
|
||||
$map = $this->getMap();
|
||||
// 数据列表
|
||||
$data_list = DocumentModel::where($map)->order('sort,id desc')->paginate();
|
||||
|
||||
// 字段管理按钮
|
||||
$btnField = [
|
||||
'title' => '字段管理',
|
||||
'icon' => 'fa fa-fw fa-navicon',
|
||||
'href' => url('field/index', ['id' => '__id__'])
|
||||
];
|
||||
|
||||
// 使用ZBuilder快速创建数据表格
|
||||
return ZBuilder::make('table')
|
||||
->setSearch(['name' => '标识', 'title' => '标题']) // 设置搜索框
|
||||
->addColumns([ // 批量添加数据列
|
||||
['id', 'ID'],
|
||||
['icon', '图标', 'icon'],
|
||||
['title', '标题'],
|
||||
['name', '标识'],
|
||||
['table', '附加表'],
|
||||
['type', '模型', 'text', '', ['系统', '普通', '独立']],
|
||||
['create_time', '创建时间', 'datetime'],
|
||||
['sort', '排序', 'text.edit'],
|
||||
['status', '状态', 'switch'],
|
||||
['right_button', '操作', 'btn']
|
||||
])
|
||||
->addFilter('type', ['系统', '普通', '独立'])
|
||||
->addTopButtons('add,enable,disable') // 批量添加顶部按钮
|
||||
->addRightButtons(['edit', 'custom' => $btnField, 'delete' => ['data-tips' => '删除模型将同时删除该模型下的所有字段,且无法恢复。']]) // 批量添加右侧按钮
|
||||
->setRowList($data_list) // 设置表格数据
|
||||
->fetch(); // 渲染模板
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增内容模型
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return mixed
|
||||
* @throws \think\Exception
|
||||
*/
|
||||
public function add()
|
||||
{
|
||||
// 保存数据
|
||||
if ($this->request->isPost()) {
|
||||
$data = $this->request->post();
|
||||
|
||||
if ($data['table'] == '') {
|
||||
$data['table'] = config('database.prefix') . 'cms_document_' . $data['name'];
|
||||
} else {
|
||||
$data['table'] = str_replace('#@__', config('database.prefix'), $data['table']);
|
||||
}
|
||||
|
||||
// 验证
|
||||
$result = $this->validate($data, 'Model');
|
||||
if(true !== $result) $this->error($result);
|
||||
// 严格验证附加表是否存在
|
||||
if (table_exist($data['table'])) {
|
||||
$this->error('附加表已存在');
|
||||
}
|
||||
|
||||
if ($model = DocumentModel::create($data)) {
|
||||
// 创建附加表
|
||||
if (false === DocumentModel::createTable($model)) {
|
||||
$this->error('创建附加表失败');
|
||||
}
|
||||
// 创建菜单节点
|
||||
$map = [
|
||||
'module' => 'cms',
|
||||
'title' => '内容管理'
|
||||
];
|
||||
$menu_data = [
|
||||
"module" => "cms",
|
||||
"pid" => Db::name('admin_menu')->where($map)->value('id'),
|
||||
"title" => $data['title'],
|
||||
"url_type" => "module_admin",
|
||||
"url_value" => "cms/content/{$data['name']}",
|
||||
"url_target" => "_self",
|
||||
"icon" => "fa fa-fw fa-list",
|
||||
"online_hide" => "0",
|
||||
"sort" => "100",
|
||||
];
|
||||
MenuModel::create($menu_data);
|
||||
|
||||
// 记录行为
|
||||
action_log('model_add', 'cms_model', $model['id'], UID, $data['title']);
|
||||
Cache::clear();
|
||||
$this->success('新增成功', 'index');
|
||||
} else {
|
||||
$this->error('新增失败');
|
||||
}
|
||||
}
|
||||
|
||||
$type_tips = '此选项添加后不可更改。如果为 <code>系统模型</code> 将禁止删除,对于 <code>独立模型</code>,将强制创建字段id,cid,uid,model,title,create_time,update_time,sort,status,trash,view';
|
||||
|
||||
// 显示添加页面
|
||||
return ZBuilder::make('form')
|
||||
->addFormItems([
|
||||
['text', 'name', '模型标识', '由小写字母、数字或下划线组成,不能以数字开头'],
|
||||
['text', 'title', '模型标题', '可填写中文'],
|
||||
['text', 'table', '附加表', '创建后不可更改。由小写字母、数字或下划线组成,如果不填写默认为 <code>'. config('database.prefix') . 'cms_document_模型标识</code>,如果需要自定义,请务必填写系统表前缀,<code>#@__</code>表示当前系统表前缀'],
|
||||
['radio', 'type', '模型类别', $type_tips, ['系统模型', '普通模型', '独立模型(不使用主表)'], 1],
|
||||
['icon', 'icon', '图标'],
|
||||
['radio', 'status', '立即启用', '', ['否', '是'], 1],
|
||||
['text', 'sort', '排序', '', 100],
|
||||
])
|
||||
->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑内容模型
|
||||
* @param null $id 模型id
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return mixed
|
||||
* @throws \think\Exception
|
||||
*/
|
||||
public function edit($id = null) {
|
||||
if ($id === null) $this->error('参数错误');
|
||||
|
||||
// 保存数据
|
||||
if ($this->request->isPost()) {
|
||||
$data = $this->request->post();
|
||||
|
||||
// 验证
|
||||
$result = $this->validate($data, 'Model.edit');
|
||||
if(true !== $result) $this->error($result);
|
||||
|
||||
if (DocumentModel::update($data)) {
|
||||
cache('cms_model_list', null);
|
||||
cache('cms_model_title_list', null);
|
||||
// 记录行为
|
||||
action_log('model_edit', 'cms_model', $id, UID, "ID({$id}),标题({$data['title']})");
|
||||
$this->success('编辑成功', 'index');
|
||||
} else {
|
||||
$this->error('编辑失败');
|
||||
}
|
||||
}
|
||||
|
||||
$list_model_type = ['系统模型', '普通模型', '独立模型(不使用主表)'];
|
||||
|
||||
// 模型信息
|
||||
$info = DocumentModel::get($id);
|
||||
$info['type'] = $list_model_type[$info['type']];
|
||||
|
||||
// 显示编辑页面
|
||||
return ZBuilder::make('form')
|
||||
->addFormItems([
|
||||
['hidden', 'id'],
|
||||
['hidden', 'name'],
|
||||
['static', 'name', '模型标识'],
|
||||
['static', 'type', '模型类别'],
|
||||
['static', 'table', '附加表'],
|
||||
['text', 'title', '模型标题', '可填写中文'],
|
||||
['icon', 'icon', '图标'],
|
||||
['radio', 'status', '立即启用', '', ['否', '是']],
|
||||
['text', 'sort', '排序'],
|
||||
])
|
||||
->setFormData($info)
|
||||
->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除内容模型
|
||||
* @param null $ids 内容模型id
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @throws \think\Exception
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @throws \think\exception\DbException
|
||||
* @throws \think\exception\PDOException
|
||||
*/
|
||||
public function delete($ids = null)
|
||||
{
|
||||
if ($ids === null) $this->error('参数错误');
|
||||
|
||||
$model = DocumentModel::where('id', $ids)->find();
|
||||
if ($model['type'] == 0) {
|
||||
$this->error('禁止删除系统模型');
|
||||
}
|
||||
|
||||
// 删除表和字段信息
|
||||
if (DocumentModel::deleteTable($ids)) {
|
||||
// 删除主表中的文档
|
||||
if (false === Db::name('cms_document')->where('model', $ids)->delete()) {
|
||||
$this->error('删除主表文档失败');
|
||||
}
|
||||
// 删除菜单节点
|
||||
$map = [
|
||||
'module' => 'cms',
|
||||
'url_value' => "cms/content/{$model['name']}"
|
||||
];
|
||||
if (false === Db::name('admin_menu')->where($map)->delete()) {
|
||||
$this->error('删除菜单节点失败');
|
||||
}
|
||||
// 删除字段数据
|
||||
if (false !== Db::name('cms_field')->where('model', $ids)->delete()) {
|
||||
cache('cms_model_list', null);
|
||||
cache('cms_model_title_list', null);
|
||||
return parent::delete();
|
||||
} else {
|
||||
$this->error('删除内容模型字段失败');
|
||||
}
|
||||
} else {
|
||||
$this->error('删除内容模型表失败');
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,175 @@
|
|||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | 海豚PHP框架 [ DolphinPHP ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 版权所有 2016~2019 广东卓锐软件有限公司 [ http://www.zrthink.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网站: http://dolphinphp.com
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace app\cms\admin;
|
||||
|
||||
use app\admin\controller\Admin;
|
||||
use app\common\builder\ZBuilder;
|
||||
use app\cms\model\Nav as NavModel;
|
||||
use app\cms\model\Menu as MenuModel;
|
||||
|
||||
/**
|
||||
* 导航控制器
|
||||
* @package app\cms\admin
|
||||
*/
|
||||
class Nav extends Admin
|
||||
{
|
||||
/**
|
||||
* 导航列表
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return mixed
|
||||
* @throws \think\Exception
|
||||
* @throws \think\exception\DbException
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
// 查询
|
||||
$map = $this->getMap();
|
||||
// 排序
|
||||
$order = $this->getOrder('update_time desc');
|
||||
// 数据列表
|
||||
$data_list = NavModel::where($map)->order($order)->paginate();
|
||||
|
||||
// 自定义按钮
|
||||
$btnMenuList = [
|
||||
'title' => '菜单列表',
|
||||
'icon' => 'fa fa-list',
|
||||
'href' => url('menu/index', ['id' => '__id__'])
|
||||
];
|
||||
|
||||
// 使用ZBuilder快速创建数据表格
|
||||
return ZBuilder::make('table')
|
||||
->setSearch(['title' => '标题'])// 设置搜索框
|
||||
->addColumns([ // 批量添加数据列
|
||||
['id', 'ID'],
|
||||
['tag', '标识', 'text.edit'],
|
||||
['title', '标题', 'text.edit'],
|
||||
['create_time', '创建时间', 'datetime'],
|
||||
['update_time', '更新时间', 'datetime'],
|
||||
['status', '状态', 'switch'],
|
||||
['right_button', '操作', 'btn']
|
||||
])
|
||||
->addTopButtons('add,enable,disable,delete')// 批量添加顶部按钮
|
||||
->addRightButton('custom', $btnMenuList)
|
||||
->addRightButton('delete', ['data-tips' => '删除后无法恢复。'])// 批量添加右侧按钮
|
||||
->addOrder('id,title,create_time,update_time')
|
||||
->setRowList($data_list)// 设置表格数据
|
||||
->addValidate('Nav', 'tag,title')
|
||||
->fetch(); // 渲染模板
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return mixed
|
||||
* @throws \think\Exception
|
||||
*/
|
||||
public function add()
|
||||
{
|
||||
// 保存数据
|
||||
if ($this->request->isPost()) {
|
||||
// 表单数据
|
||||
$data = $this->request->post();
|
||||
|
||||
// 验证
|
||||
$result = $this->validate($data, 'Nav');
|
||||
if(true !== $result) $this->error($result);
|
||||
|
||||
if ($nav = NavModel::create($data)) {
|
||||
// 记录行为
|
||||
action_log('nav_add', 'cms_nav', $nav['id'], UID, $data['title']);
|
||||
$this->success('新增成功', 'index');
|
||||
} else {
|
||||
$this->error('新增失败');
|
||||
}
|
||||
}
|
||||
|
||||
// 显示添加页面
|
||||
return ZBuilder::make('form')
|
||||
->addFormItems([
|
||||
['text', 'tag', '菜单标识', '由字母和下划线组成,如:main_nav'],
|
||||
['text', 'title', '菜单标题', '必填'],
|
||||
['radio', 'status', '立即启用', '', ['否', '是'], 1]
|
||||
])
|
||||
->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除导航
|
||||
* @param null $ids 菜单id
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return mixed
|
||||
* @throws \think\Exception
|
||||
* @throws \think\exception\PDOException
|
||||
*/
|
||||
public function delete($ids = null)
|
||||
{
|
||||
if ($ids === null) $this->error('参数错误');
|
||||
// 删除该导航的所有子菜单
|
||||
if (false === MenuModel::where('nid', 'in', $ids)->delete()) {
|
||||
$this->error('删除失败');
|
||||
}
|
||||
return $this->setStatus('delete');
|
||||
}
|
||||
|
||||
/**
|
||||
* 启用导航
|
||||
* @param array $record 行为日志
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @throws \think\Exception
|
||||
* @throws \think\exception\PDOException
|
||||
*/
|
||||
public function enable($record = [])
|
||||
{
|
||||
return $this->setStatus('enable');
|
||||
}
|
||||
|
||||
/**
|
||||
* 禁用导航
|
||||
* @param array $record 行为日志
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @throws \think\Exception
|
||||
* @throws \think\exception\PDOException
|
||||
*/
|
||||
public function disable($record = [])
|
||||
{
|
||||
return $this->setStatus('disable');
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置导航状态:删除、禁用、启用
|
||||
* @param string $type 类型:delete/enable/disable
|
||||
* @param array $record
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @throws \think\Exception
|
||||
* @throws \think\exception\PDOException
|
||||
*/
|
||||
public function setStatus($type = '', $record = [])
|
||||
{
|
||||
$ids = $this->request->isPost() ? input('post.ids/a') : input('param.ids');
|
||||
$nav_title = NavModel::where('id', 'in', $ids)->column('title');
|
||||
return parent::setStatus($type, ['nav_'.$type, 'cms_nav', 0, UID, implode('、', $nav_title)]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 快速编辑
|
||||
* @param array $record 行为日志
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return mixed
|
||||
*/
|
||||
public function quickEdit($record = [])
|
||||
{
|
||||
$id = input('post.pk', '');
|
||||
$field = input('post.name', '');
|
||||
$value = input('post.value', '');
|
||||
$nav = NavModel::where('id', $id)->value($field);
|
||||
$details = '字段(' . $field . '),原值(' . $nav . '),新值:(' . $value . ')';
|
||||
return parent::quickEdit(['nav_edit', 'cms_nav', $id, UID, $details]);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,212 @@
|
|||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | 海豚PHP框架 [ DolphinPHP ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 版权所有 2016~2019 广东卓锐软件有限公司 [ http://www.zrthink.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网站: http://dolphinphp.com
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace app\cms\admin;
|
||||
|
||||
use app\admin\controller\Admin;
|
||||
use app\common\builder\ZBuilder;
|
||||
use app\cms\model\Page as PageModel;
|
||||
|
||||
/**
|
||||
* 单页控制器
|
||||
* @package app\cms\admin
|
||||
*/
|
||||
class Page extends Admin
|
||||
{
|
||||
/**
|
||||
* 单页列表
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return mixed
|
||||
* @throws \think\Exception
|
||||
* @throws \think\exception\DbException
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
// 查询
|
||||
$map = $this->getMap();
|
||||
// 排序
|
||||
$order = $this->getOrder();
|
||||
// 数据列表
|
||||
$data_list = PageModel::where($map)->order($order)->paginate();
|
||||
|
||||
// 使用ZBuilder快速创建数据表格
|
||||
return ZBuilder::make('table')
|
||||
->setSearch(['title' => '标题']) // 设置搜索框
|
||||
->addColumns([ // 批量添加数据列
|
||||
['id', 'ID'],
|
||||
['title', '标题', 'text.edit'],
|
||||
['create_time', '创建时间', 'datetime'],
|
||||
['update_time', '更新时间', 'datetime'],
|
||||
['status', '状态', 'switch'],
|
||||
['right_button', '操作', 'btn']
|
||||
])
|
||||
->addTopButtons('add,enable,disable,delete') // 批量添加顶部按钮
|
||||
->addRightButtons(['edit', 'delete' => ['data-tips' => '删除后无法恢复。']]) // 批量添加右侧按钮
|
||||
->addOrder('id,title,create_time,update_time')
|
||||
->setRowList($data_list) // 设置表格数据
|
||||
->addValidate('Page', 'title')
|
||||
->fetch(); // 渲染模板
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return mixed
|
||||
* @throws \think\Exception
|
||||
*/
|
||||
public function add()
|
||||
{
|
||||
// 保存数据
|
||||
if ($this->request->isPost()) {
|
||||
// 表单数据
|
||||
$data = $this->request->post();
|
||||
|
||||
// 验证
|
||||
$result = $this->validate($data, 'Page');
|
||||
if(true !== $result) $this->error($result);
|
||||
|
||||
if ($page = PageModel::create($data)) {
|
||||
// 记录行为
|
||||
action_log('page_add', 'cms_page', $page['id'], UID, $data['title']);
|
||||
$this->success('新增成功', 'index');
|
||||
} else {
|
||||
$this->error('新增失败');
|
||||
}
|
||||
}
|
||||
|
||||
// 显示添加页面
|
||||
return ZBuilder::make('form')
|
||||
->addFormItems([
|
||||
['text', 'title', '页面标题'],
|
||||
['tags', 'keywords', '页面关键词', '关键字之间用英文逗号隔开'],
|
||||
['textarea', 'description', '页面描述', '100字左右'],
|
||||
['text', 'template', '模板文件名'],
|
||||
['ckeditor', 'content', '页面内容'],
|
||||
['image', 'cover', '单页封面'],
|
||||
['text', 'view', '阅读量', '', 0],
|
||||
['radio', 'status', '立即启用', '', ['否', '是'], 1]
|
||||
])
|
||||
->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑
|
||||
* @param null $id 单页id
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return mixed
|
||||
* @throws \think\Exception
|
||||
*/
|
||||
public function edit($id = null)
|
||||
{
|
||||
if ($id === null) $this->error('缺少参数');
|
||||
|
||||
// 保存数据
|
||||
if ($this->request->isPost()) {
|
||||
// 表单数据
|
||||
$data = $this->request->post();
|
||||
|
||||
// 验证
|
||||
$result = $this->validate($data, 'Page');
|
||||
if(true !== $result) $this->error($result);
|
||||
|
||||
if (PageModel::update($data)) {
|
||||
// 记录行为
|
||||
action_log('page_edit', 'cms_page', $id, UID, $data['title']);
|
||||
$this->success('编辑成功', 'index');
|
||||
} else {
|
||||
$this->error('编辑失败');
|
||||
}
|
||||
}
|
||||
|
||||
$info = PageModel::get($id);
|
||||
|
||||
// 显示编辑页面
|
||||
return ZBuilder::make('form')
|
||||
->addFormItems([
|
||||
['hidden', 'id'],
|
||||
['text', 'title', '页面标题'],
|
||||
['tags', 'keywords', '页面关键词', '关键字之间用英文逗号隔开'],
|
||||
['textarea', 'description', '页面描述', '100字左右'],
|
||||
['text', 'template', '模板文件名'],
|
||||
['ckeditor', 'content', '页面内容'],
|
||||
['image', 'cover', '单页封面'],
|
||||
['text', 'view', '阅读量', '', 0],
|
||||
['radio', 'status', '立即启用', '', ['否', '是']]
|
||||
])
|
||||
->setFormdata($info)
|
||||
->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除单页
|
||||
* @param array $record 行为日志
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @throws \think\Exception
|
||||
* @throws \think\exception\PDOException
|
||||
*/
|
||||
public function delete($record = [])
|
||||
{
|
||||
return $this->setStatus('delete');
|
||||
}
|
||||
|
||||
/**
|
||||
* 启用单页
|
||||
* @param array $record 行为日志
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @throws \think\Exception
|
||||
* @throws \think\exception\PDOException
|
||||
*/
|
||||
public function enable($record = [])
|
||||
{
|
||||
return $this->setStatus('enable');
|
||||
}
|
||||
|
||||
/**
|
||||
* 禁用单页
|
||||
* @param array $record 行为日志
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @throws \think\Exception
|
||||
* @throws \think\exception\PDOException
|
||||
*/
|
||||
public function disable($record = [])
|
||||
{
|
||||
return $this->setStatus('disable');
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置单页状态:删除、禁用、启用
|
||||
* @param string $type 类型:delete/enable/disable
|
||||
* @param array $record
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @throws \think\Exception
|
||||
* @throws \think\exception\PDOException
|
||||
*/
|
||||
public function setStatus($type = '', $record = [])
|
||||
{
|
||||
$ids = $this->request->isPost() ? input('post.ids/a') : input('param.ids');
|
||||
$page_title = PageModel::where('id', 'in', $ids)->column('title');
|
||||
return parent::setStatus($type, ['page_'.$type, 'cms_page', 0, UID, implode('、', $page_title)]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 快速编辑
|
||||
* @param array $record 行为日志
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return mixed
|
||||
*/
|
||||
public function quickEdit($record = [])
|
||||
{
|
||||
$id = input('post.pk', '');
|
||||
$field = input('post.name', '');
|
||||
$value = input('post.value', '');
|
||||
$page = PageModel::where('id', $id)->value($field);
|
||||
$details = '字段(' . $field . '),原值(' . $page . '),新值:(' . $value . ')';
|
||||
return parent::quickEdit(['page_edit', 'cms_page', $id, UID, $details]);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,202 @@
|
|||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | 海豚PHP框架 [ DolphinPHP ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 版权所有 2016~2019 广东卓锐软件有限公司 [ http://www.zrthink.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网站: http://dolphinphp.com
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace app\cms\admin;
|
||||
|
||||
use app\admin\controller\Admin;
|
||||
use app\common\builder\ZBuilder;
|
||||
use app\cms\model\Document as DocumentModel;
|
||||
use think\Db;
|
||||
|
||||
/**
|
||||
* 回收站控制器
|
||||
* @package app\cms\admin
|
||||
*/
|
||||
class Recycle extends Admin
|
||||
{
|
||||
/**
|
||||
* 文档列表
|
||||
* @param string $model 内容模型id
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return mixed
|
||||
* @throws \think\Exception
|
||||
* @throws \think\exception\DbException
|
||||
*/
|
||||
public function index($model = '')
|
||||
{
|
||||
if ($model == '') {
|
||||
// 查询
|
||||
$map = $this->getMap();
|
||||
$map[] = ['cms_document.trash', '=', 1];
|
||||
// 排序
|
||||
$order = $this->getOrder('update_time desc');
|
||||
// 数据列表
|
||||
$data_list = DocumentModel::getList($map, $order);
|
||||
|
||||
// 自定义按钮
|
||||
$btnRestore = [
|
||||
'class' => 'btn btn-xs btn-default ajax-get confirm',
|
||||
'icon' => 'fa fa-fw fa-reply',
|
||||
'title' => '还原',
|
||||
'href' => url('restore', ['ids' => '__id__'])
|
||||
];
|
||||
$btnRestoreAll = [
|
||||
'class' => 'btn btn-success ajax-post confirm',
|
||||
'icon' => 'fa fa-fw fa-reply-all',
|
||||
'title' => '批量还原',
|
||||
'href' => url('restore')
|
||||
];
|
||||
|
||||
// 使用ZBuilder快速创建数据表格
|
||||
return ZBuilder::make('table')
|
||||
->setSearch(['title' => '标题', 'cms_column.name' => '栏目名称']) // 设置搜索框
|
||||
->addColumns([ // 批量添加数据列
|
||||
['id', 'ID'],
|
||||
['title', '标题'],
|
||||
['column_name', '栏目名称'],
|
||||
['view', '点击量'],
|
||||
['username', '发布人'],
|
||||
['update_time', '更新时间', 'datetime'],
|
||||
['right_button', '操作', 'btn']
|
||||
])
|
||||
->addTopButton('enable', $btnRestoreAll) // 批量添加顶部按钮
|
||||
->addTopButton('delete', ['title' => '批量删除', 'href' => url('delete'), 'data-tips' => '删除后不可回复!']) // 批量添加顶部按钮
|
||||
->addRightButton('custom', $btnRestore) // 添加右侧按钮
|
||||
->addRightButton('delete', ['href' => url('delete', ['ids' => '__id__']), 'data-tips' => '删除后不可回复!']) // 添加右侧按钮
|
||||
->addOrder('id,title,column_name,view,username,update_time')
|
||||
->addFilter(['column_name' => 'cms_column.name', 'username' => 'admin_user'])
|
||||
->setRowList($data_list) // 设置表格数据
|
||||
->fetch(); // 渲染模板
|
||||
} else {
|
||||
$table_name = get_model_table($model);
|
||||
|
||||
// 查询
|
||||
$map = $this->getMap();
|
||||
$map[] = ['trash', '=', 1];
|
||||
|
||||
// 排序
|
||||
$order = $this->getOrder('update_time desc');
|
||||
// 数据列表
|
||||
$data_list = Db::view($table_name, true)
|
||||
->view("cms_column", ['name' => 'column_name'], 'cms_column.id='.$table_name.'.cid', 'left')
|
||||
->view("admin_user", 'username', 'admin_user.id='.$table_name.'.uid', 'left')
|
||||
->where($map)
|
||||
->order($order)
|
||||
->paginate();
|
||||
|
||||
// 自定义按钮
|
||||
$btnRestore = [
|
||||
'class' => 'btn btn-xs btn-default ajax-get confirm',
|
||||
'icon' => 'fa fa-fw fa-reply',
|
||||
'title' => '还原',
|
||||
'href' => url('restore', ['table' => $table_name, 'ids' => '__id__'])
|
||||
];
|
||||
$btnRestoreAll = [
|
||||
'class' => 'btn btn-success ajax-post confirm',
|
||||
'icon' => 'fa fa-fw fa-reply-all',
|
||||
'title' => '批量还原',
|
||||
'href' => url('restore', ['table' => $table_name])
|
||||
];
|
||||
|
||||
// 使用ZBuilder快速创建数据表格
|
||||
return ZBuilder::make('table')
|
||||
->setSearch(['title' => '标题', 'cms_column.name' => '栏目名称']) // 设置搜索框
|
||||
->addColumns([ // 批量添加数据列
|
||||
['id', 'ID'],
|
||||
['title', '标题'],
|
||||
['column_name', '栏目名称'],
|
||||
['view', '点击量'],
|
||||
['username', '发布人'],
|
||||
['update_time', '更新时间', 'datetime'],
|
||||
['right_button', '操作', 'btn']
|
||||
])
|
||||
->addTopButton('enable', $btnRestoreAll) // 添加顶部按钮
|
||||
->addTopButton('delete', ['title' => '批量删除', 'href' => url('delete', ['table' => $table_name]), 'data-tips' => '删除后不可回复!']) // 添加顶部按钮
|
||||
->addRightButton('custom', $btnRestore) // 添加右侧按钮
|
||||
->addRightButton('delete', ['href' => url('delete', ['ids' => '__id__', 'table' => $table_name]), 'data-tips' => '删除后不可回复!']) // 添加右侧按钮
|
||||
->addOrder('id,title,column_name,view,username,update_time')
|
||||
->addFilter(['column_name' => 'cms_column.name', 'username' => 'admin_user'])
|
||||
->setRowList($data_list) // 设置表格数据
|
||||
->fetch(); // 渲染模板
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 还原文档
|
||||
* @param null $ids 文档id
|
||||
* @param string $table 表名
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
*/
|
||||
public function restore($ids = null, $table = '')
|
||||
{
|
||||
if ($ids === null) $this->error('请选择要操作的数据');
|
||||
$table = $table != '' ? substr($table, strlen(config('database.prefix'))) : 'cms_document';
|
||||
|
||||
$document_id = is_array($ids) ? '' : $ids;
|
||||
$document_title = Db::name($table)->where('id', 'in', $ids)->column('title');
|
||||
|
||||
// 还原文档
|
||||
if (false === Db::name($table)->where('id', 'in', $ids)->setField('trash', 0)) {
|
||||
$this->error('还原失败');
|
||||
}
|
||||
|
||||
// 删除并记录日志
|
||||
action_log('document_restore', $table, $document_id, UID, implode('、', $document_title));
|
||||
$this->success('还原成功');
|
||||
}
|
||||
|
||||
/**
|
||||
* 彻底删除文档
|
||||
* @param null $ids 文档id
|
||||
* @param string $table 表名
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @throws \think\Exception
|
||||
* @throws \think\exception\PDOException
|
||||
*/
|
||||
public function delete($ids = null, $table = '')
|
||||
{
|
||||
if ($ids === null) $this->error('请选择要操作的数据');
|
||||
$ids = is_array($ids) ? $ids : (array)$ids;
|
||||
|
||||
if ($table == '') {
|
||||
// 获取文档标题和模型id
|
||||
$data_list = Db::name('cms_document')->where('id', 'in', $ids)->column('id,model,title');
|
||||
|
||||
foreach ($data_list as $document) {
|
||||
// 附加表名
|
||||
$extra_table = get_model_table($document['model']);
|
||||
|
||||
// 删除附加表文档
|
||||
if (false === Db::table($extra_table)->where('aid', $document['id'])->delete()) {
|
||||
$this->error('删除文档:'. $document['title']. ' 失败');
|
||||
}
|
||||
|
||||
// 删除主表文档
|
||||
if (false === Db::name('cms_document')->where('id', $document['id'])->delete()) {
|
||||
$this->error('删除失败');
|
||||
}
|
||||
|
||||
// 记录行为
|
||||
action_log('document_delete', 'cms_document', $document['id'], UID, $document['title']);
|
||||
}
|
||||
} else {
|
||||
// 文档标题
|
||||
$document_title = Db::table($table)->where('id', 'in', $ids)->column('title');
|
||||
|
||||
// 删除独立文档
|
||||
if (false === Db::table($table)->where('id', 'in', $ids)->delete()) {
|
||||
$this->error('删除失败');
|
||||
}
|
||||
|
||||
// 记录行为
|
||||
action_log('document_delete', $table, 0, UID, '表('.$table.'),文档('.implode('、', $document_title).')');
|
||||
}
|
||||
$this->success('删除成功');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,208 @@
|
|||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | 海豚PHP框架 [ DolphinPHP ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 版权所有 2016~2019 广东卓锐软件有限公司 [ http://www.zrthink.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网站: http://dolphinphp.com
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace app\cms\admin;
|
||||
|
||||
use app\admin\controller\Admin;
|
||||
use app\common\builder\ZBuilder;
|
||||
use app\cms\model\Slider as SliderModel;
|
||||
|
||||
/**
|
||||
* 滚动图片控制器
|
||||
* @package app\cms\admin
|
||||
*/
|
||||
class Slider extends Admin
|
||||
{
|
||||
/**
|
||||
* 滚动图片列表
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return mixed
|
||||
* @throws \think\Exception
|
||||
* @throws \think\exception\DbException
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
// 查询
|
||||
$map = $this->getMap();
|
||||
// 排序
|
||||
$order = $this->getOrder();
|
||||
// 数据列表
|
||||
$data_list = SliderModel::where($map)->order($order)->paginate();
|
||||
|
||||
// 使用ZBuilder快速创建数据表格
|
||||
return ZBuilder::make('table')
|
||||
->setSearch(['title' => '标题']) // 设置搜索框
|
||||
->addColumns([ // 批量添加数据列
|
||||
['id', 'ID'],
|
||||
['cover', '图片', 'picture'],
|
||||
['title', '标题', 'text.edit'],
|
||||
['url', '链接', 'text.edit'],
|
||||
['create_time', '创建时间', 'datetime'],
|
||||
['sort', '排序', 'text.edit'],
|
||||
['status', '状态', 'switch'],
|
||||
['right_button', '操作', 'btn']
|
||||
])
|
||||
->addTopButtons('add,enable,disable,delete') // 批量添加顶部按钮
|
||||
->addRightButtons(['edit', 'delete' => ['data-tips' => '删除后无法恢复。']]) // 批量添加右侧按钮
|
||||
->addOrder('id,title,create_time')
|
||||
->setRowList($data_list) // 设置表格数据
|
||||
->addValidate('Slider', 'title,url')
|
||||
->fetch(); // 渲染模板
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return mixed
|
||||
* @throws \think\Exception
|
||||
*/
|
||||
public function add()
|
||||
{
|
||||
// 保存数据
|
||||
if ($this->request->isPost()) {
|
||||
// 表单数据
|
||||
$data = $this->request->post();
|
||||
|
||||
// 验证
|
||||
$result = $this->validate($data, 'Slider');
|
||||
if(true !== $result) $this->error($result);
|
||||
|
||||
if ($slider = SliderModel::create($data)) {
|
||||
// 记录行为
|
||||
action_log('slider_add', 'cms_slider', $slider['id'], UID, $data['title']);
|
||||
$this->success('新增成功', 'index');
|
||||
} else {
|
||||
$this->error('新增失败');
|
||||
}
|
||||
}
|
||||
|
||||
// 显示添加页面
|
||||
return ZBuilder::make('form')
|
||||
->addFormItems([
|
||||
['text', 'title', '标题'],
|
||||
['image', 'cover', '图片'],
|
||||
['text', 'url', '链接'],
|
||||
['text', 'sort', '排序', '', 100],
|
||||
['radio', 'status', '立即启用', '', ['否', '是'], 1]
|
||||
])
|
||||
->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑
|
||||
* @param null $id 滚动图片id
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return mixed
|
||||
* @throws \think\Exception
|
||||
*/
|
||||
public function edit($id = null)
|
||||
{
|
||||
if ($id === null) $this->error('缺少参数');
|
||||
|
||||
// 保存数据
|
||||
if ($this->request->isPost()) {
|
||||
// 表单数据
|
||||
$data = $this->request->post();
|
||||
|
||||
// 验证
|
||||
$result = $this->validate($data, 'Slider');
|
||||
if(true !== $result) $this->error($result);
|
||||
|
||||
if (SliderModel::update($data)) {
|
||||
// 记录行为
|
||||
action_log('slider_add', 'cms_slider', $id, UID, $data['title']);
|
||||
$this->success('编辑成功', 'index');
|
||||
} else {
|
||||
$this->error('编辑失败');
|
||||
}
|
||||
}
|
||||
|
||||
$info = SliderModel::get($id);
|
||||
|
||||
// 显示编辑页面
|
||||
return ZBuilder::make('form')
|
||||
->addFormItems([
|
||||
['hidden', 'id'],
|
||||
['text', 'title', '标题'],
|
||||
['image', 'cover', '图片'],
|
||||
['text', 'url', '链接'],
|
||||
['text', 'sort', '排序'],
|
||||
['radio', 'status', '立即启用', '', ['否', '是']]
|
||||
])
|
||||
->setFormData($info)
|
||||
->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除单页
|
||||
* @param array $record 行为日志
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @throws \think\Exception
|
||||
* @throws \think\exception\PDOException
|
||||
*/
|
||||
public function delete($record = [])
|
||||
{
|
||||
return $this->setStatus('delete');
|
||||
}
|
||||
|
||||
/**
|
||||
* 启用单页
|
||||
* @param array $record 行为日志
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @throws \think\Exception
|
||||
* @throws \think\exception\PDOException
|
||||
*/
|
||||
public function enable($record = [])
|
||||
{
|
||||
return $this->setStatus('enable');
|
||||
}
|
||||
|
||||
/**
|
||||
* 禁用单页
|
||||
* @param array $record 行为日志
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @throws \think\Exception
|
||||
* @throws \think\exception\PDOException
|
||||
*/
|
||||
public function disable($record = [])
|
||||
{
|
||||
return $this->setStatus('disable');
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置单页状态:删除、禁用、启用
|
||||
* @param string $type 类型:delete/enable/disable
|
||||
* @param array $record
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @throws \think\Exception
|
||||
* @throws \think\exception\PDOException
|
||||
*/
|
||||
public function setStatus($type = '', $record = [])
|
||||
{
|
||||
$ids = $this->request->isPost() ? input('post.ids/a') : input('param.ids');
|
||||
$slider_title = SliderModel::where('id', 'in', $ids)->column('title');
|
||||
return parent::setStatus($type, ['slider_'.$type, 'cms_slider', 0, UID, implode('、', $slider_title)]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 快速编辑
|
||||
* @param array $record 行为日志
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return mixed
|
||||
*/
|
||||
public function quickEdit($record = [])
|
||||
{
|
||||
$id = input('post.pk', '');
|
||||
$field = input('post.name', '');
|
||||
$value = input('post.value', '');
|
||||
$slider = SliderModel::where('id', $id)->value($field);
|
||||
$details = '字段(' . $field . '),原值(' . $slider . '),新值:(' . $value . ')';
|
||||
return parent::quickEdit(['slider_edit', 'cms_slider', $id, UID, $details]);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,220 @@
|
|||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | 海豚PHP框架 [ DolphinPHP ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 版权所有 2016~2019 广东卓锐软件有限公司 [ http://www.zrthink.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网站: http://dolphinphp.com
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace app\cms\admin;
|
||||
|
||||
use app\admin\controller\Admin;
|
||||
use app\common\builder\ZBuilder;
|
||||
use app\cms\model\Support as SupportModel;
|
||||
|
||||
/**
|
||||
* 客服控制器
|
||||
* @package app\cms\admin
|
||||
*/
|
||||
class Support extends Admin
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
// 查询
|
||||
$map = $this->getMap();
|
||||
// 排序
|
||||
$order = $this->getOrder();
|
||||
// 数据列表
|
||||
$data_list = SupportModel::where($map)->order($order)->paginate();
|
||||
|
||||
$search = [
|
||||
'name' => '客服名称',
|
||||
'qq' => 'QQ',
|
||||
'msn' => 'MSN',
|
||||
'taobao' => '淘宝旺旺',
|
||||
'alibaba' => '阿里旺旺',
|
||||
'skype' => 'SKYPE'
|
||||
];
|
||||
|
||||
// 使用ZBuilder快速创建数据表格
|
||||
return ZBuilder::make('table')
|
||||
->setPageTips('添加的QQ需要到【shang.qq.com】登录后在【商家沟通组建—设置】开启QQ的在线状态,否则将显示“未启用”<br>开启和关闭在线客服功能,以及更多设置,请在 <a class="alert-link link-effect" href="'.url('admin/system/index', ['group' => 'cms']).'">系统设置</a> 中操作。')
|
||||
->setSearch($search) // 设置搜索框
|
||||
->addColumns([ // 批量添加数据列
|
||||
['id', 'ID'],
|
||||
['name', '客服名称', 'text.edit'],
|
||||
['qq', 'QQ'],
|
||||
['msn', 'MSN'],
|
||||
['taobao', '淘宝旺旺'],
|
||||
['alibaba', '阿里旺旺'],
|
||||
['skype', 'SKYPE'],
|
||||
['create_time', '创建时间', 'datetime'],
|
||||
['sort', '排序', 'text.edit'],
|
||||
['status', '状态', 'switch'],
|
||||
['right_button', '操作', 'btn']
|
||||
])
|
||||
->addTopButtons('add,enable,disable,delete') // 批量添加顶部按钮
|
||||
->addRightButtons(['edit', 'delete' => ['data-tips' => '删除后无法恢复。']]) // 批量添加右侧按钮
|
||||
->addOrder('id,name,create_time,update_time')
|
||||
->addValidate('Support', 'name')
|
||||
->setRowList($data_list) // 设置表格数据
|
||||
->fetch(); // 渲染模板
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return mixed
|
||||
* @throws \think\Exception
|
||||
*/
|
||||
public function add()
|
||||
{
|
||||
// 保存数据
|
||||
if ($this->request->isPost()) {
|
||||
// 表单数据
|
||||
$data = $this->request->post();
|
||||
|
||||
// 验证
|
||||
$result = $this->validate($data, 'Support');
|
||||
if(true !== $result) $this->error($result);
|
||||
|
||||
if ($support = SupportModel::create($data)) {
|
||||
// 记录行为
|
||||
action_log('support_add', 'cms_support', $support['id'], UID, $data['name']);
|
||||
$this->success('新增成功', 'index');
|
||||
} else {
|
||||
$this->error('新增失败');
|
||||
}
|
||||
}
|
||||
|
||||
// 显示添加页面
|
||||
return ZBuilder::make('form')
|
||||
->addFormItems([
|
||||
['text', 'name', '客服名称'],
|
||||
['text', 'qq', 'QQ号码'],
|
||||
['text', 'msn', 'MSN号码'],
|
||||
['text', 'taobao', '淘宝旺旺'],
|
||||
['text', 'alibaba', '阿里旺旺'],
|
||||
['text', 'skype', 'SKYPE'],
|
||||
['text', 'sort', '排序', '', 100],
|
||||
['radio', 'status', '立即启用', '', ['否', '是'], 1]
|
||||
])
|
||||
->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑
|
||||
* @param null $id 客服id
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return mixed
|
||||
* @throws \think\Exception
|
||||
*/
|
||||
public function edit($id = null)
|
||||
{
|
||||
if ($id === null) $this->error('缺少参数');
|
||||
|
||||
// 保存数据
|
||||
if ($this->request->isPost()) {
|
||||
// 表单数据
|
||||
$data = $this->request->post();
|
||||
|
||||
// 验证
|
||||
$result = $this->validate($data, 'Support');
|
||||
if(true !== $result) $this->error($result);
|
||||
|
||||
if (SupportModel::update($data)) {
|
||||
// 记录行为
|
||||
action_log('support_edit', 'cms_support', $id, UID, $data['name']);
|
||||
$this->success('编辑成功', 'index');
|
||||
} else {
|
||||
$this->error('编辑失败');
|
||||
}
|
||||
}
|
||||
|
||||
$info = SupportModel::get($id);
|
||||
|
||||
// 显示编辑页面
|
||||
return ZBuilder::make('form')
|
||||
->addFormItems([
|
||||
['hidden', 'id'],
|
||||
['text', 'name', '客服名称'],
|
||||
['text', 'qq', 'QQ号码'],
|
||||
['text', 'msn', 'MSN号码'],
|
||||
['text', 'taobao', '淘宝旺旺'],
|
||||
['text', 'alibaba', '阿里旺旺'],
|
||||
['text', 'skype', 'SKYPE'],
|
||||
['text', 'sort', '排序'],
|
||||
['radio', 'status', '立即启用', '', ['否', '是']]
|
||||
])
|
||||
->setFormData($info)
|
||||
->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除客服
|
||||
* @param array $record 行为日志
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @throws \think\Exception
|
||||
* @throws \think\exception\PDOException
|
||||
*/
|
||||
public function delete($record = [])
|
||||
{
|
||||
return $this->setStatus('delete');
|
||||
}
|
||||
|
||||
/**
|
||||
* 启用客服
|
||||
* @param array $record 行为日志
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @throws \think\Exception
|
||||
* @throws \think\exception\PDOException
|
||||
*/
|
||||
public function enable($record = [])
|
||||
{
|
||||
return $this->setStatus('enable');
|
||||
}
|
||||
|
||||
/**
|
||||
* 禁用客服
|
||||
* @param array $record 行为日志
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @throws \think\Exception
|
||||
* @throws \think\exception\PDOException
|
||||
*/
|
||||
public function disable($record = [])
|
||||
{
|
||||
return $this->setStatus('disable');
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置客服状态:删除、禁用、启用
|
||||
* @param string $type 类型:delete/enable/disable
|
||||
* @param array $record
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @throws \think\Exception
|
||||
* @throws \think\exception\PDOException
|
||||
*/
|
||||
public function setStatus($type = '', $record = [])
|
||||
{
|
||||
$ids = $this->request->isPost() ? input('post.ids/a') : input('param.ids');
|
||||
$support_title = SupportModel::where('id', 'in', $ids)->column('name');
|
||||
return parent::setStatus($type, ['support_'.$type, 'cms_support', 0, UID, implode('、', $support_title)]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 快速编辑
|
||||
* @param array $record 行为日志
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return mixed
|
||||
*/
|
||||
public function quickEdit($record = [])
|
||||
{
|
||||
$id = input('post.pk', '');
|
||||
$field = input('post.name', '');
|
||||
$value = input('post.value', '');
|
||||
$support = SupportModel::where('id', $id)->value($field);
|
||||
$details = '字段(' . $field . '),原值(' . $support . '),新值:(' . $value . ')';
|
||||
return parent::quickEdit(['support_edit', 'cms_support', $id, UID, $details]);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,158 @@
|
|||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | 海豚PHP框架 [ DolphinPHP ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 版权所有 2016~2017 河源市卓锐科技有限公司 [ http://www.zrthink.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网站: http://dolphinphp.com
|
||||
// +----------------------------------------------------------------------
|
||||
// | 开源协议 ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
// 门户模块公共函数库
|
||||
use think\Db;
|
||||
|
||||
if (!function_exists('get_column_name')) {
|
||||
/**
|
||||
* 获取栏目名称
|
||||
* @param int $cid 栏目id
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return string
|
||||
*/
|
||||
function get_column_name($cid = 0)
|
||||
{
|
||||
$column_list = model('cms/column')->getList();
|
||||
return isset($column_list[$cid]) ? $column_list[$cid]['name'] : '';
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('get_model_name')) {
|
||||
/**
|
||||
* 获取内容模型名称
|
||||
* @param string $id 内容模型id
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return string
|
||||
*/
|
||||
function get_model_name($id = '')
|
||||
{
|
||||
$model_list = model('cms/model')->getList();
|
||||
return isset($model_list[$id]) ? $model_list[$id]['name'] : '';
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('get_model_title')) {
|
||||
/**
|
||||
* 获取内容模型标题
|
||||
* @param string $id 内容模型标题
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return string
|
||||
*/
|
||||
function get_model_title($id = '')
|
||||
{
|
||||
$model_list = model('cms/model')->getList();
|
||||
return isset($model_list[$id]) ? $model_list[$id]['title'] : '';
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('get_model_type')) {
|
||||
/**
|
||||
* 获取内容模型类别:0-系统,1-普通,2-独立
|
||||
* @param int $id 模型id
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return string
|
||||
*/
|
||||
function get_model_type($id = 0)
|
||||
{
|
||||
$model_list = model('cms/model')->getList();
|
||||
return isset($model_list[$id]) ? $model_list[$id]['type'] : '';
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('get_model_table')) {
|
||||
/**
|
||||
* 获取内容模型附加表名
|
||||
* @param int $id 模型id
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return string
|
||||
*/
|
||||
function get_model_table($id = 0)
|
||||
{
|
||||
$model_list = model('cms/model')->getList();
|
||||
return isset($model_list[$id]) ? $model_list[$id]['table'] : '';
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('is_default_field')) {
|
||||
/**
|
||||
* 检查是否为系统默认字段
|
||||
* @param string $field 字段名称
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return bool
|
||||
*/
|
||||
function is_default_field($field = '')
|
||||
{
|
||||
$system_fields = cache('cms_system_fields');
|
||||
if (!$system_fields) {
|
||||
$system_fields = Db::name('cms_field')->where('model', 0)->column('name');
|
||||
cache('cms_system_fields', $system_fields);
|
||||
}
|
||||
return in_array($field, $system_fields, true);
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('table_exist')) {
|
||||
/**
|
||||
* 检查附加表是否存在
|
||||
* @param string $table_name 附加表名
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return string
|
||||
*/
|
||||
function table_exist($table_name = '')
|
||||
{
|
||||
return true == Db::query("SHOW TABLES LIKE '{$table_name}'");
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('time_tran')) {
|
||||
/**
|
||||
* 转换时间
|
||||
* @param int $timer 时间戳
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return string
|
||||
*/
|
||||
function time_tran($timer)
|
||||
{
|
||||
$diff = $_SERVER['REQUEST_TIME'] - $timer;
|
||||
$day = floor($diff / 86400);
|
||||
$free = $diff % 86400;
|
||||
if ($day > 0) {
|
||||
return $day . " 天前";
|
||||
} else {
|
||||
if ($free > 0) {
|
||||
$hour = floor($free / 3600);
|
||||
$free = $free % 3600;
|
||||
if ($hour > 0) {
|
||||
return $hour . " 小时前";
|
||||
} else {
|
||||
if ($free > 0) {
|
||||
$min = floor($free / 60);
|
||||
$free = $free % 60;
|
||||
if ($min > 0) {
|
||||
return $min . " 分钟前";
|
||||
} else {
|
||||
if ($free > 0) {
|
||||
return $free . " 秒前";
|
||||
} else {
|
||||
return '刚刚';
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return '刚刚';
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return '刚刚';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,105 @@
|
|||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | 海豚PHP框架 [ DolphinPHP ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 版权所有 2016~2019 广东卓锐软件有限公司 [ http://www.zrthink.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网站: http://dolphinphp.com
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace app\cms\home;
|
||||
|
||||
use app\cms\model\Column as ColumnModel;
|
||||
use think\Db;
|
||||
use util\Tree;
|
||||
|
||||
/**
|
||||
* 前台栏目文档列表控制器
|
||||
* @package app\cms\admin
|
||||
*/
|
||||
class Column extends Common
|
||||
{
|
||||
/**
|
||||
* 栏目文章列表
|
||||
* @param null $id 栏目id
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return mixed
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @throws \think\exception\DbException
|
||||
*/
|
||||
public function index($id = null)
|
||||
{
|
||||
if ($id === null) $this->error('缺少参数');
|
||||
$map = [
|
||||
'status' => 1,
|
||||
'id' => $id
|
||||
];
|
||||
|
||||
$column = Db::name('cms_column')->where($map)->find();
|
||||
if (!$column) $this->error('该栏目不存在');
|
||||
|
||||
$model = Db::name('cms_model')->where('id', $column['model'])->find();
|
||||
|
||||
if ($model['type'] == 2) {
|
||||
$cid_all = ColumnModel::getChildsId($id);
|
||||
$cid_all[] = (int)$id;
|
||||
|
||||
$map = [
|
||||
[$model['table'].'.trash', '=', 0],
|
||||
[$model['table'].'.status', '=', 1],
|
||||
[$model['table'].'.cid', 'in', $cid_all],
|
||||
];
|
||||
|
||||
$data_list = Db::view($model['table'], true)
|
||||
->view('admin_user', 'username', $model['table'].'.uid=admin_user.id', 'left')
|
||||
->where($map)
|
||||
->order('create_time desc')
|
||||
->paginate(config('list_rows'));
|
||||
$this->assign('model', $column['model']);
|
||||
} else {
|
||||
$cid_all = ColumnModel::getChildsId($id);
|
||||
$cid_all[] = (int)$id;
|
||||
|
||||
$map = [
|
||||
['cms_document.trash', '=', 0],
|
||||
['cms_document.status', '=', 1],
|
||||
['cms_document.cid', 'in', $cid_all],
|
||||
];
|
||||
|
||||
$data_list = Db::view('cms_document', true)
|
||||
->view('admin_user', 'username', 'cms_document.uid=admin_user.id', 'left')
|
||||
->view($model['table'], '*', 'cms_document.id='. $model['table'] . '.aid', 'left')
|
||||
->where($map)
|
||||
->order('create_time desc')
|
||||
->paginate(config('list_rows'));
|
||||
$this->assign('model', '');
|
||||
}
|
||||
|
||||
$this->assign('lists', $data_list);
|
||||
$this->assign('pages', $data_list->render());
|
||||
$this->assign('breadcrumb', $this->getBreadcrumb($id));
|
||||
$this->assign('column_info', $column);
|
||||
|
||||
$template = $column['list_template'] == '' ? 'list' : substr($column['list_template'], 0, strpos($column['list_template'], '.'));
|
||||
return $this->fetch($template);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取栏目面包屑导航
|
||||
* @param $id
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return mixed
|
||||
*/
|
||||
public function getBreadcrumb($id)
|
||||
{
|
||||
$columns = ColumnModel::where('status', 1)->column('id,pid,name,url,target,type');
|
||||
foreach ($columns as &$column) {
|
||||
if ($column['type'] == 0) {
|
||||
$column['url'] = url('cms/column/index', ['id' => $column['id']]);
|
||||
}
|
||||
}
|
||||
|
||||
return Tree::config(['title' => 'name'])->getParents($columns, $id);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,90 @@
|
|||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | 海豚PHP框架 [ DolphinPHP ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 版权所有 2016~2019 广东卓锐软件有限公司 [ http://www.zrthink.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网站: http://dolphinphp.com
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace app\cms\home;
|
||||
|
||||
use app\index\controller\Home;
|
||||
use think\Db;
|
||||
use util\Tree;
|
||||
|
||||
/**
|
||||
* 前台公共控制器
|
||||
* @package app\cms\admin
|
||||
*/
|
||||
class Common extends Home
|
||||
{
|
||||
/**
|
||||
* 初始化方法
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
*/
|
||||
protected function initialize()
|
||||
{
|
||||
parent::initialize();
|
||||
|
||||
// 获取菜单
|
||||
$this->getNav();
|
||||
// 获取滚动图片
|
||||
$this->assign('slider', $this->getSlider());
|
||||
// 获取客服
|
||||
$this->assign('support', $this->getSupport());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取导航
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
*/
|
||||
private function getNav()
|
||||
{
|
||||
$list_nav = Db::name('cms_nav')->where('status', 1)->column('id,tag');
|
||||
|
||||
foreach ($list_nav as $id => $tag) {
|
||||
$data_list = Db::view('cms_menu', true)
|
||||
->view('cms_column', ['name' => 'column_name'], 'cms_menu.column=cms_column.id', 'left')
|
||||
->view('cms_page', ['title' => 'page_title'], 'cms_menu.page=cms_page.id', 'left')
|
||||
->where('cms_menu.nid', $id)
|
||||
->where('cms_menu.status', 1)
|
||||
->order('cms_menu.sort,cms_menu.pid,cms_menu.id')
|
||||
->select();
|
||||
|
||||
foreach ($data_list as &$item) {
|
||||
if ($item['type'] == 0) { // 栏目链接
|
||||
$item['title'] = $item['column_name'];
|
||||
$item['url'] = url('cms/column/index', ['id' => $item['column']]);
|
||||
} elseif ($item['type'] == 1) { // 单页链接
|
||||
$item['title'] = $item['page_title'];
|
||||
$item['url'] = url('cms/page/detail', ['id' => $item['page']]);
|
||||
} else {
|
||||
if ($item['url'] != '#' && substr($item['url'], 0, 4) != 'http') {
|
||||
$item['url'] = url($item['url']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->assign($tag, Tree::toLayer($data_list));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取滚动图片
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
*/
|
||||
private function getSlider()
|
||||
{
|
||||
return Db::name('cms_slider')->where('status', 1)->select();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取在线客服
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
*/
|
||||
private function getSupport()
|
||||
{
|
||||
return Db::name('cms_support')->where('status', 1)->order('sort')->select();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,152 @@
|
|||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | 海豚PHP框架 [ DolphinPHP ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 版权所有 2016~2019 广东卓锐软件有限公司 [ http://www.zrthink.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网站: http://dolphinphp.com
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace app\cms\home;
|
||||
|
||||
use app\cms\model\Column as ColumnModel;
|
||||
use app\cms\model\Document as DocumentModel;
|
||||
use util\Tree;
|
||||
use think\Db;
|
||||
|
||||
/**
|
||||
* 文档控制器
|
||||
* @package app\cms\home
|
||||
*/
|
||||
class Document extends Common
|
||||
{
|
||||
/**
|
||||
* 文档详情页
|
||||
* @param null $id 文档id
|
||||
* @param string $model 独立模型id
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return mixed
|
||||
*/
|
||||
public function detail($id = null, $model = '')
|
||||
{
|
||||
if ($id === null) $this->error('缺少参数');
|
||||
|
||||
if ($model != '') {
|
||||
$table = get_model_table($model);
|
||||
$map = [
|
||||
$table.'.status' => 1,
|
||||
$table.'.trash' => 0
|
||||
];
|
||||
} else {
|
||||
$map = [
|
||||
'cms_document.status' => 1,
|
||||
'cms_document.trash' => 0
|
||||
];
|
||||
}
|
||||
|
||||
$info = DocumentModel::getOne($id, $model, $map);
|
||||
if (isset($info['tags'])) {
|
||||
$info['tags'] = explode(',', $info['tags']);
|
||||
}
|
||||
|
||||
$this->assign('document', $info);
|
||||
$this->assign('breadcrumb', $this->getBreadcrumb($info['cid']));
|
||||
$this->assign('prev', $this->getPrev($id, $model));
|
||||
$this->assign('next', $this->getNext($id, $model));
|
||||
|
||||
$template = $info['detail_template'] == '' ? 'detail' : substr($info['detail_template'], 0, strpos($info['detail_template'], '.'));
|
||||
return $this->fetch($template);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取栏目面包屑导航
|
||||
* @param int $id 栏目id
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return mixed
|
||||
*/
|
||||
private function getBreadcrumb($id)
|
||||
{
|
||||
$columns = ColumnModel::where('status', 1)->column('id,pid,name,url,target,type');
|
||||
foreach ($columns as &$column) {
|
||||
if ($column['type'] == 0) {
|
||||
$column['url'] = url('cms/column/index', ['id' => $column['id']]);
|
||||
}
|
||||
}
|
||||
return Tree::config(['title' => 'name'])->getParents($columns, $id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取上一篇文档
|
||||
* @param int $id 当前文档id
|
||||
* @param string $model 独立模型id
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return array|string|\think\Model|null
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @throws \think\exception\DbException
|
||||
*/
|
||||
private function getPrev($id, $model = '')
|
||||
{
|
||||
if ($model == '') {
|
||||
$cid = Db::name('cms_document')->where('id', $id)->value('cid');
|
||||
$document = Db::name('cms_document')->where([
|
||||
['status', '=', 1],
|
||||
['trash', '=', 0],
|
||||
['cid', '=', $cid],
|
||||
['id', 'lt', $id]
|
||||
])->order('id desc')->find();
|
||||
} else {
|
||||
$table = get_model_table($model);
|
||||
$cid = Db::table($table)->where('id', $id)->value('cid');
|
||||
$document = Db::table($table)->where([
|
||||
['status', '=', 1],
|
||||
['trash', '=', 0],
|
||||
['cid', '=', $cid],
|
||||
['id', 'lt', $id]
|
||||
])->order('id desc')->find();
|
||||
}
|
||||
|
||||
if ($document) {
|
||||
$document['url'] = url('cms/document/detail', ['id' => $document['id'], 'model' => $model]);
|
||||
}
|
||||
return $document;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取下一篇文档
|
||||
* @param int $id 当前文档id
|
||||
* @param string $model 独立模型id
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return array|string|\think\Model|null
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @throws \think\exception\DbException
|
||||
*/
|
||||
private function getNext($id, $model = '')
|
||||
{
|
||||
if ($model == '') {
|
||||
$cid = Db::name('cms_document')->where('id', $id)->value('cid');
|
||||
$document = Db::name('cms_document')->where([
|
||||
['status', '=', 1],
|
||||
['trash', '=', 0],
|
||||
['cid', '=', $cid],
|
||||
['id', 'gt', $id]
|
||||
])->find();
|
||||
} else {
|
||||
$table = get_model_table($model);
|
||||
$cid = Db::table($table)->where('id', $id)->value('cid');
|
||||
$document = Db::table($table)->where([
|
||||
['status', '=', 1],
|
||||
['trash', '=', 0],
|
||||
['cid', '=', $cid],
|
||||
['id', 'gt', $id]
|
||||
])->find();
|
||||
}
|
||||
|
||||
if ($document) {
|
||||
$document['url'] = url('cms/document/detail', ['id' => $document['id'], 'model' => $model]);
|
||||
}
|
||||
|
||||
return $document;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | 海豚PHP框架 [ DolphinPHP ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 版权所有 2016~2019 广东卓锐软件有限公司 [ http://www.zrthink.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网站: http://dolphinphp.com
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace app\cms\home;
|
||||
|
||||
/**
|
||||
* 前台首页控制器
|
||||
* @package app\cms\admin
|
||||
*/
|
||||
class Index extends Common
|
||||
{
|
||||
/**
|
||||
* 首页
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return mixed
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
return $this->fetch(); // 渲染模板
|
||||
}
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | 海豚PHP框架 [ DolphinPHP ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 版权所有 2016~2019 广东卓锐软件有限公司 [ http://www.zrthink.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网站: http://dolphinphp.com
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace app\cms\home;
|
||||
|
||||
use app\cms\model\Page as PageModel;
|
||||
|
||||
/**
|
||||
* 前台单页控制器
|
||||
* @package app\cms\admin
|
||||
*/
|
||||
class Page extends Common
|
||||
{
|
||||
/**
|
||||
* 单页详情
|
||||
* @param null $id 单页id
|
||||
* @author 蔡伟明 <314013107@qq.com>
|
||||
* @return mixed
|
||||
* @throws \think\Exception
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @throws \think\exception\DbException
|
||||
*/
|
||||
public function detail($id = null)
|
||||
{
|
||||
$info = PageModel::where('status', 1)->find($id);
|
||||
$info['url'] = url('cms/page/detail', ['id' => $info['id']]);
|
||||
$info['tags'] = explode(',', $info['keywords']);
|
||||
|
||||
// 更新阅读量
|
||||
PageModel::where('id', $id)->setInc('view');
|
||||
|
||||
$this->assign('page_info', $info);
|
||||
return $this->fetch(); // 渲染模板
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue