HarmonyOS ArkTS 实战:实现一个外出报备晚归登记应用

HarmonyOS ArkTS 实战:实现一个外出报备晚归登记应用

项目效果

本文使用 HarmonyOS 和 ArkTS 实现一个外出报备晚归登记应用。

应用可以提交外出报备,晚归登记,查看审批状态,历史记录,并提供返校打卡、辅导员审批、请假记录、统计等完整功能。

项目使用 DevEco Studio 开发,适配 API 23 及以上版本。

运行效果

功能介绍

  • 外出报备提交
  • 晚归原因填写
  • 目的地填写
  • 往返时间
  • 紧急联系人
  • 审批状态查询
  • 返校打卡
  • 历史记录
  • 辅导员审批
  • 请假记录
  • 统计分析
  • 提醒通知

定义数据结构

typescript 复制代码
interface Report {
  id: number;
  type: string; // 外出报备/晚归登记
  destination: string;
  reason: string;
  leaveTime: string;
  returnTime: string;
  contact: string;
  contactPhone: string;
  status: string; // 待审批/已通过/已驳回/已返校
  approver: string;
  approveTime: string;
  actualReturnTime: string;
  createTime: string;
}

初始化页面状态

typescript 复制代码
@State private tabIndex: number = 0;
@State private reportType: string = '外出报备';
@State private destination: string = '';
@State private reason: string = '';
@State private leaveTime: string = '2026-07-22 18:00';
@State private returnTime: string = '2026-07-22 21:00';
@State private contact: string = '父母';
@State private contactPhone: string = '138****8888';

@State private reports: Report[] = [
  { id: 1, type: '外出报备', destination: '浦东新区陆家嘴', reason: '购买生活用品', leaveTime: '2026-07-20 14:00', returnTime: '2026-07-20 18:00', contact: '父母', contactPhone: '138****8888', status: '已返校', approver: '张辅导员', approveTime: '2026-07-20 13:30', actualReturnTime: '2026-07-20 17:45', createTime: '2026-07-20 13:00' },
  { id: 2, type: '晚归登记', destination: '虹桥火车站', reason: '接同学', leaveTime: '2026-07-21 20:00', returnTime: '2026-07-21 23:30', contact: '父母', contactPhone: '138****8888', status: '已通过', approver: '张辅导员', approveTime: '2026-07-21 19:50', actualReturnTime: '', createTime: '2026-07-21 19:30' },
];

@State private nextId: number = 10;

提交报备

typescript 复制代码
private submitReport(): void {
  if (!this.destination || !this.reason) return;
  
  const report: Report = {
    id: this.nextId, type: this.reportType, destination: this.destination,
    reason: this.reason, leaveTime: this.leaveTime, returnTime: this.returnTime,
    contact: this.contact, contactPhone: this.contactPhone,
    status: '待审批', approver: '张辅导员', approveTime: '', actualReturnTime: '',
    createTime: new Date().toLocaleString()
  };
  this.reports = [report, ...this.reports];
  this.destination = '';
  this.reason = '';
  this.nextId += 1;
}

返校打卡

typescript 复制代码
private checkIn(reportId: number): void {
  this.reports = this.reports.map(r => r.id === reportId ? {
    ...r, status: '已返校', actualReturnTime: new Date().toLocaleString()
  } : r);
}

状态颜色

typescript 复制代码
private getStatusColor(status: string): string {
  switch (status) {
    case '待审批': return '#F59E0B';
    case '已通过': return '#059669';
    case '已驳回': return '#DC2626';
    case '已返校': return '#7C3AED';
    default: return '#64748B';
  }
}

报备记录卡片组件

typescript 复制代码
@Builder
ReportCard(report: Report) {
  Column({ space: 8 }) {
    Row() {
      Text(report.type)
        .fontSize(12)
        .fontColor(Color.White)
        .padding({ left: 8, right: 8, top: 3, bottom: 3 })
        .backgroundColor(report.type === '外出报备' ? '#7C3AED' : '#DB2777')
        .borderRadius(10)
      Blank()
      Text(report.status)
        .fontSize(12)
        .fontColor(this.getStatusColor(report.status))
        .padding({ left: 8, right: 8, top: 3, bottom: 3 })
        .backgroundColor(this.getStatusColor(report.status) + '20')
        .borderRadius(10)
    }
    .width('100%')
    
    Text(`📍 ${report.destination}`)
      .fontSize(15)
      .fontWeight(FontWeight.Medium)
      .fontColor('#2E1065')
      .width('100%')
    
    Text(`原因:${report.reason}`)
      .fontSize(12)
      .fontColor('#6D28D9')
      .width('100%')
    
    Text(`🕐 ${report.leaveTime} - ${report.returnTime}`)
      .fontSize(12)
      .fontColor('#7C3AED')
    
    Text(`审批人:${report.approver}`)
      .fontSize(11)
      .fontColor('#8B5CF6')
    
    if (report.status === '已通过') {
      Button('返校打卡')
        .width('100%')
        .height(36)
        .fontSize(14)
        .backgroundColor('#7C3AED')
        .margin({ top: 4 })
        .onClick(() => this.checkIn(report.id))
    }
  }
  .width('100%')
  .padding(16)
  .backgroundColor('#F5F3FF')
  .borderRadius(12)
}

页面布局

