微信小程序

交友小程序后台管理

用 React + Vite + Tailwind CSS 搭一个交友小程序的后台管理系统:仪表盘、用户管理、活动管理、会员订单管理。

背景

小程序做完了,用户来了,活动也搞起来了。这时候你会需要一套后台管理系统——用来管用户、管活动、看订单。

这篇和 AI 交友小程序 配套使用。技术栈换成了 React + Vite + Tailwind CSS + Ant Design——不是小程序,是 Web 应用,跑在浏览器里。

完整链路只需要 4 步:

  1. 项目初始化 + 管理员登录(CloudBase 用户名密码认证)
  2. 仪表盘:数据总览 + 近 7 日趋势图
  3. 用户管理 + 活动管理:查看、编辑、审核
  4. 订单管理 + 会员管理:会员续费、订单查询

项目概览

技术栈

模块选型
框架React 18 + Vite
UIAnt Design
样式Tailwind CSS
状态管理Zustand(轻量)
路由React Router v6
图表Recharts
后端CloudBase SDK(Node.js)

为什么选 React + Vite + Tailwind CSS

  • React:组件生态最成熟,Ant Design 本身就是 React 组件库
  • Vite:开发热更新快,构建也快,不用 Webpack 了
  • Tailwind CSS:Ant Design 负责组件,Tailwind 负责间距、颜色、布局微调——二者互补不冲突
  • CloudBase SDK:后端调用云开发能力,不需要自己搭服务器

第一步:初始化项目 + 管理员登录

创建项目

npm create vite@latest dating-admin -- --template react-ts
cd dating-admin
pnpm install antd @ant-design/icons tailwindcss zustand react-router-dom recharts
pnpm install @cloudbase/js-sdk  # CloudBase 前端 SDK

管理员登录

和小程序端的手机号登录不同,后台使用的是 CloudBase 的 用户名密码认证

  1. 在云开发控制台 → 身份认证 → 开启用户名密码登录
  2. 手动创建管理员账号(不是开放注册)
  3. 前端用 CloudBase SDK 的 auth.signInWithUsernameAndPassword 登录
// src/pages/Login.jsx
import { useState } from 'react'
import { Form, Input, Button, message } from 'antd'
import cloudbase from '@cloudbase/js-sdk'

const app = cloudbase.init({
  env: 'your-env-id'
})

function Login() {
  const [loading, setLoading] = useState(false)

  const onFinish = async (values) => {
    setLoading(true)
    try {
      await app.auth().signInWithUsernameAndPassword(values)
      message.success('登录成功')
      // 跳转到后台
    } catch (err) {
      message.error('用户名或密码错误')
    }
    setLoading(false)
  }

  return (
    <div className="flex h-screen items-center justify-center bg-gray-50">
      <Form onFinish={onFinish} className="w-80">
        <h1 className="mb-6 text-xl font-bold text-center">管理后台</h1>
        <Form.Item name="username" rules={[{ required: true }]}>
          <Input placeholder="用户名" />
        </Form.Item>
        <Form.Item name="password" rules={[{ required: true }]}>
          <Input.Password placeholder="密码" />
        </Form.Item>
        <Button type="primary" htmlType="submit" loading={loading} block>
          登录
        </Button>
      </Form>
    </div>
  )
}

为什么后台不用微信登录? 管理员通常不是小程序用户,用用户名密码更简单。同一个 CloudBase 环境支持多种认证方式,互不冲突。

路由保护

// src/router.jsx
function RequireAuth({ children }) {
  const user = useCloudBaseUser()
  if (!user) return <Navigate to="/login" replace />
  return children
}

第二步:仪表盘

仪表盘显示四个核心指标 + 两个趋势图表。

布局

+----------------------------------+
| 总用户数 | 会员数 | 活动数 | 订单金额 |
+----------------------------------+
|                                    |
|  近 7 日新增用户(柱状图)          |
|                                    |
+----------------------------------+
|                                    |
|  近 7 日订单金额(柱状图)          |
|                                    |
+----------------------------------+

数据获取

通过 CloudBase SDK 调用云函数获取统计数据:

