feat(tenant/kol): let KOLs self-subscribe to their own published packages
Add /kol/manage/packages/:id/self-subscription POST/DELETE on the tenant side so a KOL can grant themselves access to their own published package without going through the marketplace approval flow. Reject self-subscribe through the marketplace with a clear error, expose owned_by_current_tenant on package responses, and surface a self_subscription block on KolPackage Response. The admin-web KOL workspace gets 订阅自己 / 取消订阅 entries with matching messaging in the marketplace detail view. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -11,6 +11,8 @@ import {
|
||||
CloudUploadOutlined,
|
||||
InboxOutlined,
|
||||
DeleteOutlined,
|
||||
CheckCircleOutlined,
|
||||
StopOutlined,
|
||||
} from "@ant-design/icons-vue";
|
||||
|
||||
import KolPackageFormModal from "@/components/kol/KolPackageFormModal.vue";
|
||||
@@ -79,6 +81,24 @@ const archivePackageMutation = useMutation({
|
||||
onError: (error) => message.error(formatError(error)),
|
||||
});
|
||||
|
||||
const selfSubscribePackageMutation = useMutation({
|
||||
mutationFn: (id: number) => kolManageApi.selfSubscribePackage(id),
|
||||
onSuccess: () => {
|
||||
message.success("已订阅自己的订阅包");
|
||||
invalidateKolPackageAccess();
|
||||
},
|
||||
onError: (error) => message.error(formatError(error)),
|
||||
});
|
||||
|
||||
const cancelSelfSubscriptionMutation = useMutation({
|
||||
mutationFn: (id: number) => kolManageApi.cancelSelfSubscription(id),
|
||||
onSuccess: () => {
|
||||
message.success("已取消订阅自己的订阅包");
|
||||
invalidateKolPackageAccess();
|
||||
},
|
||||
onError: (error) => message.error(formatError(error)),
|
||||
});
|
||||
|
||||
const deletePackageMutation = useMutation({
|
||||
mutationFn: (id: number) => kolManageApi.deletePackage(id),
|
||||
onSuccess: (_, id) => {
|
||||
@@ -150,6 +170,12 @@ const deletePromptMutation = useMutation({
|
||||
},
|
||||
});
|
||||
|
||||
function invalidateKolPackageAccess() {
|
||||
void queryClient.invalidateQueries({ queryKey: ["kol", "packages"] });
|
||||
void queryClient.invalidateQueries({ queryKey: ["kol", "my-subscription-prompts"] });
|
||||
void queryClient.invalidateQueries({ queryKey: ["workspace"] });
|
||||
}
|
||||
|
||||
const packageInitialValue = computed<Partial<CreateKolPackageRequest> | undefined>(() => {
|
||||
if (!editingPackage.value) return undefined;
|
||||
return {
|
||||
@@ -220,6 +246,18 @@ function packageStatusLabel(status: string) {
|
||||
if (status === "archived") return t("kol.manage.packageStatus.archived");
|
||||
return t("kol.manage.packageStatus.draft");
|
||||
}
|
||||
|
||||
function isSelfSubscribed(pkg: KolPackageSummary) {
|
||||
return pkg.self_subscription?.status === "active";
|
||||
}
|
||||
|
||||
function canSelfSubscribe(pkg: KolPackageSummary) {
|
||||
return pkg.status === "published" && !isSelfSubscribed(pkg);
|
||||
}
|
||||
|
||||
function canCancelSelfSubscription(pkg: KolPackageSummary) {
|
||||
return pkg.self_subscription?.status === "active";
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -267,6 +305,7 @@ function packageStatusLabel(status: string) {
|
||||
>
|
||||
{{ packageStatusLabel(item.status) }}
|
||||
</a-tag>
|
||||
<a-tag v-if="isSelfSubscribed(item)" color="blue" size="small">自己已订阅</a-tag>
|
||||
<span>{{ t("kol.marketplace.prompts", { count: item.prompt_count }) }}</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -290,6 +329,19 @@ function packageStatusLabel(status: string) {
|
||||
>
|
||||
<InboxOutlined /> {{ t('kol.manage.archivePackage') }}
|
||||
</a-menu-item>
|
||||
<a-menu-item
|
||||
v-if="canSelfSubscribe(item)"
|
||||
@click="selfSubscribePackageMutation.mutate(item.id)"
|
||||
>
|
||||
<CheckCircleOutlined /> 订阅自己
|
||||
</a-menu-item>
|
||||
<a-menu-item
|
||||
v-if="canCancelSelfSubscription(item)"
|
||||
danger
|
||||
@click="cancelSelfSubscriptionMutation.mutate(item.id)"
|
||||
>
|
||||
<StopOutlined /> 取消订阅
|
||||
</a-menu-item>
|
||||
<a-menu-divider />
|
||||
<a-menu-item danger @click="handleDeletePackage(item.id)">
|
||||
<DeleteOutlined /> {{ t('common.delete') }}
|
||||
|
||||
Reference in New Issue
Block a user