鸿蒙 DevEco Studio HarmonyOS5实现购物功能的基础功能的实现

213 阅读3分钟

在鸿蒙(HarmonyOS)生态中使用 ​​DevEco Studio​​ 实现购物应用的基础功能(如商品展示、购物车、订单管理),可以通过以下步骤完成。这里以 ​​ArkTS​​(推荐语言)为例,提供核心代码和实现逻辑。


​1. 基础功能实现​

​1.1 商品列表展示​

​功能需求​

  • 从本地或网络加载商品数据。
  • 使用 List 组件展示商品图片、名称、价格等信息。

​代码实现​

typescript
复制
// 商品数据类型
interface Product {
  id: number;
  name: string;
  price: number;
  image: string; // 图片资源路径或URL
}

@Entry
@Component
struct ProductList {
  // 模拟商品数据
  @State products: Product[] = [
    { id: 1, name: "华为Mate 60", price: 5999, image: "common/images/mate60.jpg" },
    { id: 2, name: "FreeBuds Pro", price: 999, image: "common/images/freebuds.jpg" },
    { id: 3, name: "Watch GT 4", price: 1499, image: "common/images/watch.jpg" },
  ];

  build() {
    List({ space: 10 }) {
      ForEach(this.products, (product: Product) => {
        ListItem() {
          Row() {
            Image(product.image)
              .width(100)
              .height(100)
              .borderRadius(8)
            Column() {
              Text(product.name)
                .fontSize(16)
                .fontWeight(FontWeight.Bold)
              Text(`¥${product.price}`)
                .fontColor(Color.Red)
            }.margin({ left: 10 })
          }
          .padding(10)
          .width('100%')
        }
      })
    }
    .width('100%')
    .height('100%')
  }
}

​1.2 购物车功能​

1. 购物车数据模型

创建购物车项数据类 CartItem.java

java

public class CartItem {
    private Product product;
    private int quantity;

    public CartItem(Product product, int quantity) {
        this.product = product;
        this.quantity = quantity;
    }

    public Product getProduct() {
        return product;
    }

    public void setProduct(Product product) {
        this.product = product;
    }

    public int getQuantity() {
        return quantity;
    }

    public void setQuantity(int quantity) {
        this.quantity = quantity;
    }

    public void increaseQuantity() {
        this.quantity++;
    }

    public void decreaseQuantity() {
        if (quantity > 1) {
            this.quantity--;
        }
    }

    public double getSubtotal() {
        return product.getPrice() * quantity;
    }
}

2. 购物车管理类

创建单例模式的购物车管理类 CartManager.java

java

public class CartManager {
    private static CartManager instance;
    private List<CartItem> cartItems;
    private Context context;

    private CartManager() {
        cartItems = new ArrayList<>();
    }

    public static CartManager getInstance() {
        if (instance == null) {
            synchronized (CartManager.class) {
                if (instance == null) {
                    instance = new CartManager();
                }
            }
        }
        return instance;
    }

    public void init(Context context) {
        this.context = context;
        // 从本地数据库或缓存加载购物车数据
        loadCartFromStorage();
    }

    // 添加商品到购物车
    public void addProduct(Product product, int quantity) {
        for (CartItem item : cartItems) {
            if (item.getProduct().getId().equals(product.getId())) {
                item.increaseQuantity();
                saveCartToStorage();
                return;
            }
        }
        cartItems.add(new CartItem(product, quantity));
        saveCartToStorage();
    }

    // 从购物车移除商品
    public void removeProduct(Product product) {
        cartItems.removeIf(item -> item.getProduct().getId().equals(product.getId()));
        saveCartToStorage();
    }

    // 更新购物车中商品数量
    public void updateProductQuantity(Product product, int quantity) {
        for (CartItem item : cartItems) {
            if (item.getProduct().getId().equals(product.getId())) {
                if (quantity <= 0) {
                    cartItems.remove(item);
                } else {
                    item.setQuantity(quantity);
                }
                saveCartToStorage();
                break;
            }
        }
    }

