fix: 解决bug
This commit is contained in:
@@ -56,6 +56,7 @@ export interface CreateCaseDraftPayload {
|
||||
title: string
|
||||
case_type: DraftCaseType
|
||||
institution_id?: number
|
||||
department_id?: number
|
||||
department_name?: string
|
||||
traditional?: Record<string, unknown>
|
||||
teaching?: Record<string, unknown>
|
||||
@@ -77,6 +78,30 @@ export interface CreateCaseDraftParams {
|
||||
payload: CreateCaseDraftPayload
|
||||
}
|
||||
|
||||
export interface SaveCaseDraftPayload {
|
||||
title?: string
|
||||
institution_id?: number
|
||||
department_id?: number
|
||||
department_name?: string
|
||||
traditional?: Record<string, unknown>
|
||||
teaching?: Record<string, unknown>
|
||||
exam_items?: CaseExamItemPayload[]
|
||||
scoring_rules?: CaseScoringRulePayload[]
|
||||
difficulty?: string
|
||||
chief_complaint?: string
|
||||
description?: string
|
||||
patient_age?: number
|
||||
patient_gender?: string
|
||||
tags?: string | string[]
|
||||
icd_codes?: string[]
|
||||
estimated_minutes?: number
|
||||
osce_enabled?: boolean
|
||||
}
|
||||
|
||||
export interface SaveCaseDraftParams extends CaseActionParams {
|
||||
payload: SaveCaseDraftPayload
|
||||
}
|
||||
|
||||
export interface AiGenerateCasePayload {
|
||||
prompt: string
|
||||
case_type: DraftCaseType
|
||||
@@ -503,6 +528,20 @@ export async function createCaseDraft(params: CreateCaseDraftParams): Promise<un
|
||||
return parseMutationResponse(response, '新增病例草稿失败')
|
||||
}
|
||||
|
||||
export async function saveCaseDraft(params: SaveCaseDraftParams): Promise<unknown> {
|
||||
const response = await fetch(`/server/api/cms/cases/${params.id}/save-draft/`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
Accept: 'application/json',
|
||||
Authorization: createAuthorization(params.token),
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify(params.payload)
|
||||
})
|
||||
|
||||
return parseMutationResponse(response, '保存病例草稿失败')
|
||||
}
|
||||
|
||||
export async function generateCaseWithAi(params: AiGenerateCaseParams): Promise<AiGenerateCaseResult> {
|
||||
const response = await fetch('/server/api/cms/cases/ai-generate/', {
|
||||
method: 'POST',
|
||||
|
||||
@@ -33,6 +33,17 @@ export interface UserListResult {
|
||||
total: number
|
||||
}
|
||||
|
||||
export interface InstitutionOption {
|
||||
id: number
|
||||
name: string
|
||||
code: string
|
||||
}
|
||||
|
||||
export interface DepartmentOption {
|
||||
id: number
|
||||
name: string
|
||||
}
|
||||
|
||||
export interface CreateUserPayload {
|
||||
phone: string
|
||||
real_name: string
|
||||
@@ -87,6 +98,8 @@ export interface ImportUsersParams {
|
||||
export interface ExportUsersParams extends UserListParams {}
|
||||
|
||||
const listKeys = ['results', 'list', 'rows', 'items', 'records', 'users']
|
||||
const institutionListKeys = ['results', 'list', 'rows', 'items', 'records', 'institutions', 'institution_list', 'institutionList']
|
||||
const departmentListKeys = ['results', 'list', 'rows', 'items', 'records', 'departments', 'department_list', 'departmentList']
|
||||
const totalKeys = ['count', 'total', 'total_count', 'totalCount']
|
||||
|
||||
function parseResponseText(text: string): unknown {
|
||||
@@ -209,6 +222,54 @@ function findUserPayload(data: unknown): { items: unknown[]; total: number } {
|
||||
return { items: [], total: getTotal(record, 0) }
|
||||
}
|
||||
|
||||
function findInstitutionItems(data: unknown): unknown[] {
|
||||
if (Array.isArray(data)) {
|
||||
return data
|
||||
}
|
||||
|
||||
if (!data || typeof data !== 'object') {
|
||||
return []
|
||||
}
|
||||
|
||||
const record = data as Record<string, unknown>
|
||||
for (const key of institutionListKeys) {
|
||||
const value = record[key]
|
||||
if (Array.isArray(value)) {
|
||||
return value
|
||||
}
|
||||
}
|
||||
|
||||
if (record.data && typeof record.data === 'object') {
|
||||
return findInstitutionItems(record.data)
|
||||
}
|
||||
|
||||
return []
|
||||
}
|
||||
|
||||
function findDepartmentItems(data: unknown): unknown[] {
|
||||
if (Array.isArray(data)) {
|
||||
return data
|
||||
}
|
||||
|
||||
if (!data || typeof data !== 'object') {
|
||||
return []
|
||||
}
|
||||
|
||||
const record = data as Record<string, unknown>
|
||||
for (const key of departmentListKeys) {
|
||||
const value = record[key]
|
||||
if (Array.isArray(value)) {
|
||||
return value
|
||||
}
|
||||
}
|
||||
|
||||
if (record.data && typeof record.data === 'object') {
|
||||
return findDepartmentItems(record.data)
|
||||
}
|
||||
|
||||
return []
|
||||
}
|
||||
|
||||
function normalizeUser(item: unknown, index: number): UserListItem {
|
||||
const record = item && typeof item === 'object' ? (item as Record<string, unknown>) : {}
|
||||
const name = getString(record, ['name', 'real_name', 'realName', 'nickname', 'username'], `用户${index + 1}`)
|
||||
@@ -235,6 +296,51 @@ function normalizeUser(item: unknown, index: number): UserListItem {
|
||||
}
|
||||
}
|
||||
|
||||
function normalizeInstitutionOption(item: unknown): InstitutionOption | null {
|
||||
if (typeof item === 'number' || (typeof item === 'string' && Number.isFinite(Number(item)))) {
|
||||
const id = Number(item)
|
||||
return { id, name: `机构 ${id}`, code: '' }
|
||||
}
|
||||
|
||||
if (!item || typeof item !== 'object') {
|
||||
return null
|
||||
}
|
||||
|
||||
const record = item as Record<string, unknown>
|
||||
const id = Number(getString(record, ['id', 'institution_id', 'institutionId', 'value', 'pk'], ''))
|
||||
if (!Number.isFinite(id) || id <= 0) {
|
||||
return null
|
||||
}
|
||||
|
||||
return {
|
||||
id,
|
||||
name: getString(record, ['name', 'institution_name', 'institutionName', 'hospital_name', 'hospitalName', 'label', 'title'], `机构 ${id}`),
|
||||
code: getString(record, ['code', 'institution_code', 'institutionCode'], '')
|
||||
}
|
||||
}
|
||||
|
||||
function normalizeDepartmentOption(item: unknown): DepartmentOption | null {
|
||||
if (typeof item === 'number' || (typeof item === 'string' && Number.isFinite(Number(item)))) {
|
||||
const id = Number(item)
|
||||
return { id, name: `科室 ${id}` }
|
||||
}
|
||||
|
||||
if (!item || typeof item !== 'object') {
|
||||
return null
|
||||
}
|
||||
|
||||
const record = item as Record<string, unknown>
|
||||
const id = Number(getString(record, ['id', 'department_id', 'departmentId', 'value', 'pk'], ''))
|
||||
if (!Number.isFinite(id) || id <= 0) {
|
||||
return null
|
||||
}
|
||||
|
||||
return {
|
||||
id,
|
||||
name: getString(record, ['name', 'department_name', 'departmentName', 'label', 'title'], `科室 ${id}`)
|
||||
}
|
||||
}
|
||||
|
||||
function createAuthorization(token: string) {
|
||||
return /^Bearer\s+/i.test(token) ? token : `Bearer ${token}`
|
||||
}
|
||||
@@ -338,6 +444,66 @@ export async function fetchUsers(params: UserListParams): Promise<UserListResult
|
||||
}
|
||||
}
|
||||
|
||||
export async function fetchInstitutionList(token: string): Promise<InstitutionOption[]> {
|
||||
const response = await fetch('/server/api/user/institution_list/', {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
Accept: 'application/json',
|
||||
Authorization: createAuthorization(token)
|
||||
}
|
||||
})
|
||||
const text = await response.text()
|
||||
const data = parseResponseText(text)
|
||||
|
||||
if (!response.ok) {
|
||||
const message = getMessageFromResponse(data) || '获取机构列表失败'
|
||||
throw new Error(message)
|
||||
}
|
||||
|
||||
const seen = new Set<number>()
|
||||
return findInstitutionItems(data)
|
||||
.map(normalizeInstitutionOption)
|
||||
.filter((item): item is InstitutionOption => {
|
||||
if (!item || seen.has(item.id)) {
|
||||
return false
|
||||
}
|
||||
seen.add(item.id)
|
||||
return true
|
||||
})
|
||||
}
|
||||
|
||||
export async function fetchMyDepartments(token: string, institutionId?: number): Promise<DepartmentOption[]> {
|
||||
const query = new URLSearchParams()
|
||||
if (institutionId) {
|
||||
query.set('institution_id', String(institutionId))
|
||||
}
|
||||
const response = await fetch(`/server/api/user/my_departments/${query.toString() ? `?${query.toString()}` : ''}`, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
Accept: 'application/json',
|
||||
Authorization: createAuthorization(token)
|
||||
}
|
||||
})
|
||||
const text = await response.text()
|
||||
const data = parseResponseText(text)
|
||||
|
||||
if (!response.ok) {
|
||||
const message = getMessageFromResponse(data) || '获取科室列表失败'
|
||||
throw new Error(message)
|
||||
}
|
||||
|
||||
const seen = new Set<number>()
|
||||
return findDepartmentItems(data)
|
||||
.map(normalizeDepartmentOption)
|
||||
.filter((item): item is DepartmentOption => {
|
||||
if (!item || seen.has(item.id)) {
|
||||
return false
|
||||
}
|
||||
seen.add(item.id)
|
||||
return true
|
||||
})
|
||||
}
|
||||
|
||||
export async function createUser(params: CreateUserParams): Promise<unknown> {
|
||||
const response = await fetch('/server/api/cms/users/', {
|
||||
method: 'POST',
|
||||
|
||||
Reference in New Issue
Block a user