Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
C
center-book
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
EzijingWeb
center-book
Commits
5452e724
提交
5452e724
authored
8月 14, 2026
作者:
王鹏飞
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
feat: 添加帮助中心和联系我们页面,优化页面布局和样式
上级
d32120dc
显示空白字符变更
内嵌
并排
正在显示
11 个修改的文件
包含
929 行增加
和
46 行删除
+929
-46
LearningLayout.tsx
apps/learning/src/layouts/LearningLayout.tsx
+2
-1
PageHero.tsx
apps/learning/src/modules/my/help/components/PageHero.tsx
+30
-0
Redbud.tsx
apps/learning/src/modules/my/help/components/Redbud.tsx
+118
-0
AboutView.tsx
apps/learning/src/modules/my/help/views/AboutView.tsx
+138
-16
ContactView.tsx
apps/learning/src/modules/my/help/views/ContactView.tsx
+42
-0
HelpDetailView.tsx
apps/learning/src/modules/my/help/views/HelpDetailView.tsx
+38
-8
HelpListView.tsx
apps/learning/src/modules/my/help/views/HelpListView.tsx
+32
-15
info-pages.css
apps/learning/src/modules/my/help/views/info-pages.css
+524
-0
menu.ts
apps/learning/src/modules/my/layout/menu.ts
+1
-4
routes.tsx
apps/learning/src/modules/my/routes.tsx
+0
-2
routes.tsx
apps/learning/src/router/routes.tsx
+4
-0
没有找到文件。
apps/learning/src/layouts/LearningLayout.tsx
浏览文件 @
5452e724
...
...
@@ -89,6 +89,7 @@ export function LearningLayout() {
<
Layout
.
Footer
className=
'learning-layout__footer'
>
<
nav
className=
'learning-layout__footer-links'
aria
-
label=
'页脚导航'
>
<
Link
to=
'/about'
>
关于我们
</
Link
>
<
Link
to=
'/help'
>
帮助中心
</
Link
>
<
a
href=
'https://webapp-pub.ezijing.com/book-app/agreement/ser_agreement.html?v=3'
target=
'_blank'
...
...
@@ -103,7 +104,7 @@ export function LearningLayout() {
>
隐私政策
</
a
>
<
span
>
联系我们
</
span
>
<
Link
to=
'/contact'
>
联系我们
</
Link
>
</
nav
>
</
Layout
.
Footer
>
<
MobileDownloadModal
/>
...
...
apps/learning/src/modules/my/help/components/PageHero.tsx
0 → 100644
浏览文件 @
5452e724
import
type
{
ReactNode
}
from
'react'
import
{
RedbudBranch
,
RedbudFlower
}
from
'./Redbud'
interface
PageHeroProps
{
title
:
string
intro
?:
ReactNode
/** 眉题,默认「✿ 清控紫荆数智学堂」 */
eyebrow
?:
ReactNode
}
const
brandEyebrow
=
(
<>
<
RedbudFlower
size=
{
13
}
color=
'#ffdce6'
centerColor=
'#b5284e'
/>
清控紫荆数智学堂
</>
)
/** 关于我们 / 帮助中心 / 联系我们 共用的页头:深紫荆红底 + 宋体标题 + 紫荆枝纹样 */
export
function
PageHero
({
title
,
intro
,
eyebrow
=
brandEyebrow
}:
PageHeroProps
)
{
return
(
<
header
className=
'info-hero'
>
<
div
className=
'info-hero__text'
>
<
p
className=
'info-hero__eyebrow'
>
{
eyebrow
}
</
p
>
<
h1
className=
'info-hero__title'
>
{
title
}
</
h1
>
{
intro
?
<
p
className=
'info-hero__intro'
>
{
intro
}
</
p
>
:
null
}
</
div
>
<
RedbudBranch
className=
'info-hero__mark'
/>
</
header
>
)
}
apps/learning/src/modules/my/help/components/Redbud.tsx
0 → 100644
浏览文件 @
5452e724
import
type
{
CSSProperties
}
from
'react'
/** 五瓣紫荆花 —— 品牌的视觉签名,用于列表标记、卡片图标与页头装饰 */
const
PETAL_ANGLES
=
[
0
,
72
,
144
,
216
,
288
]
interface
RedbudFlowerProps
{
size
?:
number
/** 花瓣颜色 */
color
?:
string
/** 花蕊颜色 */
centerColor
?:
string
className
?:
string
style
?:
CSSProperties
}
export
function
RedbudFlower
({
size
=
16
,
color
=
'#aa1941'
,
centerColor
=
'#ffffff'
,
className
,
style
,
}:
RedbudFlowerProps
)
{
return
(
<
svg
className=
{
className
}
style=
{
style
}
width=
{
size
}
height=
{
size
}
viewBox=
'0 0 40 40'
aria
-
hidden=
'true'
focusable=
'false'
>
{
PETAL_ANGLES
.
map
((
angle
)
=>
(
<
ellipse
key=
{
angle
}
cx=
'20'
cy=
'8.4'
rx=
'5.4'
ry=
'7.6'
fill=
{
color
}
transform=
{
`rotate(${angle} 20 20)`
}
/>
))
}
<
circle
cx=
'20'
cy=
'20'
r=
'4.4'
fill=
{
centerColor
}
/>
</
svg
>
)
}
interface
FlowerShapeProps
{
offsetX
:
number
offsetY
:
number
petal
:
string
}
function
FlowerShape
({
offsetX
,
offsetY
,
petal
}:
FlowerShapeProps
)
{
return
(
<
g
transform=
{
`translate(${offsetX} ${offsetY})`
}
>
{
PETAL_ANGLES
.
map
((
angle
)
=>
(
<
ellipse
key=
{
angle
}
cx=
'0'
cy=
'-6'
rx=
'4'
ry=
'5.6'
fill=
{
petal
}
transform=
{
`rotate(${angle})`
}
/>
))
}
<
circle
r=
'3.2'
fill=
'#c2456a'
/>
</
g
>
)
}
/** 花团(紫荆花成簇生于枝干,三朵一组) */
function
FlowerCluster
({
x
,
y
,
scale
}:
{
x
:
number
;
y
:
number
;
scale
:
number
})
{
return
(
<
g
transform=
{
`translate(${x} ${y}) scale(${scale})`
}
>
<
FlowerShape
offsetX=
{
-
14
}
offsetY=
{
-
8
}
petal=
'#ffdce6'
/>
<
FlowerShape
offsetX=
{
0
}
offsetY=
{
0
}
petal=
'#ffffff'
/>
<
FlowerShape
offsetX=
{
12
}
offsetY=
{
-
6
}
petal=
'#ffdce6'
/>
</
g
>
)
}
const
CLUSTERS
=
[
{
x
:
34
,
y
:
92
,
scale
:
1
},
{
x
:
96
,
y
:
60
,
scale
:
0.8
},
{
x
:
168
,
y
:
42
,
scale
:
0.95
},
{
x
:
222
,
y
:
54
,
scale
:
0.65
},
]
interface
RedbudBranchProps
{
className
?:
string
style
?:
CSSProperties
}
/** 一枝紫荆 —— 页头 hero 的装饰纹样(浅色线稿,用于深紫荆红底) */
export
function
RedbudBranch
({
className
,
style
}:
RedbudBranchProps
)
{
return
(
<
svg
className=
{
className
}
style=
{
style
}
viewBox=
'0 0 260 130'
fill=
'none'
aria
-
hidden=
'true'
focusable=
'false'
>
<
path
d=
'M10 118 C 66 112, 128 84, 186 60 C 216 48, 238 42, 252 40'
stroke=
'#ffc9d6'
strokeWidth=
'3'
strokeLinecap=
'round'
/>
<
path
d=
'M96 60 C 88 44, 84 34, 90 22'
stroke=
'#ffc9d6'
strokeWidth=
'2.4'
strokeLinecap=
'round'
/>
{
CLUSTERS
.
map
((
cluster
,
index
)
=>
(
<
FlowerCluster
key=
{
index
}
x=
{
cluster
.
x
}
y=
{
cluster
.
y
}
scale=
{
cluster
.
scale
}
/>
))
}
{
/* 心形叶(紫荆的叶形,尖顶心形) */
}
<
path
d=
'M212 6 C 221 2, 230 8, 230 17 C 230 27, 222 34, 212 30 C 202 34, 194 27, 194 17 C 194 8, 203 2, 212 6 Z'
fill=
'#ffdce6'
opacity=
'0.85'
/>
</
svg
>
)
}
apps/learning/src/modules/my/help/views/AboutView.tsx
浏览文件 @
5452e724
import
{
Card
,
Divider
,
Space
,
Typography
}
from
'antd'
import
{
PageHero
}
from
'../components/PageHero'
import
{
RedbudFlower
}
from
'../components/Redbud'
import
'./info-pages.css'
const
agreementBaseUrl
=
'https://webapp-pub.ezijing.com/book-app/agreement'
const
NUMERALS
=
[
'一'
,
'二'
,
'三'
,
'四'
,
'五'
]
const
teachingLoop
=
[
{
title
:
'编写'
,
desc
:
'多形态工具与 AI 大模型结合的数字教材编辑器'
},
{
title
:
'出版'
,
desc
:
'高品质专业出版服务'
},
{
title
:
'学习'
,
desc
:
'富媒体、交互式数字教材'
},
{
title
:
'测验'
,
desc
:
'基于大数据、多模态 AI 的学习测评'
},
{
title
:
'评价'
,
desc
:
'教学评价与全流程数字化管理'
},
]
const
highlights
=
[
{
title
:
'AI 数字教材编辑器'
,
desc
:
'多形态工具与 AI 大模型结合,打通学校端、出版端、教学端、学生端的完整流程'
,
},
{
title
:
'富媒体交互式教材'
,
desc
:
'支持富媒体、交互式数字教材,满足全流程数字化教学及管理要求'
,
},
{
title
:
'专业出版服务'
,
desc
:
'配套高品质专业出版服务,实现教育资源的优化配置与高效利用'
,
},
]
export
function
AboutView
()
{
return
(
<
main
>
<
Typography
.
Title
level=
{
1
}
>
关于我们
</
Typography
.
Title
>
<
Card
>
<
Space
direction=
'vertical'
size=
'middle'
style=
{
{
width
:
'100%'
,
textAlign
:
'center'
}
}
>
<
Typography
.
Title
level=
{
2
}
style=
{
{
margin
:
0
}
}
>
清控紫荆数智学堂
</
Typography
.
Title
>
<
Typography
.
Text
type=
'secondary'
>
清控紫荆(北京)教育科技股份有限公司
</
Typography
.
Text
>
<
Divider
style=
{
{
margin
:
0
}
}
/>
<
Space
split=
{
<
Divider
type=
'vertical'
/>
}
>
<
main
className=
'info-page'
>
<
PageHero
title=
'关于我们'
intro=
'清控紫荆教育深耕高等教育多年,以数字教材为核心,贯通「编写 — 出版 — 学习 — 测验 — 评价」的教学闭环。'
/>
<
section
className=
'info-section'
>
<
h2
className=
'info-section__title'
>
教学闭环
</
h2
>
<
p
className=
'info-section__lede'
>
数字教材的重要性并不局限于教材的编写与出版——它更应服务于教学的后续环节,构建起以数字教材为核心的完整教学闭环。
</
p
>
<
div
className=
'info-flow'
>
<
ol
className=
'info-flow__steps'
>
{
teachingLoop
.
map
((
step
,
index
)
=>
(
<
li
className=
'info-flow__step'
key=
{
step
.
title
}
>
<
span
className=
'info-flow__num'
aria
-
hidden=
'true'
>
{
NUMERALS
[
index
]
}
</
span
>
<
span
className=
'info-flow__name'
>
{
step
.
title
}
</
span
>
<
span
className=
'info-flow__desc'
>
{
step
.
desc
}
</
span
>
{
index
<
teachingLoop
.
length
-
1
?
(
<
span
className=
'info-flow__arrow'
aria
-
hidden=
'true'
>
→
</
span
>
)
:
null
}
</
li
>
))
}
</
ol
>
<
svg
className=
'info-flow__loop'
viewBox=
'0 0 800 46'
preserveAspectRatio=
'none'
aria
-
hidden=
'true'
>
<
defs
>
<
marker
id=
'info-loop-arrow'
viewBox=
'0 0 10 10'
refX=
'9'
refY=
'5'
markerWidth=
'7'
markerHeight=
'7'
orient=
'auto'
>
<
path
d=
'M0 0 L10 5 L0 10 z'
fill=
'#aa1941'
/>
</
marker
>
</
defs
>
<
path
d=
'M720 14 C 560 46, 240 46, 80 14'
fill=
'none'
stroke=
'#aa1941'
strokeWidth=
'2'
strokeDasharray=
'0.5 8'
strokeLinecap=
'round'
markerEnd=
'url(#info-loop-arrow)'
/>
</
svg
>
<
p
className=
'info-flow__caption'
>
循环往复,构筑教育新质生产力
</
p
>
</
div
>
</
section
>
<
section
className=
'info-section'
>
<
h2
className=
'info-section__title'
>
平台能力
</
h2
>
<
p
className=
'info-section__lede'
>
平台打通「学校端 — 出版端 — 教学端 — 学生端」的完整流程,基于大数据、多模态的 AI 辅助教学,配套高品质专业出版服务。
</
p
>
<
div
className=
'info-highlights'
>
{
highlights
.
map
((
item
)
=>
(
<
article
className=
'info-highlight'
key=
{
item
.
title
}
>
<
span
className=
'info-highlight__icon'
>
<
RedbudFlower
size=
{
22
}
/>
</
span
>
<
h3
className=
'info-highlight__title'
>
{
item
.
title
}
</
h3
>
<
p
className=
'info-highlight__desc'
>
{
item
.
desc
}
</
p
>
</
article
>
))
}
</
div
>
</
section
>
<
section
className=
'info-card info-meta'
aria
-
label=
'公司信息'
>
<
dl
className=
'info-meta__rows'
>
<
div
className=
'info-meta__row'
>
<
dt
>
公司名称
</
dt
>
<
dd
>
清控紫荆(北京)教育科技股份有限公司
</
dd
>
</
div
>
<
div
className=
'info-meta__row'
>
<
dt
>
地址
</
dt
>
<
dd
>
北京市海淀区北四环西路52号方正国际大厦5层501
</
dd
>
</
div
>
<
div
className=
'info-meta__row'
>
<
dt
>
联系电话
</
dt
>
<
dd
>
<
a
href=
'tel:010-62793909'
>
010-62793909
</
a
>
</
dd
>
</
div
>
<
div
className=
'info-meta__row'
>
<
dt
>
邮箱
</
dt
>
<
dd
>
<
a
href=
'mailto:service@ezijing.com'
>
service@ezijing.com
</
a
>
</
dd
>
</
div
>
<
div
className=
'info-meta__row'
>
<
dt
>
相关协议
</
dt
>
<
dd
>
<
a
href=
{
`${agreementBaseUrl}/ser_agreement.html?v=3`
}
target=
'_blank'
rel=
'noreferrer'
>
《用户协议》
</
a
>
<
a
href=
{
`${agreementBaseUrl}/pri_agreement.html?v=3`
}
target=
'_blank'
rel=
'noreferrer'
>
《隐私政策》
</
a
>
</
Space
>
<
Typography
.
Text
type=
'secondary'
>
</
dd
>
</
div
>
</
dl
>
<
p
className=
'info-meta__copyright'
>
Copyright © 2026 Zijing Education. All rights reserved.
<
br
/>
京ICP证150431号
</
Typography
.
Text
>
</
Space
>
</
Card
>
</
p
>
</
section
>
</
main
>
)
}
apps/learning/src/modules/my/help/views/ContactView.tsx
0 → 100644
浏览文件 @
5452e724
import
{
EnvironmentOutlined
,
MailOutlined
,
PhoneOutlined
}
from
'@ant-design/icons'
import
{
PageHero
}
from
'../components/PageHero'
import
'./info-pages.css'
const
contactChannels
=
[
{
key
:
'address'
,
icon
:
EnvironmentOutlined
,
label
:
'公司地址'
,
value
:
'北京市海淀区北四环西路52号方正国际大厦5层501'
,
},
{
key
:
'phone'
,
icon
:
PhoneOutlined
,
label
:
'联系电话'
,
value
:
'010-62793909'
,
href
:
'tel:010-62793909'
},
{
key
:
'email'
,
icon
:
MailOutlined
,
label
:
'电子邮箱'
,
value
:
'service@ezijing.com'
,
href
:
'mailto:service@ezijing.com'
,
},
]
export
function
ContactView
()
{
return
(
<
main
className=
'info-page'
>
<
PageHero
title=
'联系我们'
intro=
'清控紫荆(北京)教育科技股份有限公司。使用平台时遇到任何问题,均可通过以下方式与我们联系。'
/>
<
section
className=
'contact-cards'
aria
-
label=
'联系方式'
>
{
contactChannels
.
map
(({
key
,
icon
:
Icon
,
label
,
value
,
href
})
=>
(
<
article
className=
'contact-card'
key=
{
key
}
>
<
span
className=
'contact-card__icon'
>
<
Icon
/>
</
span
>
<
p
className=
'contact-card__label'
>
{
label
}
</
p
>
<
p
className=
'contact-card__value'
>
{
href
?
<
a
href=
{
href
}
>
{
value
}
</
a
>
:
value
}
</
p
>
</
article
>
))
}
</
section
>
</
main
>
)
}
apps/learning/src/modules/my/help/views/HelpDetailView.tsx
浏览文件 @
5452e724
import
{
useQuery
}
from
'@tanstack/react-query'
import
{
Alert
,
Button
,
Card
,
Skeleton
,
Typography
}
from
'antd'
import
{
useParams
}
from
'react-router'
import
{
Alert
,
Button
,
Card
,
Skeleton
}
from
'antd'
import
{
Link
,
useParams
}
from
'react-router'
import
{
helpArticleOptions
}
from
'../query'
import
{
PageHero
}
from
'../components/PageHero'
import
'./info-pages.css'
const
ARTICLE_BASE_STYLES
=
'body{margin:0;padding:24px;color:#262626;font:16px/1.75 -apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;word-break:break-word}img,video,table,pre,code{max-width:100%;box-sizing:border-box}pre{white-space:pre-wrap}table,td,th{border:1px solid #d9d9d9;border-collapse:collapse;padding:6px}'
export
function
HelpDetailView
()
{
const
{
id
=
''
}
=
useParams
()
const
articleQuery
=
useQuery
(
helpArticleOptions
(
id
))
if
(
articleQuery
.
isPending
)
return
<
Skeleton
active
paragraph=
{
{
rows
:
12
}
}
/>
if
(
articleQuery
.
isPending
)
return
(
<
main
className=
'info-page'
>
<
section
className=
'info-card'
>
<
Skeleton
active
paragraph=
{
{
rows
:
10
}
}
style=
{
{
padding
:
'16px 0'
}
}
/>
</
section
>
</
main
>
)
if
(
articleQuery
.
isError
)
return
(
<
main
className=
'info-page'
>
<
PageHero
title=
'帮助详情'
intro=
'文章加载失败,请稍后重试。'
/>
<
section
className=
'info-card'
>
<
Alert
style=
{
{
margin
:
'16px 0'
}
}
type=
'error'
showIcon
message=
'帮助详情加载失败'
description=
{
articleQuery
.
error
.
message
}
action=
{
<
Button
onClick=
{
()
=>
void
articleQuery
.
refetch
()
}
>
重试
</
Button
>
}
/>
</
section
>
</
main
>
)
const
article
=
articleQuery
.
data
if
(
!
article
)
return
null
return
(
<
main
>
<
Typography
.
Title
level=
{
1
}
>
{
article
.
title
||
'帮助详情'
}
</
Typography
.
Title
>
<
Card
bodyStyle=
{
{
padding
:
0
}
}
>
<
main
className=
'info-page'
>
<
PageHero
title=
{
article
.
title
||
'帮助详情'
}
intro=
{
<>
使用指南与常见问题。如未找到所需内容,可前往
<
Link
to=
'/contact'
>
联系我们
</
Link
>
获取帮助。
</>
}
eyebrow=
{
<
Link
to=
'/help'
>
← 返回帮助中心
</
Link
>
}
/>
<
Card
className=
'info-doc'
styles=
{
{
body
:
{
padding
:
0
}
}
}
>
<
iframe
className=
'info-doc__frame'
title=
{
article
.
title
||
'帮助详情'
}
sandbox=
''
srcDoc=
{
`<!doctype html><html lang="zh-CN"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><style>body{margin:0;padding:24px;color:#262626;font:16px/1.75 -apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;word-break:break-word}img,video,table,pre,code{max-width:100%;box-sizing:border-box}pre{white-space:pre-wrap}table,td,th{border:1px solid #d9d9d9;border-collapse:collapse;padding:6px}</style></head><body>${article.content}</body></html>`
}
style=
{
{
width
:
'100%'
,
minHeight
:
480
,
border
:
0
,
display
:
'block'
}
}
srcDoc=
{
`<!doctype html><html lang="zh-CN"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><style>${ARTICLE_BASE_STYLES}</style></head><body>${article.content}</body></html>`
}
/>
</
Card
>
</
main
>
...
...
apps/learning/src/modules/my/help/views/HelpListView.tsx
浏览文件 @
5452e724
import
{
useQuery
}
from
'@tanstack/react-query'
import
{
Alert
,
Button
,
Empty
,
List
,
Skeleton
,
Typography
}
from
'antd'
import
{
RightOutlined
}
from
'@ant-design/icons'
import
{
Alert
,
Button
,
Empty
,
Skeleton
}
from
'antd'
import
{
Link
}
from
'react-router'
import
{
helpArticlesOptions
}
from
'../query'
import
{
PageHero
}
from
'../components/PageHero'
import
{
RedbudFlower
}
from
'../components/Redbud'
import
'./info-pages.css'
export
function
HelpListView
()
{
const
articlesQuery
=
useQuery
(
helpArticlesOptions
())
const
articles
=
articlesQuery
.
data
??
[]
return
(
<
main
>
<
Typography
.
Title
level=
{
1
}
>
帮助中心
</
Typography
.
Title
>
{
articlesQuery
.
isPending
?
<
Skeleton
active
paragraph=
{
{
rows
:
10
}
}
/>
:
null
}
<
main
className=
'info-page'
>
<
PageHero
title=
'帮助中心'
intro=
'常见问题与使用指南,助你更快上手数智学堂。'
/>
<
section
className=
'info-card'
aria
-
label=
'帮助文章列表'
>
{
articlesQuery
.
isPending
?
(
<
Skeleton
active
paragraph=
{
{
rows
:
8
}
}
style=
{
{
padding
:
'16px 0'
}
}
/>
)
:
null
}
{
articlesQuery
.
isError
?
(
<
Alert
style=
{
{
margin
:
'16px 0'
}
}
type=
'error'
showIcon
message=
'帮助内容加载失败'
...
...
@@ -19,20 +27,29 @@ export function HelpListView() {
action=
{
<
Button
onClick=
{
()
=>
void
articlesQuery
.
refetch
()
}
>
重试
</
Button
>
}
/>
)
:
null
}
{
articlesQuery
.
data
&&
articles
.
length
===
0
?
<
Empty
description=
'暂无帮助内容'
/>
:
null
}
{
articlesQuery
.
data
&&
articles
.
length
===
0
?
(
<
Empty
description=
'暂无帮助内容'
style=
{
{
padding
:
'32px 0'
}
}
/>
)
:
null
}
{
articles
.
length
?
(
<
List
bordered
dataSource=
{
articles
}
renderItem=
{
(
article
,
index
)
=>
(
<
List
.
Item
>
<
Link
to=
{
`/my/help/${encodeURIComponent(article.id)}`
}
>
{
index
+
1
}
.
{
article
.
title
}
<
ul
className=
'info-list'
>
{
articles
.
map
((
article
,
index
)
=>
(
<
li
className=
'info-list__item'
key=
{
article
.
id
}
style=
{
{
animationDelay
:
`${index * 36}ms`
}
}
>
<
Link
className=
'info-list__link'
to=
{
`/help/${encodeURIComponent(article.id)}`
}
>
<
span
className=
'info-list__flower'
>
<
RedbudFlower
size=
{
15
}
/>
</
span
>
<
span
className=
'info-list__title'
>
{
article
.
title
}
</
span
>
<
RightOutlined
className=
'info-list__chevron'
/>
</
Link
>
</
List
.
Item
>
)
}
/
>
</
li
>
)
)
}
</
ul
>
)
:
null
}
</
section
>
</
main
>
)
}
apps/learning/src/modules/my/help/views/info-pages.css
0 → 100644
浏览文件 @
5452e724
/* 关于我们 / 帮助中心 / 联系我们 ——「紫荆印象」页面家族样式 */
.info-page
{
display
:
grid
;
gap
:
28px
;
--info-crimson
:
#aa1941
;
--info-blush
:
#fff1f4
;
--info-line
:
#e9ebef
;
--info-ink
:
#252b36
;
--info-muted
:
#6b7280
;
--info-faint
:
#9ca3af
;
--info-serif
:
'Songti SC'
,
'STSong'
,
'Noto Serif CJK SC'
,
'SimSun'
,
serif
;
}
/* ---------- 页头 hero ---------- */
.info-hero
{
position
:
relative
;
display
:
flex
;
min-height
:
224px
;
padding
:
52px
56px
;
overflow
:
hidden
;
align-items
:
center
;
color
:
#fff
;
background
:
radial-gradient
(
130%
180%
at
90%
-30%
,
rgb
(
255
255
255
/
12%
),
transparent
52%
),
linear-gradient
(
128deg
,
#7b1230
0%
,
#aa1941
56%
,
#b5284e
100%
);
border-radius
:
20px
;
}
.info-hero__text
{
position
:
relative
;
z-index
:
1
;
max-width
:
600px
;
}
.info-hero__eyebrow
{
display
:
inline-flex
;
gap
:
8px
;
margin
:
0
0
18px
;
align-items
:
center
;
color
:
rgb
(
255
255
255
/
74%
);
font-size
:
13px
;
letter-spacing
:
0.32em
;
}
.info-hero__eyebrow
a
{
color
:
rgb
(
255
255
255
/
88%
);
letter-spacing
:
normal
;
text-decoration
:
none
;
}
.info-hero__eyebrow
a
:hover
{
color
:
#fff
;
text-decoration
:
underline
;
text-underline-offset
:
4px
;
}
.info-hero__title
{
margin
:
0
;
font-family
:
var
(
--info-serif
);
font-size
:
clamp
(
30px
,
3.6vw
,
42px
);
font-weight
:
700
;
letter-spacing
:
0.08em
;
line-height
:
1.3
;
}
.info-hero__intro
{
max-width
:
480px
;
margin
:
14px
0
0
;
color
:
rgb
(
255
255
255
/
84%
);
font-size
:
15px
;
line-height
:
1.85
;
}
.info-hero__intro
a
{
color
:
#fff
;
text-decoration
:
underline
;
text-underline-offset
:
4px
;
}
.info-hero__mark
{
position
:
absolute
;
right
:
20px
;
bottom
:
-6px
;
width
:
min
(
320px
,
40%
);
opacity
:
0.92
;
animation
:
info-drift
9s
ease-in-out
infinite
alternate
;
}
@keyframes
info-drift
{
from
{
transform
:
translateY
(
0
)
rotate
(
0deg
);
}
to
{
transform
:
translateY
(
-7px
)
rotate
(
-1.4deg
);
}
}
/* ---------- 通用卡片与章节 ---------- */
.info-section
{
display
:
grid
;
gap
:
18px
;
}
.info-section__title
{
margin
:
0
;
color
:
var
(
--info-ink
);
font-family
:
var
(
--info-serif
);
font-size
:
22px
;
font-weight
:
700
;
letter-spacing
:
0.06em
;
}
.info-section__lede
{
max-width
:
680px
;
margin
:
-6px
0
0
;
color
:
var
(
--info-muted
);
font-size
:
14px
;
line-height
:
1.9
;
}
.info-card
{
padding
:
8px
28px
;
background
:
#fff
;
border
:
1px
solid
var
(
--info-line
);
border-radius
:
16px
;
}
/* ---------- 关于我们:教学闭环 ---------- */
.info-flow
{
display
:
grid
;
gap
:
10px
;
}
.info-flow__steps
{
display
:
grid
;
grid-template-columns
:
repeat
(
5
,
1
fr
);
gap
:
28px
;
margin
:
0
;
padding
:
0
;
list-style
:
none
;
}
.info-flow__step
{
position
:
relative
;
display
:
grid
;
gap
:
8px
;
padding
:
24px
20px
;
justify-items
:
start
;
background
:
#fff
;
border
:
1px
solid
var
(
--info-line
);
border-radius
:
14px
;
}
.info-flow__arrow
{
position
:
absolute
;
top
:
50%
;
right
:
-22px
;
z-index
:
1
;
color
:
var
(
--info-crimson
);
font-size
:
15px
;
line-height
:
1
;
transform
:
translateY
(
-50%
);
}
.info-flow__num
{
color
:
var
(
--info-crimson
);
font-family
:
var
(
--info-serif
);
font-size
:
20px
;
font-weight
:
700
;
}
.info-flow__name
{
color
:
var
(
--info-ink
);
font-size
:
15px
;
font-weight
:
600
;
}
.info-flow__desc
{
margin
:
0
;
color
:
var
(
--info-muted
);
font-size
:
13px
;
line-height
:
1.7
;
}
.info-flow__loop
{
display
:
block
;
width
:
100%
;
height
:
46px
;
}
.info-flow__caption
{
margin
:
0
;
color
:
var
(
--info-faint
);
font-size
:
12px
;
letter-spacing
:
0.3em
;
text-align
:
center
;
}
/* ---------- 关于我们:平台能力 ---------- */
.info-highlights
{
display
:
grid
;
grid-template-columns
:
repeat
(
3
,
1
fr
);
gap
:
20px
;
}
.info-highlight
{
display
:
grid
;
gap
:
12px
;
padding
:
26px
24px
;
background
:
#fff
;
border
:
1px
solid
var
(
--info-line
);
border-radius
:
14px
;
transition
:
border-color
180ms
ease-out
,
box-shadow
180ms
ease-out
,
transform
180ms
ease-out
;
}
.info-highlight
:hover
{
border-color
:
#efc3cf
;
box-shadow
:
var
(
--learning-shadow
);
transform
:
translateY
(
-2px
);
}
.info-highlight__icon
{
display
:
grid
;
width
:
42px
;
height
:
42px
;
place-items
:
center
;
background
:
var
(
--info-blush
);
border-radius
:
12px
;
}
.info-highlight__title
{
margin
:
0
;
color
:
var
(
--info-ink
);
font-size
:
15px
;
font-weight
:
600
;
}
.info-highlight__desc
{
margin
:
0
;
color
:
var
(
--info-muted
);
font-size
:
13px
;
line-height
:
1.75
;
}
/* ---------- 关于我们:公司信息 ---------- */
.info-meta
{
display
:
grid
;
gap
:
4px
;
padding
:
28px
;
}
.info-meta__rows
{
display
:
grid
;
gap
:
12px
;
margin
:
0
;
}
.info-meta__row
{
display
:
flex
;
gap
:
8px
28px
;
align-items
:
baseline
;
flex-wrap
:
wrap
;
color
:
#4b5563
;
font-size
:
14px
;
line-height
:
1.7
;
}
.info-meta__row
dt
{
flex
:
0
0
76px
;
color
:
var
(
--info-faint
);
font-size
:
13px
;
}
.info-meta__row
dd
{
margin
:
0
;
}
.info-meta__row
a
{
color
:
var
(
--info-crimson
);
text-decoration
:
none
;
}
.info-meta__row
a
:hover
{
text-decoration
:
underline
;
text-underline-offset
:
3px
;
}
.info-meta__row
a
+
a
{
margin-left
:
20px
;
}
.info-meta__copyright
{
margin
:
8px
0
0
;
padding-top
:
18px
;
color
:
var
(
--info-faint
);
font-size
:
12px
;
line-height
:
1.9
;
text-align
:
center
;
border-top
:
1px
solid
#f1f2f5
;
}
/* ---------- 帮助中心:文章列表 ---------- */
.info-list
{
margin
:
0
;
padding
:
0
;
list-style
:
none
;
}
.info-list__item
{
border-bottom
:
1px
solid
#f1f2f5
;
animation
:
info-rise
360ms
ease-out
both
;
}
.info-list__item
:last-child
{
border-bottom
:
0
;
}
.info-list__link
{
display
:
flex
;
gap
:
14px
;
padding
:
18px
4px
;
align-items
:
center
;
color
:
var
(
--info-ink
);
text-decoration
:
none
;
transition
:
color
160ms
ease-out
;
}
.info-list__link
:hover
{
color
:
var
(
--info-crimson
);
}
.info-list__flower
{
display
:
inline-flex
;
flex
:
0
0
auto
;
transition
:
transform
300ms
cubic-bezier
(
0.34
,
1.56
,
0.64
,
1
);
}
.info-list__link
:hover
.info-list__flower
{
transform
:
rotate
(
26deg
)
scale
(
1.1
);
}
.info-list__title
{
flex
:
1
;
min-width
:
0
;
overflow
:
hidden
;
font-size
:
15px
;
text-overflow
:
ellipsis
;
white-space
:
nowrap
;
}
.info-list__chevron
{
flex
:
0
0
auto
;
color
:
#c3c7ce
;
font-size
:
12px
;
transition
:
color
160ms
ease-out
,
transform
160ms
ease-out
;
}
.info-list__link
:hover
.info-list__chevron
{
color
:
var
(
--info-crimson
);
transform
:
translateX
(
3px
);
}
@keyframes
info-rise
{
from
{
opacity
:
0
;
transform
:
translateY
(
6px
);
}
to
{
opacity
:
1
;
transform
:
none
;
}
}
/* ---------- 联系我们:联系方式卡片 ---------- */
.contact-cards
{
display
:
grid
;
grid-template-columns
:
repeat
(
3
,
1
fr
);
gap
:
20px
;
}
.contact-card
{
display
:
grid
;
gap
:
14px
;
padding
:
30px
26px
;
justify-items
:
start
;
background
:
#fff
;
border
:
1px
solid
var
(
--info-line
);
border-radius
:
14px
;
transition
:
border-color
180ms
ease-out
,
box-shadow
180ms
ease-out
;
}
.contact-card
:hover
{
border-color
:
#efc3cf
;
box-shadow
:
var
(
--learning-shadow
);
}
.contact-card__icon
{
display
:
grid
;
width
:
46px
;
height
:
46px
;
place-items
:
center
;
color
:
var
(
--info-crimson
);
font-size
:
19px
;
background
:
var
(
--info-blush
);
border-radius
:
50%
;
}
.contact-card__label
{
margin
:
0
;
color
:
var
(
--info-faint
);
font-size
:
12px
;
letter-spacing
:
0.22em
;
}
.contact-card__value
{
margin
:
0
;
color
:
var
(
--info-ink
);
font-size
:
15px
;
font-weight
:
600
;
line-height
:
1.7
;
}
.contact-card__value
a
{
color
:
inherit
;
text-decoration
:
none
;
}
.contact-card__value
a
:hover
{
color
:
var
(
--info-crimson
);
text-decoration
:
underline
;
text-underline-offset
:
3px
;
}
/* ---------- 帮助详情:文档容器 ---------- */
.info-doc.ant-card
{
overflow
:
hidden
;
border-color
:
var
(
--info-line
);
border-radius
:
16px
;
}
.info-doc__frame
{
display
:
block
;
width
:
100%
;
min-height
:
clamp
(
380px
,
58vh
,
780px
);
border
:
0
;
}
/* ---------- 响应式 ---------- */
@media
(
max-width
:
960px
)
{
.info-highlights
,
.contact-cards
{
grid-template-columns
:
1
fr
;
}
.info-flow__steps
{
grid-template-columns
:
1
fr
;
gap
:
30px
;
}
.info-flow__arrow
{
top
:
auto
;
right
:
auto
;
bottom
:
-24px
;
left
:
50%
;
transform
:
translateX
(
-50%
)
rotate
(
90deg
);
}
.info-flow__loop
{
display
:
none
;
}
}
@media
(
max-width
:
640px
)
{
.info-hero
{
min-height
:
196px
;
padding
:
36px
24px
;
}
.info-hero__mark
{
right
:
-40px
;
width
:
220px
;
opacity
:
0.6
;
}
.info-card
{
padding
:
8px
18px
;
}
.info-meta
{
padding
:
22px
18px
;
}
.info-meta__row
dt
{
flex-basis
:
auto
;
min-width
:
70px
;
}
}
@media
(
prefers-reduced-motion
:
reduce
)
{
.info-hero__mark
{
animation
:
none
;
}
.info-list__item
{
animation
:
none
;
}
}
apps/learning/src/modules/my/layout/menu.ts
浏览文件 @
5452e724
...
...
@@ -42,10 +42,7 @@ export const myMenuGroups: MyMenuGroup[] = [
{
key
:
'help-feedback'
,
label
:
'帮助与反馈'
,
items
:
[
{
path
:
'/my/help'
,
label
:
'帮助中心'
},
{
path
:
'/my/feedback'
,
label
:
'意见反馈'
},
],
items
:
[{
path
:
'/my/feedback'
,
label
:
'意见反馈'
}],
},
]
...
...
apps/learning/src/modules/my/routes.tsx
浏览文件 @
5452e724
...
...
@@ -6,7 +6,6 @@ import { routes as couponRoutes } from './coupons/routes'
import
{
MyDiscussionsView
}
from
'./discussions/views/MyDiscussionsView'
import
{
routes
as
feedbackRoutes
}
from
'./feedback/routes'
import
{
MyFavoritesView
}
from
'./favorites/views/MyFavoritesView'
import
{
routes
as
helpRoutes
}
from
'./help/routes'
import
{
MyHistoryView
}
from
'./history/views/MyHistoryView'
import
{
MyLayout
}
from
'./layout/MyLayout'
import
{
routes
as
messageRoutes
}
from
'./messages/routes'
...
...
@@ -44,7 +43,6 @@ export const routes: RouteObject[] = [
...
securityRoutes
,
...
messageRoutes
,
...
feedbackRoutes
,
...
helpRoutes
,
],
},
]
apps/learning/src/router/routes.tsx
浏览文件 @
5452e724
...
...
@@ -6,10 +6,14 @@ import { routes as libraryRoutes } from '@/modules/library/routes'
import
{
routes
as
myRoutes
}
from
'@/modules/my/routes'
import
{
routes
as
readerRoutes
}
from
'@/modules/reader/routes'
import
{
AboutView
}
from
'@/modules/my/help/views/AboutView'
import
{
ContactView
}
from
'@/modules/my/help/views/ContactView'
import
{
routes
as
helpRoutes
}
from
'@/modules/my/help/routes'
export
const
appChildRoutes
:
RouteObject
[]
=
[
{
index
:
true
,
element
:
<
Navigate
to=
'/library'
replace
/>
},
{
path
:
'about'
,
element
:
<
AboutView
/>
},
{
path
:
'contact'
,
element
:
<
ContactView
/>
},
...
helpRoutes
,
...
libraryRoutes
,
...
bookRoutes
,
...
myRoutes
,
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论