Merge branch 'vue3_tmp' of https://gitee.com/huizhizao/yudao-mall-uniapp into master-vue3

# Conflicts:
#	pages/index/index.vue
pull/25/head
YunaiV 2023-12-09 11:45:12 +08:00
commit 4854cee7ca
25 changed files with 4404 additions and 4257 deletions

63
App.vue
View File

@ -1,41 +1,46 @@
<script setup> <script setup>
import { onLaunch, onShow, onError } from '@dcloudio/uni-app'; import {
import { ShoproInit } from './sheep'; onLaunch,
onShow,
onError
} from '@dcloudio/uni-app';
import {
ShoproInit
} from './sheep';
onLaunch(() => { onLaunch(() => {
// 使 // 使
uni.hideTabBar(); uni.hideTabBar();
// Shopro // Shopro
ShoproInit(); ShoproInit();
}); });
onError((err) => { onError((err) => {
console.log('AppOnError:', err); console.log('AppOnError:', err);
}); });
onShow((options) => { onShow((options) => {
// #ifdef APP-PLUS // #ifdef APP-PLUS
// urlSchemes // urlSchemes
const args = plus.runtime.arguments; const args = plus.runtime.arguments;
if (args) { if (args) {}
}
// //
uni.getClipboardData({ uni.getClipboardData({
success: (res) => { }, success: (res) => {},
}); });
// #endif // #endif
// #ifdef MP-WEIXIN // #ifdef MP-WEIXIN
// //
console.log(options,'options'); console.log(options, 'options');
// #endif // #endif
}); });
</script> </script>
<style lang="scss"> <style lang="scss">
@import '@/sheep/scss/index.scss'; @import '@/sheep/scss/index.scss';
</style> </style>

View File

@ -1,242 +1,261 @@
<!-- 优惠券中心 --> <!-- 优惠券中心 -->
<template> <template>
<s-layout title="优惠券" :bgStyle="{ color: '#f2f2f2' }"> <s-layout title="优惠券" :bgStyle="{ color: '#f2f2f2' }">
<su-sticky bgColor="#fff"> <su-sticky bgColor="#fff">
<su-tabs <su-tabs :list="tabMaps" :scrollable="false" @change="onTabsChange" :current="state.currentTab"></su-tabs>
:list="tabMaps" </su-sticky>
:scrollable="false" <s-empty v-if="state.pagination.total === 0" icon="/static/coupon-empty.png" text="暂无优惠券"></s-empty>
@change="onTabsChange" <template v-if="state.currentTab == '0'">
:current="state.currentTab" <view v-for="item in state.pagination.list" :key="item.id">
></su-tabs> <s-coupon-list :data="item">
</su-sticky> <!-- @tap="
<s-empty sheep.$router.go('/pages/coupon/detail', {
v-if="state.pagination.total === 0" id: item.id,
icon="/static/coupon-empty.png" })
text="暂无优惠券" " -->
></s-empty> <template #default>
<template v-if="state.currentTab == '0'"> <button class="ss-reset-button card-btn ss-flex ss-row-center ss-col-center"
<view v-for="item in state.pagination.data" :key="item.id"> :class="item.get_status != 'can_get' ? 'border-btn' : ''" @click.stop="getBuy(item.id)"
<s-coupon-list :disabled="item.get_status != 'can_get'">
:data="item" <!-- {{ item.status_text }} -->
@tap=" {{item.status_text|| '立即使用' }}
sheep.$router.go('/pages/coupon/detail', { </button>
id: item.id, </template>
}) </s-coupon-list>
" </view>
> </template>
<template #default> <template v-else>
<button <view v-for="item in state.pagination.list" :key="item.id">
class="ss-reset-button card-btn ss-flex ss-row-center ss-col-center" <s-coupon-list :data="item" type="user">
:class="item.get_status != 'can_get' ? 'border-btn' : ''" <!-- @tap="
@click.stop="getBuy(item.id)" sheep.$router.go('/pages/coupon/detail', {
:disabled="item.get_status != 'can_get'" id: item.id,
> })
{{ item.get_status_text }} " -->
</button> <template #default>
</template> <button class="ss-reset-button card-btn ss-flex ss-row-center ss-col-center" :class="
</s-coupon-list>
</view>
</template>
<template v-else>
<view v-for="item in state.pagination.data" :key="item.id">
<s-coupon-list
:data="item"
type="user"
@tap="
sheep.$router.go('/pages/coupon/detail', {
id: item.coupon_id,
user_coupon_id: item.id,
})
"
>
<template #default>
<button
class="ss-reset-button card-btn ss-flex ss-row-center ss-col-center"
:class="
item.status == 'can_get' || item.status == 'can_use' item.status == 'can_get' || item.status == 'can_use'
? '' ? ''
: item.status == 'used' || item.status == 'expired' : item.status == 'used' || item.status == 'expired'
? 'disabled-btn' ? 'disabled-btn'
: 'border-btn' : 'border-btn'
" " :disabled="item.status != 'can_get' && item.status != 'can_use'" @click.stop="
:disabled="item.status != 'can_get' && item.status != 'can_use'"
@click.stop="
sheep.$router.go('/pages/coupon/detail', { sheep.$router.go('/pages/coupon/detail', {
id: item.coupon_id, id: item.coupon_id,
user_coupon_id: item.id, user_coupon_id: item.id,
}) })
" ">
> <!-- {{ item.status_text }} -->
{{ item.status_text }} {{item.status_text|| '立即使用' }}
</button> </button>
</template> </template>
</s-coupon-list> </s-coupon-list>
</view> </view>
</template> </template>
<uni-load-more <!-- <uni-load-more v-if="state.pagination.total > 0" :status="state.loadStatus" :content-text="{
v-if="state.pagination.total > 0"
:status="state.loadStatus"
:content-text="{
contentdown: '上拉加载更多', contentdown: '上拉加载更多',
}" }" @tap="loadmore" /> -->
@tap="loadmore" </s-layout>
/>
</s-layout>
</template> </template>
<script setup> <script setup>
import sheep from '@/sheep'; import sheep from '@/sheep';
import { onLoad, onReachBottom } from '@dcloudio/uni-app'; import {
import { computed, reactive } from 'vue'; onLoad,
import _ from 'lodash'; onReachBottom
} from '@dcloudio/uni-app';
import {
computed,
reactive
} from 'vue';
import _ from 'lodash';
const pagination = { const pagination = {
data: [], data: [],
current_page: 1, current_page: 1,
total: 1, total: 1,
last_page: 1, last_page: 1,
}; };
// //
const state = reactive({ const state = reactive({
currentTab: 0, currentTab: 0,
pagination: { pagination: {
data: [], data: [],
current_page: 1, current_page: 1,
total: 1, total: 1,
last_page: 1, last_page: 1,
}, },
loadStatus: '', loadStatus: '',
type: '', type: '1',
}); });
const tabMaps = [ const tabMaps = [
{ // {
name: '领券中心', // name: '',
value: 'all', // value: 'all',
}, // },
{ {
name: '已领取', name: '已领取',
value: 'geted', value: '1',
}, },
{ {
name: '已使用', name: '已使用',
value: 'used', value: '2',
}, },
{ {
name: '已失效', name: '已失效',
value: 'expired', value: '3',
}, },
]; ];
function onTabsChange(e) {
state.pagination = pagination
state.currentTab = e.index;
state.type = e.value;
if (state.currentTab == 0) {
getData();
} else {
getCoupon();
}
}
async function getData(page = 1, list_rows = 5) {
state.loadStatus = 'loading';
const res = await sheep.$api.coupon.list({ list_rows, page });
if (res.error === 0) {
let couponlist = _.concat(state.pagination.data, res.data.data);
state.pagination = {
...res.data,
data: couponlist,
};
if (state.pagination.current_page < state.pagination.last_page) {
state.loadStatus = 'more';
} else {
state.loadStatus = 'noMore';
}
}
}
async function getCoupon(page = 1, list_rows = 5) { function onTabsChange(e) {
state.loadStatus = 'loading'; state.pagination = pagination
let res = await sheep.$api.coupon.userCoupon({ state.currentTab = e.index;
type: state.type, state.type = e.value;
list_rows, // if (state.currentTab == 0) {
page, // getData();
}); // } else {
if (res.error === 0) { getCoupon();
if (page >= 2) { // }
let couponlist = _.concat(state.pagination.data, res.data.data); }
state.pagination = { async function getData(page = 1, list_rows = 5) {
...res.data, state.loadStatus = 'loading';
data: couponlist, const res = await sheep.$api.coupon.list({
}; list_rows,
} else { page
state.pagination = res.data; });
} if (res.error === 0) {
if (state.pagination.current_page < state.pagination.last_page) { let couponlist = _.concat(state.pagination.data, res.data.data);
state.loadStatus = 'more'; state.pagination = {
} else { ...res.data,
state.loadStatus = 'noMore'; data: couponlist,
} };
} if (state.pagination.current_page < state.pagination.last_page) {
} state.loadStatus = 'more';
async function getBuy(id) { } else {
const { error, msg } = await sheep.$api.coupon.get(id); state.loadStatus = 'noMore';
if (error === 0) { }
uni.showToast({ }
title: msg, }
});
setTimeout(() => {
state.pagination = pagination
getData();
}, 1000);
}
}
// async function getCoupon(page = 1, list_rows = 5) {
function loadmore() { state.loadStatus = 'loading';
if (state.loadStatus !== 'noMore') { let res = await sheep.$api.coupon.userCoupon({
if (state.currentTab == 0) { status: state.type,
getData(state.pagination.current_page + 1); pageSize: list_rows,
} else { pageNo: page
getCoupon(state.pagination.current_page + 1); });
} if (res.code === 0) {
} //
} let obj = {
onLoad((Option) => { 1: '可用',
if (Option.type === 'all' || !Option.type) { 2: '已用',
getData(); 3: '过期'
} else { }
state.type = Option.type; res.data.list = res.data.list.map(item => {
Option.type === 'geted' return {
? (state.currentTab = 1) ...item,
: Option.type === 'used' enough: (item.usePrice / 100).toFixed(2),
? (state.currentTab = 2) amount: (item.discountPrice / 100).toFixed(2),
: (state.currentTab = 3); use_start_time: sheep.$helper.timeFormat(item.validStartTime, 'yyyy-mm-dd hh:MM:ss'),
getCoupon(); use_end_time: sheep.$helper.timeFormat(item.validEndTime, 'yyyy-mm-dd hh:MM:ss'),
} status_text: obj[item.status]
}); }
onReachBottom(() => { });
loadmore(); if (page >= 2) {
}); let couponlist = _.concat(state.pagination.data, res.data.list);
state.pagination = {
...res.data,
data: couponlist,
};
console.log(state.pagination, '拿到的优惠券数据');
} else {
state.pagination = res.data;
console.log(state.pagination, '拿到的优惠券数据');
}
// if (state.pagination.current_page < state.pagination.last_page) {
// state.loadStatus = 'more';
// } else {
// state.loadStatus = 'noMore';
// }
}
}
async function getBuy(id) {
const {
error,
msg
} = await sheep.$api.coupon.get(id);
if (error === 0) {
uni.showToast({
title: msg,
});
setTimeout(() => {
state.pagination = pagination
getData();
}, 1000);
}
}
//
function loadmore() {
if (state.loadStatus !== 'noMore') {
if (state.currentTab == 0) {
getData(state.pagination.current_page + 1);
} else {
getCoupon(state.pagination.current_page + 1);
}
}
}
onLoad((Option) => {
// if (Option.type === 'all' || !Option.type) {
// getData();
// } else {
// state.type = Option.type;
// Option.type === 'geted' ?
// () :
// Option.type === 'used' ?
// (state.currentTab = 1 && state.type = 2) :
// (state.currentTab = 2 && state.type = 3);
if (Option.type == 'geted') {
state.currentTab = 0
state.type = 1
} else if (Option.type == 'used') {
state.currentTab = 1
state.type = 2
} else {
state.currentTab = 2
state.type = 3
}
getCoupon();
// }
});
onReachBottom(() => {
loadmore();
});
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.card-btn { .card-btn {
// width: 144rpx; // width: 144rpx;
padding: 0 16rpx; padding: 0 16rpx;
height: 50rpx; height: 50rpx;
border-radius: 40rpx; border-radius: 40rpx;
background: linear-gradient(90deg, var(--ui-BG-Main), var(--ui-BG-Main-gradient)); background: linear-gradient(90deg, var(--ui-BG-Main), var(--ui-BG-Main-gradient));
color: #ffffff; color: #ffffff;
font-size: 24rpx; font-size: 24rpx;
font-weight: 400; font-weight: 400;
} }
.border-btn {
background: linear-gradient(90deg, var(--ui-BG-Main-opacity-4), var(--ui-BG-Main-light)); .border-btn {
color: #fff !important; background: linear-gradient(90deg, var(--ui-BG-Main-opacity-4), var(--ui-BG-Main-light));
} color: #fff !important;
.disabled-btn { }
background: #cccccc;
background-color: #cccccc !important; .disabled-btn {
color: #fff !important; background: #cccccc;
} background-color: #cccccc !important;
</style> color: #fff !important;
}
</style>

View File

