02 选课系统

一. README.md

本周作业:综合应用面向对象
角色:学校、学员、课程、讲师
要求:
    1. 创建北京、上海 2 所学校
    2. 创建linux , python , go 3个课程 , linux\py 在北京开, go 在上海开
    3. 课程包含,周期,价格,通过学校创建课程
    4. 通过学校创建课程, 课程关联学校
        4.1 创建学员时,选择学校,关联课程
        4.2 创建讲师角色
    5. 提供三个角色接口
        5.1 学员视图, 可以注册, 交学费, 选择课程,
        5.2 讲师视图, 讲师可管理自己的课程, 上课时选择班级, 查看课程学员列表,修改所管理的学员的成绩
        5.3 管理视图,创建讲师, 创建班级,创建课程
    6. 上面的操作产生的数据都通过pickle序列化保存到文件里
    
    
1. 需求分析
    - 管理员功能
        - 注册
        - 登录
        - 创建学校
        - 创建课程(先选择校区. 再创建课程, 并将课程绑定到选择的校区)
        - 创建讲师(老师名,老师密码默认密码为123)
    - 学生功能
        - 注册
        - 登录
        - 选择校区
        - 选择课程(先选择校区, 再选择校区中的某一门课程)
            - 学生选择课程, 学生可以修多门课程, 选择课程对选择的课程进行标识. 
                - {"课程": False, "课程1": False}. 只有在交费以后学生才能看到交费后的课程成绩.
        - 查看余额
        - 充值金额             
        - 交学费
            - 交费以后修改交费课程对应的课程标识
                - {"课程": True}
            - 交费以后学生当前校区下的课程添加该学生(某一校区下的某一门课程包含多个来选择的学生          )
        - 查看成绩
    - 老师功能
        - 登录
        - 查看授课课程
        - 选择授课课程(先选择校区, 再选择校区下开设的课程)
        - 查看授课课程下学生(先查看授课课程, 并选择相应课程, 拿到课程下对应的学生)
        - 修改授课课程下学生分数(先查看授课课程, 并选择相应课程, 拿到课程下对应的学生, 再进行修改分数)
2. 程序的架构设计
    - ATM + 购物车
        - 用户视图层: 与用户交互
        - 逻辑接口层: 核型的业务逻辑
        - 数据处理层: 针对数据的增删改查
            - json格式的数据
                - '{"key": "value"}' 类型的数据
            - python
                - 字典格式: --> {'key': 'value'}
                
    - 选课系统
        - 三层架构
            - 用户视图层: 
                - 与用户交互
                - core
                    - main.py  主视图
                    - admin.py
                        admin_view
                    - teacher.py
                        teacher_view
                    - student.py
                        student.view
            - 逻辑接口层: 
               - 核心的业务逻辑的处理
               - interface
                    - admin_interface.py
                    - teacher_interface.py
                    - student_interface.py
            - 数据处理层: 
                - 争对数据的 增 删 查 改
                - models.py
                    - 用于存放所有类, 管理所有类
                    - Base
                        - save(self):
                            db_handler.save(self)
                            
                          @classmethod
                        - select(cls, user):
                            return db_handler.select(cls, user)
                    - Admin(Base)   
                        - __init__(self, admin_name, password):
                            self.user = admin_name
                            self.password = password
                            self.save()
                            
                          @classmethod
                        - create_school(addr):
                            School(addr)
                            
                          @classmethod
                        - create_course(school_obj, course_name, course_period, course_price):
                          Course(course_name, course_period, course_price)
                          school_obj.course_list.append(course_name)
                          school_obj.save()
                        
                          @classmethod
                        - create_teacher(teacher_name, password):
                          Teacher(teacher_name, password)
                          
                    - School(Base)
                        - __init__(self, addr):
                          self.user = addr
                          self.course_list = []
                          self.save()
                          
                    - Course(Base)
                        - __init__(self, course_name, course_period, course_price):
                          self.user = course_name
                          self.period = course_period
                          self.price = course_price
                          self.student_list = []
                          self.save()
                          
                    - Student(Base)
                        - __init__(self, student_name, password):
                          self.user = student_name
                          self.password = password
                          self.balance = 0
                          self.course_dic = {}
                          self.score = {}
                          self.save()
                          
                    - Teacher(Base)
                        - __init__(self, teacher_name, password):
                          self.user = teacher_name
                          self.password = password
                          self.course_list = []
                          self.save()
                    
                - db_handler.py
                    - save(self): # 保存对象
                        - 拼接文件夹, 获取对象的类名充当文件夹管理文件
                            class_name = obj.__class__.__name__
                        - 再拼接文件, 然后把对象通过pickle序列化到文件中
                    - select(cls, user): # 获取对象
                        - 拼接文件夹, 获取类名充当文件夹管理文件
                            class_name = cls.__name__
                        - 再拼接文件, 然后把通过pickle反序列文件取出文件中的对象
                        
                    - ATM + 购物车 
                        - 存放json格式的数据
                        - python数据类型 <-> json <-> 文件
                    
                    - 选课系统
                        - pickle保存对象
                        - 对象 <-> pickle <-> 文件  
