This commit is contained in:
2025-10-29 15:32:26 +08:00
parent d90614805b
commit b7462657cd
78921 changed files with 2753938 additions and 71 deletions

View File

@@ -0,0 +1,351 @@
<?php
/**
*/
namespace addon\coupon\api\controller;
use app\api\controller\BaseApi;
use addon\coupon\model\Coupon as CouponModel;
use addon\coupon\model\CouponType as CouponTypeModel;
use addon\coupon\model\MemberCoupon;
use think\facade\Db;
/**
* 优惠券
*/
class Coupon extends BaseApi
{
/**
* 优惠券类型信息
*/
public function typeinfo()
{
$coupon_type_id = $this->params['coupon_type_id'] ?? 0;
if (empty($coupon_type_id)) {
return $this->response($this->error('', 'REQUEST_COUPON_TYPE_ID'));
}
$app_type = $this->params['app_type'] ?? 'h5';
$coupon_model = new CouponModel();
$condition = [
[ 'coupon_type_id', '=', $coupon_type_id ],
[ 'is_show', '=', 1 ],
[ 'site_id', '=', $this->site_id ]
];
$coupon_type_model = new CouponTypeModel();
$qrcode = $coupon_type_model->qrcode($coupon_type_id, $app_type, $this->site_id)[ 'data' ];
$info = $coupon_model->getCouponTypeInfo($condition);
if (!empty($info[ 'data' ]) && !empty($qrcode)) {
$info[ 'data' ][ 'qrcode' ] = $qrcode[ 'path' ];
}
return $this->response($info);
}
/**
* 列表信息
*/
public function memberpage()
{
$token = $this->checkToken();
if ($token[ 'code' ] < 0) return $this->response($token);
$page = $this->params['page'] ?? 1;
$page_size = $this->params['page_size'] ?? PAGE_LIST_ROWS;
$state = $this->params['state'] ?? 1;//优惠券状态 1已领用未使用 2已使用 3已过期
$coupon_model = new CouponModel();
$condition = [
[ 'npc.member_id', '=', $token[ 'data' ][ 'member_id' ] ],
[ 'npc.state', '=', $state ]
];
//按类型筛选
$type = $this->params['type'] ?? '';
$related_id = $this->params['related_id'] ?? 0;
switch ( $type ) {
case 'reward'://满减
$condition[] = ['npc.type', '=', 'reward'];
break;
case 'discount'://折扣
$condition[] = ['npc.type', '=', 'discount'];
break;
case 'no_threshold'://无门槛
$condition[] = ['npc.at_least', '=', 0 ];
break;
}
if (!empty($related_id)) {
$condition[] = [ 'related_id', '=', $related_id ];
}
$list = $coupon_model->getMemberCouponPageList($condition, $page, $page_size);
return $this->response($list);
}
/**
* 优惠券类型列表
*/
public function typelists()
{
$num = $this->params['num'] ?? 0;
$coupon_type_id_arr = $this->params['coupon_type_id_arr'] ?? '';//coupon_type_id数组
$can_receive = $this->params['can_receive'] ?? 0;// 是否只查询可领取的
$token = $this->checkToken();
$coupon_model = new CouponModel();
$condition = [
[ 'status', '=', 1 ],
[ 'is_show', '=', 1 ],
[ 'site_id', '=', $this->site_id ]
];
//按类型查询
$type = $this->params['type'] ?? '';
switch ( $type ) {
case 'reward'://满减
$condition[] = ['type', '=', 'reward'];
break;
case 'discount'://折扣
$condition[] = ['type', '=', 'discount'];
break;
case 'no_threshold'://无门槛
$condition[] = ['at_least', '=', 0 ];
break;
}
if (!empty($coupon_type_id_arr)) {
$condition[] = [ 'coupon_type_id', 'in', $coupon_type_id_arr ];
}
$field = 'coupon_type_id,type,site_id,coupon_name,money,discount,max_fetch,at_least,end_time,image,validity_type,fixed_term,status,is_show,goods_type,discount_limit,count,lead_count,IF(count < 0 or count - lead_count > 0, 1, 0) as is_remain';
if ($can_receive == 1) {
$condition[] = [ [ 'count', '<>', Db::raw('lead_count') ] ];
}
$order = Db::raw('IF(count < 0 or count - lead_count > 0, 1, 0) DESC,sort ASC');
$list = $coupon_model->getCouponTypeList($condition, $field, $order, $num);
if (!empty($list[ 'data' ]) && $this->member_id) {
foreach ($list[ 'data' ] as $k => $v) {
$list[ 'data' ][ $k ][ 'member_coupon_num' ] = $coupon_model->getCouponCount([
[ 'get_type', '=', 2 ],
[ 'member_id', '=', $this->member_id ],
[ 'coupon_type_id', '=', $v[ 'coupon_type_id' ] ]
])[ 'data' ];
}
}
return $this->response($list);
}
/**
* 优惠券类型分页列表
*/
public function typepagelists()
{
$page = $this->params['page'] ?? 1;
$page_size = $this->params['page_size'] ?? PAGE_LIST_ROWS;
$coupon_type_id_arr = $this->params['coupon_type_id_arr'] ?? '';//coupon_type_id数组
$can_receive = $this->params['can_receive'] ?? 0;// 是否只查询可领取的
$token = $this->checkToken();
$coupon_model = new CouponModel();
$condition = [
[ 'status', '=', 1 ],
[ 'is_show', '=', 1 ],
[ 'site_id', '=', $this->site_id ]
];
//按类型查询
$type = $this->params['type'] ?? '';
switch ( $type ) {
case 'reward'://满减
$condition[] = ['type', '=', 'reward'];
break;
case 'discount'://折扣
$condition[] = ['type', '=', 'discount'];
break;
case 'no_threshold'://无门槛
$condition[] = ['at_least', '=', 0 ];
break;
}
if (!empty($coupon_type_id_arr)) {
$condition[] = [ 'coupon_type_id', 'in', $coupon_type_id_arr ];
}
$field = 'coupon_type_id,type,site_id,coupon_name,money,discount,max_fetch,at_least,end_time,image,validity_type,fixed_term,status,is_show,goods_type,discount_limit,count,lead_count,IF(count < 0 or count - lead_count > 0, 1, 0) as is_remain';
if ($can_receive == 1) {
$condition[] = [ [ 'count', '<>', Db::raw('lead_count') ] ];
}
if ($this->member_id) {
$prefix = config('database.connections.mysql.prefix');
$field .= ', (select count(coupon_id) from ' . $prefix . 'promotion_coupon pc where pc.coupon_type_id = ct.coupon_type_id and pc.get_type=2 and pc.member_id=' . $this->member_id . ') as member_coupon_num';
}
$order = Db::raw('IF(count < 0 or count - lead_count > 0, 1, 0) DESC,sort ASC');
$list = $coupon_model->getCouponTypePageList($condition, $page, $page_size, $order, $field, 'ct');
return $this->response($list);
}
/**
* 获取优惠券
*/
public function receive()
{
$token = $this->checkToken();
if ($token[ 'code' ] < 0) return $this->response($token);
$site_id = $this->site_id;
$coupon_type_id = $this->params['coupon_type_id'] ?? 0;
$get_type = $this->params['get_type'] ?? 2;//获取方式:1订单2.直接领取3.活动领取
if (empty($coupon_type_id)) {
return $this->response($this->error('', 'REQUEST_COUPON_TYPE_ID'));
}
$coupon_model = new CouponModel();
$res = $coupon_model->receiveCoupon($coupon_type_id, $site_id, $token[ 'data' ][ 'member_id' ], $get_type);
$res[ 'data' ] = [];
//判断一下用户是否拥有当前优惠券
$coupon = $coupon_model->getCouponInfo([ [ 'coupon_type_id', '=', $coupon_type_id ], [ 'site_id', '=', $site_id ], [ 'member_id', '=', $token[ 'data' ][ 'member_id' ] ] ], 'coupon_id')[ 'data' ];
$res[ 'data' ][ 'is_exist' ] = empty($coupon) ? 0 : 1;
return $this->response($res);
}
/**
* 会员优惠券数量
* @return string
*/
public function num()
{
$token = $this->checkToken();
if ($token[ 'code' ] < 0) return $this->response($token);
$state = $this->params[ 'state' ] ?? 1;
$coupon_model = new MemberCoupon();
$count = $coupon_model->getMemberCouponNum($token[ 'data' ][ 'member_id' ], $state);
return $this->response($count);
}
/**
* 是否可以领取
*/
public function receivedNum()
{
$token = $this->checkToken();
if ($token[ 'code' ] < 0) return $this->response($token);
$coupon_type_id = $this->params['coupon_type_id'] ?? 0;
$coupon_model = new MemberCoupon();
$res = $coupon_model->receivedNum($coupon_type_id, $this->member_id);
return $this->response($res);
}
/**
* 查询商品可用的优惠券
* @param int $id
* @return false|string
*/
public function goodsCoupon($id = 0)
{
$this->checkToken();
$coupon_model = new CouponModel();
$goods_id = $this->params[ 'goods_id' ] ?? 0;
if (!empty($id)) {
$goods_id = $id;
}
// 查询全部商品参与
$condition = [
[ 'site_id', '=', $this->site_id ],
[ 'status', '=', 1 ],
[ 'is_show', '=', 1 ],
[ 'goods_type', '=', 1 ]
];
$field = 'count,lead_count,coupon_type_id,coupon_type_id as type_id,type,site_id,coupon_name,money,discount,max_fetch,at_least,end_time,validity_type,fixed_term,goods_type,discount_limit';
if ($this->member_id) {
$prefix = config('database.connections.mysql.prefix');
$field .= ',(select count(coupon_id) from ' . $prefix . 'promotion_coupon pc where pc.coupon_type_id = type_id and pc.get_type=2 and pc.member_id=' . $this->member_id . ') as member_coupon_num';
}
$list = $coupon_model->getCouponTypeList($condition, $field, 'money desc', null, 'ct');
// 查询指定商品参与
$goods_condition = [
[ 'site_id', '=', $this->site_id ],
[ 'status', '=', 1 ],
[ 'is_show', '=', 1 ],
[ 'goods_type', '=', 2 ],
[ 'goods_ids', 'like', "%,$goods_id,%" ]
];
$goods_coupon = $coupon_model->getCouponTypeList($goods_condition, $field, 'money desc', null, 'ct');
if (!empty($goods_coupon[ 'data' ])) {
$list[ 'data' ] = array_merge($list[ 'data' ], $goods_coupon[ 'data' ]);
}
// 查询指定商品不参与
$not_goods_condition = [
[ 'site_id', '=', $this->site_id ],
[ 'status', '=', 1 ],
[ 'is_show', '=', 1 ],
[ 'goods_type', '=', 3 ],
[ 'goods_ids', 'not like', "%,$goods_id,%" ]
];
$not_goods_coupon = $coupon_model->getCouponTypeList($not_goods_condition, $field, 'money desc', null, 'ct');
if (!empty($not_goods_coupon[ 'data' ])) {
$list[ 'data' ] = array_merge($list[ 'data' ], $not_goods_coupon[ 'data' ]);
}
if ($list[ 'data' ] && $this->member_id) {
foreach ($list[ 'data' ] as $k => $v) {
// 已抢光
if ($v[ 'count' ] == $v[ 'lead_count' ]) {
unset($list[ 'data' ][ $k ]);
} elseif ($v[ 'max_fetch' ] != 0 && $v[ 'member_coupon_num' ] > 0 && $v[ 'member_coupon_num' ] >= $v[ 'max_fetch' ]) {
// 已领取
unset($list[ 'data' ][ $k ]);
}
}
$list[ 'data' ] = array_values($list[ 'data' ]);
}
return $this->response($list);
}
/**
* 查询优惠券通过优惠券类型id
*/
public function couponById()
{
$id = $this->params[ 'id' ] ?? 0;
$coupon_model = new CouponModel();
$condition = [
[ 'site_id', '=', $this->site_id ],
[ 'status', '=', 1 ],
[ 'coupon_type_id', 'in', $id ]
];
$list = $coupon_model->getCouponTypeList($condition, 'coupon_type_id,type,site_id,coupon_name,money,discount,max_fetch,at_least,end_time,validity_type,fixed_term,goods_type,discount_limit', 'money desc', '');
return $this->response($list);
}
}

View File

@@ -0,0 +1,19 @@
<?php
namespace addon\coupon\component\controller;
use app\component\controller\BaseDiyView;
/**
* 优惠券·组件
*/
class Coupon extends BaseDiyView
{
/**
* 后台编辑界面
*/
public function design()
{
return $this->fetch('coupon/design.html');
}
}

View File

