增加了首页语言分类及语言二级菜单,美化了结果路径,添加了内容层级及content居中

This commit is contained in:
mxr612 2025-03-07 03:54:04 +00:00
parent 1e4470650a
commit 4954abfca4
10 changed files with 117 additions and 48 deletions

30
app.py
View File

@ -15,6 +15,12 @@ app.mount("/static", StaticFiles(directory="static"), name="static")
def load_all_scales():
scale_folder = 'scales'
scales = {}
lang = {}
try:
with open(os.path.join('langmap.yml'), 'r', encoding='utf-8') as f:
langmap = yaml.safe_load(f)
except Exception as e:
print(f"Error loading scale langmap: {e}")
for filename in os.listdir(scale_folder):
if filename.endswith(('.yaml', '.yml')):
try:
@ -22,15 +28,18 @@ def load_all_scales():
scale = yaml.safe_load(f)
scale['instructions']=markdown.markdown(scale['instructions'], extensions=['fenced_code','tables','mdx_math'])
scale['descriptions']=markdown.markdown(scale['descriptions'], extensions=['fenced_code','tables','mdx_math'])
if 'lang' not in scale or scale['lang'] not in langmap:
scale['lang']='other'
lang[scale['lang']]=langmap[scale['lang']]
scale_id = os.path.splitext(filename)[0] # 使用文件名作为标识
scales[scale_id] = scale
except Exception as e:
print(f"Error loading scale {filename}: {e}")
return scales
return lang, scales
@app.get("/", response_class=HTMLResponse)
async def index(request: Request):
scales = load_all_scales()
lang, _ = load_all_scales()
# 新增读取README.md的逻辑
readme_content = ""
try:
@ -40,13 +49,22 @@ async def index(request: Request):
pass # 如果README不存在则静默失败
return templates.TemplateResponse("index.html", {
"request": request,
"scales": scales,
"lang": lang,
"readme_content": readme_content # 新增模板变量
})
@app.get("/{lang}", response_class=HTMLResponse)
async def scale(request: Request, lang: str):
_, scales = load_all_scales()
return templates.TemplateResponse("list.html", {
"request": request,
"scales": scales,
"lang": lang
})
@app.get("/scales/{scale_id}", response_class=HTMLResponse)
async def scale(request: Request, scale_id: str):
scales = load_all_scales()
_, scales = load_all_scales()
scale = scales.get(scale_id)
if scale:
return templates.TemplateResponse("scale.html", {
@ -56,10 +74,10 @@ async def scale(request: Request, scale_id: str):
})
raise HTTPException(status_code=404, detail="问卷未找到")
@app.post("/result/{scale_id}", response_class=HTMLResponse)
@app.post("/scales/{scale_id}", response_class=HTMLResponse)
async def result(request: Request, scale_id: str):
form_data = await request.form()
scales = load_all_scales()
lang, scales = load_all_scales()
scale = scales.get(scale_id)
if scale:
# 这里可以添加保存数据到数据库等逻辑

3
langmap.yml Normal file
View File

@ -0,0 +1,3 @@
other: 未分类 Other
zh: 中文
en: English

View File

@ -1,4 +1,5 @@
title: 中国大五人格问卷(简式版)
lang: zh
instructions: 下面是一些描述人们性格特点的句子请根据每个句子与您性格相符程度选择相应的数字。1-6分别代表完全不符合、大部分不符合、有点不符合、有点符合、大部分符合、完全符合。
descriptions: |
中国大五人格问卷CBF-PI是由王孟成和戴晓阳等编制的中国拥有其知识产权的人格问卷相比NEO-PI。此处是基于其简化的问卷与完整版问卷的各项相关系数的$r$神经质最小的$0.886$、宜人性最大的$0.922$。

View File

@ -1,4 +1,5 @@
title: Symptom Checklist-90 (SCL90)
lang: en
instructions: |
Below is a list of problems and complaints that people sometimes have. Please read each one carefully. After you have done so, select one of the numbered descriptors that best describes HOW
MUCH THAT PROBLEM HAS BOTHERED OR DISTRESSED YOU DURING THE

View File

@ -1,4 +1,5 @@
title: 中庸实践思维量表
lang: zh
instructions: |
以下题目是对个人思维方式的描述,不需要过多考虑,请根据你平时的真实想法,或者假设遇到所说的情形时,内心里自动出现的想法进行选择,根据符合度进行打分,答案并无对错之分。

View File

