25 lines
2.1 KiB
TypeScript
25 lines
2.1 KiB
TypeScript
import { Injectable } from '@nestjs/common';
|
|
import { BillsService } from '../../bills/bills.service';
|
|
import type { AgentToolContext, ToolDef, ToolInputResult } from '../agent-tool.types';
|
|
import { optionalDate, optionalPositiveInt, optionalString, rejectUnknownKeys } from './tool-input';
|
|
|
|
interface Input { keyword?: string; periodStart?: string; periodEnd?: string; status?: string; limit?: number }
|
|
@Injectable()
|
|
export class SearchBillsTool implements ToolDef<Input> {
|
|
readonly name = 'search_bills'; readonly requiredPermission = 'bill:view';
|
|
readonly description = '查询账单编号、学生显示名、账期、金额和状态。';
|
|
readonly inputSchema = { type: 'object', properties: { keyword: { type: 'string', maxLength: 100 }, periodStart: { type: 'string', format: 'date' }, periodEnd: { type: 'string', format: 'date' }, status: { type: 'string', maxLength: 20 }, limit: { type: 'integer', minimum: 1, maximum: 50 } }, additionalProperties: false };
|
|
constructor(private readonly service: BillsService) {}
|
|
validate(raw: Record<string, unknown>): ToolInputResult<Input> {
|
|
const invalid = rejectUnknownKeys(raw, ['keyword', 'periodStart', 'periodEnd', 'status', 'limit']); if (invalid) return invalid;
|
|
const keyword = optionalString(raw.keyword, 'keyword', 100); if (!keyword.ok) return keyword;
|
|
const periodStart = optionalDate(raw.periodStart, 'periodStart'); if (!periodStart.ok) return periodStart;
|
|
const periodEnd = optionalDate(raw.periodEnd, 'periodEnd'); if (!periodEnd.ok) return periodEnd;
|
|
if (periodStart.value && periodEnd.value && periodStart.value > periodEnd.value) return { ok: false, error: 'periodEnd 不能早于 periodStart' };
|
|
const status = optionalString(raw.status, 'status', 20); if (!status.ok) return status;
|
|
const limit = optionalPositiveInt(raw.limit, 'limit', 50); if (!limit.ok) return limit;
|
|
return { ok: true, value: { keyword: keyword.value, periodStart: periodStart.value, periodEnd: periodEnd.value, status: status.value, limit: limit.value } };
|
|
}
|
|
execute(input: Input, _context: AgentToolContext) { return this.service.agentSearchBills(input); }
|
|
}
|