鸿蒙期末项目(2)

news2024/11/25 0:47:43

主界面

主界面和商店详情界面参考如下设计图(灵感严重匮乏)

img

简单起见,将整个app分为4个布局,分别是主界面、搜索界面、购物车界面,以及个人界面。

所以在app中也需要使用tab组件进行分割,且需要通过tabBar方法设置底部导航栏

Tabs({
    barPosition: BarPosition.End,
    controller: this.tabsController,
}) {
    TabContent() {
        HomeView()
    }
    .tabBar(this.TabBuilder(
        'Home',
        CommentConstant.HOME_TAB_INDEX,
        CommentConstant.HomeIconActive,
        CommentConstant.HomeIconNormal
    ))
​
    TabContent() {
        SearchView()
    }
    .tabBar(this.TabBuilder(
        'Search',
        CommentConstant.SEARCH_TAB_INDEX,
        CommentConstant.SearchIconActive,
        CommentConstant.SearchIconNormal
    ))
​
    TabContent() {
        CartView()
    }
    .tabBar(this.TabBuilder(
        'Cart',
        CommentConstant.CART_TAB_INDEX,
        CommentConstant.CartIconActive,
        CommentConstant.CartIconNormal
    ))
​
    TabContent() {
        ProfileView()
    }
    .tabBar(this.TabBuilder(
        'Profile',
        CommentConstant.PROFILE_TAB_INDEX,
        CommentConstant.ProfileIconActive,
        CommentConstant.ProfileIconNormal
    ))
}

导航栏样式的设置:

@State currentIndex: number = CommentConstant.HOME_TAB_INDEX;
private tabsController: TabsController = new TabsController();
​
@Builder
TabBuilder(title: string, index: number, selectIcon: ResourceStr, normalIcon: ResourceStr) {
    Column() {
        Image(this.currentIndex === index ? selectIcon : normalIcon)
            .width('25vp')
            .height('25vp')
​
        Text(title)
            .margin({ top: '4vp' })
            .fontSize('10fp')
            .fontColor(this.currentIndex === index ? '#e76b7a' : '#6b6b6b')
    }
    .justifyContent(FlexAlign.Center)
        .height('56vp')
        .width('100%')
        .onClick(() => {
        this.currentIndex = index;
        this.tabsController.changeIndex(index)
    })
}

即可实现如下效果

随后开始编写四个页面组件

根据页面图,整个页面分为五个部分,分别为头部位置信息和通知选项、广告栏、热门标签栏、今日推荐栏、著名品牌栏,由于五个组件仅会在主页面中使用,所以可以使用@Builder创建组件函数在主页面组件中函数式声明,简单快捷且不需要额外import,灰常好用~

由于主页面需要放下的内容过多导致一页不能放下,考虑使用Scroll滚动布局,当子节点高度超过时自动加滚动条,同时需要设置

.align(Alignment.TopStart)

保证子节点从顶部开始排列

其中在实现下面这个卡片的样式时,可以看到卡片是有四个方向的圆角的,但是如果直接放图片,图片会将上方的两个圆角覆盖住,这个时候可以使用.clip(true) 属性,意为沿边缘裁剪,即可达到下面这种效果。

实现效果如下:

Web服务器搭建和数据持久化

到目前位置,本项目的所有数据都是保存在内存中的,仅作外观测试使用,而没有实际作用。

那么如何实现数据持久化呢?

鸿蒙提供了数据库接口,其可以方便地通过一系列配置和方法读取或修改数据库中的数据。然而,使用这种方法却存在一个问题,数据库文件保存在用户本地,既无数据来源,也无法实时更新。所以更好的解决方法应当是建立服务器,客户端通过调用 api 的方式从服务器的数据库中获取数据。

所以现在项目迫切需要搭建一个javaweb服务器。

根据点餐app需求分析,可以大致抽象出如下几个数据表(使用mysql数据库)。

用户表 user

属性列描述
email邮箱
phone电话
id编号
username用户名
password密码

商店表 store

属性列描述
id编号
storeName商店名
address地址
phone电话
intro介绍
score评分
open目前是否营业
cover店铺封面
logo店铺logo
special特殊性 0-无 1-著名 2-TopRated

菜品表 dish

属性列描述
id编号
sid所属商铺编号
dishName菜名
intro介绍
price价格
discount折扣
catalog所属分类

标签表 tags

属性列描述
id编号
tagName标签名

菜品-标签表 dt

属性列描述
Did菜品编号
Tid标签标号

订单表 orders

属性列描述
id订单号
time付款时间
uid用户
price总额
state订单状态 0-待支付 1-送餐中 2-已取消 3-已完成 4-已过期
sid消费商店

订单-菜表 od

