增加了首页语言分类及语言二级菜单,美化了结果路径,添加了内容层级及content居中
This commit is contained in:
parent
1e4470650a
commit
4954abfca4
30
app.py
30
app.py
@ -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
3
langmap.yml
Normal file
@ -0,0 +1,3 @@
|
||||
other: 未分类 Other
|
||||
zh: 中文
|
||||
en: English
|
@ -1,4 +1,5 @@
|
||||
title: 中国大五人格问卷(简式版)
|
||||
lang: zh
|
||||
instructions: 下面是一些描述人们性格特点的句子,请根据每个句子与您性格相符程度选择相应的数字。1-6分别代表完全不符合、大部分不符合、有点不符合、有点符合、大部分符合、完全符合。
|
||||
descriptions: |
|
||||
中国大五人格问卷(CBF-PI)是由王孟成和戴晓阳等编制的,中国拥有其知识产权的人格问卷(相比NEO-PI)。此处是基于其简化的问卷,与完整版问卷的各项相关系数的$r$神经质最小的$0.886$、宜人性最大的$0.922$。
|
||||
|
@ -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
|
||||
|
@ -1,4 +1,5 @@
|
||||
title: 中庸实践思维量表
|
||||
lang: zh
|
||||
instructions: |
|
||||
以下题目是对个人思维方式的描述,不需要过多考虑,请根据你平时的真实想法,或者假设遇到所说的情形时,内心里自动出现的想法进行选择,根据符合度进行打分,答案并无对错之分。
|
||||
|
||||
|
@ -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;
|
||||
/* 适当调整内边距 */
|
||||
}
|
||||
|
@ -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
27
templates/list.html
Normal 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>
|
@ -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>
|
||||
|
||||
|
@ -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>
|
Loading…
x
Reference in New Issue
Block a user