This commit is contained in:
Your Name 2025-01-16 17:47:49 +08:00
commit 8d1d44bee7
59 changed files with 1981 additions and 0 deletions

10
MySQL/config/my.cnf Executable file
View File

@ -0,0 +1,10 @@
[mysqld]
user=mysql
default-storage-engine=INNODB
character-set-server=utf8
[client]
default-character-set=utf8
[mysql]
default-character-set=utf8

View File

@ -0,0 +1,336 @@
-- MySQL dump 10.13 Distrib 5.7.44, for Linux (x86_64)
--
-- Host: localhost Database: sims
-- ------------------------------------------------------
-- Server version 5.7.44
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
--
-- Table structure for table `Student`
--
DROP TABLE IF EXISTS `Student`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `Student` (
`SNo` int(11) NOT NULL,
`SName` varchar(100) NOT NULL,
`Gender` varchar(100) NOT NULL,
`Birthday` date NOT NULL,
`Mobile` varchar(100) NOT NULL,
`Email` varchar(100) NOT NULL,
`Address` varchar(500) NOT NULL,
`Image` varchar(200) DEFAULT NULL,
PRIMARY KEY (`SNo`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `Student`
--
LOCK TABLES `Student` WRITE;
/*!40000 ALTER TABLE `Student` DISABLE KEYS */;
INSERT INTO `Student` VALUES (95001,'王进','','2020-02-01','13900998877','wangjin@abc.com','江苏省南京市溧水区宝塔路11号','e8ec33473c6d16a19d280b8dc634758c.jpg'),(95002,'李四','','1994-07-25','13462312498','lisi@sohu.com','上海市徐汇区漕宝路99弄',NULL),(95003,'陈鹏','','1995-03-04','18987123123','chenpeng@163.com','上海市闵行区银都路294号',NULL),(95004,'张丽','','1995-03-05','13482034096','zhangli@iLync.cn','上海市徐汇区习勤路100弄',NULL),(95005,'刘向东','','1995-03-06','13787123123','liuxiangdong@iLync.cn','上海市闵行区春申路295号',NULL),(95006,'李明博','','1995-03-07','18932178905','zhangzhiqiang@sina.com','上海市徐汇区柳州路101弄',NULL),(95007,'张子强','','1995-03-08','17600715247','wwh@live.cn','上海市闵行区虹梅南路296号',NULL),(95008,'王文海','','1995-03-09','18238391838','65212321@qq.com','上海市徐汇区龙漕路102弄',NULL),(95009,'刘慧娟','','1995-03-10','18876068428','liuhuijuan@iLync.cn','上海市闵行区颛兴东路297号',NULL),(95010,'陈敏','','1995-03-11','13513745019','chenming@sohu.com','上海市徐汇区桂林路103弄','dae3aa26a0c8cfa950e6cbb98425b9d8.jpg'),(95011,'王云','','1995-03-12','13051421609','wangyun@gmail.com','上海市闵行区开发区大道298号','1fec845b4fc9065c249914047c2e32c7.jpg'),(95012,'沈璐','','1995-03-13','13889098199','shenlu@iLync.cn','上海市徐汇区田东路104弄','8892f98a849bdcc06eece1738d47c2bf.jpg'),(95013,'赵鹏飞','','1995-03-14','15026774790','chenpengfei@iLync.cn','上海市闵行区都市路99号','76c0581ba6f7c8d637f971be17848ef3.jpg'),(95014,'谢朝阳','','1995-03-15','18064451380','xiechaoyang@sohu.com','上海市徐汇区钦州北路105弄',NULL),(95015,'刘子歌','','1995-03-16','13902127970','6533422@qq.com','上海市闵行区都会路300号',NULL),(95016,'陈照升','','1995-03-17','13339804561','chenzs@iLync.cn','上海市徐汇区中山北路106弄',NULL),(95017,'秦小路','','1995-03-18','13477481151','qinxl@sina.com','上海市闵行区都庄路301号',NULL),(95018,'张大宝','','1995-03-19','13915157742','zhangdb@sohu.com','上海市徐汇区桂林东街107弄',NULL),(95019,'刘佳','','1995-03-20','13352834332','liujia@sohu.com','上海市闵行区剑川路302号',NULL),(95020,'李伟','','1995-03-21','15990510922','lw@263.com','上海市徐汇区桂林西街108弄',NULL),(95021,'杨荣','','1995-05-31','13522341234','yangrong@iLync.cn','江苏省泰州市姜堰区华港镇254号',NULL);
/*!40000 ALTER TABLE `Student` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `auth_group`
--
DROP TABLE IF EXISTS `auth_group`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `auth_group` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(80) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `name` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `auth_group`
--
LOCK TABLES `auth_group` WRITE;
/*!40000 ALTER TABLE `auth_group` DISABLE KEYS */;
/*!40000 ALTER TABLE `auth_group` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `auth_group_permissions`
--
DROP TABLE IF EXISTS `auth_group_permissions`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `auth_group_permissions` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`group_id` int(11) NOT NULL,
`permission_id` int(11) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `auth_group_permissions_group_id_permission_id_0cd325b0_uniq` (`group_id`,`permission_id`),
KEY `auth_group_permissio_permission_id_84c5c92e_fk_auth_perm` (`permission_id`),
CONSTRAINT `auth_group_permissio_permission_id_84c5c92e_fk_auth_perm` FOREIGN KEY (`permission_id`) REFERENCES `auth_permission` (`id`),
CONSTRAINT `auth_group_permissions_group_id_b120cbf9_fk_auth_group_id` FOREIGN KEY (`group_id`) REFERENCES `auth_group` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `auth_group_permissions`
--
LOCK TABLES `auth_group_permissions` WRITE;
/*!40000 ALTER TABLE `auth_group_permissions` DISABLE KEYS */;
/*!40000 ALTER TABLE `auth_group_permissions` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `auth_permission`
--
DROP TABLE IF EXISTS `auth_permission`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `auth_permission` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL,
`content_type_id` int(11) NOT NULL,
`codename` varchar(100) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `auth_permission_content_type_id_codename_01ab375a_uniq` (`content_type_id`,`codename`),
CONSTRAINT `auth_permission_content_type_id_2f476e4b_fk_django_co` FOREIGN KEY (`content_type_id`) REFERENCES `django_content_type` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=29 DEFAULT CHARSET=utf8mb4;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `auth_permission`
--
LOCK TABLES `auth_permission` WRITE;
/*!40000 ALTER TABLE `auth_permission` DISABLE KEYS */;
INSERT INTO `auth_permission` VALUES (1,'Can add log entry',1,'add_logentry'),(2,'Can change log entry',1,'change_logentry'),(3,'Can delete log entry',1,'delete_logentry'),(4,'Can view log entry',1,'view_logentry'),(5,'Can add permission',2,'add_permission'),(6,'Can change permission',2,'change_permission'),(7,'Can delete permission',2,'delete_permission'),(8,'Can view permission',2,'view_permission'),(9,'Can add group',3,'add_group'),(10,'Can change group',3,'change_group'),(11,'Can delete group',3,'delete_group'),(12,'Can view group',3,'view_group'),(13,'Can add user',4,'add_user'),(14,'Can change user',4,'change_user'),(15,'Can delete user',4,'delete_user'),(16,'Can view user',4,'view_user'),(17,'Can add content type',5,'add_contenttype'),(18,'Can change content type',5,'change_contenttype'),(19,'Can delete content type',5,'delete_contenttype'),(20,'Can view content type',5,'view_contenttype'),(21,'Can add session',6,'add_session'),(22,'Can change session',6,'change_session'),(23,'Can delete session',6,'delete_session'),(24,'Can view session',6,'view_session'),(25,'Can add student',7,'add_student'),(26,'Can change student',7,'change_student'),(27,'Can delete student',7,'delete_student'),(28,'Can view student',7,'view_student');
/*!40000 ALTER TABLE `auth_permission` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `auth_user`
--
DROP TABLE IF EXISTS `auth_user`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `auth_user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`password` varchar(128) NOT NULL,
`last_login` datetime(6) DEFAULT NULL,
`is_superuser` tinyint(1) NOT NULL,
`username` varchar(150) NOT NULL,
`first_name` varchar(30) NOT NULL,
`last_name` varchar(150) NOT NULL,
`email` varchar(254) NOT NULL,
`is_staff` tinyint(1) NOT NULL,
`is_active` tinyint(1) NOT NULL,
`date_joined` datetime(6) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `username` (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `auth_user`
--
LOCK TABLES `auth_user` WRITE;
/*!40000 ALTER TABLE `auth_user` DISABLE KEYS */;
/*!40000 ALTER TABLE `auth_user` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `auth_user_groups`
--
DROP TABLE IF EXISTS `auth_user_groups`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `auth_user_groups` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) NOT NULL,
`group_id` int(11) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `auth_user_groups_user_id_group_id_94350c0c_uniq` (`user_id`,`group_id`),
KEY `auth_user_groups_group_id_97559544_fk_auth_group_id` (`group_id`),
CONSTRAINT `auth_user_groups_group_id_97559544_fk_auth_group_id` FOREIGN KEY (`group_id`) REFERENCES `auth_group` (`id`),
CONSTRAINT `auth_user_groups_user_id_6a12ed8b_fk_auth_user_id` FOREIGN KEY (`user_id`) REFERENCES `auth_user` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `auth_user_groups`
--
LOCK TABLES `auth_user_groups` WRITE;
/*!40000 ALTER TABLE `auth_user_groups` DISABLE KEYS */;
/*!40000 ALTER TABLE `auth_user_groups` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `auth_user_user_permissions`
--
DROP TABLE IF EXISTS `auth_user_user_permissions`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `auth_user_user_permissions` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) NOT NULL,
`permission_id` int(11) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `auth_user_user_permissions_user_id_permission_id_14a6b632_uniq` (`user_id`,`permission_id`),
KEY `auth_user_user_permi_permission_id_1fbb5f2c_fk_auth_perm` (`permission_id`),
CONSTRAINT `auth_user_user_permi_permission_id_1fbb5f2c_fk_auth_perm` FOREIGN KEY (`permission_id`) REFERENCES `auth_permission` (`id`),
CONSTRAINT `auth_user_user_permissions_user_id_a95ead1b_fk_auth_user_id` FOREIGN KEY (`user_id`) REFERENCES `auth_user` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `auth_user_user_permissions`
--
LOCK TABLES `auth_user_user_permissions` WRITE;
/*!40000 ALTER TABLE `auth_user_user_permissions` DISABLE KEYS */;
/*!40000 ALTER TABLE `auth_user_user_permissions` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `django_admin_log`
--
DROP TABLE IF EXISTS `django_admin_log`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `django_admin_log` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`action_time` datetime(6) NOT NULL,
`object_id` longtext,
`object_repr` varchar(200) NOT NULL,
`action_flag` smallint(5) unsigned NOT NULL,
`change_message` longtext NOT NULL,
`content_type_id` int(11) DEFAULT NULL,
`user_id` int(11) NOT NULL,
PRIMARY KEY (`id`),
KEY `django_admin_log_content_type_id_c4bce8eb_fk_django_co` (`content_type_id`),
KEY `django_admin_log_user_id_c564eba6_fk_auth_user_id` (`user_id`),
CONSTRAINT `django_admin_log_content_type_id_c4bce8eb_fk_django_co` FOREIGN KEY (`content_type_id`) REFERENCES `django_content_type` (`id`),
CONSTRAINT `django_admin_log_user_id_c564eba6_fk_auth_user_id` FOREIGN KEY (`user_id`) REFERENCES `auth_user` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `django_admin_log`
--
LOCK TABLES `django_admin_log` WRITE;
/*!40000 ALTER TABLE `django_admin_log` DISABLE KEYS */;
/*!40000 ALTER TABLE `django_admin_log` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `django_content_type`
--
DROP TABLE IF EXISTS `django_content_type`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `django_content_type` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`app_label` varchar(100) NOT NULL,
`model` varchar(100) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `django_content_type_app_label_model_76bd3d3b_uniq` (`app_label`,`model`)
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8mb4;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `django_content_type`
--
LOCK TABLES `django_content_type` WRITE;
/*!40000 ALTER TABLE `django_content_type` DISABLE KEYS */;
INSERT INTO `django_content_type` VALUES (1,'admin','logentry'),(3,'auth','group'),(2,'auth','permission'),(4,'auth','user'),(5,'contenttypes','contenttype'),(6,'sessions','session'),(7,'sims','student');
/*!40000 ALTER TABLE `django_content_type` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `django_migrations`
--
DROP TABLE IF EXISTS `django_migrations`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `django_migrations` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`app` varchar(255) NOT NULL,
`name` varchar(255) NOT NULL,
`applied` datetime(6) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=17 DEFAULT CHARSET=utf8mb4;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `django_migrations`
--
LOCK TABLES `django_migrations` WRITE;
/*!40000 ALTER TABLE `django_migrations` DISABLE KEYS */;
INSERT INTO `django_migrations` VALUES (1,'contenttypes','0001_initial','2024-12-20 08:26:13.110217'),(2,'auth','0001_initial','2024-12-20 08:26:14.077220'),(3,'admin','0001_initial','2024-12-20 08:26:14.310216'),(4,'admin','0002_logentry_remove_auto_add','2024-12-20 08:26:14.325216'),(5,'admin','0003_logentry_add_action_flag_choices','2024-12-20 08:26:14.347215'),(6,'contenttypes','0002_remove_content_type_name','2024-12-20 08:26:14.477216'),(7,'auth','0002_alter_permission_name_max_length','2024-12-20 08:26:14.550215'),(8,'auth','0003_alter_user_email_max_length','2024-12-20 08:26:14.586216'),(9,'auth','0004_alter_user_username_opts','2024-12-20 08:26:14.601214'),(10,'auth','0005_alter_user_last_login_null','2024-12-20 08:26:14.669215'),(11,'auth','0006_require_contenttypes_0002','2024-12-20 08:26:14.681214'),(12,'auth','0007_alter_validators_add_error_messages','2024-12-20 08:26:14.696217'),(13,'auth','0008_alter_user_username_max_length','2024-12-20 08:26:14.770216'),(14,'auth','0009_alter_user_last_name_max_length','2024-12-20 08:26:14.841235'),(15,'sessions','0001_initial','2024-12-20 08:26:14.930216'),(16,'sims','0001_initial','2024-12-20 08:26:15.037217');
/*!40000 ALTER TABLE `django_migrations` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `django_session`
--
DROP TABLE IF EXISTS `django_session`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `django_session` (
`session_key` varchar(40) NOT NULL,
`session_data` longtext NOT NULL,
`expire_date` datetime(6) NOT NULL,
PRIMARY KEY (`session_key`),
KEY `django_session_expire_date_a5c62663` (`expire_date`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `django_session`
--
LOCK TABLES `django_session` WRITE;
/*!40000 ALTER TABLE `django_session` DISABLE KEYS */;
/*!40000 ALTER TABLE `django_session` ENABLE KEYS */;
UNLOCK TABLES;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-- Dump completed on 2024-12-26 16:58:05

18
README.md Executable file
View File

@ -0,0 +1,18 @@
## 环境信息
Python版本Python 3.7
Django版本2.1.4
Vue版本2.6.11
Element版本2.13.0
数据库MySQL 5.7
后端编辑器PyCharm
前端编辑器VS code 插件:`Vue 2 Snippets` + `Live Server`

0
apps/__init__.py Executable file
View File

2
apps/sims/__init__.py Executable file
View File

@ -0,0 +1,2 @@
import pymysql
pymysql.install_as_MySQLdb()

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

3
apps/sims/admin.py Executable file
View File

@ -0,0 +1,3 @@
from django.contrib import admin
# Register your models here.

5
apps/sims/apps.py Executable file
View File

@ -0,0 +1,5 @@
from django.apps import AppConfig
class SimsConfig(AppConfig):
name = 'apps.sims'

View File

@ -0,0 +1,31 @@
# Generated by Django 2.1.4 on 2024-12-20 08:23
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='Student',
fields=[
('sno', models.IntegerField(db_column='SNo', primary_key=True, serialize=False)),
('name', models.CharField(db_column='SName', max_length=100)),
('gender', models.CharField(choices=[('', ''), ('', '')], db_column='Gender', max_length=100)),
('birthday', models.DateField(db_column='Birthday')),
('mobile', models.CharField(db_column='Mobile', max_length=100)),
('email', models.CharField(db_column='Email', max_length=100)),
('address', models.CharField(db_column='Address', max_length=500)),
('image', models.CharField(db_column='Image', max_length=200, null=True)),
],
options={
'db_table': 'Student',
'managed': True,
},
),
]