属性列描述
oid订单号
Did菜号
number选菜数量

使用sql建表

use pigdelivery;
​
create table user (
    email varchar(2048) not null,
    id int auto_increment primary key ,
    username varchar(30) not null,
    password double not null
);
​
create table store(
    id int auto_increment primary key ,
    storeName varchar(50) not null,
    intro varchar(100) not null,
    score double not null,
    open bit not null,
    cover varchar(2048) not null,
    logo varchar(2048) default 'defaultLogo.jpg',
    special int default 0 not null
);
​
create table dish(
    id int auto_increment primary key ,
    sid int not null,
    dishName varchar(50) not null,
    intro varchar(100) not null,
    price double not null,
    discount double not null,
    catalog varchar(30) not null,
    foreign key (sid) references store(id)
);
​
create table tags(
    id int auto_increment primary key ,
    tagName varchar(30) not null
);
​
create table dt(
    Did int not null,
    Tid int not null,
    foreign key (Did) references dish(id),
    foreign key (Tid) references tags(id)
);
​
create table orders(
    id int auto_increment primary key ,
    time varchar(30),
    uid int not null,
    price double not null,
    state int not null,
    sid int not null,
    foreign key (uid) references user(id),
    foreign key (sid) references store(id)
);
​
create table od(
    Oid int not null,
    Did int not null,
    number int not null,
    foreign key (Oid) references orders(id),
    foreign key (Did) references dish(id)
);

建表完成后,填入一些商店数据用于测试。


数据库建立完成后,接下来开始写Javaweb,javaweb就很好写了,按照流程一步一步来就好,这里仅仅简单地概述一下步骤:

使用Tomcat10.1.24构建服务器,通过JavaWeb编写Servlet,并使用mybatis框架连接数据库。

首先新建一个Jakarta EE项目

通过maven导入依赖的jar包,在资源目录下新建 mybatis-config.xml 用作mybatis配置文件,并按照mybatis配置文件格式填写该xml

随后写相应的Mapper接口和实体类(省略)

以登入接口为例,写一个doPost

@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    EvalTran.evalJSON(req, resp);
​
    if(req.getParameter("email") != null && req.getParameter("password") != null) {
        try {
            double password = Double.parseDouble(req.getParameter("password"));
            String email = req.getParameter("email");
            User user = UserLoader.selectUser(email, password);
            if(user != null) {
                resp.getWriter().write(gson.toJson(Response.success("success")));
            } else {
                resp.getWriter().write(gson.toJson(Response.success("user not exist")));
            }
        } catch (NumberFormatException e) {
            resp.getWriter().write(gson.toJson(Response.badRequest("参数不合法")));
        }
    } else {
        resp.getWriter().write(gson.toJson(Response.badRequest("表单数据不完整")));
    }
}

javaWeb程序写好之后,回到DevEco Studio中尝试调用该url

在DevEco Studio中打开Terminal终端执行指令 npm install axios 安装axios

在model目录下编写LoginModel类

import axios from '@ohos/axios';
​
class LoginModel {
    readonly baseUrl = 'http://localhost:8080/PigDeliveryServer_war_exploded'
​
    // 当返回 0 表示登入失败, 否则返回一个数字代表登入成功后的用户id
    async verifyAccount(email: string, password: string): Promise<number> {
        return await axios.post(
            this.baseUrl + '/login',
            {
                email: email,
                password: password,
            }
        )
            .then((resp) => {
                console.log(resp.data.message + '');
            // 下面使用双等号的原因是json传输是数字类型可能会被转成字符串类型
                if(resp.data.code == 200 && resp.data.message == 'success') {
                    return parseInt(resp.data.code);
                } else {
                    return 0;
                }
            })
            .catch((error) => {
                console.log("error: " + error);
                return 0;
            })
    }
}
​
export default new LoginModel() as LoginModel;

回到之前编写的登入界面,当时为了测试登入界面,将登入按钮设计成点击就可以登入,现在,我们尝试将点击事件改成真实有效的验证方式:

Button('LogIn')
    .regButton()
    .onClick(() => {
    loginModel.verifyAccount(this.emailInput, this.passwordInput)
        .then((data) => {
        if(data === 0) {
            AlertDialog.show({
                message: '用户不存在或密码错误',
            })
        } else {
            CommentConstant.userId = data;
            router.replaceUrl({
                url: 'pages/MainPage',
            })
        }
    })
})

当点击登入按钮中,期望中进入主界面的效果并没有实现,而是出现了密码错误的提示,将服务器返回值输出后,控制台输出:

success表示服务器收到了请求,但是参数没有传递过去。

在服务器端doPost方法中编写如下代码:

