feat: 接入内容服务端真实接口并优化页面交互

- 迁移内容数据到服务端接口,移除本地模拟数据
- 首页新增推荐课程加载与未读消息检查
- 资讯、课程、搜索页面支持分页加载与错误重试
- 登录页新增恢复课程、消息、帮助页的路由逻辑
- 评估分析页新增处理中状态动效与阶段提示
- API 环境切换到正式域名 airz.hqling.cloud
This commit is contained in:
hujun
2026-10-01 20:26:41 +08:00
parent 3b2a0139e4
commit 2a9ff403c4
41 changed files with 21742 additions and 427 deletions
+35 -4
View File
@@ -35,7 +35,10 @@
<view class="section-head"><text class="section-title">我的融资方案</text><view class="more-link" @click="go('/packages/finance/matches/matches')"><text class="more">查看全部</text><AppIcon name="chevron-right" :size="24" /></view></view>
<view class="plan-card" @click="go('/packages/finance/matches/matches')"><view class="plan-main"><text class="plan-name">信用融资方案</text><text class="plan-meta">了解额度、利率与申请条件</text></view><view class="score"><text class="score-number">3</text><text class="score-label">可查看方案</text></view></view>
<view class="section-head"><text class="section-title">融资课堂</text><view class="more-link" @click="go('/packages/content/classroom/classroom')"><text class="more">进入课堂</text><AppIcon name="chevron-right" :size="24" /></view></view>
<view class="news-preview" @click="go('/packages/content/classroom/classroom')"><view class="news-copy"><text class="news-title">如何提高个人贷款通过率</text><text class="news-meta">信用管理 · 6分钟阅读</text></view><image class="news-art" src="/static/mobile/images/news-calculator.png" mode="aspectFill"></image></view>
<view v-if="contentLoading" class="home-content-state"><text>正在加载课程…</text></view>
<view v-else-if="contentError.length > 0" class="home-content-state" @click="loadRecommendations"><text>{{ contentError }}</text><text class="home-content-retry">重新加载</text></view>
<view v-else-if="recommendedLessons.length == 0" class="home-content-state"><text>暂无推荐课程</text></view>
<view v-else class="news-preview" @click="go('/packages/content/lesson/lesson?id=' + recommendedLessons[0].id)"><view class="news-copy"><text class="news-title">{{ recommendedLessons[0].title }}</text><text class="news-meta">{{ recommendedLessons[0].tag }} · {{ recommendedLessons[0].duration }}</text></view><image class="news-art" :src="recommendedLessons[0].image" mode="aspectFill"></image></view>
</view>
</scroll-view>
<BottomNav active="home" />
@@ -43,7 +46,9 @@
</template>
<script setup lang="uts">
import { getUserStorage } from '@/services/storage.uts'
import { getSession } from '@/services/api.uts'
import { fetchUnreadMessages } from '@/services/messages.uts'
import { fetchContentHome, FinanceLesson } from '@/services/content.uts'
import { usePageLayout } from '@/services/layout.uts'
const { contentStyle, statusStyle, pageStyle, navigationStyle, navigationActionStyle, navigationBrandStyle } = usePageLayout()
@@ -54,13 +59,39 @@
onLoad(() => {
if (consumeInitialLaunch()) uni.reLaunch({ url: '/packages/account/index/index' })
})
const hasUnread = ref(true)
onShow(() => { hasUnread.value = getUserStorage('finance.notice.read.assessment-guide') != true })
const hasUnread = ref(false)
const recommendedLessons = ref<FinanceLesson[]>([])
const contentLoading = ref(false); const contentError = ref('')
let contentGeneration = 0
async function loadRecommendations() {
const request = ++contentGeneration
contentLoading.value = true; contentError.value = ''; recommendedLessons.value = []
try {
const result = await fetchContentHome()
if (request == contentGeneration) recommendedLessons.value = result.lessons
} catch (_) { if (request == contentGeneration) contentError.value = '推荐课程加载失败' }
finally { if (request == contentGeneration) contentLoading.value = false }
}
let unreadGeneration = 0
onShow(async () => {
loadRecommendations()
const request = ++unreadGeneration; const token = getSession()?.getString('token') ?? ''
hasUnread.value = false
if (token.length == 0) return
try {
const unread = await fetchUnreadMessages()
if (request == unreadGeneration && getSession()?.getString('token') == token) hasUnread.value = unread > 0
} catch (_) { /* 首页其他入口仍可用,消息页提供明确的加载错误与重试。 */ }
})
onHide(() => { unreadGeneration++; contentGeneration++; hasUnread.value = false })
onUnload(() => { unreadGeneration++; contentGeneration++ })
const go = (url: string) => { uni.navigateTo({ url: url }) }
const openEntry = (type: string) => { go('/packages/finance/entry/entry?type=' + type) }
</script>
<style>
.home-content-state { padding: 24rpx 0; font-size: 25rpx; line-height: 40rpx; color: #66758a; }
.home-content-retry { color: #0868f7; margin-top: 12rpx; }
.home-header { background-color: #ffffff; }
.safe { }
.home-bar { height: 104rpx; padding: 0 28rpx; flex-direction: row; align-items: center; justify-content: space-between; position: relative; }