zoukankan      html  css  js  c++  java
  • 会议室预定

    效果:

    主要代码:

    from django.db import models
    from django.contrib.auth.models import AbstractUser
    
    
    class UserInfo(AbstractUser):
        telephone = models.CharField(max_length=32)
    
        def __str__(self):
            return self.username
    
    
    class MeetingRoom(models.Model):
        """
        会议室表
        """
        name = models.CharField(max_length=32)
        num = models.IntegerField()  # 容纳人数
    
        def __str__(self):
            return self.name
    
    
    class BookRecord(models.Model):
        """
        会议室预定信息
        """
        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"),
        )
        user = models.ForeignKey("UserInfo")
        room = models.ForeignKey(to="MeetingRoom")
        time_id = models.IntegerField(choices=time_choices)
        book_date = models.DateField()
    
        class Meta:
            unique_together = (
                ("room", "book_date", "time_id"),
            )
    
        def __str__(self):
            return str(self.user) + "预定了" + str(self.room)
    models.py
    import json
    import datetime
    from django.db.models import Q
    from django.contrib import auth
    from django.http import JsonResponse
    from django.shortcuts import render, redirect
    from django.utils.safestring import mark_safe
    
    from app01 import models
    
    
    def login(request):
        """
        登录
        :param request:
        :return:
        """
        if request.method == "GET":
            return render(request, "login.html")
        if request.method == "POST":
            username = request.POST.get("username")
            password = request.POST.get("password")
            user = auth.authenticate(username=username, password=password)
            if user:
                auth.login(request, user)
                return redirect("/")
            else:
                return render(request, "login.html")
    
    
    def log_out(request):
        """
        退出登录
        :param request:
        :return:
        """
        auth.logout(request)
        return redirect("/")
    
    def index(request):
        """
        首页
        :param request:
        :return:
        """
        now = datetime.datetime.now().date()
        book_date = request.GET.get("book_date", now)
        time_choices = models.BookRecord.time_choices
        room_list = models.MeetingRoom.objects.all()
        try:
            book_record_list = models.BookRecord.objects.filter(book_date=book_date)
        except Exception:
            book_record_list = models.BookRecord.objects.filter(book_date=now)
        table_body_html = ""
        for room in room_list:
            table_body_html += "<tr><td>{}({})</td>".format(room.name, room.num)
            for time_choice in time_choices:
                book_flag = False  # 预定标志
                book_record = None
                for book_record in book_record_list:
                    if book_record.room.pk == room.pk and book_record.time_id == time_choice[0]:
                        # 判断成立,意味这个单元格已被预定
                        book_flag = True
                        book_record = book_record
                        break
                if book_flag:
                    if request.user.pk == book_record.user.pk:
                        table_body_html += "<td class='active-self item' room-id={} time-id={}>{}</td>".format(room.pk, time_choice[0], "")
                    else:
                        table_body_html += "<td class='active-others item' room-id={} time-id={}>{}</td>".format(room.pk, time_choice[0], book_record.user.username)
                else:
                    table_body_html += "<td class='item' room-id={} time-id={}></td>".format(room.pk, time_choice[0])
            table_body_html += "</tr>"
        data = {
            "time_choices": time_choices,
            "table_body_html": mark_safe(table_body_html)
        }
        return render(request, "index.html", data)
    
    
    def book_meeting_room(request):
        """
        处理预定
        :param request:
        :return:
        """
        rep = {"code": 1000}
        if not request.user.username:
            rep["code"] = 1001
            return JsonResponse(rep)
        post_data = json.loads(request.POST.get("post_data"))  # {"DEL":{"1":["3","7"]},"ADD":{"2":["1","2"],"3":["1"]}}
        choose_date = request.POST.get("choose_date")
        try:
            # 添加预定
            book_list = []
            for room_id, time_id_list in post_data["ADD"].items():
                for time_id in time_id_list:
                    obj = models.BookRecord(user=request.user, room_id=int(room_id), time_id=int(time_id), book_date=choose_date)
                    book_list.append(obj)
            models.BookRecord.objects.bulk_create(book_list)
            # 删除预定
            for room_id, time_id_list in post_data["DEL"].items():
                for time_id in time_id_list:
                    models.BookRecord.objects.filter(room_id=room_id, user_id=request.user.pk, time_id=int(time_id), book_date=choose_date).delete()
        except Exception:
            rep["code"] = 1002
        return JsonResponse(rep)
    views.py
    <!DOCTYPE html>
    <html lang="zh-cn">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Index</title>
        <link rel="stylesheet" href="/static/bootstrap/css/bootstrap.min.css">
        <link rel="stylesheet" href="/static/sweetalert/sweetalert.css">
        <link rel="stylesheet" href="/static/datetimepicker/bootstrap-datetimepicker.min.css">
        <style>
            .navbar{
                border-radius: unset;
            }
            .navbar-nav{
                float: right;
            }
            @media (max- 800px){
                .navbar-nav{
                    float: none;
                }
            }
            .active-self{
                background-color: #228B22;
                color: white;
            }
            .active-others{
                background-color: #CD3333;
                color: white;
            }
            .active-checked{
                background-color: #87CEFA;
                color: white;
            }
            .input-date{
                 206px;
            }
            .form_datetime{
                margin-bottom: 10px;
            }
        </style>
    </head>
    <body>
    <nav class="navbar navbar-inverse">
        <div class="container">
            <div class="navbar-header">
                <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar"
                        aria-expanded="false" aria-controls="navbar">
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                </button>
                <span class="navbar-brand">会议室预定</span>
            </div>
            <div id="navbar" class="collapse navbar-collapse">
                <ul class="nav navbar-nav">
                    {% with user=request.user.username %}
                        {% if user %}
                            <li><a href="/">{{ user }}</a></li>
                            <li><a href="/logout">注销</a></li>
                        {% else %}
                            <li><a href="/login">登录</a></li>
                            <li><a href="#">注册</a></li>
                        {% endif %}
                    {% endwith %}
                </ul>
            </div>
        </div>
    </nav>
    <div class="container">
    
        <div class="form_datetime pull-right">
            <div class="input-group input-date">
                <input type="text" class="form-control" id="datetimepicker" autocomplete="off"  placeholder="请选择日期">
                <span class="input-group-addon">
                    <span class="glyphicon glyphicon-calendar"></span>
                </span>
            </div>
        </div>
    
        <table class="table table-bordered table-striped">
            <thead>
            <tr>
                <th id="is-login" user="{{ request.user.username }}">会议室/时间</th>
                {% for time_choice in time_choices %}
                    <th>{{ time_choice.1 }}</th>
                {% endfor %}
            </tr>
            </thead>
            <tbody>
                {{ table_body_html }}
            </tbody>
        </table>
    
        <button class="btn btn-primary pull-right save">保存</button>
        {% csrf_token %}
    </div>
    <script src="/static/jquery-3.3.1.min.js"></script>
    <script src="/static/bootstrap/js/bootstrap.min.js"></script>
    <script src="/static/sweetalert/sweetalert.min.js"></script>
    <script src="/static/datetimepicker/bootstrap-datetimepicker.min.js"></script>
    <script src="/static/datetimepicker/bootstrap-datetimepicker.zh-CN.js"></script>
    <script src="/static/index.js"></script>
    </body>
    </html>
    index.html
    // 用来保存用户提交信息
    var POST_DATA = {
        "ADD": {},
        "DEL": {}
    };
    
    // 为td绑定单击事件
    function ClickTableTd() {
        $(".item").click(function () {
            var isLogin = $("#is-login");
            var user = isLogin.attr("user");
            if (user === "") {
                location.href = "/login/"
            } else {
                var roomId = $(this).attr("room-id");
                var timeId = $(this).attr("time-id");
                // 取消预定
                if ($(this).hasClass("active-self")) {
                    $(this).removeClass("active-self").empty();
                    if (POST_DATA.DEL[roomId]) {
                        POST_DATA.DEL[roomId].push(timeId);
                    } else {
                        POST_DATA.DEL[roomId] = [timeId];
                    }
                // 取消临时预定
                } else if ($(this).hasClass("active-checked")) {
                    $(this).removeClass("active-checked").empty();
                    if (POST_DATA.ADD[roomId].length === 1) {
                        delete POST_DATA.ADD[roomId];
                    }
                    else {
                        var index = POST_DATA.ADD[roomId].indexOf(timeId);
                        POST_DATA.ADD[roomId].splice(index, 1);
                    }
                // 其他
                } else {
                    // 他人已预定
                    if ($(this).hasClass("active-others")) {
                        swal("该会议室已被他人预定")
                    // 添加临时预定
                    } else {
                        $(this).addClass("active-checked").text("");
                        if (POST_DATA.ADD[roomId]) {
                            POST_DATA.ADD[roomId].push(timeId);
                        } else {
                            POST_DATA.ADD[roomId] = [timeId];
                        }
                    }
                }
            }
            console.log(POST_DATA)
        })
    }
    ClickTableTd();
    
    // 日期格式化方法
    Date.prototype.pd = function (fmt) {
        var o = {
            "M+": this.getMonth() + 1,  //月份
            "d+": this.getDate(),       //"h+": this.getHours(),      //小时
            "m+": this.getMinutes(),    //"s+": this.getSeconds(),    //"q+": Math.floor((this.getMonth() + 3) / 3), //季度
            "S": this.getMilliseconds() //毫秒
        };
        if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
        for (var k in o)
            if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
        return fmt;
    };
    
    // 日历插件
    $("#datetimepicker").datetimepicker({
            minView: "month",
            format: "yyyy-mm-dd",
            language: "zh-CN",
            startDate: new Date(),
            autoclose: true,
            todayBtn: true,
    }).on("changeDate", queryBookInfo);
    function queryBookInfo(e) {
        CHOOSE_DATE = e.date.pd("yyyy-MM-dd");
        location.href = "/?book_date=" + CHOOSE_DATE;
    }
    
    // 日期
    if (location.search.slice(11)){
        CHOOSE_DATE = location.search.slice(11)
    } else {
        CHOOSE_DATE = new Date().pd("yyyy-MM-dd");
    }
    
    // 发送Ajax
    $(".save").click(function () {
        $.ajax({
            url:"/book/",
            type:"post",
            data:{
               "csrfmiddlewaretoken": $("[name='csrfmiddlewaretoken']").val(),
               "choose_date": CHOOSE_DATE,
               "post_data": JSON.stringify(POST_DATA)
            },
            success: function (rep) {
                if (rep.code === 1000) {
                    location.href = "/";
                } else if (rep.code === 1001){
                    location.href = "login";
                } else {
                    swal("预定的会议室已被他人预定");
                    location.href = "/"
                }
            }
        })
    });
    index.js

    完整zip包:

    https://files.cnblogs.com/files/believepd/msbr.zip

    1

  • 相关阅读:
    HDOJ 4248 A Famous Stone Collector DP
    Android开发系列(十九个):至SimpleAdapter设置样式
    matlab入门 蜂窝阵列
    OpenGL缓冲区
    如何在终端编辑命令
    struts2跳转类型解析
    设计模式(Facade)状态(注意事项)
    Swift与Objective-C API的交互
    Swift调用Objective C的FrameWork
    初探swift语言的学习—Object-C与Swift混编
  • 原文地址:https://www.cnblogs.com/believepd/p/10664276.html
Copyright © 2011-2022 走看看