更新3.1版本

This commit is contained in:
liaofei 2019-10-25 09:24:29 +08:00
parent 2c5802ff8e
commit 758706b465
6784 changed files with 4046 additions and 3925 deletions

3
.gitignore vendored
View File

@ -5,4 +5,5 @@
**/*.pid
runtime/
install.lock
public/uploads
public/uploads
remarks.txt

View File

@ -1,2 +0,0 @@
version=CRMEB-KYDT v3.01
version_code=132

View File

@ -1,33 +0,0 @@
版权所有 (c)2017-2027西安众邦网络科技有限公司 保留所有权利。
感谢您选择CrmEb开源客户管理+电商系统简称CRMEBCRMEB是国内最稳定、最强大、最先进的互联网电商平台解决方案之一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

398
README.md
View File

@ -15,86 +15,107 @@
<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>
### 如果对您有帮助,您可以点右上角 "Star" 支持一下 谢谢!
+ CRMEB后端程序下载地址
+ 码云:https://gitee.com/ZhongBangKeJi/CRMEB.git
+ github:https://github.com/crmeb/CRMEB
+ 微信小程序版前端界面
+ github:https://github.com/crmeb/CRMEB_WechatApplet_v3.0
+ 码云https://gitee.com/ZhongBangKeJi/CRMEB_WechatApplet_v3.0
+ H5版前端界面
+ github:https://github.com/crmeb/CRMEB-H5-v3.0
+ 码云https://gitee.com/ZhongBangKeJi/CRMEB-H5-v3.0
### 帮助文档:
https://help.crmeb.net/crmeb
### 论坛地址:
http://bbs.crmeb.net
QQ群: 710729856 <a target="_blank" href="//shang.qq.com/wpa/qunwpa?idkey=1794ec6e9fd6ac21bd6519d459d4495e824553693ab0a98a9899e61d68a494d0"><img border="0" src="//pub.idqqimg.com/wpa/images/group.png" alt="CRMEB微信开发四群" title="CRMEB微信开发四群"></a>
## 获得荣誉
![输入图片说明](https://images.gitee.com/uploads/images/2019/0805/111208_eb4fe823_892944.jpeg "WechatIMG2434.jpeg")
## 演示地址
演示站后台:[<a href='http://demo25.crmeb.net' target="_blank"> crmeb_v2.6 </a>]
<a href='http://demo25.crmeb.net' target="_blank">http://demo26.crmeb.net</a>
账号demo
密码crmeb.com
![输入图片说明](https://images.gitee.com/uploads/images/2019/0302/165543_801cf1e6_892944.jpeg "二维码.jpg")
## CRMEB推荐服务器配置
<table><tr><td>
入门级配置
```
CPU1核
内存1G
实例规格突发性能t5实例
带宽1M
系统CentOS 7.4 64位(推荐)
价格366元/年 933.3 元/三年
```
<a href="https://promotion.aliyun.com/ntms/yunparter/invite.html?userCode=dligum2z">查看服务器详情</a>
</td>
<td>
标准级配置
```
CPU2核
内存4G
实例规格突发性能t5实例
带宽2M
系统CentOS 7.4 64位(推荐)
价格936元/年 2386.8 元/三年
```
<a href="https://promotion.aliyun.com/ntms/yunparter/invite.html?userCode=dligum2z">查看服务器详情</a>
</td></tr></table>
## 项目介绍
基于ThinkPhp5.0+Vue+EasyWeChat 开发的一套CRMEB新零售商城系统
CRMEB系统就是集客户关系管理+营销电商系统能够真正帮助企业基于微信公众号、小程序、wap、pc、app等实现会员管理、数据分析,精准营销的电子商务管理系统。可满足企业新零售、批发、分销、预约、O2O、多店等各种业务需求
CRMEB的优势:快速积累客户、会员数据分析、智能转化客户、有效提高销售、会员维护;
CRMEB商城系统是基于ThinkPhp6.0+Vue开发的一套新零售移动电商系统CRMEB系统就是集客户关系管理+营销电商系统,能够快速积累客户、会员数据分析、智能转化客户、
有效提高销售、会员维护、网络营销的一款企业应用,包含商城、拼团、砍价、秒杀、优惠券、积分、分销等功能,更适合企业二次开发;
### 导航栏目
[前端下载](/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)
| [授权价格](https://s.click.taobao.com/W7hVkLw)
- - -
### :tw-1f427: QQ交流群
CRMEB微信开发6群: 341864990 <a target="_blank" href="//shang.qq.com/wpa/qunwpa?idkey=13e9ce8da34352ee2420576aef65ae377479ac0958fab2d4a6e01e8d2479621f"><img border="0" src="//pub.idqqimg.com/wpa/images/group.png" alt="CRMEB微信开发6群" title="CRMEB微信开发6群"></a>
|CRMEB微信开发3群:69741389<a target="_blank" href="//shang.qq.com/wpa/qunwpa?idkey=a8d2235bd79d65ea465e43ed81001d0641f875675ab80051118a43cfc468cbaa"><img border="0" src="//pub.idqqimg.com/wpa/images/group.png" alt="CRMEB微信开发3群" title="CRMEB微信开发3群"></a>
### 前后台演示
![前端演示](/readme/images/演示二维码.jpg)
#### :fire: 演示站后台:[<a href='http://demo.crmeb.net' target="_blank"> 查看 </a>]
<a href='http://demo.crmeb.net' target="_blank">http://demo.crmeb.net</a> 账号demo 密码crmeb.com
### CRMEB推荐阿里云服务器配置
阿里云领取2000元代金劵[<a href="https://promotion.aliyun.com/ntms/yunparter/invite.html?userCode=dligum2z">https://www.aliyun.com</a>]
## 技术亮点
<table><tr><td>
入门级配置
```
CPU1核
内存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>
标准级配置
```
CPU2核
内存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>
企业级配置
```
CPU4核
内存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>
### :tw-1f50a: 开源版使用须知
1.允许用于个人学习、毕业设计、教学案例、公益事业;
2.如果商用必须保留版权信息,请自觉遵守。开源版不合适商用,商用请购买商业版;
3.禁止将本项目的代码和资源进行任何形式的出售,产生的一切任何后果责任由侵权者自负。
### 商业版与 :tw-1f19a: 源版差异
![系统功能](/readme/images/商业版对比.jpg)
### 商业版[<a href='https://s.click.taobao.com/W7hVkLw' target="_blank"> 去看看 </a>]
[![输入图片说明](https://images.gitee.com/uploads/images/2019/0122/114739_a48f5bfd_892944.gif "tasheng jo(1).gif")](https://s.click.taobao.com/W7hVkLw)
商业授权及定制服务版http://www.crmeb.com
### 技术亮点
~~~
1.后台应用form-builder PHP快速生成现代化表单
2.前端以Vue + RequireJS模块化开发
@ -109,212 +130,51 @@ CPU2核
11.对接公众号和小程序,并且数据同步;
12.内置客服系统;
13.高频数据缓存;
14.数据备份和恢复
15.一键安装;
14.数据备份和恢复;
15.后台文件管理,带代码高亮,无需开发工具在线编辑代码;
16.标准接口、前后端分离,二次开发更方便;
17.长连接减少CPU及内存使用及网络堵塞减少请求响应时长
18.无缝事件机制行为扩展更方便,方便二次开发;
19.支持队列降低流量高峰,解除耦合,高可用;
16.一键安装自动检查系统环境一键安装;
~~~
## 功能
### 系统功能
![系统功能](/readme/images/系统功能.jpg)
1.商品: 能够对商品的状态分类管理 (出售中、待上架、库存中、已售馨、库存警戒、回收站)、添加产品、添加商品分类等功能
2.会员:站内会员的管理 (发放优惠劵、发通知、发图文消息、增加余额、会员行为详情)、站内通知 、微信端用户管理 (微信用
户的管理、分组、行为观察、添加标签) 等功能
3.营销:能够管理优惠的发放和制作、用户积分的统计使用情况、秒杀产品的管理等
4.财务:能够对用户的消费、充值、返佣的记录
5.订单:能够完成用户的订单管理(发货、订单详情、修改订单、订单备注、订单记录、订单退款) 、售后服务 (评论的回复与删除)
6.分销:后台有分销统计管理,分销可以设置人人分销和指定人分销,也可以自己稍微开发一下修改规则,例如下单后成为分销等
### 页面展示
![展示图](/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")
7.数据统计图表统计分析(财务统计、产品统计、会员统计、营销统计、分销统计、交易统计等)
8.设置:能够完成管理员对网站的商品资料(添加大类、添加小类、商品添加、属性快速生成、商品审查)、商品交易(外理订单、发货查询)、会员管理(会员审查)、操作管理(管理员添加、管理员审查、管理员退出)、系统配置、后台通知等功能
9.内容:管理文章分类 (添加分类、删除分类、修改分类) 、 管理文章
10.维护:查看系统日志、文件变动效验、刷新网站缓存、在线更新系统、清除数据、文件管理等功能
### 获得荣誉
![输入图片说明](https://images.gitee.com/uploads/images/2019/0805/111208_eb4fe823_892944.jpeg "WechatIMG2434.jpeg")
11.权限管理:可以创建不同身份,不同管理员,同一个管理员可以拥有多重身份,权限可以控制到每一个控制器函数,例如:张三
1.可以控制他可以查看产品,但不能编辑产品;
2.可以添加产品,但不能删除产品;
3.可以查看用户但不能给用户发信息、加积分、开通分销等等;
。。。灵活应用,权限想怎么配就怎么配
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)。
## 付费版
淘宝超值版:
CRMEB微信公众号小程序打通v2.6版:除了以上功能还带砍价、拼团功能,永久免费升级提供升级包
还有定制开发服务例如预约系统、O2O、付费阅读、多店版、多商家版
### 详情[<a href='https://s.click.taobao.com/W7hVkLw' target="_blank"> 进入淘宝 </a>]
[![输入图片说明](https://images.gitee.com/uploads/images/2019/0122/114739_a48f5bfd_892944.gif "tasheng jo(1).gif")](https://s.click.taobao.com/W7hVkLw)
官网线下定制服务版http://www.crmeb.com
## 系统组件开源项目
### 系统组件开源项目
#### form-builder
tp5 PHP表单生成器快速生成现代化的form表单。包含复选框、单选框、输入框、下拉选择框等元素以及,省市区三级联动,时间选择,日期选择,颜色选择,文件/图片上传等功能。
form-builder : https://github.com/xaboy/form-builder
## 特别鸣谢
感谢以下的项目,排名不分先后
### 参与开发
ThinkPHPhttp://www.thinkphp.cn
请提交 [CRMEB](https://gitee.com/ZhongBangKeJi/CRMEB/pulls)。
Bootstraphttp://getbootstrap.com
jQueryhttp://jquery.com
iViewhttps://www.iviewui.com
Vuehttps://cn.vuejs.org/
font-awesome https://fontawesome.com/?from=io
requirejs http://requirejs.org/
umeditorhttp://ueditor.baidu.com/website/umeditor.html
## 版权信息
### 特别鸣谢
[samoye](https://gitee.com/yizhisamoye)
| [Stone Bai](https://gitee.com/bys1123)
### 版权信息
本项目包含的第三方源码和二进制文件之版权信息另行标注。

View File

@ -1,43 +0,0 @@
<?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 (env("APP_DEBUG") == true) { //如是开启调试,就走原来的方法
return parent::render($request, $e);
} else {
if ($e instanceof \Exception && request()->isAjax()) {
return app('json')->fail(['code' => $e->getCode(), 'message' => $e->getMessage(), 'file' => $e->getFile()]);
} else {
$title = '系统错误';
$msg = addslashes($e->getMessage());
return \response(view('public/500', compact('title', 'msg'))->getContent());
}
}
}
}

View File

@ -1,340 +0,0 @@
<?php
/**
* Created by PhpStorm.
* User: Administrator
* Date: 2018/4/16 0016
* Time: 10:39
*/
namespace app\admin\controller\ump;
use app\admin\controller\AuthController;
use crmeb\services\JsonService;
use crmeb\services\UtilService as Util;
use crmeb\services\FormBuilder as Form;
use crmeb\services\UtilService;
use crmeb\traits\CurdControllerTrait;
use crmeb\services\JsonService as Json;
use crmeb\services\UploadService as Upload;
use think\facade\Route as Url;
use app\admin\model\store\StoreProduct as ProductModel;
use app\admin\model\ump\StoreBargain as StoreBargainModel;
use app\admin\model\system\SystemAttachment;
//砍价
class StoreBargain extends AuthController
{
use CurdControllerTrait;
protected $bindModel = StoreBargainModel::class;
/**
* 显示资源列表
*
* @return \think\Response
*/
public function index()
{
$where = Util::getMore([
['status',''],
['store_name',''],
['export',0],
['data',''],
],$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('countBargain',StoreBargainModel::getCountBargain());
$this->assign('limitTimeList',$limitTimeList);
$this->assign(StoreBargainModel::systemPage($where));
$this->assign('bargainId',StoreBargainModel::getBargainIdAll($where));
return $this->fetch();
}
/**
* 异步获取砍价数据
*/
public function get_bargain_list(){
$where=Util::getMore([
['page',1],
['limit',20],
['export',0],
['store_name',''],
['status',''],
['data','']
]);
$bargainList = StoreBargainModel::systemPage($where);
if(is_object($bargainList['list'])) $bargainList['list'] = $bargainList['list']->toArray();
$data = $bargainList['list']['data'];
foreach ($data as $k=>$v){
$data[$k]['_stop_time'] = date('Y/m/d H:i:s',$v['stop_time']);
}
return Json::successlayui(['count'=>$bargainList['list']['total'],'data'=>$data]);
}
/**
* 上传图片
* @return \think\response\Json
*/
public function upload()
{
$res = Upload::image('file','store/bargain/'.date('Ymd'));
if(is_array($res)){
SystemAttachment::attachmentAdd($res['name'],$res['size'],$res['type'],$res['dir'],$res['thumb_path'],3,$res['image_type'],$res['time']);
return Json::successful('图片上传成功!',['name'=>$res['name'],'url'=>Upload::pathToUrl($res['thumb_path'])]);
}else
return Json::fail($res);
}
/**
* 添加砍价
* @param int $id
* @return \think\Response
*/
public function create()
{
$f = array();
$f[] = Form::input('title','砍价活动名称');
$f[] = Form::input('info','砍价活动简介')->type('textarea');
$f[] = Form::input('store_name','砍价产品名称');
$f[] = Form::input('unit_name','单位')->placeholder('个、位');
$f[] = Form::dateTimeRange('section_time','活动时间');
$f[] = Form::frameImageOne('image','产品主图片(305*305px)',Url::buildUrl('admin/widget.images/index',array('fodder'=>'image')))->icon('image')->width('100%')->height('500px');
$f[] = Form::frameImages('images','产品轮播图(640*640px)',Url::buildUrl('admin/widget.images/index',array('fodder'=>'images')))->maxLength(5)->icon('images')->width('100%')->height('500px');
$f[] = Form::number('price','显示原价')->min(0)->col(12);
$f[] = Form::number('min_price','最低购买价')->min(0);
$f[] = Form::number('bargain_max_price','单次砍价的最大金额')->min(0)->col(12);
$f[] = Form::number('bargain_min_price','单次砍价的最小金额')->min(0)->col(12);
$f[] = Form::number('cost','成本价')->min(0)->col(12);
$f[] = Form::number('bargain_num','单次砍价的次数')->min(0)->col(12);
$f[] = Form::number('stock','库存')->min(0)->col(12);
$f[] = Form::number('sales','销量')->min(0)->col(12);
$f[] = Form::number('sort','排序')->col(12);
$f[] = Form::number('num','单次允许购买数量')->col(12);
$f[] = Form::number('give_integral','赠送积分')->min(0)->col(12);
$f[] = Form::number('postage','邮费')->min(0)->col(12);
$f[] = Form::radio('is_postage','是否包邮',1)->options([['label'=>'是','value'=>1],['label'=>'否','value'=>0]])->col(12);
$f[] = Form::radio('is_hot','热门推荐',1)->options([['label'=>'开启','value'=>1],['label'=>'关闭','value'=>0]])->col(12);
$f[] = Form::radio('status','活动状态',1)->options([['label'=>'开启','value'=>1],['label'=>'关闭','value'=>0]])->col(12);
$form = Form::make_post_form('添加用户通知',$f,Url::buildUrl('update'));
$this->assign(compact('form'));
return $this->fetch('public/form-builder');
}
/**
* 显示编辑资源表单页.
*
* @param int $id
* @return \think\Response
*/
public function edit($id)
{
if(!$id) return $this->failed('数据不存在');
$product = StoreBargainModel::get($id);
if(!$product) return $this->failed('数据不存在!');
$f = array();
$f[] = Form::input('title','砍价活动名称',$product->getData('title'));
$f[] = Form::hidden('product_id',$product->getData('product_id'));
$f[] = Form::input('info','砍价活动简介',$product->getData('info'))->type('textarea');
$f[] = Form::input('store_name','砍价产品名称',$product->getData('store_name'));
$f[] = Form::input('unit_name','单位',$product->getData('unit_name'))->placeholder('个、位');
$f[] = Form::dateTimeRange('section_time','活动时间',date("Y-m-d H:i:s",$product->getData('start_time')),date("Y-m-d H:i:s",$product->getData('stop_time')));//->format("yyyy-MM-dd HH:mm:ss");
$f[] = Form::frameImageOne('image','产品主图片(305*305px)',Url::buildUrl('admin/widget.images/index',array('fodder'=>'image')),$product->getData('image'))->icon('image')->width('100%')->height('500px');
$f[] = Form::frameImages('images','产品轮播图(640*640px)',Url::buildUrl('admin/widget.images/index',array('fodder'=>'images')),json_decode($product->getData('images'),1))->maxLength(5)->icon('images')->width('100%')->height('500px');
$f[] = Form::number('price','显示原价',$product->getData('price'))->min(0)->col(12);
$f[] = Form::number('min_price','最低购买价',$product->getData('min_price'))->min(0)->col(12);
$f[] = Form::number('bargain_max_price','单次砍价的最大金额',$product->getData('bargain_max_price'))->min(0)->col(12);
$f[] = Form::number('bargain_min_price','单次砍价的最小金额',$product->getData('bargain_min_price'))->min(0)->col(12);
$f[] = Form::number('cost','成本价',$product->getData('cost'))->min(0)->col(12);
$f[] = Form::number('bargain_num','单次砍价的次数',$product->getData('bargain_num'))->min(0)->col(12);
$f[] = Form::number('stock','库存',$product->getData('stock'))->min(0)->col(12);
$f[] = Form::number('sales','销量',$product->getData('sales'))->min(0)->col(12);
$f[] = Form::number('sort','排序',$product->getData('sort'))->col(12);
$f[] = Form::number('num','单次允许购买数量',$product->getData('num'))->col(12);
$f[] = Form::number('give_integral','赠送积分',$product->getData('give_integral'))->min(0)->col(12);
$f[] = Form::number('postage','邮费',$product->getData('postage'))->min(0)->col(12);
$f[] = Form::radio('is_postage','是否包邮',$product->getData('is_postage'))->options([['label'=>'是','value'=>1],['label'=>'否','value'=>0]])->col(12);
$f[] = Form::radio('is_hot','热门推荐',$product->getData('is_hot'))->options([['label'=>'开启','value'=>1],['label'=>'关闭','value'=>0]])->col(12);
$f[] = Form::radio('status','活动状态',$product->getData('status'))->options([['label'=>'开启','value'=>1],['label'=>'关闭','value'=>0]])->col(12);
$form = Form::make_post_form('添加用户通知',$f,Url::buildUrl('update',array('id'=>$id)));
$this->assign(compact('form'));
return $this->fetch('public/form-builder');
}
/**
* 保存更新的资源
* @param string $id
*/
public function update($id='')
{
$data = UtilService::postMore([
['title',''],
['info',''],
['store_name',''],
['unit_name',''],
['section_time',[]],
['image',''],
['images',[]],
['price',0],
['min_price',0],
['bargain_max_price',0],
['bargain_min_price',0],
['cost',0],
['bargain_num',0],
['stock',0],
['sales',0],
['sort',0],
['num',0],
['give_integral',0],
['postage',0],
['is_postage',0],
['is_hot',0],
['status',0],
['product_id',0]
]);
if($data['title'] == '') return JsonService::fail('请输入砍价活动名称');
if($data['info'] == '') return JsonService::fail('请输入砍价活动简介');
if($data['store_name'] == '') return JsonService::fail('请输入砍价产品名称');
if($data['unit_name'] == '') return JsonService::fail('请输入产品单位');
if(count($data['section_time'])<1) return JsonService::fail('请选择活动时间');
if(!$data['section_time'][0]) return JsonService::fail('请选择活动时间');
if(!$data['section_time'][1]) return JsonService::fail('请选择活动时间');
$data['start_time'] = strtotime($data['section_time'][0]);
$data['stop_time'] = strtotime($data['section_time'][1]);
unset($data['section_time']);
if(!($data['image'])) return JsonService::fail('请选择推荐图');
if(count($data['images'])<1) return JsonService::fail('请选择轮播图');
$data['images'] = json_encode($data['images']);
if($data['price'] == '' || $data['price'] < 0) return JsonService::fail('请输入砍价金额');
if($data['min_price'] == '' || $data['min_price'] < 0) return JsonService::fail('请输入砍价最低金额');
if($data['bargain_max_price'] == '' || $data['bargain_max_price'] < 0) return JsonService::fail('请输入用户单次砍价的最大金额');
if($data['bargain_min_price'] == '' || $data['bargain_min_price'] < 0) return JsonService::fail('请输入用户单次砍价的最小金额');
if($data['cost'] == '' || $data['cost'] < 0) return JsonService::fail('请输入成本价');
if($data['bargain_num'] == '' || $data['bargain_num'] < 0) return JsonService::fail('请输入用户单次砍价的次数');
if($data['stock'] == '' || $data['stock'] < 0) return JsonService::fail('请输入库存');
if($data['num'] == '' || $data['num'] < 0) return JsonService::fail('请输入单次购买的砍价产品数量');
unset($data['img']);
if($id){
$product = StoreBargainModel::get($id);
if(!$product) return Json::fail('数据不存在!');
$res = StoreBargainModel::edit($data,$id);
if($res) return JsonService::successful('修改成功');
else return JsonService::fail('修改失败');
}
else{
$data['add_time'] = time();
$res = StoreBargainModel::create($data);
if($res) return JsonService::successful('添加成功');
else return JsonService::fail('添加成功');
}
}
/**
* 删除指定资源
*
* @param int $id
* @return \think\Response
*/
public function delete($id)
{
if(!$id) return Json::fail('数据不存在');
$product = StoreBargainModel::get($id);
if(!$product) return Json::fail('数据不存在!');
if($product['is_del']) return Json::fail('已删除!');
$data['is_del'] = 1;
if(StoreBargainModel::edit($data,$id))
return Json::successful('删除成功!');
else
return Json::fail(StoreBargainModel::getErrorInfo('删除失败,请稍候再试!'));
}
/**
* 显示内容窗口
* @param $id
* @return mixed|\think\response\Json|void
*/
public function edit_content($id){
if(!$id) return $this->failed('数据不存在');
$seckill = StoreBargainModel::get($id);
if(!$seckill) return $this->failed('数据不存在');
$this->assign([
'content'=>StoreBargainModel::where('id',$id)->value('description'),
'field'=>'description',
'action'=>Url::buildUrl('change_field',['id'=>$id,'field'=>'description'])
]);
return $this->fetch('public/edit_content');
}
public function edit_rule($id){
if(!$id) return $this->failed('数据不存在');
$seckill = StoreBargainModel::get($id);
if(!$seckill) return $this->failed('数据不存在');
$this->assign([
'content'=>StoreBargainModel::where('id',$id)->value('rule'),
'field'=>'rule',
'action'=>Url::buildUrl('change_field',['id'=>$id,'field'=>'rule'])
]);
return $this->fetch('public/edit_content');
}
/**
* 开启砍价产品
* @param int $id
* @return mixed|\think\response\Json|void
*/
public function bargain($id = 0){
if(!$id) return $this->failed('数据不存在');
$product = ProductModel::get($id);
if(!$product) return Json::fail('数据不存在!');
$f = array();
$f[] = Form::input('title','砍价活动名称');
$f[] = Form::input('info','砍价活动简介')->type('textarea');
$f[] = Form::hidden('product_id',$product->getData('id'));
$f[] = Form::input('store_name','砍价产品名称',$product->getData('store_name'));
$f[] = Form::input('unit_name','单位',$product->getData('unit_name'))->placeholder('个、位');
$f[] = Form::dateTimeRange('section_time','活动时间');//->format("yyyy-MM-dd HH:mm:ss");
$f[] = Form::frameImageOne('image','产品主图片(305*305px)',Url::buildUrl('admin/widget.images/index',array('fodder'=>'image')),$product->getData('image'))->icon('image')->width('100%')->height('500px');
$f[] = Form::frameImages('images','产品轮播图(640*640px)',Url::buildUrl('admin/widget.images/index',array('fodder'=>'images')),json_decode($product->getData('slider_image'),1))->maxLength(5)->icon('images')->width('100%')->height('500px');
$f[] = Form::number('price','砍价金额')->min(0)->col(12);
$f[] = Form::number('min_price','砍价最低金额',0)->min(0)->col(12);
$f[] = Form::number('bargain_max_price','单次砍价的最大金额',10)->min(0)->col(12);
$f[] = Form::number('bargain_min_price','单次砍价的最小金额',0.01)->min(0)->precision(2)->col(12);
$f[] = Form::number('cost','成本价',$product->getData('cost'))->min(0)->col(12);
$f[] = Form::number('bargain_num','单次砍价的次数',1)->min(0)->col(12);
$f[] = Form::number('stock','库存',$product->getData('stock'))->min(1)->col(12);
$f[] = Form::number('sales','销量',$product->getData('sales'))->min(0)->col(12);
$f[] = Form::number('sort','排序',$product->getData('sort'))->col(12);
$f[] = Form::number('num','单次购买的砍价产品数量',1)->col(12);
$f[] = Form::number('give_integral','赠送积分',$product->getData('give_integral'))->min(0)->col(12);
$f[] = Form::number('postage','邮费',$product->getData('postage'))->min(0)->col(12);
$f[] = Form::radio('is_postage','是否包邮',$product->getData('is_postage'))->options([['label'=>'是','value'=>1],['label'=>'否','value'=>0]])->col(12);
$f[] = Form::radio('is_hot','热门推荐',$product->getData('is_hot'))->options([['label'=>'开启','value'=>1],['label'=>'关闭','value'=>0]])->col(12);
$f[] = Form::radio('status','活动状态',1)->options([['label'=>'开启','value'=>1],['label'=>'关闭','value'=>0]])->col(12);
$form = Form::make_post_form('开启砍价活动',$f,Url::buildUrl('update'));
$this->assign(compact('form'));
return $this->fetch('public/form-builder');
}
/**
* 修改砍价状态
* @param $status
* @param int $id
*/
public function set_bargain_status($status,$id = 0){
if(!$id) return JsonService::fail('参数错误');
$res = StoreBargainModel::edit(['status'=>$status],$id);
if($res) return JsonService::successful('修改成功');
else return JsonService::fail('修改失败');
}
}

View File

@ -1,395 +0,0 @@
<?php
namespace app\admin\controller\ump;
use app\admin\controller\AuthController;
use crmeb\services\FormBuilder as Form;
use crmeb\traits\CurdControllerTrait;
use crmeb\services\UtilService as Util;
use crmeb\services\JsonService as Json;
use crmeb\services\UploadService as Upload;
use app\admin\model\store\StoreProduct as ProductModel;
use app\admin\model\ump\StoreCombinationAttr;
use app\admin\model\ump\StoreCombinationAttrResult;
use app\admin\model\ump\StoreCombination as StoreCombinationModel;
use think\facade\Route as Url;
use app\admin\model\system\SystemAttachment;
use app\admin\model\ump\StorePink;
/**
* 拼团管理
* Class StoreCombination
* @package app\admin\controller\store
*/
class StoreCombination extends AuthController
{
use CurdControllerTrait;
protected $bindModel = StoreCombinationModel::class;
/**
* @return mixed
*/
public function index()
{
$this->assign('countCombination',StoreCombinationModel::getCombinationCount());
$this->assign(StoreCombinationModel::getStatistics());
$this->assign('combinationId',StoreCombinationModel::getCombinationIdAll());
return $this->fetch();
}
public function save_excel(){
$where = Util::getMore([
['is_show',''],
['store_name',''],
]);
StoreCombinationModel::SaveExcel($where);
}
/**
* 异步获取拼团数据
*/
public function get_combination_list(){
$where=Util::getMore([
['page',1],
['limit',20],
['export',0],
['is_show',''],
['is_host',''],
['store_name','']
]);
$combinationList = StoreCombinationModel::systemPage($where);
if(is_object($combinationList['list'])) $combinationList['list'] = $combinationList['list']->toArray();
$data = $combinationList['list']['data'];
foreach ($data as $k=>$v){
$data[$k]['_stop_time'] = date('Y/m/d H:i:s',$v['stop_time']);
}
return Json::successlayui(['count'=>$combinationList['list']['total'],'data'=>$data]);
}
public function combination($id = 0){
if(!$id) return $this->failed('数据不存在');
$product = ProductModel::get($id);
if(!$product) return Json::fail('数据不存在!');
$f = array();
$f[] = Form::hidden('product_id',$id);
// $f[] = Form::select('product_id','产品名称')->setOptions(function(){
// $list = ProductModel::getTierList();
// foreach ($list as $menu){
// $menus[] = ['value'=>$menu['id'],'label'=>$menu['store_name'].'/'.$menu['id']];
// }
// return $menus;
// })->filterable(1);
$f[] = Form::input('title','拼团名称',$product->getData('store_name'));
$f[] = Form::input('info','拼团简介',$product->getData('store_info'))->type('textarea');
$f[] = Form::input('unit_name','单位',$product->getData('unit_name'))->placeholder('个、位');
$f[] = Form::dateTimeRange('section_time','拼团时间');
$f[] = Form::frameImageOne('image','产品主图片(305*305px)',Url::buildUrl('admin/widget.images/index',array('fodder'=>'image')),$product->getData('image'))->icon('image')->width('100%')->height('500px');
$f[] = Form::frameImages('images','产品轮播图(640*640px)',Url::buildUrl('admin/widget.images/index',array('fodder'=>'images')),json_decode($product->getData('slider_image')))->maxLength(5)->icon('images')->width('100%')->height('500px');
$f[] = Form::number('price','拼团价')->min(0)->col(12);
$f[] = Form::number('people','拼团人数')->min(2)->col(12);
$f[] = Form::number('stock','库存',$product->getData('stock'))->min(0)->precision(0)->col(12);
$f[] = Form::number('sales','销量',$product->getData('sales'))->min(0)->precision(0)->col(12);
$f[] = Form::number('sort','排序')->col(12);
$f[] = Form::number('postage','邮费',$product->getData('postage'))->min(0)->col(12);
$f[] = Form::radio('is_postage','是否包邮',$product->getData('is_postage'))->options([['label'=>'是','value'=>1],['label'=>'否','value'=>0]])->col(12);
$f[] = Form::radio('is_host','热门推荐',1)->options([['label'=>'开启','value'=>1],['label'=>'关闭','value'=>0]])->col(12);
$f[] = Form::radio('is_show','活动状态',1)->options([['label'=>'开启','value'=>1],['label'=>'关闭','value'=>0]])->col(12);
$form = Form::make_post_form('添加用户通知',$f,Url::buildUrl('save'));
$this->assign(compact('form'));
return $this->fetch('public/form-builder');
}
/**
* 显示创建资源表单页.
*
* @return \think\Response
*/
public function create()
{
$f = array();
$f[] = Form::select('product_id','产品名称')->setOptions(function(){
$list = ProductModel::getTierList();
foreach ($list as $menu){
$menus[] = ['value'=>$menu['id'],'label'=>$menu['store_name'].'/'.$menu['id']];
}
return $menus;
})->filterable(1);
$f[] = Form::input('title','拼团名称');
$f[] = Form::input('info','拼团简介')->type('textarea');
$f[] = Form::input('unit_name','单位')->placeholder('个、位');
$f[] = Form::dateTimeRange('section_time','拼团时间');
$f[] = Form::frameImageOne('image','产品主图片(305*305px)',Url::buildUrl('admin/widget.images/index',array('fodder'=>'image')))->icon('image')->width('100%')->height('500px');
$f[] = Form::frameImages('images','产品轮播图(640*640px)',Url::buildUrl('admin/widget.images/index',array('fodder'=>'images')))->maxLength(5)->icon('images')->width('100%')->height('500px');
$f[] = Form::number('price','拼团价')->min(0)->col(12);
$f[] = Form::number('people','拼团人数')->min(2)->col(12);
$f[] = Form::number('stock','库存')->min(0)->precision(0)->col(12);
$f[] = Form::number('sales','销量')->min(0)->precision(0)->col(12);
$f[] = Form::number('sort','排序')->col(12);
$f[] = Form::number('postage','邮费')->min(0)->col(12);
$f[] = Form::radio('is_postage','是否包邮',1)->options([['label'=>'是','value'=>1],['label'=>'否','value'=>0]])->col(12);
$f[] = Form::radio('is_host','热门推荐',1)->options([['label'=>'开启','value'=>1],['label'=>'关闭','value'=>0]])->col(12);
$f[] = Form::radio('is_show','活动状态',1)->options([['label'=>'开启','value'=>1],['label'=>'关闭','value'=>0]])->col(12);
$form = Form::make_post_form('添加用户通知',$f,Url::buildUrl('save'));
$this->assign(compact('form'));
return $this->fetch('public/form-builder');
}
/**
* 保存新建的资源
* @param int $id
*/
public function save($id = 0)
{
$data = Util::postMore([
'product_id',
'title',
'info',
['unit_name','个'],
['image',''],
['images',[]],
['section_time',[]],
'postage',
'price',
'people',
'sort',
'stock',
'sales',
['is_show',0],
['is_host',0],
['is_postage',0],
]);
if(!$data['title']) return Json::fail('请输入拼团名称');
if(!$data['info']) return Json::fail('请输入拼团简介');
if(!$data['image']) return Json::fail('请上传产品图片');
if(count($data['images'])<1) return Json::fail('请上传产品轮播图');
if($data['price'] == '' || $data['price'] < 0) return Json::fail('请输入产品售价');
if($data['people'] == '' || $data['people'] < 1) return Json::fail('请输入拼团人数');
if(count($data['section_time'])<1) return Json::fail('请选择活动时间');
if($data['stock'] == '' || $data['stock'] < 0) return Json::fail('请输入库存');
$data['images'] = json_encode($data['images']);
$data['start_time'] = strtotime($data['section_time'][0]);
$data['stop_time'] = strtotime($data['section_time'][1]);
unset($data['section_time']);
if($id){
$product = StoreCombinationModel::get($id);
if(!$product) return Json::fail('数据不存在!');
$data['product_id']=$product['product_id'];
StoreCombinationModel::edit($data,$id);
return Json::successful('编辑成功!');
}else{
$data['add_time'] = time();
$data['description'] = '';
StoreCombinationModel::create($data);
return Json::successful('添加拼团成功!');
}
}
/**
* 显示编辑资源表单页.
*
* @param int $id
* @return \think\Response
*/
public function edit($id)
{
if(!$id) return $this->failed('数据不存在');
$product = StoreCombinationModel::get($id);
if(!$product) return Json::fail('数据不存在!');
$f = array();
$f[] = Form::hidden('product_id',$product->getData('product_id'));
$f[] = Form::input('title','拼团名称',$product->getData('title'));
$f[] = Form::input('info','拼团简介',$product->getData('info'))->type('textarea');
$f[] = Form::input('unit_name','单位',$product->getData('unit_name'))->placeholder('个、位');
$f[] = Form::dateTimeRange('section_time','拼团时间',date("Y-m-d H:i:s",$product->getData('start_time')),date("Y-m-d H:i:s",$product->getData('stop_time')));
$f[] = Form::frameImageOne('image','产品主图片(305*305px)',Url::buildUrl('admin/widget.images/index',array('fodder'=>'image')),$product->getData('image'))->icon('image')->width('100%')->height('500px');
$f[] = Form::frameImages('images','产品轮播图(640*640px)',Url::buildUrl('admin/widget.images/index',array('fodder'=>'images')),json_decode($product->getData('images')))->maxLength(5)->icon('images')->width('100%')->height('500px');
$f[] = Form::number('price','拼团价',$product->getData('price'))->min(0)->col(12);
$f[] = Form::number('people','拼团人数',$product->getData('people'))->min(2)->col(12);
$f[] = Form::number('stock','库存',$product->getData('stock'))->min(0)->precision(0)->col(12);
$f[] = Form::number('sales','销量',$product->getData('sales'))->min(0)->precision(0)->col(12);
$f[] = Form::number('sort','排序',$product->getData('sort'))->col(12);
$f[] = Form::number('postage','邮费',$product->getData('postage'))->min(0)->col(12);
$f[] = Form::radio('is_postage','是否包邮',$product->getData('is_postage'))->options([['label'=>'是','value'=>1],['label'=>'否','value'=>0]])->col(12);
$f[] = Form::radio('is_host','热门推荐',$product->getData('is_host'))->options([['label'=>'开启','value'=>1],['label'=>'关闭','value'=>0]])->col(12);
$f[] = Form::radio('is_show','活动状态',$product->getData('is_show'))->options([['label'=>'开启','value'=>1],['label'=>'关闭','value'=>0]])->col(12);
$form = Form::make_post_form('添加用户通知',$f,Url::buildUrl('save',compact('id')));
$this->assign(compact('form'));
return $this->fetch('public/form-builder');
// $this->assign([
// 'title'=>'编辑产品','rules'=>$this->read($id)->getContent(),
// 'action'=>Url::buildUrl('update',array('id'=>$id))
// ]);
// return $this->fetch('public/common_form');
}
/**
* 删除指定资源
*
* @param int $id
* @return \think\Response
*/
public function delete($id)
{
if(!$id) return $this->failed('数据不存在');
$product = StoreCombinationModel::get($id);
if(!$product) return Json::fail('数据不存在!');
if($product['is_del']) return Json::fail('已删除!');
$data['is_del'] = 1;
if(!StoreCombinationModel::edit($data,$id))
return Json::fail(StoreCombinationModel::getErrorInfo('删除失败,请稍候再试!'));
else
return Json::successful('删除成功!');
}
/**
* 属性页面
* @param $id
* @return mixed|void
*/
public function attr($id)
{
if(!$id) return $this->failed('数据不存在!');
$result = StoreCombinationAttrResult::getResult($id);
$image = StoreCombinationModel::where('id',$id)->value('image');
$this->assign(compact('id','result','product','image'));
return $this->fetch();
}
/**
* 生成属性
* @param int $id
*/
public function is_format_attr($id = 0){
if(!$id) return Json::fail('产品不存在');
list($attr,$detail) = Util::postMore([
['items',[]],
['attrs',[]]
],$this->request,true);
$product = StoreCombinationModel::get($id);
if(!$product) return Json::fail('产品不存在');
$attrFormat = attrFormat($attr)[1];
if(count($detail)){
foreach ($attrFormat as $k=>$v){
foreach ($detail as $kk=>$vv){
if($v['detail'] == $vv['detail']){
$attrFormat[$k]['price'] = $vv['price'];
$attrFormat[$k]['sales'] = $vv['sales'];
$attrFormat[$k]['pic'] = $vv['pic'];
$attrFormat[$k]['check'] = false;
break;
}else{
$attrFormat[$k]['price'] = '';
$attrFormat[$k]['sales'] = '';
$attrFormat[$k]['pic'] = $product['image'];
$attrFormat[$k]['check'] = true;
}
}
}
}else{
foreach ($attrFormat as $k=>$v){
$attrFormat[$k]['price'] = $product['price'];
$attrFormat[$k]['sales'] = $product['stock'];
$attrFormat[$k]['pic'] = $product['image'];
$attrFormat[$k]['check'] = false;
}
}
return Json::successful($attrFormat);
}
/**
* 添加 修改属性
* @param $id
*/
public function set_attr($id)
{
if(!$id) return $this->failed('产品不存在!');
list($attr,$detail) = Util::postMore([
['items',[]],
['attrs',[]]
],$this->request,true);
$res = StoreCombinationAttr::createProductAttr($attr,$detail,$id);
if($res)
return $this->successful('编辑属性成功!');
else
return $this->failed(StoreCombinationAttr::getErrorInfo());
}
/**
* 清除属性
* @param $id
*/
public function clear_attr($id)
{
if(!$id) return $this->failed('产品不存在!');
if(false !== StoreCombinationAttr::clearProductAttr($id) && false !== StoreCombinationAttrResult::clearResult($id))
return $this->successful('清空产品属性成功!');
else
return $this->failed(StoreCombinationAttr::getErrorInfo('清空产品属性失败!'));
}
public function edit_content($id){
if(!$id) return $this->failed('数据不存在');
$product = StoreCombinationModel::get($id);
if(!$product) return Json::fail('数据不存在!');
$this->assign([
'content'=>StoreCombinationModel::where('id',$id)->value('description'),
'field'=>'description',
'action'=>Url::buildUrl('change_field',['id'=>$id,'field'=>'description'])
]);
return $this->fetch('public/edit_content');
}
/**
* 上传图片
* @return \think\response\Json
*/
public function upload()
{
$res = Upload::image('file','store/product/'.date('Ymd'));
if(is_array($res)){
SystemAttachment::attachmentAdd($res['name'],$res['size'],$res['type'],$res['dir'],$res['thumb_path'],2,$res['image_type'],$res['time']);
return Json::successful('图片上传成功!',['name'=>$res['name'],'url'=>Upload::pathToUrl($res['thumb_path'])]);
}else
return Json::fail($res);
}
/**拼团列表
* @return mixed
*/
public function combina_list()
{
$where = Util::getMore([
['status',''],
['data',''],
],$this->request);
$this->assign('where',$where);
$this->assign(StorePink::systemPage($where));
return $this->fetch();
}
/**拼团人列表
* @return mixed
*/
public function order_pink($id){
if(!$id) return $this->failed('数据不存在');
$StorePink = StorePink::getPinkUserOne($id);
if(!$StorePink) return $this->failed('数据不存在!');
$list = StorePink::getPinkMember($id);
$list[] = $StorePink;
$this->assign('list',$list);
return $this->fetch();
}/**
* 修改拼团状态
* @param $status
* @param int $idd
*/
public function set_combination_status($status,$id = 0){
if(!$id) return Json::fail('参数错误');
$res = StoreCombinationModel::edit(['is_show'=>$status],$id);
if($res) return Json::successful('修改成功');
else return Json::fail('修改失败');
}
}

View File

@ -1,45 +0,0 @@
<?php
namespace app\admin\model\system;
use crmeb\traits\ModelTrait;
use crmeb\basic\BaseModel;
/**
* 门店自提 model
* Class SystemVip
* @package app\admin\model\system
*/
class SystemStore extends BaseModel
{
use ModelTrait;
/**
* 数据表主键
* @var string
*/
protected $pk = 'id';
/**
* 模型名称
* @var string
*/
protected $name = 'system_store';
public function getLatlngAttr($value,$data)
{
return $data['latitude'].','.$data['longitude'];
}
/*
*
*
* */
public static function getStoreDispose()
{
}
}

View File

@ -1,30 +0,0 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
{include file="public/head"}
<title>{$title|default=''}</title>
<style>
</style>
</head>
<body id="body" style="position: absolute;height: 100%;width: 100%">
<iframe id="mapPage" width="100%" height="100%" frameborder=0
src="https://apis.map.qq.com/tools/locpicker?type=1&key={$key}&referer=myapp">
</iframe>
</body>
<script>
window.onload=function(){
document.getElementById('body').style.height=document.body.clientHeight+'px';
}
mpFrame.start(function(layer) {
window.addEventListener('message',function (evevt) {
if(evevt.data){
parent.selectAdderss(evevt.data);
var index = parent.layer.getFrameIndex(window.name);
parent.layer.close(index);
}else{
return layer.msg('请选择地图');
}
});
})
</script>

View File

@ -1 +0,0 @@
{extend name="public/container"} {block name="head_top"} <link href="{__ADMIN_PATH}module/wechat/news_category/css/style.css" type="text/css" rel="stylesheet"> <script src="{__FRAME_PATH}js/content.min.js"></script> <script src="{__PLUG_PATH}sweetalert2/sweetalert2.all.min.js"></script> {/block} {block name="content"} <div class="row"> <div class="col-sm-12"> <div class="ibox"> <div class="ibox-title"> <div class="ibox-tools"> <button class="btn btn-white btn-sm" onclick="location.reload()"><i class="fa fa-refresh"></i> 刷新</button> </div> <div style="margin-top: 2rem"></div> <div class="row"> <div class="col-sm-8 m-b-xs"> <form action="" class="form-inline"> <i class="fa fa-search" style="margin-right: 10px;"></i> <div class="input-group"> <input type="text" name="cate_name" value="{$where.cate_name}" placeholder="请输入关键词" class="input-sm form-control"> <span class="input-group-btn"> <button type="submit" class="btn btn-sm btn-primary"> 搜索</button> </span> </div> </form> </div> </div> </div> <div class="ibox-content"> <div id="news_box"> {volist name="list" id="vo"} <div class="news_item" > <div class="title" ><span>图文名称:{$vo.cate_name}</span></div> {volist name="$vo['new']" id="vvo" key="k"} {if condition="$k eq 1"} <div class="news_tools hide"> <a href="javascript:void(0)">预览</a> <a href="javascript:void(0)" data-url="{:Url('push',array('id'=>$vo['id'],'wechat'=>$wechat))}" class="push">推送</a> </div> <div class="news_articel_item" style="background-image:url({$vvo.image_input})"> <p>{$vvo.title}</p> </div> <div class="hr-line-dashed"></div> {else/} <div class="news_articel_item other"> <div class="right-text">{$vvo.title}</div> <div class="left-image" style="background-image:url({$vvo.image_input});"> </div> </div> <div class="hr-line-dashed"></div> {/if} {/volist} </div> {/volist} </div> </div> </div> </div> </div> <div style="margin-left: 10px"> {include file="public/inner_page"} </div> {/block} {block name="script"} <script> $('body').on('mouseenter', '.news_item', function () { $(this).find('.news_tools').removeClass('hide'); }).on('mouseleave', '.news_item', function () { $(this).find('.news_tools').addClass('hide'); }); $('.push').on('click',function(){ window.t = $(this); var _this = $(this),url =_this.data('url'); swal({ title: "您确定要发送消息吗?", text:"发送后将无法撤回,请谨慎操作!", type: "warning", showCancelButton: true, confirmButtonColor: "#DD6B55", confirmButtonText:"是的,我要发送!", cancelButtonText:"让我再考虑一下…", closeOnConfirm: false, closeOnCancel: false }).then(function(){ $eb.axios.get(url).then(function(res){ if(res.status == 200 && res.data.code == 200) swal(res.data.msg); else swal('发送失败'); }).catch(function(err){ swal(err); }); }).catch(console.log); }); </script> {/block}

1
crmeb/.env Normal file
View File

@ -0,0 +1 @@
APP_DEBUG = true [APP] DEFAULT_TIMEZONE = Asia/Shanghai [DATABASE] TYPE = mysql HOSTNAME = 127.0.0.1 DATABASE = 123 USERNAME = 123 PASSWORD = 123 HOSTPORT = 3306 CHARSET = utf8 DEBUG = true [LANG] default_lang = zh-cn

2
crmeb/.version Normal file
View File

@ -0,0 +1,2 @@
version=CRMEB-DT v3.1
version_code=133

View File

@ -0,0 +1,36 @@
<?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(['code' => $e->getCode(), 'message' => $e->getMessage(), 'file' => $e->getFile()]);
}
return parent::render($request, $e);
}
}

