1.配置App主导航菜单:

在生成纯血鸿蒙App项目之前,我们需要为该App配置MainTab菜单。点击页面设计模块下的“会员菜单”,然后点击页面右上角的“新增导航模块”按钮。

2.如下图所示,为该导航模块命名(英文名称、中文名称),导航类型要选择“App主导航”,然后点击“保存信息”按钮:


3.在导航模块预览界面,点击“新增菜单”图标:

4.如下图所示,为主导航菜单增加菜单:

5.用相同方法,为鸿蒙App主导航增加最多5个菜单,创建完后结果如下图所示:

6.侧栏菜单选择“纯血鸿蒙”,然后点击“代码魔法棒”图标,在确认面板中点击“确认”按钮:

7.一秒生成生产级纯血鸿蒙项目工程。如下图所示:

8.以下是部分订单相关页面的代码,包含UI排版、TS校验及后端接口访问。创建订单页代码如下:

import {
  A_Button,
  A_TextField,
  A_TitleBar,
  SideBar,
  ColorConstants,
  FloatConstants,
  GirdConstants,
  Validator,
  AlertUtils,
  HttpUtils,
  WindowUtils,
  Logger
} from '@ohos/commons'
import { emitter } from '@kit.BasicServicesKit'
import { BusinessError } from '@kit.BasicServicesKit'
import { OrderCreateDTO } from '../viewmodel/OrderCreateDTO'

const orderNumRules = new Validator([
  (v: string) => !!v.trim() || "订单号:不能为空",
  (v: string) => v.length <= 50 || "订单号:最长不能超过50个字符",
])
const amountRules = new Validator([
  (v: string) => v !== null || "订单金额:不能为null",
  (v: string) => Number(v) >= 0.00 || "订单金额:必须大于或等于0.00",
  (v: string) => Number(v) <= 100.00 || "订单金额:必须小于或等于100.00",
  (v: string) => {
    const integerPart = 10
    const fractionPart = 2
    const regExp = new RegExp(`^\\d{1,${integerPart}}(\\.\\d{0,${fractionPart}})?$`)
    return regExp.test(v) || "订单金额:数字的值只允许在10位整数和2位小数范围内"
  }
])
const memoRules = new Validator([
  (v: string) => !!v.trim() || "订单描述:不能为空",
  (v: string) => v.length <= 50 || "订单描述:最长不能超过50个字符",
])

/**
 * 新增订单
 * @author 极客学院
 * @date 2025/03/20
 */
@Component
export struct CreateView {
  @StorageLink('pageInfo') pageInfo: NavPathStack = new NavPathStack()
  @StorageLink('primaryColor') primaryColor: ResourceStr = ColorConstants.INFO
  @StorageLink('deviceType') deviceType: string = GirdConstants.DEVICE_SM
  @StorageLink('showSideBar') showSideBar: boolean = false

  @State params:[] = []
  @State errorMessages:[] = []
  @State loading:boolean = false

  // 表单校验
  private validateForm(): boolean {
    this.errorMessages = [] // 重置错误消息

    const orderNumResult = orderNumRules.validate(this.params['orderNum'])
    if (orderNumResult !== true) {
      AlertUtils.showErrorMessage(orderNumResult as string)
      return false
    }

    const amountResult = amountRules.validate(this.params['amount'])
    if (amountResult !== true) {
      AlertUtils.showErrorMessage(amountResult as string)
      return false
    }

    const memoResult = memoRules.validate(this.params['memo'])
    if (memoResult !== true) {
      AlertUtils.showErrorMessage(memoResult as string)
      return false
    }

    return true
  }

  aboutToAppear() {
    WindowUtils.getInstance()?.setFullScreen()
  }

  // 提交新增订单的请求
  async handleCreate() {
    if(!this.loading && this.validateForm()){
      this.loading = true
      const dto: OrderCreateDTO = new OrderCreateDTO(
        this.params['orderNum'],
        this.params['amount'],
        this.params['memo']
      )
      await HttpUtils.post(
        `/demo/order/user/create`,
        dto
      )
        .then((res) => {
          AlertUtils.showSuccessMessage("成功创建订单!")
          // TODO 请确认以下发送事件的名称和将要返回的上一级页面(通常是列表页)中订阅/取消的事件名称一致
          emitter.emit("OrderUpdate")
          this.pageInfo.pop()
        }).catch((error: BusinessError) => {
          Logger.error(`提交新增订单的请求:操作失败。 Code:${error.code}, message:${error.message}`)
        }).finally(() => {
          this.loading = false
        })
    }
  }

