feat: enrich lottery detail with news

This commit is contained in:
hajimi
2026-08-03 16:05:08 +08:00
parent 9de071a10d
commit 432ce3244f
3 changed files with 172 additions and 91 deletions
+170 -90
View File
@@ -18,21 +18,10 @@
<view v-if="!loading && drawData" class="dd-body">
<!-- 彩种+期号信息 -->
<view class="dd-info">
<view class="dd-info__identity">
<view class="dd-info__logo">
<image v-if="drawData.category?.icon" class="dd-info__logo-img" :src="drawData.category.icon"
mode="aspectFit" />
<text v-else class="dd-info__logo-text">{{ (drawData.category?.name || '彩种').substring(0, 1) }}</text>
</view>
<view class="dd-info__meta">
<text class="dd-info__name">{{ drawData.category?.name || '' }}</text>
<view class="dd-info__sub">
<text class="dd-info__period"> {{ drawData.period }} </text>
<text class="dd-info__date">{{ drawData.draw_date || '开奖日期待定' }}</text>
</view>
</view>
</view>
<view class="dd-info__status">
<view class="dd-info__header">
<text class="dd-info__name">{{ drawData.category?.name || '' }}</text>
<text class="dd-info__period"> {{ drawData.period }} </text>
<text class="dd-info__date">{{ drawData.draw_date || '开奖日期待定' }}</text>
<view class="dd-info__badge" :class="{ 'dd-info__badge--pending': drawData.status === 0 }">
<text>{{ drawData.status === 1 ? '已开奖' : '待开奖' }}</text>
</view>
@@ -106,7 +95,9 @@
<view class="ai-btn-wrap">
<view class="ai-btn" @tap="goAiPredict">
<text class="ai-btn__text">进入AI智能分析</text>
<text class="ai-btn__icon">AI</text>
<text class="ai-btn__text">智能预测</text>
<text class="ai-btn__arrow"></text>
</view>
</view>
@@ -175,6 +166,24 @@
</view>
</view>
<!-- 彩票资讯 -->
<view v-if="lotteryNews.length" class="dd-news">
<view class="dd-news__header">
<text class="dd-news__title">彩票资讯</text>
<text class="dd-news__sub">最新动态</text>
</view>
<view v-for="item in lotteryNews" :key="item.id" class="dd-news__item" @tap="goNewsDetail(item.id)">
<view class="dd-news__content">
<text class="dd-news__item-title">{{ item.title }}</text>
<view class="dd-news__meta">
<text>{{ item.author || '彩票资讯' }}</text>
<text>{{ formatNewsTime(item.create_time) }}</text>
</view>
</view>
<image v-if="item.image" class="dd-news__image" :src="item.image" mode="aspectFill" />
</view>
</view>
<!-- 免责声明 -->
<view class="dd-disclaimer">
<text>声明开奖数据仅供参考请以官方公布为准</text>
@@ -191,11 +200,13 @@
import { ref, computed } from 'vue'
import { onLoad } from '@dcloudio/uni-app'
import { getLotteryDrawDetail } from '@/api/lottery'
import { getArticleCate, getArticleList } from '@/api/news'
const statusBarHeight = ref(0)
const loading = ref(true)
const drawData = ref<any>(null)
const errorMsg = ref('')
const lotteryNews = ref<any[]>([])
uni.getSystemInfo({
success: (res) => {
@@ -243,6 +254,30 @@ const fetchDetail = async (params: { id?: number; code?: string; issue?: string
}
}
const fetchLotteryNews = async () => {
try {
const categories = await getArticleCate()
const lotteryCategory = (categories || []).find((item: any) => String(item?.name || '').includes('彩票'))
if (!lotteryCategory?.id) return
const data = await getArticleList({
cid: lotteryCategory.id,
page_no: 1,
page_size: 5
})
lotteryNews.value = data?.lists || []
} catch (error) {
console.log('彩票资讯加载失败=>', error)
}
}
const formatNewsTime = (value: string) => String(value || '').slice(0, 10)
const goNewsDetail = (id: number) => {
if (!id) return
uni.navigateTo({ url: `/pages/news_detail/news_detail?id=${id}` })
}
const aiLoading = ref(false)
const aiLoaded = ref(false)
const aiError = ref('')
@@ -274,6 +309,7 @@ onLoad((options: any) => {
loading.value = false
errorMsg.value = '参数错误'
}
fetchLotteryNews()
})
</script>
@@ -321,95 +357,52 @@ onLoad((options: any) => {
}
.dd-body {
padding: 20rpx 24rpx 40rpx;
padding: 0 0 40rpx;
}
.dd-info {
display: flex;
align-items: center;
justify-content: space-between;
gap: 16rpx;
margin: 20rpx 24rpx 0;
padding: 24rpx;
margin-bottom: 20rpx;
background: #fff;
border: 1rpx solid #f0f0f0;
border-radius: 16rpx;
box-shadow: 0 6rpx 20rpx rgba(24, 93, 255, 0.04);
&__identity {
min-width: 0;
display: flex;
align-items: center;
gap: 16rpx;
}
&__logo {
width: 72rpx;
height: 72rpx;
flex: 0 0 72rpx;
display: flex;
align-items: center;
justify-content: center;
overflow: hidden;
border-radius: 16rpx;
background: linear-gradient(135deg, #185dff, #ff6b6b);
}
&__logo-img {
&__header {
width: 100%;
height: 100%;
}
&__logo-text {
color: #fff;
font-size: 30rpx;
font-weight: bold;
}
&__meta {
min-width: 0;
display: flex;
flex-direction: column;
align-items: center;
gap: 12rpx;
}
&__name {
flex-shrink: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
font-size: 32rpx;
font-size: 28rpx;
font-weight: bold;
color: #222;
}
&__sub {
display: flex;
align-items: center;
gap: 12rpx;
margin-top: 8rpx;
}
&__period {
font-size: 24rpx;
color: #185dff;
background: #E5EDFF;
padding: 4rpx 12rpx;
border-radius: 8rpx;
color: #999;
white-space: nowrap;
}
&__date {
min-width: 0;
margin-left: auto;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
font-size: 22rpx;
font-size: 24rpx;
color: #999;
}
&__status {
flex-shrink: 0;
}
&__badge {
flex-shrink: 0;
font-size: 22rpx;
color: #22c55e;
background: #f0fdf4;
@@ -424,12 +417,10 @@ onLoad((options: any) => {
}
.dd-result {
margin: 20rpx 24rpx 0;
background: #fff;
border-radius: 16rpx;
padding: 24rpx;
margin-bottom: 20rpx;
border: 1rpx solid #f0f0f0;
box-shadow: 0 6rpx 20rpx rgba(24, 93, 255, 0.04);
&__header {
display: flex;
@@ -520,8 +511,8 @@ onLoad((options: any) => {
border-top: 1rpx solid #f0f0f0;
&__label {
font-size: 26rpx;
color: #666;
font-size: 24rpx;
color: #999;
margin-bottom: 12rpx;
}
@@ -533,7 +524,7 @@ onLoad((options: any) => {
}
.dd-tag {
font-size: 24rpx;
font-size: 22rpx;
color: #333;
background: #f5f5f5;
padding: 8rpx 20rpx;
@@ -569,13 +560,11 @@ onLoad((options: any) => {
}
.dd-pending {
margin: 20rpx 24rpx 0;
background: #fff;
border-radius: 16rpx;
padding: 48rpx 24rpx;
padding: 32rpx 24rpx;
text-align: center;
margin-bottom: 20rpx;
border: 1rpx solid #f0f0f0;
box-shadow: 0 6rpx 20rpx rgba(24, 93, 255, 0.04);
&__icon {
font-size: 64rpx;
@@ -598,12 +587,10 @@ onLoad((options: any) => {
}
.dd-rule {
margin: 20rpx 24rpx 0;
background: #fff;
border-radius: 16rpx;
padding: 24rpx;
margin-bottom: 20rpx;
border: 1rpx solid #f0f0f0;
box-shadow: 0 6rpx 20rpx rgba(24, 93, 255, 0.04);
&__title {
font-size: 28rpx;
@@ -619,8 +606,82 @@ onLoad((options: any) => {
}
}
.dd-news {
margin: 20rpx 24rpx 0;
padding: 24rpx;
background: #fff;
border-radius: 16rpx;
&__header {
display: flex;
align-items: center;
justify-content: space-between;
padding-bottom: 20rpx;
}
&__title {
font-size: 28rpx;
font-weight: bold;
color: #222;
}
&__sub {
font-size: 24rpx;
color: #999;
}
&__item {
display: flex;
align-items: stretch;
gap: 16rpx;
padding: 20rpx 0;
border-top: 1rpx solid #f0f0f0;
}
&__content {
min-width: 0;
flex: 1;
display: flex;
flex-direction: column;
justify-content: space-between;
}
&__item-title {
display: -webkit-box;
overflow: hidden;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
font-size: 26rpx;
line-height: 1.45;
color: #333;
}
&__meta {
display: flex;
gap: 12rpx;
margin-top: 12rpx;
overflow: hidden;
color: #999;
font-size: 22rpx;
text {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}
&__image {
width: 160rpx;
height: 108rpx;
flex: 0 0 160rpx;
border-radius: 8rpx;
background: #f5f5f5;
}
}
.dd-disclaimer {
padding: 30rpx 0;
padding: 30rpx 24rpx 0;
text-align: center;
font-size: 22rpx;
color: #ccc;
@@ -636,12 +697,10 @@ onLoad((options: any) => {
/* AI预测区块 */
.ai-section {
margin: 20rpx 24rpx 0;
background: #fff;
border-radius: 16rpx;
padding: 24rpx;
margin-bottom: 20rpx;
border: 1rpx solid #f0f0f0;
box-shadow: 0 6rpx 20rpx rgba(24, 93, 255, 0.04);
&__header {
display: flex;
@@ -685,14 +744,35 @@ onLoad((options: any) => {
}
.ai-btn {
display: inline-flex;
align-items: center;
gap: 10rpx;
background: linear-gradient(135deg, #6366f1, #8b5cf6);
padding: 20rpx 60rpx;
border-radius: 40rpx;
padding: 16rpx 36rpx;
border-radius: 36rpx;
box-shadow: 0 8rpx 24rpx rgba(102, 126, 234, 0.4);
&__icon {
padding: 4rpx 14rpx;
color: #fff;
background: rgba(255, 255, 255, 0.3);
border-radius: 10rpx;
font-size: 24rpx;
font-weight: 900;
letter-spacing: 2rpx;
}
&__text {
color: #fff;
font-size: 28rpx;
font-weight: bold;
letter-spacing: 2rpx;
}
&__arrow {
color: rgba(255, 255, 255, 0.8);
font-size: 36rpx;
font-weight: bold;
}
}