This commit is contained in:
lik
2026-09-09 17:36:25 +08:00
parent 1f2da22cae
commit d6efb180dd
54 changed files with 0 additions and 2000 deletions
@@ -0,0 +1,87 @@
import { tool } from "@langchain/core/tools";
import z from "zod";
import { DBModel } from "../../../../models/index.js";
function createEscortRecordQueryTool(userInfo) {
const userMobile = userInfo?.profile?.mobile;
return tool(
async ({ patientName, status, page = 1, pageSize = 20 }) => {
try {
const filter = {};
if (patientName) {
filter["patient.name"] = { $regex: patientName, $options: "i" };
}
// 强制使用当前登录用户的手机号进行查询
if (!userMobile) {
return {
success: false,
error: "用户未登录或手机号缺失,无法查询陪诊记录",
};
}
filter["patient.mobile"] = userMobile;
if (status) {
filter.status = status;
}
const skip = (page - 1) * pageSize;
const records = await DBModel.EscortRecord.find(filter)
.sort({ "schedule.date": -1 })
.skip(skip)
.limit(pageSize)
.lean();
const total = await DBModel.EscortRecord.countDocuments(filter);
return {
success: true,
data: records,
total,
page,
pageSize,
};
} catch (error) {
return {
success: false,
error: error.message,
};
}
},
{
name: "escort_record_query",
description:
"Query escort records from database for the current user. Supports filtering by patient name and appointment status. Returns paginated results sorted by appointment date in descending order. The query is automatically scoped to the current logged-in user's mobile phone number.",
schema: z.object({
patientName: z
.string()
.optional()
.describe("Patient name for fuzzy search"),
status: z
.enum(["pending", "confirmed", "in_progress", "completed", "cancelled"])
.optional()
.describe(
"Appointment status: pending (待确认), confirmed (已确认), in_progress (进行中), completed (已完成), cancelled (已取消)"
),
page: z
.number()
.int()
.min(1)
.optional()
.describe("Page number, starting from 1"),
pageSize: z
.number()
.int()
.min(1)
.max(50)
.optional()
.describe("Records per page (1-50), default 20"),
}),
}
);
}
export { createEscortRecordQueryTool };
@@ -0,0 +1,79 @@
import { tool } from "@langchain/core/tools";
import z from "zod";
import { DBModel } from "../../../../models/index.js";
const escortRecordQueryTool = tool(
async ({ patientName, mobile, status, page = 1, pageSize = 20 }) => {
try {
const filter = {};
if (patientName) {
filter["patient.name"] = { $regex: patientName, $options: "i" };
}
if (mobile) {
filter["patient.mobile"] = mobile;
}
if (status) {
filter.status = status;
}
const skip = (page - 1) * pageSize;
const records = await DBModel.EscortRecord.find(filter)
.sort({ "schedule.date": -1 })
.skip(skip)
.limit(pageSize)
.lean();
const total = await DBModel.EscortRecord.countDocuments(filter);
return {
success: true,
data: records,
};
} catch (error) {
return {
success: false,
error: error.message,
};
}
},
{
name: "escort_record_query",
description:
"Query escort records from database. Supports filtering by patient name, mobile phone number, and appointment status. Returns paginated results sorted by appointment date in descending order.",
schema: z.object({
patientName: z
.string()
.optional()
.describe("Patient name for fuzzy search"),
mobile: z
.string()
.optional()
.describe("Patient mobile phone number for exact match"),
status: z
.enum(["pending", "confirmed", "in_progress", "completed", "cancelled"])
.optional()
.describe(
"Appointment status: pending (待确认), confirmed (已确认), in_progress (进行中), completed (已完成), cancelled (已取消)"
),
page: z
.number()
.int()
.min(1)
.optional()
.describe("Page number, starting from 1"),
pageSize: z
.number()
.int()
.min(1)
.max(50)
.optional()
.describe("Records per page (1-50), default 20"),
}),
}
);
export { escortRecordQueryTool };
+117
View File
@@ -0,0 +1,117 @@
import { tool } from "@langchain/core/tools";
import z from "zod";
import mongoose from "mongoose";
import { DBModel } from "../../../../models/index.js";
const escortRecordSetTool = tool(
async ({ orderId, status, notes, payment }) => {
try {
if (!orderId) {
return {
success: false,
error: "Record ID (_id) is required as the lookup key",
};
}
if (!mongoose.Types.ObjectId.isValid(orderId)) {
return {
success: false,
error: `Invalid record ID: ${orderId}. A valid record _id is required.`,
};
}
const record = await DBModel.EscortRecord.findById(orderId);
if (!record) {
return {
success: false,
error: `No escort record found for order ID: ${orderId}`,
};
}
const update = {};
if (status !== undefined) {
update.status = status;
}
if (notes !== undefined) {
if (notes.patientNote !== undefined) {
update["notes.patientNote"] = notes.patientNote;
}
if (notes.escortNote !== undefined) {
update["notes.escortNote"] = notes.escortNote;
}
if (notes.medicalSummary !== undefined) {
update["notes.medicalSummary"] = notes.medicalSummary;
}
}
if (payment !== undefined) {
if (payment.totalFee !== undefined) {
update["payment.totalFee"] = payment.totalFee;
}
if (payment.paidFee !== undefined) {
update["payment.paidFee"] = payment.paidFee;
}
if (payment.status !== undefined) {
update["payment.status"] = payment.status;
}
}
update["meta.updatetime"] = Date.now();
const updatedRecord = await DBModel.EscortRecord.findByIdAndUpdate(
record._id,
{ $set: update },
{ new: true }
);
return {
success: true,
data: updatedRecord,
};
} catch (error) {
return {
success: false,
error: error.message,
};
}
},
{
name: "escort_record_set",
description:
"Update escort record fields by record ID (_id). Supports updating status, notes (patientNote, escortNote, medicalSummary), and payment (totalFee, paidFee, status). Only provided fields will be updated.",
schema: z.object({
orderId: z
.string()
.describe("Record ID (_id) used as the lookup key"),
status: z
.enum(["pending", "confirmed", "in_progress", "completed", "cancelled"])
.optional()
.describe(
"Appointment status: pending (待确认), confirmed (已确认), in_progress (进行中), completed (已完成), cancelled (已取消)"
),
notes: z
.object({
patientNote: z.string().optional().describe("Patient remarks / special requirements"),
escortNote: z.string().optional().describe("Escort service notes"),
medicalSummary: z.string().optional().describe("Medical visit summary"),
})
.optional()
.describe("Notes information to update"),
payment: z
.object({
totalFee: z.number().optional().describe("Total service fee (RMB)"),
paidFee: z.number().optional().describe("Amount already paid (RMB)"),
status: z
.enum(["unpaid", "partial", "paid", "refunded"])
.optional()
.describe("Payment status: unpaid, partial, paid, refunded"),
})
.optional()
.describe("Payment information to update"),
}),
}
);
export { escortRecordSetTool };