    // 获取购物车所有商品
    public List<CartItem> getCartItems() {
        return new ArrayList<>(cartItems);
    }

    // 获取购物车商品总数
    public int getTotalItemCount() {
        return cartItems.stream().mapToInt(CartItem::getQuantity).sum();
    }

    // 获取购物车商品总价
    public double getTotalAmount() {
        return cartItems.stream().mapToDouble(CartItem::getSubtotal).sum();
    }

    // 保存购物车到存储
    private void saveCartToStorage() {
        if (context != null) {
            // 使用鸿蒙的Preferences存储简单数据
            Preferences preferences = Preferences.create(context, "shopping_cart");
            preferences.putString("cart_items", new Gson().toJson(cartItems));
            preferences.flush();
        }
    }

    // 从存储加载购物车
    private void loadCartFromStorage() {
        if (context != null) {
            Preferences preferences = Preferences.create(context, "shopping_cart");
            String cartJson = preferences.getString("cart_items", "[]");
            cartItems = new Gson().fromJson(cartJson, new TypeToken<List<CartItem>>() {
            }.getType());
            if (cartItems == null) {
                cartItems = new ArrayList<>();
            }
        }
    }
}

3. 购物车页面设计

创建购物车页面 CartAbility.java 及其布局文件 cart_layout.xml

xml

<!-- cart_layout.xml -->
<DirectionalLayout
    xmlns:ohos="http://schemas.huawei.com/res/ohos"
    ohos:height="match_parent"
    ohos:width="match_parent"
    ohos:orientation="vertical">
    
    <!-- 购物车标题栏 -->
    <DirectionalLayout
        ohos:height="56vp"
        ohos:width="match_parent"
        ohos:background="#FFFFFF"
        ohos:orientation="horizontal"
        ohos:padding="16vp">
        
        <Text
            ohos:height="match_content"
            ohos:width="match_content"
            ohos:text="购物车"
            ohos:text_color="#333333"
            ohos:text_size="18sp"
            ohos:text_weight="bold"/>
    </DirectionalLayout>
    
    <!-- 购物车商品列表 -->
    <ListContainer
        ohos:id="$+id/cart_list"
        ohos:height="0vp"
        ohos:width="match_parent"
        ohos:layout_weight="1"/>
    
    <!-- 空购物车提示 -->
    <DirectionalLayout
        ohos:id="$+id/empty_cart_container"
        ohos:height="match_parent"
        ohos:width="match_parent"
        ohos:alignment="center"
        ohos:orientation="vertical"
        ohos:visibility="gone">
        
        <Image
            ohos:height="120vp"
            ohos:width="120vp"
            ohos:image_src="$media:empty_cart"/>
        
        <Text
            ohos:height="wrap_content"
            ohos:width="wrap_content"
            ohos:margin="top=24vp"
            ohos:text="购物车空空如也"
            ohos:text_color="#999999"
            ohos:text_size="16sp"/>
        
        <Text
            ohos:height="wrap_content"
            ohos:width="wrap_content"
            ohos:margin="top=8vp"
            ohos:text="快去挑选喜欢的商品吧"
            ohos:text_color="#999999"
            ohos:text_size="14sp"/>
        
        <Button
            ohos:id="$+id/go_shopping_btn"
            ohos:height="48vp"
            ohos:width="200vp"
            ohos:background="#007DFF"
            ohos:border_radius="24vp"
            ohos:margin="top=32vp"
            ohos:text="去购物"
            ohos:text_color="white"
            ohos:text_size="16sp"/>
    </DirectionalLayout>
    
    <!-- 底部结算栏 -->
    <DirectionalLayout
        ohos:height="72vp"
        ohos:width="match_parent"
        ohos:background="#FFFFFF"
        ohos:orientation="horizontal"
        ohos:padding="16vp 0vp">
        
        <CheckBox
            ohos:id="$+id/select_all"
            ohos:height="match_content"
            ohos:width="match_content"
            ohos:checked="true"/>
        
        <Text
            ohos:height="match_content"
            ohos:width="wrap_content"
            ohos:margin="left=8vp"
            ohos:text="全选"
            ohos:text_color="#333333"
            ohos:text_size="14sp"/>
        
        <DirectionalLayout
            ohos:height="match_parent"
            ohos:width="0vp"
            ohos:layout_weight="1"
            ohos:alignment="center_vertical"
            ohos:orientation="horizontal"
            ohos:padding="left=24vp">
            
            <Text
                ohos:height="wrap_content"
                ohos:width="wrap_content"
                ohos:text="合计:"
                ohos:text_color="#333333"
                ohos:text_size="14sp"/>
            
            <Text
                ohos:id="$+id/total_amount"
                ohos:height="wrap_content"
                ohos:width="wrap_content"
                ohos:margin="left=4vp"
                ohos:text="¥0.00

