我用 HarmonyOS NEXT 做了一款排班倒班 App

我用 HarmonyOS NEXT 做了一款排班倒班 App,把 3D Soft UI 写进了日历

一款叫《班妥了》的鸿蒙原生 + 微信小程序双端排班应用,聊聊我为什么做、怎么做、踩了哪些坑。

0. 前言

我是一名 AI 平台工程师。去年开始给自己写一个排班工具,原因是市面上实在找不到一个「小而美、本地优先、能看清自己一年到底有多拼」的 App。于是从 0 开始用 HarmonyOS NEXT 撸了一版,又顺手做了个微信小程序版给同事用。

先放个成品图。左边手机端个人版月历,右边平板端团队排班:

1. 为什么做

排班这个场景其实很割裂

  • Excel:自由但丑,且多端没法同步
  • 钉钉/企业微信排班:重 B 端,个人用起来被淹没在团队功能里
  • 国外 App(Shiftly、Shyft 等):云端 + 付费 + 国内访问偶尔抽风
  • 极简个人向:好看,但没有月历 / 没有统计 / 没有团队视图

我想做一个「会陪着我值夜班」的工具:

  • 打开就知道今天是什么班
  • 看一眼月历知道这个月节奏
  • 看一眼年度知道今年真的辛苦过
  • 团队里能让我快速看谁连班了、谁该轮休

2. 技术栈

技术
鸿蒙原生 ArkTS + HarmonyOS NEXT(Stage 模型)
微信小程序 原生 WXML/WXSS + 微信云开发
团队数据同步 HarmonyOS 端用分布式数据 + 云函数兜底

为什么不上 Flutter / RN? 鸿蒙 NEXT 已经不兼容 AOSP 套件,纯血鸿蒙的体验和性能 ArkTS 是唯一正解。微信小程序则是因为团队里有同事没装鸿蒙原生 App,得让 Ta 们扫个码就能用。

3. 关键模块拆解

3.1 数据模型

班次是循环 + 临时双轨:

typescript 复制代码
// 班次循环(持续到被打断)
interface ScheduleCycle {
  id: string;
  userId: string;
  startDate: string;        // 从哪天开始循环
  pattern: ShiftType[];     // [白班, 晚班, 夜班, 休] 这种顺序
  // ...
}

// 临时调整(覆盖某一天)
interface ScheduleOverride {
  date: string;             // 哪一天
  shift: ShiftType;         // 这一天的班次
  note?: string;
  cycleId: string;          // 属于哪个循环
}

月历渲染时先取循环再覆盖临时,这样既不破坏循环,又留了"今天和白班兄弟换一下"的口子。

3.2 月历的 3D 软 UI 怎么实现

这里我踩了第一个坑------毛玻璃在 ArkTS 里的写法跟 iOS 完全不同

  • ❌ iOS 的 backdrop-filter: blur() 不能直接拿过来
  • ✅ HarmonyOS 的方案是Stack 叠两层 + 前景色用 Color.BlendMode.OVERLAY
  • ✅ 圆角和阴影用 borderRadius + shadow 复合,3D 感来自阴影的颜色(不是纯黑,而是品牌色的低饱和版)
typescript 复制代码
@Builder
function GlassCard() {
  Stack() {
    // 底层:背景模糊模拟
    Column().width('100%').height('100%')
      .backgroundColor('#F3E5F5')
      .blur(20)
    // 顶层:玻璃质感
    Column() {
      // 内容
    }
    .width('100%').height('100%')
    .backgroundColor('rgba(255,255,255,0.6)')
    .borderRadius(20)
    .shadow({ radius: 24, color: '#E8F5E9', offsetY: 8 })
  }
}

阴影颜色取自品牌色板(#E8F5E9 薄荷绿 / #F3E5F5 樱花粉 / #37474F 深石板),比纯黑阴影更柔和也更克制

3.3 统计图表

没有用三方库,全部用 Canvas 自绘------鸿蒙的 Canvas 性能足够,个人版月统计这种轻量图表没必要引 ECharts。

typescript 复制代码
// 月度班次分布
@Builder
function ShiftDistribution(shifts: ShiftCount[]) {
  Canvas(this.context)
    .onReady(() => {
      // 画 5 条横条:早班 / 白班 / 晚班 / 夜班 / 休息
      shifts.forEach((s, i) => {
        const ratio = s.count / max;
        // 进度条用 渐变 + 圆头
      });
    })
}

4. 团队版的取舍

团队版没做云端账号体系,而是:

  • 主管在自己的鸿蒙 App 里排好班
  • 一键"发布"生成一个团队码
  • 成员扫这个码进入微信小程序,只读 + 申请调班
  • 主管再在 App 里批量调整并发布

这个设计绕开了企业级账号 / 权限 / 审计 的复杂度,对小团队(≤20 人)刚刚好

5. 一些彩蛋

  • 今日片刻 :每天轮换一句鼓励 / 短句,从"不用预支整天的疲惫"到"公平比看起来平均更重要",不鸡汤、有点暖(设计师朋友说这是灵魂 😄)
  • 多主题:浅蓝 / 浅绿 / 樱花粉 / 深色模式
  • 年度回顾 :把这一年的工时、连班、夜班做成一张自己的日历热力图

6. 反思与不足

  • 团队版还没做权限分级------所有成员都能申请调班,没有"只能看自己"模式
  • iOS 暂未支持------纯血鸿蒙的优先级更高,鸿蒙版体验最完整
  • 没有云端账本 ------数据本地优先,换手机需要走备份恢复(这是设计选择,但确实劝退了一些人)

7. 体验一下

  • 鸿蒙原生版 :HarmonyOS 应用市场搜「班妥了
  • 微信小程序版:扫下面这个码

如果你也是倒班人,欢迎反馈你最在意的功能;如果你是开发者,欢迎来喷我的代码 ☕️。

相关推荐
●VON13 小时前
芯笺 Markdown:面向 HarmonyOS PC 的本地优先 Markdown 编辑器
华为·编辑器·harmonyos·鸿蒙
世人万千丶13 小时前
鸿蒙项目实战 - 社区活动编排板:标签云布局算法与自动换行
学习·算法·华为·harmonyos·鸿蒙
YM52e15 小时前
鸿蒙ArkTS项目实战 - 门店陈列巡检台:完整代码与运行效果
学习·华为·harmonyos
贾伟康15 小时前
【中国方言题库|06】HarmonyOS ArkTS 闽南语与客家话实战:统一分库页面导航与空状态
harmonyos·arkts·arkui·router·空状态
贾伟康15 小时前
【中国方言题库|07】HarmonyOS ArkTS 方言练习实战:推进题目、提交答案并同步统计
harmonyos·arkts·数据持久化·状态管理·arkui
深念Y16 小时前
RIO-UL00(EMUI 4.1 / Android 6.0.1 / arm64)开机自启动 sshd
android·linux·华为·安卓·chroot·sshd·emui
AI备忘录16 小时前
(十二)MSTP 多实例生成树配置命令五厂商对照:华为 华三 锐捷 迈普 思科
华为
贾伟康16 小时前
【中国方言题库|05】HarmonyOS ArkTS 东北话分库实战:让地区内容与通用列表解耦
harmonyos·arkts·路由·arkui·数据架构
HwJack2017 小时前
鸿蒙AbilityKit深度解析:应用模型的核心骨架
华为·harmonyos