View File

Binary file not shown.

Binary file not shown.

27
apps/sims/models.py Executable file
View File

@ -0,0 +1,27 @@
from django.db import models
# Create your models here.
# student: 学号,姓名,性别,出生日期,手机号码,邮箱地址,家庭住址,照片
# 创建一个类,类属性映射表字段
class Student(models.Model):
gender_choices = (('',''),('',''))
sno = models.IntegerField(db_column="SNo", primary_key=True, null=False) # 学号,不允许为空,主键
name = models.CharField(db_column="SName", max_length=100, null=False) # 姓名最长100个字符不允许为空
gender = models.CharField(db_column="Gender",max_length=100,choices=gender_choices) # 性别,选项选择
birthday = models.DateField(db_column="Birthday", null=False) # 出生日期,不允许为空
mobile = models.CharField(db_column="Mobile", max_length=100) # 手机号码,
email = models.CharField(db_column="Email",max_length=100) # 邮箱地址
address = models.CharField(db_column="Address",max_length=500) # 家庭住址
image = models.CharField(db_column="Image", max_length=200,null=True) # 照片
# 在默认情况下生成的表名App_class, 如果要自定义 需要使用Class Meta来自定义
class Meta:
managed = True
db_table = "Student"
# __str__方法
def __str__(self):
return "学号:%s\t姓名:%s\t性别:%s" %(self.sno,self.name,self.gender)

