微信小程序电商实战 04:微信云开发环境搭建与数据库设计

微信小程序电商实战 01 技术选型 | 02 脚手架搭建 | 03 NutUI 配置 | 04 云开发环境 ← 本文 | 05 商品模块 | 06 购物车与订单 | 07 微信支付 | 08 用户中心 | 09 性能优化 | 10 上线部署


# 微信云开发环境 ## 控制台配置 ### 创建云开发环境 - 开发环境(dev) - 生产环境(prod) ### 开通服务 - 云数据库 - 云存储 - 云函数 ## 数据库设计(6张表) ### products 商品表 - 基础信息 + SKU + 图片 ### categories 分类表 ### users 用户表 - openid + 地址列表 ### carts 购物车表 ### orders 订单表 - 状态机:待付→待发→待收→完成 ### order_items 订单商品表 ## 云存储 ### 商品图片目录结构 ### 上传权限配置 ## 云函数封装 ### callFunction 统一封装 ### 错误处理 ### TypeScript 类型 ## 权限配置 ### 数据库读写权限 ### 云存储上传权限

一、初始化云开发

1. 开通环境

在微信开发者工具中:

  1. 点击工具栏「云开发」按钮
  2. 创建环境,推荐创建两个:wxshop-dev(开发)和 wxshop-prod(生产)
  3. 记录两个环境的 环境 ID(格式类似 wxshop-dev-xxxxxx

2. 在 Taro 项目中初始化

// src/utils/cloud.ts
import Taro from '@tarojs/taro'

const ENV_ID = import.meta.env.VITE_CLOUD_ENV

let isInited = false

export function initCloud() {
  if (isInited) return
  // @ts-ignore — wx 对象在小程序运行时环境存在
  wx.cloud.init({
    env: ENV_ID,
    traceUser: true,
  })
  isInited = true
}

app.tsonLaunch 中调用:

// src/app.ts
import { initCloud } from '@/utils/cloud'

// app.vue 的 onLaunch
onLaunch() {
  initCloud()
}

二、数据库设计

云数据库是 MongoDB-like 的文档数据库,无需预先定义 Schema,但规划好结构对后续开发很重要。

flowchart LR A[users] -->|1:N| B[orders] B -->|1:N| C[order_items] C -->|N:1| D[products] D -->|N:1| E[categories] A -->|1:1| F[carts] F -->|引用| D

collections/products — 商品表

{
  "_id": "prod_001",
  "name": "经典白T恤",
  "categoryId": "cat_001",
  "price": 199,
  "originalPrice": 299,
  "coverImage": "cloud://wxshop-dev.xxx/products/prod_001/cover.jpg",
  "images": ["cloud://...", "cloud://..."],
  "description": "商品详细描述(富文本/图片列表)",
  "stock": 100,
  "soldCount": 256,
  "status": 1,
  "skuTree": [
    { "k": "颜色", "k_s": "s1", "v": [{ "id": 1, "name": "白色" }, { "id": 2, "name": "黑色" }] },
    { "k": "尺寸", "k_s": "s2", "v": [{ "id": 10, "name": "S" }, { "id": 11, "name": "M" }] }
  ],
  "skuList": [
    { "skuId": "sku_001", "s1": 1, "s2": 10, "price": 199, "stock": 50, "image": "" }
  ],
  "createdAt": "2026-01-01T00:00:00Z",
  "updatedAt": "2026-06-01T00:00:00Z"
}

collections/categories — 分类表

{
  "_id": "cat_001",
  "name": "上衣",
  "icon": "cloud://...",
  "sort": 1,
  "parentId": null
}

collections/users — 用户表

{
  "_id": "user_001",
  "_openid": "oXXXXX...",
  "nickName": "张三",
  "avatarUrl": "https://...",
  "phone": "138xxxx1234",
  "addresses": [
    {
      "id": "addr_001",
      "name": "张三",
      "phone": "138xxxx1234",
      "province": "广东省",
      "city": "深圳市",
      "district": "南山区",
      "detail": "科技园南区xx栋",
      "isDefault": true
    }
  ],
  "createdAt": "2026-01-01T00:00:00Z"
}

collections/orders — 订单表

{
  "_id": "order_202601010001",
  "_openid": "oXXXXX...",
  "orderNo": "20260101000001",
  "status": 1,
  "statusText": "待付款",
  "totalAmount": 398,
  "shippingAmount": 0,
  "address": { /* 快照,不引用原始地址 */ },
  "prepayId": "",
  "transactionId": "",
  "payTime": null,
  "shipTime": null,
  "receiveTime": null,
  "createdAt": "2026-06-01T10:00:00Z",
  "updatedAt": "2026-06-01T10:00:00Z"
}

订单状态机

stateDiagram-v2 [*] --> 待付款: 创建订单 待付款 --> 已取消: 超时/主动取消 待付款 --> 待发货: 支付成功 待发货 --> 待收货: 商家发货 待收货 --> 已完成: 确认收货 待收货 --> 售后中: 申请退货 已完成 --> 售后中: 申请售后 售后中 --> 已退款: 审核通过 已取消 --> [*] 已完成 --> [*] 已退款 --> [*]

collections/order_items — 订单商品表

{
  "_id": "oi_001",
  "orderId": "order_202601010001",
  "_openid": "oXXXXX...",
  "productId": "prod_001",
  "skuId": "sku_001",
  "productName": "经典白T恤",
  "skuDesc": "白色 / M",
  "coverImage": "cloud://...",
  "price": 199,
  "quantity": 2,
  "totalPrice": 398
}

三、云存储目录结构

cloud://wxshop-dev.xxx/
├── products/
│   ├── {productId}/
│   │   ├── cover.jpg      # 封面图(600x600)
│   │   ├── detail-1.jpg   # 详情图
│   │   └── detail-2.jpg
├── avatars/
│   └── {openid}.jpg
└── banners/
    └── banner-1.jpg

在云开发控制台 → 存储 → 权限设置中,将权限设为「所有用户可读,仅创建者可写」。


四、数据库权限配置

在云开发控制台 → 数据库 → 对应集合 → 权限设置:

集合 权限模式 说明
products 所有用户可读,仅管理端可写 商品信息公开
categories 所有用户可读,仅管理端可写 分类公开
users 仅创建者可读写 用户隐私
carts 仅创建者可读写 购物车隐私
orders 仅创建者可读,云函数写 订单用云函数操作
order_items 仅创建者可读,云函数写 同上

五、封装云函数调用层

统一封装,方便后续 Mock 和错误处理:

// src/api/cloud.ts
import Taro from '@tarojs/taro'

interface CloudResult<T = any> {
  data: T
  errMsg: string
}

export async function callCloud<T = any>(name: string, data: Record<string, any> = {}): Promise<T> {
  const res = await Taro.cloud.callFunction({
    name,
    data,
  }) as CloudResult<T>

  if (res.errMsg !== 'cloud.callFunction:ok') {
    throw new Error(res.errMsg)
  }

  return res.data
}
// src/api/product.ts
import { callCloud } from './cloud'
import type { Product } from '@/types/product'

export const getProductList = (params: { categoryId?: string; page: number; pageSize: number }) =>
  callCloud<{ list: Product[]; total: number }>('product', { action: 'list', ...params })

export const getProductDetail = (id: string) =>
  callCloud<Product>('product', { action: 'detail', id })

六、创建第一个云函数

cloudfunctions/ 目录下创建 product 云函数:

cloudfunctions/
└── product/
    ├── index.js
    └── package.json
// cloudfunctions/product/index.js
const cloud = require('wx-server-sdk')
cloud.init({ env: cloud.DYNAMIC_CURRENT_ENV })
const db = cloud.database()

exports.main = async (event) => {
  const { action } = event

  if (action === 'list') {
    const { categoryId, page = 1, pageSize = 10 } = event
    const query = db.collection('products').where({ status: 1 })
    if (categoryId) query.where({ categoryId })

    const [countRes, listRes] = await Promise.all([
      query.count(),
      query.skip((page - 1) * pageSize).limit(pageSize).get(),
    ])

    return { list: listRes.data, total: countRes.total }
  }

  if (action === 'detail') {
    const res = await db.collection('products').doc(event.id).get()
    return res.data
  }

  return { error: 'unknown action' }
}

在微信开发者工具中右键 cloudfunctions/product → 「上传并部署」。


微信小程序电商实战 01 技术选型 | 02 脚手架搭建 | 03 NutUI 配置 | 04 云开发环境 ← 本文 | 05 商品模块 | 06 购物车与订单 | 07 微信支付 | 08 用户中心 | 09 性能优化 | 10 上线部署

实操清单

  • 在微信开发者工具开通云开发,创建 dev 和 prod 两个环境,记录环境 ID
  • 将环境 ID 填入 .env.development.env.production
  • app.vueonLaunch 中调用 initCloud(),运行后控制台无报错
  • 在云数据库控制台创建 6 个集合:products、categories、users、carts、orders、order_items
  • 按本文设计配置各集合的读写权限
  • 在 products 集合手动插入一条测试商品数据
  • 配置云存储权限为「所有用户可读,仅创建者可写」,上传一张测试图片
  • 创建 src/api/cloud.ts 统一封装 callCloud()
  • 创建 cloudfunctions/product/index.js,实现 list 和 detail action
  • 在微信开发者工具中上传部署 product 云函数
  • 在小程序端调用 getProductList() 并打印结果,验证云函数调用通路畅通