3. 分任务开发
4. 测试
5. 上线运行

二. 流程图

二. 项目架构

course_selection_system/     

├── start.py (提示: 这里的start.py有两种放置的方法,一种是放到bin目录下。一种放到course_selection_system这个文件夹下面。放到course_selection_system这个文件夹下面。好处是不需要在当前文件中处理添加环境变量的问题, 也就是当我们调用别的目录下的模块功能的时候不会发生找不到到模块路径的问题。)


├── conf  
    └── settings.py                

├── core                 
│   ├── common_main.py
│   ├── main.py
│   ├── teacher.py
│   ├── student.py
    └── admin.py

├── db                 
│   ├── models.py
    └── db_handler.py

├── interface                 
│   ├── common_interface.py
│   ├── admin_interface.py
│   ├── student_interface.py
    └── teacher_interface.py

├── lib  
    └── common.py               

├── log               

├── README.md

四. conf

1. settings.py

import os

def base_path(*paths):
    return os.path.normpath(os.path.join(__file__, '..', '..', *paths))


DB_DIR_PATH = base_path('db')


# %(name)s             Logger的名字
# %(levelno)s          数字形式的日志级别(10, 20, 30, 40, 50)
# %(levelname)s        文本形式的日志级别(debug调试, info信息, warning警告, error错误, critical危险)
# %(pathname)s         调用日志输出函数的模块的完整路径名,可能没有
# %(filename)s         调用日志输出函数的模块的文件名
# %(module)s           调用日志输出函数的模块名
# %(funcName)s         调用日志输出函数的函数名
# %(lineno)d           调用日志输出函数的语句所在的代码行
# %(created)f          当前时间,用UNIX标准的表示时间的浮 点数表示
# %(relativeCreated)d  输出日志信息时的,自Logger创建以 来的毫秒数
# %(asctime)s          字符串形式的当前时间。默认格式是 “2003-07-08 16:49:45,896”。逗号后面的是毫秒
# %(thread)d           线程ID。可能没有
# %(threadName)s       线程名。可能没有
# %(process)d          进程ID。可能没有
# %(message)s          用户输出的消息
standard_format = '[%(asctime)s][%(threadName)s:%(thread)d][task_id:%(name)s][%(filename)s:%(lineno)d]' \
                  '[%(levelname)s][%(message)s]'

simple_format = '[%(levelname)s][%(asctime)s][%(filename)s:%(lineno)d][%(message)s]'

test_format = '%(asctime)s][%(message)s]'

