Files
prop-ai-hr/frontend/src/api/aihr/sop.ts
T
admin c38a723ae4 Merge branch 'codex/brd-release-20260715' into codex/multi-tenant-knowledge-platform
# Conflicts:
#	AGENTS.md
#	README.md
#	backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/domain/AihrPracticeDto.java
#	backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrOrgSyncService.java
#	backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrPracticeSeedService.java
#	backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrUploadQueueService.java
#	backend/ruoyi-modules/ruoyi-aihr/src/test/java/org/dromara/aihr/service/AihrOrgSyncServiceTest.java
#	backend/ruoyi-modules/ruoyi-aihr/src/test/java/org/dromara/aihr/service/AihrPracticeSeedServiceTest.java
#	backend/ruoyi-modules/ruoyi-aihr/src/test/java/org/dromara/aihr/service/AihrUploadQueueServiceTest.java
#	docs/20260708/uni-app用户侧前端重建计划.md
#	docs/API_INTEGRATION.md
#	docs/BRD_IMPLEMENTATION_AUDIT.md
#	docs/BRD_PRODUCTION_MIGRATION_RUNBOOK.md
#	docs/DEMO_ACCEPTANCE.md
#	docs/DEV_SETUP.md
#	docs/FIGMA_IMPLEMENTATION_MATRIX.md
#	docs/README.md
#	frontend/src/views/knowledge/processing.vue
#	mobile-uni/src/pages/supervisor/assign/index.vue
#	mobile-uni/src/pages/supervisor/index/index.vue
#	mobile-uni/src/pages/supervisor/profile/index.vue
#	mobile-uni/src/pages/supervisor/review/index.vue
#	mobile-uni/src/pages/supervisor/reviews/index.vue
#	mobile-uni/src/pages/supervisor/team/index.vue
#	mobile-uni/src/pages/user/cases/index.vue
#	mobile-uni/src/pages/user/practice/index.vue
#	mobile-uni/src/pages/user/profile/index.vue
#	mobile-uni/src/pages/user/sop/index.vue
#	mobile-uni/src/pages/user/today/index.vue
#	mobile-uni/src/types/api.ts
#	scripts/tests/aihr-schema-migrations.test.sh
2026-07-22 08:41:49 +08:00

253 lines
6.0 KiB
TypeScript

