style: format code with Prettier
Apply Prettier formatting to maintain consistent code style across the codebase. Changes include formatting improvements for: - IPC handlers (database, file, material-type, resolver, user-erp-config, validation) - Type definitions (ipc-api.types) - React components (MaterialTypeManagementDialog) - React hooks (useAuth, useCleaner, useValidation) - Pages (SettingsPage) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -21,7 +21,10 @@ const mysqlServices = new Map<string, MySqlService>()
|
||||
const sqlServerServices = new Map<string, SqlServerService>()
|
||||
const cleanupBoundWindows = new Set<string>()
|
||||
|
||||
function bindWindowCleanup(windowId: string, sender: { once: (event: string, listener: () => void) => void }): void {
|
||||
function bindWindowCleanup(
|
||||
windowId: string,
|
||||
sender: { once: (event: string, listener: () => void) => void }
|
||||
): void {
|
||||
if (cleanupBoundWindows.has(windowId)) {
|
||||
return
|
||||
}
|
||||
@@ -31,7 +34,9 @@ function bindWindowCleanup(windowId: string, sender: { once: (event: string, lis
|
||||
const sqlServer = getSqlServerService(windowId)
|
||||
|
||||
if (mysql) {
|
||||
mysql.disconnect().catch((error) => log.warn('MySQL disconnect on window destroy failed', { error }))
|
||||
mysql
|
||||
.disconnect()
|
||||
.catch((error) => log.warn('MySQL disconnect on window destroy failed', { error }))
|
||||
deleteMySqlService(windowId)
|
||||
}
|
||||
|
||||
@@ -99,39 +104,48 @@ export function registerDatabaseHandlers(): void {
|
||||
IPC_CHANNELS.DATABASE_MYSQL_CONNECT,
|
||||
async (event, config: MySqlConfig): Promise<IpcResult<void>> => {
|
||||
return withErrorHandling(async () => {
|
||||
// Use window ID as connection identifier
|
||||
const windowId = (event.sender as { id: number }).id.toString()
|
||||
bindWindowCleanup(windowId, event.sender as { once: (event: string, listener: () => void) => void })
|
||||
log.info('Connecting to MySQL', { windowId })
|
||||
const service = new MySqlService(config)
|
||||
await service.connect()
|
||||
setMySqlService(windowId, service)
|
||||
log.info('MySQL connected', { windowId })
|
||||
// Use window ID as connection identifier
|
||||
const windowId = (event.sender as { id: number }).id.toString()
|
||||
bindWindowCleanup(
|
||||
windowId,
|
||||
event.sender as { once: (event: string, listener: () => void) => void }
|
||||
)
|
||||
log.info('Connecting to MySQL', { windowId })
|
||||
const service = new MySqlService(config)
|
||||
await service.connect()
|
||||
setMySqlService(windowId, service)
|
||||
log.info('MySQL connected', { windowId })
|
||||
}, 'database:mysql:connect')
|
||||
}
|
||||
)
|
||||
|
||||
// Disconnect from MySQL
|
||||
ipcMain.handle(IPC_CHANNELS.DATABASE_MYSQL_DISCONNECT, async (event): Promise<IpcResult<void>> => {
|
||||
return withErrorHandling(async () => {
|
||||
const windowId = (event.sender as { id: number }).id.toString()
|
||||
const service = getMySqlService(windowId)
|
||||
if (service) {
|
||||
await service.disconnect()
|
||||
deleteMySqlService(windowId)
|
||||
log.info('MySQL disconnected', { windowId })
|
||||
}
|
||||
}, 'database:mysql:disconnect')
|
||||
})
|
||||
ipcMain.handle(
|
||||
IPC_CHANNELS.DATABASE_MYSQL_DISCONNECT,
|
||||
async (event): Promise<IpcResult<void>> => {
|
||||
return withErrorHandling(async () => {
|
||||
const windowId = (event.sender as { id: number }).id.toString()
|
||||
const service = getMySqlService(windowId)
|
||||
if (service) {
|
||||
await service.disconnect()
|
||||
deleteMySqlService(windowId)
|
||||
log.info('MySQL disconnected', { windowId })
|
||||
}
|
||||
}, 'database:mysql:disconnect')
|
||||
}
|
||||
)
|
||||
|
||||
// Check if MySQL is connected
|
||||
ipcMain.handle(IPC_CHANNELS.DATABASE_MYSQL_IS_CONNECTED, async (event): Promise<IpcResult<boolean>> => {
|
||||
return withErrorHandling(async () => {
|
||||
const windowId = (event.sender as { id: number }).id.toString()
|
||||
const service = getMySqlService(windowId)
|
||||
return service ? service.isConnected() : false
|
||||
}, 'database:mysql:isConnected')
|
||||
})
|
||||
ipcMain.handle(
|
||||
IPC_CHANNELS.DATABASE_MYSQL_IS_CONNECTED,
|
||||
async (event): Promise<IpcResult<boolean>> => {
|
||||
return withErrorHandling(async () => {
|
||||
const windowId = (event.sender as { id: number }).id.toString()
|
||||
const service = getMySqlService(windowId)
|
||||
return service ? service.isConnected() : false
|
||||
}, 'database:mysql:isConnected')
|
||||
}
|
||||
)
|
||||
|
||||
// Execute MySQL query
|
||||
ipcMain.handle(
|
||||
@@ -160,7 +174,10 @@ export function registerDatabaseHandlers(): void {
|
||||
async (event, config: SqlServerConfig): Promise<IpcResult<void>> => {
|
||||
return withErrorHandling(async () => {
|
||||
const windowId = (event.sender as { id: number }).id.toString()
|
||||
bindWindowCleanup(windowId, event.sender as { once: (event: string, listener: () => void) => void })
|
||||
bindWindowCleanup(
|
||||
windowId,
|
||||
event.sender as { once: (event: string, listener: () => void) => void }
|
||||
)
|
||||
log.info('Connecting to SQL Server', { windowId })
|
||||
const service = new SqlServerService(config)
|
||||
await service.connect()
|
||||
@@ -171,26 +188,32 @@ export function registerDatabaseHandlers(): void {
|
||||
)
|
||||
|
||||
// Disconnect from SQL Server
|
||||
ipcMain.handle(IPC_CHANNELS.DATABASE_SQLSERVER_DISCONNECT, async (event): Promise<IpcResult<void>> => {
|
||||
return withErrorHandling(async () => {
|
||||
const windowId = (event.sender as { id: number }).id.toString()
|
||||
const service = getSqlServerService(windowId)
|
||||
if (service) {
|
||||
await service.disconnect()
|
||||
deleteSqlServerService(windowId)
|
||||
log.info('SQL Server disconnected', { windowId })
|
||||
}
|
||||
}, 'database:sqlserver:disconnect')
|
||||
})
|
||||
ipcMain.handle(
|
||||
IPC_CHANNELS.DATABASE_SQLSERVER_DISCONNECT,
|
||||
async (event): Promise<IpcResult<void>> => {
|
||||
return withErrorHandling(async () => {
|
||||
const windowId = (event.sender as { id: number }).id.toString()
|
||||
const service = getSqlServerService(windowId)
|
||||
if (service) {
|
||||
await service.disconnect()
|
||||
deleteSqlServerService(windowId)
|
||||
log.info('SQL Server disconnected', { windowId })
|
||||
}
|
||||
}, 'database:sqlserver:disconnect')
|
||||
}
|
||||
)
|
||||
|
||||
// Check if SQL Server is connected
|
||||
ipcMain.handle(IPC_CHANNELS.DATABASE_SQLSERVER_IS_CONNECTED, async (event): Promise<IpcResult<boolean>> => {
|
||||
return withErrorHandling(async () => {
|
||||
const windowId = (event.sender as { id: number }).id.toString()
|
||||
const service = getSqlServerService(windowId)
|
||||
return service ? service.isConnected() : false
|
||||
}, 'database:sqlserver:isConnected')
|
||||
})
|
||||
ipcMain.handle(
|
||||
IPC_CHANNELS.DATABASE_SQLSERVER_IS_CONNECTED,
|
||||
async (event): Promise<IpcResult<boolean>> => {
|
||||
return withErrorHandling(async () => {
|
||||
const windowId = (event.sender as { id: number }).id.toString()
|
||||
const service = getSqlServerService(windowId)
|
||||
return service ? service.isConnected() : false
|
||||
}, 'database:sqlserver:isConnected')
|
||||
}
|
||||
)
|
||||
|
||||
// Execute SQL Server query
|
||||
ipcMain.handle(
|
||||
|
||||
@@ -31,13 +31,16 @@ function normalizeAndValidatePath(inputPath: string): string {
|
||||
}
|
||||
|
||||
export function registerFileHandlers(): void {
|
||||
ipcMain.handle(IPC_CHANNELS.FILE_READ, async (_event, filePath: string): Promise<IpcResult<string>> => {
|
||||
return withErrorHandling(async () => {
|
||||
const safePath = normalizeAndValidatePath(filePath)
|
||||
log.debug('Reading file', { filePath: safePath })
|
||||
return await fs.readFile(safePath, 'utf-8')
|
||||
}, 'file:read')
|
||||
})
|
||||
ipcMain.handle(
|
||||
IPC_CHANNELS.FILE_READ,
|
||||
async (_event, filePath: string): Promise<IpcResult<string>> => {
|
||||
return withErrorHandling(async () => {
|
||||
const safePath = normalizeAndValidatePath(filePath)
|
||||
log.debug('Reading file', { filePath: safePath })
|
||||
return await fs.readFile(safePath, 'utf-8')
|
||||
}, 'file:read')
|
||||
}
|
||||
)
|
||||
|
||||
ipcMain.handle(
|
||||
IPC_CHANNELS.FILE_WRITE,
|
||||
@@ -52,36 +55,45 @@ export function registerFileHandlers(): void {
|
||||
}
|
||||
)
|
||||
|
||||
ipcMain.handle(IPC_CHANNELS.FILE_EXISTS, async (_event, filePath: string): Promise<IpcResult<boolean>> => {
|
||||
return withErrorHandling(async () => {
|
||||
const safePath = normalizeAndValidatePath(filePath)
|
||||
try {
|
||||
ipcMain.handle(
|
||||
IPC_CHANNELS.FILE_EXISTS,
|
||||
async (_event, filePath: string): Promise<IpcResult<boolean>> => {
|
||||
return withErrorHandling(async () => {
|
||||
const safePath = normalizeAndValidatePath(filePath)
|
||||
try {
|
||||
await fs.access(safePath)
|
||||
return true
|
||||
} catch {
|
||||
return false
|
||||
}
|
||||
}, 'file:exists')
|
||||
}
|
||||
)
|
||||
|
||||
ipcMain.handle(
|
||||
IPC_CHANNELS.FILE_LIST,
|
||||
async (_event, dirPath: string): Promise<IpcResult<string[]>> => {
|
||||
return withErrorHandling(async () => {
|
||||
const safePath = normalizeAndValidatePath(dirPath)
|
||||
log.debug('Listing directory', { dirPath: safePath })
|
||||
const entries = await fs.readdir(safePath, { withFileTypes: true })
|
||||
return entries
|
||||
.filter((entry) => entry.isFile())
|
||||
.map((entry) => entry.name)
|
||||
.sort()
|
||||
}, 'file:list')
|
||||
}
|
||||
)
|
||||
|
||||
ipcMain.handle(
|
||||
IPC_CHANNELS.FILE_OPEN_PATH,
|
||||
async (_event, filePath: string): Promise<IpcResult<void>> => {
|
||||
return withErrorHandling(async () => {
|
||||
const safePath = normalizeAndValidatePath(filePath)
|
||||
log.debug('Opening path in explorer', { filePath: safePath })
|
||||
await fs.access(safePath)
|
||||
return true
|
||||
} catch {
|
||||
return false
|
||||
}
|
||||
}, 'file:exists')
|
||||
})
|
||||
|
||||
ipcMain.handle(IPC_CHANNELS.FILE_LIST, async (_event, dirPath: string): Promise<IpcResult<string[]>> => {
|
||||
return withErrorHandling(async () => {
|
||||
const safePath = normalizeAndValidatePath(dirPath)
|
||||
log.debug('Listing directory', { dirPath: safePath })
|
||||
const entries = await fs.readdir(safePath, { withFileTypes: true })
|
||||
return entries
|
||||
.filter((entry) => entry.isFile())
|
||||
.map((entry) => entry.name)
|
||||
.sort()
|
||||
}, 'file:list')
|
||||
})
|
||||
|
||||
ipcMain.handle(IPC_CHANNELS.FILE_OPEN_PATH, async (_event, filePath: string): Promise<IpcResult<void>> => {
|
||||
return withErrorHandling(async () => {
|
||||
const safePath = normalizeAndValidatePath(filePath)
|
||||
log.debug('Opening path in explorer', { filePath: safePath })
|
||||
await fs.access(safePath)
|
||||
await shell.openPath(safePath)
|
||||
}, 'file:openPath')
|
||||
})
|
||||
await shell.openPath(safePath)
|
||||
}, 'file:openPath')
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
@@ -47,10 +47,7 @@ export function registerMaterialTypeHandlers(): void {
|
||||
*/
|
||||
ipcMain.handle(
|
||||
IPC_CHANNELS.MATERIAL_TYPE_GET_BY_MANAGER,
|
||||
async (
|
||||
_event,
|
||||
managerName: string
|
||||
): Promise<IpcResult<MaterialTypeRecord[]>> => {
|
||||
async (_event, managerName: string): Promise<IpcResult<MaterialTypeRecord[]>> => {
|
||||
return withErrorHandling(async () => {
|
||||
const records = await dao.getMaterialsByManager(managerName)
|
||||
return records
|
||||
@@ -127,4 +124,3 @@ export function registerMaterialTypeHandlers(): void {
|
||||
|
||||
log.info('Material type handlers registered')
|
||||
}
|
||||
|
||||
|
||||
@@ -106,7 +106,9 @@ export function registerResolverHandlers(): void {
|
||||
async (
|
||||
_event,
|
||||
inputs: string[]
|
||||
): Promise<IpcResult<Array<{ input: string; type: 'productionId' | 'orderNumber' | 'unknown' }>>> => {
|
||||
): Promise<
|
||||
IpcResult<Array<{ input: string; type: 'productionId' | 'orderNumber' | 'unknown' }>>
|
||||
> => {
|
||||
return withErrorHandling(async () => {
|
||||
// Create a mock resolver without database connection
|
||||
const resolver = new OrderNumberResolver({
|
||||
|
||||
@@ -42,7 +42,10 @@ export function registerUserErpConfigHandlers(): void {
|
||||
const credentials = await erpConfigService.getCurrentUserErpConfig()
|
||||
|
||||
if (!credentials) {
|
||||
throw new ValidationError('未找到 ERP 配置。请先配置 ERP 账号和密码。', 'VAL_INVALID_INPUT')
|
||||
throw new ValidationError(
|
||||
'未找到 ERP 配置。请先配置 ERP 账号和密码。',
|
||||
'VAL_INVALID_INPUT'
|
||||
)
|
||||
}
|
||||
|
||||
const configManager = ConfigManager.getInstance()
|
||||
@@ -86,7 +89,10 @@ export function registerUserErpConfigHandlers(): void {
|
||||
|
||||
ipcMain.handle(
|
||||
IPC_CHANNELS.USER_ERP_CONFIG_TEST_CONNECTION,
|
||||
async (_event, credentials: ErpCredentialsRequest): Promise<IpcResult<ConnectionTestResult>> => {
|
||||
async (
|
||||
_event,
|
||||
credentials: ErpCredentialsRequest
|
||||
): Promise<IpcResult<ConnectionTestResult>> => {
|
||||
return withErrorHandling(async () => {
|
||||
if (!credentials.username || !credentials.password) {
|
||||
throw new ValidationError(
|
||||
@@ -139,4 +145,3 @@ export function registerUserErpConfigHandlers(): void {
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -497,18 +497,21 @@ export function registerValidationHandlers(): void {
|
||||
/**
|
||||
* Get unique manager names
|
||||
*/
|
||||
ipcMain.handle(IPC_CHANNELS.MATERIALS_GET_MANAGERS, async (_event): Promise<{ managers: string[] }> => {
|
||||
try {
|
||||
const dao = new MaterialsToBeDeletedDAO()
|
||||
const managers = await dao.getManagers()
|
||||
return { managers }
|
||||
} catch (error) {
|
||||
log.error('Get managers error', {
|
||||
error: error instanceof Error ? error.message : String(error)
|
||||
})
|
||||
return { managers: [] }
|
||||
ipcMain.handle(
|
||||
IPC_CHANNELS.MATERIALS_GET_MANAGERS,
|
||||
async (_event): Promise<{ managers: string[] }> => {
|
||||
try {
|
||||
const dao = new MaterialsToBeDeletedDAO()
|
||||
const managers = await dao.getManagers()
|
||||
return { managers }
|
||||
} catch (error) {
|
||||
log.error('Get managers error', {
|
||||
error: error instanceof Error ? error.message : String(error)
|
||||
})
|
||||
return { managers: [] }
|
||||
}
|
||||
}
|
||||
})
|
||||
)
|
||||
|
||||
/**
|
||||
* Update manager for a single material
|
||||
|
||||
@@ -76,9 +76,7 @@ export interface ExtractorAPI {
|
||||
* Run ERP data extractor
|
||||
* @param input - Extractor input parameters
|
||||
*/
|
||||
runExtractor: (
|
||||
input: ExtractorInput
|
||||
) => Promise<IpcResult<ExtractorResult>>
|
||||
runExtractor: (input: ExtractorInput) => Promise<IpcResult<ExtractorResult>>
|
||||
/**
|
||||
* Subscribe to progress updates
|
||||
* @param callback - Callback function receiving progress data
|
||||
@@ -101,9 +99,7 @@ export interface CleanerAPI {
|
||||
* Run ERP cleaner service
|
||||
* @param input - Cleaner input parameters
|
||||
*/
|
||||
runCleaner: (
|
||||
input: CleanerInput
|
||||
) => Promise<IpcResult<CleanerResult>>
|
||||
runCleaner: (input: CleanerInput) => Promise<IpcResult<CleanerResult>>
|
||||
|
||||
/**
|
||||
* Export validation results to Excel
|
||||
|
||||
Reference in New Issue
Block a user