# 3、日志配置字典
LOGGING_DIC = {
    # version 指定的是你的版本信息。
    'version': 1,

    # disable_existing_loggers 关闭已存在日志。默认False
    'disable_existing_loggers': False,

    # formatters 加s代表可以设置很多个不同的日志格式。(注意: 这个不能改,这个是固定的。)
    'formatters': {

        # standard, simple, test 通过自定义的这些名字拿到下面自定义的日志格式的表现形式(自定义的日志格式可以修改)。
        'standard': {
            # format (注意: 这个不能改,这是固定的格式。)  # standard_format 这里可以指定你自定义的日志格式表现的形式。
            'format': standard_format
        },
        'simple': {
            'format': simple_format
        },
        'test': {
            'format': test_format
        },
    },
    'filters': {},

    # handlers 它是日志的接收者, 它用于控制日志的输出位置。
    'handlers': {
        # console, default, other 这是你自定义的handler

        # 输出位置: 打印到终端的日志
        'console': {
            'level': 10,
            'class': 'logging.StreamHandler',  # class 指定日志输出的形式。(注意不能改。)打印到屏幕
            'formatter': 'simple'  # formatter 指定日志格式输出的形式, 会跑到上面formatters找到你之前所定义的格式simple。
        },
        # 输出位置: 打印到文件的日志,收集info及以上的日志
        'default': {
            'level': 'DEBUG',
            'class': 'logging.handlers.RotatingFileHandler',  # RotatingFileHandler 指定日志轮转。
            'formatter': 'standard',
            # 可以定制日志文件路径
            # BASE_DIR = os.path.dirname(os.path.abspath(__file__))  # log文件的目录
            # LOG_PATH = os.path.join(BASE_DIR,'a1.log')
            'filename': base_path('log', 'access.log'),  # 日志文件
            'maxBytes': 1024 * 1024 * 5,  # 默认单位是字节Bytes。日志大小 5M
            'backupCount': 5,  # backupCount 指的是最多给你保存几份。
            'encoding': 'utf-8',  # 日志文件的编码,再也不用担心中文log乱码了
        },
    },

    # loggers 它是日志的产生者, 负责产生不同级别的日志, 产生的日志会传递给handlers, 让handlers控制输出的位置。
    'loggers': {

        # logger
        # '' 执行logging.getLogger(key)时会判断,如果指定的key在下面的这些"logger"中都没找到, 就会把自定义key

        # logging.getLogger(__name__)拿到的logger配置
        '': {
            'handlers': ['default', 'console'],
            # handlers 这里指定你要交给的Handler路径, 交给"default"和"console"之前定义的日志handler.  这里把上面定义的两个handler都加上,即log数据既写入文件又打印到屏幕

            # 这里又设置了日志级别,而handler中又设置了日志级别,这里有两层关卡。当使用log_obj.info()等输入内容的时候. 会进行判断。如果日志级别满足,那么就会被收取到。满足以后会交给handlers中你自定义的"handler"来进行第二次筛选, 如果又满足,那么就会被你相应的"handler"功能, 进行处理。
            'level': 'DEBUG',  # loggers(第一层日志级别关限制)--->handlers(第二层日志级别关卡限制)
            'propagate': False,  # 默认为True,向上(更高level的logger)传递,通常设置为False即可,否则会一份日志向上层层传递
        },
    },
}

五. core

1. common_main.py

from interface import commom_interface


def choose_campus():
    flag, campus_list = commom_interface.get_all_campus_interface()
    if not flag:
        print(campus_list)
        return

    for index, campus in enumerate(campus_list):
        print(f"编号:{index}  校区:{campus}")
    choice = input("[返回上一层: B/b]请输入编号选择相应的校区地址: ").strip()
    if choice.lower() == 'b':
        return
    if choice not in map(lambda i: str(i), range(len(campus_list))):
        print("对不起, 输入范围有误!")
        return False
    choice = int(choice)
    campus = campus_list[choice]
    return campus


def choose_course_off_campus(campus):
    flag, course_list = commom_interface.get_course_off_campus_interface(campus)
    if not flag:
        print(course_list)
        return
    for index, course_name in enumerate(course_list):
        print(f"编号:{index}  课程名:{course_name}")
    choice = input("[返回上一层: B/b]请根据编号选择相应的课程: ").strip()
    if choice.lower() == 'b':
        return
    if choice not in map(lambda i: str(i), range(len(course_list))):
        print("对不起, 输入范围有误!")
        return False
    choice = int(choice)
    course_name = course_list[choice]
    return course_name

2. main.py

"""
- 管理员功能

- 学生功能

- 老师功能
"""

from .teacher import teacher_view
from .student import student_view
from .admin import admin_view
func_dic = {
    '1': admin_view,
    '2': student_view,
    '3': teacher_view,
}


def run():
    while True:
        print("""
        ========= 欢迎来到选课系统 =========
                1. 管理员视图
                2. 学生视图
                3. 老师视图
        ============ end =================               
        """)
        cmd = input('[退出: Q/q]请输入输入功能编号: ').strip()
        if cmd.lower() == 'q':
            break
        if cmd not in func_dic:
            print("对不起, 输入有误!")
            continue
        func_dic[cmd]()

3. teacher.py

"""
- 登录
- 查看授课课程
- 选择授课课程
- 查看授课课程下学生
- 修改授课课程下学生分数
"""
from lib import common
from interface import commom_interface
from interface import teacher_interface
from . import common_main

teacher_login = None
func_dic = {}


