Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dorm agreement #805

Merged
merged 5 commits into from
Jan 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions dormitory/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@

admin.site.register(Dormitory)

@admin.register(Agreement)
class DormitoryAgreementAdmin(admin.ModelAdmin):
list_display = ['user', 'sign_time']

@admin.register(DormitoryAssignment)
class DormitoryAssignmentAdmin(admin.ModelAdmin):
list_display = ['dormitory', 'user', 'bed_id', 'time']
Expand Down
28 changes: 28 additions & 0 deletions dormitory/migrations/0003_agreement.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Generated by Django 4.2.3 on 2024-01-02 13:11

from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('dormitory', '0002_initial'),
]

operations = [
migrations.CreateModel(
name='Agreement',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('sign_time', models.DateTimeField(auto_now_add=True, verbose_name='签订时间')),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='用户')),
],
options={
'verbose_name': '住宿协议',
'verbose_name_plural': '住宿协议',
},
),
]
11 changes: 11 additions & 0 deletions dormitory/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,19 @@
__all__ = [
'Dormitory',
'DormitoryAssignment',
'Agreement'
]

class Agreement(models.Model):

class Meta:
verbose_name = '住宿协议'
verbose_name_plural = verbose_name

user = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name='用户')
sign_time = models.DateTimeField('签订时间', auto_now_add=True)


class Dormitory(models.Model):
class Meta:
verbose_name = '宿舍'
Expand Down
18 changes: 17 additions & 1 deletion dormitory/serializers.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from rest_framework import serializers

from dormitory.models import Dormitory, DormitoryAssignment
from dormitory.models import Dormitory, DormitoryAssignment, Agreement


class DormitorySerializer(serializers.ModelSerializer):
Expand All @@ -13,3 +13,19 @@ class DormitoryAssignmentSerializer(serializers.ModelSerializer):
class Meta:
model = DormitoryAssignment
fields = '__all__'


class AgreementSerializerFixme(serializers.ModelSerializer):
class Meta:
model = Agreement
fields = ['id']


class AgreementSerializer(serializers.ModelSerializer):

user = serializers.StringRelatedField()

class Meta:
model = Agreement
fields = ['user', 'sign_time']
read_only_fields = ['user', 'sign_time']
13 changes: 10 additions & 3 deletions dormitory/urls.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
from django.urls import include, path
from rest_framework.routers import DefaultRouter

from dormitory.views import (DormitoryAssignmentViewSet,
DormitoryAssignResultView, DormitoryRoutineQAView,
DormitoryViewSet)
from dormitory.views import (
DormitoryAssignmentViewSet, DormitoryAssignResultView,
DormitoryRoutineQAView, DormitoryViewSet,
AgreementView, DormitoryAgreementViewSetFixme, DormitoryAgreementViewSet)


router = DefaultRouter()
router.register('dormitory', DormitoryViewSet, basename='dormitory')
router.register('dormitoryassignment', DormitoryAssignmentViewSet,
basename='dormitoryassignment')
router.register('agreement-query-fixme', DormitoryAgreementViewSetFixme,
basename='agreement-query-fixme')
router.register('agreement-query', DormitoryAgreementViewSet,
basename='agreement-query')


urlpatterns = [
Expand All @@ -18,4 +23,6 @@
name='dormitory-routine-QA'),
path('assign-result/', DormitoryAssignResultView.as_view(),
name='dormitory-assign-result'),
path('agreement/', AgreementView.as_view(),
name='agreement'),
]
40 changes: 37 additions & 3 deletions dormitory/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,14 @@
from rest_framework import viewsets

# TODO: Leaky dependency
from utils.marker import fix_me
from generic.models import User
from app.models import NaturalPerson
from app.view.base import ProfileTemplateView
from dormitory.models import Dormitory, DormitoryAssignment
from dormitory.serializers import (DormitoryAssignmentSerializer,
DormitorySerializer)
from dormitory.models import Dormitory, DormitoryAssignment, Agreement
from dormitory.serializers import (
DormitoryAssignmentSerializer, DormitorySerializer,
AgreementSerializerFixme, AgreementSerializer)
from questionnaire.models import AnswerSheet, AnswerText, Survey


Expand All @@ -20,6 +23,23 @@ class DormitoryAssignmentViewSet(viewsets.ReadOnlyModelViewSet):
serializer_class = DormitoryAssignmentSerializer


class DormitoryAgreementViewSetFixme(viewsets.ReadOnlyModelViewSet):
serializer_class = AgreementSerializerFixme
def get_queryset(self):
# Only active students need to sign the agreement
require_agreement = User.objects.filter(active=True,
utype=User.Type.STUDENT).contains(self.request.user)
if require_agreement:
return Agreement.objects.filter(user=self.request.user)
# A hack to return something, so that the frontend won't redirect
official_user = User.objects.get(username='zz00000')
Agreement.objects.get_or_create(user=official_user)
return Agreement.objects.filter(user=official_user)

class DormitoryAgreementViewSet(viewsets.ReadOnlyModelViewSet):
queryset = Agreement.objects.all()
serializer_class = AgreementSerializer

class DormitoryRoutineQAView(ProfileTemplateView):

template_name = 'dormitory/routine_QA.html'
Expand Down Expand Up @@ -85,3 +105,17 @@ def show_dorm_assign(self):
)
except DormitoryAssignment.DoesNotExist:
self.extra_context.update(dorm_assign=False)

class AgreementView(ProfileTemplateView):
template_name = 'dormitory/agreement.html'
page_name = '住宿协议'
need_prepare = False

def get(self):
return self.render()

