dinner_vote/templates/dinner.html

217 lines
9.3 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{% extends "base.html" %}
{% block title %}晚餐吃什么鸭{% endblock %}
{% block head %}
{{ super() }}
{% endblock %}
{% block content %}
<p>每天8:00-17:30间开放匿名投票更新17:30以后允许发起抽签抽签结果确定后不可更改</p>
<p>第一名与第二名得票数相差不超过10%时随机抽签,按其得票数决定中签概率,否则选择第一名</p>
<p>投票结果仅供参考,最终解释权归部门总经理、副总经理所有</p>
{% for last_result in last_results %}
<p>今日{{ last_result.value }}最终得票数降低{{ 2 + loop.index0 }}0%</p>
{% endfor %}
<form id="inputForm" class="form-inline" onsubmit="return false;">
<div class="form-group">
<div class="mb-3">
<div class="input-group">
<label class="input-group-text" for="inputName" id="basic-addon1">姓名</label>
<input type="text"
class="form-control" {{ 'readonly="readonly"' if user_menu.nickname else '' | safe }}
id="inputName" name="nickname" value="{{ user_menu.nickname }}">
</div>
</div>
<div class="mb-3">
<label class="input-group-addon">我选择</label>
</div>
{% for choice in all_choice %}
<div class="mb-3 row">
<div class="col-9">
<div class="input-group">
<label for="range{{ loop.index }}" class="form-label">
<span>{{ choice.label }} - </span>
<span class="percentage">{{ '{:.2f}'.format((user_menu.menu.get(choice.name) or 0) * 100) }}</span>%
</label>
<input type="range" class="form-range" data-skip-falsy="true"
id="range{{ loop.index }}" name="choice[{{ choice.name }}]:number"
min="0" max="10" step="1"
value="{{ (user_menu.menu.get(choice.name) or 0) * 10 }}">
</div>
</div>
<div class="col-3">
<input class="form-check-input" type="checkbox" name="dislike[]"
id="checkDislike{{ loop.index }}" value="{{ choice.name }}"
{{ 'checked' if choice.name in user_menu.dislike else '' }}>
<label class="form-check-label" for="checkDislike{{ loop.index }}">
不吃
</label>
</div>
</div>
{% endfor %}
</div>
</form>
<button type="button" class="btn btn-primary" onclick="update()">更新</button>
<button type="button" class="btn btn-secondary" onclick="clearValue()">不吃</button>
<button type="button" id="btnRoll"
class="btn btn-secondary" {{ "" if can_roll == True else ' disabled="disabled"' | safe }}
onclick="roll()">开始抽签
</button>
<div class="pt-3">
<label>大家的选择 - 总投票人数:{{ total_vote }}</label>
<ul class="list-group pt-2 mb-4">
{% for key in summary_keys %}
<li class="list-group-item d-flex justify-content-between align-items-center{{ " active" if result == key else "" }} {{ " list-group-item-primary" if predict_result == key else "" }}">
<span class="col-5">{{ key }}</span>
<span class="col-3">{{ '{:.2f}'.format(summary[key] | round(2)) }}票</span>
<span class="col-3">{{ '{:.2f}'.format(summary[key] / total_vote * 100 | round(2)) }}%</span>
</li>
{% endfor %}
</ul>
</div>
{% if (users|length) > 3 %}
<div class="pt-1 mb-3">
<label class="mb-2">参与投票人员</label>
<ul class="list-group list-group-horizontal">
{% for user in users %}
<li class="list-group-item">{{ user }}</li>
{% endfor %}
</ul>
</div>
{% endif %}
{% if ((users|length) > 3 or result) %}
<div class="pt-1 mb-3">
<label class="mb-2">{{ ('如果吃' + predict_result) if predict_result else '' }}就餐人员</label>
<ul class="list-group list-group-horizontal">
{% for user in eat_users %}
<li class="list-group-item">{{ user }}</li>
{% endfor %}
</ul>
</div>
{% endif %}
<div class="pt-1 mb-3">
<label class="mb-2">最近点餐结果</label>
<ul class="list-group">
{% for recent_result in recent_results %}
<li onclick="viewChart('{{ recent_result.datestr }}')" class="list-group-item d-flex justify-content-between align-items-center">
<span>{{ recent_result.value }}</span>
<span>{{ recent_result.datestr }}</span>
</li>
{% endfor %}
</ul>
</div>
{% endblock %}
{% block script %}
{{ super() }}
<!--suppress JSUnresolvedReference -->
<script>
document.addEventListener('keydown', function (event) {
if (event.key === 'Enter' || event.keyCode === 13) {
update();
return false;
}
});
const rangesInput = $("input[type=range]");
const checkBoxs = $("input[type=checkbox]")
rangesInput.change(function () {
const values = rangesInput.map(function () {
return $(this).val();
}).get();
const summary = values.reduce((a, b) => parseInt(a) + parseInt(b));
const spans = $(".percentage")
for (let i = 0; i < values.length; i++) {
spans[i].innerHTML = summary > 0 ? (parseFloat(values[i]) * 100 / summary).toFixed(2) : 0;
if (values[i] > 0 && checkBoxs[i].checked) {
checkBoxs[i].checked = false;
}
}
});
checkBoxs.change(function () {
const data = $('#inputForm').serializeJSON();
const values = checkBoxs.map(function () {
return $(this).val();
}).get();
for (let i = 0; i < values.length; i++) {
if (data.dislike.includes(values[i])) {
$(rangesInput[i]).val(0);
}
}
$(rangesInput[0]).trigger('change');
});
function update() {
const data = $('#inputForm').serializeJSON();
const nickname = data.nickname;
data.nickname = undefined;
$.ajax({
url: 'dinner/update?nickname=' + nickname + '&value=' + JSON.stringify(data),
dataType: 'json',
success: function (result) {
if (result.code === 0) {
window.location.reload();
} else {
alert('更新失败: ' + result.data)
}
}
})
}
function clearValue() {
const data = $('#inputForm').serializeJSON();
const nickname = data.nickname;
$.ajax({
url: 'dinner/update?nickname=' + nickname + '&value=',
dataType: 'json',
success: function (result) {
if (result.code === 0) {
window.location.reload();
} else {
alert('更新失败: ' + result.data)
}
}
})
}
function roll() {
$.ajax({
url: 'dinner/roll',
dataType: 'json',
success: function (result) {
if (result.code === 0) {
window.location.reload();
} else {
alert('更新失败: ' + result.data)
}
}
})
}
function viewChart(datestr) {
window.location.href = 'chart?date=' + datestr;
}
$(function () {
const counterId = window.setInterval(counter, 1000);
function counter() {
const now = new Date();
const targetTime = new Date(
now.getFullYear(), now.getMonth(), now.getDate(),
17, 30, 0, 0
);
const diff = targetTime - now;
const btn = $("#btnRoll");
if (diff <= 0) {
window.clearInterval(counterId);
btn.text('开始抽签');
btn.attr('disabled', null)
return;
}
// Convert diff to hours, minutes, and seconds
const hours = Math.floor(diff / (1000 * 60 * 60)).toString().padStart(2, '0');
const minutes = Math.floor((diff % (1000 * 60 * 60)) / (1000 * 60)).toString().padStart(2, '0');
const seconds = Math.floor((diff % (1000 * 60)) / 1000).toString().padStart(2, '0');
btn.text(hours + ':' + minutes + ':' + seconds)
}
});
</script>
{% endblock %}