会议室预定(可作为插件使用)

Posted ゛竹先森゜

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了会议室预定(可作为插件使用)相关的知识,希望对你有一定的参考价值。

会议室预定(小项目)

该项目仍旧是用Django框架完成的,此项目的重点在于前端页面中有关预定的操作

  首先建表,这里用的表较少,一共三张表,表结构如下:

from django.db import models
class UserInfo(models.Model):
    name = models.CharField(verbose_name=\'用户姓名\', max_length=32)
    password = models.CharField(verbose_name=\'密码\', max_length=32)

class MeetingRoom(models.Model):
    title = models.CharField(verbose_name=\'会议室\', max_length=32)

class Booking(models.Model):
    user = models.ForeignKey(verbose_name=\'用户\', to=\'UserInfo\')
    room = models.ForeignKey(verbose_name=\'会议室\', to=\'MeetingRoom\')
    booking_date = models.DateField(verbose_name=\'预定日期\')
    time_choices = (
        (1, \'8:00\'),
        (2, \'9:00\'),
        (3, \'10:00\'),
        (4, \'11:00\'),
        (5, \'12:00\'),
        (6, \'13:00\'),
        (7, \'14:00\'),
        (8, \'15:00\'),
        (9, \'16:00\'),
        (10, \'17:00\'),
        (11, \'18:00\'),
        (12, \'19:00\'),
        (13, \'20:00\'),
    )
    booking_time = models.IntegerField(verbose_name=\'预定时间段\', choices=time_choices)
    class Meta:
        unique_together = (
            (\'booking_date\', \'booking_time\', \'room\')
        )

 

 

接下来分配路由(项目较为简单,所以并没有写注册的页面,这里是直接将用户数据录入数据库了,若想使项目更完善,可自行添加注册功能。)

from django.conf.urls import url
from django.contrib import admin
from meet import views
urlpatterns = [
    url(r\'^admin/\', admin.site.urls),
    url(r\'^login/$\', views.login),
    url(r\'^index/$\', views.index),
    url(r\'^booking/$\', views.booking),
    url(r\'^log_out/$\', views.log_out),
]

 

然后是静态文件static的配置

STATIC_URL = \'/static/\'
STATICFILES_DIRS=[
    os.path.join(BASE_DIR, \'meet\',\'static\'),#别名所指的实际文件夹路径
]

 

  这里我们用到两个插件,分别是datetimepicker和sweetalert2,前者是在前端页面对Date进行扩展的时间工具,后者是对alert进行美化的一共工具,如不想使用后者,直接用alert即可。

从网上下载两个插件,放入static下。

 

   登录、注销功能  

    url(r\'^login/$\', views.login),
    url(r\'^log_out/$\', views.log_out),
#注销功能
def log_out(request):
    del request.session[\'user_info\']
    return redirect(\'/index/\')


def login(request):
    """
    用户登录
    """
    if request.method == "GET":
        form = LoginForm()
        return render(request, \'login.html\', {\'form\': form})
    else:
        form = LoginForm(request.POST)
        if form.is_valid():
            rmb = form.cleaned_data.pop(\'rmb\')#一周免登陆选项
            user = models.UserInfo.objects.filter(**form.cleaned_data).first()
            if user:
                request.session[\'user_info\'] = {\'id\': user.id, \'name\': user.name}
                if rmb:#若勾选了一周免登陆选项
                    request.session.set_expiry(60 * 60 * 24 * 30)
                return redirect(\'/index/\')
            else:
                form.add_error(\'password\', \'密码错误\')
                return render(request, \'login.html\', {\'form\': form})
        else:
            return render(request, \'login.html\', {\'form\': form})
注销、登录的views

上面用到了form组件如下:

from django.forms import Form
from django.forms import fields
from django.forms import widgets

class LoginForm(Form):
    name = fields.CharField(
        required=True,
        error_messages={\'required\': \'用户名不能为空\'},
        widget=widgets.TextInput(attrs={\'class\': \'form-control\', \'placeholder\': \'用户名\', \'id\': \'name\'})
    )
    password = fields.CharField(
        required=True,
        error_messages={\'required\': \'密码不能为空\'},
        widget=widgets.PasswordInput(attrs={\'class\': \'form-control\', \'placeholder\': \'密码\', \'id\': \'password\'})
    )
    #一周免登陆选项
    rmb = fields.BooleanField(required=False, widget=widgets.CheckboxInput(attrs={\'value\': 1}))
LoginForm
{% load staticfiles %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="{% static \'bootstrap-3.3.7-dist/css/bootstrap.min.css\' %}">
    <style>


    </style>
</head>

<body>

<div style="width: 500px;margin: 50px auto;padding-top: 180px;">
    <form class="form-horizontal" method="post" novalidate>
        {% csrf_token %}
        <div class="form-group">
            <label for="name" class="col-sm-2 control-label">用户名:</label>
            <div class="col-sm-10">
                {{ form.name }}
                {{ form.errors.name.0 }}
            </div>
        </div>
        <div class="form-group">
            <label for="password" class="col-sm-2 control-label">密码:</label>
            <div class="col-sm-10">
                {{ form.password }}
                {{ form.errors.password.0 }}
            </div>
        </div>
        <div class="form-group">
            <div class="col-sm-offset-2 col-sm-10">
                <div class="checkbox">
                    <label>
                       {{ form.rmb }} 一周内免登录
                    </label>
                </div>
            </div>
        </div>
        <div class="form-group">
            <div class="col-sm-offset-2 col-sm-10">
                <button type="submit" class="btn btn-primary">登录</button>
            </div>
        </div>
    </form>

</div>
</body>
</html>
login.html

之后用于验证登陆与否的装饰器:

#验证登陆与否的装饰器
def auth(func):
    def inner(request, *args, **kwargs):
        user_info = request.session.get(\'user_info\')
        if not user_info:
            return redirect(\'/login/\')
        return func(request, *args, **kwargs)
    return inner
装饰器auth

 

登录功能较为简单,不做详述,接下来我们做首页

 

  我们的预定功能就在首页中,所以首页是重中之重。

难点:index.html中的js:tbody的生成、datetimepicker插件的使用、前后端发送的时间格式的转换、后端录入数据库的操作

    url(r\'^index/$\', views.index),
    url(r\'^booking/$\', views.booking),
#views.py中:
import json
import datetime
from django.shortcuts import render, HttpResponse, redirect
from django.http import JsonResponse
from meet import models
from meet.form import *
from django.db.models import Q
from django.db.utils import IntegrityError

@auth def index(request): """ 会议室预定首页 :param request: :return: """ #拿到所有的时间段 time_choices = models.Booking.time_choices user_info = request.session.get(\'user_info\') name=user_info[\'name\'] return render(request, \'index.html\', {\'time_choices\': time_choices,\'name\':name})
{% load staticfiles %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="{% static \'bootstrap-3.3.7-dist/css/bootstrap.min.css\' %}">
    <link rel="stylesheet" href="{% static \'datetimepicker/bootstrap-datetimepicker.min.css\' %}">
    <link rel="stylesheet" href="{% static \'sweetalert2/sweetalert2.css\' %}">

    {#    <link rel="stylesheet" href="{% static \'mycss/index.css\' %}">#}
    <style>

    body {
        font-size: 14px;
    }

    .shade {
        position: fixed;
        z-index: 1040;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
        background-color: #999;
        filter: alpha(opacity=50);
        -moz-opacity: 0.5;
        opacity: 0.5;
    }

    .loading {
        position: fixed;
        z-index: 1050;
        top: 40%;
        left: 50%;
        height: 32px;
        width: 32px;
        margin: 0 0 0 -16px;
        background: url(/static/img/loading.gif);
    }


    .clearfix{
        padding: 10px 0;

    }
    .input-group{
        width: 230px;
        float:left;
    }
    .save-btn{
        padding: 0 5px;float: left
    }

    table > tbody td {
        height: 80px;
        width: 80px;
        text-align: center;
        vertical-align: middle;

    }

    table > tbody td.chosen {
        background-color: #ebccd1;
    }

    table > tbody td.selected {
        background-color:#d58512 ;
    }
    .mycolor{
        background-color: #EEE685;
    }
    .unable{

        color: #002a80;
        opacity: 0.5;
    }


    </style>

</head>
<body>

<div class="container">
<div class="panel panel-primary">
  <div class="panel-heading">
          <h1 class="text-center">会议室预定</h1>
  </div>
  <div class="panel-body">
        <div class="clearfix">
        <div style="float: left;color: red" id="errors"></div>
        <div class=\'input-group\'>
{#            时间插件#}
            <input type=\'text\' class="form-control" id=\'datetimepicker11\' placeholder="请选择日期"/>
            <span class="input-group-addon">
                <span class="glyphicon glyphicon-calendar">
                </span>
            </span>
        </div>
        <div class="save-btn">
            <a id="save"  class="btn btn-primary">保存</a>
        </div>
        <div class="pull-right">
            <b>hello {{ name }} </b>&nbsp;&nbsp;&nbsp;&nbsp;<a href="/log_out/">注销</a>
        </div>
    </div>

    <table class="table table-bordered  table-striped" style="border:1px solid red">
        <thead>
        <tr>
            <th>会议室</th>
{#            拿到从后端发过来的所有时间段#}
            {% for choice in time_choices %}
                <th>{{ choice.1 }}</th>
            {% endfor %}
        </tr>
        </thead>
        <tbody id="tBody">
{#        tbody中的内容包含未预定信息和预定信息,且需要实时更新

以上是关于会议室预定(可作为插件使用)的主要内容,如果未能解决你的问题,请参考以下文章

系统设计会议室预定系统房间预定系统设计

活字格 Web 应用生成平台 V4.0 发布,首次公开插件机制

#VSCode保存插件配置并使用 gist 管理代码片段

会议室预定终章

关于腾讯会议pc端的使用教程

会议室预定demo