Files
ws_health/api/models/schema/org.js
2026-05-25 12:34:16 +08:00

246 lines
7.9 KiB
JavaScript
Raw 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定义
*
* 包含5个主要分类块基本信息、位置信息、联系方式、服务信息和元数据。
* 用于记录和管理医院信息,支持陪诊服务的医院选择功能。
*/
const HospitalSchema = mongoose.Schema(
{
// 基本信息 - 医院的核心标识信息
basic: {
name: { type: String, required: true, comment: "医院名称" },
shortName: { type: String, default: "", comment: "医院简称" },
pinyin: { type: String, default: "", comment: "医院名称拼音,用于搜索" },
pinyinFL: { type: String, default: "", comment: "医院名称拼音首字母,用于搜索" },
level: {
type: String,
enum: ["tertiary", "secondary", "primary", "other"],
default: "other",
comment: "医院等级:三级、二级、一级、其他",
},
type: {
type: String,
enum: ["general", "specialized", "traditional_chinese", "integrated", "other"],
default: "general",
comment: "医院类型:综合医院、专科医院、中医医院、中西医结合医院、其他",
},
description: { type: String, default: "", comment: "医院简介" },
logo: { type: String, default: "", comment: "医院Logo地址" },
},
// 位置信息 - 医院的地理位置
location: {
province: { type: String, default: "", comment: "省份" },
city: { type: String, default: "", comment: "城市" },
district: { type: String, default: "", comment: "区县" },
address: { type: String, default: "", comment: "详细地址" },
longitude: { type: Number, default: 0, comment: "经度" },
latitude: { type: Number, default: 0, comment: "纬度" },
},
// 联系方式 - 医院的联系信息
contact: {
phone: { type: String, default: "", comment: "联系电话" },
emergencyPhone: { type: String, default: "", comment: "急诊电话" },
website: { type: String, default: "", comment: "官方网站" },
email: { type: String, default: "", comment: "电子邮箱" },
},
// 服务信息 - 医院提供的服务
service: {
features: [{ type: String, comment: "特色服务" }],
isEnabled: { type: Boolean, default: true, comment: "是否启用" },
sortOrder: { type: Number, default: 0, comment: "排序优先级" },
},
// 科室信息 - 医院科室详细信息
departments: [
{
name: { type: String, required: true, comment: "科室名称" },
pinyin: { type: String, default: "", comment: "科室名称拼音" },
pinyinFL: { type: String, default: "", comment: "科室名称拼音首字母" },
location: { type: String, default: "", comment: "科室位置(几号楼,几层)" },
phone: { type: String, default: "", comment: "科室联系电话" },
description: { type: String, default: "", comment: "科室简介" },
doctors: [
{
name: { type: String, required: true, comment: "医生姓名" },
title: {
type: String,
enum: ["resident", "attending", "deputy_chief", "chief", "other"],
default: "attending",
comment: "医生职称:住院医师、主治医师、副主任医师、主任医师、其他",
},
specialty: { type: String, default: "", comment: "专业擅长" },
avatar: { type: String, default: "", comment: "医生头像" },
},
],
isEnabled: { type: Boolean, default: true, comment: "是否启用" },
sortOrder: { type: Number, default: 0, comment: "排序优先级" },
},
],
// 元数据 - 系统管理信息
meta: {
createtime: { type: Date, default: Date.now, comment: "创建时间" },
updatetime: { type: Date, default: Date.now, comment: "更新时间" },
},
},
{
minimize: false,
strict: false,
collection: "hospital",
timestamps: false,
}
);
/**
* 根据名称查找医院
*
* @param {String} name - 医院名称(支持模糊搜索)
* @param {Object} options - 查询选项 { page, pageSize }
* @param {Function} cb - 可选的回调函数
* @returns {Promise<Array>} 医院列表
*/
HospitalSchema.statics.findByName = async function (name, options = {}, cb) {
const { page = 1, pageSize = 20 } = options;
const filter = {
$or: [
{ "basic.name": new RegExp(name, "i") },
{ "basic.shortName": new RegExp(name, "i") },
{ "basic.pinyin": new RegExp(name.toLowerCase(), "i") },
{ "basic.pinyinFL": new RegExp(name.toUpperCase(), "i") },
],
"service.isEnabled": true,
};
const skip = (page - 1) * pageSize;
return await this.find(filter)
.sort({ "service.sortOrder": 1, "basic.name": 1 })
.skip(skip)
.limit(pageSize)
.exec(cb);
};
/**
* 根据城市查找医院
*
* @param {String} city - 城市名称
* @param {Object} options - 查询选项 { page, pageSize, level, type }
* @param {Function} cb - 可选的回调函数
* @returns {Promise<Array>} 医院列表
*/
HospitalSchema.statics.findByCity = async function (city, options = {}, cb) {
const { page = 1, pageSize = 20, level, type } = options;
const filter = {
"location.city": city,
"service.isEnabled": true,
};
if (level) {
filter["basic.level"] = level;
}
if (type) {
filter["basic.type"] = type;
}
const skip = (page - 1) * pageSize;
return await this.find(filter)
.sort({ "service.sortOrder": 1, "basic.name": 1 })
.skip(skip)
.limit(pageSize)
.exec(cb);
};
/**
* 获取所有启用的医院列表(用于选择器)
*
* @param {Object} options - 查询选项 { city, level, type }
* @param {Function} cb - 可选的回调函数
* @returns {Promise<Array>} 医院列表仅包含名称和ID
*/
HospitalSchema.statics.getHospitalSelector = async function (options = {}, cb) {
const { city, level, type } = options;
const filter = { "service.isEnabled": true };
if (city) {
filter["location.city"] = city;
}
if (level) {
filter["basic.level"] = level;
}
if (type) {
filter["basic.type"] = type;
}
return await this.find(filter, { "basic.name": 1 })
.sort({ "service.sortOrder": 1, "basic.name": 1 })
.exec(cb);
};
/**
* 创建医院
*
* @param {Object} hospital - 医院对象
* @param {Function} cb - 可选的回调函数
* @returns {Promise<Object>} 创建的医院
*/
HospitalSchema.statics.createHospital = async function (hospital, cb) {
hospital.meta = {
createtime: Date.now(),
updatetime: Date.now(),
};
const newHospital = new this(hospital);
return await newHospital.save(cb);
};
/**
* 更新医院信息
*
* @param {ObjectId} id - 医院ID
* @param {Object} update - 要更新的字段
* @param {Function} cb - 可选的回调函数
* @returns {Promise<Object|null>} 更新后的医院
*/
HospitalSchema.statics.updateHospital = async function (id, update, cb) {
try {
update["meta.updatetime"] = Date.now();
return await this.findByIdAndUpdate(id, { $set: update }, { new: true }, cb);
} catch (error) {
return null;
}
};
/**
* 启用/禁用医院
*
* @param {ObjectId} id - 医院ID
* @param {Boolean} isEnabled - 是否启用
* @param {Function} cb - 可选的回调函数
* @returns {Promise<Object|null>} 更新后的医院
*/
HospitalSchema.statics.setHospitalStatus = async function (id, isEnabled, cb) {
try {
return await this.findByIdAndUpdate(
id,
{
"service.isEnabled": isEnabled,
"meta.updatetime": Date.now(),
},
{ new: true },
cb
);
} catch (error) {
return null;
}
};
// 医院名称索引
HospitalSchema.index({ "basic.name": 1 });
// 城市和等级索引
HospitalSchema.index({ "location.city": 1, "basic.level": 1 });
// 启用状态索引
HospitalSchema.index({ "service.isEnabled": 1 });
export { HospitalSchema };