Merge remote-tracking branch 'origin/master-vue3' into master-vue3

pull/28/head
owen 2023-12-15 12:08:10 +08:00
commit 062ede78a2
59 changed files with 4887 additions and 4961 deletions

View File

@ -33,7 +33,7 @@
// #endif // #endif
// #ifdef MP-WEIXIN // #ifdef MP-WEIXIN
// //
console.log(options, 'options'); console.log(options, 'options');
// #endif // #endif

View File

@ -260,16 +260,6 @@
"auth": true, "auth": true,
"title": "物流轨迹" "title": "物流轨迹"
} }
},
{
"path": "express/list",
"style": {
"navigationBarTitleText": "订单包裹"
},
"meta": {
"auth": true,
"title": "订单包裹"
}
} }
] ]
}, },

File diff suppressed because it is too large Load Diff

View File

@ -1,372 +1,350 @@
<!-- 优惠券详情 --> <!-- 优惠券详情 -->
<template> <template>
<s-layout title="优惠券详情"> <s-layout title="优惠券详情">
<view class="bg-white"> <view class="bg-white">
<!-- 详情卡片 --> <!-- 详情卡片 -->
<view class="detail-wrap ss-p-20"> <view class="detail-wrap ss-p-20">
<view class="detail-box"> <view class="detail-box">
<view class="tag-box ss-flex ss-col-center ss-row-center"> <view class="tag-box ss-flex ss-col-center ss-row-center">
<image <image class="tag-image" :src="sheep.$url.static('/static/img/shop/app/coupon_icon.png')"
class="tag-image" mode="aspectFit"></image>
:src="sheep.$url.static('/static/img/shop/app/coupon_icon.png')" </view>
mode="aspectFit" <view class="top ss-flex-col ss-col-center">
></image> <view class="title ss-m-t-50 ss-m-b-20 ss-m-x-20">{{ state.list.name }}</view>
</view> <view class="subtitle ss-m-b-50">{{ state.list.enough }}{{ state.list.amount }}</view>
<view class="top ss-flex-col ss-col-center"> <!-- (state.list.get_status != 'can_get' && state.list.get_status != 'can_use') ||
<view class="title ss-m-t-50 ss-m-b-20 ss-m-x-20">{{ state.list.name }}</view> state.userCouponId -->
<view class="subtitle ss-m-b-50">{{ state.list.amount_text }}</view> <button class="ss-reset-button ss-m-b-30" :class="
<button
class="ss-reset-button ss-m-b-30"
:class="
state.list.get_status == 'can_get' || state.list.get_status == 'can_use' state.list.get_status == 'can_get' || state.list.get_status == 'can_use'
? 'use-btn' ? 'use-btn'
: 'disable-btn' : 'disable-btn' " :disabled="state.list.status_text=='已过期'" @click="getCoupon">
" <!-- {{ state.list.get_status_text }} -->
:disabled=" 立即使用
(state.list.get_status != 'can_get' && state.list.get_status != 'can_use') || </button>
state.userCouponId <view class="time ss-m-y-30" v-if="
"
@click="getCoupon"
>
{{ state.list.get_status_text }}
</button>
<view
class="time ss-m-y-30"
v-if="
state.list.get_status == 'can_get' || state.list.get_status == 'can_get' ||
state.list.get_status == 'cannot_get' || state.list.get_status == 'cannot_get' ||
state.list.get_status == 'get_over' state.list.get_status == 'get_over'
" ">
> 领取时间{{ state.list.get_start_time }}{{ state.list.get_end_time }}
领取时间{{ state.list.get_start_time }}{{ state.list.get_end_time }} </view>
</view> <view class="time ss-m-y-30" v-else>
<view class="time ss-m-y-30" v-else> 有效期{{ state.list.use_start_time }}{{ state.list.use_end_time }}
有效期{{ state.list.use_start_time }}{{ state.list.use_end_time }} </view>
</view> <view class="coupon-line ss-m-t-14"></view>
<view class="coupon-line ss-m-t-14"></view> </view>
</view> <view class="bottom">
<view class="bottom"> <view class="type ss-flex ss-col-center ss-row-between ss-p-x-30">
<view class="type ss-flex ss-col-center ss-row-between ss-p-x-30"> <view>优惠券类型</view>
<view>优惠券类型</view> <view>{{ state.list.type_text }}</view>
<view>{{ state.list.type_text }}</view> </view>
</view> <uni-collapse>
<uni-collapse> <uni-collapse-item title="优惠券说明" v-if="state.list.description">
<uni-collapse-item title="优惠券说明" v-if="state.list.description"> <view class="content ss-p-b-20">
<view class="content ss-p-b-20"> <text class="des ss-p-l-30">{{ state.list.description }}</text>
<text class="des ss-p-l-30">{{ state.list.description }}</text> </view>
</view> </uni-collapse-item>
</uni-collapse-item> </uni-collapse>
</uni-collapse> </view>
</view> </view>
</view> </view>
</view> <!-- 适用商品 -->
<!-- 适用商品 --> <view class="all-user ss-flex ss-row-center ss-col-center" v-if="state.list.use_scope == 'all_use'">
<view {{ state.list.use_scope_text }}
class="all-user ss-flex ss-row-center ss-col-center" </view>
v-if="state.list.use_scope == 'all_use'"
>
{{ state.list.use_scope_text }}
</view>
<su-sticky v-else bgColor="#fff"> <su-sticky v-else bgColor="#fff">
<view class="goods-title ss-p-20">{{ state.list.use_scope_text }}</view> <view class="goods-title ss-p-20">{{ state.list.use_scope_text }}</view>
<su-tabs <su-tabs :scrollable="true" :list="state.tabMaps" @change="onTabsChange" :current="state.currentTab"
:scrollable="true" v-if="state.list.use_scope == 'category'"></su-tabs>
:list="state.tabMaps" </su-sticky>
@change="onTabsChange" <view v-if="state.list.use_scope == 'goods' || state.list.use_scope == 'disabled_goods'">
:current="state.currentTab" <view v-for="(item, index) in state.list.items_value" :key="index">
v-if="state.list.use_scope == 'category'" <s-goods-column class="ss-m-20" size="lg" :data="item"
></su-tabs> :titleColor="props.goodsFieldsStyle?.title?.color"
</su-sticky> :subTitleColor="props.goodsFieldsStyle?.subtitle?.color"
<view v-if="state.list.use_scope == 'goods' || state.list.use_scope == 'disabled_goods'"> @click="sheep.$router.go('/pages/goods/index', { id: item.id })" :goodsFields="{
<view v-for="(item, index) in state.list.items_value" :key="index">
<s-goods-column
class="ss-m-20"
size="lg"
:data="item"
:titleColor="props.goodsFieldsStyle?.title?.color"
:subTitleColor="props.goodsFieldsStyle?.subtitle?.color"
@click="sheep.$router.go('/pages/goods/index', { id: item.id })"
:goodsFields="{
title: { show: true }, title: { show: true },
subtitle: { show: true }, subtitle: { show: true },
price: { show: true }, price: { show: true },
original_price: { show: true }, original_price: { show: true },
sales: { show: true }, sales: { show: true },
stock: { show: false }, stock: { show: false },
}" }" :buttonShow="state.list.use_scope != 'disabled_goods'"></s-goods-column>
:buttonShow="state.list.use_scope != 'disabled_goods'" </view>
></s-goods-column> </view>
</view> <view v-if="state.list.use_scope == 'category'">
</view> <view v-for="(item, index) in state.pagination.data" :key="index">
<view v-if="state.list.use_scope == 'category'"> <s-goods-column class="ss-m-20" size="lg" :data="item"
<view v-for="(item, index) in state.pagination.data" :key="index"> :titleColor="props.goodsFieldsStyle?.title?.color"
<s-goods-column :subTitleColor="props.goodsFieldsStyle?.subtitle?.color"
class="ss-m-20" @click="sheep.$router.go('/pages/goods/index', { id: item.id })" :goodsFields="{
size="lg"
:data="item"
:titleColor="props.goodsFieldsStyle?.title?.color"
:subTitleColor="props.goodsFieldsStyle?.subtitle?.color"
@click="sheep.$router.go('/pages/goods/index', { id: item.id })"
:goodsFields="{
title: { show: true }, title: { show: true },
subtitle: { show: true }, subtitle: { show: true },
price: { show: true }, price: { show: true },
original_price: { show: true }, original_price: { show: true },
sales: { show: true }, sales: { show: true },
stock: { show: false }, stock: { show: false },
}" }" :buttonShow="state.list.use_scope != 'disabled_goods'"></s-goods-column>
:buttonShow="state.list.use_scope != 'disabled_goods'" </view>
></s-goods-column> </view>
</view> <uni-load-more v-if="state.pagination.total > 0 && state.list.use_scope == 'category'"
</view> :status="state.loadStatus" :content-text="{
<uni-load-more
v-if="state.pagination.total > 0 && state.list.use_scope == 'category'"
:status="state.loadStatus"
:content-text="{
contentdown: '上拉加载更多', contentdown: '上拉加载更多',
}" }" @tap="loadmore" />
@tap="loadmore" <s-empty v-if="state.list.use_scope == 'category' && state.pagination.total === 0" paddingTop="0"
/> icon="/static/soldout-empty.png" text="暂无商品">
<s-empty </s-empty>
v-if="state.list.use_scope == 'category' && state.pagination.total === 0" </view>
paddingTop="0" </s-layout>
icon="/static/soldout-empty.png"
text="暂无商品"
>
</s-empty>
</view>
</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 { reactive } from 'vue'; onLoad,
import _ from 'lodash'; onReachBottom
} from '@dcloudio/uni-app';
import {
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({
list: {}, list: {},
couponId: 0, couponId: 0,
userCouponId: 0, userCouponId: 0,
pagination: { pagination: {
data: [], data: [],
current_page: 1, current_page: 1,
total: 1, total: 1,
last_page: 1, last_page: 1,
}, },
tabMaps: [], tabMaps: [],
loadStatus: '', loadStatus: '',
categoryId: 0, categoryId: 0,
}); });
// //
const props = defineProps({ const props = defineProps({
includes: { includes: {
type: Array, type: Array,
default() { default () {
return []; return [];
}, },
}, },
list: { list: {
type: Array, type: Array,
default: () => [], default: () => [],
}, },
goodsFieldsStyle: { goodsFieldsStyle: {
type: Object, type: Object,
default() {}, default () {},
}, },
buyData: { buyData: {
type: Object, type: Object,
default() {}, default () {},
}, },
}); });
function onTabsChange(e) { function onTabsChange(e) {
state.pagination = pagination; state.pagination = pagination;
state.currentTab = e.index; state.currentTab = e.index;
state.categoryId = e.value; state.categoryId = e.value;
getGoodsList(state.categoryId); getGoodsList(state.categoryId);
} }
async function getGoodsList(categoryId, page = 1, list_rows = 5) { async function getGoodsList(categoryId, page = 1, list_rows = 5) {
state.loadStatus = 'loading'; state.loadStatus = 'loading';
const res = await sheep.$api.goods.list({ const res = await sheep.$api.goods.list({
category_id: categoryId, category_id: categoryId,
list_rows, list_rows,
page, page,
is_category_deep: false, is_category_deep: false,
}); });
if (res.error === 0) { if (res.error === 0) {
let couponlist = _.concat(state.pagination.data, res.data.data); let couponlist = _.concat(state.pagination.data, res.data.data);
state.pagination = { state.pagination = {
...res.data, ...res.data,
data: couponlist, data: couponlist,
}; };
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 {
state.loadStatus = 'noMore'; state.loadStatus = 'noMore';
} }
} }
} }
async function getCoupon() { async function getCoupon() {
const { error, msg } = await sheep.$api.coupon.get(state.couponId); const {
if (error === 0) { error,
uni.showToast({ msg
title: msg, } = await sheep.$api.coupon.get(state.couponId);
}); if (error === 0) {
setTimeout(() => { uni.showToast({
getCouponContent(state.couponId, state.userCouponId); title: msg,
}, 1000); });
} setTimeout(() => {
} getCouponContent(state.couponId, state.userCouponId);
async function getCouponContent(id, c) { }, 1000);
const { data } = await sheep.$api.coupon.detail(id, c); }
state.list = data; }
data.items_value.forEach((i) => { async function getCouponContent(id, c) {
state.tabMaps.push({ name: i.name, value: i.id }); const {
}); data
state.pagination = pagination; } = await sheep.$api.coupon.detail(id, c);
if (state.list.use_scope == 'category') { state.list = data;
getGoodsList(state.tabMaps[0].value); data.items_value.forEach((i) => {
} state.tabMaps.push({
} name: i.name,
// value: i.id
function loadmore() { });
if (state.loadStatus !== 'noMore') { });
getGoodsList(state.categoryId, state.pagination.current_page + 1); state.pagination = pagination;
} if (state.list.use_scope == 'category') {
} getGoodsList(state.tabMaps[0].value);
onLoad((options) => { }
state.couponId = options.id; }
state.userCouponId = options.user_coupon_id; //
getCouponContent(state.couponId, state.userCouponId); function loadmore() {
}); if (state.loadStatus !== 'noMore') {
// getGoodsList(state.categoryId, state.pagination.current_page + 1);
onReachBottom(() => { }
loadmore(); }
}); onLoad((options) => {
if (options.data) {
let data = JSON.parse(options.data);
console.log(data);
state.list = data;
return;
}
state.couponId = options.id;
state.userCouponId = options.user_coupon_id;
getCouponContent(state.couponId, state.userCouponId);
});
//
onReachBottom(() => {
loadmore();
});
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.goods-title { .goods-title {
font-size: 34rpx; font-size: 34rpx;
font-weight: bold; font-weight: bold;
color: #333333; color: #333333;
} }
.detail-wrap { .detail-wrap {
background: linear-gradient( background: linear-gradient(180deg,
180deg, var(--ui-BG-Main),
var(--ui-BG-Main), var(--ui-BG-Main-gradient),
var(--ui-BG-Main-gradient), var(--ui-BG-Main),
var(--ui-BG-Main), #fff);
#fff }
);
}
.detail-box { .detail-box {
// background-color: var(--ui-BG); // background-color: var(--ui-BG);
border-radius: 6rpx; border-radius: 6rpx;
position: relative; position: relative;
margin-top: 100rpx; margin-top: 100rpx;
.tag-box {
width: 140rpx;
height: 140rpx;
background: var(--ui-BG);
border-radius: 50%;
position: absolute;
top: -70rpx;
left: 50%;
z-index: 6;
transform: translateX(-50%);
.tag-image { .tag-box {
width: 104rpx; width: 140rpx;
height: 104rpx; height: 140rpx;
border-radius: 50%; background: var(--ui-BG);
} border-radius: 50%;
} position: absolute;
top: -70rpx;
left: 50%;
z-index: 6;
transform: translateX(-50%);
.top { .tag-image {
background-color: #fff; width: 104rpx;
border-radius: 20rpx 20rpx 0 0; height: 104rpx;
-webkit-mask: radial-gradient(circle at 16rpx 100%, #0000 16rpx, red 0) -16rpx; border-radius: 50%;
padding: 110rpx 0 0 0; }
position: relative; }
z-index: 5;
.title { .top {
font-size: 40rpx; background-color: #fff;
color: #333; border-radius: 20rpx 20rpx 0 0;
font-weight: bold; -webkit-mask: radial-gradient(circle at 16rpx 100%, #0000 16rpx, red 0) -16rpx;
} padding: 110rpx 0 0 0;
position: relative;
z-index: 5;
.subtitle { .title {
font-size: 28rpx; font-size: 40rpx;
color: #333333; color: #333;
} font-weight: bold;
}
.use-btn { .subtitle {
width: 386rpx; font-size: 28rpx;
height: 80rpx; color: #333333;
line-height: 80rpx; }
background: linear-gradient(90deg, var(--ui-BG-Main), var(--ui-BG-Main-gradient));
border-radius: 40rpx;
color: $white;
}
.disable-btn { .use-btn {
width: 386rpx; width: 386rpx;
height: 80rpx; height: 80rpx;
line-height: 80rpx; line-height: 80rpx;
background: #e5e5e5; background: linear-gradient(90deg, var(--ui-BG-Main), var(--ui-BG-Main-gradient));
border-radius: 40rpx; border-radius: 40rpx;
color: $white; color: $white;
} }
.time { .disable-btn {
font-size: 26rpx; width: 386rpx;
font-weight: 400; height: 80rpx;
color: #999999; line-height: 80rpx;
} background: #e5e5e5;
border-radius: 40rpx;
color: $white;
}
.coupon-line { .time {
width: 95%; font-size: 26rpx;
border-bottom: 2rpx solid #eeeeee; font-weight: 400;
} color: #999999;
} }
.bottom { .coupon-line {
background-color: #fff; width: 95%;
border-radius: 0 0 20rpx 20rpx; border-bottom: 2rpx solid #eeeeee;
-webkit-mask: radial-gradient(circle at 16rpx 0%, #0000 16rpx, red 0) -16rpx; }
padding: 40rpx 30rpx; }
.type { .bottom {
height: 96rpx; background-color: #fff;
border-bottom: 2rpx solid #eeeeee; border-radius: 0 0 20rpx 20rpx;
} -webkit-mask: radial-gradient(circle at 16rpx 0%, #0000 16rpx, red 0) -16rpx;
} padding: 40rpx 30rpx;
.des { .type {
font-size: 24rpx; height: 96rpx;
font-weight: 400; border-bottom: 2rpx solid #eeeeee;
color: #666666; }
} }
}
.all-user { .des {
width: 100%; font-size: 24rpx;
height: 300rpx; font-weight: 400;
font-size: 34rpx; color: #666666;
font-weight: bold; }
color: #333333; }
}
</style> .all-user {
width: 100%;
height: 300rpx;
font-size: 34rpx;
font-weight: bold;
color: #333333;
}
</style>

View File

@ -7,12 +7,11 @@
<s-empty v-if="state.pagination.total === 0" icon="/static/coupon-empty.png" text="暂无优惠券"></s-empty> <s-empty v-if="state.pagination.total === 0" icon="/static/coupon-empty.png" text="暂无优惠券"></s-empty>
<template v-if="state.currentTab == '0'"> <template v-if="state.currentTab == '0'">
<view v-for="item in state.pagination.list" :key="item.id"> <view v-for="item in state.pagination.list" :key="item.id">
<s-coupon-list :data="item"> <s-coupon-list :data="item" @tap="
<!-- @tap=" sheep.$router.go('/pages/coupon/detail', {
sheep.$router.go('/pages/coupon/detail', { data: JSON.stringify(item),
id: item.id, })">
})
" -->
<template #default> <template #default>
<button class="ss-reset-button card-btn ss-flex ss-row-center ss-col-center" <button class="ss-reset-button card-btn ss-flex ss-row-center ss-col-center"
:class="item.get_status != 'can_get' ? 'border-btn' : ''" @click.stop="getBuy(item.id)" :class="item.get_status != 'can_get' ? 'border-btn' : ''" @click.stop="getBuy(item.id)"
@ -26,12 +25,12 @@
</template> </template>
<template v-else> <template v-else>
<view v-for="item in state.pagination.list" :key="item.id"> <view v-for="item in state.pagination.list" :key="item.id">
<s-coupon-list :data="item" type="user"> <s-coupon-list :data="item" type="user" @tap="
<!-- @tap="
sheep.$router.go('/pages/coupon/detail', { sheep.$router.go('/pages/coupon/detail', {
id: item.id, data: JSON.stringify(item),
}) })
" --> ">
<template #default> <template #default>
<button class="ss-reset-button card-btn ss-flex ss-row-center ss-col-center" :class=" <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'
@ -148,19 +147,14 @@
}); });
if (res.code === 0) { if (res.code === 0) {
// //
let obj2 = {
2: '折扣',
1: '满减'
}
let obj = { let obj = {
1: '可用', 1: '可用',
2: '已用', 2: '已用',
3: '过期' 3: '过期'
} }
let obj3 = { let obj2 = {
1: '已领取', 1: '满减',
2: '已使用', 2: '折扣'
3: '已过期'
} }
res.data.list = res.data.list.map(item => { res.data.list = res.data.list.map(item => {
return { return {

View File

@ -3,35 +3,34 @@
<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>
<view class="commont-from-wrap"> <view class="commont-from-wrap">
<!-- 评价商品 --> <!-- 评价商品 -->
<s-goods-item :img="item.goods_image" :title="item.goods_title" :skuText="item.goods_sku_text" <s-goods-item
:price="item.goods_price" :num="item.goods_num"></s-goods-item> :img="item.picUrl"
:title="item.spuName"
:skuText="item.properties.map((property) => property.valueName).join(' ')"
:price="item.payPrice"
:num="item.count"
/>
</view> </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">商品质量</view>
<!-- {{ rateMap[state.commentList[index].level] }} --> <uni-rate v-model="state.commentList[index].descriptionScores" />
商品质量
</view>
<uni-rate v-model="state.commentList[index].level" />
</view> </view>
<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">服务态度</view>
<!-- {{ rateMap[state.commentList[index].level] }} --> <uni-rate v-model="state.commentList[index].benefitScores" />
服务态度
</view>
<uni-rate v-model="state.commentList[index].level2" />
</view> </view>
<!-- 评价 --> <!-- 评价 -->
<view class="area-box"> <view class="area-box">
<uni-easyinput :inputBorder="false" type="textarea" maxlength="120" autoHeight <uni-easyinput :inputBorder="false" type="textarea" maxlength="120" autoHeight
v-model="state.commentList[index].content" v-model="state.commentList[index].content"
placeholder="宝贝满足你的期待吗?说说你的使用心得,分享给想买的他们吧~"></uni-easyinput> placeholder="宝贝满足你的期待吗?说说你的使用心得,分享给想买的他们吧~" />
<!-- TODO 芋艿文件上传 -->
<view class="img-box"> <view class="img-box">
<s-uploader v-model:url="state.commentList[index].images" fileMediatype="image" <s-uploader v-model:url="state.commentList[index].images" fileMediatype="image"
limit="9" mode="grid" :imageStyles="{ width: '168rpx', height: '168rpx' }" /> limit="9" mode="grid" :imageStyles="{ width: '168rpx', height: '168rpx' }" />
@ -41,6 +40,7 @@
</view> </view>
</view> </view>
</view> </view>
<!-- TODO 芋艿是否匿名 -->
<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">
@ -54,113 +54,49 @@
<script setup> <script setup>
import sheep from '@/sheep'; import sheep from '@/sheep';
import { import { onLoad } from '@dcloudio/uni-app';
onLoad import { reactive } from 'vue';
} from '@dcloudio/uni-app'; import OrderApi from '@/sheep/api/trade/order';
import {
computed,
reactive
} from 'vue';
const state = reactive({ const state = reactive({
orderInfo: {}, orderInfo: {},
commentList: [], commentList: [],
orderId: null id: null
}); });
const rateMap = {
1: '糟糕',
2: '差评',
3: '一般',
4: '良好',
5: '好评',
};
async function onSubmit() { async function onSubmit() {
// //
// console.log(state.orderInfo); for (const comment of state.commentList) {
// return; await OrderApi.createOrderItemComment(comment);
let obj = { }
anonymous: false, //
benefitScores: state.commentList[0].level2, sheep.$router.back();
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 = ''; if (!options.id) {
if (options.orderSN) { sheep.$helper.toast(`缺少订单信息,请检查`);
id = options.orderSN; return
} }
if (options.id) { state.id = options.id;
id = options.id;
}
if (options.orderId) {
state.orderId = options.orderId
}
const res = await sheep.$api.order.detail(id); const { code, data } = await sheep.$api.order.detail(state.id);
if (res.code === 0) { if (code !== 0) {
let obj = { sheep.$helper.toast('无待评价订单');
10: ['待发货', '等待买家付款', ["apply_refund"]], return
30: ['待评价', '等待买家评价', ["express", "comment"]] }
} //
data.items.forEach((item) => {
res.data.status_text = obj[res.data.status][0]; state.commentList.push({
res.data.status_desc = obj[res.data.status][1]; anonymous: false,
res.data.btns = obj[res.data.status][2]; orderItemId: item.id,
res.data.address = { descriptionScores: 5,
province_name: res.data.receiverAreaName.split(' ')[0], benefitScores: 5,
district_name: res.data.receiverAreaName.split(' ')[2], content: '',
city_name: res.data.receiverAreaName.split(' ')[1], picUrls: []
address: res.data.receiverDetailAddress, });
consignee: res.data.receiverName, });
mobile: res.data.receiverMobile, state.orderInfo = data;
}
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>

View File

@ -1,165 +1,169 @@
<!-- 商品详情的底部导航 -->
<template> <template>
<su-fixed bottom placeholder bg="bg-white"> <su-fixed bottom placeholder bg="bg-white">
<view class="ui-tabbar-box"> <view class="ui-tabbar-box">
<view class="ui-tabbar ss-flex ss-col-center ss-row-between"> <view class="ui-tabbar ss-flex ss-col-center ss-row-between">
<view v-if="collectIcon" class="detail-tabbar-item ss-flex ss-flex-col ss-row-center ss-col-center" <view
@tap="onFavorite"> v-if="collectIcon"
<block v-if="modelValue.favorite"> class="detail-tabbar-item ss-flex ss-flex-col ss-row-center ss-col-center"
<image class="item-icon" :src="sheep.$url.static('/static/img/shop/goods/collect_1.gif')" @tap="onFavorite"
mode="aspectFit"></image> >
<view class="item-title">已收藏</view> <block v-if="modelValue.favorite">
</block> <image
<block v-else> class="item-icon"
<image class="item-icon" :src="sheep.$url.static('/static/img/shop/goods/collect_0.png')" :src="sheep.$url.static('/static/img/shop/goods/collect_1.gif')"
mode="aspectFit"></image> mode="aspectFit"
<view class="item-title">收藏</view> />
</block> <view class="item-title">已收藏</view>
</view> </block>
<view v-if="serviceIcon" class="detail-tabbar-item ss-flex ss-flex-col ss-row-center ss-col-center" <block v-else>
@tap="onChat"> <image
<image class="item-icon" :src="sheep.$url.static('/static/img/shop/goods/message.png')" class="item-icon"
mode="aspectFit"></image> :src="sheep.$url.static('/static/img/shop/goods/collect_0.png')"
<view class="item-title">客服</view> mode="aspectFit"
</view> />
<view v-if="shareIcon" class="detail-tabbar-item ss-flex ss-flex-col ss-row-center ss-col-center" <view class="item-title">收藏</view>
@tap="showShareModal"> </block>
<image class="item-icon" :src="sheep.$url.static('/static/img/shop/goods/share.png')" </view>
mode="aspectFit"></image> <view
<view class="item-title">分享</view> v-if="serviceIcon"
</view> class="detail-tabbar-item ss-flex ss-flex-col ss-row-center ss-col-center"
<slot></slot> @tap="onChat"
</view> >
</view> <image
</su-fixed> class="item-icon"
:src="sheep.$url.static('/static/img/shop/goods/message.png')"
mode="aspectFit"
/>
<view class="item-title">客服</view>
</view>
<view
v-if="shareIcon"
class="detail-tabbar-item ss-flex ss-flex-col ss-row-center ss-col-center"
@tap="showShareModal"
>
<image
class="item-icon"
:src="sheep.$url.static('/static/img/shop/goods/share.png')"
mode="aspectFit"
/>
<view class="item-title">分享</view>
</view>
<slot></slot>
</view>
</view>
</su-fixed>
</template> </template>
<script setup> <script setup>
/** /**
* *
* 底部导航 * 底部导航
* *
* @property {String} bg - 背景颜色Class * @property {String} bg - 背景颜色Class
* @property {String} ui - 自定义样式Class * @property {String} ui - 自定义样式Class
* @property {Boolean} noFixed - 是否定位 * @property {Boolean} noFixed - 是否定位
* @property {Boolean} topRadius - 上圆角 * @property {Boolean} topRadius - 上圆角
* */
* import { reactive } from 'vue';
*/ import sheep from '@/sheep';
import { showShareModal } from '@/sheep/hooks/useModal';
import FavoriteApi from '@/sheep/api/product/favorite';
import { //
computed, const state = reactive({});
reactive
} from 'vue';
import sheep from '@/sheep';
import {
showShareModal
} from '@/sheep/hooks/useModal';
// //
const state = reactive({}); const props = defineProps({
modelValue: {
type: Object,
default() {},
},
bg: {
type: String,
default: 'bg-white',
},
bgStyles: {
type: Object,
default() {},
},
ui: {
type: String,
default: '',
},
// noFixed: {
const props = defineProps({ type: Boolean,
modelValue: { default: false,
type: Object, },
default () {}, topRadius: {
}, type: Number,
bg: { default: 0,
type: String, },
default: 'bg-white', collectIcon: {
}, type: Boolean,
bgStyles: { default: true,
type: Object, },
default () {}, serviceIcon: {
}, type: Boolean,
ui: { default: true,
type: String, },
default: '', shareIcon: {
}, type: Boolean,
default: true,
},
});
noFixed: { async function onFavorite() {
type: Boolean, //
default: false, if (props.modelValue.favorite) {
}, const { code } = await FavoriteApi.deleteFavorite(props.modelValue.id);
topRadius: { if (code !== 0) {
type: Number, return
default: 0, }
}, sheep.$helper.toast('取消收藏');
collectIcon: { props.modelValue.favorite = false;
type: Boolean, //
default: true, } else {
}, const { code } = await FavoriteApi.createFavorite(props.modelValue.id);
serviceIcon: { if (code !== 0) {
type: Boolean, return
default: true, }
}, sheep.$helper.toast('收藏成功');
shareIcon: { props.modelValue.favorite = true;
type: Boolean, }
default: true, }
},
});
const elStyles = computed(() => {
return {
'border-top-left-radius': props.topRadius + 'rpx',
'border-top-right-radius': props.topRadius + 'rpx',
overflow: 'hidden',
};
});
const tabbarheight = (e) => { const onChat = () => {
uni.setStorageSync('tabbar', e); sheep.$router.go('/pages/chat/index', {
}; id: props.modelValue.id,
async function onFavorite() { });
// const { error } = await sheep.$api.user.favorite.do(props.modelValue.id); };
// if (error === 0) {
// if (props.modelValue.favorite) {
// props.modelValue.favorite = 0;
// } else {
// props.modelValue.favorite = 1;
// }
// }
let data;
if (props.modelValue.favorite) {
data = await sheep.$api.user.favorite.dos(props.modelValue.id);
} else {
data = await sheep.$api.user.favorite.do(props.modelValue.id);
}
if (data.data) {
props.modelValue.favorite = !props.modelValue.favorite;
}
}
const onChat = () => {
sheep.$router.go('/pages/chat/index', {
id: props.modelValue.id,
});
};
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.ui-tabbar-box { .ui-tabbar-box {
box-shadow: 0px -6px 10px 0px rgba(51, 51, 51, 0.2); box-shadow: 0px -6px 10px 0px rgba(51, 51, 51, 0.2);
} }
.ui-tabbar {
display: flex;
height: 50px;
background: #fff;
.ui-tabbar { .detail-tabbar-item {
display: flex; width: 100rpx;
height: 50px;
background: #fff;
.detail-tabbar-item { .item-icon {
width: 100rpx; width: 40rpx;
height: 40rpx;
}
.item-icon { .item-title {
width: 40rpx; font-size: 20rpx;
height: 40rpx; font-weight: 500;
} line-height: 20rpx;
margin-top: 12rpx;
.item-title { }
font-size: 20rpx; }
font-weight: 500; }
line-height: 20rpx; </style>
margin-top: 12rpx;
}
}
}
</style>

View File

@ -12,7 +12,9 @@
<block v-else> <block v-else>
<view class="detail-swiper-selector"> <view class="detail-swiper-selector">
<!-- 商品轮播图 --> <!-- 商品轮播图 -->
<su-swiper class="ss-m-b-14" isPreview :list="formatGoodsSwiper(state.goodsInfo.sliderPicUrls)" dotStyle="tag" imageMode="widthFix" dotCur="bg-mask-40" :seizeHeight="750" /> <su-swiper class="ss-m-b-14" isPreview :list="formatGoodsSwiper(state.goodsInfo.sliderPicUrls)"
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">
@ -31,14 +33,14 @@
<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">
<!-- 满减送/限时折扣活动的提示 TODO 芋艿promos 未写 --> <!-- 满减送/限时折扣活动的提示 TODO 芋艿promos 未写 -->
<div class="tag-content"> <div class="tag-content">
<!-- 满减送/限时折扣活动的提示 TODO 芋艿promos 未写 -->
<div class="tag-content">
<view class="tag-box ss-flex"> <view class="tag-box ss-flex">
<view class="tag ss-m-r-10" v-for="promos in state.goodsInfo.promos" :key="promos.id" @tap="onActivity"> <view class="tag ss-m-r-10" v-for="promos in state.goodsInfo.promos"
:key="promos.id" @tap="onActivity">
{{ promos.title }} {{ promos.title }}
</view> </view>
</view> </view>
</div> </div>
<!-- 优惠劵 --> <!-- 优惠劵 -->
<view class="get-coupon-box ss-flex ss-col-center ss-m-l-20" @tap="state.showModel = true" <view class="get-coupon-box ss-flex ss-col-center ss-m-l-20" @tap="state.showModel = true"
v-if="state.couponInfo.length"> v-if="state.couponInfo.length">
@ -61,7 +63,7 @@
<!-- 规格与数量弹框 --> <!-- 规格与数量弹框 -->
<s-select-sku :goodsInfo="state.goodsInfo" :show="state.showSelectSku" @addCart="onAddCart" <s-select-sku :goodsInfo="state.goodsInfo" :show="state.showSelectSku" @addCart="onAddCart"
@buy="onBuy" @change="onSkuChange" @close="state.showSelectSku = false" /> @buy="onBuy" @change="onSkuChange" @close="state.showSelectSku = false" />
</view> </view>
<!-- 评价 --> <!-- 评价 -->
@ -86,13 +88,12 @@
<button class="ss-reset-button disabled-btn" disabled> 已售罄 </button> <button class="ss-reset-button disabled-btn" disabled> 已售罄 </button>
</view> </view>
</detail-tabbar> </detail-tabbar>
<!-- 优惠劵弹窗 --> <!-- 优惠劵弹窗 -->
<s-coupon-get v-model="state.couponInfo" :show="state.showModel" @close="state.showModel = false" @get="onGet" /> <s-coupon-get v-model="state.couponInfo" :show="state.showModel" @close="state.showModel = false"
@get="onGet" />
<!-- 满减送/限时折扣活动弹窗 --> <!-- 满减送/限时折扣活动弹窗 -->
<!-- 优惠劵弹窗 -->
<s-coupon-get v-model="state.couponInfo" :show="state.showModel" @close="state.showModel = false" @get="onGet" />
<!-- 满减送/限时折扣活动弹窗 -->
<s-activity-pop v-model="state.activityInfo" :show="state.showActivityModel" <s-activity-pop v-model="state.activityInfo" :show="state.showActivityModel"
@close="state.showActivityModel = false" /> @close="state.showActivityModel = false" />
</block> </block>
@ -101,19 +102,23 @@
</template> </template>
<script setup> <script setup>
import { reactive, computed } from 'vue'; import {
import { onLoad, onPageScroll } from '@dcloudio/uni-app'; reactive,
computed
} from 'vue';
import {
onLoad,
onPageScroll
} from '@dcloudio/uni-app';
import sheep from '@/sheep'; import sheep from '@/sheep';
import CouponApi from '@/sheep/api/promotion/coupon'; import CouponApi from '@/sheep/api/promotion/coupon';
import ActivityApi from '@/sheep/api/promotion/activity'; import ActivityApi from '@/sheep/api/promotion/activity';
import { import FavoriteApi from '@/sheep/api/product/favorite';
import {
formatSales, formatSales,
formatGoodsSwiper, formatGoodsSwiper,
fen2yuan, fen2yuan,
} from '@/sheep/hooks/useGoods'; } from '@/sheep/hooks/useGoods';
import CouponApi from '@/sheep/api/promotion/coupon';
import ActivityApi from '@/sheep/api/promotion/activity';
import { formatSales, formatGoodsSwiper, fen2yuan, } from '@/sheep/hooks/useGoods';
import detailNavbar from './components/detail/detail-navbar.vue'; import detailNavbar from './components/detail/detail-navbar.vue';
import detailCellSku from './components/detail/detail-cell-sku.vue'; import detailCellSku from './components/detail/detail-cell-sku.vue';
import detailCellService from './components/detail/detail-cell-service.vue'; import detailCellService from './components/detail/detail-cell-service.vue';
@ -138,7 +143,7 @@
showActivityModel: false, // / Activity showActivityModel: false, // / Activity
activityInfo: [], // / Activity activityInfo: [], // / Activity
activityList: [], // // Activity activityList: [], // // Activity
}); });
// //
function onSkuChange(e) { function onSkuChange(e) {
@ -147,22 +152,30 @@
// TODO // TODO
function onAddCart(e) { function onAddCart(e) {
console.log(e, '加入购物车'); if (!e.id) {
sheep.$helper.toast('请选择商品规格');
return;
}
sheep.$store('cart').add(e); sheep.$store('cart').add(e);
} }
// TODO //
function onBuy(e) { function onBuy(e) {
sheep.$router.go('/pages/order/confirm', { if (!state.selectedSku.id) {
data: JSON.stringify({ sheep.$helper.toast('请选择商品规格');
order_type: 'goods', return;
goods_list: [{ }
goods_id: e.goods_id, sheep.$router.go('/pages/order/confirm', {
goods_num: e.goods_num, data: JSON.stringify({
goods_sku_price_id: e.id, items: [{
}, ], skuId: state.selectedSku.id,
}), count: 1
}); }],
// TODO 2
deliveryType: 1,
pointStatus: false,
}),
});
} }
// TODO // TODO
@ -174,10 +187,10 @@
// TODO // TODO
async function onGet(id) { async function onGet(id) {
const { const {
code, error,
msg msg
} = await sheep.$api.coupon.get(id); } = await sheep.$api.coupon.get(id);
if (code === 0) { if (error === 0) {
uni.showToast({ uni.showToast({
title: msg, title: msg,
}); });
@ -187,8 +200,7 @@
} }
} }
// TODO // TODO
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({
@ -202,8 +214,9 @@
}, { }, {
type: 'goods', // type: 'goods', //
title: state.goodsInfo.name, // title: state.goodsInfo.name, //
image: sheep.$url.cdn(state.goodsInfo.image), // // image: sheep.$url.cdn(state.goodsInfo.image), //
price: state.goodsInfo.price[0], // image: sheep.$url.cdn(state.goodsInfo.picUrl), //
price: state.goodsInfo.price, //
original_price: state.goodsInfo.original_price, // original_price: state.goodsInfo.original_price, //
}, ); }, );
}); });
@ -216,7 +229,7 @@
} }
state.goodsId = options.id; state.goodsId = options.id;
// 1. // 1.
sheep.$api.goods.detail(state.goodsId).then(async (res) => { sheep.$api.goods.detail(state.goodsId).then((res) => {
// //
if (res.code !== 0 || !res.data) { if (res.code !== 0 || !res.data) {
state.goodsInfo = null; state.goodsInfo = null;
@ -224,60 +237,25 @@
} }
// //
state.skeletonLoading = false; state.skeletonLoading = false;
//
let dasa = await sheep.$api.goods.exits(options.id);
res.data.favorite = dasa.data;
state.goodsInfo = res.data; state.goodsInfo = res.data;
console.log(state.goodsInfo, '商品信息');
// //
// 2. FavoriteApi.isFavoriteExists(state.goodsId, 'goods').then((res) => {
CouponApi.getCouponTemplateList({ if (res.code !== 0) {
price: state.goodsInfo.price, return;
spuIds: [state.goodsInfo.id], }
skuIds: state.goodsInfo.skus.map(item => item.id), state.goodsInfo.favorite = res.data;
// });
categoryIds: [52]
}).then((res) => {
console.log(res, '优惠券信息进行对接')
if (res.code !== 0) {
return;
}
//
let obj2 = {
2: '折扣',
1: '满减'
}
let obj = {
1: '可用',
2: '已用',
3: '过期'
}
let obj3 = {
1: '已领取',
2: '已使用',
3: '已过期'
}
res.data = res.data.map(item => {
return {
...item,
enough: (item.usePrice / 100).toFixed(2),
amount: (item.discountPrice / 100).toFixed(2),
use_start_time: sheep.$helper.timeFormat(item
.validStartTime,
'yyyy-mm-dd hh:MM:ss'),
use_end_time: sheep.$helper.timeFormat(item.validEndTime,
'yyyy-mm-dd hh:MM:ss'),
status_text: obj[item.status],
type_text: obj2[item.discountType],
get_status_text: obj3[item.status],
type_text: obj2[item.discountType]
}
});
state.couponInfo = res.data;
});
}); });
// return;
// 2.
CouponApi.getCouponTemplateList(state.goodsId, 2, 10).then((res) => {
if (res.code !== 0) {
return;
}
state.couponInfo = res.data;
});
// 3. // 3.
ActivityApi.getActivityListBySpuId(state.goodsId).then((res) => { ActivityApi.getActivityListBySpuId(state.goodsId).then((res) => {
if (res.code !== 0) { if (res.code !== 0) {
@ -285,32 +263,6 @@
} }
state.activityList = res.data; state.activityList = res.data;
}); });
sheep.$api.goods.detail(state.goodsId).then((res) => {
//
if (res.code !== 0 || !res.data) {
state.goodsInfo = null;
return;
}
//
state.skeletonLoading = false;
state.goodsInfo = res.data;
});
// 2.
CouponApi.getCouponTemplateList(state.goodsId,2, 10).then((res) => {
if (res.code !== 0) {
return;
}
state.couponInfo = res.data;
});
// 3.
ActivityApi.getActivityListBySpuId(state.goodsId).then((res) => {
if (res.code !== 0) {
return;
}
state.activityList = res.data;
});
}); });
</script> </script>

