Browse Source

完成简道云动态配置和同步状态管理功能

JDY3
Trae AI 1 month ago
parent
commit
719285eda0
  1. 13
      index.js
  2. 103
      src/config/config.js
  3. 7
      src/services/databaseService.js
  4. 94
      src/services/jiandaoyunService.js
  5. 72
      test-single-user.js

13
index.js

@ -24,17 +24,8 @@ async function syncData() {
console.log('开始向简道云提交数据...'); console.log('开始向简道云提交数据...');
const results = await jiandaoyunService.batchSubmitData(syncData, connection); const results = await jiandaoyunService.batchSubmitData(syncData, connection);
// 4. 更新同步状态 // 4. 同步状态已在jiandaoyunService.js中更新,此处不再重复更新
console.log('\n更新同步状态...'); 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);
}
}
// 5. 统计结果 // 5. 统计结果
const successCount = results.filter(result => result.success).length; const successCount = results.filter(result => result.success).length;

103
src/config/config.js

@ -36,15 +36,102 @@ module.exports = {
} }
}, },
// 简道云配置 // 简道云配置 - 根据sync_statuss值不同使用不同配置
jiandaoyun: { jiandaoyun: {
appId: '684bd1da61702bed58d15d13', default: {
entryId: '6822e45e5b34abd7d81f34b5', appId: '684bd1da61702bed58d15d13',
apiKey: 'JgTzhmiwlwzz4LWl4dJ4FGZ6yr3VqxoW', entryId: '6822e45e5b34abd7d81f34b5',
apiUrl: 'https://api.jiandaoyun.com/api/v1' 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: { fieldMapping: {
'userId': '_widget_1767422700667', 'userId': '_widget_1767422700667',
'userName': '_widget_1747117151082', 'userName': '_widget_1747117151082',
@ -57,7 +144,7 @@ module.exports = {
'followup': '_widget_1767426290793' 'followup': '_widget_1767426290793'
}, },
// 子表字段配置 // 保持原配置结构兼容,默认使用default配置
subTableFields: { subTableFields: {
'subTable': '_widget_1747117151085', 'subTable': '_widget_1747117151085',
'nickName': '_widget_1747117151087', 'nickName': '_widget_1747117151087',
@ -72,7 +159,7 @@ module.exports = {
// 同步状态字段 // 同步状态字段
statusField: 'sync_statuss', statusField: 'sync_statuss',
// 已同步状态值 // 已同步状态值
syncedValue: 1, syncedValue: 4,
// 未同步状态值 // 未同步状态值
unsyncedValue: 0, unsyncedValue: 0,
// 自动同步配置 // 自动同步配置

7
src/services/databaseService.js

@ -47,13 +47,14 @@ class DatabaseService {
${config.tables.users.fields.detailedaddress}, ${config.tables.users.fields.detailedaddress},
${config.tables.users.fields.type}, ${config.tables.users.fields.type},
${config.tables.users.fields.followup}, ${config.tables.users.fields.followup},
${config.sync.statusField},
dataid dataid
FROM ${config.tables.users.name}`; FROM ${config.tables.users.name}`;
// 如果是增量同步,查询未同步的数据 // 如果是增量同步,查询sync_statuss为0、1、2、3的数据(只有4是已同步状态)
if (config.sync.incremental) { if (config.sync.incremental) {
usersQuery += ` WHERE ${config.sync.statusField} = ${config.sync.unsyncedValue}`; usersQuery += ` WHERE ${config.sync.statusField} IN (0, 1, 2, 3)`;
console.log('启用增量同步模式,查询未同步数据'); console.log('启用增量同步模式,查询sync_statuss为0、1、2、3的数据');
} else { } else {
console.log('启用全量同步模式,查询所有数据'); console.log('启用全量同步模式,查询所有数据');
} }

94
src/services/jiandaoyunService.js

@ -6,9 +6,8 @@ class JiandaoyunService {
constructor() { constructor() {
// 简道云API基础配置 // 简道云API基础配置
this.baseUrl = 'https://api.jiandaoyun.com'; this.baseUrl = 'https://api.jiandaoyun.com';
this.apiKey = config.jiandaoyun.apiKey; // 从配置中获取apiKey(所有表单共享)
this.appId = config.jiandaoyun.appId; this.apiKey = config.jiandaoyun.default.apiKey;
this.entryId = config.jiandaoyun.entryId;
// 人员简道云编号映射表 // 人员简道云编号映射表
this.userNameToUsernameMap = { 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 { try {
console.log('准备提交数据到简道云:', JSON.stringify(data, null, 2)); 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参数 // 使用简道云API v5版本,支持data_creator参数
const url = `${this.baseUrl}/api/v5/app/entry/data/create`; const url = `${this.baseUrl}/api/v5/app/entry/data/create`;
const headers = { const headers = {
@ -61,8 +75,8 @@ class JiandaoyunService {
// 构建请求体,添加data_creator参数 // 构建请求体,添加data_creator参数
const payload = { const payload = {
app_id: this.appId, app_id: appId,
entry_id: this.entryId, entry_id: entryId,
data: data, data: data,
data_creator: dataCreator data_creator: dataCreator
}; };
@ -92,11 +106,16 @@ class JiandaoyunService {
} }
// 将数据库数据转换为简道云表单所需格式 // 将数据库数据转换为简道云表单所需格式
transformDataToJiandaoyunFormat(databaseData) { transformDataToJiandaoyunFormat(databaseData, syncStatus) {
console.log('开始转换数据:', JSON.stringify(databaseData, null, 2)); 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 jiandaoyunData = {};
const mapping = config.fieldMapping;
// 转换主表数据 // 转换主表数据
const user = databaseData.user; const user = databaseData.user;
@ -131,12 +150,12 @@ class JiandaoyunService {
jiandaoyunData[mapping.followup] = { value: user.followup || '' }; jiandaoyunData[mapping.followup] = { value: user.followup || '' };
// 处理子表字段 // 处理子表字段
const subTableField = config.subTableFields.subTable; const subTableField = subTableConfig.subTable;
const subTableData = [{ const subTableData = [{
[config.subTableFields.nickName]: { value: user.nickName || '' }, [subTableConfig.nickName]: { value: user.nickName || '' },
[config.subTableFields.phoneNumber]: { value: user.phoneNumber || '' }, [subTableConfig.phoneNumber]: { value: user.phoneNumber || '' },
// 地址字段直接作为字符串写入子表 // 地址字段直接作为字符串写入子表
[config.subTableFields.detailedaddress]: { value: user.detailedaddress || '' } [subTableConfig.detailedaddress]: { value: user.detailedaddress || '' }
}]; }];
jiandaoyunData[subTableField] = { value: subTableData }; jiandaoyunData[subTableField] = { value: subTableData };
@ -209,27 +228,31 @@ class JiandaoyunService {
console.log(`从数据库获取到简道云记录ID: ${recordId}`); console.log(`从数据库获取到简道云记录ID: ${recordId}`);
} }
// 获取sync_statuss值,默认为0
const syncStatus = item.user[config.sync.statusField] || 0;
console.log(`当前用户的sync_statuss值: ${syncStatus}`);
if (recordId) { if (recordId) {
console.log(`使用记录ID ${recordId} 更新数据`); console.log(`使用记录ID ${recordId} 更新数据`);
// 转换数据格式 // 转换数据格式,传递syncStatus
const jiandaoyunData = this.transformDataToJiandaoyunFormat(item); const jiandaoyunData = this.transformDataToJiandaoyunFormat(item, syncStatus);
try { try {
// 更新数据,传递userManagement参数 // 更新数据,传递userManagement参数和syncStatus
const result = await this.updateDataInForm(recordId, jiandaoyunData, item.userManagement); const result = await this.updateDataInForm(recordId, jiandaoyunData, item.userManagement, syncStatus);
// 更新数据库中的同步状态 // 更新数据库中的同步状态
if (dbConnection && item.user && item.user.userId) { if (dbConnection && item.user && item.user.userId) {
try { try {
console.log(`更新用户 ${item.user.userId} 的同步状态`); console.log(`更新用户 ${item.user.userId} 的同步状态${config.sync.syncedValue}`);
const [updateResult] = await dbConnection.execute( const [updateResult] = await dbConnection.execute(
`UPDATE ${config.tables.users.name} SET ${config.sync.statusField} = ${config.sync.syncedValue} WHERE userId = ?`, `UPDATE ${config.tables.users.name} SET ${config.sync.statusField} = ${config.sync.syncedValue} WHERE userId = ?`,
[item.user.userId] [item.user.userId]
); );
if (updateResult.affectedRows > 0) { if (updateResult.affectedRows > 0) {
console.log(`✅ 成功更新用户 ${item.user.userId} 的同步状态`); console.log(`✅ 成功更新用户 ${item.user.userId} 的同步状态${config.sync.syncedValue}`);
} else { } else {
console.log(`⚠️ 更新用户 ${item.user.userId} 的同步状态失败: 未找到匹配的用户`); console.log(`⚠️ 更新用户 ${item.user.userId} 的同步状态失败: 未找到匹配的用户`);
} }
@ -271,11 +294,11 @@ class JiandaoyunService {
} }
} }
// 转换数据格式 // 转换数据格式,传递syncStatus
const jiandaoyunData = this.transformDataToJiandaoyunFormat(item); const jiandaoyunData = this.transformDataToJiandaoyunFormat(item, syncStatus);
// 提交数据,传递userManagement参数 // 提交数据,传递userManagement参数和syncStatus
const result = await this.submitDataToForm(jiandaoyunData, item.userManagement); const result = await this.submitDataToForm(jiandaoyunData, item.userManagement, syncStatus);
// 保存返回的记录ID到数据库 // 保存返回的记录ID到数据库
console.log('检查返回结果结构:', JSON.stringify(result, null, 2)); console.log('检查返回结果结构:', JSON.stringify(result, null, 2));
@ -286,7 +309,7 @@ class JiandaoyunService {
if (dbConnection && item.user && item.user.userId) { if (dbConnection && item.user && item.user.userId) {
try { try {
console.log(`准备更新用户 ${item.user.userId} 的dataid为 ${newRecordId} 并设置同步状态`); console.log(`准备更新用户 ${item.user.userId} 的dataid为 ${newRecordId} 并设置同步状态${config.sync.syncedValue}`);
const [updateResult] = await dbConnection.execute( const [updateResult] = await dbConnection.execute(
`UPDATE ${config.tables.users.name} SET dataid = ?, ${config.sync.statusField} = ${config.sync.syncedValue} WHERE userId = ?`, `UPDATE ${config.tables.users.name} SET dataid = ?, ${config.sync.statusField} = ${config.sync.syncedValue} WHERE userId = ?`,
[newRecordId, item.user.userId] [newRecordId, item.user.userId]
@ -294,7 +317,7 @@ class JiandaoyunService {
console.log(`数据库更新结果:`, updateResult); console.log(`数据库更新结果:`, updateResult);
if (updateResult.affectedRows > 0) { if (updateResult.affectedRows > 0) {
console.log(`✅ 成功将简道云记录ID ${newRecordId} 保存到数据库并更新同步状态`); console.log(`✅ 成功将简道云记录ID ${newRecordId} 保存到数据库并更新同步状态${config.sync.syncedValue}`);
} else { } else {
console.log(`⚠️ 更新用户 ${item.user.userId} 的dataid和同步状态失败: 未找到匹配的用户`); 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 { try {
// 根据syncStatus获取对应的表单配置
const formConfig = this.getFormConfig(syncStatus);
const appId = formConfig.appId;
const entryId = formConfig.entryId;
// 使用简道云API v5版本,支持data_creator参数 // 使用简道云API v5版本,支持data_creator参数
const url = `${this.baseUrl}/api/v5/app/entry/data/update`; const url = `${this.baseUrl}/api/v5/app/entry/data/update`;
const headers = { const headers = {
@ -374,8 +402,8 @@ class JiandaoyunService {
// 构建更新请求体:记录ID和要更新的数据 // 构建更新请求体:记录ID和要更新的数据
const payload = { const payload = {
app_id: this.appId, app_id: appId,
entry_id: this.entryId, entry_id: entryId,
data_id: recordId, data_id: recordId,
data: data, data: data,
data_creator: dataCreator data_creator: dataCreator
@ -389,13 +417,13 @@ class JiandaoyunService {
console.log('更新响应:', JSON.stringify(response.data, null, 2)); console.log('更新响应:', JSON.stringify(response.data, null, 2));
return response.data; return response.data;
} catch (error) { } catch (error) {
console.error('更新数据失败:', error.message); console.error('更新数据失败:', error.message);
if (error.response) { if (error.response) {
console.error('响应状态:', error.response.status); console.error('响应状态:', error.response.status);
console.error('响应数据:', JSON.stringify(error.response.data, null, 2)); console.error('响应数据:', JSON.stringify(error.response.data, null, 2));
}
throw error;
} }
throw error;
}
} }
// 测试简道云API连接 // 测试简道云API连接

72
test-single-user.js

@ -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();
Loading…
Cancel
Save