Files
pqs-9100_tool_client/electron/service/database/activateRecord.ts
hongawen 51d607d970 调整界面
调整脚本
增加功能:备份、恢复、清空
2026-04-03 14:05:18 +08:00

207 lines
6.8 KiB
TypeScript

import fs from 'fs';
import { BasedbService } from './basedb';
interface ActivateRecordItem {
applicant: string;
macAddress: string;
applicationCode: string;
module: string;
activationCode: string;
createTime: string;
remark: string;
}
/**
* sqlite data storage
*/
class ActivateRecordService extends BasedbService {
tableName: string;
constructor() {
const options = {
dbname: 'pqs9100-tool.db',
};
super(options);
this.tableName = 'activate_record';
}
/**
* Initialize table and perform lightweight schema migration.
*/
init(): void {
this._init();
const masterStmt = this.db.prepare('SELECT * FROM sqlite_master WHERE type=? AND name = ?');
const tableExists = masterStmt.get('table', this.tableName);
if (!tableExists) {
const createTableSql =
`CREATE TABLE ${this.tableName}
(
id INTEGER PRIMARY KEY AUTOINCREMENT,
applicant CHAR(100) NULL,
macAddress CHAR(50) NOT NULL,
applicationCode CHAR(2000) NOT NULL,
module CHAR(200) NOT NULL,
activationCode CHAR(2000) NOT NULL,
createTime CHAR(32) NOT NULL,
remark CHAR(120) NULL
);`;
this.db.exec(createTableSql);
return;
}
const columns = this.db.prepare(`PRAGMA table_info(${this.tableName})`).all() as Array<{ name: string }>;
const hasApplicant = columns.some((column) => column.name === 'applicant');
if (!hasApplicant) {
this.db.exec(`ALTER TABLE ${this.tableName} ADD COLUMN applicant CHAR(100) NULL`);
}
}
/**
* Insert one record.
*/
async save(data: ActivateRecordItem) {
const insert = this.db.prepare(
`INSERT INTO ${this.tableName} (applicant, macAddress, applicationCode, module, activationCode, createTime, remark)
VALUES (@applicant, @macAddress, @applicationCode, @module, @activationCode, @createTime, @remark)`
);
insert.run({
...data,
applicant: data.applicant || '',
remark: data.remark || ''
});
return true;
}
/**
* Delete one record by id.
*/
async removeById(id: number): Promise<boolean> {
const remove = this.db.prepare(`DELETE
FROM ${this.tableName}
WHERE id = ?`);
remove.run(id);
return true;
}
/**
* Clear all records.
*/
async clear(): Promise<boolean> {
const clearStmt = this.db.prepare(`DELETE FROM ${this.tableName}`);
clearStmt.run();
return true;
}
/**
* Query record list.
*/
async list(macAddress: string = '', modules: string[] = []): Promise<any[]> {
let condition = '';
if (macAddress) {
condition += ` AND macAddress = '${macAddress}'`;
}
if (modules.length > 0) {
const moduleConditions = modules.map((module) => `module LIKE '%${module}%'`).join(' OR ');
condition += ` AND (${moduleConditions})`;
}
const select = this.db.prepare(`SELECT *
FROM ${this.tableName}
WHERE 1 = 1 ${condition}
order by id desc`);
return select.all();
}
/**
* Export all records to a JSON backup file.
*/
async backup(filePath: string): Promise<number> {
const records = await this.getAllTestDataSqlite();
const payload = {
version: 1,
tableName: this.tableName,
exportedAt: new Date().toISOString(),
records
};
fs.writeFileSync(filePath, JSON.stringify(payload, null, 2), 'utf8');
return records.length;
}
/**
* Import backup and replace current records.
*/
async importBackup(filePath: string): Promise<number> {
const raw = fs.readFileSync(filePath, 'utf8');
const parsed = JSON.parse(raw);
const inputRecords = Array.isArray(parsed) ? parsed : parsed.records;
if (!Array.isArray(inputRecords)) {
throw new Error('Invalid backup file');
}
const records = inputRecords.map((item: any) => this.normalizeRecord(item));
const clearStmt = this.db.prepare(`DELETE FROM ${this.tableName}`);
const insertStmt = this.db.prepare(
`INSERT INTO ${this.tableName} (applicant, macAddress, applicationCode, module, activationCode, createTime, remark)
VALUES (@applicant, @macAddress, @applicationCode, @module, @activationCode, @createTime, @remark)`
);
const transaction = this.db.transaction((rows: ActivateRecordItem[]) => {
clearStmt.run();
for (const row of rows) {
insertStmt.run(row);
}
});
transaction(records);
return records.length;
}
/**
* Read all records.
*/
async getAllTestDataSqlite(): Promise<any[]> {
const selectAllUser = this.db.prepare(`SELECT *
FROM ${this.tableName}
ORDER BY id DESC`);
return selectAllUser.all();
}
/**
* Get data directory.
*/
async getDataDir(): Promise<string> {
return this.storage.getDbDir();
}
/**
* Set custom data directory.
*/
async setCustomDataDir(dir: string): Promise<void> {
if (dir.length === 0) {
return;
}
this.changeDataDir(dir);
this.init();
}
private normalizeRecord(item: any): ActivateRecordItem {
return {
applicant: typeof item?.applicant === 'string' ? item.applicant : '',
macAddress: typeof item?.macAddress === 'string' ? item.macAddress : '',
applicationCode: typeof item?.applicationCode === 'string' ? item.applicationCode : '',
module: typeof item?.module === 'string' ? item.module : Array.isArray(item?.modules) ? item.modules.join(',') : '',
activationCode: typeof item?.activationCode === 'string' ? item.activationCode : '',
createTime: typeof item?.createTime === 'string' ? item.createTime : '',
remark: typeof item?.remark === 'string' ? item.remark : '',
};
}
}
ActivateRecordService.toString = () => '[class ActivateRecordService]';
const activateRecordService = new ActivateRecordService();
export {
ActivateRecordService,
activateRecordService
};