View File

@ -1,383 +1,352 @@
<template> <template>
<s-layout <s-layout navbar="normal" :leftWidth="0" :rightWidth="0" tools="search" :defaultSearch="state.keyword"
navbar="normal" @search="onSearch">
:leftWidth="0" <!-- 筛选 -->
:rightWidth="0" <su-sticky bgColor="#fff">
tools="search" <view class="ss-flex">
:defaultSearch="state.keyword" <view class="ss-flex-1">
@search="onSearch" <su-tabs :list="state.tabList" :scrollable="false" @change="onTabsChange"
> :current="state.currentTab"></su-tabs>
<!-- 筛选 --> </view>
<su-sticky bgColor="#fff"> <view class="list-icon" @tap="state.iconStatus = !state.iconStatus">
<view class="ss-flex"> <text v-if="state.iconStatus" class="sicon-goods-list"></text>
<view class="ss-flex-1"> <text v-else class="sicon-goods-card"></text>
<su-tabs </view>
:list="state.tabList" </view>
:scrollable="false" </su-sticky>
@change="onTabsChange"
:current="state.currentTab"
></su-tabs>
</view>
<view class="list-icon" @tap="state.iconStatus = !state.iconStatus">
<text v-if="state.iconStatus" class="sicon-goods-list"></text>
<text v-else class="sicon-goods-card"></text>
</view>
</view>
</su-sticky>
<!-- 弹窗 --> <!-- 弹窗 -->
<su-popup <su-popup :show="state.showFilter" type="top" round="10" :space="sys_navBar + 38" backgroundColor="#F6F6F6"
:show="state.showFilter" :zIndex="10" @close="state.showFilter = false">
type="top" <view class="filter-list-box">
round="10" <view class="filter-item" v-for="(item, index) in state.tabList[state.currentTab].list"
:space="sys_navBar + 38" :key="item.value" :class="[{ 'filter-item-active': index == state.curFilter }]"
backgroundColor="#F6F6F6" @tap="onFilterItem(index)">
:zIndex="10" {{ item.label }}
@close="state.showFilter = false" </view>
> </view>
<view class="filter-list-box"> </su-popup>
<view <view v-if="state.iconStatus && state.pagination.total > 0" class="goods-list ss-m-t-20">
class="filter-item" <view class="ss-p-l-20 ss-p-r-20 ss-m-b-20" v-for="item in state.pagination.data" :key="item.id">
v-for="(item, index) in state.tabList[state.currentTab].list" <s-goods-column class="" size="lg" :data="item" :topRadius="10" :bottomRadius="10"
:key="item.value" @click="sheep.$router.go('/pages/goods/index', { id: item.id })"></s-goods-column>
:class="[{ 'filter-item-active': index == state.curFilter }]" </view>
@tap="onFilterItem(index)" </view>
> <view v-if="!state.iconStatus && state.pagination.total > 0"
{{ item.label }} class="ss-flex ss-flex-wrap ss-p-x-20 ss-m-t-20 ss-col-top">
</view> <view class="goods-list-box">
</view> <view class="left-list" v-for="item in state.leftGoodsList" :key="item.id">
</su-popup> <s-goods-column class="goods-md-box" size="md" :data="item" :topRadius="10" :bottomRadius="10"
<view v-if="state.iconStatus && state.pagination.total > 0" class="goods-list ss-m-t-20"> @click="sheep.$router.go('/pages/goods/index', { id: item.id })"
<view @getHeight="mountMasonry($event, 'left')">
class="ss-p-l-20 ss-p-r-20 ss-m-b-20" <template v-slot:cart>
v-for="item in state.pagination.data" <button class="ss-reset-button cart-btn"> </button>
:key="item.id" </template>
> </s-goods-column>
<s-goods-column </view>
class="" </view>
size="lg" <view class="goods-list-box">
:data="item" <view class="right-list" v-for="item in state.rightGoodsList" :key="item.id">
:topRadius="10" <s-goods-column class="goods-md-box" size="md" :topRadius="10" :bottomRadius="10" :data="item"
:bottomRadius="10" @click="sheep.$router.go('/pages/goods/index', { id: item.id })"
@click="sheep.$router.go('/pages/goods/index', { id: item.id })" @getHeight="mountMasonry($event, 'right')">
></s-goods-column> <template v-slot:cart>
</view> <button class="ss-reset-button cart-btn"> </button>
</view> </template>
<view </s-goods-column>
v-if="!state.iconStatus && state.pagination.total > 0" </view>
class="ss-flex ss-flex-wrap ss-p-x-20 ss-m-t-20 ss-col-top" </view>
> </view>
<view class="goods-list-box"> <uni-load-more v-if="state.pagination.total > 0" :status="state.loadStatus" :content-text="{
<view class="left-list" v-for="item in state.leftGoodsList" :key="item.id">
<s-goods-column
class="goods-md-box"
size="md"
:data="item"
:topRadius="10"
:bottomRadius="10"
@click="sheep.$router.go('/pages/goods/index', { id: item.id })"
@getHeight="mountMasonry($event, 'left')"
>
<template v-slot:cart>
<button class="ss-reset-button cart-btn"> </button>
</template>
</s-goods-column>
</view>
</view>
<view class="goods-list-box">
<view class="right-list" v-for="item in state.rightGoodsList" :key="item.id">
<s-goods-column
class="goods-md-box"
size="md"
:topRadius="10"
:bottomRadius="10"
:data="item"
@click="sheep.$router.go('/pages/goods/index', { id: item.id })"
@getHeight="mountMasonry($event, 'right')"
>
<template v-slot:cart>
<button class="ss-reset-button cart-btn"> </button>
</template>
</s-goods-column>
</view>
</view>
</view>
<uni-load-more
v-if="state.pagination.total > 0"
:status="state.loadStatus"
:content-text="{
contentdown: '上拉加载更多', contentdown: '上拉加载更多',
}" }" @tap="loadmore" />
@tap="loadmore" <s-empty v-if="state.pagination.total === 0" icon="/static/soldout-empty.png" text="暂无商品">
/> </s-empty>
<s-empty v-if="state.pagination.total === 0" icon="/static/soldout-empty.png" text="暂无商品"> </s-layout>
</s-empty>
</s-layout>
</template> </template>
<script setup> <script setup>
import { reactive } from 'vue'; import {
import { onLoad, onReachBottom } from '@dcloudio/uni-app'; reactive
import sheep from '@/sheep'; } from 'vue';
import _ from 'lodash'; import {
onLoad,
onReachBottom
} from '@dcloudio/uni-app';
import sheep from '@/sheep';
import _ from 'lodash';
const sys_navBar = sheep.$platform.navbar; const sys_navBar = sheep.$platform.navbar;
const emits = defineEmits(['close', 'change']); const emits = defineEmits(['close', 'change']);
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({
pagination: { pagination: {
data: [], data: [],
current_page: 1, current_page: 1,
total: 1, total: 1,
last_page: 1, last_page: 1,
}, },
// currentSort: 'weigh', // currentSort: 'weigh',
// currentOrder: 'desc', // currentOrder: 'desc',
currentTab: 0, currentTab: 0,
filterParams: {}, filterParams: {},
curFilter: 0, curFilter: 0,
showFilter: false, showFilter: false,
iconStatus: false, iconStatus: false,
categoryId: 0, categoryId: 0,
tabList: [ tabList: [{
{ name: '综合推荐',
name: '综合推荐', // value: '',
// value: '', list: [{
list: [ label: '综合推荐',
{ // sort: '',
label: '综合推荐', // order: true,
// sort: '', },
// order: true, {
}, label: '价格升序',
{ sort: 'price',
label: '价格升序', order: true,
sort: 'price', },
order: true, {
}, label: '价格降序',
{ sort: 'price',
label: '价格降序', order: false,
sort: 'price', },
order: false, ],
}, },
], {
}, name: '销量',
{ sort: 'salesCount',
name: '销量', order: false,
// value: 'salesCount', // value: 'salesCount',
}, },
{ {
name: '新品优先', name: '新品优先',
// value: 'create_time', // value: 'create_time',
}, },
], ],
loadStatus: '', loadStatus: '',
keyword: '', keyword: '',
leftGoodsList: [], leftGoodsList: [],
rightGoodsList: [], rightGoodsList: [],
}); });
// //
let count = 0; let count = 0;
let leftHeight = 0; let leftHeight = 0;
let rightHeight = 0; let rightHeight = 0;
function mountMasonry(height = 0, where = 'left') { function mountMasonry(height = 0, where = 'left') {
if (!state.pagination.data[count]) return; if (!state.pagination.data[count]) return;
if (where === 'left') { if (where === 'left') {
leftHeight += height; leftHeight += height;
} else { } else {
rightHeight += height; rightHeight += height;
} }
if (leftHeight <= rightHeight) { if (leftHeight <= rightHeight) {
state.leftGoodsList.push(state.pagination.data[count]); state.leftGoodsList.push(state.pagination.data[count]);
} else { } else {
state.rightGoodsList.push(state.pagination.data[count]); state.rightGoodsList.push(state.pagination.data[count]);
} }
count++; count++;
} }
function emptyList() { function emptyList() {
state.pagination = pagination state.pagination = pagination
state.leftGoodsList = []; state.leftGoodsList = [];
state.rightGoodsList = []; state.rightGoodsList = [];
count = 0; count = 0;
leftHeight = 0; leftHeight = 0;
rightHeight = 0; rightHeight = 0;
} }
// //
function onSearch(e) { function onSearch(e) {
state.keyword = e; state.keyword = e;
emptyList(); emptyList();
getList(state.currentSort, state.currentOrder, state.categoryId, e); getList(state.currentSort, state.currentOrder, state.categoryId, e);
} }
// //
function onTabsChange(e) { function onTabsChange(e) {
if (state.tabList[e.index].list) { if (state.tabList[e.index].list) {
state.currentTab = e.index; state.currentTab = e.index;
state.showFilter = !state.showFilter; state.showFilter = !state.showFilter;
return; return;
} else { } else {
state.showFilter = false; state.showFilter = false;
} }
if (e.index === state.currentTab) { if (e.index === state.currentTab) {
return; return;
} else { } else {
state.currentTab = e.index; state.currentTab = e.index;
} }
emptyList(); emptyList();
console.log(e, '6666')
getList(e.sort, e.order, state.categoryId, state.keyword);
}
getList(e.value, state.currentOrder, state.categoryId, state.keyword); //
} const onFilterItem = (val) => {
console.log(val)
if (
state.currentSort === state.tabList[0].list[val].sort &&
state.currentOrder === state.tabList[0].list[val].order
) {
state.showFilter = false;
return;
}
state.curFilter = val;
state.tabList[0].name = state.tabList[0].list[val].label;
state.currentSort = state.tabList[0].list[val].sort;
state.currentOrder = state.tabList[0].list[val].order;
emptyList();
getList(state.currentSort, state.currentOrder, state.categoryId, state.keyword);
state.showFilter = false;
};
// async function getList(Sort, Order, categoryId, keyword, page = 1, list_rows = 6) {
const onFilterItem = (val) => { state.loadStatus = 'loading';
console.log(val) const res = await sheep.$api.goods.list({
if ( sortField: Sort,
state.currentSort === state.tabList[0].list[val].sort && sortAsc: Order,
state.currentOrder === state.tabList[0].list[val].order category_id: !keyword ? categoryId : '',
) { pageSize: list_rows,
state.showFilter = false; keyword: keyword,
return; pageNo: page,
} });
state.curFilter = val; if (res.code === 0) {
state.tabList[0].name = state.tabList[0].list[val].label; let couponList = _.concat(state.pagination.data, res.data.list);
state.currentSort = state.tabList[0].list[val].sort; state.pagination = {
state.currentOrder = state.tabList[0].list[val].order; ...res.data,
emptyList(); data: couponList,
getList(state.currentSort, state.currentOrder, state.categoryId, state.keyword); };
state.showFilter = false; mountMasonry();
}; if (state.pagination.current_page < state.pagination.last_page) {
state.loadStatus = 'more';
async function getList(Sort, Order, categoryId, keyword, page = 1, list_rows = 6) { } else {
state.loadStatus = 'loading'; state.loadStatus = 'noMore';
const res = await sheep.$api.goods.list({ }
sortField: Sort, }
sortAsc: Order, }
category_id: !keyword ? categoryId : '', //
pageSize:list_rows, function loadmore() {
keyword: keyword, if (state.loadStatus !== 'noMore') {
pageNo:page, getList(
}); state.currentSort,
if (res.code === 0) { state.currentOrder,
let couponList = _.concat(state.pagination.data, res.data.list); state.categoryId,
state.pagination = { state.keyword,
...res.data, state.pagination.current_page + 1,
data: couponList, );
}; }
mountMasonry(); }
if (state.pagination.current_page < state.pagination.last_page) { onLoad((options) => {
state.loadStatus = 'more'; state.categoryId = options.categoryId;
} else { state.keyword = options.keyword;
state.loadStatus = 'noMore'; getList(state.currentSort, state.currentOrder, state.categoryId, state.keyword);
} });
} //
} onReachBottom(() => {
// loadmore();
function loadmore() { });
if (state.loadStatus !== 'noMore') {
getList(
state.currentSort,
state.currentOrder,
state.categoryId,
state.keyword,
state.pagination.current_page + 1,
);
}
}
onLoad((options) => {
state.categoryId = options.categoryId;
state.keyword = options.keyword;
getList(state.currentSort, state.currentOrder, state.categoryId, state.keyword);
});
//
onReachBottom(() => {
loadmore();
});
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.goods-list-box { .goods-list-box {
width: 50%; width: 50%;
box-sizing: border-box; box-sizing: border-box;
.left-list {
margin-right: 10rpx;
margin-bottom: 20rpx;
}
.right-list {
margin-left: 10rpx;
margin-bottom: 20rpx;
}
}
.goods-box {
&:nth-last-of-type(1) {
margin-bottom: 0 !important;
}
&:nth-child(2n) {
margin-right: 0;
}
}
.list-icon {
width: 80rpx;
.sicon-goods-card {
font-size: 40rpx;
}
.sicon-goods-list {
font-size: 40rpx;
}
}
.goods-card {
margin-left: 20rpx;
}
.list-filter-tabs {
background-color: #fff;
}
.filter-list-box {
padding: 28rpx 52rpx;
.filter-item {
font-size: 28rpx;
font-weight: 500;
color: #333333;
line-height: normal;
margin-bottom: 24rpx;
&:nth-last-child(1) {
margin-bottom: 0;
}
}
.filter-item-active {
color: var(--ui-BG-Main);
}
}
.tab-item {
height: 50px;
position: relative;
z-index: 11;
.tab-title { .left-list {
font-size: 30rpx; margin-right: 10rpx;
} margin-bottom: 20rpx;
}
.cur-tab-title { .right-list {
font-weight: $font-weight-bold; margin-left: 10rpx;
} margin-bottom: 20rpx;
}
}
.tab-line { .goods-box {
width: 60rpx; &:nth-last-of-type(1) {
height: 6rpx; margin-bottom: 0 !important;
border-radius: 6rpx; }
position: absolute;
left: 50%; &:nth-child(2n) {
transform: translateX(-50%); margin-right: 0;
bottom: 10rpx; }
background-color: var(--ui-BG-Main); }
z-index: 12;
} .list-icon {
} width: 80rpx;
</style>
.sicon-goods-card {
font-size: 40rpx;
}
.sicon-goods-list {
font-size: 40rpx;
}
}
.goods-card {
margin-left: 20rpx;
}
.list-filter-tabs {
background-color: #fff;
}
.filter-list-box {
padding: 28rpx 52rpx;
.filter-item {
font-size: 28rpx;
font-weight: 500;
color: #333333;
line-height: normal;
margin-bottom: 24rpx;
&:nth-last-child(1) {
margin-bottom: 0;
}
}
.filter-item-active {
color: var(--ui-BG-Main);
}
}
.tab-item {
height: 50px;
position: relative;
z-index: 11;
.tab-title {
font-size: 30rpx;
}
.cur-tab-title {
font-weight: $font-weight-bold;
}
.tab-line {
width: 60rpx;
height: 6rpx;
border-radius: 6rpx;
position: absolute;
left: 50%;
transform: translateX(-50%);
bottom: 10rpx;
background-color: var(--ui-BG-Main);
z-index: 12;
}
}
</style>

