提交 9f532056 编写于 作者: S sugar1569

Initial commit

上级

要显示的变更太多。

To preserve performance only 1000 of 1000+ files are displayed.
此差异已折叠。
<p align="center">
<img src="https://images.gitee.com/uploads/images/2018/1214/151026_2299df23_892944.gif" />
</p>
<h1 align="center"> CRMEB客户管理+电商营销系统</h1>
<p align="center">
<a href="http://www.crmeb.com">
<img src="https://img.shields.io/badge/OfficialWebsite-CRMEB-yellow.svg" />
</a>
<a href="http://www.crmeb.com">
<img src="https://img.shields.io/badge/Licence-GPL3.0-green.svg?style=flat" />
</a>
<a href="http://www.crmeb.com">
<img src="https://img.shields.io/badge/Edition-3.1-blue.svg" />
</a>
<a href="https://gitee.com/ZhongBangKeJi/CRMEB/repository/archive/master.zip">
<img src="https://img.shields.io/badge/download-80m-red.svg" />
</a>
</p>
<p align="center">
<b>如果对您有帮助,您可以点右上角 "Star" 支持一下 谢谢!</b>
</p>
## 项目介绍
码云开源项目php语言排名第一的开源GVP项目,感谢码云提供的平台!
CRMEB系统就是集客户关系管理+营销电商系统,能够快速积累客户、会员数据分析、智能转化客户、有效提高销售、会员维护、网络营销的一款企业应用,包含商城、拼团、砍价、秒杀、优惠券、积分、分销等功能。
系统采用TP6+Vue+Layui+Mysql核心技术,系统功能介绍[<a href="http://help.crmeb.net/crmeb_30/1345181">查看</a>],十几个开发交流群,专业售后技术团队,让您二开无忧。
有着详细文档地址:http://help.crmeb.net/crmeb_30
<p align="center">
<a href="http://bbs.crmeb.net/forum.php?mod=viewthread&tid=4864&page=1&extra=#pid42012" target="_blank" >
<img src="https://images.gitee.com/uploads/images/2020/1103/161801_46bb022b_1491977.png" />
</a>
</p>
<p align="center">
<b>CRMEB赋能开发者,提速企业数字化。</b>
<br/>
## QQ群
会员群全部加满,请加客服微信,会员专属微信群
CRMEB会员群(156535570)已满
CRMEB会员2群(68808391)已满
CRMEB会员5群(609480511)已满
CRMEB会员8群(1030955182)已满
CRMEB会员9群(633569634)已满
CRMEB微信开发群(116279623)2000人已满
CRMEB微信开发3群(69741389)2000人已满
CRMEB微信开发4群(710729856)2000人已满
CRMEB微信开发6群(341864990)2000人已满
CRMEB微信开发10群(862316758)3000人群可加
CRMEB微信开发11群(824195682)2000人群可加
CRMEB微信开发12群(1025263163)2000人群可加
CRMEB官方二开交流群(943955364)2000人群可加
## 导航栏目
[前端下载](/readme/前端下载地址.md)
| [使用手册](https://help.crmeb.net)
| [安装说明](/readme/安装说明.md)
| [论坛地址](http://bbs.crmeb.net)
| [官网地址](https://www.crmeb.com)
| [TP6开发手册](https://www.kancloud.cn/manual/thinkphp6_0/content)
| [服务器](https://promotion.aliyun.com/ntms/yunparter/invite.html?userCode=dligum2z)
| [授权价格](http://crmeb.com/web/index/price.html)
- - -
## 相关项目
公众号前端:https://gitee.com/ZhongBangKeJi/CRMEB-H5
微信小程序前端:https://gitee.com/ZhongBangKeJi/CRMEB_WechatApplet
不要再说假开源了,公众号、小程序、H5前端代码都开源着
JAVA版商城:https://gitee.com/ZhongBangKeJi/crmeb_java
感谢大家对CRMEB的支持,为了感谢java开发者对CRMEB的支持,特别推出CRMEB java版
知识付费:https://gitee.com/ZhongBangKeJi/crmeb_zzff_class
CRMEB知识付费系统是基于ThinkPhp5.0+Vue开发的一套新零售直播/点播知识付费系统,CRMEB系统就是集分销推广关系管理+营销+直播的知识类电商系统,能够快速积累客户、会员数据分析、智能转化客户、 有效提高销售、吸引流量、网络营销、品牌推广的一款应用,且更适合企业二次开发;
form-builder : https://github.com/xaboy/form-builder
tp PHP表单生成器,快速生成现代化的form表单。包含复选框、单选框、输入框、下拉选择框等元素以及,省市区三级联动,时间选择,日期选择,颜色选择,文件/图片上传等功能。
## 系统演示
![前端演示](https://images.gitee.com/uploads/images/2020/1103/161837_52d08017_1491977.png "屏幕截图.png")
开源演示站: http://demo32.crmeb.net/admin 账号:demo 密码:crmeb.com
## 推荐服务器
阿里云领取2000元代金劵:[<a href="https://promotion.aliyun.com/ntms/yunparter/invite.html?userCode=dligum2z">https://www.aliyun.com</a>]
<table><tr><td>
入门级配置
```
CPU:1核
内存:1G
实例规格:突发性能t5实例
带宽:1M
系统:CentOS 7.4 64位(推荐)
价格:366元/年 933.3元/三年
```
<a href="https://promotion.aliyun.com/ntms/yunparter/invite.html?userCode=dligum2z">学生9.5/月</a>
</td>
<td>
标准级配置
```
CPU:2核
内存:4G
实例规格:突发性能t5实例
带宽:2M
系统:CentOS 7.4 64位(推荐)
价格:936元/年 2386.8元/三年
```
<a href="https://promotion.aliyun.com/ntms/yunparter/invite.html?userCode=dligum2z">新用户半价</a>
</td>
<td>
企业级配置
```
CPU:4核
内存:8G
实例规格:突发性能t6实例
带宽:5M
系统:CentOS 7.4 64位(推荐)
价格:2786.64元/年 5389.20元/三年
```
<a href="https://promotion.aliyun.com/ntms/yunparter/invite.html?userCode=dligum2z">领取¥2000红包</a>
</td>
</tr></table>
## 技术亮点
~~~
1.后台应用form-builder PHP快速生成现代化表单;
2.前端以Vue + RequireJS模块化开发;
3.PHPExcel数据导出,导出表格更加美观,可视;
4.EasyWeChat部署微信开发,微信接入更加快捷,简单;
5.后台应用ECharts实现完善的数据统计和分析;
6.内部预留事件钩子,方面用户二次开发;
7.后台多任务窗口化操作界面;
8.内置强大灵活的权限管理;
9.内置组合数据,系统配置,管理碎片化数据;
10.客户端完善的交互效果和动画;
11.对接公众号和小程序,并且数据同步;
12.内置客服系统;
13.高频数据缓存;
14.数据备份和恢复;
15.后台文件管理,带代码高亮,无需开发工具在线编辑代码;
16.标准接口、前后端分离,二次开发更方便;
17.长连接减少CPU及内存使用及网络堵塞,减少请求响应时长;
18.无缝事件机制行为扩展更方便,方便二次开发;
19.支持队列降低流量高峰,解除耦合,高可用;
16.一键安装自动检查系统环境一键安装;
~~~
## 系统功能
![系统功能](/readme/images/系统功能.jpg)
## 页面展示
![展示图](/readme/images/展示图_01.jpg "展示图.png")
![展示图](/readme/images/展示图_02.jpg "展示图.png")
![展示图](/readme/images/展示图_03.jpg "展示图.png")
![后台首页](/readme/images/后台首页.png "后台首页.png")
![后台产品管理](/readme/images/后台产品管理.png "后台产品管理.png")
![后台订单管理](/readme/images/后台订单管理.png "后台订单管理.png")
![后台订单统计](/readme/images/后台订单统计.png "后台订单统计.png")
![后台公众号菜单管理](/readme/images/后台公众号菜单管理.png "后台公众号菜单管理.png")
![后台财务报表](/readme/images/后台财务报表.png "后台财务报表.png")
![后台用户统计](/readme/images/后台用户统计.png "后台用户统计.png")
![后台权限管理](/readme/images/后台权限管理.png "后台权限管理.png")
![后台数据备份](/readme/images/后台数据备份.png "后台数据备份.png")
![后台文件管理](/readme/images/后台文件管理.png "后台文件管理.png")
## 获得荣誉
![输入图片说明](https://images.gitee.com/uploads/images/2019/0805/111208_eb4fe823_892944.jpeg "WechatIMG2434.jpeg")
## 商业版
<p align="center">
<b>商业版与开源版区别</b>
</p>
![系统功能](/readme/images/商业版对比.jpg)
扫描公众号二维码,回复“4.0体验”免费下载商业版源码
商业版演示站后台: http://demo.crmeb.net/admin 账号:demo 密码:crmeb.com
<b>去了解商业版 <a href='https://s.click.taobao.com/W7hVkLw' target="_blank"> 支持一下 </a></b>
## 联系我们
![有问题?联系CRMEB官方客服]![输入图片说明](https://images.gitee.com/uploads/images/2020/1103/190941_dd6acebb_892944.jpeg "客服二维码.jpg")
:satisfied: 微信扫码联系客服,发送“体验”,获取商业版源码免费体验,赶紧来体验吧! :wink:
官方网站:http://www.crmeb.com
## 参与开发
请提交 [CRMEB](https://gitee.com/ZhongBangKeJi/CRMEB/pulls)
开源版使用须知
1.允许用于个人学习、毕业设计、教学案例、公益事业;
2.如果商用必须保留版权信息,请自觉遵守;
3.禁止将本项目的代码和资源进行任何形式的出售,产生的一切任何后果责任由侵权者自负。
## 版权信息
本项目包含的第三方源码和二进制文件之版权信息另行标注。
版权所有Copyright © 2017-2020 by CRMEB (http://www.crmeb.com)
All rights reserved。
CRMEB® 商标和著作权所有者为西安众邦网络科技有限公司。
<?php
define('INSTALL_DATE',1578360044);
define('SERIALNUMBER','N2L6Px');
\ No newline at end of file
APP_DEBUG = true [APP] DEFAULT_TIMEZONE = Asia/Shanghai [DATABASE] TYPE = mysql HOSTNAME = 127.0.0.1 DATABASE = test USERNAME = username PASSWORD = password HOSTPORT = 3306 CHARSET = utf8 DEBUG = true [LANG] default_lang = zh-cn
\ No newline at end of file
/.idea
/.vscode
*.log
/.env
**/*.pid
runtime/
install.lock
public/uploads
public/nginx.htaccess
public/index.html
public/live-logo.gif
<IfModule mod_rewrite.c>
Options +FollowSymlinks -Multiviews
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php/$1 [QSA,PT,L]
</IfModule>
sudo: false
language: php
branches:
only:
- stable
cache:
directories:
- $HOME/.composer/cache
before_install:
- composer self-update
install:
- composer install --no-dev --no-interaction --ignore-platform-reqs
- zip -r --exclude='*.git*' --exclude='*.zip' --exclude='*.travis.yml' ThinkPHP_Core.zip .
- composer require --update-no-dev --no-interaction "topthink/think-image:^1.0"
- composer require --update-no-dev --no-interaction "topthink/think-migration:^1.0"
- composer require --update-no-dev --no-interaction "topthink/think-captcha:^1.0"
- composer require --update-no-dev --no-interaction "topthink/think-mongo:^1.0"
- composer require --update-no-dev --no-interaction "topthink/think-worker:^1.0"
- composer require --update-no-dev --no-interaction "topthink/think-helper:^1.0"
- composer require --update-no-dev --no-interaction "topthink/think-queue:^1.0"
- composer require --update-no-dev --no-interaction "topthink/think-angular:^1.0"
- composer require --dev --update-no-dev --no-interaction "topthink/think-testing:^1.0"
- zip -r --exclude='*.git*' --exclude='*.zip' --exclude='*.travis.yml' ThinkPHP_Full.zip .
script:
- php think unit
deploy:
provider: releases
api_key:
secure: TSF6bnl2JYN72UQOORAJYL+CqIryP2gHVKt6grfveQ7d9rleAEoxlq6PWxbvTI4jZ5nrPpUcBUpWIJHNgVcs+bzLFtyh5THaLqm39uCgBbrW7M8rI26L8sBh/6nsdtGgdeQrO/cLu31QoTzbwuz1WfAVoCdCkOSZeXyT/CclH99qV6RYyQYqaD2wpRjrhA5O4fSsEkiPVuk0GaOogFlrQHx+C+lHnf6pa1KxEoN1A0UxxVfGX6K4y5g4WQDO5zT4bLeubkWOXK0G51XSvACDOZVIyLdjApaOFTwamPcD3S1tfvuxRWWvsCD5ljFvb2kSmx5BIBNwN80MzuBmrGIC27XLGOxyMerwKxB6DskNUO9PflKHDPI61DRq0FTy1fv70SFMSiAtUv9aJRT41NQh9iJJ0vC8dl+xcxrWIjU1GG6+l/ZcRqVx9V1VuGQsLKndGhja7SQ+X1slHl76fRq223sMOql7MFCd0vvvxVQ2V39CcFKao/LB1aPH3VhODDEyxwx6aXoTznvC/QPepgWsHOWQzKj9ftsgDbsNiyFlXL4cu8DWUty6rQy8zT2b4O8b1xjcwSUCsy+auEjBamzQkMJFNlZAIUrukL/NbUhQU37TAbwsFyz7X0E/u/VMle/nBCNAzgkMwAUjiHM6FqrKKBRWFbPrSIixjfjkCnrMEPw=
file:
- ThinkPHP_Core.zip
- ThinkPHP_Full.zip
skip_cleanup: true
on:
tags: true
version=CRMEB-DTKY v3.2.8
version_code=134
\ No newline at end of file
版权所有 (c)2017-2027,西安众邦网络科技有限公司 保留所有权利。
感谢您选择CrmEb开源客户管理+电商系统(简称CRMEB),CRMEB是国内最稳定、最强大、最先进的互联网电商平台解决方案之一,CRMEB基于 PHP + MySQL 的技术,采用ThinkPHP5.0框架开发。
为了使你正确并合法的使用本软件,请你在使用前务必阅读清楚下面的协议条款:
本授权协议适用且仅适用于CRMEB任何版本,CRMEB官方对本授权协议的最终解释权和修改权。
一、协议许可的权利
1、您可以在完全遵守本最终用户授权协议的基础上,将本软件应用于非商业用途,而不必支付软件版权授权费用。
2、您可以在协议规定的约束和限制范围内修改 CRMEB 源代码或界面风格以适应您的网站要求。
3、您拥有使用本软件构建的网站全部内容所有权,并独立承担与这些内容的相关法律义务。
4、获得商业授权之后,您可以将本软件应用于商业用途,同时依据所购买的授权类型中确定的技术支持内容。商业授权用户享有反映和提出意见的权力,相关意见将被作为首要考虑,但没有一定被采纳的承诺或保证。
二、协议许可的权利和限制
1、未获商业授权之前,不得删除网站底部及相应的官方版权信息和链接。购买商业授权请联系西安众邦网络科技有限公司了解最新说明。CRMEB著作权已在中华人民共和国国家版权局注册(中国国家版权局著作权登记号 2018SR024463),著作权受到法律和国际公约保护。
2、未经官方许可,不得对本软件或与之关联的商业授权进行出租、出售、抵押或发放子许可证。
3、不管你的网站是否整体使用 CRMEB ,还是部份栏目使用 CRMEB,在你使用了 CRMEB 的网站主页上必须加上 CRMEB 官方网址(www.crmeb.com)的链接。
4、未经官方许可,禁止在 CRMEB 的整体或任何部分基础上以发展任何派生版本、修改版本或第三方版本用于重新分发。
5、如果您未能遵守本协议的条款,您的授权将被终止,所被许可的权利将被收回,并承担相应法律责任。
三、有限担保和免责声明
1、本软件及所附带的文件是作为不提供任何明确的或隐含的赔偿或担保的形式提供的。
2、用户出于自愿而使用本软件,您必须了解使用本软件的风险,在尚未购买产品技术服务之前,我们不承诺对免费用户提供任何形式的技术支持、使用担保,也不承担任何因使用本软件而产生问题的相关责任。
3、电子文本形式的授权协议如同双方书面签署的协议一样,具有完全的和等同的法律效力。您一旦开始确认本协议并安装 CRMEB,即被视为完全理解并接受本协议的各项条款,在享有上述条款授予的权力的同时,受到相关的约束和限制。协议许可范围以外的行为,将直接违反本授权协议并构成侵权,我们有权随时终止授权,责令停止损害,并保留追究相关责任的权力。
协议发布时间: 2017年8月01日
版本最新更新: 2019年8月15日 By CRMEB
CRMEB官方网站:http://www.crmeb.com
CRMEB演示站:http://demo.crmeb.com
-----------------------------------------------------
运营团队: 众邦科技
电 话: 400-8888-794
邮 箱: admin@xazbkj.com
网 址: http://www.xazbkj.com
\ No newline at end of file
CRMEB 3.0
===============
> 运行环境要求PHP7.1+。
## 主要特性
### 开源无加密
源码开源无加密,有详细的代码注释,有完整系统手册
### TP6框架
使用最新的 ThinkPHP 6.0框架开发
### 前端采用Vue CLI框架
前端使用Vue CLI框架nodejs打包,页面加载更流畅,用户体验更好
### 标准接口
标准接口、前后端分离,二次开发更方便
### 支持队列
降低流量高峰,解除耦合,高可用
### 长连接
减少CPU及内存使用及网络堵塞,减少请求响应时长
### 无缝事件机制
行为扩展更方便,方便二次开发
### 后台快速生成表单
后台应用form-builder 无需写页面快速增删改查
### 数据表格导出
PHPExcel数据导出,导出表格更加美观可视;
### 数据统计分析
后台使用ECharts图表统计,实现用户、产品、订单、资金等统计分析
### 强大的后台权限管理
后台多种角色、多重身份权限管理,权限可以控制到每一步操作
### 一件安装
自动检查系统环境一键安装
## 安装
## 一键安装
上传你的代码,站点入口目录设置/public
在浏览器中输入你的域名或IP(例如:www.yourdomain.com),
安装程序会自动执行安装。期间系统会提醒你输入数据库信息以完成安装,安装完成后建议删除install目录下index.php文件或将其改名。
后台访问地址:
1.域名/admin
2.域名/index.php/admin
3.域名/index.php?s=/admin
公众号和H5首页访问地址:
1.域名/
提示:正常访问是第一中模式,第一种访问不了请检测[URL重写](http://help.crmeb.net/895486)是否配置好
安装过程中请牢记您的账号密码!
## 重新安装
1. 清除数据库
2. 删除/public/install/install.lock 文件
## 手动安装
1.创建数据库,倒入数据库文件
数据库文件目录/public/install/crmeb.sql
2.修改数据库连接文件
配置文件路径/.env
~~~
APP_DEBUG = true
[APP]
DEFAULT_TIMEZONE = Asia/Shanghai
[DATABASE]
TYPE = mysql
HOSTNAME = 127.0.0.1 #数据库连接地址
DATABASE = test #数据库名称
USERNAME = username #数据库登录账号
PASSWORD = password #数据库登录密码
HOSTPORT = 3306 #数据库端口
CHARSET = utf8
DEBUG = true
[LANG]
default_lang = zh-cn
~~~
3.修改目录权限(linux系统)777
/public
/runtime
4.后台登录:
http://域名/admin
默认账号:admin 密码:crmeb.com
## 定时任务
在自动收货,库存预警等功能使用到
```sh
php think timer [ status ] [ --d ]
```
参数
- status: 状态
- start: 启动
- stop: 关闭
- restart: 重启
- --d : 后台执行
## 长连接服务
在h5聊天,后台管理员消息通知等功能使用到
```sh
php think workerman [ status ] [ server ] [ --d ]
```
windows环境下需要分三步执行
```sh
# 内部通讯服务
php think workerman start channel
# h5端聊天服务
php think workerman start chat
# 后台管理员通知
php think workerman start admin
```
参数
- status: 状态
- start: 启动
- stop: 关闭
- restart: 重启
- server: 服务 (windows)
- channel: 内部通讯
- chat: h5
- admin: 后台
- --d : 后台执行
## 文档
[使用手册](https://help.crmeb.net)
[TP6开发手册](https://www.kancloud.cn/manual/thinkphp6_0/content)
## 参与开发
请参阅 [CRMEB](https://github.com/crmeb/CRMEB)
## 版权信息
本项目包含的第三方源码和二进制文件之版权信息另行标注。
版权所有Copyright © 2017-2019 by CRMEB (http://www.crmeb.com)
All rights reserved。
CRMEB® 商标和著作权所有者为西安众邦网络科技有限公司。
deny from all
\ No newline at end of file
<?php
namespace app;
use crmeb\services\SystemConfigService;
use crmeb\services\GroupDataService;
use crmeb\utils\Json;
use think\facade\Db;
use think\Service;
class AppService extends Service
{
public $bind = [
'json' => Json::class,
'sysConfig' => SystemConfigService::class,
'sysGroupData' => GroupDataService::class
];
public function boot()
{
}
}
<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006~2019 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: liu21st <liu21st@gmail.com>
// +----------------------------------------------------------------------
namespace app;
use think\db\exception\DataNotFoundException;
use think\db\exception\ModelNotFoundException;
use think\exception\Handle;
use think\exception\HttpException;
use think\exception\HttpResponseException;
use think\exception\ValidateException;
use think\Response;
use Throwable;
/**
* 应用异常处理类
*/
class ExceptionHandle extends Handle
{
/**
* 不需要记录信息(日志)的异常类列表
* @var array
*/
protected $ignoreReport = [
HttpException::class,
HttpResponseException::class,
ModelNotFoundException::class,
DataNotFoundException::class,
ValidateException::class,
];
/**
* 记录异常信息(包括日志或者其它方式记录)
*
* @access public
* @param Throwable $exception
* @return void
*/
public function report(Throwable $exception): void
{
// 使用内置的方式记录异常日志
parent::report($exception);
}
/**
* Render an exception into an HTTP response.
*
* @access public
* @param \think\Request $request
* @param Throwable $e
* @return Response
*/
public function render($request, Throwable $e): Response
{
// 添加自定义异常处理机制
// 其他错误交给系统处理
return parent::render($request, $e);
}
}
<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006~2019 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: liu21st <liu21st@gmail.com>
// +----------------------------------------------------------------------
namespace app;
use Spatie\Macroable\Macroable;
class Request extends \think\Request
{
use Macroable;
}
<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006-2016 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: 流年 <liu21st@gmail.com>
// +----------------------------------------------------------------------
// 应用公共文件
if (!function_exists('attr_format')) {
/**
* 格式化属性
* @param $arr
* @return array
*/
function attr_format($arr)
{
$data = [];
$res = [];
$count = count($arr);
if ($count > 1) {
for ($i = 0; $i < $count - 1; $i++) {
if ($i == 0) $data = $arr[$i]['detail'];
//替代变量1
$rep1 = [];
foreach ($data as $v) {
foreach ($arr[$i + 1]['detail'] as $g) {
//替代变量2
$rep2 = ($i != 0 ? '' : $arr[$i]['value'] . '_$_') . $v . '-$-' . $arr[$i + 1]['value'] . '_$_' . $g;
$tmp[] = $rep2;
if ($i == $count - 2) {
foreach (explode('-$-', $rep2) as $k => $h) {
//替代变量3
$rep3 = explode('_$_', $h);
//替代变量4
$rep4['detail'][$rep3[0]] = isset($rep3[1]) ? $rep3[1] : '';
}
if($count == count($rep4['detail']))
$res[] = $rep4;
}
}
}
$data = isset($tmp) ? $tmp : [];
}
} else {
$dataArr = [];
foreach ($arr as $k => $v) {
foreach ($v['detail'] as $kk => $vv) {
$dataArr[$kk] = $v['value'] . '_' . $vv;
$res[$kk]['detail'][$v['value']] = $vv;
}
}
$data[] = implode('-', $dataArr);
}
return [$data, $res];
}
}
if (!function_exists('get_month')) {
/**
* 格式化月份
* @param string $time
* @param int $ceil
* @return array
*/
function get_month($time = '', $ceil = 0)
{
if (empty($time)) {
$firstday = date("Y-m-01", time());
$lastday = date("Y-m-d", strtotime("$firstday +1 month -1 day"));
} else if ($time == 'n') {
if ($ceil != 0)
$season = ceil(date('n') / 3) - $ceil;
else
$season = ceil(date('n') / 3);
$firstday = date('Y-m-01', mktime(0, 0, 0, ($season - 1) * 3 + 1, 1, date('Y')));
$lastday = date('Y-m-t', mktime(0, 0, 0, $season * 3, 1, date('Y')));
} else if ($time == 'y') {
$firstday = date('Y-01-01');
$lastday = date('Y-12-31');
} else if ($time == 'h') {
$firstday = date('Y-m-d', strtotime('this week +' . $ceil . ' day')) . ' 00:00:00';
$lastday = date('Y-m-d', strtotime('this week +' . ($ceil + 1) . ' day')) . ' 23:59:59';
}
return array($firstday, $lastday);
}
}
if (!function_exists('clearfile')) {
/**删除目录下所有文件
* @param $path 目录或者文件路径
* @param string $ext
* @return bool
*/
function clearfile($path, $ext = '*.log')
{
$files = (array)glob($path . DS . '*');
foreach ($files as $path) {
if (is_dir($path)) {
$matches = glob($path . '/' . $ext);
if (is_array($matches)) {
array_map('unlink', $matches);
}
rmdir($path);
} else {
unlink($path);
}
}
return true;
}
}
if (!function_exists('get_this_class_methods')) {
/**获取当前类方法
* @param $class
* @return array
*/
function get_this_class_methods($class, $unarray = [])
{
$arrayall = get_class_methods($class);
if ($parent_class = get_parent_class($class)) {
$arrayparent = get_class_methods($parent_class);
$arraynow = array_diff($arrayall, $arrayparent);//去除父级的
} else {
$arraynow = $arrayall;
}
return array_diff($arraynow, $unarray);//去除无用的
}
}
if (!function_exists('verify_domain')) {
/**
* 验证域名是否合法
* @param string $domain
* @return bool
*/
function verify_domain(string $domain): bool
{
$res = "/^(?=^.{3,255}$)(http(s)?:\/\/)(www\.)?[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(\.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+(:\d+)*(\/\w+\.\w+)*$/";
if (preg_match($res, $domain))
return true;
else
return false;
}
}
<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: liu21st <liu21st@gmail.com>
// +----------------------------------------------------------------------
// +----------------------------------------------------------------------
// | 应用设置
// +----------------------------------------------------------------------
return [
// 是否强制使用路由
'url_route_must' => false,
// 合并路由规则
'route_rule_merge' => true,
// 路由是否完全匹配
'route_complete_match' => false,
// 是否自动转换URL中的控制器和操作名
'url_convert' => true,
];
<?php
// +----------------------------------------------------------------------
// | 模板设置
// +----------------------------------------------------------------------
return [
// 模板后缀
'view_suffix' => 'php',
// 视图输出字符串内容替换
'tpl_replace_string' => [
'{__PUBLIC_PATH}' => '/', //public 目录
'{__STATIC_PATH}' => '/static/', //全局静态目录
'{__PLUG_PATH}' => '/static/plug/', //全局静态插件
'{__ADMIN_PATH}' => '/system/', //后台目录
'{__FRAME_PATH}' => '/system/frame/', //后台框架
'{__MODULE_PATH}' => '/system/module/', //后台模块
]
];
<?php
// +----------------------------------------------------------------------
// | 模板设置
// +----------------------------------------------------------------------
return [
// 模板后缀
'view_suffix' => 'php',
// 模板路径
'view_path' => app_path('view'),
// 视图输出字符串内容替换
'tpl_replace_string' => [
'{__PUBLIC_PATH}' => '/', //public 目录
'{__STATIC_PATH}' => '/static/', //全局静态目录
'{__PLUG_PATH}' => '/static/plug/', //全局静态插件
'{__ADMIN_PATH}' => '/system/', //后台目录
'{__FRAME_PATH}' => '/system/frame/', //后台框架
'{__MODULE_PATH}' => '/system/module/', //后台模块
]
];
<?php
/**
*
* @author: xaboy<365615158@qq.com>
* @day: 2018/01/10
*/
namespace app\admin\controller;
use think\exception\Handle;
use think\exception\ValidateException;
use think\Response;
use Throwable;
/**
* 后台异常处理
*
* Class AdminException
* @package app\admin\controller
*/
class AdminException extends Handle
{
public function render($request, Throwable $e): Response
{
// 参数验证错误
if ($e instanceof ValidateException) {
return app('json')->make(422, $e->getError());
}
if ($e instanceof \Exception && request()->isAjax()) {
return app('json')->fail($e->getMessage(), ['code' => $e->getCode(), 'line' => $e->getLine(), 'message' => $e->getMessage(), 'file' => $e->getFile()]);
}
return parent::render($request, $e);
}
}
\ No newline at end of file
<?php
namespace app\admin\controller;
use app\admin\model\system\SystemAdmin;
use app\admin\model\system\SystemMenus;
use app\admin\model\system\SystemRole;
use think\facade\Route as Url;
/**
* 基类 所有控制器继承的类
* Class AuthController
* @package app\admin\controller
*/
class AuthController extends SystemBasic
{
/**
* 当前登陆管理员信息
* @var
*/
protected $adminInfo;
/**
* 当前登陆管理员ID
* @var
*/
protected $adminId;
/**
* 当前管理员权限
* @var array
*/
protected $auth = [];
protected $skipLogController = ['index', 'common'];
protected function initialize()
{
parent::initialize();
if (!SystemAdmin::hasActiveAdmin()) return $this->redirect(Url::buildUrl('login/index')->suffix(false)->build());
try {
$adminInfo = SystemAdmin::activeAdminInfoOrFail();
} catch (\Exception $e) {
return $this->failed(SystemAdmin::getErrorInfo($e->getMessage()), Url::buildUrl('login/index')->suffix(false)->build());
}
$this->adminInfo = $adminInfo;
$this->adminId = $adminInfo['id'];
$this->getActiveAdminInfo();
$this->auth = SystemAdmin::activeAdminAuthOrFail();
$this->adminInfo->level === 0 || $this->checkAuth();
$this->assign('_admin', $this->adminInfo);
$type = 'system';
event('AdminVisit', [$this->adminInfo, $type]);
}
protected function checkAuth($action = null, $controller = null, $module = null, array $route = [])
{
static $allAuth = null;
if ($allAuth === null) $allAuth = SystemRole::getAllAuth();
if ($module === null) $module = app('http')->getName();
if ($controller === null) $controller = $this->request->controller();
if ($action === null) $action = $this->request->action();
if (!count($route)) $route = $this->request->route();
if (in_array(strtolower($controller), $this->skipLogController, true)) return true;
$nowAuthName = SystemMenus::getAuthName($action, $controller, $module, $route);
$baseNowAuthName = SystemMenus::getAuthName($action, $controller, $module, []);
if ((in_array($nowAuthName, $allAuth) && !in_array($nowAuthName, $this->auth)) || (in_array($baseNowAuthName, $allAuth) && !in_array($baseNowAuthName, $this->auth)))
exit($this->failed('没有权限访问!'));
return true;
}
/**
* 获得当前用户最新信息
* @return SystemAdmin
*/
protected function getActiveAdminInfo()
{
$adminId = $this->adminId;
$adminInfo = SystemAdmin::getValidAdminInfoOrFail($adminId);
if (!$adminInfo) $this->failed(SystemAdmin::getErrorInfo('请登陆!'));
$this->adminInfo = $adminInfo;
SystemAdmin::setLoginInfo($adminInfo);
return $adminInfo;
}
}
\ No newline at end of file
此差异已折叠。
<?php
namespace app\admin\controller;
use app\admin\model\system\SystemAdmin;
use crmeb\services\UtilService;
use think\facade\Session;
use think\facade\Route as Url;
/**
* 登录验证控制器
* Class Login
* @package app\admin\controller
*/
class Login extends SystemBasic
{
public function index()
{
return $this->fetch();
}
/**
* 登录验证 + 验证码验证
*/
public function verify()
{
if (!request()->isPost()) return $this->failed('请登陆!');
list($account, $pwd, $verify) = UtilService::postMore([
'account', 'pwd', 'verify'
], null, true);
//检验验证码
if (!captcha_check($verify)) return $this->failed('验证码错误,请重新输入');
$error = Session::get('login_error') ?: ['num' => 0, 'time' => time()];
$error['num'] = 0;
if ($error['num'] >= 5 && $error['time'] > strtotime('- 5 minutes'))
return $this->failed('错误次数过多,请稍候再试!');
//检验帐号密码
$res = SystemAdmin::login($account, $pwd);
if ($res) {
Session::set('login_error', null);
Session::save();
return $this->successful(['url' => Url::buildUrl('Index/index')->build()]);
} else {
$error['num'] += 1;
$error['time'] = time();
Session::set('login_error', $error);
Session::save();
return $this->failed(SystemAdmin::getErrorInfo('用户名错误,请重新输入'));
}
}
public function captcha()
{
ob_clean();
return captcha();
}
/**
* 退出登陆
*/
public function logout()
{
SystemAdmin::clearLoginInfo();
$this->redirect(Url::buildUrl('index')->build());
}
}
\ No newline at end of file
<?php
/**
*
* @author: xaboy<365615158@qq.com>
* @day: 2017/10/09
*/
namespace app\admin\controller;
use crmeb\services\JsonService;
use crmeb\basic\BaseController;
class SystemBasic extends BaseController
{
/**
* 操作失败提示框
* @param string $msg 提示信息
* @param string $backUrl 跳转地址
* @param string $title 标题
* @param int $duration 持续时间
* @return mixed
*/
protected function failedNotice($msg = '操作失败', $backUrl = 0, $info = '', $duration = 3)
{
$type = 'error';
$this->assign(compact('msg', 'backUrl', 'info', 'duration', 'type'));
return $this->fetch('public/notice');
}
/**
* 失败提示一直持续
* @param $msg
* @param int $backUrl
* @param string $title
* @return mixed
*/
protected function failedNoticeLast($msg = '操作失败', $backUrl = 0, $info = '')
{
return $this->failedNotice($msg, $backUrl, $info, 0);
}
/**
* 操作成功提示框
* @param string $msg 提示信息
* @param string $backUrl 跳转地址
* @param string $title 标题
* @param int $duration 持续时间
* @return mixed
*/
protected function successfulNotice($msg = '操作成功', $backUrl = 0, $info = '', $duration = 3)
{
$type = 'success';
$this->assign(compact('msg', 'backUrl', 'info', 'duration', 'type'));
return $this->fetch('public/notice');
}
/**
* 成功提示一直持续
* @param $msg
* @param int $backUrl
* @param string $title
* @return mixed
*/
protected function successfulNoticeLast($msg = '操作成功', $backUrl = 0, $info = '')
{
return $this->successfulNotice($msg, $backUrl, $info, 0);
}
/**
* 错误提醒页面
* @param string $msg
* @param int $url
*/
protected function failed($msg = '哎呀…亲…您访问的页面出现错误', $url = 0)
{
if ($this->request->isAjax()) {
exit(JsonService::fail($msg, $url)->getContent());
} else {
$this->assign(compact('msg', 'url'));
exit($this->fetch('public/error'));
}
}
/**
* 成功提醒页面
* @param string $msg
* @param int $url
*/
protected function successful($msg, $url = 0)
{
if ($this->request->isAjax()) {
exit(JsonService::successful($msg, $url)->getContent());
} else {
$this->assign(compact('msg', 'url'));
exit($this->fetch('public/success'));
}
}
/**异常抛出
* @param $name
*/
protected function exception($msg = '无法打开页面')
{
$this->assign(compact('msg'));
exit($this->fetch('public/exception'));
}
/**找不到页面
* @param $name
*/
public function _empty($name)
{
exit($this->fetch('public/404'));
}
}
<?php
namespace app\admin\controller;
use app\admin\model\system\SystemCity;
use crmeb\services\ExpressService;
use crmeb\services\HttpService;
use crmeb\services\JsonService;
use crmeb\utils\Queue;
use think\facade\Db;
use think\facade\Queue as QueueJob;
class Test
{
public function index($page = 1, $limit = 50, $level = 0)
{
// var_dump(is_file('uploads/981_1_user.jpg'));
// $appCode = '4a5b910fc344434cacb2edd36e0e56aa';
// $list = ExpressService::query('75341495702624');
// dump($list);
// $data = [];
// foreach ($list['data'] as $item) {
// $data[] = [
// 'level' => $item['level'],
// 'parent_id' => $item['parent_id'],
// 'area_code' => $item['area_code'],
// 'name' => $item['name'],
// 'merger_name' => $item['merger_name'],
// 'lng' => $item['lng'],
// 'lat' => $item['lat'],
// 'city_id' => $item['id'],
// ];
// }
// $res = SystemCity::insertAll($data);
// return JsonService::successful(['count' => $res]);
$sql = Db::name('system_menus')->whereIn('paid', function ($query) {
$query->name('system_menus')->where('menu_name', '评论管理')->find();
})->fetchSql(true)->delete();
var_dump($sql);
}
}
\ No newline at end of file
<?php
namespace app\admin\controller\agent;
use app\admin\controller\AuthController;
use app\admin\model\order\StoreOrder;
use app\admin\model\system\SystemAttachment;
use app\admin\model\user\User;
use app\models\user\UserBill;
use app\admin\model\wechat\WechatUser as UserModel;
use app\models\routine\{
RoutineCode, RoutineQrcode
};
use crmeb\services\{
JsonService, QrcodeService, UtilService as Util
};
use crmeb\services\upload\Upload;
/**
* 分销商管理控制器
* Class AgentManage
* @package app\admin\controller\agent
*/
class AgentManage extends AuthController
{
/**
* @return mixed
*/
public function index()
{
$this->assign('year', get_month());
$this->assign('store_brokerage_statu', sys_config('store_brokerage_statu'));
return $this->fetch();
}
/**
* 分销员列表
*/
public function get_spread_list()
{
$where = Util::getMore([
['nickname', ''],
['sex', ''],
['excel', ''],
['subscribe', ''],
['order', ''],
['page', 1],
['limit', 20],
['user_type', ''],
['data', '']
]);
return JsonService::successlayui(UserModel::agentSystemPage($where));
}
/**
* 分销员列表头部数据统计
*/
public function get_badge()
{
$where = Util::postMore([
['data', ''],
['nickname', ''],
['excel', ''],
]);
return JsonService::successful(UserModel::getSpreadBadge($where));
}
/**
* 一级推荐人页面
* @return mixed
*/
public function stair($uid = '')
{
if ($uid == '') return $this->failed('参数错误');
$this->assign('uid', $uid ?: 0);
$this->assign('year', get_month());
return $this->fetch();
}
/*
* 统计推广订单页面
* @param int $uid
* */
public function stair_order($uid = 0)
{
if ($uid == '') return $this->failed('参数错误');
$this->assign('uid', $uid ?: 0);
$this->assign('year', get_month());
return $this->fetch();
}
/**
* 统计推广订单列表
*/
public function get_stair_order_list()
{
$where = Util::getMore([
['uid', $this->request->param('uid', 0)],
['data', ''],
['order_id', ''],
['type', ''],
['page', 1],
['limit', 20],
]);
return JsonService::successlayui(UserModel::getStairOrderList($where));
}
/**
* 统计推广订单列表头部统计数据
*/
public function get_stair_order_badge()
{
$where = Util::getMore([
['uid', ''],
['data', ''],
['order_id', ''],
['type', ''],
]);
return JsonService::successful(UserModel::getStairOrderBadge($where));
}
public function get_stair_list()
{
$where = Util::getMore([
['uid', $this->request->param('uid', 0)],
['data', ''],
['nickname', ''],
['type', ''],
['page', 1],
['limit', 20],
]);
return JsonService::successlayui(UserModel::getStairList($where));
}
public function get_stair_badge()
{
$where = Util::getMore([
['uid', ''],
['data', ''],
['nickname', ''],
['type', ''],
]);
return JsonService::successful(UserModel::getSairBadge($where));
}
/**
* 二级推荐人页面
* @return mixed
*/
public function stair_two($uid = '')
{
if ($uid == '') return $this->failed('参数错误');
$spread_uid = User::where('spread_uid', $uid)->column('uid', 'uid');
if (count($spread_uid))
$spread_uid_two = User::where('spread_uid', 'in', $spread_uid)->column('uid', 'uid');
else
$spread_uid_two = [0];
$list = User::alias('u')
->where('u.uid', 'in', $spread_uid_two)
->field('u.avatar,u.nickname,u.now_money,u.spread_time,u.uid')
->where('u.status', 1)
->order('u.add_time DESC')
->select()
->toArray();
foreach ($list as $key => $value) $list[$key]['orderCount'] = StoreOrder::getOrderCount($value['uid']) ?: 0;
$this->assign('list', $list);
return $this->fetch('stair');
}
/*
* 批量清除推广权限
* */
public function delete_promoter()
{
list($uids) = Util::postMore([
['uids', []]
], $this->request, true);
if (!count($uids)) return JsonService::fail('请选择需要解除推广权限的用户!');
User::beginTrans();
try {
if (User::where('uid', 'in', $uids)->update(['is_promoter' => 0])) {
User::commitTrans();
return JsonService::successful('解除成功');
} else {
User::rollbackTrans();
return JsonService::fail('解除失败');
}
} catch (\PDOException $e) {
User::rollbackTrans();
return JsonService::fail('数据库操作错误', ['line' => $e->getLine(), 'message' => $e->getMessage()]);
} catch (\Exception $e) {
User::rollbackTrans();
return JsonService::fail('系统错误', ['line' => $e->getLine(), 'message' => $e->getMessage()]);
}
}
/*
* 查看公众号推广二维码
* @param int $uid
* @return json
* */
public function look_code($uid = '', $action = '')
{
if (!$uid || !$action) return JsonService::fail('缺少参数');
try {
if (method_exists($this, $action)) {
$res = $this->$action($uid);
if ($res)
return JsonService::successful($res);
else
return JsonService::fail(isset($res['msg']) ? $res['msg'] : '获取失败,请稍后再试!');
} else
return JsonService::fail('暂无此方法');
} catch (\Exception $e) {
return JsonService::fail('获取推广二维码失败,请检查您的微信配置', ['line' => $e->getLine(), 'messag' => $e->getMessage()]);
}
}
/*
* 获取小程序二维码
* */
public function routine_code($uid)
{
$userInfo = User::getUserInfos($uid);
$name = $userInfo['uid'] . '_' . $userInfo['is_promoter'] . '_user.jpg';
$imageInfo = SystemAttachment::getInfo($name, 'name');
if (!$imageInfo) {
$res = RoutineCode::getShareCode($uid, 'spread', '', '');
if (!$res) throw new \think\Exception('二维码生成失败');
$upload_type = sys_config('upload_type', 1);
$upload = new Upload((int)$upload_type, [
'accessKey' => sys_config('accessKey'),
'secretKey' => sys_config('secretKey'),
'uploadUrl' => sys_config('uploadUrl'),
'storageName' => sys_config('storage_name'),
'storageRegion' => sys_config('storage_region'),
]);
$info = $upload->to('routine/spread/code')->validate()->stream($res['res'], $name);
if ($info === false) {
return $upload->getError();
}
$imageInfo = $upload->getUploadInfo();
$imageInfo['image_type'] = $upload_type;
SystemAttachment::attachmentAdd($imageInfo['name'], $imageInfo['size'], $imageInfo['type'], $imageInfo['dir'], $imageInfo['thumb_path'], 1, $imageInfo['image_type'], $imageInfo['time'], 2);
RoutineQrcode::setRoutineQrcodeFind($res['id'], ['status' => 1, 'time' => time(), 'qrcode_url' => $imageInfo['dir']]);
$urlCode = $imageInfo['dir'];
} else $urlCode = $imageInfo['att_dir'];
return ['code_src' => $urlCode];
}
/*
* 获取公众号二维码
* */
public function wechant_code($uid)
{
$qr_code = QrcodeService::getForeverQrcode('spread', $uid);
if (isset($qr_code['url']))
return ['code_src' => $qr_code['url']];
else
throw new \think\Exception('获取失败,请稍后再试!');
}
/**
* TODO 查看小程序推广二维码
* @param string $uid
*/
public function look_xcx_code($uid = '')
{
if (!strlen(trim($uid))) return JsonService::fail('缺少参数');
try {
$userInfo = User::getUserInfos($uid);
$name = $userInfo['uid'] . '_' . $userInfo['is_promoter'] . '_user.jpg';
$imageInfo = SystemAttachment::getInfo($name, 'name');
if (!$imageInfo) {
$res = RoutineCode::getShareCode($uid, 'spread', '', '');
if (!$res) return JsonService::fail('二维码生成失败');
$upload_type = sys_config('upload_type', 1);
$upload = new Upload((int)$upload_type, [
'accessKey' => sys_config('accessKey'),
'secretKey' => sys_config('secretKey'),
'uploadUrl' => sys_config('uploadUrl'),
'storageName' => sys_config('storage_name'),
'storageRegion' => sys_config('storage_region'),
]);
$info = $upload->to('routine/spread/code')->validate()->stream($res['res'], $name);
if ($info === false) {
return $upload->getError();
}
$imageInfo = $upload->getUploadInfo();
$imageInfo['image_type'] = $upload_type;
SystemAttachment::attachmentAdd($imageInfo['name'], $imageInfo['size'], $imageInfo['type'], $imageInfo['dir'], $imageInfo['thumb_path'], 1, $imageInfo['image_type'], $imageInfo['time'], 2);
RoutineQrcode::setRoutineQrcodeFind($res['id'], ['status' => 1, 'time' => time(), 'qrcode_url' => $imageInfo['dir']]);
$urlCode = $imageInfo['dir'];
} else $urlCode = $imageInfo['att_dir'];
return JsonService::successful(['code_src' => $urlCode]);
} catch (\Exception $e) {
return JsonService::fail('查看推广二维码失败!', ['line' => $e->getLine(), 'meassge' => $e->getMessage()]);
}
}
/*
* 解除单个用户的推广权限
* @param int $uid
* */
public function delete_spread($uid = 0)
{
if (!$uid) return JsonService::fail('缺少参数');
if (User::where('uid', $uid)->update(['is_promoter' => 0]))
return JsonService::successful('解除成功');
else
return JsonService::fail('解除失败');
}
/*
* 清除推广人
* */
public function empty_spread($uid = 0)
{
if (!$uid) return JsonService::fail('缺少参数');
$res = User::where('uid', $uid)->update(['spread_uid' => 0]);
if ($res)
return JsonService::successful('清除成功');
else
return JsonService::fail('清除失败');
}
/**
* 个人资金详情页面
* @return mixed
*/
public function now_money($uid = '')
{
if ($uid == '') return $this->failed('参数错误');
$list = UserBill::where('uid', $uid)->where('category', 'now_money')
->field('mark,pm,number,add_time')
->where('status', 1)->order('add_time DESC')->select()->toArray();
foreach ($list as &$v) {
$v['add_time'] = $v['add_time'] ? date('Y-m-d H:i:s', $v['add_time']) : '';
}
$this->assign('list', $list);
return $this->fetch();
}
}
<?php
namespace app\admin\controller\article;
use app\admin\controller\AuthController;
use app\admin\model\system\SystemAttachment;
use crmeb\services\{
UtilService as Util, JsonService as Json
};
use app\admin\model\article\{
ArticleCategory as ArticleCategoryModel, Article as ArticleModel
};
/**
* 图文管理
* Class WechatNews
* @package app\admin\controller\wechat
*/
class Article extends AuthController
{
/**
* TODO 显示后台管理员添加的图文
* @return mixed
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
public function index()
{
$where = Util::getMore([
['title', ''],
['cid', $this->request->param('pid', '')],
], $this->request);
$this->assign('where', $where);
$where['merchant'] = 0;//区分是管理员添加的图文显示 0 还是 商户添加的图文显示 1
$tree = sort_list_tier(ArticleCategoryModel::getArticleCategoryList());
$this->assign(compact('tree'));
$this->assign(ArticleModel::getAll($where));
return $this->fetch();
}
/**
* TODO 文件添加和修改
* @return mixed
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
public function create()
{
$id = $this->request->param('id');
$cid = $this->request->param('cid');
$news = [];
$all = [];
$news['id'] = '';
$news['image_input'] = '';
$news['title'] = '';
$news['author'] = '';
$news['is_banner'] = '';
$news['is_hot'] = '';
$news['content'] = '';
$news['synopsis'] = '';
$news['url'] = '';
$news['cid'] = [];
$select = 0;
if ($id) {
$news = ArticleModel::where('n.id', $id)->alias('n')->field('n.*,c.content')->join('ArticleContent c', 'c.nid=n.id', 'left')->find();
if (!$news) return $this->failed('数据不存在!');
$news['cid'] = explode(',', $news['cid']);
$news['content'] = htmlspecialchars_decode($news['content']);
}
if ($cid && in_array($cid, ArticleCategoryModel::getArticleCategoryInfo(0, 'id'))) {
$all = ArticleCategoryModel::getArticleCategoryInfo($cid);
$select = 1;
}
if (!$select) {
$list = ArticleCategoryModel::getTierList();
foreach ($list as $menu) {
$all[$menu['id']] = $menu['html'] . $menu['title'];
}
}
$this->assign('all', $all);
$this->assign('news', $news);
$this->assign('cid', $cid);
$this->assign('select', $select);
return $this->fetch();
}
/**
* 上传图文图片
* @return \think\response\Json
*/
public function upload_image()
{
$res = Upload::instance()->setUploadPath('wechat/image/' . date('Ymd'))->image($_POST['file']);
if (!is_array($res)) return Json::fail($res);
SystemAttachment::attachmentAdd($res['name'], $res['size'], $res['type'], $res['dir'], $res['thumb_path'], 5, $res['image_type'], $res['time']);
return Json::successful('上传成功!', ['url' => $res['dir']]);
}
/**
* 添加和修改图文
*/
public function add_new()
{
$data = Util::postMore([
['id', 0],
['cid', []],
'title',
'author',
'image_input',
'content',
'synopsis',
'share_title',
'share_synopsis',
['visit', 0],
['sort', 0],
'url',
['is_banner', 0],
['is_hot', 0],
['status', 1],]);
$data['cid'] = implode(',', $data['cid']);
$content = $data['content'];
unset($data['content']);
if ($data['id']) {
$id = $data['id'];
unset($data['id']);
$res = false;
ArticleModel::beginTrans();
$res1 = ArticleModel::edit($data, $id, 'id');
$res2 = ArticleModel::setContent($id, $content);
if ($res1 && $res2) {
$res = true;
}
ArticleModel::checkTrans($res);
if ($res)
return Json::successful('修改图文成功!', $id);
else
return Json::fail('修改图文失败,您并没有修改什么!', $id);
} else {
$data['add_time'] = time();
$data['admin_id'] = $this->adminId;
$res = false;
ArticleModel::beginTrans();
$res1 = ArticleModel::create($data);
$res2 = false;
if ($res1)
$res2 = ArticleModel::setContent($res1->id, $content);
if ($res1 && $res2) {
$res = true;
}
ArticleModel::checkTrans($res);
if ($res)
return Json::successful('添加图文成功!', $res1->id);
else
return Json::successful('添加图文失败!', $res1->id);
}
}
/**
* 删除图文
* @param $id
* @return \think\response\Json
*/
public function delete($id)
{
$res = ArticleModel::del($id);
if (!$res)
return Json::fail('删除失败,请稍候再试!');
else
return Json::successful('删除成功!');
}
public function merchantIndex()
{
$where = Util::getMore([
['title', '']
], $this->request);
$this->assign('where', $where);
$where['cid'] = input('cid');
$where['merchant'] = 1;//区分是管理员添加的图文显示 0 还是 商户添加的图文显示 1
$this->assign(ArticleModel::getAll($where));
return $this->fetch();
}
/**
* 关联文章 id
* @param int $id
*/
public function relation($id = 0)
{
$this->assign('id', $id);
return $this->fetch();
}
/**
* 保存选择的产品
* @param int $id
*/
public function edit_article($id = 0)
{
if (!$id) return Json::fail('缺少参数');
list($product_id) = Util::postMore([
['product_id', 0]
], $this->request, true);
if (ArticleModel::edit(['product_id' => $product_id], ['id' => $id]))
return Json::successful('保存成功');
else
return Json::fail('保存失败');
}
/**
* 取消绑定的产品id
* @param int $id
*/
public function unrelation($id = 0)
{
if (!$id) return Json::fail('缺少参数');
if (ArticleModel::edit(['product_id' => 0], $id))
return Json::successful('取消关联成功!');
else
return Json::fail('取消失败');
}
}
\ No newline at end of file
<?php
namespace app\admin\controller\article;
use think\facade\Route as Url;
use app\admin\controller\AuthController;
use app\admin\model\system\SystemAttachment;
use app\admin\model\article\{ArticleCategory as ArticleCategoryModel,Article as ArticleModel};
use crmeb\services\{FormBuilder as Form,UtilService as Util,JsonService as Json};
/**
* 文章分类管理 控制器
* */
class ArticleCategory extends AuthController
{
/**
* 分类管理
* */
public function index()
{
$where = Util::getMore([
['status', ''],
['title', ''],
], $this->request);
$this->assign('where', $where);
$this->assign(ArticleCategoryModel::systemPage($where));
return $this->fetch();
}
/**
* 添加分类管理
* */
public function create()
{
$f = array();
$f[] = Form::select('pid', '父级id')->setOptions(function () {
$list = ArticleCategoryModel::getTierList();
$menus[] = ['value' => 0, 'label' => '顶级分类'];
foreach ($list as $menu) {
$menus[] = ['value' => $menu['id'], 'label' => $menu['html'] . $menu['title']];
}
return $menus;
})->filterable(1);
$f[] = Form::input('title', '分类名称');
$f[] = Form::input('intr', '分类简介')->type('textarea');
$f[] = Form::frameImageOne('image', '分类图片', Url::buildUrl('admin/widget.images/index', array('fodder' => 'image')))->icon('image')->width('100%')->height('500px');
$f[] = Form::number('sort', '排序', 0);
$f[] = Form::radio('status', '状态', 1)->options([['value' => 1, 'label' => '显示'], ['value' => 0, 'label' => '隐藏']]);
$form = Form::make_post_form('添加分类', $f, Url::buildUrl('save'));
$this->assign(compact('form'));
return $this->fetch('public/form-builder');
}
/**
* s上传图片
* */
public function upload()
{
$res = Upload::instance()->setUploadPath('article')->image('file');
if (!is_array($res)) return Json::fail($res);
SystemAttachment::attachmentAdd($res['name'], $res['size'], $res['type'], $res['dir'], $res['thumb_path'], 5, $res['image_type'], $res['time']);
return Json::successful('图片上传成功!', ['name' => $res['name'], 'url' => path_to_url($res['thumb_path'])]);
}
/**
* 保存分类管理
* */
public function save()
{
$data = Util::postMore([
'title',
'pid',
'intr',
['new_id', []],
['image', []],
['sort', 0],
'status',]);
if (!$data['title']) return Json::fail('请输入分类名称');
if (count($data['image']) != 1) return Json::fail('请选择分类图片,并且只能上传一张');
if ($data['sort'] < 0) return Json::fail('排序不能是负数');
$data['add_time'] = time();
$data['image'] = $data['image'][0];
$new_id = $data['new_id'];
unset($data['new_id']);
$res = ArticleCategoryModel::create($data);
if (!ArticleModel::saveBatchCid($res['id'], implode(',', $new_id))) return Json::fail('文章列表添加失败');
return Json::successful('添加分类成功!');
}
/**
* 修改分类
* */
public function edit($id)
{
if (!$id) return $this->failed('参数错误');
$article = ArticleCategoryModel::get($id)->getData();
if (!$article) return Json::fail('数据不存在!');
$f = array();
$f[] = Form::select('pid', '父级id', (string)$article['pid'])->setOptions(function () {
$list = ArticleCategoryModel::getTierList();
$menus[] = ['value' => 0, 'label' => '顶级分类'];
foreach ($list as $menu) {
$menus[] = ['value' => $menu['id'], 'label' => $menu['html'] . $menu['title']];
}
return $menus;
})->filterable(1);
$f[] = Form::input('title', '分类名称', $article['title']);
$f[] = Form::input('intr', '分类简介', $article['intr'])->type('textarea');
$f[] = Form::frameImageOne('image', '分类图片', Url::buildUrl('admin/widget.images/index', array('fodder' => 'image')), $article['image'])->icon('image')->width('100%')->height('500px');
$f[] = Form::number('sort', '排序', $article['sort']);
$f[] = Form::radio('status', '状态', $article['status'])->options([['value' => 1, 'label' => '显示'], ['value' => 0, 'label' => '隐藏']]);
$form = Form::make_post_form('编辑分类', $f, Url::buildUrl('update', array('id' => $id)));
$this->assign(compact('form'));
return $this->fetch('public/form-builder');
}
public function update($id)
{
$data = Util::postMore([
'pid',
'title',
'intr',
// ['new_id',[]],
['image', []],
['sort', 0],
'status',]);
if (!$data['title']) return Json::fail('请输入分类名称');
if (count($data['image']) != 1) return Json::fail('请选择分类图片,并且只能上传一张');
if ($data['sort'] < 0) return Json::fail('排序不能是负数');
$data['image'] = $data['image'][0];
if (!ArticleCategoryModel::get($id)) return Json::fail('编辑的记录不存在!');
// if(!ArticleModel::saveBatchCid($id,implode(',',$data['new_id']))) return Json::fail('文章列表添加失败');
// unset($data['new_id']);
ArticleCategoryModel::edit($data, $id);
return Json::successful('修改成功!');
}
/**
* 删除分类
* */
public function delete($id)
{
$res = ArticleCategoryModel::delArticleCategory($id);
if (!$res)
return Json::fail(ArticleCategoryModel::getErrorInfo('删除失败,请稍候再试!'));
else
return Json::successful('删除成功!');
}
}
<?php
namespace app\admin\controller\article;
use app\admin\controller\AuthController;
use app\admin\model\system\SystemAttachment;
use app\admin\model\wechat\WechatNews as WechatNewsModel;
use crmeb\services\{
UtilService as Util, JsonService as Json
};
use app\admin\model\article\{
Article as ArticleModel, ArticleCategory as ArticleCategoryModel
};
use crmeb\services\upload\Upload;
/**
* 图文管理
* Class WechatNews
* @package app\admin\controller\wechat
*/
class WechatNews extends AuthController
{
/**
* 显示后台管理员添加的图文
* @return mixed
*/
public function index($cid = 0)
{
$where = Util::getMore([
['title', '']
], $this->request);
if ($cid)
$where['cid'] = $cid;
else
$where['cid'] = '';
$this->assign('where', $where);
$where['merchant'] = 0;//区分是管理员添加的图文显示 0 还是 商户添加的图文显示 1
$this->assign('cid', $cid);
$this->assign(ArticleModel::getAll($where));
return $this->fetch();
}
/**
* 展示页面 添加和删除
* @return mixed
*/
public function create()
{
$id = input('id');
$cid = input('cid');
$news = array();
$news['id'] = '';
$news['image_input'] = '';
$news['title'] = '';
$news['author'] = '';
$news['content'] = '';
$news['synopsis'] = '';
$news['url'] = '';
$news['cid'] = array();
if ($id) {
$news = WechatNewsModel::where('n.id', $id)->alias('n')->field('n.*,c.content')->join('wechat_news_content c', 'c.nid=n.id')->find();
if (!$news) return $this->failedNotice('数据不存在!');
$news['cid'] = explode(',', $news['cid']);
}
$all = array();
$select = 0;
if (!$cid)
$cid = '';
else {
if ($id) {
$all = ArticleCategoryModel::where('id', $cid)->where('hidden', '<>', 0)->column('title', 'id');
$select = 1;
} else {
$all = ArticleCategoryModel::where('id', $cid)->column('title', 'id');
$select = 1;
}
}
if (empty($all)) {
$all = ArticleCategoryModel::getField();//新闻分类
$select = 0;
}
$this->assign('all', $all);
$this->assign('news', $news);
$this->assign('cid', $cid);
$this->assign('select', $select);
return $this->fetch();
}
/**
* 上传图文图片
* @return \think\response\Json
*/
public function upload_image()
{
$uploadType = (int)sys_config('upload_type', 1);
$upload = new Upload($uploadType, [
'accessKey' => sys_config('accessKey'),
'secretKey' => sys_config('secretKey'),
'uploadUrl' => sys_config('uploadUrl'),
'storageName' => sys_config('storage_name'),
'storageRegion' => sys_config('storage_region'),
]);
$resInfo = $upload->to('wechat/image/' . date('Ymd'))->validate()->move($this->request->post('file'));
if ($resInfo === false) {
return Json::fail($upload->getError());
}
$res = $upload->getUploadInfo();
$res['image_type'] = $uploadType;
SystemAttachment::attachmentAdd($res['name'], $res['size'], $res['type'], $res['dir'], $res['thumb_path'], 5, $res['image_type'], $res['time']);
return Json::successful('上传成功!', ['url' => $res['thumb_path']]);
}
/**
* 添加和修改图文
*/
public function add_new()
{
$data = Util::postMore([
['id', 0],
['cid', []],
'title',
'author',
'image_input',
'content',
'synopsis',
'share_title',
'share_synopsis',
['visit', 0],
['sort', 0],
'url',
['status', 1],]);
$data['cid'] = implode(',', $data['cid']);
$content = $data['content'];
unset($data['content']);
if ($data['id']) {
$id = $data['id'];
unset($data['id']);
ArticleModel::beginTrans();
$res1 = ArticleModel::edit($data, $id, 'id');
$res2 = ArticleModel::setContent($id, $content);
if ($res1 && $res2)
$res = true;
else
$res = false;
ArticleModel::checkTrans($res);
if ($res)
return Json::successful('修改图文成功!', $id);
else
return Json::fail('修改图文失败!', $id);
} else {
$data['add_time'] = time();
$data['admin_id'] = $this->adminId;
ArticleModel::beginTrans();
$res1 = ArticleModel::create($data);
$res2 = false;
if ($res1)
$res2 = ArticleModel::setContent($res1->id, $content);
if ($res1 && $res2)
$res = true;
else
$res = false;
ArticleModel::checkTrans($res);
if ($res)
return Json::successful('添加图文成功!', $res1->id);
else
return Json::successful('添加图文失败!', $res1->id);
}
}
/**
* 删除图文
* @param $id
* @return \think\response\Json
*/
public function delete($id)
{
$res = ArticleModel::del($id);
if (!$res)
return Json::fail('删除失败,请稍候再试!');
else
return Json::successful('删除成功!');
}
public function merchantIndex()
{
$where = Util::getMore([
['title', '']
], $this->request);
$this->assign('where', $where);
$where['cid'] = input('cid');
$where['merchant'] = 1;//区分是管理员添加的图文显示 0 还是 商户添加的图文显示 1
$this->assign(ArticleModel::getAll($where));
return $this->fetch();
}
}
\ No newline at end of file
<?php
/**
* Created by PhpStorm.
* User: xurongyao <763569752@qq.com>
* Date: 2018/6/14 下午5:25
*/
namespace app\admin\controller\finance;
use app\admin\controller\AuthController;
use app\admin\model\user\{User,UserBill};
use app\admin\model\finance\FinanceModel;
use crmeb\services\{UtilService as Util,JsonService as Json};
/**
* 微信充值记录
* Class UserRecharge
* @package app\admin\controller\user
*/
class Finance extends AuthController
{
/**
* 显示资金记录
*/
public function bill()
{
$list = UserBill::where('type', 'not in', ['gain', 'system_sub', 'deduction', 'sign'])
->where('category', 'not in', 'integral')
->field(['title', 'type'])
->group('type')
->distinct(true)
->select()
->toArray();
$this->assign('selectList', $list);
return $this->fetch();
}
/**
* 显示资金记录ajax列表
*/
public function billlist()
{
$where = Util::getMore([
['start_time', ''],
['end_time', ''],
['nickname', ''],
['limit', 20],
['page', 1],
['type', ''],
]);
return Json::successlayui(FinanceModel::getBillList($where));
}
/**
*保存资金监控的excel表格
*/
public function save_bell_export()
{
$where = Util::getMore([
['start_time', ''],
['end_time', ''],
['nickname', ''],
['type', ''],
]);
FinanceModel::SaveExport($where);
}
/**
* 显示佣金记录
*/
public function commission_list()
{
$this->assign('is_layui', true);
return $this->fetch();
}
/**
* 佣金记录异步获取
*/
public function get_commission_list()
{
$get = Util::getMore([
['page', 1],
['limit', 20],
['nickname', ''],
['price_max', ''],
['price_min', ''],
['order', ''],
['excel', ''],
]);
return Json::successlayui(User::getCommissionList($get));
}
/**
* 显示操作记录
*/
public function index3()
{
}
/**
* 佣金详情
*/
public function content_info($uid = '')
{
if ($uid == '') return $this->failed('缺少参数');
$this->assign('userinfo', User::getUserinfo($uid));
$this->assign('uid', $uid);
return $this->fetch();
}
/**
* 佣金提现记录个人列表
*/
public function get_extract_list($uid = '')
{
if ($uid == '') return Json::fail('缺少参数');
$where = Util::getMore([
['page', 1],
['limit', 20],
['start_time', ''],
['end_time', ''],
['nickname', '']
]);
return Json::successlayui(UserBill::getExtrctOneList($where, $uid));
}
}
<?php
/**
* Created by PhpStorm.
* User: lianghuan
* Date: 2018-03-03
* Time: 16:37
*/
namespace app\admin\controller\finance;
use app\admin\controller\AuthController;
use think\facade\Route as Url;
use crmeb\services\JsonService;
use app\admin\model\user\UserExtract as UserExtractModel;
use crmeb\services\{UtilService as Util, FormBuilder as Form};
/**
* 用户提现管理
* Class UserExtract
* @package app\admin\controller\finance
*/
class UserExtract extends AuthController
{
public function index()
{
$where = Util::getMore([
['status', ''],
['nickname', ''],
['extract_type', ''],
['nireid', ''],
['date', ''],
], $this->request);
$limitTimeList = [
'today' => implode(' - ', [date('Y/m/d'), date('Y/m/d', strtotime('+1 day'))]),
'week' => implode(' - ', [
date('Y/m/d', (time() - ((date('w') == 0 ? 7 : date('w')) - 1) * 24 * 3600)),
date('Y-m-d', (time() + (7 - (date('w') == 0 ? 7 : date('w'))) * 24 * 3600))
]),
'month' => implode(' - ', [date('Y/m') . '/01', date('Y/m') . '/' . date('t')]),
'quarter' => implode(' - ', [
date('Y') . '/' . (ceil((date('n')) / 3) * 3 - 3 + 1) . '/01',
date('Y') . '/' . (ceil((date('n')) / 3) * 3) . '/' . date('t', mktime(0, 0, 0, (ceil((date('n')) / 3) * 3), 1, date('Y')))
]),
'year' => implode(' - ', [
date('Y') . '/01/01', date('Y/m/d', strtotime(date('Y') . '/01/01 + 1year -1 day'))
])
];
$this->assign('where', $where);
$this->assign('limitTimeList', $limitTimeList);
$this->assign(UserExtractModel::extractStatistics());
$this->assign(UserExtractModel::systemPage($where));
return $this->fetch();
}
public function edit($id)
{
if (!$id) return $this->failed('数据不存在');
$UserExtract = UserExtractModel::get($id);
if (!$UserExtract) return JsonService::fail('数据不存在!');
$f = array();
$f[] = Form::input('real_name', '姓名', $UserExtract['real_name']);
$f[] = Form::number('extract_price', '提现金额', $UserExtract['extract_price'])->precision(2);
if ($UserExtract['extract_type'] == 'alipay') {
$f[] = Form::input('alipay_code', '支付宝账号', $UserExtract['alipay_code']);
} else if ($UserExtract['extract_type'] == 'weixin') {
$f[] = Form::input('wechat', '微信号', $UserExtract['wechat']);
} else {
$f[] = Form::input('bank_code', '银行卡号', $UserExtract['bank_code']);
$f[] = Form::input('bank_address', '开户行', $UserExtract['bank_address']);
}
$f[] = Form::input('mark', '备注', $UserExtract['mark'])->type('textarea');
$form = Form::make_post_form('编辑', $f, Url::buildUrl('update', array('id' => $id)));
$this->assign(compact('form'));
return $this->fetch('public/form-builder');
}
public function update($id)
{
$UserExtract = UserExtractModel::get($id);
if (!$UserExtract) return JsonService::fail('数据不存在!');
if ($UserExtract['extract_type'] == 'alipay') {
$data = Util::postMore([
'real_name',
'mark',
'extract_price',
'alipay_code',
]);
if (!$data['real_name']) return JsonService::fail('请输入姓名');
if ($data['extract_price'] <= -1) return JsonService::fail('请输入提现金额');
if (!$data['alipay_code']) return JsonService::fail('请输入支付宝账号');
} else if ($UserExtract['extract_type'] == 'weixin') {
$data = Util::postMore([
'real_name',
'mark',
'extract_price',
'wechat',
]);
// if(!$data['real_name']) return JsonService::fail('请输入姓名');
if ($data['extract_price'] <= -1) return JsonService::fail('请输入提现金额');
if (!$data['wechat']) return JsonService::fail('请输入微信账号');
} else {
$data = Util::postMore([
'real_name',
'extract_price',
'mark',
'bank_code',
'bank_address',
]);
if (!$data['real_name']) return JsonService::fail('请输入姓名');
if ($data['extract_price'] <= -1) return JsonService::fail('请输入提现金额');
if (!$data['bank_code']) return JsonService::fail('请输入银行卡号');
if (!$data['bank_address']) return JsonService::fail('请输入开户行');
}
if (!UserExtractModel::edit($data, $id))
return JsonService::fail(UserExtractModel::getErrorInfo('修改失败'));
else
return JsonService::successful('修改成功!');
}
public function fail($id)
{
if (!UserExtractModel::be(['id' => $id, 'status' => 0])) return JsonService::fail('操作记录不存在或状态错误!');
$fail_msg = request()->post();
$extract = UserExtractModel::get($id);
if (!$extract) return JsonService::fail('操作记录不存在!');
if ($extract->status == 1) return JsonService::fail('已经提现,错误操作');
if ($extract->status == -1) return JsonService::fail('您的提现申请已被拒绝,请勿重复操作!');
$res = UserExtractModel::changeFail($id, $fail_msg['message']);
if ($res) {
return JsonService::successful('操作成功!');
} else {
return JsonService::fail('操作失败!');
}
}
public function succ($id)
{
if (!UserExtractModel::be(['id' => $id, 'status' => 0]))
return JsonService::fail('操作记录不存在或状态错误!');
UserExtractModel::beginTrans();
$extract = UserExtractModel::get($id);
if (!$extract) return JsonService::fail('操作记录不存!');
if ($extract->status == 1) return JsonService::fail('您已提现,请勿重复提现!');
if ($extract->status == -1) return JsonService::fail('您的提现申请已被拒绝!');
$res = UserExtractModel::changeSuccess($id);
if ($res) {
UserExtractModel::commitTrans();
return JsonService::successful('操作成功!');
} else {
UserExtractModel::rollbackTrans();
return JsonService::fail('操作失败!');
}
}
}
\ No newline at end of file
<?php
namespace app\admin\controller\finance;
use app\admin\controller\AuthController;
use app\admin\model\user\{User, UserRecharge as UserRechargeModel};
use app\models\routine\RoutineTemplate;
use app\models\user\{UserBill, WechatUser as WechatUserWap};
use crmeb\services\{JsonService,
MiniProgramService,
WechatService,
UtilService as Util,
FormBuilder as Form,
WechatTemplateService};
use think\facade\Route as Url;
/**
* 微信充值记录
* Class UserRecharge
* @package app\admin\controller\user
*/
class UserRecharge extends AuthController
{
/**
* 显示操作记录
*/
public function index()
{
$this->assign('year', get_month());
return $this->fetch();
}
public function get_user_recharge_list()
{
$where = Util::getMore([
['data', ''],
['paid', ''],
['page', 1],
['limit', 20],
['nickname', ''],
['excel', ''],
]);
return JsonService::successlayui(UserRechargeModel::getUserRechargeList($where));
}
public function delect($id = 0)
{
if (!$id) return JsonService::fail('缺少参数');
$rechargInfo = UserRechargeModel::get($id);
if ($rechargInfo->paid) return JsonService::fail('已支付的订单记录无法删除');
if (UserRechargeModel::del($id))
return JsonService::successful('删除成功');
else
return JsonService::fail('删除失败');
}
public function get_badge()
{
$where = Util::getMore([
['data', ''],
['paid', ''],
['nickname', ''],
]);
return JsonService::successful(UserRechargeModel::getDataList($where));
}
/**退款
* @param $id
* @return mixed|void
*/
public function edit($id)
{
if (!$id) return $this->failed('数据不存在');
$UserRecharge = UserRechargeModel::get($id);
if (!$UserRecharge) return JsonService::fail('数据不存在!');
if ($UserRecharge['paid'] == 1) {
$f = array();
$f[] = Form::input('order_id', '退款单号', $UserRecharge->getData('order_id'))->disabled(1);
$f[] = Form::number('refund_price', '退款金额', $UserRecharge->getData('price'))->precision(2)->min(0)->max($UserRecharge->getData('price'));
$jsContent = <<<SCRIPT
parent.SuccessFun();
parent.layer.close(parent.layer.getFrameIndex(window.name));
SCRIPT;
$form = Form::make_post_form('编辑', $f, Url::buildUrl('updateRefundY', array('id' => $id)), $jsContent);
$this->assign(compact('form'));
return $this->fetch('public/form-builder');
} else return JsonService::fail('数据不存在!');
}
/**
* 退款更新
* @param $id
*/
public function updateRefundY($id)
{
$data = Util::postMore([
'refund_price',
]);
if (!$id) return $this->failed('数据不存在');
$UserRecharge = UserRechargeModel::get($id);
if (!$UserRecharge) return JsonService::fail('数据不存在!');
if ($UserRecharge['price'] == $UserRecharge['refund_price']) return JsonService::fail('已退完支付金额!不能再退款了');
if (!$data['refund_price']) return JsonService::fail('请输入退款金额');
$refund_price = $data['refund_price'];
$data['refund_price'] = bcadd($data['refund_price'], $UserRecharge['refund_price'], 2);
$bj = bccomp((float)$UserRecharge['price'], (float)$data['refund_price'], 2);
if ($bj < 0) return JsonService::fail('退款金额大于支付金额,请修改退款金额');
$refund_data['pay_price'] = $UserRecharge['price'];
$refund_data['refund_price'] = $refund_price;
// $refund_data['refund_account']='REFUND_SOURCE_RECHARGE_FUNDS';
try {
$recharge_type = UserRechargeModel::where('order_id', $UserRecharge['order_id'])->value('recharge_type');
if ($recharge_type == 'weixin') {
WechatService::payOrderRefund($UserRecharge['order_id'], $refund_data);
} else {
MiniProgramService::payOrderRefund($UserRecharge['order_id'], $refund_data);
}
} catch (\Exception $e) {
return JsonService::fail($e->getMessage());
}
UserRechargeModel::edit($data, $id);
User::bcDec($UserRecharge['uid'], 'now_money', $refund_price, 'uid');
switch (strtolower($UserRecharge['recharge_type'])) {
case 'weixin':
WechatTemplateService::sendTemplate(WechatUserWap::where('uid', $UserRecharge['uid'])->value('openid'), WechatTemplateService::ORDER_REFUND_STATUS, [
'first' => '亲,您充值的金额已退款,本次退款' .
$data['refund_price'] . '金额',
'keyword1' => $UserRecharge['order_id'],
'keyword2' => $UserRecharge['price'],
'keyword3' => date('Y-m-d H:i:s', $UserRecharge['add_time']),
'remark' => '点击查看订单详情'
], Url::buildUrl('/user/bill/2')->suffix(false)->build());
break;
case 'routine':
RoutineTemplate::sendRechargeSuccess($UserRecharge, $data['refund_price']);
break;
}
UserBill::expend('系统退款', $UserRecharge['uid'], 'now_money', 'user_recharge_refund', $refund_price, $id, $UserRecharge['price'], '退款给用户' . $refund_price . '元');
return JsonService::successful('退款成功!');
}
}
此差异已折叠。
此差异已折叠。
此差异已折叠。
<?php
/**
* Created by PhpStorm.
* User: Administrator
* Date: 2018/4/16 0016
* Time: 10:39
*/
namespace app\admin\controller\record;
use app\admin\controller\AuthController;
use crmeb\services\UtilService as Util;
use app\admin\model\record\StoreStatistics as StatisticsModel;
/**
* Class StoreStatistics
* @package app\admin\controller\record
*/
class StoreStatistics extends AuthController
{
/**
* 显示列表
*/
public function index()
{
$where = Util::getMore([
['date', ''],
['export', ''],
['data', '']
], $this->request);
$where['date'] = $this->request->param('date');
$where['data'] = $this->request->param('data');
$where['export'] = $this->request->param('export');
$trans = StatisticsModel::trans();//最近交易
$seckill = StatisticsModel::getSeckill($where);//秒杀商品
$ordinary = StatisticsModel::getOrdinary($where);//普通商品
$pink = StatisticsModel::getPink($where);//拼团商品
$recharge = StatisticsModel::getRecharge($where);//充值
$extension = StatisticsModel::getExtension($where);//推广金
$orderCount = [
urlencode('微信支付') => StatisticsModel::getTimeWhere($where, StatisticsModel::statusByWhere('weixin'))->count(),
urlencode('余额支付') => StatisticsModel::getTimeWhere($where, StatisticsModel::statusByWhere('yue'))->count(),
urlencode('线下支付') => StatisticsModel::getTimeWhere($where, StatisticsModel::statusByWhere('offline'))->count(),
];
$Statistic = [
['name' => '营业额', 'type' => 'line', 'data' => []],
['name' => '支出', 'type' => 'line', 'data' => []],
['name' => '盈利', 'type' => 'line', 'data' => []],
];
$orderinfos = StatisticsModel::getOrderInfo($where);
$orderinfo = $orderinfos['orderinfo'];
$orderDays = [];
if (empty($orderinfo)) {
$orderDays[] = date('Y-m-d', time());
$Statistic[0]['data'][] = 0;
$Statistic[1]['data'][] = 0;
$Statistic[2]['data'][] = 0;
}
foreach ($orderinfo as $info) {
$orderDays[] = $info['pay_time'];
$Statistic[0]['data'][] = $info['total_price'] + $info['pay_postage'];
$Statistic[1]['data'][] = $info['coupon_price'] + $info['deduction_price'] + $info['cost'];
$Statistic[2]['data'][] = ($info['total_price'] + $info['pay_postage']) - ($info['coupon_price'] + $info['deduction_price'] + $info['cost']);
}
$price = $orderinfos['price'] + $orderinfos['postage'];
$cost = $orderinfos['deduction'] + $orderinfos['coupon'] + $orderinfos['cost'];
$Consumption = StatisticsModel::getConsumption($where)['number'];
$header = [
['name' => '总营业额', 'class' => 'fa-line-chart', 'value' => '¥' . $price, 'color' => 'red'],
['name' => '总支出', 'class' => 'fa-area-chart', 'value' => '¥' . ($cost + $extension), 'color' => 'lazur'],
['name' => '总盈利', 'class' => 'fa-bar-chart', 'value' => '¥' . bcsub($price, $cost, 0), 'color' => 'navy'],
['name' => '新增消费', 'class' => 'fa-pie-chart', 'value' => '¥' . ($Consumption == 0 ? 0 : $Consumption), 'color' => 'yellow']
];
$data = [
['value' => $orderinfos['cost'], 'name' => '商品成本'],
['value' => $orderinfos['coupon'], 'name' => '优惠券抵扣'],
['value' => $orderinfos['deduction'], 'name' => '积分抵扣'],
['value' => $extension, 'name' => '推广人佣金']
];
$this->assign(StatisticsModel::systemTable($where));
$this->assign(compact('where', 'trans', 'orderCount', 'orderDays', 'header', 'Statistic', 'ordinary', 'pink', 'recharge', 'data', 'seckill'));
$this->assign('price', StatisticsModel::getOrderPrice($where));
return $this->fetch();
}
}
\ No newline at end of file
<?php
namespace app\admin\controller\routine;
use app\admin\controller\AuthController;
use crmeb\services\CacheService;
use crmeb\services\FormBuilder as Form;
use crmeb\services\UtilService as Util;
use crmeb\services\JsonService as Json;
use think\facade\Route as Url;
use app\admin\model\routine\RoutineTemplate as RoutineTemplateModel;
/**
* 小程序模板消息控制器
* Class RoutineTemplate
* @package app\admin\controller\routine
*/
class RoutineTemplate extends AuthController
{
public function index()
{
$where = Util::getMore([
['name', ''],
['status', '']
], $this->request);
$this->assign('where', $where);
$this->assign(RoutineTemplateModel::SystemPage($where));
return $this->fetch();
}
/**
* 添加模板消息
* @return mixed
*/
public function create()
{
$f = array();
$f[] = Form::input('tempkey', '模板编号');
$f[] = Form::input('tempid', '模板ID');
$f[] = Form::input('name', '模板名');
$f[] = Form::input('content', '回复内容')->type('textarea');
$f[] = Form::radio('status', '状态', 1)->options([['label' => '开启', 'value' => 1], ['label' => '关闭', 'value' => 0]]);
$form = Form::make_post_form('添加模板消息', $f, Url::buildUrl('save'));
$this->assign(compact('form'));
return $this->fetch('public/form-builder');
}
public function save()
{
$data = Util::postMore([
'tempkey',
'tempid',
'name',
'content',
['status', 0]
]);
if ($data['tempkey'] == '') return Json::fail('请输入模板编号');
if ($data['tempkey'] != '' && RoutineTemplateModel::be($data['tempkey'], 'tempkey'))
return Json::fail('请输入模板编号已存在,请重新输入');
if ($data['tempid'] == '') return Json::fail('请输入模板ID');
if ($data['name'] == '') return Json::fail('请输入模板名');
if ($data['content'] == '') return Json::fail('请输入回复内容');
$data['add_time'] = time();
$data['type'] = 0;
RoutineTemplateModel::create($data);
CacheService::clear();
return Json::successful('添加模板消息成功!');
}
/**
* 编辑模板消息
* @param $id
* @return mixed|\think\response\Json|void
*/
public function edit($id)
{
if (!$id) return $this->failed('数据不存在');
$product = RoutineTemplateModel::get($id);
if (!$product) return Json::fail('数据不存在!');
$f = array();
$f[] = Form::input('tempkey', '模板编号', $product->getData('tempkey'))->disabled(1);
$f[] = Form::input('name', '模板名', $product->getData('name'))->disabled(1);
$f[] = Form::input('tempid', '模板ID', $product->getData('tempid'));
$f[] = Form::radio('status', '状态', $product->getData('status'))->options([['label' => '开启', 'value' => 1], ['label' => '关闭', 'value' => 0]]);
$form = Form::make_post_form('编辑模板消息', $f, Url::buildUrl('update', compact('id')));
$this->assign(compact('form'));
return $this->fetch('public/form-builder');
}
public function update($id)
{
$data = Util::postMore([
'tempid',
['status', 0]
]);
if ($data['tempid'] == '') return Json::fail('请输入模板ID');
if (!$id) return $this->failed('数据不存在');
$product = RoutineTemplateModel::get($id);
if (!$product) return Json::fail('数据不存在!');
RoutineTemplateModel::edit($data, $id);
CacheService::clear();
return Json::successful('修改成功!');
}
/**
* 删除模板消息
* @param $id
* @return \think\response\Json
*/
public function delete($id)
{
if (!$id) return Json::fail('数据不存在!');
if (!RoutineTemplateModel::del($id))
return Json::fail(RoutineTemplateModel::getErrorInfo('删除失败,请稍候再试!'));
else {
CacheService::clear();
return Json::successful('删除成功!');
}
}
}
\ No newline at end of file
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
<?php
namespace app\admin\controller\sms;
use app\admin\controller\AuthController;
use app\admin\model\system\SystemConfig;
use crmeb\services\{
CacheService, HttpService, JsonService, sms\Sms, UtilService
};
/**
* 短信账号
* Class SmsAdmin
* @package app\admin\controller\sms
*/
class SmsAdmin extends AuthController
{
/**
* @return string
*/
public function index()
{
return $this->fetch();
}
public function captcha()
{
if (!request()->isPost()) return JsonService::fail('发送失败');
$phone = request()->param('phone');
if (!trim($phone)) return JsonService::fail('请填写手机号');
$sms = new Sms('yunxin');
$res = json_decode(HttpService::getRequest($sms->getSmsUrl(), compact('phone')), true);
if (!isset($res['status']) && $res['status'] !== 200)
return JsonService::fail(isset($res['data']['message']) ? $res['data']['message'] : $res['msg']);
return JsonService::success(isset($res['data']['message']) ? $res['data']['message'] : '发送成功');
}
/**
* 修改/注册短信平台账号
*/
public function save()
{
list($account, $password, $phone, $code, $url, $sign) = UtilService::postMore([
['account', ''],
['password', ''],
['phone', ''],
['code', ''],
['url', ''],
['sign', ''],
], null, true);
$signLen = mb_strlen(trim($sign));
if (!strlen(trim($account))) return JsonService::fail('请填写账号');
if (!strlen(trim($password))) return JsonService::fail('请填写密码');
if (!$signLen) return JsonService::fail('请填写短信签名');
if ($signLen > 8) return JsonService::fail('短信签名最长为8位');
if (!strlen(trim($code))) return JsonService::fail('请填写验证码');
if (!strlen(trim($url))) return JsonService::fail('请填写域名');
$sms = new Sms('yunxin');
$status = $sms->register($account, md5(trim($password)), $url, $phone, $code, $sign);
if ($status['status'] == 400) return JsonService::fail('短信平台:' . $status['msg']);
CacheService::clear();
SystemConfig::setConfigSmsInfo($account, $password);
return JsonService::success('短信平台:' . $status['msg']);
}
}
\ No newline at end of file
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
<?php
/**
* Created by PhpStorm.
* User: Administrator
* Date: 2018/4/18 0018
* Time: 上午 10:44
*/
\ No newline at end of file
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册