Tornado笔记——用Tornado搭建假单统计考勤系统(八)

本文介绍如何使用Tornado框架实现用户上下级关系和考勤审批功能。包括在数据库中添加`supervisor`字段,实现用户组织调整、审批考勤页面,以及前后端交互逻辑。
摘要由CSDN通过智能技术生成

在上一篇博客中,我们补全了一些用户系统的相关功能,这期让我们来实现用户的上下级关系以及考勤审批

十 用户上下级和考勤审批

在我们的系统中,每个用户只有一个上级,但每个用户可以有多个下级。因此,我们需要给User表加一个名为supervisor的字段,表明该用户的上级是谁。一个用户的可以审批其所有下级的考勤,他自身的考勤也只能被他的上级审批。

我们migrate目录下打开Powershell,输入以下命令:

alembic revision -m "add supervisor on user table"

alembic会在versions下生成如下命名方式的文件:ead049362c51_add_supervisor_on_user_table.py。开头的16进制字符串为当前数据库的版本,每人都是不同的。

在ead049362c51_add_supervisor_on_user_table.py中输入以下内容,为User表加入supervisor字段:

# add_supervisor_on_user_table.py

"""add supervisor on user table

Revision ID: ead049362c51
Revises: ac252cf2f6aa
Create Date: 2020-11-10 20:47:31.458590

"""
from alembic import op
import sqlalchemy as sa


# revision identifiers, used by Alembic.
revision = 'ead049362c51'
down_revision = 'ac252cf2f6aa'
branch_labels = None
depends_on = None


def upgrade():
    op.add_column('user', sa.Column('supervisor', sa.String))


def downgrade():
    pass

然后回到powershell,输入以下命令完成对数据库的升版:

alembic upgrade head

再打开database/tbluser.py,把新的supervisor字段加到User类中:

# database/tbluser.py

from database.tablebase import Base
from sqlalchemy import Column,String,Integer,Date,DateTime

class User(Base):
    __tablename__ = 'user'
    id = Column(Integer,autoincrement=True,primary_key=True)
    username = Column(String,unique=True,nullable=False)
    password = Column(String,nullable=False)
    email = Column(String,unique=True,nullable=False)
    usergroup = Column(String,nullable=False)
    state = Column(String)
    registerdate = Column(Date)
    lastlogintime = Column(DateTime)
    supervisor = Column(String)


    def __repr__(self):
        return '<user(username=%s,email=%s,registerdate=%s)>' % (self.username,self.email,self.registerdate)

这样,我们数据库层面的准备工作就大功告成,下面让我们开始实现调整用户上下级的功能(俗称“挂人”,即把某个用户挂在某个用户的下面)。实现后的效果如下图:

在这个页面中,我们可以对用户的上下级关系进行调整,也可以对用户所属的用户组进行调整。 

我们打开user_app/user_app.py,建立UserOrganization RequestHandler:

# user_app.py
# ...

class UserOrganization(BaseHandler):
    def get(self):
        userorganizationpath = gettemplatepath('userorganization.html')
        users = session.query(User).filter(User.username != 'Root')
        usergroups = getallusergroup()
        userInfos = []
        for user in users:
            usergrouplist = []
            usersupervisorlist = []
            userInfo = {}
            userInfo['username'] = user.username
            userInfo['usergroup'] = user.usergroup
            if user.usergroup not in usergrouplist:
                usergrouplist.append(user.usergroup)
            if user.supervisor not in usersupervisorlist and type(user.supervisor) is str:
                usersupervisorlist.append(user.supervisor)
            userInfo['formid'] = user.id
            userInfo['groupid'] = str(user.id)+'_group'
            userInfo['supervisorid'] = str(user.id) + '_supervisor'
            for othergroup in usergroups:
                if othergroup.groupname not in usergrouplist:
                    usergrouplist.append(othergroup.groupname)
            for otheruser in users:
                if otheruser.username not in usersupervisorlist:
                    usersupervisorlist.append(otheruser.username)
            userInfo['usergrouplist'] = usergrouplist
            userInfo['usersupervisorlist'] = usersupervisorlist
            userInfos.append(userInfo)
        self.render(userorganizationpath,userInfos=userInfos)

    def post(self):
        userid = self.get_argument('userid')
        username = self.get_argument('username')
        usergroupid = userid + '_group'
        usergroup = self.get_argument(usergroupid)
        supervisorid = userid + '_supervisor'
        supervisor = self.get_argument(supervisorid)
        result = 'Fail'
        result = changeuserorganization(username,usergroup,supervisor)
        resultpath = gettemplatepath('result.html')
        if result == 'Success':
            self.redirect('/userorganization')
        else:
            result = '操作失败!'
            self.render(resultpath,result=result)

# main.py
# ...
routelist = [
    # ...
    (r"/userorganization",UserOrganization),
    # ...
]
# ...

在get请求中,我们会获得除了Root用户外的所有用户,并将其相关信息返回到前端页面显示;在post页面则是根据选择的用户组和上级用户将选定用户的用户组和上级改变。

changeuserorganization函数位于userutil.py中,代码如下:

# util/users/userutil.py

def changeuserorganization(username,usergroup,supervisor):
    print(username)
    user = session.query(User).filter(User.username == username).first()
    result = 'Fail'
    if type(user) is User:
        user.usergroup = usergroup
        user.supervisor = supervisor
        result = insertdata(user)
        if result == 'Success':
            pass
            #sendapprovemail(user.username,usergroup,user.email)
    return result

这个函数没啥说的,根据传入的用户名去修改用户组和上级,如果修改成功后,还可以调用之前写的email模块向用户发送邮件,这里就先用pass占个位。

调整用户组织的前端页面代码如下:

<!--userorganization.html-->

        {% block content %}
        <div class="page-wrapper">
            <!-- ============================================================== -->
            <!-- Container fluid  -->
            <!-- ============================================================== -->
            <div class="container-fluid">
                <!-- ============================================================== -->
                <!-- Bread crumb and right sidebar toggle -->
                <!-- ============================================================== -->
                <div class="row page-titles">
                    <div class="col-md-6 col-8 align-self-center">
                        <h3 class="text-themecolor m-b-0 m-t-0">调整用户组织</h3>
                        <ol class="breadcrumb">
                            <li class="breadcrumb-item"><a href="/">Home</a></li>
                            <li class="breadcrumb-item active">调整用户组织</li>
                        </ol>
                    </div>
                </div>
                <!-- ============================================================== -->
                <!-- End Bread crumb and right sidebar toggle -->
                <!-- ============================================================== -->
                <!-- ============================================================== -->
                <!-- Start Page Content -->
                <!-- ============================================================== -->
                <div class="row">
                    <!-- column -->
                    <div class="col-sm-12">
                        <div class="card"&g
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值