feat: implement core backend for team owner management with SQLite, auto-add APIs, and a frontend owner list component.

This commit is contained in:
2026-01-30 20:20:35 +08:00
parent 3c5bb04d82
commit 10cda012af
6 changed files with 125 additions and 14 deletions

View File

@@ -16,14 +16,16 @@ const statusColors: Record<string, string> = {
pooled: 'bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-400',
processing: 'bg-purple-100 text-purple-700 dark:bg-purple-900/30 dark:text-purple-400',
invalid: 'bg-red-100 text-red-700 dark:bg-red-900/30 dark:text-red-400',
used: 'bg-gray-100 text-gray-700 dark:bg-gray-900/30 dark:text-gray-400',
}
const statusLabels: Record<string, string> = {
valid: '有效',
registered: '已注册',
pooled: '已入库',
processing: 'processing',
processing: '处理中',
invalid: '无效',
used: '已使用',
}
interface OwnerListProps {
@@ -131,6 +133,24 @@ export default function OwnerList({ onStatsChange }: OwnerListProps) {
}
}
const handleClearUsed = async () => {
if (!confirm('确认清理所有已使用的母号?')) return
try {
const res = await fetch('/api/db/owners/clear-used', { method: 'POST' })
const data = await res.json()
if (data.code === 0) {
alert(data.data.message)
loadOwners()
onStatsChange?.()
} else {
alert(data.message || '清理失败')
}
} catch (e) {
console.error('Failed to clear used:', e)
alert('清理失败')
}
}
const [refetching, setRefetching] = useState(false)
const handleRefetchAccountIds = async () => {
@@ -212,6 +232,7 @@ export default function OwnerList({ onStatsChange }: OwnerListProps) {
<option value="valid"></option>
<option value="registered"></option>
<option value="pooled"></option>
<option value="used">使</option>
<option value="invalid"></option>
</select>
<Button variant="ghost" size="sm" onClick={loadOwners} icon={<RefreshCw className="h-4 w-4" />}>
@@ -239,6 +260,15 @@ export default function OwnerList({ onStatsChange }: OwnerListProps) {
{deleting ? '删除中...' : `删除选中 (${selectedIds.size})`}
</Button>
)}
<Button
variant="ghost"
size="sm"
onClick={handleClearUsed}
icon={<Trash2 className="h-4 w-4" />}
className="text-yellow-600 hover:text-yellow-700"
>
使
</Button>
<Button
variant="ghost"
size="sm"