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
197
README.md
@ -1,10 +1,10 @@
|
||||

|
||||
|
||||
<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>
|
||||
|
||||
|
||||
### 系统演示
|
||||
### 📱 系统演示
|
||||
|
||||

|
||||
|
||||
管理后台: 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端
|
||||
#### 系统设置:开发配置、安全维护、城市数据、权限控制、消息管理、多语言包、在线升级
|
||||
#### 方便二开:接口管理、代码自动生成、文件和数据库备注管理、自动生成接口文档、业务与开发权限分管
|
||||
|
||||

|
||||
|
||||
|
||||
产品BUG、优化建议,欢迎社区反馈:https://www.crmeb.com/ask/thread/list?id=147
|
||||
---
|
||||
|
||||
### 📖 UI界面展示
|
||||
|
||||

|
||||

|
||||

|
||||

|
||||
|
||||
---
|
||||
|
||||
|
||||
### 页面展示
|
||||
(页面仅展示部分UI)
|
||||

|
||||

|
||||

|
||||

|
||||

|
||||
### 📕 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互动
|
||||
#### 技术娱乐!代码写累了?那就歇会吧!扫码让你开心一刻!
|
||||

|
||||
#### 技术社区!找方法、提bug、看官方消息、拿活跃大奖!都在 <a href="https://www.crmeb.com/ask" target="_blank">CRMEB 技术社区</a> 应有尽有
|
||||
#### 技术交流!跟着官方,不迷路!欢迎扫码加入CRMEB 开源项目群,一手消息及资源,尽在掌握!
|
||||

|
||||
|
||||
| 项目名称 | 关注量 | 项目介绍 |
|
||||
| ------------ | ------------ | ------------ |
|
||||
| [](https://gitee.com/ZhongBangKeJi/CRMChat) | [](https://gitee.com/ZhongBangKeJi/CRMChat/stargazers) | CRMChat客服系统,支持接入各种渠道. |
|
||||
| [](https://gitee.com/ZhongBangKeJi/crmeb_java) | [](https://gitee.com/ZhongBangKeJi/crmeb_java/stargazers) | JAVA版开源商城. |
|
||||
| [](https://gitee.com/xaboy/form-builder) | [](https://gitee.com/xaboy/form-builder/stargazers) | PHP表单生成器,快速生成现代化的form表单。 |
|
||||
| [](https://gitee.com/layui/layui-vue) | [](https://gitee.com/layui/layui-vue/stargazers) | layui-vue(谐音:类UI)是一套Vue3.0 的桌面端组件库. |
|
||||
| [](https://gitee.com/ntdgg/tpflow) | [](https://gitee.com/ntdgg/tpflow/stargazers) | TpFlow工作流引擎是一套规范化的流程管理系统,基于业务而驱动系统生命力的一套引擎. |
|
||||
|
||||
### 商业版购买
|
||||
开源不易,以下如果有需要,请支持一下,感谢您的支持,让我们更多动力!
|
||||
|
||||
[](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)
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -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)
|
||||
{
|
||||
|
||||
@ -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'));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -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');
|
||||
}
|
||||
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -91,6 +91,7 @@ class SystemConfigServices extends BaseServices
|
||||
'spread_banner' => '',
|
||||
'brokerage_level' => '',
|
||||
'division_status' => '',
|
||||
'agent_apply_open' => '',
|
||||
],
|
||||
'show_value' => 1
|
||||
],
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -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]);
|
||||
}
|
||||
|
||||
@ -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');
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -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'])) {
|
||||
|
||||
BIN
readme/pic/PHP功能列表.jpg
Normal file
|
After Width: | Height: | Size: 911 KiB |
BIN
readme/pic/ui.jpg
Normal file
|
After Width: | Height: | Size: 1.0 MiB |
BIN
readme/pic/ui2.jpg
Normal file
|
After Width: | Height: | Size: 656 KiB |
BIN
readme/pic/ui2_01.jpg
Normal file
|
After Width: | Height: | Size: 173 KiB |
BIN
readme/pic/ui2_02.jpg
Normal file
|
After Width: | Height: | Size: 167 KiB |
BIN
readme/pic/ui_01.jpg
Normal file
|
After Width: | Height: | Size: 372 KiB |
BIN
readme/pic/ui_02.jpg
Normal file
|
After Width: | Height: | Size: 266 KiB |
BIN
readme/pic/小剧场.jpg
Normal file
|
After Width: | Height: | Size: 246 KiB |
BIN
readme/pic/联系我们.jpg
Normal file
|
After Width: | Height: | Size: 226 KiB |
@ -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>
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -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"
|
||||
|
||||
@ -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);
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -151,7 +151,7 @@
|
||||
*
|
||||
*/
|
||||
bindCode: function(e) {
|
||||
this.$emit('iptCartNum', this.attr.productSelect.cart_num);
|
||||
this.$emit('iptCartNum', e);
|
||||
},
|
||||
closeAttr: function() {
|
||||
this.$emit('myevent');
|
||||
|
||||
@ -13,7 +13,7 @@ module.exports = {
|
||||
|
||||
|
||||
// 后台版本号
|
||||
SYSTEM_VERSION: 510,
|
||||
SYSTEM_VERSION: 520,
|
||||
|
||||
// 以下配置在不做二开的前提下,不需要做任何的修改
|
||||
HEADER: {
|
||||
|
||||
@ -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() {
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -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(`更多`)}}
|
||||
|
||||
@ -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>
|
||||
|
||||