3
apps/sims/tests.py Executable file
View File

@ -0,0 +1,3 @@
from django.test import TestCase
# Create your tests here.

323
apps/sims/views.py Executable file
View File

@ -0,0 +1,323 @@
from django.shortcuts import render
# 引入 Student 的类
from sims.models import Student
# 引入 JsonResponse 模块
from django.http import JsonResponse
# 导入 json 模块
import json
# 导入 Q 查询
from django.db.models import Q
# 导入 uuid 类
import uuid
# 导入哈希库
import hashlib
# 导入setting
from django.conf import settings
# 导入os
import os
# 导入 openpyxl
import openpyxl
# Create your views here.
def get_students(request):
"""" 获取所有学生的信息 """
try:
# 使用 ORM 获取所有学生信息
obj_students = Student.objects.all().values()
# 把结果转为 List
students = list(obj_students)
# 返回
return JsonResponse({'code': 1, 'data': students})
except Exception as e:
# 如果出现异常返回
return JsonResponse({'code': 0, 'msg': "获取学生信息出现异常:" + str(e)})
def query_students(request):
"""" 查询学生的信息 """
# 接收传递过来的关键字 --- axios默认是json --- 转换为字典类型('inputstr') --- data['inputstr']
data = json.loads(request.body.decode('utf-8'))
try:
# 使用ORM获取满足条件的学生信息 并把对象转为字典格式
obj_students = Student.objects.filter(Q(sno__icontains=data['inputstr']) | Q(name__icontains=data['inputstr']) |
Q(gender__icontains=data['inputstr']) | Q(
mobile__icontains=data['inputstr'])
| Q(email__icontains=data['inputstr']) | Q(
address__icontains=data['inputstr'])).values()
# 把结果转为 List
students = list(obj_students)
# 返回
return JsonResponse({'code': 1, 'data': students})
except Exception as e:
# 如果出现异常返回
return JsonResponse({'code': 0, 'msg': "获取学生信息出现异常:" + str(e)})
def is_exists_sno(request):
"""判断学号是否存在"""
# 接收传递过来的学号
data = json.loads(request.body.decode('utf-8'))
try:
obj_students = Student.objects.filter(sno=data['sno'])
if obj_students.count() == 0:
return JsonResponse({'code': 1, 'exists': False})
else:
return JsonResponse({'code': 1, 'exists': True})
except Exception as e:
return JsonResponse({'code': 0, 'msg': "校验学号失败,失败原因:" + str(e)})
def add_student(request):
"""" 添加学生信息到数据库 """
# 接收传递过来的值
data = json.loads(request.body.decode('utf-8'))
try:
# 添加到数据库
obj_student = Student(sno=data['sno'],
name=data['name'],
gender=data['gender'],
birthday=data['birthday'],
mobile=data['mobile'],
email=data['email'],
address=data['address'],
image=data['image']
)
# 执行添加
obj_student.save()
# 使用 ORM 获取所有学生信息
obj_students = Student.objects.all().values()
# 把结果转为 List
students = list(obj_students)
# 返回
return JsonResponse({'code': 1, 'data': students})
except Exception as e:
# 如果出现异常返回
return JsonResponse({'code': 0, 'msg': "添加学生信息到数据库出现异常,原因如下:" + str(e)})
def update_student(request):
"""" 更新学生信息到数据库 """
# 接收传递过来的值
data = json.loads(request.body.decode('utf-8'))
try:
# 查找到要修改的学生信息
obj_student = Student.objects.get(sno=data['sno'])
# 依次修改
obj_student.name = data['name']
obj_student.gender = data['gender']
obj_student.birthday = data['birthday']
obj_student.mobile = data['mobile']
obj_student.email = data['email']
obj_student.address = data['address']
obj_student.image = data['image']
# 保存
obj_student.save()
# 使用 ORM 获取所有学生信息
obj_students = Student.objects.all().values()
# 把结果转为 List
students = list(obj_students)
# 返回
return JsonResponse({'code': 1, 'data': students})
except Exception as e:
# 如果出现异常返回
return JsonResponse({'code': 0, 'msg': "修改学生信息到数据库出现异常,原因如下:" + str(e)})
def delete_student(request):
"""" 删除一条学生信息 """
# 接收传递过来的值
data = json.loads(request.body.decode('utf-8'))
try:
# 查找到要删除的学生信息
obj_student = Student.objects.get(sno=data['sno'])
# 删除
obj_student.delete();
# 使用 ORM 获取所有学生信息
obj_students = Student.objects.all().values()
# 把结果转为 List
students = list(obj_students)
# 返回
return JsonResponse({'code': 1, 'data': students})
except Exception as e:
# 如果出现异常返回
return JsonResponse({'code': 0, 'msg': "删除学生信息写入数据库出现异常,原因如下:" + str(e)})
def delete_students(request):
"""" 批量删除学生信息 """
# 接收传递过来的值
data = json.loads(request.body.decode('utf-8'))
try:
# 遍历传递的集合
for one_student in data['student']:
# 查询当前记录
obj_student = Student.objects.get(sno=one_student['sno'])
# 执行删除
obj_student.delete()
# 获取最后的结果
# 使用 ORM 获取所有学生信息
obj_students = Student.objects.all().values()
# 把结果转为 List
students = list(obj_students)
# 返回
return JsonResponse({'code': 1, 'data': students})
except Exception as e:
# 如果出现异常返回
return JsonResponse({'code': 0, 'msg': "批量删除学生信息写入数据库出现异常,原因如下:" + str(e)})
def upload(request):
"""接收上传的文件"""
# 接收上传的文件
rev_file = request.FILES.get('avatar')
# 判断,是否有文件
if not rev_file:
return JsonResponse({'code': 0, 'msg': '图片不存在!'})
# 获得一个唯一的名字: uuid +hash
new_name = get_random_str()
# 准备写入的URL
file_path = os.path.join(settings.MEDIA_ROOT, new_name + os.path.splitext(rev_file.name)[1])
# 开始写入到本次磁盘
try:
f = open(file_path, 'wb')
# 多次写入
for i in rev_file.chunks():
f.write(i)
# 要关闭
f.close()
# 返回
return JsonResponse({'code': 1, 'name': new_name + os.path.splitext(rev_file.name)[1]})
except Exception as e:
return JsonResponse({'code': 0, 'msg': str(e)})
def get_random_str():
# 获取uuid的随机数
uuid_val = uuid.uuid4()
# 获取uuid的随机数字符串
uuid_str = str(uuid_val).encode('utf-8')
# 获取md5实例
md5 = hashlib.md5()
# 拿取uuid的md5摘要
md5.update(uuid_str)
# 返回固定长度的字符串
return md5.hexdigest()
def import_students_excel(request):
""" 从 excel 批量导入学生信息 """
# 1. 接收 excel 文件存储到 Media 文件夹
rev_file = request.FILES.get('excel')
# 判断,是否有文件
if not rev_file:
return JsonResponse({'code': 0, 'msg': 'excel文件不存在'})
# 获得一个唯一的名字: uuid +hash
new_name = get_random_str()
# 准备写入的URL
file_path = os.path.join(settings.MEDIA_ROOT, new_name + os.path.splitext(rev_file.name)[1])
# 开始写入到本次磁盘
try:
f = open(file_path, 'wb')
# 多次写入
for i in rev_file.chunks():
f.write(i)
# 要关闭
f.close()
except Exception as e:
return JsonResponse({'code': 0, 'msg': str(e)})
# 2. 读取存储在 Media 的文件
ex_students = read_excel_dict(file_path)
# 3. 把读取的数据存储到数据库
success = 0
error = 0
error_snos = []
# 开始遍历
for one_student in ex_students:
try:
obj_student = Student.objects.create(sno=one_student['sno'],
name=one_student['name'],
gender=one_student['gender'],
birthday=one_student['birthday'],
mobile=one_student['mobile'],
email=one_student['email'],
address=one_student['address'])
# 保存
obj_student.save()
# 计数
success += 1
except:
# 如果失败了
error += 1
error_snos.append(one_student['sno'])
# 4. 返回导入的信息
obj_student = Student.objects.all().values()
students = list(obj_student)
return JsonResponse({'code':1, 'success': success, 'error': error, 'errors': error_snos, 'data': students})
def write_to_excel(data:list, path:str):
"""把数据库写入到Excel"""
# 实例化一个workbook
workbook = openpyxl.Workbook()
# 激活一个sheet
sheet = workbook.active
# 为sheet命名
sheet.title = 'student'
# 准备keys
keys = data[0].keys()
# 准备写入数据
for index, item in enumerate(data):
# 遍历每一个元素
for k,v in enumerate(keys):
sheet.cell(row=index + 1, column=k+ 1, value=str(item[v]))
# 写入到文件
workbook.save(path)
def read_excel_dict(path: str):
""" 读取 Excel 文件存储为字典"""
# 实例化一个workbook
workbook = openpyxl.load_workbook(path)
# 实例化一个sheet
sheet = workbook['student']
# 定义一个变量存储最终的数据
students = []
# 准备key
keys = ['sno', 'name', 'gender', 'birthday', 'mobile', 'email', 'address']
# 遍历
for row in sheet.rows:
# 定义一个临时字典
temp_dict = {}
# 组合值和key
for index, cell in enumerate(row):
# 组合
temp_dict[keys[index]] = cell.value
# 附加到 list 中
students.append(temp_dict)
# 返回
return students
def export_students_excel(request):
"""到处数据到excel"""
# 获取所有的学生信息
obj_students = Student.objects.all().values()
# 转为List
students = list(obj_students)
# 准备名称
excel_name = get_random_str() + ".xlsx"
# 准备写入的路劲
path = os.path.join(settings.MEDIA_ROOT, excel_name)
# 写入到Excel
write_to_excel(students, path)
# 返回
return JsonResponse({'code':1, 'name':excel_name })

