You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

234 lines
8.6 KiB

// 简道云API服务
const axios = require('axios');
const config = require('../config/config');
class JiandaoyunService {
constructor() {
// 简道云API基础配置
this.baseUrl = 'https://api.jiandaoyun.com';
this.apiKey = config.jiandaoyun.apiKey;
this.appId = config.jiandaoyun.appId;
this.entryId = config.jiandaoyun.entryId;
}
// 提交数据到简道云表单
async submitDataToForm(data) {
try {
console.log('准备提交数据到简道云:', JSON.stringify(data, null, 2));
// 简道云API v1的正确请求格式 - 使用data_create端点
const url = `${this.baseUrl}/api/v1/app/${this.appId}/entry/${this.entryId}/data_create`;
const headers = {
'Content-Type': 'application/json',
'Authorization': `Bearer ${this.apiKey}`
};
// 简道云API v1只需要在请求体中包含data字段
const payload = {
data: data
};
console.log('请求URL:', url);
console.log('请求头:', headers);
console.log('请求体:', JSON.stringify(payload, null, 2));
const response = await axios.post(url, payload, { headers });
console.log('简道云API调用成功:', response.data);
return response.data;
} catch (error) {
console.error('简道云API调用失败:', error.message);
if (error.response) {
console.error('响应状态:', error.response.status);
console.error('响应数据:', JSON.stringify(error.response.data, null, 2));
console.error('响应头:', JSON.stringify(error.response.headers, null, 2));
if (error.config) {
console.error('请求URL:', error.config.url);
console.error('请求头:', JSON.stringify(error.config.headers, null, 2));
console.error('请求数据:', error.config.data);
}
}
throw error;
}
}
// 将数据库数据转换为简道云表单所需格式
transformDataToJiandaoyunFormat(databaseData) {
console.log('开始转换数据:', JSON.stringify(databaseData, null, 2));
const jiandaoyunData = {};
const mapping = config.fieldMapping;
// 转换主表数据
const user = databaseData.user;
console.log('用户数据:', JSON.stringify(user, null, 2));
console.log('字段映射:', JSON.stringify(mapping, null, 2));
// 使用简道云API v1的正确值格式,使用value字段来包装值
jiandaoyunData[mapping.userId] = { value: user.userId || '' };
jiandaoyunData[mapping.company] = { value: user.company || '' };
jiandaoyunData[mapping.nickName] = { value: user.name || '' };
jiandaoyunData[mapping.phoneNumber] = { value: user.phoneNumber || '' };
jiandaoyunData[mapping.type] = { value: user.type || '' };
jiandaoyunData[mapping.city] = { value: user.city || '' };
// 转换cart_items数据(buyer)
const cartItems = databaseData.cartItems;
console.log('购物车数据:', JSON.stringify(cartItems, null, 2));
if (cartItems.length > 0) {
const firstCartItem = cartItems[0];
jiandaoyunData[mapping['productName-buyer']] = { value: firstCartItem.productName || '' };
jiandaoyunData[mapping['specification-buyer']] = { value: firstCartItem.specification || '' };
jiandaoyunData[mapping['quantity-buyer']] = { value: firstCartItem.quantity || '' };
// 计算毛重:数量 * 规格中的克数
const specification = firstCartItem.specification || '';
const weightPerUnit = parseInt(specification.match(/(\d+)克/)?.[1] || '0');
const quantity = parseInt(firstCartItem.quantity || '0');
const grossWeight = weightPerUnit * quantity;
jiandaoyunData[mapping['grossWeight-buyer']] = { value: grossWeight.toString() };
jiandaoyunData[mapping['yolk-buyer']] = { value: firstCartItem.yolk || '' };
}
// 转换products数据(sell)
const products = databaseData.products;
console.log('产品数据:', JSON.stringify(products, null, 2));
if (products.length > 0) {
const firstProduct = products[0];
jiandaoyunData[mapping['productName-sell']] = { value: firstProduct.productName || '' };
jiandaoyunData[mapping['specification-sell']] = { value: firstProduct.specification || '' };
jiandaoyunData[mapping['quantity-sell']] = { value: firstProduct.quantity || '' };
// 计算毛重:数量 * 规格中的克数
const specification = firstProduct.specification || '';
const weightPerUnit = parseInt(specification.match(/(\d+)克/)?.[1] || '0');
const quantity = parseInt(firstProduct.quantity || '0');
const grossWeight = weightPerUnit * quantity;
jiandaoyunData[mapping['grossWeight-sell']] = { value: grossWeight.toString() };
jiandaoyunData[mapping['yolk-sell']] = { value: firstProduct.yolk || '' };
}
console.log('转换后的数据:', JSON.stringify(jiandaoyunData, null, 2));
return jiandaoyunData;
}
// 查询简道云表单中是否存在指定电话号码的数据
async isPhoneNumberExists(phoneNumber) {
try {
const mapping = config.fieldMapping;
const url = `${this.baseUrl}/api/v1/app/${this.appId}/entry/${this.entryId}/data_list`;
const headers = {
'Content-Type': 'application/json',
'Authorization': `Bearer ${this.apiKey}`
};
// 构建查询条件:电话号码字段等于指定值
const payload = {
filter: {
rel: 'and',
cond: [
{
field: mapping.phoneNumber,
type: 'text',
method: 'eq',
value: phoneNumber
}
]
},
page_size: 1 // 只需要知道是否存在,不需要返回所有结果
};
const response = await axios.post(url, payload, { headers });
// 如果返回的数据数量大于0,则表示该电话号码已存在
return response.data.data.length > 0;
} catch (error) {
console.error('查询电话号码是否存在失败:', error.message);
if (error.response) {
console.error('响应状态:', error.response.status);
console.error('响应数据:', error.response.data);
}
// 发生错误时,为了避免数据丢失,默认返回false,表示不存在该电话号码
return false;
}
}
// 批量提交数据到简道云
async batchSubmitData(dataList) {
const results = [];
for (const data of dataList) {
try {
// 检查电话号码是否已存在
const phoneNumber = data.user.phoneNumber;
const exists = await this.isPhoneNumberExists(phoneNumber);
if (exists) {
console.log(`电话号码 ${phoneNumber} 已存在于简道云表单中,跳过同步`);
results.push({
success: true,
skipped: true,
message: `电话号码 ${phoneNumber} 已存在,跳过同步`,
originalData: data
});
continue;
}
// 转换数据格式
const jiandaoyunData = this.transformDataToJiandaoyunFormat(data);
// 提交数据
const result = await this.submitDataToForm(jiandaoyunData);
results.push({
success: true,
data: result,
originalData: data
});
console.log('数据提交成功:', result);
} catch (error) {
results.push({
success: false,
error: error.message,
originalData: data
});
console.error('数据提交失败:', error.message);
}
}
return results;
}
// 测试简道云API连接
async testApiConnection() {
try {
console.log('===== 测试简道云API连接 =====');
// 使用fieldMapping来构建测试数据,验证字段映射是否正确
const mapping = config.fieldMapping;
const testData = {
[mapping.userId]: { value: '123456' }, // 测试用户ID
[mapping.company]: { value: '测试公司' },
[mapping.nickName]: { value: '测试联系人' },
[mapping.phoneNumber]: { value: '13800138000' },
[mapping.type]: { value: '零售客户' }, // 测试客户类型
[mapping.city]: { value: '北京' } // 测试地区
};
const response = await this.submitDataToForm(testData);
console.log('简道云API连接成功');
return true;
} catch (error) {
console.error('简道云API连接失败:', error.message);
if (error.response) {
console.error('响应状态:', error.response.status);
console.error('响应数据:', error.response.data);
}
console.error('错误堆栈:', error.stack);
return false;
}
}
}
module.exports = new JiandaoyunService();