View File

@ -1,220 +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 :checked="state.selectedIds.includes(item.id)" color="var(--ui-BG-Main)"
<radio style="transform: scale(0.8)" @tap.stop="onSelectSingle(item.id)" />
:checked="state.selectedIds.includes(item.id)" </label>
color="var(--ui-BG-Main)" <s-goods-item :title="item.spu.name" :img="item.spu.picUrl || item.goods.image"
style="transform: scale(0.8)" :price="item.sku.price/100"
@tap.stop="onSelectSingle(item.id)" :skuText="item.sku.properties.length>1? item.sku.properties.reduce((items2,items)=>items2.valueName+' '+items.valueName):item.sku.properties[0].valueName"
/> priceColor="#FF3000" :titleWidth="400">
</label> <template v-if="!state.editMode" v-slot:tool>
<s-goods-item <su-number-box :min="0" :max="item.sku.stock" :step="1" v-model="item.count"
:title="item.spu.name" @change="onNumberChange($event, item)"></su-number-box>
:img="item.sku.picUrl || item.spu.picUrl" </template>
:price="fen2yuan(item.sku.price)" </s-goods-item>
:skuText="item.sku.properties.map((property) => property.valueName).join(' ')" </view>
priceColor="#FF3000" </view>
:titleWidth="400" </view>
> <!-- 底部 -->
<template v-if="!state.editMode" v-slot:tool> <su-fixed bottom :val="48" placeholder v-if="state.list.length > 0" :isInset="false">
<su-number-box <view class="cart-footer ss-flex ss-col-center ss-row-between ss-p-x-30 border-bottom">
:min="0" <view class="footer-left ss-flex ss-col-center">
:max="item.sku.stock" <label class="check-box ss-flex ss-col-center ss-p-r-30" @tap="onSelectAll">
:step="1" <radio :checked="state.isAllSelected" color="var(--ui-BG-Main)"
v-model="item.count" style="transform: scale(0.8)" @tap.stop="onSelectAll" />
@change="onNumberChange($event, item)" <view class="ss-m-l-8"> 全选 </view>
/> </label>
</template> <text>合计</text>
</s-goods-item> <view class="text-price price-text">
</view> {{ state.totalPriceSelected }}
</view> </view>
</view> </view>
<view class="footer-right">
<!-- 底部 --> <button v-if="state.editMode" class="ss-reset-button ui-BG-Main-Gradient pay-btn ui-Shadow-Main"
<su-fixed bottom :val="48" placeholder v-if="state.list.length > 0" :isInset="false"> @tap="onDelete">
<view class="cart-footer ss-flex ss-col-center ss-row-between ss-p-x-30 border-bottom"> 删除
<view class="footer-left ss-flex ss-col-center"> </button>
<label class="check-box ss-flex ss-col-center ss-p-r-30" @tap="onSelectAll"> <button v-else class="ss-reset-button ui-BG-Main-Gradient pay-btn ui-Shadow-Main"
<radio @tap="onConfirm">
:checked="state.isAllSelected" 去结算
color="var(--ui-BG-Main)" {{ state.selectedIds?.length ? `(${state.selectedIds.length})` : '' }}
style="transform: scale(0.8)" </button>
@tap.stop="onSelectAll" </view>
/> </view>
<view class="ss-m-l-8"> 全选 </view> </su-fixed>
</label> </view>
<text>合计</text> </s-layout>
<view class="text-price price-text">
{{ fen2yuan(state.totalPriceSelected) }}
</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 } from 'vue'; import {
import { fen2yuan } from '@/sheep/hooks/useGoods'; computed,
import { property } from 'lodash/util'; 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),
selectedIds: computed(() => cart.selectedIds), selectedList: [],
isAllSelected: computed(() => cart.isAllSelected), selectedIds: computed(() => cart.selectedIds),
totalPriceSelected: computed(() => cart.totalPriceSelected), isAllSelected: computed(() => cart.isAllSelected),
}); totalPriceSelected: computed(() => cart.totalPriceSelected),
});
//
function onSelectSingle(id) {
console.log('单选')
cart.selectSingle(id);
}
//
function onSelectAll() {
cart.selectAll(!state.isAllSelected);
}
// //
function onSelectSingle(id) { function onConfirm() {
cart.selectSingle(id); let items = []
} let goods_list = [];
state.selectedList = state.list.filter((item) => state.selectedIds.includes(item.id));
state.selectedList.map((item) => {
console.log(item, '便利');
//
items.push({
skuId: item.sku.id,
count: item.count,
cartId: item.id,
})
goods_list.push({
// goods_id: item.goods_id,
goods_id: item.spu.id,
// goods_num: item.goods_num,
goods_num: item.count,
// id
// 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 onSelectAll() { if (e === 0) {
cart.selectAll(!state.isAllSelected); cart.delete(cartItem.id);
} return;
}
// if (cartItem.goods_num === e) return;
function onConfirm() { cartItem.goods_num = e;
const items = state.list cart.update({
.filter((item) => state.selectedIds.includes(item.id)) goods_id: cartItem.id,
.map((item) => { goods_num: e,
return { goods_sku_price_id: cartItem.goods_sku_price_id,
skuId: item.sku.id, });
count: item.count, }
cartId: item.id, async function onDelete() {
}; cart.delete(state.selectedIds);
}); }
if (items.length === 0) {
sheep.$helper.toast('请选择商品');
return;
}
sheep.$router.go('/pages/order/confirm', {
data: JSON.stringify({
items,
// order_type: 'goods',
// goods_list,
// from: 'cart',
deliveryType: 1,
pointStatus: false,
}),
});
}
//
function onNumberChange(number, cartItem) {
if (number === 0) {
cart.delete([cartItem.id]);
return;
}
if (cartItem.goods_num === number) {
return;
}
cartItem.goods_num = number;
cart.update({
goods_id: cartItem.id,
goods_num: number,
});
}
//
async function onDelete() {
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 { .goods-box {
background-color: #fff; background-color: #fff;
} }
} }
} }
</style> </style>

View File

@ -1,42 +1,41 @@
<template> <template>
<s-layout
<s-layout title="我的" tabbar="/pages/index/user" navbar="custom" :bgStyle="template.page" title="我的"
:navbarStyle="template.style?.navbar" onShareAppMessage> tabbar="/pages/index/user"
<s-block v-for="(item, index) in template.components" :key="index" :styles="item.property.style"> navbar="custom"
<s-block-item :type="item.id" :data="item.property" :styles="item.property.style" /> :bgStyle="template.page"
</s-block> :navbarStyle="template.style?.navbar"
</s-layout> onShareAppMessage
>
<s-block v-for="(item, index) in template.components" :key="index" :styles="item.property.style">
<s-block-item :type="item.id" :data="item.property" :styles="item.property.style" />
</s-block>
</s-layout>
</template> </template>
<script setup> <script setup>
import { import { computed } from 'vue';
computed import { onShow, onPageScroll, onPullDownRefresh } from '@dcloudio/uni-app';
} from 'vue'; import sheep from '@/sheep';
import {
onShow,
onPageScroll,
onPullDownRefresh
} from '@dcloudio/uni-app';
import sheep from '@/sheep';
// tabBar // tabBar
uni.hideTabBar(); uni.hideTabBar();
const template = computed(() => sheep.$store('app').template.user); const template = computed(() => sheep.$store('app').template.user);
const isLogin = computed(() => sheep.$store('user').isLogin); const isLogin = computed(() => sheep.$store('user').isLogin);
onShow(() => { onShow(() => {
sheep.$store('user').updateUserData(); sheep.$store('user').updateUserData();
}); });
onPullDownRefresh(() => { onPullDownRefresh(() => {
sheep.$store('user').updateUserData(); sheep.$store('user').updateUserData();
setTimeout(function() { setTimeout(function () {
uni.stopPullDownRefresh(); uni.stopPullDownRefresh();
}, 800); }, 800);
}); });
onPageScroll(() => {}); onPageScroll(() => {});
</script> </script>
<style></style> <style></style>

View File

@ -1,4 +1,4 @@
<!-- 订单详情 --> <!-- 售后申请 -->
<template> <template>
<s-layout title="申请售后"> <s-layout title="申请售后">
<!-- 售后商品 --> <!-- 售后商品 -->

View File

@ -0,0 +1,215 @@
<template>
<s-layout>
<!-- title='退货物流' -->
<!-- 不知为何加上页面就错误 -->
<view>
<form @submit="subRefund" report-submit='true'>
<view class='apply-return'>
<view class='list borRadius14'>
<view class='item acea-row row-between-wrapper' style="display: flex;align-items: center;">
<view>物流公司</view>
<picker mode='selector' class='num' @change="bindPickerChange" :value="state.expressIndex"
:range="state.expresses" range-key="name">
<view class="picker acea-row row-between-wrapper">
<view class='reason'>{{ state.expresses[state.expressIndex].name }}</view>
<text class='iconfont icon-jiantou'></text>
</view>
</picker>
</view>
<view class='item textarea acea-row row-between' style="display: flex;align-items: center;">
<view>物流单号</view>
<input placeholder='请填写物流单号' class='num' name="logisticsNo"
placeholder-class='placeholder' />
</view>
<button class='returnBnt bg-color ss-reset-button ui-BG-Main-Gradient sub-btn'
form-type="submit"
style="background: linear-gradient(90deg,var(--ui-BG-Main),var(--ui-BG-Main-gradient))!important">提交</button>
</view>
</view>
</form>
</view>
</s-layout>
</template>
<script setup>
import sheep from '@/sheep';
import {
onLoad,
onReachBottom,
onPullDownRefresh
} from '@dcloudio/uni-app';
import {
computed,
watch,
ref,
reactive,
unref
} from 'vue';
const state = reactive({
expressIndex: 0,
expresses: [{
"id": 1,
"name": "申通快递"
},
{
"id": 2,
"name": "顺丰速运"
},
{
"id": 3,
"name": "中通快递"
},
{
"id": 4,
"name": "韵达快递"
}
], //
})
function bindPickerChange(e) {
state.expressIndex = e.detail.value;
}
function subRefund(e) {
const formData = e.detail.value;
console.log(formData, '表单数据');
console.log(state.expresses[state.expressIndex].id, '物流公司id');
return;
//
AfterSaleApi.deliveryAfterSale({
id: this.id,
logisticsId: this.expresses[this.expressIndex].id,
logisticsNo: formData.logisticsNo,
}).then(res => {
this.$util.Tips({
title: '填写退货成功',
icon: 'success'
}, {
tab: 5,
url: '/pages/users/user_return_detail/index?id=' + this.id
});
}).catch(err => {
return this.$util.Tips({
title: err
});
})
}
function getList() {
}
onLoad(() => {
// 退
})
</script>
<style lang="scss" scoped>
.apply-return {
padding: 20rpx 30rpx 70rpx 30rpx;
}
.apply-return .list {
background-color: #fff;
margin-top: 18rpx;
padding: 0 24rpx 70rpx 24rpx;
}
.apply-return .list .item {
min-height: 90rpx;
border-bottom: 1rpx solid #eee;
font-size: 30rpx;
color: #333;
}
.apply-return .list .item .num {
color: #282828;
margin-left: 27rpx;
// width: 227rpx;
// text-align: right;
}
.apply-return .list .item .num .picker .reason {
width: 385rpx;
}
.apply-return .list .item .num .picker .iconfont {
color: #666;
font-size: 30rpx;
margin-top: 2rpx;
}
.apply-return .list .item.textarea {
padding: 24rpx 0;
}
.apply-return .list .item textarea {
height: 100rpx;
font-size: 30rpx;
}
.apply-return .list .item .placeholder {
color: #bbb;
}
.apply-return .list .item .title {
height: 95rpx;
width: 100%;
}
.apply-return .list .item .title .tip {
font-size: 30rpx;
color: #bbb;
}
.apply-return .list .item .upload {
padding-bottom: 36rpx;
}
.apply-return .list .item .upload .pictrue {
border-radius: 14rpx;
margin: 22rpx 23rpx 0 0;
width: 156rpx;
height: 156rpx;
position: relative;
font-size: 24rpx;
color: #bbb;
}
.apply-return .list .item .upload .pictrue:nth-of-type(4n) {
margin-right: 0;
}
.apply-return .list .item .upload .pictrue image {
width: 100%;
height: 100%;
border-radius: 14rpx;
}
.apply-return .list .item .upload .pictrue .icon-guanbi1 {
position: absolute;
font-size: 45rpx;
top: -10rpx;
right: -10rpx;
}
.apply-return .list .item .upload .pictrue .icon-icon25201 {
color: #bfbfbf;
font-size: 50rpx;
}
.apply-return .list .item .upload .pictrue:nth-last-child(1) {
border: 1rpx solid #ddd;
box-sizing: border-box;
}
.apply-return .returnBnt {
font-size: 32rpx;
color: #fff;
width: 100%;
height: 86rpx;
border-radius: 50rpx;
text-align: center;
line-height: 86rpx;
margin: 43rpx auto;
}
</style>

View File

