# Imitation Hema - Confirmation Order Page (Business Logic) (30)

Technology Stack  
Appgallery Connect

Development Preparation In the previous section, we implemented the page rendering, price calculation, discount calculation, and order list display for the order confirmation page. In this section, we will implement the entire business logic of the order confirmation page. First, we need to implement address selection, save the calculated prices, product lists, and other data, then create order table entities, and submit this data to the order table.

Functional Analysis To implement the order confirmation function, we first need to create the corresponding table. The data we need to pay attention to includes the user ID corresponding to the current order, the table ID, and the data carried by the table, such as order creation time, completion time, refund time, order number, payment method, remarks, etc. We also need to consider how to effectively insert and query data when there are multiple items in the product list.

Code Implementation First, let's implement the remark pop-up dialog:

typescript import showToast from "../utils/ToastUtils"; import { cloudDatabase } from "@kit.CloudFoundationKit"; import { user\_info } from "../clouddb/user\_info"; import { UserInfo } from "../entity/UserInfo"; import { hilog } from "@kit.PerformanceAnalysisKit";

@Preview @CustomDialog export struct OrderRemarkDialog { controller: CustomDialogController; @Link str: string; build() { Column({ space: 20 }) { Text("Remark") .fontSize($r('app.float.size\_20')) .fontWeight(FontWeight.Bold) .fontColor([Color.Black](http://Color.Black)) .margin({ top: 20 });

TextArea({ text: this.str }) .backgroundColor("#f6f6f6") .placeholderColor("#ff999595") .fontColor("#333333") .height(150) .maxLength(50) .onChange((value: String) =&gt; { if (value.length &gt; 50) { showToast("Up to 50 characters~"); return; } else { this.str = value.toString(); } }) .margin(20);

Row() { Text("Cancel") .width('30%') .textAlign([TextAlign.Center](http://TextAlign.Center)) .height(40) .fontSize(18) .fontColor(Color.White) .backgroundColor(0xff0000) .borderRadius(30) .margin({ top: 30 }) .onClick(() =&gt; { this.str = ''; this.controller.close(); });

Text("Confirm") .width('30%') .textAlign([TextAlign.Center](http://TextAlign.Center)) .height(40) .fontSize(18) .fontColor(Color.White) .backgroundColor(0xff0000) .borderRadius(30) .margin({ top: 30 }) .onClick(async () =&gt; { if (this.str !== '') { this.controller.close(); } else { this.str = ''; this.controller.close(); } }); } .width('100%') .justifyContent(FlexAlign.SpaceAround); } .borderRadius({ topLeft: 20, topRight: 20 }) .justifyContent(FlexAlign.Start) .backgroundColor(Color.White) .height(400) .width('100%'); } }

Invoke the dialog on the order confirmation page:

typescript orderController: CustomDialogController | null = new CustomDialogController({ builder: OrderRemarkDialog({ str: this.remark }), alignment: DialogAlignment.Bottom, customStyle: true });

// Add a click event to the order remark to trigger the dialog Text(this.remark !== "" ? this.remark : "Optional, please specify remarks") .fontColor(Color.Gray) .fontSize(12) .onClick(() =&gt; { this.orderController?.open(); });

// Define the variable to receive remarks @State remark: string = '';

Next, retrieve the saved user information:

typescript // Define the user variable @State user: User | null = null;

// Receive user data const value = await StorageUtils.getAll('user'); if (value !== "") { this.user = JSON.parse(value); }

// Add a click event to the order submission button Text("Submit Order") .fontColor(Color.White) .padding(10) .borderRadius(10) .backgroundColor("#d81e06") .fontSize(14) .onClick(() =&gt; { // Order submission logic will be added here });

Next, perform cloud operations by first creating the table, entity, and DB class for saving the product list:

json { "objectTypeName": "order\_product\_list", "fields": \[ {"fieldName": "id", "fieldType": "Integer", "notNull": true, "belongPrimaryKey": true}, {"fieldName": "order\_product\_id", "fieldType": "Integer", "notNull": true, "defaultValue": 0}, {"fieldName": "img", "fieldType": "String"}, {"fieldName": "price", "fieldType": "Double"}, {"fieldName": "name", "fieldType": "String"}, {"fieldName": "originalPrice", "fieldType": "Double"}, {"fieldName": "spec", "fieldType": "String"}, {"fieldName": "buyAmount", "fieldType": "Integer"} \], "indexes": \[ {"indexName": "field1Index", "indexList": \[{"fieldName":"id","sortType":"ASC"}\]} \], "permissions": \[ {"role": "World", "rights": \["Read", "Upsert", "Delete"\]}, {"role": "Authenticated", "rights": \["Read", "Upsert", "Delete"\]}, {"role": "Creator", "rights": \["Read", "Upsert", "Delete"\]}, {"role": "Administrator", "rights": \["Read", "Upsert", "Delete"\]} \] }

Entity class:

typescript /\*

* Copyright (c) Huawei Technologies Co., Ltd. 2020-2023. All rights reserved.
    
* Generated by the CloudDB ObjectType compiler. DO NOT EDIT! \*/
    

class OrderProductList { id: number; order\_product\_id: number = 0; img: string; price: number; name: string; originalPrice: number; spec: string; buyAmount: number;

constructor() { }

getFieldTypeMap(): Map&lt;string, string&gt; { const fieldTypeMap = new Map&lt;string, string&gt;(); fieldTypeMap.set('id', 'Integer'); fieldTypeMap.set('order\_product\_id', 'Integer'); fieldTypeMap.set('img', 'String'); fieldTypeMap.set('price', 'Double'); fieldTypeMap.set('name', 'String'); fieldTypeMap.set('originalPrice', 'Double'); fieldTypeMap.set('spec', 'String'); fieldTypeMap.set('buyAmount', 'Integer'); return fieldTypeMap; }

getClassName(): string { return 'order\_product\_list'; }

getPrimaryKeyList(): string\[\] { const primaryKeyList: string\[\] = \[\]; primaryKeyList.push('id'); return primaryKeyList; }

getIndexList(): string\[\] { const indexList: string\[\] = \[\]; indexList.push('id'); return indexList; }

getEncryptedFieldList(): string\[\] { const encryptedFieldList: string\[\] = \[\]; return encryptedFieldList; }

// Getter and setter methods setId(id: number): void { [this.id](http://this.id) = id; }

getId(): number { return [this.id](http://this.id); }

setOrder\_product\_id(order\_product\_id: number): void { this.order\_product\_id = order\_product\_id; }

getOrder\_product\_id(): number { return this.order\_product\_id; }

// ... (Other getter and setter methods follow the same pattern)

static parseFrom(inputObject: any): OrderProductList { const result = new OrderProductList(); if (!inputObject) { return result; } if ([inputObject.id](http://inputObject.id) !== undefined) { [result.id](http://result.id) = [inputObject.id](http://inputObject.id); } if (inputObject.order\_product\_id !== undefined) { result.order\_product\_id = inputObject.order\_product\_id; } // ... (Field assignment logic for other properties) return result; } }

export { OrderProductList };

DB class:

typescript import { cloudDatabase } from '@kit.CloudFoundationKit';

class order\_product\_list extends cloudDatabase.DatabaseObject { public id: number; public order\_product\_id = 0; public img: string; public price: number; public name: string; public originalPrice: number; public spec: string; public buyAmount: number;

public naturalbase\_ClassName(): string { return 'order\_product\_list'; } }

export { order\_product\_list };

Since there are multiple products, we implement the addition method within a for loop:

typescript let databaseZone = [cloudDatabase.zone](http://cloudDatabase.zone)('default'); try { for (let i = 0; i &lt; this.productList.length; i++) { const productPush = new order\_product\_list(); [productPush.id](http://productPush.id) = this.codeId + i; productPush.order\_product\_id = this.codeId; productPush.img = this.productList\[i\].productImgAddress; productPush.price = this.productList\[i\].productPrice; [productPush.name](http://productPush.name) = this.productList\[i\].productName; productPush.originalPrice = this.productList\[i\].productOriginalPrice; productPush.spec = this.productList\[i\].productSpecName; productPush.buyAmount = this.productList\[i\].buyAmount; const num = await databaseZone.upsert(productPush); [hilog.info](http://hilog.info)(0x0000, 'testTag', `Succeeded in upserting data, result: ${num}`); } } catch (e) { [hilog.info](http://hilog.info)(0x0000, 'testTag', `Upsert failed, error: ${e}`); }

Next, create the order table to achieve data linking between the two tables via order\_product\_id:

json { "objectTypeName": "order\_list", "fields": \[ {"fieldName": "id", "fieldType": "Integer", "notNull": true, "belongPrimaryKey": true}, {"fieldName": "user\_id", "fieldType": "Integer", "notNull": true, "defaultValue": 0}, {"fieldName": "order\_code", "fieldType": "String"}, {"fieldName": "order\_status", "fieldType": "Integer"}, {"fieldName": "order\_product\_id", "fieldType": "String"}, {"fieldName": "address", "fieldType": "String"}, {"fieldName": "nickname", "fieldType": "String"}, {"fieldName": "phone", "fieldType": "String"}, {"fieldName": "order\_remark", "fieldType": "String"}, {"fieldName": "pay\_type", "fieldType": "String"}, {"fieldName": "order\_create\_time", "fieldType": "String"}, {"fieldName": "order\_pay\_time", "fieldType": "String"}, {"fieldName": "order\_delivery\_time", "fieldType": "String"}, {"fieldName": "order\_over\_time", "fieldType": "String"} \], "indexes": \[ {"indexName": "field1Index", "indexList": \[{"fieldName":"id","sortType":"ASC"}\]} \], "permissions": \[ {"role": "World", "rights": \["Read", "Upsert", "Delete"\]}, {"role": "Authenticated", "rights": \["Read", "Upsert", "Delete"\]}, {"role": "Creator", "rights": \["Read", "Upsert", "Delete"\]}, {"role": "Administrator", "rights": \["Read", "Upsert", "Delete"\]} \] }

Entity class:

typescript class OrderList { id: number; user\_id: number = 0; order\_code: string; order\_status: number; order\_product\_id: string; address: string; nickname: string; phone: string; order\_remark: string; pay\_type: string; order\_create\_time: string; order\_pay\_time: string; order\_delivery\_time: string; order\_over\_time: string;

constructor() { }

getFieldTypeMap(): Map&lt;string, string&gt; { const fieldTypeMap = new Map&lt;string, string&gt;(); fieldTypeMap.set('id', 'Integer'); fieldTypeMap.set('user\_id', 'Integer'); fieldTypeMap.set('order\_code', 'String'); fieldTypeMap.set('order\_status', 'Integer'); fieldTypeMap.set('order\_product\_id', 'String'); fieldTypeMap.set('address', 'String'); fieldTypeMap.set('nickname', 'String'); fieldTypeMap.set('phone', 'String'); fieldTypeMap.set('order\_remark', 'String'); fieldTypeMap.set('pay\_type', 'String'); fieldTypeMap.set('order\_create\_time', 'String'); fieldTypeMap.set('order\_pay\_time', 'String'); fieldTypeMap.set('order\_delivery\_time', 'String'); fieldTypeMap.set('order\_over\_time', 'String'); return fieldTypeMap; }

// ... (Other methods such as getClassName, getPrimaryKeyList, etc., follow the same pattern as OrderProductList)

static parseFrom(inputObject: any): OrderList { const result = new OrderList(); if (!inputObject) { return result; } if ([inputObject.id](http://inputObject.id) !== undefined) { [result.id](http://result.id) = [inputObject.id](http://inputObject.id); } if (inputObject.user\_id !== undefined) { result.user\_id = inputObject.user\_id; } // ... (Field assignment logic for other properties) return result; } }

export { OrderList };

DB class:

typescript import { cloudDatabase } from '@kit.CloudFoundationKit';

class order\_list extends cloudDatabase.DatabaseObject { public id: number; public user\_id = 0; public order\_code: string; public order\_status: number; public order\_product\_id: string; public address: string; public nickname: string; public phone: string; public order\_remark: string; public pay\_type: string; public order\_create\_time: string; public order\_pay\_time: string; public order\_delivery\_time: string; public order\_over\_time: string;

public naturalbase\_ClassName(): string { return 'order\_list'; } }

export { order\_list };

After adding all the above, continue to add the corresponding data in the click event of the submit button:

typescript const orderPush = new order\_list(); [orderPush.id](http://orderPush.id) = Math.floor(Math.random() \* 1000000); orderPush.user\_id = this.user!.user\_id; orderPush.order\_product\_id = String(this.codeId); orderPush.order\_code = this.generateOrderNo(10); orderPush.order\_status = 0; if (this.remark !== '') { orderPush.order\_remark = this.remark; } orderPush.address = this.addressInfo.address; orderPush.nickname = this.addressInfo.nikeName; [orderPush.phone](http://orderPush.phone) = [this.addressInfo.phone](http://this.addressInfo.phone); orderPush.order\_create\_time = this.formatCurrentDate(); orderPush.order\_pay\_time = this.formatCurrentDate(); const num = await databaseZone.upsert(orderPush); [hilog.info](http://hilog.info)(0x0000, 'testTag', `Succeeded in upserting data, result: ${num}`);

After completing the above additions, clicking the submit button will implement the business logic of the order confirmation page.
