Files
api_health/agent/infra/tools/db/health_profile_query.js
2026-09-09 17:36:45 +08:00

86 lines
2.9 KiB
JavaScript
Raw Permalink 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.
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 };