Merge branch 'feature/task1.0.0' into msb_test

merge-requests/30/merge
ch 3 years ago
commit 0312416318

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

@ -33,5 +33,5 @@ table {border-collapse: collapse; border-spacing: 0;
color: #333;} color: #333;}
a { text-decoration:none; a { text-decoration:none;
color: #333; color: #333;
&:hover { text-decoration:none;} &:hover { text-decoration:none; color: #FF512B;}
} }

@ -2,13 +2,13 @@
* @Author: ch * @Author: ch
* @Date: 2022-05-08 14:41:42 * @Date: 2022-05-08 14:41:42
* @LastEditors: ch * @LastEditors: ch
* @LastEditTime: 2022-05-12 10:00:52 * @LastEditTime: 2022-05-12 14:37:00
* @Description: file content * @Description: file content
--> -->
<template> <template>
<div class="ui-goods-info" @click="$router.push(`/goods/detail/${goods.productId}`)"> <div class="ui-goods-info" @click="$router.push(`/goods/detail/${goods.productId}`)">
<div class="ui-goods-info--img"> <div class="ui-goods-info--img">
<img :src="goods.productImageUrl"/> <img :src="goods.productImageUrl || goods.productMainPicture"/>
</div> </div>
<p> <p>
<b>{{goods.productName}}</b> <b>{{goods.productName}}</b>

@ -0,0 +1,24 @@
<!--
* @Author: ch
* @Date: 2022-05-12 16:52:52
* @LastEditors: ch
* @LastEditTime: 2022-05-12 17:02:52
* @Description: file content
-->
<template>
<div class="loading" >正在查询数据...</div>
</template>
<script>
export default {
}
</script>
<style lang="scss" scoped>
.loading{
height: 300px;
line-height: 100px;
text-align: center;
color: #666;
}
</style>

@ -2,16 +2,16 @@
* @Author: ch * @Author: ch
* @Date: 2022-05-04 20:47:29 * @Date: 2022-05-04 20:47:29
* @LastEditors: ch * @LastEditors: ch
* @LastEditTime: 2022-05-12 11:29:24 * @LastEditTime: 2022-05-12 16:55:56
* @Description: file content * @Description: file content
--> -->
<template> <template>
<div class="main"> <div class="main">
<Tab :active="tabActive" @change="changeTab"></Tab> <Tab :active="tabActive" @change="changeTab"></Tab>
<div class="loading" v-if="loading">...</div> <UiLoading v-if="loading"></UiLoading>
<UiEmptyAccount v-if="!orderTotal && !loading" desc="暂无订单数据" :icon="require('@/assets/img/account/order/empty.png')"> <UiEmpty v-if="!orderTotal && !loading" desc="暂无订单数据" :icon="require('@/assets/img/account/order/empty.png')">
<UiButton type="grey" @click="$router.push('/')"></UiButton> <UiButton type="grey" @click="$router.push('/')"></UiButton>
</UiEmptyAccount> </UiEmpty>
<template v-if="!loading"> <template v-if="!loading">
<table v-if="orderTotal" class="order--table order--table-head"> <table v-if="orderTotal" class="order--table order--table-head">
<thead> <thead>
@ -73,15 +73,16 @@
</template> </template>
<script> <script>
import {ApiGetOrderList, ApiPutOrderReceive, ApiGetOrderStatistics} from '~/plugins/api/order'; import {ApiGetOrderList, ApiPutOrderReceive, ApiGetOrderStatistics} from '~/plugins/api/order';
import BsCancelOrder from '../../../../../components/BsCancelOrder.vue'; import BsCancelOrder from '@/components/BsCancelOrder.vue';
import BsPay from '../../../../../components/BsPay.vue'; import BsPay from '@/components/BsPay.vue';
import UiButton from '../../../../../components/UiButton.vue'; import UiButton from '@/components/UiButton.vue';
import UiEmptyAccount from '../../../../../components/UiEmptyAccount.vue'; import UiEmpty from '@/components/UiEmpty.vue';
import UIGoodsInfo from '../../../../../components/UIGoodsInfo.vue'; import UIGoodsInfo from '@/components/UIGoodsInfo.vue';
import UiLineBox from '../../../../../components/UiLineBox.vue'; import UiLineBox from '@/components/UiLineBox.vue';
import Tab from './module/Tab.vue'; import Tab from './module/Tab.vue';
import UiLoading from '../../../../../components/UiLoading.vue';
export default { export default {
components: { UiLineBox, UIGoodsInfo, Tab, UiButton, BsPay, UiEmptyAccount, BsCancelOrder }, components: { UiLineBox, UIGoodsInfo, Tab, UiButton, BsPay, UiEmpty, BsCancelOrder, UiLoading },
data(){ data(){
return { return {
tabActive : this.$route.query.type || -1, tabActive : this.$route.query.type || -1,
@ -90,7 +91,6 @@ export default {
orderList : [], orderList : [],
orderTotal : 0, orderTotal : 0,
loading : true, loading : true,
payVisible : false, payVisible : false,
cancelVisible : false, cancelVisible : false,
operationOrder : {} operationOrder : {}
@ -162,12 +162,6 @@ export default {
.main{ .main{
flex: 1; flex: 1;
} }
.loading{
height: 100px;
line-height: 100px;
text-align: center;
color: #666;
}
.order{ .order{
margin: 10px 0; margin: 10px 0;
&--head{ &--head{

@ -2,21 +2,326 @@
* @Author: ch * @Author: ch
* @Date: 2022-05-03 22:41:15 * @Date: 2022-05-03 22:41:15
* @LastEditors: ch * @LastEditors: ch
* @LastEditTime: 2022-05-04 17:27:21 * @LastEditTime: 2022-05-12 17:36:08
* @Description: file content * @Description: file content
--> -->
<template> <template>
<div>我是购物车</div> <div>
<UiEmpty v-if="!isLoading && !list.length" desc="购物车空空如也,去挑点喜欢的好货吧~" :icon="require('@/assets/img/cart/empty.png')">
<UiButton type="grey" @click="$router.push('/')"></UiButton>
</UiEmpty>
<UiLoading v-if="isLoading" ></UiLoading>
<div class="main" v-else>
<table class="table table--head">
<thead>
<tr>
<th width="90">
<el-checkbox label="全选" @change="handleCheckAll"
v-model="checkAll" :indeterminate="isIndeterminate"></el-checkbox>
</th>
<th>商品信息</th>
<th width="115">单价</th>
<th width="115">数量</th>
<th width="115">小计</th>
<th width="115">操作</th>
</tr>
</thead>
</table>
<el-checkbox-group v-model="checkedIds" @change="changeCheckedGoods">
<table class="table">
<tbody>
<tr v-for="item in list" :key="item.id" :class="item.status !== 'normal' && 'disable'">
<td width="50">
<el-checkbox v-if="item.status === 'normal'" :label="item.id" class="checkbox"></el-checkbox>
<span v-else class="tag">失效</span>
</td>
<td>
<UIGoodsInfo :goods="item"></UIGoodsInfo>
</td>
<td width="115">
<UiMoney :money="item.productSku ? item.productSku.sellPrice : 0"></UiMoney>
</td>
<td width="115">
<el-input-number :value="item.number" @change="onChangeStepper($event, item)"
:min="1" :max="item.maxBuyNum" size="mini">
</el-input-number>
</td>
<td width="115">
<UiMoney :money="item.totalPrice"></UiMoney>
</td>
<td width="115">
<a @click="handleDelete(item.id)" class="del">删除</a>
</td>
</tr>
</tbody>
</table>
</el-checkbox-group>
<div class="operation">
<div>
<el-checkbox label="全选" @change="handleCheckAll"
v-model="checkAll" :indeterminate="isIndeterminate"></el-checkbox>
<a @click="handleDelete()" class="operation--del">批量删除</a>
</div>
<div class="operation--right">
<p>已选<span class="operation--count">{{checkedIds.length}}</span></p>
<p class="operation--total">总计
<UiMoney class="operation--total-price" :money="totalPrice"
size="20px" float prefix preSize="14px"/>
</p>
<UiButton class="operation--settlement" @click="settlement" :disabled="!checkedIds.length">去结算</UiButton>
</div>
</div>
</div>
</div>
</template> </template>
<script> <script>
import {ApiGetCartList, ApiDeleteCartGoods, ApiPutCartNum} from '@/plugins/api/cart';
import {Debounce} from '@/plugins/utils';
import UIGoodsInfo from '../../components/UIGoodsInfo.vue';
import UiButton from '../../components/UiButton.vue';
import UiMoney from '../../components/UiMoney.vue';
import UiEmpty from '../../components/UiEmpty.vue';
import UiLoading from '../../components/UiLoading.vue';
export default { export default {
components: { UIGoodsInfo, UiButton, UiMoney, UiEmpty, UiLoading },
data(){ data(){
return { return {
isLoading : false,
list : [],
checkedIds : [],
checkAll : false,
isIndeterminate : false
}
},
computed:{
totalPrice(){
const checkedList = this.list.filter(item => this.checkedIds.includes(item.id)) || [];
let tempPrice = 0;
checkedList.forEach(item => {
// , 便 ()
const unitPrice = item.productSku ? item.productSku.sellPrice * 100 : 0
tempPrice += unitPrice * (item.number || 0)
});
return (tempPrice / 100).toFixed(2);
},
//
normalList(){
return this.list.filter(i => i.status == 'normal');
}
},
created(){
this.getCartList();
},
methods:{
/**
* 获取购物车商品列表
*/
async getCartList() {
this.isLoading = true;
const {error, result} = await ApiGetCartList();
if(error){
this.$message.warning(error.message);
return false;
}
this.isLoading = false
this.list = result.map(item => {
const singleBuyLimit = item.product.singleBuyLimit;
const stock = item.productSku && item.productSku.stock;
//
item.maxBuyNum = singleBuyLimit ? Math.min(singleBuyLimit, stock || 1) : stock;
//
item.status = item.product.isEnable ?
(!item.productSku || item.productSku.stock == 0) ? 'notSku': 'normal' :
'isDisable';
// sku
item.skuDescribe = item.status === 'normal' ? item.productSku?.name :
item.status === 'normal' ? '请重新选择商品规格' : '宝贝已失效,暂时无法购买';
//
item.totalPrice = item.status === 'normal' ?
this.calcMonery(item.productSku.sellPrice, item.number) : 0
return item;
});
},
calcMonery(moery, number){
return (((moery * 100) * number) / 100).toFixed(2);
},
/**
* 商品选择框改变全选按钮 半选全选不选状态
*/
changeCheckedGoods(){
this.checkAll = this.normalList.length === this.checkedIds.length;
this.isIndeterminate = this.checkedIds.length > 0 && !this.checkAll;
},
/**
* 点击全选选择框全选反选功能
*/
handleCheckAll(val) {
this.checkedIds = val ? this.normalList.map(item => item.id) : [] ;
},
/**
* 监听步进器更改事件
*/
onChangeStepper(value, item) {
//
if (!item.debounceHandle) {
item.oldValue = item.number
item.debounceHandle = Debounce(this.updateCartNum, 500)
}
//
item.number = value;
item.totalPrice = this.calcMonery(item.productSku.sellPrice, value);
// ()
item.debounceHandle(item, item.oldValue, value);
},
/**
* 提交更新购物车数量
*/
async updateCartNum(item, oldValue, newValue) {
const {error, result} = await ApiPutCartNum({
id : item.id,
number : item.number
});
if(error){
this.$message.error(error.message);
item.number = item.sku;
return false;
}
if(result.isBeyondMaxLimit){
this.$message.error('数量超出范围');
item.number = result.canSetShoppingCartNumber;
return false;
}
},
/**
* 删除选中的商品
*/
handleDelete(id) {
const ids = id ? [id] : this.checkedIds;
const tips = id ? '您确定要删除该商品吗?' : '您确定要删除选中的商品吗?'
if (!ids.length) {
return false
}
this.$confirm(tips, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(async () => {
const {error} = await ApiDeleteCartGoods({idList : ids.join(',')});
if(error){
this.$message.error(error.message);
return false;
}
this.list = this.list.filter(item => !ids.includes(item.id));
if(id){
this.checkedIds = this.checkedIds.filter(i => i.id !== id);
}else{
this.checkedIds = [];
}
})
},
/**
* 点击去结算
*/
settlement(){
this.$router.push({
path : '/order/submit',
query : {
mode: 'cart',
ids:this.checkedIds.join(',')
}
})
} }
} }
} }
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.main{
@include layout-box;
padding-bottom: 50px;
}
.table{
width: 100%;
border: 1px solid #ddd;
font-size: 14px;
&--head{
margin: 30px 0 20px;
}
.disable td{
background: #f8f8f8;
opacity: .6;
}
.del{
cursor: pointer;
}
.tag{
display: inline-block;
background: #ddd;
height: 20px;
width: 40px;
line-height: 20px;
font-size: 12px;
}
th{
height: 46px;
line-height: 46px;
background: #f8f8f8;
font-weight: normal;
}
td{
text-align: center;
padding: 40px 0;
}
}
.operation{
display: flex;
justify-content: space-between;
align-items: center;
background: #f8f8f8;
border: 1px solid #ddd;
margin-top: 10px;
height: 70px;
padding: 0 237px 0 20px;
position: relative;
&--del{
margin-left: 70px;
}
&--right{
display: flex;
align-items: center;
}
&--count{
color: #FF512B;
margin: 0 5px;
}
&--total{
display: flex;
align-items: center;
margin-left: 90px;
&-price{
color: #FF512B;
font-weight: bold;
}
}
&--settlement{
position: absolute;
top: -1px;
right: 0;
width: 160px;
height: 70px;
}
}
/deep/{
.checkbox{
.el-checkbox__label{
display: none;
}
}
}
</style> </style>
Loading…
Cancel
Save