@common.function_dic(func_dic, '登录')
def login():
    username = input("please input your username: ").strip()
    password = input("please input your password: ").strip()
    # flag, msg = commom_interface.login_interface(username, password, user_type='teacher')
    flag, msg = commom_interface.login_interface(username, password, user_type='Teacher')
    if flag:
        global teacher_login
        teacher_login = username
    print(msg)


@common.function_dic(func_dic, '查看授课课程')
@common.auth('teacher')
def check_teach_course():
    flag, course_list = teacher_interface.check_teach_course_interface(teacher_login)
    if flag:
        for index, course_name in enumerate(course_list):
            print(f"编号:{index}  教授课程:{course_name}")
        return course_list
    else:
        print(course_list)


@common.function_dic(func_dic, '选择授课课程')
@common.auth('teacher')
def choose_teach_course():
    while True:
        campus = common_main.choose_campus()
        if campus is None:
            break
        elif campus is False:
            continue

        course_name = common_main.choose_course_off_campus(campus)
        if course_name is None:
            break
        elif course_name is False:
            continue

        msg = teacher_interface.add_teach_course_interface(teacher_login, course_name)
        print(msg)


@common.function_dic(func_dic, '查看课程下学生')
@common.auth('teacher')
def check_course_student():
    while True:
        course_list = check_teach_course()
        if not course_list:
            break
        choice = input('[返回上一层: B/b]请根据编号选择相应教授课程下的学生: ').strip()
        if choice.lower() == 'b':
            break
        if choice not in map(lambda i: str(i), range(len(course_list))):
            print("对不起, 输入范围有误!")
            continue
        choice = int(choice)
        course_name = course_list[choice]

        flag, student_list = teacher_interface.check_course_student_interface(teacher_login, course_name)
        if flag:
            for index, student_name in enumerate(student_list):
                print(f'编号:{index}  学生:{student_name}')
            return course_name, student_list
        else:
            print(student_list)


@common.function_dic(func_dic, '修改学生分数')
@common.auth('teacher')
def modify_score():
    while True:
        res = check_course_student()
        if not res:
            return
        course_name, student_list = res
        choice = input("请根据编号选择要修改成绩的学生: ").strip()
        if choice not in map(lambda i: str(i), range(len(student_list))):
            print("对不起, 输入范围有误!")
            continue
        choice = int(choice)
        student_name = student_list[choice]

        score = input("请输入修改的成绩: ").strip()
        if not score.isdigit():
            print("对不起, 请输入数字!")
            continue
        score = int(score)
        if score > 100 or score < 0:
            print("对不起, 修改成绩范围0~100之间")
            continue
        msg = teacher_interface.modify_score_interface(teacher_login, course_name, student_name, score)
        print(msg)


def teacher_view():
    common.execute_func_view(func_dic)

4. student.py

"""
- 注册
- 登录
- 选择校区
- 选择课程(先选择校区, 再选择校区中的某一门课程)
    - 学生选择课程, 学生可以修多门课程, 选择课程对选择的课程进行标识.
        - {"课程": False, "课程1": False}. 只有在交费以后学生才能看到交费后的课程成绩.
- 查看余额
- 充值金额
- 交学费
    - 交费以后修改交费课程对应的课程标识
        - {"课程": True}
    - 交费以后学生当前校区下的课程添加该学生(某一校区下的某一门课程包含多个来选择的学生          )
- 查看成绩
"""

from lib import common
from interface import commom_interface
from interface import student_interface
from . import common_main

student_login = None
func_dic = {}


@common.function_dic(func_dic, '注册')
def register():
    username = input("please input your username: ").strip()
    password = input("please input your password: ").strip()
    re_password = input("please again confirm your password: ").strip()
    if not all([username, password, re_password]):
        print("对不起, 以上输入内容不能有空!")
        return
    if password == re_password:
        msg = student_interface.register_interface(username, password)
        print(msg)
    else:
        print("对不起, 2次密码不一致!")


@common.function_dic(func_dic, '登录')
def login():
    username = input("please input your username: ").strip()
    password = input("please input your password: ").strip()
    # flag, msg = commom_interface.login_interface(username, password, user_type='student')
    flag, msg = commom_interface.login_interface(username, password, user_type='Student')
    if flag:
        global student_login
        student_login = username
    print(msg)


@common.function_dic(func_dic, '选择校区')
@common.auth('student')
def choose_campus():
    while True:
        campus = common_main.choose_campus()
        if campus is None:
            break
        elif campus is False:
            continue
        flag, msg = student_interface.add_campus_interface(student_login, campus)
        print(msg)
        if flag:
            break


