锻造步骤怎么管理?HarmonyOS preferences存储制作步骤
如果你对金属锻造感兴趣,可以去鸿蒙应用市场搜一下**「锻艺册」**,下载下来体验体验。从退火到抛光,每个锻造步骤都有详细的温度、时间和技巧说明。体验完了再回来看这篇文章,你会更清楚这些步骤数据是怎么存储和管理的。
写在前面
大家好,我是一名写了十多年Web前端的老兵。从jQuery时代一路走到React/Vue,CSS3动画、requestAnimationFrame、Web Animation API这些都算是看家本领。去年开始转战鸿蒙生态,用ArkTS开发App,这一路踩了不少坑,也积累了不少心得。
很多人觉得"前端转鸿蒙"应该很容易——都是写UI嘛,组件化、状态管理、生命周期,概念都差不多。但真正上手之后你会发现,相似的地方让你觉得亲切,不同的地方让你抓狂。
比如:
- 步骤序列化:锻造步骤有固定的顺序,需要正确管理步骤的先后关系。
- 状态追踪:每个步骤有自己的状态(未开始、进行中、已完成),需要正确更新。
别担心,接下来这篇文章,我会用"锻艺册"的步骤管理功能,带你看看怎么在HarmonyOS里管理锻造步骤数据。
这篇文章聊什么
锻艺册的步骤管理功能,核心要解决:
- 步骤定义:每个锻造步骤的详细信息
- 步骤排序:正确的制作顺序
- 状态追踪:记录每个步骤的完成状态
- 进度显示:显示整体完成进度
第一步:设计步骤数据结构
// 锻造步骤
interface ForgingStep {
id: string;
name: string;
description: string;
temperature: string; // 温度要求
duration: string; // 时间要求
tip: string; // 技巧提示
status: 'pending' | 'in_progress' | 'completed';
completedAt: string; // 完成时间
}
// 项目中的步骤记录
interface ProjectStep {
stepId: string;
status: 'pending' | 'in_progress' | 'completed';
startedAt: string;
completedAt: string;
notes: string;
}
// 锻造项目
interface ForgingProject {
id: string;
name: string;
category: string; // 项目分类
metalType: string; // 金属类型
steps: ProjectStep[]; // 步骤记录
status: string;
notes: string;
createdAt: string;
}
// 锻造步骤定义
const FORGING_STEPS = [
{ id: 'annealing', name: '退火', description: '加热金属使其软化便于加工', temperature: '600-700°C', duration: '2-5分钟', tip: '观察金属颜色变为暗红即可' },
{ id: 'pickling', name: '酸洗', description: '去除退火产生的氧化层', temperature: '常温', duration: '1-3分钟', tip: '使用稀硫酸溶液,注意安全' },
{ id: 'forming', name: '成型', description: '锤打、弯曲塑造基本形状', temperature: '常温', duration: '视作品而定', tip: '力度均匀,逐步成型' },
{ id: 'soldering', name: '焊接', description: '用焊料连接金属部件', temperature: '600-800°C', duration: '10-30秒', tip: '焊药要均匀涂抹' },
{ id: 'filing', name: '锉修', description: '锉平焊接点和不平整处', temperature: '常温', duration: '10-30分钟', tip: '从粗锉到细锉逐步进行' },
{ id: 'sanding', name: '打磨', description: '砂纸打磨表面至光滑', temperature: '常温', duration: '15-45分钟', tip: '逐级提高砂纸目数' },
{ id: 'polishing', name: '抛光', description: '抛光至镜面或哑光效果', temperature: '常温', duration: '10-30分钟', tip: '根据需要选择抛光膏' },
{ id: 'texturing', name: '做纹理', description: '锤纹、拉丝、喷砂等表面处理', temperature: '常温', duration: '5-20分钟', tip: '先在废料上试验效果' },
{ id: 'setting', name: '镶嵌', description: '将宝石固定在金属座上', temperature: '常温', duration: '20-60分钟', tip: '爪镶、包镶、钉镶等技法' },
{ id: 'finishing', name: '收尾', description: '最终检查与调整', temperature: '常温', duration: '5-15分钟', tip: '检查每个连接点是否牢固' },
];
第二步:实现步骤管理功能
import { preferences } from '@kit.ArkData';
let prefInstance: preferences.Preferences | null = null;
async function getPreferences(context: Context): Promise<preferences.Preferences> {
if (!prefInstance) {
prefInstance = await preferences.getPreferences(context, 'duanyice_data');
}
return prefInstance;
}
async function setItem(context: Context, key: string, value: unknown): Promise<boolean> {
try {
const pref = await getPreferences(context);
await pref.put(key, JSON.stringify(value));
await pref.flush();
return true;
} catch (err) {
console.error('存储失败:', err);
return false;
}
}
async function getItem<T>(context: Context, key: string, defaultValue: T): Promise<T> {
try {
const pref = await getPreferences(context);
const value = await pref.get(key, '');
if (typeof value === 'string' && value.length > 0) {
return JSON.parse(value) as T;
}
return defaultValue;
} catch (err) {
console.error('读取失败:', err);
return defaultValue;
}
}
// 添加项目
async function addProject(context: Context, project: ForgingProject): Promise<boolean> {
const projects = await getItem<ForgingProject[]>(context, 'projects', []);
const newProject: ForgingProject = {
...project,
id: `project_${Date.now()}`,
createdAt: new Date().toISOString().slice(0, 10)
};
projects.push(newProject);
return await setItem(context, 'projects', projects);
}
// 更新步骤状态
async function updateStepStatus(
context: Context,
projectId: string,
stepId: string,
status: 'pending' | 'in_progress' | 'completed',
notes: string = ''
): Promise<boolean> {
const projects = await getItem<ForgingProject[]>(context, 'projects', []);
const projectIndex = projects.findIndex(p => p.id === projectId);
if (projectIndex === -1) return false;
const project = projects[projectIndex];
const stepIndex = project.steps.findIndex(s => s.stepId === stepId);
if (stepIndex > -1) {
// 更新现有步骤
project.steps[stepIndex].status = status;
project.steps[stepIndex].notes = notes;
if (status === 'completed') {
project.steps[stepIndex].completedAt = new Date().toISOString().slice(0, 10);
}
} else {
// 添加新步骤
project.steps.push({
stepId,
status,
startedAt: status === 'in_progress' ? new Date().toISOString().slice(0, 10) : '',
completedAt: status === 'completed' ? new Date().toISOString().slice(0, 10) : '',
notes
});
}
// 更新项目状态
const completedCount = project.steps.filter(s => s.status === 'completed').length;
const totalSteps = FORGING_STEPS.length;
if (completedCount === totalSteps) {
project.status = 'completed';
} else if (completedCount > 0) {
project.status = 'in_progress';
}
return await setItem(context, 'projects', projects);
}
// 计算进度
function calculateProgress(project: ForgingProject): number {
if (project.steps.length === 0) return 0;
const completed = project.steps.filter(s => s.status === 'completed').length;
return Math.round((completed / FORGING_STEPS.length) * 100);
}
第三步:实现步骤列表页面
@Entry
@Component
struct StepListPage {
@State project: ForgingProject | null = null
async aboutToAppear() {
const projects = await getProjects(getContext(this) as Context);
this.project = projects[0]; // 示例:显示第一个项目
}
private getStepStatus(stepId: string): ProjectStep | null {
return this.project?.steps.find(s => s.stepId === stepId) || null;
}
private getStepColor(stepId: string): string {
const status = this.getStepStatus(stepId);
if (!status) return '#e5e7eb';
if (status.status === 'completed') return '#22c55e';
if (status.status === 'in_progress') return '#f97316';
return '#e5e7eb';
}
build() {
Column() {
if (this.project) {
Text(this.project.name)
.fontSize(24)
.fontWeight(FontWeight.Bold)
.margin({ bottom: 8)
Text(`进度: ${calculateProgress(this.project)}%`)
.fontSize(14)
.fontColor('#6b7280')
.margin({ bottom: 16)
// 进度条
Stack({ alignContent: Alignment.Start }) {
Row()
.width('100%')
.height(8)
.backgroundColor('#e5e7eb')
.borderRadius(4)
Row()
.width(`${calculateProgress(this.project)}%`)
.height(8)
.backgroundColor('#22c55e')
.borderRadius(4)
}
.width('100%')
.margin({ bottom: 20 })
// 步骤列表
ForEach(FORGING_STEPS, (step, index) => {
Row() {
// 步骤图标
Circle({ width: 32, height: 32 })
.fill(this.getStepColor(step.id))
.overlay(
Text(this.getStepStatus(step.id)?.status === 'completed' ? '✓' : `${index + 1}`)
.fontSize(14)
.fontColor('#ffffff')
)
// 步骤信息
Column() {
Text(step.name)
.fontSize(16)
.fontWeight(FontWeight.Medium)
Text(step.description)
.fontSize(12)
.fontColor('#9ca3af')
Row() {
Text(step.temperature)
.fontSize(10)
.fontColor('#f97316')
.padding({ left: 4, right: 4, top: 2, bottom: 2 })
.backgroundColor('#fff7ed')
.borderRadius(4)
Text(step.duration)
.fontSize(10)
.fontColor('#3b82f6')
.padding({ left: 4, right: 4, top: 2, bottom: 2 })
.backgroundColor('#eff6ff')
.borderRadius(4)
.margin({ left: 4 })
}
.margin({ top: 4 })
}
.layoutWeight(1)
.margin({ left: 12 })
.alignItems(HorizontalAlign.Start)
// 操作按钮
if (this.getStepStatus(step.id)?.status !== 'completed') {
Button(this.getStepStatus(step.id)?.status === 'in_progress' ? '完成' : '开始')
.fontSize(12)
.height(32)
.backgroundColor(this.getStepStatus(step.id)?.status === 'in_progress' ? '#22c55e' : '#f97316')
.borderRadius(8)
.onClick(async () => {
const newStatus = this.getStepStatus(step.id)?.status === 'in_progress' ? 'completed' : 'in_progress';
await updateStepStatus(
getContext(this) as Context,
this.project!.id,
step.id,
newStatus
);
// 刷新数据
const projects = await getProjects(getContext(this) as Context);
this.project = projects.find(p => p.id === this.project?.id) || null;
})
}
}
.width('100%')
.padding(12)
.backgroundColor('#ffffff')
.borderRadius(12)
.margin({ bottom: 8 })
})
}
}
.padding(16)
}
}
第四步:常见问题
4.1 步骤顺序管理
问题:用户可能跳过某些步骤。
解决:提示用户按顺序完成,或者允许跳过但标记警告。
4.2 步骤时间记录
问题:需要记录每个步骤的实际耗时。
解决:在步骤开始时记录时间戳,完成时计算差值。
总结
这篇文章围绕"锻艺册"的步骤管理功能,讲解了:
步骤数据管理
- 步骤定义和状态追踪
- 进度计算和显示
- 状态流转管理
UI设计
- 步骤列表和状态图标
- 进度条可视化
- 操作按钮
如果你对"锻艺册"感兴趣,欢迎去鸿蒙应用市场搜索下载体验。