@ -1,57 +1,35 @@
<!-- 售后日志的每一项展示 -->
<template> <template>
<view class="log-item ss-flex"> <view class="log-item ss-flex">
<view class="log-icon ss-flex-col ss-col-center ss-m-r-20"> <view class="log-icon ss-flex-col ss-col-center ss-m-r-20">
<text class="cicon-title" :class="index === 0 ? 'activity-color' : ''"></text> <text class="cicon-title" :class="index === 0 ? 'activity-color' : ''" />
<view v-if="data.length - 1 != index" class="line"></view> <view v-if="data.length - 1 !== index" class="line" />
</view> </view>
<view> <view>
<view class="text">{{ item.log_type_text }}</view> <view class="text">{{ item.content }}</view>
<mp-html class="richtext" :content="item.content"></mp-html> <view class="date">
<view class="" v-if="item.images?.length"> {{ sheep.$helper.timeFormat(item.createTime, 'yyyy-mm-dd hh:MM:ss') }}
<scroll-view class="scroll-box" scroll-x scroll-anchoring>
<view class="ss-flex">
<view v-for="i in item.images" :key="i" class="ss-m-r-20">
<su-image
class="content-img"
isPreview
:previewList="state.commentImages"
:current="index"
:src="i"
:height="120"
:width="120"
mode="aspectFit"
></su-image>
</view>
</view>
</scroll-view>
</view> </view>
<view class="date">{{ item.create_time }}</view>
</view> </view>
</view> </view>
</template> </template>
<script setup> <script setup>
import sheep from '@/sheep'; import sheep from '@/sheep';
import { reactive } from 'vue';
const props = defineProps({ const props = defineProps({
item: { item: {
type: Object, type: Object, //
default() {}, default() {},
}, },
index: { index: {
type: Number, type: Number, // item data
default: 0, default: 0,
}, },
data: { data: {
type: Object, type: Object, //
default() {}, default() {},
}, },
}); });
const state = reactive({
commentImages: [],
});
props.item.images?.forEach((i) => {
state.commentImages.push(sheep.$url.cdn(i));
});
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.log-item { .log-item {

View File

@ -1,45 +1,29 @@
<!-- 售后进度 --> <!-- 售后日志列表 -->
<template> <template>
<s-layout title="售后进度"> <s-layout title="售后进度">
<view class="log-box"> <view class="log-box">
<view v-for="(item, index) in state.info" :key="item.title"> <view v-for="(item, index) in state.list" :key="item.id">
<log-item :item="item" :index="index" :data="state.info"></log-item> <log-item :item="item" :index="index" :data="state.list" />
</view> </view>
</view> </view>
</s-layout> </s-layout>
</template> </template>
<script setup> <script setup>
import sheep from '@/sheep';
import { onLoad } from '@dcloudio/uni-app'; import { onLoad } from '@dcloudio/uni-app';
import { computed, reactive } from 'vue'; import { reactive } from 'vue';
import logItem from './log-item.vue'; import logItem from './log-item.vue';
import AfterSaleApi from '@/sheep/api/trade/afterSale';
const state = reactive({ const state = reactive({
active: 1, list: [],
list: [
{
title: '买家下单',
desc: '2018-11-11',
},
{
title: '卖家发货',
desc: '2018-11-12',
},
{
title: '买家签收',
desc: '2018-11-13',
},
{
title: '交易完成',
desc: '2018-11-14',
},
],
}); });
async function getDetail(id) { async function getDetail(id) {
const { data } = await sheep.$api.order.aftersale.detail(id); const { data } = await AfterSaleApi.getAfterSaleLogList(id);
state.info = data.logs; state.list = data;
} }
onLoad((options) => { onLoad((options) => {
state.aftersaleId = options.id; state.aftersaleId = options.id;
getDetail(options.id); getDetail(options.id);

View File

@ -1,388 +1,414 @@
<template> <template>
<s-layout title="确认订单"> <s-layout title="确认订单">
<!-- TODO这个判断先删除 v-if="state.orderInfo.need_address === 1" --> <!-- v-if="state.orderInfo.need_address === 1" -->
<view class="bg-white address-box ss-m-b-14 ss-r-b-10" @tap="onSelectAddress"> <!-- 这个判断先删除 -->
<s-address-item :item="state.addressInfo" :hasBorderBottom="false"> <view class="bg-white address-box ss-m-b-14 ss-r-b-10" @tap="onSelectAddress">
<view class="ss-rest-button"> <s-address-item :item="state.addressInfo" :hasBorderBottom="false">
<text class="_icon-forward" /> <view class="ss-rest-button"><text class="_icon-forward"></text></view>
</view> </s-address-item>
</s-address-item> </view>
</view> <view class="order-card-box ss-m-b-14">
<s-goods-item v-for="item in state.orderInfo.goods_list" :key="item.goods_id"
:img="item.current_sku_price.image || item.goods.image" :title="item.goods.title"
:skuText="item.current_sku_price?.goods_sku_text" :price="item.current_sku_price.price"
:num="item.goods_num" marginBottom="10">
<template #top>
<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-card-box ss-m-b-14"> <view class="item-title">订单备注</view>
<s-goods-item <view class="ss-flex ss-col-center">
v-for="item in state.orderInfo.items" <uni-easyinput maxlength="20" placeholder="建议留言前先与商家沟通" v-model="state.orderPayload.remark"
:key="item.skuId" :inputBorder="false" :clearable="false"></uni-easyinput>
:img="item.picUrl" </view>
:title="item.spuName" </view>
:skuText="item.properties.map((property) => property.valueName).join(' ')" </view>
:price="item.price" <!-- 合计 -->
:num="item.count" <view class="bg-white total-card-box ss-p-20 ss-m-b-14 ss-r-10">
marginBottom="10" <view class="total-box-content border-bottom">
/> <view class="order-item ss-flex ss-col-center ss-row-between">
<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"> <text class="item-value ss-m-r-24">{{ state.orderInfo.goods_amount }}</text>
<uni-easyinput </view>
maxlength="20" </view>
placeholder="建议留言前先与商家沟通" <view class="order-item ss-flex ss-col-center ss-row-between"
v-model="state.orderPayload.remark" v-if="state.orderPayload.order_type === 'score'">
:inputBorder="false" <view class="item-title">扣除积分</view>
:clearable="false" <view class="ss-flex ss-col-center">
/> <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>
</view> </view>
</view> </view>
<view class="order-item ss-flex ss-col-center ss-row-between">
<view class="item-title">运费</view>
<view class="ss-flex ss-col-center">
<text class="item-value ss-m-r-24">+{{ state.orderInfo.dispatch_amount }}</text>
</view>
</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 + '张可用'
: '暂无可用优惠券'
}}</text>
<!-- 价格信息 --> <text class="_icon-forward item-icon"></text>
<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 class="order-item ss-flex ss-col-center ss-row-between"
<view class="item-title">商品金额</view> v-if="state.orderInfo.promo_infos?.length">
<view class="ss-flex ss-col-center"> <!-- <view v-if="state.orderInfo.promo_discount_fee > 0" class="order-item ss-flex ss-col-center ss-row-between"> -->
<text class="item-value ss-m-r-24"> <view class="item-title">活动优惠</view>
{{ fen2yuan(state.orderInfo.price.totalPrice) }} <view class="ss-flex ss-col-center" @tap="state.showDiscount = true">
</text> <text class="item-value text-red"> -{{ state.orderInfo.promo_discount_fee }} </text>
</view> <text class="_icon-forward item-icon"></text>
</view> </view>
<!-- TODO 芋艿接入积分 --> </view>
<view </view>
class="order-item ss-flex ss-col-center ss-row-between" <view class="total-box-footer ss-font-28 ss-flex ss-row-right ss-col-center ss-m-r-28">
v-if="state.orderPayload.order_type === 'score'" <view class="total-num ss-m-r-20">{{ state.totalNumber }}</view>
> <view>合计</view>
<view class="item-title">扣除积分</view> <view class="total-num text-red"> {{ state.orderInfo.pay_fee }} </view>
<view class="ss-flex ss-col-center"> <view class="ss-flex" v-if="state.orderPayload.order_type === 'score'">
<image <view class="total-num ss-font-30 text-red ss-m-l-4"> + </view>
:src="sheep.$url.static('/static/img/shop/goods/score1.svg')" <image :src="sheep.$url.static('/static/img/shop/goods/score1.svg')" class="score-img"></image>
class="score-img" <view class="total-num ss-font-30 text-red">{{ state.orderInfo.score_amount }}</view>
/> </view>
<text class="item-value ss-m-r-24">{{ state.orderInfo.score_amount }}</text> </view>
</view> </view>
</view> <!-- 发票 -->
<view class="order-item ss-flex ss-col-center ss-row-between"> <view class="bg-white ss-p-20 ss-r-20">
<view class="item-title">运费</view> <view class="order-item ss-flex ss-col-center ss-row-between">
<view class="ss-flex ss-col-center"> <view class="item-title">发票申请</view>
<text class="item-value ss-m-r-24"> <view class="ss-flex ss-col-center" @tap="onSelectInvoice">
+{{ fen2yuan(state.orderInfo.price.deliveryPrice) }} <text class="item-value">{{ state.invoiceInfo.name || '无需开具发票' }}</text>
</text> <text class="_icon-forward item-icon"></text>
</view> </view>
</view> </view>
<!-- 优惠劵只有 type = 0 普通订单非拼团秒杀砍价才可以使用优惠劵 --> </view>
<view <!-- 选择优惠券弹框 -->
class="order-item ss-flex ss-col-center ss-row-between" <s-coupon-select v-model="state.couponInfo" :show="state.showCoupon" @confirm="onSelectCoupon"
v-if="state.orderInfo.type === 0" @close="state.showCoupon = false" />
> <!-- 满额折扣弹框 -->
<view class="item-title">优惠券</view> <s-discount-list v-model="state.orderInfo" :show="state.showDiscount" @close="state.showDiscount = false" />
<view class="ss-flex ss-col-center" @tap="state.showCoupon = true"> <!-- 底部 -->
<text class="item-value text-red" v-if="state.orderPayload.couponId > 0"> <su-fixed bottom :opacity="false" bg="bg-white" placeholder :noFixed="false" :index="200">
-{{ fen2yuan(state.orderInfo.price.couponPrice) }} <view class="footer-box border-top ss-flex ss-row-between ss-p-x-20 ss-col-center">
</text> <view class="total-box-footer ss-flex ss-col-center">
<text <view class="total-num ss-font-30 text-red"> {{ state.orderInfo.pay_fee }} </view>
class="item-value" <view v-if="state.orderPayload.order_type === 'score'" class="ss-flex">
:class="state.couponInfo.length > 0 ? 'text-red' : 'text-disabled'" <view class="total-num ss-font-30 text-red ss-m-l-4">+</view>
v-else <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>
state.couponInfo.length > 0 ? state.couponInfo.length + ' 张可用' : '暂无可用优惠券' </view>
}}
</text>
<text class="_icon-forward item-icon" />
</view>
</view>
<view
class="order-item ss-flex ss-col-center ss-row-between"
v-if="state.orderInfo.price.discountPrice > 0"
>
<view class="item-title">活动优惠</view>
<view class="ss-flex ss-col-center">
<!-- @tap="state.showDiscount = true" TODO 芋艿后续要把优惠信息打进去 -->
<text class="item-value text-red">
-{{ fen2yuan(state.orderInfo.price.discountPrice) }}
</text>
<text class="_icon-forward item-icon" />
</view>
</view>
</view>
<view class="total-box-footer ss-font-28 ss-flex ss-row-right ss-col-center ss-m-r-28">
<view class="total-num ss-m-r-20">
{{ state.orderInfo.items.reduce((acc, item) => acc + item.count, 0) }}
</view>
<view>合计</view>
<view class="total-num text-red"> {{ fen2yuan(state.orderInfo.price.payPrice) }} </view>
</view>
</view>
<!-- 选择优惠券弹框 --> <button class="ss-reset-button ui-BG-Main-Gradient ss-r-40 submit-btn ui-Shadow-Main" @tap="onConfirm">
<s-coupon-select {{ exchangeNow ? '立即兑换' : '提交订单' }}
v-model="state.couponInfo" </button>
:show="state.showCoupon" </view>
@confirm="onSelectCoupon" </su-fixed>
@close="state.showCoupon = false" </s-layout>
/>
<!-- 满额折扣弹框 TODO 芋艿后续要把优惠信息打进去 -->
<s-discount-list
v-model="state.orderInfo"
:show="state.showDiscount"
@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">
{{ fen2yuan(state.orderInfo.price.payPrice) }}
</view>
</view>
<button
class="ss-reset-button ui-BG-Main-Gradient ss-r-40 submit-btn ui-Shadow-Main"
@tap="onConfirm"
>
提交订单
</button>
</view>
</su-fixed>
</s-layout>
</template> </template>
<script setup> <script setup>
import { reactive } from 'vue'; import {
import { onLoad } from '@dcloudio/uni-app'; reactive,
import sheep from '@/sheep'; computed
import { isEmpty } from 'lodash'; } from 'vue';
import OrderApi from '@/sheep/api/trade/order'; import {
import CouponApi from '@/sheep/api/promotion/coupon'; onLoad,
import { fen2yuan } from '@/sheep/hooks/useGoods'; onPageScroll,
onShow
} from '@dcloudio/uni-app';
import sheep from '@/sheep';
import {
isEmpty
} from 'lodash';
const state = reactive({ const state = reactive({
orderPayload: {}, orderPayload: {},
orderInfo: { orderInfo: {},
items: [], // addressInfo: {},
price: {}, // invoiceInfo: {},
}, totalNumber: 0,
addressInfo: {}, // showCoupon: false,
showCoupon: false, // couponInfo: [],
couponInfo: [], // showDiscount: false,
showDiscount: false, // });
});
// // ()
function onSelectAddress() { const exchangeNow = computed(
uni.$once('SELECT_ADDRESS', (e) => { () => state.orderPayload.order_type === 'score' && state.orderInfo.pay_fee == 0,
changeConsignee(e.addressInfo); );
});
sheep.$router.go('/pages/user/address/list');
}
// & //
async function changeConsignee(addressInfo = {}) { function onSelectAddress() {
if (!isEmpty(addressInfo)) { uni.$once('SELECT_ADDRESS', (e) => {
state.addressInfo = addressInfo; changeConsignee(e.addressInfo);
} });
await getOrderInfo(); sheep.$router.go('/pages/user/address/list');
} }
// // &
async function onSelectCoupon(couponId) { async function changeConsignee(addressInfo = {}) {
state.orderPayload.couponId = couponId || 0; if (isEmpty(addressInfo)) {
await getOrderInfo(); const {
state.showCoupon = false; code,
} data
} = await sheep.$api.user.address.default();
console.log(data, '默认收货地址');
if (code === 0 && !isEmpty(data)) {
console.log('执行赋值')
addressInfo = data;
}
}
if (!isEmpty(addressInfo)) {
state.addressInfo = addressInfo;
state.orderPayload.address_id = state.addressInfo.id;
}
getOrderInfo();
}
// //
function onConfirm() { async function onSelectCoupon(e) {
if (!state.addressInfo.id) { state.orderPayload.coupon_id = e || 0;
sheep.$helper.toast('请选择收货地址'); getOrderInfo();
return; state.showCoupon = false;
} }
submitOrder();
}
// & //
async function submitOrder() { function onSelectInvoice() {
const { code, data } = await OrderApi.createOrder({ uni.$once('SELECT_INVOICE', (e) => {
items: state.orderPayload.items, state.invoiceInfo = e.invoiceInfo;
couponId: state.orderPayload.couponId, state.orderPayload.invoice_id = e.invoiceInfo.id || 0;
addressId: state.addressInfo.id, });
deliveryType: 1, // TODO sheep.$router.go('/pages/user/invoice/list');
pointStatus: false, // TODO }
});
if (code !== 0) {
return;
}
//
if (state.orderPayload.items[0].cartId > 0) {
sheep.$store('cart').getList();
}
//
sheep.$router.redirect('/pages/pay/index', {
orderSN: data.payOrderId,
});
}
// & // /
async function getOrderInfo() { function onConfirm() {
// if (!state.orderPayload.address_id && state.orderInfo.need_address === 1) {
const { data, code } = await OrderApi.settlementOrder({ sheep.$helper.toast('请选择收货地址');
items: state.orderPayload.items, return;
couponId: state.orderPayload.couponId, }
addressId: state.addressInfo.id,
deliveryType: 1, // TODO
pointStatus: false, // TODO
});
if (code !== 0) {
return;
}
state.orderInfo = data;
//
if (state.orderInfo.address) {
state.addressInfo = state.orderInfo.address;
}
}
// if (exchangeNow.value) {
async function getCoupons() { uni.showModal({
const { code, data } = await CouponApi.getMatchCouponList( title: '提示',
state.orderInfo.price.payPrice, content: '确定使用积分立即兑换?',
state.orderInfo.items.map((item) => item.spuId), cancelText: '再想想',
state.orderPayload.items.map((item) => item.skuId), success: async function(res) {
state.orderPayload.items.map((item) => item.categoryId), if (res.confirm) {
); submitOrder();
if (code === 0) { }
state.couponInfo = data; },
} });
} } else {
submitOrder();
}
}
onLoad(async (options) => { // &
if (!options.data) { async function submitOrder() {
sheep.$helper.toast('参数不正确,请检查!'); const {
return; error,
} data
state.orderPayload = JSON.parse(options.data); } = await sheep.$api.order.create(state.orderPayload);
await getOrderInfo(); if (error === 0) {
await getCoupons(); //
}); if (state.orderPayload.from === 'cart') {
sheep.$store('cart').getList();
}
if (exchangeNow.value) {
sheep.$router.redirect('/pages/pay/result', {
orderSN: data.order_sn,
});
} else {
sheep.$router.redirect('/pages/pay/index', {
orderSN: data.order_sn,
});
}
}
}
// &
async function getOrderInfo() {
console.log(state.orderPayload, '计算价格传参')
// let {code, data} = await sheep.$api.order.calc(state.orderPayload);
// let data = await sheep.$api.order.calc(state.orderPayload);
console.log(state.orderPayload.items)
let data = await sheep.$api.order.calc({
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() {
const {
error,
data
} = await sheep.$api.order.coupons(state.orderPayload);
if (error === 0) {
state.couponInfo = data;
}
}
onLoad(async (options) => {
console.log(options)
if (options.data) {
state.orderPayload = JSON.parse(options.data);
changeConsignee();
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 { .uni-easyinput__content {
display: flex !important; display: flex !important;
align-items: center !important; align-items: center !important;
justify-content: right !important; justify-content: right !important;
} }
} }
.score-img { .score-img {
width: 36rpx; width: 36rpx;
height: 36rpx; height: 36rpx;
margin: 0 4rpx; margin: 0 4rpx;
} }
.order-item { .order-item {
height: 80rpx; height: 80rpx;
.item-title { .item-title {
font-size: 28rpx; font-size: 28rpx;
font-weight: 400; font-weight: 400;
} }
.item-value { .item-value {
font-size: 28rpx; font-size: 28rpx;
font-weight: 500; font-weight: 500;
font-family: OPPOSANS; font-family: OPPOSANS;
} }
.text-disabled { .text-disabled {
color: #bbbbbb; color: #bbbbbb;
} }
.item-icon { .item-icon {
color: $dark-9; color: $dark-9;
} }
.remark-input { .remark-input {
text-align: right; text-align: right;
} }
.item-placeholder { .item-placeholder {
color: $dark-9; color: $dark-9;
font-size: 26rpx; font-size: 26rpx;
text-align: right; text-align: right;
} }
} }
.total-box-footer { .total-box-footer {
height: 90rpx; height: 90rpx;
.total-num { .total-num {
color: #333333; color: #333333;
font-family: OPPOSANS; font-family: OPPOSANS;
} }
} }
.footer-box { .footer-box {
height: 100rpx; height: 100rpx;
.submit-btn { .submit-btn {
width: 240rpx; width: 240rpx;
height: 70rpx; height: 70rpx;
font-size: 28rpx; font-size: 28rpx;
font-weight: 500; font-weight: 500;
.goto-pay-text { .goto-pay-text {
line-height: 28rpx; line-height: 28rpx;
} }
} }
.cancel-btn { .cancel-btn {
width: 240rpx; width: 240rpx;
height: 80rpx; height: 80rpx;
font-size: 26rpx; font-size: 26rpx;
background-color: #e5e5e5; background-color: #e5e5e5;
color: $dark-9; color: $dark-9;
} }
} }
.title { .title {
font-size: 36rpx; font-size: 36rpx;
font-weight: bold; font-weight: bold;
color: #333333; color: #333333;
} }
.subtitle { .subtitle {
font-size: 28rpx; font-size: 28rpx;
color: #999999; color: #999999;
} }
.cicon-checkbox { .cicon-checkbox {
font-size: 36rpx; font-size: 36rpx;
color: var(--ui-BG-Main); color: var(--ui-BG-Main);
} }
.cicon-box { .cicon-box {
font-size: 36rpx; font-size: 36rpx;
color: #999999; color: #999999;
} }
</style> </style>

View File

@ -232,7 +232,7 @@
<button <button
class="ss-reset-button cancel-btn" class="ss-reset-button cancel-btn"
v-if="state.orderInfo.buttons?.includes('comment')" v-if="state.orderInfo.buttons?.includes('comment')"
@tap="onComment(state.orderInfo.id, state.orderInfo)" @tap="onComment(state.orderInfo.id)"
> >
评价 评价
</button> </button>
@ -299,10 +299,10 @@
}); });
} }
// TODO //
async function onExpress(orderId) { async function onExpress(id) {
sheep.$router.go('/pages/order/express/list', { sheep.$router.go('/pages/order/express/log', {
orderId, id,
}); });
} }
@ -362,10 +362,9 @@
// #endif // #endif
// //
function onComment(orderSN, orderId) { function onComment(id) {
sheep.$router.go('/pages/goods/comment/add', { sheep.$router.go('/pages/goods/comment/add', {
orderSN, id
orderId,
}); });
} }
@ -377,7 +376,7 @@
merchant_trade_no: state.merchantTradeNo, merchant_trade_no: state.merchantTradeNo,
}); });
} else { } else {
res = await sheep.$api.order.detail(id); res = await OrderApi.getOrder(id);
} }
if (res.code === 0) { if (res.code === 0) {
state.orderInfo = res.data; state.orderInfo = res.data;

View File

@ -1,104 +0,0 @@
<!-- 物流包裹-->
<template>
<s-layout title="物流包裹">
<view class="express-wrap">
<su-sticky bgColor="#FFE2B6">
<view class="header ss-flex ss-p-l-24">{{ state.list.length }}个包裹已派送</view>
</su-sticky>
<view
class="express-box"
v-for="item in state.list"
:key="item.type"
@tap="sheep.$router.go('/pages/order/express/log', { id: item.id, orderId: state.orderId })"
>
<view class="express-box-header ss-flex ss-row-between">
<view class="express-box-header-type">{{ item.status_text }}</view>
<view class="express-box-header-num">{{
item.express_name + ' : ' + item.express_no
}}</view>
</view>
<view class="express-box-content">
<view class="content-address">{{ item.logs[0]?.content }}</view>
<view class="" v-if="item.items?.length">
<scroll-view class="scroll-box" scroll-x scroll-anchoring>
<view class="ss-flex">
<view v-for="i in item.items" :key="i" class="ss-m-r-20"
><image class="content-img" :src="sheep.$url.static(i.goods_image)" />
</view>
</view>
</scroll-view>
</view>
</view>
<view class="express-box-foot">{{ item.items.length }}件商品</view>
</view>
</view>
</s-layout>
</template>
<script setup>
import sheep from '@/sheep';
import { onLoad } from '@dcloudio/uni-app';
import { computed, reactive } from 'vue';
const state = reactive({
list: [],
orderId: '',
});
async function getExpressList(id) {
const { data } = await sheep.$api.order.express(id, '');
state.list = data;
}
onLoad((Option) => {
state.orderId = Option.orderId;
getExpressList(state.orderId);
});
</script>
<style lang="scss" scoped>
.header {
height: 84rpx;
font-size: 30rpx;
font-weight: 500;
color: #a8700d;
}
.express-box {
background: #fff;
padding-bottom: 30rpx;
box-sizing: border-box;
margin-bottom: 20rpx;
.express-box-header {
height: 76rpx;
padding: 0 24rpx;
border-bottom: 2rpx solid rgba(#dfdfdf, 0.5);
.express-box-header-type {
font-size: 26rpx;
font-weight: 500;
color: #999;
}
.express-box-header-num {
font-size: 26rpx;
font-weight: 400;
color: #999999;
}
}
.express-box-content {
padding: 20rpx 24rpx;
.content-address {
font-size: 28rpx;
font-weight: 400;
color: #333333;
line-height: normal;
margin-bottom: 20rpx;
}
.content-img {
width: 180rpx;
height: 180rpx;
}
}
.express-box-foot {
padding: 0 24rpx;
font-size: 24rpx;
font-weight: 400;
color: #999999;
}
}
</style>

View File

@ -2,65 +2,46 @@
<template> <template>
<s-layout title="物流追踪"> <s-layout title="物流追踪">
<view class="log-wrap"> <view class="log-wrap">
<!-- 商品信息 -->
<view class="log-card ss-flex ss-m-20 ss-r-10" v-if="goodsImages.length > 0"> <view class="log-card ss-flex ss-m-20 ss-r-10" v-if="goodsImages.length > 0">
<uni-swiper-dot :info="goodsImages" :current="state.current" mode="round"> <uni-swiper-dot :info="goodsImages" :current="state.current" mode="round">
<swiper class="swiper-box" @change="change"> <swiper class="swiper-box">
<swiper-item v-for="(item, index) in goodsImages" :key="index"> <swiper-item v-for="(item, index) in goodsImages" :key="index">
<image class="log-card-img" :src="sheep.$url.static(item.image)"></image> <image class="log-card-img" :src="sheep.$url.static(item.image)" />
</swiper-item> </swiper-item>
</swiper> </swiper>
</uni-swiper-dot> </uni-swiper-dot>
<view class="log-card-msg"> <view class="log-card-msg">
<view class="ss-flex ss-m-b-8"> <!-- TODO 芋艿优化点展示状态 -->
<view>物流状态</view> <!-- <view class="ss-flex ss-m-b-8">-->
<view class="warning-color">{{ state.info.status_text }}</view> <!-- <view>物流状态</view>-->
</view> <!-- <view class="warning-color">{{ state.info.status_text }}</view>-->
<view class="ss-m-b-8">快递单号{{ state.info.express_no }}</view> <!-- </view>-->
<view>快递公司{{ state.info.express_name }}</view> <view class="ss-m-b-8">快递单号{{ state.info.logisticsNo }}</view>
<view>快递公司{{ state.info.logisticsName }}</view>
</view> </view>
</view> </view>
<!-- 物流轨迹 -->
<view class="log-content ss-m-20 ss-r-10"> <view class="log-content ss-m-20 ss-r-10">
<view <view
class="log-content-box ss-flex" class="log-content-box ss-flex"
v-for="(item, index) in state.info.logs" v-for="(item, index) in state.tracks"
:key="item.title" :key="item.title"
> >
<view class="log-icon ss-flex-col ss-col-center ss-m-r-20"> <view class="log-icon ss-flex-col ss-col-center ss-m-r-20">
<text <text class="cicon-title" />
v-if="state.info.logs[index].status === state.info.logs[index - 1]?.status" <view v-if="state.tracks.length - 1 !== index" class="line" />
class="cicon-title"
></text>
<text
v-if="state.info.logs[index].status != state.info.logs[index - 1]?.status"
:class="[
index === 0 ? 'activity-color' : 'info-color',
item.status === 'transport'
? 'sicon-transport'
: item.status === 'delivery'
? 'sicon-delivery'
: item.status === 'collect'
? 'sicon-a-collectmaterials'
: item.status === 'fail' || item.status === 'back' || item.status === 'refuse'
? 'sicon-circleclose'
: item.status === 'signfor'
? 'sicon-circlecheck'
: 'sicon-warning-outline',
]"
></text>
<view v-if="state.info.logs.length - 1 != index" class="line"></view>
</view> </view>
<view class="log-content-msg"> <view class="log-content-msg">
<view <!-- TODO 芋艿优化点展示状态 -->
v-if=" <!-- <view class="log-msg-title ss-m-b-20">-->
item.status_text && <!-- {{ item.status_text }}-->
state.info.logs[index].status != state.info.logs[index - 1]?.status <!-- </view>-->
"
class="log-msg-title ss-m-b-20"
>{{ item.status_text }}</view
>
<view class="log-msg-desc ss-m-b-16">{{ item.content }}</view> <view class="log-msg-desc ss-m-b-16">{{ item.content }}</view>
<view class="log-msg-date ss-m-b-40">{{ item.change_date }}</view> <view class="log-msg-date ss-m-b-40">
{{ sheep.$helper.timeFormat(item.time, 'yyyy-mm-dd hh:MM:ss') }}
</view>
</view> </view>
</view> </view>
</view> </view>
@ -72,31 +53,38 @@
import sheep from '@/sheep'; import sheep from '@/sheep';
import { onLoad } from '@dcloudio/uni-app'; import { onLoad } from '@dcloudio/uni-app';
import { computed, reactive } from 'vue'; import { computed, reactive } from 'vue';
import OrderApi from '@/sheep/api/trade/order';
const state = reactive({ const state = reactive({
info: [], info: [],
current: 0, tracks: [],
}); });
const goodsImages = computed(() => { const goodsImages = computed(() => {
let array = []; let array = [];
if (state.info.items) { if (state.info.items) {
state.info.items.forEach((item) => { state.info.items.forEach((item) => {
array.push({ array.push({
image: item.goods_image, image: item.picUrl,
}); });
}); });
} }
return array; return array;
}); });
function change(e) {
state.current = e.detail.current; async function getExpressDetail(id) {
const { data } = await OrderApi.getOrderExpressTrackList(id);
state.tracks = data.reverse();
} }
async function getExpressdetail(id, orderId) {
const { data } = await sheep.$api.order.express(id, orderId); async function getOrderDetail(id) {
const { data } = await OrderApi.getOrder(id)
state.info = data; state.info = data;
} }
onLoad((Option) => {
getExpressdetail(Option.id, Option.orderId); onLoad((options) => {
getExpressDetail(options.id);
getOrderDetail(options.id);
}); });
</script> </script>

View File

@ -55,7 +55,7 @@
取消订单 取消订单
</button> </button>
<button v-if="order.buttons.includes('comment')" class="tool-btn ss-reset-button" <button v-if="order.buttons.includes('comment')" class="tool-btn ss-reset-button"
@tap.stop="onComment(order.order_sn)"> @tap.stop="onComment(order.id)">
评价 评价
</button> </button>
<button v-if="order.buttons.includes('delete')" class="delete-btn ss-reset-button" <button v-if="order.buttons.includes('delete')" class="delete-btn ss-reset-button"
@ -164,10 +164,10 @@
}); });
} }
// TODO //
function onComment(orderSN) { function onComment(id) {
sheep.$router.go('/pages/goods/comment/add', { sheep.$router.go('/pages/goods/comment/add', {
orderSN, id,
}); });
} }
@ -228,10 +228,10 @@
} }
// #endif // #endif
// TODO //
async function onExpress(orderId) { async function onExpress(id) {
sheep.$router.go('/pages/order/express/list', { sheep.$router.go('/pages/order/express/log', {
orderId, id,
}); });
} }

View File