0
db.sqlite3 Executable file
View File

71
docker-compose.yml Executable file
View File

@ -0,0 +1,71 @@
version: '3'
services:
simsdb:
image: registry.cn-hangzhou.aliyuncs.com/hzbb/mysql:5.7.44
restart: always
container_name: simsdb
environment:
TZ: Asia/Shanghai
MYSQL_DATABASE: sims
MYSQL_USER: test
MYSQL_PASSWORD: admin@123456
MYSQL_ROOT_PASSWORD: admin@123456
ports:
- 3306:3306
volumes:
- ./MySQL/data:/var/lib/mysql
- ./MySQL/config/my.cnf:/etc/mysql/my.cnf
- ./MySQL/mysql-files:/var/lib/mysql-files
- ./MySQL/docker-entrypoint-initdb.d/:/docker-entrypoint-initdb.d/
command:
--max_connections=1000
--character-set-server=utf8mb4
--collation-server=utf8mb4_general_ci
--default-authentication-plugin=mysql_native_password
simsbe:
image: registry.cn-hangzhou.aliyuncs.com/hzbb/python:3.7.0
restart: always
hostname: simsbe
container_name: simsbe
volumes:
- ./:/simsBE
- ./module:/module
depends_on:
- simsdb
environment:
- TZ=Asia/Shanghai
command: bash /module/run.sh
healthcheck:
test: ["CMD", "curl", "-f", "http://127.0.0.1:8000/students/"]
interval: 20s
timeout: 5s
retries: 3
start_period: 10s
simsfe:
image: registry.cn-hangzhou.aliyuncs.com/hzbb/nginx:1.26.0
restart: always
container_name: simsfe
environment:
TZ: Asia/Shanghai
ports:
- 80:80
- 443:443
depends_on:
- simsbe
- simsdb
volumes:
- ./nginx/nginx.conf:/etc/nginx/nginx.conf
- ./nginx/conf.d:/etc/nginx/conf.d
- ./nginx/cert:/etc/nginx/cert
- ./front:/simsFE
autoheal:
image: registry.cn-hangzhou.aliyuncs.com/hzbb/autoheal:1.2.0
restart: always
container_name: sims-autoheal
environment:
- AUTOHEAL_CONTAINER_LABEL=all
volumes:
- /var/run/docker.sock:/var/run/docker.sock

