feat: 什么是票根经济?介绍
This commit is contained in:
1 parent
2f35e953df
commit
2ccff41066
6 files changed
+97
-5
No files matched your search
+17
-1
@@ -8,7 +8,7 @@
|
|||||||
* 2)公共内容(协议 / 隐私 / 关于 / 客服)
|
* 2)公共内容(协议 / 隐私 / 关于 / 客服)
|
||||||
* GET /v1/content(列表,登录同意版本号取这里) + GET /v1/content/:key(单条详情)
|
* GET /v1/content(列表,登录同意版本号取这里) + GET /v1/content/:key(单条详情)
|
||||||
*/
|
*/
|
||||||
import { AGREEMENT_DATE, CUSTOMER_SERVICE_PHONE, CUSTOMER_SERVICE_TIME } from "@/constant";
|
import { AGREEMENT_DATE, CUSTOMER_SERVICE_PHONE, CUSTOMER_SERVICE_TIME, TICKET_ECONOMY_KEY } from "@/constant";
|
||||||
import { clone, cnDate, unique } from "@/utils";
|
import { clone, cnDate, unique } from "@/utils";
|
||||||
import { toPublicCard } from "@/api/benefit";
|
import { toPublicCard } from "@/api/benefit";
|
||||||
import * as contentApi from "@/request/api/content";
|
import * as contentApi from "@/request/api/content";
|
||||||
@@ -166,6 +166,21 @@ export const getCustomerService = async () => {
|
|||||||
return { phone: (info && info.phone) || CUSTOMER_SERVICE_PHONE };
|
return { phone: (info && info.phone) || CUSTOMER_SERVICE_PHONE };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------------
|
||||||
|
* 票根经济介绍页(GET /v1/content/ticket_economy)
|
||||||
|
* 口径与公共内容一致:title 作标题、body 作正文(纯文本按行拆段,`一、` 行作小标题)。
|
||||||
|
* 内容全部取自接口,接口无内容时正文为空(无本地兜底)。
|
||||||
|
* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/** 票根经济介绍页:标题 + 正文段落 */
|
||||||
|
export const getTicketEconomy = async () => {
|
||||||
|
const info = await getContent(TICKET_ECONOMY_KEY);
|
||||||
|
return {
|
||||||
|
title: (info && info.title) || "票根经济",
|
||||||
|
blocks: toContentBlocks(info && info.body),
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
getHomepage,
|
getHomepage,
|
||||||
getCategories,
|
getCategories,
|
||||||
@@ -178,4 +193,5 @@ export default {
|
|||||||
getAgreement,
|
getAgreement,
|
||||||
getAbout,
|
getAbout,
|
||||||
getCustomerService,
|
getCustomerService,
|
||||||
|
getTicketEconomy,
|
||||||
};
|
};
|
||||||
@@ -188,5 +188,9 @@ export const ROUTES = {
|
|||||||
DETAIL: "/pages-sub/detail/index",
|
DETAIL: "/pages-sub/detail/index",
|
||||||
AGREEMENT: "/pages-sub/agreement/index",
|
AGREEMENT: "/pages-sub/agreement/index",
|
||||||
ABOUT: "/pages-sub/about/index",
|
ABOUT: "/pages-sub/about/index",
|
||||||
|
INTRO: "/pages-sub/intro/index",
|
||||||
ACCOUNT_CANCEL: "/pages-sub/account/cancel",
|
ACCOUNT_CANCEL: "/pages-sub/account/cancel",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** 票根经济介绍页的内容 key(GET /v1/content/ticket_economy) */
|
||||||
|
export const TICKET_ECONOMY_KEY = "ticket_economy";
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
<script setup>
|
||||||
|
/**
|
||||||
|
* 票根经济介绍页(首页品牌名同行小胶囊进入)
|
||||||
|
* ---------------------------------------------------------------------------
|
||||||
|
* 内容:GET /v1/content/ticket_economy —— 与公共内容同口径,title 作标题、body 作正文。
|
||||||
|
* 布局:根 `h-screen flex flex-col` —— 状态栏 + 导航栏(无底色)为固定区 `shrink-0`,
|
||||||
|
* 正文在导航栏下方的独立 scroll-view 里滚动,正文不会窜到导航栏底下。
|
||||||
|
*/
|
||||||
|
import { ref } from "vue";
|
||||||
|
import contentApi from "@/api/content";
|
||||||
|
|
||||||
|
const title = ref("票根经济");
|
||||||
|
const blocks = ref([]);
|
||||||
|
|
||||||
|
const load = async () => {
|
||||||
|
const res = await contentApi.getTicketEconomy();
|
||||||
|
title.value = res.title;
|
||||||
|
blocks.value = res.blocks || [];
|
||||||
|
};
|
||||||
|
load();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<view class="relative h-screen w-full flex flex-col skin-benefit">
|
||||||
|
<!-- 固定区:状态栏 + 导航栏(无底色、不随内容滚动),标题常显 -->
|
||||||
|
<view class="relative z-[60] shrink-0">
|
||||||
|
<AppStatusBar />
|
||||||
|
<AppNavBar bare :title="title" />
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 滚动区:只有导航栏下方这一块滚动 -->
|
||||||
|
<scroll-view class="flex-1 min-h-0" scroll-y :show-scrollbar="false">
|
||||||
|
<view class="px-5 pt-4 pb-10">
|
||||||
|
<template v-for="(block, i) in blocks" :key="i">
|
||||||
|
<view v-if="block.type === 'h5'" class="text-[14px] font-semibold mt-5 mb-2 text-ink">{{ block.text }}</view>
|
||||||
|
<view v-else class="text-[13px] leading-[1.9] text-[#4B5563]">{{ block.text }}</view>
|
||||||
|
</template>
|
||||||
|
<view class="h-10" />
|
||||||
|
</view>
|
||||||
|
</scroll-view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
@@ -68,6 +68,14 @@
|
|||||||
"enablePullDownRefresh": false
|
"enablePullDownRefresh": false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"path": "intro/index",
|
||||||
|
"style": {
|
||||||
|
"navigationStyle": "custom",
|
||||||
|
"navigationBarTitleText": "票根经济",
|
||||||
|
"enablePullDownRefresh": false
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"path": "account/cancel",
|
"path": "account/cancel",
|
||||||
"style": {
|
"style": {
|
||||||
|
|||||||
@@ -220,6 +220,9 @@ export const goAgreement = (type) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const goAbout = () => uni.navigateTo({ url: ROUTES.ABOUT });
|
export const goAbout = () => uni.navigateTo({ url: ROUTES.ABOUT });
|
||||||
|
|
||||||
|
/** 跳票根经济介绍页 */
|
||||||
|
export const goIntro = () => uni.navigateTo({ url: ROUTES.INTRO });
|
||||||
export const goAccountCancel = () => uni.navigateTo({ url: ROUTES.ACCOUNT_CANCEL });
|
export const goAccountCancel = () => uni.navigateTo({ url: ROUTES.ACCOUNT_CANCEL });
|
||||||
|
|
||||||
/** 拨打电话 */
|
/** 拨打电话 */
|
||||||
|
|||||||
@@ -14,10 +14,12 @@
|
|||||||
*/
|
*/
|
||||||
import { computed, ref } from "vue";
|
import { computed, ref } from "vue";
|
||||||
import contentApi from "@/api/content";
|
import contentApi from "@/api/content";
|
||||||
import { goCatalog, previewImages } from "@/utils/nav";
|
import { goCatalog, goIntro, previewImages } from "@/utils/nav";
|
||||||
|
|
||||||
const home = ref({});
|
const home = ref({});
|
||||||
const featured = ref([]);
|
const featured = ref([]);
|
||||||
|
/** 票根经济入口文案:取接口 /v1/content/ticket_economy 的 title(与首页首屏并行前置请求) */
|
||||||
|
const introTitle = ref("什么是票根经济?");
|
||||||
/** 首屏数据是否已回来(骨架屏开关;请求失败也置真,避免骨架常驻) */
|
/** 首屏数据是否已回来(骨架屏开关;请求失败也置真,避免骨架常驻) */
|
||||||
const loaded = ref(false);
|
const loaded = ref(false);
|
||||||
|
|
||||||
@@ -44,9 +46,15 @@ const load = async () => {
|
|||||||
if (loading) return;
|
if (loading) return;
|
||||||
loading = true;
|
loading = true;
|
||||||
try {
|
try {
|
||||||
const data = await contentApi.getHomepage();
|
// 票根经济介绍内容与首屏一起前置请求:入口文案首屏即为接口值,
|
||||||
|
// 且二级页进入时命中内容缓存(不再等请求)。
|
||||||
|
const [data, intro] = await Promise.all([
|
||||||
|
contentApi.getHomepage(),
|
||||||
|
contentApi.getTicketEconomy(),
|
||||||
|
]);
|
||||||
home.value = data || {};
|
home.value = data || {};
|
||||||
featured.value = data?.featured?.items || [];
|
featured.value = data?.featured?.items || [];
|
||||||
|
if (intro?.title) introTitle.value = intro.title;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
home.value = {};
|
home.value = {};
|
||||||
featured.value = [];
|
featured.value = [];
|
||||||
@@ -140,8 +148,19 @@ const onMapTap = () => {
|
|||||||
<view class="w-[5px] h-[5px] rounded-full bg-brand shadow-[0_0_0_4px_rgba(0,181,120,0.14)]" />
|
<view class="w-[5px] h-[5px] rounded-full bg-brand shadow-[0_0_0_4px_rgba(0,181,120,0.14)]" />
|
||||||
<text>{{ brand.sub_name }}</text>
|
<text>{{ brand.sub_name }}</text>
|
||||||
</view>
|
</view>
|
||||||
<view class="mt-[9px] text-display font-bold tracking-[-1px] leading-[1.1] text-ink">
|
<view class="flex items-center justify-between gap-2 mt-[9px]">
|
||||||
{{ brandHead }}<text class="not-italic gradtext-brand">{{ brandTail }}</text>
|
<view class="min-w-0 truncate text-display font-bold tracking-[-1px] leading-[1.1] text-ink">
|
||||||
|
{{ brandHead }}<text class="not-italic gradtext-brand">{{ brandTail }}</text>
|
||||||
|
</view>
|
||||||
|
<!-- 票根经济介绍入口:贴品牌名右端,半透明白底,不增加固定区高度;相对品牌名基线下移 8px -->
|
||||||
|
<view
|
||||||
|
class="shrink-0 relative top-2 flex items-center gap-[3px] h-[24px] px-[9px] rounded-full bg-[rgba(255,255,255,0.5)] border-[0.5px] border-brand-line"
|
||||||
|
hover-class="opacity-70"
|
||||||
|
@click="goIntro"
|
||||||
|
>
|
||||||
|
<text class="text-[11px] font-semibold text-brand-deep">{{ introTitle }}</text>
|
||||||
|
<AppIcon name="chev" tone="brandDeep" :size="11" />
|
||||||
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="mt-2 text-[11.5px] leading-[1.55] text-ink2 tracking-[0.1px]">
|
<view class="mt-2 text-[11.5px] leading-[1.55] text-ink2 tracking-[0.1px]">
|
||||||
{{ brand.slogan }}
|
{{ brand.slogan }}
|
||||||
|
|||||||
Reference in new issue
Block a user