当前位置: 首页 > news >正文

鸿蒙NEXT项目实战-百得知识库01

代码仓地址,大家记得点个star

IbestKnowTeach: 百得知识库基于鸿蒙NEXT稳定版实现的一款企业级开发项目案例。 本案例涉及到多个鸿蒙相关技术知识点: 1、布局 2、配置文件 3、组件的封装和使用 4、路由的使用 5、请求响应拦截器的封装 6、位置服务 7、三方库的使用和封装 8、头像上传 9、应用软件更新等https://gitee.com/xt1314520/IbestKnowTeach

项目准备

项目介绍

“百得知识库软件”是一款专注于编程技术领域的学习资源App,旨在为开发者提供丰富的学习材料。这里涵盖了广泛的IT相关知识,无论是编程语言、软件开发,还是最新的技术趋势,都能找到详尽的资料。该软件不仅有助于开发者提升专业技能,还通过完善的社区和文档支持促进交流与合作。用户可以轻松获取解决方案,参与讨论,从而加速个人成长和技术问题的解决。

通过项目学到什么

  1. 华为账号授权登录
  2. 三方库的使用和封装
  3. 组件的封装和使用
  4. 头像上传
  5. 应用软件更新
  6. 日历组件的使用
  7. 地理位置定位

......

创建项目

1、点击文件,新建项目

2、选择模板

修改项目名,包名,项目名等信息

3、完成创建

4、打开模拟器,运行项目

5、修改应用名称和图标

1、在跟目录下面AppScope/resources/base/media替换app_icon图片

2、修改module.json5文件

替换成app_icon

3、修改应用名称

将label修改成百得知识库

导入静态资源

1、resources/base/element

📎color.json

📎float.json

📎string.json

2、resources/en_US/element

📎string.json

3、resources/zh_CN/element

📎string.json

4、百得知识库里面的静态图片资源

https://download.csdn.net/download/weixin_51166786/90426858

5、修改module.json5里面的startWindowIcon里面的值

"startWindowIcon": "$media:start_icon"

项目三方库依赖

三方库官方地址:

OpenHarmony三方库中心仓

1、@ohos/axios (网络请求三方库)

ohpm install @ohos/axios@2.2.0

2、@ibestservices/ibest-ui (组件三方库)

ohpm install @ibestservices/ibest-ui@2.0.3

日志的封装

在ets下面新建utils目录,然后在这个目录下面新建Logger.ets

import { hilog } from '@kit.PerformanceAnalysisKit'

const DOMAIN = 0x0000
const TAG = 'wdl'
const FORMAT = '%{public}s %{public}s'

export class Logger {
  static debug(...args: string[]) {
    hilog.debug(DOMAIN, TAG, FORMAT, args)
  }

  static info(...args: string[]) {
    hilog.info(DOMAIN, TAG, FORMAT, args)
  }

  static warn(...args: string[]) {
    hilog.warn(DOMAIN, TAG, FORMAT, args)
  }

  static error(...args: string[]) {
    hilog.error(DOMAIN, TAG, FORMAT, args)
  }
}

文本提示框的封装

在ets/utils目录下面新建Toast.ets

import promptAction from '@ohos.promptAction'

/**
 * 显示toast
 * @param { string } message 显示的信息
 */
export function showToast(message: string) {
  promptAction.showToast({
    message: message || '请求错误',
    duration: 2000,
  })
}

用户首选项的封装

在ets/utils目录下面新建PreferencesUtil.ets

import { preferences } from '@kit.ArkData'

export class PreferencesUtil {
  /**
   * 保存数据到首选项
   * @param preferencesName
   * @param key
   * @param value
   */
  static async savaData<T extends keyof number | number | string | boolean | Array<number> | Array<string> | Array<boolean>>(preferencesName: string,
                                                                                                                             key: string, value: T) {
    const pre = preferences.getPreferencesSync(getContext(), { name: preferencesName })
    pre.putSync(key, value as preferences.ValueType)
    await pre.flush()
  }

  /**
   * 获取数据
   * @param preferencesName
   * @param key
   * @param defaultValue
   * @returns
   */
  static getData<T extends keyof number | number | string | boolean | Array<number> | Array<string> | Array<boolean>>(preferencesName: string,
                                                                                                                      key: string, defaultValue: T) {
    const pre = preferences.getPreferencesSync(getContext(), { name: preferencesName })
    return pre.getSync(key, defaultValue as preferences.ValueType) as T
  }

