334 lines
14 KiB
JavaScript
Raw Normal View History

2026-01-22 15:54:15 +08:00
import dayjs from 'dayjs';
const DB_KEY = 'ykt_case_archive_detail_mockdb_v1';
export const VISIT_RECORD_TEMPLATES = [
{
templateType: 'outpatient',
templateName: '门诊记录',
templateList: [
{ title: 'visitTime', name: '就诊日期', type: 'date', required: true, format: 'YYYY-MM-DD' },
{ title: 'corpName', name: '就诊机构', type: 'input', required: false, wordLimit: 30, inputType: 'text' },
{ title: 'deptName', name: '科室', type: 'input', required: false, wordLimit: 30, inputType: 'text' },
{ title: 'doctor', name: '医生', type: 'input', required: false, wordLimit: 30, inputType: 'text' },
{ title: 'diagnosisName', name: '诊断', type: 'textarea', required: false, wordLimit: 200 },
{ title: 'summary', name: '摘要', type: 'textarea', required: false, wordLimit: 200 },
],
},
{
templateType: 'inhospital',
templateName: '住院记录',
templateList: [
{ title: 'inhospitalDate', name: '入院日期', type: 'date', required: true, format: 'YYYY-MM-DD' },
{ title: 'corpName', name: '住院机构', type: 'input', required: false, wordLimit: 30, inputType: 'text' },
{ title: 'diagnosisName', name: '诊断', type: 'textarea', required: false, wordLimit: 200 },
{ title: 'summary', name: '摘要', type: 'textarea', required: false, wordLimit: 200 },
],
},
{
templateType: 'physicalExaminationTemplate',
templateName: '体检记录',
templateList: [
{ title: 'inspectDate', name: '体检日期', type: 'date', required: true, format: 'YYYY-MM-DD' },
{ title: 'corpName', name: '体检机构', type: 'input', required: false, wordLimit: 30, inputType: 'text' },
{ title: 'inspectPakageName', name: '体检套餐', type: 'input', required: false, wordLimit: 50, inputType: 'text' },
{ title: 'positiveFind', name: '阳性发现', type: 'textarea', required: false, wordLimit: 300 },
{ title: 'summary', name: '摘要', type: 'textarea', required: false, wordLimit: 200 },
],
},
];
export function getVisitRecordTemplates() {
return VISIT_RECORD_TEMPLATES.map((i) => ({ templateType: i.templateType, name: i.templateName, templateList: i.templateList }));
}
export function getVisitRecordTemplate(templateType) {
return VISIT_RECORD_TEMPLATES.find((i) => i.templateType === templateType) || null;
}
function safeParse(json) {
try {
return JSON.parse(json);
} catch {
return null;
}
}
function getDb() {
const raw = uni.getStorageSync(DB_KEY);
const db = raw && typeof raw === 'string' ? safeParse(raw) : raw;
const next = db && typeof db === 'object' ? db : {};
next.visitRecordsByArchiveId = next.visitRecordsByArchiveId || {};
next.serviceRecordsByArchiveId = next.serviceRecordsByArchiveId || {};
next.followupsByArchiveId = next.followupsByArchiveId || {};
return next;
}
function setDb(db) {
uni.setStorageSync(DB_KEY, JSON.stringify(db));
}
function uid(prefix) {
return `${prefix}_${Date.now()}_${Math.random().toString(16).slice(2)}`;
}
export function ensureSeed(archiveId, archive) {
if (!archiveId) return;
const db = getDb();
if (!Array.isArray(db.visitRecordsByArchiveId[archiveId]) || db.visitRecordsByArchiveId[archiveId].length === 0) {
const now = Date.now();
db.visitRecordsByArchiveId[archiveId] = [
{
_id: uid('mr'),
medicalType: 'outpatient',
tempName: '门诊记录',
templateType: 'outpatient',
sortTime: now - 1000 * 60 * 60 * 24 * 2,
visitTime: dayjs(now - 1000 * 60 * 60 * 24 * 2).format('YYYY-MM-DD'),
corpName: '某某医院',
deptName: '口腔科',
doctor: '李医生',
diagnosisName: '牙列不齐mock',
summary: '初诊:拍片、取模,制定治疗方案。',
createTime: now - 1000 * 60 * 60 * 24 * 2,
creatorName: '李医生',
},
{
_id: uid('mr'),
medicalType: 'inhospital',
tempName: '住院记录',
templateType: 'inhospital',
sortTime: now - 1000 * 60 * 60 * 24 * 15,
inhospitalDate: dayjs(now - 1000 * 60 * 60 * 24 * 15).format('YYYY-MM-DD'),
corpName: '某某医院',
diagnosisName: '术后复查mock',
summary: '复诊:术后复查,恢复良好。',
createTime: now - 1000 * 60 * 60 * 24 * 15,
creatorName: '王护士',
},
];
}
if (!Array.isArray(db.serviceRecordsByArchiveId[archiveId]) || db.serviceRecordsByArchiveId[archiveId].length === 0) {
const now = Date.now();
db.serviceRecordsByArchiveId[archiveId] = Array.from({ length: 18 }).map((_, idx) => {
const eventType =
idx % 5 === 0 ? 'questionnaire' : idx % 4 === 0 ? 'article' : idx % 3 === 0 ? 'sms' : 'phone';
const executionTime = now - 1000 * 60 * 60 * (idx * 6 + 3);
const executeTeamId = idx % 2 === 0 ? 'team_1' : 'team_2';
const executeTeamName = executeTeamId === 'team_1' ? '口腔一科(示例)' : '正畸团队(示例)';
return {
_id: uid('sr'),
eventType,
taskContent: `服务内容示例 #${idx + 1}:这里是任务描述,支持长文本展开收起。`,
result: idx % 7 === 0 ? '已联系患者,已确认到院时间。' : '',
executorName: idx % 2 === 0 ? '李医生' : '王护士',
executeTeamId,
executeTeamName,
executionTime,
pannedEventSendFile:
eventType === 'article'
? { type: 'article', url: 'https://example.com/article/1' }
: eventType === 'questionnaire'
? { type: 'questionnaire', surveryId: 'q_1' }
: null,
archiveName: archive?.name || '',
};
});
}
if (!Array.isArray(db.followupsByArchiveId[archiveId]) || db.followupsByArchiveId[archiveId].length === 0) {
const now = Date.now();
db.followupsByArchiveId[archiveId] = Array.from({ length: 22 }).map((_, idx) => {
const plannedExecutionTime = now + 1000 * 60 * 60 * 24 * ((idx % 9) - 2);
const createTime = now - 1000 * 60 * 60 * (idx * 5 + 2);
const statusPool = ['processing', 'notStart', 'treated', 'cancelled', 'expired'];
const status = statusPool[idx % statusPool.length];
const eventTypePool = ['followup', 'revisit', 'questionnaire', 'other'];
const eventType = eventTypePool[idx % eventTypePool.length];
const executeTeamId = idx % 2 === 0 ? 'team_1' : 'team_2';
const executeTeamName = executeTeamId === 'team_1' ? '口腔一科(示例)' : '正畸团队(示例)';
return {
_id: uid('td'),
plannedExecutionTime,
planDate: dayjs(plannedExecutionTime).format('YYYY-MM-DD'),
createTime,
createTimeStr: dayjs(createTime).format('YYYY-MM-DD HH:mm'),
executorName: idx % 2 === 0 ? '李医生' : '王护士',
executeTeamId,
executeTeamName,
creatorName: idx % 3 === 0 ? '系统' : '管理员A',
status,
eventType,
eventTypeLabel:
eventType === 'followup' ? '回访' : eventType === 'revisit' ? '复诊提醒' : eventType === 'questionnaire' ? '问卷' : '其他',
eventStatusLabel:
status === 'processing'
? '待处理'
: status === 'notStart'
? '未开始'
: status === 'treated'
? '已完成'
: status === 'cancelled'
? '已取消'
: '已过期',
taskContent: `回访任务示例 #${idx + 1}:电话回访/提醒到院等。`,
result: status === 'treated' ? '已完成回访,患者反馈良好。' : '',
archiveName: archive?.name || '',
};
});
}
setDb(db);
}
export function queryVisitRecords({ archiveId, medicalType = 'ALL', date = '' }) {
const db = getDb();
const list = Array.isArray(db.visitRecordsByArchiveId[archiveId]) ? db.visitRecordsByArchiveId[archiveId] : [];
const withDate = list.map((i) => ({
...i,
dateStr: i.sortTime ? dayjs(i.sortTime).format('YYYY-MM-DD') : '',
}));
const matchType = medicalType === 'ALL' ? withDate : withDate.filter((i) => i.medicalType === medicalType);
const matchDate = date ? matchType.filter((i) => i.dateStr === date) : matchType;
return matchDate.sort((a, b) => (b.sortTime || 0) - (a.sortTime || 0));
}
export function getVisitRecord({ archiveId, id }) {
const db = getDb();
const list = Array.isArray(db.visitRecordsByArchiveId[archiveId]) ? db.visitRecordsByArchiveId[archiveId] : [];
return list.find((i) => i._id === id) || null;
}
export function upsertVisitRecord({ archiveId, record }) {
const db = getDb();
const list = Array.isArray(db.visitRecordsByArchiveId[archiveId]) ? db.visitRecordsByArchiveId[archiveId] : [];
const next = { ...record };
if (!next._id) next._id = uid('mr');
if (!next.sortTime) next.sortTime = Date.now();
if (!next.createTime) next.createTime = Date.now();
const idx = list.findIndex((i) => i._id === next._id);
if (idx >= 0) list[idx] = { ...list[idx], ...next };
else list.unshift(next);
db.visitRecordsByArchiveId[archiveId] = list;
setDb(db);
return next;
}
export function removeVisitRecord({ archiveId, id }) {
const db = getDb();
const list = Array.isArray(db.visitRecordsByArchiveId[archiveId]) ? db.visitRecordsByArchiveId[archiveId] : [];
db.visitRecordsByArchiveId[archiveId] = list.filter((i) => i._id !== id);
setDb(db);
}
export function queryServiceRecords({ archiveId, page = 1, pageSize = 10, eventType = 'ALL', teamId = 'ALL', dateRange = [] }) {
const db = getDb();
const list = Array.isArray(db.serviceRecordsByArchiveId[archiveId]) ? db.serviceRecordsByArchiveId[archiveId] : [];
let filtered = [...list];
if (eventType !== 'ALL') filtered = filtered.filter((i) => i.eventType === eventType);
if (teamId !== 'ALL') filtered = filtered.filter((i) => i.executeTeamId === teamId);
if (Array.isArray(dateRange) && dateRange.length === 2 && dateRange[0] && dateRange[1]) {
filtered = filtered.filter((i) => {
const d = i.executionTime ? dayjs(i.executionTime).format('YYYY-MM-DD') : '';
return d >= dateRange[0] && d <= dateRange[1];
});
}
filtered.sort((a, b) => (b.executionTime || 0) - (a.executionTime || 0));
const total = filtered.length;
const pages = Math.ceil(total / pageSize) || 1;
const start = (page - 1) * pageSize;
const slice = filtered.slice(start, start + pageSize);
return { list: slice, total, pages };
}
export function getServiceRecord({ archiveId, id }) {
const db = getDb();
const list = Array.isArray(db.serviceRecordsByArchiveId[archiveId]) ? db.serviceRecordsByArchiveId[archiveId] : [];
return list.find((i) => i._id === id) || null;
}
export function upsertServiceRecord({ archiveId, record }) {
const db = getDb();
const list = Array.isArray(db.serviceRecordsByArchiveId[archiveId]) ? db.serviceRecordsByArchiveId[archiveId] : [];
const next = { ...record };
if (!next._id) next._id = uid('sr');
if (!next.executionTime) next.executionTime = Date.now();
const idx = list.findIndex((i) => i._id === next._id);
if (idx >= 0) list[idx] = { ...list[idx], ...next };
else list.unshift(next);
db.serviceRecordsByArchiveId[archiveId] = list;
setDb(db);
return next;
}
export function removeServiceRecord({ archiveId, id }) {
const db = getDb();
const list = Array.isArray(db.serviceRecordsByArchiveId[archiveId]) ? db.serviceRecordsByArchiveId[archiveId] : [];
db.serviceRecordsByArchiveId[archiveId] = list.filter((i) => i._id !== id);
setDb(db);
}
export function queryFollowups({ archiveId, page = 1, pageSize = 10, status = 'all', isMy = false, eventTypes = [], teamId = 'ALL', planRange = ['', ''] }) {
const db = getDb();
const list = Array.isArray(db.followupsByArchiveId[archiveId]) ? db.followupsByArchiveId[archiveId] : [];
let filtered = [...list];
if (status !== 'all') filtered = filtered.filter((i) => i.status === status);
if (isMy) filtered = filtered.filter((i) => i.executorName === '李医生');
if (Array.isArray(eventTypes) && eventTypes.length) filtered = filtered.filter((i) => eventTypes.includes(i.eventType));
if (teamId !== 'ALL') filtered = filtered.filter((i) => i.executeTeamId === teamId);
if (planRange && (planRange[0] || planRange[1])) {
if (planRange[0]) filtered = filtered.filter((i) => i.planDate >= planRange[0]);
if (planRange[1]) filtered = filtered.filter((i) => i.planDate <= planRange[1]);
}
filtered.sort((a, b) => (b.plannedExecutionTime || 0) - (a.plannedExecutionTime || 0));
const total = filtered.length;
const pages = Math.ceil(total / pageSize) || 1;
const start = (page - 1) * pageSize;
const slice = filtered.slice(start, start + pageSize);
return { list: slice, total, pages };
}
export function getFollowup({ archiveId, id }) {
const db = getDb();
const list = Array.isArray(db.followupsByArchiveId[archiveId]) ? db.followupsByArchiveId[archiveId] : [];
return list.find((i) => i._id === id) || null;
}
export function upsertFollowup({ archiveId, followup }) {
const db = getDb();
const list = Array.isArray(db.followupsByArchiveId[archiveId]) ? db.followupsByArchiveId[archiveId] : [];
const next = { ...followup };
if (!next._id) next._id = uid('td');
if (!next.plannedExecutionTime) next.plannedExecutionTime = Date.now();
next.planDate = dayjs(next.plannedExecutionTime).format('YYYY-MM-DD');
if (!next.createTime) next.createTime = Date.now();
next.createTimeStr = dayjs(next.createTime).format('YYYY-MM-DD HH:mm');
const idx = list.findIndex((i) => i._id === next._id);
if (idx >= 0) list[idx] = { ...list[idx], ...next };
else list.unshift(next);
db.followupsByArchiveId[archiveId] = list;
setDb(db);
return next;
}
export function removeFollowup({ archiveId, id }) {
const db = getDb();
const list = Array.isArray(db.followupsByArchiveId[archiveId]) ? db.followupsByArchiveId[archiveId] : [];
db.followupsByArchiveId[archiveId] = list.filter((i) => i._id !== id);
setDb(db);
}