fix: 更新多个组件样式和功能以提升用户体验

- 在 myCollect.vue 中优化收藏页面的布局和样式,增加主题支持
- 在 searchPage.vue 中修复搜索组件的输入值设置逻辑
- 在 coupon/index.vue 中重构优惠券列表的展示逻辑,提升可用性
- 在 m-search-revision.vue 中调整搜索组件的样式和功能,增加清除图标的交互
- 在 pages.json 中禁用下拉刷新功能以改善性能
This commit is contained in:
Yer11214
2026-07-09 16:34:22 +08:00
parent f727e01ef0
commit 41e8cff749
9 changed files with 861 additions and 579 deletions

View File

@@ -1,17 +1,23 @@
<template> <template>
<view class="serach"> <view class="serach">
<view class="left-box" @tap="onClickLeft"> <view class="left-box" @tap="onClickLeft">
<u-icon name="arrow-left" size="28" color="#666"></u-icon> <u-icon name="arrow-left" size="28rpx" color="#606266"></u-icon>
</view> </view>
<view class="content" :style="{ 'border-radius': radius + 'px' }"> <view class="content" :style="{ 'border-radius': radius + 'px' }">
<!-- HM修改 增加进入输入状态的点击范围 --> <!-- HM修改 增加进入输入状态的点击范围 -->
<view class="content-box" :class="{ center: mode === 2 }"> <view class="content-box" :class="{ center: mode === 2 }">
<u-icon name="search" size="32" style="padding:0 15rpx;"></u-icon> <u-icon name="search" size="30rpx" color="#909399" style="padding:0 14rpx;"></u-icon>
<!-- HM修改 增加placeholder input confirm-type confirm--> <!-- HM修改 增加placeholder input confirm-type confirm-->
<input style="width:100%; " :placeholder="placeholder" placeholder-class="placeholder-color" <input style="width:100%; " :placeholder="placeholder" placeholder-class="placeholder-color"
@input="inputChange" confirm-type="search" @confirm="triggerConfirm" class="input" @input="inputChange" confirm-type="search" @confirm="triggerConfirm" class="input"
:class="{ center: !active && mode === 2 }" :focus="isFocus" v-model="inputVal" @focus="focus" @blur="blur" /> :class="{ center: !active && mode === 2 }" :focus="isFocus" v-model="inputVal" @focus="focus" @blur="blur" />
<u-icon name="close" v-if="showClear && isDelShow" style="padding:0 30rpx;" @click="clear"></u-icon> <view
class="clear-icon"
v-if="showClear && isDelShow"
@tap.stop.prevent="clear"
>
<u-icon name="close" size="28rpx" color="#909399"></u-icon>
</view>
</view> </view>
</view> </view>
@@ -21,8 +27,8 @@
</view> </view>
<view v-else class="button-item"> <view v-else class="button-item">
<u-icon name="grid-fill" size="32" @click="handelListClass()" v-if="!switchLayout"></u-icon> <u-icon name="grid-fill" size="32rpx" color="var(--theme-light, #ff6b35)" @click="handelListClass()" v-if="!switchLayout"></u-icon>
<u-icon v-else @click="handelListClass()" name="list-dot" size="32"></u-icon> <u-icon v-else @click="handelListClass()" name="list-dot" size="32rpx" color="var(--theme-light, #ff6b35)"></u-icon>
</view> </view>
</view> </view>
</view> </view>
@@ -34,6 +40,7 @@ import { ref, watch, onMounted } from 'vue'
const props = withDefaults(defineProps<{ const props = withDefaults(defineProps<{
mode?: number mode?: number
placeholder?: string placeholder?: string
modelValue?: string
value?: string value?: string
radius?: string radius?: string
isFocusVal?: boolean isFocusVal?: boolean
@@ -41,13 +48,14 @@ const props = withDefaults(defineProps<{
}>(), { }>(), {
mode: 1, mode: 1,
placeholder: "请输入搜索内容", placeholder: "请输入搜索内容",
modelValue: "",
value: "", value: "",
radius: "60", radius: "60",
isFocusVal: true, isFocusVal: true,
showClear: true, showClear: true,
}) })
const emit = defineEmits(['confirm', 'input', 'search', 'SwitchType']) const emit = defineEmits(['confirm', 'input', 'update:modelValue', 'search', 'SwitchType'])
const isShowSeachGoods = ref(false) const isShowSeachGoods = ref(false)
const active = ref(false) const active = ref(false)
@@ -58,6 +66,7 @@ const switchLayout = ref(true)
onMounted(() => { onMounted(() => {
isFocus.value = props.isFocusVal isFocus.value = props.isFocusVal
inputVal.value = props.modelValue || props.value || ''
}) })
// //
@@ -80,6 +89,7 @@ const triggerConfirm = () => {
const inputChange = (event: any) => { const inputChange = (event: any) => {
var keyword = event.detail.value var keyword = event.detail.value
emit("input", keyword) emit("input", keyword)
emit("update:modelValue", keyword)
if (inputVal.value) { if (inputVal.value) {
isDelShow.value = true isDelShow.value = true
} }
@@ -103,11 +113,19 @@ const clear = () => {
isFocus.value = false isFocus.value = false
inputVal.value = "" inputVal.value = ""
active.value = false active.value = false
isDelShow.value = false
//HM修改 清空内容时候触发组件input //HM修改 清空内容时候触发组件input
emit("input", "") emit("input", "")
emit("update:modelValue", "")
//this.$emit('search', '');//HM修改 清空内容时候不进行搜索 //this.$emit('search', '');//HM修改 清空内容时候不进行搜索
} }
const setInputValue = (value: string) => {
inputVal.value = value || ''
emit("input", inputVal.value)
emit("update:modelValue", inputVal.value)
}
/** /**
* 回退到上一级 * 回退到上一级
*/ */
@@ -144,6 +162,19 @@ const search = () => {
watch(inputVal, (newVal) => { watch(inputVal, (newVal) => {
newVal ? (isDelShow.value = true) : (isDelShow.value = false) newVal ? (isDelShow.value = true) : (isDelShow.value = false)
}) })
watch(() => props.modelValue, (newVal) => {
if (newVal !== inputVal.value) {
inputVal.value = newVal || ''
}
})
defineExpose({
isShowSeachGoods,
inputVal,
clear,
setInputValue,
})
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
@@ -195,6 +226,15 @@ watch(inputVal, (newVal) => {
width: auto; width: auto;
} }
} }
.clear-icon {
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
width: 72rpx;
height: 70rpx;
}
} }
} }

View File