​1.3 订单提交(模拟HTTP请求)​

​功能需求​

  • 提交购物车数据到后端(模拟API)。
  • 使用 @ohos.net.http 发送网络请求。

​代码实现​

typescript
复制
import http from '@ohos.net.http';

// 模拟订单提交
async function submitOrder(cartItems: CartItem[]): Promise<boolean> {
  const httpRequest = http.createHttp();
  const url = "https://api.example.com/orders";
  const data = JSON.stringify({ items: cartItems });

  try {
    const response = await httpRequest.request(
      url,
      { method: "POST", header: { "Content-Type": "application/json" }, extraData: data }
    );
    return response.responseCode === 200;
  } catch (error) {
    console.error("订单提交失败:", error);
    return false;
  }
}

// 在购物车页面调用
Button("提交订单")
  .onClick(async () => {
    const success = await submitOrder(this.cartItems);
    if (success) {
      alert("订单提交成功!");
      this.cartItems = []; // 清空购物车
    }
  })

​2. 进阶优化​

​2.1 数据持久化​

  • 使用 @ohos.data.storage 存储购物车数据,避免页面刷新后丢失:
typescript
复制
import storage from '@ohos.data.storage';

const storageKey = "cartData";
const context = getContext(this);

// 保存购物车数据
function saveCart(items: CartItem[]) {
  const storage = storage.getStorageSync(context, "CartDB");
  storage.putSync(storageKey, JSON.stringify(items));
  storage.flushSync();
}

// 读取购物车数据
function loadCart(): CartItem[] {
  const storage = storage.getStorageSync(context, "CartDB");
  const data = storage.getSync(storageKey, "[]");
  return JSON.parse(data);
}

​2.2 多设备协同​

  • 通过 分布式数据管理 实现手机/平板同步购物车:
typescript
复制
import distributedData from '@ohos.data.distributedData';

// 初始化分布式数据
const kvManager = distributedData.createKVManager({
  bundleName: "com.example.shop",
  options: { syncPolicy: "DEVICE_COLLABORATION" }
});

// 同步购物车数据
async function syncCart() {
  const kvStore = await kvManager.getKVStore("cartStore");
  await kvStore.put("cartItems", JSON.stringify(this.cartItems));
}

​3. 运行效果​


​4. 完整项目结构​

markdown
复制
resources/
  ├── base/
  │   ├── element/    // 字符串和样式
  │   └── media/      // 图片资源
src/
  ├── main/
  │   ├── ets/
  │   │   ├── pages/
  │   │   │   ├── ProductList.ets  // 商品列表
  │   │   │   ├── Cart.ets         // 购物车逻辑
  │   │   │   └── Order.ets        // 订单提交
  │   │   └── utils/
  │   │       ├── http.ets         // 网络请求封装
  │   │       └── storage.ets      // 数据持久化
  │   └── resources/  // 资源文件

​5. 常见问题​

  1. ​图片加载失败​

    • 确保图片路径正确,或使用网络图片时添加 ohos.permission.INTERNET 权限。
  2. ​购物车数据不同步​

    • 检查 @State 和 @Link 的使用,或改用 AppStorage 全局状态管理。
  3. ​HTTP请求报错​

    • 在 module.json5 中声明网络权限:
    json
    复制
    {
      "requestPermissions": [
        { "name": "ohos.permission.INTERNET" }
      ]
    }