新增公共商品加入购物车操作

feat/task1-c-wallet
gongfuxiang 2022-12-08 16:22:40 +08:00
parent 0ffab4cef2
commit 5c06c7c041
7 changed files with 601 additions and 5 deletions

View File

@ -11,11 +11,12 @@
namespace app\index\controller;
use app\service\ApiService;
use app\service\SeoService;
use app\service\GoodsService;
use app\service\GoodsCommentsService;
use app\service\GoodsBrowseService;
use app\service\GoodsFavorService;
use app\service\SeoService;
use app\service\GoodsCartService;
/**
* 商品详情
@ -59,7 +60,7 @@ class Goods extends Common
'is_params' => true,
];
$ret = GoodsService::GoodsList($params);
if(!empty($ret['data']) && !empty($ret['data'][0]) && $ret['data'][0]['is_delete_time'] == 0)
if(!empty($ret['data']) && !empty($ret['data'][0]))
{
// 商品信息
$goods = $ret['data'][0];
@ -162,6 +163,45 @@ class Goods extends Common
return MyView('/public/tips_error');
}
/**
* 加入购物车页面
* @author Devil
* @blog http://gong.gg/
* @version 0.0.1
* @datetime 2017-02-22T16:50:32+0800
*/
public function CartInfo()
{
$goods_id = isset($this->data_request['id']) ? $this->data_request['id'] : 0;
$params = [
'where' => [
['id', '=', $goods_id],
['is_delete_time', '=', 0],
],
'is_spec' => true,
];
$ret = GoodsService::GoodsList($params);
if(!empty($ret['data']) && !empty($ret['data'][0]))
{
$goods = $ret['data'][0];
$buy_button = GoodsService::GoodsBuyButtonList($goods);
MyViewAssign([
'goods' => $goods,
'buy_button' => $buy_button,
'is_header' => 0,
'is_footer' => 0,
]);
return MyView();
}
MyViewAssign([
'msg' => '商品不存在或已删除',
'is_header' => 0,
'is_footer' => 0,
'is_to_home' => 0,
]);
return MyView('/public/tips_error');
}
/**
* 商品收藏
* @author Devil

View File

@ -0,0 +1,92 @@
{{include file="public/header" /}}
{{if empty($goods)}}
{{include file="public/not_data" /}}
{{else /}}
<form class="am-form form-validation am-form-popup-fixed" method="post" action="{{:MyUrl('index/cart/save')}}" request-type="ajax-fun" request-value="GoodsCartInfoSubmitBack">
<div class="goods-spec-container am-padding-sm" data-spectype-url="{{:MyUrl('index/goods/spectype')}}" data-specdetail-url="{{:MyUrl('index/goods/specdetail')}}" >
<h2>
<img src="{{$goods.images}}" width="24" height="24" />
<span class="am-margin-left-xs">{{$goods.title}}</span>
</h2>
<hr data-am-widget="divider" class="am-divider am-divider-default" />
{{if $goods.inventory gt 0}}
{{if $goods.inventory egt $goods.buy_min_number}}
<div class="goods-spec-content" data-id="{{$goods.id}}">
{{if !empty($goods['specifications']['choose'])}}
{{foreach $goods.specifications.choose as $key=>$spec}}
{{if !empty($spec['value'])}}
<div class="spec-options sku-items am-radius">
<div class="spec-title">{{$spec.name}}</div>
<ul>
{{foreach $spec.value as $keys=>$specs}}
<li class="am-radius sku-line {{if !empty($specs['images'])}} sku-line-images{{/if}} {{if $key gt 0}} sku-dont-choose{{/if}} {{if isset($specs['is_only_level_one']) and isset($specs['inventory']) and $specs['inventory'] elt 0}} sku-items-disabled{{/if}}" data-type-value="{{$spec.name}}" data-value="{{$specs.name}}" {{if !empty($specs['images'])}} data-type-images="{{$specs.images}}"{{/if}}>
{{if !empty($specs['images'])}}
<img src="{{$specs.images}}" class="am-radius" />
{{/if}}
{{$specs.name}}<i></i>
</li>
{{/foreach}}
</ul>
</div>
{{/if}}
{{/foreach}}
{{/if}}
<div class="spec-options">
<div class="spec-title">销售价</div>
<div class="am-margin-top-xs am-margin-bottom-sm">
<strong class="price am-text-lg" data-default-price="{{$goods.price}}" data-is-clearout="0">{{$currency_symbol}}{{$goods.price}}</strong>
{{if !empty($goods['original_price']) and $goods['original_price'] gt 0}}
<span class="am-margin-left-sm original-price" data-default-price="{{$goods.original_price}}" data-price="{{$goods.original_price}}">{{$currency_symbol}}{{$goods.original_price}}</span>
{{/if}}
</div>
</div>
<div class="spec-options am-margin-top-sm">
<div class="am-input-group am-input-group-sm number-operate">
<span class="am-input-group-label am-radius stock-submit" data-type="min">-</span>
<input type="number" name="stock" class="am-form-field am-text-center" value="{{$goods.buy_min_number}}" min="{{$goods.buy_min_number}}" max="{{if empty($goods['buy_max_number'])}}{{$goods.inventory}}{{else /}}{{$goods.buy_max_number}}{{/if}}" data-original-max="{{if empty($goods['buy_max_number'])}}{{$goods.inventory}}{{else /}}{{$goods.buy_max_number}}{{/if}}" data-is-clearout="0" />
<span class="am-input-group-label am-radius stock-submit" data-type="add">+</span>
</div>
<span class="am-margin-left-sm stock-tips">库存<span class="stock" data-original-stock="{{$goods.inventory}}" data-min-limit="{{$goods.buy_min_number}}" data-max-limit="{{$goods.buy_max_number}}" data-unit="{{$goods.inventory_unit}}">{{$goods.inventory}}</span>{{$goods.inventory_unit}}</span>
</div>
</div>
{{else /}}
<p class="am-text-danger error-msg">库存不足起购数({{$goods.inventory}}<{{$goods.buy_min_number}})</p>
{{/if}}
{{else /}}
<p class="am-text-danger">没货了</p>
{{/if}}
</div>
<div class="am-form-popup-submit">
<input type="hidden" name="goods_id" value="{{$goods.id}}" />
<input type="hidden" name="spec" value="" />
{{if empty($user) or $buy_button['is_cart'] eq 0}}
<button type="submit" class="am-btn am-btn-primary am-radius btn-loading-example am-btn-sm am-btn-block" disabled>{{if empty($user)}}请先登录{{else /}}{{$buy_button.error}}{{/if}}</button>
{{else /}}
<button type="submit" class="am-btn am-btn-primary am-radius btn-loading-example am-btn-sm am-btn-block" data-am-loading="{loadingText:'处理中...'}">加入购物车</button>
{{/if}}
</div>
</form>
{{/if}}
{{include file="public/footer" /}}
<script type="text/javascript">
// 购物车回调
function GoodsCartInfoSubmitBack(e)
{
$.AMUI.progress.done();
if(e.code == 0)
{
Prompt(e.msg, 'success');
setTimeout(function()
{
parent.IframePopupHomeCartNumberTotalUpdate(parseInt(e.data.buy_number), '.common-goods-cart-popup');
}, 1500);
} else {
Prompt(e.msg);
$('form.form-validation').find('button[type="submit"]').button('reset');
}
}
</script>

View File

@ -843,7 +843,7 @@ function CartSubmitBack(e)
{
if(e.code == 0)
{
HomeCartNumberTotalUpdate(parseInt(e.data));
HomeCartNumberTotalUpdate(parseInt(e.data.buy_number));
Prompt(e.msg, 'success');
} else {
Prompt(e.msg);

View File

@ -155,6 +155,16 @@
scaleEnabled:true,
toolbars: [["insertimage", "insertvideo", "attachment"]]
});
// 子级调用购物车数量更新
function IframePopupHomeCartNumberTotalUpdate(value, popup = null)
{
HomeCartNumberTotalUpdate(value);
if((popup || null) != null)
{
$(popup).modal('close');
}
}
</script>
<!-- 项目公共 -->

View File

@ -4206,8 +4206,7 @@ $(function()
});
} else {
// 开启规格选择弹窗
console.log(goods_id, 'spec');
ModalLoad(UrlFieldReplace('id', goods_id, $(this).data('cart-info-url')));
ModalLoad(UrlFieldReplace('id', goods_id, $(this).data('cart-info-url')), '', 'common-goods-cart-popup');
}
});
});

View File

@ -0,0 +1,94 @@
/**
*
*/
.goods-spec-container .am-input-group {
display: inline-flex;
}
.goods-spec-container .number-operate span:hover {
color: #000;
background: #f2f2f2;
}
.goods-spec-container .number-operate span {
cursor: pointer;
font-weight: bold;
}
.goods-spec-container .am-input-group span {
height: 37px !important;
line-height: 35px !important;
width: 80px;
}
.goods-spec-container .am-input-group input {
height: 37px !important;
font-size: 14px !important;
}
.goods-spec-container .number-operate input {
max-width: 100px;
min-width: 100px;
}
.goods-spec-container .price-operate input {
max-width: 180px;
min-width: 180px;
}
/**
*
*/
.goods-spec-content .spec-options {
overflow: hidden;
padding: 0 1px;
margin: 5px 0;
}
.goods-spec-content .spec-title, .price-title {
font-weight: 500;
}
.goods-spec-content .sku-line {
float: left;
margin: 5px 25px 10px 0;
background: #efefef;
padding: 8px 20px;
border: 1px solid #d5d5d5;
cursor: pointer;
}
.goods-spec-content .sku-line:hover {
background: none;
color: #333;
border: 1px solid #e23f36;
box-shadow: 0px 0 0px 1px #e23f36;
}
.goods-spec-content .sku-line.selected {
background: #e23f36;
color: #fff;
border: 1px solid #e23f36;
}
.goods-spec-content .sku-line-images {
padding: 6px 15px !important;
}
.goods-spec-content .sku-line-images img {
width: 30px;
height: 30px;
vertical-align: middle;
}
.goods-spec-content .sku-not-active {
border: 1px solid #f03726 !important;
box-shadow: 0 0px 3px #ed7f76, 0 0 6px rgba(0, 0, 0, 0);
padding: 5px 10px 0 10px;
}
.goods-spec-content .sku-items-disabled {
color: #d2cfcf !important;
background-color: #ffffff !important;
border: 1px dashed #d5d5d5 !important;
box-shadow: none !important;
}
.goods-spec-content .sku-dont-choose {
color: #b4b3b3 !important;
background-color: #ffffff !important;
border: 1px solid #ebeaea !important;
box-shadow: none !important;
}
.goods-spec-content .sku-dont-choose img {
opacity: 0.5;
}
.goods-spec-content .sku-items-disabled img {
opacity: 0.3;
}

