diff --git a/bysms/config/__init__.py b/bysms/config/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/bysms/config/__pycache__/__init__.cpython-312.pyc b/bysms/config/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000..3faa8ed Binary files /dev/null and b/bysms/config/__pycache__/__init__.cpython-312.pyc differ diff --git a/bysms/config/__pycache__/settings.cpython-312.pyc b/bysms/config/__pycache__/settings.cpython-312.pyc new file mode 100644 index 0000000..233017c Binary files /dev/null and b/bysms/config/__pycache__/settings.cpython-312.pyc differ diff --git a/bysms/config/__pycache__/urls.cpython-312.pyc b/bysms/config/__pycache__/urls.cpython-312.pyc new file mode 100644 index 0000000..4da7556 Binary files /dev/null and b/bysms/config/__pycache__/urls.cpython-312.pyc differ diff --git a/bysms/config/__pycache__/wsgi.cpython-312.pyc b/bysms/config/__pycache__/wsgi.cpython-312.pyc new file mode 100644 index 0000000..9a440f2 Binary files /dev/null and b/bysms/config/__pycache__/wsgi.cpython-312.pyc differ diff --git a/bysms/config/asgi.py b/bysms/config/asgi.py new file mode 100644 index 0000000..400e9e3 --- /dev/null +++ b/bysms/config/asgi.py @@ -0,0 +1,16 @@ +""" +ASGI config for config project. + +It exposes the ASGI callable as a module-level variable named ``application``. + +For more information on this file, see +https://docs.djangoproject.com/en/5.1/howto/deployment/asgi/ +""" + +import os + +from django.core.asgi import get_asgi_application + +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings') + +application = get_asgi_application() diff --git a/bysms/config/settings.py b/bysms/config/settings.py new file mode 100644 index 0000000..b730da8 --- /dev/null +++ b/bysms/config/settings.py @@ -0,0 +1,134 @@ +""" +Django settings for config project. + +Generated by 'django-admin startproject' using Django 5.1.1. + +For more information on this file, see +https://docs.djangoproject.com/en/5.1/topics/settings/ + +For the full list of settings and their values, see +https://docs.djangoproject.com/en/5.1/ref/settings/ +""" + +from pathlib import Path +import os + +# Build paths inside the project like this: BASE_DIR / 'subdir'. +BASE_DIR = Path(__file__).resolve().parent.parent + + +# Quick-start development settings - unsuitable for production +# See https://docs.djangoproject.com/en/5.1/howto/deployment/checklist/ + +# SECURITY WARNING: keep the secret key used in production secret! +SECRET_KEY = 'django-insecure-q4zt_!3q_l9bdtyzdaeqvf=gm)6^g+)h^h400+jugzvdeakvl5' + +# SECURITY WARNING: don't run with debug turned on in production! +DEBUG = True + +ALLOWED_HOSTS = [] + + +# Application definition + +INSTALLED_APPS = [ + 'django.contrib.admin', + 'django.contrib.auth', + 'django.contrib.contenttypes', + 'django.contrib.sessions', + 'django.contrib.messages', + 'django.contrib.staticfiles', + 'user.apps.UserConfig' +] + +MIDDLEWARE = [ + 'django.middleware.security.SecurityMiddleware', + 'django.contrib.sessions.middleware.SessionMiddleware', + 'django.middleware.common.CommonMiddleware', + # 'django.middleware.csrf.CsrfViewMiddleware', + 'django.contrib.auth.middleware.AuthenticationMiddleware', + 'django.contrib.messages.middleware.MessageMiddleware', + 'django.middleware.clickjacking.XFrameOptionsMiddleware', +] + +ROOT_URLCONF = 'config.urls' + +TEMPLATES = [ + { + 'BACKEND': 'django.template.backends.django.DjangoTemplates', + 'DIRS': [os.path.join(BASE_DIR, 'pages')], + 'APP_DIRS': True, + 'OPTIONS': { + 'context_processors': [ + 'django.template.context_processors.debug', + 'django.template.context_processors.request', + 'django.contrib.auth.context_processors.auth', + 'django.contrib.messages.context_processors.messages', + ], + }, + }, +] + +WSGI_APPLICATION = 'config.wsgi.application' + + +# Database +# https://docs.djangoproject.com/en/5.1/ref/settings/#databases + +DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.sqlite3', + 'NAME': BASE_DIR / 'db.sqlite3', + } +} + + +# Password validation +# https://docs.djangoproject.com/en/5.1/ref/settings/#auth-password-validators + +AUTH_PASSWORD_VALIDATORS = [ + { + 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', + }, +] + + +# Internationalization +# https://docs.djangoproject.com/en/5.1/topics/i18n/ + +LANGUAGE_CODE = 'en-us' + +TIME_ZONE = 'UTC' + +USE_I18N = True + +USE_TZ = True + + +# Static files (CSS, JavaScript, Images) +# https://docs.djangoproject.com/en/5.1/howto/static-files/ + + +# Default primary key field type +# https://docs.djangoproject.com/en/5.1/ref/settings/#default-auto-field + +DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' +# settings.py +STATIC_URL = '/static/' # 静态文件访问路径 + +STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static/')]#css问题加载这个 +DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.sqlite3', + 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), + } +} \ No newline at end of file diff --git a/bysms/config/urls.py b/bysms/config/urls.py new file mode 100644 index 0000000..55d17bf --- /dev/null +++ b/bysms/config/urls.py @@ -0,0 +1,24 @@ +""" +URL configuration for config project. + +The `urlpatterns` list routes URLs to views. For more information please see: + https://docs.djangoproject.com/en/5.1/topics/http/urls/ +Examples: +Function views + 1. Add an import: from my_app import views + 2. Add a URL to urlpatterns: path('', views.home, name='home') +Class-based views + 1. Add an import: from other_app.views import Home + 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home') +Including another URLconf + 1. Import the include() function: from django.urls import include, path + 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) +""" +from django.contrib import admin +from django.urls import path,include + +urlpatterns = [ + # path('admin/', admin.site.urls), + path('',include('user.urls')), + ] + diff --git a/bysms/config/wsgi.py b/bysms/config/wsgi.py new file mode 100644 index 0000000..e232e56 --- /dev/null +++ b/bysms/config/wsgi.py @@ -0,0 +1,16 @@ +""" +WSGI config for config project. + +It exposes the WSGI callable as a module-level variable named ``application``. + +For more information on this file, see +https://docs.djangoproject.com/en/5.1/howto/deployment/wsgi/ +""" + +import os + +from django.core.wsgi import get_wsgi_application + +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings') + +application = get_wsgi_application() diff --git a/bysms/db.sqlite3 b/bysms/db.sqlite3 new file mode 100644 index 0000000..1daabcb Binary files /dev/null and b/bysms/db.sqlite3 differ diff --git a/bysms/manage.py b/bysms/manage.py new file mode 100644 index 0000000..8e7ac79 --- /dev/null +++ b/bysms/manage.py @@ -0,0 +1,22 @@ +#!/usr/bin/env python +"""Django's command-line utility for administrative tasks.""" +import os +import sys + + +def main(): + """Run administrative tasks.""" + os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings') + try: + from django.core.management import execute_from_command_line + except ImportError as exc: + raise ImportError( + "Couldn't import Django. Are you sure it's installed and " + "available on your PYTHONPATH environment variable? Did you " + "forget to activate a virtual environment?" + ) from exc + execute_from_command_line(sys.argv) + + +if __name__ == '__main__': + main() diff --git a/bysms/pages/ceshi.html b/bysms/pages/ceshi.html new file mode 100644 index 0000000..b235a6c --- /dev/null +++ b/bysms/pages/ceshi.html @@ -0,0 +1,76 @@ + + + + + + + Document + + + nihap +