BufferedReader reader = new BufferedReader(req.getReader());
StringBuilder stringBuilder = new StringBuilder();
while (reader.ready()) {
    stringBuilder.append(reader.readLine());
}
​
String json = stringBuilder.toString();
System.out.println(json);

再次请求,结果如下

ArkTs 中的 axios 直接将data中的数据以 json 字符串的形式发给了服务器,所以在服务器中还要对json的情况做处理

BufferedReader reader = new BufferedReader(req.getReader());
StringBuilder stringBuilder = new StringBuilder();
while (reader.ready()) {
    stringBuilder.append(reader.readLine());
}

String json = stringBuilder.toString();
UserTemp userTemp = gson.fromJson(json, UserTemp.class);

if(userTemp == null || userTemp.getEmail() == null || userTemp.getPassword() == null) {
    resp.getWriter().write(gson.toJson(Response.badRequest("表单数据不完整")));
} else {
    User user = UserLoader.verifyUser(userTemp.getEmail(), userTemp.getPassword());
    if(user != null) {
        resp.getWriter().write(gson.toJson(Response.success("success", String.valueOf(user.getId()))));
    } else {
        resp.getWriter().write(gson.toJson(Response.success("userNotExist")));
    }
}

改变之后,鸿蒙端测试登入成功。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1870109.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

笔记本电脑录屏,教你3个方法,简单录屏

随着科技的飞速发展&#xff0c;笔记本电脑录屏功能已经不再局限于传统的录制需求&#xff0c;而是成为了探索屏幕动态的新方式。无论是创意工作者、游戏爱好者还是日常办公者&#xff0c;都可以借助这一功能&#xff0c;将屏幕上的精彩瞬间、重要信息或创新思路记录下来&#…

Quads,一个无敌的 Python 库!

更多资料获取 &#x1f4da; 个人网站&#xff1a;ipengtao.com 大家好&#xff0c;今天为大家分享一个无敌的 Python 库 - Quads。 Github地址&#xff1a;https://github.com/fogleman/Quads 在科学计算和工程应用中&#xff0c;数值积分是一个常见的问题。Python的Quads库…

maven仓库的作用以及安装 , DEA配置本地Maven

ay12-maven 主要内容 Maven的作用Maven仓库的作用Maven的坐标概念Maven的安装IDEA配置本地Maven 一、maven概述 1.1、项目开发中的问题 1、我的项目依赖一些jar包&#xff0c;我把他们放在哪里&#xff1f;直接拷贝到项目的lib文件夹中?如果我开发的第二个项目还是需要上面…

【独家揭秘】SmartEDA电路仿真软件:电子电路基础学习的神器!

在电子科技日新月异的今天&#xff0c;电路基础学习的重要性愈发凸显。但你是否曾为复杂的电路图、难以理解的电路原理而感到困扰&#xff1f;今天&#xff0c;我要向大家推荐一款学习神器——SmartEDA电路仿真软件&#xff0c;让你轻松踏入电子电路基础学习的殿堂&#xff01;…

pytorch为自己的extension backend添加profiler功能