2
front/cdn/axios.min.js vendored Executable file

File diff suppressed because one or more lines are too long

6
front/cdn/vue.min.js vendored Executable file

File diff suppressed because one or more lines are too long

71
front/css/index.css Executable file
View File

@ -0,0 +1,71 @@
html,body,#app,.el-container{
margin: 0px;
padding: 0px;
height: 100%;
}
.el-header {
background-color: #B3C0D1;
color: #333;
text-align: left;
line-height: 80px;
font-size: 30px;
font-weight: bold;
}
.el-footer {
background-color: #B3C0D1;
color: #333;
text-align: center;
line-height: 30px;
font-size: 12px;
}
.el-aside {
background-color: #D3DCE6;
color: #333;
text-align: center;
line-height: 200px;
}
.el-main {
background-color: #E9EEF3;
color: #333;
}
body > .el-container {
margin-bottom: 40px;
}
.el-container:nth-child(5) .el-aside,
.el-container:nth-child(6) .el-aside {
line-height: 260px;
}
.el-container:nth-child(7) .el-aside {
line-height: 320px;
}
.el-dialog .avatar-uploader .el-upload {
border: 1px dashed #d9d9d9;
border-radius: 6px;
cursor: pointer;
position: relative;
overflow: hidden;
}
.el-dialog .avatar-uploader .el-upload:hover {
border-color: #409EFF;
}
.el-dialog .avatar-uploader-icon {
font-size: 28px;
color: #8c939d;
width: 178px;
height: 178px;
line-height: 178px;
text-align: center;
}
.el-dialog .avatar {
width: 178px;
height: 178px;
display: block;
}

175
front/index.html Executable file
View File

@ -0,0 +1,175 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>学生信息管理系统</title>
<!-- 引入外部样式 -->
<link rel="stylesheet" href="./css/index.css">
<!-- 使用CDN引入 Vue 模块 -->
<!-- <script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script> -->
<script src="./cdn/vue.min.js"></script>
<!-- 使用CDN引入 Element UI 样式 -->
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
<!-- 使用CDN引入 Element UI 组件库 -->
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
<!-- 引入 Axios 组件库 -->
<!-- <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script> -->
<script src="./cdn/axios.min.js"></script>
</head>
<body>
<div id="app">
<el-container>
<el-header style="height: 80px;">学生信息管理系统</el-header>
<el-container>
<el-aside width="200px">
<el-menu default-active="2" class="el-menu-vertical-demo">
<el-menu-item index="1">
<i class="el-icon-menu"></i>
<span slot="title">班级管理</span>
</el-menu-item>
<el-menu-item index="2">
<i class="el-icon-user"></i>
<span slot="title">学生信息</span>
</el-menu-item>
<el-menu-item index="3">
<i class="el-icon-s-custom"></i>
<span slot="title">讲师信息</span>
</el-menu-item>
<el-menu-item index="4">
<i class="el-icon-date"></i>
<span slot="title">课程管理</span>
</el-menu-item>
</el-menu>
</el-aside>
<el-container>
<el-main>
<!-- 面包屑导航 -->
<el-breadcrumb separator-class="el-icon-arrow-right">
<el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item>
<el-breadcrumb-item>学生管理</el-breadcrumb-item>
</el-breadcrumb>
<!-- 表单 -->
<el-form :inline="true" style="margin-top: 20px;">
<el-row>
<el-col :span="12">
<el-form-item label="请输入查询的关键字:">
<el-input v-model="inputStr" placeholder="输入查询的关键字" style="width: 360px;"></el-input>
</el-form-item>
</el-col>
<el-col :span="8" style="text-align: right; padding-right: 40px;">
<el-button type="primary" icon="el-icon-search" @click="queryStudents()">查询</el-button>
<el-button type="primary" icon="el-icon-tickets" @click="getAllStudents()">全部</el-button>
<el-button type="primary" icon="el-icon-plus" @click="addStudent()">添加</el-button>
</el-col>
<el-col :span="2" style="text-align: right; padding-right: 10px;">
<el-upload :show-file-list="false" :http-request="uploadExcelPost">
<el-button type="primary" >导入Excel</el-button>
</el-upload>
</el-col>
<el-col :span="2">
<el-button type="primary" @click="exportToExcel()">导出Excel</el-button>
</el-col>
</el-row>
</el-form>
<!-- 表格 -->
<el-table :data="pageStudents" border style="width: 100%" @selection-change="handleSelectionChange">
<el-table-column :resizable="false" type="selection">
</el-table-column>
<el-table-column :resizable="false" type="index" label="序号" align="center" width="60">
</el-table-column>
<el-table-column :resizable="false" prop="sno" label="学号" align="center" width="120">
</el-table-column>
<el-table-column :resizable="false" prop="name" label="姓名" align="center" align="center" width="120">
</el-table-column>
<el-table-column :resizable="false" prop="gender" label="性别" align="center" width="60">
</el-table-column>
<el-table-column :resizable="false" prop="birthday" label="出生日期" align="center" width="120">
</el-table-column>
<el-table-column :resizable="false" prop="mobile" label="电话号码" align="center" width="160">
</el-table-column>
<el-table-column :resizable="false" prop="email" label="邮箱" align="center" width="300">
</el-table-column>
<el-table-column :resizable="false" prop="address" label="地址" align="center">
</el-table-column>
<el-table-column :resizable="false" label="操作" align="center" width="180">
<template slot-scope="scope">
<el-button type="success" icon="el-icon-more" size="mini" @click="viewStudent(scope.row)" circle>
</el-button>
<el-button type="primary" icon="el-icon-edit" size="mini" @click="updateStudent(scope.row)" circle>
</el-button>
<el-button type="danger" icon="el-icon-delete" size="mini" @click="deleteStudent(scope.row)" circle>
</el-button>
</template>
</el-table-column>
</el-table>
<!-- 分页 -->
<el-row style="margin-top: 20px;">
<el-col :span="8" style="text-align: left;">
<el-button type="danger" icon="el-icon-delete" size="mini" @click="deleteStudents">批量删除</el-button>
</el-col>
<el-col :span="16" style="text-align:right;">
<el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange"
:current-page="currentpage" :page-sizes="[5, 10, 50, 100]" :page-size="pagesize"
layout="total, sizes, prev, pager, next, jumper" :total="total">
</el-pagination>
</el-col>
</el-row>
<!-- 弹出框学生明细 -->
<el-dialog :title="dialogTitle" :visible.sync="dialogVisible" width="40%" :close-on-click-modal="false"
@close="closeDialogForm('studentForm')">
<el-form :model="studentForm" ref="studentForm" :rules="rules" :inline="true" style="margin-left: 24px;"
label-width="110px" label-position="right" size="mini">
<el-upload class="avatar-uploader"
:show-file-list="false" :http-request="uploadPicturePost" style=" text-align: center; margin: 20px;">
<img v-if="studentForm.image" :src="studentForm.imageUrl" class="avatar">
<i v-else class="el-icon-plus avatar-uploader-icon"></i>
</el-upload>
<el-form-item label="学号:" prop="sno">
<el-input v-model="studentForm.sno" :disabled="isView || isEdit" suffix-icon="el-icon-edit">
</el-input>
</el-form-item>
<el-form-item label="姓名:" prop="name">
<el-input v-model="studentForm.name" :disabled="isView" suffix-icon="el-icon-edit"></el-input>
</el-form-item>
<el-form-item label="性别:" prop="gender">
<el-select v-model="studentForm.gender" :disabled="isView" placeholder="请选择性别">
<el-option label="男" value="男"></el-option>
<el-option label="女" value="女"></el-option>
</el-select>
</el-form-item>
<el-form-item label="出生日期:" prop="birthday">
<el-date-picker v-model="studentForm.birthday" type="date" value-format="yyyy-MM-dd"
placeholder="选择日期" :disabled="isView" style="width: 93%;">
</el-date-picker>
</el-form-item>
<el-form-item label="手机号码:" prop="mobile">
<el-input v-model="studentForm.mobile" :disabled="isView" suffix-icon="el-icon-edit"></el-input>
</el-form-item>
<el-form-item label="邮箱地址:" prop="email">
<el-input v-model="studentForm.email" :disabled="isView" suffix-icon="el-icon-edit"></el-input>
</el-form-item>
<el-form-item label="家庭住址:" prop="address">
<el-input v-model="studentForm.address" :disabled="isView" suffix-icon="el-icon-edit"
style="width: 264%;"></el-input>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitStudentForm('studentForm')" v-show="!isView">确定</el-button>
<el-button type="info" @click="closeDialogForm('studentForm')">取消</el-button>
</span>
</el-dialog>
</el-main>
<el-footer style="height: 30px;">学生信息管理系统 版权所有: Hzbb | 2024-12-20 </el-footer>
</el-container>
</el-container>
</el-container>
</div>
</body>
</html>
<!-- 引入Vue代码 -->
<script src="js/index.js"></script>