View File

@ -12,6 +12,7 @@ use app\admin\model\user\UserExtract as UserExtractModel;//分销
use app\admin\model\user\User as UserModel;//用户
use app\admin\model\store\StoreProductReply as StoreProductReplyModel;//评论
use app\admin\model\store\StoreProduct as ProductModel;//产品
use app\models\store\StoreOrder;
use crmeb\services\SystemConfigService;
use FormBuilder\Json;
@ -29,8 +30,6 @@ class Index extends AuthController
$adminInfo = $this->adminInfo->toArray();
$roles = explode(',',$adminInfo['roles']);
$site_logo = SystemConfig::getOneConfig('menu_name','site_logo')->toArray();
// dump(SystemMenus::menuList());
// exit();
$this->assign([
'menuList'=>SystemMenus::menuList(),
'site_logo'=>json_decode($site_logo['value'],true),

View File

@ -211,7 +211,7 @@ class AgentManage extends AuthController
if(!$imageInfo){
$res = \app\models\routine\RoutineCode::getShareCode($uid, 'spread', '', '');
if(!$res) throw new \think\Exception('二维码生成失败');
$imageInfo = UploadService::imageStream($name,$res['res'],'routine/spread/code');
$imageInfo = UploadService::getInstance()->setUploadPath('routine/spread/code')->imageStream($name,$res['res']);
if(!is_array($imageInfo)) return $imageInfo;
SystemAttachment::attachmentAdd($imageInfo['name'],$imageInfo['size'],$imageInfo['type'],$imageInfo['dir'],$imageInfo['thumb_path'],1,$imageInfo['image_type'],$imageInfo['time']);
RoutineQrcode::setRoutineQrcodeFind($res['id'],['status'=>1,'time'=>time(),'qrcode_url'=>$imageInfo['dir']]);
@ -246,7 +246,7 @@ class AgentManage extends AuthController
if(!$imageInfo){
$res = \app\models\routine\RoutineCode::getShareCode($uid, 'spread', '', '');
if(!$res) return JsonService::fail('二维码生成失败');
$imageInfo = UploadService::imageStream($name,$res['res'],'routine/spread/code');
$imageInfo = UploadService::getInstance()->setUploadPath('routine/spread/code')->imageStream($name,$res['res']);
if(!is_array($imageInfo)) return JsonService::fail($imageInfo);
SystemAttachment::attachmentAdd($imageInfo['name'],$imageInfo['size'],$imageInfo['type'],$imageInfo['dir'],$imageInfo['thumb_path'],1,$imageInfo['image_type'],$imageInfo['time']);
RoutineQrcode::setRoutineQrcodeFind($res['id'],['status'=>1,'time'=>time(),'qrcode_url'=>$imageInfo['dir']]);

View File

@ -99,7 +99,7 @@ class Article extends AuthController
* @return \think\response\Json
*/
public function upload_image(){
$res = Upload::Image($_POST['file'],'wechat/image/'.date('Ymd'));
$res = Upload::getInstance()->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']]);
@ -187,4 +187,42 @@ class Article extends AuthController
$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('取消失败');
}
}

View File

@ -72,7 +72,7 @@ class ArticleCategory extends AuthController
* s上传图片
* */
public function upload(){
$res = Upload::image('file','article');
$res = Upload::getInstance()->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'=>Upload::pathToUrl($res['thumb_path'])]);

View File

@ -89,7 +89,7 @@ class WechatNews extends AuthController
* @return \think\response\Json
*/
public function upload_image(){
$res = Upload::Image($_POST['file'],'wechat/image/'.date('Ymd'));
$res = Upload::getInstance()->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['thumb_path']]);

View File

@ -10,6 +10,7 @@ use app\admin\controller\AuthController;
use app\admin\model\system\Express;
use crmeb\repositories\OrderRepository;
use crmeb\services\ExpressService;
use crmeb\services\JsonService;
use crmeb\services\MiniProgramService;
use crmeb\services\UtilService;
use crmeb\services\WechatService;
@ -22,7 +23,6 @@ use app\admin\model\user\User;
use app\admin\model\user\UserBill;
use crmeb\basic\BaseModel;
use crmeb\services\CacheService;
use crmeb\services\JsonService;
use crmeb\services\UtilService as Util;
use crmeb\services\JsonService as Json;
use think\facade\Db;
@ -85,6 +85,41 @@ class StoreOrder extends AuthController
]);
return JsonService::successlayui(StoreOrderModel::OrderList($where));
}
/**
* 核销码核销
* @param string $verify_code
* @return html
*/
public function write_order($verify_code = '',$is_confirm = 0)
{
if($this->request->isAjax()){
if(!$verify_code) return JsonService::fail('缺少核销码!');
StoreOrderModel::beginTrans();
$orderInfo = StoreOrderModel::where('verify_code',$verify_code)->where('paid',1)->where('refund_status',0)->find();
if(!$orderInfo) return JsonService::fail('核销订单不存在!');
if($orderInfo->status > 0) return JsonService::fail('订单已核销!');
if($orderInfo->combination_id && $orderInfo->pink_id){
$res = StorePink::where('id',$orderInfo->pink_id)->where('status','<>',2)->count();
if($res) return JsonService::fail('拼团订单暂未成功无法核销!');
}
if($is_confirm == 0){
$orderInfo['nickname'] = User::where(['uid'=>$orderInfo['uid']])->value('nickname');
return JsonService::successful($orderInfo);
}
$orderInfo->status = 2;
if($orderInfo->save()) {
StoreOrderModel::commitTrans();
return JsonService::successful('核销成功!');
}else {
StoreOrderModel::rollbackTrans();
return JsonService::fail('核销失败');
}
}else
$this->assign('is_layui',1);
return $this->fetch();
}
public function orderchart(){
$where = Util::getMore([
['status',''],
@ -268,6 +303,8 @@ class StoreOrder extends AuthController
return Json::fail('暂时不支持其他发货类型');
break;
}
//短信发送
event('ShortMssageSend',[StoreOrderModel::where('id',$id)->value('order_id'),'Deliver']);
return Json::successful('修改成功!');
}
@ -380,6 +417,8 @@ class StoreOrder extends AuthController
OrderRepository::storeProductOrderTakeDeliveryAdmin($order, $id);
StoreOrderStatus::setStatus($id,'take_delivery','已收货');
StoreOrderModel::commitTrans();
//发送短信
event('ShortMssageSend',[$order['order_id'],'Receiving']);
return Json::successful('收货成功!');
}
}catch (\Exception $e){
@ -465,9 +504,11 @@ class StoreOrder extends AuthController
if(!$res) return Json::fail('余额退款失败!');
}
$resEdit = StoreOrderModel::edit($data,$id);
$res = true;
if($resEdit){
$data['type'] = $type;
if($data['type'] == 1) StorePink::setRefundPink($id);
if($data['type'] == 1) $res = StorePink::setRefundPink($id);
if(!$res) return Json::fail('修改失败');
try{
OrderRepository::storeProductOrderRefundY($data, $id);
}catch (\Exception $e){
@ -479,7 +520,7 @@ class StoreOrder extends AuthController
return Json::successful('修改成功!');
}else{
StoreOrderStatus::setStatus($id,'refund_price','退款给用户'.$refund_price.'元失败');
return Json::successful('修改失败!');
return Json::fail('修改失败!');
}
}
public function order_info($oid = '')
@ -694,4 +735,13 @@ class StoreOrder extends AuthController
$this->assign(StoreOrderStatus::systemPage($oid));
return $this->fetch();
}
/*
* 订单列表推荐人详细
*/
public function order_spread_user($uid){
$spread = User::where('uid',$uid)->find();
$this->assign('spread',$spread);
return $this->fetch();
}
}