@fix_me
def post(self):
Agreement.objects.get_or_create(user=self.request.user)
from django.shortcuts import redirect
return redirect("/welcome")
32 changes: 32 additions & 0 deletions static/assets/js/dorm_forcement.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
const dorm_path = '/dormitory/agreement';
const query_path = '/dormitory/agreement-query-fixme';

function currentIsDormPage() {
var current_url = window.location.pathname;
return current_url.includes(dorm_path);
}

function getAgreementState() {
return fetch(query_path)
.then(response => response.json())
.then(data => {
// Bad design:
// If user do not have to sign,
// or user has signed, return is not empty.
return data.length > 0;
})
.catch(error => {
console.error('Error fetching agreement state:', error);
return true; // Pretend user has signed on network error.
});
}

$(function() {
if (!currentIsDormPage()) {
getAgreementState().then(signed => {
if (!signed) {
window.location.href = dorm_path;
}
});
}
});
2 changes: 2 additions & 0 deletions templates/base.html
Original file line number Diff line number Diff line change
Expand Up @@ -380,6 +380,8 @@ <h3>
<script src={% static "datetimepicker/js/moment-with-locales.min.js" %}></script>
<script src={% static "plugins/perfect-scrollbar/perfect-scrollbar.min.js" %}></script>
<script src={% static "assets/js/app.js" %}></script>
<script src={% static "assets/js/dorm_forcement.js" %}></script>


<script>
$(document).ready(function () {
Expand Down
96 changes: 96 additions & 0 deletions templates/dormitory/agreement.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
{% extends "base.html" %}
{% comment %}
# XXX: Vars {{ I(bar_display) }}
# XXX: Request {{ I(session) }}
# XXX: Depends {% base %}
{% endcomment %}
{% load static %}

{% block add_css_file %}
<link href={% static "assets/css/authentication/form-2.css" %} rel="stylesheet" type="text/css" />
<!-- END GLOBAL MANDATORY STYLES -->
<link rel="stylesheet" type="text/css" href={% static "assets/css/forms/theme-checkbox-radio.css" %}>
<link rel="stylesheet" type="text/css" href={% static "assets/css/forms/switches.css" %}>
{% endblock %}

{% block mainpage %}
<div id="content" class="main-content" >
<div class="form-container outer">

<center>
<div class="form-form">
<div class="form-content">

<form class="text-left" id="form" method="POST">

<div class="widget-content widget-content-area">

<div class="widget-header">
<div class="row">
<div class="col-xl-12 col-md-12 col-sm-12 col-12">
<h3 style="text-align: center; padding-top: 20px; padding-bottom: 20px;">元培学院学生公寓住宿公约</h3>
</div>
</div>
</div>

<!-- <div class="row"> -->
<div class="col">
<p>一、自觉遵守国家法律法规、《北京大学学生公寓管理办法》及学校、学院的其他相关规定,包括但不限于公寓管理、安全等。</p>
<br/>
<p>二、服从学校及学院的住宿安排,不擅自更换、占用床位和房间;因特殊情况确有需要调换床位或宿舍的,应向元培学院提出申请,经批准后方可进行调换。</p>
<br/>
<p>三、爱护和正常合理使用公寓楼内的设备和家具等生活服务设施,自觉维护公寓楼内公共秩序,不得留宿他人,不得出租、私自出借学生公寓床位。自觉遵守熄灯规定,适时关闭宿舍内有关电器。不得有任何影响或可能影响公共安全和他人身心健康的行为。</p>
<br/>
<p>四、积极发挥“自我教育、自我管理、自我服务”的作用,主动参与学生公寓管理服务与文化建设活动。住宿学生应互相尊重,团结友爱,养成健康的学习生活习惯。住宿学生应当尊重公寓工作人员劳动,保持楼梯间、走廊无垃圾;节约水电,杜绝浪费;自觉爱护公寓区的绿地和景观等。</p>
<br/>
<p>五、未经学院同意,不占用公共空间存放物品;违反学校、学院规定存放物品,经公告30日仍不收回、清理的,视为同意学院清理该物品。</p>
<br/>
<p>六、学院每月进行卫生检查,检查不合格且经提醒后仍不整改的,取消评奖评优资格,学院有权请学生搬离35号楼。</p>
<br/>
<p>七、35楼宿舍为学生租借使用,管理权归属学校公寓中心与学院。学生租借床位期间,应按规定使用分配设备,不得私自占用他人或空置床位及设施、设备。</p>
<br/>
<br/>
<br/>
<br/>
<p>我已认真阅读上述内容,承诺遵守上述公约及其他学校和学院的规定,如有违反,我接受宿舍调整安排及学校和学院的其他决定。</p>

<div class="d-flex justify-content-between">
<button type="submit" id="confirm" name="confirm" class="btn btn-lg btn-primary" value="yes"
style="display:block;margin:0 auto">同意</button>
</div>
</div>
<!-- </div> -->
</div>
</form>


</div>
</div>
</center>
</div>
</div>

{% endblock %}

{% block add_js_file %}
<!-- END GLOBAL MANDATORY SCRIPTS -->
<script src={% static "assets/js/authentication/form-2.js" %}></script>

<script>
var countdown = 10;
var btn = document.getElementById('confirm');
function settime() {
if (countdown == 0) {
btn.removeAttribute("disabled");
btn.innerHTML="同意";
} else {
btn.setAttribute("disabled", true);
btn.innerHTML="同意(" + countdown + ")";
countdown--;
setTimeout("settime()",1000);
}
}
settime()
</script>

{% endblock %}