@common.function_dic(func_dic, '选择课程')
@common.auth('student')
def choose_course():
    while True:
        flag, campus = student_interface.get_campus_interface(student_login)
        if not flag:
            print(campus)
            return

        course_name = common_main.choose_course_off_campus(campus)
        if course_name is None:
            break
        elif course_name is False:
            continue
        msg = student_interface.add_course_interface(student_login, course_name)
        print(msg)


@common.function_dic(func_dic, '查看余额')
@common.auth('student')
def check_balance():
    balance = student_interface.check_balance_interface(student_login)
    print(f"用户:{student_login} 当前余额:{balance}元")


@common.function_dic(func_dic, '充值金额')
@common.auth('student')
def recharge_balance():
    add_balance = input('请输入充值额度: ').strip()
    if not add_balance.isdigit():
        print("对不起, 请输入数字!")
        return
    msg = student_interface.recharge_balance_interface(student_login, add_balance)
    print(msg)


@common.function_dic(func_dic, '交学费')
@common.auth('student')
def pay_tuiton():
    while True:
        flag, course_list = student_interface.get_unpaid_tuition_course(student_login)
        if not flag:
            print(course_list)
            break

        for index, course_name in enumerate(course_list):
            print(f'编号:{index} 待支付课程:{course_name}')
        choice = input("[返回上一层: B/b]请根据编号选择支付相应课程: ").strip()
        if choice.lower() == 'b':
            break
        if choice not in map(lambda i: str(i), range(len(course_list))):
            print("对不起, 输入范围有误!")
            continue
        choice = int(choice)
        course_name = course_list[choice]
        msg = student_interface.pay_tuition_interface(student_login, course_name)
        print(msg)


@common.function_dic(func_dic, '查看成绩')
@common.auth('student')
def check_score():
    flag, score_dic = student_interface.check_score_interface(student_login)
    if flag:
        for course_name, score in score_dic.items():
            print(f'课程:{course_name}  成绩:{score}分')
    else:
        print(score_dic)


def student_view():
    common.execute_func_view(func_dic)

5. admin.py

"""
- 注册
- 登录
- 创建学校
- 创建课程(先选择校区. 再创建课程, 并将课程绑定到选择的校区)
- 创建讲师(老师名,老师密码默认密码为123)
"""
from lib import common
from interface import commom_interface
from interface import admin_interface
from . import common_main

admin_login = None
func_dic = {}


@common.function_dic(func_dic, '注册')
def register():
    username = input("please input your username: ").strip()
    password = input("please input your password: ").strip()
    re_password = input("please again confirm your password: ").strip()
    if not all([username, password, re_password]):
        print("对不起, 以上输入内容不能有空!")
        return
    if password == re_password:
        msg = admin_interface.register_interface(username, password)
        print(msg)
    else:
        print("对不起, 2次密码不一致!")


@common.function_dic(func_dic, '登录')
def login():
    username = input("please input your username: ").strip()
    password = input("please input your password: ").strip()
    # flag, msg = commom_interface.login_interface(username, password, user_type='admin')
    flag, msg = commom_interface.login_interface(username, password, user_type='Admin')
    if flag:
        global admin_login
        admin_login = username
    print(msg)


@common.function_dic(func_dic, '创建学校')
@common.auth('admin')
def create_school():
    while True:
        campus = input("[返回上一层: B/b]请输入需要创建的校区: ").strip()
        if campus.lower() == 'b':
            break
        if not campus:
            print("对不起, 以上输入内容不能有空!")
            continue
        msg = admin_interface.create_school_interface(admin_login, campus)
        print(msg)


@common.function_dic(func_dic, '创建课程')
@common.auth('admin')
def create_course():
    while True:
        campus = common_main.choose_campus()
        if campus is None:
            break
        elif campus is False:
            continue

        course_name = input('请输入需要创建的课程名称: ').strip()
        course_period = input('请设置创建的课程课时周期: ').strip()
        course_price = input('请为你创建的课程指定价格: ').strip()
        if not all([course_name, course_period, course_price]):
            print("对不起, 以上输入内容不能有空!")
            continue
        if not course_price.isdigit():
            print("对不起, 课程定价应该为数字!")
            continue
        msg = admin_interface.create_course_interface(
            admin_login, campus,
            course_name, course_period, course_price)
        print(msg)


