Merge branch 'v5.2.0dev' into v5.1.0-el

# Conflicts:
#	template/admin/src/pages/marketing/storeCouponIssue/index.vue
#	template/admin/src/pages/marketing/storeIntegralOrder/components/tableList.vue
#	template/admin/src/pages/order/orderList/handle/orderDetails.vue
#	template/admin/src/pages/product/productAdd/index.vue
#	template/admin/src/pages/product/productList/index.vue
#	template/admin/src/pages/system/backendRouting/index.vue
#	template/admin/src/pages/user/list/handle/userDetails.vue
#	template/admin/src/pages/user/list/index.vue
This commit is contained in:
From-wh 2023-07-15 14:54:06 +08:00
commit 39a04c2739
43 changed files with 1583 additions and 176 deletions

197
README.md
View File

@ -1,10 +1,10 @@
![输入图片说明](readme/pic/gitee.jpg)
<div align="center" >
<img src="https://images.gitee.com/uploads/images/2021/1109/164354_0aafe3d2_892944.gif" />
</div>
<div align="center">
支持免费商用的PHP **多语言** 商城系统
CRMEB开源商城系统PHP版
</div>
@ -36,34 +36,67 @@
</div>
<div align="center" >
<a href="https://gitee.com/ZhongBangKeJi/CRMEB/blob/master/README.md">宽 屏 预 览</a>
<a href="https://gitee.com/ZhongBangKeJi/CRMEB/blob/master/README.md">宽屏预览</a>
</div>
### 介绍
CRMEB打通版是历经6年时间匠心之作!系统全开源可商用,包含小程序商城、H5商城、公众号商城、PC商城、App,多种分销模式、拼团、砍价、秒杀、优惠券、抽奖、积分、会员等级、小程序直播、页面DIY,前后端分离全部100%开源。方便二开,更有详细使用文档、接口文档、数据字典、二开文档/视频教程。为开发者赋能,助力企业发展、国家富强,致力于打造最受欢迎的商城项目
---
### 📋 更新说明
```
v5.0.0 更新说明【更新时间2023年06月12日】
1、后台管理页面增加风格选项切换功能
2、新增接口管理
3、新增代码生成功能,能快速生成基础的增删改查代码,并自动生成菜单和功能页面
4、文件管理和数据库管理增加添加备注功能
5、后台根据新增的路由表,生成接口文档,并支持在线调试
6、权限管理优化,业务和开发分离,分工更明确
7、新增代理商申请页面按钮开关
8、增加小程序发货信息管理接口
9、优惠券优化,优惠券修改后台添加,增加多分类,恢复系统赠送功能
10、后台分类样式统一,优化分类选择体验
以及其他共计21跳更新和优化
v4.7.1 更新说明【更新时间2023年04月26日】
1.优化订单下单时订单号的生成
2.版权设置增加清除缓存,及时生效
3.企业微信无法通知问题修复
4.修复重量体积包邮的问题
5.佣金转入余额报错问题处理
6.拼团未支付的时候查看拼团报错处理
7.自提商品下单后默认门店不是最近的问题处理
8.不能修改cos空间名,cos优化;
9.核销订单部分退款问题优化
10.更新修改后台admin之后无法选择图片的问题
以及其他共计40跳更新和优化
```
### 用心做开源,我们也很需要你的鼓励!右上角Star,等你点亮!
---
### 📝 介绍
CRMEB开源商城系统是一款全开源可商用的系统,前后端分离开发,全部100%开源,在小程序、公众号、H5、APP、PC端都能用,使用方便,二开方便!安装使用也很简单!使用文档、接口文档、数据字典、二开文档、视频教程,各种资料应有尽有,就算你是技术小白,也能轻松上手!
欢迎大家来体验、来提建议,来一起让CRMEB开源商城系统更强大,让更多开发者受益!虽然是开源,但我们该有的功能全都有!拼团、秒杀、优惠券、抽奖、积分、直播、分销、页面DIY... 常用商城系统功能,都是全开源,直接用!
CRMEB开源商城Java版:https://gitee.com/ZhongBangKeJi/crmeb_java
---
### 系统亮点
### 🫧 系统亮点
~~~
多 语 言:后台随时配置语言包,移动端支持多语言切换;
高 性 能:redis缓存、队列、长连接、多种云储存、支持集群部署;
个 性 UI:多种风格切换、支持DIY各种首页/专题页面
前后端分离:后端TP6,管理端iviewui,移动端uniapp;
代码规范:遵循PSR-2命名规范、Restful标准接口、代码严格分层、注释齐全、统一错误码;
权限管理:内置强大灵活的权限管理,可以控制到每一个菜单;
开发配置:低代码增加配置、系统组合数据模块;
二开效率:PHP快速生成表单、内置所有事件、后台在线编辑器、代码注释齐全、完整接口文档;
快速上手:详细帮助文档、接口文档、数据库字典、代码注释、一键安装;
系统安全:系统操作日志、系统生产日志、文件校验、数据备份;
系统功能:请看帮助文档 https://doc.crmeb.com/single/crmeb_v4/1758
用户体验:等您来评!
1.前后端分离:后端TP6,管理端iView UI,移动端Uni-app;
2.代码规范:遵循PSR-2命名规范、Restful标准接口、代码严格分层、注释齐全、统一错误码;
3.权限管理:内置强大灵活的权限管理,可以控制到每一个菜单;
4.开发配置:低代码增加配置、系统组合数据模块;
5.二开效率:应用form-builder PHP快速生成表单、内置所有事件、后台接口管理调试、后台代码在线编辑器、代码生成,快速对接第三方接口;
6.快速上手:详细帮助文档、后台接口管理、后台数据库字典、系统文件管理备注、代码注释、一键安装;
7.系统安全:系统操作日志、系统生产日志、文件校验、数据备份;
8.高 性 能:支持Redis缓存、队列、长连接、多种云储存、支持集群部署。
~~~
---
### 运行环境
### 🖥 运行环境
```
Nignx/Apache/IIS
@ -73,97 +106,116 @@ Redis
```
> 温馨提示:虚拟空间不支持,推荐使用bt宝塔面板,服务器推荐阿里云ecs或腾讯云cvm 云服务器:<a href="https://promotion.aliyun.com/ntms/yunparter/invite.html?userCode=dligum2z" target="_blank"> 查看 </a>
> 温馨提示:虚拟空间不支持,推荐使用bt宝塔面板,服务器推荐京东云服务器:<a href="https://partner.jdcloud.com/partner/notice/b06c3232b6394fdfa496923b8e00b286" target="_blank">注册即享6.5折专属优惠,点我领取!</a>
### 系统演示
### 📱 系统演示
![输入图片说明](readme/pic/20公众号.jpg)
管理后台: http://v4.crmeb.net/admin 账号:demo 密码:crmeb.com
管理后台: http://v5.crmeb.net/admin
H5端:http://v4.crmeb.net/(移动端打开)
账号:demo 密码:crmeb.com
PC端:http://v4.crmeb.net/(电脑端打开)
H5端:http://v5.crmeb.net/(移动端打开)
APP下载:http://app.crmeb.cn/bzv (苹果手机直接在APP Store里搜索CRMEB下载)
PC端:http://v5.crmeb.net/(电脑端打开)
APP下载:http://app.crmeb.cn/bzv(苹果手机直接在APP Store里搜索CRMEB下载)
> 听说,大神你想看看CRMEB开源项目的完整框架?<a href="https://doc.crmeb.com/single/v5/7712" target="_blank">戳这儿,轻松获取!</a>
---
#### 体验云部署
不懂服务器?不懂技术?无法解决高并发?想数据私有化?还想后期定制开发?
### 🔐 安装教程
推荐云部署版一键超低价格低至 :collision: 9.9元/年,解决以上所有问题<a href='https://saas.crmeb.com/saas-home-software-detail-50043-s-y.html' target='_blank'>点击了解 </a>
想要快速安装,教程来助攻!<a href="https://doc.crmeb.com/single/v5/7714" target="_blank">查看安装教程!</a>
---
### 官方论坛
### 📲 核心功能
#### 商城页面维护:自定义底部菜单、5种主题风格切换、分类页风格切换、个人中心风格切换、数据配置、首页DIY设计、开屏广告...
#### 商品:商品运营(分类、列表、详情、规格、收藏、评价、视频、海报、采集、口令)、卡密商品、虚拟商品、商品预售、限购
#### 订单:订单状态、订单类型、移动端订单管理、移动端订单核销、发票管理
#### 营销功能:拼团、秒杀、砍价、预售、积分商城、九宫格抽奖、优惠券、积分、余额充值、公众号渠道码、微信小程序直播
#### 物流配送:快递发货、商家发货、虚拟发货、自提点核销、物流跟踪
#### 分销推广:分销模式、绑定模式、分销推广、返佣设置、佣金提现、拼团返佣
#### 用户:用户等级、付费会员(SVIP)、用户管理
#### 客服:客服管理、客服工作台
#### 第三方设置:短信、商品采集、小票打印、电子面单打印、物流查询、云存储
#### 多终端适配:小程序、公众号、H5、APP、PC端
#### 系统设置:开发配置、安全维护、城市数据、权限控制、消息管理、多语言包、在线升级
#### 方便二开:接口管理、代码自动生成、文件和数据库备注管理、自动生成接口文档、业务与开发权限分管
![输入图片说明](readme/pic/PHP功能列表.jpg)
产品BUG、优化建议,欢迎社区反馈:https://www.crmeb.com/ask/thread/list?id=147
---
### 📖 UI界面展示
![输入图片说明](readme/pic/ui_01.jpg)
![输入图片说明](readme/pic/ui_02.jpg)
![输入图片说明](readme/pic/ui2_01.jpg)
![输入图片说明](readme/pic/ui2_02.jpg)
---
### 页面展示
(页面仅展示部分UI)
![输入图片说明](readme/pic/gitee开源版详情_01.jpg)
![输入图片说明](readme/pic/gitee开源版详情_02.jpg)
![输入图片说明](readme/pic/gitee开源版详情_03.jpg)
![输入图片说明](readme/pic/gitee开源版详情_04.jpg)
![输入图片说明](readme/pic/gitee开源版详情_05.jpg)
### 📕 CRMEB公益
做开源,帮助更多人!CRMEB开源项目,不仅让开发者从中受益,也在公益活动中帮助了很多人,对此,我们很荣幸,也乐此不疲!
<div align="center">
<a href='http://s.crmeb.com/goods_detail/739' target='_blank'>点击查看高清版全套UI设计图</a>
</div>
So~~想要用CRMEB开源商城系统做公益项目的朋友,可以来免费申请商业版系统哦!有需要的朋友,快去找官方客服咨询吧!
---
### 💎 捐赠
赠人玫瑰,手留余香!CRMEB诚挚地邀请大家积极参与捐赠,我们会将捐赠获得的费用,悉数用于支持公益项目,让善意无限传递下去!
在此深表感谢~
### 推荐项目(欢迎合作,QQ:763569752 )
---
### 📞 CRMEB互动
#### 技术娱乐!代码写累了?那就歇会吧!扫码让你开心一刻!
![输入图片说明](readme/pic/小剧场.jpg)
#### 技术社区!找方法、提bug、看官方消息、拿活跃大奖!都在 <a href="https://www.crmeb.com/ask" target="_blank">CRMEB 技术社区</a> 应有尽有
#### 技术交流!跟着官方,不迷路!欢迎扫码加入CRMEB 开源项目群,一手消息及资源,尽在掌握!
![输入图片说明](readme/pic/联系我们.jpg)
| 项目名称 | 关注量 | 项目介绍 |
| ------------ | ------------ | ------------ |
| [![](https://img.shields.io/badge/CRMEB-CRMChat-blue.svg)](https://gitee.com/ZhongBangKeJi/CRMChat) | [![](https://gitee.com/ZhongBangKeJi/CRMChat/badge/star.svg)](https://gitee.com/ZhongBangKeJi/CRMChat/stargazers) | CRMChat客服系统,支持接入各种渠道. |
| [![](https://img.shields.io/badge/CRMEB-crmeb_java-blue.svg)](https://gitee.com/ZhongBangKeJi/crmeb_java) | [![](https://gitee.com/ZhongBangKeJi/crmeb_java/badge/star.svg)](https://gitee.com/ZhongBangKeJi/crmeb_java/stargazers) | JAVA版开源商城. |
| [![](https://img.shields.io/badge/xaboy-formbuilder-blue.svg)](https://gitee.com/xaboy/form-builder) | [![](https://gitee.com/xaboy/form-builder/badge/star.svg)](https://gitee.com/xaboy/form-builder/stargazers) | PHP表单生成器,快速生成现代化的form表单。 |
| [![](https://img.shields.io/badge/就眠儀式-LayuiVue-blue.svg)](https://gitee.com/layui/layui-vue) | [![](https://gitee.com/layui/layui-vue/badge/star.svg)](https://gitee.com/layui/layui-vue/stargazers) | layui-vue(谐音:类UI)是一套Vue3.0 的桌面端组件库. |
| [![](https://img.shields.io/badge/逆天的蝈蝈-TpFlow-blue.svg)](https://gitee.com/ntdgg/tpflow) | [![](https://gitee.com/ntdgg/tpflow/badge/star.svg?theme=gvp)](https://gitee.com/ntdgg/tpflow/stargazers) | TpFlow工作流引擎是一套规范化的流程管理系统,基于业务而驱动系统生命力的一套引擎. |
### 商业版购买
开源不易,以下如果有需要,请支持一下,感谢您的支持,让我们更多动力!
[![](readme/pic/gitee2.png)](https://www.crmeb.com/index/criteria)
### 🔥🔥庆祝:CRMEB开源商城系统Gitee star突破10000+ 专属活动福利 [点击了解](https://www.crmeb.com/ask/thread/20738)
### 感谢参与开发者
感谢大神们提交代码(排名不分先后)
---
### 📻 感谢参与开发者
#### 感谢大神们提交代码(排名不分先后)
@yizhisamoye,@bys1123,@xaboy,@youngxj0,@jacklincheung,@392256866,@sxsea
欢迎反馈问题 [反馈问题](https://gitee.com/ZhongBangKeJi/CRMEB/issues)。
欢迎<a href="https://gitee.com/ZhongBangKeJi/CRMEB/issues" target="_blank">反馈问题</a>
欢迎提交代码 [提交代码](https://gitee.com/ZhongBangKeJi/CRMEB/pulls)。
### 特别鸣谢
欢迎<a href="https://gitee.com/ZhongBangKeJi/CRMEB/pulls" target="_blank">提交代码</a>
---
### 📸 特别鸣谢
排名不分先后,感谢这些软件的开发者:thinkphp、iview、vue、mysql、redis、uniapp、echarts、tree-table-vue、swiper、form-create等,如有遗漏请联系我!
### 核心开发团队
---
### 🎬 核心开发团队
产品:木子刀客
技术:聆听、等风来、xaboy、吴汐、最后一片叶、旺仔、小小、娜娜、归来仍是少年
UI:xy-yyds、LXT
测试:夏天、绵绵羊、。ws
测试:夏天、绵绵羊、。ws、半山
### 使用须知
1.允许用于个人学习、毕业设计、教学案例、公益事业、商业使用;
---
### 📺 使用须知
1、允许用于个人学习、毕业设计、教学案例、公益事业、商业使用;
2.如果商用必须保留版权信息,请自觉遵守;
2、如果商用必须保留版权信息,请自觉遵守;
3.禁止将本项目的代码和资源进行任何形式的出售,产生的一切任何后果责任由侵权者自负。
3、禁止将本项目的代码和资源进行任何形式的出售,产生的一切任何后果责任由侵权者自负。
### 版权信息
---
### 💾 版权信息
本项目包含的第三方源码和二进制文件之版权信息另行标注。
@ -173,6 +225,9 @@ All rights reserved。
CRMEB® 商标和著作权所有者为西安众邦网络科技有限公司。
---
[返回顶部 :fa-arrow-circle-up: ](https://gitee.com/ZhongBangKeJi/CRMEB#%E9%A1%B9%E7%9B%AE%E4%BB%8B%E7%BB%8D)

View File

@ -1,5 +1,5 @@
version=CRMEB-KY v5.1.0
version_code=510
version=CRMEB-KY v5.2.0
version_code=520
platform=gitee
app_id=ze7x9rxsv09l6pvsyo
app_key=fuF7U9zaybLa5gageVQzxtxQMFnvU2OI

View File

@ -68,7 +68,7 @@ class PublicController
if ($service->cacheDriver()->get('scan_upload') != $uploadToken) {
return app('json')->fail(410086);
}
$service->upload($pid, $file, $upload_type, $type, '', $uploadToken);
$service->upload((int)$pid, $file, $upload_type, $type, '', $uploadToken);
return app('json')->success(100032);
}
}

File diff suppressed because it is too large Load Diff

View File

@ -111,24 +111,25 @@ class SystemRoute extends AuthController
['describe', ''],
]);
if (!$data['name']) {
return app('json')->fail(500031);
}
if (!$data['path']) {
return app('json')->fail(500032);
}
if (!$data['method']) {
return app('json')->fail(500033);
}
if (!$data['app_name']) {
return app('json')->fail(500034);
}
// if (!$data['name']) {
// return app('json')->fail(500031);
// }
// if (!$data['path']) {
// return app('json')->fail(500032);
// }
// if (!$data['method']) {
// return app('json')->fail(500033);
// }
// if (!$data['app_name']) {
// return app('json')->fail(500034);
// }
if ($id) {
$this->services->update($id, $data);
} else {
$data['add_time'] = date('Y-m-d H:i:s');
$this->services->save($data);
}
$this->services->cacheDriver()->clear();
return app('json')->success($id ? 100001 : 100021);
}

View File

@ -51,6 +51,8 @@ class PublicController
$data['site_keywords'] = sys_config('site_keywords');
$data['site_description'] = sys_config('site_description');
$data['network_security'] = sys_config('network_security');
$data['network_security_url'] = sys_config('network_security_url');
$data['icp_url'] = sys_config('icp_url');
$logoUrl = sys_config('pc_logo');
if (strstr($logoUrl, 'http') === false && $logoUrl) {
$logoUrl = sys_config('site_url') . $logoUrl;

View File

@ -23,6 +23,7 @@ use app\services\system\lang\LangCodeServices;
use app\services\system\lang\LangCountryServices;
use think\facade\Config;
use think\facade\Log;
use think\facade\Db;
if (!function_exists('crmebLog')) {
/**
@ -1090,3 +1091,19 @@ if (!function_exists('out_push')) {
return true;
}
}
if (!function_exists('dump_sql')) {
/**
* 默认数据推送
* @param string $pushUrl
* @param array $data
* @param string $tip
* @return bool
*/
function dump_sql()
{
Db::listen(function ($sql) {
var_dump($sql);
});
}
}

View File

@ -72,6 +72,17 @@ class StoreCouponIssueDao extends BaseDao
->page($page, $limit)->order('id desc')->select()->toArray();
}
/**
* 优惠券数量
* @param $where
* @return int
* @throws \ReflectionException
*/
public function couponCount($where): int
{
return $this->search($where)->count();
}
/**
* 获取优惠券列表
* @param int $uid 用户ID

View File

@ -95,7 +95,7 @@ class StoreIntegralOrderDao extends BaseDao
*/
public function count(array $where = [], bool $search = true)
{
return $this->search($where, $search)->count();
return $this->search($where)->count();
}
/**

View File

@ -41,7 +41,7 @@ class StoreSeckillDao extends BaseDao
*/
public function search(array $where = [], bool $search = false)
{
return parent::search($where, $search)->when(isset($where['seckllTime']), function ($query) use ($where) {
return parent::search($where)->when(isset($where['seckllTime']), function ($query) use ($where) {
[$startTime, $stopTime] = is_array($where['seckllTime']) ? $where['seckllTime'] : [time(), time() - 86400];
$query->where('start_time', '<=', $startTime)->where('stop_time', '>=', $stopTime);
})->when(isset($where['sid']) && $where['sid'], function ($query) use ($where) {
@ -67,6 +67,7 @@ class StoreSeckillDao extends BaseDao
* 条件获取数量
* @param array $where
* @return int
* @throws \ReflectionException
*/
public function getCount(array $where)
{

View File

@ -130,7 +130,8 @@ class User extends AuthController
public function info($uid)
{
if (!$uid) return app('json')->fail(100100);
return app('json')->success($this->services->userInfo($uid));
$data = $this->services->userInfo($uid);
return app('json')->success(compact('data'));
}
/**

View File

@ -65,8 +65,7 @@ class StoreCouponIssueServices extends BaseServices
foreach ($list as &$item) {
$item['use_time'] = date('Y-m-d', $item['start_use_time']) . ' ~ ' . date('Y-m-d', $item['end_use_time']);
}
// unset($where['type'], $where['receive_type']);
$count = $this->dao->count($where);
$count = $this->dao->couponCount($where);
return compact('list', 'count');
}

View File

@ -210,7 +210,9 @@ class LuckLotteryServices extends BaseServices
$luckPrizeServices = app()->make(LuckPrizeServices::class);
$data = [];
$sort = 1;
$prizeStatus = false;
foreach ($prizes as $prize) {
if (isset($prize['type']) && $prize['type'] == 1) $prizeStatus = true;
$prize = $luckPrizeServices->checkPrizeData($prize);
$prize['lottery_id'] = $lottery->id;
unset($prize['id']);
@ -219,6 +221,9 @@ class LuckLotteryServices extends BaseServices
$data[] = $prize;
$sort++;
}
if (!$prizeStatus) {
throw new AdminException('必须设置至少一个未中奖');
}
if (!$luckPrizeServices->saveAll($data)) {
throw new AdminException(400536);
}
@ -261,7 +266,9 @@ class LuckLotteryServices extends BaseServices
$insert = [];
$time = time();
$sort = 1;
$prizeStatus = false;
foreach ($newPrizes as $prize) {
if (isset($prize['type']) && $prize['type'] == 1) $prizeStatus = true;
$prize = $luckPrizeServices->checkPrizeData($prize);
$prize['sort'] = $sort;
if (isset($prize['id']) && $prize['id']) {
@ -280,6 +287,9 @@ class LuckLotteryServices extends BaseServices
}
$sort++;
}
if (!$prizeStatus) {
throw new AdminException('必须设置至少一个未中奖');
}
if ($insert) {
if (!$luckPrizeServices->saveAll($insert)) {
throw new AdminException(100022);

View File

@ -201,6 +201,9 @@ class SystemRouteServices extends BaseServices
{
$oneId = app()->make(SystemRouteCateServices::class)->value(['app_name' => $app, 'name' => $cateName, 'pid' => 0], 'id');
if (!$oneId) {
//修复重复同步后反复增加二级文件夹
$id = app()->make(SystemRouteCateServices::class)->value(['app_name' => $app, 'name' => $cateName, 'pid' => $pid], 'id');
if ($id) return $id;
$res = app()->make(SystemRouteCateServices::class)->save([
'app_name' => $app,
'name' => $cateName,

View File

@ -91,6 +91,7 @@ class SystemConfigServices extends BaseServices
'spread_banner' => '',
'brokerage_level' => '',
'division_status' => '',
'agent_apply_open' => '',
],
'show_value' => 1
],

View File

@ -15,6 +15,7 @@ namespace app\services\user;
use app\dao\user\UserDao;
use app\services\activity\coupon\StoreCouponIssueServices;
use app\services\agent\AgentLevelServices;
use app\services\BaseServices;
use app\services\system\SystemUserLevelServices;
use crmeb\exceptions\ApiException;
@ -92,9 +93,19 @@ class OutUserServices extends BaseServices
*/
public function userInfo($uid)
{
$userType = ['h5' => 'H5', 'wechat' => '公众号', 'routine' => '小程序', 'app' => 'APP', 'pc' => 'PC'];
$fields = ['uid', 'real_name', 'mark', 'nickname', 'avatar', 'phone', 'now_money', 'brokerage_price', 'integral', 'exp', 'sign_num', 'user_type', 'status', 'level',
'agent_level', 'spread_open', 'spread_uid', 'spread_time', 'user_type', 'is_promoter', 'pay_count', 'is_ever_level', 'is_money_level', 'overdue_time', 'add_time'];
return app()->make(UserServices::class)->get($uid, $fields);
$data = app()->make(UserServices::class)->get($uid, $fields);
$data['user_type'] = $userType[$data['user_type']];
$data['status'] = $data['status'] ? '正常' : '禁用';
$data['level'] = app()->make(SystemUserLevelServices::class)->value($data['level'], 'name') ?? '无';
$data['agent_level'] = app()->make(AgentLevelServices::class)->value($data['agent_level'], 'name') ?? '无';
$data['spread_open'] = $data['spread_open'] ? '分销开启' : '分销关闭';
$data['spread_name'] = app()->make(UserServices::class)->value($data['spread_uid'], 'nickname') ?? '无';
$data['spread_time'] = date('Y-m-d H:i:s', $data['spread_time']);
$data['add_time'] = date('Y-m-d H:i:s', $data['add_time']);
return $data;
}
/**

View File

@ -2041,6 +2041,17 @@ class UserServices extends BaseServices
if (!$userInfo) {
return false;
}
//根据手机号码查询此用户注销过,不反推广佣金
if ($userInfo['phone'] != '' && $this->dao->getCount(['phone' => $userInfo['phone'], 'is_del' => 1])) {
return false;
}
//根据openid查询此用户注销过,不反推广佣金
$openidArray = app()->make(WechatUserServices::class)->getColumn(['uid' => $uid], 'openid', 'id');
if ($this->dao->getCount([['openid', 'in', $openidArray], ['is_del', '=', 1]])) {
return false;
}
if (!$spread_user) {
$spread_user = $this->dao->getOne(['uid' => $spread_uid, 'status' => 1]);
}

View File

@ -395,8 +395,7 @@ class WechatServices extends BaseServices
if (!$uid && !$res) {
return false;
}
}
if ($openid && $storeUserMobile) {
} elseif ($openid && $storeUserMobile) {
/** @var UserServices $userServices */
$userServices = app()->make(UserServices::class);
$uid = $this->dao->value(['openid' => $openid], 'uid');

View File

@ -4,36 +4,19 @@ namespace crmeb\services\easywechat\orderShipping;
use crmeb\exceptions\AdminException;
use crmeb\services\CacheService;
use EasyWeChat\Core\AccessToken;
use EasyWeChat\Core\Exceptions\HttpException;
use think\facade\Cache;
class OrderClient extends BaseOrder
{
const redis_prefix = 'mini_order';
const cache_prefix = 'mini_order';
const express_company = 'ZTO'; // 默认发货快递公司为(中通快递)
/**
* @var \Redis
* @var
*/
protected $redis;
/**
* @return object|\Redis|null
*
* @date 2023/05/10
* @author yyw
*/
protected function getRedis()
{
if (empty($this->redis)) {
$this->redis = Cache::store('redis')->handler();
}
return $this->redis;
}
protected $cache;
/**
* 处理联系人
@ -214,8 +197,8 @@ class OrderClient extends BaseOrder
{
$res = $this->isManaged();
if ($res['is_trade_managed']) {
$key = self::redis_prefix . '_is_trade_managed';
$this->getRedis()->set($key, $res['is_trade_managed']);
$key = self::cache_prefix . '_is_trade_managed';
CacheService::set($key, $res['is_trade_managed']);
return true;
} else {
return false;
@ -232,8 +215,8 @@ class OrderClient extends BaseOrder
*/
public function checkManaged()
{
$key = self::redis_prefix . '_is_trade_managed';
if ($this->getRedis()->exists($key)) {
$key = self::cache_prefix . '_is_trade_managed';
if (CacheService::get($key)) {
return true;
} else {
return $this->setManaged();
@ -252,10 +235,10 @@ class OrderClient extends BaseOrder
{
$list = $this->getDeliveryList();
if ($list) {
$key = self::redis_prefix . '_delivery_list';
$key = self::cache_prefix . '_delivery_list';
$date = array_column($list['delivery_list'], 'delivery_id', 'delivery_name');
// 创建缓存
$this->getRedis()->hMSet($key, $date);
CacheService::set($key, json_encode($date));
return $date;
} else {
@ -274,15 +257,14 @@ class OrderClient extends BaseOrder
*/
public function getDelivery($company_name)
{
$key = self::redis_prefix . '_delivery_list';
if (!$this->getRedis()->exists($key)) {
$key = self::cache_prefix . '_delivery_list';
if (!CacheService::get($key)) {
$date = $this->setDeliveryList();
$express_company = $date[$company_name] ?? '';
} else {
$express_company = $this->getRedis()->hMGet($key, [$company_name])[$company_name] ?? '';
$express_company = json_decode(CacheService::get($key), true)[$company_name] ?? '';
}
if (empty($express_company)) {
// throw new AdminException('物流公司异常2');
$express_company = self::express_company;
}

View File

@ -440,14 +440,11 @@ class Cos extends BaseUpload
public function deleteBucket(string $name)
{
try {
$res = $this->app()->deleteBucket($name);
if ($res->get('RequestId')) {
return true;
}
$this->app()->deleteBucket($name);
return true;
} catch (\Throwable $e) {
return $this->setError($e->getMessage());
}
return false;
}
/**
@ -459,8 +456,8 @@ class Cos extends BaseUpload
{
$this->storageRegion = $region;
try {
$res = $this->app()->GetBucketDomain($name);
$domainRules = $res->toArray()['DomainRules'];
$res = $this->app()->getBucketDomain($name);
$domainRules = $res['DomainRules'];
return array_column($domainRules, 'Name');
} catch (\Throwable $e) {
}
@ -533,11 +530,11 @@ class Cos extends BaseUpload
{
$this->storageRegion = $region;
try {
$res = $this->app()->PutBucketCors($name, [
'AllowedHeaders' => ['*'],
'AllowedMethods' => ['PUT', 'GET', 'POST', 'DELETE', 'HEAD'],
'AllowedOrigins' => ['*'],
'ExposeHeaders' => ['ETag', 'Content-Length', 'x-cos-request-id'],
$res = $this->app()->putBucketCors($name, [
'AllowedHeader' => ['*'],
'AllowedMethod' => ['PUT', 'GET', 'POST', 'DELETE', 'HEAD'],
'AllowedOrigin' => ['*'],
'ExposeHeader' => ['ETag', 'Content-Length', 'x-cos-request-id'],
'MaxAgeSeconds' => 12
]);
if (isset($res['RequestId'])) {

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 911 KiB

BIN
readme/pic/ui.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB

BIN
readme/pic/ui2.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 656 KiB

BIN
readme/pic/ui2_01.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 173 KiB

BIN
readme/pic/ui2_02.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 167 KiB

BIN
readme/pic/ui_01.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 372 KiB

BIN
readme/pic/ui_02.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 266 KiB

BIN
readme/pic/小剧场.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 246 KiB

BIN
readme/pic/联系我们.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 226 KiB

View File

@ -13,7 +13,7 @@
v-model="formValidate.cate_id"
size="small"
:options="treeSelect"
:props="{ emitPath: false }"
:props="{ checkStrictly: true, emitPath: false }"
clearable
></el-cascader>
</el-form-item>

View File

@ -402,6 +402,7 @@ export default {
pid: this.pids,
images: this.ids.toString(),
};
if (!data.images) return;
moveApi(data)
.then(async (res) => {
this.$message.success(res.msg);

View File

@ -67,7 +67,7 @@
<!-- <el-dropdown-item name="10" v-show="scope.row._status >= 2">订单打印</el-dropdown-item> -->
<el-dropdown-item command="4" v-show="scope.row.status !== 4">订单备注</el-dropdown-item>
<el-dropdown-item command="8" v-show="scope.row.status === 2">已收货</el-dropdown-item>
<!-- <el-dropdown-item name="9">删除订单</el-dropdown-item> -->
<el-dropdown-item command="9" v-show="row.is_del === 1">删除订单</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</template>

View File

@ -96,9 +96,23 @@
>虚拟发货备注:{{ orderDatalist.orderInfo.fictitious_content }}</el-col
>
</el-row>
<el-divider></el-divider>
<div class="ivu-description-list-title">商品信息</div>
<el-row class="mb10">
<div class="tabBox" v-for="(val, i) in orderDatalist.orderInfo.cartInfo" :key="i">
<div class="tabBox_img" v-viewer>
<img v-lazy="val.productInfo.attrInfo ? val.productInfo.attrInfo.image : val.productInfo.image" />
</div>
<span class="tabBox_tit"
>{{ val.productInfo.store_name + ' | '
}}{{ val.productInfo.attrInfo ? val.productInfo.attrInfo.suk : '' }}</span
>
<span class="tabBox_pice">{{ '¥' + val.truePrice + ' x ' + val.cart_num }}</span>
</div>
</el-row>
<el-divider></el-divider>
<div v-if="orderDatalist.orderInfo.invoice">
<Divider style="margin: 20px 0 !important" />
<el-divider></el-divider>
<div class="ivu-description-list-title">发票信息</div>
<el-row class="mb10">
<el-col span="12">发票抬头:{{ orderDatalist.orderInfo.invoice.name }}</el-col>
@ -150,7 +164,6 @@
<el-col span="12">联系邮箱:{{ orderDatalist.orderInfo.invoice.email || '' }}</el-col>
<el-col span="12">联系电话:{{ orderDatalist.orderInfo.invoice.user_phone || '' }}</el-col>
</el-row>
<div v-if="orderDatalist.orderInfo.invoice.header_type === 2 && orderDatalist.orderInfo.invoice.type === 2">
<el-row class="mb10">
<el-col span="12"
@ -187,8 +200,7 @@
<el-col span="12">开票状态:{{ orderDatalist.orderInfo.invoice.is_invoice ? '已开票' : '未开票' }}</el-col>
</el-row>
</div>
<Divider style="margin: 20px 0 !important" v-if="orderDatalist.orderInfo.custom_form.length" />
<el-divider v-if="orderDatalist.orderInfo.custom_form.length"></el-divider>
<div class="ivu-description-list-title" v-if="orderDatalist.orderInfo.custom_form.length">表单信息</div>
<el-row class="mb10" v-if="orderDatalist.orderInfo.custom_form.length">
<el-col
@ -429,4 +441,15 @@ export default {
height: 100%;
}
}
.tabBox{
display:flex;
align-items center
.tabBox_img{
margin-right 10px
}
.tabBox_tit{
margin-right 20px
}
}
</style>

View File

@ -13,11 +13,6 @@
<el-row :gutter="24">
<el-col v-bind="grid">
<el-form-item label="商品分类:" label-for="pid">
<!-- <el-select v-model="artFrom.cate_id" placeholder="请选择商品分类" clearable @change="userSearchs">
<el-option v-for="item in treeSelect" :value="item.id" :key="item.id">{{
item.html + item.cate_name
}}</el-option>
</el-select> -->
<el-cascader
v-model="artFrom.cate_id"
size="small"

View File

@ -674,8 +674,7 @@ export default {
}
})
.catch((err) => {
console.log(err);
this.$message.error(err);
this.$message.error(err.msg);
});
} catch (error) {
console.log(error);
@ -696,7 +695,7 @@ export default {
this.formValidate = res.data;
})
.catch((err) => {
this.$message.error(err);
this.$message.error(err.msg);
});
},
async handleSubmit() {
@ -718,7 +717,7 @@ export default {
this.getRoteData(this.paramsId);
})
.catch((err) => {
this.$message.error(err);
this.$message.error(err.msg);
});
},
async insertEvent(type) {
@ -833,7 +832,7 @@ export default {
this.getInterfaceList();
})
.catch((err) => {
this.$message.error(err);
this.$message.error(err.msg);
});
},
//侧边栏右键点击事件
@ -938,7 +937,7 @@ export default {
node.remove();
})
.catch((err) => {
this.$message.error(err);
this.$message.error(err.msg);
});
},
onCancel: () => {},
@ -956,7 +955,7 @@ export default {
this.$message.success(res.msg);
})
.catch((err) => {
this.$message.error(err);
this.$message.error(err.msg);
});
}
},

View File

@ -213,8 +213,9 @@ body {
font-size: 13px;
padding: 10px 5px !important;
}
.ivu-form .ivu-form-item-label,
.ivu-form .ivu-form-item-label {
font-size: 12px !important;
}
.ivu-radio-group-button .ivu-radio-wrapper,
.ivu-table {
font-size: 13px !important;

View File

@ -151,7 +151,7 @@
*
*/
bindCode: function(e) {
this.$emit('iptCartNum', this.attr.productSelect.cart_num);
this.$emit('iptCartNum', e);
},
closeAttr: function() {
this.$emit('myevent');

View File

@ -13,7 +13,7 @@ module.exports = {
// 后台版本号
SYSTEM_VERSION: 510,
SYSTEM_VERSION: 520,
// 以下配置在不做二开的前提下,不需要做任何的修改
HEADER: {

View File

@ -806,7 +806,15 @@
*
*/
iptCartNum: function(e) {
this.$set(this.attr.productSelect, "cart_num", e);
if (e) {
let number = 1
if (Number.isInteger(parseInt(e)) && parseInt(e) > 0) {
number = parseInt(e);
}
this.$nextTick(e => {
this.$set(this.attr.productSelect, "cart_num", e < 0 ? 1 : number);
})
}
},
// 后退
returns() {

View File

@ -18,7 +18,7 @@
</form> -->
<view class='search acea-row row-between-wrapper'>
<view class='input'><input :placeholder='$t(`点击搜索会员名称`)' placeholder-class='placeholder'
<view class='input'><input :placeholder='$t(`点击搜索名称`)' placeholder-class='placeholder'
v-model="keyword" @confirm="submitForm" confirm-type='search' name="search"></input></view>
<button class='iconfont icon-sousuo2' @click="submitForm"></button>
</view>

View File

@ -4,7 +4,7 @@
<view class='promoterHeader bg-color'>
<view class='headerCon acea-row row-between-wrapper'>
<view>
<view class='name'>{{$t(`累积推广订单`)}}</view>
<view class='name'>{{$t(`累计推广订单`)}}</view>
<view><text class='num'>{{count || 0}}</text>{{$t(`单`)}}</view>
</view>
<view class='iconfont icon-2'></view>
@ -34,9 +34,7 @@
</view>
<view class='bottom'>
<view><text class='name'>{{$t(`订单编号`)}}:</text>{{child.order_id}}</view>
<view v-if="child.type == 'brokerage'"><text
class='name'>{{$t(`返佣时间`)}}:</text>{{child.time}}</view>
<view v-else><text class='name'>{{$t(`下单时间`)}}:</text>{{child.time}}</view>
<view><text class='name'>{{$t(`下单时间`)}}:</text>{{child.time}}</view>
<view class="more" v-if="child.children && child.children.length"
@click="open(child)">
{{child.open?$t(`收起`):$t(`更多`)}}

View File

@ -22,11 +22,11 @@
<!-- #endif -->
<!-- #ifdef MP -->
<button hover-class="none" v-if="mp_is_new" @tap="userLogin"
class="bg-green btn1">{{$t(`微信登录`)}}</button>
class="bg-green btn1">{{$t(`授权登录`)}}</button>
<button v-else-if="canUseGetUserProfile && code" hover-class="none" @tap="getUserProfile"
class="bg-green btn1">{{$t(`微信登录`)}}</button>
class="bg-green btn1">{{$t(`授权登录`)}}</button>
<button v-else hover-class="none" open-type="getUserInfo" @getuserinfo="setUserInfo"
class="bg-green btn1">{{$t(`微信登录`)}}</button>
class="bg-green btn1">{{$t(`授权登录`)}}</button>
<!-- #endif -->
<!-- <button hover-class="none" @click="phoneLogin" class="btn2">{{$t(`手机号登录`)}}</button> -->
</view>