ArKTS: DAL,Model,BLL,Interface,Factory using SQLite
HarmonyOS 用@ohos.data.rdb 用DBHelper.ets 共用调用SQLite 库,进行DAL,Model,BLL,Interface,Factory 框架模式,表为
CREATE TABLE IF NOT EXISTS signInRecord (
id INTEGER PRIMARY KEY AUTOINCREMENT,
employeeId TEXT NOT NULL,
employeeName TEXT NOT NULL,
signInTime TEXT NOT NULL
)
项目结构 :
UtilitieDB
--DBHelper.ets
DAL
--signIn.ets
Model
--signIn.ets
BLL
----signIn.ets
Interface
----IsignIn.ets
Factory
--AbstractFactory.ets
/*
# encoding: utf-8
# 版权所有 2025 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:
# Author : geovindu,Geovin Du 涂聚文.
# IDE : DevEco Studio 5.1.1 HarmonyOS
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2025/7/22 19:11
# User : geovindu
# Product : DevEco Studio
# Project : MyApplication
# File : signIn.ets
*/export interface SignInRecordDbObject {id?: number;employeeId: string;employeeName: string;signInTime: string;
}export class SignInRecord {id: number | null;employeeId: string;employeeName: string;signInTime: string;constructor(employeeId: string,employeeName: string,signInTime: string,id: number | null = null) {this.id = id;this.employeeId = employeeId;this.employeeName = employeeName;this.signInTime = signInTime;}// 转换为数据库存储的对象格式(类型安全版本)toDbObject(): SignInRecordDbObject {const dbObject: SignInRecordDbObject = {employeeId: this.employeeId,employeeName: this.employeeName,signInTime: this.signInTime};if (this.id !== null) {dbObject.id = this.id;}return dbObject;}// 从数据库对象创建模型实例(类型安全版本)static fromDbObject(dbObject: SignInRecordDbObject): SignInRecord {return new SignInRecord(dbObject.employeeId,dbObject.employeeName,dbObject.signInTime,dbObject.id !== undefined ? dbObject.id : null);}
}/*
# encoding: utf-8
# 版权所有 2025 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:
# Author : geovindu,Geovin Du 涂聚文.
# IDE : DevEco Studio 5.1.1 HarmonyOS
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2025/7/22 19:04
# User : geovindu
# Product : DevEco Studio
# Project : MyApplication
# File : DBHelper.ets
*/import relationalStore from '@ohos.data.relationalStore';
import { BusinessError } from '@ohos.base';
import { Context } from '@ohos.abilityAccessCtrl';export class DBHelper {private static readonly DB_NAME: string = 'signInDB.db';private static readonly DB_VERSION: number = 1;private rdbStore: relationalStore.RdbStore | null = null;private static instance: DBHelper | null = null;private context: Context | null = null; // 新增上下文存储private constructor() {}/**** @returns*/public static getInstance(): DBHelper {if (!DBHelper.instance) {DBHelper.instance = new DBHelper();}if (!DBHelper.instance) {throw new Error('无法创建DBHelper实例,请检查实现');}return DBHelper.instance;}/*** 初始化数据库时保存上下文* @param context* @returns*/public async initDB(context: Context): Promise<relationalStore.RdbStore> {if (this.rdbStore) {return this.rdbStore;}/*** 保存上下文供后续使用*/this.context = context;const storeConfig: relationalStore.StoreConfig = {name: DBHelper.DB_NAME,securityLevel: relationalStore.SecurityLevel.S1};try {this.rdbStore = await relationalStore.getRdbStore(context, storeConfig);await this.createTables();return this.rdbStore;} catch (error) {const err = error as BusinessError;console.error(`初始化数据库失败: ${err.code} - ${err.message}`);throw new Error(`数据库初始化失败: ${err.message}`);}}/**** @returns*/private async createTables(): Promise<void> {if (!this.rdbStore) {throw new Error('数据库未初始化,请先调用initDB方法');}const createTableSql: string = `CREATE TABLE IF NOT EXISTS signInRecord (id INTEGER PRIMARY KEY AUTOINCREMENT,employeeId TEXT NOT NULL,employeeName TEXT NOT NULL,signInTime TEXT NOT NULL)`;try {await this.rdbStore.executeSql(createTableSql);console.log('签到记录表创建成功或已存在');} catch (error) {const err = error as BusinessError;console.error(`创建签到记录表失败: ${err.code} - ${err.message}`);throw new Error(`创建数据表失败: ${err.message}`);}}/**** @returns*/public getRdbStore(): relationalStore.RdbStore | null {if (!this.rdbStore) {console.warn('数据库尚未初始化,请先调用initDB方法');}return this.rdbStore;}/*** 修正关闭数据库的方法* @returns*/public async closeDB(): Promise<void> {if (this.rdbStore && this.context) {try {// 正确调用deleteRdbStore,需要传入上下文和数据库名称await relationalStore.deleteRdbStore(this.context, DBHelper.DB_NAME);this.rdbStore = null;this.context = null; // 清除上下文console.log('数据库已关闭并删除');} catch (error) {const err = error as BusinessError;console.error(`关闭数据库失败: ${err.code} - ${err.message}`);throw new Error(`关闭数据库失败: ${err.message}`);}} else {if (!this.context) {console.warn('上下文不存在,无法关闭数据库');} else {console.warn('数据库连接不存在,无需关闭');}}}
}/*
# encoding: utf-8
# 版权所有 2025 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:
# Author : geovindu,Geovin Du 涂聚文.
# IDE : DevEco Studio 5.1.1 HarmonyOS
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2025/7/22 19:14
# User : geovindu
# Product : DevEco Studio
# Project : MyApplication
# File : IsignIn.ets
*/import { SignInRecord } from '../model/signIn';export interface ISignIn {/*** 添加签到记录* @param record* @returns*/addSignInRecord(record: SignInRecord): Promise<number>;/*** 根据ID获取签到记录* @param id* @returns*/getSignInRecordById(id: number): Promise<SignInRecord | null>;/*** 获取所有签到记录* @returns*/getAllSignInRecords(): Promise<SignInRecord[]>;/*** 根据员工ID获取签到记录* @param employeeId* @returns*/getSignInRecordsByEmployeeId(employeeId: string): Promise<SignInRecord[]>;/*** 更新签到记录* @param record* @returns*/updateSignInRecord(record: SignInRecord): Promise<number>;/*** 删除签到记录* @param id* @returns*/deleteSignInRecord(id: number): Promise<number>;
}/*
# encoding: utf-8
# 版权所有 2025 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:
# Author : geovindu,Geovin Du 涂聚文.
# IDE : DevEco Studio 5.1.1 HarmonyOS
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2025/7/22 19:16
# User : geovindu
# Product : DevEco Studio
# Project : MyApplication
# File : AbstractFactory.ets
*/
import { ISignIn } from '../Interface/IsignIn';
import { SignInDAL } from '../DAL/signIn';
import { SignInBLL } from '../BLL/signIn';/*** 抽象工厂类*/
export abstract class AbstractFactory {// 创建数据访问层实例public abstract createSignInDAL(): ISignIn;// 创建业务逻辑层实例public abstract createSignInBLL(): ISignIn;
}/*** 签到记录工厂类*/
export class SignInFactory extends AbstractFactory {// 创建签到记录数据访问层实例public createSignInDAL(): ISignIn {return new SignInDAL();}/*** 创建签到记录业务逻辑层实例* @returns*/public createSignInBLL(): ISignIn {// 可以在这里注入不同的DAL实现,方便测试或切换数据源const dal = this.createSignInDAL();return new SignInBLL(dal);}
}/*
# encoding: utf-8
# 版权所有 2025 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:
# Author : geovindu,Geovin Du 涂聚文.
# IDE : DevEco Studio 5.1.1 HarmonyOS
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2025/7/22 19:17
# User : geovindu
# Product : DevEco Studio
# Project : MyApplication
# File : signIn.ets
*/
import relationalStore from '@ohos.data.relationalStore';
import { DBHelper } from '../UtilitieDB/DBHelper';
import { SignInRecord, SignInRecordDbObject } from '../model/signIn';
import { ISignIn } from '../Interface/IsignIn';
import { BusinessError } from '@ohos.base';// 定义与数据库字段对应的类型映射
type SignInColumn = 'id' | 'employeeId' | 'employeeName' | 'signInTime';export class SignInDAL implements ISignIn {private getRdbStore() {const rdbStore = DBHelper.getInstance().getRdbStore();if (!rdbStore) {throw new Error('数据库未初始化,请先调用initDB方法');}return rdbStore;}/*** 添加签到记录* @param record* @returns*/async addSignInRecord(record: SignInRecord): Promise<number> {try {const dbObject = record.toDbObject();// 构建符合要求的ValuesBucketconst valuesBucket: relationalStore.ValuesBucket = {'employeeId': dbObject.employeeId,'employeeName': dbObject.employeeName,'signInTime': dbObject.signInTime};const rowId = await this.getRdbStore().insert('signInRecord', valuesBucket);return rowId;} catch (error) {const err = error as BusinessError;console.error(`添加签到记录失败: ${err.code} - ${err.message}`);throw new Error(`添加签到记录失败: ${err.message}`);}}/*** 根据ID获取签到记录* @param id* @returns*/async getSignInRecordById(id: number): Promise<SignInRecord | null> {try {const predicates = new relationalStore.RdbPredicates('signInRecord');predicates.equalTo('id', id);const resultSet = await this.getRdbStore().query(predicates, ['*']);let record: SignInRecord | null = null;if (await resultSet.goToFirstRow()) {const dbObject: SignInRecordDbObject = {id: resultSet.getLong(resultSet.getColumnIndex('id')),employeeId: resultSet.getString(resultSet.getColumnIndex('employeeId')),employeeName: resultSet.getString(resultSet.getColumnIndex('employeeName')),signInTime: resultSet.getString(resultSet.getColumnIndex('signInTime'))};record = SignInRecord.fromDbObject(dbObject);}await resultSet.close();return record;} catch (error) {const err = error as BusinessError;console.error(`查询签到记录失败: ${err.code} - ${err.message}`);throw new Error(`查询签到记录失败: ${err.message}`);}}/*** 根据员工ID获取签到记录* @param employeeId* @returns*/async getSignInRecordsByEmployeeId(employeeId: string): Promise<SignInRecord[]> {try {const predicates = new relationalStore.RdbPredicates('signInRecord');predicates.equalTo('employeeId', employeeId).orderByDesc('signInTime');const resultSet = await this.getRdbStore().query(predicates, ['*']);const records: SignInRecord[] = [];while (await resultSet.goToNextRow()) {const dbObject: SignInRecordDbObject = {id: resultSet.getLong(resultSet.getColumnIndex('id')),employeeId: resultSet.getString(resultSet.getColumnIndex('employeeId')),employeeName: resultSet.getString(resultSet.getColumnIndex('employeeName')),signInTime: resultSet.getString(resultSet.getColumnIndex('signInTime'))};records.push(SignInRecord.fromDbObject(dbObject));}await resultSet.close();return records;} catch (error) {const err = error as BusinessError;console.error(`根据员工ID查询签到记录失败: ${err.code} - ${err.message}`);throw new Error(`根据员工ID查询签到记录失败: ${err.message}`);}}/*** 获取所有签到记录* @returns*/async getAllSignInRecords(): Promise<SignInRecord[]> {try {const predicates = new relationalStore.RdbPredicates('signInRecord');predicates.orderByDesc('signInTime');const resultSet = await this.getRdbStore().query(predicates, ['*']);const records: SignInRecord[] = [];while (await resultSet.goToNextRow()) {const dbObject: SignInRecordDbObject = {id: resultSet.getLong(resultSet.getColumnIndex('id')),employeeId: resultSet.getString(resultSet.getColumnIndex('employeeId')),employeeName: resultSet.getString(resultSet.getColumnIndex('employeeName')),signInTime: resultSet.getString(resultSet.getColumnIndex('signInTime'))};records.push(SignInRecord.fromDbObject(dbObject));}await resultSet.close();return records;} catch (error) {const err = error as BusinessError;console.error(`获取所有签到记录失败: ${err.code} - ${err.message}`);throw new Error(`获取所有签到记录失败: ${err.message}`);}}/*** 更新签到记录* @param record* @returns*/async updateSignInRecord(record: SignInRecord): Promise<number> {if (record.id === null) {throw new Error('更新失败,签到记录ID不能为空');}try {const dbObject = record.toDbObject();const predicates = new relationalStore.RdbPredicates('signInRecord');predicates.equalTo('id', record.id); // 这里已经指定了要更新的记录ID// 构建ValuesBucket,不包含id字段,因为不需要更新主键const valuesBucket: relationalStore.ValuesBucket = {'employeeId': dbObject.employeeId,'employeeName': dbObject.employeeName,'signInTime': dbObject.signInTime};// 执行更新操作const rowsUpdated = await this.getRdbStore().update(valuesBucket, predicates);return rowsUpdated;} catch (error) {const err = error as BusinessError;console.error(`更新签到记录失败: ${err.code} - ${err.message}`);throw new Error(`更新签到记录失败: ${err.message}`);}}/*** 删除签到记录* @param id* @returns*/async deleteSignInRecord(id: number): Promise<number> {try {const predicates = new relationalStore.RdbPredicates('signInRecord');predicates.equalTo('id', id);const rowsDeleted = await this.getRdbStore().delete(predicates);return rowsDeleted;} catch (error) {const err = error as BusinessError;console.error(`删除签到记录失败: ${err.code} - ${err.message}`);throw new Error(`删除签到记录失败: ${err.message}`);}}/*** 将结果集转换为签到记录数组* @param resultSet* @returns*/private convertResultSetToSignInRecords(resultSet: relationalStore.ResultSet): SignInRecord[] {const records: SignInRecord[] = [];resultSet.goToFirstRow();do {const record = this.convertResultSetToSignInRecord(resultSet);records.push(record);} while (resultSet.goToNextRow());return records;}/*** 结果集转换为单个签到记录* @param resultSet* @returns*/private convertResultSetToSignInRecord(resultSet: relationalStore.ResultSet): SignInRecord {return new SignInRecord(resultSet.getString(resultSet.getColumnIndex('employeeId')),resultSet.getString(resultSet.getColumnIndex('employeeName')),resultSet.getString(resultSet.getColumnIndex('signInTime')),resultSet.getLong(resultSet.getColumnIndex('id')));}}/*
# encoding: utf-8
# 版权所有 2025 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:
# Author : geovindu,Geovin Du 涂聚文.
# IDE : DevEco Studio 5.1.1 HarmonyOS
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2025/7/22 18:18
# User : geovindu
# Product : DevEco Studio
# Project : MyApplication
# File : signIn.ets
*/
import { ISignIn } from '../Interface/IsignIn';
import { SignInRecord } from '../model/signIn';
import { SignInDAL } from '../DAL/signIn';export class SignInBLL implements ISignIn {private signInDAL: ISignIn;constructor(signInDAL: ISignIn = new SignInDAL()) {this.signInDAL = signInDAL;}/*** 添加签到记录,包含业务逻辑验证* @param record* @returns*/async addSignInRecord(record: SignInRecord): Promise<number> {// 业务逻辑验证:检查必要字段if (!record.employeeId || record.employeeId.trim() === '') {throw new Error('员工ID不能为空');}if (!record.employeeName || record.employeeName.trim() === '') {throw new Error('员工姓名不能为空');}// 检查签到时间格式是否合法if (!this.isValidDateTime(record.signInTime)) {throw new Error('签到时间格式不正确');}// 调用数据访问层添加记录return this.signInDAL.addSignInRecord(record);}/*** 根据ID获取签到记录* @param id* @returns*/async getSignInRecordById(id: number): Promise<SignInRecord | null> {if (id <= 0) {throw new Error('无效的记录ID');}return this.signInDAL.getSignInRecordById(id);}/*** 获取所有签到记录* @returns*/async getAllSignInRecords(): Promise<SignInRecord[]> {return this.signInDAL.getAllSignInRecords();}/*** 根据员工ID获取签到记录* @param employeeId* @returns*/async getSignInRecordsByEmployeeId(employeeId: string): Promise<SignInRecord[]> {if (!employeeId || employeeId.trim() === '') {throw new Error('员工ID不能为空');}return this.signInDAL.getSignInRecordsByEmployeeId(employeeId);}/*** 更新签到记录* @param record* @returns*/async updateSignInRecord(record: SignInRecord): Promise<number> {if (!record.id) {throw new Error('签到记录ID不能为空');}/*** 验证更新的数据*/if (!record.employeeId || record.employeeId.trim() === '') {throw new Error('员工ID不能为空');}if (!this.isValidDateTime(record.signInTime)) {throw new Error('签到时间格式不正确');}return this.signInDAL.updateSignInRecord(record);}/*** 删除签到记录* @param id* @returns*/async deleteSignInRecord(id: number): Promise<number> {if (id <= 0) {throw new Error('无效的记录ID');}return this.signInDAL.deleteSignInRecord(id);}// 验证日期时间格式 (YYYY-MM-DD HH:MM:SS)private isValidDateTime(dateTime: string): boolean {const regex = /^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/;return regex.test(dateTime);}
}/*
# encoding: utf-8
# 版权所有 2025 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:
# Author : geovindu,Geovin Du 涂聚文.
# IDE : DevEco Studio 5.1.1 HarmonyOS
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2025/7/22 18:56
# User : geovindu
# Product : DevEco Studio
# Project : MyApplication
# File : SignInExample.ets
*/
import { Context } from '@ohos.abilityAccessCtrl';
import { SignInFactory } from '../Factory/AbstractFactory';
import { DBHelper } from '../UtilitieDB/DBHelper';
import { SignInRecord } from '../model/signIn';
import { ISignIn } from '../Interface/IsignIn';export class SignInExample {private signInBLL: ISignIn;constructor(context: Context) {// 初始化数据库this.initDatabase(context);// 通过工厂获取BLL实例const factory = new SignInFactory();this.signInBLL = factory.createSignInBLL();}/*** 初始化数据库* @param context*/private async initDatabase(context: Context) {try {await DBHelper.getInstance().initDB(context);console.log('数据库初始化成功');} catch (error) {console.error('数据库初始化失败:', error);}}/*** 添加签到记录示例* @returns*/async addSignInRecordExample() {try {// 创建签到记录对象const now = new Date();const signInTime = `${now.getFullYear()}-${(now.getMonth() + 1).toString().padStart(2, '0')}-${now.getDate().toString().padStart(2, '0')} ${now.getHours().toString().padStart(2, '0')}:${now.getMinutes().toString().padStart(2, '0')}:${now.getSeconds().toString().padStart(2, '0')}`;const record = new SignInRecord('EMP001', // employeeId'张三', // employeeNamesignInTime // signInTime);// 调用BLL层添加记录const rowId = await this.signInBLL.addSignInRecord(record);console.log(`添加签到记录成功,ID: ${rowId}`);return rowId;} catch (error) {console.error('添加签到记录失败:', error);return null;}}/*** 查询签到记录示例*/async querySignInRecordsExample() {try {// 1. 查询所有签到记录const allRecords = await this.signInBLL.getAllSignInRecords();console.log(`所有签到记录(${allRecords.length}条):`, allRecords);// 2. 根据ID查询记录(假设我们知道一个存在的ID)if (allRecords.length > 0) {const firstRecordId = allRecords[0].id;if (firstRecordId !== null) {const singleRecord = await this.signInBLL.getSignInRecordById(firstRecordId);console.log(`ID为${firstRecordId}的签到记录:`, singleRecord);}}// 3. 根据员工ID查询记录const empRecords = await this.signInBLL.getSignInRecordsByEmployeeId('EMP001');console.log(`员工EMP001的签到记录(${empRecords.length}条):`, empRecords);return allRecords;} catch (error) {console.error('查询签到记录失败:', error);return null;}}/**** @param id* @returns*/async querySignInRecordsExampleId(id:string) {try {// 1. 查询所有签到记录const allRecords = await this.signInBLL.getSignInRecordsByEmployeeId(id);console.log(`所有签到记录(${allRecords.length}条):`, allRecords);// 2. 根据ID查询记录(假设我们知道一个存在的ID)if (allRecords.length > 0) {const firstRecordId = allRecords[0].id;if (firstRecordId !== null) {const singleRecord = await this.signInBLL.getSignInRecordById(firstRecordId);console.log(`ID为${firstRecordId}的签到记录:`, singleRecord);}}// 3. 根据员工ID查询记录const empRecords = await this.signInBLL.getSignInRecordsByEmployeeId('EMP001');console.log(`员工EMP001的签到记录(${empRecords.length}条):`, empRecords);return allRecords;} catch (error) {console.error('查询签到记录失败:', error);return null;}}/*** 更新签到记录示例* @param recordId*/async updateSignInRecordExample(recordId: number) {try {// 先查询要更新的记录const record = await this.signInBLL.getSignInRecordById(recordId);if (!record) {console.log(`未找到ID为${recordId}的签到记录`);return -1;}// 修改记录内容record.employeeName = '张三(更新)'; // 修改员工姓名// 调用BLL层更新记录const rowsUpdated = await this.signInBLL.updateSignInRecord(record);console.log(`更新成功,影响行数: ${rowsUpdated}`);// 验证更新结果const updatedRecord = await this.signInBLL.getSignInRecordById(recordId);console.log('更新后的记录:', updatedRecord);return 1;} catch (error) {console.error('更新签到记录失败:', error);return -1;}}/*** 删除签到记录示例* @param recordId*/async deleteSignInRecordExample(recordId: number) {try {// 调用BLL层删除记录const rowsDeleted = await this.signInBLL.deleteSignInRecord(recordId);console.log(`删除成功,影响行数: ${rowsDeleted}`);// 验证删除结果const deletedRecord = await this.signInBLL.getSignInRecordById(recordId);if (!deletedRecord) {console.log(`ID为${recordId}的签到记录已成功删除`);}return 1;} catch (error) {console.error('删除签到记录失败:', error);return -1;}}/*** 完整操作流程示例*/async completeOperationFlow() {// 1. 添加一条新记录const newRecordId = await this.addSignInRecordExample();if (newRecordId) {// 2. 查询记录await this.querySignInRecordsExample();// 3. 更新记录await this.updateSignInRecordExample(newRecordId);// 4. 删除记录await this.deleteSignInRecordExample(newRecordId);}// 关闭数据库(通常在应用退出时调用)// await DBHelper.getInstance().closeDB();}
}// 在Ability中使用示例
// export default class SignInAbility extends Ability {
// onWindowStageCreate(windowStage: window.WindowStage) {
// // 初始化示例并执行操作
// const signInExample = new SignInExample(this.context);
// signInExample.completeOperationFlow();
// }
// }
调用:
/**# encoding: utf-8# 版权所有 2024 ©涂聚文有限公司# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎# 描述:# Author : geovindu,Geovin Du 涂聚文.# IDE : DevEco Studio 5.1.1# OS : windows 10# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j# Datetime : 2025/7/22 19:33# User : geovindu# Product : MyApplicatin# Project : MyApplicatin# File : Register.ets* */import router from '@ohos.router'
import promptAction from '@ohos.promptAction'
import { SignInExample } from '../Controller/SignInExample';
import { SignInRecord } from '../model/signIn';
import { Context } from '@ohos.abilityAccessCtrl';@Entry
@Component
struct Register {@State message: string = '注册用户';// 页面数据@State allRecords: SignInRecord[] = [];@State employeeId: string = 'EMP001';@State employeeName: string = '张三';@State currentRecordId: number | null = null;// 页面上下文(用于数据库初始化)private context: Context = getContext(this) as Context;// 签到业务实例private signInExample: SignInExample = new SignInExample(this.context);// 页面加载时初始化数据async aboutToAppear() {await this.loadAllRecords(); // 加载所有签到记录}// 加载所有签到记录// 修正后的加载所有签到记录方法async loadAllRecords() {try {// 调用查询方法并获取结果const result = await this.signInExample.querySignInRecordsExample();// 空值判断:如果结果为null,设置为空数组if (result === null) {this.allRecords = [];promptAction.showToast({ message: '没有查询到签到记录' });return;}// 类型判断:确保返回的是数组if (!Array.isArray(result)) {this.allRecords = [];promptAction.showToast({ message: '数据格式错误' });console.error('查询签到记录返回非数组类型:', result);return;}// 正常赋值this.allRecords = result;// 空数组提示if (this.allRecords.length === 0) {promptAction.showToast({ message: '当前没有签到记录' });}} catch (error) {// 错误处理:统一捕获并处理所有可能的异常this.allRecords = []; // 出错时清空列表const errorMsg = error instanceof Error ? error.message : String(error);promptAction.showToast({ message: `加载失败: ${errorMsg}` });console.error('加载签到记录失败:', error);}}/*** 添加签到记录(绑定按钮点击事件)*/async handleAdd() {if (!this.employeeId || !this.employeeName) {promptAction.showToast({ message: '请输入员工ID和姓名' });return;}try {// 生成当前时间(格式:yyyy-MM-dd HH:mm:ss)const now = new Date();const signInTime = `${now.getFullYear()}-${(now.getMonth() + 1).toString().padStart(2, '0')}-${now.getDate().toString().padStart(2, '0')} ${now.getHours().toString().padStart(2, '0')}:${now.getMinutes().toString().padStart(2, '0')}:${now.getSeconds().toString().padStart(2, '0')}`;// 创建记录并添加const record = new SignInRecord(this.employeeId, this.employeeName, signInTime);const newId = await this.signInExample.addSignInRecordExample(); //recordpromptAction.showToast({ message: `添加成功,ID: ${newId}` });// 刷新列表await this.loadAllRecords();} catch (error) {promptAction.showToast({ message: `添加失败: ${error.message}` });}}/*** 更新签到记录(绑定按钮点击事件)* @param record*/async handleUpdate(record: SignInRecord) {if (!record.id) {promptAction.showToast({ message: '记录ID不存在' });return;}try {// 修改记录(示例:在姓名后加"[已更新]")const updatedRecord = new SignInRecord(record.employeeId,`${record.employeeName}[已更新]`,record.signInTime,record.id);// 执行更新const rows = await this.signInExample.updateSignInRecordExample(1) //(updatedRecord);if (rows > 0) {promptAction.showToast({ message: '更新成功' });await this.loadAllRecords(); // 刷新列表}} catch (error) {promptAction.showToast({ message: `更新失败: ${error.message}` });}}/*** 删除签到记录(绑定按钮点击事件)* @param id*/async handleDelete(id: number) {try {const rows = await this.signInExample.deleteSignInRecordExample(id);if (rows > 0) {promptAction.showToast({ message: '删除成功' });await this.loadAllRecords(); // 刷新列表}} catch (error) {promptAction.showToast({ message: `删除失败: ${error.message}` });}}/*** 根据员工ID查询(绑定按钮点击事件)*/async handleQueryByEmpId() {// 验证员工ID输入if (!this.employeeId || this.employeeId.trim() === '') {promptAction.showToast({ message: '请输入有效的员工ID' });return;}try {// 调用BLL层方法查询(修正方法名和调用方式)const result = await this.signInExample.querySignInRecordsExampleId(this.employeeId.trim());// 空值判断if (result === null) {this.allRecords = [];promptAction.showToast({ message: '未查询到相关记录' });return;}// 类型验证if (!Array.isArray(result)) {this.allRecords = [];promptAction.showToast({ message: '查询数据格式错误' });console.error('员工签到记录查询返回非数组类型:', result);return;}// 赋值并提示结果this.allRecords = result;// 根据结果数量显示不同提示if (this.allRecords.length === 0) {promptAction.showToast({ message: `未查询到员工${this.employeeId}的签到记录` });} else {promptAction.showToast({ message: `查询到${this.allRecords.length}条记录` });}} catch (error) {// 错误处理this.allRecords = [];const errorMsg = error instanceof Error ? error.message : String(error);promptAction.showToast({ message: `查询失败: ${errorMsg}` });console.error(`查询员工${this.employeeId}的签到记录失败:`, error);}}// 界面渲染build() {Column() {// 操作区域Column() {Text('签到管理').fontSize(20).fontWeight(FontWeight.Bold).margin(10);// 输入区域Row() {Button('添加签到').onClick(() => this.handleAdd()).backgroundColor('#007DFF');Button('查询该员工').onClick(() => this.handleQueryByEmpId()).backgroundColor('#00B42A');Button('查询所有').onClick(() => this.loadAllRecords()).backgroundColor('#F53F3F');Button('返回').onClick(() => {router.back();}).backgroundColor('#F53F3F');}.margin(10);// 记录列表Scroll() {List() {ForEach(this.allRecords, (record: SignInRecord) => {ListItem() {Row() {Column() {Text(`ID: ${record.id}`).fontSize(12);Text(`员工: ${record.employeeName}(${record.employeeId})`).fontSize(14);Text(`签到时间: ${record.signInTime}`).fontSize(12);}.width('70%');Column() {Button('修改').onClick(() => this.handleUpdate(record)).width(80).margin(5).backgroundColor('#FF7D00');Button('删除').onClick(() => this.handleDelete(record.id!)).width(80).margin(5).backgroundColor('#F53F3F');}}.padding(10);}})}}.width('100%').flexGrow(1);}.width('100%').height('100%');}.width('100%').height('100%');}
}
输出: