增加了首页语言分类及语言二级菜单,美化了结果路径,添加了内容层级及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():
|
def load_all_scales():
|
||||||
scale_folder = 'scales'
|
scale_folder = 'scales'
|
||||||
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):
|
for filename in os.listdir(scale_folder):
|
||||||
if filename.endswith(('.yaml', '.yml')):
|
if filename.endswith(('.yaml', '.yml')):
|
||||||
try:
|
try:
|
||||||
@ -22,15 +28,18 @@ def load_all_scales():
|
|||||||
scale = yaml.safe_load(f)
|
scale = yaml.safe_load(f)
|
||||||
scale['instructions']=markdown.markdown(scale['instructions'], extensions=['fenced_code','tables','mdx_math'])
|
scale['instructions']=markdown.markdown(scale['instructions'], extensions=['fenced_code','tables','mdx_math'])
|
||||||
scale['descriptions']=markdown.markdown(scale['descriptions'], 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] # 使用文件名作为标识
|
scale_id = os.path.splitext(filename)[0] # 使用文件名作为标识
|
||||||
scales[scale_id] = scale
|
scales[scale_id] = scale
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"Error loading scale {filename}: {e}")
|
print(f"Error loading scale {filename}: {e}")
|
||||||
return scales
|
return lang, scales
|
||||||
|
|
||||||
@app.get("/", response_class=HTMLResponse)
|
@app.get("/", response_class=HTMLResponse)
|
||||||
async def index(request: Request):
|
async def index(request: Request):
|
||||||
scales = load_all_scales()
|
lang, _ = load_all_scales()
|
||||||
# 新增读取README.md的逻辑
|
# 新增读取README.md的逻辑
|
||||||
readme_content = ""
|
readme_content = ""
|
||||||
try:
|
try:
|
||||||
@ -40,13 +49,22 @@ async def index(request: Request):
|
|||||||
pass # 如果README不存在则静默失败
|
pass # 如果README不存在则静默失败
|
||||||
return templates.TemplateResponse("index.html", {
|
return templates.TemplateResponse("index.html", {
|
||||||
"request": request,
|
"request": request,
|
||||||
"scales": scales,
|
"lang": lang,
|
||||||
"readme_content": readme_content # 新增模板变量
|
"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)
|
@app.get("/scales/{scale_id}", response_class=HTMLResponse)
|
||||||
async def scale(request: Request, scale_id: str):
|
async def scale(request: Request, scale_id: str):
|
||||||
scales = load_all_scales()
|
_, scales = load_all_scales()
|
||||||
scale = scales.get(scale_id)
|
scale = scales.get(scale_id)
|
||||||
if scale:
|
if scale:
|
||||||
return templates.TemplateResponse("scale.html", {
|
return templates.TemplateResponse("scale.html", {
|
||||||
@ -56,10 +74,10 @@ async def scale(request: Request, scale_id: str):
|
|||||||
})
|
})
|
||||||
raise HTTPException(status_code=404, detail="问卷未找到")
|
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):
|
async def result(request: Request, scale_id: str):
|
||||||
form_data = await request.form()
|
form_data = await request.form()
|
||||||
scales = load_all_scales()
|
lang, scales = load_all_scales()
|
||||||
scale = scales.get(scale_id)
|
scale = scales.get(scale_id)
|
||||||
if scale:
|
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: 中国大五人格问卷(简式版)
|
title: 中国大五人格问卷(简式版)
|
||||||
|
lang: zh
|
||||||
instructions: 下面是一些描述人们性格特点的句子,请根据每个句子与您性格相符程度选择相应的数字。1-6分别代表完全不符合、大部分不符合、有点不符合、有点符合、大部分符合、完全符合。
|
instructions: 下面是一些描述人们性格特点的句子,请根据每个句子与您性格相符程度选择相应的数字。1-6分别代表完全不符合、大部分不符合、有点不符合、有点符合、大部分符合、完全符合。
|
||||||
descriptions: |
|
descriptions: |
|
||||||
中国大五人格问卷(CBF-PI)是由王孟成和戴晓阳等编制的,中国拥有其知识产权的人格问卷(相比NEO-PI)。此处是基于其简化的问卷,与完整版问卷的各项相关系数的$r$神经质最小的$0.886$、宜人性最大的$0.922$。
|
中国大五人格问卷(CBF-PI)是由王孟成和戴晓阳等编制的,中国拥有其知识产权的人格问卷(相比NEO-PI)。此处是基于其简化的问卷,与完整版问卷的各项相关系数的$r$神经质最小的$0.886$、宜人性最大的$0.922$。
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
title: Symptom Checklist-90 (SCL90)
|
title: Symptom Checklist-90 (SCL90)
|
||||||
|
lang: en
|
||||||
instructions: |
|
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
|
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
|
MUCH THAT PROBLEM HAS BOTHERED OR DISTRESSED YOU DURING THE
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
title: 中庸实践思维量表
|
title: 中庸实践思维量表
|
||||||
|
lang: zh
|
||||||
instructions: |
|
instructions: |
|
||||||
以下题目是对个人思维方式的描述,不需要过多考虑,请根据你平时的真实想法,或者假设遇到所说的情形时,内心里自动出现的想法进行选择,根据符合度进行打分,答案并无对错之分。
|
以下题目是对个人思维方式的描述,不需要过多考虑,请根据你平时的真实想法,或者假设遇到所说的情形时,内心里自动出现的想法进行选择,根据符合度进行打分,答案并无对错之分。
|
||||||
|
|
||||||
|
@ -1,27 +1,35 @@
|
|||||||
/* 全局样式 */
|
|
||||||
body {
|
body {
|
||||||
font-family: Arial, sans-serif;
|
font-family: Arial, sans-serif;
|
||||||
line-height: 1.6;
|
line-height: 1.6;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
|
padding-top: 20px;
|
||||||
|
/* 使用 flexbox 布局实现 body 内元素的居中 */
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
/* 确保 body 至少占据整个视口的高度 */
|
||||||
|
min-height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
width: 40%;
|
.content {
|
||||||
max-width: 1200px;
|
|
||||||
margin: 0 auto;
|
|
||||||
|
|
||||||
/* 可选:添加一些内边距,让内容不紧贴容器边缘 */
|
/* 可选:添加一些内边距,让内容不紧贴容器边缘 */
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
|
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
|
||||||
/* 设置背景颜色为纯白色 */
|
/* 设置背景颜色为纯白色 */
|
||||||
background-color: #ffffff;
|
background-color: #ffffff;
|
||||||
color: #333;
|
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) {
|
@media (max-width: 768px) {
|
||||||
body {
|
.content {
|
||||||
width: 95%;
|
width: 95%;
|
||||||
/* 全屏展示 */
|
/* 全屏展示 */
|
||||||
|
padding-top: 10px;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
/* 适当调整内边距 */
|
/* 适当调整内边距 */
|
||||||
}
|
}
|
||||||
|
@ -9,17 +9,23 @@
|
|||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
{% if readme_content %}
|
<div class="header">
|
||||||
<div class="readme-section">
|
|
||||||
{{ readme_content|safe }}
|
</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>
|
</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>
|
</body>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</html>
|
</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>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<h1>{{ scale.title }} </h1>
|
<div class="content">
|
||||||
<ul>
|
<h1>{{ scale.title }} </h1>
|
||||||
{% for key, value in responses.items() %}
|
<ul>
|
||||||
<li>{{ key }}: 在 {{ranges[key][0]}} 到 {{ranges[key][1]}} 的量表中得分 {{ value }}</li>
|
{% for key, value in responses.items() %}
|
||||||
{% endfor %}
|
<li>{{ key }}: 在 {{ranges[key][0]}} 到 {{ranges[key][1]}} 的量表中得分 {{ value }}</li>
|
||||||
</ul>
|
{% endfor %}
|
||||||
<div>
|
</ul>
|
||||||
{{scale.descriptions|safe}}
|
<div>
|
||||||
|
{{scale.descriptions|safe}}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
|
@ -16,23 +16,25 @@
|
|||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<h1>{{ scale.title }}</h1>
|
<div class="content">
|
||||||
<div>
|
<h1>{{ scale.title }}</h1>
|
||||||
{{ scale.instructions|safe }}
|
<div>
|
||||||
</div>
|
{{ scale.instructions|safe }}
|
||||||
<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>
|
</div>
|
||||||
{% endfor %}
|
<form action="/scales/{{ scale_id }}" method="post">
|
||||||
<input type="submit" value="提交">
|
{% for id, question in scale.questions.items() %}
|
||||||
</form>
|
<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>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
Loading…
x
Reference in New Issue
Block a user