Merge pull request #1 from zoujingli/master

get new
This commit is contained in:
Chen,Yongze 2019-03-18 07:51:04 +08:00 committed by GitHub
commit e1dbdf6120
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1693 changed files with 111849 additions and 173730 deletions

8
.gitignore vendored
View File

@ -1,9 +1,11 @@
!.gitignore
!.gitattributes
/.idea
/.svn
*.DS_Store
*.idea
*.svn
*.git
/runtime
/nbproject
!composer.json
/composer.lock
/public/upload
/static/upload

View File

@ -1,6 +1,7 @@
<IfModule mod_rewrite.c>
Options +FollowSymlinks -Multiviews
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php/$1 [QSA,PT,L]

View File

@ -1,34 +1,59 @@
Think.Admin
---
ThinkAdmin for PHP
--
## 大道至简 · 悟在天成
`Think.Admin`是一个基于`Thinkphp5`开发的后台管理系统,集成后台系统常用功能。
* ThinkAdmin 是一个基于 Thinkphp 5.1.x 开发的后台管理系统,集成后台系统常用功能。
* 项目安装及二次开发请参考 ThinkPHP 官方文档及下面的服务环境说明,数据库 sql 文件存放于项目根目录下。
>* 注意:项目测试请另行搭建环境并创建数据库(数据库配置 config/database.php, 切勿直接使用测试环境数据!
>* 如果系统提示“测试系统禁止操作等字样”可以删除项目演示路由配置route/demo.php或清空里面的路由记录。
>* 当前版本使用 ThinkPHP 5.1.x 版本对PHP版本要求不低于php5.6具体请查阅ThinkPHP官方文档。
项目安装请参考`ThinkPHP`官方文档及下面的服务环境说明,数据库`sql`文件存放于项目根目录下。
注意:项目测试请另行搭建环境并创建数据库(数据库配置`application/database.php`, 切勿直接使用测试环境数据!
Documentation
--
认真看看文档可能会对你的开发有所帮助哦!
`Think.Admin``微信开发`技术交流QQ群
[![QQ群](http://pub.idqqimg.com/wpa/images/group.png "QQ群")](http://shang.qq.com/wpa/qunwpa?idkey=ae25cf789dafbef62e50a980ffc31242f150bc61a61164458216dd98c411832a)
文档地址:[ThinkAdmin 开发文档](https://www.kancloud.cn/zoujingli/thinkadmin/content)
**`Think.Admin`开发手册 ( 撰写中 )** : http://doc.think.ctolog.com
`Think.Admin`已集成模块
---
PHP开发技术交流QQ群 513350915
[![PHP微信开发群 (SDK)](http://pub.idqqimg.com/wpa/images/group.png)](http://shang.qq.com/wpa/qunwpa?idkey=ae25cf789dafbef62e50a980ffc31242f150bc61a61164458216dd98c411832a)
Repositorie
--
ThinkAdmin 为开源项目,允许把它用于任何地方,不受任何约束,欢迎 fork 项目。
* Gitee 托管地址https://gitee.com/zoujingli/Think.Admin
* GitHub 托管地址https://github.com/zoujingli/ThinkAdmin
对于新版本的微信模块使用的是授权模式,需要用到 ThinkService 项目。
* Gitee 托管地址https://gitee.com/zoujingli/ThinkService
* GitHub 托管地址https://github.com/zoujingli/ThinkService
其安装与 ThinkAdmin 相似,这里就不多说了。具体可以参见微信开放平台官网
https://open.weixin.qq.com ThinkService 后台具体可以配置对应参数。
ThinkAdmin 与 ThinkService 对接是通过 WebService 通信的,因此运行环境需要安装 Soap 模块支持。
Module
--
* 简易`RBAC`权限管理(用户、权限、节点、菜单控制)
* 自建秒传文件上载组件本地存储、七牛云存储阿里云OSS存储
* 基站数据服务组件(唯一随机序号、表单更新)
* `Http`服务组件(原生`CURL`封装兼容PHP多版本
* 微信公众号服务组件(基于[wechat-php-sdk](https://github.com/zoujingli/wechat-php-sdk),微信网页授权获取用户信息、已关注粉丝管理、自定义菜单管理等等)
* 微信商户支付服务组件(基于[wechat-php-sdk](https://github.com/zoujingli/wechat-php-sdk)支持JSAPI支付、扫码模式一支付、扫码模式二支付
* 测试公众号名称:思过崖思过 (大家可以关注它来进行简单的测试)
* 微信公众号服务组件(基于[WeChatDeveloper](https://github.com/zoujingli/WeChatDeveloper),微信网页授权获取用户信息、已关注粉丝管理、自定义菜单管理等等)
* 微信商户支付服务组件(基于[WeChatDeveloper](https://github.com/zoujingli/WeChatDeveloper)支持JSAPI支付、扫码模式一支付、扫码模式二支付
* 更多组件开发中...
服务器环境
Environment
---
* `PHP`版本不低于`PHP5.4`,推荐使用`PHP7`以达到最优效果
* 项目运行需支持`PATHINFO`,项目不支持`ThinkPHP``URL`兼容模式运行(源于如何优雅的展示)
* `Apache`:已在项目根目录加入`.htaccess`文件,只需开启`rewrite`模块
>1. PHP 版本不低于 PHP5.6,推荐使用 PHP7 以达到最优效果;
>2. 需开启 PATHINFO不再支持 ThinkPHP 的 URL 兼容模式运行(源于如何优雅的展示)。
* Apache
```xml
<IfModule mod_rewrite.c>
@ -40,13 +65,13 @@ Think.Admin
</IfModule>
```
* `Nginx`:配置参考下面的`demo`代码
* Nginx
```
server {
listen 80;
server_name wealth.demo.cuci.cc;
root /home/wwwroot/Think.Admin;
root /home/wwwroot/ThinkAdmin;
index index.php index.html index.htm;
add_header X-Powered-Host $hostname;
@ -87,3 +112,13 @@ server {
}
}
```
Copyright
--
* ThinkAdmin 基于`MIT`协议发布,任何人可以用在任何地方,不受约束
* ThinkAdmin 部分代码来自互联网,若有异议,可以联系作者进行删除
Sponsor
--
![赞助](http://zoujingli.oschina.io/static/pay.png)

View File

@ -1,13 +0,0 @@
:: Composer 安装更新脚本
@echo off
title Composer Plugs Install And Optimize
echo.
echo ========= 1. 清理已安装插件 =========
rmdir /s/q vendor thinkphp runtime
echo.
echo ========= 2. 下载并安装插件 =========
composer update --profile --prefer-dist --optimize-autoloader
echo.
echo ========= 3. 压缩并发布插件 =========
composer dump-autoload --optimize
exit

947
admin_v3.sql Normal file
View File

@ -0,0 +1,947 @@
/*
Navicat MySQL Data Transfer
Source Server : server.cuci.cc
Source Server Version : 50558
Source Host : server.cuci.cc:3306
Source Database : admin_v3
Target Server Type : MYSQL
Target Server Version : 50558
File Encoding : 65001
Date: 2018-05-04 11:40:19
*/
SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for store_express
-- ----------------------------
DROP TABLE IF EXISTS `store_express`;
CREATE TABLE `store_express` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`express_title` varchar(50) DEFAULT '' COMMENT '快递公司名称',
`express_code` varchar(50) DEFAULT '' COMMENT '快递公司代码',
`express_desc` text COMMENT '快递公司描述',
`status` tinyint(1) unsigned DEFAULT '1' COMMENT '状态(0.无效,1.有效)',
`sort` bigint(20) unsigned DEFAULT '0' COMMENT '排序',
`is_deleted` tinyint(1) unsigned DEFAULT '0' COMMENT '删除状态(1删除,0未删除)',
`create_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=95 DEFAULT CHARSET=utf8 COMMENT='商城快递配置';
-- ----------------------------
-- Records of store_express
-- ----------------------------
INSERT INTO `store_express` VALUES ('5', 'AAE全球专递', 'aae', '顺丰快递公司', '0', '0', '0', '2017-09-12 11:53:40');
INSERT INTO `store_express` VALUES ('6', '安捷快递', 'anjie', '', '0', '0', '0', '2017-09-13 15:27:26');
INSERT INTO `store_express` VALUES ('7', '安信达快递', 'anxindakuaixi', null, '0', '0', '0', '2017-09-13 16:05:19');
INSERT INTO `store_express` VALUES ('8', '彪记快递', 'biaojikuaidi', null, '0', '0', '0', '2017-09-13 16:05:26');
INSERT INTO `store_express` VALUES ('9', 'BHT', 'bht', '', '0', '0', '0', '2017-09-13 16:05:37');
INSERT INTO `store_express` VALUES ('10', '百福东方国际物流', 'baifudongfang', null, '0', '0', '0', '2017-09-13 16:05:41');
INSERT INTO `store_express` VALUES ('11', '中国东方COE', 'coe', null, '0', '0', '0', '2017-09-13 16:05:48');
INSERT INTO `store_express` VALUES ('12', '长宇物流', 'changyuwuliu', null, '0', '0', '0', '2017-09-13 16:05:58');
INSERT INTO `store_express` VALUES ('13', '大田物流', 'datianwuliu', null, '0', '0', '0', '2017-09-13 16:06:06');
INSERT INTO `store_express` VALUES ('14', '德邦物流', 'debangwuliu', null, '1', '1', '0', '2017-09-13 16:06:14');
INSERT INTO `store_express` VALUES ('15', 'DHL', 'dhl', null, '0', '0', '0', '2017-09-13 16:06:24');
INSERT INTO `store_express` VALUES ('16', 'DPEX', 'dpex', null, '0', '0', '0', '2017-09-13 16:06:29');
INSERT INTO `store_express` VALUES ('17', 'd速快递', 'dsukuaidi', null, '0', '0', '0', '2017-09-13 16:06:34');
INSERT INTO `store_express` VALUES ('18', '递四方', 'disifang', null, '0', '0', '0', '2017-09-13 16:06:40');
INSERT INTO `store_express` VALUES ('19', 'EMS快递', 'ems', '', '1', '0', '0', '2017-09-13 16:06:47');
INSERT INTO `store_express` VALUES ('20', 'FEDEX国外', 'fedex', null, '0', '0', '0', '2017-09-13 16:06:56');
INSERT INTO `store_express` VALUES ('21', '飞康达物流', 'feikangda', null, '0', '0', '0', '2017-09-13 16:07:03');
INSERT INTO `store_express` VALUES ('22', '凤凰快递', 'fenghuangkuaidi', null, '0', '0', '0', '2017-09-13 16:07:10');
INSERT INTO `store_express` VALUES ('23', '飞快达', 'feikuaida', null, '0', '0', '0', '2017-09-13 16:07:16');
INSERT INTO `store_express` VALUES ('24', '国通快递', 'guotongkuaidi', null, '0', '0', '0', '2017-09-13 16:07:27');
INSERT INTO `store_express` VALUES ('25', '港中能达物流', 'ganzhongnengda', null, '0', '0', '0', '2017-09-13 16:07:33');
INSERT INTO `store_express` VALUES ('26', '广东邮政物流', 'guangdongyouzhengwuliu', null, '0', '0', '0', '2017-09-13 16:08:22');
INSERT INTO `store_express` VALUES ('27', '共速达', 'gongsuda', null, '0', '0', '0', '2017-09-13 16:08:48');
INSERT INTO `store_express` VALUES ('28', '汇通快运', 'huitongkuaidi', null, '0', '0', '0', '2017-09-13 16:08:56');
INSERT INTO `store_express` VALUES ('29', '恒路物流', 'hengluwuliu', null, '0', '0', '0', '2017-09-13 16:09:02');
INSERT INTO `store_express` VALUES ('30', '华夏龙物流', 'huaxialongwuliu', null, '0', '0', '0', '2017-09-13 16:09:12');
INSERT INTO `store_express` VALUES ('31', '海红', 'haihongwangsong', null, '0', '0', '0', '2017-09-13 16:09:20');
INSERT INTO `store_express` VALUES ('32', '海外环球', 'haiwaihuanqiu', null, '0', '0', '0', '2017-09-13 16:09:27');
INSERT INTO `store_express` VALUES ('33', '佳怡物流', 'jiayiwuliu', null, '0', '0', '0', '2017-09-13 16:09:35');
INSERT INTO `store_express` VALUES ('34', '京广速递', 'jinguangsudikuaijian', null, '0', '0', '0', '2017-09-13 16:09:42');
INSERT INTO `store_express` VALUES ('35', '急先达', 'jixianda', null, '0', '0', '0', '2017-09-13 16:09:49');
INSERT INTO `store_express` VALUES ('36', '佳吉物流', 'jjwl', null, '0', '0', '0', '2017-09-13 16:10:01');
INSERT INTO `store_express` VALUES ('37', '加运美物流', 'jymwl', null, '0', '0', '0', '2017-09-13 16:10:13');
INSERT INTO `store_express` VALUES ('38', '金大物流', 'jindawuliu', null, '0', '0', '0', '2017-09-13 16:10:22');
INSERT INTO `store_express` VALUES ('39', '嘉里大通', 'jialidatong', null, '0', '0', '0', '2017-09-13 16:10:33');
INSERT INTO `store_express` VALUES ('40', '晋越快递', 'jykd', null, '0', '0', '0', '2017-09-13 16:10:40');
INSERT INTO `store_express` VALUES ('41', '快捷速递', 'kuaijiesudi', null, '0', '0', '0', '2017-09-13 16:10:49');
INSERT INTO `store_express` VALUES ('42', '联邦快递(国内)', 'lianb', null, '0', '0', '0', '2017-09-13 16:10:58');
INSERT INTO `store_express` VALUES ('43', '联昊通物流', 'lianhaowuliu', null, '0', '0', '0', '2017-09-13 16:11:07');
INSERT INTO `store_express` VALUES ('44', '龙邦物流', 'longbanwuliu', null, '0', '0', '0', '2017-09-13 16:11:15');
INSERT INTO `store_express` VALUES ('45', '立即送', 'lijisong', null, '0', '0', '0', '2017-09-13 16:11:25');
INSERT INTO `store_express` VALUES ('46', '乐捷递', 'lejiedi', null, '0', '0', '0', '2017-09-13 16:11:36');
INSERT INTO `store_express` VALUES ('47', '民航快递', 'minghangkuaidi', null, '0', '0', '0', '2017-09-13 16:11:45');
INSERT INTO `store_express` VALUES ('48', '美国快递', 'meiguokuaidi', null, '0', '0', '0', '2017-09-13 16:11:53');
INSERT INTO `store_express` VALUES ('49', '门对门', 'menduimen', null, '0', '0', '0', '2017-09-13 16:12:01');
INSERT INTO `store_express` VALUES ('50', 'OCS', 'ocs', null, '0', '0', '0', '2017-09-13 16:12:10');
INSERT INTO `store_express` VALUES ('51', '配思货运', 'peisihuoyunkuaidi', null, '0', '0', '0', '2017-09-13 16:12:18');
INSERT INTO `store_express` VALUES ('52', '全晨快递', 'quanchenkuaidi', null, '0', '0', '0', '2017-09-13 16:12:26');
INSERT INTO `store_express` VALUES ('53', '全峰快递', 'quanfengkuaidi', null, '0', '0', '0', '2017-09-13 16:12:34');
INSERT INTO `store_express` VALUES ('54', '全际通物流', 'quanjitong', null, '0', '0', '0', '2017-09-13 16:12:41');
INSERT INTO `store_express` VALUES ('55', '全日通快递', 'quanritongkuaidi', null, '0', '0', '0', '2017-09-13 16:12:49');
INSERT INTO `store_express` VALUES ('56', '全一快递', 'quanyikuaidi', null, '0', '0', '0', '2017-09-13 16:12:56');
INSERT INTO `store_express` VALUES ('57', '如风达', 'rufengda', null, '0', '0', '0', '2017-09-13 16:13:03');
INSERT INTO `store_express` VALUES ('58', '三态速递', 'santaisudi', null, '0', '0', '0', '2017-09-13 16:13:15');
INSERT INTO `store_express` VALUES ('59', '盛辉物流', 'shenghuiwuliu', null, '0', '0', '0', '2017-09-13 16:13:22');
INSERT INTO `store_express` VALUES ('60', '申通', 'shentong', null, '0', '0', '0', '2017-09-13 16:13:34');
INSERT INTO `store_express` VALUES ('61', '顺丰', 'shunfeng', '', '1', '0', '0', '2017-09-13 16:13:41');
INSERT INTO `store_express` VALUES ('62', '速尔物流', 'sue', null, '0', '0', '0', '2017-09-13 16:13:48');
INSERT INTO `store_express` VALUES ('63', '盛丰物流', 'shengfeng', null, '0', '0', '0', '2017-09-13 16:13:55');
INSERT INTO `store_express` VALUES ('64', '赛澳递', 'saiaodi', null, '0', '0', '0', '2017-09-13 16:14:02');
INSERT INTO `store_express` VALUES ('65', '天地华宇', 'tiandihuayu', null, '0', '0', '0', '2017-09-13 16:14:11');
INSERT INTO `store_express` VALUES ('66', '天天快递', 'tiantian', null, '0', '0', '0', '2017-09-13 16:14:19');
INSERT INTO `store_express` VALUES ('67', 'TNT', 'tnt', null, '0', '0', '0', '2017-09-13 16:14:26');
INSERT INTO `store_express` VALUES ('68', 'UPS', 'ups', null, '0', '0', '0', '2017-09-13 16:14:29');
INSERT INTO `store_express` VALUES ('69', '万家物流', 'wanjiawuliu', null, '0', '0', '0', '2017-09-13 16:14:37');
INSERT INTO `store_express` VALUES ('70', '文捷航空速递', 'wenjiesudi', null, '0', '0', '0', '2017-09-13 16:14:46');
INSERT INTO `store_express` VALUES ('71', '伍圆', 'wuyuan', null, '0', '0', '0', '2017-09-13 16:14:52');
INSERT INTO `store_express` VALUES ('72', '万象物流', 'wxwl', null, '0', '0', '0', '2017-09-13 16:15:00');
INSERT INTO `store_express` VALUES ('73', '新邦物流', 'xinbangwuliu', null, '0', '0', '0', '2017-09-13 16:15:06');
INSERT INTO `store_express` VALUES ('74', '信丰物流', 'xinfengwuliu', null, '0', '0', '0', '2017-09-13 16:15:15');
INSERT INTO `store_express` VALUES ('75', '亚风速递', 'yafengsudi', null, '0', '0', '0', '2017-09-13 16:15:23');
INSERT INTO `store_express` VALUES ('76', '一邦速递', 'yibangwuliu', null, '0', '0', '0', '2017-09-13 16:15:30');
INSERT INTO `store_express` VALUES ('77', '优速物流', 'youshuwuliu', null, '0', '0', '0', '2017-09-13 16:15:36');
INSERT INTO `store_express` VALUES ('78', '邮政包裹挂号信', 'youzhengguonei', null, '0', '3', '0', '2017-09-13 16:15:44');
INSERT INTO `store_express` VALUES ('79', '邮政国际包裹挂号信', 'youzhengguoji', null, '0', '2', '0', '2017-09-13 16:15:51');
INSERT INTO `store_express` VALUES ('80', '远成物流', 'yuanchengwuliu', null, '0', '0', '0', '2017-09-13 16:15:57');
INSERT INTO `store_express` VALUES ('81', '圆通速递', 'yuantong', null, '1', '1', '0', '2017-09-13 16:16:03');
INSERT INTO `store_express` VALUES ('82', '源伟丰快递', 'yuanweifeng', null, '0', '0', '0', '2017-09-13 16:16:10');
INSERT INTO `store_express` VALUES ('83', '元智捷诚快递', 'yuanzhijiecheng', null, '0', '0', '0', '2017-09-13 16:16:17');
INSERT INTO `store_express` VALUES ('84', '韵达快运', 'yunda', null, '0', '0', '0', '2017-09-13 16:16:24');
INSERT INTO `store_express` VALUES ('85', '运通快递', 'yuntongkuaidi', null, '0', '0', '0', '2017-09-13 16:16:33');
INSERT INTO `store_express` VALUES ('86', '越丰物流', 'yuefengwuliu', null, '0', '0', '0', '2017-09-13 16:16:40');
INSERT INTO `store_express` VALUES ('87', '源安达', 'yad', null, '0', '0', '0', '2017-09-13 16:16:47');
INSERT INTO `store_express` VALUES ('88', '银捷速递', 'yinjiesudi', null, '0', '0', '0', '2017-09-13 16:16:56');
INSERT INTO `store_express` VALUES ('89', '宅急送', 'zhaijisong', null, '0', '0', '0', '2017-09-13 16:17:03');
INSERT INTO `store_express` VALUES ('90', '中铁快运', 'zhongtiekuaiyun', null, '0', '0', '0', '2017-09-13 16:17:10');
INSERT INTO `store_express` VALUES ('91', '中通速递', 'zhongtong', '', '0', '0', '0', '2017-09-13 16:17:16');
INSERT INTO `store_express` VALUES ('92', '中邮物流', 'zhongyouwuliu', null, '0', '0', '0', '2017-09-13 16:17:27');
INSERT INTO `store_express` VALUES ('93', '忠信达', 'zhongxinda', null, '0', '0', '0', '2017-09-13 16:17:34');
INSERT INTO `store_express` VALUES ('94', '芝麻开门', 'zhimakaimen', null, '0', '0', '0', '2017-09-13 16:17:41');
-- ----------------------------
-- Table structure for store_goods
-- ----------------------------
DROP TABLE IF EXISTS `store_goods`;
CREATE TABLE `store_goods` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`brand_id` bigint(20) unsigned DEFAULT '0' COMMENT '品牌ID',
`cate_id` bigint(20) unsigned DEFAULT '0' COMMENT '商品分类id',
`unit_id` bigint(20) DEFAULT NULL COMMENT '商品单位ID',
`spec_id` bigint(20) unsigned DEFAULT '0' COMMENT '规格ID',
`tags_id` varchar(255) DEFAULT '' COMMENT '商品标签ID',
`is_code` bigint(1) DEFAULT '1' COMMENT '是否有码商品',
`goods_title` varchar(255) DEFAULT '' COMMENT '商品标签',
`goods_content` text COMMENT '商品内容',
`goods_logo` varchar(255) DEFAULT '' COMMENT '商品LOGO',
`goods_image` text COMMENT '商品图片地址',
`goods_video` varchar(500) DEFAULT '' COMMENT '商品视频URL',
`goods_desc` varchar(500) DEFAULT '' COMMENT '商品描述',
`package_stock` bigint(20) unsigned DEFAULT '0' COMMENT '总库存数量',
`package_sale` bigint(20) unsigned DEFAULT '0' COMMENT '已销售数量',
`favorite_num` bigint(20) unsigned DEFAULT '0' COMMENT '收藏次数',
`sort` bigint(20) unsigned DEFAULT '0' COMMENT '数据排序',
`status` bigint(1) unsigned DEFAULT '1' COMMENT '商品状态(1有效,0无效)',
`is_deleted` bigint(1) unsigned DEFAULT '0' COMMENT '删除状态(1删除,0未删除)',
`create_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='商城商品主表';
-- ----------------------------
-- Records of store_goods
-- ----------------------------
-- ----------------------------
-- Table structure for store_goods_brand
-- ----------------------------
DROP TABLE IF EXISTS `store_goods_brand`;
CREATE TABLE `store_goods_brand` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`brand_logo` varchar(1024) DEFAULT '' COMMENT '品牌logo',
`brand_cover` varchar(1024) DEFAULT '' COMMENT '品牌封面',
`brand_title` varchar(255) DEFAULT '' COMMENT '商品品牌名称',
`brand_desc` text COMMENT '商品品牌描述',
`brand_detail` text COMMENT '品牌图文信息',
`sort` int(11) unsigned DEFAULT '0' COMMENT '商品分类排序',
`status` tinyint(1) unsigned DEFAULT '1' COMMENT '商品状态(1有效,0无效)',
`is_deleted` tinyint(1) unsigned DEFAULT '0' COMMENT '删除状态(1删除,0未删除)',
`create_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='产品品牌';
-- ----------------------------
-- Records of store_goods_brand
-- ----------------------------
-- ----------------------------
-- 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,
`pid` bigint(20) unsigned DEFAULT '0' COMMENT '上级分类编号',
`brand_id` bigint(20) DEFAULT '0' COMMENT '品牌ID',
`cate_title` varchar(255) DEFAULT '' COMMENT '商品分类名称',
`cate_desc` text COMMENT '商品分类',
`sort` bigint(20) unsigned DEFAULT '0' COMMENT '商品分类排序',
`status` bigint(1) unsigned DEFAULT '1' COMMENT '商品状态(1有效,0无效)',
`is_deleted` bigint(1) unsigned DEFAULT '0' COMMENT '删除状态(1删除,0未删除)',
`create_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='商城商品分类';
-- ----------------------------
-- Records of store_goods_cate
-- ----------------------------
-- ----------------------------
-- 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,
`goods_id` bigint(20) unsigned DEFAULT '0' COMMENT '商品ID',
`goods_spec` varchar(255) DEFAULT '' COMMENT '商品规格名称',
`goods_number` bigint(20) unsigned DEFAULT '0' COMMENT '商品礼品-商品数量',
`market_price` decimal(20,2) unsigned DEFAULT '0.00' COMMENT '销售价格',
`selling_price` decimal(20,2) unsigned DEFAULT '0.00' COMMENT '商品价格',
`goods_stock` bigint(20) unsigned DEFAULT '0' COMMENT '商品库存统计',
`goods_sale` bigint(20) unsigned DEFAULT '0' COMMENT '已销售数量',
`status` bigint(1) unsigned DEFAULT '1' COMMENT '商品状态(1有效,0无效)',
`is_deleted` bigint(1) unsigned DEFAULT '0' COMMENT '删除状态(1删除,0未删除)',
`create_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='商城商品列表';
-- ----------------------------
-- Records of store_goods_list
-- ----------------------------
-- ----------------------------
-- Table structure for store_goods_spec
-- ----------------------------
DROP TABLE IF EXISTS `store_goods_spec`;
CREATE TABLE `store_goods_spec` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`mch_id` bigint(20) unsigned DEFAULT '0' COMMENT '商户ID',
`spec_title` varchar(255) DEFAULT '' COMMENT '商品规格名称',
`spec_param` varchar(255) DEFAULT '' COMMENT '商品规格参数',
`spec_desc` varchar(255) DEFAULT '' COMMENT '商品规格描述',
`sort` bigint(20) unsigned DEFAULT '0' COMMENT '商品规格排序',
`status` bigint(1) unsigned DEFAULT '1' COMMENT '商品状态(1有效,0无效)',
`is_deleted` bigint(1) unsigned DEFAULT '0' COMMENT '删除状态(1删除,0未删除)',
`create_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
PRIMARY KEY (`id`),
KEY `index_store_goods_spec_mch_id` (`mch_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='商城商品规格';
-- ----------------------------
-- Records of store_goods_spec
-- ----------------------------
-- ----------------------------
-- 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) DEFAULT '' COMMENT '会员微信OPENID',
`phone` varchar(16) DEFAULT '' COMMENT '会员手机号',
`password` varchar(64) NOT NULL DEFAULT '' COMMENT '登录密码',
`nickname` varchar(20) DEFAULT '' COMMENT '会员昵称',
`headimg` varchar(500) DEFAULT '' COMMENT '会员头像',
`sex` char(2) DEFAULT '' COMMENT '性别',
`level` tinyint(2) unsigned DEFAULT '1' COMMENT '会员级别',
`remark` varchar(500) DEFAULT '' COMMENT '会员个性签名',
`status` tinyint(1) unsigned DEFAULT '1' COMMENT '会员状态(1有效,0无效)',
`create_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
PRIMARY KEY (`id`),
UNIQUE KEY `index_store_member_openid` (`openid`) USING BTREE,
KEY `index_store_member_phone` (`phone`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='商城会员信息';
-- ----------------------------
-- Records of store_member
-- ----------------------------
-- ----------------------------
-- 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 DEFAULT '0' COMMENT '会员ID',
`username` varchar(20) DEFAULT '' COMMENT '收货人姓名',
`phone` varchar(16) DEFAULT '' COMMENT '收货手机号',
`province` varchar(50) DEFAULT '' COMMENT '收货地址省份',
`city` varchar(50) DEFAULT '' COMMENT '收货地址城市',
`area` varchar(255) DEFAULT '' COMMENT '收货地址区域',
`address` varchar(255) DEFAULT '' COMMENT '收货详细地址',
`status` tinyint(1) unsigned DEFAULT '1' COMMENT '状态(0无效, 1新快递)',
`is_default` tinyint(1) unsigned DEFAULT '1' COMMENT '默认收货地址',
`is_deleted` bigint(1) unsigned DEFAULT '0' COMMENT '删除状态(1删除,0未删除)',
`create_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='商城会员收货地址';
-- ----------------------------
-- Records of store_member_address
-- ----------------------------
-- ----------------------------
-- Table structure for store_order
-- ----------------------------
DROP TABLE IF EXISTS `store_order`;
CREATE TABLE `store_order` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`type` tinyint(1) unsigned DEFAULT '1' COMMENT '订单类型(1普通订单,2积分订单)',
`mid` bigint(20) unsigned DEFAULT '0' COMMENT '会员ID',
`order_no` char(10) DEFAULT '' COMMENT '订单号',
`freight_price` decimal(20,2) unsigned DEFAULT '0.00' COMMENT '快递费',
`goods_price` decimal(20,2) unsigned DEFAULT '0.00' COMMENT '商品总金额(不含快递费)',
`real_price` decimal(20,2) unsigned DEFAULT '0.00' COMMENT '真实支付金额(商品金额+快递金额)',
`is_pay` tinyint(1) unsigned DEFAULT '0' COMMENT '订单支付状态(0.未支付,1.已支付)',
`pay_type` varchar(255) DEFAULT '' COMMENT '支付方式 (wechat微信支付, alipay支付宝支付)',
`pay_no` varchar(100) DEFAULT '' COMMENT '商户交易号',
`pay_price` decimal(20,2) unsigned DEFAULT '0.00' COMMENT '实际支付金额',
`pay_at` datetime DEFAULT NULL COMMENT '支付时间',
`desc` text COMMENT '订单描述',
`status` bigint(1) unsigned DEFAULT '1' COMMENT '订单状态(0.无效,1.新订单,2.待发货,3.已发货,4.已收货,5.已完成,6.已退货及退款)',
`is_deleted` tinyint(1) unsigned DEFAULT '0' COMMENT '删除状态(1删除,0未删除)',
`create_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
PRIMARY KEY (`id`),
KEY `index_store_order_order_no` (`order_no`) USING BTREE,
KEY `index_store_order_status` (`status`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='商城订单主表';
-- ----------------------------
-- Records of store_order
-- ----------------------------
-- ----------------------------
-- Table structure for store_order_express
-- ----------------------------
DROP TABLE IF EXISTS `store_order_express`;
CREATE TABLE `store_order_express` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`mid` bigint(20) unsigned DEFAULT '0' COMMENT '会员ID',
`type` tinyint(1) unsigned DEFAULT '0' COMMENT '快递类型(0.订单快递,1.退货快递)',
`order_no` char(10) DEFAULT '' COMMENT '订单编号',
`company_title` varchar(50) DEFAULT '' COMMENT '物流公司名称',
`company_code` varchar(50) DEFAULT '' COMMENT '物流公司编码',
`username` varchar(20) DEFAULT '' COMMENT '收货人姓名',
`phone` varchar(16) DEFAULT '' COMMENT '收货手机号',
`province` varchar(50) DEFAULT NULL COMMENT '收货地址省份',
`city` varchar(50) DEFAULT '' COMMENT '收货地址城市',
`area` varchar(255) DEFAULT '' COMMENT '收货地址区域',
`address` varchar(255) DEFAULT '' COMMENT '收货详细地址',
`send_no` varchar(50) DEFAULT '' COMMENT '实际物流公司单号',
`send_company_title` varchar(50) DEFAULT '' COMMENT '实际发货快递公司',
`send_company_code` varchar(50) DEFAULT '' COMMENT '实际发货快递代码',
`send_username` varchar(255) DEFAULT '' COMMENT '寄件人名称',
`send_phone` varchar(16) DEFAULT '' COMMENT '寄件人手机号',
`send_province` varchar(50) DEFAULT '' COMMENT '寄件人地址省份',
`send_city` varchar(50) DEFAULT '' COMMENT '寄件人地址城市',
`send_area` varchar(255) DEFAULT '' COMMENT '寄件人地址区域',
`send_address` varchar(255) DEFAULT '' COMMENT '寄件人详细地址',
`send_at` datetime DEFAULT NULL COMMENT '快递发货时间',
`desc` text COMMENT '发货描述',
`status` tinyint(1) unsigned DEFAULT '1' COMMENT '状态(0.无效,1.新快递,2.已签收,3.签收失败)',
`is_deleted` bigint(1) unsigned DEFAULT '0' COMMENT '删除状态(1删除,0未删除)',
`create_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='商城订单快递';
-- ----------------------------
-- Records of store_order_express
-- ----------------------------
-- ----------------------------
-- Table structure for store_order_goods
-- ----------------------------
DROP TABLE IF EXISTS `store_order_goods`;
CREATE TABLE `store_order_goods` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`mid` bigint(20) unsigned DEFAULT '0' COMMENT '会员ID',
`order_no` char(10) DEFAULT '' COMMENT '订单编号',
`goods_id` bigint(20) DEFAULT '0' COMMENT '商品ID',
`goods_title` varchar(255) DEFAULT '' COMMENT '商品标签',
`goods_spec` varchar(255) DEFAULT '' COMMENT '商品规格',
`goods_logo` varchar(255) DEFAULT '' COMMENT '商品LOGO',
`goods_image` text COMMENT '商品图片地址',
`market_price` decimal(20,2) unsigned DEFAULT '0.00' COMMENT '市场价格',
`selling_price` decimal(20,2) unsigned DEFAULT '0.00' COMMENT '商品销售价格',
`price_field` varchar(20) DEFAULT 'selling_price' COMMENT '计价字段',
`number` bigint(20) unsigned DEFAULT '0' COMMENT '订单商品数量',
`status` bigint(1) unsigned DEFAULT '1' COMMENT '商品状态(1有效,0无效)',
`is_deleted` bigint(1) unsigned DEFAULT '0' COMMENT '删除状态(1删除,0未删除)',
`create_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
PRIMARY KEY (`id`),
KEY `index_store_order_list_order_no` (`order_no`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='商城订单关联商品';
-- ----------------------------
-- Records of store_order_goods
-- ----------------------------
-- ----------------------------
-- 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) NOT NULL COMMENT '权限名称',
`status` tinyint(1) unsigned DEFAULT '1' COMMENT '状态(1:禁用,2:启用)',
`sort` smallint(6) unsigned DEFAULT '0' COMMENT '排序权重',
`desc` varchar(255) DEFAULT NULL COMMENT '备注说明',
`create_by` bigint(11) unsigned DEFAULT '0' COMMENT '创建人',
`create_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
PRIMARY KEY (`id`),
UNIQUE KEY `index_system_auth_title` (`title`) USING BTREE,
KEY `index_system_auth_status` (`status`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='系统权限表';
-- ----------------------------
-- Records of system_auth
-- ----------------------------
-- ----------------------------
-- 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 DEFAULT NULL COMMENT '角色ID',
`node` varchar(200) DEFAULT NULL COMMENT '节点路径',
PRIMARY KEY (`id`),
KEY `index_system_auth_auth` (`auth`) USING BTREE,
KEY `index_system_auth_node` (`node`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='系统角色与节点绑定';
-- ----------------------------
-- Records of system_auth_node
-- ----------------------------
-- ----------------------------
-- Table structure for system_config
-- ----------------------------
DROP TABLE IF EXISTS `system_config`;
CREATE TABLE `system_config` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(100) DEFAULT NULL COMMENT '配置编码',
`value` varchar(500) DEFAULT NULL COMMENT '配置值',
PRIMARY KEY (`id`),
KEY `index_system_config_name` (`name`)
) ENGINE=InnoDB AUTO_INCREMENT=43 DEFAULT CHARSET=utf8 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', '3.0 dev');
INSERT INTO `system_config` VALUES ('4', 'site_copy', '©版权所有 2014-2018 楚才科技');
INSERT INTO `system_config` VALUES ('5', 'browser_icon', 'http://localhost/ThinkAdmin/static/upload/f47b8fe06e38ae99/08e8398da45583b9.png');
INSERT INTO `system_config` VALUES ('6', 'tongji_baidu_key', '');
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', 'png,jpg,rar,doc,icon,mp4');
INSERT INTO `system_config` VALUES ('10', 'storage_qiniu_bucket', '');
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');
INSERT INTO `system_config` VALUES ('15', 'storage_oss_endpoint', 'oss-cn-beijing.aliyuncs.com');
INSERT INTO `system_config` VALUES ('16', 'storage_oss_domain', 'cuci.oss-cn-beijing.aliyuncs.com');
INSERT INTO `system_config` VALUES ('17', 'storage_oss_keyid', '用你自己的吧');
INSERT INTO `system_config` VALUES ('18', 'storage_oss_secret', '用你自己的吧');
INSERT INTO `system_config` VALUES ('34', 'wechat_appid', 'wx60a43dd8161666d4');
INSERT INTO `system_config` VALUES ('35', 'wechat_appkey', '9890a0d7c91801a609d151099e95b61a');
INSERT INTO `system_config` VALUES ('36', 'storage_oss_is_https', 'http');
INSERT INTO `system_config` VALUES ('37', 'wechat_type', 'thr');
INSERT INTO `system_config` VALUES ('38', 'wechat_token', 'test');
INSERT INTO `system_config` VALUES ('39', 'wechat_appsecret', 'a041bec98ed015d52b99acea5c6a16ef');
INSERT INTO `system_config` VALUES ('40', 'wechat_encodingaeskey', 'BJIUzE0gqlWy0GxfPp4J1oPTBmOrNDIGPNav1YFH5Z5');
INSERT INTO `system_config` VALUES ('41', 'wechat_thr_appid', 'wx60a43dd8161666d4');
INSERT INTO `system_config` VALUES ('42', 'wechat_thr_appkey', '05db2aa335382c66ab56d69b1a9ad0ee');
-- ----------------------------
-- Table structure for system_log
-- ----------------------------
DROP TABLE IF EXISTS `system_log`;
CREATE TABLE `system_log` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`ip` char(15) NOT NULL DEFAULT '' COMMENT '操作者IP地址',
`node` char(200) NOT NULL DEFAULT '' COMMENT '当前操作节点',
`username` varchar(32) NOT NULL DEFAULT '' COMMENT '操作人用户名',
`action` varchar(200) NOT NULL DEFAULT '' COMMENT '操作行为',
`content` text NOT NULL COMMENT '操作内容描述',
`create_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='系统操作日志表';
-- ----------------------------
-- Records of system_log
-- ----------------------------
-- ----------------------------
-- 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 NOT NULL DEFAULT '0' COMMENT '父id',
`title` varchar(100) NOT NULL DEFAULT '' COMMENT '名称',
`node` varchar(200) NOT NULL DEFAULT '' COMMENT '节点代码',
`icon` varchar(100) NOT NULL DEFAULT '' COMMENT '菜单图标',
`url` varchar(400) NOT NULL DEFAULT '' COMMENT '链接',
`params` varchar(500) DEFAULT '' COMMENT '链接参数',
`target` varchar(20) NOT NULL DEFAULT '_self' COMMENT '链接打开方式',
`sort` int(11) unsigned DEFAULT '0' COMMENT '菜单排序',
`status` tinyint(1) unsigned NOT NULL DEFAULT '1' COMMENT '状态(0:禁用,1:启用)',
`create_by` bigint(20) unsigned NOT NULL DEFAULT '0' COMMENT '创建人',
`create_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
PRIMARY KEY (`id`),
KEY `index_system_menu_node` (`node`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=43 DEFAULT CHARSET=utf8 COMMENT='系统菜单表';
-- ----------------------------
-- Records of system_menu
-- ----------------------------
INSERT INTO `system_menu` VALUES ('1', '0', '系统设置', '', '', '#', '', '_self', '9000', '1', '10000', '2018-01-19 15:27:00');
INSERT INTO `system_menu` VALUES ('2', '10', '后台菜单', '', 'fa fa-leaf', 'admin/menu/index', '', '_self', '10', '1', '10000', '2018-01-19 15:27:17');
INSERT INTO `system_menu` VALUES ('3', '10', '系统参数', '', 'fa fa-modx', 'admin/config/index', '', '_self', '20', '1', '10000', '2018-01-19 15:27:57');
INSERT INTO `system_menu` VALUES ('4', '11', '访问授权', '', 'fa fa-group', 'admin/auth/index', '', '_self', '20', '1', '10000', '2018-01-22 11:13:02');
INSERT INTO `system_menu` VALUES ('5', '11', '用户管理', '', 'fa fa-user', 'admin/user/index', '', '_self', '10', '1', '0', '2018-01-23 12:15:12');
INSERT INTO `system_menu` VALUES ('6', '11', '访问节点', '', 'fa fa-fort-awesome', 'admin/node/index', '', '_self', '30', '1', '0', '2018-01-23 12:36:54');
INSERT INTO `system_menu` VALUES ('7', '0', '后台首页', '', '', 'admin/index/main', '', '_self', '1000', '1', '0', '2018-01-23 13:42:30');
INSERT INTO `system_menu` VALUES ('8', '16', '系统日志', '', 'fa fa-code', 'admin/log/index', '', '_self', '10', '1', '0', '2018-01-24 13:52:58');
INSERT INTO `system_menu` VALUES ('9', '10', '文件存储', '', 'fa fa-stop-circle', 'admin/config/file', '', '_self', '30', '1', '0', '2018-01-25 10:54:28');
INSERT INTO `system_menu` VALUES ('10', '1', '系统管理', '', '', '#', '', '_self', '200', '1', '0', '2018-01-25 18:14:28');
INSERT INTO `system_menu` VALUES ('11', '1', '访问权限', '', '', '#', '', '_self', '300', '1', '0', '2018-01-25 18:15:08');
INSERT INTO `system_menu` VALUES ('16', '1', '日志管理', '', '', '#', '', '_self', '400', '1', '0', '2018-02-10 16:31:15');
INSERT INTO `system_menu` VALUES ('17', '0', '微信管理', '', '', '#', '', '_self', '8000', '1', '0', '2018-03-06 14:42:49');
INSERT INTO `system_menu` VALUES ('18', '17', '公众号配置', '', '', '#', '', '_self', '0', '1', '0', '2018-03-06 14:43:05');
INSERT INTO `system_menu` VALUES ('19', '18', '微信授权绑定', '', 'fa fa-cog', 'wechat/config/index', '', '_self', '0', '1', '0', '2018-03-06 14:43:26');
INSERT INTO `system_menu` VALUES ('20', '18', '关注默认回复', '', 'fa fa-comment-o', 'wechat/keys/subscribe', '', '_self', '0', '1', '0', '2018-03-06 14:44:45');
INSERT INTO `system_menu` VALUES ('21', '18', '无反馈默认回复', '', 'fa fa-commenting', 'wechat/keys/defaults', '', '_self', '0', '1', '0', '2018-03-06 14:45:55');
INSERT INTO `system_menu` VALUES ('22', '18', '微信关键字管理', '', 'fa fa-hashtag', 'wechat/keys/index', '', '_self', '0', '1', '0', '2018-03-06 14:46:23');
INSERT INTO `system_menu` VALUES ('23', '17', '微信服务定制', '', '', '#', '', '_self', '0', '1', '0', '2018-03-06 14:47:11');
INSERT INTO `system_menu` VALUES ('24', '23', '微信菜单管理', '', 'fa fa-gg-circle', 'wechat/menu/index', '', '_self', '0', '1', '0', '2018-03-06 14:47:39');
INSERT INTO `system_menu` VALUES ('25', '23', '微信图文管理', '', 'fa fa-map-o', 'wechat/news/index', '', '_self', '0', '1', '0', '2018-03-06 14:48:14');
INSERT INTO `system_menu` VALUES ('26', '17', '微信粉丝管理', '', 'fa fa-user', '#', '', '_self', '0', '1', '0', '2018-03-06 14:48:33');
INSERT INTO `system_menu` VALUES ('27', '26', '微信粉丝列表', '', 'fa fa-users', 'wechat/fans/index', '', '_self', '20', '1', '0', '2018-03-06 14:49:04');
INSERT INTO `system_menu` VALUES ('28', '26', '微信黑名单管理', '', 'fa fa-user-times', 'wechat/fans_block/index', '', '_self', '30', '1', '0', '2018-03-06 14:49:22');
INSERT INTO `system_menu` VALUES ('29', '26', '微信标签管理', '', 'fa fa-tags', 'wechat/tags/index', '', '_self', '10', '1', '0', '2018-03-06 14:49:39');
INSERT INTO `system_menu` VALUES ('32', '0', '商城管理', '', '', '#', '', '_self', '2000', '1', '0', '2018-03-20 16:46:07');
INSERT INTO `system_menu` VALUES ('33', '32', '商品管理', '', '', '#', '', '_self', '0', '1', '0', '2018-03-20 16:46:21');
INSERT INTO `system_menu` VALUES ('34', '33', '产品管理', '', 'fa fa-modx', 'store/goods/index', '', '_self', '0', '1', '0', '2018-03-20 16:46:45');
INSERT INTO `system_menu` VALUES ('35', '33', '规格管理', '', 'fa fa-hashtag', 'store/goods_spec/index', '', '_self', '0', '1', '0', '2018-03-20 16:47:08');
INSERT INTO `system_menu` VALUES ('36', '33', '分类管理', '', 'fa fa-product-hunt', 'store/goods_cate/index', '', '_self', '0', '1', '0', '2018-03-20 16:47:50');
INSERT INTO `system_menu` VALUES ('37', '33', '品牌管理', '', 'fa fa-scribd', 'store/goods_brand/index', '', '_self', '0', '1', '0', '2018-03-20 16:48:05');
INSERT INTO `system_menu` VALUES ('38', '32', '订单管理', '', '', '#', '', '_self', '0', '1', '0', '2018-04-21 15:07:36');
INSERT INTO `system_menu` VALUES ('39', '38', '订单列表', '', 'fa fa-adjust', 'store/order/index', '', '_self', '0', '1', '0', '2018-04-21 15:07:54');
INSERT INTO `system_menu` VALUES ('40', '32', '商城配置', '', '', '#', '', '_self', '0', '1', '0', '2018-04-21 15:08:17');
INSERT INTO `system_menu` VALUES ('41', '40', '参数管理', '', '', '#', '', '_self', '0', '0', '0', '2018-04-21 15:08:25');
INSERT INTO `system_menu` VALUES ('42', '40', '快递公司', '', 'fa fa-mixcloud', 'store/express/index', '', '_self', '0', '1', '0', '2018-04-21 15:08:50');
-- ----------------------------
-- Table structure for system_node
-- ----------------------------
DROP TABLE IF EXISTS `system_node`;
CREATE TABLE `system_node` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`node` varchar(100) DEFAULT NULL COMMENT '节点代码',
`title` varchar(500) DEFAULT NULL COMMENT '节点标题',
`is_menu` tinyint(1) unsigned DEFAULT '0' COMMENT '是否可设置为菜单',
`is_auth` tinyint(1) unsigned DEFAULT '1' COMMENT '是否启动RBAC权限控制',
`is_login` tinyint(1) unsigned DEFAULT '1' COMMENT '是否启动登录控制',
`create_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
PRIMARY KEY (`id`),
KEY `index_system_node_node` (`node`)
) ENGINE=InnoDB AUTO_INCREMENT=145 DEFAULT CHARSET=utf8 COMMENT='系统节点表';
-- ----------------------------
-- Records of system_node
-- ----------------------------
INSERT INTO `system_node` VALUES ('13', 'admin', '系统设置', '0', '1', '1', '2018-05-04 11:02:34');
INSERT INTO `system_node` VALUES ('14', 'admin/auth', '权限管理', '0', '1', '1', '2018-05-04 11:06:55');
INSERT INTO `system_node` VALUES ('15', 'admin/auth/index', '权限列表', '1', '1', '1', '2018-05-04 11:06:56');
INSERT INTO `system_node` VALUES ('16', 'admin/auth/apply', '权限配置', '0', '1', '1', '2018-05-04 11:06:56');
INSERT INTO `system_node` VALUES ('17', 'admin/auth/add', '添加权限', '0', '1', '1', '2018-05-04 11:06:56');
INSERT INTO `system_node` VALUES ('18', 'admin/auth/edit', '编辑权限', '0', '1', '1', '2018-05-04 11:06:56');
INSERT INTO `system_node` VALUES ('19', 'admin/auth/forbid', '禁用权限', '0', '1', '1', '2018-05-04 11:06:56');
INSERT INTO `system_node` VALUES ('20', 'admin/auth/resume', '启用权限', '0', '1', '1', '2018-05-04 11:06:56');
INSERT INTO `system_node` VALUES ('21', 'admin/auth/del', '删除权限', '0', '1', '1', '2018-05-04 11:06:56');
INSERT INTO `system_node` VALUES ('22', 'admin/config', '系统配置', '0', '1', '1', '2018-05-04 11:08:18');
INSERT INTO `system_node` VALUES ('23', 'admin/config/index', '系统参数', '1', '1', '1', '2018-05-04 11:08:25');
INSERT INTO `system_node` VALUES ('24', 'admin/config/file', '文件存储', '1', '1', '1', '2018-05-04 11:08:27');
INSERT INTO `system_node` VALUES ('25', 'admin/log', '日志管理', '0', '1', '1', '2018-05-04 11:08:43');
INSERT INTO `system_node` VALUES ('26', 'admin/log/index', '日志管理', '1', '1', '1', '2018-05-04 11:08:43');
INSERT INTO `system_node` VALUES ('28', 'admin/log/del', '日志删除', '0', '1', '1', '2018-05-04 11:08:43');
INSERT INTO `system_node` VALUES ('29', 'admin/menu', '系统菜单', '0', '1', '1', '2018-05-04 11:09:54');
INSERT INTO `system_node` VALUES ('30', 'admin/menu/index', '菜单列表', '1', '1', '1', '2018-05-04 11:09:54');
INSERT INTO `system_node` VALUES ('31', 'admin/menu/add', '添加菜单', '0', '1', '1', '2018-05-04 11:09:55');
INSERT INTO `system_node` VALUES ('32', 'admin/menu/edit', '编辑菜单', '0', '1', '1', '2018-05-04 11:09:55');
INSERT INTO `system_node` VALUES ('33', 'admin/menu/del', '删除菜单', '0', '1', '1', '2018-05-04 11:09:55');
INSERT INTO `system_node` VALUES ('34', 'admin/menu/forbid', '禁用菜单', '0', '1', '1', '2018-05-04 11:09:55');
INSERT INTO `system_node` VALUES ('35', 'admin/menu/resume', '启用菜单', '0', '1', '1', '2018-05-04 11:09:55');
INSERT INTO `system_node` VALUES ('36', 'admin/node', '节点管理', '0', '1', '1', '2018-05-04 11:10:20');
INSERT INTO `system_node` VALUES ('37', 'admin/node/index', '节点列表', '1', '1', '1', '2018-05-04 11:10:20');
INSERT INTO `system_node` VALUES ('38', 'admin/node/clear', '清理节点', '0', '1', '1', '2018-05-04 11:10:21');
INSERT INTO `system_node` VALUES ('39', 'admin/node/save', '更新节点', '0', '1', '1', '2018-05-04 11:10:21');
INSERT INTO `system_node` VALUES ('40', 'admin/user', '系统用户', '0', '1', '1', '2018-05-04 11:10:43');
INSERT INTO `system_node` VALUES ('41', 'admin/user/index', '用户列表', '1', '1', '1', '2018-05-04 11:10:43');
INSERT INTO `system_node` VALUES ('42', 'admin/user/auth', '用户授权', '0', '1', '1', '2018-05-04 11:10:43');
INSERT INTO `system_node` VALUES ('43', 'admin/user/add', '添加用户', '0', '1', '1', '2018-05-04 11:10:43');
INSERT INTO `system_node` VALUES ('44', 'admin/user/edit', '编辑用户', '0', '1', '1', '2018-05-04 11:10:43');
INSERT INTO `system_node` VALUES ('45', 'admin/user/pass', '修改密码', '0', '1', '1', '2018-05-04 11:10:43');
INSERT INTO `system_node` VALUES ('46', 'admin/user/del', '删除用户', '0', '1', '1', '2018-05-04 11:10:43');
INSERT INTO `system_node` VALUES ('47', 'admin/user/forbid', '禁用启用', '0', '1', '1', '2018-05-04 11:10:43');
INSERT INTO `system_node` VALUES ('48', 'admin/user/resume', '启用用户', '0', '1', '1', '2018-05-04 11:10:44');
INSERT INTO `system_node` VALUES ('49', 'store', '商城管理', '0', '1', '1', '2018-05-04 11:11:28');
INSERT INTO `system_node` VALUES ('50', 'store/express', '快递公司管理', '0', '1', '1', '2018-05-04 11:11:39');
INSERT INTO `system_node` VALUES ('51', 'store/express/index', '快递公司列表', '1', '1', '1', '2018-05-04 11:11:39');
INSERT INTO `system_node` VALUES ('52', 'store/express/add', '添加快递公司', '0', '1', '1', '2018-05-04 11:11:39');
INSERT INTO `system_node` VALUES ('53', 'store/express/edit', '编辑快递公司', '0', '1', '1', '2018-05-04 11:11:39');
INSERT INTO `system_node` VALUES ('54', 'store/express/del', '删除快递公司', '0', '1', '1', '2018-05-04 11:11:39');
INSERT INTO `system_node` VALUES ('55', 'store/express/forbid', '禁用快递公司', '0', '1', '1', '2018-05-04 11:11:39');
INSERT INTO `system_node` VALUES ('56', 'store/express/resume', '启用快递公司', '0', '1', '1', '2018-05-04 11:11:40');
INSERT INTO `system_node` VALUES ('57', 'store/order', '订单管理', '0', '1', '1', '2018-05-04 11:12:14');
INSERT INTO `system_node` VALUES ('58', 'store/order/index', '订单列表', '1', '1', '1', '2018-05-04 11:12:17');
INSERT INTO `system_node` VALUES ('59', 'store/order/address', '修改地址', '0', '1', '1', '2018-05-04 11:12:19');
INSERT INTO `system_node` VALUES ('76', 'wechat', '微信管理', '0', '1', '1', '2018-05-04 11:14:59');
INSERT INTO `system_node` VALUES ('78', 'wechat/config', '微信对接管理', '0', '1', '1', '2018-05-04 11:16:20');
INSERT INTO `system_node` VALUES ('79', 'wechat/config/index', '微信对接配置', '1', '1', '1', '2018-05-04 11:16:23');
INSERT INTO `system_node` VALUES ('80', 'wechat/fans', '微信粉丝管理', '0', '1', '1', '2018-05-04 11:16:31');
INSERT INTO `system_node` VALUES ('81', 'wechat/fans/index', '微信粉丝列表', '1', '1', '1', '2018-05-04 11:16:32');
INSERT INTO `system_node` VALUES ('82', 'wechat/fans/backadd', '微信粉丝拉黑', '0', '1', '1', '2018-05-04 11:16:32');
INSERT INTO `system_node` VALUES ('83', 'wechat/fans/tagset', '设置粉丝标签', '0', '1', '1', '2018-05-04 11:16:32');
INSERT INTO `system_node` VALUES ('84', 'wechat/fans/tagadd', '添加粉丝标签', '0', '1', '1', '2018-05-04 11:16:32');
INSERT INTO `system_node` VALUES ('85', 'wechat/fans/tagdel', '删除粉丝标签', '0', '1', '1', '2018-05-04 11:16:32');
INSERT INTO `system_node` VALUES ('86', 'wechat/fans/sync', '同步粉丝列表', '0', '1', '1', '2018-05-04 11:16:32');
INSERT INTO `system_node` VALUES ('87', 'wechat/fans_block', '粉丝黑名单管理', '0', '1', '1', '2018-05-04 11:17:25');
INSERT INTO `system_node` VALUES ('88', 'wechat/fans_block/index', '粉丝黑名单列表', '1', '1', '1', '2018-05-04 11:17:50');
INSERT INTO `system_node` VALUES ('89', 'wechat/fans_block/backdel', '移除粉丝黑名单', '0', '1', '1', '2018-05-04 11:17:51');
INSERT INTO `system_node` VALUES ('90', 'wechat/keys', '微信关键字', '0', '1', '1', '2018-05-04 11:18:09');
INSERT INTO `system_node` VALUES ('91', 'wechat/keys/index', '关键字列表', '1', '1', '1', '2018-05-04 11:18:09');
INSERT INTO `system_node` VALUES ('92', 'wechat/keys/add', '添加关键字', '0', '1', '1', '2018-05-04 11:18:09');
INSERT INTO `system_node` VALUES ('93', 'wechat/keys/edit', '编辑关键字', '0', '1', '1', '2018-05-04 11:18:09');
INSERT INTO `system_node` VALUES ('94', 'wechat/keys/del', '删除关键字', '0', '1', '1', '2018-05-04 11:18:09');
INSERT INTO `system_node` VALUES ('95', 'wechat/keys/forbid', '禁用关键字', '0', '1', '1', '2018-05-04 11:18:09');
INSERT INTO `system_node` VALUES ('96', 'wechat/keys/resume', '启用关键字', '0', '1', '1', '2018-05-04 11:18:09');
INSERT INTO `system_node` VALUES ('97', 'wechat/keys/subscribe', '关注回复', '1', '1', '1', '2018-05-04 11:18:09');
INSERT INTO `system_node` VALUES ('98', 'wechat/keys/defaults', '默认回复', '1', '1', '1', '2018-05-04 11:18:09');
INSERT INTO `system_node` VALUES ('99', 'wechat/menu', '微信菜单管理', '0', '1', '1', '2018-05-04 11:18:57');
INSERT INTO `system_node` VALUES ('100', 'wechat/menu/index', '微信菜单展示', '1', '1', '1', '2018-05-04 11:19:10');
INSERT INTO `system_node` VALUES ('101', 'wechat/menu/edit', '编辑微信菜单', '0', '1', '1', '2018-05-04 11:19:22');
INSERT INTO `system_node` VALUES ('102', 'wechat/menu/cancel', '取消微信菜单', '0', '1', '1', '2018-05-04 11:19:26');
INSERT INTO `system_node` VALUES ('103', 'wechat/news/index', '微信图文列表', '1', '1', '1', '2018-05-04 11:19:28');
INSERT INTO `system_node` VALUES ('104', 'wechat/news/select', '微信图文选择', '0', '1', '1', '2018-05-04 11:19:28');
INSERT INTO `system_node` VALUES ('105', 'wechat/news/image', '微信图片选择', '0', '1', '1', '2018-05-04 11:19:28');
INSERT INTO `system_node` VALUES ('106', 'wechat/news/add', '添加微信图文', '0', '1', '1', '2018-05-04 11:19:28');
INSERT INTO `system_node` VALUES ('107', 'wechat/news/edit', '编辑微信图文', '0', '1', '1', '2018-05-04 11:19:28');
INSERT INTO `system_node` VALUES ('108', 'wechat/news/del', '删除微信图文', '0', '1', '1', '2018-05-04 11:19:28');
INSERT INTO `system_node` VALUES ('109', 'wechat/news/push', '推送微信图文', '0', '1', '1', '2018-05-04 11:19:28');
INSERT INTO `system_node` VALUES ('110', 'wechat/news', '微信图文管理', '0', '1', '1', '2018-05-04 11:19:35');
INSERT INTO `system_node` VALUES ('111', 'wechat/tags', '微信粉丝标签管理', '0', '1', '1', '2018-05-04 11:20:28');
INSERT INTO `system_node` VALUES ('112', 'wechat/tags/index', '粉丝标签列表', '1', '1', '1', '2018-05-04 11:20:28');
INSERT INTO `system_node` VALUES ('113', 'wechat/tags/add', '添加粉丝标签', '0', '1', '1', '2018-05-04 11:20:28');
INSERT INTO `system_node` VALUES ('114', 'wechat/tags/edit', '编辑粉丝标签', '0', '1', '1', '2018-05-04 11:20:29');
INSERT INTO `system_node` VALUES ('115', 'wechat/tags/del', '删除粉丝标签', '0', '1', '1', '2018-05-04 11:20:29');
INSERT INTO `system_node` VALUES ('116', 'wechat/tags/sync', '同步粉丝标签', '0', '1', '1', '2018-05-04 11:20:29');
INSERT INTO `system_node` VALUES ('117', 'store/goods', '商品管理', '0', '1', '1', '2018-05-04 11:29:55');
INSERT INTO `system_node` VALUES ('118', 'store/goods/index', '商品列表', '1', '1', '1', '2018-05-04 11:29:56');
INSERT INTO `system_node` VALUES ('119', 'store/goods/add', '添加商品', '0', '1', '1', '2018-05-04 11:29:56');
INSERT INTO `system_node` VALUES ('120', 'store/goods/edit', '编辑商品', '0', '1', '1', '2018-05-04 11:29:56');
INSERT INTO `system_node` VALUES ('121', 'store/goods/del', '删除商品', '0', '1', '1', '2018-05-04 11:29:56');
INSERT INTO `system_node` VALUES ('122', 'store/goods/forbid', '下架商品', '0', '1', '1', '2018-05-04 11:29:56');
INSERT INTO `system_node` VALUES ('123', 'store/goods/resume', '上架商品', '0', '1', '1', '2018-05-04 11:29:57');
INSERT INTO `system_node` VALUES ('124', 'store/goods_brand', '商品品牌管理', '0', '1', '1', '2018-05-04 11:30:44');
INSERT INTO `system_node` VALUES ('125', 'store/goods_brand/index', '商品品牌列表', '1', '1', '1', '2018-05-04 11:30:52');
INSERT INTO `system_node` VALUES ('126', 'store/goods_brand/add', '添加商品品牌', '0', '1', '1', '2018-05-04 11:30:55');
INSERT INTO `system_node` VALUES ('127', 'store/goods_brand/edit', '编辑商品品牌', '0', '1', '1', '2018-05-04 11:30:56');
INSERT INTO `system_node` VALUES ('128', 'store/goods_brand/del', '删除商品品牌', '0', '1', '1', '2018-05-04 11:30:56');
INSERT INTO `system_node` VALUES ('129', 'store/goods_brand/forbid', '禁用商品品牌', '0', '1', '1', '2018-05-04 11:30:56');
INSERT INTO `system_node` VALUES ('130', 'store/goods_brand/resume', '启用商品品牌', '0', '1', '1', '2018-05-04 11:30:56');
INSERT INTO `system_node` VALUES ('131', 'store/goods_cate', '商品分类管理', '0', '1', '1', '2018-05-04 11:31:19');
INSERT INTO `system_node` VALUES ('132', 'store/goods_cate/index', '商品分类列表', '1', '1', '1', '2018-05-04 11:31:23');
INSERT INTO `system_node` VALUES ('133', 'store/goods_cate/add', '添加商品分类', '0', '1', '1', '2018-05-04 11:31:23');
INSERT INTO `system_node` VALUES ('134', 'store/goods_cate/edit', '编辑商品分类', '0', '1', '1', '2018-05-04 11:31:23');
INSERT INTO `system_node` VALUES ('135', 'store/goods_cate/del', '删除商品分类', '0', '1', '1', '2018-05-04 11:31:24');
INSERT INTO `system_node` VALUES ('136', 'store/goods_cate/forbid', '禁用商品分类', '0', '1', '1', '2018-05-04 11:31:24');
INSERT INTO `system_node` VALUES ('137', 'store/goods_cate/resume', '启用商品分类', '0', '1', '1', '2018-05-04 11:31:24');
INSERT INTO `system_node` VALUES ('138', 'store/goods_spec', '商品规格管理', '0', '1', '1', '2018-05-04 11:31:47');
INSERT INTO `system_node` VALUES ('139', 'store/goods_spec/index', '商品规格列表', '1', '1', '1', '2018-05-04 11:31:47');
INSERT INTO `system_node` VALUES ('140', 'store/goods_spec/add', '添加商品规格', '0', '1', '1', '2018-05-04 11:31:47');
INSERT INTO `system_node` VALUES ('141', 'store/goods_spec/edit', '编辑商品规格', '0', '1', '1', '2018-05-04 11:31:48');
INSERT INTO `system_node` VALUES ('142', 'store/goods_spec/del', '删除商品规格', '0', '1', '1', '2018-05-04 11:31:48');
INSERT INTO `system_node` VALUES ('143', 'store/goods_spec/forbid', '禁用商品规格', '0', '1', '1', '2018-05-04 11:31:48');
INSERT INTO `system_node` VALUES ('144', 'store/goods_spec/resume', '启用商品规格', '0', '1', '1', '2018-05-04 11:31:48');
-- ----------------------------
-- Table structure for system_sequence
-- ----------------------------
DROP TABLE IF EXISTS `system_sequence`;
CREATE TABLE `system_sequence` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`type` varchar(20) DEFAULT NULL COMMENT '序号类型',
`sequence` char(50) NOT NULL COMMENT '序号值',
`create_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `index_system_sequence_unique` (`type`,`sequence`) USING BTREE,
KEY `index_system_sequence_type` (`type`),
KEY `index_system_sequence_number` (`sequence`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='系统序号表';
-- ----------------------------
-- Records of system_sequence
-- ----------------------------
-- ----------------------------
-- 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) NOT NULL DEFAULT '' COMMENT '用户登录名',
`password` char(32) NOT NULL DEFAULT '' COMMENT '用户登录密码',
`qq` varchar(16) DEFAULT NULL COMMENT '联系QQ',
`mail` varchar(32) DEFAULT NULL COMMENT '联系邮箱',
`phone` varchar(16) DEFAULT NULL COMMENT '联系手机号',
`desc` varchar(255) DEFAULT '' COMMENT '备注说明',
`login_num` bigint(20) unsigned DEFAULT '0' COMMENT '登录次数',
`login_at` datetime DEFAULT NULL,
`status` tinyint(1) unsigned NOT NULL DEFAULT '1' COMMENT '状态(0:禁用,1:启用)',
`authorize` varchar(255) DEFAULT NULL,
`is_deleted` tinyint(1) unsigned DEFAULT '0' COMMENT '删除状态(1:删除,0:未删)',
`create_by` bigint(20) unsigned DEFAULT NULL COMMENT '创建人',
`create_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
PRIMARY KEY (`id`),
UNIQUE KEY `index_system_user_username` (`username`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=utf8 COMMENT='系统用户表';
-- ----------------------------
-- Records of system_user
-- ----------------------------
INSERT INTO `system_user` VALUES ('10000', 'admin', '21232f297a57a5a743894a0e4a801fc3', '22222222', '', '', '', '22973', '2018-03-26 17:06:48', '1', '2,4', '0', null, '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` char(50) DEFAULT '' COMMENT '公众号Appid',
`unionid` char(100) DEFAULT '' COMMENT 'unionid',
`openid` char(100) DEFAULT '' COMMENT '用户的标识,对当前公众号唯一',
`spread_openid` char(100) DEFAULT '' COMMENT '推荐人OPENID',
`spread_at` datetime DEFAULT NULL COMMENT '推荐时间',
`tagid_list` varchar(100) DEFAULT '' COMMENT '标签id',
`is_black` tinyint(1) unsigned DEFAULT '0' COMMENT '是否为黑名单用户',
`subscribe` tinyint(1) unsigned DEFAULT '0' COMMENT '用户是否关注该公众号(0:未关注, 1:已关注)',
`nickname` varchar(200) DEFAULT '' COMMENT '用户的昵称',
`sex` tinyint(1) unsigned DEFAULT NULL COMMENT '用户的性别,值为1时是男性,值为2时是女性,值为0时是未知',
`country` varchar(50) DEFAULT '' COMMENT '用户所在国家',
`province` varchar(50) DEFAULT '' COMMENT '用户所在省份',
`city` varchar(50) DEFAULT '' COMMENT '用户所在城市',
`language` varchar(50) DEFAULT '' COMMENT '用户的语言,简体中文为zh_CN',
`headimgurl` varchar(500) DEFAULT '' COMMENT '用户头像',
`subscribe_time` bigint(20) unsigned DEFAULT '0' COMMENT '用户关注时间',
`subscribe_at` datetime DEFAULT NULL COMMENT '关注时间',
`remark` varchar(50) DEFAULT '' COMMENT '备注',
`expires_in` bigint(20) unsigned DEFAULT '0' COMMENT '有效时间',
`refresh_token` varchar(200) DEFAULT '' COMMENT '刷新token',
`access_token` varchar(200) DEFAULT '' COMMENT '访问token',
`subscribe_scene` varchar(200) DEFAULT '' COMMENT '扫码关注场景',
`qr_scene` varchar(100) DEFAULT '' COMMENT '二维码场景值',
`qr_scene_str` varchar(200) DEFAULT '' COMMENT '二维码场景内容',
`create_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
PRIMARY KEY (`id`),
KEY `index_wechat_fans_spread_openid` (`spread_openid`) USING BTREE,
KEY `index_wechat_fans_openid` (`openid`) USING BTREE,
KEY `index_wechat_fans_unionid` (`unionid`),
KEY `index_wechat_fans_is_back` (`is_black`),
KEY `index_wechat_fans_subscribe` (`subscribe`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='微信粉丝';
-- ----------------------------
-- Records of wechat_fans
-- ----------------------------
-- ----------------------------
-- 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` char(50) DEFAULT NULL COMMENT '公众号APPID',
`name` varchar(35) DEFAULT NULL COMMENT '标签名称',
`count` int(11) unsigned DEFAULT NULL COMMENT '总数',
`create_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建日期',
KEY `index_wechat_fans_tags_id` (`id`) USING BTREE,
KEY `index_wechat_fans_tags_appid` (`appid`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='微信会员标签';
-- ----------------------------
-- Records of wechat_fans_tags
-- ----------------------------
-- ----------------------------
-- 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) DEFAULT '' COMMENT '公众号APPID',
`type` varchar(20) DEFAULT '' COMMENT '类型text 文件消息image 图片消息news 图文消息',
`keys` varchar(100) DEFAULT NULL COMMENT '关键字',
`content` text COMMENT '文本内容',
`image_url` varchar(255) DEFAULT '' COMMENT '图片链接',
`voice_url` varchar(255) DEFAULT '' COMMENT '语音链接',
`music_title` varchar(100) DEFAULT '' COMMENT '音乐标题',
`music_url` varchar(255) DEFAULT '' COMMENT '音乐链接',
`music_image` varchar(255) DEFAULT '' COMMENT '音乐缩略图链接',
`music_desc` varchar(255) DEFAULT '' COMMENT '音乐描述',
`video_title` varchar(100) DEFAULT '' COMMENT '视频标题',
`video_url` varchar(255) DEFAULT '' COMMENT '视频URL',
`video_desc` varchar(255) DEFAULT '' COMMENT '视频描述',
`news_id` bigint(20) unsigned DEFAULT NULL COMMENT '图文ID',
`sort` bigint(20) unsigned DEFAULT '0' COMMENT '排序字段',
`status` tinyint(1) unsigned DEFAULT '1' COMMENT '0 禁用1 启用',
`create_by` bigint(20) unsigned DEFAULT NULL COMMENT '创建人',
`create_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '创建时间',
PRIMARY KEY (`id`),
KEY `index_wechat_keys_appid` (`appid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='微信关键字';
-- ----------------------------
-- Records of wechat_keys
-- ----------------------------
-- ----------------------------
-- Table structure for wechat_menu
-- ----------------------------
DROP TABLE IF EXISTS `wechat_menu`;
CREATE TABLE `wechat_menu` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`index` bigint(20) DEFAULT NULL,
`pindex` bigint(20) unsigned NOT NULL DEFAULT '0' COMMENT '父id',
`type` varchar(24) NOT NULL DEFAULT '' COMMENT '菜单类型 null主菜单 link链接 keys关键字',
`name` varchar(256) NOT NULL DEFAULT '' COMMENT '菜单名称',
`content` text NOT NULL COMMENT '文字内容',
`sort` bigint(20) unsigned DEFAULT '0' COMMENT '排序',
`status` tinyint(1) unsigned DEFAULT '1' COMMENT '状态(0禁用1启用)',
`create_by` bigint(20) unsigned NOT NULL DEFAULT '0' COMMENT '创建人',
`create_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
PRIMARY KEY (`id`),
KEY `index_wechat_menu_pindex` (`pindex`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='微信菜单配置';
-- ----------------------------
-- Records of wechat_menu
-- ----------------------------
-- ----------------------------
-- 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) DEFAULT '' COMMENT '永久素材MediaID',
`local_url` varchar(300) DEFAULT '' COMMENT '永久素材显示URL',
`article_id` varchar(60) DEFAULT '' COMMENT '关联图文ID号做分割',
`is_deleted` tinyint(1) unsigned DEFAULT '0' COMMENT '是否删除',
`create_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`create_by` bigint(20) DEFAULT NULL COMMENT '创建人',
PRIMARY KEY (`id`),
KEY `index_wechat_news_artcle_id` (`article_id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='微信图文表';
-- ----------------------------
-- Records of wechat_news
-- ----------------------------
-- ----------------------------
-- 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) DEFAULT '' COMMENT '素材标题',
`local_url` varchar(300) DEFAULT '' COMMENT '永久素材显示URL',
`show_cover_pic` tinyint(4) unsigned DEFAULT '0' COMMENT '是否显示封面 0不显示1 显示',
`author` varchar(20) DEFAULT '' COMMENT '作者',
`digest` varchar(300) DEFAULT '' COMMENT '摘要内容',
`content` longtext COMMENT '图文内容',
`content_source_url` varchar(200) DEFAULT '' COMMENT '图文消息原文地址',
`create_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`create_by` bigint(20) DEFAULT NULL COMMENT '创建人',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='微信素材表';
-- ----------------------------
-- Records of wechat_news_article
-- ----------------------------
-- ----------------------------
-- Table structure for wechat_news_image
-- ----------------------------
DROP TABLE IF EXISTS `wechat_news_image`;
CREATE TABLE `wechat_news_image` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`md5` varchar(32) DEFAULT '' COMMENT '文件md5',
`local_url` varchar(300) DEFAULT '' COMMENT '本地文件链接',
`media_url` varchar(300) DEFAULT '' COMMENT '远程图片链接',
`create_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
PRIMARY KEY (`id`),
KEY `index_wechat_news_image_md5` (`md5`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='微信服务器图片';
-- ----------------------------
-- Records of wechat_news_image
-- ----------------------------
-- ----------------------------
-- Table structure for wechat_news_media
-- ----------------------------
DROP TABLE IF EXISTS `wechat_news_media`;
CREATE TABLE `wechat_news_media` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`appid` varchar(100) DEFAULT '' COMMENT '公众号ID',
`md5` varchar(32) DEFAULT '' COMMENT '文件md5',
`type` varchar(20) DEFAULT '' COMMENT '媒体类型',
`media_id` varchar(100) DEFAULT '' COMMENT '永久素材MediaID',
`local_url` varchar(300) DEFAULT '' COMMENT '本地文件链接',
`media_url` varchar(300) DEFAULT '' COMMENT '远程图片链接',
`create_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 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 DEFAULT '0' COMMENT '商品ID',
`goods_spec` varchar(255) DEFAULT '' COMMENT '商品属性',
`goods_stock` bigint(20) unsigned DEFAULT '0' COMMENT '商品库存',
`stock_desc` varchar(255) DEFAULT '' COMMENT '商品库存描述',
`sort` bigint(20) unsigned DEFAULT '0' COMMENT '数据排序',
`status` bigint(1) unsigned DEFAULT '1' COMMENT '商品状态(1有效,0无效)',
`is_deleted` bigint(1) unsigned DEFAULT '0' COMMENT '删除状态(1删除,0未删除)',
`create_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=36 DEFAULT CHARSET=utf8 COMMENT='商城商品库存';
-- ----------------------------
-- Records of wechat_news_media
-- ----------------------------

1
application/.htaccess Normal file
View File

@ -0,0 +1 @@
deny from all

View File

@ -1,7 +1,7 @@
<?php
// +----------------------------------------------------------------------
// | Think.Admin
// | ThinkAdmin
// +----------------------------------------------------------------------
// | 版权所有 2014~2017 广州楚才信息科技有限公司 [ http://www.cuci.cc ]
// +----------------------------------------------------------------------
@ -9,7 +9,7 @@
// +----------------------------------------------------------------------
// | 开源协议 ( https://mit-license.org )
// +----------------------------------------------------------------------
// | github开源项目https://github.com/zoujingli/Think.Admin
// | github开源项目https://github.com/zoujingli/ThinkAdmin
// +----------------------------------------------------------------------
namespace app\admin\controller;
@ -27,7 +27,8 @@ use think\Db;
* @author Anyon <zoujingli@qq.com>
* @date 2017/02/15 18:13
*/
class Auth extends BasicAdmin {
class Auth extends BasicAdmin
{
/**
* 默认数据模型
@ -37,44 +38,67 @@ class Auth extends BasicAdmin {
/**
* 权限列表
* @return array|string
* @throws \think\Exception
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
public function index() {
public function index()
{
$this->title = '系统权限管理';
return parent::_list($this->table);
}
/**
* 权限授权
* @return string|array
* @return string
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
* @throws \think\Exception
*/
public function apply() {
public function apply()
{
$this->title = '节点授权';
$auth_id = $this->request->get('id', '0');
switch (strtolower($this->request->get('action', '0'))) {
case 'getnode':
$nodes = NodeService::get();
$checked = Db::name('SystemAuthNode')->where('auth', $auth_id)->column('node');
foreach ($nodes as $key => &$node) {
$node['checked'] = in_array($node['node'], $checked);
if (empty($node['is_auth']) && substr_count($node['node'], '/') > 1) {
unset($nodes[$key]);
}
}
$this->success('获取节点成功!', '', $this->_filterNodes($this->_filterNodes(ToolsService::arr2tree($nodes, 'node', 'pnode', '_sub_'))));
break;
case 'save':
$data = [];
$post = $this->request->post();
foreach (isset($post['nodes']) ? $post['nodes'] : [] as $node) {
$data[] = ['auth' => $auth_id, 'node' => $node];
}
Db::name('SystemAuthNode')->where('auth', $auth_id)->delete();
Db::name('SystemAuthNode')->insertAll($data);
$this->success('节点授权更新成功!', '');
break;
default :
$this->assign('title', '节点授权');
return $this->_form($this->table, 'apply');
$method = '_apply_' . strtolower($this->request->get('action', '0'));
if (method_exists($this, $method)) {
return $this->$method($auth_id);
}
return $this->_form($this->table, 'apply');
}
/**
* 读取授权节点
* @param string $auth
*/
protected function _apply_getnode($auth)
{
$nodes = NodeService::get();
$checked = Db::name('SystemAuthNode')->where(['auth' => $auth])->column('node');
foreach ($nodes as &$node) {
$node['checked'] = in_array($node['node'], $checked);
}
$all = $this->_apply_filter(ToolsService::arr2tree($nodes, 'node', 'pnode', '_sub_'));
$this->success('获取节点成功!', '', $all);
}
/**
* 保存授权节点
* @param string $auth
* @throws \think\Exception
* @throws \think\exception\PDOException
*/
protected function _apply_save($auth)
{
list($data, $post) = [[], $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);
$this->success('节点授权更新成功!', '');
}
/**
@ -83,12 +107,11 @@ class Auth extends BasicAdmin {
* @param int $level
* @return array
*/
protected function _filterNodes($nodes, $level = 1) {
foreach ($nodes as $key => &$node) {
protected function _apply_filter($nodes, $level = 1)
{
foreach ($nodes as $key => $node) {
if (!empty($node['_sub_']) && is_array($node['_sub_'])) {
$node['_sub_'] = $this->_filterNodes($node['_sub_'], $level + 1);
} elseif ($level < 3) {
unset($nodes[$key]);
$node[$key]['_sub_'] = $this->_apply_filter($node['_sub_'], $level + 1);
}
}
return $nodes;
@ -96,22 +119,37 @@ class Auth extends BasicAdmin {
/**
* 权限添加
* @return array|string
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
* @throws \think\Exception
*/
public function add() {
public function add()
{
return $this->_form($this->table, 'form');
}
/**
* 权限编辑
* @return array|string
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
* @throws \think\Exception
*/
public function edit() {
public function edit()
{
return $this->_form($this->table, 'form');
}
/**
* 权限禁用
* @throws \think\Exception
* @throws \think\exception\PDOException
*/
public function forbid() {
public function forbid()
{
if (DataService::update($this->table)) {
$this->success("权限禁用成功!", '');
}
@ -120,8 +158,11 @@ class Auth extends BasicAdmin {
/**
* 权限恢复
* @throws \think\Exception
* @throws \think\exception\PDOException
*/
public function resume() {
public function resume()
{
if (DataService::update($this->table)) {
$this->success("权限启用成功!", '');
}
@ -130,11 +171,14 @@ class Auth extends BasicAdmin {
/**
* 权限删除
* @throws \think\Exception
* @throws \think\exception\PDOException
*/
public function del() {
public function del()
{
if (DataService::update($this->table)) {
$id = $this->request->post('id');
Db::name('SystemAuthNode')->where('auth', $id)->delete();
$where = ['auth' => $this->request->post('id')];
Db::name('SystemAuthNode')->where($where)->delete();
$this->success("权限删除成功!", '');
}
$this->error("权限删除失败,请稍候再试!");

View File

@ -1,7 +1,7 @@
<?php
// +----------------------------------------------------------------------
// | Think.Admin
// | ThinkAdmin
// +----------------------------------------------------------------------
// | 版权所有 2014~2017 广州楚才信息科技有限公司 [ http://www.cuci.cc ]
// +----------------------------------------------------------------------
@ -9,13 +9,14 @@
// +----------------------------------------------------------------------
// | 开源协议 ( https://mit-license.org )
// +----------------------------------------------------------------------
// | github开源项目https://github.com/zoujingli/Think.Admin
// | github开源项目https://github.com/zoujingli/ThinkAdmin
// +----------------------------------------------------------------------
namespace app\admin\controller;
use controller\BasicAdmin;
use service\LogService;
use service\WechatService;
/**
* 后台参数配置控制器
@ -24,7 +25,8 @@ use service\LogService;
* @author Anyon <zoujingli@qq.com>
* @date 2017/02/15 18:05
*/
class Config extends BasicAdmin {
class Config extends BasicAdmin
{
/**
* 当前默认数据模型
@ -36,32 +38,36 @@ class Config extends BasicAdmin {
* 当前页面标题
* @var string
*/
public $title = '网站参数配置';
public $title = '系统参数配置';
/**
* 显示系统常规配置
* @return string
* @throws \think\Exception
* @throws \think\exception\PDOException
*/
public function index() {
if (!$this->request->isPost()) {
$this->assign('title', $this->title);
return view();
public function index()
{
if ($this->request->isGet()) {
return $this->fetch('', ['title' => $this->title]);
}
foreach ($this->request->post() as $key => $vo) {
sysconf($key, $vo);
if ($this->request->isPost()) {
foreach ($this->request->post() as $key => $vo) {
sysconf($key, $vo);
}
LogService::write('系统管理', '系统参数配置成功');
$this->success('系统参数配置成功!', '');
}
LogService::write('系统管理', '修改系统配置参数成功');
$this->success('数据修改成功!', '');
}
/**
* 文件存储配置
* @return string
* @throws \think\Exception
* @throws \think\exception\PDOException
*/
public function file() {
$this->assign('alert', [
'type' => 'success',
'title' => '操作提示',
'content' => '文件引擎参数影响全局文件上传功能,请勿随意修改!'
]);
public function file()
{
$this->title = '文件存储配置';
return $this->index();
}

View File

@ -1,7 +1,7 @@
<?php
// +----------------------------------------------------------------------
// | Think.Admin
// | ThinkAdmin
// +----------------------------------------------------------------------
// | 版权所有 2014~2017 广州楚才信息科技有限公司 [ http://www.cuci.cc ]
// +----------------------------------------------------------------------
@ -9,7 +9,7 @@
// +----------------------------------------------------------------------
// | 开源协议 ( https://mit-license.org )
// +----------------------------------------------------------------------
// | github开源项目https://github.com/zoujingli/Think.Admin
// | github开源项目https://github.com/zoujingli/ThinkAdmin
// +----------------------------------------------------------------------
namespace app\admin\controller;
@ -18,8 +18,8 @@ use controller\BasicAdmin;
use service\DataService;
use service\NodeService;
use service\ToolsService;
use think\App;
use think\Db;
use think\View;
/**
* 后台入口
@ -28,37 +28,49 @@ use think\View;
* @author Anyon <zoujingli@qq.com>
* @date 2017/02/15 10:41
*/
class Index extends BasicAdmin {
class Index extends BasicAdmin
{
/**
* 后台框架布局
* @return View
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
public function index() {
public function index()
{
NodeService::applyAuthNode();
$list = Db::name('SystemMenu')->where('status', '1')->order('sort asc,id asc')->select();
$menus = $this->_filterMenu(ToolsService::arr2tree($list));
$this->assign('title', '系统管理');
$this->assign('menus', $menus);
return view();
$list = (array)Db::name('SystemMenu')->where(['status' => '1'])->order('sort asc,id asc')->select();
$menus = $this->buildMenuData(ToolsService::arr2tree($list), NodeService::get(), !!session('user'));
if (empty($menus) && !session('user.id')) {
$this->redirect('@admin/login');
}
return $this->fetch('', ['title' => '系统管理', 'menus' => $menus]);
}
/**
* 后台主菜单权限过滤
* @param array $menus
* @param array $menus 当前菜单列表
* @param array $nodes 系统权限节点数据
* @param bool $isLogin 是否已经登录
* @return array
*/
private function _filterMenu($menus) {
private function buildMenuData($menus, $nodes, $isLogin)
{
foreach ($menus as $key => &$menu) {
if (!empty($menu['sub'])) {
$menu['sub'] = $this->_filterMenu($menu['sub']);
}
!empty($menu['sub']) && $menu['sub'] = $this->buildMenuData($menu['sub'], $nodes, $isLogin);
if (!empty($menu['sub'])) {
$menu['url'] = '#';
} elseif (stripos($menu['url'], 'http') === 0) {
} elseif (preg_match('/^https?\:/i', $menu['url'])) {
continue;
} elseif ($menu['url'] !== '#' && auth(join('/', array_slice(explode('/', $menu['url']), 0, 3)))) {
$menu['url'] = url($menu['url']);
} elseif ($menu['url'] !== '#') {
$node = join('/', array_slice(explode('/', preg_replace('/[\W]/', '/', $menu['url'])), 0, 3));
$menu['url'] = url($menu['url']) . (empty($menu['params']) ? '' : "?{$menu['params']}");
if (isset($nodes[$node]) && $nodes[$node]['is_login'] && empty($isLogin)) {
unset($menus[$key]);
} elseif (isset($nodes[$node]) && $nodes[$node]['is_auth'] && $isLogin && !auth($node)) {
unset($menus[$key]);
}
} else {
unset($menus[$key]);
}
@ -68,66 +80,64 @@ class Index extends BasicAdmin {
/**
* 主机信息显示
* @return View
* @return string
*/
public function main() {
public function main()
{
$_version = Db::query('select version() as ver');
$version = array_pop($_version);
$this->assign('mysql_ver', $version['ver']);
if (session('user.username') === 'admin' && session('user.password') === '21232f297a57a5a743894a0e4a801fc3') {
$url = url('admin/index/pass') . '?id=' . session('user.id');
$alert = [
'type' => 'danger',
'title' => '安全提示',
'content' => "超级管理员默认密码未修改,建议马上<a href='javascript:void(0)' data-modal='{$url}'>修改</a>"
];
$this->assign('alert', $alert);
$this->assign('title', '后台首页');
}
return view();
return $this->fetch('', [
'title' => '后台首页',
'think_ver' => App::VERSION,
'mysql_ver' => array_pop($_version)['ver'],
]);
}
/**
* 修改密码
* @return array|string
* @throws \think\Exception
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
* @throws \think\exception\PDOException
*/
public function pass() {
if (in_array('10000', explode(',', $this->request->post('id')))) {
$this->error('系统超级账号禁止操作!');
}
public function pass()
{
if (intval($this->request->request('id')) !== intval(session('user.id'))) {
$this->error('访问异常');
$this->error('只能修改当前用户的密码!');
}
if ($this->request->isGet()) {
$this->assign('verify', true);
return $this->_form('SystemUser', 'user/pass');
} else {
$data = $this->request->post();
if ($data['password'] !== $data['repassword']) {
$this->error('两次输入的密码不一致,请重新输入!');
}
$user = Db::name('SystemUser')->where('id', session('user.id'))->find();
if (md5($data['oldpassword']) !== $user['password']) {
$this->error('旧密码验证失败,请重新输入!');
}
if (DataService::save('SystemUser', ['id' => session('user.id'), 'password' => md5($data['password'])])) {
$this->success('密码修改成功,下次请使用新密码登录!', '');
} else {
$this->error('密码修改失败,请稍候再试!');
}
}
$data = $this->request->post();
if ($data['password'] !== $data['repassword']) {
$this->error('两次输入的密码不一致,请重新输入!');
}
$user = Db::name('SystemUser')->where('id', session('user.id'))->find();
if (md5($data['oldpassword']) !== $user['password']) {
$this->error('旧密码验证失败,请重新输入!');
}
if (DataService::save('SystemUser', ['id' => session('user.id'), 'password' => md5($data['password'])])) {
$this->success('密码修改成功,下次请使用新密码登录!', '');
}
$this->error('密码修改失败,请稍候再试!');
}
/**
* 修改资料
* @return array|string
* @throws \think\Exception
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
public function info() {
if (in_array('10000', explode(',', $this->request->post('id')))) {
$this->error('系统超级账号禁止操作!');
}
public function info()
{
if (intval($this->request->request('id')) === intval(session('user.id'))) {
return $this->_form('SystemUser', 'user/form');
}
$this->error('访问异常');
$this->error('只能修改当前用户的资料');
}
}

View File

@ -1,7 +1,7 @@
<?php
// +----------------------------------------------------------------------
// | Think.Admin
// | ThinkAdmin
// +----------------------------------------------------------------------
// | 版权所有 2014~2017 广州楚才信息科技有限公司 [ http://www.cuci.cc ]
// +----------------------------------------------------------------------
@ -9,7 +9,7 @@
// +----------------------------------------------------------------------
// | 开源协议 ( https://mit-license.org )
// +----------------------------------------------------------------------
// | github开源项目https://github.com/zoujingli/Think.Admin
// | github开源项目https://github.com/zoujingli/ThinkAdmin
// +----------------------------------------------------------------------
namespace app\admin\controller;
@ -20,12 +20,13 @@ use think\Db;
/**
* 系统日志管理
* Class User
* Class Log
* @package app\admin\controller
* @author Anyon <zoujingli@qq.com>
* @date 2017/02/15 18:12
*/
class Log extends BasicAdmin {
class Log extends BasicAdmin
{
/**
* 指定当前数据表
@ -35,41 +36,56 @@ class Log extends BasicAdmin {
/**
* 日志列表
* @return array|string
* @throws \think\Exception
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
public function index() {
$this->title = '系统操作日志';
$this->assign('actions', Db::name($this->table)->group('action')->column('action'));
public function index()
{
// 日志行为类别
$actions = Db::name($this->table)->group('action')->column('action');
$this->assign('actions', $actions);
// 日志数据库对象
list($this->title, $get) = ['系统操作日志', $this->request->get()];
$db = Db::name($this->table)->order('id desc');
$get = $this->request->get();
foreach (['action', 'content', 'username'] as $key) {
if (isset($get[$key]) && $get[$key] !== '') {
$db->where($key, 'like', "%{$get[$key]}%");
}
(isset($get[$key]) && $get[$key] !== '') && $db->whereLike($key, "%{$get[$key]}%");
}
if (isset($get['create_at']) && $get['create_at'] !== '') {
list($start, $end) = explode(' - ', $get['create_at']);
$db->whereBetween('create_at', ["{$start} 00:00:00", "{$end} 23:59:59"]);
}
return parent::_list($db);
}
/**
* 列表数据处理
* @param $data
* @param array $data
* @throws \Exception
*/
protected function _index_data_filter(&$data) {
protected function _index_data_filter(&$data)
{
$ip = new \Ip2Region();
foreach ($data as &$vo) {
$result = $ip->btreeSearch($vo['ip']);
$vo['isp'] = isset($result['region']) ? $result['region'] : '';
$vo['isp'] = str_replace(['|0|0|0|0', '|'], ['', ' '], $vo['isp']);
$vo['isp'] = str_replace(['内网IP', '0', '|'], '', $vo['isp']);
}
}
/**
* 日志删除操作
* @throws \think\Exception
* @throws \think\exception\PDOException
*/
public function del() {
public function del()
{
if (DataService::update($this->table)) {
$this->success("日志删除成功", '');
$this->success("日志删除成功!", '');
}
$this->error("日志删除失败,请稍候再试!");
$this->error("日志删除失败, 请稍候再试!");
}
}

View File

@ -1,7 +1,7 @@
<?php
// +----------------------------------------------------------------------
// | Think.Admin
// | ThinkAdmin
// +----------------------------------------------------------------------
// | 版权所有 2014~2017 广州楚才信息科技有限公司 [ http://www.cuci.cc ]
// +----------------------------------------------------------------------
@ -9,7 +9,7 @@
// +----------------------------------------------------------------------
// | 开源协议 ( https://mit-license.org )
// +----------------------------------------------------------------------
// | github开源项目https://github.com/zoujingli/Think.Admin
// | github开源项目https://github.com/zoujingli/ThinkAdmin
// +----------------------------------------------------------------------
namespace app\admin\controller;
@ -18,6 +18,8 @@ use controller\BasicAdmin;
use service\LogService;
use service\NodeService;
use think\Db;
use think\facade\Validate;
/**
* 系统登录控制器
@ -26,25 +28,15 @@ use think\Db;
* @author Anyon <zoujingli@qq.com>
* @date 2017/02/10 13:59
*/
class Login extends BasicAdmin {
/**
* 默认检查用户登录状态
* @var bool
*/
public $checkLogin = false;
/**
* 默认检查节点访问权限
* @var bool
*/
public $checkAuth = false;
class Login extends BasicAdmin
{
/**
* 控制器基础方法
*/
public function _initialize() {
if (session('user') && $this->request->action() !== 'out') {
public function initialize()
{
if (session('user.id') && $this->request->action() !== 'out') {
$this->redirect('@admin');
}
}
@ -52,34 +44,56 @@ class Login extends BasicAdmin {
/**
* 用户登录
* @return string
* @throws \think\Exception
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
* @throws \think\exception\PDOException
*/
public function index() {
public function index()
{
if ($this->request->isGet()) {
$this->assign('title', '用户登录');
return $this->fetch();
} else {
$username = $this->request->post('username', '', 'trim');
$password = $this->request->post('password', '', 'trim');
(empty($username) || strlen($username) < 4) && $this->error('登录账号长度不能少于4位有效字符!');
(empty($password) || strlen($password) < 4) && $this->error('登录密码长度不能少于4位有效字符!');
$user = Db::name('SystemUser')->where('username', $username)->find();
empty($user) && $this->error('登录账号不存在,请重新输入!');
($user['password'] !== md5($password)) && $this->error('登录密码与账号不匹配,请重新输入!');
Db::name('SystemUser')->where('id', $user['id'])->update(['login_at' => ['exp', 'now()'], 'login_num' => ['exp', 'login_num+1']]);
session('user', $user);
!empty($user['authorize']) && NodeService::applyAuthNode();
LogService::write('系统管理', '用户登录系统成功');
$this->success('登录成功,正在进入系统...', '@admin');
return $this->fetch('', ['title' => '用户登录']);
}
// 输入数据效验
$validate = Validate::make([
'username' => 'require|min:4',
'password' => 'require|min:4',
], [
'username.require' => '登录账号不能为空!',
'username.min' => '登录账号长度不能少于4位有效字符',
'password.require' => '登录密码不能为空!',
'password.min' => '登录密码长度不能少于4位有效字符',
]);
$data = [
'username' => $this->request->post('username', ''),
'password' => $this->request->post('password', ''),
];
$validate->check($data) || $this->error($validate->getError());
// 用户信息验证
$user = Db::name('SystemUser')->where(['username' => $data['username'], 'is_deleted' => '0'])->find();
empty($user) && $this->error('登录账号不存在,请重新输入!');
empty($user['status']) && $this->error('账号已经被禁用,请联系管理员!');
$user['password'] !== md5($data['password']) && $this->error('登录密码错误,请重新输入!');
// 更新登录信息
Db::name('SystemUser')->where(['id' => $user['id']])->update([
'login_at' => Db::raw('now()'),
'login_num' => Db::raw('login_num+1'),
]);
session('user', $user);
!empty($user['authorize']) && NodeService::applyAuthNode();
LogService::write('系统管理', '用户登录系统成功');
$this->success('登录成功,正在进入系统...', '@admin');
}
/**
* 退出登录
*/
public function out() {
LogService::write('系统管理', '用户退出系统成功');
session('user', null);
session_destroy();
public function out()
{
session('user') && LogService::write('系统管理', '用户退出系统成功');
!empty($_SESSION) && $_SESSION = [];
[session_unset(), session_destroy()];
$this->success('退出登录成功!', '@admin/login');
}

View File

@ -1,7 +1,7 @@
<?php
// +----------------------------------------------------------------------
// | Think.Admin
// | ThinkAdmin
// +----------------------------------------------------------------------
// | 版权所有 2014~2017 广州楚才信息科技有限公司 [ http://www.cuci.cc ]
// +----------------------------------------------------------------------
@ -9,7 +9,7 @@
// +----------------------------------------------------------------------
// | 开源协议 ( https://mit-license.org )
// +----------------------------------------------------------------------
// | github开源项目https://github.com/zoujingli/Think.Admin
// | github开源项目https://github.com/zoujingli/ThinkAdmin
// +----------------------------------------------------------------------
namespace app\admin\controller;
@ -27,7 +27,8 @@ use think\Db;
* @author Anyon <zoujingli@qq.com>
* @date 2017/02/15
*/
class Menu extends BasicAdmin {
class Menu extends BasicAdmin
{
/**
* 绑定操作模型
@ -37,9 +38,15 @@ class Menu extends BasicAdmin {
/**
* 菜单列表
* @return array|string
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
* @throws \think\Exception
*/
public function index() {
$this->title = '系统菜单管理';
public function index()
{
$this->title = '后台菜单管理';
$db = Db::name($this->table)->order('sort asc,id asc');
return parent::_list($db, false);
}
@ -48,9 +55,12 @@ class Menu extends BasicAdmin {
* 列表数据处理
* @param array $data
*/
protected function _index_data_filter(&$data) {
protected function _index_data_filter(&$data)
{
foreach ($data as &$vo) {
($vo['url'] !== '#') && ($vo['url'] = url($vo['url']));
if ($vo['url'] !== '#') {
$vo['url'] = url($vo['url']) . (empty($vo['params']) ? '' : "?{$vo['params']}");
}
$vo['ids'] = join(',', ToolsService::getArrSubIds($data, $vo['id']));
}
$data = ToolsService::arr2table($data);
@ -58,26 +68,42 @@ class Menu extends BasicAdmin {
/**
* 添加菜单
* @return array|string
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
* @throws \think\Exception
*/
public function add() {
public function add()
{
return $this->_form($this->table, 'form');
}
/**
* 编辑菜单
* @return array|string
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
* @throws \think\Exception
*/
public function edit() {
public function edit()
{
return $this->_form($this->table, 'form');
}
/**
* 表单数据前缀方法
* @param array $vo
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
protected function _form_filter(&$vo) {
protected function _form_filter(&$vo)
{
if ($this->request->isGet()) {
// 上级菜单处理
$_menus = Db::name($this->table)->where('status', '1')->order('sort desc,id desc')->select();
$_menus = Db::name($this->table)->where(['status' => '1'])->order('sort asc,id asc')->select();
$_menus[] = ['title' => '顶级菜单', 'id' => '0', 'pid' => '-1'];
$menus = ToolsService::arr2table($_menus);
foreach ($menus as $key => &$menu) {
@ -89,49 +115,62 @@ class Menu extends BasicAdmin {
$current_path = "-{$vo['pid']}-{$vo['id']}";
if ($vo['pid'] !== '' && (stripos("{$menu['path']}-", "{$current_path}-") !== false || $menu['path'] === $current_path)) {
unset($menus[$key]);
continue;
}
}
}
// 读取系统功能节点
$nodes = NodeService::get();
foreach ($nodes as $key => $_vo) {
if (empty($_vo['is_menu'])) {
foreach ($nodes as $key => $node) {
if (empty($node['is_menu'])) {
unset($nodes[$key]);
}
}
$this->assign('nodes', array_column($nodes, 'node'));
$this->assign('menus', $menus);
// 设置上级菜单
if (!isset($vo['pid']) && $this->request->get('pid', '0')) {
$vo['pid'] = $this->request->get('pid', '0');
}
$this->assign(['nodes' => array_column($nodes, 'node'), 'menus' => $menus]);
}
}
/**
* 删除菜单
* @throws \think\Exception
* @throws \think\exception\PDOException
*/
public function del() {
public function del()
{
if (DataService::update($this->table)) {
$this->success("菜单删除成功", '');
$this->success("菜单删除成功!", '');
}
$this->error("菜单删除失败,请稍候再试!");
$this->error("菜单删除失败, 请稍候再试!");
}
/**
* 菜单禁用
* @throws \think\Exception
* @throws \think\exception\PDOException
*/
public function forbid() {
public function forbid()
{
if (DataService::update($this->table)) {
$this->success("菜单禁用成功", '');
$this->success("菜单禁用成功!", '');
}
$this->error("菜单禁用失败,请稍候再试!");
$this->error("菜单禁用失败, 请稍候再试!");
}
/**
* 菜单禁用
* @throws \think\Exception
* @throws \think\exception\PDOException
*/
public function resume() {
public function resume()
{
if (DataService::update($this->table)) {
$this->success("菜单启用成功", '');
$this->success("菜单启用成功!", '');
}
$this->error("菜单启用失败,请稍候再试!");
$this->error("菜单启用失败, 请稍候再试!");
}
}

View File

@ -1,7 +1,7 @@
<?php
// +----------------------------------------------------------------------
// | Think.Admin
// | ThinkAdmin
// +----------------------------------------------------------------------
// | 版权所有 2014~2017 广州楚才信息科技有限公司 [ http://www.cuci.cc ]
// +----------------------------------------------------------------------
@ -9,7 +9,7 @@
// +----------------------------------------------------------------------
// | 开源协议 ( https://mit-license.org )
// +----------------------------------------------------------------------
// | github开源项目https://github.com/zoujingli/Think.Admin
// | github开源项目https://github.com/zoujingli/ThinkAdmin
// +----------------------------------------------------------------------
namespace app\admin\controller;
@ -18,6 +18,7 @@ use controller\BasicAdmin;
use service\DataService;
use service\NodeService;
use service\ToolsService;
use think\Db;
/**
* 系统功能节点管理
@ -26,7 +27,8 @@ use service\ToolsService;
* @author Anyon <zoujingli@qq.com>
* @date 2017/02/15 18:13
*/
class Node extends BasicAdmin {
class Node extends BasicAdmin
{
/**
* 指定当前默认模型
@ -36,34 +38,55 @@ class Node extends BasicAdmin {
/**
* 显示节点列表
* @return string
*/
public function index() {
$this->assign('alert', [
'type' => 'danger',
'title' => '安全警告',
'content' => '结构为系统自动生成,状态数据请勿随意修改!'
]);
$this->assign('title', '系统节点管理');
$this->assign('nodes', ToolsService::arr2table(NodeService::get(), 'node', 'pnode'));
return view();
public function index()
{
$nodes = ToolsService::arr2table(NodeService::get(), 'node', 'pnode');
$groups = [];
foreach ($nodes as $node) {
$pnode = explode('/', $node['node'])[0];
if ($node['node'] === $pnode) {
$groups[$pnode]['node'] = $node;
}
$groups[$pnode]['list'][] = $node;
}
return $this->fetch('', ['title' => '系统节点管理', 'nodes' => $nodes, 'groups' => $groups]);
}
/**
* 清理无效的节点记录
* @throws \think\Exception
* @throws \think\exception\PDOException
*/
public function clear()
{
$nodes = array_keys(NodeService::get());
if (false !== Db::name($this->table)->whereNotIn('node', $nodes)->delete()) {
$this->success('清理无效节点记录成功!', '');
}
$this->error('清理无效记录失败,请稍候再试!');
}
/**
* 保存节点变更
* @throws \think\Exception
* @throws \think\exception\PDOException
*/
public function save() {
public function save()
{
if ($this->request->isPost()) {
$post = $this->request->post();
if (isset($post['name']) && isset($post['value'])) {
$nameattr = explode('.', $post['name']);
$field = array_shift($nameattr);
$data = ['node' => join(',', $nameattr), $field => $post['value']];
DataService::save($this->table, $data, 'node');
$this->success('参数保存成功!', '');
list($post, $data) = [$this->request->post(), []];
foreach ($post['list'] as $vo) {
if (!empty($vo['node'])) {
$data['node'] = $vo['node'];
$data[$vo['name']] = $vo['value'];
}
}
} else {
$this->error('访问异常,请重新进入...');
!empty($data) && DataService::save($this->table, $data, 'node');
$this->success('参数保存成功!', '');
}
$this->error('访问异常,请重新进入...');
}
}

View File

@ -1,7 +1,7 @@
<?php
// +----------------------------------------------------------------------
// | Think.Admin
// | ThinkAdmin
// +----------------------------------------------------------------------
// | 版权所有 2014~2017 广州楚才信息科技有限公司 [ http://www.cuci.cc ]
// +----------------------------------------------------------------------
@ -9,14 +9,13 @@
// +----------------------------------------------------------------------
// | 开源协议 ( https://mit-license.org )
// +----------------------------------------------------------------------
// | github开源项目https://github.com/zoujingli/Think.Admin
// | github开源项目https://github.com/zoujingli/ThinkAdmin
// +----------------------------------------------------------------------
namespace app\admin\controller;
use controller\BasicAdmin;
use service\FileService;
use think\View;
/**
* 插件助手控制器
@ -25,119 +24,129 @@ use think\View;
* @author Anyon <zoujingli@qq.com>
* @date 2017/02/21
*/
class Plugs extends BasicAdmin {
/**
* 默认检查用户登录状态
* @var bool
*/
public $checkLogin = false;
/**
* 默认检查节点访问权限
* @var bool
*/
public $checkAuth = false;
class Plugs extends BasicAdmin
{
/**
* 文件上传
* @return View
* @return mixed
* @throws \think\Exception
* @throws \think\exception\PDOException
*/
public function upfile() {
$types = $this->request->get('type', 'jpg,png');
$mode = $this->request->get('mode', 'one');
$this->assign('mode', $mode);
$this->assign('types', $types);
if (!in_array(($uptype = $this->request->get('uptype')), ['local', 'qiniu'])) {
public function upfile()
{
$uptype = $this->request->get('uptype');
if (!in_array($uptype, ['local', 'qiniu', 'oss'])) {
$uptype = sysconf('storage_type');
}
$this->assign('uptype', $uptype);
$mode = $this->request->get('mode', 'one');
$types = $this->request->get('type', 'jpg,png');
$this->assign('mimes', FileService::getFileMine($types));
$this->assign('field', $this->request->get('field', 'file'));
return view();
return $this->fetch('', ['mode' => $mode, 'types' => $types, 'uptype' => $uptype]);
}
/**
* 通用文件上传
* @return string
* @return \think\response\Json
* @throws \think\Exception
* @throws \think\exception\PDOException
* @throws \OSS\Core\OssException
*/
public function upload() {
if ($this->request->isPost()) {
$md5s = str_split($this->request->post('md5'), 16);
if (($info = $this->request->file('file')->move('static' . DS . 'upload' . DS . $md5s[0], $md5s[1], true))) {
$filename = join('/', $md5s) . '.' . $info->getExtension();
$site_url = FileService::getFileUrl($filename, 'local');
if ($site_url) {
return json(['data' => ['site_url' => $site_url], 'code' => 'SUCCESS']);
}
public function upload()
{
$file = $this->request->file('file');
if (!$file->checkExt(strtolower(sysconf('storage_local_exts')))) {
return json(['code' => 'ERROR', 'msg' => '文件上传类型受限']);
}
$names = str_split($this->request->post('md5'), 16);
$ext = strtolower(pathinfo($file->getInfo('name'), 4));
$ext = $ext ? $ext : 'tmp';
$filename = "{$names[0]}/{$names[1]}.{$ext}";
// 文件上传Token验证
if ($this->request->post('token') !== md5($filename . session_id())) {
return json(['code' => 'ERROR', 'msg' => '文件上传验证失败']);
}
// 文件上传处理
if (($info = $file->move("static/upload/{$names[0]}", "{$names[1]}.{$ext}", true))) {
if (($site_url = FileService::getFileUrl($filename, 'local'))) {
return json(['data' => ['site_url' => $site_url], 'code' => 'SUCCESS', 'msg' => '文件上传成功']);
}
}
return json(['code' => 'ERROR']);
return json(['code' => 'ERROR', 'msg' => '文件上传失败']);
}
/**
* 文件状态检查
* @throws \OSS\Core\OssException
* @throws \think\Exception
* @throws \think\exception\PDOException
*/
public function upstate() {
public function upstate()
{
$post = $this->request->post();
$filename = join('/', str_split($post['md5'], 16)) . '.' . pathinfo($post['filename'], PATHINFO_EXTENSION);
$ext = strtolower(pathinfo($post['filename'], 4));
$filename = join('/', str_split($post['md5'], 16)) . '.' . ($ext ? $ext : 'tmp');
// 检查文件是否已上传
if (($site_url = FileService::getFileUrl($filename))) {
$this->result(['site_url' => $site_url], 'IS_FOUND');
return json(['data' => ['site_url' => $site_url], 'code' => "IS_FOUND"]);
}
// 需要上传文件,生成上传配置参数
$config = ['uptype' => $post['uptype'], 'file_url' => $filename];
$data = ['uptype' => $post['uptype'], 'file_url' => $filename];
switch (strtolower($post['uptype'])) {
case 'qiniu':
$config['server'] = FileService::getUploadQiniuUrl(true);
$config['token'] = $this->_getQiniuToken($filename);
break;
case 'local':
$config['server'] = FileService::getUploadLocalUrl();
$data['token'] = md5($filename . session_id());
$data['server'] = FileService::getUploadLocalUrl();
break;
case 'qiniu':
$data['token'] = $this->_getQiniuToken($filename);
$data['server'] = FileService::getUploadQiniuUrl(true);
break;
case 'oss':
$time = time() + 3600;
$policyText = [
'expiration' => date('Y-m-d', $time) . 'T' . date('H:i:s', $time) . '.000Z',
'conditions' => [
['content-length-range', 0, 1048576000]
]
'conditions' => [['content-length-range', 0, 1048576000]],
];
$config['policy'] = base64_encode(json_encode($policyText));
$config['server'] = FileService::getUploadOssUrl();
$config['site_url'] = FileService::getBaseUriOss() . $filename;
$config['signature'] = base64_encode(hash_hmac('sha1', $config['policy'], sysconf('storage_oss_secret'), true));
$config['OSSAccessKeyId'] = sysconf('storage_oss_keyid');
$data['server'] = FileService::getUploadOssUrl();
$data['policy'] = base64_encode(json_encode($policyText));
$data['site_url'] = FileService::getBaseUriOss() . $filename;
$data['signature'] = base64_encode(hash_hmac('sha1', $data['policy'], sysconf('storage_oss_secret'), true));
$data['OSSAccessKeyId'] = sysconf('storage_oss_keyid');
break;
}
$this->result($config, 'NOT_FOUND');
return json(['data' => $data, 'code' => "NOT_FOUND"]);
}
/**
* 生成七牛文件上传Token
* @param string $key
* @return string
* @throws \think\Exception
* @throws \think\exception\PDOException
*/
protected function _getQiniuToken($key) {
protected function _getQiniuToken($key)
{
$baseUrl = FileService::getBaseUriQiniu();
$bucket = sysconf('storage_qiniu_bucket');
$accessKey = sysconf('storage_qiniu_access_key');
$secretKey = sysconf('storage_qiniu_secret_key');
$bucket = sysconf('storage_qiniu_bucket');
$host = sysconf('storage_qiniu_domain');
$protocol = sysconf('storage_qiniu_is_https') ? 'https' : 'http';
$params = [
"scope" => "{$bucket}:{$key}",
"deadline" => 3600 + time(),
"returnBody" => "{\"data\":{\"site_url\":\"{$protocol}://{$host}/$(key)\",\"file_url\":\"$(key)\"}, \"code\": \"SUCCESS\"}",
"scope" => "{$bucket}:{$key}", "deadline" => 3600 + time(),
"returnBody" => "{\"data\":{\"site_url\":\"{$baseUrl}/$(key)\",\"file_url\":\"$(key)\"}, \"code\": \"SUCCESS\"}",
];
$data = str_replace(['+', '/'], ['-', '_'], base64_encode(json_encode($params)));
return $accessKey . ':' . str_replace(['+', '/'], ['-', '_'], base64_encode(hash_hmac('sha1', $data, $secretKey, true))) . ':' . $data;
}
/**
* 字体图标
* 字体图标选择器
* @return \think\response\View
*/
public function icon() {
$this->assign('field', $this->request->get('field', 'icon'));
return view();
public function icon()
{
$field = $this->request->get('field', 'icon');
return $this->fetch('', ['field' => $field]);
}
}

View File

@ -1,7 +1,7 @@
<?php
// +----------------------------------------------------------------------
// | Think.Admin
// | ThinkAdmin
// +----------------------------------------------------------------------
// | 版权所有 2014~2017 广州楚才信息科技有限公司 [ http://www.cuci.cc ]
// +----------------------------------------------------------------------
@ -9,7 +9,7 @@
// +----------------------------------------------------------------------
// | 开源协议 ( https://mit-license.org )
// +----------------------------------------------------------------------
// | github开源项目https://github.com/zoujingli/Think.Admin
// | github开源项目https://github.com/zoujingli/ThinkAdmin
// +----------------------------------------------------------------------
namespace app\admin\controller;
@ -25,7 +25,8 @@ use think\Db;
* @author Anyon <zoujingli@qq.com>
* @date 2017/02/15 18:12
*/
class User extends BasicAdmin {
class User extends BasicAdmin
{
/**
* 指定当前数据表
@ -35,62 +36,86 @@ class User extends BasicAdmin {
/**
* 用户列表
* @return array|string
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
* @throws \think\Exception
*/
public function index() {
// 设置页面标题
public function index()
{
$this->title = '系统用户管理';
// 获取到所有GET参数
$get = $this->request->get();
// 实例Query对象
$db = Db::name($this->table)->where('is_deleted', '0');
// 应用搜索条件
foreach (['username', 'phone'] as $key) {
if (isset($get[$key]) && $get[$key] !== '') {
$db->where($key, 'like', "%{$get[$key]}%");
}
list($get, $db) = [$this->request->get(), Db::name($this->table)];
foreach (['username', 'phone', 'mail'] as $key) {
(isset($get[$key]) && $get[$key] !== '') && $db->whereLike($key, "%{$get[$key]}%");
}
// 实例化并显示
return parent::_list($db);
if (isset($get['date']) && $get['date'] !== '') {
list($start, $end) = explode(' - ', $get['date']);
$db->whereBetween('login_at', ["{$start} 00:00:00", "{$end} 23:59:59"]);
}
return parent::_list($db->where(['is_deleted' => '0']));
}
/**
* 授权管理
* @return array|string
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
* @throws \think\Exception
*/
public function auth() {
public function auth()
{
return $this->_form($this->table, 'auth');
}
/**
* 用户添加
* @return array|string
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
* @throws \think\Exception
*/
public function add() {
public function add()
{
return $this->_form($this->table, 'form');
}
/**
* 用户编辑
* @return array|string
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
* @throws \think\Exception
*/
public function edit() {
public function edit()
{
return $this->_form($this->table, 'form');
}
/**
* 用户密码修改
* @return array|string
* @throws \think\Exception
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
* @throws \think\exception\PDOException
*/
public function pass() {
if (in_array('10000', explode(',', $this->request->post('id')))) {
$this->error('系统超级账号禁止操作!');
}
public function pass()
{
if ($this->request->isGet()) {
$this->assign('verify', false);
return $this->_form($this->table, 'pass');
}
$data = $this->request->post();
if ($data['password'] !== $data['repassword']) {
$post = $this->request->post();
if ($post['password'] !== $post['repassword']) {
$this->error('两次输入的密码不一致!');
}
if (DataService::save($this->table, ['id' => $data['id'], 'password' => md5($data['password'])], 'id')) {
$data = ['id' => $post['id'], 'password' => md5($post['password'])];
if (DataService::save($this->table, $data, 'id')) {
$this->success('密码修改成功,下次请使用新密码登录!', '');
}
$this->error('密码修改失败,请稍候再试!');
@ -99,27 +124,36 @@ class User extends BasicAdmin {
/**
* 表单数据默认处理
* @param array $data
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
public function _form_filter(&$data) {
public function _form_filter(&$data)
{
if ($this->request->isPost()) {
if (isset($data['authorize']) && is_array($data['authorize'])) {
$data['authorize'] = join(',', $data['authorize']);
} else {
$data['authorize'] = '';
}
if (isset($data['id'])) {
unset($data['username']);
} elseif (Db::name($this->table)->where('username', $data['username'])->find()) {
} elseif (Db::name($this->table)->where(['username' => $data['username']])->count() > 0) {
$this->error('用户账号已经存在,请使用其它账号!');
}
} else {
$data['authorize'] = explode(',', isset($data['authorize']) ? $data['authorize'] : '');
$this->assign('authorizes', Db::name('SystemAuth')->select());
$this->assign('authorizes', Db::name('SystemAuth')->where(['status' => '1'])->select());
}
}
/**
* 删除用户
* @throws \think\Exception
* @throws \think\exception\PDOException
*/
public function del() {
public function del()
{
if (in_array('10000', explode(',', $this->request->post('id')))) {
$this->error('系统超级账号禁止删除!');
}
@ -131,8 +165,11 @@ class User extends BasicAdmin {
/**
* 用户禁用
* @throws \think\Exception
* @throws \think\exception\PDOException
*/
public function forbid() {
public function forbid()
{
if (in_array('10000', explode(',', $this->request->post('id')))) {
$this->error('系统超级账号禁止操作!');
}
@ -144,8 +181,11 @@ class User extends BasicAdmin {
/**
* 用户禁用
* @throws \think\Exception
* @throws \think\exception\PDOException
*/
public function resume() {
public function resume()
{
if (DataService::update($this->table)) {
$this->success("用户启用成功!", '');
}

View File

@ -0,0 +1,71 @@
<?php
// +----------------------------------------------------------------------
// | ThinkAdmin
// +----------------------------------------------------------------------
// | 版权所有 2014~2017 广州楚才信息科技有限公司 [ http://www.cuci.cc ]
// +----------------------------------------------------------------------
// | 官方网站: http://think.ctolog.com
// +----------------------------------------------------------------------
// | 开源协议 ( https://mit-license.org )
// +----------------------------------------------------------------------
// | github开源项目https://github.com/zoujingli/ThinkAdmin
// +----------------------------------------------------------------------
namespace app\admin\middleware;
use service\NodeService;
use think\Db;
use think\Request;
/**
* 系统权限访问管理
* Class Auth
* @package app\admin\middleware
*/
class Auth
{
/**
* @param Request $request
* @param \Closure $next
* @return mixed
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
public function handle($request, \Closure $next)
{
list($module, $controller, $action) = [$request->module(), $request->controller(), $request->action()];
$access = $this->buildAuth($node = NodeService::parseNodeStr("{$module}/{$controller}/{$action}"));
// 登录状态检查
if (!empty($access['is_login']) && !session('user')) {
$msg = ['code' => 0, 'msg' => '抱歉,您还没有登录获取访问权限!', 'url' => url('@admin/login')];
return $request->isAjax() ? json($msg) : redirect($msg['url']);
}
// 访问权限检查
if (!empty($access['is_auth']) && !auth($node)) {
return json(['code' => 0, 'msg' => '抱歉,您没有访问该模块的权限!']);
}
// 模板常量声明
app('view')->init(config('template.'))->assign(['classuri' => NodeService::parseNodeStr("{$module}/{$controller}")]);
return $next($request);
}
/**
* 根据节点获取对应权限配置
* @param string $node 权限节点
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
private function buildAuth($node)
{
$info = Db::name('SystemNode')->cache(true, 30)->where(['node' => $node])->find();
return [
'is_menu' => intval(!empty($info['is_menu'])),
'is_auth' => intval(!empty($info['is_auth'])),
'is_login' => empty($info['is_auth']) ? intval(!empty($info['is_login'])) : 1,
];
}
}

View File

@ -1,78 +0,0 @@
{extend name='extra@admin/content'}
{block name="button"}
<div class="nowrap pull-right" style="margin-top:10px">
<button data-modal='{:url("$classuri/add")}' data-title="添加权限" class='layui-btn layui-btn-small'><i class='fa fa-plus'></i> 添加权限</button>
<button data-update data-field='delete' data-action='{:url("$classuri/del")}' class='layui-btn layui-btn-small layui-btn-danger'><i class='fa fa-remove'></i> 删除权限</button>
</div>
{/block}
{block name="content"}
<form onsubmit="return false;" data-auto="true" method="post">
<input type="hidden" value="resort" name="action"/>
<table class="table table-hover">
<thead>
<tr>
<th class='list-table-check-td'>
<input data-none-auto="" data-check-target='.list-check-box' type='checkbox'/>
</th>
<th class='list-table-sort-td'>
<button type="submit" class="layui-btn layui-btn-normal layui-btn-mini"> </button>
</th>
<th class='text-center'>权限名称</th>
<th class='text-center'>权限描述</th>
<th class='text-center'>状态</th>
<th class='text-center'>操作</th>
</tr>
</thead>
<tbody>
{foreach $list as $key=>$vo}
<tr>
<td class='list-table-check-td'>
<input class="list-check-box" value='{$vo.id}' type='checkbox'/>
</td>
<td class='list-table-sort-td'>
<input name="_{$vo.id}" value="{$vo.sort}" class="list-sort-input"/>
</td>
<td class='text-center'>{$vo.title}</td>
<td class='text-center'>{$vo.desc|default="<span style='color:#ccc'>没有写描述哦!</span>"}</td>
<td class='text-center'>
{if $vo.status eq 0}
<span>已禁用</span>
{elseif $vo.status eq 1}
<span style="color:#090">使用中</span>
{/if}
</td>
<td class='text-center nowrap'>
{if auth("$classuri/edit")}
<span class="text-explode">|</span>
<a data-modal='{:url("$classuri/edit")}?id={$vo.id}' href="javascript:void(0)">编辑</a>
{/if}
{if auth("$classuri/apply")}
<span class="text-explode">|</span>
<a data-open='{:url("$classuri/apply")}?id={$vo.id}' href="javascript:void(0)">授权</a>
{/if}
{if $vo.status eq 1 and auth("$classuri/forbid")}
<span class="text-explode">|</span>
<a data-update="{$vo.id}" data-field='status' data-value='0'data-action='{:url("$classuri/forbid")}' href="javascript:void(0)">禁用</a>
{elseif auth("$classuri/resume")}
<span class="text-explode">|</span>
<a data-update="{$vo.id}" data-field='status' data-value='1' data-action='{:url("$classuri/resume")}' href="javascript:void(0)">启用</a>
{/if}
{if auth("$classuri/del")}
<span class="text-explode">|</span>
<a data-update="{$vo.id}" data-field='delete' data-action='{:url("$classuri/del")}' href="javascript:void(0)">删除</a>
{/if}
</td>
</tr>
{/foreach}
</tbody>
</table>
{if isset($page)}<p>{$page}</p>{/if}
</form>
{/block}

View File

@ -1,36 +1,22 @@
{extend name='extra@admin/content'}
{extend name='admin@public/content'}
{block name="content"}
<style>
ul.ztree li span.button.switch{margin-right:5px}
ul.ztree ul ul li{display:inline-block;white-space:normal}
ul.ztree>li>ul>li{padding:5px}
ul.ztree>li{background: #dae6f0}
ul.ztree>li:nth-child(even)>ul>li:nth-child(even){background: #eef5fa}
ul.ztree>li:nth-child(even)>ul>li:nth-child(odd){background: #f6fbff}
ul.ztree>li:nth-child(odd)>ul>li:nth-child(even){background: #eef5fa}
ul.ztree>li:nth-child(odd)>ul>li:nth-child(odd){background: #f6fbff}
ul.ztree>li>ul{margin-top:12px}
ul.ztree>li{padding:15px;padding-right:25px}
ul.ztree li{white-space:normal!important}
ul.ztree>li>a>span{font-size:15px;font-weight:700}
</style>
<ul id="zTree" class="ztree loading">
<li style="height:100px;"></li>
<li></li>
</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>
{/block}
{block name="script"}
<link href="__STATIC__/plugs/ztree/zTreeStyle/zTreeStyle.css" rel="stylesheet" type="text/css">
<script src="__STATIC__/plugs/ztree/jquery.ztree.all.min.js" type="text/javascript">;</script>
<script>
require(['jquery.ztree'], function () {
function showTree() {
$(function () {
window.roleForm = new function () {
this.data = {};
this.ztree = null;
this.setting = {
@ -44,18 +30,16 @@
window.roleForm.ztree.expandNode(treeNode);
}
return false;
}}};
this.listen();
}
showTree.prototype = {
constructor: showTree,
listen: function () {
this.getData(this);
},
getData: function (self) {
$.msg.loading();
}
}
};
this.getData = function (self) {
var index = $.msg.loading();
jQuery.get('{:url()}?id={$vo.id}', {action: 'getNode'}, function (ret) {
$.msg.close();
$.msg.close(index);
self.data = renderChildren(ret.data, 1);
self.showTree();
function renderChildren(data, level) {
var childrenData = [];
for (var i in data) {
@ -69,15 +53,13 @@
}
return childrenData;
}
self.data = renderChildren(ret.data, 1);
self.showTree();
}, 'JSON');
},
showTree: function () {
};
this.showTree = function () {
this.ztree = jQuery.fn.zTree.init(jQuery("#zTree"), this.setting, this.data);
while (true) {
var reNodes = this.ztree.getNodesByFilter(function (node) {
return (!node.node && node.children.length < 1);
return (!node.node && node.children.length < 1);
});
if (reNodes.length < 1) {
break;
@ -86,20 +68,56 @@
this.ztree.removeNode(reNodes[i]);
}
}
},
submit: function () {
};
this.submit = function () {
var nodes = [];
var data = this.ztree.getCheckedNodes(true);
for (var i in data) {
(data[i].node) && nodes.push(data[i].node);
}
$.form.load('{:url()}?id={$vo.id}&action=save', {nodes: nodes}, 'POST');
}};
window.roleForm = new showTree();
$.form.load('{:url()}?id={$vo.id}&action=save', {nodes: nodes}, 'post');
};
this.getData(this);
};
$('[data-submit-role]').on('click', function () {
window.roleForm.submit();
});
});
</script>
{/block}
{block name="style"}
<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-size: 15px;
font-weight: 700
}
</style>
{/block}

View File

@ -1,4 +1,4 @@
<form class="layui-form layui-box" style='padding:25px 30px 20px 0' action="__SELF__" data-auto="true" method="post">
<form autocomplete="off" class="layui-form layui-box modal-form-box" action="{:request()->url()}" data-auto="true" method="post">
<div class="layui-form-item">
<label class="layui-form-label">权限名称</label>
@ -17,7 +17,7 @@
<div class="hr-line-dashed"></div>
<div class="layui-form-item text-center">
{if isset($vo['id'])}<input type='hidden' value='{$vo.id}' name='id'/>{/if}
{if isset($vo['id'])}<input type='hidden' value='{$vo.id}' name='id'>{/if}
<button class="layui-btn" type='submit'>保存数据</button>
<button class="layui-btn layui-btn-danger" type='button' data-confirm="确定要取消编辑吗?" data-close>取消编辑</button>
</div>

View File

@ -0,0 +1,83 @@
{extend name='admin@public/content'}
{block name="button"}
<!--{if auth("$classuri/add")}-->
<button data-modal='{:url("$classuri/add")}' data-title="添加权限" class='layui-btn layui-btn-sm layui-btn-primary'>添加权限</button>
<!--{/if}-->
<!--{if auth("$classuri/del")}-->
<button data-update data-field='delete' data-action='{:url("$classuri/del")}' class='layui-btn layui-btn-sm layui-btn-primary'>删除权限</button>
<!--{/if}-->
{/block}
{block name="content"}
<form autocomplete="off" onsubmit="return false;" data-auto="true" method="post">
<!--{if empty($list)}-->
<p class="help-block text-center well"> 哦!</p>
<!--{else}-->
<input type="hidden" value="resort" name="action">
<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="submit" class="layui-btn layui-btn-normal layui-btn-xs"> </button>
</th>
<th class='text-left'>名称</th>
<th class='text-left'>描述</th>
<th class='text-center'>状态</th>
<th class='text-left'>添加时间</th>
<th class='text-center'></th>
</tr>
</thead>
<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='list-table-sort-td'>
<input name="_{$vo.id}" value="{$vo.sort}" class="list-sort-input">
</td>
<td class='text-left'>{$vo.title}</td>
<td class='text-left'>{$vo.desc|default="<span class='color-desc'>没有写描述哦!</span>"}</td>
<td class='text-center'>
{if $vo.status eq 0}<span>已禁用</span>{elseif $vo.status eq 1}<span class="color-green">使用中</span>{/if}
</td>
<td class="text-left nowrap">{$vo.create_at|format_datetime}</td>
<td class='text-center nowrap'>
{if auth("$classuri/edit")}
<span class="text-explode">|</span>
<a data-title="编辑权限" data-modal='{:url("$classuri/edit")}?id={$vo.id}'>编辑</a>
{/if}
{if auth("$classuri/apply")}
<span class="text-explode">|</span>
<a data-open='{:url("$classuri/apply")}?id={$vo.id}'>授权</a>
{/if}
{if $vo.status eq 1 and auth("$classuri/forbid")}
<span class="text-explode">|</span>
<a data-update="{$vo.id}" data-field='status' data-value='0' data-action='{:url("$classuri/forbid")}'>禁用</a>
{elseif auth("$classuri/resume")}
<span class="text-explode">|</span>
<a data-update="{$vo.id}" data-field='status' data-value='1' data-action='{:url("$classuri/resume")}'>启用</a>
{/if}
{if auth("$classuri/del")}
<span class="text-explode">|</span>
<a data-update="{$vo.id}" data-field='delete' data-action='{:url("$classuri/del")}'>删除</a>
{/if}
</td>
</tr>
<!--{/foreach}-->
</tbody>
</table>
{if isset($page)}<p>{$page|raw}</p>{/if}
<!--{/if}-->
</form>
{/block}

View File

@ -1,200 +0,0 @@
{extend name="extra@admin/content"}
{block name="content"}
<form onsubmit="return false;" action="__SELF__" data-auto="true" method="post" class='form-horizontal' style='padding-top:20px'>
<div class="form-group">
<label class="col-sm-2 control-label">Storage <span class="nowrap">(存储引擎)</span></label>
<div class='col-sm-8'>
<select class="layui-input" name="storage_type" required="required">
<!--{if sysconf('storage_type') eq 'qiniu'}-->
<option value='local'>本地服务器</option>
<option selected="selected" value='qiniu'>七牛云存储</option>
<option value='oss'>AliOSS存储</option>
<!--{elseif sysconf('storage_type') eq 'oss'}-->
<option value='local'>本地服务器</option>
<option value='qiniu'>七牛云存储</option>
<option selected="selected" value='oss'>AliOSS存储</option>
<!--{else}-->
<option selected="selected" value='local'>本地服务器</option>
<option value='qiniu'>七牛云存储</option>
<option value='oss'>AliOSS存储</option>
<!--{/if}-->
</select>
<div class="help-block" data-storage-type="qiniu">
若还没有七牛云帐号,请点击
<a target="_blank" href="https://portal.qiniu.com/signup?code=3lhz6nmnwbple">免费申请10G存储空间</a>,
申请成功后添加公开bucket空间
</div>
<div class="help-block" data-storage-type="oss">
若还没有AliOSS存储账号, 请点击 <a target="_blank" href="https://oss.console.aliyun.com">创建AliOSS存储空间</a>,
目前仅支持公开空间URL访问, 另外还需要配置AliOSS跨域策略
</div>
</div>
</div>
<div class="hr-line-dashed" data-storage-type="qiniu"></div>
<div class="form-group" data-storage-type="qiniu">
<label class="col-sm-2 control-label">Region <span class="nowrap">(存储区域)</span></label>
<div class='col-sm-8'>
<select class="layui-input" name="storage_qiniu_region" required="required">
<!--{if sysconf('storage_qiniu_region') eq '华东'}-->
<option selected value='华东'>华东</option>
<!--{else}-->
<option value='华东'>华东</option>
<!--{/if}-->
<!--{if sysconf('storage_qiniu_region') eq '华北'}-->
<option selected value='华北'>华北</option>
<!--{else}-->
<option value='华北'>华北</option>
<!--{/if}-->
<!--{if sysconf('storage_qiniu_region') eq '华南'}-->
<option selected value='华南'>华南</option>
<!--{else}-->
<option value='华南'>华南</option>
<!--{/if}-->
<!--{if sysconf('storage_qiniu_region') eq '北美'}-->
<option selected value='北美'>北美</option>
<!--{else}-->
<option value='北美'>北美</option>
<!--{/if}-->
</select>
<p class="help-block">七牛云存储空间所在区域,需要严格对应储存所在区域才能上传文件</p>
</div>
</div>
<div class="form-group" data-storage-type="qiniu">
<label class="col-sm-2 control-label">Protocol <span class="nowrap">(访问协议)</span></label>
<div class='col-sm-8'>
<select class="layui-input" name="storage_qiniu_is_https" required="required">
<!--{if sysconf('storage_qiniu_is_https')!=='1'}-->
<option selected value='0'>HTTP</option>
<option value='1'>HTTPS</option>
<!--{else}-->
<option value='0'>HTTP</option>
<option selected value='1'>HTTPS</option>
<!--{/if}-->
</select>
<p class="help-block">七牛云资源访问协议HTTP HTTPSHTTPS 需要配置证书才能使用</p>
</div>
</div>
<div class="form-group" data-storage-type="qiniu">
<label class="col-sm-2 control-label">Bucket <span class="nowrap">(空间名称)</span></label>
<div class='col-sm-8'>
<input type="text" name="storage_qiniu_bucket" required="required" title="请输入七牛云存储 Bucket (空间名称)"
placeholder="请输入七牛云存储 Bucket (空间名称)" value="{:sysconf('storage_qiniu_bucket')}"
class="layui-input">
<p class="help-block">填写七牛云存储空间名称static</p>
</div>
</div>
<div class="form-group" data-storage-type="qiniu">
<label class="col-sm-2 control-label">Domain <span class="nowrap">(访问域名)</span></label>
<div class='col-sm-8'>
<input type="text" name="storage_qiniu_domain" required="required" title="请输入七牛云存储 Domain (访问域名)"
placeholder="请输入七牛云存储 Domain (访问域名)" value="{:sysconf('storage_qiniu_domain')}" class="layui-input">
<p class="help-block">填写七牛云存储访问域名static.ctolog.cc</p>
</div>
</div>
<div class="form-group" data-storage-type="qiniu">
<label class="col-sm-2 control-label">AccessKey <span class="nowrap">(访问密钥)</span></label>
<div class='col-sm-8'>
<input type="text" name="storage_qiniu_access_key" required="required" title="请输入七牛云 AccessKey (访问密钥)"
placeholder="请输入七牛云 AccessKey (访问密钥)" value="{:sysconf('storage_qiniu_access_key')}" class="layui-input">
<p class="help-block">可以在 [ 七牛云 > 个人中心 ] 设置并获取到访问密钥</p>
</div>
</div>
<div class="form-group" data-storage-type="qiniu">
<label class="col-sm-2 control-label">SecretKey <span class="nowrap">(安全密钥)</span></label>
<div class='col-sm-8'>
<input type="password" name="storage_qiniu_secret_key" required="required" title="请输入七牛云 SecretKey (安全密钥)"
placeholder="请输入七牛云 SecretKey (安全密钥)" value="{:sysconf('storage_qiniu_secret_key')}"
maxlength="43" class="layui-input">
<p class="help-block">可以在 [ 七牛云 > 个人中心 ] 设置并获取到安全密钥</p>
</div>
</div>
<div class="form-group" data-storage-type="oss">
<label class="col-sm-2 control-label">Protocol <span class="nowrap">(访问协议)</span></label>
<div class='col-sm-8'>
<select class="layui-input" name="storage_oss_is_https" required="required">
<!--{if sysconf('storage_oss_is_https')!=='1'}-->
<option selected value='0'>HTTP</option>
<option value='1'>HTTPS</option>
<!--{else}-->
<option value='0'>HTTP</option>
<option selected value='1'>HTTPS</option>
<!--{/if}-->
</select>
<p class="help-block">AliOSS资源访问协议HTTP HTTPSHTTPS 需要配置证书才能使用</p>
</div>
</div>
<div class="form-group" data-storage-type="oss">
<label class="col-sm-2 control-label">Bucket <span class="nowrap">(空间名称)</span></label>
<div class='col-sm-8'>
<input type="text" name="storage_oss_bucket" required="required" title="请输入AliOSS Bucket (空间名称)"
placeholder="请输入AliOSS Bucket (空间名称)" value="{:sysconf('storage_oss_bucket')}" class="layui-input">
<p class="help-block">填写OSS存储空间名称static</p>
</div>
</div>
<div class="form-group" data-storage-type="oss">
<label class="col-sm-2 control-label">Domain <span class="nowrap">(访问域名)</span></label>
<div class='col-sm-8'>
<input type="text" name="storage_oss_domain" required="required" title="请输入AliOSS存储 Domain (访问域名)"
placeholder="请输入AliOSS存储 Domain (访问域名)" value="{:sysconf('storage_oss_domain')}" class="layui-input">
<p class="help-block">填写OSS存储外部访问域名static.ctolog.cc</p>
</div>
</div>
<div class="form-group" data-storage-type="oss">
<label class="col-sm-2 control-label">AccessKey <span class="nowrap">(访问密钥)</span></label>
<div class='col-sm-8'>
<input type="text" name="storage_oss_keyid" required="required" title="请输入16位AliOSS AccessKey (访问密钥)"
placeholder="请输入AliOSS AccessKey (访问密钥)" value="{:sysconf('storage_oss_keyid')}" maxlength="16" class="layui-input">
<p class="help-block">可以在 [ 阿里云 > 个人中心 ] 设置并获取到访问密钥</p>
</div>
</div>
<div class="form-group" data-storage-type="oss">
<label class="col-sm-2 control-label">SecretKey <span class="nowrap">(安全密钥)</span></label>
<div class='col-sm-8'>
<input type="password" name="storage_oss_secret" required="required" title="请输入30位AliOSS SecretKey (安全密钥)"
placeholder="请输入AliOSS SecretKey (安全密钥)" value="{:sysconf('storage_oss_secret')}" maxlength="30" class="layui-input">
<p class="help-block">可以在 [ 阿里云 > 个人中心 ] 设置并获取到安全密钥</p>
</div>
</div>
<div class="hr-line-dashed"></div>
<div class="col-sm-4 col-sm-offset-2">
<div class="layui-form-item text-center">
<button class="layui-btn" type="submit">保存配置</button>
</div>
</div>
</form>
{/block}
{block name="script"}
<script>
$(function () {
$('[name="storage_type"]').on('change', function () {
$("[data-storage-type]").not($("[data-storage-type='" + $(this).val() + "']").show()).hide();
}).trigger('change');
});
</script>
{/block}

View File

@ -1,68 +0,0 @@
{extend name="extra@admin/content"}
{block name="content"}
<form onsubmit="return false;" action="__SELF__" data-auto="true" method="post" class='form-horizontal' style='padding-top:20px'>
<div class="form-group">
<label class="col-sm-2 control-label">SiteName <span class="nowrap">(网站名称)</span></label>
<div class='col-sm-8'>
<input type="text" name="site_name" required="required" title="请输入网站名称" placeholder="请输入网站名称" value="{:sysconf('site_name')}" class="layui-input">
<p class="help-block">网站名称,显示在浏览器标签上</p>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">Copyright <span class="nowrap">(版权信息)</span></label>
<div class='col-sm-8'>
<input type="text" name="site_copy" required="required" title="请输入版权信息" placeholder="请输入版权信息" value="{:sysconf('site_copy')}" class="layui-input">
<p class="help-block">程序的版权信息设置,在后台登录页面显示</p>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">AppName <span class="nowrap">(程序名称)</span></label>
<div class='col-sm-8'>
<input type="text" name="app_name" required="required" title="请输入程序名称" placeholder="请输入程序名称" value="{:sysconf('app_name')}" class="layui-input">
<p class="help-block">当前程序名称,在后台主标题上显示</p>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">AppVersion <span class="nowrap">(程序版本)</span></label>
<div class='col-sm-8'>
<input type="text" name="app_version" required="required" title="请输入程序版本" placeholder="请输入程序版本" value="{:sysconf('app_version')}" class="layui-input">
<p class="help-block">当前程序版本号,在后台主标题上标显示</p>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">Baidu <span class="nowrap">(百度统计)</span></label>
<div class='col-sm-8'>
<input type="text" name="tongji_baidu_key" maxlength="32" pattern="^[0-9a-z]{32}$" title="请输入32位百度统计应用ID" placeholder="请输入32位百度统计应用ID" value="{:sysconf('tongji_baidu_key')}" class="layui-input">
<p class="help-block">百度统计应用ID可以在<a target="_blank" href="https://tongji.baidu.com">百度网站统计</a>申请并获取</p>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">BrowserIcon <span class="nowrap">(浏览器图标)</span></label>
<div class='col-sm-8'>
<img data-tips-image style="height:auto;max-height:32px;min-width:32px" src="{:sysconf('browser_icon')}"/>
<input type="hidden" name="browser_icon" onchange="$(this).prev('img').attr('src', this.value)"
value="{:sysconf('browser_icon')}" class="layui-input">
<a class="btn btn-link" data-file="one" data-type="ico,png" data-field="browser_icon">上传图片</a>
<p>建议上传ICO图标的尺寸为128x128px此图标用于网站标题前ICON在线制作。</p>
</div>
</div>
<div class="hr-line-dashed"></div>
<div class="col-sm-4 col-sm-offset-2">
<div class="layui-form-item text-center">
<button class="layui-btn" type="submit">保存配置</button>
</div>
</div>
</form>
{/block}

View File

@ -0,0 +1,228 @@
{extend name="admin@public/content"}
{block name="content"}
<form autocomplete="off" onsubmit="return false;" action="{:request()->url()}" data-auto="true" method="post" class='form-horizontal layui-form padding-top-20'>
<div class="form-group">
<label class="col-sm-2 control-label label-required">
Storage<br><span class="nowrap color-desc">存储引擎</span>
</label>
<div class='col-sm-8'>
{foreach ['local'=>'本地服务器存储','qiniu'=>'七牛云存储','oss'=>'阿里云OSS存储'] as $k=>$v}
<label class="think-radio">
<!--{if sysconf('storage_type') eq $k}-->
<input checked type="radio" name="storage_type" value="{$k}" title="{$v}" lay-ignore>
<!--{else}-->
<input type="radio" name="storage_type" value="{$k}" title="{$v}" lay-ignore>
<!--{/if}-->
{$v}
</label>
{/foreach}
<div class="help-block" data-storage-type="local">
文件存储在本地服务器,请确保服务器的 ./static/upload/ 目录有写入权限
</div>
<div class="help-block" data-storage-type="qiniu">
若还没有七牛云帐号,可<a target="_blank" href="https://portal.qiniu.com/signup?code=3lhz6nmnwbple">免费申请10G存储</a>申请成功后添加公开bucket。
</div>
<div class="help-block" data-storage-type="oss">
若还没有OSS存储账号, <a target="_blank" href="https://oss.console.aliyun.com">创建阿里云OSS存储</a>需要配置OSS公开访问及跨域策略。
</div>
</div>
</div>
<div class="hr-line-dashed"></div>
<div class="form-group" data-storage-type="local">
<label class="col-sm-2 control-label">
AllowExts<br><span class="nowrap color-desc">允许类型</span>
</label>
<div class='col-sm-8'>
<input type="text" name="storage_local_exts" required="required" value="{:sysconf('storage_local_exts')}"
title="请输入系统文件上传后缀" placeholder="请输入系统文件上传后缀" class="layui-input">
<p class="help-block">设置系统允许上传文件的后缀多个以英文逗号隔开。如png,jpg,rar,doc</p>
</div>
</div>
<div class="form-group" data-storage-type="qiniu">
<label class="col-sm-2 control-label label-required">
Region<br><span class="nowrap color-desc">存储区域</span>
</label>
<div class='col-sm-8'>
{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="form-group" data-storage-type="qiniu">
<label class="col-sm-2 control-label label-required">
Protocol<br><span class="nowrap color-desc">访问协议</span>
</label>
<div class='col-sm-8'>
<!--{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="form-group" data-storage-type="qiniu">
<label class="col-sm-2 control-label">
Bucket<br><span class="nowrap color-desc">空间名称</span>
</label>
<div class='col-sm-8'>
<input type="text" name="storage_qiniu_bucket" required="required" value="{:sysconf('storage_qiniu_bucket')}"
title="请输入七牛云存储 Bucket (空间名称)" placeholder="请输入七牛云存储 Bucket (空间名称)" class="layui-input">
<p class="help-block">填写七牛云存储空间名称static</p>
</div>
</div>
<div class="form-group" data-storage-type="qiniu">
<label class="col-sm-2 control-label">
Domain<br><span class="nowrap color-desc">访问域名</span>
</label>
<div class='col-sm-8'>
<input type="text" name="storage_qiniu_domain" required="required" value="{:sysconf('storage_qiniu_domain')}"
title="请输入七牛云存储 Domain (访问域名)" placeholder="请输入七牛云存储 Domain (访问域名)" class="layui-input">
<p class="help-block">填写七牛云存储访问域名static.ctolog.cc</p>
</div>
</div>
<div class="form-group" data-storage-type="qiniu">
<label class="col-sm-2 control-label">
AccessKey<br><span class="nowrap color-desc">访问密钥</span>
</label>
<div class='col-sm-8'>
<input type="text" name="storage_qiniu_access_key" required="required" value="{:sysconf('storage_qiniu_access_key')}"
title="请输入七牛云 AccessKey (访问密钥)" placeholder="请输入七牛云 AccessKey (访问密钥)" class="layui-input">
<p class="help-block">可以在 [ 七牛云 > 个人中心 ] 设置并获取到访问密钥。</p>
</div>
</div>
<div class="form-group" data-storage-type="qiniu">
<label class="col-sm-2 control-label">
SecretKey<br><span class="nowrap color-desc">安全密钥</span>
</label>
<div class='col-sm-8'>
<input type="text" name="storage_qiniu_secret_key" required="required" value="{:sysconf('storage_qiniu_secret_key')}" maxlength="43"
title="请输入七牛云 SecretKey (安全密钥)" placeholder="请输入七牛云 SecretKey (安全密钥)" class="layui-input">
<p class="help-block">可以在 [ 七牛云 > 个人中心 ] 设置并获取到安全密钥。</p>
</div>
</div>
<div class="form-group" data-storage-type="oss">
<label class="col-sm-2 control-label label-required">
Protocol<br><span class="nowrap color-desc">访问协议</span>
</label>
<div class='col-sm-8'>
<!--{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="form-group" data-storage-type="oss">
<label class="col-sm-2 control-label">
Bucket<br><span class="nowrap color-desc">空间名称</span>
</label>
<div class='col-sm-8'>
<input type="text" name="storage_oss_bucket" required="required" value="{:sysconf('storage_oss_bucket')}"
title="请输入OSS Bucket (空间名称)" placeholder="请输入OSS Bucket (空间名称)" class="layui-input">
<p class="help-block">填写OSS存储空间名称think-admin-oss</p>
</div>
</div>
<div class="form-group" data-storage-type="oss">
<label class="col-sm-2 control-label">
EndPoint<br><span class="nowrap color-desc">数据中心</span>
</label>
<div class='col-sm-8'>
<input type="text" name="storage_oss_endpoint" required="required" value="{:sysconf('storage_oss_endpoint')}"
title="请输入OSS数据中心访问域名 (访问域名)" placeholder="请输入OSS数据中心访问域名 (访问域名)" class="layui-input">
<p class="help-block">填写OSS数据中心访问域名oss-cn-shenzhen.aliyuncs.com</p>
</div>
</div>
<div class="form-group" data-storage-type="oss">
<label class="col-sm-2 control-label">
Domain<br><span class="nowrap color-desc">访问域名</span>
</label>
<div class='col-sm-8'>
<input type="text" name="storage_oss_domain" required="required" value="{:sysconf('storage_oss_domain')}"
title="请输入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="form-group" data-storage-type="oss">
<label class="col-sm-2 control-label">
AccessKey<br><span class="nowrap color-desc">访问密钥</span>
</label>
<div class='col-sm-8'>
<input type="text" name="storage_oss_keyid" required="required" value="{:sysconf('storage_oss_keyid')}" maxlength="16"
title="请输入16位OSS AccessKey (访问密钥)" placeholder="请输入OSS AccessKey (访问密钥)" class="layui-input">
<p class="help-block">可以在 [ 阿里云 > 个人中心 ] 设置并获取到访问密钥。</p>
</div>
</div>
<div class="form-group" data-storage-type="oss">
<label class="col-sm-2 control-label">
SecretKey<br><span class="nowrap color-desc">安全密钥</span>
</label>
<div class='col-sm-8'>
<input type="text" name="storage_oss_secret" required="required" value="{:sysconf('storage_oss_secret')}" maxlength="30"
title="请输入30位OSS SecretKey (安全密钥)" placeholder="请输入OSS SecretKey (安全密钥)" class="layui-input">
<p class="help-block">可以在 [ 阿里云 > 个人中心 ] 设置并获取到安全密钥。</p>
</div>
</div>
<div class="hr-line-dashed"></div>
<div class="col-sm-4 col-sm-offset-2">
<div class="layui-form-item text-center">
<button class="layui-btn" type="submit">保存配置</button>
</div>
</div>
</form>
{/block}
{block name="script"}
<script>
(function () {
window.form.render();
buildForm('{:sysconf("storage_type")}');
$('[name=storage_type]').on('click', function () {
buildForm($('[name=storage_type]:checked').val())
});
// 表单显示编译
function buildForm(value) {
var $tips = $("[data-storage-type='" + value + "']");
$("[data-storage-type]").not($tips.show()).hide();
}
})();
</script>
{/block}

View File

@ -0,0 +1,82 @@
{extend name="admin@public/content"}
{block name="content"}
<form autocomplete="off" onsubmit="return false;" action="{:request()->url()}" data-auto="true" method="post" class='form-horizontal layui-form padding-top-20'>
<div class="form-group">
<label class="col-sm-2 control-label">
AppName<br><span class="nowrap color-desc">程序名称</span>
</label>
<div class='col-sm-8'>
<input name="app_name" required="required" title="请输入程序名称" placeholder="请输入程序名称" value="{:sysconf('app_name')}" class="layui-input">
<p class="help-block">当前程序名称,在后台主标题上显示</p>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">
AppVersion<br><span class="nowrap color-desc">程序版本</span>
</label>
<div class='col-sm-8'>
<input name="app_version" required="required" title="请输入程序版本" placeholder="请输入程序版本" value="{:sysconf('app_version')}" class="layui-input">
<p class="help-block">当前程序版本号,在后台主标题上标显示</p>
</div>
</div>
<div class="hr-line-dashed"></div>
<div class="form-group">
<label class="col-sm-2 control-label">
SiteName<br><span class="nowrap color-desc">网站名称</span>
</label>
<div class='col-sm-8'>
<input name="site_name" required="required" title="请输入网站名称" placeholder="请输入网站名称" value="{:sysconf('site_name')}" class="layui-input">
<p class="help-block">网站名称,显示在浏览器标签上</p>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">
Copyright<br><span class="nowrap color-desc">版权信息</span>
</label>
<div class='col-sm-8'>
<input name="site_copy" required="required" title="请输入版权信息" placeholder="请输入版权信息" value="{:sysconf('site_copy')}" class="layui-input">
<p class="help-block">程序的版权信息设置,在后台登录页面显示</p>
</div>
</div>
<div class="hr-line-dashed"></div>
<div class="form-group">
<label class="col-sm-2 control-label">
Browser<br><span class="nowrap color-desc">浏览器图标</span>
</label>
<div class='col-sm-8'>
<img data-tips-image style="height:auto;max-height:32px;min-width:32px" src="{:sysconf('browser_icon')}"/>
<input type="hidden" name="browser_icon" onchange="$(this).prev('img').attr('src', this.value)" value="{:sysconf('browser_icon')}" class="layui-input">
<a class="btn btn-link" data-file="one" data-uptype="local" data-type="ico,png" data-field="browser_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="form-group">
<label class="col-sm-2 control-label">
Miitbeian<br><span class="nowrap color-desc">网站备案</span>
</label>
<div class='col-sm-8'>
<input name="miitbeian" title="请输入网站备案号" 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"></div>
<div class="col-sm-4 col-sm-offset-2">
<div class="layui-form-item text-center">
<button class="layui-btn" type="submit">保存配置</button>
</div>
</div>
</form>
{/block}

View File

@ -1,9 +0,0 @@
{extend name="extra@admin/main"}
{block name='body'}
{include file="extra@admin/main/top"}
<div class="framework-body framework-sidebar-mini">
{include file="extra@admin/main/left"}
<div class="framework-container layer-main-container"></div>
</div>
{/block}

View File

@ -1,122 +0,0 @@
{extend name='extra@admin/content'}
{block name="content"}
<div class="row">
<div class="col-lg-6">
<table class="layui-box layui-table" lay-even lay-skin="line">
<colgroup>
<col width="40%">
<col>
</colgroup>
<thead>
<tr>
<th class="text-center" colspan="2">系统信息</th>
</tr>
</thead>
<tbody>
<tr>
<td>Think.Admin 版本</td>
<td>{:sysconf('app_version')}</td>
</tr>
<tr>
<td>ThinkPHP 版本</td>
<td>{$Think.const.THINK_VERSION}</td>
</tr>
<tr>
<td>服务器操作系统</td>
<td>{:php_uname('s')}</td>
</tr>
<tr>
<td>WEB运行环境</td>
<td>{:php_sapi_name()}</td>
</tr>
<tr>
<td>MySQL数据库版本</td>
<td>{$mysql_ver}</td>
</tr>
<tr>
<td>运行PHP版本</td>
<td>{:phpversion()}</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 class="col-lg-6">
<table class="layui-box layui-table" lay-even lay-skin="line">
<colgroup>
<col width="40%">
<col>
</colgroup>
<thead>
<tr>
<th class="text-center" colspan="2">产品团队</th>
</tr>
</thead>
<tbody>
<tr>
<td>产品名称</td>
<td>Think.Admin 管理框架</td>
</tr>
<tr>
<td>产品研发团队</td>
<td>广州楚才信息科技有限公司</td>
</tr>
<tr>
<td>产品DEMO体验</td>
<td>
<a target="_blank" href="https://think.ctolog.com">
https://think.ctolog.com
</a>
</td>
</tr>
<tr>
<td>官方QQ群</td>
<td>
<a target="_blank" href="http://shang.qq.com/wpa/qunwpa?idkey=ae25cf789dafbef62e50a980ffc31242f150bc61a61164458216dd98c411832a">
<img src="//pub.idqqimg.com/wpa/images/group.png" style="height:18px;width:auto" alt="PHP微信开发群 (SDK)">
</a>
</td>
</tr>
<tr>
<td>BUG反馈</td>
<td>
<a target="_blank" href="https://github.com/zoujingli/Think.Admin/issues">
https://github.com/zoujingli/Think.Admin/issues
</a>
</td>
</tr>
<tr>
<td>项目地址</td>
<td>
<a target="_blank" href="https://github.com/zoujingli/Think.Admin">
https://github.com/zoujingli/Think.Admin
</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>
广东省 广州市 海珠区 世港国际公寓E1栋
</td>
</tr>
</tbody>
</table>
</div>
</div>
{/block}

View File

@ -0,0 +1,83 @@
{extend name="admin@public/main"}
{block name='body'}
<!-- 顶部菜单区域 开始 -->
<div class="framework-topbar">
<div class="topbar-head pull-left">
<a href="{:url('@')}" class="topbar-logo pull-left">{:sysconf('app_name')} <sup>{:sysconf('app_version')}</sup></a>
</div>
<!--{foreach $menus as $oneMenu}-->
<a data-menu-node="m-{$oneMenu.id}" data-open="{$oneMenu.url}" class="topbar-btn pull-left transition">
{notempty name='oneMenu.icon'}<span class='font-s13 {$oneMenu.icon}'></span>&nbsp;{/notempty}
{$oneMenu.title|default=''}
</a>
<!--{/foreach}-->
<div class="pull-right">
<!--{if session('user.id')}-->
<div class="dropdown">
<a href="#" class="dropdown-toggle topbar-btn text-center transition" data-toggle="dropdown">
<span class="glyphicon glyphicon-user font-s13"></span>
{:session('user.username')}
<span class="toggle-icon glyphicon glyphicon-menu-up transition font-s13"></span>
</a>
<ul class="dropdown-menu">
<li class="topbar-btn"><a data-modal="{:url('admin/index/pass')}?id={:session('user.id')}" data-title="修改密码"><i class="glyphicon glyphicon-lock"></i> 修改密码</a></li>
<li class="topbar-btn"><a data-modal="{:url('admin/index/info')}?id={:session('user.id')}" data-title="修改资料"><i class="glyphicon glyphicon-edit"></i> 修改资料</a></li>
<li class="topbar-btn">
<a data-load="{:url('admin/login/out')}" data-confirm="确定要退出登录吗?"><i class="glyphicon glyphicon-log-out"></i> 退出登录</a>
</li>
</ul>
</div>
<!--{else}-->
<div class="topbar-info-item">
<a data-href="{:url('@admin/login')}" data-toggle="dropdown" class=" topbar-btn text-center">
<span class='glyphicon glyphicon-user'></span> 立即登录 </span>
</a>
</div>
<!--{/if}-->
</div>
<a class="topbar-btn pull-right transition" data-tips-text="刷新" data-reload="true" style="width:50px"><span class="glyphicon glyphicon-refresh font-s12"></span></a>
</div>
<!-- 顶部菜单区域 结束 -->
<!-- 左则菜单区域 开始 -->
<div class="framework-leftbar">
{foreach $menus as $oneMenu}
<!--{notempty name='$oneMenu.sub'}-->
<div class="leftbar-container hide notselect" data-menu-layout="m-{$oneMenu.id}">
<div class="line-top">
<i class="layui-icon font-s12">&#xe65f;</i>
</div>
{foreach $oneMenu.sub as $twoMenu}
<!--{empty name='$twoMenu.sub'}-->
<a class='transition' data-menu-node="m-{$oneMenu.id}-{$twoMenu.id}" data-open="{$twoMenu.url}">
{notempty name='twoMenu.icon'}<span class='{$twoMenu.icon} font-icon'></span>&nbsp;{/notempty}
{$twoMenu.title}
</a>
<!--{else}-->
<div data-submenu-layout='m-{$oneMenu.id}-{$twoMenu.id}'>
<a class='menu-title transition'>
{notempty name='twoMenu.icon'}<span class='{$twoMenu.icon} font-icon'></span>&nbsp;{/notempty}
{$twoMenu.title} <i class='layui-icon pull-right font-s12 transition'>&#xe619;</i>
</a>
<div>
{foreach $twoMenu.sub as $thrMenu}
<a class='transition' data-open="{$thrMenu.url}" data-menu-node="m-{$oneMenu.id}-{$twoMenu.id}-{$thrMenu.id}">
{notempty name='thrMenu.icon'}<span class='{$thrMenu.icon} font-icon'></span>{/notempty} {$thrMenu.title}
</a>
{/foreach}
</div>
</div>
<!--{/empty}-->
{/foreach}
</div>
<!--{/notempty}-->
{/foreach}
</div>
<!-- 左则菜单区域 结束 -->
<!-- 右则内容区域 开始 -->
<div class="framework-body"></div>
<!-- 右则内容区域 结束 -->
{/block}

View File

@ -0,0 +1,83 @@
{extend name='admin@public/content'}
{block name="content"}
<table class="layui-table" lay-even lay-skin="line">
<colgroup>
<col width="20%">
<col width="30%">
<col width="20%">
<col width="30%">
</colgroup>
<thead>
<tr>
<th class="text-left" colspan="2">系统信息</th>
<th class="text-left" colspan="2">产品团队</th>
</tr>
</thead>
<tbody>
<tr>
<td style="max-width:200px" class="nowrap">ThinkAdmin 版本</td>
<td class="nowrap">{:sysconf('app_version')}</td>
<td style="max-width:200px" class="nowrap">产品名称</td>
<td class="nowrap">ThinkAdmin 管理框架</td>
</tr>
<tr>
<td class="nowrap">ThinkPHP 版本</td>
<td class="nowrap">{$think_ver}</td>
<td class="nowrap">产品名称</td>
<td class="nowrap">ThinkAdmin 管理框架</td>
</tr>
<tr>
<td class="nowrap">服务器操作系统</td>
<td class="nowrap">{:php_uname('s')}</td>
<td class="nowrap">产品DEMO体验</td>
<td class="nowrap">
<a target="_blank" href="http://demo.thinkadmin.top">http://demo.thinkadmin.top</a>
</td>
</tr>
<tr>
<td class="nowrap">WEB运行环境</td>
<td class="nowrap">{:php_sapi_name()}</td>
<td class="nowrap">官方QQ群</td>
<td class="nowrap">
<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 class="nowrap">MySQL数据库版本</td>
<td class="nowrap">{$mysql_ver}</td>
<td class="nowrap">BUG反馈</td>
<td class="nowrap">
<a target="_blank" href="https://github.com/zoujingli/ThinkAdmin/issues">
https://github.com/zoujingli/ThinkAdmin/issues
</a>
</td>
</tr>
<tr>
<td class="nowrap">运行PHP版本</td>
<td class="nowrap">{$Think.PHP_VERSION}</td>
<td class="nowrap">项目地址</td>
<td class="nowrap">
<a target="_blank" href="https://github.com/zoujingli/ThinkAdmin">
https://github.com/zoujingli/ThinkAdmin
</a>
</td>
</tr>
<tr>
<td class="nowrap">上传大小限制</td>
<td class="nowrap">{:ini_get('upload_max_filesize')}</td>
<td class="nowrap">公司官网</td>
<td class="nowrap"><a target="_blank" href="http://www.cuci.cc">http://www.cuci.cc</a></td>
</tr>
<tr>
<td class="nowrap">POST大小限制</td>
<td class="nowrap">{:ini_get('post_max_size')}</td>
<td class="nowrap">公司地址</td>
<td class="nowrap">广州市天河区东圃一横路东泷商贸中心C座316</td>
</tr>
</tbody>
</table>
{/block}

View File

@ -1,89 +0,0 @@
{extend name='extra@admin/content'}
{block name="button"}
<div class="nowrap pull-right" style="margin-top:10px">
{if auth("$classuri/del")}
<button data-update data-field='delete' data-action='{:url("$classuri/del")}' class='layui-btn layui-btn-small layui-btn-danger'>
<i class='fa fa-remove'></i> 删除日志
</button>
{/if}
</div>
{/block}
{block name="content"}
<!-- 表单搜索 开始 -->
<form class="animated form-search" action="__SELF__" onsubmit="return false" method="get">
<div class="row">
<div class="col-xs-3">
<div class="form-group">
<input type="text" name="username" value="{$Think.get.username|default=''}" placeholder="操作者" class="input-sm form-control">
</div>
</div>
<div class="col-xs-3">
<div class="form-group">
<select name='action' class='input-sm form-control'>
<option value=''> - 行为 - </option>
<!--{foreach $actions as $action}-->
<!--{if $action===$Think.get.action}-->
<option selected="selected" value='{$action}'>{$action}</option>
<!--{else}-->
<option value='{$action}'>{$action}</option>
<!--{/if}-->
<!--{/foreach}-->
</select>
</div>
</div>
<div class="col-xs-3">
<div class="form-group">
<input type="text" name="content" value="{$Think.get.content|default=''}" placeholder="操作内容" class="input-sm form-control">
</div>
</div>
<div class="col-xs-1">
<div class="form-group">
<button type="submit" class="btn btn-sm btn-white"><i class="fa fa-search"></i> 搜索</button>
</div>
</div>
</div>
</form>
<!-- 表单搜索 结束 -->
<form onsubmit="return false;" data-auto="" method="POST">
<input type="hidden" value="resort" name="action"/>
<table class="table table-hover">
<thead>
<tr>
<th class='list-table-check-td'>
<input data-none-auto="" data-check-target='.list-check-box' type='checkbox'/>
</th>
<th class='text-center'>操作者</th>
<th class='text-left'>节点</th>
<th class='text-left'>行为</th>
<th class='text-left'>操作内容</th>
<th class='text-left'>操作位置</th>
<th class='text-left'>操作时间</th>
</tr>
</thead>
<tbody>
{foreach $list as $key=>$vo}
<tr>
<td class='list-table-check-td'>
<input class="list-check-box" value='{$vo.id}' type='checkbox'/>
</td>
<td class='text-center'>{$vo.username}</td>
<td class='text-left'>{$vo.node}</td>
<td class='text-left'>{$vo.action}</td>
<td class='text-left'>{$vo.content}</td>
<td class='text-left'>{$vo.isp|default=$vo.ip}</td>
<td class='text-left'>{$vo.create_at}</td>
</tr>
{/foreach}
</tbody>
</table>
{if isset($page)}<p>{$page}</p>{/if}
</form>
{/block}

View File

@ -0,0 +1,100 @@
{extend name='admin@public/content'}
{block name="button"}
<!--{if auth("$classuri/del")}-->
<button data-update data-field='delete' data-action='{:url("$classuri/del")}' class='layui-btn layui-btn-sm layui-btn-primary'>删除日志</button>
<!--{/if}-->
{/block}
{block name="content"}
<!-- 表单搜索 开始 -->
<form autocomplete="off" class="layui-form layui-form-pane form-search" action="{:request()->url()}" onsubmit="return false" method="get">
<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">
<select name='action' class='layui-select' lay-search="">
<option value=''> - 所有记录 -</option>
<!--{foreach $actions as $action}-->
<!--{if $action===$Think.get.action}-->
<option selected="selected" value='{$action}'>{$action}</option>
<!--{else}-->
<option value='{$action}'>{$action}</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="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="create_at" id='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">&#xe615;</i> 搜 索</button>
</div>
</form>
<script>
window.form.render();
window.laydate.render({range: true, elem: '#create_at'});
</script>
<!-- 表单搜索 结束 -->
<form onsubmit="return false;" data-auto="true" method="post">
<!--{empty name='list'}-->
<p class="help-block text-center well"> 哦!</p>
<!--{else}-->
<input type="hidden" value="resort" name="action">
<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='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 class='text-left nowrap'>操作时间</th>
</tr>
</thead>
<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.username}</td>
<td class='text-left nowrap'>{$vo.node}</td>
<td class='text-left nowrap'>{$vo.action}</td>
<td class='text-left nowrap'>{$vo.content}</td>
<td class='text-left nowrap'>{$vo.isp|default=$vo.ip}</td>
<td class='text-left nowrap'>{$vo.create_at|format_datetime}</td>
</tr>
<!--{/foreach}-->
</tbody>
</table>
{if isset($page)}<p>{$page|raw}</p>{/if}
<!--{/empty}-->
</form>
{/block}

View File

@ -0,0 +1,76 @@
{extend name='admin@public/content'}
{block name="content"}
<!-- 表单搜索 开始 -->
<form class="layui-form layui-form-pane form-search" action="{:request()->url()}" onsubmit="return false" method="get">
<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="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="result" value="{$Think.get.result|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="date" id='range-date' value="{$Think.get.date|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">&#xe615;</i> 搜 索</button>
</div>
</form>
<!-- 表单搜索 结束 -->
<form onsubmit="return false;" data-auto="true" method="post">
<input type="hidden" value="resort" name="action"/>
<table class="layui-table" lay-skin="line">
<thead>
<tr>
<th class='list-table-check-td'>
<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>
</tr>
</thead>
<tbody>
{foreach $list as $key=>$vo}
<tr>
<td class='list-table-check-td'>
<input class="list-check-box" value='{$vo.id}' type='checkbox'/>
</td>
<td class='text-left nowrap'>{$vo.phone}</td>
<td class='text-left nowrap'>{$vo.content}</td>
<td class='text-left nowrap'>{$vo.result}</td>
<td class='text-left nowrap'>{$vo.create_at|format_datetime}</td>
</tr>
{/foreach}
</tbody>
</table>
{if isset($page)}<p>{$page}</p>{/if}
<script>
window.form.render();
window.laydate.render({range: true, elem: '#range-date'});
</script>
</form>
{/block}

View File

@ -1,102 +0,0 @@
{extend name="extra@admin/main"}
{block name="style"}
<link rel="stylesheet" href="__PUBLIC__/static/theme/default/css/login.css">
{/block}
{block name="body"}
<div class="login-container" style="height:100%">
<!-- 动态云层动画 开始 -->
<div class="clouds clouds-footer"></div>
<div class="clouds"></div>
<div class="clouds clouds-fast"></div>
<!-- 动态云层动画 结束 -->
<!-- 顶部导航条 开始 -->
<div class="header">
<span>欢迎登录后台管理界面平台</span>
<ul>
<li><a href="{:url('@')}">回首页</a></li>
<li>
<a href="javascript:void(0)" target="_blank"><b style="color:#fff">帮助</b></a>
</li>
<li>
<a href="http://sw.bos.baidu.com/sw-search-sp/software/4bcf5e4f1835b/ChromeStandalone_54.0.2840.99_Setup.exe" target="_blank">
<b style="color:#fff">推荐谷歌浏览器</b>
</a>
</li>
<li><a target="_blank" href="http://www.cuci.cc">楚才官网</a></li>
</ul>
</div>
<!-- 顶部导航条 结束 -->
<!-- 页面表单主体 开始 -->
<div class="container" style="top:50%;margin-top:-300px">
<form onsubmit="return false;" data-time="0.001" data-auto="true" method="post" class="content layui-form">
<div class="people">
<div class="tou"></div>
<div id="left-hander" class="initial_left_hand transition"></div>
<div id="right-hander" class="initial_right_hand transition"></div>
</div>
<ul>
<li>
<input name='username' style='display:none'/>
<input required="required"
pattern="^\S{4,}$"
title="请输入4位及以上的字符"
type="text"
name="username"
value="admin"
autocomplete="off"
autofocus="autofocus"
class="login-input username"
placeholder="请输入用户名/手机号码"/>
</li>
<li>
<input name='password' style='display:none'/>
<input required="required"
pattern="^\S{4,}$"
title="请输入4位及以上的字符"
type="password"
name="password"
value="admin"
autocomplete="off"
class="login-input password"
placeholder="请输入密码"/>
</li>
<li class="text-center">
<button type="submit" class="layui-btn layui-disabled" data-form-loaded="立 即 登 入"> </button>
<a style="position:absolute;display:block;right:0" href="javascript:void(0)">忘记密码?</a>
</li>
</ul>
</form>
</div>
<!-- 页面表单主体 结束 -->
<!-- 底部版权信息 开始 -->
{if sysconf('site_copy')}
<div class="footer">{:sysconf('site_copy')}</div>
{/if}
<!-- 底部版本信息 结束 -->
</div>
{/block}
{block name="script"}
<script>
if (window.location.href.indexOf('#') > -1) {
window.location.href = window.location.href.split('#')[0];
}
require(['jquery'], function ($) {
$('[name="password"]').on('focus', function () {
$('#left-hander').removeClass('initial_left_hand').addClass('left_hand');
$('#right-hander').removeClass('initial_right_hand').addClass('right_hand')
}).on('blur', function () {
$('#left-hander').addClass('initial_left_hand').removeClass('left_hand');
$('#right-hander').addClass('initial_right_hand').removeClass('right_hand')
});
});
</script>
{/block}

View File

@ -0,0 +1,82 @@
{extend name="admin@public/main"}
{block name="style"}
<link href="__STATIC__/theme/css/login.css" rel="stylesheet">
{/block}
{block name="body"}
<div class="login-container">
<!-- 动态云层动画 开始 -->
<div class="clouds-container">
<div class="clouds clouds-footer"></div>
<div class="clouds"></div>
<div class="clouds clouds-fast"></div>
</div>
<!-- 动态云层动画 结束 -->
<!-- 顶部导航条 开始 -->
<div class="header notselect">
<span class="title notselect">{:sysconf('app_name')} <sup>{:sysconf('app_version')}</sup></span>
<ul>
<li><a href="javascript:void(0)" target="_blank">帮助</a></li>
<li>
<a href="http://sw.bos.baidu.com/sw-search-sp/software/9e6bc213b9d0b/ChromeStandalone_63.0.3239.132_Setup.exe">推荐使用谷歌浏览器</a>
</li>
</ul>
</div>
<!-- 顶部导航条 结束 -->
<!-- 页面表单主体 开始 -->
<div class="container">
<form autocomplete="off" onsubmit="return false;" data-time="0.001" data-auto="true" method="post" class="content layui-form animated fadeInDown">
<div class="people">
<div class="tou"></div>
<div id="left-hander" class="initial_left_hand transition"></div>
<div id="right-hander" class="initial_right_hand transition"></div>
</div>
<ul>
<li class="username">
<i></i>
<input required pattern="^\S{4,}$" name="username" value="admin" type="text" autofocus="autofocus" autocomplete="off" title="请输入4位及以上的字符" placeholder="请输入用户名/手机号码">
</li>
<li class="password">
<i></i>
<input required pattern="^\S{4,}$" name="password" value="admin" type="password" autocomplete="off" title="请输入4位及以上的字符" placeholder="请输入密码">
</li>
<li class="text-center">
<button type="submit" class="layui-btn layui-disabled" data-form-loaded="立 即 登 入"> </button>
</li>
</ul>
</form>
</div>
<!-- 页面表单主体 结束 -->
<!-- 底部版权信息 开始 -->
<!--{if sysconf('site_copy')}-->
<div class="footer notselect">
{:sysconf('site_copy')}
{if sysconf('miitbeian')} <span>|</span> <a target="_blank" href="http://www.miitbeian.gov.cn">{:sysconf('miitbeian')}</a>{/if}
</div>
<!--{/if}-->
<!-- 底部版本信息 结束 -->
</div>
{/block}
{block name="script"}
<script>
if (window.location.href.indexOf('#') > -1) {
window.location.href = window.location.href.split('#')[0];
}
$(function () {
$('[name="password"]').on('focus', function () {
$('#left-hander').removeClass('initial_left_hand').addClass('left_hand');
$('#right-hander').removeClass('initial_right_hand').addClass('right_hand')
}).on('blur', function () {
$('#left-hander').addClass('initial_left_hand').removeClass('left_hand');
$('#right-hander').addClass('initial_right_hand').removeClass('right_hand')
});
});
</script>
{/block}

View File

@ -1,58 +0,0 @@
<form class="layui-form layui-box" style='padding:25px 30px 20px 0' action="__SELF__" data-auto="true" method="post">
<div class="layui-form-item">
<label class="layui-form-label">上级菜单</label>
<div class="layui-input-block">
<select name='pid' class='layui-select full-width' style='display:block'>
<!--{foreach $menus as $menu}-->
<!--{eq name='menu.id' value='$vo.pid|default=0'}-->
<option selected value='{$menu.id}'>{$menu.spl}{$menu.title}</option>
<!--{else}-->
<option value='{$menu.id}'>{$menu.spl}{$menu.title}</option>
<!--{/eq}-->
<!--{/foreach}-->
</select>
</div>
</div>
<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="required" title="请输入菜单名称" 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" onblur="(this.value === '') && (this.value = '#')" name="url" autocomplete="off" required="required" title="请输入菜单链接" placeholder="请输入菜单链接" value="{$vo.url|default='#'}" class="layui-input typeahead">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">菜单图标</label>
<div class="layui-input-inline" style='width:300px'>
<input placeholder="请输入或选择图标" onchange="$('#icon-preview').get(0).className = this.value" type="text" name="icon" value='{$vo.icon|default=""}' class="layui-input">
</div>
<span class='layui-btn layui-btn-primary' style='padding:0 12px;min-width:45.2px'>
<i id='icon-preview' style='font-size:1.2em' class='{$vo.icon|default=""}'></i>
</span>
<button data-icon='icon' type='button' class='layui-btn layui-btn-primary'>选择图标</button>
</div>
<div class="hr-line-dashed"></div>
<div class="layui-form-item text-center">
{if isset($vo['id'])}<input type='hidden' value='{$vo.id}' name='id'/>{/if}
<button class="layui-btn" type='submit'>保存数据</button>
<button class="layui-btn layui-btn-danger" type='button' data-confirm="确定要取消编辑吗?" data-close>取消编辑</button>
</div>
<script>
require(['bootstrap.typeahead'], function () {
var subjects = JSON.parse('{$nodes|json_encode}');
$('.typeahead').typeahead({source: subjects, items: 5});
});
</script>
</form>

View File

@ -1,73 +0,0 @@
{extend name='extra@admin/content'}
{block name="button"}
<div class="nowrap pull-right" style="margin-top:10px">
<button data-modal='{:url("$classuri/add")}' data-title="添加菜单" class='layui-btn layui-btn-small'><i class='fa fa-plus'></i> 添加菜单</button>
<button data-update data-field='delete' data-action='{:url("$classuri/del")}' class='layui-btn layui-btn-small layui-btn-danger'><i class='fa fa-remove'></i> 删除菜单</button>
</div>
{/block}
{block name="content"}
<form onsubmit="return false;" data-auto="true" method="post">
<input type="hidden" value="resort" name="action"/>
<table class="table table-hover">
<thead>
<tr>
<th class='list-table-check-td'>
<input data-none-auto="" data-check-target='.list-check-box' type='checkbox'/>
</th>
<th class='list-table-sort-td'>
<button type="submit" class="layui-btn layui-btn-normal layui-btn-mini"> </button>
</th>
<th class='text-center'></th>
<th>菜单名称</th>
<th class='visible-lg'>菜单链接</th>
<th class='text-center'>状态</th>
<th class='text-center'>操作</th>
</tr>
</thead>
<tbody>
{foreach $list as $key=>$vo}
<tr>
<td class='list-table-check-td'>
<input class="list-check-box" value='{$vo.ids}' type='checkbox'/>
</td>
<td class='list-table-sort-td'>
<input name="_{$vo.id}" value="{$vo.sort}" class="list-sort-input"/>
</td>
<td class='text-center'>
<i style="font-size:18px;" class="{$vo.icon}"></i>
</td>
<td>{$vo.spl}{$vo.title}</td>
<td class='visible-lg'>{$vo.url}</td>
<td class='text-center'>
{if $vo.status eq 0}
<span>已禁用</span>
{elseif $vo.status eq 1}
<span style="color:#090">使用中</span>
{/if}
</td>
<td class='text-center nowrap'>
{if auth("$classuri/edit")}
<span class="text-explode">|</span>
<a data-modal='{:url("$classuri/edit")}?id={$vo.id}' href="javascript:void(0)">编辑</a>
{/if}
{if $vo.status eq 1 and auth("$classuri/forbid")}
<span class="text-explode">|</span>
<a data-update="{$vo.ids}" data-field='status' data-value='0'data-action='{:url("$classuri/forbid")}' href="javascript:void(0)">禁用</a>
{elseif auth("$classuri/resume")}
<span class="text-explode">|</span>
<a data-update="{$vo.ids}" data-field='status' data-value='1' data-action='{:url("$classuri/resume")}' href="javascript:void(0)">启用</a>
{/if}
{if auth("$classuri/del")}
<span class="text-explode">|</span>
<a data-update="{$vo.ids}" data-field='delete' data-action='{:url("$classuri/del")}' href="javascript:void(0)">删除</a>
{/if}
</td>
</tr>
{/foreach}
</tbody>
</table>
</form>
{/block}

View File

@ -0,0 +1,74 @@
<form autocomplete="off" class="layui-form layui-box modal-form-box" action="{:request()->url()}" data-auto="true" method="post">
<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 color-desc"><b>必填</b>,请选择上级菜单或顶级菜单(目前最多支持三级菜单)</p>
</div>
</div>
<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="required" title="请输入菜单名称" placeholder="请输入菜单名称" class="layui-input">
<p class="help-block color-desc"><b>必填</b>请填写菜单名称系统管理建议字符不要太长一般4-6个汉字</p>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">菜单链接</label>
<div class="layui-input-block">
<input type="text" onblur="(this.value === '') && (this.value = '#')" name="url" autocomplete="off" required="required" title="请输入菜单链接" placeholder="请输入菜单链接" value="{$vo.url|default='#'}" class="layui-input typeahead">
<p class="help-block color-desc">
<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 type="text" name="params" autocomplete="off" title="请输入链接参数" placeholder="请输入链接参数" value="{$vo.params|default=''}" class="layui-input">
<p class="help-block color-desc"><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" style='width:300px'>
<input placeholder="请输入或选择图标" onchange="$('#icon-preview').get(0).className = this.value" type="text" name="icon" value='{$vo.icon|default=""}' class="layui-input">
</div>
<span class='layui-btn layui-btn-primary' style='padding:0 12px;min-width:45px'>
<i id='icon-preview' style='font-size:1.2em' class='{$vo.icon|default=""}'></i>
</span>
<button data-icon='icon' type='button' class='layui-btn layui-btn-primary'>选择图标</button>
<p class="help-block color-desc"><b>可选</b>,设置菜单选项前置图标,目前只支持 Font Awesome 4.7.0 字体图标</p>
</div>
</div>
<div class="hr-line-dashed"></div>
<div class="layui-form-item text-center">
{if isset($vo['id'])}<input type='hidden' value='{$vo.id}' name='id'>{/if}
<button class="layui-btn" type='submit'>保存数据</button>
<button class="layui-btn layui-btn-danger" type='button' data-confirm="确定要取消编辑吗?" data-close>取消编辑</button>
</div>
<script>
require(['bootstrap.typeahead'], function () {
var subjects = JSON.parse('{$nodes|raw|json_encode}');
$('.typeahead').typeahead({source: subjects, items: 5});
});
</script>
</form>

View File

@ -0,0 +1,87 @@
{extend name='admin@public/content'}
{block name="button"}
<!--{if auth("$classuri/add")}-->
<button data-modal='{:url("$classuri/add")}' data-title="添加菜单" class='layui-btn layui-btn-sm layui-btn-primary'>添加菜单</button>
<!--{/if}-->
<!--{if auth("$classuri/del")}-->
<button data-update data-field='delete' data-action='{:url("$classuri/del")}' class='layui-btn layui-btn-sm layui-btn-primary'>删除菜单</button>
<!--{/if}-->
{/block}
{block name="content"}
<form autocomplete="off" onsubmit="return false;" data-auto="true" method="post">
<!--{empty name='list'}-->
<p class="help-block text-center well"> 哦!</p>
<!--{else}-->
<input type="hidden" value="resort" name="action">
<table id="test" 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="submit" class="layui-btn layui-btn-normal layui-btn-xs"> </button>
</th>
<th class='text-center'></th>
<th></th>
<th class='visible-lg'></th>
<th class='text-center'></th>
<th class='text-center'></th>
</tr>
</thead>
<tbody>
<!--{foreach $list as $key=>$vo}-->
<tr>
<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 name="_{$vo.id}" 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='visible-lg'>{$vo.url}</td>
<td class='text-center nowrap'>
{if $vo.status eq 0}<span>已禁用</span>{elseif $vo.status eq 1}<span class="color-green">使用中</span>{/if}
</td>
<td class='text-center nowrap notselect'>
{if auth("$classuri/add")}
<span class="text-explode">|</span>
<!--{if $vo.spt<2}-->
<a data-title="添加菜单" data-modal='{:url("$classuri/add")}?pid={$vo.id}'>添加下级</a>
<!--{else}-->
<a class="color-desc">添加下级</a>
<!--{/if}-->
{/if}
{if auth("$classuri/edit")}
<span class="text-explode">|</span>
<a data-title="编辑菜单" data-modal='{:url("$classuri/edit")}?id={$vo.id}'>编辑</a>
{/if}
{if $vo.status eq 1 and auth("$classuri/forbid")}
<span class="text-explode">|</span>
<a data-update="{$vo.ids}" data-field='status' data-value='0' data-action='{:url("$classuri/forbid")}'>禁用</a>
{elseif auth("$classuri/resume")}
<span class="text-explode">|</span>
<a data-update="{$vo.ids}" data-field='status' data-value='1' data-action='{:url("$classuri/resume")}'>启用</a>
{/if}
{if auth("$classuri/del")}
<span class="text-explode">|</span>
<a data-update="{$vo.ids}" data-field='delete' data-action='{:url("$classuri/del")}'>删除</a>
{/if}
</td>
</tr>
<!--{/foreach}-->
</tbody>
</table>
<!--{/empty}-->
</form>
{/block}

View File

@ -1,69 +0,0 @@
{extend name='extra@admin/content'}
{block name="content"}
<table class="table table-hover">
<thead>
<tr>
<th style="width:20px"></th>
<th class='text-left'>系统节点结构</th>
<th class='text-left'></th>
<th>&nbsp;</th>
</tr>
</thead>
<tbody>
{foreach $nodes as $key=>$vo}
<tr>
<td style="width:20px"></td>
<td class='text-left nowrap'>
{$vo.spl}{$vo.node}
{if auth("$classuri/save")}
&nbsp;<input class='layui-input layui-input-inline title-input' style='height:28px;line-height:28px;width:auto' name='title.{$vo.node}' value="{$vo.title}"/>
{/if}
</td>
<td class='text-left nowrap'>
{if auth("$classuri/save")}
<label>
{if substr_count($vo['node'],'/')==2}
{notempty name='vo.is_auth'}
<input name='is_auth.{$vo.node}' checked='checked' class="check-box" type='checkbox' value='1'/>
{else}
<input name='is_auth.{$vo.node}' class="check-box" type='checkbox' value='1'/>
{/notempty}
加入权限控制
{/if}
</label>
&nbsp;&nbsp;&nbsp;&nbsp;
<label>
{if substr_count($vo['node'],'/')==2}
{notempty name='vo.is_menu'}
<input name='is_menu.{$vo.node}' checked='checked' class='check-box' type='checkbox' value='1'/>
{else}
<input name='is_menu.{$vo.node}' class='check-box' type='checkbox' value='1'/>
{/notempty}
可设为菜单
{/if}
</label>
{/if}
</td>
<td style="width:100%"></td>
</tr>
{/foreach}
</tbody>
</table>
{if auth("$classuri/save")}
<script>
$(function () {
$('input.title-input').on('blur', function () {
$.form.load('{:url("save")}', {name: this.name, value: this.value}, 'POST', function (ret) {
return false;
});
});
$('input.check-box').on('click', function () {
$.form.load('{:url("save")}', {name: this.name, value: this.checked ? 1 : 0}, 'POST', function (ret) {
return false;
});
});
});
</script>
{/if}
{/block}

View File

@ -0,0 +1,225 @@
{extend name='admin@public/content'}
{block name='button'}
<!--{if auth("$classuri/clear")}-->
<button data-load='{:url("$classuri/clear")}' class='layui-btn layui-btn-sm layui-btn-primary'>清理无效记录</button>
<!--{/if}-->
{/block}
{block name="content"}
<style>
.layui-table .title-input {
width: auto;
height: 28px;
line-height: 28px;
}
.layui-table label {
cursor: pointer
}
</style>
<script>
$(function () {
$('.layui-tab ul.layui-tab-title li:first').trigger('click');
});
</script>
<div class="layui-tab layui-tab-card layui-box">
<ul class="layui-tab-title">
<!--{foreach $groups as $key=>$group}-->
<li>{$group.node.title|default='<span class="color-desc">未配置名称</span>'|raw}{$key}</li>
<!--{/foreach}-->
</ul>
<div class="layui-tab-content">
{foreach $groups as $k=>$group}
<div class="layui-tab-item">
<table class="layui-table border-none" lay-skin="line">
<!--{empty name='nodes'}-->
<p class="help-block text-center well"> 哦!</p>
<!--{else}-->
<!--{foreach $group.list as $key=>$vo}-->
<tr>
<td class='text-left nowrap'>
<span class="color-desc">{$vo.spl|raw}</span> {$vo.node}
{if auth("$classuri/save")}&nbsp;<input autocomplete="off" class='layui-input layui-input-inline title-input' name='title' data-node="{$vo.node}" value="{$vo.title}">{/if}
</td>
<td class='text-left nowrap'>
{if auth("$classuri/save") and $vo.spt eq 1}
<label class="color-desc think-checkbox">
<input data-login-group="{$vo.node}" type="checkbox"> 全部加入登录控制
</label>
&nbsp;&nbsp;&nbsp;&nbsp;
<label class="notselect margin-left-15 color-desc think-checkbox">
<input data-auth-group="{$vo.node}" type="checkbox"> 全部加入权限控制
</label>
&nbsp;&nbsp;&nbsp;&nbsp;
<label class="notselect margin-left-15 color-desc think-checkbox">
<input data-menu-group="{$vo.node}" type="checkbox"> 全部加入菜单节点选择器
</label>
{/if}
{if auth("$classuri/save") and $vo.spt eq 2}
<span class="color-desc">&nbsp;&nbsp;├─&nbsp;</span>
<label class="notselect margin-right-15 think-checkbox">
<!--{notempty name='vo.is_login'}-->
<input data-login-filter="{$vo.pnode}" checked='checked' class="check-box login_{$k}_{$key}" type='checkbox' value='1' name='is_login' data-node="{$vo.node}" onclick="!this.checked && ($('.auth_{$k}_{$key}')[0].checked = !!this.checked)">
<!--{else}-->
<input data-login-filter="{$vo.pnode}" class="check-box login_{$k}_{$key}" type='checkbox' value='1' name='is_login' data-node="{$vo.node}" onclick="!this.checked && ($('.auth_{$k}_{$key}')[0].checked = !!this.checked)">
<!--{/notempty}-->
加入登录控制
</label>
<span class="color-desc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;├─&nbsp;</span>
<label class="notselect margin-right-15 think-checkbox">
<!--{notempty name='vo.is_auth'}-->
<input data-auth-filter="{$vo.pnode}" name='is_auth' data-node="{$vo.node}" checked='checked' class="check-box auth_{$k}_{$key}" type='checkbox' onclick="this.checked && ($('.login_{$k}_{$key}')[0].checked = !!this.checked)" value='1'>
<!--{else}-->
<input data-auth-filter="{$vo.pnode}" name='is_auth' data-node="{$vo.node}" class="check-box auth_{$k}_{$key}" type='checkbox' value='1' onclick="this.checked && ($('.login_{$k}_{$key}')[0].checked = !!this.checked)">
<!--{/notempty}-->
加入权限控制
</label>
<span class="color-desc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;├─&nbsp;</span>
<label class="notselect think-checkbox">
<!--{notempty name='vo.is_menu'}-->
<input data-menu-filter="{$vo.pnode}" name='is_menu' data-node="{$vo.node}" checked='checked' class='check-box menu_{$k}_{$key}' type='checkbox' value='1'>
<!--{else}-->
<input data-menu-filter="{$vo.pnode}" name='is_menu' data-node="{$vo.node}" class='check-box menu_{$k}_{$key}' type='checkbox' value='1'>
<!--{/notempty}-->
加入菜单节点选择器
</label>
{/if}
</td>
<td data-tips-filter="{$vo.pnode}" class="loading-tips nowrap full-width"></td>
</tr>
<!--{/foreach}-->
<!--{/empty}-->
</table>
</div>
{/foreach}
</div>
</div>
<!--{if auth("$classuri/save")}-->
<script>
$(function () {
syncLoginGroup.call(this);
$('[data-login-group]').on('click', function () {
var twoNode = this.getAttribute('data-login-group');
if (!checkRequestStatus(twoNode)) {
this.checked = !this.checked;
return $.msg.tips('正在处理中, 请稍候...');
}
var checked = !!this.checked;
$('[data-login-filter="' + twoNode + '"]').map(function () {
if (!(this.checked = checked)) {
$('[data-auth-filter="' + twoNode + '"]').map(function () {
this.checked = false;
});
}
update(this);
});
});
syncAuthGroup.call(this);
$('[data-auth-group]').on('click', function () {
var twoNode = this.getAttribute('data-auth-group');
if (!checkRequestStatus(twoNode)) {
this.checked = !this.checked;
return $.msg.tips('正在处理中, 请稍候...');
}
var checked = !!this.checked;
$('[data-auth-filter="' + twoNode + '"]').map(function () {
if ((this.checked = checked)) {
$('[data-login-filter="' + twoNode + '"]').map(function () {
this.checked = checked;
});
}
update(this);
});
});
syncMenuGroup.call(this);
$('[data-menu-group]').on('click', function () {
var twoNode = this.getAttribute('data-menu-group');
if (!checkRequestStatus(twoNode)) {
this.checked = !this.checked;
return $.msg.tips('正在处理中, 请稍候...');
}
var checked = !!this.checked;
$('[data-menu-filter="' + twoNode + '"]').map(function () {
this.checked = checked;
update(this);
});
});
// 更新触发更新
$('input.check-box').on('click', function () {
update(this);
});
$('input.title-input').on('blur', function () {
update(this);
});
// 数据自动更新
function update(self) {
var $item = $(self).parents('tr'), data = {list: []};
$item.find('input').map(function () {
var value = this.type === 'text' ? this.value : (this.checked ? 1 : 0);
data.list.push({name: this.name, value: value, node: this.getAttribute('data-node')});
});
$item.find('.loading-tips').html('<p class="color-green"><i class="fa fa-spinner fa-spin"></i> 更新数据...</p>');
$.form.load('{:url("save")}', data, 'post', function (ret) {
if (ret.code === 0) {
var tips = '<p class="color-red"><i class="fa fa-close"></i> 更新异常</p>';
return $item.find('.loading-tips').html(tips), false;
}
return $item.find('.loading-tips').html(''), false;
}, false);
return syncLoginGroup(), syncMenuGroup(), syncAuthGroup();
}
// 状态网络处理状态
function checkRequestStatus(twoNode) {
var status = true;
$('.loading-tips[data-tips-filter="' + twoNode + '"]').map(function () {
$(this).html() && (status = false);
});
return status;
}
// 同步登录分组状态
function syncLoginGroup() {
$('[data-login-group]').map(function () {
var node = this.getAttribute('data-login-group'), checked = true;
$('[data-login-filter="' + node + '"]').map(function () {
this.checked || (checked = false);
});
this.checked = checked;
});
}
// 同步权限分组状态
function syncAuthGroup() {
$('[data-auth-group]').map(function () {
var node = this.getAttribute('data-auth-group'), checked = true;
$('[data-auth-filter="' + node + '"]').map(function () {
this.checked || (checked = false);
});
this.checked = checked;
});
}
// 同步菜单分组状态
function syncMenuGroup() {
$('[data-menu-group]').map(function () {
var node = this.getAttribute('data-menu-group'), checked = true;
$('[data-menu-filter="' + node + '"]').map(function () {
this.checked || (checked = false);
});
this.checked = checked;
});
}
});
</script>
<!--{/if}-->
{/block}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -6,11 +6,11 @@
<link rel="icon" href="../image/favicon.ico">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=0">
<link href="__PUBLIC__/static/plugs/uploader/webuploader.css" rel="stylesheet" type="text/css"/>
<link href="__PUBLIC__/static/plugs/uploader/theme/uploader.css" rel="stylesheet" type="text/css"/>
<script src="__PUBLIC__/static/plugs/jquery/jquery.min.js" type="text/javascript"></script>
<script src="__PUBLIC__/static/plugs/uploader/webuploader.min.js" type="text/javascript"></script>
<script src="__PUBLIC__/static/plugs/uploader/theme/upload.js" type="text/javascript"></script>
<link href="__STATIC__/plugs/uploader/webuploader.css" rel="stylesheet" type="text/css"/>
<link href="__STATIC__/plugs/uploader/theme/uploader.css" rel="stylesheet" type="text/css"/>
<script src="__STATIC__/plugs/jquery/jquery.min.js"></script>
<script src="__STATIC__/plugs/uploader/webuploader.min.js"></script>
<script src="__STATIC__/plugs/uploader/theme/upload.js"></script>
</head>
<body>
<div id="uploader">
@ -43,40 +43,38 @@
function uploaded(ret, file) {
var url = ret.url || ret.site_url;
$('#' + file.id).attr('data-md5', file.md5).attr('data-src', url);
/* {if $mode === 'one'} */
/*{if $mode === 'one'}*/
top.$('[name="{$field}"]').map(function () {
top.$(this).attr('data-srcs', ret.url).attr('data-md5', file.md5).val(url).trigger('change');
});
//top.$.msg.tips('文件上传成功!');
var index = top.layer.getFrameIndex(window.name);
top.layer.close(index);
/* {/if} {$mode}*/
top.layer.close(top.layer.getFrameIndex(window.name));
/*{/if}*/
}
function confirmSelected() {
var srcs = new Array(), md5s = new Array();
$('[data-md5] .success').map(function () {
var $li = $(this).parents('[data-md5]');
md5s.push($li.attr('data-md5'));
srcs.push($li.attr('data-src'));
});
if (srcs.length < 1) {
return top.$.msg.tips('还没有选择文件,请勾选需要使用的文件!');
}
top.$('[name="{$field}"]').map(function () {
top.$(this).attr('data-srcs', srcs.join('|')).attr('data-md5', md5s.join('|')).val(srcs.join('|')).trigger('change');
});
var index = top.layer.getFrameIndex(window.name);
top.layer.close(index);
}
var isSuccessState = false;
function completed() {
var btnHTML = '完成上传';
$('.uploadBtn').on('click', function () {
if (this.innerHTML === btnHTML) {
confirmSelected.call(this);
$('.uploadBtn').html(btnHTML).on('click', successSelected);
function successSelected() {
if (!isSuccessState && this.innerHTML === btnHTML) {
isSuccessState = true;
var srcs = [], md5s = [];
$('[data-md5] .success').map(function () {
var $li = $(this).parents('[data-md5]');
md5s.push($li.attr('data-md5'));
srcs.push($li.attr('data-src'));
});
if (srcs.length < 1) {
return top.$.msg.tips('还没有选择文件,请勾选需要使用的文件!');
}
top.$('[name="{$field}"]').map(function () {
top.$(this).attr('data-srcs', srcs.join('|')).attr('data-md5', md5s.join('|')).val(srcs.join('|')).trigger('change');
});
top.layer.close(top.layer.getFrameIndex(window.name));
}
}).html(btnHTML);
}
}
// 当domReady的时候开始初始化
@ -121,7 +119,7 @@
flashVersion = (function () {
var version;
try {
version = navigator.plugins[ 'Shockwave Flash' ];
version = navigator.plugins['Shockwave Flash'];
version = version.description;
} catch (ex) {
try {
@ -131,12 +129,12 @@
}
}
version = version.match(/\d+/g);
return parseFloat(version[ 0 ] + '.' + version[ 1 ], 10);
return parseFloat(version[0] + '.' + version[1], 10);
})(),
supportTransition = (function () {
var s = document.createElement('p').style, r = 'transition' in s || 'WebkitTransition' in s || 'MozTransition' in s || 'msTransition' in s || 'OTransition' in s;
s = null;
return r;
var s = document.createElement('p').style,
r = 'transition' in s || 'WebkitTransition' in s || 'MozTransition' in s || 'msTransition' in s || 'OTransition' in s;
return (s = null), r;
})(),
uploader;
if (!WebUploader.Uploader.support('flash') && WebUploader.browser.ie) {
@ -146,10 +144,10 @@
window['expressinstallcallback'] = function (state) {
switch (state) {
case 'Download.Cancelled':
alert('您取消了更新!')
alert('您取消了更新!');
break;
case 'Download.Failed':
alert('安装失败')
alert('安装失败');
break;
default:
alert('安装已成功,请刷新!');
@ -157,7 +155,7 @@
}
delete window['expressinstallcallback'];
};
var swf = '__PUBLIC__/static/plugs/uploader/expressInstall.swf';
var swf = '__STATIC__/plugs/uploader/expressInstall.swf';
var html = '<object type="application/' + 'x-shockwave-flash" data="' + swf + '" ';
if (WebUploader.browser.ie) {
html += 'classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" ';
@ -177,15 +175,17 @@
alert('Web Uploader 不支持您的浏览器!');
return;
}
WebUploader.Uploader.register({'before-send-file': 'preupload'}, {preupload: function (file) {
// 文件上传前的检查
WebUploader.Uploader.register({'before-send-file': 'preupload'}, {
preupload: function (file) {
var me = this, owner = this.owner, deferred = WebUploader.Deferred();
owner.md5File(file.source).fail(function () {
deferred.reject();
}).then(function (md5) {
file.md5 = md5;
var data = {id: file.id, md5: md5, uptype: '{$uptype}', filename: file.name};
$.ajax("{:url('admin/plugs/upstate')}", {dataType: 'json', method: 'post', data: data, success: function (ret) {
$.ajax("{:url('admin/plugs/upstate')}", {
dataType: 'json', method: 'post', data: data, success: function (ret) {
if (ret.code !== 'NOT_FOUND') {
owner.skipFile(file);
uploaded.call(uploader, ret.data, file);
@ -218,25 +218,21 @@
label: '点击选择文件',
/*{if $mode === 'one'}*/
multiple: false,
/* {else} */
/*{else}*/
multiple: true,
/* {/if} */
},
accept: {
title: '选择文件',
extensions: '{$types}', //'gif,jpg,jpeg,bmp,png',
mimeTypes: '{$mimes}'
/*{/if}*/
},
accept: {title: '选择文件', extensions: '{$types}', mimeTypes: '{$mimes}'},
formData: {},
/*{if $mode === 'one'}*/
auto: true,
fileNumLimit: 1,
/* {else} */
/*{else}*/
auto: false,
fileNumLimit: 300,
/* {/if} */
/*{/if}*/
server: '{:url("admin/plugs/upload")}',
swf: '__PUBLIC__/static/plugs/uploader/Uploader.swf',
swf: '__STATIC__/plugs/uploader/Uploader.swf',
chunked: false,
dnd: '#dndArea',
paste: document.body,
@ -249,7 +245,7 @@
height: 16000,
crop: false, // 是否允许裁剪
quality: 90, // 图片质量(只有type为`image/jpeg`的时候才有效)
allowMagnify: false, // // 是否允许放大(如果想要生成小图的时候不失真此选项应该设置为false).
allowMagnify: false, // 是否允许放大(如果想要生成小图的时候不失真此选项应该设置为false).
preserveHeaders: true, // 是否保留头部meta信息
noCompressIfLarger: false, // 如果发现压缩后文件大小比原来还大,则使用原来图片
compressSize: 1024 * 512, // 单位字节(如果图片大小小于此值,不会采用压缩)
@ -260,16 +256,12 @@
uploader.on('uploadBeforeSend', function (file, data, header) {
header['X_Requested_With'] = 'XMLHttpRequest';
data['allowed_types'] = this.options.accept[0].extensions.split(',').join('|');
data['token'] = file.file.token;
data['md5'] = file.file.md5;
data['key'] = file.file.key;
data['token'] = file.file.token;
});
/**
* 处理上传后的结果
* @param {type} file
* @returns {undefined}
*/
/* 处理上传后的结果 */
uploader.on('uploadAccept', function (fieldata, ret) {
// Qiniu or Local 上传
if (ret.code === 'SUCCESS') {
@ -281,15 +273,16 @@
uploaded.call(uploader, {'site_url': fieldata.file.site_url}, fieldata.file);
return true;
}
// 接收服务器返回的错误消息
fieldata.file.setStatus('error', ret.msg);
return false;
});
// 拖拽时不接受 js, txt 文件。
uploader.on('dndAccept', function (items) {
var denied = false, len = items.length;
var unAllowed = 'text/plain;application/javascript ';
var denied = false, len = items.length, unAllowed = 'text/plain;application/javascript ';
for (var i = 0; i < len; i++) {
if (~unAllowed.indexOf(items[ i ].type)) {
if (~unAllowed.indexOf(items[i].type)) {
denied = true;
break;
}
@ -297,62 +290,52 @@
return !denied;
});
// 添加“添加文件”的按钮,
uploader.addButton({
id: '#filePicker2',
label: '继续添加'
});
uploader.addButton({id: '#filePicker2', label: '继续添加'});
uploader.on('ready', function () {
window.uploader = uploader;
});
// 当有文件添加进来时执行负责view的创建
function addFile(file) {
var $li = $('<li id="' + file.id + '">' + '<p class="title">' + file.name + '</p>' +
'<p class="imgWrap"></p>' +
'<p class="progress"><span></span></p>' +
'</li>'),
$btns = $('<div class="file-panel">' +
'<span class="cancel">删除</span>' +
'<span class="rotateRight">向右旋转</span>' +
'<span class="rotateLeft">向左旋转</span></div>').appendTo($li),
$prgress = $li.find('p.progress span'),
$wrap = $li.find('p.imgWrap'),
$info = $('<p class="error"></p>'),
showError = function (code) {
var text = '';
switch (code) {
case 'exceed_size':
text = '文件大小超出';
break;
case 'interrupt':
text = '上传暂停';
break;
default:
text = '上传失败,请重试';
break;
}
$info.text(text).appendTo($li);
};
var $li = $('<li id="' + file.id + '"><p class="title">' + file.name + '</p><p class="imgWrap"></p><p class="progress"><span></span></p></li>'),
$btns = $('<div class="file-panel"><span class="cancel">删除</span><span class="rotateRight">向右旋转</span><span class="rotateLeft">向左旋转</span></div>').appendTo($li),
$prgress = $li.find('p.progress span'), $wrap = $li.find('p.imgWrap'), $info = $('<p class="error"></p>');
var showError = function (code) {
var text = '';
switch (code) {
case 'exceed_size':
text = '文件大小超出';
break;
case 'interrupt':
text = '上传暂停';
break;
case 'http':
case 'server':
case 'abort':
text = '上传失败,请重试';
break;
default:
text = code;
break;
}
$info.text(text).appendTo($li);
};
if (file.getStatus() === 'invalid') {
showError(file.statusText);
} else {
// @todo lazyload
$wrap.text('预览中');
uploader.makeThumb(file, function (error, src) {
var img;
if (error) {
$wrap.text('不能预览');
return;
return $wrap.text('不能预览');
}
var img;
if (isSupportBase64) {
img = $('<img src="' + src + '">');
$wrap.empty().append(img);
} else {
$.ajax('{"plugs/file/preview"|url}', {method: 'POST', data: src, dataType: 'json'}).done(function (response) {
$.ajax('{"plugs/file/preview"|url}', {method: 'post', data: src, dataType: 'json'}).done(function (response) {
if (response.result) {
img = $('<img src="' + response.result + '">');
$wrap.empty().append(img);
@ -362,50 +345,41 @@
});
}
}, thumbnailWidth, thumbnailHeight);
percentages[ file.id ] = [file.size, 0];
percentages[file.id] = [file.size, 0];
file.rotation = 0;
$upload.html('开始上传');
}
// 文件上传状态变化
file.on('statuschange', function (cur, prev) {
if (prev === 'progress') {
$prgress.hide().width(0);
} else if (prev === 'queued') {
$li.off('mouseenter mouseleave');
$btns.remove();
$li.off('mouseenter mouseleave'), $btns.remove();
}
// 成功
if (cur === 'error' || cur === 'invalid') {
showError(file.statusText);
percentages[ file.id ][ 1 ] = 1;
percentages[file.id][1] = 1;
} else if (cur === 'interrupt') {
showError('interrupt');
} else if (cur === 'queued') {
percentages[ file.id ][ 1 ] = 0;
percentages[file.id][1] = 0;
} else if (cur === 'progress') {
$info.remove();
$prgress.css('display', 'block');
$info.remove(), $prgress.css('display', 'block');
} else if (cur === 'complete') {
$li.append('<span class="success"></span>');
}
$li.removeClass('state-' + prev).addClass('state-' + cur);
});
$li.on('mouseenter', function () {
$btns.stop().animate({height: 30});
});
$li.on('mouseleave', function () {
}).on('mouseleave', function () {
$btns.stop().animate({height: 0});
});
$btns.on('click', 'span', function () {
var index = $(this).index(), deg;
switch (index) {
switch ($(this).index()) {
case 0:
uploader.removeFile(file);
return;
removeFile(file);
return uploader.removeFile(file);
case 1:
file.rotation += 90;
break;
@ -414,7 +388,7 @@
break;
}
if (supportTransition) {
deg = 'rotate(' + file.rotation + 'deg)';
var deg = 'rotate(' + file.rotation + 'deg)';
$wrap.css({'-webkit-transform': deg, '-mos-transform': deg, '-o-transform': deg, 'transform': deg});
} else {
$wrap.css('filter', 'progid:DXImageTransform.Microsoft.BasicImage(rotation=' + (~~((file.rotation / 90) % 4 + 4) % 4) + ')');
@ -425,17 +399,16 @@
// 负责view的销毁
function removeFile(file) {
var $li = $('#' + file.id);
delete percentages[ file.id ];
delete percentages[file.id];
updateTotalProgress();
$li.off().find('.file-panel').off().end().remove();
$('#' + file.id).off().find('.file-panel').off().end().remove();
}
function updateTotalProgress() {
var loaded = 0, total = 0, spans = $progress.children(), percent;
$.each(percentages, function (k, v) {
total += v[ 0 ];
loaded += v[ 0 ] * v[ 1 ];
total += v[0];
loaded += v[0] * v[1];
});
percent = total ? loaded / total : 0;
spans.eq(0).text(Math.round(percent * 100) + '%');
@ -463,7 +436,7 @@
}
function setState(val) {
var file, stats;
var stats;
if (val === state) {
return;
}
@ -519,7 +492,7 @@
uploader.onUploadProgress = function (file, percentage) {
var $li = $('#' + file.id), $percent = $li.find('.progress span');
$percent.css('width', percentage * 100 + '%');
percentages[ file.id ][ 1 ] = percentage;
percentages[file.id][1] = percentage;
updateTotalProgress();
};
@ -530,35 +503,29 @@
$placeHolder.addClass('element-invisible');
$statusBar.show();
}
addFile(file);
setState('ready');
updateTotalProgress();
addFile(file), setState('ready'), updateTotalProgress();
};
uploader.onfieldequeued = function (file) {
fileCount--;
fileSize -= file.size;
!fileCount && setState('pedding');
removeFile(file);
updateTotalProgress();
removeFile(file), updateTotalProgress();
};
uploader.on('all', function (type) {
switch (type) {
case 'uploadFinished':
setState('confirm');
break;
return setState('confirm');
case 'startUpload':
setState('uploading');
break;
return setState('uploading');
case 'stopUpload':
setState('paused');
break;
return setState('paused');
}
});
uploader.onError = function (code) {
//alert('Eroor: ' + code);
// 000alert('Error: ' + code);
};
$upload.on('click', function () {

View File

@ -0,0 +1,13 @@
<!-- 右则内容区域 开始 -->
{block name="style"}{/block}
<div class="layui-card">
<!--{notempty name='title'}-->
<div class="layui-header notselect">
<div class="pull-left"><span>{$title}</span></div>
<div class="pull-right margin-right-15 nowrap">{block name="button"}{/block}</div>
</div>
<!--{/notempty}-->
<div class="layui-card-body">{block name='content'}{/block}</div>
</div>
{block name='script'}{/block}
<!-- 右则内容区域 结束 -->

View File

@ -0,0 +1,26 @@
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="utf-8">
<meta name="renderer" content="webkit">
<title>{block name="title"}{$title|default=''}{if !empty($title)} · {/if}{:sysconf('site_name')}{/block}</title>
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<link href="{:sysconf('browser_icon')}" rel="shortcut icon">
<link href="__STATIC__/plugs/awesome/css/font-awesome.min.css?v={:date('ymd')}" rel="stylesheet">
<link href="__STATIC__/plugs/bootstrap/css/bootstrap.min.css?v={:date('ymd')}" rel="stylesheet">
<link href="__STATIC__/plugs/layui/css/layui.css?v={:date('ymd')}" rel="stylesheet">
<link href="__STATIC__/theme/css/console.css?v={:date('ymd')}" rel="stylesheet">
<link href="__STATIC__/theme/css/animate.css?v={:date('ymd')}" rel="stylesheet">
{block name="style"}{/block}
<script>window.ROOT_URL = '__ROOT__';</script>
<script src="__STATIC__/plugs/jquery/pace.min.js"></script>
<script src="__STATIC__/plugs/layui/layui.all.js"></script>
<script src="__STATIC__/admin.js"></script>
</head>
<body class="framework mini">
{block name="body"}{/block}
<script src="__STATIC__/plugs/require/require.js"></script>
<script src="__STATIC__/app.js"></script>
{block name="script"}{/block}
</body>
</html>

View File

@ -1,110 +0,0 @@
{extend name='extra@admin/content'}
{block name="button"}
<div class="nowrap pull-right" style="margin-top:10px">
<button data-modal='{:url("$classuri/add")}' data-title="添加用户" class='layui-btn layui-btn-small'><i
class='fa fa-plus'></i> 添加用户
</button>
<button data-update data-field='delete' data-action='{:url("$classuri/del")}'
class='layui-btn layui-btn-small layui-btn-danger'><i class='fa fa-remove'></i> 删除用户
</button>
</div>
{/block}
{block name="content"}
<!-- 表单搜索 开始 -->
<form class="animated form-search" action="__SELF__" onsubmit="return false" method="get">
<div class="row">
<div class="col-xs-3">
<div class="form-group">
<input type="text" name="username" value="{$Think.get.username|default=''}" placeholder="用户名" class="input-sm form-control">
</div>
</div>
<div class="col-xs-3">
<div class="form-group">
<input type="text" name="phone" value="{$Think.get.phone|default=''}" placeholder="手机号" class="input-sm form-control">
</div>
</div>
<div class="col-xs-1">
<div class="form-group">
<button type="submit" class="btn btn-sm btn-white"><i class="fa fa-search"></i> 搜索</button>
</div>
</div>
</div>
</form>
<!-- 表单搜索 结束 -->
<form onsubmit="return false;" data-auto="" method="POST">
<input type="hidden" value="resort" name="action"/>
<table class="table table-hover">
<thead>
<tr>
<th class='list-table-check-td'>
<input data-none-auto="" data-check-target='.list-check-box' type='checkbox'/>
</th>
<th class='text-center'>用户账号</th>
<th class='text-center'>手机号</th>
<th class='text-center'>电子邮箱</th>
<th class='text-center'>登录次数</th>
<th class='text-center'>最后登录</th>
<th class='text-center'>状态</th>
<th class='text-center'>操作</th>
</tr>
</thead>
<tbody>
{foreach $list as $key=>$vo}
<tr>
<td class='list-table-check-td'>
<input class="list-check-box" value='{$vo.id}' type='checkbox'/>
</td>
<td class='text-center'>{$vo.username}</td>
<td class='text-center'>{$vo.phone|default="<span style='color:#ccc'>还没有设置手机号</span>"}</td>
<td class='text-center'>{$vo.mail|default="<span style='color:#ccc'>还没有设置邮箱</span>"}</td>
<td class='text-center'>{$vo.login_num|default="<span style='color:#ccc'>从未登录</span>"}</td>
<td class='text-center'>{$vo.login_at|default="<span style='color:#ccc'>从未登录</span>"}</td>
<td class='text-center'>
{if $vo.status eq 0}
<span>已禁用</span>
{elseif $vo.status eq 1}
<span style="color:#090">使用中</span>
{/if}
</td>
<td class='text-center nowrap'>
{if auth("$classuri/edit")}
<span class="text-explode">|</span>
<a data-modal='{:url("$classuri/edit")}?id={$vo.id}' href="javascript:void(0)">编辑</a>
{/if}
{if auth("$classuri/auth")}
<span class="text-explode">|</span>
<a data-modal='{:url("$classuri/auth")}?id={$vo.id}' href="javascript:void(0)">授权</a>
{/if}
{if auth("$classuri/pass")}
<span class="text-explode">|</span>
<a data-modal='{:url("$classuri/pass")}?id={$vo.id}' href="javascript:void(0)">密码</a>
{/if}
{if $vo.status eq 1 and auth("$classuri/forbid")}
<span class="text-explode">|</span>
<a data-update="{$vo.id}" data-field='status' data-value='0' data-action='{:url("$classuri/forbid")}'
href="javascript:void(0)">禁用</a>
{elseif auth("$classuri/resume")}
<span class="text-explode">|</span>
<a data-update="{$vo.id}" data-field='status' data-value='1' data-action='{:url("$classuri/resume")}'
href="javascript:void(0)">启用</a>
{/if}
{if auth("$classuri/del")}
<span class="text-explode">|</span>
<a data-update="{$vo.id}" data-field='delete' data-action='{:url("$classuri/del")}'
href="javascript:void(0)">删除</a>
{/if}
</td>
</tr>
{/foreach}
</tbody>
</table>
{if isset($page)}<p>{$page}</p>{/if}
</form>
{/block}

View File

@ -1,45 +0,0 @@
<form class="layui-form layui-box" style='padding:25px 30px 20px 0' action="__SELF__" data-auto="true" method="post">
<div class="layui-form-item">
<label class="layui-form-label">用户账号</label>
<div class="layui-input-block">
{if $vo and $vo.username}
<input type="text" readonly="" disabled="" name="username" value='{$vo.username|default=""}' required="required" title="请输入用户名称" placeholder="请输入用户名称" class="layui-input disabled">
{else}
<input type="text" name="username" value='{$vo.username|default=""}' required="required" title="请输入用户名称" placeholder="请输入用户名称" 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="" title="请输入旧的密码" placeholder="请输入旧的密码" class="layui-input">
</div>
</div>
{/if}
<div class="layui-form-item">
<label class="layui-form-label">新的密码</label>
<div class="layui-input-block">
<input type="password" name="password" value='' pattern="^\S{1,}$" required="" title="请输入新的密码" placeholder="请输入新的密码" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">重复密码</label>
<div class="layui-input-block">
<input type="password" name="repassword" value='' pattern="^\S{1,}$" required="" title="请输入重复密码" placeholder="请输入重复密码" class="layui-input">
</div>
</div>
<div class="hr-line-dashed"></div>
<div class="layui-form-item text-center">
{if isset($vo['id'])}<input type='hidden' value='{$vo.id}' name='id'/>{/if}
<button class="layui-btn" type='submit'>保存数据</button>
<button class="layui-btn layui-btn-danger" type='button' data-confirm="确定要取消编辑吗?" data-close>取消编辑</button>
</div>
</form>

View File

@ -1,35 +1,39 @@
<form class="layui-form layui-box" style='padding:25px 30px 20px 0' action="__SELF__" data-auto="true" method="post">
<div class="layui-form-item">
<label class="layui-form-label">用户账号</label>
<div class="layui-input-block">
{if $vo and $vo.username}
<input type="text" readonly="" disabled="" name="username" value='{$vo.username|default=""}' required="required" title="请输入用户名称" placeholder="请输入用户名称" class="layui-input disabled">
{else}
<input type="text" name="username" value='{$vo.username|default=""}' required="required" title="请输入用户名称" placeholder="请输入用户名称" class="layui-input">
{/if}
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">访问授权</label>
<div class="layui-input-block">
{foreach $authorizes as $authorize}
{if in_array($authorize['id'],$vo['authorize'])}
<input type="checkbox" checked name="authorize[]" value="{$authorize.id}" title="{$authorize.title}">
{else}
<input type="checkbox" name="authorize[]" value="{$authorize.id}" title="{$authorize.title}">
{/if}
{/foreach}
</div>
</div>
<div class="hr-line-dashed"></div>
<div class="layui-form-item text-center">
{if isset($vo['id'])}<input type='hidden' value='{$vo.id}' name='id'/>{/if}
<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>
<form autocomplete="off" class="layui-form layui-box modal-form-box" action="{:request()->url()}" data-auto="true" method="post">
<div class="layui-form-item">
<label class="layui-form-label">用户账号</label>
<div class="layui-input-block">
{if $vo and $vo.username}
<input type="text" readonly="" disabled="" name="username" value='{$vo.username|default=""}' required="required" title="请输入用户名称" placeholder="请输入用户名称" class="layui-input layui-bg-gray">
{else}
<input type="text" name="username" value='{$vo.username|default=""}' required="required" title="请输入用户名称" placeholder="请输入用户名称" class="layui-input">
{/if}
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">访问授权</label>
<div class="layui-input-block">
{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}
{if empty($authorizes)}<span class="color-desc" style="line-height:36px">未配置权限</span>{/if}
</div>
</div>
<div class="hr-line-dashed"></div>
<div class="layui-form-item text-center">
{if isset($vo['id'])}<input type='hidden' value='{$vo.id}' name='id'>{/if}
<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>

View File

@ -1,60 +1,61 @@
<form class="layui-form layui-box" style='padding:25px 30px 20px 0' action="__SELF__" data-auto="true" method="post">
<div class="layui-form-item">
<label class="layui-form-label">用户账号</label>
<div class="layui-input-block">
{if $vo and isset($vo.username)}
<input type="text" readonly="" disabled="" name="username" value='{$vo.username|default=""}' required="required" title="请输入用户名称" placeholder="请输入用户名称" class="layui-input disabled">
{else}
<input type="text" name="username" value='{$vo.username|default=""}' required="required" title="请输入用户名称" placeholder="请输入用户名称" class="layui-input">
{/if}
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">联系手机</label>
<div class="layui-input-block">
<input type="tel" autofocus name="phone" value='{$vo.phone|default=""}' pattern="^1[3-9][0-9]{9}$" title="请输入联系手机" 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="mail" pattern="^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$" value='{$vo.mail|default=""}' title="请输入联系邮箱" placeholder="请输入联系邮箱" class="layui-input">
</div>
</div>
{if isset($authorizes)}
<div class="layui-form-item">
<label class="layui-form-label">访问授权</label>
<div class="layui-input-block">
{foreach $authorizes as $authorize}
{if in_array($authorize['id'],$vo['authorize'])}
<input type="checkbox" checked name="authorize[]" value="{$authorize.id}" title="{$authorize.title}">
{else}
<input type="checkbox" name="authorize[]" value="{$authorize.id}" title="{$authorize.title}">
{/if}
{/foreach}
</div>
</div>
{/if}
<div class="layui-form-item">
<label class="layui-form-label">用户描述</label>
<div class="layui-input-block">
<textarea placeholder="请输入用户描述" title="请输入用户描述" class="layui-textarea" name="desc">{$vo.desc|default=""}</textarea>
</div>
</div>
<div class="hr-line-dashed"></div>
<div class="layui-form-item text-center">
{if isset($vo['id'])}<input type='hidden' value='{$vo.id}' name='id'/>{/if}
<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>
<form autocomplete="off" class="layui-form layui-box modal-form-box" action="{:request()->url()}" data-auto="true" method="post">
<div class="layui-form-item">
<label class="layui-form-label">用户账号</label>
<div class="layui-input-block">
{if $vo and isset($vo.username)}
<input readonly="readonly" disabled="disabled" name="username" value='{$vo.username|default=""}' required="required" title="请输入用户名称" placeholder="请输入用户名称" class="layui-input layui-bg-gray">
{else}
<input name="username" value='{$vo.username|default=""}' required="required" pattern="^.{4,}$" title="请输入用户名称" placeholder="请输入4位及以上字符用户名称" class="layui-input">
{/if}
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">联系手机</label>
<div class="layui-input-block">
<input type="tel" autofocus name="phone" value='{$vo.phone|default=""}' pattern="^1[3-9][0-9]{9}$" title="请输入联系手机" placeholder="请输入联系手机" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">联系邮箱</label>
<div class="layui-input-block">
<input name="mail" pattern="^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$" value='{$vo.mail|default=""}' title="请输入联系邮箱" placeholder="请输入联系邮箱" class="layui-input">
</div>
</div>
{if isset($authorizes)}
<div class="layui-form-item">
<label class="layui-form-label">访问授权</label>
<div class="layui-input-block">
{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}
{if empty($authorizes)}<span class="color-desc" style="line-height:36px">未配置权限</span>{/if}
</div>
</div>
{/if}
<div class="layui-form-item">
<label class="layui-form-label">用户描述</label>
<div class="layui-input-block">
<textarea placeholder="请输入用户描述" title="请输入用户描述" class="layui-textarea" name="desc">{$vo.desc|default=""}</textarea>
</div>
</div>
<div class="hr-line-dashed"></div>
<div class="layui-form-item text-center">
{if isset($vo['id'])}<input type='hidden' value='{$vo.id}' name='id'>{/if}
<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>

View File

@ -0,0 +1,136 @@
{extend name='admin@public/content'}
{block name="button"}
<!--{if auth("$classuri/add")}-->
<button data-modal='{:url("$classuri/add")}' data-title="添加用户" class='layui-btn layui-btn-sm layui-btn-primary'>添加用户</button>
<!--{/if}-->
<!--{if auth("$classuri/del")}-->
<button data-update data-field='delete' data-action='{:url("$classuri/del")}' class='layui-btn layui-btn-sm layui-btn-primary'>删除用户</button>
<!--{/if}-->
{/block}
{block name="content"}
<!-- 表单搜索 开始 -->
<form autocomplete="off" class="layui-form layui-form-pane form-search" action="{:request()->url()}" onsubmit="return false" method="get">
<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">
<input name="date" id='range-date' value="{$Think.get.date|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">&#xe615;</i> 搜 索</button>
</div>
</form>
<script>
window.laydate.render({range: true, elem: '#range-date'});
</script>
<!-- 表单搜索 结束 -->
<form onsubmit="return false;" data-auto="true" method="post">
<!--{empty name='list'}-->
<p class="help-block text-center well"> 哦!</p>
<!--{else}-->
<input type="hidden" value="resort" name="action">
<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='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 class='text-left nowrap'>状态</th>
<th class='text-left nowrap'></th>
</tr>
</thead>
<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.username}
</td>
<td class='text-left nowrap'>
{$vo.phone|default="<span class='color-desc'>还没有设置手机号</span>"|raw}
</td>
<td class='text-left nowrap'>
{$vo.mail|default="<span class='color-desc'>还没有设置邮箱</span>"|raw}
</td>
<td class='text-left nowrap'>{$vo.login_num|default=0}</td>
<td class='text-left nowrap'>
{$vo.login_at|format_datetime|default="<span class='color-desc'>从未登录</span>"|raw}
</td>
<td class='text-left nowrap'>
{if $vo.status eq 0}<span class="color-red">已禁用</span>{elseif $vo.status eq 1}<span class="color-green">使用中</span>{/if}
</td>
<td class='text-left nowrap'>
{if auth("$classuri/edit")}
<span class="text-explode">|</span>
<a data-title="编辑用户" data-modal='{:url("$classuri/edit")}?id={$vo.id}'>编辑</a>
{/if}
{if auth("$classuri/auth")}
<span class="text-explode">|</span>
<a data-title="用户授权" data-modal='{:url("$classuri/auth")}?id={$vo.id}'>授权</a>
{/if}
{if auth("$classuri/pass")}
<span class="text-explode">|</span>
<a data-title="设置密码" data-modal='{:url("$classuri/pass")}?id={$vo.id}'>密码</a>
{/if}
{if $vo.status eq 1 and auth("$classuri/forbid")}
<span class="text-explode">|</span>
<a data-update="{$vo.id}" data-field='status' data-value='0' data-action='{:url("$classuri/forbid")}'>禁用</a>
{elseif auth("$classuri/resume")}
<span class="text-explode">|</span>
<a data-update="{$vo.id}" data-field='status' data-value='1' data-action='{:url("$classuri/resume")}'>启用</a>
{/if}
{if auth("$classuri/del")}
<span class="text-explode">|</span>
<a data-update="{$vo.id}" data-field='delete' data-action='{:url("$classuri/del")}'>删除</a>
{/if}
</td>
</tr>
<!--{/foreach}-->
</tbody>
</table>
{if isset($page)}<p>{$page|raw}</p>{/if}
<!--{/empty}-->
</form>
{/block}

View File

@ -0,0 +1,45 @@
<form autocomplete="off" class="layui-form layui-box modal-form-box" action="{:request()->url()}" data-auto="true" method="post">
<div class="layui-form-item">
<label class="layui-form-label">用户账号</label>
<div class="layui-input-block">
{if $vo and $vo.username}
<input readonly="readonly" disabled="disabled" name="username" value='{$vo.username|default=""}' required="required" title="请输入用户名称" placeholder="请输入用户名称" class="layui-input layui-bg-gray">
{else}
<input name="username" value='{$vo.username|default=""}' required="required" title="请输入用户名称" placeholder="请输入用户名称" 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 autofocus name="oldpassword" value='' pattern="^\S{1,}$" required="" title="请输入旧的密码" placeholder="请输入旧的密码" class="layui-input">
</div>
</div>
<!--{/if}-->
<div class="layui-form-item">
<label class="layui-form-label">新的密码</label>
<div class="layui-input-block">
<input name="password" value='' pattern="^\S{1,}$" required="" title="请输入新的密码" placeholder="请输入新的密码" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">重复密码</label>
<div class="layui-input-block">
<input name="repassword" value='' pattern="^\S{1,}$" required="" title="请输入重复密码" placeholder="请输入重复密码" class="layui-input">
</div>
</div>
<div class="hr-line-dashed"></div>
<div class="layui-form-item text-center">
{if isset($vo['id'])}<input type='hidden' value='{$vo.id}' name='id'>{/if}
<button class="layui-btn" type='submit'>保存数据</button>
<button class="layui-btn layui-btn-danger" type='button' data-confirm="确定要取消编辑吗?" data-close>取消编辑</button>
</div>
</form>

View File

@ -1,7 +1,7 @@
<?php
// +----------------------------------------------------------------------
// | Think.Admin
// | ThinkAdmin
// +----------------------------------------------------------------------
// | 版权所有 2014~2017 广州楚才信息科技有限公司 [ http://www.cuci.cc ]
// +----------------------------------------------------------------------
@ -9,71 +9,24 @@
// +----------------------------------------------------------------------
// | 开源协议 ( https://mit-license.org )
// +----------------------------------------------------------------------
// | github开源项目https://github.com/zoujingli/Think.Admin
// | github开源项目https://github.com/zoujingli/ThinkAdmin
// +----------------------------------------------------------------------
use service\DataService;
use service\NodeService;
use Wechat\Loader;
use think\Db;
/**
* 打印输出数据到文件
* @param mixed $data
* @param bool $replace
* @param string|null $pathname
* @param mixed $data 输出的数据
* @param bool $force 强制替换
* @param string|null $file
*/
function p($data, $replace = false, $pathname = NULL) {
is_null($pathname) && $pathname = RUNTIME_PATH . date('Ymd') . '.txt';
$str = (is_string($data) ? $data : (is_array($data) || is_object($data)) ? print_r($data, true) : var_export($data, true)) . "\n";
$replace ? file_put_contents($pathname, $str) : file_put_contents($pathname, $str, FILE_APPEND);
}
/**
* 获取微信操作对象
* @param string $type
* @return \Wechat\WechatReceive|\Wechat\WechatUser|\Wechat\WechatPay|\Wechat\WechatScript|\Wechat\WechatOauth|\Wechat\WechatMenu
*/
function & load_wechat($type = '') {
static $wechat = array();
$index = md5(strtolower($type));
if (!isset($wechat[$index])) {
$config = [
'token' => sysconf('wechat_token'),
'appid' => sysconf('wechat_appid'),
'appsecret' => sysconf('wechat_appsecret'),
'encodingaeskey' => sysconf('wechat_encodingaeskey'),
'mch_id' => sysconf('wechat_mch_id'),
'partnerkey' => sysconf('wechat_partnerkey'),
'ssl_cer' => sysconf('wechat_cert_cert'),
'ssl_key' => sysconf('wechat_cert_key'),
'cachepath' => CACHE_PATH . 'wxpay' . DS,
];
$wechat[$index] = Loader::get($type, $config);
}
return $wechat[$index];
}
/**
* 安全URL编码
* @param array|string $data
* @return string
*/
function encode($data) {
return str_replace(['+', '/', '='], ['-', '_', ''], base64_encode(serialize($data)));
}
/**
* 安全URL解码
* @param string $string
* @return string
*/
function decode($string) {
$data = str_replace(['-', '_'], ['+', '/'], $string);
$mod4 = strlen($data) % 4;
!!$mod4 && $data .= substr('====', $mod4);
return unserialize(base64_decode($data));
function p($data, $force = false, $file = null)
{
is_null($file) && $file = env('runtime_path') . date('Ymd') . '.txt';
$str = (is_string($data) ? $data : (is_array($data) || is_object($data)) ? print_r($data, true) : var_export($data, true)) . PHP_EOL;
$force ? file_put_contents($file, $str) : file_put_contents($file, $str, FILE_APPEND);
}
/**
@ -81,46 +34,77 @@ function decode($string) {
* @param string $node
* @return bool
*/
function auth($node) {
function auth($node)
{
return NodeService::checkAuthNode($node);
}
/**
* 设备或配置系统参数
* @param string $name 参数名称
* @param bool $value 默认是false为获取值,否则为更新
* @param bool $value 默认是null为获取值,否则为更新
* @return string|bool
* @throws \think\Exception
* @throws \think\exception\PDOException
*/
function sysconf($name, $value = false) {
function sysconf($name, $value = null)
{
static $config = [];
if ($value !== false) {
$config = [];
$data = ['name' => $name, 'value' => $value];
if ($value !== null) {
list($config, $data) = [[], ['name' => $name, 'value' => $value]];
return DataService::save('SystemConfig', $data, 'name');
}
if (empty($config)) {
foreach (Db::name('SystemConfig')->select() as $vo) {
$config[$vo['name']] = $vo['value'];
}
$config = Db::name('SystemConfig')->column('name,value');
}
return isset($config[$name]) ? $config[$name] : '';
}
/**
* array_column 函数兼容
* 日期格式标准输出
* @param string $datetime 输入日期
* @param string $format 输出格式
* @return false|string
*/
if (!function_exists("array_column")) {
function format_datetime($datetime, $format = 'Y年m月d日 H:i:s')
{
return date($format, strtotime($datetime));
}
function array_column(array &$rows, $column_key, $index_key = null) {
$data = [];
foreach ($rows as $row) {
if (empty($index_key)) {
$data[] = $row[$column_key];
} else {
$data[$row[$index_key]] = $row[$column_key];
}
}
return $data;
/**
* UTF8字符串加密
* @param string $string
* @return string
*/
function encode($string)
{
list($chars, $length) = ['', strlen($string = iconv('utf-8', 'gbk', $string))];
for ($i = 0; $i < $length; $i++) {
$chars .= str_pad(base_convert(ord($string[$i]), 10, 36), 2, 0, 0);
}
return $chars;
}
}
/**
* UTF8字符串解密
* @param string $string
* @return string
*/
function decode($string)
{
$chars = '';
foreach (str_split($string, 2) as $char) {
$chars .= chr(intval(base_convert($char, 36, 10)));
}
return iconv('gbk', 'utf-8', $chars);
}
/**
* 下载远程文件到本地
* @param string $url 远程图片地址
* @return string
*/
function local_image($url)
{
return \service\FileService::download($url)['url'];
}

View File

@ -1,224 +0,0 @@
<?php
// +----------------------------------------------------------------------
// | Think.Admin
// +----------------------------------------------------------------------
// | 版权所有 2014~2017 广州楚才信息科技有限公司 [ http://www.cuci.cc ]
// +----------------------------------------------------------------------
// | 官方网站: http://think.ctolog.com
// +----------------------------------------------------------------------
// | 开源协议 ( https://mit-license.org )
// +----------------------------------------------------------------------
// | github开源项目https://github.com/zoujingli/Think.Admin
// +----------------------------------------------------------------------
return [
// +----------------------------------------------------------------------
// | 应用设置
// +----------------------------------------------------------------------
// 应用命名空间
'app_namespace' => 'app',
// 应用调试模式
'app_debug' => true,
// 应用Trace
'app_trace' => false,
// 应用模式状态
'app_status' => '',
// 是否支持多模块
'app_multi_module' => true,
// 入口自动绑定模块
'auto_bind_module' => false,
// 注册的根命名空间
'root_namespace' => [],
// 扩展函数文件
'extra_file_list' => [THINK_PATH . 'helper' . EXT],
// 默认输出类型
'default_return_type' => 'html',
// 默认AJAX 数据返回格式,可选json xml ...
'default_ajax_return' => 'json',
// 默认JSONP格式返回的处理方法
'default_jsonp_handler' => 'jsonpReturn',
// 默认JSONP处理方法
'var_jsonp_handler' => 'callback',
// 默认时区
'default_timezone' => 'PRC',
// 是否开启多语言
'lang_switch_on' => false,
// 默认全局过滤方法 用逗号分隔多个
'default_filter' => '',
// 默认语言
'default_lang' => 'zh-cn',
// 应用类库后缀
'class_suffix' => false,
// 控制器类后缀
'controller_suffix' => false,
// +----------------------------------------------------------------------
// | 模块设置
// +----------------------------------------------------------------------
// 默认模块名
'default_module' => 'index',
// 禁止访问模块
'deny_module_list' => ['common'],
// 默认控制器名
'default_controller' => 'Index',
// 默认操作名
'default_action' => 'index',
// 默认验证器
'default_validate' => '',
// 默认的空控制器名
'empty_controller' => 'Error',
// 操作方法后缀
'action_suffix' => '',
// 自动搜索控制器
'controller_auto_search' => false,
// +----------------------------------------------------------------------
// | URL设置
// +----------------------------------------------------------------------
// PATHINFO变量名 用于兼容模式
'var_pathinfo' => 's',
// 兼容PATH_INFO获取
'pathinfo_fetch' => ['ORIG_PATH_INFO', 'REDIRECT_PATH_INFO', 'REDIRECT_URL'],
// pathinfo分隔符
'pathinfo_depr' => '/',
// URL伪静态后缀
'url_html_suffix' => 'html',
// URL普通方式参数 用于自动生成
'url_common_param' => false,
// URL参数方式 0 按名称成对解析 1 按顺序解析
'url_param_type' => 0,
// 是否开启路由
'url_route_on' => true,
// 路由使用完整匹配
'route_complete_match' => false,
// 路由配置文件(支持配置多个)
'route_config_file' => ['route'],
// 是否强制使用路由
'url_route_must' => false,
// 域名部署
'url_domain_deploy' => false,
// 域名根如thinkphp.cn
'url_domain_root' => '',
// 是否自动转换URL中的控制器和操作名
'url_convert' => true,
// 默认的访问控制器层
'url_controller_layer' => 'controller',
// 表单请求类型伪装变量
'var_method' => '_method',
// 表单ajax伪装变量
'var_ajax' => '_ajax',
// 表单pjax伪装变量
'var_pjax' => '_pjax',
// 是否开启请求缓存 true自动缓存 支持设置请求缓存规则
'request_cache' => false,
// 请求缓存有效期
'request_cache_expire' => null,
// +----------------------------------------------------------------------
// | 模板设置
// +----------------------------------------------------------------------
'template' => [
// 模板引擎类型 支持 php think 支持扩展
'type' => 'Think',
// 模板路径
'view_path' => '',
// 模板后缀
'view_suffix' => 'html',
// 模板文件名分隔符
'view_depr' => '.',
// 模板引擎普通标签开始标记
'tpl_begin' => '{',
// 模板引擎普通标签结束标记
'tpl_end' => '}',
// 标签库标签开始标记
'taglib_begin' => '{',
// 标签库标签结束标记
'taglib_end' => '}',
],
// 视图输出字符串内容替换
'view_replace_str' => [],
// 默认跳转页面对应的模板文件
'dispatch_success_tmpl' => THINK_PATH . 'tpl' . DS . 'dispatch_jump.tpl',
'dispatch_error_tmpl' => THINK_PATH . 'tpl' . DS . 'dispatch_jump.tpl',
// +----------------------------------------------------------------------
// | 异常及错误设置
// +----------------------------------------------------------------------
// 异常页面的模板文件
'exception_tmpl' => THINK_PATH . 'tpl' . DS . 'think_exception.tpl',
// 错误显示信息,非调试模式有效
'error_message' => '页面错误!请稍后再试~',
// 显示错误信息
'show_error_msg' => false,
// 异常处理handle类 留空使用 \think\exception\Handle
'exception_handle' => '',
// +----------------------------------------------------------------------
// | 日志设置
// +----------------------------------------------------------------------
'log' => [
// 日志记录方式,内置 file socket 支持扩展
'type' => 'File',
// 日志保存目录
'path' => LOG_PATH,
// 日志记录级别 log,error,info,sql,notice,alert,debug
'level' => ['error', 'log', 'info', 'sql', 'notice', 'alert', 'debug'],
// error和sql日志单独记录
'apart_level' => ['error', 'sql'],
],
// +----------------------------------------------------------------------
// | Trace设置 开启 app_trace 后 有效
// +----------------------------------------------------------------------
'trace' => [
// 内置Html Console 支持扩展
'type' => 'Html',
],
// +----------------------------------------------------------------------
// | 缓存设置
// +----------------------------------------------------------------------
'cache' => [
// 驱动方式
'type' => 'File',
// 缓存保存目录
'path' => CACHE_PATH,
// 缓存前缀
'prefix' => '',
// 缓存有效期 0表示永久缓存
'expire' => 0,
],
// +----------------------------------------------------------------------
// | 会话设置
// +----------------------------------------------------------------------
'session' => [
'id' => '',
// SESSION_ID的提交变量,解决flash上传跨域
'var_session_id' => '',
// SESSION 前缀
'prefix' => 'think',
// 驱动方式 支持redis memcache memcached
'type' => '',
// 是否自动开启 SESSION
'auto_start' => true,
],
// +----------------------------------------------------------------------
// | Cookie设置
// +----------------------------------------------------------------------
'cookie' => [
// cookie 名称前缀
'prefix' => '',
// cookie 保存时间
'expire' => 0,
// cookie 保存路径
'path' => '/',
// cookie 有效域名
'domain' => '',
// cookie 启用安全传输
'secure' => false,
// httponly设置
'httponly' => '',
// 是否使用 setcookie
'setcookie' => true,
],
//分页配置
'paginate' => [
'type' => 'bootstrap',
'var_page' => 'page',
'list_rows' => 15,
],
];

View File

@ -1,60 +0,0 @@
<?php
// +----------------------------------------------------------------------
// | Think.Admin
// +----------------------------------------------------------------------
// | 版权所有 2014~2017 广州楚才信息科技有限公司 [ http://www.cuci.cc ]
// +----------------------------------------------------------------------
// | 官方网站: http://think.ctolog.com
// +----------------------------------------------------------------------
// | 开源协议 ( https://mit-license.org )
// +----------------------------------------------------------------------
// | github开源项目https://github.com/zoujingli/Think.Admin
// +----------------------------------------------------------------------
return [
// 数据库类型
'type' => 'mysql',
// 服务器地址
'hostname' => '127.0.0.1',
// 数据库名
'database' => 'think.admin',
// 用户名
'username' => 'think.admin',
// 密码
'password' => '',
// 端口
'hostport' => '3306',
// 连接dsn
'dsn' => '',
// 数据库连接参数
'params' => [],
// 数据库编码默认采用utf8
'charset' => 'utf8',
// 数据库表前缀
'prefix' => '',
// 数据库调试模式
'debug' => true,
// 数据库部署方式:0 集中式(单一服务器),1 分布式(主从服务器)
'deploy' => 0,
// 数据库读写是否分离 主从式有效
'rw_separate' => false,
// 读写分离后 主服务器数量
'master_num' => 1,
// 指定从服务器序号
'slave_no' => '',
// 是否严格检查字段是否存在
'fields_strict' => true,
// 数据集返回类型
'resultset_type' => 'array',
// 自动写入时间戳字段
'auto_timestamp' => false,
// 时间字段取出后的默认时间格式
'datetime_format' => 'Y-m-d H:i:s',
// 是否需要进行SQL性能分析
'sql_explain' => false,
// Builder类
'builder' => '',
// Query类
'query' => '\\think\\db\\Query',
];

View File

@ -1,161 +0,0 @@
<?php
// +----------------------------------------------------------------------
// | Think.Admin
// +----------------------------------------------------------------------
// | 版权所有 2014~2017 广州楚才信息科技有限公司 [ http://www.cuci.cc ]
// +----------------------------------------------------------------------
// | 官方网站: http://think.ctolog.com
// +----------------------------------------------------------------------
// | 开源协议 ( https://mit-license.org )
// +----------------------------------------------------------------------
// | github开源项目https://github.com/zoujingli/Think.Admin
// +----------------------------------------------------------------------
return [
'hqx' => ['application/mac-binhex40', 'application/mac-binhex', 'application/x-binhex40', 'application/x-mac-binhex40'],
'cpt' => 'application/mac-compactpro',
'csv' => ['text/x-comma-separated-values', 'text/comma-separated-values', 'application/octet-stream', 'application/vnd.ms-excel', 'application/x-csv', 'text/x-csv', 'text/csv', 'application/csv', 'application/excel', 'application/vnd.msexcel', 'text/plain'],
'bin' => ['application/macbinary', 'application/mac-binary', 'application/octet-stream', 'application/x-binary', 'application/x-macbinary'],
'dms' => 'application/octet-stream',
'lha' => 'application/octet-stream',
'lzh' => 'application/octet-stream',
'exe' => ['application/octet-stream', 'application/x-msdownload'],
'class' => 'application/octet-stream',
'psd' => ['application/x-photoshop', 'image/vnd.adobe.photoshop'],
'so' => 'application/octet-stream',
'sea' => 'application/octet-stream',
'dll' => 'application/octet-stream',
'oda' => 'application/oda',
'pdf' => ['application/pdf', 'application/force-download', 'application/x-download', 'binary/octet-stream'],
'ai' => ['application/pdf', 'application/postscript'],
'eps' => 'application/postscript',
'ps' => 'application/postscript',
'smi' => 'application/smil',
'smil' => 'application/smil',
'mif' => 'application/vnd.mif',
'xls' => ['application/vnd.ms-excel', 'application/msexcel', 'application/x-msexcel', 'application/x-ms-excel', 'application/x-excel', 'application/x-dos_ms_excel', 'application/xls', 'application/x-xls', 'application/excel', 'application/download', 'application/vnd.ms-office', 'application/msword'],
'ppt' => ['application/powerpoint', 'application/vnd.ms-powerpoint', 'application/vnd.ms-office', 'application/msword'],
'pptx' => ['application/vnd.openxmlformats-officedocument.presentationml.presentation', 'application/x-zip', 'application/zip'],
'wbxml' => 'application/wbxml',
'wmlc' => 'application/wmlc',
'dcr' => 'application/x-director',
'dir' => 'application/x-director',
'dxr' => 'application/x-director',
'dvi' => 'application/x-dvi',
'gtar' => 'application/x-gtar',
'gz' => 'application/x-gzip',
'gzip' => 'application/x-gzip',
'php' => ['application/x-httpd-php', 'application/php', 'application/x-php', 'text/php', 'text/x-php', 'application/x-httpd-php-source'],
'php4' => 'application/x-httpd-php',
'php3' => 'application/x-httpd-php',
'phtml' => 'application/x-httpd-php',
'phps' => 'application/x-httpd-php-source',
'js' => ['application/x-javascript', 'text/plain'],
'swf' => 'application/x-shockwave-flash',
'sit' => 'application/x-stuffit',
'tar' => 'application/x-tar',
'tgz' => ['application/x-tar', 'application/x-gzip-compressed'],
'z' => 'application/x-compress',
'xhtml' => 'application/xhtml+xml',
'xht' => 'application/xhtml+xml',
'zip' => ['application/x-zip', 'application/zip', 'application/x-zip-compressed', 'application/s-compressed', 'multipart/x-zip'],
'rar' => ['application/x-rar', 'application/rar', 'application/x-rar-compressed'],
'mid' => 'audio/midi',
'midi' => 'audio/midi',
'mpga' => 'audio/mpeg',
'mp2' => 'audio/mpeg',
'mp3' => ['audio/mpeg', 'audio/mpg', 'audio/mpeg3', 'audio/mp3'],
'aif' => ['audio/x-aiff', 'audio/aiff'],
'aiff' => ['audio/x-aiff', 'audio/aiff'],
'aifc' => 'audio/x-aiff',
'ram' => 'audio/x-pn-realaudio',
'rm' => 'audio/x-pn-realaudio',
'rpm' => 'audio/x-pn-realaudio-plugin',
'ra' => 'audio/x-realaudio',
'rv' => 'video/vnd.rn-realvideo',
'wav' => ['audio/x-wav', 'audio/wave', 'audio/wav'],
'bmp' => ['image/bmp', 'image/x-bmp', 'image/x-bitmap', 'image/x-xbitmap', 'image/x-win-bitmap', 'image/x-windows-bmp', 'image/ms-bmp', 'image/x-ms-bmp', 'application/bmp', 'application/x-bmp', 'application/x-win-bitmap'],
'gif' => 'image/gif',
'jpeg' => ['image/jpeg', 'image/pjpeg'],
'jpg' => ['image/jpeg', 'image/pjpeg'],
'jpe' => ['image/jpeg', 'image/pjpeg'],
'png' => ['image/png', 'image/x-png'],
'tiff' => 'image/tiff',
'tif' => 'image/tiff',
'css' => ['text/css', 'text/plain'],
'html' => ['text/html', 'text/plain'],
'htm' => ['text/html', 'text/plain'],
'shtml' => ['text/html', 'text/plain'],
'txt' => 'text/plain',
'text' => 'text/plain',
'log' => ['text/plain', 'text/x-log'],
'rtx' => 'text/richtext',
'rtf' => 'text/rtf',
'xml' => ['application/xml', 'text/xml', 'text/plain'],
'xsl' => ['application/xml', 'text/xsl', 'text/xml'],
'mpeg' => 'video/mpeg',
'mpg' => 'video/mpeg',
'mpe' => 'video/mpeg',
'qt' => 'video/quicktime',
'mov' => 'video/quicktime',
'avi' => ['video/x-msvideo', 'video/msvideo', 'video/avi', 'application/x-troff-msvideo'],
'movie' => 'video/x-sgi-movie',
'doc' => ['application/msword', 'application/vnd.ms-office'],
'docx' => ['application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'application/zip', 'application/msword', 'application/x-zip'],
'dot' => ['application/msword', 'application/vnd.ms-office'],
'dotx' => ['application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'application/zip', 'application/msword'],
'xlsx' => ['application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 'application/zip', 'application/vnd.ms-excel', 'application/msword', 'application/x-zip'],
'word' => ['application/msword', 'application/octet-stream'],
'xl' => 'application/excel',
'eml' => 'message/rfc822',
'json' => ['application/json', 'text/json'],
'pem' => ['application/x-x509-user-cert', 'application/x-x509-ca-cert', 'application/x-pem-file', 'application/pkix-cert'],
'crt' => ['application/x-x509-user-cert', 'application/x-x509-ca-cert', 'application/pkix-cert'],
'p10' => ['application/x-pkcs10', 'application/pkcs10'],
'p12' => 'application/x-pkcs12',
'p7a' => 'application/x-pkcs7-signature',
'p7c' => ['application/pkcs7-mime', 'application/x-pkcs7-mime'],
'p7m' => ['application/pkcs7-mime', 'application/x-pkcs7-mime'],
'p7r' => 'application/x-pkcs7-certreqresp',
'p7s' => 'application/pkcs7-signature',
'crl' => ['application/pkix-crl', 'application/pkcs-crl'],
'der' => 'application/x-x509-ca-cert',
'kdb' => 'application/octet-stream',
'pgp' => 'application/pgp',
'gpg' => 'application/gpg-keys',
'sst' => 'application/octet-stream',
'csr' => 'application/octet-stream',
'rsa' => 'application/x-pkcs7',
'cer' => ['application/pkix-cert', 'application/x-x509-ca-cert'],
'3g2' => 'video/3gpp2',
'3gp' => ['video/3gp', 'video/3gpp'],
'mp4' => 'video/mp4',
'm4a' => 'audio/x-m4a',
'f4v' => 'video/mp4',
'webm' => 'video/webm',
'webp' => 'image/webp',
'aac' => 'audio/x-acc',
'm4u' => 'application/vnd.mpegurl',
'm3u' => 'text/plain',
'xspf' => 'application/xspf+xml',
'vlc' => 'application/videolan',
'wmv' => ['video/x-ms-wmv', 'video/x-ms-asf'],
'au' => 'audio/x-au',
'ac3' => 'audio/ac3',
'flac' => 'audio/x-flac',
'ogg' => 'audio/ogg',
'kmz' => ['application/vnd.google-earth.kmz', 'application/zip', 'application/x-zip'],
'kml' => ['application/vnd.google-earth.kml+xml', 'application/xml', 'text/xml'],
'ics' => 'text/calendar',
'ical' => 'text/calendar',
'zsh' => 'text/x-scriptzsh',
'7zip' => ['application/x-compressed', 'application/x-zip-compressed', 'application/zip', 'multipart/x-zip'],
'cdr' => ['application/cdr', 'application/coreldraw', 'application/x-cdr', 'application/x-coreldraw', 'image/cdr', 'image/x-cdr', 'zz-application/zz-winassoc-cdr'],
'wma' => ['audio/x-ms-wma', 'video/x-ms-asf'],
'jar' => ['application/java-archive', 'application/x-java-application', 'application/x-jar', 'application/x-compressed'],
'svg' => ['image/svg+xml', 'application/xml', 'text/xml'],
'vcf' => 'text/x-vcard',
'srt' => ['text/srt', 'text/plain'],
'vtt' => ['text/vtt', 'text/plain'],
'ico' => ['image/x-icon', 'image/x-ico', 'image/vnd.microsoft.icon'],
];

View File

@ -1,22 +0,0 @@
<div class="ibox">
{block name="style"}{/block}
{if isset($title)}
<div class="ibox-title">
<h5>{$title}</h5>
{block name="button"}{/block}
</div>
{/if}
<div class="ibox-content fadeInUp animated">
{if isset($alert)}
<div class="alert alert-{$alert.type} alert-dismissible" role="alert" style="border-radius:0">
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
{if isset($alert['title'])}<p style="font-size:18px;padding-bottom:10px">{$alert.title}</p>{/if}
{if isset($alert['content'])}<p style="font-size:14px">{$alert.content}</p>{/if}
</div>
{/if}
{block name="content"}{/block}
</div>
{block name='script'}{/block}
</div>

View File

@ -1,23 +0,0 @@
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="utf-8">
<meta name="renderer" content="webkit"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<link rel="shortcut icon" href="{:sysconf('browser_icon')}" />
<title>{block name="title"}{$title|default=''}&nbsp;{if !empty($title)}-{/if}&nbsp;{:sysconf('site_name')}{/block}</title>
<link rel="stylesheet" href="__PUBLIC__/static/plugs/bootstrap/css/bootstrap.min.css?ver={:date('ymd')}"/>
<link rel="stylesheet" href="__PUBLIC__/static/plugs/layui/css/layui.css?ver={:date('ymd')}"/>
<link rel="stylesheet" href="__PUBLIC__/static/theme/default/css/console.css?ver={:date('ymd')}">
<link rel="stylesheet" href="__PUBLIC__/static/theme/default/css/animate.css?ver={:date('ymd')}">{block name="style"}{/block}
<script>window.ROOT_URL = '__PUBLIC__';</script>
<script src="__PUBLIC__/static/plugs/require/require.js?ver={:date('ymd')}"></script>
<script src="__PUBLIC__/static/admin/app.js?ver={:date('ymd')}"></script>
</head>
{block name="bodyTag"}
<body>
{block name="body"}{/block}
{block name="script"}{/block}
</body>
{/block}
</html>

View File

@ -1,52 +0,0 @@
<div class="framework-sidebar">
<div class="sidebar-content">
<div class="sidebar-inner">
<div class="sidebar-fold">
<span class="glyphicon glyphicon-option-vertical transition"></span>
</div>
{volist name='menus' id='pmenu'}
{notempty name='pmenu.sub'}
<div data-menu-box="m-{$pmenu.id}">
{volist name='pmenu.sub' id='menu'}
<div class="sidebar-nav main-nav">
{empty name='menu.sub'}
<ul class="sidebar-trans">
<li class="nav-item">
<a data-menu-node='m-{$pmenu.id}-{$menu.id}' data-open="{$menu.url}"
class="sidebar-trans">
<div class="nav-icon sidebar-trans">
<span class="{$menu.icon|default='fa fa-link'} transition"></span>
</div>
<span class="nav-title">{$menu.title}</span>
</a>
</li>
</ul>
{else}
<div class="sidebar-title">
<div class="sidebar-title-inner">
<span class="sidebar-title-icon fa fa-caret-right transition"></span>
<span class="sidebar-title-text">{$menu.title}</span>
</div>
</div>
<ul class="sidebar-trans" style="display:none" data-menu-node='m-{$pmenu.id}-{$menu.id}'>
{volist name='menu.sub' id='submenu'}
<li class="nav-item">
<a data-menu-node='m-{$pmenu.id}-{$submenu.id}' data-open="{$submenu.url}"
class="sidebar-trans">
<div class="nav-icon sidebar-trans">
<span class="{$submenu.icon|default='fa fa-link'} transition"></span>
</div>
<span class="nav-title">{$submenu.title}</span>
</a>
</li>
{/volist}
</ul>
{/empty}
</div>
{/volist}
</div>
{/notempty}
{/volist}
</div>
</div>
</div>

View File

@ -1,65 +0,0 @@
<div class="framework-topbar">
<div class="console-topbar">
<div class="topbar-wrap topbar-clearfix">
<div class="topbar-head topbar-left">
<a href="{:url('@admin')}" class="topbar-logo topbar-left">
<span class="icon-logo">{:sysconf('app_name')} <sup>{:sysconf('app_version')}</sup></span>
</a>
</div>
{volist name='menus' id='pmenu'}
{empty name='pmenu.sub'}
<a data-menu-node='m-{$pmenu.id}' data-open="{$pmenu.url}"
class="topbar-home-link topbar-btn topbar-left">
<span>{notempty name='$pmenu.icon'}<i class="{$pmenu.icon}"></i>{/notempty} {$pmenu.title}</span>
</a>
{else}
<a data-menu-target='m-{$pmenu.id}' class="topbar-home-link topbar-btn topbar-left">
<span>{notempty name='$pmenu.icon'}<i class="{$pmenu.icon}"></i>{/notempty} {$pmenu.title}</span>
</a>
{/empty}
{/volist}
<div class="topbar-info topbar-right">
<a data-reload data-tips-text='刷新'
class=" topbar-btn topbar-left topbar-info-item text-center"
style='width:50px;'>
<span class='glyphicon glyphicon-refresh'></span>
</a>
<script>
require(['jquery'], function () {
$('[data-reload]').hover(function () {
$(this).find('.glyphicon').addClass('fa-spin');
}, function () {
$(this).find('.glyphicon').removeClass('fa-spin');
});
});
</script>
<div class="topbar-left topbar-user">
<div class="dropdown topbar-info-item">
<a href="#" class="dropdown-toggle topbar-btn text-center" data-toggle="dropdown">
<span class='glyphicon glyphicon-user'></span> {:session('user.username')} </span>
<span class="glyphicon glyphicon-menu-up transition" style="font-size:12px"></span>
</a>
<ul class="dropdown-menu">
<li class="topbar-info-btn">
<a data-modal="{:url('admin/index/pass')}?id={:session('user.id')}">
<span><i class='glyphicon glyphicon-lock'></i> 修改密码</span>
</a>
</li>
<li class="topbar-info-btn">
<a data-modal="{:url('admin/index/info')}?id={:session('user.id')}">
<span><i class='glyphicon glyphicon-edit'></i> 修改资料</span>
</a>
</li>
<li class="topbar-info-btn">
<a data-load="{:url('admin/login/out')}" data-confirm='确定要退出登录吗?'>
<span><i class="glyphicon glyphicon-log-out"></i> 退出登录</span>
</a>
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>

View File

@ -1,7 +1,7 @@
<?php
// +----------------------------------------------------------------------
// | Think.Admin
// | ThinkAdmin
// +----------------------------------------------------------------------
// | 版权所有 2014~2017 广州楚才信息科技有限公司 [ http://www.cuci.cc ]
// +----------------------------------------------------------------------
@ -9,7 +9,7 @@
// +----------------------------------------------------------------------
// | 开源协议 ( https://mit-license.org )
// +----------------------------------------------------------------------
// | github开源项目https://github.com/zoujingli/Think.Admin
// | github开源项目https://github.com/zoujingli/ThinkAdmin
// +----------------------------------------------------------------------
namespace app\index\controller;
@ -17,19 +17,14 @@ namespace app\index\controller;
use think\Controller;
/**
* 网站入口控制器
* Class Index
* @package app\index\controller
* 应用入口控制器
* @author Anyon <zoujingli@qq.com>
* @date 2017/04/05 10:38
*/
class Index extends Controller {
class Index extends Controller
{
/**
* 网站入口
*/
public function index() {
$this->redirect('@admin');
public function index()
{
$this->redirect('@admin/login');
}
}

View File

@ -1,99 +0,0 @@
<?php
// +----------------------------------------------------------------------
// | Think.Admin
// +----------------------------------------------------------------------
// | 版权所有 2014~2017 广州楚才信息科技有限公司 [ http://www.cuci.cc ]
// +----------------------------------------------------------------------
// | 官方网站: http://think.ctolog.com
// +----------------------------------------------------------------------
// | 开源协议 ( https://mit-license.org )
// +----------------------------------------------------------------------
// | github开源项目https://github.com/zoujingli/Think.Admin
// +----------------------------------------------------------------------
namespace app\index\controller;
use controller\BasicWechat;
use service\DataService;
use service\PayService;
class Wap extends BasicWechat {
/**
* 禁用自动网页授权
* @var bool
*/
protected $checkAuth = false;
/**
* 网页授权DEMO
*/
public function index() {
// dump($this->oAuth(false)); // 仅获取用户openid
dump($this->oAuth()); // 获取用户详情信息
dump($this->fansinfo); // 打
}
/**
* 微信二维码支付DEMO
* @return \think\response\Json|\think\response\View
*/
public function payqrc() {
switch ($this->request->get('action')) {
case 'payqrc':
$pay = &load_wechat('pay');
$order_no = session('pay-test-order-no');
if (empty($order_no)) {
$order_no = DataService::createSequence(10, 'wechat-pay-test');
session('pay-test-order-no', $order_no);
}
if (PayService::isPay($order_no)) {
return json(['code' => 2, 'order_no' => $order_no]);
}
$url = PayService::createWechatPayQrc($pay, $order_no, 1, '微信扫码支付测试!');
if ($url !== false) {
return json(['code' => 1, 'url' => $url, 'order_no' => $order_no]);
}
$this->error("生成支付二维码失败,{$pay->errMsg}[{$pay->errCode}]");
break;
case 'reset':
session('pay-test-order-no', null);
break;
default:
return view();
}
}
/**
* 微信JSAPI支付DEMO
* @return \think\response\Json|\think\response\View
*/
public function payjs() {
$this->openid = $this->oAuth(false);
switch ($this->request->get('action')) {
case 'options':
$order_no = session('pay-test-order-no');
if (empty($order_no)) {
$order_no = DataService::createSequence(10, 'wechat-pay-test');
session('pay-test-order-no', $order_no);
}
if (PayService::isPay($order_no)) {
return json(['code' => 2, 'order_no' => $order_no]);
}
$pay = &load_wechat('pay');
$options = PayService::createWechatPayJsPicker($pay, $this->openid, $order_no, 1, 'JSAPI支付测试');
if ($options === false) {
$options = ['code' => 3, 'msg' => "创建支付失败,{$pay->errMsg}[$pay->errCode]"];
}
$options['order_no'] = $order_no;
return json($options);
case 'reset':
session('pay-test-order-no', null);
break;
default:
return view();
}
}
}

View File

@ -1,57 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>JSAPI支付DEMO</title>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="//cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css">
</head>
<body style="text-align:center">
<div class="contrainer">
<h3>JSAPI支付DEMO</h3>
<hr/>
<p class="price">金额: 0.01</p>
<hr/>
<p class="orderno"></p>
<hr/>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10" id="test">
<button type="submit" class="btn btn-success">立即支付</button>
</div>
</div>
<a href="{:url('payqrc')}" class="btn btn-link">扫码支付测试</a>
</div>
<script src="//cdn.bootcss.com/jquery/1.11.0/jquery.min.js"></script>
<script src="//cdn.bootcss.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script src="//res.wx.qq.com/open/js/jweixin-1.2.0.js"></script>
<script>
wx.error(function (e) {
console.log(e);
});
wx.config($.parseJSON('{$jsSign|json_encode}'));
wx.ready(function () {
$.get('{:url("payjs")}', {'action': 'options'}, function (ret) {
$('.orderno').html('订单号:' + ret.order_no);
if (ret.code && ret.code === 2) {
$('#test').append('<button type="button" class="btn btn-success">已支付,刷新支付号</button>');
return $('[type="submit"]').remove();
}
$('[type="submit"]').on('click', function () {
if (ret.code && ret.code === 3) {
return alert(ret.msg);
}
wx.chooseWXPay(ret);
});
});
$('body').on('click', '[type="button"]', function () {
$.get('{:url("payjs")}', {'action': 'reset'}, function () {
window.location.reload();
});
});
});
</script>
</body>
</html>

View File

@ -1,53 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>扫码支付DEMO</title>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="//cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css">
</head>
<body style="text-align:center">
<div class="contrainer">
<h3>扫码支付DEMO</h3>
<hr/>
<p id="showbox"></p>
<p class="help-block">请使用其它手机微信扫描二维码。</p>
<hr/>
<p class="price">金额: 0.01</p>
<hr/>
<p id="orderno"></p>
<hr/>
<button data-reset class="btn btn-default hide">重置订单号</button>
<a href="{:url('payjs')}" class="btn btn-link">JSAPI支付测试</a>
</div>
<script src="//cdn.bootcss.com/jquery/1.11.0/jquery.min.js"></script>
<script src="//cdn.bootcss.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script>
$(function () {
payTest.call(this), setInterval(payTest, 3000);
/*! 支付测试动作 */
function payTest() {
$.get('{:url("payqrc")}', {'action': 'payqrc'}, function (ret) {
if (ret.code === 2) {
$('[data-reset]').removeClass('hide');
ret.url = '__PUBLIC__/static/theme/default/img/wechat/qrc_payed.jpg';
}
$('#showbox').html('<img style="width:300px" class="img-thumbnail" src="' + ret.url + '"/>');
$('#orderno').html('订单号:' + ret.order_no);
});
}
$('[data-reset]').on('click', function () {
$.get('{:url("payqrc")}', {'action': 'reset'}, function () {
window.location.reload();
});
});
});
</script>
</body>
</html>

View File

@ -1,7 +1,7 @@
<?php
// +----------------------------------------------------------------------
// | Think.Admin
// | ThinkAdmin
// +----------------------------------------------------------------------
// | 版权所有 2014~2017 广州楚才信息科技有限公司 [ http://www.cuci.cc ]
// +----------------------------------------------------------------------
@ -9,9 +9,10 @@
// +----------------------------------------------------------------------
// | 开源协议 ( https://mit-license.org )
// +----------------------------------------------------------------------
// | github开源项目https://github.com/zoujingli/Think.Admin
// | github开源项目https://github.com/zoujingli/ThinkAdmin
// +----------------------------------------------------------------------
return [
'connector' => 'Sync'
];
// 系统权限访问管理
\app\admin\middleware\Auth::class,
];

View File

@ -1,51 +0,0 @@
<?php
// +----------------------------------------------------------------------
// | Think.Admin
// +----------------------------------------------------------------------
// | 版权所有 2014~2017 广州楚才信息科技有限公司 [ http://www.cuci.cc ]
// +----------------------------------------------------------------------
// | 官方网站: http://think.ctolog.com
// +----------------------------------------------------------------------
// | 开源协议 ( https://mit-license.org )
// +----------------------------------------------------------------------
// | github开源项目https://github.com/zoujingli/Think.Admin
// +----------------------------------------------------------------------
/* 测试环境禁止操作路由绑定 */
think\Route::post([
'admin/config/index' => function() {
return json(['code' => 0, 'msg' => '测试环境禁修改系统配置操作!']);
},
'admin/config/file' => function() {
return json(['code' => 0, 'msg' => '测试环境禁修改文件配置操作!']);
},
'admin/menu/add' => function() {
return json(['code' => 0, 'msg' => '测试环境禁添加菜单操作!']);
},
'admin/menu/edit' => function() {
return json(['code' => 0, 'msg' => '测试环境禁编辑菜单操作!']);
},
'admin/menu/forbid' => function() {
return json(['code' => 0, 'msg' => '测试环境禁止禁用菜单操作!']);
},
'admin/menu/del' => function() {
return json(['code' => 0, 'msg' => '测试环境禁止删除菜单操作!']);
},
'wechat/config/index' => function() {
return json(['code' => 0, 'msg' => '测试环境禁止修改微信配置操作!']);
},
'wechat/config/pay' => function() {
return json(['code' => 0, 'msg' => '测试环境禁止修改微信支付操作!']);
},
'wechat/menu/edit' => function() {
return json(['code' => 0, 'msg' => '测试环境禁止修改微信菜单操作!']);
}
]);
think\Route::get([
'wechat/menu/cancel' => function() {
return json(['code' => 0, 'msg' => '测试环境禁止删除微信菜单操作!']);
}
]);
return [];

View File

@ -0,0 +1,126 @@
<?php
// +----------------------------------------------------------------------
// | Think.Admin
// +----------------------------------------------------------------------
// | 版权所有 2014~2017 广州楚才信息科技有限公司 [ http://www.cuci.cc ]
// +----------------------------------------------------------------------
// | 官方网站: http://think.ctolog.com
// +----------------------------------------------------------------------
// | 开源协议 ( https://mit-license.org )
// +----------------------------------------------------------------------
// | github开源项目https://github.com/zoujingli/Think.Admin
// +----------------------------------------------------------------------
namespace app\store\controller;
use controller\BasicAdmin;
use service\DataService;
use think\Db;
/**
* 商城快递公司管理
* Class Express
* @package app\store\controller
* @author Anyon <zoujingli@qq.com>
* @date 2017/03/27 14:43
*/
class Express extends BasicAdmin
{
/**
* 定义当前操作表名
* @var string
*/
public $table = 'StoreExpress';
/**
* 快递公司列表
* @return array|string
* @throws \think\Exception
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
public function index()
{
$this->title = '快递公司管理';
list($get, $db) = [$this->request->get(), Db::name($this->table)];
foreach (['express_title', 'express_code'] as $field) {
(isset($get[$field]) && $get[$field] !== '') && $db->whereLike($field, "%{$get[$field]}%");
}
if (isset($get['date']) && $get['date'] !== '') {
list($start, $end) = explode(' - ', $get['date']);
$db->whereBetween('create_at', ["{$start} 00:00:00", "{$end} 23:59:59"]);
}
return parent::_list($db->where(['is_deleted' => '0'])->order('status desc,sort asc,id desc'));
}
/**
* 添加快递公司
* @return array|string
* @throws \think\Exception
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
public function add()
{
$this->title = '添加快递公司';
return $this->_form($this->table, 'form');
}
/**
* 编辑快递公司
* @return array|string
* @throws \think\Exception
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
public function edit()
{
$this->title = '编辑快递公司';
return $this->_form($this->table, 'form');
}
/**
* 删除快递公司
* @throws \think\Exception
* @throws \think\exception\PDOException
*/
public function del()
{
if (DataService::update($this->table)) {
$this->success("快递公司删除成功!", '');
}
$this->error("快递公司删除失败,请稍候再试!");
}
/**
* 快递公司禁用
* @throws \think\Exception
* @throws \think\exception\PDOException
*/
public function forbid()
{
if (DataService::update($this->table)) {
$this->success("快递公司禁用成功!", '');
}
$this->error("快递公司禁用失败,请稍候再试!");
}
/**
* 快递公司禁用
* @throws \think\Exception
* @throws \think\exception\PDOException
*/
public function resume()
{
if (DataService::update($this->table)) {
$this->success("快递公司启用成功!", '');
}
$this->error("快递公司启用失败,请稍候再试!");
}
}

View File

@ -0,0 +1,304 @@
<?php
// +----------------------------------------------------------------------
// | ThinkAdmin
// +----------------------------------------------------------------------
// | 版权所有 2014~2017 广州楚才信息科技有限公司 [ http://www.cuci.cc ]
// +----------------------------------------------------------------------
// | 官方网站: http://think.ctolog.com
// +----------------------------------------------------------------------
// | 开源协议 ( https://mit-license.org )
// +----------------------------------------------------------------------
// | github开源项目https://github.com/zoujingli/ThinkAdmin
// +----------------------------------------------------------------------
namespace app\store\controller;
use app\store\service\GoodsService;
use controller\BasicAdmin;
use service\DataService;
use service\ToolsService;
use think\Db;
use think\exception\HttpResponseException;
/**
* 商店商品管理
* Class Goods
* @package app\store\controller
* @author Anyon <zoujingli@qq.com>
* @date 2017/03/27 14:43
*/
class Goods extends BasicAdmin
{
/**
* 定义当前操作表名
* @var string
*/
public $table = 'StoreGoods';
/**
* 普通商品
* @return array|string
* @throws \think\Exception
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
public function index()
{
$this->title = '商品管理';
$get = $this->request->get();
$db = Db::name($this->table)->where(['is_deleted' => '0']);
if (isset($get['tags_id']) && $get['tags_id'] !== '') {
$db->whereLike('tags_id', "%,{$get['tags_id']},%");
}
if (isset($get['goods_title']) && $get['goods_title'] !== '') {
$db->whereLike('goods_title', "%{$get['goods_title']}%");
}
foreach (['cate_id', 'brand_id'] as $field) {
(isset($get[$field]) && $get[$field] !== '') && $db->where($field, $get[$field]);
}
if (isset($get['create_at']) && $get['create_at'] !== '') {
list($start, $end) = explode(' - ', $get['create_at']);
$db->whereBetween('create_at', ["{$start} 00:00:00", "{$end} 23:59:59"]);
}
return parent::_list($db->order('status desc,sort asc,id desc'));
}
/**
* 商城数据处理
* @param array $data
*/
protected function _data_filter(&$data)
{
$result = GoodsService::buildGoodsList($data);
$this->assign([
'brands' => $result['brand'],
'cates' => ToolsService::arr2table($result['cate']),
]);
}
/**
* 添加商品
* @return array|string
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
* @throws \think\Exception
*/
public function add()
{
if ($this->request->isGet()) {
$this->title = '添加商品';
$this->_form_assign();
return $this->_form($this->table, 'form');
}
try {
$data = $this->_form_build_data();
Db::transaction(function () use ($data) {
$goodsID = Db::name($this->table)->insertGetId($data['main']);
foreach ($data['list'] as &$vo) {
$vo['goods_id'] = $goodsID;
}
Db::name('StoreGoodsList')->insertAll($data['list']);
});
} catch (HttpResponseException $exception) {
return $exception->getResponse();
} catch (\Exception $e) {
$this->error('商品添加失败,请稍候再试!');
}
list($base, $spm, $url) = [url('@admin'), $this->request->get('spm'), url('store/goods/index')];
$this->success('添加商品成功!', "{$base}#{$url}?spm={$spm}");
}
/**
* 编辑商品
* @return array|string
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
public function edit()
{
if (!$this->request->isPost()) {
$goods_id = $this->request->get('id');
$goods = Db::name($this->table)->where(['id' => $goods_id, 'is_deleted' => '0'])->find();
empty($goods) && $this->error('需要编辑的商品不存在!');
$goods['list'] = Db::name('StoreGoodsList')->where(['goods_id' => $goods_id, 'is_deleted' => '0'])->select();
$this->_form_assign();
return $this->fetch('form', ['vo' => $goods, 'title' => '编辑商品']);
}
try {
$data = $this->_form_build_data();
$goods_id = $this->request->post('id');
$goods = Db::name($this->table)->where(['id' => $goods_id, 'is_deleted' => '0'])->find();
empty($goods) && $this->error('商品编辑失败,请稍候再试!');
foreach ($data['list'] as &$vo) {
$vo['goods_id'] = $goods_id;
}
Db::transaction(function () use ($data, $goods_id, $goods) {
// 更新商品主表
$where = ['id' => $goods_id, 'is_deleted' => '0'];
Db::name('StoreGoods')->where($where)->update(array_merge($goods, $data['main']));
// 更新商品详细
Db::name('StoreGoodsList')->where(['goods_id' => $goods_id])->delete();
Db::name('StoreGoodsList')->insertAll($data['list']);
});
} catch (HttpResponseException $exception) {
return $exception->getResponse();
} catch (\Exception $e) {
$this->error('商品编辑失败,请稍候再试!' . $e->getMessage());
}
list($base, $spm, $url) = [url('@admin'), $this->request->get('spm'), url('store/goods/index')];
$this->success('商品编辑成功!', "{$base}#{$url}?spm={$spm}");
}
/**
* 表单数据处理
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
protected function _form_assign()
{
list($where, $order) = [['status' => '1', 'is_deleted' => '0'], 'sort asc,id desc'];
$specs = (array)Db::name('StoreGoodsSpec')->where($where)->order($order)->select();
$brands = (array)Db::name('StoreGoodsBrand')->where($where)->order($order)->select();
$cates = (array)Db::name('StoreGoodsCate')->where($where)->order($order)->select();
// 所有的商品信息
$where = ['is_deleted' => '0', 'status' => '1'];
$goodsListField = 'goods_id,goods_spec,goods_stock,goods_sale';
$goods = Db::name('StoreGoods')->field('id,goods_title')->where($where)->select();
$list = Db::name('StoreGoodsList')->field($goodsListField)->where($where)->select();
foreach ($goods as $k => $g) {
$goods[$k]['list'] = [];
foreach ($list as $v) {
($g['id'] === $v['goods_id']) && $goods[$k]['list'][] = $v;
}
}
array_unshift($specs, ['spec_title' => ' - 不使用规格模板 -', 'spec_param' => '[]', 'id' => '0']);
$this->assign([
'specs' => $specs,
'cates' => ToolsService::arr2table($cates),
'brands' => $brands,
'all' => $goods,
]);
}
/**
* 读取POST表单数据
* @return array
*/
protected function _form_build_data()
{
list($main, $list, $post, $verify) = [[], [], $this->request->post(), false];
empty($post['goods_logo']) && $this->error('商品LOGO不能为空请上传后再提交数据');
// 商品主数据组装
$main['cate_id'] = $this->request->post('cate_id', '0');
$main['spec_id'] = $this->request->post('spec_id', '0');
$main['brand_id'] = $this->request->post('brand_id', '0');
$main['goods_logo'] = $this->request->post('goods_logo', '');
$main['goods_title'] = $this->request->post('goods_title', '');
$main['goods_video'] = $this->request->post('goods_video', '');
$main['goods_image'] = $this->request->post('goods_image', '');
$main['goods_desc'] = $this->request->post('goods_desc', '', null);
$main['goods_content'] = $this->request->post('goods_content', '');
$main['tags_id'] = ',' . join(',', isset($post['tags_id']) ? $post['tags_id'] : []) . ',';
// 商品从数据组装
if (!empty($post['goods_spec'])) {
foreach ($post['goods_spec'] as $key => $value) {
$goods = [];
$goods['goods_spec'] = $value;
$goods['market_price'] = $post['market_price'][$key];
$goods['selling_price'] = $post['selling_price'][$key];
$goods['status'] = intval(!empty($post['spec_status'][$key]));
!empty($goods['status']) && $verify = true;
$list[] = $goods;
}
} else {
$this->error('没有商品规格或套餐信息哦!');
}
!$verify && $this->error('没有设置有效的商品规格!');
return ['main' => $main, 'list' => $list];
}
/**
* 商品库存信息更新
* @return string
* @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->post()) {
$goods_id = $this->request->get('id');
$goods = Db::name('StoreGoods')->where(['id' => $goods_id, 'is_deleted' => '0'])->find();
empty($goods) && $this->error('该商品无法操作入库操作!');
$where = ['goods_id' => $goods_id, 'status' => '1', 'is_deleted' => '0'];
$goods['list'] = Db::name('StoreGoodsList')->where($where)->select();
return $this->fetch('', ['vo' => $goods]);
}
// 入库保存
$goods_id = $this->request->post('id');
list($post, $data) = [$this->request->post(), []];
foreach ($post['spec'] as $key => $spec) {
if ($post['stock'][$key] > 0) {
$data[] = [
'goods_stock' => $post['stock'][$key],
'stock_desc' => $this->request->post('desc'),
'goods_spec' => $spec, 'goods_id' => $goods_id,
];
}
}
empty($data) && $this->error('无需入库的数据哦!');
if (Db::name('StoreGoodsStock')->insertAll($data) !== false) {
GoodsService::syncGoodsStock($goods_id);
$this->success('商品入库成功!', '');
}
$this->error('商品入库失败,请稍候再试!');
}
/**
* 删除商品
* @throws \think\Exception
* @throws \think\exception\PDOException
*/
public function del()
{
if (DataService::update($this->table)) {
$this->success("商品删除成功!", '');
}
$this->error("商品删除失败,请稍候再试!");
}
/**
* 商品禁用
* @throws \think\Exception
* @throws \think\exception\PDOException
*/
public function forbid()
{
if (DataService::update($this->table)) {
$this->success("商品下架成功!", '');
}
$this->error("商品下架失败,请稍候再试!");
}
/**
* 商品禁用
* @throws \think\Exception
* @throws \think\exception\PDOException
*/
public function resume()
{
if (DataService::update($this->table)) {
$this->success("商品上架成功!", '');
}
$this->error("商品上架失败,请稍候再试!");
}
}

View File

@ -0,0 +1,151 @@
<?php
// +----------------------------------------------------------------------
// | Think.Admin
// +----------------------------------------------------------------------
// | 版权所有 2014~2017 广州楚才信息科技有限公司 [ http://www.cuci.cc ]
// +----------------------------------------------------------------------
// | 官方网站: http://think.ctolog.com
// +----------------------------------------------------------------------
// | 开源协议 ( https://mit-license.org )
// +----------------------------------------------------------------------
// | github开源项目https://github.com/zoujingli/Think.Admin
// +----------------------------------------------------------------------
namespace app\store\controller;
use controller\BasicAdmin;
use service\DataService;
use think\Db;
/**
* 商店品牌管理
* Class Brand
* @package app\store\controller
* @author Anyon <zoujingli@qq.com>
* @date 2017/03/27 14:43
*/
class GoodsBrand extends BasicAdmin
{
/**
* 定义当前操作表名
* @var string
*/
public $table = 'StoreGoodsBrand';
/**
* 品牌列表
* @return array|string
* @throws \think\Exception
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
public function index()
{
$this->title = '品牌管理';
$get = $this->request->get();
$db = Db::name($this->table)->where(['is_deleted' => '0']);
if (isset($get['brand_title']) && $get['brand_title'] !== '') {
$db->whereLike('brand_title', "%{$get['brand_title']}%");
}
if (isset($get['create_at']) && $get['create_at'] !== '') {
list($start, $end) = explode(' - ', $get['create_at']);
$db->whereBetween('create_at', ["{$start} 00:00:00", "{$end} 23:59:59"]);
}
return parent::_list($db->order('sort asc,id desc'));
}
/**
* 添加品牌
* @return array|string
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
* @throws \think\Exception
*/
public function add()
{
$this->title = '添加品牌';
return $this->_form($this->table, 'form');
}
/**
* 编辑品牌
* @return array|string
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
* @throws \think\Exception
*/
public function edit()
{
$this->title = '编辑品牌';
return $this->_form($this->table, 'form');
}
/**
* 表单提交数据处理
* @param array $data
*/
protected function _form_filter($data)
{
if ($this->request->isPost()) {
empty($data['brand_logo']) && $this->error('请上传品牌Logo图片');
empty($data['brand_cover']) && $this->error('请上传品牌封面图片');
}
}
/**
* 添加成功回跳处理
* @param bool $result
*/
protected function _form_result($result)
{
if ($result !== false) {
list($base, $spm, $url) = [url('@admin'), $this->request->get('spm'), url('store/goods_brand/index')];
$this->success('数据保存成功!', "{$base}#{$url}?spm={$spm}");
}
}
/**
* 删除品牌
* @throws \think\Exception
* @throws \think\exception\PDOException
*/
public function del()
{
if (DataService::update($this->table)) {
$this->success("品牌删除成功!", '');
}
$this->error("品牌删除失败,请稍候再试!");
}
/**
* 品牌禁用
* @throws \think\Exception
* @throws \think\exception\PDOException
*/
public function forbid()
{
if (DataService::update($this->table)) {
$this->success("品牌禁用成功!", '');
}
$this->error("品牌禁用失败,请稍候再试!");
}
/**
* 品牌签禁用
* @throws \think\Exception
* @throws \think\exception\PDOException
*/
public function resume()
{
if (DataService::update($this->table)) {
$this->success("品牌启用成功!", '');
}
$this->error("品牌启用失败,请稍候再试!");
}
}

View File

@ -0,0 +1,157 @@
<?php
// +----------------------------------------------------------------------
// | ThinkAdmin
// +----------------------------------------------------------------------
// | 版权所有 2014~2017 广州楚才信息科技有限公司 [ http://www.cuci.cc ]
// +----------------------------------------------------------------------
// | 官方网站: http://think.ctolog.com
// +----------------------------------------------------------------------
// | 开源协议 ( https://mit-license.org )
// +----------------------------------------------------------------------
// | github开源项目https://github.com/zoujingli/ThinkAdmin
// +----------------------------------------------------------------------
namespace app\store\controller;
use controller\BasicAdmin;
use service\DataService;
use service\ToolsService;
use think\Db;
/**
* 商店商品分类管理
* Class Cate
* @package app\store\controller
* @author Anyon <zoujingli@qq.com>
* @date 2017/03/27 14:43
*/
class GoodsCate extends BasicAdmin
{
/**
* 定义当前操作表名
* @var string
*/
public $table = 'StoreGoodsCate';
/**
* 商品分类列表
* @return array|string
* @throws \think\Exception
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
public function index()
{
$this->title = '商品分类';
$db = Db::name($this->table)->where(['is_deleted' => '0']);
return parent::_list($db->order('sort asc,id asc'), false);
}
/**
* 列表数据处理
* @param array $data
*/
protected function _index_data_filter(&$data)
{
foreach ($data as &$vo) {
$vo['ids'] = join(',', ToolsService::getArrSubIds($data, $vo['id']));
}
$data = ToolsService::arr2table($data);
}
/**
* 添加菜单
* @return array|string
* @throws \think\Exception
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
public function add()
{
return $this->_form($this->table, 'form');
}
/**
* 编辑菜单
* @return array|string
* @throws \think\Exception
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
public function edit()
{
return $this->_form($this->table, 'form');
}
/**
* 表单数据前缀方法
* @param array $vo
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
protected function _form_filter(&$vo)
{
if ($this->request->isGet()) {
// 读取上级分类
$where = ['status' => '1', 'is_deleted' => '0'];
$_cates = (array)Db::name($this->table)->where($where)->order('sort desc,id desc')->select();
array_unshift($_cates, ['id' => 0, 'pid' => -1, 'cate_title' => '--- 顶级分类 ---']);
$cates = ToolsService::arr2table($_cates);
foreach ($cates as $key => &$cate) {
if (isset($vo['pid'])) {
$path = "-{$vo['pid']}-{$vo['id']}";
if ($vo['pid'] !== '' && (stripos("{$cate['path']}-", "{$path}-") !== false || $cate['path'] === $path)) {
unset($cates[$key]);
}
}
}
$this->assign('cates', $cates);
}
}
/**
* 删除商品分类
* @throws \think\Exception
* @throws \think\exception\PDOException
*/
public function del()
{
if (DataService::update($this->table)) {
$this->success("商品分类删除成功!", '');
}
$this->error("商品分类删除失败,请稍候再试!");
}
/**
* 商品分类禁用
* @throws \think\Exception
* @throws \think\exception\PDOException
*/
public function forbid()
{
if (DataService::update($this->table)) {
$this->success("商品分类禁用成功!", '');
}
$this->error("商品分类禁用失败,请稍候再试!");
}
/**
* 商品分类禁用
* @throws \think\Exception
* @throws \think\exception\PDOException
*/
public function resume()
{
if (DataService::update($this->table)) {
$this->success("商品分类启用成功!", '');
}
$this->error("商品分类启用失败,请稍候再试!");
}
}

View File

@ -0,0 +1,157 @@
<?php
// +----------------------------------------------------------------------
// | ThinkAdmin
// +----------------------------------------------------------------------
// | 版权所有 2014~2017 广州楚才信息科技有限公司 [ http://www.cuci.cc ]
// +----------------------------------------------------------------------
// | 官方网站: http://think.ctolog.com
// +----------------------------------------------------------------------
// | 开源协议 ( https://mit-license.org )
// +----------------------------------------------------------------------
// | github开源项目https://github.com/zoujingli/ThinkAdmin
// +----------------------------------------------------------------------
namespace app\store\controller;
use controller\BasicAdmin;
use service\DataService;
use think\Db;
/**
* 商店规格管理
* Class Spec
* @package app\store\controller
* @author Anyon <zoujingli@qq.com>
* @date 2017/03/27 14:43
*/
class GoodsSpec extends BasicAdmin
{
/**
* 定义当前操作表名
* @var string
*/
public $table = 'StoreGoodsSpec';
/**
* 商品列表
* @return array|string
* @throws \think\Exception
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
public function index()
{
$this->title = '规格管理(请勿随意修改或删除)';
$get = $this->request->get();
$db = Db::name($this->table)->where(['is_deleted' => '0']);
if (isset($get['spec_title']) && $get['spec_title'] !== '') {
$db->whereLike('spec_title', "%{$get['spec_title']}%");
}
if (isset($get['date']) && $get['date'] !== '') {
list($start, $end) = explode(' - ', $get['date']);
$db->whereBetween('create_at', ["{$start} 00:00:00", "{$end} 23:59:59"]);
}
return parent::_list($db->order('sort asc,id desc'));
}
/**
* 列表数据处理
* @param array $data
*/
protected function _index_data_filter(&$data)
{
foreach ($data as &$vo) {
$vo['spec_param'] = json_decode($vo['spec_param'], true);
$vo['spec_param'] = is_array($vo['spec_param']) ? $vo['spec_param'] : [];
}
}
/**
* 添加商品
* @return array|string
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
* @throws \think\Exception
*/
public function add()
{
$this->title = '添加规格';
return $this->_form($this->table, 'form');
}
/**
* 编辑商品
* @return array|string
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
* @throws \think\Exception
*/
public function edit()
{
$this->title = '编辑规格';
return $this->_form($this->table, 'form');
}
/**
* 表单数据处理
* @param array $vo
*/
protected function _form_filter(&$vo)
{
if ($this->request->isPost()) {
$param = json_decode($this->request->post('spec_param', '[]', null), true);
foreach ($param as &$v) {
$count = 1;
while ($count) {
$v['value'] = trim(str_replace([' ', '_', ',', '', ';', ''], ' ', $v['value'], $count));
}
}
$vo['spec_param'] = json_encode($param, JSON_UNESCAPED_UNICODE);
}
}
/**
* 删除商品规格
* @throws \think\Exception
* @throws \think\exception\PDOException
*/
public function del()
{
if (DataService::update($this->table)) {
$this->success("商品规格删除成功!", '');
}
$this->error("商品规格删除失败,请稍候再试!");
}
/**
* 商品规格禁用
* @throws \think\Exception
* @throws \think\exception\PDOException
*/
public function forbid()
{
if (DataService::update($this->table)) {
$this->success("商品规格禁用成功!", '');
}
$this->error("商品规格禁用失败,请稍候再试!");
}
/**
* 商品规格禁用
* @throws \think\Exception
* @throws \think\exception\PDOException
*/
public function resume()
{
if (DataService::update($this->table)) {
$this->success("商品规格启用成功!", '');
}
$this->error("商品规格启用失败,请稍候再试!");
}
}

View File

@ -0,0 +1,157 @@
<?php
// +----------------------------------------------------------------------
// | Think.Admin
// +----------------------------------------------------------------------
// | 版权所有 2014~2017 广州楚才信息科技有限公司 [ http://www.cuci.cc ]
// +----------------------------------------------------------------------
// | 官方网站: http://think.ctolog.com
// +----------------------------------------------------------------------
// | 开源协议 ( https://mit-license.org )
// +----------------------------------------------------------------------
// | github开源项目https://github.com/zoujingli/Think.Admin
// +----------------------------------------------------------------------
namespace app\store\controller;
use app\store\service\OrderService;
use controller\BasicAdmin;
use service\DataService;
use think\Db;
/**
* 商店订单管理
* Class Order
* @package app\store\controller
* @author Anyon <zoujingli@qq.com>
* @date 2017/03/27 14:43
*/
class Order extends BasicAdmin
{
/**
* 定义当前操作表名
* @var string
*/
public $table = 'StoreOrder';
/**
* 订单列表
* @return array|string
* @throws \think\Exception
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
public function index()
{
$this->title = '订单管理';
$db = Db::name($this->table);
$get = $this->request->get();
// 会员信息查询过滤
$memberWhere = [];
foreach (['phone', 'nickname'] as $field) {
if (isset($get[$field]) && $get[$field] !== '') {
$memberWhere[] = [$field, 'like', "%{$get[$field]}%"];
}
}
if (!empty($memberWhere)) {
$memberWhere['status'] = '1';
$sql = Db::name('Member')->field('id')->where($memberWhere)->buildSql(true);
$db->where("mid in {$sql}");
}
// =============== 商品信息查询过滤 ===============
$goodsWhere = [];
foreach (['goods_title'] as $field) {
if (isset($get[$field]) && $get[$field] !== '') {
$goodsWhere[] = [$field, 'like', "%{$get[$field]}%"];
}
}
if (!empty($goodsWhere)) {
$sql = Db::name('StoreOrderList')->field('order_no')->where($goodsWhere)->buildSql(true);
$db->where("order_no in {$sql}");
}
// =============== 收货地址过滤 ===============
$expressWhere = [];
if (isset($get['express_title']) && $get['express_title'] !== '') {
$expressWhere[] = ['send_company_title|company_title', 'like', "%{$get['express_title']}%"];
}
foreach (['send_no', 'username', 'phone', 'province', 'city', 'area', 'address'] as $field) {
if (isset($get[$field]) && $get[$field] !== '') {
$expressWhere[] = [$field, 'like', "%{$get[$field]}%"];
}
}
if (isset($get['send_status']) && $get['send_status'] !== '') {
$expressWhere[] = empty($get['send_status']) ? ['send_no', 'eq', ''] : ['send_no', 'neq', ''];
}
if (!empty($expressWhere)) {
$sql = Db::name('StoreOrderExpress')->field('order_no')->where($expressWhere)->buildSql(true);
$db->where("order_no in {$sql}");
}
// =============== 主订单过滤 ===============
foreach (['order_no', 'desc'] as $field) {
(isset($get[$field]) && $get[$field] !== '') && $db->whereLike($field, "%{$get[$field]}%");
}
(isset($get['status']) && $get['status'] !== '') && $db->where('status', $get['status']);
// 订单是否包邮状态检索
if (isset($get['express_zero']) && $get['express_zero'] !== '') {
empty($get['express_zero']) ? $db->where('freight_price', '>', '0') : $db->where('freight_price', '0');
}
// 订单时间过滤
foreach (['create_at', 'pay_at'] as $field) {
if (isset($get[$field]) && $get[$field] !== '') {
list($start, $end) = explode(' - ', $get[$field]);
$db->whereBetween($field, ["{$start} 00:00:00", "{$end} 23:59:59"]);
}
}
return parent::_list($db);
}
/**
* 订单列表数据处理
* @param array $data
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
protected function _data_filter(&$data)
{
OrderService::buildOrderList($data);
}
/**
* 订单地址修改
* @return string
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
* @throws \think\Exception
*/
public function address()
{
$order_no = $this->request->get('order_no');
if ($this->request->isGet()) {
$order = Db::name('StoreOrder')->where(['order_no' => $order_no])->find();
empty($order) && $this->error('该订单无法进行地址修改,订单数据不存在!');
$orderExpress = Db::name('StoreOrderExpress')->where(['order_no' => $order_no])->find();
empty($orderExpress) && $this->error('该订单无法进行地址修改!');
return $this->fetch('', $orderExpress);
}
$data = [
'order_no' => $order_no,
'username' => $this->request->post('express_username'),
'phone' => $this->request->post('express_phone'),
'province' => $this->request->post('form_express_province'),
'city' => $this->request->post('form_express_city'),
'area' => $this->request->post('form_express_area'),
'address' => $this->request->post('express_address'),
'desc' => $this->request->post('express_desc'),
];
if (DataService::save('StoreOrderExpress', $data, 'order_no')) {
$this->success('收货地址修改成功!', '');
}
$this->error('收货地址修改失败,请稍候再试!');
}
}

View File

@ -0,0 +1,204 @@
<?php
// +----------------------------------------------------------------------
// | Think.Admin
// +----------------------------------------------------------------------
// | 版权所有 2014~2017 广州楚才信息科技有限公司 [ http://www.cuci.cc ]
// +----------------------------------------------------------------------
// | 官方网站: http://think.ctolog.com
// +----------------------------------------------------------------------
// | 开源协议 ( https://mit-license.org )
// +----------------------------------------------------------------------
// | github开源项目https://github.com/zoujingli/Think.Admin
// +----------------------------------------------------------------------
namespace app\store\controller\wechat;
use Endroid\QrCode\QrCode;
use service\WechatService;
use WeChat\Pay;
/**
* 微信功能demo
* Class Demo
* @package app\store\controller\wechat
*/
class Demo
{
/**
* 微信扫码支付模式一二维码显示
* @return \think\Response
* @throws \Endroid\QrCode\Exceptions\ImageFunctionFailedException
* @throws \Endroid\QrCode\Exceptions\ImageFunctionUnknownException
* @throws \Endroid\QrCode\Exceptions\ImageTypeInvalidException
*/
public function scanOneQrc()
{
$wechat = new Pay(config('wechat.'));
$result = $wechat->createParamsForRuleQrc('8888888');
return $this->createQrc($result);
}
/**
* 微信扫码支付模式一通知处理
* @return string
* @throws \WeChat\Exceptions\InvalidResponseException
*/
public function scanOneNotify()
{
$wechat = new Pay(config('wechat.'));
$notify = $wechat->getNotify();
p('======= 来自扫码支付1的数据 ======');
p($notify);
// 产品ID @todo 你的业务,并实现下面的统一下单操作
$product_id = $notify['product_id'];
// 微信统一下单处理
$options = [
'body' => '测试商品产品ID' . $product_id,
'out_trade_no' => time(),
'total_fee' => '1',
'trade_type' => 'NATIVE',
'notify_url' => url('@wx-demo-notify', '', true, true),
'spbill_create_ip' => request()->ip(),
];
$order = $wechat->createOrder($options);
p('======= 来自扫码支付1统一下单结果 ======');
p($order);
// 回复XML文本
$result = [
'return_code' => 'SUCCESS',
'return_msg' => '处理成功',
'appid' => $notify['appid'],
'mch_id' => $notify['mch_id'],
'nonce_str' => \WeChat\Contracts\Tools::createNoncestr(),
'prepay_id' => $order['prepay_id'],
'result_code' => 'SUCCESS',
];
$result['sign'] = $wechat->getPaySign($result);
p('======= 来自扫码支付1返回的结果 ======');
p($result);
return \WeChat\Contracts\Tools::arr2xml($result);
}
/**
* 扫码支付模式二测试二维码
* @return \think\Response
* @throws \Endroid\QrCode\Exceptions\ImageFunctionFailedException
* @throws \Endroid\QrCode\Exceptions\ImageFunctionUnknownException
* @throws \Endroid\QrCode\Exceptions\ImageTypeInvalidException
* @throws \WeChat\Exceptions\InvalidResponseException
*/
public function scanQrc()
{
$wechat = new Pay(config('wechat.'));
$options = [
'body' => '测试商品',
'out_trade_no' => time(),
'total_fee' => '1',
'trade_type' => 'NATIVE',
'notify_url' => url('@wx-demo-notify', '', true, true),
'spbill_create_ip' => request()->ip(),
];
// 生成预支付码
$result = $wechat->createOrder($options);
return $this->createQrc($result['code_url']);
}
/**
* 公众号JSAPI支付二维码
* @return \think\Response
* @throws \Endroid\QrCode\Exceptions\ImageFunctionFailedException
* @throws \Endroid\QrCode\Exceptions\ImageFunctionUnknownException
* @throws \Endroid\QrCode\Exceptions\ImageTypeInvalidException
*/
public function jsapiQrc()
{
$url = url('@wx-demo-jsapi', '', true, true);
return $this->createQrc($url);
}
/**
* 公众号JSAPI支付测试
* @link wx-demo-jsapi
* @throws \WeChat\Exceptions\InvalidResponseException
* @throws \WeChat\Exceptions\LocalCacheException
* @throws \think\Exception
* @throws \think\exception\PDOException
*/
public function jsapi()
{
$wechat = new Pay(config('wechat.'));
$openid = WechatService::webOauth(request()->url(true), 0)['openid'];
$options = [
'body' => '测试商品',
'out_trade_no' => time(),
'total_fee' => '1',
'openid' => $openid,
'trade_type' => 'JSAPI',
'notify_url' => url('@wx-demo-notify', '', true, true),
'spbill_create_ip' => request()->ip(),
];
// 生成预支付码
$result = $wechat->createOrder($options);
// 创建JSAPI参数签名
$options = $wechat->createParamsForJsApi($result['prepay_id']);
$optionJSON = json_encode($options, JSON_UNESCAPED_UNICODE);
// JSSDK 签名配置
$configJSON = json_encode(WechatService::webJsSDK(), JSON_UNESCAPED_UNICODE);
echo '<pre>';
echo "当前用户OPENID: {$openid}";
echo "\n--- 创建预支付码 ---\n";
var_export($result);
echo '</pre>';
echo '<pre>';
echo "\n\n--- JSAPI 及 H5 参数 ---\n";
var_export($options);
echo '</pre>';
echo "<button id='paytest' type='button'>JSAPI支付测试</button>";
echo "
<script src='//res.wx.qq.com/open/js/jweixin-1.2.0.js'></script>
<script>
wx.config($configJSON);
document.getElementById('paytest').onclick = function(){
var options = $optionJSON;
options.success = function(){
alert('支付成功');
}
wx.chooseWXPay(options);
}
</script>";
}
/**
* 支付通知接收处理
* @return string
* @throws \WeChat\Exceptions\InvalidResponseException
*/
public function notify()
{
$wechat = new Pay(config('wechat.'));
p($wechat->getNotify());
return 'SUCCESS';
}
/**
* 显示二维码
* @param string $url
* @return \think\Response
* @throws \Endroid\QrCode\Exceptions\ImageFunctionFailedException
* @throws \Endroid\QrCode\Exceptions\ImageFunctionUnknownException
* @throws \Endroid\QrCode\Exceptions\ImageTypeInvalidException
*/
protected function createQrc($url)
{
$qrCode = new QrCode();
$qrCode->setText($url)->setSize(300)->setPadding(20)->setImageType(QrCode::IMAGE_TYPE_PNG);
return \think\facade\Response::header('Content-Type', 'image/png')->data($qrCode->get());
}
}

View File

@ -3,24 +3,28 @@
// +----------------------------------------------------------------------
// | Think.Admin
// +----------------------------------------------------------------------
// | 版权所有 2016~2017 广州楚才信息科技有限公司 [ http://www.cuci.cc ]
// | 版权所有 2014~2017 广州楚才信息科技有限公司 [ http://www.cuci.cc ]
// +----------------------------------------------------------------------
// | 官方网站: http://think.ctolog.com
// +----------------------------------------------------------------------
// | 开源协议 ( http://www.apache.org/licenses/LICENSE-2.0 )
// | 开源协议 ( https://mit-license.org )
// +----------------------------------------------------------------------
// | github开源项目https://github.com/zoujingli/Think.Admin
// +----------------------------------------------------------------------
namespace app\index\controller;
namespace app\store\controller\wechat;
use controller\BasicApi;
use service\FileService;
class Test extends BasicApi {
public function index() {
dump(FileService::oss('fassdfsa', 'fsadfasdf'));
class Index
{
public function index()
{
return '微信商城---开发中...';
}
}
public function pay()
{
return 'fsdfasfsa';
}
}

View File

@ -0,0 +1,34 @@
<?php
// +----------------------------------------------------------------------
// | ThinkAdmin
// +----------------------------------------------------------------------
// | 版权所有 2014~2017 广州楚才信息科技有限公司 [ http://www.cuci.cc ]
// +----------------------------------------------------------------------
// | 官方网站: http://think.ctolog.com
// +----------------------------------------------------------------------
// | 开源协议 ( https://mit-license.org )
// +----------------------------------------------------------------------
// | github开源项目https://github.com/zoujingli/ThinkAdmin
// +----------------------------------------------------------------------
use think\facade\App;
use think\facade\Route;
use think\Request;
/* 注册微信端路由支持 */
Route::rule('wx<_?>', function (Request $request) {
$params = explode('-', $request->path());
array_shift($params);
$controller = array_shift($params) ?: config('app.default_controller');
$action = array_shift($params) ?: config('app.default_action');
return App::action("store/wechat.{$controller}/{$action}", $params);
});
// 微信菜单链接配置
$GLOBALS['WechatMenuLink'][] = ['link' => '@wx', 'title' => '微信商城首页'];
$GLOBALS['WechatMenuLink'][] = ['link' => '@wx-demo-jsapi', 'title' => 'JSAPI支付测试'];
// @todo 模块处理机制将写在下面(包括模块初始化及升级)
// @todo 模块权限处理,使用全局数组
// @todo 模板菜单处理,默认放到全局数组中,然后在菜单中可以快速编辑(还要考虑下)

View File

@ -0,0 +1,130 @@
<?php
// +----------------------------------------------------------------------
// | ThinkAdmin
// +----------------------------------------------------------------------
// | 版权所有 2014~2017 广州楚才信息科技有限公司 [ http://www.cuci.cc ]
// +----------------------------------------------------------------------
// | 官方网站: http://think.ctolog.com
// +----------------------------------------------------------------------
// | 开源协议 ( https://mit-license.org )
// +----------------------------------------------------------------------
// | github开源项目https://github.com/zoujingli/ThinkAdmin
// +----------------------------------------------------------------------
namespace app\store\service;
use think\Db;
/**
* 商品数据服务支持
* Class ProductService
* @package app\goods\service
*/
class GoodsService
{
/**
* 主商品表数据处理
* @param array $goodsList
* @return array
*/
public static function buildGoodsList(&$goodsList)
{
// 商品分类处理
$cateField = 'id,pid,cate_title,cate_desc';
$cateWhere = ['status' => '1', 'is_deleted' => '0'];
$cateList = Db::name('StoreGoodsCate')->where($cateWhere)->order('sort asc,id desc')->column($cateField);
// 商品品牌处理
$brandWhere = ['status' => '1', 'is_deleted' => '0'];
$brandField = 'id,brand_logo,brand_cover,brand_title,brand_desc,brand_detail';
$brandList = Db::name('StoreGoodsBrand')->where($brandWhere)->order('sort asc,id desc')->column($brandField);
// 无商品列表时
if (empty($goodsList)) {
return ['list' => $goodsList, 'cate' => $cateList, 'brand' => $brandList];
}
// 读取商品详情列表
$specWhere = [['status', 'eq', '1'], ['is_deleted', 'eq', '0'], ['goods_id', 'in', array_column($goodsList, 'id')]];
$specField = 'id,goods_id,goods_spec,goods_number,market_price,selling_price,goods_stock,goods_sale';
$specList = Db::name('StoreGoodsList')->where($specWhere)->column($specField);
foreach ($specList as $key => $spec) {
foreach ($goodsList as $goods) {
if ($goods['id'] === $spec['goods_id']) {
$specList[$key]['goods_title'] = $goods['goods_title'];
}
}
if ($spec['goods_spec'] === 'default:default') {
$specList[$key]['goods_spec_alias'] = '<span class="color-desc">默认规格</span>';
} else {
$specList[$key]['goods_spec_alias'] = str_replace([':', ','], [': ', ', '], $spec['goods_spec']);
}
}
// 商品数据组装
foreach ($goodsList as $key => $vo) {
// 商品内容处理
$goodsList[$key]['goods_content'] = $vo['goods_content'];
// 商品品牌处理
$goodsList[$key]['brand'] = isset($brandList[$vo['brand_id']]) ? $brandList[$vo['brand_id']] : [];
// 商品分类关联
$goodsList[$key]['cate'] = [];
if (isset($cateList[$vo['cate_id']])) {
$goodsList[$key]['cate'][] = ($tcate = $cateList[$vo['cate_id']]);
while (isset($tcate['pid']) && $tcate['pid'] > 0 && isset($cateList[$tcate['pid']])) {
$goodsList[$key]['cate'][] = ($tcate = $cateList[$tcate['pid']]);
}
$goodsList[$key]['cate'] = array_reverse($goodsList[$key]['cate']);
}
// 商品详细列表关联
$goodsList[$key]['spec'] = [];
foreach ($specList as $spec) {
if ($vo['id'] === $spec['goods_id']) {
$goodsList[$key]['spec'][] = $spec;
}
}
}
return ['list' => $goodsList, 'cate' => $cateList, 'brand' => $brandList];
}
/**
* 同步更新商品库存及售出
* @param int $goods_id 商品ID
* @return array
* @throws \think\Exception
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
* @throws \think\exception\PDOException
*/
public static function syncGoodsStock($goods_id)
{
// 检查商品是否需要更新库存
$map = ['id' => $goods_id, 'is_deleted' => '0'];
if (!($goods = Db::name('StoreGoods')->where($map)->find())) {
return ['code' => 0, 'msg' => '指定商品信息无法同步库存!'];
}
// 统计入库信息
$stockField = 'goods_id,goods_spec,ifnull(sum(goods_stock), 0) goods_stock';
$stockWhere = ['status' => '1', 'is_deleted' => '0', 'goods_id' => $goods_id];
$stockList = (array)Db::name('StoreGoodsStock')->field($stockField)->where($stockWhere)->group('goods_id,goods_spec')->select();
// 统计销售信息
$saleField = 'goods_id,goods_spec,ifnull(sum(number), 0) goods_sale';
$saleWhere = ['status' => '1', 'is_deleted' => '0', 'goods_id' => $goods_id];
$saleList = (array)Db::name('StoreOrderGoods')->field($saleField)->where($saleWhere)->group('goods_id,goods_spec')->select();
// 库存置零
list($where, $total_sale) = [['goods_id' => $goods_id], 0];
Db::name('StoreGoodsList')->where($where)->update(['goods_stock' => 0, 'goods_sale' => 0]);
// 更新商品库存
foreach ($stockList as $stock) {
$where = ['goods_id' => $goods_id, 'goods_spec' => $stock['goods_spec']];
Db::name('StoreGoodsList')->where($where)->update(['goods_stock' => $stock['goods_stock']]);
}
// 更新商品销量
foreach ($saleList as $sale) {
$total_sale += intval($sale['goods_sale']);
$where = ['goods_id' => $goods_id, 'goods_spec' => $sale['goods_spec']];
Db::name('StoreGoodsList')->where($where)->update(['goods_sale' => $sale['goods_sale']]);
}
return ['code' => 1, 'msg' => '同步商品库存成功!'];
}
}

View File

@ -0,0 +1,37 @@
<?php
// +----------------------------------------------------------------------
// | ThinkAdmin
// +----------------------------------------------------------------------
// | 版权所有 2014~2017 广州楚才信息科技有限公司 [ http://www.cuci.cc ]
// +----------------------------------------------------------------------
// | 官方网站: http://think.ctolog.com
// +----------------------------------------------------------------------
// | 开源协议 ( https://mit-license.org )
// +----------------------------------------------------------------------
// | github开源项目https://github.com/zoujingli/ThinkAdmin
// +----------------------------------------------------------------------
namespace app\store\service;
use service\DataService;
/**
* 会员数据初始化
* Class MemberService
* @package app\store\service
*/
class MemberService
{
/**
* 创建会员数据
* @param array $data 会员数据
* @return bool
* @throws \think\Exception
* @throws \think\exception\PDOException
*/
public static function create($data)
{
return DataService::save('StoreMember', $data, 'id');
}
}

View File

@ -0,0 +1,189 @@
<?php
// +----------------------------------------------------------------------
// | Think.Admin
// +----------------------------------------------------------------------
// | 版权所有 2014~2017 广州楚才信息科技有限公司 [ http://www.cuci.cc ]
// +----------------------------------------------------------------------
// | 官方网站: http://think.ctolog.com
// +----------------------------------------------------------------------
// | 开源协议 ( https://mit-license.org )
// +----------------------------------------------------------------------
// | github开源项目https://github.com/zoujingli/Think.Admin
// +----------------------------------------------------------------------
namespace app\store\service;
use service\DataService;
use service\ToolsService;
use think\Db;
/**
* 商城订单服务
* Class OrderService
* @package app\store
*/
class OrderService
{
/**
* 商城创建订单
* @param int $mid 会员ID
* @param string $params 商品参数规格 (商品ID@商品规格@购买数量;商品ID@商品规格@购买数量)
* @param int $addressId 地址记录ID
* @param int $expressId 快递记录ID
* @param string $orderDesc 订单描述
* @param integer $orderType 订单类型
* @param string $from 订单来源
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
public static function create($mid, $params, $addressId, $expressId, $orderDesc = '', $orderType = 1, $from = 'wechat')
{
// 会员数据获取与检验
if (!($member = Db::name('StoreMember')->where(['id' => $mid])->find())) {
return ['code' => 0, 'msg' => '会员数据处理异常,请刷新重试!'];
}
// 订单数据生成
list($order_no, $orderList) = [DataService::createSequence(10, 'ORDER'), []];
$order = ['mid' => $mid, 'order_no' => $order_no, 'real_price' => 0, 'goods_price' => 0, 'desc' => $orderDesc, 'type' => $orderType, 'from' => $from];
foreach (explode(';', trim($params, ',;@')) as $param) {
list($goods_id, $goods_spec, $number) = explode('@', "{$param}@@");
$item = ['mid' => $mid, 'type' => $orderType, 'order_no' => $order_no, 'goods_id' => $goods_id, 'goods_spec' => $goods_spec, 'goods_number' => $number];
$goodsResult = self::buildOrderData($item, $order, $orderList, 'selling_price');
if (empty($goodsResult['code'])) {
return $goodsResult;
}
}
// 生成快递信息
$expressResult = self::buildExpressData($order, $addressId, $expressId);
if (empty($expressResult['code'])) {
return $expressResult;
}
try {
// 写入订单信息
Db::transaction(function () use ($order, $orderList, $expressResult) {
Db::name('StoreOrder')->insert($order); // 主订单信息
Db::name('StoreOrderGoods')->insertAll($orderList); // 订单关联的商品信息
Db::name('storeOrderExpress')->insert($expressResult['data']); // 快递信息
});
// 同步商品库存列表
foreach (array_unique(array_column($orderList, 'goods_id')) as $stock_goods_id) {
GoodsService::syncGoodsStock($stock_goods_id);
}
} catch (\Exception $e) {
return ['code' => 0, 'msg' => '商城订单创建失败,请稍候再试!' . $e->getLine() . $e->getFile() . $e->getMessage()];
}
return ['code' => 1, 'msg' => '商城订单创建成功!', 'order_no' => $order_no];
}
/**
* 生成订单快递数据
* @param array $order 订单主表记录
* @param int $address_id 会员地址ID
* @param int $express_id 快递信息ID
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
public static function buildExpressData(&$order, $address_id, $express_id)
{
// 收货地址处理
$addressWhere = ['mid' => $order['mid'], 'id' => $address_id, 'status' => '1', 'is_deleted' => '0'];
$addressField = 'username express_username,phone express_phone,province express_province,city express_city,area express_area,address express_address';
if (!($address = Db::name('StoreMemberAddress')->field($addressField)->where($addressWhere)->find())) {
return ['code' => 0, 'msg' => '收货地址数据异常!'];
}
// 物流信息查询
$expressField = 'express_title,express_code';
$expressWhere = ['id' => $express_id, 'status' => '1', 'is_deleted' => '0'];
if (!($express = Db::name('StoreExpress')->field($expressField)->where($expressWhere)->find())) {
return ['code' => 0, 'msg' => '快递公司数据异常!'];
}
// @todo 运费计算处理
// $order['freight_price'] = '0.00';
// $order['real_price'] += floatval($order['freight_price']);
$extend = ['mid' => $order['mid'], 'order_no' => $order['order_no'], 'type' => $order['type']];
return ['code' => 1, 'data' => array_merge($address, $express, $extend), 'msg' => '生成快递信息成功!'];
}
/**
* 订单数据生成
* @param array $item 订单单项参数
* (mid,type,order_no,goods_id,goods_spec,goods_number)
* @param array $order 订单主表
* @param array $orderList 订单详细表
* @param string $price_field 实际计算单价字段
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
private static function buildOrderData($item, &$order, &$orderList, $price_field = 'selling_price')
{
list($mid, $type, $order_no, $goods_id, $goods_spec, $number) = [
$item['mid'], $item['type'], $item['order_no'], $item['goods_id'], $item['goods_spec'], $item['goods_number'],
];
// 商品主体信息
$goodsField = 'goods_title,goods_logo,goods_image';
$goodsWhere = ['id' => $goods_id, 'status' => '1', 'is_deleted' => '0'];
if (!($goods = Db::name('StoreGoods')->field($goodsField)->where($goodsWhere)->find())) {
return ['code' => 0, 'msg' => "无效的商品信息!", 'data' => "{$goods_id}, {$goods_spec}, {$number}"];
}
// 商品规格信息
$specField = 'goods_id,goods_spec,market_price,selling_price,goods_stock,goods_sale';
$specWhere = ['status' => '1', 'is_deleted' => '0', 'goods_id' => $goods_id, 'goods_spec' => $goods_spec];
if (!($goodsSpec = Db::name('StoreGoodsList')->field($specField)->where($specWhere)->find())) {
return ['code' => 0, 'msg' => '无效的商品规格信息!', 'data' => "{$goods_id}, {$goods_spec}, {$number}"];
}
// 商品库存检查
if ($goodsSpec['goods_stock'] - $goodsSpec['goods_sale'] < $number) {
return ['code' => 0, 'msg' => '商品库存不足,请更换其它商品!', 'data' => "{$goods_id}, {$goods_spec}, {$number}"];
}
// 订单价格处理
$goodsSpec['price_field'] = $price_field;
$orderList[] = array_merge($goods, $goodsSpec, ['mid' => $mid, 'number' => $number, 'order_no' => $order_no, 'type' => $type]);
$order['goods_price'] += floatval($goodsSpec[$price_field]) * $number;
$order['real_price'] += floatval($goodsSpec[$price_field]) * $number;
return ['code' => 1, 'msg' => '商品添加到订单成功!'];
}
/**
* 订单主表数据处理
* @param array $list
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
public static function buildOrderList(&$list)
{
$mids = array_unique(array_column($list, 'mid'));
$orderNos = array_unique(array_column($list, 'order_no'));
$memberList = Db::name("StoreMember")->whereIn('id', $mids)->select();
$goodsList = Db::name('StoreOrderGoods')->whereIn('order_no', $orderNos)->select();
$expressList = Db::name('StoreOrderExpress')->whereIn('order_no', $orderNos)->select();
foreach ($list as $key => $vo) {
list($list[$key]['member'], $list[$key]['goods'], $list[$key]['express']) = [[], [], []];
foreach ($memberList as $member) {
$member['nickname'] = ToolsService::emojiDecode($member['nickname']);
($vo['mid'] === $member['id']) && $list[$key]['member'] = $member;
}
foreach ($expressList as $express) {
($vo['order_no'] === $express['order_no']) && $list[$key]['express'] = $express;
}
foreach ($goodsList as $goods) {
if ($goods['goods_spec'] === 'default:default') {
$goods['goods_spec_alias'] = '<span class="color-desc">默认规格</span>';
} else {
$goods['goods_spec_alias'] = str_replace([':', ','], ['', ''], $goods['goods_spec']);
}
($vo['order_no'] === $goods['order_no']) && $list[$key]['goods'][] = $goods;
}
}
return $list;
}
}

View File

@ -0,0 +1,36 @@
<form autocomplete="off" class="layui-form layui-box" style='padding:25px 30px 20px 0' action="{:request()->url()}" data-auto="true" method="post">
<div class="layui-form-item">
<label class="layui-form-label">快递公司名称</label>
<div class="layui-input-block">
<input autofocus name="express_title" value='{$vo.express_title|default=""}' required="required"
title="请输入快递公司名称" placeholder="请输入快递公司名称" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">快递公司代码</label>
<div class="layui-input-block">
<input autofocus name="express_code" value='{$vo.express_code|default=""}' required="required"
title="请输入快递公司代码" placeholder="请输入快递公司代码" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">快递公司描述</label>
<div class="layui-input-block">
<textarea placeholder="请输入快递公司描述" title="请输入快递公司描述"
class="layui-textarea" name="express_desc">{$vo.express_desc|default=""}</textarea>
</div>
</div>
<div class="hr-line-dashed"></div>
<div class="layui-form-item text-center">
{if isset($vo['id'])}<input type='hidden' value='{$vo.id}' name='id'/>{/if}
<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>

View File

@ -0,0 +1,117 @@
{extend name='admin@public/content'}
{block name="button"}
<!--{if auth("$classuri/add")}-->
<button data-modal='{:url("$classuri/add")}' data-title="添加快递" class='layui-btn layui-btn-sm layui-btn-primary'>添加快递</button>
<!--{/if}-->
<!--{if auth("$classuri/del")}-->
<button data-update data-field='delete' data-action='{:url("$classuri/del")}' class='layui-btn layui-btn-sm layui-btn-primary'>删除快递</button>
<!--{/if}-->
{/block}
{block name="content"}
<!-- 表单搜索 开始 -->
<form autocomplete="off" class="layui-form layui-form-pane form-search" action="{:request()->url()}" onsubmit="return false" method="get">
<div class="layui-form-item layui-inline">
<label class="layui-form-label">快递公司</label>
<div class="layui-input-inline">
<input name="express_title" value="{$Think.get.express_title}" placeholder="请输入快递名称" class="layui-input">
</div>
</div>
<div class="layui-form-item layui-inline">
<label class="layui-form-label">快递代码</label>
<div class="layui-input-inline">
<input name="express_code" value="{$Think.get.express_code}" 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="date" id="range-date" value="{$Think.get.date}" placeholder="请选择添加时间" class="layui-input">
</div>
</div>
<div class="layui-form-item layui-inline">
<button class="layui-btn layui-btn-primary"><i class="layui-icon">&#xe615;</i> 搜 索</button>
</div>
</form>
<script>
window.laydate.render({range: true, elem: '#range-date'});
window.form.render();
</script>
<!-- 表单搜索 结束 -->
<form autocomplete="off" onsubmit="return false;" data-auto="true" method="post">
<input type="hidden" value="resort" name="action"/>
{if empty($list)}
<p class="help-block text-center well"> 哦!</p>
{else}
<table class="layui-table" lay-skin="line" lay-size="sm">
<thead>
<tr>
<th class='list-table-check-td think-checkbox'>
<input data-auto-none="none" data-check-target='.list-check-box' type='checkbox'/>
</th>
<th class='list-table-sort-td'>
<button type="submit" class="layui-btn layui-btn-normal layui-btn-xs"> </button>
</th>
<th class='text-left'>快递公司</th>
<th class='text-left'>快递代码</th>
<th class='text-left'>添加时间</th>
<th class='text-left'>快递状态</th>
<th class='text-left'>操作</th>
</tr>
</thead>
<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='list-table-sort-td'>
<input name="_{$vo.id}" value="{$vo.sort}" class="list-sort-input"/>
</td>
<td class='text-left'>{$vo.express_title}</td>
<td class='text-left'>{$vo.express_code}</td>
<td class='text-left'>{$vo.create_at|format_datetime}</td>
<td class='text-left'>
{if $vo.status eq 0}<span class="color-red">已禁用</span>{elseif $vo.status eq 1}<span class="color-green">使用中</span>{/if}
</td>
<td class='text-left nowrap'>
<!--{if auth("$classuri/edit")}-->
<span class="text-explode">|</span>
<a data-title="编辑快递" data-modal='{:url("$classuri/edit")}?id={$vo.id}'>编辑</a>
<!--{/if}-->
<!--{if $vo.status eq 1 and auth("$classuri/forbid")}-->
<span class="text-explode">|</span>
<a data-update="{$vo.id}" data-field='status' data-value='0' data-action='{:url("$classuri/forbid")}'>禁用</a>
<!--{elseif auth("$classuri/resume")}-->
<span class="text-explode">|</span>
<a data-update="{$vo.id}" data-field='status' data-value='1' data-action='{:url("$classuri/resume")}'>启用</a>
<!--{/if}-->
{if auth("$classuri/del")}
<span class="text-explode">|</span>
<a data-update="{$vo.id}" data-field='delete' data-action='{:url("$classuri/del")}'>删除</a>
{/if}
</td>
</tr>
{/foreach}
</tbody>
</table>
{if isset($page)}<p>{$page|raw}</p>{/if}
{/if}
</form>
{/block}

View File

@ -0,0 +1,357 @@
{extend name='admin@public/content'}
{block name="content"}
<form autocomplete="off" onsubmit="return false;" action="{:request()->url()}" data-auto="true" method="post" id="ProductForm" class='form-horizontal layui-form padding-top-20'>
<!--{if !empty($brands)}-->
<div class="form-group">
<label class="col-sm-2 control-label">商品品牌</label>
<div class='col-sm-8'>
<select required class="layui-select full-width" name="brand_id">
{foreach $brands as $brand}
<!--{eq name='$brand.id' value='$vo.brand_id|default=0'}-->
<option selected="selected" value="{$brand.id}">{$brand.brand_title}</option>
<!--{else}-->
<option value="{$brand.id}">{$brand.brand_title}</option>
<!--{/eq}-->
{/foreach}
</select>
</div>
</div>
<!--{/if}-->
<!--{if !empty($cates)}-->
<div class="form-group">
<label class="col-sm-2 control-label">商品分类</label>
<div class='col-sm-8 text-top'>
<select required class="layui-select full-width" name="cate_id">
{foreach $cates as $cate}
<!--{if isset($vo.cate_id) and $cate.id eq $vo.cate_id}-->
<option selected value="{$cate.id}">{$cate.spl|raw}{$cate.cate_title}</option>
<!--{else}-->
<option value="{$cate.id}">{$cate.spl|raw}{$cate.cate_title}</option>
<!--{/if}-->
{/foreach}
</select>
</div>
</div>
<!--{/if}-->
<div class="form-group">
<label class="col-sm-2 control-label">商品名称</label>
<div class='col-sm-8'>
<input name="goods_title" required value="{$vo.goods_title|default=''}" class="layui-input" title="请输入商品名称" placeholder="请输入商品名称">
</div>
</div>
{if !empty($tags)}
<div class="form-group">
<label class="col-sm-2 control-label">商品标签</label>
<div class='col-sm-8'>
<div class="background-item">
{foreach $tags as $tag}
<label class="nowrap margin-right-10 line-height-18">
<!--{if isset($vo.tags_id) && in_array($tag.id,$vo.tags_id)}-->
<input type="checkbox" value="{$tag.id}" name="tags_id[]" checked="checked" lay-ignore>
<!--{else}-->
<input type="checkbox" value="{$tag.id}" name="tags_id[]" lay-ignore>
<!--{/if}-->
{$tag.tags_title}
</label>
{/foreach}
</div>
</div>
</div>
{/if}
<div class="form-group">
<label class="col-sm-2 control-label label-required">商品图片</label>
<div class='col-sm-8'>
<table class="layui-table background-item margin-none" lay-size="sm" lay-skin="nob">
<thead>
<tr>
<td>商品LOGO</td>
<td>商品图片</td>
</tr>
</thead>
<tbody>
<tr>
<td class="text-top" style="width:100px">
<input type="hidden" name="goods_logo" value="{$vo.goods_logo|default=''}">
</td>
<td class="text-top">
<input type="hidden" name="goods_image" value="{$vo.goods_image|default=''}">
</td>
</tr>
</tbody>
</table>
</div>
</div>
<!-- 普通商品及积分商品 开始 -->
<div class="form-group">
<label class="col-sm-2 control-label">商品规格</label>
<div class='col-sm-8'>
<select required class="layui-select full-width block" name="spec_id" lay-ignore>
{foreach $specs as $spec}
{php}$param=str_replace('"',"'",$spec['spec_param']);{/php}
<!--{eq name='spec.id' value='$vo.spec_id|default=0'}-->
<option data-param="{$param}" selected="selected" value="{$spec.id}">{$spec.spec_title}</option>
<!--{else}-->
<option data-param="{$param}" value="{$spec.id}">{$spec.spec_title}</option>
<!--{/eq}-->
{/foreach}
</select>
<table class="layui-table notevent" lay-size="sm" ng-if="specs.length>0">
<tr>
<th>可选规格</th>
<th>规格内容</th>
</tr>
<tr ng-repeat="x in specs">
<td ng-bind="x.name"></td>
<td>
<label ng-repeat="m in x.param" class="nowrap margin-right-10 line-height-18">
<input data-spec="{{x.name}}_{{m.value}}" ng-model="m.checked" class="inline-block" type="checkbox" lay-ignore>
<span ng-bind="m.value"></span>
</label>
</td>
</tr>
</table>
<table class="layui-table notevent" lay-size="sm">
<thead>
<tr>
<th>商品规格</th>
<th>市场价格</th>
<th>销售价格</th>
<th>规格状态</th>
</tr>
</thead>
<tbody>
<tr ng-class="x.status?'':'layui-bg-gray'" ng-repeat="x in specdata">
<td class="nowrap">
<input type="hidden" name="goods_spec[]" value="{{x.spec_name}}">
<span ng-repeat="a in x.spec_attrs">
<span class="layui-badge layui-bg-blue" ng-bind="a.name"></span>
<span ng-if="b" class="layui-badge layui-bg-green" ng-repeat="b in a.value" ng-bind="b"></span>
</span>
</td>
<td class="price-input-td">
<input onblur="this.value=(parseFloat(this.value)||0).toFixed(2)" class="layui-input" placeholder="0.00" name="market_price[]" value="{{x.market_price}}">
</td>
<td class="price-input-td">
<input onblur="this.value=(parseFloat(this.value)||0).toFixed(2)" class="layui-input" placeholder="0.00" name="selling_price[]" value="{{x.selling_price}}">
</td>
<td>
<label class="nowrap line-height-18">
<input type="hidden" name="spec_status[]" value="{{x.status?1:0}}">
<input ng-checked="x.status" ng-model="x.status" value="1" lay-ignore class="inline-block" type="checkbox"/> 启用
</label>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<!-- 普通商品及积分商品 结束 -->
<div class="form-group">
<label class="col-sm-2 control-label">视频展示</label>
<div class='col-sm-8'>
<div class="row">
<div class="col-sm-10 padding-right-0">
<input style="border-right:none" name="goods_video" value="{$vo.goods_video|default=''}" class="layui-input" title="请输入链接或上传视频展示文件" placeholder="请输入链接或上传视频展示文件">
</div>
<div class="col-sm-2 padding-left-0">
<button data-file="one" data-type="mp4" data-field="goods_video" type="button" class="layui-btn layui-btn-sm" style="height:38px;line-height:38px;width:100%">上传视频文件</button>
</div>
</div>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">展示描述</label>
<div class='col-sm-8'>
<textarea class="layui-textarea" name="goods_desc" placeholder="请输入展示描述">{$vo.goods_desc|default=''}</textarea>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label label-required">商品内容</label>
<div class='col-sm-8'>
<textarea name="goods_content">{$vo.goods_content|default=''|htmlspecialchars_decode}</textarea>
</div>
</div>
<div class="hr-line-dashed"></div>
<div class="col-sm-7 col-sm-offset-2">
<div class="layui-form-item text-center">
{if !empty($vo.id)}<input type="hidden" name="id" value="{$vo.id}">{/if}
<button class="layui-btn" type="submit">保存配置</button>
<button class="layui-btn layui-btn-danger" type='button' onclick="window.history.back()">取消编辑</button>
</div>
</div>
</form>
<script>
require(['jquery', 'ckeditor', 'angular'], function () {
window.form.render();
window.createEditor('[name="goods_content"]', {height: 500});
var app = angular.module("ProductForm", []).run(callback);
angular.bootstrap(document.getElementById(app.name), [app.name]);
function callback($rootScope) {
// 绑定规格列表
$rootScope.specs = [];
// 规格默认数据
var specdata = JSON.parse('{$vo.list|default=[]|json_encode=###,256|raw}');
// 单图片上传处理
$('#ProductForm [name="goods_logo"]').uploadOneImage();
// 多图片上传处理
$('#ProductForm [name="goods_image"]').uploadMultipleImage();
// 规格显示切换
$('#ProductForm').on('click', '[data-spec]', applySpecData);
// 商品规格切换
$('#ProductForm').on('change', '[name="spec_id"]', function () {
var specs = eval(this.options[this.selectedIndex].getAttribute('data-param'));
for (var i in specs) {
specs[i].param = [];
var values = specs[i].value.split(' ');
for (var j in values) {
specs[i].param.push({
name: specs[i].name, value: values[j],
checked: getSpecStatus(specs[i].name, values[j])
});
}
}
$rootScope.$apply(function () {
$rootScope.specs = specs;
setTimeout(applySpecData, 10);
});
}).find('[name="spec_id"]').trigger('change');
// 规格属性切换
function applySpecData() {
var params = {};
for (var i in $rootScope.specs) {
var isChecked = false;
for (var j in $rootScope.specs[i].param) {
if ($rootScope.specs[i].param[j].checked) {
isChecked = true;
var name = $rootScope.specs[i].param[j].name;
var value = $rootScope.specs[i].param[j].value;
(params[name] || (params[name] = [])).push({name: name, value: value});
}
}
if (!isChecked) {
$rootScope.specs[i].param[0].checked = true;
var name = $rootScope.specs[i].param[0].name;
var value = $rootScope.specs[i].param[0].value;
(params[name] || (params[name] = [])).push({name: name, value: value});
}
}
$rootScope.$apply(function () {
$rootScope.specdata = DataArray.render(params);
});
}
// 获取规格选择状态
function getSpecStatus(name, spec) {
for (var i in specdata) {
if (specdata[i].goods_spec.indexOf(name + ':' + spec) > -1) {
return true;
}
}
return false;
}
// 数据处理
var DataArray = new function () {
// 编译生成规格数据
this.render = function (data) {
var specs = [], list = [];
for (var i in data) {
specs = this.joinArray(data[i], specs, i);
}
(specs.length < 1) && (specs = ['default:default']);
for (var i in specs) {
var specName = specs[i];
var specTitle = (specName === 'default:default') ? '默认规格' : specName.replace(/,/ig, ';').replace(/:/ig, ':');
var specAttrs = [], lines = specTitle.split(';');
for (var j in lines) {
var line = lines[j].split(':');
specAttrs.push({name: line[0], value: (line[1] || '').split(',')});
}
list.push({
spec_name: specName, spec_title: specTitle, spec_attrs: specAttrs,
market_price: parseFloat(this.getData(specs[i], 'market_price') || '0').toFixed(2),
selling_price: parseFloat(this.getData(specs[i], 'selling_price') || '0').toFixed(2),
status: this.getData(specName, 'status') !== '0'
});
}
return list;
};
// 读取规格默认数据
this.getData = function (spec, field) {
for (var i in specdata) {
if (specdata[i].goods_spec === spec) {
return specdata[i][field] || '0';
}
}
return '1';
};
// 数组交叉计算
this.joinArray = function (item, list, pk) {
var _list = [];
for (var i in item) {
if (list.length > 0) {
for (var j in list) {
_list.push(list[j] + ',' + pk + ':' + item[i].value);
}
} else {
_list.push(pk + ':' + item[i].value);
}
}
return _list;
}
};
}
});
</script>
{/block}
{block name="style"}
<style>
.background-item {
padding: 15px;
background: #efefef;
}
.background-item thead tr {
background: #e0e0e0
}
.price-input-td {
padding: 0 !important;
}
.price-input-td:before {
margin: 4px;
width: 35px;
height: 22px;
content: "金额";
line-height: 20px;
text-align: center;
position: absolute;
background: #e2e2e2;
}
.price-input-td input {
height: 30px;
padding-left: 50px;
border: none !important;
}
</style>
{/block}

View File

@ -0,0 +1,194 @@
{extend name='admin@public/content'}
{block name="button"}
<!--{if auth("$classuri/add")}-->
<button data-open='{:url("$classuri/add")}' data-title="添加商品" class='layui-btn layui-btn-sm layui-btn-primary'>添加商品</button>
<!--{/if}-->
<!--{if auth("$classuri/forbid")}-->
<button data-update data-field='status' data-value='0' data-action='{:url("$classuri/forbid")}' class='layui-btn layui-btn-sm layui-btn-primary'>批量下架</button>
<!--{/if}-->
<!--{if auth("$classuri/resume")}-->
<button data-update data-field='status' data-value='1' data-action='{:url("$classuri/resume")}' class='layui-btn layui-btn-sm layui-btn-primary'>批量上架</button>
<!--{/if}-->
<!--{if auth("$classuri/del")}-->
<button data-update data-field='delete' data-action='{:url("$classuri/del")}' class='layui-btn layui-btn-sm layui-btn-primary'>批量删除</button>
<!--{/if}-->
{/block}
{block name="content"}
<!-- 表单搜索 开始 -->
<form autocomplete="off" class="layui-form layui-form-pane form-search" action="{:request()->url()}" onsubmit="return false" method="get">
<div class="layui-form-item layui-inline">
<label class="layui-form-label">商品名称</label>
<div class="layui-input-inline">
<input name="goods_title" value="{$Think.get.goods_title}" placeholder="请输入商品名称" class="layui-input">
</div>
</div>
<!--{if !empty($cates)}-->
<div class="layui-form-item layui-inline">
<label class="layui-form-label">商品品牌</label>
<div class="layui-input-inline">
<select name="brand_id" lay-search>
<option value="">商品品牌</option>
{foreach $brands as $brand}
<!--{if $Think.get.brand_id eq $brand.id}-->
<option selected="selected" value="{$brand.id}">{$brand.brand_title}</option>
<!--{else}-->
<option value="{$brand.id}">{$brand.brand_title}</option>
<!--{/if}-->
{/foreach}
</select>
</div>
</div>
<!--{/if}-->
<!--{if !empty($cates)}-->
<div class="layui-form-item layui-inline">
<label class="layui-form-label">商品分类</label>
<div class="layui-input-inline">
<select name="cate_id" lay-search>
<option value="">所有分类</option>
{foreach $cates as $cate}
<!--{if $Think.get.cate_id eq $cate.id}-->
<option selected="selected" value="{$cate.id}">{$cate.spl|raw}{$cate.cate_title}</option>
<!--{else}-->
<option value="{$cate.id}">{$cate.spl|raw}{$cate.cate_title}</option>
<!--{/if}-->
{/foreach}
</select>
</div>
</div>
<!--{/if}-->
<div class="layui-form-item layui-inline">
<label class="layui-form-label">发布时间</label>
<div class="layui-input-inline">
<input name="create_at" id="create_at" value="{$Think.get.create_at}" placeholder="请选择发布时间" class="layui-input">
</div>
</div>
<div class="layui-form-item layui-inline">
<button class="layui-btn layui-btn-primary"><i class="layui-icon">&#xe615;</i> 搜 索</button>
</div>
</form>
<!-- 表单搜索 结束 -->
<form onsubmit="return false;" data-auto="true" method="post">
<!--{if empty($list)}-->
<p class="help-block text-center well"> 哦!</p>
<!--{else}-->
<input type="hidden" value="resort" name="action">
<table class="layui-table notevent" lay-skin="line">
<thead>
<tr>
<th class='list-table-check-td think-checkbox'>
<input data-auto-none="none" data-check-target='.list-check-box' type='checkbox'>
</th>
<th class='list-table-sort-td'>
<button type="submit" class="layui-btn layui-btn-normal layui-btn-xs"> </button>
</th>
<th class="nowrap">品牌分类</th>
<th class="padding-none">
<table class="think-inner-table layui-table">
<thead>
<tr>
<td>商品信息</td>
<td class="text-right nowrap">售价 ( 标价 ) / 库存 ( 剩余, 已售 )</td>
</tr>
</thead>
</table>
</th>
<th class="text-left">添加时间 / 状态</th>
<th class='text-center'></th>
</tr>
</thead>
<tbody>
{foreach $list as $key=>$vo}
<tr>
<td class='list-table-check-td text-top think-checkbox'>
<input class="list-check-box" value='{$vo.id}' type='checkbox'>
</td>
<td class='list-table-sort-td text-top'>
<input name="_{$vo.id}" value="{$vo.sort}" class="list-sort-input">
</td>
<td class="text-left nowrap text-top">
品牌:{$vo.brand.brand_title|default='<span class="color-desc">未配置品牌</span>'|raw}<br>
分类:{if empty($vo.cate)}<span class="color-desc">未配置分类</span>{else}
{foreach $vo.cate as $k=>$cate}{$cate.cate_title}
{if $k+1 < count($vo.cate)}<span class="layui-icon font-s12">&#xe602;</span>{/if}
{/foreach}
{/if}
</td>
<td class="text-left nowrap text-top" style="padding:2px">
<table class="think-inner-table layui-table notevent">
<colgroup>
<col width="60%">
</colgroup>
{foreach $vo.spec as $spec}
<tr>
<td>
[{$spec.goods_id}] {$spec.goods_title|default=''|raw}
<span class="layui-badge layui-bg-gray">{$spec.goods_spec_alias|raw}</span>
</td>
<td class="text-right nowrap">
<span class="layui-badge layui-bg-gray"> {$spec.selling_price} ( {$spec.market_price} ) </span>
<span class="layui-badge layui-bg-gray"> {$spec.goods_stock} ( {$spec.goods_stock-$spec.goods_sale}, {$spec.goods_sale} ) </span>
</td>
</tr>
{/foreach}
</table>
</td>
<td class='text-left nowrap text-top'>
{$vo.create_at|format_datetime|str_replace=' ','<br>',###|raw}
{if $vo.status eq '0'}<span class="color-red margin-left-10">已下架</span>{elseif $vo.status eq '1'}<span class="color-green margin-left-10">销售中</span>{/if}
</td>
<td class='text-center nowrap text-top'>
<!--{if auth("$classuri/edit")}-->
<span class="text-explode">|</span>
<a data-open='{:url("$classuri/edit")}?id={$vo.id}'>编辑</a>
<!--{/if}-->
<!--{if auth("$classuri/stock")}-->
<span class="text-explode">|</span>
<a data-title="商品入库" data-modal='{:url("$classuri/stock")}?id={$vo.id}'>入库</a>
<!--{/if}-->
<!--{if $vo.status eq 1 and auth("$classuri/forbid")}-->
<span class="text-explode">|</span>
<a data-update="{$vo.id}" data-field='status' data-value='0' data-action='{:url("$classuri/forbid")}'>下架</a>
<!--{elseif auth("$classuri/resume")}-->
<span class="text-explode">|</span>
<a data-update="{$vo.id}" data-field='status' data-value='1' data-action='{:url("$classuri/resume")}'>上架</a>
<!--{/if}-->
<!--{if auth("$classuri/del")}-->
<span class="text-explode">|</span>
<a data-update="{$vo.id}" data-field='delete' data-action='{:url("$classuri/del")}'>删除</a>
<!--{/if}-->
</td>
</tr>
{/foreach}
</tbody>
</table>
{if isset($page)}<p>{$page|raw}</p>{/if}
<!--{/if}-->
</form>
<script>
(function () {
window.form.render();
window.laydate.render({range: true, elem: '#create_at'});
})();
</script>
{/block}

View File

@ -0,0 +1,52 @@
<form autocomplete="off" class="layui-form layui-box modal-form-box" action="{:request()->url()}" data-auto="true" method="post">
<div class="layui-form-item">
<label class="layui-form-label">商品名称</label>
<div class="layui-input-block">
<input value='[{$vo.id}] {$vo.goods_title|default=""}' disabled="disabled" class="layui-input layui-bg-gray">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label label-required">商品库存</label>
<div class="layui-input-block">
<table class="layui-table" lay-size="sm">
<thead>
<tr>
<th>商品规格</th>
<th class="text-right">入库数量</th>
</tr>
</thead>
{foreach $vo.list as $spec}
<tr>
<td>
{$spec.goods_spec|str_replace=['default:default',',',':'],['默认规格','',''],###}
</td>
<td style="padding:0">
<input name="spec[]" value="{$spec.goods_spec}" type="hidden">
<input name="stock[]" value="0" onblur="this.value=parseInt(this.value)||0"
class="layui-input text-right padding-right-10 border-none">
</td>
</tr>
{/foreach}
</table>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">入库描述</label>
<div class="layui-input-block">
<textarea placeholder="请输入入库描述" title="请输入入库描述" class="layui-textarea" name="desc"></textarea>
</div>
</div>
<div class="hr-line-dashed"></div>
<div class="layui-form-item text-center">
{if isset($vo['id'])}<input type='hidden' value='{$vo.id}' name='id'/>{/if}
<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>

View File

@ -0,0 +1,82 @@
{extend name='admin@public/content'}
{block name="content"}
<form autocomplete="off" onsubmit="return false;" action="{:request()->url()}" data-auto="true" method="post" class='form-horizontal layui-form padding-top-20'>
<div class="form-group">
<label class="col-sm-2 control-label">品牌名称</label>
<div class='col-sm-8'>
<input autofocus name="brand_title" value='{$vo.brand_title|default=""}' required="required" title="请输入品牌名称" placeholder="请输入品牌名称" class="layui-input">
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label label-required">品牌图片</label>
<div class='col-sm-8'>
<table class="layui-table background-item margin-none" lay-size="sm" lay-skin="nob">
<thead>
<tr>
<td>品牌LOGO</td>
<td>品牌图片</td>
</tr>
</thead>
<tbody>
<tr>
<td class="text-top" style="width:100px">
<input type="hidden" name="brand_logo" value="{$vo.brand_logo|default=''}">
<script>$('[name=brand_logo]').uploadOneImage()</script>
</td>
<td class="text-top">
<input type="hidden" name="brand_cover" value="{$vo.brand_cover|default=''}">
<script>$('[name=brand_cover]').uploadOneImage()</script>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">品牌描述</label>
<div class='col-sm-8'>
<textarea placeholder="请输入品牌描述" title="请输入品牌描述" class="layui-textarea" name="brand_desc">{$vo.brand_desc|default=""}</textarea>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">品牌内容</label>
<div class='col-sm-8'>
<textarea name="brand_detail">{$vo.brand_detail|default=''|raw}</textarea>
</div>
</div>
<div class="hr-line-dashed"></div>
<div class="col-sm-7 col-sm-offset-2">
<div class="layui-form-item text-center">
{if !empty($vo.id)}<input type="hidden" name="id" value="{$vo.id}">{/if}
<button class="layui-btn" type="submit">保存配置</button>
<button class="layui-btn layui-btn-danger" type='button' onclick="window.history.back()">取消编辑</button>
</div>
</div>
<script>window.form.render();</script>
<script>
/*! 实例富文本编辑器 */
require(['ckeditor'], function () {
window.createEditor('[name="brand_detail"]', {height: 500});
});
</script>
<style>
.background-item {
padding: 15px;
background: #efefef;
}
.background-item thead tr {
background: #e0e0e0
}
</style>
</form>
{/block}

View File

@ -0,0 +1,108 @@
{extend name='admin@public/content'}
{block name="button"}
<!--{if auth("$classuri/add")}-->
<button data-open='{:url("$classuri/add")}' data-title="添加品牌" class='layui-btn layui-btn-sm layui-btn-primary'>添加品牌</button>
<!--{/if}-->
<!--{if auth("$classuri/del")}-->
<button data-update="" data-field='delete' data-action='{:url("$classuri/del")}' class='layui-btn layui-btn-sm layui-btn-primary'>删除品牌</button>
<!--{/if}-->
{/block}
{block name="content"}
<!-- 表单搜索 开始 -->
<form autocomplete="off" class="layui-form layui-form-pane form-search" action="{:request()->url()}" onsubmit="return false" method="get">
<div class="layui-form-item layui-inline">
<label class="layui-form-label">品牌名称</label>
<div class="layui-input-inline">
<input name="brand_title" value="{$Think.get.brand_title}" placeholder="请输入品牌名称" class="layui-input">
</div>
</div>
<div class="layui-form-item layui-inline">
<label class="layui-form-label">添加时间</label>
<div class="layui-input-inline">
<input name="create_at" id="create_at" value="{$Think.get.create_at}" placeholder="请选择添加时间" class="layui-input">
</div>
</div>
<div class="layui-form-item layui-inline">
<button class="layui-btn layui-btn-primary"><i class="layui-icon">&#xe615;</i> 搜 索</button>
</div>
</form>
<script>
window.laydate.render({range: true, elem: '#create_at'});
window.form.render();
</script>
<!-- 表单搜索 结束 -->
<form onsubmit="return false;" data-auto="true" method="post">
{if empty($list)}
<p class="help-block text-center well"> 哦!</p>
{else}
<input type="hidden" value="resort" name="action"/>
<table class="layui-table" lay-skin="line">
<thead>
<tr>
<th class='list-table-check-td think-checkbox'>
<input data-auto-none="none" data-check-target='.list-check-box' type='checkbox'/>
</th>
<th class='list-table-sort-td'>
<button type="submit" class="layui-btn layui-btn-normal layui-btn-xs"> </button>
</th>
<th class='text-left nowrap'>商品品牌</th>
<th class='text-left nowrap'>添加时间</th>
<th class='text-left nowrap'>品牌状态</th>
<th class='text-left'></th>
</tr>
</thead>
<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='list-table-sort-td'>
<input name="_{$vo.id}" value="{$vo.sort}" class="list-sort-input"/>
</td>
<td class='text-left nowrap'>{$vo.brand_title}</td>
<td class='text-left nowrap'>{$vo.create_at|format_datetime}</td>
<td class='text-left nowrap'>
{if $vo.status eq 0}<span class="color-red">已禁用</span>{elseif $vo.status eq 1}<span class="color-green">使用中</span>{/if}
</td>
<td class='text-left nowrap'>
{if auth("$classuri/edit")}
<span class="text-explode">|</span>
<a data-title="编辑品牌" data-open='{:url("$classuri/edit")}?id={$vo.id}'>编辑</a>
{/if}
{if $vo.status eq 1 and auth("$classuri/forbid")}
<span class="text-explode">|</span>
<a data-update="{$vo.id}" data-field='status' data-value='0' data-action='{:url("$classuri/forbid")}'>禁用</a>
{elseif auth("$classuri/resume")}
<span class="text-explode">|</span>
<a data-update="{$vo.id}" data-field='status' data-value='1' data-action='{:url("$classuri/resume")}'>启用</a>
{/if}
{if auth("$classuri/del")}
<span class="text-explode">|</span>
<a data-update="{$vo.id}" data-field='delete' data-action='{:url("$classuri/del")}'>删除</a>
{/if}
</td>
</tr>
{/foreach}
</tbody>
</table>
{if isset($page)}<p>{$page|raw}</p>{/if}
{/if}
</form>
{/block}

View File

@ -0,0 +1,39 @@
<form autocomplete="off" class="layui-form layui-box modal-form-box" action="{:request()->url()}" data-auto="true" method="post">
<div class="layui-form-item">
<label class="layui-form-label">商品主分类</label>
<div class="layui-input-block">
<select name='pid' class='layui-select full-width block'>
<!--{foreach cates as $cate}-->
<!--{eq name='cate.id' value='$vo.pid|default=0'}-->
<option selected value='{$cate.id}'>{$cate.spl|raw}{$cate.cate_title|default=''}</option>
<!--{else}-->
<option value='{$cate.id}'>{$cate.spl|raw}{$cate.cate_title}</option>
<!--{/eq}-->
<!--{/foreach}-->
</select>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">商品分类</label>
<div class="layui-input-block">
<input autofocus name="cate_title" value='{$vo.cate_title|default=""}' required title="请输入商品分类" placeholder="请输入商品分类" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">分类描述</label>
<div class="layui-input-block">
<textarea placeholder="请输入分类描述" title="请输入分类描述" class="layui-textarea" name="cate_desc">{$vo.cate_desc|default=""}</textarea>
</div>
</div>
<div class="hr-line-dashed"></div>
<div class="layui-form-item text-center">
{if isset($vo['id'])}<input type='hidden' value='{$vo.id}' name='id'/>{/if}
<button class="layui-btn" type='submit'>保存数据</button>
<button class="layui-btn layui-btn-danger" type='button' data-confirm="确定要取消编辑吗?" data-close>取消编辑</button>
</div>
</form>

View File

@ -0,0 +1,83 @@
{extend name='admin@public/content'}
{block name="button"}
<!--{if auth("$classuri/add")}-->
<button data-modal='{:url("@$classuri/add")}' data-title="添加分类" class='layui-btn layui-btn-sm layui-btn-primary'>添加分类</button>
<!--{/if}-->
<!--{if auth("$classuri/del")}-->
<button data-update="" data-field='delete' data-action='{:url("@$classuri/del")}' class='layui-btn layui-btn-sm layui-btn-primary'>删除分类</button>
<!--{/if}-->
{/block}
{block name="content"}
<form autocomplete="off" onsubmit="return false;" data-auto="true" method="post">
<!--{if empty($list)}-->
<p class="help-block text-center well"> 哦!</p>
<!--{else}-->
<input type="hidden" value="resort" name="action">
<table class="layui-table" lay-skin="line">
<thead>
<tr>
<th class='list-table-check-td think-checkbox'>
<input data-auto-none="none" data-check-target='.list-check-box' type='checkbox'>
</th>
<th class='list-table-sort-td'>
<button type="submit" class="layui-btn layui-btn-normal layui-btn-xs"> </button>
</th>
<th class='text-left nowrap'>商品分类</th>
<th class='text-left nowrap'>分类描述</th>
<th class='text-left nowrap'>添加时间</th>
<th class='text-center nowrap'>分类状态</th>
<th class='text-center'></th>
</tr>
</thead>
<tbody>
{foreach $list as $key=>$vo}
<tr>
<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 name="_{$vo.id}" value="{$vo.sort}" class="list-sort-input">
</td>
<td class='text-left nowrap'>
<span class="color-desc">{$vo.spl|raw}</span> {$vo.cate_title}
</td>
<td class='text-left nowrap'>
{$vo.cate_desc|default='<span class="color-desc">未设置分类描述</span>'|raw}
</td>
<td class='text-left nowrap'>
{$vo.create_at|format_datetime}
</td>
<td class='text-center nowrap'>
{if $vo.status eq 0}<span>已禁用</span>{elseif $vo.status eq 1}<span class="color-green">使用中</span>{/if}
</td>
<td class='text-center nowrap'>
{if auth("$classuri/edit")}
<span class="text-explode">|</span>
<a data-title="编辑分类" data-modal='{:url("@$classuri/edit")}?id={$vo.id}'>编辑</a>
{/if}
{if $vo.status eq 1 and auth("$classuri/forbid")}
<span class="text-explode">|</span>
<a data-update="{$vo.ids}" data-field='status' data-value='0' data-action='{:url("$classuri/forbid")}'>禁用</a>
{elseif auth("$classuri/resume")}
<span class="text-explode">|</span>
<a data-update="{$vo.ids}" data-field='status' data-value='1' data-action='{:url("$classuri/resume")}'>启用</a>
{/if}
{if auth("$classuri/del")}
<span class="text-explode">|</span>
<a data-update="{$vo.ids}" data-field='delete' data-action='{:url("$classuri/del")}'>删除</a>
{/if}
</td>
</tr>
{/foreach}
</tbody>
</table>
{if isset($page)}<p>{$page|raw}</p>{/if}
<!--{/if}-->
</form>
{/block}

View File

@ -0,0 +1,200 @@
<form autocomplete="off" class="layui-form layui-box" style='padding:25px 30px 20px 0' method="post" id="spec-form">
<div class="layui-form-item">
<label class="layui-form-label">规格名称</label>
<div class="layui-input-block">
<input name="spec_title" ng-model="spec_title" required title="请输入规格名称" placeholder="请输入规格名称" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label label-required">规格参数</label>
<div class="layui-input-block">
<textarea class="hide" ng-model="spec_param"></textarea>
<div class="param-table-list">
<table class="layui-table margin-none">
<tbody class="param-table-list">
<tr ng-repeat="x in paramList" class="transition">
<td class="param-input-td one nowrap">
<input required placeholder="分组" title="请输入属性分组" ng-model="x.name" class="layui-input">
</td>
<td class="param-input-td two nowrap">
<input required placeholder="名称" title="请输入属性名称" ng-model="x.value" class="layui-input">
</td>
<td class="param-input-td thr nowrap">
<a ng-if="$index<1" class="color-desc">删除</a>
<a ng-if="$index>0" ng-click="delParam($index)">删除</a>
<a ng-if="$index<1" class="color-desc">上移</a>
<a ng-if="$index>0" ng-click="moveToUp($index)">上移</a>
<a ng-if="$index+1<paramList.length" ng-click="moveToDn($index)">下移</a>
<a ng-if="$index+1>=paramList.length" class="color-desc">下移</a>
</td>
</tr>
</tbody>
</table>
</div>
<table class="layui-table">
<tr>
<td class="text-center notselect padding-none border-none">
<button type="button" class="layui-btn full-width layui-btn-primary" ng-click="addParam()">添加属性</button>
</td>
</tr>
</table>
<p class="help-block">设置多个内容值时请使用空格键或英文逗号隔开。</p>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">规格描述</label>
<div class="layui-input-block">
<textarea placeholder="请输入规格描述" title="请输入规格描述" class="layui-textarea" ng-model="spec_desc" name="spec_desc"></textarea>
</div>
</div>
<div class="hr-line-dashed"></div>
<div class="layui-form-item text-center">
{if isset($vo['id'])}<input type='hidden' value='{$vo.id}' name='id'/>{/if}
<button class="layui-btn" type='submit'>保存数据</button>
<button class="layui-btn layui-btn-danger" type='button' data-confirm="确定要取消编辑吗?" data-close>取消编辑</button>
</div>
<script>
require(['angular'], function () {
// 应用创建与初始化
var app = angular.module("SpecForm", []).run(callback);
angular.bootstrap(document.getElementById('spec-form'), [app.name]);
// 应用事件处理
function callback($rootScope) {
// 属性参数
$rootScope.paramList = filterParamList(JSON.parse('{$vo.spec_param|default="[]"|raw}') || []);
$rootScope.spec_title = '{$vo.spec_title|default=""}';
$rootScope.spec_desc = '{$vo.spec_desc|default=""}';
// 删除菜单
$rootScope.delParam = function (x) {
var dialogIndex = $.msg.confirm('确定移除参数吗?', function () {
$rootScope.$apply(function () {
var tmp = [];
for (var i in $rootScope.paramList) {
(parseInt(i) !== parseInt(x)) && tmp.push($rootScope.paramList[i]);
}
$rootScope.paramList = filterParamList(tmp);
$.msg.close(dialogIndex);
});
});
};
// 添加参数
$rootScope.addParam = function () {
$rootScope.paramList.push({name: '', value: ''});
setTimeout(function () {
$('.param-table-list').scrollTop('10000')
}, 10);
};
// 属性参数下移
$rootScope.moveToDn = function (index) {
var tmp = [], cur = $rootScope.paramList[index];
if (index > $rootScope.paramList.length - 2) {
return false;
}
for (var i in $rootScope.paramList) {
(parseInt(i) !== parseInt(index)) && tmp.push($rootScope.paramList[i]);
(parseInt(i) === parseInt(index) + 1) && tmp.push(cur);
}
$rootScope.paramList = tmp;
};
// 属性参数上移
$rootScope.moveToUp = function (index) {
var tmp = [], cur = $rootScope.paramList[index];
if (index < 1) {
return false;
}
for (var i in $rootScope.paramList) {
(parseInt(i) === parseInt(index) - 1) && tmp.push(cur);
(parseInt(i) !== parseInt(index)) && tmp.push($rootScope.paramList[i]);
}
$rootScope.paramList = tmp;
};
// 表单验证
$('#spec-form').vali(function (ret) {
try {
var spect_param = [];
for (var i in $rootScope.paramList) {
spect_param.push({
name: $rootScope.paramList[i].name,
value: $rootScope.paramList[i].value
});
}
var data = {
spec_title: $rootScope.spec_title || '',
spec_desc: $rootScope.spec_desc || '',
spec_param: JSON.stringify(spect_param)
};
var id = '{$vo.id|default=0}';
id > 0 && (data.id = id);
$.form.load('{:request()->url()}', data, 'post');
} catch ($e) {
console.log($e);
}
return false;
});
}
// 过滤规格参数列表
function filterParamList(list) {
return list.length < 1 ? [{name: '', value: ''}] : list;
}
});
</script>
<style>
.param-table-list {
overflow: auto;
max-height: 200px;
position: relative;
overflow-y: scroll;
}
.param-input-td {
position: relative;
padding: 0 !important;
}
.param-input-td.one {
width: 30%;
}
.param-input-td.thr {
width: 20%;
text-align: center;
}
.param-input-td.one:before {
content: '分组'
}
.param-input-td.two:before {
content: '规格'
}
.param-input-td:before {
margin: 4px;
width: 40px;
height: 30px;
line-height: 30px;
text-align: center;
position: absolute;
background: #e2e2e2;
}
.param-input-td input {
padding-left: 50px;
border: none !important;
}
</style>
</form>

View File

@ -0,0 +1,116 @@
{extend name='admin@public/content'}
{block name="button"}
<!--{if auth("$classuri/add")}-->
<button data-modal='{:url("$classuri/add")}' data-title="添加规格" class='layui-btn layui-btn-sm layui-btn-primary'>添加规格</button>
<!--{/if}-->
<!--{if auth("$classuri/del")}-->
<button data-update data-field='delete' data-action='{:url("$classuri/del")}' class='layui-btn layui-btn-sm layui-btn-primary'>删除规格</button>
<!--{/if}-->
{/block}
{block name="content"}
<!-- 表单搜索 开始 -->
<form autocomplete="off" class="layui-form layui-form-pane form-search" action="{:request()->url()}" onsubmit="return false" method="get">
<div class="layui-form-item layui-inline">
<label class="layui-form-label">规格分组</label>
<div class="layui-input-inline">
<input name="spec_title" value="{$Think.get.spec_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="date" id="range-date" value="{$Think.get.date}" placeholder="请选择添加时间" class="layui-input">
</div>
</div>
<div class="layui-form-item layui-inline">
<button class="layui-btn layui-btn-primary"><i class="layui-icon">&#xe615;</i> 搜 索</button>
</div>
</form>
<script>
window.laydate.render({range: true, elem: '#range-date'});
window.form.render();
</script>
<!-- 表单搜索 结束 -->
<form autocomplete="off" onsubmit="return false;" data-auto="true" method="post">
{if empty($list)}
<p class="help-block text-center well"> 哦!</p>
{else}
<input type="hidden" value="resort" name="action"/>
<table class="layui-table" lay-skin="line" lay-size="sm">
<thead>
<tr>
<th class='list-table-check-td think-checkbox'>
<input data-auto-none="none" data-check-target='.list-check-box' type='checkbox'/>
</th>
<th class='list-table-sort-td'>
<button type="submit" class="layui-btn layui-btn-normal layui-btn-xs"> </button>
</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'></th>
</tr>
</thead>
<tbody>
{foreach $list as $key=>$vo}
<tr>
<td class='list-table-check-td text-top think-checkbox'>
<input class="list-check-box" value='{$vo.id}' type='checkbox'/>
</td>
<td class='list-table-sort-td text-top'>
<input name="_{$vo.id}" value="{$vo.sort}" class="list-sort-input"/>
</td>
<td class='text-left text-top nowrap'>{$vo.spec_title}</td>
<td class='text-left text-top nowrap'>
{foreach $vo.spec_param as $param}
<p><b>{$param.name}</b> : {$param.value}</p>
{/foreach}
</td>
<td class='text-left text-top nowrap'>
{$vo.create_at|format_datetime|raw}
</td>
<td class='text-left text-top nowrap'>
{if $vo.status eq 0}<span class="color-red">已禁用</span>{elseif $vo.status eq 1}<span class="color-green">使用中</span>{/if}
</td>
<td class='text-left text-top nowrap'>
<!--{if auth("$classuri/edit")}-->
<span class="text-explode">|</span>
<a data-title="编辑规格" data-modal='{:url("$classuri/edit")}?id={$vo.id}'>编辑</a>
<!--{/if}-->
<!--{if $vo.status eq 1 and auth("$classuri/forbid")}-->
<span class="text-explode">|</span>
<a data-update="{$vo.id}" data-field='status' data-value='0' data-action='{:url("$classuri/forbid")}'>禁用</a>
<!--{elseif auth("$classuri/resume")}-->
<span class="text-explode">|</span>
<a data-update="{$vo.id}" data-field='status' data-value='1' data-action='{:url("$classuri/resume")}'>启用</a>
<!--{/if}-->
<!--{if auth("$classuri/del")}-->
<span class="text-explode">|</span>
<a data-update="{$vo.id}" data-field='delete' data-action='{:url("$classuri/del")}'>删除</a>
<!--{/if}-->
</td>
</tr>
{/foreach}
</tbody>
</table>
{if isset($page)}<p>{$page|raw}</p>{/if}
{/if}
</form>
{/block}

View File

@ -0,0 +1,60 @@
<form autocomplete="off" class="layui-form layui-box" style='padding:25px 30px 20px 0' action="{:request()->url()}" data-auto="true" method="post">
<div class="layui-form-item">
<label class="layui-form-label">收货人姓名</label>
<div class="layui-input-block">
<input class="layui-input" required placeholder="请输入收货人姓名" title="请输入收货人姓名" name="express_username" value="{$username}">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">收货人手机</label>
<div class="layui-input-block">
<input class="layui-input" pattern="^1\d{10}$" required placeholder="请输入收货人手机" title="请输入收货人手机" name="express_phone" value="{$phone}">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label label-required">收货省市区</label>
<div class="layui-input-block">
<div class="layui-col-xs4 padding-right-5">
<select name="form_express_province" class="layui-select block full-width" lay-ignore></select>
</div>
<div class="layui-col-xs4 padding-right-5">
<select name="form_express_city" class="layui-select block full-width" lay-ignore></select>
</div>
<div class="layui-col-xs4">
<select name="form_express_area" class="layui-select block full-width" lay-ignore></select>
</div>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">详细地址</label>
<div class="layui-input-block">
<textarea required placeholder="请输入详细地址" title="请输入详细地址" name="express_address" class="layui-textarea">{$address|default=""}</textarea>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">备注</label>
<div class="layui-input-block">
<textarea required placeholder="请输入备注" title="请输入备注" name="express_desc" class="layui-textarea">{$desc|default=""}</textarea>
</div>
</div>
<div class="hr-line-dashed"></div>
<div class="layui-form-item text-center">
{if isset($order_no)}<input type='hidden' value='{$order_no}' name='order_no'>{/if}
<button class="layui-btn" type='submit'>保存数据</button>
<button class="layui-btn layui-btn-danger" type='button' data-confirm="确定要取消编辑吗?" data-close>取消编辑</button>
</div>
<script>
require(['pcasunzips'], function () {
new PCAS('form_express_province', 'form_express_city', 'form_express_area', '{$province}', '{$city}', '{$area}');
});
</script>
</form>

View File

@ -0,0 +1,287 @@
{extend name='admin@public/content'}
{block name="content"}
<!-- 表单搜索 开始 -->
<form autocomplete="off" class="layui-form layui-form-pane form-search" action="{:request()->url()}" onsubmit="return false" method="get">
<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}" 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="nickname" value="{$Think.get.nickname}" 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="order_no" value="{$Think.get.order_no}" 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="status" class="layui-select">
<option value="">所有订单</option>
<!--{foreach ["已取消","待付款","待发货","已发货","已完成","已退单","退单审核中","退款处理中"] as $k=>$v}-->
{if $Think.get.status eq "$k"}
<option selected="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="goods_title" value="{$Think.get.goods_title}" placeholder="请输入商品名称" class="layui-input">
</div>
</div>
<div class="layui-form-item layui-inline">
<label class="layui-form-label">发货状态</label>
<div class="layui-input-inline">
<select name="send_status" class="layui-select">
<option value="">所有订单</option>
{foreach ['未发货','已发货'] as $k=>$v}
{if $Think.get.send_status eq "$k"}
<option selected="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 name="express_zero" class="layui-select">
<option value="">所有订单</option>
{if $Think.get.express_zero == '0'}
<option selected="selected" value="0">不包邮</option>
{else}
<option value="0">不包邮</option>
{/if}
{if $Think.get.express_zero eq 1}
<option selected="selected" value="1">包邮</option>
{else}
<option value="1">包邮</option>
{/if}
</select>
</div>
</div>
<div class="layui-form-item layui-inline">
<label class="layui-form-label">下单时间</label>
<div class="layui-input-inline">
<input name="create_at" data-time value="{$Think.get.create_at}" placeholder="请选择下单时间" class="layui-input">
</div>
</div>
<div class="layui-form-item layui-inline">
<label class="layui-form-label">支付时间</label>
<div class="layui-input-inline">
<input name="pay_at" data-time value="{$Think.get.pay_at}" placeholder="请选择支付时间间" class="layui-input">
</div>
</div>
<div class="layui-form-item layui-inline">
<label class="layui-form-label">订单描述</label>
<div class="layui-input-inline">
<input name="order_desc" value="{$Think.get.order_desc}" 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="company_title" value="{$Think.get.company_title}" placeholder="请输入物流公司" class="layui-input">
</div>
</div>
<div class="layui-form-item layui-inline">
<label class="layui-form-label">快递单号</label>
<div class="layui-input-inline">
<input name="send_no" value="{$Think.get.send_no}" 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="username" value="{$Think.get.username}" 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}" 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="province" value="{$Think.get.province}" 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="city" value="{$Think.get.city}" 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="area" value="{$Think.get.area}" 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="address" value="{$Think.get.address}" placeholder="请输入详细地址" class="layui-input">
</div>
</div>
<div class="layui-form-item layui-inline">
<button class="layui-btn layui-btn-primary"><i class="layui-icon">&#xe615;</i> 搜 索</button>
</div>
</form>
<script>
window.form.render();
$('[data-time]').map(function () {
window.laydate.render({range: true, elem: this});
});
</script>
<!-- 表单搜索 结束 -->
<form autocomplete="off" onsubmit="return false;" data-auto="true" method="post">
{if empty($list)}
<p class="help-block text-center well"> 哦!</p>
{else}
<table class="layui-table" lay-size="sm">
<thead>
<tr>
<th class='list-table-check-td think-checkbox'>
<input data-auto-none="none" data-check-target='.list-check-box' type='checkbox'/>
</th>
<th class="text-left">会员信息</th>
<th class="text-left">订单信息</th>
<th class="text-left nowrap padding-none">
<table class="layui-table think-inner-table">
<colgroup>
<col width="70%">
</colgroup>
<tr>
<td>商品信息</td>
<td class="text-right">
价格 <span class="layui-icon font-s12">&#x1006;</span> 数量
</td>
</tr>
</table>
</th>
<th class="text-left">发货信息</th>
</tr>
</thead>
<tbody>
{foreach $list as $key=>$vo}
<tr>
<td class='list-table-check-td text-top think-checkbox'>
<input class="list-check-box" value='{$vo.id}' type='checkbox'/>
</td>
<td class="text-left text-top nowrap">
会员昵称:{$vo.member.nickname|default='<span class="color-desc">未设置会员昵称</span>'|raw}<br>
会员手机:{$vo.member.phone|default='<span class="color-desc">未设置会员手机</span>'|raw}
</td>
<td class="text-left text-top nowrap">
订单单号:<b>{$vo.order_no}</b> {if $vo.type eq 3}<span class="layui-badge-rim">套餐</span> {/if}
{switch name='vo.status'}
{case value='0'}<span class="layui-badge layui-bg-gray">已取消</span>{/case}
{case value='1'}<span class="layui-badge layui-bg-black">待付款</span>{/case}
{case value='2'}<span class="layui-badge layui-bg-blue">待发货</span>{/case}
{case value='3'}<span class="layui-badge layui-bg-orange">已发货</span>{/case}
{case value='4'}<span class="layui-badge layui-bg-green">已完成</span>{/case}
{case value='5'}<span class="layui-badge layui-bg-gray">已退单</span>{/case}
{case value='6'}<span class="layui-badge layui-bg-red">退款审核中({if($vo.refund_type == 1)}退款申请{/if}{if($vo.refund_type == 2)}退货申请{/if}</span>
<span class="margin-left-5"><a data-title="退款审核" data-modal="{:url('order/checkRefund')}?order_no={$vo.order_no}&id={$vo.id}">审核</a></span>{/case}
{case value='7'}<span class="layui-badge layui-bg-rown">退款处理中</span>{/case}
{/switch}
<br>
</td>
<td class="text-left text-top nowrap padding-none">
<table class="layui-table think-inner-table">
<colgroup>
<col width="70%">
</colgroup>
{foreach $vo.goods as $goods}
<tr>
<td>[{$goods.goods_id}] {$goods.goods_title}{$goods.goods_spec_alias}</td>
<td class="text-right">
<b>
{if in_array($vo.type,['1','3'])}
{$goods[$goods['price_field']]}
{else}
{$goods.selling_integral} 积分
{/if}
<span class="layui-icon font-s12">&#x1006;</span>
{$goods.number}
</b>
</td>
</tr>
{/foreach}
</table>
</td>
<td class="text-left text-top nowrap">
{if empty($vo.express)}
<span class="color-desc">无发货信息</span>
{else}
快递公司:{$vo.express.real_company_title|default=$vo.express.company_title}
{if !empty($vo.express.real_company_title)}
<!--<span class="color-desc">{$vo.express.real_express_at|format_datetime|default='未发货'}</span>-->
{if $vo.express.real_company_title neq $vo.express.company_title}
<s class="color-desc">{$vo.express.company_title}</s>
{/if}
{/if}
<br>
快递单号:{$vo.express.real_express_no|default='<span class="layui-badge layui-bg-blue">未发货</span>'|raw}
<!--{if auth('store/deliver/tracking') and !empty($vo.express.real_express_no)}-->
<a data-modal="{:url('store/deliver/tracking')}?express_code={$vo.express.real_express_code}&express_no={$vo.express.real_express_no}&company_title={$vo.express.real_company_title}" data-title="追踪物流">查看</a>
<!--{elseif auth('store/deliver/express') and $vo.status eq 2 and $vo.is_pay eq 1}-->
<a data-title="快速发货" data-modal="{:url('store/deliver/express')}?order_no={$vo.order_no}">快速发货</a>
<!--{/if}-->
<br>
收货信息:{$vo.express.username} {$vo.express.phone}<br>
收货地址:{$vo.express.province}{$vo.express.city}{$vo.express.area}{$vo.express.address}
{if auth('store/order/address')}<a data-title="修改收货人信息" data-modal="{:url('order/address')}?order_no={$vo.order_no}">修改</a>{/if}
{/if}
{if !empty($vo.express.real_express_at)}<br>发货时间:{$vo.express.real_express_at|format_datetime}{/if}
</td>
</tr>
{/foreach}
</tbody>
</table>
{if isset($page)}<p>{$page|raw}</p>{/if}
{/if}
</form>
{/block}

View File

@ -1,254 +0,0 @@
<?php
// +----------------------------------------------------------------------
// | Think.Admin
// +----------------------------------------------------------------------
// | 版权所有 2014~2017 广州楚才信息科技有限公司 [ http://www.cuci.cc ]
// +----------------------------------------------------------------------
// | 官方网站: http://think.ctolog.com
// +----------------------------------------------------------------------
// | 开源协议 ( https://mit-license.org )
// +----------------------------------------------------------------------
// | github开源项目https://github.com/zoujingli/Think.Admin
// +----------------------------------------------------------------------
namespace app\wechat\controller;
use service\DataService;
use service\WechatService;
use think\Controller;
use think\Db;
use think\Log;
use Wechat\WechatReceive;
/**
* 微信接口控制器
* Class Api
* @package app\wechat\controller
* @author Anyon <zoujingli@qq.com>
*/
class Api extends Controller {
/**
* 微信openid
* @var string
*/
protected $openid;
/**
* 微信消息对象
* @var WechatReceive
*/
protected $wechat;
/**
* 微信消息接口
* @return string
*/
public function index() {
// 实例接口对象
$this->wechat = &load_wechat('Receive');
// 验证接口请求
if ($this->wechat->valid() === false) {
$msg = "{$this->wechat->errMsg}[{$this->wechat->errCode}]";
Log::error($msg);
return $msg;
}
// 获取消息来源用户OPENID
$this->openid = $this->wechat->getRev()->getRevFrom();
// 获取并同步粉丝信息到数据库
$this->_updateFansInfo(true);
// 分别执行对应类型的操作
switch ($this->wechat->getRev()->getRevType()) {
case WechatReceive::MSGTYPE_TEXT:
return $this->_keys("WechatKeys#keys#" . $this->wechat->getRevContent());
case WechatReceive::MSGTYPE_EVENT:
return $this->_event();
case WechatReceive::MSGTYPE_IMAGE:
return $this->_image();
case WechatReceive::MSGTYPE_LOCATION:
return $this->_location();
default:
return 'success';
}
}
/**
* 关键字处理
* @param string $keys
* @param bool $isForce
* @return string
*/
private function _keys($keys, $isForce = false) {
list($table, $field, $value) = explode('#', $keys . '##');
if (is_array($info = Db::name($table)->where($field, $value)->find()) && isset($info['type'])) {
// 数据状态检查
if (array_key_exists('status', $info) && empty($info['status'])) {
return 'success';
}
switch ($info['type']) {
case 'customservice': // 多客服
$this->wechat->sendCustomMessage(['touser' => $this->openid, 'msgtype' => 'text', 'text' => ['content' => $info['content']]]);
return $this->wechat->transfer_customer_service()->reply(false, true);
case 'keys': // 关键字
if (empty($info['content']) && empty($info['name'])) {
return 'success';
}
return $this->_keys('wechat_keys#keys#' . (empty($info['content']) ? $info['name'] : $info['content']));
case 'text': // 文本消息
if (empty($info['content']) && empty($info['name'])) {
return 'success';
}
return $this->wechat->text($info['content'])->reply(false, true);
case 'news': // 图文消息
if (empty($info['news_id'])) {
return 'success';
}
return $this->_news($info['news_id']);
case 'music': // 音频消息
if (empty($info['music_url']) || empty($info['music_title']) || empty($info['music_desc'])) {
return 'success';
}
$media_id = empty($info['music_image']) ? '' : WechatService::uploadForeverMedia($info['music_image'], 'image');
if (empty($media_id)) {
return 'success';
}
return $this->wechat->music($info['music_title'], $info['music_desc'], $info['music_url'], $info['music_url'], $media_id)->reply(false, true);
case 'voice': // 语音消息
if (empty($info['voice_url'])) {
return 'success';
}
$media_id = WechatService::uploadForeverMedia($info['voice_url'], 'voice');
if (empty($media_id)) {
return 'success';
}
return $this->wechat->voice($media_id)->reply(false, true);
case 'image': // 图文消息
if (empty($info['image_url'])) {
return 'success';
}
$media_id = WechatService::uploadForeverMedia($info['image_url'], 'image');
if (empty($media_id)) {
return 'success';
}
return $this->wechat->image($media_id)->reply(false, true);
case 'video': // 视频消息
if (empty($info['video_url']) || empty($info['video_desc']) || empty($info['video_title'])) {
return 'success';
}
$data = ['title' => $info['video_title'], 'introduction' => $info['video_desc']];
$media_id = WechatService::uploadForeverMedia($info['video_url'], 'video', true, $data);
return $this->wechat->video($media_id, $info['video_title'], $info['video_desc'])->reply(false, true);
}
}
if ($isForce) {
return 'success';
}
return $this->_keys('wechat_keys#keys#default', true);
}
/**
* 回复图文
* @param int $news_id
* @return bool|string
*/
protected function _news($news_id = 0) {
if (is_array($newsinfo = WechatService::getNewsById($news_id)) && !empty($newsinfo['articles'])) {
$newsdata = array();
foreach ($newsinfo['articles'] as $vo) {
$newsdata[] = [
'Title' => $vo['title'],
'Description' => $vo['digest'],
'PicUrl' => $vo['local_url'],
'Url' => url("@wechat/review", '', true, true) . "?content={$vo['id']}&type=article",
];
}
return $this->wechat->news($newsdata)->reply(false, true);
}
return 'success';
}
/**
* 事件处理
*/
protected function _event() {
$event = $this->wechat->getRevEvent();
switch (strtolower($event['event'])) {
case 'subscribe': // 粉丝关注事件
$this->_updateFansInfo(true);
$this->_spread($event['key']);
return $this->_keys('wechat_keys#keys#subscribe', true);
case 'unsubscribe':// 粉丝取消关注
$this->_updateFansInfo(false);
return 'success';
case 'click': // 点击菜单事件
return $this->_keys($event['key']);
case 'scancode_push':
case 'scancode_waitmsg': // 扫码推事件
$scanInfo = $this->wechat->getRev()->getRevScanInfo();
if (isset($scanInfo['ScanResult'])) {
return $this->_keys($scanInfo['ScanResult']);
}
return 'success';
case 'scan':
if (!empty($event['key'])) {
return $this->_spread($event['key']);
}
return 'success';
}
return 'success';
}
/**
* 推荐好友扫码关注
* @param string $event
* @return mixed
*/
private function _spread($event) {
$key = preg_replace('|^.*?(\d+).*?$|', '$1', "{$event}");
// 检测推荐是否有效
$fans = Db::name('WechatFans')->where('id', $key)->find();
if (!is_array($fans) || !isset($fans['openid']) || $fans['openid'] === $this->openid) {
return false;
}
// 标识推荐关系
$data = ['spread_by' => $fans['openid'], 'spread_at' => date('Y-m-d H:i:s')];
Db::name('WechatFans')->where("openid='{$this->openid}' and (spread_openid is null or spread_openid='')")->setField($data);
// @todo 推荐成功的奖励
}
/**
* 位置事情回复
* @return string
*/
private function _location() {
return 'success';
}
/**
* 图片事件处理
*/
private function _image() {
return 'success';
}
/**
* 同步粉丝状态
* @param bool $subscribe 关注状态
*/
protected function _updateFansInfo($subscribe = true) {
if ($subscribe) {
$fans = WechatService::getFansInfo($this->openid);
if (empty($fans) || empty($fans['subscribe'])) {
$wechat = &load_wechat('User');
$userInfo = $wechat->getUserInfo($this->openid);
$userInfo['subscribe'] = intval($subscribe);
WechatService::setFansInfo($userInfo, $wechat->appid);
}
} else {
$data = ['subscribe' => '0', 'appid' => $this->wechat->appid, 'openid' => $this->openid];
DataService::save('wechat_fans', $data, ['appid', 'openid']);
}
}
}

View File

@ -1,7 +1,7 @@
<?php
// +----------------------------------------------------------------------
// | Think.Admin
// | ThinkAdmin
// +----------------------------------------------------------------------
// | 版权所有 2014~2017 广州楚才信息科技有限公司 [ http://www.cuci.cc ]
// +----------------------------------------------------------------------
@ -9,16 +9,15 @@
// +----------------------------------------------------------------------
// | 开源协议 ( https://mit-license.org )
// +----------------------------------------------------------------------
// | github开源项目https://github.com/zoujingli/Think.Admin
// | github开源项目https://github.com/zoujingli/ThinkAdmin
// +----------------------------------------------------------------------
namespace app\wechat\controller;
use controller\BasicAdmin;
use service\DataService;
use service\LogService;
use service\PayService;
use think\response\View;
use service\WechatService;
use think\Exception;
/**
* 微信配置管理
@ -27,7 +26,8 @@ use think\response\View;
* @author Anyon <zoujingli@qq.com>
* @date 2017/03/27 14:43
*/
class Config extends BasicAdmin {
class Config extends BasicAdmin
{
/**
* 定义当前操作表名
@ -37,88 +37,56 @@ class Config extends BasicAdmin {
/**
* 微信基础参数配置
* @return View
* @return string
* @throws \think\Exception
* @throws \think\exception\PDOException
*/
public function index() {
public function index()
{
$thrNotifyUrl = url('@wechat/api.push', '', true, true);
if ($this->request->isGet()) {
$this->assign('title', '微信接口配置');
return view();
}
foreach ($this->request->post() as $key => $vo) {
sysconf($key, $vo);
}
LogService::write('微信管理', '修改微信接口参数成功');
$this->success('数据修改成功!', '');
}
/**
* 微信商户参数配置
* @return View
*/
public function pay() {
if ($this->request->isGet()) {
switch ($this->request->get('action')) {
// 生成测试支付二维码
case 'payqrc':
$pay = &load_wechat('pay');
// 生成订单号
$order_no = session('pay-test-order-no');
if (empty($order_no)) {
$order_no = DataService::createSequence(10, 'wechat-pay-test');
session('pay-test-order-no', $order_no);
}
// 该订单号已经支付
if (PayService::isPay($order_no)) {
return json(['code' => 2, 'order_no' => $order_no]);
}
// 订单号未支付生成支付二维码URL
$url = PayService::createWechatPayQrc($pay, $order_no, 1, '微信扫码支付测试!');
if ($url !== false) {
return json(['code' => 1, 'url' => $url, 'order_no' => $order_no]);
}
// 生成支付二维码URL失败
$this->error("生成支付二维码失败,{$pay->errMsg}[{$pay->errCode}]");
break;
// 微信支付退款操作
case 'refund':
$order_no = session('pay-test-order-no');
if (empty($order_no)) {
$this->error('测试订单号不存在,请重新开始支付测试!');
}
if (!PayService::isPay($order_no)) {
$this->error('测试订单未支付或未收到微信支付通过!');
}
$pay = &load_wechat('pay');
if (!file_exists($pay->ssl_cer) || !file_exists($pay->ssl_key)) {
$this->error('微信支付双向证书异常,无法完成退款操作!');
}
$refund_no = DataService::createSequence(10, 'wechat-pay-test');
if (false !== PayService::putWechatRefund($pay, $order_no, 1, $refund_no)) {
session('pay-test-order-no', null);
$this->success('测试退款操作成功,请查看微信通知!', '');
}
$this->error("操作退款失败,{$pay->errMsg}[{$pay->errCode}]");
break;
// 显示支付配置界面
default:
$this->assign('title', '微信支付配置');
return view();
$code = encode(url('@admin', '', true, true) . '#' . $this->request->url());
$data = [
'title' => '微信接口配置',
'appid' => $this->request->get('appid', sysconf('wechat_thr_appid')),
'appkey' => $this->request->get('appkey', sysconf('wechat_thr_appkey')),
'authurl' => config('wechat.service_url') . "/wechat/api.push/auth/{$code}.html",
];
if ($this->request->get('appid', false)) {
sysconf('wechat_thr_appid', $data['appid']);
sysconf('wechat_thr_appkey', $data['appkey']);
sysconf('wechat_type', 'thr');
WechatService::config()->setApiNotifyUri($thrNotifyUrl);
}
}
$data = $this->request->post();
foreach ($data as $key => $vo) {
if (in_array($key, ['wechat_cert_key_md5', 'wechat_cert_cert_md5']) && !empty($vo)) {
$filename = ROOT_PATH . 'static/upload/' . join('/', str_split($vo, 16)) . '.pem';
!file_exists($filename) && $this->error('支付双向证书上传失败,请重新上传!');
$data[str_replace('_md5', '', $key)] = $filename;
try {
$data['wechat'] = WechatService::config()->getConfig();
} catch (Exception $e) {
$data['wechat'] = [];
}
return $this->fetch('', $data);
}
unset($data['wechat_cert_key_md5'], $data['wechat_cert_cert_md5']);
foreach ($data as $key => $vo) {
DataService::save($this->table, ['name' => $key, 'value' => $vo], 'name');
try {
// 接口对接类型
sysconf('wechat_type', $this->request->post('wechat_type'));
// 直接参数对应
sysconf('wechat_token', $this->request->post('wechat_token'));
sysconf('wechat_appid', $this->request->post('wechat_appid'));
sysconf('wechat_appsecret', $this->request->post('wechat_appsecret'));
sysconf('wechat_encodingaeskey', $this->request->post('wechat_encodingaeskey'));
// 第三方平台配置
sysconf('wechat_thr_appid', $this->request->post('wechat_thr_appid'));
sysconf('wechat_thr_appkey', $this->request->post('wechat_thr_appkey'));
// 第三方平台时设置远程平台通知接口
if ($this->request->post('wechat_type') === 'thr') {
if (!WechatService::config()->setApiNotifyUri($thrNotifyUrl)) {
$this->error('远程服务端接口更新失败,请稍候再试!');
}
}
LogService::write('微信管理', '修改微信接口参数成功');
} catch (\Exception $e) {
$this->error('微信授权保存成功, 但授权验证失败 ! <br>' . $e->getMessage());
}
LogService::write('微信管理', '修改微信支付参数成功');
$this->success('数据修改成功!', '');
$this->success('微信授权数据修改成功!', url('@admin') . "#" . url('@wechat/config/index'));
}
}

View File

@ -1,7 +1,7 @@
<?php
// +----------------------------------------------------------------------
// | Think.Admin
// | ThinkAdmin
// +----------------------------------------------------------------------
// | 版权所有 2014~2017 广州楚才信息科技有限公司 [ http://www.cuci.cc ]
// +----------------------------------------------------------------------
@ -9,11 +9,13 @@
// +----------------------------------------------------------------------
// | 开源协议 ( https://mit-license.org )
// +----------------------------------------------------------------------
// | github开源项目https://github.com/zoujingli/Think.Admin
// | github开源项目https://github.com/zoujingli/ThinkAdmin
// +----------------------------------------------------------------------
namespace app\wechat\controller;
use app\wechat\service\FansService;
use app\wechat\service\TagsService;
use controller\BasicAdmin;
use service\LogService;
use service\ToolsService;
@ -27,7 +29,8 @@ use think\Db;
* @author Anyon <zoujingli@qq.com>
* @date 2017/03/27 14:43
*/
class Fans extends BasicAdmin {
class Fans extends BasicAdmin
{
/**
* 定义当前默认数据表
@ -38,32 +41,39 @@ class Fans extends BasicAdmin {
/**
* 显示粉丝列表
* @return array|string
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
* @throws \think\Exception
*/
public function index() {
public function index()
{
$this->title = '微信粉丝管理';
$db = Db::name($this->table)->where('is_back', '0')->order('subscribe_time desc');
$get = $this->request->get();
!empty($get['sex']) && $db->where('sex', $get['sex']);
$db = Db::name($this->table)->where(['is_black' => '0']);
(isset($get['sex']) && $get['sex'] !== '') && $db->where('sex', $get['sex']);
foreach (['nickname', 'country', 'province', 'city'] as $key) {
if (isset($get[$key]) && $get[$key] !== '') {
$db->where($key, 'like', "%{$get[$key]}%");
}
(isset($get[$key]) && $get[$key] !== '') && $db->whereLike($key, "%{$get[$key]}%");
}
if (isset($get['tag']) && $get['tag'] !== '') {
$db->where("concat(',',tagid_list,',') like :tag", ['tag' => "%,{$get['tag']},%"]);
}
return parent::_list($db);
if (isset($get['create_at']) && $get['create_at'] !== '') {
list($start, $end) = explode(' - ', $get['create_at']);
$db->whereBetween('subscribe_at', ["{$start} 00:00:00", "{$end} 23:59:59"]);
}
return parent::_list($db->order('subscribe_time desc'));
}
/**
* 列表数据处理
* @param type $list
* @param array $list
*/
protected function _data_filter(&$list) {
protected function _data_filter(&$list)
{
$tags = Db::name('WechatFansTags')->column('id,name');
foreach ($list as &$vo) {
$vo['nickname'] = ToolsService::emojiDecode($vo['nickname']);
$vo['tags_list'] = [];
list($vo['tags_list'], $vo['nickname']) = [[], ToolsService::emojiDecode($vo['nickname'])];
foreach (explode(',', $vo['tagid_list']) as $tag) {
if ($tag !== '' && isset($tags[$tag])) {
$vo['tags_list'][$tag] = $tags[$tag];
@ -75,108 +85,89 @@ class Fans extends BasicAdmin {
$this->assign('tags', $tags);
}
/**
* 黑名单列表
*/
public function back() {
$this->title = '微信粉丝黑名单管理';
$db = Db::name($this->table)->where('is_back', '1')->order('subscribe_time desc');
$get = $this->request->get();
!empty($get['sex']) && $db->where('sex', $get['sex']);
foreach (['nickname', 'country', 'province', 'city'] as $key) {
if (isset($get[$key]) && $get[$key] !== '') {
$db->where($key, 'like', "%{$get[$key]}%");
}
}
if (isset($get['tag']) && $get['tag'] !== '') {
$db->where("concat(',',tagid_list,',') like :tag", ['tag' => "%,{$get['tag']},%"]);
}
return parent::_list($db);
}
/**
* 设置黑名单
*/
public function backadd() {
$wechat = & load_wechat('User');
$openids = $this->_getActionOpenids();
if (false !== $wechat->addBacklist($openids)) {
Db::name($this->table)->where('openid', 'in', $openids)->setField('is_back', '1');
$this->success("已成功将 " . count($openids) . " 名粉丝移到黑名单!", '');
public function backadd()
{
try {
$openids = $this->_getActionOpenids();
WechatService::WeChatUser()->batchBlackList($openids);
Db::name($this->table)->whereIn('openid', $openids)->setField('is_black', '1');
} catch (\Exception $e) {
$this->error("设置黑名单失败,请稍候再试!");
}
$this->error("设备黑名单失败,请稍候再试!{$wechat->errMsg}[{$wechat->errCode}]");
$this->success('设置黑名单成功!', '');
}
/**
* 标签选择
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
public function tagset() {
public function tagset()
{
$tags = $this->request->post('tags', '');
$fans_id = $this->request->post('fans_id', '');
$fans = Db::name('WechatFans')->where('id', $fans_id)->find();
$fans = Db::name('WechatFans')->where(['id' => $fans_id])->find();
empty($fans) && $this->error('需要操作的数据不存在!');
$wechat = & load_wechat('User');
foreach (explode(',', $fans['tagid_list']) as $tagid) {
is_numeric($tagid) && $wechat->batchDeleteUserTag($tagid, [$fans['openid']]);
try {
$wechat = WechatService::WeChatTags();
foreach (explode(',', $fans['tagid_list']) as $tagid) {
is_numeric($tagid) && $wechat->batchUntagging([$fans['openid']], $tagid);
}
foreach (explode(',', $tags) as $tagid) {
is_numeric($tagid) && $wechat->batchTagging([$fans['openid']], $tagid);
}
Db::name('WechatFans')->where(['id' => $fans_id])->setField('tagid_list', $tags);
} catch (\Exception $e) {
$this->error('粉丝标签设置失败, 请稍候再试!');
}
foreach (explode(',', $tags) as $tagid) {
is_numeric($tagid) && $wechat->batchAddUserTag($tagid, [$fans['openid']]);
}
if (false !== Db::name('WechatFans')->where('id', $fans_id)->setField('tagid_list', $tags)) {
$this->success('粉丝标签成功!', '');
}
$this->error('粉丝标签设置失败, 请稍候再试!');
}
/**
* 取消黑名
*/
public function backdel() {
$wechat = & load_wechat('User');
$openids = $this->_getActionOpenids();
if (false !== $wechat->delBacklist($openids)) {
Db::name($this->table)->where('openid', 'in', $openids)->setField('is_back', '0');
$this->success("已成功将 " . count($openids) . " 名粉丝从黑名单中移除!", '');
}
$this->error("设备黑名单失败,请稍候再试!{$wechat->errMsg}[{$wechat->errCode}]");
$this->success('粉丝标签成功!', '');
}
/**
* 给粉丝增加标签
*/
public function tagadd() {
public function tagadd()
{
$tagid = $this->request->post('tag_id', 0);
empty($tagid) && $this->error('没有可能操作的标签ID');
$openids = $this->_getActionOpenids();
$wechat = & load_wechat('User');
if (false !== $wechat->batchAddUserTag($tagid, $openids)) {
$this->success('设置粉丝标签成功!', '');
try {
$openids = $this->_getActionOpenids();
WechatService::WeChatTags()->batchTagging($openids, $tagid);
} catch (\Exception $e) {
$this->error("设置粉丝标签失败, 请稍候再试! " . $e->getMessage());
}
$this->error("设置粉丝标签失败, 请稍候再试! {$wechat->errMsg}[{$wechat->errCode}]");
$this->success('设置粉丝标签成功!', '');
}
/**
* 移除粉丝标签
*/
public function tagdel() {
public function tagdel()
{
$tagid = $this->request->post('tag_id', 0);
empty($tagid) && $this->error('没有可能操作的标签ID');
$openids = $this->_getActionOpenids();
$wechat = & load_wechat('User');
if (false !== $wechat->batchDeleteUserTag($tagid, $openids)) {
$this->success('删除粉丝标签成功!', '');
try {
$openids = $this->_getActionOpenids();
WechatService::WeChatTags()->batchUntagging($openids, $tagid);
} catch (\Exception $e) {
$this->error("删除粉丝标签失败, 请稍候再试! ");
}
$this->error("删除粉丝标签失败, 请稍候再试! {$wechat->errMsg}[{$wechat->errCode}]");
$this->success('删除粉丝标签成功!', '');
}
/**
* 获取当前操作用户openid数组
* @return array
*/
private function _getActionOpenids() {
private function _getActionOpenids()
{
$ids = $this->request->post('id', '');
empty($ids) && $this->error('没有需要操作的数据!');
$openids = Db::name($this->table)->where('id', 'in', explode(',', $ids))->column('openid');
$openids = Db::name($this->table)->whereIn('id', explode(',', $ids))->column('openid');
empty($openids) && $this->error('没有需要操作的数据!');
return $openids;
}
@ -184,14 +175,16 @@ class Fans extends BasicAdmin {
/**
* 同步粉丝列表
*/
public function sync() {
Db::name($this->table)->where('1=1')->delete();
if (WechatService::syncAllFans('')) {
WechatService::syncBlackFans('');
public function sync()
{
try {
Db::name($this->table)->where('1=1')->delete();
[FansService::sync(), TagsService::sync()];
LogService::write('微信管理', '同步全部微信粉丝成功');
$this->success('同步获取所有粉丝成功!', '');
} catch (\Exception $e) {
$this->error('同步粉丝记录失败,请稍候再试!' . $e->getMessage());
}
$this->error('同步获取粉丝失败,请稍候再试!');
$this->success('同步获取所有粉丝成功!', '');
}
}

View File

@ -0,0 +1,113 @@
<?php
// +----------------------------------------------------------------------
// | ThinkAdmin
// +----------------------------------------------------------------------
// | 版权所有 2014~2017 广州楚才信息科技有限公司 [ http://www.cuci.cc ]
// +----------------------------------------------------------------------
// | 官方网站: http://think.ctolog.com
// +----------------------------------------------------------------------
// | 开源协议 ( https://mit-license.org )
// +----------------------------------------------------------------------
// | github开源项目https://github.com/zoujingli/ThinkAdmin
// +----------------------------------------------------------------------
namespace app\wechat\controller;
use controller\BasicAdmin;
use service\ToolsService;
use service\WechatService;
use think\Db;
/**
* 微信粉丝管理
* Class Block
* @package app\wechat\controller
* @author Anyon <zoujingli@qq.com>
* @date 2017/03/27 14:43
*/
class FansBlock extends BasicAdmin
{
/**
* 定义当前默认数据表
* @var string
*/
public $table = 'WechatFans';
/**
* 黑名单列表
* @return array|string
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
* @throws \think\Exception
*/
public function index()
{
$this->title = '微信黑名单管理';
$get = $this->request->get();
$db = Db::name($this->table)->where(['is_black' => '1']);
(isset($get['sex']) && $get['sex'] !== '') && $db->where('sex', $get['sex']);
foreach (['nickname', 'country', 'province', 'city'] as $key) {
(isset($get[$key]) && $get[$key] !== '') && $db->whereLike($key, "%{$get[$key]}%");
}
if (isset($get['tag']) && $get['tag'] !== '') {
$db->where("concat(',',tagid_list,',') like :tag", ['tag' => "%,{$get['tag']},%"]);
}
if (isset($get['create_at']) && $get['create_at'] !== '') {
list($start, $end) = explode(' - ', $get['create_at']);
$db->whereBetween('subscribe_at', ["{$start} 00:00:00", "{$end} 23:59:59"]);
}
return parent::_list($db->order('subscribe_time desc'));
}
/**
* 列表数据处理
* @param array $list
*/
protected function _data_filter(&$list)
{
$tags = Db::name('WechatFansTags')->column('id,name');
foreach ($list as &$vo) {
list($vo['tags_list'], $vo['nickname']) = [[], ToolsService::emojiDecode($vo['nickname'])];
foreach (explode(',', $vo['tagid_list']) as $tag) {
if ($tag !== '' && isset($tags[$tag])) {
$vo['tags_list'][$tag] = $tags[$tag];
} elseif ($tag !== '') {
$vo['tags_list'][$tag] = $tag;
}
}
}
$this->assign('tags', $tags);
}
/**
* 取消黑名
*/
public function backdel()
{
$openids = $this->_getActionOpenids();
try {
WechatService::WeChatUser()->batchUnblackList($openids);
Db::name($this->table)->whereIn('openid', $openids)->setField('is_black', '0');
} catch (\Exception $e) {
$this->error("设备黑名单失败,请稍候再试!" . $e->getMessage());
}
$this->success("已成功将 " . count($openids) . " 名粉丝从黑名单中移除!", '');
}
/**
* 获取当前操作用户openid数组
* @return array
*/
private function _getActionOpenids()
{
$ids = $this->request->post('id', '');
empty($ids) && $this->error('没有需要操作的数据!');
$openids = Db::name($this->table)->whereIn('id', explode(',', $ids))->column('openid');
empty($openids) && $this->error('没有需要操作的数据!');
return $openids;
}
}

View File

@ -1,6 +1,7 @@
<?php
// +----------------------------------------------------------------------
// | Think.Admin
// | ThinkAdmin
// +----------------------------------------------------------------------
// | 版权所有 2014~2017 广州楚才信息科技有限公司 [ http://www.cuci.cc ]
// +----------------------------------------------------------------------
@ -8,23 +9,25 @@
// +----------------------------------------------------------------------
// | 开源协议 ( https://mit-license.org )
// +----------------------------------------------------------------------
// | github开源项目https://github.com/zoujingli/Think.Admin
// | github开源项目https://github.com/zoujingli/ThinkAdmin
// +----------------------------------------------------------------------
namespace app\wechat\controller;
use controller\BasicAdmin;
use service\DataService;
use service\WechatService;
use think\Db;
/**
* 微信文章管理
* Class Article
* Class Keys
* @package app\wechat\controller
* @author Anyon <zoujingli@qq.com>
* @date 2017/03/27 14:43
*/
class Keys extends BasicAdmin {
class Keys extends BasicAdmin
{
/**
* 指定当前数据表
@ -34,29 +37,58 @@ class Keys extends BasicAdmin {
/**
* 显示关键字列表
* @return array|string
* @throws \WeChat\Exceptions\InvalidResponseException
* @throws \WeChat\Exceptions\LocalCacheException
* @throws \think\Exception
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
public function index() {
$this->assign('title', '微信关键字');
$db = Db::name($this->table)->where('keys', 'not in', ['subscribe', 'default']);
return $this->_list($db);
public function index()
{
// 关键字二维码显示
if ($this->request->get('action') === 'qrc') {
$wechat = WechatService::WeChatQrcode();
$result = $wechat->create($this->request->get('keys', ''));
$this->redirect($wechat->url($result['ticket']));
}
// 显示关键字列表
$this->title = '微信关键字管理';
$db = Db::name($this->table)->whereNotIn('keys', ['subscribe', 'default']);
return $this->_list($db->order('sort asc,id desc'));
}
/**
* 列表数据处理
* @param array $data
*/
protected function _index_data_filter(&$data) {
$types = ['keys' => '关键字', 'image' => '图片', 'news' => '图文', 'music' => '音乐', 'text' => '文字', 'video' => '视频', 'voice' => '语音'];
foreach ($data as &$vo) {
$vo['type'] = isset($types[$vo['type']]) ? $types[$vo['type']] : $vo['type'];
protected function _index_data_filter(&$data)
{
try {
$types = [
'keys' => '关键字', 'image' => '图片', 'news' => '图文',
'music' => '音乐', 'text' => '文字', 'video' => '视频', 'voice' => '语音',
];
foreach ($data as &$vo) {
$vo['qrc'] = url('@wechat/keys/index') . "?action=qrc&keys={$vo['keys']}";
$vo['type'] = isset($types[$vo['type']]) ? $types[$vo['type']] : $vo['type'];
}
} catch (\Exception $e) {
$this->error($e->getMessage());
}
}
/**
* 添加关键字
* @return string
* @throws \think\Exception
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
public function add() {
public function add()
{
$this->title = '添加关键字规则';
return $this->_form($this->table, 'form');
}
@ -64,40 +96,38 @@ class Keys extends BasicAdmin {
/**
* 编辑关键字
* @return string
* @throws \think\Exception
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
public function edit() {
public function edit()
{
$this->title = '编辑关键字规则';
return $this->_form($this->table, 'form');
}
/**
* 表单处理
* @param $data
*/
protected function _form_filter($data) {
if ($this->request->isPost() && isset($data['keys'])) {
$db = Db::name($this->table)->where('keys', $data['keys']);
!empty($data['id']) && $db->where('id', 'neq', $data['id']);
$db->count() > 0 && $this->error('关键字已经存在,请使用其它关键字!');
}
}
/**
* 删除关键字
* @throws \think\Exception
* @throws \think\exception\PDOException
*/
public function del() {
public function del()
{
if (DataService::update($this->table)) {
$this->success("关键字删除成功!", '');
}
$this->error("关键字删除失败,请稍候再试!");
}
/**
* 关键字禁用
* @throws \think\Exception
* @throws \think\exception\PDOException
*/
public function forbid() {
public function forbid()
{
if (DataService::update($this->table)) {
$this->success("关键字禁用成功!", '');
}
@ -106,8 +136,11 @@ class Keys extends BasicAdmin {
/**
* 关键字禁用
* @throws \think\Exception
* @throws \think\exception\PDOException
*/
public function resume() {
public function resume()
{
if (DataService::update($this->table)) {
$this->success("关键字启用成功!", '');
}
@ -116,41 +149,60 @@ class Keys extends BasicAdmin {
/**
* 关注默认回复
* @return array|string
* @throws \think\Exception
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
public function subscribe() {
public function subscribe()
{
$this->assign('title', '编辑默认回复');
return $this->_form($this->table, 'form');
}
/**
* 关注默认回复表单处理
* @param $data
*/
protected function _subscribe_form_filter(&$data) {
if ($this->request->isGet()) {
$data = Db::name($this->table)->where('keys', 'subscribe')->find();
}
$data['keys'] = 'subscribe';
return $this->_form($this->table, 'form', 'keys', [], ['keys' => 'subscribe']);
}
/**
* 无配置默认回复
* @return array|string
* @throws \think\Exception
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
public function defaults() {
public function defaults()
{
$this->assign('title', '编辑无配置默认回复');
return $this->_form($this->table, 'form');
return $this->_form($this->table, 'form', 'keys', [], ['keys' => 'default']);
}
/**
* 无配置默认回复表单处理
* @param $data
* 添加数据处理
* @param array $data
*/
protected function _defaults_form_filter(&$data) {
if ($this->request->isGet()) {
$data = Db::name($this->table)->where('keys', 'default')->find();
protected function _form_filter(array &$data)
{
if ($this->request->isPost() && isset($data['keys'])) {
$db = Db::name($this->table)->where('keys', $data['keys']);
!empty($data['id']) && $db->where('id', 'neq', $data['id']);
$db->count() > 0 && $this->error('关键字已经存在,请使用其它关键字!');
}
$data['keys'] = 'default';
}
/**
* 编辑结果处理
* @param $result
*/
protected function _form_result($result)
{
if ($result !== false) {
list($url, $keys) = ['', $this->request->post('keys')];
if (!in_array($keys, ['subscribe', 'default'])) {
$url = url('@admin') . '#' . url('wechat/keys/index') . '?spm=' . $this->request->get('spm');
}
$this->success('恭喜, 关键字保存成功!', $url);
}
$this->error('关键字保存失败, 请稍候再试!');
}
}

View File

@ -1,7 +1,7 @@
<?php
// +----------------------------------------------------------------------
// | Think.Admin
// | ThinkAdmin
// +----------------------------------------------------------------------
// | 版权所有 2014~2017 广州楚才信息科技有限公司 [ http://www.cuci.cc ]
// +----------------------------------------------------------------------
@ -9,7 +9,7 @@
// +----------------------------------------------------------------------
// | 开源协议 ( https://mit-license.org )
// +----------------------------------------------------------------------
// | github开源项目https://github.com/zoujingli/Think.Admin
// | github开源项目https://github.com/zoujingli/ThinkAdmin
// +----------------------------------------------------------------------
namespace app\wechat\controller;
@ -17,6 +17,7 @@ namespace app\wechat\controller;
use controller\BasicAdmin;
use service\LogService;
use service\ToolsService;
use service\WechatService;
use think\Db;
/**
@ -26,7 +27,8 @@ use think\Db;
* @author Anyon <zoujingli@qq.com>
* @date 2017/03/27 14:43
*/
class Menu extends BasicAdmin {
class Menu extends BasicAdmin
{
/**
* 指定当前页面标题
@ -44,7 +46,7 @@ class Menu extends BasicAdmin {
* 微信菜单的类型
* @var array
*/
protected $menu_type = array(
protected $menuType = [
'view' => '跳转URL',
'click' => '点击推事件',
'scancode_push' => '扫码推事件',
@ -53,12 +55,18 @@ class Menu extends BasicAdmin {
'pic_photo_or_album' => '弹出拍照或者相册发图',
'pic_weixin' => '弹出微信相册发图器',
'location_select' => '弹出地理位置选择器',
);
];
/**
* 显示列表操作
* 显示菜单列表
* @return array|string
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
* @throws \think\Exception
*/
public function index() {
public function index()
{
return parent::_list(Db::name($this->table), false, true);
}
@ -66,78 +74,91 @@ class Menu extends BasicAdmin {
* 列表数据处理
* @param array $data
*/
protected function _index_data_filter(&$data) {
protected function _index_data_filter(&$data)
{
$data = ToolsService::arr2tree($data, 'index', 'pindex');
}
/**
* 微信菜单编辑
*/
public function edit() {
public function edit()
{
if ($this->request->isPost()) {
$post = $this->request->post();
!isset($post['data']) && $this->error('访问出错,请稍候再试!');
$data = $post['data'];
if (empty($data)) {
Db::name($this->table)->where('1=1')->delete();
load_wechat('Menu')->deleteMenu();
// 删除菜单
if (empty($post['data'])) {
try {
Db::name($this->table)->where('1=1')->delete();
WechatService::WeChatMenu()->delete();
} catch (\Exception $e) {
$this->error('删除取消微信菜单失败,请稍候再试!' . $e->getMessage());
}
$this->success('删除并取消微信菜单成功!', '');
}
foreach ($data as &$vo) {
if (isset($vo['content'])) {
$vo['content'] = str_replace('"', "'", $vo['content']);
// 数据过滤处理
try {
foreach ($post['data'] as &$vo) {
isset($vo['content']) && ($vo['content'] = str_replace('"', "'", $vo['content']));
}
Db::transaction(function () use ($post) {
Db::name($this->table)->where('1=1')->delete();
Db::name($this->table)->insertAll($post['data']);
});
$this->_push();
} catch (\Exception $e) {
$this->error('微信菜单发布失败,请稍候再试!' . $e->getMessage());
}
if (Db::name($this->table)->where('1=1')->delete() !== false && Db::name($this->table)->insertAll($data) !== false) {
$result = $this->_push();
if ($result['status']) {
LogService::write('微信管理', '发布微信菜单成功');
$this->success('保存发布菜单成功!', '');
}
$this->error('菜单发布失败,' . $result['errmsg']);
}
$this->error('保存发布菜单失败!');
LogService::write('微信管理', '发布微信菜单成功');
$this->success('保存发布菜单成功!', '');
}
}
/**
* 取消菜单
*/
public function cancel() {
$wehcat = &load_wechat('Menu');
if (false !== $wehcat->deleteMenu()) {
$this->success('菜单取消成功,重新关注可立即生效!', '');
public function cancel()
{
try {
WechatService::WeChatMenu()->delete();
} catch (\Exception $e) {
$this->error('菜单取消失败');
}
$this->error('菜单取消失败,' . $wehcat->errMsg);
$this->success('菜单取消成功,重新关注可立即生效!', '');
}
/**
* 菜单推送
* @throws \WeChat\Exceptions\InvalidResponseException
* @throws \WeChat\Exceptions\LocalCacheException
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
protected function _push() {
$result = Db::name($this->table)
->field('id,index,pindex,name,type,content')
->where('status', '1')
->order('sort ASC,id ASC')
->select();
private function _push()
{
list($map, $field) = [['status' => '1'], 'id,index,pindex,name,type,content'];
$result = (array)Db::name($this->table)->field($field)->where($map)->order('sort ASC,id ASC')->select();
foreach ($result as &$row) {
empty($row['content']) && $row['content'] = uniqid();
switch ($row['type']) {
case 'view':
$row['url'] = preg_match('#^(\w+:)?//#i', $row['content']) ? $row['content'] : url($row['content'], '', true, true);
break;
case 'event':
if (isset($this->menu_type[$row['content']])) {
$row['type'] = $row['content'];
$row['key'] = "wechat_menu#id#{$row['id']}";
}
break;
case 'media_id':
$row['media_id'] = $row['content'];
break;
default :
(!in_array($row['type'], $this->menu_type)) && $row['type'] = 'click';
$row['key'] = "wechat_menu#id#{$row['id']}";
if ($row['type'] === 'miniprogram') {
list($row['appid'], $row['url'], $row['pagepath']) = explode(',', "{$row['content']},,");
} elseif ($row['type'] === 'view') {
if (preg_match('#^(\w+:)?//#', $row['content'])) {
$row['url'] = $row['content'];
} else {
$row['url'] = url($row['content'], '', true, true);
}
} elseif ($row['type'] === 'event') {
if (isset($this->menuType[$row['content']])) {
list($row['type'], $row['key']) = [$row['content'], "wechat_menu#id#{$row['id']}"];
}
} elseif ($row['type'] === 'media_id') {
$row['media_id'] = $row['content'];
} else {
$row['key'] = "wechat_menu#id#{$row['id']}";
!in_array($row['type'], $this->menuType) && $row['type'] = 'click';
}
unset($row['content']);
}
@ -153,11 +174,7 @@ class Menu extends BasicAdmin {
}
unset($menu['type']);
}
$wechat = &load_wechat('Menu');
if (false !== $wechat->createMenu(['button' => $menus])) {
return array('status' => true, 'errmsg' => '');
}
return array('status' => false, 'errmsg' => $wechat->errMsg);
WechatService::WeChatMenu()->create(['button' => $menus]);
}
}

View File

@ -1,7 +1,7 @@
<?php
// +----------------------------------------------------------------------
// | Think.Admin
// | ThinkAdmin
// +----------------------------------------------------------------------
// | 版权所有 2014~2017 广州楚才信息科技有限公司 [ http://www.cuci.cc ]
// +----------------------------------------------------------------------
@ -9,18 +9,19 @@
// +----------------------------------------------------------------------
// | 开源协议 ( https://mit-license.org )
// +----------------------------------------------------------------------
// | github开源项目https://github.com/zoujingli/Think.Admin
// | github开源项目https://github.com/zoujingli/ThinkAdmin
// +----------------------------------------------------------------------
namespace app\wechat\controller;
use app\wechat\service\MediaService;
use controller\BasicAdmin;
use service\DataService;
use service\LogService;
use service\ToolsService;
use service\WechatService;
use think\Db;
use think\Log;
use think\response\View;
use think\facade\Log;
/**
* 微信图文管理
@ -29,7 +30,8 @@ use think\response\View;
* @author Anyon <zoujingli@qq.com>
* @date 2017/03/27 14:43
*/
class News extends BasicAdmin {
class News extends BasicAdmin
{
/**
* 设置默认操作表
@ -39,65 +41,93 @@ class News extends BasicAdmin {
/**
* 图文列表
* @return array|string
* @throws \think\Exception
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
public function index() {
$this->assign('title', '图文列表');
$db = Db::name($this->table)->where('is_deleted', '0')->order('id desc');
return parent::_list($db);
public function index()
{
$this->title = '微信图文列表';
$db = Db::name($this->table)->where(['is_deleted' => '0']);
return parent::_list($db->order('id desc'));
}
/**
* 图文列表数据处理
* @param array $data
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
protected function _index_data_filter(&$data)
{
foreach ($data as &$vo) {
$vo = MediaService::getNewsById($vo['id']);
}
}
/**
* 图文选择器
* @return string
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
* @throws \think\Exception
*/
public function select() {
public function select()
{
return $this->index();
}
/**
* 图文列表数据处理
* @param array $data
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
protected function _select_data_filter(&$data)
{
foreach ($data as &$vo) {
$vo = MediaService::getNewsById($vo['id']);
}
}
/**
* 媒体资源显示
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
* @throws \think\Exception
*/
public function image() {
public function image()
{
$_GET['rows'] = 18;
$this->assign('field', $this->request->get('field', 'local_url'));
return $this->_list(Db::name('WechatNewsMedia')->where('type', 'image'));
}
/**
* 图文列表数据处理
* @param $data
*/
protected function _index_data_filter(&$data) {
foreach ($data as &$vo) {
$vo = WechatService::getNewsById($vo['id']);
}
}
/**
* 图文列表数据处理
* @param $data
*/
protected function _select_data_filter(&$data) {
foreach ($data as &$vo) {
$vo = WechatService::getNewsById($vo['id']);
}
}
/**
* 添加图文
* @return View
* @return string
* @throws \think\Exception
* @throws \think\exception\PDOException
*/
public function add() {
public function add()
{
if ($this->request->isGet()) {
return view('form', ['title' => '新建图文']);
return $this->fetch('form', ['title' => '新建图文']);
}
if ($this->request->isPost()) {
$data = $this->request->post();
if (($ids = $this->_apply_news_article($data['data'])) && !empty($ids)) {
$post = ['article_id' => $ids, 'create_by' => session('user.id')];
if (DataService::save($this->table, $post, 'id') !== false) {
$this->success('图文添加成功!', '');
$url = url('@admin') . '#' . url('@wechat/news/index') . '?spm=' . $this->request->get('spm');
$this->success('图文添加成功!', $url);
}
}
$this->error('图文添加失败,请稍候再试!');
@ -106,20 +136,27 @@ class News extends BasicAdmin {
/**
* 编辑图文
* @return View
* @return string
* @throws \think\Exception
* @throws \think\exception\PDOException
*/
public function edit() {
public function edit()
{
$id = $this->request->get('id', '');
if ($this->request->isGet()) {
empty($id) && $this->error('参数错误,请稍候再试!');
return view('form', ['title' => '编辑图文', 'vo' => WechatService::getNewsById($id)]);
if ($this->request->get('output') === 'json') {
ToolsService::success('获取数据成功', MediaService::getNewsById($id));
}
return $this->fetch('form', ['title' => '编辑图文']);
}
$data = $this->request->post();
$ids = $this->_apply_news_article($data['data']);
if (!empty($ids)) {
$post = ['id' => $id, 'article_id' => $ids, 'create_by' => session('user.id')];
if (false !== DataService::save('wechat_news', $post, 'id')) {
$this->success('图文更新成功!', '');
$url = url('@admin') . '#' . url('@wechat/news/index') . '?spm=' . $this->request->get('spm');
$this->success('图文更新成功!', $url);
}
}
$this->error('图文更新失败,请稍候再试!');
@ -130,19 +167,24 @@ class News extends BasicAdmin {
* @param array $data
* @param array $ids
* @return string
* @throws \think\Exception
* @throws \think\exception\PDOException
*/
protected function _apply_news_article($data, $ids = []) {
protected function _apply_news_article($data, $ids = [])
{
foreach ($data as &$vo) {
$vo['create_by'] = session('user.id');
$vo['create_at'] = date('Y-m-d H:i:s');
$vo['digest'] = empty($vo['digest']) ? mb_substr(strip_tags(str_replace(["\s", ' '], '', $vo['content'])), 0, 120) : $vo['digest'];
if (empty($vo['digest'])) {
$vo['digest'] = mb_substr(strip_tags(str_replace(["\s", ' '], '', $vo['content'])), 0, 120);
}
if (empty($vo['id'])) {
$result = $id = Db::name('WechatNewsArticle')->insertGetId($vo);
} else {
$id = intval($vo['id']);
$result = Db::name('WechatNewsArticle')->where('id', $id)->update($vo);
}
if ($result !== FALSE) {
if ($result !== false) {
$ids[] = $id;
}
}
@ -151,8 +193,11 @@ class News extends BasicAdmin {
/**
* 删除用户
* @throws \think\Exception
* @throws \think\exception\PDOException
*/
public function del() {
public function del()
{
if (DataService::update($this->table)) {
$this->success("图文删除成功!", '');
}
@ -161,32 +206,40 @@ class News extends BasicAdmin {
/**
* 推荐图文
* @return array|void
* @return array
* @throws \WeChat\Exceptions\InvalidResponseException
* @throws \WeChat\Exceptions\LocalCacheException
* @throws \think\Exception
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
* @throws \think\exception\PDOException
*/
public function push() {
public function push()
{
# 获取将要推送的粉丝列表
switch (strtolower($this->request->get('action', ''))) {
case 'getuser':
if ('' === ($params = $this->request->post('group', ''))) {
return ['code' => 'SUCCESS', 'data' => []];
}
$ids = explode(',', $params);
$db = Db::name('WechatFans');
list($ids, $db) = [explode(',', $params), Db::name('WechatFans')];
!in_array('0', $ids) && $db->where("concat(',',tagid_list,',') REGEXP '," . join(',|,', $ids) . ",'");
return ['code' => "SUCCESS", 'data' => $db->where('subscribe', '1')->limit(200)->column('nickname')];
$list = $db->where(['subscribe' => '1'])->limit(200)->column('nickname');
foreach ($list as &$vo) {
$vo = ToolsService::emojiDecode($vo);
}
return ['code' => "SUCCESS", 'data' => $list];
default :
$news_id = $this->request->get('id', '');
// 显示及图文
$newsinfo = WechatService::getNewsById($news_id);
$newsinfo = MediaService::getNewsById($news_id);
// Get 请求,显示选择器界面
if ($this->request->isGet()) {
$fans_tags = Db::name('WechatFansTags')->select();
array_unshift($fans_tags, [
'id' => 0,
'name' => '全部',
'count' => Db::name('WechatFans')->where('subscribe', '1')->count(),
]);
return view('push', ['vo' => $newsinfo, 'fans_tags' => $fans_tags]);
$fans_tags = (array)Db::name('WechatFansTags')->select();
$count = Db::name('WechatFans')->where(['subscribe' => '1'])->count();
array_unshift($fans_tags, ['id' => 0, 'name' => '全部', 'count' => $count]);
return $this->fetch('push', ['vo' => $newsinfo, 'fans_tags' => $fans_tags]);
}
// Post 请求,执行图文推送操作
$post = $this->request->post();
@ -204,38 +257,42 @@ class News extends BasicAdmin {
$data['filter'] = ['is_to_all' => false, 'tag_id' => join(',', $post['fans_tags'])];
$data['mpnews'] = ['media_id' => $newsinfo['media_id']];
}
$wechat = &load_wechat('Receive');
if (FALSE !== $wechat->sendGroupMassMessage($data)) {
if (WechatService::WeChatCustom()->massSendAll($data)) {
LogService::write('微信管理', "图文[{$news_id}]推送成功");
$this->success('微信图文推送成功!', '');
}
$this->error("微信图文推送失败{$wechat->errMsg} [{$wechat->errCode}]");
$this->error("微信图文推送失败");
}
}
/**
* 上传永久图文
* @param type $newsinfo
* @return boolean
* @param array $news
* @return bool
* @throws \WeChat\Exceptions\InvalidResponseException
* @throws \WeChat\Exceptions\LocalCacheException
* @throws \think\Exception
* @throws \think\exception\PDOException
*/
private function _uploadWechatNews(&$newsinfo) {
foreach ($newsinfo['articles'] as &$article) {
$article['thumb_media_id'] = WechatService::uploadForeverMedia($article['local_url']);
private function _uploadWechatNews(&$news)
{
foreach ($news['articles'] as &$article) {
$article['thumb_media_id'] = MediaService::uploadForeverMedia($article['local_url']);
$article['content'] = preg_replace_callback("/<img(.*?)src=['\"](.*?)['\"](.*?)\/?>/i", function ($matches) {
$src = WechatService::uploadImage($matches[2]);
$src = MediaService::uploadImage($matches[2]);
return "<img{$matches[1]}src=\"{$src}\"{$matches[3]}/>";
}, htmlspecialchars_decode($article['content']));
}, $article['content']);
}
$wechat = & load_wechat('media');
$wechat = WechatService::WeChatMedia();
// 如果已经上传过,先删除之前的历史记录
!empty($newsinfo['media_id']) && $wechat->delForeverMedia($newsinfo['media_id']);
!empty($news['media_id']) && $wechat->delMaterial($news['media_id']);
// 上传图文到微信服务器
$result = $wechat->uploadForeverArticles(['articles' => $newsinfo['articles']]);
$result = $wechat->addNews(['articles' => $news['articles']]);
if (isset($result['media_id'])) {
$newsinfo['media_id'] = $result['media_id'];
return Db::name('WechatNews')->where('id', $newsinfo['id'])->setField('media_id', $result['media_id']);
$news['media_id'] = $result['media_id'];
return Db::name('WechatNews')->where(['id' => $news['id']])->update(['media_id' => $result['media_id']]);
}
Log::error("上传永久图文失败, {$wechat->errMsg}[{$wechat->errCode}]");
Log::error("上传永久图文失败");
return false;
}

View File

@ -1,66 +0,0 @@
<?php
// +----------------------------------------------------------------------
// | Think.Admin
// +----------------------------------------------------------------------
// | 版权所有 2014~2017 广州楚才信息科技有限公司 [ http://www.cuci.cc ]
// +----------------------------------------------------------------------
// | 官方网站: http://think.ctolog.com
// +----------------------------------------------------------------------
// | 开源协议 ( https://mit-license.org )
// +----------------------------------------------------------------------
// | github开源项目https://github.com/zoujingli/Think.Admin
// +----------------------------------------------------------------------
namespace app\wechat\controller;
use think\Controller;
use think\Db;
use think\Log;
/**
* 微信支付通知处理控制器
* Class Notify
* @package app\wechat\controller
* @author Anyon <zoujingli@qq.com>
* @date 2017/04/05 14:02
*/
class Notify extends Controller {
public function index() {
// 实例支付接口
$pay = &load_wechat('Pay');
// 获取支付通知
$notifyInfo = $pay->getNotify();
// 支付通知数据获取失败
if ($notifyInfo === FALSE) {
// 接口失败的处理
Log::error("微信支付通知消息验证失败,{$pay->errCode}[{$pay->errCode}]");
return $pay->errMsg;
} else {
//支付通知数据获取成功
if ($notifyInfo['result_code'] == 'SUCCESS' && $notifyInfo['return_code'] == 'SUCCESS') {
// 记录支付通知数据
if(!Db::name('WechatPayNotify')->insert($notifyInfo)){
$pay->replyXml(['return_code' => 'ERROR', 'return_msg' => '系统记录微信通知时发生异常!']);
}
$prepayMap = ['out_trade_no' => $notifyInfo['out_trade_no']];
$prepayData = Db::name('WechatPayPrepayid')->where($prepayMap)->find();
if (empty($prepayData)) {
$pay->replyXml(['return_code' => 'ERROR', 'return_msg' => '系统中未发现对应的预支付记录!']);
}
$prepayUpdateData = ['transaction_id' => $notifyInfo['transaction_id'], 'is_pay' => 1, 'pay_at' => date('Y-m-d H:i:s')];
if (false === Db::name('WechatPayPrepayid')->where($prepayMap)->update($prepayUpdateData)) {
$pay->replyXml(['return_code' => 'ERROR', 'return_msg' => '更新系统预支付记录失败!']);
}
// 支付状态完全成功,可以更新订单的支付状态了
// @todo 这里去完成你的订单状态修改操作
// 回复xmlreplyXml方法是终态方法
$pay->replyXml(['return_code' => 'SUCCESS', 'return_msg' => '系统业务处理成功!']);
}
}
}
}

View File

@ -1,7 +1,7 @@
<?php
// +----------------------------------------------------------------------
// | Think.Admin
// | ThinkAdmin
// +----------------------------------------------------------------------
// | 版权所有 2014~2017 广州楚才信息科技有限公司 [ http://www.cuci.cc ]
// +----------------------------------------------------------------------
@ -9,54 +9,52 @@
// +----------------------------------------------------------------------
// | 开源协议 ( https://mit-license.org )
// +----------------------------------------------------------------------
// | github开源项目https://github.com/zoujingli/Think.Admin
// | github开源项目https://github.com/zoujingli/ThinkAdmin
// +----------------------------------------------------------------------
namespace app\wechat\controller;
use service\FileService;
use service\WechatService;
use app\wechat\service\MediaService;
use think\Controller;
use think\Db;
class Review extends Controller {
/**
* 微信素材预览
* Class Review
* @package app\wechat\controller
*/
class Review extends Controller
{
/**
* 显示手机预览
* @return string
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
public function index() {
$get = $this->request->get();
$content = str_replace("\n", "<br>", $this->request->get('content', '')); // 内容
public function index()
{
$content = str_replace("\n", "<br>", $this->request->get('content', '', 'urldecode')); // 内容
$type = $this->request->get('type', 'text'); // 类型
$this->assign('type', $type);
// 图文处理
if ($type === 'news' && is_numeric($content) && !empty($content)) {
$news = WechatService::getNewsById($content);
$news = MediaService::getNewsById($content);
$this->assign('articles', $news['articles']);
}
// 文章预览
if ($type === 'article' && is_numeric($content) && !empty($content)) {
$article = Db::name('WechatNewsArticle')->where('id', $content)->find();
if (!empty($article['content_source_url'])) {
$this->redirect($article['content_source_url']);
}
$this->assign('vo', $article);
}
$this->assign($get);
$this->assign('type', $type);
$this->assign('content', $content);
$this->assign($this->request->get());
// 渲染模板并显示
return view();
}
/**
* 微信图片显示
*/
public function img() {
$url = $this->request->get('url', '');
$filename = FileService::getFileName($url, 'jpg', 'tmp/');
if (false === ($img = FileService::getFileUrl($filename))) {
$info = FileService::save($filename, file_get_contents($url));
$img = (is_array($info) && isset($info['url'])) ? $info['url'] : $url;
}
$this->redirect($img);
return $this->fetch();
}
}

View File

@ -1,7 +1,7 @@
<?php
// +----------------------------------------------------------------------
// | Think.Admin
// | ThinkAdmin
// +----------------------------------------------------------------------
// | 版权所有 2014~2017 广州楚才信息科技有限公司 [ http://www.cuci.cc ]
// +----------------------------------------------------------------------
@ -9,11 +9,12 @@
// +----------------------------------------------------------------------
// | 开源协议 ( https://mit-license.org )
// +----------------------------------------------------------------------
// | github开源项目https://github.com/zoujingli/Think.Admin
// | github开源项目https://github.com/zoujingli/ThinkAdmin
// +----------------------------------------------------------------------
namespace app\wechat\controller;
use app\wechat\service\TagsService;
use controller\BasicAdmin;
use service\DataService;
use service\LogService;
@ -24,10 +25,9 @@ use think\Db;
* 微信粉丝标签管理
* Class Tags
* @package app\wechat\controller
* @author Anyon <zoujingli@qq.com>
* @date 2017/03/27 14:43
*/
class Tags extends BasicAdmin {
class Tags extends BasicAdmin
{
/**
* 定义当前默认数据表
@ -38,69 +38,118 @@ class Tags extends BasicAdmin {
/**
* 显示粉丝标签列表
* @return array|string
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
* @throws \think\Exception
*/
public function index() {
public function index()
{
$this->title = '微信粉丝标签管理';
$get = $this->request->get();
$db = Db::name($this->table)->order('id asc');
list($get, $db) = [$this->request->get(), Db::name($this->table)];
foreach (['name'] as $key) {
if (isset($get[$key]) && $get[$key] !== '') {
$db->where($key, 'like', "%{$get[$key]}%");
}
(isset($get[$key]) && $get[$key] !== '') && $db->whereLike($key, "%{$get[$key]}%");
}
return parent::_list($db);
return parent::_list($db->order('id asc'));
}
/**
* 添加粉丝标签
* @return array|string
* @throws \WeChat\Exceptions\InvalidResponseException
* @throws \WeChat\Exceptions\LocalCacheException
* @throws \think\Exception
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
* @throws \think\exception\PDOException
*/
public function add() {
public function add()
{
if ($this->request->isGet()) {
return parent::_form($this->table, 'form', 'id');
}
$name = $this->request->post('name', '');
empty($name) && $this->error('粉丝标签名不能为空!');
(Db::name($this->table)->where('name', $name)->count() > 0) && $this->error('粉丝标签标签名已经存在, 请使用其它标签名!');
$wechat = & load_wechat('User');
if (Db::name($this->table)->where('name', $name)->count() > 0) {
$this->error('粉丝标签标签名已经存在, 请使用其它标签名!');
}
$wechat = WechatService::WeChatTags();
if (false === ($result = $wechat->createTags($name)) && isset($result['tag'])) {
$this->error("添加粉丝标签失败. {$wechat->errMsg}[{$wechat->errCode}]");
$this->error("添加粉丝标签失败. ");
}
$result['tag']['count'] = 0;
DataService::save($this->table, $result['tag'], 'id') && $this->success('添加粉丝标签成功!', '');
if (DataService::save($this->table, $result['tag'], 'id')) {
$this->success('添加粉丝标签成功!', '');
}
$this->error('粉丝标签添加失败, 请稍候再试!');
}
/**
* 编辑粉丝标签
* @return array|string
* @throws \think\Exception
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
public function edit() {
public function edit()
{
// 显示编辑界面
if ($this->request->isGet()) {
return parent::_form($this->table, 'form', 'id');
}
// 接收提交的数据
list($name, $id) = [$this->request->post('name', ''), $this->request->post('id', '0')];
$info = Db::name($this->table)->where('name', $name)->find();
$id = $this->request->post('id', '0');
$name = $this->request->post('name', '');
$info = Db::name($this->table)->where(['name' => $name])->find();
if (!empty($info)) {
if (intval($info['id']) === intval($id)) {
$this->error('粉丝标签名没有改变, 无需修改!');
}
$this->error('标签已经存在, 使用其它名称再试!');
}
$wechat = &load_wechat('User');
$data = ['id' => $id, 'name' => $name];
if (false !== $wechat->updateTag($id, $name) && false !== DataService::save($this->table, $data, 'id')) {
$this->success('编辑标签成功!', '');
try {
WechatService::WeChatTags()->updateTags($id, $name);
DataService::save($this->table, ['id' => $id, 'name' => $name], 'id');
} catch (\Exception $e) {
$this->error('编辑标签失败, 请稍后再试!' . $e->getMessage());
}
$this->error('编辑标签失败, 请稍后再试!' . $wechat->errMsg);
$this->success('编辑标签成功!', '');
}
/**
* 删除粉丝标签
* @throws \WeChat\Exceptions\InvalidResponseException
* @throws \WeChat\Exceptions\LocalCacheException
* @throws \think\Exception
* @throws \think\exception\PDOException
*/
public function del()
{
$wechat = WechatService::WeChatTags();
foreach (explode(',', $this->request->post('id', '')) as $id) {
if ($wechat->deleteTags($id)) {
Db::name('WechatFansTags')->where(['id' => $id])->delete();
} else {
$this->error('移除粉丝标签失败,请稍候再试!');
}
}
$this->success('移除粉丝标签成功!', '');
}
/**
* 同步粉丝标签列表
* @throws \WeChat\Exceptions\InvalidResponseException
* @throws \WeChat\Exceptions\LocalCacheException
* @throws \think\Exception
* @throws \think\exception\PDOException
*/
public function sync() {
public function sync()
{
Db::name($this->table)->where('1=1')->delete();
if (WechatService::syncFansTags()) {
if (TagsService::sync()) {
LogService::write('微信管理', '同步全部微信粉丝标签成功');
$this->success('同步获取所有粉丝标签成功!', '');
}

View File

@ -0,0 +1,50 @@
<?php
// +----------------------------------------------------------------------
// | ThinkAdmin
// +----------------------------------------------------------------------
// | 版权所有 2014~2017 广州楚才信息科技有限公司 [ http://www.cuci.cc ]
// +----------------------------------------------------------------------
// | 官方网站: http://think.ctolog.com
// +----------------------------------------------------------------------
// | 开源协议 ( https://mit-license.org )
// +----------------------------------------------------------------------
// | github开源项目https://github.com/zoujingli/ThinkAdmin
// +----------------------------------------------------------------------
namespace app\wechat\controller\api;
use service\WechatService;
use think\facade\Response;
/**
* 公众号页面支持
* Class Script
* @package app\wechat\controller\api
*/
class Js
{
/**
* jsSign签名
* @return mixed
* @throws \WeChat\Exceptions\InvalidResponseException
* @throws \WeChat\Exceptions\LocalCacheException
* @throws \think\Exception
* @throws \think\exception\PDOException
*/
public function index()
{
$result = app('request');
$url = $result->server('HTTP_REFERER', $result->url(true), null);
$wechat = WechatService::webOauth($url, $result->get('mode', 1), false);
$assign = [
'jssdk' => WechatService::webJsSDK($url),
'openid' => $wechat['openid'], 'fansinfo' => $wechat['fansinfo'],
];
return Response::create(env('APP_PATH') . 'wechat/view/api/script/index.js', 'view', 200, [
'Content-Type' => 'application/x-javascript',
'Cache-Control' => 'no-cache', 'Pragma' => 'no-cache', 'Expires' => '0',
])->assign($assign);
}
}

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