import type { TransformList, TransformRecord } from '#/api'; /** 处方点评(接口就绪后替换为真实请求) */ export namespace PrescriptionReviewModel { export interface ReviewExpert extends TransformRecord { access: string; name: string; hospitalName: string; phone: string; /** 0 启用,1 禁用 */ status: 0 | 1; institutionId?: string; pid?: string; } /** 点评指标来源:系统内置 / 用户新增 */ export type ReviewIndicatorSource = 'custom' | 'system'; export interface ReviewIndicatorCategory extends TransformRecord { name: string; /** 系统内置分类不可删除 */ source: ReviewIndicatorSource; /** 分类下点评项数量 */ indicatorCount?: number; } export interface ReviewIndicator extends TransformRecord { categoryId: string; categoryName: string; name: string; source: ReviewIndicatorSource; /** 是否关联中药 */ associatedChineseMedicine: boolean; remark?: string; /** 0 启用,1 禁用 */ status: 0 | 1; } } const MOCK_EXPERTS: PrescriptionReviewModel.ReviewExpert[] = [ { id: '1', access: 'za00011', name: '孙明1', hospitalName: '蒋村社区卫生服务中心', phone: '13112342344', status: 1, institutionId: 'org-1', createUser: '张三', createTime: '2023-05-15 13:35', }, { id: '2', access: 'za00012', name: '孙明2', hospitalName: '蒋村社区卫生服务中心', phone: '13156782344', status: 0, institutionId: 'org-1', createUser: '张三', createTime: '2023-05-16 09:20', }, { id: '3', access: 'za00013', name: '李华', hospitalName: '西溪社区卫生服务中心', phone: '13298765432', status: 0, institutionId: 'org-2', createUser: '李四', createTime: '2023-06-01 10:15', }, { id: '4', access: 'za00014', name: '王芳', hospitalName: '西溪社区卫生服务中心', phone: '13387654321', status: 1, institutionId: 'org-2', createUser: '李四', createTime: '2023-06-02 14:40', }, { id: '5', access: 'za00015', name: '赵强', hospitalName: '蒋村社区卫生服务中心', phone: '13567891234', status: 0, institutionId: 'org-1', createUser: '王五', createTime: '2023-07-10 08:50', }, { id: '6', access: 'za00016', name: '周敏', hospitalName: '文新社区卫生服务中心', phone: '13678901234', status: 1, institutionId: 'org-3', createUser: '王五', createTime: '2023-07-11 16:25', }, { id: '7', access: 'za00017', name: '吴磊', hospitalName: '文新社区卫生服务中心', phone: '13789012345', status: 0, institutionId: 'org-3', createUser: '赵六', createTime: '2023-08-05 11:30', }, { id: '8', access: 'za00018', name: '郑洁', hospitalName: '蒋村社区卫生服务中心', phone: '13890123456', status: 0, institutionId: 'org-1', createUser: '赵六', createTime: '2023-08-06 15:45', }, { id: '9', access: 'za00019', name: '钱伟', hospitalName: '西溪社区卫生服务中心', phone: '13901234567', status: 1, institutionId: 'org-2', createUser: '张三', createTime: '2023-09-12 09:10', }, { id: '10', access: 'za00020', name: '孙丽', hospitalName: '文新社区卫生服务中心', phone: '13012345678', status: 0, institutionId: 'org-3', createUser: '李四', createTime: '2023-09-13 13:55', }, ]; function filterExperts( items: PrescriptionReviewModel.ReviewExpert[], query?: Partial, ) { const institutionId = query?.institutionId; if (!institutionId) return items; return items.filter((item) => item.institutionId === String(institutionId)); } /** 点评专家列表(当前为本地 mock,后期对接后端分页接口) */ export function listReviewExpertsMethod( page = 1, size = 10, query?: Partial, ): Promise> { const filtered = filterExperts(MOCK_EXPERTS, query); const start = (page - 1) * size; const items = filtered.slice(start, start + size); return Promise.resolve({ items, total: filtered.length, data: { page, size, total: filtered.length }, }); } /** 点评专家状态更改(当前为本地 mock,后期对接后端接口) */ export function updateReviewExpertStatusMethod( expertId: string, { status }: { status: 0 | 1 }, ) { const expert = MOCK_EXPERTS.find( (item) => item.id === expertId || item.pid === expertId, ); if (!expert) { return Promise.reject(new Error('专家不存在')); } expert.status = status; return Promise.resolve(true); } const MOCK_INDICATOR_CATEGORIES: PrescriptionReviewModel.ReviewIndicatorCategory[] = [ { id: 'cat-1', name: '适应症', source: 'system' }, { id: 'cat-2', name: '用法用量', source: 'system' }, { id: 'cat-3', name: '配伍禁忌', source: 'system' }, { id: 'cat-4', name: '特殊人群禁忌', source: 'system' }, { id: 'cat-5', name: '其他禁忌', source: 'system' }, ]; const MOCK_INDICATORS: PrescriptionReviewModel.ReviewIndicator[] = [ { id: 'ind-1', categoryId: 'cat-1', categoryName: '适应症', name: '病证禁忌', source: 'system', associatedChineseMedicine: false, status: 1, }, { id: 'ind-2', categoryId: 'cat-1', categoryName: '适应症', name: '慎用', source: 'system', associatedChineseMedicine: false, status: 1, }, { id: 'ind-3', categoryId: 'cat-1', categoryName: '适应症', name: '禁用', source: 'system', associatedChineseMedicine: false, status: 1, }, { id: 'ind-4', categoryId: 'cat-1', categoryName: '适应症', name: '忌用', source: 'system', associatedChineseMedicine: false, status: 1, }, { id: 'ind-5', categoryId: 'cat-2', categoryName: '用法用量', name: '超剂量用药', source: 'system', associatedChineseMedicine: false, status: 1, }, { id: 'ind-6', categoryId: 'cat-3', categoryName: '配伍禁忌', name: '十八反十九畏', source: 'system', associatedChineseMedicine: true, status: 0, }, { id: 'ind-7', categoryId: 'cat-1', categoryName: '适应症', name: '点评项1', source: 'custom', associatedChineseMedicine: true, createUser: '陆长林', createTime: '2023-09-23 15:29:38', status: 0, }, { id: 'ind-8', categoryId: 'cat-1', categoryName: '适应症', name: '点评项2', source: 'custom', associatedChineseMedicine: true, createUser: '陆长林', createTime: '2023-09-23 15:29:38', status: 0, }, ]; function getCategoryIndicatorCount(categoryId: string) { return MOCK_INDICATORS.filter((item) => item.categoryId === categoryId).length; } function withCategoryIndicatorCount( categories: PrescriptionReviewModel.ReviewIndicatorCategory[], ) { return categories.map((item) => ({ ...item, indicatorCount: getCategoryIndicatorCount(item.id), })); } function getNextCustomCategoryName() { const prefix = '新加分类'; let index = 1; while ( MOCK_INDICATOR_CATEGORIES.some((item) => item.name === `${prefix}${index}`) ) { index += 1; } return `${prefix}${index}`; } function syncIndicatorCategoryName( indicator: PrescriptionReviewModel.ReviewIndicator, ) { const category = MOCK_INDICATOR_CATEGORIES.find( (item) => item.id === indicator.categoryId, ); indicator.categoryName = category?.name ?? indicator.categoryName; } function filterIndicators( items: PrescriptionReviewModel.ReviewIndicator[], query?: Partial< PrescriptionReviewModel.ReviewIndicator & { categoryId?: string } >, ) { let result = [...items]; if (query?.categoryId) { result = result.filter((item) => item.categoryId === query.categoryId); } if (query?.name?.trim()) { const keyword = query.name.trim(); result = result.filter((item) => item.name.includes(keyword)); } return result; } /** 点评指标分类列表(当前为本地 mock) */ export function listReviewIndicatorCategoriesMethod(): Promise< PrescriptionReviewModel.ReviewIndicatorCategory[] > { return Promise.resolve(withCategoryIndicatorCount([...MOCK_INDICATOR_CATEGORIES])); } /** 新增点评指标分类(当前为本地 mock) */ export function createReviewIndicatorCategoryMethod(name?: string) { const trimmed = (name ?? getNextCustomCategoryName()).trim(); if (!trimmed) { return Promise.reject(new Error('分类名称不能为空')); } if (MOCK_INDICATOR_CATEGORIES.some((item) => item.name === trimmed)) { return Promise.reject(new Error('分类名称已存在')); } const category: PrescriptionReviewModel.ReviewIndicatorCategory = { id: `cat-${Date.now()}`, name: trimmed, source: 'custom', indicatorCount: 0, }; MOCK_INDICATOR_CATEGORIES.push(category); return Promise.resolve(category); } /** 更新点评指标分类名称(当前为本地 mock,系统内置不可改) */ export function updateReviewIndicatorCategoryMethod( categoryId: string, { name }: { name: string }, ) { const category = MOCK_INDICATOR_CATEGORIES.find((item) => item.id === categoryId); if (!category) { return Promise.reject(new Error('分类不存在')); } if (category.source === 'system') { return Promise.reject(new Error('系统内置分类不可修改')); } const trimmed = name.trim(); if (!trimmed) { return Promise.reject(new Error('分类名称不能为空')); } if ( MOCK_INDICATOR_CATEGORIES.some( (item) => item.id !== categoryId && item.name === trimmed, ) ) { return Promise.reject(new Error('分类名称已存在')); } category.name = trimmed; MOCK_INDICATORS.forEach((item) => { if (item.categoryId === categoryId) { item.categoryName = trimmed; } }); return Promise.resolve({ ...category, indicatorCount: getCategoryIndicatorCount(categoryId), }); } /** 点评指标分类排序(当前为本地 mock) */ export function sortReviewIndicatorCategoriesMethod(orderedIds: string[]) { if (orderedIds.length !== MOCK_INDICATOR_CATEGORIES.length) { return Promise.reject(new Error('分类排序数据不完整')); } const categoryMap = new Map( MOCK_INDICATOR_CATEGORIES.map((item) => [item.id, item]), ); const sorted = orderedIds.map((id) => categoryMap.get(id)).filter(Boolean) as PrescriptionReviewModel.ReviewIndicatorCategory[]; if (sorted.length !== MOCK_INDICATOR_CATEGORIES.length) { return Promise.reject(new Error('分类排序数据无效')); } MOCK_INDICATOR_CATEGORIES.splice(0, MOCK_INDICATOR_CATEGORIES.length, ...sorted); return Promise.resolve(withCategoryIndicatorCount([...MOCK_INDICATOR_CATEGORIES])); } /** 删除点评指标分类(当前为本地 mock,系统内置不可删) */ export function deleteReviewIndicatorCategoryMethod(categoryId: string) { const index = MOCK_INDICATOR_CATEGORIES.findIndex( (item) => item.id === categoryId, ); if (index === -1) { return Promise.reject(new Error('分类不存在')); } const category = MOCK_INDICATOR_CATEGORIES[index]; if (!category) { return Promise.reject(new Error('分类不存在')); } if (category.source === 'system') { return Promise.reject(new Error('系统内置分类不可删除')); } const inUse = MOCK_INDICATORS.some((item) => item.categoryId === categoryId); if (inUse) { return Promise.reject(new Error('该分类下存在点评项,无法删除')); } MOCK_INDICATOR_CATEGORIES.splice(index, 1); return Promise.resolve(true); } /** 按分类获取点评指标列表(当前为本地 mock) */ export function listReviewIndicatorsByCategoryMethod(categoryId: string) { const category = MOCK_INDICATOR_CATEGORIES.find((item) => item.id === categoryId); if (!category) { return Promise.reject(new Error('分类不存在')); } return Promise.resolve( MOCK_INDICATORS.filter((item) => item.categoryId === categoryId), ); } /** 点评指标排序(当前为本地 mock,按分类内顺序) */ export function sortReviewIndicatorsMethod( categoryId: string, orderedIds: string[], ) { const categoryIndicators = MOCK_INDICATORS.filter( (item) => item.categoryId === categoryId, ); if (orderedIds.length !== categoryIndicators.length) { return Promise.reject(new Error('点评项排序数据不完整')); } const indicatorMap = new Map(categoryIndicators.map((item) => [item.id, item])); const sorted = orderedIds.map((id) => indicatorMap.get(id)).filter(Boolean) as PrescriptionReviewModel.ReviewIndicator[]; if (sorted.length !== categoryIndicators.length) { return Promise.reject(new Error('点评项排序数据无效')); } const others = MOCK_INDICATORS.filter((item) => item.categoryId !== categoryId); MOCK_INDICATORS.splice(0, MOCK_INDICATORS.length, ...others, ...sorted); return Promise.resolve(sorted); } /** 点评指标列表(当前为本地 mock,后期对接后端分页接口) */ export function listReviewIndicatorsMethod( page = 1, size = 10, query?: Partial< PrescriptionReviewModel.ReviewIndicator & { categoryId?: string } >, ): Promise> { const filtered = filterIndicators(MOCK_INDICATORS, query); const start = (page - 1) * size; const items = filtered.slice(start, start + size); return Promise.resolve({ items, total: filtered.length, data: { page, size, total: filtered.length }, }); } /** 新增点评指标(当前为本地 mock) */ export function createReviewIndicatorMethod( data: Pick< PrescriptionReviewModel.ReviewIndicator, 'categoryId' | 'name' | 'associatedChineseMedicine' | 'remark' | 'status' >, ) { const category = MOCK_INDICATOR_CATEGORIES.find( (item) => item.id === data.categoryId, ); if (!category) { return Promise.reject(new Error('点评项分类不存在')); } const indicator: PrescriptionReviewModel.ReviewIndicator = { id: `ind-${Date.now()}`, categoryId: data.categoryId, categoryName: category.name, name: data.name.trim(), source: 'custom', associatedChineseMedicine: data.associatedChineseMedicine, remark: data.remark, status: data.status ?? 0, createUser: '陆长林', createTime: new Date().toISOString().slice(0, 19).replace('T', ' '), }; MOCK_INDICATORS.push(indicator); return Promise.resolve(indicator); } /** 编辑点评指标(当前为本地 mock,系统内置仅可改部分字段) */ export function updateReviewIndicatorMethod( indicatorId: string, data: Partial< Pick< PrescriptionReviewModel.ReviewIndicator, | 'categoryId' | 'name' | 'associatedChineseMedicine' | 'remark' | 'status' > >, ) { const indicator = MOCK_INDICATORS.find((item) => item.id === indicatorId); if (!indicator) { return Promise.reject(new Error('点评项不存在')); } if (data.categoryId) { indicator.categoryId = data.categoryId; syncIndicatorCategoryName(indicator); } if (data.name !== undefined) indicator.name = data.name.trim(); if (data.associatedChineseMedicine !== undefined) { indicator.associatedChineseMedicine = data.associatedChineseMedicine; } if (data.remark !== undefined) indicator.remark = data.remark; if (data.status !== undefined) indicator.status = data.status; return Promise.resolve(indicator); } /** 删除点评指标(当前为本地 mock,系统内置不可删) */ export function deleteReviewIndicatorMethod(indicatorId: string) { const index = MOCK_INDICATORS.findIndex((item) => item.id === indicatorId); if (index === -1) { return Promise.reject(new Error('点评项不存在')); } const indicator = MOCK_INDICATORS[index]; if (!indicator) { return Promise.reject(new Error('点评项不存在')); } if (indicator.source === 'system') { return Promise.reject(new Error('系统内置点评项不可删除')); } MOCK_INDICATORS.splice(index, 1); return Promise.resolve(true); } /** 点评指标状态更改(当前为本地 mock,后期对接后端接口) */ export function updateReviewIndicatorStatusMethod( indicatorId: string, { status }: { status: 0 | 1 }, ) { const indicator = MOCK_INDICATORS.find((item) => item.id === indicatorId); if (!indicator) { return Promise.reject(new Error('点评项不存在')); } indicator.status = status; return Promise.resolve(true); }