  build() {
    SideBarContainer(this.deviceType === GirdConstants.DEVICE_LG ? SideBarContainerType.Embed : SideBarContainerType.Overlay) {
      SideBar()

      Stack() {
        if (this.deviceType !== GirdConstants.DEVICE_LG) {
          Column()
            .height(GirdConstants.FULL_PERCENT)
            .width(GirdConstants.FULL_PERCENT)
            .backgroundColor(ColorConstants.TOAST_BG)
            .zIndex(1)
            .visibility(this.showSideBar ? Visibility.Visible : Visibility.Hidden)
        }

        Row() {
          Column() {
            // 标题栏
            A_TitleBar({text: '新增订单'})
              .padding({
                left: this.showSideBar ? GirdConstants.ZERO : GirdConstants.THIRTY,
                right: this.showSideBar ? GirdConstants.ZERO : GirdConstants.THIRTY
              })

            // 下拉容器
            Scroll() {
              GridRow({
                columns: { sm: GirdConstants.GRID_COLUMNS[0], md: GirdConstants.GRID_COLUMNS[1], lg: this.showSideBar ? GirdConstants.GRID_COLUMNS[1] : GirdConstants.GRID_COLUMNS[2] },
                gutter: { x: GirdConstants.GRID_GUTTER, y: GirdConstants.GRID_GUTTER },
                breakpoints: { reference: BreakpointsReference.WindowSize } }) {

                GridCol({ span: 4 }) {
                  A_TextField({
                    params: this.params,
                    name: 'orderNum',
                    label: '订单号',
                    modelValue: this.params['orderNum'],
                    placeholder: '请输入订单号',
                    color: this.primaryColor,
                    rules: orderNumRules,
                    errorMessages: this.errorMessages['orderNum'],
                  })
                }

                GridCol({ span: 4 }) {
                  A_TextField({
                    params: this.params,
                    name: 'amount',
                    label: '订单金额',
                    modelValue: this.params['amount'],
                    placeholder: '请输入订单金额',
                    color: this.primaryColor,
                    rules: amountRules,
                    errorMessages: this.errorMessages['amount'],
                  })
                }

                GridCol({ span: 4 }) {
                  A_TextField({
                    params: this.params,
                    name: 'memo',
                    label: '订单描述',
                    modelValue: this.params['memo'],
                    placeholder: '请输入订单描述',
                    color: this.primaryColor,
                    rules: memoRules,
                    errorMessages: this.errorMessages['memo'],
                  })
                }

                GridCol({ span: 12 }) {
                  Column({ space: GirdConstants.FIFTEEN }){
                    Divider()
                    Row({ space: GirdConstants.EIGHT }){
                      Blank()
                      A_Button({
                        text: '返回列表'
                      })
                        .onClick(() => {
                          this.pageInfo.pop()
                        })
                      A_Button({
                        text: '保存信息',
                        loading: this.loading
                      })
                        .onClick(() => {
                          this.handleCreate()
                        })
                      Blank()
                    }
                  }
                  .width(GirdConstants.FULL_PERCENT)
                }

              }
            }
            .scrollBar(BarState.Off)
          }
          .height(GirdConstants.FULL_PERCENT)
        }
        .alignItems(VerticalAlign.Top)
        .padding({
          top: FloatConstants.SPACE_TOP,
          left: FloatConstants.SPACE_LEFT,
          right: FloatConstants.SPACE_RIGHT,
          bottom: GirdConstants.GRID_BOTTOM
        })
        .width(GirdConstants.FULL_PERCENT)
        .backgroundColor(ColorConstants.APP_BG)
      }
    }
    .controlButton({
      top: GirdConstants.FIFTY_SIX,
      width: GirdConstants.TWENTY_FOUR,
      height: GirdConstants.TWENTY_FOUR
    })
    .showSideBar(this.showSideBar && this.deviceType === GirdConstants.DEVICE_LG)
    .onChange((value: boolean) => {
      this.showSideBar = value
    })
    .height(GirdConstants.FULL_PERCENT)
  }
}

订单列表页代码如下:

