diff --git a/index.js b/index.js index 3d7641a..b199f59 100644 --- a/index.js +++ b/index.js @@ -24,17 +24,8 @@ async function syncData() { console.log('开始向简道云提交数据...'); const results = await jiandaoyunService.batchSubmitData(syncData, connection); - // 4. 更新同步状态 - console.log('\n更新同步状态...'); - for (let i = 0; i < results.length; i++) { - const result = results[i]; - const data = syncData[i]; - - if (result.success && !result.skipped) { - // 同步成功且未被跳过,更新状态为已同步 - await databaseService.updateSyncStatus(data.userId, true); - } - } + // 4. 同步状态已在jiandaoyunService.js中更新,此处不再重复更新 + console.log('\n同步状态已在提交过程中更新'); // 5. 统计结果 const successCount = results.filter(result => result.success).length; @@ -131,4 +122,4 @@ async function startAutoSync() { main().catch(error => { console.error('程序执行失败:', error.message); process.exit(1); -}); +}); \ No newline at end of file diff --git a/src/config/config.js b/src/config/config.js index 8049c7c..c2c062b 100644 --- a/src/config/config.js +++ b/src/config/config.js @@ -36,15 +36,102 @@ module.exports = { } }, - // 简道云配置 + // 简道云配置 - 根据sync_statuss值不同使用不同配置 jiandaoyun: { - appId: '684bd1da61702bed58d15d13', - entryId: '6822e45e5b34abd7d81f34b5', - apiKey: 'JgTzhmiwlwzz4LWl4dJ4FGZ6yr3VqxoW', - apiUrl: 'https://api.jiandaoyun.com/api/v1' + default: { + appId: '684bd1da61702bed58d15d13', + entryId: '6822e45e5b34abd7d81f34b5', + apiKey: 'JgTzhmiwlwzz4LWl4dJ4FGZ6yr3VqxoW', + apiUrl: 'https://api.jiandaoyun.com/api/v1', + fieldMapping: { + 'userId': '_widget_1767422700667', + 'userName': '_widget_1747117151082', + 'company': '_widget_1747117151075', + 'level': '_widget_1755333366982', + 'demand': '_widget_1757035166649', + 'region': '_widget_1749864292852', + 'detailedaddress': '_widget_1747204368174', + 'type': '_widget_1768897870066', + 'followup': '_widget_1767426290793' + }, + subTableFields: { + 'subTable': '_widget_1747117151085', + 'nickName': '_widget_1747117151087', + 'phoneNumber': '_widget_1747117151088', + 'detailedaddress': '_widget_1747204368174' + } + }, + // sync_statuss=1时的配置 + 1: { + appId: '684bd1da61702bed58d15d13', + entryId: '6822f75848b106daeab8a284', + apiKey: 'JgTzhmiwlwzz4LWl4dJ4FGZ6yr3VqxoW', + apiUrl: 'https://api.jiandaoyun.com/api/v1', + fieldMapping: { + 'userId': '_widget_1767426694297', + 'userName': '_widget_1747186159197', + 'company': '_widget_1747122009104', + 'level': '_widget_1754983406535', + 'demand': '_widget_1749870821108', + 'region': '_widget_1749870420548', + 'detailedaddress': '_widget_1747204368174', + 'type': '_widget_1747122009109', + 'followup': '_widget_1767426694300' + }, + subTableFields: { + 'subTable': '_widget_1747122009118', + 'nickName': '_widget_1747122009120', + 'phoneNumber': '_widget_1747122009121', + 'detailedaddress': '_widget_1747204368174' + } + }, + // sync_statuss=2时的配置 + 2: { + appId: '681db12023f2ca535ff29cfc', + entryId: '681dc81e821222305984219e', + apiKey: 'JgTzhmiwlwzz4LWl4dJ4FGZ6yr3VqxoW', + apiUrl: 'https://api.jiandaoyun.com/api/v1', + fieldMapping: { + 'userId': '_widget_1769138938780', + 'userName': '_widget_1747364014473', + 'company': '_widget_1746782238762', + 'level': '_widget_1746782238764', + 'demand': '_widget_1747374154860', + 'region': '_widget_1749870420548', + 'detailedaddress': '_widget_1747204368174', + 'type': '_widget_1746782238763', + 'followup': '_widget_1769138938795' + }, + subTableFields: { + 'subTable': '_widget_1747105269437', + 'nickName': '_widget_1747105269440', + 'phoneNumber': '_widget_1747364014484', + 'detailedaddress': '_widget_1747204368174' + } + }, + // sync_statuss=3时的配置 + 3: { + appId: '681db12023f2ca535ff29cfc', + entryId: '6826ec6872f007130d304d9c', + apiKey: 'JgTzhmiwlwzz4LWl4dJ4FGZ6yr3VqxoW', + apiUrl: 'https://api.jiandaoyun.com/api/v1', + fieldMapping: { + 'userId': '_widget_1769157566033', + 'userName': '_widget_1747381352563', + 'company': '_widget_1747381352567', + 'demand': '_widget_1747381352569', + 'type': '_widget_1747381352568', + 'followup': '_widget_1769157566032' + }, + subTableFields: { + 'subTable': '_widget_1747385370675', + 'nickName': '_widget_1747385370677', + 'phoneNumber': '_widget_1747385370678' + } + } }, - // 字段映射关系 + // 保持原配置结构兼容,默认使用default配置 fieldMapping: { 'userId': '_widget_1767422700667', 'userName': '_widget_1747117151082', @@ -57,7 +144,7 @@ module.exports = { 'followup': '_widget_1767426290793' }, - // 子表字段配置 + // 保持原配置结构兼容,默认使用default配置 subTableFields: { 'subTable': '_widget_1747117151085', 'nickName': '_widget_1747117151087', @@ -72,7 +159,7 @@ module.exports = { // 同步状态字段 statusField: 'sync_statuss', // 已同步状态值 - syncedValue: 1, + syncedValue: 4, // 未同步状态值 unsyncedValue: 0, // 自动同步配置 diff --git a/src/services/databaseService.js b/src/services/databaseService.js index 8b3a1d5..a544a73 100644 --- a/src/services/databaseService.js +++ b/src/services/databaseService.js @@ -47,13 +47,14 @@ class DatabaseService { ${config.tables.users.fields.detailedaddress}, ${config.tables.users.fields.type}, ${config.tables.users.fields.followup}, + ${config.sync.statusField}, dataid FROM ${config.tables.users.name}`; - // 如果是增量同步,查询未同步的数据 + // 如果是增量同步,查询sync_statuss为0、1、2、3的数据(只有4是已同步状态) if (config.sync.incremental) { - usersQuery += ` WHERE ${config.sync.statusField} = ${config.sync.unsyncedValue}`; - console.log('启用增量同步模式,查询未同步数据'); + usersQuery += ` WHERE ${config.sync.statusField} IN (0, 1, 2, 3)`; + console.log('启用增量同步模式,查询sync_statuss为0、1、2、3的数据'); } else { console.log('启用全量同步模式,查询所有数据'); } diff --git a/src/services/jiandaoyunService.js b/src/services/jiandaoyunService.js index 1c9ed97..35bc850 100644 --- a/src/services/jiandaoyunService.js +++ b/src/services/jiandaoyunService.js @@ -6,9 +6,8 @@ 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; + // 从配置中获取apiKey(所有表单共享) + this.apiKey = config.jiandaoyun.default.apiKey; // 人员简道云编号映射表 this.userNameToUsernameMap = { @@ -33,11 +32,26 @@ class JiandaoyunService { }; } + // 根据syncStatus获取对应的表单配置 + getFormConfig(syncStatus) { + // 如果syncStatus为0或未定义,使用默认配置 + if (!syncStatus || syncStatus === 0) { + return config.jiandaoyun.default; + } + // 否则使用对应的配置,如果不存在则使用默认配置 + return config.jiandaoyun[syncStatus] || config.jiandaoyun.default; + } + // 提交数据到简道云表单 - async submitDataToForm(data, userManagement = null) { + async submitDataToForm(data, userManagement = null, syncStatus = 0) { try { console.log('准备提交数据到简道云:', JSON.stringify(data, null, 2)); + // 根据syncStatus获取对应的表单配置 + const formConfig = this.getFormConfig(syncStatus); + const appId = formConfig.appId; + const entryId = formConfig.entryId; + // 使用简道云API v5版本,支持data_creator参数 const url = `${this.baseUrl}/api/v5/app/entry/data/create`; const headers = { @@ -61,8 +75,8 @@ class JiandaoyunService { // 构建请求体,添加data_creator参数 const payload = { - app_id: this.appId, - entry_id: this.entryId, + app_id: appId, + entry_id: entryId, data: data, data_creator: dataCreator }; @@ -92,11 +106,16 @@ class JiandaoyunService { } // 将数据库数据转换为简道云表单所需格式 - transformDataToJiandaoyunFormat(databaseData) { + transformDataToJiandaoyunFormat(databaseData, syncStatus) { console.log('开始转换数据:', JSON.stringify(databaseData, null, 2)); + console.log('使用的syncStatus:', syncStatus); + + // 根据syncStatus获取对应的表单配置 + const formConfig = this.getFormConfig(syncStatus); + const mapping = formConfig.fieldMapping; + const subTableConfig = formConfig.subTableFields; const jiandaoyunData = {}; - const mapping = config.fieldMapping; // 转换主表数据 const user = databaseData.user; @@ -131,12 +150,12 @@ class JiandaoyunService { jiandaoyunData[mapping.followup] = { value: user.followup || '' }; // 处理子表字段 - const subTableField = config.subTableFields.subTable; + const subTableField = subTableConfig.subTable; const subTableData = [{ - [config.subTableFields.nickName]: { value: user.nickName || '' }, - [config.subTableFields.phoneNumber]: { value: user.phoneNumber || '' }, + [subTableConfig.nickName]: { value: user.nickName || '' }, + [subTableConfig.phoneNumber]: { value: user.phoneNumber || '' }, // 地址字段直接作为字符串写入子表 - [config.subTableFields.detailedaddress]: { value: user.detailedaddress || '' } + [subTableConfig.detailedaddress]: { value: user.detailedaddress || '' } }]; jiandaoyunData[subTableField] = { value: subTableData }; @@ -209,27 +228,31 @@ class JiandaoyunService { console.log(`从数据库获取到简道云记录ID: ${recordId}`); } + // 获取sync_statuss值,默认为0 + const syncStatus = item.user[config.sync.statusField] || 0; + console.log(`当前用户的sync_statuss值: ${syncStatus}`); + if (recordId) { console.log(`使用记录ID ${recordId} 更新数据`); - // 转换数据格式 - const jiandaoyunData = this.transformDataToJiandaoyunFormat(item); + // 转换数据格式,传递syncStatus + const jiandaoyunData = this.transformDataToJiandaoyunFormat(item, syncStatus); try { - // 更新数据,传递userManagement参数 - const result = await this.updateDataInForm(recordId, jiandaoyunData, item.userManagement); + // 更新数据,传递userManagement参数和syncStatus + const result = await this.updateDataInForm(recordId, jiandaoyunData, item.userManagement, syncStatus); // 更新数据库中的同步状态 if (dbConnection && item.user && item.user.userId) { try { - console.log(`更新用户 ${item.user.userId} 的同步状态`); + console.log(`更新用户 ${item.user.userId} 的同步状态为${config.sync.syncedValue}`); const [updateResult] = await dbConnection.execute( `UPDATE ${config.tables.users.name} SET ${config.sync.statusField} = ${config.sync.syncedValue} WHERE userId = ?`, [item.user.userId] ); if (updateResult.affectedRows > 0) { - console.log(`✅ 成功更新用户 ${item.user.userId} 的同步状态`); + console.log(`✅ 成功更新用户 ${item.user.userId} 的同步状态为${config.sync.syncedValue}`); } else { console.log(`⚠️ 更新用户 ${item.user.userId} 的同步状态失败: 未找到匹配的用户`); } @@ -271,11 +294,11 @@ class JiandaoyunService { } } - // 转换数据格式 - const jiandaoyunData = this.transformDataToJiandaoyunFormat(item); + // 转换数据格式,传递syncStatus + const jiandaoyunData = this.transformDataToJiandaoyunFormat(item, syncStatus); - // 提交数据,传递userManagement参数 - const result = await this.submitDataToForm(jiandaoyunData, item.userManagement); + // 提交数据,传递userManagement参数和syncStatus + const result = await this.submitDataToForm(jiandaoyunData, item.userManagement, syncStatus); // 保存返回的记录ID到数据库 console.log('检查返回结果结构:', JSON.stringify(result, null, 2)); @@ -286,7 +309,7 @@ class JiandaoyunService { if (dbConnection && item.user && item.user.userId) { try { - console.log(`准备更新用户 ${item.user.userId} 的dataid为 ${newRecordId} 并设置同步状态`); + console.log(`准备更新用户 ${item.user.userId} 的dataid为 ${newRecordId} 并设置同步状态为${config.sync.syncedValue}`); const [updateResult] = await dbConnection.execute( `UPDATE ${config.tables.users.name} SET dataid = ?, ${config.sync.statusField} = ${config.sync.syncedValue} WHERE userId = ?`, [newRecordId, item.user.userId] @@ -294,7 +317,7 @@ class JiandaoyunService { console.log(`数据库更新结果:`, updateResult); if (updateResult.affectedRows > 0) { - console.log(`✅ 成功将简道云记录ID ${newRecordId} 保存到数据库并更新同步状态`); + console.log(`✅ 成功将简道云记录ID ${newRecordId} 保存到数据库并更新同步状态为${config.sync.syncedValue}`); } else { console.log(`⚠️ 更新用户 ${item.user.userId} 的dataid和同步状态失败: 未找到匹配的用户`); } @@ -349,8 +372,13 @@ class JiandaoyunService { } // 更新简道云表单中的数据 - async updateDataInForm(recordId, data, userManagement = null) { + async updateDataInForm(recordId, data, userManagement = null, syncStatus = 0) { try { + // 根据syncStatus获取对应的表单配置 + const formConfig = this.getFormConfig(syncStatus); + const appId = formConfig.appId; + const entryId = formConfig.entryId; + // 使用简道云API v5版本,支持data_creator参数 const url = `${this.baseUrl}/api/v5/app/entry/data/update`; const headers = { @@ -374,8 +402,8 @@ class JiandaoyunService { // 构建更新请求体:记录ID和要更新的数据 const payload = { - app_id: this.appId, - entry_id: this.entryId, + app_id: appId, + entry_id: entryId, data_id: recordId, data: data, data_creator: dataCreator @@ -389,13 +417,13 @@ class JiandaoyunService { console.log('更新响应:', JSON.stringify(response.data, null, 2)); return response.data; } catch (error) { - console.error('更新数据失败:', error.message); - if (error.response) { - console.error('响应状态:', error.response.status); - console.error('响应数据:', JSON.stringify(error.response.data, null, 2)); + console.error('更新数据失败:', error.message); + if (error.response) { + console.error('响应状态:', error.response.status); + console.error('响应数据:', JSON.stringify(error.response.data, null, 2)); + } + throw error; } - throw error; - } } // 测试简道云API连接 diff --git a/test-single-user.js b/test-single-user.js deleted file mode 100644 index 3efde98..0000000 --- a/test-single-user.js +++ /dev/null @@ -1,72 +0,0 @@ -// 测试单个用户数据同步 -const mysql = require('mysql2/promise'); -const config = require('./src/config/config'); -const jiandaoyunService = require('./src/services/jiandaoyunService'); - -async function testSingleUserSync() { - console.log('===== 测试单个用户数据同步 ====='); - - try { - // 连接数据库 - const connection = await mysql.createConnection(config.db); - - // 查询指定用户数据 - const [users] = await connection.execute( - `SELECT DISTINCT ${config.tables.users.fields.userId}, - ${config.tables.users.fields.nickName}, - ${config.tables.users.fields.phoneNumber}, - ${config.tables.users.fields.company}, - ${config.tables.users.fields.level}, - ${config.tables.users.fields.demand}, - ${config.tables.users.fields.region}, - ${config.tables.users.fields.detailedaddress}, - ${config.tables.users.fields.type}, - dataid - FROM ${config.tables.users.name} - WHERE ${config.tables.users.fields.userId} = ?`, - ['user_1768360161521_zz8rtwtip'] - ); - - if (users.length === 0) { - console.log('未找到指定用户数据'); - return; - } - - const user = users[0]; - console.log('用户数据:', JSON.stringify(user, null, 2)); - - // 查询负责人信息 - const [userManagements] = await connection.execute( - `SELECT ${config.tables.userManagements.fields.userName} - FROM ${config.tables.userManagements.name} - WHERE ${config.tables.userManagements.fields.userId} = ?`, - [user.userId] - ); - - const syncData = [{ - user: user, - userManagement: userManagements[0] || {}, - userId: user.userId - }]; - - // 转换数据格式 - const transformedData = jiandaoyunService.transformDataToJiandaoyunFormat(syncData[0]); - console.log('转换后的数据:', JSON.stringify(transformedData, null, 2)); - - // 检查地址字段是否正确包含在子表中 - const subTableData = transformedData[config.subTableFields.subTable].value; - console.log('子表数据:', JSON.stringify(subTableData, null, 2)); - - // 执行同步 - const results = await jiandaoyunService.batchSubmitData(syncData, connection); - console.log('同步结果:', JSON.stringify(results, null, 2)); - - await connection.end(); - console.log('测试完成'); - } catch (error) { - console.error('测试过程中发生错误:', error.message); - console.error('错误堆栈:', error.stack); - } -} - -testSingleUserSync();