View File

@ -0,0 +1,361 @@
var $cart_info_goods_spec = $('.goods-spec-container');
/**
* 获取规格详情
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @date 2018-12-14
* @desc description
*/
function GoodsCartInfoSpecDetail()
{
// 是否全部选中
var sku_count = $('.goods-spec-content .sku-items').length;
var active_count = $('.goods-spec-content .sku-items li.selected').length;
if(active_count < sku_count)
{
return false;
}
// 获取规格值
var spec = [];
$('.goods-spec-content .sku-items li.selected').each(function(k, v)
{
spec.push({"type": $(this).data('type-value'), "value": $(this).data('value')})
});
var stock = $cart_info_goods_spec.find('.number-operate input[type="number"]').val() || 1;
// 开启进度条
$.AMUI.progress.start();
// ajax请求
$.ajax({
url: $cart_info_goods_spec.data('specdetail-url'),
type: 'post',
dataType: "json",
timeout: 10000,
data: {"id": $('.goods-spec-content').data('id'), "spec": spec, "stock": stock},
success: function(result)
{
$.AMUI.progress.done();
if(result.code == 0)
{
// 售价
$cart_info_goods_spec.find('.price').text(__currency_symbol__+result.data.spec_base.price);
// 限购数量是否已大于库存
var max = parseInt(result.data.spec_base.inventory);
var $stock = $cart_info_goods_spec.find('.stock-tips .stock');
var limit_max = parseInt($stock.attr('data-max-limit') || 0);
if(limit_max > 0)
{
max = (max < limit_max) ? max : limit_max;
$stock.attr('data-max-limit', max);
}
$cart_info_goods_spec.find('.number-operate input[type="number"]').attr('max', max);
// 库存
$stock.text(result.data.spec_base.inventory);
if(result.data.spec_base.original_price > 0)
{
$cart_info_goods_spec.find('.original-price').attr('data-price', result.data.spec_base.original_price);
$cart_info_goods_spec.find('.original-price').text(__currency_symbol__+result.data.spec_base.original_price);
$cart_info_goods_spec.find('.original-price').show();
} else {
$('.original-price').hide();
}
} else {
Prompt(result.msg);
}
},
error: function(xhr, type)
{
$.AMUI.progress.done();
Prompt(HtmlToString(xhr.responseText) || '异常错误', null, 30);
}
});
}
/**
* 获取规格类型
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @date 2018-12-14
* @desc description
*/
function GoodsCartInfoSpecType()
{
// 是否全部选中
var sku_count = $('.goods-spec-content .sku-items').length;
var active_count = $('.goods-spec-content .sku-items li.selected').length;
if(active_count <= 0 || active_count >= sku_count)
{
return false;
}
// 获取规格值
var spec = [];
$('.goods-spec-content .sku-items li.selected').each(function(k, v)
{
spec.push({"type": $(this).data('type-value'), "value": $(this).data('value')})
});
// 开启进度条
$.AMUI.progress.start();
// ajax请求
$.ajax({
url: $cart_info_goods_spec.data('spectype-url'),
type: 'post',
dataType: "json",
timeout: 10000,
data: {"id": $('.goods-spec-content').data('id'), "spec": spec},
success: function(result)
{
$.AMUI.progress.done();
if(result.code == 0)
{
var spec_count = spec.length;
var index = (spec_count > 0) ? spec_count : 0;
if(index < sku_count)
{
$('.goods-spec-content .sku-items').eq(index).find('li').each(function(k, v)
{
$(this).removeClass('sku-dont-choose');
var value = $(this).data('value').toString();
if(result.data.spec_type.indexOf(value) == -1)
{
$(this).addClass('sku-items-disabled');
} else {
$(this).removeClass('sku-items-disabled');
}
});
}
} else {
Prompt(result.msg);
}
},
error: function(xhr, type)
{
$.AMUI.progress.done();
Prompt(HtmlToString(xhr.responseText) || '异常错误', null, 30);
}
});
}
/**
* 商品基础数据恢复
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @date 2018-12-25
* @desc description
*/
function GoodsCartInfoBaseRestore()
{
$cart_info_goods_spec.find('.price').text(__currency_symbol__+$cart_info_goods_spec.find('.price').data('default-price'));
$cart_info_goods_spec.find('.number-operate input[type="number"]').attr('max', $cart_info_goods_spec.find('.number-operate input[type="number"]').data('original-max'));
$cart_info_goods_spec.find('.stock-tips .stock').text($cart_info_goods_spec.find('.stock-tips .stock').data('original-stock'));
if($cart_info_goods_spec.find('.original-price').length > 0)
{
$cart_info_goods_spec.find('.original-price').text(__currency_symbol__+$cart_info_goods_spec.find('.original-price').data('default-price'));
}
}
/**
* 加入购物车校验
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @date 2018-09-13
* @desc description
*/
function GoodsCartInfoBuyCartCheck()
{
// 参数
var $stock = $cart_info_goods_spec.find('.stock-tips .stock');
var stock = parseInt($cart_info_goods_spec.find('.number-operate input').val() || 1);
var inventory = parseInt($stock.text());
var min = $stock.data('min-limit') || 1;
var max = $stock.data('max-limit') || 0;
var unit = $stock.data('unit') || '';
if(stock < min)
{
Prompt((window['lang_goods_stock_min_tips'] || '最低起购数量')+min+unit);
return false;
}
if(max > 0 && stock > max)
{
Prompt((window['lang_goods_stock_max_tips'] || '最大限购数量')+max+unit);
return false;
}
if(stock > inventory)
{
Prompt((window['lang_goods_inventory_number_tips'] || '库存数量')+inventory+unit);
return false;
}
// 规格
var spec = [];
var sku_count = $('.goods-spec-content .sku-items').length;
if(sku_count > 0)
{
var spec_count = $('.sku-line.selected').length;
if(spec_count < sku_count)
{
$('.goods-spec-content .sku-items').each(function(k, v)
{
if($(this).find('.sku-line.selected').length == 0)
{
$(this).addClass('sku-not-active');
}
});
Prompt(window['lang_goods_no_choice_spec_tips'] || '请选择规格');
return false;
}
// 已选规格
spec = GoodsCartInfoSelectedSpec();
}
return {
stock: stock,
spec: spec,
};
}
/**
* 已选规格
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @date 2021-10-05
* @desc description
*/
function GoodsCartInfoSelectedSpec()
{
// 规格
var spec = [];
var sku_count = $('.sku-items').length;
if(sku_count > 0)
{
var spec_count = $('.sku-line.selected').length;
if(spec_count >= sku_count)
{
$('.sku-items li.selected').each(function(k, v)
{
spec.push({"type": $(this).data('type-value'), "value": $(this).data('value')});
});
}
}
return spec;
}
$(function()
{
// 商品规格选择
$(document).on('click', '.spec-options ul>li', function()
{
// 切换规格购买数量清空
$cart_info_goods_spec.find('.number-operate input').val($cart_info_goods_spec.find('.stock-tips .stock').data('min-limit') || 1);
// 规格处理
var length = $('.goods-spec-content .sku-items').length;
var index = $(this).parents('.sku-items').index();
if($(this).hasClass('selected'))
{
$(this).removeClass('selected');
// 去掉元素之后的禁止
$('.goods-spec-content .sku-items').each(function(k, v)
{
if(k > index)
{
$(this).find('li').removeClass('sku-items-disabled').removeClass('selected').addClass('sku-dont-choose');
}
});
// 数据还原
GoodsCartInfoBaseRestore();
} else {
if($(this).hasClass('sku-items-disabled') || $(this).hasClass('sku-dont-choose'))
{
return false;
}
$(this).addClass('selected').siblings('li').removeClass('selected');
$(this).parents('.sku-items').removeClass('sku-not-active');
// 去掉元素之后的禁止
if(index < length)
{
$('.goods-spec-content .sku-items').each(function(k, v)
{
if(k > index)
{
$(this).find('li').removeClass('sku-items-disabled').removeClass('selected').addClass('sku-dont-choose');
}
});
}
// 后面是否还有未选择的规格
if(index < length-1)
{
// 数据还原
GoodsCartInfoBaseRestore();
}
// 获取下一个规格类型
GoodsCartInfoSpecType();
// 获取规格详情
GoodsCartInfoSpecDetail();
}
});
// 数量操作
$(document).on('click', '.goods-spec-content .number-operate span', function()
{
var $input = $(this).parents('.number-operate').find('input');
var min = parseInt($input.attr('min') || 0);
var max = parseInt($input.attr('max') || 0);
var stock = parseInt($input.val());
var type = $(this).data('type');
var temp_stock = (type == 'add') ? stock+1 : stock-1;
if(temp_stock < min)
{
temp_stock = min;
Prompt('不能小于最低限购('+min+')');
}
if(temp_stock > max)
{
temp_stock = max;
Prompt('超过最大限购('+max+')');
}
$input.val(temp_stock).blur();
});
$(document).on('blur', '.goods-spec-content .number-operate input', function()
{
if(parseInt($(this).val() || 0) <= 0)
{
$(this).val($(this).attr('min'));
}
});
$(document).on('focus', '.goods-spec-content .number-operate input', function()
{
$(this).select();
});
// 加入购物车
$('form.form-validation button[type="submit"]').on('click', function()
{
// 参数
var params = GoodsCartInfoBuyCartCheck();
if(params === false)
{
return false;
}
$('form.form-validation input[name="spec"]').val(JSON.stringify(params.spec));
return true;
});
});