@common.function_dic(func_dic, '创建讲师')
@common.auth('admin')
def create_teacher():
    while True:
        teacher_name = input('[返回上一层: B/b]请输入讲师姓名: ').strip()
        if teacher_name.lower() == 'b':
            break
        msg = admin_interface.create_teacher_interface(admin_login, teacher_name)
        print(msg)


def admin_view():
    common.execute_func_view(func_dic)

六. db

1. models.py

from db import db_handler


class Base:
    def save(self):
        db_handler.save(self)

    @classmethod
    def select(cls, username):
        return db_handler.select(cls, username)


class Admin(Base):
    def __init__(self, username, password):
        self.user = username
        self.password = password
        self.save()

    @staticmethod
    def create_school(campus):
        School(campus)

    @staticmethod
    def create_course(
            school_obj,
            course_name, course_period, course_price):
        Course(course_name, course_period, course_price)

        school_obj.course_list.append(course_name)
        school_obj.save()

    @staticmethod
    def create_teacher(teacher_name, password):
        Teacher(teacher_name, password)


class School(Base):
    school_name = '老男孩'

    def __init__(self, campus):
        self.user = campus
        self.course_list = []
        self.save()

    def __str__(self):
        return f'学校名:{self.school_name} 校区:{self.user}'


class Course(Base):
    def __init__(self, course_name, course_period, course_price):
        self.user = course_name
        self.period = course_period
        self.price = int(course_price)
        self.student_list = []
        self.save()

    def __str__(self):
        return f'课程:{self.user} 周期时长:{self.period} 定价:{self.price}元'


class Student(Base):
    def __init__(self, username, password):
        self.user = username
        self.password = password
        self.campus = None
        self.course_dic = {}
        self.score_dic = {}
        self.balance = 0
        self.save()

    def set_campus(self, campus):
        self.campus = campus
        self.save()

    def add_course(self, course_name):
        self.course_dic[course_name] = False
        self.save()

    def add_balance(self, balance):
        self.balance += balance
        self.save()

    def pay_course(self, course_obj):
        self.balance -= course_obj.price
        self.course_dic[course_obj.user] = True
        self.score_dic[course_obj.user] = 0
        self.save()

        course_obj.student_list.append(self.user)
        course_obj.save()

    def __str__(self):
        if self.campus:
            campus = self.campus
        else:
            campus = '未绑定'
        return f'学生:{self.user} 所在校区:{campus}'


class Teacher(Base):
    def __init__(self, username, password):
        self.user = username
        self.password = password
        self.course_list = []
        self.save()

    def add_teacher_couser(self, course_name):
        self.course_list.append(course_name)
        self.save()

    @staticmethod
    def check_course_student(course_name):
        course_obj = Course.select(course_name)
        return course_obj.student_list

    @staticmethod
    def modify_score(course_name, student_name, score):
        student_obj = Student.select(student_name)
        student_obj.score_dic[course_name] = score
        student_obj.save()

2. db_handler.py

import pickle
import os
from conf import settings


def join_path(*paths):
    return os.path.join(*paths)


def save(self):
    dir_path = join_path(
        settings.DB_DIR_PATH,
        self.__class__.__name__,
    )
    if not os.path.isdir(dir_path):
        os.mkdir(dir_path)

    path = join_path(
        dir_path, self.user
    )
    with open(path, 'wb') as f:
        pickle.dump(self, f)


def select(cls, username):
    path = join_path(
        settings.DB_DIR_PATH,
        cls.__name__,
        username
    )
    if os.path.isfile(path):
        with open(path, 'rb') as f:
            return pickle.load(f)

七. interface

1. common_interface.py

import os
from conf import settings
from lib import common
from db import models

logger = common.logger('auth')


# def login_interface(username, password, user_type):
#     if user_type == 'admin':
#         obj = models.Admin.select(username)
#     elif user_type == 'student':
#         obj = models.Student.select(username)
#     elif user_type == 'teacher':
#         obj = models.Teacher.select(username)
#     else:
#         return '对不起, 用户类型输入错误!'
#
#     if obj:
#         if obj.password == lib.encryption(password):
#             info = f'登录成功! 登录用户:{username}'
#             logger.info(info)
#             return True, info
#         return False, '登录失败! 用户密码错误!'
#     return False, '登录失败! 用户不存在!'

