目录
- 前情回顾与本节目标
- 第一步:数据模型准备
-
- [1.1 学员档案表(MBA_StudentProfiles)](#1.1 学员档案表(MBA_StudentProfiles))
- [1.2 班级表(MBA_Classes)](#1.2 班级表(MBA_Classes))
- [1.3 班级花名册表(MBA_ClassRosters)](#1.3 班级花名册表(MBA_ClassRosters))
- 第一步:创建应用
- 第二步:创建门户页面
-
- [2.1 创建首页](#2.1 创建首页)
- [2.2 搭建账号绑定弹窗](#2.2 搭建账号绑定弹窗)
- 第三步:实现登录与账号绑定逻辑
-
- [3.1 创建登录检查方法](#3.1 创建登录检查方法)
- [3.2 创建账号绑定方法](#3.2 创建账号绑定方法)
- 最终效果
- 总结
前情回顾与本节目标
在前述章节中我们已经完成了管理后台的搭建,包括销售、财务、教务、教师相关角色。当学员分班成功后,需要登录小程序进行签到。登录小程序之前需要和学员表创建的账号进行绑定,本节我们将正式打通用户登录与账号绑定的闭环。
本节核心目标:
- 微搭登录认证 :基于云开发内置的
$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' });
}
}
给弹窗的确认按钮绑定事件,调用我们的方法

最终效果
打开首页,弹出电话绑定窗口

输入电话,点击确认完成用户的绑定,后续就可以查看课表进行签到了
总结
本节我们完成了小程序用户登录与账号绑定的完整流程:
- 数据模型准备:建立了学员档案表和班级表,包含 OpenID 字段用于小程序登录
- 门户页登录检查:页面加载时自动获取当前用户的 OpenID,查询学员档案表
- 账号绑定流程 :
- 未绑定用户显示弹窗,要求输入手机号
- 根据手机号查询学员档案
- 未找到则提示"尚未开通账号"
- 找到则更新 OpenID 字段完成绑定
下一节我们将实现课程预约功能,让学员可以在小程序中预约上课。