# temp **Repository Path**: leaf-domain/temp ## Basic Information - **Project Name**: temp - **Description**: No description available - **Primary Language**: Unknown - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2024-01-19 - **Last Updated**: 2024-01-19 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 基于openharmony开发的智能秤 ## 一、介绍 ​ 在智慧社区大背景下,我们深刻认识到科技的持续进步对于社区生活和商业发展的重要影响。基于这一理念,我们积极投入研发,致力于打造一款具备自动识别商品、称重计价和展示广告的功能的智能电子秤产品,以此为切入点,引领智慧菜场的全面升级与创新。 ​ 智能电子秤不仅为消费者提供了更加便捷的购物方式,也为商家创造了更高效的运营环境,同时为市场管理人员提供了更具数据化的管理手段。我们的目标不仅仅是在购物体验方面带来提升,更是实现多方共赢的创新力量,共建智慧社区 ### 整体视图 ![whole](./image/whole.jpg) ### 主要功能介绍 ①、自动感应商品称重 ②、商品数据设置和修改 ③、营业额展示 ④、展示广告和社区新闻 ⑤、订单项详情展示 ⑥、平台交易情况看板 ⑦、鸿蒙关系型数据库RDB ⑧、HTTP协议使用 ## 二、系统架构 #### 系统结构图 ![系统架构](./image/系统架构.png) ## 三、开发指导 ### ①、openharmony应用开发 #### 1.商品详情展示 ![product](./image/product.jpg) ``` 通过使用ArkTS的List组件和ListItem组件进行商品数据的循环渲染,以表格的形式展示 List({ space: 5 }) { ForEach(this.products, (item: Product) => { ListItem() { Row({ space: 30 }) { Text(item.productName) .flexGrow(1) .width(0) Text(item.productPrice.toString()) .flexGrow(1) .width(0) Text(item.productUnit) .flexGrow(1) .width(0) .fontColor('red') Button("修改").onClick(() => { router.pushUrl({ url: 'pages/set/SetFix', params: { "productId": item.productId, "productName": item.productName, "productPrice": item.productPrice.toString(), "productUnit": item.productUnit } }) }) .width(80) }.width("100%") .onClick(() => { this.imageResourse = $r('app.media.icon') }) } }) } .height(0) .flexGrow(6) ``` #### 2.自定义商品项组件 ![ordergoods](./image/ordergoods.jpg) 对于自定义组件的开发,可以使用@Component,用import引入父组件中 通过我们引用自定义组件时,通过import导入,同时我们可以使用@ObjectLink对数据进行监听 父组件: ``` import { OrderGoodsView } from "../view/OrderGoodsView" List({ space: 8 }) { ForEach(this.shoppingCart, (item: OrderGoods) => { ListItem() { OrderGoodsView({ orderGoods: item }) } }, (item: OrderGoods) => `${item.goodsId}` ) } .height("100%") ``` 子组件: ``` @Component export struct OrderGoodsView { @ObjectLink orderGoods: OrderGoods; build() { Row() { GridRow({ columns: 6 }) { // 商品名 GridCol() { Text(`${this.orderGoods.goodsName}`) } // 商品单价 GridCol() { Text(`${this.orderGoods.goodsPrice}`) } // 数量 GridCol() { Text(`${this.orderGoods.goodsWeight}`) } // 单位 GridCol() { Text(`${this.orderGoods.goodsUnit}`) } // 金额 GridCol() { Text(`${this.orderGoods.goodsTotalPrice}`) } }.width("100%") } } } ``` #### 3.平台交易数据看板 ![search](./image/databoard.jpg) 这里采用的自定义的图传视频组件,是采用http获取图片然后通过canvas进行绘画 #### 4.商品搜索框 ![search](./image/Search.png) 使用鸿蒙的Search组件,自带的searchButton在用户点击搜索时完成搜查功能 ``` Search({ placeholder: "请输入品名" }) .width(180) .searchButton("搜索").onSubmit((value: string) => { if (value == "") { AlertDialog.show({ message: "请输入内容" }) } else { this.getOne(value); } }) ``` #### 5.数据上传到服务器 使用HTTP网络请求上传数据到MYSQL数据库中,并封装HTTP请求 ##### 1).在module.json5文件中加入网络权限 文件位置:![position1](./image/position1.png) ``` “requestPermissions”:[ { “name”: “ohos.permission.INTERNET” } ] , ``` ##### 2).导入http ``` import http from ‘@ohos.net.http’; ``` ##### 3).书写http请求 例:post请求: ``` let httpRequest = http.createHttp(); //获取HTTP对象 let url = "http://somewords.xyz:80/store/login" //填写路径 let promise = httpRequest.request( // 请求url地址 url, { // 请求方式 method: http.RequestMethod.POST, extraData: { "storeId": this.storeId, "password": this.storePassword, }, // 可选,默认为60s connectTimeout: 60000, // 可选,默认为60s readTimeout: 60000, // 开发者根据自身业务需要添加header字段 header: { 'Content-Type': 'application/json' } }).then((data) => { //回调函数 }).catch((err) => { console.info('error:' + JSON.stringify(err)); }) ``` ##### 4).使用axios框架并封装 ![position2](./image/position2.png) 通过这个工具类,我们可以获得axios对象,并配置网络请求的基础路径。后续利用axios发送http请求 ``` var _axios: AxiosInstance = null; export function getAxios() { if (_axios) { return _axios } return _axios = axios.create({ baseURL: 'http://jiazixin.xyz:80' }); } ``` ##### 5).封装HTTP请求 将不同功能的请求封装在不同的Request类里 ![Requests](./image/Requests.png) 以登录功能的POST请求为例:配置好post请求的路径和参数,利用axios进行网络请求 ``` import { getAxios } from "../util/HttpUtil" import { AxiosRequestConfig } from "@ohos/axios" export namespace LoginRequest { /** * 登录请求 * @param storeId * @param password * @returns */ export function login(storeId, password) { // 请求url地址 let url = "/store/login" return getAxios().post(url, { "storeId": storeId, "password": password, }) } } ``` #### 6.上传数据到鸿蒙关系型数据库RDB ##### 1).导入模块@ohos.data.relationalStore ``` import relationalStore from '@ohos.data.relationalStore' ``` ##### 2).创建数据库 这里用一个工具类DataBaseUtil去创建并初始化数据库 ![position2](./image/position2.png) ``` export default class DatabaseUtil { /** * 关系型数据库 */ public static dbs: relationalStore.RdbStore; /** * 键值型数据库管理器 */ public static KVDBManager: distributedKVStore.KVManager; /** * 初始化数据库dbs */ public static init(context) { this.initDBS(context); this.initKVDBManager(context); } /** * 初始化键值型数据库 * @param context */ public static initKVDBManager(context) { const kvManagerConfig = { context: context, bundleName: 'com.example.datamanagertest' }; try { // 创建KVManager实例 this.KVDBManager = distributedKVStore.createKVManager(kvManagerConfig); console.info('Succeeded in creating KVManager.'); // 继续创建获取数据库 } catch (e) { console.error(`Failed to create KVManager. Code:${e.code},message:${e.message}`); } } /** * 初始化关系型数据库。 * @param context */ private static initDBS(context) { const STORE_CONFIG = { name: 'RdbStore.db', // 数据库名 securityLevel: relationalStore.SecurityLevel.S1 // 数据库安全级别 }; relationalStore.getRdbStore(context, STORE_CONFIG, (err, store) => { if (err) { console.error(`Failed to get RdbStore. Code:${err.code}, message:${err.message}`); return; } console.info(`Succeeded in getting RdbStore.`); store.executeSql(PRODUCT_SQL_CREATE); // 创建数据表 product store.executeSql(STORE_SQL_CREATE); // 创建数据表 store store.executeSql(ORDERGOODS_SQL_CREATE); // 创建数据表 orderGoods store.executeSql(TABLEORDER_SQL_CREATE); // 创建数据表 order this.dbs = store; }); } } ``` 数据库创建时机: EntryAbility的onWindowStageCreate方法中初始化数据库。 ![position3](./image/position3.png) ``` DatabaseUtil.init(this.context) ``` ##### 3).创建需要用到的表 建表语句作为常量放在contants文件夹的TableConst中 图 ``` //商品表product export const PRODUCT_SQL_CREATE = 'CREATE TABLE IF NOT EXISTS PRODUCT (' + 'PRODUCTID INTEGER PRIMARY KEY , ' + //商品ID,有AUTOINCREMENT关键字时无法实现自增。 'PRODUCTNAME TEXT NOT NULL, ' + //品名 'PRODUCTPRICE REAL, ' + //单价 'PRODUCTUNIT TEXT, '+ //单位 'STOREID INTEGER, '+ //单位 'CREATEDTIME TEXT, ' + //首次创建时间 'UPDATETIME TEXT)'; //最后更新时间 //商户表store export const STORE_SQL_CREATE = 'CREATE TABLE IF NOT EXISTS STORE (' + 'STOREID INTEGER PRIMARY KEY )' //商店ID //订单列表order_goods export const ORDERGOODS_SQL_CREATE = 'CREATE TABLE IF NOT EXISTS ORDERGOODS (' + 'ORDERGOODSID INTEGER PRIMARY KEY , ' + //订单项唯一ID 'GOODSID INTEGER, ' + //商品唯一ID,和productId相同 'ORDERID INTEGER, ' + //订单ID 'GOODSNAME TEXT, ' + //商品名称 'GOODSWEIGHT TEXT, ' + //商品称重 'GOODSUNIT TEXT, ' + //商品单位 'GOODSPRICE REAL, ' + //商品总价 'GOODSTOTALPRICE REAL, ' + //订单总价 'STOREID INTEGER, ' + //商户ID 'STATUS INTEGER, ' + //订单状态 'CREATEDTIME TEXT, ' + //订单创建时间 'UPDATETIME TEXT)'; //订单修改时间 //订单不会被修改,CS同步与之无关,字段冗余。 //订单表order export const TABLEORDER_SQL_CREATE = 'CREATE TABLE IF NOT EXISTS `TABLEORDER` (' + 'ORDERID INTEGER PRIMARY KEY , ' + //ID 'TOTALPRICE REAL, ' + //总价 'STOREID INTEGER, ' + //商户ID 'STATUS INTEGER, ' + //订单状态 'CREATEDTIME TEXT, ' + //创建时间 'UPDATETIME TEXT)'; //更新时间 ``` 这些语句在DataBaseUtil中被调用继而创建表格。调用代码: ``` store.executeSql(PRODUCT_SQL_CREATE); // 创建数据表 product store.executeSql(STORE_SQL_CREATE); // 创建数据表 store store.executeSql(ORDERGOODS_SQL_CREATE); // 创建数据表 orderGoods store.executeSql(TABLEORDER_SQL_CREATE); // 创建数据表 order ``` ##### 4).实现表格的增删改查操作 例如:STROE表格的新增功能: ``` public insert(store: Store) { const valueBucket = { 'STOREID': store.storeId, }; DatabaseUtil.dbs.insert('STORE', valueBucket, (err, rowId) => { if (err) { console.error(`Failed to insert data. Code:${err.code}, message:${err.message}`); return; } console.info(`Succeeded in inserting data. rowId:${rowId}`); }) } ``` ### ⑤、3D模型开发 ![1659021241571](media/1659021241571.png) ### 四、 参考资料 - https://ost.51cto.com/posts/25527