pytorch为自己的extension backend添加profiler功能 1.参考文档2.your-extension-for-pytorch需要增加的代码3.pytorch demo及如何调整chrome trace json文件4.[可视化](https://ui.perfetto.dev/) 本文演示了pytorch如何为自己的extension backend添加profiler功能 背景介绍 …

HarmonyOS Next开发学习手册——代码混淆

代码混淆简介 针对工程源码的混淆可以降低工程被破解攻击的风险&#xff0c;缩短代码的类与成员的名称&#xff0c;减小应用的大小。 DevEco Studio提供代码混淆的能力并默认开启&#xff0c;API 10及以上版本的Stage模型、 编译模式为release 时自动进行代码混淆。 使用约束…

React_创建一个项目

目录 一、React&#xff08;js 版&#xff09; 二、React&#xff08;ts 版&#xff09; 使用react创建一个项目,前提是确保你已经安装了Node.js和npm。 如果没有安装Node.js和npm&#xff0c;查看这个文件&#xff1a; 安装node.js和npmhttps://blog.csdn.net/zxy1993106…

Arcgis地统计分析工具灰色不可用 解决方法

使用Arcmap&#xff0c;调用地统计分析工具&#xff08;Geostatistical Analyst&#xff09;下的探索数据&#xff08;Explore Data&#xff09;&#xff0c;发现工具呈灰色不可用。这是由于扩展模块中没有将该模块做勾选设置导致的。下面介绍一下如何解决地统计分析工具不可用…

学生成绩管理系统带8000字文档学生选课管理系统java项目javaweb项目ssm项目jsp项目java课程设计java毕业设计

文章目录 学生选课成绩管理系统一、项目演示二、项目介绍三、8500字项目文档四、部分功能截图五、部分代码展示六、底部获取项目源码带8500字文档&#xff08;9.9&#xffe5;带走&#xff09; 学生选课成绩管理系统 一、项目演示 选课成绩管理系统 二、项目介绍 语言: Java …

【从0实现React18】 (五) 初探react mount流程 完成核心递归流程

更新流程的目的&#xff1a; 生成wip fiberNode树标记副作用flags 更新流程的步骤&#xff1a; 递&#xff1a;beginWork归&#xff1a;completeWork 在 上一节 &#xff0c;我们探讨了 React 应用在首次渲染或后续更新时的整体更新流程。在 Reconciler 工作流程中&#xff…

硬盘空间告急?监控服务器容量,钉钉及时提醒!

在日常的服务器维护中&#xff0c;硬盘容量的监控是非常重要的。如果硬盘容量超过某个阈值&#xff0c;可能会导致服务器无法正常运行&#xff0c;影响业务的正常运作。为了避免这种情况&#xff0c;我们可以编写一个Shell脚本&#xff0c;定期检查硬盘容量&#xff0c;当超过设…

springboot + Vue前后端项目(第二十记)

项目实战第二十记 写在前面1. 高德地图官网2. 开发文档3. 集成高德地图3.1 在public文件夹下创建config.js3.2 index.html&#xff08;在项目启动文件中引入外部的js&#xff09;3.3 点标记&#xff08;用点标记当前位置&#xff09;3.4 信息窗体&#xff08;点击当前位置&…

如何预防和处理他人盗用IP地址?

IP地址的定义及作用 解释 IP 地址在互联网中的作用。它是唯一标识网络设备的数字地址&#xff0c;类似于物理世界中的邮政地址。 1、IP地址盗窃的定义 解释一下什么是IP地址盗用&#xff0c;即非法使用他人的IP地址或者伪造IP地址的行为&#xff0c;这种行为可能引发法律和安…

DLMS/COSEM协议—(Green-Book)Gateway protocol

DLMS/COSEM协议 — Gateway protocol 10.10 Gateway protocol &#xff08;网关协议&#xff09;10.10.1 概述10.10.2 网关协议 &#xff08;The gateway protocol&#xff09;10.10.3 HES在WAN/NN中作为发起者&#xff08;拉取操作&#xff09;10.10.4 LAN中的终端设备作为发起…

数据库物理结构设计-定义数据库模式结构(概念模式、用户外模式、内模式)、定义数据库、物理结构设计策略

一、引言 如何基于具体的DBMS产品&#xff0c;为数据库逻辑结构设计的结果&#xff0c;即关系数据库模式&#xff0c;制定适合应用要求的物理结构 1、在设计数据库物理结构前&#xff0c;数据库设计人员首先 要充分了解所用的DBMS产品的功能、性能和特点&#xff0c;包括提供…

【最新综述】基于伪标签的半监督语义分割

Semi-Supervised Semantic Segmentation Based on Pseudo-Labels: A Survey 摘要&#xff1a; 语义分割是计算机视觉领域的一个重要而热门的研究领域&#xff0c;其重点是根据图像中像素的语义对其进行分类。然而&#xff0c;有监督的深度学习需要大量数据来训练模型&#xff…

Asm动态生成类和get and set方法

asm在解析文件的时候是按照特定顺序进行分析的&#xff0c;首先是visit方法&#xff0c;做类相关的解析&#xff0c;然后是注解&#xff0c;然后是属性&#xff0c;最后才是方法&#xff0c;属性是在所有方法分析前面进行&#xff0c;也就是只有当class文件中的所有属性都遍历完…

【Android11】开机启动日志捕捉服务

一、前言 制作这个功能的原因是客户想要自动的记录日志中的报错和警告到设备的内存卡里面。虽然开发者模式中有一个“bug report” 会在/data/user_de/0/com.android.shell/files/bugreports/目录下生成一个zip包记录了日志。但是客户觉得这个日志很难获取到他们需要的信息&am…

无需劳师动众,让石油化工DCS集散控制系统轻松实现无线传输!

石油化工中,为了保证较高的可靠性和安全性,大量使用的是DCS集散控制系统。与FCS现场总线的“现场采集,转换为数字信号来集中传输”不同,DCS系统为了避免由于线缆断裂或者节点问题导致整个控制系统失灵,采用“分散传输,集中采集”的方式,即每个传感器通过4-20mA的模拟量通…

el-upload 上传图片及回显照片和预览图片,文件流和http线上链接格式操作

<div v-for"(info, index) in zsjzqwhxqList.helicopterTourInfoList" :key"info.id" >编辑上传图片// oss返回线上地址http链接格式&#xff1a;<el-form-itemlabel"巡视结果照片":label-width"formLabelWidth"><el…