桌子生成二维码

This commit is contained in:
ahao 2025-03-20 13:21:31 +08:00
parent adbe039e3d
commit 64f44d0736
3 changed files with 215 additions and 115 deletions

View File

@ -3,3 +3,6 @@ import os
class Config: class Config:
SECRET_KEY = os.getenv('SECRET_KEY', 'jagxor-xokwis-dekqE6') SECRET_KEY = os.getenv('SECRET_KEY', 'jagxor-xokwis-dekqE6')
BASE_API_URL = os.getenv('BASE_API_URL', 'http://127.0.0.1:8000') BASE_API_URL = os.getenv('BASE_API_URL', 'http://127.0.0.1:8000')
WX_APP_ID = os.getenv('WX_APP_ID', 'wx2c0e64b724b6dec4')
WX_APP_SECRET = os.getenv('WX_APP_SECRET', 'b5330aece22ce5cf5df3048cb28d1558')
WX_QRCODE_API = 'https://api.weixin.qq.com/wxa/getwxacode'

View File

@ -1,6 +1,14 @@
from flask import Blueprint, render_template, request, redirect, url_for, flash, session from flask import Blueprint, render_template, request, redirect, url_for, flash, session
import requests import requests
from frontend.config import Config from frontend.config import Config
import time
import base64
wx_token_cache = {
'access_token': None,
'expires_at': 0 # 过期时间戳
}
tables_bp = Blueprint('tables', __name__) tables_bp = Blueprint('tables', __name__)
@ -162,3 +170,50 @@ def list_all_tables():
return resp.json() return resp.json()
except Exception as e: except Exception as e:
return {"detail": str(e)}, 500 return {"detail": str(e)}, 500
@tables_bp.route('/tables/qrcode/<int:table_id>')
def get_table_qrcode(table_id):
if not session.get('token'):
return {"detail": "未认证"}, 401
# 获取access_token
try:
current_time = time.time()
if current_time > wx_token_cache['expires_at']:
resp = requests.get(
"https://api.weixin.qq.com/cgi-bin/token",
params={
"grant_type": "client_credential",
"appid": Config.WX_APP_ID,
"secret": Config.WX_APP_SECRET
}
)
token_data = resp.json()
if 'access_token' not in token_data:
return {"detail": "获取token失败"}, 500
wx_token_cache['access_token'] = token_data['access_token']
wx_token_cache['expires_at'] = current_time + token_data['expires_in'] - 300 # 提前5分钟过期
# 生成小程序码
qr_resp = requests.post(
Config.WX_QRCODE_API,
params={"access_token": wx_token_cache['access_token']},
json={
"path": f"/pages/timer/timer?table_id={table_id}",
"env_version": "trial",
"width": 280
}
)
if qr_resp.status_code != 200 or 'image' not in qr_resp.headers.get('Content-Type', ''):
return {"detail": "生成二维码失败"}, 500
return {
"image": f"data:image/png;base64,{base64.b64encode(qr_resp.content).decode('utf-8')}",
"table_id": table_id
}
except Exception as e:
return {"detail": str(e)}, 500

View File

@ -27,10 +27,16 @@
<td> <td>
<a href="{{ url_for('tables.edit_table', table_id=table.table_id) }}" <a href="{{ url_for('tables.edit_table', table_id=table.table_id) }}"
class="btn btn-warning btn-sm">编辑</a> class="btn btn-warning btn-sm">编辑</a>
<button class="btn btn-sm btn-info"
onclick="showQRCode({{ table.table_id }}, '{{ table.game_table_number }}')">
生成二维码
</button>
<form action="{{ url_for('tables.delete_table', table_id=table.table_id) }}" method="post" <form action="{{ url_for('tables.delete_table', table_id=table.table_id) }}" method="post"
class="d-inline"> class="d-inline">
<button type="submit" class="btn btn-danger btn-sm" <button type="submit" class="btn btn-danger btn-sm"
onclick="return confirm('确认删除该桌台吗?')">删除</button> onclick="return confirm('确认删除该桌台吗?')">删除
</button>
</form> </form>
</td> </td>
</tr> </tr>
@ -39,6 +45,23 @@
</table> </table>
</div> </div>
<div class="modal fade" id="qrcodeModal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">桌台二维码 - 桌号<span id="tableNumber"></span></h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body text-center">
<img id="qrcodeImage" class="img-fluid mb-3" style="max-width: 300px;">
<div>
<button class="btn btn-primary" onclick="downloadQRCode()">下载二维码</button>
</div>
</div>
</div>
</div>
</div>
<!-- 选择策略模态框 --> <!-- 选择策略模态框 -->
<div class="modal fade" id="selectStrategyModal" tabindex="-1" aria-labelledby="selectStrategyModalLabel" <div class="modal fade" id="selectStrategyModal" tabindex="-1" aria-labelledby="selectStrategyModalLabel"
aria-hidden="true"> aria-hidden="true">
@ -69,6 +92,25 @@
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
<script> <script>
function showQRCode(tableId, tableNumber) {
fetch(`/tables/qrcode/${tableId}`)
.then(res => res.json())
.then(data => {
if (data.image) {
document.getElementById('qrcodeImage').src = data.image;
document.getElementById('tableNumber').textContent = tableNumber;
new bootstrap.Modal(document.getElementById('qrcodeModal')).show();
}
});
}
function downloadQRCode() {
const link = document.createElement('a');
link.download = `桌台二维码-${document.getElementById('tableNumber').textContent}.png`;
link.href = document.getElementById('qrcodeImage').src;
link.click();
}
async function openSelectStrategyModal(tableId) { async function openSelectStrategyModal(tableId) {
try { try {
const token = "{{ session['token'] }}"; const token = "{{ session['token'] }}";