提交 edaa9946 编写于 作者: Y yxf15732625262

Sat Feb 8 18:11:00 CST 2025 inscode

上级 0128a52a
......@@ -3,7 +3,7 @@
#app {
max-width: 1280px;
margin: 0 auto;
padding: 2rem;
padding: 1rem;
font-weight: normal;
}
......@@ -30,6 +30,6 @@ a,
#app {
display: grid;
grid-template-columns: 1fr 1fr;
padding: 0 2rem;
padding: 0 1rem;
}
}
......@@ -84,3 +84,18 @@ export const BANNER_JSON = {
}
}
}
export const getStatusFromBackEnd = (statusTag) => {
switch (statusTag) {
case CARD_STATUS_BACKEND.VALID:
return CARD_STATUS.CANUSE
case CARD_STATUS_BACKEND.USED:
return CARD_STATUS.USED
case CARD_STATUS_BACKEND.LOCKED:
case CARD_STATUS_BACKEND.NOT_VALID:
case CARD_STATUS_BACKEND.EXPIRED:
return CARD_STATUS.UNAVAILABLE
default:
return CARD_STATUS.CANUSE
}
}
<template>
<div :class="['banner-card-container', computedClass]" :style="containerStyle">
<div class="status" :style="statusStyle">{{ statusText }}</div>
<template v-if="isCoupon">
<div class="title">
<div class="amount">{{ benefitValueDesc.value }}</div>
<div class="unit">{{ benefitValueDesc.unit }}</div>
</div>
</template>
<template v-else>
<div class="title non-coupon-title">
<div class="amount non-coupon-amount">
{{ benefitTypeDesc }}
</div>
</div>
</template>
<div class="desc">{{ benefitBottomDesc }}</div>
</div>
</template>
<script setup lang="ts">
import { computed } from 'vue'
import { CARD_CATEGORY, getStatusFromBackEnd } from '../assets/constant'
const props = defineProps({
cardData: {
type: Object,
default: () => ({})
},
staticData: {
type: Object,
default: () => ({})
},
index: {
type: Number,
default: 0
}
})
const containerStyle = computed(()=>{
return `
margin-left: ${props.index === 0 ? '0.1rem' : '0rem'}; !important;
`
})
const category = computed(()=>{
return props.cardData.benefitType === CARD_CATEGORY.COUPON ? CARD_CATEGORY.COUPON : CARD_CATEGORY.RIGHT
})
const isCoupon = computed(()=>{
return category.value === CARD_CATEGORY.COUPON
})
const status = computed(()=>{
return getStatusFromBackEnd(props.cardData.statusTag)
})
const computedClass = computed(()=>{
return `${status.value} ${category.value === CARD_CATEGORY.COUPON ? 'coupon' : 'right'}`
})
const statusText = computed(()=>{
const { statusTexts } = props.staticData.card || {}
return statusTexts ? statusTexts[props.cardData.statusTag] : ''
})
const statusStyle = computed(()=>{
const { statusImgs } = props.staticData.card || {}
const bgUrl = statusImgs && category.value && status.value ? statusImgs[category.value][status.value] : ''
return `
background: url(${bgUrl}) no-repeat;
background-size: 100% 100%;
`
})
const benefitValueDesc = computed(()=>{
const benefitValueDesc = props.cardData.benefitValueDesc || ''
const [value, unit] = benefitValueDesc.split('/')
return {
value,
unit
}
})
const benefitTypeDesc = computed(()=>{
return props.cardData.benefitTypeDesc || ''
})
const benefitBottomDesc = computed(()=>{
return props.cardData.benefitBottomDesc || ''
})
</script>
<style scoped lang="less">
.banner-card-container {
position: relative;
margin: 0 5px;
width: 78px;
height: 68px;
font-family: PingFang SC;
border-radius: 10px;
background: #fff4f0;
box-sizing: border-box;
border: 1px solid #ffe5db;
color: #ff6722;
.status {
position: absolute;
left: 50%;
top: 0;
transform: translateX(-50%);
width: 1rem;
height: 16px;
line-height: 16px;
font-size: 10px;
font-weight: bold;
text-align: center;
color: #e49877;
}
.title {
margin: 3px auto 0;
font-family: PingFang SC;
font-size: 10px;
font-weight: bold;
line-height: 10px;
text-align: center;
width: fit-content;
display: flex;
align-items: baseline;
.amount {
font-family: BarlowSemiCondensed-Bold;
font-size: 20px;
color: #ff6722;
}
.unit {
transform: translateY(-1px);
margin-left: 1px;
}
}
.desc {
margin-top: 5px;
font-size: 10px;
font-weight: bold;
line-height: normal;
text-align: center;
}
&.right,
&.unavailable {
.non-coupon-title {
margin-top: 27px;
}
.non-coupon-amount {
font-size: 12px;
font-family: PingFang SC;
font-weight: bold;
}
}
&.right {
background: #fff6eb;
border-color: #ffe3b7;
.status {
color: #a47149;
}
.title {
&,
.amount,
.unit {
color: #7a3c13;
}
}
.desc {
color: #a47149;
}
}
&.unavailable {
background: #f6f6f6;
border-color: #e9e9e9;
.status {
color: #ababab;
}
.title {
&,
.amount,
.unit {
color: #666666;
}
}
.desc {
color: #666666;
}
}
}
</style>
\ No newline at end of file
<template>
<div class="banner-flag-container" :class="computedClass">
<div class="top" :style="topStyle">{{ taskTitle }}</div>
<div class="bottom"></div>
</div>
</template>
<script setup lang="ts">
import { computed } from 'vue'
import { TASK_STATUS } from '../assets/constant'
const props = defineProps({
status: {
type: Number,
default: TASK_STATUS.UNCOMPLETE
},
staticData: {
type: Object,
default: () => ({})
},
sectionData: {
type: Object,
default: () => ({})
}
})
const topStyle = computed(()=>{
const { flagBgs } = props.staticData || {}
const bgUrl = flagBgs && props.status ? flagBgs[props.status] : ''
return `
background: url(${bgUrl}) no-repeat;
background-size: 100% 100%;
`
})
const taskTitle = computed(()=>{
return props.sectionData.taskTitle || ''
})
const computedClass = computed(()=>{
return props.status === TASK_STATUS.COMPLETED ? 'completed' : 'uncomplete'
})
</script>
<style scoped lang="less">
.banner-flag-container {
position: absolute;
left: 0;
top: 0;
transform: translateX(-50%);
z-index: 2;
display: flex;
flex-direction: column;
align-items: center;
.top {
width: 22px;
height: 70px;
font-family: PingFang SC;
font-size: 10px;
line-height: 11px;
font-weight: bold;
text-align: center;
color: #ffffff;
box-sizing: border-box;
padding: 18px 5px 0;
white-space: normal;
}
.bottom {
margin-top: 5px;
width: 9px;
height: 9px;
border-radius: 50%;
background: #ffdea2;
}
// 状态类名
&.completed {
.bottom {
background: #ff6722;
}
}
&.uncomplete {
.bottom {
background: #ffdea2;
}
}
}
</style>
\ No newline at end of file
<template>
<div :class="'banner-section-container ' + bannerSection">
<BannerFlag :status="status" :static-data="staticData" :section-data="sectionData" />
<div class="banner-card-list">
<BannerCard v-for="(item, idx) in cardList" :key="idx" :card-data="item" :index="idx" :static-data="staticData" />
</div>
</div>
</template>
<script setup lang="ts">
import { computed } from 'vue'
import BannerFlag from './BannerFlag.vue'
import BannerCard from './BannerCard.vue'
import { TASK_STATUS } from '../assets/constant'
const props = defineProps({
sectionData: {
type: Object,
default: () => ({})
},
staticData: {
type: Object,
default: () => ({})
},
index: {
type: Number,
default: () => 0
},
sectionList: {
type: Array,
default: () => []
}
})
const bannerSection = computed(()=>{
return `${props.index + 1 >= props.sectionList.length ? 'no-padding-right' : ''}`
})
const cardList = computed(()=>{
return props.sectionData.benefitVOS || []
})
const status = computed(()=>{
return props.sectionData.taskStatus || TASK_STATUS.UNCOMPLETE
})
</script>
<style scoped lang="less">
.banner-section-container {
box-sizing: border-box;
padding: 0 11px;
position: relative;
z-index: 0;
width: fit-content;
&.no-padding-right {
padding-right: 0;
}
.banner-card-list {
display: flex;
}
}
</style>
\ No newline at end of file
......@@ -49,6 +49,7 @@ import { onMounted, onBeforeUnmount, ref, computed } from 'vue'
import { findLastIndex } from 'lodash-es'
import { getTimes } from '../assets/utils'
import { BANNER_JSON, SCENE, CATEGORY, TASK_STATUS } from '../assets/constant.js'
import BannerSection from './BannerSection.vue'
const props = withDefaults(defineProps<{ bannerData: any }>(), {
bannerData: ()=> ({})
......@@ -168,6 +169,25 @@ const jumpPage = () => {
</script>
<style lang="less" scoped>
.stair-new-user-banner-container {
margin: 0 auto;
width: 355px;
height: 167px;
border-radius: 16px;
box-shadow: 0 3px 10px 0 #eaecf6;
::-webkit-scrollbar {
width: 0;
height: 0;
display: none;
}
.top {
height: 28px;
box-sizing: border-box;
padding: 10px 14px 0;
}
}
.title {
display: flex;
flex-direction: row;
......@@ -199,16 +219,28 @@ const jumpPage = () => {
}
.desc {
margin-top: 8px;
// margin-top: 8px;
// display: flex;
// flex-direction: row;
// align-items: center;
// font-size: 12px;
// font-weight: normal;
// line-height: 12px;
// text-align: right;
// letter-spacing: 0px;
// color: #AE795F;
height: 19px;
display: flex;
flex-direction: row;
align-items: center;
margin-top: 5px;
font-family: PingFang SC;
font-size: 12px;
font-weight: normal;
line-height: 12px;
text-align: right;
letter-spacing: 0px;
color: #AE795F;
color: #ae795f;
.line {
width: 1px;
......@@ -241,4 +273,51 @@ const jumpPage = () => {
}
.content {
height: 112px;
border-radius: 16px;
background: #ffffff;
margin-top: -20px;
box-sizing: border-box;
display: flex;
overflow-x: scroll;
scroll-behavior: smooth;
::-webkit-scrollbar {
display: none;
}
.crisp {
display: flex;
position: relative;
z-index: 0;
height: 82px;
width: fit-content;
margin-left: 24px;
margin-top: 12px;
margin-right: 7px;
white-space: nowrap;
.bottom-bar {
position: absolute;
left: 0;
right: 5px;
bottom: 0;
height: 5px;
background: #fcf8ed;
z-index: -1;
border-radius: 20px;
.process-bar {
position: absolute;
left: 0;
top: 0;
bottom: 0;
width: 0;
background: linear-gradient(90deg, #ffe2a7 2%, #ff6722 103%);
border-radius: 20px;
}
}
}
}
</style>
\ No newline at end of file
......@@ -37,5 +37,26 @@ const onChange = (index) => {
</script>
<style lang="less" scoped>
.my_swipe {
margin: 13px auto 0 auto;
width:355px;
border-radius: 12px;
::v-deep .van-swipe__indicators {
bottom: 2px;
}
.swipe_item {
width: 355px !important;
.head_img {
width: 355px;
height: 61px;
}
}
.activity-container {
width: 355px;
height: 166px;
}
}
</style>
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册