@ -1,157 +1,209 @@
<!-- 评价 --> <!-- 评价 -->
<template> <template>
<s-layout title="评价"> <s-layout title="评价">
<view> <view>
<view v-for="(item, index) in state.orderInfo.items" :key="item.id"> <view v-for="(item, index) in state.orderInfo.items" :key="item.id">
<view v-if="item.btns.includes('comment')"> <view v-if="item.btns.includes('comment')">
<view class="commont-from-wrap"> <view class="commont-from-wrap">
<!-- 评价商品 --> <!-- 评价商品 -->
<s-goods-item <s-goods-item :img="item.goods_image" :title="item.goods_title" :skuText="item.goods_sku_text"
:img="item.goods_image" :price="item.goods_price" :num="item.goods_num"></s-goods-item>
:title="item.goods_title" </view>
:skuText="item.goods_sku_text"
:price="item.goods_price"
:num="item.goods_num"
></s-goods-item>
</view>
<view class="form-item"> <view class="form-item">
<!-- 评分 --> <!-- 评分 -->
<view class="star-box ss-flex ss-col-center"> <view class="star-box ss-flex ss-col-center">
<view class="star-title ss-m-r-40"> <view class="star-title ss-m-r-40">
{{ rateMap[state.commentList[index].level] }} <!-- {{ rateMap[state.commentList[index].level] }} -->
</view> 商品质量
<uni-rate v-model="state.commentList[index].level" /> </view>
</view> <uni-rate v-model="state.commentList[index].level" />
<!-- 评价 --> </view>
<view class="area-box"> <view class="star-box ss-flex ss-col-center">
<uni-easyinput <view class="star-title ss-m-r-40">
:inputBorder="false" <!-- {{ rateMap[state.commentList[index].level] }} -->
type="textarea" 服务态度
maxlength="120" </view>
autoHeight <uni-rate v-model="state.commentList[index].level2" />
v-model="state.commentList[index].content" </view>
placeholder="宝贝满足你的期待吗?说说你的使用心得,分享给想买的他们吧~" <!-- 评价 -->
></uni-easyinput> <view class="area-box">
<uni-easyinput :inputBorder="false" type="textarea" maxlength="120" autoHeight
v-model="state.commentList[index].content"
placeholder="宝贝满足你的期待吗?说说你的使用心得,分享给想买的他们吧~"></uni-easyinput>
<view class="img-box"> <view class="img-box">
<s-uploader <s-uploader v-model:url="state.commentList[index].images" fileMediatype="image"
v-model:url="state.commentList[index].images" limit="9" mode="grid" :imageStyles="{ width: '168rpx', height: '168rpx' }" />
fileMediatype="image" </view>
limit="9" </view>
mode="grid" </view>
:imageStyles="{ width: '168rpx', height: '168rpx' }" </view>
/> </view>
</view> </view>
</view>
</view>
</view>
</view>
</view>
<su-fixed bottom placeholder> <su-fixed bottom placeholder>
<view class="foot_box ss-flex ss-row-center ss-col-center"> <view class="foot_box ss-flex ss-row-center ss-col-center">
<button class="ss-reset-button post-btn ui-BG-Main-Gradient ui-Shadow-Main" @tap="onSubmit"> <button class="ss-reset-button post-btn ui-BG-Main-Gradient ui-Shadow-Main" @tap="onSubmit">
发布 发布
</button> </button>
</view> </view>
</su-fixed> </su-fixed>
</s-layout> </s-layout>
</template> </template>
<script setup> <script setup>
import sheep from '@/sheep'; import sheep from '@/sheep';
import { onLoad } from '@dcloudio/uni-app'; import {
import { computed, reactive } from 'vue'; onLoad
} from '@dcloudio/uni-app';
import {
computed,
reactive
} from 'vue';
const state = reactive({ const state = reactive({
orderInfo: {}, orderInfo: {},
commentList: [], commentList: [],
}); orderId: null
});
const rateMap = { const rateMap = {
1: '糟糕', 1: '糟糕',
2: '差评', 2: '差评',
3: '一般', 3: '一般',
4: '良好', 4: '良好',
5: '好评', 5: '好评',
}; };
async function onSubmit() { async function onSubmit() {
const { error } = await sheep.$api.order.comment(state.orderInfo.id, { //
comments: state.commentList, // console.log(state.orderInfo);
}); // return;
if (error === 0) { let obj = {
sheep.$router.back(); anonymous: false,
} benefitScores: state.commentList[0].level2,
} content: state.commentList[0].content,
descriptionScores: state.commentList[0].level,
orderItemId: state.commentList[0].item_id,
picUrls: 'https://t7.baidu.com/it/u=2531125946,3055766435&fm=193&f=GIF'
}
const {
code
} = await sheep.$api.order.comment(obj);
if (code === 0) {
sheep.$router.back();
}
}
onLoad(async (options) => { onLoad(async (options) => {
let id = ''; let id = '';
if (options.orderSN) { if (options.orderSN) {
id = options.orderSN; id = options.orderSN;
} }
if (options.id) { if (options.id) {
id = options.id; id = options.id;
} }
if (options.orderId) {
state.orderId = options.orderId
}
const { data, error } = await sheep.$api.order.detail(id); const res = await sheep.$api.order.detail(id);
if (error === 0) { if (res.code === 0) {
if (data.btns.includes('comment')) { let obj = {
state.orderInfo = data; 10: ['待发货', '等待买家付款', ["apply_refund"]],
state.orderInfo.items.forEach((item) => { 30: ['待评价', '等待买家评价', ["express", "comment"]]
if (item.btns.includes('comment')) { }
state.commentList.push({
item_id: item.id, res.data.status_text = obj[res.data.status][0];
level: 5, res.data.status_desc = obj[res.data.status][1];
content: '', res.data.btns = obj[res.data.status][2];
images: [], res.data.address = {
}); province_name: res.data.receiverAreaName.split(' ')[0],
} district_name: res.data.receiverAreaName.split(' ')[2],
}); city_name: res.data.receiverAreaName.split(' ')[1],
return; address: res.data.receiverDetailAddress,
} consignee: res.data.receiverName,
} mobile: res.data.receiverMobile,
sheep.$helper.toast('无待评价订单'); }
}); res.data.pay_fee = res.data.payPrice / 100
res.data.create_time = sheep.$helper.timeFormat(res.data.createTime, 'yyyy-mm-dd hh:MM:ss')
res.data.order_sn = res.data.no
res.data.id = res.data.id
res.data.goods_amount = res.data.totalPrice / 100
res.data.dispatch_amount = res.data.deliveryPrice / 100
res.data.pay_types_text = res.data.payChannelName.split(',')
res.data.items = res.data.items.map(ite => {
return {
...ite,
btns: obj[res.data.status][2],
goods_title: ite.spuName,
goods_num: ite.count,
goods_price: ite.price / 100,
goods_image: ite.picUrl,
goods_sku_text: ite.properties.reduce((it0, it1) => it0 + it1.valueName + ' ', '')
}
})
if (res.data.btns.includes('comment')) {
state.orderInfo = res.data;
state.orderInfo.items.forEach((item) => {
if (item.btns.includes('comment')) {
state.commentList.push({
item_id: item.id,
level: 5,
content: '',
images: [],
});
}
});
console.log(state.orderInfo.items, '循环')
return;
}
}
sheep.$helper.toast('无待评价订单');
});
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
// //
.goods-card { .goods-card {
margin: 10rpx 0; margin: 10rpx 0;
padding: 20rpx; padding: 20rpx;
background: #fff; background: #fff;
} }
// //
.form-item { .form-item {
background: #fff; background: #fff;
.star-box {
height: 100rpx;
padding: 0 25rpx;
}
.star-title {
font-weight: 600;
}
}
.area-box {
width: 690rpx;
min-height: 306rpx;
background: rgba(249, 250, 251, 1);
border-radius: 20rpx;
padding: 28rpx;
margin: auto;
.img-box { .star-box {
margin-top: 20rpx; height: 100rpx;
} padding: 0 25rpx;
} }
.post-btn {
width: 690rpx; .star-title {
line-height: 80rpx; font-weight: 600;
border-radius: 40rpx; }
color: rgba(#fff, 0.9); }
margin-bottom: 20rpx;
} .area-box {
</style> width: 690rpx;
min-height: 306rpx;
background: rgba(249, 250, 251, 1);
border-radius: 20rpx;
padding: 28rpx;
margin: auto;
.img-box {
margin-top: 20rpx;
}
}
.post-btn {
width: 690rpx;
line-height: 80rpx;
border-radius: 40rpx;
color: rgba(#fff, 0.9);
margin-bottom: 20rpx;
}
</style>

View File

@ -1,417 +1,400 @@
<template> <template>
<view> <view>
<s-layout :onShareAppMessage="shareInfo" navbar="goods"> <s-layout :onShareAppMessage="shareInfo" navbar="goods">
<!-- 标题栏 --> <!-- 标题栏 -->
<detailNavbar /> <detailNavbar />
<!-- 骨架屏 --> <!-- 骨架屏 -->
<detailSkeleton v-if="state.skeletonLoading" /> <detailSkeleton v-if="state.skeletonLoading" />
<!-- 下架/售罄提醒 --> <!-- 下架/售罄提醒 -->
<s-empty <s-empty v-else-if="state.goodsInfo === null" text="商品不存在或已下架" icon="/static/soldout-empty.png" showAction
v-else-if="state.goodsInfo === null" actionText="再逛逛" actionUrl="/pages/goods/list" />
text="商品不存在或已下架" <block v-else>
icon="/static/soldout-empty.png" <view class="detail-swiper-selector">
showAction <!-- 商品轮播图 -->
actionText="再逛逛" <su-swiper class="ss-m-b-14" isPreview :list="state.goodsSwiper" dotStyle="tag" imageMode="widthFix"
actionUrl="/pages/goods/list" dotCur="bg-mask-40" :seizeHeight="750" />
/>
<block v-else>
<view class="detail-swiper-selector">
<!-- 商品轮播图 -->
<su-swiper
class="ss-m-b-14"
isPreview
:list="state.goodsSwiper"
dotStyle="tag"
imageMode="widthFix"
dotCur="bg-mask-40"
:seizeHeight="750"
/>
<!-- 价格+标题 --> <!-- 价格+标题 -->
<view class="title-card detail-card ss-p-y-40 ss-p-x-20"> <view class="title-card detail-card ss-p-y-40 ss-p-x-20">
<view class="ss-flex ss-row-between ss-col-center ss-m-b-26"> <view class="ss-flex ss-row-between ss-col-center ss-m-b-26">
<view class="price-box ss-flex ss-col-bottom"> <view class="price-box ss-flex ss-col-bottom">
<view class="price-text ss-m-r-16"> <view class="price-text ss-m-r-16">
{{ state.selectedSkuPrice.price || formatPrice(state.goodsInfo.price) }} {{ state.selectedSkuPrice.price || formatPrice(state.goodsInfo.price) }}
</view> </view>
<view class="origin-price-text" v-if="state.goodsInfo.original_price > 0"> <view class="origin-price-text" v-if="state.goodsInfo.original_price > 0">
{{ state.selectedSkuPrice.original_price || state.goodsInfo.original_price }} {{ state.selectedSkuPrice.original_price || state.goodsInfo.original_price }}
</view> </view>
</view> </view>
<view class="sales-text"> <view class="sales-text">
{{ formatSales(state.goodsInfo.sales_show_type, state.goodsInfo.sales) }} {{ formatSales(state.goodsInfo.sales_show_type, state.goodsInfo.sales) }}
</view> </view>
</view> </view>
<view class="discounts-box ss-flex ss-row-between ss-m-b-28"> <view class="discounts-box ss-flex ss-row-between ss-m-b-28">
<div class="tag-content"> <div class="tag-content">
<view class="tag-box ss-flex"> <view class="tag-box ss-flex">
<view <view class="tag ss-m-r-10" v-for="promos in state.goodsInfo.promos"
class="tag ss-m-r-10" :key="promos.id" @tap="onActivity">
v-for="promos in state.goodsInfo.promos" {{ promos.title }}
:key="promos.id" </view>
@tap="onActivity" </view>
> </div>
{{ promos.title }}
</view>
</view>
</div>
<view <view class="get-coupon-box ss-flex ss-col-center ss-m-l-20" @tap="state.showModel = true"
class="get-coupon-box ss-flex ss-col-center ss-m-l-20" v-if="state.couponInfo.length">
@tap="state.showModel = true" <view class="discounts-title ss-m-r-8">领券</view>
v-if="state.couponInfo.length" <text class="cicon-forward"></text>
> </view>
<view class="discounts-title ss-m-r-8">领券</view> </view>
<text class="cicon-forward"></text> <view class="title-text ss-line-2 ss-m-b-6">{{ state.goodsInfo.title }}</view>
</view> <view class="subtitle-text ss-line-1">{{ state.goodsInfo.subtitle }}</view>
</view> </view>
<view class="title-text ss-line-2 ss-m-b-6">{{ state.goodsInfo.title }}</view>
<view class="subtitle-text ss-line-1">{{ state.goodsInfo.subtitle }}</view>
</view>
<!-- 功能卡片 --> <!-- 功能卡片 -->
<view class="detail-cell-card detail-card ss-flex-col"> <view class="detail-cell-card detail-card ss-flex-col">
<detail-cell-sku <detail-cell-sku v-model="state.selectedSkuPrice.goods_sku_text" :skus="state.goodsInfo.skus"
v-model="state.selectedSkuPrice.goods_sku_text" @tap="state.showSelectSku = true" />
:skus="state.goodsInfo.skus" <detail-cell-service v-if="state.goodsInfo.service" v-model="state.goodsInfo.service" />
@tap="state.showSelectSku = true" <detail-cell-params v-if="state.goodsInfo.params" v-model="state.goodsInfo.params" />
/> </view>
<detail-cell-service v-if="state.goodsInfo.service" v-model="state.goodsInfo.service" />
<detail-cell-params v-if="state.goodsInfo.params" v-model="state.goodsInfo.params" />
</view>
<!-- 规格与数量弹框 --> <!-- 规格与数量弹框 -->
<s-select-sku <s-select-sku :goodsInfo="state.goodsInfo" :show="state.showSelectSku" @addCart="onAddCart"
:goodsInfo="state.goodsInfo" @buy="onBuy" @change="onSkuChange" @close="state.showSelectSku = false" />
:show="state.showSelectSku" </view>
@addCart="onAddCart"
@buy="onBuy"
@change="onSkuChange"
@close="state.showSelectSku = false"
/>
</view>
<!-- 评价 --> <!-- 评价 -->
<detail-comment-card class="detail-comment-selector" :goodsId="state.goodsId" /> <detail-comment-card class="detail-comment-selector" :goodsId="state.goodsId" />
<!-- 详情 --> <!-- 详情 -->
<detail-content-card class="detail-content-selector" :content="state.goodsInfo.description" /> <detail-content-card class="detail-content-selector" :content="state.goodsInfo.description" />
<!-- 活动跳转 --> <!-- 活动跳转 -->
<detail-activity-tip <detail-activity-tip v-if="state.goodsInfo.activities" :data="state.goodsInfo"></detail-activity-tip>
v-if="state.goodsInfo.activities"
:data="state.goodsInfo"
></detail-activity-tip>
<!-- 详情tabbar --> <!-- 详情tabbar -->
<detail-tabbar v-model="state.goodsInfo"> <detail-tabbar v-model="state.goodsInfo">
<!-- TODO: 缺货中 已售罄 判断 设计--> <!-- TODO: 缺货中 已售罄 判断 设计-->
<view class="buy-box ss-flex ss-col-center ss-p-r-20" v-if="state.goodsInfo.stock > 0"> <view class="buy-box ss-flex ss-col-center ss-p-r-20" v-if="state.goodsInfo.stock > 0">
<button <button class="ss-reset-button add-btn ui-Shadow-Main" @tap="state.showSelectSku = true">
class="ss-reset-button add-btn ui-Shadow-Main" 加入购物车
@tap="state.showSelectSku = true" </button>
> <button class="ss-reset-button buy-btn ui-Shadow-Main" @tap="state.showSelectSku = true">
加入购物车 立即购买
</button> </button>
<button </view>
class="ss-reset-button buy-btn ui-Shadow-Main" <view class="buy-box ss-flex ss-col-center ss-p-r-20" v-else>
@tap="state.showSelectSku = true" <button class="ss-reset-button disabled-btn" disabled> 已售罄 </button>
> </view>
立即购买 </detail-tabbar>
</button> <s-coupon-get v-model="state.couponInfo" :show="state.showModel" @close="state.showModel = false"
</view> @get="onGet" />
<view class="buy-box ss-flex ss-col-center ss-p-r-20" v-else> <s-activity-pop v-model="state.activityInfo" :show="state.showActivityModel"
<button class="ss-reset-button disabled-btn" disabled> 已售罄 </button> @close="state.showActivityModel = false" />
</view> </block>
</detail-tabbar> </s-layout>
<s-coupon-get </view>
v-model="state.couponInfo"
:show="state.showModel"
@close="state.showModel = false"
@get="onGet"
/>
<s-activity-pop
v-model="state.activityInfo"
:show="state.showActivityModel"
@close="state.showActivityModel = false"
/>
</block>
</s-layout>
</view>
</template> </template>
<script setup> <script setup>
import { reactive, computed } from 'vue'; import {
import { onLoad, onPageScroll } from '@dcloudio/uni-app'; reactive,
import sheep from '@/sheep'; computed
import { formatSales, formatGoodsSwiper, formatPrice } from '@/sheep/hooks/useGoods'; } from 'vue';
import detailNavbar from './components/detail/detail-navbar.vue'; import {
import detailCellSku from './components/detail/detail-cell-sku.vue'; onLoad,
import detailCellService from './components/detail/detail-cell-service.vue'; onPageScroll
import detailCellParams from './components/detail/detail-cell-params.vue'; } from '@dcloudio/uni-app';
import detailTabbar from './components/detail/detail-tabbar.vue'; import sheep from '@/sheep';
import detailSkeleton from './components/detail/detail-skeleton.vue'; import {
import detailCommentCard from './components/detail/detail-comment-card.vue'; formatSales,
import detailContentCard from './components/detail/detail-content-card.vue'; formatGoodsSwiper,
import detailActivityTip from './components/detail/detail-activity-tip.vue'; formatPrice
import { isEmpty } from 'lodash'; } from '@/sheep/hooks/useGoods';
import detailNavbar from './components/detail/detail-navbar.vue';
import detailCellSku from './components/detail/detail-cell-sku.vue';
import detailCellService from './components/detail/detail-cell-service.vue';
import detailCellParams from './components/detail/detail-cell-params.vue';
import detailTabbar from './components/detail/detail-tabbar.vue';
import detailSkeleton from './components/detail/detail-skeleton.vue';
import detailCommentCard from './components/detail/detail-comment-card.vue';
import detailContentCard from './components/detail/detail-content-card.vue';
import detailActivityTip from './components/detail/detail-activity-tip.vue';
import {
isEmpty
} from 'lodash';
// import detailActivityTip from './components/detail/detail-activity-tip.vue'; // import detailActivityTip from './components/detail/detail-activity-tip.vue';
// import detailTab from './components/detail/detail-tab.vue'; // import detailTab from './components/detail/detail-tab.vue';
// import detailCoupon from './components/detail/detail-coupon.vue'; // import detailCoupon from './components/detail/detail-coupon.vue';
onPageScroll(() => {}); onPageScroll(() => {});
const state = reactive({ const state = reactive({
goodsId: 0, goodsId: 0,
skeletonLoading: true, skeletonLoading: true,
goodsInfo: {}, goodsInfo: {},
showSelectSku: false, showSelectSku: false,
goodsSwiper: [], goodsSwiper: [],
selectedSkuPrice: {}, selectedSkuPrice: {},
showModel: false, showModel: false,
total: 0, total: 0,
couponInfo: [], couponInfo: [],
showActivityModel: false, showActivityModel: false,
activityInfo: [], activityInfo: [],
}); });
// //
function onSkuChange(e) { function onSkuChange(e) {
state.selectedSkuPrice = e; state.selectedSkuPrice = e;
} }
// //
function onAddCart(e) { function onAddCart(e) {
sheep.$store('cart').add(e); sheep.$store('cart').add(e);
} }
// //
function onBuy(e) { function onBuy(e) {
sheep.$router.go('/pages/order/confirm', { sheep.$router.go('/pages/order/confirm', {
data: JSON.stringify({ data: JSON.stringify({
order_type: 'goods', order_type: 'goods',
goods_list: [ goods_list: [{
{ goods_id: e.goods_id,
goods_id: e.goods_id, goods_num: e.goods_num,
goods_num: e.goods_num, goods_sku_price_id: e.id,
goods_sku_price_id: e.id, }, ],
}, }),
], });
}), }
}); //
} function onActivity() {
// state.activityInfo = state.goodsInfo.promos;
function onActivity() { state.showActivityModel = true;
state.activityInfo = state.goodsInfo.promos; }
state.showActivityModel = true;
}
// //
async function onGet(id) { async function onGet(id) {
const { error, msg } = await sheep.$api.coupon.get(id); const {
if (error === 0) { error,
uni.showToast({ msg
title: msg, } = await sheep.$api.coupon.get(id);
}); if (error === 0) {
setTimeout(() => { uni.showToast({
getCoupon(); title: msg,
}, 1000); });
} setTimeout(() => {
} getCoupon();
}, 1000);
}
}
const shareInfo = computed(() => { const shareInfo = computed(() => {
if (isEmpty(state.goodsInfo)) return {}; if (isEmpty(state.goodsInfo)) return {};
return sheep.$platform.share.getShareInfo( return sheep.$platform.share.getShareInfo({
{ title: state.goodsInfo.title,
title: state.goodsInfo.title, image: sheep.$url.cdn(state.goodsInfo.image),
image: sheep.$url.cdn(state.goodsInfo.image), desc: state.goodsInfo.subtitle,
desc: state.goodsInfo.subtitle, params: {
params: { page: '2',
page: '2', query: state.goodsInfo.id,
query: state.goodsInfo.id, },
}, }, {
}, type: 'goods', //
{ title: state.goodsInfo.title, //
type: 'goods', // image: sheep.$url.cdn(state.goodsInfo.image), //
title: state.goodsInfo.title, // price: state.goodsInfo.price[0], //
image: sheep.$url.cdn(state.goodsInfo.image), // original_price: state.goodsInfo.original_price, //
price: state.goodsInfo.price[0], // }, );
original_price: state.goodsInfo.original_price, // });
},
);
});
onLoad(async (options) => { onLoad(async (options) => {
console.log('页面被访问') console.log('页面被访问')
// //
if (!options.id) { if (!options.id) {
state.goodsInfo = null; state.goodsInfo = null;
return; return;
} }
state.goodsId = options.id; state.goodsId = options.id;
// //
sheep.$api.goods.detail(state.goodsId).then((res) => { sheep.$api.goods.detail(state.goodsId).then((res) => {
console.log(res) //
state.skeletonLoading = false; // let arr = [];
if (res.code === 0) { // res.skus = res.data.skus.map(item => {
// // arr = [...arr, ...item.properties];
res.data.sales=res.data.salesCount // item.children = item.properties;
res.data.original_price=res.data.marketPrice/100 // item.goods_id = res.data.id;
res.data.subtitle=res.data.introduction // item.name = item.children[0].propertyName;
res.data.title=res.data.name // return item;
res.data.price=[res.data.price/100] // })
state.goodsInfo = res.data; // console.log(arr, '');
state.goodsSwiper = formatGoodsSwiper(state.goodsInfo.sliderPicUrls); // console.log(res.data, '');
} else { state.skeletonLoading = false;
// if (res.code === 0) {
state.goodsInfo = null; //
} res.data.sales = res.data.salesCount
}); res.data.original_price = res.data.marketPrice / 100
const { error, data } = await sheep.$api.coupon.listByGoods(state.goodsId); res.data.subtitle = res.data.introduction
if (error === 0) { res.data.title = res.data.name
state.couponInfo = data; res.data.price = [res.data.price / 100]
} state.goodsInfo = res.data;
}); state.goodsSwiper = formatGoodsSwiper(state.goodsInfo.sliderPicUrls);
} else {
//
state.goodsInfo = null;
}
});
const {
error,
data
} = await sheep.$api.coupon.listByGoods(state.goodsId);
if (error === 0) {
state.couponInfo = data;
}
});
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.detail-card { .detail-card {
background-color: #ffff; background-color: #ffff;
margin: 14rpx 20rpx; margin: 14rpx 20rpx;
border-radius: 10rpx; border-radius: 10rpx;
overflow: hidden; overflow: hidden;
} }
// //
.title-card { .title-card {
.price-box { .price-box {
.price-text { .price-text {
font-size: 42rpx; font-size: 42rpx;
font-weight: 500; font-weight: 500;
color: #ff3000; color: #ff3000;
line-height: 30rpx; line-height: 30rpx;
font-family: OPPOSANS; font-family: OPPOSANS;
&::before { &::before {
content: '¥'; content: '¥';
font-size: 30rpx; font-size: 30rpx;
} }
} }
.origin-price-text { .origin-price-text {
font-size: 26rpx; font-size: 26rpx;
font-weight: 400; font-weight: 400;
text-decoration: line-through; text-decoration: line-through;
color: $gray-c; color: $gray-c;
font-family: OPPOSANS; font-family: OPPOSANS;
&::before { &::before {
content: '¥'; content: '¥';
} }
} }
} }
.sales-text { .sales-text {
font-size: 26rpx; font-size: 26rpx;
font-weight: 500; font-weight: 500;
color: $gray-c; color: $gray-c;
} }
.discounts-box { .discounts-box {
.tag-content { .tag-content {
flex: 1; flex: 1;
min-width: 0; min-width: 0;
white-space: nowrap; white-space: nowrap;
} }
.tag-box {
overflow: hidden;
text-overflow: ellipsis;
}
.tag {
flex-shrink: 0;
padding: 4rpx 10rpx;
font-size: 24rpx;
font-weight: 500;
border-radius: 4rpx;
color: var(--ui-BG-Main);
background: var(--ui-BG-Main-tag);
}
.discounts-title { .tag-box {
font-size: 24rpx; overflow: hidden;
font-weight: 500; text-overflow: ellipsis;
color: var(--ui-BG-Main); }
line-height: normal;
}
.cicon-forward { .tag {
color: var(--ui-BG-Main); flex-shrink: 0;
font-size: 24rpx; padding: 4rpx 10rpx;
line-height: normal; font-size: 24rpx;
margin-top: 4rpx; font-weight: 500;
} border-radius: 4rpx;
} color: var(--ui-BG-Main);
background: var(--ui-BG-Main-tag);
}
.title-text { .discounts-title {
font-size: 30rpx; font-size: 24rpx;
font-weight: bold; font-weight: 500;
line-height: 42rpx; color: var(--ui-BG-Main);
} line-height: normal;
}
.subtitle-text { .cicon-forward {
font-size: 26rpx; color: var(--ui-BG-Main);
font-weight: 400; font-size: 24rpx;
color: $dark-9; line-height: normal;
line-height: 42rpx; margin-top: 4rpx;
} }
} }
// .title-text {
.buy-box { font-size: 30rpx;
.add-btn { font-weight: bold;
width: 214rpx; line-height: 42rpx;
height: 72rpx; }
font-weight: 500;
font-size: 28rpx;
border-radius: 40rpx 0 0 40rpx;
background-color: var(--ui-BG-Main-light);
color: var(--ui-BG-Main);
}
.buy-btn { .subtitle-text {
width: 214rpx; font-size: 26rpx;
height: 72rpx; font-weight: 400;
font-weight: 500; color: $dark-9;
font-size: 28rpx; line-height: 42rpx;
}
}
border-radius: 0 40rpx 40rpx 0; //
background: linear-gradient(90deg, var(--ui-BG-Main), var(--ui-BG-Main-gradient)); .buy-box {
color: $white; .add-btn {
} width: 214rpx;
.disabled-btn { height: 72rpx;
width: 428rpx; font-weight: 500;
height: 72rpx; font-size: 28rpx;
border-radius: 40rpx; border-radius: 40rpx 0 0 40rpx;
background: #999999; background-color: var(--ui-BG-Main-light);
color: $white; color: var(--ui-BG-Main);
} }
}
.model-box { .buy-btn {
height: 60vh; width: 214rpx;
.model-content { height: 72rpx;
height: 56vh; font-weight: 500;
} font-size: 28rpx;
.title {
font-size: 36rpx;
font-weight: bold;
color: #333333;
}
.subtitle { border-radius: 0 40rpx 40rpx 0;
font-size: 26rpx; background: linear-gradient(90deg, var(--ui-BG-Main), var(--ui-BG-Main-gradient));
font-weight: 500; color: $white;
color: #333333; }
}
} .disabled-btn {
</style> width: 428rpx;
height: 72rpx;
border-radius: 40rpx;
background: #999999;
color: $white;
}
}
.model-box {
height: 60vh;
.model-content {
height: 56vh;
}
.title {
font-size: 36rpx;
font-weight: bold;
color: #333333;
}
.subtitle {
font-size: 26rpx;
font-weight: 500;
color: #333333;
}
}
</style>

View File

@ -1,207 +1,200 @@
<template> <template>
<s-layout title="购物车" tabbar="/pages/index/cart" :bgStyle="{ color: '#fff' }"> <s-layout title="购物车" tabbar="/pages/index/cart" :bgStyle="{ color: '#fff' }">
<s-empty <s-empty v-if="state.list.length === 0" text="购物车空空如也,快去逛逛吧~" icon="/static/cart-empty.png" />
v-if="state.list.length === 0"
text="购物车空空如也,快去逛逛吧~"
icon="/static/cart-empty.png"
/>
<!-- 头部 --> <!-- 头部 -->
<view class="cart-box ss-flex ss-flex-col ss-row-between" v-if="state.list.length"> <view class="cart-box ss-flex ss-flex-col ss-row-between" v-if="state.list.length">
<view class="cart-header ss-flex ss-col-center ss-row-between ss-p-x-30"> <view class="cart-header ss-flex ss-col-center ss-row-between ss-p-x-30">
<view class="header-left ss-flex ss-col-center ss-font-26"> <view class="header-left ss-flex ss-col-center ss-font-26">
<text class="goods-number ui-TC-Main ss-flex">{{ state.list.length }}</text> <text class="goods-number ui-TC-Main ss-flex">{{ state.list.length }}</text>
件商品 件商品
</view> </view>
<view class="header-right"> <view class="header-right">
<button v-if="state.editMode" class="ss-reset-button" @tap="state.editMode = false"> <button v-if="state.editMode" class="ss-reset-button" @tap="state.editMode = false">
取消 取消
</button> </button>
<button v-else class="ss-reset-button ui-TC-Main" @tap="state.editMode = true"> <button v-else class="ss-reset-button ui-TC-Main" @tap="state.editMode = true">
编辑 编辑
</button> </button>
</view> </view>
</view> </view>
<!-- 内容 --> <!-- 内容 -->
<view class="cart-content ss-flex-1 ss-p-x-30 ss-m-b-40"> <view class="cart-content ss-flex-1 ss-p-x-30 ss-m-b-40">
<view class="goods-box ss-r-10 ss-m-b-14" v-for="item in state.list" :key="item.id"> <view class="goods-box ss-r-10 ss-m-b-14" v-for="item in state.list" :key="item.id">
<view class="ss-flex ss-col-center"> <view class="ss-flex ss-col-center">
<label class="check-box ss-flex ss-col-center ss-p-l-10" @tap="onSelectSingle(item.id)"> <label class="check-box ss-flex ss-col-center ss-p-l-10" @tap="onSelectSingle(item.id)">
<radio <radio :checked="state.selectedIds.includes(item.id)" color="var(--ui-BG-Main)"
:checked="state.selectedIds.includes(item.id)" style="transform: scale(0.8)" @tap.stop="onSelectSingle(item.id)" />
color="var(--ui-BG-Main)" </label>
style="transform: scale(0.8)" <s-goods-item :title="item.spu.name" :img="item.spu.picUrl || item.goods.image"
@tap.stop="onSelectSingle(item.id)" :price="item.sku.price/100"
/> :skuText="item.sku.properties.length>1? item.sku.properties.reduce((items2,items)=>items2.valueName+' '+items.valueName):item.sku.properties[0].valueName"
</label> priceColor="#FF3000" :titleWidth="400">
<s-goods-item <template v-if="!state.editMode" v-slot:tool>
:title="item.spu.name" <su-number-box :min="0" :max="item.sku.stock" :step="1" v-model="item.count"
:img="item.spu.picUrl || item.goods.image" @change="onNumberChange($event, item)"></su-number-box>
:price="item.sku.price/100" </template>
:skuText="item.sku.properties.length>1? item.sku.properties.reduce((items2,items)=>items2.valueName+' '+items.valueName):item.sku.properties[0].valueName" </s-goods-item>
priceColor="#FF3000" </view>
:titleWidth="400" </view>
> </view>
<template v-if="!state.editMode" v-slot:tool> <!-- 底部 -->
<su-number-box <su-fixed bottom :val="48" placeholder v-if="state.list.length > 0" :isInset="false">
:min="0" <view class="cart-footer ss-flex ss-col-center ss-row-between ss-p-x-30 border-bottom">
:max="item.sku.stock" <view class="footer-left ss-flex ss-col-center">
:step="1" <label class="check-box ss-flex ss-col-center ss-p-r-30" @tap="onSelectAll">
v-model="item.count" <radio :checked="state.isAllSelected" color="var(--ui-BG-Main)"
@change="onNumberChange($event, item)" style="transform: scale(0.8)" @tap.stop="onSelectAll" />
></su-number-box> <view class="ss-m-l-8"> 全选 </view>
</template> </label>
</s-goods-item> <text>合计</text>
</view> <view class="text-price price-text">
</view> {{ state.totalPriceSelected }}
</view> </view>
<!-- 底部 --> </view>
<su-fixed bottom :val="48" placeholder v-if="state.list.length > 0" :isInset="false"> <view class="footer-right">
<view class="cart-footer ss-flex ss-col-center ss-row-between ss-p-x-30 border-bottom"> <button v-if="state.editMode" class="ss-reset-button ui-BG-Main-Gradient pay-btn ui-Shadow-Main"
<view class="footer-left ss-flex ss-col-center"> @tap="onDelete">
<label class="check-box ss-flex ss-col-center ss-p-r-30" @tap="onSelectAll"> 删除
<radio </button>
:checked="state.isAllSelected" <button v-else class="ss-reset-button ui-BG-Main-Gradient pay-btn ui-Shadow-Main"
color="var(--ui-BG-Main)" @tap="onConfirm">
style="transform: scale(0.8)" 去结算
@tap.stop="onSelectAll" {{ state.selectedIds?.length ? `(${state.selectedIds.length})` : '' }}
/> </button>
<view class="ss-m-l-8"> 全选 </view> </view>
</label> </view>
<text>合计</text> </su-fixed>
<view class="text-price price-text"> </view>
{{ state.totalPriceSelected }} </s-layout>
</view>
</view>
<view class="footer-right">
<button
v-if="state.editMode"
class="ss-reset-button ui-BG-Main-Gradient pay-btn ui-Shadow-Main"
@tap="onDelete"
>
删除
</button>
<button
v-else
class="ss-reset-button ui-BG-Main-Gradient pay-btn ui-Shadow-Main"
@tap="onConfirm"
>
去结算
{{ state.selectedIds?.length ? `(${state.selectedIds.length})` : '' }}
</button>
</view>
</view>
</su-fixed>
</view>
</s-layout>
</template> </template>
<script setup> <script setup>
import sheep from '@/sheep'; import sheep from '@/sheep';
import { computed, reactive, unref } from 'vue'; import {
computed,
reactive,
unref
} from 'vue';
const sys_navBar = sheep.$platform.navbar; const sys_navBar = sheep.$platform.navbar;
const cart = sheep.$store('cart'); const cart = sheep.$store('cart');
const state = reactive({ const state = reactive({
editMode: false, editMode: false,
list: computed(() => cart.list), list: computed(() => cart.list),
selectedList: [], selectedList: [],
selectedIds: computed(() => cart.selectedIds), selectedIds: computed(() => cart.selectedIds),
isAllSelected: computed(() => cart.isAllSelected), isAllSelected: computed(() => cart.isAllSelected),
totalPriceSelected: computed(() => cart.totalPriceSelected), totalPriceSelected: computed(() => cart.totalPriceSelected),
}); });
// //
function onSelectSingle(id) { function onSelectSingle(id) {
console.log('单选') console.log('单选')
cart.selectSingle(id); cart.selectSingle(id);
} }
// //
function onSelectAll() { function onSelectAll() {
cart.selectAll(!state.isAllSelected); cart.selectAll(!state.isAllSelected);
} }
// //
function onConfirm() { function onConfirm() {
let goods_list = []; let items = []
state.selectedList = state.list.filter((item) => state.selectedIds.includes(item.id)); let goods_list = [];
state.selectedList.map((item) => { state.selectedList = state.list.filter((item) => state.selectedIds.includes(item.id));
goods_list.push({ state.selectedList.map((item) => {
goods_id: item.goods_id, console.log(item, '便利');
goods_num: item.goods_num, //
goods_sku_price_id: item.goods_sku_price_id, items.push({
}); skuId: item.sku.id,
}); count: item.count,
if (goods_list.length === 0) { cartId: item.id,
sheep.$helper.toast('请选择商品'); })
return; goods_list.push({
} // goods_id: item.goods_id,
sheep.$router.go('/pages/order/confirm', { goods_id: item.spu.id,
data: JSON.stringify({ // goods_num: item.goods_num,
order_type: 'goods', goods_num: item.count,
goods_list, // id
from: 'cart', // goods_sku_price_id: item.goods_sku_price_id,
}), });
}); });
} // return;
if (goods_list.length === 0) {
sheep.$helper.toast('请选择商品');
return;
}
sheep.$router.go('/pages/order/confirm', {
data: JSON.stringify({
// order_type: 'goods',
// goods_list,
items,
// from: 'cart',
deliveryType: 1,
pointStatus: false,
}),
});
}
function onNumberChange(e, cartItem) { function onNumberChange(e, cartItem) {
if (e === 0) { if (e === 0) {
cart.delete(cartItem.id); cart.delete(cartItem.id);
return; return;
} }
if(cartItem.goods_num === e) return; if (cartItem.goods_num === e) return;
cartItem.goods_num = e; cartItem.goods_num = e;
cart.update({ cart.update({
goods_id: cartItem.id, goods_id: cartItem.id,
goods_num: e, goods_num: e,
goods_sku_price_id: cartItem.goods_sku_price_id, goods_sku_price_id: cartItem.goods_sku_price_id,
}); });
} }
async function onDelete() { async function onDelete() {
cart.delete(state.selectedIds); cart.delete(state.selectedIds);
} }
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
:deep(.ui-fixed) { :deep(.ui-fixed) {
height: 72rpx; height: 72rpx;
} }
.cart-box { .cart-box {
width: 100%; width: 100%;
.cart-header { .cart-header {
height: 70rpx; height: 70rpx;
background-color: #f6f6f6; background-color: #f6f6f6;
width: 100%; width: 100%;
position: fixed; position: fixed;
left: 0; left: 0;
top: v-bind('sys_navBar') rpx; top: v-bind('sys_navBar') rpx;
z-index: 1000; z-index: 1000;
box-sizing: border-box; box-sizing: border-box;
} }
.cart-footer { .cart-footer {
height: 100rpx; height: 100rpx;
background-color: #fff; background-color: #fff;
.pay-btn { .pay-btn {
width: 180rpx; width: 180rpx;
height: 70rpx; height: 70rpx;
font-size: 28rpx; font-size: 28rpx;
line-height: 28rpx; line-height: 28rpx;
font-weight: 500; font-weight: 500;
border-radius: 40rpx; border-radius: 40rpx;
} }
} }
.cart-content { .cart-content {
margin-top: 70rpx; margin-top: 70rpx;
.goods-box {
background-color: #fff; .goods-box {
} background-color: #fff;
} }
} }
</style> }
</style>

View File

@ -89,4 +89,4 @@
onPageScroll(() => {}); onPageScroll(() => {});
</script> </script>
<style></style> <style></style>

View File

@ -1,357 +1,355 @@
<!-- 售后详情 --> <!-- 售后详情 -->
<template> <template>
<s-layout title="售后详情" :navbar="!isEmpty(state.info) && state.loading ? 'inner' : 'normal'"> <s-layout title="售后详情" :navbar="!isEmpty(state.info) && state.loading ? 'inner' : 'normal'">
<view class="content_box" v-if="!isEmpty(state.info) && state.loading"> <view class="content_box" v-if="!isEmpty(state.info) && state.loading">
<!-- 步骤条 --> <!-- 步骤条 -->
<view <!-- 这个没找到替换方案 -->
class="steps-box ss-flex" <view class="steps-box ss-flex" :style="[
:style="[
{ {
marginTop: '-' + Number(statusBarHeight + 88) + 'rpx', marginTop: '-' + Number(statusBarHeight + 88) + 'rpx',
paddingTop: Number(statusBarHeight + 88) + 'rpx', paddingTop: Number(statusBarHeight + 88) + 'rpx',
}, },
]" ]">
> <!-- <uni-steps :options="state.list" :active="state.active" active-color="#fff" /> -->
<!-- <uni-steps :options="state.list" :active="state.active" active-color="#fff" /> --> <view class="ss-flex">
<view class="ss-flex"> <view class="steps-item" v-for="(item, index) in state.list" :key="index">
<view class="steps-item" v-for="(item, index) in state.list" :key="index"> <view class="ss-flex">
<view class="ss-flex"> <text class="sicon-circleclose" v-if="
<text
class="sicon-circleclose"
v-if="
(state.list.length - 1 == index && state.info.aftersale_status === -2) || (state.list.length - 1 == index && state.info.aftersale_status === -2) ||
(state.list.length - 1 == index && state.info.aftersale_status === -1) (state.list.length - 1 == index && state.info.aftersale_status === -1)
" "></text>
></text> <text class="sicon-circlecheck" v-else
<text :class="state.active >= index ? 'activity-color' : 'info-color'"></text>
class="sicon-circlecheck"
v-else
:class="state.active >= index ? 'activity-color' : 'info-color'"
></text>
<view <view v-if="state.list.length - 1 != index" class="line"
v-if="state.list.length - 1 != index" :class="state.active >= index ? 'activity-bg' : 'info-bg'"></view>
class="line" </view>
:class="state.active >= index ? 'activity-bg' : 'info-bg'" <view class="steps-item-title" :class="state.active >= index ? 'activity-color' : 'info-color'">
></view> {{ item.title }}
</view> </view>
<view </view>
class="steps-item-title" </view>
:class="state.active >= index ? 'activity-color' : 'info-color'" </view>
>{{ item.title }}</view
>
</view>
</view>
</view>
<!-- 服务状态 --> <!-- 服务状态 -->
<view <!-- <view class="status-box ss-flex ss-col-center ss-row-between ss-m-x-20"
class="status-box ss-flex ss-col-center ss-row-between ss-m-x-20" @tap="sheep.$router.go('/pages/order/aftersale/log', { id: state.aftersaleId })">
@tap="sheep.$router.go('/pages/order/aftersale/log', { id: state.aftersaleId })" <view class="">
> <view class="status-text">{{ state.info.aftersale_status_desc }}</view>
<view class=""> <view class="status-time">{{ state.info.update_time }}</view>
<view class="status-text">{{ state.info.aftersale_status_desc }}</view> </view>
<view class="status-time">{{ state.info.update_time }}</view> <text class="ss-iconfont _icon-forward" style="color: #666"></text>
</view> </view> -->
<text class="ss-iconfont _icon-forward" style="color: #666"></text>
</view>
<!-- 退款金额 --> <!-- 退款金额 -->
<view class="aftersale-money ss-flex ss-col-center ss-row-between"> <view class="aftersale-money ss-flex ss-col-center ss-row-between">
<view class="aftersale-money--title">退款总额</view> <view class="aftersale-money--title">退款总额</view>
<view class="aftersale-money--num">{{ state.info.refund_fee }}</view> <view class="aftersale-money--num">{{ state.info.refundPrice/100 }}</view>
</view> </view>
<!-- 服务商品 --> <!-- 服务商品 -->
<view class="order-shop"> <view class="order-shop">
<s-goods-item <!-- <s-goods-item :title="state.info.goods_title" :price="state.info.goods_price"
:title="state.info.goods_title" :img="state.info.goods_image" priceColor="#333333" :titleWidth="480"
:price="state.info.goods_price" :skuText="state.info.goods_sku_text" :num="state.info.goods_num"></s-goods-item> -->
:img="state.info.goods_image" <s-goods-item :img=" state.info.picUrl" :title=" state.info.spuName" priceColor="#333333"
priceColor="#333333" :titleWidth="480" :skuText=" state.info.properties.reduce((a,b)=>a+b.valueName+' ','')"
:titleWidth="480" :price=" state.info.refundPrice/100" :num=" state.info.count"></s-goods-item>
:skuText="state.info.goods_sku_text" </view>
:num="state.info.goods_num"
></s-goods-item>
</view>
<!-- 服务内容 --> <!-- 服务内容 -->
<view class="aftersale-content"> <view class="aftersale-content">
<view class="aftersale-item ss-flex ss-col-center"> <view class="aftersale-item ss-flex ss-col-center">
<view class="item-title">服务单号</view> <view class="item-title">服务单号</view>
<view class="item-content ss-m-r-16">{{ state.info.aftersale_sn }}</view> <view class="item-content ss-m-r-16">{{ state.info.no }}</view>
<button class="ss-reset-button copy-btn" @tap="onCopy"></button> <button class="ss-reset-button copy-btn" @tap="onCopy"></button>
</view> </view>
<view class="aftersale-item ss-flex ss-col-center"> <view class="aftersale-item ss-flex ss-col-center">
<view class="item-title">申请时间</view> <view class="item-title">申请时间</view>
<view class="item-content">{{ state.info.create_time }}</view> <view class="item-content">
</view> {{ sheep.$helper.timeFormat(state.info.createTime, 'yyyy-mm-dd hh:MM:ss') }}
<view class="aftersale-item ss-flex ss-col-center"> </view>
<view class="item-title">售后类型</view> </view>
<view class="item-content">{{ state.info.type_text }}</view> <view class="aftersale-item ss-flex ss-col-center">
</view> <view class="item-title">售后类型</view>
<view class="aftersale-item ss-flex ss-col-center"> <view class="item-content">{{ status2[state.info.way] }}</view>
<view class="item-title">申请原因</view> </view>
<view class="item-content">{{ state.info.reason }}</view> <view class="aftersale-item ss-flex ss-col-center">
</view> <view class="item-title">申请原因</view>
<view class="aftersale-item ss-flex ss-col-center"> <view class="item-content">{{ state.info.applyReason }}</view>
<view class="item-title">相关描述</view> </view>
<view class="item-content">{{ state.info.content }}</view> <view class="aftersale-item ss-flex ss-col-center">
</view> <view class="item-title">相关描述</view>
</view> <view class="item-content">{{ state.info.applyDescription }}</view>
</view> </view>
<s-empty </view>
v-if="isEmpty(state.info) && state.loading" </view>
icon="/static/order-empty.png" <s-empty v-if="isEmpty(state.info) && state.loading" icon="/static/order-empty.png" text="暂无该订单售后详情" />
text="暂无该订单售后详情" <!-- <su-fixed bottom placeholder bg="bg-white" v-if="!isEmpty(state.info)">
/> <view class="foot_box">
<su-fixed bottom placeholder bg="bg-white" v-if="!isEmpty(state.info)"> <button class="ss-reset-button btn" v-if="state.info.btns?.includes('cancel')"
<view class="foot_box"> @tap="onApply(state.info.id)">取消申请</button>
<button <button class="ss-reset-button btn" v-if="state.info.btns?.includes('delete')"
class="ss-reset-button btn" @tap="onDelete(state.info.id)">删除</button>
v-if="state.info.btns?.includes('cancel')" <button class="ss-reset-button contcat-btn btn"
@tap="onApply(state.info.id)" @tap="sheep.$router.go('/pages/chat/index')">联系客服</button>
>取消申请</button </view>
> </su-fixed> -->
<!-- <button </s-layout>
class="ss-reset-button btn"
v-if="state.info.btns?.includes('delete')"
@tap="onDelete(state.info.id)"
>删除</button
> -->
<button class="ss-reset-button contcat-btn btn" @tap="sheep.$router.go('/pages/chat/index')"
>联系客服</button
>
</view>
</su-fixed>
</s-layout>
</template> </template>
<script setup> <script setup>
import sheep from '@/sheep'; import sheep from '@/sheep';
import { onLoad } from '@dcloudio/uni-app'; import {
import { reactive } from 'vue'; onLoad
import { isEmpty } from 'lodash'; } from '@dcloudio/uni-app';
import {
reactive
} from 'vue';
import {
isEmpty
} from 'lodash';
const statusBarHeight = sheep.$platform.device.statusBarHeight * 2; const statusBarHeight = sheep.$platform.device.statusBarHeight * 2;
const headerBg = sheep.$url.css('/static/img/shop/order/order_bg.png'); const headerBg = sheep.$url.css('/static/img/shop/order/order_bg.png');
const state = reactive({ const state = reactive({
active: 0, active: 0,
aftersaleId: 0, aftersaleId: 0,
info: {}, info: {},
list: [ list: [{
{ title: '提交申请',
title: '提交申请', },
}, {
{ title: '处理中',
title: '处理中', },
}, ],
], loading: false,
loading: false, });
});
function onApply(orderId) { const status2 = {
uni.showModal({ 10: '仅退款',
title: '提示', 20: '退货退款'
content: '确定要取消此申请吗?', }
success: async function (res) {
if (res.confirm) {
const { error } = await sheep.$api.order.aftersale.cancel(orderId);
if (error === 0) {
getDetail(state.aftersaleId);
}
}
},
});
}
function onDelete(orderId) { function onApply(orderId) {
uni.showModal({ uni.showModal({
title: '提示', title: '提示',
content: '确定要删除吗?', content: '确定要取消此申请吗?',
success: async function (res) { success: async function(res) {
if (res.confirm) { if (res.confirm) {
const { error } = await sheep.$api.order.aftersale.delete(orderId); const {
if (error === 0) { error
sheep.$router.back(); } = await sheep.$api.order.aftersale.cancel(orderId);
} if (error === 0) {
} getDetail(state.aftersaleId);
}, }
}); }
} },
const onCopy = () => { });
sheep.$helper.copyText(state.info.aftersale_sn); }
};
async function getDetail(id) { function onDelete(orderId) {
const { error, data } = await sheep.$api.order.aftersale.detail(id); uni.showModal({
state.loading = true; title: '提示',
if (error === 0) { content: '确定要删除吗?',
state.info = data; success: async function(res) {
if (state.info.aftersale_status === -2 || state.info.aftersale_status === -1) { if (res.confirm) {
state.list.push({ title: state.info.aftersale_status_text }); const {
state.active = 2; error
} else { } = await sheep.$api.order.aftersale.delete(orderId);
state.list.push({ title: '完成' }); if (error === 0) {
state.active = state.info.aftersale_status; sheep.$router.back();
} }
} else { }
state.info = null; },
} });
} }
onLoad((options) => { const onCopy = () => {
state.aftersaleId = options.id; sheep.$helper.copyText(state.info.aftersale_sn);
getDetail(options.id); };
}); async function getDetail(id) {
const {
code,
data
} = await sheep.$api.order.aftersale.detail(id);
state.loading = true;
if (code === 0) {
state.info = data;
if (state.info.aftersale_status === -2 || state.info.aftersale_status === -1) {
state.list.push({
title: state.info.aftersale_status_text
});
state.active = 2;
} else {
state.list.push({
title: '完成'
});
state.active = state.info.aftersale_status;
}
} else {
state.info = null;
}
}
onLoad((options) => {
state.aftersaleId = options.id;
getDetail(options.id);
});
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
// //
.steps-box { .steps-box {
width: 100%; width: 100%;
height: 190rpx; height: 190rpx;
background: v-bind(headerBg) no-repeat, background: v-bind(headerBg) no-repeat,
linear-gradient(90deg, var(--ui-BG-Main), var(--ui-BG-Main-gradient)); linear-gradient(90deg, var(--ui-BG-Main), var(--ui-BG-Main-gradient));
background-size: 750rpx 100%; background-size: 750rpx 100%;
padding-left: 72rpx; padding-left: 72rpx;
.steps-item { .steps-item {
.sicon-circleclose { .sicon-circleclose {
font-size: 24rpx; font-size: 24rpx;
color: #fff; color: #fff;
} }
.sicon-circlecheck {
font-size: 24rpx;
}
.steps-item-title {
font-size: 24rpx;
font-weight: 400;
margin-top: 16rpx;
margin-left: -36rpx;
width: 100rpx;
text-align: center;
}
}
}
.activity-color {
color: #fff;
}
.info-color {
color: rgba(#fff, 0.4);
}
.activity-bg {
background: #fff;
}
.info-bg {
background: rgba(#fff, 0.4);
}
.line { .sicon-circlecheck {
width: 270rpx; font-size: 24rpx;
height: 4rpx; }
}
// .steps-item-title {
.status-box { font-size: 24rpx;
position: relative; font-weight: 400;
z-index: 3; margin-top: 16rpx;
background-color: #fff; margin-left: -36rpx;
border-radius: 20rpx 20rpx 0px 0px; width: 100rpx;
padding: 20rpx; text-align: center;
margin-top: -20rpx; }
}
}
.status-text { .activity-color {
font-size: 28rpx; color: #fff;
}
font-weight: 500; .info-color {
color: rgba(51, 51, 51, 1); color: rgba(#fff, 0.4);
margin-bottom: 20rpx; }
}
.status-time { .activity-bg {
font-size: 24rpx; background: #fff;
}
font-weight: 400; .info-bg {
color: rgba(153, 153, 153, 1); background: rgba(#fff, 0.4);
} }
}
// 退 .line {
.aftersale-money { width: 270rpx;
background-color: #fff; height: 4rpx;
height: 98rpx; }
padding: 0 20rpx;
margin: 20rpx;
.aftersale-money--title { //
font-size: 28rpx; .status-box {
position: relative;
z-index: 3;
background-color: #fff;
border-radius: 20rpx 20rpx 0px 0px;
padding: 20rpx;
margin-top: -20rpx;
font-weight: 500; .status-text {
color: rgba(51, 51, 51, 1); font-size: 28rpx;
}
.aftersale-money--num { font-weight: 500;
font-size: 28rpx; color: rgba(51, 51, 51, 1);
font-family: OPPOSANS; margin-bottom: 20rpx;
font-weight: 500; }
color: #ff3000;
}
}
// order-shop .status-time {
.order-shop { font-size: 24rpx;
padding: 20rpx;
background-color: #fff;
margin: 0 20rpx 20rpx 20rpx;
}
// font-weight: 400;
.aftersale-content { color: rgba(153, 153, 153, 1);
background-color: #fff; }
padding: 20rpx; }
margin: 0 20rpx;
.aftersale-item { // 退
height: 60rpx; .aftersale-money {
background-color: #fff;
height: 98rpx;
padding: 0 20rpx;
margin: 20rpx;
.copy-btn { .aftersale-money--title {
background: #eeeeee; font-size: 28rpx;
color: #333;
border-radius: 20rpx;
width: 75rpx;
height: 40rpx;
font-size: 22rpx;
}
.item-title { font-weight: 500;
color: #999; color: rgba(51, 51, 51, 1);
font-size: 28rpx; }
}
.item-content { .aftersale-money--num {
color: #333; font-size: 28rpx;
font-size: 28rpx; font-family: OPPOSANS;
} font-weight: 500;
} color: #ff3000;
} }
}
// // order-shop
.foot_box { .order-shop {
height: 100rpx; padding: 20rpx;
background-color: #fff; background-color: #fff;
display: flex; margin: 0 20rpx 20rpx 20rpx;
align-items: center; }
justify-content: flex-end;
.btn { //
width: 160rpx; .aftersale-content {
line-height: 60rpx; background-color: #fff;
background: rgba(238, 238, 238, 1); padding: 20rpx;
border-radius: 30rpx; margin: 0 20rpx;
padding: 0;
margin-right: 20rpx;
font-size: 26rpx;
font-weight: 400; .aftersale-item {
color: rgba(51, 51, 51, 1); height: 60rpx;
}
} .copy-btn {
</style> background: #eeeeee;
color: #333;
border-radius: 20rpx;
width: 75rpx;
height: 40rpx;
font-size: 22rpx;
}
.item-title {
color: #999;
font-size: 28rpx;
}
.item-content {
color: #333;
font-size: 28rpx;
}
}
}
//
.foot_box {
height: 100rpx;
background-color: #fff;
display: flex;
align-items: center;
justify-content: flex-end;
.btn {
width: 160rpx;
line-height: 60rpx;
background: rgba(238, 238, 238, 1);
border-radius: 30rpx;
padding: 0;
margin-right: 20rpx;
font-size: 26rpx;
font-weight: 400;
color: rgba(51, 51, 51, 1);
}
}
</style>

View File

@ -1,235 +1,238 @@
<!-- 售后列表 --> <!-- 售后列表 -->
<template> <template>
<s-layout title="售后列表"> <s-layout title="售后列表">
<!-- tab --> <!-- tab -->
<su-sticky bgColor="#fff"> <su-sticky bgColor="#fff">
<su-tabs <su-tabs :list="tabMaps" :scrollable="false" @change="onTabsChange" :current="state.currentTab"></su-tabs>
:list="tabMaps" </su-sticky>
:scrollable="false" <s-empty v-if="state.pagination.total === 0" icon="/static/data-empty.png" text="暂无数据">
@change="onTabsChange" </s-empty>
:current="state.currentTab" <!-- 列表 -->
></su-tabs> <view v-if="state.pagination.total > 0">
</su-sticky> <view class="list-box ss-m-y-20" v-for="order in state.pagination.data" :key="order.id"
<s-empty v-if="state.pagination.total === 0" icon="/static/data-empty.png" text="暂无数据"> @tap="sheep.$router.go('/pages/order/aftersale/detail', { id: order.id })">
</s-empty> <view class="order-head ss-flex ss-col-center ss-row-between">
<!-- 列表 --> <text class="no">服务单号{{ order.no }}</text>
<view v-if="state.pagination.total > 0"> <text class="state">{{ status[order.status] }}</text>
<view </view>
class="list-box ss-m-y-20" <s-goods-item :img="order.picUrl" :title="order.spuName"
v-for="order in state.pagination.data" :skuText="order.properties.reduce((a,b)=>a+b.valueName+' ','')" :price="order.refundPrice/100"
:key="order.id" :num="order.count"></s-goods-item>
@tap="sheep.$router.go('/pages/order/aftersale/detail', { id: order.id })" <view class="apply-box ss-flex ss-col-center ss-row-between border-bottom ss-p-x-20">
> <view class="ss-flex ss-col-center">
<view class="order-head ss-flex ss-col-center ss-row-between"> <!-- 此处需修改 -->
<text class="no">服务单号{{ order.aftersale_sn }}</text> <view class="title ss-m-r-20">{{ status2[order.way] }}</view>
<text class="state">{{ order.aftersale_status_text }}</text> <!-- <view class="value">{{ order.aftersale_status_desc }}</view> -->
</view> <view class="value">{{ order.applyReason }}</view>
<s-goods-item </view>
:img="order.goods_image" <text class="_icon-forward"></text>
:title="order.goods_title" </view>
:skuText="order.goods_sku_text" <!-- <view class="tool-btn-box ss-flex ss-col-center ss-row-right ss-p-r-20">
:price="order.goods_price" <view>
:num="order.goods_num" <button class="ss-reset-button tool-btn" @tap.stop="onApply(order.id)"
></s-goods-item> v-if="order.btns.includes('cancel')">取消申请</button>
<view class="apply-box ss-flex ss-col-center ss-row-between border-bottom ss-p-x-20"> </view>
<view class="ss-flex ss-col-center"> <view>
<view class="title ss-m-r-20">{{ order.type_text }}</view> <button class="ss-reset-button tool-btn" @tap.stop="onDelete(order.id)"
<view class="value">{{ order.aftersale_status_desc }}</view> v-if="order.btns.includes('delete')">删除</button>
</view> </view>
<text class="_icon-forward"></text> </view> -->
</view> </view>
<view class="tool-btn-box ss-flex ss-col-center ss-row-right ss-p-r-20"> </view>
<view> <uni-load-more v-if="state.pagination.total > 0" :status="state.loadStatus" :content-text="{
<button
class="ss-reset-button tool-btn"
@tap.stop="onApply(order.id)"
v-if="order.btns.includes('cancel')"
>取消申请</button
>
</view>
<view>
<button
class="ss-reset-button tool-btn"
@tap.stop="onDelete(order.id)"
v-if="order.btns.includes('delete')"
>删除</button
>
</view>
</view>
</view>
</view>
<uni-load-more
v-if="state.pagination.total > 0"
:status="state.loadStatus"
:content-text="{
contentdown: '上拉加载更多', contentdown: '上拉加载更多',
}" }" @tap="loadmore" />
@tap="loadmore" </s-layout>
/>
</s-layout>
</template> </template>
<script setup> <script setup>
import sheep from '@/sheep'; import sheep from '@/sheep';
import { onLoad, onReachBottom } from '@dcloudio/uni-app'; import {
import { computed, reactive } from 'vue'; onLoad,
import _ from 'lodash'; onReachBottom
} from '@dcloudio/uni-app';
import {
computed,
reactive
} from 'vue';
import _ from 'lodash';
const pagination = { const pagination = {
data: [], data: [],
current_page: 1, current_page: 1,
total: 1, total: 1,
last_page: 1, last_page: 1,
}; };
const state = reactive({ const state = reactive({
currentTab: 0, currentTab: 0,
showApply: false, showApply: false,
pagination: { pagination: {
data: [], data: [],
current_page: 1, current_page: 1,
total: 1, total: 1,
last_page: 1, last_page: 1,
}, },
loadStatus: '', loadStatus: '',
}); });
//
const status = {
10: '申请售后',
20: '商品待退货',
30: '商家待收货',
40: '等待退款',
50: '退款成功',
61: '买家取消',
62: '商家拒绝',
63: '商家拒收货'
}
const status2 = {
10: '仅退款',
20: '退货退款'
}
const tabMaps = [{
name: '全部',
value: 'all',
},
// {
// name: '',
// value: 'nooper',
// },
// {
// name: '',
// value: 'ing',
// },
// {
// name: '',
// value: 'completed',
// },
// {
// name: '',
// value: 'refuse',
// },
];
//
function onTabsChange(e) {
state.pagination = pagination
state.currentTab = e.index;
getOrderList();
}
const tabMaps = [ //
{ async function getOrderList(page = 1, list_rows = 5) {
name: '全部', pagination.current_page = page;
value: 'all', state.loadStatus = 'loading';
}, let res = await sheep.$api.order.aftersale.list({
{ // type: tabMaps[state.currentTab].value,
name: '申请中', pageSize: list_rows,
value: 'nooper', pageNo: page,
}, });
{ console.log(res, '未处理前售后列表数据')
name: '处理中', if (res.code === 0) {
value: 'ing', let orderList = _.concat(state.pagination.data, res.data.list);
},
{
name: '已完成',
value: 'completed',
},
{
name: '已拒绝',
value: 'refuse',
},
];
//
function onTabsChange(e) {
state.pagination = pagination
state.currentTab = e.index;
getOrderList();
}
// state.pagination = {
async function getOrderList(page = 1, list_rows = 5) { total: res.data.total,
state.loadStatus = 'loading'; ...res.data,
let res = await sheep.$api.order.aftersale.list({ data: orderList,
type: tabMaps[state.currentTab].value, };
list_rows, console.log(state.pagination, '售后订单数据')
page, // if (state.pagination.current_page < state.pagination.last_page) {
}); state.loadStatus = 'more';
if (res.error === 0) { // } else {
let orderList = _.concat(state.pagination.data, res.data.data); // state.loadStatus = 'noMore';
state.pagination = { // }
...res.data, }
data: orderList, }
};
if (state.pagination.current_page < state.pagination.last_page) { function onApply(orderId) {
state.loadStatus = 'more'; uni.showModal({
} else { title: '提示',
state.loadStatus = 'noMore'; content: '确定要取消此申请吗?',
} success: async function(res) {
} if (res.confirm) {
} const {
error
} = await sheep.$api.order.aftersale.cancel(orderId);
if (error === 0) {
state.pagination = pagination
getOrderList();
}
}
},
});
}
function onApply(orderId) { function onDelete(orderId) {
uni.showModal({ uni.showModal({
title: '提示', title: '提示',
content: '确定要取消此申请吗?', content: '确定要删除吗?',
success: async function (res) { success: async function(res) {
if (res.confirm) { if (res.confirm) {
const { error } = await sheep.$api.order.aftersale.cancel(orderId); const {
if (error === 0) { error
state.pagination = pagination } = await sheep.$api.order.aftersale.delete(orderId);
getOrderList(); if (error === 0) {
} state.pagination = pagination
} getOrderList();
}, }
}); }
} },
});
}
function onDelete(orderId) { onLoad(async (options) => {
uni.showModal({ if (options.type) {
title: '提示', state.currentTab = options.type;
content: '确定要删除吗?', }
success: async function (res) { getOrderList();
if (res.confirm) { });
const { error } = await sheep.$api.order.aftersale.delete(orderId);
if (error === 0) {
state.pagination = pagination
getOrderList();
}
}
},
});
}
onLoad(async (options) => { //
if (options.type) { function loadmore() {
state.currentTab = options.type; // if (state.loadStatus !== 'noMore') {
} getOrderList(pagination.current_page + 1);
getOrderList(); // }
}); }
// //
function loadmore() { onReachBottom(() => {
if (state.loadStatus !== 'noMore') { loadmore();
getOrderList(state.pagination.current_page + 1); });
}
}
//
onReachBottom(() => {
loadmore();
});
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.list-box { .list-box {
background-color: #fff; background-color: #fff;
.order-head { .order-head {
padding: 0 25rpx; padding: 0 25rpx;
height: 77rpx; height: 77rpx;
} }
.apply-box { .apply-box {
height: 82rpx; height: 82rpx;
.title { .title {
font-size: 24rpx; font-size: 24rpx;
} }
.value { .value {
font-size: 22rpx; font-size: 22rpx;
color: $dark-6; color: $dark-6;
} }
} }
.tool-btn-box { .tool-btn-box {
height: 100rpx; height: 100rpx;
.tool-btn { .tool-btn {
width: 160rpx; width: 160rpx;
height: 60rpx; height: 60rpx;
background: #f6f6f6; background: #f6f6f6;
border-radius: 30rpx; border-radius: 30rpx;
font-size: 26rpx; font-size: 26rpx;
font-weight: 400; font-weight: 400;
} }
} }
} }
</style> </style>

View File

@ -1,419 +1,414 @@
<template> <template>
<s-layout title="确认订单"> <s-layout title="确认订单">
<view <!-- v-if="state.orderInfo.need_address === 1" -->
class="bg-white address-box ss-m-b-14 ss-r-b-10" <!-- 这个判断先删除 -->
@tap="onSelectAddress" <view class="bg-white address-box ss-m-b-14 ss-r-b-10" @tap="onSelectAddress">
v-if="state.orderInfo.need_address === 1" <s-address-item :item="state.addressInfo" :hasBorderBottom="false">
> <view class="ss-rest-button"><text class="_icon-forward"></text></view>
<s-address-item :item="state.addressInfo" :hasBorderBottom="false"> </s-address-item>
<view class="ss-rest-button"><text class="_icon-forward"></text></view> </view>
</s-address-item> <view class="order-card-box ss-m-b-14">
</view> <s-goods-item v-for="item in state.orderInfo.goods_list" :key="item.goods_id"
<view class="order-card-box ss-m-b-14"> :img="item.current_sku_price.image || item.goods.image" :title="item.goods.title"
<s-goods-item :skuText="item.current_sku_price?.goods_sku_text" :price="item.current_sku_price.price"
v-for="item in state.orderInfo.goods_list" :num="item.goods_num" marginBottom="10">
:key="item.goods_id" <template #top>
:img="item.current_sku_price.image || item.goods.image" <view class="order-item ss-flex ss-col-center ss-row-between ss-p-x-20 bg-white">
:title="item.goods.title" <view class="item-title">配送方式</view>
:skuText="item.current_sku_price?.goods_sku_text" <view class="ss-flex ss-col-center">
:price="item.current_sku_price.price" <text class="item-value">{{ item.dispatch_type_text }}</text>
:num="item.goods_num" </view>
marginBottom="10" </view>
> </template>
<template #top> </s-goods-item>
<view class="order-item ss-flex ss-col-center ss-row-between ss-p-x-20 bg-white">
<view class="item-title">配送方式</view>
<view class="ss-flex ss-col-center">
<text class="item-value">{{ item.dispatch_type_text }}</text>
</view>
</view>
</template>
</s-goods-item>
<view class="order-item ss-flex ss-col-center ss-row-between ss-p-x-20 bg-white ss-r-10"> <view class="order-item ss-flex ss-col-center ss-row-between ss-p-x-20 bg-white ss-r-10">
<view class="item-title">订单备注</view> <view class="item-title">订单备注</view>
<view class="ss-flex ss-col-center"> <view class="ss-flex ss-col-center">
<uni-easyinput <uni-easyinput maxlength="20" placeholder="建议留言前先与商家沟通" v-model="state.orderPayload.remark"
maxlength="20" :inputBorder="false" :clearable="false"></uni-easyinput>
placeholder="建议留言前先与商家沟通" </view>
v-model="state.orderPayload.remark" </view>
:inputBorder="false" </view>
:clearable="false" <!-- 合计 -->
></uni-easyinput> <view class="bg-white total-card-box ss-p-20 ss-m-b-14 ss-r-10">
</view> <view class="total-box-content border-bottom">
</view> <view class="order-item ss-flex ss-col-center ss-row-between">
</view> <view class="item-title">商品金额</view>
<!-- 合计 --> <view class="ss-flex ss-col-center">
<view class="bg-white total-card-box ss-p-20 ss-m-b-14 ss-r-10"> <text class="item-value ss-m-r-24">{{ state.orderInfo.goods_amount }}</text>
<view class="total-box-content border-bottom"> </view>
<view class="order-item ss-flex ss-col-center ss-row-between"> </view>
<view class="item-title">商品金额</view> <view class="order-item ss-flex ss-col-center ss-row-between"
<view class="ss-flex ss-col-center"> v-if="state.orderPayload.order_type === 'score'">
<text class="item-value ss-m-r-24">{{ state.orderInfo.goods_amount }}</text> <view class="item-title">扣除积分</view>
</view> <view class="ss-flex ss-col-center">
</view> <image :src="sheep.$url.static('/static/img/shop/goods/score1.svg')" class="score-img"></image>
<view <text class="item-value ss-m-r-24">{{ state.orderInfo.score_amount }}</text>
class="order-item ss-flex ss-col-center ss-row-between" </view>
v-if="state.orderPayload.order_type === 'score'" </view>
> <view class="order-item ss-flex ss-col-center ss-row-between">
<view class="item-title">扣除积分</view> <view class="item-title">运费</view>
<view class="ss-flex ss-col-center"> <view class="ss-flex ss-col-center">
<image <text class="item-value ss-m-r-24">+{{ state.orderInfo.dispatch_amount }}</text>
:src="sheep.$url.static('/static/img/shop/goods/score1.svg')" </view>
class="score-img" </view>
></image> <view class="order-item ss-flex ss-col-center ss-row-between"
<text class="item-value ss-m-r-24">{{ state.orderInfo.score_amount }}</text> v-if="state.orderPayload.order_type != 'score'">
</view> <!-- <view v-if="state.orderInfo.coupon_discount_fee > 0" class="order-item ss-flex ss-col-center ss-row-between"> -->
</view> <view class="item-title">优惠券</view>
<view class="order-item ss-flex ss-col-center ss-row-between"> <view class="ss-flex ss-col-center" @tap="state.showCoupon = true">
<view class="item-title">运费</view> <text class="item-value text-red"
<view class="ss-flex ss-col-center"> v-if="state.orderPayload.coupon_id">-{{ state.orderInfo.coupon_discount_fee }}</text>
<text class="item-value ss-m-r-24">+{{ state.orderInfo.dispatch_amount }}</text> <text class="item-value"
</view> :class="state.couponInfo.can_use?.length > 0 ? 'text-red' : 'text-disabled'" v-else>{{
</view>
<view
class="order-item ss-flex ss-col-center ss-row-between"
v-if="state.orderPayload.order_type != 'score'"
>
<!-- <view v-if="state.orderInfo.coupon_discount_fee > 0" class="order-item ss-flex ss-col-center ss-row-between"> -->
<view class="item-title">优惠券</view>
<view class="ss-flex ss-col-center" @tap="state.showCoupon = true">
<text class="item-value text-red" v-if="state.orderPayload.coupon_id"
>-{{ state.orderInfo.coupon_discount_fee }}</text
>
<text
class="item-value"
:class="state.couponInfo.can_use?.length > 0 ? 'text-red' : 'text-disabled'"
v-else
>{{
state.couponInfo.can_use?.length > 0 state.couponInfo.can_use?.length > 0
? state.couponInfo.can_use?.length + '张可用' ? state.couponInfo.can_use?.length + '张可用'
: '暂无可用优惠券' : '暂无可用优惠券'
}}</text }}</text>
>
<text class="_icon-forward item-icon"></text> <text class="_icon-forward item-icon"></text>
</view> </view>
</view> </view>
<view <view class="order-item ss-flex ss-col-center ss-row-between"
class="order-item ss-flex ss-col-center ss-row-between" v-if="state.orderInfo.promo_infos?.length">
v-if="state.orderInfo.promo_infos?.length" <!-- <view v-if="state.orderInfo.promo_discount_fee > 0" class="order-item ss-flex ss-col-center ss-row-between"> -->
> <view class="item-title">活动优惠</view>
<!-- <view v-if="state.orderInfo.promo_discount_fee > 0" class="order-item ss-flex ss-col-center ss-row-between"> --> <view class="ss-flex ss-col-center" @tap="state.showDiscount = true">
<view class="item-title">活动优惠</view> <text class="item-value text-red"> -{{ state.orderInfo.promo_discount_fee }} </text>
<view class="ss-flex ss-col-center" @tap="state.showDiscount = true"> <text class="_icon-forward item-icon"></text>
<text class="item-value text-red"> -{{ state.orderInfo.promo_discount_fee }} </text> </view>
<text class="_icon-forward item-icon"></text> </view>
</view> </view>
</view> <view class="total-box-footer ss-font-28 ss-flex ss-row-right ss-col-center ss-m-r-28">
</view> <view class="total-num ss-m-r-20">{{ state.totalNumber }}</view>
<view class="total-box-footer ss-font-28 ss-flex ss-row-right ss-col-center ss-m-r-28"> <view>合计</view>
<view class="total-num ss-m-r-20">{{ state.totalNumber }}</view> <view class="total-num text-red"> {{ state.orderInfo.pay_fee }} </view>
<view>合计</view> <view class="ss-flex" v-if="state.orderPayload.order_type === 'score'">
<view class="total-num text-red"> {{ state.orderInfo.pay_fee }} </view> <view class="total-num ss-font-30 text-red ss-m-l-4"> + </view>
<view class="ss-flex" v-if="state.orderPayload.order_type === 'score'"> <image :src="sheep.$url.static('/static/img/shop/goods/score1.svg')" class="score-img"></image>
<view class="total-num ss-font-30 text-red ss-m-l-4"> + </view> <view class="total-num ss-font-30 text-red">{{ state.orderInfo.score_amount }}</view>
<image </view>
:src="sheep.$url.static('/static/img/shop/goods/score1.svg')" </view>
class="score-img" </view>
></image> <!-- 发票 -->
<view class="total-num ss-font-30 text-red">{{ state.orderInfo.score_amount }}</view> <view class="bg-white ss-p-20 ss-r-20">
</view> <view class="order-item ss-flex ss-col-center ss-row-between">
</view> <view class="item-title">发票申请</view>
</view> <view class="ss-flex ss-col-center" @tap="onSelectInvoice">
<!-- 发票 --> <text class="item-value">{{ state.invoiceInfo.name || '无需开具发票' }}</text>
<view class="bg-white ss-p-20 ss-r-20"> <text class="_icon-forward item-icon"></text>
<view class="order-item ss-flex ss-col-center ss-row-between"> </view>
<view class="item-title">发票申请</view> </view>
<view class="ss-flex ss-col-center" @tap="onSelectInvoice"> </view>
<text class="item-value">{{ state.invoiceInfo.name || '无需开具发票' }}</text> <!-- 选择优惠券弹框 -->
<text class="_icon-forward item-icon"></text> <s-coupon-select v-model="state.couponInfo" :show="state.showCoupon" @confirm="onSelectCoupon"
</view> @close="state.showCoupon = false" />
</view> <!-- 满额折扣弹框 -->
</view> <s-discount-list v-model="state.orderInfo" :show="state.showDiscount" @close="state.showDiscount = false" />
<!-- 选择优惠券弹框 --> <!-- 底部 -->
<s-coupon-select <su-fixed bottom :opacity="false" bg="bg-white" placeholder :noFixed="false" :index="200">
v-model="state.couponInfo" <view class="footer-box border-top ss-flex ss-row-between ss-p-x-20 ss-col-center">
:show="state.showCoupon" <view class="total-box-footer ss-flex ss-col-center">
@confirm="onSelectCoupon" <view class="total-num ss-font-30 text-red"> {{ state.orderInfo.pay_fee }} </view>
@close="state.showCoupon = false" <view v-if="state.orderPayload.order_type === 'score'" class="ss-flex">
/> <view class="total-num ss-font-30 text-red ss-m-l-4">+</view>
<!-- 满额折扣弹框 --> <image :src="sheep.$url.static('/static/img/shop/goods/score1.svg')" class="score-img"></image>
<s-discount-list <view class="total-num ss-font-30 text-red">{{ state.orderInfo.score_amount }}</view>
v-model="state.orderInfo" </view>
:show="state.showDiscount" </view>
@close="state.showDiscount = false"
/>
<!-- 底部 -->
<su-fixed bottom :opacity="false" bg="bg-white" placeholder :noFixed="false" :index="200">
<view class="footer-box border-top ss-flex ss-row-between ss-p-x-20 ss-col-center">
<view class="total-box-footer ss-flex ss-col-center">
<view class="total-num ss-font-30 text-red"> {{ state.orderInfo.pay_fee }} </view>
<view v-if="state.orderPayload.order_type === 'score'" class="ss-flex">
<view class="total-num ss-font-30 text-red ss-m-l-4">+</view>
<image
:src="sheep.$url.static('/static/img/shop/goods/score1.svg')"
class="score-img"
></image>
<view class="total-num ss-font-30 text-red">{{ state.orderInfo.score_amount }}</view>
</view>
</view>
<button <button class="ss-reset-button ui-BG-Main-Gradient ss-r-40 submit-btn ui-Shadow-Main" @tap="onConfirm">
class="ss-reset-button ui-BG-Main-Gradient ss-r-40 submit-btn ui-Shadow-Main" {{ exchangeNow ? '立即兑换' : '提交订单' }}
@tap="onConfirm" </button>
> </view>
{{ exchangeNow ? '立即兑换' : '提交订单' }} </su-fixed>
</button> </s-layout>
</view>
</su-fixed>
</s-layout>
</template> </template>
<script setup> <script setup>
import { reactive, computed } from 'vue'; import {
import { onLoad, onPageScroll, onShow } from '@dcloudio/uni-app'; reactive,
import sheep from '@/sheep'; computed
import { isEmpty } from 'lodash'; } from 'vue';
import {
onLoad,
onPageScroll,
onShow
} from '@dcloudio/uni-app';
import sheep from '@/sheep';
import {
isEmpty
} from 'lodash';
const state = reactive({ const state = reactive({
orderPayload: {}, orderPayload: {},
orderInfo: {}, orderInfo: {},
addressInfo: {}, addressInfo: {},
invoiceInfo: {}, invoiceInfo: {},
totalNumber: 0, totalNumber: 0,
showCoupon: false, showCoupon: false,
couponInfo: [], couponInfo: [],
showDiscount: false, showDiscount: false,
}); });
// () // ()
const exchangeNow = computed( const exchangeNow = computed(
() => state.orderPayload.order_type === 'score' && state.orderInfo.pay_fee == 0, () => state.orderPayload.order_type === 'score' && state.orderInfo.pay_fee == 0,
); );
// //
function onSelectAddress() { function onSelectAddress() {
uni.$once('SELECT_ADDRESS', (e) => { uni.$once('SELECT_ADDRESS', (e) => {
changeConsignee(e.addressInfo); changeConsignee(e.addressInfo);
}); });
sheep.$router.go('/pages/user/address/list'); sheep.$router.go('/pages/user/address/list');
} }
// & // &
async function changeConsignee(addressInfo = {}) { async function changeConsignee(addressInfo = {}) {
if (isEmpty(addressInfo)) { if (isEmpty(addressInfo)) {
const { error, data } = await sheep.$api.user.address.default(); const {
if (error === 0 && !isEmpty(data)) { code,
addressInfo = data; data
} } = await sheep.$api.user.address.default();
} console.log(data, '默认收货地址');
if (!isEmpty(addressInfo)) { if (code === 0 && !isEmpty(data)) {
state.addressInfo = addressInfo; console.log('执行赋值')
state.orderPayload.address_id = state.addressInfo.id; addressInfo = data;
} }
getOrderInfo(); }
} if (!isEmpty(addressInfo)) {
state.addressInfo = addressInfo;
state.orderPayload.address_id = state.addressInfo.id;
}
getOrderInfo();
}
// //
async function onSelectCoupon(e) { async function onSelectCoupon(e) {
state.orderPayload.coupon_id = e || 0; state.orderPayload.coupon_id = e || 0;
getOrderInfo(); getOrderInfo();
state.showCoupon = false; state.showCoupon = false;
} }
// //
function onSelectInvoice() { function onSelectInvoice() {
uni.$once('SELECT_INVOICE', (e) => { uni.$once('SELECT_INVOICE', (e) => {
state.invoiceInfo = e.invoiceInfo; state.invoiceInfo = e.invoiceInfo;
state.orderPayload.invoice_id = e.invoiceInfo.id || 0; state.orderPayload.invoice_id = e.invoiceInfo.id || 0;
}); });
sheep.$router.go('/pages/user/invoice/list'); sheep.$router.go('/pages/user/invoice/list');
} }
// / // /
function onConfirm() { function onConfirm() {
if (!state.orderPayload.address_id && state.orderInfo.need_address === 1) { if (!state.orderPayload.address_id && state.orderInfo.need_address === 1) {
sheep.$helper.toast('请选择收货地址'); sheep.$helper.toast('请选择收货地址');
return; return;
} }
if (exchangeNow.value) { if (exchangeNow.value) {
uni.showModal({ uni.showModal({
title: '提示', title: '提示',
content: '确定使用积分立即兑换?', content: '确定使用积分立即兑换?',
cancelText: '再想想', cancelText: '再想想',
success: async function (res) { success: async function(res) {
if (res.confirm) { if (res.confirm) {
submitOrder(); submitOrder();
} }
}, },
}); });
} else { } else {
submitOrder(); submitOrder();
} }
} }
// & // &
async function submitOrder() { async function submitOrder() {
const { error, data } = await sheep.$api.order.create(state.orderPayload); const {
if (error === 0) { error,
// data
if (state.orderPayload.from === 'cart') { } = await sheep.$api.order.create(state.orderPayload);
sheep.$store('cart').getList(); if (error === 0) {
} //
if (exchangeNow.value) { if (state.orderPayload.from === 'cart') {
sheep.$router.redirect('/pages/pay/result', { sheep.$store('cart').getList();
orderSN: data.order_sn, }
}); if (exchangeNow.value) {
} else { sheep.$router.redirect('/pages/pay/result', {
sheep.$router.redirect('/pages/pay/index', { orderSN: data.order_sn,
orderSN: data.order_sn, });
}); } else {
} sheep.$router.redirect('/pages/pay/index', {
} orderSN: data.order_sn,
} });
}
}
}
// & // &
async function getOrderInfo() { async function getOrderInfo() {
let { error, data } = await sheep.$api.order.calc(state.orderPayload); console.log(state.orderPayload, '计算价格传参')
if (error === 0) { // let {code, data} = await sheep.$api.order.calc(state.orderPayload);
state.totalNumber = 0; // let data = await sheep.$api.order.calc(state.orderPayload);
state.orderInfo = data; console.log(state.orderPayload.items)
state.orderInfo.goods_list.forEach((item) => { let data = await sheep.$api.order.calc({
state.totalNumber += item.goods_num; deliveryType: 1,
}); pointStatus: false,
} items: state.orderPayload.items
} });
console.log(data, '修改后的获取订单详细数据')
return;
if (error === 0) {
state.totalNumber = 0;
state.orderInfo = data;
state.orderInfo.goods_list.forEach((item) => {
state.totalNumber += item.goods_num;
});
}
}
// //
async function getCoupons() { async function getCoupons() {
const { error, data } = await sheep.$api.order.coupons(state.orderPayload); const {
if (error === 0) { error,
state.couponInfo = data; data
} } = await sheep.$api.order.coupons(state.orderPayload);
} if (error === 0) {
state.couponInfo = data;
}
}
onLoad(async (options) => { onLoad(async (options) => {
if (options.data) { console.log(options)
state.orderPayload = JSON.parse(options.data); if (options.data) {
changeConsignee(); state.orderPayload = JSON.parse(options.data);
if (state.orderPayload.order_type !== 'score') { changeConsignee();
getCoupons(); if (state.orderPayload.order_type !== 'score') {
} getCoupons();
} }
}); }
});
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
:deep() { :deep() {
.uni-input-wrapper { .uni-input-wrapper {
width: 320rpx; width: 320rpx;
} }
.uni-easyinput__content-input { .uni-easyinput__content-input {
font-size: 28rpx; font-size: 28rpx;
height: 72rpx; height: 72rpx;
text-align: right !important; text-align: right !important;
padding-right: 0 !important; padding-right: 0 !important;
.uni-input-input { .uni-input-input {
font-weight: 500; font-weight: 500;
color: #333333; color: #333333;
font-size: 26rpx; font-size: 26rpx;
height: 32rpx; height: 32rpx;
margin-top: 4rpx; margin-top: 4rpx;
} }
} }
.uni-easyinput__content {
display: flex !important;
align-items: center !important;
justify-content: right !important;
}
}
.score-img {
width: 36rpx;
height: 36rpx;
margin: 0 4rpx;
}
.order-item {
height: 80rpx;
.item-title { .uni-easyinput__content {
font-size: 28rpx; display: flex !important;
font-weight: 400; align-items: center !important;
} justify-content: right !important;
}
}
.item-value { .score-img {
font-size: 28rpx; width: 36rpx;
font-weight: 500; height: 36rpx;
font-family: OPPOSANS; margin: 0 4rpx;
} }
.text-disabled {
color: #bbbbbb;
}
.item-icon { .order-item {
color: $dark-9; height: 80rpx;
}
.remark-input { .item-title {
text-align: right; font-size: 28rpx;
} font-weight: 400;
}
.item-placeholder { .item-value {
color: $dark-9; font-size: 28rpx;
font-size: 26rpx; font-weight: 500;
text-align: right; font-family: OPPOSANS;
} }
}
.total-box-footer { .text-disabled {
height: 90rpx; color: #bbbbbb;
}
.total-num { .item-icon {
color: #333333; color: $dark-9;
font-family: OPPOSANS; }
}
}
.footer-box { .remark-input {
height: 100rpx; text-align: right;
}
.submit-btn { .item-placeholder {
width: 240rpx; color: $dark-9;
height: 70rpx; font-size: 26rpx;
font-size: 28rpx; text-align: right;
font-weight: 500; }
}
.goto-pay-text { .total-box-footer {
line-height: 28rpx; height: 90rpx;
}
}
.cancel-btn { .total-num {
width: 240rpx; color: #333333;
height: 80rpx; font-family: OPPOSANS;
font-size: 26rpx; }
background-color: #e5e5e5; }
color: $dark-9;
} .footer-box {
} height: 100rpx;
.title {
font-size: 36rpx; .submit-btn {
font-weight: bold; width: 240rpx;
color: #333333; height: 70rpx;
} font-size: 28rpx;
.subtitle { font-weight: 500;
font-size: 28rpx;
color: #999999; .goto-pay-text {
} line-height: 28rpx;
.cicon-checkbox { }
font-size: 36rpx; }
color: var(--ui-BG-Main);
} .cancel-btn {
.cicon-box { width: 240rpx;
font-size: 36rpx; height: 80rpx;
color: #999999; font-size: 26rpx;
} background-color: #e5e5e5;
</style> color: $dark-9;
}
}
.title {
font-size: 36rpx;
font-weight: bold;
color: #333333;
}
.subtitle {
font-size: 28rpx;
color: #999999;
}
.cicon-checkbox {
font-size: 36rpx;
color: var(--ui-BG-Main);
}
.cicon-box {
font-size: 36rpx;
color: #999999;
}
</style>

File diff suppressed because it is too large Load Diff

View File

@ -7,7 +7,7 @@
<s-empty v-if="state.pagination.total === 0" icon="/static/order-empty.png" text="暂无订单"></s-empty> <s-empty v-if="state.pagination.total === 0" icon="/static/order-empty.png" text="暂无订单"></s-empty>
<view v-if="state.pagination.total > 0"> <view v-if="state.pagination.total > 0">
<view class="bg-white order-list-card-box ss-r-10 ss-m-t-14 ss-m-20" v-for="order in state.pagination.data" <view class="bg-white order-list-card-box ss-r-10 ss-m-t-14 ss-m-20" v-for="order in state.pagination.data"
:key="order.id" @tap="onOrderDetail(order.no)"> :key="order.id" @tap="onOrderDetail(order.id)">
<view class="order-card-header ss-flex ss-col-center ss-row-between ss-p-x-20"> <view class="order-card-header ss-flex ss-col-center ss-row-between ss-p-x-20">
<view class="order-no">订单号{{ order.no }}</view> <view class="order-no">订单号{{ order.no }}</view>
<view class="order-state ss-font-26" :class="formatOrderColor(order.status_code)">{{ <view class="order-state ss-font-26" :class="formatOrderColor(order.status_code)">{{
@ -15,7 +15,8 @@
}}</view> }}</view>
</view> </view>
<view class="border-bottom" v-for="item in order.items" :key="item.id"> <view class="border-bottom" v-for="item in order.items" :key="item.id">
<s-goods-item :img="item.picUrl" :title="item.spuName" :skuText="item.properties.length>1? item.properties.reduce((items2,items)=>items2.valueName+' '+items.valueName):item.properties[0].valueName" <s-goods-item :img="item.picUrl" :title="item.spuName"
:skuText="item.properties.length>1? item.properties.reduce((items2,items)=>items2.valueName+' '+items.valueName):item.properties[0].valueName"
:price="item.price/100" :score="order.score_amount" :num="item.count"> :price="item.price/100" :score="order.score_amount" :num="item.count">
<template #tool> <template #tool>
<view class="ss-flex"> <view class="ss-flex">
@ -61,7 +62,7 @@
<view class="discounts-title">优惠:</view> <view class="discounts-title">优惠:</view>
<view class="discounts-money">{{ order.total_discount_fee }}</view> <view class="discounts-money">{{ order.total_discount_fee }}</view>
</view> --> </view> -->
<!-- <view class="ss-flex ss-col-center ss-m-r-8"> <!-- <view class="ss-flex ss-col-center ss-m-r-8">
<view class="discounts-title">运费:</view> <view class="discounts-title">运费:</view>
<view class="discounts-money">{{ order.dispatch_amount }}</view> <view class="discounts-money">{{ order.dispatch_amount }}</view>
</view> --> </view> -->
@ -96,7 +97,7 @@
</template> </template>
</su-popover> --> </su-popover> -->
<view class="ss-flex ss-col-center"> <view class="ss-flex ss-col-center">
<!-- <button v-if="order.btns.includes('groupon')" class="tool-btn ss-reset-button" <!-- <button v-if="order.btns.includes('groupon')" class="tool-btn ss-reset-button"
@tap.stop="onOrderGroupon(order)"> @tap.stop="onOrderGroupon(order)">
{{ order.status_code === 'groupon_ing' ? '邀请拼团' : '拼团详情' }} {{ order.status_code === 'groupon_ing' ? '邀请拼团' : '拼团详情' }}
</button> </button>
@ -402,7 +403,7 @@
status: tabMaps[state.currentTab].value, status: tabMaps[state.currentTab].value,
pageSize: list_rows, pageSize: list_rows,
pageNo: page, pageNo: page,
commentStatus: tabMaps[state.currentTab].value==30?false:null commentStatus: tabMaps[state.currentTab].value == 30 ? false : null
}); });
state.error = res.code; state.error = res.code;
if (res.code === 0) { if (res.code === 0) {
@ -430,7 +431,7 @@
// //
function loadmore() { function loadmore() {
if (state.loadStatus !== 'noMore') { if (state.loadStatus !== 'noMore') {
getOrderList(parseInt((state.pagination.data.length/5)+1)); getOrderList(parseInt((state.pagination.data.length / 5) + 1));
} }
} }

View File

@ -1,153 +1,147 @@
<template> <template>
<s-layout title="收货地址" :bgStyle="{ color: '#FFF' }"> <s-layout title="收货地址" :bgStyle="{ color: '#FFF' }">
<view v-if="state.list.length"> <view v-if="state.list.length">
<s-address-item <s-address-item hasBorderBottom v-for="item in state.list" :key="item.id" :item="item"
hasBorderBottom @tap="onSelect(item)">
v-for="item in state.list" </s-address-item>
:key="item.id" </view>
:item="item"
@tap="onSelect(item)"
>
</s-address-item>
</view>
<su-fixed bottom placeholder> <su-fixed bottom placeholder>
<view class="footer-box ss-flex ss-row-between ss-p-20"> <view class="footer-box ss-flex ss-row-between ss-p-20">
<!-- 微信小程序和微信H5 --> <!-- 微信小程序和微信H5 -->
<button <button v-if="['WechatMiniProgram', 'WechatOfficialAccount'].includes(sheep.$platform.name)"
v-if="['WechatMiniProgram', 'WechatOfficialAccount'].includes(sheep.$platform.name)" @tap="importWechatAddress"
@tap="importWechatAddress" class="border ss-reset-button sync-wxaddress ss-m-20 ss-flex ss-row-center ss-col-center">
class="border ss-reset-button sync-wxaddress ss-m-20 ss-flex ss-row-center ss-col-center" <text class="cicon-weixin ss-p-r-10" style="color: #09bb07; font-size: 40rpx"></text>
> 导入微信地址
<text class="cicon-weixin ss-p-r-10" style="color: #09bb07; font-size: 40rpx"></text> </button>
导入微信地址 <button class="add-btn ss-reset-button ui-Shadow-Main"
</button> @tap="sheep.$router.go('/pages/user/address/edit')">
<button 新增收货地址
class="add-btn ss-reset-button ui-Shadow-Main" </button>
@tap="sheep.$router.go('/pages/user/address/edit')" </view>
> </su-fixed>
新增收货地址 <s-empty v-if="state.list.length === 0 && !state.loading" text="暂无收货地址" icon="/static/data-empty.png" />
</button> </s-layout>
</view>
</su-fixed>
<s-empty
v-if="state.list.length === 0 && !state.loading"
text="暂无收货地址"
icon="/static/data-empty.png"
/>
</s-layout>
</template> </template>
<script setup> <script setup>
import { reactive, onBeforeMount } from 'vue'; import {
import { onShow } from '@dcloudio/uni-app'; reactive,
import sheep from '@/sheep'; onBeforeMount
import { isEmpty } from 'lodash'; } from 'vue';
import {
onShow
} from '@dcloudio/uni-app';
import sheep from '@/sheep';
import {
isEmpty
} from 'lodash';
const state = reactive({ const state = reactive({
list: [], list: [],
loading: true, loading: true,
}); });
// //
const onSelect = (addressInfo) => { const onSelect = (addressInfo) => {
uni.$emit('SELECT_ADDRESS', { uni.$emit('SELECT_ADDRESS', {
addressInfo, addressInfo,
}); });
sheep.$router.back(); sheep.$router.back();
}; };
// //
function importWechatAddress() { function importWechatAddress() {
let wechatAddress = {}; let wechatAddress = {};
// #ifdef MP // #ifdef MP
uni.chooseAddress({ uni.chooseAddress({
success: (res) => { success: (res) => {
wechatAddress = { wechatAddress = {
consignee: res.userName, consignee: res.userName,
mobile: res.telNumber, mobile: res.telNumber,
province_name: res.provinceName, province_name: res.provinceName,
city_name: res.cityName, city_name: res.cityName,
district_name: res.countyName, district_name: res.countyName,
address: res.detailInfo, address: res.detailInfo,
region: '', region: '',
is_default: false, is_default: false,
}; };
if (!isEmpty(wechatAddress)) { if (!isEmpty(wechatAddress)) {
sheep.$router.go('/pages/user/address/edit', { sheep.$router.go('/pages/user/address/edit', {
data: JSON.stringify(wechatAddress), data: JSON.stringify(wechatAddress),
}); });
} }
}, },
fail: (err) => { fail: (err) => {
console.log('%cuni.chooseAddress,调用失败', 'color:green;background:yellow'); console.log('%cuni.chooseAddress,调用失败', 'color:green;background:yellow');
}, },
}); });
// #endif // #endif
// #ifdef H5 // #ifdef H5
sheep.$platform.useProvider('wechat').jssdk.openAddress({ sheep.$platform.useProvider('wechat').jssdk.openAddress({
success: (res) => { success: (res) => {
wechatAddress = { wechatAddress = {
consignee: res.userName, consignee: res.userName,
mobile: res.telNumber, mobile: res.telNumber,
province_name: res.provinceName, province_name: res.provinceName,
city_name: res.cityName, city_name: res.cityName,
district_name: res.countryName, district_name: res.countryName,
address: res.detailInfo, address: res.detailInfo,
region: '', region: '',
is_default: false, is_default: false,
}; };
if (!isEmpty(wechatAddress)) { if (!isEmpty(wechatAddress)) {
sheep.$router.go('/pages/user/address/edit', { sheep.$router.go('/pages/user/address/edit', {
data: JSON.stringify(wechatAddress), data: JSON.stringify(wechatAddress),
}); });
} }
}, },
}); });
// #endif // #endif
} }
onShow(async () => { onShow(async () => {
state.list = (await sheep.$api.user.address.list()).data; state.list = (await sheep.$api.user.address.list()).data;
state.loading = false; state.loading = false;
}); });
onBeforeMount(() => { onBeforeMount(() => {
if (!!uni.getStorageSync('areaData')) { if (!!uni.getStorageSync('areaData')) {
return; return;
} }
// //
sheep.$api.data.area().then((res) => { sheep.$api.data.area().then((res) => {
if (res.error === 0) { if (res.error === 0) {
uni.setStorageSync('areaData', res.data); uni.setStorageSync('areaData', res.data);
} }
}); });
}); });
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.footer-box { .footer-box {
.add-btn { .add-btn {
flex: 1; flex: 1;
background: linear-gradient(90deg, var(--ui-BG-Main), var(--ui-BG-Main-gradient)); background: linear-gradient(90deg, var(--ui-BG-Main), var(--ui-BG-Main-gradient));
border-radius: 80rpx; border-radius: 80rpx;
font-size: 30rpx; font-size: 30rpx;
font-weight: 500; font-weight: 500;
line-height: 80rpx; line-height: 80rpx;
color: $white; color: $white;
position: relative; position: relative;
z-index: 1; z-index: 1;
} }
.sync-wxaddress { .sync-wxaddress {
flex: 1; flex: 1;
line-height: 80rpx; line-height: 80rpx;
background: $white; background: $white;
border-radius: 80rpx; border-radius: 80rpx;
font-size: 30rpx; font-size: 30rpx;
font-weight: 500; font-weight: 500;
color: $dark-6; color: $dark-6;
margin-right: 18rpx; margin-right: 18rpx;
} }
} }
</style> </style>

View File

@ -20,7 +20,7 @@
<su-sticky> <su-sticky>
<!-- 统计 --> <!-- 统计 -->
<view class="filter-box ss-p-x-30 ss-flex ss-col-center ss-row-between"> <view class="filter-box ss-p-x-30 ss-flex ss-col-center ss-row-between">
<!-- <uni-datetime-picker v-model="state.data" type="daterange" @change="onChangeTime" :end="state.today"> <!-- <uni-datetime-picker v-model="state.data" type="daterange" @change="onChangeTime" :end="state.today">
<button class="ss-reset-button date-btn"> <button class="ss-reset-button date-btn">
<text>{{ dateFilterText }}</text> <text>{{ dateFilterText }}</text>
<text class="cicon-drop-down ss-seldate-icon"></text> <text class="cicon-drop-down ss-seldate-icon"></text>
@ -28,9 +28,9 @@
</uni-datetime-picker> --> </uni-datetime-picker> -->
<view class="total-box"> <view class="total-box">
<!-- state.pagination.income.toFixed(2) --> <!-- state.pagination.income.toFixed(2) -->
<view class="ss-m-b-10">总收入{{ }}</view> <!-- <view class="ss-m-b-10">总收入{{ }}</view>
<view>总支出{{ }}</view> <view>总支出{{ }}</view> -->
<!-- (-state.pagination.expense).toFixed(2) --> <!-- (-state.pagination.expense).toFixed(2) -->
</view> </view>
</view> </view>
@ -45,7 +45,8 @@
<!-- <text class="title ss-line-1">{{ item.event_text }}{{ item.memo ? '-' + item.memo : '' }}</text> --> <!-- <text class="title ss-line-1">{{ item.event_text }}{{ item.memo ? '-' + item.memo : '' }}</text> -->
<text class="title ss-line-1">{{ item.title }}</text> <text class="title ss-line-1">{{ item.title }}</text>
<view class="money"> <view class="money">
<text v-if="(item.amount >= 0||item.price>=0)" class="add">+{{ item.amount||item.price }}</text> <text v-if="(item.amount >= 0||item.price>=0)"
class="add">+{{ item.amount||item.price }}</text>
<text v-else class="minus">{{ item.price }}</text> <text v-else class="minus">{{ item.price }}</text>
</view> </view>
</view> </view>
@ -133,7 +134,7 @@
income: res.data.income, income: res.data.income,
expense: res.data.expense, expense: res.data.expense,
}; };
console.log('交易数据',state.pagination) console.log('交易数据', state.pagination)
if (state.pagination.current_page < state.pagination.last_page) { if (state.pagination.current_page < state.pagination.last_page) {
state.loadStatus = 'more'; state.loadStatus = 'more';
} else { } else {

View File

@ -1,281 +1,279 @@
<!-- 页面 --> <!-- 页面 -->
<template> <template>
<s-layout class="wallet-wrap" title="我的积分" navbar="inner"> <s-layout class="wallet-wrap" title="我的积分" navbar="inner">
<view <view class="header-box ss-flex ss-flex-col ss-row-center ss-col-center" :style="[
class="header-box ss-flex ss-flex-col ss-row-center ss-col-center"
:style="[
{ {
marginTop: '-' + Number(statusBarHeight + 88) + 'rpx', marginTop: '-' + Number(statusBarHeight + 88) + 'rpx',
paddingTop: Number(statusBarHeight + 88) + 'rpx', paddingTop: Number(statusBarHeight + 88) + 'rpx',
}, },
]" ]">
> <view class="header-bg">
<view class="header-bg"><view class="bg"></view></view> <view class="bg"></view>
<view class="score-box ss-flex-col ss-row-center ss-col-center"> </view>
<view class="ss-m-b-30"> <view class="score-box ss-flex-col ss-row-center ss-col-center">
<text class="all-title ss-m-r-8">当前积分</text> <view class="ss-m-b-30">
<!-- <text class="cicon-help-o"></text> --> <text class="all-title ss-m-r-8">当前积分</text>
</view> <!-- <text class="cicon-help-o"></text> -->
<text class="all-num">{{ userInfo.score || 0 }}</text> </view>
</view> <text class="all-num">{{ userInfo.point || 0 }}</text>
</view> </view>
<!-- tab --> </view>
<su-sticky :customNavHeight="sys_navBar"> <!-- tab -->
<!-- 统计 --> <su-sticky :customNavHeight="sys_navBar">
<view class="filter-box ss-p-x-30 ss-flex ss-col-center ss-row-between"> <!-- 统计 -->
<uni-datetime-picker v-model="state.data" type="daterange" @change="onChangeTime" :end="state.today"> <!-- <view class="filter-box ss-p-x-30 ss-flex ss-col-center ss-row-between">
<button class="ss-reset-button date-btn"> <uni-datetime-picker v-model="state.data" type="daterange" @change="onChangeTime" :end="state.today">
<text>{{ dateFilterText }}</text> <button class="ss-reset-button date-btn">
<text class="cicon-drop-down ss-seldate-icon"></text> <text>{{ dateFilterText }}</text>
</button> <text class="cicon-drop-down ss-seldate-icon"></text>
</uni-datetime-picker> </button>
</uni-datetime-picker>
<view class="total-box"> <view class="total-box">
<view class="ss-m-b-10">总收入{{ state.pagination.income }}</view> <view class="ss-m-b-10">总收入{{ state.pagination.income }}</view>
<view>总支出{{ -state.pagination.expense }}</view> <view>总支出{{ -state.pagination.expense }}</view>
</view> </view>
</view> </view> -->
<su-tabs <su-tabs :list="tabMaps" @change="onChange" :scrollable="false" :current="state.currentTab"></su-tabs>
:list="tabMaps" </su-sticky>
@change="onChange" <!-- list -->
:scrollable="false" <view class="list-box">
:current="state.currentTab" <view v-if="state.pagination.total > 0">
></su-tabs> <view class="list-item ss-flex ss-col-center ss-row-between" v-for="item in state.pagination.data"
</su-sticky> :key="item.id">
<!-- list --> <view class="ss-flex-col">
<view class="list-box"> <view class="name">{{ item.title }}{{ item.description ? '-' + item.description : '' }}</view>
<view v-if="state.pagination.total > 0"> <view class="time">{{ sheep.$helper.timeFormat(item.createTime, 'yyyy-mm-dd hh:MM:ss')}}</view>
<view </view>
class="list-item ss-flex ss-col-center ss-row-between" <view class="add" v-if="item.point > 0">+{{ parseInt(item.point) }}</view>
v-for="item in state.pagination.data" <view class="minus" v-else>{{ parseInt(item.point) }}</view>
:key="item.id" </view>
> </view>
<view class="ss-flex-col"> <s-empty v-else text="暂无数据" icon="/static/data-empty.png" />
<view class="name">{{ item.event_text }}{{ item.memo ? '-' + item.memo : '' }}</view> </view>
<view class="time">{{ item.create_time }}</view>
</view>
<view class="add" v-if="item.amount > 0">+{{ parseInt(item.amount) }}</view>
<view class="minus" v-else>{{ parseInt(item.amount) }}</view>
</view>
</view>
<s-empty v-else text="暂无数据" icon="/static/data-empty.png" />
</view>
<uni-load-more <uni-load-more v-if="state.pagination.total > 0" :status="state.loadStatus" :content-text="{
v-if="state.pagination.total > 0"
:status="state.loadStatus"
:content-text="{
contentdown: '上拉加载更多', contentdown: '上拉加载更多',
}" }" @tap="onLoadMore" />
@tap="onLoadMore" </s-layout>
/>
</s-layout>
</template> </template>
<script setup> <script setup>
import sheep from '@/sheep'; import sheep from '@/sheep';
import { onLoad, onReachBottom } from '@dcloudio/uni-app'; import {
import { computed, reactive } from 'vue'; onLoad,
import _ from 'lodash'; onReachBottom
import dayjs from 'dayjs'; } from '@dcloudio/uni-app';
import { onPageScroll } from '@dcloudio/uni-app'; import {
onPageScroll(() => {}); computed,
reactive
} from 'vue';
import _ from 'lodash';
import dayjs from 'dayjs';
import {
onPageScroll
} from '@dcloudio/uni-app';
onPageScroll(() => {});
const statusBarHeight = sheep.$platform.device.statusBarHeight * 2; const statusBarHeight = sheep.$platform.device.statusBarHeight * 2;
const userInfo = computed(() => sheep.$store('user').userInfo); const userInfo = computed(() => sheep.$store('user').userInfo);
const sys_navBar = sheep.$platform.navbar; const sys_navBar = sheep.$platform.navbar;
const pagination = { const pagination = {
data: [], data: [],
current_page: 1, current_page: 1,
total: 1, total: 1,
last_page: 1, last_page: 1,
expense: 0, expense: 0,
income: 0, income: 0,
}; };
const state = reactive({ const state = reactive({
currentTab: 0, currentTab: 0,
pagination, pagination,
loadStatus: '', loadStatus: '',
date: [], date: [],
today:'', today: '',
}); });
const tabMaps = [ const tabMaps = [{
{ name: '全部',
name: '全部', value: 'all',
value: 'all', },
},
{ // {
name: '收入', // name: '',
value: 'income', // value: 'income',
}, // },
{ // {
name: '支出', // name: '',
value: 'expense', // value: 'expense',
}, // },
]; ];
const dateFilterText = computed(() => { const dateFilterText = computed(() => {
if (state.date[0] === state.date[1]) { if (state.date[0] === state.date[1]) {
return state.date[0]; return state.date[0];
} else { } else {
return state.date.join('~'); return state.date.join('~');
} }
}); });
async function getLogList(page = 1, list_rows = 8) { async function getLogList(page = 1, list_rows = 8) {
state.loadStatus = 'loading'; pagination.current_page = page;
let res = await sheep.$api.user.wallet.log({ state.loadStatus = 'loading';
type: 'score', let res = await sheep.$api.user.wallet.log2({
list_rows, // type: 'score',
page, pageSize: list_rows,
tab: tabMaps[state.currentTab].value, pageNo: page,
date: appendTimeHMS(state.date), // tab: tabMaps[state.currentTab].value,
}); // date: appendTimeHMS(state.date),
if (res.error === 0) { });
let list = _.concat(state.pagination.data, res.data.list.data); console.log(res, '优惠券列表')
state.pagination = { if (res.code === 0) {
...res.data.list, let list = _.concat(state.pagination.data, res.data.list);
data: list, console.log(list, '处理后数据')
income: res.data.income, state.pagination = {
expense: res.data.expense, total: res.data.total,
}; ...res.data.list,
if (state.pagination.current_page < state.pagination.last_page) { data: list,
state.loadStatus = 'more'; // income: res.data.income,
} else { // expense: res.data.expense,
state.loadStatus = 'noMore'; };
} // if (state.pagination.current_page < state.pagination.last_page) {
} state.loadStatus = 'more';
} // } else {
onLoad(async (options) => { // state.loadStatus = 'noMore';
state.today = dayjs().format('YYYY-MM-DD'); // }
state.date = [state.today, state.today]; }
getLogList(); }
}); onLoad(async (options) => {
state.today = dayjs().format('YYYY-MM-DD');
state.date = [state.today, state.today];
getLogList();
});
function onChange(e) { function onChange(e) {
state.pagination = pagination; state.pagination = pagination;
state.currentTab = e.index; state.currentTab = e.index;
getLogList(); getLogList();
} }
function onChangeTime(e) {
state.date[0] = e[0];
state.date[1] = e[e.length - 1];
state.pagination = pagination;
getLogList();
}
function appendTimeHMS(arr) { function onChangeTime(e) {
return [arr[0] + ' 00:00:00', arr[1] + ' 23:59:59']; state.date[0] = e[0];
} state.date[1] = e[e.length - 1];
state.pagination = pagination;
getLogList();
}
function onLoadMore() { function appendTimeHMS(arr) {
if (state.loadStatus !== 'noMore') { return [arr[0] + ' 00:00:00', arr[1] + ' 23:59:59'];
getLogList(state.pagination.current_page + 1); }
}
} function onLoadMore() {
onReachBottom(() => { // if (state.loadStatus !== 'noMore') {
onLoadMore(); getLogList(pagination.current_page + 1);
}); // }
}
onReachBottom(() => {
onLoadMore();
});
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.header-box { .header-box {
width: 100%; width: 100%;
background: linear-gradient(180deg, var(--ui-BG-Main) 0%, var(--ui-BG-Main-gradient) 100%) background: linear-gradient(180deg, var(--ui-BG-Main) 0%, var(--ui-BG-Main-gradient) 100%) no-repeat;
no-repeat; background-size: 750rpx 100%;
background-size: 750rpx 100%; padding: 0 0 120rpx 0;
padding: 0 0 120rpx 0; box-sizing: border-box;
box-sizing: border-box;
.score-box { .score-box {
height: 100%; height: 100%;
.all-num { .all-num {
font-size: 50rpx; font-size: 50rpx;
font-weight: bold; font-weight: bold;
color: #fff; color: #fff;
font-family: OPPOSANS; font-family: OPPOSANS;
} }
.all-title { .all-title {
font-size: 26rpx; font-size: 26rpx;
font-weight: 500; font-weight: 500;
color: #fff; color: #fff;
} }
.cicon-help-o { .cicon-help-o {
color: #fff; color: #fff;
font-size: 28rpx; font-size: 28rpx;
} }
} }
} }
//
.filter-box {
height: 114rpx;
background-color: $bg-page;
.total-box { //
font-size: 24rpx; .filter-box {
font-weight: 500; height: 114rpx;
color: $dark-9; background-color: $bg-page;
}
.date-btn { .total-box {
background-color: $white; font-size: 24rpx;
line-height: 54rpx; font-weight: 500;
border-radius: 27rpx; color: $dark-9;
padding: 0 20rpx; }
font-size: 24rpx;
font-weight: 500;
color: $dark-6;
.ss-seldate-icon { .date-btn {
font-size: 50rpx; background-color: $white;
color: $dark-9; line-height: 54rpx;
} border-radius: 27rpx;
} padding: 0 20rpx;
} font-size: 24rpx;
font-weight: 500;
color: $dark-6;
.list-box { .ss-seldate-icon {
.list-item { font-size: 50rpx;
background: #fff; color: $dark-9;
border-bottom: 1rpx solid #dfdfdf; }
padding: 30rpx; }
}
.name { .list-box {
font-size: 28rpx; .list-item {
background: #fff;
border-bottom: 1rpx solid #dfdfdf;
padding: 30rpx;
font-weight: 500; .name {
color: rgba(102, 102, 102, 1); font-size: 28rpx;
line-height: 28rpx;
margin-bottom: 20rpx;
}
.time { font-weight: 500;
font-size: 24rpx; color: rgba(102, 102, 102, 1);
line-height: 28rpx;
margin-bottom: 20rpx;
}
font-weight: 500; .time {
color: rgba(196, 196, 196, 1); font-size: 24rpx;
line-height: 24px;
}
.add { font-weight: 500;
font-size: 30rpx; color: rgba(196, 196, 196, 1);
line-height: 24px;
}
font-weight: 500; .add {
color: #e6b873; font-size: 30rpx;
}
.minus { font-weight: 500;
font-size: 30rpx; color: #e6b873;
}
font-weight: 500; .minus {
color: $dark-3; font-size: 30rpx;
}
} font-weight: 500;
} color: $dark-3;
</style> }
}
}
</style>

View File

@ -2,41 +2,41 @@ import request from '@/sheep/request';
import request2 from '@/sheep/request2'; import request2 from '@/sheep/request2';
export default { export default {
list: (data) => list: (data) =>
request2({ request2({
url: 'trade/cart/list', url: 'trade/cart/list',
method: 'GET', method: 'GET',
custom: { custom: {
showLoading: false, showLoading: false,
auth: true, auth: true,
}, },
}), }),
append: (data) => append: (data) =>
request({ request({
url: 'cart', url: 'cart',
method: 'POST', method: 'POST',
custom: { custom: {
showSuccess: true, showSuccess: true,
successMsg: '已添加到购物车~', successMsg: '已添加到购物车~',
}, },
data: { data: {
...data, ...data,
type: 'inc', type: 'inc',
}, },
}), }),
// 删除购物车 // 删除购物车
delete: (ids) => delete: (ids) =>
request2({ request2({
url: 'trade/cart/delete?ids=' + ids, url: 'trade/cart/delete?ids=' + ids,
method: 'DELETE', method: 'DELETE',
}), }),
update: (data) => update: (data) =>
request2({ request2({
url: 'trade/cart/update-count', url: 'trade/cart/update-count',
method: 'PUT', method: 'PUT',
data: { data: {
...data, ...data,
type: 'cover', type: 'cover',
}, },
}), }),
}; };

View File

@ -1,38 +1,45 @@
import request from '@/sheep/request'; import request from '@/sheep/request';
import request2 from '@/sheep/request2';
export default { export default {
// 我的拼团 // 我的拼团
list: (params) => list: (params) =>
request({ request({
url: 'coupon', url: 'coupon',
method: 'GET', method: 'GET',
params, params,
custom: { custom: {
showLoading: false, showLoading: false,
}, },
}), }),
userCoupon: (params) => userCoupon: (params) =>
request({ request2({
url: 'user/coupon', url: 'promotion/coupon/page',
method: 'GET', method: 'GET',
params, params,
}), }),
detail: (id, user_coupon_id) => // userCoupon: (params) =>
request({ // request({
url: 'coupon/' + id, // url: 'user/coupon',
method: 'GET', // method: 'GET',
params: { // params,
user_coupon_id, // }),
}, detail: (id, user_coupon_id) =>
}), request({
get: (id) => url: 'coupon/' + id,
request({ method: 'GET',
url: 'coupon/get/' + id, params: {
method: 'POST', user_coupon_id,
}), },
listByGoods: (id) => }),
request({ get: (id) =>
url: 'coupon/listByGoods/' + id, request({
method: 'GET', url: 'coupon/get/' + id,
}), method: 'POST',
}; }),
listByGoods: (id) =>
request({
url: 'coupon/listByGoods/' + id,
method: 'GET',
}),
};

View File

@ -2,148 +2,191 @@ import request from '@/sheep/request';
import request2 from '@/sheep/request2'; import request2 from '@/sheep/request2';
export default { export default {
// 订单详情 // 订单详情
detail: (id,params) => detail: (id, params) =>
request({ request2({
url: 'order/order/' + id, url: 'trade/order/get-detail?id=' + id,
method: 'GET', method: 'GET',
params, params,
}), }),
// 发票详情 // detail: (id, params) =>
invoice: (id) => // request({
request({ // url: 'order/order/' + id,
url: 'order/invoice/' + id, // method: 'GET',
method: 'GET', // params,
}), // }),
// 获取支付结果 // 发票详情
payResult: (id) => invoice: (id) =>
request({ request({
url: 'order/order/' + id, url: 'order/invoice/' + id,
method: 'GET', method: 'GET',
custom: { }),
showLoading: false, // 获取支付结果
}, payResult: (id) =>
}), request({
itemDetail: (id,itemId) => url: 'order/order/' + id,
request({ method: 'GET',
url: 'order/order/itemDetail/'+ id + '/' + itemId, custom: {
method: 'GET', showLoading: false,
custom: { },
showLoading: false, }),
}, itemDetail: (id, itemId) =>
}), request({
// 订单列表 url: 'order/order/itemDetail/' + id + '/' + itemId,
list: (params) => method: 'GET',
request2({ custom: {
url: 'trade/order/page', showLoading: false,
method: 'GET', },
params, }),
custom: { // 订单列表
showLoading: false, list: (params) =>
}, request2({
}), url: 'trade/order/page',
// list: (params) => method: 'GET',
// request({ params,
// url: 'order/order', custom: {
// method: 'GET', showLoading: false,
// params, },
// custom: { }),
// showLoading: false, // list: (params) =>
// }, // request({
// }), // url: 'order/order',
// 计算订单信息 // method: 'GET',
calc: (data) => // params,
request({ // custom: {
url: 'order/order/calc', // showLoading: false,
method: 'POST', // },
data, // }),
}), // 计算订单信息
// 创建订单 calc: (data) => {
create: (data) => const data2 = {
request({ ...data,
url: 'order/order/create', }
method: 'POST', // 解决 SpringMVC 接受 List<Item> 参数的问题
data, delete data2.items
}), for (let i = 0; i < data.items.length; i++) {
//订单可用优惠券 // data2['items[' + i + '' + '].skuId'] = data.items[i].skuId + '';
coupons: (data) => // data2['items[' + i + '' + '].count'] = data.items[i].count + '';
request({ // data2['items[' + i + '' + '].cartId'] = data.items[i].cartId + '';
url: 'order/order/coupons', data2['items' + `%5B${i}%5D` + '.skuId'] = data.items[i].skuId + '';
method: 'POST', data2['items' + `%5B${i}%5D` + '.count'] = data.items[i].count + '';
data, data2['items' + `%5B${i}%5D` + '.cartId'] = data.items[i].cartId + '';
}), }
// 确认收货 console.log(data2, '对比数据')
confirm: (id) => return request2({
request({ url: 'trade/order/settlement',
url: 'order/order/confirm/' + id, method: 'GET',
method: 'PUT', // data,
}), params: data2
// 评价订单 })
comment: (id, data) => },
request({ // calc: (data) =>
url: 'order/order/comment/' + id, // request({
method: 'POST', // url: 'order/order/calc',
data, // method: 'POST',
}), // data,
// 申请退款 // }),
applyRefund: (id) => // 创建订单
request({ create: (data) =>
url: 'order/order/applyRefund/' + id, request({
method: 'PUT', url: 'order/order/create',
}), method: 'POST',
// 取消订单 data,
cancel: (id) => }),
request({ //订单可用优惠券
url: 'order/order/cancel/' + id, coupons: (data) =>
method: 'PUT', request({
}), url: 'order/order/coupons',
// 删除订单 method: 'POST',
delete: (id) => data,
request({ }),
url: 'order/order/' + id, // 确认收货
method: 'DELETE', confirm: (id) =>
}), request({
// 售后 url: 'order/order/confirm/' + id,
aftersale: { method: 'PUT',
// 申请售后 }),
apply: (data) => // 评价订单
request({ comment: (data) =>
url: 'order/aftersale', request2({
method: 'POST', url: 'trade/order/item/create-comment',
data, method: 'POST',
}), data,
list: (params) => }),
request({ // comment: (id, data) =>
url: 'order/aftersale', // request({
method: 'GET', // url: 'order/order/comment/' + id,
params, // method: 'POST',
custom: { // data,
showLoading: false, // }),
}, // 申请退款
}), applyRefund: (id) =>
//取消售后 request({
cancel: (id) => url: 'order/order/applyRefund/' + id,
request({ method: 'PUT',
url: 'order/aftersale/cancel/' + id, }),
method: 'PUT', // 取消订单
}), cancel: (id) =>
//删除售后单 request({
delete: (id) => url: 'order/order/cancel/' + id,
request({ method: 'PUT',
url: 'order/aftersale/' + id, }),
method: 'DELETE', // 删除订单
}), delete: (id) =>
// 售后详情 request({
detail: (id) => url: 'order/order/' + id,
request({ method: 'DELETE',
url: 'order/aftersale/' + id, }),
method: 'GET', // 售后
}), aftersale: {
}, // 申请售后
//订单包裹 apply: (data) =>
express: (id, orderId) => request({
request({ url: 'order/aftersale',
url: 'order/express/' + id + `${orderId ? '/' + orderId : ''}`, method: 'POST',
method: 'GET', data,
}), }),
}; list: (params) =>
request2({
url: 'trade/after-sale/page',
method: 'GET',
params,
custom: {
showLoading: false,
},
}),
// list: (params) =>
// request({
// url: 'order/aftersale',
// method: 'GET',
// params,
// custom: {
// showLoading: false,
// },
// }),
//取消售后
cancel: (id) =>
request({
url: 'order/aftersale/cancel/' + id,
method: 'PUT',
}),
//删除售后单
delete: (id) =>
request({
url: 'order/aftersale/' + id,
method: 'DELETE',
}),
// 售后详情
detail: (id) =>
request2({
url: 'trade/after-sale/get?id=' + id,
method: 'GET',
}),
},
//订单包裹
express: (id, orderId) =>
request({
url: 'order/express/' + id + `${orderId ? '/' + orderId : ''}`,
method: 'GET',
}),
};