@@ -126,7 +126,7 @@
"path": "myCollect", "path": "myCollect",
"style": { "style": {
"navigationBarTitleText": "收藏", "navigationBarTitleText": "收藏",
"enablePullDownRefresh": true, //下拉刷新 "enablePullDownRefresh": false,
"navigationStyle": "custom", "navigationStyle": "custom",
"app-plus": { "app-plus": {
"scrollIndicator": "none" "scrollIndicator": "none"

View File

@@ -1,84 +1,109 @@
<template> <template>
<div class="wrapper"> <view class="b-content" :style="themeStyle">
<view class="coupon-tabs">
<u-tabs <u-tabs
class="coupon-tabs"
:list="list" :list="list"
:scrollable="false" :scrollable="false"
:inactiveStyle="{ color: '#333' }"
v-model:current="current"
:lineColor="lightColor" :lineColor="lightColor"
:activeStyle="{ color: lightColor }" :activeStyle="{ color: lightColor }"
v-model:current="current" ></u-tabs>
> </view>
</u-tabs>
<scroll-view class="list-scroll-content" scroll-y>
<u-empty
mode="coupon"
text="暂无优惠券"
v-if="couponsList.length <= 0"
></u-empty>
<div class="empty" v-if="couponsList.length <= 0">
<u-empty text="暂无优惠券" mode="coupon"></u-empty>
</div>
<view class="coupon-item" v-for="(item, index) in couponsList" :key="index">
<view class="left">
<view class="wave-line">
<view class="wave" v-for="(item, index) in 12" :key="index"></view>
</view>
<view class="message">
<view>
<span v-if="item.couponType == 'DISCOUNT'">{{ item.discount }}</span>
<span v-else>{{ item.price }}</span>
</view>
<view>{{unitPrice(item.consumeThreshold) }}元可用</view>
</view>
<view class="circle circle-top"></view>
<view class="circle circle-bottom"></view>
</view>
<view class="right">
<view class="desc">
<view v-if="item.scopeType">
<span v-if="item.scopeType == 'ALL' && item.storeId == '0'">全平台</span>
<span v-if="item.scopeType == 'PORTION_GOODS_CATEGORY'">仅限品类</span>
<view v-else
>{{
item.storeName == "platform" ? "全平台" : item.storeName + "店铺"
}}使用</view
>
</view>
<view class="reason" v-if="item.reason">{{ item.reason }}</view>
<view class="end-time">有效期至:{{ item.endTime }}</view>
</view>
<view <view
class="receive" class="coupon-card"
v-if="current == 0 && !routerVal.selectedCoupon.includes(item.id)" :class="{ 'coupon-used': current != 0 }"
v-for="(item, index) in couponsList"
:key="item.id || index"
>
<view class="coupon-card-left">
<text class="coupon-price-symbol" v-if="item.couponType != 'DISCOUNT'">¥</text>
<text class="coupon-price-value">
{{ item.couponType == 'DISCOUNT' ? item.discount + '折' : unitPrice(item.price) }}
</text>
</view>
<view class="coupon-divider"></view>
<view class="coupon-card-right">
<view class="coupon-info">
<text class="coupon-card-name">
<template v-if="item.scopeType == 'ALL' && item.storeId == '0'">全平台</template>
<template v-else-if="item.scopeType == 'PORTION_GOODS_CATEGORY'">仅限品类</template>
<template v-else>
{{ item.storeName == 'platform' ? '全平台' : (item.storeName || '') + '店铺' }}
</template>
使用
</text>
<text class="coupon-card-desc">{{ unitPrice(item.consumeThreshold) }}元可用</text>
<text class="coupon-card-time" v-if="item.reason">{{ item.reason }}</text>
<text class="coupon-card-time" v-if="item.endTime">有效期至:{{ item.endTime }}</text>
</view>
<view
class="coupon-status-btn"
v-if="current == 0 && !isSelected(item)"
@click="clickWay(item)" @click="clickWay(item)"
> >
<text>立即</text><br /> 立即使用
<text>使用</text>
</view> </view>
<view class="used" v-if="current == 0 && routerVal.selectedCoupon.includes(item.id)" @click="clickWay(item)"> <view
<text>取消</text><br /> class="coupon-status-btn cancel"
<text>使用</text> v-else-if="current == 0 && isSelected(item)"
@click="clickWay(item)"
>
取消使用
</view> </view>
<view class="bg-quan"></view> <view class="coupon-status-btn disabled" v-else>
不可用
</view> </view>
</view> </view>
</div> </view>
</scroll-view>
</view>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, computed, watch, onMounted } from 'vue' import { ref, computed, watch, onMounted } from 'vue'
import { onLoad } from '@dcloudio/uni-app' import { onLoad } from '@dcloudio/uni-app'
import { useStore } from '@/store' import { useStore } from '@/store'
import { useCoupon } from '@/api/trade.js' import { useCoupon } from '@/api/trade.js'
import { unitPrice } from '@/utils/filters.js' import { unitPrice } from '@/utils/filters.js'
import { getThemeStyle } from '@/utils/theme'
const store = useStore() const store = useStore()
const lightColor = computed(() => store.getters.lightColor) const lightColor = computed(() => store.getters.lightColor)
const themeStyle = computed(() => getThemeStyle(store.state.theme))
const current = ref(0) const current = ref(0)
const list = [ const list = [
{ name: '可用优惠券' }, { name: '可用优惠券' },
{ name: '不可用优惠券' }, { name: '不可用优惠券' },
] ]
const couponsList = ref<any[]>([]) const couponsList = ref<any[]>([])
const routerVal = ref<Record<string, any>>({}) const routerVal = ref<Record<string, any>>({
selectedCoupon: [],
way: '',
})
onLoad((options) => { onLoad((options) => {
routerVal.value = options || {} const selectedCoupon = options?.selectedCoupon
let selected: string[] = []
if (Array.isArray(selectedCoupon)) {
selected = selectedCoupon
} else if (typeof selectedCoupon === 'string' && selectedCoupon) {
selected = selectedCoupon.split(',')
}
routerVal.value = {
...(options || {}),
selectedCoupon: selected,
}
}) })
watch(current, (val) => { watch(current, (val) => {
@@ -88,17 +113,17 @@ watch(current, (val) => {
}) })
onMounted(() => { onMounted(() => {
init() couponsList.value = store.state.canUseCoupons || []
}) })
function init() { function isSelected(coupon: any) {
couponsList.value = store.state.canUseCoupons return (routerVal.value.selectedCoupon || []).includes(coupon.id)
} }
function clickWay(coupon: any) { function clickWay(coupon: any) {
useCoupon({ useCoupon({
memberCouponId: coupon.id, memberCouponId: coupon.id,
used: !routerVal.value.selectedCoupon.includes(coupon.id), used: !isSelected(coupon),
way: routerVal.value.way, way: routerVal.value.way,
}).then((res) => { }).then((res) => {
if (res.data.success) { if (res.data.success) {
@@ -113,160 +138,186 @@ function clickWay(coupon: any) {
}) })
} }
</script> </script>
<style scoped lang="scss">
.desc { <style lang="scss" scoped>
height: 220rpx; .b-content {
flex: 2; background: #f7f8fa;
min-height: 100vh;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-content: space-around;
} }
.end-time,
.reason {
color: #999;
line-height: 1.5;
font-size: 24rpx;
}
.empty {
margin-top: 20px;
text-align: center;
}
.wrapper {
background: #f9f9f9;
overflow: hidden;
.coupon-tabs { .coupon-tabs {
background: #fff;
height: 88rpx;
box-shadow: 0 1rpx 8rpx rgba(0, 0, 0, 0.04);
position: relative;
z-index: 2;
flex-shrink: 0;
}
:deep(.u-tabs),
:deep(.u-tabs__wrapper),
:deep(.u-tabs__wrapper__scroll-view-wrapper),
:deep(.u-tabs__wrapper__scroll-view),
:deep(.u-tabs__wrapper__nav) {
background: #fff;
height: 88rpx;
}
:deep(.u-tabs__wrapper__nav__item) {
min-height: 88rpx;
}
:deep(.u-tabs__wrapper__nav__item__text) {
color: #333;
font-size: 28rpx;
}
.list-scroll-content {
flex: 1;
height: 0;
width: 100%; width: 100%;
padding: 24rpx;
box-sizing: border-box;
}
.coupon-card {
display: flex;
align-items: stretch;
background: #fff;
border-radius: 24rpx;
margin-bottom: 24rpx;
position: relative;
border: 1rpx solid #f0f1f5;
overflow: hidden;
&:active {
transform: scale(0.98);
}
&::before,
&::after {
content: '';
position: absolute;
width: 32rpx;
height: 32rpx;
background: #f7f8fa;
border-radius: 50%;
left: 204rpx;
z-index: 2;
box-shadow: inset 0 0 0 1rpx #eceef2;
}
&::before {
top: -16rpx;
}
&::after {
bottom: -16rpx;
}
&.coupon-used {
.coupon-card-left {
background: linear-gradient(135deg, #f5f5f5 0%, #eeeeee 100%);
color: #999;
}
}
}
.coupon-card-left {
width: 220rpx;
min-height: 180rpx;
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
color: #ff3b30;
position: relative;
background: linear-gradient(135deg, #fff5f5 0%, #ffecec 100%);
}
.coupon-price-symbol {
font-size: 32rpx;
font-weight: 700;
margin-right: 4rpx;
}
.coupon-price-value {
font-size: 56rpx;
font-weight: 900;
line-height: 1;
letter-spacing: -1rpx;
}
.coupon-divider {
position: absolute;
left: 220rpx;
top: 24rpx;
bottom: 24rpx;
width: 0;
border-left: 2rpx dashed #eceef2;
}
.coupon-card-right {
flex: 1;
padding: 32rpx 32rpx 32rpx 40rpx;
display: flex;
align-items: center;
justify-content: space-between;
gap: 20rpx;
background: #fff; background: #fff;
} }
}
.coupon-item {
display: flex;
align-items: center;
height: 220rpx;
margin: 20rpx;
.left { .coupon-info {
height: 100%;
width: 260rpx;
background-color: $light-color;
position: relative;
.message {
color: $font-color-white;
display: flex; display: flex;
justify-content: center;
align-items: center;
flex-direction: column; flex-direction: column;
margin-top: 40rpx; gap: 12rpx;
flex: 1;
view:nth-child(1) { min-width: 0;
font-weight: bold;
font-size: 60rpx;
} }
view:nth-child(2) { .coupon-card-name {
font-size: $font-sm;
}
}
.wave-line {
height: 220rpx;
width: 8rpx;
position: absolute;
top: 0;
left: 0;
background-color: $light-color;
overflow: hidden;
.wave {
width: 8rpx;
height: 16rpx;
background-color: #ffffff;
border-radius: 0 16rpx 16rpx 0;
margin-top: 4rpx;
}
}
.circle {
width: 40rpx;
height: 40rpx;
background-color: $bg-color;
position: absolute;
border-radius: 50%;
z-index: 111;
}
.circle-top {
top: -20rpx;
right: -20rpx;
}
.circle-bottom {
bottom: -20rpx;
right: -20rpx;
}
}
.right {
display: flex;
justify-content: space-between;
align-items: center;
width: 450rpx;
font-size: $font-sm;
height: 220rpx;
background-color: #ffffff;
overflow: hidden;
position: relative;
> view:nth-child(1) {
color: #666666;
margin-left: 20rpx;
> view:nth-child(1) {
color: #ff6262;
font-size: 30rpx; font-size: 30rpx;
} color: #111;
font-weight: 700;
line-height: 1.3;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
} }
.receive { .coupon-card-desc {
color: #ffffff; font-size: 24rpx;
background-color: $main-color; color: #8a8f99;
border-radius: 50%; font-weight: 500;
width: 86rpx;
height: 86rpx;
text-align: center;
margin-right: 30rpx;
vertical-align: middle;
padding-top: 8rpx;
position: relative;
z-index: 2;
} }
.used { .coupon-card-time {
color: #ffffff; font-size: 22rpx;
background-color: black; color: #b0b3bf;
border-radius: 50%;
width: 86rpx;
height: 86rpx;
text-align: center;
margin-right: 30rpx;
vertical-align: middle;
padding-top: 8rpx;
position: relative;
z-index: 2;
} }
.bg-quan { .coupon-status-btn {
width: 244rpx; flex-shrink: 0;
height: 244rpx; padding: 16rpx 28rpx;
border: 6rpx solid $main-color; border-radius: 40rpx;
border-radius: 50%; font-size: 26rpx;
opacity: 0.1; font-weight: 700;
color: $main-color; color: #fff;
text-align: center; background: linear-gradient(135deg, var(--theme-light, #ff6b35), var(--theme-primary, #ff4b2b));
padding-top: 30rpx;
font-size: 130rpx; &:active {
position: absolute; opacity: 0.9;
right: -54rpx;
bottom: -60rpx;
} }
&.cancel {
background: #333;
}
&.disabled {
background: #ccc;
} }
} }
</style> </style>

View File

@@ -1,29 +1,42 @@
<template> <template>
<view class="content"> <view class="page" :style="themeStyle">
<u-navbar <u-navbar
title="收藏"
:fixed="true" :fixed="true"
:placeholder="true" :placeholder="true"
:border="false" :border="false"
:auto-back="true" :auto-back="true"
title="" ></u-navbar>
>
<template #center> <view class="tabs-wrap">
<view class="slot-wrap">
<u-tabs <u-tabs
:lineColor="lightColor"
:activeStyle="{ color: lightColor }"
class="collect-tabs"
:list="navList" :list="navList"
:scrollable="false" :scrollable="false"
:lineColor="lightColor"
:activeStyle="{ color: lightColor, fontWeight: '600' }"
:inactiveStyle="{ color: '#666' }"
v-model:current="tabCurrentIndex" v-model:current="tabCurrentIndex"
@change="onTabChange"
></u-tabs> ></u-tabs>
</view> </view>
</template>
</u-navbar> <scroll-view
<view class="collect-body"> class="list-scroll"
<!-- 显示商品栏 --> scroll-y
enable-back-to-top
:refresher-enabled="true"
:refresher-triggered="refreshing"
@refresherrefresh="onRefresh"
@scrolltolower="loadMore"
>
<!-- 商品 -->
<view v-if="tabCurrentIndex === 0" class="tab-content"> <view v-if="tabCurrentIndex === 0" class="tab-content">
<u-empty style="margin-top: 40rpx" text="暂无收藏商品数据" mode="favor" v-if="goodsEmpty"></u-empty> <u-empty
v-if="!goodsLoading && goodsEmpty"
class="empty-box"
text="暂无收藏商品"
mode="favor"
></u-empty>
<template v-else> <template v-else>
<u-swipe-action <u-swipe-action
v-for="(item, index) in goodsList" v-for="(item, index) in goodsList"
@@ -34,26 +47,34 @@
@open="openSwipeItem(item, 'goods')" @open="openSwipeItem(item, 'goods')"
:show="item.selected" :show="item.selected"
:options="swipeOptions" :options="swipeOptions"
@click="removeGoodsCollection(item, index)" @click="removeGoodsCollection(item)"
:name="index" :name="index"
> >
<view class="goods" @click="goGoodsDetail(item)"> <view class="goods" @click="goGoodsDetail(item)">
<u-image width="131rpx" height="131rpx" :src="item.image" mode="aspectFit"> <u-image width="140rpx" height="140rpx" radius="12rpx" :src="item.image" mode="aspectFill">
<template #loading><u-loading-icon></u-loading-icon></template> <template #loading><u-loading-icon></u-loading-icon></template>
</u-image> </u-image>
<view class="goods-intro"> <view class="goods-intro">
<view class="goods-name">{{ item.goodsName }}</view> <view class="goods-name wes-2">{{ item.goodsName }}</view>
<view class="goods-sn">{{ item.goods_sn }}</view>
<view class="goods-price">{{ unitPrice(item.price) }}</view> <view class="goods-price">{{ unitPrice(item.price) }}</view>
</view> </view>
</view> </view>
</u-swipe-action-item> </u-swipe-action-item>
</u-swipe-action> </u-swipe-action>
<view class="load-status" v-if="goodsList.length">
{{ goodsFinished ? '没有更多了' : goodsLoading ? '加载中...' : '上拉加载更多' }}
</view>
</template> </template>
</view> </view>
<!-- 显示收藏的店铺栏 -->
<!-- 店铺 -->
<view v-else class="tab-content"> <view v-else class="tab-content">
<u-empty style="margin-top: 40rpx" text="暂无收藏店铺数据" mode="favor" v-if="storeEmpty"></u-empty> <u-empty
v-if="!storeLoading && storeEmpty"
class="empty-box"
text="暂无收藏店铺"
mode="favor"
></u-empty>
<template v-else> <template v-else>
<u-swipe-action <u-swipe-action
v-for="(item, index) in storeList" v-for="(item, index) in storeList"
@@ -68,36 +89,51 @@
:name="index" :name="index"
> >
<view class="store" @click="goStoreMainPage(item.id)"> <view class="store" @click="goStoreMainPage(item.id)">
<view class="intro">
<view class="store-logo"> <view class="store-logo">
<u-image width="102rpx" height="102rpx" :src="item.storeLogo" :alt="item.storeName" <u-image
mode="aspectFit"> width="96rpx"
height="96rpx"
shape="circle"
:src="item.storeLogo"
mode="aspectFill"
>
<template #loading><u-loading-icon></u-loading-icon></template> <template #loading><u-loading-icon></u-loading-icon></template>
</u-image> </u-image>
</view> </view>
<view class="store-name"> <view class="store-info">
<view>{{ item.storeName }}</view> <view class="store-name-row">
<u-tag size="mini" type="error" :color="mainColor" v-if="item.selfOperated" <text class="store-name wes">{{ item.storeName }}</text>
text="自营" mode="plain" shape="circle" /> <u-tag
</view> v-if="item.selfOperated"
<view class="store-collect"> size="mini"
<view>进店逛逛</view> type="error"
:color="mainColor"
text="自营"
plain
shape="circle"
/>
</view> </view>
<view class="store-tip">左滑可取消收藏</view>
</view> </view>
<view class="store-enter">进店逛逛</view>
</view> </view>
</u-swipe-action-item> </u-swipe-action-item>
</u-swipe-action> </u-swipe-action>
<view class="load-status" v-if="storeList.length">
{{ storeFinished ? '没有更多了' : storeLoading ? '加载中...' : '上拉加载更多' }}
</view>
</template> </template>
</view> </view>
</view> </scroll-view>
</view> </view>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, computed } from 'vue' import { ref, computed } from 'vue'
import { onShow, onReachBottom, onPullDownRefresh } from '@dcloudio/uni-app' import { onShow } from '@dcloudio/uni-app'
import { useStore } from '@/store' import { useStore } from '@/store'
import { unitPrice } from '@/utils/filters.js' import { unitPrice } from '@/utils/filters.js'
import { getThemeStyle } from '@/utils/theme'
import { import {
getGoodsCollection, getGoodsCollection,
getStoreCollection, getStoreCollection,
@@ -109,6 +145,7 @@ const store = useStore()
const lightColor = computed(() => store.getters.lightColor) const lightColor = computed(() => store.getters.lightColor)
const mainColor = computed(() => store.getters.mainColor) const mainColor = computed(() => store.getters.mainColor)
const themeStyle = computed(() => getThemeStyle(store.state.theme))
const swipeOptions = computed(() => [ const swipeOptions = computed(() => [
{ {
@@ -119,55 +156,93 @@ const swipeOptions = computed(() => [
const tabCurrentIndex = ref(0) const tabCurrentIndex = ref(0)
const navList = ref([ const navList = ref([
{ name: '商品(0)', params: { pageNumber: 1, pageSize: 10 } }, { name: '商品(0)' },
{ name: '店铺(0)', params: { pageNumber: 1, pageSize: 10 } }, { name: '店铺(0)' },
]) ])
const goodsParams = ref({ pageNumber: 1, pageSize: 10 })
const storeParams = ref({ pageNumber: 1, pageSize: 10 })
const goodsEmpty = ref(false) const goodsEmpty = ref(false)
const storeEmpty = ref(false) const storeEmpty = ref(false)
const goodsList = ref<any[]>([]) const goodsList = ref<any[]>([])
const storeList = ref<any[]>([]) const storeList = ref<any[]>([])
const goodsLoading = ref(false)
const storeLoading = ref(false)
const goodsFinished = ref(false)
const storeFinished = ref(false)
const refreshing = ref(false)
const inited = ref(false)
onShow(() => { onShow(() => {
reloadOrLoadMore('reload') if (!inited.value) {
}) inited.value = true
reloadAll()
onReachBottom(() => { return
reloadOrLoadMore('next')
})
onPullDownRefresh(() => {
if (tabCurrentIndex.value === 0) {
navList.value[0].params.pageNumber = 1
goodsList.value = []
fetchGoodsList()
} else {
navList.value[1].params.pageNumber = 1
storeList.value = []
fetchStoreList()
} }
reloadCurrent()
}) })
function hideLoadingIfNeeded() { function hideLoadingIfNeeded() {
if (store.state.isShowToast) uni.hideLoading() if (store.state.isShowToast) uni.hideLoading()
} }
function reloadOrLoadMore(type: 'reload' | 'next') { function onTabChange(e: any) {
if (type === 'next') { const index = typeof e === 'number' ? e : e?.index
navList.value[tabCurrentIndex.value].params.pageNumber++ if (typeof index === 'number') {
tabCurrentIndex.value = index
}
if (tabCurrentIndex.value === 0 && !goodsList.value.length && !goodsEmpty.value) {
reloadGoods()
}
if (tabCurrentIndex.value === 1 && !storeList.value.length && !storeEmpty.value) {
reloadStore()
}
}
function onRefresh() {
refreshing.value = true
reloadCurrent()
}
function loadMore() {
if (tabCurrentIndex.value === 0) { if (tabCurrentIndex.value === 0) {
if (goodsLoading.value || goodsFinished.value || goodsEmpty.value) return
goodsParams.value.pageNumber++
fetchGoodsList() fetchGoodsList()
} else { } else {
if (storeLoading.value || storeFinished.value || storeEmpty.value) return
storeParams.value.pageNumber++
fetchStoreList() fetchStoreList()
} }
return
} }
navList.value[0].params.pageNumber = 1
navList.value[1].params.pageNumber = 1 function reloadAll() {
reloadGoods()
reloadStore()
}
function reloadCurrent() {
if (tabCurrentIndex.value === 0) {
reloadGoods()
} else {
reloadStore()
}
}
function reloadGoods() {
goodsParams.value.pageNumber = 1
goodsFinished.value = false
goodsEmpty.value = false goodsEmpty.value = false
storeEmpty.value = false
goodsList.value = [] goodsList.value = []
storeList.value = []
fetchGoodsList() fetchGoodsList()
}
function reloadStore() {
storeParams.value.pageNumber = 1
storeFinished.value = false
storeEmpty.value = false
storeList.value = []
fetchStoreList() fetchStoreList()
} }
@@ -182,9 +257,7 @@ function openSwipeItem(val: any, type: 'goods' | 'store') {
function removeGoodsCollection(val: any) { function removeGoodsCollection(val: any) {
deleteGoodsCollection(val.skuId).then((res) => { deleteGoodsCollection(val.skuId).then((res) => {
if (res.statusCode === 200) { if (res.statusCode === 200) {
goodsList.value = [] reloadGoods()
navList.value[0].params.pageNumber = 1
fetchGoodsList()
} }
}) })
} }
@@ -192,9 +265,7 @@ function removeGoodsCollection(val: any) {
function removeStoreCollection(val: any) { function removeStoreCollection(val: any) {
deleteStoreCollection(val.id).then((res) => { deleteStoreCollection(val.id).then((res) => {
if (res.statusCode === 200) { if (res.statusCode === 200) {
storeList.value = [] reloadStore()
navList.value[1].params.pageNumber = 1
fetchStoreList()
} }
}) })
} }
@@ -212,91 +283,106 @@ function goStoreMainPage(id: string) {
} }
function fetchGoodsList() { function fetchGoodsList() {
if (goodsLoading.value) return
goodsLoading.value = true
uni.showLoading({ title: '加载中' }) uni.showLoading({ title: '加载中' })
getGoodsCollection(navList.value[0].params, 'GOODS') getGoodsCollection(goodsParams.value, 'GOODS')
.then((res) => { .then((res) => {
goodsLoading.value = false
refreshing.value = false
hideLoadingIfNeeded() hideLoadingIfNeeded()
uni.stopPullDownRefresh()
if (res.data.success) { if (res.data.success) {
const data = res.data.result const data = res.data.result
navList.value[0].name = `商品(${data.total})` navList.value[0].name = `商品(${data.total || 0})`
goodsEmpty.value = data.total === 0 goodsEmpty.value = !data.total
if (data.records?.length) { const records = (data.records || []).map((item: any) => ({
const records = data.records.map((item: any) => ({ ...item, selected: false })) ...item,
selected: false,
}))
if (goodsParams.value.pageNumber === 1) {
goodsList.value = records
} else {
goodsList.value.push(...records) goodsList.value.push(...records)
} }
goodsFinished.value =
!records.length || goodsList.value.length >= (data.total || 0)
} }
}) })
.catch(() => { .catch(() => {
goodsLoading.value = false
refreshing.value = false
hideLoadingIfNeeded() hideLoadingIfNeeded()
uni.stopPullDownRefresh()
}) })
} }
function fetchStoreList() { function fetchStoreList() {
if (storeLoading.value) return
storeLoading.value = true
uni.showLoading({ title: '加载中' }) uni.showLoading({ title: '加载中' })
getStoreCollection(navList.value[1].params, 'STORE') getStoreCollection(storeParams.value, 'STORE')
.then((res) => { .then((res) => {
storeLoading.value = false
refreshing.value = false
hideLoadingIfNeeded() hideLoadingIfNeeded()
uni.stopPullDownRefresh()
if (res.data.success) { if (res.data.success) {
const data = res.data.result const data = res.data.result
navList.value[1].name = `店铺(${data.total})` navList.value[1].name = `店铺(${data.total || 0})`
storeEmpty.value = data.total === 0 storeEmpty.value = !data.total
if (data.records?.length) { const records = (data.records || []).map((item: any) => ({
const records = data.records.map((item: any) => ({ ...item, selected: false })) ...item,
selected: false,
}))
if (storeParams.value.pageNumber === 1) {
storeList.value = records
} else {
storeList.value.push(...records) storeList.value.push(...records)
} }
storeFinished.value =
!records.length || storeList.value.length >= (data.total || 0)
} }
}) })
.catch(() => { .catch(() => {
storeLoading.value = false
refreshing.value = false
hideLoadingIfNeeded() hideLoadingIfNeeded()
uni.stopPullDownRefresh()
}) })
} }
</script> </script>
<style lang="scss"> <style lang="scss">
page, page {
.content { background: #f8f8f8;
background: $page-color-base;
height: 100%; height: 100%;
} }
</style>
.content { <style lang="scss" scoped>
width: 100%; .page {
height: 100vh;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
min-height: 100vh; background: #f8f8f8;
}
.slot-wrap {
flex: 1;
display: flex;
justify-content: center;
padding: 0 20rpx;
box-sizing: border-box; box-sizing: border-box;
} }
.collect-tabs { .tabs-wrap {
width: 100%; flex-shrink: 0;
background: #fff;
border-bottom: 1rpx solid #f0f0f0;
} }
.collect-body { .list-scroll {
flex: 1; flex: 1;
width: 100%; height: 0;
min-height: 0;
} }
.tab-content { .tab-content {
width: 100%; padding-bottom: calc(24rpx + env(safe-area-inset-bottom));
} }
:deep(.u-tabs), .empty-box {
:deep(.u-tabs__wrapper), margin-top: 120rpx;
:deep(.u-tabs__wrapper__scroll-view-wrapper),
:deep(.u-tabs__wrapper__scroll-view),
:deep(.u-tabs__wrapper__nav) {
width: 100%;
} }
.collect-swipe, .collect-swipe,
@@ -311,84 +397,96 @@ function fetchStoreList() {
} }
.goods { .goods {
background-color: #fff;
border-bottom: 1px solid $border-color-light;
min-height: 190rpx;
box-sizing: border-box;
display: flex; display: flex;
align-items: center; align-items: center;
padding: 30rpx 20rpx;
margin-top: 20rpx;
width: 100%; width: 100%;
box-sizing: border-box;
padding: 24rpx;
margin-top: 16rpx;
background: #fff;
.goods-intro { .goods-intro {
flex: 1; flex: 1;
min-width: 0; min-width: 0;
font-size: $font-base; margin-left: 24rpx;
line-height: 48rpx; display: flex;
margin-left: 30rpx; flex-direction: column;
justify-content: space-between;
.goods-name { min-height: 140rpx;
line-height: 1.4em;
font-size: 24rpx;
max-height: 2.8em;
overflow: hidden;
color: #666;
} }
.goods-sn { .goods-name {
color: #cccccc; font-size: 28rpx;
font-size: 24rpx; color: #333;
line-height: 1.4;
} }
.goods-price { .goods-price {
color: $light-color; margin-top: 16rpx;
} font-size: 32rpx;
font-weight: 600;
color: var(--theme-light, #ff6b35);
} }
} }
.store { .store {
background-color: #fff;
border: 1px solid $border-color-light;
border-radius: 16rpx;
margin: 20rpx 10rpx;
width: calc(100% - 20rpx);
box-sizing: border-box;
.intro {
display: flex; display: flex;
justify-content: space-between;
align-items: center; align-items: center;
padding: 0 30rpx 0 40rpx; box-sizing: border-box;
min-height: 170rpx; width: calc(100% - 32rpx);
margin: 16rpx auto 0;
padding: 24rpx;
background: #fff;
border-radius: 16rpx;
}
.store-logo { .store-logo {
width: 102rpx; flex-shrink: 0;
height: 102rpx; width: 96rpx;
height: 96rpx;
border-radius: 50%; border-radius: 50%;
overflow: hidden; overflow: hidden;
flex-shrink: 0; background: #f5f5f5;
}
.store-info {
flex: 1;
min-width: 0;
margin: 0 20rpx;
}
.store-name-row {
display: flex;
align-items: center;
gap: 12rpx;
} }
.store-name { .store-name {
flex: 1; max-width: 360rpx;
min-width: 0; font-size: 30rpx;
margin-left: 30rpx; font-weight: 600;
line-height: 2em; color: #333;
:first-child {
font-size: $font-base;
}
} }
.store-collect { .store-tip {
flex-shrink: 0; margin-top: 10rpx;
border-left: 1px solid $border-color-light; font-size: 22rpx;
padding-left: 20rpx;
text-align: center;
color: #999; color: #999;
font-size: $font-sm;
} }
.store-enter {
flex-shrink: 0;
padding: 12rpx 20rpx;
border-radius: 100px;
border: 1rpx solid var(--theme-light, #ff6b35);
color: var(--theme-light, #ff6b35);
font-size: 24rpx;
} }
.load-status {
padding: 24rpx 0 8rpx;
text-align: center;
font-size: 24rpx;
color: #999;
} }
</style> </style>

View File

@@ -15,7 +15,6 @@
<mSearch <mSearch
ref="mSearchRef" ref="mSearchRef"
class="mSearch-input-box" class="mSearch-input-box"
:show-clear="false"
@clickLeft="back" @clickLeft="back"
:mode="2" :mode="2"
:placeholder="defaultKeyword" :placeholder="defaultKeyword"
@@ -271,7 +270,7 @@ import storage from '@/utils/storage'
const store = useStore() const store = useStore()
const { proxy } = getCurrentInstance()! const { proxy } = getCurrentInstance()!
const mSearchRef = ref<InstanceType<typeof mSearch> | null>(null) const mSearchRef = ref<any>(null)
const empty = ref(false) const empty = ref(false)
const scrollTop = ref(0) const scrollTop = ref(0)
@@ -806,7 +805,7 @@ function doSearch(searchKeyword: string | false) {
isShowSeachGoods.value = true isShowSeachGoods.value = true
if (mSearchRef.value) { if (mSearchRef.value) {
mSearchRef.value.isShowSeachGoods = true mSearchRef.value.isShowSeachGoods = true
mSearchRef.value.inputVal = resolvedKeyword mSearchRef.value.setInputValue(resolvedKeyword)
} }
params.value.keyword = keyword.value params.value.keyword = keyword.value
params.value.pageNumber = 1 params.value.pageNumber = 1

View File

@@ -247,6 +247,26 @@ page {
position: relative; position: relative;
z-index: 10; z-index: 10;
background: #ffffff; background: #ffffff;
height: 88rpx;
box-shadow: 0 1rpx 8rpx rgba(0, 0, 0, 0.04);
}
:deep(.u-tabs),
:deep(.u-tabs__wrapper),
:deep(.u-tabs__wrapper__scroll-view-wrapper),
:deep(.u-tabs__wrapper__scroll-view),
:deep(.u-tabs__wrapper__nav) {
background: #fff;
height: 88rpx;
}
:deep(.u-tabs__wrapper__nav__item) {
min-height: 88rpx;
}
:deep(.u-tabs__wrapper__nav__item__text) {
color: #333;
font-size: 28rpx;
} }
.box-content { .box-content {
margin: 20rpx 0; margin: 20rpx 0;

View File

@@ -1,6 +1,12 @@
<template> <template>
<div class="page"> <div class="page" :style="themeStyle">
<u-navbar :auto-back="false" @leftClick="back" left-icon-color="#fff" :bg-color="background.backgroundColor" :border="false"> <u-navbar
:auto-back="false"
@leftClick="back"
left-icon-color="#fff"
:bg-color="background.backgroundColor"
:border="false"
>
</u-navbar> </u-navbar>
<div class="wrapper-box"> <div class="wrapper-box">
@@ -9,7 +15,7 @@
<div class="bargain"> <div class="bargain">
<div class="flex bargain-item"> <div class="flex bargain-item">
<div class="goods-img"> <div class="goods-img">
<u-image width="200" height="200" :src="bargainDetail.thumbnail"></u-image> <u-image width="200rpx" height="200rpx" :src="bargainDetail.thumbnail"></u-image>
</div> </div>
<div class="goods-config"> <div class="goods-config">
<div class="goods-title wes-2"> <div class="goods-title wes-2">
@@ -17,18 +23,22 @@
</div> </div>
<div class="flex price-box"> <div class="flex price-box">
<div class="purchase-price"> <div class="purchase-price">
当前:<span>{{ activityData.surplusPrice == 0 ? bargains.purchasePrice : unitPrice(activityData.surplusPrice)}}</span> 当前:<text>{{ activityData.surplusPrice == 0 ? bargains.purchasePrice : unitPrice(activityData.surplusPrice) }}</text>
</div>
<div class="max-price">原价:<span>{{unitPrice(bargainDetail.price)}}</span>
</div> </div>
<div class="max-price">原价:<text>{{ unitPrice(bargainDetail.price) }}</text></div>
</div> </div>
<div class="tips">{{ bargainDetail.sellingPoint }}</div> <div class="tips">{{ bargainDetail.sellingPoint }}</div>
</div> </div>
</div> </div>
<!-- 砍价进度 --> <!-- 砍价进度 -->
<div class="bargain-progress"> <div class="bargain-progress">
<u-line-progress class="line" :active-color="lightColor" striped striped-active :percent="totalPercent"> <u-line-progress
class="line"
:active-color="lightColor"
:percentage="totalPercent"
:show-text="false"
height="12"
>
</u-line-progress> </u-line-progress>
<div class="flex tips"> <div class="flex tips">
<div>已砍{{ cutPrice }}</div> <div>已砍{{ cutPrice }}</div>
@@ -41,14 +51,12 @@
</div> </div>
<!-- 立即购买 --> <!-- 立即购买 -->
<div v-else> <div v-else>
<div v-if="activityData.status != 'END'" class="buy" @click="getGoodsDetail"> <div v-if="activityData.status != 'END'" class="buy" @click="getGoodsDetail">
立即购买 立即购买
</div> </div>
</div> </div>
<!-- 我要开团 --> <!-- 我要开团 -->
<div class="start" v-if="activityData.memberId != loginUser.id" @click="startOpenGroup">我要开团 <div class="start" v-if="activityData.memberId != loginUser.id" @click="startOpenGroup">我要开团</div>
</div>
</div> </div>
</div> </div>
<!-- 帮砍列表 --> <!-- 帮砍列表 -->
@@ -57,14 +65,14 @@
<div class="bargain-title">帮忙砍</div> <div class="bargain-title">帮忙砍</div>
<div class="user-item flex" v-if="logData.length != 0" v-for="(item, index) in logData" :key="index"> <div class="user-item flex" v-if="logData.length != 0" v-for="(item, index) in logData" :key="index">
<div> <div>
<u-image width="75" shape="circle" height="75" :src="item.kanjiaMemberFace"></u-image> <u-image width="75rpx" shape="circle" height="75rpx" :src="item.kanjiaMemberFace"></u-image>
</div> </div>
<div class="user-config flex"> <div class="user-config flex">
<div class="user-name"> <div class="user-name">
<div>{{ noPassByName(item.kanjiaMemberName) }}</div> <div>{{ noPassByName(item.kanjiaMemberName) }}</div>
<div>使出吃的奶劲儿</div> <div>使出吃的奶劲儿</div>
</div> </div>
<div class="save">砍掉<span>{{unitPrice(item.kanjiaPrice)}}</span></div> <div class="save">砍掉<text>{{ unitPrice(item.kanjiaPrice) }}</text></div>
</div> </div>
</div> </div>
</div> </div>
@@ -76,36 +84,61 @@
<view class="u-content"> <view class="u-content">
<u-parse :content="bargainDetail.mobileIntro" :tag-style="style"></u-parse> <u-parse :content="bargainDetail.mobileIntro" :tag-style="style"></u-parse>
</view> </view>
</div> </div>
</div> </div>
<!-- 砍价 --> <!-- 砍价 -->
<u-modal title="恭喜您砍掉了" v-model:show="Bargaining" mask-close-able :show-confirm-button="false" <u-modal
:title-style="{color: lightColor}"> title="恭喜您砍掉了"
v-model:show="Bargaining"
:close-on-click-overlay="true"
:show-confirm-button="false"
>
<view class="slot-content"> <view class="slot-content">
<u-count-to :start-val="0" ref="uCountToRef" font-size="100" :color="lightColor" :end-val="kanjiaPrice" <u-count-to
:decimals="2" :autoplay="autoplay"></u-count-to><span class="price"></span> :start-val="0"
ref="uCountToRef"
font-size="100"
:color="lightColor"
:end-val="kanjiaPrice"
:decimals="2"
:autoplay="autoplay"
></u-count-to>
<text class="price"></text>
</view> </view>
</u-modal> </u-modal>
<!-- 帮砍 --> <!-- 帮砍 -->
<u-modal title=" " v-model:show="helpBargainFlage" :show-confirm-button="false">
<u-modal :show-title="false" v-model:show="helpBargainFlage" :show-confirm-button="false">
<view class="help-bargain" @click="handleClickHelpBargain"> <view class="help-bargain" @click="handleClickHelpBargain">
<u-image width="100%" height="600rpx" <u-image
src="https://lilishop-oss.oss-cn-beijing.aliyuncs.com/91631d5a66c7426bbe3f7d644ee41946.jpeg"></u-image> width="100%"
height="600rpx"
src="https://lilishop-oss.oss-cn-beijing.aliyuncs.com/91631d5a66c7426bbe3f7d644ee41946.jpeg"
></u-image>
<u-image class="help" width="300rpx" height="80rpx" src="/pages/promotion/static/help-bargain.png"></u-image> <u-image class="help" width="300rpx" height="80rpx" src="/pages/promotion/static/help-bargain.png"></u-image>
</view> </view>
</u-modal> </u-modal>
<!-- 分享 --> <!-- 分享 -->
<shares @close="closeShare" :link="share()" type="kanjia" :thumbnail="bargainDetail.thumbnail" <shares
:goodsName="bargainDetail.goodsName" v-if="shareFlage " /> @close="closeShare"
:link="share()"
type="kanjia"
:thumbnail="bargainDetail.thumbnail"
:goodsName="bargainDetail.goodsName"
v-if="shareFlage"
/>
<!-- 购买 --> <!-- 购买 -->
<popupGoods ref="popupGoodsRef" :buyMask="maskFlag" @closeBuy="closePopupBuy" :goodsDetail="bargainDetail" <popupGoods
:goodsSpec="goodsSpec" v-if="bargainDetail.id " @handleClickSku="getGoodsDetail" /> ref="popupGoodsRef"
:buyMask="maskFlag"
@closeBuy="closePopupBuy"
:goodsDetail="bargainDetail"
:goodsSpec="goodsSpec"
v-if="bargainDetail.id"
@handleClickSku="getGoodsDetail"
/>
</div> </div>
</div> </div>
</template> </template>
@@ -128,10 +161,12 @@ import {
import shares from '@/components/m-share/index' import shares from '@/components/m-share/index'
import config from '@/config/config' import config from '@/config/config'
import { unitPrice, noPassByName, isLogin } from '@/utils/filters.js' import { unitPrice, noPassByName, isLogin } from '@/utils/filters.js'
import { getThemeStyle } from '@/utils/theme'
const store = useStore() const store = useStore()
const lightColor = computed(() => store.getters.lightColor) const lightColor = computed(() => store.getters.lightColor)
const themeStyle = computed(() => getThemeStyle(store.state.theme))
const style = ref({ const style = ref({
img: 'display:block', img: 'display:block',
@@ -205,8 +240,7 @@ watch(
(val) => { (val) => {
if (val) { if (val) {
totalPercent.value = totalPercent.value =
100 - 100 - Math.floor((val.surplusPrice / bargainDetail.value.price) * 100)
Math.floor((val.surplusPrice / bargainDetail.value.price) * 100)
cutPrice.value = ( cutPrice.value = (
bargainDetail.value.price - activityData.value.surplusPrice bargainDetail.value.price - activityData.value.surplusPrice
).toFixed(2) ).toFixed(2)
@@ -324,32 +358,44 @@ async function openActivity() {
} }
} }
</script> </script>
<style lang="scss"> <style lang="scss">
page { page {
background-color: $light-color !important; background-color: var(--theme-light, #ff6b35) !important;
} }
</style> </style>
<style lang="scss" scoped> <style lang="scss" scoped>
.page {
min-height: 100vh;
box-sizing: border-box;
padding-bottom: 40rpx;
}
.slot-content { .slot-content {
display: flex; display: flex;
align-items: flex-end; align-items: flex-end;
justify-content: center; justify-content: center;
margin: 20rpx 0 80rpx 0; margin: 20rpx 0 80rpx 0;
} }
.price { .price {
margin-left: 10rpx; margin-left: 10rpx;
color: $light-color; color: var(--theme-light, #ff6b35);
} }
.price-box { .price-box {
align-items: center; align-items: center;
padding: 10rpx 0; padding: 10rpx 0;
} }
.wrapper-box { .wrapper-box {
background: url("https://lili-system.oss-cn-beijing.aliyuncs.com/kanjia.png"); background: url('https://lili-system.oss-cn-beijing.aliyuncs.com/kanjia.png') no-repeat top center;
background-repeat: no-repeat; background-size: 100% 506rpx;
background-size: 100% 100%;
height: 506rpx;
width: 100%; width: 100%;
box-sizing: border-box;
padding-top: 420rpx;
padding-bottom: 40rpx;
} }
.box { .box {
@@ -357,99 +403,92 @@ page {
border-radius: 20rpx; border-radius: 20rpx;
position: relative; position: relative;
width: 94%; width: 94%;
margin: 0 auto; margin: 0 auto 20rpx;
overflow: hidden;
> .bargain { > .bargain {
padding: 32rpx; padding: 32rpx;
} }
} }
.box1 {
top: 560rpx;
}
.box2 {
top: 580rpx;
}
.box3 {
top: 600rpx;
}
.box4 {
top: 620 rpx;
height: 200rpx;
}
.bargain-item { .bargain-item {
align-items: center; align-items: center;
} }
.goods-img {
flex-shrink: 0;
}
.goods-config { .goods-config {
flex: 1;
min-width: 0;
margin-left: 20rpx; margin-left: 20rpx;
> .goods-title { > .goods-title {
font-weight: bold; font-weight: bold;
font-size: 28rpx;
color: #333;
line-height: 1.4;
} }
} }
.max-price, .max-price,
.purchase-price { .purchase-price {
font-size: 24rpx; font-size: 24rpx;
color: #999; color: #999;
} }
.max-price { .max-price {
margin-left: 10rpx; margin-left: 10rpx;
text-decoration: line-through; text-decoration: line-through;
} }
.purchase-price { .purchase-price {
color: $main-color; color: var(--theme-primary, #ff3c2a);
> span {
> text {
font-size: 32rpx; font-size: 32rpx;
font-weight: bold; font-weight: bold;
} }
} }
.bargaining, .bargaining,
.buy, .buy,
.start { .start {
font-size: 24rpx;
width: 80%; width: 80%;
margin: 50rpx auto 0 auto; margin: 50rpx auto 0;
text-align: center; text-align: center;
font-size: 30rpx; font-size: 30rpx;
padding: 18rpx; padding: 18rpx;
border-radius: 100px; border-radius: 100px;
box-sizing: border-box;
} }
.start { .start {
border: 1rpx solid $main-color; border: 1rpx solid var(--theme-primary, #ff3c2a);
color: $main-color; color: var(--theme-primary, #ff3c2a);
} }
.bargaining, .bargaining,
.buy { .buy {
font-size: 24rpx;
color: #fff; color: #fff;
width: 80%;
margin: 50rpx auto 0 auto;
text-align: center;
font-size: 30rpx;
background-image: linear-gradient( background-image: linear-gradient(
25deg, 25deg,
$main-color, var(--theme-primary, #ff3c2a),
$light-color, var(--theme-light, #ff6b35),
$aider-light-color var(--theme-aider, #ff9f28)
); );
padding: 18rpx;
border-radius: 100px;
animation: mymove 5s infinite; animation: mymove 5s infinite;
-webkit-animation: mymove 5s infinite; /*Safari and Chrome*/ animation-direction: alternate;
animation-direction: alternate; /*轮流反向播放动画。*/ animation-timing-function: ease-in-out;
animation-timing-function: ease-in-out; /*动画的速度曲线*/
/* Safari 和 Chrome */
-webkit-animation: mymove 5s infinite;
-webkit-animation-direction: alternate; /*轮流反向播放动画。*/
-webkit-animation-timing-function: ease-in-out; /*动画的速度曲线*/
} }
@keyframes mymove { @keyframes mymove {
0% { 0% {
transform: scale(1); /*开始为原始大小*/ transform: scale(1);
} }
25% { 25% {
transform: scale(1.1); /*放大1.1倍*/ transform: scale(1.1);
} }
50% { 50% {
transform: scale(1); transform: scale(1);
@@ -458,65 +497,80 @@ page {
transform: scale(1.1); transform: scale(1.1);
} }
} }
.line { .line {
margin: 20rpx 0; margin: 20rpx 0;
} }
.tips { .tips {
font-size: 24rpx; font-size: 24rpx;
color: #999; color: #999;
justify-content: space-between; justify-content: space-between;
} }
.bargain-progress { .bargain-progress {
margin: 20rpx 0; margin: 20rpx 0;
} }
.bargain-title { .bargain-title {
font-size: 32rpx; font-size: 32rpx;
font-weight: bold; font-weight: bold;
color: $light-color; color: var(--theme-light, #ff6b35);
text-align: center; text-align: center;
margin-bottom: 40rpx; margin-bottom: 40rpx;
} }
.user-item { .user-item {
margin: 40rpx 0; margin: 40rpx 0;
align-items: center; align-items: center;
} }
.user-config { .user-config {
margin-left: 20rpx; margin-left: 20rpx;
flex: 8; flex: 1;
min-width: 0;
align-items: center; align-items: center;
justify-content: space-between; justify-content: space-between;
> .user-name { > .user-name {
flex: 1;
min-width: 0;
> div:nth-of-type(1) { > div:nth-of-type(1) {
font-size: 28rpx; font-size: 28rpx;
max-width: 300rpx; max-width: 300rpx;
overflow: hidden; overflow: hidden;
word-wrap: normal;
white-space: nowrap; white-space: nowrap;
text-overflow: ellipsis; text-overflow: ellipsis;
} }
> div:nth-last-of-type(1) { > div:nth-last-of-type(1) {
font-size: 24rpx; font-size: 24rpx;
color: #999; color: #999;
} }
} }
} }
.save { .save {
color: $light-color; flex-shrink: 0;
> span { color: var(--theme-light, #ff6b35);
> text {
font-weight: bold; font-weight: bold;
} }
} }
.mobile-intro {
.u-content {
overflow: hidden; overflow: hidden;
max-width: 100%; max-width: 100%;
} }
@keyframes fontMove { @keyframes fontMove {
0% { 0% {
transform: scale(1); /*开始为原始大小*/ transform: scale(1);
} }
25% { 25% {
transform: scale(1.1); /*放大1.1倍*/ transform: scale(1.1);
} }
50% { 50% {
transform: scale(1); transform: scale(1);
@@ -531,19 +585,13 @@ page {
justify-content: center; justify-content: center;
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
> .help {
margin-bottom: 40rpx;
border-radius: 20rpx;
margin-top: 40rpx; > .help {
margin: 40rpx 0;
border-radius: 20rpx;
animation: fontMove 5s infinite; animation: fontMove 5s infinite;
-webkit-animation: fontMove 5s infinite; /*Safari and Chrome*/ animation-direction: alternate;
animation-direction: alternate; /*轮流反向播放动画。*/ animation-timing-function: ease-in-out;
animation-timing-function: ease-in-out; /*动画的速度曲线*/
/* Safari 和 Chrome */
-webkit-animation: fontMove 5s infinite;
-webkit-animation-direction: alternate; /*轮流反向播放动画。*/
-webkit-animation-timing-function: ease-in-out; /*动画的速度曲线*/
} }
} }
</style> </style>

View File

@@ -4,7 +4,10 @@
<u-tabs <u-tabs
:list="list" :list="list"
:scrollable="false" :scrollable="false"
:inactiveStyle="{ color: '#333' }"
v-model:current="current" v-model:current="current"
:lineColor="lightColor"
:activeStyle="{ color: lightColor }"
@change="change" @change="change"
></u-tabs> ></u-tabs>
<view v-if="showLoading" style="width:500rpx;margin:0 auto;text-align: center;height:800rpx;line-height: 800rpx;"> <view v-if="showLoading" style="width:500rpx;margin:0 auto;text-align: center;height:800rpx;line-height: 800rpx;">
@@ -183,9 +186,27 @@ function getMessage() {
}) })
} }
</script> </script>
<style> <style lang="scss" scoped>
.foot { .foot {
position: fixed; position: fixed;
bottom: 0; bottom: 0;
} }
:deep(.u-tabs),
:deep(.u-tabs__wrapper),
:deep(.u-tabs__wrapper__scroll-view-wrapper),
:deep(.u-tabs__wrapper__scroll-view),
:deep(.u-tabs__wrapper__nav) {
background: #fff;
height: 88rpx;
}
:deep(.u-tabs__wrapper__nav__item) {
min-height: 88rpx;
}
:deep(.u-tabs__wrapper__nav__item__text) {
color: #333;
font-size: 28rpx;
}
</style> </style>

5
project.config.json Normal file
View File

@@ -0,0 +1,5 @@
{
"setting": {
"minifyWXML": true
}
}