This commit is contained in:
77 2024-09-27 18:36:26 +08:00
parent eddf5b2aba
commit 613122558a
16 changed files with 1836 additions and 986 deletions

View File

@ -177,6 +177,17 @@
"group": "商品" "group": "商品"
} }
}, },
{
"path": "sales",
"style": {
"navigationBarTitleText": "促销商品"
},
"meta": {
"sync": true,
"title": "促销商品",
"group": "商品"
}
},
{ {
"path": "list", "path": "list",
"style": { "style": {

View File

@ -1,516 +1,531 @@
<!-- 拼团订单的详情 --> <!-- 拼团订单的详情 -->
<template> <template>
<s-layout <s-layout title="拼团详情" class="detail-wrap" :navbar="state.data && !state.loading ? 'inner' : 'normal'">
title="拼团详情" <!-- :onShareAppMessage="shareInfo" -->
class="detail-wrap" <view v-if="state.loading"></view>
:navbar="state.data && !state.loading ? 'inner' : 'normal'" <view v-if="state.data && !state.loading">
:onShareAppMessage="shareInfo" <!-- 团长信息 + 活动信息 -->
> <view class="recharge-box" v-if="state.data.headRecord" :style="[
<view v-if="state.loading"></view>
<view v-if="state.data && !state.loading">
<!-- 团长信息 + 活动信息 -->
<view
class="recharge-box"
v-if="state.data.headRecord"
:style="[
{ {
marginTop: '-' + Number(statusBarHeight + 88) + 'rpx', marginTop: '-' + Number(statusBarHeight + 88) + 'rpx',
paddingTop: Number(statusBarHeight + 108) + 'rpx', paddingTop: Number(statusBarHeight + 108) + 'rpx',
}, },
]" ]">
> <s-goods-item class="goods-box" :img="state.data.headRecord.picUrl"
<s-goods-item :title="state.data.headRecord.spuName" :price="state.data.headRecord.combinationPrice"
class="goods-box" priceColor="#E1212B" @tap="
:img="state.data.headRecord.picUrl"
:title="state.data.headRecord.spuName"
:price="state.data.headRecord.combinationPrice"
priceColor="#E1212B"
@tap="
sheep.$router.go('/pages/goods/groupon', { sheep.$router.go('/pages/goods/groupon', {
id: state.data.headRecord.activityId, id: state.data.headRecord.activityId,
}) })
" " :style="[{ top: Number(statusBarHeight + 108) + 'rpx' }]">
:style="[{ top: Number(statusBarHeight + 108) + 'rpx' }]" <template #groupon>
> <view class="ss-flex">
<template #groupon> <view class="sales-title">{{ state.data.headRecord.userSize }}人团</view>
<view class="ss-flex"> <view class="num-title ss-m-l-20">已拼{{ state.data.headRecord.userCount }}</view>
<view class="sales-title">{{ state.data.headRecord.userSize }}人团</view> </view>
<view class="num-title ss-m-l-20">已拼{{ state.data.headRecord.userCount }}</view> </template>
</view> </s-goods-item>
</template> </view>
</s-goods-item> <image class="image" mode="aspectFill"
</view> src="https://zysc.fjptzykj.com:3000/shangcheng/2dc59ec207f1c5bd04d0f4734a4600c5e2dce8e5d740bb7ddfce75e9012a4b04.png" />
<view class="countdown-box detail-card ss-p-t-44 ss-flex-col ss-col-center">
<!-- 情况一拼团成功 -->
<view v-if="state.data.headRecord.status === 1">
<view v-if="state.data.orderId">
<view class="countdown-title ss-flex">
<text class="cicon-check-round" />
恭喜您~拼团成功
</view>
</view>
<view v-else>
<view class="countdown-title ss-flex">
<text class="cicon-info" />
抱歉~该团已满员
</view>
</view>
</view>
<view class="countdown-box detail-card ss-p-t-44 ss-flex-col ss-col-center"> <!-- 情况二拼团失败 -->
<!-- 情况一拼团成功 --> <view v-if="state.data.headRecord.status === 2">
<view v-if="state.data.headRecord.status === 1"> <view class="countdown-title ss-flex">
<view v-if="state.data.orderId"> <text class="cicon-info"></text>
<view class="countdown-title ss-flex"> {{ state.data.orderId ? '拼团超时,已自动退款' : '该团已解散' }}
<text class="cicon-check-round" /> </view>
恭喜您~拼团成功 </view>
</view>
</view>
<view v-else>
<view class="countdown-title ss-flex">
<text class="cicon-info" />
抱歉~该团已满员
</view>
</view>
</view>
<!-- 情况二拼团失败 --> <!-- 情况三拼团进行中 -->
<view v-if="state.data.headRecord.status === 2"> <view v-if="state.data.headRecord.status === 0">
<view class="countdown-title ss-flex"> <view v-if="state.data.headRecord.expireTime <= new Date().getTime()">
<text class="cicon-info"></text> <view class="countdown-title ss-flex">
{{ state.data.orderId ? '拼团超时,已自动退款' : '该团已解散' }} <text class="cicon-info"></text>
</view> 拼团已结束,请关注下次活动
</view> </view>
</view>
<view class="countdown-title ss-flex" v-else>
还差
<view class="num">{{ state.data.headRecord.userSize - state.data.headRecord.userCount }}</view>
拼团成功
<view class="ss-flex countdown-time">
<view class="countdown-h ss-flex ss-row-center">{{ endTime.h }}</view>
<view class="ss-m-x-4">:</view>
<view class="countdown-num ss-flex ss-row-center">
{{ endTime.m }}
</view>
<view class="ss-m-x-4">:</view>
<view class="countdown-num ss-flex ss-row-center">
{{ endTime.s }}
</view>
</view>
</view>
</view>
<!-- 情况三拼团进行中 --> <!-- 拼团的记录列表展示每个参团人 -->
<view v-if="state.data.headRecord.status === 0"> <view class="ss-m-t-60 ss-flex ss-flex-wrap ss-row-center">
<view v-if="state.data.headRecord.expireTime <= new Date().getTime()"> <!-- 团长 -->
<view class="countdown-title ss-flex"> <view class="header-avatar ss-m-r-24 ss-m-b-20">
<text class="cicon-info"></text> <image :src="sheep.$url.cdn(state.data.headRecord.avatar)" class="avatar-img"></image>
拼团已结束,请关注下次活动 <view class="header-tag ss-flex ss-col-center ss-row-center">团长</view>
</view> </view>
</view> <!-- 团员 -->
<view class="countdown-title ss-flex" v-else> <view class="header-avatar ss-m-r-24 ss-m-b-20" v-for="item in state.data.memberRecords"
还差 :key="item.id">
<view class="num" <image :src="sheep.$url.cdn(item.avatar)" class="avatar-img"></image>
>{{ state.data.headRecord.userSize - state.data.headRecord.userCount }}</view <view class="header-tag ss-flex ss-col-center ss-row-center" v-if="item.is_leader == '1'">
> 团长
拼团成功 </view>
<view class="ss-flex countdown-time"> </view>
<view class="countdown-h ss-flex ss-row-center">{{ endTime.h }}</view> <!-- 还有几个坑位 -->
<view class="ss-m-x-4">:</view> <view class="default-avatar ss-m-r-24 ss-m-b-20" v-for="item in state.remainNumber" :key="item">
<view class="countdown-num ss-flex ss-row-center"> <image :src="sheep.$url.static('/static/img/shop/avatar/unknown.png')" class="avatar-img">
{{ endTime.m }} </image>
</view> </view>
<view class="ss-m-x-4">:</view> </view>
<view class="countdown-num ss-flex ss-row-center"> </view>
{{ endTime.s }}
</view>
</view>
</view>
</view>
<!-- 拼团的记录列表展示每个参团人 --> <!-- 情况一拼团成功情况二拼团失败 -->
<view class="ss-m-t-60 ss-flex ss-flex-wrap ss-row-center"> <view v-if="state.data.headRecord.status === 1 || state.data.headRecord.status === 2"
<!-- 团长 --> class="ss-m-t-40 ss-flex ss-row-center">
<view class="header-avatar ss-m-r-24 ss-m-b-20"> <button class="ss-reset-button order-btn" v-if="state.data.orderId" @tap="onDetail(state.data.orderId)">
<image :src="sheep.$url.cdn(state.data.headRecord.avatar)" class="avatar-img"></image> 查看订单
<view class="header-tag ss-flex ss-col-center ss-row-center">团长</view> </button>
</view> <button class="ss-reset-button join-btn" v-else @tap="onCreateGroupon"> 我要开团 </button>
<!-- 团员 --> </view>
<view
class="header-avatar ss-m-r-24 ss-m-b-20"
v-for="item in state.data.memberRecords"
:key="item.id"
>
<image :src="sheep.$url.cdn(item.avatar)" class="avatar-img"></image>
<view
class="header-tag ss-flex ss-col-center ss-row-center"
v-if="item.is_leader == '1'"
>
团长
</view>
</view>
<!-- 还有几个坑位 -->
<view
class="default-avatar ss-m-r-24 ss-m-b-20"
v-for="item in state.remainNumber"
:key="item"
>
<image
:src="sheep.$url.static('/static/img/shop/avatar/unknown.png')"
class="avatar-img"
></image>
</view>
</view>
</view>
<!-- 情况一拼团成功情况二拼团失败 --> <!-- 情况三拼团进行中查看订单或参加或邀请好友或参加 -->
<view <view v-if="state.data.headRecord.status === 0" class="ss-m-t-40 ss-flex ss-row-center">
v-if="state.data.headRecord.status === 1 || state.data.headRecord.status === 2" <view v-if="state.data.headRecord.expireTime <= new Date().getTime()">
class="ss-m-t-40 ss-flex ss-row-center" <button class="ss-reset-button join-btn" v-if="state.data.orderId"
> @tap="onDetail(state.data.orderId)">
<button 查看订单
class="ss-reset-button order-btn" </button>
v-if="state.data.orderId" <button class="ss-reset-button disabled-btn" v-else disabled @tap="onDetail(state.data.orderId)">
@tap="onDetail(state.data.orderId)" 去参团
> </button>
查看订单 </view>
</button> <view v-else class="ss-flex ss-row-center">
<button class="ss-reset-button join-btn" v-else @tap="onCreateGroupon"> 我要开团 </button> <view v-if="state.data.orderId">
</view> <button class="ss-reset-button join-btn" :disabled="endTime.ms <= 0" @tap="onShare">
邀请好友来拼团
</button>
</view>
<view v-else>
<button class="ss-reset-button join-btn" :disabled="endTime.ms <= 0" @tap="onJoinGroupon()">
立即参团
</button>
</view>
</view>
</view>
<!-- 情况三拼团进行中查看订单或参加或邀请好友或参加 --> <!-- TODO 芋艿这里暂时没接入 -->
<view v-if="state.data.headRecord.status === 0" class="ss-m-t-40 ss-flex ss-row-center"> <s-select-groupon-sku :show="state.showSelectSku" :goodsInfo="state.goodsInfo"
<view v-if="state.data.headRecord.expireTime <= new Date().getTime()"> :grouponAction="state.grouponAction" :grouponNum="state.grouponNum" @buy="onBuy" @change="onSkuChange"
<button @close="state.showSelectSku = false" />
class="ss-reset-button join-btn" </view>
v-if="state.data.orderId"
@tap="onDetail(state.data.orderId)"
>
查看订单
</button>
<button
class="ss-reset-button disabled-btn"
v-else
disabled
@tap="onDetail(state.data.orderId)"
>
去参团
</button>
</view>
<view v-else class="ss-flex ss-row-center">
<view v-if="state.data.orderId">
<button class="ss-reset-button join-btn" :disabled="endTime.ms <= 0" @tap="onShare">
邀请好友来拼团
</button>
</view>
<view v-else>
<button
class="ss-reset-button join-btn"
:disabled="endTime.ms <= 0"
@tap="onJoinGroupon()"
>
立即参团
</button>
</view>
</view>
</view>
<!-- TODO 芋艿这里暂时没接入 --> <s-empty v-if="!state.data && !state.loading" icon="/static/goods-empty.png" />
<view v-if="state.data.goods"> </s-layout>
<s-select-groupon-sku
:show="state.showSelectSku"
:goodsInfo="state.data.goods"
:grouponAction="state.grouponAction"
:grouponNum="state.grouponNum"
@buy="onBuy"
@change="onSkuChange"
@close="state.showSelectSku = false"
/>
</view>
</view>
<s-empty v-if="!state.data && !state.loading" icon="/static/goods-empty.png" />
</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
import { useDurationTime } from '@/sheep/hooks/useGoods'; } from 'vue';
import { showShareModal } from '@/sheep/hooks/useModal'; import sheep from '@/sheep';
import { isEmpty } from 'lodash'; import {
import CombinationApi from '@/sheep/api/promotion/combination'; onLoad
} from '@dcloudio/uni-app';
import {
useDurationTime
} from '@/sheep/hooks/useGoods';
import {
showShareModal
} from '@/sheep/hooks/useModal';
import {
isEmpty
} from 'lodash';
import CombinationApi from '@/sheep/api/promotion/combination';
import SpuApi from '@/sheep/api/product/spu';
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 statusBarHeight = sheep.$platform.device.statusBarHeight * 2; const statusBarHeight = sheep.$platform.device.statusBarHeight * 2;
const state = reactive({ const state = reactive({
data: {}, // data: {
loading: true, goods: true
grouponAction: 'create', }, //
showSelectSku: false, loading: true,
grouponNum: 0, grouponAction: 'create',
number: 0, showSelectSku: false,
activity: {}, grouponNum: 0,
combinationHeadId: null, // number: 0,
}); activity: {},
combinationHeadId: null, //
goodsInfo: {}, //
goodsId: '',
skeletonLoading: false,
goodsSwiper: [], //
});
// todo // todo
const shareInfo = computed(() => { const shareInfo = computed(() => {
if (isEmpty(state.data)) return {}; if (isEmpty(state.data)) return {};
return sheep.$platform.share.getShareInfo( return sheep.$platform.share.getShareInfo({
{ title: state.data.headRecord.spuName,
title: state.data.headRecord.spuName, image: sheep.$url.cdn(state.data.headRecord.picUrl),
image: sheep.$url.cdn(state.data.headRecord.picUrl), desc: state.data.goods?.subtitle,
desc: state.data.goods?.subtitle, params: {
params: { page: '5',
page: '5', query: state.data.id,
query: state.data.id, },
}, }, {
}, type: 'groupon', //
{ title: state.data.headRecord.spuName, //
type: 'groupon', // image: sheep.$url.cdn(state.data.headRecord.picUrl), //
title: state.data.headRecord.spuName, // price: state.data.goods?.price, //
image: sheep.$url.cdn(state.data.headRecord.picUrl), // original_price: state.data.goods?.original_price, //
price: state.data.goods?.price, // }, );
original_price: state.data.goods?.original_price, // });
},
);
});
// //
function onDetail(orderId) { function onDetail(orderId) {
sheep.$router.go('/pages/order/detail', { sheep.$router.go('/pages/order/detail', {
id: orderId, id: orderId,
}); });
} }
// TODO // TODO
function onCreateGroupon() { function onCreateGroupon() {
state.grouponAction = 'create'; state.grouponAction = 'create';
state.grouponId = 0; state.grouponId = 0;
state.showSelectSku = true; state.showSelectSku = true;
} }
// TODO // TODO
function onSkuChange(e) { function onSkuChange(e) {
state.selectedSkuPrice = e; state.selectedSkuPrice = e;
} }
// TODO // TODO
function onJoinGroupon() { function onJoinGroupon() {
state.grouponAction = 'join'; state.grouponAction = 'join';
state.grouponId = state.data.activityId; state.grouponId = state.activityId;
state.combinationHeadId = state.data.id; state.combinationHeadId = state.id;
state.grouponNum = state.data.num; state.grouponNum = state.userSize;
state.showSelectSku = true; state.showSelectSku = true;
} }
// TODO // TODO
function onBuy(sku) { function onBuy(sku) {
sheep.$router.go('/pages/order/confirm', { sheep.$router.go('/pages/order/confirm', {
data: JSON.stringify({ data: JSON.stringify({
order_type: 'goods', order_type: 'goods',
combinationActivityId: state.data.activity.id, combinationActivityId: state.grouponId,
combinationHeadId: state.combinationHeadId, combinationHeadId: state.combinationHeadId,
items: [ items: [{
{ skuId: sku.id,
skuId: sku.id, count: sku.count,
count: sku.count, }, ],
}, }),
], });
}), }
});
}
const endTime = computed(() => { //
return useDurationTime(state.data.headRecord.expireTime); const loadActiv = async () => {
}); //
const {
code,
data: activity
} = await CombinationApi.getCombinationActivity(state.grouponId);
state.activity = activity;
const {
data: spu
} = await SpuApi.getSpuDetail(activity.spuId);
state.goodsId = spu.id;
activity.products.forEach((product) => {
spu.price = Math.min(spu.price, product.combinationPrice); // SPU
});
//
state.skeletonLoading = false;
if (code === 0) {
state.goodsInfo = spu;
state.grouponNum = activity.userSize;
// state.goodsSwiper = formatGoodsSwiper(state.goodsInfo.sliderPicUrls);
} else {
//
state.goodsInfo = null;
}
}
// const endTime = computed(() => {
async function getGrouponDetail(id) { return useDurationTime(state.data.headRecord.expireTime);
const { code, data } = await CombinationApi.getCombinationRecordDetail(id); });
if (code === 0) {
state.data = data;
const remainNumber = Number(state.data.headRecord.userSize - state.data.headRecord.userCount);
state.remainNumber = remainNumber > 0 ? remainNumber : 0;
// //
const { data: activity } = await CombinationApi.getCombinationActivity( async function getGrouponDetail(id) {
data.headRecord.activityId, const {
); code,
state.activity = activity; data
} else { } = await CombinationApi.getCombinationRecordDetail(id);
state.data = null; if (code === 0) {
} state.data = data;
state.loading = false; const remainNumber = Number(state.data.headRecord.userSize - state.data.headRecord.userCount);
} state.remainNumber = remainNumber > 0 ? remainNumber : 0;
function onShare() { //
showShareModal(); const {
} data: activity
} = await CombinationApi.getCombinationActivity(
data.headRecord.activityId,
);
state.activity = activity;
} else {
state.data = null;
}
state.loading = false;
}
onLoad((options) => { function onShare() {
getGrouponDetail(options.id); showShareModal();
}); }
onLoad((options) => {
getGrouponDetail(options.id);
//
if (!options.id) {
state.goodsInfo = null;
return;
}
state.grouponId = options.id;
loadActiv();
});
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.recharge-box { .image {
position: relative; display: block;
margin-bottom: 120rpx; margin: 0 auto;
background: v-bind(headerBg) center/750rpx 100% no-repeat, width: 100%;
linear-gradient(115deg, #f44739 0%, #ff6600 100%); height: 154px;
border-radius: 0 0 5% 5%; }
height: 100rpx;
.goods-box { .recharge-box {
width: 710rpx; position: relative;
border-radius: 20rpx; margin-bottom: 120rpx;
position: absolute; background: v-bind(headerBg) center/750rpx 100% no-repeat,
left: 20rpx; linear-gradient(115deg, #f44739 0%, #ff6600 100%);
box-sizing: border-box; border-radius: 0 0 5% 5%;
} height: 100rpx;
.sales-title { .goods-box {
height: 32rpx; width: 710rpx;
background: rgba(#ffe0e2, 0.29); border-radius: 20rpx;
border-radius: 16rpx; position: absolute;
font-size: 24rpx; left: 20rpx;
font-weight: 400; box-sizing: border-box;
padding: 6rpx 20rpx; }
color: #f7979c;
}
.num-title { .sales-title {
font-size: 24rpx; height: 32rpx;
font-weight: 400; background: rgba(#ffe0e2, 0.29);
color: #999999; border-radius: 16rpx;
} font-size: 24rpx;
} font-weight: 400;
padding: 6rpx 20rpx;
color: #f7979c;
}
.countdown-time { .num-title {
font-size: 26rpx; font-size: 24rpx;
font-weight: 500; font-weight: 400;
color: #383a46; color: #999999;
.countdown-h { }
font-size: 24rpx; }
font-family: OPPOSANS;
font-weight: 500;
color: #ffffff;
padding: 0 4rpx;
margin-left: 16rpx;
height: 40rpx;
background: linear-gradient(90deg, #ff6000 0%, #fe832a 100%);
border-radius: 6rpx;
}
.countdown-num {
font-size: 24rpx;
font-family: OPPOSANS;
font-weight: 500;
color: #ffffff;
width: 40rpx;
height: 40rpx;
background: linear-gradient(90deg, #ff6000 0%, #fe832a 100%);
border-radius: 6rpx;
}
}
.countdown-box { .countdown-time {
// height: 364rpx; font-size: 26rpx;
background: #ffffff; font-weight: 500;
border-radius: 10rpx; color: #383a46;
box-sizing: border-box;
.countdown-title { .countdown-h {
font-size: 28rpx; font-size: 24rpx;
font-weight: 500; font-family: OPPOSANS;
color: #333333; font-weight: 500;
color: #ffffff;
padding: 0 4rpx;
margin-left: 16rpx;
height: 40rpx;
background: linear-gradient(90deg, #ff6000 0%, #fe832a 100%);
border-radius: 6rpx;
}
.cicon-check-round { .countdown-num {
color: #42b111; font-size: 24rpx;
margin-right: 24rpx; font-family: OPPOSANS;
} font-weight: 500;
color: #ffffff;
width: 40rpx;
height: 40rpx;
background: linear-gradient(90deg, #ff6000 0%, #fe832a 100%);
border-radius: 6rpx;
}
}
.cicon-info { .countdown-box {
color: #d71e08; // height: 364rpx;
margin-right: 24rpx; background: #ffffff;
} border-radius: 10rpx;
box-sizing: border-box;
.num { .countdown-title {
color: #ff6000; font-size: 28rpx;
} font-weight: 500;
} color: #333333;
.header-avatar { .cicon-check-round {
width: 86rpx; color: #42b111;
height: 86rpx; margin-right: 24rpx;
background: #ececec; }
border-radius: 50%;
border: 4rpx solid #edc36c;
position: relative;
box-sizing: border-box;
.avatar-img { .cicon-info {
width: 100%; color: #d71e08;
height: 100%; margin-right: 24rpx;
border-radius: 50%; }
}
.header-tag { .num {
width: 72rpx; color: #ff6000;
height: 36rpx; }
font-size: 24rpx; }
line-height: nor;
background: linear-gradient(132deg, #f3dfb1, #f3dfb1, #ecbe60);
border-radius: 16rpx;
position: absolute;
left: 4rpx;
top: -36rpx;
}
}
.default-avatar {
width: 86rpx;
height: 86rpx;
background: #ececec;
border-radius: 50%;
.avatar-img {
width: 100%;
height: 100%;
border-radius: 50%;
}
}
.user-avatar { .header-avatar {
width: 86rpx; width: 86rpx;
height: 86rpx; height: 86rpx;
background: #ececec; background: #ececec;
border-radius: 50%; border-radius: 50%;
} border: 4rpx solid #edc36c;
} position: relative;
.order-btn { box-sizing: border-box;
width: 668rpx;
height: 70rpx;
border: 2rpx solid #dfdfdf;
border-radius: 35rpx;
color: #999999;
font-weight: 500;
font-size: 26rpx;
line-height: normal;
}
.disabled-btn { .avatar-img {
width: 668rpx; width: 100%;
height: 70rpx; height: 100%;
background: #dddddd; border-radius: 50%;
border-radius: 35rpx; }
color: #999999;
font-weight: 500;
font-size: 28rpx;
line-height: normal;
}
.join-btn { .header-tag {
width: 668rpx; width: 72rpx;
height: 70rpx; height: 36rpx;
background: linear-gradient(90deg, #ff6000 0%, #fe832a 100%); font-size: 24rpx;
box-shadow: 0px 8rpx 6rpx 0px rgba(255, 104, 4, 0.22); line-height: nor;
border-radius: 35rpx; background: linear-gradient(132deg, #f3dfb1, #f3dfb1, #ecbe60);
color: #fff; border-radius: 16rpx;
font-weight: 500; position: absolute;
font-size: 28rpx; left: 4rpx;
line-height: normal; top: -36rpx;
} }
}
.detail-cell-wrap { .default-avatar {
width: 100%; width: 86rpx;
padding: 10rpx 20rpx; height: 86rpx;
box-sizing: border-box; background: #ececec;
border-top: 2rpx solid #dfdfdf; border-radius: 50%;
background-color: #fff;
// min-height: 60rpx;
.label-text { .avatar-img {
font-size: 28rpx; width: 100%;
font-weight: 400; height: 100%;
} border-radius: 50%;
}
}
.cell-content { .user-avatar {
font-size: 28rpx; width: 86rpx;
font-weight: 500; height: 86rpx;
color: $dark-6; background: #ececec;
} border-radius: 50%;
}
}
.right-forwrad-icon { .order-btn {
font-size: 28rpx; width: 668rpx;
font-weight: 500; height: 70rpx;
color: $dark-9; border: 2rpx solid #dfdfdf;
} border-radius: 35rpx;
} color: #999999;
</style> font-weight: 500;
font-size: 26rpx;
line-height: normal;
}
.disabled-btn {
width: 668rpx;
height: 70rpx;
background: #dddddd;
border-radius: 35rpx;
color: #999999;
font-weight: 500;
font-size: 28rpx;
line-height: normal;
}
.join-btn {
width: 668rpx;
height: 70rpx;
background: linear-gradient(90deg, #ff6000 0%, #fe832a 100%);
box-shadow: 0px 8rpx 6rpx 0px rgba(255, 104, 4, 0.22);
border-radius: 35rpx;
color: #fff;
font-weight: 500;
font-size: 28rpx;
line-height: normal;
}
.detail-cell-wrap {
width: 100%;
padding: 10rpx 20rpx;
box-sizing: border-box;
border-top: 2rpx solid #dfdfdf;
background-color: #fff;
// min-height: 60rpx;
.label-text {
font-size: 28rpx;
font-weight: 400;
}
.cell-content {
font-size: 28rpx;
font-weight: 500;
color: $dark-6;
}
.right-forwrad-icon {
font-size: 28rpx;
font-weight: 500;
color: $dark-9;
}
}
</style>

View File

@ -119,7 +119,7 @@
width: 100%; width: 100%;
height: 458rpx; height: 458rpx;
margin-top: -88rpx; margin-top: -88rpx;
background: v-bind(headerBg) no-repeat; background: url('https://zysc.fjptzykj.com:3000/shangcheng/fea9ad54f32d4705a633874efd534e70e507030ea5a7604b0110fdf7292f1f4d.png');
background-size: 100% 100%; background-size: 100% 100%;
} }
.list-content { .list-content {

View File

@ -85,7 +85,12 @@
<!-- 参团列表 --> <!-- 参团列表 -->
<groupon-card-list v-model="state.activity" @join="onJoinGroupon" /> <groupon-card-list v-model="state.activity" @join="onJoinGroupon" />
<!-- 参团玩法 -->
<view class="detail-cell-card detail-card ss-flex-col">
<image class="image" mode="aspectFill" src="https://zysc.fjptzykj.com:3000/shangcheng/27747f3ba1d36807f485eab196aecd357e0811d6f74b36936818a2a7ff86d96e.png"/>
</view>
<!-- 规格与数量弹框 --> <!-- 规格与数量弹框 -->
<s-select-groupon-sku <s-select-groupon-sku
:show="state.showSelectSku" :show="state.showSelectSku"
@ -279,6 +284,9 @@
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.image{
height: 142px;
}
.detail-card { .detail-card {
background-color: $white; background-color: $white;
margin: 14rpx 20rpx; margin: 14rpx 20rpx;
@ -529,4 +537,7 @@
width: 100%; width: 100%;
height: 100%; height: 100%;
} }
body{
background:#f6f6f6 !important;
}
</style> </style>

295
pages/goods/sales.vue Normal file
View File

@ -0,0 +1,295 @@
<!-- 秒杀商品详情 -->
<template>
<s-layout :onShareAppMessage="shareInfo" navbar="goods">
ssss
</s-layout>
</template>
<script setup>
import SpuApi from '@/sheep/api/product/spu';
const getSpu = async (id) => {
const { data } = await SpuApi.getSpusales(id);
console.log(data,"我要留了")
};
getSpu()
</script>
<style lang="scss" scoped>
.disabled-btn-box[disabled] {
background-color: transparent;
}
.detail-card {
background-color: $white;
margin: 14rpx 20rpx;
border-radius: 10rpx;
overflow: hidden;
}
//
.title-card {
width: 710rpx;
box-sizing: border-box;
// height: 320rpx;
background-size: 100% 100%;
border-radius: 10rpx;
background-image: url('@/static/images/seckill-header.png');
background-repeat: no-repeat;
.price-box {
.price-text {
font-size: 30rpx;
font-weight: 500;
color: #fff;
line-height: normal;
font-family: OPPOSANS;
&::before {
content: '¥';
font-size: 30rpx;
}
}
}
.origin-price {
font-size: 24rpx;
font-weight: 400;
color: #fff;
opacity: 0.7;
.origin-price-text {
text-decoration: line-through;
font-family: OPPOSANS;
&::before {
content: '¥';
}
}
}
.tig {
border: 2rpx solid #ffffff;
border-radius: 4rpx;
width: 126rpx;
height: 38rpx;
.tig-icon {
width: 40rpx;
height: 40rpx;
margin-left: -2rpx;
background: #ffffff;
border-radius: 4rpx 0 0 4rpx;
.cicon-alarm {
font-size: 32rpx;
color: #fc6e6f;
}
}
.tig-title {
width: 86rpx;
font-size: 24rpx;
font-weight: 500;
line-height: normal;
color: #ffffff;
display: flex;
justify-content: center;
align-items: center;
}
}
.countdown-title {
font-size: 26rpx;
font-weight: 500;
color: #ffffff;
}
.countdown-time {
font-size: 26rpx;
font-weight: 500;
color: #ffffff;
.countdown-h {
font-size: 24rpx;
font-family: OPPOSANS;
font-weight: 500;
color: #ffffff;
padding: 0 4rpx;
height: 40rpx;
background: rgba(#000000, 0.1);
border-radius: 6rpx;
}
.countdown-num {
font-size: 24rpx;
font-family: OPPOSANS;
font-weight: 500;
color: #ffffff;
width: 40rpx;
height: 40rpx;
background: rgba(#000000, 0.1);
border-radius: 6rpx;
}
}
.discounts-box {
.discounts-tag {
padding: 4rpx 10rpx;
font-size: 24rpx;
font-weight: 500;
border-radius: 4rpx;
color: var(--ui-BG-Main);
// background: rgba(#2aae67, 0.05);
background: var(--ui-BG-Main-tag);
}
.discounts-title {
font-size: 24rpx;
font-weight: 500;
color: var(--ui-BG-Main);
line-height: normal;
}
.cicon-forward {
color: var(--ui-BG-Main);
font-size: 24rpx;
line-height: normal;
margin-top: 4rpx;
}
}
.title-text {
font-size: 30rpx;
font-weight: bold;
line-height: 42rpx;
color: #fff;
}
.subtitle-text {
font-size: 26rpx;
font-weight: 400;
color: #ffffff;
line-height: 42rpx;
opacity: 0.9;
}
}
//
.buy-box {
.check-btn-box {
width: 248rpx;
height: 80rpx;
font-size: 24rpx;
font-weight: 600;
margin-left: -36rpx;
background-image: url('@/static/images/groupon-btn.png');
background-repeat: no-repeat;
background-size: 100% 100%;
color: #ffffff;
line-height: normal;
border-radius: 0px 40rpx 40rpx 0px;
}
.disabled-btn-box {
width: 248rpx;
height: 80rpx;
font-size: 24rpx;
font-weight: 600;
margin-left: -36rpx;
background-image: url('@/static/images/activity-btn-disabled.png');
background-repeat: no-repeat;
background-size: 100% 100%;
color: #999999;
line-height: normal;
border-radius: 0px 40rpx 40rpx 0px;
}
.btn-price {
font-family: OPPOSANS;
&::before {
content: '¥';
}
}
.origin-price-btn {
width: 236rpx;
height: 80rpx;
background: rgba(#ff5651, 0.1);
color: #ff6000;
border-radius: 40rpx 0px 0px 40rpx;
line-height: normal;
font-size: 24rpx;
font-weight: 500;
.no-original {
font-size: 28rpx;
}
.btn-title {
font-size: 28rpx;
}
}
}
//
.seckill-box {
background: v-bind(seckillBg) no-repeat;
background-size: 100% 100%;
}
.groupon-box {
background: v-bind(grouponBg) no-repeat;
background-size: 100% 100%;
}
//
.activity-box {
width: 100%;
height: 80rpx;
box-sizing: border-box;
margin-bottom: 10rpx;
.activity-title {
font-size: 26rpx;
font-weight: 500;
color: #ffffff;
line-height: 42rpx;
.activity-icon {
width: 38rpx;
height: 38rpx;
}
}
.activity-go {
width: 70rpx;
height: 32rpx;
background: #ffffff;
border-radius: 16rpx;
font-weight: 500;
color: #ff6000;
font-size: 24rpx;
line-height: normal;
}
}
.model-box {
.title {
font-size: 36rpx;
font-weight: bold;
color: #333333;
}
.subtitle {
font-size: 26rpx;
font-weight: 500;
color: #333333;
}
}
image {
width: 100%;
height: 100%;
}
</style>

View File

@ -1,35 +1,36 @@
<template> <template>
<s-layout title="预约" :bgStyle="{ color: '#fff' }"> <s-layout title="预约" :bgStyle="{ color: '#fff' }">
<view class="container"> <view class="container">
<view class="doctor-list"> <view class="doctor-list">
<view class="doctor-cards" > <view class="doctor-cards">
<image class="doctor-avatars" :src="'https://sfyjk.com/api'+brandList[selectedClinicIndex].picUrl" mode="aspectFill"></image><br/><br/> <image class="doctor-avatars" :src="brandList.list[selectedClinicIndex].picUrl"
mode="aspectFill"></image><br /><br />
<view class="brandr-info"> <view class="brandr-info">
<text class="doctor-names"> <text class="doctor-names">
<text class="ygcontent">医馆地址</text> <text class="ygcontent">医馆地址</text>
{{ brandList[selectedClinicIndex].address }}</text><br/><br/> {{ brandList.list[selectedClinicIndex].address }}</text><br /><br />
<!-- <div v-html='brandList[selectedClinicIndex].depict'></div> --> <!-- <div v-html='brandList.list[selectedClinicIndex].depict'></div> -->
<rich-text class="doctor-specialtys" :nodes="brandList[selectedClinicIndex].depict"></rich-text> <rich-text class="doctor-specialtys" :nodes="brandList.list[selectedClinicIndex].depict"></rich-text>
</view> </view>
</view> </view>
</view> </view>
<view class="clinic-select"> <view class="clinic-select">
<text class="clinic-select-label">医馆选择</text> <text class="clinic-select-label">医馆选择</text>
<picker mode="selector" :range="brandNameList" @change="onClinicChange"> <picker mode="selector" :range="brandNameList" @change="onClinicChange">
<view class="clinic-select-value"> <view class="clinic-select-value">
<text>{{ brandList[selectedClinicIndex].name}}</text> <text>{{ brandList.list[selectedClinicIndex].name}}</text>
</view> </view>
</picker> </picker>
</view> </view>
<view class="clinic-select"> <view class="clinic-select">
<text class="clinic-select-label">预约类型</text> <text class="clinic-select-label">预约类型</text>
<picker mode="selector" :range="typenameList" @change="ontype"> <picker mode="selector" :range="typenameList" @change="ontype">
<view class="clinic-select-value"> <view class="clinic-select-value">
<text>{{ typeList[selecttypeIndex].dictLabel}}</text> <text>{{ typeList[selecttypeIndex].label}}</text>
</view> </view>
</picker> </picker>
</view> </view>
@ -52,12 +53,12 @@
<view class="date-list"> <view class="date-list">
<view v-for="(item, index) in dateList" :key="index" @click="selectDate(index)"> <view v-for="(item, index) in dateList" :key="index" @click="selectDate(index)">
<view class="date-item" v-if="addDate==item.addDate" style="background-color: #ff5541;"> <view class="date-item" v-if="addDate==item.addDate" style="background-color: #ff5541;">
<text class="date" style="color: #FFFFFF;">{{ item.formattedDate }}</text> <text class="date" style="color: #FFFFFF;">{{ item.formattedDate }}</text>
<text class="weekday" style="color: #FFFFFF;">{{ item.weekday }}</text> <text class="weekday" style="color: #FFFFFF;">{{ item.weekday }}</text>
</view> </view>
<view class="date-item" v-if="addDate!=item.addDate"> <view class="date-item" v-if="addDate!=item.addDate">
<text class="date">{{ item.formattedDate }}</text> <text class="date">{{ item.formattedDate }}</text>
<text class="weekday">{{ item.weekday }}</text> <text class="weekday">{{ item.weekday }}</text>
</view> </view>
@ -76,13 +77,15 @@
<!-- {{techList}} --> <!-- {{techList}} -->
<view class="doctor-card" v-for="(item, index) in techList" :key="index"> <view class="doctor-card" v-for="(item, index) in techList" :key="index">
<view class="doctor-info"> <view class="doctor-info">
<image class="doctor-avatar" :src="'https://sfyjk.com/api'+item.photo" mode="aspectFill"></image> <image class="doctor-avatar" :src="'https://sfyjk.com/api'+item.photo" mode="aspectFill">
</image>
<text class="doctor-name">{{ item.technicianName }}</text> <text class="doctor-name">{{ item.technicianName }}</text>
<text class="doctor-name" style="float: right;margin-right: 20px;">{{item.typeName}}</text> <text class="doctor-name" style="float: right;margin-right: 20px;">{{item.typeName}}</text>
<!-- <text class="doctor-specialty" v-if="item.content">介绍: {{item.content.substr(0, 20)}}...</text> --> <!-- <text class="doctor-specialty" v-if="item.content">介绍: {{item.content.substr(0, 20)}}...</text> -->
</view> </view>
<radio style="float: right;" :value="item.id" @click="onradio(item)" :checked="index==0"></radio> <radio style="float: right;" :value="item.id" @click="onradio(item)" :checked="index==0">
</radio>
<div v-if="techid == item.id"> <div v-if="techid == item.id">
<view class="info-title">服务范围</view> <view class="info-title">服务范围</view>
<rich-text style="white-space: pre-wrap;" :nodes="item.serviceScope"></rich-text> <rich-text style="white-space: pre-wrap;" :nodes="item.serviceScope"></rich-text>
@ -90,7 +93,7 @@
<rich-text style="white-space: pre-wrap;" :nodes="item.content"></rich-text> <rich-text style="white-space: pre-wrap;" :nodes="item.content"></rich-text>
</div> </div>
</view> </view>
</view> </view>
</radio-group> </radio-group>
<radio-group> <radio-group>
@ -99,20 +102,20 @@
<view class="date-itemstr" v-if="hsstr==item.str" style="background-color: #ff5541;"> <view class="date-itemstr" v-if="hsstr==item.str" style="background-color: #ff5541;">
<text class="weekday">{{ item.str }}</text> <text class="weekday">{{ item.str }}</text>
</view> </view>
<view v-if="item.ym==='true'"> <view v-if="item.ym==='true'">
<view class="date-itemym" v-if="hsstr!=item.str" > <view class="date-itemym" v-if="hsstr!=item.str">
<text class="weekdayym">约满</text><br/> <text class="weekdayym">约满</text><br />
<text class="weekday">{{ item.str }}</text> <text class="weekday">{{ item.str }}</text>
</view> </view>
</view> </view>
<view v-if="item.ym==='false'"> <view v-if="item.ym==='false'">
<view class="date-itemstr" v-if="hsstr!=item.str" > <view class="date-itemstr" v-if="hsstr!=item.str">
<text class="weekday">{{ item.str }}</text> <text class="weekday">{{ item.str }}</text>
</view> </view>
</view> </view>
</view> </view>
</view> </view>
</radio-group> </radio-group>
@ -127,24 +130,33 @@
</template> </template>
<script> <script>
import { baseUrl, apiPath } from '@/sheep/config'; import request from '@/sheep/request';
import { computed } from 'vue'; import {
baseUrl,
apiPath
} from '@/sheep/config';
import {
computed
} from 'vue';
import sheep from '@/sheep'; import sheep from '@/sheep';
import { showShareModal, showAuthModal } from '@/sheep/hooks/useModal'; import {
showShareModal,
showAuthModal
} from '@/sheep/hooks/useModal';
// import pickerTime from "@/pages/commission/pickerTime.vue" // import pickerTime from "@/pages/commission/pickerTime.vue"
// //
export default { export default {
// components: { // components: {
// pickerTime // pickerTime
// }, // },
data() { data() {
return { return {
isLogin:null, isLogin: null,
memberId:null, memberId: null,
// showTime: false, // showTime: false,
serviceTime:[], serviceTime: [],
sjd:{}, sjd: {},
ym:[], ym: [],
// starhour: 8, // starhour: 8,
// starminute: 0, // starminute: 0,
// endhour: 18, // endhour: 18,
@ -154,47 +166,53 @@
hsstr: "", hsstr: "",
dateList: [], dateList: [],
typeList:[ typeList: [{
{dictValue:0,dictLabel:"调理预约"}, dictValue: 0,
{dictValue:1,dictLabel:"教培预约"} dictLabel: "调理预约"
},
{
dictValue: 1,
dictLabel: "教培预约"
}
], ],
typenameList:[], typenameList: [],
addDate: "", addDate: "",
techList: [], // techList: [], //
// //
selectedClinicIndex: 0, // selectedClinicIndex: 0, //
brandList: [{ brandList: [{
name:"" name: ""
}], }],
brandNameList: [], brandNameList: [],
brandId: "", brandId: "",
brandName: "", brandName: "",
selectedDayIndex: 0, selectedDayIndex: 0,
selecttypeIndex:0, selecttypeIndex: 0,
techid: 0, techid: 0,
type: 0, type: 0,
}; };
}, },
created() { created() {
this.isLogin = computed(() => sheep.$store('user').isLogin); this.isLogin = computed(() => sheep.$store('user').isLogin);
this.memberId=computed(() => sheep.$store('user').userInfo).value.id this.memberId = computed(() => sheep.$store('user').userInfo).value.id
this.brandlist(); this.brandlists();
this.generateDateList(); this.generateDateList();
this.addDate=this.dateList[0].addDate; this.addDate = this.dateList[0].addDate;
this.gettypeList(); this.gettypeList();
console.log(apiPath,baseUrl,"import.meta.env.SHOPRO_API_PATH") console.log(apiPath, baseUrl, "import.meta.env.SHOPRO_API_PATH")
}, },
methods: { methods: {
onClinicChange(event) { onClinicChange(event) {
const selectedClinicIndex = event.detail.value; const selectedClinicIndex = event.detail.value;
this.selectedClinicIndex = selectedClinicIndex; this.selectedClinicIndex = selectedClinicIndex;
this.brandName = this.brandList[selectedClinicIndex].name this.brandName = this.brandList.list[selectedClinicIndex].name
this.brandId = this.brandList[selectedClinicIndex].id this.brandId = this.brandList.list[selectedClinicIndex].id
console.log("dddddddddddd")
this.technicianList(); this.technicianList();
}, },
ontype(event){ ontype(event) {
const selecttypeIndex = event.detail.value; const selecttypeIndex = event.detail.value;
this.selecttypeIndex = selecttypeIndex; this.selecttypeIndex = selecttypeIndex;
this.typename = this.typeList[selecttypeIndex].dictValue this.typename = this.typeList[selecttypeIndex].dictValue
@ -203,110 +221,201 @@
this.technicianList(); this.technicianList();
}, },
// //
brandlist() { brandlists() {
uni.request({ request({
url: `${baseUrl}/api/h5/brand/list`, url: `${baseUrl}${apiPath}/h5/brand/list`,
success: (res) => { method: 'GET',
this.brandList = res.data custom: {
for (var i = 0; i < this.brandList.length; i++) { showLoading: false,
// this.brandList[i].depict=(this.brandList[i].depict).replace(/\<img/gi, '<img style="max-width:100%;height:auto" ')
this.brandNameList.push(this.brandList[i].name)
}
this.brandId = this.brandList[0].id
this.technicianList();
}, },
fail: (error) => { }).then((res) => {
console.log(error) this.brandList = res.data
console.log(this.brandList,"this.brandList")
for (var i = 0; i < this.brandList.list.length; i++) {
// this.brandList[i].depict=(this.brandList[i].depict).replace(/\<img/gi, '<img style="max-width:100%;height:auto" ')
this.brandNameList.push(this.brandList.list[i].name)
} }
})
}, this.brandId = this.brandList[0].id
this.technicianList();
gettypeList() { });
uni.request({ // uni.request({
url: `${baseUrl}/api/h5/reservation/type`, // url: `${baseUrl}/api/h5/brand/list`,
success: (res) => { // success: (res) => {
this.typeList = res.data.data // this.brandList = res.data
// this.typeList.depict=this.typeList.depict.replace(/\<img/gi, '<img style="max-width:100%;float:left; height:auto" ') // for (var i = 0; i < this.brandList.length; i++) {
for (var i = 0; i < this.typeList.length; i++) { // // this.brandList[i].depict=(this.brandList[i].depict).replace(/\<img/gi, '<img style="max-width:100%;height:auto" ')
this.typenameList.push(this.typeList[i].dictLabel); // this.brandNameList.push(this.brandList[i].name)
} // }
console.log(this.typenameList)
}, // this.brandId = this.brandList[0].id
fail: (error) => { // this.technicianList();
console.log(error) // },
} // fail: (error) => {
}) // console.log(error)
// }
// })
},
gettypeList() {
request({
url: `${baseUrl}${apiPath}/h5/reservation/type`,
method: 'GET',
custom: {
showLoading: false,
},
}).then((res) => {
console.log(res,"typeListtypeList")
this.typeList = res.data
// this.typeList.depict=this.typeList.depict.replace(/\<img/gi, '<img style="max-width:100%;float:left; height:auto" ')
for (var i = 0; i < this.typeList.length; i++) {
this.typenameList.push(this.typeList[i].label);
}
console.log(this.typenameList)
});
// uni.request({
// url: `${baseUrl}/api/h5/reservation/type`,
// success: (res) => {
// this.typeList = res.data.data
// // this.typeList.depict=this.typeList.depict.replace(/\<img/gi, '<img style="max-width:100%;float:left; height:auto" ')
// for (var i = 0; i < this.typeList.length; i++) {
// this.typenameList.push(this.typeList[i].dictLabel);
// }
// console.log(this.typenameList)
// },
// fail: (error) => {
// console.log(error)
// }
// })
}, },
// //
technicianList() { technicianList() {
console.log("有没有进来technicianList");
this.techid = null, this.techid = null,
this.serviceTime=[] this.serviceTime = []
this.hsstr="" this.hsstr = ""
uni.request({ request({
// url: 'https://sfyjk.com/api/h5/technician/list', url: `${baseUrl}${apiPath}/h5/technician/list`,
url: 'https://sfyjk.com/api/h5/technician/list', method: 'GET',
data: { params:{
type: this.type, type: this.type,
// addDate:this.addDate, // addDate:this.addDate,
brandId:this.brandId brandId: this.brandId
}, },
success: (res) => { custom: {
console.log(res) showLoading: false,
this.techList = res.data.rows },
console.log(this.techList) }).then((res) => {
if (this.techList.length > 0) { console.log(res)
this.techid=this.techList[0].id this.techList = res.data.list
var item={id:this.techid} console.log(this.techList)
this.onradio(item); if (this.techList.length > 0) {
this.techid = this.techList[0].id
var item = {
id: this.techid
} }
this.onradio(item);
console.log(this.techList)
},
fail: (error) => {
console.log(error)
} }
})
console.log(this.techList)
});
// uni.request({
// // url: 'https://sfyjk.com/api/h5/technician/list',
// url: `${baseUrl}/app-api/h5/technician/list`,
// data: {
// type: this.type,
// // addDate:this.addDate,
// brandId: this.brandId
// },
// success: (res) => {
// console.log(res)
// this.techList = res.data.rows
// console.log(this.techList)
// if (this.techList.length > 0) {
// this.techid = this.techList[0].id
// var item = {
// id: this.techid
// }
// this.onradio(item);
// }
// console.log(this.techList)
// },
// fail: (error) => {
// console.log(error)
// }
// })
}, },
onradio(item) { onradio(item) {
this.techid = item.id this.techid = item.id
this.serviceTime=[] this.serviceTime = []
this.hsstr="" this.hsstr = ""
uni.request({ request({
// url: 'https://sfyjk.com/api/h5/technician/' + this.techid, // url: `${baseUrl}${apiPath}/h5/technician/h5xq`,
url: 'https://sfyjk.com/api/h5/technician/h5xq', // method: 'GET',
data: { params:{
addDate:this.addDate, addDate: this.addDate,
id:this.techid id: this.techid
}, },
success: (res) => { custom: {
console.log(res); showLoading: false,
var serviceTime=JSON.parse(res.data.data.serviceTime)
console.log(serviceTime)
if (serviceTime){
for (let i = 0; i <serviceTime.length; i++) {
console.log(serviceTime[i].endTime)
console.log(serviceTime[i].startTime)
console.log(serviceTime[i].ym)
if (serviceTime[i].endTime&&serviceTime[i].startTime){
this.sjd={},
this.sjd.str=serviceTime[i].startTime.toString()+"-"+serviceTime[i].endTime.toString()
this.sjd.ym=serviceTime[i].ym
this.serviceTime.push(this.sjd)
}
}
}
console.log(this.serviceTime)
}, },
fail: (error) => { }).then((res) => {
console.log(error) console.log(res);
var serviceTime = JSON.parse(res.data.serviceTime)
console.log(serviceTime,"serviceTimeserviceTimeserviceTime")
if (serviceTime) {
for (let i = 0; i < serviceTime.length; i++) {
console.log(serviceTime[i].end)
console.log(serviceTime[i].start)
console.log(serviceTime[i].ym)
if (serviceTime[i].end && serviceTime[i].start) {
this.sjd = {},
this.sjd.str = serviceTime[i].start.toString() + "-" + serviceTime[
i].end.toString()
this.sjd.ym = serviceTime[i].ym
this.serviceTime.push(this.sjd)
}
}
} }
}) console.log(this.serviceTime,"this.serviceTime")
});
// uni.request({
// // url: 'https://sfyjk.com/api/h5/technician/' + this.techid, //
// url: `${baseUrl}/app-api/h5/technician/h5xq`, //
// data: {
// addDate: this.addDate,
// id: this.techid
// },
// success: (res) => {
// console.log(res);
// var serviceTime = JSON.parse(res.data.data.serviceTime)
// console.log(serviceTime)
// if (serviceTime) {
// for (let i = 0; i < serviceTime.length; i++) {
// console.log(serviceTime[i].endTime)
// console.log(serviceTime[i].startTime)
// console.log(serviceTime[i].ym)
// if (serviceTime[i].endTime && serviceTime[i].startTime) {
// this.sjd = {},
// this.sjd.str = serviceTime[i].startTime.toString() + "-" + serviceTime[
// i].endTime.toString()
// this.sjd.ym = serviceTime[i].ym
// this.serviceTime.push(this.sjd)
// }
// }
// }
// console.log(this.serviceTime)
// },
// fail: (error) => {
// console.log(error)
// }
// })
}, },
selectDay(index) { selectDay(index) {
@ -323,64 +432,95 @@
return date.toLocaleDateString("en-US", options); return date.toLocaleDateString("en-US", options);
}, },
handleSubmit() { handleSubmit() {
this.memberId=computed(() => sheep.$store('user').userInfo).value.id this.memberId = computed(() => sheep.$store('user').userInfo).value.id
if (!this.memberId){ if (!this.memberId) {
if (sheep.$platform.name === 'WechatMiniProgram') { if (sheep.$platform.name === 'WechatMiniProgram') {
showAuthModal('wechatMiniLogin') showAuthModal('wechatMiniLogin')
return; return;
} }
showAuthModal('accountLogin') showAuthModal('accountLogin')
}else{ } else {
this.memberId=computed(() => sheep.$store('user').userInfo).value.id this.memberId = computed(() => sheep.$store('user').userInfo).value.id
if(!this.brandId){ if (!this.brandId) {
sheep.$helper.toast('请选择医馆') sheep.$helper.toast('请选择医馆')
}else if(!this.techid){ } else if (!this.techid) {
sheep.$helper.toast('请选择技师') sheep.$helper.toast('请选择技师')
}else if(!this.addDate){ } else if (!this.addDate) {
sheep.$helper.toast('请选择预约时间') sheep.$helper.toast('请选择预约时间')
}else if(!this.hsstr){ } else if (!this.hsstr) {
sheep.$helper.toast('请选择预约时间段') sheep.$helper.toast('请选择预约时间段')
}else if(this.memberId){ } else if (this.memberId) {
uni.request({ request({
method: "post", url: `${baseUrl}/app-api/h5/reservation`,
url: 'https://sfyjk.com/api/h5/reservation', method: 'post',
data: { params: {
type: this.type, type: this.type,
brandId: this.brandId, brandId: this.brandId,
technicianId: this.techid, technicianId: this.techid,
reAddTime: this.addDate, reAddTime: this.addDate,
hsstr: this.hsstr, hsstr: this.hsstr,
userId:this.memberId, userId: this.memberId,
}, },
success: (res) => { custom: {
uni.showModal({ showLoading: false,
title: '预约提示', },
content: '预约成功!', }).then((res) => {
success: function(res) { uni.showModal({
if (res.confirm) { title: '预约提示',
uni.switchTab({ content: '预约成功!',
url: '/pages/index/user' success: function(res) {
}); if (res.confirm) {
} else { uni.switchTab({
uni.switchTab({ url: '/pages/index/user'
url: '/pages/index/user' });
}); } else {
} uni.switchTab({
} url: '/pages/index/user'
}); });
}
},
fail: (error) => {
console.log(error)
} }
}) });
});
// uni.request({
// method: "post",
// url: `${baseUrl}/app-api/h5/reservation`,
// data: {
// type: this.type,
// brandId: this.brandId,
// technicianId: this.techid,
// reAddTime: this.addDate,
// hsstr: this.hsstr,
// userId: this.memberId,
// },
// success: (res) => {
// uni.showModal({
// title: '',
// content: '',
// success: function(res) {
// if (res.confirm) {
// uni.switchTab({
// url: '/pages/index/user'
// });
// } else {
// uni.switchTab({
// url: '/pages/index/user'
// });
// }
// }
// });
// },
// fail: (error) => {
// console.log(error)
// }
// })
} }
} }
console.log("立即预约");
console.log("立即预约");
}, },
@ -406,25 +546,27 @@
}, },
selectDate(index) { selectDate(index) {
this.addDate = this.dateList[index].addDate this.addDate = this.dateList[index].addDate
if(this.techid){ if (this.techid) {
var item={id:this.techid} var item = {
id: this.techid
}
this.onradio(item); this.onradio(item);
} }
// //
console.log('Selected date:', this.addDate); console.log('Selected date:', this.addDate);
}, },
selecthsstr(index) { selecthsstr(index) {
console.log(this.serviceTime[index].str) console.log(this.serviceTime[index].str)
console.log(this.serviceTime[index].ym) console.log(this.serviceTime[index].ym)
if(this.serviceTime[index].ym==="true"){ if (this.serviceTime[index].ym === "true") {
this.hsstr = this.serviceTime[index].str
}else if(this.serviceTime[index].ym==="false"){ } else if (this.serviceTime[index].ym === "false") {
this.hsstr = this.serviceTime[index].str this.hsstr = this.serviceTime[index].str
} }
// //
console.log('Selected hs:', this.hsstr); console.log('this.serviceTimesss:', this.serviceTime[index].ym);
}, },
}, },
}; };
@ -462,6 +604,7 @@
font-weight: bold; font-weight: bold;
margin-bottom: 10px; margin-bottom: 10px;
} }
.dropdown-icon { .dropdown-icon {
width: 12px; width: 12px;
height: 12px; height: 12px;
@ -513,6 +656,7 @@
margin-right: 15px; margin-right: 15px;
cursor: pointer; cursor: pointer;
} }
.date-itemym { .date-itemym {
/* display: flex; */ /* display: flex; */
align-items: center; align-items: center;
@ -524,6 +668,7 @@
margin-right: 15px; margin-right: 15px;
cursor: pointer; cursor: pointer;
} }
.date-item.active { .date-item.active {
background-color: #ff5541; background-color: #ff5541;
color: #fff; color: #fff;
@ -550,7 +695,8 @@
border-radius: 10px; border-radius: 10px;
margin-bottom: 10px; margin-bottom: 10px;
} }
.doctor-cards {
.doctor-cards {
/* display: flex; */ /* display: flex; */
align-items: center; align-items: center;
padding: 10px; padding: 10px;
@ -560,27 +706,31 @@
border-radius: 10px; border-radius: 10px;
margin-bottom: 10px; margin-bottom: 10px;
} }
.doctor-avatar { .doctor-avatar {
width: 100px; width: 100px;
height: 70px; height: 70px;
border-radius: 50%; border-radius: 50%;
margin-right: 10px; margin-right: 10px;
} }
.doctor-avatars{
display: flex; .doctor-avatars {
/* height: 70px; */ display: flex;
/* border-radius: 50%; */ /* height: 70px; */
/* margin-right: 10px; */ /* border-radius: 50%; */
} /* margin-right: 10px; */
}
.doctor-info { .doctor-info {
display: flex; display: flex;
flex-grow: 1; flex-grow: 1;
} }
.brandr-info { .brandr-info {
/* display: flex; */ /* display: flex; */
flex-grow: 1; flex-grow: 1;
} }
.doctor-name { .doctor-name {
@ -594,25 +744,29 @@
.doctor-specialty { .doctor-specialty {
font-size: 14px; font-size: 14px;
color: #ff5541; color: #ff5541;
} }
.doctor-names {
.doctor-names {
font-size: 14px; font-size: 14px;
/* color: #ff5541; */ /* color: #ff5541; */
margin-bottom: 5px; margin-bottom: 5px;
} }
.ygcontent{
font-size: 16px; .ygcontent {
font-weight: 700; font-size: 16px;
} font-weight: 700;
}
.doctor-specialtys { .doctor-specialtys {
/* text-indent: 20px; */ /* text-indent: 20px; */
white-space: pre-wrap; white-space: pre-wrap;
font-size: 14px; font-size: 14px;
/* color: #ff5541; */ /* color: #ff5541; */
} }
.doctor-checkbox { .doctor-checkbox {
margin-left: auto; margin-left: auto;
} }
@ -670,4 +824,4 @@
.radiodate { .radiodate {
display: none; display: none;
} }
</style> </style>

View File

@ -1,5 +1,5 @@
<template> <template>
<s-layout title="会员中心" tabbar=" "> <s-layout title="会员中心">
<view class="memberVip"> <view class="memberVip">
<!-- 基本信息 --> <!-- 基本信息 -->
@ -20,29 +20,13 @@
<!-- {{ userInfo.level.name }} --> <!-- {{ userInfo.level.name }} -->
白金会员 白金会员
</view> </view>
</view> </view>
</view> </view>
</view> </view>
<!-- 会员卡信息 --> <!-- 会员卡信息 -->
<swiper class="swiper" circular :indicator-dots="indicatorDots" :autoplay="autoplay" <zmxy-slideshow :items="levelList" :autoplay="false"></zmxy-slideshow>
:interval="interval" :duration="duration">
<swiper-item>
<view class="swiper-item uni-bg-red">
<image class="new-img"
src="https://zysc.fjptzykj.com:3000/shangcheng/94eaaae47569b35cd1f06f2507b0b56f7b597b82b359ee9fb90fd9db630e64cc.png">
</image>
</view>
</swiper-item>
<swiper-item>
<view class="swiper-item uni-bg-green">
<image class="new-img"
src="https://zysc.fjptzykj.com:3000/shangcheng/6cb1566a669a2d0a0d043df9d69341fbb9e386fd08fea0bb5288e3baf8543553.png">
</image>
</view>
</swiper-item>
</swiper>
<!-- TODO --> <!-- TODO -->
<view class="experience"> <view class="experience">
<view class="title">当前经验值</view> <view class="title">当前经验值</view>
@ -137,7 +121,7 @@
<view class="info line1">每日签到可获得经验值</view> <view class="info line1">每日签到可获得经验值</view>
</view> </view>
</view> </view>
<navigator url='/pages/users/user_sgin/index' class="button" hover-class="none">去获取 <navigator url='/pages/app/sign' class="button" hover-class="none">去获取
</navigator> </navigator>
</view> </view>
<view class="item acea-row row-between-wrapper"> <view class="item acea-row row-between-wrapper">
@ -151,8 +135,8 @@
<view class="info line1">购买商品可获得对应是经验值</view> <view class="info line1">购买商品可获得对应是经验值</view>
</view> </view>
</view> </view>
<navigator url="/pages/goods_cate/goods_cate" class="button" hover-class="none" <navigator url="/pages/index/category" class="button" hover-class="none"
open-type='switchTab'>去获取</navigator> >去获取</navigator>
</view> </view>
</view> </view>
</view> </view>
@ -192,103 +176,94 @@
</s-layout> </s-layout>
</template> </template>
<script> <script setup>
// import home from './home/index.vue'; import {
// import { ref,
// mapGetters reactive,
// } from "vuex"; onMounted
// import * as LevelApi from '@/sheep/api/member/level'; } from 'vue';
// // import dayjs from './dayjs/dayjs.min.js'; import home from './home/index.vue';
// export default { import {
// components: { mapGetters
// home, } from "vuex";
// }, import getExper from '@/sheep/api/member/level';
// computed: mapGetters(['userInfo']), // import dayjs from './dayjs/dayjs.min.js';
// data() {
// return {
// levelInfo: '',
// levelList: [], //
// current: 0, //
// widthLen: 0,
// loading: false, // const store = useStore();
// loadend: false, // const userInfo = computed(() => store.state.userInfo);
// loadTitle: '', //
// page: 1,
// limit: 20,
// expList: []
// };
// },
// onLoad() {
// this.getInfo();
// this.getlevelList();
// },
// methods: {
// /**
// *
// */
// getInfo: function() {
// LevelApi.getLevelList().then(res => {
// let levelList = res.data;
// this.levelList = levelList;
// // const levelList = ref([]); //
// let list = [] const current = ref(0); //
// levelList.map((item, index) => { const widthLen = ref(0);
// if (item.experience <= this.userInfo.experience) { const loading = ref(false);
// list.push(item.experience) const loadend = ref(false);
// } const loadTitle = ref('加载更多'); //
// }) const page = ref(1);
// const maxn = Math.max.apply(null, list); const limit = ref(20);
// this.current = maxn; const expList = ref([]);
// const items = ref([{
// url: 'https://zysc.fjptzykj.com:3000/shangcheng/94eaaae47569b35cd1f06f2507b0b56f7b597b82b359ee9fb90fd9db630e64cc.png',
// // len // }, {
// const levelListLen = levelList[list.length] ? levelList[list.length] : levelList[list // url: 'https://zysc.fjptzykj.com:3000/shangcheng/6cb1566a669a2d0a0d043df9d69341fbb9e386fd08fea0bb5288e3baf8543553.png',
// .length - 1];
// // 0
// const divisor = levelListLen.experience - maxn ? levelListLen.experience - maxn : 1;
// //
// const per = (this.userInfo.experience - maxn) / divisor / levelList.length;
// this.widthLen = ((list.length - 0.5) / (levelList.length)) * 100 + per * 100
// }).catch(res => {
// return this.$util.Tips({
// title: res
// });
// })
// },
// /**
// *
// */
// getlevelList: function() {
// if (this.loadend || this.loading) {
// return false;
// }
// LevelApi.getExperienceRecordPage({
// pageNo: this.page,
// pageSize: this.limit
// }).then(res => {
// const list = res.data.list;
// const loadend = list.length < this.limit;
// let expList = this.$util.SplitArray(list, this.expList);
// this.$set(this, 'expList', expList);
// this.loadend = loadend;
// this.loadTitle = loadend ? '线' : '';
// this.page = this.page + 1;
// this.loading = false;
// }).catch(err => {
// this.loading = false;
// this.loadTitle = '';
// });
// },
// formatDate: function(date) { // }]);
// // return dayjs(date).format("YYYY-MM-DD HH:mm:ss"); const items = ref([]);
// }
// }, const getInfo = async () => {
// onReachBottom: function() { try {
// this.getlevelList(); const res = await getExper.getLevelList();
// } levelList.value = res.data;
// } // levelList.value = res.data.map(member => member.backgroundUrl);
//
let list = [];
levelList.value.forEach((item) => {
if (item.experience <= userInfo.value.experience) {
list.push(item.experience);
}
});
const maxn = Math.max(...list);
current.value = maxn;
// len
const levelListLen = list.length > 0 ? levelList.value[list.length - 1] : levelList.value[0];
// 0
const divisor = levelListLen.experience - maxn || 1;
//
const per = (userInfo.value.experience - maxn) / divisor / levelList.value.length;
widthLen.value = ((list.length - 0.5) / levelList.value.length) * 100 + per * 100;
} catch (res) {
//
}
};
const getlevelList = async () => {
if (loadend.value || loading.value) {
return false;
}
loading.value = true;
try {
const res = await LevelApi.getExperienceRecordPage({
pageNo: page.value,
pageSize: limit.value
});
const list = res.data.list;
const loadendNew = list.length < limit.value;
expList.value = [...expList.value, ...list];
loadend.value = loadendNew;
loadTitle.value = loadendNew ? '我也是有底线的' : '加载更多';
page.value++;
loading.value = false;
} catch (err) {
loading.value = false;
loadTitle.value = '加载更多';
}
};
onMounted(() => {
getInfo();
getlevelList();
});
</script> </script>
<style lang="scss"> <style lang="scss">
.swiper { .swiper {
@ -297,9 +272,9 @@
.new-img { .new-img {
width: 90%; width: 90%;
height:150px; height: 150px;
display:block; display: block;
margin:0 auto; margin: 0 auto;
} }
} }

View File

@ -4,14 +4,14 @@ const getExper = {
// 获得会员等级列表 // 获得会员等级列表
getLevelList: () => { getLevelList: () => {
return request({ return request({
url: '/app-api/member/level/list', url: '/member/level/list',
method: 'GET', method: 'GET',
}); });
}, },
// 获得会员经验记录分页 // 获得会员经验记录分页
getExperienceRecordPage: () => { getExperienceRecordPage: () => {
return request({ return request({
url: '/app-api/member/experience-record/page', url: '/member/experience-record/page',
method: 'GET', method: 'GET',
}); });
}, },

View File

@ -1,41 +1,75 @@
import request from '@/sheep/request'; import request from '@/sheep/request';
const SpuApi = { const SpuApi = {
// 获得商品 SPU 列表 // 获得商品促销列表
getSpuListByIds: (ids) => { getSpusales: (ids) => {
return request({ return request({
url: '/product/spu/list-by-ids', url:'/product/spu/get-recommend-page',
method: 'GET', method: 'GET',
params: { ids }, params: {
custom: { pageNo:1,
showLoading: false, pageSize:10,
showError: false, recommendBenefit:1
}, },
}); custom: {
}, showLoading: false,
// 获得商品 SPU 分页 showError: false,
getSpuPage: (params) => { },
return request({ });
url: '/product/spu/page', },
method: 'GET', // 获得商品 SPU 列表
params, getSpuListByIds: (ids) => {
custom: { return request({
showLoading: false, url: '/product/spu/list-by-ids',
showError: false, method: 'GET',
}, params: {
}); ids
}, },
// 查询商品 custom: {
getSpuDetail: (id) => { showLoading: false,
return request({ showError: false,
url: '/product/spu/get-detail', },
method: 'GET', });
params: { id }, },
custom: { // 获得商品 SPU 分页
showLoading: false, getSpuPage: (params) => {
showError: false, return request({
}, url: '/product/spu/page',
}); method: 'GET',
}, params,
custom: {
showLoading: false,
showError: false,
},
});
},
// 查询商品
getSpuDetail: (id) => {
return request({
url: '/product/spu/get-detail',
method: 'GET',
params: {
id
},
custom: {
showLoading: false,
showError: false,
},
});
},
//获取拼团列表接口
getSpulist: (id) => {
return request({
url: '/promotion/combination-activity/list',
method: 'GET',
params: {
count:3
},
custom: {
showLoading: false,
showError: false,
},
});
},
}; };
export default SpuApi; export default SpuApi;

View File

@ -2,10 +2,11 @@
<template> <template>
<scroll-view class="scroll-box" scroll-x scroll-anchoring> <scroll-view class="scroll-box" scroll-x scroll-anchoring>
<view class="coupon-box ss-flex"> <view class="coupon-box ss-flex">
<!-- couponList -->
<view <view
class="coupon-item" class="coupon-item new-class"
:style="[couponBg, { marginLeft: `${data.space}px` }]" :style="[couponBg, { marginLeft: `${data.space}px` }]"
v-for="(item, index) in couponList" v-for="(item, index) in 3"
:key="index" :key="index"
> >
<su-coupon <su-coupon
@ -126,6 +127,10 @@
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.new-class{
margin: 0 10px !important;
margin-right: 2px !important;
}
.card-btn { .card-btn {
width: 140rpx; width: 140rpx;
height: 50rpx; height: 50rpx;
@ -145,8 +150,8 @@
} }
} }
.coupon-item { .coupon-item {
&:nth-of-type(1) { // &:nth-of-type(1) {
margin-left: 0 !important; // margin-left: 0 !important;
} // }
} }
</style> </style>

View File

@ -1,154 +1,164 @@
<!-- 装修组件 - 拼团 --> <!-- 装修组件 - 拼团 -->
<template> <template>
<view> <view>
<view <!-- <view v-if="layoutType === 'threeCol'" class="goods-sm-box ss-flex ss-flex-wrap"
v-if="layoutType === 'threeCol'" :style="[{ margin: '-' + data.space + 'rpx' }]">
class="goods-sm-box ss-flex ss-flex-wrap" <view v-for="product in productList" :key="product.id" class="goods-card-box" :style="[
:style="[{ margin: '-' + data.space + 'rpx' }]"
>
<view
v-for="product in productList"
:key="product.id"
class="goods-card-box"
:style="[
{ {
padding: data.space + 'rpx', padding: data.space + 'rpx',
}, },
]" ]">
> <s-goods-column class="goods-card" size="sm" :goodsFields="data.fields" :tagStyle="tagStyle"
<s-goods-column :data="product" :titleColor="data.fields.name?.color" :topRadius="data.borderRadiusTop"
class="goods-card" :bottomRadius="data.borderRadiusBottom" @click="
size="sm"
:goodsFields="data.fields"
:tagStyle="tagStyle"
:data="product"
:titleColor="data.fields.name?.color"
:topRadius="data.borderRadiusTop"
:bottomRadius="data.borderRadiusBottom"
@click="
sheep.$router.go('/pages/goods/groupon', { sheep.$router.go('/pages/goods/groupon', {
id: props.data.activityId, id: props.data.activityId,
}) })
" "></s-goods-column>
></s-goods-column> </view>
</view> </view> -->
</view> <!-- 样式2 一行一个 图片左 文案右 -->
<!-- 样式2 一行一个 图片左 文案右 --> <!-- <view class="goods-box" v-if="layoutType === 'oneCol'">
<view class="goods-box" v-if="layoutType === 'oneCol'"> <view class="goods-list" v-for="(product, index) in productList" :key="index"
<view :style="[{ marginBottom: space + 'px' }]">
class="goods-list" <s-goods-column class="goods-card" size="lg" :goodsFields="data.fields" :tagStyle="tagStyle"
v-for="(product, index) in productList" :data="product" :titleColor="data.fields.name?.color"
:key="index" :subTitleColor="data.fields.introduction?.color" :topRadius="data.borderRadiusTop"
:style="[{ marginBottom: space + 'px' }]" :bottomRadius="data.borderRadiusBottom" @click="
>
<s-goods-column
class="goods-card"
size="lg"
:goodsFields="data.fields"
:tagStyle="tagStyle"
:data="product"
:titleColor="data.fields.name?.color"
:subTitleColor="data.fields.introduction?.color"
:topRadius="data.borderRadiusTop"
:bottomRadius="data.borderRadiusBottom"
@click="
sheep.$router.go('/pages/goods/groupon', { sheep.$router.go('/pages/goods/groupon', {
id: props.data.activityId, id: props.data.activityId,
}) })
" ">
> <template v-slot:cart>
<template v-slot:cart> <button class="ss-reset-button cart-btn" :style="[buyStyle]">
<button class="ss-reset-button cart-btn" :style="[buyStyle]"> {{ btnBuy?.type === 'text' ? btnBuy.text : '' }}
{{ btnBuy?.type === 'text' ? btnBuy.text : '' }} </button>
</button> </template>
</template> </s-goods-column>
</s-goods-column> </view>
</view> </view> -->
</view>
</view> <view v-if="'threeCol' === 'threeCol'" class="goods-sm-box ss-flex ss-flex-wrap"
:style="[{ margin: '-' + data.space + 'rpx' }]">
<!-- productList -->
<view v-for="product in 3" :key="product.id" class="goods-card-box" :style="[
{
padding: data.space + 'rpx',
},
]">
<s-goods-column class="goods-card" size="sm" :goodsFields="data.fields" :tagStyle="tagStyle"
:data="product" :titleColor="data.fields.name?.color" :topRadius="data.borderRadiusTop"
:bottomRadius="data.borderRadiusBottom" @click="
sheep.$router.go('/pages/goods/groupon', {
id: props.data.activityId,
})
"></s-goods-column>
</view>
</view>
</view>
</template> </template>
<script setup> <script setup>
/** /**
* 拼团 * 拼团
*/ */
import { computed, onMounted, ref } from 'vue'; import {
import sheep from '@/sheep'; computed,
import SpuApi from '@/sheep/api/product/spu'; onMounted,
import CombinationApi from '@/sheep/api/promotion/combination'; ref
} from 'vue';
import sheep from '@/sheep';
import SpuApi from '@/sheep/api/product/spu';
import CombinationApi from '@/sheep/api/promotion/combination';
// //
const props = defineProps({ const props = defineProps({
data: { data: {
type: Object, type: Object,
default() {}, default () {},
}, },
styles: { styles: {
type: Object, type: Object,
default() {}, default () {},
}, },
}); });
let { layoutType, tagStyle, btnBuy, space } = props.data; let {
let { marginLeft, marginRight } = props.styles; layoutType,
tagStyle,
btnBuy,
space
} = props.data;
let {
marginLeft,
marginRight
} = props.styles;
// //
const buyStyle = computed(() => { const buyStyle = computed(() => {
let btnBuy = props.data.btnBuy; let btnBuy = props.data.btnBuy;
if (btnBuy?.type === 'text') { if (btnBuy?.type === 'text') {
return { return {
background: `linear-gradient(to right, ${btnBuy.bgBeginColor}, ${btnBuy.bgEndColor})`, background: `linear-gradient(to right, ${btnBuy.bgBeginColor}, ${btnBuy.bgEndColor})`,
}; };
} }
if (btnBuy?.type === 'img') { if (btnBuy?.type === 'img') {
return { return {
width: '54rpx', width: '54rpx',
height: '54rpx', height: '54rpx',
background: `url(${sheep.$url.cdn(btnBuy.imgUrl)}) no-repeat`, background: `url(${sheep.$url.cdn(btnBuy.imgUrl)}) no-repeat`,
backgroundSize: '100% 100%', backgroundSize: '100% 100%',
}; };
} }
}); });
const productList = ref([]); const productList = ref([]);
onMounted(async () => { onMounted(async () => {
// todo@owen Yudao // todo@owen Yudao
const { data: activity } = await CombinationApi.getCombinationActivity(props.data.activityId); const {
const { data: spu } = await SpuApi.getSpuDetail(activity.spuId); data: activity
productList.value = [spu]; } = await CombinationApi.getCombinationActivity(props.data.activityId);
}); const ss= await SpuApi.getSpulist();
console.log(ss,"getSpuListByIds")
productList.value = spu;
});
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.goods-list { .goods-list {
position: relative; position: relative;
.cart-btn {
position: absolute; .cart-btn {
bottom: 10rpx; position: absolute;
right: 20rpx; bottom: 10rpx;
z-index: 11; right: 20rpx;
height: 50rpx; z-index: 11;
line-height: 50rpx; height: 50rpx;
padding: 0 20rpx; line-height: 50rpx;
border-radius: 25rpx; padding: 0 20rpx;
font-size: 24rpx; border-radius: 25rpx;
color: #fff; font-size: 24rpx;
} color: #fff;
} }
.goods-list { }
&:nth-last-of-type(1) {
margin-bottom: 0 !important; .goods-list {
} &:nth-last-of-type(1) {
} margin-bottom: 0 !important;
.goods-sm-box { }
margin: 0 auto; }
box-sizing: border-box;
.goods-card-box { .goods-sm-box {
flex-shrink: 0; margin: 0 auto;
overflow: hidden; box-sizing: border-box;
width: 33.3%;
box-sizing: border-box; .goods-card-box {
} flex-shrink: 0;
} overflow: hidden;
</style> width: 33.3%;
box-sizing: border-box;
}
}
</style>

View File

@ -1,7 +1,7 @@
<template> <template>
<view class="ui-coupon-wrap"> <view class="ui-coupon-wrap">
<!-- xs: 一行三个竖向 --> <!-- xs: 一行三个竖向 -->
<view <!-- <view
v-if="props.size === 'xs'" v-if="props.size === 'xs'"
class="xs-coupon-card ss-flex ss-flex-col ss-row-between" class="xs-coupon-card ss-flex ss-flex-col ss-row-between"
:style="[cardStyle]" :style="[cardStyle]"
@ -23,10 +23,10 @@
<button class="ss-reset-button card-btn">{{ state.stateMap[props.state] }}</button> <button class="ss-reset-button card-btn">{{ state.stateMap[props.state] }}</button>
</slot> </slot>
</view> </view>
</view> </view> -->
<!-- md: 一行两个横向 --> <!-- md: 一行两个横向 -->
<view <!-- <view
v-if="props.size === 'md'" v-if="props.size === 'md'"
class="md-coupon-card ss-flex ss-row-between" class="md-coupon-card ss-flex ss-row-between"
:style="[cardStyle]" :style="[cardStyle]"
@ -53,10 +53,10 @@
</button> </button>
</slot> </slot>
</view> </view>
</view> </view> -->
<!-- lg: 一行一个横向 --> <!-- lg: 一行一个横向 -->
<view <!-- <view
v-if="props.size === 'lg'" v-if="props.size === 'lg'"
class="lg-coupon-card ss-flex ss-row-between" class="lg-coupon-card ss-flex ss-row-between"
:style="[cardStyle]" :style="[cardStyle]"
@ -84,7 +84,35 @@
</slot> </slot>
<view class="surplus-text ss-m-t-24" v-if="props.surplus">仅剩{{ props.surplus }}</view> <view class="surplus-text ss-m-t-24" v-if="props.surplus">仅剩{{ props.surplus }}</view>
</view> </view>
</view> </view> -->
<view
v-if="'md' === 'md'"
class=" md-coupon-card ss-flex ss-row-between"
:style="[cardStyle]"
@tap="
sheep.$router.go('/pages/coupon/detail', {
id: couponId,
})
"
>
<view class="card-left ss-flex ss-flex-col ss-row-between ss-col-top ss-m-l-40">
<view class="face-value-box ss-flex ss-col-bottom ss-m-t-28">
<view class="value-text ss-m-r-4">{{ type === 'reduce' ? value : Number(value) }}</view>
<view class="value-unit">{{ type === 'reduce' ? '元' : '折' }}</view>
</view>
<view class="ss-m-b-28">
<view class="title-text ss-m-b-10">{{ props.title }}</view>
<view class="surplus-text" v-if="props.surplus">仅剩{{ props.surplus }}</view>
</view>
</view>
<view class="card-right ss-flex ss-row-center">
<slot name="btn">
<button class="ss-reset-button card-btn ss-flex ss-row-center ss-col-center">
<view class="btn-text">{{ state.stateMap[props.state] }}</view>
</button>
</slot>
</view>
</view>
</view> </view>
</template> </template>
@ -175,6 +203,7 @@
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
// xs // xs
.xs-coupon-card { .xs-coupon-card {
width: 227rpx; width: 227rpx;

View File

@ -0,0 +1,14 @@
## 1.0.32023-11-25
修改:点击事件的返回参数
this.$emit('clickItem',item,index,this.items)
## 1.0.22023-11-18
修复:高度设置失效
## 1.0.12023-11-18
修复:在 vue2 中 class 调用方法不支持传参问题
## 1.0.02023-10-18
# 创建项目:个性化幻灯片
1. 支持放大动画;
2. 幻灯片点击事件;
3. 幻灯片动态定义;
4. 幻灯片数据多态,对象数组或字符串数组。

View File

@ -0,0 +1,147 @@
<template>
<swiper class="zmxy-slideshow swiper" circular :autoplay="autoplay" :vertical="vertical" :previous-margin="margin"
:next-margin="margin" :current="current" :interval="interval" :easing-function="easingFunction"
:style="'height:' + height" @change="swiperChange">
<swiper-item v-for="(item,index) in items" :key="index">
<view :class="'swiper-item '+(index == current ?'active':'')" @click="clickItem(item)">
<view class="yi sd">VIP{{item.level}}</view>
<view class="er sd">{{item.name}}</view>
<view class="san sd">再获得 {{item.experience}} 成长值升级为该等级</view>
<image class="swiper-item-image" :src="item.backgroundUrl||item" mode="aspectFill"></image>
<view v-if="item.title" class="swiper-item-title">
{{ item.title }}
</view>
</view>
</swiper-item>
</swiper>
</template>
<script>
export default {
name: 'zmxy-slideshow', //
data() {
return {
current: 0,
}
},
props: {
items: {
type: [Array, Object],
default: () => {
return [];
}
},
interval: {
type: [Number, String],
default: 5000
},
autoplay: {
type: Boolean,
default: true
},
vertical: {
type: Boolean,
default: false
},
margin: {
type: String,
default: '60rpx'
},
height: {
type: String,
default: '300rpx'
},
easingFunction: {
type: String,
default: 'easeInOutCubic'
},
},
mounted(){
console.log(this.items,"items")
// this.items = this.items.map(member => member.backgroundUrl)
},
methods: {
swiperChange(e) {
this.current = e.detail.current
},
clickItem(item) {
this.$emit('clickItem', item)
},
}
}
</script>
<style lang="scss">
.sd{
color:white;
position: absolute;
z-index: 22;
}
.yi{
top: 25px;
font-size: 26px;
left: 12px;
font-weight: 600;
}
.er{
top: 60px;
font-size: 13px;
left: 12px;
/* font-weight: 600;*/
}
.san{
bottom: 10px;
font-size: 13px;
left: 12px;
/* font-weight: 600;*/
}
.zmxy-slideshow {
width: 100%;
.swiper-item {
width: 100%;
height: 100%;
overflow: hidden;
border-radius: 5px;
position: relative;
display: flex;
align-items: center;
transform: scale(0.9, 0.80);
transition: all .6s;
.swiper-item-image {
width: 100%;
height: 100%;
border-radius: 6rpx;
}
.swiper-item-title {
position: absolute;
bottom: 0;
left: 0;
right: 0;
color: rgba(255, 255, 255, 0);
background: rgba(0, 0, 0, 0);
padding: 10rpx;
transition: color .6s, background .6s;
width: 100%;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
&.active {
transform: scale(1, 1);
.swiper-item-image {}
.swiper-item-title {
color: rgba(255, 255, 255, 1);
background: rgba(0, 0, 0, 0.5);
}
}
}
}
</style>

View File

@ -0,0 +1,85 @@
{
"id": "zmxy-slideshow",
"displayName": "zmxy-slideshow-个性化幻灯片",
"version": "1.0.3",
"description": "zmxy-slideshow-个性化幻灯片,常用于轮播图,广告播放",
"keywords": [
"幻灯片",
"轮播图",
"广告横幅",
"渐变",
"放大"
],
"repository": "",
"engines": {
"HBuilderX": "^3.8.0"
},
"dcloudext": {
"type": "component-vue",
"sale": {
"regular": {
"price": "0.00"
},
"sourcecode": {
"price": "0.00"
}
},
"contact": {
"qq": ""
},
"declaration": {
"ads": "无",
"data": "无",
"permissions": "无"
},
"npmurl": ""
},
"uni_modules": {
"dependencies": [],
"encrypt": [],
"platforms": {
"cloud": {
"tcb": "y",
"aliyun": "y"
},
"client": {
"Vue": {
"vue2": "y",
"vue3": "y"
},
"App": {
"app-vue": "y",
"app-nvue": "n"
},
"H5-mobile": {
"Safari": "y",
"Android Browser": "y",
"微信浏览器(Android)": "y",
"QQ浏览器(Android)": "y"
},
"H5-pc": {
"Chrome": "y",
"IE": "y",
"Edge": "y",
"Firefox": "y",
"Safari": "y"
},
"小程序": {
"微信": "y",
"阿里": "y",
"百度": "y",
"字节跳动": "n",
"QQ": "y",
"钉钉": "y",
"快手": "y",
"飞书": "n",
"京东": "n"
},
"快应用": {
"华为": "u",
"联盟": "u"
}
}
}
}
}

View File

@ -0,0 +1,65 @@
# zmxy-slideshow 幻灯片
> 该组件是对原生
> [swiper](https://uniapp.dcloud.net.cn/component/swiper.html)
> 进行封装,继承了原组件部分属性及功能。
## 属性说明
| 属性名 | 类型 | 默认值 | 说明 | 平台差异说明 |
|:-------------------:|:-----------:|:--------:|:----------------------------------------------------------------------------------------------------:|:------------------------------------------------:|
| autoplay | Boolean | true | 是否自动切换 | |
| interval | Number | 5000 | 自动切换时间间隔 | |
| vertical | Boolean | false | 滑动方向是否为纵向 | |
| margin | String | 60rpx | 前后边距,接受 px 和 rpx 值 | app-nvue、抖音小程序、飞书小程序不支持 |
| easing-function | String | default | 指定 swiper 切换缓动动画类型有效值default、linear、easeInCubic、easeOutCubic、easeInOutCubic | 微信小程序、快手小程序、京东小程序 |
| height | String | 300rpx | 组件整体高度,接受 px 和 rpx 值 | |
| items | Array | [] | 图片地址、标题、链接等数据组成的对象数组([{url,title,link,...},{url,title,link,...},...]),也支持字符串数组([url1,url2,url3,...] | |
| @clickItem | EventHandle | | 点击幻灯片触发 clickItem 事件item = {url,title,link,...} 或者 item = url |
### easing-function 属性
| 值 | 说明 |
|:---------------:|:-------:|
| default | 默认缓动函数 |
| linear | 线性动画 |
| easeInCubic | 缓入动画 |
| easeOutCubic | 缓出动画 |
| easeInOutCubic | 缓入缓出动画 |
### 案例代码
```vue
# 基础使用
<zmxy-slideshow :items="items"></zmxy-slideshow>
# 字符串数组,线性动画
<zmxy-slideshow :items="items2" easing-function="linear"></zmxy-slideshow>
```
```javascript
export default {
data() {
return {
items: [{
url: 'https://web-assets.dcloud.net.cn/unidoc/zh/shuijiao.jpg',
title: '内容标题',
}, {
url: 'https://web-assets.dcloud.net.cn/unidoc/zh/shuijiao.jpg',
title: '内容标题',
}, {
url: 'https://web-assets.dcloud.net.cn/unidoc/zh/shuijiao.jpg',
title: '内容标题',
}, ],
items2: [
'https://web-assets.dcloud.net.cn/unidoc/zh/shuijiao.jpg',
'https://web-assets.dcloud.net.cn/unidoc/zh/shuijiao.jpg',
'https://web-assets.dcloud.net.cn/unidoc/zh/shuijiao.jpg',
],
};
},
methods: {
clickItem(item) {
console.log(item);
}
}
}
```