def login_interface(username, password, user_type):
    if hasattr(models, user_type):
        obj = getattr(models, user_type).select(username)
        if obj:
            if obj.password == common.encryption(password):
                info = f'登录成功! 登录用户:{username}'
                logger.info(info)
                return True, info
            return False, '登录失败! 用户密码错误!'
        else:
            return False, '登录失败! 用户不存在!'
    return '对不起, 用户类型输入错误!'



def get_all_campus_interface():
    dir_path = os.path.join(settings.DB_DIR_PATH, 'School')
    if os.path.isdir(dir_path):
        if os.listdir(dir_path):
            return True, os.listdir(dir_path)
        else:
            return False, '对不起, 学校校区不存在, 请联系管理员创建学校'
    return False, '对不起, 学校未曾创建, 请联系管理员创建学校!'


def get_course_off_campus_interface(campus):
    school_obj = models.School.select(campus)
    course_list = school_obj.course_list
    if course_list:
        return True, course_list
    return False, '对不起, 校区下课程还没有开通, 请联系管理员创建本校区的课程!'

2. admin_interface.py

from lib import common
from db import models

logger = common.logger('admin')


def register_interface(username, password):
    admin_obj = models.Admin.select(username)
    if admin_obj:
        return '该用户已经存在!'
    models.Admin(username, common.encryption(password))

    info = f'注册成功! 新注册用户:{username}'
    logger.info(info)

    return info


def create_school_interface(admin_login, campus):
    admin_obj = models.Admin.select(admin_login)
    admin_obj.create_school(campus)

    info = f'校区创建成功! 创建校区管理员:{admin_login} 新建校区:{campus}'
    logger.info(info)

    return info


def create_course_interface(
        admin_login, campus,
        course_name, course_period, course_price):
    school_obj = models.School.select(campus)
    if course_name in school_obj.course_list:
        return '对不起, 课程已经存在!'

    admin_obj = models.Admin.select(admin_login)
    admin_obj.create_course(
        school_obj,
        course_name, course_period, course_price)

    info = f'课程创建成功! 创建校区管理员:{admin_login} 新建课程:{course_name} 课时周期:{course_period} 定价:{course_price}元 课程开设校区:{campus}'
    logger.info(info)

    return info


def create_teacher_interface(admin_login, teacher_name, password='123'):
    teacher_obj = models.Teacher.select(teacher_name)
    if teacher_obj:
        return '对不起, 该讲师已经存在!'

    admin_obj = models.Admin.select(admin_login)
    admin_obj.create_teacher(teacher_name, common.encryption(password))

    info = f'讲师创建成功! 创建讲师管理员:{admin_login} 新建讲师:{teacher_name} 讲师初始密码:{password}'
    logger.info(info)

    return info

3. student_interface.py

from lib import common
from db import models

logger = common.logger('student')


def register_interface(username, password):
    student_obj = models.Student.select(username)
    if student_obj:
        return '该用户已经存在!'
    models.Student(username, common.encryption(password))

    info = f'注册成功! 新注册用户:{username}'
    logger.info(info)

    return info


def add_campus_interface(student_login, campus):
    student_obj = models.Student.select(student_login)
    if student_obj.campus:
        return False, '对不起, 你已经选择了校区, 如果想转校请联系管理员!'

    student_obj.set_campus(campus)

    info = f'选择校区成功! 校区选择用户:{student_login} 选择校区:{campus}'
    logger.info(info)

    return True, info


def get_campus_interface(student_login):
    student_obj = models.Student.select(student_login)
    campus = student_obj.campus
    if campus:
        return True, campus
    else:
        return False, '对不起, 您还未选择校区, 请先选择校区!'


def add_course_interface(student_login, course_name):
    student_obj = models.Student.select(student_login)
    course_dic = student_obj.course_dic
    if course_name in course_dic:
        return '对不起, 课程已经被你选择, 无法重复选择!'

    student_obj.add_course(course_name)

    info = f'课程选择成功! 课程选择用户:{student_login} 选择课程:{course_name}'
    logger.info(info)

    return info


def check_balance_interface(student_login):
    student_obj = models.Student.select(student_login)
    return student_obj.balance


def recharge_balance_interface(student_login, add_balance):
    student_obj = models.Student.select(student_login)

    add_balance = int(add_balance)
    student_obj.add_balance(add_balance)

    info = f'充值成功! 充值用户:{student_login} 充值金额:{add_balance}元'
    logger.info(info)

    return info


