fix: resolve lint and typecheck issues

This commit is contained in:
Misaka
2026-03-21 09:33:07 +08:00
parent 2fba07fd8f
commit 2b4a09dabe
26 changed files with 356 additions and 336 deletions

View File

@@ -31,6 +31,11 @@ import {
} from '../../types/config.schema'
const log = createLogger('ConfigManager')
type DeepPartialRecord = Record<string, unknown>
function formatZodIssue(issue: { path: PropertyKey[]; message: string }): string {
return `${issue.path.map((segment) => String(segment)).join('.')}: ${issue.message}`
}
const __filename = fileURLToPath(import.meta.url)
const __dirname = dirname(__filename)
@@ -190,7 +195,7 @@ export class ConfigManager {
log.info('Configuration loaded and validated successfully')
} catch (error) {
if (error instanceof z.ZodError) {
const messages = error.issues.map((e: any) => `${e.path.join('.')}: ${e.message}`)
const messages = error.issues.map(formatZodIssue)
log.error('Configuration validation failed', { errors: messages })
throw new Error(`配置文件验证失败:\n${messages.join('\n')}`)
}
@@ -300,7 +305,7 @@ export class ConfigManager {
return { success: true }
} catch (error) {
if (error instanceof z.ZodError) {
const messages = error.issues.map((e: any) => `${e.path.join('.')}: ${e.message}`)
const messages = error.issues.map(formatZodIssue)
return { success: false, error: `配置验证失败:\n${messages.join('\n')}` }
}
return { success: false, error: error instanceof Error ? error.message : '未知错误' }
@@ -310,18 +315,27 @@ export class ConfigManager {
/**
* 深合并工具函数
*/
private deepMerge<T extends Record<string, any>>(source: T, target: Partial<T>): T {
const result = { ...source }
private deepMerge<T extends DeepPartialRecord>(source: T, target: Partial<T>): T {
const result: T = { ...source }
for (const key in target) {
if (target[key] !== undefined) {
const sourceValue = result[key]
const targetValue = target[key]
if (targetValue !== undefined) {
if (
typeof target[key] === 'object' &&
target[key] !== null &&
!Array.isArray(target[key])
typeof sourceValue === 'object' &&
sourceValue !== null &&
!Array.isArray(sourceValue) &&
typeof targetValue === 'object' &&
targetValue !== null &&
!Array.isArray(targetValue)
) {
result[key] = this.deepMerge(result[key] as any, target[key] as any)
result[key] = this.deepMerge(
sourceValue as DeepPartialRecord,
targetValue as Partial<DeepPartialRecord>
) as T[Extract<keyof T, string>]
} else {
result[key] = target[key] as any
result[key] = targetValue as T[Extract<keyof T, string>]
}
}
}

View File

@@ -5,7 +5,7 @@
*/
import { DataSource, Repository, In } from 'typeorm'
import { DiscreteMaterialPlan, MaterialPlanRecordData } from '../entities/DiscreteMaterialPlan'
import { DiscreteMaterialPlan } from '../entities/DiscreteMaterialPlan'
import { getDataSource } from '../data-source'
import { createLogger } from '../../logger'

View File

@@ -124,12 +124,6 @@ export class MaterialsToBeDeletedRepository {
async getAllMaterialCodes(): Promise<Set<string>> {
try {
const repo = await this.getRepository()
const records = await repo.find({
select: ['materialCode'],
where: { materialCode: In([]) } // This will be overridden
})
// Use query builder for better performance
const result = await repo
.createQueryBuilder('m')
.select('m.materialCode')

View File

@@ -108,7 +108,6 @@ export class ErpAuthService {
browser,
context,
page,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
mainFrame: mainFrame as any, // Store forwardFrame content frame for subsequent operations
isLoggedIn: true
}

View File

@@ -70,7 +70,7 @@ export class ExcelParser {
const allRows: any[][] = []
// Read all rows into memory
worksheet.eachRow((row, _rowNumber) => {
worksheet.eachRow((row) => {
allRows.push(row.values as any[])
})

View File

@@ -28,7 +28,11 @@ import {
const log = createLogger('UpdateService')
function appendPortableLaunchLog(logPath: string, message: string, meta?: Record<string, unknown>): void {
function appendPortableLaunchLog(
logPath: string,
message: string,
meta?: Record<string, unknown>
): void {
try {
fs.mkdirSync(path.dirname(logPath), { recursive: true })
const timestamp = new Date().toISOString()
@@ -217,10 +221,7 @@ export class UpdateService {
return {
mode: 'admin',
recommendedRelease: this.status.recommendedRelease,
channels: limitCatalogHistory(
this.catalog,
this.config?.maxAdminHistoryPerChannel ?? 10
)
channels: limitCatalogHistory(this.catalog, this.config?.maxAdminHistoryPerChannel ?? 10)
}
}
@@ -570,13 +571,16 @@ export class UpdateService {
return
}
this.intervalHandle = setInterval(() => {
this.checkForUpdates().catch((error) => {
log.warn('Periodic update check failed', {
error: error instanceof Error ? error.message : String(error)
this.intervalHandle = setInterval(
() => {
this.checkForUpdates().catch((error) => {
log.warn('Periodic update check failed', {
error: error instanceof Error ? error.message : String(error)
})
})
})
}, this.config.checkIntervalMinutes * 60 * 1000)
},
this.config.checkIntervalMinutes * 60 * 1000
)
}
private clearPolling(): void {
@@ -607,7 +611,11 @@ export class UpdateService {
}
private getDownloadPath(release: UpdateRelease): string {
return path.join(app.getPath('userData'), 'pending-update', `${release.channel}-${release.version}.exe`)
return path.join(
app.getPath('userData'),
'pending-update',
`${release.channel}-${release.version}.exe`
)
}
private async calculateSha256(filePath: string): Promise<string> {

View File

@@ -24,7 +24,9 @@ export function compareVersions(left: string, right: string): number {
export function normalizeReleases(input: unknown, channel: ReleaseChannel): UpdateRelease[] {
const list = Array.isArray(input)
? input
: input && typeof input === 'object' && Array.isArray((input as { releases?: unknown[] }).releases)
: input &&
typeof input === 'object' &&
Array.isArray((input as { releases?: unknown[] }).releases)
? (input as { releases: unknown[] }).releases
: []

View File

@@ -11,14 +11,12 @@
* npx tsx src/main/services/user/migration/add-erp-params-migration.ts
*/
import * as fs from 'fs'
import * as path from 'path'
import { fileURLToPath } from 'url'
import { dirname } from 'path'
import { ConfigManager } from '../../config/config-manager'
import { MySqlService } from '../../database/mysql'
import { SqlServerService } from '../../database/sql-server'
import yaml from 'js-yaml'
const __filename = fileURLToPath(import.meta.url)
const __dirname = dirname(__filename)
@@ -92,62 +90,6 @@ async function addColumnSqlServer(
console.log(` ✓ Added column ${columnName} (${columnType})`)
}
/**
* Initialize ERP credentials for all users in MySQL
*/
async function initializeErpCredentialsMySQL(
mysqlService: MySqlService,
tableName: string,
erpUrl: string,
erpUsername: string,
erpPassword: string
): Promise<void> {
const result = await mysqlService.query(`SELECT COUNT(*) as count FROM ${tableName}`)
const userCount = result.rows[0]?.count as number
if (userCount === 0) {
console.log('No users found in BIPUsers table')
return
}
console.log(`Initializing ERP credentials for ${userCount} user(s)...`)
await mysqlService.query(
`UPDATE ${tableName} SET ERP_URL = ?, ERP_Username = ?, ERP_Password = ?`,
[erpUrl, erpUsername, erpPassword]
)
console.log('✓ ERP credentials initialized for all users')
}
/**
* Initialize ERP credentials for all users in SQL Server
*/
async function initializeErpCredentialsSqlServer(
sqlServerService: SqlServerService,
tableName: string,
erpUrl: string,
erpUsername: string,
erpPassword: string
): Promise<void> {
const result = await sqlServerService.query(`SELECT COUNT(*) as count FROM ${tableName}`)
const userCount = result.rows[0]?.count as number
if (userCount === 0) {
console.log('No users found in BIPUsers table')
return
}
console.log(`Initializing ERP credentials for ${userCount} user(s)...`)
await sqlServerService.query(
`UPDATE ${tableName} SET ERP_URL = @p0, ERP_Username = @p1, ERP_Password = @p2`,
[erpUrl, erpUsername, erpPassword]
)
console.log('✓ ERP credentials initialized for all users')
}
/**
* Run migration for MySQL
*/

View File

@@ -11,13 +11,9 @@
import * as mysql from 'mysql2/promise'
import * as fs from 'fs'
import * as path from 'path'
import { fileURLToPath } from 'url'
import { dirname } from 'path'
import yaml from 'js-yaml'
import { z } from 'zod'
const __filename = fileURLToPath(import.meta.url)
/**
* MySQL configuration schema
*/

View File

@@ -70,8 +70,9 @@ export class SessionManager {
public async loginByComputerName(): Promise<boolean> {
try {
const { BIPUsersDAO } = await import('./bip-users-dao')
const { hostname } = await import('os')
const dao = new BIPUsersDAO()
const computerName = require('os').hostname()
const computerName = hostname()
const userInfo = await dao.authenticateByComputerName(computerName)
if (userInfo) {