dinner_vote/templates/dinner.html

272 lines
14 KiB
HTML
Raw Normal View History

2024-09-19 16:53:25 +08:00
{% extends "base.html" %}
{% block title %}晚餐吃什么鸭{% endblock %}
{% block head %}
{{ super() }}
{% endblock %}
{% block content %}
2024-09-20 14:27:16 +08:00
<div class="border rounded p-2 mb-2 text-start" style="text-indent: 2em">
<div class="m-1">每天8:00-17:30间开放匿名投票更新17:30以后允许发起抽签抽签结果确定后不可更改。</div>
<div class="m-1">第一名与第二名得票数相差不超过<strong>10%</strong>时随机抽签,按其得票数决定中签概率,否则选择第一名。
</div>
<div class="m-1">投票结果仅供参考,最终解释权归部门总经理、副总经理所有。</div>
</div>
<div class="alert alert-light text-start" role="alert" style="text-indent: 2em">
{% for last_result in last_results %}
<div class="m-1">
今日<strong>{{ last_result.value }}</strong>最终得票数降低<strong>{{ 2 + loop.index0 }}0%</strong></div>
{% endfor %}
</div>
2024-09-13 08:28:41 +08:00
<form id="inputForm" class="form-inline" onsubmit="return false;">
2024-09-10 10:55:19 +08:00
<div class="form-group">
2024-09-20 15:48:58 +08:00
<div class="accordion">
<div class="accordion-item">
<h2 class="accordion-header">
<button class="accordion-button" type="button" data-bs-toggle="collapse"
data-bs-target="#collapseMyChoice" aria-expanded="true"
aria-controls="collapseMyChoice">
我选择
</button>
</h2>
<div id="collapseMyChoice" class="accordion-collapse collapse show">
<div class="accordion-body">
<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 row p-2">
{% for choice in all_choice %}
<div class="col-6 mb-1 p-1 border rounded {{ loop.cycle("rounded-end-0", "border-start-0 rounded-start-0") }}">
<div class="row">
<label for="range{{ loop.index }}"
class="col-12 d-flex justify-content-between align-items-center">
<span>{{ choice.label }}</span>
<span class="percentage">{{ '{:.1f}'.format((user_menu.menu.get(choice.name) or 0) * 100) }}%</span>
</label>
</div>
<div class="d-flex justify-content-between">
<div class="col-sm-8 col-md-9 col-lg-10">
<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 class="col-auto">
<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>
</div>
{% endfor %}
</div>
<button type="button" class="btn btn-outline-primary" onclick="update()">更新</button>
<button type="button" class="btn btn-outline-secondary" onclick="clearValue()">不吃</button>
<button type="button" id="btnRoll"
class="btn btn-outline-secondary" {{ "" if can_roll == True else ' disabled="disabled"' | safe }}
onclick="roll()">开始抽签
</button>
</div>
</div>
2024-09-14 07:58:21 +08:00
</div>
2024-09-20 15:48:58 +08:00
<div class="accordion-item">
<h2 class="accordion-header">
<button class="accordion-button" type="button" data-bs-toggle="collapse"
data-bs-target="#collapseAllChoice" aria-expanded="true"
aria-controls="collapseAllChoice">
大家的选择
</button>
</h2>
<div id="collapseAllChoice" class="accordion-collapse collapse show">
<div class="accordion-body">
<label class="d-flex justify-content-between">
总投票人数:{{ total_vote }}
2024-09-14 07:58:21 +08:00
</label>
2024-09-20 15:48:58 +08:00
<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>
2024-09-23 17:10:44 +08:00
<span class="col-3">{{ '{:.1f}'.format(summary[key] | round(1)) }}票</span>
<span class="col-3">{{ '{:.1f}'.format(summary[key] / total_vote * 100 | round(1)) }}%</span>
2024-09-20 15:48:58 +08:00
</li>
{% else %}
<li class="list-group-item">
<span>大家还没有选择</span>
</li>
{% endfor %}
</ul>
{% 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 %}
2024-09-20 14:27:16 +08:00
</div>
2024-09-20 15:48:58 +08:00
</div>
</div>
<div class="accordion-item">
<h2 class="accordion-header">
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse"
data-bs-target="#collapseRecentResult" aria-expanded="false"
aria-controls="collapseRecentResult">
最近点餐结果
</button>
</h2>
<div id="collapseRecentResult" class="accordion-collapse collapse">
<div class="accordion-body">
<div class="pt-1 mb-3">
<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>
2024-09-20 14:27:16 +08:00
</div>
2024-09-14 07:58:21 +08:00
</div>
</div>
2024-09-20 15:48:58 +08:00
</div>
2024-09-20 14:27:16 +08:00
</div>
2024-09-10 10:55:19 +08:00
</div>
</form>
2024-09-19 16:53:25 +08:00
{% endblock %}
{% block script %}
{{ super() }}
<!--suppress JSUnresolvedReference -->
<script>
document.addEventListener('keydown', function (event) {
if (event.key === 'Enter' || event.keyCode === 13) {
update();
return false;
2024-09-14 07:58:21 +08:00
}
2024-09-19 16:53:25 +08:00
});
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++) {
2024-09-20 15:48:58 +08:00
spans[i].innerHTML = (summary > 0 ? (parseFloat(values[i]) * 100 / summary).toFixed(1) : '0.0') + '%';
2024-09-19 16:53:25 +08:00
if (values[i] > 0 && checkBoxs[i].checked) {
checkBoxs[i].checked = false;
}
2024-09-14 07:58:21 +08:00
}
2024-09-19 16:53:25 +08:00
});
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);
2024-09-10 10:55:19 +08:00
}
}
2024-09-19 16:53:25 +08:00
$(rangesInput[0]).trigger('change');
});
2024-09-10 10:55:19 +08:00
2024-09-19 16:53:25 +08:00
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)
}
2024-09-10 10:55:19 +08:00
}
2024-09-19 16:53:25 +08:00
})
}
2024-09-10 10:55:19 +08:00
2024-09-19 16:53:25 +08:00
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)
}
2024-09-10 10:55:19 +08:00
}
2024-09-19 16:53:25 +08:00
})
}
2024-09-11 10:15:20 +08:00
2024-09-19 16:53:25 +08:00
function roll() {
$.ajax({
url: 'dinner/roll',
dataType: 'json',
success: function (result) {
if (result.code === 0) {
window.location.reload();
} else {
alert('更新失败: ' + result.data)
}
}
})
}
2024-09-11 10:15:20 +08:00
2024-09-19 16:53:25 +08:00
function viewChart(datestr) {
window.location.href = 'chart?date=' + datestr;
2024-09-11 10:15:20 +08:00
}
2024-09-19 16:53:25 +08:00
$(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 %}