feat(home): 实现首页内容动态渲染
- 新增首页内容 API 接口及 mock 数据 - 重构首页 UI,移除静态占位内容,改为动态渲染 banner、导航和图文链接 - 添加点击跳转逻辑,支持页面内跳转和 WebView 打开外部链接
Showing
6 changed files
with
245 additions
and
187 deletions
| 1 | import { fn, fetch } from './fn' | 1 | import { fn, fetch } from './fn' |
| 2 | 2 | ||
| 3 | const Api = { | 3 | const Api = { |
| 4 | + HOME_CONTENT: '/srv/?a=home&t=content', | ||
| 4 | PAY_TEST: '/srv/?a=pay', | 5 | PAY_TEST: '/srv/?a=pay', |
| 5 | } | 6 | } |
| 6 | 7 | ||
| 8 | +export const getHomeContentAPI = () => fn(fetch.get(Api.HOME_CONTENT)) | ||
| 9 | + | ||
| 7 | /** | 10 | /** |
| 8 | * @description 获取微信支付参数(对齐 meihuaApp 的支付接口) | 11 | * @description 获取微信支付参数(对齐 meihuaApp 的支付接口) |
| 9 | * @param {Object} params 请求参数 | 12 | * @param {Object} params 请求参数 | ... | ... |
src/mock/fixtures/home.fixture.js
0 → 100644
| 1 | +const banner_image = 'https://cdn.ipadbiz.cn/jls_weapp/images/banner01@2x.png' | ||
| 2 | +const activity_image_01 = 'https://cdn.ipadbiz.cn/jls_weapp/images/banner02@2x.png' | ||
| 3 | +const activity_image_02 = 'https://cdn.ipadbiz.cn/jls_weapp/images/banner03@2x.png' | ||
| 4 | + | ||
| 5 | +export const getHomeContentFixture = () => ({ | ||
| 6 | + banner: { | ||
| 7 | + id: 'home-banner-01', | ||
| 8 | + image_url: banner_image, | ||
| 9 | + title: '苏州觉林寺', | ||
| 10 | + link_url: 'https://oa-dev.onwall.cn/f/futian_home/?f=f&p=futian_list', | ||
| 11 | + link_title: '苏州觉林寺', | ||
| 12 | + }, | ||
| 13 | + nav_list: [ | ||
| 14 | + { | ||
| 15 | + id: 'map-guide', | ||
| 16 | + title: '地图导览', | ||
| 17 | + icon: 'icon-jingxiuying', | ||
| 18 | + link_url: '', | ||
| 19 | + page_url: '/pages/map-guide/index', | ||
| 20 | + }, | ||
| 21 | + { | ||
| 22 | + id: 'news', | ||
| 23 | + title: '法讯-最新动态', | ||
| 24 | + icon: 'icon-jingxiuying', | ||
| 25 | + link_url: 'https://oa-dev.onwall.cn/f/futian_home/?f=f&p=news_list', | ||
| 26 | + link_title: '法讯-最新动态', | ||
| 27 | + }, | ||
| 28 | + { | ||
| 29 | + id: 'intro', | ||
| 30 | + title: '寺院介绍', | ||
| 31 | + icon: 'icon-jingxiuying', | ||
| 32 | + link_url: 'https://oa-dev.onwall.cn/f/futian_home/?f=f&p=temple_intro', | ||
| 33 | + link_title: '寺院介绍', | ||
| 34 | + }, | ||
| 35 | + { | ||
| 36 | + id: 'practice', | ||
| 37 | + title: '共修活动', | ||
| 38 | + icon: 'icon-jingxiuying', | ||
| 39 | + link_url: 'https://oa-dev.onwall.cn/f/futian_home/?f=f&p=practice', | ||
| 40 | + link_title: '共修活动', | ||
| 41 | + }, | ||
| 42 | + { | ||
| 43 | + id: 'volunteer', | ||
| 44 | + title: '义工报名', | ||
| 45 | + icon: 'icon-jingxiuying', | ||
| 46 | + link_url: 'https://oa-dev.onwall.cn/f/futian_home/?f=f&p=volunteer', | ||
| 47 | + link_title: '义工报名', | ||
| 48 | + }, | ||
| 49 | + { | ||
| 50 | + id: 'contact', | ||
| 51 | + title: '联系我们', | ||
| 52 | + icon: 'icon-jingxiuying', | ||
| 53 | + link_url: '', | ||
| 54 | + }, | ||
| 55 | + ], | ||
| 56 | + image_links: [ | ||
| 57 | + { | ||
| 58 | + id: 'activity-01', | ||
| 59 | + title: '新春祈福法会', | ||
| 60 | + tag: '活动报名', | ||
| 61 | + image_url: activity_image_01, | ||
| 62 | + link_url: 'https://oa-dev.onwall.cn/f/futian_home/?f=f&p=activity_spring', | ||
| 63 | + link_title: '新春祈福法会', | ||
| 64 | + }, | ||
| 65 | + { | ||
| 66 | + id: 'activity-02', | ||
| 67 | + title: '中秋月光茶会', | ||
| 68 | + tag: '活动报名', | ||
| 69 | + image_url: activity_image_02, | ||
| 70 | + link_url: 'https://oa-dev.onwall.cn/f/futian_home/?f=f&p=activity_moon', | ||
| 71 | + link_title: '中秋月光茶会', | ||
| 72 | + }, | ||
| 73 | + { | ||
| 74 | + id: 'activity-03', | ||
| 75 | + title: '禅修静心体验', | ||
| 76 | + tag: '预约参加', | ||
| 77 | + image_url: activity_image_01, | ||
| 78 | + link_url: 'https://oa-dev.onwall.cn/f/futian_home/?f=f&p=activity_meditation', | ||
| 79 | + link_title: '禅修静心体验', | ||
| 80 | + }, | ||
| 81 | + { | ||
| 82 | + id: 'activity-04', | ||
| 83 | + title: '法物流通', | ||
| 84 | + tag: '查看详情', | ||
| 85 | + image_url: activity_image_02, | ||
| 86 | + link_url: '', | ||
| 87 | + }, | ||
| 88 | + ], | ||
| 89 | +}) |
src/mock/modules/home.mock.js
0 → 100644
| 1 | +import { getHomeContentFixture } from '../fixtures/home.fixture' | ||
| 2 | +import { buildMockSuccess } from '../shared/response' | ||
| 3 | + | ||
| 4 | +export const homeMockHandlers = [ | ||
| 5 | + { | ||
| 6 | + action: 'home', | ||
| 7 | + type: 'content', | ||
| 8 | + method: 'GET', | ||
| 9 | + handle: () => buildMockSuccess(getHomeContentFixture(), '首页内容获取成功 (mock)'), | ||
| 10 | + }, | ||
| 11 | +] |
| ... | @@ -2,10 +2,12 @@ import { authMockHandlers } from './auth.mock' | ... | @@ -2,10 +2,12 @@ import { authMockHandlers } from './auth.mock' |
| 2 | import { paymentMockHandlers } from './payment.mock' | 2 | import { paymentMockHandlers } from './payment.mock' |
| 3 | import { commonMockHandlers } from './common.mock' | 3 | import { commonMockHandlers } from './common.mock' |
| 4 | import { messageMockHandlers } from './message.mock' | 4 | import { messageMockHandlers } from './message.mock' |
| 5 | +import { homeMockHandlers } from './home.mock' | ||
| 5 | 6 | ||
| 6 | export const mockHandlers = [ | 7 | export const mockHandlers = [ |
| 7 | ...authMockHandlers, | 8 | ...authMockHandlers, |
| 8 | ...paymentMockHandlers, | 9 | ...paymentMockHandlers, |
| 9 | ...commonMockHandlers, | 10 | ...commonMockHandlers, |
| 10 | ...messageMockHandlers, | 11 | ...messageMockHandlers, |
| 12 | + ...homeMockHandlers, | ||
| 11 | ] | 13 | ] | ... | ... |
| 1 | <template> | 1 | <template> |
| 2 | <view class="index-page"> | 2 | <view class="index-page"> |
| 3 | <view class="page-content"> | 3 | <view class="page-content"> |
| 4 | - <view class="hero-card"> | 4 | + <view |
| 5 | - <text class="hero-eyebrow">觉林寺小程序</text> | 5 | + v-if="banner.image_url" |
| 6 | - <text class="hero-title">首页</text> | 6 | + class="home-banner" |
| 7 | - <text class="hero-desc"> | 7 | + :class="{ clickable: hasLink(banner) }" |
| 8 | - 当前先完成首页、消息、我的三栏结构,测试能力统一收口到测试中心,避免首页继续堆放调试按钮。 | 8 | + @tap="handleLinkedItemTap(banner)" |
| 9 | - </text> | 9 | + > |
| 10 | + <image class="home-banner__image" :src="banner.image_url" mode="aspectFill" /> | ||
| 10 | </view> | 11 | </view> |
| 11 | 12 | ||
| 12 | - <view class="status-card"> | 13 | + <view class="nav-panel"> |
| 13 | - <view> | 14 | + <view |
| 14 | - <text class="section-label">当前授权状态</text> | 15 | + v-for="item in nav_list" |
| 15 | - <text class="status-text">应用启动时会优先尝试静默授权</text> | 16 | + :key="item.id" |
| 17 | + class="nav-entry" | ||
| 18 | + :class="{ clickable: hasLink(item) }" | ||
| 19 | + @tap="handleLinkedItemTap(item)" | ||
| 20 | + > | ||
| 21 | + <view class="nav-entry__icon-wrap"> | ||
| 22 | + <i | ||
| 23 | + class="fa iconfont iconfont-demo" | ||
| 24 | + :class="item.icon || default_icon" | ||
| 25 | + ></i> | ||
| 16 | </view> | 26 | </view> |
| 17 | - <text class="status-tag" :class="{ authed: isAuthed }"> | 27 | + <text class="nav-entry__title">{{ item.title }}</text> |
| 18 | - {{ isAuthed ? '已授权' : '未授权' }} | ||
| 19 | - </text> | ||
| 20 | </view> | 28 | </view> |
| 21 | - | ||
| 22 | - <view class="overview-grid"> | ||
| 23 | - <view class="overview-card"> | ||
| 24 | - <view class="card-title-row"> | ||
| 25 | - <text class="card-title">首页</text> | ||
| 26 | - <i class="fa iconfont icon-jingxiuying iconfont-demo"></i> | ||
| 27 | - </view> | ||
| 28 | - <text class="card-desc">展示当前项目概览、地图导览与测试入口。</text> | ||
| 29 | - </view> | ||
| 30 | - <view class="overview-card"> | ||
| 31 | - <text class="card-title">消息</text> | ||
| 32 | - <text class="card-desc">后续承接通知、订单提醒与系统消息。</text> | ||
| 33 | - </view> | ||
| 34 | - <view class="overview-card"> | ||
| 35 | - <text class="card-title">我的</text> | ||
| 36 | - <text class="card-desc">后续承接个人信息、授权状态与常用功能。</text> | ||
| 37 | - </view> | ||
| 38 | - </view> | ||
| 39 | - | ||
| 40 | - <view class="map-entry-card"> | ||
| 41 | - <text class="section-label">地图导览</text> | ||
| 42 | - <text class="map-entry-desc"> | ||
| 43 | - 当前通过小程序 WebView 承载地图项目,方便从首页直接进入步行导览页面。 | ||
| 44 | - </text> | ||
| 45 | - <button class="primary-btn" @tap="goToMapGuide">打开地图导览</button> | ||
| 46 | </view> | 29 | </view> |
| 47 | 30 | ||
| 48 | - <view class="webview-entry-card"> | 31 | + <view class="image-link-list"> |
| 49 | - <text class="section-label">模拟 WebView</text> | 32 | + <view |
| 50 | - <text class="webview-entry-desc"> | 33 | + v-for="item in image_links" |
| 51 | - 这里提供一个首页直达的测试 WebView 入口,用于验证通用 WebView 承载能力。 | 34 | + :key="item.id" |
| 52 | - </text> | 35 | + class="image-link-card" |
| 53 | - <button class="outline-btn" @tap="goToMockWebview">打开模拟 WebView</button> | 36 | + :class="{ clickable: hasLink(item) }" |
| 37 | + @tap="handleLinkedItemTap(item)" | ||
| 38 | + > | ||
| 39 | + <image class="image-link-card__image" :src="item.image_url" mode="aspectFill" /> | ||
| 54 | </view> | 40 | </view> |
| 55 | - | ||
| 56 | - <view class="test-entry-card"> | ||
| 57 | - <text class="section-label">测试入口</text> | ||
| 58 | - <text class="test-entry-desc"> | ||
| 59 | - 支付测试等调试能力仍统一收口到测试中心,方便集中联调。 | ||
| 60 | - </text> | ||
| 61 | - <button class="outline-btn" @tap="goToTestCenter">进入测试中心</button> | ||
| 62 | </view> | 41 | </view> |
| 63 | </view> | 42 | </view> |
| 64 | 43 | ||
| ... | @@ -68,197 +47,171 @@ | ... | @@ -68,197 +47,171 @@ |
| 68 | 47 | ||
| 69 | <script setup> | 48 | <script setup> |
| 70 | import { ref } from 'vue' | 49 | import { ref } from 'vue' |
| 71 | -import Taro, { useDidShow } from '@tarojs/taro' | 50 | +import Taro, { useLoad } from '@tarojs/taro' |
| 72 | import AppTabbar from '@/components/AppTabbar.vue' | 51 | import AppTabbar from '@/components/AppTabbar.vue' |
| 73 | -import { hasAuth } from '@/utils/authRedirect' | 52 | +import { getHomeContentAPI } from '@/api' |
| 74 | import { buildWebviewPreviewUrl } from '@/utils/webview' | 53 | import { buildWebviewPreviewUrl } from '@/utils/webview' |
| 75 | 54 | ||
| 76 | -const mock_webview_url = 'https://oa-dev.onwall.cn/f/futian_home/?f=f&p=futian_list' | 55 | +const default_icon = 'icon-jingxiuying' |
| 77 | -const mock_webview_title = '福田首页' | 56 | +const banner = ref({}) |
| 57 | +const nav_list = ref([]) | ||
| 58 | +const image_links = ref([]) | ||
| 78 | 59 | ||
| 79 | -const isAuthed = ref(false) | 60 | +const hasLink = (item) => !!(item?.page_url || item?.link_url) |
| 80 | 61 | ||
| 81 | -const refreshAuthStatus = () => { | 62 | +const handleLinkedItemTap = (item) => { |
| 82 | - isAuthed.value = hasAuth() | 63 | + if (!item) return |
| 83 | -} | ||
| 84 | 64 | ||
| 85 | -const goToMapGuide = () => { | 65 | + if (item.page_url) { |
| 86 | Taro.navigateTo({ | 66 | Taro.navigateTo({ |
| 87 | - url: '/pages/map-guide/index', | 67 | + url: item.page_url, |
| 88 | }) | 68 | }) |
| 89 | -} | 69 | + return |
| 70 | + } | ||
| 90 | 71 | ||
| 91 | -const goToMockWebview = () => { | 72 | + if (item.link_url) { |
| 92 | Taro.navigateTo({ | 73 | Taro.navigateTo({ |
| 93 | - url: buildWebviewPreviewUrl(mock_webview_url, mock_webview_title), | 74 | + url: buildWebviewPreviewUrl(item.link_url, item.link_title || item.title || ''), |
| 94 | }) | 75 | }) |
| 76 | + } | ||
| 95 | } | 77 | } |
| 96 | 78 | ||
| 97 | -const goToTestCenter = () => { | 79 | +const fetchHomeContent = async () => { |
| 98 | - Taro.navigateTo({ | 80 | + const response = await getHomeContentAPI() |
| 99 | - url: '/pages/pay-test/index', | 81 | + |
| 82 | + if (response?.code !== 1) { | ||
| 83 | + Taro.showToast({ | ||
| 84 | + title: response?.msg || '获取首页内容失败', | ||
| 85 | + icon: 'none', | ||
| 100 | }) | 86 | }) |
| 87 | + return | ||
| 88 | + } | ||
| 89 | + | ||
| 90 | + const data = response?.data || {} | ||
| 91 | + banner.value = data.banner || {} | ||
| 92 | + nav_list.value = data.nav_list || [] | ||
| 93 | + image_links.value = data.image_links || [] | ||
| 101 | } | 94 | } |
| 102 | 95 | ||
| 103 | -useDidShow(() => { | 96 | +useLoad(() => { |
| 104 | - refreshAuthStatus() | 97 | + fetchHomeContent() |
| 105 | }) | 98 | }) |
| 106 | </script> | 99 | </script> |
| 107 | 100 | ||
| 108 | <style lang="less"> | 101 | <style lang="less"> |
| 109 | .index-page { | 102 | .index-page { |
| 110 | min-height: 100vh; | 103 | min-height: 100vh; |
| 111 | - background: | 104 | + background: #f1f1f1; |
| 112 | - radial-gradient(circle at top right, rgba(166, 121, 57, 0.18), transparent 32%), | ||
| 113 | - linear-gradient(180deg, #fffaf3 0%, #f6f7fb 100%); | ||
| 114 | 105 | ||
| 115 | .page-content { | 106 | .page-content { |
| 116 | - padding: 32rpx 24rpx 0; | 107 | + padding: 32rpx 32rpx 0; |
| 117 | - box-sizing: border-box; | ||
| 118 | - } | ||
| 119 | - | ||
| 120 | - .hero-card, | ||
| 121 | - .status-card, | ||
| 122 | - .overview-card, | ||
| 123 | - .map-entry-card, | ||
| 124 | - .webview-entry-card, | ||
| 125 | - .test-entry-card { | ||
| 126 | - background: rgba(255, 255, 255, 0.94); | ||
| 127 | - border: 2rpx solid rgba(166, 121, 57, 0.08); | ||
| 128 | - border-radius: 28rpx; | ||
| 129 | - box-shadow: 0 20rpx 60rpx rgba(15, 23, 42, 0.06); | ||
| 130 | box-sizing: border-box; | 108 | box-sizing: border-box; |
| 131 | } | 109 | } |
| 132 | 110 | ||
| 133 | - .hero-card { | 111 | + .home-banner { |
| 134 | - display: flex; | 112 | + margin: -32rpx -32rpx 0; |
| 135 | - flex-direction: column; | 113 | + height: 420rpx; |
| 136 | - padding: 36rpx 32rpx; | 114 | + overflow: hidden; |
| 137 | - } | 115 | + background: #e5e7eb; |
| 138 | - | ||
| 139 | - .hero-eyebrow { | ||
| 140 | - font-size: 24rpx; | ||
| 141 | - font-weight: 600; | ||
| 142 | - letter-spacing: 4rpx; | ||
| 143 | - color: #a67939; | ||
| 144 | } | 116 | } |
| 145 | 117 | ||
| 146 | - .hero-title { | 118 | + .home-banner__image, |
| 147 | - margin-top: 12rpx; | 119 | + .image-link-card__image { |
| 148 | - font-size: 52rpx; | 120 | + display: block; |
| 149 | - font-weight: 700; | 121 | + width: 100%; |
| 150 | - color: #1f2937; | 122 | + height: 100%; |
| 151 | } | 123 | } |
| 152 | 124 | ||
| 153 | - .hero-desc { | 125 | + .nav-panel { |
| 154 | - margin-top: 18rpx; | 126 | + display: grid; |
| 155 | - font-size: 26rpx; | 127 | + grid-template-columns: repeat(3, minmax(0, 1fr)); |
| 156 | - line-height: 1.8; | 128 | + margin: 32rpx 0 0; |
| 157 | - color: #6b7280; | 129 | + overflow: hidden; |
| 130 | + border-radius: 16rpx; | ||
| 131 | + background: #fff; | ||
| 132 | + box-shadow: 0 16rpx 40rpx rgba(31, 41, 55, 0.06); | ||
| 158 | } | 133 | } |
| 159 | 134 | ||
| 160 | - .status-card { | 135 | + .nav-entry { |
| 161 | - margin-top: 24rpx; | 136 | + position: relative; |
| 162 | - padding: 28rpx 32rpx; | ||
| 163 | display: flex; | 137 | display: flex; |
| 138 | + flex-direction: column; | ||
| 164 | align-items: center; | 139 | align-items: center; |
| 165 | - justify-content: space-between; | 140 | + justify-content: center; |
| 166 | - gap: 24rpx; | 141 | + min-width: 0; |
| 167 | - } | 142 | + min-height: 184rpx; |
| 168 | - | 143 | + padding: 28rpx 8rpx 24rpx; |
| 169 | - .section-label { | 144 | + box-sizing: border-box; |
| 170 | - display: block; | 145 | + color: #98271d; |
| 171 | - font-size: 30rpx; | ||
| 172 | - font-weight: 600; | ||
| 173 | - color: #111827; | ||
| 174 | - } | ||
| 175 | - | ||
| 176 | - .status-text, | ||
| 177 | - .card-desc, | ||
| 178 | - .map-entry-desc, | ||
| 179 | - .webview-entry-desc, | ||
| 180 | - .test-entry-desc { | ||
| 181 | - display: block; | ||
| 182 | - margin-top: 12rpx; | ||
| 183 | - font-size: 24rpx; | ||
| 184 | - line-height: 1.7; | ||
| 185 | - color: #6b7280; | ||
| 186 | - } | ||
| 187 | - | ||
| 188 | - .status-tag { | ||
| 189 | - flex-shrink: 0; | ||
| 190 | - padding: 12rpx 22rpx; | ||
| 191 | - border-radius: 999rpx; | ||
| 192 | - font-size: 24rpx; | ||
| 193 | - font-weight: 600; | ||
| 194 | - color: #b45309; | ||
| 195 | - background: #fef3c7; | ||
| 196 | - } | ||
| 197 | - | ||
| 198 | - .status-tag.authed { | ||
| 199 | - color: #166534; | ||
| 200 | - background: #dcfce7; | ||
| 201 | - } | ||
| 202 | - | ||
| 203 | - .overview-grid { | ||
| 204 | - margin-top: 24rpx; | ||
| 205 | - display: grid; | ||
| 206 | - grid-template-columns: repeat(2, minmax(0, 1fr)); | ||
| 207 | - gap: 20rpx; | ||
| 208 | } | 146 | } |
| 209 | 147 | ||
| 210 | - .overview-card { | 148 | + .nav-entry::after { |
| 211 | - padding: 28rpx; | 149 | + position: absolute; |
| 150 | + top: 0; | ||
| 151 | + right: 0; | ||
| 152 | + width: 1rpx; | ||
| 153 | + height: 100%; | ||
| 154 | + background: #ececec; | ||
| 155 | + content: ''; | ||
| 212 | } | 156 | } |
| 213 | 157 | ||
| 214 | - .overview-card:last-child { | 158 | + .nav-entry:nth-child(3n)::after { |
| 215 | - grid-column: 1 / span 2; | 159 | + display: none; |
| 216 | } | 160 | } |
| 217 | 161 | ||
| 218 | - .card-title { | 162 | + .nav-entry:nth-child(n + 4)::before { |
| 219 | - display: block; | 163 | + position: absolute; |
| 220 | - font-size: 30rpx; | 164 | + top: 0; |
| 221 | - font-weight: 600; | 165 | + left: 0; |
| 222 | - color: #111827; | 166 | + width: 100%; |
| 167 | + height: 1rpx; | ||
| 168 | + background: #ececec; | ||
| 169 | + content: ''; | ||
| 223 | } | 170 | } |
| 224 | 171 | ||
| 225 | - .card-title-row { | 172 | + .nav-entry__icon-wrap { |
| 226 | display: flex; | 173 | display: flex; |
| 227 | align-items: center; | 174 | align-items: center; |
| 228 | - justify-content: space-between; | 175 | + justify-content: center; |
| 229 | - gap: 16rpx; | 176 | + width: 76rpx; |
| 177 | + height: 76rpx; | ||
| 178 | + line-height: 1; | ||
| 230 | } | 179 | } |
| 231 | 180 | ||
| 232 | .iconfont-demo { | 181 | .iconfont-demo { |
| 233 | - flex-shrink: 0; | 182 | + font-size: 64rpx; |
| 234 | - font-size: 42rpx; | 183 | + color: #98271d; |
| 235 | - color: #a67939; | ||
| 236 | } | 184 | } |
| 237 | 185 | ||
| 238 | - .map-entry-card, | 186 | + .nav-entry__title { |
| 239 | - .webview-entry-card, | 187 | + display: block; |
| 240 | - .test-entry-card { | 188 | + width: 100%; |
| 241 | - margin-top: 24rpx; | 189 | + margin-top: 18rpx; |
| 242 | - padding: 32rpx; | 190 | + font-size: 28rpx; |
| 191 | + line-height: 1.25; | ||
| 192 | + text-align: center; | ||
| 193 | + color: #98271d; | ||
| 194 | + word-break: break-all; | ||
| 243 | } | 195 | } |
| 244 | 196 | ||
| 245 | - .primary-btn, | 197 | + .image-link-list { |
| 246 | - .outline-btn { | 198 | + display: flex; |
| 247 | - margin-top: 24rpx; | 199 | + flex-direction: column; |
| 248 | - border-radius: 999rpx; | 200 | + gap: 32rpx; |
| 249 | - font-size: 30rpx; | 201 | + margin-top: 40rpx; |
| 250 | - line-height: 88rpx; | 202 | + padding: 0 4rpx 40rpx; |
| 251 | } | 203 | } |
| 252 | 204 | ||
| 253 | - .primary-btn { | 205 | + .image-link-card { |
| 254 | - color: #fff; | 206 | + position: relative; |
| 255 | - background: linear-gradient(135deg, #a67939, #8f5e20); | 207 | + height: 252rpx; |
| 208 | + overflow: hidden; | ||
| 209 | + border-radius: 12rpx; | ||
| 210 | + background: #d1d5db; | ||
| 256 | } | 211 | } |
| 257 | 212 | ||
| 258 | - .outline-btn { | 213 | + .clickable { |
| 259 | - color: #0f172a; | 214 | + cursor: pointer; |
| 260 | - background: #fff; | ||
| 261 | - border: 2rpx solid #d1d5db; | ||
| 262 | } | 215 | } |
| 263 | } | 216 | } |
| 264 | </style> | 217 | </style> | ... | ... |
-
Please register or login to post a comment