【鸿蒙】鸿蒙App应用-《记账软件》开发步骤

1. 介绍

《记账软件》是日常生活中每天都要使用的软件,通过软件来统计和规划每天的收入和支出情况,并根据日,周,月,年的数据进行生成图表,折线图,柱状图等等,并对消费情况进行分析给出合理的规划策略。

实现思路:

  1. 创建Java语言的项目,完成欢迎引导页滑动页面
  2. 创建登录页面,注册页面,找回密码页面
  3. 创建主界面,包含明细,图表,记账,发现,我的五大模块
  4. 明细模块:展示每天的收入支出情况,并可以根据月份统计本月,本日的收入支出的总和等功能
  5. 图表模块:根据收入支出情况生成日,周,月,年的折线图,饼状图,折线图等等,并对各种支出情况分类显示支出金额
  6. 记账模块:对消费的情况按不同分类进行记账,例如水果,公交,餐饮,工资等等
  7. 发现模块:这里接入web端的网站展示在移动端中
  8. 我的模块:对用户个人信息的设置和显示,头像,VIP设置,主题设置,提醒等等功能

2. 搭建HarmonyOS环境

我们首先需要完成HarmonyOS开发环境搭建,可参照如下步骤进行。

  • 安装DevEco Studio,详情请参考下载和安装软件
  • 设置DevEco Studio开发环境,DevEco Studio开发环境依赖于网络环境,需要连接上网络才能确保工具的正常使用,可以根据如下两种情况来配置开发环境:
    1. 如果可以直接访问Internet,只需进行下载HarmonyOS SDK操作。
    2. 如果网络不能直接访问Internet,需要通过代理服务器才可以访问,请参考配置开发环境

3. 搭建项目开发架构

在鸿蒙系统项目中,一个项目只会存在一个Application类作为管理整个软件的应用程序。因此我们使用该类进行管理所打开的所有Ability页面,在开启一个新的页面,或者关闭一个页面的同时,我们更好的对页面的状态以及生命周期进行监听。代码如下:

package com.example.bookkeepproject;

import ohos.aafwk.ability.Ability;
import ohos.aafwk.ability.AbilityPackage;

import java.util.ArrayList;
import java.util.List;

/**
 * 主应用程序类,一个应用只有一个应用程序类
 */
public class MyApplication extends AbilityPackage {
    private static List<Ability> abilities;
    @Override
    public void onInitialize() {
        super.onInitialize();
        abilities=new ArrayList<>();
    }

    /**
     * 将开启的界面添加至界面集合
     * @param ability
     */
    public void addAbility(Ability ability) {
        if (!abilities.contains(ability)) {
            abilities.add(ability);
        }
    }

    /**
     * 销毁所有的界面对象
     */
    public  void removeAllAbility() {
        for (Ability activity : abilities) {
            activity.terminateAbility();
        }
    }
}

在应用程序类中,定义一个ability集合,创建两个方法,用于监听新的ability界面的开启和关闭。

4.创建Ability类的基类

为了更好的统一管理所有的ability,我们建立BaseAbility(基类)继承至Ability类,那么我们所有的Ability都继承至我们自己的基类,在基类中可以定义封装常用的方法,方便调用,减少耦合度,避免代码冗余。代码如下:

package com.example.bookkeepproject;

import ohos.aafwk.ability.Ability;
import ohos.aafwk.content.Intent;

/**
 * 界面基类
 */
public class BaseAbility extends Ability {
    MyApplication application;
    BaseAbility context;
    @Override
    protected void onStart(Intent intent) {
        super.onStart(intent);
        // 单例模式
        if (application == null) {
            application = (MyApplication) getAbilityPackage();
        }
        context = this;
        addAbility();
    }

    @Override
    protected void onStop() {
        super.onStop();
    }

    public void addAbility() {
        application.addAbility(context);
    }

    public void removeAllActivity() {
        application.removeAllAbility();
    }
}

并改变MainAbility类继承至BaseAbility类,完成统一所有Ability的管理,统一监听其生命周期过程。

5.创建AbilitySlice基类

在鸿蒙的学习中,大家知道一个Ability可以管理包含多个AbilitySlice类,这里为了能更好的管理多个AbilitySlice类,我们也建立AbilitySlice的基类。

package com.example.bookkeepproject.slice;

import com.example.bookkeepproject.MainAbility;
import com.example.bookkeepproject.utils.MyHelper;
import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.content.Intent;
import ohos.agp.window.dialog.ToastDialog;
import ohos.data.rdb.RdbStore;

import java.text.SimpleDateFormat;
import java.util.Calendar;

/**
 * 子界面的基类
 */
