使用了html模板;增加了导航栏;将lang改为看起来更加通用的tag
This commit is contained in:
parent
4954abfca4
commit
441768dab0
37
app.py
37
app.py
@ -15,10 +15,10 @@ app.mount("/static", StaticFiles(directory="static"), name="static")
|
||||
def load_all_scales():
|
||||
scale_folder = 'scales'
|
||||
scales = {}
|
||||
lang = {}
|
||||
tags = {}
|
||||
try:
|
||||
with open(os.path.join('langmap.yml'), 'r', encoding='utf-8') as f:
|
||||
langmap = yaml.safe_load(f)
|
||||
with open(os.path.join('tagmap.yml'), 'r', encoding='utf-8') as f:
|
||||
tagmap = yaml.safe_load(f)
|
||||
except Exception as e:
|
||||
print(f"Error loading scale langmap: {e}")
|
||||
for filename in os.listdir(scale_folder):
|
||||
@ -28,18 +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']]
|
||||
if 'tag' not in scale or scale['tag'] not in tagmap:
|
||||
scale['tag']='other'
|
||||
tags[scale['tag']]=tagmap[scale['tag']]
|
||||
scale_id = os.path.splitext(filename)[0] # 使用文件名作为标识
|
||||
scales[scale_id] = scale
|
||||
except Exception as e:
|
||||
print(f"Error loading scale {filename}: {e}")
|
||||
return lang, scales
|
||||
return tags, scales
|
||||
|
||||
@app.get("/", response_class=HTMLResponse)
|
||||
async def index(request: Request):
|
||||
lang, _ = load_all_scales()
|
||||
tags, _ = load_all_scales()
|
||||
# 新增读取README.md的逻辑
|
||||
readme_content = ""
|
||||
try:
|
||||
@ -49,35 +49,37 @@ async def index(request: Request):
|
||||
pass # 如果README不存在则静默失败
|
||||
return templates.TemplateResponse("index.html", {
|
||||
"request": request,
|
||||
"lang": lang,
|
||||
"tags": tags,
|
||||
"readme_content": readme_content # 新增模板变量
|
||||
})
|
||||
|
||||
@app.get("/{lang}", response_class=HTMLResponse)
|
||||
async def scale(request: Request, lang: str):
|
||||
_, scales = load_all_scales()
|
||||
@app.get("/{tag}", response_class=HTMLResponse)
|
||||
async def list(request: Request, tag: str):
|
||||
tags, scales = load_all_scales()
|
||||
return templates.TemplateResponse("list.html", {
|
||||
"request": request,
|
||||
"tags": tags,
|
||||
"scales": scales,
|
||||
"lang": lang
|
||||
"tag": tag
|
||||
})
|
||||
|
||||
@app.get("/scales/{scale_id}", response_class=HTMLResponse)
|
||||
async def scale(request: Request, scale_id: str):
|
||||
_, scales = load_all_scales()
|
||||
tags, scales = load_all_scales()
|
||||
scale = scales.get(scale_id)
|
||||
if scale:
|
||||
return templates.TemplateResponse("scale.html", {
|
||||
"request": request,
|
||||
"scale_id": scale_id,
|
||||
"scale": scale
|
||||
"scale": scale,
|
||||
"tags":tags
|
||||
})
|
||||
raise HTTPException(status_code=404, detail="问卷未找到")
|
||||
|
||||
@app.post("/scales/{scale_id}", response_class=HTMLResponse)
|
||||
async def result(request: Request, scale_id: str):
|
||||
form_data = await request.form()
|
||||
lang, scales = load_all_scales()
|
||||
tags, scales = load_all_scales()
|
||||
scale = scales.get(scale_id)
|
||||
if scale:
|
||||
# 这里可以添加保存数据到数据库等逻辑
|
||||
@ -95,7 +97,8 @@ async def result(request: Request, scale_id: str):
|
||||
"request": request,
|
||||
"responses": responses,
|
||||
"ranges": ranges,
|
||||
"scale": scale
|
||||
"scale": scale,
|
||||
"tags":tags
|
||||
})
|
||||
raise HTTPException(status_code=404, detail="问卷未找到")
|
||||
|
||||
|
@ -1,3 +0,0 @@
|
||||
other: 未分类 Other
|
||||
zh: 中文
|
||||
en: English
|
@ -1,5 +1,5 @@
|
||||
title: 中国大五人格问卷(简式版)
|
||||
lang: zh
|
||||
tag: zh
|
||||
instructions: 下面是一些描述人们性格特点的句子,请根据每个句子与您性格相符程度选择相应的数字。1-6分别代表完全不符合、大部分不符合、有点不符合、有点符合、大部分符合、完全符合。
|
||||
descriptions: |
|
||||
中国大五人格问卷(CBF-PI)是由王孟成和戴晓阳等编制的,中国拥有其知识产权的人格问卷(相比NEO-PI)。此处是基于其简化的问卷,与完整版问卷的各项相关系数的$r$神经质最小的$0.886$、宜人性最大的$0.922$。
|
||||
|
@ -1,5 +1,5 @@
|
||||
title: Symptom Checklist-90 (SCL90)
|
||||
lang: en
|
||||
tag: 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,5 +1,5 @@
|
||||
title: 中庸实践思维量表
|
||||
lang: zh
|
||||
tag: zh
|
||||
instructions: |
|
||||
以下题目是对个人思维方式的描述,不需要过多考虑,请根据你平时的真实想法,或者假设遇到所说的情形时,内心里自动出现的想法进行选择,根据符合度进行打分,答案并无对错之分。
|
||||
|
||||
|
@ -12,7 +12,7 @@ body {
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.content {
|
||||
main {
|
||||
/* 可选:添加一些内边距,让内容不紧贴容器边缘 */
|
||||
padding: 20px;
|
||||
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
|
||||
@ -26,7 +26,7 @@ body {
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.content {
|
||||
main {
|
||||
width: 95%;
|
||||
/* 全屏展示 */
|
||||
padding-top: 10px;
|
||||
@ -61,4 +61,52 @@ body {
|
||||
.scale-button input[type="radio"]:checked+label {
|
||||
background-color: #007BFF;
|
||||
color: white;
|
||||
}
|
||||
|
||||
/* 导航栏样式 */
|
||||
nav {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
background-color: #f8f9fa;
|
||||
padding: 1rem 2rem;
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.nav-left .logo {
|
||||
font-weight: 700;
|
||||
font-size: 1.5rem;
|
||||
color: #2c3e50;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.nav-links {
|
||||
display: flex;
|
||||
gap: 2rem;
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.nav-links a {
|
||||
text-decoration: none;
|
||||
color: #34495e;
|
||||
font-weight: 500;
|
||||
transition: color 0.3s ease;
|
||||
}
|
||||
|
||||
.nav-links a:hover {
|
||||
color: #3498db;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
padding-top: 80px;
|
||||
/* 增加顶部内边距避免内容被导航栏遮挡 */
|
||||
min-height: calc(100vh - 80px);
|
||||
/* 补偿导航栏高度 */
|
||||
}
|
3
tagmap.yml
Normal file
3
tagmap.yml
Normal file
@ -0,0 +1,3 @@
|
||||
other: 未分类 Other
|
||||
zh: 中文量表
|
||||
en: English Scales
|
35
templates/base.html
Normal file
35
templates/base.html
Normal file
@ -0,0 +1,35 @@
|
||||
<!DOCTYPE html>
|
||||
<!-- <html lang="zh"> -->
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="stylesheet" href="/static/styles.css">
|
||||
<!-- 添加KaTeX支持 -->
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.min.css">
|
||||
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.min.js"></script>
|
||||
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/contrib/auto-render.min.js" onload="renderMathInElement(document.body, {delimiters: [
|
||||
{left: '$$', right: '$$', display: true},
|
||||
{left: '$', right: '$', display: false}]});">
|
||||
</script>
|
||||
{% block head_extra %}{% endblock %}
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<nav>
|
||||
<div class="nav-left">
|
||||
<a href="/" class="logo">PsychoScales</a>
|
||||
</div>
|
||||
<ul class="nav-links">
|
||||
{% for key,value in tags.items() %}
|
||||
<li><a href="/{{ key }}"">{{ value }}</a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</nav>
|
||||
<br>
|
||||
<main>
|
||||
{% block main %}{% endblock %}
|
||||
</main>
|
||||
</body>
|
||||
|
||||
</html>
|
@ -1,31 +1,13 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh">
|
||||
{% extends 'base.html' %}
|
||||
|
||||
<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>
|
||||
{% block head_extra %}
|
||||
<title>心尺 PsychoScales</title>
|
||||
{% endblock %}
|
||||
|
||||
<body>
|
||||
<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>
|
||||
</body>
|
||||
|
||||
|
||||
|
||||
</html>
|
||||
{% block main %}
|
||||
{% if readme_content %}
|
||||
<div class="readme-section">
|
||||
{{ readme_content|safe }}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endblock %}
|
@ -1,27 +1,16 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh">
|
||||
{% extends 'base.html' %}
|
||||
|
||||
<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>
|
||||
{% block head_extra %}
|
||||
<title>心尺 PsychoScales</title>
|
||||
{% endblock %}
|
||||
|
||||
<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>
|
||||
{% block main %}
|
||||
<ul>
|
||||
{% for scale_id, scale in scales.items() %}
|
||||
{% if scale.tag == tag %}
|
||||
<li><a href="/scales/{{ scale_id }}" , title=" {{ scale.abstract }}">{{ scale.get('title','未命名问卷') }}</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endblock %}
|
@ -1,32 +1,17 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh">
|
||||
{% extends 'base.html' %}
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>{{scale_title}}</title>
|
||||
<link rel="stylesheet" href="/static/styles.css">
|
||||
<!-- 添加KaTeX支持 -->
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.min.css">
|
||||
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.min.js"></script>
|
||||
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/contrib/auto-render.min.js" onload="renderMathInElement(document.body, {delimiters: [
|
||||
{left: '$$', right: '$$', display: true},
|
||||
{left: '$', right: '$', display: false}]});">
|
||||
</script>
|
||||
</head>
|
||||
{% block head_extra %}
|
||||
<title>{{scale_title}}</title>
|
||||
{% endblock %}
|
||||
|
||||
<body>
|
||||
<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>
|
||||
|
||||
</html>
|
||||
{% block main %}
|
||||
<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>
|
||||
{% endblock %}
|
@ -1,40 +1,25 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh">
|
||||
{% extends 'base.html' %}
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>{{ scale.title }}</title>
|
||||
<link rel="stylesheet" href="/static/styles.css">
|
||||
<!-- 添加KaTeX支持 -->
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.min.css">
|
||||
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.min.js"></script>
|
||||
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/contrib/auto-render.min.js" onload="renderMathInElement(document.body, {delimiters: [
|
||||
{left: '$$', right: '$$', display: true},
|
||||
{left: '$', right: '$', display: false}]});">
|
||||
</script>
|
||||
</head>
|
||||
{% block head_extra %}
|
||||
<title>{{ scale.title }}</title>
|
||||
{% endblock %}
|
||||
|
||||
<body>
|
||||
<div class="content">
|
||||
<h1>{{ scale.title }}</h1>
|
||||
<div>
|
||||
{{ scale.instructions|safe }}
|
||||
</div>
|
||||
<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>
|
||||
{% block main %}
|
||||
<h1>{{ scale.title }}</h1>
|
||||
<div>
|
||||
{{ scale.instructions|safe }}
|
||||
</div>
|
||||
<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>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
{% endfor %}
|
||||
<input type="submit" value="提交">
|
||||
</form>
|
||||
{% endblock %}
|
Loading…
x
Reference in New Issue
Block a user