分享一套【优质Java源码】微信小程序系统小店会员管理(适合理发店,宠物店等各种小店),使用 云函数 + 云数据库

0 阅读3分钟

大家好,我是java1234_小锋老师,分享一套微信小程序系统小店会员管理(适合理发店,宠物店等各种小店),使用 云函数 + 云数据库  。

未命名.jpg

项目简介

随着移动互联网的快速发展和微信生态的日益完善,微信小程序凭借其"即用即走"、无需安装的特点,成为线下商户数字化转型的重要工具。传统线下小店在会员管理方面普遍存在管理方式落后、信息化程度低、会员信息易丢失等问题,严重影响了门店的运营效率和服务质量。

本文设计并实现了一个基于微信小程序的小店会员管理系统,采用微信云开发技术架构,前端使用微信小程序原生框架(WXML/WXSS/JS),后端采用云函数(Node.js)作为服务层,数据存储使用微信云数据库(文档型NoSQL数据库)。系统实现了用户手机号授权登录、会员储值充值、消费扣费管理、消费与充值流水查询、店铺信息展示与管理、消费项目与常用价格维护等核心功能。系统采用单云函数多路由架构,通过中间件管道实现了鉴权、限流和操作日志等横切关注点。

源码下载

链接: pan.baidu.com/s/1Ae2eAF4A…

提取码: 1234

相关截图

B.jpg

C.jpg

登录.jpg

核心代码

const cloud = require('wx-server-sdk')
// 云函数初始化:使用当前环境变量动态选择环境
cloud.init({ env: cloud.DYNAMIC_CURRENT_ENV })

// 鉴权:判断是否已注册/是否管理员等
const { authenticate } = require('./middleware/auth')
// 频率限制:限制单用户/管理员群体的调用次数
const { checkRateLimit } = require('./middleware/rateLimit')
// 操作日志:记录管理员/会员的关键操作
const { logOperation } = require('./middleware/logger')

// 业务控制器:用户相关接口
const userCtrl = require('./controllers/user')
// 业务控制器:店铺信息相关接口
const shopCtrl = require('./controllers/shop')
// 业务控制器:会员查询相关接口
const memberCtrl = require('./controllers/member')
// 业务控制器:充值/消费/记录查询相关接口
const financeCtrl = require('./controllers/finance')
// 业务控制器:后台配置(项目/价格/警报/日志)相关接口
const systemCtrl = require('./controllers/system')
// 开发期:初始化集合与测试数据(生产应禁用)
const initDbCtrl = require('./controllers/initDb')

// 无需登录即可访问的接口(仅做 openid 校验)
const PUBLIC_ACTIONS = ['user.login', 'user.getProfile']
// 开发期:允许免鉴权执行的接口(仍校验 openid)
const DEV_NO_AUTH_ACTIONS = ['initDb.run']

// 需要管理员权限的接口列表
const ADMIN_ACTIONS = [
  'shop.updateInfo',
  'member.list', 'member.getByMemberNo',
  'finance.recharge', 'finance.consume', 'finance.getMemberRecords',
  'system.getItems', 'system.addItem', 'system.deleteItem',
  'system.getPrices', 'system.addPrice', 'system.deletePrice',
  'system.getAlerts', 'system.dismissAlert', 'system.getAdminLogs',
  // 'system.initDB' 已移除(改为启动自动 initDb.run)
]

// action -> 处理函数 的路由映射表
const ROUTE_MAP = {
  'user.login': userCtrl.login,
  'user.getProfile': userCtrl.getProfile,
  'user.updateName': userCtrl.updateName,
  'shop.getInfo': shopCtrl.getInfo,
  'shop.updateInfo': shopCtrl.updateInfo,
  'member.list': memberCtrl.list,
  'member.getByMemberNo': memberCtrl.getByMemberNo,
  'finance.recharge': financeCtrl.recharge,
  'finance.consume': financeCtrl.consume,
  'finance.getMyRecords': financeCtrl.getMyRecords,
  'finance.getMemberRecords': financeCtrl.getMemberRecords,
  'system.getItems': systemCtrl.getItems,
  'system.addItem': systemCtrl.addItem,
  'system.deleteItem': systemCtrl.deleteItem,
  'system.getPrices': systemCtrl.getPrices,
  'system.addPrice': systemCtrl.addPrice,
  'system.deletePrice': systemCtrl.deletePrice,
  'system.getAlerts': systemCtrl.getAlerts,
  'system.dismissAlert': systemCtrl.dismissAlert,
  'system.getAdminLogs': systemCtrl.getAdminLogs,
  'initDb.run': initDbCtrl.run
}

/**
 * 云函数入口。
 * - **入参**: event.action 指定路由;其余字段为各接口参数
 * - **鉴权**: 基于 openid 判断登录/管理员权限
 * - **限流**: 按月/按日统计并触发警报
 * - **返回**: { code, data|message }
 */
exports.main = async (event, context) => {
  try {
    // 前端传入的动作名(如 'user.login')
    const { action } = event

    if (!action || !ROUTE_MAP[action]) {
      return { code: 400, message: '无效的操作' }
    }

    // 微信上下文(包含 OPENID 等身份信息)
    const wxContext = cloud.getWXContext()
    // 当前调用者 openid(唯一标识)
    const openid = wxContext.OPENID

    if (!openid) {
      return { code: 401, message: '身份验证失败,无法获取openid' }
    }

    // 开发期:启动自动初始化(无鉴权,但仍校验 openid)
    if (DEV_NO_AUTH_ACTIONS.includes(action)) {
      const handler = ROUTE_MAP[action]
      const result = await handler(event)
      return { code: 0, data: result }
    }

    // 鉴权结果:registered/isAdmin/userInfo/phone 等
    const authResult = await authenticate(openid)

    // 限流检查(管理员与普通用户规则不同)
    const rateLimitResult = await checkRateLimit(openid, authResult.isAdmin, authResult.phone)
    if (rateLimitResult.limited) {
      return { code: 429, message: rateLimitResult.message }
    }

    // 非公开接口必须先完成手机号授权登录
    if (!PUBLIC_ACTIONS.includes(action) && !authResult.registered) {
      return { code: 403, message: '请先完成手机号授权登录' }
    }

    // 管理员接口:校验管理员权限
    if (ADMIN_ACTIONS.includes(action) && !authResult.isAdmin) {
      return { code: 403, message: '权限不足,需要管理员权限' }
    }

    // 命中路由并执行处理器
    const handler = ROUTE_MAP[action]
    const result = await handler(event, authResult)

    // 异步写操作日志(不影响主流程返回)
    logOperation(authResult, action, event).catch(err => {
      console.error('日志记录失败:', err)
    })

    return { code: 0, data: result }
  } catch (err) {
    console.error('云函数执行错误:', err)
    return { code: 500, message: err.message || '服务器内部错误' }
  }
}