public class BaseAbilitySlice extends AbilitySlice {
    MainAbility ability;
    BaseAbilitySlice context;
    RdbStore rs;
//    Preferences preferences;
    public Calendar calendar = null;
    public int year=Calendar.getInstance().get(Calendar.YEAR);
    public int month=Calendar.getInstance().get(Calendar.MONTH)+1;
    public int day=Calendar.getInstance().get(Calendar.DAY_OF_MONTH);
    public String[] months = { "1月", "2月", "3月", "4月", "5月", "6月", "7月", "8月",
            "9月", "10月", "11月", "12月" };

    public String[] types={"支出","收入","转账","余额"};
    @Override
    protected void onStart(Intent intent) {
        super.onStart(intent);
        // 单例模式
        if (ability == null) {
            ability = (MainAbility) getAbility();
        }
        context = this;
//        addAbilitySlice();

        if (calendar == null) {
            calendar = Calendar.getInstance();
        }

        if (rs==null)
            rs= MyHelper.getInstance(getContext(),"BookKeep");
//        if (preferences==null)
//            preferences= MyHelper.getInstance("BKInfo",getContext());
//
//        // 向preferences实例注册观察者
//        PreferencesObserverImpl observer = new PreferencesObserverImpl();
//        preferences.registerObserver(observer);
    }

//    private class PreferencesObserverImpl implements Preferences.PreferencesObserver {
//
//        @Override
//        public void onChange(Preferences preferences, String key) {
//            if ("intKey".equals(key)) {
//                showToastDialogShort("添加了key重复了");
//            }
//        }
//    }

    /**
     * 获得实时的年月日时分秒
     * @return
     */
    public static String getDate() {
        Calendar ca = Calendar.getInstance();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd hh:mm:ss");
        String date = sdf.format(ca.getTimeInMillis());
        return date;
    }

    /**
     * 获得实时的年月日
     * @return
     */
    public static String getDate1() {
        Calendar ca = Calendar.getInstance();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String date = sdf.format(ca.getTimeInMillis());
        return date;
    }

    public void addAbilitySlice() {
        ability.addAbilitySlice(context);
    }

    public void removeAllAbilitySlice() {
        ability.removeAllActivity();
    }

    @Override
    protected void onStop() {
        super.onStop();
    }

    public String getWeek() {
        String info = null;
        int month = calendar.get(Calendar.MONTH) + 1;
        int day = calendar.get(Calendar.DAY_OF_MONTH);
        int count = calendar.get(Calendar.DAY_OF_WEEK) - 1;
        if (count > 0) {
            info = month + "_" + (day - count + 1) + "_" + month + "_"
                    + (day + 7 - count);
        }
        return info;
    }

    public String getmonth() {
        String info = null;

        int month = calendar.get(Calendar.MONTH) + 1;
        // 计算是当月的第几天
        int dayOfMonth = calendar.get(Calendar.DAY_OF_MONTH);
        System.out.printf("输入的日期是当月的第%d天\n ", dayOfMonth);
        // 计算当月的第一天
        calendar.add(Calendar.DATE, 1 - dayOfMonth);
        // 计算下月的第一天
        calendar.add(Calendar.MONTH, 1);
        // 计算当月的最后一天
        calendar.add(Calendar.DATE, -1);
        // 计算是当月一共几天
        dayOfMonth = calendar.get(Calendar.DAY_OF_MONTH);
        System.out.printf("当月一共%d天\n ", dayOfMonth);

        info = month + "月" + 1 + "日--" + month + "月" + dayOfMonth + "日";

        return info;
    }

    public String getyear() {
        String info = null;

        int month = calendar.get(Calendar.MONTH) + 1;
        // 计算是当月的第几天
        int dayOfMonth = calendar.get(Calendar.DAY_OF_MONTH);
        System.out.printf("输入的日期是当月的第%d天\n ", dayOfMonth);
        // 计算当月的第一天
        calendar.add(Calendar.DATE, 1 - dayOfMonth);
        // 计算下月的第一天
        calendar.add(Calendar.MONTH, 1);
        // 计算当月的最后一天
        calendar.add(Calendar.DATE, -1);
        // 计算是当月一共几天
        dayOfMonth = calendar.get(Calendar.DAY_OF_MONTH);
        System.out.printf("当月一共%d天\n ", dayOfMonth);

        info = "1月1日--" + month + "月" + dayOfMonth + "日";

        return info;
    }

    /**
     * 查看当前月份
     * @param month
     * @return
     */
    public int select_month(int month) {

        return (month == 13) ? 1 : (month);
    }

    /**
     * 查看当前天数
     * @param month
     * @param day
     * @return
     */
    public String select_day(int month, int day) {
        if (day >= 32) {
            int months = select_month(month + 1);
            return months + "-" + (day % 31);
        } else {
            return month + "-" + day;
        }
    }

    public void showToastDialogShort(String info){
        new ToastDialog(context).setText(info).setDuration(1000).show();
    }

