This commit is contained in:
lik
2026-05-25 12:46:14 +08:00
parent 01d54cc580
commit 17014446ba
24 changed files with 5932 additions and 0 deletions

View File

@@ -0,0 +1,304 @@
"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 };