feat(desktop): drop parked review flow, add publish management

SaaS 侧人工审核后才创建 publish job,desktop 不再做二次审核:移除
manual/waiting_user/parked/from_parked 状态机与 LeaseFromParked 查询,
desktop client 只执行发布并新增"发布管理"页(待发布队列 / 历史 / 再次
发送)。同时抽离 @geo/publisher-platforms 共享适配器包、新增 Redis-based
desktop_presence 与 publish_record_support,刷新 admin-web 发布弹窗与
媒体库;plan A / spec 文档同步口径。
This commit is contained in:
2026-04-20 09:52:48 +08:00
parent b16e9f0bd1
commit a617d39a4a
93 changed files with 5519 additions and 3594 deletions
@@ -1,6 +1,6 @@
<script setup lang="ts">
import { computed } from "vue";
import { WarningOutlined } from "@ant-design/icons-vue";
import { ReloadOutlined, WarningOutlined } from "@ant-design/icons-vue";
import StatusBadge from "../components/StatusBadge.vue";
import { useDesktopRuntime } from "../composables/useDesktopRuntime";
@@ -10,11 +10,11 @@ import type { RuntimeAccount } from "../types";
type AccountRow = Readonly<Omit<RuntimeAccount, "tags">> & { tags: readonly string[] };
const { snapshot } = useDesktopRuntime();
const { snapshot, refreshAccounts, loading } = useDesktopRuntime();
const clientsById = computed(
() => new Map((snapshot.value?.clients ?? []).map((item) => [item.id, item])),
);
function handleCardClick() {
void refreshAccounts();
}
const aiAccounts = computed(() =>
(snapshot.value?.accounts ?? []).filter((account) =>
@@ -72,11 +72,19 @@ function sessionTone(account: AccountRow | null) {
}
}
function clientName(account: AccountRow | null): string {
function sessionLabel(account: AccountRow | null): string {
if (!account) {
return "未绑定客户端";
return "无本地缓存";
}
switch (account.sessionState) {
case "hot":
return "活跃会话";
case "warm":
return "本地缓存";
default:
return "冷缓存";
}
return clientsById.value.get(account.clientId)?.deviceName ?? account.clientId;
}
function shortName(value: string): string {
@@ -92,9 +100,15 @@ function shortName(value: string): string {
<p class="eyebrow" style="color: #8c8c8c; font-size: 11px; text-transform: uppercase; letter-spacing: 0.14em; margin-bottom: 6px;">AI PLATFORMS</p>
<h2>AI 平台管理</h2>
<p class="summary" style="margin-top: 10px; line-height: 1.6; color: #595959; font-size: 13px; max-width: 800px;">
AI 平台按每个平台只绑定一个账号建模所以这里不走媒体账号表格而是用一平台一卡片的结构直接看绑定状态会话热度和客户端归属
AI 平台按每个平台只绑定一个账号建模所以这里直接看本机缓存下的绑定状态会话热度和过期情况
</p>
</div>
<div class="media-view__header-actions">
<a-button :loading="loading" @click="refreshAccounts">
<template #icon><ReloadOutlined /></template>
刷新数据
</a-button>
</div>
</div>
<div class="overview-strip border-t">
@@ -129,6 +143,7 @@ function shortName(value: string): string {
:key="platform.id"
class="media-card"
:class="platform.account ? 'media-card--bound' : 'media-card--unbound'"
@click="handleCardClick"
>
<div class="media-card__head">
<div class="media-card__identity">
@@ -156,8 +171,8 @@ function shortName(value: string): string {
<strong>{{ platform.account.platformUid }}</strong>
</div>
<div class="account-row-info">
<span>归属客户端</span>
<strong>{{ clientName(platform.account) }}</strong>
<span>本地会话</span>
<strong>{{ sessionLabel(platform.account) }}</strong>
</div>
<div class="account-row-info">
<span>最近同步</span>