| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144 |
- 'use strict';
- const axios = require('axios');
- const DOCUMENT_EXTENSIONS = ['pdf', 'doc', 'docx'];
- const IMAGE_EXTENSIONS = ['jpg', 'jpeg', 'png', 'webp'];
- class AiDify {
- /**
- * 构造函数
- * @param {object} config
- * @param {string} config.apiKey - Dify API Key
- * @param {string} config.chatflowId - ChatFlow ID
- * @param {string} [config.baseUrl=https://api.dify.ai/v1] - Dify API 接口地址
- */
- constructor({ apiKey = 'app-fiJr1pNxjdKXpetko8ANawnY', chatflowId = '', baseUrl = 'http://workflow.smartcost.com.cn/v1' }) {
- if (!apiKey) {
- throw new Error('apiKey 不能为空');
- }
- this.apiKey = apiKey;
- this.chatflowId = chatflowId;
- this.baseUrl = baseUrl;
- }
- /**
- * 向 ChatFlow 发送请求
- * @param {string} userInput - 用户输入内容
- * @param {string} [userId='user_123'] - 用户 ID
- * @returns {Promise<object>} - Dify 返回的对象
- */
- async ask(userInput, userId = 'user_123') {
- const url = `${this.baseUrl}/chat-messages`;
- const headers = {
- 'Authorization': `Bearer ${this.apiKey}`,
- 'Content-Type': 'application/json',
- };
- const body = {
- inputs: {}, // 如果你的 ChatFlow 有 schema,可填写 key-value
- query: userInput,
- response_mode: 'blocking',
- user: userId,
- conversation_id: this.chatflowId,
- };
- try {
- const res = await axios.post(url, body, { headers });
- return res.data;
- } catch (err) {
- console.error('Dify 请求失败:', err.response || err.response.data || err.message);
- throw new Error('Dify 请求失败');
- }
- }
- async workflows(body) {
- const url = `${this.baseUrl}/workflows/run`;
- const headers = {
- 'Authorization': `Bearer ${this.apiKey}`,
- 'Content-Type': 'application/json',
- };
- try {
- const res = await axios.post(url, body, { headers });
- return res.data.data.outputs;
- } catch (err) {
- console.error('Dify 请求失败:', err.response || err.response.data || err.message);
- throw new Error('Dify 请求失败');
- }
- }
- async posCalcDetailRead(col, billsName, keyword, files, userId = `user_123`) {
- const body = {
- inputs: {
- header: col.map(x => { return x.title + (x.unit ? `(${x.unit})` : '') }).join(','),
- billsName,
- keyword,
- imgList: [],
- },
- user: userId,
- };
- for (const f of files) {
- body.inputs.imgList.push({
- type: "image",
- transfer_method: "remote_url",
- url: f.viewpath,
- })
- }
- return await this.workflows(body);
- }
- async imageTransExcel(files, userId = `user_123`) {
- const body = {
- inputs: { imgList: [] },
- user: userId,
- response_mode: 'blocking',
- };
- for (const f of files) {
- body.inputs.imgList.push({
- type: "image",
- transfer_method: "remote_url",
- url: f.viewpath,
- })
- }
- return await this.workflows(body);
- }
- async billsIdentify(name, unit, userId = `user_123`) {
- const body = {
- inputs: { billsName: name || '' + ( unit ? `(${unit})` : '') },
- user: userId,
- response_mode: 'blocking',
- };
- return await this.workflows(body);
- }
- /**
- * 根据文件名后缀判断 Dify 的 type 字段(image / document)
- */
- resolveDifyFileType(filename = '') {
- const ext = filename ? filename.split('.').pop().toLowerCase() : '';
- if (IMAGE_EXTENSIONS.includes(ext)) return 'image';
- if (DOCUMENT_EXTENSIONS.includes(ext)) return 'document';
- // 无法判断时默认按document处理,让Dify那边自行兜底
- return 'document';
- }
- async contractTrans(file, userId = 'user_123') {
- const body = {
- inputs: { fileList: [] },
- user: userId,
- response_mode: 'blocking',
- };
- if (!file.viewpath) {
- throw new Error('文件缺少viewpath字段');
- }
- const fileType = this.resolveDifyFileType(file.filename);
- body.inputs.fileList.push({
- type: fileType,
- transfer_method: 'remote_url',
- url: file.viewpath,
- });
- return await this.workflows(body);
- }
- }
- module.exports = AiDify;
|