Files
api_health/models/schema/employee.js
2026-05-31 12:49:23 +08:00

191 lines
5.6 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";
/**
* Employee Schema
* 员工/人员信息,支持陪诊员、护士、医生、管理员等角色
*/
const EmployeeSchema = mongoose.Schema(
{
// 基础信息
name: { type: String, required: true, comment: "姓名" },
employeeNo: { type: String, default: "", unique: true, sparse: true, comment: "工号" },
// 登录账号(关联用户体系)
userId: {
type: mongoose.Schema.Types.ObjectId,
ref: "user",
index: true,
comment: "关联用户ID",
},
// 所属机构
orgId: {
type: mongoose.Schema.Types.ObjectId,
ref: "organization",
index: true,
comment: "所属机构ID",
},
// 角色/岗位
role: {
type: String,
enum: ["attendant", "nurse", "doctor", "admin", "operator", "other"],
default: "attendant",
comment: "角色:陪诊员、护士、医生、管理员、运营、其他",
},
// 个人信息
profile: {
sex: { type: String, enum: ["male", "female", "other", ""], default: "", comment: "性别" },
birthday: { type: Date, comment: "出生日期" },
idNumber: { type: String, default: "", comment: "身份证号" },
phone: { type: String, default: "", comment: "手机号" },
email: { type: String, default: "", comment: "邮箱" },
avatar: { type: String, default: "", comment: "头像URL" },
},
// 工作信息
work: {
department: { type: String, default: "", comment: "所属科室/部门" },
title: { type: String, default: "", comment: "职称/头衔" },
entryDate: { type: Date, comment: "入职日期" },
workYears: { type: Number, default: 0, comment: "工作年限" },
qualification: { type: String, default: "", comment: "资质证书编号" },
},
// 陪诊员特有信息
attendantInfo: {
serviceAreas: { type: [String], default: [], comment: "服务区域/城市列表" },
specialties: { type: [String], default: [], comment: "擅长科室/领域" },
languages: { type: [String], default: ["普通话"], comment: "掌握语言" },
rating: { type: Number, default: 5.0, min: 1, max: 5, comment: "评分1-5" },
orderCount: { type: Number, default: 0, comment: "接单数量" },
isOnline: { type: Boolean, default: false, comment: "是否在线" },
},
// 紧急联系人
emergencyContact: {
name: { type: String, default: "", comment: "紧急联系人姓名" },
phone: { type: String, default: "", comment: "紧急联系人电话" },
relation: { type: String, default: "", comment: "关系" },
},
// 状态
status: {
type: String,
enum: ["active", "inactive", "resigned", "suspended"],
default: "active",
comment: "状态:在职、停用、离职、暂停",
},
// 简介/备注
introduction: { type: String, default: "", comment: "个人简介" },
remark: { type: String, default: "", comment: "备注" },
// 元数据
meta: {
createtime: { type: Date, default: Date.now, comment: "创建时间" },
updatetime: { type: Date, default: Date.now, comment: "更新时间" },
},
},
{
minimize: false,
strict: false,
collection: "employee",
timestamps: false,
}
);
// ==================== 静态方法 ====================
/**
* 根据机构ID查询员工列表
*/
EmployeeSchema.statics.findByOrg = async function (orgId, options = {}) {
const { page = 1, pageSize = 20, role, status } = options;
const filter = { orgId };
if (role) filter.role = role;
if (status) filter.status = status;
const skip = (page - 1) * pageSize;
return await this.find(filter)
.skip(skip)
.limit(pageSize)
.exec();
};
/**
* 根据角色查询员工
*/
EmployeeSchema.statics.findByRole = async function (role, options = {}) {
const { page = 1, pageSize = 20, status = "active" } = options;
const filter = { role };
if (status) filter.status = status;
const skip = (page - 1) * pageSize;
return await this.find(filter)
.skip(skip)
.limit(pageSize)
.exec();
};
/**
* 根据用户ID查找员工
*/
EmployeeSchema.statics.findByUserId = async function (userId) {
return await this.findOne({ userId }).exec();
};
/**
* 根据ID查找员工
*/
EmployeeSchema.statics.findByEmployeeId = async function (id) {
return await this.findById(id).exec();
};
/**
* 创建员工
*/
EmployeeSchema.statics.createEmployee = async function (data) {
data.meta = { createtime: Date.now(), updatetime: Date.now() };
const doc = new this(data);
return await doc.save();
};
/**
* 更新员工
*/
EmployeeSchema.statics.updateEmployee = async function (id, update) {
update["meta.updatetime"] = Date.now();
return await this.findByIdAndUpdate(id, { $set: update }, { new: true }).exec();
};
/**
* 查询在线陪诊员列表
*/
EmployeeSchema.statics.findOnlineAttendants = async function (options = {}) {
const { page = 1, pageSize = 20 } = options;
const skip = (page - 1) * pageSize;
return await this.find({
role: "attendant",
status: "active",
"attendantInfo.isOnline": true,
})
.sort({ "attendantInfo.rating": -1 })
.skip(skip)
.limit(pageSize)
.exec();
};
// ==================== 索引定义 ====================
EmployeeSchema.index({ name: 1 });
EmployeeSchema.index({ employeeNo: 1 });
EmployeeSchema.index({ userId: 1 });
EmployeeSchema.index({ orgId: 1, role: 1, status: 1 });
EmployeeSchema.index({ role: 1, status: 1 });
EmployeeSchema.index({ "profile.phone": 1 });
EmployeeSchema.index({ status: 1 });
export { EmployeeSchema };