import {
  A_TitleBar,
  A_SubTitle1,
  A_Body1,
  A_Button,
  A_Pagination,
  SideBar,
  ColorConstants,
  FloatConstants,
  GirdConstants,
  AlertUtils,
  HttpUtils,
  WindowUtils,
  Logger
} from '@ohos/commons'
import { AlertDialog } from '@kit.ArkUI'
import { emitter } from '@kit.BasicServicesKit'
import { BusinessError } from '@kit.BasicServicesKit'
import { OrderVO } from '../viewmodel/OrderVO'

/**
 * 订单列表
 * @author 极客学院
 * @date 2025/03/20
 */
@Component
export struct ListView {
  @StorageLink('pageInfo') pageInfo: NavPathStack = new NavPathStack()
  @StorageLink('primaryColor') primaryColor: ResourceStr = ColorConstants.INFO
  @StorageLink('deviceType') deviceType: string = GirdConstants.DEVICE_SM
  @StorageLink('showSideBar') showSideBar: boolean = false

  @State selectId: number = 0
  @State dataList: Array<OrderVO> = []
  @State totalItems: number = 0

  // TODO 修正list接口扩展参数赋值
  @State listExtendParams: Record<string, string> = {
    'keyword': '',
    'page': '1',
    'size': '10',
    'sortBy': 'orderId'
  }

  // TODO 修正remove接口路径参数赋值
  @State removePathParams: Record<string, string> = {
    'orderId': '0'
  }

  // 列表页订阅的事件(请与新增表单和修改表单中的事件名称一致)
  eventId: string = 'OrderUpdate'
  controller: SearchController = new SearchController()

  aboutToAppear() {
    this.fetchData()
    emitter.on(this.eventId, () => {
      this.fetchData()
    })
    WindowUtils.getInstance()?.setFullScreen()
  }

  aboutToDisappear(){
    emitter.off(this.eventId)
  }

  // 订单列表
  async fetchData() {
    if(Number(this.listExtendParams.page) > 0) {
      this.listExtendParams.page = (Number(this.listExtendParams.page) - 1).toString()
    }

    await HttpUtils.get(
      `/demo/order/user/list`,
      this.listExtendParams
    )
      .then((res) => {
        this.dataList = res.result['list']
        this.totalItems = res.result['total']
      }).catch((error: BusinessError) => {
        Logger.error(`订单列表:请求失败。 Code:${error.code}, message:${error.message}`)
      })
  }

  // 删除确认
  dialogControllerConfirm: CustomDialogController = new CustomDialogController({
    builder: AlertDialog({
      primaryTitle: '确认删除',
      content: '您确定要删除此订单吗?此操作无法撤销。',
      primaryButton: {
        value: '取消',
        action: () => {
        },
      },
      secondaryButton: {
        value: '确认',
        role: ButtonRole.ERROR,
        action: () => {
          this.confirmDelete()
        }
      },
    }),
  })

  // 删除一条订单信息(非物理删除)
  async confirmDelete() {
    await HttpUtils.delete(
      `/demo/order/user/remove/${this.removePathParams['orderId']}`
    )
      .then((res) => {
        AlertUtils.showSuccessMessage("已成功删除该订单!")
        // 更新列表数据
        this.fetchData()
      }).catch((error: BusinessError) => {
        Logger.error(`删除一条订单信息(非物理删除):操作失败。 Code:${error.code}, message:${error.message}`)
      })
  }

