You've already forked guangan
1
This commit is contained in:
22
.env.example
Normal file
22
.env.example
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
# 数据配置
|
||||||
|
DB_TYPE=mysql
|
||||||
|
DB_MYSQL_HOST=thinkadmin.top
|
||||||
|
DB_MYSQL_PORT=3306
|
||||||
|
DB_MYSQL_PREFIX=
|
||||||
|
DB_MYSQL_DATABASE=admin_v6
|
||||||
|
DB_MYSQL_USERNAME=root
|
||||||
|
DB_MYSQL_PASSWORD=
|
||||||
|
|
||||||
|
# 缓存配置
|
||||||
|
CACHE_TYPE=file
|
||||||
|
CACHE_REDIS_HOST=127.0.0.1
|
||||||
|
CACHE_REDIS_PORT=6379
|
||||||
|
CACHE_REDIS_SELECT=
|
||||||
|
CACHE_REDIS_PASSWORD=
|
||||||
|
|
||||||
|
# 会话配置
|
||||||
|
SESSION_NAME=ssid
|
||||||
|
SESSION_TYPE=file
|
||||||
|
SESSION_STORE=
|
||||||
|
SESSION_EXPIRE=7200
|
||||||
|
SESSION_PREFIX=
|
3
.gitattributes
vendored
Normal file
3
.gitattributes
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
*.js linguist-language=php
|
||||||
|
*.css linguist-language=php
|
||||||
|
*.html linguist-language=php
|
50
.gitignore
vendored
Normal file
50
.gitignore
vendored
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
.env
|
||||||
|
.git
|
||||||
|
.svn
|
||||||
|
.idea
|
||||||
|
.fleet
|
||||||
|
.vscode
|
||||||
|
.DS_Store
|
||||||
|
|
||||||
|
/vendor
|
||||||
|
/runtime
|
||||||
|
/safefile
|
||||||
|
/nbproject
|
||||||
|
/composer.lock
|
||||||
|
!composer.json
|
||||||
|
|
||||||
|
### 屏蔽环境文件
|
||||||
|
/404.html
|
||||||
|
/.user.ini
|
||||||
|
/index.html
|
||||||
|
/public/upload
|
||||||
|
/public/404.html
|
||||||
|
/public/.htaccess
|
||||||
|
/public/.user.ini
|
||||||
|
/public/index.html
|
||||||
|
/public/favicon.ico
|
||||||
|
/database/sqlite.db
|
||||||
|
|
||||||
|
### 屏蔽插件文件
|
||||||
|
/app/admin
|
||||||
|
/app/wechat
|
||||||
|
|
||||||
|
### 屏蔽配置文件
|
||||||
|
/config/app.php
|
||||||
|
/config/cookie.php
|
||||||
|
/config/lang.php
|
||||||
|
/config/log.php
|
||||||
|
/config/route.php
|
||||||
|
/config/session.php
|
||||||
|
/config/view.php
|
||||||
|
|
||||||
|
/public/static/plugs
|
||||||
|
/public/static/theme
|
||||||
|
/public/static/admin.js
|
||||||
|
/public/static/login.js
|
||||||
|
|
||||||
|
### 屏蔽数据库脚本
|
||||||
|
/database/migrations/*_install_*.php
|
||||||
|
/database/migrations/*_upgrade_*.php
|
||||||
|
!database/migrations/*_install_table.php
|
||||||
|
!database/migrations/*_install_package.php
|
27
app/index/controller/Index.php
Normal file
27
app/index/controller/Index.php
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | Static Plugin for ThinkAdmin
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | 版权所有 2014~2024 ThinkAdmin [ thinkadmin.top ]
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | 官方网站: https://thinkadmin.top
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | 开源协议 ( https://mit-license.org )
|
||||||
|
// | 免责声明 ( https://thinkadmin.top/disclaimer )
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | gitee 代码仓库:https://gitee.com/zoujingli/think-plugs-static
|
||||||
|
// | github 代码仓库:https://github.com/zoujingli/think-plugs-static
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
|
||||||
|
namespace app\index\controller;
|
||||||
|
|
||||||
|
use think\admin\Controller;
|
||||||
|
|
||||||
|
class Index extends Controller
|
||||||
|
{
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
$this->redirect(sysuri('admin/login/index'));
|
||||||
|
}
|
||||||
|
}
|
53
composer.json
Normal file
53
composer.json
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
{
|
||||||
|
"type": "project",
|
||||||
|
"name": "jerryyan/guangan",
|
||||||
|
"version": "0.0.1",
|
||||||
|
"license": "MIT",
|
||||||
|
"description": "Application Development Framework",
|
||||||
|
"keywords": [
|
||||||
|
"ThinkAdmin",
|
||||||
|
"ThinkLibrary",
|
||||||
|
"WeChatDeveloper"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Anyon",
|
||||||
|
"email": "zoujingli@qq.com"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"config": {
|
||||||
|
"allow-plugins": {
|
||||||
|
"zoujingli/think-install": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": ">=7.1",
|
||||||
|
"jerryyan/think-plugs-cms": "@dev",
|
||||||
|
"jerryyan/think-plugs-points-mall": "@dev",
|
||||||
|
"jerryyan/think-plugs-ticket": "@dev",
|
||||||
|
"zoujingli/think-plugs-admin": "^1.0",
|
||||||
|
"zoujingli/think-plugs-wechat": "^1.0",
|
||||||
|
"zoujingli/think-plugs-center": "^1.0",
|
||||||
|
"zoujingli/think-plugs-account": "^1.0",
|
||||||
|
"ext-json": "*"
|
||||||
|
},
|
||||||
|
"repositories": {
|
||||||
|
"jerryyan/think-plugs-cms": {
|
||||||
|
"type": "path",
|
||||||
|
"url": "./plugs/think-plugs-cms"
|
||||||
|
},
|
||||||
|
"jerryyan/think-plugs-points-mall": {
|
||||||
|
"type": "path",
|
||||||
|
"url": "./plugs/think-plugs-points-mall"
|
||||||
|
},
|
||||||
|
"jerryyan/think-plugs-ticket": {
|
||||||
|
"type": "path",
|
||||||
|
"url": "./plugs/think-plugs-ticket"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"app\\": "app"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
51
config/cache.php
Normal file
51
config/cache.php
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | Static Plugin for ThinkAdmin
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | 版权所有 2014~2024 ThinkAdmin [ thinkadmin.top ]
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | 官方网站: https://thinkadmin.top
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | 开源协议 ( https://mit-license.org )
|
||||||
|
// | 免责声明 ( https://thinkadmin.top/disclaimer )
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | gitee 代码仓库:https://gitee.com/zoujingli/think-plugs-static
|
||||||
|
// | github 代码仓库:https://github.com/zoujingli/think-plugs-static
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
|
||||||
|
return [
|
||||||
|
// 默认缓存驱动
|
||||||
|
'default' => 'file',
|
||||||
|
// 缓存连接配置
|
||||||
|
'stores' => [
|
||||||
|
'file' => [
|
||||||
|
// 驱动方式
|
||||||
|
'type' => 'File',
|
||||||
|
// 缓存保存目录
|
||||||
|
'path' => '',
|
||||||
|
// 缓存名称前缀
|
||||||
|
'prefix' => '',
|
||||||
|
// 缓存有效期 0 表示永久缓存
|
||||||
|
'expire' => 0,
|
||||||
|
// 缓存标签前缀
|
||||||
|
'tag_prefix' => 'tag:',
|
||||||
|
// 序列化机制
|
||||||
|
'serialize' => [],
|
||||||
|
],
|
||||||
|
'safe' => [
|
||||||
|
// 驱动方式
|
||||||
|
'type' => 'File',
|
||||||
|
// 缓存保存目录
|
||||||
|
'path' => syspath('safefile/cache/'),
|
||||||
|
// 缓存名称前缀
|
||||||
|
'prefix' => '',
|
||||||
|
// 缓存有效期 0 表示永久缓存
|
||||||
|
'expire' => 0,
|
||||||
|
// 缓存标签前缀
|
||||||
|
'tag_prefix' => 'tag:',
|
||||||
|
// 序列化机制
|
||||||
|
'serialize' => [],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
];
|
82
config/database.php
Normal file
82
config/database.php
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | Static Plugin for ThinkAdmin
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | 版权所有 2014~2024 ThinkAdmin [ thinkadmin.top ]
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | 官方网站: https://thinkadmin.top
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | 开源协议 ( https://mit-license.org )
|
||||||
|
// | 免责声明 ( https://thinkadmin.top/disclaimer )
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | gitee 代码仓库:https://gitee.com/zoujingli/think-plugs-static
|
||||||
|
// | github 代码仓库:https://github.com/zoujingli/think-plugs-static
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
|
||||||
|
return [
|
||||||
|
// 默认使用的数据库连接配置
|
||||||
|
'default' => 'mysql',
|
||||||
|
// 自定义时间查询规则
|
||||||
|
'time_query_rule' => [],
|
||||||
|
// 自动写入时间戳字段
|
||||||
|
'auto_timestamp' => true,
|
||||||
|
// 时间字段取出后的默认时间格式
|
||||||
|
'datetime_format' => 'Y-m-d H:i:s',
|
||||||
|
// 数据库连接配置信息
|
||||||
|
'connections' => [
|
||||||
|
'mysql' => [
|
||||||
|
// 数据库类型
|
||||||
|
'type' => 'mysql',
|
||||||
|
// 服务器地址
|
||||||
|
'hostname' => 'database.jerryyan.net',
|
||||||
|
// 数据库名
|
||||||
|
'database' => 'guangan',
|
||||||
|
// 用户名
|
||||||
|
'username' => 'guangan',
|
||||||
|
// 密码
|
||||||
|
'password' => 'guangan123',
|
||||||
|
// 端口
|
||||||
|
'hostport' => '33306',
|
||||||
|
// 数据库连接参数
|
||||||
|
'params' => [],
|
||||||
|
// 数据库编码默认采用 utf8
|
||||||
|
'charset' => 'utf8mb4',
|
||||||
|
// 数据库表前缀
|
||||||
|
'prefix' => '',
|
||||||
|
// 数据库部署方式:0 集中式(单一服务器),1 分布式(主从服务器)
|
||||||
|
'deploy' => 0,
|
||||||
|
// 数据库读写是否分离 主从式有效
|
||||||
|
'rw_separate' => false,
|
||||||
|
// 读写分离后 主服务器数量
|
||||||
|
'master_num' => 1,
|
||||||
|
// 指定从服务器序号
|
||||||
|
'slave_no' => '',
|
||||||
|
// 检查字段是否存在
|
||||||
|
'fields_strict' => true,
|
||||||
|
// 是否需要断线重连
|
||||||
|
'break_reconnect' => false,
|
||||||
|
// 监听SQL执行日志
|
||||||
|
'trigger_sql' => true,
|
||||||
|
// 开启字段类型缓存
|
||||||
|
'fields_cache' => isOnline(),
|
||||||
|
],
|
||||||
|
'sqlite' => [
|
||||||
|
'charset' => 'utf8',
|
||||||
|
// 数据库类型
|
||||||
|
'type' => 'sqlite',
|
||||||
|
// 数据库文件
|
||||||
|
'database' => syspath('database/sqlite.db'),
|
||||||
|
// 监听执行日志
|
||||||
|
'trigger_sql' => true,
|
||||||
|
// 其他参数字段
|
||||||
|
'deploy' => 0,
|
||||||
|
'suffix' => '',
|
||||||
|
'prefix' => '',
|
||||||
|
'hostname' => '',
|
||||||
|
'hostport' => '',
|
||||||
|
'username' => '',
|
||||||
|
'password' => '',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
];
|
24
config/phinx.php
Normal file
24
config/phinx.php
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | Static Plugin for ThinkAdmin
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | 版权所有 2014~2024 ThinkAdmin [ thinkadmin.top ]
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | 官方网站: https://thinkadmin.top
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | 开源协议 ( https://mit-license.org )
|
||||||
|
// | 免责声明 ( https://thinkadmin.top/disclaimer )
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | gitee 代码仓库:https://gitee.com/zoujingli/think-plugs-static
|
||||||
|
// | github 代码仓库:https://github.com/zoujingli/think-plugs-static
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
|
||||||
|
return [
|
||||||
|
// 忽略数据表,填写表名
|
||||||
|
'ignore' => [],
|
||||||
|
// 创建数据表,填写表名
|
||||||
|
'tables' => [],
|
||||||
|
// 备份数据表,填写表名
|
||||||
|
'backup' => [],
|
||||||
|
];
|
21
license
Normal file
21
license
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2014-2023 Anyon <zoujingli@qq.com>
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
135
plugin.md
Normal file
135
plugin.md
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
# 插件生态
|
||||||
|
|
||||||
|
》》》 更多插件正在开发,敬请期待…… 《《《
|
||||||
|
|
||||||
|
目前插件更新比较频繁,如果有发现 **bug**,请尝试升级最新版本。
|
||||||
|
|
||||||
|
如果问题依旧,请到 [Gitee](https://gitee.com/zoujingli/ThinkAdmin/issues) 提交问题,提交的内容中需要标注插件名称及问题详情,最好附加环境版本信息。
|
||||||
|
|
||||||
|
使用现有插件前请务必认真阅读每个插件的介绍,如果需要开发自己的插件请查看 [插件开发](https://thinkadmin.top/system/plugin-register.html) 章节。
|
||||||
|
|
||||||
|
通常情况下,使用 **admin** 及 **wechat** 两个插件就可以完成系统定制开发,且这两个插件都是遵循 **MIT** 协议开源,不影响商业授权。
|
||||||
|
|
||||||
|
## 免费开源插件
|
||||||
|
|
||||||
|
> 后台基础 Admin 管理插件( 已稳定可用 )
|
||||||
|
>
|
||||||
|
> * 插件标识:`admin`
|
||||||
|
> * 插件包名:`zoujingli/think-plugs-admin`
|
||||||
|
> * 安装方式:`composer require zoujingli/think-plugs-admin`
|
||||||
|
> * 插件仓库:[https://gitee.com/zoujingli/think-plugs-admin](https://gitee.com/zoujingli/think-plugs-admin)
|
||||||
|
> * 文档地址:[查看文档](https://thinkadmin.top/plugin/think-plugs-admin.html)
|
||||||
|
> * 开源协议:[MIT](https://mit-license.org) ( 免费开源,支持本地插件化定制 )
|
||||||
|
|
||||||
|
> 后台基础 WeChat 微信插件( 已稳定可用 )
|
||||||
|
> * 插件标识:`wechat`
|
||||||
|
> * 插件包名:`zoujingli/think-plugs-wechat`
|
||||||
|
> * 安装方式:`composer require zoujingli/think-plugs-wechat`
|
||||||
|
> * 插件仓库:[https://gitee.com/zoujingli/think-plugs-wechat](https://gitee.com/zoujingli/think-plugs-wechat)
|
||||||
|
> * 文档地址:[查看文档](https://thinkadmin.top/plugin/think-plugs-wechat.html)
|
||||||
|
> * 开源协议:[MIT](https://mit-license.org) ( 免费开源,支持本地插件化定制 )
|
||||||
|
|
||||||
|
> 后台静态 Static 初始化插件 ( 通常不需要独立安装 )
|
||||||
|
> * 插件标识:`static`
|
||||||
|
> * 插件包名:`zoujingli/think-plugs-static`
|
||||||
|
> * 安装方式:`composer require zoujingli/think-plugs-static`
|
||||||
|
> * 插件仓库:[https://gitee.com/zoujingli/think-plugs-static](https://gitee.com/zoujingli/think-plugs-static)
|
||||||
|
> * 开源协议:[MIT](https://mit-license.org) ( 免费开源,部分插件包含其他开源协议,具体可以查看源文件,不支持本地插件化定制 )
|
||||||
|
|
||||||
|
> 基础插件市场系统 ( 开发中,后期开放 ThinkAdmin 生态市场 )
|
||||||
|
> * 插件标识:`plugin-center`
|
||||||
|
> * 插件包名:`zoujingli/think-plugs-center`
|
||||||
|
> * 安装方式:`composer require zoujingli/think-plugs-center`
|
||||||
|
> * 插件仓库:[https://gitee.com/zoujingli/think-plugs-center](https://gitee.com/zoujingli/think-plugs-center)
|
||||||
|
> * 文档地址:[查看文档](https://thinkadmin.top/plugin/think-plugs-center.html)
|
||||||
|
> * 开源协议:[Apache2](https://www.apache.org/licenses/LICENSE-2.0) ( 免费开源,建议保留版权注释,支持本地插件化定制 )
|
||||||
|
|
||||||
|
> 基础插件市场系统 ( 已稳定可用,建议使用 plugin-center )
|
||||||
|
> * 插件标识:`plugin-center-simple`
|
||||||
|
> * 插件包名:`zoujingli/think-plugs-center-simple`
|
||||||
|
> * 安装方式:`composer require zoujingli/think-plugs-center-simple`
|
||||||
|
> * 插件仓库:[https://gitee.com/zoujingli/think-plugs-center-simple](https://gitee.com/zoujingli/think-plugs-center-simple)
|
||||||
|
> * 文档地址:[查看文档](https://thinkadmin.top/plugin/think-plugs-center-simple.html)
|
||||||
|
> * 开源协议:[Apache2](https://www.apache.org/licenses/LICENSE-2.0) ( 免费开源,建议保留版权注释,支持本地插件化定制 )
|
||||||
|
|
||||||
|
> 基于 Workerman 的 网络服务插件 ( 已稳定可用 )
|
||||||
|
> * 插件标识:`plugin-worker`
|
||||||
|
> * 插件包名:`zoujingli/think-plugs-worker`
|
||||||
|
> * 安装方式:`composer require zoujingli/think-plugs-worker`
|
||||||
|
> * 插件仓库:[https://gitee.com/zoujingli/think-plugs-worker](https://gitee.com/zoujingli/think-plugs-worker)
|
||||||
|
> * 文档地址:[查看文档](https://thinkadmin.top/plugin/think-plugs-worker.html)
|
||||||
|
> * 开源协议:[Apache2](https://www.apache.org/licenses/LICENSE-2.0) ( 免费开源,建议保留版权注释,支持本地插件化定制 )
|
||||||
|
|
||||||
|
## 会员尊享插件
|
||||||
|
|
||||||
|
> 多端用户账号系统 ( 已稳定可用 )
|
||||||
|
> * 插件标识:`plugin-account`
|
||||||
|
> * 插件包名:`zoujingli/think-plugs-account`
|
||||||
|
> * 安装方式:`composer require zoujingli/think-plugs-account`
|
||||||
|
> * 插件仓库:[https://gitee.com/zoujingli/think-plugs-account](https://gitee.com/zoujingli/think-plugs-account)
|
||||||
|
> * 文档地址:[查看文档](https://thinkadmin.top/plugin/think-plugs-account.html)
|
||||||
|
> * 授权协议:[VIP授权](https://thinkadmin.top/vip-introduce.html) ( 非VIP用户仅可用于学习,不得商用,支持本地插件化定制 )
|
||||||
|
|
||||||
|
> 多端支付管理系统 ( 已稳定可用 )
|
||||||
|
> * 插件标识:`plugin-payment`
|
||||||
|
> * 插件包名:`zoujingli/think-plugs-payment`
|
||||||
|
> * 安装方式:`composer require zoujingli/think-plugs-payment`
|
||||||
|
> * 插件仓库:[https://gitee.com/zoujingli/think-plugs-payment](https://gitee.com/zoujingli/think-plugs-payment)
|
||||||
|
> * 文档地址:[查看文档](https://thinkadmin.top/plugin/think-plugs-payment.html)
|
||||||
|
> * 授权协议:[VIP授权](https://thinkadmin.top/vip-introduce.html) ( 非VIP用户仅可用于学习,不得商用,支持本地插件化定制 )
|
||||||
|
|
||||||
|
> 多端微商城系统 ( 已稳定可用 )
|
||||||
|
> * 插件标识:`plugin-wemall`
|
||||||
|
> * 插件包名:`zoujingli/think-plugs-wemall`
|
||||||
|
> * 安装方式:`composer require zoujingli/think-plugs-wemall`
|
||||||
|
> * 插件仓库:[https://gitee.com/zoujingli/think-plugs-wemall](https://gitee.com/zoujingli/think-plugs-wemall)
|
||||||
|
> * 文档地址:[查看文档](https://thinkadmin.top/plugin/think-plugs-wemall.html)
|
||||||
|
> * 授权协议:[VIP授权](https://thinkadmin.top/vip-introduce.html) ( 非VIP用户仅可用于学习,不得商用,支持本地插件化定制 )
|
||||||
|
|
||||||
|
> 微信开放平台基础插件( 已稳定可用 )
|
||||||
|
> * 插件标识:`plugin-wechat-service`
|
||||||
|
> * 插件包名:`zoujingli/think-plugs-wechat-service`
|
||||||
|
> * 安装方式:`composer require zoujingli/think-plugs-wechat-service`
|
||||||
|
> * 插件仓库:[https://gitee.com/zoujingli/think-plugs-wechat-service](https://gitee.com/zoujingli/think-plugs-wechat-service)
|
||||||
|
> * 文档地址:[查看文档](https://thinkadmin.top/plugin/think-plugs-wechat-service.html)
|
||||||
|
> * 授权协议:[VIP授权](https://thinkadmin.top/vip-introduce.html) ( 非VIP用户仅可用于学习,不得商用,支持本地插件化定制 )
|
||||||
|
|
||||||
|
## 收费授权插件
|
||||||
|
|
||||||
|
> 一物一码溯源系统 ( 开发中,还未发布 )
|
||||||
|
> * 插件标识:`plugin-wuma`
|
||||||
|
> * 插件包名:`zoujingli/think-plugs-wuma`
|
||||||
|
> * 安装方式:`composer require zoujingli/think-plugs-wuma`
|
||||||
|
> * 插件仓库:[https://gitee.com/zoujingli/think-plugs-wuma](https://gitee.com/zoujingli/think-plugs-wuma)
|
||||||
|
> * 文档地址:[查看文档](https://thinkadmin.top/plugin/think-plugs-wuma.html)
|
||||||
|
> * 授权协议:[收费授权](https://thinkadmin.top/fee-introduce.html) ( 未获得授权仅可用于学习,不得商用,支持本地插件化定制 )
|
||||||
|
|
||||||
|
## 案例安装体验
|
||||||
|
|
||||||
|
如果需要本地化定制开发,请参考[插件本地化定制](https://thinkadmin.top/system/plugin-developer.html)文档
|
||||||
|
|
||||||
|
```shell
|
||||||
|
# 创建项目
|
||||||
|
composer create-project zoujingli/thinkadmin
|
||||||
|
|
||||||
|
# 进入项目目录
|
||||||
|
cd thinkadmin
|
||||||
|
|
||||||
|
# 安装微信插件
|
||||||
|
composer require zoujingli/think-plugs-wechat
|
||||||
|
|
||||||
|
# 安装插件管理中心
|
||||||
|
composer require zoujingli/think-plugs-center
|
||||||
|
|
||||||
|
# 安装多端账号管理
|
||||||
|
composer require zoujingli/think-plugs-account
|
||||||
|
|
||||||
|
# 安装多端支付管理
|
||||||
|
composer require zoujingli/think-plugs-payment
|
||||||
|
|
||||||
|
# 安装多端商城管理
|
||||||
|
composer require zoujingli/think-plugs-wemall
|
||||||
|
|
||||||
|
# 启动 WEB 内置服务
|
||||||
|
php think run --host 127.0.0.1
|
||||||
|
```
|
41
plugs/think-plugs-cms/composer.json
Normal file
41
plugs/think-plugs-cms/composer.json
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
{
|
||||||
|
"type": "think-admin-plugin",
|
||||||
|
"name": "jerryyan/think-plugs-cms",
|
||||||
|
"license": "WTFPL",
|
||||||
|
"homepage": "https://thinkadmin.top",
|
||||||
|
"description": "CMS Plugin for ThinkAdmin",
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Jerry Yan",
|
||||||
|
"email": "jerryyan0912@qq.com"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"require": {
|
||||||
|
"php": ">7.1"
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"plugin\\cms\\": "src"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"extra": {
|
||||||
|
"config": {
|
||||||
|
"type": "module",
|
||||||
|
"name": "新闻资讯",
|
||||||
|
"document": "https://thinkadmin.top/plugin/think-plugs-wechat.html",
|
||||||
|
"description": "新闻资讯"
|
||||||
|
},
|
||||||
|
"think": {
|
||||||
|
"services": [
|
||||||
|
"plugin\\cms\\Service"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"minimum-stability": "dev",
|
||||||
|
"config": {
|
||||||
|
"sort-packages": true,
|
||||||
|
"allow-plugins": {
|
||||||
|
"zoujingli/think-install": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
36
plugs/think-plugs-cms/src/Service.php
Normal file
36
plugs/think-plugs-cms/src/Service.php
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace plugin\cms;
|
||||||
|
|
||||||
|
use think\admin\Plugin;
|
||||||
|
use think\facade\View;
|
||||||
|
|
||||||
|
class Service extends Plugin
|
||||||
|
{
|
||||||
|
protected $appName = '文章管理';
|
||||||
|
protected $appCode = 'cms';
|
||||||
|
protected $package = 'jerryyan/think-plugs-cms';
|
||||||
|
|
||||||
|
public static function register(): void
|
||||||
|
{
|
||||||
|
View::assign("_YES_OR_NO", [
|
||||||
|
'1' => '是',
|
||||||
|
'0' => '否'
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function menu(): array
|
||||||
|
{
|
||||||
|
$code = app(static::class)->appCode;
|
||||||
|
return [
|
||||||
|
[
|
||||||
|
'name' => '文章管理',
|
||||||
|
'subs' => [
|
||||||
|
['name' => '文章分类', 'icon' => 'layui-icon layui-icon-template-1', 'node' => "{$code}/category/index"],
|
||||||
|
['name' => '文章列表', 'icon' => 'layui-icon layui-icon-template-1', 'node' => "{$code}/article/index"],
|
||||||
|
['name' => '轮播图列表', 'icon' => 'layui-icon layui-icon-template-1', 'node' => "{$code}/banner/index"],
|
||||||
|
]
|
||||||
|
]
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
143
plugs/think-plugs-cms/src/controller/Article.php
Normal file
143
plugs/think-plugs-cms/src/controller/Article.php
Normal file
@ -0,0 +1,143 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace plugin\cms\controller;
|
||||||
|
|
||||||
|
use plugin\cms\model\CmsArticle;
|
||||||
|
use plugin\cms\model\CmsCateArticle;
|
||||||
|
use plugin\cms\model\CmsCategory;
|
||||||
|
use think\admin\Controller;
|
||||||
|
use think\admin\helper\QueryHelper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文章管理
|
||||||
|
*/
|
||||||
|
class Article extends Controller
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 文章管理
|
||||||
|
* @auth true
|
||||||
|
* @menu true
|
||||||
|
* @login true
|
||||||
|
* @return void
|
||||||
|
* @throws \think\db\exception\DataNotFoundException
|
||||||
|
* @throws \think\db\exception\DbException
|
||||||
|
* @throws \think\db\exception\ModelNotFoundException
|
||||||
|
*/
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
$this->title = '文章管理';
|
||||||
|
CmsArticle::mQuery()->layTable(function () {
|
||||||
|
}, static function (QueryHelper $query) {
|
||||||
|
$query->where('is_deleted', 0);
|
||||||
|
$query->with(['category']);
|
||||||
|
$query->equal('status')->like('title');
|
||||||
|
$query->timeBetween('create_at');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public function _index_page_filter(&$list)
|
||||||
|
{
|
||||||
|
foreach ($list as &$item) {
|
||||||
|
$cate_list = $item['category'];
|
||||||
|
$item['cate_name'] = join(',', array_column($cate_list, 'name'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加文章
|
||||||
|
* @auth true
|
||||||
|
* @menu true
|
||||||
|
* @login true
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function add()
|
||||||
|
{
|
||||||
|
$this->title = '添加文章';
|
||||||
|
$this->cates = CmsCategory::getList();
|
||||||
|
$this->cate_ids = [];
|
||||||
|
CmsArticle::mForm('form');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 编辑文章
|
||||||
|
* @auth true
|
||||||
|
* @menu true
|
||||||
|
* @login true
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function edit()
|
||||||
|
{
|
||||||
|
$this->title = '编辑文章';
|
||||||
|
$this->cates = CmsCategory::getList();
|
||||||
|
$this->id = $this->request->param('id');
|
||||||
|
$this->cate_ids = CmsCateArticle::where(['aid' => $this->id])->column('cid');
|
||||||
|
CmsArticle::mForm('form', "id");
|
||||||
|
}
|
||||||
|
|
||||||
|
public function _form_filter(&$data)
|
||||||
|
{
|
||||||
|
unset($data['cate_ids']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function _form_result($state, $data)
|
||||||
|
{
|
||||||
|
if (isset($data['id'])) {
|
||||||
|
CmsCateArticle::where(['aid' => $data['id']])->delete();
|
||||||
|
$cate_ids = $this->request->param('cate_ids', []);
|
||||||
|
foreach ($cate_ids as $cid) {
|
||||||
|
CmsCateArticle::create(['aid' => $data['id'], 'cid' => $cid]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除文章
|
||||||
|
* @auth true
|
||||||
|
* @menu true
|
||||||
|
* @login true
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function remove()
|
||||||
|
{
|
||||||
|
CmsArticle::mDelete('id');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 修改文章状态
|
||||||
|
* @auth true
|
||||||
|
* @menu true
|
||||||
|
* @login true
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function status()
|
||||||
|
{
|
||||||
|
CmsArticle::mSave($this->_vali([
|
||||||
|
'id.require' => '文章ID不能为空',
|
||||||
|
'status.in:0,1' => '状态值范围异常!',
|
||||||
|
'status.require' => '状态值不能为空!',
|
||||||
|
]), 'id');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function _status_save_result($state, $data)
|
||||||
|
{
|
||||||
|
if ($state) {
|
||||||
|
$status = $this->request->param('status');
|
||||||
|
$id = $this->request->param('id');
|
||||||
|
if ($status == 1) {
|
||||||
|
CmsArticle::mk()->where('id', $id)->save([
|
||||||
|
'publish_at' => date('Y-m-d H:i:s')
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function sort()
|
||||||
|
{
|
||||||
|
CmsArticle::mSave($this->_vali([
|
||||||
|
'id.require' => '文章ID不能为空',
|
||||||
|
'sort.require' => '排序值不能为空!',
|
||||||
|
'sort.number' => '排序必须为数字!',
|
||||||
|
'sort.between:0,9999' => '排序值必须为0~9999之间!',
|
||||||
|
]), 'id');
|
||||||
|
}
|
||||||
|
}
|
97
plugs/think-plugs-cms/src/controller/Banner.php
Normal file
97
plugs/think-plugs-cms/src/controller/Banner.php
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace plugin\cms\controller;
|
||||||
|
|
||||||
|
use plugin\cms\model\CmsBanner;
|
||||||
|
use think\admin\Controller;
|
||||||
|
use think\admin\helper\QueryHelper;
|
||||||
|
|
||||||
|
class Banner extends Controller
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 轮播图管理
|
||||||
|
* @auth true
|
||||||
|
* @menu true
|
||||||
|
* @login true
|
||||||
|
* @return void
|
||||||
|
* @throws \think\db\exception\DataNotFoundException
|
||||||
|
* @throws \think\db\exception\DbException
|
||||||
|
* @throws \think\db\exception\ModelNotFoundException
|
||||||
|
*/
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
$this->title = '轮播图管理';
|
||||||
|
CmsBanner::mQuery()->layTable(function () {
|
||||||
|
}, static function (QueryHelper $query) {
|
||||||
|
$query->equal('status')->like('title');
|
||||||
|
$query->timeBetween('create_at');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加轮播图
|
||||||
|
* @auth true
|
||||||
|
* @menu true
|
||||||
|
* @login true
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function add()
|
||||||
|
{
|
||||||
|
$this->title = '添加栏目';
|
||||||
|
$this->_applyFormToken();
|
||||||
|
CmsBanner::mForm('form');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 编辑轮播图
|
||||||
|
* @auth true
|
||||||
|
* @menu true
|
||||||
|
* @login true
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function edit()
|
||||||
|
{
|
||||||
|
$this->title = '编辑栏目';
|
||||||
|
$this->id = $this->request->param('id', 0, 'intval'); //当前栏目ID
|
||||||
|
$this->_applyFormToken();
|
||||||
|
CmsBanner::mForm('form');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除轮播图
|
||||||
|
* @auth true
|
||||||
|
* @menu true
|
||||||
|
* @login true
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function remove()
|
||||||
|
{
|
||||||
|
CmsBanner::mDelete('id');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 状态切换
|
||||||
|
* @auth true
|
||||||
|
* @menu true
|
||||||
|
* @login true
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function status()
|
||||||
|
{
|
||||||
|
CmsBanner::mSave($this->_vali([
|
||||||
|
'id.require' => '栏目ID不能为空',
|
||||||
|
'status.in:0,1' => '状态值范围异常!',
|
||||||
|
'status.require' => '状态值不能为空!',
|
||||||
|
]), 'id');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function sort()
|
||||||
|
{
|
||||||
|
CmsBanner::mSave($this->_vali([
|
||||||
|
'id.require' => '栏目ID不能为空',
|
||||||
|
'sort.require' => '排序值不能为空!',
|
||||||
|
'sort.number' => '排序必须为数字!',
|
||||||
|
'sort.between:0,9999' => '排序值必须为0~9999之间!',
|
||||||
|
]), 'id');
|
||||||
|
}
|
||||||
|
}
|
111
plugs/think-plugs-cms/src/controller/Category.php
Normal file
111
plugs/think-plugs-cms/src/controller/Category.php
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace plugin\cms\controller;
|
||||||
|
|
||||||
|
use plugin\cms\model\CmsCateArticle;
|
||||||
|
use plugin\cms\model\CmsCategory;
|
||||||
|
use think\admin\Controller;
|
||||||
|
use think\admin\helper\QueryHelper;
|
||||||
|
|
||||||
|
class Category extends Controller
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 栏目管理
|
||||||
|
* @auth true
|
||||||
|
* @menu true
|
||||||
|
* @login true
|
||||||
|
* @return void
|
||||||
|
* @throws \think\db\exception\DataNotFoundException
|
||||||
|
* @throws \think\db\exception\DbException
|
||||||
|
* @throws \think\db\exception\ModelNotFoundException
|
||||||
|
*/
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
$this->title = '栏目列表';
|
||||||
|
CmsCategory::mQuery()->layTable(function () {
|
||||||
|
}, static function (QueryHelper $query) {
|
||||||
|
$query->equal('status')->like('name');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加栏目
|
||||||
|
* @auth true
|
||||||
|
* @menu true
|
||||||
|
* @login true
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function add()
|
||||||
|
{
|
||||||
|
$this->title = '添加栏目';
|
||||||
|
$this->_applyFormToken();
|
||||||
|
CmsCategory::mForm('form');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 编辑栏目
|
||||||
|
* @auth true
|
||||||
|
* @menu true
|
||||||
|
* @login true
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function edit()
|
||||||
|
{
|
||||||
|
$this->title = '编辑栏目';
|
||||||
|
$this->id = $this->request->param('id', 0, 'intval'); //当前栏目ID
|
||||||
|
$this->_applyFormToken();
|
||||||
|
CmsCategory::mForm('form');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除栏目
|
||||||
|
* @auth true
|
||||||
|
* @menu true
|
||||||
|
* @login true
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function remove()
|
||||||
|
{
|
||||||
|
CmsCategory::mDelete('id');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function _delete_filter()
|
||||||
|
{
|
||||||
|
$id = $this->request->post('id');
|
||||||
|
$children_count = CmsCategory::where('pid', $id)->count();
|
||||||
|
if ($children_count > 0) {
|
||||||
|
$this->error("该栏目下有子栏目,不能删除!");
|
||||||
|
}
|
||||||
|
$articles_count = CmsCateArticle::where('cid', $id)->count();
|
||||||
|
if ($articles_count > 0) {
|
||||||
|
$this->error("该栏目下有文章,不能删除!");
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 状态切换
|
||||||
|
* @auth true
|
||||||
|
* @menu true
|
||||||
|
* @login true
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function status()
|
||||||
|
{
|
||||||
|
CmsCategory::mSave($this->_vali([
|
||||||
|
'id.require' => '栏目ID不能为空',
|
||||||
|
'status.in:0,1' => '状态值范围异常!',
|
||||||
|
'status.require' => '状态值不能为空!',
|
||||||
|
]), 'id');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function sort()
|
||||||
|
{
|
||||||
|
CmsCategory::mSave($this->_vali([
|
||||||
|
'id.require' => '栏目ID不能为空',
|
||||||
|
'sort.require' => '排序值不能为空!',
|
||||||
|
'sort.number' => '排序必须为数字!',
|
||||||
|
'sort.between:0,9999' => '排序值必须为0~9999之间!',
|
||||||
|
]), 'id');
|
||||||
|
}
|
||||||
|
}
|
12
plugs/think-plugs-cms/src/controller/Index.php
Normal file
12
plugs/think-plugs-cms/src/controller/Index.php
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace plugin\cms\controller;
|
||||||
|
|
||||||
|
use think\admin\Controller;
|
||||||
|
|
||||||
|
class Index extends Controller
|
||||||
|
{
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
31
plugs/think-plugs-cms/src/controller/api/Article.php
Normal file
31
plugs/think-plugs-cms/src/controller/api/Article.php
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace plugin\cms\controller\api;
|
||||||
|
|
||||||
|
use plugin\cms\model\CmsArticle;
|
||||||
|
use think\admin\Controller;
|
||||||
|
|
||||||
|
class Article extends Controller
|
||||||
|
{
|
||||||
|
public function index() {
|
||||||
|
$categoryId = $this->request->get('cid');
|
||||||
|
$query = CmsArticle::mk()->where('status', 1);
|
||||||
|
if (is_numeric($categoryId)) {
|
||||||
|
$query->hasWhere('cateids', function ($subQuery) use ($categoryId) {
|
||||||
|
$subQuery->where('cid', $categoryId);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
$articles = $query->field('id,title,thumb,author,from,view_count,publish_at')->order('sort asc,id desc')->paginate();
|
||||||
|
$this->success('获取文章列表', $articles);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function info() {
|
||||||
|
$id = $this->request->get('id');
|
||||||
|
CmsArticle::mk()->where('id', $id)->inc('view_count');
|
||||||
|
$article = CmsArticle::mk()->where('id', $id)->find();
|
||||||
|
if (empty($article)) {
|
||||||
|
$this->error('文章不存在');
|
||||||
|
}
|
||||||
|
$this->success('获取文章详情', $article);
|
||||||
|
}
|
||||||
|
}
|
14
plugs/think-plugs-cms/src/controller/api/Banner.php
Normal file
14
plugs/think-plugs-cms/src/controller/api/Banner.php
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace plugin\cms\controller\api;
|
||||||
|
|
||||||
|
use plugin\cms\model\CmsBanner;
|
||||||
|
use think\admin\Controller;
|
||||||
|
|
||||||
|
class Banner extends Controller
|
||||||
|
{
|
||||||
|
public function index() {
|
||||||
|
$banners = CmsBanner::mk()->where('status', '=', 1)->field("id, image")->order('sort asc,id desc')->select();
|
||||||
|
$this->success('获取轮播图列表', $banners);
|
||||||
|
}
|
||||||
|
}
|
14
plugs/think-plugs-cms/src/controller/api/Category.php
Normal file
14
plugs/think-plugs-cms/src/controller/api/Category.php
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace plugin\cms\controller\api;
|
||||||
|
|
||||||
|
use plugin\cms\model\CmsCategory;
|
||||||
|
use think\admin\Controller;
|
||||||
|
|
||||||
|
class Category extends Controller
|
||||||
|
{
|
||||||
|
public function index() {
|
||||||
|
$categories = CmsCategory::mk()->where('status', 1)->order('sort asc,id desc')->field("id, name")->select();
|
||||||
|
$this->success('获取分类成功', $categories);
|
||||||
|
}
|
||||||
|
}
|
24
plugs/think-plugs-cms/src/model/CmsArticle.php
Normal file
24
plugs/think-plugs-cms/src/model/CmsArticle.php
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace plugin\cms\model;
|
||||||
|
|
||||||
|
use think\admin\Model;
|
||||||
|
|
||||||
|
class CmsArticle extends Model
|
||||||
|
{
|
||||||
|
public function category()
|
||||||
|
{
|
||||||
|
return $this->belongsToMany(CmsCategory::class, CmsCateArticle::class,
|
||||||
|
'cid', 'aid');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function cateids()
|
||||||
|
{
|
||||||
|
return $this->hasMany(CmsCateArticle::class, 'aid');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getCateIdsAttr()
|
||||||
|
{
|
||||||
|
return $this->cateids->column('cid');
|
||||||
|
}
|
||||||
|
}
|
10
plugs/think-plugs-cms/src/model/CmsBanner.php
Normal file
10
plugs/think-plugs-cms/src/model/CmsBanner.php
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace plugin\cms\model;
|
||||||
|
|
||||||
|
use think\admin\Model;
|
||||||
|
|
||||||
|
class CmsBanner extends Model
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
17
plugs/think-plugs-cms/src/model/CmsCateArticle.php
Normal file
17
plugs/think-plugs-cms/src/model/CmsCateArticle.php
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace plugin\cms\model;
|
||||||
|
|
||||||
|
use think\model\Pivot;
|
||||||
|
|
||||||
|
class CmsCateArticle extends Pivot
|
||||||
|
{
|
||||||
|
public function category()
|
||||||
|
{
|
||||||
|
return $this->belongsTo('CmsCategory', 'cid', 'id');
|
||||||
|
}
|
||||||
|
public function article()
|
||||||
|
{
|
||||||
|
return $this->belongsTo('CmsArtical', 'aid', 'id');
|
||||||
|
}
|
||||||
|
}
|
29
plugs/think-plugs-cms/src/model/CmsCategory.php
Normal file
29
plugs/think-plugs-cms/src/model/CmsCategory.php
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace plugin\cms\model;
|
||||||
|
|
||||||
|
use think\admin\Model;
|
||||||
|
|
||||||
|
class CmsCategory extends Model
|
||||||
|
{
|
||||||
|
public static function getList()
|
||||||
|
{
|
||||||
|
return static::mk()->order('sort asc')->field('id,name')->where('status', 1)->select()->toArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function articles()
|
||||||
|
{
|
||||||
|
return $this->hasManyThrough(CmsArticle::class, CmsCateArticle::class,
|
||||||
|
'cid', 'id', 'id', 'aid');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function children()
|
||||||
|
{
|
||||||
|
return $this->hasMany(CmsCategory::class, 'pid', 'id');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function parent()
|
||||||
|
{
|
||||||
|
return $this->belongsTo(CmsCategory::class, 'pid', 'id');
|
||||||
|
}
|
||||||
|
}
|
88
plugs/think-plugs-cms/src/view/article/form.html
Normal file
88
plugs/think-plugs-cms/src/view/article/form.html
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
<form class="layui-form layui-card" action="{:sysuri()}" data-auto="true" method="post" autocomplete="off" data-table-id="articleTable">
|
||||||
|
<div class="layui-row">
|
||||||
|
<div class="layui-form-item">
|
||||||
|
<label class="layui-form-label">文章标题</label>
|
||||||
|
<div class="layui-input-block">
|
||||||
|
<input type="text" name="title" value='{$vo.title|default=""}' required placeholder="请输入文章标题" class="layui-input">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="layui-row">
|
||||||
|
<div class="layui-col-md6">
|
||||||
|
<div class="layui-form-item">
|
||||||
|
<label class="layui-form-label">文章作者</label>
|
||||||
|
<div class="layui-input-block">
|
||||||
|
<input type="text" name="author" value='{$vo.author|default=""}' placeholder="请输入文章作者" class="layui-input">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="layui-col-md6">
|
||||||
|
<div class="layui-form-item">
|
||||||
|
<label class="layui-form-label">文章来源</label>
|
||||||
|
<div class="layui-input-block">
|
||||||
|
<input type="text" name="source" value='{$vo.source|default=""}' placeholder="请输入文章来源" class="layui-input">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="layui-form-item">
|
||||||
|
<label class="layui-form-label">缩略图图片</label>
|
||||||
|
<div class="layui-input-block">
|
||||||
|
<input type="hidden" onchange="$(this).nextAll('img').attr('src', this.value)" name="thumb" value='{$vo.thumb|default=""}' placeholder="请上传缩略图图片" class="layui-input layui-hide">
|
||||||
|
<div class="layui-btn-container">
|
||||||
|
<a data-file="btn" data-type="bmp,png,jpeg,jpg" data-field="thumb" class="input-group-addon layui-btn layui-btn-active">
|
||||||
|
<i class="layui-icon layui-icon-upload"></i>
|
||||||
|
点击上传图片
|
||||||
|
</a>
|
||||||
|
<div class="layui-form-mid layui-word-aux">建议尺寸:750px*300px</div>
|
||||||
|
<a onclick="$('input[name=thumb]').val('').trigger('change')" class="layui-btn layui-btn-danger">
|
||||||
|
<i class="layui-icon layui-icon-close"></i>
|
||||||
|
点击清除图片
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<img data-tips-image src='{$vo.thumb|default=""}' alt="image" style="width: 375px; height: 150px; object-fit: cover">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="layui-form-item">
|
||||||
|
<label class="layui-form-label">文章分类</label>
|
||||||
|
<div class="layui-input-block">
|
||||||
|
{foreach $cates as $cate}
|
||||||
|
<label class="think-checkbox">
|
||||||
|
{if in_array($cate.id, $cate_ids)}
|
||||||
|
<input type="checkbox" checked name="cate_ids[]" value="{$cate.id}" lay-ignore>{$cate.name}
|
||||||
|
{else}
|
||||||
|
<input type="checkbox" name="cate_ids[]" value="{$cate.id}" lay-ignore>{$cate.name}
|
||||||
|
{/if}
|
||||||
|
</label>
|
||||||
|
{/foreach}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="layui-form-item">
|
||||||
|
<label class="layui-form-label">文章内容</label>
|
||||||
|
<div class="layui-input-block">
|
||||||
|
<textarea data-textarea class="layui-hide" name='content'>{$vo.content|default=""}</textarea>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{notempty name='id'}<input class="layui-input layui-hide" type='hidden' value='{$id}' name='id'>{/notempty}
|
||||||
|
<div class="layui-form-item text-center">
|
||||||
|
<button class="layui-btn layui-btn-normal" type='submit'>保存数据</button>
|
||||||
|
<button class="layui-btn layui-btn-danger" type='button' data-confirm="确定要取消编辑吗?" data-close>取消编辑</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
<script>
|
||||||
|
$(function () {
|
||||||
|
var editor = window.createEditor('[name="content"]');
|
||||||
|
if (typeof editor !== 'undefined') {
|
||||||
|
editor.on('change', function () {
|
||||||
|
$('[name="content"]').text(editor.getData());
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
$('[name="content"]').on('editor.init', function (event, myEditor) {
|
||||||
|
editor = myEditor;
|
||||||
|
myEditor.on('change', function () {
|
||||||
|
$('[name="content"]').text(editor.getData());
|
||||||
|
});
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
108
plugs/think-plugs-cms/src/view/article/index.html
Normal file
108
plugs/think-plugs-cms/src/view/article/index.html
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
{extend name="table"}
|
||||||
|
|
||||||
|
{block name="button"}
|
||||||
|
<!--{if auth("add")}-->
|
||||||
|
<button type="button" class="layui-btn layui-btn-sm layui-btn-primary" data-modal='{:url("add")}' data-title="添加文章">添加</button>
|
||||||
|
<!--{/if}-->
|
||||||
|
{/block}
|
||||||
|
|
||||||
|
{block name="content"}
|
||||||
|
<div class="layui-tab">
|
||||||
|
<div class="layui-row">
|
||||||
|
<div class="layui-col">
|
||||||
|
<div class="article_list think-bg-white">
|
||||||
|
{include file='article/index_search'}
|
||||||
|
<table class="layui-hide" data-url="{$request->url()}" data-target-search="form.form-search" id="articleTable" lay-filter="articleTable"></table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<script type="text/html" id="toolbar">
|
||||||
|
<!--{if auth("edit")}-->
|
||||||
|
<a data-modal="{:url('edit')}?id={{ d.id }}" data-height="80%" data-width="80%" class="layui-btn layui-btn-xs layui-btn-normal" title="修改">修改</a>
|
||||||
|
<!--{/if}-->
|
||||||
|
<!--{if auth("status")}-->
|
||||||
|
{{# if(d.status == 0){ }}
|
||||||
|
<a class="layui-btn layui-btn-xs layui-btn-normal" data-title="启用该轮播图" data-modal='{:url("status")}?id={{ d.id }}&status=1'>启 用</a>
|
||||||
|
{{# } else { }}
|
||||||
|
<a class="layui-btn layui-btn-xs layui-btn-primary" data-title="隐藏该轮播图" data-modal='{:url("status")}?id={{ d.id }}&status=0'>隐 藏</a>
|
||||||
|
{{# } }}
|
||||||
|
<!--{/if}-->
|
||||||
|
<!--{if auth("remove")}-->
|
||||||
|
<a data-confirm="确定要永久删除此文章吗?" data-action="{:url('remove')}" data-value="id#{{ d.id }}" data-csrf="{:systoken('remove')}" class="layui-btn layui-btn-xs layui-btn-danger" title="删除">删除</a>
|
||||||
|
<!--{/if}-->
|
||||||
|
</script>
|
||||||
|
{/block}
|
||||||
|
|
||||||
|
{block name='style'}
|
||||||
|
<style>
|
||||||
|
</style>
|
||||||
|
{/block}
|
||||||
|
|
||||||
|
{block name='script'}
|
||||||
|
<script>
|
||||||
|
$(function () {
|
||||||
|
$('#articleTable').layTable({
|
||||||
|
height: 'full-250',
|
||||||
|
toolbar: true,
|
||||||
|
sort: {field: 'sort', type: 'asc'},
|
||||||
|
title: '文章列表',
|
||||||
|
cols: [[
|
||||||
|
{type: 'numbers'},
|
||||||
|
{field: 'sort', title: '排序', width: 80, sort: true, edit: 'text'},
|
||||||
|
{field: 'thumb', title: '轮播图', width: 140, templet:function(item){
|
||||||
|
if (item.thumb) {
|
||||||
|
return '<img data-tips-image src="'+item.thumb+'" alt="image" style="width: 120px;height: 60px;">';
|
||||||
|
} else {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
}},
|
||||||
|
{field:'title', title:'标题'},
|
||||||
|
{field:'cate_name', title:'栏目', width:120},
|
||||||
|
{field:'status', title:'状态', width:80, templet:function(item){
|
||||||
|
if(item.status == 0){
|
||||||
|
return '<span style="color:red;">隐藏</span>';
|
||||||
|
}else if(item.status == 1){
|
||||||
|
return '<span style="color:green;">显示</span>';
|
||||||
|
}
|
||||||
|
}},
|
||||||
|
{field:'view_count', title:'浏览数', width:100, sort: true},
|
||||||
|
{field:'like_count', title:'点赞数', width:100, sort: true},
|
||||||
|
{field:'share_count', title:'分享数', width:100, sort: true},
|
||||||
|
{fixed: 'right', title:'操作', toolbar: '#toolbar', width:180}
|
||||||
|
]],
|
||||||
|
page: true
|
||||||
|
})
|
||||||
|
layui.use(['table'], function(){
|
||||||
|
var table = layui.table,
|
||||||
|
layer = layui.layer;
|
||||||
|
table.on('edit(articleTable)', function(obj) {
|
||||||
|
if (obj.field == 'sort') {
|
||||||
|
if (obj.value == '') {
|
||||||
|
obj.value = obj.oldValue
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
$.form.load("{:url('sort')}", {sort: obj.value, id: obj.data.id}, 'post', function (ret) {
|
||||||
|
$('#tree-table').trigger('reload');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})
|
||||||
|
})
|
||||||
|
layui.use(['table'], function(){
|
||||||
|
var table = layui.table,
|
||||||
|
layer = layui.layer;
|
||||||
|
|
||||||
|
//监听工具条
|
||||||
|
table.on('tool(articleTable)', function(obj){
|
||||||
|
if(obj.event === 'del'){
|
||||||
|
layer.confirm('真的删除行么', function(index){
|
||||||
|
obj.del();
|
||||||
|
layer.close(index);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
{/block}
|
23
plugs/think-plugs-cms/src/view/article/index_search.html
Normal file
23
plugs/think-plugs-cms/src/view/article/index_search.html
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
<fieldset>
|
||||||
|
<legend>条件搜索</legend>
|
||||||
|
<form class="layui-form layui-form-pane form-search" action="{:request()->url()}" onsubmit="return false" method="get" autocomplete="off">
|
||||||
|
<div class="layui-form-item layui-inline">
|
||||||
|
<label class="layui-form-label">文章标题</label>
|
||||||
|
<div class="layui-input-inline">
|
||||||
|
<input name="title" value="{:input('get.title')}" placeholder="请输入文章标题" class="layui-input">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="layui-form-item layui-inline">
|
||||||
|
<label class="layui-form-label">创建时间</label>
|
||||||
|
<div class="layui-input-inline">
|
||||||
|
<input data-date-range name="create_at" value="{:input('get.create_at')}" placeholder="请选择创建时间" class="layui-input">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="layui-form-item layui-inline">
|
||||||
|
<button class="layui-btn layui-btn-primary" lay-submit lay-filter="searchData"><i class="layui-icon"></i> 搜 索</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
</fieldset>
|
33
plugs/think-plugs-cms/src/view/banner/form.html
Normal file
33
plugs/think-plugs-cms/src/view/banner/form.html
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
<form class="layui-form layui-card" action="{:sysuri()}" data-auto="true" method="post" autocomplete="off" data-table-id="articleTable">
|
||||||
|
<div class="layui-row layui-col-space15">
|
||||||
|
<div class="layui-form-item">
|
||||||
|
<label class="layui-form-label">轮播图名称</label>
|
||||||
|
<div class="layui-input-block">
|
||||||
|
<input type="text" name="name" value='{$vo.name|default=""}' required placeholder="请输入轮播图名称" class="layui-input">
|
||||||
|
<div class="layui-form-mid layui-word-aux">仅用于后台展示</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="layui-form-item">
|
||||||
|
<label class="layui-form-label">轮播图图片</label>
|
||||||
|
<div class="layui-input-block">
|
||||||
|
<input type="hidden" name="image" data-size="1" value='{$vo.image|default=""}' required placeholder="请上传轮播图图片" class="layui-input layui-hide">
|
||||||
|
<div class="layui-form-mid layui-word-aux">建议尺寸:750*300</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{notempty name='id'}<input class="layui-input layui-hide" type='hidden' value='{$id}' name='id'>{/notempty}
|
||||||
|
<div class="layui-form-item text-center">
|
||||||
|
<button class="layui-btn layui-btn-normal" type='submit'>保存数据</button>
|
||||||
|
<button class="layui-btn layui-btn-danger" type='button' data-confirm="确定要取消编辑吗?" data-close>取消编辑</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
<script>
|
||||||
|
$('[name="image"]').uploadOneImage()
|
||||||
|
layui.use(['form'], function () {
|
||||||
|
var layer = layui.layer,
|
||||||
|
form = layui.form;
|
||||||
|
form.render();
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
</script>
|
87
plugs/think-plugs-cms/src/view/banner/index.html
Normal file
87
plugs/think-plugs-cms/src/view/banner/index.html
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
{extend name="table"}
|
||||||
|
|
||||||
|
{block name="button"}
|
||||||
|
<!--{if auth("add")}-->
|
||||||
|
<button type="button" class="layui-btn layui-btn-sm layui-btn-primary" data-modal='{:url("add")}' data-title="添加轮播图">添加</button>
|
||||||
|
<!--{/if}-->
|
||||||
|
{/block}
|
||||||
|
|
||||||
|
{block name="content"}
|
||||||
|
<div class="layui-tab layui-tab-card think-bg-white">
|
||||||
|
<div class="layui-tab-content think-box-shadow">
|
||||||
|
{include file='banner/index_search'}
|
||||||
|
<table class="layui-table margin-top-10" data-url="{$request->url()}" data-target-search="form.form-search" lay-skin="line" id="bannerTable"></table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script type="text/html" id="toolbar">
|
||||||
|
|
||||||
|
<!--{if auth("edit")}-->
|
||||||
|
<a data-modal="{:url('edit')}?id={{ d.id }}" class="layui-btn layui-btn-xs layui-btn-normal" title="修改">修改</a>
|
||||||
|
<!--{/if}-->
|
||||||
|
|
||||||
|
<!--{if auth("status")}-->
|
||||||
|
{{# if(d.status == 0){ }}
|
||||||
|
<a class="layui-btn layui-btn-xs layui-btn-normal" data-title="启用该轮播图" data-modal='{:url("status")}?id={{ d.id }}&status=1'>启 用</a>
|
||||||
|
{{# } else { }}
|
||||||
|
<a class="layui-btn layui-btn-xs layui-btn-primary" data-title="隐藏该轮播图" data-modal='{:url("status")}?id={{ d.id }}&status=0'>隐 藏</a>
|
||||||
|
{{# } }}
|
||||||
|
<!--{/if}-->
|
||||||
|
|
||||||
|
<!--{if auth("remove")}-->
|
||||||
|
<a data-confirm="确定要永久删除此轮播图吗?" data-action="{:url('remove')}" data-value="id#{{ d.id }}" data-csrf="{:systoken('remove')}" class="layui-btn layui-btn-xs layui-btn-danger" title="删除">删除</a>
|
||||||
|
<!--{/if}-->
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{/block}
|
||||||
|
|
||||||
|
{block name='style'}
|
||||||
|
<style>
|
||||||
|
</style>
|
||||||
|
{/block}
|
||||||
|
|
||||||
|
{block name='script'}
|
||||||
|
<script>
|
||||||
|
$(function () {
|
||||||
|
$('#bannerTable').layTable({
|
||||||
|
height: 'full-240',
|
||||||
|
toolbar: true,
|
||||||
|
sort: {field: 'sort', type: 'asc'},
|
||||||
|
title: '轮播图列表',
|
||||||
|
cols: [[
|
||||||
|
{type: 'numbers'},
|
||||||
|
{field: 'sort', title: '排序', width: 80, sort: true, edit: 'text'},
|
||||||
|
{field: 'image', title: '轮播图', width: 140, templet:function(item){
|
||||||
|
return '<img data-tips-image src="'+item.image+'" alt="image" style="width: 120px;height: 60px;">';
|
||||||
|
}},
|
||||||
|
{field: 'name', title: '轮播图名称', minWidth: 120},
|
||||||
|
{field: 'status', title: '状态', width: 60,templet:function(item){
|
||||||
|
if(item.status == 0){
|
||||||
|
return '<span style="color:red;">隐藏</span>';
|
||||||
|
}else if(item.status == 1){
|
||||||
|
return '<span style="color:green;">显示</span>';
|
||||||
|
}
|
||||||
|
}},
|
||||||
|
{field: 'create_at', title: '创建时间', width: 150},
|
||||||
|
{align: 'center', toolbar: '#toolbar', title: '操作', width: 240}
|
||||||
|
]]
|
||||||
|
})
|
||||||
|
layui.use(['table'], function(){
|
||||||
|
var table = layui.table,
|
||||||
|
layer = layui.layer;
|
||||||
|
table.on('edit(bannerTable)', function(obj) {
|
||||||
|
if (obj.field == 'sort') {
|
||||||
|
if (obj.value == '') {
|
||||||
|
obj.value = obj.oldValue
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
$.form.load("{:url('sort')}", {sort: obj.value, id: obj.data.id}, 'post', function (ret) {
|
||||||
|
$('#bannerTable').trigger('reload');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
{/block}
|
16
plugs/think-plugs-cms/src/view/banner/index_search.html
Normal file
16
plugs/think-plugs-cms/src/view/banner/index_search.html
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
<fieldset>
|
||||||
|
<legend>条件搜索</legend>
|
||||||
|
<form class="layui-form layui-form-pane form-search" action="{:request()->url()}" onsubmit="return false" method="get" autocomplete="off">
|
||||||
|
<div class="layui-form-item layui-inline">
|
||||||
|
<label class="layui-form-label">名称</label>
|
||||||
|
<div class="layui-input-inline">
|
||||||
|
<input name="name" value="{:input('get.name')}" placeholder="请输入名称" class="layui-input">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="layui-form-item layui-inline">
|
||||||
|
<button class="layui-btn layui-btn-primary" lay-submit lay-filter="searchData"><i class="layui-icon"></i> 搜 索</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
</fieldset>
|
99
plugs/think-plugs-cms/src/view/category/form.html
Normal file
99
plugs/think-plugs-cms/src/view/category/form.html
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
<form class="layui-form layui-card" action="{:request()->url()}" data-auto="true" method="post" autocomplete="off">
|
||||||
|
<div class="layui-card-body">
|
||||||
|
<div class="layui-row layui-col-space15">
|
||||||
|
<!--<div class="layui-form-item">
|
||||||
|
<label class="layui-form-label label-required-next">所属分类</label>
|
||||||
|
<div class="layui-input-block">
|
||||||
|
<select class="layui-input" name="pid" required>
|
||||||
|
<option value="0">作为一级分类</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>-->
|
||||||
|
|
||||||
|
<div class="layui-form-item">
|
||||||
|
<label class="layui-form-label">栏目名称</label>
|
||||||
|
<div class="layui-input-block">
|
||||||
|
<input type="text" name="name" value='{$vo.name|default=""}' required placeholder="请输入栏目名称" class="layui-input">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="layui-form-item">
|
||||||
|
<label class="layui-form-label">栏目描述</label>
|
||||||
|
<div class="layui-input-block">
|
||||||
|
<textarea name="description" placeholder="请输入描述" class="layui-textarea">{$vo.description|default=""}</textarea>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="layui-form-item">
|
||||||
|
<label class="layui-form-label">是否为外链</label>
|
||||||
|
<div class="layui-input-block">
|
||||||
|
<div class="layui-col-space15" style="content: none">
|
||||||
|
<div class="layui-col-xs2">
|
||||||
|
{foreach $_YES_OR_NO as $k=>$v}
|
||||||
|
<!--{if (!isset($vo.is_link) and $k eq '0') or (isset($vo.is_link) and $vo.is_link eq $k)}-->
|
||||||
|
<input type="radio" name="is_link" lay-filter="islink_filter" checked value="{$k}" title="{$v}">
|
||||||
|
<!--{else}-->
|
||||||
|
<input type="radio" name="is_link" lay-filter="islink_filter" value="{$k}" title="{$v}">
|
||||||
|
<!--{/if}-->
|
||||||
|
{/foreach}
|
||||||
|
</div>
|
||||||
|
<div class="layui-col-xs8" id="category_link_url" style="display: none;">
|
||||||
|
<input type="text" name="link_url" value='{$vo.link_url|default=""}' pattern="^(http:\/\/|^https:\/\/|^\/\/)((\w|=|\?|\.|\/|&|-)+)" placeholder="请输入跳转链接地址" class="layui-input">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="hr-line-dashed"></div>
|
||||||
|
{notempty name='vo.id'}<input type='hidden' value='{$vo.id}' name='id'>{/notempty}
|
||||||
|
<div class="layui-form-item text-center">
|
||||||
|
<button class="layui-btn layui-btn-normal" type='submit'>保存数据</button>
|
||||||
|
<button class="layui-btn layui-btn-danger" type='button' data-confirm="确定要取消编辑吗?" data-close>取消编辑</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.layui-tab-item{ min-height: 400px;}
|
||||||
|
.input-group-addon {
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
color: #eee;
|
||||||
|
width: 25px;
|
||||||
|
padding: 7px;
|
||||||
|
position: absolute;
|
||||||
|
margin-top: -1px;
|
||||||
|
text-align: center;
|
||||||
|
background: #393D49;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<script>
|
||||||
|
layui.form.render();
|
||||||
|
layui.use(['layer', 'jquery', 'form','element'], function () {
|
||||||
|
var layer = layui.layer,
|
||||||
|
$ = layui.jquery,
|
||||||
|
form = layui.form,
|
||||||
|
element = layui.element;
|
||||||
|
|
||||||
|
//监听是否为跳转链接的选择变化
|
||||||
|
form.on("radio(islink_filter)", function (data) {
|
||||||
|
if(parseInt(data.value)){
|
||||||
|
$('#category_link_url').show();
|
||||||
|
}else{
|
||||||
|
$('#category_link_url').hide();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
//监听指定开关
|
||||||
|
form.on('switch(urlpath_filter)', function(data){
|
||||||
|
if(this.checked){
|
||||||
|
$(this).parent('.layui-input-block').prev().removeClass('label-required-next');
|
||||||
|
$('input[name="url_path"]').next('span').hide();
|
||||||
|
$('input[name="url_path"]').removeAttr('required').attr('disabled',true);
|
||||||
|
}else{
|
||||||
|
$(this).parent('.layui-input-block').prev().addClass('label-required-next');
|
||||||
|
$('input[name="url_path"]').next('span').show();
|
||||||
|
$('input[name="url_path"]').removeAttr('disabled').attr('required',true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
84
plugs/think-plugs-cms/src/view/category/index.html
Normal file
84
plugs/think-plugs-cms/src/view/category/index.html
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
{extend name="table"}
|
||||||
|
|
||||||
|
{block name="button"}
|
||||||
|
<!--{if auth("add")}-->
|
||||||
|
<button data-modal='{:url("add")}' data-title="添加栏目" class='layui-btn layui-btn-sm layui-btn-primary'>添加栏目</button>
|
||||||
|
<!--{/if}-->
|
||||||
|
{/block}
|
||||||
|
|
||||||
|
{block name="content"}
|
||||||
|
<div class="layui-tab layui-tab-card think-bg-white">
|
||||||
|
<div class="layui-tab-content think-box-shadow">
|
||||||
|
{include file='category/index_search'}
|
||||||
|
<table class="layui-table margin-top-10" data-url="{$request->url()}" data-target-search="form.form-search" lay-skin="line" id="categoryTable"></table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script type="text/html" id="toolbar">
|
||||||
|
|
||||||
|
<!--{if auth("edit")}-->
|
||||||
|
<a data-modal="{:url('edit')}?id={{ d.id }}" class="layui-btn layui-btn-xs layui-btn-normal" title="修改">修改</a>
|
||||||
|
<!--{/if}-->
|
||||||
|
|
||||||
|
<!--{if auth("status")}-->
|
||||||
|
{{# if(d.status == 0){ }}
|
||||||
|
<a class="layui-btn layui-btn-xs layui-btn-normal" data-title="显示分类" data-modal='{:url("status")}?id={{ d.id }}&status=1'>显 示</a>
|
||||||
|
{{# } else { }}
|
||||||
|
<a class="layui-btn layui-btn-xs layui-btn-primary" data-title="隐藏分类" data-modal='{:url("status")}?id={{ d.id }}&status=0'>隐 藏</a>
|
||||||
|
{{# } }}
|
||||||
|
<!--{/if}-->
|
||||||
|
|
||||||
|
<!--{if auth("remove")}-->
|
||||||
|
<a data-confirm="确定要永久删除此分类吗?" data-action="{:url('remove')}" data-value="id#{{ d.id }}" data-csrf="{:systoken('remove')}" class="layui-btn layui-btn-xs layui-btn-danger" title="删除">删除</a>
|
||||||
|
<!--{/if}-->
|
||||||
|
</script>
|
||||||
|
{/block}
|
||||||
|
|
||||||
|
{block name='style'}
|
||||||
|
<style>
|
||||||
|
</style>
|
||||||
|
{/block}
|
||||||
|
|
||||||
|
{block name='script'}
|
||||||
|
<script>
|
||||||
|
$(function () {
|
||||||
|
$('#categoryTable').layTable({
|
||||||
|
height: 'full-240',
|
||||||
|
toolbar: true,
|
||||||
|
sort: {field: 'sort', type: 'asc'},
|
||||||
|
cols: [[
|
||||||
|
{type: 'numbers'},
|
||||||
|
{field: 'sort', title: '排序', width: 80, sort: true, edit: 'text'},
|
||||||
|
{field: 'name', title: '栏目名称', minWidth: 165},
|
||||||
|
{field: 'status', title: '状态', width: 60,templet:function(item){
|
||||||
|
if(item.status == 0){
|
||||||
|
return '<span style="color:red;">隐藏</span>';
|
||||||
|
}else if(item.status == 1){
|
||||||
|
return '<span style="color:green;">显示</span>';
|
||||||
|
}
|
||||||
|
}},
|
||||||
|
{field: 'description', title: '分类描述', width: 150},
|
||||||
|
{field: 'is_link', title: '是否为外链', templet: '<p>{{d.is_link?"是":"否"}}</p>', align: 'center', width: 90},
|
||||||
|
{field: 'create_at', title: '创建时间', width: 150},
|
||||||
|
{align: 'center', toolbar: '#toolbar', title: '操作', width: 240}
|
||||||
|
]]
|
||||||
|
})
|
||||||
|
layui.use(['table'], function(){
|
||||||
|
var table = layui.table,
|
||||||
|
layer = layui.layer;
|
||||||
|
table.on('edit(categoryTable)', function(obj) {
|
||||||
|
if (obj.field == 'sort') {
|
||||||
|
if (obj.value == '') {
|
||||||
|
obj.value = obj.oldValue
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
$.form.load("{:url('sort')}", {sort: obj.value, id: obj.data.id}, 'post', function (ret) {
|
||||||
|
$('#categoryTable').trigger('reload');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
{/block}
|
16
plugs/think-plugs-cms/src/view/category/index_search.html
Normal file
16
plugs/think-plugs-cms/src/view/category/index_search.html
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
<fieldset>
|
||||||
|
<legend>条件搜索</legend>
|
||||||
|
<form class="layui-form layui-form-pane form-search" action="{:request()->url()}" onsubmit="return false" method="get" autocomplete="off">
|
||||||
|
<div class="layui-form-item layui-inline">
|
||||||
|
<label class="layui-form-label">分类名称</label>
|
||||||
|
<div class="layui-input-inline">
|
||||||
|
<input name="name" value="{:input('get.name')}" placeholder="请输入分类名称" class="layui-input">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="layui-form-item layui-inline">
|
||||||
|
<button class="layui-btn layui-btn-primary" lay-submit lay-filter="searchData"><i class="layui-icon"></i> 搜 索</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
</fieldset>
|
11
plugs/think-plugs-cms/src/view/main.html
Normal file
11
plugs/think-plugs-cms/src/view/main.html
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<div class="layui-card layui-bg-gray">
|
||||||
|
{block name='style'}{/block}
|
||||||
|
{notempty name='title'}
|
||||||
|
<div class="layui-card-header notselect">
|
||||||
|
<span class="layui-icon layui-icon-next font-s10 color-desc margin-right-5"></span>{$title|default=''}
|
||||||
|
<div class="pull-right">{block name='button'}{/block}</div>
|
||||||
|
</div>
|
||||||
|
{/notempty}
|
||||||
|
<div class="layui-card-body">{block name='content'}{/block}</div>
|
||||||
|
{block name='script'}{/block}
|
||||||
|
</div>
|
23
plugs/think-plugs-cms/src/view/table.html
Normal file
23
plugs/think-plugs-cms/src/view/table.html
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
<div class="layui-card">
|
||||||
|
{block name='style'}{/block}
|
||||||
|
{block name='header'}
|
||||||
|
{notempty name='title'}
|
||||||
|
<div class="layui-card-header">
|
||||||
|
<span class="layui-icon font-s10 color-desc ta-mr-5"></span>{$title|lang}
|
||||||
|
<div class="pull-right">{block name='button'}{/block}</div>
|
||||||
|
</div>
|
||||||
|
{/notempty}
|
||||||
|
{/block}
|
||||||
|
<div class="layui-card-line"></div>
|
||||||
|
<div class="layui-card-body">
|
||||||
|
<div class="layui-card-table">
|
||||||
|
{notempty name='showErrorMessage'}
|
||||||
|
<div class="think-box-notify" type="error">
|
||||||
|
<b>系统提示:</b><span>{$showErrorMessage|raw}</span>
|
||||||
|
</div>
|
||||||
|
{/notempty}
|
||||||
|
{block name='content'}{/block}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{block name='script'}{/block}
|
||||||
|
</div>
|
41
plugs/think-plugs-points-mall/composer.json
Normal file
41
plugs/think-plugs-points-mall/composer.json
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
{
|
||||||
|
"type": "think-admin-plugin",
|
||||||
|
"name": "jerryyan/think-plugs-points-mall",
|
||||||
|
"license": "WTFPL",
|
||||||
|
"homepage": "https://thinkadmin.top",
|
||||||
|
"description": "Points Mall Plugin for ThinkAdmin",
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Jerry Yan",
|
||||||
|
"email": "jerryyan0912@qq.com"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"require": {
|
||||||
|
"php": ">7.1"
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"plugin\\points_mall\\": "src"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"extra": {
|
||||||
|
"config": {
|
||||||
|
"type": "module",
|
||||||
|
"name": "积分商城",
|
||||||
|
"document": "https://thinkadmin.top/plugin/think-plugs-wechat.html",
|
||||||
|
"description": "积分商城"
|
||||||
|
},
|
||||||
|
"think": {
|
||||||
|
"services": [
|
||||||
|
"plugin\\points_mall\\Service"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"minimum-stability": "dev",
|
||||||
|
"config": {
|
||||||
|
"sort-packages": true,
|
||||||
|
"allow-plugins": {
|
||||||
|
"zoujingli/think-install": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
36
plugs/think-plugs-points-mall/src/Service.php
Normal file
36
plugs/think-plugs-points-mall/src/Service.php
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace plugin\points_mall;
|
||||||
|
|
||||||
|
use think\admin\Plugin;
|
||||||
|
use think\facade\View;
|
||||||
|
|
||||||
|
class Service extends Plugin
|
||||||
|
{
|
||||||
|
protected $appName = '积分商城';
|
||||||
|
protected $appCode = 'points-mall';
|
||||||
|
protected $package = 'jerryyan/think-plugs-points-mall';
|
||||||
|
|
||||||
|
public static function register(): void
|
||||||
|
{
|
||||||
|
View::assign("_YES_OR_NO", [
|
||||||
|
'1' => '是',
|
||||||
|
'0' => '否'
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function menu(): array
|
||||||
|
{
|
||||||
|
$code = app(static::class)->appCode;
|
||||||
|
return [
|
||||||
|
[
|
||||||
|
'name' => '积分商城',
|
||||||
|
'subs' => [
|
||||||
|
['name' => '商品管理', 'icon' => 'layui-icon layui-icon-template-1', 'node' => "{$code}/goods/index"],
|
||||||
|
['name' => '订单管理', 'icon' => 'layui-icon layui-icon-template-1', 'node' => "{$code}/order/index"],
|
||||||
|
['name' => '用户积分', 'icon' => 'layui-icon layui-icon-template-1', 'node' => "{$code}/point/index"],
|
||||||
|
]
|
||||||
|
]
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
22
plugs/think-plugs-points-mall/src/controller/Goods.php
Normal file
22
plugs/think-plugs-points-mall/src/controller/Goods.php
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace plugin\points_mall\controller;
|
||||||
|
|
||||||
|
use think\admin\Controller;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 商品管理
|
||||||
|
*/
|
||||||
|
class Goods extends Controller
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 商品管理
|
||||||
|
* @auth true
|
||||||
|
* @menu true
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
$this->title = '商品管理';
|
||||||
|
}
|
||||||
|
}
|
22
plugs/think-plugs-points-mall/src/controller/Point.php
Normal file
22
plugs/think-plugs-points-mall/src/controller/Point.php
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace plugin\points_mall\controller;
|
||||||
|
|
||||||
|
use think\admin\Controller;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 积分情况
|
||||||
|
*/
|
||||||
|
class Point extends Controller
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 积分情况
|
||||||
|
* @auth true
|
||||||
|
* @menu true
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
25
plugs/think-plugs-points-mall/src/controller/api/Auth.php
Normal file
25
plugs/think-plugs-points-mall/src/controller/api/Auth.php
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace plugin\points_mall\controller\api;
|
||||||
|
|
||||||
|
use plugin\account\controller\api\Auth as AuthController;
|
||||||
|
use think\exception\HttpResponseException;
|
||||||
|
|
||||||
|
class Auth extends AuthController
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 控制器初始化
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
protected function initialize()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
parent::initialize();
|
||||||
|
$this->checkUserStatus(false);
|
||||||
|
} catch (HttpResponseException $exception) {
|
||||||
|
throw $exception;
|
||||||
|
} catch (\Exception $exception) {
|
||||||
|
$this->error($exception->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace plugin\points_mall\controller\api\auth;
|
||||||
|
|
||||||
|
use plugin\points_mall\controller\api\Auth;
|
||||||
|
use plugin\points_mall\model\PointsMallUserPointLog;
|
||||||
|
use plugin\points_mall\service\UserPointService;
|
||||||
|
|
||||||
|
class UserPoint extends Auth
|
||||||
|
{
|
||||||
|
public function myPoint() {
|
||||||
|
$point = UserPointService::getUserPoint($this->usid);
|
||||||
|
$this->success('获取用户积分', [
|
||||||
|
'point' => $point
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function myPointLog() {
|
||||||
|
$page = PointsMallUserPointLog::mk()->where('uid', $this->usid)->order('create_at desc')->paginate();
|
||||||
|
$this->success('获取积分记录', $page);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,21 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace plugin\points_mall\model;
|
||||||
|
|
||||||
|
use plugin\account\model\PluginAccountBind;
|
||||||
|
use think\admin\Model;
|
||||||
|
|
||||||
|
class PointsMallUserPoint extends Model
|
||||||
|
{
|
||||||
|
protected $pk = 'uid';
|
||||||
|
|
||||||
|
public function log()
|
||||||
|
{
|
||||||
|
return $this->hasMany(PointsMallUserPointLog::class, 'uid');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function user()
|
||||||
|
{
|
||||||
|
return $this->belongsTo(PluginAccountBind::class, 'uid');
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace plugin\points_mall\model;
|
||||||
|
|
||||||
|
use think\admin\Model;
|
||||||
|
|
||||||
|
class PointsMallUserPointLog extends Model
|
||||||
|
{
|
||||||
|
protected $pk = 'uid';
|
||||||
|
}
|
@ -0,0 +1,35 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace plugin\points_mall\service;
|
||||||
|
|
||||||
|
use plugin\points_mall\model\PointsMallUserPoint;
|
||||||
|
use plugin\points_mall\model\PointsMallUserPointLog;
|
||||||
|
|
||||||
|
class UserPointService
|
||||||
|
{
|
||||||
|
public static function getUserPoint($uid)
|
||||||
|
{
|
||||||
|
$point = PointsMallUserPoint::mk()->where('uid', $uid)->value('point');
|
||||||
|
if ($point === null) {
|
||||||
|
$point = 0;
|
||||||
|
PointsMallUserPoint::mk()->save(['uid' => $uid, 'point' => $point]);
|
||||||
|
}
|
||||||
|
return $point;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function addUserPoint($uid, $point, $reason)
|
||||||
|
{
|
||||||
|
$userPoint = PointsMallUserPoint::mk()->where('uid', $uid)->find();
|
||||||
|
if (empty($userPoint)) {
|
||||||
|
$userPoint = PointsMallUserPoint::mk()->create(['uid' => $uid, 'point' => 0]);
|
||||||
|
}
|
||||||
|
$userPoint->startTrans();
|
||||||
|
$userPoint->inc('point', $point);
|
||||||
|
$userPoint->log()->save([
|
||||||
|
'point' => $point,
|
||||||
|
'reason' => $reason,
|
||||||
|
]);
|
||||||
|
$userPoint->save();
|
||||||
|
$userPoint->commit();
|
||||||
|
}
|
||||||
|
}
|
11
plugs/think-plugs-points-mall/src/view/main.html
Normal file
11
plugs/think-plugs-points-mall/src/view/main.html
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<div class="layui-card layui-bg-gray">
|
||||||
|
{block name='style'}{/block}
|
||||||
|
{notempty name='title'}
|
||||||
|
<div class="layui-card-header notselect">
|
||||||
|
<span class="layui-icon layui-icon-next font-s10 color-desc margin-right-5"></span>{$title|default=''}
|
||||||
|
<div class="pull-right">{block name='button'}{/block}</div>
|
||||||
|
</div>
|
||||||
|
{/notempty}
|
||||||
|
<div class="layui-card-body">{block name='content'}{/block}</div>
|
||||||
|
{block name='script'}{/block}
|
||||||
|
</div>
|
23
plugs/think-plugs-points-mall/src/view/table.html
Normal file
23
plugs/think-plugs-points-mall/src/view/table.html
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
<div class="layui-card">
|
||||||
|
{block name='style'}{/block}
|
||||||
|
{block name='header'}
|
||||||
|
{notempty name='title'}
|
||||||
|
<div class="layui-card-header">
|
||||||
|
<span class="layui-icon font-s10 color-desc ta-mr-5"></span>{$title|lang}
|
||||||
|
<div class="pull-right">{block name='button'}{/block}</div>
|
||||||
|
</div>
|
||||||
|
{/notempty}
|
||||||
|
{/block}
|
||||||
|
<div class="layui-card-line"></div>
|
||||||
|
<div class="layui-card-body">
|
||||||
|
<div class="layui-card-table">
|
||||||
|
{notempty name='showErrorMessage'}
|
||||||
|
<div class="think-box-notify" type="error">
|
||||||
|
<b>系统提示:</b><span>{$showErrorMessage|raw}</span>
|
||||||
|
</div>
|
||||||
|
{/notempty}
|
||||||
|
{block name='content'}{/block}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{block name='script'}{/block}
|
||||||
|
</div>
|
41
plugs/think-plugs-ticket/composer.json
Normal file
41
plugs/think-plugs-ticket/composer.json
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
{
|
||||||
|
"type": "think-admin-plugin",
|
||||||
|
"name": "jerryyan/think-plugs-ticket",
|
||||||
|
"license": "WTFPL",
|
||||||
|
"homepage": "https://thinkadmin.top",
|
||||||
|
"description": "Ticket Plugin for ThinkAdmin",
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Jerry Yan",
|
||||||
|
"email": "jerryyan0912@qq.com"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"require": {
|
||||||
|
"php": ">7.1"
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"plugin\\ticket\\": "src"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"extra": {
|
||||||
|
"config": {
|
||||||
|
"type": "module",
|
||||||
|
"name": "工单管理",
|
||||||
|
"document": "https://thinkadmin.top/plugin/think-plugs-wechat.html",
|
||||||
|
"description": "工单管理"
|
||||||
|
},
|
||||||
|
"think": {
|
||||||
|
"services": [
|
||||||
|
"plugin\\ticket\\Service"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"minimum-stability": "dev",
|
||||||
|
"config": {
|
||||||
|
"sort-packages": true,
|
||||||
|
"allow-plugins": {
|
||||||
|
"zoujingli/think-install": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
30
plugs/think-plugs-ticket/src/Service.php
Normal file
30
plugs/think-plugs-ticket/src/Service.php
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace plugin\ticket;
|
||||||
|
|
||||||
|
use think\admin\Plugin;
|
||||||
|
|
||||||
|
class Service extends Plugin
|
||||||
|
{
|
||||||
|
protected $appName = '工单管理';
|
||||||
|
protected $appCode = 'ticket';
|
||||||
|
protected $package = 'jerryyan/think-plugs-ticket';
|
||||||
|
|
||||||
|
public static function register(): void
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function menu(): array
|
||||||
|
{
|
||||||
|
$code = app(static::class)->appCode;
|
||||||
|
return [
|
||||||
|
[
|
||||||
|
'name' => '工单管理',
|
||||||
|
'subs' => [
|
||||||
|
['name' => '工单列表', 'icon' => 'layui-icon layui-icon-template-1', 'node' => "{$code}/ticket/index"],
|
||||||
|
['name' => '工单分类', 'icon' => 'layui-icon layui-icon-template-1', 'node' => "{$code}/type/index"],
|
||||||
|
]
|
||||||
|
]
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
130
plugs/think-plugs-ticket/src/controller/Ticket.php
Normal file
130
plugs/think-plugs-ticket/src/controller/Ticket.php
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace plugin\ticket\controller;
|
||||||
|
|
||||||
|
use plugin\ticket\model\TicketReply;
|
||||||
|
use plugin\ticket\model\TicketTicket;
|
||||||
|
use plugin\ticket\model\TicketType;
|
||||||
|
use think\admin\Controller;
|
||||||
|
use think\admin\helper\QueryHelper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 工单管理
|
||||||
|
*/
|
||||||
|
class Ticket extends Controller
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 工单列表
|
||||||
|
* @auth true
|
||||||
|
* @menu true
|
||||||
|
* @return void
|
||||||
|
* @throws \think\db\exception\DataNotFoundException
|
||||||
|
* @throws \think\db\exception\DbException
|
||||||
|
* @throws \think\db\exception\ModelNotFoundException
|
||||||
|
*/
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
$this->title = '工单中心';
|
||||||
|
$this->type_list = TicketType::getList();
|
||||||
|
$this->user_id = $this->request->session('user')['id'];
|
||||||
|
TicketTicket::mQuery()->layTable(function () {
|
||||||
|
|
||||||
|
}, function (QueryHelper $query) {
|
||||||
|
$query->like(['title|content|contact_name|ticket_address|contact_phone#keyword'])
|
||||||
|
->dateBetween(['create_at', 'last_activity_at'])
|
||||||
|
->equal(['status', 'type_id']);
|
||||||
|
$query->with(['user'])->append(['imgs_arr', 'status_text', 'type_name', 'last_reply']);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加工单
|
||||||
|
* @auth true
|
||||||
|
* @menu true
|
||||||
|
* @return void
|
||||||
|
* @throws \think\db\exception\DataNotFoundException
|
||||||
|
* @throws \think\db\exception\DbException
|
||||||
|
* @throws \think\db\exception\ModelNotFoundException
|
||||||
|
*/
|
||||||
|
public function add()
|
||||||
|
{
|
||||||
|
$this->title = '添加工单';
|
||||||
|
$this->types = TicketType::mk()->scope('active')->select();
|
||||||
|
TicketTicket::mForm('form');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function _form_filter(&$data)
|
||||||
|
{
|
||||||
|
if ($this->request->isPost()) {
|
||||||
|
$data['uid'] = 0;
|
||||||
|
}
|
||||||
|
$data['status'] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查看工单
|
||||||
|
* @auth true
|
||||||
|
* @menu true
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function detail()
|
||||||
|
{
|
||||||
|
$this->title = '工单详情';
|
||||||
|
['id' => $id] = $this->_vali(['id.require' => '请指定工单ID!']);
|
||||||
|
$this->vo = TicketTicket::mk()->with(['user', 'type', 'reply'])->append(['imgs_arr', 'status_text', 'type_name', 'last_reply'])->find($id);
|
||||||
|
$this->fetch();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 编辑工单
|
||||||
|
* @auth true
|
||||||
|
* @menu true
|
||||||
|
* @return void
|
||||||
|
* @throws \think\db\exception\DataNotFoundException
|
||||||
|
* @throws \think\db\exception\DbException
|
||||||
|
* @throws \think\db\exception\ModelNotFoundException
|
||||||
|
*/
|
||||||
|
public function edit()
|
||||||
|
{
|
||||||
|
$this->title = '编辑工单';
|
||||||
|
$this->types = TicketType::mk()->scope('active')->select();
|
||||||
|
TicketTicket::mForm('form');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除工单
|
||||||
|
* @auth true
|
||||||
|
* @menu true
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function remove()
|
||||||
|
{
|
||||||
|
TicketTicket::mDelete();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function reply()
|
||||||
|
{
|
||||||
|
$this->title = '回复工单';
|
||||||
|
[
|
||||||
|
'ticket_id'=>$ticket_id,
|
||||||
|
'id'=>$id
|
||||||
|
] = $this->_vali([
|
||||||
|
'ticket_id.require'=>'请指定工单ID!',
|
||||||
|
'id.require'=>'请指定回复ID!'
|
||||||
|
]);
|
||||||
|
$this->vo = TicketTicket::mk()->with(['user', 'type'])->append(['imgs_arr', 'status_text', 'type_name'])->find($ticket_id);
|
||||||
|
TicketReply::mForm('reply');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function _reply_form_filter(&$data)
|
||||||
|
{
|
||||||
|
if ($this->request->isPost()) {
|
||||||
|
$this->_applyFormToken();
|
||||||
|
$data['type'] = 1;
|
||||||
|
$adminInfo = $this->request->session('user');
|
||||||
|
$data['user_id'] = $adminInfo['id'];
|
||||||
|
$data['username'] = $adminInfo['nickname'];
|
||||||
|
$data['contact'] = $adminInfo['contact_phone'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
90
plugs/think-plugs-ticket/src/controller/Type.php
Normal file
90
plugs/think-plugs-ticket/src/controller/Type.php
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace plugin\ticket\controller;
|
||||||
|
|
||||||
|
use plugin\ticket\model\TicketTicket;
|
||||||
|
use plugin\ticket\model\TicketType;
|
||||||
|
use think\admin\Controller;
|
||||||
|
use think\admin\helper\QueryHelper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 工单类型管理
|
||||||
|
*/
|
||||||
|
class Type extends Controller
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 工单类型列表
|
||||||
|
* @return void
|
||||||
|
* @throws \think\db\exception\DataNotFoundException
|
||||||
|
* @throws \think\db\exception\DbException
|
||||||
|
* @throws \think\db\exception\ModelNotFoundException
|
||||||
|
*/
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
$this->title = '工单类型';
|
||||||
|
TicketType::mQuery()->layTable(function () {
|
||||||
|
|
||||||
|
}, function (QueryHelper $query) {
|
||||||
|
$query->withCount(['tickets']);
|
||||||
|
$query->like(['name'])->equal(['status']);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加工单类型
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function add()
|
||||||
|
{
|
||||||
|
TicketType::mForm('form');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 编辑工单类型
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function edit()
|
||||||
|
{
|
||||||
|
TicketType::mForm('form');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 修改工单类型状态
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function status()
|
||||||
|
{
|
||||||
|
TicketType::mSave($this->_vali([
|
||||||
|
'id.require' => '类型ID不能为空',
|
||||||
|
'status.in:0,1' => '状态值范围异常!',
|
||||||
|
'status.require' => '状态值不能为空!',
|
||||||
|
]), 'id');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 修改工单类型排序
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function sort()
|
||||||
|
{
|
||||||
|
TicketType::mSave($this->_vali([
|
||||||
|
'id.require' => '文章ID不能为空',
|
||||||
|
'sort.require' => '排序值不能为空!',
|
||||||
|
'sort.number' => '排序必须为数字!',
|
||||||
|
'sort.between:0,9999' => '排序值必须为0~9999之间!',
|
||||||
|
]), 'id');
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 删除工单类型
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function remove()
|
||||||
|
{
|
||||||
|
['id' => $id] = $this->_vali(['id.require' => '请指定工单类型ID!']);
|
||||||
|
$count = TicketTicket::mk()->scope('avail')->where('type_id', '=', $id)->count();
|
||||||
|
if ($count > 0) {
|
||||||
|
$this->error('工单类型删除失败,请先删除该类型下的工单!');
|
||||||
|
}
|
||||||
|
TicketType::mDelete();
|
||||||
|
}
|
||||||
|
}
|
31
plugs/think-plugs-ticket/src/model/TicketReply.php
Normal file
31
plugs/think-plugs-ticket/src/model/TicketReply.php
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace plugin\ticket\model;
|
||||||
|
|
||||||
|
use think\admin\Model;
|
||||||
|
use think\admin\model\SystemUser;
|
||||||
|
|
||||||
|
class TicketReply extends Model
|
||||||
|
{
|
||||||
|
protected $append = ['type_name'];
|
||||||
|
public function ticket()
|
||||||
|
{
|
||||||
|
return $this->belongsTo(TicketTicket::class, 'ticket_id');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function user()
|
||||||
|
{
|
||||||
|
return $this->belongsTo(SystemUser::class, 'user_id');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getTypeNameAttr($value, $data)
|
||||||
|
{
|
||||||
|
switch ($data['type']) {
|
||||||
|
case 0: return '流转';
|
||||||
|
case 1: return '回复';
|
||||||
|
case 9: return '退回';
|
||||||
|
default: return '其他';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
68
plugs/think-plugs-ticket/src/model/TicketTicket.php
Normal file
68
plugs/think-plugs-ticket/src/model/TicketTicket.php
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace plugin\ticket\model;
|
||||||
|
|
||||||
|
use plugin\account\model\PluginAccountBind;
|
||||||
|
use think\admin\Model;
|
||||||
|
|
||||||
|
class TicketTicket extends Model
|
||||||
|
{
|
||||||
|
protected $append = ['status_text', 'type_name'];
|
||||||
|
public function type()
|
||||||
|
{
|
||||||
|
return $this->belongsTo(TicketType::class, 'type_id');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function user()
|
||||||
|
{
|
||||||
|
return $this->belongsTo(PluginAccountBind::class, 'uid');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function reply()
|
||||||
|
{
|
||||||
|
return $this->hasMany(TicketReply::class, 'ticket_id')->order("create_at", 'asc');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getImgsArrAttr($value, $data)
|
||||||
|
{
|
||||||
|
return str2arr($data['imgs'] ?: '', '|');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getLastReplyAttr($value, $data)
|
||||||
|
{
|
||||||
|
return $this->reply()->order('create_at', 'desc')->find();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getTypeNameAttr($value, $data)
|
||||||
|
{
|
||||||
|
$type = $this->type()->find();
|
||||||
|
if (!empty($type)) {
|
||||||
|
return $type['name'];
|
||||||
|
} else {
|
||||||
|
return '未知';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getStatusTextAttr($value, $data)
|
||||||
|
{
|
||||||
|
if (!empty($this->getStatusList()[$data['status']])) {
|
||||||
|
return $this->getStatusList()[$data['status']];
|
||||||
|
} else {
|
||||||
|
return '未知';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getStatusList()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
-1 => '已关闭',
|
||||||
|
0 => '待处理',
|
||||||
|
1 => '已作处理',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function scopeAvail($query)
|
||||||
|
{
|
||||||
|
return $query->where('status', '>=', '0');
|
||||||
|
}
|
||||||
|
}
|
23
plugs/think-plugs-ticket/src/model/TicketType.php
Normal file
23
plugs/think-plugs-ticket/src/model/TicketType.php
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace plugin\ticket\model;
|
||||||
|
|
||||||
|
use think\admin\Model;
|
||||||
|
|
||||||
|
class TicketType extends Model
|
||||||
|
{
|
||||||
|
public static function getList()
|
||||||
|
{
|
||||||
|
return self::mk()->scope('active')->order('sort', 'asc')->field('name, id')->select();
|
||||||
|
}
|
||||||
|
public function tickets()
|
||||||
|
{
|
||||||
|
return $this->hasMany(TicketTicket::class, 'type_id');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function scopeActive($query)
|
||||||
|
{
|
||||||
|
return $query->where('status', '=', '1');
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
11
plugs/think-plugs-ticket/src/view/main.html
Normal file
11
plugs/think-plugs-ticket/src/view/main.html
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<div class="layui-card layui-bg-gray">
|
||||||
|
{block name='style'}{/block}
|
||||||
|
{notempty name='title'}
|
||||||
|
<div class="layui-card-header notselect">
|
||||||
|
<span class="layui-icon layui-icon-next font-s10 color-desc margin-right-5"></span>{$title|default=''}
|
||||||
|
<div class="pull-right">{block name='button'}{/block}</div>
|
||||||
|
</div>
|
||||||
|
{/notempty}
|
||||||
|
<div class="layui-card-body">{block name='content'}{/block}</div>
|
||||||
|
{block name='script'}{/block}
|
||||||
|
</div>
|
23
plugs/think-plugs-ticket/src/view/table.html
Normal file
23
plugs/think-plugs-ticket/src/view/table.html
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
<div class="layui-card">
|
||||||
|
{block name='style'}{/block}
|
||||||
|
{block name='header'}
|
||||||
|
{notempty name='title'}
|
||||||
|
<div class="layui-card-header">
|
||||||
|
<span class="layui-icon font-s10 color-desc ta-mr-5"></span>{$title|lang}
|
||||||
|
<div class="pull-right">{block name='button'}{/block}</div>
|
||||||
|
</div>
|
||||||
|
{/notempty}
|
||||||
|
{/block}
|
||||||
|
<div class="layui-card-line"></div>
|
||||||
|
<div class="layui-card-body">
|
||||||
|
<div class="layui-card-table">
|
||||||
|
{notempty name='showErrorMessage'}
|
||||||
|
<div class="think-box-notify" type="error">
|
||||||
|
<b>系统提示:</b><span>{$showErrorMessage|raw}</span>
|
||||||
|
</div>
|
||||||
|
{/notempty}
|
||||||
|
{block name='content'}{/block}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{block name='script'}{/block}
|
||||||
|
</div>
|
65
plugs/think-plugs-ticket/src/view/ticket/detail.html
Normal file
65
plugs/think-plugs-ticket/src/view/ticket/detail.html
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
<div class="layui-card">
|
||||||
|
<div class="layui-card-header">工单内容</div>
|
||||||
|
<div class="layui-card-body">
|
||||||
|
<div class="layui-row">
|
||||||
|
工单编号:{$vo.id|default=""}
|
||||||
|
</div>
|
||||||
|
<div class="layui-row">
|
||||||
|
工单标题:{$vo.title|default=""}
|
||||||
|
</div>
|
||||||
|
<div class="layui-row">
|
||||||
|
反馈人信息:{$vo.contact_name|default="未填写名称"},
|
||||||
|
联系方式:{$vo.contact_phone|default="未填写联系方式"},
|
||||||
|
联系地址:{$vo.contact_address|default="未填写地址"}
|
||||||
|
</div>
|
||||||
|
<div class="layui-row">
|
||||||
|
工单类型:{$vo.type_name|default=""}
|
||||||
|
</div>
|
||||||
|
<div class="layui-row">
|
||||||
|
工单地址:{$vo.ticket_address|default=""}
|
||||||
|
</div>
|
||||||
|
<div class="layui-row">
|
||||||
|
工单内容:{$vo.content|default=""}
|
||||||
|
</div>
|
||||||
|
<div class="layui-row">
|
||||||
|
工单图片:
|
||||||
|
<div>
|
||||||
|
{foreach $vo.imgs_arr as $img}
|
||||||
|
<img data-tips-image src="{$img}" alt="image" style="height: 100px;">
|
||||||
|
<span> </span>
|
||||||
|
{/foreach}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="layui-card">
|
||||||
|
<div class="layui-card-header">工单流转详情</div>
|
||||||
|
<div class="layui-card-body">
|
||||||
|
<table id="replyTable" class="layui-table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th lay-data='{field: "username", width: "120px"}'>工单处理人</th>
|
||||||
|
<th lay-data='{field: "type_name", width: "120px"}'>处理类型</th>
|
||||||
|
<th lay-data='{field: "create_at", width: "180px"}'>工单处理时间</th>
|
||||||
|
<th lay-data='{field: "content", minWidth: "200px"}'>处理内容</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{notempty name='vo.reply'}
|
||||||
|
{foreach $vo.reply as $reply}
|
||||||
|
<tr>
|
||||||
|
<td>{$reply.username|default=""}</td>
|
||||||
|
<td>{$reply.type_name|default=""}</td>
|
||||||
|
<td>{$reply.create_at|default=""}</td>
|
||||||
|
<td>{$reply.content|default=""}</td>
|
||||||
|
</tr>
|
||||||
|
{/foreach}
|
||||||
|
{else}
|
||||||
|
<tr>
|
||||||
|
<td colspan="999" class="text-center">暂无工单流转记录</td>
|
||||||
|
</tr>
|
||||||
|
{/notempty}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
44
plugs/think-plugs-ticket/src/view/ticket/form.html
Normal file
44
plugs/think-plugs-ticket/src/view/ticket/form.html
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
<form class="layui-form layui-card" action="{:sysuri()}" data-auto="true" method="post" autocomplete="off" data-table-id="ticketTable">
|
||||||
|
<h1 style="color: red; text-align: center; padding: 20px; border: 1px solid red; margin-bottom: 20px">
|
||||||
|
原则上不允许私自创建或修改工单!!!
|
||||||
|
</h1>
|
||||||
|
<div class="layui-row">
|
||||||
|
<div class="layui-form-item">
|
||||||
|
<label class="layui-form-label">工单标题</label>
|
||||||
|
<div class="layui-input-block">
|
||||||
|
<input type="text" name="title" value='{$vo.title|default=""}' required placeholder="请输入工单标题" class="layui-input">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="layui-form-item">
|
||||||
|
<label class="layui-form-label">工单分类</label>
|
||||||
|
<div class="layui-input-block">
|
||||||
|
<select class="layui-select" name="type_id" required>
|
||||||
|
{foreach $types as $type}
|
||||||
|
<option value='{$type.id}'>{$type.name}</option>
|
||||||
|
{/foreach}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="layui-form-item">
|
||||||
|
<label class="layui-form-label">工单内容</label>
|
||||||
|
<div class="layui-input-block">
|
||||||
|
<textarea data-textarea class="layui-textarea" name='content' required>{$vo.content|default=""}</textarea>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="layui-form-item">
|
||||||
|
<label class="layui-form-label">工单图片</label>
|
||||||
|
<div class="layui-input-block">
|
||||||
|
<input type="hidden" value='{$vo.imgs|default=""}' name="imgs">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{notempty name='id'}<input class="layui-input layui-hide" type='hidden' value='{$id}' name='id'>{/notempty}
|
||||||
|
<div class="layui-form-item text-center">
|
||||||
|
<button class="layui-btn layui-btn-normal" type='submit'>保存数据</button>
|
||||||
|
<button class="layui-btn layui-btn-danger" type='button' data-confirm="确定要取消编辑吗?" data-close>取消编辑</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
<script>
|
||||||
|
$('[name="imgs"]').uploadMultipleImage()
|
||||||
|
</script>
|
85
plugs/think-plugs-ticket/src/view/ticket/index.html
Normal file
85
plugs/think-plugs-ticket/src/view/ticket/index.html
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
{extend name="table"}
|
||||||
|
|
||||||
|
{block name="button"}
|
||||||
|
<!--{if auth("add")}-->
|
||||||
|
<button type="button" class="layui-btn layui-btn-sm layui-btn-disabled" data-modal='{:url("add")}' data-title="添加工单">添加工单</button>
|
||||||
|
<!--{/if}-->
|
||||||
|
{/block}
|
||||||
|
|
||||||
|
{block name="content"}
|
||||||
|
<div class="layui-tab">
|
||||||
|
<div class="layui-row">
|
||||||
|
<div class="layui-col">
|
||||||
|
<div class="article_list think-bg-white">
|
||||||
|
{include file='ticket/index_search'}
|
||||||
|
<table class="layui-hide" data-url="{$request->url()}" data-target-search="form.form-search" id="ticketTable" lay-filter="ticketTable"></table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<script type="text/html" id="toolbar">
|
||||||
|
<!--{if auth("detail")}-->
|
||||||
|
<a data-modal="{:url('detail')}?id={{ d.id }}" data-height="90%" data-width="60%" class="layui-btn layui-btn-xs layui-btn-normal" title="详情">详情</a>
|
||||||
|
<!--{/if}-->
|
||||||
|
<!--{if auth("move")}-->
|
||||||
|
<a data-modal="{:url('move')}?ticket_id={{ d.id }}" data-height="80%" data-width="80%" class="layui-btn layui-btn-xs" title="流转">流转</a>
|
||||||
|
<!--{/if}-->
|
||||||
|
<!--{if auth("reply")}-->
|
||||||
|
{{# if (d.last_reply && d.last_reply.user_id == {$user_id} && d.last_reply.status == 0) { }}
|
||||||
|
<a data-modal="{:url('reply')}?id={{ d.last_reply.id }}&ticket_id={{ d.id }}" data-height="80%" data-width="80%" class="layui-btn layui-btn-xs" title="回复">回复</a>
|
||||||
|
{{# }; }}
|
||||||
|
<!--{/if}-->
|
||||||
|
<!--{if auth("edit")}-->
|
||||||
|
<a data-modal="{:url('edit')}?id={{ d.id }}" data-height="80%" data-width="80%" class="layui-btn layui-btn-xs layui-btn-danger" title="修改工单">修改</a>
|
||||||
|
<!--{/if}-->
|
||||||
|
<!--{if auth("remove")}-->
|
||||||
|
<a data-confirm="原则上不允许主动删除用户工单,是否继续删除?" data-action="{:url('remove')}" data-value="id#{{ d.id }}" class="layui-btn layui-btn-xs layui-btn-danger" title="删除">删除</a>
|
||||||
|
<!--{/if}-->
|
||||||
|
</script>
|
||||||
|
{/block}
|
||||||
|
|
||||||
|
{block name='style'}
|
||||||
|
<style>
|
||||||
|
</style>
|
||||||
|
{/block}
|
||||||
|
|
||||||
|
{block name='script'}
|
||||||
|
<script>
|
||||||
|
$(function () {
|
||||||
|
$('#ticketTable').layTable({
|
||||||
|
height: 'full-250',
|
||||||
|
toolbar: true,
|
||||||
|
sort: {field: 'create_at', type: 'desc'},
|
||||||
|
title: '工单列表',
|
||||||
|
cols: [[
|
||||||
|
{field: 'create_at', title: '工单创建时间', width: 160, sort: true},
|
||||||
|
{field:'title', title:'标题', width:160},
|
||||||
|
{field:'type_name', title:'工单类型', width:120},
|
||||||
|
{field:'content', title:'工单内容', minWidth:100},
|
||||||
|
{field:'ticket_address', title:'工单地址', width:100},
|
||||||
|
{field: 'imgs', title: '工单图片', width: 100, templet:function(item){
|
||||||
|
if (item.imgs) {
|
||||||
|
return item.imgs.split("|").map((img) => {
|
||||||
|
return laytpl('<a target="_blank" data-tips-hover data-tips-image="{{d}}"><i class="layui-icon layui-icon-picture"></i></a>').render(img)
|
||||||
|
}).concat(' ')
|
||||||
|
} else {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
}},
|
||||||
|
{field:'status', title:'状态', width:80, templet:function(item){
|
||||||
|
if(item.status == 0){
|
||||||
|
return '<span style="color:red;">正在处理</span>';
|
||||||
|
}else if(item.status == 1){
|
||||||
|
return '<span style="color:green;">已处理</span>';
|
||||||
|
}else{
|
||||||
|
return '<span style="color:gray;">已关闭</span>';
|
||||||
|
}
|
||||||
|
}},
|
||||||
|
|
||||||
|
{fixed: 'right', title:'操作', toolbar: '#toolbar', width:200}
|
||||||
|
]],
|
||||||
|
page: true
|
||||||
|
})
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
{/block}
|
50
plugs/think-plugs-ticket/src/view/ticket/index_search.html
Normal file
50
plugs/think-plugs-ticket/src/view/ticket/index_search.html
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
<fieldset>
|
||||||
|
<legend>条件搜索</legend>
|
||||||
|
<form class="layui-form layui-form-pane form-search" action="{:request()->url()}" onsubmit="return false" method="get" autocomplete="off">
|
||||||
|
<div class="layui-form-item layui-inline">
|
||||||
|
<label class="layui-form-label">关键字</label>
|
||||||
|
<div class="layui-input-inline">
|
||||||
|
<input name="keyword" value="{:input('get.keyword')}" placeholder="标题、内容、地址、当事人、电话" class="layui-input">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="layui-form-item layui-inline">
|
||||||
|
<label class="layui-form-label">工单类型</label>
|
||||||
|
<div class="layui-input-inline">
|
||||||
|
<select class="layui-select" name="type_id">
|
||||||
|
<option value=''>-- 全部 --</option>
|
||||||
|
{foreach $type_list as $type}
|
||||||
|
<option value='{$type.id}'>{$type.name}</option>
|
||||||
|
{/foreach}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="layui-form-item layui-inline">
|
||||||
|
<label class="layui-form-label">工单状态</label>
|
||||||
|
<div class="layui-input-inline">
|
||||||
|
<select class="layui-select" name="status">
|
||||||
|
<option value=''>-- 全部 --</option>
|
||||||
|
<option value='0'>正在处理</option>
|
||||||
|
<option value='1'>已处理</option>
|
||||||
|
<option value='-1'>已取消</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="layui-form-item layui-inline">
|
||||||
|
<label class="layui-form-label">创建时间</label>
|
||||||
|
<div class="layui-input-inline">
|
||||||
|
<input data-date-range name="create_at" value="{:input('get.create_at')}" placeholder="请选择创建时间" class="layui-input">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="layui-form-item layui-inline">
|
||||||
|
<label class="layui-form-label">最后操作时间</label>
|
||||||
|
<div class="layui-input-inline">
|
||||||
|
<input data-date-range name="last_activity_at" value="{:input('get.last_activity_at')}" placeholder="请选择最后操作时间" class="layui-input">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="layui-form-item layui-inline">
|
||||||
|
<button class="layui-btn layui-btn-primary" lay-submit lay-filter="searchData"><i class="layui-icon"></i> 搜 索</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
</fieldset>
|
43
plugs/think-plugs-ticket/src/view/ticket/reply.html
Normal file
43
plugs/think-plugs-ticket/src/view/ticket/reply.html
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
<form class="layui-form layui-card margin-top-10 padding-10" action="{:sysuri()}" data-auto="true" method="post" autocomplete="off" data-table-id="ticketTable">
|
||||||
|
<input class="layui-input layui-hide" type='hidden' value="{:input('get.id')}" name='id'>
|
||||||
|
<input class="layui-input layui-hide" type='hidden' value="{:input('get.ticket_id')}" name='ticket_id'>
|
||||||
|
<input class="layui-input layui-hide" type='hidden' value='{:systoken("reply")}' name='_token_'>
|
||||||
|
<div class="layui-form-item">
|
||||||
|
<label class="layui-form-label">回复内容</label>
|
||||||
|
<div class="layui-input-block">
|
||||||
|
<textarea data-textarea class="layui-textarea" name='content' required></textarea>
|
||||||
|
<div class="layui-word-aux">此回复对外可见,请认真回复。</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="layui-form-item">
|
||||||
|
<label class="layui-form-label">回复图片</label>
|
||||||
|
<div class="layui-input-block">
|
||||||
|
<input class="layui-hide" name='imgs'>
|
||||||
|
<div class="layui-word-aux">此图片对外可见,请认真回复。</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<hr>
|
||||||
|
<div class="layui-form-item">
|
||||||
|
<label class="layui-form-label">内部回复内容</label>
|
||||||
|
<div class="layui-input-block">
|
||||||
|
<textarea data-textarea class="layui-textarea" name='inner_content'></textarea>
|
||||||
|
<div class="layui-word-aux">此回复仅系统内部可见。</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="layui-form-item">
|
||||||
|
<label class="layui-form-label">内部回复图片</label>
|
||||||
|
<div class="layui-input-block">
|
||||||
|
<input class="layui-hide" name='inner_imgs'>
|
||||||
|
<div class="layui-word-aux">此图片仅系统内部可见。</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="layui-form-item text-center">
|
||||||
|
<button class="layui-btn layui-btn-normal" type='submit'>保存数据</button>
|
||||||
|
<button class="layui-btn layui-btn-danger" type='button' data-confirm="确定要取消编辑吗?" data-close>取消编辑</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
<script>
|
||||||
|
$('[name="imgs"]').uploadMultipleImage()
|
||||||
|
$('[name="inner_imgs"]').uploadMultipleImage()
|
||||||
|
</script>
|
||||||
|
{include file="ticket/detail"}
|
63
plugs/think-plugs-ticket/src/view/type/form.html
Normal file
63
plugs/think-plugs-ticket/src/view/type/form.html
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
<form class="layui-form layui-card" action="{:request()->url()}" data-auto="true" method="post" autocomplete="off" data-table-id="typeTable">
|
||||||
|
<div class="layui-card-body">
|
||||||
|
<div class="layui-row layui-col-space15">
|
||||||
|
<div class="layui-form-item">
|
||||||
|
<label class="layui-form-label">分类名称</label>
|
||||||
|
<div class="layui-input-block">
|
||||||
|
<input type="text" name="name" value='{$vo.name|default=""}' required placeholder="请输入分类名称" class="layui-input">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="hr-line-dashed"></div>
|
||||||
|
{notempty name='vo.id'}<input type='hidden' value='{$vo.id}' name='id'>{/notempty}
|
||||||
|
<div class="layui-form-item text-center">
|
||||||
|
<button class="layui-btn layui-btn-normal" type='submit'>保存数据</button>
|
||||||
|
<button class="layui-btn layui-btn-danger" type='button' data-confirm="确定要取消编辑吗?" data-close>取消编辑</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.layui-tab-item{ min-height: 400px;}
|
||||||
|
.input-group-addon {
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
color: #eee;
|
||||||
|
width: 25px;
|
||||||
|
padding: 7px;
|
||||||
|
position: absolute;
|
||||||
|
margin-top: -1px;
|
||||||
|
text-align: center;
|
||||||
|
background: #393D49;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<script>
|
||||||
|
layui.form.render();
|
||||||
|
layui.use(['layer', 'jquery', 'form','element'], function () {
|
||||||
|
var layer = layui.layer,
|
||||||
|
$ = layui.jquery,
|
||||||
|
form = layui.form,
|
||||||
|
element = layui.element;
|
||||||
|
|
||||||
|
//监听是否为跳转链接的选择变化
|
||||||
|
form.on("radio(islink_filter)", function (data) {
|
||||||
|
if(parseInt(data.value)){
|
||||||
|
$('#category_link_url').show();
|
||||||
|
}else{
|
||||||
|
$('#category_link_url').hide();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
//监听指定开关
|
||||||
|
form.on('switch(urlpath_filter)', function(data){
|
||||||
|
if(this.checked){
|
||||||
|
$(this).parent('.layui-input-block').prev().removeClass('label-required-next');
|
||||||
|
$('input[name="url_path"]').next('span').hide();
|
||||||
|
$('input[name="url_path"]').removeAttr('required').attr('disabled',true);
|
||||||
|
}else{
|
||||||
|
$(this).parent('.layui-input-block').prev().addClass('label-required-next');
|
||||||
|
$('input[name="url_path"]').next('span').show();
|
||||||
|
$('input[name="url_path"]').removeAttr('disabled').attr('required',true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
83
plugs/think-plugs-ticket/src/view/type/index.html
Normal file
83
plugs/think-plugs-ticket/src/view/type/index.html
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
{extend name="table"}
|
||||||
|
|
||||||
|
{block name="button"}
|
||||||
|
<!--{if auth("add")}-->
|
||||||
|
<button data-modal='{:url("add")}' data-title="添加栏目" class='layui-btn layui-btn-sm layui-btn-primary'>添加类型</button>
|
||||||
|
<!--{/if}-->
|
||||||
|
{/block}
|
||||||
|
|
||||||
|
{block name="content"}
|
||||||
|
<div class="layui-tab layui-tab-card think-bg-white">
|
||||||
|
<div class="layui-tab-content think-box-shadow">
|
||||||
|
{include file='type/index_search'}
|
||||||
|
<table class="layui-table margin-top-10" data-url="{$request->url()}" data-target-search="form.form-search" lay-skin="line" id="typeTable"></table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script type="text/html" id="toolbar">
|
||||||
|
|
||||||
|
<!--{if auth("edit")}-->
|
||||||
|
<a data-modal="{:url('edit')}?id={{ d.id }}" class="layui-btn layui-btn-xs layui-btn-normal" title="修改">修改</a>
|
||||||
|
<!--{/if}-->
|
||||||
|
|
||||||
|
<!--{if auth("status")}-->
|
||||||
|
{{# if(d.status == 0){ }}
|
||||||
|
<a class="layui-btn layui-btn-xs layui-btn-normal" data-title="显示分类" data-modal='{:url("status")}?id={{ d.id }}&status=1'>显 示</a>
|
||||||
|
{{# } else { }}
|
||||||
|
<a class="layui-btn layui-btn-xs layui-btn-primary" data-title="隐藏分类" data-modal='{:url("status")}?id={{ d.id }}&status=0'>隐 藏</a>
|
||||||
|
{{# } }}
|
||||||
|
<!--{/if}-->
|
||||||
|
|
||||||
|
<!--{if auth("remove")}-->
|
||||||
|
<a data-confirm="确定要永久删除此分类吗?" data-action="{:url('remove')}" data-value="id#{{ d.id }}" data-csrf="{:systoken('remove')}" class="layui-btn layui-btn-xs layui-btn-danger" title="删除">删除</a>
|
||||||
|
<!--{/if}-->
|
||||||
|
</script>
|
||||||
|
{/block}
|
||||||
|
|
||||||
|
{block name='style'}
|
||||||
|
<style>
|
||||||
|
</style>
|
||||||
|
{/block}
|
||||||
|
|
||||||
|
{block name='script'}
|
||||||
|
<script>
|
||||||
|
$(function () {
|
||||||
|
$('#typeTable').layTable({
|
||||||
|
height: 'full-240',
|
||||||
|
toolbar: true,
|
||||||
|
sort: {field: 'sort', type: 'asc'},
|
||||||
|
cols: [[
|
||||||
|
{type: 'numbers'},
|
||||||
|
{field: 'sort', title: '排序', width: 80, sort: true, edit: 'text'},
|
||||||
|
{field: 'name', title: '工单类型名称', minWidth: 165},
|
||||||
|
{field: 'status', title: '状态', width: 60,templet:function(item){
|
||||||
|
if(item.status == 0){
|
||||||
|
return '<span style="color:red;">隐藏</span>';
|
||||||
|
}else if(item.status == 1){
|
||||||
|
return '<span style="color:green;">显示</span>';
|
||||||
|
}
|
||||||
|
}},
|
||||||
|
{field: 'tickets_count', title: '该类型工单数', width: 120},
|
||||||
|
{field: 'create_at', title: '创建时间', width: 150},
|
||||||
|
{align: 'center', toolbar: '#toolbar', title: '操作', width: 240}
|
||||||
|
]]
|
||||||
|
})
|
||||||
|
layui.use(['table'], function(){
|
||||||
|
var table = layui.table,
|
||||||
|
layer = layui.layer;
|
||||||
|
table.on('edit(typeTable)', function(obj) {
|
||||||
|
if (obj.field == 'sort') {
|
||||||
|
if (obj.value == '') {
|
||||||
|
obj.value = obj.oldValue
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
$.form.load("{:url('sort')}", {sort: obj.value, id: obj.data.id}, 'post', function (ret) {
|
||||||
|
$('#typeTable').trigger('reload');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
{/block}
|
16
plugs/think-plugs-ticket/src/view/type/index_search.html
Normal file
16
plugs/think-plugs-ticket/src/view/type/index_search.html
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
<fieldset>
|
||||||
|
<legend>条件搜索</legend>
|
||||||
|
<form class="layui-form layui-form-pane form-search" action="{:request()->url()}" onsubmit="return false" method="get" autocomplete="off">
|
||||||
|
<div class="layui-form-item layui-inline">
|
||||||
|
<label class="layui-form-label">分类名称</label>
|
||||||
|
<div class="layui-input-inline">
|
||||||
|
<input name="name" value="{:input('get.name')}" placeholder="请输入分类名称" class="layui-input">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="layui-form-item layui-inline">
|
||||||
|
<button class="layui-btn layui-btn-primary" lay-submit lay-filter="searchData"><i class="layui-icon"></i> 搜 索</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
</fieldset>
|
23
public/index.php
Normal file
23
public/index.php
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | Static Plugin for ThinkAdmin
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | 版权所有 2014~2024 ThinkAdmin [ thinkadmin.top ]
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | 官方网站: https://thinkadmin.top
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | 开源协议 ( https://mit-license.org )
|
||||||
|
// | 免责声明 ( https://thinkadmin.top/disclaimer )
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | gitee 代码仓库:https://gitee.com/zoujingli/think-plugs-static
|
||||||
|
// | github 代码仓库:https://github.com/zoujingli/think-plugs-static
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
|
||||||
|
use think\admin\service\RuntimeService;
|
||||||
|
|
||||||
|
// 加载基础文件
|
||||||
|
require __DIR__ . '/../vendor/autoload.php';
|
||||||
|
|
||||||
|
// WEB应用初始化
|
||||||
|
RuntimeService::doWebsiteInit();
|
4
public/robots.txt
Normal file
4
public/robots.txt
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
User-agent: *
|
||||||
|
Disallow: /data
|
||||||
|
Disallow: /admin
|
||||||
|
Disallow: /wechat
|
22
public/router.php
Normal file
22
public/router.php
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | Static Plugin for ThinkAdmin
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | 版权所有 2014~2024 ThinkAdmin [ thinkadmin.top ]
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | 官方网站: https://thinkadmin.top
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | 开源协议 ( https://mit-license.org )
|
||||||
|
// | 免责声明 ( https://thinkadmin.top/disclaimer )
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | gitee 代码仓库:https://gitee.com/zoujingli/think-plugs-static
|
||||||
|
// | github 代码仓库:https://github.com/zoujingli/think-plugs-static
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
|
||||||
|
if (is_file($_SERVER['DOCUMENT_ROOT'] . $_SERVER['SCRIPT_NAME'])) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
$_SERVER['SCRIPT_FILENAME'] = __DIR__ . '/index.php';
|
||||||
|
require $_SERVER['SCRIPT_FILENAME'];
|
||||||
|
}
|
48
public/static/extra/script.js
Normal file
48
public/static/extra/script.js
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | Static Plugin for ThinkAdmin
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | 官方网站: https://thinkadmin.top
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | 版权所有 2014~2024 ThinkAdmin [ thinkadmin.top ]
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | 开源协议 ( https://mit-license.org )
|
||||||
|
// | 免责声明 ( https://thinkadmin.top/disclaimer )
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | gitee 代码仓库:https://gitee.com/zoujingli/think-plugs-static
|
||||||
|
// | github 代码仓库:https://github.com/zoujingli/think-plugs-static
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | 自定义后台扩展脚本,需要在加载 admin.js 后载入
|
||||||
|
// | 使用 composer require zoujingli/think-plugs-static 时不会更新此文件
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
|
||||||
|
$(function () {
|
||||||
|
window.$body = $('body');
|
||||||
|
|
||||||
|
/*! 初始化异步加载的内容扩展动作 */
|
||||||
|
// $body.on('reInit', function (evt, $dom) {
|
||||||
|
// console.log('Event.reInit', $dom);
|
||||||
|
// });
|
||||||
|
|
||||||
|
/*! 追加 require 配置参数
|
||||||
|
/*! 加载的文件不能与主配置重复 */
|
||||||
|
// require.config({
|
||||||
|
// paths: {
|
||||||
|
// 'vue': ['plugs/vue/vue.min'],
|
||||||
|
// },
|
||||||
|
// shim: {
|
||||||
|
// 'vue': ['json']
|
||||||
|
// },
|
||||||
|
// });
|
||||||
|
// // 基于 Require 加载测试
|
||||||
|
// require(['vue', 'md5'], function (vue, md5) {
|
||||||
|
// console.log(vue)
|
||||||
|
// console.log(md5.hash('content'))
|
||||||
|
// });
|
||||||
|
|
||||||
|
/*! 其他 javascript 脚本代码 */
|
||||||
|
|
||||||
|
// 显示表格图片
|
||||||
|
window.showTableImage = function (image, circle, size, title) {
|
||||||
|
return $.layTable.showImage(image, circle, size, title);
|
||||||
|
};
|
||||||
|
});
|
16
public/static/extra/style.css
Normal file
16
public/static/extra/style.css
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
/* +----------------------------------------------------------------------
|
||||||
|
/* | Static Plugin for ThinkAdmin
|
||||||
|
/* +----------------------------------------------------------------------
|
||||||
|
/* | 官方网站: https://thinkadmin.top
|
||||||
|
/* +----------------------------------------------------------------------
|
||||||
|
/* | 版权所有 2014~2024 ThinkAdmin [ thinkadmin.top ]
|
||||||
|
/* +----------------------------------------------------------------------
|
||||||
|
/* | 开源协议 ( https://mit-license.org )
|
||||||
|
/* | 免责声明 ( https://thinkadmin.top/disclaimer )
|
||||||
|
/* +----------------------------------------------------------------------
|
||||||
|
/* | gitee 代码仓库:https://gitee.com/zoujingli/think-plugs-static
|
||||||
|
/* | github 代码仓库:https://github.com/zoujingli/think-plugs-static
|
||||||
|
/* +----------------------------------------------------------------------
|
||||||
|
/* | 自定义后台扩展样式,需要在加载 console.css 后载入
|
||||||
|
/* | 使用 composer require zoujingli/think-plugs-static 时不会更新此文件
|
||||||
|
/* +---------------------------------------------------------------------- */
|
224
readme.md
Normal file
224
readme.md
Normal file
@ -0,0 +1,224 @@
|
|||||||
|
## 大道至简 · 原生框架
|
||||||
|
|
||||||
|
[](https://packagist.org/packages/zoujingli/thinkadmin)
|
||||||
|
[](https://packagist.org/packages/zoujingli/thinkadmin)
|
||||||
|
[](https://packagist.org/packages/zoujingli/thinkadmin)
|
||||||
|
[](https://packagist.org/packages/zoujingli/thinkadmin)
|
||||||
|
[](https://packagist.org/packages/zoujingli/thinkadmin)
|
||||||
|
|
||||||
|
### 项目介绍
|
||||||
|
|
||||||
|
**ThinkAdmin** 是一款遵循 **MIT** 协议开源的快速开发框架,基于最新版本 **ThinkPHP6** 的极简后台管理系统,在使用 **ThinkAdmin** 前请认真阅读[《免责声明》](https://thinkadmin.top/disclaimer)并同意该声明。
|
||||||
|
|
||||||
|
我们致力于快速开发的底层框架,让项目开发变得更容易。框架提供完善的基础组件以及对应的 **API** 支持,基于此框架可以快速开发各种 **WEB** 应用。任何一个系统都不能完全满足所有的业务场景,**ThinkAdmin** 免费提供基础底层的功能,这里包括系统权限管理,系统存储配置,微信授权管理,以及其他常用功能集成等…… 因此 **ThinkAdmin** 也被大家定性为外包二开基线系统。目前已经有许多公司及个人在使用 **ThinkAdmin**,通过数据聚合统计已有 **5** 万多在线运行的项目。
|
||||||
|
|
||||||
|
**ThinkAdmin v6** 是基于 **v1**-**v5** 大版本的积累,经历了几次大的调整,结合 **ThinkPHP6** 的思维重新构建,减少大量原非必需的组件,自建存储层、服务层及队列任务机制,另外还增加了许多友好指令!当前 **v6** 版本已经通过了数个系统实践与测试,过程中不停调整与优化,目前系统模块及微信模块已经趋于稳定,现将系统管理 **`app/admin`** 及微信管理 **`app/wechat`** 定为 **v6** 内核两大模块并以 **MIT** 协议发布,后续可能还有其他模块及相关辅助模块更新发布,敬请期待……
|
||||||
|
|
||||||
|
当前 **ThinkAdmin** 的最新版本为 **v6.1**,从这个版本开始正式进入插件时代,基础组件及扩展插件统一使用 **Composer**
|
||||||
|
管理。现在通过对 **Composer** 深度开发已实现了插件自动安装机制,可以大大减少项目初始化安装的成本。**ThinkAdmin** 与传统
|
||||||
|
**ThinkPHP** 多应用模式无差别,用户可以自行开发自己的模块,此次升级可完美兼容 **ThinkAdmin v6.0**
|
||||||
|
应用。我们强烈建议不要占用或修改 **`app/admin`** 和 **`app/wechat`** 两个目录里面的代码,这些未来可以通过 **Composer**
|
||||||
|
进行功能及安全升级。
|
||||||
|
|
||||||
|
系统核心组件 **ThinkLibrary** 封装了大量常用操作以及多应用组件,可快速开发各种应用程序,且不影响原 **ThinkPHP** 生态,大大简化编码成本;可自行选择集成 **WechatDeveloper** 组件 ( 支持微信公众号、微信小程序、微信企业号、微信商户支付、支付宝支付等 ) 及 **QRcode** 二维码生成工具等。里面还内置了 **ThinkPHP6** 多应用组件并且完美支持路由;文件存储支持本地服务器存储、七牛云对象存储(支持CDN加速)、又拍云USS存储(支持CDN加速)、阿里云OSS存储(支持CDN加速)、腾讯云COS存储(支持CDN加速)等存储方式;自带异步任务处理机制,可以并列多进程执行任务,任务响应延时小于 **0.5** 秒,兼容 **windows** 及 **linux**。
|
||||||
|
|
||||||
|
**温馨提示:** 如果需要直接查看源代码和数据库 **SQL** 文件,请切换到 `v6` 分支,从 `v6.1` 开始不再直接提供源代码和数据库 **SQL**
|
||||||
|
文件,其初始化及安装都由插件实现。使用 **Composer** 时建议安装新版本并使用官方源,目前国内大部分镜像经常出现`404`
|
||||||
|
导致组件下载失败或安装不完整等异常情况!
|
||||||
|
|
||||||
|
使用 **ThinkAdmin** 需要掌握 **ThinkPHP**、**jQuery**、**LayUI**、**RequireJs** 等开发技能,后台 **UI** 界面基于最新版本的 **LayUI** 前端框架以及 **RequireJs** 组件加载方式,默认加载了所有 **LayUI** 的组件,框架中可以直接使用组件(独立页面需要注意 **js** 加载顺序哦),使用 **RequireJs** 加载插件,互联网上资源非常多,可自行下载进行二次扩展。目前后台大部分页面为单页程序,页面加载速度非常快速,也因此后台不再支持选项卡模式。
|
||||||
|
|
||||||
|
### 注意事项
|
||||||
|
|
||||||
|
* **ThinkAdmin** 是基于国内最流行的 **ThinkPHP6** 框架开发,要求在不低于 **PHP 7.2.5** 的版本上运行,如果使用低版本的 **PHP** 可能会影响 **Composer** 依赖组件的安装,或将存在一定的安全隐患;
|
||||||
|
* 运行环境必需开启 **PATHINFO** 并将对应的 **rewrite** 规则配置到站点才能访问,系统已不再支持 **ThinkPHP** 的 **URL** 兼容模式运行 ( 源于如何优雅地展示 ),可以阅读 **ThinkAdmin** 的文档[安装部署](https://thinkadmin.top/guide/install.html)章节;
|
||||||
|
* 代码仓库下载的文件不包含 **Composer** 组件的 **vendor** 目录,下载后需要执行 **composer install** 安装依赖组件,同时会触发执行 **php think migrate:run** 安装数据库 **Phinx** 脚本,如需切换数据库只需要先配置再执行指令即可完成初始化安装数据;
|
||||||
|
* 为保持系统可持续在线升级,建议不要在 **app/admin**、**app/wechat** 、**public/static** 这三个目录创建或修改文件,可以自行创建其他模块再编写自己的业务代码,自定义样式及脚本可以放置在 **public/static/extra** 目录里面。
|
||||||
|
* 系统是基于严格类型 **PHP** 新特性开发,务必使用专业的 **IDE** ( 如:**PhpStorm**、**NetBeans**、**VsCode**、**Eclipse for PHP** 等 ) 进行项目开发以达到更好的体验与更高的效率!
|
||||||
|
|
||||||
|
## 插件生态
|
||||||
|
|
||||||
|
了解更多插件信息请阅读 [《ThinkAdmin 插件生态》](plugin.md)
|
||||||
|
|
||||||
|
## 系统安装
|
||||||
|
|
||||||
|
通过 Composer 工具安装系统, 创建并进入 **ThinkAdmin** 根目录,运行指令安装依赖组件。
|
||||||
|
|
||||||
|
```shell
|
||||||
|
### 创建项目( 需要在英文目录下面执行 )
|
||||||
|
composer create-project zoujingli/thinkadmin
|
||||||
|
|
||||||
|
### 进入项目根目录
|
||||||
|
cd thinkadmin
|
||||||
|
|
||||||
|
### 数据库初始化并安装
|
||||||
|
php think migrate:run
|
||||||
|
```
|
||||||
|
|
||||||
|
> **A. 测试或体验环境**
|
||||||
|
>
|
||||||
|
> 系统默认使用`Sqlite`数据库,不需要配置任何参数,特别要注意使用`Sqlite`
|
||||||
|
> 数据库时是没有密码的,容易造成数据丢失或泄露。执行上面的安装操作初始化并安装系统依赖组件,
|
||||||
|
> 并自动安装数据库并初始化数据;执行`php think run`启动系统内置的`WEB`服务,用浏览器访问
|
||||||
|
> `http://127.0.0.1:8000`进入后台登录界面后,使用系统默认的账号`admin`和密码`admin`登录管理后台;也可以使用其他`Web`
|
||||||
|
> 服务软件方案实现。
|
||||||
|
|
||||||
|
> **B. 开发或线上环境**
|
||||||
|
>
|
||||||
|
> 执行上面的安装操作初始化并安装系统依赖组件,通过数据库管理工具创建空数据库,并将数据库参数配置到`config/database.php`;
|
||||||
|
> 然后执行`php think migrate:run`完成数据库初始化安装;线上环境还需要安装`Nginx`或`Apache`等`Web`服务 (
|
||||||
|
> 推荐使用[宝塔](https://www.bt.cn/?invite_code=MV90a3Z6dmI=)集成环境 ),并按照`ThinkPHP6`系统要求配置网站参数。
|
||||||
|
|
||||||
|
## 数据管理
|
||||||
|
|
||||||
|
> **A. 注意事项**
|
||||||
|
>
|
||||||
|
> 数据库是使用 `Phinx` 工具管理的,在未配置数据库时默认使用 `Sqlite`,数据库文件位于 `database/sqlite.db`,使用 `Sqlite`
|
||||||
|
> 数据库时仅限用于体验与测试,建议不要用于生产环境,生产环境建议使用开源免费的 `MySQL` 数据库;
|
||||||
|
|
||||||
|
> **B. 数据库初始化安装**
|
||||||
|
>
|
||||||
|
> 使用 `MySql`, `SqlServer`, `Postgres` 等服务型数据库时,需要先创建空的数据库并将参数配置到 `config/database.php`
|
||||||
|
> ,然后执行 `composer update` 或 `php think migrate:run`
|
||||||
|
> 安装并初始化数据库;开发部署系统时,如果要对数据库添加数据表或修改数据表,可以直接修改数据库或创建 `Phinx`
|
||||||
|
> 脚本后执行 `php think migrate:run` 进行数据库更新升级。另外系统提供 `php think xadmin:package` 指令可以把现有 `MySQl`
|
||||||
|
> 数据库打包为 `Phinx` 脚本,迁移系统时只需要执行前面的安装步骤即可。
|
||||||
|
|
||||||
|
## 注解权限
|
||||||
|
|
||||||
|
注解权限是指通过方法注释来实现后台 RBAC 授权管理,用注解来管理功能节点。
|
||||||
|
|
||||||
|
开发人员只需要写好注释,RBAC 的节点会自动生成,只需要配置角色及用户就可以使用RBAC权限。
|
||||||
|
|
||||||
|
* 此版本的权限使用注解实现
|
||||||
|
* 注释必须标准的块注释,如下案例
|
||||||
|
* 其中`@auth true`表示访问需要权限验证
|
||||||
|
* 其中`@menu true`菜单编辑显示可选节点
|
||||||
|
* 其中`@login true`需要强制登录才可访问
|
||||||
|
|
||||||
|
```php
|
||||||
|
/**
|
||||||
|
* 操作的名称
|
||||||
|
* @auth true # 表示访问需要权限验证
|
||||||
|
* @menu true # 菜单编辑显示可选节点
|
||||||
|
* @login true # 需要强制登录才可访问
|
||||||
|
*/
|
||||||
|
public function index(){
|
||||||
|
// @todo
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 代码仓库
|
||||||
|
|
||||||
|
主仓库放置于`Gitee`, `Github`为镜像仓库。
|
||||||
|
|
||||||
|
部分代码来自互联网,若有异议可以联系作者进行删除。
|
||||||
|
|
||||||
|
* 在线体验地址:https://v6.thinkadmin.top (账号和密码都是 admin )
|
||||||
|
* Gitee仓库地址:https://gitee.com/zoujingli/ThinkAdmin/tree/v6.1
|
||||||
|
* GitHub仓库地址:https://github.com/zoujingli/ThinkAdmin/tree/v6.1
|
||||||
|
|
||||||
|
## 技术支持
|
||||||
|
|
||||||
|
开发前请认真阅读 ThinkPHP 官方文档,会对您有帮助哦!
|
||||||
|
|
||||||
|
本地开发请使用 `php think run` 运行服务,访问 `http://127.0.0.1:8000` 即可进入项目。
|
||||||
|
|
||||||
|
官方地址及开发指南:https://doc.thinkadmin.top ,如果实在无法解决问题,可以加入官方群免费交流。
|
||||||
|
|
||||||
|
**1.官方QQ交流群:** 513350915
|
||||||
|
|
||||||
|
**2.官方QQ交流群:** 866345568
|
||||||
|
|
||||||
|
**3.官方微信交流群**
|
||||||
|
|
||||||
|
<img src="https://thinkadmin.top/static/img/wx.png" width="250">
|
||||||
|
|
||||||
|
## 框架指令
|
||||||
|
|
||||||
|
* 执行 `php think run` 启用本地开发环境,访问 `http://127.0.0.1:8000`
|
||||||
|
* 执行 `php think xadmin:package` 将现有 `MySQL` 数据库打包为 `Phinx` 数据库脚本
|
||||||
|
* 执行 `php think xadmin:sysmenu` 重写系统菜单并生成新编号,同时会清理已禁用的菜单数据
|
||||||
|
* 执行 `php think xadmin:fansall` 同步微信粉丝数据,依赖于 `ThinkPlugsWechat` 应用插件
|
||||||
|
* 执行 `php think xadmin:replace` 可以批量替换数据库指定字符字段内容,通常用于文件地址替换
|
||||||
|
* 执行 `php think xadmin:database` 对数据库的所有表 `repair|optimize` 操作,优化并整理数据库碎片
|
||||||
|
* 执行 `php think xadmin:publish` 可自动安装现在模块或已安装应用插件,参数 `--migrate` 执行数据库脚本
|
||||||
|
|
||||||
|
#### 1. 守护进程管理(可自建定时任务去守护监听主进程)
|
||||||
|
|
||||||
|
* 执行 `php think xadmin:queue listen` [监听]启动异步任务监听服务
|
||||||
|
* 执行 `php think xadmin:queue start` [控制]检查创建任务监听服务(建议定时任务执行)
|
||||||
|
* 执行 `php think xadmin:queue query` [控制]查询当前任务相关的进程
|
||||||
|
* 执行 `php think xadmin:queue status` [控制]查看异步任务监听状态
|
||||||
|
* 执行 `php think xadmin:queue stop` [控制]平滑停止所有任务进程
|
||||||
|
|
||||||
|
#### 2. 本地调试管理(可自建定时任务去守护监听主进程)
|
||||||
|
|
||||||
|
* 执行 `php think xadmin:queue webstop` [调试]停止本地调试服务
|
||||||
|
* 执行 `php think xadmin:queue webstart` [调试]开启本地调试服务(建议定时任务执行)
|
||||||
|
* 执行 `php think xadmin:queue webstatus` [调试]查看本地调试状态
|
||||||
|
|
||||||
|
## 问题修复
|
||||||
|
|
||||||
|
* 增加 `CORS` 跨域规则配置,配置参数置放于 `config/app.php`,需要更新 `ThinkLibrary`。
|
||||||
|
* 修复 `layui.table` 导致基于 `ThinkPHP` 模板输出自动转义 `XSS` 过滤机制失效,需要更新 `ThinkLibrary`。
|
||||||
|
* 修复在模板中使用 `{:input(NAME)}` 取值而产生的 `XSS` 问题,模板取值更换为 `{$get.NAME|default=''}`。
|
||||||
|
* 修复 `CKEDITOR` 配置文件,禁用所有标签的 `on` 事件,阻止 `xss` 脚本注入,需要更新 `ckeditor/config.js`。
|
||||||
|
* 修复文件上传入口的后缀验证,读取真实文件后缀与配置对比,阻止不合法的文件上传并存储到本地服务器。
|
||||||
|
* 修改 `JsonRpc` 接口异常处理机制,当服务端绑定 `Exception` 时,客户端将能收到 `error` 消息及异常数据。
|
||||||
|
* 修改 `location.hash` 访问机制,禁止直接访问外部 `URL` 资源链接,防止外部 `XSS` 攻击读取本地缓存数据。
|
||||||
|
* 增加后台主题样式配置,支持全局默认+用户个性配置,需要更新 `admin`, `static`, `ThinkLibrary` 组件及模块。
|
||||||
|
* 后台行政区域数据更新,由原来的腾讯地图数据切换为百度地图最新数据,需要更新`static`,数据库版需另行更新。
|
||||||
|
* 增加`Phinx`数据库迁移脚本支持,可根据自己的需求安装对应模块,其中 `admin` 为改选模块!
|
||||||
|
* 从分离 `SystemService` 分离出 `RuntimeService` 服务,精减服务启动入口,优化性能!
|
||||||
|
* 增加插件模式,支持独立封装应用,可以通过 `composer` 管理并自动安装应用模块!
|
||||||
|
|
||||||
|
## 版权信息
|
||||||
|
|
||||||
|
[**ThinkAdmin**](https://thinkadmin.top) 遵循 [**MIT**](license) 开源协议发布,并免费提供使用。
|
||||||
|
|
||||||
|
本项目包含的第三方源码和二进制文件的版权信息另行标注。
|
||||||
|
|
||||||
|
版权所有 Copyright © 2014-2023 by ThinkAdmin (https://thinkadmin.top) All rights reserved。
|
||||||
|
|
||||||
|
更多细节参阅 [`LISENSE`](license) 文件
|
||||||
|
|
||||||
|
## 系统版本
|
||||||
|
|
||||||
|
以下系统的体验账号及密码都是 admin
|
||||||
|
|
||||||
|
### ThinkAdmin v6 基于 ThinkPHP6 开发(后台权限基于注解实现)
|
||||||
|
|
||||||
|
* 在线体验地址:https://v6.thinkadmin.top (运行中)
|
||||||
|
* Gitee 代码地址:https://gitee.com/zoujingli/ThinkAdmin/tree/v6
|
||||||
|
* Github 代码地址:https://github.com/zoujingli/ThinkAdmin/tree/v6
|
||||||
|
|
||||||
|
### ThinkAdmin v5 基于 ThinkPHP 5.1 开发(后台权限基于注解实现)
|
||||||
|
|
||||||
|
* 在线体验地址:https://v5.thinkadmin.top (已停用)
|
||||||
|
* Gitee 代码地址:https://gitee.com/zoujingli/ThinkAdmin/tree/v5
|
||||||
|
* Github 代码地址:https://github.com/zoujingli/ThinkAdmin/tree/v5
|
||||||
|
|
||||||
|
### ThinkAdmin v4 基于 ThinkPHP 5.1 开发(不建议继续使用)
|
||||||
|
|
||||||
|
* 在线体验地址:https://v4.thinkadmin.top (已停用)
|
||||||
|
* Gitee 代码地址:https://gitee.com/zoujingli/ThinkAdmin/tree/v4
|
||||||
|
* Github 代码地址:https://github.com/zoujingli/ThinkAdmin/tree/v4
|
||||||
|
|
||||||
|
### ThinkAdmin v3 基于 ThinkPHP 5.1 开发(不建议继续使用)
|
||||||
|
|
||||||
|
* 在线体验地址:https://v3.thinkadmin.top (已停用)
|
||||||
|
* Gitee 代码地址:https://gitee.com/zoujingli/ThinkAdmin/tree/v3
|
||||||
|
* Github 代码地址:https://github.com/zoujingli/ThinkAdmin/tree/v3
|
||||||
|
|
||||||
|
### ThinkAdmin v2 基于 ThinkPHP 5.0 开发(不建议继续使用)
|
||||||
|
|
||||||
|
* 在线体验地址:https://v2.thinkadmin.top (已停用)
|
||||||
|
* Gitee 代码地址:https://gitee.com/zoujingli/ThinkAdmin/tree/v2
|
||||||
|
* Github 代码地址:https://github.com/zoujingli/ThinkAdmin/tree/v2
|
||||||
|
|
||||||
|
### ThinkAdmin v1 基于 ThinkPHP 5.0 开发(不建议继续使用)
|
||||||
|
|
||||||
|
* 在线体验地址:https://v1.thinkadmin.top (已停用)
|
||||||
|
* Gitee 代码地址:https://gitee.com/zoujingli/ThinkAdmin/tree/v1
|
||||||
|
* Github 代码地址:https://github.com/zoujingli/ThinkAdmin/tree/v1
|
24
think
Normal file
24
think
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
#!/usr/bin/env php
|
||||||
|
<?php
|
||||||
|
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | Static Plugin for ThinkAdmin
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | 版权所有 2014~2024 ThinkAdmin [ thinkadmin.top ]
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | 官方网站: https://thinkadmin.top
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | 开源协议 ( https://mit-license.org )
|
||||||
|
// | 免责声明 ( https://thinkadmin.top/disclaimer )
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | gitee 代码仓库:https://gitee.com/zoujingli/think-plugs-static
|
||||||
|
// | github 代码仓库:https://github.com/zoujingli/think-plugs-static
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
|
||||||
|
use think\admin\service\RuntimeService;
|
||||||
|
|
||||||
|
// 加载基础文件
|
||||||
|
require __DIR__ . '/vendor/autoload.php';
|
||||||
|
|
||||||
|
// 命令行应用初始化
|
||||||
|
RuntimeService::doConsoleInit();
|
Reference in New Issue
Block a user