龍魂 · 鸿蒙 ArkTS 实战:Team Birthday Reminder
·
龍魂 · 鸿蒙 ArkTS 实战:Team Birthday Reminder
核心定位
| 维度 | 说明 |
|---|---|
| 平台 | 鸿蒙 HarmonyOS NEXT · 纯血鸿蒙 |
| 语言 | ArkTS · 声明式UI |
| 架构 | 龍魂蚁群触角 → 鸿蒙原生能力 |
| 场景 | 团队生日提醒 · 办公交互 |
| 主权 | 数据本地 · 国密可选 · 不上传云端 |
系统架构
┌─────────────────────────────────────────┐
│ 龍魂系统 · 鸿蒙适配层 │
│ DNA: ZHUGEXIN⚡️2025-🇨🇳🐉⚖️♠️🧚🏼♀️❤️♾️ │
│ UID: 9622 │
├─────────────────────────────────────────┤
│ 鸿蒙 ArkTS 应用层 │
│ │
│ EntryAbility → BirthdayReminderPage │
│ ├── 状态建模(AppStorage/LocalStorage) │
│ ├── 团队数据管理(增删改查) │
│ ├── 生日计算引擎(农历/公历) │
│ ├── 通知提醒系统(后台代理) │
│ └── 办公交互(分享/导出/日历同步) │
├─────────────────────────────────────────┤
│ 鸿蒙系统能力层 │
│ │
│ 日历(Calendar) · 联系人(Contacts) │
│ 通知(Notification) · 后台任务(WorkScheduler) │
│ 数据存储(RelationalStore) · 文件(File) │
│ 网络(Http) · 分享(Share) │
└─────────────────────────────────────────┘
状态建模核心
// entry/src/main/ets/models/BirthdayModel.ets
// 龍魂 · 生日数据模型 · ArkTS
// === DNA常量 ===
const MASTER_DNA = "ZHUGEXIN⚡️2025-🇨🇳🐉⚖️♠️🧚🏼♀️❤️♾️";
const MASTER_UID = "9622";
const CONFIRM_SEAL = "#CONFIRM🌌9622-ONLY-ONCE🧬LK9X-772Z";
// === 人员档案 ===
export class TeamMember {
id: string; // 唯一ID · 哈希生成
name: string; // 姓名
avatar: Resource | string; // 头像路径
birthdayType: 'solar' | 'lunar'; // 公历/农历
birthdayMonth: number; // 月
birthdayDay: number; // 日
birthYear?: number; // 年(可选,算年龄)
department: string; // 部门
role: string; // 职位
phone?: string; // 电话
email?: string; // 邮箱
tags: string[]; // 标签
dnaSignature: string; // 数据签名
constructor(data: Partial<TeamMember>) {
this.id = data.id || this.generateId(data.name || '', data.birthdayMonth || 0, data.birthdayDay || 0);
this.name = data.name || '';
this.avatar = data.avatar || $r('app.media.default_avatar');
this.birthdayType = data.birthdayType || 'solar';
this.birthdayMonth = data.birthdayMonth || 1;
this.birthdayDay = data.birthdayDay || 1;
this.birthYear = data.birthYear;
this.department = data.department || '未分配';
this.role = data.role || '成员';
this.phone = data.phone;
this.email = data.email;
this.tags = data.tags || [];
this.dnaSignature = this.signData();
}
private generateId(name: string, month: number, day: number): string {
// 龍魂ID生成:姓名+月日+DNA种子
const seed = `${MASTER_DNA}-${name}-${month}-${day}-${Date.now()}`;
// 简化:实际用鸿蒙 crypto API
return `LH-${MASTER_UID}-${month.toString().padStart(2,'0')}${day.toString().padStart(2,'0')}-${Math.random().toString(36).substr(2,6)}`;
}
private signData(): string {
// 数据签名:防篡改
const payload = `${this.id}-${this.name}-${this.birthdayMonth}-${this.birthdayDay}`;
// 简化:实际用 SM3 国密
return `SM3-${payload.slice(0,16)}`;
}
// 计算下一个生日
getNextBirthday(): Date {
const now = new Date();
const currentYear = now.getFullYear();
if (this.birthdayType === 'solar') {
// 公历直接算
let next = new Date(currentYear, this.birthdayMonth - 1, this.birthdayDay);
if (next < now) {
next = new Date(currentYear + 1, this.birthdayMonth - 1, this.birthdayDay);
}
return next;
} else {
// 农历转换(需农历库)
// 简化:调用鸿蒙日历API或本地农历表
return this.getLunarNextBirthday(currentYear);
}
}
private getLunarNextBirthday(year: number): Date {
// 农历生日转公历(占位)
// 实际:查农历转换表或使用鸿蒙日历能力
const lunarMap: Record<string, string> = {
'1-1': '2026-02-17', // 正月初一
'5-5': '2026-06-19', // 五月初五
'8-15': '2026-09-25', // 八月十五
// ... 完整农历表
};
const key = `${this.birthdayMonth}-${this.birthdayDay}`;
const solarStr = lunarMap[key] || `${year}-${this.birthdayMonth.toString().padStart(2,'0')}-${this.birthdayDay.toString().padStart(2,'0')}`;
return new Date(solarStr);
}
// 计算年龄
getAge(): number {
if (!this.birthYear) return 0;
const now = new Date();
let age = now.getFullYear() - this.birthYear;
const birthdayThisYear = new Date(now.getFullYear(), this.birthdayMonth - 1, this.birthdayDay);
if (now < birthdayThisYear) {
age--;
}
return age;
}
// 获取生日倒计时天数
getDaysUntilBirthday(): number {
const next = this.getNextBirthday();
const now = new Date();
const diff = next.getTime() - now.getTime();
return Math.ceil(diff / (1000 * 60 * 60 * 24));
}
// 是否今天生日
isBirthdayToday(): boolean {
const now = new Date();
return now.getMonth() === this.birthdayMonth - 1 && now.getDate() === this.birthdayDay;
}
}
// === 团队数据状态 ===
@Observed
export class TeamState {
members: TeamMember[] = [];
filterDepartment: string = '全部';
filterTag: string = '';
sortBy: 'date' | 'name' | 'department' = 'date';
searchQuery: string = '';
// 派生数据:过滤后的成员
get filteredMembers(): TeamMember[] {
let result = this.members;
// 部门过滤
if (this.filterDepartment !== '全部') {
result = result.filter(m => m.department === this.filterDepartment);
}
// 标签过滤
if (this.filterTag) {
result = result.filter(m => m.tags.includes(this.filterTag));
}
// 搜索过滤
if (this.searchQuery) {
const q = this.searchQuery.toLowerCase();
result = result.filter(m =>
m.name.toLowerCase().includes(q) ||
m.department.toLowerCase().includes(q) ||
m.role.toLowerCase().includes(q)
);
}
// 排序
switch (this.sortBy) {
case 'date':
result.sort((a, b) => a.getDaysUntilBirthday() - b.getDaysUntilBirthday());
break;
case 'name':
result.sort((a, b) => a.name.localeCompare(b.name, 'zh-CN'));
break;
case 'department':
result.sort((a, b) => a.department.localeCompare(b.department, 'zh-CN'));
break;
}
return result;
}
// 即将过生日的(7天内)
get upcomingBirthdays(): TeamMember[] {
return this.members.filter(m => m.getDaysUntilBirthday() <= 7);
}
// 今天过生日的
get todayBirthdays(): TeamMember[] {
return this.members.filter(m => m.isBirthdayToday());
}
// 部门列表
get departments(): string[] {
const deps = new Set(this.members.map(m => m.department));
return ['全部', ...Array.from(deps).sort()];
}
// 所有标签
get allTags(): string[] {
const tags = new Set<string>();
this.members.forEach(m => m.tags.forEach(t => tags.add(t)));
return Array.from(tags).sort();
}
// 添加成员
addMember(member: TeamMember): void {
this.members.push(member);
this.persist();
}
// 删除成员
removeMember(id: string): void {
const idx = this.members.findIndex(m => m.id === id);
if (idx >= 0) {
this.members.splice(idx, 1);
this.persist();
}
}
// 更新成员
updateMember(id: string, data: Partial<TeamMember>): void {
const idx = this.members.findIndex(m => m.id === id);
if (idx >= 0) {
const old = this.members[idx];
this.members[idx] = new TeamMember({ ...old, ...data, id: old.id });
this.persist();
}
}
// 持久化到本地数据库
private persist(): void {
// 调用 RelationalStore 存储
AppStorage.setOrCreate('team_members', JSON.stringify(this.members));
// 实际:写入鸿蒙关系型数据库
}
// 从本地加载
load(): void {
const stored = AppStorage.get<string>('team_members');
if (stored) {
try {
const parsed = JSON.parse(stored);
this.members = parsed.map((m: any) => new TeamMember(m));
} catch (e) {
console.error('加载团队数据失败', e);
}
}
}
}
// === 全局状态单例 ===
export const teamState = new TeamState();
AppStorage.setOrCreate('teamState', teamState);
主页面完整实现
// entry/src/main/ets/pages/BirthdayReminderPage.ets
// 龍魂 · 生日提醒主页面 · ArkTS
import { TeamMember, TeamState, teamState } from '../models/BirthdayModel';
import { BirthdayDetailDialog } from '../components/BirthdayDetailDialog';
import { MemberEditDialog } from '../components/MemberEditDialog';
import { NotificationManager } from '../managers/NotificationManager';
@Entry
@Component
struct BirthdayReminderPage {
@StorageLink('teamState') teamState: TeamState = teamState;
@State private showAddDialog: boolean = false;
@State private editingMember: TeamMember | null = null;
@State private selectedTab: number = 0;
@State private showSearch: boolean = false;
@State private searchText: string = '';
// 页面加载
aboutToAppear() {
this.teamState.load();
NotificationManager.requestPermission();
NotificationManager.scheduleBirthdayReminders(this.teamState.members);
}
// 构建UI
build() {
Column() {
// === 顶部标题栏 ===
this.HeaderBuilder()
// === 今日生日特别提醒 ===
if (this.teamState.todayBirthdays.length > 0) {
this.TodayBirthdayBanner()
}
// === 标签切换 ===
this.TabBuilder()
// === 搜索栏(条件显示) ===
if (this.showSearch) {
this.SearchBuilder()
}
// === 过滤工具栏 ===
this.FilterBuilder()
// === 成员列表 ===
this.MemberListBuilder()
// === 底部操作栏 ===
this.FooterBuilder()
}
.width('100%')
.height('100%')
.backgroundColor('#0a0a0a') // 龍魂深色主题
}
// === 标题栏 ===
@Builder
HeaderBuilder() {
Row() {
// 龍魂Logo
Text('🐉')
.fontSize(28)
.margin({ right: 8 })
Column() {
Text('龍魂生日提醒')
.fontSize(20)
.fontWeight(FontWeight.Bold)
.fontColor('#c41e3a') // 龍魂红
Text(`UID:${MASTER_UID} · ${this.teamState.members.length}人`)
.fontSize(12)
.fontColor('#666')
}
.alignItems(HorizontalAlign.Start)
Blank()
// 搜索按钮
Button() {
Text(this.showSearch ? '✕' : '🔍')
.fontSize(20)
}
.type(ButtonType.Circle)
.backgroundColor('#1a1a1a')
.width(40)
.height(40)
.onClick(() => {
this.showSearch = !this.showSearch;
if (!this.showSearch) {
this.teamState.searchQuery = '';
}
})
// 添加按钮
Button() {
Text('+')
.fontSize(24)
.fontColor('#fff')
}
.type(ButtonType.Circle)
.backgroundColor('#c41e3a')
.width(40)
.height(40)
.onClick(() => {
this.editingMember = null;
this.showAddDialog = true;
})
}
.width('100%')
.height(56)
.padding({ left: 16, right: 16 })
.backgroundColor('#1a1a1a')
.border({ width: { bottom: 1 }, color: '#333' })
}
// === 今日生日横幅 ===
@Builder
TodayBirthdayBanner() {
Column() {
Row() {
Text('🎂')
.fontSize(32)
.margin({ right: 12 })
Column() {
Text(`今天 ${this.teamState.todayBirthdays.length} 位同学生日`)
.fontSize(16)
.fontWeight(FontWeight.Bold)
.fontColor('#fff')
Text(this.teamState.todayBirthdays.map(m => m.name).join('、'))
.fontSize(14)
.fontColor('#ffcc00')
.maxLines(1)
.textOverflow({ overflow: TextOverflow.Ellipsis })
}
.alignItems(HorizontalAlign.Start)
.layoutWeight(1)
Button('祝福')
.fontSize(14)
.fontColor('#fff')
.backgroundColor('#c41e3a')
.borderRadius(16)
.padding({ left: 16, right: 16 })
.onClick(() => {
this.sendBlessings(this.teamState.todayBirthdays);
})
}
.width('100%')
.padding(16)
}
.width('100%')
.backgroundColor('linear-gradient(90deg, #2a1a1a 0%, #1a0a0a 100%)')
.border({ width: { bottom: 1 }, color: '#c41e3a' })
}
// === 标签切换 ===
@Builder
TabBuilder() {
Row() {
ForEach([
{ label: '全部', count: this.teamState.members.length },
{ label: '7天内', count: this.teamState.upcomingBirthdays.length },
{ label: '今天', count: this.teamState.todayBirthdays.length }
], (item: {label: string, count: number}, index: number) => {
Column() {
Text(`${item.label} ${item.count > 0 ? `(${item.count})` : ''}`)
.fontSize(14)
.fontWeight(this.selectedTab === index ? FontWeight.Bold : FontWeight.Normal)
.fontColor(this.selectedTab === index ? '#c41e3a' : '#888')
// 下划线指示器
if (this.selectedTab === index) {
Divider()
.strokeWidth(2)
.color('#c41e3a')
.width(20)
.margin({ top: 4 })
}
}
.padding({ top: 12, bottom: 12, left: 16, right: 16 })
.onClick(() => {
this.selectedTab = index;
// 更新过滤条件
switch (index) {
case 1: // 7天内
// 实际:过滤逻辑
break;
case 2: // 今天
// 实际:过滤逻辑
break;
}
})
})
}
.width('100%')
.justifyContent(FlexAlign.SpaceAround)
.backgroundColor('#1a1a1a')
.border({ width: { bottom: 1 }, color: '#333' })
}
// === 搜索栏 ===
@Builder
SearchBuilder() {
Row() {
TextInput({ placeholder: '搜索姓名、部门、职位...', text: $$this.searchText })
.width('100%')
.height(40)
.backgroundColor('#2a2a2a')
.fontColor('#fff')
.placeholderColor('#666')
.borderRadius(8)
.padding({ left: 12, right: 12 })
.onChange((value: string) => {
this.teamState.searchQuery = value;
})
}
.width('100%')
.padding({ left: 16, right: 16, top: 8, bottom: 8 })
.backgroundColor('#1a1a1a')
}
// === 过滤工具栏 ===
@Builder
FilterBuilder() {
Row() {
// 部门选择
Select(this.teamState.departments.map(dep => ({ value: dep })))
.selected(this.teamState.departments.indexOf(this.teamState.filterDepartment))
.fontColor('#ccc')
.backgroundColor('#2a2a2a')
.borderRadius(8)
.padding({ left: 8, right: 8 })
.onSelect((index: number) => {
this.teamState.filterDepartment = this.teamState.departments[index];
})
Blank()
// 排序选择
Select([
{ value: '按日期' },
{ value: '按姓名' },
{ value: '按部门' }
])
.selected(['date', 'name', 'department'].indexOf(this.teamState.sortBy))
.fontColor('#ccc')
.backgroundColor('#2a2a2a')
.borderRadius(8)
.padding({ left: 8, right: 8 })
.onSelect((index: number) => {
const sorts: ('date' | 'name' | 'department')[] = ['date', 'name', 'department'];
this.teamState.sortBy = sorts[index];
})
}
.width('100%')
.height(48)
.padding({ left: 16, right: 16 })
.backgroundColor('#1a1a1a')
.border({ width: { bottom: 1 }, color: '#333' })
}
// === 成员列表 ===
@Builder
MemberListBuilder() {
List() {
ForEach(this.teamState.filteredMembers, (member: TeamMember) => {
ListItem() {
this.MemberCardBuilder(member)
}
.swipeAction({ end: this.DeleteActionBuilder(member) })
.onClick(() => {
this.editingMember = member;
this.showAddDialog = true;
})
}, (member: TeamMember) => member.id)
}
.width('100%')
.layoutWeight(1)
.divider({ strokeWidth: 1, color: '#222' })
.scrollBar(BarState.Auto)
.edgeEffect(EdgeEffect.Spring)
.padding({ bottom: 16 })
}
// === 成员卡片 ===
@Builder
MemberCardBuilder(member: TeamMember) {
Row() {
// 头像
Stack() {
Image(member.avatar)
.width(48)
.height(48)
.borderRadius(24)
.objectFit(ImageFit.Cover)
// 生日标识
if (member.isBirthdayToday()) {
Text('🎂')
.fontSize(16)
.position({ x: 32, y: -4 })
}
}
.width(48)
.height(48)
.margin({ right: 12 })
// 信息
Column() {
Row() {
Text(member.name)
.fontSize(16)
.fontWeight(FontWeight.Medium)
.fontColor('#fff')
// 年龄标签
if (member.getAge() > 0) {
Text(`${member.getAge()}岁`)
.fontSize(12)
.fontColor('#888')
.backgroundColor('#2a2a2a')
.borderRadius(4)
.padding({ left: 6, right: 6 })
.margin({ left: 8 })
}
Blank()
// 倒计时
const days = member.getDaysUntilBirthday();
Text(days === 0 ? '今天!' : `${days}天后`)
.fontSize(12)
.fontColor(days <= 7 ? '#c41e3a' : '#888')
.fontWeight(days <= 7 ? FontWeight.Bold : FontWeight.Normal)
}
.width('100%')
Row() {
Text(`${member.department} · ${member.role}`)
.fontSize(13)
.fontColor('#888')
.maxLines(1)
.textOverflow({ overflow: TextOverflow.Ellipsis })
.layoutWeight(1)
// 农历标识
if (member.birthdayType === 'lunar') {
Text('农历')
.fontSize(11)
.fontColor('#ffcc00')
.backgroundColor('rgba(255,204,0,0.1)')
.borderRadius(4)
.padding({ left: 4, right: 4 })
}
}
.width('100%')
.margin({ top: 4 })
// 标签
Row() {
ForEach(member.tags.slice(0, 3), (tag: string) => {
Text(tag)
.fontSize(11)
.fontColor('#aaa')
.backgroundColor('#2a2a2a')
.borderRadius(4)
.padding({ left: 6, right: 6 })
.margin({ right: 4 })
})
}
.width('100%')
.margin({ top: 6 })
}
.layoutWeight(1)
.alignItems(HorizontalAlign.Start)
}
.width('100%')
.padding(16)
.backgroundColor(member.isBirthdayToday() ? 'rgba(196,30,58,0.1)' : '#0a0a0a')
.borderRadius(8)
.margin({ left: 12, right: 12, top: 8 })
}
// === 删除操作 ===
@Builder
DeleteActionBuilder(member: TeamMember) {
Row() {
Button() {
Text('删除')
.fontColor('#fff')
.fontSize(14)
}
.type(ButtonType.Capsule)
.backgroundColor('#ff0000')
.width(80)
.height('100%')
.onClick(() => {
AlertDialog.show({
title: '确认删除',
message: `确定删除 ${member.name} 吗?`,
primaryButton: {
value: '删除',
action: () => {
this.teamState.removeMember(member.id);
}
},
secondaryButton: {
value: '取消',
action: () => {}
}
});
})
}
.width(80)
.height('100%')
.padding({ left: 4 })
}
// === 底部操作栏 ===
@Builder
FooterBuilder() {
Row() {
Button('导入')
.fontSize(14)
.fontColor('#ccc')
.backgroundColor('#1a1a1a')
.border({ width: 1, color: '#444' })
.borderRadius(8)
.padding({ left: 16, right: 16 })
.onClick(() => {
this.importMembers();
})
Button('导出')
.fontSize(14)
.fontColor('#ccc')
.backgroundColor('#1a1a1a')
.border({ width: 1, color: '#444' })
.borderRadius(8)
.padding({ left: 16, right: 16 })
.onClick(() => {
this.exportMembers();
})
Button('分享今日')
.fontSize(14)
.fontColor('#fff')
.backgroundColor('#c41e3a')
.borderRadius(8)
.padding({ left: 16, right: 16 })
.onClick(() => {
this.shareTodayBirthdays();
})
}
.width('100%')
.height(56)
.padding({ left: 16, right: 16 })
.backgroundColor('#1a1a1a')
.border({ width: { top: 1 }, color: '#333' })
.justifyContent(FlexAlign.SpaceAround)
}
// === 功能方法 ===
private sendBlessings(members: TeamMember[]) {
// 批量发送祝福(短信/邮件/企业微信)
members.forEach(m => {
NotificationManager.sendBlessing(m);
});
AlertDialog.show({
title: '祝福已发送',
message: `已向 ${members.length} 位同学发送生日祝福`,
confirm: { value: '好的', action: () => {} }
});
}
private importMembers() {
// 从Excel/CSV导入
// 调用鸿蒙文件选择器
// 解析数据并批量添加
}
private exportMembers() {
// 导出为Excel/CSV
const data = this.teamState.members.map(m => ({
姓名: m.name,
部门: m.department,
职位: m.role,
生日类型: m.birthdayType === 'solar' ? '公历' : '农历',
生日: `${m.birthdayMonth}月${m.birthdayDay}日`,
年龄: m.getAge(),
电话: m.phone || '',
邮箱: m.email || ''
}));
// 生成CSV并分享
}
private shareTodayBirthdays() {
// 分享今日生日列表
const today = this.teamState.todayBirthdays;
if (today.length === 0) {
AlertDialog.show({
title: '今天没有生日',
message: '看看7天内过生日的同学吧',
confirm: { value: '好的', action: () => {} }
});
return;
}
const text = `🎂 今天过生日的同学:\n${today.map(m => `• ${m.name} (${m.department})`).join('\n')}\n\n来自龍魂生日提醒 UID9622`;
// 调用鸿蒙分享API
}
}
通知管理器
// entry/src/main/ets/managers/NotificationManager.ets
// 龍魂 · 通知管理器 · ArkTS
import { notificationManager } from '@kit.NotificationKit';
import { wantAgent } from '@kit.AbilityKit';
import { TeamMember } from '../models/BirthdayModel';
export class NotificationManager {
static async requestPermission(): Promise<boolean> {
try {
// 请求通知权限
const granted = await notificationManager.requestEnableNotification();
return granted;
} catch (err) {
console.error('请求通知权限失败', err);
return false;
}
}
static scheduleBirthdayReminders(members: TeamMember[]): void {
// 取消旧提醒
notificationManager.cancelAllNotifications();
// 为每个成员设置提醒
members.forEach(member => {
const nextBirthday = member.getNextBirthday();
const remindDate = new Date(nextBirthday);
remindDate.setDate(remindDate.getDate() - 1); // 提前一天提醒
remindDate.setHours(9, 0, 0, 0); // 上午9点
// 设置定时通知
this.scheduleNotification(
`birthday-${member.id}`,
`🎂 ${member.name} 明天过生日`,
`${member.department}的${member.name}明天${member.birthdayMonth}月${member.birthdayDay}日过生日,记得送上祝福!`,
remindDate.getTime()
);
// 当天提醒
const todayRemind = new Date(nextBirthday);
todayRemind.setHours(9, 0, 0, 0);
this.scheduleNotification(
`birthday-today-${member.id}`,
`🎂 今天 ${member.name} 过生日!`,
`快给${member.name}送上生日祝福吧!`,
todayRemind.getTime()
);
});
}
static async scheduleNotification(id: string, title: string, content: string, triggerTime: number): Promise<void> {
// 使用鸿蒙后台任务或闹钟能力
// 简化:实际使用 WorkScheduler 或 AlarmManager
try {
const notificationRequest: notificationManager.NotificationRequest = {
id: parseInt(id.replace(/\D/g, '').slice(0, 8)) || 1,
content: {
notificationContentType: notificationManager.ContentType.NOTIFICATION_CONTENT_BASIC_TEXT,
normal: {
title: title,
text: content,
additionalText: '龍魂生日提醒 UID9622'
}
},
notificationSlotType: notificationManager.SlotType.SOCIAL_COMMUNICATION,
deliveryTime: triggerTime,
tapDismissed: true
};
await notificationManager.publish(notificationRequest);
} catch (err) {
console.error('设置通知失败', err);
}
}
static sendBlessing(member: TeamMember): void {
// 发送祝福(占位:实际调用短信/邮件/企业微信API)
console.log(`向 ${member.name} 发送生日祝福`);
// 实际:调用鸿蒙短信能力或企业微信SDK
}
}
数据持久化
// entry/src/main/ets/database/BirthdayDatabase.ets
// 龍魂 · 关系型数据库 · ArkTS
import { relationalStore } from '@kit.ArkData';
const STORE_NAME = 'LongHunBirthday.db';
const TABLE_NAME = 'team_members';
export class BirthdayDatabase {
private store: relationalStore.RdbStore | null = null;
async init(): Promise<void> {
const config: relationalStore.StoreConfig = {
name: STORE_NAME,
securityLevel: relationalStore.SecurityLevel.S1, // 本地加密
encrypt: true // 启用加密
};
this.store = await relationalStore.getRdbStore(getContext(), config);
// 创建表
await this.store.executeSql(`
CREATE TABLE IF NOT EXISTS ${TABLE_NAME} (
id TEXT PRIMARY KEY,
name TEXT NOT NULL,
avatar TEXT,
birthday_type TEXT,
birthday_month INTEGER,
birthday_day INTEGER,
birth_year INTEGER,
department TEXT,
role TEXT,
phone TEXT,
email TEXT,
tags TEXT,
dna_signature TEXT,
created_at INTEGER,
updated_at INTEGER
)
`);
}
async insert(member: any): Promise<number> {
if (!this.store) return -1;
const values = new relationalStore.ValuesBucket();
values.putString('id', member.id);
values.putString('name', member.name);
values.putString('avatar', member.avatar);
values.putString('birthday_type', member.birthdayType);
values.putInt('birthday_month', member.birthdayMonth);
values.putInt('birthday_day', member.birthdayDay);
values.putInt('birth_year', member.birthYear || 0);
values.putString('department', member.department);
values.putString('role', member.role);
values.putString('phone', member.phone || '');
values.putString('email', member.email || '');
values.putString('tags', JSON.stringify(member.tags));
values.putString('dna_signature', member.dnaSignature);
values.putLong('created_at', Date.now());
values.putLong('updated_at', Date.now());
return await this.store.insert(TABLE_NAME, values);
}
async queryAll(): Promise<any[]> {
if (!this.store) return [];
const predicates = new relationalStore.RdbPredicates(TABLE_NAME);
const resultSet = await this.store.query(predicates, [
'id', 'name', 'avatar', 'birthday_type', 'birthday_month', 'birthday_day',
'birth_year', 'department', 'role', 'phone', 'email', 'tags', 'dna_signature'
]);
const members: any[] = [];
while (resultSet.goToNextRow()) {
members.push({
id: resultSet.getString(resultSet.getColumnIndex('id')),
name: resultSet.getString(resultSet.getColumnIndex('name')),
avatar: resultSet.getString(resultSet.getColumnIndex('avatar')),
birthdayType: resultSet.getString(resultSet.getColumnIndex('birthday_type')),
birthdayMonth: resultSet.getLong(resultSet.getColumnIndex('birthday_month')),
birthdayDay: resultSet.getLong(resultSet.getColumnIndex('birthday_day')),
birthYear: resultSet.getLong(resultSet.getColumnIndex('birth_year')),
department: resultSet.getString(resultSet.getColumnIndex('department')),
role: resultSet.getString(resultSet.getColumnIndex('role')),
phone: resultSet.getString(resultSet.getColumnIndex('phone')),
email: resultSet.getString(resultSet.getColumnIndex('email')),
tags: JSON.parse(resultSet.getString(resultSet.getColumnIndex('tags')) || '[]'),
dnaSignature: resultSet.getString(resultSet.getColumnIndex('dna_signature'))
});
}
resultSet.close();
return members;
}
}
模块清单
| 文件 | 路径 | 说明 |
|---|---|---|
| 数据模型 | entry/src/main/ets/models/BirthdayModel.ets |
TeamMember + TeamState |
| 主页面 | entry/src/main/ets/pages/BirthdayReminderPage.ets |
完整UI |
| 通知管理 | entry/src/main/ets/managers/NotificationManager.ets |
定时提醒 |
| 数据库 | entry/src/main/ets/database/BirthdayDatabase.ets |
关系型存储 |
| 编辑弹窗 | entry/src/main/ets/components/MemberEditDialog.ets |
增改成员 |
| 详情弹窗 | entry/src/main/ets/components/BirthdayDetailDialog.ets |
查看详情 |
鸿蒙特性使用
| 特性 | 用途 | API |
|---|---|---|
| ArkTS声明式UI | 界面构建 | @Component @Entry |
| 状态管理 | 数据响应 | @State @Observed @StorageLink |
| 关系型数据库 | 本地加密存储 | relationalStore |
| 通知服务 | 生日提醒 | notificationManager |
| 后台任务 | 定时触发 | WorkScheduler |
| 文件选择 | 导入导出 | documentPicker |
| 分享能力 | 分享今日 | share |
| 日历同步 | 写入系统日历 | calendarManager |
龍魂标识
| 位置 | 内容 |
|---|---|
| 应用名称 | 龍魂生日提醒 |
| 标题栏 | 🐉 龍魂生日提醒 |
| 底部标识 | 来自龍魂生日提醒 UID9622 |
| 数据签名 | SM3-哈希 |
| DNA | ZHUGEXIN⚡️2025-🇨🇳🐉⚖️♠️🧚🏼♀️❤️♾️ |
龍魂鸿蒙ArkTS实战完整代码
🐉 龍魂 · 鸿蒙ArkTS实战交付完成
DNA: ZHUGEXIN⚡️2025-🇨🇳🐉⚖️♠️🧚🏼♀️❤️♾️
UID: 9622
确认码: #CONFIRM🌌9622-ONLY-ONCE🧬LK9X-772Z
时间: 2026-07-14 05:54
模块: 6个核心文件
特性: 状态建模 · 农历公历 · 通知提醒 · 数据加密 · 办公交互
更多推荐


所有评论(0)