微搭低代码MBA 培训管理系统实战 25——小程序用户登录与账号绑定

目录

前情回顾与本节目标

在前述章节中我们已经完成了管理后台的搭建,包括销售、财务、教务、教师相关角色。当学员分班成功后,需要登录小程序进行签到。登录小程序之前需要和学员表创建的账号进行绑定,本节我们将正式打通用户登录与账号绑定的闭环。

本节核心目标:

  • 微搭登录认证 :基于云开发内置的 $w.auth.currentUser 获取已登录用户的 OpenID
  • 账号绑定验证:在门户页初始化时,根据 OpenID 查询学员档案表,未绑定则引导绑定
  • 手机号验证绑定:用户输入手机号进行账号绑定,验证通过后更新学员档案的 OpenID 字段
  • 个人信息展示:绑定成功后跳转到"我的"页面,展示学员个人信息及班级信息

第一步:数据模型准备

1.1 学员档案表(MBA_StudentProfiles)

确保系统中已存在学员档案表,核心字段如下:

字段名称 字段标识 字段类型 说明
学员ID _id 文本 主键,系统自动生成
学员姓名 student_name 文本 姓名
手机号 mobile 文本 用于登录和账号绑定
微信OpenID openid 文本 学员微信OpenID,用于小程序端登录和权限控制
关联班级 rel_class_id 关联关系 关联 Classes 表,记录学员所在班级
学籍状态 status 枚举 1-在读、2-休学、3-毕业、4-退费
入学时间 enroll_date 日期 入学日期

1.2 班级表(MBA_Classes)

用于关联查询学员所在班级信息:

字段名称 字段标识 字段类型 说明
班级ID _id 文本 主键
班级名称 class_name 文本 班级名称
课程类型 course_type 文本 课程类型
班主任 teacher_name 文本 班主任姓名

1.3 班级花名册表(MBA_ClassRosters)

用于记录学员与班级的关联关系,一个学员可能关联多个班级:

字段名称 字段标识 字段类型 说明
花名册ID _id 文本 主键,系统自动生成
关联学员 rel_student_id 多对一 关联 StudentProfiles 表
关联班级 rel_class_id 多对一 关联 Classes 表
关联课时卡 rel_card_id 多对一 关联课时卡表
学员状态 status 枚举 1-在读、2-休学、3-毕业、4-退费
入班日期 join_date 日期时间 加入班级日期
退班日期 leave_date 日期时间 退出班级日期
备注 remark 文本 备注信息

第一步:创建应用

在搭建小程序之前,需要先创建应用。打开控制台,选择小程序应用,点击从空白创建

输入小程序的名称,启用登录

切换到基础设置,绑定小程序

点击添加微信小程序

点击扫码认证授权

根据弹出的授权提示进行授权,绑定小程序即可

第二步:创建门户页面

2.1 创建首页

点击设计页面 ,将页面重命名为首页

2.2 搭建账号绑定弹窗

在页面组件下添加弹窗组件,设置标题为"账号绑定"

在弹窗内容添加电话输入组件

在代码区创建变量来控制弹窗是否显示

创建全局变量用来保存用户的登录信息

给弹窗的默认打开状态绑定我们的布尔值变量


第三步:实现登录与账号绑定逻辑

3.1 创建登录检查方法

在页面中创建自定义方法 checkLogin

javascript 复制代码
export default async function checkLogin({ event, data }) {
  try {
    $w.utils.showLoading({ title: '加载中...' });
    
    // 1. 从云开发原生 auth 对象中获取当前已登录用户的 OpenID
    const openid = $w.auth.currentUser?.openId||"123";
    
    if (!openid) {
      $w.utils.hideLoading();
      return $w.utils.showToast({ title: '获取授权信息失败,请重新登录', icon: 'error' });
    }

    // 2. 根据 OpenID 查询学员档案表
    const studentRes = await $w.cloud.callDataSource({
      dataSourceName: 'MBA_StudentProfiles',
      methodName: 'wedaGetRecordsV2',
      params: {
        filter: { 
          where: { 
            openid: { $eq: openid } 
          } 
        },
        select: { 
          $master: true, 
          rel_class_id: true  // 关联查询班级信息
        }
      }
    });

    // 3. 判断是否找到学员档案
    if (!studentRes.records || studentRes.records.length === 0) {
      // 未找到,显示账号绑定弹窗
      $w.page.dataset.state.isBindModalVisible = true;
      $w.utils.hideLoading();
      return;
    }

    // 4. 已绑定,保存用户信息并跳转到我的页面
    const student = studentRes.records[0];

    // 查询班级花名册,获取在读班级
    const rosterRes = await $w.cloud.callDataSource({
      dataSourceName: 'MBA_ClassRosters',
      methodName: 'wedaGetRecordsV2',
      params: {
        filter: { 
          where: { 
            $and: [
              { rel_student_id: { $eq: student._id } },
              { status: { $eq: '1' } }  // 1-在读
            ]
          } 
        },
        select: { 
          $master: true, 
          rel_class_id: true,  // 关联查询班级信息
          rel_card_id:true
        }
      }
    });
    
    // 构造用户信息对象
    const userInfo = {
      ...student,
      classInfo: rosterRes.records || []  // 班级花名册列表(可能多个班级)
    };

    // 保存到全局状态
    $w.app.dataset.state.currentUser = userInfo;

    $w.utils.hideLoading();
    
    
  } catch (e) {
    console.error('登录检查失败', e);
    $w.utils.hideLoading();
    $w.utils.showToast({ title: '系统加载失败,请刷新重试', icon: 'error' });
  }
}