// 云函数 getDashboardStats
const cloud = require('wx-server-sdk')
cloud.init()
const db = cloud.database()

exports.main = async () => {
  const totalUsers = await db.collection('users').count()
  const vipUsers = await db.collection('users')
    .where({ isVip: true }).count()
  const totalOrders = await db.collection('member_orders').count()
  const totalRevenue = await db.collection('member_orders')
    .where({ status: 'paid' })
    .sum('totalFee')

  return { totalUsers, vipUsers, totalOrders, totalRevenue }
}

前端展示

使用 Ant Design 的 Card + Statistic 组件显示指标,Recharts 的 BarChart 显示趋势:

import { Card, Col, Row, Statistic } from 'antd'
import { BarChart, Bar, XAxis, YAxis, Tooltip } from 'recharts'

function Dashboard() {
  const { stats, chartData } = useDashboardData()

  return (
    <div>
      <Row gutter={16}>
        <Col span={6}>
          <Card><Statistic title="总用户数" value={stats.totalUsers} /></Card>
        </Col>
        <Col span={6}>
          <Card><Statistic title="会员数" value={stats.vipUsers} /></Card>
        </Col>
        {/* ... */}
      </Row>
      <BarChart width={600} height={300} data={chartData}>
        <Bar dataKey="count" fill="#1677ff" />
        <XAxis dataKey="date" />
        <Tooltip />
      </BarChart>
    </div>
  )
}

第三步:用户管理 + 活动管理

用户管理

用户表展示了注册用户的全部信息。使用 Ant Design 的 Table 组件:

const columns = [
  { title: '昵称', dataIndex: 'nickName' },
  { title: '手机号', dataIndex: 'phoneNumber' },
  { title: '城市', dataIndex: 'city' },
  { title: '会员', dataIndex: 'isVip', render: (v) => v ? '✅ 会员' : '非会员' },
  { title: '注册时间', dataIndex: 'createdAt' },
]

活动管理

活动管理需要 CRUD 操作:创建活动、编辑、查看报名列表、取消活动。

关键在于 MCP 协助创建和管理数据表——不需要手动写 SQL:

给 AI 的提示词示例: "在 CloudBase SQL 数据库中创建 events 表,包含 title, description, location, startTime, maxParticipants, currentCount, status 字段。并用 MCP 部署云函数 eventCRUD。"

第四步:订单管理 + 会员管理

订单管理

订单表展示所有会员购买记录:用户、金额、支付状态、支付时间、到期时间。

关键操作:

  • 查看订单详情
  • 手动补单(用户反馈已支付但没到账时)
  • 退款处理

会员管理

会员管理比订单管理多一层:可以看到当前所有会员、到期时间、是否续费。

管理员还可以手动给某个用户添加会员时长(比如活动赠送)。

与小程序共用同一套 CloudBase 环境

后台和小程序是同一个 CloudBase 环境——这意味着:

  • 同一张用户表:小程序用户注册后,后台直接能看到
  • 同一张活动表:后台发布活动 → 小程序用户看到
  • 同一张订单表:后台能查所有交易记录
// 后台读取同一张表
const db = cloudbase.database()
const allUsers = await db.collection('users').get()
const allOrders = await db.collection('member_orders').get()

重要:云函数的权限控制要区分"小程序用户调用"和"后台管理员调用"。小程序云函数通过 cloud.getWXContext() 判断用户身份;后台云函数需要通过 token 验证管理员身份。

关键教训

  1. 选 Ant Design + Tailwind CSS 不是二选一:Ant Design 负责表格、表单、日期选择器这些复杂组件,Tailwind 负责间距、布局、微调——它们互补
  2. 后台和小程序共用一套 CloudBase 环境,但权限要分开:小程序端云函数用 WXContext 做用户维度的权限控制,后台用单独的管理员验证逻辑
  3. MCP 建表 + 后端 SDK 调用的组合:建表、部署云函数用 MCP 做(AI 直接操作),前端展示和调用用 CloudBase SDK 做(代码中写)
  4. 不要把管理员身份写死在前端:通过 CloudBase 身份认证判断角色,而不是在前端硬编码管理员列表