Files
hack/tools/scripts/llm-key-hunter/results/_cache/content/c-shunyi_pink-ledger.json
T

1 line
10 KiB
JSON
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.
{"repo": "c-shunyi/pink-ledger", "files": {"pink-ledger-node/.env": {"829a14e8a8dbde9b40fd4602fd3ebca074e6ae36": {"t": 1785745091.7968197, "n": 413, "h": "2173677013a2a6a7", "c": "# JWT Configuration\nJWT_SECRET=pink_ledger_super_secret_key_2024_secure_random_string_please_change_in_production\nJWT_EXPIRES_IN=60d\n\n# Server Configuration\nPORT=8860\nNODE_ENV=development\n\n# Database Configuration\nDB_PATH=./database.sqlite\n\n# 微信小程序配置(用于微信一键登录)\nWECHAT_APPID=wxc140eef540b899db\nWECHAT_APP_SECRET=9ecd9693ad3627ae9bef4b92e5c0b25f\n\nDEEPSEEK_API_KEY=sk-GwTsGxoPmDCsO47P6aT5oF2IWoJS7taY5EL6KNbqrIs2Yo3V"}, "37095846540c73810416deebe57c7c3d530f76a6": {"t": 1785747744.9143991, "n": 413, "h": "2173677013a2a6a7", "c": "# JWT Configuration\nJWT_SECRET=pink_ledger_super_secret_key_2024_secure_random_string_please_change_in_production\nJWT_EXPIRES_IN=60d\n\n# Server Configuration\nPORT=8860\nNODE_ENV=development\n\n# Database Configuration\nDB_PATH=./database.sqlite\n\n# 微信小程序配置(用于微信一键登录)\nWECHAT_APPID=wxc140eef540b899db\nWECHAT_APP_SECRET=9ecd9693ad3627ae9bef4b92e5c0b25f\n\nDEEPSEEK_API_KEY=sk-GwTsGxoPmDCsO47P6aT5oF2IWoJS7taY5EL6KNbqrIs2Yo3V"}, "6e1823d59d3d0f9cc732c52b1a95c67b7a7e7b38": {"t": 1785747747.224378, "n": 292, "h": "3ddf7195f6148056", "c": "# JWT Configuration\nJWT_SECRET=pink_ledger_super_secret_key_2024_secure_random_string_please_change_in_production\nJWT_EXPIRES_IN=7d\n\n# Server Configuration\nPORT=8860\nNODE_ENV=development\n\n# Database Configuration\nDB_PATH=./database.sqlite\n\n# Additional Security (optional)\n# BCRYPT_ROUNDS=12\n"}, "8d4bf7b2b6e0440ad129ceccc087e0a455317a89": {"t": 1785747748.3251812, "n": 292, "h": "65b3d848bac5744f", "c": "# JWT Configuration\nJWT_SECRET=pink_ledger_super_secret_key_2024_secure_random_string_please_change_in_production\nJWT_EXPIRES_IN=7d\n\n# Server Configuration\nPORT=3000\nNODE_ENV=development\n\n# Database Configuration\nDB_PATH=./database.sqlite\n\n# Additional Security (optional)\n# BCRYPT_ROUNDS=12\n"}}, "demo.js": {"829a14e8a8dbde9b40fd4602fd3ebca074e6ae36": {"t": 1785809872.143768, "n": 2163, "h": "f73501aac5f9d420", "c": "/**\n * DMXAPI 对话接口调用示例\n * 功能:使用 gpt-5-mini 模型进行智能对话\n */\n\nconst https = require('https');\n\n// ==================== API 配置 ====================\n\n// API 接口地址\nconst url = \"https://www.dmxapi.cn/v1/chat/completions\";\n\n// 请求头配置\nconst headers = {\n \"Authorization\": \"sk-GwTsGxoPmDCsO47P6aT5oF2IWoJS7taY5EL6KNbqrIs2Yo3V\", // 替换为你的 DMXAPI 令牌\n \"Content-Type\": \"application/json\"\n};\n\n// ==================== 请求参数 ====================\n\n// 构造请求数据\nconst payload = {\n model: \"DeepSeek-V3.2\", // 选择使用的模型\n messages: [\n {\n role: \"system\",\n content: `\n 你是一个账单处理系统,并且只返回JSON数据,不需要标记是什么数据,只要返回JSON` // 系统提示词:定义 AI 助手的角色\n },\n {\n role: \"user\",\n content: `\n 分类数据为:\n [{type: \"餐饮\", id: \"25\"},\n {type: \"零食\", id: \"22\"},\n {type: \"日用\", id: \"23\"},\n {type: \"交通\", id: \"24\"}]\n `\n },\n {\n role: \"user\",\n content: `\n 我的账单是:早餐在麦当劳吃了2个汉堡,花费了25元,然后打车回家花了了了40\n `\n },\n {\n role: \"user\",\n content: `\n 基于分类数据整理账单\n 请分类并且返回JSON格式数据\n [{\"typeId\": xxx, \"money\": xxx, \"remark\": xxx}]\n `\n }\n ]\n};\n\n// ==================== 发送请求 ====================\n\nconst data = JSON.stringify(payload);\n\nconst options = {\n method: 'POST',\n headers: {\n ...headers,\n 'Content-Length': Buffer.byteLength(data)\n }\n};\n\nconst req = https.request(url, options, (res) => {\n let responseData = '';\n\n // 接收数据\n res.on('data', (chunk) => {\n responseData += chunk;\n });\n\n // 请求完成\n res.on('end', () => {\n try {\n console.log(\"=\".repeat(50));\n console.log(\"API 响应结果:\");\n console.log(\"=\".repeat(50));\n console.log(JSON.stringify(JSON.parse(responseData), null, 2));\n } catch (error) {\n console.error(\"❌ 解析响应失败:\", error.message);\n console.log(\"原始响应:\", responseData);\n }\n });\n});\n\n// 错误处理\nreq.on('error', (error) => {\n console.error(`❌ 请求失败: ${error.message}`);\n});\n\n// 发送请求数据\nreq.write(data);\nreq.end();\n"}}, "pink-ledger-node/src/controllers/aiController.js": {"829a14e8a8dbde9b40fd4602fd3ebca074e6ae36": {"t": 1785809874.6288776, "n": 4832, "h": "dcd038cd7a3bcc0b", "c": "const axios = require('axios');\nconst { Op } = require('sequelize');\nconst { Category } = require('../models');\nconst sendResponse = require('../utils/response');\n\nconst DATE_REGEX = /^\\d{4}-\\d{2}-\\d{2}$/;\n\nconst buildCategoryData = (categories) => categories.map((cat) => ({\n id: cat.id,\n name: cat.name,\n type: cat.type\n}));\n\nconst normalizeBills = (bills, categories) => {\n const categoryMap = new Map(categories.map((cat) => [cat.id, cat]));\n const today = new Date().toISOString().split('T')[0];\n\n return bills\n .map((bill) => {\n const categoryId = Number(bill.categoryId);\n const category = categoryMap.get(categoryId);\n const amount = Number(bill.amount);\n const date = typeof bill.date === 'string' && DATE_REGEX.test(bill.date)\n ? bill.date\n : today;\n\n if (!category || !Number.isFinite(amount) || amount <= 0) {\n return null;\n }\n\n return {\n categoryId,\n type: category.type,\n amount,\n date,\n description: String(bill.description || bill.remark || '').trim()\n };\n })\n .filter(Boolean);\n};\n\n// AI 智能解析账单\nexports.parseSmartBilling = async (req, res) => {\n try {\n const { text } = req.body;\n const userId = req.userId;\n\n if (!text || text.trim().length === 0) {\n return sendResponse(res, {\n code: 400,\n msg: '请输入账单描述'\n });\n }\n\n if (!process.env.DEEPSEEK_API_KEY) {\n return sendResponse(res, {\n code: 500,\n msg: '未配置 DEEPSEEK_API_KEY'\n });\n }\n\n const categories = await Category.findAll({\n where: {\n [Op.or]: [\n { isSystem: true },\n { userId }\n ]\n },\n attributes: ['id', 'name', 'type'],\n order: [['sortOrder', 'ASC']]\n });\n\n if (categories.length === 0) {\n return sendResponse(res, {\n code: 400,\n msg: '暂无可用分类,请先创建分类'\n });\n }\n\n const aiResult = await callDeepSeekAPI(text.trim(), buildCategoryData(categories));\n\n if (!aiResult.success) {\n return sendResponse(res, {\n code: 500,\n msg: aiResult.error || 'AI 解析失败'\n });\n }\n\n const parsedBills = normalizeBills(aiResult.data, categories);\n\n if (parsedBills.length === 0) {\n return sendResponse(res, {\n code: 400,\n msg: 'AI 未能识别出有效的账单信息'\n });\n }\n\n return sendResponse(res, {\n code: 200,\n msg: '解析成功',\n data: { bills: parsedBills }\n });\n } catch (error) {\n console.error('AI 智能解析失败:', error);\n return sendResponse(res, {\n code: 500,\n msg: 'AI 解析失败,请稍后重试'\n });\n }\n};\n\nconst extractJson = (content) => {\n const jsonMatch = content.match(/```json\\s*([\\s\\S]*?)\\s*```/i)\n || content.match(/```\\s*([\\s\\S]*?)\\s*```/i);\n return jsonMatch ? jsonMatch[1] : content;\n};\n\nconst callDeepSeekAPI = async (userText, categories) => {\n const apiUrl = process.env.DEEPSEEK_API_URL || 'https://www.dmxapi.cn/v1/chat/completions';\n const apiKey = process.env.DEEPSEEK_API_KEY;\n const model = process.env.DEEPSEEK_MODEL || 'DeepSeek-V3.2';\n const timeout = parseInt(process.env.DEEPSEEK_TIMEOUT_MS, 10) || 30000;\n\n const today = new Date().toISOString().split('T')[0];\n const payload = {\n model,\n messages: [\n {\n role: 'system',\n content: `你是一个账单处理系统,只返回 JSON 数据,不需要任何其他文字说明。\n今天日期:${today}\n规则:\n1. 从用户描述中提取所有账单项\n2. 每笔账单必须包含:categoryId(分类ID)、amount(金额,正数)、date(交易日期,YYYY-MM-DD)、description(备注)\n3. 如果用户未明确日期,date 使用今天(YYYY-MM-DD)\n4. 根据分类的 type 字段判断收入还是支出\n5. 如果无法识别分类,使用最相近的分类\n6. 金额必须是数字,不要包含货币符号\n7. 返回格式:[{\"categoryId\": 数字, \"amount\": 数字, \"date\": \"YYYY-MM-DD\", \"description\": \"字符串\"}]`\n },\n {\n role: 'user',\n content: `可用分类数据:\\n${JSON.stringify(categories, null, 2)}`\n },\n {\n role: 'user',\n content: `用户账单描述:${userText}`\n },\n {\n role: 'user',\n content: '请解析账单并返回 JSON 数组格式:[{\"categoryId\": xxx, \"amount\": xxx, \"date\": \"YYYY-MM-DD\", \"description\": \"xxx\"}]'\n }\n ],\n temperature: 0.2\n };\n\n try {\n const response = await axios.post(apiUrl, payload, {\n headers: {\n // 如需 Bearer 前缀,请在环境变量中自行拼接\n Authorization: apiKey,\n 'Content-Type': 'application/json'\n },\n timeout\n });\n\n const content = response.data?.choices?.[0]?.message?.content;\n if (!content) {\n return { success: false, error: 'AI 响应格式异常' };\n }\n\n const jsonText = extractJson(content.trim());\n const parsed = JSON.parse(jsonText);\n const bills = Array.isArray(parsed) ? parsed : parsed?.bills;\n\n if (!Array.isArray(bills)) {\n return { success: false, error: 'AI 返回数据格式错误' };\n }\n\n return { success: true, data: bills };\n } catch (error) {\n console.error('调用 AI API 失败:', error?.response?.data || error.message || error);\n return { success: false, error: 'AI 请求失败' };\n }\n};\n"}}}}