给页面的显示事件绑定我们的检查登录方法

3.2 创建账号绑定方法

创建自定义方法 bindAccount

javascript 复制代码
export default async function bindAccount({ event, data }) {
  try {
    const phone = $w.inputPhone1.value;
    
    // 1. 校验手机号
    if (!phone || phone.trim() === '') {
      return $w.utils.showToast({ title: '请输入手机号', icon: 'error' });
    }
    
    // 简单的手机号格式校验
    const phoneRegex = /^1[3-9]\d{9}$/;
    if (!phoneRegex.test(phone.trim())) {
      return $w.utils.showToast({ title: '手机号格式不正确', icon: 'error' });
    }

    $w.utils.showLoading({ title: '绑定中...' });

    // 2. 根据手机号查询学员档案
    const studentRes = await $w.cloud.callDataSource({
      dataSourceName: 'MBA_StudentProfiles',
      methodName: 'wedaGetRecordsV2',
      params: {
        filter: { 
          where: { 
            mobile: { $eq: phone.trim() } 
          } 
        },
        select: { 
          $master: true, 
          rel_class_id: true 
        }
      }
    });

    // 3. 判断是否找到学员
    if (!studentRes.records || studentRes.records.length === 0) {
      $w.utils.hideLoading();
      return $w.utils.showModal({
        title: '提示',
        content: '该手机号尚未开通账号,请联系管理员',
        showCancel: false
      });
    }

    const student = studentRes.records[0];
    
    // 4. 获取当前用户的 OpenID
    const openid = $w.auth.currentUser?.openId||"123";
    
    if (!openid) {
      $w.utils.hideLoading();
      return $w.utils.showToast({ title: '获取授权信息失败', icon: 'error' });
    }

    // 5. 更新学员档案的 openid 字段
    await $w.cloud.callDataSource({
      dataSourceName: 'MBA_StudentProfiles',
      methodName: 'wedaUpdateV2',
      params: {
        data: { 
          openid: openid 
        },
        filter: { 
          where: { 
            _id: { $eq: student._id } 
          } 
        }
      }
    });

    // 6. 绑定成功,关闭弹窗,保存用户信息
    $w.app.dataset.state.isBindModalVisible = false;
    // 5. 根据学员ID从班级花名册获取班级信息(学员状态=1-在读)
    const rosterRes = await $w.cloud.callDataSource({
      dataSourceName: 'MBA_ClassRosters',
      methodName: 'wedaGetRecordsV2',
      params: {
        filter: { 
          where: { 
            $and: [
              { rel_student_id: { $eq: student._id } },
              { status: { $eq: '1' } }  // 1-在读
            ]
          } 
        },
        select: { 
          $master: true, 
          rel_class_id: true  // 关联查询班级信息
        }
      }
    });

    // 构造用户信息对象
    const userInfo = {
      ...student,
      openid: openid,
      classList: rosterRes.records || []  // 班级花名册列表(可能多个班级)
    };
   

    // 保存到全局状态
    $w.app.dataset.state.currentUser = userInfo;
    

    // 清空输入
    $w.app.dataset.state.bindPhone = '';

    $w.utils.hideLoading();
    
    $w.utils.showToast({ title: '绑定成功', icon: 'success' });
    
    $w.modal1.close({})
  } catch (e) {
    console.error('账号绑定失败', e);
    $w.utils.hideLoading();
    $w.utils.showToast({ title: '绑定失败,请重试', icon: 'error' });
  }
}

给弹窗的确认按钮绑定事件,调用我们的方法

最终效果

打开首页,弹出电话绑定窗口

输入电话,点击确认完成用户的绑定,后续就可以查看课表进行签到了


总结

本节我们完成了小程序用户登录与账号绑定的完整流程:

  1. 数据模型准备:建立了学员档案表和班级表,包含 OpenID 字段用于小程序登录
  2. 门户页登录检查:页面加载时自动获取当前用户的 OpenID,查询学员档案表
  3. 账号绑定流程
    • 未绑定用户显示弹窗,要求输入手机号
    • 根据手机号查询学员档案
    • 未找到则提示"尚未开通账号"
    • 找到则更新 OpenID 字段完成绑定

下一节我们将实现课程预约功能,让学员可以在小程序中预约上课。

相关推荐
数智化管理手记1 天前
精益生产合理化建议核心解读:本质、价值与提报规范
大数据·网络·人工智能·低代码·制造
清风絮柳1 天前
65.少儿英语微信小程序
vue.js·spring boot·微信小程序·小程序·毕业设计
tjsoft1 天前
unigui开发微信小程序
微信小程序·小程序
数智化管理手记2 天前
精益生产中的TPM管理是什么?一文破解设备零故障的密码
服务器·网络·数据库·低代码·制造·源代码管理·精益工程
麦聪聊数据2 天前
企业数据流通与敏捷API交付实战(五):异构数据跨库联邦与零代码发布
数据库·sql·低代码·restful
m0_462803882 天前
“趣味运动会记分”功能教学指南
小程序