View File

@ -1,7 +1,6 @@
<?php
namespace app\admin\controller\setting;
use app\admin\model\system\SystemAttachment;
use think\facade\Route as Url;
use crmeb\services\FormBuilder as Form;
use crmeb\services\UtilService as Util;
@ -250,7 +249,7 @@ class SystemConfig extends AuthController
* @param $id
* @return mixed
*/
public function edit_cinfig($id){
public function edit_config($id){
$menu = ConfigModel::get($id)->getData();
if(!$menu) return Json::fail('数据不存在!');
$formbuider = array();
@ -342,7 +341,7 @@ class SystemConfig extends AuthController
* 删除子字段
* @return \think\response\Json
*/
public function delete_cinfig(){
public function delete_config(){
$id = input('id');
if(!ConfigModel::del($id))
return Json::fail(ConfigModel::getErrorInfo('删除失败,请稍候再试!'));
@ -395,7 +394,7 @@ class SystemConfig extends AuthController
* 文件上传
* */
public function file_upload(){
$res = Upload::file($this->request->param('file','file'),'config/file');
$res = Upload::getInstance()->setUploadPath('config/file')->file($this->request->param('file','file'));
if(!$res->status) return Json::fail($res->error);
return Json::successful('上传成功!',['filePath'=>$res->filePath]);
}

View File

@ -250,7 +250,7 @@ class SystemGroupData extends AuthController
public function upload()
{
$res = Upload::image('file','common');
$res = Upload::getInstance()->setUploadPath('common')->image('file');
if(!is_array($res)) return Json::fail($res);
SystemAttachment::attachmentAdd($res['name'],$res['size'],$res['type'],$res['dir'],$res['thumb_path'],6,$res['image_type'],$res['time']);
return Json::successful('图片上传成功!',['name'=>$res['name'],'url'=>Upload::pathToUrl($res['thumb_path'])]);

View File

@ -156,6 +156,7 @@ class CopyTaobao extends AuthController
$images = $this->getTaobaoImg($html);
$images = array_merge($images);
$this->productInfo['slider_image'] = isset($images['gaoqing']) ? $images['gaoqing'] : (array)$images;
$this->productInfo['slider_image'] = array_slice($this->productInfo['slider_image'],0,5);
//获取产品详情请求链接
$link = $this->getTaobaoDesc($html);
//获取请求内容
@ -184,6 +185,7 @@ class CopyTaobao extends AuthController
$images = $this->getTianMaoImg($html);
$images = array_merge($images);
$this->productInfo['slider_image'] = $images;
$this->productInfo['slider_image'] = array_slice($this->productInfo['slider_image'],0,5);
$this->productInfo['image'] = is_array($this->productInfo['slider_image']) && isset($this->productInfo['slider_image'][0]) ? $this->productInfo['slider_image'][0] : '';
//获取产品详情请求链接
$link = $this->getTianMaoDesc($html);
@ -214,6 +216,7 @@ class CopyTaobao extends AuthController
$this->productInfo['slider_image'] = $images['gaoqing'];
} else
$this->productInfo['slider_image'] = $images;
$this->productInfo['slider_image'] = array_slice($this->productInfo['slider_image'],0,5);
$this->productInfo['image'] = is_array($this->productInfo['slider_image']) && isset($this->productInfo['slider_image'][0]) ? $this->productInfo['slider_image'][0] : '';
//获取产品详情请求链接
$link = $this->get1688Desc($html);
@ -391,7 +394,7 @@ class CopyTaobao extends AuthController
return JsonService::fail('插入数据库错误', ['line' => $e->getLine(), 'messag' => $e->getMessage()]);
} catch (\Exception $e) {
ProductModel::rollbackTrans();
return JsonService::fail('系统错误', ['line' => $e->getLine(), 'messag' => $e->getMessage()]);
return JsonService::fail('系统错误', ['line' => $e->getLine(), 'messag' => $e->getMessage(),'file'=>$e->getFile()]);
}
}
@ -766,7 +769,7 @@ class CopyTaobao extends AuthController
$size = strlen(trim($content));
if (!$content || $size <= 2) return '图片流获取失败';
$date_dir = date('Y') . DS . date('m') . DS . date('d');
$imageInfo = UploadService::imageStream($name, $content, 'attach/' . $date_dir);
$imageInfo = UploadService::getInstance()->setUploadPath('attach/' . $date_dir)->imageStream($name, $content);
if (!is_array($imageInfo)) return $imageInfo;
$date['path'] = $imageInfo['dir'];
$date['name'] = $imageInfo['name'];

View File

@ -107,7 +107,7 @@ class StoreCategory extends AuthController
*/
public function upload()
{
$res = Upload::image('file','store/category'.date('Ymd'));
$res = Upload::getInstance()->setUploadPath('store/category'.date('Ymd'))->image('file');
if(is_array($res)){
SystemAttachment::attachmentAdd($res['name'],$res['size'],$res['type'],$res['dir'],$res['thumb_path'],1,$res['image_type'],$res['time']);
return Json::successful('图片上传成功!',['name'=>$res['name'],'url'=>Upload::pathToUrl($res['thumb_path'])]);

View File

@ -68,7 +68,7 @@ class StoreInfoMana extends AuthController
* */
public function upload()
{
$res = Upload::image('file','article/'.date('Ymd'));
$res = Upload::getInstance()->setUploadPath('article/'.date('Ymd'))->image('file');
SystemAttachment::attachmentAdd($res['name'],$res['size'],$res['type'],$res['dir'],$res['thumb_path'],2,$res['image_type'],$res['time']);
if(is_array($res))
return Json::successful('图片上传成功!',['name'=>$res['name'],'url'=>Upload::pathToUrl($res['thumb_path'])]);

View File

@ -142,7 +142,8 @@ class StoreProduct extends AuthController
Form::input('store_name','产品名称')->col(Form::col(24)),
Form::input('store_info','产品简介')->type('textarea'),
Form::input('keyword','产品关键字')->placeholder('多个用英文状态下的逗号隔开'),
Form::input('unit_name','产品单位','件'),
Form::input('unit_name','产品单位','件')->col(Form::col(12)),
Form::input('bar_code','产品条码','')->placeholder('请输入商品条形码')->col(Form::col(12)),
Form::frameImageOne('image','产品主图片(305*305px)',Url::buildUrl('admin/widget.images/index',array('fodder'=>'image')))->icon('image')->width('100%')->height('500px'),
Form::frameImages('slider_image','产品轮播图(640*640px)',Url::buildUrl('admin/widget.images/index',array('fodder'=>'slider_image')))->maxLength(5)->icon('images')->width('100%')->height('500px')->spin(0),
Form::number('price','产品售价')->min(0)->col(8),
@ -159,7 +160,8 @@ class StoreProduct extends AuthController
Form::radio('is_benefit','促销单品',0)->options([['label'=>'是','value'=>1],['label'=>'否','value'=>0]])->col(8),
Form::radio('is_best','精品推荐',0)->options([['label'=>'是','value'=>1],['label'=>'否','value'=>0]])->col(8),
Form::radio('is_new','首发新品',0)->options([['label'=>'是','value'=>1],['label'=>'否','value'=>0]])->col(8),
Form::radio('is_postage','是否包邮',0)->options([['label'=>'是','value'=>1],['label'=>'否','value'=>0]])->col(8)
Form::radio('is_postage','是否包邮',0)->options([['label'=>'是','value'=>1],['label'=>'否','value'=>0]])->col(8),
Form::radio('is_good','是否优品推荐',0)->options([['label'=>'是','value'=>1],['label'=>'否','value'=>0]])->col(8),
];
$form = Form::make_post_form('添加产品',$field,Url::buildUrl('save'),2);
$this->assign(compact('form'));
@ -172,7 +174,7 @@ class StoreProduct extends AuthController
*/
public function upload()
{
$res = Upload::image('file','store/product/'.date('Ymd'));
$res = Upload::getInstance()->setUploadPath('store/product/'.date('Ymd'))->image('file');
SystemAttachment::attachmentAdd($res['name'],$res['size'],$res['type'],$res['dir'],$res['thumb_path'],1,$res['image_type'],$res['time']);
if(is_array($res))
return Json::successful('图片上传成功!',['name'=>$res['name'],'url'=>Upload::pathToUrl($res['thumb_path'])]);
@ -193,6 +195,7 @@ class StoreProduct extends AuthController
'store_info',
'keyword',
['unit_name','件'],
'bar_code',
['image',[]],
['slider_image',[]],
['postage',0],
@ -211,6 +214,7 @@ class StoreProduct extends AuthController
['is_new',0],
['mer_use',0],
['is_postage',0],
['is_good',0],
]);
if(count($data['cate_id']) < 1) return Json::fail('请选择产品分类');
$cate_id=$data['cate_id'];
@ -269,12 +273,13 @@ class StoreProduct extends AuthController
Form::input('store_name','产品名称',$product->getData('store_name')),
Form::input('store_info','产品简介',$product->getData('store_info'))->type('textarea'),
Form::input('keyword','产品关键字',$product->getData('keyword'))->placeholder('多个用英文状态下的逗号隔开'),
Form::input('unit_name','产品单位',$product->getData('unit_name')),
Form::input('unit_name','产品单位',$product->getData('unit_name'))->col(12),
Form::input('bar_code','产品条码',$product->getData('bar_code'))->col(12),
Form::frameImageOne('image','产品主图片(305*305px)',Url::buildUrl('admin/widget.images/index',array('fodder'=>'image')),$product->getData('image'))->icon('image')->width('100%')->height('500px'),
Form::frameImages('slider_image','产品轮播图(640*640px)',Url::buildUrl('admin/widget.images/index',array('fodder'=>'slider_image')),json_decode($product->getData('slider_image'),1) ? : [])->maxLength(5)->icon('images')->width('100%')->height('500px'),
Form::number('price','产品售价',$product->getData('price'))->min(0)->precision(2)->col(8),
Form::number('price','产品售价',$product->getData('price'))->min(0)->col(8),
Form::number('ot_price','产品市场价',$product->getData('ot_price'))->min(0)->col(8),
Form::number('give_integral','赠送积分',$product->getData('give_integral'))->min(0)->precision(0)->col(8),
Form::number('give_integral','赠送积分',$product->getData('give_integral'))->min(0)->col(8),
Form::number('postage','邮费',$product->getData('postage'))->min(0)->col(8),
Form::number('sales','销量',$product->getData('sales'))->min(0)->precision(0)->col(8)->readonly(1),
Form::number('ficti','虚拟销量',$product->getData('ficti'))->min(0)->precision(0)->col(8),
@ -286,7 +291,8 @@ class StoreProduct extends AuthController
Form::radio('is_benefit','促销单品',$product->getData('is_benefit'))->options([['label'=>'是','value'=>1],['label'=>'否','value'=>0]])->col(8),
Form::radio('is_best','精品推荐',$product->getData('is_best'))->options([['label'=>'是','value'=>1],['label'=>'否','value'=>0]])->col(8),
Form::radio('is_new','首发新品',$product->getData('is_new'))->options([['label'=>'是','value'=>1],['label'=>'否','value'=>0]])->col(8),
Form::radio('is_postage','是否包邮',$product->getData('is_postage'))->options([['label'=>'是','value'=>1],['label'=>'否','value'=>0]])->col(8)
Form::radio('is_postage','是否包邮',$product->getData('is_postage'))->options([['label'=>'是','value'=>1],['label'=>'否','value'=>0]])->col(8),
Form::radio('is_good','是否优品推荐',$product->getData('is_good'))->options([['label'=>'是','value'=>1],['label'=>'否','value'=>0]])->col(8),
];
$form = Form::make_post_form('编辑产品',$field,Url::buildUrl('update',array('id'=>$id)),2);
$this->assign(compact('form'));
@ -306,6 +312,7 @@ class StoreProduct extends AuthController
'store_name',
'store_info',
'keyword',
'bar_code',
['unit_name','件'],
['image',[]],
['slider_image',[]],
@ -324,6 +331,7 @@ class StoreProduct extends AuthController
['is_new',0],
['mer_use',0],
['is_postage',0],
['is_good',0],
]);
if(count($data['cate_id']) < 1) return Json::fail('请选择产品分类');
$cate_id=$data['cate_id'];

