Fix admin QR generation flow
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
const searchInput = document.getElementById("searchInput");
|
const ADMIN_MEMBER_ID = 104891;
|
||||||
const memberSelect = document.getElementById("memberSelect");
|
|
||||||
const generateBtn = document.getElementById("generateBtn");
|
const generateBtn = document.getElementById("generateBtn");
|
||||||
const statusText = document.getElementById("statusText");
|
const statusText = document.getElementById("statusText");
|
||||||
const resultCard = document.getElementById("resultCard");
|
const resultCard = document.getElementById("resultCard");
|
||||||
@@ -16,70 +16,11 @@ const metaQrPrefix = document.getElementById("metaQrPrefix");
|
|||||||
const metaPayloadLen = document.getElementById("metaPayloadLen");
|
const metaPayloadLen = document.getElementById("metaPayloadLen");
|
||||||
const metaPayloadPrefix = document.getElementById("metaPayloadPrefix");
|
const metaPayloadPrefix = document.getElementById("metaPayloadPrefix");
|
||||||
|
|
||||||
let allItems = [];
|
|
||||||
|
|
||||||
function setStatus(message, isError = false) {
|
function setStatus(message, isError = false) {
|
||||||
statusText.textContent = message;
|
statusText.textContent = message;
|
||||||
statusText.classList.toggle("error", isError);
|
statusText.classList.toggle("error", isError);
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderOptions(items) {
|
|
||||||
memberSelect.innerHTML = "";
|
|
||||||
|
|
||||||
if (!items.length) {
|
|
||||||
const option = document.createElement("option");
|
|
||||||
option.value = "";
|
|
||||||
option.textContent = "没有可选 ID";
|
|
||||||
memberSelect.appendChild(option);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const item of items) {
|
|
||||||
const option = document.createElement("option");
|
|
||||||
option.value = String(item.member_id);
|
|
||||||
option.textContent = item.label;
|
|
||||||
memberSelect.appendChild(option);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!memberSelect.value) {
|
|
||||||
memberSelect.selectedIndex = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function filterItems() {
|
|
||||||
const keyword = searchInput.value.trim().toLowerCase();
|
|
||||||
if (!keyword) {
|
|
||||||
renderOptions(allItems);
|
|
||||||
setStatus(`已加载 ${allItems.length} 个 ID`);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const filtered = allItems.filter((item) => {
|
|
||||||
const idText = String(item.member_id);
|
|
||||||
const village = String(item.village_name || "").toLowerCase();
|
|
||||||
return idText.includes(keyword) || village.includes(keyword);
|
|
||||||
});
|
|
||||||
|
|
||||||
renderOptions(filtered);
|
|
||||||
setStatus(`筛选后剩余 ${filtered.length} 个 ID`);
|
|
||||||
}
|
|
||||||
|
|
||||||
async function loadFoundIds() {
|
|
||||||
setStatus("正在加载 ID 列表...");
|
|
||||||
try {
|
|
||||||
const response = await fetch("/api/found-ids");
|
|
||||||
const data = await response.json();
|
|
||||||
if (!response.ok || !data.ok) {
|
|
||||||
throw new Error(data.error || "加载 ID 列表失败");
|
|
||||||
}
|
|
||||||
allItems = data.items || [];
|
|
||||||
renderOptions(allItems);
|
|
||||||
setStatus(`已加载 ${allItems.length} 个 ID`);
|
|
||||||
} catch (error) {
|
|
||||||
setStatus(error.message || "加载失败", true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function showResult(data) {
|
function showResult(data) {
|
||||||
resultCard.classList.remove("hidden");
|
resultCard.classList.remove("hidden");
|
||||||
qrImage.src = data.data_url;
|
qrImage.src = data.data_url;
|
||||||
@@ -97,14 +38,8 @@ function showResult(data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function generateQr() {
|
async function generateQr() {
|
||||||
const memberId = memberSelect.value;
|
|
||||||
if (!memberId) {
|
|
||||||
setStatus("请先选择一个 member_id", true);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
generateBtn.disabled = true;
|
generateBtn.disabled = true;
|
||||||
setStatus(`正在为 ${memberId} 生成二维码...`);
|
setStatus(`正在生成管理员二维码(member_id=${ADMIN_MEMBER_ID})...`);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await fetch("/api/generate", {
|
const response = await fetch("/api/generate", {
|
||||||
@@ -112,14 +47,14 @@ async function generateQr() {
|
|||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
},
|
},
|
||||||
body: JSON.stringify({ member_id: Number(memberId) }),
|
body: JSON.stringify({ member_id: ADMIN_MEMBER_ID }),
|
||||||
});
|
});
|
||||||
const data = await response.json();
|
const data = await response.json();
|
||||||
if (!response.ok || !data.ok) {
|
if (!response.ok || !data.ok) {
|
||||||
throw new Error(data.error || "生成二维码失败");
|
throw new Error(data.error || "生成二维码失败");
|
||||||
}
|
}
|
||||||
showResult(data);
|
showResult(data);
|
||||||
setStatus(`member_id=${memberId} 生成成功`);
|
setStatus("管理员二维码生成成功");
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
setStatus(error.message || "生成失败", true);
|
setStatus(error.message || "生成失败", true);
|
||||||
} finally {
|
} finally {
|
||||||
@@ -127,8 +62,4 @@ async function generateQr() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
searchInput.addEventListener("input", filterItems);
|
|
||||||
generateBtn.addEventListener("click", generateQr);
|
generateBtn.addEventListener("click", generateQr);
|
||||||
memberSelect.addEventListener("dblclick", generateQr);
|
|
||||||
|
|
||||||
loadFoundIds();
|
|
||||||
|
|||||||
@@ -10,17 +10,11 @@
|
|||||||
<main class="container">
|
<main class="container">
|
||||||
<section class="card">
|
<section class="card">
|
||||||
<h1>MiniApp QR 页面</h1>
|
<h1>MiniApp QR 页面</h1>
|
||||||
<p class="subtitle">从 <code>found_ids.txt</code> 里选择一个 ID,然后请求服务端生成二维码。</p>
|
<p class="subtitle">点击生成管理员二维码</p>
|
||||||
|
|
||||||
<label for="searchInput">筛选</label>
|
|
||||||
<input id="searchInput" type="text" placeholder="输入 ID 或小区名过滤">
|
|
||||||
|
|
||||||
<label for="memberSelect">member_id 列表</label>
|
|
||||||
<select id="memberSelect" size="14"></select>
|
|
||||||
|
|
||||||
<div class="actions">
|
<div class="actions">
|
||||||
<button id="generateBtn" type="button">生成二维码</button>
|
<button id="generateBtn" type="button">点击生成管理员二维码</button>
|
||||||
<span id="statusText" class="status-text">正在加载 ID 列表...</span>
|
<span id="statusText" class="status-text">等待生成</span>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
|||||||
17
web_app.py
17
web_app.py
@@ -2,9 +2,10 @@ import os
|
|||||||
|
|
||||||
from flask import Flask, jsonify, render_template, request
|
from flask import Flask, jsonify, render_template, request
|
||||||
|
|
||||||
from miniapp_qr_poc import generate_member_qr, load_found_ids
|
from miniapp_qr_poc import generate_member_qr
|
||||||
|
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
|
ADMIN_MEMBER_ID = 104891
|
||||||
|
|
||||||
|
|
||||||
@app.get("/")
|
@app.get("/")
|
||||||
@@ -17,24 +18,18 @@ def healthz():
|
|||||||
return jsonify({"ok": True})
|
return jsonify({"ok": True})
|
||||||
|
|
||||||
|
|
||||||
@app.get("/api/found-ids")
|
|
||||||
def api_found_ids():
|
|
||||||
items = load_found_ids()
|
|
||||||
return jsonify({"ok": True, "count": len(items), "items": items})
|
|
||||||
|
|
||||||
|
|
||||||
@app.post("/api/generate")
|
@app.post("/api/generate")
|
||||||
def api_generate():
|
def api_generate():
|
||||||
payload = request.get_json(silent=True)
|
payload = request.get_json(silent=True)
|
||||||
if payload is None:
|
if payload is None:
|
||||||
payload = request.form
|
payload = request.form
|
||||||
|
|
||||||
member_id = payload.get("member_id") if payload else None
|
member_id = ADMIN_MEMBER_ID
|
||||||
if member_id is None or str(member_id).strip() == "":
|
if payload and payload.get("member_id") not in (None, "", ADMIN_MEMBER_ID, str(ADMIN_MEMBER_ID)):
|
||||||
return jsonify({"ok": False, "error": "missing member_id"}), 400
|
return jsonify({"ok": False, "error": f"only member_id={ADMIN_MEMBER_ID} is supported"}), 400
|
||||||
|
|
||||||
try:
|
try:
|
||||||
result = generate_member_qr(int(member_id), include_data_url=True)
|
result = generate_member_qr(member_id, include_data_url=True)
|
||||||
except ValueError as exc:
|
except ValueError as exc:
|
||||||
return jsonify({"ok": False, "error": str(exc)}), 400
|
return jsonify({"ok": False, "error": str(exc)}), 400
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
|
|||||||
Reference in New Issue
Block a user