typescript 复制代码
build() {
  Column() {
    Text('外出报备 · 晚归登记')
      .fontSize(22)
      .fontWeight(FontWeight.Bold)
      .fontColor('#2E1065')
      .width('100%')
      .padding(20)
    
    // Tab
    Row({ space: 20 }) {
      Text('新建报备')
        .fontSize(16)
        .fontWeight(this.tabIndex === 0 ? FontWeight.Bold : FontWeight.Normal)
        .fontColor(this.tabIndex === 0 ? '#2E1065' : '#94A3B8')
        .onClick(() => this.tabIndex = 0)
      Text('报备记录')
        .fontSize(16)
        .fontWeight(this.tabIndex === 1 ? FontWeight.Bold : FontWeight.Normal)
        .fontColor(this.tabIndex === 1 ? '#2E1065' : '#94A3B8')
        .onClick(() => this.tabIndex = 1)
    }
    .width('100%')
    .padding({ left: 20, right: 20 })
    
    if (this.tabIndex === 0) {
      Scroll() {
        Column({ space: 16 }) {
          // 类型选择
          Row({ space: 12 }) {
            Text('外出报备')
              .fontSize(14)
              .fontColor(this.reportType === '外出报备' ? Color.White : '#2E1065')
              .padding({ left: 20, right: 20, top: 10, bottom: 10 })
              .backgroundColor(this.reportType === '外出报备' ? '#7C3AED' : '#F5F3FF')
              .borderRadius(20)
              .onClick(() => this.reportType = '外出报备')
            Text('晚归登记')
              .fontSize(14)
              .fontColor(this.reportType === '晚归登记' ? Color.White : '#2E1065')
              .padding({ left: 20, right: 20, top: 10, bottom: 10 })
              .backgroundColor(this.reportType === '晚归登记' ? '#DB2777' : '#F5F3FF')
              .borderRadius(20)
              .onClick(() => this.reportType = '晚归登记')
          }
          
          TextInput({ text: this.destination, placeholder: '目的地(如:XX商场/XX火车站)' })
            .width('100%')
            .height(44)
            .backgroundColor('#F5F3FF')
            .onChange((v: string) => this.destination = v)
          
          TextArea({ text: this.reason, placeholder: '外出/晚归原因' })
            .width('100%')
            .height(80)
            .backgroundColor('#F5F3FF')
            .onChange((v: string) => this.reason = v)
          
          TextInput({ text: this.leaveTime, placeholder: '出发时间' })
            .width('100%')
            .height(44)
            .backgroundColor('#F5F3FF')
          
          TextInput({ text: this.returnTime, placeholder: '预计返回时间' })
            .width('100%')
            .height(44)
            .backgroundColor('#F5F3FF')
          
          TextInput({ text: this.contact, placeholder: '紧急联系人' })
            .width('100%')
            .height(44)
            .backgroundColor('#F5F3FF')
          
          TextInput({ text: this.contactPhone, placeholder: '紧急联系人电话' })
            .width('100%')
            .height(44)
            .backgroundColor('#F5F3FF')
          
          Button('提交报备')
            .width('100%')
            .height(48)
            .fontSize(16)
            .backgroundColor('#2E1065')
            .margin({ top: 10 })
            .onClick(() => this.submitReport())
        }
        .width('100%')
        .padding(20)
      }
      .layoutWeight(1)
    } else {
      List({ space: 12 }) {
        ForEach(this.reports, (r: Report) => {
          ListItem() { this.ReportCard(r) }
        })
      }
      .width('100%')
      .padding(20)
      .layoutWeight(1)
    }
  }
  .width('100%')
  .height('100%')
  .backgroundColor(Color.White)
}

页面设计说明

主题色采用violet-950#2E1065,深紫色体现安全管理的严肃、规范。紫色系卡片,外出报备紫色、晚归粉色区分,状态标签颜色明确。

SDK配置

API 24,compatibleSdkVersion: "6.1.1(24)"

运行项目

将代码复制到 entry/src/main/ets/pages/Index.ets 即可运行。

项目总结

实现了外出报备、晚归登记、审批状态、返校打卡、历史记录等功能。掌握了表单输入、TextArea多行输入、状态颜色函数、类型切换等。后续可加入定位打卡、辅导员端审批、通知推送、请假统计、位置共享、异常提醒等功能。

相关推荐
aqi004 小时前
鸿蒙版本的JSBridge兼容与安卓配套的H5啦
android·华为·harmonyos·鸿蒙·移动应用
熊猫钓鱼>_>4 小时前
Flutter app_settings 鸿蒙适配实战:Intent 体系到 Want 的跨越
flutter·华为·harmonyos·openharmony·intent·want
贾伟康7 小时前
【句匠|20】HarmonyOS ArkTS AppGallery 发布复查实战:核对包名、版本、设备、素材和离线声明
harmonyos·arkts·应用上架·appgallery·发布审核
贾伟康8 小时前
【句匠|15】HarmonyOS ArkTS 本地状态持久化实战:让保存、删除和页面返回后的数据即时一致
harmonyos·arkts·数据持久化·appstorage·preferences
贾伟康11 小时前
【句匠|16】HarmonyOS ArkTS 多设备布局实战:适配手机、平板和 PC/2in1 的窗口变化
harmonyos·arkts·arkui·响应式布局·多设备适配
小雨青年11 小时前
【HarmonyOS 7 平行视界深度实战】03 购物模式怎么实现连续浏览和左右推挤
华为·harmonyos
SuperHeroWu713 小时前
HarmonyOS Dev Assistant (HarmonyOS开发助手)如何打通元服务开发全流程
ai·agent·harmonyos·vs code·元服务·hbuilderx·assistant
熊猫钓鱼>_>13 小时前
用 OHAudioSuite 空间渲染节点搭一座「3D 有声博物馆」——从三种模式到 FreeBuds 头追的实战记录
c++·3d·ai·harmonyos·arkts·audio·ohaudiosuite
OH_TPC14 小时前
HarmonyOS APP开发---"心动卡"社交匹配App,需要用到这个库
harmonyos
光锥智能14 小时前
HUAWEI WATCH 6系列正式发布:鸿蒙AI手表,智慧健康旗舰
人工智能·华为·harmonyos