View File

@ -21,7 +21,7 @@ class SystemAttachment extends AuthController
*/
public function upload()
{
$res = Upload::image('upfile','editor/'.date('Ymd'));
$res = Upload::getInstance()->setUploadPath('editor/'.date('Ymd'))->image('upfile');
if(is_array($res)){
SystemAttachmentModel::attachmentAdd($res['name'],$res['size'],$res['type'],$res['dir'],$res['thumb_path'],0,$res['image_type'],$res['time']);
$info["originalName"] = $res['name'];

View File

@ -41,12 +41,13 @@ class SystemclearData extends AuthController
self::clearData('store_bargain_user',1);
self::clearData('store_bargain_user_help',1);
self::clearData('store_product_reply',1);
self::clearData('store_product_cate',1);
self::clearData('routine_qrcode',1);
self::clearData('routine_form_id',1);
self::clearData('user_sign',1);
self::clearData('user_task_finish',1);
self::clearData('user_level',1);
self::clearData('token',1);
self::clearData('user_token',1);
self::clearData('user_group',1);
$this->delDirAndFile('./public/uploads/store/comment');
self::clearData('store_product_relation',1);
@ -62,6 +63,7 @@ class SystemclearData extends AuthController
self::clearData('store_combination_attr_result',1);
self::clearData('store_combination_attr_value',1);
self::clearData('store_product_attr',1);
self::clearData('store_product_cate',1);
self::clearData('store_product_attr_result',1);
self::clearData('store_product_attr_value',1);
self::clearData('store_seckill',1);

View File

@ -5,6 +5,7 @@ namespace app\admin\controller\system;
use app\admin\controller\AuthController;
use crmeb\services\JsonService as Json;
use \crmeb\services\MysqlBackupService as Backup;
use think\facade\Env;
use think\facade\Session;
use think\facade\Db;
@ -55,7 +56,7 @@ class SystemDatabackup extends AuthController
*/
public function seetable()
{
$database = config("database.database");
$database = Env::get("database.database");
$tablename = request()->param('tablename');
$res = Db::query("select * from information_schema.columns where table_name = '" . $tablename . "' and table_schema = '" . $database . "'");
$html = '';
@ -98,8 +99,12 @@ class SystemDatabackup extends AuthController
{
$tables = request()->post('tables/a');
$db = $this->DB;
$res = $db->optimize($tables);
return Json::successful($res ? '优化成功' : '优化失败');
try{
$db->optimize($tables);
return Json::successful( '优化成功' );
}catch (\Exception $e){
return Json::fail($e->getMessage());
}
}
/**
@ -109,8 +114,12 @@ class SystemDatabackup extends AuthController
{
$tables = request()->post('tables/a');
$db = $this->DB;
$res = $db->repair($tables);
return Json::successful($res ? '修复成功' : '修复失败');
try{
$db->repair($tables);
return Json::successful( '修复成功' );
}catch (\Exception $e){
return Json::fail($e->getMessage());
}
}
/**

View File

@ -51,7 +51,6 @@ class SystemFile extends AuthController
}
}
}
//var_dump($fileAll['dir']);
//兼容windows
$uname = php_uname('s');
if (strstr($uname, 'Windows') !== false) $dir = ltrim($dir, '\\');

View File

@ -3,6 +3,7 @@
namespace app\admin\controller\system;
use app\admin\controller\AuthController;
use app\admin\model\system\SystemConfig;
use crmeb\services\JsonService;
use crmeb\services\SystemConfigService;
use app\admin\model\system\SystemStore as SystemStoreModel;
@ -22,14 +23,8 @@ class SystemStore extends AuthController
* */
public function index()
{
$store = SystemStoreModel::where('is_show',1)->where('is_del',0)->find();
$storeData = '{}';
$id = 0;
if($store){
$storeData = json_encode($store->toArray());
$id = $store->id;
}
$this->assign(compact('storeData','id'));
$store = SystemStoreModel::getStoreDispose();
$this->assign(compact('store'));
return $this->fetch();
}
@ -39,6 +34,7 @@ class SystemStore extends AuthController
public function select_address()
{
$key = SystemConfigService::get('tengxun_map_key');
if(!$key) return $this->failed('请前往设置->系统设置->物流配置 配置腾讯地图KEY','#');
$this->assign(compact('key'));
return $this->fetch();
}
@ -51,19 +47,29 @@ class SystemStore extends AuthController
{
$data = UtilService::postMore([
['name',''],
['introduction',''],
['image',''],
['phone',''],
['address',''],
['detailed_address',''],
['latlng',''],
['valid_time',[]],
['day_time',[]],
]);
SystemStoreModel::beginTrans();
try{
$data['latlng'] = explode(',',$data);
$data['address'] = implode(',',$data['address']);
$data['latlng'] = explode(',',$data['latlng']);
if(!isset($data['latlng'][0]) || !isset($data['latlng'][1])) return JsonService::fail('请选择门店位置');
$data['latitude'] = $data['latlng'][0];
$data['longitude'] = $data['latlng'][1];
$data['valid_time'] = implode(' - ',$data['valid_time']);
$data['day_time'] = implode(' - ',$data['day_time']);
unset($data['latlng']);
if($data['image'] && strstr($data['image'],'http') === false){
$site_url = SystemConfig::getConfigValue('site_url');
$data['image'] = $site_url.$data['image'];
}
if($id){
if(SystemStoreModel::where('id',$id)->update($data)){
SystemStoreModel::commitTrans();
@ -74,9 +80,10 @@ class SystemStore extends AuthController
}
}else{
$data['add_time'] = time();
if(SystemStoreModel::create($data)){
$data['is_show'] = 1;
if($res=SystemStoreModel::create($data)){
SystemStoreModel::commitTrans();
return JsonService::success('保存成功');
return JsonService::success('保存成功',['id'=>$res->id]);
}else{
SystemStoreModel::rollbackTrans();
return JsonService::fail('保存失败!');

View File

@ -191,7 +191,7 @@ class StoreSeckill extends AuthController
*/
public function upload()
{
$res = Upload::image('file','store/product/'.date('Ymd'));
$res = Upload::getInstance()->setUploadPath('store/product/'.date('Ymd'))->image('file');
if(is_array($res)){
SystemAttachment::attachmentAdd($res['name'],$res['size'],$res['type'],$res['dir'],$res['thumb_path'],4,$res['image_type'],$res['time']);
return Json::successful('图片上传成功!',['name'=>$res['name'],'url'=>Upload::pathToUrl($res['thumb_path'])]);

View File

@ -262,7 +262,7 @@ class UserLevel extends AuthController
['illustrate',''],
]);
if(!$data['task_type']) return JsonService::fail('请选择任务类型');
if($data['number'] < 0) return JsonService::fail('请输入限定数量');
if($data['number'] < 1) return JsonService::fail('请输入限定数量,数量不能小于1');
$tash=SystemUserTask::getTaskType($data['task_type']);
if($tash['max_number']!=0 && $data['number'] > $tash['max_number']) return JsonService::fail('您设置的限定数量超出最大限制,最大限制为:'.$tash['max_number']);
$data['name']=SystemUserTask::setTaskName($data['task_type'],$data['number']);

View File

@ -82,7 +82,8 @@ class Reply extends AuthController
{
$name = $this->request->post('file');
if(!$name) return Json::fail('请上传图片');
$res = Upload::image($name,'wechat/image',true,true,null,'uniqid',1);
$res = Upload::getInstance()->setUploadType(1)->setUploadPath('wechat/image')
->setAutoValidate(true)->image($name);
if(!is_array($res)) return Json::fail($res);
SystemAttachment::attachmentAdd($res['name'],$res['size'],$res['type'],$res['dir'],$res['thumb_path'],0,$res['image_type'],$res['time']);
return Json::successful('上传成功',$res['dir']);
@ -92,8 +93,7 @@ class Reply extends AuthController
{
$name = $this->request->post('file');
if(!$name) return Json::fail('请上传声音');
$autoValidate['size'] = 2097152;
$res = Upload::file($name,'wechat/voice',true,$autoValidate);
$res = Upload::getInstance()->setUploadPath('wechat/voice')->setAutoValidate(true)->file($name);
return $res->status === true ? Json::successful('上传成功',$res->filePath) : Json::fail($res->error);
}

View File

@ -136,7 +136,7 @@ class StoreService extends AuthController
*/
public function upload()
{
$res = Upload::image('file','store/product/'.date('Ymd'));
$res = Upload::getInstance()->setUploadPath('store/product/'.date('Ymd'))->image('file');
if(is_array($res)){
SystemAttachment::attachmentAdd($res['name'],$res['size'],$res['type'],$res['dir'],$res['thumb_path'],2,$res['image_type'],$res['time']);
return Json::successful('图片上传成功!',['name'=>$res['name'],'url'=>Upload::pathToUrl($res['thumb_path'])]);

View File

@ -249,11 +249,11 @@ class WechatUser extends AuthController
public function group($refresh = 0)
{
$list=[];
if($refresh == 1) {
UserModel::clearUserGroup();
$this->redirect(Url::buildUrl('group'));
}
try{
if($refresh == 1) {
UserModel::clearUserGroup();
$this->redirect(Url::buildUrl('group'));
}
$list = UserModel::getUserGroup();
}catch (\Exception $e){}
$this->assign(compact('list'));

View File

@ -71,7 +71,8 @@ class Images extends AuthController
$upload_type = $this->request->get('upload_type',0);
try{
$path = make_path('attach');
$res = Upload::image('file',$path,true,true,null,'uniqid',$upload_type);
$res = Upload::getInstance()->setUploadPath($path)->setAutoValidate(true)
->setUploadType($upload_type)->image('file');
if(is_object($res) && $res->status === false){
$info = array(
'code' =>400,

View File

@ -12,6 +12,7 @@
namespace app\admin\model\article;
use app\admin\model\store\StoreProduct;
use app\admin\model\system\SystemAdmin;
use crmeb\traits\ModelTrait;
use crmeb\basic\BaseModel;
@ -30,6 +31,10 @@ class Article extends BaseModel {
protected $name = 'article';
public function profile()
{
return $this->hasOne(StoreProduct::class,'id','product_id')->field('store_name');
}
/**
* 获取配置分类
* @param array $where
@ -53,6 +58,7 @@ class Article extends BaseModel {
else $item['admin_name'] = Merchant::where('id',$item['mer_id'])->value('mer_name').'---》'.MerchantAdmin::where('id',$item['admin_id'])->value('real_name');
$item['content'] = Db::name('ArticleContent')->where('nid',$item['id'])->value('content');
$item['catename'] = Db::name('ArticleCategory')->where('id',$item['cid'])->value('title');
$item['store_name'] = $item->profile->store_name ?? '';
},$where);
}

View File

@ -46,13 +46,14 @@ class StoreOrder extends BaseModel
public static function orderCount(){
$data['wz']=self::statusByWhere(0,new self())->where(['is_system_del'=>0])->count();
$data['wf']=self::statusByWhere(1,new self())->where(['is_system_del'=>0])->count();
$data['ds']=self::statusByWhere(2,new self())->where(['is_system_del'=>0])->count();
$data['wf']=self::statusByWhere(1,new self())->where(['is_system_del'=>0,'shipping_type'=>1])->count();
$data['ds']=self::statusByWhere(2,new self())->where(['is_system_del'=>0,'shipping_type'=>1])->count();
$data['dp']=self::statusByWhere(3,new self())->where(['is_system_del'=>0])->count();
$data['jy']=self::statusByWhere(4,new self())->where(['is_system_del'=>0])->count();
$data['tk']=self::statusByWhere(-1,new self())->where(['is_system_del'=>0])->count();
$data['yt']=self::statusByWhere(-2,new self())->where(['is_system_del'=>0])->count();
$data['del']=self::statusByWhere(-4,new self())->where(['is_system_del'=>0])->count();
$data['write_off'] =self::statusByWhere(5,new self())->where(['is_system_del'=>0])->count();
$data['general']=self::where(['pink_id'=>0,'combination_id'=>0,'seckill_id'=>0,'bargain_id'=>0,'is_system_del'=>0])->count();
$data['pink']=self::where('pink_id|combination_id','>',0)->where('is_system_del',0)->count();
$data['seckill']=self::where('seckill_id','>',0)->where('is_system_del',0)->count();
@ -61,7 +62,7 @@ class StoreOrder extends BaseModel
}
public static function OrderList($where){
$model = self::getOrderWhere($where,self::alias('a')->join('user r','r.uid=a.uid','LEFT'),'a.','r')->field('a.*,r.nickname,r.phone');
$model = self::getOrderWhere($where,self::alias('a')->join('user r','r.uid=a.uid','LEFT'),'a.','r')->field('a.*,r.nickname,r.phone,r.spread_uid');
if($where['order']!=''){
$model = $model->order(self::setOrder($where['order']));
}else{
@ -72,7 +73,7 @@ class StoreOrder extends BaseModel
}else{
$data=($data=$model->page((int)$where['page'],(int)$where['limit'])->select()) && count($data) ? $data->toArray() : [];
}
// $data=($data=$model->page((int)$where['page'],(int)$where['limit'])->select()) && count($data) ? $data->toArray() : [];
foreach ($data as &$item){
$_info = Db::name('store_order_cart_info')->where('oid',$item['id'])->field('cart_info')->select();
$_info = count($_info) ? $_info->toArray() : [];
@ -83,6 +84,7 @@ class StoreOrder extends BaseModel
unset($cart_info);
}
$item['_info'] = $_info;
$item['spread_nickname'] = Db::name('user')->where('uid',$item['spread_uid'])->value('nickname');
$item['add_time'] = date('Y-m-d H:i:s',$item['add_time']);
if($item['pink_id'] || $item['combination_id']){
$pinkStatus = StorePink::where('order_id_key',$item['id'])->value('status');
@ -111,8 +113,13 @@ class StoreOrder extends BaseModel
$item['pink_name'] = '[砍价订单]';
$item['color'] = '#12c5e9';
}else{
$item['pink_name'] = '[普通订单]';
$item['color'] = '#895612';
if($item['shipping_type']==1){
$item['pink_name'] = '[普通订单]';
$item['color'] = '#895612';
}else if($item['shipping_type']==2){
$item['pink_name'] = '[核销订单]';
$item['color'] = '#8956E8';
}
}
if($item['paid']==1){
switch ($item['pay_type']){
@ -142,10 +149,14 @@ class StoreOrder extends BaseModel
}
if($item['paid']==0 && $item['status']==0){
$item['status_name']='未支付';
}else if($item['paid']==1 && $item['status']==0 && $item['refund_status']==0){
}else if($item['paid']==1 && $item['status']==0 && $item['shipping_type']==1 && $item['refund_status']==0){
$item['status_name']='未发货';
}else if($item['paid']==1 && $item['status']==1 && $item['refund_status']==0){
}else if($item['paid']==1 && $item['status']==0 && $item['shipping_type']==2 && $item['refund_status']==0){
$item['status_name']='未核销';
}else if($item['paid']==1 && $item['status']==1 && $item['shipping_type']==1 && $item['refund_status']==0){
$item['status_name']='待收货';
}else if($item['paid']==1 && $item['status']==1 && $item['shipping_type']==2 && $item['refund_status']==0){
$item['status_name']='未核销';
}else if($item['paid']==1 && $item['status']==2 && $item['refund_status']==0){
$item['status_name']='待评价';
}else if($item['paid']==1 && $item['status']==3 && $item['refund_status']==0){
@ -345,21 +356,23 @@ HTML;
else if($status == 8)
return $model;
else if($status == 0)//未支付
return $model->where($alert.'paid',0)->where($alert.'status',0)->where($alert.'refund_status',0);
return $model->where($alert.'paid',0)->where($alert.'status',0)->where($alert.'refund_status',0)->where($alert.'is_del',0);
else if($status == 1)//已支付 未发货
return $model->where($alert.'paid',1)->where($alert.'status',0)->where($alert.'refund_status',0);
return $model->where($alert.'paid',1)->where($alert.'status',0)->where($alert.'shipping_type',1)->where($alert.'refund_status',0)->where($alert.'is_del',0);
else if($status == 2)//已支付 待收货
return $model->where($alert.'paid',1)->where($alert.'status',1)->where($alert.'refund_status',0);
return $model->where($alert.'paid',1)->where($alert.'status',1)->where($alert.'shipping_type',1)->where($alert.'refund_status',0)->where($alert.'is_del',0);
else if($status == 5)//已支付 待核销
return $model->where($alert.'paid',1)->where($alert.'status',0)->where($alert.'shipping_type',2)->where($alert.'refund_status',0)->where($alert.'is_del',0);
else if($status == 3)// 已支付 已收货 待评价
return $model->where($alert.'paid',1)->where($alert.'status',2)->where($alert.'refund_status',0);
return $model->where($alert.'paid',1)->where($alert.'status',2)->where($alert.'refund_status',0)->where($alert.'is_del',0);
else if($status == 4)// 交易完成
return $model->where($alert.'paid',1)->where($alert.'status',3)->where($alert.'refund_status',0);
return $model->where($alert.'paid',1)->where($alert.'status',3)->where($alert.'refund_status',0)->where($alert.'is_del',0);
else if($status == -1)//退款中
return $model->where($alert.'paid',1)->where($alert.'refund_status',1);
return $model->where($alert.'paid',1)->where($alert.'refund_status',1)->where($alert.'is_del',0);
else if($status == -2)//已退款
return $model->where($alert.'paid',1)->where($alert.'refund_status',2);
return $model->where($alert.'paid',1)->where($alert.'refund_status',2)->where($alert.'is_del',0);
else if($status == -3)//退款
return $model->where($alert.'paid',1)->where($alert.'refund_status','in','1,2');
return $model->where($alert.'paid',1)->where($alert.'refund_status','in','1,2')->where($alert.'is_del',0);
else if($status == -4)//已删除
return $model->where($alert.'is_del',1);
else
@ -409,7 +422,7 @@ HTML;
'keyword2'=>$order['pay_price'],
'keyword3'=>date('Y-m-d H:i:s',$order['add_time']),
'remark'=>'点击查看订单详情'
],Url::buildUrl('wap/My/order',['uni'=>$order['order_id']],true,true));
],Url::buildUrl('/order/detail/'.$order['order_id'])->suffix('')->domain(true)->build());
}
/**
@ -1051,7 +1064,7 @@ HTML;
{
$order = self::where('id',$oid)->find();
$url = Url::buildUrl('wap/My/order',['uni'=>$order['order_id']],true,true);
$url = Url::buildUrl('/order/detail/'.$order['order_id'])->suffix('')->domain(true)->build();
$group = [
'first'=>'亲,您的订单已发货,请注意查收',
'remark'=>'点击查看订单详情'

View File

@ -91,7 +91,8 @@ class StoreProductAttr extends BaseModel
'cost'=>$value['cost'],
'stock'=>$value['sales'],
'unique'=> StoreProductAttrValue::uniqueId($productId.$suk.uniqid(true)),
'image'=>$value['pic']
'image'=>$value['pic'],
'bar_code'=>$value['bar_code'] ?? '',
];
}
if(!count($attrGroup) || !count($valueGroup)) return self::setErrorInfo('请设置至少一个属性!');

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