def get_unpaid_tuition_course(student_login):
    student_obj = models.Student.select(student_login)
    course_dic = student_obj.course_dic
    if not course_dic:
        return False, '对不起, 至今为止您还未选择过课程!'
    course_list = [course_name for course_name, flag in course_dic.items() if not flag]
    if course_list:
        return True, course_list
    return False, '对不起, 您未有需要支付的课程!'


def pay_tuition_interface(student_login, course_name):
    student_obj = models.Student.select(student_login)
    course_obj = models.Course.select(course_name)
    if student_obj.balance < course_obj.price:
        return f'对不起, 余额不足请充值! 课程价格:{course_obj.price}元 当前余额:{student_obj.balance}元'
    student_obj.pay_course(course_obj)

    info = f'支付成功! 支付用户:{student_login} 支付金额:{course_obj.price}元 支付课程:{course_name}元'
    logger.info(info)

    return info


def check_score_interface(student_login):
    student_obj = models.Student.select(student_login)
    score_dic = student_obj.score_dic
    if score_dic:
        return True, score_dic
    else:
        return False, '对不起, 至今为止您还未选择并支付任意一门课程!'

4. teacher_interface.py

from lib import common
from db import models

logger = common.logger('teacher')


def check_teach_course_interface(teacher_login):
    teacher_obj = models.Teacher.select(teacher_login)
    course_list = teacher_obj.course_list
    if course_list:
        return True, course_list
    return False, '对不起, 您还未选则教授课程!'


def add_teach_course_interface(teacher_login, course_name):
    teacher_obj = models.Teacher.select(teacher_login)
    course_list = teacher_obj.course_list
    if course_name in course_list:
        return '对不起, 该课程已经在你教授范围之内!'

    teacher_obj.add_teacher_couser(course_name)

    info = f'选择教授课程成功! 教授课程讲师:{teacher_login} 教授课程名称:{course_name}'
    logger.info(info)

    return info


def check_course_student_interface(teacher_login, course_name):
    teacher_obj = models.Teacher.select(teacher_login)
    student_list = teacher_obj.check_course_student(course_name)
    if student_list:
        return True, student_list
    return False, '对不起, 这们课程没有学生学, 请联系学生!'


def modify_score_interface(teacher_login, course_name, student_name, score):
    teacher_obj = models.Teacher.select(teacher_login)
    teacher_obj.modify_score(course_name, student_name, score)

    info = f'修改学生成绩成功! 批改老师:{teacher_login} 被修改成绩学生:{student_name} 针对的课程:{course_name} 本次课程批改成绩:{score}分'
    logger.info(info)

    return info

八. lib

1. common.py

import hashlib
import logging.config
from functools import wraps
from conf import settings

logging.config.dictConfig(settings.LOGGING_DIC)


def logger(log_name):
    return logging.getLogger(log_name)


def encryption(password: str):
    m = hashlib.md5(password.encode("utf-8"))
    return m.hexdigest()


def function_dic(func_dic, description):
    def deco(func):
        if func_dic:
            max_num = max(func_dic, key=lambda k: int(k))
            max_num = int(max_num) + 1
            func_dic[str(max_num)] = (func, description)
        else:
            func_dic['1'] = (func, description)

        @wraps(func)
        def wrapper(*args, **kwargs):
            res = func(*args, **kwargs)
            return res

        return wrapper

    return deco


def execute_func_view(func_dic):
    while True:
        msg_list = []
        for key, value in func_dic.items():
            msg_list.append(f'      {key}. {value[1]}\n')
        print(f"""
{''.join(msg_list)}        
        """)
        cmd = input('[退出: B/b]请输入输入功能编号: ').strip()
        if cmd.lower() == 'b':
            break
        if cmd not in func_dic:
            print("对不起, 输入有误!")
            continue
        func_dic[cmd][0]()


def auth(role):
    def deco(func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            if role == 'admin':
                from core import admin
                if admin.admin_login:
                    res = func(*args, **kwargs)
                    return res
            elif role == 'student':
                from core import student
                if student.student_login:
                    res = func(*args, **kwargs)
                    return res
            elif role == 'teacher':
                from core import teacher
                if teacher.teacher_login:
                    res = func(*args, **kwargs)
                    return res
            else:
                print("对不起, 当前视图没有权限!")
                return
            print('对不起, 请先登录!')

        return wrapper

    return deco

九. log

posted @ 2020-05-17 23:04  给你加马桶唱疏通  阅读(122)  评论(0编辑  收藏  举报