@ -2,17 +2,14 @@
<template> <template>
<s-layout title="收银台"> <s-layout title="收银台">
<view class="bg-white ss-modal-box ss-flex-col"> <view class="bg-white ss-modal-box ss-flex-col">
<!-- 订单信息 -->
<view class="modal-header ss-flex-col ss-col-center ss-row-center"> <view class="modal-header ss-flex-col ss-col-center ss-row-center">
<view class="money-box ss-m-b-20"> <view class="money-box ss-m-b-20">
<text class="money-text">{{ fen2yuan(state.orderInfo.price) }}</text> <text class="money-text">{{ state.orderInfo.pay_fee }}</text>
</view> </view>
<view class="time-text"> <view class="time-text">
<text>{{ payDescText }}</text> <text>{{ payDescText }}</text>
</view> </view>
</view> </view>
<!-- 支付方式 -->
<view class="modal-content ss-flex-1"> <view class="modal-content ss-flex-1">
<view class="pay-title ss-p-l-30 ss-m-y-30">选择支付方式</view> <view class="pay-title ss-p-l-30 ss-m-y-30">选择支付方式</view>
<radio-group @change="onTapPay"> <radio-group @change="onTapPay">
@ -20,6 +17,7 @@
<view <view
class="pay-item ss-flex ss-col-center ss-row-between ss-p-x-30 border-bottom" class="pay-item ss-flex ss-col-center ss-row-between ss-p-x-30 border-bottom"
:class="{ 'disabled-pay-item': item.disabled }" :class="{ 'disabled-pay-item': item.disabled }"
v-if="allowedPayment.includes(item.value)"
> >
<view class="ss-flex ss-col-center"> <view class="ss-flex ss-col-center">
<image <image
@ -27,19 +25,25 @@
v-if="item.disabled" v-if="item.disabled"
:src="sheep.$url.static('/static/img/shop/pay/cod_disabled.png')" :src="sheep.$url.static('/static/img/shop/pay/cod_disabled.png')"
mode="aspectFit" mode="aspectFit"
/> ></image>
<image <image
class="pay-icon" class="pay-icon"
v-else v-else
:src="sheep.$url.static(item.icon)" :src="sheep.$url.static(item.icon)"
mode="aspectFit" mode="aspectFit"
/> ></image>
<text class="pay-title">{{ item.title }}</text> <text class="pay-title">{{ item.title }}</text>
</view> </view>
<view class="check-box ss-flex ss-col-center ss-p-l-10"> <view class="check-box ss-flex ss-col-center ss-p-l-10">
<view class="userInfo-money ss-m-r-10" v-if="item.value === 'wallet'"> <view class="userInfo-money ss-m-r-10" v-if="item.value == 'money'">
余额: {{ userInfo.money }} 余额: {{ userInfo.money }}
</view> </view>
<view
class="userInfo-money ss-m-r-10"
v-if="item.value == 'offline' && item.disabled"
>
部分商品不支持
</view>
<radio <radio
:value="item.value" :value="item.value"
color="var(--ui-BG-Main)" color="var(--ui-BG-Main)"
@ -52,7 +56,6 @@
</label> </label>
</radio-group> </radio-group>
</view> </view>
<!-- 工具 --> <!-- 工具 -->
<view class="modal-footer ss-flex ss-row-center ss-col-center ss-m-t-80 ss-m-b-40"> <view class="modal-footer ss-flex ss-row-center ss-col-center ss-m-t-80 ss-m-b-40">
<button v-if="state.payStatus === 0" class="ss-reset-button past-due-btn"> <button v-if="state.payStatus === 0" class="ss-reset-button past-due-btn">
@ -78,49 +81,95 @@
import { computed, reactive } from 'vue'; import { computed, reactive } from 'vue';
import { onLoad } from '@dcloudio/uni-app'; import { onLoad } from '@dcloudio/uni-app';
import sheep from '@/sheep'; import sheep from '@/sheep';
import { fen2yuan, useDurationTime } from '@/sheep/hooks/useGoods'; import { useDurationTime } from '@/sheep/hooks/useGoods';
import PayOrderApi from '@/sheep/api/pay/order';
import PayChannelApi from '@/sheep/api/pay/channel';
import { getPayMethods } from '@/sheep/platform/pay';
const userInfo = computed(() => sheep.$store('user').userInfo); const userInfo = computed(() => sheep.$store('user').userInfo);
// //
const state = reactive({ const state = reactive({
orderType: 'goods', // ; goods - , recharge - orderType: 'goods',
orderInfo: {}, // payment: '',
orderInfo: {},
payStatus: 0, // 0=, -2= -1= 1=2= payStatus: 0, // 0=, -2= -1= 1=2=
payMethods: [], // payMethods: [],
payment: '', //
}); });
const allowedPayment = computed(() => {
if(state.orderType === 'recharge') {
return sheep.$store('app').platform.recharge_payment
}
return sheep.$store('app').platform.payment
});
const payMethods = [
{
icon: '/static/img/shop/pay/wechat.png',
title: '微信支付',
value: 'wechat',
disabled: false,
},
{
icon: '/static/img/shop/pay/alipay.png',
title: '支付宝支付',
value: 'alipay',
disabled: false,
},
{
icon: '/static/img/shop/pay/wallet.png',
title: '余额支付',
value: 'money',
disabled: false,
},
{
icon: '/static/img/shop/pay/apple.png',
title: 'Apple Pay',
value: 'apple',
disabled: false,
},
{
icon: '/static/img/shop/pay/cod.png',
title: '货到付款',
value: 'offline',
disabled: false,
},
];
const onPay = () => { const onPay = () => {
if (state.payment === '') { if (state.payment === '') {
sheep.$helper.toast('请选择支付方式'); sheep.$helper.toast('请选择支付方式');
return; return;
} }
if (state.payment === 'wallet') { if (state.payment === 'money') {
uni.showModal({ uni.showModal({
title: '提示', title: '提示',
content: '确定要支付吗?', content: '确定要支付吗?',
success: function (res) { success: function (res) {
if (res.confirm) { if (res.confirm) {
sheep.$platform.pay(state.payment, state.orderType, state.orderInfo.id); sheep.$platform.pay(state.payment, state.orderType, state.orderInfo.order_sn);
}
},
});
} else if (state.payment === 'offline') {
uni.showModal({
title: '提示',
content: '确定要下单吗?',
success: function (res) {
if (res.confirm) {
sheep.$platform.pay(state.payment, state.orderType, state.orderInfo.order_sn);
} }
}, },
}); });
} else { } else {
sheep.$platform.pay(state.payment, state.orderType, state.orderInfo.id); sheep.$platform.pay(state.payment, state.orderType, state.orderInfo.order_sn);
} }
}; };
//
const payDescText = computed(() => { const payDescText = computed(() => {
if (state.payStatus === 2) { if (state.payStatus === 2) {
return '该订单已支付'; return '该订单已支付';
} }
if (state.payStatus === 1) { if (state.payStatus === 1 && state.orderInfo.ext.expired_time !== 0) {
const time = useDurationTime(state.orderInfo.expireTime); const time = useDurationTime(state.orderInfo.ext.expired_time);
if (time.ms <= 0) { if (time.ms <= 0) {
state.payStatus = -1; state.payStatus = -1;
return ''; return '';
@ -130,65 +179,86 @@
if (state.payStatus === -2) { if (state.payStatus === -2) {
return '未查询到支付单信息'; return '未查询到支付单信息';
} }
return ''; return '';
}); });
// payOrder.status => payStatus
function checkPayStatus() { function checkPayStatus() {
if (state.orderInfo.status === 10 if (state.orderInfo.status === 'unpaid') {
|| state.orderInfo.status === 20 ) { // state.payStatus = 1;
state.payStatus = 2;
return; return;
} }
if (state.orderInfo.status === 30) { // if (state.orderInfo.status === 'closed') {
state.payStatus = -1; state.payStatus = -1;
return; return;
} }
state.payStatus = 1; // state.payStatus = 2;
} }
//
function onTapPay(e) { function onTapPay(e) {
state.payment = e.detail.value; state.payment = e.detail.value;
} }
// async function setRechargeOrder(id) {
async function setOrder(id) { const { data, error } = await sheep.$api.trade.order(id);
// if (error === 0) {
const { data, code } = await PayOrderApi.getOrder(id); state.orderInfo = data;
if (code !== 0 || !data) { state.payMethods = payMethods;
checkPayStatus();
} else {
state.payStatus = -2; state.payStatus = -2;
return;
} }
state.orderInfo = data;
//
await setPayMethods();
//
checkPayStatus();
} }
// async function setGoodsOrder(id) {
async function setPayMethods() { const { data, error } = await sheep.$api.order.detail(id);
const { data, code } = await PayChannelApi.getEnableChannelCodeList(state.orderInfo.appId) if (error === 0) {
if (code !== 0) { state.orderInfo = data;
return if (state.orderInfo.ext.offline_status === 'none') {
payMethods.forEach((item, index, array) => {
if (item.value === 'offline') {
array.splice(index, 1);
}
});
} else if (state.orderInfo.ext.offline_status === 'disabled') {
payMethods.forEach((item) => {
if (item.value === 'offline') {
item.disabled = true;
}
});
}
state.payMethods = payMethods;
checkPayStatus();
} else {
state.payStatus = -2;
} }
state.payMethods = getPayMethods(data)
} }
onLoad((options) => { onLoad((options) => {
if (sheep.$platform.name === 'WechatOfficialAccount' if (
&& sheep.$platform.os === 'ios' sheep.$platform.name === 'WechatOfficialAccount' &&
&& !sheep.$platform.landingPage.includes('pages/pay/index')) { sheep.$platform.os === 'ios' &&
!sheep.$platform.landingPage.includes('pages/pay/index')
) {
location.reload(); location.reload();
return; return;
} }
// let id = '';
let id = options.id; if (options.orderSN) {
if (options.orderType) { id = options.orderSN;
state.orderType = options.orderType; }
if (options.id) {
id = options.id;
}
if (options.type === 'recharge') {
state.orderType = 'recharge';
//
setRechargeOrder(id);
} else {
state.orderType = 'goods';
//
setGoodsOrder(id);
} }
setOrder(id);
}); });
</script> </script>

View File

