添加了一个新的页面logs.html,用于显示今天的扫描日志。用户可以在该页面上查看扫描的条码和相关信息。
This commit is contained in:
parent
a7865638f4
commit
fe4be1b06e
24
app.py
24
app.py
@ -4,7 +4,7 @@ import os
|
|||||||
import re
|
import re
|
||||||
|
|
||||||
from apscheduler.schedulers.background import BackgroundScheduler
|
from apscheduler.schedulers.background import BackgroundScheduler
|
||||||
from flask import Flask, jsonify, request
|
from flask import Flask, jsonify, request, render_template
|
||||||
from pygrocy import EntityType, Grocy
|
from pygrocy import EntityType, Grocy
|
||||||
import atexit
|
import atexit
|
||||||
import base64
|
import base64
|
||||||
@ -16,6 +16,7 @@ import requests
|
|||||||
|
|
||||||
from barcode import BarcodeSpider, ShowApiSpider
|
from barcode import BarcodeSpider, ShowApiSpider
|
||||||
from recipe import get_recipe_from_xiachufang
|
from recipe import get_recipe_from_xiachufang
|
||||||
|
import models
|
||||||
|
|
||||||
logger = loguru.logger
|
logger = loguru.logger
|
||||||
# config = configparser.ConfigParser()
|
# config = configparser.ConfigParser()
|
||||||
@ -540,6 +541,27 @@ def add_to_stream():
|
|||||||
return jsonify({"message": str(e)}), 500
|
return jsonify({"message": str(e)}), 500
|
||||||
|
|
||||||
|
|
||||||
|
@app.route('/scanlogs/today', methods=['GET'])
|
||||||
|
def get_today_scanlogs():
|
||||||
|
try:
|
||||||
|
# 获取今天的所有日志并序列化
|
||||||
|
logs = models.ScanLog.get_today_logs()
|
||||||
|
serialized_logs = [log.serialize() for log in logs]
|
||||||
|
|
||||||
|
return jsonify({
|
||||||
|
'logs': serialized_logs,
|
||||||
|
'count': len(serialized_logs)
|
||||||
|
}), 200
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
return jsonify({'error': str(e)}), 500
|
||||||
|
|
||||||
|
|
||||||
|
@app.route('/logs')
|
||||||
|
def show_logs():
|
||||||
|
return render_template('logs.html')
|
||||||
|
|
||||||
|
|
||||||
# 初始化 APScheduler 并添加定时任务
|
# 初始化 APScheduler 并添加定时任务
|
||||||
scheduler = BackgroundScheduler()
|
scheduler = BackgroundScheduler()
|
||||||
scheduler.add_job(func=consume_stream, trigger="interval", seconds=10)
|
scheduler.add_job(func=consume_stream, trigger="interval", seconds=10)
|
||||||
|
|||||||
63
models.py
Normal file
63
models.py
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
from peewee import *
|
||||||
|
from datetime import datetime, time
|
||||||
|
import json
|
||||||
|
|
||||||
|
# Create database instance
|
||||||
|
db = SqliteDatabase('scanner.db')
|
||||||
|
|
||||||
|
class BaseModel(Model):
|
||||||
|
class Meta:
|
||||||
|
database = db
|
||||||
|
|
||||||
|
class BarcodeDB(BaseModel):
|
||||||
|
barcode = CharField(unique=True)
|
||||||
|
product_info = TextField()
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
table_name = 'barcode_db'
|
||||||
|
|
||||||
|
class ScanLog(BaseModel):
|
||||||
|
barcode = CharField()
|
||||||
|
scan_at = DateTimeField(default=datetime.now)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
table_name = 'scan_logs'
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_today_logs(cls):
|
||||||
|
# Get today's start and end timestamps
|
||||||
|
today = datetime.now().date()
|
||||||
|
today_start = datetime.combine(today, time.min) # Start of day (00:00:00)
|
||||||
|
today_end = datetime.combine(today, time.max) # End of day (23:59:59.999999)
|
||||||
|
|
||||||
|
# Query logs for today
|
||||||
|
return cls.objects.filter(
|
||||||
|
scan_at__gte=today_start,
|
||||||
|
scan_at__lte=today_end
|
||||||
|
).order_by('-scan_at')
|
||||||
|
|
||||||
|
def serialize(self):
|
||||||
|
# Try to get product info from BarcodeDB
|
||||||
|
name = None
|
||||||
|
try:
|
||||||
|
product = BarcodeDB.get(BarcodeDB.barcode == self.barcode)
|
||||||
|
product_info = json.loads(product.product_info)
|
||||||
|
name = product_info.get('name')
|
||||||
|
except BarcodeDB.DoesNotExist:
|
||||||
|
pass
|
||||||
|
|
||||||
|
return {
|
||||||
|
'barcode': self.barcode,
|
||||||
|
'name': name,
|
||||||
|
'scan_at': self.scan_at
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Create tables
|
||||||
|
def create_tables():
|
||||||
|
with db:
|
||||||
|
db.create_tables([BarcodeDB, ScanLog])
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
create_tables()
|
||||||
116
templates/logs.html
Normal file
116
templates/logs.html
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Today's Scan Logs</title>
|
||||||
|
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
|
||||||
|
<style>
|
||||||
|
table {
|
||||||
|
width: 80%;
|
||||||
|
margin: 20px auto;
|
||||||
|
border-collapse: collapse;
|
||||||
|
}
|
||||||
|
th, td {
|
||||||
|
padding: 8px;
|
||||||
|
text-align: left;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
}
|
||||||
|
th {
|
||||||
|
background-color: #f2f2f2;
|
||||||
|
}
|
||||||
|
.empty-name {
|
||||||
|
background-color: #ffe6e6;
|
||||||
|
}
|
||||||
|
.retry-button {
|
||||||
|
padding: 5px 10px;
|
||||||
|
background-color: #4CAF50;
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
border-radius: 4px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.retry-button:hover {
|
||||||
|
background-color: #45a049;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1 style="text-align: center;">Today's Scan Logs</h1>
|
||||||
|
<div id="logs-container">
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Barcode</th>
|
||||||
|
<th>Name</th>
|
||||||
|
<th>Action</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody id="logs-body">
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
// 加载日志数据
|
||||||
|
function loadLogs() {
|
||||||
|
$.ajax({
|
||||||
|
url: '/scanlogs/today',
|
||||||
|
method: 'GET',
|
||||||
|
success: function(logs) {
|
||||||
|
const tbody = $('#logs-body');
|
||||||
|
tbody.empty();
|
||||||
|
|
||||||
|
logs.forEach(function(log) {
|
||||||
|
const row = $('<tr>');
|
||||||
|
if (!log.name) {
|
||||||
|
row.addClass('empty-name');
|
||||||
|
}
|
||||||
|
|
||||||
|
row.append($('<td>').text(log.barcode));
|
||||||
|
row.append($('<td>').text(log.name || 'Empty'));
|
||||||
|
|
||||||
|
const actionCell = $('<td>');
|
||||||
|
if (!log.name) {
|
||||||
|
const retryButton = $('<button>')
|
||||||
|
.addClass('retry-button')
|
||||||
|
.text('Retry')
|
||||||
|
.click(() => retryBarcode(log.barcode));
|
||||||
|
actionCell.append(retryButton);
|
||||||
|
}
|
||||||
|
row.append(actionCell);
|
||||||
|
|
||||||
|
tbody.append(row);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
error: function(xhr, status, error) {
|
||||||
|
alert('Failed to load logs: ' + error);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 重试处理条码
|
||||||
|
function retryBarcode(barcode) {
|
||||||
|
$.ajax({
|
||||||
|
url: '/barcode',
|
||||||
|
method: 'POST',
|
||||||
|
data: JSON.stringify({ barcode: barcode }),
|
||||||
|
contentType: 'application/json',
|
||||||
|
success: function(response) {
|
||||||
|
alert('Barcode has been added to queue');
|
||||||
|
loadLogs(); // 重新加载数据
|
||||||
|
},
|
||||||
|
error: function(xhr, status, error) {
|
||||||
|
alert('Failed to process barcode: ' + error);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 页面加载时获取数据
|
||||||
|
$(document).ready(function() {
|
||||||
|
loadLogs();
|
||||||
|
|
||||||
|
// 每30秒自动刷新一次
|
||||||
|
setInterval(loadLogs, 30000);
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
Loading…
x
Reference in New Issue
Block a user