feat: 第一次上传

This commit is contained in:
2025-12-14 22:21:03 +08:00
commit 366ab0b2e8
19 changed files with 1008 additions and 0 deletions

44
templates/base.html Normal file
View File

@@ -0,0 +1,44 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
<title>{% block title %}XBXS{% endblock %}</title>
<script src="https://cdn.tailwindcss.com"></script>
</head>
<body class="bg-zinc-100">
<!-- App 容器 -->
<div class="mx-auto max-w-md min-h-screen bg-white relative">
<!-- 主内容 -->
<main class="pb-20">
{% block content %}{% endblock %}
</main>
<!-- 底部 Tab -->
<nav class="fixed bottom-0 left-1/2 -translate-x-1/2
w-full max-w-md
bg-white border-t
flex justify-around items-center
h-16">
<a href="/" class="flex flex-col items-center text-sm
{% if active == 'home' %}text-blue-600{% else %}text-zinc-500{% endif %}">
<span>🏠</span>
首页
</a>
<a href="/profile" class="flex flex-col items-center text-sm
{% if active == 'profile' %}text-blue-600{% else %}text-zinc-500{% endif %}">
<span>👤</span>
我的
</a>
</nav>
</div>
</body>
</html>

21
templates/home.html Normal file
View File

@@ -0,0 +1,21 @@
{% extends "base.html" %}
{% block title %}首页{% endblock %}
{% block content %}
<div class="p-4 space-y-6">
<h1 class="text-xl font-bold">应用</h1>
<!-- 签到 App 卡片 -->
<a href="/sign" class="block bg-blue-500 text-white rounded-2xl p-6 shadow
active:scale-95 transition">
<div class="text-lg font-semibold">📍 签到</div>
<div class="text-sm opacity-90 mt-1">
课程签到 / 定位 / 拍照
</div>
</a>
</div>
{% endblock %}

55
templates/login.html Normal file
View File

@@ -0,0 +1,55 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<title>登录</title>
<script src="https://cdn.tailwindcss.com"></script>
</head>
<body class="min-h-screen flex items-center justify-center bg-gray-100">
<div class="w-full max-w-sm bg-white rounded-xl shadow-lg p-8">
<h2 class="text-2xl font-bold text-center mb-6">登录</h2>
<div class="space-y-4">
<input id="username" type="text" placeholder="用户名"
class="w-full px-4 py-2 border rounded-lg focus:outline-none focus:ring" />
<input id="password" type="password" placeholder="密码"
class="w-full px-4 py-2 border rounded-lg focus:outline-none focus:ring" />
<button onclick="login()"
class="w-full bg-blue-600 text-white py-2 rounded-lg hover:bg-blue-700 transition">
登录
</button>
</div>
<p id="error" class="text-red-500 text-sm mt-4 hidden"></p>
</div>
<script>
async function login() {
const username = document.getElementById("username").value;
const password = document.getElementById("password").value;
const res = await fetch("/login", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ username, password }),
});
if (res.ok) {
window.location.href = "/home";
} else {
document.getElementById("error").innerText = "登录失败";
document.getElementById("error").classList.remove("hidden");
}
}
</script>
</body>
</html>

55
templates/profile.html Normal file
View File

@@ -0,0 +1,55 @@
{% extends "base.html" %}
{% block title %}我的{% endblock %}
{% block content %}
<div class="p-4 space-y-6">
<!-- 头像 + 名字 -->
<div class="bg-gradient-to-r from-blue-500 to-indigo-500
rounded-2xl p-6 text-white">
<div class="text-lg font-semibold">
{{ student.studentName }}
</div>
<div class="text-sm opacity-90">
学号 {{ student.studentNumber }}
</div>
</div>
<!-- 信息卡 -->
<div class="bg-white rounded-2xl shadow divide-y text-sm">
<div class="flex justify-between p-4">
<span class="text-zinc-500">学院</span>
<span>{{ student.collegeName }}</span>
</div>
<div class="flex justify-between p-4">
<span class="text-zinc-500">专业</span>
<span>{{ student.professionalName }}</span>
</div>
<div class="flex justify-between p-4">
<span class="text-zinc-500">班级</span>
<span>{{ student.deptName }}</span>
</div>
<div class="flex justify-between p-4">
<span class="text-zinc-500">性别</span>
<span>{{ student.studentSex }}</span>
</div>
<div class="flex justify-between p-4">
<span class="text-zinc-500">手机号</span>
<span>{{ student.studentIpone }}</span>
</div>
</div>
<!-- 操作 -->
<a href="/logout" class="block text-center text-red-500 py-3">
退出登录
</a>
</div>
{% endblock %}

