Files
api_health/models/schema/escort_record.js
2026-05-25 12:46:14 +08:00

305 lines
9.3 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"use strict";
import mongoose from "mongoose";
/**
* 陪诊记录Schema定义
*
* 用于记录和管理陪诊服务全流程数据,包含以下主要分类:
* - 基础信息userId订单提交用户
* - 患者信息patient姓名、电话、性别、年龄、身份证号
* - 陪诊服务escort服务ID、服务名称
* - 就诊信息hospital医院省份、名称、地址、科室、医生、病历号
* - 时间安排schedule预约时间、开始时间、结束时间、时长
* - 陪诊员信息attendant陪诊员ID、姓名
* - 费用信息payment总费用、已支付、支付状态
* - 备注信息notes患者备注、陪诊记录、就诊摘要
* - 状态信息status陪诊状态
* - 元数据meta创建时间、更新时间
*/
const EscortRecordSchema = mongoose.Schema(
{
/**
* 提交订单的用户ID订单创建者
* @type {ObjectId}
* @ref user
*/
userId: {
type: mongoose.Schema.Types.ObjectId,
ref: "user",
index: true,
comment: "提交订单用户ID"
},
/**
* 患者信息 - 就诊患者的基本信息
*/
patient: {
name: { type: String, default: "", comment: "患者姓名" },
mobile: { type: String, default: "", comment: "患者联系电话" },
sex: { type: String, enum: ["male", "female"], comment: "患者性别" },
age: { type: Number, default: 0, comment: "患者年龄" },
idnumber: { type: String, default: "", comment: "患者身份证号" },
},
/**
* 陪诊服务信息 - 选择的陪诊服务配置
*/
escort: {
serviceId: { type: Number, default: -1, comment: "陪诊服务ID" },
serviceName: { type: String, default: "", comment: "陪诊服务名称" },
},
/**
* 就诊信息 - 医院和科室相关信息
*/
hospital: {
province: { type: String, default: "", comment: "就诊医院省份" },
name: { type: String, default: "", comment: "就诊医院名称" },
address: { type: String, default: "", comment: "医院详细地址" },
department: { type: String, default: "", comment: "就诊科室" },
doctor: { type: String, default: "", comment: "就诊医生" },
medicalRecordNo: { type: String, default: "", comment: "病历号" },
},
/**
* 时间信息 - 陪诊服务的时间安排
*/
schedule: {
date: { type: Date, default: Date.now, comment: "预约就诊日期" },
startTime: { type: String, default: "", comment: "陪诊实际开始时间" },
endTime: { type: String, default: "", comment: "陪诊实际结束时间" },
duration: { type: Number, default: 60, comment: "陪诊时长(分钟)" },
},
/**
* 陪诊员信息 - 为患者提供服务的陪诊员
*/
attendant: {
id: {
type: mongoose.Schema.Types.ObjectId,
ref: "user",
index: true,
comment: "陪诊员用户ID"
},
name: { type: String, default: "", comment: "陪诊员姓名" },
sex: { type: String, enum: ["none", "male", "female"], comment: "陪诊员性别" },
},
/**
* 费用信息 - 服务费用相关
*/
payment: {
totalFee: { type: Number, default: 0, comment: "陪诊服务总费用(元)" },
paidFee: { type: Number, default: 0, comment: "已支付费用(元)" },
status: {
type: String,
enum: ["unpaid", "partial", "paid", "refunded"],
default: "unpaid",
comment: "支付状态:未支付、部分支付、已支付、已退款",
},
},
/**
* 备注信息 - 陪诊过程中的记录
*/
notes: {
patientNote: { type: String, default: "", comment: "患者备注/特殊需求" },
escortNote: { type: String, default: "", comment: "陪诊员服务记录" },
medicalSummary: { type: String, default: "", comment: "就诊摘要" },
},
/**
* 陪诊状态
* - pending: 待确认 - 订单已创建,等待确认
* - confirmed: 已确认 - 订单已确认,等待服务
* - in_progress: 进行中 - 陪诊服务正在进行
* - completed: 已完成 - 陪诊服务已完成
* - cancelled: 已取消 - 订单已取消
*/
status: {
type: String,
enum: ["pending", "confirmed", "in_progress", "completed", "cancelled"],
default: "pending",
comment: "陪诊状态:待确认、已确认、进行中、已完成、已取消",
},
/**
* 元数据 - 系统管理信息
*/
meta: {
createtime: { type: Date, default: Date.now, comment: "创建时间" },
updatetime: { type: Date, default: Date.now, comment: "更新时间" },
},
},
{
minimize: false,
strict: false,
collection: "escort_record",
timestamps: false,
}
);
/**
* 根据用户ID查找陪诊记录
*
* @param {ObjectId} userId - 订单提交用户ID
* @param {Object} options - 查询选项
* @param {number} [options.page=1] - 页码
* @param {number} [options.pageSize=20] - 每页数量
* @param {string} [options.status] - 状态筛选
* @param {Function} [cb] - 可选的回调函数
* @returns {Promise<Array>} 陪诊记录列表(按预约日期倒序)
*/
EscortRecordSchema.statics.findRecordsByUser = async function (userId, options = {}, cb) {
const { page = 1, pageSize = 20, status } = options;
const filter = { userId };
if (status) {
filter.status = status;
}
const skip = (page - 1) * pageSize;
return await this.find(filter)
.sort({ "schedule.date": -1 })
.skip(skip)
.limit(pageSize)
.exec(cb);
};
/**
* 根据陪诊员ID查找陪诊记录
*
* @param {ObjectId} attendantId - 陪诊员用户ID
* @param {Object} options - 查询选项
* @param {number} [options.page=1] - 页码
* @param {number} [options.pageSize=20] - 每页数量
* @param {string} [options.status] - 状态筛选
* @param {Function} [cb] - 可选的回调函数
* @returns {Promise<Array>} 陪诊记录列表(按预约日期倒序)
*/
EscortRecordSchema.statics.findRecordsByAttendant = async function (attendantId, options = {}, cb) {
const { page = 1, pageSize = 20, status } = options;
const filter = { "attendant.id": attendantId };
if (status) {
filter.status = status;
}
const skip = (page - 1) * pageSize;
return await this.find(filter)
.sort({ "schedule.date": -1 })
.skip(skip)
.limit(pageSize)
.exec(cb);
};
/**
* 创建陪诊记录
*
* @param {Object} record - 陪诊记录对象
* @param {Function} [cb] - 可选的回调函数
* @returns {Promise<Object>} 创建的陪诊记录
*/
EscortRecordSchema.statics.createRecord = async function (record, cb) {
record.meta = {
createtime: Date.now(),
updatetime: Date.now(),
};
const newRecord = new this(record);
return await newRecord.save(cb);
};
/**
* 更新陪诊记录
*
* @param {ObjectId} id - 记录ID
* @param {Object} update - 要更新的字段
* @param {Function} [cb] - 可选的回调函数
* @returns {Promise<Object|null>} 更新后的记录失败返回null
*/
EscortRecordSchema.statics.updateRecord = async function (id, update, cb) {
try {
update["meta.updatetime"] = Date.now();
return await this.findByIdAndUpdate(id, { $set: update }, { new: true }, cb);
} catch (error) {
console.error("更新陪诊记录失败:", error);
return null;
}
};
/**
* 根据ID查找陪诊记录
*
* @param {ObjectId} id - 记录ID
* @param {Function} [cb] - 可选的回调函数
* @returns {Promise<Object|null>} 陪诊记录不存在返回null
*/
EscortRecordSchema.statics.findRecordById = async function (id, cb) {
return await this.findById(id).exec(cb);
};
/**
* 根据状态查找陪诊记录
*
* @param {string} status - 状态
* @param {Object} options - 查询选项
* @param {number} [options.page=1] - 页码
* @param {number} [options.pageSize=20] - 每页数量
* @param {Function} [cb] - 可选的回调函数
* @returns {Promise<Array>} 陪诊记录列表
*/
EscortRecordSchema.statics.findRecordsByStatus = async function (status, options = {}, cb) {
const { page = 1, pageSize = 20 } = options;
const skip = (page - 1) * pageSize;
return await this.find({ status })
.sort({ "schedule.date": -1 })
.skip(skip)
.limit(pageSize)
.exec(cb);
};
/**
* 删除陪诊记录
*
* @param {ObjectId} id - 记录ID
* @param {Function} [cb] - 可选的回调函数
* @returns {Promise<Object|null>} 删除的记录失败返回null
*/
EscortRecordSchema.statics.deleteRecord = async function (id, cb) {
try {
return await this.findByIdAndDelete(id, cb);
} catch (error) {
console.error("删除陪诊记录失败:", error);
return null;
}
};
// ==================== 索引定义 ====================
/**
* 用户ID索引 - 用于快速查询用户的陪诊记录
*/
EscortRecordSchema.index({ userId: 1, "schedule.date": -1 });
/**
* 陪诊员ID索引 - 用于快速查询陪诊员的服务记录
*/
EscortRecordSchema.index({ "attendant.id": 1, status: 1, "schedule.date": -1 });
/**
* 状态索引 - 用于快速按状态筛选记录
*/
EscortRecordSchema.index({ status: 1 });
/**
* 医院名称索引 - 用于快速按医院筛选记录
*/
EscortRecordSchema.index({ "hospital.name": 1 });
export { EscortRecordSchema };