86 lines
2.9 KiB
JavaScript
86 lines
2.9 KiB
JavaScript
import { tool } from "@langchain/core/tools";
|
||
import z from "zod";
|
||
import mongoose from "mongoose";
|
||
import { DBModel } from "../../../../models/index.js";
|
||
|
||
const healthProfileQueryTool = tool(
|
||
async ({ profileId, userId, name, mobile, page = 1, pageSize = 20 }) => {
|
||
try {
|
||
// 按档案 _id 精确查询单条
|
||
if (profileId) {
|
||
if (!mongoose.Types.ObjectId.isValid(profileId)) {
|
||
return { success: false, error: `Invalid profile ID: ${profileId}` };
|
||
}
|
||
const doc = await DBModel.HealthProfile.findById(profileId).lean();
|
||
if (!doc) {
|
||
return { success: false, error: `未找到 ID 为 ${profileId} 的健康档案` };
|
||
}
|
||
return { success: true, data: [doc], total: 1 };
|
||
}
|
||
|
||
const filter = {};
|
||
|
||
if (userId) {
|
||
if (!mongoose.Types.ObjectId.isValid(userId)) {
|
||
return { success: false, error: `Invalid user ID: ${userId}` };
|
||
}
|
||
filter.userId = new mongoose.Types.ObjectId(userId);
|
||
}
|
||
if (name) {
|
||
// 转义正则特殊字符,避免查询报错或 ReDoS;姓名支持中文、全拼、拼音首字母匹配
|
||
const escaped = name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
||
const re = { $regex: escaped, $options: "i" };
|
||
filter.$or = [{ "profile.name": re }, { "profile.pinyin": re }, { "profile.pinyinFL": re }];
|
||
}
|
||
if (mobile) {
|
||
filter["profile.mobile"] = mobile;
|
||
}
|
||
|
||
const skip = (page - 1) * pageSize;
|
||
|
||
const [list, total] = await Promise.all([
|
||
DBModel.HealthProfile.find(filter)
|
||
.sort({ "meta.createtime": -1 })
|
||
.skip(skip)
|
||
.limit(pageSize)
|
||
.lean(),
|
||
DBModel.HealthProfile.countDocuments(filter),
|
||
]);
|
||
|
||
return {
|
||
success: true,
|
||
data: list,
|
||
total,
|
||
page,
|
||
pageSize,
|
||
};
|
||
} catch (error) {
|
||
return { success: false, error: error.message };
|
||
}
|
||
},
|
||
{
|
||
name: "health_profile_query",
|
||
description:
|
||
"查询患者健康档案。支持按档案 ID 精确查询,或按用户 ID、患者姓名(模糊)、患者电话筛选,返回分页结果。",
|
||
schema: z.object({
|
||
profileId: z
|
||
.string()
|
||
.optional()
|
||
.describe("健康档案 ID(_id),提供时精确查询单条,忽略其他筛选条件"),
|
||
userId: z.string().optional().describe("所属用户ID(精确匹配)"),
|
||
name: z.string().optional().describe("患者姓名(支持中文模糊、全拼、拼音首字母匹配,如 张三/zhangsan/zs)"),
|
||
mobile: z.string().optional().describe("患者电话(精确匹配)"),
|
||
page: z.number().int().min(1).optional().describe("页码,从 1 开始"),
|
||
pageSize: z
|
||
.number()
|
||
.int()
|
||
.min(1)
|
||
.max(50)
|
||
.optional()
|
||
.describe("每页数量(1-50),默认 20"),
|
||
}),
|
||
}
|
||
);
|
||
|
||
export { healthProfileQueryTool };
|