@@ -289,7 +290,7 @@ function submitDeleteCard() {
{{ item.title }}
- {{ item.reportTypeLabel }}
+ {{ item.reportTypeLabel }} · AI生成
{{ item.content }}
@@ -343,7 +344,7 @@ function submitDeleteCard() {
-
{{ item.copied ? "已复制给老师" : "尚未复制" }}
+
{{ item.copied ? "已复制给老师" : "尚未复制" }} · AI生成
{{ item.content.slice(0, 72) }}{{ item.content.length > 72 ? "…" : "" }}
@@ -382,7 +383,7 @@ function submitDeleteCard() {
-
{{ item.copied ? "已复制" : "尚未复制" }}
+
{{ item.copied ? "已复制" : "尚未复制" }} · AI生成
{{ item.content.slice(0, 72) }}{{ item.content.length > 72 ? "…" : "" }}
diff --git a/ai_knowledge_base_v2/apps/user-client/src/components/SiteFilingFooter.vue b/ai_knowledge_base_v2/apps/user-client/src/components/SiteFilingFooter.vue
new file mode 100644
index 0000000..3b1ccdf
--- /dev/null
+++ b/ai_knowledge_base_v2/apps/user-client/src/components/SiteFilingFooter.vue
@@ -0,0 +1,37 @@
+
+
+
+
+
+
+
diff --git a/ai_knowledge_base_v2/apps/user-client/src/services/api.ts b/ai_knowledge_base_v2/apps/user-client/src/services/api.ts
index 7446f19..d12d8fb 100644
--- a/ai_knowledge_base_v2/apps/user-client/src/services/api.ts
+++ b/ai_knowledge_base_v2/apps/user-client/src/services/api.ts
@@ -6,6 +6,7 @@ import type {
PracticeReviewResult,
LoginResult,
PeriodicReport,
+ PublicSiteConfig,
ShareDraft,
TeacherHelpCard,
UserProfile,
@@ -78,6 +79,7 @@ async function request(path: string, init: RequestInit = {}, options: Request
}
export const api = {
+ publicSiteConfig: () => request("/site/config"),
captcha: () => request("/auth/captcha"),
sendSms: (phone: string, captchaId?: string, captchaCode?: string) =>
request("/auth/sms/send", {
diff --git a/ai_knowledge_base_v2/apps/user-client/src/styles.css b/ai_knowledge_base_v2/apps/user-client/src/styles.css
index 6790757..7b752ee 100644
--- a/ai_knowledge_base_v2/apps/user-client/src/styles.css
+++ b/ai_knowledge_base_v2/apps/user-client/src/styles.css
@@ -1126,6 +1126,14 @@ textarea:focus-visible {
background: var(--chat-bg);
}
+.phone-frame.chat-mode.has-filing {
+ grid-template-rows: auto auto minmax(0, 1fr) auto auto;
+}
+
+.phone-frame.chat-mode.has-filing .chat-composer {
+ padding-bottom: 10px;
+}
+
.chat-header {
position: relative;
z-index: 5;
@@ -1603,6 +1611,7 @@ textarea:focus-visible {
.message-feedback-button { margin-top: 8px; display: inline-flex; align-items: center; gap: 5px; padding: 4px 8px; border: 0; border-radius: 7px; background: transparent; color: var(--chat-weak); font-size: 12px; }
.message-feedback-button:hover { background: rgba(20, 148, 119, 0.08); color: var(--chat-brand-deep); }
+.ai-generated-badge { display: inline-flex; width: fit-content; align-items: center; justify-content: center; margin-top: 7px; padding: 2px 6px; border: 1px solid rgba(31, 118, 93, 0.18); border-radius: 999px; background: #f1f8f5; color: #4f7568; font-size: 10px; font-weight: 700; line-height: 1.4; }
.feedback-dialog p { margin: 0 0 12px; color: var(--chat-muted); line-height: 1.65; }
.feedback-dialog textarea { width: 100%; resize: vertical; padding: 12px; border: 1px solid var(--chat-control-border); border-radius: 10px; font: inherit; }
.feedback-dialog-footer { display: flex; align-items: center; justify-content: space-between; margin-top: 10px; color: var(--chat-weak); font-size: 12px; }
diff --git a/ai_knowledge_base_v2/apps/user-client/src/types/api.ts b/ai_knowledge_base_v2/apps/user-client/src/types/api.ts
index d9013dc..132361e 100644
--- a/ai_knowledge_base_v2/apps/user-client/src/types/api.ts
+++ b/ai_knowledge_base_v2/apps/user-client/src/types/api.ts
@@ -4,6 +4,11 @@ export interface ApiResponse {
data: T;
}
+export interface PublicSiteConfig {
+ filingText: string;
+ filingUrl: string;
+}
+
export interface UserProfile {
id: number;
phone: string;
@@ -75,6 +80,7 @@ export interface PeriodicReport {
periodEnd: string;
title: string;
content: string;
+ aiGenerated: boolean;
status: "pending" | "running" | "success" | "failed" | "empty" | string;
nextRunAt?: string | null;
finishedAt?: string | null;
@@ -87,6 +93,7 @@ export interface TeacherHelpCard {
topicSessionId: number;
summaryId?: number | null;
content: string;
+ aiGenerated: boolean;
source: string;
copied: boolean;
copiedAt?: string | null;
@@ -99,6 +106,7 @@ export interface ShareDraft {
topicSessionId: number;
summaryId?: number | null;
content: string;
+ aiGenerated: boolean;
source: string;
copied: boolean;
copiedAt?: string | null;
diff --git a/ai_knowledge_base_v2/apps/user-client/src/utils/aiGenerated.ts b/ai_knowledge_base_v2/apps/user-client/src/utils/aiGenerated.ts
new file mode 100644
index 0000000..1fadb0d
--- /dev/null
+++ b/ai_knowledge_base_v2/apps/user-client/src/utils/aiGenerated.ts
@@ -0,0 +1,7 @@
+export const AI_GENERATED_NOTICE = "AI生成内容,请结合实际情况核对后使用。";
+
+export function withAiGeneratedNotice(content: string) {
+ const text = content.trim();
+ if (!text || text.includes(AI_GENERATED_NOTICE)) return text;
+ return `${text}\n\n—— ${AI_GENERATED_NOTICE}`;
+}
diff --git a/ai_knowledge_base_v2/docker-compose.dev.yml b/ai_knowledge_base_v2/docker-compose.dev.yml
index 88fbf28..0392515 100644
--- a/ai_knowledge_base_v2/docker-compose.dev.yml
+++ b/ai_knowledge_base_v2/docker-compose.dev.yml
@@ -68,6 +68,10 @@ services:
AGENT_BATCH_POLL_SECONDS: "2"
AGENT_BATCH_STALE_MINUTES: "30"
AGENT_BATCH_WORKER_CONCURRENCY: "10"
+ HUMAN_ATTENTION_WORKER_ENABLED: "true"
+ HUMAN_ATTENTION_WORKER_POLL_SECONDS: "2"
+ HUMAN_ATTENTION_WORKER_STALE_MINUTES: "30"
+ HUMAN_ATTENTION_WORKER_MAX_ATTEMPTS: "3"
JWT_SECRET_KEY: local-dev-secret-change-before-production
MOCK_SMS_ENABLED: "true"
MOCK_SMS_CODE: "123456"
diff --git a/ai_knowledge_base_v2/docker-compose.prod.yml b/ai_knowledge_base_v2/docker-compose.prod.yml
index 2b78af0..0a87482 100644
--- a/ai_knowledge_base_v2/docker-compose.prod.yml
+++ b/ai_knowledge_base_v2/docker-compose.prod.yml
@@ -68,6 +68,10 @@ services:
AGENT_BATCH_POLL_SECONDS: ${AGENT_BATCH_POLL_SECONDS:-2}
AGENT_BATCH_STALE_MINUTES: ${AGENT_BATCH_STALE_MINUTES:-30}
AGENT_BATCH_WORKER_CONCURRENCY: ${AGENT_BATCH_WORKER_CONCURRENCY:-10}
+ HUMAN_ATTENTION_WORKER_ENABLED: ${HUMAN_ATTENTION_WORKER_ENABLED:-true}
+ HUMAN_ATTENTION_WORKER_POLL_SECONDS: ${HUMAN_ATTENTION_WORKER_POLL_SECONDS:-2}
+ HUMAN_ATTENTION_WORKER_STALE_MINUTES: ${HUMAN_ATTENTION_WORKER_STALE_MINUTES:-30}
+ HUMAN_ATTENTION_WORKER_MAX_ATTEMPTS: ${HUMAN_ATTENTION_WORKER_MAX_ATTEMPTS:-3}
JWT_SECRET_KEY: ${JWT_SECRET_KEY:?必须配置 JWT_SECRET_KEY}
CONFIG_ENCRYPTION_KEY: ${CONFIG_ENCRYPTION_KEY:?必须配置 CONFIG_ENCRYPTION_KEY}
MOCK_SMS_ENABLED: "false"