commit
3b5ce47f81
2247 changed files with 220049 additions and 0 deletions
@ -0,0 +1,8 @@ |
|||||
|
# Default ignored files |
||||
|
/shelf/ |
||||
|
/workspace.xml |
||||
|
# Editor-based HTTP Client requests |
||||
|
/httpRequests/ |
||||
|
# Datasource local storage ignored files |
||||
|
/dataSources/ |
||||
|
/dataSources.local.xml |
||||
@ -0,0 +1,5 @@ |
|||||
|
<component name="InspectionProjectProfileManager"> |
||||
|
<settings> |
||||
|
<option name="PROJECT_PROFILE" /> |
||||
|
</settings> |
||||
|
</component> |
||||
@ -0,0 +1,8 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
<project version="4"> |
||||
|
<component name="ProjectModuleManager"> |
||||
|
<modules> |
||||
|
<module fileurl="file://$PROJECT_DIR$/.idea/xunxibaoapi.yaoyz.com.iml" filepath="$PROJECT_DIR$/.idea/xunxibaoapi.yaoyz.com.iml" /> |
||||
|
</modules> |
||||
|
</component> |
||||
|
</project> |
||||
@ -0,0 +1,6 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
<project version="4"> |
||||
|
<component name="VcsDirectoryMappings"> |
||||
|
<mapping directory="$PROJECT_DIR$" vcs="Git" /> |
||||
|
</component> |
||||
|
</project> |
||||
@ -0,0 +1,8 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
<module type="WEB_MODULE" version="4"> |
||||
|
<component name="NewModuleRootManager"> |
||||
|
<content url="file://$MODULE_DIR$" /> |
||||
|
<orderEntry type="inheritedJdk" /> |
||||
|
<orderEntry type="sourceFolder" forTests="false" /> |
||||
|
</component> |
||||
|
</module> |
||||
@ -0,0 +1,21 @@ |
|||||
|
MIT License |
||||
|
|
||||
|
Copyright (c) 2019 邹景立 |
||||
|
|
||||
|
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. |
||||
@ -0,0 +1,131 @@ |
|||||
|
[](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 V5 是一个基于 ThinkPHP 5.1 开发的后台管理系统。 |
||||
|
|
||||
|
我们致力于二次开发底层框架,提供完整的组件及API,基于此框架可以快速开发应用。 |
||||
|
|
||||
|
另外项目安装及二次开发可以参考 ThinkPHP 官方文档,数据库文件摆放在项目根目录下。 |
||||
|
|
||||
|
#### 注意事项 |
||||
|
* 项目测试需要自行搭建环境导入数据库( admin_v5.sql )并修改配置( config/database.php ); |
||||
|
* 若操作提示“测试系统禁止操作”等字样,需要删除演示路由配置( route/demo.php )或清空路由文件; |
||||
|
* 当前版本使用 ThinkPHP 5.1.x,对 PHP 版本标注不低于 PHP 5.6,具体请阅读 ThinkPHP 官方文档; |
||||
|
* 环境需开启 PATHINFO,不再支持 ThinkPHP 的 URL 兼容模式运行(源于如何优雅的展示); |
||||
|
|
||||
|
## 技术支持 |
||||
|
|
||||
|
开发前请认真阅读 ThinkPHP 官方文档会对您有帮助哦! |
||||
|
|
||||
|
本地开发命令`php think run`,使用`http://127.0.0.1:8000`访问项目。 |
||||
|
|
||||
|
PHP 开发技术交流( QQ 群 513350915) |
||||
|
|
||||
|
[](http://shang.qq.com/wpa/qunwpa?idkey=ae25cf789dafbef62e50a980ffc31242f150bc61a61164458216dd98c411832a) |
||||
|
|
||||
|
|
||||
|
## 注解权限 |
||||
|
|
||||
|
注解权限是指通过方法注释来实现后台RBAC授权管理,用注解来管理功能节点。 |
||||
|
|
||||
|
开发人员只需要写好注释,RBAC的节点会自动生成,只需要配置角色及用户就可以使用RBAC权限。 |
||||
|
|
||||
|
* 此版本的权限使用注解实现 |
||||
|
* 注释必需使用标准的块注释,如下案例 |
||||
|
* 其中`@auth true`表示访问需要权限验证 |
||||
|
* 其中`@menu true`显示在菜单编辑的节点可选项 |
||||
|
```php |
||||
|
/** |
||||
|
* 操作的名称 |
||||
|
* @auth true # 表示需要验证权限 |
||||
|
* @menu true # 在菜单编辑的节点可选项 |
||||
|
*/ |
||||
|
public function index(){ |
||||
|
// @todo |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
## 代码仓库 |
||||
|
|
||||
|
ThinkAdmin 为 MIT 协议开源项目,安装使用或二次开发不受约束,欢迎 fork 项目。 |
||||
|
|
||||
|
部分代码来自互联网,若有异议可以联系作者进行删除。 |
||||
|
|
||||
|
* 在线体验地址:https://demo.thinkadmin.top (账号和密码都是 admin ) |
||||
|
* Gitee仓库地址:https://gitee.com/zoujingli/ThinkAdmin |
||||
|
* GitHub仓库地址:https://github.com/zoujingli/ThinkAdmin |
||||
|
|
||||
|
## 框架指令 |
||||
|
|
||||
|
* 执行 `build.cmd` 可更新 `Composer` 插件,会删除并替换 `vendor` 目录 |
||||
|
* 执行 `php think run` 启用本地开发环境,访问 `http://127.0.0.1:8000` |
||||
|
|
||||
|
#### 1. 线上代码更新 |
||||
|
* 执行 `php think xsync:admin` 从线上服务更新 `admin` 模块的所有文件(注意文件安全) |
||||
|
* 执行 `php think xsync:wechat` 从线上服务更新 `wechat` 模块的所有文件(注意文件安全) |
||||
|
* 执行 `php think xsync:service` 从线上服务更新 `service` 模块的所有文件(注意文件安全) |
||||
|
* 执行 `php think xsync:plugs` 从线上服务更新 `plugs` 静态插件的部分文件(注意文件安全) |
||||
|
* 执行 `php think xsync:config` 从线上服务更新 `config` 项目配置的部分文件(注意文件安全) |
||||
|
|
||||
|
#### 2. 微信资料管理 |
||||
|
* 执行 `php think xfans:all` 更新已经对接的公众号全部列表 |
||||
|
* 执行 `php think xfans:list` 更新已经对接的公众号粉丝列表 |
||||
|
* 执行 `php think xfans:tags` 更新已经对接的公众号标签列表 |
||||
|
* 执行 `php think xfans:black` 更新已经对接的公众号黑名单列表 |
||||
|
|
||||
|
#### 3. 守护进程管理 |
||||
|
* 执行 `php think xtask:reset` 重启消息任务守护进程 |
||||
|
* 执行 `php think xtask:start` 启动消息任务守护进程 |
||||
|
* 执行 `php think xtask:state` 查询消息任务守护进程 |
||||
|
* 执行 `php think xtask:stop` 暂停消息任务守护进程 |
||||
|
|
||||
|
#### 4. 其它自定工具 |
||||
|
* 执行 `php think xclean:session` 清理无效的会话SESSION文件 |
||||
|
* 执行 `php think xclean:store` 清理无效的订单信息及定时任务 |
||||
|
|
||||
|
## 特别感谢 |
||||
|
|
||||
|
|名称|版本|描述|链接| |
||||
|
|---|---|---|---| |
||||
|
|layui|2.4.5|UI组件库|https://github.com/sentsin/layui| |
||||
|
|ckeditor|4.10.1|富文件编辑器|https://github.com/ckeditor/ckeditor-dev| |
||||
|
|pluploader|3.1.2|文件上传工具|https://www.plupload.com| |
||||
|
|webuploader|0.1.5|暂时不使用了|https://github.com/fex-team/webuploader| |
||||
|
|font-awesome|4.7.0|字体图标库|https://github.com/FortAwesome/Font-Awesome| |
||||
|
|ThinkPHP|5.1.37|PHP基础框架|https://github.com/top-think/framework| |
||||
|
|ThinkLibrary|5.1.x-dev|ThinkPHP扩展组件|https://github.com/zoujingli/ThinkLibrary| |
||||
|
|WeChatDeveloper|1.2.9|微信公众号组件|https://github.com/zoujingli/WeChatDeveloper| |
||||
|
|WeOpenDeveloper|dev-master|微信开放平台组件|https://github.com/zoujingli/WeOpenDeveloper| |
||||
|
|
||||
|
## 赞助打赏 |
||||
|
 |
||||
|
|
||||
|
## 项目版本 |
||||
|
体验账号及密码都是`admin` |
||||
|
|
||||
|
#### 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 |
||||
|
|
||||
|
#### 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 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 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 v5 基于 ThinkPHP 5.1 开发(后台权限基于注解实现) |
||||
|
* 在线体验地址:https://v5.thinkadmin.top |
||||
|
* Gitee 代码地址:https://gitee.com/zoujingli/ThinkAdmin/tree/v5 |
||||
|
* Github 代码地址:https://github.com/zoujingli/ThinkAdmin/tree/v5 |
||||
@ -0,0 +1,790 @@ |
|||||
|
/* |
||||
|
Navicat Premium Data Transfer |
||||
|
|
||||
|
Source Server : local.ctolog.com |
||||
|
Source Server Type : MySQL |
||||
|
Source Server Version : 50562 |
||||
|
Source Host : 127.0.0.1:3306 |
||||
|
Source Schema : admin_v4_1 |
||||
|
|
||||
|
Target Server Type : MySQL |
||||
|
Target Server Version : 50562 |
||||
|
File Encoding : 65001 |
||||
|
|
||||
|
Date: 06/07/2019 19:07:04 |
||||
|
*/ |
||||
|
|
||||
|
SET NAMES utf8mb4; |
||||
|
SET FOREIGN_KEY_CHECKS = 0; |
||||
|
|
||||
|
-- ---------------------------- |
||||
|
-- Table structure for store_express_company |
||||
|
-- ---------------------------- |
||||
|
DROP TABLE IF EXISTS `store_express_company`; |
||||
|
CREATE TABLE `store_express_company` ( |
||||
|
`id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT, |
||||
|
`express_title` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT '' COMMENT '快递公司名称', |
||||
|
`express_code` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT '' COMMENT '快递公司代码', |
||||
|
`express_desc` varchar(512) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT '' COMMENT '快递公司描述', |
||||
|
`status` tinyint(1) UNSIGNED NULL DEFAULT 1 COMMENT '状态(0.无效,1.有效)', |
||||
|
`sort` bigint(20) UNSIGNED NULL DEFAULT 0 COMMENT '排序权重', |
||||
|
`is_deleted` tinyint(1) UNSIGNED NULL DEFAULT 0 COMMENT '删除状态(1删除,0未删除)', |
||||
|
`create_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', |
||||
|
PRIMARY KEY (`id`) USING BTREE |
||||
|
) ENGINE = InnoDB AUTO_INCREMENT = 95 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '商城-快递-公司'; |
||||
|
|
||||
|
-- ---------------------------- |
||||
|
-- Records of store_express_company |
||||
|
-- ---------------------------- |
||||
|
INSERT INTO `store_express_company` VALUES (5, 'AAE全球专递', 'aae', NULL, 0, 0, 0, '2017-09-12 11:53:40'); |
||||
|
INSERT INTO `store_express_company` VALUES (6, '安捷快递', 'anjie', '', 0, 0, 0, '2017-09-13 15:27:26'); |
||||
|
INSERT INTO `store_express_company` VALUES (7, '安信达快递', 'anxindakuaixi', NULL, 0, 0, 0, '2017-09-13 16:05:19'); |
||||
|
INSERT INTO `store_express_company` VALUES (8, '彪记快递', 'biaojikuaidi', NULL, 0, 0, 0, '2017-09-13 16:05:26'); |
||||
|
INSERT INTO `store_express_company` VALUES (9, 'BHT', 'bht', '', 0, 0, 0, '2017-09-13 16:05:37'); |
||||
|
INSERT INTO `store_express_company` VALUES (10, '百福东方国际物流', 'baifudongfang', NULL, 0, 0, 0, '2017-09-13 16:05:41'); |
||||
|
INSERT INTO `store_express_company` VALUES (11, '中国东方(COE)', 'coe', NULL, 0, 0, 0, '2017-09-13 16:05:48'); |
||||
|
INSERT INTO `store_express_company` VALUES (12, '长宇物流', 'changyuwuliu', NULL, 0, 0, 0, '2017-09-13 16:05:58'); |
||||
|
INSERT INTO `store_express_company` VALUES (13, '大田物流', 'datianwuliu', NULL, 0, 0, 0, '2017-09-13 16:06:06'); |
||||
|
INSERT INTO `store_express_company` VALUES (14, '德邦物流', 'debangwuliu', '', 0, 1, 0, '2017-09-13 16:06:14'); |
||||
|
INSERT INTO `store_express_company` VALUES (15, 'DHL', 'dhl', NULL, 0, 0, 0, '2017-09-13 16:06:24'); |
||||
|
INSERT INTO `store_express_company` VALUES (16, 'DPEX', 'dpex', NULL, 0, 0, 0, '2017-09-13 16:06:29'); |
||||
|
INSERT INTO `store_express_company` VALUES (17, 'd速快递', 'dsukuaidi', NULL, 0, 0, 0, '2017-09-13 16:06:34'); |
||||
|
INSERT INTO `store_express_company` VALUES (18, '递四方', 'disifang', NULL, 0, 0, 0, '2017-09-13 16:06:40'); |
||||
|
INSERT INTO `store_express_company` VALUES (19, 'EMS快递', 'ems', '', 1, 0, 0, '2017-09-13 16:06:47'); |
||||
|
INSERT INTO `store_express_company` VALUES (20, 'FEDEX(国外)', 'fedex', NULL, 0, 0, 0, '2017-09-13 16:06:56'); |
||||
|
INSERT INTO `store_express_company` VALUES (21, '飞康达物流', 'feikangda', NULL, 0, 0, 0, '2017-09-13 16:07:03'); |
||||
|
INSERT INTO `store_express_company` VALUES (22, '凤凰快递', 'fenghuangkuaidi', NULL, 0, 0, 0, '2017-09-13 16:07:10'); |
||||
|
INSERT INTO `store_express_company` VALUES (23, '飞快达', 'feikuaida', NULL, 0, 0, 0, '2017-09-13 16:07:16'); |
||||
|
INSERT INTO `store_express_company` VALUES (24, '国通快递', 'guotongkuaidi', NULL, 0, 0, 0, '2017-09-13 16:07:27'); |
||||
|
INSERT INTO `store_express_company` VALUES (25, '港中能达物流', 'ganzhongnengda', NULL, 0, 0, 0, '2017-09-13 16:07:33'); |
||||
|
INSERT INTO `store_express_company` VALUES (26, '广东邮政物流', 'guangdongyouzhengwuliu', NULL, 0, 0, 0, '2017-09-13 16:08:22'); |
||||
|
INSERT INTO `store_express_company` VALUES (27, '共速达', 'gongsuda', NULL, 0, 0, 0, '2017-09-13 16:08:48'); |
||||
|
INSERT INTO `store_express_company` VALUES (28, '汇通快运', 'huitongkuaidi', NULL, 0, 0, 0, '2017-09-13 16:08:56'); |
||||
|
INSERT INTO `store_express_company` VALUES (29, '恒路物流', 'hengluwuliu', NULL, 0, 0, 0, '2017-09-13 16:09:02'); |
||||
|
INSERT INTO `store_express_company` VALUES (30, '华夏龙物流', 'huaxialongwuliu', NULL, 0, 0, 0, '2017-09-13 16:09:12'); |
||||
|
INSERT INTO `store_express_company` VALUES (31, '海红', 'haihongwangsong', NULL, 0, 0, 0, '2017-09-13 16:09:20'); |
||||
|
INSERT INTO `store_express_company` VALUES (32, '海外环球', 'haiwaihuanqiu', NULL, 0, 0, 0, '2017-09-13 16:09:27'); |
||||
|
INSERT INTO `store_express_company` VALUES (33, '佳怡物流', 'jiayiwuliu', NULL, 0, 0, 0, '2017-09-13 16:09:35'); |
||||
|
INSERT INTO `store_express_company` VALUES (34, '京广速递', 'jinguangsudikuaijian', NULL, 0, 0, 0, '2017-09-13 16:09:42'); |
||||
|
INSERT INTO `store_express_company` VALUES (35, '急先达', 'jixianda', NULL, 0, 0, 0, '2017-09-13 16:09:49'); |
||||
|
INSERT INTO `store_express_company` VALUES (36, '佳吉物流', 'jjwl', NULL, 0, 0, 0, '2017-09-13 16:10:01'); |
||||
|
INSERT INTO `store_express_company` VALUES (37, '加运美物流', 'jymwl', NULL, 0, 0, 0, '2017-09-13 16:10:13'); |
||||
|
INSERT INTO `store_express_company` VALUES (38, '金大物流', 'jindawuliu', NULL, 0, 0, 0, '2017-09-13 16:10:22'); |
||||
|
INSERT INTO `store_express_company` VALUES (39, '嘉里大通', 'jialidatong', NULL, 0, 0, 0, '2017-09-13 16:10:33'); |
||||
|
INSERT INTO `store_express_company` VALUES (40, '晋越快递', 'jykd', NULL, 0, 0, 0, '2017-09-13 16:10:40'); |
||||
|
INSERT INTO `store_express_company` VALUES (41, '快捷速递', 'kuaijiesudi', NULL, 0, 0, 0, '2017-09-13 16:10:49'); |
||||
|
INSERT INTO `store_express_company` VALUES (42, '联邦快递(国内)', 'lianb', NULL, 0, 0, 0, '2017-09-13 16:10:58'); |
||||
|
INSERT INTO `store_express_company` VALUES (43, '联昊通物流', 'lianhaowuliu', NULL, 0, 0, 0, '2017-09-13 16:11:07'); |
||||
|
INSERT INTO `store_express_company` VALUES (44, '龙邦物流', 'longbanwuliu', NULL, 0, 0, 0, '2017-09-13 16:11:15'); |
||||
|
INSERT INTO `store_express_company` VALUES (45, '立即送', 'lijisong', NULL, 0, 0, 0, '2017-09-13 16:11:25'); |
||||
|
INSERT INTO `store_express_company` VALUES (46, '乐捷递', 'lejiedi', NULL, 0, 0, 0, '2017-09-13 16:11:36'); |
||||
|
INSERT INTO `store_express_company` VALUES (47, '民航快递', 'minghangkuaidi', NULL, 0, 0, 0, '2017-09-13 16:11:45'); |
||||
|
INSERT INTO `store_express_company` VALUES (48, '美国快递', 'meiguokuaidi', NULL, 0, 0, 0, '2017-09-13 16:11:53'); |
||||
|
INSERT INTO `store_express_company` VALUES (49, '门对门', 'menduimen', NULL, 0, 0, 0, '2017-09-13 16:12:01'); |
||||
|
INSERT INTO `store_express_company` VALUES (50, 'OCS', 'ocs', NULL, 0, 0, 0, '2017-09-13 16:12:10'); |
||||
|
INSERT INTO `store_express_company` VALUES (51, '配思货运', 'peisihuoyunkuaidi', NULL, 0, 0, 0, '2017-09-13 16:12:18'); |
||||
|
INSERT INTO `store_express_company` VALUES (52, '全晨快递', 'quanchenkuaidi', NULL, 0, 0, 0, '2017-09-13 16:12:26'); |
||||
|
INSERT INTO `store_express_company` VALUES (53, '全峰快递', 'quanfengkuaidi', NULL, 0, 0, 0, '2017-09-13 16:12:34'); |
||||
|
INSERT INTO `store_express_company` VALUES (54, '全际通物流', 'quanjitong', NULL, 0, 0, 0, '2017-09-13 16:12:41'); |
||||
|
INSERT INTO `store_express_company` VALUES (55, '全日通快递', 'quanritongkuaidi', NULL, 0, 0, 0, '2017-09-13 16:12:49'); |
||||
|
INSERT INTO `store_express_company` VALUES (56, '全一快递', 'quanyikuaidi', NULL, 0, 0, 0, '2017-09-13 16:12:56'); |
||||
|
INSERT INTO `store_express_company` VALUES (57, '如风达', 'rufengda', NULL, 0, 0, 0, '2017-09-13 16:13:03'); |
||||
|
INSERT INTO `store_express_company` VALUES (58, '三态速递', 'santaisudi', NULL, 0, 0, 0, '2017-09-13 16:13:15'); |
||||
|
INSERT INTO `store_express_company` VALUES (59, '盛辉物流', 'shenghuiwuliu', NULL, 0, 0, 0, '2017-09-13 16:13:22'); |
||||
|
INSERT INTO `store_express_company` VALUES (60, '申通', 'shentong', NULL, 0, 0, 0, '2017-09-13 16:13:34'); |
||||
|
INSERT INTO `store_express_company` VALUES (61, '顺丰', 'shunfeng', '', 0, 0, 0, '2017-09-13 16:13:41'); |
||||
|
INSERT INTO `store_express_company` VALUES (62, '速尔物流', 'sue', NULL, 0, 0, 0, '2017-09-13 16:13:48'); |
||||
|
INSERT INTO `store_express_company` VALUES (63, '盛丰物流', 'shengfeng', NULL, 0, 0, 0, '2017-09-13 16:13:55'); |
||||
|
INSERT INTO `store_express_company` VALUES (64, '赛澳递', 'saiaodi', NULL, 0, 0, 0, '2017-09-13 16:14:02'); |
||||
|
INSERT INTO `store_express_company` VALUES (65, '天地华宇', 'tiandihuayu', NULL, 0, 0, 0, '2017-09-13 16:14:11'); |
||||
|
INSERT INTO `store_express_company` VALUES (66, '天天快递', 'tiantian', NULL, 0, 0, 0, '2017-09-13 16:14:19'); |
||||
|
INSERT INTO `store_express_company` VALUES (67, 'TNT', 'tnt', NULL, 0, 0, 0, '2017-09-13 16:14:26'); |
||||
|
INSERT INTO `store_express_company` VALUES (68, 'UPS', 'ups', NULL, 0, 0, 0, '2017-09-13 16:14:29'); |
||||
|
INSERT INTO `store_express_company` VALUES (69, '万家物流', 'wanjiawuliu', NULL, 0, 0, 0, '2017-09-13 16:14:37'); |
||||
|
INSERT INTO `store_express_company` VALUES (70, '文捷航空速递', 'wenjiesudi', NULL, 0, 0, 0, '2017-09-13 16:14:46'); |
||||
|
INSERT INTO `store_express_company` VALUES (71, '伍圆', 'wuyuan', NULL, 0, 0, 0, '2017-09-13 16:14:52'); |
||||
|
INSERT INTO `store_express_company` VALUES (72, '万象物流', 'wxwl', NULL, 0, 0, 0, '2017-09-13 16:15:00'); |
||||
|
INSERT INTO `store_express_company` VALUES (73, '新邦物流', 'xinbangwuliu', NULL, 0, 0, 0, '2017-09-13 16:15:06'); |
||||
|
INSERT INTO `store_express_company` VALUES (74, '信丰物流', 'xinfengwuliu', NULL, 0, 0, 0, '2017-09-13 16:15:15'); |
||||
|
INSERT INTO `store_express_company` VALUES (75, '亚风速递', 'yafengsudi', NULL, 0, 0, 0, '2017-09-13 16:15:23'); |
||||
|
INSERT INTO `store_express_company` VALUES (76, '一邦速递', 'yibangwuliu', NULL, 0, 0, 0, '2017-09-13 16:15:30'); |
||||
|
INSERT INTO `store_express_company` VALUES (77, '优速物流', 'youshuwuliu', NULL, 0, 0, 0, '2017-09-13 16:15:36'); |
||||
|
INSERT INTO `store_express_company` VALUES (78, '邮政包裹挂号信', 'youzhengguonei', NULL, 0, 3, 0, '2017-09-13 16:15:44'); |
||||
|
INSERT INTO `store_express_company` VALUES (79, '邮政国际包裹挂号信', 'youzhengguoji', NULL, 0, 2, 0, '2017-09-13 16:15:51'); |
||||
|
INSERT INTO `store_express_company` VALUES (80, '远成物流', 'yuanchengwuliu', NULL, 0, 0, 0, '2017-09-13 16:15:57'); |
||||
|
INSERT INTO `store_express_company` VALUES (81, '圆通速递', 'yuantong', '', 1, 1, 0, '2017-09-13 16:16:03'); |
||||
|
INSERT INTO `store_express_company` VALUES (82, '源伟丰快递', 'yuanweifeng', NULL, 0, 0, 0, '2017-09-13 16:16:10'); |
||||
|
INSERT INTO `store_express_company` VALUES (83, '元智捷诚快递', 'yuanzhijiecheng', NULL, 0, 0, 0, '2017-09-13 16:16:17'); |
||||
|
INSERT INTO `store_express_company` VALUES (84, '韵达快运', 'yunda', NULL, 0, 0, 0, '2017-09-13 16:16:24'); |
||||
|
INSERT INTO `store_express_company` VALUES (85, '运通快递', 'yuntongkuaidi', NULL, 0, 0, 0, '2017-09-13 16:16:33'); |
||||
|
INSERT INTO `store_express_company` VALUES (86, '越丰物流', 'yuefengwuliu', NULL, 0, 0, 0, '2017-09-13 16:16:40'); |
||||
|
INSERT INTO `store_express_company` VALUES (87, '源安达', 'yad', NULL, 0, 0, 0, '2017-09-13 16:16:47'); |
||||
|
INSERT INTO `store_express_company` VALUES (88, '银捷速递', 'yinjiesudi', NULL, 0, 0, 0, '2017-09-13 16:16:56'); |
||||
|
INSERT INTO `store_express_company` VALUES (89, '宅急送', 'zhaijisong', NULL, 0, 0, 0, '2017-09-13 16:17:03'); |
||||
|
INSERT INTO `store_express_company` VALUES (90, '中铁快运', 'zhongtiekuaiyun', NULL, 0, 0, 0, '2017-09-13 16:17:10'); |
||||
|
INSERT INTO `store_express_company` VALUES (91, '中通速递', 'zhongtong', '', 0, 0, 0, '2017-09-13 16:17:16'); |
||||
|
INSERT INTO `store_express_company` VALUES (92, '中邮物流', 'zhongyouwuliu', NULL, 0, 0, 0, '2017-09-13 16:17:27'); |
||||
|
INSERT INTO `store_express_company` VALUES (93, '忠信达', 'zhongxinda', NULL, 0, 0, 0, '2017-09-13 16:17:34'); |
||||
|
INSERT INTO `store_express_company` VALUES (94, '芝麻开门', 'zhimakaimen', '', 1, 0, 0, '2017-09-13 16:17:41'); |
||||
|
|
||||
|
-- ---------------------------- |
||||
|
-- Table structure for store_express_template |
||||
|
-- ---------------------------- |
||||
|
DROP TABLE IF EXISTS `store_express_template`; |
||||
|
CREATE TABLE `store_express_template` ( |
||||
|
`id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT, |
||||
|
`rule` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '省份规则内容', |
||||
|
`order_reduction_state` tinyint(1) UNSIGNED NULL DEFAULT 0 COMMENT '订单满减状态', |
||||
|
`order_reduction_price` decimal(20, 2) UNSIGNED NULL DEFAULT 0.00 COMMENT '订单满减金额', |
||||
|
`first_number` bigint(20) UNSIGNED NULL DEFAULT 0 COMMENT '首件数量', |
||||
|
`first_price` decimal(20, 2) UNSIGNED NULL DEFAULT 0.00 COMMENT '首件邮费', |
||||
|
`next_number` bigint(20) UNSIGNED NULL DEFAULT 0 COMMENT '续件数量', |
||||
|
`next_price` decimal(20, 2) UNSIGNED NULL DEFAULT 0.00 COMMENT '续件邮费', |
||||
|
`is_default` tinyint(1) UNSIGNED NULL DEFAULT 0 COMMENT '默认规则', |
||||
|
`create_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', |
||||
|
PRIMARY KEY (`id`) USING BTREE, |
||||
|
INDEX `index_store_express_template_is_default`(`is_default`) USING BTREE |
||||
|
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '商城-快递-模板'; |
||||
|
|
||||
|
-- ---------------------------- |
||||
|
-- Table structure for store_goods |
||||
|
-- ---------------------------- |
||||
|
DROP TABLE IF EXISTS `store_goods`; |
||||
|
CREATE TABLE `store_goods` ( |
||||
|
`id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT, |
||||
|
`cate_id` bigint(20) UNSIGNED NULL DEFAULT 0 COMMENT '商品分类', |
||||
|
`title` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '商品标题', |
||||
|
`logo` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '商品图标', |
||||
|
`specs` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '商品规格JSON', |
||||
|
`lists` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '商品列表JSON', |
||||
|
`image` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '商品图片', |
||||
|
`content` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '商品内容', |
||||
|
`number_sales` bigint(20) UNSIGNED NULL DEFAULT 0 COMMENT '销售数量', |
||||
|
`number_stock` bigint(20) UNSIGNED NULL DEFAULT 0 COMMENT '库库数量', |
||||
|
`price_rate` decimal(20, 4) UNSIGNED NULL DEFAULT 0.0000 COMMENT '返利比例', |
||||
|
`price_express` decimal(20, 2) UNSIGNED NULL DEFAULT 0.00 COMMENT '统一运费', |
||||
|
`status` tinyint(1) UNSIGNED NULL DEFAULT 1 COMMENT '销售状态', |
||||
|
`sort` bigint(20) UNSIGNED NULL DEFAULT 0 COMMENT '排序权重', |
||||
|
`is_deleted` tinyint(1) UNSIGNED NULL DEFAULT 0 COMMENT '删除状态', |
||||
|
`create_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', |
||||
|
PRIMARY KEY (`id`) USING BTREE, |
||||
|
INDEX `index_store_goods_status`(`status`) USING BTREE, |
||||
|
INDEX `index_store_goods_cate_id`(`cate_id`) USING BTREE, |
||||
|
INDEX `index_store_goods_is_deleted`(`is_deleted`) USING BTREE |
||||
|
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '商品-记录'; |
||||
|
|
||||
|
-- ---------------------------- |
||||
|
-- Table structure for store_goods_cate |
||||
|
-- ---------------------------- |
||||
|
DROP TABLE IF EXISTS `store_goods_cate`; |
||||
|
CREATE TABLE `store_goods_cate` ( |
||||
|
`id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT, |
||||
|
`logo` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '分类图标', |
||||
|
`title` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '分类名称', |
||||
|
`desc` varchar(1024) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '分类描述', |
||||
|
`status` tinyint(1) UNSIGNED NULL DEFAULT 1 COMMENT '销售状态', |
||||
|
`sort` bigint(20) UNSIGNED NULL DEFAULT 0 COMMENT '排序权重', |
||||
|
`is_deleted` tinyint(1) UNSIGNED NULL DEFAULT 0 COMMENT '删除状态', |
||||
|
`create_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', |
||||
|
PRIMARY KEY (`id`) USING BTREE, |
||||
|
INDEX `index_store_goods_cate_is_deleted`(`is_deleted`) USING BTREE, |
||||
|
INDEX `index_store_goods_cate_status`(`status`) USING BTREE |
||||
|
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '商品-分类'; |
||||
|
|
||||
|
-- ---------------------------- |
||||
|
-- Table structure for store_goods_list |
||||
|
-- ---------------------------- |
||||
|
DROP TABLE IF EXISTS `store_goods_list`; |
||||
|
CREATE TABLE `store_goods_list` ( |
||||
|
`id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT, |
||||
|
`sku` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT 'sku', |
||||
|
`goods_id` bigint(20) UNSIGNED NULL DEFAULT 0 COMMENT '商品ID', |
||||
|
`goods_spec` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '商品规格', |
||||
|
`price_market` decimal(20, 2) UNSIGNED NULL DEFAULT 0.00 COMMENT '商品标价', |
||||
|
`price_selling` decimal(20, 2) UNSIGNED NULL DEFAULT 0.00 COMMENT '商品售价', |
||||
|
`number_sales` bigint(20) UNSIGNED NULL DEFAULT 0 COMMENT '销售数量', |
||||
|
`number_stock` bigint(20) UNSIGNED NULL DEFAULT 0 COMMENT '商品库存', |
||||
|
`number_virtual` bigint(20) UNSIGNED NULL DEFAULT 0 COMMENT '虚拟销量', |
||||
|
`number_express` bigint(20) UNSIGNED NULL DEFAULT 1 COMMENT '快递数量', |
||||
|
`status` tinyint(1) UNSIGNED NULL DEFAULT 1 COMMENT '商品状态', |
||||
|
`create_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', |
||||
|
PRIMARY KEY (`id`) USING BTREE, |
||||
|
INDEX `index_store_goods_list_id`(`goods_id`) USING BTREE, |
||||
|
INDEX `index_store_goods_list_spec`(`goods_spec`) USING BTREE, |
||||
|
INDEX `index_store_goods_list_status`(`status`) USING BTREE, |
||||
|
INDEX `index_store_goods_list_sku`(`sku`) USING BTREE |
||||
|
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '商品-详情'; |
||||
|
|
||||
|
-- ---------------------------- |
||||
|
-- Table structure for store_goods_stock |
||||
|
-- ---------------------------- |
||||
|
DROP TABLE IF EXISTS `store_goods_stock`; |
||||
|
CREATE TABLE `store_goods_stock` ( |
||||
|
`id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT, |
||||
|
`goods_id` bigint(20) UNSIGNED NULL DEFAULT 0 COMMENT '商品ID', |
||||
|
`goods_spec` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '商品规格', |
||||
|
`number_stock` bigint(20) UNSIGNED NULL DEFAULT 0 COMMENT '商品库存', |
||||
|
`create_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', |
||||
|
PRIMARY KEY (`id`) USING BTREE, |
||||
|
INDEX `index_store_goods_stock_gid`(`goods_id`) USING BTREE, |
||||
|
INDEX `index_store_goods_stock_spec`(`goods_spec`(191)) USING BTREE |
||||
|
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '商品-入库'; |
||||
|
|
||||
|
-- ---------------------------- |
||||
|
-- Table structure for store_member |
||||
|
-- ---------------------------- |
||||
|
DROP TABLE IF EXISTS `store_member`; |
||||
|
CREATE TABLE `store_member` ( |
||||
|
`id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT, |
||||
|
`openid` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '微信OPENID', |
||||
|
`headimg` varchar(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '头像地址', |
||||
|
`nickname` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '微信昵称', |
||||
|
`phone` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '联系手机', |
||||
|
`username` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '真实姓名', |
||||
|
`vip_level` tinyint(1) UNSIGNED NULL DEFAULT 0 COMMENT '会员级别(0游客,1为临时,2为VIP1,3为VIP2)', |
||||
|
`vip_date` date NULL DEFAULT NULL COMMENT '保级日期', |
||||
|
`create_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', |
||||
|
PRIMARY KEY (`id`) USING BTREE, |
||||
|
INDEX `index_store_member_openid`(`openid`) USING BTREE, |
||||
|
INDEX `index_store_member_phone`(`phone`) USING BTREE, |
||||
|
INDEX `index_store_member_vip_level`(`vip_level`) USING BTREE |
||||
|
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '会员-记录'; |
||||
|
|
||||
|
-- ---------------------------- |
||||
|
-- Table structure for store_member_address |
||||
|
-- ---------------------------- |
||||
|
DROP TABLE IF EXISTS `store_member_address`; |
||||
|
CREATE TABLE `store_member_address` ( |
||||
|
`id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT, |
||||
|
`mid` bigint(20) UNSIGNED NULL DEFAULT 0 COMMENT '会员ID', |
||||
|
`name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '收货姓名', |
||||
|
`phone` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '收货手机', |
||||
|
`province` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '地址-省份', |
||||
|
`city` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '地址-城市', |
||||
|
`area` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '地址-区域', |
||||
|
`address` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '地址-详情', |
||||
|
`is_default` tinyint(1) UNSIGNED NULL DEFAULT 0 COMMENT '默认地址', |
||||
|
`create_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', |
||||
|
PRIMARY KEY (`id`) USING BTREE, |
||||
|
INDEX `index_store_member_address_mid`(`mid`) USING BTREE, |
||||
|
INDEX `index_store_member_address_is_default`(`is_default`) USING BTREE |
||||
|
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '会员-地址'; |
||||
|
|
||||
|
-- ---------------------------- |
||||
|
-- Table structure for store_member_sms_history |
||||
|
-- ---------------------------- |
||||
|
DROP TABLE IF EXISTS `store_member_sms_history`; |
||||
|
CREATE TABLE `store_member_sms_history` ( |
||||
|
`id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT, |
||||
|
`mid` bigint(20) UNSIGNED NULL DEFAULT 0 COMMENT '会员ID', |
||||
|
`phone` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '目标手机', |
||||
|
`content` varchar(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '短信内容', |
||||
|
`result` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '返回结果', |
||||
|
`create_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', |
||||
|
PRIMARY KEY (`id`) USING BTREE, |
||||
|
INDEX `index_store_member_sms_history_phone`(`phone`) USING BTREE, |
||||
|
INDEX `index_store_member_sms_history_mid`(`mid`) USING BTREE |
||||
|
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '会员-短信'; |
||||
|
|
||||
|
-- ---------------------------- |
||||
|
-- Table structure for store_order |
||||
|
-- ---------------------------- |
||||
|
DROP TABLE IF EXISTS `store_order`; |
||||
|
CREATE TABLE `store_order` ( |
||||
|
`id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT, |
||||
|
`mid` bigint(20) UNSIGNED NULL DEFAULT 0 COMMENT '会员ID', |
||||
|
`order_no` bigint(20) UNSIGNED NULL DEFAULT 0 COMMENT '订单单号', |
||||
|
`from_mid` bigint(20) UNSIGNED NULL DEFAULT 0 COMMENT '推荐会员ID', |
||||
|
`price_total` decimal(20, 2) UNSIGNED NULL DEFAULT 0.00 COMMENT '待付金额统计', |
||||
|
`price_goods` decimal(20, 2) UNSIGNED NULL DEFAULT 0.00 COMMENT '商品费用统计', |
||||
|
`price_express` decimal(20, 2) UNSIGNED NULL DEFAULT 0.00 COMMENT '快递费用统计', |
||||
|
`price_rate_amount` decimal(20, 2) UNSIGNED NULL DEFAULT 0.00 COMMENT '返利金额统计', |
||||
|
`pay_state` tinyint(1) UNSIGNED NULL DEFAULT 0 COMMENT '支付状态(0未支付,1已支付)', |
||||
|
`pay_type` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '支付方式', |
||||
|
`pay_price` decimal(20, 2) UNSIGNED NULL DEFAULT 0.00 COMMENT '支付金额', |
||||
|
`pay_no` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '支付单号', |
||||
|
`pay_at` datetime NULL DEFAULT NULL COMMENT '支付时间', |
||||
|
`cancel_state` tinyint(1) UNSIGNED NULL DEFAULT 0 COMMENT '取消状态', |
||||
|
`cancel_at` datetime NULL DEFAULT NULL COMMENT '取消时间', |
||||
|
`cancel_desc` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '取消描述', |
||||
|
`refund_state` tinyint(1) UNSIGNED NULL DEFAULT 0 COMMENT '退款状态(0未退款,1待退款,2已退款)', |
||||
|
`refund_at` datetime NULL DEFAULT NULL COMMENT '退款时间', |
||||
|
`refund_no` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '退款单号', |
||||
|
`refund_price` decimal(20, 2) NULL DEFAULT 0.00 COMMENT '退款金额', |
||||
|
`refund_desc` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '退款描述', |
||||
|
`express_state` tinyint(1) UNSIGNED NULL DEFAULT 0 COMMENT '发货状态(0未发货,1已发货,2已签收)', |
||||
|
`express_company_code` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '发货快递公司编码', |
||||
|
`express_company_title` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '发货快递公司名称', |
||||
|
`express_send_no` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '发货单号', |
||||
|
`express_send_at` datetime NULL DEFAULT NULL COMMENT '发货时间', |
||||
|
`express_address_id` bigint(20) UNSIGNED NULL DEFAULT 0 COMMENT '收货地址ID', |
||||
|
`express_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '收货人姓名', |
||||
|
`express_phone` varchar(11) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '收货人手机', |
||||
|
`express_province` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '收货地址省份', |
||||
|
`express_city` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '收货地址城市', |
||||
|
`express_area` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '收货地址区域', |
||||
|
`express_address` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '收货详细地址', |
||||
|
`status` tinyint(1) UNSIGNED NULL DEFAULT 1 COMMENT '订单状态(0已取消,1预订单待补全,2新订单待支付,3已支付待发货,4已发货待签收,5已完成)', |
||||
|
`is_deleted` tinyint(1) UNSIGNED NULL DEFAULT 0 COMMENT '删除状态', |
||||
|
`create_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', |
||||
|
PRIMARY KEY (`id`) USING BTREE, |
||||
|
INDEX `index_store_groups_order_mid`(`mid`) USING BTREE, |
||||
|
INDEX `index_store_groups_order_order_no`(`order_no`) USING BTREE, |
||||
|
INDEX `index_store_groups_order_pay_state`(`pay_state`) USING BTREE, |
||||
|
INDEX `index_store_groups_order_cancel_state`(`cancel_state`) USING BTREE, |
||||
|
INDEX `index_store_groups_order_refund_state`(`refund_state`) USING BTREE, |
||||
|
INDEX `index_store_groups_order_status`(`status`) USING BTREE, |
||||
|
INDEX `index_store_groups_order_pay_no`(`pay_no`) USING BTREE |
||||
|
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '订单-记录'; |
||||
|
|
||||
|
-- ---------------------------- |
||||
|
-- Table structure for store_order_list |
||||
|
-- ---------------------------- |
||||
|
DROP TABLE IF EXISTS `store_order_list`; |
||||
|
CREATE TABLE `store_order_list` ( |
||||
|
`id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT, |
||||
|
`mid` bigint(20) UNSIGNED NULL DEFAULT 0 COMMENT '会员ID', |
||||
|
`from_id` bigint(20) UNSIGNED NULL DEFAULT 0 COMMENT '推荐会员', |
||||
|
`order_no` bigint(20) UNSIGNED NULL DEFAULT 0 COMMENT '订单单号', |
||||
|
`goods_id` bigint(20) UNSIGNED NULL DEFAULT 0 COMMENT '商品标识', |
||||
|
`goods_title` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '商品标题', |
||||
|
`goods_logo` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '商品图标', |
||||
|
`goods_spec` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '商品规格', |
||||
|
`price_real` decimal(20, 2) UNSIGNED NULL DEFAULT 0.00 COMMENT '交易金额', |
||||
|
`price_selling` decimal(20, 2) UNSIGNED NULL DEFAULT 0.00 COMMENT '销售价格', |
||||
|
`price_market` decimal(20, 2) UNSIGNED NULL DEFAULT 0.00 COMMENT '市场价格', |
||||
|
`price_express` decimal(20, 2) UNSIGNED NULL DEFAULT 0.00 COMMENT '快递费用', |
||||
|
`price_rate` decimal(20, 4) UNSIGNED NULL DEFAULT 0.0000 COMMENT '分成比例', |
||||
|
`price_rate_amount` decimal(20, 2) UNSIGNED NULL DEFAULT 0.00 COMMENT '分成金额', |
||||
|
`number_goods` bigint(20) UNSIGNED NULL DEFAULT 0 COMMENT '商品数量', |
||||
|
`number_express` bigint(20) UNSIGNED NULL DEFAULT 0 COMMENT '快递数量', |
||||
|
`create_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', |
||||
|
PRIMARY KEY (`id`) USING BTREE, |
||||
|
INDEX `index_store_goods_list_id`(`goods_id`) USING BTREE, |
||||
|
INDEX `index_store_goods_list_spec`(`goods_spec`) USING BTREE |
||||
|
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '订单-详情'; |
||||
|
|
||||
|
-- ---------------------------- |
||||
|
-- Table structure for system_auth |
||||
|
-- ---------------------------- |
||||
|
DROP TABLE IF EXISTS `system_auth`; |
||||
|
CREATE TABLE `system_auth` ( |
||||
|
`id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT, |
||||
|
`title` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '权限名称', |
||||
|
`status` tinyint(1) UNSIGNED NULL DEFAULT 1 COMMENT '权限状态', |
||||
|
`sort` bigint(20) UNSIGNED NULL DEFAULT 0 COMMENT '排序权重', |
||||
|
`desc` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '备注说明', |
||||
|
`create_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', |
||||
|
PRIMARY KEY (`id`) USING BTREE, |
||||
|
INDEX `index_system_auth_status`(`status`) USING BTREE, |
||||
|
INDEX `index_system_auth_title`(`title`) USING BTREE |
||||
|
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '系统-权限'; |
||||
|
|
||||
|
-- ---------------------------- |
||||
|
-- Table structure for system_auth_node |
||||
|
-- ---------------------------- |
||||
|
DROP TABLE IF EXISTS `system_auth_node`; |
||||
|
CREATE TABLE `system_auth_node` ( |
||||
|
`id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT, |
||||
|
`auth` bigint(20) UNSIGNED NULL DEFAULT NULL COMMENT '角色', |
||||
|
`node` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '节点', |
||||
|
PRIMARY KEY (`id`) USING BTREE, |
||||
|
INDEX `index_system_auth_auth`(`auth`) USING BTREE, |
||||
|
INDEX `index_system_auth_node`(`node`(191)) USING BTREE |
||||
|
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '系统-权限-授权'; |
||||
|
|
||||
|
-- ---------------------------- |
||||
|
-- Table structure for system_config |
||||
|
-- ---------------------------- |
||||
|
DROP TABLE IF EXISTS `system_config`; |
||||
|
CREATE TABLE `system_config` ( |
||||
|
`id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT, |
||||
|
`name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '配置名', |
||||
|
`value` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '配置值', |
||||
|
PRIMARY KEY (`id`) USING BTREE, |
||||
|
INDEX `index_system_config_name`(`name`) USING BTREE |
||||
|
) ENGINE = InnoDB AUTO_INCREMENT = 74 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '系统-配置'; |
||||
|
|
||||
|
-- ---------------------------- |
||||
|
-- Records of system_config |
||||
|
-- ---------------------------- |
||||
|
INSERT INTO `system_config` VALUES (1, 'app_name', 'ThinkAdmin'); |
||||
|
INSERT INTO `system_config` VALUES (2, 'site_name', 'ThinkAdmin'); |
||||
|
INSERT INTO `system_config` VALUES (3, 'app_version', 'v5'); |
||||
|
INSERT INTO `system_config` VALUES (4, 'site_copy', '©版权所有 2014-2018 楚才科技'); |
||||
|
INSERT INTO `system_config` VALUES (5, 'site_icon', '/upload/decb0fe26fa3f486/b3f6521bf29403c8.png'); |
||||
|
INSERT INTO `system_config` VALUES (7, 'miitbeian', '粤ICP备16006642号-2'); |
||||
|
INSERT INTO `system_config` VALUES (8, 'storage_type', 'local'); |
||||
|
INSERT INTO `system_config` VALUES (9, 'storage_local_exts', 'doc,gif,icon,jpg,mp3,mp4,p12,pem,png,rar'); |
||||
|
INSERT INTO `system_config` VALUES (10, 'storage_qiniu_bucket', 'https'); |
||||
|
INSERT INTO `system_config` VALUES (11, 'storage_qiniu_domain', '用你自己的吧'); |
||||
|
INSERT INTO `system_config` VALUES (12, 'storage_qiniu_access_key', '用你自己的吧'); |
||||
|
INSERT INTO `system_config` VALUES (13, 'storage_qiniu_secret_key', '用你自己的吧'); |
||||
|
INSERT INTO `system_config` VALUES (14, 'storage_oss_bucket', 'cuci-mytest'); |
||||
|
INSERT INTO `system_config` VALUES (15, 'storage_oss_endpoint', 'oss-cn-hangzhou.aliyuncs.com'); |
||||
|
INSERT INTO `system_config` VALUES (16, 'storage_oss_domain', '用你自己的吧'); |
||||
|
INSERT INTO `system_config` VALUES (17, 'storage_oss_keyid', '用你自己的吧'); |
||||
|
INSERT INTO `system_config` VALUES (18, 'storage_oss_secret', '用你自己的吧'); |
||||
|
INSERT INTO `system_config` VALUES (36, 'storage_oss_is_https', 'http'); |
||||
|
INSERT INTO `system_config` VALUES (43, 'storage_qiniu_region', '华东'); |
||||
|
INSERT INTO `system_config` VALUES (44, 'storage_qiniu_is_https', 'https'); |
||||
|
INSERT INTO `system_config` VALUES (45, 'wechat_mch_id', '1332187001'); |
||||
|
INSERT INTO `system_config` VALUES (46, 'wechat_mch_key', 'A82DC5BD1F3359081049C568D8502BC5'); |
||||
|
INSERT INTO `system_config` VALUES (47, 'wechat_mch_ssl_type', 'p12'); |
||||
|
INSERT INTO `system_config` VALUES (48, 'wechat_mch_ssl_p12', '65b8e4f56718182d/1bc857ee646aa15d.p12'); |
||||
|
INSERT INTO `system_config` VALUES (49, 'wechat_mch_ssl_key', 'cc2e3e1345123930/c407d033294f283d.pem'); |
||||
|
INSERT INTO `system_config` VALUES (50, 'wechat_mch_ssl_cer', '966eaf89299e9c95/7014872cc109b29a.pem'); |
||||
|
INSERT INTO `system_config` VALUES (51, 'wechat_token', 'mytoken'); |
||||
|
INSERT INTO `system_config` VALUES (52, 'wechat_appid', 'wx60a43dd8161666d4'); |
||||
|
INSERT INTO `system_config` VALUES (53, 'wechat_appsecret', '9978422e0e431643d4b42868d183d60b'); |
||||
|
INSERT INTO `system_config` VALUES (54, 'wechat_encodingaeskey', ''); |
||||
|
INSERT INTO `system_config` VALUES (55, 'wechat_push_url', '消息推送地址:http://127.0.0.1:8000/wechat/api.push'); |
||||
|
INSERT INTO `system_config` VALUES (56, 'wechat_type', 'thr'); |
||||
|
INSERT INTO `system_config` VALUES (57, 'wechat_thr_appid', 'wx60a43dd8161666d4'); |
||||
|
INSERT INTO `system_config` VALUES (58, 'wechat_thr_appkey', 'd2c0139213d7a27898ca047d81a617be'); |
||||
|
INSERT INTO `system_config` VALUES (60, 'wechat_thr_appurl', '消息推送地址:http://127.0.0.1:8000/wechat/api.push'); |
||||
|
INSERT INTO `system_config` VALUES (61, 'component_appid', 'wx28b58798480874f9'); |
||||
|
INSERT INTO `system_config` VALUES (62, 'component_appsecret', '87ddce1cc24e4cd691039f926febd942'); |
||||
|
INSERT INTO `system_config` VALUES (63, 'component_token', 'P8QHTIxpBEq88IrxatqhgpBm2OAQROkI'); |
||||
|
INSERT INTO `system_config` VALUES (64, 'component_encodingaeskey', 'L5uFIa0U6KLalPyXckyqoVIJYLhsfrg8k9YzybZIHsx'); |
||||
|
INSERT INTO `system_config` VALUES (65, 'system_message_state', '0'); |
||||
|
INSERT INTO `system_config` VALUES (66, 'sms_zt_username', '可以找CUCI申请'); |
||||
|
INSERT INTO `system_config` VALUES (67, 'sms_zt_password', '可以找CUCI申请'); |
||||
|
INSERT INTO `system_config` VALUES (68, 'sms_reg_template', '您的验证码为{code},请在十分钟内完成操作!'); |
||||
|
INSERT INTO `system_config` VALUES (69, 'sms_secure', '可以找CUCI申请'); |
||||
|
INSERT INTO `system_config` VALUES (70, 'store_title', '测试商城'); |
||||
|
INSERT INTO `system_config` VALUES (71, 'store_order_wait_time', '0.50'); |
||||
|
INSERT INTO `system_config` VALUES (72, 'store_order_clear_time', '24.00'); |
||||
|
INSERT INTO `system_config` VALUES (73, 'store_order_confirm_time', '60.00'); |
||||
|
|
||||
|
-- ---------------------------- |
||||
|
-- Table structure for system_data |
||||
|
-- ---------------------------- |
||||
|
DROP TABLE IF EXISTS `system_data`; |
||||
|
CREATE TABLE `system_data` ( |
||||
|
`id` bigint(11) UNSIGNED NOT NULL AUTO_INCREMENT, |
||||
|
`name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '配置名', |
||||
|
`value` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '配置值', |
||||
|
PRIMARY KEY (`id`) USING BTREE, |
||||
|
INDEX `index_system_data_name`(`name`) USING BTREE |
||||
|
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '系统-数据'; |
||||
|
|
||||
|
-- ---------------------------- |
||||
|
-- Table structure for system_jobs |
||||
|
-- ---------------------------- |
||||
|
DROP TABLE IF EXISTS `system_jobs`; |
||||
|
CREATE TABLE `system_jobs` ( |
||||
|
`id` bigint(20) NOT NULL AUTO_INCREMENT, |
||||
|
`queue` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, |
||||
|
`payload` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, |
||||
|
`attempts` bigint(20) UNSIGNED NOT NULL DEFAULT 0, |
||||
|
`reserved` bigint(20) UNSIGNED NOT NULL DEFAULT 0, |
||||
|
`reserved_at` int(10) UNSIGNED NULL DEFAULT NULL, |
||||
|
`available_at` int(10) UNSIGNED NOT NULL, |
||||
|
`created_at` int(10) UNSIGNED NOT NULL, |
||||
|
PRIMARY KEY (`id`) USING BTREE, |
||||
|
INDEX `index_system_jobs_reserved`(`reserved`) USING BTREE, |
||||
|
INDEX `index_system_jobs_attempts`(`attempts`) USING BTREE, |
||||
|
INDEX `index_system_jobs_reserved_at`(`reserved_at`) USING BTREE, |
||||
|
INDEX `index_system_jobs_available_at`(`available_at`) USING BTREE, |
||||
|
INDEX `index_system_jobs_create_at`(`created_at`) USING BTREE, |
||||
|
INDEX `index_system_jobs_queue`(`queue`) USING BTREE |
||||
|
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '系统-任务'; |
||||
|
|
||||
|
-- ---------------------------- |
||||
|
-- Table structure for system_jobs_log |
||||
|
-- ---------------------------- |
||||
|
DROP TABLE IF EXISTS `system_jobs_log`; |
||||
|
CREATE TABLE `system_jobs_log` ( |
||||
|
`id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT, |
||||
|
`title` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '任务名称', |
||||
|
`uri` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '任务对象', |
||||
|
`later` bigint(20) UNSIGNED NULL DEFAULT 0 COMMENT '任务延时', |
||||
|
`data` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '任务数据', |
||||
|
`desc` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '任务描述', |
||||
|
`double` tinyint(1) UNSIGNED NULL DEFAULT 1 COMMENT '任务多开', |
||||
|
`status` tinyint(1) UNSIGNED NULL DEFAULT 1 COMMENT '任务状态(1新任务,2任务进行中,3任务成功,4任务失败)', |
||||
|
`status_at` datetime NULL DEFAULT NULL COMMENT '任务状态时间', |
||||
|
`status_desc` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '任务状态描述', |
||||
|
`create_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', |
||||
|
PRIMARY KEY (`id`) USING BTREE, |
||||
|
INDEX `index_system_jobs_log_status`(`status`) USING BTREE |
||||
|
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '系统-任务-日志'; |
||||
|
|
||||
|
-- ---------------------------- |
||||
|
-- Table structure for system_log |
||||
|
-- ---------------------------- |
||||
|
DROP TABLE IF EXISTS `system_log`; |
||||
|
CREATE TABLE `system_log` ( |
||||
|
`id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT, |
||||
|
`node` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '当前操作节点', |
||||
|
`geoip` varchar(15) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '操作者IP地址', |
||||
|
`action` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '操作行为名称', |
||||
|
`content` varchar(1024) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '操作内容描述', |
||||
|
`username` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '操作人用户名', |
||||
|
`create_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', |
||||
|
PRIMARY KEY (`id`) USING BTREE |
||||
|
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '系统-日志'; |
||||
|
|
||||
|
-- ---------------------------- |
||||
|
-- Table structure for system_menu |
||||
|
-- ---------------------------- |
||||
|
DROP TABLE IF EXISTS `system_menu`; |
||||
|
CREATE TABLE `system_menu` ( |
||||
|
`id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT, |
||||
|
`pid` bigint(20) UNSIGNED NULL DEFAULT 0 COMMENT '父ID', |
||||
|
`title` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '名称', |
||||
|
`node` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '节点代码', |
||||
|
`icon` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '菜单图标', |
||||
|
`url` varchar(400) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '链接', |
||||
|
`params` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '链接参数', |
||||
|
`target` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '_self' COMMENT '打开方式', |
||||
|
`sort` int(11) UNSIGNED NULL DEFAULT 0 COMMENT '菜单排序', |
||||
|
`status` tinyint(1) UNSIGNED NULL DEFAULT 1 COMMENT '状态(0:禁用,1:启用)', |
||||
|
`create_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', |
||||
|
PRIMARY KEY (`id`) USING BTREE, |
||||
|
INDEX `index_system_menu_node`(`node`(191)) USING BTREE, |
||||
|
INDEX `index_system_menu_status`(`status`) USING BTREE |
||||
|
) ENGINE = InnoDB AUTO_INCREMENT = 56 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '系统-菜单'; |
||||
|
|
||||
|
-- ---------------------------- |
||||
|
-- Records of system_menu |
||||
|
-- ---------------------------- |
||||
|
INSERT INTO `system_menu` VALUES (1, 0, '后台首页', '', '', 'admin/index/main', '', '_self', 500, 1, '2018-09-05 17:59:38'); |
||||
|
INSERT INTO `system_menu` VALUES (2, 0, '系统管理', '', '', '#', '', '_self', 100, 1, '2018-09-05 18:04:52'); |
||||
|
INSERT INTO `system_menu` VALUES (3, 4, '系统菜单管理', '', 'layui-icon layui-icon-layouts', 'admin/menu/index', '', '_self', 1, 1, '2018-09-05 18:05:26'); |
||||
|
INSERT INTO `system_menu` VALUES (4, 2, '系统配置', '', '', '#', '', '_self', 20, 1, '2018-09-05 18:07:17'); |
||||
|
INSERT INTO `system_menu` VALUES (5, 12, '系统用户管理', '', 'layui-icon layui-icon-username', 'admin/user/index', '', '_self', 1, 1, '2018-09-06 11:10:42'); |
||||
|
INSERT INTO `system_menu` VALUES (7, 12, '访问权限管理', '', 'layui-icon layui-icon-vercode', 'admin/auth/index', '', '_self', 2, 1, '2018-09-06 15:17:14'); |
||||
|
INSERT INTO `system_menu` VALUES (11, 4, '系统参数配置', '', 'layui-icon layui-icon-set', 'admin/config/info', '', '_self', 4, 1, '2018-09-06 16:43:47'); |
||||
|
INSERT INTO `system_menu` VALUES (12, 2, '权限管理', '', '', '#', '', '_self', 10, 1, '2018-09-06 18:01:31'); |
||||
|
INSERT INTO `system_menu` VALUES (13, 0, '商城管理', '', '', '#', '', '_self', 400, 1, '2018-10-12 13:56:29'); |
||||
|
INSERT INTO `system_menu` VALUES (14, 48, '商品信息管理', '', 'layui-icon layui-icon-component', 'store/goods/index', '', '_self', 3, 1, '2018-10-12 13:56:48'); |
||||
|
INSERT INTO `system_menu` VALUES (16, 0, '微信管理', '', '', '#', '', '_self', 300, 1, '2018-10-31 15:15:27'); |
||||
|
INSERT INTO `system_menu` VALUES (17, 16, '微信管理', '', '', '#', '', '_self', 20, 1, '2018-10-31 15:16:46'); |
||||
|
INSERT INTO `system_menu` VALUES (18, 17, '微信授权配置', '', 'layui-icon layui-icon-set', 'wechat/config/options', '', '_self', 2, 1, '2018-10-31 15:17:11'); |
||||
|
INSERT INTO `system_menu` VALUES (19, 17, '微信支付配置', '', 'layui-icon layui-icon-rmb', 'wechat/config/payment', '', '_self', 1, 1, '2018-10-31 18:28:09'); |
||||
|
INSERT INTO `system_menu` VALUES (20, 16, '微信定制', '', '', '#', '', '_self', 10, 1, '2018-11-13 11:46:27'); |
||||
|
INSERT INTO `system_menu` VALUES (21, 20, '图文素材管理', '', 'layui-icon layui-icon-template', 'wechat/news/index', '', '_self', 6, 1, '2018-11-13 11:46:55'); |
||||
|
INSERT INTO `system_menu` VALUES (22, 20, '粉丝信息管理', '', 'layui-icon layui-icon-user', 'wechat/fans/index', '', '_self', 5, 1, '2018-11-15 09:51:13'); |
||||
|
INSERT INTO `system_menu` VALUES (23, 20, '回复规则管理', '', 'layui-icon layui-icon-engine', 'wechat/keys/index', '', '_self', 4, 1, '2018-11-22 11:29:08'); |
||||
|
INSERT INTO `system_menu` VALUES (24, 20, '关注回复配置', '', 'layui-icon layui-icon-senior', 'wechat/keys/subscribe', '', '_self', 3, 1, '2018-11-27 11:45:28'); |
||||
|
INSERT INTO `system_menu` VALUES (25, 20, '默认回复配置', '', 'layui-icon layui-icon-survey', 'wechat/keys/defaults', '', '_self', 2, 1, '2018-11-27 11:45:58'); |
||||
|
INSERT INTO `system_menu` VALUES (26, 20, '微信菜单管理', '', 'layui-icon layui-icon-cellphone', 'wechat/menu/index', '', '_self', 1, 1, '2018-11-27 17:56:56'); |
||||
|
INSERT INTO `system_menu` VALUES (27, 4, '系统任务管理', '', 'layui-icon layui-icon-log', 'admin/queue/index', '', '_self', 3, 1, '2018-11-29 11:13:34'); |
||||
|
INSERT INTO `system_menu` VALUES (37, 0, '开放平台', '', '', '#', '', '_self', 200, 1, '2018-12-28 13:29:25'); |
||||
|
INSERT INTO `system_menu` VALUES (38, 40, '开放平台配置', '', 'layui-icon layui-icon-set', 'service/config/index', '', '_self', 0, 1, '2018-12-28 13:29:44'); |
||||
|
INSERT INTO `system_menu` VALUES (39, 40, '公众授权管理', '', 'layui-icon layui-icon-template-1', 'service/index/index', '', '_self', 0, 1, '2018-12-28 13:30:07'); |
||||
|
INSERT INTO `system_menu` VALUES (40, 37, '平台管理', '', '', '#', '', '_self', 0, 1, '2018-12-28 16:05:46'); |
||||
|
INSERT INTO `system_menu` VALUES (42, 48, '会员信息管理', '', 'layui-icon layui-icon-user', 'store/member/index', '', '_self', 1, 1, '2019-01-22 14:24:23'); |
||||
|
INSERT INTO `system_menu` VALUES (43, 48, '订单记录管理', '', 'layui-icon layui-icon-template-1', 'store/order/index', '', '_self', 2, 1, '2019-01-22 14:46:22'); |
||||
|
INSERT INTO `system_menu` VALUES (44, 48, '商品分类管理', '', 'layui-icon layui-icon-app', 'store/goods_cate/index', '', '_self', 4, 1, '2019-01-23 10:41:06'); |
||||
|
INSERT INTO `system_menu` VALUES (45, 47, '商城参数配置', '', 'layui-icon layui-icon-set', 'store/config/index', '', '_self', 5, 1, '2019-01-24 16:47:33'); |
||||
|
INSERT INTO `system_menu` VALUES (46, 47, '短信发送记录', '', 'layui-icon layui-icon-console', 'store/message/index', '', '_self', 4, 1, '2019-01-24 18:09:58'); |
||||
|
INSERT INTO `system_menu` VALUES (47, 13, '商城配置', '', '', '#', '', '_self', 20, 1, '2019-01-25 16:47:49'); |
||||
|
INSERT INTO `system_menu` VALUES (48, 13, '数据管理', '', '', '#', '', '_self', 10, 1, '2019-01-25 16:48:35'); |
||||
|
INSERT INTO `system_menu` VALUES (49, 4, '系统日志管理', '', 'layui-icon layui-icon-form', 'admin/oplog/index', '', '_self', 2, 1, '2019-02-18 12:56:56'); |
||||
|
INSERT INTO `system_menu` VALUES (50, 47, '快递公司管理', '', 'layui-icon layui-icon-form', 'store/express_company/index', '', '_self', 3, 1, '2019-04-01 17:10:59'); |
||||
|
INSERT INTO `system_menu` VALUES (52, 47, '邮费模板管理', '', 'layui-icon layui-icon-fonts-clear', 'store/express_template/index', '', '_self', 1, 1, '2019-04-23 13:17:10'); |
||||
|
INSERT INTO `system_menu` VALUES (55, 17, '微信数据统计', '', 'layui-icon layui-icon-chart-screen', 'wechat/index/index', '', '_self', 3, 1, '2019-06-15 15:03:51'); |
||||
|
|
||||
|
-- ---------------------------- |
||||
|
-- Table structure for system_user |
||||
|
-- ---------------------------- |
||||
|
DROP TABLE IF EXISTS `system_user`; |
||||
|
CREATE TABLE `system_user` ( |
||||
|
`id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT, |
||||
|
`username` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '用户账号', |
||||
|
`password` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '用户密码', |
||||
|
`qq` varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '联系QQ', |
||||
|
`mail` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '联系邮箱', |
||||
|
`phone` varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '联系手机', |
||||
|
`login_at` datetime NULL DEFAULT NULL COMMENT '登录时间', |
||||
|
`login_ip` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '登录IP', |
||||
|
`login_num` bigint(20) UNSIGNED NULL DEFAULT 0 COMMENT '登录次数', |
||||
|
`authorize` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '权限授权', |
||||
|
`desc` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '备注说明', |
||||
|
`status` tinyint(1) UNSIGNED NULL DEFAULT 1 COMMENT '状态(0:禁用,1:启用)', |
||||
|
`is_deleted` tinyint(1) UNSIGNED NULL DEFAULT 0 COMMENT '删除(1:删除,0:未删)', |
||||
|
`create_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', |
||||
|
PRIMARY KEY (`id`) USING BTREE, |
||||
|
UNIQUE INDEX `index_system_user_username`(`username`) USING BTREE, |
||||
|
INDEX `index_system_user_status`(`status`) USING BTREE, |
||||
|
INDEX `index_system_user_deleted`(`is_deleted`) USING BTREE |
||||
|
) ENGINE = InnoDB AUTO_INCREMENT = 10001 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '系统-用户'; |
||||
|
|
||||
|
-- ---------------------------- |
||||
|
-- Records of system_user |
||||
|
-- ---------------------------- |
||||
|
INSERT INTO `system_user` VALUES (10000, 'admin', '21232f297a57a5a743894a0e4a801fc3', '22222222', '', '', '2019-07-06 18:29:31', '127.0.0.1', 611, '', '', 1, 0, '2015-11-13 15:14:22'); |
||||
|
|
||||
|
-- ---------------------------- |
||||
|
-- Table structure for wechat_fans |
||||
|
-- ---------------------------- |
||||
|
DROP TABLE IF EXISTS `wechat_fans`; |
||||
|
CREATE TABLE `wechat_fans` ( |
||||
|
`id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT, |
||||
|
`appid` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '公众号APPID', |
||||
|
`unionid` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '粉丝unionid', |
||||
|
`openid` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '粉丝openid', |
||||
|
`tagid_list` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '粉丝标签id', |
||||
|
`is_black` tinyint(1) UNSIGNED NULL DEFAULT 0 COMMENT '是否为黑名单状态', |
||||
|
`subscribe` tinyint(1) UNSIGNED NULL DEFAULT 0 COMMENT '关注状态(0未关注,1已关注)', |
||||
|
`nickname` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '用户昵称', |
||||
|
`sex` tinyint(1) UNSIGNED NULL DEFAULT NULL COMMENT '用户性别(1男性,2女性,0未知)', |
||||
|
`country` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '用户所在国家', |
||||
|
`province` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '用户所在省份', |
||||
|
`city` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '用户所在城市', |
||||
|
`language` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '用户的语言(zh_CN)', |
||||
|
`headimgurl` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '用户头像', |
||||
|
`subscribe_time` bigint(20) UNSIGNED NULL DEFAULT 0 COMMENT '关注时间', |
||||
|
`subscribe_at` datetime NULL DEFAULT NULL COMMENT '关注时间', |
||||
|
`remark` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '备注', |
||||
|
`subscribe_scene` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '扫码关注场景', |
||||
|
`qr_scene` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '二维码场景值', |
||||
|
`qr_scene_str` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '二维码场景内容', |
||||
|
`create_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', |
||||
|
PRIMARY KEY (`id`) USING BTREE, |
||||
|
INDEX `index_wechat_fans_openid`(`openid`) USING BTREE, |
||||
|
INDEX `index_wechat_fans_unionid`(`unionid`) USING BTREE, |
||||
|
INDEX `index_wechat_fans_is_back`(`is_black`) USING BTREE, |
||||
|
INDEX `index_wechat_fans_subscribe`(`subscribe`) USING BTREE |
||||
|
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '微信-粉丝'; |
||||
|
|
||||
|
-- ---------------------------- |
||||
|
-- Table structure for wechat_fans_tags |
||||
|
-- ---------------------------- |
||||
|
DROP TABLE IF EXISTS `wechat_fans_tags`; |
||||
|
CREATE TABLE `wechat_fans_tags` ( |
||||
|
`id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '标签ID', |
||||
|
`appid` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '公众号APPID', |
||||
|
`name` varchar(35) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '标签名称', |
||||
|
`count` bigint(20) UNSIGNED NULL DEFAULT 0 COMMENT '总数', |
||||
|
`create_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建日期', |
||||
|
INDEX `index_wechat_fans_tags_id`(`id`) USING BTREE, |
||||
|
INDEX `index_wechat_fans_tags_appid`(`appid`) USING BTREE |
||||
|
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '微信-粉丝-标签'; |
||||
|
|
||||
|
-- ---------------------------- |
||||
|
-- Table structure for wechat_keys |
||||
|
-- ---------------------------- |
||||
|
DROP TABLE IF EXISTS `wechat_keys`; |
||||
|
CREATE TABLE `wechat_keys` ( |
||||
|
`id` bigint(20) NOT NULL AUTO_INCREMENT, |
||||
|
`appid` char(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '公众号APPID', |
||||
|
`type` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '类型(text,image,news)', |
||||
|
`keys` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '关键字', |
||||
|
`content` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '文本内容', |
||||
|
`image_url` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '图片链接', |
||||
|
`voice_url` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '语音链接', |
||||
|
`music_title` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '音乐标题', |
||||
|
`music_url` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '音乐链接', |
||||
|
`music_image` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '缩略图片', |
||||
|
`music_desc` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '音乐描述', |
||||
|
`video_title` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '视频标题', |
||||
|
`video_url` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '视频URL', |
||||
|
`video_desc` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '视频描述', |
||||
|
`news_id` bigint(20) UNSIGNED NULL DEFAULT NULL COMMENT '图文ID', |
||||
|
`sort` bigint(20) UNSIGNED NULL DEFAULT 0 COMMENT '排序字段', |
||||
|
`status` tinyint(1) UNSIGNED NULL DEFAULT 1 COMMENT '状态(0禁用,1启用)', |
||||
|
`create_by` bigint(20) UNSIGNED NULL DEFAULT 0 COMMENT '创建人', |
||||
|
`create_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '创建时间', |
||||
|
PRIMARY KEY (`id`) USING BTREE, |
||||
|
INDEX `index_wechat_keys_appid`(`appid`) USING BTREE, |
||||
|
INDEX `index_wechat_keys_type`(`type`) USING BTREE, |
||||
|
INDEX `index_wechat_keys_keys`(`keys`) USING BTREE |
||||
|
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '微信-关键字'; |
||||
|
|
||||
|
-- ---------------------------- |
||||
|
-- Table structure for wechat_media |
||||
|
-- ---------------------------- |
||||
|
DROP TABLE IF EXISTS `wechat_media`; |
||||
|
CREATE TABLE `wechat_media` ( |
||||
|
`id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT, |
||||
|
`appid` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '公众号ID', |
||||
|
`md5` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '文件md5', |
||||
|
`type` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '媒体类型', |
||||
|
`media_id` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '永久素材MediaID', |
||||
|
`local_url` varchar(300) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '本地文件链接', |
||||
|
`media_url` varchar(300) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '远程图片链接', |
||||
|
`create_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', |
||||
|
PRIMARY KEY (`id`) USING BTREE, |
||||
|
INDEX `index_wechat_media_appid`(`appid`) USING BTREE, |
||||
|
INDEX `index_wechat_media_md5`(`md5`) USING BTREE, |
||||
|
INDEX `index_wechat_media_type`(`type`) USING BTREE, |
||||
|
INDEX `index_wechat_media_media_id`(`media_id`) USING BTREE |
||||
|
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '微信-素材'; |
||||
|
|
||||
|
-- ---------------------------- |
||||
|
-- Table structure for wechat_news |
||||
|
-- ---------------------------- |
||||
|
DROP TABLE IF EXISTS `wechat_news`; |
||||
|
CREATE TABLE `wechat_news` ( |
||||
|
`id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT, |
||||
|
`media_id` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '永久素材MediaID', |
||||
|
`local_url` varchar(300) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '永久素材显示URL', |
||||
|
`article_id` varchar(60) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '关联图文ID(用英文逗号做分割)', |
||||
|
`is_deleted` tinyint(1) UNSIGNED NULL DEFAULT 0 COMMENT '是否删除', |
||||
|
`create_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', |
||||
|
`create_by` bigint(20) NULL DEFAULT NULL COMMENT '创建人', |
||||
|
PRIMARY KEY (`id`) USING BTREE, |
||||
|
INDEX `index_wechat_news_artcle_id`(`article_id`) USING BTREE, |
||||
|
INDEX `index_wechat_news_media_id`(`media_id`) USING BTREE |
||||
|
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '微信-图文'; |
||||
|
|
||||
|
-- ---------------------------- |
||||
|
-- Table structure for wechat_news_article |
||||
|
-- ---------------------------- |
||||
|
DROP TABLE IF EXISTS `wechat_news_article`; |
||||
|
CREATE TABLE `wechat_news_article` ( |
||||
|
`id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT, |
||||
|
`title` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '素材标题', |
||||
|
`local_url` varchar(300) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '永久素材显示URL', |
||||
|
`show_cover_pic` tinyint(4) UNSIGNED NULL DEFAULT 0 COMMENT '显示封面(0不显示,1显示)', |
||||
|
`author` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '文章作者', |
||||
|
`digest` varchar(300) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '摘要内容', |
||||
|
`content` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '图文内容', |
||||
|
`content_source_url` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '原文地址', |
||||
|
`read_num` bigint(20) UNSIGNED NULL DEFAULT 0 COMMENT '阅读数量', |
||||
|
`create_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', |
||||
|
PRIMARY KEY (`id`) USING BTREE |
||||
|
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '微信-图文-文章'; |
||||
|
|
||||
|
-- ---------------------------- |
||||
|
-- Table structure for wechat_service_config |
||||
|
-- ---------------------------- |
||||
|
DROP TABLE IF EXISTS `wechat_service_config`; |
||||
|
CREATE TABLE `wechat_service_config` ( |
||||
|
`id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT, |
||||
|
`authorizer_appid` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '公众号APPID', |
||||
|
`authorizer_access_token` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '公众号授权Token', |
||||
|
`authorizer_refresh_token` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '公众号刷新Token', |
||||
|
`func_info` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '公众号集权', |
||||
|
`nick_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '公众号昵称', |
||||
|
`head_img` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '公众号头像', |
||||
|
`expires_in` bigint(20) NULL DEFAULT NULL COMMENT 'Token有效时间', |
||||
|
`service_type` tinyint(2) NULL DEFAULT NULL COMMENT '微信类型(0代表订阅号,2代表服务号,3代表小程序)', |
||||
|
`service_type_info` tinyint(2) NULL DEFAULT NULL COMMENT '公众号实际类型', |
||||
|
`verify_type` tinyint(2) NULL DEFAULT NULL COMMENT '公众号认证类型(-1代表未认证, 0代表微信认证)', |
||||
|
`verify_type_info` tinyint(2) NULL DEFAULT NULL COMMENT '公众号实际认证类型', |
||||
|
`user_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '众众号原始账号', |
||||
|
`alias` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '公众号别名', |
||||
|
`qrcode_url` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '公众号二维码', |
||||
|
`business_info` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '', |
||||
|
`principal_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '公司名称', |
||||
|
`miniprograminfo` varchar(1024) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '小程序JSON', |
||||
|
`idc` tinyint(1) UNSIGNED NULL DEFAULT NULL, |
||||
|
`signature` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '小程序的描述', |
||||
|
`total` bigint(20) UNSIGNED NULL DEFAULT 0 COMMENT '统计调用次数', |
||||
|
`appkey` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '应用接口KEY', |
||||
|
`appuri` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '应用接口URI', |
||||
|
`status` tinyint(1) UNSIGNED NULL DEFAULT 1 COMMENT '状态(1正常授权,0取消授权)', |
||||
|
`is_deleted` tinyint(1) UNSIGNED NULL DEFAULT 0 COMMENT '删除状态(0未删除,1已删除)', |
||||
|
`create_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', |
||||
|
PRIMARY KEY (`id`) USING BTREE, |
||||
|
UNIQUE INDEX `index_wechat_service_config_authorizer_appid`(`authorizer_appid`) USING BTREE, |
||||
|
INDEX `index_wechat_service_config_status`(`status`) USING BTREE, |
||||
|
INDEX `index_wechat_service_config_is_deleted`(`is_deleted`) USING BTREE |
||||
|
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '微信-授权'; |
||||
|
|
||||
|
SET FOREIGN_KEY_CHECKS = 1; |
||||
@ -0,0 +1,180 @@ |
|||||
|
<?php |
||||
|
|
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | ThinkAdmin |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 版权所有 2014~2019 广州楚才信息科技有限公司 [ http://www.cuci.cc ] |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 官方网站: http://demo.thinkadmin.top |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 开源协议 ( https://mit-license.org ) |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin |
||||
|
// | github 代码仓库:https://github.com/zoujingli/ThinkAdmin |
||||
|
// +---------------------------------------------------------------------- |
||||
|
|
||||
|
namespace app\admin\controller; |
||||
|
|
||||
|
use app\admin\service\NodeService; |
||||
|
use library\Controller; |
||||
|
use think\Db; |
||||
|
|
||||
|
/** |
||||
|
* 系统权限管理 |
||||
|
* Class Auth |
||||
|
* @package app\admin\controller |
||||
|
*/ |
||||
|
class Auth extends Controller |
||||
|
{ |
||||
|
/** |
||||
|
* 默认数据模型 |
||||
|
* @var string |
||||
|
*/ |
||||
|
public $table = 'SystemAuth'; |
||||
|
|
||||
|
/** |
||||
|
* 系统权限管理 |
||||
|
* @auth true |
||||
|
* @menu true |
||||
|
* @throws \think\Exception |
||||
|
* @throws \think\db\exception\DataNotFoundException |
||||
|
* @throws \think\db\exception\ModelNotFoundException |
||||
|
* @throws \think\exception\DbException |
||||
|
* @throws \think\exception\PDOException |
||||
|
*/ |
||||
|
public function index() |
||||
|
{ |
||||
|
$this->title = '系统权限管理'; |
||||
|
$query = $this->_query($this->table)->dateBetween('create_at'); |
||||
|
$query->like('title,desc')->equal('status')->order('sort desc,id desc')->page(); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 权限配置节点 |
||||
|
* @auth true |
||||
|
* @throws \ReflectionException |
||||
|
* @throws \think\Exception |
||||
|
* @throws \think\exception\PDOException |
||||
|
*/ |
||||
|
public function apply() |
||||
|
{ |
||||
|
$this->title = '权限配置节点'; |
||||
|
$auth = $this->request->post('id', '0'); |
||||
|
switch (strtolower($this->request->post('action'))) { |
||||
|
case 'get': // 获取权限配置 |
||||
|
$checks = Db::name('SystemAuthNode')->where(['auth' => $auth])->column('node'); |
||||
|
return $this->success('获取权限节点成功!', NodeService::getAuthTree($checks)); |
||||
|
case 'save': // 保存权限配置 |
||||
|
list($post, $data) = [$this->request->post(), []]; |
||||
|
foreach (isset($post['nodes']) ? $post['nodes'] : [] as $node) { |
||||
|
$data[] = ['auth' => $auth, 'node' => $node]; |
||||
|
} |
||||
|
Db::name('SystemAuthNode')->where(['auth' => $auth])->delete(); |
||||
|
Db::name('SystemAuthNode')->insertAll($data); |
||||
|
NodeService::applyUserAuth(); |
||||
|
return $this->success('权限授权更新成功!'); |
||||
|
default: |
||||
|
return $this->_form($this->table, 'apply'); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 添加系统权限 |
||||
|
* @auth true |
||||
|
* @throws \think\Exception |
||||
|
* @throws \think\db\exception\DataNotFoundException |
||||
|
* @throws \think\db\exception\ModelNotFoundException |
||||
|
* @throws \think\exception\DbException |
||||
|
* @throws \think\exception\PDOException |
||||
|
*/ |
||||
|
public function add() |
||||
|
{ |
||||
|
$this->applyCsrfToken(); |
||||
|
$this->_form($this->table, 'form'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 编辑系统权限 |
||||
|
* @auth true |
||||
|
* @throws \think\Exception |
||||
|
* @throws \think\db\exception\DataNotFoundException |
||||
|
* @throws \think\db\exception\ModelNotFoundException |
||||
|
* @throws \think\exception\DbException |
||||
|
* @throws \think\exception\PDOException |
||||
|
*/ |
||||
|
public function edit() |
||||
|
{ |
||||
|
$this->applyCsrfToken(); |
||||
|
$this->_form($this->table, 'form'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 刷新系统权限 |
||||
|
* @auth true |
||||
|
*/ |
||||
|
public function refresh() |
||||
|
{ |
||||
|
try { |
||||
|
NodeService::applyUserAuth(true); |
||||
|
$this->success('刷新系统授权成功!'); |
||||
|
} catch (\think\exception\HttpResponseException $exception) { |
||||
|
throw $exception; |
||||
|
} catch (\Exception $e) { |
||||
|
$this->error("刷新系统授权失败<br>{$e->getMessage()}"); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 禁用系统权限 |
||||
|
* @auth true |
||||
|
* @throws \think\Exception |
||||
|
* @throws \think\exception\PDOException |
||||
|
*/ |
||||
|
public function forbid() |
||||
|
{ |
||||
|
$this->applyCsrfToken(); |
||||
|
$this->_save($this->table, ['status' => '0']); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 启用系统权限 |
||||
|
* @auth true |
||||
|
* @throws \think\Exception |
||||
|
* @throws \think\exception\PDOException |
||||
|
*/ |
||||
|
public function resume() |
||||
|
{ |
||||
|
$this->applyCsrfToken(); |
||||
|
$this->_save($this->table, ['status' => '1']); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 删除系统权限 |
||||
|
* @auth true |
||||
|
* @throws \think\Exception |
||||
|
* @throws \think\exception\PDOException |
||||
|
*/ |
||||
|
public function remove() |
||||
|
{ |
||||
|
$this->applyCsrfToken(); |
||||
|
$this->_delete($this->table); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 删除结果处理 |
||||
|
* @param boolean $result |
||||
|
* @throws \think\Exception |
||||
|
* @throws \think\exception\PDOException |
||||
|
*/ |
||||
|
protected function _remove_delete_result($result) |
||||
|
{ |
||||
|
if ($result) { |
||||
|
$map = ['auth' => $this->request->post('id')]; |
||||
|
Db::name('SystemAuthNode')->where($map)->delete(); |
||||
|
$this->success("权限删除成功!", ''); |
||||
|
} else { |
||||
|
$this->error("权限删除失败,请稍候再试!"); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,108 @@ |
|||||
|
<?php |
||||
|
|
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | ThinkAdmin |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 版权所有 2014~2019 广州楚才信息科技有限公司 [ http://www.cuci.cc ] |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 官方网站: http://demo.thinkadmin.top |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 开源协议 ( https://mit-license.org ) |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin |
||||
|
// | github 代码仓库:https://github.com/zoujingli/ThinkAdmin |
||||
|
// +---------------------------------------------------------------------- |
||||
|
|
||||
|
namespace app\admin\controller; |
||||
|
|
||||
|
use library\Controller; |
||||
|
use think\exception\HttpResponseException; |
||||
|
|
||||
|
/** |
||||
|
* 系统参数配置 |
||||
|
* Class Config |
||||
|
* @package app\admin\controller |
||||
|
*/ |
||||
|
class Config extends Controller |
||||
|
{ |
||||
|
/** |
||||
|
* 默认数据模型 |
||||
|
* @var string |
||||
|
*/ |
||||
|
protected $table = 'SystemConfig'; |
||||
|
|
||||
|
/** |
||||
|
* 阿里云OSS上传点 |
||||
|
* @var array |
||||
|
*/ |
||||
|
protected $ossPoints = [ |
||||
|
'oss-cn-hangzhou.aliyuncs.com' => '华东 1 杭州', |
||||
|
'oss-cn-shanghai.aliyuncs.com' => '华东 2 上海', |
||||
|
'oss-cn-qingdao.aliyuncs.com' => '华北 1 青岛', |
||||
|
'oss-cn-beijing.aliyuncs.com' => '华北 2 北京', |
||||
|
'oss-cn-zhangjiakou.aliyuncs.com' => '华北 3 张家口', |
||||
|
'oss-cn-huhehaote.aliyuncs.com' => '华北 5 呼和浩特', |
||||
|
'oss-cn-shenzhen.aliyuncs.com' => '华南 1 深圳', |
||||
|
'oss-cn-hongkong.aliyuncs.com' => '香港 1', |
||||
|
'oss-us-west-1.aliyuncs.com' => '美国西部 1 硅谷', |
||||
|
'oss-us-east-1.aliyuncs.com' => '美国东部 1 弗吉尼亚', |
||||
|
'oss-ap-southeast-1.aliyuncs.com' => '亚太东南 1 新加坡', |
||||
|
'oss-ap-southeast-2.aliyuncs.com' => '亚太东南 2 悉尼', |
||||
|
'oss-ap-southeast-3.aliyuncs.com' => '亚太东南 3 吉隆坡', |
||||
|
'oss-ap-southeast-5.aliyuncs.com' => '亚太东南 5 雅加达', |
||||
|
'oss-ap-northeast-1.aliyuncs.com' => '亚太东北 1 日本', |
||||
|
'oss-ap-south-1.aliyuncs.com' => '亚太南部 1 孟买', |
||||
|
'oss-eu-central-1.aliyuncs.com' => '欧洲中部 1 法兰克福', |
||||
|
'oss-eu-west-1.aliyuncs.com' => '英国 1 伦敦', |
||||
|
'oss-me-east-1.aliyuncs.com' => '中东东部 1 迪拜', |
||||
|
]; |
||||
|
|
||||
|
/** |
||||
|
* 系统参数配置 |
||||
|
* @auth true |
||||
|
* @menu true |
||||
|
*/ |
||||
|
public function info() |
||||
|
{ |
||||
|
$this->title = '系统参数配置'; |
||||
|
$this->applyCsrfToken('save'); |
||||
|
$this->fetch(); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 保存参数到服务器 |
||||
|
* @auth true |
||||
|
* @throws \think\Exception |
||||
|
* @throws \think\exception\PDOException |
||||
|
*/ |
||||
|
public function save() |
||||
|
{ |
||||
|
$this->applyCsrfToken('save'); |
||||
|
$post = $this->request->post(); |
||||
|
if (isset($post['storage_type']) && isset($post['storage_local_exts'])) { |
||||
|
$exts = array_unique(explode(',', strtolower($post['storage_local_exts']))); |
||||
|
sort($exts); |
||||
|
if (in_array('php', $exts)) $this->error('禁止上传可执行文件到本地服务器!'); |
||||
|
$post['storage_local_exts'] = join(',', $exts); |
||||
|
} |
||||
|
foreach ($post as $key => $value) sysconf($key, $value); |
||||
|
if (isset($post['storage_type']) && $post['storage_type'] === 'oss') { |
||||
|
try { |
||||
|
$local = sysconf('storage_oss_domain'); |
||||
|
$bucket = $this->request->post('storage_oss_bucket'); |
||||
|
$domain = \library\File::instance('oss')->setBucket($bucket); |
||||
|
if (empty($local) || stripos($local, '.aliyuncs.com') !== false) { |
||||
|
sysconf('storage_oss_domain', $domain); |
||||
|
} |
||||
|
$this->success('阿里云OSS存储动态配置成功!'); |
||||
|
} catch (HttpResponseException $exception) { |
||||
|
throw $exception; |
||||
|
} catch (\Exception $e) { |
||||
|
$this->error("阿里云OSS存储配置失效,{$e->getMessage()}"); |
||||
|
} |
||||
|
} else { |
||||
|
$this->success('系统参数配置成功!'); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,177 @@ |
|||||
|
<?php |
||||
|
|
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | ThinkAdmin |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 版权所有 2014~2019 广州楚才信息科技有限公司 [ http://www.cuci.cc ] |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 官方网站: http://demo.thinkadmin.top |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 开源协议 ( https://mit-license.org ) |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin |
||||
|
// | github 代码仓库:https://github.com/zoujingli/ThinkAdmin |
||||
|
// +---------------------------------------------------------------------- |
||||
|
|
||||
|
namespace app\admin\controller; |
||||
|
|
||||
|
use app\admin\service\NodeService; |
||||
|
use library\Controller; |
||||
|
use library\tools\Data; |
||||
|
use think\Console; |
||||
|
use think\Db; |
||||
|
use think\exception\HttpResponseException; |
||||
|
|
||||
|
/** |
||||
|
* 系统公共操作 |
||||
|
* Class Index |
||||
|
* @package app\admin\controller |
||||
|
*/ |
||||
|
class Index extends Controller |
||||
|
{ |
||||
|
|
||||
|
/** |
||||
|
* 显示后台首页 |
||||
|
* @throws \ReflectionException |
||||
|
* @throws \think\db\exception\DataNotFoundException |
||||
|
* @throws \think\db\exception\ModelNotFoundException |
||||
|
* @throws \think\exception\DbException |
||||
|
*/ |
||||
|
public function index() |
||||
|
{ |
||||
|
$this->title = '系统管理后台'; |
||||
|
NodeService::applyUserAuth(true); |
||||
|
$this->menus = NodeService::getMenuNodeTree(); |
||||
|
if (empty($this->menus) && !NodeService::islogin()) { |
||||
|
$this->redirect('@admin/login'); |
||||
|
} else { |
||||
|
$this->fetch(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 后台环境信息 |
||||
|
*/ |
||||
|
public function main() |
||||
|
{ |
||||
|
$this->think_ver = \think\App::VERSION; |
||||
|
$this->mysql_ver = Db::query('select version() as ver')[0]['ver']; |
||||
|
$this->fetch(); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 修改密码 |
||||
|
* @param integer $id |
||||
|
* @throws \think\Exception |
||||
|
* @throws \think\db\exception\DataNotFoundException |
||||
|
* @throws \think\db\exception\ModelNotFoundException |
||||
|
* @throws \think\exception\DbException |
||||
|
* @throws \think\exception\PDOException |
||||
|
*/ |
||||
|
public function pass($id) |
||||
|
{ |
||||
|
$this->applyCsrfToken(); |
||||
|
if (intval($id) !== intval(session('admin_user.id'))) { |
||||
|
$this->error('只能修改当前用户的密码!'); |
||||
|
} |
||||
|
if (!NodeService::islogin()) { |
||||
|
$this->error('需要登录才能操作哦!'); |
||||
|
} |
||||
|
if ($this->request->isGet()) { |
||||
|
$this->verify = true; |
||||
|
$this->_form('SystemUser', 'admin@user/pass', 'id', [], ['id' => $id]); |
||||
|
} else { |
||||
|
$data = $this->_input([ |
||||
|
'password' => $this->request->post('password'), |
||||
|
'repassword' => $this->request->post('repassword'), |
||||
|
'oldpassword' => $this->request->post('oldpassword'), |
||||
|
], [ |
||||
|
'oldpassword' => 'require', |
||||
|
'password' => 'require|min:4', |
||||
|
'repassword' => 'require|confirm:password', |
||||
|
], [ |
||||
|
'oldpassword.require' => '旧密码不能为空!', |
||||
|
'password.require' => '登录密码不能为空!', |
||||
|
'password.min' => '登录密码长度不能少于4位有效字符!', |
||||
|
'repassword.require' => '重复密码不能为空!', |
||||
|
'repassword.confirm' => '重复密码与登录密码不匹配,请重新输入!', |
||||
|
]); |
||||
|
$user = Db::name('SystemUser')->where(['id' => $id])->find(); |
||||
|
if (md5($data['oldpassword']) !== $user['password']) { |
||||
|
$this->error('旧密码验证失败,请重新输入!'); |
||||
|
} |
||||
|
$result = NodeService::checkpwd($data['password']); |
||||
|
if (empty($result['code'])) $this->error($result['msg']); |
||||
|
if (Data::save('SystemUser', ['id' => $user['id'], 'password' => md5($data['password'])])) { |
||||
|
$this->success('密码修改成功,下次请使用新密码登录!', ''); |
||||
|
} else { |
||||
|
$this->error('密码修改失败,请稍候再试!'); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 修改用户资料 |
||||
|
* @param integer $id 会员ID |
||||
|
* @throws \think\Exception |
||||
|
* @throws \think\db\exception\DataNotFoundException |
||||
|
* @throws \think\db\exception\ModelNotFoundException |
||||
|
* @throws \think\exception\DbException |
||||
|
* @throws \think\exception\PDOException |
||||
|
*/ |
||||
|
public function info($id = 0) |
||||
|
{ |
||||
|
if (!NodeService::islogin()) { |
||||
|
$this->error('需要登录才能操作哦!'); |
||||
|
} |
||||
|
$this->applyCsrfToken(); |
||||
|
if (intval($id) === intval(session('admin_user.id'))) { |
||||
|
$this->_form('SystemUser', 'admin@user/form', 'id', [], ['id' => $id]); |
||||
|
} else { |
||||
|
$this->error('只能修改登录用户的资料!'); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 清理运行缓存 |
||||
|
* @auth true |
||||
|
*/ |
||||
|
public function clearRuntime() |
||||
|
{ |
||||
|
if (!NodeService::islogin()) { |
||||
|
$this->error('需要登录才能操作哦!'); |
||||
|
} |
||||
|
try { |
||||
|
Console::call('clear'); |
||||
|
Console::call('xclean:session'); |
||||
|
$this->success('清理运行缓存成功!'); |
||||
|
} catch (HttpResponseException $exception) { |
||||
|
throw $exception; |
||||
|
} catch (\Exception $e) { |
||||
|
$this->error("清理运行缓存失败,{$e->getMessage()}"); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 压缩发布系统 |
||||
|
* @auth true |
||||
|
*/ |
||||
|
public function buildOptimize() |
||||
|
{ |
||||
|
if (!NodeService::islogin()) { |
||||
|
$this->error('需要登录才能操作哦!'); |
||||
|
} |
||||
|
try { |
||||
|
Console::call('optimize:route'); |
||||
|
Console::call('optimize:schema'); |
||||
|
Console::call('optimize:autoload'); |
||||
|
Console::call('optimize:config'); |
||||
|
$this->success('压缩发布成功!'); |
||||
|
} catch (HttpResponseException $exception) { |
||||
|
throw $exception; |
||||
|
} catch (\Exception $e) { |
||||
|
$this->error("压缩发布失败,{$e->getMessage()}"); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,124 @@ |
|||||
|
<?php |
||||
|
|
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | ThinkAdmin |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 版权所有 2014~2019 广州楚才信息科技有限公司 [ http://www.cuci.cc ] |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 官方网站: http://demo.thinkadmin.top |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 开源协议 ( https://mit-license.org ) |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin |
||||
|
// | github 代码仓库:https://github.com/zoujingli/ThinkAdmin |
||||
|
// +---------------------------------------------------------------------- |
||||
|
|
||||
|
namespace app\admin\controller; |
||||
|
|
||||
|
use app\admin\service\NodeService; |
||||
|
use library\Controller; |
||||
|
use think\Db; |
||||
|
|
||||
|
/** |
||||
|
* 用户登录管理 |
||||
|
* Class Login |
||||
|
* @package app\admin\controller |
||||
|
*/ |
||||
|
class Login extends Controller |
||||
|
{ |
||||
|
|
||||
|
/** |
||||
|
* 后台登录入口 |
||||
|
* @throws \think\Exception |
||||
|
* @throws \think\db\exception\DataNotFoundException |
||||
|
* @throws \think\db\exception\ModelNotFoundException |
||||
|
* @throws \think\exception\DbException |
||||
|
* @throws \think\exception\PDOException |
||||
|
*/ |
||||
|
public function index() |
||||
|
{ |
||||
|
$this->title = '系统登录'; |
||||
|
if ($this->request->isGet()) { |
||||
|
// 运行环境检查 |
||||
|
list($host,) = explode(':', $this->request->host()); |
||||
|
if (in_array($host, ['127.0.0.1', 'localhost', 'thinkadmin.top', 'ctolog.com'])) { |
||||
|
$this->devMode = true; |
||||
|
} else { |
||||
|
$this->devMode = false; |
||||
|
} |
||||
|
// 登录状态检查 |
||||
|
if (NodeService::islogin()) { |
||||
|
$this->redirect('@admin'); |
||||
|
} else { |
||||
|
$this->loginskey = session('loginskey'); |
||||
|
if (empty($this->loginskey)) { |
||||
|
$this->loginskey = uniqid(); |
||||
|
session('loginskey', $this->loginskey); |
||||
|
} |
||||
|
$this->fetch(); |
||||
|
} |
||||
|
} else { |
||||
|
$data = $this->_input([ |
||||
|
'username' => $this->request->post('username'), |
||||
|
'password' => $this->request->post('password'), |
||||
|
], [ |
||||
|
'username' => 'require|min:4', |
||||
|
'password' => 'require|min:4', |
||||
|
], [ |
||||
|
'username.require' => '登录账号不能为空!', |
||||
|
'password.require' => '登录密码不能为空!', |
||||
|
'username.min' => '登录账号长度不能少于4位有效字符!', |
||||
|
'password.min' => '登录密码长度不能少于4位有效字符!', |
||||
|
]); |
||||
|
// 用户信息验证 |
||||
|
$map = ['is_deleted' => '0', 'username' => $data['username']]; |
||||
|
$user = Db::name('SystemUser')->where($map)->order('id desc')->find(); |
||||
|
if (empty($user)) $this->error('登录账号或密码错误,请重新输入!'); |
||||
|
if (empty($user['status'])) $this->error('账号已经被禁用,请联系管理员!'); |
||||
|
// 账号锁定消息 |
||||
|
$cache = cache("user_login_{$user['username']}"); |
||||
|
if (is_array($cache) && !empty($cache['number']) && !empty($cache['time'])) { |
||||
|
if ($cache['number'] >= 10 && ($diff = $cache['time'] + 3600 - time()) > 0) { |
||||
|
list($m, $s, $info) = [floor($diff / 60), floor($diff % 60), '']; |
||||
|
if ($m > 0) $info = "{$m} 分"; |
||||
|
$this->error("<strong class='color-red'>抱歉,该账号已经被锁定!</strong><p class='nowrap'>连续 10 次登录错误,请 {$info} {$s} 秒后再登录!</p>"); |
||||
|
} |
||||
|
} |
||||
|
if (md5($user['password'] . session('loginskey')) !== $data['password']) { |
||||
|
if (empty($cache) || empty($cache['time']) || empty($cache['number']) || $cache['time'] + 3600 < time()) { |
||||
|
$cache = ['time' => time(), 'number' => 1, 'geoip' => $this->request->ip()]; |
||||
|
} elseif ($cache['number'] + 1 <= 10) { |
||||
|
$cache = ['time' => time(), 'number' => $cache['number'] + 1, 'geoip' => $this->request->ip()]; |
||||
|
} |
||||
|
cache("user_login_{$user['username']}", $cache); |
||||
|
if (($diff = 10 - $cache['number']) > 0) { |
||||
|
$this->error("<strong class='color-red'>登录账号或密码错误!</strong><p class='nowrap'>还有 {$diff} 次尝试机会,将锁定一小时内禁止登录!</p>"); |
||||
|
} else { |
||||
|
sysoplog('系统管理', "账号{$user['username']}连续10次登录密码错误,请注意账号安全!"); |
||||
|
$this->error("<strong class='color-red'>登录账号或密码错误!</strong><p class='nowrap'>尝试次数达到上限,锁定一小时内禁止登录!</p>"); |
||||
|
} |
||||
|
} |
||||
|
// 登录成功并更新账号 |
||||
|
cache("user_login_{$user['username']}", null); |
||||
|
Db::name('SystemUser')->where(['id' => $user['id']])->update([ |
||||
|
'login_at' => Db::raw('now()'), 'login_ip' => $this->request->ip(), 'login_num' => Db::raw('login_num+1'), |
||||
|
]); |
||||
|
session('loginskey', null); |
||||
|
session('admin_user', $user); |
||||
|
NodeService::applyUserAuth(); |
||||
|
sysoplog('系统管理', '用户登录系统成功'); |
||||
|
$this->success('登录成功,正在进入系统...', url('@admin')); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 退出登录 |
||||
|
*/ |
||||
|
public function out() |
||||
|
{ |
||||
|
\think\facade\Session::clear(); |
||||
|
\think\facade\Session::destroy(); |
||||
|
$this->success('退出登录成功!', url('@admin/login')); |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,162 @@ |
|||||
|
<?php |
||||
|
|
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | ThinkAdmin |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 版权所有 2014~2019 广州楚才信息科技有限公司 [ http://www.cuci.cc ] |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 官方网站: http://demo.thinkadmin.top |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 开源协议 ( https://mit-license.org ) |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin |
||||
|
// | github 代码仓库:https://github.com/zoujingli/ThinkAdmin |
||||
|
// +---------------------------------------------------------------------- |
||||
|
|
||||
|
namespace app\admin\controller; |
||||
|
|
||||
|
use app\admin\service\NodeService; |
||||
|
use library\Controller; |
||||
|
use library\tools\Data; |
||||
|
use think\Db; |
||||
|
|
||||
|
/** |
||||
|
* 系统菜单管理 |
||||
|
* Class Menu |
||||
|
* @package app\admin\controller |
||||
|
*/ |
||||
|
class Menu extends Controller |
||||
|
{ |
||||
|
|
||||
|
/** |
||||
|
* 当前操作数据库 |
||||
|
* @var string |
||||
|
*/ |
||||
|
protected $table = 'SystemMenu'; |
||||
|
|
||||
|
/** |
||||
|
* 系统菜单管理 |
||||
|
* @auth true |
||||
|
* @menu true |
||||
|
* @throws \think\Exception |
||||
|
* @throws \think\db\exception\DataNotFoundException |
||||
|
* @throws \think\db\exception\ModelNotFoundException |
||||
|
* @throws \think\exception\DbException |
||||
|
* @throws \think\exception\PDOException |
||||
|
*/ |
||||
|
public function index() |
||||
|
{ |
||||
|
$this->title = '系统菜单管理'; |
||||
|
$this->_page($this->table, false); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 列表数据处理 |
||||
|
* @param array $data |
||||
|
*/ |
||||
|
protected function _index_page_filter(&$data) |
||||
|
{ |
||||
|
foreach ($data as &$vo) { |
||||
|
if ($vo['url'] !== '#') { |
||||
|
$vo['url'] = url($vo['url']) . (empty($vo['params']) ? '' : "?{$vo['params']}"); |
||||
|
} |
||||
|
$vo['ids'] = join(',', Data::getArrSubIds($data, $vo['id'])); |
||||
|
} |
||||
|
$data = Data::arr2table($data); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 添加系统菜单 |
||||
|
* @auth true |
||||
|
* @throws \think\Exception |
||||
|
* @throws \think\db\exception\DataNotFoundException |
||||
|
* @throws \think\db\exception\ModelNotFoundException |
||||
|
* @throws \think\exception\DbException |
||||
|
* @throws \think\exception\PDOException |
||||
|
*/ |
||||
|
public function add() |
||||
|
{ |
||||
|
$this->applyCsrfToken(); |
||||
|
$this->_form($this->table, 'form'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 编辑系统菜单 |
||||
|
* @auth true |
||||
|
* @throws \think\Exception |
||||
|
* @throws \think\db\exception\DataNotFoundException |
||||
|
* @throws \think\db\exception\ModelNotFoundException |
||||
|
* @throws \think\exception\DbException |
||||
|
* @throws \think\exception\PDOException |
||||
|
*/ |
||||
|
public function edit() |
||||
|
{ |
||||
|
$this->applyCsrfToken(); |
||||
|
$this->_form($this->table, 'form'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 表单数据处理 |
||||
|
* @param array $vo |
||||
|
* @throws \ReflectionException |
||||
|
* @throws \think\db\exception\DataNotFoundException |
||||
|
* @throws \think\db\exception\ModelNotFoundException |
||||
|
* @throws \think\exception\DbException |
||||
|
*/ |
||||
|
protected function _form_filter(&$vo) |
||||
|
{ |
||||
|
if ($this->request->isGet()) { |
||||
|
$menus = Db::name($this->table)->where(['status' => '1'])->order('sort desc,id asc')->select(); |
||||
|
$menus[] = ['title' => '顶级菜单', 'id' => '0', 'pid' => '-1']; |
||||
|
foreach ($this->menus = Data::arr2table($menus) as $key => &$menu) { |
||||
|
if (substr_count($menu['path'], '-') > 3) unset($this->menus[$key]); # 移除三级以下的菜单 |
||||
|
elseif (isset($vo['pid']) && $vo['pid'] !== '' && $cur = "-{$vo['pid']}-{$vo['id']}") { |
||||
|
if (stripos("{$menu['path']}-", "{$cur}-") !== false || $menu['path'] === $cur) unset($this->menus[$key]); # 移除与自己相关联的菜单 |
||||
|
} |
||||
|
} |
||||
|
// 选择自己的上级菜单 |
||||
|
if (empty($vo['pid']) && $this->request->get('pid', '0')) { |
||||
|
$vo['pid'] = $this->request->get('pid', '0'); |
||||
|
} |
||||
|
// 读取系统功能节点 |
||||
|
$this->nodes = NodeService::getMenuNodeList(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 启用系统菜单 |
||||
|
* @auth true |
||||
|
* @throws \think\Exception |
||||
|
* @throws \think\exception\PDOException |
||||
|
*/ |
||||
|
public function resume() |
||||
|
{ |
||||
|
$this->applyCsrfToken(); |
||||
|
$this->_save($this->table, ['status' => '1']); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 禁用系统菜单 |
||||
|
* @auth true |
||||
|
* @throws \think\Exception |
||||
|
* @throws \think\exception\PDOException |
||||
|
*/ |
||||
|
public function forbid() |
||||
|
{ |
||||
|
$this->applyCsrfToken(); |
||||
|
$this->_save($this->table, ['status' => '0']); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 删除系统菜单 |
||||
|
* @auth true |
||||
|
* @throws \think\Exception |
||||
|
* @throws \think\exception\PDOException |
||||
|
*/ |
||||
|
public function remove() |
||||
|
{ |
||||
|
$this->applyCsrfToken(); |
||||
|
$this->_delete($this->table); |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,94 @@ |
|||||
|
<?php |
||||
|
|
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | ThinkAdmin |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 版权所有 2014~2019 广州楚才信息科技有限公司 [ http://www.cuci.cc ] |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 官方网站: http://demo.thinkadmin.top |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 开源协议 ( https://mit-license.org ) |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin |
||||
|
// | github 代码仓库:https://github.com/zoujingli/ThinkAdmin |
||||
|
// +---------------------------------------------------------------------- |
||||
|
|
||||
|
namespace app\admin\controller; |
||||
|
|
||||
|
use library\Controller; |
||||
|
use think\Db; |
||||
|
|
||||
|
/** |
||||
|
* 系统日志管理 |
||||
|
* Class Oplog |
||||
|
* @package app\admin\controller |
||||
|
*/ |
||||
|
class Oplog extends Controller |
||||
|
{ |
||||
|
|
||||
|
/** |
||||
|
* 指定当前数据表 |
||||
|
* @var string |
||||
|
*/ |
||||
|
public $table = 'SystemLog'; |
||||
|
|
||||
|
/** |
||||
|
* 系统操作日志 |
||||
|
* @auth true |
||||
|
* @menu true |
||||
|
* @throws \think\Exception |
||||
|
* @throws \think\db\exception\DataNotFoundException |
||||
|
* @throws \think\db\exception\ModelNotFoundException |
||||
|
* @throws \think\exception\DbException |
||||
|
*/ |
||||
|
public function index() |
||||
|
{ |
||||
|
$this->title = '系统操作日志'; |
||||
|
$query = $this->_query($this->table)->like('action,node,content,username,geoip'); |
||||
|
$query->dateBetween('create_at')->order('id desc')->page(); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 列表数据处理 |
||||
|
* @auth true |
||||
|
* @param array $data |
||||
|
* @throws \Exception |
||||
|
*/ |
||||
|
protected function _index_page_filter(&$data) |
||||
|
{ |
||||
|
$ip = new \Ip2Region(); |
||||
|
foreach ($data as &$vo) { |
||||
|
$result = $ip->btreeSearch($vo['geoip']); |
||||
|
$vo['isp'] = isset($result['region']) ? $result['region'] : ''; |
||||
|
$vo['isp'] = str_replace(['内网IP', '0', '|'], '', $vo['isp']); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 清理系统日志 |
||||
|
* @auth true |
||||
|
* @throws \think\Exception |
||||
|
* @throws \think\exception\PDOException |
||||
|
*/ |
||||
|
public function clear() |
||||
|
{ |
||||
|
if (Db::name($this->table)->whereRaw('1=1')->delete() !== false) { |
||||
|
$this->success('日志清理成功!'); |
||||
|
} else { |
||||
|
$this->error('日志清理失败,请稍候再试!'); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 删除系统日志 |
||||
|
* @auth true |
||||
|
* @throws \think\Exception |
||||
|
* @throws \think\exception\PDOException |
||||
|
*/ |
||||
|
public function remove() |
||||
|
{ |
||||
|
$this->applyCsrfToken(); |
||||
|
$this->_delete($this->table); |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,97 @@ |
|||||
|
<?php |
||||
|
|
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | ThinkAdmin |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 版权所有 2014~2019 广州楚才信息科技有限公司 [ http://www.cuci.cc ] |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 官方网站: http://demo.thinkadmin.top |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 开源协议 ( https://mit-license.org ) |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin |
||||
|
// | github 代码仓库:https://github.com/zoujingli/ThinkAdmin |
||||
|
// +---------------------------------------------------------------------- |
||||
|
|
||||
|
namespace app\admin\controller; |
||||
|
|
||||
|
use library\Controller; |
||||
|
use think\Console; |
||||
|
use think\Db; |
||||
|
|
||||
|
/** |
||||
|
* 系统系统任务 |
||||
|
* Class Queue |
||||
|
* @package app\admin\controller |
||||
|
*/ |
||||
|
class Queue extends Controller |
||||
|
{ |
||||
|
/** |
||||
|
* 绑定数据表 |
||||
|
* @var string |
||||
|
*/ |
||||
|
protected $table = 'SystemJobsLog'; |
||||
|
|
||||
|
/** |
||||
|
* 系统系统任务 |
||||
|
* @auth true |
||||
|
* @menu true |
||||
|
* @throws \think\Exception |
||||
|
* @throws \think\db\exception\DataNotFoundException |
||||
|
* @throws \think\db\exception\ModelNotFoundException |
||||
|
* @throws \think\exception\DbException |
||||
|
* @throws \think\exception\PDOException |
||||
|
*/ |
||||
|
public function index() |
||||
|
{ |
||||
|
$this->title = '系统任务管理'; |
||||
|
if (session('admin_user.username') === 'admin') { |
||||
|
$this->cmd = 'php ' . env('root_path') . 'think xtask:start'; |
||||
|
$this->message = Console::call('xtask:state')->fetch(); |
||||
|
} |
||||
|
$this->uris = Db::name($this->table)->distinct(true)->column('uri'); |
||||
|
$query = $this->_query($this->table)->dateBetween('create_at,status_at'); |
||||
|
$query->equal('status,title,uri')->order('id desc')->page(); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 重置失败任务 |
||||
|
* @auth true |
||||
|
*/ |
||||
|
public function redo() |
||||
|
{ |
||||
|
try { |
||||
|
$where = ['id' => $this->request->post('id')]; |
||||
|
$info = Db::name($this->table)->where($where)->find(); |
||||
|
if (empty($info)) $this->error('需要重置的任务获取异常!'); |
||||
|
$data = isset($info['data']) ? json_decode($info['data'], true) : '[]'; |
||||
|
\app\admin\service\QueueService::add($info['title'], $info['uri'], $info['later'], $data, $info['double'], $info['desc']); |
||||
|
$this->success('任务重置成功!', url('@admin') . '#' . url('@admin/queue/index')); |
||||
|
} catch (\think\exception\HttpResponseException $exception) { |
||||
|
throw $exception; |
||||
|
} catch (\Exception $e) { |
||||
|
$this->error("任务重置失败,请稍候再试!<br> {$e->getMessage()}"); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 删除系统任务 |
||||
|
* @auth true |
||||
|
*/ |
||||
|
public function remove() |
||||
|
{ |
||||
|
try { |
||||
|
$isNot = false; |
||||
|
foreach (explode(',', $this->request->post('id', '0')) as $id) { |
||||
|
if (!\app\admin\service\QueueService::del($id)) $isNot = true; |
||||
|
} |
||||
|
if (empty($isNot)) $this->_delete($this->table); |
||||
|
$this->success($isNot ? '部分任务删除成功!' : '任务删除成功!'); |
||||
|
} catch (\think\exception\HttpResponseException $exception) { |
||||
|
throw $exception; |
||||
|
} catch (\Exception $e) { |
||||
|
$this->error("任务删除失败,请稍候再试!<br> {$e->getMessage()}"); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,176 @@ |
|||||
|
<?php |
||||
|
|
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | ThinkAdmin |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 版权所有 2014~2019 广州楚才信息科技有限公司 [ http://www.cuci.cc ] |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 官方网站: http://demo.thinkadmin.top |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 开源协议 ( https://mit-license.org ) |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin |
||||
|
// | github 代码仓库:https://github.com/zoujingli/ThinkAdmin |
||||
|
// +---------------------------------------------------------------------- |
||||
|
|
||||
|
namespace app\admin\controller; |
||||
|
|
||||
|
use app\admin\service\NodeService; |
||||
|
use library\Controller; |
||||
|
use library\tools\Data; |
||||
|
use think\Db; |
||||
|
|
||||
|
/** |
||||
|
* 系统用户管理 |
||||
|
* Class User |
||||
|
* @package app\admin\controller |
||||
|
*/ |
||||
|
class User extends Controller |
||||
|
{ |
||||
|
|
||||
|
/** |
||||
|
* 指定当前数据表 |
||||
|
* @var string |
||||
|
*/ |
||||
|
public $table = 'SystemUser'; |
||||
|
|
||||
|
/** |
||||
|
* 系统用户管理 |
||||
|
* @auth true |
||||
|
* @menu true |
||||
|
* @throws \think\Exception |
||||
|
* @throws \think\db\exception\DataNotFoundException |
||||
|
* @throws \think\db\exception\ModelNotFoundException |
||||
|
* @throws \think\exception\DbException |
||||
|
* @throws \think\exception\PDOException |
||||
|
*/ |
||||
|
public function index() |
||||
|
{ |
||||
|
$this->title = '系统用户管理'; |
||||
|
$query = $this->_query($this->table)->like('username,phone,mail')->equal('status'); |
||||
|
$query->dateBetween('login_at,create_at')->where(['is_deleted' => '0'])->order('id desc')->page(); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 添加系统用户 |
||||
|
* @auth true |
||||
|
* @throws \think\Exception |
||||
|
* @throws \think\db\exception\DataNotFoundException |
||||
|
* @throws \think\db\exception\ModelNotFoundException |
||||
|
* @throws \think\exception\DbException |
||||
|
* @throws \think\exception\PDOException |
||||
|
*/ |
||||
|
public function add() |
||||
|
{ |
||||
|
$this->applyCsrfToken(); |
||||
|
$this->_form($this->table, 'form'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 编辑系统用户 |
||||
|
* @auth true |
||||
|
* @throws \think\Exception |
||||
|
* @throws \think\db\exception\DataNotFoundException |
||||
|
* @throws \think\db\exception\ModelNotFoundException |
||||
|
* @throws \think\exception\DbException |
||||
|
* @throws \think\exception\PDOException |
||||
|
*/ |
||||
|
public function edit() |
||||
|
{ |
||||
|
$this->applyCsrfToken(); |
||||
|
$this->_form($this->table, 'form'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 修改用户密码 |
||||
|
* @auth true |
||||
|
* @throws \think\Exception |
||||
|
* @throws \think\exception\PDOException |
||||
|
*/ |
||||
|
public function pass() |
||||
|
{ |
||||
|
$this->applyCsrfToken(); |
||||
|
if ($this->request->isGet()) { |
||||
|
$this->verify = false; |
||||
|
$this->_form($this->table, 'pass'); |
||||
|
} else { |
||||
|
$post = $this->request->post(); |
||||
|
if ($post['password'] !== $post['repassword']) { |
||||
|
$this->error('两次输入的密码不一致!'); |
||||
|
} |
||||
|
$result = NodeService::checkpwd($post['password']); |
||||
|
if (empty($result['code'])) $this->error($result['msg']); |
||||
|
if (Data::save($this->table, ['id' => $post['id'], 'password' => md5($post['password'])], 'id')) { |
||||
|
$this->success('密码修改成功,下次请使用新密码登录!', ''); |
||||
|
} else { |
||||
|
$this->error('密码修改失败,请稍候再试!'); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 表单数据处理 |
||||
|
* @param array $data |
||||
|
* @throws \think\db\exception\DataNotFoundException |
||||
|
* @throws \think\db\exception\ModelNotFoundException |
||||
|
* @throws \think\exception\DbException |
||||
|
*/ |
||||
|
public function _form_filter(&$data) |
||||
|
{ |
||||
|
if ($this->request->isPost()) { |
||||
|
NodeService::applyUserAuth(); |
||||
|
$data['authorize'] = (isset($data['authorize']) && is_array($data['authorize'])) ? join(',', $data['authorize']) : ''; |
||||
|
if (isset($data['id'])) { |
||||
|
unset($data['username']); |
||||
|
} elseif (Db::name($this->table)->where(['username' => $data['username']])->count() > 0) { |
||||
|
$this->error('用户账号已经存在,请使用其它账号!'); |
||||
|
} |
||||
|
} else { |
||||
|
$data['authorize'] = explode(',', isset($data['authorize']) ? $data['authorize'] : ''); |
||||
|
$this->authorizes = Db::name('SystemAuth')->where(['status' => '1'])->order('sort desc,id desc')->select(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 禁用系统用户 |
||||
|
* @auth true |
||||
|
* @throws \think\Exception |
||||
|
* @throws \think\exception\PDOException |
||||
|
*/ |
||||
|
public function forbid() |
||||
|
{ |
||||
|
if (in_array('10000', explode(',', $this->request->post('id')))) { |
||||
|
$this->error('系统超级账号禁止操作!'); |
||||
|
} |
||||
|
$this->applyCsrfToken(); |
||||
|
$this->_save($this->table, ['status' => '0']); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 启用系统用户 |
||||
|
* @auth true |
||||
|
* @throws \think\Exception |
||||
|
* @throws \think\exception\PDOException |
||||
|
*/ |
||||
|
public function resume() |
||||
|
{ |
||||
|
$this->applyCsrfToken(); |
||||
|
$this->_save($this->table, ['status' => '1']); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 删除系统用户 |
||||
|
* @auth true |
||||
|
* @throws \think\Exception |
||||
|
* @throws \think\exception\PDOException |
||||
|
*/ |
||||
|
public function remove() |
||||
|
{ |
||||
|
if (in_array('10000', explode(',', $this->request->post('id')))) { |
||||
|
$this->error('系统超级账号禁止删除!'); |
||||
|
} |
||||
|
$this->applyCsrfToken(); |
||||
|
$this->_delete($this->table); |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,100 @@ |
|||||
|
<?php |
||||
|
|
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | ThinkAdmin |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 版权所有 2014~2019 广州楚才信息科技有限公司 [ http://www.cuci.cc ] |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 官方网站: http://demo.thinkadmin.top |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 开源协议 ( https://mit-license.org ) |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin |
||||
|
// | github 代码仓库:https://github.com/zoujingli/ThinkAdmin |
||||
|
// +---------------------------------------------------------------------- |
||||
|
|
||||
|
namespace app\admin\controller\api; |
||||
|
|
||||
|
use app\admin\service\NodeService; |
||||
|
use library\Controller; |
||||
|
use library\File; |
||||
|
|
||||
|
/** |
||||
|
* 后台插件管理 |
||||
|
* Class Plugs |
||||
|
* @package app\admin\controller\api |
||||
|
*/ |
||||
|
class Plugs extends Controller |
||||
|
{ |
||||
|
|
||||
|
/** |
||||
|
* 系统选择器图标 |
||||
|
*/ |
||||
|
public function icon() |
||||
|
{ |
||||
|
$this->title = '图标选择器'; |
||||
|
$this->field = input('field', 'icon'); |
||||
|
$this->fetch(); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Plupload 插件上传文件 |
||||
|
* @return \think\response\Json |
||||
|
* @throws \think\Exception |
||||
|
* @throws \think\exception\PDOException |
||||
|
*/ |
||||
|
public function plupload() |
||||
|
{ |
||||
|
if (!NodeService::islogin()) { |
||||
|
$this->error('访问授权失败,请重新登录授权再试!'); |
||||
|
} |
||||
|
if (!($file = $this->getUploadFile()) || empty($file)) { |
||||
|
return json(['uploaded' => false, 'error' => ['message' => '文件上传异常,文件可能过大或未上传']]); |
||||
|
} |
||||
|
if (!$file->checkExt(strtolower(sysconf('storage_local_exts')))) { |
||||
|
return json(['uploaded' => false, 'error' => ['message' => '文件上传类型受限,请在后台配置']]); |
||||
|
} |
||||
|
if ($file->checkExt('php,sh')) { |
||||
|
return json(['uploaded' => false, 'error' => ['message' => '可执行文件禁止上传到本地服务器']]); |
||||
|
} |
||||
|
$this->safe = boolval(input('safe')); |
||||
|
$this->uptype = $this->getUploadType(); |
||||
|
$this->extend = pathinfo($file->getInfo('name'), PATHINFO_EXTENSION); |
||||
|
$name = File::name($file->getPathname(), $this->extend, '', 'md5_file'); |
||||
|
$info = File::instance($this->uptype)->save($name, file_get_contents($file->getRealPath()), $this->safe); |
||||
|
if (is_array($info) && isset($info['url'])) { |
||||
|
return json(['uploaded' => true, 'filename' => $name, 'url' => $this->safe ? $name : $info['url']]); |
||||
|
} else { |
||||
|
return json(['uploaded' => false, 'error' => ['message' => '文件处理失败,请稍候再试!']]); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 获取文件上传方式 |
||||
|
* @return string |
||||
|
* @throws \think\Exception |
||||
|
* @throws \think\exception\PDOException |
||||
|
*/ |
||||
|
private function getUploadType() |
||||
|
{ |
||||
|
$this->uptype = input('uptype'); |
||||
|
if (!in_array($this->uptype, ['local', 'oss', 'qiniu'])) { |
||||
|
$this->uptype = sysconf('storage_type'); |
||||
|
} |
||||
|
return $this->uptype; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 获取本地文件对象 |
||||
|
* @return \think\File |
||||
|
*/ |
||||
|
private function getUploadFile() |
||||
|
{ |
||||
|
try { |
||||
|
return $this->request->file('file'); |
||||
|
} catch (\Exception $e) { |
||||
|
$this->error(lang($e->getMessage())); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,60 @@ |
|||||
|
<?php |
||||
|
|
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | ThinkAdmin |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 版权所有 2014~2019 广州楚才信息科技有限公司 [ http://www.cuci.cc ] |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 官方网站: http://demo.thinkadmin.top |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 开源协议 ( https://mit-license.org ) |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin |
||||
|
// | github 代码仓库:https://github.com/zoujingli/ThinkAdmin |
||||
|
// +---------------------------------------------------------------------- |
||||
|
|
||||
|
namespace app\admin\controller\api; |
||||
|
|
||||
|
use library\command\Sync; |
||||
|
use library\Controller; |
||||
|
|
||||
|
/** |
||||
|
* 系统更新接口 |
||||
|
* Class Update |
||||
|
* @package app\admin\controller\api |
||||
|
*/ |
||||
|
class Update extends Controller |
||||
|
{ |
||||
|
/** |
||||
|
* 基础URL地址 |
||||
|
* @var string |
||||
|
*/ |
||||
|
protected $baseUri = 'https://demo.thinkadmin.top'; |
||||
|
|
||||
|
/** |
||||
|
* 获取文件列表 |
||||
|
*/ |
||||
|
public function tree() |
||||
|
{ |
||||
|
$sync = new Sync('Update'); |
||||
|
$this->success('获取当前文件列表成功!', $sync->build()); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 读取线上文件数据 |
||||
|
* @param string $encode |
||||
|
*/ |
||||
|
public function read($encode) |
||||
|
{ |
||||
|
$this->file = env('root_path') . decode($encode); |
||||
|
if (file_exists($this->file)) { |
||||
|
$this->success('读取文件成功!', [ |
||||
|
'format' => 'base64', |
||||
|
'content' => base64_encode(file_get_contents($this->file)), |
||||
|
]); |
||||
|
} else { |
||||
|
$this->error('获取文件内容失败!'); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,124 @@ |
|||||
|
<?php |
||||
|
|
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | ThinkAdmin |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 版权所有 2014~2019 广州楚才信息科技有限公司 [ http://www.cuci.cc ] |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 官方网站: http://demo.thinkadmin.top |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 开源协议 ( https://mit-license.org ) |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin |
||||
|
// | github 代码仓库:https://github.com/zoujingli/ThinkAdmin |
||||
|
// +---------------------------------------------------------------------- |
||||
|
|
||||
|
namespace app\admin\queue; |
||||
|
|
||||
|
use app\admin\service\QueueService; |
||||
|
use think\console\Output; |
||||
|
|
||||
|
/** |
||||
|
* 基础指令公共类 |
||||
|
* Class JobsQueue |
||||
|
* @package app\admin |
||||
|
*/ |
||||
|
class JobsQueue |
||||
|
{ |
||||
|
/** |
||||
|
* 待处理 |
||||
|
*/ |
||||
|
const STATUS_PEND = 1; |
||||
|
|
||||
|
/** |
||||
|
* 处理中 |
||||
|
*/ |
||||
|
const STATUS_PROC = 2; |
||||
|
|
||||
|
/** |
||||
|
* 处理完成 |
||||
|
*/ |
||||
|
const STATUS_COMP = 3; |
||||
|
|
||||
|
/** |
||||
|
* 处理失败 |
||||
|
*/ |
||||
|
const STATUS_FAIL = 4; |
||||
|
|
||||
|
/** |
||||
|
* 任务ID |
||||
|
* @var integer |
||||
|
*/ |
||||
|
protected $id; |
||||
|
|
||||
|
/** |
||||
|
* 任务数据 |
||||
|
* @var array |
||||
|
*/ |
||||
|
protected $data; |
||||
|
|
||||
|
/** |
||||
|
* 任务名称 |
||||
|
* @var string |
||||
|
*/ |
||||
|
protected $title; |
||||
|
|
||||
|
/** |
||||
|
* 任务状态 |
||||
|
* @var integer |
||||
|
*/ |
||||
|
protected $status; |
||||
|
|
||||
|
/** |
||||
|
* @var Output |
||||
|
*/ |
||||
|
protected $output; |
||||
|
|
||||
|
/** |
||||
|
* 任务状态描述 |
||||
|
* @var string |
||||
|
*/ |
||||
|
protected $statusDesc = ''; |
||||
|
|
||||
|
/** |
||||
|
* 启动任务处理 |
||||
|
* @param \think\queue\Job $job 当前任务对象 |
||||
|
* @param array $data 任务执行对象 |
||||
|
* @throws \think\Exception |
||||
|
* @throws \think\exception\PDOException |
||||
|
*/ |
||||
|
public function fire(\think\queue\Job $job, $data = []) |
||||
|
{ |
||||
|
$this->data = $data; |
||||
|
$this->output = new Output(); |
||||
|
$this->id = isset($data['_job_id_']) ? $data['_job_id_'] : ''; |
||||
|
$this->title = isset($data['_job_title_']) ? $data['_job_title_'] : ''; |
||||
|
$this->output->newLine(); |
||||
|
$this->output->writeln(" system task {$this->id} execution start"); |
||||
|
$this->output->writeln('---------------------------------------------'); |
||||
|
QueueService::status($this->id, self::STATUS_PROC, $this->statusDesc); |
||||
|
if ($this->execute()) { |
||||
|
$this->output->writeln('---------------------------------------------'); |
||||
|
$this->output->info(" successful"); |
||||
|
$this->status = self::STATUS_COMP; |
||||
|
} else { |
||||
|
$this->output->writeln('---------------------------------------------'); |
||||
|
$this->output->error(" failure"); |
||||
|
$this->status = self::STATUS_FAIL; |
||||
|
} |
||||
|
$job->delete(); |
||||
|
QueueService::status($this->id, $this->status, $this->statusDesc); |
||||
|
$this->output->writeln('---------------------------------------------'); |
||||
|
$this->output->newLine(); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 执行任务 |
||||
|
* @return boolean |
||||
|
*/ |
||||
|
protected function execute() |
||||
|
{ |
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,346 @@ |
|||||
|
<?php |
||||
|
|
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | ThinkAdmin |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 版权所有 2014~2019 广州楚才信息科技有限公司 [ http://www.cuci.cc ] |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 官方网站: http://demo.thinkadmin.top |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 开源协议 ( https://mit-license.org ) |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin |
||||
|
// | github 代码仓库:https://github.com/zoujingli/ThinkAdmin |
||||
|
// +---------------------------------------------------------------------- |
||||
|
|
||||
|
namespace app\admin\service; |
||||
|
|
||||
|
use library\tools\Data; |
||||
|
use library\tools\Node; |
||||
|
use think\Db; |
||||
|
use think\facade\App; |
||||
|
use think\facade\Cache; |
||||
|
use think\facade\Request; |
||||
|
|
||||
|
/** |
||||
|
* 功能节点管理服务 |
||||
|
* Class NodeService |
||||
|
* @package app\admin\service |
||||
|
*/ |
||||
|
class NodeService |
||||
|
{ |
||||
|
|
||||
|
/** |
||||
|
* 获取标准访问节点 |
||||
|
* @param string $node |
||||
|
* @return string |
||||
|
*/ |
||||
|
public static function full($node = null) |
||||
|
{ |
||||
|
if (empty($node)) return self::current(); |
||||
|
if (count(explode('/', $node)) === 1) { |
||||
|
$node = Request::module() . '/' . Request::controller() . '/' . $node; |
||||
|
} |
||||
|
return self::parseString(trim($node, " /")); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 判断是否已经登录 |
||||
|
* @return boolean |
||||
|
*/ |
||||
|
public static function islogin() |
||||
|
{ |
||||
|
return session('admin_user.id') ? true : false; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 获取当前访问节点 |
||||
|
* @return string |
||||
|
*/ |
||||
|
public static function current() |
||||
|
{ |
||||
|
return self::parseString(Request::module() . '/' . Request::controller() . '/' . Request::action()); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 检查密码是否合法 |
||||
|
* @param string $password |
||||
|
* @return array |
||||
|
*/ |
||||
|
public static function checkpwd($password) |
||||
|
{ |
||||
|
$password = trim($password); |
||||
|
if (!strlen($password) >= 6) { |
||||
|
return ['code' => 0, 'msg' => '密码必须大于6字符!']; |
||||
|
} |
||||
|
if (!preg_match("/^(?![\d]+$)(?![a-zA-Z]+$)(?![^\da-zA-Z]+$).{6,32}$/", $password)) { |
||||
|
return ['code' => 0, 'msg' => '密码必需包含大小写字母、数字、符号任意两者组合!']; |
||||
|
} else { |
||||
|
return ['code' => 1, 'msg' => '密码复杂度通过验证!']; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 获取可选菜单节点 |
||||
|
* @return array |
||||
|
* @throws \ReflectionException |
||||
|
*/ |
||||
|
public static function getMenuNodeList() |
||||
|
{ |
||||
|
static $nodes = []; |
||||
|
if (count($nodes) > 0) return $nodes; |
||||
|
foreach (self::getMethodList() as $node => $method) if ($method['menu']) { |
||||
|
$nodes[] = ['node' => $node, 'title' => $method['title']]; |
||||
|
} |
||||
|
return $nodes; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 获取系统菜单树数据 |
||||
|
* @return array |
||||
|
* @throws \ReflectionException |
||||
|
* @throws \think\db\exception\DataNotFoundException |
||||
|
* @throws \think\db\exception\ModelNotFoundException |
||||
|
* @throws \think\exception\DbException |
||||
|
*/ |
||||
|
public static function getMenuNodeTree() |
||||
|
{ |
||||
|
$list = Db::name('SystemMenu')->where(['status' => '1'])->order('sort desc,id asc')->select(); |
||||
|
return self::buildMenuData(Data::arr2tree($list), self::getMethodList()); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 后台主菜单权限过滤 |
||||
|
* @param array $menus 当前菜单列表 |
||||
|
* @param array $nodes 系统权限节点 |
||||
|
* @return array |
||||
|
* @throws \ReflectionException |
||||
|
*/ |
||||
|
private static function buildMenuData($menus, $nodes) |
||||
|
{ |
||||
|
foreach ($menus as $key => &$menu) { |
||||
|
if (!empty($menu['sub'])) $menu['sub'] = self::buildMenuData($menu['sub'], $nodes); |
||||
|
if (!empty($menu['sub'])) $menu['url'] = '#'; |
||||
|
elseif (preg_match('/^https?\:/i', $menu['url'])) continue; |
||||
|
elseif ($menu['url'] === '#') unset($menus[$key]); |
||||
|
else { |
||||
|
$node = join('/', array_slice(explode('/', preg_replace('/[\W]/', '/', $menu['url'])), 0, 3)); |
||||
|
$menu['url'] = url($menu['url']) . (empty($menu['params']) ? '' : "?{$menu['params']}"); |
||||
|
if (!self::checkAuth($node)) unset($menus[$key]); |
||||
|
} |
||||
|
} |
||||
|
return $menus; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 获取授权节点列表 |
||||
|
* @return array |
||||
|
* @throws \ReflectionException |
||||
|
*/ |
||||
|
public static function getAuthList() |
||||
|
{ |
||||
|
static $nodes = []; |
||||
|
if (count($nodes) > 0) return $nodes; |
||||
|
$nodes = Cache::tag('system')->get('NodeAuthList', []); |
||||
|
if (count($nodes) > 0) return $nodes; |
||||
|
foreach (self::getMethodList() as $key => $node) { |
||||
|
if ($node['auth']) $nodes[$key] = $node['title']; |
||||
|
} |
||||
|
Cache::tag('system')->set('NodeAuthList', $nodes); |
||||
|
return $nodes; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 强制验证访问权限 |
||||
|
* --- 需要加载对应的控制器 |
||||
|
* @param null|string $node |
||||
|
* @return boolean |
||||
|
* @throws \ReflectionException |
||||
|
*/ |
||||
|
public static function forceAuth($node = null) |
||||
|
{ |
||||
|
if (session('admin_user.username') === 'admin') return true; |
||||
|
$real = is_null($node) ? self::current() : self::full($node); |
||||
|
list($module, $controller, $action) = explode('/', $real); |
||||
|
if (class_exists($class = App::parseClass($module, 'controller', $controller))) { |
||||
|
$reflection = new \ReflectionClass($class); |
||||
|
if ($reflection->hasMethod($action)) { |
||||
|
$comment = preg_replace("/\s/", '', $reflection->getMethod($action)->getDocComment()); |
||||
|
if (stripos($comment, '@authtrue') === false) { |
||||
|
return true; |
||||
|
} else { |
||||
|
return in_array($real, (array)session('admin_user.nodes')); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 检查指定节点授权 |
||||
|
* --- 需要读取缓存或扫描所有节点 |
||||
|
* @param null|string $node |
||||
|
* @return boolean |
||||
|
* @throws \ReflectionException |
||||
|
*/ |
||||
|
public static function checkAuth($node = null) |
||||
|
{ |
||||
|
if (session('admin_user.username') === 'admin') return true; |
||||
|
$real = is_null($node) ? self::current() : self::full($node); |
||||
|
if (isset(self::getAuthList()[$real])) { |
||||
|
return in_array($real, (array)session('admin_user.nodes')); |
||||
|
} else { |
||||
|
return true; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 获取授权节点列表 |
||||
|
* @param array $checkeds |
||||
|
* @return array |
||||
|
* @throws \ReflectionException |
||||
|
*/ |
||||
|
public static function getAuthTree($checkeds = []) |
||||
|
{ |
||||
|
static $nodes = []; |
||||
|
if (count($nodes) > 0) return $nodes; |
||||
|
foreach (self::getAuthList() as $node => $title) { |
||||
|
$pnode = substr($node, 0, strripos($node, '/')); |
||||
|
$nodes[$node] = ['node' => $node, 'title' => $title, 'pnode' => $pnode, 'checked' => in_array($node, $checkeds)]; |
||||
|
} |
||||
|
foreach (self::getClassList() as $node => $title) foreach (array_keys($nodes) as $key) { |
||||
|
if (stripos($key, "{$node}/") !== false) { |
||||
|
$pnode = substr($node, 0, strripos($node, '/')); |
||||
|
$nodes[$node] = ['node' => $node, 'title' => $title, 'pnode' => $pnode, 'checked' => in_array($node, $checkeds)]; |
||||
|
$nodes[$pnode] = ['node' => $pnode, 'title' => ucfirst($pnode), 'checked' => in_array($pnode, $checkeds)]; |
||||
|
} |
||||
|
} |
||||
|
return $nodes = Data::arr2tree($nodes, 'node', 'pnode', '_sub_'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 初始化用户权限 |
||||
|
* @param boolean $force 是否重置系统权限 |
||||
|
* @throws \think\db\exception\DataNotFoundException |
||||
|
* @throws \think\db\exception\ModelNotFoundException |
||||
|
* @throws \think\exception\DbException |
||||
|
*/ |
||||
|
public static function applyUserAuth($force = false) |
||||
|
{ |
||||
|
if ($force) { |
||||
|
Cache::tag('system')->rm('NodeAuthList'); |
||||
|
Cache::tag('system')->rm('NodeClassData'); |
||||
|
Cache::tag('system')->rm('NodeMethodData'); |
||||
|
} |
||||
|
if (($uid = session('admin_user.id'))) { |
||||
|
session('admin_user', Db::name('SystemUser')->where(['id' => $uid])->find()); |
||||
|
} |
||||
|
if (($aids = session('admin_user.authorize'))) { |
||||
|
$where = [['status', 'eq', '1'], ['id', 'in', explode(',', $aids)]]; |
||||
|
$subsql = Db::name('SystemAuth')->field('id')->where($where)->buildSql(); |
||||
|
session('admin_user.nodes', array_unique(Db::name('SystemAuthNode')->whereRaw("auth in {$subsql}")->column('node'))); |
||||
|
} else { |
||||
|
session('admin_user.nodes', []); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 获取控制器节点列表 |
||||
|
* @return array |
||||
|
* @throws \ReflectionException |
||||
|
*/ |
||||
|
public static function getClassList() |
||||
|
{ |
||||
|
static $nodes = []; |
||||
|
if (count($nodes) > 0) return $nodes; |
||||
|
$nodes = Cache::tag('system')->get('NodeClassData', []); |
||||
|
if (count($nodes) > 0) return $nodes; |
||||
|
self::eachController(function (\ReflectionClass $reflection, $prenode) use (&$nodes) { |
||||
|
list($node, $comment) = [trim($prenode, ' / '), $reflection->getDocComment()]; |
||||
|
$nodes[$node] = preg_replace('/^\/\*\*\*(.*?)\*.*?$/', '$1', preg_replace("/\s/", '', $comment)); |
||||
|
if (stripos($nodes[$node], '@') !== false) $nodes[$node] = ''; |
||||
|
}); |
||||
|
Cache::tag('system')->set('NodeClassData', $nodes); |
||||
|
return $nodes; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 获取方法节点列表 |
||||
|
* @return array |
||||
|
* @throws \ReflectionException |
||||
|
*/ |
||||
|
public static function getMethodList() |
||||
|
{ |
||||
|
static $nodes = []; |
||||
|
if (count($nodes) > 0) return $nodes; |
||||
|
$nodes = Cache::tag('system')->get('NodeMethodData', []); |
||||
|
if (count($nodes) > 0) return $nodes; |
||||
|
self::eachController(function (\ReflectionClass $reflection, $prenode) use (&$nodes) { |
||||
|
foreach ($reflection->getMethods(\ReflectionMethod::IS_PUBLIC) as $method) { |
||||
|
$action = strtolower($method->getName()); |
||||
|
list($node, $comment) = ["{$prenode}{$action}", preg_replace("/\s/", '', $method->getDocComment())]; |
||||
|
$nodes[$node] = [ |
||||
|
'auth' => stripos($comment, '@authtrue') !== false, |
||||
|
'menu' => stripos($comment, '@menutrue') !== false, |
||||
|
'title' => preg_replace('/^\/\*\*\*(.*?)\*.*?$/', '$1', $comment), |
||||
|
]; |
||||
|
if (stripos($nodes[$node]['title'], '@') !== false) $nodes[$node]['title'] = ''; |
||||
|
} |
||||
|
}); |
||||
|
Cache::tag('system')->set('NodeMethodData', $nodes); |
||||
|
return $nodes; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 控制器扫描回调 |
||||
|
* @param callable $callable |
||||
|
* @throws \ReflectionException |
||||
|
*/ |
||||
|
public static function eachController($callable) |
||||
|
{ |
||||
|
foreach (self::scanPath(env('app_path') . "*/controller/") as $file) { |
||||
|
if (!preg_match("|/(\w+)/controller/(.+)\.php$|", $file, $matches)) continue; |
||||
|
list($module, $controller) = [$matches[1], strtr($matches[2], '/', '.')]; |
||||
|
if (class_exists($class = substr(strtr(env('app_namespace') . $matches[0], '/', '\\'), 0, -4))) { |
||||
|
call_user_func($callable, new \ReflectionClass($class), Node::parseString("{$module}/{$controller}/")); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 驼峰转下划线规则 |
||||
|
* @param string $node 节点名称 |
||||
|
* @return string |
||||
|
*/ |
||||
|
public static function parseString($node) |
||||
|
{ |
||||
|
if (count($nodes = explode('/', $node)) > 1) { |
||||
|
$dots = []; |
||||
|
foreach (explode('.', $nodes[1]) as $dot) { |
||||
|
$dots[] = trim(preg_replace("/[A-Z]/", "_\\0", $dot), "_"); |
||||
|
} |
||||
|
$nodes[1] = join('.', $dots); |
||||
|
} |
||||
|
return strtolower(join('/', $nodes)); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 获取所有PHP文件 |
||||
|
* @param string $dirname 扫描目录 |
||||
|
* @param array $data 额外数据 |
||||
|
* @param string $ext 有文件后缀 |
||||
|
* @return array |
||||
|
*/ |
||||
|
private static function scanPath($dirname, $data = [], $ext = 'php') |
||||
|
{ |
||||
|
foreach (glob("{$dirname}*") as $file) { |
||||
|
if (is_dir($file)) { |
||||
|
$data = array_merge($data, self::scanPath("{$file}/")); |
||||
|
} elseif (is_file($file) && pathinfo($file, 4) === $ext) { |
||||
|
$data[] = str_replace('\\', '/', $file); |
||||
|
} |
||||
|
} |
||||
|
return $data; |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,53 @@ |
|||||
|
<?php |
||||
|
|
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | ThinkAdmin |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 版权所有 2014~2019 广州楚才信息科技有限公司 [ http://www.cuci.cc ] |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 官方网站: http://demo.thinkadmin.top |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 开源协议 ( https://mit-license.org ) |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin |
||||
|
// | github 代码仓库:https://github.com/zoujingli/ThinkAdmin |
||||
|
// +---------------------------------------------------------------------- |
||||
|
|
||||
|
namespace app\admin\service; |
||||
|
|
||||
|
use library\tools\Node; |
||||
|
use think\Db; |
||||
|
|
||||
|
/** |
||||
|
* 系统日志服务管理 |
||||
|
* Class LogService |
||||
|
* @package app\admin\service |
||||
|
*/ |
||||
|
class OplogService |
||||
|
{ |
||||
|
/** |
||||
|
* 写入操作日志 |
||||
|
* @param string $action |
||||
|
* @param string $content |
||||
|
* @return bool |
||||
|
*/ |
||||
|
public static function write($action = '行为', $content = "内容描述") |
||||
|
{ |
||||
|
return Db::name('SystemLog')->insert([ |
||||
|
'node' => Node::current(), 'action' => $action, 'content' => $content, |
||||
|
'geoip' => PHP_SAPI === 'cli' ? '127.0.0.1' : request()->ip(), |
||||
|
'username' => PHP_SAPI === 'cli' ? 'cli' : (string)session('admin_user.username'), |
||||
|
]); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 清理系统日志 |
||||
|
* @return boolean |
||||
|
* @throws \think\Exception |
||||
|
* @throws \think\exception\PDOException |
||||
|
*/ |
||||
|
public static function clear() |
||||
|
{ |
||||
|
return Db::name('SystemLog')->where('1=1')->delete() !== false; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,130 @@ |
|||||
|
<?php |
||||
|
|
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | ThinkAdmin |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 版权所有 2014~2019 广州楚才信息科技有限公司 [ http://www.cuci.cc ] |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 官方网站: http://demo.thinkadmin.top |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 开源协议 ( https://mit-license.org ) |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin |
||||
|
// | github 代码仓库:https://github.com/zoujingli/ThinkAdmin |
||||
|
// +---------------------------------------------------------------------- |
||||
|
|
||||
|
namespace app\admin\service; |
||||
|
|
||||
|
use think\Db; |
||||
|
|
||||
|
/** |
||||
|
* 任务管理器 |
||||
|
* Class QueueService |
||||
|
* @package app\admin\service |
||||
|
*/ |
||||
|
class QueueService |
||||
|
{ |
||||
|
/** |
||||
|
* 待处理 |
||||
|
*/ |
||||
|
const STATUS_PEND = 1; |
||||
|
|
||||
|
/** |
||||
|
* 处理中 |
||||
|
*/ |
||||
|
const STATUS_PROC = 2; |
||||
|
|
||||
|
/** |
||||
|
* 处理完成 |
||||
|
*/ |
||||
|
const STATUS_COMP = 3; |
||||
|
|
||||
|
/** |
||||
|
* 处理失败 |
||||
|
*/ |
||||
|
const STATUS_FAIL = 4; |
||||
|
|
||||
|
/** |
||||
|
* 创建任务并记录日志 |
||||
|
* @param string $title 任务名称 |
||||
|
* @param string $uri 任务命令 |
||||
|
* @param integer $later 延时时间 |
||||
|
* @param array $data 任务附加数据 |
||||
|
* @param integer $double 任务多开 |
||||
|
* @param string $desc 任务描述 |
||||
|
* @throws \think\Exception |
||||
|
*/ |
||||
|
public static function add($title, $uri, $later, array $data, $double = 1, $desc = '') |
||||
|
{ |
||||
|
if (empty($double) && self::exists($title)) { |
||||
|
throw new \think\Exception('该任务已经创建,请耐心等待处理完成!'); |
||||
|
} |
||||
|
$jobId = Db::name('SystemJobsLog')->insertGetId([ |
||||
|
'title' => $title, 'later' => $later, 'uri' => $uri, 'double' => intval($double), |
||||
|
'data' => json_encode($data, 256), 'desc' => $desc, 'status_at' => date('Y-m-d H:i:s'), |
||||
|
]); |
||||
|
$data['_job_id_'] = $jobId; |
||||
|
$data['_job_title_'] = $title; |
||||
|
\think\Queue::later($later, $uri, $data); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 更新任务状态 |
||||
|
* @param integer $jobId |
||||
|
* @param integer $status |
||||
|
* @param string $statusDesc |
||||
|
* @return boolean |
||||
|
* @throws \think\Exception |
||||
|
* @throws \think\exception\PDOException |
||||
|
*/ |
||||
|
public static function status($jobId, $status = self::STATUS_PEND, $statusDesc = '') |
||||
|
{ |
||||
|
$result = Db::name('SystemJobsLog')->where(['id' => $jobId])->update([ |
||||
|
'status' => $status, 'status_desc' => $statusDesc, 'status_at' => date('Y-m-d H:i:s'), |
||||
|
]); |
||||
|
return $result !== false; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 检查任务是否存在 |
||||
|
* @param string $title |
||||
|
* @return boolean |
||||
|
*/ |
||||
|
public static function exists($title) |
||||
|
{ |
||||
|
$where = [['title', 'eq', $title], ['status', 'in', [1, 2]]]; |
||||
|
return Db::name('SystemJobsLog')->where($where)->count() > 0; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 获取任务数据 |
||||
|
* @param integer $jobId |
||||
|
* @return array|null |
||||
|
* @throws \think\db\exception\DataNotFoundException |
||||
|
* @throws \think\db\exception\ModelNotFoundException |
||||
|
* @throws \think\exception\DbException |
||||
|
*/ |
||||
|
public static function get($jobId) |
||||
|
{ |
||||
|
return Db::name('SystemJobsLog')->where(['id' => $jobId])->find(); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 删除任务数据 |
||||
|
* @param integer $jobId |
||||
|
* @return boolean |
||||
|
* @throws \think\Exception |
||||
|
* @throws \think\exception\PDOException |
||||
|
*/ |
||||
|
public static function del($jobId) |
||||
|
{ |
||||
|
$where = [['id', 'eq', $jobId], ['status', 'in', [1, 3, 4]]]; |
||||
|
if (Db::name('SystemJobsLog')->where($where)->delete() > 0) { |
||||
|
Db::name('SystemJobs')->whereLike('payload', '%"_job_id_":"' . $jobId . '"%')->delete(); |
||||
|
return true; |
||||
|
} else { |
||||
|
return false; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,119 @@ |
|||||
|
<?php |
||||
|
|
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | ThinkAdmin |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 版权所有 2014~2019 广州楚才信息科技有限公司 [ http://www.cuci.cc ] |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 官方网站: http://demo.thinkadmin.top |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 开源协议 ( https://mit-license.org ) |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin |
||||
|
// | github 代码仓库:https://github.com/zoujingli/ThinkAdmin |
||||
|
// +---------------------------------------------------------------------- |
||||
|
|
||||
|
use app\admin\service\NodeService; |
||||
|
use app\admin\service\OplogService; |
||||
|
use library\File; |
||||
|
use think\Db; |
||||
|
use think\facade\Middleware; |
||||
|
use think\Request; |
||||
|
|
||||
|
if (!function_exists('auth')) { |
||||
|
/** |
||||
|
* 节点访问权限检查 |
||||
|
* @param string $node |
||||
|
* @return boolean |
||||
|
* @throws ReflectionException |
||||
|
*/ |
||||
|
function auth($node) |
||||
|
{ |
||||
|
return NodeService::checkAuth($node); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
if (!function_exists('sysdata')) { |
||||
|
/** |
||||
|
* JSON 数据读取与存储 |
||||
|
* @param string $name 数据名称 |
||||
|
* @param array|null $value 数据内容 |
||||
|
* @return mixed |
||||
|
* @throws \think\Exception |
||||
|
* @throws \think\exception\PDOException |
||||
|
*/ |
||||
|
function sysdata($name, array $value = null) |
||||
|
{ |
||||
|
if (is_null($value)) { |
||||
|
$data = json_decode(Db::name('SystemData')->where(['name' => $name])->value('value'), true); |
||||
|
return empty($data) ? [] : $data; |
||||
|
} else { |
||||
|
return data_save('SystemData', ['name' => $name, 'value' => json_encode($value, JSON_UNESCAPED_UNICODE)], 'name'); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
if (!function_exists('sysoplog')) { |
||||
|
/** |
||||
|
* 写入系统日志 |
||||
|
* @param string $action 日志行为 |
||||
|
* @param string $content 日志内容 |
||||
|
* @return boolean |
||||
|
*/ |
||||
|
function sysoplog($action, $content) |
||||
|
{ |
||||
|
return OplogService::write($action, $content); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
if (!function_exists('local_image')) { |
||||
|
/** |
||||
|
* 下载远程文件到本地 |
||||
|
* @param string $url 远程图片地址 |
||||
|
* @return string |
||||
|
*/ |
||||
|
function local_image($url) |
||||
|
{ |
||||
|
$result = File::down($url); |
||||
|
if (isset($result['url'])) { |
||||
|
return $result['url']; |
||||
|
} else { |
||||
|
return $url; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
if (!function_exists('base64_image')) { |
||||
|
/** |
||||
|
* base64 图片上传接口 |
||||
|
* @param string $content |
||||
|
* @param string $predir |
||||
|
* @return string |
||||
|
*/ |
||||
|
function base64_image($content, $predir = 'base64/') |
||||
|
{ |
||||
|
try { |
||||
|
if (preg_match('|^data:image/(.*?);base64,|i', $content)) { |
||||
|
list($ext, $base) = explode('|||', preg_replace('|^data:image/(.*?);base64,|i', '$1|||', $content)); |
||||
|
$info = File::save($predir . md5($base) . '.' . (empty($ext) ? 'tmp' : $ext), base64_decode($base)); |
||||
|
return $info['url']; |
||||
|
} else { |
||||
|
return $content; |
||||
|
} |
||||
|
} catch (\Exception $e) { |
||||
|
return $content; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// 访问权限检查中间键 |
||||
|
Middleware::add(function (Request $request, \Closure $next) { |
||||
|
// 验证访问节点权限 |
||||
|
if (NodeService::forceAuth()) { |
||||
|
return $next($request); |
||||
|
} elseif (NodeService::islogin()) { |
||||
|
return json(['code' => 0, 'msg' => '抱歉,没有访问该操作的权限!']); |
||||
|
} else { |
||||
|
return json(['code' => 0, 'msg' => '抱歉,需要登录获取访问权限!', 'url' => url('@admin/login')]); |
||||
|
} |
||||
|
}); |
||||
File diff suppressed because it is too large
@ -0,0 +1,116 @@ |
|||||
|
{extend name='main'} |
||||
|
|
||||
|
{block name="button"} |
||||
|
|
||||
|
{if auth("admin/auth/refresh")} |
||||
|
<button data-load='{:url("refresh")}' class='layui-btn layui-btn-sm layui-btn-primary'>刷新权限</button> |
||||
|
{/if} |
||||
|
|
||||
|
{/block} |
||||
|
|
||||
|
{block name="content"} |
||||
|
<div class="think-box-shadow"> |
||||
|
<ul id="zTree" class="ztree notselect"></ul> |
||||
|
<div class="hr-line-dashed"></div> |
||||
|
<div class="layui-form-item text-center"> |
||||
|
<button class="layui-btn" data-submit-role type='button'>保存数据</button> |
||||
|
<button class="layui-btn layui-btn-danger" type='button' onclick="window.history.back()">取消编辑</button> |
||||
|
</div> |
||||
|
</div> |
||||
|
{/block} |
||||
|
|
||||
|
{block name="script"} |
||||
|
<script> |
||||
|
window.RoleAction = new function () { |
||||
|
this.data = {}; |
||||
|
this.ztree = null; |
||||
|
this.setting = { |
||||
|
view: {showLine: false, showIcon: false, dblClickExpand: false}, |
||||
|
check: {enable: true, nocheck: false, chkboxType: {"Y": "ps", "N": "ps"}}, |
||||
|
callback: { |
||||
|
beforeClick: function (id, node) { |
||||
|
node.children.length < 1 ? RoleAction.ztree.checkNode(node, !node.checked, null, true) : RoleAction.ztree.expandNode(node); |
||||
|
return false; |
||||
|
} |
||||
|
} |
||||
|
}; |
||||
|
this.renderChildren = function (list, level) { |
||||
|
var childrens = []; |
||||
|
for (var i in list) childrens.push({ |
||||
|
open: true, node: list[i].node, name: list[i].title || list[i].node, |
||||
|
checked: list[i].checked || false, children: this.renderChildren(list[i]._sub_, level + 1) |
||||
|
}); |
||||
|
return childrens; |
||||
|
}; |
||||
|
this.getData = function (that) { |
||||
|
var index = $.msg.loading(); |
||||
|
$.form.load('{:url()}', {id: '{$vo.id}', action: 'get'}, 'post', function (ret) { |
||||
|
that.data = that.renderChildren(ret.data, 1); |
||||
|
return $.msg.close(index), that.showTree(), false; |
||||
|
}); |
||||
|
}; |
||||
|
this.showTree = function () { |
||||
|
this.ztree = $.fn.zTree.init($("#zTree"), this.setting, this.data); |
||||
|
while (true) { |
||||
|
var nodes = this.ztree.getNodesByFilter(function (node) { |
||||
|
return (!node.node && node.children.length < 1); |
||||
|
}); |
||||
|
if (nodes.length < 1) break; |
||||
|
for (var i in nodes) this.ztree.removeNode(nodes[i]); |
||||
|
} |
||||
|
}; |
||||
|
this.submit = function () { |
||||
|
var nodes = [], data = this.ztree.getCheckedNodes(true); |
||||
|
for (var i in data) if (data[i].node) nodes.push(data[i].node); |
||||
|
$.form.load('{:url()}', {id: '{$vo.id}', action: 'save', nodes: nodes}, 'post'); |
||||
|
}; |
||||
|
// 刷新数据 |
||||
|
this.getData(this); |
||||
|
// 提交表单 |
||||
|
$('[data-submit-role]').on('click', function () { |
||||
|
RoleAction.submit(); |
||||
|
}); |
||||
|
}; |
||||
|
</script> |
||||
|
{/block} |
||||
|
|
||||
|
{block name="style"} |
||||
|
<link href="__ROOT__/static/plugs/ztree/zTreeStyle/zTreeStyle.css" rel="stylesheet"> |
||||
|
<script src="__ROOT__/static/plugs/ztree/ztree.all.min.js"></script> |
||||
|
<style> |
||||
|
ul.ztree li { |
||||
|
white-space: normal !important; |
||||
|
} |
||||
|
|
||||
|
ul.ztree li span.button.switch { |
||||
|
margin-right: 5px; |
||||
|
} |
||||
|
|
||||
|
ul.ztree ul ul li { |
||||
|
display: inline-block; |
||||
|
white-space: normal; |
||||
|
} |
||||
|
|
||||
|
ul.ztree > li { |
||||
|
padding: 15px 25px 15px 15px; |
||||
|
} |
||||
|
|
||||
|
ul.ztree > li > ul { |
||||
|
margin-top: 12px; |
||||
|
border-top: 1px solid rgba(0, 0, 0, .1); |
||||
|
} |
||||
|
|
||||
|
ul.ztree > li > ul > li { |
||||
|
padding: 5px; |
||||
|
} |
||||
|
|
||||
|
ul.ztree > li > a > span { |
||||
|
font-weight: 700; |
||||
|
font-size: 15px; |
||||
|
} |
||||
|
|
||||
|
ul.ztree .level2 .button.level2 { |
||||
|
background: 0 0; |
||||
|
} |
||||
|
</style> |
||||
|
{/block} |
||||
@ -0,0 +1,22 @@ |
|||||
|
<form class="layui-form layui-card" action="{:request()->url()}" data-auto="true" method="post" autocomplete="off"> |
||||
|
<div class="layui-card-body"> |
||||
|
<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"> |
||||
|
<textarea placeholder="请输入权限描述" required class="layui-textarea" name="desc">{$vo.desc|default=""}</textarea> |
||||
|
</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" type='submit'>保存数据</button> |
||||
|
<button class="layui-btn layui-btn-danger" type='button' data-confirm="确定要取消编辑吗?" data-close>取消编辑</button> |
||||
|
</div> |
||||
|
</form> |
||||
@ -0,0 +1,80 @@ |
|||||
|
{extend name='main'} |
||||
|
|
||||
|
{block name="button"} |
||||
|
|
||||
|
{if auth("admin/auth/add")} |
||||
|
<button data-modal='{:url("add")}' data-title="添加权限" class='layui-btn layui-btn-sm layui-btn-primary'>添加权限</button> |
||||
|
{/if} |
||||
|
|
||||
|
{if auth("admin/auth/remove")} |
||||
|
<button data-action='{:url("remove")}' data-rule="id#{key}" data-csrf="{:systoken('admin/auth/remove')}" data-confirm="确定要删除这些权限吗?" class='layui-btn layui-btn-sm layui-btn-primary'>删除权限</button> |
||||
|
{/if} |
||||
|
|
||||
|
{/block} |
||||
|
|
||||
|
{block name="content"} |
||||
|
|
||||
|
<div class="think-box-shadow"> |
||||
|
{include file='auth/index_search'} |
||||
|
<table class="layui-table margin-top-10" lay-skin="line"> |
||||
|
{notempty name='list'} |
||||
|
<thead> |
||||
|
<tr> |
||||
|
<th class='list-table-check-td think-checkbox'> |
||||
|
<label><input data-auto-none data-check-target='.list-check-box' type='checkbox'></label> |
||||
|
</th> |
||||
|
<th class='text-left nowrap'>权限信息</th> |
||||
|
<th class='text-left nowrap'>创建时间</th> |
||||
|
<th class="text-center nowrap">使用状态</th> |
||||
|
<th></th> |
||||
|
</tr> |
||||
|
</thead> |
||||
|
{/notempty} |
||||
|
<tbody> |
||||
|
{foreach $list as $key=>$vo} |
||||
|
<tr data-dbclick> |
||||
|
<td class='list-table-check-td think-checkbox'> |
||||
|
<label><input class="list-check-box" value='{$vo.id}' type='checkbox'></label> |
||||
|
</td> |
||||
|
<td class='text-left'> |
||||
|
权限名称:{$vo.title|default='-'}<br> |
||||
|
<p class="color-desc">权限描述:{$vo.desc|default="没有写描述哦!"}</p> |
||||
|
</td> |
||||
|
<td class="text-left nowrap"> |
||||
|
日期:{$vo.create_at|format_datetime|str_replace=' ','<br><span class="color-desc">时间:',###|raw}</span> |
||||
|
</td> |
||||
|
<td class='text-center nowrap'> |
||||
|
{eq name='vo.status' value='0'}<span class="color-red">已禁用</span>{else}<span class="color-green">使用中</span>{/eq} |
||||
|
</td> |
||||
|
<td class='text-center nowrap'> |
||||
|
|
||||
|
{if auth("admin/auth/edit")} |
||||
|
<span class="text-explode">|</span> |
||||
|
<a data-dbclick class="layui-btn layui-btn-sm" data-title="编辑权限" data-modal='{:url("admin/auth/edit")}?id={$vo.id}'>编 辑</a> |
||||
|
{/if} |
||||
|
|
||||
|
{if auth("admin/auth/apply")} |
||||
|
<a class="layui-btn layui-btn-normal layui-btn-sm" data-open='{:url("admin/auth/apply")}?id={$vo.id}'>授 权</a> |
||||
|
{/if} |
||||
|
|
||||
|
{if $vo.status eq 1 and auth("admin/auth/forbid")} |
||||
|
<a class="layui-btn layui-btn-warm layui-btn-sm" data-action="{:url('forbid')}" data-value="id#{$vo.id};status#0" data-csrf="{:systoken('admin/auth/forbid')}">禁 用</a> |
||||
|
{elseif $vo.status eq 0 and auth("admin/auth/resume")} |
||||
|
<a class="layui-btn layui-btn-warm layui-btn-sm" data-action="{:url('resume')}" data-value="id#{$vo.id};status#1" data-csrf="{:systoken('admin/auth/resume')}">启 用</a> |
||||
|
{/if} |
||||
|
|
||||
|
{if auth("admin/auth/remove")} |
||||
|
<a class="layui-btn layui-btn-danger layui-btn-sm" data-confirm="确定要删除数据吗?" data-action="{:url('remove')}" data-value="id#{$vo.id}" data-csrf="{:systoken('admin/auth/remove')}">删 除</a> |
||||
|
{/if} |
||||
|
|
||||
|
</td> |
||||
|
</tr> |
||||
|
{/foreach} |
||||
|
</tbody> |
||||
|
</table> |
||||
|
|
||||
|
{empty name='list'}<span class="notdata">没有记录哦</span>{else}{$pagehtml|raw|default=''}{/empty} |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
{/block} |
||||
@ -0,0 +1,42 @@ |
|||||
|
<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="{$Think.get.title|default=''}" 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 name="desc" value="{$Think.get.desc|default=''}" 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="status"> |
||||
|
{foreach [''=>'-- 全部状态 --','0'=>'已禁用的权限','1'=>'使用中的权限'] as $k=>$v} |
||||
|
{eq name='Think.get.status' value='$k.""'} |
||||
|
<option selected value="{$k}">{$v}</option> |
||||
|
{else} |
||||
|
<option value="{$k}">{$v}</option> |
||||
|
{/eq} |
||||
|
{/foreach} |
||||
|
</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="{$Think.get.create_at|default=''}" placeholder="请选择创建时间" class="layui-input"> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="layui-form-item layui-inline"> |
||||
|
<button class="layui-btn layui-btn-primary"><i class="layui-icon"></i> 搜 索</button> |
||||
|
</div> |
||||
|
</form> |
||||
|
</fieldset> |
||||
|
|
||||
|
<script>form.render()</script> |
||||
@ -0,0 +1,21 @@ |
|||||
|
<form onsubmit="return false;" data-auto="true" action="{:url('save')}" method="post" class='layui-form layui-card' autocomplete="off"> |
||||
|
<div class="layui-card-body"> |
||||
|
<div class="padding-right-40"> |
||||
|
<div class="color-blue padding-left-40 padding-bottom-20"> |
||||
|
文件将存储在本地服务器,需确保服务器的 public/upload 目录有写入权限,有足够的存储空间。 |
||||
|
</div> |
||||
|
<div class="layui-form-item"> |
||||
|
<label class="layui-form-label">AllowExts<br><span class="nowrap color-desc">允许类型</span></label> |
||||
|
<div class="layui-input-block"> |
||||
|
<input type="text" name="storage_local_exts" required value="{:sysconf('storage_local_exts')}" placeholder="请输入系统文件上传后缀" class="layui-input"> |
||||
|
<p class="help-block">设置系统允许上传文件的后缀,多个以英文逗号隔开。如:png,jpg,rar,doc</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="hr-line-dashed margin-left-40"></div> |
||||
|
<div class="layui-form-item text-center"> |
||||
|
<input type="hidden" name="storage_type" value="local"> |
||||
|
<button class="layui-btn" type="submit">保存配置</button> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</form> |
||||
@ -0,0 +1,79 @@ |
|||||
|
<form onsubmit="return false;" data-auto="true" action="{:url('save')}" method="post" class='layui-form layui-card' autocomplete="off"> |
||||
|
<div class="layui-card-body"> |
||||
|
<div class="padding-right-40"> |
||||
|
<div class="color-blue padding-left-40 padding-bottom-20"> |
||||
|
文件将上传到阿里云OSS空间,需要配置OSS公开访问及跨域策略(目前已实现自动创建空间及配置访问策略)。 |
||||
|
</div> |
||||
|
<div class="layui-form-item"> |
||||
|
<label class="layui-form-label">AllowExts<br><span class="nowrap color-desc">允许类型</span></label> |
||||
|
<div class="layui-input-block"> |
||||
|
<input type="text" name="storage_local_exts" required value="{:sysconf('storage_local_exts')}" placeholder="请输入系统文件上传后缀" class="layui-input"> |
||||
|
<p class="help-block">设置系统允许上传文件的后缀,多个以英文逗号隔开。如:png,jpg,rar,doc</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="layui-form-item"> |
||||
|
<label class="layui-form-label label-required">Protocol<br><span class="nowrap color-desc">访问协议</span></label> |
||||
|
<div class="layui-input-block"> |
||||
|
<!--{foreach ['http','https','auto'] as $pro}--> |
||||
|
<label class="think-radio"> |
||||
|
<!--{if sysconf('storage_oss_is_https') eq $pro}--> |
||||
|
<input checked type="radio" name="storage_oss_is_https" value="{$pro}" lay-ignore> {$pro} |
||||
|
<!--{else}--> |
||||
|
<input type="radio" name="storage_oss_is_https" value="{$pro}" lay-ignore> {$pro} |
||||
|
<!--{/if}--> |
||||
|
</label> |
||||
|
<!--{/foreach}--> |
||||
|
<p class="help-block">阿里云对象存储访问协议(http、https、auto),其中 https 需要配置证书才能使用,auto 为相对协议自动根据域名切换http与https。</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="layui-form-item"> |
||||
|
<label class="layui-form-label">Bucket<br><span class="nowrap color-desc">空间名称</span></label> |
||||
|
<div class="layui-input-block"> |
||||
|
<input type="text" name="storage_oss_bucket" required value="{:sysconf('storage_oss_bucket')}" placeholder="请输入OSS Bucket (空间名称)" class="layui-input"> |
||||
|
<p class="help-block">填写OSS存储空间名称,如:think-admin-oss(需要是全区唯一的值,不存在时会自动创建)</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="layui-form-item"> |
||||
|
<label class="layui-form-label">EndPoint<br><span class="nowrap color-desc">数据中心</span></label> |
||||
|
<div class="layui-input-block"> |
||||
|
<select required name="storage_oss_endpoint" class="layui-select" lay-search> |
||||
|
{foreach $ossPoints as $k=>$p} |
||||
|
<!--{if sysconf('storage_oss_endpoint') eq $k}--> |
||||
|
<option selected value="{$k}">{$p} <span class="font-s10 color-desc">({$k})</span></option> |
||||
|
<!--{else}--> |
||||
|
<option value="{$k}">{$p} <span class="font-s10 color-desc">({$k})</span></option> |
||||
|
<!--{/if}--> |
||||
|
{/foreach} |
||||
|
</select> |
||||
|
<p class="help-block">请选择OSS数据中心访问节点,有效值如:oss-cn-shenzhen.aliyuncs.com</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="layui-form-item"> |
||||
|
<label class="layui-form-label">AccessKey<br><span class="nowrap color-desc">访问密钥</span></label> |
||||
|
<div class="layui-input-block"> |
||||
|
<input type="text" name="storage_oss_keyid" required value="{:sysconf('storage_oss_keyid')}" maxlength="16" placeholder="请输入OSS AccessKey (访问密钥)" class="layui-input"> |
||||
|
<p class="help-block">可以在 [ 阿里云 > 个人中心 ] 设置并获取到访问密钥。</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="layui-form-item"> |
||||
|
<label class="layui-form-label">SecretKey<br><span class="nowrap color-desc">安全密钥</span></label> |
||||
|
<div class="layui-input-block"> |
||||
|
<input type="text" name="storage_oss_secret" required value="{:sysconf('storage_oss_secret')}" maxlength="30" placeholder="请输入OSS SecretKey (安全密钥)" class="layui-input"> |
||||
|
<p class="help-block">可以在 [ 阿里云 > 个人中心 ] 设置并获取到安全密钥。</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="layui-form-item"> |
||||
|
<label class="layui-form-label">Domain<br><span class="nowrap color-desc">访问域名</span></label> |
||||
|
<div class="layui-input-block"> |
||||
|
<input type="text" name="storage_oss_domain" value="{:sysconf('storage_oss_domain')}" placeholder="请输入OSS存储 Domain (访问域名)" class="layui-input"> |
||||
|
<p class="help-block">填写OSS存储外部访问域名,如:think-admin-oss.oss-cn-shenzhen.aliyuncs.com(正常情况下是自动获取的)</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="hr-line-dashed margin-left-40"></div> |
||||
|
<div class="layui-form-item text-center"> |
||||
|
<input type="hidden" name="storage_type" value="oss"> |
||||
|
<button class="layui-btn" type="submit">保存配置</button> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</form> |
||||
@ -0,0 +1,80 @@ |
|||||
|
<form onsubmit="return false;" data-auto="true" action="{:url('save')}" method="post" class='layui-form layui-card' autocomplete="off"> |
||||
|
<div class="layui-card-body"> |
||||
|
<div class="padding-right-40"> |
||||
|
<div class="color-blue padding-left-40 padding-bottom-20"> |
||||
|
文件将上传到七牛云空间(<a target="_blank" href="https://portal.qiniu.com/signup?code=3lhz6nmnwbple">点击这里免费申请10G存储</a>),申请成功后添加公开bucket并配置接口密钥。 |
||||
|
</div> |
||||
|
<div class="layui-form-item"> |
||||
|
<label class="layui-form-label">AllowExts<br><span class="nowrap color-desc">允许类型</span></label> |
||||
|
<div class="layui-input-block"> |
||||
|
<input type="text" name="storage_local_exts" required value="{:sysconf('storage_local_exts')}" placeholder="请输入系统文件上传后缀" class="layui-input"> |
||||
|
<p class="help-block">设置系统允许上传文件的后缀,多个以英文逗号隔开。如:png,jpg,rar,doc</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="layui-form-item" data-storage-type="qiniu"> |
||||
|
<label class="layui-form-label label-required">Protocol<br><span class="nowrap color-desc">访问协议</span></label> |
||||
|
<div class="layui-input-block"> |
||||
|
<!--{foreach ['http','https','auto'] as $pro}--> |
||||
|
<label class="think-radio"> |
||||
|
<!--{if sysconf('storage_qiniu_is_https') eq $pro}--> |
||||
|
<input checked type="radio" name="storage_qiniu_is_https" value="{$pro}" lay-ignore> {$pro} |
||||
|
<!--{else}--> |
||||
|
<input type="radio" name="storage_qiniu_is_https" value="{$pro}" lay-ignore> {$pro} |
||||
|
<!--{/if}--> |
||||
|
</label> |
||||
|
<!--{/foreach}--> |
||||
|
<p class="help-block">七牛云存储访问协议(http、https、auto),其中 https 需要配置证书才能使用,auto 为相对协议自动根据域名切换http与https。</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="layui-form-item" data-storage-type="qiniu"> |
||||
|
<label class="layui-form-label">Region<br><span class="nowrap color-desc label-required">存储区域</span></label> |
||||
|
<div class="layui-input-block"> |
||||
|
{foreach ['华东','华北','华南','北美'] as $area} |
||||
|
<label class="think-radio"> |
||||
|
<!--{if sysconf('storage_qiniu_region') eq $area}--> |
||||
|
<input checked type="radio" name="storage_qiniu_region" value="{$area}" lay-ignore> |
||||
|
<!--{else}--> |
||||
|
<input type="radio" name="storage_qiniu_region" value="{$area}" lay-ignore> |
||||
|
<!--{/if}--> |
||||
|
{$area} |
||||
|
</label> |
||||
|
{/foreach} |
||||
|
<p class="help-block">七牛云存储空间所在区域,需要严格对应储存所在区域才能上传文件。</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="layui-form-item" data-storage-type="qiniu"> |
||||
|
<label class="layui-form-label">Bucket<br><span class="nowrap color-desc">空间名称</span></label> |
||||
|
<div class="layui-input-block"> |
||||
|
<input type="text" name="storage_qiniu_bucket" required value="{:sysconf('storage_qiniu_bucket')}" placeholder="请输入七牛云存储 Bucket (空间名称)" class="layui-input"> |
||||
|
<p class="help-block">填写七牛云存储空间名称,如:static</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="layui-form-item" data-storage-type="qiniu"> |
||||
|
<label class="layui-form-label">Domain<br><span class="nowrap color-desc">访问域名</span></label> |
||||
|
<div class="layui-input-block"> |
||||
|
<input type="text" name="storage_qiniu_domain" required value="{:sysconf('storage_qiniu_domain')}" placeholder="请输入七牛云存储 Domain (访问域名)" class="layui-input"> |
||||
|
<p class="help-block">填写七牛云存储访问域名,如:static.ctolog.cc</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="layui-form-item" data-storage-type="qiniu"> |
||||
|
<label class="layui-form-label">AccessKey<br><span class="nowrap color-desc">访问密钥</span></label> |
||||
|
<div class="layui-input-block"> |
||||
|
<input type="text" name="storage_qiniu_access_key" required value="{:sysconf('storage_qiniu_access_key')}" placeholder="请输入七牛云 AccessKey (访问密钥)" class="layui-input"> |
||||
|
<p class="help-block">可以在 [ 七牛云 > 个人中心 ] 设置并获取到访问密钥。</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="layui-form-item" data-storage-type="qiniu"> |
||||
|
<label class="layui-form-label">SecretKey<br><span class="nowrap color-desc">安全密钥</span></label> |
||||
|
<div class="layui-input-block"> |
||||
|
<input type="text" name="storage_qiniu_secret_key" required value="{:sysconf('storage_qiniu_secret_key')}" maxlength="43" placeholder="请输入七牛云 SecretKey (安全密钥)" class="layui-input"> |
||||
|
<p class="help-block">可以在 [ 七牛云 > 个人中心 ] 设置并获取到安全密钥。</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="hr-line-dashed margin-left-40"></div> |
||||
|
<div class="layui-form-item text-center"> |
||||
|
<input type="hidden" name="storage_type" value="qiniu"> |
||||
|
<button class="layui-btn" type="submit">保存配置</button> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</form> |
||||
@ -0,0 +1,32 @@ |
|||||
|
<div class="layui-card layui-form"> |
||||
|
<div class="layui-card-body"> |
||||
|
<div class="layui-form-item padding-top-20"> |
||||
|
<label class="layui-form-label">Storage<br><span class="nowrap color-desc">存储类型</span></label> |
||||
|
<div class="layui-input-block"> |
||||
|
{foreach ['local'=>'本地服务器存储','qiniu'=>'七牛云对象存储','oss'=>'阿里云OSS存储'] as $k=>$v} |
||||
|
<input type="radio" data-storagetype="{$k}" name="storage_type" value="{$k}" title="{$v}" lay-filter="storage_type"> |
||||
|
{/foreach} |
||||
|
<p class="help-block">请选择文件存储类型,其它云储存需要配置正确的参数才可以上传文件哦!</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div class="padding-bottom-10"> |
||||
|
<div data-type="oss">{include file='config/info-storage-oss'}</div> |
||||
|
<div data-type="local">{include file='config/info-storage-local'}</div> |
||||
|
<div data-type="qiniu">{include file='config/info-storage-qiniu'}</div> |
||||
|
</div> |
||||
|
|
||||
|
<script> |
||||
|
apply('{:sysconf("storage_type")}'); |
||||
|
form.render().on('radio(storage_type)', function (data) { |
||||
|
apply(data.value); |
||||
|
}); |
||||
|
|
||||
|
function apply(value) { |
||||
|
this.$active = $("[data-storagetype='" + value + "']").trigger('click'); |
||||
|
if (this.$active.size() < 1) $("[data-storagetype]:first").trigger('click'); |
||||
|
$('[data-type="' + value + '"]').show().siblings('[data-type]').hide(); |
||||
|
} |
||||
|
</script> |
||||
@ -0,0 +1,54 @@ |
|||||
|
<form onsubmit="return false;" data-auto="true" action="{:url('save')}" method="post" class='layui-form layui-card' autocomplete="off"> |
||||
|
<div class="layui-card-body"> |
||||
|
<div class="padding-right-40 padding-bottom-10 margin-top-20"> |
||||
|
<div class="layui-form-item"> |
||||
|
<label class="layui-form-label">Name<br><span class="nowrap color-desc">程序名称</span></label> |
||||
|
<div class="layui-input-block"> |
||||
|
<input name="app_name" required placeholder="请输入程序名称" value="{:sysconf('app_name')}" class="layui-input"> |
||||
|
<p class="help-block">当前程序名称,在后台主标题上显示 {:sysconf('app_name')}</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="layui-form-item"> |
||||
|
<label class="layui-form-label">Version<br><span class="nowrap color-desc">程序版本</span></label> |
||||
|
<div class="layui-input-block"> |
||||
|
<input name="app_version" placeholder="请输入程序版本" value="{:sysconf('app_version')}" class="layui-input"> |
||||
|
<p class="help-block">当前程序版本号,在后台主标题上标显示版本 {:sysconf('app_version')}</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="layui-form-item"> |
||||
|
<label class="layui-form-label">Website<br><span class="nowrap color-desc">网站名称</span></label> |
||||
|
<div class="layui-input-block"> |
||||
|
<input name="site_name" required placeholder="请输入网站名称" value="{:sysconf('site_name')}" class="layui-input"> |
||||
|
<p class="help-block">网站名称,将在浏览器的标签上显示 {:sysconf('site_name')}</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="layui-form-item"> |
||||
|
<label class="layui-form-label">Browser<br><span class="nowrap color-desc">浏览器图标</span></label> |
||||
|
<div class="layui-input-block"> |
||||
|
<img alt="icon" data-tips-image style="height:auto;max-height:32px;min-width:32px" src="{:sysconf('site_icon')}"/> |
||||
|
<input type="hidden" name="site_icon" onchange="$(this).prev('img').attr('src', this.value)" value="{:sysconf('site_icon')}" class="layui-input"> |
||||
|
<a class="margin-left-10" data-file="btn" data-type="ico,png" data-field="site_icon">上传图片</a> |
||||
|
<p class="help-block">建议上传 ICO 图标的尺寸为 128x128px,此图标用于网站标题前,<a href="http://www.favicon-icon-generator.com/" target="_blank">ICON在线制作</a></p> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="layui-form-item"> |
||||
|
<label class="layui-form-label">Copyright<br><span class="nowrap color-desc">版权信息</span></label> |
||||
|
<div class="layui-input-block"> |
||||
|
<input name="site_copy" required placeholder="请输入版权信息" value="{:sysconf('site_copy')}" class="layui-input"> |
||||
|
<p class="help-block">程序的版权信息设置,在后台登录页面显示版本信息</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="layui-form-item"> |
||||
|
<label class="layui-form-label">Miitbeian<br><span class="nowrap color-desc">网站备案号</span></label> |
||||
|
<div class="layui-input-block"> |
||||
|
<input name="miitbeian" placeholder="请输入网站备案号" value="{:sysconf('miitbeian')}" class="layui-input"> |
||||
|
<p class="help-block">网站备案号,可以在<a target="_blank" href="http://www.miitbeian.gov.cn">备案管理中心</a>查询获取,将在登录页面下面显示</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="hr-line-dashed margin-left-40"></div> |
||||
|
<div class="layui-form-item text-center padding-bottom-10"> |
||||
|
<button class="layui-btn" type="submit">保存配置</button> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</form> |
||||
@ -0,0 +1,29 @@ |
|||||
|
{extend name="main"} |
||||
|
|
||||
|
{block name="content"} |
||||
|
|
||||
|
<div class="layui-tab layui-tab-card think-bg-white"> |
||||
|
<ul class="layui-tab-title notselect"> |
||||
|
<li data-type='website'>网站参数设置</li> |
||||
|
<li data-type="storage">文件存储配置</li> |
||||
|
</ul> |
||||
|
<div class="layui-tab-content"> |
||||
|
<div class="layui-tab-item">{include file='config/info-website'}</div> |
||||
|
<div class="layui-tab-item">{include file='config/info-storage'}</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<script> |
||||
|
(function (storage) { |
||||
|
(function (type, $default, $checked) { |
||||
|
$default = $('.layui-tab ul.layui-tab-title li:first'); |
||||
|
$checked = $('.layui-tab ul.layui-tab-title li[data-type="' + type + '"]'); |
||||
|
($checked.length > 0 ? $checked : $default).trigger('click'); |
||||
|
})(layui.data(storage)['type'] || ''); |
||||
|
$('.layui-tab ul.layui-tab-title li[data-type]').on('click', function () { |
||||
|
layui.data(storage, {key: 'type', value: this.getAttribute('data-type')}); |
||||
|
}); |
||||
|
})('website-config-type'); |
||||
|
</script> |
||||
|
|
||||
|
{/block} |
||||
@ -0,0 +1,125 @@ |
|||||
|
<!DOCTYPE html> |
||||
|
<html lang="zh"> |
||||
|
|
||||
|
<head> |
||||
|
<title>{block name="title"}{$title|default=''}{if !empty($title)} · {/if}{:sysconf('site_name')}{/block}</title> |
||||
|
<meta charset="utf-8"> |
||||
|
<meta name="renderer" content="webkit"> |
||||
|
<meta name="format-detection" content="telephone=no"> |
||||
|
<meta name="apple-mobile-web-app-capable" content="yes"> |
||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> |
||||
|
<meta name="apple-mobile-web-app-status-bar-style" content="black"> |
||||
|
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=0.4"> |
||||
|
<link rel="shortcut icon" href="{:sysconf('site_icon')}"> |
||||
|
<link rel="stylesheet" href="__ROOT__/static/plugs/awesome/fonts.css?at={:date('md')}"> |
||||
|
<link rel="stylesheet" href="__ROOT__/static/plugs/layui/css/layui.css?at={:date('md')}"> |
||||
|
<link rel="stylesheet" href="__ROOT__/static/theme/css/console.css?at={:date('md')}"> |
||||
|
{block name="style"}{/block} |
||||
|
<script>window.ROOT_URL = '__ROOT__';</script> |
||||
|
<script src="__ROOT__/static/plugs/jquery/pace.min.js"></script> |
||||
|
</head> |
||||
|
|
||||
|
<body class="layui-layout-body"> |
||||
|
{block name='body'} |
||||
|
<div class="layui-layout layui-layout-admin layui-layout-left-hide"> |
||||
|
|
||||
|
<!-- 顶部菜单 开始 --> |
||||
|
<div class="layui-header notselect"> |
||||
|
<a href="{:url('@')}" class="layui-logo layui-elip"> |
||||
|
{:sysconf('app_name')} {if sysconf('app_version')}<sup class="padding-left-5">{:sysconf('app_version')}</sup>{/if} |
||||
|
</a> |
||||
|
<ul class="layui-nav layui-layout-left"> |
||||
|
<li class="layui-nav-item" lay-unselect> |
||||
|
<a class="text-center" data-target-menu-type> |
||||
|
<i class="layui-icon layui-icon-spread-left"></i> |
||||
|
</a> |
||||
|
</li> |
||||
|
{foreach $menus as $oneMenu} |
||||
|
<li class="layui-nav-item"> |
||||
|
<a data-menu-node="m-{$oneMenu.id}" data-open="{$oneMenu.url}"> |
||||
|
{notempty name='oneMenu.icon'}<span class='{$oneMenu.icon} padding-right-5'></span>{/notempty} |
||||
|
<span>{$oneMenu.title|default=''}</span> |
||||
|
</a> |
||||
|
</li> |
||||
|
{/foreach} |
||||
|
</ul> |
||||
|
<ul class="layui-nav layui-layout-right"> |
||||
|
<li lay-unselect class="layui-nav-item"><a data-reload><i class="layui-icon layui-icon-refresh-3"></i></a></li> |
||||
|
{notempty name='Think.session.admin_user.username'} |
||||
|
<li class="layui-nav-item"> |
||||
|
<dl class="layui-nav-child"> |
||||
|
<dd lay-unselect><a data-modal="{:url('admin/index/info',['id'=>session('admin_user.id')])}"><i class="layui-icon layui-icon-set-fill margin-right-5"></i>基本资料</a></dd> |
||||
|
<dd lay-unselect><a data-modal="{:url('admin/index/pass',['id'=>session('admin_user.id')])}"><i class="layui-icon layui-icon-component margin-right-5"></i>安全设置</a></dd> |
||||
|
{if auth('admin/index/buildoptimize')} |
||||
|
<dd lay-unselect><a data-modal="{:url('admin/index/buildOptimize')}"><i class="layui-icon layui-icon-template-1 margin-right-5"></i>压缩发布</a></dd> |
||||
|
{/if} |
||||
|
{if auth('admin/index/clearruntime')} |
||||
|
<dd lay-unselect><a data-modal="{:url('admin/index/clearRuntime')}"><i class="layui-icon layui-icon-fonts-clear margin-right-5"></i>清理缓存</a></dd> |
||||
|
{/if} |
||||
|
<dd lay-unselect><a data-confirm="确定要退出登录吗?" data-load="{:url('admin/login/out')}"><i class="layui-icon layui-icon-release margin-right-5"></i>退出登录</a></dd> |
||||
|
</dl> |
||||
|
<a><span><i class="layui-icon layui-icon-username margin-right-5"></i> {:session('admin_user.username')}</span></a> |
||||
|
</li> |
||||
|
{else} |
||||
|
<li class="layui-nav-item"> |
||||
|
<a data-href="{:url('@admin/login')}"><i class="layui-icon layui-icon-username"></i> 立即登录</a> |
||||
|
</li> |
||||
|
{/notempty} |
||||
|
</ul> |
||||
|
</div> |
||||
|
<!-- 顶部菜单 结束 --> |
||||
|
|
||||
|
<!-- 左则菜单 开始 --> |
||||
|
<div class="layui-side layui-bg-black notselect"> |
||||
|
<div class="layui-side-scroll"> |
||||
|
|
||||
|
{foreach $menus as $oneMenu} |
||||
|
{notempty name='oneMenu.sub'} |
||||
|
<ul class="layui-nav layui-nav-tree layui-hide" data-menu-layout="m-{$oneMenu.id}"> |
||||
|
{foreach $oneMenu.sub as $twoMenu} |
||||
|
{empty name='twoMenu.sub'} |
||||
|
<li class="layui-nav-item"> |
||||
|
<a data-target-tips="{$twoMenu.title}" data-menu-node="m-{$oneMenu.id}-{$twoMenu.id}" data-open="{$twoMenu.url}"> |
||||
|
<span class='{$twoMenu.icon|default="layui-icon layui-icon-link"}'></span> |
||||
|
<span class="nav-text padding-left-5">{$twoMenu.title}</span> |
||||
|
</a> |
||||
|
</li> |
||||
|
{else} |
||||
|
<li class="layui-nav-item" data-submenu-layout='m-{$oneMenu.id}-{$twoMenu.id}'> |
||||
|
<a data-target-tips="{$twoMenu.title}" style="background:#393D49"> |
||||
|
<span class='nav-icon layui-hide {$twoMenu.icon|default="layui-icon layui-icon-triangle-d"}'></span> |
||||
|
<span class="nav-text padding-left-5">{$twoMenu.title}</span> |
||||
|
</a> |
||||
|
<dl class="layui-nav-child"> |
||||
|
{foreach $twoMenu.sub as $thrMenu} |
||||
|
<dd> |
||||
|
<a data-target-tips="{$thrMenu.title}" data-open="{$thrMenu.url}" data-menu-node="m-{$oneMenu.id}-{$twoMenu.id}-{$thrMenu.id}"> |
||||
|
<span class='nav-icon padding-left-5 {$thrMenu.icon|default="layui-icon layui-icon-link"}'></span> |
||||
|
<span class="nav-text padding-left-5">{$thrMenu.title}</span> |
||||
|
</a> |
||||
|
</dd> |
||||
|
{/foreach} |
||||
|
</dl> |
||||
|
</li> |
||||
|
{/empty} |
||||
|
{/foreach} |
||||
|
</ul> |
||||
|
{/notempty} |
||||
|
{/foreach} |
||||
|
</div> |
||||
|
</div> |
||||
|
<!-- 左则菜单 结束 --> |
||||
|
|
||||
|
<!-- 主体内容 开始 --> |
||||
|
<div class="layui-body layui-bg-gray">{block name='content'}{/block}</div> |
||||
|
<!-- 主体内容 结束 --> |
||||
|
|
||||
|
</div> |
||||
|
{/block} |
||||
|
<script src="__ROOT__/static/plugs/layui/layui.all.js"></script> |
||||
|
<script src="__ROOT__/static/plugs/require/require.js"></script> |
||||
|
<script src="__ROOT__/static/admin.js"></script> |
||||
|
{block name='script'}{/block} |
||||
|
</body> |
||||
|
|
||||
|
</html> |
||||
@ -0,0 +1,207 @@ |
|||||
|
{extend name='main'} |
||||
|
|
||||
|
{block name='content'} |
||||
|
|
||||
|
<style> |
||||
|
|
||||
|
.store-total-container { |
||||
|
font-size: 14px; |
||||
|
margin-bottom: 20px; |
||||
|
letter-spacing: 1px; |
||||
|
} |
||||
|
|
||||
|
.store-total-container .store-total-icon { |
||||
|
top: 45%; |
||||
|
right: 8%; |
||||
|
font-size: 65px; |
||||
|
position: absolute; |
||||
|
color: rgba(255, 255, 255, 0.4); |
||||
|
} |
||||
|
|
||||
|
.store-total-container .store-total-item { |
||||
|
color: #fff; |
||||
|
line-height: 4em; |
||||
|
padding: 15px 25px; |
||||
|
position: relative; |
||||
|
} |
||||
|
|
||||
|
.store-total-container .store-total-item > div:nth-child(2) { |
||||
|
font-size: 46px; |
||||
|
line-height: 46px; |
||||
|
} |
||||
|
|
||||
|
</style> |
||||
|
|
||||
|
<div class="think-box-shadow store-total-container notselect"> |
||||
|
<div class="margin-bottom-15">商城统计</div> |
||||
|
<div class="layui-row layui-col-space15"> |
||||
|
<div class="layui-col-sm6 layui-col-md3"> |
||||
|
<div class="store-total-item nowrap" style="background:linear-gradient(-125deg,#57bdbf,#2f9de2)"> |
||||
|
<div>商品总量</div> |
||||
|
<div>63</div> |
||||
|
<div>当前商品总数量</div> |
||||
|
</div> |
||||
|
<i class="store-total-icon layui-icon layui-icon-template-1"></i> |
||||
|
</div> |
||||
|
<div class="layui-col-sm6 layui-col-md3"> |
||||
|
<div class="store-total-item nowrap" style="background:linear-gradient(-125deg,#ff7d7d,#fb2c95)"> |
||||
|
<div>用户总量</div> |
||||
|
<div>1,634</div> |
||||
|
<div>当前用户总数量</div> |
||||
|
</div> |
||||
|
<i class="store-total-icon layui-icon layui-icon-user"></i> |
||||
|
</div> |
||||
|
<div class="layui-col-sm6 layui-col-md3"> |
||||
|
<div class="store-total-item nowrap" style="background:linear-gradient(-113deg,#c543d8,#925cc3)"> |
||||
|
<div>订单总量</div> |
||||
|
<div>148</div> |
||||
|
<div>已付款订单总数量</div> |
||||
|
</div> |
||||
|
<i class="store-total-icon layui-icon layui-icon-read"></i> |
||||
|
</div> |
||||
|
<div class="layui-col-sm6 layui-col-md3"> |
||||
|
<div class="store-total-item nowrap" style="background:linear-gradient(-141deg,#ecca1b,#f39526)"> |
||||
|
<div>评价总量</div> |
||||
|
<div>0</div> |
||||
|
<div>订单评价总数量</div> |
||||
|
</div> |
||||
|
<i class="store-total-icon layui-icon layui-icon-survey"></i> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div class="think-box-shadow store-total-container"> |
||||
|
<div class="margin-bottom-15">实时概况</div> |
||||
|
<div class="layui-row layui-col-space15"> |
||||
|
<div class="layui-col-md6 margin-bottom-15"> |
||||
|
<div class="layui-row"> |
||||
|
<div class="layui-col-xs3 text-center"> |
||||
|
<i class="layui-icon color-blue" style="font-size:60px;line-height:72px"></i> |
||||
|
</div> |
||||
|
<div class="layui-col-xs4"> |
||||
|
<div class="font-s14">销售额(元)</div> |
||||
|
<div class="font-s16">1351.00</div> |
||||
|
<div class="font-s12 color-desc">昨日:974.00</div> |
||||
|
</div> |
||||
|
<div class="layui-col-xs5"> |
||||
|
<div class="font-s14">支付订单数</div> |
||||
|
<div class="font-s16">106</div> |
||||
|
<div class="font-s12 color-desc">昨日:76</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="layui-col-md6 margin-bottom-15"> |
||||
|
<div class="layui-row"> |
||||
|
<div class="layui-col-xs3 text-center"> |
||||
|
<i class="layui-icon color-blue" style="font-size:60px;line-height:72px"></i> |
||||
|
</div> |
||||
|
<div class="layui-col-xs4"> |
||||
|
<div class="font-s14">新增用户数</div> |
||||
|
<div class="font-s16">327</div> |
||||
|
<div class="font-s12 color-desc">昨日:238</div> |
||||
|
</div> |
||||
|
<div class="layui-col-xs5"> |
||||
|
<div class="font-s14">下单用户数</div> |
||||
|
<div class="font-s16">69</div> |
||||
|
<div class="font-s12 color-desc">昨日:34</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div class="layui-row layui-col-space15"> |
||||
|
<div class="layui-col-md6"> |
||||
|
<div class="think-box-shadow"> |
||||
|
<table class="layui-table" lay-skin="line" lay-even> |
||||
|
<caption class="text-left margin-bottom-15 font-s14">系统信息</caption> |
||||
|
<colgroup> |
||||
|
<col width="30%"> |
||||
|
</colgroup> |
||||
|
<tbody> |
||||
|
<tr> |
||||
|
<td>当前程序版本</td> |
||||
|
<td>{:sysconf('app_version')}</td> |
||||
|
</tr> |
||||
|
<tr> |
||||
|
<td>运行PHP版本</td> |
||||
|
<td>{$Think.PHP_VERSION}</td> |
||||
|
</tr> |
||||
|
<tr> |
||||
|
<td>ThinkPHP版本</td> |
||||
|
<td>{$think_ver}</td> |
||||
|
</tr> |
||||
|
<tr> |
||||
|
<td>MySQL数据库版本</td> |
||||
|
<td>{$mysql_ver}</td> |
||||
|
</tr> |
||||
|
<tr> |
||||
|
<td>服务器操作系统</td> |
||||
|
<td>{:php_uname('s')}</td> |
||||
|
</tr> |
||||
|
<tr> |
||||
|
<td>WEB运行环境</td> |
||||
|
<td>{:php_sapi_name()}</td> |
||||
|
</tr> |
||||
|
<tr> |
||||
|
<td>上传大小限制</td> |
||||
|
<td>{:ini_get('upload_max_filesize')}</td> |
||||
|
</tr> |
||||
|
<tr> |
||||
|
<td>POST大小限制</td> |
||||
|
<td>{:ini_get('post_max_size')}</td> |
||||
|
</tr> |
||||
|
</tbody> |
||||
|
</table> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="layui-col-md6"> |
||||
|
<div class="think-box-shadow"> |
||||
|
<table class="layui-table" lay-skin="line" lay-even> |
||||
|
<caption class="text-left margin-bottom-15 font-s14">产品团队</caption> |
||||
|
<colgroup> |
||||
|
<col width="30%"> |
||||
|
</colgroup> |
||||
|
<tbody> |
||||
|
<tr> |
||||
|
<td>产品名称</td> |
||||
|
<td>ThinkAdmin</td> |
||||
|
</tr> |
||||
|
<tr> |
||||
|
<td>在线体验</td> |
||||
|
<td><a target="_blank" href="http://demo.thinkadmin.top">http://demo.thinkadmin.top</a></td> |
||||
|
</tr> |
||||
|
<tr> |
||||
|
<td>官方QQ群</td> |
||||
|
<td> |
||||
|
<a href="http://shang.qq.com/wpa/qunwpa?idkey=ae25cf789dafbef62e50a980ffc31242f150bc61a61164458216dd98c411832a"> |
||||
|
<img src="//pub.idqqimg.com/wpa/images/group.png" style="height:18px;width:auto" target="_blank"> |
||||
|
</a> |
||||
|
</td> |
||||
|
</tr> |
||||
|
<tr> |
||||
|
<td>项目地址</td> |
||||
|
<td><a target="_blank" href="https://github.com/zoujingli/ThinkAdmin">https://github.com/zoujingli/ThinkAdmin</a></td> |
||||
|
</tr> |
||||
|
<tr> |
||||
|
<td>BUG反馈</td> |
||||
|
<td><a target="_blank" href="https://github.com/zoujingli/ThinkAdmin/issues">https://github.com/zoujingli/ThinkAdmin/issues</a></td> |
||||
|
</tr> |
||||
|
<tr> |
||||
|
<td>开发团队</td> |
||||
|
<td><a href="http://www.cuci.cc" target="_blank">广州楚才信息科技有限公司</a></td> |
||||
|
</tr> |
||||
|
<tr> |
||||
|
<td>团队官网</td> |
||||
|
<td><a target="_blank" href="http://www.cuci.cc">http://www.cuci.cc</a></td> |
||||
|
</tr> |
||||
|
<tr> |
||||
|
<td>办公地址</td> |
||||
|
<td>广州市天河区东圃一横路东泷商贸中心G02</td> |
||||
|
</tr> |
||||
|
</tbody> |
||||
|
</table> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
{/block} |
||||
@ -0,0 +1,50 @@ |
|||||
|
{extend name="admin@index/index"} |
||||
|
|
||||
|
{block name="body"} |
||||
|
<div class="login-container" data-supersized="__ROOT__/static/theme/img/login/bg1.jpg,__ROOT__/static/theme/img/login/bg2.jpg"> |
||||
|
<div class="header notselect layui-hide-xs"> |
||||
|
<a href="{:url('@')}" class="title">{:sysconf('app_name')}<span class="padding-left-5 font-s10">{:sysconf('app_version')}</span></a> |
||||
|
{notempty name='devMode'} |
||||
|
<a class="pull-right layui-anim layui-anim-fadein" href='https://gitee.com/zoujingli/ThinkAdmin'> |
||||
|
<img src='https://gitee.com/zoujingli/ThinkAdmin/widgets/widget_1.svg' alt='Fork me on Gitee'> |
||||
|
</a> |
||||
|
{/notempty} |
||||
|
</div> |
||||
|
<form data-login-form onsubmit="return false" method="post" class="layui-anim layui-anim-upbit" autocomplete="off"> |
||||
|
<h2 class="notselect">系统管理</h2> |
||||
|
<ul> |
||||
|
<li class="username"> |
||||
|
<label> |
||||
|
<i class="layui-icon layui-icon-username"></i> |
||||
|
<input class="layui-input" required pattern="^\S{4,}$" name="username" autofocus autocomplete="off" placeholder="请输入账号"> |
||||
|
</label> |
||||
|
</li> |
||||
|
<li class="password"> |
||||
|
<label> |
||||
|
<i class="layui-icon layui-icon-password"></i> |
||||
|
<input class="layui-input" required pattern="^\S{4,}$" name="password" maxlength="32" type="password" autocomplete="off" placeholder="请输入密码"> |
||||
|
</label> |
||||
|
</li> |
||||
|
<li class="text-center padding-top-20"> |
||||
|
<input type="hidden" name="skey" value="{$loginskey|default=''}"> |
||||
|
<button type="submit" class="layui-btn layui-disabled full-width" data-form-loaded="立即登入">正在载入</button> |
||||
|
</li> |
||||
|
</ul> |
||||
|
</form> |
||||
|
<div class="footer notselect"> |
||||
|
<p class="layui-hide-xs"><a target="_blank" href="https://www.google.cn/chrome">推荐使用谷歌浏览器</a></p> |
||||
|
{:sysconf('site_copy')} |
||||
|
{if sysconf('miitbeian')}<span class="padding-5">|</span><a target="_blank" href="http://www.miitbeian.gov.cn">{:sysconf('miitbeian')}</a>{/if} |
||||
|
</div> |
||||
|
</div> |
||||
|
{/block} |
||||
|
|
||||
|
{block name='style'} |
||||
|
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1"> |
||||
|
<script>if (location.href.indexOf('#') > -1) location.replace(location.href.split('#')[0])</script> |
||||
|
<link rel="stylesheet" href="__ROOT__/static/theme/css/login.css"> |
||||
|
{/block} |
||||
|
|
||||
|
{block name='script'} |
||||
|
<script src="__ROOT__/static/plugs/supersized/supersized.3.2.7.min.js"></script> |
||||
|
{/block} |
||||
@ -0,0 +1,11 @@ |
|||||
|
<div class="layui-card layui-bg-gray"> |
||||
|
{block name='style'}{/block} |
||||
|
{notempty name='title'} |
||||
|
<div class="layui-card-header layui-anim layui-anim-fadein 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 layui-anim layui-anim-upbit">{block name='content'}{/block}</div> |
||||
|
{block name='script'}{/block} |
||||
|
</div> |
||||
@ -0,0 +1,88 @@ |
|||||
|
<form class="layui-form layui-card" action="{:request()->url()}" data-auto="true" method="post" autocomplete="off"> |
||||
|
|
||||
|
<div class="layui-card-body"> |
||||
|
|
||||
|
<div class="layui-form-item"> |
||||
|
<label class="layui-form-label">上级菜单</label> |
||||
|
<div class="layui-input-block"> |
||||
|
<select name='pid' class='layui-select full-width' lay-ignore> |
||||
|
<!--{foreach $menus as $menu}--> |
||||
|
<!--{eq name='menu.id' value='$vo.pid|default=0'}--> |
||||
|
<option selected value='{$menu.id}'>{$menu.spl|raw}{$menu.title}</option> |
||||
|
<!--{else}--> |
||||
|
<option value='{$menu.id}'>{$menu.spl|raw}{$menu.title}</option> |
||||
|
<!--{/eq}--> |
||||
|
<!--{/foreach}--> |
||||
|
</select> |
||||
|
<p class="help-block"><b>必选</b>,请选择上级菜单或顶级菜单(目前最多支持三级菜单)</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div class="layui-form-item"> |
||||
|
<label class="layui-form-label">菜单名称</label> |
||||
|
<div class="layui-input-block"> |
||||
|
<input name="title" value='{$vo.title|default=""}' required placeholder="请输入菜单名称" class="layui-input"> |
||||
|
<p class="help-block"><b>必填</b>,请填写菜单名称(如:系统管理),建议字符不要太长,一般4-6个汉字</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div class="layui-form-item"> |
||||
|
<label class="layui-form-label">菜单链接</label> |
||||
|
<div class="layui-input-block"> |
||||
|
<input onblur="this.value=this.value === ''?'#':this.value" name="url" required placeholder="请输入菜单链接" value="{$vo.url|default='#'}" class="layui-input"> |
||||
|
<p class="help-block"> |
||||
|
<b>必填</b>,请填写系统节点(如:admin/user/index),节点加入权限管理时菜单才会自动隐藏,非规则内的不会隐藏; |
||||
|
<br>正常情况下,在输入的时候会有自动提示。如果是上级菜单时,请填写"#"符号,不要填写地址或节点地址 |
||||
|
</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div class="layui-form-item"> |
||||
|
<label class="layui-form-label">链接参数</label> |
||||
|
<div class="layui-input-block"> |
||||
|
<input name="params" placeholder="请输入链接参数" value="{$vo.params|default=''}" class="layui-input"> |
||||
|
<p class="help-block"><b>可选</b>,设置菜单链接的GET访问参数(如:name=1&age=3)</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div class="layui-form-item"> |
||||
|
<label class="layui-form-label">菜单图标</label> |
||||
|
<div class="layui-input-block"> |
||||
|
<div class="layui-input-inline"> |
||||
|
<input placeholder="请输入或选择图标" name="icon" value='{$vo.icon|default=""}' class="layui-input"> |
||||
|
</div> |
||||
|
<span style="padding:0 12px;min-width:45px" class='layui-btn layui-btn-primary'> |
||||
|
<i style="font-size:1.2em;margin:0" class='{$vo.icon|default=""}'></i> |
||||
|
</span> |
||||
|
<button data-icon='icon' type='button' class='layui-btn layui-btn-primary'>选择图标</button> |
||||
|
<p class="help-block"><b>可选</b>,设置菜单选项前置图标,目前只支持 Font Awesome 5.2.0 字体图标</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
<div class="hr-line-dashed"></div> |
||||
|
|
||||
|
<div class="layui-form-item text-center"> |
||||
|
{notempty name='vo.id'}<input type='hidden' value='{$vo.id}' name='id'>{/notempty} |
||||
|
<button class="layui-btn" type='submit'>保存数据</button> |
||||
|
<button class="layui-btn layui-btn-danger" type='button' data-confirm="确定要取消编辑吗?" data-close>取消编辑</button> |
||||
|
</div> |
||||
|
|
||||
|
</form> |
||||
|
|
||||
|
{block name='script'} |
||||
|
<script> |
||||
|
require(['jquery.autocompleter'], function () { |
||||
|
$('[name="icon"]').on('change', function () { |
||||
|
$(this).parent().next().find('i').get(0).className = this.value |
||||
|
}); |
||||
|
$('input[name=url]').autocompleter({ |
||||
|
limit: 6, highlightMatches: true, template: '{{ label }} <span> {{ title }} </span>', source: (function (subjects, data) { |
||||
|
for (var i in subjects) data.push({value: subjects[i].node, label: subjects[i].node, title: subjects[i].title}); |
||||
|
return data; |
||||
|
})(JSON.parse('{$nodes|raw|json_encode}'), []) |
||||
|
}); |
||||
|
}); |
||||
|
</script> |
||||
|
{/block} |
||||
@ -0,0 +1,80 @@ |
|||||
|
{extend name='main'} |
||||
|
|
||||
|
{block name="button"} |
||||
|
|
||||
|
{if auth("admin/menu/add")} |
||||
|
<button data-modal='{:url("add")}' data-title="添加菜单" class='layui-btn layui-btn-sm layui-btn-primary'>添加菜单</button> |
||||
|
{/if} |
||||
|
|
||||
|
{if auth("admin/menu/remove")} |
||||
|
<button data-action='{:url("remove")}' data-csrf="{:systoken('admin/menu/remove')}" data-rule="id#{key}" class='layui-btn layui-btn-sm layui-btn-primary'>删除菜单</button> |
||||
|
{/if} |
||||
|
|
||||
|
{/block} |
||||
|
|
||||
|
{block name="content"} |
||||
|
<div class="think-bg-white"> |
||||
|
{empty name='list'} |
||||
|
<blockquote class="layui-elem-quote">没 有 记 录 哦!</blockquote> |
||||
|
{else} |
||||
|
<table class="layui-table" lay-skin="line"> |
||||
|
<thead> |
||||
|
<tr> |
||||
|
<th class='list-table-check-td think-checkbox'> |
||||
|
<input data-auto-none data-check-target='.list-check-box' type='checkbox'> |
||||
|
</th> |
||||
|
<th class='list-table-sort-td'> |
||||
|
<button type="button" data-reload class="layui-btn layui-btn-xs">刷 新</button> |
||||
|
</th> |
||||
|
<th class='text-center' style="width:30px"></th> |
||||
|
<th style="width:180px"></th> |
||||
|
<th class='layui-hide-xs' style="width:180px"></th> |
||||
|
<th colspan="2"></th> |
||||
|
</tr> |
||||
|
</thead> |
||||
|
<tbody> |
||||
|
{foreach $list as $key=>$vo} |
||||
|
<tr data-dbclick> |
||||
|
<td class='list-table-check-td think-checkbox'> |
||||
|
<input class="list-check-box" value='{$vo.ids}' type='checkbox'> |
||||
|
</td> |
||||
|
<td class='list-table-sort-td'> |
||||
|
<input data-action-blur="{:request()->url()}" data-value="id#{$vo.id};action#sort;sort#{value}" data-loading="false" value="{$vo.sort}" class="list-sort-input"> |
||||
|
</td> |
||||
|
<td class='text-center'><i class="{$vo.icon} font-s18"></i></td> |
||||
|
<td class="nowrap"><span class="color-desc">{$vo.spl|raw}</span>{$vo.title}</td> |
||||
|
<td class='layui-hide-xs'>{$vo.url}</td> |
||||
|
<td class='text-center nowrap'>{eq name='vo.status' value='0'}<span class="color-red">已禁用</span>{else}<span class="color-green">使用中</span>{/eq}</td> |
||||
|
<td class='text-center nowrap notselect'> |
||||
|
|
||||
|
{if auth("admin/menu/add")} |
||||
|
<span class="text-explode">|</span> |
||||
|
<!--{if $vo.spt < 2}--> |
||||
|
<a class="layui-btn layui-btn-xs layui-btn-primary" data-title="添加子菜单" data-modal='{:url("add")}?pid={$vo.id}'>添 加</a> |
||||
|
<!--{else}--> |
||||
|
<a class="layui-btn layui-btn-xs layui-btn-disabled">添 加</a> |
||||
|
<!--{/if}--> |
||||
|
{/if} |
||||
|
|
||||
|
{if auth("admin/menu/edit")} |
||||
|
<a data-dbclick class="layui-btn layui-btn-xs" data-title="编辑菜单" data-modal='{:url("admin/menu/edit")}?id={$vo.id}'>编 辑</a> |
||||
|
{/if} |
||||
|
|
||||
|
{if $vo.status eq 1 and auth("admin/menu/forbid")} |
||||
|
<a class="layui-btn layui-btn-warm layui-btn-xs" data-action="{:url('forbid')}" data-value="id#{$vo.ids};status#0" data-csrf="{:systoken('admin/menu/forbid')}">禁 用</a> |
||||
|
{elseif auth("admin/menu/resume")} |
||||
|
<a class="layui-btn layui-btn-warm layui-btn-xs" data-action="{:url('resume')}" data-value="id#{$vo.ids};status#1" data-csrf="{:systoken('admin/menu/resume')}">启 用</a> |
||||
|
{/if} |
||||
|
|
||||
|
{if auth("admin/menu/remove")} |
||||
|
<a class="layui-btn layui-btn-danger layui-btn-xs" data-confirm="确定要删除数据吗?" data-action="{:url('remove')}" data-value="id#{$vo.ids}" data-csrf="{:systoken('admin/menu/remove')}">删 除</a> |
||||
|
{/if} |
||||
|
|
||||
|
</td> |
||||
|
</tr> |
||||
|
{/foreach} |
||||
|
</tbody> |
||||
|
</table> |
||||
|
{/empty} |
||||
|
</div> |
||||
|
{/block} |
||||
@ -0,0 +1,67 @@ |
|||||
|
{extend name='main'} |
||||
|
|
||||
|
{block name="button"} |
||||
|
|
||||
|
{if auth("admin/oplog/clear")} |
||||
|
<button data-load='{:url("clear")}' data-confirm="确定要消除所有日志吗?" class='layui-btn layui-btn-sm layui-btn-primary'>清理日志</button> |
||||
|
{/if} |
||||
|
|
||||
|
{if auth("admin/oplog/remove")} |
||||
|
<button data-action='{:url("remove")}' data-rule="id#{key}" data-csrf="{:systoken('admin/oplog/remove')}" data-confirm="确定要删除日志吗?" class='layui-btn layui-btn-sm layui-btn-primary'>删除日志</button> |
||||
|
{/if} |
||||
|
|
||||
|
{/block} |
||||
|
|
||||
|
{block name="content"} |
||||
|
<div class="think-box-shadow"> |
||||
|
{include file='oplog/index_search'} |
||||
|
<table class="layui-table margin-top-10" lay-skin="line"> |
||||
|
{notempty name='list'} |
||||
|
<thead> |
||||
|
<tr> |
||||
|
<th class='list-table-check-td think-checkbox'> |
||||
|
<input data-auto-none data-check-target='.list-check-box' type='checkbox'> |
||||
|
</th> |
||||
|
<th class='text-left nowrap'>操作账号</th> |
||||
|
<th class='text-left nowrap'>权限节点</th> |
||||
|
<th class='text-left nowrap'>操作行为</th> |
||||
|
<th class='text-left nowrap'>地理位置</th> |
||||
|
<th class='text-left nowrap'>操作时间</th> |
||||
|
<th></th> |
||||
|
</tr> |
||||
|
</thead> |
||||
|
<tbody> |
||||
|
{foreach $list as $key=>$vo} |
||||
|
<tr data-dbclick> |
||||
|
<td class='list-table-check-td think-checkbox'> |
||||
|
<input class="list-check-box" value='{$vo.id}' type='checkbox'> |
||||
|
</td> |
||||
|
<td class="text-left nowrap">{$vo.username|default='-'}</td> |
||||
|
<td class="text-left nowrap">{$vo.node|default='-'}</td> |
||||
|
<td class='text-left nowrap'> |
||||
|
<p class="color-text">{$vo.action|default='-'}</p> |
||||
|
<p class="color-desc">{$vo.content|default='-'}</p> |
||||
|
</td> |
||||
|
<td class='text-left nowrap'> |
||||
|
<p class="color-text">{$vo.geoip|default='-'}</p> |
||||
|
<p class="color-desc">{$vo.isp|default='-'}</p> |
||||
|
</td> |
||||
|
<td class='text-left nowrap'> |
||||
|
日期:{$vo.create_at|format_datetime|str_replace=' ','<br><span class="color-desc">时间:',###|raw}</span> |
||||
|
</td> |
||||
|
<td class='text-left nowrap'> |
||||
|
{if auth("admin/oplog/remove")} |
||||
|
<a data-dbclick class="layui-btn layui-btn-sm layui-btn-danger" data-confirm="确定要删除该日志吗?" data-action="{:url('remove')}" data-value="id#{$vo.id}" data-csrf="{:systoken('admin/oplog/remove')}">删 除</a> |
||||
|
{/if} |
||||
|
</td> |
||||
|
</tr> |
||||
|
{/foreach} |
||||
|
</tbody> |
||||
|
{/notempty} |
||||
|
</table> |
||||
|
|
||||
|
{empty name='list'}<span class="notdata">没有记录哦</span>{else}{$pagehtml|raw|default=''}{/empty} |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
{/block} |
||||
@ -0,0 +1,56 @@ |
|||||
|
<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="username" value="{$Think.get.username|default=''}" 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 name="node" value="{$Think.get.node|default=''}" 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 name="action" value="{$Think.get.action|default=''}" 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 name="content" value="{$Think.get.content|default=''}" 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 name="geoip" value="{$Think.get.geoip|default=''}" 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="{$Think.get.create_at|default=''}" placeholder="请选择操作时间" class="layui-input"> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div class="layui-form-item layui-inline"> |
||||
|
<button class="layui-btn layui-btn-primary"><i class="layui-icon"></i> 搜 索</button> |
||||
|
</div> |
||||
|
</form> |
||||
|
|
||||
|
</fieldset> |
||||
|
|
||||
|
<script>form.render()</script> |
||||
@ -0,0 +1,79 @@ |
|||||
|
{extend name='main'} |
||||
|
|
||||
|
{block name="button"} |
||||
|
|
||||
|
{if auth("admin/queue/remove")} |
||||
|
<button data-action='{:url("remove")}' data-confirm="确定要删除这些任务吗?" data-rule="id#{key}" class='layui-btn layui-btn-sm layui-btn-primary'>删除任务</button> |
||||
|
{/if} |
||||
|
|
||||
|
{/block} |
||||
|
|
||||
|
{block name="content"} |
||||
|
|
||||
|
<div class="think-box-shadow"> |
||||
|
{include file='queue/index_search'} |
||||
|
<table class="layui-table margin-top-15" lay-skin="line"> |
||||
|
{notempty name='list'} |
||||
|
<thead> |
||||
|
<tr> |
||||
|
<th class='list-table-check-td think-checkbox'> |
||||
|
<input data-auto-none data-check-target='.list-check-box' type='checkbox'> |
||||
|
</th> |
||||
|
<th class='text-left nowrap'>任务信息</th> |
||||
|
<th class='text-left nowrap'>任务时间</th> |
||||
|
<th class='text-left nowrap'>任务状态</th> |
||||
|
</tr> |
||||
|
</thead> |
||||
|
{/notempty} |
||||
|
<tbody> |
||||
|
{foreach $list as $key=>$vo} |
||||
|
<tr> |
||||
|
<td class='list-table-check-td think-checkbox'> |
||||
|
<input class="list-check-box" value='{$vo.id}' type='checkbox'> |
||||
|
</td> |
||||
|
<td class='text-left nowrap'> |
||||
|
任务名称:{$vo.title} |
||||
|
<br> |
||||
|
任务指令:{$vo.uri} |
||||
|
</td> |
||||
|
<td class='text-left nowrap'> |
||||
|
创建时间:{$vo.create_at|format_datetime|raw} |
||||
|
<br> |
||||
|
跟进时间:{$vo.status_at|format_datetime|raw} |
||||
|
</td> |
||||
|
<td class='text-left nowrap'> |
||||
|
任务状态:{eq name='vo.double' value='1'} |
||||
|
<span class="layui-badge layui-bg-green margin-right-5">复</span> |
||||
|
{else} |
||||
|
<span class="layui-badge layui-bg-blue margin-right-5">单</span> |
||||
|
{/eq} |
||||
|
|
||||
|
{eq name='vo.status' value='1'} |
||||
|
<span class="layui-badge layui-bg-black">待处理</span> |
||||
|
{elseif $vo.status eq 2} |
||||
|
<span class="layui-badge layui-bg-green">处理中</span> |
||||
|
{elseif $vo.status eq 3} |
||||
|
<span class="layui-badge layui-bg-blue">处理完成</span> |
||||
|
{elseif $vo.status eq 4} |
||||
|
<span class="layui-badge layui-bg-red margin-right-5">处理失败</span> |
||||
|
<a class="layui-badge layui-bg-green" data-tips-text="重置该任务" data-action="{:url('redo')}" data-value="id#{$vo.id}"> |
||||
|
<i class="layui-icon font-s12"></i> |
||||
|
</a> |
||||
|
{/eq} |
||||
|
{if auth("admin/queue/remove") and in_array($vo.status,[1,3,4])} |
||||
|
<a data-action='{:url("remove")}' data-confirm="确定要删除该任务吗?" data-value="id#{$vo.id}" data-tips-text="删除该任务" class='layui-badge layui-bg-red margin-left-5'> |
||||
|
<i class="layui-icon"></i> |
||||
|
</a> |
||||
|
{/if} |
||||
|
<br> |
||||
|
状态描述:<span class="color-desc">{$vo.status_desc|raw|default="没有获取到状态描述"}</span> |
||||
|
</td> |
||||
|
</tr> |
||||
|
{/foreach} |
||||
|
</tbody> |
||||
|
</table> |
||||
|
|
||||
|
{empty name='list'}<span class="notdata">没有记录哦</span>{else}{$pagehtml|raw|default=''}{/empty} |
||||
|
|
||||
|
</div> |
||||
|
{/block} |
||||
@ -0,0 +1,68 @@ |
|||||
|
{if session('admin_user.username') eq 'admin'} |
||||
|
<fieldset class="margin-bottom-10"> |
||||
|
<legend>进程守护</legend> |
||||
|
<div class="layui-code border-0 margin-top-0"> |
||||
|
<p class="color-desc margin-top-10">当前消息队列守护进程运行状态</p> |
||||
|
{$message|raw|default='--'} |
||||
|
<p class="color-desc margin-top-10">配置定时任务来检查并启动进程(建议每分钟执行)</p> |
||||
|
{$cmd|default='--'} |
||||
|
</div> |
||||
|
</fieldset> |
||||
|
{/if} |
||||
|
<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="{$Think.get.title|default=''}" 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="uri" lay-search> |
||||
|
<option value="">-- 全部指令 --</option> |
||||
|
{foreach $uris as $uri} |
||||
|
<!--{eq name='Think.get.uri' value='$uri'}--> |
||||
|
<option selected value="{$uri}">{$uri}</option> |
||||
|
<!--{else}--> |
||||
|
<option value="{$uri}">{$uri}</option> |
||||
|
<!--{/eq}--> |
||||
|
{/foreach} |
||||
|
</select> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="layui-form-item layui-inline"> |
||||
|
<label class="layui-form-label">任务状态</label> |
||||
|
<div class="layui-input-inline"> |
||||
|
<select name="status" class="layui-select"> |
||||
|
{foreach [''=>'-- 全部状态 --','1'=>'待处理','2'=>'处理中','3'=>'处理完成','4'=>'处理失败'] as $k=>$v} |
||||
|
<!--{if $Think.get.status eq $k}--> |
||||
|
<option selected value="{$k}">{$v}</option> |
||||
|
<!--{else}--> |
||||
|
<option value="{$k}">{$v}</option> |
||||
|
<!--{/if}--> |
||||
|
{/foreach} |
||||
|
</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="{$Think.get.create_at|default=''}" 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="status_at" value="{$Think.get.status_at|default=''}" placeholder="请选择跟进时间" class="layui-input"> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="layui-form-item layui-inline"> |
||||
|
<button class="layui-btn layui-btn-primary"><i class="layui-icon"></i> 搜 索</button> |
||||
|
</div> |
||||
|
</form> |
||||
|
</fieldset> |
||||
|
|
||||
|
<script>form.render()</script> |
||||
@ -0,0 +1,63 @@ |
|||||
|
<form class="layui-form layui-card" action="{:request()->url()}" data-auto="true" method="post" autocomplete="off"> |
||||
|
<div class="layui-card-body"> |
||||
|
<div class="layui-form-item"> |
||||
|
<label class="layui-form-label label-required">用户账号</label> |
||||
|
<div class="layui-input-block"> |
||||
|
<!--{if isset($vo) and isset($vo.username)}--> |
||||
|
<input disabled value='{$vo.username|default=""}' class="layui-input layui-bg-gray"> |
||||
|
<!--{else}--> |
||||
|
<input name="username" value='{$vo.username|default=""}' required pattern="^.{4,}$" placeholder="请输入4位及以上字符用户名称" class="layui-input"> |
||||
|
<!--{/if}--> |
||||
|
<p class="color-desc">用户账号创建后,不允许再次修改。</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="layui-form-item"> |
||||
|
<label class="layui-form-label">联系手机</label> |
||||
|
<div class="layui-input-block"> |
||||
|
<input type="tel" maxlength="11" autocomplete="off" autofocus name="phone" value='{$vo.phone|default=""}' pattern="^1[3-9][0-9]{9}$" placeholder="请输入联系手机" class="layui-input"> |
||||
|
<p class="color-desc">可选,用户联系手机号码,需要填写正确的格式</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="layui-form-item"> |
||||
|
<label class="layui-form-label">联系邮箱</label> |
||||
|
<div class="layui-input-block"> |
||||
|
<input name="mail" autocomplete="off" pattern="^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$" value='{$vo.mail|default=""}' placeholder="请输入联系邮箱" class="layui-input"> |
||||
|
<p class="color-desc">可选,用户联系电子邮箱,需要填写正确的格式</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
{notempty name='authorizes'} |
||||
|
<div class="layui-form-item"> |
||||
|
<label class="layui-form-label">访问授权</label> |
||||
|
<div class="layui-input-block"> |
||||
|
{if isset($vo.username) and $vo.username eq 'admin'} |
||||
|
<span class="color-desc" style="line-height:36px">超级用户不需要配置权限</span> |
||||
|
{else} |
||||
|
{foreach $authorizes as $authorize} |
||||
|
<label class="think-checkbox"> |
||||
|
{if in_array($authorize.id, $vo.authorize)} |
||||
|
<input type="checkbox" checked name="authorize[]" value="{$authorize.id}" lay-ignore> {$authorize.title} |
||||
|
{else} |
||||
|
<input type="checkbox" name="authorize[]" value="{$authorize.id}" lay-ignore> {$authorize.title} |
||||
|
{/if} |
||||
|
</label> |
||||
|
{/foreach} |
||||
|
{empty name='authorizes'}<span class="color-desc" style="line-height:36px">未配置权限</span>{/empty} |
||||
|
{/if} |
||||
|
</div> |
||||
|
</div> |
||||
|
{/notempty} |
||||
|
<div class="layui-form-item"> |
||||
|
<label class="layui-form-label">用户描述</label> |
||||
|
<div class="layui-input-block"> |
||||
|
<textarea placeholder="请输入用户描述" class="layui-textarea" name="desc">{$vo.desc|default=""}</textarea> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="hr-line-dashed"></div> |
||||
|
<div class="layui-form-item text-center"> |
||||
|
{notempty name='vo.id'}<input type='hidden' value='{$vo.id}' name='id'>{/notempty} |
||||
|
<button class="layui-btn" type='submit'>保存数据</button> |
||||
|
<button class="layui-btn layui-btn-danger" type='button' data-confirm="确定要取消编辑吗?" data-close>取消编辑</button> |
||||
|
</div> |
||||
|
<script>window.form.render();</script> |
||||
|
</form> |
||||
@ -0,0 +1,77 @@ |
|||||
|
{extend name='main'} |
||||
|
|
||||
|
{block name="button"} |
||||
|
|
||||
|
{if auth("admin/user/add")} |
||||
|
<button data-modal='{:url("add")}' data-title="添加用户" class='layui-btn layui-btn-sm layui-btn-primary'>添加用户</button> |
||||
|
{/if} |
||||
|
|
||||
|
{if auth("admin/user/remove")} |
||||
|
<button data-action='{:url("remove")}' data-rule="id#{key}" data-csrf="{:systoken('admin/user/remove')}" data-confirm="确定要删除这些用户吗?" class='layui-btn layui-btn-sm layui-btn-primary'>删除用户</button> |
||||
|
{/if} |
||||
|
|
||||
|
{/block} |
||||
|
|
||||
|
{block name="content"} |
||||
|
<div class="think-box-shadow"> |
||||
|
{include file='user/index_search'} |
||||
|
<table class="layui-table margin-top-10" lay-skin="line"> |
||||
|
{notempty name='list'} |
||||
|
<thead> |
||||
|
<tr> |
||||
|
<th class='list-table-check-td think-checkbox'> |
||||
|
<label><input data-auto-none data-check-target='.list-check-box' type='checkbox'></label> |
||||
|
</th> |
||||
|
<th class='text-left nowrap'>用户账号</th> |
||||
|
<th class='text-left nowrap'>联系手机</th> |
||||
|
<th class='text-center nowrap'>登录次数</th> |
||||
|
<th class='text-center nowrap'>使用状态</th> |
||||
|
<th class='text-left nowrap'>创建时间</th> |
||||
|
<th class='text-left nowrap'>登录时间</th> |
||||
|
<th class='text-left nowrap'></th> |
||||
|
</tr> |
||||
|
</thead> |
||||
|
{/notempty} |
||||
|
<tbody> |
||||
|
{foreach $list as $key=>$vo} |
||||
|
<tr data-dbclick> |
||||
|
<td class='list-table-check-td think-checkbox'> |
||||
|
<label><input class="list-check-box" value='{$vo.id}' type='checkbox'></label> |
||||
|
</td> |
||||
|
<td class='text-left nowrap'>{$vo.username|default=''}</td> |
||||
|
<td class='text-left nowrap'>{$vo.phone|default='-'}</td> |
||||
|
<td class='text-center nowrap'>{$vo.login_num|default=0}</td> |
||||
|
<td class='text-center nowrap'>{eq name='vo.status' value='0'}<span class="color-red">已禁用</span>{else}<span class="color-green">使用中</span>{/eq}</td> |
||||
|
<td class='text-left nowrap'>{$vo.create_at|format_datetime}</td> |
||||
|
<td class='text-left nowrap'>{if $vo.login_num>0}{$vo.login_at|format_datetime}{else} - {/if}</td> |
||||
|
<td class='text-left nowrap'> |
||||
|
|
||||
|
{if auth("admin/user/pass")} |
||||
|
<a class="layui-btn layui-btn-normal layui-btn-sm" data-title="设置密码" data-modal='{:url("pass")}?id={$vo.id}'>密 码</a> |
||||
|
{/if} |
||||
|
|
||||
|
{if auth("admin/user/edit")} |
||||
|
<a data-dbclick class="layui-btn layui-btn-sm" data-title="编辑用户" data-modal='{:url("edit")}?id={$vo.id}'>编 辑</a> |
||||
|
{/if} |
||||
|
|
||||
|
{if $vo.status eq 1 and auth("admin/user/forbid")} |
||||
|
<a class="layui-btn layui-btn-sm layui-btn-warm" data-action="{:url('forbid')}" data-value="id#{$vo.id};status#0" data-csrf="{:systoken('admin/user/forbid')}">禁 用</a> |
||||
|
{elseif $vo.status eq 0 and auth("admin/user/resume")} |
||||
|
<a class="layui-btn layui-btn-sm layui-btn-warm" data-action="{:url('resume')}" data-value="id#{$vo.id};status#1" data-csrf="{:systoken('admin/user/resume')}">启 用</a> |
||||
|
{/if} |
||||
|
|
||||
|
{if auth("admin/user/remove")} |
||||
|
<a class="layui-btn layui-btn-sm layui-btn-danger" data-confirm="确定要删除该用户吗?" data-action="{:url('remove')}" data-value="id#{$vo.id}" data-csrf="{:systoken('admin/user/remove')}">删 除</a> |
||||
|
{/if} |
||||
|
|
||||
|
</td> |
||||
|
</tr> |
||||
|
{/foreach} |
||||
|
</tbody> |
||||
|
</table> |
||||
|
|
||||
|
{empty name='list'}<span class="notdata">没有记录哦</span>{else}{$pagehtml|raw|default=''}{/empty} |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
{/block} |
||||
@ -0,0 +1,57 @@ |
|||||
|
<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="username" value="{$Think.get.username|default=''}" 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 name="phone" value="{$Think.get.phone|default=''}" 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 name="mail" value="{$Think.get.mail|default=''}" 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="status"> |
||||
|
{foreach [''=>'-- 全部状态 --','0'=>'已禁用的账号','1'=>'使用中的账号'] as $k=>$v} |
||||
|
{eq name='Think.get.status' value='$k.""'} |
||||
|
<option selected value="{$k}">{$v}</option> |
||||
|
{else} |
||||
|
<option value="{$k}">{$v}</option> |
||||
|
{/eq} |
||||
|
{/foreach} |
||||
|
</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="login_at" value="{$Think.get.login_at|default=''}" placeholder="请选择登录时间" class="layui-input"> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div class="layui-form-item layui-inline"> |
||||
|
<button class="layui-btn layui-btn-primary"><i class="layui-icon"></i> 搜 索</button> |
||||
|
</div> |
||||
|
</form> |
||||
|
|
||||
|
</fieldset> |
||||
|
|
||||
|
<script>form.render()</script> |
||||
@ -0,0 +1,53 @@ |
|||||
|
<form class="layui-form layui-card" action="{:request()->url()}" data-auto="true" method="post" autocomplete="off"> |
||||
|
|
||||
|
<div class="layui-card-body"> |
||||
|
|
||||
|
<div class="layui-form-item"> |
||||
|
<label class="layui-form-label label-required">用户账号</label> |
||||
|
<div class="layui-input-block"> |
||||
|
<!--{if $vo and isset($vo.username)}--> |
||||
|
<input disabled value='{$vo.username|default=""}' class="layui-input layui-bg-gray"> |
||||
|
<p class="help-block">用户账号创建后,不允许再次修改。</p> |
||||
|
<!--{else}--> |
||||
|
<input name="username" value='{$vo.username|default=""}' required pattern="^.{4,}$" placeholder="请输入4位及以上字符用户名称" class="layui-input"> |
||||
|
<!--{/if}--> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<!--{if $verify}--> |
||||
|
<div class="layui-form-item"> |
||||
|
<label class="layui-form-label">旧的密码</label> |
||||
|
<div class="layui-input-block"> |
||||
|
<input type="password" autofocus name="oldpassword" value='' pattern="^\S{1,}$" required placeholder="请输入旧的密码" class="layui-input"> |
||||
|
<p class="help-block">请输入旧密码来验证修改权限,旧密码不限制格式。</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
<!--{/if}--> |
||||
|
|
||||
|
<div class="layui-form-item"> |
||||
|
<label class="layui-form-label">新的密码</label> |
||||
|
<div class="layui-input-block"> |
||||
|
<input type="password" name="password" maxlength="32" pattern="^(?![\d]+$)(?![a-zA-Z]+$)(?![^\da-zA-Z]+$).{6,32}$" required placeholder="请输入新的密码" class="layui-input"> |
||||
|
<p class="help-block">密码必需包含大小写字母、数字、符号的任意两者组合。</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div class="layui-form-item"> |
||||
|
<label class="layui-form-label">重复密码</label> |
||||
|
<div class="layui-input-block"> |
||||
|
<input type="password" name="repassword" maxlength="32" pattern="^(?![\d]+$)(?![a-zA-Z]+$)(?![^\da-zA-Z]+$).{6,32}$" required placeholder="请输入重复密码" class="layui-input"> |
||||
|
<p class="help-block">密码必需包含大小写字母、数字、符号的任意两者组合。</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
<div class="hr-line-dashed"></div> |
||||
|
|
||||
|
<div class="layui-form-item text-center"> |
||||
|
{notempty name='vo.id'}<input type='hidden' value='{$vo.id}' name='id'>{/notempty} |
||||
|
<button class="layui-btn" type='submit'>保存数据</button> |
||||
|
<button class="layui-btn layui-btn-danger" type='button' data-confirm="确定要取消编辑吗?" data-close>取消编辑</button> |
||||
|
</div> |
||||
|
|
||||
|
</form> |
||||
@ -0,0 +1,2 @@ |
|||||
|
<?php |
||||
|
|
||||
@ -0,0 +1,41 @@ |
|||||
|
<?php |
||||
|
/*---------------------------------------------------------------------- |
||||
|
* 项目名称: CloudAdmin |
||||
|
* +---------------------------------------------------------------------- |
||||
|
* 版权所有: 2014~2020 安徽云掌开发团队 |
||||
|
* +---------------------------------------------------------------------- |
||||
|
* 官方网站: [ http://www.yaoyz.com、http://www.ahyunzhang.com ] |
||||
|
* +---------------------------------------------------------------------- |
||||
|
* Date: 2018/11/15 9:47 |
||||
|
* +---------------------------------------------------------------------- |
||||
|
* Des: 前台基类 |
||||
|
+----------------------------------------------------------------------*/ |
||||
|
|
||||
|
namespace app\api\controller; |
||||
|
|
||||
|
use think\Controller; |
||||
|
|
||||
|
class Base extends Controller |
||||
|
{ |
||||
|
/** |
||||
|
* 配置信息 |
||||
|
* @var array |
||||
|
*/ |
||||
|
static protected $config = []; |
||||
|
|
||||
|
public function __construct() |
||||
|
{ |
||||
|
parent::__construct(); |
||||
|
|
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 获取全局配置信息 |
||||
|
* @return \type |
||||
|
*/ |
||||
|
private function getConfig() |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,166 @@ |
|||||
|
<?php |
||||
|
/*---------------------------------------------------------------------- |
||||
|
* 项目名称: CloudAdmin |
||||
|
* +---------------------------------------------------------------------- |
||||
|
* 版权所有: 2014~2020 安徽云掌开发团队 |
||||
|
* +---------------------------------------------------------------------- |
||||
|
* 官方网站: [ http://www.yaoyz.com、http://www.ahyunzhang.com ] |
||||
|
* +---------------------------------------------------------------------- |
||||
|
* Date: 2019/04/09 23:50 |
||||
|
* +---------------------------------------------------------------------- |
||||
|
* Des: 短信发送api |
||||
|
+----------------------------------------------------------------------*/ |
||||
|
|
||||
|
namespace app\api\controller; |
||||
|
|
||||
|
|
||||
|
use service\SendSms; |
||||
|
use think\Db; |
||||
|
use think\facade\Cache; |
||||
|
use think\facade\Validate; |
||||
|
|
||||
|
class Sms extends Base |
||||
|
{ |
||||
|
|
||||
|
/** |
||||
|
* @var string |
||||
|
* 短信服务商数据表 |
||||
|
*/ |
||||
|
private static $table = 'cloud_sms'; |
||||
|
|
||||
|
/** |
||||
|
* @var string |
||||
|
* 短信日志表 |
||||
|
*/ |
||||
|
private static $table_log = 'cloud_sms_log'; |
||||
|
|
||||
|
/** |
||||
|
* @var string |
||||
|
* 短信服务商模板配置表 |
||||
|
*/ |
||||
|
private static $table_config = 'cloud_sms_config'; |
||||
|
|
||||
|
public static function db($table = '') |
||||
|
{ |
||||
|
//读取短信配置信息 |
||||
|
$table = !empty($table) ? $table : self::$table; |
||||
|
$sms = Db::name($table)->where('status=1')->select(); |
||||
|
if (empty($sms)) { |
||||
|
return json_status(40602); |
||||
|
} |
||||
|
//随机一个数组元素 |
||||
|
$key = array_rand($sms); |
||||
|
$sms = $sms[$key]; |
||||
|
return empty($sms) ? json_status(40601) : $sms; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 发送短信验证码【单条】 |
||||
|
* @param string $mobile 手机号 |
||||
|
* @param int $tempid 模板id |
||||
|
* @return \type|void |
||||
|
*/ |
||||
|
public static function send($mobile = '', $tempid = 1) |
||||
|
{ |
||||
|
if (!Validate::is($mobile, 'mobile')) { |
||||
|
return json_status(40601); |
||||
|
} |
||||
|
//获取短信服务端信息 |
||||
|
$sms = self::db(); |
||||
|
//替换模板变量 |
||||
|
$code = mt_rand(999, 10000); |
||||
|
$replace_str = [ |
||||
|
'{code}' => $code, |
||||
|
]; |
||||
|
Cache::set('sms_' . $mobile . '_' . $tempid, $code, 300); |
||||
|
$text = self::parseTemplate($tempid, $replace_str); |
||||
|
$data = SendSms::send($sms, $mobile, $sms['code_url'], $text); |
||||
|
$data['mobile'] = $mobile; //重复发送的api没有返回mobile |
||||
|
self::writeLog($data, $sms['name'], $text); //记录短信日志 |
||||
|
return $data; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 验证验证码 |
||||
|
* @param $mobile 手机号 |
||||
|
* @param $code 验证码 |
||||
|
* @param $tempid 模板id |
||||
|
*/ |
||||
|
public static function verification($mobile, $code, $tempid = 1) |
||||
|
{ |
||||
|
$validate = new \app\api\validate\Sms; |
||||
|
$data = [ |
||||
|
'mobile' => $mobile, |
||||
|
'code' => $code, |
||||
|
]; |
||||
|
if (!$validate->check($data)) { |
||||
|
return json_status($validate->getError()); |
||||
|
} |
||||
|
//验证手机号 |
||||
|
$cache_name = 'sms_' . $mobile . '_' . $tempid; |
||||
|
$cache_code = Cache::get($cache_name); |
||||
|
if ($cache_code != $code) { |
||||
|
return json_status(40605); |
||||
|
} |
||||
|
//删除成功后的缓存 |
||||
|
Cache::rm($cache_name); |
||||
|
return json_status(); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 发送系统通知类【单条】 |
||||
|
* @param string $mobile 手机号 |
||||
|
* @param int $tempid 模板id |
||||
|
* @param int $arr 需要替换的变量数组 |
||||
|
* @return \type|void |
||||
|
*/ |
||||
|
public static function sendNotify($mobile = 0, $arr = [], $tempid = 3) |
||||
|
{ |
||||
|
if (!Validate::is($mobile, 'mobile')) { |
||||
|
return json_status(40601); |
||||
|
} |
||||
|
//获取短信服务端信息 |
||||
|
$sms = self::db(); |
||||
|
$text = self::parseTemplate($tempid, $arr); |
||||
|
$data = SendSms::send($sms, $mobile, $sms['notify_url'], $text); |
||||
|
self::writeLog($data, $sms['name'], $text); //记录短信日志 |
||||
|
return $data; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 记录发送日志 |
||||
|
* @param array $arr 短信服务商返回数据 |
||||
|
* @param $sms_name 当前短信发送服务商名称 |
||||
|
* @param $text 短信内容 |
||||
|
*/ |
||||
|
private static function writeLog($arr = [], $sms_name, $text) |
||||
|
{ |
||||
|
if (isset($arr['data'][0])) { |
||||
|
$_data = $arr['data'][0]; |
||||
|
} else { |
||||
|
$_data = $arr; |
||||
|
} |
||||
|
$_data['text'] = $text; |
||||
|
$_data['platform'] = $sms_name; |
||||
|
$_data['status'] = $_data['code'] === 0 ? 1 : 0; |
||||
|
$_data['create_time'] = time(); |
||||
|
$_data['month'] = date('Y-m'); |
||||
|
Db::name(self::$table_log)->strict(false)->insert($_data); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 短信模板解析 |
||||
|
* @param $tempid |
||||
|
* @param array $arr |
||||
|
*/ |
||||
|
private static function parseTemplate($tempid, $arr = []) |
||||
|
{ |
||||
|
$template = Db::name(self::$table_config)->find($tempid); |
||||
|
if (empty($template)) { |
||||
|
return json_status(40603); |
||||
|
} |
||||
|
$template['content'] = str_replace(array_keys($arr), $arr, $template['content']); |
||||
|
return $template['content']; |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,33 @@ |
|||||
|
<?php |
||||
|
/*---------------------------------------------------------------------- |
||||
|
* 项目名称: CloudAdmin |
||||
|
* +---------------------------------------------------------------------- |
||||
|
* 版权所有: 2014~2020 安徽云掌开发团队 |
||||
|
* +---------------------------------------------------------------------- |
||||
|
* 官方网站: [ http://www.yaoyz.com、http://www.ahyunzhang.com ] |
||||
|
* +---------------------------------------------------------------------- |
||||
|
* Date: 2018/11/30 9:47 |
||||
|
* +---------------------------------------------------------------------- |
||||
|
* Des: 短信验证 |
||||
|
+----------------------------------------------------------------------*/ |
||||
|
|
||||
|
namespace app\api\validate; |
||||
|
|
||||
|
use think\Validate; |
||||
|
|
||||
|
class Sms extends Validate |
||||
|
{ |
||||
|
|
||||
|
protected $rule = [ |
||||
|
'mobile' => 'require|length:11', |
||||
|
'code' => 'require|length:4', |
||||
|
]; |
||||
|
|
||||
|
protected $message = [ |
||||
|
'mobile.require' => '40601', |
||||
|
'mobile.length' => '40601', |
||||
|
'code.require' => '40604', |
||||
|
'code.length' => '40604', |
||||
|
]; |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,122 @@ |
|||||
|
<?php |
||||
|
|
||||
|
/** |
||||
|
* 计算指定时间与当前比较剩余多少天 |
||||
|
* @param $time |
||||
|
*/ |
||||
|
function time_days($time = 0) |
||||
|
{ |
||||
|
if (!$time || !is_numeric($time)) { |
||||
|
return ['msg' => '未出租', 'num' => 2]; |
||||
|
} |
||||
|
|
||||
|
$now_time = time(); |
||||
|
|
||||
|
$days = ceil(($time - $now_time) / 3600 / 24); |
||||
|
if ($days > 0) { |
||||
|
return ['msg' => $days . '天后到期', 'num' => 2]; |
||||
|
} else { |
||||
|
return ['msg' => '已过期' . abs($days) . '天', 'num' => 1]; |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 格式化数组,删除字段 |
||||
|
* @param type $_arr 数组对象 |
||||
|
* @param type $field 需要删除的字段 |
||||
|
*/ |
||||
|
function format_field(&$_arr = array(), $_field = array()) |
||||
|
{ |
||||
|
|
||||
|
if (!$_arr || !$_field) { |
||||
|
return; |
||||
|
} |
||||
|
if (!is_array($_field)) { |
||||
|
$_field = explode(',', $_field); |
||||
|
} |
||||
|
$_field = array_flip($_field); |
||||
|
|
||||
|
array_walk($_arr, function (&$v, &$k) use ($_field) { |
||||
|
$v = array_intersect_key($v, $_field); |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* |
||||
|
* @param type $code 状态编码 |
||||
|
* @param type $data 返回数据 |
||||
|
* @param type $msg 错误的提示信息 |
||||
|
* @return type |
||||
|
*/ |
||||
|
function send_http_status($code, $_data = array(), $msg = '') |
||||
|
{ |
||||
|
if (!$code) { |
||||
|
return; |
||||
|
} |
||||
|
$_status = config('status'); |
||||
|
if (isset($_status[$code])) { |
||||
|
header('HTTP/1.1 200 ' . $_status[$code]); |
||||
|
// 确保FastCGI模式下正常 |
||||
|
header('Status: 200 ' . $_status[$code]); |
||||
|
} |
||||
|
if ($_data == null) { |
||||
|
$_data = []; |
||||
|
} |
||||
|
$msg = empty($msg) ? $_status[$code] : $msg; |
||||
|
$_msg = [ |
||||
|
'code' => $code, |
||||
|
'msg' => $msg, |
||||
|
'data' => $_data, |
||||
|
'time' => $_SERVER['REQUEST_TIME'], |
||||
|
]; |
||||
|
return json_encode($_msg, JSON_UNESCAPED_UNICODE); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* 去除html js css 危险注入代码 |
||||
|
*/ |
||||
|
function filter_danger_str($_string) |
||||
|
{ |
||||
|
$search = array("'<script[^>]*?>.*?</script>'si", // 去掉 javascript |
||||
|
"'<style[^>]*?>.*?</style>'si", // 去掉 css |
||||
|
"'<[/!]*?[^<>]*?>'si", // 去掉 HTML 标记 |
||||
|
"'<!--[/!]*?[^<>]*?>'si", // 去掉 注释标记 |
||||
|
"'([rn])[s]+'", // 去掉空白字符 |
||||
|
"'&(quot|#34);'i", // 替换 HTML 实体 |
||||
|
"'&(amp|#38);'i", |
||||
|
"'&(lt|#60);'i", |
||||
|
"'&(gt|#62);'i", |
||||
|
"'&(nbsp|#160);'i", |
||||
|
"'&(iexcl|#161);'i", |
||||
|
"'&(cent|#162);'i", |
||||
|
"'&(pound|#163);'i", |
||||
|
"'&(copy|#169);'i", |
||||
|
); |
||||
|
$replace = array("", "", "", "", "\1", "\"", "&", "<", ">", " ", chr(161), chr(162), chr(163), chr(169)); |
||||
|
|
||||
|
$out = preg_replace($search, $replace, $_string); |
||||
|
return htmlspecialchars_custom($out); |
||||
|
} |
||||
|
|
||||
|
//过滤单双引号 |
||||
|
function htmlspecialchars_custom($str) |
||||
|
{ |
||||
|
return htmlspecialchars($str, ENT_QUOTES); |
||||
|
} |
||||
|
|
||||
|
function order_no(){ |
||||
|
return date('Ymd').rand(1000,9999).date('His').rand(1000,9999); |
||||
|
} |
||||
|
|
||||
|
function formart_time($time){ |
||||
|
if ($time < strtotime(date("Y-m-d",strtotime('+1 day'))) ){ |
||||
|
return '今天'; |
||||
|
}elseif ( $time < strtotime(date("Y-m-d",strtotime('+2 day'))) ){ |
||||
|
return '明天'; |
||||
|
}else{ |
||||
|
return date('Y-m-d',$time); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,42 @@ |
|||||
|
<?php |
||||
|
|
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | ThinkAdmin |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 版权所有 2014~2019 广州楚才信息科技有限公司 [ http://www.cuci.cc ] |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 官方网站: http://demo.thinkadmin.top |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 开源协议 ( https://mit-license.org ) |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin |
||||
|
// | github 代码仓库:https://github.com/zoujingli/ThinkAdmin |
||||
|
// +---------------------------------------------------------------------- |
||||
|
|
||||
|
namespace app\index\controller; |
||||
|
|
||||
|
|
||||
|
use think\Db; |
||||
|
|
||||
|
/** |
||||
|
* 应用入口 |
||||
|
* Class Index |
||||
|
* @package app\index\controller |
||||
|
*/ |
||||
|
class Ad extends Base |
||||
|
{ |
||||
|
public $table = 'CloudAdData'; |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* 获取广告列表 |
||||
|
*/ |
||||
|
public function index() |
||||
|
{ |
||||
|
$page = $this->request->param('page', 1); |
||||
|
$pagesize = $this->request->param('pagesize', 3); |
||||
|
$data = Db::name($this->table)->where('is_delete', 0)->page($page, $pagesize)->order('sort ASC')->select(); |
||||
|
return json($data); |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,212 @@ |
|||||
|
<?php |
||||
|
|
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | ThinkAdmin |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 版权所有 2014~2019 广州楚才信息科技有限公司 [ http://www.cuci.cc ] |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 官方网站: http://demo.thinkadmin.top |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 开源协议 ( https://mit-license.org ) |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin |
||||
|
// | github 代码仓库:https://github.com/zoujingli/ThinkAdmin |
||||
|
// +---------------------------------------------------------------------- |
||||
|
|
||||
|
namespace app\index\controller; |
||||
|
|
||||
|
|
||||
|
use think\App; |
||||
|
use think\Controller; |
||||
|
use think\Db; |
||||
|
|
||||
|
/** |
||||
|
* 应用入口 |
||||
|
* Class Index |
||||
|
* @package app\index\controller |
||||
|
*/ |
||||
|
class Base extends Controller |
||||
|
{ |
||||
|
protected static $table_user = "CloudMember"; |
||||
|
public $table_room_crontab = 'CloudRoomCrontab';//房间时间切割 |
||||
|
|
||||
|
public function __construct(App $app = null) |
||||
|
{ |
||||
|
parent::__construct($app); |
||||
|
//判断是否开启验证 |
||||
|
if (config('istoken')) { |
||||
|
$this->run(); //token验证 |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 用户信息传递 |
||||
|
* @throws \think\db\exception\DataNotFoundException |
||||
|
* @throws \think\db\exception\ModelNotFoundException |
||||
|
* @throws \think\exception\DbException |
||||
|
*/ |
||||
|
protected static function auth() |
||||
|
{ |
||||
|
//$this->info(); //获取相关信息 |
||||
|
if (!isset($_SERVER['HTTP_USERID'])) { |
||||
|
exit(send_http_status(412)); |
||||
|
} |
||||
|
$user_id = $_SERVER['HTTP_USERID']; |
||||
|
$_USER = Db::name(self::$table_user)->where('id', $user_id)->find(); |
||||
|
if (!$_USER) { |
||||
|
exit(send_http_status(415)); |
||||
|
} |
||||
|
!defined('USER_ID') ? define('USER_ID', $_USER['id']) : ''; |
||||
|
!defined('MEMBER') ? define('MEMBER', $_USER) : ''; |
||||
|
|
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 会员发布权限判断 |
||||
|
* @param int $curr_count 当前已有数据统计 |
||||
|
* @param string $count_type 判断的类型 默认房源,否则根据传入的类型 |
||||
|
*/ |
||||
|
protected static function authAddHouse($curr_count = 0, $count_type = 'count') |
||||
|
{ |
||||
|
|
||||
|
//子账号不允许删除和添加 |
||||
|
if ($_SERVER['HTTP_SUBUSERID'] > 0) { |
||||
|
exit(send_http_status(417)); |
||||
|
} |
||||
|
|
||||
|
//判断有没有手机号 |
||||
|
if (empty(MEMBER['phone']) || strlen(MEMBER['phone']) != 11) { |
||||
|
exit(send_http_status(51016)); |
||||
|
} |
||||
|
|
||||
|
//暂时免费 |
||||
|
return; |
||||
|
|
||||
|
//超级管理员直接返回 |
||||
|
if (MEMBER['is_manager'] == 1) { |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
//判断当前用户 会员是否过期(普通用户不用判断) |
||||
|
if (MEMBER['vip_level'] > 0 && MEMBER['vip_endtime'] < time() && MEMBER['is_manager'] != 1) { |
||||
|
exit(send_http_status(416)); |
||||
|
} |
||||
|
//获取等级配置信息 |
||||
|
$vip_level = config('vip_level'); |
||||
|
$member_vip = $vip_level[MEMBER['vip_level']]; |
||||
|
if ($curr_count >= $member_vip[$count_type]) { |
||||
|
exit(send_http_status(51004)); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 获取常用硬件信息 |
||||
|
*/ |
||||
|
protected function info() |
||||
|
{ |
||||
|
$code = ''; |
||||
|
if (!isset($_SERVER['HTTP_DEVICENAME'])) { |
||||
|
$code = 408; |
||||
|
} |
||||
|
if (!isset($_SERVER['HTTP_SYSTEMVERSION'])) { |
||||
|
$code = 409; |
||||
|
} |
||||
|
if (!isset($_SERVER['HTTP_DEVICECODE'])) { |
||||
|
$code = 410; |
||||
|
} |
||||
|
if (!isset($_SERVER['HTTP_PHONETYPE'])) { |
||||
|
$code = 411; |
||||
|
} |
||||
|
if (!isset($_SERVER['HTTP_USERID'])) { |
||||
|
$code = 412; |
||||
|
} |
||||
|
if ($code) { |
||||
|
exit(send_http_status($code)); |
||||
|
} |
||||
|
//获取、设备号、机型、终端 |
||||
|
$devicename = 'Android'; |
||||
|
if (strtolower($_SERVER['HTTP_DEVICENAME']) != strtolower($devicename)) { |
||||
|
$devicename = 'iOS'; |
||||
|
} |
||||
|
//获取版本号 |
||||
|
$version = isset($_SERVER['HTTP_VERSION']) ? $_SERVER['HTTP_VERSION'] : 0; |
||||
|
defined('VERSION') or define("VERSION", $version); //版本号 |
||||
|
defined('DEVICENAME') or define("DEVICENAME", $devicename); //终端名称 |
||||
|
defined('SYSTEMVERSION') or define("SYSTEMVERSION", strtoupper($_SERVER['HTTP_SYSTEMVERSION'])); //系统版本 |
||||
|
defined('DEVICECODE') or define("DEVICECODE", $_SERVER['HTTP_DEVICECODE']); //设备号 |
||||
|
defined('PHONETYPE') or define("PHONETYPE", $_SERVER['HTTP_PHONETYPE']); //机型 |
||||
|
defined('USERID') or define("USERID", $_SERVER['HTTP_USERID']); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 根据密钥、标识、时间戳、随机数 验证请求接口 |
||||
|
*/ |
||||
|
public function run() |
||||
|
{ |
||||
|
//客户端标识列表 |
||||
|
$_client = config('CLIENT'); |
||||
|
$_secret = config('SECRET'); |
||||
|
$code = ''; |
||||
|
//没有指定平台标识 |
||||
|
defined('CLIENT') or define("CLIENT", strtoupper($_SERVER['HTTP_CLIENT'])); //终端名称 |
||||
|
if (empty(CLIENT) || !in_array(CLIENT, $_client)) { |
||||
|
$code = 201; |
||||
|
} |
||||
|
//判断标识是否正确 |
||||
|
if (!isset($_SERVER['HTTP_APPID']) || $_SERVER['HTTP_APPID'] != $_secret[CLIENT]['APPID']) { |
||||
|
$code = 202; |
||||
|
} |
||||
|
|
||||
|
//指定随机数 |
||||
|
$nonce = $_SERVER['HTTP_NONCE']; |
||||
|
if (!isset($nonce) || empty($nonce)) { |
||||
|
$code = 203; |
||||
|
} |
||||
|
|
||||
|
//判断加密串 |
||||
|
$openkey = $_secret[CLIENT]['APPID'] . $nonce . $_secret[CLIENT]['SECRET']; |
||||
|
$encry_old = md5($openkey); |
||||
|
$encry = md5($openkey . $_SERVER['HTTP_USERID']); |
||||
|
if ($_SERVER['HTTP_OPENKEY'] != $encry && $encry_old != $_SERVER['HTTP_OPENKEY']) { |
||||
|
$code = 207; |
||||
|
} |
||||
|
if ($code) { |
||||
|
exit(send_http_status($code)); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* 根据收租方式 切割提醒的时间节点 |
||||
|
* @param $_data 房间数据 |
||||
|
* @param int $month 指定分割月数 |
||||
|
* @throws \think\Exception |
||||
|
* @throws \think\exception\PDOException |
||||
|
*/ |
||||
|
protected function crontab_room($_data, $month = 3) |
||||
|
{ |
||||
|
$start_time = $_data['start_time']; |
||||
|
$end_time = $_data['end_time']; |
||||
|
//计算指定天数后的时间戳 |
||||
|
$_arr = []; |
||||
|
while ($start_time < $end_time) { |
||||
|
$arr_temp['room_id'] = $_data['id']; |
||||
|
$arr_temp['user_id'] = USER_ID; |
||||
|
$arr_temp['start_time'] = $start_time; |
||||
|
$arr_temp['end_time'] = $start_time = strtotime('+' . $month . ' month', $start_time); |
||||
|
$arr_temp['create_time'] = time(); |
||||
|
$_arr[] = $arr_temp; |
||||
|
} |
||||
|
//删除最后一个元素,置换为end_time(防止开始时间与结束时间不一致) |
||||
|
$last_arr = array_pop($_arr); |
||||
|
$last_arr['end_time'] = $end_time; |
||||
|
$_arr[] = $last_arr; |
||||
|
//新增前先清空 |
||||
|
$house_crontab = Db::name($this->table_room_crontab); |
||||
|
$house_crontab->where('room_id', $_data['id'])->where('user_id', USER_ID)->delete(); |
||||
|
$house_crontab->insertAll($_arr); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
} |
||||
@ -0,0 +1,269 @@ |
|||||
|
<?php |
||||
|
|
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | ThinkAdmin |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 版权所有 2014~2019 广州楚才信息科技有限公司 [ http://www.cuci.cc ] |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 官方网站: http://demo.thinkadmin.top |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 开源协议 ( https://mit-license.org ) |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin |
||||
|
// | github 代码仓库:https://github.com/zoujingli/ThinkAdmin |
||||
|
// +---------------------------------------------------------------------- |
||||
|
|
||||
|
namespace app\index\controller; |
||||
|
|
||||
|
|
||||
|
use think\Db; |
||||
|
|
||||
|
/** |
||||
|
* 保洁 |
||||
|
* Class Index |
||||
|
* @package app\index\controller |
||||
|
*/ |
||||
|
class Clean extends Base |
||||
|
{ |
||||
|
public $table = 'CloudClean'; |
||||
|
|
||||
|
public function __construct() |
||||
|
{ |
||||
|
parent::__construct(); |
||||
|
parent::auth(); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 获取列表 |
||||
|
*/ |
||||
|
public function index() |
||||
|
{ |
||||
|
$data = Db::name($this->table)->select(); |
||||
|
return send_http_status(200, $data); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 更改打扫时间 |
||||
|
*/ |
||||
|
public function change_date() |
||||
|
{ |
||||
|
$param = $this->request->param(); |
||||
|
$res = Db::name('CloudCleanState') |
||||
|
->where('id', $param['id']) |
||||
|
->update([ |
||||
|
'create_time' => strtotime($param['date']), |
||||
|
]); |
||||
|
return send_http_status(200, ['date' => formart_time(strtotime($param['date']))]); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 我要打扫的房间 |
||||
|
*/ |
||||
|
public function my_clean() |
||||
|
{ |
||||
|
$param = $this->request->param(); |
||||
|
$is_complete = $this->request->param('is_complete', 0); |
||||
|
$type = $is_complete == 0 ? '=' : '>'; |
||||
|
$res = Db::name('CloudCleanState') |
||||
|
->alias('s') |
||||
|
->leftJoin('cloud_clean_order o', 'o.order_no=s.order_no') |
||||
|
->leftJoin('cloud_house h', 'h.id=o.house_id') |
||||
|
->leftJoin('cloud_member m', 'o.openid = m.openid') |
||||
|
->page($param['page'], 10) |
||||
|
->where('o.service_openid', $param['openid']) |
||||
|
->where('s.complete_time', $type, $is_complete) |
||||
|
->field('m.phone,s.id,s.picture,s.create_time,s.complete_time,s.step,s.order_no, h.name,h.photo,h.latitude,h.longitude,h.door_number,o.content,o.second,o.service_openid,m.nickname,m.headimg') |
||||
|
->order('s.create_time', 'ASC') |
||||
|
->select(); |
||||
|
foreach ($res as &$v) { |
||||
|
$v['picture'] = json_decode($v['picture'], true); |
||||
|
$v['create_time'] = formart_time($v['create_time']); |
||||
|
$v['complete_time'] = !empty($v['complete_time']) ? date('Y-m-d', $v['complete_time']) : 0; |
||||
|
$v['photo'] = $v['photo'] ? explode(',', $v['photo'])[0] : ''; |
||||
|
} |
||||
|
return send_http_status(200, $res); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 我发布的保洁 |
||||
|
* @return \type |
||||
|
* @throws \think\db\exception\DataNotFoundException |
||||
|
* @throws \think\db\exception\ModelNotFoundException |
||||
|
* @throws \think\exception\DbException |
||||
|
*/ |
||||
|
public function my() |
||||
|
{ |
||||
|
$param = $this->request->param(); |
||||
|
//$user = Db::name('CloudMember')->where('openid',$param['openid'])->find(); |
||||
|
$page = $this->request->param('page', 1); |
||||
|
$query = Db::name('CloudCleanOrder') |
||||
|
->alias('o') |
||||
|
->leftJoin('cloud_house h', 'o.house_id = h.id') |
||||
|
->leftJoin('cloud_member m', 'h.user_id = m.id') // 查询房源手机号 |
||||
|
->where('o.state', 1) |
||||
|
->field('m.phone,h.name,h.latitude,h.longitude,h.photo,h.door_number,o.create_time,o.content,o.second,o.complete,o.order_no,o.service_openid') |
||||
|
->order('o.create_time', 'desc') |
||||
|
->limit(($page - 1) * 15, 15); |
||||
|
/*if ($user['is_clean']){ |
||||
|
$query->where('o.openid|o.service_openid','=', $param['openid'])->whereNotNull('service_openid'); |
||||
|
}else{ |
||||
|
$query->where('o.openid',$param['openid']); |
||||
|
}*/ |
||||
|
$query->where('o.openid', $param['openid']); |
||||
|
$res = $query->select(); |
||||
|
|
||||
|
foreach ($res as &$v) { |
||||
|
$v['create_time'] = !empty($v['create_time']) ? date('Y-m-d H:i:s', $v['create_time']) : 0; |
||||
|
$v['photo'] = $v['photo'] ? explode(',', $v['photo'])[0] : ''; |
||||
|
} |
||||
|
|
||||
|
return send_http_status(200, $res); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 订单详情 |
||||
|
*/ |
||||
|
public function info() |
||||
|
{ |
||||
|
$order_no = $this->request->param('order_no'); |
||||
|
|
||||
|
$res = Db::name('CloudCleanState') |
||||
|
->alias('s') |
||||
|
->leftJoin('cloud_clean_order o', 'o.order_no=s.order_no') |
||||
|
->leftJoin('cloud_house h', 'h.id=o.house_id') |
||||
|
->leftJoin('cloud_member m', 'o.openid = m.openid') |
||||
|
->where('s.order_no', $order_no) |
||||
|
->field('s.id,s.picture,s.commont,s.commont_time,s.create_time,s.complete_time,s.step,s.order_no, h.name,o.content,o.second,o.service_openid,m.nickname,m.headimg') |
||||
|
->select(); |
||||
|
foreach ($res as &$v) { |
||||
|
$v['picture'] = json_decode($v['picture'], true); |
||||
|
$v['create_time'] = formart_time($v['create_time']); |
||||
|
$v['commont'] = [ |
||||
|
'nickname' => $v['nickname'], |
||||
|
'headimg' => $v['headimg'], |
||||
|
'commont' => $v['commont'], |
||||
|
'commont_time' => date('Y-m-d H:i:s', $v['commont_time']) |
||||
|
]; |
||||
|
$v['complete_time'] = !empty($v['complete_time']) ? date('Y-m-d', $v['complete_time']) : '未打扫'; |
||||
|
unset($v['nickname'], $v['headimg'], $v['commont_time']); |
||||
|
} |
||||
|
return send_http_status(200, $res); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 评价 |
||||
|
*/ |
||||
|
public function commont() |
||||
|
{ |
||||
|
$param = $this->request->param(); |
||||
|
$res = Db::name('CloudCleanState')->where('id', $param['id']) |
||||
|
->update([ |
||||
|
'commont' => $param['commont'], |
||||
|
'commont_time' => time(), |
||||
|
]); |
||||
|
if ($res) { |
||||
|
$data = Db::name('CloudCleanState') |
||||
|
->alias('a') |
||||
|
->leftJoin('cloud_clean_order o', 'o.order_no = a.order_no') |
||||
|
->leftJoin('cloud_member m', 'o.openid = m.openid') |
||||
|
->field('a.commont,a.commont_time,m.nickname,m.headimg') |
||||
|
->where('a.id', $param['id']) |
||||
|
->find(); |
||||
|
$data['index'] = $param['index']; |
||||
|
$data['commont_time'] = date('Y-m-d H:i:s', $data['commont_time']); |
||||
|
return send_http_status(200, $data); |
||||
|
} else { |
||||
|
return send_http_status(201, '', '操作失败!'); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 保洁完成上传图片 |
||||
|
* @return \type |
||||
|
*/ |
||||
|
public function complete() |
||||
|
{ |
||||
|
$param = $this->request->param(); |
||||
|
Db::startTrans(); |
||||
|
try { |
||||
|
Db::name('CloudCleanState')->where('id', $param['id'])->update([ |
||||
|
'service_openid' => $param['openid'], |
||||
|
'picture' => json_encode(explode(',', $param['images'])), |
||||
|
'complete_time' => strtotime($param['complete_time']), |
||||
|
]); |
||||
|
Db::name('CloudCleanOrder') |
||||
|
->where('order_no', $param['order_no']) |
||||
|
->update(['complete' => Db::raw('complete+1')]); |
||||
|
Db::commit(); |
||||
|
return send_http_status(200); |
||||
|
} catch (\Exception $e) { |
||||
|
Db::rollback(); |
||||
|
return send_http_status(201, '', $e->getMessage()); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public function create() |
||||
|
{ |
||||
|
$param = $this->request->post(); |
||||
|
$clean = Db::name($this->table)->find($param['cleanid']); |
||||
|
if (!$clean) return $this->error('选项不存在'); |
||||
|
$order_no = order_no(); |
||||
|
$order = [ |
||||
|
'order_no' => $order_no, |
||||
|
'openid' => $param['openid'], |
||||
|
'content' => $clean['title'] . ' - ' . $clean['summary'], |
||||
|
'second' => $clean['second'], |
||||
|
'price' => $clean['price'], |
||||
|
'house_id' => $param['house_id'], |
||||
|
'create_time' => time(), |
||||
|
'update_time' => time(), |
||||
|
]; |
||||
|
//生成副表订单 |
||||
|
Db::startTrans(); |
||||
|
try { |
||||
|
Db::name('CloudCleanOrder')->insert($order); |
||||
|
$row = []; |
||||
|
$day_num = 10; |
||||
|
if ($clean['second'] == 2) { |
||||
|
$day_num = 15; |
||||
|
} |
||||
|
for ($i = 0; $i < $clean['second']; $i++) { |
||||
|
$create_time = strtotime((($i * $day_num) + 1) . ' day'); |
||||
|
$row[] = [ |
||||
|
'create_time' => $create_time, |
||||
|
'update_time' => $create_time, |
||||
|
'order_no' => $order_no, |
||||
|
'step' => $i + 1 |
||||
|
]; |
||||
|
} |
||||
|
Db::name('CloudCleanState')->insertAll($row); |
||||
|
Db::commit(); |
||||
|
} catch (\Throwable $e) { |
||||
|
Db::rollback(); |
||||
|
return send_http_status(202, '', $e->getMessage()); |
||||
|
} |
||||
|
$wechat = new \WeChat\Pay(config('wechat.miniapp')); |
||||
|
$options = [ |
||||
|
'body' => '保洁' . $clean['title'] . '(' . $clean['second'] . '次)', |
||||
|
'out_trade_no' => $order_no, |
||||
|
'total_fee' => $clean['price'] * 100, |
||||
|
'openid' => $param['openid'], |
||||
|
'trade_type' => 'JSAPI', |
||||
|
'notify_url' => $this->request->domain() . '/index/notify/clean', |
||||
|
'spbill_create_ip' => $this->request->ip(), |
||||
|
]; |
||||
|
try { |
||||
|
// 生成预支付码 |
||||
|
$result = $wechat->createOrder($options); |
||||
|
// 创建JSAPI参数签名 |
||||
|
$options = $wechat->createParamsForJsApi($result['prepay_id']); |
||||
|
// @todo 把 $options 传到前端用js发起支付就可以了 |
||||
|
return send_http_status(200, $options); |
||||
|
} catch (Exception $e) { |
||||
|
// 出错啦,处理下吧 |
||||
|
return send_http_status(201, '', $e->getMessage()); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
} |
||||
@ -0,0 +1,73 @@ |
|||||
|
<?php |
||||
|
|
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | ThinkAdmin |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 版权所有 2014~2019 广州楚才信息科技有限公司 [ http://www.cuci.cc ] |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 官方网站: http://demo.thinkadmin.top |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 开源协议 ( https://mit-license.org ) |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin |
||||
|
// | github 代码仓库:https://github.com/zoujingli/ThinkAdmin |
||||
|
// +---------------------------------------------------------------------- |
||||
|
|
||||
|
namespace app\index\controller; |
||||
|
|
||||
|
|
||||
|
use think\App; |
||||
|
use think\Db; |
||||
|
|
||||
|
/** |
||||
|
* 采集数据 |
||||
|
* Class Index |
||||
|
* @package app\index\controller |
||||
|
*/ |
||||
|
class Collection extends Base |
||||
|
{ |
||||
|
private $table = 'CloudHouseCollection'; |
||||
|
|
||||
|
/** |
||||
|
* 获取问题列表 |
||||
|
*/ |
||||
|
public function index() |
||||
|
{ |
||||
|
$count = Db::name($this->table)->count(); |
||||
|
$page = $this->request->param('page', 1); |
||||
|
$pagesize = $this->request->param('pagesize', 10); |
||||
|
$pages = ceil($count / $pagesize); //总页数 |
||||
|
$_result = Db::name($this->table)->page($page, $pagesize)->order('id', "DESC")->select(); |
||||
|
$_data['list'] = $_result; |
||||
|
$_data['pages'] = $pages; |
||||
|
self::formatData($_data['list']); |
||||
|
return $_data; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 问题详情 |
||||
|
*/ |
||||
|
public function view($id = '') |
||||
|
{ |
||||
|
if (!$id) { |
||||
|
return; |
||||
|
} |
||||
|
//获取房源详情 |
||||
|
$_data = Db::name($this->table)->find($id); |
||||
|
return send_http_status(200, $_data); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
static private function formatData(&$data) |
||||
|
{ |
||||
|
if (!$data) { |
||||
|
return; |
||||
|
} |
||||
|
array_walk($data, function (&$v, &$k) { |
||||
|
// !empty($v['create_time']) ? $v['create_time'] = date('Y-m-d', $v['create_time']) : $v['create_time'] = ''; |
||||
|
}); |
||||
|
|
||||
|
} |
||||
|
|
||||
|
|
||||
|
} |
||||
@ -0,0 +1,46 @@ |
|||||
|
<?php |
||||
|
|
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | ThinkAdmin |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 版权所有 2014~2019 广州楚才信息科技有限公司 [ http://www.cuci.cc ] |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 官方网站: http://demo.thinkadmin.top |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 开源协议 ( https://mit-license.org ) |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin |
||||
|
// | github 代码仓库:https://github.com/zoujingli/ThinkAdmin |
||||
|
// +---------------------------------------------------------------------- |
||||
|
|
||||
|
namespace app\index\controller; |
||||
|
|
||||
|
/** |
||||
|
* 配置信息 |
||||
|
* Class Index |
||||
|
* @package app\index\controller |
||||
|
*/ |
||||
|
class Config extends Base |
||||
|
{ |
||||
|
|
||||
|
/** |
||||
|
* 获取配置信息 |
||||
|
* @param string $name 配置key名称,支持逗号分割 |
||||
|
* @return \type |
||||
|
*/ |
||||
|
public function index($name = '') |
||||
|
{ |
||||
|
if (!$name) { |
||||
|
return send_http_status(51005); |
||||
|
} |
||||
|
$name = explode(',', $name); |
||||
|
foreach ($name as $v) { |
||||
|
$_data[$v] = config($v); |
||||
|
} |
||||
|
if (is_array($_data)) { |
||||
|
return send_http_status(200, $_data); |
||||
|
} |
||||
|
return send_http_status(413); |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,105 @@ |
|||||
|
<?php |
||||
|
|
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | ThinkAdmin |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 版权所有 2014~2019 广州楚才信息科技有限公司 [ http://www.cuci.cc ] |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 官方网站: http://demo.thinkadmin.top |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 开源协议 ( https://mit-license.org ) |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin |
||||
|
// | github 代码仓库:https://github.com/zoujingli/ThinkAdmin |
||||
|
// +---------------------------------------------------------------------- |
||||
|
|
||||
|
namespace app\index\controller; |
||||
|
|
||||
|
|
||||
|
use think\App; |
||||
|
use think\Db; |
||||
|
|
||||
|
/** |
||||
|
* 合同管理 |
||||
|
* Class Index |
||||
|
* @package app\index\controller |
||||
|
*/ |
||||
|
class Contract extends Base |
||||
|
{ |
||||
|
private $table = 'CloudHouseContract'; |
||||
|
|
||||
|
public function __construct(App $app = null) |
||||
|
{ |
||||
|
parent::__construct($app); |
||||
|
parent::auth(); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 获取合同列表 |
||||
|
*/ |
||||
|
public function index() |
||||
|
{ |
||||
|
$_where = 'user_id = ' . USER_ID . ' AND is_del = 0'; |
||||
|
$count = Db::name($this->table)->where($_where)->count(); |
||||
|
$page = $this->request->param('page', 1); |
||||
|
$pagesize = $this->request->param('pagesize', 10); |
||||
|
$pages = ceil($count / $pagesize); //总页数 |
||||
|
$_result = Db::name($this->table)->where($_where)->page($page, $pagesize)->order('id', "DESC")->select(); |
||||
|
$_data['list'] = $_result; |
||||
|
$_data['pages'] = $pages; |
||||
|
self::formatData($_data['list']); |
||||
|
return send_http_status(200, $_data); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 合同详情 |
||||
|
*/ |
||||
|
public function view($id = '') |
||||
|
{ |
||||
|
if (!$id) { |
||||
|
return; |
||||
|
} |
||||
|
//获取房源详情 |
||||
|
$_data = Db::name($this->table)->where('user_id', USER_ID)->find($id); |
||||
|
if ($_data) { |
||||
|
$_data['create_time'] = date('Y-m-d', $_data['create_time']); |
||||
|
$_data['contract_starttime'] = date('Y-m-d', $_data['contract_starttime']); |
||||
|
$_data['contract_endtime'] = date('Y-m-d', $_data['contract_endtime']); |
||||
|
return send_http_status(200, $_data); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 删除合同信息 |
||||
|
* @param string $id 合同id |
||||
|
* @return \type |
||||
|
* @throws \think\Exception |
||||
|
* @throws \think\exception\PDOException |
||||
|
*/ |
||||
|
public function del($id = '') |
||||
|
{ |
||||
|
if ((!$id || !is_numeric($id))) { |
||||
|
return send_http_status(51003); |
||||
|
} |
||||
|
$affected = Db::name($this->table)->where('id', $id)->where('user_id', USER_ID)->update(['is_del' => 1]); |
||||
|
if ($affected) { |
||||
|
return send_http_status(200); |
||||
|
} |
||||
|
return send_http_status(413); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
static private function formatData(&$data) |
||||
|
{ |
||||
|
if (!$data) { |
||||
|
return; |
||||
|
} |
||||
|
array_walk($data, function (&$v, &$k) { |
||||
|
!empty($v['create_time']) ? $v['create_time'] = date('Y-m-d', $v['create_time']) : $v['create_time'] = ''; |
||||
|
!empty($v['update_time']) ? $v['update_time'] = date('Y-m-d', $v['update_time']) : $v['update_time'] = ''; |
||||
|
}); |
||||
|
|
||||
|
} |
||||
|
|
||||
|
|
||||
|
} |
||||
@ -0,0 +1,137 @@ |
|||||
|
<?php |
||||
|
/*---------------------------------------------------------------------- |
||||
|
* 项目名称: CloudAdmin |
||||
|
* +---------------------------------------------------------------------- |
||||
|
* 版权所有: 2014~2020 安徽云掌开发团队 |
||||
|
* +---------------------------------------------------------------------- |
||||
|
* 官方网站: [ http://www.yaoyz.com、http://www.ahyunzhang.com ] |
||||
|
* +---------------------------------------------------------------------- |
||||
|
* Date: 2018/11/15 9:47 |
||||
|
* +---------------------------------------------------------------------- |
||||
|
* Des: 短信插件 |
||||
|
+----------------------------------------------------------------------*/ |
||||
|
|
||||
|
|
||||
|
namespace app\index\controller; |
||||
|
|
||||
|
use think\Controller; |
||||
|
use think\Db; |
||||
|
|
||||
|
class Crontab extends Controller |
||||
|
{ |
||||
|
|
||||
|
/** |
||||
|
* 房间表 |
||||
|
* @var string |
||||
|
*/ |
||||
|
private $table_room = 'CloudHouseRoom'; |
||||
|
|
||||
|
/** |
||||
|
* 一手房源时间节点副表 |
||||
|
* @var string |
||||
|
*/ |
||||
|
private $table_house_crontab = 'CloudHouseCrontab'; |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* 租户表 |
||||
|
* @var string |
||||
|
*/ |
||||
|
private $table_tenant = 'CloudHouseTenant'; |
||||
|
|
||||
|
/** |
||||
|
* 短信日志表 |
||||
|
* @var string |
||||
|
*/ |
||||
|
private $table_sms_log = 'CloudSmsLog'; |
||||
|
|
||||
|
/** |
||||
|
* html5支付页面 |
||||
|
* @var string |
||||
|
*/ |
||||
|
private $url = 'http://xunxibaoapi.yaoyz.com/index/pay/index'; |
||||
|
|
||||
|
/** |
||||
|
* 到期子房源提醒 |
||||
|
* @param int $day 默认3天 |
||||
|
*/ |
||||
|
public function index($day = 30) |
||||
|
{ |
||||
|
if ($day && is_numeric($day)) { |
||||
|
//计算指定天数后的时间戳 |
||||
|
$day_time = strtotime('+' . $day . ' day'); |
||||
|
$_where[] = ['r.end_time', '<', $day_time]; //结束时间小于当前时间+30天 |
||||
|
$_where[] = ['r.end_time', '>', time()]; //且结束时间大于当前时间 |
||||
|
$_where[] = ['r.end_time', '<>', '']; |
||||
|
} |
||||
|
$_where[] = ['r.is_del', '=', 0]; |
||||
|
$_data = Db::name($this->table_room)->alias('r')->leftJoin('cloud_house_tenant t', 'r.id = t.room_id')->where($_where)->field('r.*,t.phone,t.name')->select(); |
||||
|
$this->send($_data); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 到期一手房源提醒 |
||||
|
* @param int $day 默认3天 |
||||
|
*/ |
||||
|
public function house($day = 3) |
||||
|
{ |
||||
|
if ($day && is_numeric($day)) { |
||||
|
//计算指定天数后的时间戳 |
||||
|
$day_time = strtotime('+' . $day . ' day'); |
||||
|
$_where[] = ['create_time', '<', $day_time]; //结束时间小于当前时间+30天 |
||||
|
$_where[] = ['create_time', '>', time()]; //且结束时间大于当前时间 |
||||
|
$_where[] = ['create_time', '<>', '']; |
||||
|
} |
||||
|
$_data = Db::name($this->table_house_crontab)->where($_where)->select(); |
||||
|
$this->sendHouse($_data); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 执行短信发送 |
||||
|
* @param $_arr |
||||
|
* |
||||
|
*/ |
||||
|
private function send($_arr) |
||||
|
{ |
||||
|
if (empty($_arr)) { |
||||
|
return; |
||||
|
} |
||||
|
$curr_month = date('Y-m'); |
||||
|
$_sms = new \app\api\controller\Sms(); |
||||
|
foreach ($_arr as $k => $v) { |
||||
|
$_str = [ |
||||
|
'{url}' => $this->url . '?roomid=' . $v['id'] . '&phone=' . $v['phone'] . '&name=' . $v['name'] |
||||
|
]; |
||||
|
//判断本月是否发送过,已发送不再发送 |
||||
|
$_data = Db::name($this->table_sms_log)->where('mobile', $v['phone'])->where('month', $curr_month)->find(); |
||||
|
if (empty($_data)) { |
||||
|
$_sms::sendNotify($v['phone'], $_str, 23); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 执行短信发送 |
||||
|
* @param $_arr |
||||
|
* |
||||
|
*/ |
||||
|
private function sendHouse($_arr) |
||||
|
{ |
||||
|
if (empty($_arr)) { |
||||
|
return; |
||||
|
} |
||||
|
$curr_month = date('Y-m'); |
||||
|
$_sms = new \app\api\controller\Sms(); |
||||
|
foreach ($_arr as $k => $v) { |
||||
|
$_str = [ |
||||
|
'{address}' => $v['address'] . $v['house_name'] . $v['door_number'] |
||||
|
]; |
||||
|
//判断本月是否发送过,已发送不再发送 |
||||
|
$_data = Db::name($this->table_sms_log)->whereLike('text', '%' . $v["house_name"] . '%')->where('mobile', $v['phone'])->where('month', $curr_month)->find(); |
||||
|
if (empty($_data)) { |
||||
|
$_sms::sendNotify($v['phone'], $_str, 24); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,580 @@ |
|||||
|
<?php |
||||
|
|
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | ThinkAdmin |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 版权所有 2014~2019 广州楚才信息科技有限公司 [ http://www.cuci.cc ] |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 官方网站: http://demo.thinkadmin.top |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 开源协议 ( https://mit-license.org ) |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin |
||||
|
// | github 代码仓库:https://github.com/zoujingli/ThinkAdmin |
||||
|
// +---------------------------------------------------------------------- |
||||
|
|
||||
|
namespace app\index\controller; |
||||
|
|
||||
|
|
||||
|
use think\Db; |
||||
|
|
||||
|
/** |
||||
|
* 应用入口 |
||||
|
* Class Index |
||||
|
* @package app\index\controller |
||||
|
*/ |
||||
|
class House extends Base |
||||
|
{ |
||||
|
public $table = 'CloudHouse';//房源表 |
||||
|
public $table_room = 'CloudHouseRoom';//子房间表 |
||||
|
public $table_tenant = 'CloudHouseTenant';//租户表 |
||||
|
public $table_holder = 'CloudHouseHolder';//一房东表 |
||||
|
public $table_house_crontab = 'CloudHouseCrontab';//一房源定时提醒表 |
||||
|
public $table_order_room = 'CloudOrderRoom';//房间续租订单表 |
||||
|
|
||||
|
public function __construct() |
||||
|
{ |
||||
|
parent::__construct(); |
||||
|
parent::auth(); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 获取管理房源列表 |
||||
|
*/ |
||||
|
public function index() |
||||
|
{ |
||||
|
$_where['is_del'] = 0; |
||||
|
$_where['user_id'] = USER_ID; |
||||
|
$count = Db::name($this->table)->where($_where)->count(); |
||||
|
$page = $this->request->param('page', 1); |
||||
|
$pagesize = $this->request->param('pagesize', 10); |
||||
|
$pages = ceil($count / $pagesize); //总页数 |
||||
|
$_result = Db::name($this->table)->where($_where)->page($page, $pagesize)->order('id', "DESC")->select(); |
||||
|
$_data['list'] = $_result; |
||||
|
$_data['pages'] = $pages; |
||||
|
self::formatData($_data['list']); |
||||
|
return send_http_status(200, $_data); |
||||
|
} |
||||
|
|
||||
|
/**房源到期列表 |
||||
|
* @param int $day 是否只返回过期房源数量,false只返回 ,默认true |
||||
|
* @param bool $is_day |
||||
|
* @return \type |
||||
|
* @throws \think\db\exception\DataNotFoundException |
||||
|
* @throws \think\db\exception\ModelNotFoundException |
||||
|
* @throws \think\exception\DbException |
||||
|
*/ |
||||
|
public function expire($day = 3, $is_day = true) |
||||
|
{ |
||||
|
if ($day) { |
||||
|
//计算指定天数后的时间戳 |
||||
|
$day_time = strtotime('+' . $day . ' day'); |
||||
|
$_where[] = ['c.create_time', '<', $day_time]; //结束时间小于当前时间+3天 |
||||
|
$_where[] = ['c.create_time', '>', time()]; //且结束时间大于当前时间 |
||||
|
$_where[] = ['c.create_time', '<>', '']; |
||||
|
} |
||||
|
$_where[] = ['c.user_id', '=', USER_ID]; |
||||
|
$db = Db::name($this->table); |
||||
|
$db->alias('h')->join(['cloud_house_crontab' => 'c'], 'h.id = c.house_id'); |
||||
|
$db->where($_where)->where('h.is_del', 0); |
||||
|
$db->field('h.*,c.create_time AS expire_time'); |
||||
|
$_result = $db->order('h.id', "DESC")->select(); |
||||
|
if (!$is_day) { |
||||
|
return count($_result); |
||||
|
} |
||||
|
if (empty(count($_result))) { |
||||
|
return send_http_status(200, []); |
||||
|
} |
||||
|
self::formatRoomData($_result); |
||||
|
$_data['list'] = $_result; |
||||
|
$_data['pages'] = 1; |
||||
|
self::formatData($_data['list']); |
||||
|
return send_http_status(200, $_data); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 获取子房间列表 |
||||
|
* @param int $day 即将到期参数 不传默认 |
||||
|
* @param int $is_is_day 是否只返回过期房源数量,false只返回 ,默认true |
||||
|
* @return \type |
||||
|
* @throws \think\db\exception\DataNotFoundException |
||||
|
* @throws \think\db\exception\ModelNotFoundException |
||||
|
* @throws \think\exception\DbException |
||||
|
*/ |
||||
|
public function room($day = 0, $is_day = true) |
||||
|
{ |
||||
|
if ($day && is_numeric($day)) { |
||||
|
//计算指定天数后的时间戳 |
||||
|
$day_time = strtotime('+' . $day . ' day'); |
||||
|
$_where[] = ['r.end_time', '<', $day_time]; //结束时间小于当前时间+30天 |
||||
|
// $_where[] = ['end_time', '>', time()]; //且结束时间大于当前时间 |
||||
|
$_where[] = ['r.end_time', '<>', '']; |
||||
|
} |
||||
|
$_where[] = ['r.user_id', '=', USER_ID]; |
||||
|
$_where[] = ['r.is_del', '=', 0]; |
||||
|
$count = Db::name($this->table_room)->alias('r')->where($_where)->count(); |
||||
|
if (!$is_day) { |
||||
|
return $count; |
||||
|
} |
||||
|
$page = $this->request->param('page', 1); |
||||
|
$pagesize = $this->request->param('pagesize', 10); |
||||
|
$pages = ceil($count / $pagesize); //总页数 |
||||
|
$_result = Db::name($this->table_room)->alias('r')->leftJoin('cloud_house h', 'r.house_id = h.id')->where($_where)->page($page, $pagesize)->order('r.id', "DESC")->field('r.*,h.name,h.photo,h.province,h.city,h.area,h.door_number')->select(); |
||||
|
self::formatRoomData($_result); |
||||
|
$_data['list'] = $_result; |
||||
|
$_data['pages'] = $pages; |
||||
|
self::formatData($_data['list']); |
||||
|
return send_http_status(200, $_data); |
||||
|
} |
||||
|
|
||||
|
/**房间到期列表 |
||||
|
* @param int $day 是否只返回过期房源数量,false只返回 ,默认true |
||||
|
* @param bool $is_day |
||||
|
* @return \type |
||||
|
* @throws \think\db\exception\DataNotFoundException |
||||
|
* @throws \think\db\exception\ModelNotFoundException |
||||
|
* @throws \think\exception\DbException |
||||
|
*/ |
||||
|
public function expire_room($day = 3, $is_day = true) |
||||
|
{ |
||||
|
if ($day) { |
||||
|
//计算指定天数后的时间戳 |
||||
|
$day_time = strtotime('+' . $day . ' day'); |
||||
|
$_where[] = ['c.end_time', '<', $day_time]; //结束时间小于当前时间+3天 |
||||
|
// $_where[] = ['c.end_time', '>', time()]; //且结束时间大于当前时间 |
||||
|
$_where[] = ['c.end_time', '<>', '']; |
||||
|
$_where[] = ['c.status', '=', 0]; |
||||
|
$_where[] = ['c.is_del', '=', 0]; |
||||
|
} |
||||
|
$_where[] = ['c.user_id', '=', USER_ID]; |
||||
|
// $room_id = Db::name($this->table_room_crontab)->where($_where)->field('room_id')->select(); |
||||
|
$db = Db::name($this->table_room); |
||||
|
$db->alias('r')->leftJoin(['cloud_house' => 'h'], 'r.house_id = h.id')->join(['cloud_order_room' => 'c'], 'r.id = c.room_id'); |
||||
|
$db->where($_where)->where('r.is_del', 0); |
||||
|
$db->field('r.*,h.name,h.photo,h.province,h.city,h.area,h.door_number,c.end_time AS expire_time,c.start_time AS order_time'); |
||||
|
$_result = $db->order('r.id', "DESC")->select(); |
||||
|
if (!$is_day) { |
||||
|
return count($_result); |
||||
|
} |
||||
|
self::formatRoomData($_result); |
||||
|
$_data['list'] = $_result; |
||||
|
$_data['pages'] = 1; |
||||
|
self::formatData($_data['list']); |
||||
|
return send_http_status(200, $_data); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 房源详情 |
||||
|
* @param string $id 房源id |
||||
|
* @return \type|void |
||||
|
* @throws \think\db\exception\DataNotFoundException |
||||
|
* @throws \think\db\exception\ModelNotFoundException |
||||
|
* @throws \think\exception\DbException |
||||
|
*/ |
||||
|
public function view($id = '') |
||||
|
{ |
||||
|
if (!$id) { |
||||
|
return; |
||||
|
} |
||||
|
//获取房源详情 |
||||
|
$_data['house'] = Db::name($this->table)->find($id); |
||||
|
if ($_data['house']) { |
||||
|
//查询户主信息 |
||||
|
$_data['holder'] = Db::name($this->table_holder)->find($_data['house']['holder_id']); |
||||
|
//查询子房源列表 |
||||
|
$_data['room_list'] = Db::name($this->table_room)->where('is_del', 0)->where('house_id', $id)->order('id', "DESC")->select(); |
||||
|
//统计房间支付数据 |
||||
|
$_order = new Order(); |
||||
|
$_data['house']['orderAmount'] = $_order->orderAmount('', $id); |
||||
|
self::formatRoomData($_data['room_list']); |
||||
|
} |
||||
|
|
||||
|
self::formatViewData($_data['house']); |
||||
|
return send_http_status(200, $_data); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 子房间详情 |
||||
|
*/ |
||||
|
public function viewRoom($id = '') |
||||
|
{ |
||||
|
if (!$id) { |
||||
|
return; |
||||
|
} |
||||
|
//获取房源详情 |
||||
|
$_data['room'] = Db::name($this->table_room)->find($id); |
||||
|
if (!empty($_data['room'])) { |
||||
|
//查询租户列表 |
||||
|
$_where['room_id'] = $_data['room']['id']; |
||||
|
$_where['is_del'] = 0; |
||||
|
$_data['tenant_list'] = Db::name($this->table_tenant)->where($_where)->order('create_time DESC')->select(); |
||||
|
//统计房间支付数据 |
||||
|
$_order = new Order(); |
||||
|
$_data['room']['orderAmount'] = $_order->orderAmount($_data['room']['id']); |
||||
|
self::formatData($_data['tenant_list']); |
||||
|
} |
||||
|
self::formatViewData($_data['room']); |
||||
|
return send_http_status(200, $_data); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 租户详情 |
||||
|
*/ |
||||
|
public function viewTenant($id = '') |
||||
|
{ |
||||
|
if (!$id) { |
||||
|
return; |
||||
|
} |
||||
|
//获取租户详情 |
||||
|
$_data['tenant'] = Db::name($this->table_tenant)->find($id); |
||||
|
if (empty($_data['tenant'])) { |
||||
|
return; |
||||
|
} |
||||
|
$_data['tenant']['sex_id'] = $_data['tenant']['sex']; |
||||
|
$_data['tenant']['sex'] = config('sex')[$_data['tenant']['sex']]; |
||||
|
if (!empty($_data['tenant'])) { |
||||
|
//查询交租记录 |
||||
|
$_where['room_id'] = $_data['tenant']['id']; |
||||
|
$_data['tenant_list'] = Db::name($this->table_tenant)->where($_where)->select(); |
||||
|
} |
||||
|
return send_http_status(200, $_data); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 添加一手房源数据及一手房东信息 |
||||
|
*/ |
||||
|
public function add() |
||||
|
{ |
||||
|
$_data = $this->request->post(); |
||||
|
$_data['create_time'] = $_data['update_time'] = time(); |
||||
|
$_data['start_time'] = !empty($_data['start_time']) ? strtotime($_data['start_time']) : ''; |
||||
|
$_data['end_time'] = !empty($_data['end_time']) ? strtotime($_data['end_time']) : ''; |
||||
|
if ($_data['start_time'] >= $_data['end_time']) { |
||||
|
return send_http_status(51000); |
||||
|
} |
||||
|
//会员等级权限判断 |
||||
|
$count = Db::name($this->table)->where('user_id', USER_ID)->count(); |
||||
|
self::authAddHouse($count); |
||||
|
$_data['user_id'] = USER_ID; |
||||
|
$_data = array_filter($_data); |
||||
|
//添加一房东信息 |
||||
|
$holder_id = Db::name($this->table_holder)->strict(false)->insertGetId($_data); |
||||
|
if ($holder_id) { |
||||
|
//添加房源数据 |
||||
|
$_data['holder_id'] = $holder_id; |
||||
|
$id = Db::name($this->table)->strict(false)->insertGetId($_data); |
||||
|
if ($id) { |
||||
|
//定时任务短信提醒房租到期数据更新 |
||||
|
$_data['id'] = $id; //添加成功后的房源id |
||||
|
$this->crontab($_data); |
||||
|
return send_http_status(200); |
||||
|
} |
||||
|
} |
||||
|
return send_http_status(413); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 修改一手房源数据及一手房东信息 |
||||
|
*/ |
||||
|
public function edit() |
||||
|
{ |
||||
|
$_data = $this->request->post(); |
||||
|
$_data['update_time'] = time(); |
||||
|
$_data['user_id'] = USER_ID; |
||||
|
$_data['start_time'] = !empty($_data['start_time']) ? strtotime($_data['start_time']) : ''; |
||||
|
$_data['end_time'] = !empty($_data['end_time']) ? strtotime($_data['end_time']) : ''; |
||||
|
if ($_data['start_time'] >= $_data['end_time']) { |
||||
|
return send_http_status(51000); |
||||
|
} |
||||
|
//修改房源数据 |
||||
|
$affected = Db::name($this->table)->strict(false)->update($_data); |
||||
|
$_data = array_filter($_data); |
||||
|
if ($affected) { |
||||
|
//定时任务短信提醒房租到期数据更新 |
||||
|
$this->crontab($_data); |
||||
|
//修改一房东信息 |
||||
|
unset($_data['id']); |
||||
|
Db::name($this->table_holder)->where('id', $_data['holder_id'])->strict(false)->update($_data); |
||||
|
} |
||||
|
if ($affected) { |
||||
|
return send_http_status(200); |
||||
|
} |
||||
|
return send_http_status(413); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 添加子房间 |
||||
|
*/ |
||||
|
public function addRoom() |
||||
|
{ |
||||
|
//会员等级权限判断 |
||||
|
$count = Db::name($this->table_room)->where('user_id', USER_ID)->count(); |
||||
|
self::authAddHouse($count, 'count_room'); |
||||
|
$_data = $this->request->post(); |
||||
|
$_data['create_time'] = $_data['update_time'] = time(); |
||||
|
$_data['user_id'] = USER_ID; |
||||
|
$_data = array_filter($_data); |
||||
|
$id = Db::name($this->table_room)->strict(false)->insertGetId($_data); |
||||
|
if (!$id) { |
||||
|
return send_http_status(51002); |
||||
|
} |
||||
|
return send_http_status(200); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 修改子房间 |
||||
|
*/ |
||||
|
public function editRoom() |
||||
|
{ |
||||
|
self::authAddHouse(0, 'count_room'); |
||||
|
$_data = $this->request->post(); |
||||
|
//是否上架到首页共享房源,即清空时间节点 |
||||
|
if ($_data['is_up'] == 'true') { |
||||
|
$_data['start_time'] = $_data['end_time'] = time() - 10000; |
||||
|
} else { |
||||
|
$_data['start_time'] = !empty($_data['start_time']) ? strtotime($_data['start_time']) : ''; |
||||
|
$_data['end_time'] = !empty($_data['end_time']) ? strtotime($_data['end_time']) : ''; |
||||
|
if ($_data['start_time'] > $_data['end_time']) { |
||||
|
return send_http_status(51000); |
||||
|
} |
||||
|
} |
||||
|
$_data['update_time'] = time(); |
||||
|
$_data['user_id'] = USER_ID; |
||||
|
unset($_data['house_id']); |
||||
|
$refected = Db::name($this->table_room)->strict(false)->update($_data); |
||||
|
if (!$refected) { |
||||
|
return send_http_status(51002); |
||||
|
} |
||||
|
//根据用户指定收费方式 切割时间 |
||||
|
$_data['id'] = $_data['id']; //添加成功后的房间id |
||||
|
$this->crontab_room($_data, $_data['rent_type']); |
||||
|
return send_http_status(200); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 添加租户 |
||||
|
*/ |
||||
|
public function addTenant() |
||||
|
{ |
||||
|
$_data = $this->request->post(); |
||||
|
$where_tenant['room_id'] = $_data['room_id']; |
||||
|
$where_tenant['card_id'] = $_data['card_id']; |
||||
|
$_tenant = Db::name($this->table_tenant)->where($where_tenant)->find(); |
||||
|
if ($_tenant) { |
||||
|
return send_http_status(51001); |
||||
|
} |
||||
|
$_data['start_time'] = $house_data['start_time'] = !empty($_data['start_time']) ? strtotime($_data['start_time']) : ''; |
||||
|
$_data['end_time'] = $house_data['end_time'] = !empty($_data['end_time']) ? strtotime($_data['end_time']) : ''; |
||||
|
if ($_data['start_time'] > $_data['end_time']) { |
||||
|
return send_http_status(51000); |
||||
|
} |
||||
|
$_data['create_time'] = $_data['update_time'] = time(); |
||||
|
$_data['user_id'] = USER_ID; |
||||
|
$_data = array_filter($_data); |
||||
|
$refected = Db::name($this->table_tenant)->strict(false)->insert($_data); |
||||
|
if ($refected && $_data['start_time'] && $_data['end_time']) { |
||||
|
//更新房间开始时间及结束时间 |
||||
|
$where['id'] = $_data['room_id']; |
||||
|
Db::name($this->table_room)->where($where)->strict(false)->update($house_data); |
||||
|
//根据用户指定收费方式 切割时间 |
||||
|
$_data['id'] = $_data['room_id']; //添加成功后的房间id |
||||
|
$this->crontab_room($_data, $_data['rent_type']); |
||||
|
} |
||||
|
return send_http_status(200); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 添加租户 |
||||
|
*/ |
||||
|
public function editTenant() |
||||
|
{ |
||||
|
$_data = $this->request->post(); |
||||
|
$_data['update_time'] = time(); |
||||
|
$_data['user_id'] = USER_ID; |
||||
|
$_data = array_filter($_data); |
||||
|
$refected = Db::name($this->table_tenant)->strict(false)->update($_data); |
||||
|
if ($refected) { |
||||
|
return send_http_status(200); |
||||
|
} |
||||
|
return send_http_status(413); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 删除房源 |
||||
|
* @param string $id |
||||
|
*/ |
||||
|
public function delHouse($id = '') |
||||
|
{ |
||||
|
if (!$id || !is_numeric($id)) { |
||||
|
return send_http_status(51003); |
||||
|
} |
||||
|
$affected = Db::name($this->table)->where('id', $id)->where('user_id', USER_ID)->update(['is_del' => 1]); |
||||
|
if ($affected) { |
||||
|
//删除房间数据 |
||||
|
$this->delRoom('', $id); |
||||
|
return send_http_status(200); |
||||
|
} |
||||
|
return send_http_status(413); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 删除房间 |
||||
|
* @param string $id 房间id |
||||
|
* @param string $house_id 一手房源id |
||||
|
* @return \type |
||||
|
* @throws \think\Exception |
||||
|
* @throws \think\exception\PDOException |
||||
|
*/ |
||||
|
public function delRoom($id = '', $house_id = '') |
||||
|
{ |
||||
|
if ((!$id || !is_numeric($id)) && !$house_id) { |
||||
|
return send_http_status(51003); |
||||
|
} |
||||
|
//如果一手房源id存在,删除所有属于一手房源的子房间 |
||||
|
$_where = !empty($house_id) ? 'house_id=' . $house_id : 'id=' . $id; |
||||
|
//(如果存在house_id说明执行了删除一手房源,即room_id为多个,所以这里需要根据house_id查询所有room_id) |
||||
|
if ($house_id) { |
||||
|
$id = Db::name($this->table_room)->where('house_id', $house_id)->field('id')->select(); |
||||
|
$id = !empty($id) ? implode(',', array_column($id, 'id')) : ''; |
||||
|
} |
||||
|
$affected = Db::name($this->table_room)->where($_where)->where('user_id', USER_ID)->update(['is_del' => 1]); |
||||
|
if ($affected) { |
||||
|
//删除租客 |
||||
|
$this->delTenant('', $id); |
||||
|
return send_http_status(200); |
||||
|
} |
||||
|
return send_http_status(413); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 删除租客信息 |
||||
|
* @param string $id 租客id |
||||
|
* @param string $room_id 所属房间id |
||||
|
* @return \type |
||||
|
* @throws \think\Exception |
||||
|
* @throws \think\exception\PDOException |
||||
|
*/ |
||||
|
public function delTenant($id = '', $room_id = '') |
||||
|
{ |
||||
|
if ((!$id || !is_numeric($id)) && !$room_id) { |
||||
|
return send_http_status(51003); |
||||
|
} |
||||
|
//如果存在房间id,删除所有属于房间的租房用户 |
||||
|
if (!empty($room_id)) { |
||||
|
$_where[] = ['room_id', 'in', $room_id]; //tp5.1 需要这样写 |
||||
|
} else { |
||||
|
$_where = 'id=' . $id; |
||||
|
} |
||||
|
$affected = Db::name($this->table_tenant)->where($_where)->where('user_id', USER_ID)->update(['is_del' => 1]); |
||||
|
if ($affected) { |
||||
|
//删除租客 |
||||
|
Db::name($this->table_order_room)->where('tenant_id', $id)->update(['is_del' => 1]); |
||||
|
//租客交费记录删除(没有总数据统计,可不删除) |
||||
|
return send_http_status(200); |
||||
|
} |
||||
|
return send_http_status(413); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 房间数据格式化 |
||||
|
* @param $data |
||||
|
*/ |
||||
|
static private function formatRoomData(&$data) |
||||
|
{ |
||||
|
if (!$data) { |
||||
|
return; |
||||
|
} |
||||
|
array_walk($data, function (&$v, &$k) { |
||||
|
$v['days'] = time_days($v['end_time']); |
||||
|
$v['expire_days'] = isset($v['expire_time']) ? time_days($v['expire_time']) : ''; |
||||
|
!empty($v['expire_time']) ? $v['expire_time'] = date('Y-m-d', $v['expire_time']) : $v['expire_time'] = ''; |
||||
|
!empty($v['order_time']) ? $v['order_time'] = date('Y-m-d', $v['order_time']) : $v['order_time'] = ''; |
||||
|
//列表封面 |
||||
|
if (isset($v['photo'])) { |
||||
|
$_arr = explode(',', $v['photo']); |
||||
|
$v['thumb'] = !empty($_arr[0]) ? $_arr[0] : config('default_list_thumb'); |
||||
|
} |
||||
|
}); |
||||
|
|
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 添加定时任务时间节点(定时任务短信提醒房租到期数据更新) |
||||
|
* @param $_data 房源数据 |
||||
|
* @param int $month 指定分割月数 |
||||
|
* @throws \think\Exception |
||||
|
* @throws \think\exception\PDOException |
||||
|
*/ |
||||
|
private function crontab($_data, $month = 3) |
||||
|
{ |
||||
|
$start_time = $_data['start_time']; |
||||
|
$end_time = $_data['end_time']; |
||||
|
//计算指定天数后的时间戳 |
||||
|
$_arr = []; |
||||
|
while ($start_time < $end_time) { |
||||
|
$arr_temp['house_id'] = $_data['id']; |
||||
|
$arr_temp['user_id'] = USER_ID; |
||||
|
$arr_temp['house_name'] = $_data['name']; |
||||
|
$arr_temp['phone'] = MEMBER['phone']; |
||||
|
$arr_temp['rent'] = $_data['rent']; |
||||
|
$arr_temp['address'] = $_data['province'] . $_data['city'] . $_data['area']; |
||||
|
$arr_temp['door_number'] = $_data['door_number']; |
||||
|
$arr_temp['create_time'] = $start_time = strtotime('+' . $month . ' month', $start_time); |
||||
|
$_arr[] = $arr_temp; |
||||
|
} |
||||
|
//删除最后一个元素,置换为end_time(防止开始时间与结束时间不一致) |
||||
|
$last_arr = array_pop($_arr); |
||||
|
$last_arr['create_time'] = $end_time; |
||||
|
$_arr[] = $last_arr; |
||||
|
//新增前先清空 |
||||
|
$house_crontab = Db::name($this->table_house_crontab); |
||||
|
$house_crontab->where('house_id', $_data['id'])->where('user_id', USER_ID)->delete(); |
||||
|
$house_crontab->insertAll($_arr); |
||||
|
} |
||||
|
|
||||
|
static private function formatData(&$data) |
||||
|
{ |
||||
|
if (!$data) { |
||||
|
return; |
||||
|
} |
||||
|
array_walk($data, function (&$v, &$k) { |
||||
|
!empty($v['create_time']) ? $v['create_time'] = date('Y-m-d', $v['create_time']) : $v['create_time'] = ''; |
||||
|
!empty($v['update_time']) ? $v['update_time'] = date('Y-m-d', $v['update_time']) : $v['update_time'] = ''; |
||||
|
!empty($v['end_time']) ? $v['end_time'] = date('Y-m-d', $v['end_time']) : $v['end_time'] = ''; |
||||
|
!empty($v['start_time']) ? $v['start_time'] = date('Y-m-d', $v['start_time']) : $v['start_time'] = ''; |
||||
|
isset($v['sex']) ? $v['sex'] = config('sex')[$v['sex']] : ''; |
||||
|
//列表封面 |
||||
|
if (isset($v['photo'])) { |
||||
|
$_arr = explode(',', $v['photo']); |
||||
|
$v['thumb'] = !empty($_arr[0]) ? $_arr[0] : config('default_list_thumb'); |
||||
|
} |
||||
|
}); |
||||
|
|
||||
|
} |
||||
|
|
||||
|
static private function formatViewData(&$data) |
||||
|
{ |
||||
|
if (!empty($data['housing_allocation'])) { |
||||
|
//获取房间配置 |
||||
|
$housingAllocation = config('housingAllocation'); |
||||
|
$data['housing_allocation_str'] = ''; |
||||
|
//转换房间配置信息 |
||||
|
$allocation_arr = explode(',', $data['housing_allocation']); |
||||
|
foreach ($allocation_arr as $k => $v) { |
||||
|
$data['housing_allocation_str'] .= $housingAllocation[$k]['name'] . ','; |
||||
|
} |
||||
|
$data['housing_allocation_str'] = trim($data['housing_allocation_str'], ','); |
||||
|
$data['housing_allocation'] = explode(',', $data['housing_allocation']); |
||||
|
} |
||||
|
if (!empty($data['photo'])) { |
||||
|
$data['imgList'] = explode(',', $data['photo']); |
||||
|
} else { |
||||
|
$data['imgList'] = []; |
||||
|
} |
||||
|
!empty($data['create_time']) ? $data['create_time'] = date('Y-m-d', $data['create_time']) : $data['create_time'] = ''; |
||||
|
!empty($data['update_time']) ? $data['update_time'] = date('Y-m-d', $data['update_time']) : $data['update_time'] = ''; |
||||
|
!empty($data['end_time']) ? $data['end_time'] = date('Y-m-d', $data['end_time']) : $data['end_time'] = ''; |
||||
|
!empty($data['start_time']) ? $data['start_time'] = date('Y-m-d', $data['start_time']) : $data['start_time'] = ''; |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,193 @@ |
|||||
|
<?php |
||||
|
|
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | ThinkAdmin |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 版权所有 2014~2019 广州楚才信息科技有限公司 [ http://www.cuci.cc ] |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 官方网站: http://demo.thinkadmin.top |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 开源协议 ( https://mit-license.org ) |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin |
||||
|
// | github 代码仓库:https://github.com/zoujingli/ThinkAdmin |
||||
|
// +---------------------------------------------------------------------- |
||||
|
|
||||
|
namespace app\index\controller; |
||||
|
|
||||
|
use think\Controller; |
||||
|
use think\Db; |
||||
|
|
||||
|
/** |
||||
|
* 应用入口 |
||||
|
* Class Index |
||||
|
* @package app\index\controller |
||||
|
*/ |
||||
|
class Index extends Controller |
||||
|
{ |
||||
|
public $table = 'CloudHouse';//房源表 |
||||
|
public $table_room = 'CloudHouseRoom';//子房间表 |
||||
|
|
||||
|
/** |
||||
|
* 首页API |
||||
|
*/ |
||||
|
public function index() |
||||
|
{ |
||||
|
// $_collection = new Collection(); |
||||
|
// $_data['collection'] = $_collection->index(); |
||||
|
$_data['room'] = $this->roomShare(); |
||||
|
$user_id = $_SERVER['HTTP_USERID']; |
||||
|
if (empty($user_id)) { |
||||
|
$_data['expire_num'] = 0; |
||||
|
} else { |
||||
|
//房源类 |
||||
|
$_house = new House(); |
||||
|
//子房间到期数量 |
||||
|
$_data['expire_num'] = $_house->expire_room(3, false); |
||||
|
//子房间到期数量 |
||||
|
$_data['house_expire_num'] = $_house->expire(3, false); |
||||
|
} |
||||
|
return send_http_status(200, $_data); |
||||
|
|
||||
|
} |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* 获取未出租共享房源 |
||||
|
* @param int $num 公里数 默认为2 |
||||
|
* @param int $latitude 纬度 |
||||
|
* @param int $longitude 经度 |
||||
|
* @return \type |
||||
|
* @throws \think\db\exception\DataNotFoundException |
||||
|
* @throws \think\db\exception\ModelNotFoundException |
||||
|
* @throws \think\exception\DbException |
||||
|
*/ |
||||
|
public function roomShare() |
||||
|
{ |
||||
|
$_search = $this->request->param('', '', 'filter_danger_str'); |
||||
|
//判断是否含有 附近几公里的搜索条件 |
||||
|
$num = $this->request->param('num', '', 'filter_danger_str'); |
||||
|
$latitude = $this->request->param('latitude', '', 'filter_danger_str'); |
||||
|
$longitude = $this->request->param('longitude', '', 'filter_danger_str'); |
||||
|
|
||||
|
$_db = Db::name($this->table_room); |
||||
|
if (!empty($num) && !empty($latitude) && !empty($longitude)) { |
||||
|
$distance = 1; |
||||
|
//查询附近几公里的一手房源数据 |
||||
|
$sql = 'SELECT id,( |
||||
|
6371 * acos ( |
||||
|
cos ( radians(' . $latitude . ') ) |
||||
|
* cos( radians( latitude ) ) |
||||
|
* cos( radians( longitude ) - radians(' . $longitude . ') ) |
||||
|
+ sin ( radians(' . $latitude . ') ) |
||||
|
* sin( radians( latitude ) ) |
||||
|
) |
||||
|
) AS distance |
||||
|
FROM cloud_house |
||||
|
HAVING distance < ' . $num . ' |
||||
|
ORDER BY distance |
||||
|
LIMIT 0 , 500'; |
||||
|
$_house = Db::query($sql); |
||||
|
if (!empty($_house)) { |
||||
|
$house_ids = implode(array_column($_house, 'id'), ','); |
||||
|
} |
||||
|
//判断几公里搜索条件是否成立即 house_ids是否有值 |
||||
|
$house_ids = !empty($house_ids) ? $house_ids : 0; |
||||
|
$_db->where('h.id', 'in', $house_ids); |
||||
|
} |
||||
|
|
||||
|
//判断是否为会员 |
||||
|
$user_id = $_SERVER['HTTP_USERID']; |
||||
|
// $vip_level = Db::name('cloud_member')->field('vip_level')->find($user_id); |
||||
|
// if (empty($vip_level) || $vip_level['vip_level'] < 1) { |
||||
|
// $_db->where('h.user_id', $user_id); |
||||
|
// } |
||||
|
|
||||
|
//城市条件搜索 |
||||
|
if (!empty($_search['province']) && empty($distance)) { |
||||
|
$_db->where('h.province', $_search['province']); |
||||
|
$_db->where('h.city', $_search['city']); |
||||
|
$_db->where('h.area', $_search['area']); |
||||
|
} |
||||
|
if (!empty($_search['search']) && empty($distance)) { |
||||
|
$_db->where('h.name', 'like', '%' . $_search['search'] . '%'); |
||||
|
} |
||||
|
|
||||
|
$_db->alias('r')->leftjoin(['cloud_house' => 'h'], 'r.house_id = h.id')->leftjoin('cloud_member m', 'r.user_id = m.id'); |
||||
|
$_db->where('r.is_del', 0); |
||||
|
$_db->where('h.is_del', 0); |
||||
|
$_db->where(function ($query) { |
||||
|
$query->where('r.end_time', '=', 0); |
||||
|
$query->whereOr('r.end_time', '<', time()); |
||||
|
}); |
||||
|
|
||||
|
$count = $_db->count(); |
||||
|
$page = $this->request->param('page', 1, 'filter_danger_str'); |
||||
|
$pagesize = $this->request->param('pagesize', 10, 'filter_danger_str'); |
||||
|
$pages = ceil($count / $pagesize); //总页数 |
||||
|
$_db->page($page, $pagesize)->order('r.id', "DESC"); |
||||
|
$field = 'r.*,h.apartment,h.id AS house_id,h.name,h.name,h.photo,h.province,h.city,h.area,h.door_number,h.floor_num,m.phone'; |
||||
|
$_result = $_db->field($field)->select(); |
||||
|
self::formatRoomData($_result); |
||||
|
$_data['list'] = $_result; |
||||
|
$_data['pages'] = $pages; |
||||
|
self::formatData($_data['list']); |
||||
|
return $_data; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 获取未出租共享房源 根据公里数 |
||||
|
* @param int $num 公里数 默认为2 |
||||
|
* @param int $latitude 纬度 |
||||
|
* @param int $longitude 经度 |
||||
|
* @return \type |
||||
|
* @throws \think\db\exception\DataNotFoundException |
||||
|
* @throws \think\db\exception\ModelNotFoundException |
||||
|
* @throws \think\exception\DbException |
||||
|
*/ |
||||
|
public function roomShareLocation($num = 2, $latitude = '', $longitude = '') |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 房间数据格式化 |
||||
|
* @param $data |
||||
|
*/ |
||||
|
static private function formatRoomData(&$data) |
||||
|
{ |
||||
|
if (!$data) { |
||||
|
return; |
||||
|
} |
||||
|
array_walk($data, function (&$v, &$k) { |
||||
|
$v['days'] = time_days($v['end_time']); |
||||
|
//列表封面 |
||||
|
if (isset($v['photo'])) { |
||||
|
$_arr = explode(',', $v['photo']); |
||||
|
$v['thumb'] = !empty($_arr[0]) ? $_arr[0] : config('default_list_thumb'); |
||||
|
} |
||||
|
}); |
||||
|
|
||||
|
} |
||||
|
|
||||
|
static private function formatData(&$data) |
||||
|
{ |
||||
|
if (!$data) { |
||||
|
return; |
||||
|
} |
||||
|
array_walk($data, function (&$v, &$k) { |
||||
|
!empty($v['create_time']) ? $v['create_time'] = date('Y-m-d', $v['create_time']) : $v['create_time'] = ''; |
||||
|
!empty($v['update_time']) ? $v['update_time'] = date('Y-m-d', $v['update_time']) : $v['update_time'] = ''; |
||||
|
!empty($v['end_time']) ? $v['end_time'] = date('Y-m-d', $v['end_time']) : $v['end_time'] = ''; |
||||
|
!empty($v['start_time']) ? $v['start_time'] = date('Y-m-d', $v['start_time']) : $v['start_time'] = ''; |
||||
|
isset($v['sex']) ? $v['sex'] = config('sex')[$v['sex']] : ''; |
||||
|
//列表封面 |
||||
|
if (isset($v['photo'])) { |
||||
|
$_arr = explode(',', $v['photo']); |
||||
|
$v['thumb'] = !empty($_arr[0]) ? $_arr[0] : config('default_list_thumb'); |
||||
|
} |
||||
|
}); |
||||
|
|
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,106 @@ |
|||||
|
<?php |
||||
|
|
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | ThinkAdmin |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 版权所有 2014~2019 广州楚才信息科技有限公司 [ http://www.cuci.cc ] |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 官方网站: http://demo.thinkadmin.top |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 开源协议 ( https://mit-license.org ) |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin |
||||
|
// | github 代码仓库:https://github.com/zoujingli/ThinkAdmin |
||||
|
// +---------------------------------------------------------------------- |
||||
|
|
||||
|
namespace app\index\controller; |
||||
|
|
||||
|
|
||||
|
use library\Controller; |
||||
|
use think\Db; |
||||
|
|
||||
|
/** |
||||
|
* 用户登录 |
||||
|
* Class Plugs |
||||
|
* @package app\admin\controller\api |
||||
|
*/ |
||||
|
class Login extends Controller |
||||
|
{ |
||||
|
|
||||
|
private $table_member = 'CloudMember'; |
||||
|
private $table_subaccount = 'CloudSubaccount'; |
||||
|
|
||||
|
/** |
||||
|
* 用户登录,先获取用户信息,再入库操作 |
||||
|
* @return \type |
||||
|
* @throws \WeChat\Exceptions\InvalidDecryptException |
||||
|
* @throws \WeChat\Exceptions\InvalidResponseException |
||||
|
* @throws \think\db\exception\DataNotFoundException |
||||
|
* @throws \think\db\exception\ModelNotFoundException |
||||
|
* @throws \think\exception\DbException |
||||
|
*/ |
||||
|
public function index() |
||||
|
{ |
||||
|
$iv = $this->request->param('iv'); |
||||
|
$encryptedData = $this->request->param('encryptedData'); |
||||
|
$code = $this->request->param('code'); |
||||
|
$config = config('appid'); |
||||
|
//实例化类解密类 |
||||
|
$crypt = \We::WeMiniCrypt($config); |
||||
|
$_data = $crypt->userInfo($code, $iv, $encryptedData); |
||||
|
if (isset($_data['openid'])) { |
||||
|
//先查询openid是否存在 |
||||
|
$_result = Db::name($this->table_member)->where('openid', $_data['openid'])->find(); |
||||
|
if ($_result) { |
||||
|
$_result['imgList'] = !empty($_result['qrcode']) ? explode(',', $_result['qrcode']) : ''; |
||||
|
self::formatMemberData($_result); |
||||
|
return send_http_status(200, $_result); |
||||
|
} |
||||
|
$_data['headimg'] = $_data['avatarUrl']; |
||||
|
$_data['sex'] = $_data['gender']; |
||||
|
$_data['nickname'] = $_data['nickName']; |
||||
|
$_data['create_time'] = $_data['update_time'] = time(); |
||||
|
if ($insert_id = Db::name($this->table_member)->strict(false)->insertGetId($_data)) { |
||||
|
$_data['id'] = $insert_id; |
||||
|
$_data['subaccount_id'] = 0; |
||||
|
return send_http_status(200, $_data); |
||||
|
} |
||||
|
return send_http_status(51006); |
||||
|
|
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 子账号登录 |
||||
|
*/ |
||||
|
public function subaccount() |
||||
|
{ |
||||
|
$_data = $this->request->post(); |
||||
|
//比对账号密码 |
||||
|
$_user = Db::name($this->table_subaccount)->where('username', $_data['username'])->where('status', 1)->find(); |
||||
|
if (!$_user) { |
||||
|
return send_http_status(51012); |
||||
|
} |
||||
|
if ($_user['password'] != sha1($_data['password'])) { |
||||
|
return send_http_status(51012); |
||||
|
} |
||||
|
$_member = Db::name($this->table_member)->find($_user['user_id']); |
||||
|
if (!$_member) { |
||||
|
return send_http_status(415); |
||||
|
} |
||||
|
$_member['subaccount_id'] = $_user['id']; //赋值子账号id |
||||
|
self::formatMemberData($_member); |
||||
|
return send_http_status(200, $_member); |
||||
|
} |
||||
|
|
||||
|
static private function formatMemberData(&$data) |
||||
|
{ |
||||
|
if (!$data) { |
||||
|
return; |
||||
|
} |
||||
|
!empty($data['create_time']) ? $data['create_time'] = date('Y-m-d', $data['create_time']) : $data['create_time'] = ''; |
||||
|
!empty($data['update_time']) ? $data['update_time'] = date('Y-m-d', $data['update_time']) : $data['update_time'] = ''; |
||||
|
!empty($data['vip_time']) ? $data['vip_time'] = date('Y-m-d', $data['vip_time']) : $data['vip_time'] = ''; |
||||
|
!empty($data['vip_endtime']) ? $data['vip_endtime'] = date('Y-m-d', $data['vip_endtime']) : $data['vip_endtime'] = ''; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,238 @@ |
|||||
|
<?php |
||||
|
|
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | ThinkAdmin |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 版权所有 2014~2019 广州楚才信息科技有限公司 [ http://www.cuci.cc ] |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 官方网站: http://demo.thinkadmin.top |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 开源协议 ( https://mit-license.org ) |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin |
||||
|
// | github 代码仓库:https://github.com/zoujingli/ThinkAdmin |
||||
|
// +---------------------------------------------------------------------- |
||||
|
|
||||
|
namespace app\index\controller; |
||||
|
|
||||
|
|
||||
|
use think\App; |
||||
|
use think\Db; |
||||
|
|
||||
|
/** |
||||
|
* 应用入口 |
||||
|
* Class Index |
||||
|
* @package app\index\controller |
||||
|
*/ |
||||
|
class Member extends Base |
||||
|
{ |
||||
|
private $table = 'CloudMember'; |
||||
|
private $table_house = 'CloudHouse'; |
||||
|
private $table_room = 'CloudHouseRoom'; |
||||
|
|
||||
|
public function __construct(App $app = null) |
||||
|
{ |
||||
|
parent::__construct($app); |
||||
|
parent::auth(); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 设置保洁 |
||||
|
*/ |
||||
|
public function setClean(){ |
||||
|
$param = $this->request->param(); |
||||
|
Db::name($this->table)->update(['id'=>$param['id'],'is_clean'=>$param['is_clean']]); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 获取管理用户列表 |
||||
|
*/ |
||||
|
public function index() |
||||
|
{ |
||||
|
//判断当前用户是否为管理员 |
||||
|
if (!MEMBER['is_manager']) { |
||||
|
return send_http_status(414); |
||||
|
} |
||||
|
$_where = 'status =1'; |
||||
|
$count = Db::name($this->table)->where($_where)->count(); |
||||
|
$page = $this->request->param('page', 1); |
||||
|
$pagesize = $this->request->param('pagesize', 10); |
||||
|
$pages = ceil($count / $pagesize); //总页数 |
||||
|
$_result = Db::name($this->table)->where($_where)->page($page, $pagesize)->order('id', "DESC")->select(); |
||||
|
$_data['list'] = $_result; |
||||
|
$_data['pages'] = $pages; |
||||
|
self::formatData($_data['list']); |
||||
|
return send_http_status(200, $_data); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 绑定用户手机号 |
||||
|
*/ |
||||
|
public function bindPhone() |
||||
|
{ |
||||
|
$iv = $this->request->param('iv'); |
||||
|
$encryptedData = $this->request->param('encryptedData'); |
||||
|
$code = $this->request->param('code'); |
||||
|
//获取小程序appid配置 |
||||
|
$config = config('appid'); |
||||
|
$crypt = \We::WeMiniCrypt($config); |
||||
|
//通过code获取 opendi及session_key |
||||
|
$_session = $crypt->session($code); |
||||
|
if (is_array($_session)) { |
||||
|
//解密用户数据 |
||||
|
$_data = $crypt->decode($iv, $_session['session_key'], $encryptedData); |
||||
|
if (isset($_data['phoneNumber']) && !empty($_data['phoneNumber'])) { |
||||
|
//通过openid修改用户手机号 |
||||
|
$affected = Db::name($this->table)->where('openid', $_session['openid'])->update(['phone' => $_data['phoneNumber']]); |
||||
|
if ($affected > -1) { |
||||
|
return send_http_status(200); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
return send_http_status(51007); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 用户资料修改 |
||||
|
*/ |
||||
|
public function modify() |
||||
|
{ |
||||
|
$_data = $this->request->post(); |
||||
|
//添加房源数据 |
||||
|
$_data = array_filter($_data); |
||||
|
$safe_data['pay_info'] = !empty($_data['pay_info']) ? $_data['pay_info'] : ''; |
||||
|
$safe_data['phone'] = $_data['phone']; |
||||
|
$safe_data['qrcode'] = $_data['qrcode']; |
||||
|
$safe_data['truename'] = $_data['truename']; |
||||
|
$safe_data['card_number'] = $_data['card_number']; |
||||
|
$safe_data['update_time'] = time(); |
||||
|
$safe_data['id'] = USER_ID; |
||||
|
$affected = Db::name($this->table)->strict(false)->update($safe_data); |
||||
|
if ($affected) { |
||||
|
$_member = Db::name($this->table)->find(USER_ID); |
||||
|
if (!empty($_member['qrcode'])) { |
||||
|
$_member['imgList'] = explode(',', $_member['qrcode']); |
||||
|
} |
||||
|
return send_http_status(200, $_member); |
||||
|
} |
||||
|
return send_http_status(413); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 会员详情 |
||||
|
* @param string $id 会员id |
||||
|
* @return \type|void |
||||
|
* @throws \think\db\exception\DataNotFoundException |
||||
|
* @throws \think\db\exception\ModelNotFoundException |
||||
|
* @throws \think\exception\DbException |
||||
|
*/ |
||||
|
public function view($id = '') |
||||
|
{ |
||||
|
if (!$id) { |
||||
|
return; |
||||
|
} |
||||
|
//获取房源详情 |
||||
|
$_data['member'] = Db::name($this->table)->find($id); |
||||
|
if ($_data['member']) { |
||||
|
//查询所有房源数据 |
||||
|
$_data['house_count'] = Db::name($this->table_house)->where('is_del', 0)->where('user_id', $_data['member']['id'])->count(); |
||||
|
$_data['room_count'] = Db::name($this->table_room)->where('is_del', 0)->where('user_id', $_data['member']['id'])->count(); |
||||
|
$_data['vip_level'] = config('vip_level'); |
||||
|
} |
||||
|
|
||||
|
self::formatViewData($_data['member']); |
||||
|
return send_http_status(200, $_data); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 获取用户信息 |
||||
|
* @param string $id |
||||
|
* @return \type |
||||
|
* @throws \think\db\exception\DataNotFoundException |
||||
|
* @throws \think\db\exception\ModelNotFoundException |
||||
|
* @throws \think\exception\DbException |
||||
|
*/ |
||||
|
public function getInfo($id = '') |
||||
|
{ |
||||
|
//先查询openid是否存在 |
||||
|
$_result = Db::name($this->table)->where('id', $id)->find(); |
||||
|
if ($_result) { |
||||
|
$_result['imgList'] = !empty($_result['qrcode']) ? explode(',', $_result['qrcode']) : ''; |
||||
|
self::formatViewData($_result); |
||||
|
return send_http_status(200, $_result); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 修改会员等级 |
||||
|
* @param string $user_id 被修改的用户id |
||||
|
* @param int $level 修改等级 |
||||
|
* @return \type |
||||
|
* @throws \think\Exception |
||||
|
* @throws \think\exception\PDOException |
||||
|
*/ |
||||
|
public function level($user_id = '', $level = 0) |
||||
|
{ |
||||
|
if (!$user_id || !is_numeric($user_id) || !in_array($level, [0, 1, 2, 3])) { |
||||
|
return send_http_status(51005); |
||||
|
} |
||||
|
//判断当前用户是否为管理员 |
||||
|
if (!MEMBER['is_manager']) { |
||||
|
return send_http_status(414); |
||||
|
} |
||||
|
$affected = Db::name($this->table)->where('id', $user_id)->update(['vip_level' => $level, 'vip_time' => time()]); |
||||
|
return send_http_status(200); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* 修改会员状态 |
||||
|
* @param string $user_id 被修改的用户id |
||||
|
* @return \type |
||||
|
* @throws \think\Exception |
||||
|
* @throws \think\exception\PDOException |
||||
|
*/ |
||||
|
public function del($id = '') |
||||
|
{ |
||||
|
if (!$id || !is_numeric($id)) { |
||||
|
return send_http_status(51003); |
||||
|
} |
||||
|
//判断当前用户是否为管理员 |
||||
|
if (!MEMBER['is_manager']) { |
||||
|
return send_http_status(414); |
||||
|
} |
||||
|
$affected = Db::name($this->table)->where('id', $id)->update(['status' => 0]); |
||||
|
return send_http_status(200); |
||||
|
} |
||||
|
|
||||
|
static private function formatData(&$data) |
||||
|
{ |
||||
|
if (!$data) { |
||||
|
return; |
||||
|
} |
||||
|
$vip_level = config('vip_level'); |
||||
|
array_walk($data, function (&$v, &$k) use ($vip_level) { |
||||
|
!empty($v['create_time']) ? $v['create_time'] = date('Y-m-d', $v['create_time']) : $v['create_time'] = ''; |
||||
|
!empty($v['update_time']) ? $v['update_time'] = date('Y-m-d', $v['update_time']) : $v['update_time'] = ''; |
||||
|
!empty($v['vip_time']) ? $v['vip_time'] = date('Y-m-d', $v['vip_time']) : $v['vip_time'] = ''; |
||||
|
isset($v['sex']) ? $v['sex'] = config('sex')[$v['sex']] : ''; |
||||
|
//列表封面 |
||||
|
if (isset($v['vip_level'])) { |
||||
|
$v['vip_level_color'] = $vip_level[$v['vip_level']]['color']; |
||||
|
$v['vip_level'] = $vip_level[$v['vip_level']]['name']; |
||||
|
} |
||||
|
}); |
||||
|
|
||||
|
} |
||||
|
|
||||
|
static private function formatViewData(&$data) |
||||
|
{ |
||||
|
!empty($data['create_time']) ? $data['create_time'] = date('Y-m-d', $data['create_time']) : $data['create_time'] = ''; |
||||
|
!empty($data['update_time']) ? $data['update_time'] = date('Y-m-d', $data['update_time']) : $data['update_time'] = ''; |
||||
|
!empty($data['vip_time']) ? $data['vip_time'] = date('Y-m-d', $data['vip_time']) : $data['vip_time'] = ''; |
||||
|
!empty($data['vip_endtime']) ? $data['vip_endtime'] = date('Y-m-d', $data['vip_endtime']) : $data['vip_endtime'] = ''; |
||||
|
$data['vip_level_str'] = config('vip_level')[$data['vip_level']]['name']; |
||||
|
$data['vip_level_color'] = config('vip_level')[$data['vip_level']]['color']; |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,67 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace app\index\controller; |
||||
|
|
||||
|
use think\Controller; |
||||
|
use think\Db; |
||||
|
|
||||
|
class Notify extends Controller{ |
||||
|
|
||||
|
public function clean(){ |
||||
|
$wechat = new \WeChat\Pay(config('wechat.miniapp')); |
||||
|
// 4. 获取通知参数 |
||||
|
$data = $wechat->getNotify(); |
||||
|
//file_put_contents('./wechat_pay.log', var_export($data,true),FILE_APPEND); |
||||
|
if ($data['return_code'] === 'SUCCESS' && $data['result_code'] === 'SUCCESS') { |
||||
|
// @todo 去更新下原订单的支付状态 |
||||
|
$order_no = $data['out_trade_no']; |
||||
|
$update = [ |
||||
|
'order_no'=>$order_no, |
||||
|
'pay_money'=>$data['total_fee'] / 100, |
||||
|
'pay_time'=>time(), |
||||
|
'transaction_no'=>$data['transaction_id'], |
||||
|
'state'=> 1, |
||||
|
]; |
||||
|
try { |
||||
|
$res = Db::name('CloudCleanOrder')->where('order_no',$order_no)->update($update); |
||||
|
if ($res){ |
||||
|
$this->selectClean($order_no, $data['openid']); |
||||
|
// 返回接收成功的回复 |
||||
|
ob_clean(); |
||||
|
echo $wechat->getNotifySuccessReply(); |
||||
|
} |
||||
|
}catch (\Throwable $e){ |
||||
|
file_put_contents('./wechat_pay.log', $e->getMessage(),FILE_APPEND); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 分配保洁 |
||||
|
*/ |
||||
|
public function selectClean($order_no = 0,$openid = 0){ |
||||
|
|
||||
|
$sql = Db::name('CloudCleanOrder') |
||||
|
->alias('o') |
||||
|
->where('m.openid',Db::raw('o.service_openid')) |
||||
|
->where('complete','<',Db::raw('second')) |
||||
|
->field('count(*)') |
||||
|
->buildSql(); |
||||
|
$clean = Db::name('CloudMember') |
||||
|
->alias('m') |
||||
|
->field($sql.' as counts,m.id, m.openid, m.nickname') |
||||
|
->where('is_clean',1) |
||||
|
->where('m.openid','<>',$openid) |
||||
|
->order('counts','asc') |
||||
|
->order('id','asc') |
||||
|
->select(); |
||||
|
|
||||
|
if (!$clean) { |
||||
|
file_put_contents('./wechat_pay.log', "\nnot find cleaner\n",FILE_APPEND); |
||||
|
return false; |
||||
|
} |
||||
|
$first = current($clean); |
||||
|
Db::name('CloudCleanOrder')->where('order_no',$order_no)->update(['service_openid'=>$first['openid']]); |
||||
|
//dump($res); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,233 @@ |
|||||
|
<?php |
||||
|
|
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | ThinkAdmin |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 版权所有 2014~2019 广州楚才信息科技有限公司 [ http://www.cuci.cc ] |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 官方网站: http://demo.thinkadmin.top |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 开源协议 ( https://mit-license.org ) |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin |
||||
|
// | github 代码仓库:https://github.com/zoujingli/ThinkAdmin |
||||
|
// +---------------------------------------------------------------------- |
||||
|
|
||||
|
namespace app\index\controller; |
||||
|
|
||||
|
|
||||
|
use think\App; |
||||
|
use think\Db; |
||||
|
|
||||
|
/** |
||||
|
* 订单管理 |
||||
|
* Class Index |
||||
|
* @package app\index\controller |
||||
|
*/ |
||||
|
class Order extends Base |
||||
|
{ |
||||
|
private $table = 'CloudOrder'; |
||||
|
private $table_tenant_order = 'CloudOrderRoom'; |
||||
|
private $table_room = 'CloudHouseRoom'; |
||||
|
private $table_member = 'CloudMember'; |
||||
|
|
||||
|
public function __construct(App $app = null) |
||||
|
{ |
||||
|
parent::__construct($app); |
||||
|
parent::auth(); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 获取订单列表 |
||||
|
*/ |
||||
|
public function index() |
||||
|
{ |
||||
|
//判断当前用户是否为管理员 |
||||
|
if (!MEMBER['is_manager']) { |
||||
|
$_where = 'user_id = ' . USER_ID; |
||||
|
} else { |
||||
|
$_where = ''; |
||||
|
} |
||||
|
$count = Db::name($this->table)->where($_where)->count(); |
||||
|
$page = $this->request->param('page', 1); |
||||
|
$pagesize = $this->request->param('pagesize', 10); |
||||
|
$pages = ceil($count / $pagesize); //总页数 |
||||
|
$_result = Db::name($this->table)->where($_where)->page($page, $pagesize)->order('id', "DESC")->select(); |
||||
|
$_data['list'] = $_result; |
||||
|
$_data['pages'] = $pages; |
||||
|
self::formatData($_data['list']); |
||||
|
return send_http_status(200, $_data); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 统计房源所有收入或者该房间收入 |
||||
|
* @param string $room_id 指定房间id 不指定默认所有房 |
||||
|
* @param string $id 指定房源id |
||||
|
* @return float |
||||
|
*/ |
||||
|
public function orderAmount($room_id = '', $house_id = '') |
||||
|
{ |
||||
|
$_where['user_id'] = USER_ID; |
||||
|
$_where['status'] = 1; |
||||
|
if ($room_id) { |
||||
|
$_where['room_id'] = $room_id; |
||||
|
} |
||||
|
$_db = Db::name($this->table_tenant_order)->where($_where); |
||||
|
if ($house_id) { |
||||
|
//查询此房源下面的子房间数据 |
||||
|
$id_arr = Db::name($this->table_room)->where('house_id', $house_id)->column('id'); |
||||
|
if (empty($id_arr)) { |
||||
|
return 0; |
||||
|
} |
||||
|
$_db->where('room_id', 'in', implode(',', $id_arr)); |
||||
|
} |
||||
|
$count = $_db->sum('price'); |
||||
|
return $count; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 获取租户订单 |
||||
|
*/ |
||||
|
public function tenant() |
||||
|
{ |
||||
|
$_where['user_id'] = USER_ID; |
||||
|
$phone = $this->request->param('phone', ''); |
||||
|
$room_id = $this->request->param('room_id', ''); |
||||
|
if ($phone) { |
||||
|
$_where['phone'] = $phone; |
||||
|
} |
||||
|
if ($room_id) { |
||||
|
$_where['room_id'] = $room_id; |
||||
|
} |
||||
|
$_where['is_del'] = 0; |
||||
|
$count = Db::name($this->table_tenant_order)->where($_where)->count(); |
||||
|
$page = $this->request->param('page', 1); |
||||
|
$pagesize = $this->request->param('pagesize', 10); |
||||
|
$pages = ceil($count / $pagesize); //总页数 |
||||
|
$_result = Db::name($this->table_tenant_order)->where($_where)->page($page, $pagesize)->order('id', "DESC")->select(); |
||||
|
$_data['list'] = $_result; |
||||
|
$_data['pages'] = $pages; |
||||
|
self::formatData($_data['list']); |
||||
|
return send_http_status(200, $_data); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 新增vip开通订单 |
||||
|
*/ |
||||
|
public function add() |
||||
|
{ |
||||
|
$_data = $this->request->post(); |
||||
|
$config = config('vip_level'); |
||||
|
//添加房源数据 |
||||
|
$_data = array_filter($_data); |
||||
|
$_data['status'] = 0; |
||||
|
$_data['price'] = !empty($_data['vip_level']) ? $config[$_data['vip_level']]['price'] : '0'; |
||||
|
$_data['create_time'] = $_data['update_time'] = time(); |
||||
|
$_data['user_id'] = USER_ID; |
||||
|
$affected = Db::name($this->table)->strict(false)->insert($_data); |
||||
|
if ($affected) { |
||||
|
return send_http_status(200); |
||||
|
} |
||||
|
return send_http_status(51008); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 修改订单状态 |
||||
|
*/ |
||||
|
public function edit() |
||||
|
{ |
||||
|
//判断当前用户是否为管理员 |
||||
|
if (!MEMBER['is_manager']) { |
||||
|
return send_http_status(414); |
||||
|
} |
||||
|
$_data = $this->request->post(); |
||||
|
if (!isset($_data['id']) || !is_numeric($_data['id'])) { |
||||
|
return send_http_status(51005); |
||||
|
} |
||||
|
$_data = array_filter($_data); |
||||
|
$_data['update_time'] = time(); |
||||
|
$affected = Db::name($this->table)->strict(false)->update($_data); |
||||
|
if ($affected) { |
||||
|
//如果订单修改成功,且为审核通过 执行会员状态更新 |
||||
|
if ($_data['status'] == 1) { |
||||
|
//查询当前订单等级 |
||||
|
$_order = Db::name($this->table)->where('id', $_data['id'])->find(); |
||||
|
$_member['vip_time'] = $_member['update_time'] = time(); |
||||
|
$_member['vip_endtime'] = strtotime('+1 year'); |
||||
|
$_member['vip_level'] = $_order['vip_level']; |
||||
|
$_member['id'] = $_order['user_id']; |
||||
|
Db::name($this->table_member)->strict(false)->update($_member); |
||||
|
} |
||||
|
return send_http_status(200); |
||||
|
} |
||||
|
return send_http_status(51009); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 修改租户订单状态 |
||||
|
*/ |
||||
|
public function tenantEdit() |
||||
|
{ |
||||
|
$_data = $this->request->post(); |
||||
|
if (!isset($_data['id']) || !is_numeric($_data['id'])) { |
||||
|
return send_http_status(51005); |
||||
|
} |
||||
|
$_data = array_filter($_data); |
||||
|
$_data['update_time'] = time(); |
||||
|
$affected = Db::name($this->table_tenant_order)->strict(false)->update($_data); |
||||
|
if ($affected) { |
||||
|
//如果订单修改成功,且为审核通过 执行当前房自动续费 |
||||
|
if ($_data['status'] == 1) { |
||||
|
//查询订单中增加的确认日期 |
||||
|
$_order = Db::name($this->table_tenant_order)->where('status', 1)->field('room_id,rent_type')->find($_data['id']); |
||||
|
if (empty($_order)) { |
||||
|
return send_http_status(51013); |
||||
|
} |
||||
|
//先查询此房的开始及结束日期 |
||||
|
$_room = Db::name($this->table_room)->where('is_del', 0)->find($_order['room_id']); |
||||
|
if (!$_room) { |
||||
|
return send_http_status(51015); |
||||
|
} |
||||
|
$month = $_order['rent_type']; //增加的月数 |
||||
|
//判断原房间 结束日期是否为空或者是否已过期 |
||||
|
// $second = $_room['end_time'] + ($month * 30 * 24 * 60 * 60); //把月时间换成秒单位 并添加到现有有时间戳 |
||||
|
$second = $_room['end_time']; |
||||
|
$now_month = strtotime('+' . $month . ' month'); //以当前时间往后累计指定的$month |
||||
|
$end_time = empty($_room['end_time']) || $_room['end_time'] < time() ? $now_month : $second; |
||||
|
//增加此房间的到期日期 |
||||
|
$start_end_time = [ |
||||
|
'id' => $_order['room_id'], |
||||
|
'start_time' => time(), |
||||
|
'end_time' => $end_time, |
||||
|
]; |
||||
|
// if (!Db::name($this->table_room)->update($start_end_time)) { |
||||
|
// return send_http_status(51014); |
||||
|
// } |
||||
|
//修改定时任务提醒 |
||||
|
// $this->crontab_room($start_end_time, $month); |
||||
|
} |
||||
|
return send_http_status(200); |
||||
|
} |
||||
|
return send_http_status(51009); |
||||
|
} |
||||
|
|
||||
|
static private function formatData(&$data) |
||||
|
{ |
||||
|
if (!$data) { |
||||
|
return; |
||||
|
} |
||||
|
$vip_level = config('vip_level'); |
||||
|
$pay_type = config('pay_type'); |
||||
|
array_walk($data, function (&$v, &$k) use ($vip_level, $pay_type) { |
||||
|
!empty($v['create_time']) ? $v['create_time'] = date('Y-m-d', $v['create_time']) : $v['create_time'] = ''; |
||||
|
!empty($v['update_time']) ? $v['update_time'] = date('Y-m-d', $v['update_time']) : $v['update_time'] = ''; |
||||
|
!empty($v['start_time']) ? $v['start_time'] = date('Y-m-d', $v['start_time']) : $v['start_time'] = ''; |
||||
|
!empty($v['end_time']) ? $v['end_time'] = date('Y-m-d', $v['end_time']) : $v['end_time'] = ''; |
||||
|
//支付方式 |
||||
|
if (isset($v['price'])) { |
||||
|
$v['pay_type'] = $pay_type[$v['pay_type']]['name']; |
||||
|
} |
||||
|
}); |
||||
|
|
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,187 @@ |
|||||
|
<?php |
||||
|
/*---------------------------------------------------------------------- |
||||
|
* 项目名称: CloudAdmin |
||||
|
* +---------------------------------------------------------------------- |
||||
|
* 版权所有: 2014~2020 安徽云掌开发团队 |
||||
|
* +---------------------------------------------------------------------- |
||||
|
* 官方网站: [ http://www.yaoyz.com、http://www.ahyunzhang.com ] |
||||
|
* +---------------------------------------------------------------------- |
||||
|
* Date: 2018/11/15 9:47 |
||||
|
* +---------------------------------------------------------------------- |
||||
|
* Des: 短信插件 |
||||
|
+----------------------------------------------------------------------*/ |
||||
|
|
||||
|
|
||||
|
namespace app\index\controller; |
||||
|
|
||||
|
use think\Controller; |
||||
|
use think\Db; |
||||
|
|
||||
|
class Pay extends Controller |
||||
|
{ |
||||
|
|
||||
|
/** |
||||
|
* 房源表 |
||||
|
* @var string |
||||
|
*/ |
||||
|
private $table_house = 'CloudHouse'; |
||||
|
|
||||
|
/** |
||||
|
* 房间表 |
||||
|
* @var string |
||||
|
*/ |
||||
|
private $table_room = 'CloudHouseRoom'; |
||||
|
|
||||
|
/** |
||||
|
* 合同表 |
||||
|
* @var string |
||||
|
*/ |
||||
|
private $table_contract = 'CloudHouseContract'; |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* 租户表 |
||||
|
* @var string |
||||
|
*/ |
||||
|
private $table_tenant = 'CloudHouseTenant'; |
||||
|
|
||||
|
/** |
||||
|
* 租户表 |
||||
|
* @var string |
||||
|
*/ |
||||
|
private $table_member = 'CloudMember'; |
||||
|
|
||||
|
/** |
||||
|
* 租户表 |
||||
|
* @var string |
||||
|
*/ |
||||
|
private $table_order = 'CloudOrderRoom'; |
||||
|
|
||||
|
/** |
||||
|
* 支付页面 |
||||
|
* @param int $roomid 房间id |
||||
|
*/ |
||||
|
public function index() |
||||
|
{ |
||||
|
$roomid = $this->request->param('roomid', 0); |
||||
|
$phone = $this->request->param('phone', 0); |
||||
|
if (!$roomid || !is_numeric($roomid)) { |
||||
|
return '房间信息不存在'; |
||||
|
} |
||||
|
if (!$phone || !is_numeric($phone)) { |
||||
|
return '手机号不正确'; |
||||
|
} |
||||
|
//查找房间及房源数据 |
||||
|
$_data = Db::name($this->table_room)->alias('r')->join('cloud_house h', 'r.house_id = h.id')->where('r.is_del', 0)->field('r.*,h.name AS house_name,h.door_number,h.water_money,h.gas_money')->find($roomid); |
||||
|
|
||||
|
if (empty($_data)) { |
||||
|
return '房间信息不存在'; |
||||
|
} |
||||
|
$_data['rent_type_name'] = config('rent_type')[$_data['rent_type']]; |
||||
|
//查找当前房间有多少人 |
||||
|
$tenant_num = Db::name($this->table_tenant)->where('room_id', $roomid)->where('is_del', 0)->count(); |
||||
|
//查找当前租户信息 |
||||
|
$_tenant = Db::name($this->table_tenant)->where('phone', $phone)->where('is_del', 0)->find(); |
||||
|
if (empty($_tenant)) { |
||||
|
return '租户信息不存在'; |
||||
|
} |
||||
|
//查找当前二房东收款账号 |
||||
|
$_holder = Db::name($this->table_member)->where('id', $_data['user_id'])->find(); |
||||
|
if (empty($_holder)) { |
||||
|
return '二房东信息不存在'; |
||||
|
} |
||||
|
if (empty($_holder['qrcode'])) { |
||||
|
//return '收款信息不存在!!!'; |
||||
|
} |
||||
|
$qrcode = explode(',', $_holder['qrcode']); |
||||
|
$_holder['pay1'] = !empty($qrcode[0]) ? $qrcode[0] : ''; |
||||
|
$_holder['pay2'] = !empty($qrcode[1]) ? $qrcode[1] : ''; |
||||
|
//查询支付记录表,计算当前押一付三 ,如果第一次支付 需要x4 如果是续租需要x3 |
||||
|
$order_num = Db::name($this->table_order)->where('room_id', $_data['id'])->where('is_del', 0)->where('status', 1)->count(); |
||||
|
$rent_type = $_data['rent_type']; |
||||
|
$_data['broadband_fee'] = empty($_data['broadband_fee']) ? 0 : $_data['broadband_fee']; |
||||
|
$_data['property_fee'] = empty($_data['property_fee']) ? 0 : $_data['property_fee']; |
||||
|
$_data['key_deposit'] = empty($_data['key_deposit']) ? 0 : $_data['key_deposit']; |
||||
|
$_data['total_rent'] = ($_data['rent'] + $_data['broadband_fee'] + $_data['property_fee'] + ($_data['water_money'] + $_data['gas_money']) * $tenant_num) * $rent_type; |
||||
|
//计算公式: (月租+物业费+宽带费+(水费+燃气费)x户数)x月数 + 钥匙押金x户数 |
||||
|
//计算公式[改版本]: (月租+物业费+宽带费+(水费+燃气费)x户数)x月数 + 钥匙押金x户数 $_data['key_deposit'] * $tenant_num |
||||
|
if (empty($order_num)) { |
||||
|
//$_data['total_rent'] += $_data['rent']; //如果之前没有订单加一个月的租金 |
||||
|
} |
||||
|
//合同开始时间 |
||||
|
$_data['contract_starttime_str'] = date('Y年m月d日'); |
||||
|
$_data['contract_endtime_str'] = date('Y年m月d日', strtotime('+ ' . $_data['rent_type'] . ' month')); |
||||
|
$_data['contract_starttime'] = time(); |
||||
|
$_data['contract_endtime'] = strtotime('+ ' . $_data['rent_type'] . ' month'); |
||||
|
//合同编号 |
||||
|
$_data['contract_number'] = 'YYT-' . date('YmdHis'); |
||||
|
$this->assign('data', $_data); |
||||
|
$this->assign('holder', $_holder); |
||||
|
$this->assign('tenant_num', $tenant_num); |
||||
|
$this->assign('deposit', $order_num > 0 ? 0 : 1); //押金 |
||||
|
$this->assign('tenant', $_tenant); |
||||
|
$this->assign('rent_type', $rent_type); |
||||
|
return $this->fetch(); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 订单提交 |
||||
|
*/ |
||||
|
public function add() |
||||
|
{ |
||||
|
$_data = $this->request->post(); |
||||
|
//通过房间查找用户user_id,确认是否存在 |
||||
|
$_room = Db::name($this->table_room)->where('id', $_data['room_id'])->where('is_del', 0)->find(); |
||||
|
if (empty($_room)) { |
||||
|
return $this->error('房间号不存在'); |
||||
|
} |
||||
|
unset($_data['status']); |
||||
|
|
||||
|
//先清空原有订单数据 |
||||
|
$room_order_db = Db::name($this->table_order); |
||||
|
$room_order_db->where('room_id', $_room['id']); |
||||
|
$room_order_db->where('name', $_data['name']); |
||||
|
$room_order_db->update(['is_del' => 1]); |
||||
|
|
||||
|
$_data['create_time'] = $_data['update_time'] = time(); |
||||
|
$_data['user_id'] = $_room['user_id']; |
||||
|
$start_time = $_room['start_time']; |
||||
|
$end_time = $_room['end_time']; |
||||
|
//计算指定天数后的时间戳 |
||||
|
if ($start_time >= $end_time) { |
||||
|
return $this->error('房间开始时间必需小于结束时间'); |
||||
|
} |
||||
|
$_arr = []; |
||||
|
while ($start_time < $end_time) { |
||||
|
$_data['room_id'] = $_room['id']; |
||||
|
$_data['start_time'] = $start_time; |
||||
|
$_data['end_time'] = $start_time = strtotime('+' . $_room['rent_type'] . ' month', $start_time); |
||||
|
$_arr[] = $_data; |
||||
|
} |
||||
|
if (empty($_arr)) { |
||||
|
return $this->error('未知错误!!!'); |
||||
|
} |
||||
|
//判断是否存在订单,如果存在代表包含押一的金额,否则不包含 |
||||
|
$order_num = Db::name($this->table_order)->where('room_id', $_room['id'])->where('is_del', 0)->where('status', 1)->count(); |
||||
|
if (empty($order_num)) { |
||||
|
(int)$_arr[0]['price'] += (int)$_data['rent_price']; //加上一个月租金 即押一 |
||||
|
(int)$_arr[0]['price'] += (int)$_data['key_deposit'] * (int)$_data['tenant_num']; //加上一个月钥匙押金 即押一 |
||||
|
$_arr[0]['detail'] .= '<br /> 房租押金:' . $_data['rent_price'] . '元'; //加上押金、钥匙押金 |
||||
|
$_arr[0]['detail'] .= '<br /> 钥匙押金:' . (int)$_data['key_deposit'] * (int)$_data['tenant_num'] . '元'; //加上押金、钥匙押金 |
||||
|
} |
||||
|
//删除最后一个元素,置换为end_time(防止开始时间与结束时间不一致) |
||||
|
$last_arr = array_pop($_arr); |
||||
|
$last_arr['end_time'] = $end_time; |
||||
|
$_arr[] = $last_arr; |
||||
|
|
||||
|
//插入新订单数据 |
||||
|
$affected = Db::name($this->table_order)->strict(false)->insertAll($_arr); |
||||
|
if ($affected) { |
||||
|
//在线合同 |
||||
|
//Db::name($this->table_contract)->strict(false)->insert($_data); |
||||
|
return $this->success('订单提交成功'); |
||||
|
} |
||||
|
return $this->error('订单提交失败'); |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,73 @@ |
|||||
|
<?php |
||||
|
|
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | ThinkAdmin |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 版权所有 2014~2019 广州楚才信息科技有限公司 [ http://www.cuci.cc ] |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 官方网站: http://demo.thinkadmin.top |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 开源协议 ( https://mit-license.org ) |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin |
||||
|
// | github 代码仓库:https://github.com/zoujingli/ThinkAdmin |
||||
|
// +---------------------------------------------------------------------- |
||||
|
|
||||
|
namespace app\index\controller; |
||||
|
|
||||
|
|
||||
|
use think\App; |
||||
|
use think\Db; |
||||
|
|
||||
|
/** |
||||
|
* 问题管理 |
||||
|
* Class Index |
||||
|
* @package app\index\controller |
||||
|
*/ |
||||
|
class Question extends Base |
||||
|
{ |
||||
|
private $table = 'CloudQuestion'; |
||||
|
|
||||
|
/** |
||||
|
* 获取问题列表 |
||||
|
*/ |
||||
|
public function index() |
||||
|
{ |
||||
|
$count = Db::name($this->table)->count(); |
||||
|
$page = $this->request->param('page', 1); |
||||
|
$pagesize = $this->request->param('pagesize', 10); |
||||
|
$pages = ceil($count / $pagesize); //总页数 |
||||
|
$_result = Db::name($this->table)->page($page, $pagesize)->order('id', "DESC")->where('status',1)->select(); |
||||
|
$_data['list'] = $_result; |
||||
|
$_data['pages'] = $pages; |
||||
|
self::formatData($_data['list']); |
||||
|
return send_http_status(200, $_data); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 合同详情 |
||||
|
*/ |
||||
|
public function view($id = '') |
||||
|
{ |
||||
|
if (!$id) { |
||||
|
return; |
||||
|
} |
||||
|
//获取房源详情 |
||||
|
$_data = Db::name($this->table)->find($id); |
||||
|
return send_http_status(200, $_data); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
static private function formatData(&$data) |
||||
|
{ |
||||
|
if (!$data) { |
||||
|
return; |
||||
|
} |
||||
|
array_walk($data, function (&$v, &$k) { |
||||
|
!empty($v['create_time']) ? $v['create_time'] = date('Y-m-d', $v['create_time']) : $v['create_time'] = ''; |
||||
|
}); |
||||
|
|
||||
|
} |
||||
|
|
||||
|
|
||||
|
} |
||||
@ -0,0 +1,42 @@ |
|||||
|
<?php |
||||
|
|
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | ThinkAdmin |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 版权所有 2014~2019 广州楚才信息科技有限公司 [ http://www.cuci.cc ] |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 官方网站: http://demo.thinkadmin.top |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 开源协议 ( https://mit-license.org ) |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin |
||||
|
// | github 代码仓库:https://github.com/zoujingli/ThinkAdmin |
||||
|
// +---------------------------------------------------------------------- |
||||
|
|
||||
|
namespace app\index\controller; |
||||
|
|
||||
|
|
||||
|
use think\App; |
||||
|
use think\Db; |
||||
|
|
||||
|
/** |
||||
|
* 应用入口 |
||||
|
* Class Index |
||||
|
* @package app\index\controller |
||||
|
*/ |
||||
|
class Single extends Base |
||||
|
{ |
||||
|
protected $table = 'CloudSingle'; |
||||
|
|
||||
|
/** |
||||
|
* 获取单页面数据 |
||||
|
* @param string $ident 单页面唯一标签 |
||||
|
*/ |
||||
|
public function index($ident = '') |
||||
|
{ |
||||
|
|
||||
|
$_data = Db::name($this->table)->where('ident', $ident)->find(); |
||||
|
return send_http_status(200, $_data); |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,34 @@ |
|||||
|
<?php |
||||
|
/*---------------------------------------------------------------------- |
||||
|
* 项目名称: CloudAdmin |
||||
|
* +---------------------------------------------------------------------- |
||||
|
* 版权所有: 2014~2020 安徽云掌开发团队 |
||||
|
* +---------------------------------------------------------------------- |
||||
|
* 官方网站: [ http://www.yaoyz.com、http://www.ahyunzhang.com ] |
||||
|
* +---------------------------------------------------------------------- |
||||
|
* Date: 2018/11/15 9:47 |
||||
|
* +---------------------------------------------------------------------- |
||||
|
* Des: 短信插件 |
||||
|
+----------------------------------------------------------------------*/ |
||||
|
|
||||
|
|
||||
|
namespace app\index\controller; |
||||
|
|
||||
|
use think\Controller; |
||||
|
|
||||
|
class Sms extends Controller |
||||
|
{ |
||||
|
|
||||
|
/** |
||||
|
* 默认操作数据表 |
||||
|
* @var string |
||||
|
*/ |
||||
|
public $table = 'sms'; |
||||
|
|
||||
|
public function index() |
||||
|
{ |
||||
|
$_result = \app\api\controller\Sms::sendNotify('13965108697', ['{url}' => 'http://www.baidu.com'], 23); |
||||
|
dump($_result); |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,127 @@ |
|||||
|
<?php |
||||
|
|
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | ThinkAdmin |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 版权所有 2014~2019 广州楚才信息科技有限公司 [ http://www.cuci.cc ] |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 官方网站: http://demo.thinkadmin.top |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 开源协议 ( https://mit-license.org ) |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin |
||||
|
// | github 代码仓库:https://github.com/zoujingli/ThinkAdmin |
||||
|
// +---------------------------------------------------------------------- |
||||
|
|
||||
|
namespace app\index\controller; |
||||
|
|
||||
|
use think\App; |
||||
|
use think\Db; |
||||
|
|
||||
|
/** |
||||
|
* 子账号管理 |
||||
|
* Class Index |
||||
|
* @package app\index\controller |
||||
|
*/ |
||||
|
class Subaccount extends Base |
||||
|
{ |
||||
|
private $table = 'CloudSubaccount'; |
||||
|
|
||||
|
public function __construct(App $app = null) |
||||
|
{ |
||||
|
parent::__construct($app); |
||||
|
parent::auth(); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 获取子账号列表 |
||||
|
*/ |
||||
|
public function index() |
||||
|
{ |
||||
|
$_where = 'user_id = ' . USER_ID; |
||||
|
$count = Db::name($this->table)->where($_where)->count(); |
||||
|
$page = $this->request->param('page', 1); |
||||
|
$pagesize = $this->request->param('pagesize', 10); |
||||
|
$pages = ceil($count / $pagesize); //总页数 |
||||
|
$_result = Db::name($this->table)->where($_where)->page($page, $pagesize)->order('id', "DESC")->select(); |
||||
|
$_data['list'] = $_result; |
||||
|
$_data['pages'] = $pages; |
||||
|
self::formatData($_data['list']); |
||||
|
return send_http_status(200, $_data); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 子账号详情 |
||||
|
*/ |
||||
|
public function view($id = '') |
||||
|
{ |
||||
|
if (!$id) { |
||||
|
return; |
||||
|
} |
||||
|
//获取房源详情 |
||||
|
$_data = Db::name($this->table)->where('user_id', USER_ID)->find($id); |
||||
|
return send_http_status(200, $_data); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 添加子账号 |
||||
|
*/ |
||||
|
public function add() |
||||
|
{ |
||||
|
$_data = $this->request->post(); |
||||
|
$_data['create_time'] = $_data['update_time'] = time(); |
||||
|
$_data['password'] = sha1($_data['password']); |
||||
|
$_data['user_id'] = USER_ID; |
||||
|
$_data = array_filter($_data); |
||||
|
//先查询账号是否存在 |
||||
|
$_user = Db::name($this->table)->where('username', $_data['username'])->find(); |
||||
|
if ($_user) { |
||||
|
return send_http_status(51010); |
||||
|
} |
||||
|
//查询已有账号的数量 |
||||
|
$count = Db::name($this->table)->where('user_id', USER_ID)->where('status', 1)->count(); |
||||
|
$_config = config('vip_level'); |
||||
|
if ($count > $_config[MEMBER['vip_level']]['subaccount_count']) { |
||||
|
return send_http_status(51011); |
||||
|
} |
||||
|
$affected = Db::name($this->table)->strict(false)->insert($_data); |
||||
|
if (!$affected) { |
||||
|
return send_http_status(51002); |
||||
|
} |
||||
|
return send_http_status(200); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 修改子账号 |
||||
|
*/ |
||||
|
public function edit() |
||||
|
{ |
||||
|
$_data = $this->request->post(); |
||||
|
$_data['update_time'] = time(); |
||||
|
$_data['user_id'] = USER_ID; |
||||
|
if ($_data['password'] == '***123***') { |
||||
|
unset($_data['password']); |
||||
|
}else{ |
||||
|
$_data['password'] = sha1($_data['password']); |
||||
|
} |
||||
|
$affected = Db::name($this->table)->strict(false)->update($_data); |
||||
|
if (!$affected) { |
||||
|
return send_http_status(51002); |
||||
|
} |
||||
|
return send_http_status(200); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
static private function formatData(&$data) |
||||
|
{ |
||||
|
if (!$data) { |
||||
|
return; |
||||
|
} |
||||
|
array_walk($data, function (&$v, &$k) { |
||||
|
!empty($v['create_time']) ? $v['create_time'] = date('Y-m-d', $v['create_time']) : $v['create_time'] = ''; |
||||
|
}); |
||||
|
|
||||
|
} |
||||
|
|
||||
|
|
||||
|
} |
||||
@ -0,0 +1,104 @@ |
|||||
|
<?php |
||||
|
|
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | ThinkAdmin |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 版权所有 2014~2019 广州楚才信息科技有限公司 [ http://www.cuci.cc ] |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 官方网站: http://demo.thinkadmin.top |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 开源协议 ( https://mit-license.org ) |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin |
||||
|
// | github 代码仓库:https://github.com/zoujingli/ThinkAdmin |
||||
|
// +---------------------------------------------------------------------- |
||||
|
|
||||
|
namespace app\index\controller; |
||||
|
|
||||
|
|
||||
|
use library\Controller; |
||||
|
use library\File; |
||||
|
|
||||
|
/** |
||||
|
* 后台插件管理 |
||||
|
* Class Plugs |
||||
|
* @package app\admin\controller\api |
||||
|
*/ |
||||
|
class Upload extends Controller |
||||
|
{ |
||||
|
|
||||
|
public function index() |
||||
|
{ |
||||
|
return $this->fetch(); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 系统选择器图标 |
||||
|
*/ |
||||
|
public function icon() |
||||
|
{ |
||||
|
$this->title = '图标选择器'; |
||||
|
$this->field = input('field', 'icon'); |
||||
|
$this->fetch(); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Plupload 插件上传文件 |
||||
|
* @return \think\response\Json |
||||
|
* @throws \think\Exception |
||||
|
* @throws \think\exception\PDOException |
||||
|
*/ |
||||
|
public function plupload() |
||||
|
{ |
||||
|
|
||||
|
if (!($file = $this->getUploadFile()) || empty($file)) { |
||||
|
return json(['uploaded' => false, 'error' => ['message' => '文件上传异常,文件可能过大或未上传']]); |
||||
|
} |
||||
|
if (!$file->checkExt(strtolower(sysconf('storage_local_exts')))) { |
||||
|
return json(['uploaded' => false, 'error' => ['message' => '文件上传类型受限,请在后台配置']]); |
||||
|
} |
||||
|
if ($file->checkExt('php,sh')) { |
||||
|
return json(['uploaded' => false, 'error' => ['message' => '可执行文件禁止上传到本地服务器']]); |
||||
|
} |
||||
|
$this->safe = boolval(input('safe')); |
||||
|
$this->uptype = 'local'; |
||||
|
$this->extend = pathinfo($file->getInfo('name'), PATHINFO_EXTENSION); |
||||
|
$pre = date('Y-m') . '/' . date('d'); |
||||
|
$name = File::name($file->getPathname(), $this->extend, $pre, 'md5_file'); |
||||
|
$info = File::instance($this->uptype)->save($name, file_get_contents($file->getRealPath()), $this->safe); |
||||
|
if (is_array($info) && isset($info['url'])) { |
||||
|
return json(['uploaded' => true, 'filename' => $name, 'url' => $this->safe ? $name : $info['url']]); |
||||
|
} else { |
||||
|
return json(['uploaded' => false, 'error' => ['message' => '文件处理失败,请稍候再试!']]); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 获取文件上传方式 |
||||
|
* @return string |
||||
|
* @throws \think\Exception |
||||
|
* @throws \think\exception\PDOException |
||||
|
*/ |
||||
|
private function getUploadType() |
||||
|
{ |
||||
|
$this->uptype = input('uptype'); |
||||
|
if (!in_array($this->uptype, ['local', 'oss', 'qiniu'])) { |
||||
|
$this->uptype = sysconf('storage_type'); |
||||
|
} |
||||
|
return $this->uptype; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 获取本地文件对象 |
||||
|
* @return \think\File |
||||
|
*/ |
||||
|
private function getUploadFile() |
||||
|
{ |
||||
|
try { |
||||
|
return $this->request->file('file'); |
||||
|
} catch (\Exception $e) { |
||||
|
$this->error(lang($e->getMessage())); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,212 @@ |
|||||
|
<!DOCTYPE html> |
||||
|
<html> |
||||
|
<head> |
||||
|
<meta charset="utf-8"> |
||||
|
<title>房租收费系统</title> |
||||
|
<meta name="renderer" content="webkit"> |
||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> |
||||
|
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"> |
||||
|
<link rel="stylesheet" href="/static/plugs/layui/css/layui.css" media="all"> |
||||
|
<link rel="stylesheet" type="text/css" href="/static/plugs/wangedit/css/wangEditor-mobile.css"> |
||||
|
<style type="text/css"> |
||||
|
html, body { |
||||
|
margin: 0; |
||||
|
padding: 0; |
||||
|
} |
||||
|
|
||||
|
.saveimg { |
||||
|
text-align: center; |
||||
|
} |
||||
|
|
||||
|
.saveimgs span { |
||||
|
display: inline-block; |
||||
|
margin-top: 5px; |
||||
|
} |
||||
|
|
||||
|
.det-nr { |
||||
|
line-height: 250%; |
||||
|
padding: 20px 30px 20px 20px; |
||||
|
} |
||||
|
|
||||
|
.underline { |
||||
|
text-decoration: underline; |
||||
|
} |
||||
|
</style> |
||||
|
</head> |
||||
|
<body> |
||||
|
|
||||
|
<div style="padding:20px;"> |
||||
|
<fieldset class="layui-elem-field layui-field-title"> |
||||
|
<legend>房租费用明细</legend> |
||||
|
</fieldset> |
||||
|
|
||||
|
<form class="layui-form layui-form-pane" method="post" action="{:url('index/pay/add')}"> |
||||
|
<div class="layui-form-item"> |
||||
|
<label class="layui-form-label">小区门牌号</label> |
||||
|
<div class="layui-input-block"> |
||||
|
<input type="text" name="door_number" readonly="readonly" |
||||
|
value="{$data.house_name}-{$data.door_number}" |
||||
|
autocomplete="off" |
||||
|
placeholder="请输入标题" |
||||
|
class="layui-input"> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div class="layui-form-item"> |
||||
|
<label class="layui-form-label">房间号</label> |
||||
|
<div class="layui-input-block"> |
||||
|
<input type="text" name="room_number" readonly="readonly" value="{$data.room_number}" |
||||
|
autocomplete="off" |
||||
|
placeholder="请输入房间号" |
||||
|
class="layui-input"> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div class="layui-form-item"> |
||||
|
<label class="layui-form-label">手机号</label> |
||||
|
<div class="layui-input-block"> |
||||
|
<input type="text" name="phone" lay-verify="required|phone" value="{$Think.get.phone|default=''}" |
||||
|
autocomplete="off" |
||||
|
placeholder="请输入手机号" |
||||
|
class="layui-input"> |
||||
|
<input type="hidden" name="room_id" value="{$Think.get.roomid|default=''}" |
||||
|
class="layui-input"> |
||||
|
<input type="hidden" name="name" value="{$tenant.name}" |
||||
|
class="layui-input"> |
||||
|
<input type="hidden" name="tenant_id" value="{$tenant.id}" |
||||
|
class="layui-input"> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div class="layui-form-item"> |
||||
|
<label class="layui-form-label">租金</label> |
||||
|
<div class="layui-input-block"> |
||||
|
<input type="text" name="rent" readonly="readonly" value="{$data.rent}元" |
||||
|
autocomplete="off" |
||||
|
placeholder="请输入租金" |
||||
|
class="layui-input"> |
||||
|
<input type="hidden" name="rent_price" value="{$data.rent}" |
||||
|
class="layui-input"> |
||||
|
<input type="hidden" name="key_deposit" value="{$data.key_deposit}" |
||||
|
class="layui-input"> |
||||
|
<input type="hidden" name="tenant_num" value="{$tenant_num}" |
||||
|
class="layui-input"> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div class="layui-form-item"> |
||||
|
<label class="layui-form-label">钥匙押金:</label> |
||||
|
<div class="layui-input-block"> |
||||
|
<input type="text" name="" readonly="readonly" value="{$data.key_deposit}元/人" |
||||
|
autocomplete="off" |
||||
|
placeholder="钥匙押金" |
||||
|
class="layui-input"> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div class="layui-form-item"> |
||||
|
<label class="layui-form-label">燃气费</label> |
||||
|
<div class="layui-input-block"> |
||||
|
<input type="text" name="gas_money" readonly="readonly" |
||||
|
value="{$data.gas_money}元/人 x {$tenant_num}人={$data.gas_money * $tenant_num}元" |
||||
|
autocomplete="off" |
||||
|
placeholder="请输入燃气费" |
||||
|
class="layui-input"> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div class="layui-form-item"> |
||||
|
<label class="layui-form-label">水费</label> |
||||
|
<div class="layui-input-block"> |
||||
|
<input type="text" name="water_money" readonly="readonly" |
||||
|
value="{$data.water_money}元/人 x {$tenant_num}人={$data.water_money * $tenant_num}元" |
||||
|
autocomplete="off" |
||||
|
placeholder="请输入水费" |
||||
|
class="layui-input"> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div class="layui-form-item"> |
||||
|
<label class="layui-form-label">交租方式</label> |
||||
|
<div class="layui-input-block"> |
||||
|
<input type="text" name="rent_type_name" readonly="readonly" value="{$data.rent_type_name}" |
||||
|
autocomplete="off" |
||||
|
class="layui-input"> |
||||
|
<input type="hidden" name="rent_type" readonly="readonly" value="{$data.rent_type}" |
||||
|
autocomplete="off" |
||||
|
class="layui-input"> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div class="layui-form-item"> |
||||
|
<label class="layui-form-label" style="color: red;">房租合计:</label> |
||||
|
<div class="layui-input-block"> |
||||
|
<textarea name="detail" rows="6" class="layui-textarea">(租金:{$data.rent}元 + 宽带费:{$data.broadband_fee}元 + 物业费:{$data.property_fee}元 + 燃气费:{$data.gas_money}元 x {$tenant_num}人 + 水费:{$data.water_money}元 x {$tenant_num}人) x {$rent_type}个月 = 合计:{$data.total_rent}元 |
||||
|
</textarea> |
||||
|
<input type="hidden" name="price" readonly="readonly" |
||||
|
value="{$data.total_rent}" |
||||
|
autocomplete="off" |
||||
|
class="layui-input"> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div class="layui-form-item"> |
||||
|
<div class="layui-input-block"> |
||||
|
{if $Think.get.sms eq true} |
||||
|
<a href="sms://{$Think.get.phone|default=''}" id="sms-text" class="layui-btn layui-bg-orange">发送短信</a> |
||||
|
{else} |
||||
|
<button class="layui-btn layui-bg-blue" lay-submit="" lay-filter="demo1">确认生成订单</button> |
||||
|
{/if} |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
</form> |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
<script src="/static/plugs/layui/layui.js" charset="utf-8"></script> |
||||
|
<script type="text/javascript" src="/static/plugs/wangedit/js/lib/zepto.js"></script> |
||||
|
<script type="text/javascript" src="/static/plugs/wangedit/js/lib/zepto.touch.js"></script> |
||||
|
<script type="text/javascript"> |
||||
|
$(function () { |
||||
|
|
||||
|
// 浏览器的用户代理报头 |
||||
|
let u = navigator.userAgent; |
||||
|
let smsurl = ''; |
||||
|
// 短信内容需要转码 |
||||
|
var smstextArea = encodeURIComponent("您的房租即将到期(租金:{$data.rent}元 + 燃气费:{$data.gas_money}元 x {$tenant_num}/人 + 水费:{$data.water_money}元 x {$tenant_num}/人) x {$rent_type}月({$data.rent_type_name}) = {$data.total_rent}元,请通过支付宝或者微信转账,有什么疑问可直接联系我!"); |
||||
|
var smsphone = $('#sms-text').attr('href'); |
||||
|
if (/(iPhone|iPad|iPod|iOS)/i.test(u)) { |
||||
|
$('#sms-text').attr('href', smsphone + '&body=' + smstextArea); |
||||
|
} else { |
||||
|
$('#sms-text').attr('href', smsphone + '?body=' + smstextArea); |
||||
|
} |
||||
|
|
||||
|
// 自定义配置 |
||||
|
editor.config.uploadImgUrl = '/upload'; |
||||
|
|
||||
|
// editor.config.menus = ['bold', 'quote', 'list','img']; |
||||
|
|
||||
|
// 初始化 |
||||
|
editor.init(); |
||||
|
|
||||
|
console.log(editor.$txt); |
||||
|
}); |
||||
|
</script> |
||||
|
<!-- 注意:如果你直接复制所有代码到本地,上述js路径需要改成你本地的 --> |
||||
|
<script> |
||||
|
layui.use(['form', 'layedit', 'laydate'], function () { |
||||
|
var form = layui.form |
||||
|
, layer = layui.layer; |
||||
|
|
||||
|
|
||||
|
//监听提交 |
||||
|
form.on('submit(demo1)', function (data) { |
||||
|
|
||||
|
}); |
||||
|
|
||||
|
}); |
||||
|
</script> |
||||
|
|
||||
|
</body> |
||||
|
</html> |
||||
@ -0,0 +1,439 @@ |
|||||
|
<!DOCTYPE html> |
||||
|
<html> |
||||
|
<head> |
||||
|
<meta charset="utf-8"> |
||||
|
<title>房租收费系统</title> |
||||
|
<meta name="renderer" content="webkit"> |
||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> |
||||
|
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"> |
||||
|
<link rel="stylesheet" href="/static/plugs/layui/css/layui.css" media="all"> |
||||
|
<link rel="stylesheet" type="text/css" href="/static/plugs/wangedit/css/wangEditor-mobile.css"> |
||||
|
<style type="text/css"> |
||||
|
html, body { |
||||
|
margin: 0; |
||||
|
padding: 0; |
||||
|
} |
||||
|
|
||||
|
.saveimg { |
||||
|
text-align: center; |
||||
|
} |
||||
|
|
||||
|
.saveimgs span { |
||||
|
display: inline-block; |
||||
|
margin-top: 5px; |
||||
|
} |
||||
|
|
||||
|
.det-nr { |
||||
|
line-height: 250%; |
||||
|
padding: 20px 30px 20px 20px; |
||||
|
} |
||||
|
|
||||
|
.underline { |
||||
|
text-decoration: underline; |
||||
|
} |
||||
|
</style> |
||||
|
</head> |
||||
|
<body> |
||||
|
|
||||
|
<div style="padding:20px;"> |
||||
|
<fieldset class="layui-elem-field layui-field-title"> |
||||
|
<legend>房租费用明细</legend> |
||||
|
</fieldset> |
||||
|
|
||||
|
<form class="layui-form layui-form-pane" method="post" action="{:url('index/pay/add')}"> |
||||
|
<div class="layui-form-item"> |
||||
|
<label class="layui-form-label">小区门牌号</label> |
||||
|
<div class="layui-input-block"> |
||||
|
<input type="text" name="door_number" readonly="readonly" |
||||
|
value="{$data.house_name}-{$data.door_number}" |
||||
|
autocomplete="off" |
||||
|
placeholder="请输入标题" |
||||
|
class="layui-input"> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div class="layui-form-item"> |
||||
|
<label class="layui-form-label">房间号</label> |
||||
|
<div class="layui-input-block"> |
||||
|
<input type="text" name="room_number" readonly="readonly" value="{$data.room_number}" |
||||
|
autocomplete="off" |
||||
|
placeholder="请输入房间号" |
||||
|
class="layui-input"> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div class="layui-form-item"> |
||||
|
<label class="layui-form-label">手机号</label> |
||||
|
<div class="layui-input-block"> |
||||
|
<input type="text" name="phone" lay-verify="required|phone" value="{$Think.get.phone|default=''}" |
||||
|
autocomplete="off" |
||||
|
placeholder="请输入手机号" |
||||
|
class="layui-input"> |
||||
|
<input type="hidden" name="room_id" value="{$Think.get.roomid|default=''}" |
||||
|
class="layui-input"> |
||||
|
<input type="hidden" name="name" value="{$tenant.name}" |
||||
|
class="layui-input"> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div class="layui-form-item"> |
||||
|
<label class="layui-form-label">租金</label> |
||||
|
<div class="layui-input-block"> |
||||
|
<input type="text" name="rent" readonly="readonly" value="{$data.rent}元" |
||||
|
autocomplete="off" |
||||
|
placeholder="请输入租金" |
||||
|
class="layui-input"> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div class="layui-form-item"> |
||||
|
<label class="layui-form-label">燃气费</label> |
||||
|
<div class="layui-input-block"> |
||||
|
<input type="text" name="gas_money" readonly="readonly" |
||||
|
value="{$data.gas_money}元/人 x {$tenant_num}人={$data.gas_money * $tenant_num}元" |
||||
|
autocomplete="off" |
||||
|
placeholder="请输入燃气费" |
||||
|
class="layui-input"> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div class="layui-form-item"> |
||||
|
<label class="layui-form-label">水费</label> |
||||
|
<div class="layui-input-block"> |
||||
|
<input type="text" name="water_money" readonly="readonly" |
||||
|
value="{$data.water_money}元/人 x {$tenant_num}人={$data.water_money * $tenant_num}元" |
||||
|
autocomplete="off" |
||||
|
placeholder="请输入水费" |
||||
|
class="layui-input"> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div class="layui-form-item"> |
||||
|
<label class="layui-form-label">交租方式</label> |
||||
|
<div class="layui-input-block"> |
||||
|
<input type="text" name="rent_type_name" readonly="readonly" value="{$data.rent_type_name}" |
||||
|
autocomplete="off" |
||||
|
placeholder="请输入交租方式" |
||||
|
class="layui-input"> |
||||
|
<input type="hidden" name="rent_type" readonly="readonly" value="{$data.rent_type}" |
||||
|
autocomplete="off" |
||||
|
placeholder="请输入交租方式" |
||||
|
class="layui-input"> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div class="layui-form-item"> |
||||
|
<label class="layui-form-label" style="color: red;">房租合计:</label> |
||||
|
<div class="layui-input-block"> |
||||
|
<input type="text" name="detail" style="color: red;font-weight: bold;" readonly="readonly" |
||||
|
value="(租金{$data.rent} + 燃气费{$data.gas_money} x {$tenant_num} + 水费{$data.water_money} x {$tenant_num}) x {$rent_type}月({$data.rent_type_name}) = {$data.total_rent}元" |
||||
|
autocomplete="off" |
||||
|
placeholder="请输入标题" |
||||
|
class="layui-input"> |
||||
|
<input type="hidden" name="price" readonly="readonly" |
||||
|
value="{$data.total_rent}" |
||||
|
autocomplete="off" |
||||
|
class="layui-input"> |
||||
|
<p style="padding:10px 0;"> |
||||
|
<img src="{$holder.pay1}" width="180" style="margin-right: 100px;"/> |
||||
|
<img src="{$holder.pay2}" width="180"/> |
||||
|
</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div class="layui-form-item" pane> |
||||
|
<label class="layui-form-label">支付方式</label> |
||||
|
<div class="layui-input-block"> |
||||
|
<input type="radio" name="pay_type" value="1" title="微信"> |
||||
|
<input type="radio" name="pay_type" value="2" title="支付宝"> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<fieldset class="layui-elem-field layui-field-title" style="margin:30px 0;"> |
||||
|
<legend>在线合同签约</legend> |
||||
|
</fieldset> |
||||
|
|
||||
|
<div class="layui-form-item" pane> |
||||
|
<label class="layui-form-label">合同编号</label> |
||||
|
<div class="layui-input-block"> |
||||
|
<input type="text" class="layui-input" name="number" value="{$data.contract_number}"> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div class="layui-form-item" pane> |
||||
|
<label class="layui-form-label">签约小区</label> |
||||
|
<div class="layui-input-block"> |
||||
|
<input type="text" class="layui-input" name="house_name" value="{$data.house_name}"> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<input type="hidden" name="contract_starttime" readonly="readonly" |
||||
|
value="{$data.contract_starttime|default=''}" |
||||
|
autocomplete="off" |
||||
|
class="layui-input"> |
||||
|
<input type="hidden" name="contract_endtime" readonly="readonly" |
||||
|
value="{$data.contract_endtime|default=''}" |
||||
|
autocomplete="off" |
||||
|
class="layui-input"> |
||||
|
|
||||
|
|
||||
|
<div class="layui-form-item" pane> |
||||
|
<div class=""> |
||||
|
<textarea id="textarea1" name="content" style="width:100%;height:100%;"> |
||||
|
<style type="text/css"> |
||||
|
html, body { |
||||
|
margin: 0; |
||||
|
padding: 0; |
||||
|
} |
||||
|
|
||||
|
.saveimg { |
||||
|
text-align: center; |
||||
|
} |
||||
|
|
||||
|
.saveimgs span { |
||||
|
display: inline-block; |
||||
|
margin-top: 5px; |
||||
|
} |
||||
|
|
||||
|
.det-nr { |
||||
|
line-height: 160%; |
||||
|
padding: 20px 30px 20px 20px; |
||||
|
} |
||||
|
|
||||
|
.underline { |
||||
|
text-decoration: underline; |
||||
|
} |
||||
|
</style> |
||||
|
<div class="det-nr mt20"> |
||||
|
<p style="text-indent:2em;">甲方姓名(出租方): |
||||
|
<span class="underline"><b>{$holder.truename}</b></span> |
||||
|
身份证号码:<span class="underline"><b>{$holder.card_number}</b> |
||||
|
</span> |
||||
|
</p> |
||||
|
<p style="text-indent:2em;">乙方姓名(承租方): |
||||
|
<span class="underline">{$tenant.name}</span> 身份证号码: |
||||
|
<span class="underline">{$tenant.card_id}</span> |
||||
|
</p> |
||||
|
<p style="text-indent:2em;">经双方协商甲方将位于 <span |
||||
|
class="underline"> {$data.contract_starttime_str|default=''}</span> 房屋出租给乙方居住使用。</p> |
||||
|
<p style="text-indent:2em;">一、租房从 |
||||
|
<span class="underline"> {$data.contract_starttime_str|default=''}</span> 起至 |
||||
|
<span class="underline"> {$data.contract_endtime_str|default=''}</span>止。</p> |
||||
|
<p style="text-indent:2em;">二、月租金为 <span class="underline">{$data.rent}</span> 元,缴租为 <span |
||||
|
class="underline">{$data.rent_type}</span> 个月支付一次,以后应提前 <span class="underline">15</span> |
||||
|
天支付。</p> |
||||
|
<p style="text-indent:2em;">三、约定事项</p> |
||||
|
<p style="text-indent:2em;">1、乙方入住时,应及时更换门锁若发生意外与甲方无关。因不慎或使用不当引起火灾、电、气灾害等非自然灾害所造成损失由乙方负责。</p> |
||||
|
<p style="text-indent:2em;"> |
||||
|
2、乙方无权转租、转借、转卖该房屋,及屋内家具家电,不得擅自改动房屋结构,爱护屋内设施,如有人为原因造成破损丢失应维修完好,否则照价赔偿。并做好防火,防盗,防漏水,和阳台摆放、花盆的安全工作,若造成损失责任自负。</p> |
||||
|
<p style="text-indent:2em;">3、乙方必须按时缴纳房租,否则视为乙方违约。协议终止。</p> |
||||
|
<p style="text-indent:2em;"> |
||||
|
4、乙方应遵守居住区内各项规章制度,按时缴纳水、电、气、光纤、电话、物业管理等费用。乙方交保证金给甲方,乙方退房时交清水,电,气,光纤和物业管理等费用及屋内设施家具、家电无损坏,下水管道,厕所无堵漏。甲方如数退还保证金。 |
||||
|
</p> |
||||
|
<p style="text-indent:2em;">5、甲方保证该房屋无产权纠纷。如遇拆迁,乙方无条件搬出,已交租金甲方按未满天数退还。</p> |
||||
|
<p style="text-indent:2em;">四、本合同一式两份,甲乙双方各存一份,自双方签字之日起生效。</p> |
||||
|
<p><br/></p> |
||||
|
<p style="text-indent:2em;">水费:<span class="underline">{$data.water_money}</span>元/人,燃气:<span |
||||
|
class="underline">{$data.gas_money}</span>元/人</p> |
||||
|
<p><br/></p> |
||||
|
<p style="text-indent:2em;"> |
||||
|
甲方签名(出租方): {$holder.truename} |
||||
|
</p> |
||||
|
<p><br/></p> |
||||
|
<p style="text-indent:2em;"> |
||||
|
乙方签名(承租方):{$tenant.name} |
||||
|
<span id="sign_name"></span> |
||||
|
</p> |
||||
|
<p><br/></p> |
||||
|
<p style="text-indent:2em;">签约日期:{$data.contract_starttime_str|default=''} </p> |
||||
|
</div> |
||||
|
</textarea> |
||||
|
|
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div align="center" style="margin:20px auto; width:320px;"> |
||||
|
<canvas id="myCanvas" height="300" width="450" style="border:1px solid #6699cc"></canvas> |
||||
|
<div class="control-ops control"> |
||||
|
<button type="button" class="layui-btn layui-bg-red" onclick="javascript:clearArea();return false;">清空画板 |
||||
|
</button> |
||||
|
<button type="button" class="saveimg layui-btn" onclick="javascript:saveImageInfo();return false;">确认 |
||||
|
</button> |
||||
|
</div> |
||||
|
<div class="saveimgs"></div> |
||||
|
</div> |
||||
|
|
||||
|
<div class="layui-form-item"> |
||||
|
<div class="layui-input-block"> |
||||
|
<button class="layui-btn layui-bg-blue" lay-submit="" lay-filter="demo1">支付完成后请点击提交</button> |
||||
|
</div> |
||||
|
</div> |
||||
|
</form> |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
<!--电子签名--> |
||||
|
<script type="text/javascript"> |
||||
|
var mousePressed = false; |
||||
|
var lastX, lastY; |
||||
|
var ctx = document.getElementById('myCanvas').getContext("2d"); |
||||
|
var c = document.getElementById("myCanvas"); |
||||
|
// console.log(c) |
||||
|
// console.log(c2) |
||||
|
var control = document.getElementsByClassName("control")[0]; |
||||
|
var saveimgs = document.getElementsByClassName("saveimgs")[0]; |
||||
|
window.onload = function () { |
||||
|
InitThis(); |
||||
|
} |
||||
|
|
||||
|
function saveImageInfo() { |
||||
|
var image = c.toDataURL("image/png"); |
||||
|
var ctximg = document.createElement("span"); |
||||
|
ctximg.innerHTML = "<input type='hidden' value='" + image + "' name='sign_name' /><img src='" + image + "' alt='from canvas'/>"; |
||||
|
if (saveimgs.getElementsByTagName('span').length >= 1) { |
||||
|
var span_old = saveimgs.getElementsByTagName("span")[0]; |
||||
|
saveimgs.replaceChild(ctximg, span_old) |
||||
|
} |
||||
|
else { |
||||
|
saveimgs.appendChild(ctximg); |
||||
|
} |
||||
|
// console.log(image) |
||||
|
} |
||||
|
|
||||
|
var selected1, selected2; |
||||
|
|
||||
|
function aaa() { |
||||
|
var sel = document.getElementById('selWidth'); |
||||
|
var value = sel.selectedIndex; |
||||
|
return selected1 = sel[value].value; |
||||
|
} |
||||
|
|
||||
|
function aaa2() { |
||||
|
var sel2 = document.getElementById('selColor'); |
||||
|
var value = sel2.selectedIndex; |
||||
|
return selected2 = sel2[value].value; |
||||
|
} |
||||
|
|
||||
|
function InitThis() { |
||||
|
// 触摸屏 |
||||
|
c.addEventListener('touchstart', function (event) { |
||||
|
console.log(1) |
||||
|
if (event.targetTouches.length == 1) { |
||||
|
event.preventDefault();// 阻止浏览器默认事件,重要 |
||||
|
var touch = event.targetTouches[0]; |
||||
|
mousePressed = true; |
||||
|
Draw(touch.pageX - this.offsetLeft, touch.pageY - this.offsetTop, false); |
||||
|
} |
||||
|
}, false); |
||||
|
c.addEventListener('touchmove', function (event) { |
||||
|
console.log(2) |
||||
|
if (event.targetTouches.length == 1) { |
||||
|
event.preventDefault();// 阻止浏览器默认事件,重要 |
||||
|
var touch = event.targetTouches[0]; |
||||
|
if (mousePressed) { |
||||
|
Draw(touch.pageX - this.offsetLeft, touch.pageY - this.offsetTop, true); |
||||
|
} |
||||
|
} |
||||
|
}, false); |
||||
|
c.addEventListener('touchend', function (event) { |
||||
|
console.log(3) |
||||
|
if (event.targetTouches.length == 1) { |
||||
|
event.preventDefault();// 阻止浏览器默认事件,防止手写的时候拖动屏幕,重要 |
||||
|
// var touch = event.targetTouches[0]; |
||||
|
mousePressed = false; |
||||
|
} |
||||
|
}, false); |
||||
|
/*c.addEventListener('touchcancel', function (event) { |
||||
|
console.log(4) |
||||
|
mousePressed = false; |
||||
|
},false);*/ |
||||
|
// 鼠标 |
||||
|
c.onmousedown = function (event) { |
||||
|
mousePressed = true; |
||||
|
Draw(event.pageX - this.offsetLeft, event.pageY - this.offsetTop, false); |
||||
|
}; |
||||
|
c.onmousemove = function (event) { |
||||
|
if (mousePressed) { |
||||
|
Draw(event.pageX - this.offsetLeft, event.pageY - this.offsetTop, true); |
||||
|
} |
||||
|
}; |
||||
|
c.onmouseup = function (event) { |
||||
|
mousePressed = false; |
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
function Draw(x, y, isDown) { |
||||
|
if (isDown) { |
||||
|
ctx.beginPath(); |
||||
|
ctx.strokeStyle = selected2; |
||||
|
ctx.lineWidth = 5; |
||||
|
ctx.lineJoin = "round"; |
||||
|
ctx.moveTo(lastX, lastY); |
||||
|
ctx.lineTo(x, y); |
||||
|
ctx.closePath(); |
||||
|
ctx.stroke(); |
||||
|
} |
||||
|
lastX = x; |
||||
|
lastY = y; |
||||
|
} |
||||
|
|
||||
|
function clearArea() { |
||||
|
// Use the identity matrix while clearing the canvas |
||||
|
ctx.setTransform(1, 0, 0, 1, 0, 0); |
||||
|
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height); |
||||
|
// 清除签名图片 |
||||
|
if (saveimgs.getElementsByTagName('span').length >= 1) { |
||||
|
var clearImg = saveimgs.getElementsByTagName('span')[0]; |
||||
|
saveimgs.removeChild(clearImg); |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
<!--电子签名--> |
||||
|
<script src="/static/plugs/layui/layui.js" charset="utf-8"></script> |
||||
|
<script type="text/javascript" src="/static/plugs/wangedit/js/lib/zepto.js"></script> |
||||
|
<script type="text/javascript" src="/static/plugs/wangedit/js/lib/zepto.touch.js"></script> |
||||
|
<script type="text/javascript" src="/static/plugs/wangedit/js/wangEditor-mobile.js"></script> |
||||
|
<script type="text/javascript"> |
||||
|
$(function () { |
||||
|
|
||||
|
// 全局配置 |
||||
|
// ___E.config.menus = ['bold', 'color', 'quote']; |
||||
|
|
||||
|
// 生成编辑器 |
||||
|
var editor = new ___E('textarea1'); |
||||
|
|
||||
|
// 自定义配置 |
||||
|
editor.config.uploadImgUrl = '/upload'; |
||||
|
|
||||
|
// editor.config.menus = ['bold', 'quote', 'list','img']; |
||||
|
|
||||
|
// 初始化 |
||||
|
editor.init(); |
||||
|
|
||||
|
console.log(editor.$txt); |
||||
|
}); |
||||
|
</script> |
||||
|
<!-- 注意:如果你直接复制所有代码到本地,上述js路径需要改成你本地的 --> |
||||
|
<script> |
||||
|
layui.use(['form', 'layedit', 'laydate'], function () { |
||||
|
var form = layui.form |
||||
|
, layer = layui.layer; |
||||
|
|
||||
|
|
||||
|
//监听提交 |
||||
|
form.on('submit(demo1)', function (data) { |
||||
|
if (data.field.pay_type == undefined) { |
||||
|
layer.alert('请选择支付方式'); |
||||
|
return false; |
||||
|
} |
||||
|
if (data.field.sign_name == undefined) { |
||||
|
layer.alert('请查看合同内容,并手写签名后确认!'); |
||||
|
return false; |
||||
|
} |
||||
|
}); |
||||
|
|
||||
|
}); |
||||
|
</script> |
||||
|
|
||||
|
</body> |
||||
|
</html> |
||||
@ -0,0 +1,14 @@ |
|||||
|
<!DOCTYPE html> |
||||
|
<html lang="en"> |
||||
|
<head> |
||||
|
<meta charset="UTF-8"> |
||||
|
<title>Title</title> |
||||
|
</head> |
||||
|
<body> |
||||
|
|
||||
|
<form action="/index/upload/plupload" method="post" enctype="multipart/form-data"> |
||||
|
<input type="file" name="file"/> |
||||
|
<input type="submit" value="上传"/> |
||||
|
</form> |
||||
|
</body> |
||||
|
</html> |
||||
@ -0,0 +1,64 @@ |
|||||
|
<?php |
||||
|
|
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | ThinkAdmin |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 版权所有 2014~2019 广州楚才信息科技有限公司 [ http://www.cuci.cc ] |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 官方网站: http://demo.thinkadmin.top |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 开源协议 ( https://mit-license.org ) |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin |
||||
|
// | github 代码仓库:https://github.com/zoujingli/ThinkAdmin |
||||
|
// +---------------------------------------------------------------------- |
||||
|
|
||||
|
namespace app\service\controller; |
||||
|
|
||||
|
use library\Controller; |
||||
|
|
||||
|
/** |
||||
|
* 开放平台参数配置 |
||||
|
* Class Config |
||||
|
* @package app\service\controller |
||||
|
*/ |
||||
|
class Config extends Controller |
||||
|
{ |
||||
|
|
||||
|
/** |
||||
|
* 定义当前操作表名 |
||||
|
* @var string |
||||
|
*/ |
||||
|
public $table = 'WechatServiceConfig'; |
||||
|
|
||||
|
/** |
||||
|
* 开放平台配置 |
||||
|
* @auth true |
||||
|
* @menu true |
||||
|
*/ |
||||
|
public function index() |
||||
|
{ |
||||
|
$this->applyCsrfToken('save'); |
||||
|
$this->title = '开放平台配置'; |
||||
|
$this->fetch(); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 保存参数数据 |
||||
|
* @auth true |
||||
|
* @throws \think\Exception |
||||
|
* @throws \think\exception\PDOException |
||||
|
*/ |
||||
|
public function save() |
||||
|
{ |
||||
|
$this->applyCsrfToken('save'); |
||||
|
if ($this->request->post()) { |
||||
|
$post = $this->request->post(); |
||||
|
foreach ($post as $k => $v) sysconf($k, $v); |
||||
|
$this->success('开放平台参数修改成功!'); |
||||
|
} else { |
||||
|
$this->error('开放平台参数修改失败!'); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,164 @@ |
|||||
|
<?php |
||||
|
|
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | ThinkAdmin |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 版权所有 2014~2019 广州楚才信息科技有限公司 [ http://www.cuci.cc ] |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 官方网站: http://demo.thinkadmin.top |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 开源协议 ( https://mit-license.org ) |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin |
||||
|
// | github 代码仓库:https://github.com/zoujingli/ThinkAdmin |
||||
|
// +---------------------------------------------------------------------- |
||||
|
|
||||
|
namespace app\service\controller; |
||||
|
|
||||
|
use app\admin\service\QueueService; |
||||
|
use app\service\service\WechatService; |
||||
|
use app\service\queue\WechatQueue; |
||||
|
use library\Controller; |
||||
|
use think\Db; |
||||
|
use think\exception\HttpResponseException; |
||||
|
|
||||
|
/** |
||||
|
* 微信粉丝管理 |
||||
|
* Class Fans |
||||
|
* @package app\wechat\controller |
||||
|
*/ |
||||
|
class Fans extends Controller |
||||
|
{ |
||||
|
|
||||
|
protected $appid = ''; |
||||
|
|
||||
|
/** |
||||
|
* 绑定数据表 |
||||
|
* @var string |
||||
|
*/ |
||||
|
protected $table = 'WechatFans'; |
||||
|
|
||||
|
/** |
||||
|
* 初始化函数 |
||||
|
* Fans constructor. |
||||
|
*/ |
||||
|
public function __construct() |
||||
|
{ |
||||
|
parent::__construct(); |
||||
|
$this->appid = input('appid', session('current_appid')); |
||||
|
if (empty($this->appid)) { |
||||
|
$this->appid = Db::name('WechatServiceConfig')->value('authorizer_appid'); |
||||
|
} |
||||
|
if (empty($this->appid)) { |
||||
|
$this->fetch('/not-auth'); |
||||
|
} else { |
||||
|
session('current_appid', $this->appid); |
||||
|
} |
||||
|
if ($this->request->isGet()) { |
||||
|
$this->where = ['status' => '1', 'service_type' => '2', 'is_deleted' => '0']; |
||||
|
$this->wechats = Db::name('WechatServiceConfig')->where($this->where)->order('id desc')->column('authorizer_appid,nick_name'); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 微信粉丝管理 |
||||
|
* @auth true |
||||
|
* @menu true |
||||
|
* @throws \think\Exception |
||||
|
* @throws \think\db\exception\DataNotFoundException |
||||
|
* @throws \think\db\exception\ModelNotFoundException |
||||
|
* @throws \think\exception\DbException |
||||
|
* @throws \think\exception\PDOException |
||||
|
*/ |
||||
|
public function index() |
||||
|
{ |
||||
|
$this->title = '微信粉丝管理'; |
||||
|
$query = $this->_query($this->table)->like('nickname')->equal('subscribe,is_black'); |
||||
|
$query->dateBetween('subscribe_at')->where(['appid' => $this->appid])->order('subscribe_time desc')->page(); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 列表数据处理 |
||||
|
* @param array $data |
||||
|
*/ |
||||
|
protected function _index_page_filter(array &$data) |
||||
|
{ |
||||
|
$tags = Db::name('WechatFansTags')->column('id,name'); |
||||
|
foreach ($data as &$user) { |
||||
|
$user['tags'] = []; |
||||
|
foreach (explode(',', $user['tagid_list']) as $tagid) { |
||||
|
if (isset($tags[$tagid])) $user['tags'][] = $tags[$tagid]; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 批量拉黑粉丝 |
||||
|
* @auth true |
||||
|
*/ |
||||
|
public function setBlack() |
||||
|
{ |
||||
|
$this->applyCsrfToken(); |
||||
|
try { |
||||
|
foreach (array_chunk(explode(',', $this->request->post('openid')), 20) as $openids) { |
||||
|
WechatService::WeChatUser($this->appid)->batchBlackList($openids); |
||||
|
Db::name('WechatFans')->whereIn('openid', $openids)->update(['is_black' => '1']); |
||||
|
} |
||||
|
$this->success('拉黑粉丝信息成功!'); |
||||
|
} catch (HttpResponseException $exception) { |
||||
|
throw $exception; |
||||
|
} catch (\Exception $e) { |
||||
|
$this->error("拉黑粉丝信息失败,请稍候再试!{$e->getMessage()}"); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 取消拉黑粉丝 |
||||
|
* @auth true |
||||
|
*/ |
||||
|
public function delBlack() |
||||
|
{ |
||||
|
try { |
||||
|
$this->applyCsrfToken(); |
||||
|
foreach (array_chunk(explode(',', $this->request->post('openid')), 20) as $openids) { |
||||
|
WechatService::WeChatUser($this->appid)->batchUnblackList($openids); |
||||
|
Db::name('WechatFans')->whereIn('openid', $openids)->update(['is_black' => '0']); |
||||
|
} |
||||
|
$this->success('取消拉黑粉丝信息成功!'); |
||||
|
} catch (HttpResponseException $exception) { |
||||
|
throw $exception; |
||||
|
} catch (\Exception $e) { |
||||
|
$this->error("取消拉黑粉丝信息失败,请稍候再试!{$e->getMessage()}"); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 同步粉丝列表 |
||||
|
* @auth true |
||||
|
*/ |
||||
|
public function sync() |
||||
|
{ |
||||
|
try { |
||||
|
sysoplog('微信管理', "创建微信[{$this->appid}]粉丝同步任务"); |
||||
|
QueueService::add("同步[{$this->appid}]粉丝列表", WechatQueue::URI, 0, ['appid' => $this->appid], 0); |
||||
|
$this->success('创建同步粉丝任务成功,需要时间来完成。<br>请到系统任务管理查看进度!'); |
||||
|
} catch (HttpResponseException $exception) { |
||||
|
throw $exception; |
||||
|
} catch (\Exception $e) { |
||||
|
$this->error("创建同步粉丝任务失败,请稍候再试!<br> {$e->getMessage()}"); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 删除粉丝信息 |
||||
|
* @auth true |
||||
|
* @throws \think\Exception |
||||
|
* @throws \think\exception\PDOException |
||||
|
*/ |
||||
|
public function remove() |
||||
|
{ |
||||
|
$this->applyCsrfToken(); |
||||
|
$this->_delete($this->table); |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,159 @@ |
|||||
|
<?php |
||||
|
|
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | ThinkAdmin |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 版权所有 2014~2019 广州楚才信息科技有限公司 [ http://www.cuci.cc ] |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 官方网站: http://demo.thinkadmin.top |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 开源协议 ( https://mit-license.org ) |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin |
||||
|
// | github 代码仓库:https://github.com/zoujingli/ThinkAdmin |
||||
|
// +---------------------------------------------------------------------- |
||||
|
|
||||
|
namespace app\service\controller; |
||||
|
|
||||
|
use app\service\service\BuildService; |
||||
|
use app\service\service\WechatService; |
||||
|
use library\Controller; |
||||
|
use think\Db; |
||||
|
|
||||
|
/** |
||||
|
* 公众授权管理 |
||||
|
* @package app\service\controller |
||||
|
*/ |
||||
|
class Index extends Controller |
||||
|
{ |
||||
|
|
||||
|
/** |
||||
|
* 绑定数据表 |
||||
|
* @var string |
||||
|
*/ |
||||
|
public $table = 'WechatServiceConfig'; |
||||
|
|
||||
|
/** |
||||
|
* 公众授权管理 |
||||
|
* @auth true |
||||
|
* @menu true |
||||
|
* @return string |
||||
|
* @throws \think\Exception |
||||
|
* @throws \think\db\exception\DataNotFoundException |
||||
|
* @throws \think\db\exception\ModelNotFoundException |
||||
|
* @throws \think\exception\DbException |
||||
|
*/ |
||||
|
public function index() |
||||
|
{ |
||||
|
$this->applyCsrfToken(); |
||||
|
$this->title = '公众授权管理'; |
||||
|
$query = $this->_query($this->table)->like('authorizer_appid,nick_name,principal_name'); |
||||
|
$query = $query->equal('service_type,status')->dateBetween('create_at'); |
||||
|
$query->where(['is_deleted' => '0'])->order('id desc')->page(); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 清理调用次数 |
||||
|
* @auth true |
||||
|
* @throws \WeChat\Exceptions\InvalidResponseException |
||||
|
* @throws \WeChat\Exceptions\LocalCacheException |
||||
|
*/ |
||||
|
public function clearQuota() |
||||
|
{ |
||||
|
$appid = input('appid'); |
||||
|
$result = WechatService::WeChatLimit($appid)->clearQuota(); |
||||
|
if (empty($result['errcode']) && $result['errmsg'] === 'ok') { |
||||
|
$this->success('接口调用次数清零成功!'); |
||||
|
} elseif (isset($result['errmsg'])) { |
||||
|
$this->error('接口调用次数清零失败,请稍候再试!' . $result['errmsg']); |
||||
|
} else { |
||||
|
$this->error('接口调用次数清零失败,请稍候再试!'); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 同步指定授权公众号 |
||||
|
* @auth true |
||||
|
*/ |
||||
|
public function sync() |
||||
|
{ |
||||
|
try { |
||||
|
$appid = $this->request->get('appid'); |
||||
|
$where = ['authorizer_appid' => $appid, 'is_deleted' => '0', 'status' => '1']; |
||||
|
$author = Db::name('WechatServiceConfig')->where($where)->find(); |
||||
|
empty($author) && $this->error('无效的授权信息,请同步其它公众号!'); |
||||
|
$data = BuildService::filter(WechatService::service()->getAuthorizerInfo($appid)); |
||||
|
$data['authorizer_appid'] = $appid; |
||||
|
$where = ['authorizer_appid' => $data['authorizer_appid']]; |
||||
|
$appkey = Db::name('WechatServiceConfig')->where($where)->value('appkey'); |
||||
|
if (empty($appkey)) $data['appkey'] = md5(uniqid('', true)); |
||||
|
if (data_save('WechatServiceConfig', $data, 'authorizer_appid')) { |
||||
|
$this->success('更新公众号授权信息成功!', ''); |
||||
|
} |
||||
|
} catch (\think\exception\HttpResponseException $exception) { |
||||
|
throw $exception; |
||||
|
} catch (\Exception $e) { |
||||
|
$this->error("获取授权信息失败,请稍候再试!<br>{$e->getMessage()}"); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 同步所有授权公众号 |
||||
|
* @auth true |
||||
|
*/ |
||||
|
public function syncall() |
||||
|
{ |
||||
|
try { |
||||
|
$wechat = WechatService::service(); |
||||
|
$result = $wechat->getAuthorizerList(); |
||||
|
foreach ($result['list'] as $item) if (!empty($item['refresh_token']) && !empty($item['auth_time'])) { |
||||
|
$data = BuildService::filter($wechat->getAuthorizerInfo($item['authorizer_appid'])); |
||||
|
$data['is_deleted'] = '0'; |
||||
|
$data['authorizer_appid'] = $item['authorizer_appid']; |
||||
|
$data['authorizer_refresh_token'] = $item['refresh_token']; |
||||
|
$data['create_at'] = date('Y-m-d H:i:s', $item['auth_time']); |
||||
|
$where = ['authorizer_appid' => $data['authorizer_appid']]; |
||||
|
$appkey = Db::name('WechatServiceConfig')->where($where)->value('appkey'); |
||||
|
if (empty($appkey)) $data['appkey'] = md5(uniqid('', true)); |
||||
|
if (!data_save('WechatServiceConfig', $data, 'authorizer_appid')) { |
||||
|
$this->error('获取授权信息失败,请稍候再试!', ''); |
||||
|
} |
||||
|
} |
||||
|
$this->success('同步所有授权信息成功!', ''); |
||||
|
} catch (\think\exception\HttpResponseException $exception) { |
||||
|
throw $exception; |
||||
|
} catch (\Exception $e) { |
||||
|
$this->error("同步授权失败,请稍候再试!<br>{$e->getMessage()}"); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 删除公众号授权 |
||||
|
* @auth true |
||||
|
*/ |
||||
|
public function remove() |
||||
|
{ |
||||
|
$this->applyCsrfToken(); |
||||
|
$this->_delete($this->table); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 禁用公众号授权 |
||||
|
* @auth true |
||||
|
*/ |
||||
|
public function forbid() |
||||
|
{ |
||||
|
$this->applyCsrfToken(); |
||||
|
$this->_save($this->table, ['status' => '0']); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 启用公众号授权 |
||||
|
* @auth true |
||||
|
*/ |
||||
|
public function resume() |
||||
|
{ |
||||
|
$this->applyCsrfToken(); |
||||
|
$this->_save($this->table, ['status' => '1']); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,155 @@ |
|||||
|
<?php |
||||
|
|
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | ThinkAdmin |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 版权所有 2014~2019 广州楚才信息科技有限公司 [ http://www.cuci.cc ] |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 官方网站: http://demo.thinkadmin.top |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 开源协议 ( https://mit-license.org ) |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin |
||||
|
// | github 代码仓库:https://github.com/zoujingli/ThinkAdmin |
||||
|
// +---------------------------------------------------------------------- |
||||
|
|
||||
|
namespace app\service\controller\api; |
||||
|
|
||||
|
use app\service\service\WechatService; |
||||
|
use think\Controller; |
||||
|
use think\Db; |
||||
|
|
||||
|
/** |
||||
|
* 获取微信SDK实例对象 |
||||
|
* Class Instance |
||||
|
* @package app\wechat\controller |
||||
|
*/ |
||||
|
class Client extends Controller |
||||
|
{ |
||||
|
|
||||
|
/** |
||||
|
* 当前配置 |
||||
|
* @var string |
||||
|
*/ |
||||
|
protected $config = []; |
||||
|
|
||||
|
/** |
||||
|
* 当前APPID |
||||
|
* @var string |
||||
|
*/ |
||||
|
protected $appid = ''; |
||||
|
|
||||
|
/** |
||||
|
* 接口实例名称 |
||||
|
* @var string |
||||
|
*/ |
||||
|
protected $name = ''; |
||||
|
|
||||
|
/** |
||||
|
* 接口类型 |
||||
|
* @var string |
||||
|
*/ |
||||
|
protected $type = ''; |
||||
|
|
||||
|
/** |
||||
|
* 错误消息 |
||||
|
* @var string |
||||
|
*/ |
||||
|
protected $message = ''; |
||||
|
|
||||
|
/** |
||||
|
* 启动Yar接口服务 |
||||
|
* @param string $param AppName-AppId-AppKey |
||||
|
* @return string |
||||
|
*/ |
||||
|
public function yar($param) |
||||
|
{ |
||||
|
try { |
||||
|
$instance = $this->create($param); |
||||
|
$service = new \Yar_Server(empty($instance) ? $this : $instance); |
||||
|
$service->handle(); |
||||
|
} catch (\Exception $e) { |
||||
|
return $e->getMessage(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 启动SOAP接口服务 |
||||
|
* @param string $param AppName-AppId-AppKey |
||||
|
* @return string |
||||
|
*/ |
||||
|
public function soap($param) |
||||
|
{ |
||||
|
try { |
||||
|
$instance = $this->create($param); |
||||
|
$service = new \SoapServer(null, ['uri' => strtolower($this->name)]); |
||||
|
$service->setObject(empty($instance) ? $this : $instance); |
||||
|
$service->handle(); |
||||
|
} catch (\Exception $e) { |
||||
|
return $e->getMessage(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 创建接口服务 |
||||
|
* @param string $token |
||||
|
* @return \WeChat\Oauth|\WeChat\Pay|\WeChat\Receive|\WeChat\Script|\WeChat\User|\WeOpen\Service |
||||
|
* @throws \think\db\exception\DataNotFoundException |
||||
|
* @throws \think\db\exception\ModelNotFoundException |
||||
|
* @throws \think\exception\DbException |
||||
|
* @throws \think\Exception |
||||
|
*/ |
||||
|
private function create($token) |
||||
|
{ |
||||
|
if ($this->auth($token)) { |
||||
|
$weminiClassName = 'Account,Basic,Code,Domain,Tester,User,Crypt,Plugs,Poi,Qrcode,Template,Total'; |
||||
|
$wechatClassName = 'Card,Custom,Limit,Media,Menu,Oauth,Pay,Product,Qrcode,Receive,Scan,Script,Shake,Tags,Template,User,Wifi'; |
||||
|
if ($this->type === 'wechat' && stripos($wechatClassName, $this->name) !== false) { |
||||
|
$instance = WechatService::instance($this->name, $this->appid, 'WeChat'); |
||||
|
} elseif ($this->type === 'wemini' && stripos($weminiClassName, $this->name) !== false) { |
||||
|
$instance = WechatService::instance($this->name, $this->appid, 'WeMini'); |
||||
|
} elseif (stripos('Service,MiniApp', $this->name) !== false) { |
||||
|
$instance = WechatService::instance($this->name, $this->appid, 'WeOpen'); |
||||
|
} elseif (stripos('Wechat,Config,Handler', $this->name) !== false) { |
||||
|
$className = "\\app\\service\\handler\\WechatHandler"; |
||||
|
$instance = new $className($this->config); |
||||
|
} |
||||
|
if (!empty($instance)) return $instance; |
||||
|
} |
||||
|
throw new \think\Exception($this->message); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 加载微信实例对象 |
||||
|
* @param string $token 数据格式 name|appid|appkey |
||||
|
* @return bool |
||||
|
* @throws \think\Exception |
||||
|
* @throws \think\db\exception\DataNotFoundException |
||||
|
* @throws \think\db\exception\ModelNotFoundException |
||||
|
* @throws \think\exception\DbException |
||||
|
*/ |
||||
|
private function auth($token = '') |
||||
|
{ |
||||
|
list($this->name, $this->appid, $appkey, $this->type) = explode('-', $token . '---'); |
||||
|
if (empty($this->name) || empty($this->appid) || empty($appkey)) { |
||||
|
$this->message = '缺少必要的参数AppId或AppKey'; |
||||
|
return false; |
||||
|
} |
||||
|
$where = ['authorizer_appid' => $this->appid, 'status' => '1', 'is_deleted' => '0']; |
||||
|
$this->config = Db::name('WechatServiceConfig')->where($where)->find(); |
||||
|
if (empty($this->config)) { |
||||
|
$this->message = '无效的微信绑定对象'; |
||||
|
return false; |
||||
|
} |
||||
|
if (strtolower($this->config['appkey']) !== strtolower($appkey)) { |
||||
|
$this->message = '授权AppId与AppKey不匹配'; |
||||
|
return false; |
||||
|
} |
||||
|
$this->message = ''; |
||||
|
$this->name = ucfirst(strtolower($this->name)); |
||||
|
$this->type = strtolower(empty($this->type) ? 'WeChat' : $this->type); |
||||
|
Db::name('WechatServiceConfig')->where($where)->setInc('total', 1); |
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,183 @@ |
|||||
|
<?php |
||||
|
|
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | ThinkAdmin |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 版权所有 2014~2019 广州楚才信息科技有限公司 [ http://www.cuci.cc ] |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 官方网站: http://demo.thinkadmin.top |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 开源协议 ( https://mit-license.org ) |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin |
||||
|
// | github 代码仓库:https://github.com/zoujingli/ThinkAdmin |
||||
|
// +---------------------------------------------------------------------- |
||||
|
|
||||
|
namespace app\service\controller\api; |
||||
|
|
||||
|
use app\service\service\BuildService; |
||||
|
use app\service\service\WechatService; |
||||
|
use library\Controller; |
||||
|
use think\Db; |
||||
|
|
||||
|
/** |
||||
|
* 微信推送事件处理 |
||||
|
* |
||||
|
* @author Anyon <zoujingli@qq.com> |
||||
|
* @date 2016/10/18 12:38 |
||||
|
*/ |
||||
|
class Push extends Controller |
||||
|
{ |
||||
|
|
||||
|
/** |
||||
|
* 微信API推送事件处理 |
||||
|
* @param string $appid |
||||
|
* @return string |
||||
|
* @throws \think\Exception |
||||
|
* @throws \WeChat\Exceptions\InvalidDecryptException |
||||
|
* @throws \think\db\exception\DataNotFoundException |
||||
|
* @throws \think\db\exception\ModelNotFoundException |
||||
|
* @throws \think\exception\DbException |
||||
|
* @throws \think\exception\PDOException |
||||
|
*/ |
||||
|
public function notify($appid) |
||||
|
{ |
||||
|
if (in_array($appid, ['wx570bc396a51b8ff8', 'wxd101a85aa106f53e'])) { |
||||
|
# 全网发布接口测试 |
||||
|
return \app\service\handler\PublishHandler::handler($appid); |
||||
|
} else { |
||||
|
# 接口类正常服务 |
||||
|
return \app\service\handler\ReceiveHandler::handler($appid); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 一、处理服务推送Ticket |
||||
|
* 二、处理取消公众号授权 |
||||
|
* @return string |
||||
|
* @throws \think\Exception |
||||
|
* @throws \WeChat\Exceptions\InvalidResponseException |
||||
|
* @throws \WeChat\Exceptions\LocalCacheException |
||||
|
* @throws \think\exception\PDOException |
||||
|
*/ |
||||
|
public function ticket() |
||||
|
{ |
||||
|
try { |
||||
|
$server = WechatService::service(); |
||||
|
if (!($data = $server->getComonentTicket())) { |
||||
|
return "Ticket event handling failed."; |
||||
|
} |
||||
|
} catch (\Exception $e) { |
||||
|
return "Ticket event handling failed, {$e->getMessage()}"; |
||||
|
} |
||||
|
if (!empty($data['AuthorizerAppid']) && isset($data['InfoType'])) { |
||||
|
# 授权成功通知 |
||||
|
if ($data['InfoType'] === 'authorized') { |
||||
|
Db::name('WechatServiceConfig')->where(['authorizer_appid' => $data['AuthorizerAppid']])->update(['is_deleted' => '0']); |
||||
|
} |
||||
|
# 接收取消授权服务事件 |
||||
|
if ($data['InfoType'] === 'unauthorized') { |
||||
|
Db::name('WechatServiceConfig')->where(['authorizer_appid' => $data['AuthorizerAppid']])->update(['is_deleted' => '1']); |
||||
|
} |
||||
|
# 授权更新通知 |
||||
|
if ($data['InfoType'] === 'updateauthorized') { |
||||
|
$_GET['auth_code'] = $data['PreAuthCode']; |
||||
|
$this->applyAuth($server); |
||||
|
} |
||||
|
} |
||||
|
return 'success'; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 网页授权 |
||||
|
* @throws \think\Exception |
||||
|
* @throws \WeChat\Exceptions\InvalidResponseException |
||||
|
* @throws \WeChat\Exceptions\LocalCacheException |
||||
|
*/ |
||||
|
public function oauth() |
||||
|
{ |
||||
|
list($mode, $appid, $enurl, $sessid) = [ |
||||
|
$this->request->get('mode'), $this->request->get('state'), |
||||
|
$this->request->get('enurl'), $this->request->get('sessid'), |
||||
|
]; |
||||
|
$service = WechatService::service(); |
||||
|
$result = $service->getOauthAccessToken($appid); |
||||
|
if (empty($result['openid'])) throw new \think\Exception('网页授权失败, 无法进一步操作!'); |
||||
|
cache("{$appid}_{$sessid}_openid", $result['openid'], 3600); |
||||
|
if (!empty($mode)) { |
||||
|
$wechat = new \WeChat\Oauth($service->getConfig($appid)); |
||||
|
$fans = $wechat->getUserInfo($result['access_token'], $result['openid']); |
||||
|
if (empty($fans)) throw new \think\Exception('网页授权信息获取失败, 无法进一步操作!'); |
||||
|
cache("{$appid}_{$sessid}_fans", $fans, 3600); |
||||
|
} |
||||
|
redirect(decode($enurl), [], 301)->send(); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 跳转到微信服务授权页面 |
||||
|
* @param string $redirect |
||||
|
* @return string |
||||
|
* @throws \think\Exception |
||||
|
* @throws \WeChat\Exceptions\InvalidResponseException |
||||
|
* @throws \WeChat\Exceptions\LocalCacheException |
||||
|
* @throws \think\exception\PDOException |
||||
|
*/ |
||||
|
public function auth($redirect = '') |
||||
|
{ |
||||
|
$fromRedirect = decode($redirect); |
||||
|
if (empty($redirect) || empty($fromRedirect)) { |
||||
|
return '请传入回跳Redirect参数 ( 请使用ENCODE加密 )'; |
||||
|
} |
||||
|
# 预授权码不为空,则表示可以进行授权处理 |
||||
|
$service = WechatService::service(); |
||||
|
if (($auth_code = $this->request->get('auth_code'))) { |
||||
|
return $this->applyAuth($service, $fromRedirect); |
||||
|
} |
||||
|
# 生成微信授权链接,使用刷新跳转到授权网页 |
||||
|
$url = url("@service/api.push/auth/{$redirect}", false, true, true); |
||||
|
if (($redirect = $service->getAuthRedirect($url))) { |
||||
|
ob_clean(); |
||||
|
header("Refresh:0;url={$redirect}"); |
||||
|
return "<script>window.location.href='{$redirect}';</script><a href='{$redirect}'>跳转中...</a>"; |
||||
|
} |
||||
|
# 生成微信授权链接失败 |
||||
|
return "<h2>Failed to create authorization. Please return to try again.</h2>"; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 公众号授权绑定数据处理 |
||||
|
* @param \WeOpen\Service $service |
||||
|
* @param string|null $redirect 授权成功回跳地址 |
||||
|
* @return string |
||||
|
* @throws \WeChat\Exceptions\InvalidResponseException |
||||
|
* @throws \WeChat\Exceptions\LocalCacheException |
||||
|
* @throws \think\Exception |
||||
|
* @throws \think\exception\PDOException |
||||
|
*/ |
||||
|
private function applyAuth($service, $redirect = null) |
||||
|
{ |
||||
|
// 通过授权code换取公众号信息 |
||||
|
$result = $service->getQueryAuthorizerInfo(); |
||||
|
if (empty($result['authorizer_appid'])) { |
||||
|
return "接收微信第三方平台授权失败! "; |
||||
|
} |
||||
|
// 重新通过接口查询公众号参数 |
||||
|
if (!($update = array_merge($result, $service->getAuthorizerInfo($result['authorizer_appid'])))) { |
||||
|
return '获取授权数据失败, 请稍候再试!'; |
||||
|
} |
||||
|
// 生成公众号授权参数 |
||||
|
$update = array_merge(BuildService::filter($update), [ |
||||
|
'status' => '1', 'is_deleted' => '0', 'expires_in' => time() + 7000, 'create_at' => date('y-m-d H:i:s'), |
||||
|
]); |
||||
|
// 微信接口APPKEY处理与更新 |
||||
|
$config = Db::name('WechatServiceConfig')->where(['authorizer_appid' => $result['authorizer_appid']])->find(); |
||||
|
$update['appkey'] = empty($config['appkey']) ? md5(uniqid('', true)) : $config['appkey']; |
||||
|
data_save('WechatServiceConfig', $update, 'authorizer_appid'); |
||||
|
if (!empty($redirect)) { // 带上appid与appkey跳转到应用 |
||||
|
$split = stripos($redirect, '?') > 0 ? '&' : '?'; |
||||
|
$realurl = preg_replace(['/appid=\w+/i', '/appkey=\w+/i', '/(\?\&)$/i'], ['', '', ''], $redirect); |
||||
|
return redirect("{$realurl}{$split}appid={$update['authorizer_appid']}&appkey={$update['appkey']}"); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,69 @@ |
|||||
|
<?php |
||||
|
|
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | ThinkAdmin |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 版权所有 2014~2019 广州楚才信息科技有限公司 [ http://www.cuci.cc ] |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 官方网站: http://demo.thinkadmin.top |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 开源协议 ( https://mit-license.org ) |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin |
||||
|
// | github 代码仓库:https://github.com/zoujingli/ThinkAdmin |
||||
|
// +---------------------------------------------------------------------- |
||||
|
|
||||
|
namespace app\service\handler; |
||||
|
|
||||
|
use app\service\service\WechatService; |
||||
|
|
||||
|
/** |
||||
|
* 第三方平台测试上线 |
||||
|
* |
||||
|
* @author Anyon <zoujingli@qq.com> |
||||
|
* @date 2016/10/27 14:14 |
||||
|
*/ |
||||
|
class PublishHandler |
||||
|
{ |
||||
|
|
||||
|
/** |
||||
|
* 当前微信APPID |
||||
|
* @var string |
||||
|
*/ |
||||
|
protected static $appid; |
||||
|
|
||||
|
/** |
||||
|
* 事件初始化 |
||||
|
* @param string $appid |
||||
|
* @return string |
||||
|
* @throws \WeChat\Exceptions\InvalidDecryptException |
||||
|
* @throws \WeChat\Exceptions\InvalidResponseException |
||||
|
* @throws \WeChat\Exceptions\LocalCacheException |
||||
|
*/ |
||||
|
public static function handler($appid) |
||||
|
{ |
||||
|
try { |
||||
|
$wechat = WechatService::WeChatReceive($appid); |
||||
|
} catch (\Exception $e) { |
||||
|
return "Wechat message handling failed, {$e->getMessage()}"; |
||||
|
} |
||||
|
/* 分别执行对应类型的操作 */ |
||||
|
switch (strtolower($wechat->getMsgType())) { |
||||
|
case 'text': |
||||
|
$receive = $wechat->getReceive(); |
||||
|
if ($receive['Content'] === 'TESTCOMPONENT_MSG_TYPE_TEXT') { |
||||
|
return $wechat->text('TESTCOMPONENT_MSG_TYPE_TEXT_callback')->reply([], true); |
||||
|
} else { |
||||
|
$key = str_replace("QUERY_AUTH_CODE:", '', $receive['Content']); |
||||
|
WechatService::service()->getQueryAuthorizerInfo($key); |
||||
|
return $wechat->text("{$key}_from_api")->reply([], true); |
||||
|
} |
||||
|
case 'event': |
||||
|
$receive = $wechat->getReceive(); |
||||
|
return $wechat->text("{$receive['Event']}from_callback")->reply([], true); |
||||
|
default: |
||||
|
return 'success'; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,69 @@ |
|||||
|
<?php |
||||
|
|
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | ThinkAdmin |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 版权所有 2014~2019 广州楚才信息科技有限公司 [ http://www.cuci.cc ] |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 官方网站: http://demo.thinkadmin.top |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 开源协议 ( https://mit-license.org ) |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin |
||||
|
// | github 代码仓库:https://github.com/zoujingli/ThinkAdmin |
||||
|
// +---------------------------------------------------------------------- |
||||
|
|
||||
|
namespace app\service\handler; |
||||
|
|
||||
|
use app\service\service\WechatService; |
||||
|
use think\Db; |
||||
|
|
||||
|
/** |
||||
|
* 微信推送消息处理 |
||||
|
* |
||||
|
* @author Anyon <zoujingli@qq.com> |
||||
|
* @date 2016/10/27 14:14 |
||||
|
*/ |
||||
|
class ReceiveHandler |
||||
|
{ |
||||
|
|
||||
|
/** |
||||
|
* 事件初始化 |
||||
|
* @param string $appid |
||||
|
* @return string |
||||
|
* @throws \think\db\exception\DataNotFoundException |
||||
|
* @throws \think\db\exception\ModelNotFoundException |
||||
|
* @throws \think\exception\DbException |
||||
|
* @throws \think\Exception |
||||
|
*/ |
||||
|
public static function handler($appid) |
||||
|
{ |
||||
|
try { |
||||
|
$wechat = WechatService::WeChatReceive($appid); |
||||
|
} catch (\Exception $e) { |
||||
|
return "Wechat message handling failed, {$e->getMessage()}"; |
||||
|
} |
||||
|
// 验证微信配置信息 |
||||
|
$config = Db::name('WechatServiceConfig')->where(['authorizer_appid' => $appid])->find(); |
||||
|
if (empty($config) || empty($config['appuri'])) { |
||||
|
\think\facade\Log::error(($message = "微信{$appid}授权配置验证无效")); |
||||
|
return $message; |
||||
|
} |
||||
|
try { |
||||
|
list($data, $openid) = [$wechat->getReceive(), $wechat->getOpenid()]; |
||||
|
if (isset($data['EventKey']) && is_object($data['EventKey'])) $data['EventKey'] = (array)$data['EventKey']; |
||||
|
$input = ['openid' => $openid, 'appid' => $appid, 'receive' => serialize($data), 'encrypt' => intval($wechat->isEncrypt())]; |
||||
|
if (is_string($result = http_post($config['appuri'], $input, ['timeout' => 30]))) { |
||||
|
if (is_array($json = json_decode($result, true))) { |
||||
|
return $wechat->reply($json, true, $wechat->isEncrypt()); |
||||
|
} else { |
||||
|
return $result; |
||||
|
} |
||||
|
} |
||||
|
} catch (\Exception $e) { |
||||
|
\think\facade\Log::error("微信{$appid}接口调用异常,{$e->getMessage()}"); |
||||
|
} |
||||
|
return 'success'; |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,161 @@ |
|||||
|
<?php |
||||
|
|
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | ThinkAdmin |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 版权所有 2014~2019 广州楚才信息科技有限公司 [ http://www.cuci.cc ] |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 官方网站: http://demo.thinkadmin.top |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 开源协议 ( https://mit-license.org ) |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin |
||||
|
// | github 代码仓库:https://github.com/zoujingli/ThinkAdmin |
||||
|
// +---------------------------------------------------------------------- |
||||
|
|
||||
|
namespace app\service\handler; |
||||
|
|
||||
|
use app\service\service\WechatService as WechatLogic; |
||||
|
use think\Db; |
||||
|
|
||||
|
/** |
||||
|
* 微信网页授权接口 |
||||
|
* Class WechatHandler |
||||
|
* @package app\wechat\handler |
||||
|
* @author Anyon <zoujingli@qq.com> |
||||
|
*/ |
||||
|
class WechatHandler |
||||
|
{ |
||||
|
/** |
||||
|
* 当前微信APPID |
||||
|
* @var string |
||||
|
*/ |
||||
|
protected $appid; |
||||
|
|
||||
|
/** |
||||
|
* 当前微信配置 |
||||
|
* @var array |
||||
|
*/ |
||||
|
protected $config; |
||||
|
|
||||
|
/** |
||||
|
* 错误消息 |
||||
|
* @var string |
||||
|
*/ |
||||
|
protected $message; |
||||
|
|
||||
|
/** |
||||
|
* Wechat constructor. |
||||
|
* @param array $config |
||||
|
*/ |
||||
|
public function __construct($config = []) |
||||
|
{ |
||||
|
$this->config = $config; |
||||
|
$this->appid = isset($config['authorizer_appid']) ? $config['authorizer_appid'] : ''; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 检查微信配置服务初始化状态 |
||||
|
* @return boolean |
||||
|
* @throws \think\Exception |
||||
|
*/ |
||||
|
private function checkInit() |
||||
|
{ |
||||
|
if (!empty($this->config)) return true; |
||||
|
throw new \think\Exception('Wechat Please bind Wechat first'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 获取当前公众号配置 |
||||
|
* @return array|boolean |
||||
|
* @throws \think\Exception |
||||
|
*/ |
||||
|
public function getConfig() |
||||
|
{ |
||||
|
$this->checkInit(); |
||||
|
$info = Db::name('WechatServiceConfig')->where(['authorizer_appid' => $this->appid])->find(); |
||||
|
if (empty($info)) return false; |
||||
|
if (isset($info['id'])) unset($info['id']); |
||||
|
return $info; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 设置微信接口通知URL地址 |
||||
|
* @param string $notifyUri 接口通知URL地址 |
||||
|
* @return boolean |
||||
|
* @throws \think\Exception |
||||
|
* @throws \think\exception\PDOException |
||||
|
*/ |
||||
|
public function setApiNotifyUri($notifyUri) |
||||
|
{ |
||||
|
$this->checkInit(); |
||||
|
if (empty($notifyUri)) throw new \think\Exception('请传入微信通知URL'); |
||||
|
list($where, $data) = [['authorizer_appid' => $this->appid], ['appuri' => $notifyUri]]; |
||||
|
return Db::name('WechatServiceConfig')->where($where)->update($data) !== false; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 更新接口Appkey(成功返回新的Appkey) |
||||
|
* @return bool|string |
||||
|
* @throws \think\Exception |
||||
|
* @throws \think\exception\PDOException |
||||
|
*/ |
||||
|
public function updateApiAppkey() |
||||
|
{ |
||||
|
$this->checkInit(); |
||||
|
$data = ['appkey' => md5(uniqid())]; |
||||
|
Db::name('WechatServiceConfig')->where(['authorizer_appid' => $this->appid])->update($data); |
||||
|
return $data['appkey']; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 获取公众号的配置参数 |
||||
|
* @param string $name 参数名称 |
||||
|
* @return array|string |
||||
|
* @throws \think\Exception |
||||
|
*/ |
||||
|
public function config($name = null) |
||||
|
{ |
||||
|
$this->checkInit(); |
||||
|
return WechatLogic::WeChatScript($this->appid)->config->get($name); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 微信网页授权 |
||||
|
* @param string $sessid 当前会话id(可用session_id()获取) |
||||
|
* @param string $selfUrl 当前会话URL地址(需包含域名的完整URL地址) |
||||
|
* @param int $fullMode 网页授权模式(0静默模式,1高级授权) |
||||
|
* @return array|bool |
||||
|
* @throws \think\Exception |
||||
|
*/ |
||||
|
public function oauth($sessid, $selfUrl, $fullMode = 0) |
||||
|
{ |
||||
|
$this->checkInit(); |
||||
|
$fans = cache("{$this->appid}_{$sessid}_fans"); |
||||
|
$openid = cache("{$this->appid}_{$sessid}_openid"); |
||||
|
if (!empty($openid) && (empty($fullMode) || !empty($fans))) { |
||||
|
return ['openid' => $openid, 'fans' => $fans, 'url' => '']; |
||||
|
} |
||||
|
$service = WechatLogic::service(); |
||||
|
$mode = empty($fullMode) ? 'snsapi_base' : 'snsapi_userinfo'; |
||||
|
$url = url('@service/api.push/oauth', '', true, true); |
||||
|
$params = ['mode' => $fullMode, 'sessid' => $sessid, 'enurl' => encode($selfUrl)]; |
||||
|
$authurl = $service->getOauthRedirect($this->appid, $url . '?' . http_build_query($params), $mode); |
||||
|
return ['openid' => $openid, 'fans' => $fans, 'url' => $authurl]; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 微信网页JS签名 |
||||
|
* @param string $url 当前会话URL地址(需包含域名的完整URL地址) |
||||
|
* @return array|boolean |
||||
|
* @throws \WeChat\Exceptions\InvalidResponseException |
||||
|
* @throws \WeChat\Exceptions\LocalCacheException |
||||
|
* @throws \think\Exception |
||||
|
*/ |
||||
|
public function jsSign($url) |
||||
|
{ |
||||
|
$this->checkInit(); |
||||
|
return WechatLogic::WeChatScript($this->appid)->getJsSign($url); |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,82 @@ |
|||||
|
<?php |
||||
|
|
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | ThinkAdmin |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 版权所有 2014~2019 广州楚才信息科技有限公司 [ http://www.cuci.cc ] |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 官方网站: http://demo.thinkadmin.top |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 开源协议 ( https://mit-license.org ) |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin |
||||
|
// | github 代码仓库:https://github.com/zoujingli/ThinkAdmin |
||||
|
// +---------------------------------------------------------------------- |
||||
|
|
||||
|
namespace app\service\queue; |
||||
|
|
||||
|
use app\admin\queue\JobsQueue; |
||||
|
use app\service\service\WechatService; |
||||
|
use app\wechat\service\FansService; |
||||
|
use think\Db; |
||||
|
|
||||
|
/** |
||||
|
* Class Jobs |
||||
|
* @package app\wechat |
||||
|
*/ |
||||
|
class WechatQueue extends JobsQueue |
||||
|
{ |
||||
|
/** |
||||
|
* 当前任务URI |
||||
|
*/ |
||||
|
const URI = self::class; |
||||
|
|
||||
|
/** |
||||
|
* 当前操作APPID |
||||
|
* @var string |
||||
|
*/ |
||||
|
protected $appid; |
||||
|
|
||||
|
/** |
||||
|
* 执行任务 |
||||
|
* @return boolean |
||||
|
*/ |
||||
|
public function execute() |
||||
|
{ |
||||
|
try { |
||||
|
$this->appid = $this->data['appid']; |
||||
|
$wechat = WechatService::WeChatUser($this->appid); |
||||
|
$next = ''; // 获取远程粉丝 |
||||
|
$this->output->writeln('Start synchronizing fans from the Wechat server'); |
||||
|
while (is_array($result = $wechat->getUserList($next)) && !empty($result['data']['openid'])) { |
||||
|
foreach (array_chunk($result['data']['openid'], 100) as $chunk) |
||||
|
if (is_array($list = $wechat->getBatchUserInfo($chunk)) && !empty($list['user_info_list'])) |
||||
|
foreach ($list['user_info_list'] as $user) FansService::set($user, $this->appid); |
||||
|
if (in_array($result['next_openid'], $result['data']['openid'])) break; |
||||
|
$next = $result['next_openid']; |
||||
|
} |
||||
|
$next = ''; // 同步粉丝黑名单 |
||||
|
$this->output->writeln('Start synchronizing black from the Wechat server'); |
||||
|
while (is_array($result = $wechat->getBlackList($next)) && !empty($result['data']['openid'])) { |
||||
|
foreach (array_chunk($result['data']['openid'], 100) as $chunk) { |
||||
|
$where = [['is_black', 'eq', '0'], ['openid', 'in', $chunk]]; |
||||
|
Db::name('WechatFans')->where($where)->update(['is_black' => '1']); |
||||
|
} |
||||
|
if (in_array($result['next_openid'], $result['data']['openid'])) break; |
||||
|
$next = $result['next_openid']; |
||||
|
} |
||||
|
// 同步粉丝标签列表 |
||||
|
$this->output->writeln('Start synchronizing tags from the Wechat server'); |
||||
|
if (is_array($list = WechatService::WeChatTags($this->appid)->getTags()) && !empty($list['tags'])) { |
||||
|
foreach ($list['tags'] as &$tag) $tag['appid'] = $this->appid; |
||||
|
Db::name('WechatFansTags')->where('1=1')->delete(); |
||||
|
Db::name('WechatFansTags')->insertAll($list['tags']); |
||||
|
} |
||||
|
return true; |
||||
|
} catch (\Exception $e) { |
||||
|
$this->statusDesc = $e->getMessage(); |
||||
|
return false; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,53 @@ |
|||||
|
<?php |
||||
|
|
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | ThinkAdmin |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 版权所有 2014~2019 广州楚才信息科技有限公司 [ http://www.cuci.cc ] |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 官方网站: http://demo.thinkadmin.top |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 开源协议 ( https://mit-license.org ) |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin |
||||
|
// | github 代码仓库:https://github.com/zoujingli/ThinkAdmin |
||||
|
// +---------------------------------------------------------------------- |
||||
|
|
||||
|
namespace app\service\service; |
||||
|
|
||||
|
/** |
||||
|
* 授权数据处理 |
||||
|
* Class Build |
||||
|
* @package app\service\service |
||||
|
*/ |
||||
|
class BuildService |
||||
|
{ |
||||
|
|
||||
|
/** |
||||
|
* 授权数据过滤转换处理 |
||||
|
* @param array $info |
||||
|
* @return mixed |
||||
|
*/ |
||||
|
public static function filter(array $info) |
||||
|
{ |
||||
|
if (isset($info['func_info'])) $info['func_info'] = join(',', array_map(function ($tmp) { |
||||
|
return $tmp['funcscope_category']['id']; |
||||
|
}, $info['func_info'])); |
||||
|
$info['verify_type_info'] = join(',', $info['verify_type_info']); |
||||
|
$info['service_type_info'] = join(',', $info['service_type_info']); |
||||
|
$info['business_info'] = json_encode($info['business_info'], JSON_UNESCAPED_UNICODE); |
||||
|
// 微信类型: 0 代表订阅号, 2 代表服务号, 3 代表小程序 |
||||
|
$info['service_type'] = intval($info['service_type_info']) === 2 ? 2 : 0; |
||||
|
if (!empty($info['MiniProgramInfo'])) { |
||||
|
// 微信类型: 0 代表订阅号, 2 代表服务号, 3 代表小程序 |
||||
|
$info['service_type'] = 3; |
||||
|
// 小程序信息 |
||||
|
$info['miniprograminfo'] = json_encode($info['MiniProgramInfo'], JSON_UNESCAPED_UNICODE); |
||||
|
} |
||||
|
unset($info['MiniProgramInfo']); |
||||
|
// 微信认证: -1 代表未认证, 0 代表微信认证 |
||||
|
$info['verify_type'] = intval($info['verify_type_info']) !== 0 ? -1 : 0; |
||||
|
return $info; |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,151 @@ |
|||||
|
<?php |
||||
|
|
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | ThinkAdmin |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 版权所有 2014~2019 广州楚才信息科技有限公司 [ http://www.cuci.cc ] |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 官方网站: http://demo.thinkadmin.top |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 开源协议 ( https://mit-license.org ) |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin |
||||
|
// | github 代码仓库:https://github.com/zoujingli/ThinkAdmin |
||||
|
// +---------------------------------------------------------------------- |
||||
|
|
||||
|
namespace app\service\service; |
||||
|
|
||||
|
use think\Db; |
||||
|
|
||||
|
/** |
||||
|
* 微信数据服务 |
||||
|
* Class WechatService |
||||
|
* @package app\service\service |
||||
|
* @method \WeChat\Card WeChatCard($appid) static 微信卡券管理 |
||||
|
* @method \WeChat\Custom WeChatCustom($appid) static 微信客服消息 |
||||
|
* @method \WeChat\Limit WeChatLimit($appid) static 接口调用频次限制 |
||||
|
* @method \WeChat\Media WeChatMedia($appid) static 微信素材管理 |
||||
|
* @method \WeChat\Menu WeChatMenu($appid) static 微信菜单管理 |
||||
|
* @method \WeChat\Oauth WeChatOauth($appid) static 微信网页授权 |
||||
|
* @method \WeChat\Pay WeChatPay($appid) static 微信支付商户 |
||||
|
* @method \WeChat\Product WeChatProduct($appid) static 微信商店管理 |
||||
|
* @method \WeChat\Qrcode WeChatQrcode($appid) static 微信二维码管理 |
||||
|
* @method \WeChat\Receive WeChatReceive($appid) static 微信推送管理 |
||||
|
* @method \WeChat\Scan WeChatScan($appid) static 微信扫一扫接入管理 |
||||
|
* @method \WeChat\Script WeChatScript($appid) static 微信前端支持 |
||||
|
* @method \WeChat\Shake WeChatShake($appid) static 微信揺一揺周边 |
||||
|
* @method \WeChat\Tags WeChatTags($appid) static 微信用户标签管理 |
||||
|
* @method \WeChat\Template WeChatTemplate($appid) static 微信模板消息 |
||||
|
* @method \WeChat\User WeChatUser($appid) static 微信粉丝管理 |
||||
|
* @method \WeChat\Wifi WeChatWifi($appid) static 微信门店WIFI管理 |
||||
|
* |
||||
|
* ----- WeMini ----- |
||||
|
* @method \WeMini\Account WeMiniAccount($appid) static 小程序账号管理 |
||||
|
* @method \WeMini\Basic WeMiniBasic($appid) static 小程序基础信息设置 |
||||
|
* @method \WeMini\Code WeMiniCode($appid) static 小程序代码管理 |
||||
|
* @method \WeMini\Domain WeMiniDomain($appid) static 小程序域名管理 |
||||
|
* @method \WeMini\Tester WeMinitester($appid) static 小程序成员管理 |
||||
|
* @method \WeMini\User WeMiniUser($appid) static 小程序帐号管理 |
||||
|
* -------------------- |
||||
|
* @method \WeMini\Crypt WeMiniCrypt($appid) static 小程序数据加密处理 |
||||
|
* @method \WeMini\Plugs WeMiniPlugs($appid) static 小程序插件管理 |
||||
|
* @method \WeMini\Poi WeMiniPoi($appid) static 小程序地址管理 |
||||
|
* @method \WeMini\Qrcode WeMiniQrcode($appid) static 小程序二维码管理 |
||||
|
* @method \WeMini\Template WeMiniTemplate($appid) static 小程序模板消息支持 |
||||
|
* @method \WeMini\Total WeMiniTotal($appid) static 小程序数据接口 |
||||
|
* |
||||
|
* ----- WePay ----- |
||||
|
* @method \WePay\Bill WePayBill($appid) static 微信商户账单及评论 |
||||
|
* @method \WePay\Order WePayOrder($appid) static 微信商户订单 |
||||
|
* @method \WePay\Refund WePayRefund($appid) static 微信商户退款 |
||||
|
* @method \WePay\Coupon WePayCoupon($appid) static 微信商户代金券 |
||||
|
* @method \WePay\Redpack WePayRedpack($appid) static 微信红包支持 |
||||
|
* @method \WePay\Transfers WePayTransfers($appid) static 微信商户打款到零钱 |
||||
|
* @method \WePay\TransfersBank WePayTransfersBank($appid) static 微信商户打款到银行卡 |
||||
|
* |
||||
|
* ----- WeOpen ----- |
||||
|
* @method \WeOpen\Login login() static 第三方微信登录 |
||||
|
* @method \WeOpen\Service service() static 第三方服务 |
||||
|
* |
||||
|
* ----- ThinkService ----- |
||||
|
* @method mixed wechat() static 第三方微信工具 |
||||
|
* @method mixed config() static 第三方配置工具 |
||||
|
*/ |
||||
|
class WechatService |
||||
|
{ |
||||
|
|
||||
|
/** |
||||
|
* 接口类型模式 |
||||
|
* @var string |
||||
|
*/ |
||||
|
private static $type = 'WeChat'; |
||||
|
|
||||
|
/** |
||||
|
* 实例微信对象 |
||||
|
* @param string $name |
||||
|
* @param string $appid 授权公众号APPID |
||||
|
* @param string $type 将要获取SDK类型 |
||||
|
* @return mixed |
||||
|
* @throws \think\Exception |
||||
|
* @throws \think\exception\PDOException |
||||
|
*/ |
||||
|
public static function instance($name, $appid = '', $type = null) |
||||
|
{ |
||||
|
$config = [ |
||||
|
'cache_path' => env('runtime_path') . 'wechat', |
||||
|
'component_appid' => sysconf('component_appid'), |
||||
|
'component_token' => sysconf('component_token'), |
||||
|
'component_appsecret' => sysconf('component_appsecret'), |
||||
|
'component_encodingaeskey' => sysconf('component_encodingaeskey'), |
||||
|
]; |
||||
|
// 注册授权公众号 AccessToken 处理 |
||||
|
$config['GetAccessTokenCallback'] = function ($authorizerAppid) use ($config) { |
||||
|
$where = ['authorizer_appid' => $authorizerAppid]; |
||||
|
if (!($refreshToken = Db::name('WechatServiceConfig')->where($where)->value('authorizer_refresh_token'))) { |
||||
|
throw new \think\Exception('The WeChat information is not configured.', '404'); |
||||
|
} |
||||
|
$open = new \WeOpen\MiniApp($config); |
||||
|
$result = $open->refreshAccessToken($authorizerAppid, $refreshToken); |
||||
|
if (empty($result['authorizer_access_token']) || empty($result['authorizer_refresh_token'])) { |
||||
|
throw new \think\Exception($result['errmsg'], '0'); |
||||
|
} |
||||
|
Db::name('WechatServiceConfig')->where($where)->update([ |
||||
|
'authorizer_access_token' => $result['authorizer_access_token'], |
||||
|
'authorizer_refresh_token' => $result['authorizer_refresh_token'], |
||||
|
]); |
||||
|
return $result['authorizer_access_token']; |
||||
|
}; |
||||
|
$app = new \WeOpen\MiniApp($config); |
||||
|
if (in_array(strtolower($name), ['service', 'miniapp'])) { |
||||
|
return $app; |
||||
|
} |
||||
|
if (!in_array($type, ['WeChat', 'WeMini'])) { |
||||
|
$type = self::$type; |
||||
|
} |
||||
|
return $app->instance($name, $appid, $type); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 静态初始化对象 |
||||
|
* @param string $name |
||||
|
* @param array $arguments |
||||
|
* @return mixed |
||||
|
* @throws \think\Exception |
||||
|
* @throws \think\exception\PDOException |
||||
|
*/ |
||||
|
public static function __callStatic($name, $arguments) |
||||
|
{ |
||||
|
if (substr($name, 0, 6) === 'WeMini') { |
||||
|
self::$type = 'WeMini'; |
||||
|
$name = substr($name, 6); |
||||
|
} elseif (substr($name, 0, 6) === 'WeChat') { |
||||
|
self::$type = 'WeChat'; |
||||
|
$name = substr($name, 6); |
||||
|
} elseif (substr($name, 0, 5) === 'WePay') { |
||||
|
self::$type = 'WePay'; |
||||
|
$name = substr($name, 5); |
||||
|
} |
||||
|
return self::instance($name, isset($arguments[0]) ? $arguments[0] : '', self::$type); |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,109 @@ |
|||||
|
{extend name="admin@main"} |
||||
|
|
||||
|
{block name="content"} |
||||
|
<div class="relative"> |
||||
|
|
||||
|
<div class="think-box-shadow border-0 margin-bottom-20"> |
||||
|
强烈建议安装 YAR 扩展来实现接口通信,SOAP 不能正常显示接口的异常信息 |
||||
|
</div> |
||||
|
|
||||
|
<div class="layui-row layui-col-space15"> |
||||
|
<div class="layui-col-lg6"> |
||||
|
<fieldset class="think-box-shadow"> |
||||
|
<legend class="layui-bg-cyan">授权参数</legend> |
||||
|
<form onsubmit="return false;" action="{:url('save')}" data-auto="true" method="post" class='layui-form padding-left-20 padding-right-20' autocomplete="off"> |
||||
|
<div class="layui-form-item"> |
||||
|
<label class="relative block"> |
||||
|
<span class="color-green">开放平台服务 AppID</span> |
||||
|
<input name="component_appid" required pattern="^.{18}$" maxlength="18" placeholder="请输入18位开放平台服务AppID" value="{:sysconf('component_appid')}" class="layui-input"> |
||||
|
</label> |
||||
|
<p class="help-block">开放平台服务 AppID,需要在微信开放平台获取</p> |
||||
|
</div> |
||||
|
<div class="layui-form-item"> |
||||
|
<label class="relative block"> |
||||
|
<span class="color-green">开放平台服务 AppSecret</span> |
||||
|
<input name="component_appsecret" required pattern="^.{32}$" maxlength="32" placeholder="请输入32位开放平台服务AppSecret" value="{:sysconf('component_appsecret')}" class="layui-input"> |
||||
|
</label> |
||||
|
<p class="help-block">开放平台服务 AppSecret,需要在微信开放平台获取</p> |
||||
|
</div> |
||||
|
<div class="layui-form-item"> |
||||
|
<label class="relative block"> |
||||
|
<span class="color-green">开放平台消息校验 Token</span> |
||||
|
<input name="component_token" required placeholder="请输入微信消息校验Token" value="{:sysconf('component_token')}" class="layui-input"> |
||||
|
</label> |
||||
|
<p class="help-block">开发者在代替微信接收到消息时,用此 Token 来校验消息</p> |
||||
|
</div> |
||||
|
<div class="layui-form-item"> |
||||
|
<label class="relative block"> |
||||
|
<span class="color-green">开放平台消息加解密 AesKey</span> |
||||
|
<input name="component_encodingaeskey" required pattern="^.{43}$" maxlength="43" placeholder="请输入43位微信消息加解密Key" value="{:sysconf('component_encodingaeskey')}" class="layui-input"> |
||||
|
</label> |
||||
|
<p class="help-block">在代替微信收发消息时使用,必须是长度为43位字母和数字组合的字符串</p> |
||||
|
</div> |
||||
|
<div class="hr-line-dashed"></div> |
||||
|
<div class="text-center padding-bottom-15 margin-bottom-20"> |
||||
|
<button class="layui-btn" type="submit">保存配置</button> |
||||
|
</div> |
||||
|
</form> |
||||
|
</fieldset> |
||||
|
</div> |
||||
|
<div class="layui-col-lg6"> |
||||
|
<fieldset class="think-box-shadow"> |
||||
|
<legend class="layui-bg-cyan">对接信息</legend> |
||||
|
<div class="padding-right-20 padding-left-20"> |
||||
|
<div class="layui-form-item"> |
||||
|
<p class="color-green">授权发起页域名</p> |
||||
|
<label class="relative block"> |
||||
|
<input disabled class="layui-input layui-bg-gray" value="{:request()->host()}"> |
||||
|
<a data-copy="{:request()->host()}" class="fa fa-copy right-btn"></a> |
||||
|
</label> |
||||
|
<p class="help-block">从本域名跳转到登录授权页才可以完成登录授权,无需填写域名协议前缀</p> |
||||
|
</div> |
||||
|
<div class="layui-form-item"> |
||||
|
<p class="color-green">授权事件接收 URL</p> |
||||
|
<label class="relative block"> |
||||
|
<input disabled class="layui-input layui-bg-gray" value="{:url('@service/api.push/ticket','',false,true)}"> |
||||
|
<a data-copy="{:url('@service/api.push/ticket','',false,true)}" class="fa fa-copy right-btn"></a> |
||||
|
</label> |
||||
|
<p class="help-block">用于接收取消授权通知、授权成功通知、授权更新通知、接收 TICKET 凭据</p> |
||||
|
</div> |
||||
|
<div class="layui-form-item"> |
||||
|
<p class="color-green">微信消息与事件接收 URL</p> |
||||
|
<label class="relative block"> |
||||
|
<input disabled class="layui-input layui-bg-gray" value="{:url('@service/api.push/notify/\$APPID\$','',false,true)}"> |
||||
|
<a data-copy="{:url('@service/api.push/notify/\$APPID\$','',false,true)}" class="fa fa-copy right-btn"></a> |
||||
|
</label> |
||||
|
<p class="help-block">通过该 URL 接收微信消息和事件推送,$APPID$ 将被替换为微信 AppId</p> |
||||
|
</div> |
||||
|
<div class="layui-form-item"> |
||||
|
<p class="color-green">客户端系统 Yar 模块接口</p> |
||||
|
<label class="relative block"><input disabled class="layui-input layui-bg-gray" value="{:url('@service/api.client/yar/PARAM','',false,true)}"></label> |
||||
|
<p class="help-block">客户端 Yar 接口,PARAM 规则 AppName-AppId-AppKey-AppType</p> |
||||
|
</div> |
||||
|
<div class="layui-form-item"> |
||||
|
<p class="color-green">客户端系统 Soap 模块接口</p> |
||||
|
<label class="relative block"><input disabled class="layui-input layui-bg-gray" value="{:url('@service/api.client/soap/PARAM','',false,true)}"></label> |
||||
|
<p class="help-block">客户端 Soap 接口,PARAM 规则 AppName-AppId-AppKey-AppType</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
</fieldset> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
</div> |
||||
|
{/block} |
||||
|
|
||||
|
{block name='style'} |
||||
|
<style> |
||||
|
.right-btn { |
||||
|
top: 0; |
||||
|
right: 0; |
||||
|
width: 38px; |
||||
|
height: 38px; |
||||
|
display: inline-block; |
||||
|
position: absolute; |
||||
|
text-align: center; |
||||
|
line-height: 38px; |
||||
|
} |
||||
|
</style> |
||||
|
{/block} |
||||
@ -0,0 +1,98 @@ |
|||||
|
{extend name='admin@main'} |
||||
|
|
||||
|
{block name="button"} |
||||
|
|
||||
|
{if auth("service/fans/setblack")} |
||||
|
<button data-action='{:url("setblack")}' data-rule="openid#{key}" data-csrf="{:systoken('service/fans/setblack')}" class='layui-btn layui-btn-sm layui-btn-primary'>批量拉黑</button> |
||||
|
{/if} |
||||
|
|
||||
|
{if auth("service/fans/delblack")} |
||||
|
<button data-action='{:url("delblack")}' data-rule="openid#{key}" data-csrf="{:systoken('service/fans/delblack')}" class='layui-btn layui-btn-sm layui-btn-primary'>取消拉黑</button> |
||||
|
{/if} |
||||
|
|
||||
|
{if auth("service/fans/sync")} |
||||
|
<button data-load='{:url("sync")}' class='layui-btn layui-btn-sm layui-btn-primary'>同步粉丝</button> |
||||
|
{/if} |
||||
|
|
||||
|
{/block} |
||||
|
|
||||
|
{block name="content"} |
||||
|
<div class="think-box-shadow"> |
||||
|
{include file='fans/index_search'} |
||||
|
<table class="layui-table margin-top-10" lay-skin="line"> |
||||
|
{notempty name='list'} |
||||
|
<thead> |
||||
|
<tr> |
||||
|
<th class='list-table-check-td think-checkbox'><input data-auto-none data-check-target='.list-check-box' type='checkbox'></th> |
||||
|
<th width="180px" class='text-left nowrap'>微信昵称</th> |
||||
|
<th width="180px" class="text-left nowrap">粉丝标签</th> |
||||
|
<th width="150px" class='text-left nowrap'>性别语言</th> |
||||
|
<th width="180px" class='text-left nowrap'>关注时间</th> |
||||
|
<th width="80px"></th> |
||||
|
<th></th> |
||||
|
</tr> |
||||
|
</thead> |
||||
|
{/notempty} |
||||
|
<tbody> |
||||
|
{foreach $list as $key=>$vo} |
||||
|
<tr> |
||||
|
<td class='list-table-check-td think-checkbox'> |
||||
|
<input class="list-check-box" value='{$vo.openid}' type='checkbox'> |
||||
|
</td> |
||||
|
<td class='text-left nowrap relative layui-elip'> |
||||
|
<img src="{$vo.headimgurl|default=''}" onerror="$(this).remove()" data-tips-image class="inline-block" style="width:40px;height:40px;vertical-align:top;margin-right:5px"> |
||||
|
<div class="inline-block"> |
||||
|
昵称:{$vo.nickname|default='--'} |
||||
|
<br> |
||||
|
区域:{$vo.country|default='--'} {$vo.province} {$vo.city} |
||||
|
</div> |
||||
|
</td> |
||||
|
<td class="text-left padding-0"> |
||||
|
<div style="max-height:60px;overflow:auto">{foreach $vo.tags as $t}<p><span class="layui-badge layui-bg-cyan margin-right-5">{$t|default='--'}</span></p>{/foreach}</div> |
||||
|
</td> |
||||
|
<td class='text-left nowrap'> |
||||
|
性别:{switch name='vo.sex'}{case value='1'}男{/case}{case value='2'}女{/case}{default}未知{/switch} |
||||
|
<br> |
||||
|
语言:{$vo.language|raw} |
||||
|
</td> |
||||
|
<td class='text-left nowrap'> |
||||
|
日期:{$vo.subscribe_at|format_datetime|str_replace=' ','<br>时间:',###|raw} |
||||
|
</td> |
||||
|
<td class='text-center nowrap'> |
||||
|
{eq name='vo.subscribe' value='0'} |
||||
|
<span class="layui-badge">未关注</span> |
||||
|
{else} |
||||
|
<span class="layui-badge layui-bg-green">已关注</span> |
||||
|
{/eq} |
||||
|
<br> |
||||
|
{eq name='vo.is_black' value='0'} |
||||
|
<span class="layui-badge layui-bg-green">未拉黑</span> |
||||
|
{else} |
||||
|
<span class="layui-badge">已拉黑</span> |
||||
|
{/eq} |
||||
|
</td> |
||||
|
<td class="nowrap"> |
||||
|
|
||||
|
{eq name='vo.is_black' value='0'} |
||||
|
<!--{if auth("service/fans/setblack")}--> |
||||
|
<a class="margin-left-10 layui-btn layui-btn-normal layui-btn-sm" data-action="{:url('setblack')}" data-value="openid#{$vo.openid}" data-csrf="{:systoken('service/fans/setblack')}">拉 黑</a> |
||||
|
<!--{/if}--> |
||||
|
{else} |
||||
|
<!--{if auth("service/fans/delblack")}--> |
||||
|
<a class="margin-left-10 layui-btn layui-btn-normal layui-btn-sm" data-action="{:url('delblack')}" data-value="openid#{$vo.openid}" data-csrf="{:systoken('service/fans/delblack')}">拉 白</a> |
||||
|
<!--{/if}--> |
||||
|
{/eq} |
||||
|
|
||||
|
{if auth("service/fans/remove")} |
||||
|
<a class="layui-btn layui-btn-sm layui-btn-danger" data-confirm="确定要删除该粉丝吗?" data-action="{:url('remove')}" data-value="id#{$vo.id}" data-csrf="{:systoken('service/fans/remove')}">删 除</a> |
||||
|
{/if} |
||||
|
</td> |
||||
|
</tr> |
||||
|
{/foreach} |
||||
|
</tbody> |
||||
|
</table> |
||||
|
|
||||
|
{empty name='list'}<span class="notdata">没有记录哦</span>{else}{$pagehtml|raw|default=''}{/empty} |
||||
|
|
||||
|
</div> |
||||
|
{/block} |
||||
@ -0,0 +1,76 @@ |
|||||
|
<!-- 表单搜索 开始 --> |
||||
|
<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"> |
||||
|
<select class="layui-select" name="appid" lay-search> |
||||
|
<!--{foreach $wechats as $k=>$v}--> |
||||
|
<!--{if $k eq $appid}--> |
||||
|
<option selected value="{$k}">{$v}</option> |
||||
|
<!--{else}--> |
||||
|
<option value="{$k}">{$v}</option> |
||||
|
<!--{/if}--> |
||||
|
<!--{/foreach}--> |
||||
|
</select> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div class="layui-form-item layui-inline"> |
||||
|
<label class="layui-form-label">微信昵称</label> |
||||
|
<div class="layui-input-inline"> |
||||
|
<input name="nickname" value="{$Think.get.nickname|default=''}" 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="subscribe"> |
||||
|
{foreach [''=>'-- 全部 --','0'=>'显示未关注的粉丝','1'=>'显示已关注的粉丝'] as $k=>$v} |
||||
|
{eq name='Think.get.subscribe' value='$k.""'} |
||||
|
<option selected value="{$k}">{$v}</option> |
||||
|
{else} |
||||
|
<option value="{$k}">{$v}</option> |
||||
|
{/eq} |
||||
|
{/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="is_black"> |
||||
|
{foreach [''=>'-- 全部 --','0'=>'显示未拉黑的粉丝','1'=>'显示已拉黑的粉丝'] as $k=>$v} |
||||
|
{eq name='Think.get.is_black' value='$k.""'} |
||||
|
<option selected value="{$k}">{$v}</option> |
||||
|
{else} |
||||
|
<option value="{$k}">{$v}</option> |
||||
|
{/eq} |
||||
|
{/foreach} |
||||
|
</select> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div class="layui-form-item layui-inline"> |
||||
|
<label class="layui-form-label">关注时间</label> |
||||
|
<div class="layui-input-inline"> |
||||
|
<input name="subscribe_at" value="{$Think.get.subscribe_at|default=''}" placeholder="请选择关注时间" class="layui-input"> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div class="layui-form-item layui-inline"> |
||||
|
<button class="layui-btn layui-btn-primary"><i class="layui-icon"></i> 搜 索</button> |
||||
|
</div> |
||||
|
</form> |
||||
|
|
||||
|
</fieldset> |
||||
|
|
||||
|
<script> |
||||
|
window.form.render(); |
||||
|
window.laydate.render({range: true, elem: '[name="subscribe_at"]'}); |
||||
|
</script> |
||||
|
<!-- 表单搜索 结束 --> |
||||
@ -0,0 +1,84 @@ |
|||||
|
{extend name="admin@main"} |
||||
|
|
||||
|
{block name="button"} |
||||
|
|
||||
|
{if auth("service/index/syncall")} |
||||
|
<button data-load="{:url('syncall')}" class='layui-btn layui-btn-sm layui-btn-primary'>同步授权信息</button> |
||||
|
{/if} |
||||
|
|
||||
|
{/block} |
||||
|
|
||||
|
{block name="content"} |
||||
|
<div class="think-box-shadow"> |
||||
|
{include file='index/index_search'} |
||||
|
<table class="layui-table margin-top-10" lay-skin="line"> |
||||
|
{notempty name='list'} |
||||
|
<thead> |
||||
|
<tr> |
||||
|
<th class='text-left nowrap' style="width:390px">接口信息</th> |
||||
|
<th class='text-left nowrap' style="width:120px">服务号信息</th> |
||||
|
<th class='text-left nowrap'></th> |
||||
|
<th class='text-left nowrap'></th> |
||||
|
</tr> |
||||
|
</thead> |
||||
|
{/notempty} |
||||
|
<tbody> |
||||
|
{foreach $list as $key=>$vo} |
||||
|
<tr> |
||||
|
<td class='text-left nowrap'> |
||||
|
<div class="inline-block text-top margin-right-5"> |
||||
|
<img onerror="this.src='__ROOT__/static/theme/img/404_icon.png'" style="width:60px;height:60px" data-tips-text="微信头像" data-tips-image src="{$vo.head_img|default=''}"> |
||||
|
</div> |
||||
|
<div class="inline-block"> |
||||
|
公众号APPID:{$vo.authorizer_appid} 调用次数:{$vo.total}<br> |
||||
|
接口授权密钥:{$vo.appkey|default='<span class="color-desc">未生成接口服务密码, 请稍候授权绑定</span>'|raw}<br> |
||||
|
消息推送接口:{$vo.appuri|default='<span class="color-desc">未配置消息推送接口</span>'|raw} |
||||
|
</div> |
||||
|
</td> |
||||
|
<td class='text-left nowrap'> |
||||
|
<div class="inline-block text-top margin-right-5"> |
||||
|
<img onerror="this.src='__ROOT__/static/theme/img/404_icon.png'" style="width:60px;height:60px" data-tips-text="微信二维码" data-tips-image src="{$vo.qrcode_url|local_image}"> |
||||
|
</div> |
||||
|
<div class="inline-block"> |
||||
|
昵称:{$vo.nick_name|default='<span class="color-desc">未获取到公众号昵称</span>'|raw}<br> |
||||
|
公司:{$vo.principal_name|default='<span class="color-desc">未获取到公司名字</span>'|raw}<br> |
||||
|
状态:{if $vo.service_type eq 2}服务号{elseif $vo.service_type eq 3}小程序{else}订阅号{/if} / |
||||
|
{$vo.verify_type == -1 ? '<span class="color-red">未认证</span>' : '<span class="color-green">已认证</span>'} / |
||||
|
{if $vo.status eq 0}<span class="color-red">已禁用</span>{elseif $vo.status eq 1}<span class="color-green">使用中</span>{/if} |
||||
|
</div> |
||||
|
</td> |
||||
|
<td class="text-left nowrap"> |
||||
|
账号:{$vo.user_name|default='--'}<br> |
||||
|
日期:{$vo.create_at|format_datetime|str_replace=' ','<br>时间:',###|raw} |
||||
|
</td> |
||||
|
<td class='text-left nowrap'> |
||||
|
|
||||
|
{if $vo.status eq 1 and auth("servce/index/forbid")} |
||||
|
<a class="layui-btn layui-btn-sm layui-btn-warm" data-action="{:url('forbid')}" data-csrf="{:systoken('service/index/forbid')}" data-value="id#{$vo.id};status#0">禁 用</a> |
||||
|
{elseif auth("servce/index/resume")} |
||||
|
<a class="layui-btn layui-btn-sm layui-btn-warm" data-action="{:url('resume')}" data-csrf="{:systoken('service/index/resume')}" data-value="id#{$vo.id};status#1">启 用</a> |
||||
|
{/if} |
||||
|
|
||||
|
{if auth("service/index/sync")} |
||||
|
<a class="layui-btn layui-btn-sm" data-load='{:url("service/index/sync")}?appid={$vo.authorizer_appid}'>同 步</a> |
||||
|
{/if} |
||||
|
|
||||
|
{if auth("service/index/remove")} |
||||
|
<a class="layui-btn layui-btn-sm layui-btn-danger" data-confirm="确定要删除该公众号吗?" data-action="{:url('remove')}" data-csrf="{:systoken('service/index/remove')}" data-value="id#{$vo.id}">删 除</a> |
||||
|
{/if} |
||||
|
|
||||
|
{if auth("service/index/clearquota")} |
||||
|
<a class="layui-btn layui-btn-sm layui-btn-primary" data-confirm="每个公众号每个月有10次清零机会,请谨慎使用!" data-load='{:url("service/index/clearquota")}?appid={$vo.authorizer_appid}'>清 零</a> |
||||
|
{/if} |
||||
|
|
||||
|
</td> |
||||
|
</tr> |
||||
|
{/foreach} |
||||
|
</tbody> |
||||
|
</table> |
||||
|
|
||||
|
{empty name='list'}<span class="notdata">没有记录哦</span>{else}{$pagehtml|raw|default=''}{/empty} |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
{/block} |
||||
@ -0,0 +1,77 @@ |
|||||
|
<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="authorizer_appid" value="{$Think.get.authorizer_appid|default=''}" placeholder="请输入微信APPID" class="layui-input"> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div class="layui-form-item layui-inline"> |
||||
|
<label class="layui-form-label">微信名称</label> |
||||
|
<div class="layui-input-inline"> |
||||
|
<input name="nick_name" value="{$Think.get.nick_name|default=''}" 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 name="service_type" class="layui-select"> |
||||
|
<option value="">- 全部 -</option> |
||||
|
{foreach ['0'=>'显示订阅号类型','2'=>'显示服务号类型','3'=>'显示小程序类型'] as $k=>$v} |
||||
|
<!--{if $k.'' eq $Think.get.service_type}--> |
||||
|
<option selected value="{$k}">{$v}</option> |
||||
|
<!--{else}--> |
||||
|
<option value="{$k}">{$v}</option> |
||||
|
<!--{/if}--> |
||||
|
{/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"> |
||||
|
{foreach [''=>'- 全部 -','0'=>'已禁用的账号','1'=>'使用中的账号'] as $k=>$v} |
||||
|
{eq name='Think.get.status' value='$k.""'} |
||||
|
<option selected value="{$k}">{$v}</option> |
||||
|
{else} |
||||
|
<option value="{$k}">{$v}</option> |
||||
|
{/eq} |
||||
|
{/foreach} |
||||
|
</select> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div class="layui-form-item layui-inline"> |
||||
|
<label class="layui-form-label">注册公司</label> |
||||
|
<div class="layui-input-inline"> |
||||
|
<input name="principal_name" value="{$Think.get.principal_name|default=''}" 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 id="create_at" name="create_at" value="{$Think.get.create_at|default=''}" placeholder="请选择授权时间" class="layui-input"> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div class="layui-form-item layui-inline"> |
||||
|
<button class="layui-btn layui-btn-primary"><i class="layui-icon"></i> 搜 索</button> |
||||
|
</div> |
||||
|
|
||||
|
</form> |
||||
|
|
||||
|
</fieldset> |
||||
|
|
||||
|
<script> |
||||
|
window.form.render(); |
||||
|
window.laydate.render({range: true, elem: '#create_at'}); |
||||
|
</script> |
||||
@ -0,0 +1 @@ |
|||||
|
还没有授权,请授权公众号 |
||||
@ -0,0 +1,191 @@ |
|||||
|
<?php |
||||
|
|
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | ThinkAdmin |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 版权所有 2014~2019 广州楚才信息科技有限公司 [ http://www.cuci.cc ] |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 官方网站: http://demo.thinkadmin.top |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 开源协议 ( https://mit-license.org ) |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin |
||||
|
// | github 代码仓库:https://github.com/zoujingli/ThinkAdmin |
||||
|
// +---------------------------------------------------------------------- |
||||
|
|
||||
|
namespace app\store\command; |
||||
|
|
||||
|
use think\Db; |
||||
|
|
||||
|
/** |
||||
|
* 商城数据处理指令 |
||||
|
* Class AutoRun |
||||
|
* @package app\store\command |
||||
|
*/ |
||||
|
class AutoRun extends \think\console\Command |
||||
|
{ |
||||
|
|
||||
|
/** |
||||
|
* 配置指令信息 |
||||
|
*/ |
||||
|
protected function configure() |
||||
|
{ |
||||
|
$this->setName('xclean:store')->setDescription('清理过期无效的订单记录'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 业务指令执行 |
||||
|
* @param \think\console\Input $input |
||||
|
* @param \think\console\Output $output |
||||
|
* @throws \think\Exception |
||||
|
* @throws \think\db\exception\DataNotFoundException |
||||
|
* @throws \think\db\exception\ModelNotFoundException |
||||
|
* @throws \think\exception\DbException |
||||
|
* @throws \think\exception\PDOException |
||||
|
*/ |
||||
|
protected function execute(\think\console\Input $input, \think\console\Output $output) |
||||
|
{ |
||||
|
// 自动取消30分钟未支付的订单 |
||||
|
$this->autoCancelOrder(); |
||||
|
// 清理一天前未支付的订单 |
||||
|
$this->autoRemoveOrder(); |
||||
|
// 订单自动退款处理 |
||||
|
// $this->autoRefundOrder(); |
||||
|
// 提现自动打款处理 |
||||
|
// $this->autoTransfer(); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 自动取消30分钟未支付的订单 |
||||
|
* @throws \think\Exception |
||||
|
* @throws \think\exception\PDOException |
||||
|
*/ |
||||
|
private function autoCancelOrder() |
||||
|
{ |
||||
|
$datetime = $this->getDatetime('store_order_wait_time'); |
||||
|
$where = [['status', 'in', ['1', '2']], ['pay_state', 'eq', '0'], ['create_at', '<', $datetime]]; |
||||
|
$count = Db::name('StoreOrder')->where($where)->update([ |
||||
|
'status' => '0', |
||||
|
'cancel_state' => '1', |
||||
|
'cancel_at' => date('Y-m-d H:i:s'), |
||||
|
'cancel_desc' => '30分钟未完成支付自动取消订单', |
||||
|
]); |
||||
|
if ($count > 0) { |
||||
|
$this->output->info("共计自动取消了30分钟未支付的{$count}笔订单!"); |
||||
|
} else { |
||||
|
$this->output->comment('没有需要自动取消30分钟未支付的订单记录!'); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 清理一天前未支付的订单 |
||||
|
* @throws \think\Exception |
||||
|
* @throws \think\db\exception\DataNotFoundException |
||||
|
* @throws \think\db\exception\ModelNotFoundException |
||||
|
* @throws \think\exception\DbException |
||||
|
* @throws \think\exception\PDOException |
||||
|
*/ |
||||
|
private function autoRemoveOrder() |
||||
|
{ |
||||
|
$datetime = $this->getDatetime('store_order_clear_time'); |
||||
|
$where = [['status', 'eq', '0'], ['pay_state', 'eq', '0'], ['create_at', '<', $datetime]]; |
||||
|
$list = Db::name('StoreOrder')->where($where)->limit(20)->select(); |
||||
|
if (count($orderNos = array_unique(array_column($list, 'order_no'))) > 0) { |
||||
|
$this->output->info("自动删除前一天已经取消的订单:" . PHP_EOL . join(',' . PHP_EOL, $orderNos)); |
||||
|
Db::name('StoreOrder')->whereIn('order_no', $orderNos)->delete(); |
||||
|
Db::name('StoreOrderList')->whereIn('order_no', $orderNos)->delete(); |
||||
|
} else { |
||||
|
$this->output->comment('没有需要自动删除前一天已经取消的订单!'); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 订单自动退款操作 |
||||
|
* @throws \think\Exception |
||||
|
* @throws \think\db\exception\DataNotFoundException |
||||
|
* @throws \think\db\exception\ModelNotFoundException |
||||
|
* @throws \think\exception\DbException |
||||
|
* @throws \think\exception\PDOException |
||||
|
*/ |
||||
|
private function autoRefundOrder() |
||||
|
{ |
||||
|
// 未完成退款的订单,执行微信退款操作 |
||||
|
foreach (Db::name('StoreOrder')->where(['refund_state' => '1'])->select() as $order) { |
||||
|
try { |
||||
|
$this->output->writeln("正在为 {$order['order_no']} 执行退款操作..."); |
||||
|
$result = \We::WePayRefund(config('wechat.wxpay'))->create([ |
||||
|
'transaction_id' => $order['pay_no'], |
||||
|
'out_refund_no' => $order['refund_no'], |
||||
|
'total_fee' => $order['price_total'] * 100, |
||||
|
'refund_fee' => $order['pay_price'] * 100, |
||||
|
'refund_account' => 'REFUND_SOURCE_UNSETTLED_FUNDS', |
||||
|
]); |
||||
|
if ($result['return_code'] === 'SUCCESS' && $result['result_code'] === 'SUCCESS') { |
||||
|
Db::name('StoreOrder')->where(['order_no' => $order['order_no']])->update([ |
||||
|
'refund_state' => '2', 'refund_desc' => '自动退款成功!', |
||||
|
]); |
||||
|
} else { |
||||
|
Db::name('StoreOrder')->where(['order_no' => $order['order_no']])->update([ |
||||
|
'refund_desc' => isset($result['err_code_des']) ? $result['err_code_des'] : '自动退款失败', |
||||
|
]); |
||||
|
} |
||||
|
} catch (\Exception $e) { |
||||
|
$this->output->writeln("订单 {$order['order_no']} 执行退款失败,{$e->getMessage()}!"); |
||||
|
Db::name('StoreOrder')->where(['order_no' => $order['order_no']])->update(['refund_desc' => $e->getMessage()]); |
||||
|
} |
||||
|
} |
||||
|
$this->output->writeln('自动检测退款订单执行完成!'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 自动企业打款操作 |
||||
|
* @throws \think\Exception |
||||
|
* @throws \think\db\exception\DataNotFoundException |
||||
|
* @throws \think\db\exception\ModelNotFoundException |
||||
|
* @throws \think\exception\DbException |
||||
|
* @throws \think\exception\PDOException |
||||
|
*/ |
||||
|
private function autoTransfer() |
||||
|
{ |
||||
|
# 批量企业打款 |
||||
|
foreach (Db::name('StoreProfitUsed')->where(['status' => '1'])->select() as $vo) { |
||||
|
try { |
||||
|
$wechat = \We::WePayTransfers(config('wechat.wxpay')); |
||||
|
$result = $wechat->create([ |
||||
|
'partner_trade_no' => $vo['trs_no'], |
||||
|
'openid' => $vo['openid'], |
||||
|
'check_name' => 'NO_CHECK', |
||||
|
'amount' => $vo['pay_price'] * 100, |
||||
|
'desc' => '营销活动拥金提现', |
||||
|
'spbill_create_ip' => '127.0.0.1', |
||||
|
]); |
||||
|
if ($result['return_code'] === 'SUCCESS' && $result['result_code'] === 'SUCCESS') { |
||||
|
Db::name('StoreProfitUsed')->where(['trs_no' => $vo['trs_no']])->update([ |
||||
|
'status' => '2', 'pay_desc' => '拥金提现成功!', 'pay_no' => $result['payment_no'], 'pay_at' => date('Y-m-d H:i:s'), |
||||
|
]); |
||||
|
} else { |
||||
|
Db::name('StoreProfitUsed')->where(['trs_no' => $vo['trs_no']])->update([ |
||||
|
'pay_desc' => isset($result['err_code_des']) ? $result['err_code_des'] : '自动打款失败', 'last_at' => date('Y-m-d H:i:s'), |
||||
|
]); |
||||
|
} |
||||
|
} catch (\Exception $e) { |
||||
|
$this->output->writeln("订单 {$vo['trs_no']} 执行提现失败,{$e->getMessage()}!"); |
||||
|
Db::name('StoreProfitUsed')->where(['trs_no' => $vo['trs_no']])->update(['pay_desc' => $e->getMessage()]); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 获取配置时间 |
||||
|
* @param string $code |
||||
|
* @return string |
||||
|
* @throws \think\Exception |
||||
|
* @throws \think\exception\PDOException |
||||
|
*/ |
||||
|
private function getDatetime($code) |
||||
|
{ |
||||
|
$minutes = intval(sysconf($code) * 60); |
||||
|
return date('Y-m-d H:i:s', strtotime("-{$minutes} minutes")); |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,61 @@ |
|||||
|
<?php |
||||
|
|
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | ThinkAdmin |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 版权所有 2014~2019 广州楚才信息科技有限公司 [ http://www.cuci.cc ] |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 官方网站: http://demo.thinkadmin.top |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 开源协议 ( https://mit-license.org ) |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin |
||||
|
// | github 代码仓库:https://github.com/zoujingli/ThinkAdmin |
||||
|
// +---------------------------------------------------------------------- |
||||
|
|
||||
|
namespace app\store\controller; |
||||
|
|
||||
|
use app\store\service\Extend; |
||||
|
use app\store\service\ExtendService; |
||||
|
use library\Controller; |
||||
|
|
||||
|
/** |
||||
|
* 商城参数配置 |
||||
|
* Class Config |
||||
|
* @package app\store\controller |
||||
|
*/ |
||||
|
class Config extends Controller |
||||
|
{ |
||||
|
|
||||
|
/** |
||||
|
* 商城参数配置 |
||||
|
* @auth true |
||||
|
* @menu true |
||||
|
* @throws \think\Exception |
||||
|
* @throws \think\exception\PDOException |
||||
|
*/ |
||||
|
public function index() |
||||
|
{ |
||||
|
$this->title = '商城参数配置'; |
||||
|
$this->applyCsrfToken('save'); |
||||
|
$this->query = ExtendService::querySmsBalance(); |
||||
|
$this->query2 = ExtendService::querySmsBalance2(); |
||||
|
$this->fetch(); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 保存商城参数 |
||||
|
* @auth true |
||||
|
* @throws \think\Exception |
||||
|
* @throws \think\exception\PDOException |
||||
|
*/ |
||||
|
public function save() |
||||
|
{ |
||||
|
if ($this->request->isPost()) { |
||||
|
$this->applyCsrfToken('save'); |
||||
|
foreach ($this->request->post() as $k => $v) sysconf($k, $v); |
||||
|
$this->success('商城短信配置保存成功!'); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,112 @@ |
|||||
|
<?php |
||||
|
|
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | ThinkAdmin |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 版权所有 2014~2019 广州楚才信息科技有限公司 [ http://www.cuci.cc ] |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 官方网站: http://demo.thinkadmin.top |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 开源协议 ( https://mit-license.org ) |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin |
||||
|
// | github 代码仓库:https://github.com/zoujingli/ThinkAdmin |
||||
|
// +---------------------------------------------------------------------- |
||||
|
|
||||
|
namespace app\store\controller; |
||||
|
|
||||
|
use library\Controller; |
||||
|
use think\Db; |
||||
|
|
||||
|
/** |
||||
|
* 快递公司管理 |
||||
|
* Class Express |
||||
|
* @package app\store\controller |
||||
|
*/ |
||||
|
class ExpressCompany extends Controller |
||||
|
{ |
||||
|
/** |
||||
|
* 指定数据表 |
||||
|
* @var string |
||||
|
*/ |
||||
|
protected $table = 'StoreExpressCompany'; |
||||
|
|
||||
|
/** |
||||
|
* 快递公司管理 |
||||
|
* @auth true |
||||
|
* @menu true |
||||
|
* @throws \think\Exception |
||||
|
* @throws \think\db\exception\DataNotFoundException |
||||
|
* @throws \think\db\exception\ModelNotFoundException |
||||
|
* @throws \think\exception\DbException |
||||
|
* @throws \think\exception\PDOException |
||||
|
*/ |
||||
|
public function index() |
||||
|
{ |
||||
|
$this->title = '快递公司管理'; |
||||
|
$query = $this->_query($this->table)->equal('status')->like('express_title,express_code'); |
||||
|
$query->dateBetween('create_at')->order('status desc,sort desc,id desc')->page(); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 添加快递公司 |
||||
|
* @auth true |
||||
|
*/ |
||||
|
public function add() |
||||
|
{ |
||||
|
$this->_form($this->table, 'form'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 编辑快递公司 |
||||
|
* @auth true |
||||
|
*/ |
||||
|
public function edit() |
||||
|
{ |
||||
|
$this->_form($this->table, 'form'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 表单数据处理 |
||||
|
* @param array $data |
||||
|
* @auth true |
||||
|
*/ |
||||
|
protected function _form_filter(array $data) |
||||
|
{ |
||||
|
if ($this->request->isPost()) { |
||||
|
$where = [['express_code', 'eq', $data['express_code']], ['is_deleted', 'eq', '0']]; |
||||
|
if (!empty($data['id'])) $where[] = ['id ', 'neq', $data['id']]; |
||||
|
if (Db::name($this->table)->where($where)->count() > 0) { |
||||
|
$this->error('该快递编码已经存在,请使用其它编码!'); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 禁用快递公司 |
||||
|
* @auth true |
||||
|
*/ |
||||
|
public function forbid() |
||||
|
{ |
||||
|
$this->_save($this->table, ['status' => '0']); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 启用快递公司 |
||||
|
* @auth true |
||||
|
*/ |
||||
|
public function resume() |
||||
|
{ |
||||
|
$this->_save($this->table, ['status' => '1']); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 删除快递公司 |
||||
|
* @auth true |
||||
|
*/ |
||||
|
public function remove() |
||||
|
{ |
||||
|
$this->_delete($this->table); |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,85 @@ |
|||||
|
<?php |
||||
|
|
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | ThinkAdmin |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 版权所有 2014~2019 广州楚才信息科技有限公司 [ http://www.cuci.cc ] |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 官方网站: http://demo.thinkadmin.top |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 开源协议 ( https://mit-license.org ) |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin |
||||
|
// | github 代码仓库:https://github.com/zoujingli/ThinkAdmin |
||||
|
// +---------------------------------------------------------------------- |
||||
|
|
||||
|
namespace app\store\controller; |
||||
|
|
||||
|
use library\Controller; |
||||
|
use think\Db; |
||||
|
|
||||
|
/** |
||||
|
* 邮费模板管理 |
||||
|
* Class ExpressTemplate |
||||
|
* @package app\store\controller |
||||
|
*/ |
||||
|
class ExpressTemplate extends Controller |
||||
|
{ |
||||
|
/** |
||||
|
* 指定数据表 |
||||
|
* @var string |
||||
|
*/ |
||||
|
protected $table = 'StoreExpressTemplate'; |
||||
|
|
||||
|
/** |
||||
|
* 邮费模板管理 |
||||
|
* @auth true |
||||
|
* @menu true |
||||
|
* @throws \think\db\exception\DataNotFoundException |
||||
|
* @throws \think\db\exception\ModelNotFoundException |
||||
|
* @throws \think\exception\DbException |
||||
|
*/ |
||||
|
public function index() |
||||
|
{ |
||||
|
$this->title = '邮费模板管理'; |
||||
|
$filename = env('root_path') . 'public/static/plugs/jquery/area/area.json'; |
||||
|
$this->provinces = array_column(json_decode(file_get_contents($filename), true), 'name'); |
||||
|
$this->list = Db::name($this->table)->where(['is_default' => '0'])->select(); |
||||
|
foreach ($this->list as &$item) $item['rule'] = explode(',', $item['rule']); |
||||
|
$this->default = Db::name($this->table)->where(['is_default' => '1'])->find(); |
||||
|
$this->fetch(); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 保存邮费模板 |
||||
|
* @auth true |
||||
|
* @throws \think\Exception |
||||
|
* @throws \think\exception\PDOException |
||||
|
*/ |
||||
|
public function save() |
||||
|
{ |
||||
|
list($list, $idxs, $post) = [[], [], $this->request->post()]; |
||||
|
foreach (array_keys($post) as $key) if (stripos($key, 'order_reduction_state_') !== false) { |
||||
|
$idxs[] = str_replace('order_reduction_state_', '', $key); |
||||
|
} |
||||
|
foreach (array_unique($idxs) as $index) if (!empty($post["rule_{$index}"])) $list[] = [ |
||||
|
'rule' => join(',', $post["rule_{$index}"]), |
||||
|
// 订单满减配置 |
||||
|
'order_reduction_state' => $post["order_reduction_state_{$index}"], |
||||
|
'order_reduction_price' => $post["order_reduction_price_{$index}"], |
||||
|
// 首件邮费配置 |
||||
|
'first_number' => $post["first_number_{$index}"], |
||||
|
'first_price' => $post["first_price_{$index}"], |
||||
|
// 首件邮费配置 |
||||
|
'next_number' => $post["next_number_{$index}"], |
||||
|
'next_price' => $post["next_price_{$index}"], |
||||
|
// 默认邮费规则 |
||||
|
'is_default' => $post["is_default_{$index}"], |
||||
|
]; |
||||
|
if (empty($list)) $this->error('请配置有效的邮费规则'); |
||||
|
Db::name($this->table)->where('1=1')->delete(); |
||||
|
Db::name($this->table)->insertAll($list); |
||||
|
$this->success('邮费规则配置成功!'); |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,197 @@ |
|||||
|
<?php |
||||
|
|
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | ThinkAdmin |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 版权所有 2014~2019 广州楚才信息科技有限公司 [ http://www.cuci.cc ] |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 官方网站: http://demo.thinkadmin.top |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 开源协议 ( https://mit-license.org ) |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin |
||||
|
// | github 代码仓库:https://github.com/zoujingli/ThinkAdmin |
||||
|
// +---------------------------------------------------------------------- |
||||
|
|
||||
|
namespace app\store\controller; |
||||
|
|
||||
|
use library\Controller; |
||||
|
use library\tools\Data; |
||||
|
use think\Db; |
||||
|
|
||||
|
/** |
||||
|
* 商品信息管理 |
||||
|
* Class Goods |
||||
|
* @package app\store\controller |
||||
|
*/ |
||||
|
class Goods extends Controller |
||||
|
{ |
||||
|
/** |
||||
|
* 指定数据表 |
||||
|
* @var string |
||||
|
*/ |
||||
|
protected $table = 'StoreGoods'; |
||||
|
|
||||
|
/** |
||||
|
* 商品信息管理 |
||||
|
* @auth true |
||||
|
* @menu true |
||||
|
* @throws \think\Exception |
||||
|
* @throws \think\db\exception\DataNotFoundException |
||||
|
* @throws \think\db\exception\ModelNotFoundException |
||||
|
* @throws \think\exception\DbException |
||||
|
* @throws \think\exception\PDOException |
||||
|
*/ |
||||
|
public function index() |
||||
|
{ |
||||
|
$this->title = '商品信息管理'; |
||||
|
$query = $this->_query($this->table)->equal('status,cate_id')->like('title'); |
||||
|
$query->where(['is_deleted' => '0'])->order('sort desc,id desc')->page(); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 数据列表处理 |
||||
|
* @param array $data |
||||
|
* @throws \think\db\exception\DataNotFoundException |
||||
|
* @throws \think\db\exception\ModelNotFoundException |
||||
|
* @throws \think\exception\DbException |
||||
|
*/ |
||||
|
protected function _index_page_filter(&$data) |
||||
|
{ |
||||
|
$this->clist = Db::name('StoreGoodsCate')->where(['is_deleted' => '0', 'status' => '1'])->select(); |
||||
|
$list = Db::name('StoreGoodsList')->where('status', '1')->whereIn('goods_id', array_unique(array_column($data, 'id')))->select(); |
||||
|
foreach ($data as &$vo) { |
||||
|
list($vo['list'], $vo['cate']) = [[], []]; |
||||
|
foreach ($list as $goods) if ($goods['goods_id'] === $vo['id']) array_push($vo['list'], $goods); |
||||
|
foreach ($this->clist as $cate) if ($cate['id'] === $vo['cate_id']) $vo['cate'] = $cate; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 商品库存入库 |
||||
|
* @auth true |
||||
|
* @throws \think\Exception |
||||
|
* @throws \think\db\exception\DataNotFoundException |
||||
|
* @throws \think\db\exception\ModelNotFoundException |
||||
|
* @throws \think\exception\DbException |
||||
|
* @throws \think\exception\PDOException |
||||
|
*/ |
||||
|
public function stock() |
||||
|
{ |
||||
|
if ($this->request->isGet()) { |
||||
|
$GoodsId = $this->request->get('id'); |
||||
|
$goods = Db::name('StoreGoods')->where(['id' => $GoodsId])->find(); |
||||
|
empty($goods) && $this->error('无效的商品信息,请稍候再试!'); |
||||
|
$goods['list'] = Db::name('StoreGoodsList')->where(['goods_id' => $GoodsId])->select(); |
||||
|
$this->fetch('', ['vo' => $goods]); |
||||
|
} else { |
||||
|
list($post, $data) = [$this->request->post(), []]; |
||||
|
if (isset($post['id']) && isset($post['goods_id']) && is_array($post['goods_id'])) { |
||||
|
foreach (array_keys($post['goods_id']) as $key) if ($post['goods_number'][$key] > 0) array_push($data, [ |
||||
|
'goods_id' => $post['goods_id'][$key], |
||||
|
'goods_spec' => $post['goods_spec'][$key], |
||||
|
'number_stock' => $post['goods_number'][$key], |
||||
|
]); |
||||
|
if (!empty($data)) { |
||||
|
Db::name('StoreGoodsStock')->insertAll($data); |
||||
|
\app\store\service\GoodsService::syncStock($post['id']); |
||||
|
$this->success('商品信息入库成功!'); |
||||
|
} |
||||
|
} |
||||
|
$this->error('没有需要商品入库的数据!'); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 添加商品信息 |
||||
|
* @auth true |
||||
|
*/ |
||||
|
public function add() |
||||
|
{ |
||||
|
$this->title = '添加商品信息'; |
||||
|
$this->isAddMode = '1'; |
||||
|
$this->_form($this->table, 'form'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 编辑商品信息 |
||||
|
* @auth true |
||||
|
*/ |
||||
|
public function edit() |
||||
|
{ |
||||
|
$this->title = '编辑商品信息'; |
||||
|
$this->isAddMode = '0'; |
||||
|
$this->_form($this->table, 'form'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 表单数据处理 |
||||
|
* @param array $data |
||||
|
* @throws \think\Exception |
||||
|
* @throws \think\db\exception\DataNotFoundException |
||||
|
* @throws \think\db\exception\ModelNotFoundException |
||||
|
* @throws \think\exception\DbException |
||||
|
* @throws \think\exception\PDOException |
||||
|
*/ |
||||
|
protected function _form_filter(&$data) |
||||
|
{ |
||||
|
// 生成商品ID |
||||
|
if (empty($data['id'])) $data['id'] = Data::uniqidNumberCode(10); |
||||
|
if ($this->request->isGet()) { |
||||
|
$fields = 'goods_spec,goods_id,status,price_market market,price_selling selling,number_virtual `virtual`,number_express express'; |
||||
|
$defaultValues = Db::name('StoreGoodsList')->where(['goods_id' => $data['id']])->column($fields); |
||||
|
$this->defaultValues = json_encode($defaultValues, JSON_UNESCAPED_UNICODE); |
||||
|
$this->cates = Db::name('StoreGoodsCate')->where(['is_deleted' => '0', 'status' => '1'])->order('sort desc,id desc')->select(); |
||||
|
} elseif ($this->request->isPost()) { |
||||
|
Db::name('StoreGoodsList')->where(['goods_id' => $data['id']])->update(['status' => '0']); |
||||
|
foreach (json_decode($data['lists'], true) as $vo) Data::save('StoreGoodsList', [ |
||||
|
'goods_id' => $data['id'], |
||||
|
'goods_spec' => $vo[0]['key'], |
||||
|
'price_market' => $vo[0]['market'], |
||||
|
'price_selling' => $vo[0]['selling'], |
||||
|
'number_virtual' => $vo[0]['virtual'], |
||||
|
'number_express' => $vo[0]['express'], |
||||
|
'status' => $vo[0]['status'] ? 1 : 0, |
||||
|
], 'goods_spec', ['goods_id' => $data['id']]); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 表单结果处理 |
||||
|
* @param boolean $result |
||||
|
*/ |
||||
|
protected function _form_result($result) |
||||
|
{ |
||||
|
if ($result && $this->request->isPost()) { |
||||
|
$this->success('商品编辑成功!', 'javascript:history.back()'); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 禁用商品信息 |
||||
|
* @auth true |
||||
|
*/ |
||||
|
public function forbid() |
||||
|
{ |
||||
|
$this->_save($this->table, ['status' => '0']); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 启用商品信息 |
||||
|
* @auth true |
||||
|
*/ |
||||
|
public function resume() |
||||
|
{ |
||||
|
$this->_save($this->table, ['status' => '1']); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 删除商品信息 |
||||
|
* @auth true |
||||
|
*/ |
||||
|
public function remove() |
||||
|
{ |
||||
|
$this->_delete($this->table); |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,97 @@ |
|||||
|
<?php |
||||
|
|
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | ThinkAdmin |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 版权所有 2014~2019 广州楚才信息科技有限公司 [ http://www.cuci.cc ] |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 官方网站: http://demo.thinkadmin.top |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 开源协议 ( https://mit-license.org ) |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin |
||||
|
// | github 代码仓库:https://github.com/zoujingli/ThinkAdmin |
||||
|
// +---------------------------------------------------------------------- |
||||
|
|
||||
|
namespace app\store\controller; |
||||
|
|
||||
|
use library\Controller; |
||||
|
|
||||
|
/** |
||||
|
* 商品分类管理 |
||||
|
* Class GoodsCate |
||||
|
* @package app\store\controller |
||||
|
*/ |
||||
|
class GoodsCate extends Controller |
||||
|
{ |
||||
|
/** |
||||
|
* 绑定数据表 |
||||
|
* @var string |
||||
|
*/ |
||||
|
protected $table = 'StoreGoodsCate'; |
||||
|
|
||||
|
/** |
||||
|
* 商品分类管理 |
||||
|
* @auth true |
||||
|
* @menu true |
||||
|
* @throws \think\Exception |
||||
|
* @throws \think\db\exception\DataNotFoundException |
||||
|
* @throws \think\db\exception\ModelNotFoundException |
||||
|
* @throws \think\exception\DbException |
||||
|
* @throws \think\exception\PDOException |
||||
|
*/ |
||||
|
public function index() |
||||
|
{ |
||||
|
$this->title = '商品分类管理'; |
||||
|
$query = $this->_query($this->table)->like('title')->equal('status'); |
||||
|
$query->where(['is_deleted' => '0'])->order('sort desc,id desc')->page(); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 添加商品分类 |
||||
|
* @auth true |
||||
|
*/ |
||||
|
public function add() |
||||
|
{ |
||||
|
$this->title = '添加商品分类'; |
||||
|
$this->_form($this->table, 'form'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 编辑商品分类 |
||||
|
* @auth true |
||||
|
*/ |
||||
|
public function edit() |
||||
|
{ |
||||
|
$this->title = '编辑商品分类'; |
||||
|
$this->_form($this->table, 'form'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 禁用商品分类 |
||||
|
* @auth true |
||||
|
*/ |
||||
|
public function forbid() |
||||
|
{ |
||||
|
$this->_save($this->table, ['status' => '0']); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 启用商品分类 |
||||
|
* @auth true |
||||
|
*/ |
||||
|
public function resume() |
||||
|
{ |
||||
|
$this->_save($this->table, ['status' => '1']); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 删除商品分类 |
||||
|
* @auth true |
||||
|
*/ |
||||
|
public function remove() |
||||
|
{ |
||||
|
$this->_delete($this->table); |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,50 @@ |
|||||
|
<?php |
||||
|
|
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | ThinkAdmin |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 版权所有 2014~2019 广州楚才信息科技有限公司 [ http://www.cuci.cc ] |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 官方网站: http://demo.thinkadmin.top |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 开源协议 ( https://mit-license.org ) |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin |
||||
|
// | github 代码仓库:https://github.com/zoujingli/ThinkAdmin |
||||
|
// +---------------------------------------------------------------------- |
||||
|
|
||||
|
namespace app\store\controller; |
||||
|
|
||||
|
use library\Controller; |
||||
|
|
||||
|
/** |
||||
|
* 会员信息管理 |
||||
|
* Class Member |
||||
|
* @package app\store\controller |
||||
|
*/ |
||||
|
class Member extends Controller |
||||
|
{ |
||||
|
/** |
||||
|
* 绑定数据表 |
||||
|
* @var string |
||||
|
*/ |
||||
|
protected $table = 'StoreMember'; |
||||
|
|
||||
|
/** |
||||
|
* 会员信息管理 |
||||
|
* @auth true |
||||
|
* @menu true |
||||
|
* @throws \think\Exception |
||||
|
* @throws \think\db\exception\DataNotFoundException |
||||
|
* @throws \think\db\exception\ModelNotFoundException |
||||
|
* @throws \think\exception\DbException |
||||
|
* @throws \think\exception\PDOException |
||||
|
*/ |
||||
|
public function index() |
||||
|
{ |
||||
|
$this->title = '会员信息管理'; |
||||
|
$query = $this->_query($this->table)->like('nickname,phone')->equal('vip_level'); |
||||
|
$query->dateBetween('create_at')->order('id desc')->page(); |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,61 @@ |
|||||
|
<?php |
||||
|
|
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | ThinkAdmin |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 版权所有 2014~2019 广州楚才信息科技有限公司 [ http://www.cuci.cc ] |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 官方网站: http://demo.thinkadmin.top |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 开源协议 ( https://mit-license.org ) |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin |
||||
|
// | github 代码仓库:https://github.com/zoujingli/ThinkAdmin |
||||
|
// +---------------------------------------------------------------------- |
||||
|
|
||||
|
namespace app\store\controller; |
||||
|
|
||||
|
use library\Controller; |
||||
|
|
||||
|
/** |
||||
|
* 短信发送管理 |
||||
|
* Class Message |
||||
|
* @package app\store\controller |
||||
|
*/ |
||||
|
class Message extends Controller |
||||
|
{ |
||||
|
/** |
||||
|
* 绑定数据表 |
||||
|
* @var string |
||||
|
*/ |
||||
|
protected $table = 'StoreMemberSmsHistory'; |
||||
|
|
||||
|
/** |
||||
|
* 短信发送管理 |
||||
|
* @auth true |
||||
|
* @menu true |
||||
|
* @throws \think\Exception |
||||
|
* @throws \think\db\exception\DataNotFoundException |
||||
|
* @throws \think\db\exception\ModelNotFoundException |
||||
|
* @throws \think\exception\DbException |
||||
|
* @throws \think\exception\PDOException |
||||
|
*/ |
||||
|
public function index() |
||||
|
{ |
||||
|
$this->title = '短信发送管理'; |
||||
|
$query = $this->_query($this->table)->like('phone,content,result'); |
||||
|
$query->dateBetween('create_at')->order('id desc')->page(); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 删除短信记录 |
||||
|
* @auth true |
||||
|
* @throws \think\Exception |
||||
|
* @throws \think\exception\PDOException |
||||
|
*/ |
||||
|
public function remove() |
||||
|
{ |
||||
|
$this->_delete($this->table); |
||||
|
} |
||||
|
|
||||
|
} |
||||
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue