添加历史图表
This commit is contained in:
parent
a7bd6b83a3
commit
a48ab84358
|
@ -64,10 +64,11 @@ def set_user_menu(menu: dict[str, float], nickname: str, dislike: list[str] = No
|
||||||
db.close()
|
db.close()
|
||||||
|
|
||||||
|
|
||||||
def fetch_all_user_today_menu() -> Generator[UserMenu, None, None]:
|
def fetch_all_user_menu(datestr: str = None) -> Generator[UserMenu, None, None]:
|
||||||
"""
|
"""
|
||||||
获取所有用户今日的投票内容
|
获取所有用户今日的投票内容
|
||||||
"""
|
"""
|
||||||
|
if not datestr:
|
||||||
datestr = datetime.now().strftime('%Y-%m-%d')
|
datestr = datetime.now().strftime('%Y-%m-%d')
|
||||||
db = sqlite3.connect(db_path)
|
db = sqlite3.connect(db_path)
|
||||||
cursor = db.cursor()
|
cursor = db.cursor()
|
||||||
|
|
|
@ -8,12 +8,16 @@ from dao import *
|
||||||
from utils import is_mobile_request
|
from utils import is_mobile_request
|
||||||
|
|
||||||
|
|
||||||
def fetch_user_menu_summary() -> tuple[defaultdict[str, float], list[str], list[tuple[str, list[str]]]]:
|
def fetch_user_menu_summary(datestr: str = None) -> tuple[
|
||||||
|
defaultdict[str, float],
|
||||||
|
list[str],
|
||||||
|
list[tuple[str, list[str]]]
|
||||||
|
]:
|
||||||
"""
|
"""
|
||||||
获取今天所有人的投票汇总
|
获取今天所有人的投票汇总
|
||||||
:return: 品类->数量
|
:return: 品类->数量
|
||||||
"""
|
"""
|
||||||
all_menu: list[UserMenu] = list(fetch_all_user_today_menu())
|
all_menu: list[UserMenu] = list(fetch_all_user_menu(datestr))
|
||||||
if len(all_menu) > 0:
|
if len(all_menu) > 0:
|
||||||
menus = list(map(lambda x: x.menu, all_menu))
|
menus = list(map(lambda x: x.menu, all_menu))
|
||||||
users = list(map(lambda x: x.nickname, all_menu))
|
users = list(map(lambda x: x.nickname, all_menu))
|
||||||
|
@ -156,6 +160,19 @@ def compute_eat_users(dislikes, result, users):
|
||||||
return eat_users
|
return eat_users
|
||||||
|
|
||||||
|
|
||||||
|
@app.route('/chart')
|
||||||
|
def chart():
|
||||||
|
datestr = request.args.get('date')
|
||||||
|
recent_results: list[RollResult] = list(fetch_roll_result_list(-1, 7))
|
||||||
|
menus, users, dislikes = fetch_user_menu_summary(datestr)
|
||||||
|
return render_template('chart.html',
|
||||||
|
date=datestr,
|
||||||
|
menus=menus,
|
||||||
|
users=users,
|
||||||
|
recent_results=recent_results
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@app.route('/dinner')
|
@app.route('/dinner')
|
||||||
def dinner():
|
def dinner():
|
||||||
"""
|
"""
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,33 @@
|
||||||
|
<html lang="zh">
|
||||||
|
<head>
|
||||||
|
{% block head %}
|
||||||
|
<title>{% block title %}{% endblock %}</title>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<link rel="stylesheet" href="/static/bootstrap.min.css">
|
||||||
|
{% endblock %}
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container text-center pt-5">
|
||||||
|
{% block content %}{% endblock %}
|
||||||
|
</div>
|
||||||
|
<footer class="footer mt-auto py-3 bg-light">
|
||||||
|
<div class="container">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12">
|
||||||
|
<a class="link-secondary link-offset-2"
|
||||||
|
href="https://git.zaneyork.cn:8443/ZaneYork/dinner_vote">本项目抽签完全公开透明,源码开放欢迎随时审查</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12">
|
||||||
|
<span style="font-size: 0.7rem">Copyright © <script>document.write(new Date().getFullYear().toString())</script> Zane York. All Rights Reserved.</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
{% block script %}
|
||||||
|
<script src="/static/jquery-3.2.1.min.js"></script>
|
||||||
|
<script src="/static/jquery.serializejson.js"></script>
|
||||||
|
<script src="/static/bootstrap.bundle.min.js"></script>
|
||||||
|
{% endblock %}
|
||||||
|
</body>
|
|
@ -0,0 +1,97 @@
|
||||||
|
{% extends "base.html" %}
|
||||||
|
{% block title %}晚餐吃什么鸭{% endblock %}
|
||||||
|
{% block head %}
|
||||||
|
{{ super() }}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<div class="pt-1 mb-3">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-10">
|
||||||
|
<select id="dateSelect" class="form-select" aria-label="日期选择">
|
||||||
|
{% for recent_result in recent_results %}
|
||||||
|
<option value="{{ recent_result.datestr }}" {{ 'selected' if date==recent_result.datestr else '' }}>
|
||||||
|
{{ recent_result.datestr }}
|
||||||
|
</option>
|
||||||
|
{% endfor %}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="col-1">
|
||||||
|
<button type="button" class="btn btn-primary" onclick="back()">返回</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="main" style="width: 100%;height:400px;"></div>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block script %}
|
||||||
|
{{ super() }}
|
||||||
|
<script src="/static/echarts.min.js"></script>
|
||||||
|
<!--suppress JSSuspiciousNameCombination -->
|
||||||
|
<script>
|
||||||
|
function back() {
|
||||||
|
window.location.href = '/dinner';
|
||||||
|
}
|
||||||
|
|
||||||
|
$("#dateSelect").change(function () {
|
||||||
|
window.location.href = 'chart?date=' + $("#dateSelect").val();
|
||||||
|
});
|
||||||
|
const chartEl = document.getElementById('main');
|
||||||
|
const menus = {{ menus | tojson }};
|
||||||
|
const legendData = [], seriesData = [];
|
||||||
|
for (let menu in menus) {
|
||||||
|
legendData.push(menu);
|
||||||
|
seriesData.push({value: menus[menu], name: menu});
|
||||||
|
}
|
||||||
|
const option = {
|
||||||
|
title: {
|
||||||
|
text: '{{date}}',
|
||||||
|
left: 'center',
|
||||||
|
top: 'center'
|
||||||
|
},
|
||||||
|
legend: {
|
||||||
|
orient: 'horizontal',
|
||||||
|
left: 20,
|
||||||
|
right: 20,
|
||||||
|
top: 10,
|
||||||
|
data: legendData
|
||||||
|
},
|
||||||
|
series: [
|
||||||
|
{
|
||||||
|
type: 'pie',
|
||||||
|
radius: ['30%', '35%'],
|
||||||
|
center: ['50%', '50%'],
|
||||||
|
data: seriesData,
|
||||||
|
label: {
|
||||||
|
show: true,
|
||||||
|
position: 'outside',
|
||||||
|
color: '#1B233E',
|
||||||
|
formatter: function (params) {
|
||||||
|
return params.name + ' ' + params.percent + '%'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
function resizeChart() {
|
||||||
|
let windowWidth = window.innerWidth;
|
||||||
|
let windowHeight = window.innerHeight;
|
||||||
|
if (windowWidth > windowHeight) {
|
||||||
|
windowHeight = 600;
|
||||||
|
} else {
|
||||||
|
windowHeight = windowWidth * 110 / 100;
|
||||||
|
}
|
||||||
|
chartEl.style.width = windowWidth * 95 / 100 + "px";
|
||||||
|
chartEl.style.height = windowHeight + "px";
|
||||||
|
}
|
||||||
|
|
||||||
|
resizeChart();
|
||||||
|
const mainChart = echarts.init(chartEl);
|
||||||
|
window.addEventListener('resize', function () {
|
||||||
|
resizeChart()
|
||||||
|
mainChart.resize();
|
||||||
|
});
|
||||||
|
mainChart.setOption(option);
|
||||||
|
</script>
|
||||||
|
{% endblock %}
|
|
@ -1,11 +1,9 @@
|
||||||
<html lang="zh">
|
{% extends "base.html" %}
|
||||||
<head>
|
{% block title %}晚餐吃什么鸭{% endblock %}
|
||||||
<title>晚餐吃什么鸭</title>
|
{% block head %}
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
{{ super() }}
|
||||||
<link rel="stylesheet" href="/static/bootstrap.min.css">
|
{% endblock %}
|
||||||
</head>
|
{% block content %}
|
||||||
<body>
|
|
||||||
<div class="container text-center pt-5">
|
|
||||||
<p>每天8:00-17:30间开放匿名投票更新,17:30以后允许发起抽签,抽签结果确定后不可更改</p>
|
<p>每天8:00-17:30间开放匿名投票更新,17:30以后允许发起抽签,抽签结果确定后不可更改</p>
|
||||||
<p>第一名与第二名得票数相差不超过10%时随机抽签,按其得票数决定中签概率,否则选择第一名</p>
|
<p>第一名与第二名得票数相差不超过10%时随机抽签,按其得票数决定中签概率,否则选择第一名</p>
|
||||||
<p>投票结果仅供参考,最终解释权归部门总经理、副总经理所有</p>
|
<p>投票结果仅供参考,最终解释权归部门总经理、副总经理所有</p>
|
||||||
|
@ -17,7 +15,8 @@
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<label class="input-group-text" for="inputName" id="basic-addon1">姓名</label>
|
<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 }}
|
<input type="text"
|
||||||
|
class="form-control" {{ 'readonly="readonly"' if user_menu.nickname else '' | safe }}
|
||||||
id="inputName" name="nickname" value="{{ user_menu.nickname }}">
|
id="inputName" name="nickname" value="{{ user_menu.nickname }}">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -92,36 +91,18 @@
|
||||||
<label class="mb-2">最近点餐结果</label>
|
<label class="mb-2">最近点餐结果</label>
|
||||||
<ul class="list-group">
|
<ul class="list-group">
|
||||||
{% for recent_result in recent_results %}
|
{% for recent_result in recent_results %}
|
||||||
<li class="list-group-item d-flex justify-content-between align-items-center">
|
<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.value }}</span>
|
||||||
<span>{{ recent_result.datestr }}</span>
|
<span>{{ recent_result.datestr }}</span>
|
||||||
</li>
|
</li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<footer class="footer mt-auto py-3 bg-light">
|
{% endblock %}
|
||||||
<div class="container">
|
{% block script %}
|
||||||
<div class="row">
|
{{ super() }}
|
||||||
<div class="col-12">
|
<!--suppress JSUnresolvedReference -->
|
||||||
<a class="link-secondary link-offset-2"
|
<script>
|
||||||
href="https://git.zaneyork.cn:8443/ZaneYork/dinner_vote">本项目抽签完全公开透明,源码开放欢迎随时审查</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-12">
|
|
||||||
<span style="font-size: 0.7rem">Copyright © <script>document.write(new Date().getFullYear().toString())</script> Zane York. All Rights Reserved.</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</footer>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script src="/static/jquery-3.2.1.min.js"></script>
|
|
||||||
<script src="/static/jquery.serializejson.js"></script>
|
|
||||||
<script src="/static/bootstrap.bundle.min.js"></script>
|
|
||||||
|
|
||||||
<!--suppress JSUnresolvedReference -->
|
|
||||||
<script>
|
|
||||||
document.addEventListener('keydown', function (event) {
|
document.addEventListener('keydown', function (event) {
|
||||||
if (event.key === 'Enter' || event.keyCode === 13) {
|
if (event.key === 'Enter' || event.keyCode === 13) {
|
||||||
update();
|
update();
|
||||||
|
@ -203,6 +184,10 @@
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function viewChart(datestr) {
|
||||||
|
window.location.href = 'chart?date=' + datestr;
|
||||||
|
}
|
||||||
|
|
||||||
$(function () {
|
$(function () {
|
||||||
const counterId = window.setInterval(counter, 1000);
|
const counterId = window.setInterval(counter, 1000);
|
||||||
|
|
||||||
|
@ -227,6 +212,5 @@
|
||||||
btn.text(hours + ':' + minutes + ':' + seconds)
|
btn.text(hours + ':' + minutes + ':' + seconds)
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
</body>
|
{% endblock %}
|
||||||
</html>
|
|
||||||
|
|
Loading…
Reference in New Issue