@@ -0,0 +1,681 @@
@CHARSET "UTF-8";
/* 弹框样式 */
.coupon-wrap .coupon-list-style {
display: none;
}
.style-list-con-coupon {
display: flex;
flex-wrap: wrap;
}
.style-list-con-coupon .style-li-coupon {
width: 32%;
height: 150px;
line-height: 150px;
margin-right: 2%;
margin-bottom: 15px;
cursor: pointer;
border: 1px solid #ededed;
background: #f7f8fa;
box-sizing: border-box;
text-align: center;
}
.style-list-con-coupon .style-li-coupon:nth-child(3n) {
margin-right: 0;
}
.style-list-con-coupon .style-li-coupon img {
max-width: 100%;
max-height: 100%;
}
.layui-layer-page .layui-layer-content {
overflow: auto !important;
}
/* 公共样式 */
.coupon-wrap .coupon-box .coupon {
display: inline-block;
width: 140px;
margin-right: 10px;
position: relative;
}
.coupon-wrap .coupon-box .coupon .coupon-intro {
position: absolute;
top: 10px;
width: 103px;
text-align: center;
font-size: 12px;
}
.coupon-wrap .coupon-box .coupon .coupon-intro .coupon-price {
margin-bottom: 3px;
}
.coupon-wrap .coupon-box .coupon .coupon-intro .coupon-price span {
font-size: 20px;
}
/* 风格一 */
.coupon-wrap .coupon-box.coupon-box-1 {
display: block;
box-sizing: border-box;
padding: 0 8px;
}
.coupon-wrap .coupon-box.coupon-box-1 .coupon-box-list {
overflow: hidden;
display: flex;
flex-wrap: nowrap;
}
.coupon-wrap .coupon-box.coupon-box-1 .coupon {
width: 105px;
flex-shrink: 0;
}
.coupon-wrap .coupon-box.coupon-box-1 .coupon:last-of-type{
margin-right: 0 !important;
}
.coupon-box-1 .coupon-price, .coupon-box-1 .coupon-desc, .coupon-box-1 .coupon-btn {
color: #FFFFFF;
}
.coupon-wrap .coupon-box.coupon-box-1 .coupon .coupon-intro {
width: 80px;
height: 52px;
top: 7px;
}
.coupon-wrap .coupon-box.coupon-box-1 .coupon .coupon-btn {
bottom: 50%;
font-size: 12px;
line-height: 13px;
transform: translateY(50%);
word-break: break-all;
width: 12px;
}
.coupon-box-1 .coupon-title {
display: flex;
width: 100%;
align-items: flex-end;
}
.coupon-box-1 .coupon-title img {
height: 15px;
margin-right: 10px;
}
.coupon-box-1 .coupon-title span {
line-height: 14px;
color: #909399;
}
.coupon-box-1 ul.coupon-list {
margin-top: 15px;
display: flex;
}
.coupon-box-1 ul.coupon-list li.coupon-li {
margin-left: 10px;
height: 65px;
position: relative;
}
.coupon-box-1 ul.coupon-list li.coupon-li:first-child {
margin-left: 0;
}
.coupon-box-1 ul.coupon-list li.coupon-li img {
height: 65px;
}
.coupon-box-1 ul.coupon-list li.coupon-li .coupon-intro {
position: absolute;
top: 12px;
left: 7px;
color: #FF4544;
}
.coupon-box-1 ul.coupon-list li.coupon-li .coupon-intro .coupon-price {
font-size: 12px;
}
.coupon-box-1 ul.coupon-list li.coupon-li .coupon-intro .coupon-price span {
font-size: 20px;
}
.coupon-box-1 ul.coupon-list li.coupon-li .coupon-intro .coupon-desc {
font-size: 12px;
margin-top: 5px;
}
.coupon-box-1 ul.coupon-list li.coupon-li .coupon-btn {
font-size: 12px;
line-height: 14px;
width: 12px;
position: absolute;
right: 11px;
top: 4px;
color: #FFFFFF;
}
/* 风格二 */
.coupon-wrap .coupon-box {
width: 100%;
overflow: hidden;
display: flex;
flex-wrap: nowrap;
background-size: cover;
background-repeat: no-repeat;
}
.coupon-wrap .coupon-box-2{
padding: 0 8px;
box-sizing: border-box;
}
.coupon-wrap .coupon-box-2 .coupon {
display: inline-block;
margin-right: 10px;
position: relative;
width: 105px;
}
.coupon-wrap .coupon-box-2 .coupon:last-of-type{
margin-right: 0 !important;
}
.coupon-wrap .coupon-box .coupon img {
width: 100%;
}
.coupon-wrap .coupon-box-2 .coupon .coupon-intro {
position: absolute;
top: 5px;
width: 80px;
text-align: center;
font-size: 12px;
}
.coupon-wrap .coupon-box-2 .coupon .coupon-intro .coupon-price {
margin-bottom: 0;
}
.coupon-wrap .coupon-box-2 .coupon .coupon-intro .coupon-price span{
font-size: 18px;
}
.coupon-wrap .coupon-box .coupon .coupon-btn {
position: absolute;
bottom: 12px;
right: 6px;
width: 20px;
font-size: 14px;
line-height: 18px;
text-align: center;
}
.coupon-wrap .coupon-box.coupon-box-2 .coupon .coupon-btn {
bottom: -4px;
right: 5px;
-webkit-writing-mode: vertical-rl;
writing-mode: vertical-rl;
letter-spacing: 9px;
}
/* 风格三 */
.coupon-wrap .coupon-box-3 {
height: 141px;
background-repeat: no-repeat;
background-size: 100% 100%;
padding: 8px;
box-sizing: border-box;
}
.coupon-block {
width: 100%;
display: flex;
overflow: hidden;
}
.coupon-wrap .coupon-box-3 .coupon {
width: 103px;
height: 125px;
margin-right: 10px;
text-align: center;
flex-shrink: 0;
}
.coupon-wrap .coupon-box-3 .coupon:last-of-type{
margin-right: 0 !important;
}
.coupon-wrap .coupon-box-3 .coupon .coupon-intro {
width: 100%;
top: 15px;
}
.coupon-wrap .coupon-box-3 .coupon .coupon-intro .coupon-price span {
font-size: 24px;
}
.coupon-wrap .coupon-box-3 .coupon .coupon-desc {
margin: 5px 0;
}
.coupon-wrap .coupon-box-3 .coupon .coupon-info {
color: #777777;
margin-top: 5px;
}
.coupon-wrap .coupon-box-3 .coupon .coupon-btn {
width: 66px;
bottom: 6px;
left: 50%;
margin-left: -33px;
font-size: 12px;
color: #FFFFFF;
line-height: 28px;
background-color: #FF4544;
border-radius: 30px;
}
/* 风格四 */
.coupon-wrap .coupon-box-4 {
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 8px;
box-sizing: border-box;
}
.coupon-wrap .coupon-box-4 .coupon {
width: 105px;
margin-right: 15px;
}
.coupon-wrap .coupon-box-4 .coupon:last-child {
margin-right: 0 !important;
}
.coupon-wrap .coupon-box-4 .coupon .coupon-intro {
width: 75px;
position: absolute;
top: 6px;
}
.coupon-wrap .coupon-box-4 .coupon .coupon-intro p {
font-size: 12px;
color: #FFFFFF;
}
.coupon-wrap .coupon-box-4 .coupon .coupon-intro .coupon-price {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
max-width: 80px
}
.coupon-wrap .coupon-box-4 .coupon .coupon-intro .coupon-price span {
font-size: 24px;
margin: 0 3px;
line-height: 1;
}
.coupon-wrap .coupon-box-4 .coupon .coupon-btn {
font-size: 12px;
line-height: 1;
position: absolute;
top: 0px;
right: 8px;
color: #FFFFFF;
-webkit-writing-mode: vertical-rl;
writing-mode: vertical-rl;
letter-spacing: 2px;
bottom: -2px;
transform: scale(.8);
}
/* 风格五 */
.coupon-wrap .coupon-box-5 {
display: flex;
justify-content: space-between;
align-items: center;
flex-direction: column;
box-sizing: border-box;
}
.coupon-wrap .coupon-box-5 .coupon {
width: 100%;
display: flex;
border-radius: 10px;
margin: 5px auto 5px;
height: 80px;
align-items: center;
position: relative;
}
.coupon-wrap .coupon-box-5 .coupon img{
position: absolute;
z-index: 1;
left: 0;
top: 0;
}
.coupon-wrap .coupon-box-5 .coupon .coupon-price{
padding: 8px;
box-sizing: border-box;
color: #f00;
font-size: 20px;
font-weight: bold;
display: flex;
justify-content: center;
align-items: baseline;
position: relative;
z-index: 1;
width: 81px;
min-width: 81px;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.coupon-wrap .coupon-box-5 .coupon .coupon-line{
position: relative;
z-index: 1;
border: 1px dashed #999;
height: 60%;
margin: 0 7px;
}
.coupon-wrap .coupon-box-5 .coupon .coupon-price span{
font-size: 12px;
font-weight: unset;
}
.coupon-wrap .coupon-box-5 .coupon .coupon-content{
display: flex;
justify-content: space-between;
width: 100%;
padding: 0 10px;
align-items: center;
position: relative;
z-index: 1;
}
.coupon-wrap .coupon-box-5 .coupon .coupon-content .coupon-intro{
display: flex;
flex-direction: column;
align-items: flex-start;
position: unset;
width: max-content;
}
.coupon-wrap .coupon-box-5 .coupon .coupon-content .coupon-intro .coupon-name{
font-size: 16px;
font-weight: bold;
width: 150px;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
text-align: left;
}
.coupon-wrap .coupon-box-5 .coupon .coupon-content .coupon-desc{
font-size: 12px;
color: #999;
margin-top: 5px;
}
.coupon-wrap .coupon-box-5 .coupon .coupon-content .coupon-btn{
font-size: 12px;
color: #fff;
background: #333;
position: unset;
min-width: 55px;
width: auto;
word-break: keep-all;
height: fit-content;
padding: 5px;
margin-right: 10px;
border-radius: 5px;
}
/* 右侧已选择优惠券 */
.select-coupon-list{
}
.select-coupon-item{
border-radius: 4px;
padding: 10px 20px 10px 10px;
color: #999;
position: relative;
margin-top: 10px;
cursor: pointer;
background: #ffffff;
border: 1px dashed #e5e5e5;
}
.select-coupon-item .close{
}
.select-coupon-item:hover .close{
display: block;
}
.select-coupon-item .coupon-content{
position: relative;
display: flex;
align-items: center;
margin-top: 15px;
}
.select-coupon-item .coupon-content:first-of-type{
margin-top: 0px;
}
.select-coupon-item .coupon-content .coupon-label-name{
width: 100px;
text-align: right;
padding-right: 8px;
color: #666;
margin-right: 15px;
}
.select-coupon-item .coupon-content .coupon-label-value{
color: #333;
width: 160px;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
/* 风格六 */
.coupon-wrap .coupon-box-6{
padding: 0 8px;
box-sizing: border-box;
}
.coupon-wrap .coupon-box-6 .coupon{
overflow: hidden;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
width: 104px;
height: 135px;
background-repeat: no-repeat;
background-size: contain;
padding: 10px;
box-sizing: border-box;
position: relative;
flex-shrink: 0;
}
.coupon-wrap .coupon-box-6 .coupon:nth-child(3){
margin-right: 0;
}
.coupon-wrap .coupon-box-6 .coupon::after{
content: "";
position: absolute;
left: 13px;
right: 13px;
bottom: 35px;
border-bottom: 1px dashed #999;
}
.coupon-wrap .coupon-box-6 .coupon .btn{
position: absolute;
height: 18px;
min-width: 31px;
line-height: 18px;
text-align: center;
font-size: 12px;
top: 10px;
right: 0;
}
.coupon-wrap .coupon-box-6 .coupon .btn > span{
display: inline-block;
line-height: 1;
transform: scale(.8);
}
.coupon-wrap .coupon-box-6 .coupon .coupon-content{
display: flex;
flex-direction: column;
align-items: center;
font-size: 12px;
}
.coupon-wrap .coupon-box-6 .coupon .coupon-content .price-wrap{
margin-top: 17px;
margin-bottom: 5px;
}
.coupon-wrap .coupon-box-6 .coupon .coupon-content .price{
margin: 5px 0;
font-size: 35px;
font-weight: bold;
}
.coupon-wrap .coupon-box-6 .coupon .coupon-content .text{
position: relative;
color: #401D00;
}
.coupon-wrap .coupon-box-6 .coupon .coupon-content .text::after{
content: "";
position: absolute;
top: 50%;
transform: translateY(-50%);
width: 10px;
right: -13px;
border-bottom: 1px solid #401D00;
}
.coupon-wrap .coupon-box-6 .coupon .coupon-content .text::before{
content: "";
position: absolute;
top: 50%;
transform: translateY(-50%);
width: 10px;
left: -13px;
border-bottom: 1px solid #401D00;
}
.coupon-wrap .coupon-box-6 .coupon .limit{
margin-top: auto;
font-size: 12px;
font-weight: bold;
}
.coupon-wrap .coupon-box-6 .coupon .unit{
color: #222;
display: inline-block;
line-height: 1;
transform: scale(.8);
}
.coupon-wrap .coupon-box-6 .coupon.coupon-null .limit{
color: #333333;
}
.coupon-wrap .coupon-box-6 .coupon.coupon-null .unit{
color: #999;
}
.coupon-wrap .coupon-box-6 .coupon.coupon-null .text {
color: #401D00;
}
.coupon-wrap .coupon-box-6 .coupon.coupon-null .coupon-content .text::before, .coupon-wrap .coupon-box-6 .coupon.coupon-null .coupon-content .text::after{
border-color: #401D00;
}
.coupon-wrap .coupon-box-6 .coupon.coupon-null .coupon-content .price{
color: #999;
font-weight: inherit;
border: 2px solid #999;
border-radius: 50%;
height: 21px;
width: 21px;
line-height: 21px;
text-align: center;
font-size: 25px;
margin: 20px 0 17px;
}
/* 风格七 */
.coupon-wrap .coupon-box-7 {
display: flex;
justify-content: space-between;
align-items: center;
box-sizing: border-box;
}
.coupon-wrap .coupon-box-7 .coupon {
width: 100%;
display: flex;
border-radius: 10px;
margin: 5px auto 5px;
height: 80px;
align-items: center;
position: relative;
}
.coupon-wrap .coupon-box-7 .coupon{
margin-right: 6px;
}
.coupon-wrap .coupon-box-7 .coupon img{
position: absolute;
z-index: 1;
left: 0;
top: 0;
}
.coupon-wrap .coupon-box-7 .coupon .coupon-price{
padding: 8px;
box-sizing: border-box;
font-size: 36px;
font-weight: bold;
display: flex;
justify-content: center;
align-items: baseline;
position: relative;
z-index: 1;
min-width: 81px;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.coupon-wrap .coupon-box-7 .coupon .coupon-line{
position: relative;
z-index: 1;
border: 1px dashed #FD463E;
height: 60%;
margin-left: 7px;
}
.coupon-wrap .coupon-box-7 .coupon .coupon-price span{
font-size: 12px;
font-weight: unset;
margin-left: 2px;
}
.coupon-wrap .coupon-box-7 .coupon .coupon-intro{
display: flex;
flex-direction: column;
align-items: flex-start;
position: unset;
width: 120px;
z-index: 5;
margin-left: 15px;
margin-right: 5px;
}
.coupon-wrap .coupon-box-7 .coupon .coupon-intro .coupon-name{
font-size: 14px;
font-weight: bold;
width: 120px;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
text-align: left;
}
.coupon-wrap .coupon-box-7 .coupon .coupon-desc{
font-size: 11px;
color: #999;
margin-top: 5px;
}
.coupon-wrap .coupon-box-7 .coupon .coupon-btn{
font-size: 12px;
color: #fff;
position: unset;
height: fit-content;
z-index: 5;
width: 65px;
padding: 10px 18px;
box-sizing: border-box;
}

View File

@@ -0,0 +1,404 @@
<nc-component :data="data[index]" class="coupon-wrap">
<!-- 预览 -->
<template slot="preview">
<div class="coupon-preview" v-if="nc.tempData.methods && Object.keys(nc.tempData.methods).length">
<div class="coupon-box coupon-box-1" v-if="nc.style == 1" :style="[nc.couponType == 'img' && {backgroundImage: 'url('+ changeImgUrl(nc.couponBgUrl) + ')'},nc.couponType == 'color'&&{backgroundColor: nc.couponBgColor}]">
<div class="coupon-box-list" v-if="nc.sources == 'diy' && nc.couponIds.length > 0">
<div class="coupon" v-for="(item, index) in nc.previewList" v-if="index < 3" :style="{marginRight: (40 - nc.margin.both * 2) / 2 + 'px'}">
<img src="{$resource_path}/img/style1-bg.png">
<div class="coupon-intro" >
<p class="coupon-price" :style="{color: nc.moneyColor}" v-if="item.type == 'reward'"><span>{{nc.tempData.methods.moneyConduct(item.money)}}</span></p>
<p class="coupon-price" :style="{color: nc.moneyColor}" v-else><span>{{nc.tempData.methods.moneyConduct(item.discount)}}</span></p>
<p class="coupon-desc" :style="{color: nc.limitColor}" v-if="parseFloat(item.at_least) > 0">满{{item.at_least.split('.')[0]}}元使用</p>
<p class="coupon-desc" :style="{color: nc.limitColor}" v-else>无门槛使用</p>
</div>
<div class="coupon-btn" :style="{color: nc.btnStyle.textColor,backgroundColor: nc.btnStyle.bgColor, borderRadius: (nc.btnStyle.aroundRadius+'px')}">{{nc.btnStyle.text}}</div>
</div>
</div>
<div class="coupon-box-list" v-else>
<div class="coupon" v-for="item in 3" :style="{marginRight: ( 40 - nc.margin.both * 2) / 2 + 'px'}">
<img src="{$resource_path}/img/style1-bg.png">
<div class="coupon-intro">
<p class="coupon-price" :style="{color: nc.moneyColor}"><span>500</span></p>
<p class="coupon-desc" :style="{color: nc.limitColor}">满3000可用</p>
</div>
<div class="coupon-btn" :style="{color: nc.btnStyle.textColor,backgroundColor: nc.btnStyle.bgColor, borderRadius: (nc.btnStyle.aroundRadius+'px')}">{{nc.btnStyle.text}}</div>
</div>
</div>
</div>
<div class="coupon-box coupon-box-2" v-else-if="nc.style == 2" :style="[nc.couponType == 'img' && {backgroundImage: 'url('+ changeImgUrl(nc.couponBgUrl) + ')'},nc.couponType == 'color'&&{backgroundColor: nc.couponBgColor}]">
<template v-if="nc.sources == 'diy' && nc.couponIds.length > 0">
<div class="coupon" v-for="(item, index) in nc.previewList" v-if="index <= 3" :style="{marginRight: ( 41 - nc.margin.both * 2) / 2 + 'px'}">
<img src="{$resource_path}/img/coupon_bg.png">
<div class="coupon-intro">
<p class="coupon-price" :style="{color: nc.moneyColor}" v-if="item.type == 'reward'"><span>{{nc.tempData.methods.moneyConduct(item.money)}}</span></p>
<p class="coupon-price" :style="{color: nc.moneyColor}" v-else><span>{{nc.tempData.methods.moneyConduct(item.discount)}}</span></p>
<p class="coupon-desc" :style="{color: nc.limitColor}" v-if="parseFloat(item.at_least) > 0">满{{item.at_least.split('.')[0]}}元使用</p>
<p class="coupon-desc" :style="{color: nc.limitColor}" v-else>无门槛使用</p>
</div>
<div class="coupon-btn" :style="{color: nc.btnStyle.textColor,backgroundColor: nc.btnStyle.bgColor, borderRadius: (nc.btnStyle.aroundRadius+'px')}">{{nc.btnStyle.text}}</div>
</div>
</template>
<template v-else>
<div class="coupon" v-for="item in 3" :style="{marginRight: (41-nc.margin.both*2)/2 + 'px'}">
<img src="{$resource_path}/img/coupon_bg.png">
<div class="coupon-intro">
<p class="coupon-price" :style="{color: nc.moneyColor}"><span>500</span></p>
<p class="coupon-desc" :style="{color: nc.limitColor}">满3000元可用</p>
</div>
<div class="coupon-btn" :style="{color: nc.btnStyle.textColor,backgroundColor: nc.btnStyle.bgColor, borderRadius: (nc.btnStyle.aroundRadius+'px')}">{{nc.btnStyle.text}}</div>
</div>
</template>
</div>
<div class="coupon-box" :class="'coupon-box-'+ nc.style" v-if="nc.style == 3" :style="[nc.couponType == 'img'&&{backgroundImage: 'url('+ changeImgUrl(nc.couponBgUrl) + ')'},nc.couponType == 'color'&&{backgroundColor: nc.couponBgColor}]">
<div class="coupon-block" v-if="nc.sources == 'diy' && nc.couponIds.length > 0">
<div class="coupon" v-for="(item, previewIndex) in nc.previewList" v-if="previewIndex < 3" :style="{marginRight: (46-nc.margin.both*2)/2 + 'px'}">
<img src="{$resource_path}/img/style3-bg-2.png">
<div class="coupon-intro">
<p class="coupon-price" :style="{color: nc.moneyColor}" v-if="item.type == 'reward'"><span>{{nc.tempData.methods.moneyConduct(item.money)}}</span></p>
<p class="coupon-price" :style="{color: nc.moneyColor}" v-else><span>{{nc.tempData.methods.moneyConduct(item.discount)}}</span></p>
<p class="coupon-desc" :style="{color: nc.limitColor}" v-if="parseFloat(item.at_least) > 0">满{{item.at_least.split('.')[0]}}元可用</p>
<p class="coupon-desc" :style="{color: nc.limitColor}" v-else>无门槛使用</p>
<p class="coupon-info" v-if="item.goods_type == 1">全部商品可用</p>
<p class="coupon-info" v-if="item.goods_type == 2">指定商品可用</p>
<p class="coupon-info" v-if="item.goods_type == 3">指定商品不可用</p>
</div>
<div class="coupon-btn" :style="{color: nc.btnStyle.textColor,backgroundColor: nc.btnStyle.bgColor, borderRadius: (nc.btnStyle.aroundRadius+'px')}">{{nc.btnStyle.text}}</div>
</div>
</div>
<div class="coupon-block" v-else>
<div class="coupon" v-for="item in 3" :style="{marginRight: (46-nc.margin.both*2)/2 + 'px'}">
<img src="{$resource_path}/img/style3-bg-2.png">
<div class="coupon-intro">
<p class="coupon-price" :style="{color: nc.moneyColor}"><span>500</span></p>
<p class="coupon-desc" :style="{color: nc.limitColor}">满3000元可用</p>
<p class="coupon-info">指定商品可用</p>
</div>
<div class="coupon-btn" :style="{color: nc.btnStyle.textColor,backgroundColor: nc.btnStyle.bgColor, borderRadius: (nc.btnStyle.aroundRadius+'px')}">{{nc.btnStyle.text}}</div>
</div>
</div>
</div>
<div class="coupon-box" :class="'coupon-box-'+ nc.style" v-else-if="nc.style == 4" :style="[nc.couponType == 'img'&&{backgroundImage: 'url('+ changeImgUrl(nc.couponBgUrl) + ')'},nc.couponType == 'color'&&{backgroundColor: nc.couponBgColor}]">
<template v-if="nc.sources == 'diy' && nc.couponIds.length > 0">
<div class="coupon" v-for="(item, previewIndex) in nc.previewList" v-if="previewIndex < 3" :style="{marginRight: (44-nc.margin.both*2)/2 + 'px'}">
<img src="{$resource_path}/img/style4-bg-1.png">
<div class="coupon-intro">
<p class="coupon-price" :style="{color: nc.moneyColor}" v-if="item.type == 'reward'"><span>{{nc.tempData.methods.moneyConduct(item.money)}}</span></p>
<p class="coupon-price" :style="{color: nc.moneyColor}" v-else><span>{{nc.tempData.methods.moneyConduct(item.discount)}}</span></p>
<p class="coupon-desc" :style="{color: nc.limitColor}" v-if="parseFloat(item.at_least) > 0">满{{item.at_least.split('.')[0]}}元使用</p>
<p class="coupon-desc" :style="{color: nc.limitColor}" v-else>无门槛使用</p>
</div>
<div class="coupon-btn" :style="{color: nc.btnStyle.textColor,backgroundColor: nc.btnStyle.bgColor, borderRadius: (nc.btnStyle.aroundRadius+'px')}">{{nc.btnStyle.text}}</div>
</div>
</template>
<template v-else>
<div class="coupon" v-for="item in 3" :style="{marginRight: (44-nc.margin.both*2)/2 + 'px'}">
<img src="{$resource_path}/img/style4-bg-1.png">
<div class="coupon-intro">
<p class="coupon-price" :style="{color: nc.moneyColor}"><span>100</span></p>
<p class="coupon-desc" :style="{color: nc.limitColor}">满1000可用</p>
</div>
<div class="coupon-btn" :style="{color: nc.btnStyle.textColor,backgroundColor: nc.btnStyle.bgColor, borderRadius: (nc.btnStyle.aroundRadius+'px')}">{{nc.btnStyle.text}}</div>
</div>
</template>
</div>
<div class="coupon-box" :class="'coupon-box-'+ nc.style" v-else-if="nc.style == 5" :style="[nc.couponType == 'img'&&{backgroundImage: 'url('+ changeImgUrl(nc.couponBgUrl) + ')'},nc.couponType == 'color'&&{backgroundColor: nc.couponBgColor}]">
<template v-if="nc.sources == 'diy' && nc.couponIds.length > 0">
<div class="coupon" v-for="item in nc.previewList">
<img src="{$resource_path}/img/style5-bg-1.png">
<div class="coupon-price" :style="{color: nc.moneyColor}" v-if="item.type == 'reward'">{{nc.tempData.methods.moneyConduct(item.money)}}<span></span>
</div>
<div class="coupon-price" :style="{color: nc.moneyColor}" v-else>{{nc.tempData.methods.moneyConduct(item.discount)}}<span></span>
</div>
<div class="coupon-line"></div>
<div class="coupon-content">
<div class="coupon-intro">
<p class="coupon-name" :style="{color: nc.nameColor}">{{item.coupon_name}}</p>
<p class="coupon-desc" :style="{color: nc.limitColor}" v-if="parseFloat(item.at_least) > 0">满{{item.at_least.split('.')[0]}}元使用</p>
<p class="coupon-desc" :style="{color: nc.limitColor}" v-else>无门槛使用</p>
</div>
<div class="coupon-btn" :style="{color: nc.btnStyle.textColor,backgroundColor: nc.btnStyle.bgColor, borderRadius: (nc.btnStyle.aroundRadius+'px')}">{{nc.btnStyle.text}}</div>
</div>
</div>
</template>
<template v-else>
<div class="coupon" v-for="item in 2">
<img src="{$resource_path}/img/style5-bg-1.png">
<div class="coupon-price" :style="{color: nc.moneyColor}">
100<span></span>
</div>
<div class="coupon-line"></div>
<div class="coupon-content">
<div class="coupon-intro">
<p :style="{color: nc.nameColor}" class="coupon-name">全场优惠抵用券</p>
<p :style="{color: nc.limitColor}" class="coupon-desc">满1000可用</p>
</div>
<div class="coupon-btn" :style="{color: nc.btnStyle.textColor,backgroundColor: nc.btnStyle.bgColor, borderRadius: (nc.btnStyle.aroundRadius+'px')}">{{nc.btnStyle.text}}</div>
</div>
</div>
</template>
</div>
<div class="coupon-box" :class="'coupon-box-'+ nc.style" v-else-if="nc.style == 6" :style="[nc.couponType == 'img'&&{backgroundImage: 'url('+ changeImgUrl(nc.couponBgUrl) + ')'},nc.couponType == 'color'&&{backgroundColor: nc.couponBgColor}]">
<template v-if="nc.sources == 'diy' && nc.couponIds.length > 0">
<template v-for="(item, previewIndex) in nc.previewList">
<div class="coupon" v-if="previewIndex < 3" :style="{color: nc.moneyColor,backgroundImage: 'url({$resource_path}/img/style6-bg-1.png)', marginRight: (43-nc.margin.both*2)/2 + 'px'}">
<div class="coupon-content" :style="{color: nc.moneyColor}">
<div class="price-wrap">
<span class="price">{{ nc.tempData.methods.moneyConduct(item.type == 'reward' ? item.money : item.discount)}}</span>
<span class="unit">{{item.type == 'reward' ? "元" : "折"}}</span>
</div>
<span class="text">优惠券</span>
</div>
<span class="btn" :style="{color: nc.btnStyle.textColor,backgroundColor: nc.btnStyle.bgColor, borderTopLeftRadius: (nc.btnStyle.aroundRadius+'px'), borderBottomLeftRadius: (nc.btnStyle.aroundRadius+'px')}"><span>{{nc.btnStyle.text}}</span></span>
<span class="limit" :style="{color: nc.limitColor}" v-if="parseFloat(item.at_least) > 0">满{{item.at_least.split('.')[0]}}使用</span>
<span class="limit" :style="{color: nc.limitColor}" v-else>无门槛使用</span>
</div>
</template>
<div v-if="nc.previewList.length <= 2" class="coupon coupon-null" :style="{color: nc.moneyColor,backgroundImage: 'url({$resource_path}/img/style6-bg-2.png)'}">
<div class="coupon-content" :style="{color: nc.moneyColor}">
<span class="price">+</span>
<span class="text">暂无优惠券</span>
</div>
<span class="limit">去逛逛</span>
</div>
</template>
<template v-else>
<div class="coupon" v-for="item in 2" :style="{color: nc.moneyColor,backgroundImage: 'url({$resource_path}/img/style6-bg-1.png)', marginRight: (43-nc.margin.both*2)/2 + 'px'}" >
<div class="coupon-content" :style="{color: nc.moneyColor}">
<div class="price-wrap">
<span class="price">10</span>
<span class="unit"></span>
</div>
<span class="text">优惠券</span>
</div>
<span class="btn" :style="{color: nc.btnStyle.textColor,backgroundColor: nc.btnStyle.bgColor, borderTopLeftRadius: (nc.btnStyle.aroundRadius+'px'), borderBottomLeftRadius: (nc.btnStyle.aroundRadius+'px')}"><span>{{nc.btnStyle.text}}</span></span>
<span class="limit" :style="{color: nc.limitColor}">满129使用</span>
</div>
<div class="coupon coupon-null" :style="{color: nc.moneyColor,backgroundImage: 'url({$resource_path}/img/style6-bg-2.png)'}">
<div class="coupon-content" :style="{color: nc.moneyColor}">
<span class="price">+</span>
<span class="text">暂无优惠券</span>
</div>
<span class="limit">去逛逛</span>
</div>
</template>
</div>
<div class="coupon-box" :class="'coupon-box-'+ nc.style" v-else-if="nc.style == 7" :style="[nc.couponType == 'img'&&{backgroundImage: 'url('+ changeImgUrl(nc.couponBgUrl) + ')'},nc.couponType == 'color'&&{backgroundColor: nc.couponBgColor}]">
<template v-if="nc.sources == 'diy' && nc.couponIds.length > 0">
<div class="coupon" v-for="item in nc.previewList">
<img src="{$resource_path}/img/style7-bg-1.png">
<div class="coupon-price" :style="{color: nc.moneyColor}" v-if="item.type == 'reward'">{{nc.tempData.methods.moneyConduct(item.money)}}<span></span>
</div>
<div class="coupon-price" :style="{color: nc.moneyColor}" v-else>{{nc.tempData.methods.moneyConduct(item.discount)}}<span></span>
</div>
<div class="coupon-intro">
<p class="coupon-name" :style="{color: nc.limitColor}" v-if="parseFloat(item.at_least) > 0">满{{item.at_least.split('.')[0]}}元可用</p>
<p class="coupon-name" :style="{color: nc.limitColor}" v-else>无门槛使用</p>
<p class="coupon-desc" :style="{color: nc.limitColor}">有效期至2022-12-31</p>
</div>
<div class="coupon-line"></div>
<div class="coupon-btn" :style="{color: nc.btnStyle.textColor,backgroundColor: nc.btnStyle.bgColor, borderRadius: (nc.btnStyle.aroundRadius+'px')}">{{nc.btnStyle.text}}</div>
</div>
</template>
<template v-else>
<div class="coupon" v-for="item in 2">
<img src="{$resource_path}/img/style7-bg-1.png">
<div class="coupon-price" :style="{color: nc.moneyColor}">
100<span></span>
</div>
<div class="coupon-intro">
<p :style="{color: nc.limitColor}" class="coupon-name">满1000元可用</p>
<p :style="{color: nc.limitColor}" class="coupon-desc">有效期至2022-12-31</p>
</div>
<div class="coupon-line"></div>
<div class="coupon-btn" :style="{color: nc.btnStyle.textColor,backgroundColor: nc.btnStyle.bgColor, borderRadius: (nc.btnStyle.aroundRadius+'px')}">{{nc.btnStyle.text}}</div>
</div>
</template>
</div>
</div>
</template>
<!-- 内容编辑 -->
<template slot="edit-content">
<template v-if="nc.lazyLoad">
<coupon-set></coupon-set>
<div class="goods-list-edit layui-form">
<div class="template-edit-title">
<h3>风格设置</h3>
<div class="layui-form-item">
<label class="layui-form-label sm">选择风格</label>
<div class="layui-input-block">
<div v-if="nc.styleName" class="input-text text-color selected-style" @click="nc.tempData.methods.selectCouponStyle()">{{nc.styleName}} <i class="layui-icon layui-icon-right"></i></div>
<div v-else class="input-text selected-style" @click="nc.tempData.methods.selectCouponStyle()">选择 <i class="layui-icon layui-icon-right"></i></div>
</div>
</div>
</div>
<div class="template-edit-title">
<h3>优惠券数据</h3>
<div class="layui-form-item icon-radio" v-if="nc.tempData.goodsSources">
<label class="layui-form-label sm">优惠券来源</label>
<div class="layui-input-block">
<span>{{nc.tempData.goodsSources[nc.sources].text}}</span>
<ul class="icon-wrap">
<li v-for="(value, name) in nc.tempData.goodsSources" :class="[name == nc.sources ? 'text-color border-color' : '']" @click="nc.sources=name">
<i class="iconfont" :class="[{'text-color': name == nc.sources}, value.src]"></i>
</li>
</ul>
</div>
</div>
<div class="layui-form-item" v-if="nc.sources == 'diy'">
<label class="layui-form-label sm">手动选择</label>
<div class="layui-input-block">
<div class="selected-style" @click="nc.tempData.methods.addCoupon()">
<span v-if="nc.couponIds.length == 0">请选择</span>
<span v-if="nc.couponIds.length > 0" class="text-color">已选{{ nc.couponIds.length}}个</span>
<i class="iconfont iconyoujiantou"></i>
</div>
</div>
</div>
<div class="layui-form-item" v-if="nc.sources == 'diy' && nc.couponIds.length > 0">
<div class="select-coupon-list">
<div class="select-coupon-item" v-for="(item, previewIndex) in nc.previewList">
<div class="coupon-content">
<div class="coupon-label-name">名称</div>
<div class="coupon-label-value">{{item.coupon_name}}</div>
</div>
<div class="coupon-content">
<div class="coupon-label-name">优惠金额/折扣</div>
<div class="coupon-label-value" v-if="item.type == 'reward'">¥{{item.money}}</div>
<div class="coupon-label-value" v-else>{{item.discount}}折</div>
</div>
<div class="coupon-content">
<div class="coupon-label-name">使用条件</div>
<div class="coupon-label-value" v-if="parseFloat(item.at_least) > 0">满{{item.at_least}}元使用</div>
<div class="coupon-label-value" v-else>无门槛使用</div>
</div>
<div class="close del" @click="nc.tempData.methods.delCoupon(previewIndex)">x</div>
</div>
</div>
</div>
<slide v-if="nc.sources == 'initial'" :data="{ field : 'count', label : '优惠券数量', max: 9, min: 1 }"></slide>
</div>
</div>
<div class="template-edit-title">
<h3>按钮内容</h3>
<div class="layui-form-item">
<label class="layui-form-label sm">按钮文字</label>
<div class="layui-input-block">
<input type="text" v-model="nc.btnStyle.text" :maxlength="nc.btnStyle.maxLen" placeholder="请输入按钮文字" class="layui-input">
</div>
</div>
</div>
</template>
<!-- 弹框 -->
<div class="coupon-list-style">
<div class="style-list-coupon layui-form">
<div class="style-list-con-coupon">
<div class="style-li-coupon" :class="{'selected border-color': nc.style == 1}">
<img src="{$resource_path}/img/style1.png" />
<span class="layui-hide">风格一</span>
</div>
<div class="style-li-coupon" :class="{'selected border-color': nc.style == 2}">
<img src="{$resource_path}/img/style2.png" />
<span class="layui-hide">风格二</span>
</div>
<div class="style-li-coupon" :class="{'selected border-color': nc.style == 3}">
<img src="{$resource_path}/img/style3.png" />
<span class="layui-hide">风格三</span>
</div>
<div class="style-li-coupon" :class="{'selected border-color': nc.style == 4}">
<img src="{$resource_path}/img/style4.png" />
<span class="layui-hide">风格四</span>
</div>
<div class="style-li-coupon" :class="{'selected border-color': nc.style == 5}">
<img src="{$resource_path}/img/style5.png" />
<span class="layui-hide">风格五</span>
</div>
<div class="style-li-coupon" :class="{'selected border-color': nc.style == 6}">
<img src="{$resource_path}/img/style6.png" />
<span class="layui-hide">风格六</span>
</div>
<div class="style-li-coupon" :class="{'selected border-color': nc.style == 7}">
<img src="{$resource_path}/img/style7.png" />
<span class="layui-hide">风格七</span>
</div>
</div>
<input type="hidden" name="style">
<input type="hidden" name="style_name">
</div>
</div>
</template>
<!-- 样式编辑 -->
<template slot="edit-style">
<template v-if="nc.lazyLoad">
<div class="template-edit-title">
<h3>优惠券样式</h3>
<color v-show="nc.isName" :data="{ field : 'nameColor', 'label' : '名称颜色', defaultColor : '#FFFFFF' }"></color>
<color :data="{ field : 'moneyColor', 'label' : '面额颜色', defaultColor : '#FFFFFF' }"></color>
<color :data="{ field : 'limitColor', 'label' : '门槛颜色', defaultColor : '#FFFFFF' }"></color>
</div>
<div class="template-edit-title">
<h3>按钮样式</h3>
<color v-show="nc.btnStyle.isBgColor" :data="{ field : 'bgColor', 'label' : '背景颜色', parent: 'btnStyle', defaultColor : '#FFFFFF' }"></color>
<color :data="{ field: 'textColor', 'label': '文字颜色', parent: 'btnStyle',defaultColor : '#FFFFFF' }"></color>
<slide v-if="nc.btnStyle.isAroundRadius" :data="{ field : 'aroundRadius', label: '按钮圆角', max: 20, parent:'btnStyle' }"></slide>
</div>
<div class="template-edit-title" v-show="nc.ifNeedBg">
<h3>背景设置</h3>
<div class="layui-form-item tag-wrap">
<label class="layui-form-label sm">组件背景</label>
<div class="layui-input-block">
<div @click="nc.couponType = 'color'" :class="{ 'layui-unselect layui-form-radio' : true,'layui-form-radioed' : nc.couponType == 'color' }">
<i class="layui-anim layui-icon">{{ nc.couponType == 'color' ? "&#xe643;" : "&#xe63f;" }}</i>
<div>背景色</div>
</div>
<div @click="nc.couponType = 'img'" :class="{ 'layui-unselect layui-form-radio' : true,'layui-form-radioed' : nc.couponType == 'img' }">
<i class="layui-anim layui-icon">{{ nc.couponType == 'img' ? "&#xe643;" : "&#xe63f;" }}</i>
<div>背景图片</div>
</div>
</div>
</div>
<color v-show="nc.couponType == 'color'" :data="{ field : 'couponBgColor', 'label' : '背景颜色',defaultColor : '#FFFFFF'}"></color>
<div v-show="nc.couponType == 'img'" class="layui-form-item">
<label class="layui-form-label sm">背景图片</label>
<div class="layui-input-block">
<img-upload :data="{ data: nc,field:'couponBgUrl'}" data-disabled="1"></img-upload>
</div>
</div>
</div>
</template>
</template>
<!-- 资源 -->
<template slot="resource">
<js>
var couponResourcePath = "{$resource_path}"; // http路径
var couponRelativePath = "{$relative_path}"; // 相对路径
</js>
<css src="{$resource_path}/css/design.css"></css>
<js src="{$resource_path}/js/design.js"></js>
</template>
</nc-component>

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@@ -0,0 +1,293 @@
/**
* 空的验证组件,后续如果增加业务,则更改组件
*/
var couponSetHtml = '<div class="layui-hide"></div>';
Vue.component("coupon-set", {
template: couponSetHtml,
data: function () {
return {
data: this.$parent.data,
goodsSources: {
initial: {
text: "默认",
src: "iconshangpinfenlei"
},
diy: {
text: "手动选择",
src: "iconshoudongxuanze"
}
},
couponList: [
{
"ifNeedBg": true,
"couponBgColor": "",
"couponBgUrl": "",
"couponType": "img",
"isName": false,
"nameColor": "",
"moneyColor": "#FFFFFF",
"limitColor": "#FFFFFF",
"btnStyle": {
"textColor": "#FFFFFF",
"bgColor": "",
"text": "立即领取",
"aroundRadius": 0,
"isBgColor": false,
"isAroundRadius": false,
"maxLen": 4
},
"bgColor": ""
},
{
"ifNeedBg": true,
"couponBgColor": "",
"couponBgUrl": "",
"couponType": "img",
"isName": false,
"nameColor": "",
"moneyColor": "#FF8143",
"limitColor": "#FF8143",
"btnStyle": {
"textColor": "#FF8143",
"bgColor": "",
"text": "领取",
"aroundRadius": 0,
"isBgColor": false,
"isAroundRadius": false,
"maxLen": 2
},
"bgColor": ""
},
{
"ifNeedBg": true,
"couponBgColor": "#FFFFFF",
"couponBgUrl": couponRelativePath + "/img/style3-bg-1.png",
"couponType": "img",
"isName": false,
"nameColor": "",
"moneyColor": "#FF4544",
"limitColor": "#FF4544",
"btnStyle": {
"textColor": "#FFFFFF",
"bgColor": "#FF4544",
"text": "立即抢",
"aroundRadius": 20,
"isBgColor": true,
"isAroundRadius": true,
"maxLen": 4
},
"bgColor": ""
},
{
"ifNeedBg": true,
"couponBgColor": "",
"couponBgUrl": "",
"couponType": "img",
"isName": false,
"nameColor": "",
"moneyColor": "#FFFFFF",
"limitColor": "#FFFFFF",
"btnStyle": {
"textColor": "#FFFFFF",
"bgColor": "",
"text": "立即领取",
"aroundRadius": 0,
"isBgColor": false,
"isAroundRadius": false,
"maxLen": 4
},
"bgColor": ""
},
{
"ifNeedBg": true,
"couponBgColor": "",
"couponBgUrl": "",
"couponType": "img",
"isName": true,
"nameColor": "#303133",
"moneyColor": "#FF0000",
"limitColor": "#999999",
"btnStyle": {
"textColor": "#FFFFFF",
"bgColor": "#303133",
"text": "立即领取",
"aroundRadius": 5,
"isBgColor": true,
"isAroundRadius": true,
"maxLen": 5
},
"bgColor": ""
},
{
"ifNeedBg": true,
"couponBgColor": "",
"couponBgUrl": "",
"couponType": "img",
"isName": true,
"nameColor": "#303133",
"moneyColor": "#FF0000",
"limitColor": "#303133",
"btnStyle": {
"textColor": "#FFFFFF",
"bgColor": "#303133",
"text": "领取",
"aroundRadius": 20,
"isBgColor": true,
"isAroundRadius": true,
"maxLen": 3
},
"bgColor": ""
},
{
"ifNeedBg": true,
"couponBgColor": "",
"couponBgUrl": "",
"couponType": "img",
"isName": true,
"nameColor": "",
"moneyColor": "#FD463E",
"limitColor": "#FD463E",
"btnStyle": {
"textColor": "#FF3D3D",
"bgColor": "",
"text": "立即领取",
"aroundRadius": 0,
"isBgColor": false,
"isAroundRadius": false,
"maxLen": 4
},
"bgColor": ""
}
]
}
},
created:function() {
if (!this.$parent.data.verify) this.$parent.data.verify = [];
this.$parent.data.verify.push(this.verify);//加载验证方法
this.$parent.data.ignore = ['textColor', 'elementAngle', 'componentAngle', 'componentBgColor']; //加载忽略内容 -- 其他设置中的属性设置
this.$parent.data.ignoreLoad = true; // 等待忽略数组赋值后加载
this.$parent.data.tempData = {
goodsSources: this.goodsSources,
methods:{
moneyConduct: this.moneyConduct,
addCoupon: this.addCoupon,
delCoupon: this.delCoupon,
selectCouponStyle: this.selectCouponStyle
}
}
},
methods: {
// 金额处理
moneyConduct(value){
var arr = value.split(".");
var str = parseInt(arr[1].split("").reverse().join("")) + '';
str = str.split("").reverse().join("");
if(str == 0) return arr[0];
else return arr[0] + '.' + str;
},
verify : function (index) {
var res = { code : true, message : "" };
if (vue.data[index].sources == 'diy' && vue.data[index].couponIds.length == 0){
res.code = false;
res.message = "请选择优惠券";
}
return res;
},
addCoupon: function(){
var self = this;
self.couponSelect(function (res) {
self.$parent.data.couponIds = [];
self.$parent.data.previewList = [];
for (var i=0; i<res.length; i++) {
self.$parent.data.couponIds.push(res[i].coupon_type_id);
self.$parent.data.previewList.push(res[i]);
}
}, self.$parent.data.couponIds);
},
delCoupon: function (index){
var self = this;
self.$parent.data.couponIds.splice(index, 1);
self.$parent.data.previewList.splice(index, 1);
},
couponSelect: function(callback, selectId) {
var self = this;
layui.use(['layer'], function () {
var url = ns.url("coupon://shop/coupon/couponselect", {
request_mode: 'iframe',
select_id: selectId.toString(),
app_module: ns.appModule,
site_id: ns.siteId
});
layer.open({
title: "优惠券选择",
type: 2,
area: ['1000px', '600px'],
fixed: false, //不固定
btn: ['保存', '返回'],
content: url,
yes: function (index, layero) {
var iframeWin = window[layero.find('iframe')[0]['name']];//得到iframe页的窗口对象执行iframe页的方法
iframeWin.selectCouponListener(function (obj) {
if (typeof callback == "string") {
try {
eval(callback + '(obj)');
layer.close(index);
} catch (e) {
console.error('回调函数' + callback + '未定义');
}
} else if (typeof callback == "function") {
callback(obj);
layer.close(index);
}
});
}
});
});
},
selectCouponStyle: function() {
var self = this;
layer.open({
type: 1,
title: '风格选择',
area:['930px','470px'],
btn: ['确定', '返回'],
content: $(".draggable-element[data-index='" + self.data.index + "'] .edit-attribute .coupon-list-style").html(),
success: function(layero, index) {
$(".layui-layer-content input[name='style']").val(self.data.style);
$(".layui-layer-content input[name='style_name']").val(self.data.styleName);
$("body").off("click", ".layui-layer-content .style-list-con-coupon .style-li-coupon").on("click", ".layui-layer-content .style-list-con-coupon .style-li-coupon", function () {
$(this).addClass("selected border-color").siblings().removeClass("selected border-color");
$(".layui-layer-content input[name='style']").val($(this).index() + 1);
$(".layui-layer-content input[name='style_name']").val($(this).find("span").text());
});
},
yes: function (index, layero) {
self.data.style = $(".layui-layer-content input[name='style']").val();
self.data.styleName = $(".layui-layer-content input[name='style_name']").val();
self.data.ifNeedBg = self.couponList[self.data.style-1].ifNeedBg;
self.data.couponBgColor = self.couponList[self.data.style-1].couponBgColor;
self.data.couponBgUrl = self.couponList[self.data.style-1].couponBgUrl;
self.data.couponType = self.couponList[self.data.style-1].couponType;
self.data.isName = self.couponList[self.data.style-1].isName;
self.data.nameColor = self.couponList[self.data.style-1].nameColor;
self.data.moneyColor = self.couponList[self.data.style-1].moneyColor;
self.data.limitColor = self.couponList[self.data.style-1].limitColor;
self.data.bgColor = self.couponList[self.data.style-1].bgColor;
self.data.btnStyle.textColor = self.couponList[self.data.style-1].btnStyle.textColor;
self.data.btnStyle.bgColor = self.couponList[self.data.style-1].btnStyle.bgColor;
self.data.btnStyle.text = self.couponList[self.data.style-1].btnStyle.text;
self.data.btnStyle.aroundRadius = self.couponList[self.data.style-1].btnStyle.aroundRadius;
self.data.btnStyle.isBgColor = self.couponList[self.data.style-1].btnStyle.isBgColor;
self.data.btnStyle.isAroundRadius = self.couponList[self.data.style-1].btnStyle.isAroundRadius;
self.data.btnStyle.maxLen = self.couponList[self.data.style-1].btnStyle.maxLen;
layer.closeAll()
}
});
}
}
});

View File

@@ -0,0 +1,67 @@
<?php
/**
*/
return [
// 自定义模板页面类型,格式:[ 'title' => '页面类型名称', 'name' => '页面标识', 'path' => '页面路径', 'value' => '页面数据json格式' ]
'template' => [],
// 后台自定义组件——装修
'util' => [
[
'name' => 'Coupon',
'title' => '优惠券',
'type' => 'PROMOTION',
'value' => '{"style":1,"sources":"initial","styleName":"风格一","couponIds":[],"count":6,"previewList":[],"nameColor":"","moneyColor":"#FFFFFF","limitColor":"#FFFFFF","btnStyle":{"maxLen": 4,"textColor":"#FFFFFF","bgColor":"","text":"立即领取","aroundRadius":0,"isBgColor":false,"isAroundRadius":false},"isName":false,"couponBgColor":"","couponBgUrl":"","couponType":"img","ifNeedBg":true}',
'sort' => '30000',
'support_diy_view' => '',
'max_count' => 0,
'icon' => 'iconfont iconyouhuiquan',
],
],
// 自定义页面路径
'link' => [
[
'name' => 'COUPON_LIST',
'title' => '优惠券',
'parent' => 'MARKETING_LINK',
'wap_url' => '',
'web_url' => '',
'sort' => 0,
'child_list' => [
[
'name' => 'COUPON_PREFECTURE',
'title' => '优惠券专区',
'wap_url' => '/pages_tool/goods/coupon',
'web_url' => '',
'sort' => 0
]
]
],
],
// 自定义图标库
'icon_library' => [],
// uni-app 组件,格式:[ 'name' => '组件名称/文件夹名称', 'path' => '文件路径/目录路径' ]多个逗号隔开自定义组件名称前缀必须是diy-,也可以引用第三方组件
'component' => [],
// uni-app 页面,多个逗号隔开
'pages' => [],
// 模板信息,格式:'title' => '模板名称', 'name' => '模板标识', 'cover' => '模板封面图', 'preview' => '模板预览图', 'desc' => '模板描述'
'info' => [],
// 主题风格配色格式可以自由定义扩展【在uni-app中通过this.themeStyle... 获取定义的颜色字段例如this.themeStyle.main_color】
'theme' => [],
// 自定义页面数据,格式:[ 'title' => '页面名称', 'name' => "页面标识", 'value' => [页面数据json格式] ]
'data' => []
];

View File

@@ -0,0 +1,29 @@
<?php
// 事件定义文件
return [
'bind' => [
],
'listen' => [
//展示活动
'ShowPromotion' => [
'addon\coupon\event\ShowPromotion',
],
//优惠券自动关闭
'CronCouponEnd' => [
'addon\coupon\event\CronCouponEnd',
],
// 优惠券活动定时结束
'CronCouponTypeEnd' => [
'addon\coupon\event\CronCouponTypeEnd',
],
//统计写入
'AddStat' => [
'addon\coupon\event\AddStat',
]
],
'subscribe' => [
],
];

View File

@@ -0,0 +1,21 @@
<?php
/**
*/
return [
'name' => 'coupon',
'title' => '优惠券',
'description' => '会员优惠券功能',
'type' => 'system', //插件类型 system :系统插件(自动安装), promotion:扩展营销插件 tool:工具插件
'status' => 1,
'author' => '',
'version' => '5.3.1',
'version_no' => '525231212001',
'content' => '',
];

View File

@@ -0,0 +1,72 @@
<?php
// +----------------------------------------------------------------------
// | 平台端菜单设置
// +----------------------------------------------------------------------
return [
[
'name' => 'PROMOTION_MERCH_MERCH_COUPON',
'title' => '优惠券',
'url' => 'coupon://merchant/coupon/lists',
'parent' => 'MERCH_SALE_ROOT',
'is_show' => 1,
'is_control' => 1,
'is_icon' => 0,
'picture' => '',
'picture_select' => '',
'sort' => 1,
'child_list' => [
[
'name' => 'PROMOTION_MERCH_COUPON_LIST',
'title' => '优惠券列表',
'url' => 'coupon://merchant/coupon/lists',
'is_show' => 1,
'is_control' => 1,
'sort' => 1,
'is_icon' => 0,
],
[
'name' => 'PROMOTION_MERCH_COUPON_DETAIL',
'title' => '优惠券详情',
'url' => 'coupon://merchant/coupon/detail',
'sort' => 1,
'is_show' => 0
],
[
'name' => 'PROMOTION_MERCH_COUPON_ADD',
'title' => '添加优惠券',
'url' => 'coupon://merchant/coupon/add',
'sort' => 1,
'is_show' => 0
],
[
'name' => 'PROMOTION_MERCH_COUPON_EDIT',
'title' => '编辑优惠券',
'url' => 'coupon://merchant/coupon/edit',
'sort' => 1,
'is_show' => 0
],
[
'name' => 'PROMOTION_MERCH_COUPON_CLOSE',
'title' => '关闭优惠券',
'url' => 'coupon://merchant/coupon/close',
'sort' => 1,
'is_show' => 0
],
[
'name' => 'PROMOTION_MERCH_COUPON_DELETE',
'title' => '删除优惠券',
'url' => 'coupon://merchant/coupon/delete',
'sort' => 1,
'is_show' => 0
],
[
'name' => 'PROMOTION_MERCH_COUPON_RECEIVE',
'title' => '优惠券领取记录',
'url' => 'coupon://merchant/coupon/receive',
'sort' => 1,
'is_show' => 0
],
]
],
];

View File

@@ -0,0 +1,79 @@
<?php
// +----------------------------------------------------------------------
// | 平台端菜单设置
// +----------------------------------------------------------------------
return [
[
'name' => 'PROMOTION_COUPON',
'title' => '优惠券',
'url' => 'coupon://shop/coupon/lists',
'parent' => 'SALE_ROOT',
'is_show' => 1,
'is_control' => 1,
'is_icon' => 0,
'picture' => '',
'picture_select' => '',
'sort' => 1,
'child_list' => [
[
'name' => 'PROMOTION_COUPON_LIST',
'title' => '优惠券列表',
'url' => 'coupon://shop/coupon/lists',
'is_show' => 1,
'is_control' => 1,
'sort' => 1,
'is_icon' => 0,
],
[
'name' => 'MEMBER_ACCOUNT_MEMBER_COUPON',
'title' => '会员优惠券',
'url' => 'shop/memberaccount/coupon',
'is_show' => 1,
'sort' => 2,
],
[
'name' => 'PROMOTION_COUPON_DETAIL',
'title' => '优惠券详情',
'url' => 'coupon://shop/coupon/detail',
'sort' => 1,
'is_show' => 0
],
[
'name' => 'PROMOTION_COUPON_ADD',
'title' => '添加优惠券',
'url' => 'coupon://shop/coupon/add',
'sort' => 1,
'is_show' => 0
],
[
'name' => 'PROMOTION_COUPON_EDIT',
'title' => '编辑优惠券',
'url' => 'coupon://shop/coupon/edit',
'sort' => 1,
'is_show' => 0
],
[
'name' => 'PROMOTION_COUPON_CLOSE',
'title' => '关闭优惠券',
'url' => 'coupon://shop/coupon/close',
'sort' => 1,
'is_show' => 0
],
[
'name' => 'PROMOTION_COUPON_DELETE',
'title' => '删除优惠券',
'url' => 'coupon://shop/coupon/delete',
'sort' => 1,
'is_show' => 0
],
[
'name' => 'PROMOTION_COUPON_RECEIVE',
'title' => '优惠券领取记录',
'url' => 'coupon://shop/coupon/receive',
'sort' => 1,
'is_show' => 0
],
]
],
];

View File

@@ -0,0 +1 @@
SET NAMES 'utf8';

View File

@@ -0,0 +1 @@
SET NAMES 'utf8';

View File

@@ -0,0 +1,55 @@
<?php
/**
*/
namespace addon\coupon\dict;
/**
* 订单公共属性
*/
class CouponDict
{
const normal = 1;
const used = 2;
const expire = 3;
const close = 4;
/**
* 优惠券状态
* @param $status
* @return string|string[]
*/
public static function getStatus($status = ''){
$list = [
self::normal => '待使用',
self::used => '已使用',
self::expire => '已过期',
self::close => '已关闭',
];
if($status) return $list[$status] ?? '';
return $list;
}
const all = 1;
const selected = 2;
const selected_out = 3;
public static function getGoodsType($type = ''){
$list = [
self::all => '全部商品参与',
self::selected => '指定商品参与',
self::selected_out => '指定不参与商品'
];
if($type) return $list[$type] ?? '';
return $list;
}
}

View File

@@ -0,0 +1,35 @@
<?php
/**
*/
namespace addon\coupon\event;
use addon\coupon\model\CouponStat;
/**
* 礼品卡统计
*/
class AddStat
{
public function handle($params)
{
$type = $params['type'];
if($type == 'receive_coupon'){
$coupon_stat_model = new CouponStat();
$res = $coupon_stat_model->addReceiveCouponStat($params['data']);
return $res;
}
}
}

View File

@@ -0,0 +1,27 @@
<?php
/**
*/
namespace addon\coupon\event;
use addon\coupon\model\Coupon;
/**
* 启动活动
*/
class CronCouponEnd
{
public function handle($params = [])
{
$coupon = new Coupon();
$res = $coupon->cronCouponEnd();
return $res;
}
}

View File

@@ -0,0 +1,27 @@
<?php
/**
*/
namespace addon\coupon\event;
use addon\coupon\model\CouponType;
/**
* 优惠券定时结束
*/
class CronCouponTypeEnd
{
public function handle($params = [])
{
$coupon = new CouponType();
$res = $coupon->couponCronEnd($params[ 'relate_id' ]);
return $res;
}
}

View File

@@ -0,0 +1,38 @@
<?php
/**
*/
namespace addon\coupon\event;
use app\model\system\Cron;
/**
* 应用安装
*/
class Install
{
/**
* 执行安装
*/
public function handle()
{
try {
execute_sql('addon/coupon/data/install.sql');
$cron = new Cron();
$cron->deleteCron([ ['event', '=', 'CronCouponEnd'] ]);
$cron->addCron(2, 1, '优惠券过期自动关闭', 'CronCouponEnd', time(), 0);
return success();
} catch (\Exception $e) {
return error('', $e->getMessage());
}
}
}

View File

@@ -0,0 +1,46 @@
<?php
/**
*/
namespace addon\coupon\event;
/**
* 店铺活动
*/
class ShowPromotion
{
/**
* 活动展示
* @return array
*/
public function handle()
{
$data = [
'shop' => [
[
//插件名称
'name' => 'coupon',
//展示分类根据平台端设置admin平台营销shop店铺营销member:会员营销, tool:应用工具)
'show_type' => 'shop',
//展示主题
'title' => '优惠券',
//展示介绍
'description' => '设置商家优惠券',
//展示图标
'icon' => 'addon/coupon/icon.png',
//跳转链接
'url' => 'coupon://shop/coupon/lists',
]
]
];
return $data;
}
}

View File

@@ -0,0 +1,32 @@
<?php
/**
*/
namespace addon\coupon\event;
/**
* 应用卸载
*/
class UnInstall
{
/**
* 执行卸载
*/
public function handle()
{
try {
return error('', "系统插件不允许删除");
//execute_sql('addon/coupon/data/uninstall.sql');
//return success();
} catch (\Exception $e) {
return error('', $e->getMessage());
}
}
}

BIN
src/addon/coupon/icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

View File

@@ -0,0 +1,357 @@
<?php
namespace addon\coupon\merchant\controller;
use addon\coupon\model\MemberCoupon;
use app\merchant\controller\BaseMerchant;
use addon\coupon\model\CouponType as CouponTypeModel;
use addon\coupon\model\Coupon as CouponModel;
use think\facade\Db;
/**
* 优惠券
* @author Administrator
*
*/
class Coupon extends BaseMerchant
{
/**
* 添加活动
*/
public function add()
{
if (request()->isJson()) {
$data = [
'site_id' => $this->site_id,
'merch_id' => $this->merch_id,
'coupon_name' => input('coupon_name', ''),//优惠券名称
'type' => input('type'),//优惠券类型
'goods_type' => input('goods_type', 1),
'goods_ids' => input('goods_ids', ''),
'sort' => input('sort', '0'), //优惠券排序
'money' => input('money', 0),//优惠券面额
'discount' => input('discount', 0),//优惠券折扣
'discount_limit' => input('discount_limit', 0),//最多优惠
'count' => input('count', ''),//发放数量
'max_fetch' => input('max_fetch', ''),//最大领取数量
'at_least' => input('at_least', ''),//满多少元可以使用
'end_time' => strtotime(input('end_time', '')),//活动结束时间
'image' => input('image', ''),//优惠券图片
'validity_type' => input('validity_type', ''),//有效期类型 0固定时间 1领取之日起
'fixed_term' => input('fixed_term', ''),//领取之日起N天内有效
'is_show' => input('is_show', 0),//是否允许直接领取 1:是 0否 允许直接领取用户才可以在手机端和PC端进行领取否则只能以活动的形式发放。
];
$coupon_type_model = new CouponTypeModel();
return $coupon_type_model->addCouponType($data);
} else {
return $this->fetch('coupon/add');
}
}
/**
* 编辑活动
*/
public function edit()
{
$coupon_type_model = new CouponTypeModel();
if (request()->isJson()) {
$data = [
'site_id' => $this->site_id,
'merch_id' => $this->merch_id,
'coupon_name' => input('coupon_name', ''),//优惠券名称
'type' => input('type'),//优惠券类型
'goods_type' => input('goods_type', 1),
'goods_ids' => input('goods_ids', ''),
'money' => input('money', 0),//优惠券面额
'sort' => input('sort', 0),//优惠券面额
'discount' => input('discount', 0),//优惠券折扣
'discount_limit' => input('discount_limit', 0),//最多优惠
'count' => input('count', ''),//发放数量
'max_fetch' => input('max_fetch', ''),//最大领取数量
'at_least' => input('at_least', ''),//满多少元可以使用
'end_time' => strtotime(input('end_time', '')),//活动结束时间
'image' => input('image', ''),//优惠券图片
'validity_type' => input('validity_type', ''),//有效期类型 0固定时间 1领取之日起
'fixed_term' => input('fixed_term', ''),//领取之日起N天内有效
'is_show' => input('is_show', 0),//是否允许直接领取 1:是 0否 允许直接领取用户才可以在手机端和PC端进行领取否则只能以活动的形式发放。
];
$coupon_type_id = input('coupon_type_id', 0);
return $coupon_type_model->editCouponType($data, $coupon_type_id);
} else {
$coupon_type_id = input('coupon_type_id', 0);
$this->assign('coupon_type_id', $coupon_type_id);
$coupon_type_info = $coupon_type_model->getCouponTypeInfo($coupon_type_id, $this->site_id);
if (empty($coupon_type_info[ 'data' ])) $this->error('未获取到优惠券数据', href_url('coupon://shop/coupon/lists'));
$this->assign('coupon_type_info', $coupon_type_info[ 'data' ][ 0 ]);
return $this->fetch('coupon/edit');
}
}
/**
* 活动详情
*/
public function detail()
{
$coupon_type_id = input('coupon_type_id', 0);
$coupon_type_model = new CouponTypeModel();
$coupon_type_info = $coupon_type_model->getCouponTypeInfo($coupon_type_id, $this->site_id)[ 'data' ] ?? [];
if (empty($coupon_type_info)) $this->error('未获取到优惠券数据', href_url('coupon://shop/coupon/lists'));
$this->assign('info', $coupon_type_info[ 0 ]);
$this->assign('get_type', ( new CouponModel() )->getCouponGetType());
return $this->fetch('coupon/detail');
}
/**
* 活动列表
*/
public function lists()
{
$coupon_type_model = new CouponTypeModel();
if (request()->isJson()) {
$page = input('page', 1);
$page_size = input('page_size', PAGE_LIST_ROWS);
$coupon_name = input('coupon_name', '');
$status = input('status', '');
$inventory_count = input('inventory_count', ''); // 剩余数量
$is_show = input('is_show', ''); // 是否显示
$condition = [];
if ($status !== '') {
$condition[] = [ 'status', '=', $status ];
}
$type = input('type');
if ($type) {
$condition[] = [ 'type', '=', $type ];
}
if ($is_show !== '') {
$condition[] = [ 'is_show', '=', $is_show ];
}
//类型
$validity_type = input('validity_type', '');
if ($validity_type !== '') {
$start_time = input('start_time', '');
$end_time = input('end_time', '');
switch ( $validity_type ) {
case 0: //固定
$condition[] = [ 'end_time', 'between', [ $start_time, $end_time ] ];
break;
case 1:
$condition[] = [ 'fixed_term', 'between', [ $start_time, $end_time ] ];
break;
case 2:
$condition[] = [ 'validity_type', '=', 2 ];
break;
}
}
if ($inventory_count) {
$condition[] = [ '', 'exp', Db::raw('(lead_count < count && count != -1) OR count = -1') ];
}
$condition[] = [ 'site_id', '=', $this->site_id ];
$condition[] = [ 'merch_id', '=', $this->merch_id ];
$condition[] = [ 'coupon_name', 'like', '%' . $coupon_name . '%' ];
$field = '*';
//排序
$link_sort = input('order', 'create_time');
$sort = input('sort', 'desc');
if ($link_sort == 'sort') {
$order_by = $link_sort . ' ' . $sort;
} else {
$order_by = $link_sort . ' ' . $sort . ',sort desc';
}
$res = $coupon_type_model->getCouponTypePageList($condition, $page, $page_size, $order_by, $field);
//获取优惠券状态
$coupon_type_status_arr = $coupon_type_model->getCouponTypeStatus();
foreach ($res[ 'data' ][ 'list' ] as $key => $val) {
$res[ 'data' ][ 'list' ][ $key ][ 'status_name' ] = $coupon_type_status_arr[ $val[ 'status' ] ];
}
return $res;
} else {
//优惠券状态
$coupon_type_status_arr = $coupon_type_model->getCouponTypeStatus();
$this->assign('coupon_type_status_arr', $coupon_type_status_arr);
return $this->fetch('coupon/lists');
}
}
/**
* 排序
* @return mixed
*/
public function couponSort()
{
$sort = input('sort', 0);
$coupon_type_id = input('coupon_type_id', 0);
$coupon_type_model = new CouponTypeModel();
return $coupon_type_model->couponSort($coupon_type_id, $sort);
}
/**
* 优惠券推广
*/
public function couponUrl()
{
$coupon_type_id = input('coupon_type_id', '');
$app_type = input('app_type', 'all');
$coupon_model = new couponTypeModel();
$res = $coupon_model->urlQrcode('/pages_tool/goods/coupon_receive', [ 'coupon_type_id' => $coupon_type_id ], 'coupon', $app_type, $this->site_id);
return $res;
}
/**
* 发放优惠券
*/
public function send()
{
if (request()->isJson()) {
$member_id = input('member_id', 0);
$coupon_data = json_decode(input('coupon_data', '[]'), true);
$get_type = input('get_type', 4);
if (empty($coupon_data)) {
return error('', 'REQUEST_COUPON_TYPE_ID');
}
$res = ( new CouponModel() )->giveCoupon($coupon_data, $this->site_id, $member_id, $get_type);
return $res;
}
}
/**
* 活动列表
*/
public function couponSelect()
{
$coupon_type_model = new CouponTypeModel();
if (request()->isJson()) {
$page = input('page', 1);
$page_size = input('page_size', PAGE_LIST_ROWS);
$coupon_name = input('coupon_name', '');
$condition[] = [ 'site_id', '=', $this->site_id ];
$condition[] = [ 'status', '=', 1 ];
$condition[] = [ 'coupon_name', 'like', '%' . $coupon_name . '%' ];
$order = 'create_time desc';
$field = '*';
$res = $coupon_type_model->getCouponTypePageList($condition, $page, $page_size, $order, $field);
//获取优惠券状态
$coupon_type_status_arr = $coupon_type_model->getCouponTypeStatus();
foreach ($res[ 'data' ][ 'list' ] as $key => $val) {
$res[ 'data' ][ 'list' ][ $key ][ 'status_name' ] = $coupon_type_status_arr[ $val[ 'status' ] ];
}
return $res;
} else {
//优惠券状态
$coupon_type_status_arr = $coupon_type_model->getCouponTypeStatus();
$this->assign('coupon_type_status_arr', $coupon_type_status_arr);
$select_id = input('select_id', '');
$this->assign('select_id', $select_id);
return $this->fetch('coupon/coupon_select');
}
}
/**
* 关闭活动
*/
public function close()
{
if (request()->isJson()) {
$coupon_type_id = input('coupon_type_id', 0);
$coupon_type_model = new CouponTypeModel();
return $coupon_type_model->closeCouponType($coupon_type_id, $this->site_id);
}
}
/**
* 删除活动
*/
public function delete()
{
if (request()->isJson()) {
$coupon_type_id = input('coupon_type_id', 0);
$coupon_type_model = new CouponTypeModel();
return $coupon_type_model->deleteCouponType($coupon_type_id, $this->site_id);
}
}
/**
* 优惠券领取记录
* */
public function receive()
{
$coupon_model = new CouponModel();
if (request()->isJson()) {
$page = input('page', 1);
$page_size = input('page_size', PAGE_LIST_ROWS);
$coupon_type_id = input('coupon_type_id', 0);
$state = input('state', '');
$condition = [];
$condition[] = [ 'npc.coupon_type_id', '=', $coupon_type_id ];
$condition[] = [ 'npc.site_id', '=', $this->site_id ];
if ($state !== '') {
$condition[] = [ 'npc.state', '=', $state ];
}
$res = $coupon_model->getMemberCouponPageList($condition, $page, $page_size);
return $res;
} else {
$coupon_type_id = input('coupon_type_id', 0);
$this->assign('coupon_type_id', $coupon_type_id);
$this->assign('get_type', $coupon_model->getCouponGetType());
return $this->fetch('coupon/receive');
}
}
/**
* 优惠券回收
*/
public function recoveryCoupon()
{
if (request()->isJson()) {
$coupon_list = json_decode(input('coupon_list', '[]'), true);
return ( new MemberCoupon() )->recoveryCoupon($coupon_list, $this->site_id);
}
}
/**
* 关闭活动(批量)
*/
public function closeAll()
{
if (request()->isJson()) {
$coupon_type_id = input('coupon_type_id', '');
$coupon_type_model = new CouponTypeModel();
foreach($coupon_type_id as $k => $v){
$res = $coupon_type_model->closeCouponType($v, $this->site_id);
}
return $res;
}
}
/**
* 删除活动(批量)
*/
public function deleteAll()
{
if (request()->isJson()) {
$coupon_type_id = input('coupon_type_id', '');
$coupon_type_model = new CouponTypeModel();
foreach($coupon_type_id as $k => $v){
$res = $coupon_type_model->deleteCouponType($v, $this->site_id);
}
return $res;
}
}
}

View File

@@ -0,0 +1,776 @@
<style>
.discount { display: flex; justify-content: space-between; height: 34px; line-height: 34px; padding: 5px 15px; background-color: #F6FBFD; border: 1px dashed #BCE8F1; }
.exchange-type {padding: 0 20px; position: relative;}
.exchange-type i{position: absolute;bottom: -10px;right: -1px;display: none;}
.exchange-type.border-color i{display: block;}
.form-wrap {position: relative;}
.custom-right {
position: absolute;
top: 20px;
left: 900px;
padding: 20px 0;
box-sizing: border-box;
overflow: hidden;
background-color: #fff;
height: 500px;
width: 600px;
}
.custom-right .phone {
min-width: 280px;
height: 600px;
background: url(__STATIC__/img/quan.png) no-repeat center;
background-size: contain;
position: relative;
overflow: auto;
padding-top: 30px;
box-sizing: border-box;
}
.custom-right .phone h2 {
position: absolute;
left: 250px;
top: 80px;
}
.item {
position: absolute;
top: 100px;
left: 165px;
width: 274px;
height: 100px;
display: flex;
background: url(__STATIC__/img/quan_bj.png) no-repeat center;
border-radius: 10px;
align-items: stretch;
overflow: hidden;
font-size: 13px;
}
.item-base {
position: relative;
width: 65px;
min-width: 65px;
text-align: center;
background-repeat: no-repeat;
background-size: 100% 100%;
padding: 10px 10px 0 10px;
}
.item-base p {
display: inline-block;
}
.item .item-base .aaa {
height: auto;
position: relative;
top: 50%;
right: 5px;
transform: translate(0, -50%);
}
.item-info {
margin:0 20px 0 0;
width: 100px;
}
.use_price {
line-height: 1;
color: #fff;
}
.use_condition {
color: #fff;
margin-top: 15px;
font-size: 12px;
}
.use_title {
margin-top: 10px !important;
}
.item-btn {
width: 50px;
min-width: 50px;
align-self: center;
position: relative;
}
.item-btn .btn{
font-size: 12px;
width: 40px;
height: 24px;
border-radius: 20px;
line-height: 24px;
margin-left: 20px;
text-align: center;
background-image: linear-gradient(to right, #fc6831, #ff4544);
color: #fff;
}
.max_price {
margin: 5px 0;
padding-bottom: 5px;
border-bottom: 1px dashed #d7d2d1;
font-size: 12px;
}
.use_time span {display: inline-block;font-size: 12px; color: #909399;}
.priceaaaa {
font-size: 16px;
}
.thistitle {
font-size: 14px;
}
.goods_num {padding-left: 20px;}
</style>
<div class="layui-form form-wrap">
<div class="layui-form-item">
<label class="layui-form-label"><span class="required">*</span>优惠券名称:</label>
<div class="layui-input-block">
<input type="text" name="coupon_name" lay-verify="required" autocomplete="off" class="layui-input len-long" maxlength="15">
</div>
</div>
<div class="layui-form">
<div class="layui-form-item">
<label class="layui-form-label">优惠券类型:</label>
<div class="layui-input-block">
<button class="layui-btn layui-btn-primary exchange-type border-color" data-status="reward">满减<i class="iconfont iconxuanzhong text-color"></i></button>
<button class="layui-btn layui-btn-primary exchange-type" data-status="discount">折扣<i class="iconfont iconxuanzhong text-color"></i></button>
<input type="hidden" name="type" value="reward">
</div>
</div>
</div>
<div class="layui-form-item" id="coupon_type">
<label class="layui-form-label"><span class="required">*</span>优惠券面额:</label>
<div class="layui-input-block">
<div class="layui-input-inline">
<input type="number" name="money" min="0" lay-verify="required|number|money|coupon_money" autocomplete="off" class="layui-input len-short" >
</div>
<span class="layui-form-mid"></span>
</div>
<div class="word-aux">
<p>价格不能小于等于0可保留两位小数</p>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label"><span class="required">*</span>满多少元可以使用:</label>
<div class="layui-input-block">
<div class="layui-input-inline">
<input type="number" name="at_least" min="0" lay-verify="required|number|money" autocomplete="off" class="layui-input len-short">
</div>
<span class="layui-form-mid"></span>
</div>
<div class="word-aux">
<p>价格不能小于0无门槛请设为0</p>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">是否允许直接领取:</label>
<div class="layui-input-block">
<input type="checkbox" name="is_show" lay-filter="is_show" value="1" lay-skin="switch" checked />
</div>
</div>
<div class="receive-limit">
<div class="layui-form-item">
<label class="layui-form-label"><span class="required">*</span>发放数量:</label>
<div class="layui-input-block">
<div class="layui-input-inline">
<input type="number" name="count" lay-verify="count" autocomplete="off" class="layui-input len-short">
</div>
<span class="layui-form-mid"></span>
</div>
<div class="word-aux">
<p>优惠券发放数量,没有之后不能领取或发放,-1为不限制发放数量</p>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label"><span class="required">*</span>最大领取数量:</label>
<div class="layui-input-block">
<div class="layui-input-inline">
<input type="number" name="max_fetch" min="0" value="1" lay-verify="max" autocomplete="off" class="layui-input len-short">
</div>
<span class="layui-form-mid"></span>
</div>
<div class="word-aux">
<p>数量不能小于0且必须为整数设置为0时可无限领取</p>
</div>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">优惠券图片:</label>
<div class="layui-input-block img-upload">
<div class="upload-img-block">
<div class="upload-img-box">
<div class="upload-default" id="couponImg">
<div class="upload">
<i class="iconfont iconshangchuan"></i>
<p>点击上传</p>
</div>
</div>
<div class="operation">
<div>
<i title="图片预览" class="iconfont iconreview js-preview" style="margin-right: 20px;"></i>
<i title="删除图片" class="layui-icon layui-icon-delete js-delete" ></i>
</div>
<div class="replace_img js-replace">点击替换</div>
</div>
<input type="hidden" name="image" />
</div>
</div>
</div>
<div class="word-aux">
<p>建议尺寸325*95像素图片上传默认不限制大小</p>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">有效期类型:</label>
<div class="layui-input-block">
<input type="radio" name="validity_type" value="0" lay-filter="filter" checked="checked" title="固定时间">
<input type="radio" name="validity_type" value="1" lay-filter="filter" title="领取之日起">
<input type="radio" name="validity_type" value="2" lay-filter="filter" title="长期有效">
</div>
</div>
<div class="layui-form-item end-time validity-type validity-type-0">
<label class="layui-form-label"></label>
<div class="layui-input-block">
<input type="text" name="end_time" lay-verify="time" id="end_time" class="layui-input len-mid" autocomplete="off" readonly>
</div>
</div>
<div class="layui-form-item fixed-term validity-type validity-type-1" style="display: none">
<label class="layui-form-label">领取之日起:</label>
<div class="layui-input-block">
<div class="layui-input-inline">
<input type="number" min="1" max="365" value="10" name="fixed_term" lay-verify="days" autocomplete="off" class="layui-input len-short">
</div>
<span class="layui-form-mid">天有效</span>
</div>
<div class="word-aux">
<p>不能小于0且必须为整数</p>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label"><span class="required">*</span>活动商品:</label>
<div class="layui-input-block">
<input type="radio" name="goods_type" lay-filter="goods_type" value="1" title="全部商品参与" checked>
<input type="radio" name="goods_type" lay-filter="goods_type" value="2" title="指定商品参与">
</div>
</div>
<div class="layui-form-item goods_list" style="display:none">
<label class="layui-form-label"></label>
<div class="layui-input-block">
<table id="selected_goods_list"></table>
<button class="layui-btn" onclick="addGoods()">选择商品</button> <span class="goods_num">已选商品(<span id="goods_num" class="text-color">0</span></span>
</div>
</div>
<input type="hidden" name="goods_ids">
<div class="form-row">
<button class="layui-btn" lay-submit lay-filter="save">保存</button>
<button class="layui-btn layui-btn-primary" onclick="back()">返回</button>
<a id="imageId"></a>
</div>
</div>
<!-- 操作 -->
<script type="text/html" id="operation">
<div class="table-btn">
<a class="layui-btn" onclick="delGoods({{d.goods_id}})">删除</a>
</div>
</script>
<script>
var submitRule, delRule;
var goods_list = [], selectedGoodsId = [], goods_id=[],table;
var saveData = null;
var totalUploadNum = 0;
var completeUploadNum = 0;
var upload;
$("body").off("change",'input[name="money"]').on("change",'input[name="money"]',function(){
let aa = $('input[name="money"]').val();
$('.priceaaaa').html('¥' + aa)
});
$("body").off("change",'input[name="discount"]').on("change",'input[name="discount"]',function(){
let bb = $('input[name="discount"]').val();
$('.pricebbbb').html(bb + ' 折 ')
});
$('input[name="at_least"]').change(function(){
let cc = $('input[name="at_least"]').val();
$('.use_price2').html(cc)
});
$('input[name="fixed_term"]').change(function(){
var time_time = $('input[name="fixed_term"]').val();
$('.time-bbb').html('有效期:领取之日起' + time_time + '日内有效');
});
$("body").off("change",'input[name="coupon_name"]').on("change",'input[name="coupon_name"]',function(){
let dd = $('input[name="coupon_name"]').val();
$('.thistitle').html(dd)
});
layui.use(['form', 'laydate','form'], function() {
var form = layui.form,
laydate = layui.laydate,
repeat_flag = false; //防重复标识
currentDate = new Date(); //当前时间
form.render();
currentDate.setDate(currentDate.getDate() + 10); //10天后的日期
form.on('switch(is_show)', function (data) {
if ($(data.elem).is(':checked')) {
$('.receive-limit').show();
} else {
$('.receive-limit').hide();
}
});
// 时间模块
laydate.render({
elem: '#end_time', //指定元素
type: 'datetime',
value: currentDate,
done: function(value, date, endDate){
$('.time-aaa').html('有效期:' + value);
}
});
var date = new Date(currentDate);
var y = date.getFullYear();
var m = date.getMonth() + 1;
m = m < 10 ? ('0' + m) : m;
var d = date.getDate();
d = d < 10 ? ('0' + d) : d;
var h = date.getHours();
var minute = date.getMinutes();
var second = date.getSeconds();
minute = minute < 10 ? ('0' + minute) : minute;
let time = y + '-' + m + '-' + d+' '+h+':'+minute+':'+second;
$('.time-aaa').html('有效期:' + time);
var time_time = $('input[name="fixed_term"]').val();
$('.time-bbb').html('有效期:领取之日起' + time_time + '日内有效');
renderTable(goods_list); // 初始化表格
//监听活动商品类型
form.on('radio(goods_type)', function(data) {
var value = data.value;
if (value == 1) {
$(".goods_list").hide();
$('.max_price').html('全场商品');
} else if (value == 2) {
$(".goods_list").show();
$('.max_price').html('指定商品');
} else if (value == 3) {
$(".goods_list").show();
$('.max_price').html('指定不参与商品');
}
});
// 监听单选按钮
form.on('radio(filter)', function(data) {
$('.validity-type').hide();
$('.validity-type-' + data.value).show();
});
/**
* 表单验证
*/
form.verify({
days: function(value) {
var validity_type = $('[name="validity_type"]:checked').val();
if (validity_type == 1) {
if (value%1 != 0) {
return '请输入整数';
}
if (value <= 0) {
return '有效天数不能小于等于0';
}
}
},
number: function (value) {
if (value < 0) {
return '请输入大于或等于0的数!'
}
},
int: function (value) {
if (value%1 != 0) {
return '请输入整数!'
}
if (value <= 0) {
return '请输入大于0的数!'
}
},
money: function (value) {
if(value < 0){
return '金额不能小于0'
}
var arrMen = value.split(".");
var val = 0;
if (arrMen.length == 2) {
val = arrMen[1];
}
if (val.length > 2) {
return '保留小数点后两位'
}
},
coupon_money: function (value) {
if(parseFloat(value) > 10000){
return '优惠券面额不能大于10000'
}
if(parseFloat(value) <= 0){
return '优惠券面额不能小于0'
}
},
time: function(value) {
var validity_type = $('[name="validity_type"]:checked').val();
if (validity_type == 0) {
var now_time = (new Date()).getTime();
var end_time = (new Date(value)).getTime();
if (now_time > end_time) {
return '结束时间不能小于当前时间!'
}
}
},
max: function(value) {
if ($('[name="is_show"]').is(':checked')) {
if (!/[\S]+/.test(value)) {
return '请输入最大领取数量';
}
var _count = $("input[name=count]").val();
if (_count != -1 && parseFloat(value) > parseFloat(_count)) {
return '最大领取数量不能超过发放数量!';
}
}
},
fl: function(value, item) {
var str = $(item).parents(".layui-form-item").find("label").text().split("*").join("");
str = str.substring(0, str.length - 1);
if (value < 1) {
return str + "不能小于1折";
}
if (value > 9.9) {
return str + "不能大于9.9折";
}
var arrMen = value.split(".");
var val = 0;
if (arrMen.length == 2) {
val = arrMen[1];
}
if (val.length > 2) {
return str + "最多可保留两位小数";
}
},
count: function(value){
if ($('[name="is_show"]').is(':checked')) {
if (!/[\S]+/.test(value)) {
return '请输入发放数量';
}
if (value%1 != 0) {
return '请输入整数';
}
if (value == 0 || value < -1) {
return '发放数量不能为0或小于-1';
}
}
}
});
upload = new Upload({
elem: '#couponImg',
auto:false,
bindAction:'#imageId',
callback: function(res) {
uploadComplete('image', res.data.pic_path);
}
});
function uploadComplete(field, pic_path) {
saveData.field[field] = pic_path;
completeUploadNum += 1;
if(completeUploadNum == totalUploadNum){
saveFunc();
}
}
function saveFunc(){
var data = saveData;
// 删除图片
if(!data.field.image) upload.delete();
$.ajax({
url: ns.url("coupon://merchant/coupon/add"),
data: data.field,
dataType: 'JSON',
type: 'POST',
success: function(res) {
repeat_flag = false;
if (res.code == 0) {
layer.confirm('添加成功', {
title:'操作提示',
btn: ['返回列表', '继续添加'],
closeBtn: 0,
yes: function(index, layero) {
location.hash = ns.hash("coupon://merchant/coupon/lists")
layer.close(index);
},
btn2: function(index, layero) {
listenerHash(); // 刷新页面
layer.close(index);
}
});
}else{
layer.msg(res.message);
}
}
});
}
/**
* 监听提交
*/
form.on('submit(save)', function(data) {
if (data.field.is_show == undefined) {
data.field.is_show = 0;
}
if(data.field.goods_type != 1){
if(data.field.goods_ids == ''){
layer.msg("请选择商品");
return;
}
}
if (repeat_flag) return;
repeat_flag = true;
saveData = data;
var obj = $("img.img_prev[data-prev='1']");
totalUploadNum = obj.length;
if(totalUploadNum > 0){
obj.each(function(){
var actionId = $(this).attr('data-action-id');
$(actionId).click();
})
}else{
saveFunc();
}
});
submitRule = function() {
var money = $("#money").val().trim(),
discount_money = $("#discount_money").val().trim();
if (Number(money) == "0" || Number(discount_money) == "0") {
layer.msg("满减金额不能为空!", {icon: 5, anim: 6});
return false;
}
if (Number(money) < 0 || Number(discount_money) < 0) {
layer.msg("金额不能小于0", {icon: 5, anim: 6});
return false;
}
if (Number(money) * 100 % 1 != 0 || Number(discount_money) * 100 % 1 != 0) {
layer.msg("金额最多保留小数点后两位!", {icon: 5, anim: 6});
return false;
}
for (var i=0; i<$(".discount-box .discount").length; i++) {
var money_num = $(".discount-box .discount").eq(i).find(".money-num").text();
if (money == money_num) {
layer.msg("该金额规则已添加,不可重复添加!");
return false;
}
}
var html = '<div class="discount form-row">'+
'<div class="discount-con">'+
'<p>单笔订单满<span class="required money-num">' + money + '</span>元,立减现金<span class="required discount_money-num">' + discount_money + '</span>元</p>'+
'</div>'+
'<div class="discount-del">'+
'<button class="layui-btn" onclick="delRule(this)">删除</button>'+
'</div>'+
'</div>';
$(".discount-box").append(html);
};
delRule = function(obj) {
$(obj).parent().parent().remove();
};
$(".exchange-type").click(function() {
$(this).addClass("border-color");
$(this).siblings("button").removeClass("border-color");
var type = $(this).attr('data-status');
var current_type = $("input[name='type']").val();
if(current_type == type){
return false;
}
$("input[name='type']").val(type);
var html = '';
if(type == 'reward'){
html += '<label class="layui-form-label"><span class="required">*</span>优惠券面额:</label>' +
'<div class="layui-input-block">' +
'<div class="layui-input-inline">' +
'<input type="number" name="money" min="0" lay-verify="required|number|money" autocomplete="off" class="layui-input len-short">' +
'</div>' +
'<span class="layui-form-mid">元</span>' +
'</div>' +
'<div class="word-aux">' +
'<p>价格不能小于0可保留两位小数</p>' +
'</div>';
$('.discount_limit').remove();
// $('body .pricebbbb').css("display","none");
// $('body .priceaaaa').css("display","block");
$("body").off("change",'input[name="money"]').on("change",'input[name="money"]',function(){
let aa = $('input[name="money"]').val();
$('.priceaaaa').html('¥' + aa)
});
}
if(type == 'discount'){
html += '<label class="layui-form-label"><span class="required">*</span>优惠券折扣:</label>' +
'<div class="layui-input-block">' +
'<div class="layui-input-inline">' +
'<input type="number" name="discount" min="1" lay-verify="required|fl" autocomplete="off" class="layui-input len-short">' +
'</div>' +
'<span class="layui-form-mid">折</span>' +
'</div>' +
'<div class="word-aux">' +
'<p>优惠券折扣不能小于1折且不可大于9.9折,可保留两位小数</p>' +
'</div>';
var discount_limit = '';
discount_limit += '<div class="layui-form-item discount_limit">' +
'<label class="layui-form-label">最多优惠:</label>' +
'<div class="layui-input-block">' +
'<div class="layui-input-inline">' +
'<input type="number" name="discount_limit" min="0" lay-verify="number|int" autocomplete="off" class="layui-input len-short">' +
'</div>' +
'<span class="layui-form-mid">元</span>' +
'</div>' +
'</div>';
$('#coupon_type').after(discount_limit);
// $('body .priceaaaa').css("display","none");
// $('body .pricebbbb').css("display","block");
$("body").off("change",'input[name="discount"]').on("change",'input[name="discount"]',function(){
let bb = $('input[name="discount"]').val();
$('.pricebbbb').html(bb + ' 折 ')
});
}
$('#coupon_type').html(html);
});
});
// 表格渲染
function renderTable(goods_list) {
//展示已知数据
table = new Table({
elem: '#selected_goods_list',
cols: [
[{
field: 'goods_name',
title: '商品名称',
unresize: 'false',
width: '50%'
}, {
field: 'price',
title: '商品价格(元)',
unresize: 'false',
align: 'right',
width: '20%',
templet: function (data) {
return '¥' + data.price;
}
}, {
field: 'goods_stock',
title: '库存',
unresize: 'false',
align: 'center',
width: '20%'
}, {
title: '操作',
toolbar: '#operation',
unresize: 'false',
align: 'right'
}],
],
data: goods_list,
});
}
// 删除选中商品
function delGoods(id) {
var i, j;
$.each(goods_list, function(index, item) {
var goods_id = item.goods_id;
if (id == Number(goods_id)) {
i = index;
}
});
goods_list.splice(i, 1);
renderTable(goods_list);
$.each(selectedGoodsId, function(index, item) {
if (id == Number(item)) {
j = index;
}
});
selectedGoodsId.splice(j, 1);
goods_id = selectedGoodsId;
$("#goods_num").html(selectedGoodsId.length);
$("input[name='goods_ids']").val(goods_id.toString());
}
/* 商品 */
function addGoods() {
goodsSelect(function (data) {
if (!Object.keys(data).length) return;
goods_id = [];
goods_list = [];
for (var key in data) {
goods_id.push(data[key].goods_id);
goods_list.push(data[key]);
}
renderTable(goods_list);
$("input[name='goods_ids']").val(goods_id.toString());
selectedGoodsId = goods_id;
$("#goods_num").html(selectedGoodsId.length)
}, selectedGoodsId, {mode: "spu", is_weigh: 1});
}
function back() {
location.hash = ns.hash("coupon://merchant/coupon/lists");
}
</script>

View File

@@ -0,0 +1,222 @@
<style>
.coupon-list {
padding: 0 20px;
}
</style>
<div class="coupon-list">
<div class="single-filter-box">
<div class="layui-form">
<div class="layui-input-inline">
<input type="text" name="coupon_name" placeholder="请输入优惠券名称" class="layui-input">
<button type="button" class="layui-btn layui-btn-primary" lay-submit lay-filter="search">
<i class="layui-icon">&#xe615;</i>
</button>
</div>
</div>
</div>
<!-- 列表 -->
<table id="coupon_list" lay-filter="coupon_list"></table>
</div>
<script type="text/html" id="checkbox">
{{# if($.inArray(d.coupon_type_id.toString(), selected_id_arr) != -1){ }}
<input type="checkbox" data-coupon-id="{{d.coupon_type_id}}" name="coupon_checkbox" lay-skin="primary" lay-filter="coupon_checkbox" checked>
{{# }else{ }}
<input type="checkbox" data-coupon-id="{{d.coupon_type_id}}" name="coupon_checkbox" lay-skin="primary" lay-filter="coupon_checkbox">
{{# } }}
<input type="hidden" data-coupon-id="{{d.coupon_type_id}}" name="coupon_json" value='{{ JSON.stringify(d) }}' />
</script>
<script>
var table, form, laytpl,
select_id = "{$select_id}", //选中商品id
selected_id_arr = select_id.length ? select_id.split(',') : [],
select_list = []; //选中商品所有数据
goodsIdArr = selected_id_arr;
$(function () {
layui.use(['form', 'laytpl'], function () {
form = layui.form;
laytpl = layui.laytpl;
table = new Table({
elem: '#coupon_list',
url: ns.url("coupon://shop/coupon/couponSelect"),
where: {
app_module: ns.appModule,
site_id: ns.siteId
},
cols: [
[
{
unresize: 'false',
width: '10%',
templet: '#checkbox'
}, {
field: 'coupon_name',
title: '优惠券名称',
unresize: 'false',
width: '20%'
}, {
field: 'reward',
title: '优惠券类型',
unresize: 'false',
width: '20%',
templet: function (data) {
if (data.type == 'reward') {
return '满减';
} else {
return '折扣';
}
}
}, {
field: 'goods_type',
title: '适用商品',
unresize: 'false',
width: '15%',
templet: function (data) {
if(data.goods_type == 1){
return '全部商品';
}else if(data.goods_type == 2){
return '指定商品';
}else if(data.goods_type == 3){
return '指定不参与商品';
}
}
}, {
title: '<span style="padding-right: 15px;">优惠金额/折扣</span>',
unresize: 'false',
width: '20%',
align: 'right',
templet: function (data) {
if (data.type == 'reward') {
return '<span style="padding-right: 15px;">¥' + data.money + '</span>';
} else {
return '<span style="padding-right: 15px;">' + data.discount + '折</span>';
}
}
}, {
field: 'count',
title: '发放数量',
unresize: 'false',
width: '15%'
}
]
],
callback: function () {
// 更新商品复选框状态
for (var i = 0; i < goodsIdArr.length; i++) {
var selected_coupons = $("input[name='coupon_checkbox'][data-coupon-id='" + goodsIdArr[i] + "']");
if (selected_coupons.length) {
$("input[name='coupon_checkbox'][data-coupon-id='" + goodsIdArr[i] + "']").prop("checked", true);
}
}
form.render();
initData();
}
});
/**
* 监听搜索
*/
form.on('submit(search)', function (data) {
data.field.app_module = ns.appModule;
data.field.site_id = ns.siteId;
table.reload({
page: {
curr: 1
},
where: data.field
});
});
// 勾选商品
form.on('checkbox(coupon_checkbox)', function(data) {
var coupon_id = $(data.elem).attr("data-coupon-id"), json = {};
form.render();
var couponLen = $("input[name='coupon_checkbox'][data-coupon-id="+ coupon_id +"]:checked").length;
if (couponLen){
json = JSON.parse($("input[name='coupon_json'][data-coupon-id="+ coupon_id +"]").val());
delete json.LAY_INDEX;
delete json.LAY_TABLE_INDEX;
delete json.create_time;
select_list.push(json);
goodsIdArr.push(coupon_id);
} else{
select_list.remove(coupon_id);
goodsIdArr.remove(coupon_id);
}
});
//初始化数据
function initData(){
var couponLen = $("input[name='coupon_checkbox'][data-coupon-id]:checked").length;
for (var i = 0; i < couponLen; i++){
var couponId = $("input[name='coupon_checkbox'][data-coupon-id]:checked").eq(i).attr("data-coupon-id");
var ident = false;
for (var k = 0; k < select_list.length; k++){
if(select_list[k].coupon_type_id == couponId){
ident = true;
break;
}
}
if (ident) return;
json = JSON.parse($("input[name='coupon_json'][data-coupon-id="+ couponId +"]").val());
delete json.LAY_INDEX;
delete json.LAY_TABLE_INDEX;
delete json.create_time;
select_list.push(json);
}
}
});
});
function selectCouponListener(callback) {
var res = select_list;
callback(res);
}
Array.prototype.indexOf = function(val) {
for (var i = 0; i < this.length; i++) {
if (this[i].coupon_type_id){
if (this[i].coupon_type_id == parseInt(val)) return i;
} else {
if (this[i] == val) return i;
}
}
return -1;
};
Array.prototype.remove = function(val) {
var index = this.indexOf(val);
if (index > -1) {
this.splice(index, 1);
}
};
select_list.__proto__ = Array.prototype;
function removeDuplicates(arr){
if (!Array.isArray(arr)) {
console.log('type error!');
return
}
var array = [];
for (var i = 0; i < arr.length; i++) {
if (array.indexOf(arr[i]) === -1) {
array.push(arr[i])
}
}
return array;
}
</script>

View File

@@ -0,0 +1,403 @@
<link rel="stylesheet" href="STATIC_CSS/promotion_detail.css">
<style>
.layui-tab-content {padding: 0}
</style>
<div class="layui-card card-common card-brief">
<div class="layui-card-header">
<div>
<span class="card-title">基本信息</span>
</div>
</div>
<div class="layui-card-body">
<div class="promotion-view">
<div class="promotion-view-item">
<label>优惠券名称:</label>
<span>{$info.coupon_name}</span>
</div>
<div class="promotion-view-item">
<label>优惠券类型:</label>
<span>{if $info.type == 'reward'} 满减 {else /} 折扣 {/if}</span>
</div>
<div class="promotion-view-item">
<label>{if $info.type == 'reward'} 优惠券面额 {else /} 优惠券折扣 {/if}</label>
<span>{if $info.type == 'reward'} ¥ {$info.money} {else /} {$info.discount} 折 {/if}</span>
</div>
{if $info.type == 'discount'}
{if $info.discount_limit != 0}
<div class="promotion-view-item">
<label>最多优惠:</label>
<span>¥ {$info.discount_limit}</span>
</div>
{/if}
{/if}
<div class="promotion-view-item">
<label>发放数量:</label>
<span>
{if $info.count > 0 }
{$info.count} 张
{else /}
无限制
{/if}
</span>
</div>
<div class="promotion-view-item">
<label>最大领取数量:</label>
<span>{$info.max_fetch} 张</span>
</div>
<div class="promotion-view-item">
<label>使用门槛:</label>
<span>{$info.at_least} 元</span>
</div>
<div class="promotion-view-item">
<label>有效期:</label>
<span>
{if $info.validity_type == 0}
{:date('Y-m-d H:i:s',$info.end_time)}
{elseif $info.validity_type == 1 }
领取后 {$info.fixed_term} 天有效
{else /}
长期有效
{/if}
</span>
</div>
<div class="promotion-view-item">
<label>活动商品:</label>
{if $info.goods_type == 1}
<span>全部商品参与</span>
{elseif $info.goods_type == 2}
<span>指定商品</span>
{elseif $info.goods_type == 3}
<span>指定不参与商品</span>
{/if}
</div>
</div>
<div class="promotion-view">
<div class="promotion-view-item-line">
<label class="promotion-view-item-custom-label">优惠券图片:</label>
<div class="promotion-view-item-custom-box img-upload">
<div class="upload-img-block icon">
<div class="upload-img-box" id="couponImg">
{if condition="$info.image"}
<img layer-src src="{:img($info.image)}" />
{/if}
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="layui-card card-common card-brief">
<div class="layui-card-header">
<div>
<span class="card-title">数据统计</span>
</div>
</div>
<div class="layui-card-body">
<div class="promotion-stat-view todo-list">
<div class="promotion-stat-item" >
<div class="promotion-stat-item-title">发放数</div>
<div class="promotion-stat-item-value">{$info.count}</div>
</div>
<div class="promotion-stat-item" >
<div class="promotion-stat-item-title">领取数</div>
<div class="promotion-stat-item-value">{$info.lead_count}</div>
</div>
<div class="promotion-stat-item" >
<div class="promotion-stat-item-title">使用数</div>
<div class="promotion-stat-item-value">{$info.used_count}</div>
</div>
</div>
</div>
</div>
<div class="layui-card card-common card-brief">
<div class="layui-card-header">
<div>
<span class="card-title">领取记录</span>
</div>
</div>
<div class="layui-card-body layui-tab table-tab" lay-filter="coupon_tab">
<ul class="layui-tab-title">
<li class="layui-this" lay-id="">全部</li>
<li lay-id="1">已领取</li>
<li lay-id="2">已使用</li>
<li lay-id="3">已过期</li>
</ul>
<div class="layui-tab-content">
<!-- 列表 -->
<table id="coupon" lay-filter="coupon"></table>
</div>
</div>
</div>
{if $info.goods_type != 1}
<div class="layui-card card-common card-brief">
<div class="layui-card-header">
<div>
{if $info.goods_type == 2}
<span class="card-title">指定商品</span>
{elseif $info.goods_type == 3}
<span class="card-title">指定不参与商品</span>
{/if}
</div>
</div>
<div class="layui-card-body">
<div class='promotion-view-list'>
<table id="promotion_list"></table>
</div>
</div>
</div>
{/if}
<script type='text/html' id="promotion_list_item_box_html">
<div class="promotion-list-item-title">
<div class="promotion-list-item-title-icon">
<img src="{{ ns.img(d.goods_image) }}" alt="">
</div>
<p class="promotion-list-item-title-name multi-line-hiding">{{ d.goods_name }}</p>
</div>
</script>
<script type="text/html" id="memberInfo">
<div class='table-title'>
<div class='title-pic'>
<img layer-src src="{{ns.img(d.headimg)}}" onerror="this.src = '{:img('public/static/img/default_img/head.png')}' ">
</div>
<div class='title-content' onclick="location.hash = ns.hash('shop/member/editmember?member_id={{d.member_id}}')">
<p class="layui-elip">{{d.nickname}}</p>
<p class="layui-elip">{{d.mobile}}</p>
</div>
</div>
</script>
<script type="text/html" id="operation">
<div class="table-btn" align="right">
{{# if(d.state == 1){ }}
<a class="layui-btn" lay-event="recovery">回收</a>
{{# } }}
</div>
</script>
<script type="text/html" id="toolbarOperation">
<button class="layui-btn layui-btn-primary" lay-event="recovery">批量回收</button>
</script>
<script type="text/html" id="batchOperation">
<button class="layui-btn layui-btn-primary" lay-event="recovery">批量回收</button>
</script>
<script>
var promotion_list = {:json_encode($info.goods_list, JSON_UNESCAPED_UNICODE)},
coupon_type_id = {$info.coupon_type_id},
element,table,
getType = {:json_encode($get_type)};
layui.use('element', function() {
element = layui.element;
element.on('tab(coupon_tab)', function(){
table.reload({
page: {curr: 1},
where: {'state': this.getAttribute('lay-id'),"coupon_type_id": coupon_type_id},
})
});
new Table({
elem: '#promotion_list',
cols: [
[{
field: 'goods_name',
title: '商品名称',
unresize: 'false',
width: '60%',
templet: '#promotion_list_item_box_html'
}, {
field: 'price',
title: '商品价格(元)',
unresize: 'false',
align: 'right',
width: '20%',
templet: function(data) {
return '¥' + data.price;
}
}, {
field: 'goods_stock',
title: '库存',
unresize: 'false',
align: 'center',
width: '20%'
}],
],
data: promotion_list
});
table = new Table({
elem: '#coupon',
url: ns.url("coupon://shop/coupon/receive"),
where: {
"coupon_type_id": coupon_type_id
},
cols: [
[{
type: 'checkbox',
width: '3%',
unresize: 'false'
},{
templet: '#memberInfo',
title: '会员信息',
width: '20%',
unresize: 'false'
}, {
field: 'coupon_name',
title: '优惠券',
width: '10%',
unresize: 'false',
templet: function(data) {
return `<a href="`+ ns.href('coupon://shop/coupon/detail', {coupon_type_id: data.coupon_type_id }) +`" target="_blank" class="text-color">`+ data.coupon_name +`</a>`;
}
}, {
title: '类型',
width: '10%',
unresize: 'false',
templet: function (data) {
return data.type == 'reward' ? '满减券' : '折扣券';
}
}, {
title: '获取方式',
width: '10%',
unresize: 'false',
templet: function(data) {
return getType[data.get_type] ? getType[data.get_type] : '';
}
}, {
title: '状态',
width: '12%',
unresize: 'false',
templet: function (data) {
var str = '';
switch (data.state) {
case 1:
str = '已领取';
break;
case 2:
str = '已使用';
break;
case 3:
str = '已过期';
break;
}
return str;
}
}, {
title: '领取时间',
width: '15%',
unresize: 'false',
templet: function(data) {
return ns.time_to_date(data.fetch_time);
}
}, {
title: '使用时间',
width: '15%',
templet: function(data) {
return data.use_time ? ns.time_to_date(data.use_time) : '';
}
},
{
title: '操作',
width: '5%',
templet: '#operation'
}
]
],
parseData: function(data){
data.data.list = data.data.list.map(function (item) {
item.LAY_DISABLED = item.state != 1;
return item;
})
return {
"code": data.code,
"msg": data.message,
"count": data.data.count,
"data": data.data.list
};
},
toolbar: '#toolbarOperation',
bottomToolbar: "#batchOperation"
});
table.tool(function(obj) {
var data = obj.data;
switch (obj.event) {
case 'recovery': //编辑
recoveryCoupon([{coupon_type_id: data.coupon_type_id, coupon_id: data.coupon_id}]);
break;
}
})
/**
* 批量操作
*/
table.bottomToolbar(function(obj) {
if (obj.data.length < 1) {
layer.msg('请选择要操作的数据');
return;
}
switch (obj.event) {
case "recovery":
var id_array = new Array();
for (i in obj.data) id_array.push({coupon_type_id: obj.data[i].coupon_type_id, coupon_id: obj.data[i].coupon_id});
recoveryCoupon(id_array);
break;
}
});
/**
* 批量操作
*/
table.toolbar(function(obj) {
if (obj.data.length < 1) {
layer.msg('请选择要操作的数据');
return;
}
switch (obj.event) {
case "del":
var id_array = new Array();
for (i in obj.data) id_array.push({coupon_type_id: obj.data[i].coupon_type_id, coupon_id: obj.data[i].coupon_id});
recoveryCoupon(id_array);
break;
}
});
});
function recoveryCoupon(data) {
layer.confirm('回收将会收回会员领取的待使用的优惠券,已使用的将无法回收,确定要回收所选优惠券吗?', function(index) {
layer.close(index);
$.ajax({
url: ns.url("coupon://shop/coupon/recoverycoupon"),
data: {
coupon_list: JSON.stringify(data)
},
dataType: 'JSON',
type: 'POST',
success: function(res) {
layer.msg(res.message);
if (res.code == 0) {
table.reload();
}
}
});
})
}
</script>

View File

@@ -0,0 +1,813 @@
<style>
.discount {
display: flex;
justify-content: space-between;
height: 34px;
line-height: 34px;
padding: 5px 15px;
background-color: #F6FBFD;
border: 1px dashed #BCE8F1;
}
.exchange-type {
padding: 0 20px;
position: relative;
}
.exchange-type i{position: absolute;bottom: -10px;right: -1px;display: none;}
.exchange-type.border-color i{display: block;}
.form-wrap {
position: relative;
}
.custom-right {
position: absolute;
top: 150px;
left: 900px;
padding: 20px 0;
box-sizing: border-box;
overflow: hidden;
background-color: #fff;
height: 500px;
width: 600px;
}
.custom-right .phone {
min-width: 280px;
height: 600px;
background: url(__STATIC__/img/quan.png) no-repeat center;
background-size: contain;
position: relative;
overflow: auto;
padding-top: 30px;
box-sizing: border-box;
}
.custom-right .phone h2 {
position: absolute;
left: 250px;
top: 80px;
}
.item {
position: absolute;
top: 100px;
left: 165px;
width: 274px;
height: 100px;
display: flex;
background: url(__STATIC__/img/quan_bj.png) no-repeat center;
border-radius: 10px;
align-items: stretch;
overflow: hidden;
font-size: 13px;
}
.item-base {
position: relative;
width: 65px;
min-width: 65px;
text-align: center;
background-repeat: no-repeat;
background-size: 100% 100%;
padding: 10px 10px 0 10px;
}
.item-base p {
display: inline-block;
}
.item .item-base .aaa {
height: auto;
position: relative;
top: 50%;
right: 5px;
transform: translate(0, -50%);
}
.item-info {
margin: 0 20px 0 0;
width: 100px;
}
.use_price {
line-height: 1;
color: #fff;
}
.use_condition {
color: #fff;
margin-top: 15px;
font-size: 12px;
}
.use_title {
margin-top: 10px !important;
}
.item-btn {
width: 50px;
min-width: 50px;
align-self: center;
position: relative;
}
.item-btn .btn {
font-size: 12px;
width: 40px;
height: 24px;
border-radius: 20px;
line-height: 24px;
margin-left: 20px;
text-align: center;
background-image: linear-gradient(to right, #fc6831, #ff4544);
color: #fff;
}
.max_price {
margin: 5px 0;
padding-bottom: 5px;
border-bottom: 1px dashed #d7d2d1;
font-size: 12px;
}
.use_time span {
display: inline-block;
font-size: 12px;
color: #909399;
}
.priceaaaa {
font-size: 16px;
}
.thistitle {
font-size: 14px;
}
</style>
<div class="layui-form form-wrap">
<div class="layui-form-item">
<label class="layui-form-label"><span class="required">*</span>优惠券名称:</label>
<div class="layui-input-block">
<input type="text" name="coupon_name" value="{$coupon_type_info.coupon_name}" lay-verify="required" autocomplete="off" class="layui-input len-long" maxlength="15">
</div>
</div>
<div class="layui-form">
<div class="layui-form-item">
<label class="layui-form-label">优惠券类型:</label>
<div class="layui-input-block">
<button class="layui-btn layui-btn-primary exchange-type {if $coupon_type_info.type == 'reward'} border-color {/if}" data-status="reward">满减<i class="iconfont iconxuanzhong text-color"></i></button>
<button class="layui-btn layui-btn-primary exchange-type {if $coupon_type_info.type == 'discount'} border-color {/if}" data-status="discount">折扣<i class="iconfont iconxuanzhong text-color"></i></button>
<input type="hidden" name="type" value="{$coupon_type_info.type}">
</div>
</div>
</div>
<div class="layui-form-item" id="coupon_type">
{if $coupon_type_info.type == 'reward'}
<label class="layui-form-label"><span class="required">*</span>优惠券面额:</label>
<div class="layui-input-block">
<div class="layui-input-inline">
<input type="number" name="money" value="{$coupon_type_info.money}" lay-verify="required|number|money|coupon_money" autocomplete="off" class="layui-input len-short">
</div>
<span class="layui-form-mid"></span>
</div>
<div class="word-aux">
<p>价格不能小于等于0可保留两位小数</p>
</div>
{else /}
<label class="layui-form-label"><span class="required">*</span>优惠券折扣:</label>
<div class="layui-input-block">
<div class="layui-input-inline">
<input type="number" name="discount" min="1" value="{$coupon_type_info.discount}" lay-verify="required|fl" autocomplete="off" class="layui-input len-short">
</div>
<span class="layui-form-mid"></span>
</div>
<div class="word-aux">
<p>优惠券折扣不能小于1折且不可大于9.9折,可保留两位小数</p>
</div>
{/if}
</div>
{if $coupon_type_info.type == 'discount'}
<div class="layui-form-item discount_limit">
<label class="layui-form-label">最多优惠:</label>
<div class="layui-input-block">
<div class="layui-input-inline">
<input type="number" name="discount_limit" min=0 value="{$coupon_type_info.discount_limit}" lay-verify="number|int" autocomplete="off" class="layui-input len-short">
</div>
<span class="layui-form-mid"></span>
</div>
</div>
{/if}
<div class="layui-form-item">
<label class="layui-form-label"><span class="required">*</span>满多少元可以使用:</label>
<div class="layui-input-block">
<div class="layui-input-inline">
<input type="number" name="at_least" value="{$coupon_type_info.at_least}" lay-verify="required|number|money" autocomplete="off" class="layui-input len-short">
</div>
<span class="layui-form-mid"></span>
</div>
<div class="word-aux">
<p>价格不能小于0可保留两位小数</p>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">是否允许直接领取:</label>
<div class="layui-input-block">
<input type="checkbox" name="is_show" min=0 lay-filter="is_show" value="1" lay-skin="switch" {if condition="$coupon_type_info.is_show == 1" }checked{/if} />
</div>
</div>
<div class="receive-limit" {if $coupon_type_info.is_show eq 0}style="display:none;"{/if}>
<div class="layui-form-item">
<label class="layui-form-label"><span class="required">*</span>发放数量:</label>
<div class="layui-input-block">
<div class="layui-input-inline">
<input type="number" name="count" min=0 value="{$coupon_type_info.count}" lay-verify="count" autocomplete="off" class="layui-input len-short" {if $coupon_type_info.count == -1}disabled style="cursor:not-allowed"{/if}>
</div>
<span class="layui-form-mid"></span>
</div>
<div class="word-aux">
<p>优惠券发放数量,没有之后不能领取或发放,-1为不限制发放数量,发放数量只能增加不能减少。</p>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label"><span class="required">*</span>最大领取数量:</label>
<div class="layui-input-block">
<div class="layui-input-inline">
<input type="number" name="max_fetch" min=0 value="{$coupon_type_info.max_fetch}" lay-verify="max" autocomplete="off" class="layui-input len-short">
</div>
<span class="layui-form-mid"></span>
</div>
<div class="word-aux">
<p>数量不能小于0且必须为整数设置为0时可无限领取</p>
</div>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">优惠券图片:</label>
<div class="layui-input-block img-upload">
<div class="upload-img-block">
<div class="upload-img-box {notempty name=" $coupon_type_info['image']"}hover{/notempty}">
<div class="upload-default " id="couponImg">
{if condition="$coupon_type_info.image"}
<div id="preview_couponImg" class="preview_img">
<img layer-src src="{:img($coupon_type_info.image)}" class="img_prev" />
</div>
{else/}
<div class="upload">
<i class="iconfont iconshangchuan"></i>
<p>点击上传</p>
</div>
{/if}
</div>
<div class="operation">
<div>
<i title="图片预览" class="iconfont iconreview js-preview" style="margin-right: 20px;"></i>
<i title="删除图片" class="layui-icon layui-icon-delete js-delete"></i>
</div>
<div class="replace_img js-replace">点击替换</div>
</div>
<input type="hidden" class="layui-input" name="image" value="{$coupon_type_info.image}" />
</div>
</div>
</div>
<div class="word-aux">
<p>建议尺寸325*95像素图片上传默认不限制大小</p>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">有效期类型:</label>
<div class="layui-input-block">
<input type="radio" name="validity_type" value="0" lay-filter="filter" title="固定时间" {if condition="$coupon_type_info.validity_type == 0" }checked{/if}>
<input type="radio" name="validity_type" value="1" lay-filter="filter" title="领取之日起" {if condition="$coupon_type_info.validity_type == 1" }checked{/if}>
<input type="radio" name="validity_type" value="2" lay-filter="filter" title="长期有效" {if condition="$coupon_type_info.validity_type == 2" }checked{/if}>
</div>
</div>
<div class="layui-form-item end-time validity-type validity-type-0">
<label class="layui-form-label ">活动结束时间:</label>
<div class="layui-input-block">
<input type="text" name="end_time" value="{:date('Y-m-d H:i:s',$coupon_type_info.end_time)}" lay-verify="time" id="end_time" class="layui-input len-mid" readonly>
</div>
</div>
<div class="layui-form-item fixed-term validity-type validity-type-1">
<label class="layui-form-label">领取后几天有效:</label>
<div class="layui-input-block">
<div class="layui-input-inline">
<input type="number" name="fixed_term" value="{$coupon_type_info.fixed_term}" lay-verify="days" autocomplete="off" class="layui-input len-short">
</div>
<span class="layui-form-mid"></span>
</div>
<div class="word-aux">
<p>不能小于0且必须为整数</p>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label"><span class="required">*</span>活动商品:</label>
<div class="layui-input-block">
<input type="radio" name="goods_type" lay-filter="goods_type" value="1" title="全部商品参与" {if $coupon_type_info.goods_type==1} checked {/if}>
<input type="radio" name="goods_type" lay-filter="goods_type" value="2" title="指定商品参与" {if $coupon_type_info.goods_type==2} checked {/if}>
</div>
</div>
<div class="layui-form-item goods_list" {if $coupon_type_info.goods_type == 1}style="display:none"{/if}>
<label class="layui-form-label"></label>
<div class="layui-input-block">
<table id="selected_sku_list"></table>
<button class="layui-btn" onclick="addGoods()">选择商品</button>
<span class="goods_num">已选商品(<span id="goods_num" class="text-color">{$coupon_type_info.goods_list_count}</span></span>
</div>
</div>
<input type="hidden" name="goods_ids">
<div class="form-row">
<button class="layui-btn" lay-submit lay-filter="save">保存</button>
<button class="layui-btn layui-btn-primary" onclick="back()">返回</button>
<a id="imageId"></a>
</div>
<input type="hidden" name="site_id" value="{$coupon_type_info.site_id}" />
<input type="hidden" name="coupon_type_id" value="{$coupon_type_info.coupon_type_id}" />
</div>
<!-- 操作 -->
<script type="text/html" id="operation">
<div class="table-btn">
<a class="layui-btn" onclick="delGoods({{d.goods_id}})">删除</a>
</div>
</script>
<script>
var validity_type = $("input[name='validity_type']:checked").val();
var saveData = null;
var totalUploadNum = 0;
var completeUploadNum = 0;
var upload;
$('.validity-type').hide();
$('.validity-type-' + validity_type).show();
var delRule, selectedGoodsId = [], goods_id = [], table;
var goods_list = {:json_encode($coupon_type_info.goods_list, JSON_UNESCAPED_UNICODE)};
$("body").off("change", 'input[name="money"]').on("change", 'input[name="money"]', function() {
let aa = $('input[name="money"]').val();
$('.priceaaaa').html('¥' + aa)
});
$("body").off("change", 'input[name="discount"]').on("change", 'input[name="discount"]', function() {
let bb = $('input[name="discount"]').val();
$('.pricebbbb').html(bb + ' 折 ')
});
$('input[name="at_least"]').change(function() {
let cc = $('input[name="at_least"]').val();
$('.use_price2').html(cc)
})
$('input[name="fixed_term"]').change(function() {
var time_time = $('input[name="fixed_term"]').val();
$('.time-bbb').html('有效期:领取之日起' + time_time + '日内有效');
})
$("body").off("change", 'input[name="coupon_name"]').on("change", 'input[name="coupon_name"]', function() {
let dd = $('input[name="coupon_name"]').val();
$('.thistitle').html(dd)
});
$.each(goods_list, function(index, item) {
var id = item.goods_id;
selectedGoodsId.push(id);
goods_id.push(id);
});
$("input[name='goods_ids']").val(goods_id.toString());
layui.use(['form', 'laydate'], function() {
var form = layui.form,
laydate = layui.laydate,
repeat_flag = false, //防重复标识
currentDate = new Date(); //当前时间
form.render();
form.on('switch(is_show)', function (data) {
if ($(data.elem).is(':checked')) {
$('.receive-limit').show();
} else {
$('.receive-limit').hide();
}
});
// 时间模块
laydate.render({
elem: '#end_time', //指定元素
type: 'datetime',
// value: currentDate,
done: function(value, date, endDate) {
$('.time-aaa').html('有效期:' + value);
}
});
var date = new Date(currentDate);
var y = date.getFullYear();
var m = date.getMonth() + 1;
m = m < 10 ? ('0' + m) : m;
var d = date.getDate();
d = d < 10 ? ('0' + d) : d;
var h = date.getHours();
var minute = date.getMinutes();
var second = date.getSeconds();
minute = minute < 10 ? ('0' + minute) : minute;
let time = y + '-' + m + '-' + d + ' ' + h + ':' + minute + ':' + second;
$('.time-aaa').html('有效期:' + time);
var time_time = $('input[name="fixed_term"]').val();
$('.time-bbb').html('有效期:领取之日起' + time_time + '日内有效');
renderTable(goods_list); // 初始化表格
//监听活动商品类型
form.on('radio(goods_type)', function(data) {
var value = data.value;
if (value == 1) {
$(".goods_list").hide();
$('.max_price').html('全场商品');
} else if (value == 2) {
$(".goods_list").show();
$('.max_price').html('指定商品');
} else if (value == 3) {
$(".goods_list").show();
$('.max_price').html('指定不参与商品');
}
});
// 监听单选按钮
form.on('radio(filter)', function(data) {
$('.validity-type').hide();
$('.validity-type-' + data.value).show();
});
/**
* 表单验证
*/
form.verify({
days: function (value) {
var validity_type = $('[name="validity_type"]:checked').val();
if (validity_type == 1) {
if (value % 1 != 0) {
return '请输入整数';
}
if (value <= 0) {
return '有效天数不能小于等于0';
}
}
},
number: function (value) {
if (value < 0) {
return '请输入不小于0的数!'
}
},
coupon_money: function (value) {
if (parseFloat(value) > 10000) {
return '优惠券面额不能大于10000'
}
if(parseFloat(value) <= 0){
return '优惠券面额不能小于0'
}
},
int: function (value) {
if (value % 1 != 0) {
return '请输入整数!'
}
if (value < 0) {
return '请输入大于0的数!'
}
},
money: function (value) {
if(value < 0){
return '金额不能小于0'
}
var arrMen = value.split(".");
var val = 0;
if (arrMen.length == 2) {
val = arrMen[1];
}
if (val.length > 2) {
return '保留小数点后两位'
}
},
time: function (value) {
var validity_type = $('[name="validity_type"]:checked').val();
if (validity_type == 0) {
var now_time = (new Date()).getTime();
var end_time = (new Date(value)).getTime();
if (now_time > end_time) {
return '结束时间不能小于当前时间!'
}
}
},
max: function (value) {
if ($('[name="is_show"]').is(':checked')) {
if (!/[\S]+/.test(value)) {
return '请输入最大领取数量';
}
var _count = $("input[name=count]").val();
if (_count != -1 && parseFloat(value) > parseFloat(_count)) {
return '最大领取数量不能超过发放数量!';
}
}
},
fl: function (value, item) {
var str = $(item).parents(".layui-form-item").find("label").text().split("*").join(
"");
str = str.substring(0, str.length - 1);
if (value < 1) {
return str + "不能小于1折";
}
if (value > 9.9) {
return str + "不能大于9.9折";
}
var arrMen = value.split(".");
var val = 0;
if (arrMen.length == 2) {
val = arrMen[1];
}
if (val.length > 2) {
return str + "最多可保留两位小数";
}
},
count: function (value) {
if ($('[name="is_show"]').is(':checked')) {
if (!/[\S]+/.test(value)) {
return '请输入发放数量';
}
if (value % 1 != 0) {
return '请输入整数';
}
if (value == 0) {
return '发放数量不能为0';
}
if (value != -1 && parseInt(value) < parseInt('{$coupon_type_info.count}')) {
return '发放数量不能小于原发放数量!';
}
}
}
});
upload = new Upload({
elem: '#couponImg',
auto:false,
bindAction:'#imageId',
callback: function(res) {
uploadComplete('image', res.data.pic_path);
}
});
function uploadComplete(field, pic_path) {
saveData.field[field] = pic_path;
completeUploadNum += 1;
if(completeUploadNum == totalUploadNum){
saveFunc();
}
}
function saveFunc() {
var data = saveData;
// 删除图片
if (!data.field.image) upload.delete();
$.ajax({
url: ns.url("coupon://merchant/coupon/edit"),
data: data.field,
dataType: 'JSON',
type: 'POST',
success: function (res) {
repeat_flag = false;
if (res.code == 0) {
layer.confirm('编辑成功', {
title: '操作提示',
btn: ['返回列表', '继续编辑'],
yes: function(index, layero) {
location.hash = ns.hash("coupon://merchant/coupon/lists")
layer.close(index);
},
btn2: function(index, layero) {
layer.close(index);
}
});
} else {
layer.msg(res.message);
}
}
});
}
/**
* 监听提交
*/
form.on('submit(save)', function(data) {
if (data.field.goods_type != 1) {
if (data.field.goods_ids == '') {
layer.msg("请选择商品");
return;
}
}
if (repeat_flag) return;
repeat_flag = true;
let new_goods_ids = [];
goods_list.forEach((item, i) => {
new_goods_ids.push(item.goods_id)
});
data.field.goods_ids = new_goods_ids.join(',');
saveData = data;
var obj = $("img.img_prev[data-prev='1']");
totalUploadNum = obj.length;
if (totalUploadNum > 0) {
obj.each(function () {
var actionId = $(this).attr('data-action-id');
$(actionId).click();
})
} else {
saveFunc();
}
});
delRule = function(obj) {
$(obj).parent().parent().remove();
};
$(".exchange-type").click(function() {
$(this).addClass("border-color");
$(this).siblings("button").removeClass("border-color");
var type = $(this).attr('data-status');
var current_type = $("input[name='type']").val();
if (current_type == type) {
return false;
}
$("input[name='type']").val(type);
var html = '';
if (type == 'reward') {
html += '<label class="layui-form-label"><span class="required">*</span>优惠券面额:</label>' +
'<div class="layui-input-block">' +
'<div class="layui-input-inline">' +
'<input type="number" name="money" min="0" lay-verify="required|number|money" autocomplete="off" class="layui-input len-short">' +
'</div>' +
'<span class="layui-form-mid">元</span>' +
'</div>' +
'<div class="word-aux">' +
'<p>价格不能小于0可保留两位小数</p>' +
'</div>';
$('.discount_limit').remove();
$("body").off("change", 'input[name="money"]').on("change", 'input[name="money"]', function() {
let aa = $('input[name="money"]').val();
$('.priceaaaa').html('¥' + aa)
});
}
if (type == 'discount') {
html += '<label class="layui-form-label"><span class="required">*</span>优惠券折扣:</label>' +
'<div class="layui-input-block">' +
'<div class="layui-input-inline">' +
'<input type="number" name="discount" min="1" lay-verify="required|fl" autocomplete="off" class="layui-input len-short">' +
'</div>' +
'<span class="layui-form-mid">折</span>' +
'</div>' +
'<div class="word-aux">' +
'<p>优惠券折扣不能小于1折且不可大于9.9折,可保留两位小数</p>' +
'</div>';
var discount_limit = '';
discount_limit += '<div class="layui-form-item discount_limit">' +
'<label class="layui-form-label">最多优惠:</label>' +
'<div class="layui-input-block">' +
'<div class="layui-input-inline">' +
'<input type="number" name="discount_limit" min="0" lay-verify="number|int" autocomplete="off" class="layui-input len-short">' +
'</div>' +
'<span class="layui-form-mid">元</span>' +
'</div>' +
'</div>';
$('#coupon_type').after(discount_limit);
$("body").off("change", 'input[name="discount"]').on("change", 'input[name="discount"]', function() {
let bb = $('input[name="discount"]').val();
$('.pricebbbb').html(bb + ' 折 ')
});
}
$('#coupon_type').html(html);
});
});
// 表格渲染
function renderTable(goods_list) {
//展示已知数据
table = new Table({
elem: '#selected_sku_list',
cols: [
[{
field: 'goods_name',
title: '商品名称',
unresize: 'false',
width: '50%'
}, {
field: 'price',
title: '商品价格(元)',
unresize: 'false',
align: 'right',
width: '20%',
templet: function(data) {
return '¥' + data.price;
}
}, {
field: 'goods_stock',
title: '库存',
unresize: 'false',
align: 'center',
width: '20%'
}, {
title: '操作',
toolbar: '#operation',
unresize: 'false',
align:'right'
}],
],
data: goods_list,
});
}
// 删除选中商品
function delGoods(id) {
var i, j;
$.each(goods_list, function(index, item) {
var goods_id = item.goods_id;
if (id == goods_id) {
i = index;
}
});
goods_list.splice(i, 1);
renderTable(goods_list);
$.each(selectedGoodsId, function(index, item) {
if (id == item) {
j = index;
}
});
selectedGoodsId.splice(j, 1);
goods_id = selectedGoodsId;
$("#goods_num").html(selectedGoodsId.length);
$("input[name='goods_ids']").val(goods_id.toString());
}
function addGoods() {
goodsSelect(function (data) {
if (!Object.keys(data).length) return;
goods_id = [];
goods_list = [];
for (var key in data) {
goods_id.push(data[key].goods_id);
goods_list.push(data[key]);
}
renderTable(goods_list);
$("input[name='goods_ids']").val(goods_id.toString());
selectedGoodsId = goods_id;
$("#goods_num").html(selectedGoodsId.length)
}, selectedGoodsId, {mode: "spu", is_weigh: 1});
}
function back() {
location.hash = ns.hash("coupon://merchant/coupon/lists");
}
</script>

View File

@@ -0,0 +1,558 @@
<link rel="stylesheet" href="MERCHANT_CSS/goods_lists.css?v={$version}">
<link rel="stylesheet" type="text/css" href="__STATIC__/ext/searchable_select/searchable_select.css"/>
<style>
.layui-layer-page .layui-layer-content { padding: 20px 30px; }
.layui-layout-admin.admin-style-2 .body-content{padding-top:15px !important;}
.layui-layout-admin.admin-style-2 .table-tab .layui-tab-title{margin-bottom: 15px;}
.prompt-con{text-align: left}
.layui-form-select {background: #fff}
.table-bottom .layui-table-page {position: inherit;text-align: right}
</style>
<!-- 按钮容器 -->
<div class="single-filter-box top">
<button class="layui-btn" onclick="add()">添加优惠券</button>
</div>
<!-- 筛选面板 -->
<div class="screen layui-collapse" lay-filter="selection_panel">
<div class="layui-colla-item">
<form class="layui-colla-content layui-form layui-show">
<div class="layui-form-item">
<div class="layui-inline">
<label class="layui-form-label">优惠券名称:</label>
<div class="layui-input-inline">
<input type="text" name="coupon_name" placeholder="请输入优惠券名称" autocomplete="off" class="layui-input">
</div>
</div>
<div class="layui-inline">
<label class="layui-form-label">优惠券类型:</label>
<div class="layui-input-inline">
<select name="type">
<option value="">全部</option>
<option value="reward">满减</option>
<option value="discount">折扣</option>
</select>
</div>
</div>
<div class="layui-inline">
<label class="layui-form-label">优惠券状态:</label>
<div class="layui-input-inline">
<select name="status">
<option value="">全部</option>
<option value="1">进行中</option>
<option value="2">已结束</option>
<option value="-1">已关闭</option>
</select>
</div>
</div>
</div>
<div class="layui-form-item">
<div class="layui-inline">
<label class="layui-form-label">有效期限:</label>
<div class="layui-input-inline">
<select name="validity_type" lay-filter="validity_type">
<option value="">全部</option>
<option value="0">固定时间</option>
<option value="1">相对时间</option>
<option value="2">长期有效</option>
</select>
</div>
</div>
<div class="layui-inline relative-time layui-hide">
<div class="layui-input-inline split">从发券</div>
<div class="layui-input-inline">
<input type="number" class="layui-input len-short" lay-verify="int" id="start_day" placeholder="开始天数" autocomplete="off">
</div>
<div class="layui-input-inline split"></div>
<div class="layui-input-inline end-time">
<input type="number" class="layui-input len-short" lay-verify="int" id="end_day" placeholder="结束天数" autocomplete="off">
</div>
</div>
<div class="layui-inline fixed-time layui-hide">
<div class="layui-input-inline">
<input type="text" class="layui-input" id="start_date" placeholder="开始时间" autocomplete="off" readonly>
<i class=" iconrili iconfont calendar"></i>
</div>
<div class="layui-input-inline split">&nbsp;&nbsp;-&nbsp;&nbsp;</div>
<div class="layui-input-inline end-time">
<input type="text" class="layui-input" id="end_date" placeholder="结束时间" autocomplete="off" readonly>
<i class=" iconrili iconfont calendar"></i>
</div>
</div>
<input type="hidden" class="layui-input" name="start_time">
<input type="hidden" class="layui-input" name="end_time">
</div>
<div class="form-row">
<button class="layui-btn" lay-submit lay-filter="search">筛选</button>
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
</div>
</form>
</div>
</div>
<div class="layui-tab table-tab" lay-filter="coupon_tab">
<div class="layui-tab-content">
<!-- 列表 -->
<table id="coupon_list" lay-filter="coupon_list"></table>
</div>
</div>
<script type="text/html" id="validity">
{{# if(d.validity_type == 0){ }}
失效期{{ ns.time_to_date(d.end_time) }}
{{# } else if(d.validity_type == 1) { }}
领取后{{ d.fixed_term }}天有效
{{# } else { }}
长期有效
{{# } }}
</script>
<!-- 推广 -->
{include file="app/merchant/view/promote.html"}
<!-- 批量操作 -->
<script type="text/html" id="toolbarAction">
<button class="layui-btn layui-btn-primary" lay-event="delete">批量删除</button>
<button class="layui-btn layui-btn-primary" lay-event="close">批量关闭</button>
</script>
<!-- 操作 -->
<script type="text/html" id="operation">
<div class="operation-wrap" data-coupon-id="{{d.coupon_type_id}}">
<div class="popup-qrcode-wrap" style="display: none"><img class="popup-qrcode-loadimg" src="__STATIC__/loading/loading.gif"/></div>
<div class="table-btn">
<!-- 进行中 -->
{{# if(d.status == 1){ }}
<a class="layui-btn" lay-event="edit">编辑</a>
<a class="layui-btn" lay-event="detail">详情</a>
<a class="layui-btn" lay-event="close">关闭</a>
{{# } }}
<!-- 已结束 -->
{{# if(d.status == 2){ }}
<a class="layui-btn" lay-event="detail">详情</a>
<a class="layui-btn" lay-event="del">删除</a>
{{# } }}
<!-- 已关闭 -->
{{# if(d.status == -1){ }}
<a class="layui-btn" lay-event="detail">详情</a>
<a class="layui-btn" lay-event="del">删除</a>
{{# } }}
</div>
</div>
</script>
<!-- 编辑排序 -->
<script type="text/html" id="editSort">
<input name="sort" type="number" onchange="editSort({{d.coupon_type_id}}, this)" value="{{d.sort}}" class="layui-input edit-sort len-short">
</script>
<script>
var laytpl;
layui.use(['form', 'laytpl','laydate'], function() {
var table,
form = layui.form,
laydate = layui.laydate,
laytpl = layui.laytpl,
validityType = 0,
repeat_flag = false; //防重复标识
form.render();
table = new Table({
elem: '#coupon_list',
url: ns.url("coupon://merchant/coupon/lists"),
cols: [
[{
type: 'checkbox',
width: '3%',
},{
field: 'coupon_name',
title: '优惠券名称',
unresize: 'false',
width: '10%'
},{
field: 'reward',
title: '优惠券类型',
unresize: 'false',
width: '10%',
templet: function(data) {
if(data.type == 'reward'){
return '满减';
}else{
return '折扣';
}
}
}, {
title: '<span style="padding-right: 15px;">优惠金额/折扣</span>',
unresize: 'false',
width: '10%',
align: 'left',
templet: function(data) {
if(data.type == 'reward'){
return '<span style="padding-right: 15px;">¥'+ data.money +'</span>';
}else{
return '<span style="padding-right: 15px;">'+ data.discount +'折</span>';
}
}
}, {
field: 'count',
title: '发放数量',
unresize: 'false',
width: '10%',
templet: function(data){
return data.is_show == 0 || data.count == -1 ? '无限制' : data.count;
}
}, {
title: '剩余数量',
unresize: 'false',
width: '10%',
templet: function(data){
return data.is_show == 0 || data.count == -1 ? '无限制' : data.count-data.lead_count;
}
},{
title: '领取上限',
unresize: 'false',
width: '10%',
templet: function(data){
return data.is_show == 0 || data.max_fetch == 0 ? '无领取限制' : data.max_fetch + '张/人';
}
}, {
title: '有效期限',
unresize: 'false',
templet: '#validity',
width: '15%'
}, {
field: 'status_name',
title: `<div class="prompt-block">状态
<div class="prompt">
<i class="iconfont iconwenhao1 required growth"></i>
<div class="growth-box reason-box reason-growth prompt-box">
<div class="prompt-con">
<p>时间超过优惠券设置的结束时间或有效期限时,优惠券自动关闭</p>
<p>手动关闭优惠券后,用户将不能领取该优惠券,但是已经领取的优惠券(未到期)仍然可以使用</p>
</div>
</div>
</div>
</div>`,
unresize: 'false',
width: '8%'
}, {
title: '操作',
toolbar: '#operation',
unresize: 'false',
width: '17%',
align : 'right'
}]
],
toolbar: '#toolbarAction'
});
// 监听工具栏操作
table.toolbar(function (obj) {
var data = obj.data;
if(data.length <= 0) return;
var couponTypeIdAll = [];
for (var i in data){
couponTypeIdAll.push(data[i].coupon_type_id);
}
switch (obj.event) {
case 'delete':
deleteCouponAll(couponTypeIdAll)
break;
case 'close':
closeCouponAll(couponTypeIdAll)
break;
}
})
function deleteCouponAll(data){
layer.confirm('确定要删除优惠券吗?', function(index) {
if (repeat_flag) return false;
repeat_flag = true;
layer.close(index);
$.ajax({
url: ns.url("coupon://merchant/coupon/deleteAll"),
data: {
coupon_type_id: data
},
dataType: 'JSON',
type: 'POST',
success: function(res) {
layer.msg(res.message);
repeat_flag = false;
table.reload({
page: {
curr: 1
},
});
}
});
}, function() {
layer.close();
repeat_flag = false;
});
}
function closeCouponAll(data){
layer.confirm('确定要关闭吗?关闭后买家将无法再领取优惠券,但已领取的将不受影响!', function(index) {
if (repeat_flag) return false;
repeat_flag = true;
layer.close(index);
$.ajax({
url: ns.url("coupon://merchant/coupon/closeAll"),
data: {
coupon_type_id: data
},
dataType: 'JSON',
type: 'POST',
success: function(res) {
layer.msg(res.message);
repeat_flag = false;
if (res.code == 0) {
table.reload();
}
}
});
}, function() {
layer.close();
repeat_flag = false;
});
}
/**
* 监听工具栏操作
*/
table.tool(function(obj) {
var data = obj.data;
switch (obj.event) {
case 'edit': //编辑
location.hash = ns.hash("coupon://merchant/coupon/edit", {"coupon_type_id": data.coupon_type_id});
break;
case 'del': //删除
layer.confirm('确定要删除该优惠券吗?', function(index) {
if (repeat_flag) return false;
repeat_flag = true;
layer.close(index);
$.ajax({
url: ns.url("coupon://merchant/coupon/delete"),
data: data,
dataType: 'JSON',
type: 'POST',
success: function(res) {
layer.msg(res.message);
repeat_flag = false;
if (res.code == 0) {
table.reload({
page: {
curr: 1
},
});
}
}
});
}, function() {
layer.close();
repeat_flag = false;
});
break;
case 'close': //关闭
layer.confirm('确定要关闭吗?关闭后买家将无法再领取该优惠券,但已领取的将不受影响!', function(index) {
if (repeat_flag) return false;
repeat_flag = true;
layer.close(index);
$.ajax({
url: ns.url("coupon://merchant/coupon/close", {"coupon_type_id": data.coupon_type_id}),
data: data,
dataType: 'JSON',
type: 'POST',
success: function(res) {
layer.msg(res.message);
repeat_flag = false;
if (res.code == 0) {
table.reload();
}
}
});
}, function() {
layer.close();
repeat_flag = false;
});
break;
case 'select': //推广
couponUrl(data);
break;
case 'detail': //详情
location.hash = ns.hash("coupon://merchant/coupon/detail", {"coupon_type_id": data.coupon_type_id});
break;
}
});
table.on("sort",function (obj) {
table.reload({
page: {
curr: 1
},
where: {
order:obj.field,
sort:obj.type
}
});
});
// 搜索
form.on('submit(search)', function(data) {
if(validityType == 2){
data.field.start_time = $("#start_day").val();
data.field.end_time = $("#end_day").val();
}
table.reload({
page: {
curr: 1
},
where: data.field
});
return false;
});
form.on('select(validity_type)', function(data){
switch (data.value) {
case '0':
laydate.render({
elem: '#start_date', //指定元素
type: 'datetime',
done: function(value, date, endDate){
$("input[name='start_time']").val(ns.date_to_time(value));
}
});
laydate.render({
elem: '#end_date', //指定元素
type: 'datetime',
done: function(value, date, endDate){
$("input[name='end_time']").val(ns.date_to_time(value));
}
});
$(".relative-time").addClass("layui-hide");
$(".fixed-time").removeClass("layui-hide");
break;
case '1':
validityType = 2;
$(".relative-time").removeClass("layui-hide");
$(".fixed-time").addClass("layui-hide");
break;
default:
$(".relative-time").addClass("layui-hide");
$(".fixed-time").addClass("layui-hide");
break;
}
});
form.verify({
int: function(value) {
if (value < 0) {
return '发券天数不能小于0';
}
}
});
// 优惠券推广
function couponUrl(data) {
if (repeat_flag) return;
repeat_flag = true;
// 先查询 H5 二维码
getCouponQrcode(data.coupon_type_id,'h5',function (res) {
res.id = res.coupon_type_id;
repeat_flag = false;
laytpl($("#promote").html()).render(res, function (html) {
layer.open({
type: 1,
area: ['730px', '450px'],
offset: '155px',
title: ['推广'],
content: html,
success: function(){
$('input[name="promote_type"][value="h5"]').attr('data-config',JSON.stringify(res.h5));
form.render();
// 推广渠道监听
promoteTypeSwitch();
// 二次查询微信小程序、支付宝小程序二维码
getCouponQrcode(data.coupon_type_id,'all',function (res) {
$('input[name="promote_type"]').each(function (index,item) {
if(res[$(item).val()]){
$(item).attr('data-config',JSON.stringify(res[$(item).val()]))
}
})
});
}
});
});
});
}
function getCouponQrcode(coupon_type_id,app_type,callback) {
$.ajax({
type: "POST",
url: ns.url("coupon://merchant/coupon/couponUrl"),
data: {
coupon_type_id,
app_type
},
dataType: 'JSON',
success: function (res) {
if (callback) callback(res.data);
}
});
}
});
// 监听单元格编辑
function editSort(id, event){
var data = $(event).val();
if (data == '') {
$(event).val(0);
data = 0;
}
if(!new RegExp("^-?[0-9]\\d*$").test(data)){
layer.msg("排序号只能是整数");
return ;
}
if(data<0){
layer.msg("排序号必须大于0");
return ;
}
$.ajax({
type: 'POST',
url: ns.url("coupon://merchant/coupon/couponSort"),
data: {
sort: data,
coupon_type_id: id
},
dataType: 'JSON',
success: function(res) {
layer.msg(res.message);
if(res.code==0){
table.reload();
}
}
});
}
function add() {
location.hash = ns.hash("coupon://merchant/coupon/add");
}
</script>

View File

@@ -0,0 +1,645 @@
<?php
/**
*/
namespace addon\coupon\model;
use addon\coupon\dict\CouponDict;
use app\model\BaseModel;
use app\model\system\Stat;
/**
* 优惠券
*/
class Coupon extends BaseModel
{
/**
* 获取优惠券来源方式
* @param string $type
* @return array|mixed|string
*/
public function getCouponGetType($type = '')
{
$get_type = [
1 => '消费奖励',
2 => '直接领取',
3 => '会员升级奖励',
4 => '商家发放',
6 => '活动奖励'
];
$event = event('CouponGetType');
if (!empty($event)) {
foreach ($event as $k => $v) {
$get_type[ array_keys($v)[ 0 ] ] = array_values($v)[ 0 ];
}
}
if ($type) return $get_type[ $type ] ?? '';
else return $get_type;
}
/**
* 获取编码
*/
public function getCode()
{
return random_keys(8);
}
/**
* 领取优惠券
* @param $coupon_type_id
* @param $site_id
* @param $member_id
* @param $get_type
* @param int $is_stock
* @param int $is_limit
* @return array
*/
public function receiveCoupon($coupon_type_id, $site_id, $member_id, $get_type, $is_stock = 0, $is_limit = 1)
{
// 用户已领取数量
if (empty($member_id)) {
return $this->error('', '请先进行登录');
}
$coupon_type_info = model('promotion_coupon_type')->getInfo([ 'coupon_type_id' => $coupon_type_id, 'site_id' => $site_id ]);
if (!empty($coupon_type_info)) {
if ($coupon_type_info[ 'count' ] != -1 || $is_stock == 0) {
if ($coupon_type_info[ 'count' ] == $coupon_type_info[ 'lead_count' ]) {
return $this->error('', '来迟了该优惠券已被领取完了');
}
}
if ($coupon_type_info[ 'max_fetch' ] != 0 && $get_type == 2) {
//限制领取
$member_receive_num = model('promotion_coupon')->getCount([
'coupon_type_id' => $coupon_type_id,
'member_id' => $member_id,
'get_type' => 2
]);
if ($member_receive_num >= $coupon_type_info[ 'max_fetch' ] && $is_limit == 1) {
return $this->error('', '该优惠券领取已达到上限');
}
}
//只有正在进行中的优惠券可以添加或者发送领取)
if ($coupon_type_info[ 'status' ] != 1) {
return $this->error('', '该优惠券已过期');
}
$data = [
'coupon_type_id' => $coupon_type_id,
'site_id' => $site_id,
'coupon_code' => $this->getCode(),
'member_id' => $member_id,
'money' => $coupon_type_info[ 'money' ],
'state' => CouponDict::normal,
'get_type' => $get_type,
'goods_type' => $coupon_type_info[ 'goods_type' ],
'fetch_time' => time(),
'coupon_name' => $coupon_type_info[ 'coupon_name' ],
'at_least' => $coupon_type_info[ 'at_least' ],
'type' => $coupon_type_info[ 'type' ],
'discount' => $coupon_type_info[ 'discount' ],
'discount_limit' => $coupon_type_info[ 'discount_limit' ],
'goods_ids' => $coupon_type_info[ 'goods_ids' ],
];
if ($coupon_type_info[ 'validity_type' ] == 0) {
$data[ 'end_time' ] = $coupon_type_info[ 'end_time' ];
} elseif ($coupon_type_info[ 'validity_type' ] == 1) {
$data[ 'end_time' ] = ( time() + $coupon_type_info[ 'fixed_term' ] * 86400 );
}
$res = model('promotion_coupon')->add($data);
if ($is_stock == 0) {
model('promotion_coupon_type')->setInc([ [ 'coupon_type_id', '=', $coupon_type_id ] ], 'lead_count');
}
$stat_model = new Stat();
$stat_model->switchStat([ 'type' => 'receive_coupon', 'data' => [
'site_id' => $site_id,
'coupon_id' => $res
] ]);
return $this->success($res);
} else {
return $this->error('', '未查找到该优惠券');
}
}
/**
* 批量奖励优惠券(不会统计领券会员数)(不会限制数量)
* @param $member_data //会员相关数据,防止重复查询
* @param $coupon_type_list //奖励优惠券活动列表(每种只发送一张)
*/
public function batchReceiveCoupon($member_data, $coupon_type_list, $get_type)
{
$coupon_list = [];
$lead_count_ids = [];
foreach ($coupon_type_list as $k => $v) {
//可发放状态
if ($v[ 'status' ] == 1) {
$data = [
'coupon_type_id' => $v[ 'coupon_type_id' ],
'site_id' => $v[ 'site_id' ],
'coupon_code' => $this->getCode(),
'member_id' => $member_data[ 'member_id' ],
'money' => $v[ 'money' ],
'state' => CouponDict::normal,
'get_type' => $get_type,
'goods_type' => $v[ 'goods_type' ],
'fetch_time' => time(),
'coupon_name' => $v[ 'coupon_name' ],
'at_least' => $v[ 'at_least' ],
'type' => $v[ 'type' ],
'discount' => $v[ 'discount' ],
'discount_limit' => $v[ 'discount_limit' ],
'goods_ids' => $v[ 'goods_ids' ],
];
if ($v[ 'validity_type' ] == 0) {
$data[ 'end_time' ] = $v[ 'end_time' ];
} elseif ($v[ 'validity_type' ] == 1) {
$data[ 'end_time' ] = ( time() + $v[ 'fixed_term' ] * 86400 );
}
$coupon_list[] = $data;
$lead_count_ids[] = $v[ 'coupon_type_id' ];
}
}
if (!empty($coupon_list)) {
model('promotion_coupon')->addList($coupon_list);
$lead_count_ids = implode(',', $lead_count_ids);
model('promotion_coupon_type')->setInc([ [ 'coupon_type_id', 'in', $lead_count_ids ] ], 'lead_count');
}
}
/**
* 发放优惠券
* @param array $coupon_data [ ['coupon_type_id' => xx, 'num' => xx ] ]
* @param int $site_id
* @param int $member_id
* @param int $get_type
* @param int $related_id
* @return array
*/
public function giveCoupon(array $coupon_data, int $site_id, int $member_id, $get_type = 4, $related_id = 0, $is_limit = 1, $is_stock = 1)
{
if (empty($member_id)) return $this->error('', '请先选择会员');
try {
$coupon_list = [];
$coupon_count = count($coupon_data);
foreach ($coupon_data as $item) {
$coupon_type_info = model('promotion_coupon_type')->getInfo([
[ 'coupon_type_id', '=', $item[ 'coupon_type_id' ] ],
[ 'site_id', '=', $site_id ],
[ 'status', '=', 1 ]
]);
if (empty($coupon_type_info)) {
continue;
}
if ($coupon_type_info[ 'count' ] != -1 && $coupon_type_info[ 'is_show' ] == 1) {
if ($is_stock && $coupon_type_info[ 'count' ] == $coupon_type_info[ 'lead_count' ]) {
if ($coupon_count == 1) {
return $this->error('', '来迟了该优惠券已被领取完了');
} else {
continue;
}
}
}
if ($coupon_type_info[ 'max_fetch' ] != 0 && $get_type == 2) {
//限制领取
if ($is_limit) {
$member_receive_num = model('promotion_coupon')->getCount([
'coupon_type_id' => $item[ 'coupon_type_id' ],
'member_id' => $member_id,
'get_type' => 2
]);
if ($member_receive_num >= $coupon_type_info[ 'max_fetch' ]) {
if ($coupon_count == 1) {
return $this->error('', '[' . $coupon_type_info[ 'coupon_name' ] . '] 优惠券领取已达到上限');
} else {
continue;
}
}
}
}
$data = [
'coupon_type_id' => $item[ 'coupon_type_id' ],
'site_id' => $site_id,
'coupon_code' => $this->getCode(),
'member_id' => $member_id,
'money' => $coupon_type_info[ 'money' ],
'state' => CouponDict::normal,
'get_type' => $get_type,
'goods_type' => $coupon_type_info[ 'goods_type' ],
'fetch_time' => time(),
'coupon_name' => $coupon_type_info[ 'coupon_name' ],
'at_least' => $coupon_type_info[ 'at_least' ],
'type' => $coupon_type_info[ 'type' ],
'discount' => $coupon_type_info[ 'discount' ],
'discount_limit' => $coupon_type_info[ 'discount_limit' ],
'goods_ids' => $coupon_type_info[ 'goods_ids' ],
'related_id' => $related_id,
'end_time' => 0
];
if ($coupon_type_info[ 'validity_type' ] == 0) {
$data[ 'end_time' ] = $coupon_type_info[ 'end_time' ];
} elseif ($coupon_type_info[ 'validity_type' ] == 1) {
$data[ 'end_time' ] = ( time() + $coupon_type_info[ 'fixed_term' ] * 86400 );
}
for ($i = 0; $i < $item[ 'num' ]; $i++) {
$data[ 'coupon_code' ] = $this->getCode();
$coupon_list[] = $data;
}
model('promotion_coupon_type')->setInc([ [ 'coupon_type_id', '=', $item[ 'coupon_type_id' ] ] ], 'lead_count', $item[ 'num' ]);
}
if (empty($coupon_list)) return $this->error('', '没有可发放的优惠券');
$res = model('promotion_coupon')->addList($coupon_list);
return $this->success($res);
} catch (\Exception $e) {
return $this->error('', '发放失败');
}
}
/**
* 使用优惠券
* @param $coupon_id
* @param $member_id
* @param $use_order_id
* @return array
*/
public function useCoupon($coupon_id, $member_id, $use_order_id)
{
$data = [ 'use_order_id' => $use_order_id, 'use_time' => time(), 'state' => CouponDict::used ];
$condition = [
[ 'coupon_id', '=', $coupon_id ],
[ 'member_id', '=', $member_id ],
[ 'state', '=', CouponDict::normal ]
];
$result = model('promotion_coupon')->update($data, $condition);
return $this->success($result);
}
/**
* 退还优惠券
* @param $coupon_id
* @param $member_id
* @return array
*/
public function refundCoupon($coupon_id, $member_id)
{
//获取优惠券信息
$condition = [
[ 'pc.coupon_id', '=', $coupon_id ],
[ 'pc.member_id', '=', $member_id ],
[ 'pc.state', '=', CouponDict::used ]
];
$field = 'pct.validity_type,pc.end_time';
$alias = 'pc';
$join = [
[ 'promotion_coupon_type pct', 'pc.coupon_type_id = pct.coupon_type_id', 'left' ]
];
$info = model('promotion_coupon')->getInfo($condition, $field, $alias, $join);
if (empty($info)) {
return $this->success();
}
$data = [ 'use_time' => 0, 'state' => CouponDict::normal ];
// 判断优惠券是否过期有效期类型0固定时间1领取之日起x天有效2长期有效
if ($info[ 'validity_type' ] == 0) {
// 固定时间
if ($info[ 'end_time' ] <= time()) {
$data[ 'state' ] = CouponDict::expire;
}
}
$result = model('promotion_coupon')->update($data, [ [ 'coupon_id', '=', $coupon_id ], [ 'member_id', '=', $member_id ], [ 'state', '=', CouponDict::used ] ]);
return $this->success($result);
}
/**
* 获取优惠券信息
* @param $condition $coupon_code 优惠券编码
* @param $field
* @return array
*/
public function getCouponInfo($condition, $field)
{
$info = model('promotion_coupon')->getInfo($condition, $field);
return $this->success($info);
}
/**
* 获取优惠券数量
* @param $condition $coupon_code 优惠券编码
* @return array
*/
public function getCouponCount($condition)
{
$info = model('promotion_coupon')->getCount($condition);
return $this->success($info);
}
/**
* 获取优惠券列表
* @param array $condition
* @param bool $field
* @param string $order
* @param null $limit
* @return array
*/
public function getCouponList($condition = [], $field = true, $order = '', $limit = null)
{
$list = model('promotion_coupon')->getList($condition, $field, $order, '', '', '', $limit);
return $this->success($list);
}
/**
* 获取优惠券列表
* @param array $condition
* @param int $page
* @param int $page_size
* @param string $order
* @param string $field
* @param string $alias
* @param array $join
* @return array
*/
public function getCouponPageList($condition = [], $page = 1, $page_size = PAGE_LIST_ROWS, $order = 'fetch_time desc', $field = 'coupon_id,type,discount,coupon_type_id,coupon_name,site_id,coupon_code,member_id,use_order_id,at_least,money,state,get_type,fetch_time,use_time,end_time', $alias = 'a', $join = [])
{
$list = model('promotion_coupon')->pageList($condition, $field, $order, $page, $page_size, $alias, $join);
return $this->success($list);
}
/**
* 获取会员优惠券列表
* @param $condition
* @param int $page
* @param int $page_size
* @return array
*/
public function getMemberCouponPageList($condition, $page = 1, $page_size = PAGE_LIST_ROWS)
{
$field = 'npc.coupon_name,npc.type,npc.use_order_id,npc.coupon_id,npc.coupon_type_id,npc.site_id,npc.coupon_code,npc.member_id,npc.discount_limit,
npc.at_least,npc.money,npc.discount,npc.state,npc.get_type,npc.fetch_time,npc.use_time,npc.end_time,mem.nickname,on.order_no,npc.end_time,mem.nickname,mem.headimg,mem.mobile';
$alias = 'npc';
$join = [
[
'member mem',
'npc.member_id = mem.member_id',
'inner'
],
[
'order on',
'npc.use_order_id = on.order_id',
'left'
]
];
$list = model('promotion_coupon')->pageList($condition, $field, 'fetch_time desc', $page, $page_size, $alias, $join);
return $this->success($list);
}
/**
* 获取优惠券信息
* @param $condition
* @param string $field
* @return array
*/
public function getCouponTypeInfo($condition, $field = 'coupon_type_id,site_id,coupon_name,money,count,lead_count,max_fetch,at_least,end_time,image,validity_type,fixed_term,status,type,discount')
{
$info = model('promotion_coupon_type')->getInfo($condition, $field);
return $this->success($info);
}
/**
* 获取优惠券列表
* @param array $condition
* @param bool $field
* @param string $order
* @param null $limit
* @return array
*/
public function getCouponTypeList($condition = [], $field = true, $order = '', $limit = null, $alias = '', $join = [])
{
$list = model('promotion_coupon_type')->getList($condition, $field, $order, $alias, $join, '', $limit);
return $this->success($list);
}
/**
* 获取优惠券分页列表
* @param $condition
* @param int $page
* @param int $page_size
* @param string $order
* @param string $field
* @return array
*/
public function getCouponTypePageList($condition, $page = 1, $page_size = PAGE_LIST_ROWS, $order = 'coupon_type_id desc', $field = '*', $alias = '', $join = [])
{
$list = model('promotion_coupon_type')->pageList($condition, $field, $order, $page, $page_size, $alias, $join);
return $this->success($list);
}
/**
* 获取会员已领取优惠券
* @param $member_id
* @param $state
* @param int $site_id
* @param int $money
* @param string $order
* @return array
*/
public function getMemberCouponList($member_id, $state, $site_id = 0, $money = 0, $order = 'fetch_time desc')
{
$condition = array (
[ 'member_id', '=', $member_id ],
[ 'state', '=', $state ],
// [ "end_time", ">", time()]
);
if ($site_id > 0) {
$condition[] = [ 'site_id', '=', $site_id ];
}
if ($money > 0) {
// $condition[] = [ "at_least", "=", 0 ];
$condition[] = [ 'at_least', '<=', $money ];
}
$list = model('promotion_coupon')->getList($condition, '*', $order, '', '', '', 0);
return $this->success($list);
}
public function getMemberCouponCount($condition)
{
$list = model('promotion_coupon')->getCount($condition);
return $this->success($list);
}
/**
* 增加库存
* @param $param
* @return array
*/
public function incStock($param)
{
$condition = array (
[ 'coupon_type_id', '=', $param[ 'coupon_type_id' ] ]
);
$num = $param[ 'num' ];
$coupon_info = model('promotion_coupon_type')->getInfo($condition, 'count,lead_count');
if (empty($coupon_info))
return $this->error(-1, '');
//更新优惠券库存
$result = model('promotion_coupon_type')->setDec($condition, 'lead_count', $num);
return $this->success($result);
}
/**
* 减少库存
* @param $param
* @return array
*/
public function decStock($param)
{
$condition = array (
[ 'coupon_type_id', '=', $param[ 'coupon_type_id' ] ]
);
$num = $param[ 'num' ];
$coupon_info = model('promotion_coupon_type')->getInfo($condition, 'count,lead_count');
if (empty($coupon_info))
return $this->error(-1, '找不到优惠券!');
//编辑sku库存
if ($coupon_info[ 'count' ] != -1) {
if (( $coupon_info[ 'count' ] - $coupon_info[ 'lead_count' ] ) < $num)
return $this->error(-1, '优惠券库存不足!');
}
$result = model('promotion_coupon_type')->setInc($condition, 'lead_count', $num);
if ($result === false)
return $this->error();
return $this->success($result);
}
/**
* 定时关闭
* @return mixed
*/
public function cronCouponEnd()
{
$res = model('promotion_coupon')->update([ 'state' => CouponDict::expire ], [ [ 'state', '=', CouponDict::normal ], [ 'end_time', '>', 0 ], [ 'end_time', '<=', time() ] ]);
return $res;
}
/**
* 核验会员是否还可以领用某一张优惠券
* @param $params
* @return array
*/
public function checkMemberReceiveCoupon($params)
{
$member_id = $params[ 'member_id' ];//会员id
$coupon_type_info = $params[ 'coupon_type_info' ];
$site_id = $params[ 'site_id' ];
$coupon_type_id = $params[ 'coupon_type_id' ] ?? 0;
if ($coupon_type_id > 0) {
$coupon_type_info = model('promotion_coupon_type')->getInfo([ 'coupon_type_id' => $coupon_type_id, 'site_id' => $site_id ]);
}
if (!empty($coupon_type_info)) {
$coupon_type_id = $coupon_type_info[ 'coupon_type_id' ] ?? 0;
if ($coupon_type_info[ 'count' ] != -1 && $coupon_type_info[ 'is_show' ] == 1) {
if ($coupon_type_info[ 'count' ] == $coupon_type_info[ 'lead_count' ]) {
return $this->error('', '来迟了该优惠券已被领取完了!');
}
}
if ($coupon_type_info[ 'max_fetch' ] != 0) {
//限制领取
$member_receive_num = model('promotion_coupon')->getCount([
'coupon_type_id' => $coupon_type_id,
'member_id' => $member_id,
'get_type' => 2
]);
if ($member_receive_num >= $coupon_type_info[ 'max_fetch' ]) {
return $this->error('', '该优惠券领取已达到上限!');
}
}
//只有正在进行中的优惠券可以添加或者发送领取)
if ($coupon_type_info[ 'status' ] != 1) {
return $this->error('', '该优惠券已过期!');
}
}
return $this->success();
}
/**
* 获取商品可领用优惠券
* @param $goods_sku_detail_array
* @param $member_id
* @param $site_id
*/
public function getGoodsCanReceiveCouponInApi($goods_sku_detail_array, $member_id, $site_id)
{
$goods_sku_detail = $goods_sku_detail_array[ 'goods_sku_detail' ];
$condition = [
[ 'site_id', '=', $site_id ],
[ 'status', '=', 1 ],
[ 'is_show', '=', 1 ],
];
//查询正在进行的优惠券活动
$field = 'count,lead_count,coupon_type_id,coupon_type_id as type_id,type,site_id,coupon_name,money,discount,max_fetch,at_least,end_time,validity_type,fixed_term,goods_type,discount_limit,goods_ids';
$coupon_type_list = model('promotion_coupon_type')->getList($condition, $field);
//查询会员领用的优惠券数量
if ($member_id != 0) {
$member_coupon_num = model('promotion_coupon')->getList([ [ 'member_id', '=', $member_id ] ], 'coupon_type_id,count(coupon_type_id) as member_coupon_num', 'money desc', 'a', [], 'coupon_type_id');
if (!empty($member_coupon_num)) {
$key = array_column($member_coupon_num, 'coupon_type_id');
$member_coupon_num = array_combine($key, $member_coupon_num);
} else {
$member_coupon_num = [];
}
}
foreach ($coupon_type_list as $k => $v) {
if ($v[ 'goods_type' ] == 2) {
//部分商品可用
$goods_id_array = explode(',', $v[ 'goods_ids' ]);
if (!in_array($goods_sku_detail[ 'goods_id' ], $goods_id_array)) {
unset($coupon_type_list[ $k ]);
continue;
}
}
if ($v[ 'goods_type' ] == 3) {
//部分商品不可用
$goods_id_array = explode(',', $v[ 'goods_ids' ]);
if (in_array($goods_sku_detail[ 'goods_id' ], $goods_id_array)) {
unset($coupon_type_list[ $k ]);
continue;
}
}
if ($member_id != 0) {
$coupon_rec_num = $member_coupon_num[ 'coupon_type_id' ][ 'member_coupon_num' ] ?? 0;
//控制领用数量
if ($v[ 'count' ] == $v[ 'lead_count' ]) {
unset($coupon_type_list[ $k ]);
} elseif ($v[ 'max_fetch' ] != 0 && $coupon_rec_num >= $v[ 'max_fetch' ]) {
// 已领取
unset($coupon_type_list[ $k ]);
}
}
}
$goods_sku_detail_array[ 'goods_sku_detail' ][ 'coupon_list' ] = $coupon_type_list;
return $goods_sku_detail_array;
}
}

View File

@@ -0,0 +1,64 @@
<?php
/**
*/
namespace addon\coupon\model;
use app\model\BaseModel;
use app\model\system\Stat;
/**
* 优惠券统计
*/
class CouponStat extends BaseModel
{
/**
* 领取优惠券统计
* @param $params
* @return array
*/
public function addReceiveCouponStat($params)
{
$coupon_id = $params[ 'coupon_id' ];
$site_id = $params[ 'site_id' ] ?? 0;
$order_condition = array (
[ 'coupon_id', '=', $coupon_id ],
[ 'site_id', '=', $site_id ]
);
$info = model('promotion_coupon')->getInfo($order_condition);
if (empty($info))
return $this->error();
$stat_data = array (
'site_id' => $site_id,
'coupon_count' => 1
);
$member_id = $info[ 'member_id' ];
//如果是第一笔订单才能累加下单会员数
$time_region = getDayStartAndEndTime();
$today_start_time = $time_region[ 'start_time' ];
$today_end_time = $time_region[ 'end_time' ];
$today_order_condition = array (
[ 'member_id', '=', $member_id ],
[ 'fetch_time', 'between', [ $today_start_time, $today_end_time ] ],
[ 'coupon_id', '<>', $coupon_id ]
);
$count = model('promotion_coupon')->getCount($today_order_condition);
if ($count == 0) {
$stat_data[ 'coupon_member_count' ] = 1;
}
//发布统计
$stat_model = new Stat();
$result = $stat_model->addShopStat($stat_data);
return $result;
}
}

View File

@@ -0,0 +1,336 @@
<?php
/**
*/
namespace addon\coupon\model;
use app\model\BaseModel;
use app\model\system\Config as ConfigModel;
use app\model\system\Cron;
use app\model\upload\Upload;
/**
* 优惠券活动
*/
class CouponType extends BaseModel
{
//优惠券类型状态
private $coupon_type_status = [
1 => '进行中',
2 => '已结束',
-1 => '已关闭',
];
public function getCouponTypeStatus()
{
return $this->coupon_type_status;
}
/**
* 添加优惠券活动
* @param $data
* @return array
*/
public function addCouponType($data)
{
//只要创建了就是进行中
$data[ 'status' ] = 1;
$data[ 'create_time' ] = time();
//获取商品id
if ($data[ 'goods_type' ] == 1) {//全部商品参与
$data[ 'goods_ids' ] = '';
}
$data[ 'goods_ids' ] = ',' . $data[ 'goods_ids' ] . ',';
$res = model('promotion_coupon_type')->add($data);
if ($data[ 'validity_type' ] == 0) {
$cron = new Cron();
$cron->addCron(1, 1, '优惠券活动定时结束', 'CronCouponTypeEnd', $data[ 'end_time' ], $res);
}
$this->qrcode($res, 'all', $data[ 'site_id' ]);
return $this->success($res);
}
/**
* 编辑优惠券活动
* @param $data
* @param $coupon_type_id
* @return array
*/
public function editCouponType($data, $coupon_type_id)
{
$data[ 'update_time' ] = time();
//获取商品id
if ($data[ 'goods_type' ] == 1) {//全部商品参与
$data[ 'goods_ids' ] = '';
}
$coupon_info = model('promotion_coupon_type')->getInfo([ [ 'coupon_type_id', '=', $coupon_type_id ] ]);
if (!empty($coupon_info[ 'image' ]) && !empty($data[ 'image' ]) && $coupon_info[ 'image' ] != $data[ 'image' ]) {
$upload_model = new Upload();
$upload_model->deletePic($coupon_info[ 'image' ], $coupon_info[ 'site_id' ]);
}
$data[ 'goods_ids' ] = ',' . $data[ 'goods_ids' ] . ',';
$res = model('promotion_coupon_type')->update($data, [ [ 'coupon_type_id', '=', $coupon_type_id ] ]);
model('promotion_coupon')->update([ 'goods_ids' => $data[ 'goods_ids' ], 'goods_type' => $data[ 'goods_type' ] ], [ [ 'coupon_type_id', '=', $coupon_type_id ], [ 'state', '=', 1 ] ]);
$cron = new Cron();
$cron->deleteCron([ [ 'event', '=', 'CronCouponTypeEnd' ], [ 'relate_id', '=', $coupon_type_id ] ]);
if ($data[ 'validity_type' ] == 0) {
$cron->addCron(1, 1, '优惠券活动定时结束', 'CronCouponTypeEnd', $data[ 'end_time' ], $coupon_type_id);
}
return $this->success($res);
}
/**
* 关闭优惠券
* @param $coupon_type_id
* @param $site_id
* @return array
*/
public function closeCouponType($coupon_type_id, $site_id)
{
$res = model('promotion_coupon_type')->update([ 'status' => -1 ], [ [ 'coupon_type_id', '=', $coupon_type_id ], [ 'site_id', '=', $site_id ] ]);
// if ($res) {
// model("promotion_coupon")->update(['state' => 3], [['coupon_type_id', '=', $coupon_type_id], ['site_id', '=', $site_id]]);
// }
$cron = new Cron();
$cron->deleteCron([ [ 'event', '=', 'CronCouponTypeEnd' ], [ 'relate_id', '=', $coupon_type_id ] ]);
return $this->success($res);
}
/**
* 删除优惠券活动
* @param $coupon_type_id
* @param $site_id
* @return array
*/
public function deleteCouponType($coupon_type_id, $site_id)
{
$coupon_info = model('promotion_coupon_type')->getInfo([ [ 'coupon_type_id', '=', $coupon_type_id ] ]);
if ($coupon_info['status'] == 1) return $this->error('', '进行中的优惠卷无法删除,请先关闭');
if (!empty($coupon_info[ 'image' ])) {
$upload_model = new Upload();
$upload_model->deletePic($coupon_info[ 'image' ], $coupon_info[ 'site_id' ]);
}
$res = model('promotion_coupon_type')->delete([ [ 'coupon_type_id', '=', $coupon_type_id ], [ 'site_id', '=', $site_id ] ]);
if ($res) {
model('promotion_coupon')->delete([ [ 'coupon_type_id', '=', $coupon_type_id ] ]);
}
$cron = new Cron();
$cron->deleteCron([ [ 'event', '=', 'CronCouponTypeEnd' ], [ 'relate_id', '=', $coupon_type_id ] ]);
return $this->success($res);
}
/**
* 获取优惠券活动详情
* @param $coupon_type_id
* @param $site_id
* @return array
*/
public function getCouponTypeInfo($coupon_type_id, $site_id)
{
$res = model('promotion_coupon_type')->getList([ [ 'coupon_type_id', 'in', $coupon_type_id ], [ 'site_id', '=', $site_id ] ]);
if (!empty($res)) {
foreach ($res as $k => $v) {
if ($v[ 'goods_type' ] == 2 || $v[ 'goods_type' ] == 3) {
$field[ $k ] = 'goods_id,goods_name,FLOOR(goods_stock) as goods_stock,goods_image,price,sort';
$goods_ids[ $k ] = substr($v[ 'goods_ids' ], '1', '-1');
$goods_list[ $k ] = model('goods')->getList([ [ 'goods_id', 'in', $goods_ids[ $k ] ] ], $field[ $k ]);
}
$res[ $k ][ 'goods_list' ] = $goods_list[$k] ?? [];
$res[ $k ][ 'goods_list_count' ] = count($res[ $k ][ 'goods_list' ]);
}
}
return $this->success($res);
}
/**
* 获取优惠券活动信息
* @param array $where
* @param bool $field
* @param string $alias
* @param null $join
* @param null $data
* @return array
*/
public function getInfo($where = [], $field = true, $alias = 'a', $join = null, $data = null)
{
$res = model('promotion_coupon_type')->getInfo($where, $field, $alias, $join, $data);
return $this->success($res);
}
/**
* 获取优惠券类型列表
* @param array $condition
* @param string $field
* @param string $order
* @param null $limit
* @return array
*/
public function getCouponTypeList($condition = [], $field = '*', $order = 'create_time desc', $limit = null)
{
$res = model('promotion_coupon_type')->getList($condition, $field, $order, '', '', '', $limit);
return $this->success($res);
}
/**
* 获取优惠券活动分页列表
* @param array $condition
* @param int $page
* @param int $page_size
* @param string $order
* @param string $field
* @return array
*/
public function getCouponTypePageList($condition = [], $page = 1, $page_size = PAGE_LIST_ROWS, $order = '', $field = '*')
{
$condition[] = [ 'promotion_type', '=', 0 ];
$list = model('promotion_coupon_type')->pageList($condition, $field, $order, $page, $page_size);
return $this->success($list);
}
/**
* 排序
* @param $coupon_type_id
* @param $sort
* @return array
*/
public function couponSort($coupon_type_id, $sort)
{
$res = model('promotion_coupon_type')->update([ 'sort' => $sort ], [ [ 'coupon_type_id', '=', $coupon_type_id ] ]);
return $this->success($res);
}
/**
* 生成优惠券二维码
* @param $coupon_type_id
* @param string $app_type all为全部
* @param string $type 类型 create创建 get获取
* @return mixed|array
*/
public function qrcode($coupon_type_id, $app_type, $site_id, $type = 'create')
{
$res = event('Qrcode', [
'site_id' => $site_id,
'app_type' => $app_type,
'type' => $type,
'data' => [
'coupon_type_id' => $coupon_type_id
],
'page' => '/pages_tool/goods/coupon_receive',
'qrcode_path' => 'upload/qrcode/coupon',
'qrcode_name' => 'coupon_type_code_' . $coupon_type_id . '_' . $site_id,
], true);
return $res;
}
/**
* 优惠券定时结束
* @param $coupon_type_id
* @return array
*/
public function couponCronEnd($coupon_type_id)
{
$res = model('promotion_coupon_type')->update([ 'status' => 2 ], [ [ 'coupon_type_id', '=', $coupon_type_id ] ]);
return $this->success($res);
}
public function spread($coupon_type_id, $name, $site_id, $type = 'create')
{
$data = [
'site_id' => $site_id,
'app_type' => 'all', // all为全部
'type' => $type, // 类型 create创建 get获取
'data' => [
'coupon_type_id' => $coupon_type_id
],
'page' => '/pages_tool/goods/coupon_receive',
'qrcode_path' => 'upload/qrcode/coupon',
'qrcode_name' => 'coupon_type_code_' . $coupon_type_id . '_' . $site_id,
];
event('Qrcode', $data, true);
$app_type_list = config('app_type');
$path = [];
foreach ($app_type_list as $k => $v) {
switch ( $k ) {
case 'h5':
$wap_domain = getH5Domain();
$path[ $k ][ 'status' ] = 1;
$path[ $k ][ 'url' ] = $wap_domain . $data[ 'page' ] . '?coupon_type_id=' . $coupon_type_id;
$path[ $k ][ 'img' ] = 'upload/qrcode/coupon/coupon_type_code_' . $coupon_type_id . '_' . $site_id . '_' . $k . '.png';
break;
case 'weapp' :
$config = new ConfigModel();
$res = $config->getConfig([ [ 'site_id', '=', $site_id ], [ 'app_module', '=', 'shop' ], [ 'config_key', '=', 'WEAPP_CONFIG' ] ]);
if (!empty($res[ 'data' ])) {
if (empty($res[ 'data' ][ 'value' ][ 'qrcode' ])) {
$path[ $k ][ 'status' ] = 2;
$path[ $k ][ 'message' ] = '未配置微信小程序';
} else {
$path[ $k ][ 'status' ] = 1;
$path[ $k ][ 'img' ] = $res[ 'data' ][ 'value' ][ 'qrcode' ];
}
} else {
$path[ $k ][ 'status' ] = 2;
$path[ $k ][ 'message' ] = '未配置微信小程序';
}
break;
case 'wechat' :
$config = new ConfigModel();
$res = $config->getConfig([ [ 'site_id', '=', $site_id ], [ 'app_module', '=', 'shop' ], [ 'config_key', '=', 'WECHAT_CONFIG' ] ]);
if (!empty($res[ 'data' ])) {
if (empty($res[ 'data' ][ 'value' ][ 'qrcode' ])) {
$path[ $k ][ 'status' ] = 2;
$path[ $k ][ 'message' ] = '未配置微信公众号';
} else {
$path[ $k ][ 'status' ] = 1;
$path[ $k ][ 'img' ] = $res[ 'data' ][ 'value' ][ 'qrcode' ];
}
} else {
$path[ $k ][ 'status' ] = 2;
$path[ $k ][ 'message' ] = '未配置微信公众号';
}
break;
}
}
$return = [
'path' => $path,
'name' => $name,
];
return $this->success($return);
}
public function urlQrcode($page, $qrcode_param, $promotion_type, $app_type, $site_id)
{
$params = [
'site_id' => $site_id,
'data' => $qrcode_param,
'page' => $page,
'promotion_type' => $promotion_type,
'app_type' => $app_type,
'h5_path' => $page . '?coupon_type_id=' . $qrcode_param[ 'coupon_type_id' ],
'qrcode_path' => 'upload/qrcode/coupon',
'qrcode_name' => 'coupon_type_code_' . $promotion_type . '_' . $qrcode_param[ 'coupon_type_id' ] . '_' . $site_id,
];
$solitaire = event('PromotionQrcode', $params, true);
return $this->success($solitaire);
}
}

View File

@@ -0,0 +1,243 @@
<?php
/**
*/
namespace addon\coupon\model;
use addon\coupon\dict\CouponDict;
use app\model\BaseModel;
/**
* 优惠券
*/
class MemberCoupon extends BaseModel
{
/**
* 获取会员已领取优惠券
* @param $member_id
* @param $state
* @param int $site_id
* @param string $order
* @return array
*/
public function getMemberCouponList($member_id, $state, $site_id = 0, $order = "fetch_time desc")
{
$condition = array (
[ "member_id", "=", $member_id ],
[ "state", "=", $state ],
);
if ($site_id > 0) {
$condition[] = [ "site_id", "=", $site_id ];
}
$list = model("promotion_coupon")->getList($condition, "*", $order, '', '', '', 0);
return $this->success($list);
}
/**
* 使用优惠券
* @param $coupon_id
* @param $member_id
* @param int $order_id
* @return array
*/
public function useMemberCoupon($coupon_id, $member_id, $order_id = 0)
{
//优惠券处理方案
$result = model('promotion_coupon')->update([ 'use_order_id' => $order_id, 'state' => 2, 'use_time' => time() ], [ [ 'coupon_id', '=', $coupon_id ], [ "member_id", "=", $member_id ], [ 'state', '=', 1 ] ]);
if ($result === false) {
return $this->error();
}
return $this->success();
}
/**
* 获取会员已领取优惠券数量
* @param $member_id
* @param $state
* @param int $site_id
* @return array
*/
public function getMemberCouponNum($member_id, $state, $site_id = 0)
{
$condition = array (
[ "member_id", "=", $member_id ],
[ "state", "=", $state ],
);
if ($site_id > 0) {
$condition[] = [ "site_id", "=", $site_id ];
}
$num = model("promotion_coupon")->getCount($condition);
return $this->success($num);
}
/**
* 会员是否可领取该优惠券
* @param $coupon_type_id
* @param $member_id
* @return array
*/
public function receivedNum($coupon_type_id, $member_id)
{
$received_num = model('promotion_coupon')->getCount([ [ 'coupon_type_id', '=', $coupon_type_id ], [ 'member_id', '=', $member_id ] ]);
return $this->success($received_num);
}
/**
* 获取编码
*/
public function getCode()
{
return random_keys(8);
}
/**
* 会员批量发放优惠券
* @param $coupon_type_ids
* @param $site_id
* @param $member_id
* @param int $get_type
* @param int $is_stock
* @param int $related_id
* @return array
*/
public function sendCoupon($coupon_type_ids, $site_id, $member_id, $get_type = 4, $is_stock = 0, $related_id = 0)
{
//已选优惠券提交数组
if (!empty($coupon_type_ids)) {
$res = 0;
foreach ($coupon_type_ids as $coupon_type_id) {
$coupon_type_info = model('promotion_coupon_type')->getInfo([ 'coupon_type_id' => $coupon_type_id, 'site_id' => $site_id, 'status' => 1 ]);
if (!empty($coupon_type_info)) {
if ($coupon_type_info[ 'count' ] != -1 || $is_stock == 0) {
if ($coupon_type_info[ 'count' ] == $coupon_type_info[ 'lead_count' ]) {
return $this->error('', '来迟了该优惠券已被领取完了');
}
}
if ($coupon_type_info[ 'max_fetch' ] != 0 && $get_type == 2) {
//限制领取
$member_receive_num = model('promotion_coupon')->getCount([
'coupon_type_id' => $coupon_type_id,
'member_id' => $member_id,
'get_type' => 2
]);
if ($member_receive_num >= $coupon_type_info[ 'max_fetch' ] ) {
return $this->error('', '该优惠券领取已达到上限');
}
}
$data = [
'coupon_type_id' => $coupon_type_id,
'site_id' => $site_id,
'coupon_code' => $this->getCode(),
'member_id' => $member_id,
'money' => $coupon_type_info[ 'money' ],
'state' => 1,
'get_type' => $get_type,
'goods_type' => $coupon_type_info[ 'goods_type' ],
'fetch_time' => time(),
'coupon_name' => $coupon_type_info[ 'coupon_name' ],
'at_least' => $coupon_type_info[ 'at_least' ],
'type' => $coupon_type_info[ 'type' ],
'discount' => $coupon_type_info[ 'discount' ],
'discount_limit' => $coupon_type_info[ 'discount_limit' ],
'goods_ids' => $coupon_type_info[ 'goods_ids' ],
'related_id' => $related_id
];
if ($coupon_type_info[ 'validity_type' ] == 0) {
$data[ 'end_time' ] = $coupon_type_info[ 'end_time' ];
} elseif ($coupon_type_info[ 'validity_type' ] == 1) {
$data[ 'end_time' ] = ( time() + $coupon_type_info[ 'fixed_term' ] * 86400 );
}
$res = model('promotion_coupon')->add($data);
if ($is_stock == 0) {
model('promotion_coupon_type')->setInc([ [ 'coupon_type_id', '=', $coupon_type_id ] ], 'lead_count');
}
}
}
if ($res) {
return $this->success($res);
} else {
return $this->error();
}
} else {
return $this->error();
}
}
/**
* 回收优惠券
* @param array $coupon_list
* @param $site_id
* @return array
*/
public function recoveryCoupon(array $coupon_list, $site_id)
{
$coupon = [];
foreach ($coupon_list as $coupon_item) {
if (isset($coupon[ $coupon_item[ 'coupon_type_id' ] ])) {
$coupon[$coupon_item['coupon_type_id']][] = $coupon_item['coupon_id'];
} else {
$coupon[ $coupon_item[ 'coupon_type_id' ] ] = [ $coupon_item[ 'coupon_id' ] ];
}
}
if (!count($coupon)) return $this->error();
model('promotion_coupon')->startTrans();
try {
foreach ($coupon as $coupon_type_id => $coupon_ids) {
$num = model('promotion_coupon')->delete([ [ 'coupon_id', 'in', $coupon_ids ], [ 'site_id', '=', $site_id ], [ 'state', '=', 1 ] ]);
if ($num) model('promotion_coupon_type')->setDec([ [ 'coupon_type_id', '=', $coupon_type_id ] ], 'lead_count', $num);
}
model('promotion_coupon')->commit();
return $this->success();
} catch (\Exception $e) {
model('promotion_coupon')->rollback();
return $this->error('', '回收失败');
}
}
/**
* 专用于撤回活动赠送的优惠券
* @return void
*/
public function cancelByPromotion($data){
$member_id = $data['member_id'];
$coupon_data = $data['coupon_data'];//优惠券id相关项
$coupon_ids = array_column($coupon_data, 'coupon_type_id');
$member_coupon_list = model('promotion_coupon')->getList([
['member_id', '=', $member_id],
['coupon_type_id', 'in', $coupon_ids],
['state', '=', CouponDict::normal]
], '*');
$member_coupon_type_group_list = [];
foreach($member_coupon_list as $v){
$member_coupon_type_group_list[$v['coupon_type_id']][] = $v['coupon_id'];
}
$cancel_ids = [];
foreach ($coupon_data as $item) {
$coupon_type_id = $item['coupon_type_id'];
$num = $item['num'];
$item_coupon_type_group = $member_coupon_type_group_list[$coupon_type_id] ?? [];
if($item_coupon_type_group){
if(count($item_coupon_type_group) > $num){
$cancel_ids = array_merge($cancel_ids, array_slice($item_coupon_type_group, 0, $num));
}else{
$cancel_ids = array_merge($cancel_ids, $item_coupon_type_group);
}
}
}
model('promotion_coupon')->update(['state' => CouponDict::close], [['coupon_id', 'in', $cancel_ids]]);
return $this->success();
}
}

View File

@@ -0,0 +1,103 @@
<?php
/**
*/
namespace addon\coupon\model\share;
use app\model\share\WchatShareBase as BaseModel;
use app\model\system\Config as ConfigModel;
use app\model\system\Site as SiteModel;
/**
* 分享
*/
class WchatShare extends BaseModel
{
protected $config = [
[
'title' => '领券中心',
'config_key' => 'WCHAT_SHARE_CONFIG_COUPON_LIST',
'path' => [ '/pages_tool/goods/coupon' ],
'method_prefix' => 'couponList',
],
];
/**
* 商品列表分享数据
* @param $param
* @return array
*/
protected function couponListShareData($param)
{
$site_id = $param[ 'site_id' ] ?? 0;
//站点设置
$site_model = new SiteModel();
$site_info = $site_model->getSiteInfo([ [ 'site_id', '=', $site_id ] ])[ 'data' ];
//跳转路径
$link = $this->getShareLink($param);
//获取和替换配置数据
$config_method = preg_replace('/Data$/', 'Config', __FUNCTION__);
$config_data = $this->$config_method($param);
$title = $config_data[ 'value' ][ 'title' ];
$desc = $config_data[ 'value' ][ 'desc' ];
$image_url = $config_data[ 'value' ][ 'imgUrl' ] ?: $site_info[ 'logo_square' ];
$data = [
'title' => $title,
'desc' => $desc,
'link' => $link,
'imgUrl' => $image_url,
];
return [
'permission' => [
'hideOptionMenu' => false,
'hideMenuItems' => [],
],
'data' => $data,//分享内容
];
}
/**
* 商品列表分享配置
* @param $param
* @return array
*/
protected function couponListShareConfig($param)
{
$site_id = $param[ 'site_id' ];
$config = $param[ 'config' ];
$config_model = new ConfigModel();
$data = $config_model->getConfig([
[ 'site_id', '=', $site_id ],
[ 'app_module', '=', 'shop' ],
[ 'config_key', '=', $config[ 'config_key' ] ],
])[ 'data' ];
if (empty($data[ 'value' ])) {
$data[ 'value' ] = [
'title' => '送你一张优惠券',
'desc' => "优惠多多\n好物多多",
'imgUrl' => '',
];
}
if (empty($data[ 'value' ][ 'imgUrl' ])) {
$data[ 'value' ][ 'imgUrl' ] = img('addon/coupon/icon.png');
}
$variable = [];
return [
'value' => $data[ 'value' ],
'variable' => $variable,
];
}
}

View File

@@ -0,0 +1,91 @@
<?php
/**
*/
namespace addon\coupon\model\share;
use app\model\share\WeappShareBase;
use app\model\system\Config as ConfigModel;
/**
* 分享
*/
class WeappShare extends WeappShareBase
{
protected $config = [
[
'title' => '领券中心',
'config_key' => 'WEAPP_SHARE_CONFIG_COUPON_LIST',
'path' => [ '/pages_tool/goods/coupon' ],
'method_prefix' => 'couponList',
],
];
protected $sort = 2;
/***************************** 领券中心 ***************************/
/**
* 首页分享数据
* @param $param
* @return array
*/
protected function couponListShareData($param)
{
//获取和替换配置数据
$config_data = $this->couponListShareConfig($param);
$title = $config_data[ 'value' ][ 'title' ];
$image_url = $config_data[ 'value' ][ 'imageUrl' ] ? img($config_data[ 'value' ][ 'imageUrl' ]) : '';
$path = $this->getSharePath($param);
$data = [
'title' => $title,
'path' => $path,
'imageUrl' => $image_url,
];
return [
'permission' => [
'onShareAppMessage' => true,
'onShareTimeline' => true,
],
'data' => $data,//分享内容
];
}
/**
* 首页分享配置
* @param $param
* @return array
*/
protected function couponListShareConfig($param)
{
$site_id = $param[ 'site_id' ];
$config = $param[ 'config' ];
$config_model = new ConfigModel();
$data = $config_model->getConfig([
[ 'site_id', '=', $site_id ],
[ 'app_module', '=', 'shop' ],
[ 'config_key', '=', $config[ 'config_key' ] ],
])[ 'data' ];
if (empty($data[ 'value' ])) {
$data[ 'value' ] = [
'title' => '送你一张优惠券,快来领取吧',
'imageUrl' => '',
];
}
$variable = [];
return [
'value' => $data[ 'value' ],
'variable' => $variable,
];
}
}

View File

@@ -0,0 +1,354 @@
<?php
namespace addon\coupon\shop\controller;
use addon\coupon\model\MemberCoupon;
use app\shop\controller\BaseShop;
use addon\coupon\model\CouponType as CouponTypeModel;
use addon\coupon\model\Coupon as CouponModel;
use think\facade\Db;
/**
* 优惠券
* @author Administrator
*
*/
class Coupon extends BaseShop
{
/**
* 添加活动
*/
public function add()
{
if (request()->isJson()) {
$data = [
'site_id' => $this->site_id,
'coupon_name' => input('coupon_name', ''),//优惠券名称
'type' => input('type'),//优惠券类型
'goods_type' => input('goods_type', 1),
'goods_ids' => input('goods_ids', ''),
'sort' => input('sort', '0'), //优惠券排序
'money' => input('money', 0),//优惠券面额
'discount' => input('discount', 0),//优惠券折扣
'discount_limit' => input('discount_limit', 0),//最多优惠
'count' => input('count', ''),//发放数量
'max_fetch' => input('max_fetch', ''),//最大领取数量
'at_least' => input('at_least', ''),//满多少元可以使用
'end_time' => strtotime(input('end_time', '')),//活动结束时间
'image' => input('image', ''),//优惠券图片
'validity_type' => input('validity_type', ''),//有效期类型 0固定时间 1领取之日起
'fixed_term' => input('fixed_term', ''),//领取之日起N天内有效
'is_show' => input('is_show', 0),//是否允许直接领取 1:是 0否 允许直接领取用户才可以在手机端和PC端进行领取否则只能以活动的形式发放。
];
$coupon_type_model = new CouponTypeModel();
return $coupon_type_model->addCouponType($data);
} else {
return $this->fetch('coupon/add');
}
}
/**
* 编辑活动
*/
public function edit()
{
$coupon_type_model = new CouponTypeModel();
if (request()->isJson()) {
$data = [
'site_id' => $this->site_id,
'coupon_name' => input('coupon_name', ''),//优惠券名称
'type' => input('type'),//优惠券类型
'goods_type' => input('goods_type', 1),
'goods_ids' => input('goods_ids', ''),
'money' => input('money', 0),//优惠券面额
'sort' => input('sort', 0),//优惠券面额
'discount' => input('discount', 0),//优惠券折扣
'discount_limit' => input('discount_limit', 0),//最多优惠
'count' => input('count', ''),//发放数量
'max_fetch' => input('max_fetch', ''),//最大领取数量
'at_least' => input('at_least', ''),//满多少元可以使用
'end_time' => strtotime(input('end_time', '')),//活动结束时间
'image' => input('image', ''),//优惠券图片
'validity_type' => input('validity_type', ''),//有效期类型 0固定时间 1领取之日起
'fixed_term' => input('fixed_term', ''),//领取之日起N天内有效
'is_show' => input('is_show', 0),//是否允许直接领取 1:是 0否 允许直接领取用户才可以在手机端和PC端进行领取否则只能以活动的形式发放。
];
$coupon_type_id = input('coupon_type_id', 0);
return $coupon_type_model->editCouponType($data, $coupon_type_id);
} else {
$coupon_type_id = input('coupon_type_id', 0);
$this->assign('coupon_type_id', $coupon_type_id);
$coupon_type_info = $coupon_type_model->getCouponTypeInfo($coupon_type_id, $this->site_id);
if (empty($coupon_type_info[ 'data' ])) $this->error('未获取到优惠券数据', href_url('coupon://shop/coupon/lists'));
$this->assign('coupon_type_info', $coupon_type_info[ 'data' ][ 0 ]);
return $this->fetch('coupon/edit');
}
}
/**
* 活动详情
*/
public function detail()
{
$coupon_type_id = input('coupon_type_id', 0);
$coupon_type_model = new CouponTypeModel();
$coupon_type_info = $coupon_type_model->getCouponTypeInfo($coupon_type_id, $this->site_id)[ 'data' ] ?? [];
if (empty($coupon_type_info)) $this->error('未获取到优惠券数据', href_url('coupon://shop/coupon/lists'));
$this->assign('info', $coupon_type_info[ 0 ]);
$this->assign('get_type', ( new CouponModel() )->getCouponGetType());
return $this->fetch('coupon/detail');
}
/**
* 活动列表
*/
public function lists()
{
$coupon_type_model = new CouponTypeModel();
if (request()->isJson()) {
$page = input('page', 1);
$page_size = input('page_size', PAGE_LIST_ROWS);
$coupon_name = input('coupon_name', '');
$status = input('status', '');
$inventory_count = input('inventory_count', ''); // 剩余数量
$is_show = input('is_show', ''); // 是否显示
$condition = [];
$condition[] = [ 'merch_id', '=', 0 ];
if ($status !== '') {
$condition[] = [ 'status', '=', $status ];
}
$type = input('type');
if ($type) {
$condition[] = [ 'type', '=', $type ];
}
if ($is_show !== '') {
$condition[] = [ 'is_show', '=', $is_show ];
}
//类型
$validity_type = input('validity_type', '');
if ($validity_type !== '') {
$start_time = input('start_time', '');
$end_time = input('end_time', '');
switch ( $validity_type ) {
case 0: //固定
$condition[] = [ 'end_time', 'between', [ $start_time, $end_time ] ];
break;
case 1:
$condition[] = [ 'fixed_term', 'between', [ $start_time, $end_time ] ];
break;
case 2:
$condition[] = [ 'validity_type', '=', 2 ];
break;
}
}
if ($inventory_count) {
$condition[] = [ '', 'exp', Db::raw('(lead_count < count && count != -1) OR count = -1') ];
}
$condition[] = [ 'site_id', '=', $this->site_id ];
$condition[] = [ 'coupon_name', 'like', '%' . $coupon_name . '%' ];
$field = '*';
//排序
$link_sort = input('order', 'create_time');
$sort = input('sort', 'desc');
if ($link_sort == 'sort') {
$order_by = $link_sort . ' ' . $sort;
} else {
$order_by = $link_sort . ' ' . $sort . ',sort desc';
}
$res = $coupon_type_model->getCouponTypePageList($condition, $page, $page_size, $order_by, $field);
//获取优惠券状态
$coupon_type_status_arr = $coupon_type_model->getCouponTypeStatus();
foreach ($res[ 'data' ][ 'list' ] as $key => $val) {
$res[ 'data' ][ 'list' ][ $key ][ 'status_name' ] = $coupon_type_status_arr[ $val[ 'status' ] ];
}
return $res;
} else {
//优惠券状态
$coupon_type_status_arr = $coupon_type_model->getCouponTypeStatus();
$this->assign('coupon_type_status_arr', $coupon_type_status_arr);
return $this->fetch('coupon/lists');
}
}
/**
* 排序
* @return mixed
*/
public function couponSort()
{
$sort = input('sort', 0);
$coupon_type_id = input('coupon_type_id', 0);
$coupon_type_model = new CouponTypeModel();
return $coupon_type_model->couponSort($coupon_type_id, $sort);
}
/**
* 优惠券推广
*/
public function couponUrl()
{
$coupon_type_id = input('coupon_type_id', '');
$app_type = input('app_type', 'all');
$coupon_model = new couponTypeModel();
$res = $coupon_model->urlQrcode('/pages_tool/goods/coupon_receive', [ 'coupon_type_id' => $coupon_type_id ], 'coupon', $app_type, $this->site_id);
return $res;
}
/**
* 发放优惠券
*/
public function send()
{
if (request()->isJson()) {
$member_id = input('member_id', 0);
$coupon_data = json_decode(input('coupon_data', '[]'), true);
$get_type = input('get_type', 4);
if (empty($coupon_data)) {
return error('', 'REQUEST_COUPON_TYPE_ID');
}
$res = ( new CouponModel() )->giveCoupon($coupon_data, $this->site_id, $member_id, $get_type);
return $res;
}
}
/**
* 活动列表
*/
public function couponSelect()
{
$coupon_type_model = new CouponTypeModel();
if (request()->isJson()) {
$page = input('page', 1);
$page_size = input('page_size', PAGE_LIST_ROWS);
$coupon_name = input('coupon_name', '');
$condition[] = [ 'site_id', '=', $this->site_id ];
$condition[] = [ 'status', '=', 1 ];
$condition[] = [ 'coupon_name', 'like', '%' . $coupon_name . '%' ];
$order = 'create_time desc';
$field = '*';
$res = $coupon_type_model->getCouponTypePageList($condition, $page, $page_size, $order, $field);
//获取优惠券状态
$coupon_type_status_arr = $coupon_type_model->getCouponTypeStatus();
foreach ($res[ 'data' ][ 'list' ] as $key => $val) {
$res[ 'data' ][ 'list' ][ $key ][ 'status_name' ] = $coupon_type_status_arr[ $val[ 'status' ] ];
}
return $res;
} else {
//优惠券状态
$coupon_type_status_arr = $coupon_type_model->getCouponTypeStatus();
$this->assign('coupon_type_status_arr', $coupon_type_status_arr);
$select_id = input('select_id', '');
$this->assign('select_id', $select_id);
return $this->fetch('coupon/coupon_select');
}
}
/**
* 关闭活动
*/
public function close()
{
if (request()->isJson()) {
$coupon_type_id = input('coupon_type_id', 0);
$coupon_type_model = new CouponTypeModel();
return $coupon_type_model->closeCouponType($coupon_type_id, $this->site_id);
}
}
/**
* 删除活动
*/
public function delete()
{
if (request()->isJson()) {
$coupon_type_id = input('coupon_type_id', 0);
$coupon_type_model = new CouponTypeModel();
return $coupon_type_model->deleteCouponType($coupon_type_id, $this->site_id);
}
}
/**
* 优惠券领取记录
* */
public function receive()
{
$coupon_model = new CouponModel();
if (request()->isJson()) {
$page = input('page', 1);
$page_size = input('page_size', PAGE_LIST_ROWS);
$coupon_type_id = input('coupon_type_id', 0);
$state = input('state', '');
$condition = [];
$condition[] = [ 'npc.coupon_type_id', '=', $coupon_type_id ];
$condition[] = [ 'npc.site_id', '=', $this->site_id ];
if ($state !== '') {
$condition[] = [ 'npc.state', '=', $state ];
}
$res = $coupon_model->getMemberCouponPageList($condition, $page, $page_size);
return $res;
} else {
$coupon_type_id = input('coupon_type_id', 0);
$this->assign('coupon_type_id', $coupon_type_id);
$this->assign('get_type', $coupon_model->getCouponGetType());
return $this->fetch('coupon/receive');
}
}
/**
* 优惠券回收
*/
public function recoveryCoupon()
{
if (request()->isJson()) {
$coupon_list = json_decode(input('coupon_list', '[]'), true);
return ( new MemberCoupon() )->recoveryCoupon($coupon_list, $this->site_id);
}
}
/**
* 关闭活动(批量)
*/
public function closeAll()
{
if (request()->isJson()) {
$coupon_type_id = input('coupon_type_id', '');
$coupon_type_model = new CouponTypeModel();
foreach($coupon_type_id as $k => $v){
$res = $coupon_type_model->closeCouponType($v, $this->site_id);
}
return $res;
}
}
/**
* 删除活动(批量)
*/
public function deleteAll()
{
if (request()->isJson()) {
$coupon_type_id = input('coupon_type_id', '');
$coupon_type_model = new CouponTypeModel();
foreach($coupon_type_id as $k => $v){
$res = $coupon_type_model->deleteCouponType($v, $this->site_id);
}
return $res;
}
}
}

View File

@@ -0,0 +1,776 @@
<style>
.discount { display: flex; justify-content: space-between; height: 34px; line-height: 34px; padding: 5px 15px; background-color: #F6FBFD; border: 1px dashed #BCE8F1; }
.exchange-type {padding: 0 20px; position: relative;}
.exchange-type i{position: absolute;bottom: -10px;right: -1px;display: none;}
.exchange-type.border-color i{display: block;}
.form-wrap {position: relative;}
.custom-right {
position: absolute;
top: 20px;
left: 900px;
padding: 20px 0;
box-sizing: border-box;
overflow: hidden;
background-color: #fff;
height: 500px;
width: 600px;
}
.custom-right .phone {
min-width: 280px;
height: 600px;
background: url(__STATIC__/img/quan.png) no-repeat center;
background-size: contain;
position: relative;
overflow: auto;
padding-top: 30px;
box-sizing: border-box;
}
.custom-right .phone h2 {
position: absolute;
left: 250px;
top: 80px;
}
.item {
position: absolute;
top: 100px;
left: 165px;
width: 274px;
height: 100px;
display: flex;
background: url(__STATIC__/img/quan_bj.png) no-repeat center;
border-radius: 10px;
align-items: stretch;
overflow: hidden;
font-size: 13px;
}
.item-base {
position: relative;
width: 65px;
min-width: 65px;
text-align: center;
background-repeat: no-repeat;
background-size: 100% 100%;
padding: 10px 10px 0 10px;
}
.item-base p {
display: inline-block;
}
.item .item-base .aaa {
height: auto;
position: relative;
top: 50%;
right: 5px;
transform: translate(0, -50%);
}
.item-info {
margin:0 20px 0 0;
width: 100px;
}
.use_price {
line-height: 1;
color: #fff;
}
.use_condition {
color: #fff;
margin-top: 15px;
font-size: 12px;
}
.use_title {
margin-top: 10px !important;
}
.item-btn {
width: 50px;
min-width: 50px;
align-self: center;
position: relative;
}
.item-btn .btn{
font-size: 12px;
width: 40px;
height: 24px;
border-radius: 20px;
line-height: 24px;
margin-left: 20px;
text-align: center;
background-image: linear-gradient(to right, #fc6831, #ff4544);
color: #fff;
}
.max_price {
margin: 5px 0;
padding-bottom: 5px;
border-bottom: 1px dashed #d7d2d1;
font-size: 12px;
}
.use_time span {display: inline-block;font-size: 12px; color: #909399;}
.priceaaaa {
font-size: 16px;
}
.thistitle {
font-size: 14px;
}
.goods_num {padding-left: 20px;}
</style>
<div class="layui-form form-wrap">
<div class="layui-form-item">
<label class="layui-form-label"><span class="required">*</span>优惠券名称:</label>
<div class="layui-input-block">
<input type="text" name="coupon_name" lay-verify="required" autocomplete="off" class="layui-input len-long" maxlength="15">
</div>
</div>
<div class="layui-form">
<div class="layui-form-item">
<label class="layui-form-label">优惠券类型:</label>
<div class="layui-input-block">
<button class="layui-btn layui-btn-primary exchange-type border-color" data-status="reward">满减<i class="iconfont iconxuanzhong text-color"></i></button>
<button class="layui-btn layui-btn-primary exchange-type" data-status="discount">折扣<i class="iconfont iconxuanzhong text-color"></i></button>
<input type="hidden" name="type" value="reward">
</div>
</div>
</div>
<div class="layui-form-item" id="coupon_type">
<label class="layui-form-label"><span class="required">*</span>优惠券面额:</label>
<div class="layui-input-block">
<div class="layui-input-inline">
<input type="number" name="money" min="0" lay-verify="required|number|money|coupon_money" autocomplete="off" class="layui-input len-short" >
</div>
<span class="layui-form-mid"></span>
</div>
<div class="word-aux">
<p>价格不能小于等于0可保留两位小数</p>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label"><span class="required">*</span>满多少元可以使用:</label>
<div class="layui-input-block">
<div class="layui-input-inline">
<input type="number" name="at_least" min="0" lay-verify="required|number|money" autocomplete="off" class="layui-input len-short">
</div>
<span class="layui-form-mid"></span>
</div>
<div class="word-aux">
<p>价格不能小于0无门槛请设为0</p>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">是否允许直接领取:</label>
<div class="layui-input-block">
<input type="checkbox" name="is_show" lay-filter="is_show" value="1" lay-skin="switch" checked />
</div>
</div>
<div class="receive-limit">
<div class="layui-form-item">
<label class="layui-form-label"><span class="required">*</span>发放数量:</label>
<div class="layui-input-block">
<div class="layui-input-inline">
<input type="number" name="count" lay-verify="count" autocomplete="off" class="layui-input len-short">
</div>
<span class="layui-form-mid"></span>
</div>
<div class="word-aux">
<p>优惠券发放数量,没有之后不能领取或发放,-1为不限制发放数量</p>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label"><span class="required">*</span>最大领取数量:</label>
<div class="layui-input-block">
<div class="layui-input-inline">
<input type="number" name="max_fetch" min="0" value="1" lay-verify="max" autocomplete="off" class="layui-input len-short">
</div>
<span class="layui-form-mid"></span>
</div>
<div class="word-aux">
<p>数量不能小于0且必须为整数设置为0时可无限领取</p>
</div>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">优惠券图片:</label>
<div class="layui-input-block img-upload">
<div class="upload-img-block">
<div class="upload-img-box">
<div class="upload-default" id="couponImg">
<div class="upload">
<i class="iconfont iconshangchuan"></i>
<p>点击上传</p>
</div>
</div>
<div class="operation">
<div>
<i title="图片预览" class="iconfont iconreview js-preview" style="margin-right: 20px;"></i>
<i title="删除图片" class="layui-icon layui-icon-delete js-delete" ></i>
</div>
<div class="replace_img js-replace">点击替换</div>
</div>
<input type="hidden" name="image" />
</div>
</div>
</div>
<div class="word-aux">
<p>建议尺寸325*95像素图片上传默认不限制大小</p>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">有效期类型:</label>
<div class="layui-input-block">
<input type="radio" name="validity_type" value="0" lay-filter="filter" checked="checked" title="固定时间">
<input type="radio" name="validity_type" value="1" lay-filter="filter" title="领取之日起">
<input type="radio" name="validity_type" value="2" lay-filter="filter" title="长期有效">
</div>
</div>
<div class="layui-form-item end-time validity-type validity-type-0">
<label class="layui-form-label"></label>
<div class="layui-input-block">
<input type="text" name="end_time" lay-verify="time" id="end_time" class="layui-input len-mid" autocomplete="off" readonly>
</div>
</div>
<div class="layui-form-item fixed-term validity-type validity-type-1" style="display: none">
<label class="layui-form-label">领取之日起:</label>
<div class="layui-input-block">
<div class="layui-input-inline">
<input type="number" min="1" max="365" value="10" name="fixed_term" lay-verify="days" autocomplete="off" class="layui-input len-short">
</div>
<span class="layui-form-mid">天有效</span>
</div>
<div class="word-aux">
<p>不能小于0且必须为整数</p>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label"><span class="required">*</span>活动商品:</label>
<div class="layui-input-block">
<input type="radio" name="goods_type" lay-filter="goods_type" value="1" title="全部商品参与" checked>
<input type="radio" name="goods_type" lay-filter="goods_type" value="2" title="指定商品参与">
</div>
</div>
<div class="layui-form-item goods_list" style="display:none">
<label class="layui-form-label"></label>
<div class="layui-input-block">
<table id="selected_goods_list"></table>
<button class="layui-btn" onclick="addGoods()">选择商品</button> <span class="goods_num">已选商品(<span id="goods_num" class="text-color">0</span></span>
</div>
</div>
<input type="hidden" name="goods_ids">
<div class="form-row">
<button class="layui-btn" lay-submit lay-filter="save">保存</button>
<button class="layui-btn layui-btn-primary" onclick="back()">返回</button>
<a id="imageId"></a>
</div>
</div>
<!-- 操作 -->
<script type="text/html" id="operation">
<div class="table-btn">
<a class="layui-btn" onclick="delGoods({{d.goods_id}})">删除</a>
</div>
</script>
<script>
var submitRule, delRule;
var goods_list = [], selectedGoodsId = [], goods_id=[],table;
var saveData = null;
var totalUploadNum = 0;
var completeUploadNum = 0;
var upload;
$("body").off("change",'input[name="money"]').on("change",'input[name="money"]',function(){
let aa = $('input[name="money"]').val();
$('.priceaaaa').html('¥' + aa)
});
$("body").off("change",'input[name="discount"]').on("change",'input[name="discount"]',function(){
let bb = $('input[name="discount"]').val();
$('.pricebbbb').html(bb + ' 折 ')
});
$('input[name="at_least"]').change(function(){
let cc = $('input[name="at_least"]').val();
$('.use_price2').html(cc)
});
$('input[name="fixed_term"]').change(function(){
var time_time = $('input[name="fixed_term"]').val();
$('.time-bbb').html('有效期:领取之日起' + time_time + '日内有效');
});
$("body").off("change",'input[name="coupon_name"]').on("change",'input[name="coupon_name"]',function(){
let dd = $('input[name="coupon_name"]').val();
$('.thistitle').html(dd)
});
layui.use(['form', 'laydate','form'], function() {
var form = layui.form,
laydate = layui.laydate,
repeat_flag = false; //防重复标识
currentDate = new Date(); //当前时间
form.render();
currentDate.setDate(currentDate.getDate() + 10); //10天后的日期
form.on('switch(is_show)', function (data) {
if ($(data.elem).is(':checked')) {
$('.receive-limit').show();
} else {
$('.receive-limit').hide();
}
});
// 时间模块
laydate.render({
elem: '#end_time', //指定元素
type: 'datetime',
value: currentDate,
done: function(value, date, endDate){
$('.time-aaa').html('有效期:' + value);
}
});
var date = new Date(currentDate);
var y = date.getFullYear();
var m = date.getMonth() + 1;
m = m < 10 ? ('0' + m) : m;
var d = date.getDate();
d = d < 10 ? ('0' + d) : d;
var h = date.getHours();
var minute = date.getMinutes();
var second = date.getSeconds();
minute = minute < 10 ? ('0' + minute) : minute;
let time = y + '-' + m + '-' + d+' '+h+':'+minute+':'+second;
$('.time-aaa').html('有效期:' + time);
var time_time = $('input[name="fixed_term"]').val();
$('.time-bbb').html('有效期:领取之日起' + time_time + '日内有效');
renderTable(goods_list); // 初始化表格
//监听活动商品类型
form.on('radio(goods_type)', function(data) {
var value = data.value;
if (value == 1) {
$(".goods_list").hide();
$('.max_price').html('全场商品');
} else if (value == 2) {
$(".goods_list").show();
$('.max_price').html('指定商品');
} else if (value == 3) {
$(".goods_list").show();
$('.max_price').html('指定不参与商品');
}
});
// 监听单选按钮
form.on('radio(filter)', function(data) {
$('.validity-type').hide();
$('.validity-type-' + data.value).show();
});
/**
* 表单验证
*/
form.verify({
days: function(value) {
var validity_type = $('[name="validity_type"]:checked').val();
if (validity_type == 1) {
if (value%1 != 0) {
return '请输入整数';
}
if (value <= 0) {
return '有效天数不能小于等于0';
}
}
},
number: function (value) {
if (value < 0) {
return '请输入大于或等于0的数!'
}
},
int: function (value) {
if (value%1 != 0) {
return '请输入整数!'
}
if (value <= 0) {
return '请输入大于0的数!'
}
},
money: function (value) {
if(value < 0){
return '金额不能小于0'
}
var arrMen = value.split(".");
var val = 0;
if (arrMen.length == 2) {
val = arrMen[1];
}
if (val.length > 2) {
return '保留小数点后两位'
}
},
coupon_money: function (value) {
if(parseFloat(value) > 10000){
return '优惠券面额不能大于10000'
}
if(parseFloat(value) <= 0){
return '优惠券面额不能小于0'
}
},
time: function(value) {
var validity_type = $('[name="validity_type"]:checked').val();
if (validity_type == 0) {
var now_time = (new Date()).getTime();
var end_time = (new Date(value)).getTime();
if (now_time > end_time) {
return '结束时间不能小于当前时间!'
}
}
},
max: function(value) {
if ($('[name="is_show"]').is(':checked')) {
if (!/[\S]+/.test(value)) {
return '请输入最大领取数量';
}
var _count = $("input[name=count]").val();
if (_count != -1 && parseFloat(value) > parseFloat(_count)) {
return '最大领取数量不能超过发放数量!';
}
}
},
fl: function(value, item) {
var str = $(item).parents(".layui-form-item").find("label").text().split("*").join("");
str = str.substring(0, str.length - 1);
if (value < 1) {
return str + "不能小于1折";
}
if (value > 9.9) {
return str + "不能大于9.9折";
}
var arrMen = value.split(".");
var val = 0;
if (arrMen.length == 2) {
val = arrMen[1];
}
if (val.length > 2) {
return str + "最多可保留两位小数";
}
},
count: function(value){
if ($('[name="is_show"]').is(':checked')) {
if (!/[\S]+/.test(value)) {
return '请输入发放数量';
}
if (value%1 != 0) {
return '请输入整数';
}
if (value == 0 || value < -1) {
return '发放数量不能为0或小于-1';
}
}
}
});
upload = new Upload({
elem: '#couponImg',
auto:false,
bindAction:'#imageId',
callback: function(res) {
uploadComplete('image', res.data.pic_path);
}
});
function uploadComplete(field, pic_path) {
saveData.field[field] = pic_path;
completeUploadNum += 1;
if(completeUploadNum == totalUploadNum){
saveFunc();
}
}
function saveFunc(){
var data = saveData;
// 删除图片
if(!data.field.image) upload.delete();
$.ajax({
url: ns.url("coupon://shop/coupon/add"),
data: data.field,
dataType: 'JSON',
type: 'POST',
success: function(res) {
repeat_flag = false;
if (res.code == 0) {
layer.confirm('添加成功', {
title:'操作提示',
btn: ['返回列表', '继续添加'],
closeBtn: 0,
yes: function(index, layero) {
location.hash = ns.hash("coupon://shop/coupon/lists")
layer.close(index);
},
btn2: function(index, layero) {
listenerHash(); // 刷新页面
layer.close(index);
}
});
}else{
layer.msg(res.message);
}
}
});
}
/**
* 监听提交
*/
form.on('submit(save)', function(data) {
if (data.field.is_show == undefined) {
data.field.is_show = 0;
}
if(data.field.goods_type != 1){
if(data.field.goods_ids == ''){
layer.msg("请选择商品");
return;
}
}
if (repeat_flag) return;
repeat_flag = true;
saveData = data;
var obj = $("img.img_prev[data-prev='1']");
totalUploadNum = obj.length;
if(totalUploadNum > 0){
obj.each(function(){
var actionId = $(this).attr('data-action-id');
$(actionId).click();
})
}else{
saveFunc();
}
});
submitRule = function() {
var money = $("#money").val().trim(),
discount_money = $("#discount_money").val().trim();
if (Number(money) == "0" || Number(discount_money) == "0") {
layer.msg("满减金额不能为空!", {icon: 5, anim: 6});
return false;
}
if (Number(money) < 0 || Number(discount_money) < 0) {
layer.msg("金额不能小于0", {icon: 5, anim: 6});
return false;
}
if (Number(money) * 100 % 1 != 0 || Number(discount_money) * 100 % 1 != 0) {
layer.msg("金额最多保留小数点后两位!", {icon: 5, anim: 6});
return false;
}
for (var i=0; i<$(".discount-box .discount").length; i++) {
var money_num = $(".discount-box .discount").eq(i).find(".money-num").text();
if (money == money_num) {
layer.msg("该金额规则已添加,不可重复添加!");
return false;
}
}
var html = '<div class="discount form-row">'+
'<div class="discount-con">'+
'<p>单笔订单满<span class="required money-num">' + money + '</span>元,立减现金<span class="required discount_money-num">' + discount_money + '</span>元</p>'+
'</div>'+
'<div class="discount-del">'+
'<button class="layui-btn" onclick="delRule(this)">删除</button>'+
'</div>'+
'</div>';
$(".discount-box").append(html);
};
delRule = function(obj) {
$(obj).parent().parent().remove();
};
$(".exchange-type").click(function() {
$(this).addClass("border-color");
$(this).siblings("button").removeClass("border-color");
var type = $(this).attr('data-status');
var current_type = $("input[name='type']").val();
if(current_type == type){
return false;
}
$("input[name='type']").val(type);
var html = '';
if(type == 'reward'){
html += '<label class="layui-form-label"><span class="required">*</span>优惠券面额:</label>' +
'<div class="layui-input-block">' +
'<div class="layui-input-inline">' +
'<input type="number" name="money" min="0" lay-verify="required|number|money" autocomplete="off" class="layui-input len-short">' +
'</div>' +
'<span class="layui-form-mid">元</span>' +
'</div>' +
'<div class="word-aux">' +
'<p>价格不能小于0可保留两位小数</p>' +
'</div>';
$('.discount_limit').remove();
// $('body .pricebbbb').css("display","none");
// $('body .priceaaaa').css("display","block");
$("body").off("change",'input[name="money"]').on("change",'input[name="money"]',function(){
let aa = $('input[name="money"]').val();
$('.priceaaaa').html('¥' + aa)
});
}
if(type == 'discount'){
html += '<label class="layui-form-label"><span class="required">*</span>优惠券折扣:</label>' +
'<div class="layui-input-block">' +
'<div class="layui-input-inline">' +
'<input type="number" name="discount" min="1" lay-verify="required|fl" autocomplete="off" class="layui-input len-short">' +
'</div>' +
'<span class="layui-form-mid">折</span>' +
'</div>' +
'<div class="word-aux">' +
'<p>优惠券折扣不能小于1折且不可大于9.9折,可保留两位小数</p>' +
'</div>';
var discount_limit = '';
discount_limit += '<div class="layui-form-item discount_limit">' +
'<label class="layui-form-label">最多优惠:</label>' +
'<div class="layui-input-block">' +
'<div class="layui-input-inline">' +
'<input type="number" name="discount_limit" min="0" lay-verify="number|int" autocomplete="off" class="layui-input len-short">' +
'</div>' +
'<span class="layui-form-mid">元</span>' +
'</div>' +
'</div>';
$('#coupon_type').after(discount_limit);
// $('body .priceaaaa').css("display","none");
// $('body .pricebbbb').css("display","block");
$("body").off("change",'input[name="discount"]').on("change",'input[name="discount"]',function(){
let bb = $('input[name="discount"]').val();
$('.pricebbbb').html(bb + ' 折 ')
});
}
$('#coupon_type').html(html);
});
});
// 表格渲染
function renderTable(goods_list) {
//展示已知数据
table = new Table({
elem: '#selected_goods_list',
cols: [
[{
field: 'goods_name',
title: '商品名称',
unresize: 'false',
width: '50%'
}, {
field: 'price',
title: '商品价格(元)',
unresize: 'false',
align: 'right',
width: '20%',
templet: function (data) {
return '¥' + data.price;
}
}, {
field: 'goods_stock',
title: '库存',
unresize: 'false',
align: 'center',
width: '20%'
}, {
title: '操作',
toolbar: '#operation',
unresize: 'false',
align: 'right'
}],
],
data: goods_list,
});
}
// 删除选中商品
function delGoods(id) {
var i, j;
$.each(goods_list, function(index, item) {
var goods_id = item.goods_id;
if (id == Number(goods_id)) {
i = index;
}
});
goods_list.splice(i, 1);
renderTable(goods_list);
$.each(selectedGoodsId, function(index, item) {
if (id == Number(item)) {
j = index;
}
});
selectedGoodsId.splice(j, 1);
goods_id = selectedGoodsId;
$("#goods_num").html(selectedGoodsId.length);
$("input[name='goods_ids']").val(goods_id.toString());
}
/* 商品 */
function addGoods() {
goodsSelect(function (data) {
if (!Object.keys(data).length) return;
goods_id = [];
goods_list = [];
for (var key in data) {
goods_id.push(data[key].goods_id);
goods_list.push(data[key]);
}
renderTable(goods_list);
$("input[name='goods_ids']").val(goods_id.toString());
selectedGoodsId = goods_id;
$("#goods_num").html(selectedGoodsId.length)
}, selectedGoodsId, {mode: "spu", is_weigh: 1});
}
function back() {
location.hash = ns.hash("coupon://shop/coupon/lists");
}
</script>

View File

@@ -0,0 +1,222 @@
<style>
.coupon-list {
padding: 0 20px;
}
</style>
<div class="coupon-list">
<div class="single-filter-box">
<div class="layui-form">
<div class="layui-input-inline">
<input type="text" name="coupon_name" placeholder="请输入优惠券名称" class="layui-input">
<button type="button" class="layui-btn layui-btn-primary" lay-submit lay-filter="search">
<i class="layui-icon">&#xe615;</i>
</button>
</div>
</div>
</div>
<!-- 列表 -->
<table id="coupon_list" lay-filter="coupon_list"></table>
</div>
<script type="text/html" id="checkbox">
{{# if($.inArray(d.coupon_type_id.toString(), selected_id_arr) != -1){ }}
<input type="checkbox" data-coupon-id="{{d.coupon_type_id}}" name="coupon_checkbox" lay-skin="primary" lay-filter="coupon_checkbox" checked>
{{# }else{ }}
<input type="checkbox" data-coupon-id="{{d.coupon_type_id}}" name="coupon_checkbox" lay-skin="primary" lay-filter="coupon_checkbox">
{{# } }}
<input type="hidden" data-coupon-id="{{d.coupon_type_id}}" name="coupon_json" value='{{ JSON.stringify(d) }}' />
</script>
<script>
var table, form, laytpl,
select_id = "{$select_id}", //选中商品id
selected_id_arr = select_id.length ? select_id.split(',') : [],
select_list = []; //选中商品所有数据
goodsIdArr = selected_id_arr;
$(function () {
layui.use(['form', 'laytpl'], function () {
form = layui.form;
laytpl = layui.laytpl;
table = new Table({
elem: '#coupon_list',
url: ns.url("coupon://shop/coupon/couponSelect"),
where: {
app_module: ns.appModule,
site_id: ns.siteId
},
cols: [
[
{
unresize: 'false',
width: '10%',
templet: '#checkbox'
}, {
field: 'coupon_name',
title: '优惠券名称',
unresize: 'false',
width: '20%'
}, {
field: 'reward',
title: '优惠券类型',
unresize: 'false',
width: '20%',
templet: function (data) {
if (data.type == 'reward') {
return '满减';
} else {
return '折扣';
}
}
}, {
field: 'goods_type',
title: '适用商品',
unresize: 'false',
width: '15%',
templet: function (data) {
if(data.goods_type == 1){
return '全部商品';
}else if(data.goods_type == 2){
return '指定商品';
}else if(data.goods_type == 3){
return '指定不参与商品';
}
}
}, {
title: '<span style="padding-right: 15px;">优惠金额/折扣</span>',
unresize: 'false',
width: '20%',
align: 'right',
templet: function (data) {
if (data.type == 'reward') {
return '<span style="padding-right: 15px;">¥' + data.money + '</span>';
} else {
return '<span style="padding-right: 15px;">' + data.discount + '折</span>';
}
}
}, {
field: 'count',
title: '发放数量',
unresize: 'false',
width: '15%'
}
]
],
callback: function () {
// 更新商品复选框状态
for (var i = 0; i < goodsIdArr.length; i++) {
var selected_coupons = $("input[name='coupon_checkbox'][data-coupon-id='" + goodsIdArr[i] + "']");
if (selected_coupons.length) {
$("input[name='coupon_checkbox'][data-coupon-id='" + goodsIdArr[i] + "']").prop("checked", true);
}
}
form.render();
initData();
}
});
/**
* 监听搜索
*/
form.on('submit(search)', function (data) {
data.field.app_module = ns.appModule;
data.field.site_id = ns.siteId;
table.reload({
page: {
curr: 1
},
where: data.field
});
});
// 勾选商品
form.on('checkbox(coupon_checkbox)', function(data) {
var coupon_id = $(data.elem).attr("data-coupon-id"), json = {};
form.render();
var couponLen = $("input[name='coupon_checkbox'][data-coupon-id="+ coupon_id +"]:checked").length;
if (couponLen){
json = JSON.parse($("input[name='coupon_json'][data-coupon-id="+ coupon_id +"]").val());
delete json.LAY_INDEX;
delete json.LAY_TABLE_INDEX;
delete json.create_time;
select_list.push(json);
goodsIdArr.push(coupon_id);
} else{
select_list.remove(coupon_id);
goodsIdArr.remove(coupon_id);
}
});
//初始化数据
function initData(){
var couponLen = $("input[name='coupon_checkbox'][data-coupon-id]:checked").length;
for (var i = 0; i < couponLen; i++){
var couponId = $("input[name='coupon_checkbox'][data-coupon-id]:checked").eq(i).attr("data-coupon-id");
var ident = false;
for (var k = 0; k < select_list.length; k++){
if(select_list[k].coupon_type_id == couponId){
ident = true;
break;
}
}
if (ident) return;
json = JSON.parse($("input[name='coupon_json'][data-coupon-id="+ couponId +"]").val());
delete json.LAY_INDEX;
delete json.LAY_TABLE_INDEX;
delete json.create_time;
select_list.push(json);
}
}
});
});
function selectCouponListener(callback) {
var res = select_list;
callback(res);
}
Array.prototype.indexOf = function(val) {
for (var i = 0; i < this.length; i++) {
if (this[i].coupon_type_id){
if (this[i].coupon_type_id == parseInt(val)) return i;
} else {
if (this[i] == val) return i;
}
}
return -1;
};
Array.prototype.remove = function(val) {
var index = this.indexOf(val);
if (index > -1) {
this.splice(index, 1);
}
};
select_list.__proto__ = Array.prototype;
function removeDuplicates(arr){
if (!Array.isArray(arr)) {
console.log('type error!');
return
}
var array = [];
for (var i = 0; i < arr.length; i++) {
if (array.indexOf(arr[i]) === -1) {
array.push(arr[i])
}
}
return array;
}
</script>

View File

@@ -0,0 +1,403 @@
<link rel="stylesheet" href="STATIC_CSS/promotion_detail.css">
<style>
.layui-tab-content {padding: 0}
</style>
<div class="layui-card card-common card-brief">
<div class="layui-card-header">
<div>
<span class="card-title">基本信息</span>
</div>
</div>
<div class="layui-card-body">
<div class="promotion-view">
<div class="promotion-view-item">
<label>优惠券名称:</label>
<span>{$info.coupon_name}</span>
</div>
<div class="promotion-view-item">
<label>优惠券类型:</label>
<span>{if $info.type == 'reward'} 满减 {else /} 折扣 {/if}</span>
</div>
<div class="promotion-view-item">
<label>{if $info.type == 'reward'} 优惠券面额 {else /} 优惠券折扣 {/if}</label>
<span>{if $info.type == 'reward'} ¥ {$info.money} {else /} {$info.discount} 折 {/if}</span>
</div>
{if $info.type == 'discount'}
{if $info.discount_limit != 0}
<div class="promotion-view-item">
<label>最多优惠:</label>
<span>¥ {$info.discount_limit}</span>
</div>
{/if}
{/if}
<div class="promotion-view-item">
<label>发放数量:</label>
<span>
{if $info.count > 0 }
{$info.count} 张
{else /}
无限制
{/if}
</span>
</div>
<div class="promotion-view-item">
<label>最大领取数量:</label>
<span>{$info.max_fetch} 张</span>
</div>
<div class="promotion-view-item">
<label>使用门槛:</label>
<span>{$info.at_least} 元</span>
</div>
<div class="promotion-view-item">
<label>有效期:</label>
<span>
{if $info.validity_type == 0}
{:date('Y-m-d H:i:s',$info.end_time)}
{elseif $info.validity_type == 1 }
领取后 {$info.fixed_term} 天有效
{else /}
长期有效
{/if}
</span>
</div>
<div class="promotion-view-item">
<label>活动商品:</label>
{if $info.goods_type == 1}
<span>全部商品参与</span>
{elseif $info.goods_type == 2}
<span>指定商品</span>
{elseif $info.goods_type == 3}
<span>指定不参与商品</span>
{/if}
</div>
</div>
<div class="promotion-view">
<div class="promotion-view-item-line">
<label class="promotion-view-item-custom-label">优惠券图片:</label>
<div class="promotion-view-item-custom-box img-upload">
<div class="upload-img-block icon">
<div class="upload-img-box" id="couponImg">
{if condition="$info.image"}
<img layer-src src="{:img($info.image)}" />
{/if}
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="layui-card card-common card-brief">
<div class="layui-card-header">
<div>
<span class="card-title">数据统计</span>
</div>
</div>
<div class="layui-card-body">
<div class="promotion-stat-view todo-list">
<div class="promotion-stat-item" >
<div class="promotion-stat-item-title">发放数</div>
<div class="promotion-stat-item-value">{$info.count}</div>
</div>
<div class="promotion-stat-item" >
<div class="promotion-stat-item-title">领取数</div>
<div class="promotion-stat-item-value">{$info.lead_count}</div>
</div>
<div class="promotion-stat-item" >
<div class="promotion-stat-item-title">使用数</div>
<div class="promotion-stat-item-value">{$info.used_count}</div>
</div>
</div>
</div>
</div>
<div class="layui-card card-common card-brief">
<div class="layui-card-header">
<div>
<span class="card-title">领取记录</span>
</div>
</div>
<div class="layui-card-body layui-tab table-tab" lay-filter="coupon_tab">
<ul class="layui-tab-title">
<li class="layui-this" lay-id="">全部</li>
<li lay-id="1">已领取</li>
<li lay-id="2">已使用</li>
<li lay-id="3">已过期</li>
</ul>
<div class="layui-tab-content">
<!-- 列表 -->
<table id="coupon" lay-filter="coupon"></table>
</div>
</div>
</div>
{if $info.goods_type != 1}
<div class="layui-card card-common card-brief">
<div class="layui-card-header">
<div>
{if $info.goods_type == 2}
<span class="card-title">指定商品</span>
{elseif $info.goods_type == 3}
<span class="card-title">指定不参与商品</span>
{/if}
</div>
</div>
<div class="layui-card-body">
<div class='promotion-view-list'>
<table id="promotion_list"></table>
</div>
</div>
</div>
{/if}
<script type='text/html' id="promotion_list_item_box_html">
<div class="promotion-list-item-title">
<div class="promotion-list-item-title-icon">
<img src="{{ ns.img(d.goods_image) }}" alt="">
</div>
<p class="promotion-list-item-title-name multi-line-hiding">{{ d.goods_name }}</p>
</div>
</script>
<script type="text/html" id="memberInfo">
<div class='table-title'>
<div class='title-pic'>
<img layer-src src="{{ns.img(d.headimg)}}" onerror="this.src = '{:img('public/static/img/default_img/head.png')}' ">
</div>
<div class='title-content' onclick="location.hash = ns.hash('shop/member/editmember?member_id={{d.member_id}}')">
<p class="layui-elip">{{d.nickname}}</p>
<p class="layui-elip">{{d.mobile}}</p>
</div>
</div>
</script>
<script type="text/html" id="operation">
<div class="table-btn" align="right">
{{# if(d.state == 1){ }}
<a class="layui-btn" lay-event="recovery">回收</a>
{{# } }}
</div>
</script>
<script type="text/html" id="toolbarOperation">
<button class="layui-btn layui-btn-primary" lay-event="recovery">批量回收</button>
</script>
<script type="text/html" id="batchOperation">
<button class="layui-btn layui-btn-primary" lay-event="recovery">批量回收</button>
</script>
<script>
var promotion_list = {:json_encode($info.goods_list, JSON_UNESCAPED_UNICODE)},
coupon_type_id = {$info.coupon_type_id},
element,table,
getType = {:json_encode($get_type)};
layui.use('element', function() {
element = layui.element;
element.on('tab(coupon_tab)', function(){
table.reload({
page: {curr: 1},
where: {'state': this.getAttribute('lay-id'),"coupon_type_id": coupon_type_id},
})
});
new Table({
elem: '#promotion_list',
cols: [
[{
field: 'goods_name',
title: '商品名称',
unresize: 'false',
width: '60%',
templet: '#promotion_list_item_box_html'
}, {
field: 'price',
title: '商品价格(元)',
unresize: 'false',
align: 'right',
width: '20%',
templet: function(data) {
return '¥' + data.price;
}
}, {
field: 'goods_stock',
title: '库存',
unresize: 'false',
align: 'center',
width: '20%'
}],
],
data: promotion_list
});
table = new Table({
elem: '#coupon',
url: ns.url("coupon://shop/coupon/receive"),
where: {
"coupon_type_id": coupon_type_id
},
cols: [
[{
type: 'checkbox',
width: '3%',
unresize: 'false'
},{
templet: '#memberInfo',
title: '会员信息',
width: '20%',
unresize: 'false'
}, {
field: 'coupon_name',
title: '优惠券',
width: '10%',
unresize: 'false',
templet: function(data) {
return `<a href="`+ ns.href('coupon://shop/coupon/detail', {coupon_type_id: data.coupon_type_id }) +`" target="_blank" class="text-color">`+ data.coupon_name +`</a>`;
}
}, {
title: '类型',
width: '10%',
unresize: 'false',
templet: function (data) {
return data.type == 'reward' ? '满减券' : '折扣券';
}
}, {
title: '获取方式',
width: '10%',
unresize: 'false',
templet: function(data) {
return getType[data.get_type] ? getType[data.get_type] : '';
}
}, {
title: '状态',
width: '12%',
unresize: 'false',
templet: function (data) {
var str = '';
switch (data.state) {
case 1:
str = '已领取';
break;
case 2:
str = '已使用';
break;
case 3:
str = '已过期';
break;
}
return str;
}
}, {
title: '领取时间',
width: '15%',
unresize: 'false',
templet: function(data) {
return ns.time_to_date(data.fetch_time);
}
}, {
title: '使用时间',
width: '15%',
templet: function(data) {
return data.use_time ? ns.time_to_date(data.use_time) : '';
}
},
{
title: '操作',
width: '5%',
templet: '#operation'
}
]
],
parseData: function(data){
data.data.list = data.data.list.map(function (item) {
item.LAY_DISABLED = item.state != 1;
return item;
})
return {
"code": data.code,
"msg": data.message,
"count": data.data.count,
"data": data.data.list
};
},
toolbar: '#toolbarOperation',
bottomToolbar: "#batchOperation"
});
table.tool(function(obj) {
var data = obj.data;
switch (obj.event) {
case 'recovery': //编辑
recoveryCoupon([{coupon_type_id: data.coupon_type_id, coupon_id: data.coupon_id}]);
break;
}
})
/**
* 批量操作
*/
table.bottomToolbar(function(obj) {
if (obj.data.length < 1) {
layer.msg('请选择要操作的数据');
return;
}
switch (obj.event) {
case "recovery":
var id_array = new Array();
for (i in obj.data) id_array.push({coupon_type_id: obj.data[i].coupon_type_id, coupon_id: obj.data[i].coupon_id});
recoveryCoupon(id_array);
break;
}
});
/**
* 批量操作
*/
table.toolbar(function(obj) {
if (obj.data.length < 1) {
layer.msg('请选择要操作的数据');
return;
}
switch (obj.event) {
case "del":
var id_array = new Array();
for (i in obj.data) id_array.push({coupon_type_id: obj.data[i].coupon_type_id, coupon_id: obj.data[i].coupon_id});
recoveryCoupon(id_array);
break;
}
});
});
function recoveryCoupon(data) {
layer.confirm('回收将会收回会员领取的待使用的优惠券,已使用的将无法回收,确定要回收所选优惠券吗?', function(index) {
layer.close(index);
$.ajax({
url: ns.url("coupon://shop/coupon/recoverycoupon"),
data: {
coupon_list: JSON.stringify(data)
},
dataType: 'JSON',
type: 'POST',
success: function(res) {
layer.msg(res.message);
if (res.code == 0) {
table.reload();
}
}
});
})
}
</script>

View File

@@ -0,0 +1,813 @@
<style>
.discount {
display: flex;
justify-content: space-between;
height: 34px;
line-height: 34px;
padding: 5px 15px;
background-color: #F6FBFD;
border: 1px dashed #BCE8F1;
}
.exchange-type {
padding: 0 20px;
position: relative;
}
.exchange-type i{position: absolute;bottom: -10px;right: -1px;display: none;}
.exchange-type.border-color i{display: block;}
.form-wrap {
position: relative;
}
.custom-right {
position: absolute;
top: 150px;
left: 900px;
padding: 20px 0;
box-sizing: border-box;
overflow: hidden;
background-color: #fff;
height: 500px;
width: 600px;
}
.custom-right .phone {
min-width: 280px;
height: 600px;
background: url(__STATIC__/img/quan.png) no-repeat center;
background-size: contain;
position: relative;
overflow: auto;
padding-top: 30px;
box-sizing: border-box;
}
.custom-right .phone h2 {
position: absolute;
left: 250px;
top: 80px;
}
.item {
position: absolute;
top: 100px;
left: 165px;
width: 274px;
height: 100px;
display: flex;
background: url(__STATIC__/img/quan_bj.png) no-repeat center;
border-radius: 10px;
align-items: stretch;
overflow: hidden;
font-size: 13px;
}
.item-base {
position: relative;
width: 65px;
min-width: 65px;
text-align: center;
background-repeat: no-repeat;
background-size: 100% 100%;
padding: 10px 10px 0 10px;
}
.item-base p {
display: inline-block;
}
.item .item-base .aaa {
height: auto;
position: relative;
top: 50%;
right: 5px;
transform: translate(0, -50%);
}
.item-info {
margin: 0 20px 0 0;
width: 100px;
}
.use_price {
line-height: 1;
color: #fff;
}
.use_condition {
color: #fff;
margin-top: 15px;
font-size: 12px;
}
.use_title {
margin-top: 10px !important;
}
.item-btn {
width: 50px;
min-width: 50px;
align-self: center;
position: relative;
}
.item-btn .btn {
font-size: 12px;
width: 40px;
height: 24px;
border-radius: 20px;
line-height: 24px;
margin-left: 20px;
text-align: center;
background-image: linear-gradient(to right, #fc6831, #ff4544);
color: #fff;
}
.max_price {
margin: 5px 0;
padding-bottom: 5px;
border-bottom: 1px dashed #d7d2d1;
font-size: 12px;
}
.use_time span {
display: inline-block;
font-size: 12px;
color: #909399;
}
.priceaaaa {
font-size: 16px;
}
.thistitle {
font-size: 14px;
}
</style>
<div class="layui-form form-wrap">
<div class="layui-form-item">
<label class="layui-form-label"><span class="required">*</span>优惠券名称:</label>
<div class="layui-input-block">
<input type="text" name="coupon_name" value="{$coupon_type_info.coupon_name}" lay-verify="required" autocomplete="off" class="layui-input len-long" maxlength="15">
</div>
</div>
<div class="layui-form">
<div class="layui-form-item">
<label class="layui-form-label">优惠券类型:</label>
<div class="layui-input-block">
<button class="layui-btn layui-btn-primary exchange-type {if $coupon_type_info.type == 'reward'} border-color {/if}" data-status="reward">满减<i class="iconfont iconxuanzhong text-color"></i></button>
<button class="layui-btn layui-btn-primary exchange-type {if $coupon_type_info.type == 'discount'} border-color {/if}" data-status="discount">折扣<i class="iconfont iconxuanzhong text-color"></i></button>
<input type="hidden" name="type" value="{$coupon_type_info.type}">
</div>
</div>
</div>
<div class="layui-form-item" id="coupon_type">
{if $coupon_type_info.type == 'reward'}
<label class="layui-form-label"><span class="required">*</span>优惠券面额:</label>
<div class="layui-input-block">
<div class="layui-input-inline">
<input type="number" name="money" value="{$coupon_type_info.money}" lay-verify="required|number|money|coupon_money" autocomplete="off" class="layui-input len-short">
</div>
<span class="layui-form-mid"></span>
</div>
<div class="word-aux">
<p>价格不能小于等于0可保留两位小数</p>
</div>
{else /}
<label class="layui-form-label"><span class="required">*</span>优惠券折扣:</label>
<div class="layui-input-block">
<div class="layui-input-inline">
<input type="number" name="discount" min="1" value="{$coupon_type_info.discount}" lay-verify="required|fl" autocomplete="off" class="layui-input len-short">
</div>
<span class="layui-form-mid"></span>
</div>
<div class="word-aux">
<p>优惠券折扣不能小于1折且不可大于9.9折,可保留两位小数</p>
</div>
{/if}
</div>
{if $coupon_type_info.type == 'discount'}
<div class="layui-form-item discount_limit">
<label class="layui-form-label">最多优惠:</label>
<div class="layui-input-block">
<div class="layui-input-inline">
<input type="number" name="discount_limit" min=0 value="{$coupon_type_info.discount_limit}" lay-verify="number|int" autocomplete="off" class="layui-input len-short">
</div>
<span class="layui-form-mid"></span>
</div>
</div>
{/if}
<div class="layui-form-item">
<label class="layui-form-label"><span class="required">*</span>满多少元可以使用:</label>
<div class="layui-input-block">
<div class="layui-input-inline">
<input type="number" name="at_least" value="{$coupon_type_info.at_least}" lay-verify="required|number|money" autocomplete="off" class="layui-input len-short">
</div>
<span class="layui-form-mid"></span>
</div>
<div class="word-aux">
<p>价格不能小于0可保留两位小数</p>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">是否允许直接领取:</label>
<div class="layui-input-block">
<input type="checkbox" name="is_show" min=0 lay-filter="is_show" value="1" lay-skin="switch" {if condition="$coupon_type_info.is_show == 1" }checked{/if} />
</div>
</div>
<div class="receive-limit" {if $coupon_type_info.is_show eq 0}style="display:none;"{/if}>
<div class="layui-form-item">
<label class="layui-form-label"><span class="required">*</span>发放数量:</label>
<div class="layui-input-block">
<div class="layui-input-inline">
<input type="number" name="count" min=0 value="{$coupon_type_info.count}" lay-verify="count" autocomplete="off" class="layui-input len-short" {if $coupon_type_info.count == -1}disabled style="cursor:not-allowed"{/if}>
</div>
<span class="layui-form-mid"></span>
</div>
<div class="word-aux">
<p>优惠券发放数量,没有之后不能领取或发放,-1为不限制发放数量,发放数量只能增加不能减少。</p>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label"><span class="required">*</span>最大领取数量:</label>
<div class="layui-input-block">
<div class="layui-input-inline">
<input type="number" name="max_fetch" min=0 value="{$coupon_type_info.max_fetch}" lay-verify="max" autocomplete="off" class="layui-input len-short">
</div>
<span class="layui-form-mid"></span>
</div>
<div class="word-aux">
<p>数量不能小于0且必须为整数设置为0时可无限领取</p>
</div>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">优惠券图片:</label>
<div class="layui-input-block img-upload">
<div class="upload-img-block">
<div class="upload-img-box {notempty name=" $coupon_type_info['image']"}hover{/notempty}">
<div class="upload-default " id="couponImg">
{if condition="$coupon_type_info.image"}
<div id="preview_couponImg" class="preview_img">
<img layer-src src="{:img($coupon_type_info.image)}" class="img_prev" />
</div>
{else/}
<div class="upload">
<i class="iconfont iconshangchuan"></i>
<p>点击上传</p>
</div>
{/if}
</div>
<div class="operation">
<div>
<i title="图片预览" class="iconfont iconreview js-preview" style="margin-right: 20px;"></i>
<i title="删除图片" class="layui-icon layui-icon-delete js-delete"></i>
</div>
<div class="replace_img js-replace">点击替换</div>
</div>
<input type="hidden" class="layui-input" name="image" value="{$coupon_type_info.image}" />
</div>
</div>
</div>
<div class="word-aux">
<p>建议尺寸325*95像素图片上传默认不限制大小</p>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">有效期类型:</label>
<div class="layui-input-block">
<input type="radio" name="validity_type" value="0" lay-filter="filter" title="固定时间" {if condition="$coupon_type_info.validity_type == 0" }checked{/if}>
<input type="radio" name="validity_type" value="1" lay-filter="filter" title="领取之日起" {if condition="$coupon_type_info.validity_type == 1" }checked{/if}>
<input type="radio" name="validity_type" value="2" lay-filter="filter" title="长期有效" {if condition="$coupon_type_info.validity_type == 2" }checked{/if}>
</div>
</div>
<div class="layui-form-item end-time validity-type validity-type-0">
<label class="layui-form-label ">活动结束时间:</label>
<div class="layui-input-block">
<input type="text" name="end_time" value="{:date('Y-m-d H:i:s',$coupon_type_info.end_time)}" lay-verify="time" id="end_time" class="layui-input len-mid" readonly>
</div>
</div>
<div class="layui-form-item fixed-term validity-type validity-type-1">
<label class="layui-form-label">领取后几天有效:</label>
<div class="layui-input-block">
<div class="layui-input-inline">
<input type="number" name="fixed_term" value="{$coupon_type_info.fixed_term}" lay-verify="days" autocomplete="off" class="layui-input len-short">
</div>
<span class="layui-form-mid"></span>
</div>
<div class="word-aux">
<p>不能小于0且必须为整数</p>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label"><span class="required">*</span>活动商品:</label>
<div class="layui-input-block">
<input type="radio" name="goods_type" lay-filter="goods_type" value="1" title="全部商品参与" {if $coupon_type_info.goods_type==1} checked {/if}>
<input type="radio" name="goods_type" lay-filter="goods_type" value="2" title="指定商品参与" {if $coupon_type_info.goods_type==2} checked {/if}>
</div>
</div>
<div class="layui-form-item goods_list" {if $coupon_type_info.goods_type == 1}style="display:none"{/if}>
<label class="layui-form-label"></label>
<div class="layui-input-block">
<table id="selected_sku_list"></table>
<button class="layui-btn" onclick="addGoods()">选择商品</button>
<span class="goods_num">已选商品(<span id="goods_num" class="text-color">{$coupon_type_info.goods_list_count}</span></span>
</div>
</div>
<input type="hidden" name="goods_ids">
<div class="form-row">
<button class="layui-btn" lay-submit lay-filter="save">保存</button>
<button class="layui-btn layui-btn-primary" onclick="back()">返回</button>
<a id="imageId"></a>
</div>
<input type="hidden" name="site_id" value="{$coupon_type_info.site_id}" />
<input type="hidden" name="coupon_type_id" value="{$coupon_type_info.coupon_type_id}" />
</div>
<!-- 操作 -->
<script type="text/html" id="operation">
<div class="table-btn">
<a class="layui-btn" onclick="delGoods({{d.goods_id}})">删除</a>
</div>
</script>
<script>
var validity_type = $("input[name='validity_type']:checked").val();
var saveData = null;
var totalUploadNum = 0;
var completeUploadNum = 0;
var upload;
$('.validity-type').hide();
$('.validity-type-' + validity_type).show();
var delRule, selectedGoodsId = [], goods_id = [], table;
var goods_list = {:json_encode($coupon_type_info.goods_list, JSON_UNESCAPED_UNICODE)};
$("body").off("change", 'input[name="money"]').on("change", 'input[name="money"]', function() {
let aa = $('input[name="money"]').val();
$('.priceaaaa').html('¥' + aa)
});
$("body").off("change", 'input[name="discount"]').on("change", 'input[name="discount"]', function() {
let bb = $('input[name="discount"]').val();
$('.pricebbbb').html(bb + ' 折 ')
});
$('input[name="at_least"]').change(function() {
let cc = $('input[name="at_least"]').val();
$('.use_price2').html(cc)
})
$('input[name="fixed_term"]').change(function() {
var time_time = $('input[name="fixed_term"]').val();
$('.time-bbb').html('有效期:领取之日起' + time_time + '日内有效');
})
$("body").off("change", 'input[name="coupon_name"]').on("change", 'input[name="coupon_name"]', function() {
let dd = $('input[name="coupon_name"]').val();
$('.thistitle').html(dd)
});
$.each(goods_list, function(index, item) {
var id = item.goods_id;
selectedGoodsId.push(id);
goods_id.push(id);
});
$("input[name='goods_ids']").val(goods_id.toString());
layui.use(['form', 'laydate'], function() {
var form = layui.form,
laydate = layui.laydate,
repeat_flag = false, //防重复标识
currentDate = new Date(); //当前时间
form.render();
form.on('switch(is_show)', function (data) {
if ($(data.elem).is(':checked')) {
$('.receive-limit').show();
} else {
$('.receive-limit').hide();
}
});
// 时间模块
laydate.render({
elem: '#end_time', //指定元素
type: 'datetime',
// value: currentDate,
done: function(value, date, endDate) {
$('.time-aaa').html('有效期:' + value);
}
});
var date = new Date(currentDate);
var y = date.getFullYear();
var m = date.getMonth() + 1;
m = m < 10 ? ('0' + m) : m;
var d = date.getDate();
d = d < 10 ? ('0' + d) : d;
var h = date.getHours();
var minute = date.getMinutes();
var second = date.getSeconds();
minute = minute < 10 ? ('0' + minute) : minute;
let time = y + '-' + m + '-' + d + ' ' + h + ':' + minute + ':' + second;
$('.time-aaa').html('有效期:' + time);
var time_time = $('input[name="fixed_term"]').val();
$('.time-bbb').html('有效期:领取之日起' + time_time + '日内有效');
renderTable(goods_list); // 初始化表格
//监听活动商品类型
form.on('radio(goods_type)', function(data) {
var value = data.value;
if (value == 1) {
$(".goods_list").hide();
$('.max_price').html('全场商品');
} else if (value == 2) {
$(".goods_list").show();
$('.max_price').html('指定商品');
} else if (value == 3) {
$(".goods_list").show();
$('.max_price').html('指定不参与商品');
}
});
// 监听单选按钮
form.on('radio(filter)', function(data) {
$('.validity-type').hide();
$('.validity-type-' + data.value).show();
});
/**
* 表单验证
*/
form.verify({
days: function (value) {
var validity_type = $('[name="validity_type"]:checked').val();
if (validity_type == 1) {
if (value % 1 != 0) {
return '请输入整数';
}
if (value <= 0) {
return '有效天数不能小于等于0';
}
}
},
number: function (value) {
if (value < 0) {
return '请输入不小于0的数!'
}
},
coupon_money: function (value) {
if (parseFloat(value) > 10000) {
return '优惠券面额不能大于10000'
}
if(parseFloat(value) <= 0){
return '优惠券面额不能小于0'
}
},
int: function (value) {
if (value % 1 != 0) {
return '请输入整数!'
}
if (value < 0) {
return '请输入大于0的数!'
}
},
money: function (value) {
if(value < 0){
return '金额不能小于0'
}
var arrMen = value.split(".");
var val = 0;
if (arrMen.length == 2) {
val = arrMen[1];
}
if (val.length > 2) {
return '保留小数点后两位'
}
},
time: function (value) {
var validity_type = $('[name="validity_type"]:checked').val();
if (validity_type == 0) {
var now_time = (new Date()).getTime();
var end_time = (new Date(value)).getTime();
if (now_time > end_time) {
return '结束时间不能小于当前时间!'
}
}
},
max: function (value) {
if ($('[name="is_show"]').is(':checked')) {
if (!/[\S]+/.test(value)) {
return '请输入最大领取数量';
}
var _count = $("input[name=count]").val();
if (_count != -1 && parseFloat(value) > parseFloat(_count)) {
return '最大领取数量不能超过发放数量!';
}
}
},
fl: function (value, item) {
var str = $(item).parents(".layui-form-item").find("label").text().split("*").join(
"");
str = str.substring(0, str.length - 1);
if (value < 1) {
return str + "不能小于1折";
}
if (value > 9.9) {
return str + "不能大于9.9折";
}
var arrMen = value.split(".");
var val = 0;
if (arrMen.length == 2) {
val = arrMen[1];
}
if (val.length > 2) {
return str + "最多可保留两位小数";
}
},
count: function (value) {
if ($('[name="is_show"]').is(':checked')) {
if (!/[\S]+/.test(value)) {
return '请输入发放数量';
}
if (value % 1 != 0) {
return '请输入整数';
}
if (value == 0) {
return '发放数量不能为0';
}
if (value != -1 && parseInt(value) < parseInt('{$coupon_type_info.count}')) {
return '发放数量不能小于原发放数量!';
}
}
}
});
upload = new Upload({
elem: '#couponImg',
auto:false,
bindAction:'#imageId',
callback: function(res) {
uploadComplete('image', res.data.pic_path);
}
});
function uploadComplete(field, pic_path) {
saveData.field[field] = pic_path;
completeUploadNum += 1;
if(completeUploadNum == totalUploadNum){
saveFunc();
}
}
function saveFunc() {
var data = saveData;
// 删除图片
if (!data.field.image) upload.delete();
$.ajax({
url: ns.url("coupon://shop/coupon/edit"),
data: data.field,
dataType: 'JSON',
type: 'POST',
success: function (res) {
repeat_flag = false;
if (res.code == 0) {
layer.confirm('编辑成功', {
title: '操作提示',
btn: ['返回列表', '继续编辑'],
yes: function(index, layero) {
location.hash = ns.hash("coupon://shop/coupon/lists")
layer.close(index);
},
btn2: function(index, layero) {
layer.close(index);
}
});
} else {
layer.msg(res.message);
}
}
});
}
/**
* 监听提交
*/
form.on('submit(save)', function(data) {
if (data.field.goods_type != 1) {
if (data.field.goods_ids == '') {
layer.msg("请选择商品");
return;
}
}
if (repeat_flag) return;
repeat_flag = true;
let new_goods_ids = [];
goods_list.forEach((item, i) => {
new_goods_ids.push(item.goods_id)
});
data.field.goods_ids = new_goods_ids.join(',');
saveData = data;
var obj = $("img.img_prev[data-prev='1']");
totalUploadNum = obj.length;
if (totalUploadNum > 0) {
obj.each(function () {
var actionId = $(this).attr('data-action-id');
$(actionId).click();
})
} else {
saveFunc();
}
});
delRule = function(obj) {
$(obj).parent().parent().remove();
};
$(".exchange-type").click(function() {
$(this).addClass("border-color");
$(this).siblings("button").removeClass("border-color");
var type = $(this).attr('data-status');
var current_type = $("input[name='type']").val();
if (current_type == type) {
return false;
}
$("input[name='type']").val(type);
var html = '';
if (type == 'reward') {
html += '<label class="layui-form-label"><span class="required">*</span>优惠券面额:</label>' +
'<div class="layui-input-block">' +
'<div class="layui-input-inline">' +
'<input type="number" name="money" min="0" lay-verify="required|number|money" autocomplete="off" class="layui-input len-short">' +
'</div>' +
'<span class="layui-form-mid">元</span>' +
'</div>' +
'<div class="word-aux">' +
'<p>价格不能小于0可保留两位小数</p>' +
'</div>';
$('.discount_limit').remove();
$("body").off("change", 'input[name="money"]').on("change", 'input[name="money"]', function() {
let aa = $('input[name="money"]').val();
$('.priceaaaa').html('¥' + aa)
});
}
if (type == 'discount') {
html += '<label class="layui-form-label"><span class="required">*</span>优惠券折扣:</label>' +
'<div class="layui-input-block">' +
'<div class="layui-input-inline">' +
'<input type="number" name="discount" min="1" lay-verify="required|fl" autocomplete="off" class="layui-input len-short">' +
'</div>' +
'<span class="layui-form-mid">折</span>' +
'</div>' +
'<div class="word-aux">' +
'<p>优惠券折扣不能小于1折且不可大于9.9折,可保留两位小数</p>' +
'</div>';
var discount_limit = '';
discount_limit += '<div class="layui-form-item discount_limit">' +
'<label class="layui-form-label">最多优惠:</label>' +
'<div class="layui-input-block">' +
'<div class="layui-input-inline">' +
'<input type="number" name="discount_limit" min="0" lay-verify="number|int" autocomplete="off" class="layui-input len-short">' +
'</div>' +
'<span class="layui-form-mid">元</span>' +
'</div>' +
'</div>';
$('#coupon_type').after(discount_limit);
$("body").off("change", 'input[name="discount"]').on("change", 'input[name="discount"]', function() {
let bb = $('input[name="discount"]').val();
$('.pricebbbb').html(bb + ' 折 ')
});
}
$('#coupon_type').html(html);
});
});
// 表格渲染
function renderTable(goods_list) {
//展示已知数据
table = new Table({
elem: '#selected_sku_list',
cols: [
[{
field: 'goods_name',
title: '商品名称',
unresize: 'false',
width: '50%'
}, {
field: 'price',
title: '商品价格(元)',
unresize: 'false',
align: 'right',
width: '20%',
templet: function(data) {
return '¥' + data.price;
}
}, {
field: 'goods_stock',
title: '库存',
unresize: 'false',
align: 'center',
width: '20%'
}, {
title: '操作',
toolbar: '#operation',
unresize: 'false',
align:'right'
}],
],
data: goods_list,
});
}
// 删除选中商品
function delGoods(id) {
var i, j;
$.each(goods_list, function(index, item) {
var goods_id = item.goods_id;
if (id == goods_id) {
i = index;
}
});
goods_list.splice(i, 1);
renderTable(goods_list);
$.each(selectedGoodsId, function(index, item) {
if (id == item) {
j = index;
}
});
selectedGoodsId.splice(j, 1);
goods_id = selectedGoodsId;
$("#goods_num").html(selectedGoodsId.length);
$("input[name='goods_ids']").val(goods_id.toString());
}
function addGoods() {
goodsSelect(function (data) {
if (!Object.keys(data).length) return;
goods_id = [];
goods_list = [];
for (var key in data) {
goods_id.push(data[key].goods_id);
goods_list.push(data[key]);
}
renderTable(goods_list);
$("input[name='goods_ids']").val(goods_id.toString());
selectedGoodsId = goods_id;
$("#goods_num").html(selectedGoodsId.length)
}, selectedGoodsId, {mode: "spu", is_weigh: 1});
}
function back() {
location.hash = ns.hash("coupon://shop/coupon/lists");
}
</script>

View File

@@ -0,0 +1,557 @@
<link rel="stylesheet" href="SHOP_CSS/goods_lists.css">
<link rel="stylesheet" type="text/css" href="__STATIC__/ext/searchable_select/searchable_select.css"/>
<style>
.layui-layer-page .layui-layer-content { padding: 20px 30px; }
.layui-layout-admin.admin-style-2 .body-content{padding-top:15px !important;}
.layui-layout-admin.admin-style-2 .table-tab .layui-tab-title{margin-bottom: 15px;}
.prompt-con{text-align: left}
.layui-form-select {background: #fff}
.table-bottom .layui-table-page {position: inherit;text-align: right}
</style>
<!-- 按钮容器 -->
<div class="single-filter-box top">
<button class="layui-btn" onclick="add()">添加优惠券</button>
</div>
<!-- 筛选面板 -->
<div class="screen layui-collapse" lay-filter="selection_panel">
<div class="layui-colla-item">
<form class="layui-colla-content layui-form layui-show">
<div class="layui-form-item">
<div class="layui-inline">
<label class="layui-form-label">优惠券名称:</label>
<div class="layui-input-inline">
<input type="text" name="coupon_name" placeholder="请输入优惠券名称" autocomplete="off" class="layui-input">
</div>
</div>
<div class="layui-inline">
<label class="layui-form-label">优惠券类型:</label>
<div class="layui-input-inline">
<select name="type">
<option value="">全部</option>
<option value="reward">满减</option>
<option value="discount">折扣</option>
</select>
</div>
</div>
<div class="layui-inline">
<label class="layui-form-label">优惠券状态:</label>
<div class="layui-input-inline">
<select name="status">
<option value="">全部</option>
<option value="1">进行中</option>
<option value="2">已结束</option>
<option value="-1">已关闭</option>
</select>
</div>
</div>
</div>
<div class="layui-form-item">
<div class="layui-inline">
<label class="layui-form-label">有效期限:</label>
<div class="layui-input-inline">
<select name="validity_type" lay-filter="validity_type">
<option value="">全部</option>
<option value="0">固定时间</option>
<option value="1">相对时间</option>
<option value="2">长期有效</option>
</select>
</div>
</div>
<div class="layui-inline relative-time layui-hide">
<div class="layui-input-inline split">从发券</div>
<div class="layui-input-inline">
<input type="number" class="layui-input len-short" lay-verify="int" id="start_day" placeholder="开始天数" autocomplete="off">
</div>
<div class="layui-input-inline split"></div>
<div class="layui-input-inline end-time">
<input type="number" class="layui-input len-short" lay-verify="int" id="end_day" placeholder="结束天数" autocomplete="off">
</div>
</div>
<div class="layui-inline fixed-time layui-hide">
<div class="layui-input-inline">
<input type="text" class="layui-input" id="start_date" placeholder="开始时间" autocomplete="off" readonly>
<i class=" iconrili iconfont calendar"></i>
</div>
<div class="layui-input-inline split">&nbsp;&nbsp;-&nbsp;&nbsp;</div>
<div class="layui-input-inline end-time">
<input type="text" class="layui-input" id="end_date" placeholder="结束时间" autocomplete="off" readonly>
<i class=" iconrili iconfont calendar"></i>
</div>
</div>
<input type="hidden" class="layui-input" name="start_time">
<input type="hidden" class="layui-input" name="end_time">
</div>
<div class="form-row">
<button class="layui-btn" lay-submit lay-filter="search">筛选</button>
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
</div>
</form>
</div>
</div>
<div class="layui-tab table-tab" lay-filter="coupon_tab">
<div class="layui-tab-content">
<!-- 列表 -->
<table id="coupon_list" lay-filter="coupon_list"></table>
</div>
</div>
<script type="text/html" id="validity">
{{# if(d.validity_type == 0){ }}
失效期{{ ns.time_to_date(d.end_time) }}
{{# } else if(d.validity_type == 1) { }}
领取后{{ d.fixed_term }}天有效
{{# } else { }}
长期有效
{{# } }}
</script>
<!-- 推广 -->
{include file="app/shop/view/promote.html"}
<!-- 批量操作 -->
<script type="text/html" id="toolbarAction">
<button class="layui-btn layui-btn-primary" lay-event="delete">批量删除</button>
<button class="layui-btn layui-btn-primary" lay-event="close">批量关闭</button>
</script>
<!-- 操作 -->
<script type="text/html" id="operation">
<div class="operation-wrap" data-coupon-id="{{d.coupon_type_id}}">
<div class="popup-qrcode-wrap" style="display: none"><img class="popup-qrcode-loadimg" src="__STATIC__/loading/loading.gif"/></div>
<div class="table-btn">
<!-- 进行中 -->
{{# if(d.status == 1){ }}
<a class="layui-btn" lay-event="edit">编辑</a>
<!-- <a class="layui-btn" lay-event="detail">详情</a> -->
<a class="layui-btn" lay-event="close">关闭</a>
{{# } }}
<!-- 已结束 -->
{{# if(d.status == 2){ }}
<!-- <a class="layui-btn" lay-event="detail">详情</a> -->
<a class="layui-btn" lay-event="del">删除</a>
{{# } }}
<!-- 已关闭 -->
<!-- {{# if(d.status == -1){ }}
<a class="layui-btn" lay-event="detail">详情</a> -->
<a class="layui-btn" lay-event="del">删除</a>
{{# } }}
</div>
</div>
</script>
<!-- 编辑排序 -->
<script type="text/html" id="editSort">
<input name="sort" type="number" onchange="editSort({{d.coupon_type_id}}, this)" value="{{d.sort}}" class="layui-input edit-sort len-short">
</script>
<script>
var laytpl;
layui.use(['form', 'laytpl','laydate'], function() {
var table,
form = layui.form,
laydate = layui.laydate,
laytpl = layui.laytpl,
validityType = 0,
repeat_flag = false; //防重复标识
form.render();
table = new Table({
elem: '#coupon_list',
url: ns.url("coupon://shop/coupon/lists"),
cols: [
[{
type: 'checkbox',
width: '3%',
},{
field: 'coupon_name',
title: '优惠券名称',
unresize: 'false',
width: '10%'
},{
field: 'reward',
title: '优惠券类型',
unresize: 'false',
width: '10%',
templet: function(data) {
if(data.type == 'reward'){
return '满减';
}else{
return '折扣';
}
}
}, {
title: '<span style="padding-right: 15px;">优惠金额/折扣</span>',
unresize: 'false',
width: '10%',
align: 'left',
templet: function(data) {
if(data.type == 'reward'){
return '<span style="padding-right: 15px;">¥'+ data.money +'</span>';
}else{
return '<span style="padding-right: 15px;">'+ data.discount +'折</span>';
}
}
}, {
field: 'count',
title: '发放数量',
unresize: 'false',
width: '10%',
templet: function(data){
return data.is_show == 0 || data.count == -1 ? '无限制' : data.count;
}
}, {
title: '剩余数量',
unresize: 'false',
width: '10%',
templet: function(data){
return data.is_show == 0 || data.count == -1 ? '无限制' : data.count-data.lead_count;
}
},{
title: '领取上限',
unresize: 'false',
width: '10%',
templet: function(data){
return data.is_show == 0 || data.max_fetch == 0 ? '无领取限制' : data.max_fetch + '张/人';
}
}, {
title: '有效期限',
unresize: 'false',
templet: '#validity',
width: '15%'
}, {
field: 'status_name',
title: `<div class="prompt-block">状态
<div class="prompt">
<i class="iconfont iconwenhao1 required growth"></i>
<div class="growth-box reason-box reason-growth prompt-box">
<div class="prompt-con">
<p>时间超过优惠券设置的结束时间或有效期限时,优惠券自动关闭</p>
<p>手动关闭优惠券后,用户将不能领取该优惠券,但是已经领取的优惠券(未到期)仍然可以使用</p>
</div>
</div>
</div>
</div>`,
unresize: 'false',
width: '8%'
}, {
title: '操作',
toolbar: '#operation',
unresize: 'false',
width: '17%',
align : 'right'
}]
],
toolbar: '#toolbarAction'
});
// 监听工具栏操作
table.toolbar(function (obj) {
var data = obj.data;
if(data.length <= 0) return;
var couponTypeIdAll = [];
for (var i in data){
couponTypeIdAll.push(data[i].coupon_type_id);
}
switch (obj.event) {
case 'delete':
deleteCouponAll(couponTypeIdAll)
break;
case 'close':
closeCouponAll(couponTypeIdAll)
break;
}
})
function deleteCouponAll(data){
layer.confirm('确定要删除优惠券吗?', function(index) {
if (repeat_flag) return false;
repeat_flag = true;
layer.close(index);
$.ajax({
url: ns.url("coupon://shop/coupon/deleteAll"),
data: {
coupon_type_id: data
},
dataType: 'JSON',
type: 'POST',
success: function(res) {
layer.msg(res.message);
repeat_flag = false;
table.reload({
page: {
curr: 1
},
});
}
});
}, function() {
layer.close();
repeat_flag = false;
});
}
function closeCouponAll(data){
layer.confirm('确定要关闭吗?关闭后买家将无法再领取优惠券,但已领取的将不受影响!', function(index) {
if (repeat_flag) return false;
repeat_flag = true;
layer.close(index);
$.ajax({
url: ns.url("coupon://shop/coupon/closeAll"),
data: {
coupon_type_id: data
},
dataType: 'JSON',
type: 'POST',
success: function(res) {
layer.msg(res.message);
repeat_flag = false;
if (res.code == 0) {
table.reload();
}
}
});
}, function() {
layer.close();
repeat_flag = false;
});
}
/**
* 监听工具栏操作
*/
table.tool(function(obj) {
var data = obj.data;
switch (obj.event) {
case 'edit': //编辑
location.hash = ns.hash("coupon://shop/coupon/edit", {"coupon_type_id": data.coupon_type_id});
break;
case 'del': //删除
layer.confirm('确定要删除该优惠券吗?', function(index) {
if (repeat_flag) return false;
repeat_flag = true;
layer.close(index);
$.ajax({
url: ns.url("coupon://shop/coupon/delete"),
data: data,
dataType: 'JSON',
type: 'POST',
success: function(res) {
layer.msg(res.message);
repeat_flag = false;
if (res.code == 0) {
table.reload({
page: {
curr: 1
},
});
}
}
});
}, function() {
layer.close();
repeat_flag = false;
});
break;
case 'close': //关闭
layer.confirm('确定要关闭吗?关闭后买家将无法再领取该优惠券,但已领取的将不受影响!', function(index) {
if (repeat_flag) return false;
repeat_flag = true;
layer.close(index);
$.ajax({
url: ns.url("coupon://shop/coupon/close", {"coupon_type_id": data.coupon_type_id}),
data: data,
dataType: 'JSON',
type: 'POST',
success: function(res) {
layer.msg(res.message);
repeat_flag = false;
if (res.code == 0) {
table.reload();
}
}
});
}, function() {
layer.close();
repeat_flag = false;
});
break;
case 'select': //推广
couponUrl(data);
break;
case 'detail': //详情
location.hash = ns.hash("coupon://shop/coupon/detail", {"coupon_type_id": data.coupon_type_id});
break;
}
});
table.on("sort",function (obj) {
table.reload({
page: {
curr: 1
},
where: {
order:obj.field,
sort:obj.type
}
});
});
// 搜索
form.on('submit(search)', function(data) {
if(validityType == 2){
data.field.start_time = $("#start_day").val();
data.field.end_time = $("#end_day").val();
}
table.reload({
page: {
curr: 1
},
where: data.field
});
return false;
});
form.on('select(validity_type)', function(data){
switch (data.value) {
case '0':
laydate.render({
elem: '#start_date', //指定元素
type: 'datetime',
done: function(value, date, endDate){
$("input[name='start_time']").val(ns.date_to_time(value));
}
});
laydate.render({
elem: '#end_date', //指定元素
type: 'datetime',
done: function(value, date, endDate){
$("input[name='end_time']").val(ns.date_to_time(value));
}
});
$(".relative-time").addClass("layui-hide");
$(".fixed-time").removeClass("layui-hide");
break;
case '1':
validityType = 2;
$(".relative-time").removeClass("layui-hide");
$(".fixed-time").addClass("layui-hide");
break;
default:
$(".relative-time").addClass("layui-hide");
$(".fixed-time").addClass("layui-hide");
break;
}
});
form.verify({
int: function(value) {
if (value < 0) {
return '发券天数不能小于0';
}
}
});
// 优惠券推广
function couponUrl(data) {
if (repeat_flag) return;
repeat_flag = true;
// 先查询 H5 二维码
getCouponQrcode(data.coupon_type_id,'h5',function (res) {
res.id = res.coupon_type_id;
repeat_flag = false;
laytpl($("#promote").html()).render(res, function (html) {
layer.open({
type: 1,
area: ['730px', '450px'],
offset: '155px',
title: ['推广'],
content: html,
success: function(){
$('input[name="promote_type"][value="h5"]').attr('data-config',JSON.stringify(res.h5));
form.render();
// 推广渠道监听
promoteTypeSwitch();
// 二次查询微信小程序、支付宝小程序二维码
getCouponQrcode(data.coupon_type_id,'all',function (res) {
$('input[name="promote_type"]').each(function (index,item) {
if(res[$(item).val()]){
$(item).attr('data-config',JSON.stringify(res[$(item).val()]))
}
})
});
}
});
});
});
}
function getCouponQrcode(coupon_type_id,app_type,callback) {
$.ajax({
type: "POST",
url: ns.url("coupon://shop/coupon/couponUrl"),
data: {
coupon_type_id,
app_type
},
dataType: 'JSON',
success: function (res) {
if (callback) callback(res.data);
}
});
}
});
// 监听单元格编辑
function editSort(id, event){
var data = $(event).val();
if (data == '') {
$(event).val(0);
data = 0;
}
if(!new RegExp("^-?[0-9]\\d*$").test(data)){
layer.msg("排序号只能是整数");
return ;
}
if(data<0){
layer.msg("排序号必须大于0");
return ;
}
$.ajax({
type: 'POST',
url: ns.url("coupon://shop/coupon/couponSort"),
data: {
sort: data,
coupon_type_id: id
},
dataType: 'JSON',
success: function(res) {
layer.msg(res.message);
if(res.code==0){
table.reload();
}
}
});
}
function add() {
location.hash = ns.hash("coupon://shop/coupon/add");
}
</script>

View File

@@ -0,0 +1,110 @@
<?php
/**
*/
namespace addon\coupon\shopapi\controller;
use addon\coupon\model\Coupon as CouponModel;
use addon\coupon\model\CouponType as CouponTypeModel;
use addon\coupon\model\MemberCoupon;
use app\shopapi\controller\BaseApi;
/**
* 优惠券
*/
class Coupon extends BaseApi
{
public function __construct()
{
//执行父类构造函数
parent::__construct();
$token = $this->checkToken();
if ($token[ 'code' ] < 0) {
echo $this->response($token);
exit;
}
}
/**
* 活动列表
*/
public function lists()
{
$coupon_type_model = new CouponTypeModel();
$page = $this->params['page'] ?? 1;
$page_size = $this->params['page_size'] ?? PAGE_LIST_ROWS;
$coupon_name = $this->params['coupon_name'] ?? '';
$status = $this->params['status'] ?? '';
$condition = [];
if ($status !== '') {
$condition[] = [ 'status', '=', $status ];
}
$type = $this->params['type'] ?? '';
if ($type) {
$condition[] = [ 'type', '=', $type ];
}
//类型
$validity_type = $this->params['validity_type'] ?? '';
if ($validity_type) {
$start_time = $this->params['start_time'] ?? '';
$end_time = $this->params['end_time'] ?? '';
switch ( $validity_type ) {
case 1: //固定
$condition[] = [ 'end_time', 'between', [ $start_time, $end_time ] ];
break;
case 2:
$condition[] = [ 'fixed_term', 'between', [ $start_time, $end_time ] ];
break;
}
}
$condition[] = [ 'site_id', '=', $this->site_id ];
$condition[] = [ 'coupon_name', 'like', '%' . $coupon_name . '%' ];
$order = 'create_time desc';
$field = '*';
$res = $coupon_type_model->getCouponTypePageList($condition, $page, $page_size, $order, $field);
//获取优惠券状态
$coupon_type_status_arr = $coupon_type_model->getCouponTypeStatus();
foreach ($res[ 'data' ][ 'list' ] as $key => $val) {
$res[ 'data' ][ 'list' ][ $key ][ 'status_name' ] = $coupon_type_status_arr[ $val[ 'status' ] ];
}
return $this->response($res);
}
/**
* 发放优惠券
*/
public function send()
{
$member_id = $this->params['member_id'] ?? 0;
$coupon_type_ids = $this->params['parent'] ?? '';
$get_type = $this->params['get_type'] ?? 4;
$site_id = $this->site_id;
$parent = $coupon_type_ids;
if (empty($parent)) {
return $this->error('', 'REQUEST_COUPON_TYPE_ID');
}
$parent = explode(',', $parent);
if (count($parent) == 1) {
$coupon_model = new CouponModel();
$res = $coupon_model->receiveCoupon($parent[ 0 ], $site_id, $member_id, $get_type);
} else {
$member_coupon_model = new MemberCoupon();
$res = $member_coupon_model->sendCoupon(explode(',', $coupon_type_ids), $site_id, $member_id, $get_type);
}
return $this->response($res);
}
}