@ -1,250 +1,268 @@
<template> <template>
<s-layout title="充值" class="withdraw-wrap" navbar="inner"> <s-layout title="充值" class="withdraw-wrap" navbar="inner">
<view class="wallet-num-box ss-flex ss-col-center ss-row-between" :style="[ <view class="wallet-num-box ss-flex ss-col-center ss-row-between" :style="[
{ {
marginTop: '-' + Number(statusBarHeight + 88) + 'rpx', marginTop: '-' + Number(statusBarHeight + 88) + 'rpx',
paddingTop: Number(statusBarHeight + 108) + 'rpx', paddingTop: Number(statusBarHeight + 108) + 'rpx',
}, },
]"> ]">
<view class=""> <view class="">
<view class="num-title">当前余额</view> <view class="num-title">当前余额</view>
<view class="wallet-num">{{ userInfo.money }}</view> <view class="wallet-num">{{ userInfo.money }}</view>
</view> </view>
<button class="ss-reset-button log-btn" @tap="sheep.$router.go('/pages/pay/recharge-log')"></button> <button class="ss-reset-button log-btn" @tap="sheep.$router.go('/pages/pay/recharge-log')"></button>
</view> </view>
<view class="recharge-box"> <view class="recharge-box">
<view class="recharge-card-box" v-if="state.data.status"> <view class="recharge-card-box" v-if="state.data.status">
<view class="input-label ss-m-b-50">充值金额</view> <view class="input-label ss-m-b-50">充值金额</view>
<view class="input-box ss-flex border-bottom ss-p-b-20" v-if="state.data.custom_status"> <view class="input-box ss-flex border-bottom ss-p-b-20" v-if="state.data.custom_status">
<view class="unit"></view> <view class="unit"></view>
<uni-easyinput v-model="state.recharge_money" type="digit" placeholder="请输入充值金额" :inputBorder="false"> <uni-easyinput v-model="state.recharge_money" type="digit" placeholder="请输入充值金额"
</uni-easyinput> :inputBorder="false">
</view> </uni-easyinput>
<view class="face-value-box ss-flex ss-flex-wrap ss-m-y-40"> </view>
<button class="ss-reset-button face-value-btn" v-for="item in state.faceValueList" :key="item.money" <view class="face-value-box ss-flex ss-flex-wrap ss-m-y-40">
:class="[{ 'btn-active': state.recharge_money == parseFloat(item.money) }]" @tap="onCard(item.money)"> <button class="ss-reset-button face-value-btn" v-for="item in state.faceValueList" :key="item.money"
<text class="face-value-title">{{ item.money }}</text> :class="[{ 'btn-active': state.recharge_money == parseFloat(item.money) }]"
<view v-if="item.gift" class="face-value-tag"> @tap="onCard(item.payPrice/100)">
{{ item.gift }}{{ state.data.gift_type == 'money' ? '元' : '积分' }}</view> <text class="face-value-title">{{ item.payPrice/100 }}</text>
</button> <view v-if="item.bonusPrice" class="face-value-tag">
</view> {{ item.bonusPrice/100 }}{{ state.data.gift_type == 'money' ? '元' : '积分' }}</view>
<button class="ss-reset-button save-btn ui-BG-Main-Gradient ss-m-t-60 ui-Shadow-Main" @tap="onConfirm"> </button>
确认充值 </view>
</button> <button class="ss-reset-button save-btn ui-BG-Main-Gradient ss-m-t-60 ui-Shadow-Main" @tap="onConfirm">
</view> 确认充值
<view class="" v-if="state.data.status === 0"> </view> </button>
</view> </view>
</s-layout> <view class="" v-if="state.data.status === 0"> </view>
</view>
</s-layout>
</template> </template>
<script setup> <script setup>
import { computed, reactive } from 'vue'; import {
import sheep from '@/sheep'; computed,
import { onLoad } from '@dcloudio/uni-app'; reactive
} from 'vue';
import sheep from '@/sheep';
import {
onLoad
} from '@dcloudio/uni-app';
const userInfo = computed(() => sheep.$store('user').userInfo); const userInfo = computed(() => sheep.$store('user').userInfo);
const statusBarHeight = sheep.$platform.device.statusBarHeight * 2; const statusBarHeight = sheep.$platform.device.statusBarHeight * 2;
const headerBg = sheep.$url.css('/static/img/shop/user/withdraw_bg.png'); const headerBg = sheep.$url.css('/static/img/shop/user/withdraw_bg.png');
const state = reactive({ const state = reactive({
recharge_money: '', recharge_money: '',
data: {}, data: {},
faceValueList: [], faceValueList: [],
}); });
// //
function onCard(e) { function onCard(e) {
state.recharge_money = e; state.recharge_money = e;
} }
async function getRechargeTabs() { async function getRechargeTabs() {
const res = await sheep.$api.trade.rechargeRules(); const res = await sheep.$api.trade.rechargeRules();
if (res.error === 0) { const res2 = await sheep.$api.trade.rechargeRules2();
state.data = res.data; if (res.error === 0) {
state.data.status = res.data.status; state.data = res.data;
state.faceValueList = res.data.quick_amounts; state.data.status = res.data.status;
} console.log(res);
} console.log(res2);
// state.faceValueList = res.data.quick_amounts;
state.faceValueList = res2.data;
}
}
function onChange(e) { function onChange(e) {
state.data.gift_type = e.detail.value; state.data.gift_type = e.detail.value;
} }
async function onConfirm() { async function onConfirm() {
const { error, data } = await sheep.$api.trade.recharge({ const {
recharge_money: state.recharge_money, code,
}); data
if (error === 0) { } = await sheep.$api.trade.recharge({
// #ifdef MP packageId: 0,
sheep.$platform.useProvider('wechat').subscribeMessage('money_change'); payPrice: state.recharge_money * 100
// #endif });
sheep.$router.go('/pages/pay/index', { orderSN: data.order_sn, type: 'recharge' }); if (code === 0) {
} // #ifdef MP
} sheep.$platform.useProvider('wechat').subscribeMessage('money_change');
onLoad(() => { // #endif
getRechargeTabs(); sheep.$router.go('/pages/pay/index', {
}); orderSN: data.order_sn,
type: 'recharge'
});
}
}
onLoad(() => {
getRechargeTabs();
});
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
:deep() { :deep() {
.uni-input-input { .uni-input-input {
font-family: OPPOSANS !important; font-family: OPPOSANS !important;
} }
} }
.wallet-num-box { .wallet-num-box {
padding: 0 40rpx 80rpx; padding: 0 40rpx 80rpx;
background: var(--ui-BG-Main) v-bind(headerBg) center/750rpx 100% no-repeat; background: var(--ui-BG-Main) v-bind(headerBg) center/750rpx 100% no-repeat;
border-radius: 0 0 5% 5%; border-radius: 0 0 5% 5%;
.num-title { .num-title {
font-size: 26rpx; font-size: 26rpx;
font-weight: 500; font-weight: 500;
color: $white; color: $white;
margin-bottom: 20rpx; margin-bottom: 20rpx;
} }
.wallet-num { .wallet-num {
font-size: 60rpx; font-size: 60rpx;
font-weight: 500; font-weight: 500;
color: $white; color: $white;
font-family: OPPOSANS; font-family: OPPOSANS;
} }
.log-btn { .log-btn {
width: 170rpx; width: 170rpx;
height: 60rpx; height: 60rpx;
line-height: 60rpx; line-height: 60rpx;
border: 1rpx solid $white; border: 1rpx solid $white;
border-radius: 30rpx; border-radius: 30rpx;
padding: 0; padding: 0;
font-size: 26rpx; font-size: 26rpx;
font-weight: 500; font-weight: 500;
color: $white; color: $white;
} }
} }
.recharge-box { .recharge-box {
position: relative; position: relative;
padding: 0 30rpx; padding: 0 30rpx;
margin-top: -60rpx; margin-top: -60rpx;
} }
.save-btn { .save-btn {
width: 620rpx; width: 620rpx;
height: 86rpx; height: 86rpx;
border-radius: 44rpx; border-radius: 44rpx;
font-size: 30rpx; font-size: 30rpx;
} }
.recharge-card-box { .recharge-card-box {
width: 690rpx; width: 690rpx;
background: var(--ui-BG); background: var(--ui-BG);
border-radius: 20rpx; border-radius: 20rpx;
padding: 30rpx; padding: 30rpx;
box-sizing: border-box; box-sizing: border-box;
.input-label { .input-label {
font-size: 30rpx; font-size: 30rpx;
font-weight: 500; font-weight: 500;
color: #333; color: #333;
} }
.unit { .unit {
display: flex; display: flex;
align-items: center; align-items: center;
font-size: 48rpx; font-size: 48rpx;
font-weight: 500; font-weight: 500;
} }
.uni-easyinput__placeholder-class { .uni-easyinput__placeholder-class {
font-size: 30rpx; font-size: 30rpx;
height: 60rpx; height: 60rpx;
display: flex; display: flex;
align-items: center; align-items: center;
} }
:deep(.uni-easyinput__content-input) { :deep(.uni-easyinput__content-input) {
font-size: 48rpx; font-size: 48rpx;
} }
.face-value-btn { .face-value-btn {
width: 200rpx; width: 200rpx;
height: 144rpx; height: 144rpx;
border: 1px solid var(--ui-BG-Main); border: 1px solid var(--ui-BG-Main);
border-radius: 10rpx; border-radius: 10rpx;
position: relative; position: relative;
z-index: 1; z-index: 1;
margin-bottom: 15rpx; margin-bottom: 15rpx;
margin-right: 15rpx; margin-right: 15rpx;
&:nth-of-type(3n) { &:nth-of-type(3n) {
margin-right: 0; margin-right: 0;
} }
.face-value-title { .face-value-title {
font-size: 36rpx; font-size: 36rpx;
font-weight: 500; font-weight: 500;
color: var(--ui-BG-Main); color: var(--ui-BG-Main);
font-family: OPPOSANS; font-family: OPPOSANS;
&::after { &::after {
content: '元'; content: '元';
font-size: 24rpx; font-size: 24rpx;
margin-left: 6rpx; margin-left: 6rpx;
} }
} }
.face-value-tag { .face-value-tag {
position: absolute; position: absolute;
z-index: 2; z-index: 2;
height: 40rpx; height: 40rpx;
line-height: 40rpx; line-height: 40rpx;
background: var(--ui-BG-Main); background: var(--ui-BG-Main);
opacity: 0.8; opacity: 0.8;
border-radius: 10rpx 0 20rpx 0; border-radius: 10rpx 0 20rpx 0;
top: 0; top: 0;
left: -2rpx; left: -2rpx;
padding: 0 16rpx; padding: 0 16rpx;
font-size: 22rpx; font-size: 22rpx;
color: $white; color: $white;
font-family: OPPOSANS; font-family: OPPOSANS;
} }
&::before { &::before {
position: absolute; position: absolute;
content: ' '; content: ' ';
width: 100%; width: 100%;
height: 100%; height: 100%;
background: var(--ui-BG-Main); background: var(--ui-BG-Main);
opacity: 0.1; opacity: 0.1;
z-index: 0; z-index: 0;
left: 0; left: 0;
top: 0; top: 0;
} }
} }
.btn-active { .btn-active {
z-index: 1; z-index: 1;
&::before { &::before {
content: ''; content: '';
background: var(--ui-BG-Main); background: var(--ui-BG-Main);
opacity: 1; opacity: 1;
} }
.face-value-title { .face-value-title {
color: $white; color: $white;
position: relative; position: relative;
z-index: 1; z-index: 1;
font-family: OPPOSANS; font-family: OPPOSANS;
} }
.face-value-tag { .face-value-tag {
background: $white; background: $white;
color: var(--ui-BG-Main); color: var(--ui-BG-Main);
font-family: OPPOSANS; font-family: OPPOSANS;
} }
} }
} }
</style> </style>

View File

@ -2,27 +2,34 @@
<template> <template>
<s-layout title="支付结果" :bgStyle="{ color: '#FFF' }"> <s-layout title="支付结果" :bgStyle="{ color: '#FFF' }">
<view class="pay-result-box ss-flex-col ss-row-center ss-col-center"> <view class="pay-result-box ss-flex-col ss-row-center ss-col-center">
<!-- 信息展示 --> <view class="pay-waiting ss-m-b-30" v-if="payResult === 'waiting'"> </view>
<view class="pay-waiting ss-m-b-30" v-if="payResult === 'waiting'" />
<image <image
class="pay-img ss-m-b-30" class="pay-img ss-m-b-30"
v-if="payResult === 'success'" v-if="payResult === 'success'"
:src="sheep.$url.static('/static/img/shop/order/order_pay_success.gif')" :src="sheep.$url.static('/static/img/shop/order/order_pay_success.gif')"
/> ></image>
<image <image
class="pay-img ss-m-b-30" class="pay-img ss-m-b-30"
v-if="['failed', 'closed'].includes(payResult)" v-if="['failed', 'closed'].includes(payResult)"
:src="sheep.$url.static('/static/img/shop/order/order_paty_fail.gif')" :src="sheep.$url.static('/static/img/shop/order/order_paty_fail.gif')"
/> ></image>
<view class="tip-text ss-m-b-30" v-if="payResult === 'success'"></view> <view class="tip-text ss-m-b-30" v-if="payResult == 'success'">{{
<view class="tip-text ss-m-b-30" v-if="payResult === 'failed'"></view> state.orderInfo.pay_mode === 'offline' ? '下单成功' : '支付成功'
<view class="tip-text ss-m-b-30" v-if="payResult === 'closed'"></view> }}</view>
<view class="tip-text ss-m-b-30" v-if="payResult === 'waiting'">...</view> <view class="tip-text ss-m-b-30" v-if="payResult == 'failed'"></view>
<view class="tip-text ss-m-b-30" v-if="payResult == 'closed'"></view>
<view class="tip-text ss-m-b-30" v-if="payResult == 'waiting'">...</view>
<view class="pay-total-num ss-flex" v-if="payResult === 'success'"> <view class="pay-total-num ss-flex" v-if="payResult === 'success'">
<view>{{ fen2yuan(state.orderInfo.price) }}</view> <view v-if="Number(state.orderInfo.pay_fee) > 0">{{ state.orderInfo.pay_fee }}</view>
<view v-if="state.orderInfo.score_amount && Number(state.orderInfo.pay_fee) > 0">+</view>
<view class="price-text ss-flex ss-col-center" v-if="state.orderInfo.score_amount">
<image
:src="sheep.$url.static('/static/img/shop/goods/score1.svg')"
class="score-img"
></image>
<view>{{ state.orderInfo.score_amount }}</view>
</view>
</view> </view>
<!-- 操作区 -->
<view class="btn-box ss-flex ss-row-center ss-m-t-50"> <view class="btn-box ss-flex ss-row-center ss-m-t-50">
<button class="back-btn ss-reset-button" @tap="sheep.$router.go('/pages/index/index')"> <button class="back-btn ss-reset-button" @tap="sheep.$router.go('/pages/index/index')">
返回首页 返回首页
@ -30,29 +37,30 @@
<button <button
class="check-btn ss-reset-button" class="check-btn ss-reset-button"
v-if="payResult === 'failed'" v-if="payResult === 'failed'"
@tap=" @tap="sheep.$router.redirect('/pages/pay/index', { orderSN: state.orderId })"
sheep.$router.redirect('/pages/pay/index', { id: state.id, orderType: state.orderType })
"
> >
重新支付 重新支付
</button> </button>
<button class="check-btn ss-reset-button" v-if="payResult === 'success'" @tap="onOrder"> <button class="check-btn ss-reset-button" v-if="payResult === 'success'" @tap="onOrder">
查看订单 查看订单
</button> </button>
<!-- TODO 芋艿拼团接入 -->
<button <button
class="check-btn ss-reset-button" class="check-btn ss-reset-button"
v-if="payResult === 'success' && state.tradeOrder.type === 3" v-if="
payResult === 'success' &&
['groupon', 'groupon_ladder'].includes(state.orderInfo.activity_type)
"
@tap="sheep.$router.redirect('/pages/activity/groupon/order')" @tap="sheep.$router.redirect('/pages/activity/groupon/order')"
> >
我的拼团 我的拼团
</button> </button>
</view> </view>
<!-- TODO 芋艿订阅 -->
<!-- #ifdef MP --> <!-- #ifdef MP -->
<view class="subscribe-box ss-flex ss-m-t-44"> <view class="subscribe-box ss-flex ss-m-t-44">
<image class="subscribe-img" :src="sheep.$url.static('/static/img/shop/order/cargo.png')" /> <image
class="subscribe-img"
:src="sheep.$url.static('/static/img/shop/order/cargo.png')"
></image>
<view class="subscribe-title ss-m-r-48 ss-m-l-16">获取实时发货信息与订单状态</view> <view class="subscribe-title ss-m-r-48 ss-m-l-16">获取实时发货信息与订单状态</view>
<view class="subscribe-start" @tap="subscribeMessage"></view> <view class="subscribe-start" @tap="subscribeMessage"></view>
</view> </view>
@ -66,20 +74,15 @@
import { reactive, computed } from 'vue'; import { reactive, computed } from 'vue';
import { isEmpty } from 'lodash'; import { isEmpty } from 'lodash';
import sheep from '@/sheep'; import sheep from '@/sheep';
import PayOrderApi from '@/sheep/api/pay/order';
import { fen2yuan } from '../../sheep/hooks/useGoods';
import OrderApi from '@/sheep/api/trade/order';
const state = reactive({ const state = reactive({
id: 0, // orderId: 0,
orderType: 'goods', // orderType: 'goods',
result: 'unpaid', // result: 'unpaid', //
orderInfo: {}, // orderInfo: {}, //
tradeOrder: {}, // orderType goods
counter: 0, // counter: 0, //
}); });
// result => payResult
const payResult = computed(() => { const payResult = computed(() => {
if (state.result === 'unpaid') { if (state.result === 'unpaid') {
return 'waiting'; return 'waiting';
@ -90,65 +93,57 @@
if (state.result === 'failed') { if (state.result === 'failed') {
return 'failed'; return 'failed';
} }
if (state.result === 'closed') { if (state.result === 'closed') {
return 'closed'; return 'closed';
} }
}); });
async function getOrderInfo(orderId) {
// let checkPayResult;
async function getOrderInfo(id) {
state.counter++; state.counter++;
// 1. if (state.orderType === 'recharge') {
const { data, code } = await PayOrderApi.getOrder(id); checkPayResult = sheep.$api.trade.order;
if (code === 0) { } else {
checkPayResult = sheep.$api.order.detail;
}
const { data, error } = await checkPayResult(orderId);
if (error === 0) {
state.orderInfo = data; state.orderInfo = data;
if (!state.orderInfo || state.orderInfo.status === 30) { if (state.orderInfo.status === 'closed') {
//
state.result = 'closed'; state.result = 'closed';
return; return;
} }
if (state.orderInfo.status !== 0) { if (state.orderInfo.status !== 'unpaid') {
// 退
state.result = 'paid'; state.result = 'paid';
// #ifdef MP // #ifdef MP
subscribeMessage(); subscribeMessage();
// #endif // #endif
//
if (state.orderType === 'goods') {
const { data, code } = await OrderApi.getOrder(state.orderInfo.merchantOrderId);
if (code === 0) {
state.tradeOrder = data;
}
}
return; return;
} }
} }
// 2.1
if (state.counter < 3 && state.result === 'unpaid') { if (state.counter < 3 && state.result === 'unpaid') {
setTimeout(() => { setTimeout(() => {
getOrderInfo(id); getOrderInfo(orderId);
}, 1500); }, 1500);
} }
// 2.2 //
if (state.counter >= 3) { if (state.counter >= 3) {
state.result = 'failed'; state.result = 'failed';
} }
} }
function onOrder() { function onOrder() {
// TODO if ((state.orderType === 'recharge')) {
if (state.orderType === 'recharge') {
sheep.$router.redirect('/pages/pay/recharge-log'); sheep.$router.redirect('/pages/pay/recharge-log');
} else { } else {
sheep.$router.redirect('/pages/order/list'); sheep.$router.redirect('/pages/order/list');
} }
} }
// TODO
// #ifdef MP // #ifdef MP
function subscribeMessage() { function subscribeMessage() {
let event = ['order_dispatched']; let event = ['order_dispatched'];
if (state.tradeOrder.type === 3) { if (['groupon', 'groupon_ladder'].includes(state.orderInfo.activity_type)) {
event.push('groupon_finish'); event.push('groupon_finish');
event.push('groupon_fail'); event.push('groupon_fail');
} }
@ -157,13 +152,18 @@
// #endif // #endif
onLoad(async (options) => { onLoad(async (options) => {
let id = '';
// //
if (options.id) { if (options.orderSN) {
state.id = options.id; id = options.orderSN;
} }
// if (options.id) {
if (options.orderType) { id = options.id;
state.orderType = options.orderType; }
state.orderId = id;
if (options.orderType === 'recharge') {
state.orderType = 'recharge';
} }
// //
@ -171,16 +171,14 @@
state.result = 'failed'; state.result = 'failed';
} else { } else {
// //
await getOrderInfo(state.id); getOrderInfo(state.orderId);
} }
}); });
onShow(() => { onShow(() => {
if (isEmpty(state.orderInfo)) { if(isEmpty(state.orderInfo)) return;
return; getOrderInfo(state.orderId);
} })
getOrderInfo(state.id);
});
onHide(() => { onHide(() => {
state.result = 'unpaid'; state.result = 'unpaid';

View File

@ -101,6 +101,7 @@
}, },
); );
const onRegionConfirm = (e) => { const onRegionConfirm = (e) => {
console.log(e);
state.model = { state.model = {
...state.model, ...state.model,
...e, ...e,
@ -186,7 +187,13 @@
if (options.data) { if (options.data) {
let data = JSON.parse(options.data); let data = JSON.parse(options.data);
console.log(data) const areaData = uni.getStorageSync('areaData');
let provinceArr = areaData.filter(item => item.name == data.province_name);
data.province_id = provinceArr[0].id;
let provinceArr2 = provinceArr[0].children.filter(item => item.name == data.city_name);
data.city_id = provinceArr2[0].id;
let provinceArr3 = provinceArr2[0].children.filter(item => item.name == data.district_name);
data.district_id = provinceArr3[0].id;
state.model = { state.model = {
...state.model, ...state.model,
...data, ...data,

View File

@ -1,12 +1,11 @@
<!-- 我的商品收藏 -->
<template> <template>
<s-layout title="商品收藏"> <s-layout title="商品收藏">
<view class="cart-box ss-flex ss-flex-col ss-row-between"> <view class="cart-box ss-flex ss-flex-col ss-row-between">
<!-- 头部 --> <!-- 头部 -->
<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.pagination.total }}</text> 件商品
<text class="goods-number ui-TC-Main ss-flex">{{ state.pagination.total }}</text>
件商品
</view> </view>
<view class="header-right"> <view class="header-right">
<button <button
@ -20,15 +19,16 @@
v-if="!state.editMode && state.pagination.total" v-if="!state.editMode && state.pagination.total"
class="ss-reset-button ui-TC-Main" class="ss-reset-button ui-TC-Main"
@tap="state.editMode = true" @tap="state.editMode = true"
>编辑</button
> >
编辑
</button>
</view> </view>
</view> </view>
<!-- 内容 --> <!-- 内容 -->
<view class="cart-content"> <view class="cart-content">
<view <view
class="goods-box ss-r-10 ss-m-b-14" class="goods-box ss-r-10 ss-m-b-14"
v-for="item in state.pagination.data" v-for="item in state.pagination.list"
:key="item.id" :key="item.id"
> >
<view class="ss-flex ss-col-center"> <view class="ss-flex ss-col-center">
@ -44,12 +44,10 @@
@tap.stop="onSelect(item.spuId)" @tap.stop="onSelect(item.spuId)"
/> />
</label> </label>
<!-- :skuText="item.goods.subtitle" -->
<s-goods-item <s-goods-item
:title="item.spuName" :title="item.spuName"
:img="item.picUrl" :img="item.picUrl"
:price="item.price" :price="item.price"
priceColor="#FF3000" priceColor="#FF3000"
:titleWidth="400" :titleWidth="400"
@tap=" @tap="
@ -57,11 +55,11 @@
id: item.spuId, id: item.spuId,
}) })
" "
> />
</s-goods-item>
</view> </view>
</view> </view>
</view> </view>
<!-- 底部 --> <!-- 底部 -->
<su-fixed bottom :val="0" placeholder v-show="state.editMode"> <su-fixed bottom :val="0" placeholder v-show="state.editMode">
<view class="cart-footer ss-flex ss-col-center ss-row-between ss-p-x-30 border-bottom"> <view class="cart-footer ss-flex ss-col-center ss-row-between ss-p-x-30 border-bottom">
@ -79,9 +77,9 @@
<view class="footer-right"> <view class="footer-right">
<button <button
class="ss-reset-button ui-BG-Main-Gradient pay-btn ss-font-28 ui-Shadow-Main" class="ss-reset-button ui-BG-Main-Gradient pay-btn ss-font-28 ui-Shadow-Main"
@tap="onCancel" @tap="onCancel">
>取消收藏</button 取消收藏
> </button>
</view> </view>
</view> </view>
</su-fixed> </su-fixed>
@ -92,7 +90,7 @@
:content-text="{ :content-text="{
contentdown: '上拉加载更多', contentdown: '上拉加载更多',
}" }"
@tap="loadmore" @tap="loadMore"
/> />
<s-empty v-if="state.pagination.total === 0" text="暂无收藏" icon="/static/collect-empty.png" /> <s-empty v-if="state.pagination.total === 0" text="暂无收藏" icon="/static/collect-empty.png" />
</s-layout> </s-layout>
@ -103,98 +101,89 @@
import { reactive } from 'vue'; import { reactive } from 'vue';
import { onLoad, onReachBottom } from '@dcloudio/uni-app'; import { onLoad, onReachBottom } from '@dcloudio/uni-app';
import _ from 'lodash'; import _ from 'lodash';
import FavoriteApi from '@/sheep/api/product/favorite';
import { resetPagination } from '@/sheep/util';
const sys_navBar = sheep.$platform.navbar; const sys_navBar = sheep.$platform.navbar;
const pagination = {
data: [],
current_page: 1,
total: 1,
last_page: 1,
};
const state = reactive({ const state = reactive({
pagination: { pagination: {
data: [], list: [],
current_page: 1, total: 0,
total: 1, pageNo: 1,
last_page: 1, pageSize: 6,
}, },
loadStatus: '', loadStatus: '',
editMode: false, editMode: false,
selectedCollectList: [], selectedCollectList: [], // SPU
selectAll: false, selectAll: false,
}); });
async function getData(page = 1, list_rows = 6) { async function getData() {
state.loadStatus = 'loading'; state.loadStatus = 'loading';
let res = await sheep.$api.user.favorite.list({ const { code, data } = await FavoriteApi.getFavoritePage({
pageSize:list_rows, pageNo: state.pagination.pageNo,
pageNo:page, pageSize: state.pagination.pageSize,
}); });
if (res.code === 0) { if (code !== 0) {
console.log('yudao收藏列表',res) return;
let orderList = _.concat(state.pagination.data, res.data.list);
state.pagination = {
...res.data,
data: orderList,
};
//
if (state.pagination.current_page < state.pagination.last_page) {
state.loadStatus = 'more';
} else {
state.loadStatus = 'noMore';
}
} }
} state.pagination.list = _.concat(state.pagination.list, data.list)
// state.pagination.total = data.total;
function formatPrice(e) { state.loadStatus = state.pagination.list.length < state.pagination.total ? 'more' : 'noMore';
return e.length === 1 ? e[0] : e.join('~');
} }
// //
const onSelect = (id) => { const onSelect = (spuId) => {
if (!state.selectedCollectList.includes(id)) { if (!state.selectedCollectList.includes(spuId)) {
state.selectedCollectList.push(id); state.selectedCollectList.push(spuId);
} else { } else {
state.selectedCollectList.splice(state.selectedCollectList.indexOf(id), 1); state.selectedCollectList.splice(state.selectedCollectList.indexOf(spuId), 1);
} }
state.selectAll = state.selectedCollectList.length === state.pagination.data.length; state.selectAll = state.selectedCollectList.length === state.pagination.list.length;
}; };
// //
const onSelectAll = () => { const onSelectAll = () => {
state.selectAll = !state.selectAll; state.selectAll = !state.selectAll;
if (!state.selectAll) { if (!state.selectAll) {
state.selectedCollectList = []; state.selectedCollectList = [];
} else { } else {
state.pagination.data.forEach((item) => { state.selectedCollectList = state.pagination.list.map((item) => item.spuId);
if (state.selectedCollectList.includes(item.goods_id)) {
state.selectedCollectList.splice(state.selectedCollectList.indexOf(item.goods_id), 1);
}
state.selectedCollectList.push(item.goods_id);
});
} }
}; };
async function onCancel() { async function onCancel() {
if (state.selectedCollectList) { if (!state.selectedCollectList) {
state.selectedCollectList = state.selectedCollectList.toString(); return;
const { code } = await sheep.$api.user.favorite.cancel(state.selectedCollectList);
if (code === 0) {
state.editMode = false;
state.selectedCollectList = [];
state.selectAll = false;
state.pagination = pagination;
getData();
}
} }
//
for (const spuId of state.selectedCollectList) {
await FavoriteApi.deleteFavorite(spuId);
}
// +
state.editMode = false;
state.selectedCollectList = [];
state.selectAll = false;
resetPagination(state.pagination);
await getData();
} }
// //
function loadmore() { function loadMore() {
if (state.loadStatus !== 'noMore') { if (state.loadStatus === 'noMore') {
getData(state.pagination.current_page + 1); return
} }
state.pagination.pageNo++;
getData();
} }
onReachBottom(() => { onReachBottom(() => {
loadmore(); loadMore();
}); });
onLoad(() => { onLoad(() => {
getData(); getData();
}); });

View File

@ -1,43 +1,64 @@
import request from '@/sheep/request'; import request from '@/sheep/request';
export default { export default {
myGroupon: (params) => myGroupon: (params) =>
request({ request({
url: 'activity/groupon/myGroupons', url: 'activity/groupon/myGroupons',
method: 'GET', method: 'GET',
params, params,
}), }),
getGrouponList: (params) => getGrouponList: (params) =>
request({ request({
url: 'activity/groupon', url: 'activity/groupon',
method: 'GET', method: 'GET',
params, params,
}), }),
grouponDetail: (id) => grouponDetail: (id) =>
request({ request({
url: 'activity/groupon/' + id, url: 'activity/groupon/' + id,
method: 'GET', method: 'GET',
}), }),
signList: (params) => signList: (params) =>
request({ request({
url: 'activity/signin', url: 'activity/signin',
method: 'GET', method: 'GET',
params, params,
}), }),
signAdd: () => signAdd: () =>
request({ request({
url: 'activity/signin', url: '/app-api/member/sign-in/record/create',
method: 'POST', method: 'POST',
}), }),
replenish: (data) => configLise: () =>
request({ request({
url: 'activity/signin/replenish', url: '/app-api/member/sign-in/config/list',
method: 'POST', method: 'GET',
data, }),
}), recordPage: () =>
activity: (id) => request({
request({ url: '/app-api/member/sign-in/record/page',
url: 'activity/activity/' + id, method: 'GET',
method: 'GET', }),
}), // signAdd: () =>
}; // request({
// url: 'activity/signin',
// method: 'POST',
// }),
replenish: (data) =>
request({
url: 'activity/signin/replenish',
method: 'POST',
data,
}),
activity: (id) =>
request({
url: 'activity/activity/' + id,
method: 'GET',
}),
getSummary: () =>
request({
url: '/app-api/member/sign-in/record/get-summary',
method: 'GET',
}),
};

View File

@ -115,14 +115,12 @@ export default {
formData: { formData: {
group, group,
}, },
// TODO 芋艿:临时写死
header: { header: {
// Accept: 'text/json', // Accept: 'text/json',
// Authorization: token, // Authorization: token,
Accept : '*/*', Accept : '*/*',
'tenant-id' :'1', 'tenant-id' :'1',
'terminal': 20, Authorization: 'Bearer test247',
Authorization: 'Bearer test247',
}, },
success: (uploadFileRes) => { success: (uploadFileRes) => {
let result = JSON.parse(uploadFileRes.data); let result = JSON.parse(uploadFileRes.data);

View File

@ -1,9 +1,10 @@
import request from '@/sheep/request'; import request from '@/sheep/request';
import request2 from '@/sheep/request2';
export default { export default {
list: (data) => list: (data) =>
request({ request2({
url: '/app-api/trade/cart/list', url: 'trade/cart/list',
method: 'GET', method: 'GET',
custom: { custom: {
showLoading: false, showLoading: false,
@ -12,40 +13,26 @@ export default {
}), }),
append: (data) => append: (data) =>
request({ request({
url: '/app-api/trade/cart/add', url: 'cart',
method: 'POST', method: 'POST',
// TODO 芋艿:这里没提示
custom: { custom: {
showSuccess: true, showSuccess: true,
successMsg: '已添加到购物车~', successMsg: '已添加到购物车~',
}, },
data: { data: {
...data, ...data,
// type: 'inc', type: 'inc',
}, },
}), }),
// append: (data) =>
// request({
// url: 'cart',
// method: 'POST',
// custom: {
// showSuccess: true,
// successMsg: '已添加到购物车~',
// },
// data: {
// ...data,
// type: 'inc',
// },
// }),
// 删除购物车 // 删除购物车
delete: (ids) => delete: (ids) =>
request({ request2({
url: '/app-api/trade/cart/delete?ids=' + ids, url: 'trade/cart/delete?ids=' + ids,
method: 'DELETE', method: 'DELETE',
}), }),
update: (data) => update: (data) =>
request({ request2({
url: '/app-api/trade/cart/update-count', url: 'trade/cart/update-count',
method: 'PUT', method: 'PUT',
data: { data: {
...data, ...data,

View File

@ -1,8 +1,10 @@
import request2 from '@/sheep/request2';
export default { export default {
list: (params) => list: (params) =>
request({ request2({
url: '/app-api/product/category/list', url: 'product/category/list',
method: 'GET', method: 'GET',
params, params,
}), }),
}; };

View File

@ -1,4 +1,5 @@
import request from '@/sheep/request'; import request from '@/sheep/request';
import request2 from '@/sheep/request2';
export default { export default {
// 我的拼团 // 我的拼团
@ -12,8 +13,8 @@ export default {
}, },
}), }),
userCoupon: (params) => userCoupon: (params) =>
request({ request2({
url: '/app-api/promotion/coupon/page', url: 'promotion/coupon/page',
method: 'GET', method: 'GET',
params, params,
}), }),
@ -33,20 +34,9 @@ export default {
}), }),
get: (id) => get: (id) =>
request({ request({
url: '/app-api/promotion/coupon/take', url: 'coupon/get/' + id,
method: 'POST', method: 'POST',
data: {
templateId: id
},
params: {
templateId: id
},
}), }),
// get: (id) =>
// request({
// url: 'coupon/get/' + id,
// method: 'POST',
// }),
listByGoods: (id) => listByGoods: (id) =>
request({ request({
url: 'coupon/listByGoods/' + id, url: 'coupon/listByGoods/' + id,

View File

@ -1,24 +1,25 @@
import request from '@/sheep/request'; import request from '@/sheep/request';
import request2 from '@/sheep/request2';
export default { export default {
area: () => area: () =>
request({ request2({
url: '/app-api/system/area/tree', url: 'system/area/tree',
method: 'GET', method: 'GET',
}), }),
// area: () => // area: () =>
// request({ // request({
// url: 'data/area', // url: 'data/area',
// method: 'GET', // method: 'GET',
// }), // }),
faq: () => faq: () =>
request({ request({
url: 'data/faq', url: 'data/faq',
method: 'GET', method: 'GET',
}), }),
richtext: (id) => richtext: (id) =>
request({ request({
url: 'data/richtext/' + id, url: 'data/richtext/' + id,
method: 'GET', method: 'GET',
}), }),
}; };

View File

@ -1,84 +1,80 @@
import request from '@/sheep/request'; import request from '@/sheep/request';
import request2 from '@/sheep/request2';
export default { export default {
// 商品详情 // 商品详情
detail: (id, params = {}) => detail: (id, params = {}) =>
request({ request2({
url: '/app-api/product/spu/get-detail?id=' + id, url: 'product/spu/get-detail?id=' + id,
method: 'GET', method: 'GET',
params, params,
custom: { custom: {
showLoading: false, showLoading: false,
showError: false, showError: false,
}, },
}), }),
// 商品列表 // 商品列表
list: (params) => list: (params) =>
request({ request2({
url: '/app-api/product/spu/page', url: 'product/spu/page',
method: 'GET', method: 'GET',
params, params,
custom: { custom: {
showLoading: false, showLoading: false,
showError: false, showError: false,
}, },
}), }),
// 商品查询 // 商品查询
ids: (params = {}) => ids: (params = {}) =>
request({ request({
url: 'goods/goods/ids', url: 'goods/goods/ids',
method: 'GET', method: 'GET',
params, params,
custom: { custom: {
showLoading: false, showLoading: false,
showError: false, showError: false,
}, },
}), }),
// 商品评价列表
comment: (id, params = {}) => // 商品评价列表
request({ comment: (id, params = {}) =>
url: '/app-api/product/comment/list?spuId=' + id, request2({
method: 'GET', url: 'product/comment/list?spuId=' + id,
params, method: 'GET',
custom: { params,
showLoading: false, custom: {
showError: false, showLoading: false,
}, showError: false,
}), },
// 商品评价类型 }),
getType: (id) => // 商品评价类型
request({ getType: (id) =>
url: 'goods/comment/getType/' + id, request({
method: 'GET', url: 'goods/comment/getType/' + id,
custom: { method: 'GET',
showLoading: false, custom: {
showError: false, showLoading: false,
}, showError: false,
}), },
// 活动商品查询 }),
// 商品查询 // 活动商品查询
activity: (params = {}) => // 商品查询
request({ activity: (params = {}) =>
url: 'goods/goods/activity', request({
method: 'GET', url: 'goods/goods/activity',
params, method: 'GET',
custom: { params,
showLoading: false, custom: {
showError: false, showLoading: false,
}, showError: false,
}), },
activityList: (params = {}) => }),
request({ activityList: (params = {}) =>
url: 'goods/goods/activityList', request({
method: 'GET', url: 'goods/goods/activityList',
params, method: 'GET',
}), params,
// 检查是否收藏商品 }),
exits: (id) => };
request({
url: '/app-api/product/favorite/exits?spuId=' + id,
method: 'GET',
}),
};

View File

@ -1,14 +1,14 @@
import request from '@/sheep/request'; import request2 from '@/sheep/request2';
export default { export default {
decorate: () => decorate: () =>
request({ request2({
url: '/app-api/promotion/decorate/list?page=1', url: 'promotion/decorate/list?page=1',
method: 'GET', method: 'GET',
}), }),
spids: () => spids: () =>
request({ request2({
url: '/app-api/product/spu/page?recommendType=best&pageNo=1&pageSize=10', url: 'product/spu/page?recommendType=best&pageNo=1&pageSize=10',
method: 'GET', method: 'GET',
}), }),
}; };

View File

@ -1,10 +1,11 @@
import request from '@/sheep/request'; import request from '@/sheep/request';
import request2 from '@/sheep/request2';
export default { export default {
// 订单详情 // 订单详情
detail: (id, params) => detail: (id, params) =>
request({ request2({
url: '/app-api/trade/order/get-detail?id=' + id, url: 'trade/order/get-detail?id=' + id,
method: 'GET', method: 'GET',
params, params,
}), }),
@ -37,7 +38,16 @@ export default {
showLoading: false, showLoading: false,
}, },
}), }),
// 订单列表
list: (params) =>
request2({
url: 'trade/order/page',
method: 'GET',
params,
custom: {
showLoading: false,
},
}),
// list: (params) => // list: (params) =>
// request({ // request({
// url: 'order/order', // url: 'order/order',
@ -55,27 +65,27 @@ export default {
// 解决 SpringMVC 接受 List<Item> 参数的问题 // 解决 SpringMVC 接受 List<Item> 参数的问题
delete data2.items delete data2.items
for (let i = 0; i < data.items.length; i++) { for (let i = 0; i < data.items.length; i++) {
// 此处转码问题,待解决方案 // data2['items[' + i + '' + '].skuId'] = data.items[i].skuId + '';
data2[encodeURIComponent('items[' + i + '' + '].skuId')] = data.items[i].skuId + ''; // data2['items[' + i + '' + '].count'] = data.items[i].count + '';
data2[encodeURIComponent('items[' + i + '' + '].count')] = data.items[i].count + ''; // data2['items[' + i + '' + '].cartId'] = data.items[i].cartId + '';
data2[encodeURIComponent('items[' + i + '' + '].cartId')] = data.items[i].cartId + ''; data2['items' + `%5B${i}%5D` + '.skuId'] = data.items[i].skuId + '';
data2['items' + `%5B${i}%5D` + '.count'] = data.items[i].count + '';
// data2['items' + `[${i}]` + '.skuId'] = data.items[i].skuId + ''; data2['items' + `%5B${i}%5D` + '.cartId'] = data.items[i].cartId + '';
// data2['items' + `[${i}]` + '.count'] = data.items[i].count + '';
// data2['items' + `[${i}]` + '.cartId'] = data.items[i].cartId + '';
// data2['items' + `%5B${i}%5D` + '.skuId'] = data.items[i].skuId + '';
// data2['items' + `%5B${i}%5D` + '.count'] = data.items[i].count + '';
// data2['items' + `%5B${i}%5D` + '.cartId'] = data.items[i].cartId + '';
} }
console.log(data2, '手动转码的参数') console.log(data2, '对比数据')
return request({ return request2({
url: '/app-api/trade/order/settlement', url: 'trade/order/settlement',
method: 'GET', method: 'GET',
// data: data2, // data,
params: data2 params: data2
}) })
}, },
// calc: (data) =>
// request({
// url: 'order/order/calc',
// method: 'POST',
// data,
// }),
// 创建订单 // 创建订单
create: (data) => create: (data) =>
request({ request({
@ -98,8 +108,8 @@ export default {
}), }),
// 评价订单 // 评价订单
comment: (data) => comment: (data) =>
request({ request2({
url: '/app-api/trade/order/item/create-comment', url: 'trade/order/item/create-comment',
method: 'POST', method: 'POST',
data, data,
}), }),
@ -129,15 +139,31 @@ export default {
}), }),
// 售后 // 售后
aftersale: { aftersale: {
list: (params) => // 申请售后
apply: (data) =>
request({ request({
url: '/app-api/trade/after-sale/page', url: 'order/aftersale',
method: 'POST',
data,
}),
list: (params) =>
request2({
url: 'trade/after-sale/page',
method: 'GET', method: 'GET',
params, params,
custom: { custom: {
showLoading: false, showLoading: false,
}, },
}), }),
// list: (params) =>
// request({
// url: 'order/aftersale',
// method: 'GET',
// params,
// custom: {
// showLoading: false,
// },
// }),
//取消售后 //取消售后
cancel: (id) => cancel: (id) =>
request({ request({
@ -150,10 +176,10 @@ export default {
url: 'order/aftersale/' + id, url: 'order/aftersale/' + id,
method: 'DELETE', method: 'DELETE',
}), }),
// 售后详情 DONE // 售后详情
detail: (id) => detail: (id) =>
request({ request2({
url: '/app-api/trade/after-sale/get?id=' + id, url: 'trade/after-sale/get?id=' + id,
method: 'GET', method: 'GET',
}), }),
}, },

View File

@ -1,14 +0,0 @@
import request from '@/sheep/request';
const PayChannelApi = {
// 获得指定应用的开启的支付渠道编码列表
getEnableChannelCodeList: (appId) => {
return request({
url: '/app-api/pay/channel/get-enable-code-list',
method: 'GET',
params: { appId }
});
},
};
export default PayChannelApi;

View File

@ -1,22 +0,0 @@
import request from '@/sheep/request';
const PayOrderApi = {
// 获得支付订单
getOrder: (id) => {
return request({
url: '/app-api/pay/order/get',
method: 'GET',
params: { id }
});
},
// 提交支付订单
submitOrder: (data) => {
return request({
url: '/app-api/pay/order/submit',
method: 'POST',
data
});
}
};
export default PayOrderApi;

View File

@ -1,19 +1,18 @@
import request from '@/sheep/request'; import request from '@/sheep/request';
const CommentApi = { const CommentApi = {
// 获得商品评价分页
// 获得商品评价分页 getCommentPage: (spuId, pageNo, pageSize, type) => {
getCommentPage: (spuId, pageNo, pageSize, type) => { return request({
return request({ url: '/app-api/product/comment/page',
url: '/app-api/product/comment/page', method: 'GET',
method: 'GET', params: {
params: { spuId,
spuId, pageNo,
pageNo, pageSize,
pageSize, type
type },
}, });
}); },
},
}; };
export default CommentApi; export default CommentApi;

View File

@ -0,0 +1,44 @@
import request from '@/sheep/request';
const FavoriteApi = {
// 获得商品收藏分页
getFavoritePage: (data) => {
return request({
url: '/app-api/product/favorite/page',
method: 'GET',
params: data
});
},
// 检查是否收藏过商品
isFavoriteExists: (spuId) => {
return request({
url: '/app-api/product/favorite/exits',
method: 'GET',
params: {
spuId
}
});
},
// 添加商品收藏
createFavorite: (spuId) => {
return request({
url: '/app-api/product/favorite/create',
method: 'POST',
data: {
spuId
}
});
},
// 取消商品收藏
deleteFavorite: (spuId) => {
return request({
url: '/app-api/product/favorite/delete',
method: 'DELETE',
data: {
spuId
}
});
}
};
export default FavoriteApi;

View File

@ -1,16 +1,16 @@
import request from '@/sheep/request'; import request2 from '@/sheep/request2';
const ActivityApi = { const ActivityApi = {
// 获得单个商品,近期参与的每个活动 // 获得单个商品,近期参与的每个活动
getActivityListBySpuId: (spuId) => { getActivityListBySpuId: (spuId) => {
return request({ return request2({
url: '/app-api/promotion/activity/list-by-spu-id', url: '/app-api/promotion/activity/list-by-spu-id',
method: 'GET', method: 'GET',
params: { params: {
spuId, spuId,
}, },
}); });
}, },
}; };
export default ActivityApi; export default ActivityApi;

View File

@ -1,69 +1,67 @@
import request from "@/sheep/request"; import request2 from "@/sheep/request2";
// 拼团 API // 拼团 API
const CombinationApi = { const CombinationApi = {
// 获得拼团活动列表 // 获得拼团活动列表
getCombinationActivityList: (count) => { getCombinationActivityList: (count) => {
return request({ return request2({
url: "/app-api/promotion/combination-activity/list", url: "promotion/combination-activity/list",
method: 'GET', method: 'GET',
params: { params: {count}
count });
} },
});
},
// 获得拼团活动分页 // 获得拼团活动分页
getCombinationActivityPage: (params) => { getCombinationActivityPage: (params) => {
return request({ return request2({
url: "/app-api/promotion/combination-activity/page", url: "promotion/combination-activity/page",
method: 'GET', method: 'GET',
params params
}); });
}, },
// 获得拼团活动明细 // 获得拼团活动明细
getCombinationActivity: (id) => { getCombinationActivity: (id) => {
return request({ return request2({
url: "/app-api/promotion/combination-activity/get-detail", url: "promotion/combination-activity/get-detail",
method: 'GET', method: 'GET',
params: { params: {
id id
} }
}); });
}, },
// 获得最近 n 条拼团记录(团长发起的) // 获得最近 n 条拼团记录(团长发起的)
getHeadCombinationRecordList: (activityId, status, count) => { getHeadCombinationRecordList: (activityId, status, count) => {
return request({ return request2({
url: "/app-api/promotion/combination-record/get-head-list", url: "promotion/combination-record/get-head-list",
method: 'GET', method: 'GET',
params: { params: {
activityId, activityId,
status, status,
count count
} }
}); });
}, },
// 获得拼团记录明细 // 获得拼团记录明细
getCombinationRecordDetail: (id) => { getCombinationRecordDetail: (id) => {
return request({ return request2({
url: "/app-api/promotion/combination-record/get-detail", url: "promotion/combination-record/get-detail",
method: 'GET', method: 'GET',
params: { params: {
id id
} }
}); });
}, },
// 获得拼团记录的概要信息 // 获得拼团记录的概要信息
getCombinationRecordSummary: () => { getCombinationRecordSummary: () => {
return request({ return request2({
url: "/app-api/promotion/combination-record/get-summary", url: "promotion/combination-record/get-summary",
method: 'GET', method: 'GET',
}); });
} }
} }
export default CombinationApi export default CombinationApi

View File

@ -17,17 +17,4 @@ export default {
params: { spuId, productScope, count }, params: { spuId, productScope, count },
}); });
}, },
// 获得匹配指定商品的优惠劵列表
getMatchCouponList: (price, spuIds, skuIds, categoryIds) => {
return request({
url: '/app-api/promotion/coupon/match-list',
method: 'GET',
params: {
price,
spuIds: spuIds.join(','),
skuIds: skuIds.join(','),
categoryIds: categoryIds.join(','),
},
});
}
}; };

View File

@ -1,44 +1,33 @@
import request from "@/sheep/request"; import request2 from "@/sheep/request2";
const SeckillApi = { const SeckillApi = {
// 获得秒杀时间段列表 // 获得秒杀时间段列表
getSeckillConfigList: () => { getSeckillConfigList: () => {
return request({ return request2({ url: 'promotion/seckill-config/list', method: 'GET' });
url: '/app-api/promotion/seckill-config/list', },
method: 'GET'
});
},
// 获得当前秒杀活动 // 获得当前秒杀活动
getNowSeckillActivity: () => { getNowSeckillActivity: () => {
return request({ return request2({ url: 'promotion/seckill-activity/get-now', method: 'GET' });
url: '/app-api/promotion/seckill-activity/get-now', },
method: 'GET'
});
},
// 获得秒杀活动分页 // 获得秒杀活动分页
getSeckillActivityPage: () => { getSeckillActivityPage: () => {
return request({ return request2({ url: 'promotion/seckill-activity/page', method: 'GET' });
url: '/app-api/promotion/seckill-activity/page', },
method: 'GET'
});
},
/** /**
* 获得秒杀活动明细 * 获得秒杀活动明细
* @param {number} id 秒杀活动编号 * @param {number} id 秒杀活动编号
* @return {*} * @return {*}
*/ */
getSeckillActivity: (id) => { getSeckillActivity: (id) => {
return request({ return request2({
url: '/app-api/promotion/seckill-activity/get-detail', url: 'promotion/seckill-activity/get-detail',
method: 'GET', method: 'GET',
params: { params: { id }
id });
} }
});
}
} }
export default SeckillApi; export default SeckillApi;

View File

@ -1,37 +1,46 @@
import request from '@/sheep/request'; import request from '@/sheep/request';
export default { export default {
order: (id) => order: (id) =>
request({ request({
url: 'trade/order/' + id, url: 'trade/order/' + id,
method: 'GET', method: 'GET',
custom: { custom: {
showLoading: false, showLoading: false,
}, },
}), }),
orderLog: (params) => orderLog: (params) =>
request({ request({
url: 'trade/order', url: 'trade/order',
method: 'GET', method: 'GET',
params, params,
custom: { custom: {
showLoading: false, showLoading: false,
}, },
}), }),
rechargeRules: () => rechargeRules: () =>
request({ request({
url: 'trade/order/rechargeRules', url: 'trade/order/rechargeRules',
method: 'GET', method: 'GET',
custom: { custom: {
showError: false, showError: false,
showLoading: false, showLoading: false,
}, },
}), }),
recharge: (data) => rechargeRules2: () =>
request({ request({
url: 'trade/order/recharge', url: '/app-api/pay/wallet-recharge-package/list',
method: 'POST', method: 'GET',
data, custom: {
}), showError: false,
}; showLoading: false,
},
}),
recharge: (data) =>
request({
url: '/app-api/pay/wallet-recharge/create',
method: 'POST',
data,
}),
};

View File

@ -29,6 +29,16 @@ const AfterSaleApi = {
id, id,
}, },
}); });
},
// 获得售后日志列表
getAfterSaleLogList: (afterSaleId) => {
return request2({
url: `/app-api/trade/after-sale-log/list`,
method: 'GET',
params: {
afterSaleId,
},
});
} }
}; };