  /**
   * 删除数据
   * @param preferencesName
   * @param key
   */
  static async delAllData(preferencesName: string, key: string) {
    const pre = preferences.getPreferencesSync(getContext(), { name: preferencesName })
    pre.deleteSync(key)
    await pre.flush()
  }
}

新建常量类

在ets/contants目录下面新建CommonConstant.ets和RouterConstant.ets

1、CommonConstant.ets

export class CommonConstant {
  /**
   * 百分百宽度
   */
  static readonly WIDTH_FULL = '100%'
  /**
  * 百分百高度
  */
  static readonly HEIGHT_FULL = '100%'
  /**
   * 开屏广告页面默认展示时间,单位秒
   */
  static readonly ADVERTISING_TIME: number = 3;
  /**
   * 结束时间,单位秒
   */
  static readonly ADVERTISING_END_TIME: number = 0;
  /**
   * 存token值的名称(token)
   */
  static readonly TOKEN_NAME: string = 'token';
  /**
   * 用户首选项实例的名称
   */
  static readonly PREFERENCES_NAME: string = 'preferences';
  /**
   * 存用户信息的本地存储名称
   */
  static readonly USER_INFO: string = 'userInfo';
  /**
   * 登录错误
   */
  static readonly DEFAULT_LOGIN_ERROR: string = '登录错误';
}

2、RouterConstant.ets

export class RouterConstant {
  /**
   * 首页
   */
  static readonly PAGE_INDEX = 'pages/Index'
  /**
   * 登录
   */
  static readonly PAGE_LOGIN = 'pages/LoginPage'
  /**
   * 打卡
   */
  static readonly VIEWS_CLOCK = 'views/Learn/Clock'
  /**
   * 打卡记录
   */
  static readonly VIEWS_CLOCK_RECORD = 'views/Learn/ClockRecord'
  /**
   * 学习目标
   */
  static readonly VIEWS_LEARN_TARGET = 'views/Learn/LearnTarget'
  /**
   * 学习工具
   */
  static readonly VIEWS_LEARN_TOOL = 'views/Learn/LearnTool'
  /**
  * 学习平台内容
  */
  static readonly VIEWS_LEARN_CONTENT = 'views/Learn/LearnContent'
  /**
   * 面试平台内容
   */
  static readonly VIEWS_INTERVIEW_CONTENT = 'views/Learn/InterviewContent'
  /**
   * home页面
   */
  static readonly VIEWS_HOME_HOME = 'views/Home/Home'
  /**
   * 文章详情页面
   */
  static readonly VIEWS_HOME_ARTICLE_INFO = 'views/Home/ArticleInfo'
  /**
   * home搜索页面
   */
  static readonly VIEWS_HOME_SEARCH = 'views/Home/Search'
  /**
   * 消息列表页面
   */
  static readonly VIEWS_MESSAGE_LIST = 'views/Message/MessageList'
  /**
   * 个人信息
   */
  static readonly VIEWS_MINE_INFO = 'views/Mine/MineInfo'
  /**
   * 我的收藏
   */
  static readonly VIEWS_MINE_COLLECT = 'views/Mine/MineCollect'
  /**
   * 我的点赞
   */
  static readonly VIEWS_MINE_LIKE = 'views/Mine/MineLike'
  /**
   * 关于我们
   */
  static readonly VIEWS_MINE_ABOUT_US = 'views/Mine/AboutUS'
  /**
   * 设置
   */
  static readonly VIEWS_MINE_SET_UP = 'views/Mine/SetUp'
  /**
   * 隐私政策
   */
  static readonly PAGE_PRIVACY_POLICY = 'pages/PrivacyPolicyPage'
  /**
   * 用户协议
   */
  static readonly PAGE_USER_POLICY = 'pages/UserPolicyPage'
}

请求响应拦截器的封装

在ets下面新建request目录,然后在这个目录下面新建Request.ets和Request.type.ets

1、Request.ets

import axios, { AxiosError, AxiosResponse, InternalAxiosRequestConfig } from '@ohos/axios'
import { CODE_TYPE, BASE_HOST } from "./Request.type"
import { Logger } from '../utils/Logger';
import { showToast } from '../utils/Toast';
import { CommonConstant } from '../contants/CommonConstant';
import { PreferencesUtil } from '../utils/PreferencesUtil';
import { router } from '@kit.ArkUI';
import { RouterConstant } from '../contants/RouterConstant';