  build() {
    SideBarContainer(this.deviceType === GirdConstants.DEVICE_LG ? SideBarContainerType.Embed : SideBarContainerType.Overlay) {
      SideBar()

      Stack() {
        if (this.deviceType !== GirdConstants.DEVICE_LG) {
          Column()
            .height(GirdConstants.FULL_PERCENT)
            .width(GirdConstants.FULL_PERCENT)
            .backgroundColor(ColorConstants.TOAST_BG)
            .zIndex(1)
            .visibility(this.showSideBar ? Visibility.Visible : Visibility.Hidden)
        }

        Row() {
          Column() {
            // 标题栏
            A_TitleBar({text: '订单列表'})
              .padding({
                left: this.showSideBar ? GirdConstants.ZERO : GirdConstants.THIRTY,
                right: this.showSideBar ? GirdConstants.ZERO : GirdConstants.THIRTY
              })

            // 下拉容器
            Scroll() {
              GridRow({
                columns: { sm: GirdConstants.GRID_COLUMNS[0], md: GirdConstants.GRID_COLUMNS[1], lg: this.showSideBar ? GirdConstants.GRID_COLUMNS[1] : GirdConstants.GRID_COLUMNS[2] },
                gutter: { x: GirdConstants.GRID_GUTTER, y: GirdConstants.GRID_GUTTER },
                breakpoints: { reference: BreakpointsReference.WindowSize } }) {

                // 搜索栏
                GridCol({ span: 12 }) {
                  Row(){
                    Search({ value: this.listExtendParams['keyword'].toString(), placeholder: '搜索订单...', controller: this.controller })
                      .searchButton('搜索')
                      .width(GirdConstants.SIXTY_PERCENT)
                      .height(FloatConstants.HEIGHT_INPUT)
                      .placeholderColor(ColorConstants.FG_LEVEL3)
                      .placeholderFont({
                        size: FloatConstants.FONT_SIZE_BODY2,
                        weight: FontWeight.Normal
                      })
                      .textFont({ size: FloatConstants.FONT_SIZE_BODY2, weight: Number(FloatConstants.FONT_WEIGHT_BODY2) })
                      .onSubmit((value: string) => {
                        this.listExtendParams['keyword'] = value
                        this.fetchData()
                      })
                      .margin(this.deviceType!==GirdConstants.DEVICE_SM ? GirdConstants.TWENTY : null)

                    Blank()

                    A_Button({
                      text: '新增订单',
                      icon: this.deviceType!==GirdConstants.DEVICE_SM ? 'mdi-plus' : undefined
                    })
                      .margin({ right: this.deviceType!==GirdConstants.DEVICE_SM ? GirdConstants.TWENTY : null })
                      .onClick(() => {
                        // TODO 根据实际情况调整路由
                        this.pageInfo.pushPathByName('OrderCreate', null)
                      })
                  }
                  .width(GirdConstants.FULL_PERCENT)
                  .height(GirdConstants.EIGHTY)
                  .padding(GirdConstants.EIGHT)
                  .borderRadius(FloatConstants.RADIUS_CARD)
                  .backgroundColor(ColorConstants.CARD_BG)
                }

                // 表格
                GridCol({ span: 12 }) {
                  List() {
                    ListItem(){
                      Grid() {
                        // 表格头
                        GridItem() {
                          A_SubTitle1({ text: '订单ID', color: ColorConstants.WHITE })
                        }
                        .backgroundColor(this.primaryColor)
                        .border({
                          width: { right: 1 },
                          color: ColorConstants.TOAST_BG
                        })

                        GridItem() {
                          A_SubTitle1({ text: '订单号', color: ColorConstants.WHITE })
                        }
                        .backgroundColor(this.primaryColor)
                        .border({
                          width: { right: 1 },
                          color: ColorConstants.TOAST_BG
                        })

                        GridItem() {
                          A_SubTitle1({ text: '订单金额', color: ColorConstants.WHITE })
                        }
                        .backgroundColor(this.primaryColor)
                        .border({
                          width: { right: 1 },
                          color: ColorConstants.TOAST_BG
                        })

                        GridItem() {
                          A_SubTitle1({ text: '订单描述', color: ColorConstants.WHITE })
                        }
                        .backgroundColor(this.primaryColor)
                        .border({
                          width: { right: 1 },
                          color: ColorConstants.TOAST_BG
                        })

                        GridItem() {
                          A_SubTitle1({ text: '操作', color: ColorConstants.WHITE })
                        }
                        .backgroundColor(this.primaryColor) 

                        // 表格体
                        ForEach(this.dataList, (item: OrderVO, index: number) => {
                          GridItem() {
                            A_Body1( { text: `${item.orderId}` } )
                          }
                          .backgroundColor(index%2===0 ? ColorConstants.APP_BG: ColorConstants.TOAST_BG)
                          .border({
                            width: { right: 1 },
                            color: ColorConstants.TOAST_BG
                          })

                          GridItem() {
                            A_Body1( { text: `${item.orderNum}` } )
                          }
                          .backgroundColor(index%2===0 ? ColorConstants.APP_BG: ColorConstants.TOAST_BG)
                          .border({
                            width: { right: 1 },
                            color: ColorConstants.TOAST_BG
                          })

                          GridItem() {
                            A_Body1( { text: `${item.amount}` } )
                          }
                          .backgroundColor(index%2===0 ? ColorConstants.APP_BG: ColorConstants.TOAST_BG)
                          .border({
                            width: { right: 1 },
                            color: ColorConstants.TOAST_BG
                          })

                          GridItem() {
                            A_Body1( { text: `${item.memo}` } )
                          }
                          .backgroundColor(index%2===0 ? ColorConstants.APP_BG: ColorConstants.TOAST_BG)
                          .border({
                            width: { right: 1 },
                            color: ColorConstants.TOAST_BG
                          })

                          GridItem() {
                            Row({ space: GirdConstants.TWELVE }){
                              Blank()

                              // 转向订单详情页
                              Image($r('app.media.mdi_file_eye_outline'))
                                .width(GirdConstants.TWENTY)
                                .height(GirdConstants.TWENTY)
                                .fillColor(ColorConstants.FG_LEVEL1)
                                .onClick(() => {
                                  // TODO 根据实际情况调整路由
                                  this.pageInfo.pushPathByName('OrderDetail', item.orderId)
                                })

                              // 转向编辑订单表单页
                              Image($r('app.media.mdi_pencil_outline'))
                                .width(GirdConstants.TWENTY)
                                .height(GirdConstants.TWENTY)
                                .fillColor(ColorConstants.INFO)
                                .onClick(() => {
                                  // TODO 根据实际情况调整路由
                                  this.pageInfo.pushPathByName('OrderModify', item.orderId)
                                })

                              // 删除确认
                              Image($r('app.media.mdi_delete_outline'))
                                .width(GirdConstants.TWENTY)
                                .height(GirdConstants.TWENTY)
                                .fillColor(ColorConstants.DANGER)
                                .onClick(() => {
                                  this.selectId = item.orderId
                                  this.dialogControllerConfirm.open()
                                })

                              Blank()
                            }
                          }
                          .backgroundColor(index%2===0 ? ColorConstants.APP_BG: ColorConstants.TOAST_BG)

                        },  (item: OrderVO, index: number) => index + JSON.stringify(item))
                      }
                      .columnsTemplate('1fr 1fr 1fr 1fr 1fr') // 此处可设置各列的宽度比例
                      .rowsTemplate('repeat(auto-fit, 40)')
                      .width(this.deviceType===GirdConstants.DEVICE_LG ? GirdConstants.FULL_PERCENT : 1200)
                      .backgroundColor(ColorConstants.CARD_BG)
                      .height(GirdConstants.FORTY * (this.dataList.length + (this.dataList.length===0 ? 1 :2)))
                      .borderWidth(1)
                      .borderColor(ColorConstants.TOAST_BG)
                      .borderRadius(this.deviceType===GirdConstants.DEVICE_LG ? FloatConstants.RADIUS_S : null)
                    }
                  }
                  .scrollBar(BarState.Off)
                  .listDirection(Axis.Horizontal)
                }

                // 翻页
                GridCol({ span: 12 }) {
                  A_Pagination({
                    pageConfig: this.listExtendParams,
                    eventId: this.eventId,
                    totalItems: this.totalItems
                  })
                }

              }
            }
            .scrollBar(BarState.Off)
          }
          .height(GirdConstants.FULL_PERCENT)
        }
        .alignItems(VerticalAlign.Top)
        .padding({
          top: FloatConstants.SPACE_TOP,
          left: FloatConstants.SPACE_LEFT,
          right: FloatConstants.SPACE_RIGHT,
          bottom: GirdConstants.GRID_BOTTOM
        })
        .width(GirdConstants.FULL_PERCENT)
        .backgroundColor(ColorConstants.APP_BG)
      }
    }
    .controlButton({
      top: GirdConstants.FIFTY_SIX,
      width: GirdConstants.TWENTY_FOUR,
      height: GirdConstants.TWENTY_FOUR
    })
    .showSideBar(this.showSideBar && this.deviceType === GirdConstants.DEVICE_LG)
    .onChange((value: boolean) => {
      this.showSideBar = value
    })
    .height(GirdConstants.FULL_PERCENT)
  }
}

详细操作可去官网免费体验


华哥的全栈次元舱
1 声望0 粉丝