feat: migrate ERP configuration from .env to per-user database storage

- Moved ERP credentials (URL, username, password) from environment variables to dbo_BIPUsers table
- Each user now has their own ERP configuration stored in the database
- Added UserErpConfigService for managing per-user ERP settings
- Updated cleaner and extractor handlers to fetch ERP config from database instead of .env
- Removed ERP fields from ConfigManager UI editable fields
- Added new IPC handlers and preload APIs for user ERP config management
- Includes migration script to transfer existing .env ERP settings to database
- Added migration guide documentation

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
Misaka
2026-03-05 21:52:54 +08:00
parent 3d2127b660
commit 5977254180
15 changed files with 1654 additions and 53 deletions

View File

@@ -17,6 +17,7 @@ import type {
ExportResultItem,
ExportResultResponse
} from '../types/cleaner.types'
import { UserErpConfigService } from '../services/user/user-erp-config-service'
const log = createLogger('CleanerHandler')
@@ -75,6 +76,27 @@ async function getDatabaseService(): Promise<MySqlService | SqlServerService> {
}
}
/**
* Get ERP configuration for current user
*/
async function getErpConfig(): Promise<{
url: string
username: string
password: string
}> {
const erpConfigService = UserErpConfigService.getInstance()
const config = await erpConfigService.getCurrentUserErpConfig()
if (!config || !config.url || !config.username || !config.password) {
throw new ValidationError(
'ERP 配置不完整。请在设置中配置 ERP URL、用户名和密码',
'VAL_MISSING_REQUIRED'
)
}
return config
}
export function registerCleanerHandlers(): void {
ipcMain.handle(
'cleaner:run',
@@ -85,24 +107,18 @@ export function registerCleanerHandlers(): void {
return withErrorHandling(async () => {
let authService: ErpAuthService | null = null
let dbService: MySqlService | SqlServerService | null = null
let erpConfigService: UserErpConfigService | null = null
try {
const erpUrl = process.env.ERP_URL || ''
const erpUsername = process.env.ERP_USERNAME || ''
const erpPassword = process.env.ERP_PASSWORD || ''
// Get ERP configuration from database for current user
log.info('Fetching ERP configuration from database...')
const erpConfig = await getErpConfig()
log.info('Config check', {
url: erpUrl ? 'configured' : 'EMPTY',
username: erpUsername ? 'configured' : 'EMPTY'
log.info('ERP config retrieved', {
url: erpConfig.url ? 'configured' : 'EMPTY',
username: erpConfig.username ? 'configured' : 'EMPTY'
})
if (!erpUrl || !erpUsername || !erpPassword) {
throw new ValidationError(
'ERP 配置不完整。请检查 .env 文件中的 ERP_URL, ERP_USERNAME, ERP_PASSWORD',
'VAL_MISSING_REQUIRED'
)
}
const dbType = process.env.DB_TYPE?.toLowerCase()
log.info(
`Connecting to ${dbType === 'sqlserver' || dbType === 'mssql' ? 'SQL Server' : 'MySQL'} for order resolution...`
@@ -138,9 +154,9 @@ export function registerCleanerHandlers(): void {
log.info('Resolved order numbers', { count: validOrderNumbers.length })
authService = new ErpAuthService({
url: erpUrl,
username: erpUsername,
password: erpPassword,
url: erpConfig.url,
username: erpConfig.username,
password: erpConfig.password,
headless: input.headless ?? true
})