/**
 * axios封装
 */
const http = axios.create({
  baseURL: `http://${BASE_HOST}`,
  headers: {
    'Content-Type': 'application/json',
    "Channel": "B2B"
  }
},)


/**
 * 添加请求拦截器
 */
http.interceptors.request.use((config: InternalAxiosRequestConfig) => {
  // 获取数据
  const token: string | undefined = AppStorage.get("token")
  // 获取token
  if (token) {
    config.headers.Authorization = token
  }
  return config;
}, (error: AxiosError) => {
  // 对请求错误做些什么
  return Promise.reject(error);
});


/**
 * 添加响应拦截器
 */
http.interceptors.response.use((response: AxiosResponse) => {
  Logger.info("请求状态码" + response.data.code, JSON.stringify(response.data));
  // 判断响应状态码
  if (response.status === CODE_TYPE.SUCCESS) {
    // 请求成功
    if (response.data.code === CODE_TYPE.SUCCESS) {
      return Promise.resolve(response.data.data);
    } else if (response.data.code === CODE_TYPE.NO_LOGIN) {
      clearLoginInfoAndGoLoginPage();
    }
  }
  // 接口响应报错新信息
  showToast(response.data.message);
  return Promise.reject(response);
}, (error: AxiosError) => {
  showToast('网络错误,换个网络试试');
  return Promise.reject(error);
});

export default http;

/**
 * 清除用户信息并跳到登录页面
 */
async function clearLoginInfoAndGoLoginPage() {
  // 401错误  -> 清理用户信息,跳转到登录页
  // 清理token,返回登录页
  // userInfo有订阅者删不掉,所以重新赋值空的给userInfo
  AppStorage.setOrCreate(CommonConstant.USER_INFO, {
    nickname: '',
    unionId: '',
    avatarUri: '',
    id: 0
  })
  AppStorage.delete(CommonConstant.TOKEN_NAME)
  await PreferencesUtil.delAllData(CommonConstant.PREFERENCES_NAME, CommonConstant.TOKEN_NAME)
  await PreferencesUtil.delAllData(CommonConstant.PREFERENCES_NAME, CommonConstant.USER_INFO)
  // 跳转登录页面
  router.pushUrl({
    url: RouterConstant.PAGE_LOGIN
  })
}

2、Request.type.ets

export enum CODE_TYPE {
  SUCCESS = 200,
  NO_LOGIN = 401
}

/**
 * host地址
 */
export const BASE_HOST = '118.31.50.145:9003'

服务端接口文档地址

api.md

相关文章:

  • 【Zephyr】【一】学习笔记
  • Linux驱动开发实战之SRIO驱动(一)
  • 江小南的题目讲解
  • 继承父类的实体对象没打印出来父级属性问题
  • YOLOv5部署全场景问题解决方案手册(2025版)
  • 2025年汽车加气站操作工考试精选题库
  • postman小白教程(从入门到实战,详细教学)
  • 【鸿蒙开发】Hi3861学习笔记- OLED示例
  • Execution failed for task ‘:path_provider_android:compileDebugJavaWithJavac‘.
  • 邮件祝福常见模版
  • #Hadoop全分布式安装 #mysql安装 #hive安装
  • 循环神经网络(Recurrent Neural Network, RNN)与 Transformer
  • 【嵌入式学习】补码-加减乘除电路
  • Netty源码—2.Reactor线程模型二
  • 强推 Maven多镜像源快速切换工具,GUI操作超便捷
  • 379_C++_通过小时、天、月、年的地址偏移,上告的图片数据存储在不同的时间粒度位置;提取的时候按照同样的小时、天、月、年偏移,提取数据
  • GitHub在push推送到远程仓库的时候显示Logon failed登录失败
  • Qt 导入TagLib库
  • 【Wconv】小波卷积--即插即用的模块
  • Redis数据类型详解
  • 博物馆日|为一个展奔赴一座城!上海171家博物馆等你来
  • 梅花奖在上海|话剧《主角》:艺术与人生的交错
  • 最高人民法院、中国证监会联合发布《关于严格公正执法司法 服务保障资本市场高质量发展的指导意见》
  • 四个“从未如此”使巴以加沙战火绵延时间创下历史之最
  • 百色一女子称家委会强制排班被迫抱婴儿校门口站岗?区教育局:自愿参与
  • 免签国+1,中乌(兹别克斯坦)互免签证协定6月生效