import request from '@/utils/request';
type ApiResult<T> = {
code: number;
msg: string;
data: T;
};
export type SopDoc = {
title: string;
desc: string;
hit: string;
type: string;
};
export type SopSnippet = {
title: string;
text: string;
fragmentId?: number | null;
spaceCode?: string | null;
sourceType?: string;
};
export type SopRecord = {
title: string;
category: string;
version: string;
status: string;
owner: string;
summary: string;
source?: 'demo' | 'uploaded' | string;
};
export type SopSearchResponse = {
requestId?: string;
queryText: string;
category: string;
answer: string;
reference: string;
docs: SopDoc[];
snippets: SopSnippet[];
training: string[];
records: SopRecord[];
keyPoints?: string[];
cautions?: string[];
promptVersion?: string | null;
reviewId?: number;
citations?: SopCitation[];
usedSpaceCodes?: string[];
noEvidence?: boolean;
data?: unknown;
};
export type SopCitation = {
spaceCode?: string | null;
sourceType: string;
docId?: string | null;
title: string;
snippet: string;
fragmentId?: number | null;
};
type UnifiedQueryResponse = {
requestId: string;
queryText: string;
answer: string;
citations: SopCitation[];
usedSpaceCodes: string[];
noEvidence: boolean;
promptVersion?: string | null;
legacy?: SopSearchResponse | null;
data?: unknown;
};
export type SopReviewResponse = {
id: number;
usable: boolean | null;
status: string;
reviewedAt: string;
promptVersion?: string | null;
};
export type AnswerFeedbackItem = {
id: number;
queryText: string;
queryNorm: string;
fragmentId: number;
verdict: string;
feedbackReasonCodes?: string | null;
feedbackComment?: string | null;
category: string;
position: string;
source: string;
reviewId?: number | null;
reviewStatus: string;
reviewer?: string | null;
reviewedTime?: string | null;
createTime: string;
updateTime: string;
};
export type AnswerFeedbackReviewResponse = {
id: number;
reviewStatus: string;
reviewer?: string | null;
reviewedTime?: string | null;
};
export type SopUploadResponse = {
docId: string;
ossId: number;
fileName: string;
category: string;
fragments: number;
summary: string;
tags: string[];
snippets: SopSnippet[];
};
export function searchKnowledgeSop(data: {
queryText: string;
category: string;
position?: string;
source?: string;
limit: number;
spaceCodes?: string[];
toolCode?: 'MY_PRACTICE_SUMMARY' | 'TEAM_PRACTICE_SUMMARY';
}): Promise<ApiResult<SopSearchResponse>> {
return request<unknown, ApiResult<UnifiedQueryResponse>>({
url: '/api/knowledge/query',
method: 'post',
data,
headers: { repeatSubmit: false }
}).then((result) => {
const response = result.data;
const legacy = response.legacy || ({} as SopSearchResponse);
const snippets = legacy.snippets?.length
? legacy.snippets
: (response.citations || []).map((item) => ({
title: item.title,
text: item.snippet,
fragmentId: item.fragmentId,
spaceCode: item.spaceCode,
sourceType: item.sourceType
}));
return {
...result,
data: {
...legacy,
requestId: response.requestId,
queryText: response.queryText,
category: legacy.category || data.category || 'sop',
answer: response.answer,
reference: legacy.reference || response.citations.map((item) => item.title).join('、'),
docs: legacy.docs || [],
snippets,
training: legacy.training || [],
records: legacy.records || [],
citations: response.citations || [],
usedSpaceCodes: response.usedSpaceCodes || [],
noEvidence: response.noEvidence,
promptVersion: response.promptVersion,
data: response.data
}
};
});
}
export function uploadKnowledgeDoc(data: FormData): Promise<ApiResult<SopUploadResponse>> {
return request({
url: '/api/knowledge/doc/upload',
method: 'post',
data,
timeout: 180000,
headers: { repeatSubmit: false }
});
}
export function reviewKnowledgeSop(id: number, data: { usable: boolean; reviewer?: string; note?: string }): Promise<ApiResult<SopReviewResponse>> {
return request({
url: `/api/knowledge/reviews/${id}`,
method: 'post',
data,
headers: { repeatSubmit: false }
});
}
export function listAnswerFeedback(status = '待复核', limit = 50): Promise<ApiResult<AnswerFeedbackItem[]>> {
return request({
url: '/api/knowledge/answer-feedback',
method: 'get',
params: { status, limit },
headers: { repeatSubmit: false }
});
}
export function reviewAnswerFeedback(id: number): Promise<ApiResult<AnswerFeedbackReviewResponse>> {
return request({
url: `/api/knowledge/answer-feedback/${id}/review`,
method: 'post',
headers: { repeatSubmit: false }
});
}
export type UploadEnqueueResponse = {
itemId: number;
batchId: string;
fileName: string;
status: string;
};
export type UploadItem = {
id: number;
batchId: string;
fileName: string;
category: string;
spaceCodes: string[];
status: number;
statusLabel: string;
error: string | null;
docId: string | null;
fragmentCount: number | null;
updatedAt: string;
};
/** 批量上传走异步队列:接口只暂存+入队即返回,解析/归类/向量化由后台 worker 处理。 */
export function uploadKnowledgeDocAsync(data: FormData): Promise<ApiResult<UploadEnqueueResponse>> {
return request({
url: '/api/knowledge/doc/upload-async',
method: 'post',
data,
timeout: 60000,
headers: { repeatSubmit: false }
});
}
export function listUploadItems(batchId: string): Promise<ApiResult<UploadItem[]>> {
return request({
url: '/api/knowledge/doc/upload-items',
method: 'get',
params: { batchId },
headers: { repeatSubmit: false }
});
}
export function retryUploadItem(id: number): Promise<ApiResult<UploadItem>> {
return request({
url: `/api/knowledge/doc/upload-items/${id}/retry`,
method: 'post',
headers: { repeatSubmit: false }
});
}