Files
kt-financial-system/apps/backend/api/finance/transactions.post.ts
你的用户名 a4e4168c00
Some checks failed
Deploy to Production / Build and Test (push) Has been cancelled
Deploy to Production / Deploy to Server (push) Has been cancelled
feat: 添加Telegram Bot通知功能
 新功能:
- 添加Telegram Bot通知支持
- 账目记录自动推送到Telegram
- 支持多个Bot配置管理
- 支持群组和个人通知

📊 数据库:
- 新增telegram_notification_configs表
- 存储Bot配置和通知类型

🔧 后端API:
- GET /api/telegram/notifications - 获取所有配置
- POST /api/telegram/notifications - 创建配置
- PUT /api/telegram/notifications/:id - 更新配置
- DELETE /api/telegram/notifications/:id - 删除配置
- POST /api/telegram/test - 测试Bot配置

💬 通知功能:
- 自动发送账目记录通知
- 包含交易类型、金额、分类、账户等信息
- 支持格式化显示(类型图标、状态标识)
- 配置创建时自动测试有效性

📝 文档:
- 添加完整的使用说明文档
- API接口说明和示例
- 常见问题解答
2025-11-04 23:15:19 +08:00

102 lines
3.0 KiB
TypeScript
Raw 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 { readBody } from 'h3';
import {
createTransaction,
type TransactionStatus,
} from '~/utils/finance-repository';
import { useResponseError, useResponseSuccess } from '~/utils/response';
import { notifyTransactionWebhook } from '~/utils/telegram-webhook';
import { notifyTransaction } from '~/utils/telegram-bot';
import db from '~/utils/sqlite';
const DEFAULT_CURRENCY = 'CNY';
const ALLOWED_STATUSES: TransactionStatus[] = [
'draft',
'pending',
'approved',
'rejected',
'paid',
];
export default defineEventHandler(async (event) => {
const body = await readBody(event);
if (!body?.type || !body?.amount || !body?.transactionDate) {
return useResponseError('缺少必填字段', -1);
}
const amount = Number(body.amount);
if (Number.isNaN(amount)) {
return useResponseError('金额格式不正确', -1);
}
const status =
(body.status as TransactionStatus | undefined) ?? 'approved';
if (!ALLOWED_STATUSES.includes(status)) {
return useResponseError('状态值不合法', -1);
}
const transaction = createTransaction({
type: body.type,
amount,
currency: body.currency ?? DEFAULT_CURRENCY,
categoryId: body.categoryId ?? null,
accountId: body.accountId ?? null,
transactionDate: body.transactionDate,
description: body.description ?? '',
project: body.project ?? null,
memo: body.memo ?? null,
status,
reimbursementBatch: body.reimbursementBatch ?? null,
reviewNotes: body.reviewNotes ?? null,
submittedBy: body.submittedBy ?? null,
approvedBy: body.approvedBy ?? null,
statusUpdatedAt: body.statusUpdatedAt ?? undefined,
approvedAt: body.approvedAt ?? undefined,
});
// 发送Webhook通知保留原有功能
notifyTransactionWebhook(transaction, { action: 'created' }).catch((error) =>
console.error('[finance][transactions.post] webhook notify failed', error),
);
// 发送Telegram通知新功能
try {
// 获取分类和账户名称
let categoryName: string | undefined;
let accountName: string | undefined;
if (transaction.categoryId) {
const category = db
.prepare<{ name: string }>('SELECT name FROM finance_categories WHERE id = ?')
.get(transaction.categoryId);
categoryName = category?.name;
}
if (transaction.accountId) {
const account = db
.prepare<{ name: string }>('SELECT name FROM finance_accounts WHERE id = ?')
.get(transaction.accountId);
accountName = account?.name;
}
await notifyTransaction(
{
id: transaction.id,
type: transaction.type,
amount: transaction.amount,
currency: transaction.currency,
categoryName,
accountName,
transactionDate: transaction.transactionDate,
description: transaction.description || undefined,
status: transaction.status,
},
'created',
);
} catch (error) {
console.error('[finance][transactions.post] telegram notify failed', error);
}
return useResponseSuccess(transaction);
});