View File

@ -3,6 +3,15 @@ import request2 from '@/sheep/request2';
import $platform from '@/sheep/platform'; import $platform from '@/sheep/platform';
export default { export default {
getUnused: () =>
request2({
url: 'promotion/coupon/get-unused-count',
method: 'GET',
custom: {
showLoading: false,
auth: true,
},
}),
profile: () => profile: () =>
request2({ request2({
url: 'member/user/get', url: 'member/user/get',
@ -187,9 +196,17 @@ export default {
}), }),
address: { address: {
// default: () =>
// request({
// url: 'user/address/default',
// method: 'GET',
// custom: {
// showError: false,
// },
// }),
default: () => default: () =>
request({ request2({
url: 'user/address/default', url: 'member/address/get-default',
method: 'GET', method: 'GET',
custom: { custom: {
showError: false, showError: false,
@ -225,7 +242,7 @@ export default {
// showSuccess: true, // showSuccess: true,
// }, // },
// }), // }),
update: ( data) => update: (data) =>
request2({ request2({
url: 'member/address/update', url: 'member/address/update',
method: 'PUT', method: 'PUT',
@ -325,7 +342,7 @@ export default {
url: 'product/favorite/delete-list', url: 'product/favorite/delete-list',
method: 'DELETE', method: 'DELETE',
data: { data: {
spuIds: id.split(',').map(item=>item*1), spuIds: id.split(',').map(item => item * 1),
// spuIds: id.split(',').join(','), // spuIds: id.split(',').join(','),
}, },
custom: { custom: {
@ -367,18 +384,27 @@ export default {
wallet: { wallet: {
log: (params) => log: (params) =>
request2({ request2({
// url: 'member/point/record/page',
url: 'pay/wallet-transaction/page', url: 'pay/wallet-transaction/page',
method: 'GET', method: 'GET',
params, params,
custom: {}, custom: {},
}), }),
// log: (params) => log2: (params) =>
// request({ request2({
// url: '/user/api/walletLog', url: 'member/point/record/page',
// method: 'GET', // url: 'pay/wallet-transaction/page',
// params, method: 'GET',
// custom: {}, params,
// }), custom: {},
}),
// log: (params) =>
// request({
// url: '/user/api/walletLog',
// method: 'GET',
// params,
// custom: {},
// }),
}, },
account: { account: {
info: (params) => info: (params) =>

View File

@ -1,80 +1,78 @@
<template> <template>
<view class="ss-coupon-menu-wrap ss-flex ss-col-center"> <view class="ss-coupon-menu-wrap ss-flex ss-col-center">
<view <view class="menu-item ss-flex-col ss-row-center ss-col-center" v-for="item in props.list" :key="item.title"
class="menu-item ss-flex-col ss-row-center ss-col-center" @tap="sheep.$router.go(item.path, { type: item.type })"
v-for="item in props.list" :class="item.type === 'all' ? 'menu-wallet' : 'ss-flex-1'">
:key="item.title" <image class="item-icon" :src="sheep.$url.static(item.icon)" mode="aspectFit"></image>
@tap="sheep.$router.go(item.path, { type: item.type })" <view class="menu-title ss-m-t-28">{{ item.title }}</view>
:class="item.type === 'all' ? 'menu-wallet' : 'ss-flex-1'" </view>
> </view>
<image class="item-icon" :src="sheep.$url.static(item.icon)" mode="aspectFit"></image>
<view class="menu-title ss-m-t-28">{{ item.title }}</view>
</view>
</view>
</template> </template>
<script setup> <script setup>
/** /**
* 装修组件 - 优惠券菜单 * 装修组件 - 优惠券菜单
*/ */
import sheep from '@/sheep'; import sheep from '@/sheep';
// //
const props = defineProps({ const props = defineProps({
list: { list: {
type: Array, type: Array,
default() { default () {
return [ return [{
{ title: '已领取',
title: '已领取', value: '0',
value: '0', icon: '/static/img/shop/order/nouse_coupon.png',
icon: '/static/img/shop/order/nouse_coupon.png', path: '/pages/coupon/list',
path: '/pages/coupon/list', type: 'geted',
type: 'geted', },
}, {
{ title: '已使用',
title: '已使用', value: '0',
value: '0', icon: '/static/img/shop/order/useend_coupon.png',
icon: '/static/img/shop/order/useend_coupon.png', path: '/pages/coupon/list',
path: '/pages/coupon/list', type: 'used',
type: 'used', },
}, {
{ title: '已失效',
title: '已失效', value: '0',
value: '0', icon: '/static/img/shop/order/out_coupon.png',
icon: '/static/img/shop/order/out_coupon.png', path: '/pages/coupon/list',
path: '/pages/coupon/list', type: 'expired',
type: 'expired', },
}, // {
{ // title: '',
title: '领券中心', // value: '0',
value: '0', // icon: '/static/img/shop/order/all_coupon.png',
icon: '/static/img/shop/order/all_coupon.png', // path: '/pages/coupon/list',
path: '/pages/coupon/list', // type: 'all',
type: 'all', // },
}, ];
]; },
}, },
}, });
});
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.ss-coupon-menu-wrap { .ss-coupon-menu-wrap {
.menu-item { .menu-item {
height: 160rpx; height: 160rpx;
.menu-title {
font-size: 24rpx; .menu-title {
line-height: 24rpx; font-size: 24rpx;
color: #333333; line-height: 24rpx;
} color: #333333;
.item-icon { }
width: 44rpx;
height: 44rpx; .item-icon {
} width: 44rpx;
} height: 44rpx;
.menu-wallet { }
width: 144rpx; }
}
} .menu-wallet {
</style> width: 144rpx;
}
}
</style>

View File

@ -1,192 +1,195 @@
<template> <template>
<view class="ss-m-20" :style="{ opacity: disabled ? '0.5' : '1' }"> <view class="ss-m-20" :style="{ opacity: disabled ? '0.5' : '1' }">
<view class="content"> <view class="content">
<view <!-- <view
class="tag ss-flex ss-row-center" class="tag ss-flex ss-row-center"
:class=" :class="
data.status == 'expired' || data.status == 'used' ? 'disabled-bg-color' : 'info-bg-color' data.status == 'expired' || data.status == 'used' ? 'disabled-bg-color' : 'info-bg-color'
" "
>{{ data.type_text }}</view >{{ data.type_text }}</view
> > -->
<view class="title ss-m-x-30 ss-p-t-18"> <view class="title ss-m-x-30 ss-p-t-18">
<view class="ss-flex ss-row-between"> <view class="ss-flex ss-row-between">
<view <view class="value-text ss-flex-1 ss-m-r-10" :class="
class="value-text ss-flex-1 ss-m-r-10"
:class="
data.status == 'expired' || data.status == 'used' ? 'disabled-color' : 'info-color' data.status == 'expired' || data.status == 'used' ? 'disabled-color' : 'info-color'
" ">{{ data.name }}</view>
>{{ data.name }}</view <view>
> <view class="ss-flex ss-col-bottom" :class="
<view>
<view
class="ss-flex ss-col-bottom"
:class="
data.status != 'expired' && data.status != 'used' ? 'price-text' : 'disabled-color' data.status != 'expired' && data.status != 'used' ? 'price-text' : 'disabled-color'
" ">
> <view class="value-reduce ss-m-b-10" v-if="data.type === 'reduce'"></view>
<view class="value-reduce ss-m-b-10" v-if="data.type === 'reduce'"></view> <view class="value-price">{{ data.amount }}</view>
<view class="value-price">{{ data.amount }}</view> <view class="value-discount ss-m-b-10 ss-m-l-4" v-if="data.type === 'discount'"></view>
<view class="value-discount ss-m-b-10 ss-m-l-4" v-if="data.type === 'discount'" </view>
></view </view>
> </view>
</view> <view class="ss-flex ss-row-between ss-m-t-16">
</view> <view class="sellby-text" :class="
</view>
<view class="ss-flex ss-row-between ss-m-t-16">
<view
class="sellby-text"
:class="
data.status == 'expired' || data.status == 'used' data.status == 'expired' || data.status == 'used'
? 'disabled-color' ? 'disabled-color'
: 'subtitle-color' : 'subtitle-color'
" ">
> {{'有效期:' + data.use_start_time.substring(0, 11) }}
{{ {{ data.use_end_time.substring(0, 11) }}
<!-- {{
type === 'user' type === 'user'
? '有效期:' + data.use_start_time.substring(0, 11) ? '有效期:' + data.use_start_time.substring(0, 11)
: '领取时间:' + data.get_start_time.substring(0, 11) : '领取时间:' + data.get_start_time.substring(0, 11)
}} }}
{{ {{
type === 'user' type === 'user'
? data.use_end_time.substring(0, 11) ? data.use_end_time.substring(0, 11)
: data.get_end_time.substring(0, 11) : data.get_end_time.substring(0, 11)
}} }} -->
</view> </view>
<view <view class="value-enough" :class="
class="value-enough"
:class="
data.status == 'expired' || data.status == 'used' data.status == 'expired' || data.status == 'used'
? 'disabled-color' ? 'disabled-color'
: 'subtitle-color' : 'subtitle-color'
" ">{{ data.enough }}可用</view>
>{{ data.enough }}可用</view </view>
> </view>
</view> </view>
</view>
</view>
<view class="desc ss-flex ss-row-between"> <view class="desc ss-flex ss-row-between">
<view> <view>
<view class="desc-title"> <view class="desc-title">
{{ data.description }} {{ data.description }}
</view> </view>
<view> <view>
<slot name="reason"> <slot name="reason">
</slot> </slot>
</view> </view>
</view> </view>
<view> <view>
<slot></slot> <slot></slot>
</view> </view>
</view> </view>
</view> </view>
</template> </template>
<script setup> <script setup>
import { reactive } from 'vue'; import {
import sheep from '@/sheep'; reactive
const state = reactive({ } from 'vue';
stateMap: { import sheep from '@/sheep';
0: '立即领取', const state = reactive({
1: '去使用', stateMap: {
}, 0: '立即领取',
}); 1: '去使用',
// },
const props = defineProps({ });
data: { //
type: Object, const props = defineProps({
default: {}, data: {
}, type: Object,
disabled: { default: {},
type: Boolean, },
default: false, disabled: {
}, type: Boolean,
type: { default: false,
type: String, },
default: 'coupon', type: {
}, type: String,
}); default: 'coupon',
},
});
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.info-bg-color { .info-bg-color {
background: linear-gradient(90deg, var(--ui-BG-Main), var(--ui-BG-Main-gradient)); background: linear-gradient(90deg, var(--ui-BG-Main), var(--ui-BG-Main-gradient));
} }
.disabled-bg-color {
background: #999;
}
.info-color {
color: #333;
}
.subtitle-color {
color: #666;
}
.disabled-color {
color: #999;
}
.content {
width: 100%;
background: #fff;
border-radius: 20rpx 20rpx 0 0;
-webkit-mask: radial-gradient(circle at 12rpx 100%, #0000 12rpx, red 0) -12rpx;
box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.04);
.tag { .disabled-bg-color {
width: 100rpx; background: #999;
}
color: #fff; .info-color {
height: 40rpx; color: #333;
font-size: 24rpx; }
border-radius: 20rpx 0 20rpx 0;
} .subtitle-color {
.title { color: #666;
padding-bottom: 22rpx; }
border-bottom: 2rpx dashed #d3d3d3;
.value-text { .disabled-color {
font-size: 32rpx; color: #999;
font-weight: 600; }
}
.sellby-text { .content {
font-size: 24rpx; width: 100%;
font-weight: 400; background: #fff;
} border-radius: 20rpx 20rpx 0 0;
.value-price { -webkit-mask: radial-gradient(circle at 12rpx 100%, #0000 12rpx, red 0) -12rpx;
font-size: 64rpx; box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.04);
font-weight: 500;
line-height: normal; .tag {
font-family: OPPOSANS; width: 100rpx;
}
.value-reduce { color: #fff;
line-height: normal; height: 40rpx;
font-size: 32rpx; font-size: 24rpx;
} border-radius: 20rpx 0 20rpx 0;
.value-discount { }
line-height: normal;
font-size: 28rpx; .title {
} padding-bottom: 22rpx;
.value-enough { border-bottom: 2rpx dashed #d3d3d3;
font-size: 24rpx;
font-weight: 400; .value-text {
font-family: OPPOSANS; font-size: 32rpx;
} font-weight: 600;
} }
}
.desc { .sellby-text {
width: 100%; font-size: 24rpx;
background: #fff; font-weight: 400;
-webkit-mask: radial-gradient(circle at 12rpx 0%, #0000 12rpx, red 0) -12rpx; }
box-shadow: rgba(#000, 0.1);
box-sizing: border-box; .value-price {
padding: 24rpx 30rpx; font-size: 64rpx;
box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.04); font-weight: 500;
border-radius: 0 0 20rpx 20rpx; line-height: normal;
.desc-title { font-family: OPPOSANS;
font-size: 24rpx; }
color: #999;
font-weight: 400; .value-reduce {
} line-height: normal;
} font-size: 32rpx;
.price-text { }
color: #ff0000;
} .value-discount {
</style> line-height: normal;
font-size: 28rpx;
}
.value-enough {
font-size: 24rpx;
font-weight: 400;
font-family: OPPOSANS;
}
}
}
.desc {
width: 100%;
background: #fff;
-webkit-mask: radial-gradient(circle at 12rpx 0%, #0000 12rpx, red 0) -12rpx;
box-shadow: rgba(#000, 0.1);
box-sizing: border-box;
padding: 24rpx 30rpx;
box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.04);
border-radius: 0 0 20rpx 20rpx;
.desc-title {
font-size: 24rpx;
color: #999;
font-weight: 400;
}
}
.price-text {
color: #ff0000;
}
</style>

View File

@ -1,476 +1,458 @@
<template> <template>
<!-- 规格弹窗 --> <!-- 规格弹窗 -->
<su-popup :show="show" round="10" @close="emits('close')"> <su-popup :show="show" round="10" @close="emits('close')">
<view class="ss-modal-box bg-white ss-flex-col"> <view class="ss-modal-box bg-white ss-flex-col">
<view class="modal-header ss-flex ss-col-center"> <view class="modal-header ss-flex ss-col-center">
<view class="header-left ss-m-r-30"> <view class="header-left ss-m-r-30">
<image <image class="sku-image" :src="sheep.$url.cdn(state.selectedSkuPrice.image || goodsInfo.image)"
class="sku-image" mode="aspectFill"></image>
:src="sheep.$url.cdn(state.selectedSkuPrice.image || goodsInfo.image)" </view>
mode="aspectFill" <view class="header-right ss-flex-col ss-row-between ss-flex-1">
></image> <view class="goods-title ss-line-2">{{ goodsInfo.title }}</view>
</view> <view class="header-right-bottom ss-flex ss-col-center ss-row-between">
<view class="header-right ss-flex-col ss-row-between ss-flex-1"> <view class="ss-flex">
<view class="goods-title ss-line-2">{{ goodsInfo.title }}</view> <view v-if="goodsPrice.price > 0" class="price-text">
<view class="header-right-bottom ss-flex ss-col-center ss-row-between"> {{ goodsPrice.price }}
<view class="ss-flex"> </view>
<view v-if="goodsPrice.price > 0" class="price-text"> <view class="ss-flex">
{{ goodsPrice.price }} <view v-if="goodsPrice.price > 0 && goodsPrice.score > 0" class="score-text ss-m-l-4">+
</view> </view>
<view class="ss-flex"> <image v-if="goodsPrice.score > 0"
<view :src="sheep.$url.static('/static/img/shop/goods/score1.svg')" class="score-img">
v-if="goodsPrice.price > 0 && goodsPrice.score > 0" </image>
class="score-text ss-m-l-4" <view v-if="goodsPrice.score > 0" class="score-text">
>+ {{ goodsPrice.score }}
</view> </view>
<image </view>
v-if="goodsPrice.score > 0" </view>
:src="sheep.$url.static('/static/img/shop/goods/score1.svg')"
class="score-img"
>
</image>
<view v-if="goodsPrice.score > 0" class="score-text">
{{ goodsPrice.score }}
</view>
</view>
</view>
<view class="stock-text ss-m-l-20"> <view class="stock-text ss-m-l-20">
{{ {{
state.selectedSkuPrice.stock state.selectedSkuPrice.stock
? formatStock(goodsInfo.stock_show_type, state.selectedSkuPrice.stock) ? formatStock(goodsInfo.stock_show_type, state.selectedSkuPrice.stock)
: formatStock(goodsInfo.stock_show_type, goodsInfo.stock) : formatStock(goodsInfo.stock_show_type, goodsInfo.stock)
}} }}
</view> </view>
</view> </view>
</view> </view>
</view> </view>
<view class="modal-content ss-flex-1"> <view class="modal-content ss-flex-1">
<scroll-view scroll-y="true" class="modal-content-scroll" @touchmove.stop> <scroll-view scroll-y="true" class="modal-content-scroll" @touchmove.stop>
<view class="sku-item ss-m-b-20" v-for="sku1 in goodsInfo.skus" :key="sku1.id"> <view class="sku-item ss-m-b-20" v-for="sku1 in goodsInfo.skus" :key="sku1.id">
<view class="label-text ss-m-b-20">{{ sku1.name }}</view> <view class="label-text ss-m-b-20">{{ sku1.name }}</view>
<view class="ss-flex ss-col-center ss-flex-wrap"> <view class="ss-flex ss-col-center ss-flex-wrap">
<button <button class="ss-reset-button spec-btn" v-for="sku2 in sku1.children" :class="[
class="ss-reset-button spec-btn"
v-for="sku2 in sku1.children"
:class="[
{ {
'ui-BG-Main-Gradient': state.currentSkuArray[sku2.parent_id] == sku2.id, 'ui-BG-Main-Gradient': state.currentSkuArray[sku2.parent_id] == sku2.id,
}, },
{ {
'disabled-btn': sku2.disabled == true, 'disabled-btn': sku2.disabled == true,
}, },
]" ]" :key="sku2.id" :disabled="sku2.disabled == true" @tap="onSelectSku(sku2.parent_id, sku2.id)">
:key="sku2.id" {{ sku2.name }}
:disabled="sku2.disabled == true" </button>
@tap="onSelectSku(sku2.parent_id, sku2.id)" </view>
> </view>
{{ sku2.name }} <view class="buy-num-box ss-flex ss-col-center ss-row-between ss-m-b-40">
</button> <view class="label-text">购买数量</view>
</view> <su-number-box :min="1" :max="state.selectedSkuPrice.stock" :step="1"
</view> v-model="state.selectedSkuPrice.goods_num" @change="onNumberChange($event)"></su-number-box>
<view class="buy-num-box ss-flex ss-col-center ss-row-between ss-m-b-40"> </view>
<view class="label-text">购买数量</view> </scroll-view>
<su-number-box </view>
:min="1" <view class="modal-footer border-top">
:max="state.selectedSkuPrice.stock" <view class="buy-box ss-flex ss-col-center ss-flex ss-col-center ss-row-center" v-if="isScore">
:step="1" <button class="ss-reset-button score-btn ui-Shadow-Main" @tap="onBuy"></button>
v-model="state.selectedSkuPrice.goods_num" </view>
@change="onNumberChange($event)" <view class="buy-box ss-flex ss-col-center ss-flex ss-col-center ss-row-center" v-else>
></su-number-box> <button class="ss-reset-button add-btn ui-Shadow-Main" @tap="onAddCart"></button>
</view> <button class="ss-reset-button buy-btn ui-Shadow-Main" @tap="onBuy"></button>
</scroll-view> </view>
</view> </view>
<view class="modal-footer border-top"> </view>
<view </su-popup>
class="buy-box ss-flex ss-col-center ss-flex ss-col-center ss-row-center"
v-if="isScore"
>
<button class="ss-reset-button score-btn ui-Shadow-Main" @tap="onBuy"></button>
</view>
<view class="buy-box ss-flex ss-col-center ss-flex ss-col-center ss-row-center" v-else>
<button class="ss-reset-button add-btn ui-Shadow-Main" @tap="onAddCart"
>加入购物车</button
>
<button class="ss-reset-button buy-btn ui-Shadow-Main" @tap="onBuy"></button>
</view>
</view>
</view>
</su-popup>
</template> </template>
<script setup> <script setup>
import { computed, reactive, watch } from 'vue'; import {
import sheep from '@/sheep'; computed,
import { formatStock, formatPrice } from '@/sheep/hooks/useGoods'; reactive,
import { isEmpty } from 'lodash'; watch
} from 'vue';
import sheep from '@/sheep';
import {
formatStock,
formatPrice
} from '@/sheep/hooks/useGoods';
import {
isEmpty
} from 'lodash';
const emits = defineEmits(['change', 'addCart', 'buy', 'close']); const emits = defineEmits(['change', 'addCart', 'buy', 'close']);
const props = defineProps({ const props = defineProps({
goodsInfo: { goodsInfo: {
type: Object, type: Object,
default() {}, default () {},
}, },
show: { show: {
type: Boolean, type: Boolean,
default: false, default: false,
}, },
isScore: { isScore: {
type: Boolean, type: Boolean,
default: false, default: false,
}, },
}); });
const state = reactive({ const state = reactive({
selectedSkuPrice: {}, selectedSkuPrice: {},
currentSkuArray: [], currentSkuArray: [],
}); });
// //
function onNumberChange(e) { function onNumberChange(e) {
if (e === 0) return; if (e === 0) return;
if (state.selectedSkuPrice.goods_num === e) return; if (state.selectedSkuPrice.goods_num === e) return;
state.selectedSkuPrice.goods_num = e; state.selectedSkuPrice.goods_num = e;
} }
// //
if (!props.goodsInfo.is_sku) { if (!props.goodsInfo.is_sku) {
state.selectedSkuPrice = props.goodsInfo.sku_prices[0]; state.selectedSkuPrice = props.goodsInfo.sku_prices[0];
} }
const skuList = props.goodsInfo.skus; const skuList = props.goodsInfo.skus;
// //
const skuPrices = computed(() => { const skuPrices = computed(() => {
let skuPrices = props.goodsInfo.sku_prices; let skuPrices = props.goodsInfo.sku_prices;
if (props.goodsInfo.is_sku) { if (props.goodsInfo.is_sku) {
skuPrices.forEach((item) => { skuPrices.forEach((item) => {
item.goods_sku_id_arr = item.goods_sku_ids.split(','); item.goods_sku_id_arr = item.goods_sku_ids.split(',');
}); });
} }
return skuPrices; return skuPrices;
}); });
watch( watch(
() => state.selectedSkuPrice, () => state.selectedSkuPrice,
(newVal) => { (newVal) => {
emits('change', newVal); emits('change', newVal);
}, }, {
{ immediate: true, //
immediate: true, // deep: true, //
deep: true, // },
}, );
);
const goodsPrice = computed(() => { const goodsPrice = computed(() => {
let price, score; let price, score;
if (isEmpty(state.selectedSkuPrice)) { if (isEmpty(state.selectedSkuPrice)) {
price = props.goodsInfo.price[0]; price = props.goodsInfo.price[0];
score = props.goodsInfo.score || 0; score = props.goodsInfo.score || 0;
} else { } else {
price = state.selectedSkuPrice.price; price = state.selectedSkuPrice.price;
score = state.selectedSkuPrice.score || 0; score = state.selectedSkuPrice.score || 0;
} }
return { return {
price, price,
score, score,
}; };
}); });
function onAddCart() { function onAddCart() {
if (state.selectedSkuPrice.goods_id) { if (state.selectedSkuPrice.goods_id) {
if (state.selectedSkuPrice.stock <= 0) { if (state.selectedSkuPrice.stock <= 0) {
sheep.$helper.toast('库存不足'); sheep.$helper.toast('库存不足');
} else { } else {
emits('addCart', state.selectedSkuPrice); emits('addCart', state.selectedSkuPrice);
} }
} else { } else {
sheep.$helper.toast('请选择规格'); sheep.$helper.toast('请选择规格');
} }
} }
function onBuy() { function onBuy() {
if (state.selectedSkuPrice.goods_id) { if (state.selectedSkuPrice.goods_id) {
if (state.selectedSkuPrice.stock <= 0) { if (state.selectedSkuPrice.stock <= 0) {
sheep.$helper.toast('库存不足'); sheep.$helper.toast('库存不足');
} else { } else {
emits('buy', state.selectedSkuPrice); emits('buy', state.selectedSkuPrice);
} }
} else { } else {
sheep.$helper.toast('请选择规格'); sheep.$helper.toast('请选择规格');
} }
} }
// //
function changeDisabled(isChecked = false, pid = 0, skuId = 0) { function changeDisabled(isChecked = false, pid = 0, skuId = 0) {
let newPrice = []; // skuPrice let newPrice = []; // skuPrice
if (isChecked) { if (isChecked) {
// //
// skuPrice // skuPrice
for (let price of skuPrices.value) { for (let price of skuPrices.value) {
if (price.stock <= 0) { if (price.stock <= 0) {
// this.goodsNum uni-number-box stock goods_num // this.goodsNum uni-number-box stock goods_num
continue; continue;
} }
if (price.goods_sku_id_arr.indexOf(skuId.toString()) >= 0) { if (price.goods_sku_id_arr.indexOf(skuId.toString()) >= 0) {
newPrice.push(price); newPrice.push(price);
} }
} }
} else { } else {
// //
// skuPrice // skuPrice
newPrice = getCanUseSkuPrice(); newPrice = getCanUseSkuPrice();
} }
// id // id
let noChooseSkuIds = []; let noChooseSkuIds = [];
for (let price of newPrice) { for (let price of newPrice) {
noChooseSkuIds = noChooseSkuIds.concat(price.goods_sku_id_arr); noChooseSkuIds = noChooseSkuIds.concat(price.goods_sku_id_arr);
} }
// //
noChooseSkuIds = Array.from(new Set(noChooseSkuIds)); noChooseSkuIds = Array.from(new Set(noChooseSkuIds));
if (isChecked) { if (isChecked) {
// //
let index = noChooseSkuIds.indexOf(skuId.toString()); let index = noChooseSkuIds.indexOf(skuId.toString());
noChooseSkuIds.splice(index, 1); noChooseSkuIds.splice(index, 1);
} else { } else {
// //
state.currentSkuArray.forEach((sku) => { state.currentSkuArray.forEach((sku) => {
if (sku.toString() != '') { if (sku.toString() != '') {
// sku // sku
let index = noChooseSkuIds.indexOf(sku.toString()); let index = noChooseSkuIds.indexOf(sku.toString());
if (index >= 0) { if (index >= 0) {
// sku noChooseSkuIds // sku noChooseSkuIds
noChooseSkuIds.splice(index, 1); noChooseSkuIds.splice(index, 1);
} }
} }
}); });
} }
// //
let chooseSkuKey = []; let chooseSkuKey = [];
if (!isChecked) { if (!isChecked) {
// //
state.currentSkuArray.forEach((sku, key) => { state.currentSkuArray.forEach((sku, key) => {
if (sku != '') { if (sku != '') {
// sku // sku
chooseSkuKey.push(key); chooseSkuKey.push(key);
} }
}); });
} else { } else {
// //
chooseSkuKey = [pid]; chooseSkuKey = [pid];
} }
for (let i in skuList) { for (let i in skuList) {
// //
if (chooseSkuKey.indexOf(skuList[i]['id']) >= 0) { if (chooseSkuKey.indexOf(skuList[i]['id']) >= 0) {
continue; continue;
} }
for (let j in skuList[i]['children']) { for (let j in skuList[i]['children']) {
// id // id
if (noChooseSkuIds.indexOf(skuList[i]['children'][j]['id'].toString()) >= 0) { if (noChooseSkuIds.indexOf(skuList[i]['children'][j]['id'].toString()) >= 0) {
skuList[i]['children'][j]['disabled'] = false; skuList[i]['children'][j]['disabled'] = false;
} else { } else {
skuList[i]['children'][j]['disabled'] = true; skuList[i]['children'][j]['disabled'] = true;
} }
} }
} }
} }
// skuPrice // skuPrice
function getCanUseSkuPrice() { function getCanUseSkuPrice() {
let newPrice = []; let newPrice = [];
for (let price of skuPrices.value) { for (let price of skuPrices.value) {
if (price.stock <= 0) { if (price.stock <= 0) {
// || price.stock < this.goodsNum uni-number-box stock goods_num // || price.stock < this.goodsNum uni-number-box stock goods_num
continue; continue;
} }
var isOk = true; var isOk = true;
state.currentSkuArray.forEach((sku) => { state.currentSkuArray.forEach((sku) => {
// sku skuPrice , // sku skuPrice ,
if (sku.toString() != '' && price.goods_sku_id_arr.indexOf(sku.toString()) < 0) { if (sku.toString() != '' && price.goods_sku_id_arr.indexOf(sku.toString()) < 0) {
isOk = false; isOk = false;
} }
}); });
if (isOk) { if (isOk) {
newPrice.push(price); newPrice.push(price);
} }
} }
return newPrice; return newPrice;
} }
// //
function onSelectSku(pid, skuId) { function onSelectSku(pid, skuId) {
// //
let isChecked = true; // or let isChecked = true; // or
if (state.currentSkuArray[pid] != undefined && state.currentSkuArray[pid] == skuId) { if (state.currentSkuArray[pid] != undefined && state.currentSkuArray[pid] == skuId) {
// '' // ''
isChecked = false; isChecked = false;
state.currentSkuArray.splice(pid, 1, ''); state.currentSkuArray.splice(pid, 1, '');
} else { } else {
// //
state.currentSkuArray[pid] = skuId; state.currentSkuArray[pid] = skuId;
} }
let chooseSkuId = []; // let chooseSkuId = []; //
state.currentSkuArray.forEach((sku) => { state.currentSkuArray.forEach((sku) => {
if (sku != '') { if (sku != '') {
// sku // sku
chooseSkuId.push(sku); chooseSkuId.push(sku);
} }
}); });
// skuPric // skuPric
let newPrice = getCanUseSkuPrice(); let newPrice = getCanUseSkuPrice();
// //
if (chooseSkuId.length == skuList.length && newPrice.length) { if (chooseSkuId.length == skuList.length && newPrice.length) {
newPrice[0].goods_num = state.selectedSkuPrice.goods_num || 1; newPrice[0].goods_num = state.selectedSkuPrice.goods_num || 1;
state.selectedSkuPrice = newPrice[0]; state.selectedSkuPrice = newPrice[0];
} else { } else {
state.selectedSkuPrice = {}; state.selectedSkuPrice = {};
} }
// //
changeDisabled(isChecked, pid, skuId); changeDisabled(isChecked, pid, skuId);
} }
changeDisabled(false); changeDisabled(false);
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
// //
.buy-box { .buy-box {
padding: 10rpx 0; padding: 10rpx 0;
.add-btn { .add-btn {
width: 356rpx; width: 356rpx;
height: 80rpx; height: 80rpx;
border-radius: 40rpx 0 0 40rpx; border-radius: 40rpx 0 0 40rpx;
background-color: var(--ui-BG-Main-light); background-color: var(--ui-BG-Main-light);
color: var(--ui-BG-Main); color: var(--ui-BG-Main);
} }
.buy-btn { .buy-btn {
width: 356rpx; width: 356rpx;
height: 80rpx; height: 80rpx;
border-radius: 0 40rpx 40rpx 0; border-radius: 0 40rpx 40rpx 0;
background: linear-gradient(90deg, var(--ui-BG-Main), var(--ui-BG-Main-gradient)); background: linear-gradient(90deg, var(--ui-BG-Main), var(--ui-BG-Main-gradient));
color: #fff; color: #fff;
} }
.score-btn { .score-btn {
width: 100%; width: 100%;
margin: 0 20rpx; margin: 0 20rpx;
height: 80rpx; height: 80rpx;
border-radius: 40rpx; border-radius: 40rpx;
background: linear-gradient(90deg, var(--ui-BG-Main), var(--ui-BG-Main-gradient)); background: linear-gradient(90deg, var(--ui-BG-Main), var(--ui-BG-Main-gradient));
color: #fff; color: #fff;
} }
} }
.ss-modal-box { .ss-modal-box {
border-radius: 30rpx 30rpx 0 0; border-radius: 30rpx 30rpx 0 0;
max-height: 1000rpx; max-height: 1000rpx;
.modal-header { .modal-header {
position: relative; position: relative;
padding: 80rpx 20rpx 40rpx; padding: 80rpx 20rpx 40rpx;
.sku-image { .sku-image {
width: 160rpx; width: 160rpx;
height: 160rpx; height: 160rpx;
border-radius: 10rpx; border-radius: 10rpx;
} }
.header-right { .header-right {
height: 160rpx; height: 160rpx;
} }
.close-icon { .close-icon {
position: absolute; position: absolute;
top: 10rpx; top: 10rpx;
right: 20rpx; right: 20rpx;
font-size: 46rpx; font-size: 46rpx;
opacity: 0.2; opacity: 0.2;
} }
.goods-title { .goods-title {
font-size: 28rpx; font-size: 28rpx;
font-weight: 500; font-weight: 500;
line-height: 42rpx; line-height: 42rpx;
} }
.score-img { .score-img {
width: 36rpx; width: 36rpx;
height: 36rpx; height: 36rpx;
margin: 0 4rpx; margin: 0 4rpx;
} }
.score-text { .score-text {
font-size: 30rpx; font-size: 30rpx;
font-weight: 500; font-weight: 500;
color: $red; color: $red;
font-family: OPPOSANS; font-family: OPPOSANS;
} }
.price-text { .price-text {
font-size: 30rpx; font-size: 30rpx;
font-weight: 500; font-weight: 500;
color: $red; color: $red;
font-family: OPPOSANS; font-family: OPPOSANS;
&::before { &::before {
content: '¥'; content: '¥';
font-size: 30rpx; font-size: 30rpx;
font-weight: 500; font-weight: 500;
color: $red; color: $red;
} }
} }
.stock-text { .stock-text {
font-size: 26rpx; font-size: 26rpx;
color: #999999; color: #999999;
} }
} }
.modal-content { .modal-content {
padding: 0 20rpx; padding: 0 20rpx;
.modal-content-scroll { .modal-content-scroll {
max-height: 600rpx; max-height: 600rpx;
.label-text { .label-text {
font-size: 26rpx; font-size: 26rpx;
font-weight: 500; font-weight: 500;
} }
.buy-num-box { .buy-num-box {
height: 100rpx; height: 100rpx;
} }
.spec-btn { .spec-btn {
height: 60rpx; height: 60rpx;
min-width: 100rpx; min-width: 100rpx;
padding: 0 30rpx; padding: 0 30rpx;
background: #f4f4f4; background: #f4f4f4;
border-radius: 30rpx; border-radius: 30rpx;
color: #434343; color: #434343;
font-size: 26rpx; font-size: 26rpx;
margin-right: 10rpx; margin-right: 10rpx;
margin-bottom: 10rpx; margin-bottom: 10rpx;
} }
.disabled-btn { .disabled-btn {
font-weight: 400; font-weight: 400;
color: #c6c6c6; color: #c6c6c6;
background: #f8f8f8; background: #f8f8f8;
} }
} }
} }
} }
</style> </style>

View File

@ -1,34 +1,31 @@
<!-- 页面 --> <!-- 页面 -->
<template> <template>
<view class="ss-user-info-wrap ss-p-t-50"> <view class="ss-user-info-wrap ss-p-t-50">
<view class="ss-flex ss-col-center ss-row-between ss-m-b-20"> <view class="ss-flex ss-col-center ss-row-between ss-m-b-20">
<view class="left-box ss-flex ss-col-center ss-m-l-36"> <view class="left-box ss-flex ss-col-center ss-m-l-36">
<view class="avatar-box ss-m-r-24"> <view class="avatar-box ss-m-r-24">
<image <image class="avatar-img" :src="
class="avatar-img"
:src="
isLogin isLogin
? sheep.$url.cdn(userInfo.avatar) ? sheep.$url.cdn(userInfo.avatar)
: sheep.$url.static('/static/img/shop/default_avatar.png') : sheep.$url.static('/static/img/shop/default_avatar.png')
" " mode="aspectFill" @tap="sheep.$router.go('/pages/user/info')"></image>
mode="aspectFill" </view>
@tap="sheep.$router.go('/pages/user/info')" <view>
></image> <view class="nickname-box ss-flex ss-col-center">
</view> <view class="nick-name ss-m-r-20">{{ userInfo?.nickname || nickname }}</view>
<view> </view>
<view class="nickname-box ss-flex ss-col-center"> </view>
<view class="nick-name ss-m-r-20">{{ userInfo?.nickname || nickname }}</view> </view>
</view> <view class="right-box ss-m-r-52">
</view> <button class="ss-reset-button" @tap="showShareModal">
</view> <text class="sicon-qrcode"></text>
<view class="right-box ss-m-r-52"> </button>
<button class="ss-reset-button" @tap="showShareModal"> </view>
<text class="sicon-qrcode"></text> </view>
</button>
</view>
</view>
<view
<!-- 提示绑定手机号 先隐藏 yudao 需要再修改 -->
<!-- <view
class="bind-mobile-box ss-flex ss-row-between ss-col-center" class="bind-mobile-box ss-flex ss-row-between ss-col-center"
v-if="isLogin && !userInfo.verification?.mobile" v-if="isLogin && !userInfo.verification?.mobile"
> >
@ -37,129 +34,135 @@
<view class="mobile-title ss-m-l-20"> 点击绑定手机号确保账户安全 </view> <view class="mobile-title ss-m-l-20"> 点击绑定手机号确保账户安全 </view>
</view> </view>
<button class="ss-reset-button bind-btn" @tap="onBind"></button> <button class="ss-reset-button bind-btn" @tap="onBind"></button>
</view> </view> -->
</view> </view>
</template> </template>
<script setup> <script setup>
/** /**
* 用户卡片 * 用户卡片
* *
* @property {Number} leftSpace - 容器左间距 * @property {Number} leftSpace - 容器左间距
* @property {Number} rightSpace - 容器右间距 * @property {Number} rightSpace - 容器右间距
* *
* @property {String} avatar - 头像 * @property {String} avatar - 头像
* @property {String} nickname - 昵称 * @property {String} nickname - 昵称
* @property {String} vip - 等级 * @property {String} vip - 等级
* @property {String} collectNum - 收藏数 * @property {String} collectNum - 收藏数
* @property {String} likeNum - 点赞数 * @property {String} likeNum - 点赞数
* *
* *
*/ */
import { computed, reactive } from 'vue'; import {
import sheep from '@/sheep'; computed,
import { showShareModal, showAuthModal } from '@/sheep/hooks/useModal'; reactive
} from 'vue';
import sheep from '@/sheep';
import {
showShareModal,
showAuthModal
} from '@/sheep/hooks/useModal';
// //
const userInfo = computed(() => sheep.$store('user').userInfo); const userInfo = computed(() => sheep.$store('user').userInfo);
console.log('用户信息',userInfo) console.log('用户信息', userInfo)
// //
const isLogin = computed(() => sheep.$store('user').isLogin); const isLogin = computed(() => sheep.$store('user').isLogin);
// //
const props = defineProps({ const props = defineProps({
background: { background: {
type: String, type: String,
default: '', default: '',
}, },
// //
avatar: { avatar: {
type: String, type: String,
default: '', default: '',
}, },
nickname: { nickname: {
type: String, type: String,
default: '请先登录', default: '请先登录',
}, },
vip: { vip: {
type: [String, Number], type: [String, Number],
default: '1', default: '1',
}, },
collectNum: { collectNum: {
type: [String, Number], type: [String, Number],
default: '1', default: '1',
}, },
likeNum: { likeNum: {
type: [String, Number], type: [String, Number],
default: '1', default: '1',
}, },
}); });
function onBind() { function onBind() {
showAuthModal('changeMobile'); showAuthModal('changeMobile');
} }
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.ss-user-info-wrap { .ss-user-info-wrap {
box-sizing: border-box; box-sizing: border-box;
.avatar-box { .avatar-box {
width: 100rpx; width: 100rpx;
height: 100rpx; height: 100rpx;
border-radius: 50%; border-radius: 50%;
overflow: hidden; overflow: hidden;
.avatar-img { .avatar-img {
width: 100%; width: 100%;
height: 100%; height: 100%;
} }
} }
.nick-name { .nick-name {
font-size: 34rpx; font-size: 34rpx;
font-weight: 400; font-weight: 400;
color: #333333; color: #333333;
line-height: normal; line-height: normal;
} }
.vip-img { .vip-img {
width: 30rpx; width: 30rpx;
height: 30rpx; height: 30rpx;
} }
.sicon-qrcode { .sicon-qrcode {
font-size: 40rpx; font-size: 40rpx;
} }
} }
.bind-mobile-box { .bind-mobile-box {
width: 100%; width: 100%;
height: 84rpx; height: 84rpx;
padding: 0 34rpx 0 44rpx; padding: 0 34rpx 0 44rpx;
box-sizing: border-box; box-sizing: border-box;
background: #ffffff; background: #ffffff;
box-shadow: 0px -8rpx 9rpx 0px rgba(#e0e0e0, 0.3); box-shadow: 0px -8rpx 9rpx 0px rgba(#e0e0e0, 0.3);
.cicon-mobile-o { .cicon-mobile-o {
font-size: 30rpx; font-size: 30rpx;
color: #ff690d; color: #ff690d;
} }
.mobile-title { .mobile-title {
font-size: 24rpx; font-size: 24rpx;
font-weight: 500; font-weight: 500;
color: #ff690d; color: #ff690d;
} }
.bind-btn { .bind-btn {
width: 100rpx; width: 100rpx;
height: 50rpx; height: 50rpx;
background: #ff6100; background: #ff6100;
border-radius: 25rpx; border-radius: 25rpx;
font-size: 24rpx; font-size: 24rpx;
font-weight: 500; font-weight: 500;
color: #ffffff; color: #ffffff;
} }
} }
</style> </style>

View File

@ -1,4 +1,16 @@
<template> <template>
<<<<<<< HEAD
<view class="ss-wallet-menu-wrap ss-flex ss-col-center">
<view class="menu-item ss-flex-1 ss-flex-col ss-row-center ss-col-center"
@tap="sheep.$router.go('/pages/user/wallet/money')">
<view class="value-box ss-flex ss-col-bottom">
<view class="value-text ss-line-1">{{ userInfo.money }}</view>
<view class="unit-text ss-m-l-6"></view>
</view>
<view class="menu-title ss-m-t-28">账户余额</view>
</view>
<!-- <view class="menu-item ss-flex-1 ss-flex-col ss-row-center ss-col-center"
=======
<view class="ss-wallet-menu-wrap ss-flex ss-col-center"> <view class="ss-wallet-menu-wrap ss-flex ss-col-center">
<view <view
class="menu-item ss-flex-1 ss-flex-col ss-row-center ss-col-center" class="menu-item ss-flex-1 ss-flex-col ss-row-center ss-col-center"
@ -11,6 +23,7 @@
<view class="menu-title ss-m-t-28">账户余额</view> <view class="menu-title ss-m-t-28">账户余额</view>
</view> </view>
<!-- <view class="menu-item ss-flex-1 ss-flex-col ss-row-center ss-col-center" <!-- <view class="menu-item ss-flex-1 ss-flex-col ss-row-center ss-col-center"
>>>>>>> 6251ffa9944516e995002e7f11539aef3e1d50de
@tap="sheep.$router.go('/pages/user/wallet/commission')"> @tap="sheep.$router.go('/pages/user/wallet/commission')">
<view class="value-box ss-flex ss-col-bottom"> <view class="value-box ss-flex ss-col-bottom">
<view class="value-text">{{ userInfo?.commission || '0.00' }}</view> <view class="value-text">{{ userInfo?.commission || '0.00' }}</view>
@ -18,6 +31,34 @@
</view> </view>
<view class="menu-title ss-m-t-28">佣金</view> <view class="menu-title ss-m-t-28">佣金</view>
</view> --> </view> -->
<<<<<<< HEAD
<view class="menu-item ss-flex-1 ss-flex-col ss-row-center ss-col-center"
@tap="sheep.$router.go('/pages/user/wallet/score')">
<view class="value-box ss-flex ss-col-bottom">
<view class="value-text">{{ userInfo.point }}</view>
<view class="unit-text ss-m-l-6"></view>
</view>
<view class="menu-title ss-m-t-28">积分</view>
</view>
<view class="menu-item ss-flex-1 ss-flex-col ss-row-center ss-col-center" @tap="
sheep.$router.go('/pages/coupon/list', {
type: 'geted',
})
">
<view class="value-box ss-flex ss-col-bottom">
<view class="value-text">{{ numData.coupons_num }}</view>
<view class="unit-text ss-m-l-6"></view>
</view>
<view class="menu-title ss-m-t-28">优惠券</view>
</view>
<view class="menu-item ss-flex-col ss-row-center ss-col-center menu-wallet"
@tap="sheep.$router.go('/pages/user/wallet/money')">
<image class="item-icon" :src="sheep.$url.static('/static/img/shop/user/wallet_icon.png')" mode="aspectFit">
</image>
<view class="menu-title ss-m-t-30">我的钱包</view>
</view>
</view>
=======
<view <view
class="menu-item ss-flex-1 ss-flex-col ss-row-center ss-col-center" class="menu-item ss-flex-1 ss-flex-col ss-row-center ss-col-center"
@tap="sheep.$router.go('/pages/user/wallet/score')" @tap="sheep.$router.go('/pages/user/wallet/score')"
@ -55,56 +96,61 @@
<view class="menu-title ss-m-t-30">我的钱包</view> <view class="menu-title ss-m-t-30">我的钱包</view>
</view> </view>
</view> </view>
>>>>>>> 6251ffa9944516e995002e7f11539aef3e1d50de
</template> </template>
<script setup> <script setup>
/** /**
* 装修组件 - 订单菜单组 * 装修组件 - 订单菜单组
*/ */
import { computed, ref } from 'vue'; import {
import sheep from '@/sheep'; computed,
ref
} from 'vue';
import sheep from '@/sheep';
const userInfo = computed(() => sheep.$store('user').userInfo); const userInfo = computed(() => sheep.$store('user').userInfo);
const numData = computed(() => sheep.$store('user').numData); const numData = computed(() => sheep.$store('user').numData);
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.ss-wallet-menu-wrap { .ss-wallet-menu-wrap {
.menu-wallet { .menu-wallet {
width: 144rpx; width: 144rpx;
} }
.menu-item {
height: 160rpx;
.menu-title { .menu-item {
font-size: 24rpx; height: 160rpx;
line-height: 24rpx;
color: #333333;
}
.item-icon { .menu-title {
width: 44rpx; font-size: 24rpx;
height: 44rpx; line-height: 24rpx;
} color: #333333;
}
.value-box { .item-icon {
height: 50rpx; width: 44rpx;
text-align: center; height: 44rpx;
}
.value-text { .value-box {
font-size: 28rpx; height: 50rpx;
color: #000000; text-align: center;
line-height: 28rpx;
vertical-align: text-bottom;
font-family: OPPOSANS;
}
.unit-text { .value-text {
font-size: 24rpx; font-size: 28rpx;
color: #343434; color: #000000;
line-height: 24rpx; line-height: 28rpx;
} vertical-align: text-bottom;
} font-family: OPPOSANS;
} }
}
</style> .unit-text {
font-size: 24rpx;
color: #343434;
line-height: 24rpx;
}
}
}
}
</style>

View File

@ -4,213 +4,218 @@
*/ */
import Request from 'luch-request'; import Request from 'luch-request';
import { baseUrl, apiPath } from '@/sheep/config'; import {
baseUrl,
apiPath
} from '@/sheep/config';
import $store from '@/sheep/store'; import $store from '@/sheep/store';
import $platform from '@/sheep/platform'; import $platform from '@/sheep/platform';
import { showAuthModal } from '@/sheep/hooks/useModal'; import {
showAuthModal
} from '@/sheep/hooks/useModal';
const options = { const options = {
// 显示操作成功消息 默认不显示 // 显示操作成功消息 默认不显示
showSuccess: false, showSuccess: false,
// 成功提醒 默认使用后端返回值 // 成功提醒 默认使用后端返回值
successMsg: '', successMsg: '',
// 显示失败消息 默认显示 // 显示失败消息 默认显示
showError: true, showError: true,
// 失败提醒 默认使用后端返回信息 // 失败提醒 默认使用后端返回信息
errorMsg: '', errorMsg: '',
// 显示请求时loading模态框 默认显示 // 显示请求时loading模态框 默认显示
showLoading: true, showLoading: true,
// loading提醒文字 // loading提醒文字
loadingMsg: '加载中', loadingMsg: '加载中',
// 需要授权才能请求 默认放开 // 需要授权才能请求 默认放开
auth: false, auth: false,
// ... // ...
}; };
// Loading全局实例 // Loading全局实例
let LoadingInstance = { let LoadingInstance = {
target: null, target: null,
count: 0, count: 0,
}; };
/** /**
* 关闭loading * 关闭loading
*/ */
function closeLoading() { function closeLoading() {
if (LoadingInstance.count > 0) LoadingInstance.count--; if (LoadingInstance.count > 0) LoadingInstance.count--;
if (LoadingInstance.count === 0) uni.hideLoading(); if (LoadingInstance.count === 0) uni.hideLoading();
} }
/** /**
* @description 请求基础配置 可直接使用访问自定义请求 * @description 请求基础配置 可直接使用访问自定义请求
*/ */
const http = new Request({ const http = new Request({
baseURL: baseUrl, baseURL: baseUrl,
timeout: 8000, timeout: 8000,
method: 'GET', method: 'GET',
header: { header: {
Accept: 'text/json', Accept: 'text/json',
'Content-Type': 'application/json;charset=UTF-8', 'Content-Type': 'application/json;charset=UTF-8',
platform: $platform.name, platform: $platform.name,
}, },
// #ifdef APP-PLUS // #ifdef APP-PLUS
sslVerify: false, sslVerify: false,
// #endif // #endif
// #ifdef H5 // #ifdef H5
// 跨域请求时是否携带凭证cookies仅H5支持HBuilderX 2.6.15+ // 跨域请求时是否携带凭证cookies仅H5支持HBuilderX 2.6.15+
withCredentials: false, withCredentials: false,
// #endif // #endif
custom: options, custom: options,
}); });
/** /**
* @description 请求拦截器 * @description 请求拦截器
*/ */
http.interceptors.request.use( http.interceptors.request.use(
(config) => { (config) => {
if (config.custom.auth && !$store('user').isLogin) { if (config.custom.auth && !$store('user').isLogin) {
showAuthModal(); showAuthModal();
return Promise.reject(); return Promise.reject();
} }
if (config.custom.showLoading) { if (config.custom.showLoading) {
LoadingInstance.count++; LoadingInstance.count++;
LoadingInstance.count === 1 && LoadingInstance.count === 1 &&
uni.showLoading({ uni.showLoading({
title: config.custom.loadingMsg, title: config.custom.loadingMsg,
mask: true, mask: true,
fail: () => { fail: () => {
uni.hideLoading(); uni.hideLoading();
}, },
}); });
} }
const token = uni.getStorageSync('token'); const token = uni.getStorageSync('token');
if (token) config.header['Authorization'] = token; if (token) config.header['Authorization'] = token;
// TODO 芋艿:特殊处理 // TODO 芋艿:特殊处理
if (config.url.indexOf('/app-api/') !== -1) { if (config.url.indexOf('/app-api/') !== -1) {
config.header['Accept'] = '*/*' config.header['Accept'] = '*/*'
config.header['tenant-id'] = '1'; config.header['tenant-id'] = '1';
config.header['Authorization'] = 'Bearer test247'; config.header['Authorization'] = 'Bearer test247';
} }
return config; return config;
}, },
(error) => { (error) => {
return Promise.reject(error); return Promise.reject(error);
}, },
); );
/** /**
* @description 响应拦截器 * @description 响应拦截器
*/ */
http.interceptors.response.use( http.interceptors.response.use(
(response) => { (response) => {
// 自动设置登陆令牌 // 自动设置登陆令牌
if (response.header.authorization || response.header.Authorization) { if (response.header.authorization || response.header.Authorization) {
$store('user').setToken(response.header.authorization || response.header.Authorization); $store('user').setToken(response.header.authorization || response.header.Authorization);
} }
response.config.custom.showLoading && closeLoading(); response.config.custom.showLoading && closeLoading();
if (response.data.error !== 0) { if (response.data.error !== 0) {
if (response.config.custom.showError) if (response.config.custom.showError)
uni.showToast({ uni.showToast({
title: response.data.msg || '服务器开小差啦,请稍后再试~', title: response.data.msg || '服务器开小差啦,请稍后再试~',
icon: 'none', icon: 'none',
mask: true, mask: true,
}); });
return Promise.resolve(response.data); return Promise.resolve(response.data);
} }
if ( if (
response.data.error === 0 && response.data.error === 0 &&
response.data.msg !== '' && response.data.msg !== '' &&
response.config.custom.showSuccess response.config.custom.showSuccess
) { ) {
uni.showToast({ uni.showToast({
title: response.config.custom.successMsg || response.data.msg, title: response.config.custom.successMsg || response.data.msg,
icon: 'none', icon: 'none',
}); });
} }
return Promise.resolve(response.data); return Promise.resolve(response.data);
}, },
(error) => { (error) => {
const userStore = $store('user'); const userStore = $store('user');
const isLogin = userStore.isLogin; const isLogin = userStore.isLogin;
let errorMessage = '网络请求出错'; let errorMessage = '网络请求出错';
if (error !== undefined) { if (error !== undefined) {
switch (error.statusCode) { switch (error.statusCode) {
case 400: case 400:
errorMessage = '请求错误'; errorMessage = '请求错误';
break; break;
case 401: case 401:
if (isLogin) { if (isLogin) {
errorMessage = '您的登陆已过期'; errorMessage = '您的登陆已过期';
} else { } else {
errorMessage = '请先登录'; errorMessage = '请先登录';
} }
userStore.logout(true); userStore.logout(true);
showAuthModal(); showAuthModal();
break; break;
case 403: case 403:
errorMessage = '拒绝访问'; errorMessage = '拒绝访问';
break; break;
case 404: case 404:
errorMessage = '请求出错'; errorMessage = '请求出错';
break; break;
case 408: case 408:
errorMessage = '请求超时'; errorMessage = '请求超时';
break; break;
case 429: case 429:
errorMessage = '请求频繁, 请稍后再访问'; errorMessage = '请求频繁, 请稍后再访问';
break; break;
case 500: case 500:
errorMessage = '服务器开小差啦,请稍后再试~'; errorMessage = '服务器开小差啦,请稍后再试~';
break; break;
case 501: case 501:
errorMessage = '服务未实现'; errorMessage = '服务未实现';
break; break;
case 502: case 502:
errorMessage = '网络错误'; errorMessage = '网络错误';
break; break;
case 503: case 503:
errorMessage = '服务不可用'; errorMessage = '服务不可用';
break; break;
case 504: case 504:
errorMessage = '网络超时'; errorMessage = '网络超时';
break; break;
case 505: case 505:
errorMessage = 'HTTP版本不受支持'; errorMessage = 'HTTP版本不受支持';
break; break;
} }
if (error.errMsg.includes('timeout')) errorMessage = '请求超时'; if (error.errMsg.includes('timeout')) errorMessage = '请求超时';
// #ifdef H5 // #ifdef H5
if (error.errMsg.includes('Network')) if (error.errMsg.includes('Network'))
errorMessage = window.navigator.onLine ? '服务器异常' : '请检查您的网络连接'; errorMessage = window.navigator.onLine ? '服务器异常' : '请检查您的网络连接';
// #endif // #endif
} }
if (error && error.config) { if (error && error.config) {
if (error.config.custom.showError === false) { if (error.config.custom.showError === false) {
uni.showToast({ uni.showToast({
title: error.data?.msg || errorMessage, title: error.data?.msg || errorMessage,
icon: 'none', icon: 'none',
mask: true, mask: true,
}); });
} }
error.config.custom.showLoading && closeLoading(); error.config.custom.showLoading && closeLoading();
} }
return false; return false;
}, },
); );
const request = (config) => { const request = (config) => {
if (config.url[0] !== '/') { if (config.url[0] !== '/') {
config.url = apiPath + config.url; config.url = apiPath + config.url;
} }
// TODO 芋艿:额外拼接 // TODO 芋艿:额外拼接
if (config.url.indexOf('/app-api/') >= 0) { if (config.url.indexOf('/app-api/') >= 0) {
config.url = 'http://api-dashboard.yudao.iocoder.cn' + config.url; // 调用【云端】 config.url = 'http://api-dashboard.yudao.iocoder.cn' + config.url; // 调用【云端】
// config.url = 'http://127.0.0.1:48080' + config.url; // 调用【本地】 // config.url = 'http://127.0.0.1:48080' + config.url; // 调用【本地】
} }
return http.middleware(config); return http.middleware(config);
}; };
export default request; export default request;

View File

@ -1,168 +1,194 @@
import { defineStore } from 'pinia'; import {
defineStore
} from 'pinia';
import userApi from '@/sheep/api/user'; import userApi from '@/sheep/api/user';
import commissionApi from '@/sheep/api/commission'; import commissionApi from '@/sheep/api/commission';
import $share from '@/sheep/platform/share'; import $share from '@/sheep/platform/share';
import { isEmpty, cloneDeep, clone } from 'lodash'; import {
isEmpty,
cloneDeep,
clone
} from 'lodash';
import cart from './cart'; import cart from './cart';
import app from './app'; import app from './app';
import { showAuthModal } from '@/sheep/hooks/useModal'; import {
showAuthModal
} from '@/sheep/hooks/useModal';
// 默认用户信息 // 默认用户信息
const defaultUserInfo = { const defaultUserInfo = {
avatar: '', // 头像 avatar: '', // 头像
nickname: '', // 昵称 nickname: '', // 昵称
gender: 0, // 性别 gender: 0, // 性别
mobile: '', // 手机号 mobile: '', // 手机号
money: '--', // 余额 money: '--', // 余额
commission: '--', // 佣金 commission: '--', // 佣金
score: '--', // 积分 score: '--', // 积分
verification: {}, // 认证字段 verification: {}, // 认证字段
}; };
// 默认订单、优惠券等其他资产信息 // 默认订单、优惠券等其他资产信息
const defaultNumData = { const defaultNumData = {
coupons_num: '--', coupons_num: '--',
order_num: { order_num: {
aftersale: 0, aftersale: 0,
nocomment: 0, nocomment: 0,
noget: 0, noget: 0,
nosend: 0, nosend: 0,
unpaid: 0, unpaid: 0,
}, },
}; };
const user = defineStore({ const user = defineStore({
id: 'user', id: 'user',
state: () => ({ state: () => ({
userInfo: clone(defaultUserInfo), // 用户信息 userInfo: clone(defaultUserInfo), // 用户信息
isLogin: !!uni.getStorageSync('token'), // 登录状态 isLogin: !!uni.getStorageSync('token'), // 登录状态
numData: cloneDeep(defaultNumData), // 用户其他数据 numData: cloneDeep(defaultNumData), // 用户其他数据
agentInfo: {}, // 分销商信息 agentInfo: {}, // 分销商信息
lastUpdateTime: 0, // 上次更新时间 lastUpdateTime: 0, // 上次更新时间
}), }),
actions: { actions: {
// 获取个人信息 // 获取个人信息
async getInfo() { async getInfo() {
const { code, data } = await userApi.profile(); const {
// 为了兼容 获取用户余额 可能还会用到其他参数 code,
const { code:code2, data:data2 } = await userApi.balance(); data
if (code !== 0||code2!=0) return; } = await userApi.profile();
data.money=data2.balance/100;
this.userInfo = data;
return Promise.resolve(data); // 为了兼容 获取用户余额 可能还会用到其他参数
}, // 优惠券数量,积分数量 应该在这里
const {
code: code2,
data: data2
} = await userApi.balance();
if (code !== 0 || code2 != 0) return;
data.money = data2.balance / 100;
this.userInfo = data;
console.log(data2, '信息')
return Promise.resolve(data);
},
// 获取分销商信息 // 获取分销商信息
async getAgentInfo() { async getAgentInfo() {
const res = await commissionApi.agent(); const res = await commissionApi.agent();
if (res.error === 0) { if (res.error === 0) {
this.agentInfo = res.data; this.agentInfo = res.data;
} }
return Promise.resolve(res); return Promise.resolve(res);
}, },
// 获取订单、优惠券等其他资产信息 // 获取订单、优惠券等其他资产信息
async getNumData() { async getNumData() {
const { code, data } = await userApi.data(); const {
const data2 = await userApi.data2(); code,
if (code === 0&&data2.code===0) { data
console.log('订单数据',data); } = await userApi.data();
this.numData = {order_num:{ const data2 = await userApi.data2();
noget:data.deliveredCount, let data3 = await userApi.getUnused();
unpaid:data.unpaidCount, console.log(data3.data, '优惠券')
nocomment:data.uncommentedCount, if (code === 0 && data2.code === 0) {
aftersale:data2.data console.log('订单数据', data);
}}; this.numData = {
} coupons_num: data3.data,
}, order_num: {
noget: data.deliveredCount,
unpaid: data.unpaidCount,
nocomment: data.uncommentedCount,
aftersale: data2.data
}
};
}
},
// 添加分享记录 // 添加分享记录
async addShareLog(params) { async addShareLog(params) {
const { error } = await userApi.addShareLog(params); const {
if (error === 0) uni.removeStorageSync('shareLog'); error
}, } = await userApi.addShareLog(params);
if (error === 0) uni.removeStorageSync('shareLog');
},
// 设置token // 设置token
setToken(token = '') { setToken(token = '') {
if (token === '') { if (token === '') {
this.isLogin = false; this.isLogin = false;
uni.removeStorageSync('token'); uni.removeStorageSync('token');
} else { } else {
this.isLogin = true; this.isLogin = true;
uni.setStorageSync('token', token); uni.setStorageSync('token', token);
this.loginAfter(); this.loginAfter();
} }
return this.isLogin; return this.isLogin;
}, },
// 更新用户相关信息 (手动限流 5秒之内不刷新) // 更新用户相关信息 (手动限流 5秒之内不刷新)
async updateUserData() { async updateUserData() {
if (!this.isLogin) { if (!this.isLogin) {
this.resetUserData(); this.resetUserData();
return; return;
} }
const nowTime = new Date().getTime(); const nowTime = new Date().getTime();
if (this.lastUpdateTime + 5000 > nowTime) return; if (this.lastUpdateTime + 5000 > nowTime) return;
await this.getInfo(); await this.getInfo();
this.getNumData(); this.getNumData();
this.lastUpdateTime = nowTime; this.lastUpdateTime = nowTime;
return this.userInfo; return this.userInfo;
}, },
// 重置用户默认数据 // 重置用户默认数据
resetUserData() { resetUserData() {
this.setToken(); this.setToken();
this.userInfo = clone(defaultUserInfo); this.userInfo = clone(defaultUserInfo);
this.numData = cloneDeep(defaultNumData); this.numData = cloneDeep(defaultNumData);
this.agentInfo = {}; this.agentInfo = {};
cart().emptyList(); cart().emptyList();
}, },
// 登录后 // 登录后
async loginAfter() { async loginAfter() {
await this.updateUserData(); await this.updateUserData();
cart().getList(); cart().getList();
// 登录后设置全局分享参数 // 登录后设置全局分享参数
$share.getShareInfo(); $share.getShareInfo();
// 提醒绑定手机号 // 提醒绑定手机号
if (app().platform.bind_mobile && !this.userInfo.verification?.mobile) { // if (app().platform.bind_mobile && !this.userInfo.verification?.mobile) {
showAuthModal('changeMobile'); // showAuthModal('changeMobile');
} // }
// 添加分享记录 // 添加分享记录
const shareLog = uni.getStorageSync('shareLog'); const shareLog = uni.getStorageSync('shareLog');
if (!isEmpty(shareLog)) { if (!isEmpty(shareLog)) {
this.addShareLog({ this.addShareLog({
...shareLog, ...shareLog,
}); });
} }
}, },
// 登出 // 登出
async logout(force = false) { async logout(force = false) {
if (!force) { if (!force) {
const { error } = await userApi.logout(); const {
if (error === 0) { error
this.resetUserData(); } = await userApi.logout();
} if (error === 0) {
} this.resetUserData();
if (force) { }
this.resetUserData(); }
} if (force) {
this.resetUserData();
}
return !this.isLogin; return !this.isLogin;
}, },
}, },
persist: { persist: {
enabled: true, enabled: true,
strategies: [ strategies: [{
{ key: 'user-store',
key: 'user-store', }, ],
}, },
],
},
}); });
export default user; export default user;