    public void showToastDialogLong(String info){
        new ToastDialog(context).setText(info).setDuration(2000).show();
    }
}

在基类中,定义了提示对话框的工具方法,根据不同条件获得日,周,月的时间,以及实时获得当天时间的方法,这些方法可以供所有继承至该AbilitySlice基类的AbilitySlice类使用,这里不过多的叙述,学过java的同学应该都清楚,子类继承父类,子类可以直接调用父类的方法。

6.创建欢迎引导页

在任何一款成熟的软件都具备引导页,这里我们也不例外,我们完成四页的引导,在第四个引导页之后,进行跳入应用。代码如下:

package com.example.bookkeepproject.slice;

import com.example.bookkeepproject.ResourceTable;
import com.example.bookkeepproject.adapter.LoadingPageAdapter;
import ohos.aafwk.content.Intent;
import ohos.agp.components.Component;
import ohos.agp.components.PageSlider;

/**
 * 引导页
 */
public class LoadingAbilitySlice extends BaseAbilitySlice {
    private PageSlider page;
    private LoadingPageAdapter adapter;
    private int[] images = {ResourceTable.Media_load_1, ResourceTable.Media_load_2, ResourceTable.Media_load_3, ResourceTable.Media_load_4};

    @Override
    protected void onStart(Intent intent) {
        super.onStart(intent);
        this.setUIContent(ResourceTable.Layout_ability_loading);

        page = (PageSlider) this.findComponentById(ResourceTable.Id_page);
        adapter = new LoadingPageAdapter(images, this);
        page.setProvider(adapter);

        page.addPageChangedListener(listener);
    }

    private PageSlider.PageChangedListener listener = new PageSlider.PageChangedListener() {
        @Override
        public void onPageSliding(int i, float v, int i1) {

        }

        @Override
        public void onPageSlideStateChanged(int i) {

        }

        @Override
        public void onPageChosen(int i) {
            if (i == images.length - 1) {
                page.setClickedListener(clickedListener);
            }
        }
    };

    private Component.ClickedListener clickedListener=new Component.ClickedListener() {
        @Override
        public void onClick(Component component) {
            present(new LoginAbilitySlice(), new Intent());
            terminate();
        }
    };
}

对应的布局文件代码如下:

<?xml version="1.0" encoding="utf-8"?>
<DirectionalLayout
    xmlns:ohos="http://schemas.huawei.com/res/ohos"
    ohos:height="match_parent"
    ohos:width="match_parent"
    ohos:orientation="vertical">

    <PageSlider
        ohos:id="$+id:page"
        ohos:height="match_parent"
        ohos:width="match_parent"/>

</DirectionalLayout>

7.创建滑动加载适配器

 创建一个adapter包,在包中新建一个LoadingPageAdapter类继承至PageSliderProvider类,并实现未实现的方法,加载图片和动态的创建子布局

package com.example.bookkeepproject.adapter;

import ohos.aafwk.ability.AbilitySlice;
import ohos.agp.components.Component;
import ohos.agp.components.ComponentContainer;
import ohos.agp.components.Image;
import ohos.agp.components.PageSliderProvider;

public class LoadingPageAdapter extends PageSliderProvider {
    private int[] images;
    private AbilitySlice context;

    public LoadingPageAdapter(int[] images, AbilitySlice context) {
        this.images = images;
        this.context = context;
    }

    @Override
    public int getCount() {
        return images.length;
    }

    @Override
    public Object createPageInContainer(ComponentContainer componentContainer, int i) {
        Image image=new Image(context);
        image.setScaleMode(Image.ScaleMode.STRETCH);
        ComponentContainer.LayoutConfig config=new ComponentContainer
                .LayoutConfig(ComponentContainer.LayoutConfig.MATCH_PARENT,
                ComponentContainer.LayoutConfig.MATCH_PARENT);
        image.setLayoutConfig(config);
        image.setPixelMap(images[i]);
        componentContainer.addComponent(image);
        return image;
    }

    @Override
    public void destroyPageFromContainer(ComponentContainer componentContainer, int i, Object o) {
        //滑出屏幕的组件进行移除
        componentContainer.removeComponent((Component) o);
    }

    @Override
    public boolean isPageMatchToObject(Component component, Object o) {
        //判断滑页上的每一页的组件和内容是否保持一致
        return true;
    }
}

8.引导页效果展示

 8.总结

一个项目的开发,开发过程中搭建框架是非常重要的,框架搭建的越好,后期的功能开发越来越轻松。

【鸿蒙】鸿蒙App应用-《记账软件》登录,注册,找回密码功能

【鸿蒙】鸿蒙App应用-《记账软件》明细模块

【鸿蒙】鸿蒙App应用-《记账软件》图表模块

【鸿蒙】鸿蒙App应用-《记账软件》记账模块