531
front/js/index.js Executable file
View File

@ -0,0 +1,531 @@
const app = new Vue({
el: '#app',
data() {
// 校验学号是否存在
const rulesSno = (rule, value, callback) => {
if (this.isEdit) {
callback();
}
// 使用 Axios 进行校验
axios
.post(
this.baseURL + 'sno/check/',
{
sno: value,
}
)
.then((res) => {
if (res.data.code === 1) {
// 请求成功
if (res.data.exists) {
callback(new Error("学号已存在"));
} else {
callback();
};
} else {
// 请求失败
callback(new Error("校验学号后端出现异常"));
};
})
.catch((err) => {
// 如果请求失败在控制台打印
console.log(err);
})
}
return {
students: [], // 所有学生信息
pageStudents: [], // 分页后当前页的学生信息
// baseURL: "http://172.29.89.96/",
baseURL: window.location.origin + '/', // 动态获取请求的url
inputStr: '', // 输入查询的关键字
selectStudents: [], // 选择复选框时把选择记录存在此集合
// === 分页相关的变量 ===
total: 0, // 数据总行数
currentpage: 1, // 当前所在的页
pagesize: 10, // 每页显示多少行
// === 弹出框表单 ===
dialogVisible: false, // 默认为不弹出状态
dialogTitle: false, // 弹出框标题默认为空
isView: false, // 标识是否是查看
isEdit: false, // 标识是否是编辑
// 添加默认空集合
studentForm: {
sno: '',
name: '',
gender: '',
birthday: '',
mobile: '',
email: '',
address: '',
image: '',
imageUrl: '',
},
// 弹出框输入校验
rules: {
sno: [
{ required: true, message: "学号不能为空", trigger: 'blur' },
{ pattern: /^[9][5]\d{3}$/, message: "学号必须是95开头的五位数字", trigger: 'blur' },
{ validator: rulesSno, trigger: 'blur' },
],
name: [
{ required: true, message: "姓名不能为空", trigger: 'blur' },
{ pattern: /^[\u4e00-\u9fa5]{2,5}$/, message: "姓名必须是2-5个汉字", trigger: 'blur' },
],
gender: [
{ required: true, message: "性别不能为空", trigger: 'change' },
],
birthday: [
{ required: true, message: "出生日期不能为空", trigger: 'change' },
],
mobile: [
{ required: true, message: "电话号码不能为空", trigger: 'blur' },
{ pattern: /^((0\d{2,3}-\d{7,8})|(1[3456789]\d{9}))$/, message: "请检查电话号码是否输入正确", triggler: 'blur' },
],
email: [
{ required: true, message: "邮箱地址不能为空", trigger: 'blur' },
{
pattern: /^([a-zA-Z0-9]+[-_\.]?)+@[a-zA-Z0-9]+\.[a-z]+$/,
message: "请检查邮箱地址是否输入正确", trigger: 'blur'
},
],
address: [
{ required: true, message: "家庭住址不能为空", trigger: 'blur' },
]
},
}
},
mounted() {
// 自动加载数据
this.getStudents();
},
// 事件
methods: {
// 获取所有学生的信息
getStudents: function () {
// 记录 this 的地址
let that = this
// 使用 Axios 实现 Ajax 请求
axios
.get(that.baseURL + "students/")
.then(function (res) {
// 请求成功后执行的函数
if (res.data.code == 1) {
// 数据返回给 students
that.students = res.data.data;
// 获取返回记录的总行数
that.total = res.data.data.length;
// 获取当前页的数据
that.getPageStudents();
// 弹窗提示
that.$message({
message: '数据加载成功!',
type: 'success'
});
console.log(that.students);
} else {
that.$message.error(res.data.msg);
}
})
.catch(function (err) {
// 请求失败后执行的函数
console.log(err)
});
},
// 清除输入内容获取所有学生信息
getAllStudents() {
this.inputStr = "";
this.getStudents();
},
// 获取当前页的学生数据
getPageStudents() {
// 清空 pageStudents 中的数据
this.pageStudents = [];
// 获取当前页的数据
for (let i = (this.currentpage - 1) * this.pagesize; i < this.total; i++) {
// 遍历数据添加到 pageStudents 中
this.pageStudents.push(this.students[i]);
// 判断是否达到一页的要求
if (this.pageStudents.length === this.pagesize) break;
}
},
// 实现学生信息查询
queryStudents() {
// 使用Ajax请求 -- POST --> 传递 InputStr
let that = this
axios
.post(
that.baseURL + "students/query/",
{
inputstr: that.inputStr
}
)
.then(function (res) {
if (res.data.code === 1) {
// 数据返回给 students
that.students = res.data.data;
// 获取返回记录的总行数
that.total = res.data.data.length;
// 获取当前页的数据
that.getPageStudents();
// 弹窗提示
that.$message({
message: '数据加载成功!',
type: 'success'
});
} else {
that.$message.error(res.data.msg);
}
})
.catch(function (err) {
console.log(err)
that.$message.error("获取后端查询结果出现异常!");
});
},
// 添加学生信息明细弹出框
addStudent() {
// 修改弹出框标题
this.dialogTitle = "添加学生明细";
// 弹出表单
this.dialogVisible = true;
},
// 根据 id 获取 image
getImageBySno(sno) {
for(oneStudent of this.students) {
// 判断
if(oneStudent.sno == sno) {
return oneStudent.image;
}
}
},
// 查看学生信息明细弹出框
viewStudent(row) {
// 修改弹出框标题
this.dialogTitle = "查看学生明细";
// 修改 isView 变量
this.isView = true;
// 弹出表单
this.dialogVisible = true;
// 深拷贝方法:
this.studentForm = JSON.parse(JSON.stringify(row));
// 获取照片
this.studentForm.image = this.getImageBySno(row.sno);
// 获取照片url
this.studentForm.imageUrl = this.baseURL + 'media/' + this.studentForm.image;
},
// 编辑学生详细信息弹出框
updateStudent(row) {
// 修改弹出框标题
this.dialogTitle = "编辑学生明细";
// 修改 isEdit 变量
this.isEdit = true;
// 弹出表单
this.dialogVisible = true;
// 深拷贝方法:
this.studentForm = JSON.parse(JSON.stringify(row));
// 获取照片
this.studentForm.image = this.getImageBySno(row.sno);
// 获取照片url
this.studentForm.imageUrl = this.baseURL + 'media/' + this.studentForm.image;
},
// 提交学生的表单(添加、编辑)
submitStudentForm(formName) {
this.$refs[formName].validate((valid) => {
if (valid) {
// 判断提交表单事件类型,添加 or 编辑
if (this.isEdit) {
// 修改事件
this.submitUpdateStudent();
} else {
// 添加事件
this.submitAddStudent();
}
} else {
console.log('error submit!!');
return false;
}
});
},
// 添加学生信息到数据库
submitAddStudent() {
// 定义 that
let that = this;
// 执行 Axios 请求
axios
.post(that.baseURL + 'student/add/', that.studentForm)
.then(res => {
// 执行成功
if (res.data.code === 1) {
// 获取所有学生信息
that.students = res.data.data;
// 获取记录条数
that.total = res.data.data.length;
// 获取分页信息
that.getPageStudents();
// 弹窗提示
that.$message({
message: '数据添加成功!',
type: 'success'
});
// 关闭弹窗
that.closeDialogForm('studentForm');
} else {
that.$message.error(res.data.msg);
}
})
.catch(err => {
// 执行失败
console.log(err)
that.$message.error("添加时获取后端查询结果出现异常!");
})
},
// 编辑学生信息到数据库
submitUpdateStudent() {
// 定义 that
let that = this;
// 执行 Axios 请求
axios
.post(that.baseURL + 'student/update/', that.studentForm)
.then(res => {
// 执行成功
if (res.data.code === 1) {
// 获取所有学生信息
that.students = res.data.data;
// 获取记录条数
that.total = res.data.data.length;
// 获取分页信息
that.getPageStudents();
// 弹窗提示
that.$message({
message: '数据修改成功!',
type: 'success'
});
// 关闭弹窗
that.closeDialogForm('studentForm');
} else {
that.$message.error(res.data.msg);
}
})
.catch(err => {
// 执行失败
console.log(err)
that.$message.error("修改时获取后端查询结果出现异常!");
})
},
// 删除学生信息到数据库
deleteStudent(row) {
// 等待确认
this.$confirm('是否确认删除学生信息【学号:' + row.sno + '\t姓名' + row.name + '】?', '提示', {
confirmButtonText: '确定删除',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
// 确认删除相应事件
let that = this
// 调用后端接口
axios
.post(that.baseURL + 'student/delete/', { sno: row.sno })
.then(res => {
if (res.data.code === 1) {
// 获取所有学生信息
that.students = res.data.data;
// 获取记录数
that.total = res.data.data.length;
// 获取分页信息
that.getPageStudents();
// 弹窗提示
that.$message({
message: '数据删除成功!',
type: 'success'
});
} else {
that.$message.error(res.data.msg);
}
})
}).catch(() => {
this.$message({
type: 'info',
message: '已取消删除'
});
});
},
// 批量删除学生信息到数据库
deleteStudents() {
// 等待确认
this.$confirm("是否确认批量删除 " + this.selectStudents.length + " 名学生信息?", '提示', {
confirmButtonText: '确定删除',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
// 确认删除相应事件
let that = this
// 调用后端接口
axios
.post(that.baseURL + 'students/delete/', { student: that.selectStudents })
.then(res => {
if (res.data.code === 1) {
// 获取所有学生信息
that.students = res.data.data;
// 获取记录数
that.total = res.data.data.length;
// 获取分页信息
that.getPageStudents();
// 弹窗提示
that.$message({
message: '数据批量删除成功!',
type: 'success'
});
} else {
that.$message.error(res.data.msg);
}
})
}).catch(() => {
this.$message({
type: 'info',
message: '已取消删除'
});
});
},
// 关闭弹出框的表单
closeDialogForm(formName) {
// 重置表单校验
this.$refs[formName].resetFields();
// 清空弹出框集合
this.studentForm.sno = '';
this.studentForm.name = '';
this.studentForm.gender = '';
this.studentForm.birthday = '';
this.studentForm.mobile = '';
this.studentForm.email = '';
this.studentForm.address = '';
this.studentForm.image = '';
this.studentForm.imageUrl = '';
// 关闭弹出框
this.dialogVisible = false;
// 清空 isView 和 isEdit 的值
this.isView = false;
this.isEdit = false;
},
//选择学生头像后点击确定后触发的事件
uploadPicturePost(file) {
//定义that
let that = this;
//定义一个FormData类
let fileReq = new FormData();
//把照片穿进去
fileReq.append('avatar', file.file);
//使用Axios发起Ajax请求
axios(
{
method: 'post',
url: that.baseURL + 'upload/',
data: fileReq
}
).then(res => {
// 根据code判断是否成功
if (res.data.code === 1) {
//把照片给image
that.studentForm.image = res.data.name;
//拼接imageurl
that.studentForm.imageUrl = that.baseURL + "media/" + res.data.name;
} else {
//失败的提示!
that.$message.error(res.data.msg);
}
}).catch(err => {
console.log(err);
that.$message.error("上传头像出现异常!");
})
},
// excel文件导入
uploadExcelPost(file) {
let that = this
//实例化一个formdata
//定义一个FormData类
let fileReq = new FormData();
//把照片穿进去
fileReq.append('excel', file.file);
//使用Axios发起Ajax请求
axios(
{
method: 'post',
url: that.baseURL + 'excel/import/',
data: fileReq
}
).then(res => {
// 根据code判断是否成功
if (res.data.code === 1) {
//把照片给image
that.students = res.data.data;
//计算总共多少条
that.total = res.data.data.length;
//分页
that.getPageStudents();
//弹出框体显示结果
this.$alert('本次导入完成! 成功:' + res.data.success +'失败:'+ res.data.error
, '导入结果展示', {
confirmButtonText: '确定',
callback: action => {
this.$message({
type: 'info',
message: "本次导入失败数量为:" + res.data.error + ",具体的学号:"+res.data.errors,
});
}
});
//把失败明细打印
console.log("本次导入失败数量为:" + res.data.error + ",具体的学号:");
console.log(res.data.errors);
} else {
//失败的提示!
that.$message.error(res.data.msg);
}
}).catch(err => {
console.log(err);
that.$message.error("上传Excel出现异常");
})
},
// excel文件导出
exportToExcel(){
let that = this
axios.get(that.baseURL + 'excel/export/')
.then(res=>{
if(res.data.code ===1){
//拼接excel 的完整URL
let url = that.baseURL + 'media/'+ res.data.name;
//下载
window.open(url);
} else {
that.$message.error("导出Excel出现异常");
}
})
.catch(err=>{
console.log(err);
});
},
// 分页时修改每页的行数
handleSizeChange(size) {
// 修改当前每页的数据行数
this.pagesize = size;
// 数据重新分页
this.getPageStudents();
},
// 调整当前的页码
handleCurrentChange(pageNumber) {
// 修改当前的页码
this.currentpage = pageNumber;
// 数据重新分页
this.getPageStudents();
},
// 选择复选框时触发的操作
handleSelectionChange(data) {
this.selectStudents = data;
console.log(data);
},
},
})

