此文档描述了如何将现有的自定义数据导入脚本重构为使用 MobX-RESTful-migrator 库的标准化方案。
- 简化代码: 减少自定义逻辑,使用成熟的迁移框架
- 提高可维护性: 标准化的架构更易于理解和维护
- 增强功能: 利用框架提供的高级特性(事件处理、错误恢复等)
- 保持兼容性: 保留现有的数据转换逻辑
import-data.ts
├── DataImporter (自定义批处理器)
│ ├── 手动批处理逻辑
│ ├── 自定义错误处理
│ └── 自定义日志系统
├── DataTransformer (数据转换)
├── ExcelReader (Excel 读取)
└── StrapiAPI (API 客户端)
import-data-refactored.ts
├── RestMigrator (MobX-RESTful-migrator)
│ ├── 标准化的迁移框架
│ ├── 内置事件处理
│ └── 内置日志系统
├── OrganizationModel (MobX-RESTful compatible)
├── UserModel (MobX-RESTful compatible)
├── MigrationSchema (声明式字段映射)
└── 现有的 DataTransformer (复用)
npm install mobx-restful-migrator// scripts/models/strapi-models.ts
import { ListModel, DataObject } from 'mobx-restful';
import { HTTPClient } from 'koajax';
export class OrganizationModel extends ListModel<Organization> {
baseURI = 'organizations';
client: HTTPClient;
constructor(baseURL: string, token: string) {
super();
this.client = new HTTPClient({
baseURI: new URL('api/', baseURL).toString(),
responseType: 'json',
});
// Add auth headers...
}
async updateOne(data: Partial<Organization>, id?: number) {
// Strapi API implementation
}
}// scripts/migration/organization-mapping.ts
import { MigrationSchema } from 'mobx-restful-migrator';
export function createMigrationMapping(): MigrationSchema<
SourceOrg,
TargetOrg
> {
return {
// 简单 1-to-1 映射
常用名称: ({ 常用名称 }) => ({
name: { value: 常用名称 || '' },
}),
// 复杂转换 (多对一)
'机构/项目简介': ({ ['机构/项目简介']: desc }) => {
return {
description: { value: DataUtils.cleanDescription(desc) },
coverageArea: { value: ServiceTransformer.extractCoverage(desc) },
};
},
// 跨表关系
机构联系人联系人姓名: (org) => {
const userData = UserTransformer.transformUser(org);
if (!userData) return {};
return {
contactUser: {
value: userData,
model: UserModel,
},
};
},
};
}// scripts/import-data-refactored.ts
import { RestMigrator, ConsoleLogger } from 'mobx-restful-migrator';
import { createMigrationMapping } from './migration/organization-mapping';
import { OrganizationModel } from './models/strapi-models';
async function* loadOrganizationData(): AsyncGenerator<SourceOrg> {
// 使用现有的 ExcelReader
const rawOrgs = ExcelReader.readExcelFile(CONFIG.EXCEL_FILE);
for (const org of rawOrgs) {
yield org;
}
}
async function main() {
const fieldMapping = createMigrationMapping();
const migrator = new RestMigrator(
loadOrganizationData,
OrganizationModel,
fieldMapping,
new ConsoleLogger(), // 内置日志
);
for await (const organization of migrator.boot()) {
console.log(`✅ 导入成功: ${organization.name}`);
}
}MobX-RESTful-migrator 支持四种映射类型:
'常用名称': 'name', // 字符串映射
// 或
'常用名称': ({ 常用名称 }) => ({ name: { value: 常用名称 } })'title': ({ title, subtitle }) => ({
title: { value: `${title}: ${subtitle}` }
})'机构/项目简介': ({ ['机构/项目简介']: desc }) => ({
description: { value: cleanDescription(desc) },
coverageArea: { value: extractCoverage(desc) }
})'联系人姓名': (org) => ({
contactUser: {
value: transformUser(org),
model: UserModel
}
})之前 (200+ 行自定义逻辑):
class DataImporter {
async importOrganizations(orgs) {
const batches = splitArray(orgs, this.batchSize);
for (const batch of batches) {
await this.processBatch(batch);
await sleep(this.batchDelay);
}
}
async processBatch(orgs) {
// 复杂的批处理逻辑
// 自定义错误处理
// 手动日志记录
}
}之后 (20+ 行配置):
const migrator = new RestMigrator(
loadData,
OrganizationModel,
migrationMapping,
new ConsoleLogger(),
);
for await (const org of migrator.boot()) {
// 自动处理批次、错误、日志
}- 内置重试机制
- 详细的错误日志
- 优雅的失败处理
class CustomEventBus implements MigrationEventBus {
async save({ index, targetItem }) {
console.log(`✅ 保存第 ${index} 项: ${targetItem.name}`);
}
async error({ index, error }) {
console.error(`❌ 第 ${index} 项失败: ${error.message}`);
}
}# 基础演示
npx tsx scripts/demo-refactoring.ts
# 独立完整演示
npx tsx scripts/standalone-refactor-demo.ts --dry-run=== 数据导入脚本重构演示 ===
使用 MobX-RESTful-migrator 模式开始迁移...
✅ [1] 成功: 爱心教育基金会
📞 创建联系人用户: 李四 (ID: 1747)
✅ [2] 成功: 绿色环保协会
📞 创建联系人用户: 赵六 (ID: 2498)
✅ [3] 成功: 国际发展合作中心
=== 迁移统计 ===
总数: 3
成功: 3
成功率: 100.0%
- ✅ 安装依赖和创建基础架构
- ✅ 创建演示脚本验证方案可行性
- ✅ 设计迁移映射配置
- 🔄 解决 TypeScript 兼容性问题
- 📋 完成实际 Strapi API 集成
- 🧪 测试完整功能
- 📚 更新文档和使用指南
- 🧹 清理旧的自定义代码
使用 MobX-RESTful-migrator 重构可以:
- 减少 70% 的自定义代码
- 提供标准化的错误处理和日志
- 支持更灵活的字段映射
- 简化维护和扩展
- 保持现有业务逻辑不变
这是一个渐进式的重构,可以逐步迁移而不影响现有功能。