sandw

+ + +
+
+
+ +
+
+ + +
+
+
修改用户名和密码
+
+ 当前用户名:{{name}} + +
+ +
+ +
+
+
+ +
+ \ No newline at end of file diff --git a/bysms/pages/firstpage.html b/bysms/pages/firstpage.html new file mode 100644 index 0000000..1b7a867 --- /dev/null +++ b/bysms/pages/firstpage.html @@ -0,0 +1,141 @@ + + + + + + 随机点名系统 + + + + +
随机点名系统
+ + +
+
+
天选之子
+
{{ form }}
+
+ {% if sign == 'zhongkou' %} + 触发随机事件:双倍扣分 + {% elif sign == 'lucky' %} + 触发随机事件:可以寻求帮助 + {% endif %} + 占位 +
+
+
+ + +
+
+ + 评分: + + + 到达课堂(加1分) + {% if sign == 'zhongkou' %} + 没到(扣2分)
+ {% else %} + 没到(扣1分)
+ {% endif %} + + + 重复问题(加0.5分) + {% if sign == 'zhongkou' %} + 不能重复问题(扣2分)
+ {% else %} + 不能重复问题(扣1分)
+ {% endif %} + + 回答问题得分: + + +
+
+
+ +
+
+ +
+
+ + \ No newline at end of file diff --git a/bysms/pages/fourthpage.html b/bysms/pages/fourthpage.html new file mode 100644 index 0000000..10b8447 --- /dev/null +++ b/bysms/pages/fourthpage.html @@ -0,0 +1,179 @@ + + + + + + 随机点名系统 + + + + +
随机点名系统
+ + + +
+
+
+ +
+
+ + +
+
+
修改用户名和密码
+
+ 当前用户名:{{name}} + +
+ +
+ +
+
+
+ +
+ + + + \ No newline at end of file diff --git a/bysms/pages/login.html b/bysms/pages/login.html new file mode 100644 index 0000000..3fe1e73 --- /dev/null +++ b/bysms/pages/login.html @@ -0,0 +1,63 @@ + + + + + +登陆界面 + + + + + + + + + +
+
+
+
+
+
+
+
+
+
+ +
+
+
login
+ + + +
+
+ +
+ + + + + + +
+ + +
+ + +
+
+
+ + + \ No newline at end of file diff --git a/bysms/pages/secondpage.html b/bysms/pages/secondpage.html new file mode 100644 index 0000000..ed99a9d --- /dev/null +++ b/bysms/pages/secondpage.html @@ -0,0 +1,144 @@ + + + + + + 随机点名系统 + + + + +
随机点名系统
+ + + +
+
+
+ +
+
+ +
+
+
+ + +
+ + + + + {% for row in form %} + + + + + + + {% endfor %} + +
学号姓名专业 班级
{{ row.student_xuehao }}{{ row.student_name }}{{ row.student_major }}{{ row.student_class }}
+
+ + + \ No newline at end of file diff --git a/bysms/pages/thirdpage.html b/bysms/pages/thirdpage.html new file mode 100644 index 0000000..e648f56 --- /dev/null +++ b/bysms/pages/thirdpage.html @@ -0,0 +1,110 @@ + + + + + + 随机点名系统 + + + + +
随机点名系统
+ + + +
+ + + + + {% for row in form %} + + + + + + + {% endfor %} +
排名学号姓名积分
{{ forloop.counter }}{{ row.student_xuehao }}{{ row.student_name }}{{ row.student_score }}
+
+ + + + \ No newline at end of file diff --git a/bysms/pages/upload.html b/bysms/pages/upload.html new file mode 100644 index 0000000..bf5ed36 --- /dev/null +++ b/bysms/pages/upload.html @@ -0,0 +1,33 @@ + + + + + 上传Excel文件 + + + + + +
+
+ + + +
+

