"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} 医院列表 */ 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} 医院列表 */ 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} 医院列表(仅包含名称和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} 创建的医院 */ 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} 更新后的医院 */ 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} 更新后的医院 */ 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 };