v1.1.45
This commit is contained in:
parent
68bc138f6a
commit
45423fa76c
@ -10,6 +10,15 @@
|
|||||||
|
|
||||||
## 更新日志
|
## 更新日志
|
||||||
|
|
||||||
|
### v1.1.45
|
||||||
|
|
||||||
|
新增:优惠券支持指定商品
|
||||||
|
新增:小程序端底部购物车数量(角标)
|
||||||
|
优化:微信退款API记录日志
|
||||||
|
优化:整点秒杀页面倒计时结束刷新
|
||||||
|
修复:后台满额包邮地区总数错误
|
||||||
|
修复:后台分销商确认打款时报错
|
||||||
|
|
||||||
### v1.1.44
|
### v1.1.44
|
||||||
|
|
||||||
```
|
```
|
||||||
|
@ -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',
|
||||||
|
17
doc/database/upgrade/v1.1.45.sql
Normal file
17
doc/database/upgrade/v1.1.45.sql
Normal 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`;
|
||||||
|
|
26
doc/更新日志.txt
26
doc/更新日志.txt
@ -1,4 +1,30 @@
|
|||||||
|
|
||||||
|
### v1.1.45 更新日志 ###
|
||||||
|
|
||||||
|
新增:优惠券支持指定商品
|
||||||
|
新增:小程序端底部购物车数量(角标)
|
||||||
|
优化:微信退款API记录日志
|
||||||
|
优化:整点秒杀页面倒计时结束刷新
|
||||||
|
修复:后台满额包邮地区总数错误
|
||||||
|
修复:后台分销商确认打款时报错
|
||||||
|
--------------------------------
|
||||||
|
注:本次更新须重新发布小程序
|
||||||
|
|
||||||
|
|
||||||
|
### v1.1.44 更新日志 ###
|
||||||
|
|
||||||
|
新增:小程序转发到朋友圈(灰度安卓用户)
|
||||||
|
优化:微信打款时验证冻结资金是否合法
|
||||||
|
优化:mysql报错时记录Error SQL
|
||||||
|
修复:后台权限缺少文件列表和回收站
|
||||||
|
修复:地区表中部分地区不存在
|
||||||
|
修复:获取直播房间列表接口报错
|
||||||
|
修复:后台订单详情页报错
|
||||||
|
修复:小程序端富文本视频高度不生效
|
||||||
|
--------------------------------
|
||||||
|
注:本次更新须重新发布小程序
|
||||||
|
|
||||||
|
|
||||||
### v1.1.43 更新日志 ###
|
### v1.1.43 更新日志 ###
|
||||||
|
|
||||||
优化:mysql5.7环境数据排序问题
|
优化:mysql5.7环境数据排序问题
|
||||||
|
@ -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], '加入购物车成功');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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,
|
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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());
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -367,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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -529,19 +535,12 @@ 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;
|
||||||
@ -556,6 +555,40 @@ class Checkout
|
|||||||
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
|
||||||
|
@ -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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -191,6 +191,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']]);
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -54,9 +54,7 @@ class Withdraw extends Controller
|
|||||||
{
|
{
|
||||||
// 提现记录详情
|
// 提现记录详情
|
||||||
$model = WithdrawModel::detail($id);
|
$model = WithdrawModel::detail($id);
|
||||||
// 验证已冻结佣金是否合法
|
if ($model->money()) {
|
||||||
// 合法 -> 确认打款
|
|
||||||
if (!$model->verifyUserFreezeMoney($model['user_id'], $model['money']) && $model->money()) {
|
|
||||||
return $this->renderSuccess('操作成功');
|
return $this->renderSuccess('操作成功');
|
||||||
}
|
}
|
||||||
return $this->renderError($model->getError() ?: '操作失败');
|
return $this->renderError($model->getError() ?: '操作失败');
|
||||||
@ -73,6 +71,11 @@ class Withdraw extends Controller
|
|||||||
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('操作成功');
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
@ -36,4 +42,4 @@ class Basic extends Controller
|
|||||||
return $this->renderError($model->getError() ?: '操作失败');
|
return $this->renderError($model->getError() ?: '操作失败');
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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'))) {
|
||||||
|
@ -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');
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -63,7 +63,7 @@
|
|||||||
</a>
|
</a>
|
||||||
<div class="help-block">
|
<div class="help-block">
|
||||||
<small class="x-color-555">
|
<small class="x-color-555">
|
||||||
<span v-if="checked.citys.length == 373">全国</span>
|
<span v-if="checked.citys.length == <?= $cityCount ?>">全国</span>
|
||||||
<template v-else v-for="(province, index) in checked.treeData">
|
<template v-else v-for="(province, index) in checked.treeData">
|
||||||
<span>{{ province.name }}</span>
|
<span>{{ province.name }}</span>
|
||||||
<template v-if="!province.isAllCitys">
|
<template v-if="!province.isAllCitys">
|
||||||
|
@ -79,7 +79,61 @@
|
|||||||
value="" placeholder="请输入最低消费金额" required>
|
value="" placeholder="请输入最低消费金额" required>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="am-form-group" data-x-switch>
|
|
||||||
|
<div class="am-form-group am-padding-top" data-x-switch>
|
||||||
|
<label class="am-u-sm-3 am-u-lg-2 am-form-label form-require">适用范围 </label>
|
||||||
|
<div class="am-u-sm-9 am-u-end">
|
||||||
|
<label class="am-radio-inline">
|
||||||
|
<input type="radio" name="coupon[apply_range]" value="10"
|
||||||
|
data-am-ucheck
|
||||||
|
data-switch-box="switch-apply_range"
|
||||||
|
data-switch-item="apply_range__10" checked>
|
||||||
|
全部商品
|
||||||
|
</label>
|
||||||
|
<label class="am-radio-inline">
|
||||||
|
<input type="radio" name="coupon[apply_range]" value="20"
|
||||||
|
data-am-ucheck
|
||||||
|
data-switch-box="switch-apply_range"
|
||||||
|
data-switch-item="apply_range__20">
|
||||||
|
指定商品
|
||||||
|
</label>
|
||||||
|
<label class="am-radio-inline">
|
||||||
|
<input type="radio" name="coupon[apply_range]" value="30"
|
||||||
|
data-am-ucheck
|
||||||
|
data-switch-box="switch-apply_range"
|
||||||
|
data-switch-item="apply_range__30">
|
||||||
|
排除商品
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="am-form-group switch-apply_range apply_range__20 hide">
|
||||||
|
<label class="am-u-sm-3 am-u-lg-2 am-form-label"> </label>
|
||||||
|
<div class="am-u-sm-9 am-u-end">
|
||||||
|
<div class="widget-become-goods am-form-file am-margin-top-xs">
|
||||||
|
<button type="button" @click.stop="onSelectGoods"
|
||||||
|
class="j-selectGoods upload-file am-btn am-btn-secondary am-radius">
|
||||||
|
<i class="am-icon-cloud-upload"></i> 选择商品
|
||||||
|
</button>
|
||||||
|
<div class="widget-goods-list uploader-list am-cf">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="am-form-group switch-apply_range apply_range__30 hide">
|
||||||
|
<label class="am-u-sm-3 am-u-lg-2 am-form-label"> </label>
|
||||||
|
<div class="am-u-sm-9 am-u-end">
|
||||||
|
<div class="widget-become-goods am-form-file am-margin-top-xs">
|
||||||
|
<button type="button" @click.stop="onSelectGoods"
|
||||||
|
class="j-selectGoods2 upload-file am-btn am-btn-secondary am-radius">
|
||||||
|
<i class="am-icon-cloud-upload"></i> 选择商品
|
||||||
|
</button>
|
||||||
|
<div class="widget-goods-list2 uploader-list am-cf">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="am-form-group am-padding-top" data-x-switch>
|
||||||
<label class="am-u-sm-3 am-u-lg-2 am-form-label form-require">到期类型 </label>
|
<label class="am-u-sm-3 am-u-lg-2 am-form-label form-require">到期类型 </label>
|
||||||
<div class="am-u-sm-9 am-u-end">
|
<div class="am-u-sm-9 am-u-end">
|
||||||
<label class="am-radio-inline">
|
<label class="am-radio-inline">
|
||||||
@ -142,6 +196,38 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- 文件库弹窗 -->
|
||||||
|
{{include file="layouts/_template/file_library" /}}
|
||||||
|
|
||||||
|
<!-- 指定的 商品列表 -->
|
||||||
|
<script id="tpl-goods-list-item" type="text/template">
|
||||||
|
{{ each $data }}
|
||||||
|
<div class="file-item">
|
||||||
|
<a href="{{ $value.image }}" title="{{ $value.goods_name }}" target="_blank">
|
||||||
|
<img src="{{ $value.image }}">
|
||||||
|
</a>
|
||||||
|
<input type="hidden" name="coupon[apply_range_config][applyGoodsIds][]" value="{{ $value.goods_id }}">
|
||||||
|
<i class="iconfont icon-shanchu file-item-delete" data-name="商品"></i>
|
||||||
|
</div>
|
||||||
|
{{ /each }}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<!-- 排除的 商品列表 -->
|
||||||
|
<script id="tpl-goods-list-item2" type="text/template">
|
||||||
|
{{ each $data }}
|
||||||
|
<div class="file-item">
|
||||||
|
<a href="{{ $value.image }}" title="{{ $value.goods_name }}" target="_blank">
|
||||||
|
<img src="{{ $value.image }}">
|
||||||
|
</a>
|
||||||
|
<input type="hidden" name="coupon[apply_range_config][excludedGoodsIds][]" value="{{ $value.goods_id }}">
|
||||||
|
<i class="iconfont icon-shanchu file-item-delete" data-name="商品"></i>
|
||||||
|
</div>
|
||||||
|
{{ /each }}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script src="assets/common/js/vue.min.js?v=<?= $version ?>"></script>
|
||||||
|
<script src="assets/store/js/select.data.js?v=<?= $version ?>"></script>
|
||||||
<script>
|
<script>
|
||||||
/**
|
/**
|
||||||
* 时间选择
|
* 时间选择
|
||||||
@ -216,6 +302,38 @@
|
|||||||
$mySwitchBox.hide().filter('.' + $(this).data('switch-item')).show();
|
$mySwitchBox.hide().filter('.' + $(this).data('switch-item')).show();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 选择商品
|
||||||
|
var $goodsList = $('.widget-goods-list');
|
||||||
|
$('.j-selectGoods').selectData({
|
||||||
|
title: '选择商品',
|
||||||
|
uri: 'goods/lists',
|
||||||
|
dataIndex: 'goods_id',
|
||||||
|
done: function (data) {
|
||||||
|
var $html = $(template('tpl-goods-list-item', data));
|
||||||
|
// 删除文件
|
||||||
|
$html.find('.file-item-delete').on('click', function () {
|
||||||
|
$(this).parent().remove();
|
||||||
|
});
|
||||||
|
$goodsList.append($html);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 选择商品
|
||||||
|
var $goodsList2 = $('.widget-goods-list2');
|
||||||
|
$('.j-selectGoods2').selectData({
|
||||||
|
title: '选择商品',
|
||||||
|
uri: 'goods/lists',
|
||||||
|
dataIndex: 'goods_id',
|
||||||
|
done: function (data) {
|
||||||
|
var $html = $(template('tpl-goods-list-item2', data));
|
||||||
|
// 删除文件
|
||||||
|
$html.find('.file-item-delete').on('click', function () {
|
||||||
|
$(this).parent().remove();
|
||||||
|
});
|
||||||
|
$goodsList2.append($html);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 表单验证提交
|
* 表单验证提交
|
||||||
* @type {*}
|
* @type {*}
|
||||||
|
@ -89,7 +89,89 @@
|
|||||||
value="<?= $model['min_price'] ?>" placeholder="请输入最低消费金额" required>
|
value="<?= $model['min_price'] ?>" placeholder="请输入最低消费金额" required>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="am-form-group" data-x-switch>
|
|
||||||
|
<div class="am-form-group am-padding-top" data-x-switch>
|
||||||
|
<label class="am-u-sm-3 am-u-lg-2 am-form-label form-require">适用范围 </label>
|
||||||
|
<div class="am-u-sm-9 am-u-end">
|
||||||
|
<label class="am-radio-inline">
|
||||||
|
<input type="radio" name="coupon[apply_range]" value="10"
|
||||||
|
data-am-ucheck
|
||||||
|
data-switch-box="switch-apply_range"
|
||||||
|
data-switch-item="apply_range__10"
|
||||||
|
<?= $model['apply_range'] == 10 ? 'checked' : '' ?>>
|
||||||
|
全部商品
|
||||||
|
</label>
|
||||||
|
<label class="am-radio-inline">
|
||||||
|
<input type="radio" name="coupon[apply_range]" value="20"
|
||||||
|
data-am-ucheck
|
||||||
|
data-switch-box="switch-apply_range"
|
||||||
|
data-switch-item="apply_range__20"
|
||||||
|
<?= $model['apply_range'] == 20 ? 'checked' : '' ?>>
|
||||||
|
指定商品
|
||||||
|
</label>
|
||||||
|
<label class="am-radio-inline">
|
||||||
|
<input type="radio" name="coupon[apply_range]" value="30"
|
||||||
|
data-am-ucheck
|
||||||
|
data-switch-box="switch-apply_range"
|
||||||
|
data-switch-item="apply_range__30"
|
||||||
|
<?= $model['apply_range'] == 30 ? 'checked' : '' ?>>
|
||||||
|
排除商品
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="am-form-group switch-apply_range apply_range__20 <?= $model['apply_range'] == 20 ? '' : 'hide' ?>">
|
||||||
|
<label class="am-u-sm-3 am-u-lg-2 am-form-label"> </label>
|
||||||
|
<div class="am-u-sm-9 am-u-end">
|
||||||
|
<div class="widget-become-goods am-form-file am-margin-top-xs">
|
||||||
|
<button type="button" @click.stop="onSelectGoods"
|
||||||
|
class="j-selectGoods upload-file am-btn am-btn-secondary am-radius">
|
||||||
|
<i class="am-icon-cloud-upload"></i> 选择商品
|
||||||
|
</button>
|
||||||
|
<div class="widget-goods-list uploader-list am-cf">
|
||||||
|
<?php if (!$applyGoodsList->isEmpty()): foreach ($applyGoodsList as $goods): ?>
|
||||||
|
<div class="file-item">
|
||||||
|
<a href="<?= $goods['goods_image'] ?>"
|
||||||
|
title="<?= $goods['goods_name'] ?>" target="_blank">
|
||||||
|
<img src="<?= $goods['goods_image'] ?>">
|
||||||
|
</a>
|
||||||
|
<input type="hidden"
|
||||||
|
name="coupon[apply_range_config][applyGoodsIds][]"
|
||||||
|
value="<?= $goods['goods_id'] ?>">
|
||||||
|
<i class="iconfont icon-shanchu file-item-delete"
|
||||||
|
data-name="商品"></i>
|
||||||
|
</div>
|
||||||
|
<?php endforeach; endif; ?>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="am-form-group switch-apply_range apply_range__30 <?= $model['apply_range'] == 30 ? '' : 'hide' ?>">
|
||||||
|
<label class="am-u-sm-3 am-u-lg-2 am-form-label"> </label>
|
||||||
|
<div class="am-u-sm-9 am-u-end">
|
||||||
|
<div class="widget-become-goods am-form-file am-margin-top-xs">
|
||||||
|
<button type="button" @click.stop="onSelectGoods"
|
||||||
|
class="j-selectGoods2 upload-file am-btn am-btn-secondary am-radius">
|
||||||
|
<i class="am-icon-cloud-upload"></i> 选择商品
|
||||||
|
</button>
|
||||||
|
<div class="widget-goods-list2 uploader-list am-cf">
|
||||||
|
<?php if (!$excludedGoodsList->isEmpty()): foreach ($excludedGoodsList as $goods): ?>
|
||||||
|
<div class="file-item">
|
||||||
|
<a href="<?= $goods['goods_image'] ?>"
|
||||||
|
title="<?= $goods['goods_name'] ?>" target="_blank">
|
||||||
|
<img src="<?= $goods['goods_image'] ?>">
|
||||||
|
</a>
|
||||||
|
<input type="hidden"
|
||||||
|
name="coupon[apply_range_config][excludedGoodsIds][]"
|
||||||
|
value="<?= $goods['goods_id'] ?>">
|
||||||
|
<i class="iconfont icon-shanchu file-item-delete"
|
||||||
|
data-name="商品"></i>
|
||||||
|
</div>
|
||||||
|
<?php endforeach; endif; ?>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="am-form-group am-padding-top" data-x-switch>
|
||||||
<label class="am-u-sm-3 am-u-lg-2 am-form-label form-require">到期类型 </label>
|
<label class="am-u-sm-3 am-u-lg-2 am-form-label form-require">到期类型 </label>
|
||||||
<div class="am-u-sm-9 am-u-end">
|
<div class="am-u-sm-9 am-u-end">
|
||||||
<label class="am-radio-inline">
|
<label class="am-radio-inline">
|
||||||
@ -159,6 +241,38 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- 文件库弹窗 -->
|
||||||
|
{{include file="layouts/_template/file_library" /}}
|
||||||
|
|
||||||
|
<!-- 指定的 商品列表 -->
|
||||||
|
<script id="tpl-goods-list-item" type="text/template">
|
||||||
|
{{ each $data }}
|
||||||
|
<div class="file-item">
|
||||||
|
<a href="{{ $value.image }}" title="{{ $value.goods_name }}" target="_blank">
|
||||||
|
<img src="{{ $value.image }}">
|
||||||
|
</a>
|
||||||
|
<input type="hidden" name="coupon[apply_range_config][applyGoodsIds][]" value="{{ $value.goods_id }}">
|
||||||
|
<i class="iconfont icon-shanchu file-item-delete" data-name="商品"></i>
|
||||||
|
</div>
|
||||||
|
{{ /each }}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<!-- 排除的 商品列表 -->
|
||||||
|
<script id="tpl-goods-list-item2" type="text/template">
|
||||||
|
{{ each $data }}
|
||||||
|
<div class="file-item">
|
||||||
|
<a href="{{ $value.image }}" title="{{ $value.goods_name }}" target="_blank">
|
||||||
|
<img src="{{ $value.image }}">
|
||||||
|
</a>
|
||||||
|
<input type="hidden" name="coupon[apply_range_config][excludedGoodsIds][]" value="{{ $value.goods_id }}">
|
||||||
|
<i class="iconfont icon-shanchu file-item-delete" data-name="商品"></i>
|
||||||
|
</div>
|
||||||
|
{{ /each }}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script src="assets/common/js/vue.min.js?v=<?= $version ?>"></script>
|
||||||
|
<script src="assets/store/js/select.data.js?v=<?= $version ?>"></script>
|
||||||
<script>
|
<script>
|
||||||
/**
|
/**
|
||||||
* 时间选择
|
* 时间选择
|
||||||
@ -233,6 +347,38 @@
|
|||||||
$mySwitchBox.hide().filter('.' + $(this).data('switch-item')).show();
|
$mySwitchBox.hide().filter('.' + $(this).data('switch-item')).show();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 选择商品
|
||||||
|
var $goodsList = $('.widget-goods-list');
|
||||||
|
$('.j-selectGoods').selectData({
|
||||||
|
title: '选择商品',
|
||||||
|
uri: 'goods/lists',
|
||||||
|
dataIndex: 'goods_id',
|
||||||
|
done: function (data) {
|
||||||
|
var $html = $(template('tpl-goods-list-item', data));
|
||||||
|
// 删除文件
|
||||||
|
$html.find('.file-item-delete').on('click', function () {
|
||||||
|
$(this).parent().remove();
|
||||||
|
});
|
||||||
|
$goodsList.append($html);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 选择商品
|
||||||
|
var $goodsList2 = $('.widget-goods-list2');
|
||||||
|
$('.j-selectGoods2').selectData({
|
||||||
|
title: '选择商品',
|
||||||
|
uri: 'goods/lists',
|
||||||
|
dataIndex: 'goods_id',
|
||||||
|
done: function (data) {
|
||||||
|
var $html = $(template('tpl-goods-list-item2', data));
|
||||||
|
// 删除文件
|
||||||
|
$html.find('.file-item-delete').on('click', function () {
|
||||||
|
$(this).parent().remove();
|
||||||
|
});
|
||||||
|
$goodsList2.append($html);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 表单验证提交
|
* 表单验证提交
|
||||||
* @type {*}
|
* @type {*}
|
||||||
|
@ -10,6 +10,21 @@
|
|||||||
<link rel="icon" type="image/png" href="assets/common/i/favicon.ico"/>
|
<link rel="icon" type="image/png" href="assets/common/i/favicon.ico"/>
|
||||||
<link rel="stylesheet" href="assets/store/css/login/style.css?v=<?= $version ?>"/>
|
<link rel="stylesheet" href="assets/store/css/login/style.css?v=<?= $version ?>"/>
|
||||||
</head>
|
</head>
|
||||||
|
<style>
|
||||||
|
.copyright {
|
||||||
|
display: none;
|
||||||
|
margin: -40px auto 0 auto;
|
||||||
|
padding: 2px 0;
|
||||||
|
width: 600px;
|
||||||
|
color: #fff;
|
||||||
|
background: #ccc;
|
||||||
|
background: rgba(0, 0, 0, 0.4);
|
||||||
|
}
|
||||||
|
|
||||||
|
.copyright a {
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
<body class="page-login-v3">
|
<body class="page-login-v3">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div id="wrapper" class="login-body">
|
<div id="wrapper" class="login-body">
|
||||||
@ -33,6 +48,9 @@
|
|||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="copyright">
|
||||||
|
<span>Copyright ©2020 xxx版权所有 <a href="https://www.baidu.com/" target="_blank">粤ICP备18030800号-1</a></span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
<script src="assets/common/js/jquery.min.js"></script>
|
<script src="assets/common/js/jquery.min.js"></script>
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
{
|
{
|
||||||
"version": "1.1.44"
|
"version": "1.1.45"
|
||||||
}
|
}
|
||||||
|
@ -48,7 +48,9 @@
|
|||||||
this.appVue = new Vue({
|
this.appVue = new Vue({
|
||||||
el: setting.el,
|
el: setting.el,
|
||||||
data: {
|
data: {
|
||||||
|
// 规格组/值
|
||||||
spec_attr: spec_attr,
|
spec_attr: spec_attr,
|
||||||
|
// sku列表
|
||||||
spec_list: spec_list,
|
spec_list: spec_list,
|
||||||
// 显示添加规格组按钮
|
// 显示添加规格组按钮
|
||||||
showAddGroupBtn: true,
|
showAddGroupBtn: true,
|
||||||
@ -121,8 +123,8 @@
|
|||||||
onSubmitAddValue: function (index) {
|
onSubmitAddValue: function (index) {
|
||||||
var _this = this
|
var _this = this
|
||||||
, specAttr = _this.spec_attr[index];
|
, specAttr = _this.spec_attr[index];
|
||||||
if (!specAttr.hasOwnProperty('tempValue') || specAttr.tempValue === '') {
|
// 验证新增规格值
|
||||||
layer.msg('规格值不能为空');
|
if (!this.verifyAddValue(specAttr)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// 添加到数据库
|
// 添加到数据库
|
||||||
@ -148,53 +150,88 @@
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 验证新增规格值
|
||||||
|
* @param specAttr
|
||||||
|
* @returns {boolean}
|
||||||
|
*/
|
||||||
|
verifyAddValue(specAttr) {
|
||||||
|
if (!specAttr.tempValue || specAttr.tempValue === '') {
|
||||||
|
layer.msg('规格值不能为空');
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
// 验证规格值是否重复
|
||||||
|
var specValues = []
|
||||||
|
specAttr.spec_items.forEach(function (item) {
|
||||||
|
specValues.push(item.spec_value)
|
||||||
|
})
|
||||||
|
if (specValues.indexOf(specAttr.tempValue) > -1) {
|
||||||
|
layer.msg('规格值不能重复');
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 构建规格组合列表
|
* 构建规格组合列表
|
||||||
*/
|
*/
|
||||||
buildSkulist: function () {
|
buildSkulist: function () {
|
||||||
var _this = this;
|
var _this = this;
|
||||||
// 规格组合总数 (table行数)
|
// 计算skuList总数 (table行数)
|
||||||
var totalRow = 1;
|
var skuDataCount = 1;
|
||||||
for (var i = 0; i < _this.spec_attr.length; i++) {
|
for (var i = 0; i < _this.spec_attr.length; i++) {
|
||||||
totalRow *= _this.spec_attr[i].spec_items.length;
|
skuDataCount *= _this.spec_attr[i].spec_items.length;
|
||||||
}
|
}
|
||||||
// 遍历tr 行
|
// 遍历skuList列表,生成tr(行)
|
||||||
var specList = [];
|
var skuList = [];
|
||||||
for (i = 0; i < totalRow; i++) {
|
for (i = 0; i < skuDataCount; i++) {
|
||||||
var rowData = [], rowCount = 1, specSkuIdAttr = [];
|
// skuItem的数据
|
||||||
// 遍历td 列
|
var skuItemRows = [],
|
||||||
|
rowCount = 1, specSkuIdAttr = [];
|
||||||
|
// 遍历规格属性, 生成td row(列)
|
||||||
for (var j = 0; j < _this.spec_attr.length; j++) {
|
for (var j = 0; j < _this.spec_attr.length; j++) {
|
||||||
var skuValues = _this.spec_attr[j].spec_items;
|
// 每组规格的值
|
||||||
rowCount *= skuValues.length;
|
var specValues = _this.spec_attr[j].spec_items;
|
||||||
var anInterBankNum = (totalRow / rowCount)
|
|
||||||
, point = ((i / anInterBankNum) % skuValues.length);
|
// 合并后的规格值显示的区块数量
|
||||||
|
rowCount = rowCount * specValues.length;
|
||||||
|
|
||||||
|
// 合并后的规格值的rowspan
|
||||||
|
var anInterBankNum = skuDataCount / rowCount;
|
||||||
|
var point = (i / anInterBankNum) % specValues.length;
|
||||||
|
|
||||||
|
// rowspan能被i整除 才写入skuItemRows
|
||||||
|
// i % anInterBankNum
|
||||||
if (0 === (i % anInterBankNum)) {
|
if (0 === (i % anInterBankNum)) {
|
||||||
rowData.push({
|
skuItemRows.push({
|
||||||
rowspan: anInterBankNum,
|
rowspan: anInterBankNum,
|
||||||
item_id: skuValues[point].item_id,
|
item_id: specValues[point].item_id,
|
||||||
spec_value: skuValues[point].spec_value
|
spec_value: specValues[point].spec_value
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
specSkuIdAttr.push(skuValues[parseInt(point.toString())].item_id);
|
const pointInt = parseInt(point.toString());
|
||||||
|
specSkuIdAttr.push(specValues[pointInt].item_id);
|
||||||
}
|
}
|
||||||
specList.push({
|
skuList.push({
|
||||||
spec_sku_id: specSkuIdAttr.join('_'),
|
spec_sku_id: specSkuIdAttr.join('_'),
|
||||||
rows: rowData,
|
rows: skuItemRows,
|
||||||
form: {}
|
form: {}
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// return false;
|
// return false;
|
||||||
// 合并旧sku数据
|
// 合并旧sku数据
|
||||||
if (_this.spec_list.length > 0 && specList.length > 0) {
|
if (_this.spec_list.length > 0 && skuList.length > 0) {
|
||||||
for (i = 0; i < specList.length; i++) {
|
for (i = 0; i < skuList.length; i++) {
|
||||||
var overlap = _this.spec_list.filter(function (val) {
|
var overlap = _this.spec_list.filter(function (val) {
|
||||||
return val.spec_sku_id === specList[i].spec_sku_id;
|
return val.spec_sku_id === skuList[i].spec_sku_id;
|
||||||
});
|
});
|
||||||
if (overlap.length > 0) specList[i].form = overlap[0].form;
|
if (overlap.length > 0) skuList[i].form = overlap[0].form;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_this.spec_list = specList;
|
_this.spec_list = skuList;
|
||||||
// 注册上传sku图片事件
|
// 注册上传sku图片事件
|
||||||
_this.onSelectImagesEvent();
|
_this.onSelectImagesEvent();
|
||||||
},
|
},
|
||||||
@ -238,7 +275,7 @@
|
|||||||
onSubmitBatchData: function () {
|
onSubmitBatchData: function () {
|
||||||
var _this = this;
|
var _this = this;
|
||||||
_this.spec_list.forEach(function (value) {
|
_this.spec_list.forEach(function (value) {
|
||||||
for (var key in _this.batchData) {
|
for (var key in _this.batchData) {
|
||||||
if (_this.batchData.hasOwnProperty(key) && _this.batchData[key]) {
|
if (_this.batchData.hasOwnProperty(key) && _this.batchData[key]) {
|
||||||
_this.$set(value.form, key, _this.batchData[key]);
|
_this.$set(value.form, key, _this.batchData[key]);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user