diff --git a/src/api/cases.ts b/src/api/cases.ts index 4f05437c..32d89bb3 100644 --- a/src/api/cases.ts +++ b/src/api/cases.ts @@ -362,9 +362,12 @@ function normalizeCase(item: unknown, index: number): CaseListItem { function normalizeAiGenerateResult(data: unknown): AiGenerateCaseResult { const root = getRecord(data) - const payload = root.parse_id || root.parseId ? root : getRecord(root.data) + const payload = root.parse_id || root.parseId || root.case_type || root.caseType || root.title + ? root + : getRecord(root.data) const usage = getRecord(getFirst(payload, ['ai_usage', 'aiUsage'])) - const generatedData = getRecord(payload.data) + const nestedData = getRecord(payload.data) + const generatedData = Object.keys(nestedData).length ? nestedData : payload return { parseId: getString(payload, ['parse_id', 'parseId']), diff --git a/src/api/teacherStudentRelations.ts b/src/api/teacherStudentRelations.ts index 5cf920b0..17a2cb6d 100644 --- a/src/api/teacherStudentRelations.ts +++ b/src/api/teacherStudentRelations.ts @@ -27,15 +27,20 @@ export interface TeacherStudentRelationListResult { } export interface TeacherStudentRelationPayload { - teacher?: number - student?: number + teacher_phone?: string + student_phone?: string relation_type?: string status?: 0 | 1 } export interface CreateTeacherStudentRelationPayload extends TeacherStudentRelationPayload { - teacher: number - student: number + teacher_phone: string + student_phone: string +} + +export interface UpdateTeacherStudentRelationPayload extends TeacherStudentRelationPayload { + teacher_phone: string + student_phone: string } export interface CreateTeacherStudentRelationParams { @@ -46,7 +51,7 @@ export interface CreateTeacherStudentRelationParams { export interface UpdateTeacherStudentRelationParams { token: string id: number - payload: TeacherStudentRelationPayload + payload: UpdateTeacherStudentRelationPayload } export interface DisableTeacherStudentRelationParams { @@ -111,14 +116,14 @@ function getRelatedUser(value: unknown, fallbackRecord: Record, return { id: getString(record, ['id', 'user_id', 'userId']), name: getString(record, ['real_name', 'realName', 'name', 'username']), - phone: getString(record, ['phone', 'mobile']) + phone: getString(record, ['phone', 'mobile', 'username']) } } return { id: typeof value === 'number' || typeof value === 'string' ? String(value) : getString(fallbackRecord, [`${prefix}_id`, `${prefix}Id`]), name: getString(fallbackRecord, [`${prefix}_name`, `${prefix}Name`, `${prefix}_real_name`, `${prefix}RealName`]), - phone: getString(fallbackRecord, [`${prefix}_phone`, `${prefix}Phone`]) + phone: getString(fallbackRecord, [`${prefix}_phone`, `${prefix}Phone`, `${prefix}_username`, `${prefix}Username`]) } } diff --git a/src/components/ChartPanel.vue b/src/components/ChartPanel.vue index e4f310f4..e9b1889f 100644 --- a/src/components/ChartPanel.vue +++ b/src/components/ChartPanel.vue @@ -12,7 +12,7 @@ diff --git a/src/router/index.ts b/src/router/index.ts index 5ced4d03..57602601 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -34,7 +34,14 @@ const routes: RouteRecordRaw[] = [ { path: 'teacher-student-relations', name: 'TeacherStudentRelations', component: () => import('@/views/TeacherStudentRelationsView.vue'), meta: { title: '师生关系管理' } }, { path: 'settings', name: 'Settings', component: () => import('@/views/SettingsView.vue'), meta: { title: '系统配置' } }, { path: 'module/hospital-dashboard', name: 'HospitalDashboard', component: () => import('@/views/HospitalDashboardView.vue'), meta: { title: '医院驾驶舱' } }, + { path: 'module/hospital-data', name: 'HospitalData', component: () => import('@/views/HospitalStatsModuleView.vue'), meta: { title: '运营数据' } }, + { path: 'module/case-usage', name: 'HospitalCaseUsage', component: () => import('@/views/HospitalStatsModuleView.vue'), meta: { title: '病例使用' } }, + { path: 'module/training-stats', name: 'HospitalTrainingStats', component: () => import('@/views/HospitalStatsModuleView.vue'), meta: { title: '训练统计' } }, + { path: 'module/dept-analysis', name: 'HospitalDeptAnalysis', component: () => import('@/views/HospitalStatsModuleView.vue'), meta: { title: '科室分析' } }, + { path: 'module/ability-trend', name: 'HospitalAbilityTrend', component: () => import('@/views/HospitalStatsModuleView.vue'), meta: { title: '能力趋势' } }, + { path: 'module/student-ranking', name: 'HospitalStudentRanking', component: () => import('@/views/HospitalStatsModuleView.vue'), meta: { title: '学生排行' } }, { path: 'module/content-dashboard', name: 'ContentDashboard', component: () => import('@/views/ContentDashboardView.vue'), meta: { title: '内容概览' } }, + { path: 'module/content-stats', name: 'ContentStats', component: () => import('@/views/ContentStatsView.vue'), meta: { title: '内容统计' } }, { path: 'module/teacher-dashboard', name: 'TeacherDashboard', component: () => import('@/views/TeacherDashboardView.vue'), meta: { title: '教学概览' } }, { path: 'module/case-list', redirect: '/cases' }, { path: 'module/case-library', redirect: '/cases' }, diff --git a/src/views/AiCaseGenerateView.vue b/src/views/AiCaseGenerateView.vue index 3f18d23c..f9288ea0 100644 --- a/src/views/AiCaseGenerateView.vue +++ b/src/views/AiCaseGenerateView.vue @@ -44,15 +44,15 @@

生成结果

-

{{ result ? `解析ID:${result.parseId || '-'}` : '等待生成结果返回。' }}

+

{{ resultStatusText }}

- {{ caseTypeLabel(result.caseType) }} + {{ caseTypeLabel(result.caseType || form.case_type) }}
diff --git a/src/views/HospitalDashboardView.vue b/src/views/HospitalDashboardView.vue index 2e2e161c..4d16b76a 100644 --- a/src/views/HospitalDashboardView.vue +++ b/src/views/HospitalDashboardView.vue @@ -84,7 +84,7 @@ diff --git a/src/views/HospitalStatsModuleView.vue b/src/views/HospitalStatsModuleView.vue new file mode 100644 index 00000000..b0c0b3cd --- /dev/null +++ b/src/views/HospitalStatsModuleView.vue @@ -0,0 +1,597 @@ + + + diff --git a/src/views/TeacherStudentRelationsView.vue b/src/views/TeacherStudentRelationsView.vue index c0b5b23b..0a7e4307 100644 --- a/src/views/TeacherStudentRelationsView.vue +++ b/src/views/TeacherStudentRelationsView.vue @@ -15,8 +15,8 @@
- - + + @@ -78,13 +78,13 @@ - - + + - - + + @@ -146,7 +146,7 @@ import { updateTeacherStudentRelation, type CreateTeacherStudentRelationPayload, type TeacherStudentRelationItem, - type TeacherStudentRelationPayload + type UpdateTeacherStudentRelationPayload } from '@/api/teacherStudentRelations' import { useAppStore } from '@/stores/app' @@ -176,15 +176,21 @@ const pagination = reactive({ total: 0 }) const relationForm = reactive({ - teacher: undefined as number | undefined, - student: undefined as number | undefined, + teacher_phone: '', + student_phone: '', relation_type: '指导', status: 1 as 0 | 1 }) const relationRules: FormRules = { - teacher: [{ required: true, message: '请输入带教医生用户ID', trigger: 'blur' }], - student: [{ required: true, message: '请输入学生用户ID', trigger: 'blur' }] + teacher_phone: [ + { required: true, message: '请输入带教医生手机号', trigger: 'blur' }, + { pattern: /^1\d{10}$/, message: '请输入正确的带教医生手机号', trigger: 'blur' } + ], + student_phone: [ + { required: true, message: '请输入学生手机号', trigger: 'blur' }, + { pattern: /^1\d{10}$/, message: '请输入正确的学生手机号', trigger: 'blur' } + ] } const relationDialogTitle = computed(() => (relationMode.value === 'create' ? '新增师生关系' : '编辑师生关系')) @@ -235,16 +241,16 @@ function openCreateDialog() { function openEditDialog(row: TeacherStudentRelationItem) { relationMode.value = 'edit' editingRelation.value = row - relationForm.teacher = Number(row.teacherId) || undefined - relationForm.student = Number(row.studentId) || undefined + relationForm.teacher_phone = row.teacherPhone + relationForm.student_phone = row.studentPhone relationForm.relation_type = row.relationType relationForm.status = row.status relationDialogVisible.value = true } function resetRelationForm() { - relationForm.teacher = undefined - relationForm.student = undefined + relationForm.teacher_phone = '' + relationForm.student_phone = '' relationForm.relation_type = '指导' relationForm.status = 1 editingRelation.value = null @@ -253,33 +259,22 @@ function resetRelationForm() { function buildCreatePayload(): CreateTeacherStudentRelationPayload { return { - teacher: Number(relationForm.teacher), - student: Number(relationForm.student), + teacher_phone: relationForm.teacher_phone.trim(), + student_phone: relationForm.student_phone.trim(), relation_type: relationForm.relation_type.trim(), status: relationForm.status } } -function buildUpdatePayload(): TeacherStudentRelationPayload { - if (!editingRelation.value) { - return {} - } - +function buildUpdatePayload(): UpdateTeacherStudentRelationPayload { const current = { - teacher: Number(relationForm.teacher), - student: Number(relationForm.student), + teacher_phone: relationForm.teacher_phone.trim(), + student_phone: relationForm.student_phone.trim(), relation_type: relationForm.relation_type.trim(), status: relationForm.status } - const original = editingRelation.value - const payload: TeacherStudentRelationPayload = {} - if (current.teacher !== Number(original.teacherId)) payload.teacher = current.teacher - if (current.student !== Number(original.studentId)) payload.student = current.student - if (current.relation_type !== original.relationType) payload.relation_type = current.relation_type - if (current.status !== original.status) payload.status = current.status - - return payload + return current } async function submitRelationForm() { @@ -304,10 +299,6 @@ async function submitRelationForm() { pagination.page = 1 } else if (editingRelation.value) { const payload = buildUpdatePayload() - if (!Object.keys(payload).length) { - ElMessage.warning('没有需要保存的修改') - return - } await updateTeacherStudentRelation({ token: appStore.token, id: editingRelation.value.id,