@ -1,27 +1,35 @@
/* 全局样式 */
body {
font-family: Arial, sans-serif;
line-height: 1.6;
margin: 0;
padding: 0;
padding-top: 20px;
/* 使用 flexbox 布局实现 body 内元素的居中 */
display: flex;
justify-content: center;
align-items: center;
/* 确保 body 至少占据整个视口的高度 */
min-height: 100vh;
}
width: 40%;
max-width: 1200px;
margin: 0 auto;
.content {
/* 可选:添加一些内边距,让内容不紧贴容器边缘 */
padding: 20px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
/* 设置背景颜色为纯白色 */
background-color: #ffffff;
color: #333;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
width: 40%;
max-width: 1200px;
/* 保留 margin: 0 auto; 用于水平居中 */
margin: 0 auto;
}
@media (max-width: 768px) {
body {
.content {
width: 95%;
/* 全屏展示 */
padding-top: 10px;
padding: 10px;
/* 适当调整内边距 */
}

View File

@ -9,17 +9,23 @@
</head>
<body>
{% if readme_content %}
<div class="readme-section">
{{ readme_content|safe }}
<div class="header">
</div>
<div class="content">
{% if readme_content %}
<div class="readme-section">
{{ readme_content|safe }}
</div>
{% endif %}
<ul>
{% for key,value in lang.items() %}
<li><a href="/{{ key }}"">{{ value }}</a></li>
{% endfor %}
</ul>
</div>
{% endif %}
<ul>
{% for scale_id, scale in scales.items() %}
<li><a href="/scales/{{ scale_id }}" , title=" {{ scale.abstract }}">{{ scale.get('title',
'未命名问卷') }}</a></li>
{% endfor %}
</ul>
</body>
</html>

27
templates/list.html Normal file
View File

@ -0,0 +1,27 @@
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>心尺 PsychoScales</title>
<link rel="stylesheet" href="/static/styles.css">
</head>
<body>
<div class="header">
</div>
<div class="content">
<ul>
{% for scale_id, scale in scales.items() %}
{% if scale.lang == lang %}
<li><a href="/scales/{{ scale_id }}" , title=" {{ scale.abstract }}">{{ scale.get('title','未命名问卷') }}</a>
</li>
{% endif %}
{% endfor %}
</ul>
</div>
</body>
</html>

View File

@ -16,14 +16,16 @@
</head>
<body>
<h1>{{ scale.title }} </h1>
<ul>
{% for key, value in responses.items() %}
<li>{{ key }}: 在 {{ranges[key][0]}} 到 {{ranges[key][1]}} 的量表中得分 {{ value }}</li>
{% endfor %}
</ul>
<div>
{{scale.descriptions|safe}}
<div class="content">
<h1>{{ scale.title }} </h1>
<ul>
{% for key, value in responses.items() %}
<li>{{ key }}: 在 {{ranges[key][0]}} 到 {{ranges[key][1]}} 的量表中得分 {{ value }}</li>
{% endfor %}
</ul>
<div>
{{scale.descriptions|safe}}
</div>
</div>
</body>

View File

@ -16,23 +16,25 @@
</head>
<body>
<h1>{{ scale.title }}</h1>
<div>
{{ scale.instructions|safe }}
</div>
<form action="/result/{{ scale_id }}" method="post">
{% for id, question in scale.questions.items() %}
<label for="{{ id }}">{{ id }}. {{ question }}</label>
<div class="scale-button">
{% for option in range(scale.range[0], scale.range[1]+1) %}
<input type="radio" id="{{ id }}_{{ option }}" name="{{ id }}" value="{{ option }}" {% if not ( 'optional'
in question and question.optional) %}required{% endif %}>
<label for="{{ id }}_{{ option }}">{{ option }}</label>
{% endfor %}
<div class="content">
<h1>{{ scale.title }}</h1>
<div>
{{ scale.instructions|safe }}
</div>
{% endfor %}
<input type="submit" value="提交">
</form>
<form action="/scales/{{ scale_id }}" method="post">
{% for id, question in scale.questions.items() %}
<label for="{{ id }}">{{ id }}. {{ question }}</label>
<div class="scale-button">
{% for option in range(scale.range[0], scale.range[1]+1) %}
<input type="radio" id="{{ id }}_{{ option }}" name="{{ id }}" value="{{ option }}" {% if not
( 'optional' in question and question.optional) %}required{% endif %}>
<label for="{{ id }}_{{ option }}">{{ option }}</label>
{% endfor %}
</div>
{% endfor %}
<input type="submit" value="提交">
</form>
</div>
</body>
</html>