提示:请上传Excel文件(学号,姓名,班级,专业)(学号必须为数字,班级和专业可以为空)

+ +
+ + \ No newline at end of file diff --git a/bysms/requirements.txt b/bysms/requirements.txt new file mode 100644 index 0000000..d90180f Binary files /dev/null and b/bysms/requirements.txt differ diff --git a/bysms/static/excel上传格式.png b/bysms/static/excel上传格式.png new file mode 100644 index 0000000..a6a9289 Binary files /dev/null and b/bysms/static/excel上传格式.png differ diff --git a/bysms/static/login.css b/bysms/static/login.css new file mode 100644 index 0000000..98fb0d8 --- /dev/null +++ b/bysms/static/login.css @@ -0,0 +1,722 @@ +@font-face { + font-family: 'icomoon'; + src: url('fonts/icomoon.eot?1tb2pa'); + src: url('fonts/icomoon.eot?1tb2pa#iefix') format('embedded-opentype'), + url('fonts/icomoon.ttf?1tb2pa') format('truetype'), + url('fonts/icomoon.woff?1tb2pa') format('woff'), + url('fonts/icomoon.svg?1tb2pa#icomoon') format('svg'); + font-weight: normal; + font-style: normal; + font-display: block; +} + +body { + /* 初始化 取消内外边距 */ + margin: 0; + padding: 0; + overflow: hidden; + zoom: 85%; +} + +button { + /* 去除按钮自带样式 */ + border: none !important; + outline: none !important; +} + + +#container { + /* 100%窗口高度 */ + height: 100vh; +} + +.bg { + /* 绝对定位 */ + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; +} + +.sun { + margin: 0; + padding: 0; + /* 绝对定位 水平垂直居中 */ + position: absolute; + top: 500px; + left: 48%; + transform: translate(-50%, -50%); + width: 600px; + height: 600px; + background: orange; + border-radius: 50%; +} + +.moon { + margin: 0; + padding: 0; + position: absolute; + top: 54%; + left: 48%; + /* 计算得出月亮的位置 */ + transform: translate(calc(-50% + -160px), calc(-50% + -180px)); + width: 600px; + height: 600px; + /* 通过阴影绘制月亮 */ + box-shadow: 160px 180px 0 cyan; + border-radius: 50%; +} + +.sea { + position: absolute; + bottom: 0; + width: 100%; + height: 35%; + /* 背景模糊制造大海的感觉 */ + backdrop-filter: blur(100px); + -webkit-backdrop-filter: blur(100px); + z-index: 100; +} + +.sun, +.moon, +.sun-box, +.moon-box, +.bg { + /* 添加动画过渡 */ + transition: all 1s ease-in-out; +} + +.sun-box, +.moon-box { + /* 相对定位 */ + position: relative; + /* 溢出隐藏 */ + /* overflow: hidden; */ +} + +.light .bg { + background: #ffeea2; +} + +/* 夜晚 */ +.dark .sun-box { + height: 0; +} + +.dark .moon-box { + height: 100%; +} + +.dark .bg { + background: #040720; +} + +/* ................................................. */ +/* ....................按钮模块..................... */ +/* ...... ..........................................*/ + +.container2 .c2 { + /* 相对定位 */ + /* position: relative; */ + transition: 1s; + z-index: 1; + float: left; + margin: 5px 0; + cursor: pointer; + position: relative; + display: block; + width: 80px; + height: 40px; + background-color: #222; + border-radius: 40px; + /* 内阴影 */ + box-shadow: inset 0 2px 15px rgba(0, 0, 0, 0.2), + inset 0 2px 2px rgba(0, 0, 0, 0.2), + inset 0 -1px 1px rgba(0, 0, 0, 0.2); +} + +/* 滑块 */ +.container2 .indicator { + /* 绝对定位 */ + position: absolute; + z-index: 2; + left: 0px; + top: 5px; + width: 40px; + height: 40px; + /* 渐变背景 */ + background: linear-gradient(to bottom, #444, #222); + border-radius: 50%; + /* 阴影 */ + box-shadow: 0 2px 5px rgba(0, 0, 0, 0.5), + inset 0 1px 1px rgba(255, 255, 255, 0.1); + /* 缩小 */ + transform: scale(0.9); + /* 动画过渡 */ + transition: 1s; + /* 鼠标事件取消 */ + pointer-events: none; +} + +/* 滑块中心发光点 */ +.container2 .indicator::before { + content: ""; + width: 5px; + height: 5px; + /* 绝对定位 居中 */ + position: absolute; + left: 50%; + top: 50%; + transform: translate(-50%, -50%); + background-color: #f00; + border-radius: 50%; + /* 阴影制造发光效果 */ + box-shadow: 0 0 2px #f00, + 0 0 5px #f00, + 0 0 10px #f00, + 0 0 15px #f00, + 0 0 20px #f00, + 0 0 25px #f00, + 0 0 30px #f00, + 0 0 35px #f00; + transition: 0.5s; +} + +/* 勾选复选框后滑块的变化 */ +.container2 input:checked~.indicator { + left: 40px; +} + +.container2 input:checked~.indicator::before { + background-color: #0f0; + box-shadow: 0 0 2px #0f0, + 0 0 5px #0f0, + 0 0 10px #0f0, + 0 0 15px #0f0, + 0 0 20px #0f0, + 0 0 25px #0f0, + 0 0 30px #0f0, + 0 0 35px #0f0; +} + +.container2 input:checked~.dark .sun-box { + height: 100% !important; +} + +.container2 input:checked~.dark .sun { + top: 62%; +} + +.container2 input:checked~.dark .moon-box { + height: 0 !important; + transform-origin: -10px; + transform: rotate(-90deg); +} + +.container2 input:checked~.dark .bg { + background: #ffeea2; +} + +.container2 input:checked~label { + background-color: #ffeea2; +} + +.container2 input:checked~.indicator { + background: #ffeea2; + box-shadow: 0 0 .5; +} + +/* ................................................. */ +/* ....................登录模块...................... */ +/* ...... ..........................................*/ + +.form-box { + /* transform: scale(0.7, 0.7); */ + /* zoom: 90%; */ + position: fixed; + top: 28%; + left: 36%; + width: 400px; + height: 550px; + z-index: 101; + background-color: rgba(255, 255, 255, 0.1); + /* 背景模糊 */ + backdrop-filter: blur(20px); + border-top: 1px solid rgba(255, 255, 255, 0.5); + border-left: 1px solid rgba(255, 255, 255, 0.5); + border-radius: 15px; + display: flex; + flex-direction: column; + align-items: center; + /* 阴影 */ + box-shadow: 0px 20px 50px rgba(0, 0, 0, 0.5); +} + +.form-box .tit { + cursor: default; + color: #fff; + font-size: 45px; + font-weight: bold; + /* 大写 */ + text-transform: uppercase; + /* 字间距 */ + letter-spacing: 10px; + text-indent: 10px; + margin: 90px auto 50px auto; +} + +.form-box input { + width: 350px; + height: 35px; + font-size: 17px; + background: transparent; + text-indent: 8px; + border: none; + border-bottom: 1px solid rgba(255, 255, 255, 0.8); + margin: 15px auto; + outline: none; + color: #fff; +} + +.form-box input::placeholder { + color: rgba(255, 255, 255, 0.8); +} + +.form-box button { + font-size: 20px; + width: 350px; + height: 45px; + margin: 35px auto 40px auto; + border: none; + background: #00addd; + color: #fff; + letter-spacing: 20px; + text-indent: 20px; + border-radius: 8px; + font-weight: bold; + cursor: pointer; +} + +.form-box button:hover { + transition: .5s; + background: #0098d4; + letter-spacing: 50px; + text-indent: 45px; +} + +.form-box span { + font-size: 14px; + color: #fff; +} + +.form-box a { + color: #00addd; + text-decoration: none; +} + +/* .............................................. */ +/* ....................注册特效................... */ +/* ...............................................*/ +.search, +.close { + font-family: 'icomoon'; + white-space: nowrap; + font-style: normal; + text-align: center; +} + +.search:hover { + text-decoration: underline; +} + +.close { + transition: .3s; +} + +.close:hover { + color: #f55858; +} + +.search { + font-size: 14px; + color: #33b7eb; +} + +/* 注册按钮 */ +.search-btn { + pointer-events: all; + z-index: 301; + font-style: normal; + position: absolute; + top: 79.2%; + left: 59%; + width: 50px; + height: 50px; + line-height: 60px; + text-align: center; + cursor: pointer; +} + + +/* 关闭按钮 */ +.close-btn { + background: none !important; + pointer-events: all; + position: absolute; + top: -238px; + right: -600px; + z-index: 302; + font-size: 25px; + color: #fff; + cursor: pointer; + display: none; +} + +.container3 { + /* zoom: 80%; */ + z-index: 301; + position: absolute; + background: linear-gradient(200deg, #e7f0fd, #accbee); + top: -97%; + left: -180%; + width: 2000px; + height: 2000px; + /* background-color: darkgrey; */ + /* 渐变背景 */ + /* background: linear-gradient(200deg, #6e86ee, #453c90); */ + /* 将元素剪切为一个圆形 【25px表示圆的半径】 【50% 50%表示圆心位置】 */ + clip-path: circle(40px at 50% 50%); + /* clip-path: inset(975px 975px round 15px); */ + /* 设置过渡 */ + transition: .9s; + opacity: 0; +} + +.search-box { + z-index: 303; + /* 默认宽度为0(隐藏) */ + position: fixed; + top: 0%; + left: 0%; + width: 0; + height: 50px; + border-bottom: 3px solid #fff; + transition: 0.3s; +} + +.search-box input { + width: 100%; + height: 50px; + background: none; + border: none; + outline: none; + color: #fff; + font-size: 22px; + font-weight: 500; + /* 请输入前的缩进 */ + text-indent: 8px; +} + +.search-box input::placeholder { + color: rgba(255, 255, 255, 0.7); +} + +.search-box .fa { + width: 50px; + height: 50px; + line-height: 50px; + color: #fff; + font-size: 22px; + text-align: center; + cursor: pointer; +} + +#search_btn:checked~.search-btn { + display: none; +} + +#search_btn:checked~.container3 .shade { + pointer-events: all; + position: fixed; + top: 28%; + left: 36%; + width: 400px; + height: 550px; + z-index: 120; +} + +#search_btn:checked~.close-btn { + display: block; +} + +#search_btn:checked~.container3 { + opacity: 1; + clip-path: circle(100%); +} + +#search_btn:checked~.container3 .search-box { + width: 400px; +} + +.sign { + pointer-events: none; + position: fixed; + top: 28%; + left: 37%; + width: 400px; + height: 550px; + z-index: 300; + /* 100%窗口高度 */ + /* 弹性布局 水平+垂直居中 */ + /* display: flex; + justify-content: center; + align-items: center; */ +} + +/* ................................................. */ +/* ....................注册界面...................... */ +/* ...... ..........................................*/ + +.signin { + pointer-events: all; + position: fixed; + top: 20%; + left: 37%; + z-index: 330; + font-size: 96px; + color: #393838; + font-weight: bold; + letter-spacing: 5px; + cursor: pointer; +} + +.signin span { + /* 动画过渡 */ + transition: 0.5s; +} + +.signin:hover span { + margin-right: 10px; +} + +.signin:hover span::after { + font-size: 20px; + content: " us"; +} + +.signin:hover span { + color: #fff; + /* 文字阴影 */ + text-shadow: 0 0 10px #fff, + 0 0 20px #fff, + 0 0 40px #fff, + 0 0 80px #fff, + 0 0 120px #fff, + 0 0 160px #fff; +} + + +.s1 { + pointer-events: all; + position: fixed; + float: left; + top: 45%; + left: 36%; +} + +.s2 { + top: 52%; +} + +.s3 { + width: 250px !important; + top: 59%; +} + +.s3 button { + position: fixed; + pointer-events: all !important; + font-style: normal; + top: 56.5%; + left: 51%; + font-size: 15px; + width: 130px; + height: 45px; + margin: 35px auto 40px auto; + border: none; + background-color: #d5e4f6; + color: #71c9eb; + /* letter-spacing: 20px; + text-indent: 20px; */ + border-radius: 8px; + font-weight: bold; + cursor: pointer; + transition: .5s; +} + +.s3 .verification-code:hover { + background-color: #5abce6; + color: #d5e4f6; +} + +.sign-btn-box { + overflow: hidden; + color: #00aeff; + border: 2px solid #00aeff; +} + +.s3 .sign-btn { + font-size: 20px; + position: fixed; + top: 65%; + left: 36%; + width: 400px; + background: #00addd; + color: #fff; + letter-spacing: 20px; + text-indent: 20px; + border-radius: 8px; + font-weight: bold; + cursor: pointer; +} + +.s3 .sign-btn:hover { + transition: .5s; + background: #0098d4; + letter-spacing: 50px; + text-indent: 45px; +} + +/* 流星特效 */ + +.container4 span { + position: absolute; + top: 50%; + left: 50%; + width: 4px; + height: 4px; + background-color: #fff; + border-radius: 50%; + /* 发光效果 */ + box-shadow: 0 0 0 4px rgba(255, 255, 255, 0.1), + 0 0 0 8px rgba(255, 255, 255, 0.1), + 0 0 20px rgba(255, 255, 255, 1); + /* 执行动画 */ + animation: animate 3s linear infinite; +} + +/* 拖尾效果 */ +.container4 span::before { + content: ""; + position: absolute; + top: 50%; + transform: translateY(-50%); + width: 300px; + height: 3px; + background: linear-gradient(90deg, #fff, transparent); +} + +/* 分别为每一个流星设置位置、动画延迟时间、动画时长 */ +.container4 span:nth-child(1) { + top: 0; + right: 0; + /* initial关键字用于设置CSS属性为它的默认值 */ + /* 这个东西可以用来强制覆盖前面设置的属性 */ + /* left的初始值为auto,所以就相当于left:auto */ + left: initial; + /* 动画延迟时间 */ + animation-delay: 0s; + /* 动画时长 */ + animation-duration: 1s; +} + +.container4 span:nth-child(2) { + top: 0; + right: 80px; + left: initial; + animation-delay: 0.2s; + animation-duration: 3s; +} + +.container4 span:nth-child(3) { + top: 80px; + right: 0; + left: initial; + animation-delay: 0.4s; + animation-duration: 2s; +} + +.container4 span:nth-child(4) { + top: 0; + right: 180px; + left: initial; + animation-delay: 0.6s; + animation-duration: 1.5s; +} + +.container4 span:nth-child(5) { + top: 0; + right: 400px; + left: initial; + animation-delay: 0.8s; + animation-duration: 2.5s; +} + +.container4 span:nth-child(6) { + top: 0; + right: 600px; + left: initial; + animation-delay: 1s; + animation-duration: 3s; +} + +.container4 span:nth-child(7) { + top: 300px; + right: 0; + left: initial; + animation-delay: 1.2s; + animation-duration: 1.75s; +} + +.container4 span:nth-child(8) { + top: 0; + right: 700px; + left: initial; + animation-delay: 1.4s; + animation-duration: 1.25s; +} + +.container4 span:nth-child(9) { + top: 0; + right: 1000px; + left: initial; + animation-delay: 0.75s; + animation-duration: 2.25s; +} + +.container4 span:nth-child(10) { + top: 0; + right: 450px; + left: initial; + animation-delay: 2.75s; + animation-duration: 2.25s; +} + +/* 流星坠落动画 */ +@keyframes animate { + 0% { + transform: rotate(315deg) translateX(0); + opacity: 1; + } + + 90% { + opacity: 1; + } + + 100% { + transform: rotate(315deg) translateX(-1000px); + opacity: 0; + } +} \ No newline at end of file diff --git a/bysms/user/__init__.py b/bysms/user/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/bysms/user/__pycache__/__init__.cpython-312.pyc b/bysms/user/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000..8b39bca Binary files /dev/null and b/bysms/user/__pycache__/__init__.cpython-312.pyc differ diff --git a/bysms/user/__pycache__/admin.cpython-312.pyc b/bysms/user/__pycache__/admin.cpython-312.pyc new file mode 100644 index 0000000..6326ac0 Binary files /dev/null and b/bysms/user/__pycache__/admin.cpython-312.pyc differ diff --git a/bysms/user/__pycache__/apps.cpython-312.pyc b/bysms/user/__pycache__/apps.cpython-312.pyc new file mode 100644 index 0000000..2478f02 Binary files /dev/null and b/bysms/user/__pycache__/apps.cpython-312.pyc differ diff --git a/bysms/user/__pycache__/models.cpython-312.pyc b/bysms/user/__pycache__/models.cpython-312.pyc new file mode 100644 index 0000000..3dc515c Binary files /dev/null and b/bysms/user/__pycache__/models.cpython-312.pyc differ diff --git a/bysms/user/__pycache__/urls.cpython-312.pyc b/bysms/user/__pycache__/urls.cpython-312.pyc new file mode 100644 index 0000000..175a288 Binary files /dev/null and b/bysms/user/__pycache__/urls.cpython-312.pyc differ diff --git a/bysms/user/__pycache__/views.cpython-312.pyc b/bysms/user/__pycache__/views.cpython-312.pyc new file mode 100644 index 0000000..84297e2 Binary files /dev/null and b/bysms/user/__pycache__/views.cpython-312.pyc differ diff --git a/bysms/user/admin.py b/bysms/user/admin.py new file mode 100644 index 0000000..8c38f3f --- /dev/null +++ b/bysms/user/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/bysms/user/apps.py b/bysms/user/apps.py new file mode 100644 index 0000000..36cce4c --- /dev/null +++ b/bysms/user/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class UserConfig(AppConfig): + default_auto_field = 'django.db.models.BigAutoField' + name = 'user' diff --git a/bysms/user/migrations/0001_initial.py b/bysms/user/migrations/0001_initial.py new file mode 100644 index 0000000..748e8ee --- /dev/null +++ b/bysms/user/migrations/0001_initial.py @@ -0,0 +1,35 @@ +# Generated by Django 5.1.1 on 2024-09-30 11:58 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ] + + operations = [ + migrations.CreateModel( + name='user', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('username', models.CharField(max_length=200, unique=True)), + ('password', models.CharField(max_length=200)), + ], + ), + migrations.CreateModel( + name='student', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('student_xuehao', models.IntegerField(default=0)), + ('student_name', models.CharField(blank=True, max_length=200, null=True)), + ('student_major', models.CharField(blank=True, max_length=200, null=True)), + ('student_class', models.CharField(blank=True, max_length=200, null=True)), + ('student_score', models.IntegerField(default=0)), + ('teather', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='user.user')), + ], + ), + ] diff --git a/bysms/user/migrations/0002_alter_student_student_score.py b/bysms/user/migrations/0002_alter_student_student_score.py new file mode 100644 index 0000000..fc21c35 --- /dev/null +++ b/bysms/user/migrations/0002_alter_student_student_score.py @@ -0,0 +1,18 @@ +# Generated by Django 5.1.1 on 2024-10-01 13:17 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('user', '0001_initial'), + ] + + operations = [ + migrations.AlterField( + model_name='student', + name='student_score', + field=models.FloatField(default=0), + ), + ] diff --git a/bysms/user/migrations/__init__.py b/bysms/user/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/bysms/user/migrations/__pycache__/0001_initial.cpython-312.pyc b/bysms/user/migrations/__pycache__/0001_initial.cpython-312.pyc new file mode 100644 index 0000000..91964ed Binary files /dev/null and b/bysms/user/migrations/__pycache__/0001_initial.cpython-312.pyc differ diff --git a/bysms/user/migrations/__pycache__/0002_alter_student_student_score.cpython-312.pyc b/bysms/user/migrations/__pycache__/0002_alter_student_student_score.cpython-312.pyc new file mode 100644 index 0000000..47ccc99 Binary files /dev/null and b/bysms/user/migrations/__pycache__/0002_alter_student_student_score.cpython-312.pyc differ diff --git a/bysms/user/migrations/__pycache__/__init__.cpython-312.pyc b/bysms/user/migrations/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000..adc0cf1 Binary files /dev/null and b/bysms/user/migrations/__pycache__/__init__.cpython-312.pyc differ diff --git a/bysms/user/models.py b/bysms/user/models.py new file mode 100644 index 0000000..d334593 --- /dev/null +++ b/bysms/user/models.py @@ -0,0 +1,16 @@ +from django.db import models + +# Create your models here. +#用户表 +class user(models.Model): + username = models.CharField(max_length=200,unique=True) + password = models.CharField(max_length=200) + +#学生表 +class student(models.Model): + student_xuehao=models.IntegerField(default=0) + student_name = models.CharField(max_length=200,null=True, blank=True) + student_major = models.CharField(max_length=200,null=True, blank=True) + student_class = models.CharField(max_length=200,null=True, blank=True) + student_score = models.FloatField(default=0) + teather=models.ForeignKey(to='user',to_field='id',on_delete=models.CASCADE) \ No newline at end of file diff --git a/bysms/user/tests.py b/bysms/user/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/bysms/user/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/bysms/user/urls.py b/bysms/user/urls.py new file mode 100644 index 0000000..f02944a --- /dev/null +++ b/bysms/user/urls.py @@ -0,0 +1,19 @@ +from django.urls import path +from . import views +urlpatterns = [ + path('', views.loginpage), + + path('first/', views.firstpage,name='first'),#随机点名界面 + path('second/',views.secondpage,name='second'),#学生名单 + path('third/',views.thirdpage,name='third'),#积分排名 + path('login/', views.Loginadmit,name='login'),#登录验证 + path('register/', views.Register,name='register'),#注册 + path('upload_excel/', views.upload_excel, name='upload_excel'),#上传文件页面 + path('upload_file/', views.upload_file, name='upload_file'),#上传execl文件 + path('delete_excel/',views.delete_excel,name='delete_excel'),#删除学生名单 + path('dianming/',views.dianming,name='dianming'),#随机点名和特殊规则 + path('submitscore/',views.submitscore,name='submitscore'),#提交积分 + path('fourth/',views.fourthpage,name='fourth'),#用户信息 + path('xiugai/',views.xiugai,name='xiugai'),#账号和密码修改 + path('zhuxiao/',views.zhuxiao,name='zhuxiao'),#账户注销 +] \ No newline at end of file diff --git a/bysms/user/views.py b/bysms/user/views.py new file mode 100644 index 0000000..683af9c --- /dev/null +++ b/bysms/user/views.py @@ -0,0 +1,217 @@ +from django.shortcuts import render +from django.http import HttpResponse, JsonResponse +from user.models import user +from user.models import student +import pandas as pd +import random +# Create your views here. +def loginpage(request): + return render(request, 'login.html') + +def Loginadmit(request): + if request.method == 'POST': + username = request.POST.get('username') + password = request.POST.get('password') + print(username,password) + if user.objects.filter(username=username).exists(): + if user.objects.filter(username=username,password=password).exists(): + request.session["info"]=username + return render(request, 'firstpage.html') + else: + return HttpResponse("密码错误") + else: + return HttpResponse("用户名不存在") + + +def Register(request): + sign=0 + if request.method == 'POST':#判断是否登录 + + username = request.POST.get('username') + password = request.POST.get('password') + qs = user.objects.values + if user.objects.filter(username=username).exists(): + return HttpResponse("用户名已存在") + else: + user.objects.create(username=username,password=password) + return render(request, 'login.html',{'success':'注册成功'}) + +# 第一页 +def firstpage(request): + if request.session.get("info"):#判断是否登录 + return render(request, 'firstpage.html') + else: + return render(request, 'login.html') + +#随机点名 +def dianming(request): + if request.session.get("info"):#判断是否登录 + User=user.objects.filter(username=request.session.get("info")).first()#获取当前用户 + studentlist=student.objects.filter(teather_id=User.id)#获取当前用户的学生表 + if len(studentlist)==0:#判断学生表是否为空 + return render(request, 'firstpage.html',{'form':'暂无学生'}) + #权重随机点名算法 + form=weights_random_choice(studentlist) + #随机事件 + random_number = random.randint(1, 11)#随机数 + if random_number ==5:#触发事件双倍扣分 + fair='zhongkou' + return render(request,'firstpage.html',{'form':form.student_name,'sign':fair}) + elif random_number ==6:#触发事件可以指定同学帮忙回答 + fair='lucky' + return render(request,'firstpage.html',{'form':form.student_name,'sign':fair}) + else: + return render(request,'firstpage.html',{'form':form.student_name,'sign':'none'}) + else: + return render(request, 'login.html') +#权重随机点名算法 +def weights_random_choice(studentlist): + # 偏移所有分数 + offset = max(1, abs(min(student.student_score for student in studentlist)))#计算最小值的绝对值 + adjusted_points = [student.student_score + offset for student in studentlist]#添加偏移 + + # 计算逆向权重 + inverse_weights = [1 / (point+1) for point in adjusted_points] + # 归一化逆向权重 + total_inverse_weight = sum(inverse_weights) + normalized_inverse_weights = [w / total_inverse_weight for w in inverse_weights] + # 选择一个学生 + selected_student = random.choices(studentlist, weights=normalized_inverse_weights, k=1)[0] + print(selected_student) + return selected_student + + +# 分数写入 +def submitscore(request): + teather=request.session.get("info")#获取当前用户 + if teather:#判断是否登录 + if request.method == 'POST': + print(request.POST) + User=user.objects.filter(username=teather).first()#获取当前用户的id + STdname=request.POST.get('student_name','')#获取被点到的学生姓名 + print(STdname) + STudent=student.objects.filter(teather_id=User.id,student_name=STdname ).first()#获取被点到的学生 + print(request.POST) + #{'student_name': ['才需困'], 'daoda': ['1'], 'score1': ['1'], 'score2': ['0.5']}> + daoda=request.POST.get('daoda','') + score1=request.POST.get('score1','') + score2=request.POST.get('score2','') + if daoda=='1':#到课堂加1分 + STudent.student_score+=1 + elif daoda=='2':#没到扣1分 + STudent.student_score-=1 + elif daoda=='22':#没到扣2分(双倍扣分) + STudent.student_score-=2 + #重复问题 + if score1=='1':#重复问题加0.5分 + STudent.student_score+=0.5 + elif score1=='2':#重复不了问题扣1分 + STudent.student_score-=1 + elif score1=='22':#重复不了问题扣2分(双倍扣分) + STudent.student_score-=2 + #回答问题 + STudent.student_score+=float(score2) + print(STudent.student_score) + #写入数据库 + STudent.save() + return render(request, 'firstpage.html') + else: + return render(request, 'login.html') +# 第二页 +def secondpage(request): + teather=request.session.get("info")#获取用户信息 + if teather:#判断是否登录 + User=user.objects.filter(username=teather).first()#获取用户 + form=student.objects.filter(teather_id=User.id) + return render(request, 'secondpage.html',{'form':form})#返回学生数据 + else: + return render(request, 'login.html') + +# 第三页 +def thirdpage(request): + teather=request.session.get("info")#获取用户session信息 + if teather: + User=user.objects.filter(username=teather).first()#获取当前用户的id + + form=student.objects.filter(teather_id=User.id).order_by('-student_score') + + return render(request, 'thirdpage.html',{"form":form}) + else: + return render(request, 'login.html') + +#上传Excel文件 +def upload_excel(request): + if request.session.get("info"): + return render(request, 'upload.html') + else: + return render(request, 'login.html') +#接收文件 +def upload_file(request): + teather=request.session.get("info")#获取session中的用户名 + if teather: + User=user.objects.filter(username=teather).first()#获取用户 + if request.method == 'POST': + excel_file = request.FILES.get('file')#获取excel表格文件 + df=pd.read_excel(excel_file)#读取excel表格 + for index, row in df.iterrows(): + if student.objects.filter(student_xuehao=row['学号'],teather_id=User.id).exists():#判断是否已经存在当前老师的学生表中 + continue + student.objects.create(student_xuehao=row['学号'],student_name=row['姓名'],student_major=row['专业'],student_class=row['班级'],teather_id=User.id)#写入学生表 + form=student.objects.filter(teather_id=User.id)#返回当前老师的学生表 + return render(request, 'secondpage.html',{'form':form}) + else: + return render(request, 'login.html') + + +#删除表格 +def delete_excel(request): + teather=request.session.get("info")#获取session中的用户名 + if teather: + User=user.objects.filter(username=teather).first()#获取用户 + print("删除当前老师的所有学生") + student.objects.filter(teather_id=User.id).delete() + return render(request, 'secondpage.html') + else: + return render(request, 'login.html') + + +#第四页 +def fourthpage(request): + teather=request.session.get("info")#获取当前用户 + if teather:#判断是否登录 + User=user.objects.filter(username=teather).first()#获取当前用户的id + return render(request, 'fourthpage.html',{'name':User.username}) + else: + return render(request, 'login.html') + +#账号和密码修改 +def xiugai(request): + teather=request.session.get("info")#获取当前用户名 + if teather:#判断是否登录 + User=user.objects.filter(username=teather).first()#获取当前用户 + if request.method == 'POST': + username=request.POST.get('username','') + password=request.POST.get('password','') + print(username,password) + if username=='' and password=='': + return render(request, 'fourthpage.html',{'name':User.username}) + else: + if username!='': + User.username=username + if password!='': + User.password=password + User.save() + return render(request, 'login.html') + else: + return render(request, 'login.html') + +#账户注销 +def zhuxiao(request): + teather=request.session.get("info")#获取当前用户名 + if teather:#判断是否登录 + User=user.objects.filter(username=teather).first()#获取当前用户 + if request.method == 'POST': + User.delete() + return render(request, 'login.html') + else: + return render(request, 'login.html') \ No newline at end of file