在上一篇博客中,我们补全了一些用户系统的相关功能,这期让我们来实现用户的上下级关系以及考勤审批
十 用户上下级和考勤审批
在我们的系统中,每个用户只有一个上级,但每个用户可以有多个下级。因此,我们需要给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