refactor: 重构移动端页面布局与资源路径,优化打包配置

1. 新增layout.uts统一管理页面尺寸与安全区计算
2. 修正图片资源路径到static/mobile目录
3. 调整App.vue与AppIcon组件样式适配多端
4. 为微信小程序配置打包忽略规则减少包体积
5. 修复API请求错误抛出类型,完善类型定义
6. 补充README文档说明项目运行与维护规范
7. 优化多个页面的样式与生命周期逻辑
This commit is contained in:
hujun
2026-09-15 16:16:55 +08:00
parent 626cef9d38
commit b0ee4f9d7e
67 changed files with 80727 additions and 189 deletions
+39 -11
View File
@@ -1,29 +1,57 @@
<template>
<view class="page">
<view class="page" :style="pageStyle()">
<AppHeader title="融资课堂" />
<scroll-view scroll-y class="classroom-scroll">
<scroll-view scroll-y class="classroom-scroll" :style="contentStyle(96, false)">
<view class="classroom-content">
<view class="classroom-hero"><view class="hero-copy"><text class="hero-title">融资课堂</text><text class="hero-subtitle">把融资知识,变成申请底气</text><text class="hero-desc">从准备材料到优化信用,分阶段掌握实用方法</text></view><image src="/static/images/news-policy.png" mode="aspectFill"></image></view>
<view class="lesson-section"><view class="section-head"><text class="section-title">热门课程</text><text class="lesson-count">12 节课程</text></view><view class="lesson-card" v-for="(item,index) in lessons" :key="item.title" @click="openLesson(index)"><image :src="item.image" mode="aspectFill"></image><view class="lesson-copy"><text class="lesson-title">{{ item.title }}</text><text class="lesson-desc">{{ item.desc }}</text><view class="lesson-meta"><text>{{ item.duration }}</text><text class="lesson-tag">{{ item.tag }}</text></view></view><AppIcon name="chevron-right" :size="28" muted /></view></view>
<view class="topic-section"><text class="section-title">按场景学习</text><view class="topic-grid"><view class="topic-card blue-topic" @click="openTopic('个人信用提升')"><AppIcon name="user" :size="46" /><text>个人信用提升</text><text>3 节课程</text></view><view class="topic-card orange-topic" @click="openTopic('小微经营融资')"><AppIcon name="building" :size="46" /><text>小微经营融资</text><text>4 节课程</text></view><view class="topic-card green-topic" @click="openTopic('材料准备清单')"><AppIcon name="file-text" :size="46" /><text>材料准备清单</text><text>5 节课程</text></view></view></view>
<view class="classroom-hero"><view class="hero-copy"><text class="hero-title">融资课堂</text><text class="hero-subtitle">把融资知识,变成申请底气</text><text class="hero-desc">从准备材料到优化信用,分阶段掌握实用方法</text></view><image src="/static/mobile/images/news-policy.png" mode="aspectFill" class="classroom-hero-image"></image></view>
<view class="lesson-section"><view class="section-head"><text class="section-title">热门课程</text><text class="lesson-count">12 节课程</text></view><view class="lesson-card" v-for="(item,index) in lessons" :key="item.title" @click="openLesson(index)"><image :src="item.image" mode="aspectFill" class="lesson-card-image"></image><view class="lesson-copy"><text class="lesson-title">{{ item.title }}</text><text class="lesson-desc">{{ item.desc }}</text><view class="lesson-meta"><text>{{ item.duration }}</text><text class="lesson-tag">{{ item.tag }}</text></view></view><AppIcon name="chevron-right" :size="28" muted /></view></view>
<view class="topic-section"><text class="section-title">按场景学习</text><view class="topic-grid"><view class="topic-card blue-topic" @click="openTopic('个人信用提升')"><AppIcon name="user" :size="46" /><text class="topic-card-text-1">个人信用提升</text><text class="topic-card-text-2">3 节课程</text></view><view class="topic-card orange-topic" @click="openTopic('小微经营融资')"><AppIcon name="building" :size="46" /><text class="topic-card-text-1">小微经营融资</text><text class="topic-card-text-2">4 节课程</text></view><view class="topic-card green-topic" @click="openTopic('材料准备清单')"><AppIcon name="file-text" :size="46" /><text class="topic-card-text-1">材料准备清单</text><text class="topic-card-text-2">5 节课程</text></view></view></view>
</view>
</scroll-view>
</view>
</template>
<script setup lang="uts">
import { usePageLayout } from '@/services/layout.uts'
const { contentStyle, pageStyle } = usePageLayout()
import AppHeader from '@/components/AppHeader.uvue'
import AppIcon from '@/components/AppIcon.uvue'
const lessons = [
{ title: '如何提高个人贷款通过率', desc: '征信、负债和收入的申请准备方法', duration: '6 分钟', tag: '个人融资', image: '/static/images/news-calculator.png' },
{ title: '小微企业融资材料清单', desc: '一次准备齐全,减少补充资料时间', duration: '8 分钟', tag: '企业融资', image: '/static/images/news-business.png' },
{ title: '读懂贷款利率与还款方式', desc: '选对期限,降低长期资金成本', duration: '5 分钟', tag: '基础知识', image: '/static/images/news-city.png' }
type LessonSummary = { title: string, desc: string, duration: string, tag: string, image: string }
const lessons: LessonSummary[] = [
{ title: '如何提高个人贷款通过率', desc: '征信、负债和收入的申请准备方法', duration: '6 分钟', tag: '个人融资', image: '/static/mobile/images/news-calculator.png' },
{ title: '小微企业融资材料清单', desc: '一次准备齐全,减少补充资料时间', duration: '8 分钟', tag: '企业融资', image: '/static/mobile/images/news-business.png' },
{ title: '读懂贷款利率与还款方式', desc: '选对期限,降低长期资金成本', duration: '5 分钟', tag: '基础知识', image: '/static/mobile/images/news-city.png' }
]
const openLesson = (index: number) => { uni.navigateTo({ url: '/pages/lesson/lesson?id=' + index }) }
const openTopic = (title: string) => { uni.navigateTo({ url: '/pages/lesson/lesson?title=' + title }) }
</script>
<style>
.classroom-scroll { height: calc(100vh - var(--status-bar-height) - 96rpx); }.classroom-content { padding: 26rpx 28rpx 70rpx; }.classroom-hero { height: 242rpx; border-radius: 20rpx; background: linear-gradient(135deg, #0b2a66, #087aff); padding: 28rpx; overflow: hidden; position: relative; }.hero-copy { width: 68%; z-index: 2; }.hero-title { color: #fff; font-size: 38rpx; line-height: 50rpx; font-weight: 800; }.hero-subtitle { color: #fff; font-size: 27rpx; line-height: 40rpx; font-weight: 700; margin-top: 10rpx; }.hero-desc { color: #bfd7ff; font-size: 21rpx; line-height: 32rpx; margin-top: 12rpx; }.classroom-hero image { position: absolute; right: -18rpx; top: 0; width: 220rpx; height: 242rpx; opacity: .78; }
.lesson-section { margin-top: 30rpx; }.section-head { flex-direction: row; align-items: center; justify-content: space-between; }.lesson-count { color: #8b98aa; font-size: 21rpx; }.lesson-card { min-height: 150rpx; margin-top: 16rpx; padding: 18rpx; border-radius: 16rpx; background-color: #fff; border: 1rpx solid #e4ebf5; flex-direction: row; align-items: center; }.lesson-card image { width: 142rpx; height: 114rpx; border-radius: 12rpx; margin-right: 18rpx; flex-shrink: 0; }.lesson-copy { flex: 1; }.lesson-title { color: #1a2941; font-size: 26rpx; line-height: 36rpx; font-weight: 700; }.lesson-desc { color: #778499; font-size: 21rpx; line-height: 31rpx; margin-top: 7rpx; }.lesson-meta { flex-direction: row; align-items: center; margin-top: 10rpx; color: #99a5b4; font-size: 18rpx; }.lesson-tag { margin-left: 14rpx; color: #0868f7; }.topic-section { margin-top: 32rpx; }.topic-grid { flex-direction: row; flex-wrap: wrap; justify-content: space-between; margin-top: 16rpx; }.topic-card { width: 48.5%; min-height: 150rpx; margin-bottom: 14rpx; padding: 20rpx; border-radius: 16rpx; border: 1rpx solid #e4ebf5; }.topic-card .app-icon { margin-bottom: 9rpx; }.topic-card text:nth-of-type(1) { color: #23324a; font-size: 23rpx; font-weight: 700; }.topic-card text:nth-of-type(2) { color: #8190a4; font-size: 19rpx; margin-top: 6rpx; }.blue-topic { background-color: #eef6ff; }.orange-topic { background-color: #fff3e9; }.green-topic { background-color: #eaf8f1; }
.classroom-scroll { }
.classroom-content { padding: 26rpx 28rpx 70rpx; }
.classroom-hero { height: 242rpx; border-radius: 20rpx; background: linear-gradient(135deg, #0b2a66, #087aff); padding: 28rpx; overflow: hidden; position: relative; }
.hero-copy { width: 68%; z-index: 2; }
.hero-title { color: #fff; font-size: 38rpx; line-height: 50rpx; font-weight: 800; }
.hero-subtitle { color: #fff; font-size: 27rpx; line-height: 40rpx; font-weight: 700; margin-top: 10rpx; }
.hero-desc { color: #bfd7ff; font-size: 21rpx; line-height: 32rpx; margin-top: 12rpx; }
.classroom-hero-image { position: absolute; right: -18rpx; top: 0; width: 220rpx; height: 242rpx; opacity: .78; }
.lesson-section { margin-top: 30rpx; }
.section-head { flex-direction: row; align-items: center; justify-content: space-between; }
.lesson-count { color: #8b98aa; font-size: 21rpx; }
.lesson-card { min-height: 150rpx; margin-top: 16rpx; padding: 18rpx; border-radius: 16rpx; background-color: #fff; border: 1rpx solid #e4ebf5; flex-direction: row; align-items: center; }
.lesson-card-image { width: 142rpx; height: 114rpx; border-radius: 12rpx; margin-right: 18rpx; flex-shrink: 0; }
.lesson-copy { flex: 1; }
.lesson-title { color: #1a2941; font-size: 26rpx; line-height: 36rpx; font-weight: 700; }
.lesson-desc { color: #778499; font-size: 21rpx; line-height: 31rpx; margin-top: 7rpx; }
.lesson-meta { flex-direction: row; align-items: center; margin-top: 10rpx; color: #99a5b4; font-size: 18rpx; }
.lesson-tag { margin-left: 14rpx; color: #0868f7; }
.topic-section { margin-top: 32rpx; }
.topic-grid { flex-direction: row; flex-wrap: wrap; justify-content: space-between; margin-top: 16rpx; }
.topic-card { width: 48.5%; min-height: 150rpx; margin-bottom: 14rpx; padding: 20rpx; border-radius: 16rpx; border: 1rpx solid #e4ebf5; }
.topic-card .app-icon { margin-bottom: 9rpx; }
.topic-card-text-1 { color: #23324a; font-size: 23rpx; font-weight: 700; }
.topic-card-text-2 { color: #8190a4; font-size: 19rpx; margin-top: 6rpx; }
.blue-topic { background-color: #eef6ff; }
.orange-topic { background-color: #fff3e9; }
.green-topic { background-color: #eaf8f1; }
</style>