Compare commits

...

10 Commits

Author SHA1 Message Date
8a1cd5266a doc:修复文档格式错误 2021-07-16 16:33:51 +08:00
11c6c651d8 v1.1.46 2021-07-16 16:31:39 +08:00
45423fa76c v1.1.45 2021-07-16 16:26:32 +08:00
68bc138f6a doc:修复文档格式错误 2020-08-28 10:46:27 +08:00
1922b35cba v1.1.44 2020-08-28 10:41:05 +08:00
46d47de0fb v1.1.43 2020-08-28 10:38:52 +08:00
88b78878f8 v1.1.42 2020-08-28 10:35:48 +08:00
6ec2a91921 1.1.41 2020-04-25 22:53:20 +08:00
dd83a2e9da 1.1.40 2020-04-25 22:48:24 +08:00
1d59f59117 1.1.39-fix
更新README.md
2020-04-25 22:36:14 +08:00
142 changed files with 14503 additions and 1430 deletions

View File

@ -10,6 +10,102 @@
## 更新日志 ## 更新日志
### v1.1.46
```
优化:兼容新版微信小程序授权登录
优化:微信支付下单时记录日志
优化:后台修改会员等级时默认选中
优化:获取海报图出错时抛错
优化:小程序端资讯列表页支持指定分类
修复:订单结算时计算优惠券精度问题
修复:后台新增优惠券报错
修复:删除购物车后更新角标数量
修复:小程序端倒计时组件报错
注:本次更新须重新发布小程序
```
### v1.1.45
```
新增:优惠券支持指定商品
新增:小程序端底部购物车数量(角标)
优化微信退款API记录日志
优化:整点秒杀页面倒计时结束刷新
修复:后台满额包邮地区总数错误
修复:后台分销商确认打款时报错
注:本次更新须重新发布小程序
```
### v1.1.44
```
新增:小程序转发到朋友圈(灰度安卓用户)
优化:微信打款时验证冻结资金是否合法
优化mysql报错时记录Error SQL
修复:后台权限缺少文件列表和回收站
修复:地区表中部分地区不存在
修复:获取直播房间列表接口报错
修复:后台订单详情页报错
修复:小程序端富文本视频高度不生效
注:本次更新须重新发布小程序
```
### v1.1.43
```
优化mysql5.7环境数据排序问题
优化:秒杀商品不允许付款减库存
优化小票打印机API记录日志
优化:调整拼团拼单失效时间
修复:后台订单导出未下载问题
修复后台添加角色cdn资源加载超时
修复:后台分销提现列表打款方式
修复:拼团订单手动退款权限问题
修复:验证会员等级权重是否存在
修复:超管后台判断商家用户名重复
注:本次更新须重新发布小程序
```
### v1.1.42
```
新增:分享小程序直播间绑定分销关系
修复小程序端ID selectors报错问题
修复:后台直播间管理置顶报错
修复取消确认弹框后未关闭loading
修复:直播间列表为空时同步失败
修复:收货地址过长发送订阅消息失败
修复:后台审核拼团订单退货报错
修复:小程序端未配置订阅消息提交表单
修复:小程序端秒杀商品分享时无标题
注:本次更新须重新发布小程序
```
### v1.1.41
```
新增:微信小程序订阅消息
修复多开小程序直播间同步ID问题
修复库存1下单后提示商品库存不足
修复拼团商品预览sku图片报错
优化:超管后台删除商家用户
注:本次更新须重新发布小程序
```
### v1.1.40
```
新增:微信小程序直播功能
优化:商品评价过滤无效内容
注:本次更新须重新发布小程序
```
### v1.1.39 ### v1.1.39
``` ```
@ -25,9 +121,8 @@
修复:订单支付成功短信提醒 修复:订单支付成功短信提醒
修复:砍价商品列表价格排序报错 修复:砍价商品列表价格排序报错
修复:小程序端订单页未支付提示 修复:小程序端订单页未支付提示
--------------------------------
注:本次更新须重新发布小程序
注:本次更新须重新发布小程序
``` ```
### v1.1.38 ### v1.1.38

View File

