style: apply Prettier formatting across codebase

Apply consistent code formatting using Prettier to improve code readability
and maintain style consistency throughout the project.

Co-Authored-By: Claude (glm-5) <noreply@anthropic.com>
This commit is contained in:
Misaka_Company
2026-03-04 14:24:16 +08:00
parent 88c8c256e2
commit c61776a1ff
6 changed files with 115 additions and 107 deletions

View File

@@ -1,9 +1,11 @@
# Implementation Plan: Auto-import Extracted Data to Database
## Overview
Implement automatic database import after ERP data extraction completes. The merged Excel file will be read and written to the `dbo_DiscreteMaterialPlanData` table.
## Requirements
- **Trigger**: Automatic after extraction completes
- **Delete Strategy**: Batch delete by `SourceNumber` before insert
- **Batch Insert**: 1000 records per batch
@@ -33,60 +35,67 @@ ExtractorService
## Field Mapping
| Excel Header | Database Column | Notes |
|-------------|-----------------|-------|
| 工厂 | Factory | |
| 备料状态 | MaterialStatus | |
| 备料计划单号 | PlanNumber | |
| 来源单号 | SourceNumber | **Deletion key** |
| 备料类型 | MaterialType | |
| 产品编码 | ProductCode | |
| 产品名称 | ProductName | |
| 产品计划数量 | ProductPlanQuantity | decimal |
| 产品单位 | ProductUnit | |
| 用料部门 | UseDepartment | |
| 备注 | Remark | |
| 制单人 | Creator | |
| 制单日期 | CreateDate | date |
| 审批人 | Approver | |
| 审批日期 | ApproveDate | date |
| 序号 | SequenceNumber | int |
| 材料编码 | MaterialCode | |
| 材料名称 | MaterialName | |
| 规格 | Specification | |
| 型号 | Model | |
| 图号 | DrawingNumber | |
| 物料材质 | MaterialQuality | |
| 计划数量 | PlanQuantity | decimal |
| 单位 | Unit | |
| 需用日期 | RequiredDate | date |
| 发料仓库 | Warehouse | |
| 单位用量 | UnitUsage | decimal |
| 累计出库数量 | CumulativeOutputQuantity | decimal |
| 打印人 | ❌ SKIP | Not in DB |
| 打印日期 | ❌ SKIP | Not in DB |
| - | BOMVersion | SKIP (no source) |
| Excel Header | Database Column | Notes |
| ------------ | ------------------------ | ---------------- |
| 工厂 | Factory | |
| 备料状态 | MaterialStatus | |
| 备料计划单号 | PlanNumber | |
| 来源单号 | SourceNumber | **Deletion key** |
| 备料类型 | MaterialType | |
| 产品编码 | ProductCode | |
| 产品名称 | ProductName | |
| 产品计划数量 | ProductPlanQuantity | decimal |
| 产品单位 | ProductUnit | |
| 用料部门 | UseDepartment | |
| 备注 | Remark | |
| 制单人 | Creator | |
| 制单日期 | CreateDate | date |
| 审批人 | Approver | |
| 审批日期 | ApproveDate | date |
| 序号 | SequenceNumber | int |
| 材料编码 | MaterialCode | |
| 材料名称 | MaterialName | |
| 规格 | Specification | |
| 型号 | Model | |
| 图号 | DrawingNumber | |
| 物料材质 | MaterialQuality | |
| 计划数量 | PlanQuantity | decimal |
| 单位 | Unit | |
| 需用日期 | RequiredDate | date |
| 发料仓库 | Warehouse | |
| 单位用量 | UnitUsage | decimal |
| 累计出库数量 | CumulativeOutputQuantity | decimal |
| 打印人 | ❌ SKIP | Not in DB |
| 打印日期 | ❌ SKIP | Not in DB |
| - | BOMVersion | SKIP (no source) |
## Files to Create/Modify
### 1. NEW: `src/main/services/database/data-importer.ts`
Main import service with:
- `importFromExcel(filePath)` - Main entry point
- `readExcelFile(filePath)` - Parse Excel using ExcelJS
- Map Excel columns to database fields
- Return records and unique SourceNumbers
### 2. MODIFY: `src/main/services/database/discrete-material-plan-dao.ts`
Add methods:
- `deleteBySourceNumbers(sourceNumbers: string[])` - Batch delete
- `batchInsert(records: MaterialPlanRecord[], batchSize: number)` - Batch insert
### 3. MODIFY: `src/main/services/erp/extractor.ts`
- After successful merge, call `importToDatabase(mergedFile)`
- Add import results to `ExtractorResult`
### 4. MODIFY: `src/main/types/extractor.types.ts`
Add types:
```typescript
export interface ImportResult {
success: boolean
@@ -102,6 +111,7 @@ export interface ExtractorResult {
```
### 5. MODIFY: `src/renderer/src/pages/ExtractorPage.tsx`
- Display import results
- Show records deleted/imported counts
@@ -114,6 +124,7 @@ export interface ExtractorResult {
5. Update UI
## Testing Plan
1. Unit test DAO methods
2. Integration test with sample Excel file
3. E2E test extraction → import flow
3. E2E test extraction → import flow

View File

@@ -4,7 +4,7 @@
* This script modifies the ID column to be AUTO_INCREMENT while preserving data
*/
const mysql = require('mysql2/promise');
const mysql = require('mysql2/promise')
async function main() {
const config = {
@@ -13,17 +13,17 @@ async function main() {
user: 'remote_user',
password: '3.1415926Beeke',
database: 'BLD_DB'
};
}
let connection;
let connection
try {
console.log('Connecting to MySQL...');
connection = await mysql.createConnection(config);
console.log('Connected successfully!\n');
console.log('Connecting to MySQL...')
connection = await mysql.createConnection(config)
console.log('Connected successfully!\n')
// Step 1: Check current table structure
console.log('=== Step 1: Current table structure ===');
console.log('=== Step 1: Current table structure ===')
const [columns] = await connection.execute(`
SELECT
COLUMN_NAME,
@@ -39,40 +39,38 @@ async function main() {
AND TABLE_SCHEMA = DATABASE()
ORDER BY
ORDINAL_POSITION
`);
console.table(columns);
`)
console.table(columns)
// Step 2: Count records before modification
console.log('\n=== Step 2: Record count before modification ===');
console.log('\n=== Step 2: Record count before modification ===')
const [countBefore] = await connection.execute(
'SELECT COUNT(*) AS total FROM dbo_MaterialsTypeToBeDeleted'
);
console.log(`Total records: ${countBefore[0].total}`);
)
console.log(`Total records: ${countBefore[0].total}`)
// Step 3: Show sample data
console.log('\n=== Step 3: Sample data ===');
const [sample] = await connection.execute(
'SELECT * FROM dbo_MaterialsTypeToBeDeleted LIMIT 5'
);
console.table(sample);
console.log('\n=== Step 3: Sample data ===')
const [sample] = await connection.execute('SELECT * FROM dbo_MaterialsTypeToBeDeleted LIMIT 5')
console.table(sample)
// Step 4: Check if ID is already AUTO_INCREMENT
const idColumn = columns.find((col) => col.COLUMN_NAME === 'ID');
const idColumn = columns.find((col) => col.COLUMN_NAME === 'ID')
if (idColumn && idColumn.EXTRA.includes('auto_increment')) {
console.log('\n=== ID is already AUTO_INCREMENT! No modification needed. ===');
return;
console.log('\n=== ID is already AUTO_INCREMENT! No modification needed. ===')
return
}
// Step 5: Modify the ID column
console.log('\n=== Step 4: Modifying ID column to AUTO_INCREMENT ===');
console.log('\n=== Step 4: Modifying ID column to AUTO_INCREMENT ===')
await connection.execute(`
ALTER TABLE dbo_MaterialsTypeToBeDeleted
MODIFY COLUMN ID INT NOT NULL AUTO_INCREMENT
`);
console.log('Modification completed successfully!\n');
`)
console.log('Modification completed successfully!\n')
// Step 6: Verify the change
console.log('=== Step 5: Verify modification ===');
console.log('=== Step 5: Verify modification ===')
const [columnsAfter] = await connection.execute(`
SELECT
COLUMN_NAME,
@@ -86,32 +84,32 @@ async function main() {
TABLE_NAME = 'dbo_MaterialsTypeToBeDeleted'
AND TABLE_SCHEMA = DATABASE()
AND COLUMN_NAME = 'ID'
`);
console.table(columnsAfter);
`)
console.table(columnsAfter)
// Step 7: Verify data is still intact
console.log('\n=== Step 6: Verify data integrity ===');
console.log('\n=== Step 6: Verify data integrity ===')
const [countAfter] = await connection.execute(
'SELECT COUNT(*) AS total FROM dbo_MaterialsTypeToBeDeleted'
);
console.log(`Total records after modification: ${countAfter[0].total}`);
)
console.log(`Total records after modification: ${countAfter[0].total}`)
if (countBefore[0].total === countAfter[0].total) {
console.log('\n✅ SUCCESS: All data preserved, AUTO_INCREMENT added to ID column!');
console.log('\n✅ SUCCESS: All data preserved, AUTO_INCREMENT added to ID column!')
} else {
console.log('\n⚠ WARNING: Record count changed! Please check data.');
console.log('\n⚠ WARNING: Record count changed! Please check data.')
}
} catch (error) {
console.error('\n❌ Error:', error.message);
console.error('\n❌ Error:', error.message)
if (error.code) {
console.error('Error code:', error.code);
console.error('Error code:', error.code)
}
} finally {
if (connection) {
await connection.end();
console.log('\nConnection closed.');
await connection.end()
console.log('\nConnection closed.')
}
}
}
main();
main()

View File

@@ -19,34 +19,34 @@ const log = createLogger('DataImportService')
* Excel column header to database field mapping
*/
const EXCEL_TO_DB_MAPPING: Record<string, keyof MaterialPlanRecord> = {
'工厂': 'factory',
'备料状态': 'materialStatus',
'备料计划单号': 'planNumber',
'来源单号': 'sourceNumber',
'备料类型': 'materialType',
'产品编码': 'productCode',
'产品名称': 'productName',
'产品计划数量': 'productPlanQuantity',
'产品单位': 'productUnit',
'用料部门': 'useDepartment',
'备注': 'remark',
'制单人': 'creator',
'制单日期': 'createDate',
'审批人': 'approver',
'审批日期': 'approveDate',
'序号': 'sequenceNumber',
'材料编码': 'materialCode',
'材料名称': 'materialName',
'规格': 'specification',
'型号': 'model',
'图号': 'drawingNumber',
'物料材质': 'materialQuality',
'计划数量': 'planQuantity',
'单位': 'unit',
'需用日期': 'requiredDate',
'发料仓库': 'warehouse',
'单位用量': 'unitUsage',
'累计出库数量': 'cumulativeOutputQuantity'
: 'factory',
: 'materialStatus',
: 'planNumber',
: 'sourceNumber',
: 'materialType',
: 'productCode',
: 'productName',
: 'productPlanQuantity',
: 'productUnit',
: 'useDepartment',
: 'remark',
: 'creator',
: 'createDate',
: 'approver',
: 'approveDate',
: 'sequenceNumber',
: 'materialCode',
: 'materialName',
: 'specification',
: 'model',
: 'drawingNumber',
: 'materialQuality',
: 'planQuantity',
: 'unit',
: 'requiredDate',
: 'warehouse',
: 'unitUsage',
: 'cumulativeOutputQuantity'
// Note: '打印人', '打印日期' are skipped (not in DB)
// Note: 'BOMVersion' is skipped (not in Excel)
}
@@ -275,11 +275,7 @@ export class DataImportService {
}
// Handle date fields
const dateFields: (keyof MaterialPlanRecord)[] = [
'createDate',
'approveDate',
'requiredDate'
]
const dateFields: (keyof MaterialPlanRecord)[] = ['createDate', 'approveDate', 'requiredDate']
if (dateFields.includes(fieldName)) {
// ExcelJS returns date as Date object if recognized
@@ -301,4 +297,4 @@ export class DataImportService {
*/
export function createDataImportService(): DataImportService {
return new DataImportService()
}
}

View File

@@ -201,4 +201,4 @@ export class ExtractorCore {
}
return batches
}
}
}

View File

@@ -227,7 +227,10 @@ const ExtractorPage: React.FC = () => {
{result?.importResult && (
<div className="bg-white rounded-xl shadow-sm border border-slate-200 p-6 flex flex-col gap-4">
<h3 className="font-semibold text-lg border-b pb-2 flex items-center gap-2">
<Database size={20} className={result.importResult.success ? 'text-emerald-600' : 'text-red-500'} />
<Database
size={20}
className={result.importResult.success ? 'text-emerald-600' : 'text-red-500'}
/>
<span className={result.importResult.success ? 'text-emerald-600' : 'text-red-500'}>
</span>

View File

@@ -116,4 +116,4 @@ describe('DataImportService', () => {
expect(result.uniqueSourceNumbers).toBeGreaterThanOrEqual(0)
})
})
})
})