no message
This commit is contained in:
@@ -0,0 +1,591 @@
|
||||
<template>
|
||||
<view class="mc" :class="'mc--' + cardType">
|
||||
<!-- 顶部:赛事标签行 -->
|
||||
<view class="mc__tags">
|
||||
<view class="mc__tags-left">
|
||||
<text class="mc__tag-label">{{ match.league_name || '赛事' }}</text>
|
||||
<view class="mc__tag-pill">
|
||||
<text>联赛</text>
|
||||
</view>
|
||||
<view v-if="match.round_name" class="mc__tag-pill">
|
||||
<text>{{ match.round_name }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="mc__tags-right">
|
||||
<text
|
||||
v-if="showTagTime"
|
||||
class="mc__time"
|
||||
:class="'mc__time--' + cardType"
|
||||
>
|
||||
{{ scheduleTime }}
|
||||
</text>
|
||||
<view v-if="match.is_hot" class="mc__tag-hot">
|
||||
<text>热门</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 中间:主客队 + 比分 -->
|
||||
<view v-if="match.status === 1" class="mc__body-live" :style="liveStyle">
|
||||
<view class="mc__bg-left"></view>
|
||||
<view class="mc__bg-right"></view>
|
||||
<view class="mc__home mc__home--live">
|
||||
<image v-if="match.home_icon" class="mc__icon" :src="match.home_icon" mode="aspectFit" />
|
||||
<text class="mc__name mc__name--white">{{ match.home_team }}</text>
|
||||
<text class="mc__eng mc__eng--white">{{ match.home_team_en || '' }}</text>
|
||||
</view>
|
||||
<view class="mc__vs-area mc__vs-area--live">
|
||||
<text class="mc__num mc__num--white">{{ match.home_score ?? 0 }}</text>
|
||||
<text class="mc__vs-text mc__vs-text--live">VS</text>
|
||||
<text class="mc__num mc__num--white">{{ match.away_score ?? 0 }}</text>
|
||||
</view>
|
||||
<view class="mc__away mc__away--live">
|
||||
<image v-if="match.away_icon" class="mc__icon" :src="match.away_icon" mode="aspectFit" />
|
||||
<text class="mc__name mc__name--white">{{ match.away_team }}</text>
|
||||
<text class="mc__eng mc__eng--white">{{ match.away_team_en || '' }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view v-else-if="match.status === 0" class="mc__body-upcoming">
|
||||
<view class="mc__row">
|
||||
<view class="mc__team-row">
|
||||
<image v-if="match.home_icon" class="mc__icon-sm" :src="match.home_icon" mode="aspectFit" />
|
||||
<view class="mc__team-info">
|
||||
<text class="mc__tname">{{ match.home_team }}</text>
|
||||
<text class="mc__teng">{{ match.home_team_en || '' }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="mc__odds-item">
|
||||
<text class="mc__odds-label">主胜</text>
|
||||
<text class="mc__odds-val">{{ match.home_odds || '0.00' }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="mc__row mc__row--mid">
|
||||
<view class="mc__vs-center">
|
||||
<text class="mc__vs-text">VS</text>
|
||||
</view>
|
||||
<view class="mc__odds-item">
|
||||
<text class="mc__odds-label">平局</text>
|
||||
<text class="mc__odds-val">{{ match.draw_odds || '0.00' }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="mc__row">
|
||||
<view class="mc__team-row mc__team-row--away">
|
||||
<image v-if="match.away_icon" class="mc__icon-sm" :src="match.away_icon" mode="aspectFit" />
|
||||
<view class="mc__team-info">
|
||||
<text class="mc__tname">{{ match.away_team }}</text>
|
||||
<text class="mc__teng">{{ match.away_team_en || '' }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="mc__odds-item">
|
||||
<text class="mc__odds-label">客胜</text>
|
||||
<text class="mc__odds-val">{{ match.away_odds || '0.00' }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view v-else class="mc__body">
|
||||
<view class="mc__home">
|
||||
<image v-if="match.home_icon" class="mc__icon" :src="match.home_icon" mode="aspectFit" />
|
||||
<text class="mc__name">{{ match.home_team }}</text>
|
||||
<text class="mc__eng">{{ match.home_team_en || '' }}</text>
|
||||
</view>
|
||||
<view class="mc__vs-area">
|
||||
<text class="mc__num">{{ match.home_score ?? 0 }}</text>
|
||||
<text class="mc__vs-text">VS</text>
|
||||
<text class="mc__num">{{ match.away_score ?? 0 }}</text>
|
||||
</view>
|
||||
<view class="mc__away">
|
||||
<image v-if="match.away_icon" class="mc__icon" :src="match.away_icon" mode="aspectFit" />
|
||||
<text class="mc__name">{{ match.away_team }}</text>
|
||||
<text class="mc__eng">{{ match.away_team_en || '' }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 底部:状态 + 时间 -->
|
||||
<view class="mc__footer" :class="{ 'mc__footer--live-ai': canShowLiveAi }">
|
||||
<view class="mc__badge" :class="'mc__badge--' + cardType">
|
||||
<text>{{ statusLabel }}</text>
|
||||
</view>
|
||||
<text v-if="showFooterTime" class="mc__time" :class="'mc__time--' + cardType">{{ scheduleTime }}</text>
|
||||
<view v-if="canShowLiveAi" class="mc__ai-entry" @tap.stop="goAiAnalysis">
|
||||
<text class="mc__ai-entry-badge">AI</text>
|
||||
<text class="mc__ai-entry-text">分析</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed } from 'vue'
|
||||
|
||||
const props = defineProps<{
|
||||
match: any
|
||||
showLiveAi?: boolean
|
||||
}>()
|
||||
|
||||
const statusTypeMap: Record<number, string> = { 1: 'live', 0: 'upcoming', 3: 'postponed', 2: 'ended' }
|
||||
const statusTextMap: Record<number, string> = { 1: '进行中', 0: '未开始', 3: '推迟', 2: '已结束' }
|
||||
|
||||
const sportColors: Record<number, { left: string; right: string }> = {
|
||||
1: { left: '#008248', right: '#00471b' },
|
||||
2: { left: '#006BB7', right: '#D0202D' },
|
||||
4: { left: '#6B3FA0', right: '#3F1D6B' },
|
||||
5: { left: '#C47A20', right: '#8B5512' }
|
||||
}
|
||||
const defaultSportColor = { left: '#008248', right: '#00471b' }
|
||||
|
||||
const liveStyle = computed(() => {
|
||||
const c = sportColors[props.match.sport_type] || defaultSportColor
|
||||
return {
|
||||
'--bg-left-color': c.left,
|
||||
'--bg-right-color': c.right
|
||||
}
|
||||
})
|
||||
|
||||
const cardType = computed(() => statusTypeMap[props.match.status] || 'other')
|
||||
|
||||
const canShowLiveAi = computed(() => {
|
||||
return !!props.showLiveAi && ['live', 'upcoming'].includes(cardType.value) && !!props.match?.id
|
||||
})
|
||||
|
||||
const showTagTime = computed(() => {
|
||||
return ['live', 'upcoming', 'ended'].includes(cardType.value)
|
||||
})
|
||||
|
||||
const showFooterTime = computed(() => {
|
||||
return !showTagTime.value
|
||||
})
|
||||
|
||||
const statusLabel = computed(() => {
|
||||
if (props.match.status === 1) return '· 进行中 ·'
|
||||
return statusTextMap[props.match.status] || '未开始'
|
||||
})
|
||||
|
||||
const scheduleTime = computed(() => {
|
||||
if (!props.match.match_time) return ''
|
||||
const d = new Date(props.match.match_time * 1000)
|
||||
const year = d.getFullYear()
|
||||
const month = String(d.getMonth() + 1).padStart(2, '0')
|
||||
const date = String(d.getDate()).padStart(2, '0')
|
||||
const hours = String(d.getHours()).padStart(2, '0')
|
||||
const minutes = String(d.getMinutes()).padStart(2, '0')
|
||||
return `${year}-${month}-${date} ${hours}:${minutes}`
|
||||
})
|
||||
|
||||
const goAiAnalysis = () => {
|
||||
const id = props.match?.id
|
||||
if (!id) return
|
||||
uni.navigateTo({ url: `/pages/ai_analysis/ai_analysis?type=match&id=${id}` })
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.mc {
|
||||
padding: 20rpx 26rpx 10rpx;
|
||||
background: #fff;
|
||||
border-radius: 24rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 10rpx;
|
||||
|
||||
&--ended {
|
||||
background: #f3f4f6;
|
||||
}
|
||||
|
||||
&__tags {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
&__tags-left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12rpx;
|
||||
}
|
||||
|
||||
&__tags-right {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10rpx;
|
||||
justify-content: flex-end;
|
||||
margin-left: 12rpx;
|
||||
}
|
||||
|
||||
&__tag-label {
|
||||
font-size: 24rpx;
|
||||
color: #808080;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
&__tag-pill {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 4rpx 8rpx;
|
||||
background: #e5edff;
|
||||
border-radius: 6rpx;
|
||||
|
||||
text {
|
||||
font-size: 20rpx;
|
||||
color: #185dff;
|
||||
line-height: 1.4;
|
||||
}
|
||||
}
|
||||
|
||||
&__tag-hot {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 4rpx 8rpx;
|
||||
background: #ffe5e5;
|
||||
border-radius: 6rpx;
|
||||
|
||||
text {
|
||||
font-size: 20rpx;
|
||||
color: #ee3835;
|
||||
line-height: 1.4;
|
||||
}
|
||||
}
|
||||
|
||||
&__body-upcoming {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 6rpx;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
&__row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
|
||||
&--mid {
|
||||
padding-left: 56rpx;
|
||||
}
|
||||
}
|
||||
|
||||
&__team-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8rpx;
|
||||
}
|
||||
|
||||
&__team-info {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
gap: 8rpx;
|
||||
}
|
||||
|
||||
&__icon-sm {
|
||||
width: 48rpx;
|
||||
height: 48rpx;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
&__tname {
|
||||
font-size: 28rpx;
|
||||
font-weight: 500;
|
||||
color: #000;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
&__teng {
|
||||
font-size: 24rpx;
|
||||
color: #000;
|
||||
line-height: 1.4;
|
||||
text-transform: capitalize;
|
||||
}
|
||||
|
||||
&__vs-center {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
&__odds-item {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
gap: 4rpx;
|
||||
}
|
||||
|
||||
&__odds-label {
|
||||
font-size: 24rpx;
|
||||
color: #808080;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
&__odds-val {
|
||||
font-size: 28rpx;
|
||||
font-weight: 500;
|
||||
color: #185dff;
|
||||
line-height: 1.4;
|
||||
width: 64rpx;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
&__body {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
&__body-live {
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
border-radius: 24rpx;
|
||||
}
|
||||
|
||||
&__bg-left {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: -8%;
|
||||
width: 56%;
|
||||
height: 100%;
|
||||
background: var(--bg-left-color, #008248);
|
||||
transform: skewX(-35deg);
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
&__bg-right {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: -8%;
|
||||
width: 56%;
|
||||
height: 100%;
|
||||
background: var(--bg-right-color, #00471b);
|
||||
transform: skewX(-35deg);
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
&__home {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 4rpx;
|
||||
min-width: 0;
|
||||
|
||||
&--live {
|
||||
padding: 20rpx 0 20rpx 40rpx;
|
||||
}
|
||||
}
|
||||
|
||||
&__away {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-end;
|
||||
gap: 4rpx;
|
||||
min-width: 0;
|
||||
|
||||
&--live {
|
||||
padding: 20rpx 40rpx 20rpx 0;
|
||||
}
|
||||
}
|
||||
|
||||
&__icon {
|
||||
width: 64rpx;
|
||||
height: 64rpx;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
&__name {
|
||||
font-size: 32rpx;
|
||||
font-weight: 500;
|
||||
color: #000;
|
||||
line-height: 1.4;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
max-width: 100%;
|
||||
|
||||
&--white {
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
&__eng {
|
||||
font-size: 24rpx;
|
||||
color: #000;
|
||||
line-height: 1.4;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
max-width: 100%;
|
||||
|
||||
&--white {
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
&__vs-area {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 32rpx;
|
||||
padding: 0 24rpx;
|
||||
flex-shrink: 0;
|
||||
align-self: center;
|
||||
|
||||
&--live {
|
||||
padding: 0 24rpx;
|
||||
}
|
||||
}
|
||||
|
||||
&__num {
|
||||
font-size: 36rpx;
|
||||
font-weight: 600;
|
||||
color: #000;
|
||||
line-height: 1.4;
|
||||
|
||||
&--white {
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
&__vs-text {
|
||||
font-size: 24rpx;
|
||||
font-weight: 600;
|
||||
color: #808080;
|
||||
line-height: 1.4;
|
||||
|
||||
&--live {
|
||||
color: #fff;
|
||||
text-shadow: 0 4rpx 6rpx rgba(0, 0, 0, 0.25);
|
||||
-webkit-text-stroke: 2rpx #ee3835;
|
||||
paint-order: stroke fill;
|
||||
background: linear-gradient(180deg, #ee3835 0%, #185dff 100%);
|
||||
-webkit-background-clip: text;
|
||||
background-clip: text;
|
||||
-webkit-text-stroke-color: transparent;
|
||||
}
|
||||
}
|
||||
|
||||
&__footer {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 16rpx;
|
||||
|
||||
&--live-ai {
|
||||
width: 100%;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 20rpx;
|
||||
}
|
||||
}
|
||||
|
||||
&__ai-entry {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 6rpx;
|
||||
min-width: 152rpx;
|
||||
padding: 6rpx 14rpx;
|
||||
border-radius: 999rpx;
|
||||
background: #f4f7ff;
|
||||
|
||||
&-badge {
|
||||
min-width: 40rpx;
|
||||
height: 40rpx;
|
||||
padding: 0 10rpx;
|
||||
border-radius: 999rpx;
|
||||
background: linear-gradient(135deg, #185dff 0%, #4f7dff 100%);
|
||||
font-size: 22rpx;
|
||||
font-weight: 700;
|
||||
color: #fff;
|
||||
line-height: 40rpx;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
&-text {
|
||||
font-size: 24rpx;
|
||||
font-weight: 600;
|
||||
color: #185dff;
|
||||
line-height: 1.2;
|
||||
}
|
||||
}
|
||||
|
||||
&__badge {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 8rpx 32rpx;
|
||||
border-radius: 24rpx;
|
||||
|
||||
text {
|
||||
font-size: 24rpx;
|
||||
font-weight: 500;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
&--upcoming {
|
||||
background: #e5edff;
|
||||
|
||||
text {
|
||||
color: #185dff;
|
||||
}
|
||||
}
|
||||
|
||||
&--live {
|
||||
background: #185dff;
|
||||
|
||||
text {
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
&--ended {
|
||||
background: #808080;
|
||||
|
||||
text {
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
&--postponed {
|
||||
background: #fff1dd;
|
||||
|
||||
text {
|
||||
color: #ff9900;
|
||||
}
|
||||
}
|
||||
|
||||
&--other {
|
||||
background: #f0f0f0;
|
||||
|
||||
text {
|
||||
color: #666;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&__time {
|
||||
font-size: 24rpx;
|
||||
color: #808080;
|
||||
line-height: 1.4;
|
||||
text-align: center;
|
||||
|
||||
&--live {
|
||||
color: #185dff;
|
||||
}
|
||||
|
||||
&--upcoming {
|
||||
color: #185dff;
|
||||
}
|
||||
|
||||
&--ended {
|
||||
color: #6b7280;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user