优化3333333 #5

Merged
root merged 1 commits from Branch_ccc into master 2024-10-11 16:19:41 +08:00
27 changed files with 2437 additions and 1836 deletions
Showing only changes of commit da534c7e55 - Show all commits

View File

@ -1,17 +1,13 @@
<!-- 拼团活动列表 -->
<template>
<s-layout navbar="inner" :bgStyle="{ color: '#FE832A' }">
<view class="page-bg" :style="[{ marginTop: '-' + Number(statusBarHeight + 88) + 'rpx' }]" />
<s-layout title="拼团列表" navbar="normal" :bgStyle="{ color: '#FE832A',backgroundColor: 'rgba(233,51,35)' }">
<!-- <view class="page-bg" :style="[{ marginTop: '-' + Number(statusBarHeight + 88) + 'rpx' }]" /> -->
<view class="list-content">
<!-- 参团会员统计 -->
<view class="content-header ss-flex-col ss-col-center ss-row-center">
<view class="content-header-title ss-flex ss-row-center">
<view
v-for="(item, index) in state.summaryData.avatars"
:key="index"
class="picture"
:style="index === 6 ? 'position: relative' : 'position: static'"
>
<view v-for="(item, index) in state.summaryData.avatars" :key="index" class="picture"
:style="index === 6 ? 'position: relative' : 'position: static'">
<span class="avatar" :style="`background-image: url(${item})`" />
<span v-if="index === 6 && state.summaryData.avatars.length > 3" class="mengceng">
<i>···</i>
@ -20,45 +16,38 @@
<text class="pic_count">{{ state.summaryData.userCount || 0 }}人参与</text>
</view>
</view>
<scroll-view
class="scroll-box"
:style="{ height: pageHeight + 'rpx' }"
scroll-y="true"
:scroll-with-animation="false"
:enable-back-to-top="true"
>
<scroll-view class="scroll-box" :style="{ height: pageHeight + 'rpx' }" scroll-y="true"
:scroll-with-animation="false" :enable-back-to-top="true">
<view class="goods-box ss-m-b-20" v-for="item in state.pagination.list" :key="item.id">
<s-goods-column
class=""
size="lg"
:data="item"
:grouponTag="true"
@click="sheep.$router.go('/pages/goods/groupon', { id: item.id })"
>
<s-goods-column class="" size="lg" :data="item" :grouponTag="true"
@click="sheep.$router.go('/pages/goods/groupon', { id: item.id })">
<template v-slot:cart>
<button class="ss-reset-button cart-btn">去拼团</button>
</template>
</s-goods-column>
</view>
<uni-load-more
v-if="state.pagination.total > 0"
:status="state.loadStatus"
:content-text="{
<uni-load-more color="white" v-if="state.pagination.total > 0" :status="state.loadStatus" :content-text="{
contentdown: '上拉加载更多',
}"
@tap="loadMore"
/>
}" @tap="loadMore" />
</scroll-view>
</view>
</s-layout>
</template>
<script setup>
import { reactive } from 'vue';
import { onLoad, onReachBottom } from '@dcloudio/uni-app';
import {
reactive
} from 'vue';
import {
onLoad,
onReachBottom
} from '@dcloudio/uni-app';
import sheep from '@/sheep';
import CombinationApi from '@/sheep/api/promotion/combination';
const { safeAreaInsets, safeArea } = sheep.$platform.device;
const {
safeAreaInsets,
safeArea
} = sheep.$platform.device;
const sysNavBar = sheep.$platform.navbar;
const statusBarHeight = sheep.$platform.device.statusBarHeight * 2;
const pageHeight =
@ -78,19 +67,26 @@
//
const getSummary = async () => {
const { data } = await CombinationApi.getCombinationRecordSummary();
const {
data
} = await CombinationApi.getCombinationRecordSummary();
state.summaryData = data;
};
//
async function getList() {
state.loadStatus = 'loading';
const { data } = await CombinationApi.getCombinationActivityPage({
const {
data
} = await CombinationApi.getCombinationActivityPage({
pageNo: state.pagination.pageNo,
pageSize: state.pagination.pageSize,
});
data.list.forEach((activity) => {
state.pagination.list.push({ ...activity, price: activity.combinationPrice });
state.pagination.list.push({
...activity,
price: activity.combinationPrice
});
});
state.pagination.total = data.total;
state.loadStatus = state.pagination.list.length < state.pagination.total ? 'more' : 'noMore';
@ -122,17 +118,44 @@
background: url('https://zysc.fjptzykj.com:3000/shangcheng/fea9ad54f32d4705a633874efd534e70e507030ea5a7604b0110fdf7292f1f4d.png');
background-size: 100% 100%;
}
.list-content {
position: relative;
z-index: 3;
margin: -190rpx 20rpx 0 20rpx;
background: #fff;
margin: 0 20rpx 0 20rpx;
// background: #fff;
border-radius: 20rpx 20rpx 0 0;
.content-header {
width: 100%;
border-radius: 20rpx 20rpx 0 0;
height: 100rpx;
background: linear-gradient(180deg, #fff4f7, #ffe4d1);
height: 50rpx;
margin: 10px 0;
position: relative;
// background: linear-gradient(180deg, #fff4f7, #ffe4d1);
&::after {
content: '';
position: absolute;
right: 15%;
height: 1px;
width: 50px;
background: white;
top: 50%;
transform: translateY(-50%);
}
&::before {
content: '';
position: absolute;
left: 15%;
height: 1px;
width: 50px;
background: white;
top: 50%;
transform: translateY(-50%);
}
.content-header-title {
width: 100%;
font-size: 30rpx;
@ -140,6 +163,7 @@
color: #ff2923;
line-height: 30rpx;
position: relative;
.more {
position: absolute;
right: 30rpx;
@ -195,6 +219,7 @@
left: -2rpx;
color: #fff;
top: 2rpx;
i {
font-style: normal;
font-size: 20rpx;
@ -202,12 +227,15 @@
}
}
}
.scroll-box {
margin-top: 13px;
// margin-top: 13px;
height: 900rpx;
.goods-box {
position: relative;
padding: 0 10px;
.cart-btn {
position: absolute;
bottom: 10rpx;

View File

@ -1,11 +1,11 @@
<!-- 秒杀活动列表 -->
<template>
<s-layout navbar="inner" :bgStyle="{ color: 'rgb(245,28,19)' }">
<s-layout title="秒杀列表" navbar="normal" :bgStyle="{ color: 'rgb(245,28,19)' }">
<!--顶部背景图-->
<view
<!-- <view
class="page-bg"
:style="[{ marginTop: '-' + Number(statusBarHeight + 88) + 'rpx' }]"
></view>
></view> -->
<!-- 时间段轮播图 -->
<view class="header" v-if="activeTimeConfig?.sliderPicUrls?.length > 0">
<swiper
@ -45,7 +45,7 @@
:key="index"
:class="['item', { active: activeTimeIndex === index }]"
:id="`timeItem${index}`"
@tap="handleChangeTimeConfig(index)"
@tap="handleChangeTimeConfig(index,config.id)"
>
<!-- 活动起始时间 -->
<view class="time">{{ config.startTime }}</view>
@ -58,7 +58,7 @@
<!-- 内容区 -->
<view class="list-content">
<!-- 活动倒计时 -->
<view class="content-header ss-flex-col ss-col-center ss-row-center">
<!-- <view class="content-header ss-flex-col ss-col-center ss-row-center">
<view class="content-header-box ss-flex ss-row-center">
<view
class="countdown-box ss-flex"
@ -75,7 +75,7 @@
</view>
<view v-else> {{ activeTimeConfig?.status }} </view>
</view>
</view>
</view> -->
<!-- 活动列表 -->
<scroll-view
@ -174,8 +174,9 @@
}
});
timeConfigList.value = data;
console.log(timeConfigList.value[0]?.id,"timeConfigList.value[0]?.id");
//
handleChangeTimeConfig(activeTimeIndex.value);
handleChangeTimeConfig(activeTimeIndex.value, timeConfigList.value[0]?.id);
//
scrollToTimeConfig(activeTimeIndex.value);
};
@ -189,13 +190,13 @@
//
const activeTimeIndex = ref(0); //
const activeTimeConfig = computed(() => timeConfigList.value[activeTimeIndex.value]); //
const handleChangeTimeConfig = (index) => {
const handleChangeTimeConfig = (index, config) => {
activeTimeIndex.value = index;
console.log(config,'config')
//
activityPageParams.pageNo = 1;
activityList.value = [];
getActivityList();
getActivityList(config);
};
//
@ -212,15 +213,16 @@
//
const activityPageParams = reactive({
id: 0, // ID
configId: 0, // ID
pageNo: 1, //
pageSize: 5, //
});
const activityTotal = ref(0); //
const activityList = ref([]); //
const loadStatus = ref(''); //
async function getActivityList() {
async function getActivityList(id) {
loadStatus.value = 'loading';
activityPageParams.configId= id;
const { data } = await SeckillApi.getSeckillActivityPage(activityPageParams);
data.list.forEach((activity) => {
//
@ -264,7 +266,7 @@
.header {
width: 710rpx;
height: 330rpx;
margin: -276rpx auto 0 auto;
margin: 0 auto 0 auto;
border-radius: 14rpx;
overflow: hidden;
swiper {
@ -331,7 +333,7 @@
position: relative;
z-index: 3;
margin: 0 20rpx 0 20rpx;
background: #fff;
// background: #fff;
border-radius: 20rpx 20rpx 0 0;
.content-header {
width: 100%;

View File

@ -10,7 +10,7 @@
v-for="(record, index) in state.list"
@tap="sheep.$router.go('/pages/activity/groupon/detail', { id: record.id })"
:key="index"
class="ss-m-t-40 ss-flex ss-row-between border-bottom ss-p-b-30"
class="ss-m-t-40 ss-flex ss-row-between ss-p-b-30"
>
<view class="ss-flex ss-col-center">
<image :src="sheep.$url.cdn(record.avatar)" class="user-avatar"></image>

File diff suppressed because one or more lines are too long

View File

@ -96,7 +96,7 @@
>
<view class="price-box ss-flex">
<image
:src="sheep.$url.static('/static/img/shop/goods/score1.svg')"
src="https://zysc.fjptzykj.com:3000/shangcheng/b0c400b1b30a9ca45031093595e42533de267823285c702fed250061920debf0.png"
style="width: 36rpx;height: 36rpx;margin: 0 4rpx;"
></image>
<text class="point-text ss-m-r-16">
@ -372,7 +372,7 @@
font-size: 24rpx;
font-weight: 600;
margin-left: -36rpx;
background-image: v-bind(btnBg);
background-image: url('https://zysc.fjptzykj.com:3000/shangcheng/ae81b6671e07f250d4bbccc9707409e970cd5ecee9d4fd861fd0bb926812dda9.png');
background-repeat: no-repeat;
background-size: 100% 100%;
color: #ffffff;

File diff suppressed because one or more lines are too long

View File

@ -1,14 +1,22 @@
<!-- 首页支持店铺装修 -->
<template>
<view v-if="template">
<s-layout
title="首页"
navbar="custom"
navbar="normal"
tools="search"
tabbar="/pages/index/index"
:bgStyle="template.page"
:navbarStyle="template.navigationBar"
onShareAppMessage
@search="(e) => { console.log(e,'eeeeeeeeeeee') }"
headerBtns='headerBtns'
navbarbackgroundColor="rgba(248,83,42)"
opacityBgUi='ll'
:navBg="true"
>
<view class="new-bg"></view>
<s-block
v-for="(item, index) in template.components"
:key="index"
@ -88,4 +96,11 @@
onPageScroll(() => {});
</script>
<style></style>
<style lang="scss">
.new-bg{
background:rgba(248,83,42);
width:100%;
height:50px;
position: absolute;
}
</style>

View File

@ -1,13 +1,6 @@
<!-- 自定义页面支持装修 -->
<template>
<s-layout
:title="state.name"
navbar="custom"
:bgStyle="state.page"
:navbarStyle="state.navigationBar"
onShareAppMessage
showLeftButton
>
<s-layout navbar="normal" :bgStyle="{ color: '#FE832A'}">
<s-block v-for="(item, index) in state.components" :key="index" :styles="item.property.style">
<s-block-item :type="item.id" :data="item.property" :styles="item.property.style" />
</s-block>

View File

@ -3,10 +3,20 @@
<s-layout title="个人中心" tabbar="/pages/index/user" navbar="normal" :bgStyle="template.page"
:navbarStyle="template.navigationBar" onShareAppMessage>
<image class="seckill" src="@/static/images/seckilbg.png"></image>
<s-block class="" 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-item style="" :class="item.id == 'UserOrder'? 'ss': ''" :type="item.id" :data="item.property" :styles="item.property.style" />
</s-block>
<view class="new-huiy" @click="
sheep.$router.go('/pages/user/user_vip/index')
">
<image class="seckill" src="@/static/images/seckilbg.png"></image>
<view class="new-button">立即开通</view>
<img class="seckill1" mode="aspectFit"
src="https://zysc.fjptzykj.com:3000/shangcheng/64776e2edc3c2f15295e7c3976ba301e08f9170f99a2e845d8f33bd65179b177.png" />
</view>
</s-layout>
</template>
@ -41,13 +51,40 @@
onPageScroll(() => {});
</script>
<style>
.new-main{
<style lang="scss" scoped>
.new-huiy {
width: 100%;
height: 240px;
position: absolute;
top: 0;
.new-button {
background: white;
padding: 8px;
text-align: center;
position: absolute;
border-radius: 20px;
right: 29px;
bottom: 17px;
font-size: 14px;
color: rgba(148, 109, 45, 1);
// z-index: 33;
}
.seckill1 {
position: absolute;
bottom: 0;
// z-index: 22;
/* left: 50%; */
/* transform: translateX(-50%); */
width: 96%;
height: 72px;
}
}
/* .new-main {} */
.seckill1 {
position: absolute;
top: 117px;
z-index: 22;
left: 50%;
transform: translateX(-50%);
@ -62,4 +99,11 @@
view {
position: relative;
}
::v-deep .ss{
z-index: 99999;
&>view{
margin-top: 94px;
}
}
</style>

View File

@ -41,36 +41,64 @@
</view>
</view>
<view
v-if="state.orderPayload.pointActivityId"
class="order-item ss-flex ss-col-center ss-row-between"
v-if="state.orderInfo.type === 0 && state.orderInfo.pointsStatus === 1"
>
<view class="item-title">积分抵扣</view>
<view class="item-title">兑换积分</view>
<view class="ss-flex ss-col-center">
{{ state.pointStatus ? '剩余积分' : '当前积分' }}
<image
:src="sheep.$url.static('/static/img/shop/goods/score1.svg')"
src="https://zysc.fjptzykj.com:3000/shangcheng/b0c400b1b30a9ca45031093595e42533de267823285c702fed250061920debf0.png"
class="score-img"
/>
<text class="item-value ss-m-r-24">
{{ state.pointStatus ? state.orderInfo.totalPoint - state.orderInfo.usedPoint : (state.orderInfo.totalPoint || 0) }}
{{ state.orderInfo.usePoint }}
</text>
<checkbox-group @change="changeIntegral">
<checkbox :checked='state.pointStatus' :disabled="!state.orderInfo.totalPoint || state.orderInfo.totalPoint <= 0" />
</view>
</view>
<view
class="order-item ss-flex ss-col-center ss-row-between"
v-if="state.orderInfo.type === 0 || state.orderPayload.pointActivityId"
>
<view class="item-title">积分抵扣</view>
<view class="ss-flex ss-col-center">
{{ state.pointStatus || state.orderPayload.pointActivityId ? '剩余积分' : '当前积分' }}
<image
src="https://zysc.fjptzykj.com:3000/shangcheng/b0c400b1b30a9ca45031093595e42533de267823285c702fed250061920debf0.png"
class="score-img"
/>
<text class="item-value ss-m-r-24">
{{
state.pointStatus || state.orderPayload.pointActivityId
? state.orderInfo.totalPoint - state.orderInfo.usePoint
: state.orderInfo.totalPoint || 0
}}
</text>
<checkbox-group @change="changeIntegral" v-if="!state.orderPayload.pointActivityId">
<checkbox
:checked="state.pointStatus"
:disabled="!state.orderInfo.totalPoint || state.orderInfo.totalPoint <= 0"
/>
</checkbox-group>
</view>
</view>
<!-- 快递配置时信息的展示 -->
<view class="order-item ss-flex ss-col-center ss-row-between" v-if='addressState.deliveryType === 1'>
<view
class="order-item ss-flex ss-col-center ss-row-between"
v-if="addressState.deliveryType === 1"
>
<view class="item-title">运费</view>
<view class="ss-flex ss-col-center">
<text class="item-value ss-m-r-24" v-if="state.orderInfo.price.deliveryPrice > 0">
+{{ fen2yuan(state.orderInfo.price.deliveryPrice) }}
</text>
<view class='item-value ss-m-r-24' v-else>免运费</view>
<view class="item-value ss-m-r-24" v-else>免运费</view>
</view>
</view>
<!-- 门店自提时需要填写姓名和手机号 -->
<view class="order-item ss-flex ss-col-center ss-row-between" v-if='addressState.deliveryType === 2'>
<view
class="order-item ss-flex ss-col-center ss-row-between"
v-if="addressState.deliveryType === 2"
>
<view class="item-title">联系人</view>
<view class="ss-flex ss-col-center">
<uni-easyinput
@ -82,7 +110,10 @@
/>
</view>
</view>
<view class="order-item ss-flex ss-col-center ss-row-between" v-if='addressState.deliveryType === 2'>
<view
class="order-item ss-flex ss-col-center ss-row-between"
v-if="addressState.deliveryType === 2"
>
<view class="item-title">联系电话</view>
<view class="ss-flex ss-col-center">
<uni-easyinput
@ -106,11 +137,17 @@
</text>
<text
class="item-value"
:class="state.couponInfo.length > 0 ? 'text-red' : 'text-disabled'"
:class="
state.couponInfo.filter((coupon) => coupon.match).length > 0
? 'text-red'
: 'text-disabled'
"
v-else
>
{{
state.couponInfo.length > 0 ? state.couponInfo.length + ' 张可用' : '暂无可用优惠券'
state.couponInfo.filter((coupon) => coupon.match).length > 0
? state.couponInfo.filter((coupon) => coupon.match).length + ' 张可用'
: '暂无可用优惠券'
}}
</text>
<text class="_icon-forward item-icon" />
@ -121,8 +158,7 @@
v-if="state.orderInfo.price.discountPrice > 0"
>
<view class="item-title">活动优惠</view>
<view class="ss-flex ss-col-center">
<!-- @tap="state.showDiscount = true" TODO 芋艿后续要把优惠信息打进去 -->
<view class="ss-flex ss-col-center" @tap="state.showDiscount = true">
<text class="item-value text-red">
-{{ fen2yuan(state.orderInfo.price.discountPrice) }}
</text>
@ -158,7 +194,7 @@
@close="state.showCoupon = false"
/>
<!-- 满额折扣弹框 TODO 芋艿后续要把优惠信息打进去 -->
<!-- 满额折扣弹框 TODO @puhui999折扣后续要把优惠信息打进去 -->
<s-discount-list
v-model="state.orderInfo"
:show="state.showDiscount"
@ -185,12 +221,12 @@
</template>
<script setup>
import { reactive, ref } from 'vue';
import { reactive, ref, watch } from 'vue';
import { onLoad } from '@dcloudio/uni-app';
import AddressSelection from '@/pages/order/addressSelection.vue';
import sheep from '@/sheep';
import OrderApi from '@/sheep/api/trade/order';
import CouponApi from '@/sheep/api/promotion/coupon';
import TradeConfigApi from '@/sheep/api/trade/config';
import { fen2yuan } from '@/sheep/hooks/useGoods';
const state = reactive({
@ -208,8 +244,8 @@
const addressState = ref({
addressInfo: {}, //
deliveryType: 1, // 1 - 2 -
isPickUp: true, // TODO puhui999:
deliveryType: 1, // 1-2-
isPickUp: true, //
pickUpInfo: {}, //
receiverName: '', //
receiverMobile: '', //
@ -226,7 +262,7 @@
//
async function onSelectCoupon(couponId) {
state.orderPayload.couponId = couponId || 0;
state.orderPayload.couponId = couponId;
await getOrderInfo();
state.showCoupon = false;
}
@ -273,6 +309,7 @@
combinationActivityId: state.orderPayload.combinationActivityId,
combinationHeadId: state.orderPayload.combinationHeadId,
seckillActivityId: state.orderPayload.seckillActivityId,
pointActivityId: state.orderPayload.pointActivityId,
});
if (code !== 0) {
return;
@ -283,9 +320,15 @@
}
//
if (data.payOrderId && data.payOrderId > 0) {
sheep.$router.redirect('/pages/pay/index', {
id: data.payOrderId,
});
} else {
sheep.$router.redirect('/pages/order/detail', {
id: data.id,
});
}
}
// &
@ -303,30 +346,19 @@
combinationActivityId: state.orderPayload.combinationActivityId,
combinationHeadId: state.orderPayload.combinationHeadId,
seckillActivityId: state.orderPayload.seckillActivityId,
pointActivityId: state.orderPayload.pointActivityId,
});
if (code !== 0) {
return;
}
state.orderInfo = data;
state.couponInfo = data.coupons || [];
//
if (state.orderInfo.address) {
addressState.value.addressInfo = state.orderInfo.address;
}
}
//
async function getCoupons() {
const { code, data } = await CouponApi.getMatchCouponList(
state.orderInfo.price.payPrice,
state.orderInfo.items.map((item) => item.spuId),
state.orderPayload.items.map((item) => item.skuId),
state.orderPayload.items.map((item) => item.categoryId),
);
if (code === 0) {
state.couponInfo = data;
}
}
onLoad(async (options) => {
if (!options.data) {
sheep.$helper.toast('参数不正确,请检查!');
@ -334,7 +366,22 @@
}
state.orderPayload = JSON.parse(options.data);
await getOrderInfo();
await getCoupons();
//
const { data, code } = await TradeConfigApi.getTradeConfig();
if (code === 0) {
addressState.value.isPickUp = data.deliveryPickUpEnabled;
}
});
// 使 watch
watch(addressState, async (newAddress, oldAddress) => {
//
if (
newAddress.addressInfo.id !== oldAddress.addressInfo.id ||
newAddress.deliveryType !== oldAddress.deliveryType
) {
await getOrderInfo();
}
});
</script>

View File

@ -68,16 +68,7 @@
<!-- 用户组件用户卡片 -->
<s-user-card v-if="type === 'UserCard'" />
<view v-if="type === 'UserOrder'" class="new-huiy"
@click="
sheep.$router.go('/pages/user/user_vip/index')
"
>
<view class="new-button">立即开通</view>
<img class="seckill1" mode="aspectFit"
src="https://zysc.fjptzykj.com:3000/shangcheng/64776e2edc3c2f15295e7c3976ba301e08f9170f99a2e845d8f33bd65179b177.png"
/>
</view>
<!-- 用户组件用户订单 -->
<s-order-card v-if="type === 'UserOrder'" :data="data" />
<!-- 用户组件用户资产 -->
@ -133,30 +124,7 @@
:deep(.uni-border-bottom){
height:0;
}
.new-huiy{
width:100%;
height:100px;
.new-button{
background:white;
padding:8px;
text-align:center;
position: absolute;
border-radius: 20px;
right: 29px;
top: 31px;
font-size:14px;
color: rgba(148, 109, 45, 1);
z-index: 33;
}
.seckill1{
position: absolute;
top: -71px;
z-index: 22;
/* left: 50%; */
/* transform: translateX(-50%); */
width: 94%;
}
}
.floxt {

View File

@ -5,7 +5,7 @@
<!-- couponList -->
<view
class="coupon-item new-class"
:style="[couponBg, { marginLeft: `${data.space}px` }]"
:style="[item.canTake ? couponBg : couponBgFalse, { marginLeft: `${data.space}px` }]"
v-for="(item, index) in couponList"
:key="index"
>
@ -22,7 +22,7 @@
<template v-slot:btn>
<!-- 两列时领取按钮坚排 -->
<button
v-if="columns === 2"
v-if="item.canTake"
@click.stop="onGetCoupon(item.id)"
class="ss-reset-button card-btn vertical"
:style="[btnStyles]"
@ -33,9 +33,8 @@
v-else
class="ss-reset-button card-btn"
:style="[btnStyles]"
@click.stop="onGetCoupon(item.id)"
>
立即领取
领取
</button>
</template>
</su-coupon>
@ -66,6 +65,11 @@
const couponBg = {
background: `url(${sheep.$url.cdn(props.data.bgImg)}) no-repeat top center / 100% 100%`,
};
const couponBgFalse = {
background: `url('https://zysc.fjptzykj.com:3000/shangcheng/94dfaa69257a102da3e28aa9b82cc7e04be5cea38555941972f6b5a3c2fc47a3.png') no-repeat top center / 100% 100%`,
};
const btnStyles = {
background: button.bgColor,
color: button.color,
@ -140,15 +144,16 @@
margin-right: 2px !important;
}
.card-btn {
width: 140rpx;
height: 50rpx;
writing-mode: tb-rl;
width: 35px;
height: auto;
border-radius: 25rpx;
font-size: 24rpx;
line-height: 50rpx;
&.vertical {
width: 50rpx;
height: 140rpx;
margin: auto 20rpx auto 0;
margin: 0;
.btn-text {
font-size: 24rpx;

View File

@ -3,8 +3,8 @@
class="ss-flex-col ss-col-center ss-row-center empty-box"
:style="[{ paddingTop: paddingTop + 'rpx' }]"
>
<view class=""><image class="empty-icon" :src="icon" mode="widthFix"></image></view>
<view class="empty-text ss-m-t-28 ss-m-b-40">
<!-- <view class=""><image class="empty-icon" :src="icon" mode="widthFix"></image></view> -->
<view class="empty-text ss-m-b-40">
<text v-if="text !== ''">{{ text }}</text>
</view>
<button class="ss-reset-button empty-btn" v-if="showAction" @tap="clickAction">

View File

@ -11,11 +11,7 @@
<view v-if="tagStyle.show" class="tag-icon-box">
<image class="tag-icon" :src="sheep.$url.cdn(tagStyle.src || tagStyle.imgUrl)"></image>
</view>
<image
class="xs-img-box"
:src="sheep.$url.cdn(data.image || data.picUrl)"
mode="aspectFit"
></image>
<image class="xs-img-box" :src="sheep.$url.cdn(data.image || data.picUrl)" mode="aspectFit" />
<view
v-if="goodsFields.title?.show || goodsFields.name?.show || goodsFields.price?.show"
class="xs-goods-content ss-flex-col ss-row-around"
@ -27,13 +23,40 @@
>
{{ data.title || data.name }}
</view>
<!-- 活动信息 -->
<view class="iconBox" v-if="data.promotionType > 0 || data.rewardActivity">
<view class="card" v-if="discountText">{{ discountText }}</view>
<view
class="card2"
v-for="item in getRewardActivityRuleItemDescriptions(data.rewardActivity).slice(0, 1)"
:key="item"
>
{{ item }}
</view>
</view>
<view
v-if="goodsFields.price?.show"
class="xs-goods-price font-OPPOSANS"
:style="[{ color: goodsFields.price.color }]"
>
<!-- 活动价格 -->
<view class="ss-flex" v-if="data.activityType && data.activityType === PromotionActivityTypeEnum.POINT.type">
<image
:src="sheep.$url.static('/static/img/shop/goods/score1.svg')"
class="point-img"
></image>
<text class="point-text ss-m-r-16">
{{ data.point }}
{{ !data.pointPrice || data.pointPrice === 0 ? '' : `+${priceUnit}${fen2yuan(data.pointPrice)}` }}
</text>
</view>
<template v-else>
<text class="price-unit ss-font-24">{{ priceUnit }}</text>
<text v-if="data.promotionPrice > 0">{{ fen2yuan(data.promotionPrice) }}</text>
<text v-else>
{{ isArray(data.price) ? fen2yuan(data.price[0]) : fen2yuan(data.price) }}
</text>
</template>
</view>
</view>
</view>
@ -60,13 +83,40 @@
>
{{ data.title || data.name }}
</view>
<!-- 活动信息 -->
<view class="iconBox" v-if="data.promotionType > 0 || data.rewardActivity">
<view class="card" v-if="discountText">{{ discountText }}</view>
<view
class="card2"
v-for="item in getRewardActivityRuleItemDescriptions(data.rewardActivity).slice(0, 1)"
:key="item"
>
{{ item }}
</view>
</view>
<view
v-if="goodsFields.price?.show"
class="sm-goods-price font-OPPOSANS"
:style="[{ color: goodsFields.price.color }]"
>
<!-- 活动价格 -->
<view class="ss-flex" v-if="data.activityType && data.activityType === PromotionActivityTypeEnum.POINT.type">
<image
:src="sheep.$url.static('/static/img/shop/goods/score1.svg')"
class="point-img"
></image>
<text class="point-text ss-m-r-16">
{{ data.point }}
{{ !data.pointPrice || data.pointPrice === 0 ? '' : `+${priceUnit}${fen2yuan(data.pointPrice)}` }}
</text>
</view>
<template v-else>
<text class="price-unit ss-font-24">{{ priceUnit }}</text>
<text v-if="data.promotionPrice > 0">{{ fen2yuan(data.promotionPrice) }}</text>
<text v-else>
{{ isArray(data.price) ? fen2yuan(data.price[0]) : fen2yuan(data.price) }}
</text>
</template>
</view>
</view>
</view>
@ -74,13 +124,9 @@
<!-- md卡片竖向一行放两个图上内容下 -->
<view v-if="size === 'md'" class="md-goods-card ss-flex-col" :style="[elStyles]" @tap="onClick">
<view v-if="tagStyle.show" class="tag-icon-box">
<image class="tag-icon" :src="sheep.$url.cdn(tagStyle.src || tagStyle.imgUrl)"></image>
<image class="tag-icon" :src="sheep.$url.cdn(tagStyle.src || tagStyle.imgUrl)" />
</view>
<image
class="md-img-box"
:src="sheep.$url.cdn(data.image || data.picUrl)"
mode="widthFix"
></image>
<image class="md-img-box" :src="sheep.$url.cdn(data.image || data.picUrl)" mode="widthFix" />
<view
class="md-goods-content ss-flex-col ss-row-around ss-p-b-20 ss-p-t-20 ss-p-x-16"
:id="elId"
@ -110,16 +156,42 @@
</view>
</view>
</slot>
<!-- 活动信息 -->
<view class="iconBox" v-if="data.promotionType > 0 || data.rewardActivity">
<view class="card" v-if="discountText">{{ discountText }}</view>
<view
class="card2"
v-for="item in getRewardActivityRuleItemDescriptions(data.rewardActivity).slice(0, 1)"
:key="item"
>
{{ item }}
</view>
</view>
<view class="ss-flex ss-col-bottom">
<view
v-if="goodsFields.price?.show"
class="md-goods-price ss-m-t-16 font-OPPOSANS ss-m-r-10"
:style="[{ color: goodsFields.price.color }]"
>
<text class="price-unit ss-font-24">{{ priceUnit }}</text>
{{ isArray(data.price) ? fen2yuan(data.price[0]) : fen2yuan(data.price) }}
<!-- 活动价格 -->
<view class="ss-flex" v-if="data.activityType && data.activityType === PromotionActivityTypeEnum.POINT.type">
<image
:src="sheep.$url.static('/static/img/shop/goods/score1.svg')"
class="point-img"
></image>
<text class="point-text ss-m-r-16">
{{ data.point }}
{{ !data.pointPrice || data.pointPrice === 0 ? '' : `+${priceUnit}${fen2yuan(data.pointPrice)}` }}
</text>
</view>
<template v-else>
<text class="price-unit ss-font-24">{{ priceUnit }}</text>
<text v-if="data.promotionPrice > 0">{{ fen2yuan(data.promotionPrice) }}</text>
<text v-else>
{{ isArray(data.price) ? fen2yuan(data.price[0]) : fen2yuan(data.price) }}
</text>
</template>
</view>
<view
v-if="
(goodsFields.original_price?.show || goodsFields.marketPrice?.show) &&
@ -155,7 +227,7 @@
<view v-if="tagStyle.show" class="tag-icon-box">
<image class="tag-icon" :src="sheep.$url.cdn(tagStyle.src || tagStyle.imgUrl)"></image>
</view>
<view v-if="seckillTag" class="seckill-tag ss-flex ss-row-center"> 秒杀 </view>
<!-- <view v-if="seckillTag" class="seckill-tag ss-flex ss-row-center">秒杀</view> -->
<view v-if="grouponTag" class="groupon-tag ss-flex ss-row-center">
<view class="tag-icon">拼团</view>
</view>
@ -163,8 +235,8 @@
class="lg-img-box"
:src="sheep.$url.cdn(data.image || data.picUrl)"
mode="aspectFill"
></image>
<view class="lg-goods-content ss-flex-1 ss-flex-col ss-row-between ss-p-b-10 ss-p-t-20">
/>
<view class="lg-goods-content ss-flex-1 ss-flex-col ss-row-between ss-p-b-10 ">
<view>
<view
v-if="goodsFields.title?.show || goodsFields.name?.show"
@ -189,21 +261,44 @@
</view>
</view>
</slot>
<view class="ss-flex ss-col-bottom ss-m-t-10">
<!-- 活动信息 -->
<view class="iconBox" v-if="data.promotionType > 0 || data.rewardActivity">
<view class="card" v-if="discountText">{{ discountText }}</view>
<view
v-if="goodsFields.price?.show"
class="lg-goods-price ss-m-r-12 ss-flex ss-col-bottom font-OPPOSANS"
:style="[{ color: goodsFields.price.color }]"
class="card2"
v-for="item in getRewardActivityRuleItemDescriptions(data.rewardActivity).slice(0, 1)"
:key="item"
>
<text class="ss-font-24">{{ priceUnit }}</text>
{{ item }}
</view>
</view>
<view v-if="goodsFields.price?.show" class="ss-flex ss-col-bottom font-OPPOSANS">
<view class="sl-goods-price ss-m-r-12" :style="[{ color: goodsFields.price.color }]">
<!-- 活动价格 -->
<view class="ss-flex" v-if="data.activityType && data.activityType === PromotionActivityTypeEnum.POINT.type">
<image
src="https://zysc.fjptzykj.com:3000/shangcheng/b0c400b1b30a9ca45031093595e42533de267823285c702fed250061920debf0.png"
class="point-img"
></image>
<text class="point-text ss-m-r-16">
{{ data.point }}
{{ !data.pointPrice || data.pointPrice === 0 ? '' : `+${priceUnit}${fen2yuan(data.pointPrice)}` }}
</text>
</view>
<template v-else>
<text class="price-unit ss-font-24">{{ priceUnit }}</text>
<text v-if="data.promotionPrice > 0">{{ fen2yuan(data.promotionPrice) }}</text>
<text v-else>
{{ isArray(data.price) ? fen2yuan(data.price[0]) : fen2yuan(data.price) }}
</text>
</template>
</view>
<view
v-if="
(goodsFields.original_price?.show || goodsFields.marketPrice?.show) &&
(data.original_price > 0 || data.marketPrice > 0)
"
class="goods-origin-price ss-flex ss-col-bottom font-OPPOSANS"
class="goods-origin-price ss-m-t-16 font-OPPOSANS ss-flex"
:style="[{ color: originPriceColor }]"
>
<text class="price-unit ss-font-20">{{ priceUnit }}</text>
@ -224,15 +319,13 @@
<!-- sl卡片竖向型一行放一个图片上内容下边 -->
<view v-if="size === 'sl'" class="sl-goods-card ss-flex-col" :style="[elStyles]" @tap="onClick">
<view v-if="tagStyle.show" class="tag-icon-box">
<image class="tag-icon" :src="sheep.$url.cdn(tagStyle.src || tagStyle.imgUrl)"></image>
<image class="tag-icon" :src="sheep.$url.cdn(tagStyle.src || tagStyle.imgUrl)" />
</view>
<image
class="sl-img-box"
:src="sheep.$url.cdn(data.image || data.picUrl)"
mode="aspectFill"
></image>
/>
<view class="sl-goods-content">
<view>
<view
@ -262,10 +355,37 @@
</view>
</view>
</slot>
<!-- 活动信息 -->
<view class="iconBox" v-if="data.promotionType > 0 || data.rewardActivity">
<view class="card" v-if="discountText">{{ discountText }}</view>
<view
class="card2"
v-for="item in getRewardActivityRuleItemDescriptions(data.rewardActivity).slice(0, 1)"
:key="item"
>
{{ item }}
</view>
</view>
<view v-if="goodsFields.price?.show" class="ss-flex ss-col-bottom font-OPPOSANS">
<view class="sl-goods-price ss-m-r-12" :style="[{ color: goodsFields.price.color }]">
<!-- 活动价格 -->
<view class="ss-flex" v-if="data.activityType && data.activityType === PromotionActivityTypeEnum.POINT.type">
<image
src="https://zysc.fjptzykj.com:3000/shangcheng/b0c400b1b30a9ca45031093595e42533de267823285c702fed250061920debf0.png"
class="point-img"
></image>
<text class="ss-m-r-16">
{{ data.point }}
{{ !data.pointPrice || data.pointPrice === 0 ? '' : `+${priceUnit}${fen2yuan(data.pointPrice)}` }}
</text>
</view>
<template v-else>
<text class="price-unit ss-font-24">{{ priceUnit }}</text>
<text v-if="data.promotionPrice > 0">{{ fen2yuan(data.promotionPrice) }}</text>
<text v-else>
{{ isArray(data.price) ? fen2yuan(data.price[0]) : fen2yuan(data.price) }}
</text>
</template>
</view>
<view
v-if="
@ -285,9 +405,9 @@
</view>
</view>
<slot name="cart"
><view class="buy-box ss-flex ss-col-center ss-row-center">去购买</view></slot
>
<slot name="cart">
<view class="buy-box ss-flex ss-col-center ss-row-center">去购买</view>
</slot>
</view>
</view>
</template>
@ -321,15 +441,17 @@
* @event {Function()} click - 点击卡片
*
*/
import { computed, reactive, getCurrentInstance, onMounted, nextTick } from 'vue';
import { computed, getCurrentInstance, nextTick, onMounted } from 'vue';
import sheep from '@/sheep';
import { fen2yuan, formatSales } from '@/sheep/hooks/useGoods';
import { formatStock } from '@/sheep/hooks/useGoods';
import goodsCollectVue from '@/pages/user/goods-collect.vue';
import { isArray } from 'lodash';
//
const state = reactive({});
import {
fen2yuan,
formatExchange,
formatSales,
formatStock,
getRewardActivityRuleItemDescriptions,
} from '@/sheep/hooks/useGoods';
import { isArray } from 'lodash-es';
import { PromotionActivityTypeEnum } from '@/sheep/util/const';
//
const props = defineProps({
@ -338,27 +460,39 @@
default() {
return {
//
price: { show: true },
price: {
show: true,
},
//
stock: { show: true },
stock: {
show: true,
},
//
name: { show: true },
name: {
show: true,
},
//
introduction: { show: true },
introduction: {
show: true,
},
//
marketPrice: { show: true },
marketPrice: {
show: true,
},
//
salesCount: { show: true },
salesCount: {
show: true,
},
};
},
},
tagStyle: {
type: Object,
default: {},
default: () => ({}),
},
data: {
type: Object,
default: {},
default: () => ({}),
},
size: {
type: String,
@ -418,6 +552,17 @@
},
});
//
const discountText = computed(() => {
const promotionType = props.data.promotionType;
if (promotionType === 4) {
return '限时优惠';
} else if (promotionType === 6) {
return '会员价';
}
return undefined;
});
//
const elStyles = computed(() => {
return {
@ -433,11 +578,19 @@
const salesAndStock = computed(() => {
let text = [];
if (props.goodsFields.salesCount?.show) {
if (props.data.activityType && props.data.activityType === PromotionActivityTypeEnum.POINT.type) {
text.push(formatExchange(props.data.sales_show_type, (props.data.pointTotalStock || 0) - (props.data.pointStock || 0)));
} else {
text.push(formatSales(props.data.sales_show_type, props.data.salesCount));
}
}
if (props.goodsFields.stock?.show) {
if (props.data.activityType && props.data.activityType === PromotionActivityTypeEnum.POINT.type) {
text.push(formatStock(props.data.stock_show_type, props.data.pointTotalStock));
} else {
text.push(formatStock(props.data.stock_show_type, props.data.stock));
}
}
return text.join(' | ');
});
@ -451,10 +604,14 @@
//
const { proxy } = getCurrentInstance();
const elId = `sheep_${Math.ceil(Math.random() * 10e5).toString(36)}`;
function getGoodsPriceCardWH() {
if (props.size === 'md') {
const view = uni.createSelectorQuery().in(proxy);
view.select(`#${elId}`).fields({ size: true, scrollOffset: true });
view.select(`#${elId}`).fields({
size: true,
scrollOffset: true,
});
view.exec((data) => {
let totalHeight = 0;
const goodsPriceCard = data[0];
@ -469,6 +626,7 @@
});
}
}
onMounted(() => {
nextTick(() => {
getGoodsPriceCardWH();
@ -482,12 +640,13 @@
left: 0;
top: 0;
z-index: 2;
.tag-icon {
width: 72rpx;
height: 44rpx;
border-radius:8px;
}
}
.seckill-tag {
position: absolute;
left: 0;
@ -502,6 +661,13 @@
color: #ffffff;
line-height: 32rpx;
}
.point-img {
width: 30rpx;
height: 30rpx;
margin: 0 4rpx;
}
.groupon-tag {
position: absolute;
left: 0;
@ -516,14 +682,17 @@
color: #ffffff;
line-height: 32rpx;
}
.goods-img {
width: 100%;
height: 100%;
background-color: #f5f5f5;
}
.price-unit {
margin-right: -4px;
}
.sales-text {
display: table;
font-size: 24rpx;
@ -581,19 +750,18 @@
// width: 100%;
background-color: $white;
position: relative;
padding: 0 10px;
padding-top: 10px;
.sm-img-box {
// width: 228rpx;
width: 100%;
height: 208rpx;
border-radius:8px;
}
.sm-goods-content {
padding: 20rpx 16rpx;
box-sizing: border-box;
}
.sm-goods-title {
font-size: 26rpx;
color: #333;
@ -608,8 +776,7 @@
// md
.md-goods-card {
overflow: hidden;
width: auto;
padding: 10px 10px;
width: 100%;
position: relative;
z-index: 1;
background-color: $white;
@ -624,6 +791,7 @@
color: #333;
width: 100%;
}
.md-goods-subtitle {
font-size: 24rpx;
font-weight: 400;
@ -659,12 +827,14 @@
position: relative;
z-index: 1;
background-color: $white;
height: 280rpx;
// height: 280rpx;
border-radius:10px !important;
padding: 10px;
.lg-img-box {
width: 280rpx;
height: 280rpx;
width: 180rpx;
height: 180rpx;
margin-right: 20rpx;
border-radius:10px;
}
.lg-goods-title {
@ -674,6 +844,7 @@
// line-height: 36rpx;
// width: 410rpx;
}
.lg-goods-subtitle {
font-size: 24rpx;
font-weight: 400;
@ -700,6 +871,7 @@
font-size: 24rpx;
color: #ffffff;
}
.tag-box {
width: 100%;
}
@ -713,10 +885,12 @@
z-index: 1;
width: 100%;
background-color: $white;
.sl-goods-content {
padding: 20rpx 20rpx;
box-sizing: border-box;
}
.sl-img-box {
width: 100%;
height: 360rpx;
@ -727,6 +901,7 @@
color: #333;
font-weight: 500;
}
.sl-goods-subtitle {
font-size: 24rpx;
font-weight: 400;
@ -753,4 +928,33 @@
color: #ffffff;
}
}
.card {
width: fit-content;
height: fit-content;
padding: 2rpx 10rpx;
background-color: red;
color: #ffffff;
font-size: 24rpx;
margin-top: 5rpx;
}
.card2 {
width: fit-content;
height: fit-content;
padding: 2rpx 10rpx;
background-color: rgb(255, 242, 241);
color: #ff2621;
font-size: 24rpx;
margin: 5rpx 0 5rpx 5rpx;
}
.iconBox {
width: 100%;
height: fit-content;
margin-top: 10rpx;
display: flex;
justify-content: flex-start;
flex-wrap: wrap;
}
</style>

View File

@ -213,6 +213,7 @@
.goods-sm-box {
margin: 0 auto;
box-sizing: border-box;
padding: 0 10px;
.goods-card-box {
flex-shrink: 0;

View File

@ -14,6 +14,9 @@
:opacityBgUi="opacityBgUi"
@search="(e) => emits('search', e)"
:defaultSearch="defaultSearch"
:headerBtns = "headerBtns"
:backgroundColor="navbarbackgroundColor"
:navBg="navBg"
/>
<!-- 顶部导航栏-情况2装修组件导航栏-标准 -->
@ -73,6 +76,14 @@
type: String,
default: '',
},
headerBtns: {
type: String,
default: '',
},
navbarbackgroundColor:{
type: String,
default: '',
},
navbar: {
type: String,
default: 'normal',
@ -136,6 +147,10 @@
type: Boolean,
default: false,
},
navBg: {
type: Boolean,
default: false,
},
});
const emits = defineEmits(['search']);

View File

@ -3,28 +3,13 @@
<!-- 商品卡片 -->
<view>
<!-- 布局1. 单列大图上图下内容-->
<view
v-if="layoutType === LayoutTypeEnum.ONE_COL_BIG_IMG && state.spuList.length"
class="goods-sl-box"
>
<view
class="goods-box"
v-for="item in state.spuList"
:key="item.id"
:style="[{ marginBottom: data.space * 2 + 'rpx' }]"
>
<s-goods-column
class=""
size="sl"
:goodsFields="data.fields"
:tagStyle="data.badge"
:data="item"
:titleColor="data.fields.name?.color"
:subTitleColor="data.fields.introduction.color"
:topRadius="data.borderRadiusTop"
:bottomRadius="data.borderRadiusBottom"
@click="sheep.$router.go('/pages/goods/point', { id: item.activityId })"
>
<view v-if="layoutType === LayoutTypeEnum.ONE_COL_BIG_IMG && state.spuList.length" class="goods-sl-box">
<view class="goods-box" v-for="item in state.spuList" :key="item.id"
:style="[{ marginBottom: data.space * 2 + 'rpx' }]">
<s-goods-column class="" size="sl" :goodsFields="data.fields" :tagStyle="data.badge" :data="item"
:titleColor="data.fields.name?.color" :subTitleColor="data.fields.introduction.color"
:topRadius="data.borderRadiusTop" :bottomRadius="data.borderRadiusBottom"
@click="sheep.$router.go('/pages/goods/point', { id: item.activityId })">
<!-- 购买按钮 -->
<template v-slot:cart>
<button class="ss-reset-button cart-btn" :style="[buyStyle]">
@ -36,28 +21,14 @@
</view>
<!-- 布局2. 单列小图左图右内容 -->
<view
v-if="layoutType === LayoutTypeEnum.ONE_COL_SMALL_IMG && state.spuList.length"
class="goods-lg-box"
>
<view
class="goods-box"
:style="[{ marginBottom: data.space + 'px' }]"
v-for="item in state.spuList"
:key="item.id"
>
<s-goods-column
class="goods-card"
size="lg"
:goodsFields="data.fields"
:data="item"
:tagStyle="data.badge"
:titleColor="data.fields.name?.color"
:subTitleColor="data.fields.introduction.color"
:topRadius="data.borderRadiusTop"
<view v-if="layoutType === LayoutTypeEnum.ONE_COL_SMALL_IMG && state.spuList.length" class="goods-lg-box">
<view class="goods-box" :style="[{ marginBottom: data.space + 'px' }]" v-for="item in state.spuList"
:key="item.id">
<s-goods-column class="goods-card" size="lg" :goodsFields="data.fields" :data="item"
:tagStyle="data.badge" :titleColor="data.fields.name?.color"
:subTitleColor="data.fields.introduction.color" :topRadius="data.borderRadiusTop"
:bottomRadius="data.borderRadiusBottom"
@tap="sheep.$router.go('/pages/goods/point', { id: item.activityId })"
>
@tap="sheep.$router.go('/pages/goods/point', { id: item.activityId })">
<!-- 购买按钮 -->
<template v-slot:cart>
<button class="ss-reset-button cart-btn" :style="[buyStyle]">
@ -69,31 +40,17 @@
</view>
<!-- 布局3. 双列每一列上图下内容-->
<view
v-if="layoutType === LayoutTypeEnum.TWO_COL && state.spuList.length"
class="goods-md-wrap ss-flex ss-flex-wrap ss-col-top"
>
<view v-if="layoutType === LayoutTypeEnum.TWO_COL && state.spuList.length"
class="goods-md-wrap ss-flex ss-flex-wrap ss-col-top">
<view class="goods-list-box">
<view
class="left-list"
:style="[{ paddingRight: data.space + 'rpx', marginBottom: data.space + 'px' }]"
v-for="item in state.leftSpuList"
:key="item.id"
>
<s-goods-column
class="goods-md-box"
size="md"
:goodsFields="data.fields"
:tagStyle="data.badge"
:data="item"
:titleColor="data.fields.name?.color"
:subTitleColor="data.fields.introduction.color"
:topRadius="data.borderRadiusTop"
:bottomRadius="data.borderRadiusBottom"
:titleWidth="330 - marginLeft - marginRight"
<view class="left-list" :style="[{ paddingRight: data.space + 'rpx', marginBottom: data.space + 'px' }]"
v-for="item in state.leftSpuList" :key="item.id">
<s-goods-column class="goods-md-box" size="md" :goodsFields="data.fields" :tagStyle="data.badge"
:data="item" :titleColor="data.fields.name?.color"
:subTitleColor="data.fields.introduction.color" :topRadius="data.borderRadiusTop"
:bottomRadius="data.borderRadiusBottom" :titleWidth="330 - marginLeft - marginRight"
@click="sheep.$router.go('/pages/goods/point', { id: item.activityId })"
@getHeight="calculateGoodsColumn($event, 'left')"
>
@getHeight="calculateGoodsColumn($event, 'left')">
<!-- 购买按钮 -->
<template v-slot:cart>
<button class="ss-reset-button cart-btn" :style="[buyStyle]">
@ -104,26 +61,14 @@
</view>
</view>
<view class="goods-list-box">
<view
class="right-list"
:style="[{ paddingLeft: data.space + 'rpx', marginBottom: data.space + 'px' }]"
v-for="item in state.rightSpuList"
:key="item.id"
>
<s-goods-column
class="goods-md-box"
size="md"
:goodsFields="data.fields"
:tagStyle="data.badge"
:data="item"
:titleColor="data.fields.name?.color"
:subTitleColor="data.fields.introduction.color"
:topRadius="data.borderRadiusTop"
:bottomRadius="data.borderRadiusBottom"
:titleWidth="330 - marginLeft - marginRight"
<view class="right-list" :style="[{ paddingLeft: data.space + 'rpx', marginBottom: data.space + 'px' }]"
v-for="item in state.rightSpuList" :key="item.id">
<s-goods-column class="goods-md-box" size="md" :goodsFields="data.fields" :tagStyle="data.badge"
:data="item" :titleColor="data.fields.name?.color"
:subTitleColor="data.fields.introduction.color" :topRadius="data.borderRadiusTop"
:bottomRadius="data.borderRadiusBottom" :titleWidth="330 - marginLeft - marginRight"
@click="sheep.$router.go('/pages/goods/point', { id: item.activityId })"
@getHeight="calculateGoodsColumn($event, 'right')"
>
@getHeight="calculateGoodsColumn($event, 'right')">
<!-- 购买按钮 -->
<template v-slot:cart>
<button class="ss-reset-button cart-btn" :style="[buyStyle]">
@ -141,11 +86,18 @@
/**
* 商品卡片
*/
import { computed, onMounted, reactive, ref } from 'vue';
import {
computed,
onMounted,
reactive,
ref
} from 'vue';
import sheep from '@/sheep';
import SpuApi from '@/sheep/api/product/spu';
import PointApi from '@/sheep/api/promotion/point';
import { PromotionActivityTypeEnum } from '@/sheep/util/const';
import {
PromotionActivityTypeEnum
} from '@/sheep/util/const';
//
const LayoutTypeEnum = {
@ -173,8 +125,15 @@
},
});
const { layoutType, btnBuy, activityIds } = props.data || {};
const { marginLeft, marginRight } = props.styles || {};
const {
layoutType,
btnBuy,
activityIds
} = props.data || {};
const {
marginLeft,
marginRight
} = props.styles || {};
//
const buyStyle = computed(() => {
@ -232,7 +191,9 @@
* @return {Promise<undefined>} 商品列表
*/
async function getPointActivityDetailList(ids) {
const { data } = await PointApi.getPointActivityListByIds(ids);
const {
data
} = await PointApi.getPointActivityListByIds(ids);
return data;
}
@ -242,7 +203,9 @@
* @return {Promise<undefined>} 商品列表
*/
async function getSpuDetail(ids) {
const { data: spu } = await SpuApi.getSpuDetail(ids);
const {
data: spu
} = await SpuApi.getSpuDetail(ids);
return spu;
}

View File

@ -336,7 +336,7 @@
.goods-sm-box {
margin: 0 auto;
box-sizing: border-box;
padding:0 10px;
.goods-card-box {
flex-shrink: 0;
overflow: hidden;

View File

@ -11,8 +11,8 @@
mode="aspectFill"
/>
</view>
<view class="header-right ss-flex-col ss-row-between ss-flex-1">
<view class="goods-title ss-line-2">
<view class="header-right ss-flex-col ss-flex-1">
<!-- <view class="goods-title ss-line-2">
<view class="tig ss-flex ss-col-center">
<view class="tig-icon ss-flex ss-col-center ss-row-center">
<view class="groupon-tag">
@ -24,12 +24,15 @@
<view class="info-title">
{{ goodsInfo.name }}
</view>
</view>
</view> -->
<view class="header-right-bottom ss-flex ss-col-center ss-row-between">
<view class="price-text"> {{ fen2yuan(goodsInfo.price) }}</view>
<view class="stock-text ss-m-l-20">
库存{{ state.selectedSku.stock || goodsInfo.stock }}
</view>
<view class="header-right-bottom ss-flex ss-col-center ss-row-between">
<view class="stock-text">
限量:{{ state.selectedSku.stock || goodsInfo.stock }}
</view>
</view>
</view>
@ -427,7 +430,7 @@
}
.price-text {
font-size: 30rpx;
font-size: 48rpx;
font-weight: 500;
color: $red;
font-family: OPPOSANS;

View File

@ -5,7 +5,7 @@
<!-- SKU 信息 -->
<view class="ss-modal-box bg-white ss-flex-col">
<view class="modal-header ss-flex ss-col-center">
<!-- 规格图 -->
<!-- 规格图 -->
<view class="header-left ss-m-r-30">
<image
class="sku-image"
@ -19,8 +19,19 @@
<view class="goods-title ss-line-2">{{ state.goodsInfo.name }}</view>
<view class="header-right-bottom ss-flex ss-col-center ss-row-between">
<!-- 价格 -->
<view class="price-text">
{{ fen2yuan(state.selectedSku.price || state.goodsInfo.price) }}
<view v-if="state.goodsInfo.activity_type === PromotionActivityTypeEnum.POINT.type"
class="price-text ss-flex">
<image
v-if="!isEmpty(state.selectedSku)"
src="https://zysc.fjptzykj.com:3000/shangcheng/b0c400b1b30a9ca45031093595e42533de267823285c702fed250061920debf0.png"
class="point-img"
></image>
<text class="point-text ss-m-r-16">
{{ getShowPriceText }}
</text>
</view>
<view v-else class="price-text">
{{ fen2yuan(state.selectedSku.price || state.goodsInfo.price) }}
</view>
<!-- 秒杀价格标签 -->
<view class="tig ss-flex ss-col-center">
@ -92,12 +103,15 @@
import { computed, reactive, watch } from 'vue';
import sheep from '@/sheep';
import { convertProductPropertyList, fen2yuan } from '@/sheep/hooks/useGoods';
import { min } from 'lodash';
import { isEmpty, min } from 'lodash-es';
import { PromotionActivityTypeEnum } from '@/sheep/util/const';
const emits = defineEmits(['change', 'addCart', 'buy', 'close']);
const props = defineProps({
modelValue: {
type: Object,
default() {},
default() {
},
},
show: {
type: Boolean,
@ -114,7 +128,14 @@
selectedSku: {},
currentPropertyArray: [],
});
const getShowPriceText = computed(() => {
let priceText = `${fen2yuan(state.goodsInfo.price)}`;
if (!isEmpty(state.selectedSku)) {
const sku = state.selectedSku;
priceText = `${sku.point}${!sku.pointPrice ? '' : `+¥${fen2yuan(sku.pointPrice)}`}`;
}
return priceText;
});
const propertyList = convertProductPropertyList(state.goodsInfo.skus);
// SKU
const skuList = computed(() => {
@ -125,10 +146,6 @@
return skuPrices;
});
if (!state.goodsInfo.is_sku) {
state.selectedSku = state.goodsInfo.skus[0];
}
watch(
() => state.selectedSku,
(newVal) => {
@ -311,6 +328,12 @@
}
}
.point-img {
width: 36rpx;
height: 36rpx;
margin: 0 4rpx;
}
.ss-modal-box {
border-radius: 30rpx 30rpx 0 0;
max-height: 1000rpx;
@ -348,11 +371,6 @@
font-weight: 500;
color: $red;
font-family: OPPOSANS;
&::before {
content: '¥';
font-size: 24rpx;
}
}
.stock-text {

View File

@ -1,7 +1,7 @@
<!-- 装修用户组件用户卡片 -->
<template>
<view class="ss-user-info-wrap ss-p-t-50">
<view class="ss-flex ss-col-center ss-row-between ss-m-b-20">
<view class="ss-user-info-wrap ss-p-t-50" style="z-index: 9999;">
<view class="ss-flex ss-col-center ss-row-between ">
<view class="left-box ss-flex ss-col-center ss-m-l-36">
<view class="avatar-box ss-m-r-24">
<image class="avatar-img" :src="

View File

@ -1,6 +1,6 @@
<!-- 装修用户组件用户资产 -->
<template>
<view class="ss-wallet-menu-wrap ss-flex ss-col-center">
<view class="ss-wallet-menu-wrap ss-flex ss-col-center" style="z-index: 9999;">
<view
class="menu-item ss-flex-1 ss-flex-col ss-row-center ss-col-center"
@tap="sheep.$router.go('/pages/user/wallet/money')"
@ -77,7 +77,7 @@
}
.menu-item {
height: 160rpx;
height: 105rpx;
.menu-title {
font-size: 24rpx;

View File

@ -82,7 +82,10 @@ export function formatGoodsSwiper(urlList) {
const isVideo = VIDEO_SUFFIX_LIST.some((suffix) => url.includes(suffix));
const type = isVideo ? 'video' : 'image';
const src = $url.cdn(url);
return { type, src };
return {
type,
src,
};
}) || []
);
}
@ -336,6 +339,27 @@ export function fen2yuan(price) {
return (price / 100.0).toFixed(2);
}
/**
* 将分转成元
*
* 如果没有小数点则不展示小数点部分
*
* @param price 例如说 100
* @returns {string} 例如说 1
*/
export function fen2yuanSimple(price) {
return fen2yuan(price).replace(/\.?0+$/, '');
}
/**
* 将折扣百分比转化为打x者 x 部分
*
* @param discountPercent
*/
export function formatDiscountPercent(discountPercent) {
return (discountPercent / 10.0).toFixed(1).replace(/\.?0+$/, '');
}
/**
* 从商品 SKU 数组中转换出商品属性的数组
*
@ -380,6 +404,99 @@ export function convertProductPropertyList(skus) {
return result;
}
export function appendSettlementProduct(spus, settlementInfos) {
if (!settlementInfos || settlementInfos.length === 0) {
return;
}
for (const spu of spus) {
const settlementInfo = settlementInfos.find((info) => info.spuId === spu.id);
if (!settlementInfo) {
return;
}
// 选择价格最小的 SKU 设置到 SPU 上
const settlementSku = settlementInfo.skus
.filter((sku) => sku.promotionPrice > 0)
.reduce((prev, curr) => (prev.promotionPrice < curr.promotionPrice ? prev : curr));
if (settlementSku) {
spu.promotionType = settlementSku.promotionType;
spu.promotionPrice = settlementSku.promotionPrice;
}
// 设置【满减送】活动
if (settlementInfo.rewardActivity) {
spu.rewardActivity = settlementInfo.rewardActivity;
}
}
}
// 获得满减送活动的规则描述group
export function getRewardActivityRuleGroupDescriptions(activity) {
if (!activity || !activity.rules || activity.rules.length === 0) {
return [];
}
const result = [
{ name: '满减', values: [] },
{ name: '赠品', values: [] },
{ name: '包邮', values: [] },
];
activity.rules.forEach((rule) => {
const conditionTypeStr =
activity.conditionType === 10 ? `${fen2yuanSimple(rule.limit)}` : `${rule.limit}`;
// 满减
if (rule.limit) {
result[0].values.push(`${conditionTypeStr}${fen2yuanSimple(rule.discountPrice)}`);
}
// 赠品
if (rule.point || (rule.giveCouponTemplateCounts && rule.giveCouponTemplateCounts.length > 0)) {
let tips = [];
if (rule.point) {
tips.push(`${rule.point} 积分`);
}
if (rule.giveCouponTemplateCounts && rule.giveCouponTemplateCounts.length > 0) {
tips.push(`${rule.giveCouponTemplateCounts.length} 张优惠券`);
}
result[1].values.push(`${conditionTypeStr} ${tips.join('、')}`);
}
// 包邮
if (rule.freeDelivery) {
result[2].values.push(`${conditionTypeStr} 包邮`);
}
});
// 移除 values 为空的元素
result.forEach((item) => {
if (item.values.length === 0) {
result.splice(result.indexOf(item), 1);
}
});
return result;
}
// 获得满减送活动的规则描述item
export function getRewardActivityRuleItemDescriptions(activity) {
if (!activity || !activity.rules || activity.rules.length === 0) {
return [];
}
const result = [];
activity.rules.forEach((rule) => {
const conditionTypeStr =
activity.conditionType === 10 ? `${fen2yuanSimple(rule.limit)}` : `${rule.limit}`;
// 满减
if (rule.limit) {
result.push(`${conditionTypeStr}${fen2yuanSimple(rule.discountPrice)}`);
}
// 赠品
if (rule.point) {
result.push(`${conditionTypeStr}${rule.point}积分`);
}
if (rule.giveCouponTemplateCounts && rule.giveCouponTemplateCounts.length > 0) {
result.push(`${conditionTypeStr}${rule.giveCouponTemplateCounts.length}张优惠券`);
}
// 包邮
if (rule.freeDelivery) {
result.push(`${conditionTypeStr}包邮`);
}
});
return result;
}
/**
* 格式化满减送活动的规则
*

View File

@ -254,7 +254,7 @@
.md-coupon-card {
width: 296rpx;
height: 74px;
height: 63px;
border-radius: 10rpx;
overflow: hidden;
@ -269,6 +269,7 @@
font-weight: bold;
color: v-bind('textColor');
vertical-align: text-bottom;
margin-bottom: 5px;
}
.value-unit {
@ -348,4 +349,10 @@
}
}
}
// .card-right{
// .card-btn{
// width:auto;
// height:auto;
// }
// }
</style>

View File

@ -1,28 +1,20 @@
<!-- 自定义导航栏 -->
<template>
<view class="uni-navbar" :class="{ 'uni-dark': dark }">
<view
:class="{
<view :class="{
'uni-navbar--fixed': fixed,
'uni-navbar--shadow': shadow,
'uni-navbar--border': border,
}"
class="uni-navbar__content"
>
}" class="uni-navbar__content">
<view class="fixed-bg" :class="[opacity ? '' : opacityBgUi]"></view>
<su-status-bar v-if="statusBar" />
<view
:style="{
<su-status-bar v-if="statusBar" :navBg = "navBg" />
<view :style="{
color: themeColor,
height: navbarHeight,
background: backgroundColor,
}"
class="uni-navbar__header"
>
<view
class="uni-navbar__header-btns uni-navbar__header-btns-left"
:style="{ width: leftIconWidth }"
>
}" class="uni-navbar__header">
<view v-if="headerBtns != 'headerBtns'" class="uni-navbar__header-btns uni-navbar__header-btns-left"
:style="{ width: leftIconWidth }">
<slot name="left">
<view class="uni-navbar__content_view" v-if="leftIcon.length > 0">
<view class="icon-box ss-flex">
@ -31,45 +23,36 @@
<text class="sicon-home" v-else />
</view>
<view class="line"></view>
<view
class="icon-button icon-button-right ss-flex ss-row-center"
@tap="showMenuTools"
>
<view class="icon-button icon-button-right ss-flex ss-row-center" @tap="showMenuTools">
<text class="sicon-more" />
</view>
</view>
</view>
<view
:class="{ 'uni-navbar-btn-icon-left': !leftIcon.length > 0 }"
class="uni-navbar-btn-text"
<view :class="{ 'uni-navbar-btn-icon-left': !leftIcon.length > 0 }" class="uni-navbar-btn-text"
v-if="
titleAlign === 'left' &&
title.length &&
sheep.$platform.name !== 'WechatOfficialAccount'
"
>
">
<text :style="{ color: themeColor, fontSize: '18px' }">{{ title }}</text>
</view>
</slot>
</view>
<view v-if="tools === 'search'" class="ss-flex-1">
<!-- <view class="new-view" v-if="headerBtns === 'headerBtns'" @click="onSearch">
<image class="new-image" src="https://zysc.fjptzykj.com:3000/shangcheng/e0d70e9bac714465b87d22d19e30f3fb008dbcdea21842674b355340d6dedceb.png"></image>
</view> -->
<view v-if="tools === 'search'" class=""
:style="`width:${sheep.$platform.device.windowWidth - sheep.$platform.capsule.width - 37}px;display: flex;align-items: center;`"
@click="onSearch">
<slot name="center">
<uni-search-bar
class="ss-flex-1 search-box"
:radius="20"
placeholder="请输入关键词"
cancelButton="none"
v-model="searchModel"
@confirm="onSearch"
/>
<uni-search-bar class="ss-flex-1 search-box" :radius="20" placeholder="请输入关键词"
cancelButton="none" v-model="searchModel" @confirm="onSearch" />
</slot>
</view>
<view v-else class="uni-navbar__header-container" @tap="onClickTitle">
<slot name="center">
<view
v-if="tools === 'title' && titleAlign === 'center' && title.length"
class="uni-navbar__header-container-inner"
>
<view v-if="tools === 'title' && titleAlign === 'center' && title.length"
class="uni-navbar__header-container-inner">
<text :style="{ color: themeColor, fontSize: '36rpx' }" class="ss-line-1">{{
title
}}</text>
@ -91,9 +74,17 @@
<script setup>
import sheep from '@/sheep';
import { onLoad } from '@dcloudio/uni-app';
import { showMenuTools, closeMenuTools } from '@/sheep/hooks/useModal';
import { computed, ref } from 'vue';
import {
onLoad
} from '@dcloudio/uni-app';
import {
showMenuTools,
closeMenuTools
} from '@/sheep/hooks/useModal';
import {
computed,
ref
} from 'vue';
/**
* NavBar 自定义导航栏
@ -117,10 +108,18 @@
const emits = defineEmits(['clickLeft', 'clickRight', 'clickTitle', 'search']);
const props = defineProps({
navBg: {
type: Boolean,
default: false,
},
dark: {
type: Boolean,
default: false,
},
headerBtns: {
type: String,
default: '',
},
modelValue: {
type: String,
default: '',
@ -211,9 +210,18 @@
};
});
const searchModel = computed(() => {
// const searchModel = computed(() => {
// return props.defaultSearch;
// });
const searchModel = computed({
get() {
return props.defaultSearch;
});
},
set(newValue) {
sheep.$router.go('/pages/index/search');
// props.defaultSearch = newValue
}
})
const themeBgColor = computed(() => {
if (props.dark) {
@ -248,7 +256,8 @@
});
function onSearch(e) {
emits('search', e.value);
sheep.$router.go('/pages/index/search');
// emits('search', e.value);
}
onLoad(() => {
@ -267,9 +276,11 @@
}
emits('clickLeft');
}
function onClickRight() {
showMenuTools();
}
function onClickTitle() {
emits('clickTitle');
}
@ -280,6 +291,7 @@
background: linear-gradient(90deg, var(--ui-BG-Main), var(--ui-BG-Main-gradient)) !important;
color: #fff !important;
}
.icon-box {
background: #ffffff;
box-shadow: 0px 0px 4rpx rgba(51, 51, 51, 0.08), 0px 4rpx 6rpx 2rpx rgba(102, 102, 102, 0.12);
@ -287,30 +299,37 @@
width: 134rpx;
height: 56rpx;
margin-left: 8rpx;
.line {
width: 2rpx;
height: 24rpx;
background: #e5e5e7;
}
.sicon-back {
font-size: 32rpx;
color: #000;
}
.sicon-home {
font-size: 32rpx;
color: #000;
}
.sicon-more {
font-size: 32rpx;
color: #000;
}
.icon-button {
width: 67rpx;
height: 56rpx;
&-left:hover {
background: rgba(0, 0, 0, 0.16);
border-radius: 30rpx 0px 0px 30rpx;
}
&-right:hover {
background: rgba(0, 0, 0, 0.16);
border-radius: 0px 30rpx 30rpx 0px;
@ -369,7 +388,7 @@
/* #endif */
padding: 0 10px;
flex-direction: row;
justify-content: space-between;
// justify-content: space-between;
height: $nav-height;
font-size: 12px;
position: relative;
@ -412,6 +431,7 @@
justify-content: flex-end;
align-items: center;
}
.uni-navbar__header-container {
/* #ifndef APP-NVUE */
// display: flex;
@ -478,6 +498,20 @@
}
//
.uni-dark {
.uni-dark {}
.new-view {
width: 40px;
height: 100%;
margin-right: 15px;
.new-image {
width: 100%;
height: 100%;
}
}
:deep(.uni-searchbar__box) {
height: 31px !important;
}
</style>

View File

@ -1,16 +1,26 @@
<!-- 自定义状态栏 -->
<template>
<view :style="{ height: statusBarHeight }" class="uni-status-bar"><slot /></view>
<view :style="{ height: statusBarHeight }" class="uni-status-bar" :class="navBg? 'ss' : ''">
<slot />
</view>
</template>
<script setup>
import sheep from '@/sheep';
const statusBarHeight = sheep.$platform.device.statusBarHeight + 'px';
const props = defineProps({
navBg: {
type: Boolean,
default: false,
}
})
const statusBarHeight = sheep.$platform.device.statusBarHeight - 2 + 'px';
</script>
<style lang="scss">
.uni-status-bar {
// width: 750rpx;
height: var(--status-bar-height);
}
.ss {
background: rgba(248, 83, 42);
}
</style>

View File

@ -226,7 +226,7 @@
</script>
<style lang="scss">
$uni-searchbar-height: 36px;
$uni-searchbar-height: 31px;
.uni-searchbar {
/* #ifndef APP-NVUE */