15
manage.py Executable file
View File

@ -0,0 +1,15 @@
#!/usr/bin/env python
import os
import sys
if __name__ == '__main__':
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'simsV4BE.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)

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 391 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 132 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 391 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 391 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 391 KiB

Binary file not shown.

Binary file not shown.

4
module/requirements.txt Executable file
View File

@ -0,0 +1,4 @@
django==2.1.4
pymysql==0.9.3
django-cors-headers==3.2.0
openpyxl==2.6.2

10
module/run.sh Executable file
View File

@ -0,0 +1,10 @@
#!/bin/bash
# 使用阿里云源安装必须组件
#pip config set global.index-url https://mirrors.aliyun.com/pypi/simple && \
#pip config set global.trusted-host mirrors.aliyun.com && \
#pip install -r /module/requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple
pip install -r /module/requirements.txt -i https://mirrors.aliyun.com/pypi/simple/ --trusted-host mirrors.aliyun.com
# 启动程序
python /simsBE/manage.py runserver 0.0.0.0:8000

9
module/run.sh_bak Normal file
View File

@ -0,0 +1,9 @@
#!/bin/bash
# 使用阿里云源安装必须组件
pip config set global.index-url https://mirrors.aliyun.com/pypi/simple && \
pip config set global.trusted-host mirrors.aliyun.com && \
pip install -r /module/requirements.txt
# 启动程序
python /simsBE/manage.py runserver 0.0.0.0:8000

