Compare commits
2 Commits
9e96559a44
...
a05eb8ce29
| Author | SHA1 | Date | |
|---|---|---|---|
| a05eb8ce29 | |||
| 8362334f1b |
@@ -394,3 +394,22 @@ page { -ms-overflow-style: none; scrollbar-width: none; }
|
||||
.ic-shield { -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23fff' stroke-width='2.5'%3E%3Cpath d='M12 3l8 3v5c0 5-3.5 8-8 10-4.5-2-8-5-8-10V6z'/%3E%3Cpath d='M9 12l2 2 4-4'/%3E%3C/svg%3E"); mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23fff' stroke-width='2.5'%3E%3Cpath d='M12 3l8 3v5c0 5-3.5 8-8 10-4.5-2-8-5-8-10V6z'/%3E%3Cpath d='M9 12l2 2 4-4'/%3E%3C/svg%3E"); }
|
||||
.ic-landmark { -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23fff' stroke-width='2.5'%3E%3Cpath d='M3 10l9-6 9 6'/%3E%3Cpath d='M5 10v9M9.5 10v9M14.5 10v9M19 10v9M3 20h18'/%3E%3C/svg%3E"); mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23fff' stroke-width='2.5'%3E%3Cpath d='M3 10l9-6 9 6'/%3E%3Cpath d='M5 10v9M9.5 10v9M14.5 10v9M19 10v9M3 20h18'/%3E%3C/svg%3E"); }
|
||||
.ic-users { -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23fff' stroke-width='2.5'%3E%3Ccircle cx='9' cy='8' r='3.5'/%3E%3Cpath d='M2.5 20a6.5 6.5 0 0 1 13 0'/%3E%3Cpath d='M15.5 5a3.5 3.5 0 0 1 0 6.6'/%3E%3Cpath d='M17.5 14.4a6.5 6.5 0 0 1 4 5.6'/%3E%3C/svg%3E"); mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23fff' stroke-width='2.5'%3E%3Ccircle cx='9' cy='8' r='3.5'/%3E%3Cpath d='M2.5 20a6.5 6.5 0 0 1 13 0'/%3E%3Cpath d='M15.5 5a3.5 3.5 0 0 1 0 6.6'/%3E%3Cpath d='M17.5 14.4a6.5 6.5 0 0 1 4 5.6'/%3E%3C/svg%3E"); }
|
||||
|
||||
/* ============ 统一固定标题区(像素字 kicker + 彩虹渐变标题 + 像素字注脚) ============ */
|
||||
.page-navbar {
|
||||
position: fixed; top: 0; left: 0; right: 0; z-index: 100;
|
||||
padding: 0 28rpx; /* 标题区上下零冗余:高度 = 安全区 + 三行文字,占位实测自然贴合 */
|
||||
background: rgba(247, 249, 255, 0.88);
|
||||
backdrop-filter: blur(20px) saturate(160%);
|
||||
-webkit-backdrop-filter: blur(20px) saturate(160%);
|
||||
}
|
||||
.page-navbar-col { display: flex; flex-direction: column; }
|
||||
.page-navbar-no { font-family: 'BubbledotICG', monospace; color: #a3abc9; font-size: 26rpx; letter-spacing: 2rpx; line-height: 1.15; }
|
||||
.page-navbar-titlerow { display: flex; align-items: baseline; gap: 16rpx; line-height: 1.15; }
|
||||
.page-navbar-title {
|
||||
font-size: 40rpx; font-weight: 800; letter-spacing: -0.5rpx; line-height: 1.15;
|
||||
background: linear-gradient(120deg, #8fc3ff 0%, #a8a0ff 45%, #e0a0ff 80%, #7fe0ff 100%);
|
||||
-webkit-background-clip: text; background-clip: text; color: transparent;
|
||||
}
|
||||
.page-navbar-sub { font-size: 24rpx; color: #5a6aa3; }
|
||||
.page-navbar-en { font-family: 'BubbledotICG', monospace; color: #5b5b5b; font-size: 24rpx; letter-spacing: 2rpx; line-height: 1.15; padding-bottom: 12rpx; }
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
import { View, Text } from '@tarojs/components';
|
||||
import Taro from '@tarojs/taro';
|
||||
import { useState, useEffect } from 'react';
|
||||
|
||||
let cached = null;
|
||||
|
||||
/** 顶部安全区(沉浸式自定义导航用):状态栏 + 胶囊高度。 */
|
||||
export function getTopInset() {
|
||||
if (!cached) {
|
||||
try {
|
||||
const win = Taro.getWindowInfo ? Taro.getWindowInfo() : Taro.getSystemInfoSync();
|
||||
const statusBar = win.statusBarHeight || 44;
|
||||
const windowWidth = win.windowWidth || 375;
|
||||
let navH = statusBar + 44;
|
||||
try {
|
||||
const menu = Taro.getMenuButtonBoundingClientRect ? Taro.getMenuButtonBoundingClientRect() : null;
|
||||
if (menu && menu.height) navH = statusBar + (menu.top - statusBar) * 2 + menu.height;
|
||||
} catch { /* 无胶囊环境用默认 */ }
|
||||
cached = { statusBar, navH, windowWidth };
|
||||
} catch {
|
||||
cached = { statusBar: 44, navH: 88, windowWidth: 375 };
|
||||
}
|
||||
}
|
||||
return cached;
|
||||
}
|
||||
|
||||
/** 统一固定标题区(fixed 不随滚动):像素字 kicker + 彩虹渐变标题 + 像素字注脚。
|
||||
* 占位高度由 createSelectorQuery 实测 navbar 真实高度,绝无空白/覆盖/重复。 */
|
||||
export function PageHeader({ no, title, en, sub }) {
|
||||
const { navH, windowWidth } = getTopInset();
|
||||
// 标题区整体上移 65rpx:从状态栏让位空间中扣除(不是容器偏移,占位实测自动跟随,无空白)
|
||||
const SHIFT_PX = Math.round((65 * (windowWidth || 375)) / 750);
|
||||
const topPad = Math.max(navH - SHIFT_PX, 24); // 下限:至少给状态栏留 24px
|
||||
const [h, setH] = useState(0);
|
||||
|
||||
useEffect(() => {
|
||||
Taro.nextTick(() => {
|
||||
Taro.createSelectorQuery()
|
||||
.select('.page-navbar')
|
||||
.boundingClientRect((r) => { if (r && r.height) setH(r.height); })
|
||||
.exec();
|
||||
});
|
||||
}, [no, title, en, sub]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<View className="page-navbar" style={{ paddingTop: `${topPad}px` }}>
|
||||
<View className="page-navbar-col">
|
||||
{no ? <Text className="page-navbar-no">{no}</Text> : null}
|
||||
<View className="page-navbar-titlerow">
|
||||
<Text className="page-navbar-title">{title}</Text>
|
||||
{sub ? <Text className="page-navbar-sub">{sub}</Text> : null}
|
||||
</View>
|
||||
{en ? <Text className="page-navbar-en">{en}</Text> : null}
|
||||
</View>
|
||||
</View>
|
||||
<View style={{ height: `${h}px` }} />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
/** 沉浸式顶部占位:配合页面 navigationStyle=custom 使用。 */
|
||||
export default function TopInset() {
|
||||
const { navH } = getTopInset();
|
||||
return <View style={{ height: `${navH}px` }} />;
|
||||
}
|
||||
@@ -1 +1 @@
|
||||
export default { navigationBarTitleText: '活动' };
|
||||
export default { navigationBarTitleText: '活动', navigationStyle: 'custom' };
|
||||
|
||||
@@ -7,6 +7,7 @@ import { useTabIndex } from '@/utils/tab';
|
||||
import Skeleton from '@/components/skeleton';
|
||||
import CountdownBox from '@/components/CountdownBox';
|
||||
import './index.scss';
|
||||
import { PageHeader } from '@/components/TopInset';
|
||||
|
||||
const FILTERS = [
|
||||
{ key: 'all', label: '全部' },
|
||||
@@ -31,6 +32,16 @@ export default function Booking() {
|
||||
const [filter, setFilter] = useState('all');
|
||||
const [err, setErr] = useState('');
|
||||
const [loaded, setLoaded] = useState(false);
|
||||
const [tabsTop, setTabsTop] = useState(0);
|
||||
// tabs 吸顶位置 = 固定标题区实测高度(滚动到顶时 tabs 悬浮在标题区正下方)
|
||||
useEffect(() => {
|
||||
Taro.nextTick(() => {
|
||||
Taro.createSelectorQuery()
|
||||
.select('.page-navbar')
|
||||
.boundingClientRect((r) => { if (r && r.height) setTabsTop(r.height); })
|
||||
.exec();
|
||||
});
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
Promise.all([
|
||||
@@ -89,11 +100,7 @@ export default function Booking() {
|
||||
|
||||
return (
|
||||
<View className="events page-in">
|
||||
<View className="ev-head">
|
||||
<Text className="ev-no">EVENTS</Text>
|
||||
<Text className="ev-title">活动</Text>
|
||||
<Text className="ev-en">线下 · 线上 公益课与沙龙</Text>
|
||||
</View>
|
||||
<PageHeader no="EVENTS" title="活动" en="线下 · 线上 公益课与沙龙" />
|
||||
|
||||
{/* 近期活动 · 首屏横幅(始终渲染,数据到位后刷新) */}
|
||||
<View className="mk-section">
|
||||
@@ -109,7 +116,7 @@ export default function Booking() {
|
||||
</View>
|
||||
|
||||
{/* 筛选 tab */}
|
||||
<View className="ev-tabs">
|
||||
<View className="ev-tabs" style={{ top: `${tabsTop}px` }}>
|
||||
{FILTERS.map((f) => (
|
||||
<Text key={f.key} className={`ev-tab${filter === f.key ? ' on' : ''}`} onClick={() => setFilter(f.key)}>{f.label}</Text>
|
||||
))}
|
||||
|
||||
@@ -20,9 +20,12 @@
|
||||
padding: 16rpx 8rpx;
|
||||
margin-top: 0;
|
||||
position: sticky;
|
||||
top: 0;
|
||||
top: 0; /* 运行时由内联 style 覆盖为标题区实测高度 */
|
||||
z-index: 3;
|
||||
background: #f4f6ff;
|
||||
/* 常驻毛玻璃底:非吸顶时与页面底色几乎一致(视觉透明),吸顶悬浮时遮挡滚过的卡片 */
|
||||
background: rgba(247, 249, 255, 0.92);
|
||||
backdrop-filter: blur(20px) saturate(160%);
|
||||
-webkit-backdrop-filter: blur(20px) saturate(160%);
|
||||
/* 顶部用伪元素延伸到视口外,确保吸顶时完全贴合、无透光间隙 */
|
||||
}
|
||||
.ev-tabs::before {
|
||||
@@ -35,11 +38,13 @@
|
||||
background: #f4f6ff;
|
||||
}
|
||||
.ev-tab {
|
||||
font-size: 26rpx; color: #9aa4c6; padding: 10rpx 30rpx;
|
||||
border-radius: 999px; border: 1rpx solid rgba(255,255,255,0.12);
|
||||
font-size: 26rpx; color: #8a94c0; padding: 10rpx 30rpx;
|
||||
border-radius: 999px; border: 1rpx solid rgba(99,132,255,0.14);
|
||||
background: rgba(255,255,255,0.72); backdrop-filter: blur(8px);
|
||||
}
|
||||
.ev-tab.on {
|
||||
color: #0a0d22; background: linear-gradient(120deg, #8fc3ff, #a8a0ff); font-weight: 700; border-color: transparent;
|
||||
color: #ffffff; background: linear-gradient(135deg, #6b8bff, #8f7bff); font-weight: 600; border-color: transparent;
|
||||
box-shadow: 0 8rpx 22rpx rgba(98,132,255,.28);
|
||||
}
|
||||
|
||||
/* 双列瀑布流 */
|
||||
|
||||
@@ -65,7 +65,7 @@
|
||||
.cd-cmt-like { display: flex; align-items: center; gap: 6rpx; }
|
||||
.cd-cmt-like-ic { width: 26rpx; height: 26rpx; }
|
||||
.cd-cmt-like-n { font-size: 22rpx; color: #9aa4c6; }
|
||||
.cd-cmt-like.on .cd-cmt-like-ic { background-color: #e05a6d; }
|
||||
.cd-cmt-like.on .cd-cmt-like-ic { background-color: #ff5f86; }
|
||||
/* 回复嵌套:左缩进 + 竖线 */
|
||||
.cd-cmt-replies { margin-top: 12rpx; padding-left: 24rpx; border-left: 3rpx solid rgba(99,132,255,.18); }
|
||||
.cd-cmt-sub { margin-top: 14rpx; }
|
||||
|
||||
@@ -1 +1 @@
|
||||
export default { navigationBarTitleText: '资讯中心' };
|
||||
export default { navigationBarTitleText: '资讯中心', navigationStyle: 'custom' };
|
||||
|
||||
@@ -5,6 +5,7 @@ import { listContent, CONTENT_CATS } from '@/utils/content';
|
||||
import { useTabIndex } from '@/utils/tab';
|
||||
import Skeleton from '@/components/skeleton';
|
||||
import './index.scss';
|
||||
import { PageHeader } from '@/components/TopInset';
|
||||
|
||||
/** 类别视觉(无 image 字段时用类别渐变占位) */
|
||||
const CAT_META = {
|
||||
@@ -90,7 +91,15 @@ export default function ContentIndex() {
|
||||
|
||||
useEffect(() => {
|
||||
setLoaded(false); setErr('');
|
||||
listContent(cat)
|
||||
const load = cat === 'all'
|
||||
? Promise.all(CONTENT_CATS.map((c) => listContent(c.key).catch(() => [])))
|
||||
.then((ls) => {
|
||||
const all = ls.flat();
|
||||
all.sort((a, b) => (b.priority || 0) - (a.priority || 0) || String(b.created_at || '').localeCompare(String(a.created_at || '')));
|
||||
return all;
|
||||
})
|
||||
: listContent(cat);
|
||||
load
|
||||
.then(setItems)
|
||||
.catch(() => setErr('加载失败,请稍后重试'))
|
||||
.finally(() => setLoaded(true));
|
||||
@@ -101,21 +110,19 @@ export default function ContentIndex() {
|
||||
|
||||
return (
|
||||
<View className="ct page-in">
|
||||
{/* 标准页头:kicker + 渐变大标题 + 英文注脚;类别 tab 药丸居右(对齐「我的」页头样式) */}
|
||||
<View className="ct-head">
|
||||
<View className="ct-head-l">
|
||||
<Text className="ct-no">NEWS</Text>
|
||||
<Text className="ct-title">资讯中心</Text>
|
||||
<Text className="ct-en">INFORMATION</Text>
|
||||
</View>
|
||||
<View className="ct-cats">
|
||||
{CONTENT_CATS.map((c) => (
|
||||
<View key={c.key} className={`ct-cat${cat === c.key ? ' on' : ''}`} onClick={() => setCat(c.key)}>{c.label}</View>
|
||||
))}
|
||||
</View>
|
||||
{/* 固定页头:标题在状态栏左侧,不随滚动 */}
|
||||
{/* 固定标题区 */}
|
||||
<PageHeader no="NEWS" title="资讯中心" en="INFORMATION" />
|
||||
|
||||
{/* 类别 tab(含全部):紧贴标题区下方,位于滚动区之外 */}
|
||||
<View className="ct-cats ct-cats-bar">
|
||||
<View key="all" className={`ct-cat${cat === 'all' ? ' on' : ''}`} onClick={() => setCat('all')}>全部</View>
|
||||
{CONTENT_CATS.map((c) => (
|
||||
<View key={c.key} className={`ct-cat${cat === c.key ? ' on' : ''}`} onClick={() => setCat(c.key)}>{c.label}</View>
|
||||
))}
|
||||
</View>
|
||||
|
||||
{/* 内容区独立滚动:页头(标题+tab)固定不动 */}
|
||||
{/* 内容区独立滚动 */}
|
||||
<ScrollView className="ct-scroll" scrollY enhanced showScrollbar={false}>
|
||||
{/* 政策测评入口(非 tab,政策分类下提供) */}
|
||||
{cat === 'policy' && (
|
||||
@@ -135,6 +142,8 @@ export default function ContentIndex() {
|
||||
) : (
|
||||
<Skeleton />
|
||||
)}
|
||||
{/* 底部留白避开自定义 tabBar(ScrollView 内无法用容器 padding) */}
|
||||
<View className="ct-scroll-pad" />
|
||||
</ScrollView>
|
||||
</View>
|
||||
);
|
||||
|
||||
@@ -2,10 +2,11 @@
|
||||
|
||||
/* 页面柔彩渐变背景(浅色粉紫→薄荷→天蓝) */
|
||||
.ct { position: relative; z-index: 2; display: flex; flex-direction: column;
|
||||
height: 100vh; overflow: hidden; padding: 24rpx 24rpx 0; box-sizing: border-box;
|
||||
height: 100vh; overflow: hidden; padding: 0 24rpx 0; box-sizing: border-box;
|
||||
background: linear-gradient(165deg, #edf2ff 0%, #f6eefc 34%, #ecf7f6 68%, #eaf4ff 100%); }
|
||||
/* 内容区独立滚动(页头固定),底部避开自定义 tabBar */
|
||||
.ct-scroll { flex: 1; min-height: 0; padding-bottom: 180rpx; }
|
||||
/* 内容区独立滚动(页头固定),底部避开自定义 tabBar。
|
||||
height:0 + flex-grow 强制 ScrollView 拿到确定高度,否则微信里内部高度随内容增长、整页滚动 */
|
||||
.ct-scroll { flex: 1 1 0; height: 0; min-height: 0; }
|
||||
/* 顶部柔光装饰(可选,营造 Soft 氛围) */
|
||||
.ct::before { content: ''; position: fixed; inset: 0; z-index: -1;
|
||||
background: radial-gradient(60% 46% at 12% 4%, rgba(229,167,224,.30), transparent 60%),
|
||||
@@ -23,7 +24,14 @@
|
||||
.ct-en { font-family: 'BubbledotICG', monospace; color: #5b5b5b; font-size: 24rpx; letter-spacing: 2rpx; }
|
||||
|
||||
/* 类别 tab:药丸居右,4 个一行与标题同排 */
|
||||
.ct-cats { flex: 1; min-width: 0; display: flex; flex-wrap: nowrap; justify-content: flex-end; gap: 8rpx; padding: 0 0 6rpx; }
|
||||
.ct-cats { min-width: 0; display: flex; flex-wrap: nowrap; justify-content: flex-start; gap: 12rpx; }
|
||||
/* 类别 tab 条:紧贴标题区下方,位于滚动区之外,固定不随内容滚动 */
|
||||
.ct-cats-bar {
|
||||
flex-wrap: nowrap; justify-content: flex-start; gap: 12rpx;
|
||||
padding: 4rpx 0 12rpx;
|
||||
background: transparent;
|
||||
}
|
||||
.ct-cats-bar .ct-cat { flex: 0 0 auto; padding: 10rpx 30rpx; }
|
||||
.ct-cat {
|
||||
flex: 1 1 0; min-width: 0; text-align: center; padding: 8rpx 0; border-radius: 999px; white-space: nowrap; overflow: hidden;
|
||||
background: rgba(255,255,255,.72); border: 1rpx solid rgba(99,132,255,.14); color: #8a94c0; font-size: 22rpx;
|
||||
@@ -86,3 +94,5 @@
|
||||
|
||||
.ct-empty { padding: 80rpx 0; text-align: center; font-size: 26rpx; color: #9aa4c6; }
|
||||
.ct-err { display: block; padding: 60rpx 0; text-align: center; font-size: 26rpx; color: #ff5f86; }
|
||||
|
||||
.ct-scroll-pad { height: 200rpx; }
|
||||
|
||||
@@ -1 +1 @@
|
||||
export default { navigationBarTitleText: 'OPC · 为进化而设计' };
|
||||
export default { navigationBarTitleText: 'OPC · 为进化而设计', navigationStyle: 'custom' };
|
||||
|
||||
@@ -1 +1 @@
|
||||
export default { navigationBarTitleText: '我的' };
|
||||
export default { navigationBarTitleText: '我的', navigationStyle: 'custom' };
|
||||
|
||||
@@ -9,6 +9,7 @@ import { API_BASE } from '@/utils/api';
|
||||
import Skeleton from '@/components/skeleton';
|
||||
import CountdownBox from '@/components/CountdownBox';
|
||||
import './index.scss';
|
||||
import { PageHeader } from '@/components/TopInset';
|
||||
|
||||
/* 报名标签:按 auditStatus + event_status 推断 待参加 / 审核中 / 已结束 / 未通过 */
|
||||
const PHASE_META = {
|
||||
@@ -274,11 +275,7 @@ export default function Mine() {
|
||||
if (!user || !isAuthed()) {
|
||||
return (
|
||||
<View className="mine page-in">
|
||||
<View className="mine-head">
|
||||
<Text className="mine-no">MY</Text>
|
||||
<Text className="mine-title">我的</Text>
|
||||
<Text className="mine-en">Account</Text>
|
||||
</View>
|
||||
<PageHeader no="MY" title="我的" en="Account" />
|
||||
<View className="mine-card login-card">
|
||||
<Button className="btn-main wx-btn" loading={busy} onClick={onWxLogin}>微信一键登录</Button>
|
||||
<Text className="muted mine-tip">登录后可绑定手机、查看报名场次与活动签到</Text>
|
||||
@@ -314,11 +311,7 @@ export default function Mine() {
|
||||
/* ============ 已登录:资料 + 我的报名 ============ */
|
||||
return (
|
||||
<View className="mine page-in">
|
||||
<View className="mine-head">
|
||||
<Text className="mine-no">MY</Text>
|
||||
<Text className="mine-title">我的</Text>
|
||||
<Text className="mine-en">Account</Text>
|
||||
</View>
|
||||
<PageHeader no="MY" title="我的" en="Account" />
|
||||
|
||||
{/* 资料卡 */}
|
||||
<View className="mine-card profile">
|
||||
|
||||
@@ -83,10 +83,11 @@
|
||||
border: 1rpx solid rgba(99, 132, 255, 0.14);
|
||||
}
|
||||
.phase-tab.on {
|
||||
color: #0a0d22;
|
||||
background: linear-gradient(120deg, #8fc3ff, #a8a0ff);
|
||||
font-weight: 700;
|
||||
color: #ffffff;
|
||||
background: linear-gradient(135deg, #6b8bff, #8f7bff);
|
||||
font-weight: 600;
|
||||
border-color: transparent;
|
||||
box-shadow: 0 8rpx 22rpx rgba(98,132,255,.28);
|
||||
}
|
||||
.mine-subtitle {
|
||||
display: block;
|
||||
|
||||
@@ -1 +1 @@
|
||||
export default { navigationBarTitleText: 'OPC 创业测评' };
|
||||
export default { navigationBarTitleText: 'OPC 创业测评', navigationStyle: 'custom' };
|
||||
|
||||
@@ -5,6 +5,7 @@ import { useTabIndex } from '@/utils/tab';
|
||||
import { request } from '@/utils/api';
|
||||
import { getUser } from '@/utils/auth';
|
||||
import './index.scss';
|
||||
import { PageHeader } from '@/components/TopInset';
|
||||
|
||||
const adaptColor = (s) => (s >= 78 ? '#a8f0c8' : s >= 55 ? '#f5d9a0' : '#f0b8b8');
|
||||
|
||||
@@ -102,11 +103,7 @@ export default function Test() {
|
||||
if (stage === 'welcome') {
|
||||
return (
|
||||
<View className="ot page-in">
|
||||
<View className="ot-head">
|
||||
<Text className="ot-no">00</Text>
|
||||
<Text className="ot-title">开始测评</Text>
|
||||
<Text className="ot-en">Start</Text>
|
||||
</View>
|
||||
<PageHeader no="00" title="开始测评" en="Start" />
|
||||
<Text className="ot-intro">
|
||||
一个人,也可以是一家公司。5–10 分钟,看清你的 OPC 赛道、角色与 AI 协作方式。
|
||||
</Text>
|
||||
@@ -194,6 +191,7 @@ export default function Test() {
|
||||
const level = r.adaptLevel || {};
|
||||
return (
|
||||
<View className="ot page-in">
|
||||
<TopInset />
|
||||
{/* 头部:类型码 + 人设 + 适配指数 */}
|
||||
<View className="ot-head">
|
||||
<Text className="ot-no">02</Text>
|
||||
|
||||
Reference in New Issue
Block a user