View File

@ -1,47 +0,0 @@
import request2 from '@/sheep/request2';
const CartApi = {
addCart: (data) => {
return request2({
url: '/app-api/trade/cart/add',
method: 'POST',
data: data,
// TODO 芋艿:这里没提示
custom: {
showSuccess: true,
successMsg: '已添加到购物车~',
}
});
},
updateCartCount: (data) => {
return request2({
url: '/app-api/trade/cart/update-count',
method: 'PUT',
data: data
});
},
updateCartSelected: (data) => {
return request2({
url: '/app-api/trade/cart/update-selected',
method: 'PUT',
data: data
});
},
deleteCart: (ids) => {
return request2({
url: '/app-api/trade/cart/delete',
method: 'DELETE',
params: {
ids
}
});
},
getCartList: () => {
return request2({
url: '/app-api/trade/cart/list',
method: 'GET',
});
},
};
export default CartApi;

View File

@ -1,95 +0,0 @@
import request2 from '@/sheep/request2';
import request from '@/sheep/request';
const OrderApi = {
// 计算订单信息
settlementOrder: (data) => {
const data2 = {
...data,
};
// 移除多余字段
if (!(data.couponId > 0)) {
delete data2.couponId;
}
if (!(data.addressId > 0)) {
delete data2.addressId;
}
// 解决 SpringMVC 接受 List<Item> 参数的问题
delete data2.items;
for (let i = 0; i < data.items.length; i++) {
data2[encodeURIComponent('items[' + i + '' + '].skuId')] = data.items[i].skuId + '';
data2[encodeURIComponent('items[' + i + '' + '].count')] = data.items[i].count + '';
if (data.items[i].cartId) {
data2[encodeURIComponent('items[' + i + '' + '].cartId')] = data.items[i].cartId + '';
}
}
const queryString = Object.keys(data2)
.map((key) => key + '=' + data2[key])
.join('&');
return request2({
url: `trade/order/settlement?${queryString}`,
method: 'GET',
});
},
// 创建订单
createOrder: (data) => {
return request2({
url: `trade/order/create`,
method: 'POST',
data,
});
},
// 获得订单
getOrder: (id) => {
return request2({
url: `trade/order/get-detail`,
method: 'GET',
params: {
id,
},
});
},
// 订单列表
getOrderPage: (params) => {
return request({
url: '/app-api/trade/order/page',
method: 'GET',
params,
custom: {
showLoading: false,
},
});
},
// 确认收货
receiveOrder: (id) => {
return request2({
url: `/app-api/trade/order/receive`,
method: 'PUT',
params: {
id,
},
});
},
// 取消订单
cancelOrder: (id) => {
return request2({
url: `/app-api/trade/order/cancel`,
method: 'DELETE',
params: {
id,
},
});
},
// 删除订单
deleteOrder: (id) => {
return request2({
url: `/app-api/trade/order/delete`,
method: 'DELETE',
params: {
id,
},
});
},
};
export default OrderApi;

View File