79
nginx/conf.d/default.conf Executable file
View File

@ -0,0 +1,79 @@
server {
listen 80;
listen [::]:80;
server_name localhost;
location / {
root /simsFE;
index index.html index.htm;
}
location /student/ {
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header X-Nginx-Proxy true;
proxy_set_header Host $host:$server_port;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://simsbe:8000/student/;
}
location /students/ {
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header X-Nginx-Proxy true;
proxy_set_header Host $host:$server_port;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://simsbe:8000/students/;
}
location /sno/ {
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header X-Nginx-Proxy true;
proxy_set_header Host $host:$server_port;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://simsbe:8000/sno/;
}
location /upload/ {
client_max_body_size 20m; # 设置上传文件的最大大小为 20MB
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header X-Nginx-Proxy true;
proxy_set_header Host $host:$server_port;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://simsbe:8000/upload/;
}
location /media/ {
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header X-Nginx-Proxy true;
proxy_set_header Host $host:$server_port;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://simsbe:8000/media/;
}
location /excel/ {
client_max_body_size 20m; # 设置上传文件的最大大小为 20MB
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header X-Nginx-Proxy true;
proxy_set_header Host $host:$server_port;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://simsbe:8000/excel/;
}
}

50
nginx/nginx.conf Executable file
View File

@ -0,0 +1,50 @@
user nginx;
worker_processes 2;
error_log /var/log/nginx/error.log notice;
pid /var/run/nginx.pid;
events {
worker_connections 10240;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
# 文件快速传输
sendfile on;
#tcp_nopush on;
server_tokens off;
keepalive_timeout 65;
gzip on;
#不压缩临界值大于4K的才压缩
gzip_min_length 4k;
gzip_buffers 4 16k;
#用了反向代理的话末端通信是HTTP/1.0,默认是HTTP/1.1
#gzip_http_version 1.0;
#压缩级别1-10数字越大压缩的越好时间也越长
gzip_comp_level 6;
#进行压缩的文件类型,
gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;
gzip_vary off;
gzip_disable "MSIE [1-6]\.";
# 过滤代理自身IP
real_ip_header proxy_protocol;
set_real_ip_from 172.16.0.0/12;
set_real_ip_from 10.100.0.1;
real_ip_recursive on;
include /etc/nginx/conf.d/*.conf;
}

0
simsV4BE/__init__.py Executable file
View File

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

146
simsV4BE/settings.py Executable file
View File

@ -0,0 +1,146 @@
"""
Django settings for simsV4BE project.
Generated by 'django-admin startproject' using Django 2.1.4.
For more information on this file, see
https://docs.djangoproject.com/en/2.1/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/2.1/ref/settings/
"""
import os, sys
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.insert(0, os.path.join(BASE_DIR, 'apps'))
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/2.1/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = '+*#94$=jxxnz6vqju=^mj9fmd7gwcz81q(u*1(z5j_#7ahmy6s'
# 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',
'sims',
'corsheaders',
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'corsheaders.middleware.CorsMiddleware',
#'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
ROOT_URLCONF = 'simsV4BE.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [BASE_DIR, '/templates']
,
'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 = 'simsV4BE.wsgi.application'
# Database
# https://docs.djangoproject.com/en/2.1/ref/settings/#databases
#DATABASES = {
# 'default': {
# 'ENGINE': 'django.db.backends.sqlite3',
# 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
# }
#}
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'sims',
'USER': 'root',
'PASSWORD': 'admin@123456',
'HOST': 'simsdb',
'PORT': '3306',
}
}
# Password validation
# https://docs.djangoproject.com/en/2.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/2.1/topics/i18n/
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/2.1/howto/static-files/
STATIC_URL = '/static/'
# 设置上传文件目录和外部访问路径
MEDIA_ROOT = os.path.join(BASE_DIR, 'media/')
MEDIA_URL = '/media/'
CORS_ALLOWED_ORIGINS = {
"https://example.com",
"https://sub.example.com",
"http://localhost:8080",
"http://127.0.0.1:9000",
}

38
simsV4BE/urls.py Executable file
View File

@ -0,0 +1,38 @@
"""simsV4BE URL Configuration
The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/2.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
from sims import views
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
path('admin/', admin.site.urls),
path('students/', views.get_students), # 获取所有学生信息的接口
path('students/query/', views.query_students), # 查询学生信息的接口
path('sno/check/', views.is_exists_sno), # 校验学号是否已存在
path('student/add/', views.add_student), # 添加学生信息的接口
path('student/update/', views.update_student), # 修改学生信息的接口
path('student/delete/', views.delete_student), # 删除学生信息的接口
path('students/delete/', views.delete_students), # 批量删除学生信息的接口
path('upload/', views.upload), # 上传文件接口
path('excel/import/', views.import_students_excel), # 导入excel文件
path('excel/export/', views.export_students_excel) # 导出excel文件
]
# 允许所有的media文件被访问
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

16
simsV4BE/wsgi.py Executable file
View File

@ -0,0 +1,16 @@
"""
WSGI config for simsV4BE 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/2.1/howto/deployment/wsgi/
"""
import os
from django.core.wsgi import get_wsgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'simsV4BE.settings')
application = get_wsgi_application()