This commit is contained in:
lik
2026-09-09 17:36:45 +08:00
parent d6efb180dd
commit 223e0ed2ee
25 changed files with 933 additions and 59 deletions
+140
View File
@@ -0,0 +1,140 @@
import { tool } from "@langchain/core/tools";
import z from "zod";
import mongoose from "mongoose";
import { DBModel } from "../../../../models/index.js";
import { genPinyin, genPinyinFL } from "../../../../models/schema/health_profile.js";
const PROFILE_KEYS = ["name", "mobile", "sex", "birth", "idnumber"];
const LOCATION_KEYS = ["country", "province", "city", "district", "address"];
const HEALTH_KEYS = ["height", "weight", "bloodType", "remark"];
const profileSchema = z
.object({
name: z.string().optional().describe("患者姓名"),
mobile: z.string().optional().describe("患者电话"),
sex: z.enum(["male", "female"]).optional().describe("性别"),
birth: z.string().optional().describe("出生年月(YYYY-MM-DD"),
idnumber: z.string().optional().describe("证件号(身份证/护照等)"),
})
.optional()
.describe("患者基本信息");
const locationSchema = z
.object({
country: z.string().optional().describe("国家(国外用户填国家,国内默认中国)"),
province: z.string().optional().describe("省"),
city: z.string().optional().describe("市"),
district: z.string().optional().describe("区/县"),
address: z.string().optional().describe("详细地址"),
})
.optional()
.describe("所在地信息");
const healthSchema = z
.object({
height: z.number().optional().describe("身高(cm"),
weight: z.number().optional().describe("体重(kg"),
bloodType: z.string().optional().describe("血型"),
remark: z.string().optional().describe("备注"),
})
.optional()
.describe("健康信息");
const healthProfileSetTool = tool(
async ({ action, profileId, userId, profile, location, health }) => {
try {
if (action === "create") {
if (!profile || (!profile.name && !profile.mobile)) {
return { success: false, error: "创建健康档案至少需要提供患者姓名或电话" };
}
const docData = {
profile: { ...profile },
location: { ...location },
health: { ...health },
meta: { createtime: new Date(), updatetime: new Date() },
};
if (userId) {
if (!mongoose.Types.ObjectId.isValid(userId)) {
return { success: false, error: `Invalid user ID: ${userId}` };
}
docData.userId = new mongoose.Types.ObjectId(userId);
}
const doc = await DBModel.HealthProfile.create(docData);
return { success: true, data: doc };
}
if (action === "update") {
if (!profileId) {
return { success: false, error: "更新健康档案必须提供 profileId(可先用 health_profile_query 查询定位)" };
}
if (!mongoose.Types.ObjectId.isValid(profileId)) {
return { success: false, error: `Invalid profile ID: ${profileId}` };
}
const update = {};
if (userId) {
if (!mongoose.Types.ObjectId.isValid(userId)) {
return { success: false, error: `Invalid user ID: ${userId}` };
}
update.userId = new mongoose.Types.ObjectId(userId);
}
if (profile) {
for (const key of PROFILE_KEYS) {
if (profile[key] !== undefined) update[`profile.${key}`] = profile[key];
}
// 更新姓名时同步拼音字段(findByIdAndUpdate 不触发 pre("save")
if (profile.name !== undefined) {
update["profile.pinyin"] = genPinyin(profile.name);
update["profile.pinyinFL"] = genPinyinFL(profile.name);
}
}
if (location) {
for (const key of LOCATION_KEYS) {
if (location[key] !== undefined) update[`location.${key}`] = location[key];
}
}
if (health) {
for (const key of HEALTH_KEYS) {
if (health[key] !== undefined) update[`health.${key}`] = health[key];
}
}
if (Object.keys(update).length === 0) {
return { success: false, error: "未提供任何要更新的字段" };
}
update["meta.updatetime"] = new Date();
const updated = await DBModel.HealthProfile.findByIdAndUpdate(
profileId,
{ $set: update },
{ new: true }
);
if (!updated) {
return { success: false, error: `未找到 ID 为 ${profileId} 的健康档案` };
}
return { success: true, data: updated };
}
return { success: false, error: "未知的 action,可选值:create / update" };
} catch (error) {
return { success: false, error: error.message };
}
},
{
name: "health_profile_set",
description:
"创建或更新患者健康档案。create 新建档案(至少提供患者姓名或电话);update 按档案 ID 局部更新,仅修改提供的字段。更新前建议先用 health_profile_query 查询现有内容。",
schema: z.object({
action: z.enum(["create", "update"]).describe("操作类型:create 新建 / update 更新"),
profileId: z.string().optional().describe("健康档案 ID_id),update 时必填"),
userId: z.string().optional().describe("所属用户ID(可选,用于关联小程序用户)"),
profile: profileSchema,
location: locationSchema,
health: healthSchema,
}),
}
);
export { healthProfileSetTool };