@ -1,10 +1,11 @@
import request from '@/sheep/request'; import request from '@/sheep/request';
import request2 from '@/sheep/request2';
import $platform from '@/sheep/platform'; import $platform from '@/sheep/platform';
export default { export default {
getUnused: () => getUnused: () =>
request({ request2({
url: '/app-api/promotion/coupon/get-unused-count', url: 'promotion/coupon/get-unused-count',
method: 'GET', method: 'GET',
custom: { custom: {
showLoading: false, showLoading: false,
@ -12,8 +13,8 @@ export default {
}, },
}), }),
profile: () => profile: () =>
request({ request2({
url: '/app-api/member/user/get', url: 'member/user/get',
method: 'GET', method: 'GET',
custom: { custom: {
showLoading: false, showLoading: false,
@ -21,7 +22,7 @@ export default {
}, },
}), }),
balance: () => balance: () =>
request({ request2({
url: '/app-api/pay/wallet/get', url: '/app-api/pay/wallet/get',
method: 'GET', method: 'GET',
custom: { custom: {
@ -29,9 +30,28 @@ export default {
auth: true, auth: true,
}, },
}), }),
// profile: () =>
// request({
// url: '/user/api/user/profile',
// method: 'GET',
// custom: {
// showLoading: false,
// auth: true,
// },
// }),
// update: (data) =>
// request({
// url: '/user/api/user/update',
// method: 'POST',
// custom: {
// showSuccess: true,
// auth: true,
// },
// data,
// }),
update: (data) => update: (data) =>
request({ request2({
url: '/app-api/member/user/update', url: 'member/user/update',
method: 'PUT', method: 'PUT',
custom: { custom: {
showSuccess: true, showSuccess: true,
@ -176,48 +196,90 @@ export default {
}), }),
address: { address: {
// default: () =>
// request({
// url: 'user/address/default',
// method: 'GET',
// custom: {
// showError: false,
// },
// }),
default: () => default: () =>
request({ request2({
url: '/app-api/member/address/get-default', url: 'member/address/get-default',
method: 'GET', method: 'GET',
custom: { custom: {
showError: false, showError: false,
}, },
}), }),
list: () => list: () =>
request({ request2({
url: '/app-api/member/address/list', url: 'member/address/list',
method: 'GET', method: 'GET',
custom: {}, custom: {},
}), }),
// list: () =>
// request({
// url: 'user/address',
// method: 'GET',
// custom: {},
// }),
create: (data) => create: (data) =>
request({ request2({
url: '/app-api/member/address/create', url: 'member/address/create',
method: 'POST', method: 'POST',
data, data,
custom: { custom: {
showSuccess: true, showSuccess: true,
}, },
}), }),
// create: (data) =>
// request({
// url: 'user/address',
// method: 'POST',
// data,
// custom: {
// showSuccess: true,
// },
// }),
update: (data) => update: (data) =>
request({ request2({
url: '/app-api/member/address/update', url: 'member/address/update',
method: 'PUT', method: 'PUT',
data, data,
custom: { custom: {
showSuccess: true, showSuccess: true,
}, },
}), }),
// update: (id, data) =>
// request({
// url: 'user/address/' + id,
// method: 'PUT',
// data,
// custom: {
// showSuccess: true,
// },
// }),
detail: (id) => detail: (id) =>
request({ request2({
url: '/app-api/member/address/get?id=' + id, url: 'member/address/get?id=' + id,
method: 'GET', method: 'GET',
}), }),
// detail: (id) =>
// request({
// url: 'user/address/' + id,
// method: 'GET',
// }),
delete: (id) => delete: (id) =>
request({ request2({
url: '/app-api/member/address/delete?id=' + id, url: 'member/address/delete?id=' + id,
method: 'DELETE', method: 'DELETE',
}), }),
// delete: (id) =>
// request({
// url: 'user/address/' + id,
// method: 'DELETE',
// }),
}, },
invoice: { invoice: {
list: () => list: () =>
@ -257,29 +319,17 @@ export default {
}, },
favorite: { favorite: {
list: (params) => list: (params) =>
request({ request2({
url: '/app-api/product/favorite/page', url: 'product/favorite/page',
method: 'GET', method: 'GET',
params, params,
}), }),
do: (id) => do: (id) =>
request({ request({
url: '/app-api/product/favorite/create', url: 'user/goodsLog/favorite',
method: 'POST', method: 'POST',
data: { data: {
spuId: id, goods_id: id,
},
custom: {
showSuccess: true,
auth: true,
},
}),
dos: (id) =>
request({
url: '/app-api/product/favorite/delete',
method: 'DELETE',
data: {
spuId: id,
}, },
custom: { custom: {
showSuccess: true, showSuccess: true,
@ -288,8 +338,8 @@ export default {
}), }),
// 取消收藏 // 取消收藏
cancel: (id) => cancel: (id) =>
request({ request2({
url: '/app-api/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),
@ -300,6 +350,18 @@ export default {
auth: true, auth: true,
}, },
}), }),
// cancel: (id) =>
// request({
// url: 'user/goodsLog/favorite',
// method: 'POST',
// data: {
// goods_ids: id,
// },
// custom: {
// showSuccess: true,
// auth: true,
// },
// }),
}, },
view: { view: {
list: (params) => list: (params) =>
@ -321,21 +383,28 @@ export default {
}, },
wallet: { wallet: {
log: (params) => log: (params) =>
request({ request2({
// url: 'member/point/record/page', // url: 'member/point/record/page',
url: '/app-api/pay/wallet-transaction/page', url: 'pay/wallet-transaction/page',
method: 'GET', method: 'GET',
params, params,
custom: {}, custom: {},
}), }),
log2: (params) => log2: (params) =>
request({ request2({
url: '/app-api/member/point/record/page', 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) =>
// request({
// url: '/user/api/walletLog',
// method: 'GET',
// params,
// custom: {},
// }),
}, },
account: { account: {
info: (params) => info: (params) =>
@ -360,9 +429,18 @@ export default {
}), }),
}, },
//数量接口 //数量接口
// data: () =>
// request({
// url: 'user/user/data',
// method: 'GET',
// custom: {
// showLoading: false,
// auth: true,
// },
// }),
data: () => data: () =>
request({ request2({
url: '/app-api/trade/order/get-count', url: 'trade/order/get-count',
method: 'GET', method: 'GET',
custom: { custom: {
showLoading: false, showLoading: false,
@ -370,8 +448,8 @@ export default {
}, },
}), }),
data2: () => data2: () =>
request({ request2({
url: '/app-api/trade/after-sale/get-applying-count', url: 'trade/after-sale/get-applying-count',
method: 'GET', method: 'GET',
custom: { custom: {
showLoading: false, showLoading: false,

View File

@ -1,104 +1,108 @@
<template> <template>
<su-popup :show="show" type="bottom" round="20" @close="emits('close')" showClose backgroundColor="#f2f2f2"> <su-popup
<view class="model-box"> :show="show"
<view class="title ss-m-t-16 ss-m-l-20 ss-flex">优惠券</view> type="bottom"
<scroll-view class="model-content" scroll-y :scroll-with-animation="false" :enable-back-to-top="true"> round="20"
<view class="subtitle ss-m-l-20">可使用优惠券</view> @close="emits('close')"
<view v-for="item in state.couponInfo" :key="item.id"> showClose
<s-coupon-list :data="item"> backgroundColor="#f2f2f2"
<template #default> >
<button class="ss-reset-button card-btn ss-flex ss-row-center ss-col-center" :class=" <view class="model-box">
<view class="title ss-m-t-16 ss-m-l-20 ss-flex">优惠券</view>
<scroll-view
class="model-content"
scroll-y
:scroll-with-animation="false"
:enable-back-to-top="true"
>
<view class="subtitle ss-m-l-20">可使用优惠券</view>
<view v-for="item in state.couponInfo" :key="item.id">
<s-coupon-list :data="item">
<template #default>
<button
class="ss-reset-button card-btn ss-flex ss-row-center ss-col-center"
:class="
item.get_status != 'can_get' && item.get_status != 'can_use' ? 'boder-btn' : '' item.get_status != 'can_get' && item.get_status != 'can_use' ? 'boder-btn' : ''
" @click.stop="getBuy(item.id)"> "
<!-- 此处对接领取优惠券先将限制解除 --> @click.stop="getBuy(item.id)"
<!-- :disabled="item.get_status != 'can_get' && item.get_status != 'can_use'" --> :disabled="item.get_status != 'can_get' && item.get_status != 'can_use'"
{{ item.get_status_text }} >
</button> {{ item.get_status_text }}
</template> </button>
</s-coupon-list> </template>
</view> </s-coupon-list>
</scroll-view> </view>
</view> </scroll-view>
</su-popup> </view>
</su-popup>
</template> </template>
<script setup> <script setup>
import { import { computed, reactive } from 'vue';
computed, const props = defineProps({
reactive modelValue: {
} from 'vue'; type: Object,
const props = defineProps({ default() {},
modelValue: { },
type: Object, show: {
default () {}, type: Boolean,
}, default: false,
show: { },
type: Boolean, });
default: false, const emits = defineEmits(['get', 'close']);
}, const state = reactive({
}); couponInfo: computed(() => props.modelValue),
const emits = defineEmits(['get', 'close']); currentValue: -1,
const state = reactive({ couponId: '',
couponInfo: computed(() => props.modelValue), });
currentValue: -1, const getBuy = (id) => {
couponId: '', emits('get', id);
}); };
const getBuy = (id) => { //
console.log('应该是详情页领取优惠券')
emits('get', id);
};
//
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.model-box { .model-box {
height: 60vh; height: 60vh;
.title {
.title { font-size: 36rpx;
font-size: 36rpx; height: 80rpx;
height: 80rpx; font-weight: bold;
font-weight: bold; color: #333333;
color: #333333; }
} .subtitle {
font-size: 26rpx;
.subtitle { font-weight: 500;
font-size: 26rpx; color: #333333;
font-weight: 500; }
color: #333333; }
} .model-content {
} height: 54vh;
}
.model-content { .modal-footer {
height: 54vh; width: 100%;
} height: 120rpx;
background: #fff;
.modal-footer { }
width: 100%; .confirm-btn {
height: 120rpx; width: 710rpx;
background: #fff; margin-left: 20rpx;
} height: 80rpx;
background: linear-gradient(90deg, var(--ui-BG-Main), var(--ui-BG-Main-gradient));
.confirm-btn { border-radius: 40rpx;
width: 710rpx; color: #fff;
margin-left: 20rpx; }
height: 80rpx; //
background: linear-gradient(90deg, var(--ui-BG-Main), var(--ui-BG-Main-gradient)); .card-btn {
border-radius: 40rpx; // width: 144rpx;
color: #fff; padding: 0 16rpx;
} height: 50rpx;
border-radius: 40rpx;
// background: linear-gradient(90deg, var(--ui-BG-Main), var(--ui-BG-Main-gradient));
.card-btn { color: #ffffff;
// width: 144rpx; font-size: 24rpx;
padding: 0 16rpx; font-weight: 400;
height: 50rpx; }
border-radius: 40rpx; .boder-btn {
background: linear-gradient(90deg, var(--ui-BG-Main), var(--ui-BG-Main-gradient)); background: linear-gradient(90deg, var(--ui-BG-Main-opacity-4), var(--ui-BG-Main-light));
color: #ffffff; color: #fff !important;
font-size: 24rpx; }
font-weight: 400; </style>
}
.boder-btn {
background: linear-gradient(90deg, var(--ui-BG-Main-opacity-4), var(--ui-BG-Main-light));
color: #fff !important;
}
</style>

View File

@ -1,9 +1,13 @@
<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 class="tag ss-flex ss-row-center" :class=" <!-- <view
class="tag ss-flex ss-row-center"
: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 class="value-text ss-flex-1 ss-m-r-10" :class=" <view class="value-text ss-flex-1 ss-m-r-10" :class="

View File

@ -1,4 +1,3 @@
<!-- 订单确认的优惠劵选择弹窗 -->
<template> <template>
<su-popup <su-popup
:show="show" :show="show"
@ -17,21 +16,20 @@
:enable-back-to-top="true" :enable-back-to-top="true"
> >
<view class="subtitle ss-m-l-20">可使用优惠券</view> <view class="subtitle ss-m-l-20">可使用优惠券</view>
<view v-for="(item, index) in state.couponInfo" :key="index"> <view v-for="(item, index) in state.couponInfo.can_use" :key="index">
<s-coupon-list :data="item" type="user" :disabled="false"> <s-coupon-list :data="item" type="user" :disabled="false">
<template #default> <template #default>
<label class="ss-flex ss-col-center" @tap="radioChange(item.id)"> <label class="ss-flex ss-col-center" @tap="radioChange(item.id)">
<radio <radio
color="var(--ui-BG-Main)" color="var(--ui-BG-Main)"
style="transform: scale(0.8)" style="transform: scale(0.8)"
:checked="state.couponId === item.id" :checked="state.couponId == item.id"
@tap.stop="radioChange(item.id)" @tap.stop="radioChange(item.id)"
/> />
</label> </label>
</template> </template>
</s-coupon-list> </s-coupon-list>
</view> </view>
<!-- TODO 芋艿未来接口需要支持下
<view class="subtitle ss-m-t-40 ss-m-l-20">不可使用优惠券</view> <view class="subtitle ss-m-t-40 ss-m-l-20">不可使用优惠券</view>
<view v-for="item in state.couponInfo.cannot_use" :key="item.id"> <view v-for="item in state.couponInfo.cannot_use" :key="item.id">
<s-coupon-list :data="item" type="user" :disabled="true"> <s-coupon-list :data="item" type="user" :disabled="true">
@ -43,7 +41,6 @@
</template> </template>
</s-coupon-list> </s-coupon-list>
</view> </view>
-->
</scroll-view> </scroll-view>
</view> </view>
<view class="modal-footer ss-flex"> <view class="modal-footer ss-flex">
@ -53,9 +50,8 @@
</template> </template>
<script setup> <script setup>
import { computed, reactive } from 'vue'; import { computed, reactive } from 'vue';
const props = defineProps({ const props = defineProps({
modelValue: { // modelValue: {
type: Object, type: Object,
default() {}, default() {},
}, },
@ -64,27 +60,21 @@
default: false, default: false,
}, },
}); });
const emits = defineEmits(['confirm', 'close']); const emits = defineEmits(['confirm', 'close']);
const state = reactive({ const state = reactive({
couponInfo: computed(() => props.modelValue), // couponInfo: computed(() => props.modelValue),
couponId: 0, // couponId: 0,
}); });
//
function radioChange(couponId) { function radioChange(couponId) {
if (state.couponId === couponId) { if (state.couponId == couponId) {
state.couponId = 0; state.couponId = 0;
} else { } else {
state.couponId = couponId; state.couponId = couponId;
} }
} }
//
const onConfirm = () => { const onConfirm = () => {
emits('confirm', state.couponId); emits('confirm', state.couponId);
} };
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
:deep() { :deep() {

View File

@ -54,7 +54,7 @@
<script setup> <script setup>
import sheep from '@/sheep'; import sheep from '@/sheep';
import { computed } from 'vue'; import { computed } from 'vue';
import { fen2yuan } from '../../hooks/useGoods'; import { fen2yuan } from '@/sheep/hooks/useGoods';
/** /**
* 订单卡片 * 订单卡片
* *

View File

@ -1,19 +1,16 @@
<template> <template>
<!-- 分享弹框 --> <!-- 分享弹框 -->
<view> <view>
<su-popup :show="state.showShareGuide" :showClose="false" @close="onCloseGuide"></su-popup> <su-popup :show="state.showShareGuide" :showClose="false" @close="onCloseGuide"></su-popup>
<view v-if="state.showShareGuide" class="guide-wrap"> <view v-if="state.showShareGuide" class="guide-wrap">
<image <image class="guide-image" :src="sheep.$url.static('/static/img/shop/share/share_guide.png')"></image>
class="guide-image" </view>
:src="sheep.$url.static('/static/img/shop/share/share_guide.png')"
></image>
</view>
<su-popup :show="show" round="10" :showClose="false" @close="closeShareModal"> <su-popup :show="show" round="10" :showClose="false" @close="closeShareModal">
<!-- 分享tools --> <!-- 分享tools -->
<view class="share-box"> <view class="share-box">
<view class="share-list-box ss-flex"> <view class="share-list-box ss-flex">
<button <!-- <button
v-if="shareConfig.methods.includes('forward')" v-if="shareConfig.methods.includes('forward')"
class="share-item share-btn ss-flex-col ss-col-center" class="share-item share-btn ss-flex-col ss-col-center"
open-type="share" open-type="share"
@ -25,20 +22,14 @@
mode="" mode=""
></image> ></image>
<text class="share-title">微信好友</text> <text class="share-title">微信好友</text>
</button> </button> -->
<button <button v-if="shareConfig.methods.includes('poster')"
v-if="shareConfig.methods.includes('poster')" class="share-item share-btn ss-flex-col ss-col-center" @tap="onShareByPoster">
class="share-item share-btn ss-flex-col ss-col-center" <image class="share-img" :src="sheep.$url.static('/static/img/shop/share/share_poster.png')"
@tap="onShareByPoster" mode=""></image>
> <text class="share-title">生成海报</text>
<image </button>
class="share-img" <!--
:src="sheep.$url.static('/static/img/shop/share/share_poster.png')"
mode=""
></image>
<text class="share-title">生成海报</text>
</button>
<button <button
v-if="shareConfig.methods.includes('link')" v-if="shareConfig.methods.includes('link')"
class="share-item share-btn ss-flex-col ss-col-center" class="share-item share-btn ss-flex-col ss-col-center"
@ -50,152 +41,157 @@
mode="" mode=""
></image> ></image>
<text class="share-title">复制链接</text> <text class="share-title">复制链接</text>
</button> </button> -->
</view> </view>
<view class="share-foot ss-flex ss-row-center ss-col-center" @tap="closeShareModal"> <view class="share-foot ss-flex ss-row-center ss-col-center" @tap="closeShareModal">
取消 取消
</view> </view>
</view> </view>
</su-popup> </su-popup>
<!-- 分享海报 --> <!-- 分享海报 -->
<canvas-poster <canvas-poster ref="SharePosterRef" :show="state.showPosterModal" :shareInfo="shareInfo"
ref="SharePosterRef" @close="state.showPosterModal = false" />
:show="state.showPosterModal" </view>
:shareInfo="shareInfo"
@close="state.showPosterModal = false"
/>
</view>
</template> </template>
<script setup> <script setup>
/** /**
* 分享弹窗 * 分享弹窗
*/ */
import { ref, unref, reactive, computed } from 'vue'; import {
import sheep from '@/sheep'; ref,
import canvasPoster from './canvas-poster/index.vue'; unref,
import { showShareModal, closeShareModal, showAuthModal } from '@/sheep/hooks/useModal'; reactive,
computed
} from 'vue';
import sheep from '@/sheep';
import canvasPoster from './canvas-poster/index.vue';
import {
showShareModal,
closeShareModal,
showAuthModal
} from '@/sheep/hooks/useModal';
const show = computed(() => sheep.$store('modal').share); const show = computed(() => sheep.$store('modal').share);
const shareConfig = computed(() => sheep.$store('app').platform.share); const shareConfig = computed(() => sheep.$store('app').platform.share);
const SharePosterRef = ref(''); const SharePosterRef = ref('');
const props = defineProps({ const props = defineProps({
shareInfo: { shareInfo: {
type: Object, type: Object,
default() {}, default () {},
}, },
}); });
const state = reactive({ const state = reactive({
showShareGuide: false, //H5 showShareGuide: false, //H5
showPosterModal: false, // showPosterModal: false, //
}); });
// //
const onShareByPoster = () => { const onShareByPoster = () => {
closeShareModal(); closeShareModal();
if (!sheep.$store('user').isLogin) { if (!sheep.$store('user').isLogin) {
showAuthModal(); showAuthModal();
return; return;
} }
unref(SharePosterRef).getPoster(); unref(SharePosterRef).getPoster();
state.showPosterModal = true; state.showPosterModal = true;
}; };
// //
const onShareByForward = () => { const onShareByForward = () => {
closeShareModal(); closeShareModal();
// #ifdef H5 // #ifdef H5
if (['WechatOfficialAccount', 'H5'].includes(sheep.$platform.name)) { if (['WechatOfficialAccount', 'H5'].includes(sheep.$platform.name)) {
state.showShareGuide = true; state.showShareGuide = true;
return; return;
} }
// #endif // #endif
// #ifdef APP-PLUS // #ifdef APP-PLUS
uni.share({ uni.share({
provider: 'weixin', provider: 'weixin',
scene: 'WXSceneSession', scene: 'WXSceneSession',
type: 0, type: 0,
href: props.shareInfo.link, href: props.shareInfo.link,
title: props.shareInfo.title, title: props.shareInfo.title,
summary: props.shareInfo.desc, summary: props.shareInfo.desc,
imageUrl: props.shareInfo.image, imageUrl: props.shareInfo.image,
success: (res) => { success: (res) => {
console.log('success:' + JSON.stringify(res)); console.log('success:' + JSON.stringify(res));
}, },
fail: (err) => { fail: (err) => {
console.log('fail:' + JSON.stringify(err)); console.log('fail:' + JSON.stringify(err));
}, },
}); });
// #endif // #endif
}; };
// //
const onShareByCopyLink = () => { const onShareByCopyLink = () => {
sheep.$helper.copyText(props.shareInfo.link); sheep.$helper.copyText(props.shareInfo.link);
closeShareModal(); closeShareModal();
}; };
function onCloseGuide() { function onCloseGuide() {
state.showShareGuide = false; state.showShareGuide = false;
} }
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.guide-image { .guide-image {
right: 30rpx; right: 30rpx;
top: 0; top: 0;
position: fixed; position: fixed;
width: 580rpx; width: 580rpx;
height: 430rpx; height: 430rpx;
z-index: 10080; z-index: 10080;
} }
// tool // tool
.share-box { .share-box {
background: $white; background: $white;
width: 750rpx; width: 750rpx;
border-radius: 30rpx 30rpx 0 0; border-radius: 30rpx 30rpx 0 0;
padding-top: 30rpx; padding-top: 30rpx;
.share-foot { .share-foot {
font-size: 24rpx; font-size: 24rpx;
color: $gray-b; color: $gray-b;
height: 80rpx; height: 80rpx;
border-top: 1rpx solid $gray-e; border-top: 1rpx solid $gray-e;
} }
.share-list-box { .share-list-box {
.share-btn { .share-btn {
background: none; background: none;
border: none; border: none;
line-height: 1; line-height: 1;
padding: 0; padding: 0;
&::after { &::after {
border: none; border: none;
} }
} }
.share-item { .share-item {
flex: 1; flex: 1;
padding-bottom: 20rpx; padding-bottom: 20rpx;
.share-img { .share-img {
width: 70rpx; width: 70rpx;
height: 70rpx; height: 70rpx;
background: $gray-f; background: $gray-f;
border-radius: 50%; border-radius: 50%;
margin-bottom: 20rpx; margin-bottom: 20rpx;
} }
.share-title { .share-title {
font-size: 24rpx; font-size: 24rpx;
color: $dark-6; color: $dark-6;
} }
} }
} }
} }
</style> </style>

View File

@ -3,20 +3,19 @@ import sheep from '@/sheep';
import $wxsdk from '@/sheep/libs/sdk-h5-weixin'; import $wxsdk from '@/sheep/libs/sdk-h5-weixin';
// #endif // #endif
import { getRootUrl } from '@/sheep/helper'; import { getRootUrl } from '@/sheep/helper';
import PayOrderApi from '@/sheep/api/pay/order';
/** /**
* 支付 * 支付
* *
* @param {String} payment = ['wechat','alipay','wallet','offline'] - 支付方式 * @param {String} payment = ['wechat','alipay','wallet','offline'] - 支付方式
* @param {String} orderType = ['goods','recharge','groupon'] - 订单类型 * @param {String} orderType = ['goods','recharge','groupon'] - 订单类型
* @param {String} id - 订单号 * @param {String} orderSN - 订单号
*/ */
export default class SheepPay { export default class SheepPay {
constructor(payment, orderType, id) { constructor(payment, orderType, orderSN) {
this.payment = payment; this.payment = payment;
this.id = id; this.orderSN = orderSN;
this.orderType = orderType; this.orderType = orderType;
this.payAction(); this.payAction();
} }
@ -30,8 +29,8 @@ export default class SheepPay {
alipay: () => { alipay: () => {
this.redirectPay(); // 现在公众号可以直接跳转支付宝页面 this.redirectPay(); // 现在公众号可以直接跳转支付宝页面
}, },
wallet: () => { money: () => {
this.walletPay(); this.moneyPay();
}, },
offline: () => { offline: () => {
this.offlinePay(); this.offlinePay();
@ -44,8 +43,8 @@ export default class SheepPay {
alipay: () => { alipay: () => {
this.copyPayLink(); this.copyPayLink();
}, },
wallet: () => { money: () => {
this.walletPay(); this.moneyPay();
}, },
offline: () => { offline: () => {
this.offlinePay(); this.offlinePay();
@ -58,8 +57,8 @@ export default class SheepPay {
alipay: () => { alipay: () => {
this.alipay(); this.alipay();
}, },
wallet: () => { money: () => {
this.walletPay(); this.moneyPay();
}, },
offline: () => { offline: () => {
this.offlinePay(); this.offlinePay();
@ -72,8 +71,8 @@ export default class SheepPay {
alipay: () => { alipay: () => {
this.redirectPay(); this.redirectPay();
}, },
wallet: () => { money: () => {
this.walletPay(); this.moneyPay();
}, },
offline: () => { offline: () => {
this.offlinePay(); this.offlinePay();
@ -84,21 +83,18 @@ export default class SheepPay {
} }
// 预支付 // 预支付
prepay(channel) { prepay() {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
let data = { let data = {
id: this.id, order_sn: this.orderSN,
channelCode: channel, payment: this.payment,
channelExtras: {}
}; };
if (uni.getStorageSync('openid')) { if (uni.getStorageSync('openid')) {
data.openid = uni.getStorageSync('openid'); data.openid = uni.getStorageSync('openid');
} }
PayOrderApi.submitOrder(data).then((res) => { sheep.$api.pay.prepay(data).then((res) => {
// 成功时 res.error === 0 && resolve(res);
res.code === 0 && resolve(res); if (res.error === -1 && res.msg === 'miss_openid') {
// 失败时
if (res.code !== 0 && res.msg === 'miss_openid') {
uni.showModal({ uni.showModal({
title: '微信支付', title: '微信支付',
content: '请先绑定微信再使用微信支付', content: '请先绑定微信再使用微信支付',
@ -113,7 +109,7 @@ export default class SheepPay {
}); });
} }
// #ifdef H5 // #ifdef H5
// 微信公众号JSSDK支付 TODO 芋艿:待接入 // 微信公众号JSSDK支付
async wechatOfficialAccountPay() { async wechatOfficialAccountPay() {
let that = this; let that = this;
let { error, data, msg } = await this.prepay(); let { error, data, msg } = await this.prepay();
@ -134,21 +130,21 @@ export default class SheepPay {
}); });
} }
//浏览器微信H5支付 TODO 芋艿:待接入 //浏览器微信H5支付
async wechatWapPay() { async wechatWapPay() {
const { error, data } = await this.prepay(); const { error, data } = await this.prepay();
if (error === 0) { if (error === 0) {
const redirect_url = `${getRootUrl()}pages/pay/result?id=${this.id}&payment=${this.payment const redirect_url = `${getRootUrl()}pages/pay/result?orderSN=${this.orderSN}&payment=${this.payment
}&orderType=${this.orderType}`; }&orderType=${this.orderType}`;
location.href = `${data.pay_data.h5_url}&redirect_url=${encodeURIComponent(redirect_url)}`; location.href = `${data.pay_data.h5_url}&redirect_url=${encodeURIComponent(redirect_url)}`;
} }
} }
// 支付链接 TODO 芋艿:待接入 // 支付链接
async redirectPay() { async redirectPay() {
let { error, data } = await this.prepay(); let { error, data } = await this.prepay();
if (error === 0) { if (error === 0) {
const redirect_url = `${getRootUrl()}pages/pay/result?id=${this.id}&payment=${this.payment const redirect_url = `${getRootUrl()}pages/pay/result?orderSN=${this.orderSN}&payment=${this.payment
}&orderType=${this.orderType}`; }&orderType=${this.orderType}`;
location.href = data.pay_data + encodeURIComponent(redirect_url); location.href = data.pay_data + encodeURIComponent(redirect_url);
} }
@ -156,7 +152,7 @@ export default class SheepPay {
// #endif // #endif
// 微信小程序支付 TODO 芋艿:待接入 // 微信小程序支付
async wechatMiniProgramPay() { async wechatMiniProgramPay() {
let that = this; let that = this;
let result = await this.prepay(); let result = await this.prepay();
@ -177,18 +173,18 @@ export default class SheepPay {
} }
// 余额支付 // 余额支付
async walletPay() { async moneyPay() {
const { code } = await this.prepay('wallet'); const { error } = await this.prepay();
code === 0 && this.payResult('success'); error === 0 && this.payResult('success');
} }
// 货到付款 TODO 芋艿:待接入 // 货到付款
async offlinePay() { async offlinePay() {
const { error } = await this.prepay(); const { error } = await this.prepay();
error === 0 && this.payResult('success'); error === 0 && this.payResult('success');
} }
// 支付宝复制链接支付 TODO 芋艿:待接入 // 支付宝复制链接支付
async copyPayLink() { async copyPayLink() {
let that = this; let that = this;
let { error, data } = await this.prepay(); let { error, data } = await this.prepay();
@ -207,7 +203,7 @@ export default class SheepPay {
} }
} }
// 支付宝支付 TODO 芋艿:待接入 // 支付宝支付
async alipay() { async alipay() {
let that = this; let that = this;
const { error, data } = await this.prepay(); const { error, data } = await this.prepay();
@ -229,7 +225,7 @@ export default class SheepPay {
} }
} }
// 微信支付 TODO 芋艿:待接入 // 微信支付
async wechatAppPay() { async wechatAppPay() {
let that = this; let that = this;
let { error, data } = await this.prepay(); let { error, data } = await this.prepay();
@ -250,72 +246,10 @@ export default class SheepPay {
// 支付结果跳转,success:成功fail:失败 // 支付结果跳转,success:成功fail:失败
payResult(resultType) { payResult(resultType) {
sheep.$router.redirect('/pages/pay/result', { sheep.$router.redirect('/pages/pay/result', {
id: this.id, orderSN: this.orderSN,
payment: this.payment, //重新支付的时候使用
payState: resultType,
orderType: this.orderType, orderType: this.orderType,
payState: resultType
}); });
} }
} }
export function getPayMethods(channels) {
const payMethods = [
{
icon: '/static/img/shop/pay/wechat.png',
title: '微信支付',
value: 'wechat',
disabled: true,
},
{
icon: '/static/img/shop/pay/alipay.png',
title: '支付宝支付',
value: 'alipay',
disabled: true,
},
{
icon: '/static/img/shop/pay/wallet.png',
title: '余额支付',
value: 'wallet',
disabled: true,
},
{
icon: '/static/img/shop/pay/apple.png',
title: 'Apple Pay',
value: 'apple',
disabled: true,
},
{
icon: '/static/img/shop/pay/wallet.png',
title: '模拟支付',
value: 'mock',
disabled: true,
}
];
const platform = sheep.$platform.name
// 1. 处理【微信支付】
const wechatMethod = payMethods[0];
if ((platform === 'WechatOfficialAccount' && channels.includes('wx_pub'))
|| platform === 'WechatMiniProgram' && channels.includes('wx_lite')
|| platform === 'App' && channels.includes('wx_app')) {
wechatMethod.disabled = false;
}
// 2. 处理【支付宝支付】
const alipayMethod = payMethods[1];
if ((platform === 'WechatOfficialAccount' && channels.includes('alipay_wap'))
|| platform === 'WechatMiniProgram' && channels.includes('alipay_wap')
|| platform === 'App' && channels.includes('alipay_app')) {
alipayMethod.disabled = false;
}
// 3. 处理【余额支付】
const walletMethod = payMethods[2];
if (channels.includes('wallet')) {
walletMethod.disabled = false;
}
// 4. 处理【苹果支付】TODO 芋艿:未来接入
// 5. 处理【模拟支付】
const mockMethod = payMethods[4];
if (channels.includes('mock')) {
mockMethod.disabled = false;
}
return payMethods;
}

View File

@ -55,8 +55,7 @@ const http = new Request({
method: 'GET', method: 'GET',
header: { header: {
Accept: 'text/json', Accept: 'text/json',
'Content-Type': 'application/json', 'Content-Type': 'application/json;charset=UTF-8',
// ;charset=UTF-8
platform: $platform.name, platform: $platform.name,
}, },
// #ifdef APP-PLUS // #ifdef APP-PLUS
@ -99,7 +98,6 @@ http.interceptors.request.use(
config.header['terminal'] = '20'; config.header['terminal'] = '20';
config.header['Authorization'] = 'Bearer test247'; config.header['Authorization'] = 'Bearer test247';
} }
// console.log(config, '看参数')
return config; return config;
}, },
(error) => { (error) => {

View File

@ -23,8 +23,8 @@ const app = defineStore({
copytime: '', // 版权信息 II copytime: '', // 版权信息 II
}, },
platform: { platform: {
payment: [], // 支持的支付方式 TODO 芋艿:可删除 payment: [], // 支持的支付方式
recharge_payment: [], // 支持的充值支付方式 TODO 芋艿:可删除 recharge_payment: [], // 支持的充值支付方式
share: { share: {
methods: [], // 支持的分享方式 methods: [], // 支持的分享方式
forwardInfo: {}, // 默认转发信息 forwardInfo: {}, // 默认转发信息

View File

@ -1,93 +1,98 @@
import { defineStore } from 'pinia'; import { defineStore } from 'pinia';
import CartApi from '@/sheep/api/trade/cart'; import cartApi from '@/sheep/api/cart';
const cart = defineStore({ const cart = defineStore({
id: 'cart', id: 'cart',
state: () => ({ state: () => ({
list: [], // 购物车列表 list: [], // 购物车列表
selectedIds: [], // 已选列表 selectedIds: [], // 已选列表
isAllSelected: false, // 是否全选 isAllSelected: false, //是否全选
totalPriceSelected: 0, // 选中项总金额 cartSelectedTotalPrice: '0.00', // 选中项总金额
}), }),
getters: {
totalPriceSelected: (state) => {
let price = 0;
if (!state.selectedIds.length) return price.toFixed(2);
state.list.forEach((item) => {
price += state.selectedIds.includes(item.id)
? Number(item.sku.price/100) * item.count
: 0;
});
return price.toFixed(2);
},
},
actions: { actions: {
// 获取购物车列表 // 获取购物车列表
async getList() { async getList() {
const { data, code } = await CartApi.getCartList(); const { data, code } = await cartApi.list();
if (code === 0) { if (code === 0) {
this.list = data.validList; this.list = data.validList;
// 计算各种关联属性
this.selectedIds = [];
this.isAllSelected = true;
this.totalPriceSelected = 0;
this.list.forEach((item) => {
if (item.selected) {
this.selectedIds.push(item.id);
this.totalPriceSelected += item.count * item.sku.price;
} else {
this.isAllSelected = false;
}
});
} }
}, },
// 添加购物车 // 添加购物车
async add(goodsInfo) { async add(goodsInfo) {
// 添加购物项 const { error } = await cartApi.append({
const { code } = await CartApi.addCart({ goods_id: goodsInfo.goods_id,
skuId: goodsInfo.id, goods_num: goodsInfo.goods_num,
count: goodsInfo.goods_num, goods_sku_price_id: goodsInfo.id,
}); });
// 刷新购物车列表 if (error === 0) {
if (code === 0) { this.getList();
await this.getList();
} }
}, },
// 更新购物车 // 更新购物车
async update(goodsInfo) { async update(goodsInfo) {
const { code } = await CartApi.updateCartCount({ const { error } = await cartApi.update({
id: goodsInfo.goods_id, id: goodsInfo.goods_id,
count: goodsInfo.goods_num, count: goodsInfo.goods_num,
goods_sku_price_id: goodsInfo.goods_sku_price_id,
}); });
if (code === 0) { if (error === 0) {
await this.getList(); // this.getList();
} }
}, },
// 移除购物车 // 移除购物车
async delete(ids) { async delete(ids) {
const { code } = await CartApi.deleteCart(ids.join(',')); if (typeof ids === 'array') {
ids = ids.join(',');
}
const { code } = await cartApi.delete(ids);
if (code === 0) { if (code === 0) {
await this.getList(); this.selectAll(false);
this.getList();
} }
}, },
// 单选购物车商品 // 选择购物车商品
async selectSingle(goodsId) { selectSingle(goodsId) {
const { code } = await CartApi.updateCartSelected({ if (!this.selectedIds.includes(goodsId)) {
ids: [goodsId], this.selectedIds.push(goodsId);
selected: !this.selectedIds.includes(goodsId), // 取反 } else {
}); this.selectedIds.splice(this.selectedIds.indexOf(goodsId), 1);
if (code === 0) {
await this.getList();
} }
this.isAllSelected = this.selectedIds.length === this.list.length;
}, },
// 全选购物车商品 // 全选
async selectAll(flag) { selectAll(flag) {
const { code } = await CartApi.updateCartSelected({ this.isAllSelected = flag;
ids: this.list.map((item) => item.id), if (!flag) {
selected: flag this.selectedIds = [];
}); } else {
if (code === 0) { this.list.forEach((item) => {
await this.getList(); this.selectedIds.push(item.id);
});
} }
}, },
// 清空购物车 // 清空购物车
async emptyList() { emptyList() {
await this.delete(this.list.map((item) => item.id)); this.list = [];
this.selectedIds = [];
this.isAllSelected = false;
this.cartSelectedTotalPrice = '0.00';
}, },
}, },
persist: { persist: {
@ -100,4 +105,4 @@ const cart = defineStore({
}, },
}); });
export default cart; export default cart;

View File

@ -99,4 +99,17 @@ export function handleTree(data, id = 'id', parentId = 'parentId', children = 'c
return father[parentId] === rootId; return father[parentId] === rootId;
}); });
return treeData !== '' ? treeData : data; return treeData !== '' ? treeData : data;
}
/**
* 重置分页对象
*
* TODO 芋艿需要处理其它页面
*
* @param pagination 分页对象
*/
export function resetPagination(pagination) {
pagination.list = [];
pagination.total = 0;
pagination.pageNo = 1;
} }

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,4 @@
import { import { loadEnv } from 'vite';
loadEnv
} from 'vite';
import uni from '@dcloudio/vite-plugin-uni'; import uni from '@dcloudio/vite-plugin-uni';
import path from 'path'; import path from 'path';
// import viteCompression from 'vite-plugin-compression'; // import viteCompression from 'vite-plugin-compression';
@ -33,4 +31,4 @@ export default (command, mode) => {
}, },
}, },
}; };
}; };