【鸿蒙】鸿蒙App应用-《记账软件》发现模块

【鸿蒙】鸿蒙App应用-《记账软件》我的模块

<think>好的,我现在需要回答用户关于如何使用DeepSeekLangChain构建聊天机器人的问题。首先,我需要理解用户的需求,他们可能希望了解两者的集成方法和步骤。接下来,我得回顾已有的引用内容,特别是引用[1]和引用[2],看看里面有哪些关键信息可以利用。 引用[1]提到使用DeepSeek构建智能聊天机器人的过程,包括环境准备、代码实现、优化和扩展。而引用[2]则具体说明了如何将DeepSeekLangchain结合,例如安装依赖包、设置环境变量以及使用管道符连接组件。这应该是用户需要的核心内容。 接下来,我需要将这些信息结构化,分步骤说明如何集成两者。首先,环境准备部分需要安装必要的库,如langchain-deepseeklangchain_community,还有管理环境变量的python-dotenv。然后,设置API密钥,这在.env文件中完成。接下来是代码实现的步骤,可能需要导入相关模块,加载环境变量,初始化DeepSeek的模型,并创建处理链,比如使用prompt、model、parser的管道结构。 另外,用户可能关心代码示例,所以需要提供一个简单的示例代码,展示如何将DeepSeek模型集成到LangChain的链中。同时,还需要说明可能的优化方法,比如调整温度参数、使用不同的提示模板,或者结合其他LangChain组件如记忆模块或检索器。 需要注意的是,引用中提到的chain = prompt | model | parser的结构类似于Linux管道符,这个类比可以帮助用户理解数据流动的方式。在解释过程中,要确保术语准确,比如正确使用LangChain中的概念,如LLMChain、PromptTemplate等。 此外,用户可能还希望了解实际应用场景,比如在客服系统中使用,或者结合知识库增强回答能力。这些可以作为扩展应用场景的部分,帮助用户更好地理解集成的优势。 最后,要检查是否符合用户的要求,比如使用正确的中文表达,LaTeX格式是否正确,以及生成的相关问题是否合理。确保所有引用都正确标注,比如在提到环境变量设置时引用[2],在优化部分引用[1]和[2]。 总结一下,回答的结构应该是:先概述集成方案,然后分步骤详细说明环境准备、代码实现、优化方法,最后给出应用场景和相关问题。确保每个部分都有对应的引用支持,并且语言清晰易懂。</think>以下是使用 DeepSeekLangChain 构建聊天机器人的集成方案详解: ### 一、核心集成架构 通过 LangChain 的模块化设计,可将 DeepSeek 大模型能力整合到对话流程中,典型架构为: $$prompt \rightarrow DeepSeek \rightarrow parser \rightarrow output$$ 类似 Linux 管道操作,其中 LangChain 负责流程编排[^2] ### 二、实施步骤 #### 1. 环境准备 ```bash pip install langchain-deepseek langchain_community python-dotenv ``` 需特别注意 LangChainDeepSeek API 的版本兼容性 #### 2. 密钥配置 在项目根目录创建`.env`文件: ```python DEEPSEEK_API_KEY="your_api_key_here" ``` #### 3. 基础实现代码 ```python from langchain_deepseek import DeepSeek from langchain_core.prompts import ChatPromptTemplate from langchain_community.llms import load_llm from dotenv import load_dotenv load_dotenv() # 初始化模型 model = DeepSeek(temperature=0.7) # 构建对话链 prompt = ChatPromptTemplate.from_template("你是一个AI助手,请回答:{query}") chain = prompt | model | (lambda x: x.content) # 执行对话 response = chain.invoke({"query": "解释量子计算原理"}) print(response) ``` 该实现包含完整的对话处理流程:提示词构造→模型推理→结果解析 ### 三、优化方案 1. **参数调优** 通过调整`temperature`参数(范围 0-1)控制生成结果的创造性,数学表达为: $$P(w_i|w_{<i}) = \frac{\exp(z_i/\tau)}{\sum_j \exp(z_j/\tau)}$$ 其中$\tau$即为temperature参数[^1] 2. **记忆增强** 集成 ConversationBufferMemory 实现多轮对话: ```python from langchain.memory import ConversationBufferMemory memory = ConversationBufferMemory() chain = ConversationChain(llm=model, memory=memory) ``` 3. **知识库集成** 通过 LangChain 的 RetrievalQA 结合向量数据库: ```python from langchain.chains import RetrievalQA qa_chain = RetrievalQA.from_chain_type( llm=model, retriever=vector_db.as_retriever() ) ``` ### 四、应用场景 1. 智能客服系统(处理日均 10万+咨询) 2. 教育领域的个性化辅导机器人 3. 结合 RAG 架构的专业领域知识问答
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

笔触狂放

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值