View File

@@ -0,0 +1,74 @@
{% extends "base.html" %}
{% block title %}签到详情{% endblock %}
{% block content %}
<div class="p-4 space-y-4">
<!-- 标题 -->
<div class="flex justify-between items-center">
<h1 class="text-xl font-bold">签到详情</h1>
<a href="/sign" class="text-sm text-blue-500 hover:underline">返回签到列表</a>
</div>
<hr />
<!-- 详情信息 -->
<div class="space-y-4">
<div>
<span class="text-zinc-500">签到名称</span>
<div class="font-medium">{{ knowing_name }}</div>
</div>
<div>
<span class="text-zinc-500">日期</span>
<div class="font-medium">{{ start_date }}</div>
</div>
<div>
<span class="text-zinc-500">时间</span>
<div class="font-medium">{{ start_time }} - {{ end_time }}</div>
</div>
<div>
<span class="text-zinc-500">发起人</span>
<div class="font-medium">{{ send_name }} ({{ send_role }})</div>
</div>
<div>
<span class="text-zinc-500">签到状态</span>
<div class="font-medium">
{% if is_finish_know == 1 %}
<span class="text-green-600">已签到</span>
{% elif is_check == 1 %}
<span class="text-green-600">已签到</span>
{% else %}
<span class="text-red-600">未签到</span>
{% endif %}
</div>
</div>
{% if is_picture == 1 %}
<div>
<span class="text-zinc-500">签到需要拍照</span>
<div class="font-medium"></div>
</div>
{% else %}
<div>
<span class="text-zinc-500">签到需要拍照</span>
<div class="font-medium"></div>
</div>
{% endif %}
</div>
<!-- 完成签到按钮 -->
{% if is_finish_know == 0 and is_check == 0 %}
<div class="mt-4">
<form method="post" action="/sign/{{ know_id }}/complete">
<button type="submit" class="bg-blue-600 text-white py-2 px-4 rounded-lg">完成签到</button>
</form>
</div>
{% endif %}
</div>
{% endblock %}

74
templates/sign_list.html Normal file
View File

@@ -0,0 +1,74 @@
{% extends "base.html" %}
{% block title %}签到{% endblock %}
{% block content %}
<div class="p-4 space-y-4">
<!-- 标题 -->
<div class="flex justify-between items-center">
<h1 class="text-xl font-bold">签到任务</h1>
<span class="text-sm text-zinc-500">
共 {{ total }} 条
</span>
</div>
{% if total == 0 %}
<div class="text-center text-zinc-400 py-10">
暂无签到任务
</div>
{% endif %}
<!-- 列表 -->
<div class="space-y-3">
{% for item in list %}
<a href="/sign/{{ item.id }}" class="block bg-white rounded-2xl p-4 shadow
active:scale-95 transition">
<!-- 第一行 -->
<div class="flex justify-between items-center">
<div class="font-semibold text-base">
{{ item.knowingName }}
</div>
{% if item.isFinishKnowing == 1 %}
<span class="text-xs bg-green-100 text-green-600 px-2 py-0.5 rounded-full">
已签到
</span>
{% elif item.isEnded %}
<span class="text-xs bg-zinc-100 text-zinc-400 px-2 py-0.5 rounded-full">
已结束
</span>
{% else %}
<span class="text-xs bg-blue-100 text-blue-600 px-2 py-0.5 rounded-full">
进行中
</span>
{% endif %}
</div>
<!-- 时间 -->
<div class="text-sm text-zinc-500 mt-1">
{{ item.startDate }} {{ item.startTime }} - {{ item.endTime }}
</div>
<!-- 发起人 -->
<div class="flex justify-between items-center mt-2 text-sm">
<div class="text-zinc-600">
{{ item.sendRole }} · {{ item.sendName }}
</div>
{% if item.isPicture == 0 %}
<span class="text-xs bg-orange-100 text-orange-600 px-2 py-0.5 rounded">
需拍照
</span>
{% endif %}
</div>
</a>
{% endfor %}
</div>
</div>
{% endblock %}