@ -56,7 +56,8 @@ CREATE TABLE `yoshop_coupon` (
`expire_day` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '领取后生效-有效天数', `expire_day` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '领取后生效-有效天数',
`start_time` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '固定时间-开始时间', `start_time` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '固定时间-开始时间',
`end_time` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '固定时间-结束时间', `end_time` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '固定时间-结束时间',
`apply_range` tinyint(3) unsigned NOT NULL DEFAULT '10' COMMENT '适用范围(10全部商品 20指定商品)', `apply_range` tinyint(3) unsigned NOT NULL DEFAULT '10' COMMENT '适用范围(10全部商品 20指定商品 30排除商品)',
`apply_range_config` text NOT NULL COMMENT '适用范围配置(json格式)',
`total_num` int(11) NOT NULL DEFAULT '0' COMMENT '发放总数量(-1为不限制)', `total_num` int(11) NOT NULL DEFAULT '0' COMMENT '发放总数量(-1为不限制)',
`receive_num` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '已领取数量', `receive_num` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '已领取数量',
`sort` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '排序方式(数字越小越靠前)', `sort` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '排序方式(数字越小越靠前)',
@ -68,17 +69,6 @@ CREATE TABLE `yoshop_coupon` (
) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=utf8 COMMENT='优惠券记录表'; ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=utf8 COMMENT='优惠券记录表';
CREATE TABLE `yoshop_coupon_goods` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键id',
`coupon_id` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '优惠券id',
`goods_id` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '商品id',
`wxapp_id` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '小程序id',
`create_time` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '创建时间',
`update_time` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '更新时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=utf8 COMMENT='优惠券指定商品记录表';
CREATE TABLE `yoshop_delivery` ( CREATE TABLE `yoshop_delivery` (
`delivery_id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '模板id', `delivery_id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '模板id',
`name` varchar(255) NOT NULL DEFAULT '' COMMENT '模板名称', `name` varchar(255) NOT NULL DEFAULT '' COMMENT '模板名称',
@ -4200,7 +4190,8 @@ CREATE TABLE `yoshop_user_coupon` (
`expire_day` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '领取后生效-有效天数', `expire_day` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '领取后生效-有效天数',
`start_time` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '有效期开始时间', `start_time` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '有效期开始时间',
`end_time` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '有效期结束时间', `end_time` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '有效期结束时间',
`apply_range` tinyint(3) unsigned NOT NULL DEFAULT '10' COMMENT '适用范围(10全部商品 20指定商品)', `apply_range` tinyint(3) unsigned NOT NULL DEFAULT '10' COMMENT '适用范围(10全部商品 20指定商品 30排除商品)',
`apply_range_config` text NOT NULL COMMENT '适用范围配置(json格式)',
`is_expire` tinyint(3) unsigned NOT NULL DEFAULT '0' COMMENT '是否过期(0未过期 1已过期)', `is_expire` tinyint(3) unsigned NOT NULL DEFAULT '0' COMMENT '是否过期(0未过期 1已过期)',
`is_use` tinyint(3) unsigned NOT NULL DEFAULT '0' COMMENT '是否已使用(0未使用 1已使用)', `is_use` tinyint(3) unsigned NOT NULL DEFAULT '0' COMMENT '是否已使用(0未使用 1已使用)',
`user_id` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '用户id', `user_id` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '用户id',
@ -4716,6 +4707,12 @@ INSERT INTO `yoshop_store_access` VALUES ('10438', '积分管理', 'market.point
INSERT INTO `yoshop_store_access` VALUES ('11003', '数据统计', 'statistics.data/index', '0', '138', '1572507520', '1572507520'); INSERT INTO `yoshop_store_access` VALUES ('11003', '数据统计', 'statistics.data/index', '0', '138', '1572507520', '1572507520');
INSERT INTO `yoshop_store_access` (`access_id`, `name`, `url`, `parent_id`, `sort`, `create_time`, `update_time`) VALUES ('10462', '小程序直播', 'apps.live', '10074', '125', '1585120375', '1585120375');
INSERT INTO `yoshop_store_access` (`access_id`, `name`, `url`, `parent_id`, `sort`, `create_time`, `update_time`) VALUES ('10463', '直播间管理', 'apps.live.room/index', '10462', '100', '1585120404', '1585120404');
INSERT INTO `yoshop_store_access` (`access_id`, `name`, `url`, `parent_id`, `sort`, `create_time`, `update_time`) VALUES ('10464', '同步刷新', 'apps.live.room/refresh', '10463', '100', '1585120404', '1585120404');
INSERT INTO `yoshop_store_access` (`access_id`, `name`, `url`, `parent_id`, `sort`, `create_time`, `update_time`) VALUES ('10465', '设置置顶状态', 'apps.live.room/refresh', '10463', '100', '1585120404', '1585120404');
# 商家用户角色表 # 商家用户角色表
@ -5597,3 +5594,22 @@ INSERT INTO `yoshop_store_access` VALUES ('10460', '删除场次', 'apps.sharp.a
INSERT INTO `yoshop_store_access` VALUES ('10461', '基础设置', 'apps.sharp.setting/index', '10444', '125', '1564449650', '1564449650'); INSERT INTO `yoshop_store_access` VALUES ('10461', '基础设置', 'apps.sharp.setting/index', '10444', '125', '1564449650', '1564449650');
CREATE TABLE `yoshop_wxapp_live_room` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键id',
`room_id` int(11) unsigned NOT NULL COMMENT '直播间id',
`room_name` varchar(200) NOT NULL DEFAULT '' COMMENT '直播间名称',
`cover_img` varchar(255) DEFAULT '' COMMENT '分享卡片封面',
`share_img` varchar(255) DEFAULT '' COMMENT '直播间背景墙封面',
`anchor_name` varchar(30) NOT NULL DEFAULT '' COMMENT '主播昵称',
`start_time` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '开播时间',
`end_time` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '结束时间',
`live_status` tinyint(3) unsigned NOT NULL DEFAULT '102' COMMENT '直播状态(101: 直播中, 102: 未开始, 103: 已结束, 104: 禁播, 105: 暂停中, 106: 异常, 107: 已过期)',
`is_top` tinyint(3) unsigned NOT NULL DEFAULT '0' COMMENT '置顶状态(0未置顶 1已置顶)',
`is_delete` tinyint(3) unsigned NOT NULL DEFAULT '0' COMMENT '软删除(0未删除 1已删除)',
`wxapp_id` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '小程序id',
`create_time` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '创建时间',
`update_time` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '更新时间',
PRIMARY KEY (`id`),
KEY `room_id` (`room_id`)
) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=utf8 COMMENT='微信小程序直播间记录表';

View File

@ -0,0 +1,28 @@
CREATE TABLE `yoshop_wxapp_live_room` (
`room_id` int(11) unsigned NOT NULL COMMENT '直播间id',
`room_name` varchar(200) NOT NULL DEFAULT '' COMMENT '直播间名称',
`cover_img` varchar(255) DEFAULT '' COMMENT '分享卡片封面',
`share_img` varchar(255) DEFAULT '' COMMENT '直播间背景墙封面',
`anchor_name` varchar(30) NOT NULL DEFAULT '' COMMENT '主播昵称',
`start_time` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '开播时间',
`end_time` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '结束时间',
`live_status` tinyint(3) unsigned NOT NULL DEFAULT '102' COMMENT '直播状态(101: 直播中, 102: 未开始, 103: 已结束, 104: 禁播, 105: 暂停中, 106: 异常, 107: 已过期)',
`is_top` tinyint(3) unsigned NOT NULL DEFAULT '0' COMMENT '置顶状态(0未置顶 1已置顶)',
`is_delete` tinyint(3) unsigned NOT NULL DEFAULT '0' COMMENT '软删除(0未删除 1已删除)',
`wxapp_id` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '小程序id',
`create_time` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '创建时间',
`update_time` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '更新时间',
PRIMARY KEY (`room_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='微信小程序直播间记录表';
INSERT INTO `yoshop_store_access` (`access_id`, `name`, `url`, `parent_id`, `sort`, `create_time`, `update_time`) VALUES ('10462', '小程序直播', 'apps.live', '10074', '125', '1585120375', '1585120375');
INSERT INTO `yoshop_store_access` (`access_id`, `name`, `url`, `parent_id`, `sort`, `create_time`, `update_time`) VALUES ('10463', '直播间管理', 'apps.live.room/index', '10462', '100', '1585120404', '1585120404');
INSERT INTO `yoshop_store_access` (`access_id`, `name`, `url`, `parent_id`, `sort`, `create_time`, `update_time`) VALUES ('10464', '同步刷新', 'apps.live.room/refresh', '10463', '100', '1585120404', '1585120404');
INSERT INTO `yoshop_store_access` (`access_id`, `name`, `url`, `parent_id`, `sort`, `create_time`, `update_time`) VALUES ('10465', '设置置顶状态', 'apps.live.room/refresh', '10463', '100', '1585120404', '1585120404');

View File

@ -0,0 +1,9 @@
ALTER TABLE `yoshop_wxapp_live_room`
ADD COLUMN `id` int UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键id' FIRST ,
DROP PRIMARY KEY,
ADD PRIMARY KEY (`id`),
ADD INDEX `room_id` (`room_id`),
AUTO_INCREMENT=10001;

View File

@ -0,0 +1,7 @@
UPDATE `yoshop_store_access` SET `sort`='105' WHERE (`access_id`='10061');
UPDATE `yoshop_store_access` SET `sort`='110' WHERE (`access_id`='10069');
INSERT INTO `yoshop_store_access` VALUES ('11004', '订阅消息', 'wxapp.submsg/index', '10059', '105', '1589158947', '1589158947');

View File

@ -0,0 +1,2 @@
UPDATE `yoshop_store_access` SET `url`='apps.sharing.order.operate/refund' WHERE (`access_id`='10323');

View File

@ -0,0 +1,17 @@
ALTER TABLE `yoshop_coupon`
ADD COLUMN `apply_range_config` text NOT NULL COMMENT '适用范围配置(json格式)' AFTER `apply_range`;
ALTER TABLE `yoshop_user_coupon`
ADD COLUMN `apply_range_config` text NOT NULL COMMENT '适用范围配置(json格式)' AFTER `apply_range`;
ALTER TABLE `yoshop_coupon`
MODIFY COLUMN `apply_range` tinyint(3) UNSIGNED NOT NULL DEFAULT 10 COMMENT '适用范围(10全部商品 20指定商品 30排除商品)' AFTER `end_time`;
ALTER TABLE `yoshop_user_coupon`
MODIFY COLUMN `apply_range` tinyint(3) UNSIGNED NOT NULL DEFAULT 10 COMMENT '适用范围(10全部商品 20指定商品 30排除商品)' AFTER `end_time`;

View File

@ -1,4 +1,95 @@
 
### v1.1.46 更新日志 ###
优化:兼容新版微信小程序授权登录
优化:微信支付下单时记录日志
优化:后台修改会员等级时默认选中
优化:获取海报图出错时抛错
优化:小程序端资讯列表页支持指定分类
修复:订单结算时计算优惠券精度问题
修复:后台新增优惠券报错
修复:删除购物车后更新角标数量
修复:小程序端倒计时组件报错
--------------------------------
注:本次更新须重新发布小程序
### v1.1.45 更新日志 ###
新增:优惠券支持指定商品
新增:小程序端底部购物车数量(角标)
优化微信退款API记录日志
优化:整点秒杀页面倒计时结束刷新
修复:后台满额包邮地区总数错误
修复:后台分销商确认打款时报错
--------------------------------
注:本次更新须重新发布小程序
### v1.1.44 更新日志 ###
新增:小程序转发到朋友圈(灰度安卓用户)
优化:微信打款时验证冻结资金是否合法
优化mysql报错时记录Error SQL
修复:后台权限缺少文件列表和回收站
修复:地区表中部分地区不存在
修复:获取直播房间列表接口报错
修复:后台订单详情页报错
修复:小程序端富文本视频高度不生效
--------------------------------
注:本次更新须重新发布小程序
### v1.1.43 更新日志 ###
优化mysql5.7环境数据排序问题
优化:秒杀商品不允许付款减库存
优化小票打印机API记录日志
优化:调整拼团拼单失效时间
修复:后台订单导出未下载问题
修复后台添加角色cdn资源加载超时
修复:后台分销提现列表打款方式
修复:拼团订单手动退款权限问题
修复:验证会员等级权重是否存在
修复:超管后台判断商家用户名重复
--------------------------------
注:本次更新须重新发布小程序
### v1.1.42 更新日志 ###
新增:分享小程序直播间绑定分销关系
修复小程序端ID selectors报错问题
修复:后台直播间管理置顶报错
修复取消确认弹框后未关闭loading
修复:直播间列表为空时同步失败
修复:收货地址过长发送订阅消息失败
修复:后台审核拼团订单退货报错
修复:小程序端未配置订阅消息提交表单
修复:小程序端秒杀商品分享时无标题
--------------------------------
注:本次更新须重新发布小程序
### v1.1.41 更新日志 ###
新增:微信小程序订阅消息
修复多开小程序直播间同步ID问题
修复库存1下单后提示商品库存不足
修复拼团商品预览sku图片报错
优化:超管后台删除商家用户
--------------------------------
注:本次更新须重新发布小程序
### v1.1.40 更新日志 ###
新增:微信小程序直播功能
优化:商品评价过滤无效内容
--------------------------------
注:本次更新须重新发布小程序
### v1.1.39 更新日志 ### ### v1.1.39 更新日志 ###
优化:后台菜单超出显示滚动条 优化:后台菜单超出显示滚动条

View File

@ -56,7 +56,6 @@ class Store extends Controller
/** /**
* 添加小程序 * 添加小程序
* @return array|mixed * @return array|mixed
* @throws \think\exception\PDOException
*/ */
public function add() public function add()
{ {

View File

@ -53,7 +53,7 @@ class Wxapp extends WxappModel
$this->error = '确认密码不正确'; $this->error = '确认密码不正确';
return false; return false;
} }
if (StoreUser::checkExist($data['store_name'])) { if (StoreUser::checkExist($data['user_name'])) {
$this->error = '商家用户名已存在'; $this->error = '商家用户名已存在';
return false; return false;
} }
@ -90,7 +90,12 @@ class Wxapp extends WxappModel
*/ */
public function setDelete() public function setDelete()
{ {
return $this->transaction(function () {
// 删除商家用户信息
(new StoreUser)->setDelete($this['wxapp_id']);
// 设置当前商城为已删除
return $this->save(['is_delete' => 1]); return $this->save(['is_delete' => 1]);
});
} }
} }

View File

@ -130,527 +130,4 @@ class Access extends AccessModel
return $prefix; return $prefix;
} }
/**
* 新增默认权限
*/
public function insertDefault()
{
$defaultData = $this->defaultData();
$this->buildData($defaultData);
}
/**
* 生成并写入默认数据
* @param $defaultData
* @param int $parent_id
*/
private function buildData(&$defaultData, $parent_id = 0)
{
foreach ($defaultData as $key => $item) {
// 保存数据
$model = new static;
$model->save([
'name' => $item['name'],
'url' => $item['url'],
'parent_id' => $parent_id,
'sort' => 100,
]);
if (isset($item['subset']) && !empty($item['subset'])) {
$this->buildData($item['subset'], $model['access_id']);
}
}
}
/**
* 默认权限数据
* @return array
*/
private function defaultData()
{
return [
[
'name' => '首页',
'url' => 'index/index'
],
[
'name' => '管理员',
'url' => 'store',
'subset' => [
[
'name' => '管理员管理',
'url' => 'store.user',
'subset' => [
[
'name' => '管理员列表',
'url' => 'store.user/index'
],
[
'name' => '添加管理员',
'url' => 'store.user/add'
],
[
'name' => '编辑管理员',
'url' => 'store.user/edit'
],
[
'name' => '删除管理员',
'url' => 'store.user/delete'
],
]
],
[
'name' => '角色管理',
'url' => 'store.role',
'subset' => [
[
'name' => '角色列表',
'url' => 'store.role/index'
],
[
'name' => '添加角色',
'url' => 'store.role/add'
],
[
'name' => '编辑角色',
'url' => 'store.role/edit'
],
[
'name' => '删除角色',
'url' => 'store.role/delete'
],
]
],
[
'name' => '权限管理',
'url' => 'store.access',
'subset' => [
[
'name' => '权限列表',
'url' => 'store.access/index'
],
[
'name' => '添加权限',
'url' => 'store.access/add'
],
[
'name' => '编辑权限',
'url' => 'store.access/edit'
],
[
'name' => '删除权限',
'url' => 'store.access/delete'
],
]
],
]
],
[
'name' => '商品管理',
'url' => 'goods',
'subset' => [
[
'name' => '商品管理',
'url' => 'goods',
'subset' => [
[
'name' => '商品列表',
'url' => 'goods/index',
],
[
'name' => '添加商品',
'url' => 'goods/add',
],
[
'name' => '编辑商品',
'url' => 'goods/edit',
],
[
'name' => '复制商品',
'url' => 'goods/copy',
],
[
'name' => '删除商品',
'url' => 'goods/delete',
],
[
'name' => '商品上下架',
'url' => 'goods/state',
],
]
],
[
'name' => '商品分类',
'url' => 'goods.category',
'subset' => [
[
'name' => '分类列表',
'url' => 'goods.category/index',
],
[
'name' => '添加分类',
'url' => 'goods.category/add',
],
[
'name' => '编辑分类',
'url' => 'goods.category/edit',
],
[
'name' => '删除分类',
'url' => 'goods.category/delete',
],
],
],
[
'name' => '商品评价',
'url' => 'goods.comment',
'subset' => [
[
'name' => '评价列表',
'url' => 'goods.comment/index',
],
[
'name' => '评价详情',
'url' => 'goods.comment/detail',
],
[
'name' => '删除评价',
'url' => 'goods.comment/delete',
],
],
],
]
],
[
'name' => '订单管理',
'url' => 'order',
'subset' => [
[
'name' => '订单列表',
'url' => '',
'subset' => [
[
'name' => '待发货',
'url' => 'order/delivery_list'
],
[
'name' => '待收货',
'url' => 'order/receipt_list'
],
[
'name' => '待付款',
'url' => 'order/pay_list'
],
[
'name' => '已完成',
'url' => 'order/complete_list'
],
[
'name' => '已取消',
'url' => 'order/cancel_list'
],
[
'name' => '全部订单',
'url' => 'order/all_list',
],
]
],
[
'name' => '订单详情',
'url' => '',
'subset' => [
[
'name' => '详情信息',
'url' => 'order/detail',
],
[
'name' => '确认发货',
'url' => 'order/delivery',
],
[
'name' => '修改订单价格',
'url' => 'order/updateprice',
],
]
],
[
'name' => '订单导出',
'url' => 'order.operate/export',
],
[
'name' => '批量发货',
'url' => 'order.operate/batchdelivery',
],
]
],
[
'name' => '用户管理',
'url' => 'user',
'subset' => [
[
'name' => '用户列表',
'url' => 'user/index'
],
[
'name' => '删除用户',
'url' => 'user/delete'
],
]
],
[
'name' => '营销设置',
'url' => 'market',
'subset' => [
[
'name' => '优惠券',
'url' => 'coupon',
'subset' => [
[
'name' => '优惠券列表',
'url' => 'market.coupon/index',
],
[
'name' => '新增优惠券',
'url' => 'market.coupon/add',
],
[
'name' => '编辑优惠券',
'url' => 'market.coupon/edit',
],
[
'name' => '删除优惠券',
'url' => 'market.coupon/delete',
],
[
'name' => '领取记录',
'url' => 'market.coupon/receive',
]
]
]
]
],
[
'name' => '小程序',
'url' => 'wxapp',
'subset' => [
[
'name' => '小程序设置',
'url' => 'wxapp/setting',
],
[
'name' => '页面管理',
'url' => 'wxapp.page',
'subset' => [
[
'name' => '页面设计',
'url' => '',
'subset' => [
[
'name' => '页面列表',
'url' => 'wxapp.page/index',
],
[
'name' => '新增页面',
'url' => 'wxapp.page/add',
],
[
'name' => '编辑页面',
'url' => 'wxapp.page/edit',
],
[
'name' => '设为首页',
'url' => 'wxapp.page/sethome',
],
]
],
[
'name' => '分类页模板',
'url' => 'wxapp.page/category',
],
[
'name' => '页面链接',
'url' => 'wxapp.page/links',
],
]
],
[
'name' => '帮助中心',
'url' => 'wxapp.help',
'subset' => [
[
'name' => '帮助列表',
'url' => 'wxapp.help/index',
],
[
'name' => '新增帮助',
'url' => 'wxapp.help/add',
],
[
'name' => '编辑帮助',
'url' => 'wxapp.help/edit',
],
[
'name' => '删除帮助',
'url' => 'wxapp.help/delete',
],
]
],
]
],
[
'name' => '应用中心',
'url' => 'apps',
'subset' => [
[
'name' => '分销中心',
'url' => 'apps.dealer',
'subset' => [
[
'name' => '入驻申请',
'url' => 'apps.dealer.apply',
'subset' => [
[
'name' => '申请列表',
'url' => 'apps.dealer.apply/index'
],
[
'name' => '分销商审核',
'url' => 'apps.dealer.apply/submit'
]
]
],
[
'name' => '分销商用户',
'url' => 'apps.dealer.user',
'subset' => [
[
'name' => '分销商列表',
'url' => 'apps.dealer.user/index',
],
[
'name' => '删除分销商',
'url' => 'apps.dealer.user/delete'
],
[
'name' => '分销商二维码',
'url' => 'apps.dealer.user/qrcode'
]
]
],
[
'name' => '分销订单',
'url' => 'apps.dealer.order/index',
],
[
'name' => '提现申请',
'url' => 'apps.dealer.withdraw',
'subset' => [
[
'name' => '申请列表',
'url' => 'apps.dealer.withdraw/index',
],
[
'name' => '提现审核',
'url' => 'apps.dealer.withdraw/submit'
],
[
'name' => '确认打款',
'url' => 'apps.dealer.withdraw/money'
]
]
],
[
'name' => '分销设置',
'url' => 'apps.dealer.setting/index',
],
[
'name' => '分销海报',
'url' => 'apps.dealer.setting/qrcode',
],
]
],
]
],
[
'name' => '设置',
'url' => 'setting',
'subset' => [
[
'name' => '商城设置',
'url' => 'setting/store',
],
[
'name' => '交易设置',
'url' => 'setting/trade',
],
[
'name' => '配送设置',
'url' => 'setting.delivery',
'subset' => [
[
'name' => '运费模板列表',
'url' => 'setting.delivery/index'
],
[
'name' => '新增运费模板',
'url' => 'setting.delivery/add'
],
[
'name' => '编辑运费模板',
'url' => 'setting.delivery/edit'
],
[
'name' => '删除运费模板',
'url' => 'setting.delivery/delete'
],
]
],
[
'name' => '物流公司',
'url' => 'setting.express',
'subset' => [
[
'name' => '物流公司列表',
'url' => 'setting.express/index'
],
[
'name' => '新增物流公司',
'url' => 'setting.express/add'
],
[
'name' => '编辑物流公司',
'url' => 'setting.express/edit'
],
[
'name' => '删除物流公司',
'url' => 'setting.express/delete'
],
]
],
[
'name' => '短信通知',
'url' => 'setting/sms',
],
[
'name' => '模板消息',
'url' => 'setting/tplmsg',
],
[
'name' => '上传设置',
'url' => 'setting/storage',
],
[
'name' => '其他',
'url' => '',
'subset' => [
[
'name' => '清理缓存',
'url' => 'setting.cache/clear',
],
]
]
]
],
];
}
} }

View File

@ -2,6 +2,7 @@
namespace app\admin\model\store; namespace app\admin\model\store;
use app\common\exception\BaseException;
use app\common\model\store\User as StoreUserModel; use app\common\model\store\User as StoreUserModel;
/** /**
@ -13,30 +14,55 @@ class User extends StoreUserModel
{ {
/** /**
* 新增商家用户记录 * 新增商家用户记录
* @param $wxapp_id * @param int $wxappId
* @param $data * @param array $data
* @return bool|false|int * @return bool|false|int
*/ */
public function add($wxapp_id, $data) public function add($wxappId, $data)
{ {
return $this->save([ return $this->save([
'user_name' => $data['user_name'], 'user_name' => $data['user_name'],
'password' => yoshop_hash($data['password']), 'password' => yoshop_hash($data['password']),
'wxapp_id' => $wxapp_id, 'is_super' => 1,
'wxapp_id' => $wxappId,
]); ]);
} }
/** /**
* 商家用户登录 * 商家用户登录
* @param $wxapp_id * @param int $wxappId
* @throws \think\Exception * @throws \think\Exception
* @throws \think\exception\DbException * @throws \think\exception\DbException
*/ */
public function login($wxapp_id) public function login($wxappId)
{ {
// 验证用户名密码是否正确 // 获取获取商城超级管理员用户信息
$user = self::detail(['wxapp_id' => $wxapp_id], ['wxapp']); $user = $this->getSuperStoreUser($wxappId);
if (empty($user)) {
throw new BaseException(['msg' => '超级管理员用户信息不存在']);
}
$this->loginState($user); $this->loginState($user);
} }
/**
* 获取获取商城超级管理员用户信息
* @param $wxappId
* @return User|null
* @throws \think\exception\DbException
*/
private function getSuperStoreUser($wxappId)
{
return static::detail(['wxapp_id' => $wxappId, 'is_super' => 1], ['wxapp']);
}
/**
* 删除小程序下的商家用户
* @param $wxappId
* @return false|int
*/
public function setDelete($wxappId)
{
return $this->save(['is_delete' => 1], ['wxapp_id' => $wxappId]);
}
} }

View File

@ -79,7 +79,10 @@ class PaySuccess
private function onCommonEvent() private function onCommonEvent()
{ {
// 发送消息通知 // 发送消息通知
(new MessageService)->payment($this->order, $this->orderType); MessageService::send('order.payment', [
'order' => $this->order,
'order_type' => $this->orderType,
]);
// 小票打印 // 小票打印
(new PrinterService)->printTicket($this->order, OrderStatusEnum::ORDER_PAYMENT); (new PrinterService)->printTicket($this->order, OrderStatusEnum::ORDER_PAYMENT);
} }

View File

@ -66,7 +66,7 @@ class Cart extends Controller
return $this->renderError($this->model->getError() ?: '加入购物车失败'); return $this->renderError($this->model->getError() ?: '加入购物车失败');
} }
// 购物车商品总数量 // 购物车商品总数量
$totalNum = $this->model->getGoodsNum(); $totalNum = $this->model->getTotalNum();
return $this->renderSuccess(['cart_total_num' => $totalNum], '加入购物车成功'); return $this->renderSuccess(['cart_total_num' => $totalNum], '加入购物车成功');
} }

View File

@ -48,15 +48,11 @@ class Goods extends Controller
if ($goods === false) { if ($goods === false) {
return $this->renderError($model->getError() ?: '商品信息不存在'); return $this->renderError($model->getError() ?: '商品信息不存在');
} }
// 多规格商品sku信息, todo: 已废弃 v1.1.25
$specData = $goods['spec_type'] == 20 ? $model->getManySpecData($goods['spec_rel'], $goods['sku']) : null;
return $this->renderSuccess([ return $this->renderSuccess([
// 商品详情 // 商品详情
'detail' => $goods, 'detail' => $goods,
// 购物车商品总数量 // 购物车商品总数量
'cart_total_num' => $user ? (new CartModel($user))->getGoodsNum() : 0, 'cart_total_num' => $user ? (new CartModel($user))->getTotalNum() : 0,
// 多规格商品sku信息
'specData' => $specData,
]); ]);
} }

View File

@ -0,0 +1,26 @@
<?php
namespace app\api\controller\live;
use app\api\controller\Controller;
use app\api\model\wxapp\LiveRoom as LiveRoomModel;
/**
* 微信小程序直播列表
* Class Room
* @package app\api\controller\live
*/
class Room extends Controller
{
/**
* 获取直播间列表
* @return mixed
* @throws \think\exception\DbException
*/
public function lists()
{
$model = new LiveRoomModel;
$list = $model->getList();
return $this->renderSuccess(compact('list'));
}
}

View File

@ -13,13 +13,14 @@ use app\api\model\sharing\Setting as SettingModel;
class Setting extends Controller class Setting extends Controller
{ {
/** /**
* 获取所有设置 * 获取拼团设置
* @return array * @return array
*/ */
public function getAll() public function getAll()
{ {
$basic = SettingModel::getItem('basic'); // 获取拼团设置
return $this->renderSuccess(['setting' => compact('basic')]); $setting = SettingModel::getSetting();
return $this->renderSuccess(compact('setting'));
} }
} }

View File

@ -37,7 +37,7 @@ class Goods extends Controller
{ {
// 获取秒杀活动商品详情 // 获取秒杀活动商品详情
$service = new ActiveService; $service = new ActiveService;
$data = $service->getyActiveGoodsDetail($active_time_id, $sharp_goods_id); $data = $service->getActiveGoodsDetail($active_time_id, $sharp_goods_id);
if ($data === false) { if ($data === false) {
return $this->renderError($service->getError()); return $this->renderError($service->getError());
} }
@ -56,7 +56,7 @@ class Goods extends Controller
{ {
// 获取秒杀活动商品详情 // 获取秒杀活动商品详情
$service = new ActiveService; $service = new ActiveService;
$data = $service->getyActiveGoodsDetail($active_time_id, $sharp_goods_id); $data = $service->getActiveGoodsDetail($active_time_id, $sharp_goods_id);
if ($data === false) { if ($data === false) {
return $this->renderError($service->getError()); return $this->renderError($service->getError());
} }

View File

@ -41,8 +41,8 @@ class Comment extends Controller
} }
// 提交商品评价 // 提交商品评价
if ($this->request->isPost()) { if ($this->request->isPost()) {
$formData = $this->request->post('formData', '', null); $post = $this->request->post('formData');
if ($model->addForOrder($order, $goodsList, $formData)) { if ($model->addForOrder($order, $goodsList, $post)) {
return $this->renderSuccess([], '评价发表成功'); return $this->renderSuccess([], '评价发表成功');
} }
return $this->renderError($model->getError() ?: '评价发表失败'); return $this->renderError($model->getError() ?: '评价发表失败');

View File

@ -32,7 +32,6 @@ class Apply extends Controller
* @param string $mobile * @param string $mobile
* @return array * @return array
* @throws \think\exception\DbException * @throws \think\exception\DbException
* @throws \think\exception\PDOException
*/ */
public function submit($name = '', $mobile = '') public function submit($name = '', $mobile = '')
{ {

View File

@ -47,7 +47,7 @@ class Withdraw extends Controller
$formData = json_decode(htmlspecialchars_decode($data), true); $formData = json_decode(htmlspecialchars_decode($data), true);
$model = new WithdrawModel; $model = new WithdrawModel;
if ($model->submit($this->dealer, $formData)) { if ($model->submit($this->dealer, $formData)) {
return $this->renderSuccess([], '申请提现成功'); return $this->renderSuccess([], '提现申请已提交成功,请等待审核');
} }
return $this->renderError($model->getError() ?: '提交失败'); return $this->renderError($model->getError() ?: '提交失败');
} }

View File

@ -3,10 +3,9 @@
namespace app\api\controller\wxapp; namespace app\api\controller\wxapp;
use app\api\controller\Controller; use app\api\controller\Controller;
use app\api\model\wxapp\Formid as FormidModel;
/** /**
* form_id 管理 * form_id 管理 (已废弃)
* Class Formid * Class Formid
* @package app\api\controller\wxapp * @package app\api\controller\wxapp
*/ */
@ -17,20 +16,10 @@ class Formid extends Controller
* (因微信模板消息已下线所以formId取消不再收集) * (因微信模板消息已下线所以formId取消不再收集)
* @param $formId * @param $formId
* @return array * @return array
* @throws \app\common\exception\BaseException
* @throws \think\exception\DbException
*/ */
public function save($formId) public function save($formId)
{ {
return $this->renderSuccess(); return $this->renderSuccess();
// if (!$user = $this->getUser(false)) {
// return $this->renderSuccess();
// }
// if (FormidModel::add($user['user_id'], $formId)) {
// return $this->renderSuccess();
// }
// return $this->renderError();
} }
} }

View File

@ -0,0 +1,25 @@
<?php
namespace app\api\controller\wxapp;
use app\api\controller\Controller;
use app\api\model\Setting as SettingModel;
/**
* 微信小程序订阅消息
* Class Submsg
* @package app\api\controller\wxapp
*/
class Submsg extends Controller
{
/**
* 获取订阅消息配置
* @return array
*/
public function setting()
{
$setting = SettingModel::getSubmsg();
return $this->renderSuccess(compact('setting'));
}
}

View File

@ -4,7 +4,7 @@ namespace app\api\model;
use app\common\exception\BaseException; use app\common\exception\BaseException;
use app\common\model\Comment as CommentModel; use app\common\model\Comment as CommentModel;
use think\Db; use app\common\library\helper;
/** /**
* 商品评价模型 * 商品评价模型
@ -107,14 +107,14 @@ class Comment extends CommentModel
* 根据已完成订单商品 添加评价 * 根据已完成订单商品 添加评价
* @param Order $order * @param Order $order
* @param \think\Collection|OrderGoods $goodsList * @param \think\Collection|OrderGoods $goodsList
* @param $formJsonData * @param $post
* @return boolean * @return boolean
* @throws \Exception * @throws \Exception
*/ */
public function addForOrder($order, $goodsList, $formJsonData) public function addForOrder($order, $goodsList, $post)
{ {
// 生成 formData // 生成 formData
$formData = $this->formatFormData($formJsonData); $formData = $this->formatFormData($post);
// 生成评价数据 // 生成评价数据
$data = $this->createCommentData($order['user_id'], $order['order_id'], $goodsList, $formData); $data = $this->createCommentData($order['user_id'], $order['order_id'], $goodsList, $formData);
if (empty($data)) { if (empty($data)) {
@ -173,6 +173,7 @@ class Comment extends CommentModel
throw new BaseException(['msg' => '提交的数据不合法']); throw new BaseException(['msg' => '提交的数据不合法']);
} }
$item = $formData[$goods['order_goods_id']]; $item = $formData[$goods['order_goods_id']];
$item['content'] = trim($item['content']);
!empty($item['content']) && $data[$goods['order_goods_id']] = [ !empty($item['content']) && $data[$goods['order_goods_id']] = [
'score' => $item['score'], 'score' => $item['score'],
'content' => $item['content'], 'content' => $item['content'],
@ -191,12 +192,13 @@ class Comment extends CommentModel
/** /**
* 格式化 formData * 格式化 formData
* @param string $formJsonData * @param string $post
* @return array * @return array
*/ */
private function formatFormData($formJsonData) private function formatFormData($post)
{ {
return array_column(json_decode($formJsonData, true), null, 'order_goods_id'); $formJsonData = htmlspecialchars_decode($post);
return helper::arrayColumn2Key(helper::jsonDecode($formJsonData), 'order_goods_id');
} }
/** /**

View File

@ -20,4 +20,18 @@ class Setting extends SettingModel
return static::getItem('points')['points_name']; return static::getItem('points')['points_name'];
} }
/**
* 获取微信订阅消息设置
*/
public static function getSubmsg()
{
$data = [];
foreach (static::getItem('submsg') as $groupName => $group) {
foreach ($group as $itemName => $item) {
$data[$groupName][$itemName]['template_id'] = $item['template_id'];
}
}
return $data;
}
} }

View File

@ -3,11 +3,12 @@
namespace app\api\model; namespace app\api\model;
use think\Cache; use think\Cache;
use app\common\library\wechat\WxUser;
use app\common\exception\BaseException;
use app\common\model\User as UserModel;
use app\api\model\dealer\Referee as RefereeModel; use app\api\model\dealer\Referee as RefereeModel;
use app\api\model\dealer\Setting as DealerSettingModel; use app\api\model\dealer\Setting as DealerSettingModel;
use app\common\model\User as UserModel;
use app\common\library\helper;
use app\common\library\wechat\WxUser;
use app\common\exception\BaseException;
/** /**
* 用户模型类 * 用户模型类
@ -56,7 +57,7 @@ class User extends UserModel
$session = $this->wxlogin($post['code']); $session = $this->wxlogin($post['code']);
// 自动注册用户 // 自动注册用户
$refereeId = isset($post['referee_id']) ? $post['referee_id'] : null; $refereeId = isset($post['referee_id']) ? $post['referee_id'] : null;
$userInfo = json_decode(htmlspecialchars_decode($post['user_info']), true); $userInfo = helper::jsonDecode(htmlspecialchars_decode($post['user_info']));
$user_id = $this->register($session['openid'], $userInfo, $refereeId); $user_id = $this->register($session['openid'], $userInfo, $refereeId);
// 生成token (session3rd) // 生成token (session3rd)
$this->token = $this->token($session['openid']); $this->token = $this->token($session['openid']);

View File

@ -12,22 +12,29 @@ use app\common\model\UserCoupon as UserCouponModel;
*/ */
class UserCoupon extends UserCouponModel class UserCoupon extends UserCouponModel
{ {
/** /**
* 获取用户优惠券列表 * 获取用户优惠券列表
* @param $user_id * @param $userId
* @param bool $is_use 是否已使用 * @param bool $isUse 是否已使用
* @param bool $is_expire 是否已过期 * @param bool $isExpire 是否已过期
* @param float $amount 订单消费金额
* @return false|\PDOStatement|string|\think\Collection * @return false|\PDOStatement|string|\think\Collection
* @throws \think\db\exception\DataNotFoundException * @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException * @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException * @throws \think\exception\DbException
*/ */
public function getList($user_id, $is_use = false, $is_expire = false) public function getList($userId, $isUse = false, $isExpire = false, $amount = null)
{ {
return $this->where('user_id', '=', $user_id) // 构建查询对象
->where('is_use', '=', $is_use ? 1 : 0) $query = $this->where('user_id', '=', $userId)
->where('is_expire', '=', $is_expire ? 1 : 0) ->where('is_use', '=', $isUse)
->select(); ->where('is_expire', '=', $isExpire);
// 最低消费金额
if (!is_null($amount) && $amount > 0) {
$query->where('min_price', '<=', $amount);
}
return $query->select();
} }
/** /**
@ -103,6 +110,7 @@ class UserCoupon extends UserCouponModel
'start_time' => $start_time, 'start_time' => $start_time,
'end_time' => $end_time, 'end_time' => $end_time,
'apply_range' => $coupon['apply_range'], 'apply_range' => $coupon['apply_range'],
'apply_range_config' => $coupon['apply_range_config'],
'user_id' => $user['user_id'], 'user_id' => $user['user_id'],
'wxapp_id' => self::$wxapp_id 'wxapp_id' => self::$wxapp_id
]; ];
@ -144,22 +152,21 @@ class UserCoupon extends UserCouponModel
/** /**
* 订单结算优惠券列表 * 订单结算优惠券列表
* @param int $user_id 用户id * @param int $userId 用户id
* @param double $orderPayPrice 订单商品总金额 * @param double $orderPayPrice 订单商品总金额
* @return mixed * @return mixed
* @throws \think\db\exception\DataNotFoundException * @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException * @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException * @throws \think\exception\DbException
*/ */
public static function getUserCouponList($user_id, $orderPayPrice) public static function getUserCouponList($userId, $orderPayPrice)
{ {
// todo: 新增筛选条件: 最低消费金额
// 获取用户可用的优惠券列表 // 获取用户可用的优惠券列表
$list = (new self)->getList($user_id); $list = (new static)->getList($userId, false, false, $orderPayPrice);
$data = []; $data = [];
foreach ($list as $coupon) { foreach ($list as $coupon) {
// 最低消费金额 // 最低消费金额
if ($orderPayPrice < $coupon['min_price']) continue; // if ($orderPayPrice < $coupon['min_price']) continue;
// 有效期范围内 // 有效期范围内
if ($coupon['start_time']['value'] > time()) continue; if ($coupon['start_time']['value'] > time()) continue;
$key = $coupon['user_coupon_id']; $key = $coupon['user_coupon_id'];
@ -174,10 +181,11 @@ class UserCoupon extends UserCouponModel
'expire_type' => $coupon['expire_type'], 'expire_type' => $coupon['expire_type'],
'start_time' => $coupon['start_time'], 'start_time' => $coupon['start_time'],
'end_time' => $coupon['end_time'], 'end_time' => $coupon['end_time'],
'apply_range' => $coupon['apply_range'],
'apply_range_config' => $coupon['apply_range_config']
]; ];
// 计算打折金额 // 计算打折金额
if ($coupon['coupon_type']['value'] == 20) { if ($coupon['coupon_type']['value'] == 20) {
// $reduce_price = $orderPayPrice * ($coupon['discount'] / 10);
$reducePrice = helper::bcmul($orderPayPrice, $coupon['discount'] / 10); $reducePrice = helper::bcmul($orderPayPrice, $coupon['discount'] / 10);
$data[$key]['reduced_price'] = bcsub($orderPayPrice, $reducePrice, 2); $data[$key]['reduced_price'] = bcsub($orderPayPrice, $reducePrice, 2);
} else } else
@ -187,4 +195,32 @@ class UserCoupon extends UserCouponModel
return array_sort($data, 'reduced_price', true); return array_sort($data, 'reduced_price', true);
} }
/**
* 判断当前优惠券是否满足订单使用条件
* @param $couponList
* @param $orderGoodsIds
* @return mixed
*/
public static function couponListApplyRange($couponList, $orderGoodsIds)
{
// 名词解释(is_apply):允许用于抵扣当前订单
foreach ($couponList as &$item) {
if ($item['apply_range'] == 10) {
// 1. 全部商品
$item['is_apply'] = true;
} elseif ($item['apply_range'] == 20) {
// 2. 指定商品, 判断订单商品是否存在可用
$applyGoodsIds = array_intersect($item['apply_range_config']['applyGoodsIds'], $orderGoodsIds);
$item['is_apply'] = !empty($applyGoodsIds);
} elseif ($item['apply_range'] == 30) {
// 2. 排除商品, 判断订单商品是否全部都在排除行列
$excludedGoodsIds = array_intersect($item['apply_range_config']['excludedGoodsIds'], $orderGoodsIds);
$item['is_apply'] = count($excludedGoodsIds) != count($orderGoodsIds);
}
!$item['is_apply'] && $item['not_apply_info'] = '该优惠券不支持当前商品';
}
return $couponList;
}
} }

View File

@ -100,7 +100,7 @@ class Active extends ActiveModel
], $param); ], $param);
// 排序规则 // 排序规则
if ($params['sortType'] === 'all') { if ($params['sortType'] === 'all') {
$this->order(['sort' => 'asc']); $this->order(['sort' => 'asc', $this->getPk() => 'desc']);
} elseif ($params['sortType'] === 'sales') { } elseif ($params['sortType'] === 'sales') {
$this->order(['active_sales' => 'desc']); $this->order(['active_sales' => 'desc']);
} elseif ($params['sortType'] === 'price') { } elseif ($params['sortType'] === 'price') {
@ -112,7 +112,7 @@ class Active extends ActiveModel
->where('end_time', '>=', time()) ->where('end_time', '>=', time())
->where('status', '=', 1) ->where('status', '=', 1)
->where('is_delete', '=', 0) ->where('is_delete', '=', 0)
->order(['sort' => 'asc']) ->order(['sort' => 'asc', $this->getPk() => 'desc'])
->paginate($params['listRows'], false, [ ->paginate($params['listRows'], false, [
'query' => \request()->request() 'query' => \request()->request()
]); ]);

View File

@ -2,14 +2,15 @@
namespace app\api\model\sharing; namespace app\api\model\sharing;
use app\common\model\sharing\Setting as SettingModel; use app\api\model\Setting as SettingModel;
use app\common\model\sharing\Setting as SharingSettingModel;
/** /**
* 拼团设置模型 * 拼团设置模型
* Class Setting * Class Setting
* @package app\api\model\sharing * @package app\api\model\sharing
*/ */
class Setting extends SettingModel class Setting extends SharingSettingModel
{ {
/** /**
* 隐藏字段 * 隐藏字段
@ -19,4 +20,19 @@ class Setting extends SettingModel
'update_time', 'update_time',
]; ];
public static function getSetting()
{
// 订阅消息
$submsgList = [];
foreach (SettingModel::getItem('submsg')['sharing'] as $key => $item) {
$submsgList[$key] = $item['template_id'];
}
return [
// 基础设置
'basic' => static::getItem('basic'),
// 订阅消息
'order_submsg' => $submsgList,
];
}
} }

View File

@ -0,0 +1,77 @@
<?php
namespace app\api\model\wxapp;
use app\common\model\wxapp\LiveRoom as LiveRoomModel;
use app\common\enum\live\LiveStatus as LiveStatusEnum;
/**
* 微信小程序直播间模型
* Class LiveRoom
* @package app\api\model\wxapp
*/
class LiveRoom extends LiveRoomModel
{
/**
* 隐藏的字段
* @var array
*/
protected $hidden = [
'is_delete',
'wxapp_id',
'create_time',
'update_time',
];
/**
* 获取直播间列表
* @return \think\Paginator
* @throws \think\exception\DbException
*/
public function getList()
{
// 直播间列表
// mix: 可设置live_status条件来显示不同直播状态的房间
$this->where('live_status', '<>', 107); // 已过期的不显示
$list = $this->where('is_delete', '=', 0)
->order([
'is_top' => 'desc',
'live_status' => 'asc',
'create_time' => 'desc'
])->paginate(15, false, [
'query' => \request()->request()
]);
// 整理api数据
foreach ($list as &$item) {
$item['live_status_text_1'] = LiveStatusEnum::data()[$item['live_status']]['name'];
$item['live_status_text_2'] = $item['live_status_text_1'];
$item['live_status'] == 101 && $item['live_status_text_1'] = '正在直播中';
$item['live_status'] == 102 && $item['live_status_text_1'] = $this->semanticStartTime($item->getData('start_time')) . ' 开播';
}
return $list;
}
/**
* 语义化开播时间
* @param $startTime
* @return string
*/
private function semanticStartTime($startTime)
{
// 转换为 YYYYMMDD 格式
$startDate = date('Ymd', $startTime);
// 获取今天的 YYYY-MM-DD 格式
$todyDate = date('Ymd');
// 获取明天的 YYYY-MM-DD 格式
$tomorrowDate = date('Ymd', strtotime('+1 day'));
// 使用IF当作字符串判断是否相等
if ($startDate == $todyDate) {
return date('今天H:i', $startTime);
} elseif ($startDate == $tomorrowDate) {
return date('明天H:i', $startTime);
}
// 常规日期格式
return date('m/d H:i', $startTime);
}
}

View File

@ -59,7 +59,7 @@ class GoodsDeduct
private function setGoodsListCouponMoney(&$goodsList) private function setGoodsListCouponMoney(&$goodsList)
{ {
foreach ($goodsList as &$goods) { foreach ($goodsList as &$goods) {
$goods['coupon_money'] = bcmul($this->actualReducedMoney, $goods['weight']); $goods['coupon_money'] = helper::bcmul($this->actualReducedMoney, $goods['weight'], 0);
} }
return true; return true;
} }

View File

@ -300,8 +300,6 @@ class Checkout
{ {
// 系统支持的配送方式 (后台设置) // 系统支持的配送方式 (后台设置)
$deliveryType = SettingModel::getItem('store')['delivery_type']; $deliveryType = SettingModel::getItem('store')['delivery_type'];
// 积分设置
$pointsSetting = SettingModel::getItem('points');
return [ return [
// 配送类型 // 配送类型
'delivery' => $this->param['delivery'] > 0 ? $this->param['delivery'] : $deliveryType[0], 'delivery' => $this->param['delivery'] > 0 ? $this->param['delivery'] : $deliveryType[0],
@ -326,15 +324,32 @@ class Checkout
// 支付方式 // 支付方式
'pay_type' => $this->param['pay_type'], 'pay_type' => $this->param['pay_type'],
// 系统设置 // 系统设置
'setting' => [ 'setting' => $this->getSetting(),
// 记忆的自提联系方式
'last_extract' => UserService::getLastExtract($this->user['user_id']),
];
}
/**
* 获取订单页面中使用到的系统设置
* @return array
*/
private function getSetting()
{
// 系统支持的配送方式 (后台设置)
$deliveryType = SettingModel::getItem('store')['delivery_type'];
// 积分设置
$pointsSetting = SettingModel::getItem('points');
// 订阅消息
$orderSubMsgList = [];
foreach (SettingModel::getItem('submsg')['order'] as $item) {
!empty($item['template_id']) && $orderSubMsgList[] = $item['template_id'];
}
return [
'delivery' => $deliveryType, // 支持的配送方式 'delivery' => $deliveryType, // 支持的配送方式
'points_name' => $pointsSetting['points_name'], // 积分名称 'points_name' => $pointsSetting['points_name'], // 积分名称
'points_describe' => $pointsSetting['describe'], // 积分说明 'points_describe' => $pointsSetting['describe'], // 积分说明
], 'order_submsg' => $orderSubMsgList, // 订阅消息
// 记忆的自提联系方式
'last_extract' => UserService::getLastExtract($this->user['user_id']),
// todo: delete - 兼容处理
'deliverySetting' => $deliveryType,
]; ];
} }
@ -352,7 +367,13 @@ class Checkout
if (!$this->checkoutRule['is_coupon']) { if (!$this->checkoutRule['is_coupon']) {
return []; return [];
} }
return UserCouponModel::getUserCouponList($this->user['user_id'], $orderTotalPrice); // 整理当前订单所有商品ID集
$orderGoodsIds = helper::getArrayColumn($this->goodsList, 'goods_id');
// 当前用户可用的优惠券列表
$couponList = UserCouponModel::getUserCouponList($this->user['user_id'], $orderTotalPrice);
// 判断当前优惠券是否满足订单使用条件 ( 优惠券适用范围 )
$couponList = UserCouponModel::couponListApplyRange($couponList, $orderGoodsIds);
return $couponList;
} }
/** /**
@ -514,33 +535,60 @@ class Checkout
helper::setDataAttribute($this->goodsList, [ helper::setDataAttribute($this->goodsList, [
'coupon_money' => 0, // 优惠券抵扣金额 'coupon_money' => 0, // 优惠券抵扣金额
], true); ], true);
// 是否开启优惠券折扣 // 验证选择的优惠券ID是否合法
if (!$this->checkoutRule['is_coupon']) { if (!$this->verifyOrderCouponId($couponId, $couponList)) {
return false; return false;
} }
// 如果没有可用的优惠券,直接返回
if ($couponId <= 0 || empty($couponList)) {
return true;
}
// 获取优惠券信息 // 获取优惠券信息
$couponInfo = helper::getArrayItemByColumn($couponList, 'user_coupon_id', $couponId); $couponInfo = $this->getCouponInfo($couponId, $couponList);
if ($couponInfo == false) {
throw new BaseException(['msg' => '未找到优惠券信息']);
}
// 计算订单商品优惠券抵扣金额 // 计算订单商品优惠券抵扣金额
$goodsListTemp = helper::getArrayColumns($this->goodsList, ['total_price']); $goodsListTemp = helper::getArrayColumns($this->goodsList, ['total_price']);
$CouponMoney = new GoodsDeductService; $CouponMoney = new GoodsDeductService;
$completed = $CouponMoney->setGoodsCouponMoney($goodsListTemp, $couponInfo['reduced_price']); $completed = $CouponMoney->setGoodsCouponMoney($goodsListTemp, $couponInfo['reduced_price']);
// 分配订单商品优惠券抵扣金额 // 分配订单商品优惠券抵扣金额
foreach ($this->goodsList as $key => &$goods) { foreach ($this->goodsList as $key => &$goods) {
$goods['coupon_money'] = $completed[$key]['coupon_money'] / 100; $goods['coupon_money'] = helper::bcdiv($completed[$key]['coupon_money'], 100);
} }
// 记录订单优惠券信息 // 记录订单优惠券信息
$this->orderData['coupon_id'] = $couponId; $this->orderData['coupon_id'] = $couponId;
$this->orderData['coupon_money'] = helper::number2($CouponMoney->getActualReducedMoney() / 100); $this->orderData['coupon_money'] = helper::bcdiv($CouponMoney->getActualReducedMoney(), 100);
return true; return true;
} }
/**
* 验证用户选择的优惠券ID是否合法
* @param $couponId
* @param $couponList
* @return bool
* @throws BaseException
*/
private function verifyOrderCouponId($couponId, $couponList)
{
// 是否开启优惠券折扣
if (!$this->checkoutRule['is_coupon']) {
return false;
}
// 如果没有可用的优惠券,直接返回
if ($couponId <= 0 || empty($couponList)) {
return false;
}
// 判断优惠券是否存在
$couponInfo = $this->getCouponInfo($couponId, $couponList);
if (!$couponInfo) {
throw new BaseException(['msg' => '未找到优惠券信息']);
}
// 判断优惠券适用范围是否合法
if (!$couponInfo['is_apply']) {
throw new BaseException(['msg' => $couponInfo['not_apply_info']]);
}
return true;
}
private function getCouponInfo($couponId, $couponList)
{
return helper::getArrayItemByColumn($couponList, 'user_coupon_id', $couponId);
}
/** /**
* 订单配送-快递配送 * 订单配送-快递配送
* @return bool * @return bool
@ -618,7 +666,7 @@ class Checkout
// 更新商品库存 (针对下单减库存的商品) // 更新商品库存 (针对下单减库存的商品)
$this->updateGoodsStockNum($order); $this->updateGoodsStockNum($order);
// 设置优惠券使用状态 // 设置优惠券使用状态
UserCouponModel::setIsUse($this->param['coupon_id']); $order['coupon_id'] > 0 && UserCouponModel::setIsUse($order['coupon_id']);
// 积分抵扣情况下扣除用户积分 // 积分抵扣情况下扣除用户积分
if ($order['is_allow_points'] && $order['is_use_points'] && $order['points_num'] > 0) { if ($order['is_allow_points'] && $order['is_use_points'] && $order['points_num'] > 0) {
$describe = "用户消费:{$this->model['order_no']}"; $describe = "用户消费:{$this->model['order_no']}";

View File

@ -299,8 +299,6 @@ class Checkout
{ {
// 系统支持的配送方式 (后台设置) // 系统支持的配送方式 (后台设置)
$deliveryType = SettingModel::getItem('store')['delivery_type']; $deliveryType = SettingModel::getItem('store')['delivery_type'];
// 积分设置
$pointsSetting = SettingModel::getItem('points');
return [ return [
// 订单类型 // 订单类型
'order_type' => $this->param['order_type'], 'order_type' => $this->param['order_type'],
@ -327,11 +325,7 @@ class Checkout
// 支付方式 // 支付方式
'pay_type' => $this->param['pay_type'], 'pay_type' => $this->param['pay_type'],
// 系统设置 // 系统设置
'setting' => [ 'setting' => $this->getSetting(),
'delivery' => $deliveryType, // 支持的配送方式
'points_name' => $pointsSetting['points_name'], // 积分名称
'points_describe' => $pointsSetting['describe'], // 积分说明
],
// 记忆的自提联系方式 // 记忆的自提联系方式
'last_extract' => UserService::getLastExtract($this->user['user_id']), 'last_extract' => UserService::getLastExtract($this->user['user_id']),
// todo: 兼容处理 // todo: 兼容处理
@ -339,6 +333,29 @@ class Checkout
]; ];
} }
/**
* 获取订单页面中使用到的系统设置
* @return array
*/
private function getSetting()
{
// 系统支持的配送方式 (后台设置)
$deliveryType = SettingModel::getItem('store')['delivery_type'];
// 积分设置
$pointsSetting = SettingModel::getItem('points');
// 订阅消息
$orderSubMsgList = [];
foreach (SettingModel::getItem('submsg')['order'] as $item) {
!empty($item['template_id']) && $orderSubMsgList[] = $item['template_id'];
}
return [
'delivery' => $deliveryType, // 支持的配送方式
'points_name' => $pointsSetting['points_name'], // 积分名称
'points_describe' => $pointsSetting['describe'], // 积分说明
'order_submsg' => $orderSubMsgList, // 订阅消息
];
}
/** /**
* 当前用户可用的优惠券列表 * 当前用户可用的优惠券列表
* @param $orderTotalPrice * @param $orderTotalPrice

View File

@ -88,7 +88,7 @@ class Active extends Basics
* @return array|bool * @return array|bool
* @throws \think\exception\DbException * @throws \think\exception\DbException
*/ */
public function getyActiveGoodsDetail($activeTimeId, $sharpGoodsId) public function getActiveGoodsDetail($activeTimeId, $sharpGoodsId)
{ {
// 活动详情 // 活动详情
$active = $this->getGoodsActive($activeTimeId, $sharpGoodsId); $active = $this->getGoodsActive($activeTimeId, $sharpGoodsId);
@ -160,7 +160,7 @@ class Active extends Basics
$startTime = $model['active']['active_date'] + ($model->active_time->getData('active_time') * 60 * 60); $startTime = $model['active']['active_date'] + ($model->active_time->getData('active_time') * 60 * 60);
$endTime = $startTime + (1 * 60 * 60); $endTime = $startTime + (1 * 60 * 60);
$activeStatus = $this->getActivcGoodsStatus($startTime, $endTime); $activeStatus = $this->getActivcGoodsStatus($startTime, $endTime);
$data = [ return [
'active_id' => $model['active_id'], 'active_id' => $model['active_id'],
'active_time_id' => $model['active_time_id'], 'active_time_id' => $model['active_time_id'],
'active_time' => $model['active_time']['active_time'], 'active_time' => $model['active_time']['active_time'],
@ -171,7 +171,6 @@ class Active extends Basics
'count_down_time' => $this->getGoodsActiveCountDownTime($activeStatus, $startTime, $endTime), 'count_down_time' => $this->getGoodsActiveCountDownTime($activeStatus, $startTime, $endTime),
'wxapp_id' => $model['wxapp_id'], 'wxapp_id' => $model['wxapp_id'],
]; ];
return $data;
} }
/** /**

View File

@ -51,6 +51,7 @@ function base_url()
$request = Request::instance(); $request = Request::instance();
$subDir = str_replace('\\', '/', dirname($request->server('PHP_SELF'))); $subDir = str_replace('\\', '/', dirname($request->server('PHP_SELF')));
$baseUrl = $request->scheme() . '://' . $request->host() . $subDir . ($subDir === '/' ? '' : '/'); $baseUrl = $request->scheme() . '://' . $request->host() . $subDir . ($subDir === '/' ? '' : '/');
// $baseUrl = 'https://' . $request->host() . $subDir . ($subDir === '/' ? '' : '/');
} }
return $baseUrl; return $baseUrl;
} }
@ -221,10 +222,10 @@ function export_excel($fileName, $tileArray = [], $dataArray = [])
{ {
ini_set('memory_limit', '512M'); ini_set('memory_limit', '512M');
ini_set('max_execution_time', 0); ini_set('max_execution_time', 0);
ob_end_clean(); // ob_end_clean();
ob_start(); ob_start();
header("Content-Type: text/csv"); header("Content-Type: text/csv");
header("Content-Disposition:filename=" . $fileName); header("Content-Disposition:attachment;filename=" . $fileName);
$fp = fopen('php://output', 'w'); $fp = fopen('php://output', 'w');
fwrite($fp, chr(0xEF) . chr(0xBB) . chr(0xBF));// 转码 防止乱码(比如微信昵称) fwrite($fp, chr(0xEF) . chr(0xBB) . chr(0xBF));// 转码 防止乱码(比如微信昵称)
fputcsv($fp, $tileArray); fputcsv($fp, $tileArray);
@ -266,7 +267,7 @@ function get_version()
{ {
static $version = null; static $version = null;
if ($version) { if ($version) {
return $version; return $version['version'];
} }
$file = dirname(ROOT_PATH) . '/version.json'; $file = dirname(ROOT_PATH) . '/version.json';
if (!file_exists($file)) { if (!file_exists($file)) {
@ -346,3 +347,17 @@ function filter_emoji($text)
// 如需支持emoji表情, 需将mysql的编码改为utf8mb4 // 如需支持emoji表情, 需将mysql的编码改为utf8mb4
return preg_replace('/[\xf0-\xf7].{3}/', '', $text); return preg_replace('/[\xf0-\xf7].{3}/', '', $text);
} }
/**
* 根据指定长度截取字符串
* @param $str
* @param int $length
* @return bool|string
*/
function str_substr($str, $length = 30)
{
if (strlen($str) > $length) {
$str = mb_substr($str, 0, $length, 'utf-8');
}
return $str;
}

View File

@ -18,8 +18,8 @@ class Setting extends EnumBasics
// 短信通知 // 短信通知
const SMS = 'sms'; const SMS = 'sms';
// 模板消息 // // 模板消息
const TPL_MSG = 'tplMsg'; // const TPL_MSG = 'tplMsg';
// 上传设置 // 上传设置
const STORAGE = 'storage'; const STORAGE = 'storage';
@ -36,6 +36,9 @@ class Setting extends EnumBasics
// 积分设置 // 积分设置
const POINTS = 'points'; const POINTS = 'points';
// 订阅消息设置
const SUBMSG = 'submsg';
/** /**
* 获取订单类型值 * 获取订单类型值
* @return array * @return array
@ -55,10 +58,10 @@ class Setting extends EnumBasics
'value' => self::SMS, 'value' => self::SMS,
'describe' => '短信通知', 'describe' => '短信通知',
], ],
self::TPL_MSG => [ // self::TPL_MSG => [
'value' => self::TPL_MSG, // 'value' => self::TPL_MSG,
'describe' => '模板消息', // 'describe' => '模板消息',
], // ],
self::STORAGE => [ self::STORAGE => [
'value' => self::STORAGE, 'value' => self::STORAGE,
'describe' => '上传设置', 'describe' => '上传设置',
@ -79,6 +82,10 @@ class Setting extends EnumBasics
'value' => self::POINTS, 'value' => self::POINTS,
'describe' => '积分设置', 'describe' => '积分设置',
], ],
self::SUBMSG => [
'value' => self::SUBMSG,
'describe' => '小程序订阅消息',
],
]; ];
} }

View File

@ -0,0 +1,45 @@
<?php
namespace app\common\enum\dealer;
use app\common\enum\EnumBasics;
/**
* 枚举类:分销商入驻审核状态
* Class ApplyStatus
* @package app\common\enum\dealer
*/
class ApplyStatus extends EnumBasics
{
// 待审核
const AUDIT_WAIT = 10;
// 审核通过
const AUDIT_PASS = 20;
// 驳回
const AUDIT_REJECT = 30;
/**
* 获取枚举类型值
* @return array
*/
public static function data()
{
return [
self::AUDIT_WAIT => [
'name' => '待审核',
'value' => self::AUDIT_WAIT,
],
self::AUDIT_PASS => [
'name' => '审核通过',
'value' => self::AUDIT_PASS,
],
self::AUDIT_REJECT => [
'name' => '驳回',
'value' => self::AUDIT_REJECT,
],
];
}
}

View File

@ -0,0 +1,52 @@
<?php
namespace app\common\enum\dealer\withdraw;
use app\common\enum\EnumBasics;
/**
* 枚举类:分销商提现审核状态
* Class ApplyStatus
* @package app\common\enum\dealer\withdraw
*/
class ApplyStatus extends EnumBasics
{
// 待审核
const AUDIT_WAIT = 10;
// 审核通过
const AUDIT_PASS = 20;
// 驳回
const AUDIT_REJECT = 30;
// 已打款
const AUDIT_PAID = 40;
/**
* 获取枚举类型值
* @return array
*/
public static function data()
{
return [
self::AUDIT_WAIT => [
'name' => '待审核',
'value' => self::AUDIT_WAIT,
],
self::AUDIT_PASS => [
'name' => '审核通过',
'value' => self::AUDIT_PASS,
],
self::AUDIT_REJECT => [
'name' => '驳回',
'value' => self::AUDIT_REJECT,
],
self::AUDIT_PAID => [
'name' => '已打款',
'value' => self::AUDIT_PAID,
],
];
}
}

View File

@ -0,0 +1,45 @@
<?php
namespace app\common\enum\dealer\withdraw;
use app\common\enum\EnumBasics;
/**
* 枚举类:分销商提现打款方式
* Class PayType
* @package app\common\enum\dealer\withdraw
*/
class PayType extends EnumBasics
{
// 微信
const WECHAT = 10;
// 支付宝
const ALIPAY = 20;
// 银行卡
const BANK_CARD = 30;
/**
* 获取枚举类型值
* @return array
*/
public static function data()
{
return [
self::WECHAT => [
'name' => '微信',
'value' => self::WECHAT,
],
self::ALIPAY => [
'name' => '支付宝',
'value' => self::ALIPAY,
],
self::BANK_CARD => [
'name' => '银行卡',
'value' => self::BANK_CARD,
]
];
}
}

View File

@ -0,0 +1,52 @@
<?php
namespace app\common\enum\live;
use app\common\enum\EnumBasics;
/**
* 微信小程序直播间状态枚举类
* Class Room
* @package app\common\enum\live
*/
class LiveStatus extends EnumBasics
{
/**
* 获取枚举数据
* @return array
*/
public static function data()
{
return [
101 => [
'name' => '直播中',
'value' => 101,
],
102 => [
'name' => '未开始',
'value' => 102,
],
103 => [
'name' => '已结束',
'value' => 103,
],
104 => [
'name' => '禁播',
'value' => 104,
],
105 => [
'name' => '暂停中',
'value' => 105,
],
106 => [
'name' => '异常',
'value' => 106,
],
107 => [
'name' => '已过期',
'value' => 107,
],
];
}
}

View File

@ -0,0 +1,51 @@
<?php
namespace app\common\enum\sharing;
use app\common\enum\EnumBasics;
/**
* 拼团拼单状态
* Class ActiveStatus
* @package app\common\enum\sharing
*/
class ActiveStatus extends EnumBasics
{
// 未拼单
const ACTIVE_STATE_NORMAL = 0;
// 拼单中
const ACTIVE_STATE_BEGIN = 10;
// 拼单成功
const ACTIVE_STATE_SUCCESS = 20;
// 拼单失败
const ACTIVE_STATE_FAIL = 30;
/**
* 获取枚举数据
* @return array
*/
public static function data()
{
return [
self::ACTIVE_STATE_NORMAL => [
'name' => '未拼单',
'value' => self::ACTIVE_STATE_NORMAL,
],
self::ACTIVE_STATE_BEGIN => [
'name' => '拼单中',
'value' => self::ACTIVE_STATE_BEGIN,
],
self::ACTIVE_STATE_SUCCESS => [
'name' => '拼单成功',
'value' => self::ACTIVE_STATE_SUCCESS,
],
self::ACTIVE_STATE_FAIL => [
'name' => '拼单失败',
'value' => self::ACTIVE_STATE_FAIL,
],
];
}
}

View File

@ -2,8 +2,9 @@
namespace app\common\exception; namespace app\common\exception;
use think\exception\Handle;
use think\Log; use think\Log;
use think\exception\Handle;
use think\exception\DbException;
use Exception; use Exception;
/** /**
@ -37,13 +38,38 @@ class ExceptionHandler extends Handle
return json(['msg' => $this->message, 'code' => $this->code]); return json(['msg' => $this->message, 'code' => $this->code]);
} }
/**
* Report or log an exception.
*
* @param \Exception $exception
* @return void
*/
public function report(Exception $exception)
{
// 不使用内置的方式记录异常日志
}
/** /**
* 将异常写入日志 * 将异常写入日志
* @param Exception $e * @param Exception $e
*/ */
private function recordErrorLog(Exception $e) private function recordErrorLog(Exception $e)
{ {
Log::record($e->getMessage(), 'error'); $data = [
Log::record($e->getTraceAsString(), 'error'); 'file' => $e->getFile(),
'line' => $e->getLine(),
'message' => $this->getMessage($e),
'code' => $this->getCode($e),
'TraceAsString' => $e->getTraceAsString()
];
// 如果是mysql报错, 则记录Error SQL
if ($e instanceof DbException) {
$data['TraceAsString'] = "[Error SQL]: " . $e->getData()['Database Status']['Error SQL'];
}
// 日志标题
$log = "[{$data['code']}]{$data['message']} [{$data['file']}:{$data['line']}]";
// 错误trace
$log .= "\r\n{$data['TraceAsString']}";
Log::record($log, 'error');
} }
} }

View File

@ -25,7 +25,7 @@ class helper
} }
/** /**
* 获取数组中指定的列 * 获取数组中指定的列 [支持多列]
* @param $source * @param $source
* @param $columns * @param $columns
* @return array * @return array
@ -83,6 +83,21 @@ class helper
return $sum / 100; return $sum / 100;
} }
/**
* 在二维数组中查找指定值
* @param array $array 二维数组
* @param string $searchIdx 查找的索引
* @param string $searchVal 查找的值
* @return bool
*/
public static function arraySearch($array, $searchIdx, $searchVal)
{
foreach ($array as $item) {
if ($item[$searchIdx] == $searchVal) return $item;
}
return false;
}
public static function setDataAttribute(&$source, $defaultData, $isArray = false) public static function setDataAttribute(&$source, $defaultData, $isArray = false)
{ {
if (!$isArray) $dataSource = [&$source]; else $dataSource = &$source; if (!$isArray) $dataSource = [&$source]; else $dataSource = &$source;

View File

@ -2,6 +2,7 @@
namespace app\common\library\printer\engine; namespace app\common\library\printer\engine;
use app\common\library\helper;
use app\common\library\printer\party\FeieHttpClient; use app\common\library\printer\party\FeieHttpClient;
/** /**
@ -36,11 +37,15 @@ class Feie extends Basics
return false; return false;
} }
// 处理返回结果 // 处理返回结果
$result = json_decode($client->getContent()); $result = helper::jsonDecode($client->getContent());
log_write($result); // 记录日志
log_write([
'describe' => 'Feie PrintTicket',
'result' => $result
]);
// 返回状态 // 返回状态
if ($result->ret != 0) { if ($result['ret'] != 0) {
$this->error = $result->msg; $this->error = $result['msg'];
return false; return false;
} }
return true; return true;

View File

@ -2,7 +2,13 @@
namespace app\common\library\printer\engine; namespace app\common\library\printer\engine;
use app\common\library\helper;
/**
* 365云打印引擎
* Class PrintCenter
* @package app\common\library\printer\engine
*/
class PrintCenter extends Basics class PrintCenter extends Basics
{ {
/** @const API地址 */ /** @const API地址 */
@ -31,11 +37,15 @@ class PrintCenter extends Basics
// API请求开始打印 // API请求开始打印
$result = file_get_contents(self::API, false, $context); $result = file_get_contents(self::API, false, $context);
// 处理返回结果 // 处理返回结果
$result = json_decode($result); $result = helper::jsonDecode($result);
log_write($result); // 记录日志
log_write([
'describe' => 'PrintCenter(365) PrintTicket',
'result' => $result
]);
// 返回状态 // 返回状态
if ($result->responseCode != 0) { if ($result['responseCode'] != 0) {
$this->error = $result->msg; $this->error = $result['msg'];
return false; return false;
} }
return true; return true;

View File

@ -3,6 +3,7 @@
namespace app\common\library\wechat; namespace app\common\library\wechat;
use think\Cache; use think\Cache;
use app\common\library\helper;
use app\common\exception\BaseException; use app\common\exception\BaseException;
/** /**
@ -56,8 +57,8 @@ class WxBase
// 请求API获取 access_token // 请求API获取 access_token
$url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={$this->appId}&secret={$this->appSecret}"; $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={$this->appId}&secret={$this->appSecret}";
$result = $this->get($url); $result = $this->get($url);
$data = $this->jsonDecode($result); $response = $this->jsonDecode($result);
if (array_key_exists('errcode', $data)) { if (array_key_exists('errcode', $response)) {
throw new BaseException(['msg' => "access_token获取失败错误信息{$result}"]); throw new BaseException(['msg' => "access_token获取失败错误信息{$result}"]);
} }
// 记录日志 // 记录日志
@ -68,7 +69,7 @@ class WxBase
'result' => $result 'result' => $result
]); ]);
// 写入缓存 // 写入缓存
Cache::set($cacheKey, $data['access_token'], 6000); // 7000 Cache::set($cacheKey, $response['access_token'], 6000); // 7000
} }
return Cache::get($cacheKey); return Cache::get($cacheKey);
} }
@ -123,6 +124,29 @@ class WxBase
return $result; return $result;
} }
/**
* 模拟POST请求 [第二种方式, 用于兼容微信api]
* @param $url
* @param array $data
* @return mixed
*/
protected function post2($url, $data = [])
{
$header = [
'Content-Type: application/x-www-form-urlencoded'
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);//这个是重点。
$result = curl_exec($ch);
curl_close($ch);
return $result;
}
/** /**
* 数组转json * 数组转json
* @param $data * @param $data
@ -130,7 +154,7 @@ class WxBase
*/ */
protected function jsonEncode($data) protected function jsonEncode($data)
{ {
return json_encode($data, JSON_UNESCAPED_UNICODE); return helper::jsonEncode($data);
} }
/** /**
@ -140,7 +164,7 @@ class WxBase
*/ */
protected function jsonDecode($json) protected function jsonDecode($json)
{ {
return json_decode($json, true); return helper::jsonDecode($json);
} }
/** /**

View File

@ -67,6 +67,8 @@ class WxPay extends WxBase
]; ];
// 生成签名 // 生成签名
$params['sign'] = $this->makeSign($params); $params['sign'] = $this->makeSign($params);
// 记录日志
$this->doLogs(['name' => '微信支付统一下单API', 'params' => $params]);
// 请求API // 请求API
$url = 'https://api.mch.weixin.qq.com/pay/unifiedorder'; $url = 'https://api.mch.weixin.qq.com/pay/unifiedorder';
$result = $this->post($url, $this->toXml($params)); $result = $this->post($url, $this->toXml($params));
@ -191,6 +193,12 @@ class WxPay extends WxBase
} }
// 格式化返回结果 // 格式化返回结果
$prepay = $this->fromXml($result); $prepay = $this->fromXml($result);
// 记录日志
log_write(['describe' => '微信退款API', [
'params' => $params,
'result' => $result,
'prepay' => $prepay
]]);
// 请求失败 // 请求失败
if ($prepay['return_code'] === 'FAIL') { if ($prepay['return_code'] === 'FAIL') {
throw new BaseException(['msg' => 'return_msg: ' . $prepay['return_msg']]); throw new BaseException(['msg' => 'return_msg: ' . $prepay['return_msg']]);

View File

@ -0,0 +1,110 @@
<?php
namespace app\common\library\wechat;
/**
* 小程序订阅消息
* Class WxSubMsg
* @package app\common\library\wechat
*/
class WxSubMsg extends WxBase
{
/**
* 发送订阅消息
* @param $param
* @return bool
* @throws \app\common\exception\BaseException
*/
public function sendTemplateMessage($param)
{
// 微信接口url
$accessToken = $this->getAccessToken();
$url = "https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token={$accessToken}";
// 构建请求
$params = [
'touser' => $param['touser'],
'template_id' => $param['template_id'],
'page' => $param['page'],
'data' => $param['data'],
];
$result = $this->post($url, $this->jsonEncode($params));
// 记录日志
$describe = '发送订阅消息';
$this->doLogs(compact('describe', 'url', 'params', 'result'));
// 返回结果
$response = $this->jsonDecode($result);
if (!isset($response['errcode'])) {
$this->error = 'not found errcode';
return false;
}
if ($response['errcode'] != 0) {
$this->error = $response['errmsg'];
return false;
}
return true;
}
/**
* 获取当前帐号下的模板列表
* @throws \app\common\exception\BaseException
*/
public function getTemplateList()
{
// 微信接口url
$accessToken = $this->getAccessToken();
$url = "https://api.weixin.qq.com/wxaapi/newtmpl/gettemplate?access_token={$accessToken}";
// 执行post请求
$result = $this->get($url);
// 记录日志
$this->doLogs(['describe' => '获取当前帐号下的订阅消息模板列表', 'url' => $url, 'result' => $result]);
// 处理返回结果
$response = $this->jsonDecode($result);
if (!isset($response['errcode'])) {
$this->error = 'not found errcode';
return false;
}
if ($response['errcode'] != 0) {
$this->error = $response['errmsg'];
return false;
}
return $response;
}
/**
* 添加订阅消息模板
* [addTemplates 组合模板并添加至帐号下的个人模板库](订阅消息)
* @param int $tid 模板标题id
* @param array $kidList 模板关键词列表
* @param string $sceneDesc 服务场景描述
* @return bool
* @throws \app\common\exception\BaseException
*/
public function addTemplate($tid, $kidList, $sceneDesc)
{
// 微信接口url
$accessToken = $this->getAccessToken();
$url = "https://api.weixin.qq.com/wxaapi/newtmpl/addtemplate?access_token={$accessToken}";
// 构建请求
$params = [
'tid' => $tid,
'kidList' => $kidList,
'sceneDesc' => $sceneDesc,
];
// 执行post请求
$result = $this->post2($url, $params);
// 记录日志
$this->doLogs(['describe' => '添加订阅消息模板', 'url' => $url, 'params' => $params, 'result' => $result]);
// 处理返回结果
$response = $this->jsonDecode($result);
if (!isset($response['errcode'])) {
$this->error = 'not found errcode';
return false;
}
if ($response['errcode'] != 0) {
$this->error = $response['errmsg'];
return false;
}
return $response;
}
}

View File

@ -3,7 +3,7 @@
namespace app\common\library\wechat; namespace app\common\library\wechat;
/** /**
* 微信模板消息 * 微信模板消息 (废弃)
* Class WxTplMsg * Class WxTplMsg
* @package app\common\library\wechat * @package app\common\library\wechat
*/ */

View File

@ -0,0 +1,44 @@
<?php
namespace app\common\library\wechat\live;
use app\common\library\wechat\WxBase;
/**
* 微信小程序直播接口
* Class Room
* @package app\common\library\wechat\live
*/
class Room extends WxBase
{
/**
* 微信小程序直播-获取直播房间列表接口
* api文档: https://developers.weixin.qq.com/miniprogram/dev/framework/liveplayer/live-player-plugin.html
* @throws \app\common\exception\BaseException
*/
public function getLiveRoomList()
{
// 微信接口url
$accessToken = $this->getAccessToken();
$apiUrl = "https://api.weixin.qq.com/wxa/business/getliveinfo?access_token={$accessToken}";
// 请求参数
$params = $this->jsonEncode(['start' => 0, 'limit' => 100]);
// 执行请求
$result = $this->post($apiUrl, $params);
// 记录日志
$this->doLogs(['describe' => '微信小程序直播-获取直播房间列表接口', 'url' => $apiUrl, 'params' => $params, 'result' => $result]);
// 返回结果
$response = $this->jsonDecode($result);
if (!isset($response['errcode'])) {
$this->error = 'not found errcode';
return false;
}
// 容错: empty room list
if ($response['errcode'] > 1 && $response['errcode'] != 9410000) {
$this->error = $response['errmsg'];
return false;
}
return $response;
}
}

View File

@ -64,7 +64,7 @@ class BaseModel extends Model
protected static function setStoreWxappId() protected static function setStoreWxappId()
{ {
$session = Session::get('yoshop_store'); $session = Session::get('yoshop_store');
self::$wxapp_id = $session['wxapp']['wxapp_id']; !empty($session) && self::$wxapp_id = $session['wxapp']['wxapp_id'];
} }
/** /**

View File

@ -2,6 +2,7 @@
namespace app\common\model; namespace app\common\model;
use app\common\library\helper;
use think\Cache; use think\Cache;
/** /**
@ -80,7 +81,7 @@ class Category extends BaseModel
*/ */
public static function getCacheTreeJson() public static function getCacheTreeJson()
{ {
return json_encode(static::getCacheTree()); return helper::jsonEncode(static::getCacheTree());
} }
/** /**

View File

@ -21,6 +21,15 @@ class Coupon extends BaseModel
'state' 'state'
]; ];
/**
* 默认数据: 适用范围配置
* @var array[]
*/
protected $applyRangeConfig = [
'applyGoodsIds' => [],
'excludedGoodsIds' => []
];
/** /**
* 优惠券状态 (是否可领取) * 优惠券状态 (是否可领取)
* @param $value * @param $value
@ -93,6 +102,27 @@ class Coupon extends BaseModel
return ['text' => date('Y/m/d', $value), 'value' => $value]; return ['text' => date('Y/m/d', $value), 'value' => $value];
} }
/**
* 获取器:适用范围配置
* @param $value
* @return mixed
*/
public function getApplyRangeConfigAttr($value)
{
$array = $value ? helper::jsonDecode($value) : [];
return array_merge($this->applyRangeConfig, $array);
}
/**
* 修改器:适用范围配置
* @param $array
* @return mixed
*/
public function setApplyRangeConfigAttr($array)
{
return helper::jsonEncode(array_merge($this->applyRangeConfig, $array));
}
/** /**
* 修改器:折扣率 * 修改器:折扣率
* @param $value * @param $value

View File

@ -40,7 +40,7 @@ class Delivery extends BaseModel
public static function getAll() public static function getAll()
{ {
$model = new static; $model = new static;
return $model->order(['sort' => 'asc'])->select(); return $model->order(['sort' => 'asc', $model->getPk() => 'desc'])->select();
} }
/** /**
@ -51,7 +51,7 @@ class Delivery extends BaseModel
public function getList() public function getList()
{ {
return $this->with(['rule']) return $this->with(['rule'])
->order(['sort' => 'asc']) ->order(['sort' => 'asc', $this->getPk() => 'desc'])
->paginate(15, false, [ ->paginate(15, false, [
'query' => Request::instance()->request() 'query' => Request::instance()->request()
]); ]);
@ -80,7 +80,7 @@ class Delivery extends BaseModel
{ {
return $this->with(['rule']) return $this->with(['rule'])
->where('delivery_id', 'in', $deliveryIds) ->where('delivery_id', 'in', $deliveryIds)
->order(['sort' => 'asc']) ->order(['sort' => 'asc', $this->getPk() => 'desc'])
->select(); ->select();
} }

View File

@ -21,7 +21,7 @@ class Express extends BaseModel
public static function getAll() public static function getAll()
{ {
$model = new static; $model = new static;
return $model->order(['sort' => 'asc'])->select(); return $model->order(['sort' => 'asc', $model->getPk() => 'desc'])->select();
} }
/** /**
@ -31,7 +31,7 @@ class Express extends BaseModel
*/ */
public function getList() public function getList()
{ {
return $this->order(['sort' => 'asc']) return $this->order(['sort' => 'asc', $this->getPk() => 'desc'])
->paginate(15, false, [ ->paginate(15, false, [
'query' => Request::instance()->request() 'query' => Request::instance()->request()
]); ]);

View File

@ -140,7 +140,7 @@ class Goods extends BaseModel
} elseif ($params['sortType'] === 'sales') { } elseif ($params['sortType'] === 'sales') {
$sort = ['goods_sales' => 'desc']; $sort = ['goods_sales' => 'desc'];
} elseif ($params['sortType'] === 'price') { } elseif ($params['sortType'] === 'price') {
$sort = $params['sortPrice'] ? ['goods_max_price' => 'desc'] : ['goods_min_price']; $sort = $params['sortPrice'] ? ['goods_max_price' => 'desc'] : ['goods_min_price' => 'asc'];
} }
// 商品表名称 // 商品表名称
$tableName = $this->getTable(); $tableName = $this->getTable();

View File

@ -64,8 +64,10 @@ class Printer extends BaseModel
*/ */
public static function getAll() public static function getAll()
{ {
return (new static)->where('is_delete', '=', 0) $model = new static;
->order(['sort' => 'asc'])->select(); return $model->where('is_delete', '=', 0)
->order(['sort' => 'asc', $model->getPk() => 'desc'])
->select();
} }
/** /**
@ -76,7 +78,7 @@ class Printer extends BaseModel
public function getList() public function getList()
{ {
return $this->where('is_delete', '=', 0) return $this->where('is_delete', '=', 0)
->order(['sort' => 'asc']) ->order(['sort' => 'asc', $this->getPk() => 'desc'])
->paginate(15, false, [ ->paginate(15, false, [
'query' => Request::instance()->request() 'query' => Request::instance()->request()
]); ]);

View File

@ -27,7 +27,7 @@ class Region extends BaseModel
]; ];
// 当前数据版本号 // 当前数据版本号
private static $version = '1.2.4'; private static $version = '1.2.5';
// 县级市别名 (兼容微信端命名) // 县级市别名 (兼容微信端命名)
private static $county = [ private static $county = [

View File

@ -3,6 +3,7 @@
namespace app\common\model; namespace app\common\model;
use think\Cache; use think\Cache;
use app\common\enum\Setting as SettingEnum;
use app\common\enum\DeliveryType as DeliveryTypeEnum; use app\common\enum\DeliveryType as DeliveryTypeEnum;
/** /**
@ -98,6 +99,7 @@ class Setting extends BaseModel
public function defaultData($storeName = null) public function defaultData($storeName = null)
{ {
return [ return [
// 商城设置
'store' => [ 'store' => [
'key' => 'store', 'key' => 'store',
'describe' => '商城设置', 'describe' => '商城设置',
@ -113,6 +115,7 @@ class Setting extends BaseModel
] ]
], ],
], ],
// 交易设置
'trade' => [ 'trade' => [
'key' => 'trade', 'key' => 'trade',
'describe' => '交易设置', 'describe' => '交易设置',
@ -125,6 +128,7 @@ class Setting extends BaseModel
'freight_rule' => '10', 'freight_rule' => '10',
] ]
], ],
// 上传设置
'storage' => [ 'storage' => [
'key' => 'storage', 'key' => 'storage',
'describe' => '上传设置', 'describe' => '上传设置',
@ -154,6 +158,7 @@ class Setting extends BaseModel
] ]
], ],
], ],
// 短信通知
'sms' => [ 'sms' => [
'key' => 'sms', 'key' => 'sms',
'describe' => '短信通知', 'describe' => '短信通知',
@ -173,24 +178,26 @@ class Setting extends BaseModel
], ],
], ],
], ],
'tplMsg' => [ // 模板消息
'key' => 'tplMsg', // 'tplMsg' => [
'describe' => '模板消息', // 'key' => 'tplMsg',
'values' => [ // 'describe' => '模板消息',
'payment' => [ // 'values' => [
'is_enable' => '0', // 'payment' => [
'template_id' => '', // 'is_enable' => '0',
], // 'template_id' => '',
'delivery' => [ // ],
'is_enable' => '0', // 'delivery' => [
'template_id' => '', // 'is_enable' => '0',
], // 'template_id' => '',
'refund' => [ // ],
'is_enable' => '0', // 'refund' => [
'template_id' => '', // 'is_enable' => '0',
], // 'template_id' => '',
], // ],
], // ],
// ],
// 小票打印机设置
'printer' => [ 'printer' => [
'key' => 'printer', 'key' => 'printer',
'describe' => '小票打印机设置', 'describe' => '小票打印机设置',
@ -200,6 +207,7 @@ class Setting extends BaseModel
'order_status' => [], // 订单类型 10下单打印 20付款打印 30确认收货打印 'order_status' => [], // 订单类型 10下单打印 20付款打印 30确认收货打印
], ],
], ],
// 满额包邮设置
'full_free' => [ 'full_free' => [
'key' => 'full_free', 'key' => 'full_free',
'describe' => '满额包邮设置', 'describe' => '满额包邮设置',
@ -214,6 +222,7 @@ class Setting extends BaseModel
'notin_goods' => [], // 不参与包邮的商品 (商品id集) 'notin_goods' => [], // 不参与包邮的商品 (商品id集)
], ],
], ],
// 用户充值设置
'recharge' => [ 'recharge' => [
'key' => 'recharge', 'key' => 'recharge',
'describe' => '用户充值设置', 'describe' => '用户充值设置',
@ -227,9 +236,10 @@ class Setting extends BaseModel
"4. 若有其它疑问可拨打客服电话400-000-1234", // 充值说明 "4. 若有其它疑问可拨打客服电话400-000-1234", // 充值说明
], ],
], ],
'points' => [ // 积分设置
'key' => 'points', SettingEnum::POINTS => [
'describe' => '积分设置', 'key' => SettingEnum::POINTS,
'describe' => SettingEnum::data()[SettingEnum::POINTS]['describe'],
'values' => [ 'values' => [
'points_name' => '积分', // 积分名称自定义 'points_name' => '积分', // 积分名称自定义
'is_shopping_gift' => '0', // 是否开启购物送积分 'is_shopping_gift' => '0', // 是否开启购物送积分
@ -247,6 +257,64 @@ class Setting extends BaseModel
"d) 买家在完成该笔交易(订单状态为“已签收”)后才能得到此笔交易的相应积分,如购买商品参加店铺其他优惠,则优惠的金额部分不享受积分获取;", "d) 买家在完成该笔交易(订单状态为“已签收”)后才能得到此笔交易的相应积分,如购买商品参加店铺其他优惠,则优惠的金额部分不享受积分获取;",
], ],
], ],
// 订阅消息设置
SettingEnum::SUBMSG => [
'key' => SettingEnum::SUBMSG,
'describe' => SettingEnum::data()[SettingEnum::SUBMSG]['describe'],
'values' => [
// 订单消息
'order' => [
// 支付成功通知
'payment' => [
'template_id' => '',
'keywords' => ['character_string1', 'time2', 'amount4', 'thing3'],
'title' => '新订单提醒',
],
// 订单发货通知
'delivery' => [
'template_id' => '',
'keywords' => ['character_string1', 'thing2', 'name12', 'thing11', 'thing17'],
'title' => '订单发货通知',
],
// 售后状态通知
'refund' => [
'template_id' => '',
'keywords' => ['phrase1', 'thing6', 'character_string2', 'date3', 'thing4'],
'title' => '售后状态通知',
],
],
// 拼团消息
'sharing' => [
// 拼团进度通知
'active_status' => [
'template_id' => '',
'keywords' => ['thing1', 'amount5', 'number7', 'thing3', 'thing6'],
'title' => '拼团进度通知',
],
],
// 分销商消息
'dealer' => [
// 分销商入驻审核通知
'apply' => [
'template_id' => '',
'keywords' => ['date1', 'phrase2', 'date3', 'thing4'],
'title' => '代理商入驻审核通知',
],
// 提现成功通知
'withdraw_01' => [
'template_id' => '',
'keywords' => ['amount1', 'thing3', 'thing4'],
'title' => '提现成功通知',
],
// 提现失败通知
'withdraw_02' => [
'template_id' => '',
'keywords' => ['amount1', 'time3', 'thing4'],
'title' => '提现失败通知',
],
],
],
],
]; ];
} }

View File

@ -3,6 +3,7 @@
namespace app\common\model; namespace app\common\model;
use think\Hook; use think\Hook;
use app\common\library\helper;
/** /**
* 用户优惠券模型 * 用户优惠券模型
@ -108,6 +109,26 @@ class UserCoupon extends BaseModel
return ['text' => date('Y/m/d', $value), 'value' => $value]; return ['text' => date('Y/m/d', $value), 'value' => $value];
} }
/**
* 获取器:适用范围配置
* @param $value
* @return mixed
*/
public function getApplyRangeConfigAttr($value)
{
return $value ? helper::jsonDecode($value) : [];
}
/**
* 修改器:适用范围配置
* @param $array
* @return mixed
*/
public function setApplyRangeConfigAttr($array)
{
return helper::jsonEncode($array);
}
/** /**
* 优惠券详情 * 优惠券详情
* @param $coupon_id * @param $coupon_id

View File

@ -25,32 +25,34 @@ class Wxapp extends BaseModel
/** /**
* 获取小程序信息 * 获取小程序信息
* @param null $wxapp_id * @param int|null $wxappId
* @return static|null * @return static|null
* @throws \think\exception\DbException * @throws \think\exception\DbException
*/ */
public static function detail($wxapp_id = null) public static function detail($wxappId = null)
{ {
return self::get($wxapp_id ?: []); return static::get($wxappId ?: []);
} }
/** /**
* 从缓存中获取小程序信息 * 从缓存中获取小程序信息
* @param null $wxapp_id * @param int|null $wxappId 小程序id
* @return mixed|null|static * @return array $data
* @throws BaseException * @throws BaseException
* @throws \think\Exception
* @throws \think\exception\DbException * @throws \think\exception\DbException
*/ */
public static function getWxappCache($wxapp_id = null) public static function getWxappCache($wxappId = null)
{ {
if (is_null($wxapp_id)) { // 小程序id
$self = new static(); is_null($wxappId) && $wxappId = static::$wxapp_id;
$wxapp_id = $self::$wxapp_id; if (!$data = Cache::get("wxapp_{$wxappId}")) {
} // 获取小程序详情, 解除hidden属性
if (!$data = Cache::get('wxapp_' . $wxapp_id)) { $detail = self::detail($wxappId)->hidden([], true);
$data = self::detail($wxapp_id); if (empty($detail)) throw new BaseException(['msg' => '未找到当前小程序信息']);
if (empty($data)) throw new BaseException(['msg' => '未找到当前小程序信息']); // 写入缓存
Cache::tag('cache')->set('wxapp_' . $wxapp_id, $data); $data = $detail->toArray();
Cache::tag('cache')->set("wxapp_{$wxappId}", $data);
} }
return $data; return $data;
} }

View File

@ -20,7 +20,7 @@ class WxappHelp extends BaseModel
*/ */
public function getList() public function getList()
{ {
return $this->order(['sort' => 'asc'])->select(); return $this->order(['sort' => 'asc', $this->getPk() => 'desc'])->select();
} }
/** /**

View File

@ -93,8 +93,6 @@ class Setting extends BaseModel
"每次砍价金额随机,可砍出最高商品日常价内的随机金额,参与好友越多越容易成功。\n\n" . "每次砍价金额随机,可砍出最高商品日常价内的随机金额,参与好友越多越容易成功。\n\n" .
"以最终砍价后的优惠价格购买该商品,且用户须在活动时间结束之前进行支付购买,否则砍价商品价格将过期失效。\n\n" . "以最终砍价后的优惠价格购买该商品,且用户须在活动时间结束之前进行支付购买,否则砍价商品价格将过期失效。\n\n" .
"商品库存有限,以前台展示的库存数量为准,先到先得。", "商品库存有限,以前台展示的库存数量为准,先到先得。",
// 模板消息
'template_msg' => []
] ]
] ]
]; ];

View File

@ -13,16 +13,6 @@ class Apply extends BaseModel
{ {
protected $name = 'dealer_apply'; protected $name = 'dealer_apply';
/**
* 申请状态
* @var array
*/
public $applyStatus = [
10 => '待审核',
20 => '审核通过',
30 => '驳回',
];
/** /**
* 获取器:申请时间 * 获取器:申请时间
* @param $value * @param $value
@ -44,7 +34,7 @@ class Apply extends BaseModel
} }
/** /**
* 关联推荐人 * 关联用户
* @return \think\model\relation\BelongsTo * @return \think\model\relation\BelongsTo
*/ */
public function referee() public function referee()
@ -53,6 +43,16 @@ class Apply extends BaseModel
->field(['user_id', 'nickName']); ->field(['user_id', 'nickName']);
} }
/**
* 关联会员记录表
* @return \think\model\relation\BelongsTo
*/
public function user()
{
$module = self::getCalledModule() ?: 'common';
return $this->belongsTo("app\\{$module}\\model\\User");
}
/** /**
* 销商申请记录详情 * 销商申请记录详情
* @param $where * @param $where

View File

@ -348,14 +348,6 @@ class Setting extends BaseModel
'withdraw_apply' => self::$base_url . 'assets/api/dealer-bg.png', 'withdraw_apply' => self::$base_url . 'assets/api/dealer-bg.png',
], ],
], ],
'template_msg' => [
'key' => 'template_msg',
'describe' => '模板消息',
'values' => [
'apply_tpl' => '', // 分销商审核通知
'withdraw_tpl' => '', // 提现状态通知
]
],
'qrcode' => [ 'qrcode' => [
'key' => 'template_msg', 'key' => 'template_msg',
'describe' => '分销海报', 'describe' => '分销海报',

View File

@ -13,27 +13,6 @@ class Withdraw extends BaseModel
{ {
protected $name = 'dealer_withdraw'; protected $name = 'dealer_withdraw';
/**
* 打款方式
* @var array
*/
public $payType = [
10 => '微信',
20 => '支付宝',
30 => '银行卡',
];
/**
* 申请状态
* @var array
*/
public $applyStatus = [
10 => '待审核',
20 => '审核通过',
30 => '驳回',
40 => '已打款',
];
/** /**
* 关联分销商用户表 * 关联分销商用户表
* @return \think\model\relation\BelongsTo * @return \think\model\relation\BelongsTo

View File

@ -5,6 +5,7 @@ namespace app\common\model\sharing;
use think\Hook; use think\Hook;
use app\common\model\BaseModel; use app\common\model\BaseModel;
use app\common\service\Message as MessageService; use app\common\service\Message as MessageService;
use app\common\enum\sharing\ActiveStatus as ActiveStatusEnum;
/** /**
* 拼团拼单模型 * 拼团拼单模型
@ -34,13 +35,7 @@ class Active extends BaseModel
*/ */
public function getStatusAttr($value) public function getStatusAttr($value)
{ {
$state = [ return ['text' => ActiveStatusEnum::data()[$value]['name'], 'value' => $value];
0 => '未拼单',
10 => '拼单中',
20 => '拼单成功',
30 => '拼单失败',
];
return ['text' => $state[$value], 'value' => $value];
} }
/** /**
@ -157,13 +152,12 @@ class Active extends BaseModel
/** /**
* 更新拼单记录 * 更新拼单记录
* @param $user_id * @param $userId
* @param $order_id * @param $orderId
* @return bool * @return bool
* @throws \app\common\exception\BaseException
* @throws \think\exception\DbException * @throws \think\exception\DbException
*/ */
public function onUpdate($user_id, $order_id) public function onUpdate($userId, $orderId)
{ {
// 验证当前拼单是否允许加入新成员 // 验证当前拼单是否允许加入新成员
if (!$this->checkAllowJoin()) { if (!$this->checkAllowJoin()) {
@ -172,8 +166,8 @@ class Active extends BaseModel
// 新增拼单成员记录 // 新增拼单成员记录
ActiveUsers::add([ ActiveUsers::add([
'active_id' => $this['active_id'], 'active_id' => $this['active_id'],
'order_id' => $order_id, 'order_id' => $orderId,
'user_id' => $user_id, 'user_id' => $userId,
'is_creator' => 0, 'is_creator' => 0,
'wxapp_id' => $this['wxapp_id'] 'wxapp_id' => $this['wxapp_id']
]); ]);
@ -185,10 +179,13 @@ class Active extends BaseModel
'actual_people' => $actual_people, 'actual_people' => $actual_people,
'status' => $status 'status' => $status
]); ]);
// 拼单成功, 发送模板消息 // 拼单成功, 发送订阅消息
if ($status == 20) { if ($status == 20) {
$model = static::detail($this['active_id']); $model = static::detail($this['active_id']);
(new MessageService)->sharingActive($model, '拼团成功'); MessageService::send('sharing.active_status', [
'active' => $model,
'status' => ActiveStatusEnum::ACTIVE_STATE_SUCCESS,
]);
} }
return true; return true;
} }

View File

@ -95,8 +95,6 @@ class Setting extends BaseModel
'rule_brief' => '好友拼单 · 人满发货 · 人不满退款', 'rule_brief' => '好友拼单 · 人满发货 · 人不满退款',
// 拼团规则 详述 // 拼团规则 详述
'rule_detail' => "开团:选择商品,点击“发起拼单”按钮,付款完成后即开团成功,就可以邀请小伙伴一起拼团啦;\n\n参团:进入朋友分享的页面,点击“立即参团”按钮,付款完成后参团成功,在有效时间内凑齐人数即成团,就可以等待收货喽;\n\n成团:在开团或参团成功后,点击“立即分享”将页面分享给好友,在有效时间内凑齐人数即成团,成团后商家开始发货;\n\n组团失败:在有效时间内未凑齐人数,即组团失败,组团失败后订单所付款将原路退回到支付账户。", 'rule_detail' => "开团:选择商品,点击“发起拼单”按钮,付款完成后即开团成功,就可以邀请小伙伴一起拼团啦;\n\n参团:进入朋友分享的页面,点击“立即参团”按钮,付款完成后参团成功,在有效时间内凑齐人数即成团,就可以等待收货喽;\n\n成团:在开团或参团成功后,点击“立即分享”将页面分享给好友,在有效时间内凑齐人数即成团,成团后商家开始发货;\n\n组团失败:在有效时间内未凑齐人数,即组团失败,组团失败后订单所付款将原路退回到支付账户。",
// 拼单状态模板消息id
'tpl_msg_id' => '',
] ]
] ]
]; ];

View File

@ -58,7 +58,7 @@ class Goods extends BaseModel
$list = $this->with(['sku']) $list = $this->with(['sku'])
->where('sharp_goods_id', 'in', $goodsIds) ->where('sharp_goods_id', 'in', $goodsIds)
->where('is_delete', '=', 0) ->where('is_delete', '=', 0)
->order(['sort' => 'asc']) ->order(['sort' => 'asc', $this->getPk() => 'desc'])
->paginate($param['limit'], false, [ ->paginate($param['limit'], false, [
'query' => \request()->request() 'query' => \request()->request()
]); ]);

View File

@ -105,6 +105,7 @@ class Grade extends BaseModel
$model = new static; $model = new static;
$gradeId > 0 && $model->where('grade_id', '<>', (int)$gradeId); $gradeId > 0 && $model->where('grade_id', '<>', (int)$gradeId);
return $model->where('weight', '=', (int)$weight) return $model->where('weight', '=', (int)$weight)
->where('is_delete', '=', 0)
->value('grade_id'); ->value('grade_id');
} }

View File

@ -0,0 +1,47 @@
<?php
namespace app\common\model\wxapp;
use app\common\model\BaseModel;
/**
* 微信小程序直播间模型
* Class LiveRoom
* @package app\common\model\wxapp
*/
class LiveRoom extends BaseModel
{
protected $name = 'wxapp_live_room';
/**
* 获取器: 开播时间
* @param $value
* @return false|string
*/
public function getStartTimeAttr($value)
{
return \format_time($value);
}
/**
* 获取器: 结束时间
* @param $value
* @return false|string
*/
public function getEndTimeAttr($value)
{
return \format_time($value);
}
/**
* 获取直播间详情
* @param int $id
* @return static|null
* @throws \think\exception\DbException
*/
public static function detail($id)
{
return static::get($id);
}
}

View File

@ -2,351 +2,47 @@
namespace app\common\service; namespace app\common\service;
//use app\common\model\User as UserModel;
use app\common\model\Wxapp as WxappModel;
use app\common\model\Setting as SettingModel;
//use app\common\model\dealer\Setting as DealerSettingModel;
//use app\common\model\sharing\Setting as SharingSettingModel;
//use app\common\service\wxapp\FormId as FormIdService;
use app\common\enum\OrderType as OrderTypeEnum;
use app\common\library\wechat\WxTplMsg;
use app\common\library\sms\Driver as SmsDriver;
/** /**
* 消息通知服务 * 消息通知服务
* Class Message * Class Message
* @package app\common\service * @package app\common\service
*/ */
class Message class Message extends Basics
{ {
/** /**
* 订单支付成功后通知 * 场景列表
* @param \think\Model $order * [场景名称] => [场景类]
* @param int $orderType 订单类型 (10商城订单 20拼团订单) * @var array
*/
private static $sceneList = [
// 订单支付成功
'order.payment' => 'app\common\service\message\order\Payment',
// 订单发货
'order.delivery' => 'app\common\service\message\order\Delivery',
// 订单退款
'order.refund' => 'app\common\service\message\order\Refund',
// 拼团进度通知
'sharing.active_status' => 'app\common\service\message\sharing\ActiveStatus',
// 分销商入驻通知
'dealer.apply' => 'app\common\service\message\dealer\Apply',
// 分销商提现通知
'dealer.withdraw' => 'app\common\service\message\dealer\Withdraw',
];
/**
* 发送消息通知
* @param string $sceneName 场景名称
* @param array $param 参数
* @return bool * @return bool
// * @throws \app\common\exception\BaseException
* @throws \think\Exception
// * @throws \think\exception\DbException
*/ */
public function payment($order, $orderType = OrderTypeEnum::MASTER) public static function send($sceneName, $param)
{ {
// // 1. 微信模板消息 if (!isset(self::$sceneList[$sceneName]))
// $template = SettingModel::getItem('tplMsg', $order['wxapp_id'])['payment']; return false;
// if (!$template['is_enable'] || empty($template['template_id'])) { $className = self::$sceneList[$sceneName];
// return false; return class_exists($className) ? (new $className)->send($param) : false;
// }
// // 获取可用的formid
// if (!$formId = FormIdService::getAvailableFormId($order['user_id'])) {
// return false;
// }
// // 页面链接
// $urls = [
// OrderTypeEnum::MASTER => 'pages/order/detail',
// OrderTypeEnum::SHARING => 'pages/sharing/order/detail/detail',
// ];
// // 发送模板消息
// $status = $this->sendTemplateMessage($order['wxapp_id'], [
// 'touser' => $order['user']['open_id'],
// 'template_id' => $template['template_id'],
// 'page' => $urls[$orderType] . '?order_id=' . $order['order_id'],
// 'form_id' => $formId['form_id'],
// 'data' => [
// // 订单编号
// 'keyword1' => $order['order_no'],
// // 支付时间
// 'keyword2' => date('Y-m-d H:i:s', $order['pay_time']),
// // 订单金额
// 'keyword3' => $order['pay_price'],
// // 商品名称
// 'keyword4' => $this->formatGoodsName($order['goods']),
// ]
// ]);
// // 标记formid已使用
// $status === true && FormIdService::setIsUsed($formId['id']);
// 2. 商家短信通知
$smsConfig = SettingModel::getItem('sms', $order['wxapp_id']);
$SmsDriver = new SmsDriver($smsConfig);
return $SmsDriver->sendSms('order_pay', ['order_no' => $order['order_no']]);
}
/**
* 后台发货通知
* @param \think\Model $order
* @param int $orderType 订单类型 (10商城订单 20拼团订单)
* @return bool
// * @throws \app\common\exception\BaseException
// * @throws \think\Exception
// * @throws \think\exception\DbException
*/
public function delivery($order, $orderType = OrderTypeEnum::MASTER)
{
return true;
// // 微信模板消息
// $template = SettingModel::getItem('tplMsg', $order['wxapp_id'])['delivery'];
// if (!$template['is_enable'] || empty($template['template_id'])) {
// return false;
// }
// // 获取可用的formid
// if (!$formId = FormIdService::getAvailableFormId($order['user_id'])) {
// return false;
// }
// // 页面链接
// $urls = [
// OrderTypeEnum::MASTER => 'pages/order/detail',
// OrderTypeEnum::SHARING => 'pages/sharing/order/detail/detail',
// ];
// // 发送模板消息
// $status = $this->sendTemplateMessage($order['wxapp_id'], [
// 'touser' => $order['user']['open_id'],
// 'template_id' => $template['template_id'],
// 'page' => $urls[$orderType] . '?order_id=' . $order['order_id'],
// 'form_id' => $formId['form_id'],
// 'data' => [
// // 订单编号
// 'keyword1' => $order['order_no'],
// // 商品信息
// 'keyword2' => $this->formatGoodsName($order['goods']),
// // 收货人
// 'keyword3' => $order['address']['name'],
// // 收货地址
// 'keyword4' => implode('', $order['address']['region']) . $order['address']['detail'],
// // 物流公司
// 'keyword5' => $order['express']['express_name'],
// // 物流单号
// 'keyword6' => $order['express_no'],
// ]
// ]);
// // 标记formid已使用
// $status === true && FormIdService::setIsUsed($formId['id']);
// return $status;
}
/**
* 后台售后单状态通知
* @param \think\Model $refund
* @param $order_no
* @param int $orderType 订单类型 (10商城订单 20拼团订单)
* @return bool
// * @throws \app\common\exception\BaseException
// * @throws \think\Exception
// * @throws \think\exception\DbException
*/
public function refund($refund, $order_no, $orderType = OrderTypeEnum::MASTER)
{
return true;
// // 微信模板消息
// $template = SettingModel::getItem('tplMsg', $refund['wxapp_id'])['refund'];
// if (!$template['is_enable'] || empty($template['template_id'])) {
// return false;
// }
// // 获取可用的formid
// if (!$formId = FormIdService::getAvailableFormId($refund['user_id'])) {
// return false;
// }
// // 页面链接
// $urls = [
// OrderTypeEnum::MASTER => 'pages/order/refund/index',
// OrderTypeEnum::SHARING => 'pages/sharing/order/refund/index',
// ];
// // 发送模板消息
// $status = $this->sendTemplateMessage($refund['wxapp_id'], [
// 'touser' => $refund['user']['open_id'],
// 'template_id' => $template['template_id'],
// 'page' => $urls[$orderType],
// 'form_id' => $formId['form_id'],
// 'data' => [
// // 售后类型
// 'keyword1' => $refund['type']['text'],
// // 状态
// 'keyword2' => $refund['status']['text'],
// // 订单号
// 'keyword3' => $order_no,
// // 商品名称
// 'keyword4' => $refund['order_goods']['goods_name'],
// // 申请时间
// 'keyword5' => $refund['create_time'],
// // 申请原因
// 'keyword6' => $refund['apply_desc'],
// ]
// ]);
// // 标记formid已使用
// FormIdService::setIsUsed($formId['id']);
// return $status;
}
/**
* 拼团拼单状态通知
* @param \app\common\model\sharing\Active $active
* @param string $status_text
* @return bool
// * @throws \app\common\exception\BaseException
// * @throws \think\exception\DbException
*/
public function sharingActive($active, $status_text)
{
return true;
// // 微信模板消息
// $config = SharingSettingModel::getItem('basic', $active['wxapp_id']);
// if (empty($config['tpl_msg_id'])) {
// return false;
// }
// foreach ($active['users'] as $item) {
// // 获取可用的formid
// if (!$formId = FormIdService::getAvailableFormId($item['user']['user_id'])) {
// continue;
// }
// // 发送模板消息
// $this->sendTemplateMessage($active['wxapp_id'], [
// 'touser' => $item['user']['open_id'],
// 'template_id' => $config['tpl_msg_id'],
// 'page' => 'pages/sharing/active/index?active_id=' . $active['active_id'],
// 'form_id' => $formId['form_id'],
// 'data' => [
// // 订单编号
// 'keyword1' => $item['sharing_order']['order_no'],
// // 商品名称
// 'keyword2' => $active['goods']['goods_name'],
// // 拼团价格
// 'keyword3' => $item['sharing_order']['pay_price'],
// // 拼团人数
// 'keyword4' => $active['people'],
// // 拼团时间
// 'keyword5' => $item['create_time'],
// // 拼团结果
// 'keyword6' => $status_text,
// ]
// ]);
// // 标记formid已使用
// FormIdService::setIsUsed($formId['id']);
// }
// return true;
}
/**
* 分销商提现审核通知
* @param \app\common\model\dealer\Withdraw $withdraw
* @return bool
// * @throws \app\common\exception\BaseException
// * @throws \think\exception\DbException
*/
public function withdraw($withdraw)
{
return true;
// // 模板消息id
// $template = DealerSettingModel::getItem('template_msg', $withdraw['wxapp_id']);
// if (empty($template['withdraw_tpl'])) {
// return false;
// }
// // 获取可用的formid
// if (!$formId = FormIdService::getAvailableFormId($withdraw['user_id'])) {
// return false;
// }
// // 获取用户信息
// $user = UserModel::detail($withdraw['user_id']);
// // 发送模板消息
// $remark = '无';
// if ($withdraw['apply_status'] == 30) {
// $remark = $withdraw['reject_reason'];
// }
// $status = $this->sendTemplateMessage($withdraw['wxapp_id'], [
// 'touser' => $user['open_id'],
// 'template_id' => $template['withdraw_tpl'],
// 'page' => 'pages/dealer/withdraw/list/list',
// 'form_id' => $formId['form_id'],
// 'data' => [
// // 提现时间
// 'keyword1' => $withdraw['create_time'],
// // 提现方式
// 'keyword2' => $withdraw['pay_type']['text'],
// // 提现金额
// 'keyword3' => $withdraw['money'],
// // 提现状态
// 'keyword4' => $withdraw->applyStatus[$withdraw['apply_status']],
// // 备注
// 'keyword5' => $remark,
// ]
// ]);
// // 标记formid已使用
// FormIdService::setIsUsed($formId['id']);
// return $status;
}
/**
* 分销商入驻审核通知
* @param \app\common\model\dealer\Apply $dealer
* @return bool
// * @throws \app\common\exception\BaseException
// * @throws \think\exception\DbException
*/
public function dealer($dealer)
{
return true;
// // 模板消息id
// $template = DealerSettingModel::getItem('template_msg', $dealer['wxapp_id']);
// if (empty($template['apply_tpl'])) {
// return false;
// }
// // 获取可用的formid
// if (!$formId = FormIdService::getAvailableFormId($dealer['user_id'])) {
// return false;
// }
// // 获取用户信息
// $user = UserModel::detail($dealer['user_id']);
// // 发送模板消息
// $remark = '分销商入驻审核通知';
// if ($dealer['apply_status'] == 30) {
// $remark .= "\n\n驳回原因" . $dealer['reject_reason'];
// }
// $status = $this->sendTemplateMessage($dealer['wxapp_id'], [
// 'touser' => $user['open_id'],
// 'template_id' => $template['apply_tpl'],
// 'page' => 'pages/dealer/index/index',
// 'form_id' => $formId['form_id'],
// 'data' => [
// // 申请时间
// 'keyword1' => $dealer['apply_time'],
// // 审核状态
// 'keyword2' => $dealer->applyStatus[$dealer['apply_status']],
// // 审核时间
// 'keyword3' => $dealer['audit_time'],
// // 备注信息
// 'keyword4' => $remark,
// ]
// ]);
// // 标记formid已使用
// FormIdService::setIsUsed($formId['id']);
// return $status;
}
/**
* 发送模板消息
* @param $wxappId
* @param $params
* @return bool
* @throws \app\common\exception\BaseException
* @throws \think\exception\DbException
*/
private function sendTemplateMessage($wxappId, $params)
{
// 微信模板消息
$wxConfig = WxappModel::getWxappCache($wxappId);
$WxTplMsg = new WxTplMsg($wxConfig['app_id'], $wxConfig['app_secret']);
return $WxTplMsg->sendTemplateMessage($params);
}
/**
* 格式化商品名称
* @param $goodsData
* @return string
*/
private function formatGoodsName($goodsData)
{
$str = '';
foreach ($goodsData as $goods) {
$str .= $goods['goods_name'] . ' ';
}
return $str;
} }
} }

View File

@ -0,0 +1,71 @@
<?php
namespace app\common\service\message;
use app\common\model\Wxapp as WxappModel;
use app\common\model\Setting as SettingModel;
use app\common\library\sms\Driver as SmsDriver;
use app\common\library\wechat\WxSubMsg;
/**
* 消息通知服务[基类]
* Class Basics
* @package app\common\service\message
*/
abstract class Basics extends \app\common\service\Basics
{
// 参数列表
protected $param = [];
/**
* 发送消息通知
* @param array $param 参数
* @return mixed
*/
abstract public function send($param);
/**
* 发送短信提醒
* @param $msgType
* @param $templateParams
* @param $wxappId
* @return bool
* @throws \think\Exception
*/
protected function sendSms($msgType, $templateParams, $wxappId)
{
$smsConfig = SettingModel::getItem('sms', $wxappId);
return (new SmsDriver($smsConfig))->sendSms($msgType, $templateParams);
}
/**
* 发送微信订阅消息
* @param $wxappId
* @param $params
* @return mixed
* @throws \app\common\exception\BaseException
* @throws \think\Exception
* @throws \think\exception\DbException
*/
protected function sendWxSubMsg($wxappId, $params)
{
// 获取小程序配置
$wxConfig = WxappModel::getWxappCache($wxappId);
// 请求微信api执行发送
$WxSubMsg = new WxSubMsg($wxConfig['app_id'], $wxConfig['app_secret']);
return $WxSubMsg->sendTemplateMessage($params);
}
/**
* 字符串截取前20字符
* [用于兼容thing数据类型]
* @param $content
* @param int $length
* @return bool|string
*/
protected function getSubstr($content, $length = 20)
{
return str_substr($content, $length);
}
}

View File

@ -0,0 +1,90 @@
<?php
namespace app\common\service\message\dealer;
use app\common\service\message\Basics;
use app\common\model\Setting as SettingModel;
use app\common\enum\dealer\ApplyStatus as ApplyStatusEnum;
/**
* 消息通知服务 [分销商入驻]
* Class Apply
* @package app\common\service\message\dealer
*/
class Apply extends Basics
{
/**
* 参数列表
* @var array
*/
protected $param = [
'apply' => [], // 申请记录
'user' => [], // 用户信息
];
/**
* 发送消息通知
* @param array $param
* @return mixed|void
* @throws \think\Exception
*/
public function send($param)
{
// 记录参数
$this->param = $param;
// 微信订阅消息通知用户
$this->onSendWxSubMsg();
}
/**
* 微信订阅消息通知用户
* @return bool|mixed
* @throws \app\common\exception\BaseException
* @throws \think\Exception
* @throws \think\exception\DbException
*/
private function onSendWxSubMsg()
{
$applyInfo = $this->param['apply'];
$userInfo = $this->param['user'];
$wxappId = $applyInfo['wxapp_id'];
// 获取订阅消息配置
$template = SettingModel::getItem('submsg', $wxappId)['dealer']['apply'];
if (empty($template['template_id'])) {
return false;
}
// 发送订阅消息
return $this->sendWxSubMsg($wxappId, [
'touser' => $userInfo['open_id'],
'template_id' => $template['template_id'],
'page' => 'pages/dealer/index/index',
'data' => [
// 申请时间
$template['keywords'][0] => ['value' => $applyInfo['apply_time']],
// 审核状态
$template['keywords'][1] => ['value' => ApplyStatusEnum::data()[$applyInfo['apply_status']]['name']],
// 审核时间
$template['keywords'][2] => ['value' => $applyInfo['audit_time']],
// 备注信息
$template['keywords'][3] => ['value' => $this->getRemarkValue($applyInfo)],
]
]);
}
/**
* 备注信息
* @param $applyInfo
* @return string
*/
private function getRemarkValue($applyInfo)
{
$remark = '分销商入驻审核通知';
if ($applyInfo['apply_status'] == 30) {
$remark .= "\n驳回原因:{$applyInfo['reject_reason']}";
}
return $this->getSubstr($remark);
}
}

View File

@ -0,0 +1,122 @@
<?php
namespace app\common\service\message\dealer;
use app\common\service\message\Basics;
use app\common\model\Setting as SettingModel;
use app\common\enum\dealer\withdraw\ApplyStatus as ApplyStatusEnum;
/**
* 消息通知服务 [分销商提现]
* Class Withdraw
* @package app\common\service\message\dealer
*/
class Withdraw extends Basics
{
/**
* 参数列表
* @var array
*/
protected $param = [
'withdraw' => [], // 提现记录
];
/**
* 发送消息通知
* @param array $param
* @return mixed|void
* @throws \think\Exception
*/
public function send($param)
{
// 记录参数
$this->param = $param;
// 微信订阅消息通知用户
$this->onSendWxSubMsg();
}
/**
* 微信订阅消息通知用户
* @return bool|mixed
* @throws \app\common\exception\BaseException
* @throws \think\Exception
* @throws \think\exception\DbException
*/
private function onSendWxSubMsg()
{
$withdrawInfo = $this->param['withdraw'];
$userInfo = $this->param['user'];
$wxappId = $withdrawInfo['wxapp_id'];
// 根据提现状态获取对应的消息模板
$template = $this->getTemplateByStatus($withdrawInfo);
if ($template === false) {
return false;
}
// 发送订阅消息
return $this->sendWxSubMsg($wxappId, [
'touser' => $userInfo['open_id'],
'template_id' => $template['template_id'],
'page' => 'pages/dealer/index/index',
'data' => $this->getTemplateData($withdrawInfo, $template)
]);
}
/**
* 生成消息内容
* @param $withdrawInfo
* @param $template
* @return array
*/
private function getTemplateData($withdrawInfo, $template)
{
if ($withdrawInfo['apply_status'] == ApplyStatusEnum::AUDIT_PASS) {
return [
// 提现金额
$template['keywords'][0] => ['value' => $withdrawInfo['money']],
// 打款方式
$template['keywords'][1] => ['value' => $withdrawInfo['pay_type']['text']],
// 打款原因
$template['keywords'][2] => ['value' => '分销商提现'],
];
}
if ($withdrawInfo['apply_status'] == ApplyStatusEnum::AUDIT_REJECT) {
return [
// 提现金额
$template['keywords'][0] => ['value' => $withdrawInfo['money']],
// 申请时间
$template['keywords'][1] => ['value' => $withdrawInfo['create_time']],
// 原因
$template['keywords'][2] => ['value' => $this->getSubstr($withdrawInfo['reject_reason'])],
];
}
return [];
}
/**
* 根据提现状态获取对应的消息模板
* @param $withdrawInfo
* @return bool
*/
private function getTemplateByStatus($withdrawInfo)
{
$wxappId = $withdrawInfo['wxapp_id'];
// 获取订阅消息配置
$templateGroup = SettingModel::getItem('submsg', $wxappId)['dealer'];
if (
$withdrawInfo['apply_status'] == ApplyStatusEnum::AUDIT_PASS
&& !empty($templateGroup['withdraw_01']['template_id'])
) {
return $templateGroup['withdraw_01'];
}
if (
$withdrawInfo['apply_status'] == ApplyStatusEnum::AUDIT_REJECT
&& !empty($templateGroup['withdraw_02']['template_id'])
) {
return $templateGroup['withdraw_02'];
}
return false;
}
}

View File

@ -0,0 +1,117 @@
<?php
namespace app\common\service\message\order;
use app\common\service\message\Basics;
use app\common\model\Setting as SettingModel;
use app\common\enum\OrderType as OrderTypeEnum;
/**
* 消息通知服务 [订单发货]
* Class Delivery
* @package app\common\service\message\order
*/
class Delivery extends Basics
{
/**
* 参数列表
* @var array
*/
protected $param = [
'order' => [],
'order_type' => OrderTypeEnum::MASTER,
];
/**
* 订单页面链接
* @var array
*/
private $pageUrl = [
OrderTypeEnum::MASTER => 'pages/order/detail',
OrderTypeEnum::SHARING => 'pages/sharing/order/detail/detail',
];
/**
* 发送消息通知
* @param array $param
* @return mixed|void
* @throws \think\Exception
*/
public function send($param)
{
// 记录参数
$this->param = $param;
// 微信订阅消息通知用户
$this->onSendWxSubMsg();
}
/**
* 微信订阅消息通知用户
* @return bool|mixed
* @throws \app\common\exception\BaseException
* @throws \think\Exception
* @throws \think\exception\DbException
*/
private function onSendWxSubMsg()
{
$orderInfo = $this->param['order'];
$orderType = $this->param['order_type'];
$wxappId = $orderInfo['wxapp_id'];
// 获取订阅消息配置
$template = SettingModel::getItem('submsg', $wxappId)['order']['delivery'];
if (empty($template['template_id'])) {
return false;
}
// 发送订阅消息
return $this->sendWxSubMsg($wxappId, [
'touser' => $orderInfo['user']['open_id'],
'template_id' => $template['template_id'],
'page' => "{$this->pageUrl[$orderType]}?order_id={$orderInfo['order_id']}",
'data' => [
// 订单号
$template['keywords'][0] => ['value' => $orderInfo['order_no']],
// 商品名称
$template['keywords'][1] => ['value' => $this->getFormatGoodsName($orderInfo['goods'])],
// 收货人
$template['keywords'][2] => ['value' => $orderInfo['address']['name']],
// 收货地址
$template['keywords'][3] => ['value' => $this->getFormatAddress($orderInfo)],
// 物流公司
$template['keywords'][4] => ['value' => $this->getFormatExpressName($orderInfo)],
]
]);
}
/**
* 格式化物流公司
* @param $orderInfo
* @return mixed
*/
private function getFormatExpressName($orderInfo)
{
return $this->getSubstr($orderInfo['express']['express_name']);
}
/**
* 格式化用户收货地址
* @param $orderInfo
* @return string
*/
private function getFormatAddress($orderInfo)
{
$address = implode('', $orderInfo['address']['region']) . $orderInfo['address']['detail'];
return $this->getSubstr($address);
}
/**
* 格式化商品名称
* @param $goodsData
* @return string
*/
private function getFormatGoodsName($goodsData)
{
return $this->getSubstr($goodsData[0]['goods_name']);
}
}

View File

@ -0,0 +1,107 @@
<?php
namespace app\common\service\message\order;
use app\common\service\message\Basics;
use app\common\model\Setting as SettingModel;
use app\common\enum\OrderType as OrderTypeEnum;
/**
* 消息通知服务 [订单支付成功]
* Class Payment
* @package app\common\service\message\order
*/
class Payment extends Basics
{
/**
* 参数列表
* @var array
*/
protected $param = [
'order' => [],
'order_type' => OrderTypeEnum::MASTER,
];
/**
* 订单页面链接
* @var array
*/
private $pageUrl = [
OrderTypeEnum::MASTER => 'pages/order/detail',
OrderTypeEnum::SHARING => 'pages/sharing/order/detail/detail',
];
/**
* 发送消息通知
* @param array $param
* @return mixed|void
* @throws \think\Exception
*/
public function send($param)
{
// 记录参数
$this->param = $param;
// 短信通知商家
$this->onSendSms();
// 微信订阅消息通知用户
$this->onSendWxSubMsg();
}
/**
* 短信通知商家
* @return bool
* @throws \think\Exception
*/
private function onSendSms()
{
$orderInfo = $this->param['order'];
$wxappId = $orderInfo['wxapp_id'];
return $this->sendSms('order_pay', ['order_no' => $orderInfo['order_no']], $wxappId);
}
/**
* 微信订阅消息通知用户
* @return bool|mixed
* @throws \app\common\exception\BaseException
* @throws \think\Exception
* @throws \think\exception\DbException
*/
private function onSendWxSubMsg()
{
$orderInfo = $this->param['order'];
$orderType = $this->param['order_type'];
$wxappId = $orderInfo['wxapp_id'];
// 获取订阅消息配置
$template = SettingModel::getItem('submsg', $wxappId)['order']['payment'];
if (empty($template['template_id'])) {
return false;
}
// 发送订阅消息
return $this->sendWxSubMsg($wxappId, [
'touser' => $orderInfo['user']['open_id'],
'template_id' => $template['template_id'],
'page' => "{$this->pageUrl[$orderType]}?order_id={$orderInfo['order_id']}",
'data' => [
// 订单编号
$template['keywords'][0] => ['value' => $orderInfo['order_no']],
// 下单时间
$template['keywords'][1] => ['value' => format_time($orderInfo['pay_time'])],
// 订单金额
$template['keywords'][2] => ['value' => $orderInfo['pay_price']],
// 商品名称
$template['keywords'][3] => ['value' => $this->getFormatGoodsName($orderInfo['goods'])],
]
]);
}
/**
* 格式化商品名称
* @param $goodsData
* @return string
*/
private function getFormatGoodsName($goodsData)
{
return $this->getSubstr($goodsData[0]['goods_name']);
}
}

View File

@ -0,0 +1,89 @@
<?php
namespace app\common\service\message\order;
use app\common\service\message\Basics;
use app\common\model\Setting as SettingModel;
use app\common\enum\OrderType as OrderTypeEnum;
/**
* 消息通知服务 [订单售后]
* Class Refund
* @package app\common\service\message\order
*/
class Refund extends Basics
{
/**
* 参数列表
* @var array
*/
protected $param = [
'refund' => [], // 退款单信息
'order_no' => [], // 订单信息
'order_type' => OrderTypeEnum::MASTER, // 订单类型
];
/**
* 订单页面链接
* @var array
*/
private $pageUrl = [
OrderTypeEnum::MASTER => 'pages/order/refund/index',
OrderTypeEnum::SHARING => 'pages/sharing/order/refund/index',
];
/**
* 发送消息通知
* @param array $param
* @return mixed|void
* @throws \think\Exception
*/
public function send($param)
{
// 记录参数
$this->param = $param;
// 微信订阅消息通知用户
$this->onSendWxSubMsg();
}
/**
* 微信订阅消息通知用户
* @return bool|mixed
* @throws \app\common\exception\BaseException
* @throws \think\Exception
* @throws \think\exception\DbException
*/
private function onSendWxSubMsg()
{
$refundInfo = $this->param['refund'];
$orderNo = $this->param['order_no'];
$orderType = $this->param['order_type'];
$wxappId = $refundInfo['wxapp_id'];
// 获取订阅消息配置
$template = SettingModel::getItem('submsg', $wxappId)['order']['refund'];
if (empty($template['template_id'])) {
return false;
}
// 发送订阅消息
return $this->sendWxSubMsg($wxappId, [
'touser' => $refundInfo['user']['open_id'],
'template_id' => $template['template_id'],
'page' => "{$this->pageUrl[$orderType]}",
'data' => [
// 售后类型
$template['keywords'][0] => ['value' => $refundInfo['type']['text']],
// 状态
$template['keywords'][1] => ['value' => $refundInfo['status']['text']],
// 订单编号
$template['keywords'][2] => ['value' => $orderNo],
// 申请时间
$template['keywords'][3] => ['value' => $refundInfo['create_time']],
// 申请原因
$template['keywords'][4] => ['value' => $this->getSubstr($refundInfo['apply_desc'])],
]
]);
}
}

View File

@ -0,0 +1,82 @@
<?php
namespace app\common\service\message\sharing;
use app\common\service\message\Basics;
use app\common\model\Setting as SettingModel;
use app\common\enum\sharing\ActiveStatus as ActiveStatusEnum;
/**
* 消息通知服务 [拼团进度]
* Class ActiveStatus
* @package app\common\service\message\sharing
*/
class ActiveStatus extends Basics
{
/**
* 参数列表
* @var array
*/
protected $param = [
'active' => [], // 拼单详情
'status' => false, // 拼单状态
];
/**
* 发送消息通知
* @param array $param
* @return mixed|void
* @throws \think\Exception
*/
public function send($param)
{
// 记录参数
$this->param = $param;
// 微信订阅消息通知用户
$this->onSendWxSubMsg();
}
/**
* 微信订阅消息通知用户
* @return bool
* @throws \app\common\exception\BaseException
* @throws \think\Exception
* @throws \think\exception\DbException
*/
private function onSendWxSubMsg()
{
// 拼单详情
$activeInfo = $this->param['active'];
$status = $this->param['status'];
$wxappId = $activeInfo['wxapp_id'];
// 获取订阅消息配置
$template = SettingModel::getItem('submsg', $wxappId)['sharing']['active_status'];
if (empty($template['template_id'])) {
return false;
}
// 发送订阅消息
foreach ($activeInfo['users'] as $item) {
$this->sendWxSubMsg($wxappId, [
'touser' => $item['user']['open_id'],
'template_id' => $template['template_id'],
'page' => "pages/sharing/active/index?active_id={$activeInfo['active_id']}",
'data' => [
// 拼团商品
$template['keywords'][0] => ['value' => str_substr($activeInfo['goods']['goods_name'], 20)],
// 拼团价格
$template['keywords'][1] => ['value' => $item['sharing_order']['pay_price']],
// 成团人数
$template['keywords'][2] => ['value' => $activeInfo['people']],
// 拼团进度
$template['keywords'][3] => ['value' => "已有{$activeInfo['actual_people']}人参与"],
// 温馨提示
$template['keywords'][4] => ['value' => ActiveStatusEnum::data()[$status]['name']],
]
]);
}
return true;
}
}

View File

@ -25,7 +25,7 @@ class Refund
* @throws \think\exception\DbException * @throws \think\exception\DbException
* @throws \app\common\exception\BaseException * @throws \app\common\exception\BaseException
*/ */
public function execute(&$order, $money = null) public function execute($order, $money = null)
{ {
// 退款金额,如不指定则默认为订单实付款金额 // 退款金额,如不指定则默认为订单实付款金额
is_null($money) && $money = $order['pay_price']; is_null($money) && $money = $order['pay_price'];

View File

@ -2,6 +2,7 @@
namespace app\common\service\qrcode; namespace app\common\service\qrcode;
use app\common\exception\BaseException;
use app\common\library\wechat\Qrcode; use app\common\library\wechat\Qrcode;
use app\common\model\Wxapp as WxappModel; use app\common\model\Wxapp as WxappModel;
@ -22,25 +23,26 @@ class Base
/** /**
* 保存小程序码到文件 * 保存小程序码到文件
* @param $wxapp_id * @param $wxappId
* @param $scene * @param $scene
* @param null $page * @param null $page
* @return string * @return string
* @throws \app\common\exception\BaseException * @throws \app\common\exception\BaseException
* @throws \think\Exception
* @throws \think\exception\DbException * @throws \think\exception\DbException
*/ */
protected function saveQrcode($wxapp_id, $scene, $page = null) protected function saveQrcode($wxappId, $scene, $page = null)
{ {
// 文件目录 // 文件目录
$dirPath = RUNTIME_PATH . 'image' . '/' . $wxapp_id; $dirPath = RUNTIME_PATH . 'image' . '/' . $wxappId;
!is_dir($dirPath) && mkdir($dirPath, 0755, true); !is_dir($dirPath) && mkdir($dirPath, 0755, true);
// 文件名称 // 文件名称
$fileName = 'qrcode_' . md5($wxapp_id . $scene . $page) . '.png'; $fileName = 'qrcode_' . md5($wxappId . $scene . $page) . '.png';
// 文件路径 // 文件路径
$savePath = "{$dirPath}/{$fileName}"; $savePath = "{$dirPath}/{$fileName}";
if (file_exists($savePath)) return $savePath; if (file_exists($savePath)) return $savePath;
// 小程序配置信息 // 小程序配置信息
$wxConfig = WxappModel::getWxappCache($wxapp_id); $wxConfig = WxappModel::getWxappCache($wxappId);
// 请求api获取小程序码 // 请求api获取小程序码
$Qrcode = new Qrcode($wxConfig['app_id'], $wxConfig['app_secret']); $Qrcode = new Qrcode($wxConfig['app_id'], $wxConfig['app_secret']);
$content = $Qrcode->getQrcode($scene, $page); $content = $Qrcode->getQrcode($scene, $page);
@ -51,14 +53,15 @@ class Base
/** /**
* 获取网络图片到临时目录 * 获取网络图片到临时目录
* @param $wxapp_id * @param $wxappId
* @param $url * @param $url
* @param string $mark * @param string $mark
* @return string * @return string
* @throws BaseException
*/ */
protected function saveTempImage($wxapp_id, $url, $mark = 'temp') protected function saveTempImage($wxappId, $url, $mark = 'temp')
{ {
$dirPath = RUNTIME_PATH . 'image' . '/' . $wxapp_id; $dirPath = RUNTIME_PATH . 'image' . '/' . $wxappId;
!is_dir($dirPath) && mkdir($dirPath, 0755, true); !is_dir($dirPath) && mkdir($dirPath, 0755, true);
$savePath = $dirPath . '/' . $mark . '_' . md5($url) . '.png'; $savePath = $dirPath . '/' . $mark . '_' . md5($url) . '.png';
if (file_exists($savePath)) return $savePath; if (file_exists($savePath)) return $savePath;
@ -67,6 +70,9 @@ class Base
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_BINARYTRANSFER, 1); curl_setopt($ch, CURLOPT_BINARYTRANSFER, 1);
$img = curl_exec($ch); $img = curl_exec($ch);
if ($img === false) {
$this->throwError('CURL错误' . curl_error($ch));
}
curl_close($ch); curl_close($ch);
$fp = fopen($savePath, 'w'); $fp = fopen($savePath, 'w');
fwrite($fp, $img); fwrite($fp, $img);
@ -74,4 +80,14 @@ class Base
return $savePath; return $savePath;
} }
/**
* 返回错误信息
* @param $msg
* @throws BaseException
*/
private function throwError($msg)
{
throw new BaseException(['msg' => $msg]);
}
} }

View File

@ -44,7 +44,7 @@ class Setting extends Controller
} }
/** /**
* 模板消息 * 发送订阅消息
* @return mixed * @return mixed
* @throws \think\exception\DbException * @throws \think\exception\DbException
*/ */

View File

@ -29,10 +29,8 @@ class Apply extends Controller
/** /**
* 分销商审核 * 分销商审核
* @param $apply_id * @param $apply_id
* @return array * @return array|bool
* @throws \app\common\exception\BaseException
* @throws \think\exception\DbException * @throws \think\exception\DbException
* @throws \think\exception\PDOException
*/ */
public function submit($apply_id) public function submit($apply_id)
{ {

View File

@ -33,7 +33,6 @@ class Withdraw extends Controller
* 提现审核 * 提现审核
* @param $id * @param $id
* @return array * @return array
* @throws \app\common\exception\BaseException
* @throws \think\exception\DbException * @throws \think\exception\DbException
*/ */
public function submit($id) public function submit($id)
@ -53,6 +52,7 @@ class Withdraw extends Controller
*/ */
public function money($id) public function money($id)
{ {
// 提现记录详情
$model = WithdrawModel::detail($id); $model = WithdrawModel::detail($id);
if ($model->money()) { if ($model->money()) {
return $this->renderSuccess('操作成功'); return $this->renderSuccess('操作成功');
@ -65,11 +65,17 @@ class Withdraw extends Controller
* @param $id * @param $id
* @return array|bool * @return array|bool
* @throws \app\common\exception\BaseException * @throws \app\common\exception\BaseException
* @throws \think\Exception
* @throws \think\exception\DbException * @throws \think\exception\DbException
*/ */
public function wechat_pay($id) public function wechat_pay($id)
{ {
$model = WithdrawModel::detail($id); $model = WithdrawModel::detail($id);
// 验证已冻结佣金是否合法
if (!$model->verifyUserFreezeMoney($model['user_id'], $model['money'])) {
return $this->renderError($model->getError());
}
// 合法 -> 确认打款
if ($model->wechatPay()) { if ($model->wechatPay()) {
return $this->renderSuccess('操作成功'); return $this->renderSuccess('操作成功');
} }

View File

@ -0,0 +1,60 @@
<?php
namespace app\store\controller\apps\live;
use app\store\controller\Controller;
use app\store\model\wxapp\LiveRoom as LiveRoomModel;
/**
* 小程序直播间管理
* Class Room
* @package app\store\controller\apps\live
*/
class Room extends Controller
{
/**
* 直播间列表页
* @param string $search 检索词
* @return mixed
* @throws \think\exception\DbException
*/
public function index($search = '')
{
$model = new LiveRoomModel;
$list = $model->getList($search);
return $this->fetch('index', compact('list'));
}
/**
* 同步刷新直播间列表
* @return array|bool
* @throws \app\common\exception\BaseException
* @throws \think\exception\DbException
*/
public function refresh()
{
$model = new LiveRoomModel;
if ($model->refreshLiveList()) {
return $this->renderSuccess('同步成功');
}
return $this->renderError($model->getError() ?: '同步失败');
}
/**
* 修改直播间置顶状态
* @param int $id
* @param int $is_top
* @return array|bool
* @throws \think\exception\DbException
*/
public function settop($id, $is_top)
{
// 直播间详情
$model = LiveRoomModel::detail($id);
if (!$model->setIsTop($is_top)) {
return $this->renderError('操作失败');
}
return $this->renderSuccess('操作成功');
}
}

View File

@ -3,7 +3,7 @@
namespace app\store\controller\market; namespace app\store\controller\market;
use app\store\controller\Controller; use app\store\controller\Controller;
use app\store\model\Goods; use app\store\model\Goods as GoodsModel;
use app\store\model\Region as RegionModel; use app\store\model\Region as RegionModel;
use app\store\model\Setting as SettingModel; use app\store\model\Setting as SettingModel;
@ -22,10 +22,16 @@ class Basic extends Controller
public function full_free() public function full_free()
{ {
if (!$this->request->isAjax()) { if (!$this->request->isAjax()) {
// 满额包邮设置
$values = SettingModel::getItem('full_free'); $values = SettingModel::getItem('full_free');
return $this->fetch('full_free', [ return $this->fetch('full_free', [
'goodsList' => (new Goods)->getListByIds($values['notin_goods']), // 不参与包邮的商品列表
'regionData' => RegionModel::getCacheTree(), // 所有地区 'goodsList' => (new GoodsModel)->getListByIds($values['notin_goods']),
// 获取所有地区(树状结构)
'regionData' => RegionModel::getCacheTree(),
// 地区总数
'cityCount' => RegionModel::getCacheCounts()['city'],
// 满额包邮设置
'values' => $values 'values' => $values
]); ]);
} }

View File

@ -3,6 +3,7 @@
namespace app\store\controller\market; namespace app\store\controller\market;
use app\store\controller\Controller; use app\store\controller\Controller;
use app\store\model\Goods as GoodsModel;
use app\store\model\Coupon as CouponModel; use app\store\model\Coupon as CouponModel;
use app\store\model\UserCoupon as UserCouponModel; use app\store\model\UserCoupon as UserCouponModel;
@ -67,7 +68,14 @@ class Coupon extends Controller
// 优惠券详情 // 优惠券详情
$model = CouponModel::detail($coupon_id); $model = CouponModel::detail($coupon_id);
if (!$this->request->isAjax()) { if (!$this->request->isAjax()) {
return $this->fetch('edit', compact('model')); // 适用范围商品列表
$goodsModel = new GoodsModel;
// 指定的商品列表
$applyGoodsList = $goodsModel->getListByIds($model['apply_range_config']['applyGoodsIds']);
// 指定的商品列表
$excludedGoodsList = $goodsModel->getListByIds($model['apply_range_config']['excludedGoodsIds']);
// 加载模板输出
return $this->fetch('edit', compact('model', 'applyGoodsList', 'excludedGoodsList'));
} }
// 更新记录 // 更新记录
if ($model->edit($this->postData('coupon'))) { if ($model->edit($this->postData('coupon'))) {

View File

@ -7,7 +7,7 @@ use app\store\model\wxapp\Formid as FormidModel;
use app\store\service\wxapp\Message as MessageService; use app\store\service\wxapp\Message as MessageService;
/** /**
* 消息推送 * 消息推送 (废弃)
* Class Push * Class Push
* @package app\store\controller\market * @package app\store\controller\market
*/ */
@ -17,6 +17,7 @@ class Push extends Controller
* 发送消息 * 发送消息
* @return array|mixed * @return array|mixed
* @throws \app\common\exception\BaseException * @throws \app\common\exception\BaseException
* @throws \think\Exception
* @throws \think\exception\DbException * @throws \think\exception\DbException
*/ */
public function send() public function send()

View File

@ -0,0 +1,50 @@
<?php
namespace app\store\controller\wxapp;
use app\store\controller\Controller;
use app\store\model\Setting as SettingModel;
use app\store\service\wxapp\SubMsg as SubMsgService;
/**
* 小程序订阅消息设置
* Class Submsg
* @package app\store\controller\wxapp
*/
class Submsg extends Controller
{
/**
* 小程序订阅消息设置
* @return array|bool|mixed
* @throws \think\exception\DbException
*/
public function index()
{
if (!$this->request->isAjax()) {
$values = SettingModel::getItem('submsg');
return $this->fetch('index', compact('values'));
}
$model = new SettingModel;
if ($model->edit('submsg', $this->postData('submsg'))) {
return $this->renderSuccess('操作成功');
}
return $this->renderError($model->getError() ?: '操作失败');
}
/**
* 一键添加订阅消息
* @return array
* @throws \app\common\exception\BaseException
* @throws \think\Exception
* @throws \think\exception\DbException
*/
public function shuttle()
{
$SubMsgService = new SubMsgService;
if ($SubMsgService->shuttle()) {
return $this->renderSuccess('操作成功');
}
return $this->renderError($SubMsgService->getError() ?: '操作失败');
}
}

View File

@ -360,6 +360,13 @@ return [
] ]
] ]
], ],
[
'name' => '订阅消息',
'index' => 'wxapp.submsg/index',
'uris' => [
'wxapp.submsg/index',
]
],
[ [
'name' => '帮助中心', 'name' => '帮助中心',
'index' => 'wxapp.help/index', 'index' => 'wxapp.help/index',
@ -544,7 +551,7 @@ return [
], ],
[ [
'name' => '好物圈', 'name' => '好物圈',
'index' => 'apps.wow.order/index', 'index' => 'apps.wow.shoping/index',
'submenu' => [ 'submenu' => [
[ [
'name' => '商品收藏', 'name' => '商品收藏',
@ -560,6 +567,16 @@ return [
] ]
] ]
], ],
[
'name' => '小程序直播',
'index' => 'apps.live.room/index',
'submenu' => [
[
'name' => '直播间管理',
'index' => 'apps.live.room/index',
],
]
],
] ]
], ],
'setting' => [ 'setting' => [
@ -597,15 +614,15 @@ return [
'name' => '短信通知', 'name' => '短信通知',
'index' => 'setting/sms' 'index' => 'setting/sms'
], ],
[ // [
'name' => '模板消息', // 'name' => '模板消息',
'index' => 'setting/tplmsg', // 'index' => 'setting/tplmsg',
'uris' => [ // 'uris' => [
'setting/tplmsg', // 'setting/tplmsg',
'setting.help/tplmsg' // 'setting.help/tplmsg'
//
], // ],
], // ],
[ [
'name' => '退货地址', 'name' => '退货地址',
'index' => 'setting.address/index', 'index' => 'setting.address/index',

View File

@ -37,6 +37,7 @@ class Coupon extends CouponModel
$data['start_time'] = strtotime($data['start_time']); $data['start_time'] = strtotime($data['start_time']);
$data['end_time'] = strtotime($data['end_time']); $data['end_time'] = strtotime($data['end_time']);
} }
$data['apply_range_config'] = isset($data['apply_range_config']) ? $data['apply_range_config'] : [];
return $this->allowField(true)->save($data); return $this->allowField(true)->save($data);
} }

View File

@ -11,45 +11,5 @@ use app\common\model\DeliveryRule as DeliveryRuleModel;
*/ */
class DeliveryRule extends DeliveryRuleModel class DeliveryRule extends DeliveryRuleModel
{ {
protected $append = ['region_content'];
static $regionAll;
static $regionTree;
/**
* 可配送区域
* @param $value
* @param $data
* @return string
*/
public function getRegionContentAttr($value, $data)
{
// 当前区域记录转换为数组
$regionIds = explode(',', $data['region']);
if (count($regionIds) === 373) return '全国';
// 所有地区
if (empty(self::$regionAll)) {
self::$regionAll = Region::getCacheAll();
self::$regionTree = Region::getCacheTree();
}
// 将当前可配送区域格式化为树状结构
$alreadyTree = [];
foreach ($regionIds as $regionId)
$alreadyTree[self::$regionAll[$regionId]['pid']][] = $regionId;
$str = '';
foreach ($alreadyTree as $provinceId => $citys) {
$str .= self::$regionTree[$provinceId]['name'];
if (count($citys) !== count(self::$regionTree[$provinceId]['city'])) {
$cityStr = '';
foreach ($citys as $cityId)
$cityStr .= self::$regionTree[$provinceId]['city'][$cityId]['name'];
$str .= ' (<span class="am-link-muted">' . mb_substr($cityStr, 0, -1, 'utf-8') . '</span>)';
}
$str .= '、';
}
return mb_substr($str, 0, -1, 'utf-8');
}
} }

View File

@ -249,19 +249,17 @@ class Order extends OrderModel
/** /**
* 确认发货后发送消息通知 * 确认发货后发送消息通知
* @param array|\think\Collection $orderList * @param $orderList
* @return bool * @return bool
* @throws \app\common\exception\BaseException
* @throws \think\Exception
* @throws \think\exception\DbException
*/ */
private function sendDeliveryMessage($orderList) private function sendDeliveryMessage($orderList)
{ {
// 实例化消息通知服务类
$Service = new MessageService;
foreach ($orderList as $item) {
// 发送消息通知 // 发送消息通知
$Service->delivery($item, OrderTypeEnum::MASTER); foreach ($orderList as $item) {
MessageService::send('order.delivery', [
'order' => $item,
'order_type' => OrderTypeEnum::MASTER,
]);
} }
return true; return true;
} }

View File

@ -59,7 +59,6 @@ class OrderRefund extends OrderRefundModel
* 商家审核 * 商家审核
* @param $data * @param $data
* @return bool * @return bool
* @throws \think\exception\PDOException
*/ */
public function audit($data) public function audit($data)
{ {
@ -71,8 +70,7 @@ class OrderRefund extends OrderRefundModel
$this->error = '请选择退货地址'; $this->error = '请选择退货地址';
return false; return false;
} }
$this->startTrans(); $this->transaction(function () use ($data) {
try {
// 拒绝申请, 标记售后单状态为已拒绝 // 拒绝申请, 标记售后单状态为已拒绝
$data['is_agree'] == 20 && $data['status'] = 10; $data['is_agree'] == 20 && $data['status'] = 10;
// 同意换货申请, 标记售后单状态为已完成 // 同意换货申请, 标记售后单状态为已完成
@ -81,21 +79,18 @@ class OrderRefund extends OrderRefundModel
$this->allowField(true)->save($data); $this->allowField(true)->save($data);
// 同意售后申请, 记录退货地址 // 同意售后申请, 记录退货地址
if ($data['is_agree'] == 10) { if ($data['is_agree'] == 10) {
$model = new OrderRefundAddress; (new OrderRefundAddress)->add($this['order_refund_id'], $data['address_id']);
$model->add($this['order_refund_id'], $data['address_id']);
} }
// 订单详情 // 订单详情
$order = Order::detail($this['order_id']); $order = Order::detail($this['order_id']);
// 发送模板消息 // 发送消息通知
(new MessageService)->refund(self::detail($this['order_refund_id']), $order['order_no'], OrderTypeEnum::MASTER); MessageService::send('order.refund', [
// 事务提交 'refund' => $this, // 退款单信息
$this->commit(); 'order_no' => $order['order_no'], // 订单信息
'order_type' => OrderTypeEnum::MASTER, // 订单类型
]);
});
return true; return true;
} catch (\Exception $e) {
$this->error = $e->getMessage();
$this->rollback();
return false;
}
} }
/** /**
@ -126,8 +121,12 @@ class OrderRefund extends OrderRefundModel
} }
// 执行原路退款 // 执行原路退款
(new RefundService)->execute($order, $data['refund_money']); (new RefundService)->execute($order, $data['refund_money']);
// 发送模板消息 // 发送消息通知
(new MessageService)->refund(self::detail($this['order_refund_id']), $order['order_no'], OrderTypeEnum::MASTER); MessageService::send('order.refund', [
'refund' => $this, // 退款单信息
'order_no' => $order['order_no'], // 订单信息
'order_type' => OrderTypeEnum::MASTER, // 订单类型
]);
}); });
return true; return true;
} }

View File

@ -18,7 +18,7 @@ class ReturnAddress extends ReturnAddressModel
*/ */
public function getList() public function getList()
{ {
return $this->order(['sort' => 'asc']) return $this->order(['sort' => 'asc', $this->getPk() => 'desc'])
->where('is_delete', '=', 0) ->where('is_delete', '=', 0)
->paginate(15, false, [ ->paginate(15, false, [
'query' => \request()->request() 'query' => \request()->request()
@ -34,7 +34,7 @@ class ReturnAddress extends ReturnAddressModel
*/ */
public function getAll() public function getAll()
{ {
return $this->order(['sort' => 'asc']) return $this->order(['sort' => 'asc', $this->getPk() => 'desc'])
->where('is_delete', '=', 0) ->where('is_delete', '=', 0)
->select(); ->select();
} }

View File

@ -2,8 +2,8 @@
namespace app\store\model; namespace app\store\model;
use app\common\model\Wxapp as WxappModel;
use think\Cache; use think\Cache;
use app\common\model\Wxapp as WxappModel;
/** /**
* 微信小程序模型 * 微信小程序模型
@ -65,40 +65,6 @@ class Wxapp extends WxappModel
return true; return true;
} }
/**
* 记录图片信息
* @param $wxapp_id
* @param $oldFileId
* @param $newFileName
* @param $fromType
* @return int|mixed
*/
private function uploadImage($wxapp_id, $oldFileId, $newFileName, $fromType)
{
// $UploadFile = new UploadFile;
$UploadFileUsed = new UploadFileUsed;
if ($oldFileId > 0) {
// 获取原图片path
$oldFileName = UploadFile::getFileName($oldFileId);
// 新文件与原来路径一致, 代表用户未修改, 不做更新
if ($newFileName === $oldFileName)
return $oldFileId;
// 删除原文件使用记录
$UploadFileUsed->remove('service', $oldFileId);
}
// 删除图片
if (empty($newFileName)) return 0;
// 查询新文件file_id
$fileId = UploadFile::getFildIdByName($newFileName);
// 添加文件使用记录
$UploadFileUsed->add([
'file_id' => $fileId,
'wxapp_id' => $wxapp_id,
'from_type' => $fromType
]);
return $fileId;
}
/** /**
* 删除wxapp缓存 * 删除wxapp缓存
* @return bool * @return bool

View File

@ -3,7 +3,8 @@
namespace app\store\model\dealer; namespace app\store\model\dealer;
use app\common\model\dealer\Apply as ApplyModel; use app\common\model\dealer\Apply as ApplyModel;
use app\common\service\Message; use app\common\service\Message as MessageService;
use app\common\enum\dealer\ApplyStatus as ApplyStatusEnum;
/** /**
* 分销商入驻申请模型 * 分销商入驻申请模型
@ -38,18 +39,15 @@ class Apply extends ApplyModel
* 分销商入驻审核 * 分销商入驻审核
* @param $data * @param $data
* @return bool * @return bool
* @throws \app\common\exception\BaseException
* @throws \think\exception\DbException
* @throws \think\exception\PDOException
*/ */
public function submit($data) public function submit($data)
{ {
if ($data['apply_status'] == '30' && empty($data['reject_reason'])) { if ($data['apply_status'] == ApplyStatusEnum::AUDIT_REJECT && empty($data['reject_reason'])) {
$this->error = '请填写驳回原因'; $this->error = '请填写驳回原因';
return false; return false;
} }
$this->startTrans(); $this->transaction(function () use ($data) {
if ($data['apply_status'] == '20') { if ($data['apply_status'] == ApplyStatusEnum::AUDIT_PASS) {
// 新增分销商用户 // 新增分销商用户
User::add($this['user_id'], [ User::add($this['user_id'], [
'real_name' => $this['real_name'], 'real_name' => $this['real_name'],
@ -60,9 +58,12 @@ class Apply extends ApplyModel
// 更新申请记录 // 更新申请记录
$data['audit_time'] = time(); $data['audit_time'] = time();
$this->allowField(true)->save($data); $this->allowField(true)->save($data);
// 发送模板消息 // 发送订阅消息
(new Message)->dealer($this); MessageService::send('dealer.apply', [
$this->commit(); 'apply' => $this, // 申请记录
'user' => $this['user'], // 用户信息
]);
});
return true; return true;
} }

View File

@ -25,7 +25,6 @@ class Setting extends SettingModel
'words' => '自定义文字', 'words' => '自定义文字',
'license' => '申请协议', 'license' => '申请协议',
'background' => '页面背景图', 'background' => '页面背景图',
'template_msg' => '模板消息',
'qrcode' => '分销海报', 'qrcode' => '分销海报',
]; ];

View File

@ -2,11 +2,15 @@
namespace app\store\model\dealer; namespace app\store\model\dealer;
use app\common\service\Message; use app\store\model\User as UserModel;
use app\common\service\Order as OrderService;
use app\common\library\wechat\WxPay;
use app\store\model\Wxapp as WxappModel; use app\store\model\Wxapp as WxappModel;
use app\common\model\dealer\User as dealerUserModel;
use app\common\model\dealer\Withdraw as WithdrawModel; use app\common\model\dealer\Withdraw as WithdrawModel;
use app\common\service\Order as OrderService;
use app\common\service\Message as MessageService;
use app\common\enum\dealer\withdraw\PayType as PayTypeEnum;
use app\common\enum\dealer\withdraw\ApplyStatus as ApplyStatusEnum;
use app\common\library\wechat\WxPay;
/** /**
* 分销商提现明细模型 * 分销商提现明细模型
@ -32,19 +36,19 @@ class Withdraw extends WithdrawModel
*/ */
public function getPayTypeAttr($value) public function getPayTypeAttr($value)
{ {
return ['text' => $this->payType[$value], 'value' => $value]; return ['text' => PayTypeEnum::data()[$value]['name'], 'value' => $value];
} }
/** /**
* 获取分销商提现列表 * 获取分销商提现列表
* @param null $user_id * @param null $userId
* @param int $apply_status * @param int $apply_status
* @param int $pay_type * @param int $pay_type
* @param string $search * @param string $search
* @return \think\Paginator * @return \think\Paginator
* @throws \think\exception\DbException * @throws \think\exception\DbException
*/ */
public function getList($user_id = null, $apply_status = -1, $pay_type = -1, $search = '') public function getList($userId = null, $apply_status = -1, $pay_type = -1, $search = '')
{ {
// 构建查询规则 // 构建查询规则
$this->alias('withdraw') $this->alias('withdraw')
@ -54,7 +58,7 @@ class Withdraw extends WithdrawModel
->join('dealer_user dealer', 'dealer.user_id = withdraw.user_id') ->join('dealer_user dealer', 'dealer.user_id = withdraw.user_id')
->order(['withdraw.create_time' => 'desc']); ->order(['withdraw.create_time' => 'desc']);
// 查询条件 // 查询条件
$user_id > 0 && $this->where('withdraw.user_id', '=', $user_id); $userId > 0 && $this->where('withdraw.user_id', '=', $userId);
!empty($search) && $this->where('dealer.real_name|dealer.mobile', 'like', "%$search%"); !empty($search) && $this->where('dealer.real_name|dealer.mobile', 'like', "%$search%");
$apply_status > 0 && $this->where('withdraw.apply_status', '=', $apply_status); $apply_status > 0 && $this->where('withdraw.apply_status', '=', $apply_status);
$pay_type > 0 && $this->where('withdraw.pay_type', '=', $pay_type); $pay_type > 0 && $this->where('withdraw.pay_type', '=', $pay_type);
@ -68,34 +72,46 @@ class Withdraw extends WithdrawModel
* 分销商提现审核 * 分销商提现审核
* @param $data * @param $data
* @return bool * @return bool
* @throws \app\common\exception\BaseException
* @throws \think\exception\DbException
*/ */
public function submit($data) public function submit($data)
{ {
if ($data['apply_status'] == '30' && empty($data['reject_reason'])) { if (
$data['apply_status'] == ApplyStatusEnum::AUDIT_REJECT
&& empty($data['reject_reason'])
) {
$this->error = '请填写驳回原因'; $this->error = '请填写驳回原因';
return false; return false;
} }
$this->transaction(function () use ($data) {
// 更新申请记录 // 更新申请记录
$data['audit_time'] = time(); $data['audit_time'] = time();
$this->allowField(true)->save($data); $this->allowField(true)->save($data);
// 提现驳回:解冻分销商资金 // 提现驳回:解冻分销商资金
$data['apply_status'] == '30' && User::backFreezeMoney($this['user_id'], $this['money']); if ($data['apply_status'] == ApplyStatusEnum::AUDIT_REJECT) {
// 发送模板消息 User::backFreezeMoney($this['user_id'], $this['money']);
(new Message)->withdraw($this); }
// 发送消息通知
MessageService::send('dealer.withdraw', [
'withdraw' => $this,
'user' => UserModel::detail($this['user_id']),
]);
});
return true; return true;
} }
/** /**
* 确认已打款 * 确认已打款
* @return bool * @param bool $verifyUserFreezeMoney 验证已冻结佣金是否合法
* @throws \think\exception\PDOException * @return bool|mixed
* @throws \think\exception\DbException
*/ */
public function money() public function money($verifyUserFreezeMoney = true)
{ {
$this->startTrans(); // 验证已冻结佣金是否合法
try { if ($verifyUserFreezeMoney && !$this->verifyUserFreezeMoney($this['user_id'], $this['money'])) {
return false;
}
return $this->transaction(function () {
// 更新申请状态 // 更新申请状态
$this->allowField(true)->save([ $this->allowField(true)->save([
'apply_status' => 40, 'apply_status' => 40,
@ -110,27 +126,23 @@ class Withdraw extends WithdrawModel
'money' => -$this['money'], 'money' => -$this['money'],
'describe' => '申请提现', 'describe' => '申请提现',
]); ]);
// 发送模板消息
(new Message)->withdraw($this);
// 事务提交
$this->commit();
return true; return true;
} catch (\Exception $e) { });
$this->error = $e->getMessage();
$this->rollback();
return false;
}
} }
/** /**
* 分销商提现:微信支付企业付款 * 分销商提现:微信支付企业付款
* @return bool * @return bool
* @throws \app\common\exception\BaseException * @throws \app\common\exception\BaseException
* @throws \think\Exception
* @throws \think\exception\DbException * @throws \think\exception\DbException
* @throws \think\exception\PDOException
*/ */
public function wechatPay() public function wechatPay()
{ {
// 验证已冻结佣金是否合法
if (!$this->verifyUserFreezeMoney($this['user_id'], $this['money'])) {
return false;
}
// 微信用户信息 // 微信用户信息
$user = $this['user']['user']; $user = $this['user']['user'];
// 生成付款订单号 // 生成付款订单号
@ -143,10 +155,27 @@ class Withdraw extends WithdrawModel
// 请求付款api // 请求付款api
if ($WxPay->transfers($orderNO, $user['open_id'], $this['money'], $desc)) { if ($WxPay->transfers($orderNO, $user['open_id'], $this['money'], $desc)) {
// 确认已打款 // 确认已打款
$this->money(); $this->money(false);
return true; return true;
} }
return false; return false;
} }
/**
* 验证已冻结佣金是否合法
* @param $userId
* @param $money
* @return bool
* @throws \think\exception\DbException
*/
public function verifyUserFreezeMoney($userId, $money)
{
$dealerUserInfo = dealerUserModel::detail($userId);
if ($dealerUserInfo['freeze_money'] < $money) {
$this->error = '数据错误:已冻结的佣金不能小于提现的金额';
return false;
}
return true;
}
} }

View File

@ -183,7 +183,6 @@ class Order extends OrderModel
* 确认发货(单独订单) * 确认发货(单独订单)
* @param $data * @param $data
* @return array|bool|false * @return array|bool|false
* @throws \app\common\exception\BaseException
* @throws \think\Exception * @throws \think\Exception
* @throws \think\exception\DbException * @throws \think\exception\DbException
* @throws \Exception * @throws \Exception
@ -262,19 +261,17 @@ class Order extends OrderModel
/** /**
* 确认发货后发送消息通知 * 确认发货后发送消息通知
* @param array|\think\Collection $orderList * @param $orderList
* @return bool * @return bool
* @throws \app\common\exception\BaseException
* @throws \think\Exception
* @throws \think\exception\DbException
*/ */
private function sendDeliveryMessage($orderList) private function sendDeliveryMessage($orderList)
{ {
// 实例化消息通知服务类
$Service = new MessageService;
foreach ($orderList as $item) {
// 发送消息通知 // 发送消息通知
$Service->delivery($item, OrderTypeEnum::SHARING); foreach ($orderList as $item) {
MessageService::send('order.delivery', [
'order' => $item,
'order_type' => OrderTypeEnum::SHARING,
]);
} }
return true; return true;
} }

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