fix: scope whitelist to selected group
This commit is contained in:
+7
-5
@@ -37,7 +37,7 @@ const rulesLoading = ref(false);
|
||||
const ruleKeyword = ref('');
|
||||
const whitelistLoading = ref(false);
|
||||
const whitelistSaving = ref(false);
|
||||
const whitelistForm = reactive({ chat_id: '', user_id: '', username: '', first_name: '', reason: '' });
|
||||
const whitelistForm = reactive({ user_id: '', username: '', first_name: '', reason: '' });
|
||||
const shopForm = reactive({ item_key: '', name: '', cost: 0, stock: -1, desc: '', enabled: true });
|
||||
const shopDialogOpen = ref(false);
|
||||
const lotteryForm = reactive({ id: 0, title: '', prize: '', description: '', condition_type: 'all', condition_value: 0, draw_type: 'people', end_type: 'people', end_value: 3, max_participants: 3, prize_count: 1, remaining_count: 1, draw_at: '', status: 'active' });
|
||||
@@ -256,12 +256,14 @@ async function loadWhitelist() {
|
||||
if (whitelistLoading.value) return;
|
||||
whitelistLoading.value = true;
|
||||
try {
|
||||
if (!selectedChatId.value) { whitelistItems.value = []; return; }
|
||||
const data = await fetchJson(`/api/whitelist${selectedQuery.value}`);
|
||||
whitelistItems.value = data.map((w: WhitelistItem) => ({ ...w, _loading: false }));
|
||||
} catch (e: any) { showToast(`加载白名单失败:${e.message}`); }
|
||||
finally { whitelistLoading.value = false; }
|
||||
}
|
||||
async function saveWhitelist() {
|
||||
if (!selectedChatId.value) return showToast('请先选择群组');
|
||||
const userId = Number(whitelistForm.user_id || 0);
|
||||
if (!userId) return showToast('请填写用户 ID');
|
||||
whitelistSaving.value = true;
|
||||
@@ -270,7 +272,7 @@ async function saveWhitelist() {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
chat_id: whitelistForm.chat_id === '' ? 0 : Number(whitelistForm.chat_id),
|
||||
chat_id: selectedChatId.value,
|
||||
user_id: userId,
|
||||
username: whitelistForm.username,
|
||||
first_name: whitelistForm.first_name,
|
||||
@@ -964,9 +966,9 @@ onBeforeUnmount(() => {
|
||||
|
||||
|
||||
<section v-show="activePage === 'whitelist'" class="tab-page whitelist-page">
|
||||
<SCard class="panel page-panel whitelist-panel" title="🛡️ 白名单管理" :description="`${whitelistItems.length} 个用户 · 命中垃圾时只删消息,不封禁账号`">
|
||||
<SCard class="panel page-panel whitelist-panel" title="🛡️ 白名单管理" :description="`${whitelistItems.length} 个用户 · 仅当前群组生效,命中垃圾时只删消息不封禁`">
|
||||
<div class="whitelist-toolbar">
|
||||
<label><span>群组 ID</span><input v-model="whitelistForm.chat_id" class="form-input" placeholder="0=全局 / 留空=全局" /></label>
|
||||
<div class="scope-chip"><span>当前群组</span><strong>{{ selectedChatId || '-' }}</strong></div>
|
||||
<label><span>用户 ID</span><input v-model="whitelistForm.user_id" class="form-input" placeholder="必填,如 5418812283" /></label>
|
||||
<label><span>用户名</span><input v-model="whitelistForm.username" class="form-input" placeholder="可选,不带 @" /></label>
|
||||
<label><span>昵称</span><input v-model="whitelistForm.first_name" class="form-input" placeholder="可选" /></label>
|
||||
@@ -979,7 +981,7 @@ onBeforeUnmount(() => {
|
||||
<div v-if="!whitelistItems.length" class="empty whitelist-empty">暂无白名单用户</div>
|
||||
<div v-for="item in whitelistItems" :key="item.id" class="table-row">
|
||||
<div><b>@{{ item.username || item.first_name || item.user_id }}</b><small>{{ item.user_id }}</small></div>
|
||||
<span>{{ Number(item.chat_id || 0) === 0 ? '全局' : item.chat_id }}</span>
|
||||
<span>{{ item.chat_id }}</span>
|
||||
<em :title="item.reason">{{ item.reason || '-' }}</em>
|
||||
<small>{{ formatTime(item.updated_at || item.created_at) }}</small>
|
||||
<SButton size="xs" variant="outline" color="destructive" :loading="item._loading" :disabled="item._loading" @click="deleteWhitelist(item)">移出</SButton>
|
||||
|
||||
@@ -640,3 +640,6 @@ body { background: #f3f6fb; }
|
||||
.whitelist-toolbar { grid-template-columns: 1fr; }
|
||||
.whitelist-table { max-height: none; }
|
||||
}
|
||||
|
||||
.scope-chip { height: 36px; display: grid; align-content: center; gap: 1px; padding: 4px 10px; border: 1px solid #e2e8f0; border-radius: 10px; background: #f8fafc; color: #64748b; font-size: 11px; }
|
||||
.scope-chip strong { color: #0f172a; font-size: 12px; line-height: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
||||
|
||||
+6
-6
@@ -988,23 +988,23 @@ async def api_add_message_user_to_whitelist(message_id: int, request: Request):
|
||||
|
||||
|
||||
@app.get("/api/whitelist")
|
||||
async def api_list_whitelist(chat_id: int | None = None, limit: int = Query(default=200, ge=1, le=1000)):
|
||||
qs = Whitelist.filter(enabled=True)
|
||||
if chat_id is not None:
|
||||
qs = qs.filter(Q(chat_id=chat_id) | Q(chat_id=0))
|
||||
async def api_list_whitelist(chat_id: int = Query(...), limit: int = Query(default=200, ge=1, le=1000)):
|
||||
qs = Whitelist.filter(enabled=True, chat_id=chat_id)
|
||||
rows = await qs.order_by("-updated_at").limit(limit).values()
|
||||
return JSONResponse(json_safe(list(rows)))
|
||||
|
||||
|
||||
@app.post("/api/whitelist")
|
||||
async def api_create_whitelist(request: Request):
|
||||
"""手动添加白名单用户。chat_id=0 表示全局白名单。"""
|
||||
"""手动添加当前群组白名单用户。白名单严格按群组隔离。"""
|
||||
data = await safe_json(request)
|
||||
try:
|
||||
user_id = int(data.get("user_id") or 0)
|
||||
chat_id = int(data.get("chat_id") if data.get("chat_id") not in (None, "") else 0)
|
||||
chat_id = int(data.get("chat_id") or 0)
|
||||
except (TypeError, ValueError):
|
||||
return JSONResponse({"ok": False, "error": "chat_id/user_id 必须是数字"}, status_code=400)
|
||||
if not chat_id:
|
||||
return JSONResponse({"ok": False, "error": "chat_id 不能为空,请先选择群组"}, status_code=400)
|
||||
if not user_id:
|
||||
return JSONResponse({"ok": False, "error": "user_id 不能为空"}, status_code=400)
|
||||
username = str(data.get("username") or "").strip().lstrip("@")[:255] or None
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -5,8 +5,8 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<link rel="icon" type="image/svg+xml" href="/static/icon.svg" />
|
||||
<title>TG Spam Guard</title>
|
||||
<script type="module" crossorigin src="/static/assets/index-CHB2F8f5.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="/static/assets/index-dR9FDmUV.css">
|
||||
<script type="module" crossorigin src="/static/assets/index-BElvzQ0F.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="/static/assets/index-DK_IvB6m.css">
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
|
||||
Reference in New Issue
Block a user