ArKTS: DAL,Model,BLL,Interface,Factory using SQLite

发布于:2025-07-24 ⋅ 阅读:(32) ⋅ 点赞:(0)

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();
  
      // 构建符合要求的ValuesBucket
      const 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
        '张三',          // employeeName
        signInTime       // 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(); //record
      promptAction.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%');
  }
}

输出:


网站公告

今日签到

点亮在社区的每一天
去签到