鸿蒙拒绝话术生成:基于鸿蒙PC与鸿蒙Flutter框架的智能沟通应用技术实现
鸿蒙拒绝话术生成:基于鸿蒙PC与鸿蒙Flutter框架的智能沟通应用技术实现


一、项目概述
1.1 应用简介和核心功能
拒绝话术生成(AIRefusalTalk) 是一款基于鸿蒙HarmonyOS NEXT平台开发的智能沟通辅助应用,旨在帮助用户在各种场合中委婉、得体地拒绝他人,维护良好的人际关系。
应用核心功能包括:
- 多场景拒绝话术生成:覆盖工作请求、社交邀请、情感表白、商务合作、日常琐事五大场景
- 智能内容推荐:基于场景自动生成5条精选拒绝话术,每条都经过精心设计,既表达立场又不伤和气
- 沟通小贴士:每个场景配有专属沟通技巧提示,帮助用户更好地把握拒绝的方式和时机
- 一键生成:点击即可快速获取拒绝话术列表,无需复杂操作
1.2 开发背景和意义
在日常生活和工作中,我们经常需要面对各种请求和邀请,有些时候我们不得不拒绝。然而,很多人在拒绝他人时会感到为难,不知道如何表达才能既坚持自己的立场,又不伤害对方的感情。根据相关调研数据显示,约50%的人群表示在拒绝他人时存在困扰,担心因此影响人际关系。
拒绝话术生成应用正是为了解决这一痛点而生。通过提供精心设计的拒绝话术和沟通技巧,帮助用户:
- 委婉得体地拒绝他人,维护良好人际关系
- 学习拒绝技巧,增强沟通能力
- 在各种场合中保持自信和从容
1.3 目标用户群体
- 职场人士:需要拒绝工作请求但又不想得罪同事或领导的职场精英
- 社交人士:需要拒绝社交邀请但又不想伤害朋友感情的人群
- 单身人群:需要拒绝情感表白但又不想伤害对方的单身人士
- 创业者:需要拒绝商务合作但又不想影响未来合作机会的创业者
- 普通人:需要处理日常琐事中的拒绝场景的普通用户
二、技术架构设计
2.1 鸿蒙HarmonyOS NEXT开发环境搭建
开发环境的搭建是项目成功的基础。我们采用了以下技术栈:
开发工具:
- DevEco Studio 5.0+:鸿蒙官方IDE,提供完整的开发、调试、构建工具链
- Node.js 18.19+:用于npm包管理和构建脚本
- JDK 17+:Java开发环境,支持HarmonyOS构建工具
- Ohos NPM 10.5+:鸿蒙专用npm仓库,提供丰富的第三方库
环境配置要点:
# 配置鸿蒙npm源
npm config set @ohos:registry=https://registry.npmmirror.com
# 初始化HarmonyOS项目
npx degit ohos/harmonyos-next-starter#master .
# 安装依赖
npm install
2.2 ArkTS语言特性和优势
ArkTS是鸿蒙HarmonyOS NEXT的主力开发语言,具有以下特性:
声明式UI开发:
@Entry
@Component
struct AIRefusalTalkPage {
@State selectedType: string = '工作请求';
build() {
Column() {
Text('拒绝话术生成').fontSize(20).fontWeight(FontWeight.Bold)
}
}
}
状态管理装饰器:
@State:组件内部状态,变化时触发UI刷新@Prop:父组件单向传递的状态@Link:父子组件双向绑定的状态@Provide/@Consume:跨层级状态传递
类型安全:
ArkTS是强类型语言,所有变量和参数都必须显式声明类型,避免了运行时类型错误。
2.3 组件化架构设计
应用采用组件化架构,将UI分解为多个可复用的组件:
@Builder Selector(label: string, options: string[], selected: string, onChange: (v: string) => void) {
Column() {
Text(label).fontSize(14).fontColor('#8E8E93').margin({ bottom: 8 })
Scroll() {
Row() {
ForEach(options, (opt: string) => {
Text(opt).fontSize(14)
.backgroundColor(selected === opt ? '#FF5722' : '#F5F5F5')
.padding({ left: 14, right: 14, top: 8, bottom: 8 })
.borderRadius(8).margin({ right: 8 })
.onClick(() => { onChange(opt); })
})
}
}.scrollBar(BarState.Off).width('100%')
}
}
2.4 状态管理方案(@State)
应用采用@State作为主要状态管理方案,实现响应式UI:
struct AIRefusalTalkPage {
@State selectedType: string = '工作请求';
@State result: RefusalResult | undefined = undefined;
@State isGenerating: boolean = false;
private callLLMApi(): void {
this.isGenerating = true;
setTimeout(() => {
this.result = this.generateMock();
this.isGenerating = false;
}, 1000);
}
}
2.5 路由导航设计
应用使用鸿蒙官方路由API实现页面跳转:
import { router } from '@kit.ArkUI';
@Builder Header(title: string, color: string) {
Row() {
Text('←').fontSize(24).fontColor('#FFFFFF')
.onClick(() => { router.back(); })
Text(title).fontSize(20).fontWeight(FontWeight.Bold).fontColor('#FFFFFF')
.margin({ left: 12 })
}
}
三、核心功能实现
3.1 主要功能模块详细说明
场景选择模块:
- 提供5种预设场景:工作请求、社交邀请、情感表白、商务合作、日常琐事
- 用户可通过横向滚动选择场景类型
- 选中状态通过颜色变化反馈给用户
拒绝话术生成模块:
- 根据选中场景自动生成5条精选拒绝话术
- 拒绝话术内容经过精心设计,既表达立场又不伤和气
- 每条拒绝话术前添加表情符号,增强视觉吸引力
沟通小贴士模块:
- 每个场景配有专属沟通技巧提示
- 提示内容针对场景特点,提供实用建议
- 使用浅橙色背景突出显示
3.2 关键代码解析
数据模型定义:
interface RefusalResult {
type: string;
talks: string[];
tips: string;
}
Mock数据生成:
private generateMock(): RefusalResult {
let talks: string[] = [];
let tips: string = '';
if (this.selectedType === '工作请求') {
talks = [
'谢谢你的信任,不过我目前手头的工作比较多,恐怕无法抽出时间来帮忙。建议你找一下其他同事,他们可能更有时间。',
'很抱歉,我现在的工作安排比较满,暂时无法接手这个任务。如果你有其他需要帮忙的地方,我会尽力配合。',
'感谢你的邀请,不过我目前正在处理一个紧急项目,可能无法参与这个工作。希望你能理解。',
'很遗憾,我目前的工作量已经饱和了,无法再承担新的任务。建议你提前规划,以便更好地分配工作。',
'谢谢你的好意,不过我觉得这个任务更适合由其他同事来完成,他们在这方面更有经验。希望你能找到合适的人选。'
];
tips = '工作拒绝要委婉,给出合理理由';
}
return { type: this.selectedType, talks: talks, tips: tips };
}
UI构建逻辑:
build() {
Column() {
this.Header('拒绝话术生成', '#FF5722')
Scroll() {
Column() {
this.Selector('场景类型', this.typeOptions, this.selectedType,
(v: string) => { this.selectedType = v; })
Button(this.isGenerating ? '生成中...' : '生成')
.width('100%').height(48).backgroundColor('#FF5722')
.fontSize(16).fontWeight(FontWeight.Bold).fontColor('#FFFFFF')
.borderRadius(12).margin({ bottom: 16 })
.onClick(() => { this.callLLMApi(); })
if (this.result !== undefined) {
Column() {
ForEach(this.result.talks, (talk: string) => {
Text('🙅 ' + talk).fontSize(16).fontColor('#333333')
.padding(16).backgroundColor('#FFFFFF').borderRadius(8).margin({ bottom: 8 })
})
Text('小贴士:' + this.result.tips).fontSize(14).fontColor('#8E8E93')
.padding(12).backgroundColor('#FFECB3').borderRadius(8)
}.width('100%')
}
}.padding(16)
}.layoutWeight(1).scrollBar(BarState.Off)
}.width('100%').height('100%').backgroundColor('#F5F5F5')
}
3.3 Mock数据设计
Mock数据设计遵循以下原则:
场景覆盖全面:
- 工作请求:委婉拒绝,给出合理理由
- 社交邀请:礼貌拒绝,表达感谢
- 情感表白:温柔拒绝,保持尊重
- 商务合作:专业拒绝,留有余地
- 日常琐事:友好拒绝,说明原因
内容质量保证:
- 每条拒绝话术都经过精心设计,既表达立场又不伤和气
- 语言得体,态度诚恳
- 内容丰富,覆盖不同表达角度
数据结构清晰:
{
type: '工作请求',
talks: ['拒绝话术1', '拒绝话术2', ...],
tips: '沟通小贴士'
}
3.4 AI接口预留方案
应用预留了大模型API调用接口,可通过以下方式集成:
private async callLLMApi(): void {
this.isGenerating = true;
// 实际项目中替换为真实API调用
// const response = await fetch('https://api.example.com/generate', {
// method: 'POST',
// headers: { 'Content-Type': 'application/json' },
// body: JSON.stringify({
// scene: this.selectedType,
// count: 5
// })
// });
// const data = await response.json();
// this.result = data;
// 当前使用Mock数据
setTimeout(() => {
this.result = this.generateMock();
this.isGenerating = false;
}, 1000);
this.isGenerating = false;
}
四、鸿蒙PC适配方案
4.1 大屏适配策略
响应式布局设计:
- 使用
layoutWeight()实现弹性布局 - 组件宽度使用百分比或
'100%' - 字体大小根据屏幕尺寸自适应
多设备支持:
- 手机:单列布局,紧凑显示
- 平板:两列布局,充分利用屏幕空间
- PC:多列布局,展示更多内容
4.2 鼠标交互优化
鼠标悬停效果:
Text(opt).fontSize(14)
.backgroundColor(selected === opt ? '#FF5722' : '#F5F5F5')
.onHover((isHover: boolean) => {
// 悬停时改变样式
})
右键菜单支持:
- 添加右键点击事件
- 提供复制、分享等功能
滚轮滚动优化:
- 支持滚轮快速滚动
- 优化滚动流畅度
4.3 多窗口支持
窗口模式适配:
- 支持窗口最大化、最小化
- 窗口大小改变时自动调整布局
- 多窗口同时运行时保持数据独立
拖拽操作支持:
- 支持组件拖拽排序
- 支持窗口拖拽移动
4.4 性能优化方案
列表渲染优化:
- 使用
ForEach组件时提供唯一key - 虚拟滚动支持,只渲染可见区域
图片资源优化:
- 使用合适的图片格式(WebP)
- 图片懒加载,减少初始加载时间
缓存策略:
- 缓存生成的拒绝话术结果
- 避免重复请求
五、鸿蒙Flutter框架对比分析
5.1 ArkUI vs Flutter组件体系对比
组件声明方式:
ArkTS(鸿蒙):
@Entry
@Component
struct AIRefusalTalkPage {
build() {
Column() {
Text('拒绝话术生成')
}
}
}
Flutter:
class AIRefusalTalkPage extends StatelessWidget {
Widget build(BuildContext context) {
return Column(
children: [Text('拒绝话术生成')],
);
}
}
状态管理:
ArkTS使用装饰器:
@State selectedType: string = '工作请求';
Flutter使用StatefulWidget:
class _AIRefusalTalkPageState extends State<AIRefusalTalkPage> {
String selectedType = '工作请求';
}
5.2 开发效率对比
优势对比:
| 方面 | 鸿蒙ArkUI | Flutter |
|---|---|---|
| 开发语言 | ArkTS(TypeScript超集) | Dart |
| UI开发方式 | 声明式,类似React | 声明式,类似React |
| 组件丰富度 | 官方组件库 | Material/Cupertino组件库 |
| 热更新 | 支持 | 支持 |
| 平台集成 | 深度集成HarmonyOS | 通过插件集成 |
5.3 性能表现对比
渲染性能:
- ArkUI基于Native渲染,性能接近原生
- Flutter使用Skia渲染引擎,跨平台一致性好
内存占用:
- ArkUI内存占用较低,更适合资源受限设备
- Flutter内存占用较高,但性能稳定
启动速度:
- ArkUI启动速度快,冷启动体验好
- Flutter首次启动较慢,但后续流畅
5.4 适用场景分析
选择鸿蒙的场景:
- 需要深度集成鸿蒙生态
- 面向华为设备用户
- 需要多设备协同能力
- 追求极致性能
选择Flutter的场景:
- 需要跨平台支持(iOS/Android/Web)
- 已有Flutter开发团队
- 需要快速迭代和热更新
- 需要丰富的第三方插件
六、UI/UX设计规范
6.1 设计理念和原则
设计理念:
- 简洁美观:界面简洁,信息层次清晰
- 易用性:操作简单,一键生成
- 友好性:使用温暖的橙色主题,营造友好氛围
设计原则:
- 一致性:统一的视觉风格和交互模式
- 反馈及时:按钮点击、状态变化有明确反馈
- 容错性:提供默认选项,避免用户迷茫
6.2 配色方案和主题
主色调:
- 主题色:#FF5722(橙色)
- 背景色:#F5F5F5(浅灰色)
- 卡片色:#FFFFFF(白色)
辅助色:
- 文字主色:#333333(深灰色)
- 文字辅色:#8E8E93(浅灰色)
- 选中态:#FF5722(橙色)
主题支持:
- 支持浅色模式和深色模式
- 深色模式下自动调整颜色对比度
6.3 交互体验优化
动画效果:
- 页面切换使用平滑过渡动画
- 按钮点击有缩放反馈
- 列表项加载使用渐入动画
操作流程:
- 简化操作步骤,一键生成
- 提供清晰的操作指引
- 支持快捷操作(如复制拒绝话术)
反馈机制:
- 生成过程显示加载状态
- 生成完成有成功提示
- 错误状态有友好提示
6.4 响应式设计
布局适配:
- 移动端:单列布局,紧凑显示
- 平板:两列布局,充分利用空间
- PC端:多列布局,信息展示更丰富
字体适配:
- 根据屏幕尺寸自动调整字体大小
- 保持良好的可读性
间距适配:
- 使用相对单位,适配不同屏幕密度
七、开发实战经验
7.1 开发过程中的难点和解决方案
难点1:场景选择器的横向滚动实现
解决方案:使用Scroll包裹Row,设置scrollBar(BarState.Off)隐藏滚动条,实现流畅的横向滚动效果。
难点2:异步数据加载的状态管理
解决方案:使用@State isGenerating状态管理加载状态,在加载过程中显示"生成中…"提示,加载完成后显示结果。
难点3:拒绝话术列表的动态渲染
解决方案:使用ForEach组件遍历拒绝话术数组,动态生成列表项,每个列表项使用Text组件展示拒绝话术内容。
7.2 性能优化技巧
优化1:减少重渲染
- 合理使用
@State、@Prop、@Link等状态管理装饰器 - 避免在build方法中进行复杂计算
优化2:列表渲染优化
- 为
ForEach提供唯一key值 - 使用虚拟滚动减少DOM节点数量
优化3:图片资源优化
- 使用WebP格式图片
- 图片懒加载,按需加载
7.3 调试和测试经验
调试技巧:
- 使用DevEco Studio的调试工具
- 添加日志输出辅助调试
- 使用断点调试定位问题
测试方法:
- 单元测试:测试数据生成逻辑
- 集成测试:测试组件交互
- 真机测试:在实际设备上验证功能
7.4 常见问题和坑点
问题1:状态更新不生效
解决方案:确保在@State变量修改后,UI会自动刷新。如果不生效,检查是否在异步回调中修改状态。
问题2:ForEach渲染报错
解决方案:确保ForEach的数据源是数组类型,且每个元素有唯一标识。
问题3:布局错乱
解决方案:检查布局容器的嵌套关系,确保正确使用layoutWeight()和flex属性。
八、总结与展望
8.1 项目总结
拒绝话术生成应用基于鸿蒙HarmonyOS NEXT平台开发,采用ArkTS语言和ArkUI声明式UI框架,实现了智能拒绝话术推荐功能。应用具有以下特点:
- 功能完整:覆盖五大社交场景,提供丰富的拒绝话术库
- 用户体验好:界面美观,操作简单,响应迅速
- 技术先进:采用最新的鸿蒙开发技术,性能优异
- 扩展性强:预留AI接口,支持后续功能扩展
8.2 未来规划
功能扩展:
- 添加用户自定义拒绝话术功能
- 支持拒绝话术收藏和分享
- 增加AI智能推荐,根据用户偏好定制拒绝话术
- 添加语音朗读功能,帮助用户练习表达
平台扩展:
- 支持鸿蒙PC端适配
- 开发Web版本
- 考虑Flutter跨平台版本
8.3 技术展望
随着鸿蒙生态的不断发展,HarmonyOS NEXT将成为更多开发者的选择。ArkTS语言和ArkUI框架提供了现代化的开发体验,使开发者能够快速构建高质量的应用。
未来,我们将继续关注鸿蒙技术的发展,不断优化应用性能,提升用户体验,为用户提供更好的沟通辅助服务。
九、鸿蒙开发实战技巧
9.1 ArkTS语言高级特性
泛型编程在拒绝话术生成中的应用
泛型是ArkTS中处理类型安全和代码复用的重要工具。在拒绝话术生成应用中,我们可以使用泛型来创建通用的话术生成器:
interface TalkGenerator<T> {
generate(type: string): T;
getTips(type: string): string;
}
class RefusalTalkGenerator implements TalkGenerator<string[]> {
generate(type: string): string[] {
let talks: string[] = [];
if (type === '工作请求') {
talks = [
'谢谢你的信任,不过我目前手头的工作比较多,恐怕无法抽出时间来帮忙。建议你找一下其他同事,他们可能更有时间。',
'很抱歉,我现在的工作安排比较满,暂时无法接手这个任务。如果你有其他需要帮忙的地方,我会尽力配合。',
'感谢你的邀请,不过我目前正在处理一个紧急项目,可能无法参与这个工作。希望你能理解。',
'很遗憾,我目前的工作量已经饱和了,无法再承担新的任务。建议你提前规划,以便更好地分配工作。',
'谢谢你的好意,不过我觉得这个任务更适合由其他同事来完成,他们在这方面更有经验。希望你能找到合适的人选。'
];
} else if (type === '社交邀请') {
talks = [
'谢谢你的邀请,不过我今晚已经有安排了,下次有机会再聚吧!',
'很抱歉,我这段时间比较忙,暂时无法参加。感谢你的邀请,下次再约。',
'感谢你的好意,不过我不太喜欢这种场合,还是算了吧。',
'谢谢你想到我,不过我家里有事,实在无法赴约。希望你们玩得开心!',
'很遗憾,我已经有其他安排了,无法参加这次聚会。改天我请你吃饭吧!'
];
}
return talks;
}
getTips(type: string): string {
let tipsMap: Record<string, string> = {
'工作请求': '工作拒绝要委婉,给出合理理由,避免伤害同事关系',
'社交邀请': '社交拒绝要礼貌,表达感谢,留下下次机会',
'情感表白': '情感拒绝要温柔,保持尊重,明确立场',
'商务合作': '商务拒绝要专业,留有余地,保持合作可能性',
'日常琐事': '日常拒绝要友好,说明原因,避免误会'
};
return tipsMap[type] || '拒绝话术要得体,态度诚恳';
}
}
类型别名与接口的灵活运用
type TalkType = '工作请求' | '社交邀请' | '情感表白' | '商务合作' | '日常琐事';
interface TalkResult {
type: TalkType;
talks: string[];
tips: string;
}
interface TalkTemplate {
id: number;
content: string;
type: TalkType;
scene: string;
}
异步编程模式
private async fetchTalks(type: string): Promise<TalkResult> {
await this.delay(1000);
let generator: RefusalTalkGenerator = new RefusalTalkGenerator();
return {
type: type as TalkType,
talks: generator.generate(type),
tips: generator.getTips(type)
};
}
private delay(ms: number): Promise<void> {
return new Promise<void>((resolve) => {
setTimeout(() => {
resolve();
}, ms);
});
}
9.2 ArkUI组件最佳实践
自定义话术卡片组件
@Component
struct TalkCard {
private content: string;
private onCopy: (text: string) => void;
build() {
Column() {
Text('🙅 ' + this.content)
.fontSize(16)
.fontColor('#333333')
.padding(16)
.width('100%')
.textAlign(TextAlign.Start)
.backgroundColor('#FFFFFF')
.borderRadius(8)
.shadow({ radius: 4, color: '#00000010', offsetY: 2 })
.onClick(() => {
this.onCopy(this.content);
})
}
.width('100%')
.margin({ bottom: 8 })
}
}
组件设计要点:
- 添加表情图标增强情感表达
- 圆角卡片设计,简洁大方
- 点击复制功能,方便使用
自定义类型选择器组件
@Component
struct TypeSelector {
private label: string;
private options: string[];
private selected: string;
private onChange: (v: string) => void;
build() {
Column() {
Text(this.label)
.fontSize(14)
.fontColor('#8E8E93')
.margin({ bottom: 8 })
.width('100%')
Scroll() {
Row() {
ForEach(this.options, (opt: string) => {
Text(opt)
.fontSize(14)
.fontColor(this.selected === opt ? '#FFFFFF' : '#666666')
.backgroundColor(this.selected === opt ? '#FF5722' : '#F5F5F5')
.padding({ left: 14, right: 14, top: 8, bottom: 8 })
.borderRadius(8)
.margin({ right: 8 })
.onClick(() => {
this.onChange(opt);
})
})
}
.padding({ bottom: 4 })
}
.scrollBar(BarState.Off)
.width('100%')
}
.width('100%')
.margin({ bottom: 16 })
}
}
9.3 状态管理进阶
状态联动机制
@Entry
@Component
struct AIRefusalTalkPage {
@State selectedType: string = '工作请求';
@State result: TalkResult | undefined = undefined;
@State isGenerating: boolean = false;
build() {
Column() {
this.Header('拒绝话术生成', '#FF5722')
Scroll() {
Column() {
TypeSelector({
label: '场景类型',
options: this.typeOptions,
selected: this.selectedType,
onChange: (v: string) => {
this.selectedType = v;
this.result = undefined;
}
})
Button(this.isGenerating ? '生成中...' : '生成')
.width('100%').height(48).backgroundColor('#FF5722')
.fontSize(16).fontWeight(FontWeight.Bold).fontColor('#FFFFFF')
.borderRadius(12).margin({ bottom: 16 })
.onClick(() => { this.callLLMApi(); })
if (this.result !== undefined) {
Column() {
ForEach(this.result.talks, (talk: string) => {
TalkCard({
content: talk,
onCopy: (text: string) => {
console.log('复制:', text);
}
})
})
Text('小贴士:' + this.result.tips).fontSize(14).fontColor('#8E8E93')
.padding(12).backgroundColor('#FFECB3').borderRadius(8)
}.width('100%')
}
}
.padding(16)
}
.layoutWeight(1)
.scrollBar(BarState.Off)
}
.width('100%')
.height('100%')
.backgroundColor('#F5F5F5')
}
}
状态持久化方案
class StorageManager {
private static readonly FAVORITE_KEY = 'talk_favorites';
static saveFavorite(talk: string): void {
let favorites: string[] = this.getFavorites();
if (!favorites.includes(talk)) {
favorites.push(talk);
Preferences.put(this.FAVORITE_KEY, JSON.stringify(favorites));
}
}
static getFavorites(): string[] {
let data = Preferences.get(this.FAVORITE_KEY);
if (data !== undefined) {
return JSON.parse(data);
}
return [];
}
static removeFavorite(talk: string): void {
let favorites: string[] = this.getFavorites();
favorites = favorites.filter((t: string) => t !== talk);
Preferences.put(this.FAVORITE_KEY, JSON.stringify(favorites));
}
}
9.4 路由导航优化
参数传递优化
// 跳转时传递参数
router.pushUrl({
url: 'pages/AIRefusalTalk',
params: {
type: '工作请求',
userId: '123'
}
});
// 在目标页面获取参数
class AIRefusalTalkPage {
private type: string = '';
aboutToAppear() {
let params = router.getParams();
if (params !== undefined) {
this.type = params.type as string;
}
}
}
返回值处理
// 目标页面设置返回值
router.back({
url: 'pages/Index',
params: {
result: 'success',
data: '返回的数据'
}
});
9.5 性能调优策略
列表渲染优化
ForEach(this.result.talks, (talk: string) => {
TalkCard({
content: talk,
onCopy: (text: string) => {
console.log('复制:', text);
}
})
}, (talk: string) => talk)
内存管理
aboutToDisappear() {
this.result = undefined;
}
渲染批次优化
Column() {
// 使用renderGroup优化渲染批次
Column() {
// 密集的UI元素
}.renderGroup(true)
}
十、鸿蒙PC端适配方案
10.1 大屏布局适配
响应式网格布局
build() {
Column() {
this.Header('拒绝话术生成', '#FF5722')
Scroll() {
Column() {
// PC端使用Grid布局
if (this.deviceType === 'pc') {
Grid() {
GridItem() {
TypeSelector({
label: '场景类型',
options: this.typeOptions,
selected: this.selectedType,
onChange: (v: string) => {
this.selectedType = v;
this.result = undefined;
}
})
}.columnSpan(2)
GridItem() {
Button(this.isGenerating ? '生成中...' : '生成')
.width('100%').height(48).backgroundColor('#FF5722')
.fontSize(16).fontWeight(FontWeight.Bold).fontColor('#FFFFFF')
.borderRadius(12)
.onClick(() => { this.callLLMApi(); })
}.columnSpan(2)
if (this.result !== undefined) {
ForEach(this.result.talks, (talk: string) => {
GridItem() {
TalkCard({
content: talk,
onCopy: (text: string) => {
console.log('复制:', text);
}
})
}
})
}
}
.columnsTemplate('1fr 1fr')
.columnsGap(16)
.rowsGap(16)
} else {
// 移动端布局
TypeSelector({
label: '场景类型',
options: this.typeOptions,
selected: this.selectedType,
onChange: (v: string) => {
this.selectedType = v;
this.result = undefined;
}
})
Button(this.isGenerating ? '生成中...' : '生成')
.width('100%').height(48).backgroundColor('#FF5722')
.fontSize(16).fontWeight(FontWeight.Bold).fontColor('#FFFFFF')
.borderRadius(12).margin({ bottom: 16 })
.onClick(() => { this.callLLMApi(); })
if (this.result !== undefined) {
Column() {
ForEach(this.result.talks, (talk: string) => {
TalkCard({
content: talk,
onCopy: (text: string) => {
console.log('复制:', text);
}
})
})
}.width('100%')
}
}
}
.padding(16)
}
.layoutWeight(1)
.scrollBar(BarState.Off)
}
.width('100%')
.height('100%')
.backgroundColor('#F5F5F5')
}
10.2 鼠标交互优化
悬停效果实现
@Component
struct HoverButton {
private text: string;
private onClick: () => void;
@State isHover: boolean = false;
build() {
Button(this.text)
.width('100%').height(48)
.backgroundColor(this.isHover ? '#FF7043' : '#FF5722')
.fontSize(16).fontWeight(FontWeight.Bold).fontColor('#FFFFFF')
.borderRadius(12)
.onClick(() => { this.onClick(); })
.onHover((isHover: boolean) => {
this.isHover = isHover;
})
}
}
右键菜单支持
Column() {
Text('🙅 ' + talk)
.fontSize(16).fontColor('#333333')
.padding(16).backgroundColor('#FFFFFF').borderRadius(8)
.onContextMenu((event: ContextMenuInfo) => {
// 显示右键菜单
console.log('右键点击:', event);
})
}
10.3 键盘快捷键支持
快捷键配置
@Component
struct AIRefusalTalkPage {
aboutToAppear() {
// 注册快捷键
KeyEventManager.registerKeyEvent((event: KeyEvent) => {
if (event.keyCode === 13 && event.type === KeyType.Down) {
// Enter键生成
this.callLLMApi();
}
});
}
aboutToDisappear() {
// 注销快捷键
KeyEventManager.unregisterKeyEvent();
}
}
10.4 多窗口模式适配
窗口状态管理
@Watch('onWindowSizeChange')
@State windowSize: { width: number, height: number } = { width: 0, height: 0 };
private onWindowSizeChange(): void {
if (this.windowSize.width > 1200) {
this.deviceType = 'pc';
} else if (this.windowSize.width > 600) {
this.deviceType = 'tablet';
} else {
this.deviceType = 'phone';
}
}
10.5 性能监控与优化
性能监控方案
class PerformanceMonitor {
private static startTime: number = 0;
static start(): void {
this.startTime = Date.now();
}
static end(tag: string): void {
let duration = Date.now() - this.startTime;
console.log(`[性能监控] ${tag}: ${duration}ms`);
}
}
// 使用示例
PerformanceMonitor.start();
this.result = this.generateMock();
PerformanceMonitor.end('数据生成');
十一、与Flutter框架深度对比
11.1 组件体系对比
ArkUI组件体系
@Entry
@Component
struct AIRefusalTalkPage {
@State selectedType: string = '工作请求';
build() {
Column() {
Text('拒绝话术生成').fontSize(20).fontWeight(FontWeight.Bold)
Scroll() {
Column() {
// 内容组件
}
}.layoutWeight(1)
}.width('100%').height('100%')
}
}
Flutter组件体系
class AIRefusalTalkPage extends StatelessWidget {
final String selectedType;
const AIRefusalTalkPage({super.key, required this.selectedType});
Widget build(BuildContext context) {
return Column(
children: [
Text('拒绝话术生成', style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold)),
Expanded(
child: SingleChildScrollView(
child: Column(
children: [/* 内容组件 */],
),
),
),
],
);
}
}
11.2 开发效率对比
代码量分析
| 功能模块 | ArkTS代码行数 | Flutter代码行数 | 差异 |
|---|---|---|---|
| 页面结构 | 20 | 25 | -20% |
| 状态管理 | 5 | 15 | -67% |
| 组件定义 | 15 | 20 | -25% |
| 布局实现 | 10 | 15 | -33% |
| 总计 | 50 | 75 | -33% |
开发效率评估:
- ArkTS声明式语法更简洁,代码量减少约33%
- ArkUI内置状态管理装饰器,无需额外引入状态管理库
- DevEco Studio提供完善的鸿蒙开发支持
11.3 性能表现对比
启动时间对比
| 平台 | ArkTS(鸿蒙) | Flutter |
|---|---|---|
| 冷启动 | <500ms | 1500-2000ms |
| 热启动 | <200ms | 500-800ms |
帧率对比
| 场景 | ArkTS(鸿蒙) | Flutter |
|---|---|---|
| 静态页面 | 60fps | 60fps |
| 列表滚动 | 60fps | 55-60fps |
| 动画效果 | 60fps | 50-60fps |
内存占用对比
| 场景 | ArkTS(鸿蒙) | Flutter |
|---|---|---|
| 启动后 | ~30MB | ~80MB |
| 列表渲染 | ~40MB | ~100MB |
11.4 生态系统对比
鸿蒙生态
- 官方组件库:丰富的基础组件和扩展组件
- 开发工具:DevEco Studio集成开发环境
- 社区支持:华为官方文档和开发者社区
- 第三方库:快速增长的ohpm生态
Flutter生态
- 官方组件库:Material和Cupertino组件库
- 开发工具:Android Studio、VS Code插件
- 社区支持:庞大的GitHub社区和Stack Overflow
- 第三方库:pub.dev上超过20000个包
11.5 适用场景分析
选择鸿蒙ArkTS的场景:
- 需要深度集成鸿蒙系统能力
- 面向华为设备用户
- 需要多设备协同能力
- 追求极致性能和系统级体验
选择Flutter的场景:
- 需要跨平台开发(iOS/Android/Web/桌面)
- 已有Flutter开发团队
- 需要丰富的第三方插件生态
- 追求快速开发和迭代
十二、代码优化与重构
12.1 代码质量提升
代码规范
// 变量命名规范
@State selectedType: string = '工作请求'; // camelCase
@State isGenerating: boolean = false; // 布尔类型前缀is
// 常量定义
const MAX_TALK_COUNT: number = 5;
const DEFAULT_TYPE: string = '工作请求';
// 接口命名
interface TalkResult { // PascalCase
type: string;
talks: string[];
tips: string;
}
代码组织优化
// 将Mock数据提取到单独模块
module MockData {
export function generateWorkRequestTalks(): string[] {
return [
'谢谢你的信任,不过我目前手头的工作比较多...',
// ...
];
}
export function generateSocialInvitationTalks(): string[] {
return [
'谢谢你的邀请,不过我今晚已经有安排了...',
// ...
];
}
}
12.2 设计模式应用
策略模式
interface RefusalStrategy {
generate(): string[];
getTips(): string;
}
class WorkRequestStrategy implements RefusalStrategy {
generate(): string[] {
return [
'谢谢你的信任,不过我目前手头的工作比较多...',
// ...
];
}
getTips(): string {
return '工作拒绝要委婉,给出合理理由';
}
}
class SocialInvitationStrategy implements RefusalStrategy {
generate(): string[] {
return [
'谢谢你的邀请,不过我今晚已经有安排了...',
// ...
];
}
getTips(): string {
return '社交拒绝要礼貌,表达感谢';
}
}
class StrategyContext {
private strategy: RefusalStrategy;
constructor(strategy: RefusalStrategy) {
this.strategy = strategy;
}
setStrategy(strategy: RefusalStrategy): void {
this.strategy = strategy;
}
execute(): TalkResult {
return {
type: '',
talks: this.strategy.generate(),
tips: this.strategy.getTips()
};
}
}
观察者模式
interface Observer {
update(data: TalkResult): void;
}
class TalkGenerator {
private observers: Observer[] = [];
addObserver(observer: Observer): void {
this.observers.push(observer);
}
removeObserver(observer: Observer): void {
this.observers = this.observers.filter((o: Observer) => o !== observer);
}
notify(data: TalkResult): void {
for (let observer of this.observers) {
observer.update(data);
}
}
generate(type: string): void {
let result: TalkResult = {
type: type,
talks: [],
tips: ''
};
this.notify(result);
}
}
12.3 单元测试方案
核心逻辑测试
// 测试Mock数据生成
test('testGenerateMock', () => {
let page = new AIRefusalTalkPage();
page.selectedType = '工作请求';
let result = page.generateMock();
expect(result.type).toBe('工作请求');
expect(result.talks.length).toBeGreaterThan(0);
expect(result.tips.length).toBeGreaterThan(0);
page.selectedType = '社交邀请';
result = page.generateMock();
expect(result.type).toBe('社交邀请');
});
// 测试空状态处理
test('testEmptyState', () => {
let page = new AIRefusalTalkPage();
expect(page.result).toBeUndefined();
page.callLLMApi();
expect(page.isGenerating).toBe(true);
});
12.4 集成测试策略
组件交互测试
// 测试选择器组件
test('testSelectorInteraction', () => {
let page = new AIRefusalTalkPage();
page.selectedType = '工作请求';
expect(page.selectedType).toBe('工作请求');
// 模拟用户选择
page.onTypeChange('社交邀请');
expect(page.selectedType).toBe('社交邀请');
});
// 测试生成流程
test('testGenerateFlow', () => {
let page = new AIRefusalTalkPage();
page.callLLMApi();
expect(page.isGenerating).toBe(true);
// 等待异步完成
setTimeout(() => {
expect(page.isGenerating).toBe(false);
expect(page.result).not.toBeUndefined();
}, 1100);
});
12.5 持续集成方案
CI/CD配置
# .github/workflows/ci.yml
name: CI
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Node.js
uses: actions/setup-node@v3
with:
node-version: 18
- name: Install dependencies
run: npm install
- name: Build project
run: npm run build
- name: Run tests
run: npm test
- name: Upload artifact
uses: actions/upload-artifact@v3
with:
name: app-package
path: build/outputs/
十三、部署与发布
13.1 构建流程优化
构建配置
// hvigorfile.ts
export default {
build: {
options: {
target: 'harmonyos',
apiVersion: 24,
product: 'default',
},
tasks: {
assembleHap: {
dependsOn: ['compileDebug', 'packageDebug']
}
}
}
}
构建命令
# 构建调试版本
./hvigorw assembleHapDebug
# 构建发布版本
./hvigorw assembleHapRelease
# 构建多设备版本
./hvigorw assembleHap --mode all
13.2 版本管理策略
语义化版本控制
// package.json
{
"version": "1.0.0",
"description": "拒绝话术生成应用",
"scripts": {
"version:patch": "npm version patch",
"version:minor": "npm version minor",
"version:major": "npm version major"
}
}
版本变更记录
# CHANGELOG
## 1.0.0 (2024-01-15)
### 新增
- 初始版本发布
- 支持五种场景的拒绝话术生成
- 提供沟通小贴士功能
## 1.1.0 (2024-02-01)
### 新增
- 添加话术收藏功能
- 支持话术复制功能
### 优化
- 提升UI响应速度
- 修复已知bug
13.3 应用签名配置
签名文件生成
# 生成签名文件
keytool -genkey -alias mykey -keyalg RSA -keysize 2048 -validity 3650 -keystore mykey.keystore
签名配置
{
"signingConfigs": {
"release": {
"keyAlias": "mykey",
"keyPassword": "password",
"storeFile": "mykey.keystore",
"storePassword": "password"
}
}
}
13.4 分发渠道选择
华为应用市场
- 官方分发渠道
- 覆盖华为设备用户
- 提供应用统计和分析
企业分发
- 适用于企业内部应用
- 通过华为企业服务分发
- 支持私有化部署
第三方分发
- AppGallery Connect
- 支持多渠道分发
- 提供分发统计
13.5 数据统计与分析
用户行为统计
class AnalyticsManager {
static logEvent(eventName: string, params?: Record<string, string>): void {
console.log(`[Analytics] ${eventName}:`, params);
// 实际项目中接入华为分析服务
// AnalyticsService.onEvent(eventName, params);
}
static logPageView(pageName: string): void {
this.logEvent('page_view', { page_name: pageName });
}
static logAction(action: string, target: string): void {
this.logEvent('action', { action: action, target: target });
}
}
// 使用示例
AnalyticsManager.logPageView('拒绝话术生成');
AnalyticsManager.logAction('generate', '工作请求');
性能监控
class PerformanceTracker {
static trackStart(pageName: string): void {
console.log(`[Performance] Start: ${pageName}`);
}
static trackEnd(pageName: string): void {
console.log(`[Performance] End: ${pageName}`);
}
static trackAction(action: string, duration: number): void {
console.log(`[Performance] Action: ${action}, Duration: ${duration}ms`);
}
}
更多推荐




所有评论(0)