目录
- 前情回顾与本节目标
- 第一步:渠道合伙人数据模型设计
-
- [1.1 渠道合伙人表(MBA_ChannelPartners)](#1.1 渠道合伙人表(MBA_ChannelPartners))
- [1.2 客户表扩展(MBA_Customers)](#1.2 客户表扩展(MBA_Customers))
- 第二步:管理员端渠道管理
-
- [2.1 创建渠道管理页面](#2.1 创建渠道管理页面)
-
- [2.1.1 搭建页面布局](#2.1.1 搭建页面布局)
- [2.1.2 配置数据表格](#2.1.2 配置数据表格)
- [2.1.3 配置菜单](#2.1.3 配置菜单)
- 第三步:渠道端工作台搭建
-
- [3.1 创建渠道端布局](#3.1 创建渠道端布局)
- [3.2 渠道端页面结构](#3.2 渠道端页面结构)
- 第四步:渠道端登录与鉴权
-
- [4.1 编写登录验证方法](#4.1 编写登录验证方法)
- [4.2 门户跳转鉴权](#4.2 门户跳转鉴权)
- 最终效果
- 总结
前情回顾与本节目标
在上一讲中,我们完成了线索管理模块的开发,包括线索录入、手机号重复校验等核心功能。在 CRM 系统中,渠道管理是一个非常重要的模块,它主要服务于外部合作伙伴(渠道合伙人),让他们能够自主报备线索,了解跟进状态。
本节我们将实现渠道合伙人端的核心功能:渠道信息管理 与线索报备。
本节核心目标:
- 渠道合伙人管理:管理员可以创建和管理渠道合伙人账号。
- 搭建渠道端工作台:为渠道合伙人搭建独立的操作界面。
- 渠道端登录鉴权:渠道合伙人登录时获取对应的渠道信息。
- 线索报备功能:渠道合伙人可以提交潜在客户线索。
第一步:渠道合伙人数据模型设计
渠道合伙人是系统的外部用户,他们需要独立的账号来登录系统并进行线索报备。
1.1 渠道合伙人表(MBA_ChannelPartners)
在微搭中创建渠道合伙人模型:
| 字段名称 | 字段标识 | 数据类型 | 说明 |
|---|---|---|---|
| 渠道名称 | name |
单行文本 | 渠道合伙人的名称 |
| 联系人 | contact_person |
单行文本 | 渠道负责人姓名 |
| 联系电话 | phone |
电话 | 渠道联系方式,用于登录 |
| 合作类型 | partner_type |
枚举 | 企业代理 / 个人代理 / 院校合作 |
| 合作等级 | level |
枚举 | 钻石 / 金牌 / 银牌 / 普通 |
| 状态 | status |
枚举 | 正常 / 禁用 |
| 创建时间 | created_at |
日期时间 | 记录创建时间 |

1.2 客户表扩展(MBA_Customers)
在上一讲设计的客户表基础上,增加渠道相关字段:
| 字段名称 | 字段标识 | 数据类型 | 说明 |
|---|---|---|---|
| 渠道来源 | channel_id |
关联关系 | 关联 ChannelPartners 表(渠道报备时填写) |
| 渠道备注 | channel_remark |
多行文本 | 渠道备注信息 |

第二步:管理员端渠道管理
2.1 创建渠道管理页面
在管理员端创建渠道管理页面,用于管理渠道合伙人信息。
2.1.1 搭建页面布局
点击创建页面,输入"渠道管理",选择管理员布局。

2.1.2 配置数据表格
添加数据表格组件,绑定渠道合伙人数据模型:

2.1.3 配置菜单
切换到布局设计,添加渠道管理菜单

第三步:渠道端工作台搭建
渠道合伙人需要独立的操作界面,与管理员端分离。
3.1 创建渠道端布局
切换到布局设计,新建布局,创建渠道布局

3.2 渠道端页面结构
渠道端主要包含以下功能模块:
- 线索报备:提交新的潜在客户信息
- 个人信息:查看和修改个人信息
点击创建页面,创建线索报备页面

选择客户表,只勾选新增查看场景

配置具体的菜单

第四步:渠道端登录与鉴权
渠道合伙人登录时,需要通过手机号获取对应的渠道信息。在全局变量中增加渠道的信息

4.1 编写登录验证方法
修改我们的全局登录方法,增加渠道的验证:
javascript
export default async function login({ event, data }) {
try {
$w.utils.showLoading({ title: '加载工作台中...' });
// 1. 从云开发原生 auth 对象中获取当前已登录的手机号
const phone = $w.auth.currentUser?.phone||"15533445566";
if (!phone) {
return $w.utils.showToast({ title: '获取授权信息失败,请重新登录', icon: 'error' });
}
// 1. 先查询是否是渠道用户
const channelRes = await $w.cloud.callDataSource({
dataSourceName: 'MBA_ChannelPartners',
methodName: 'wedaGetRecordsV2',
params: {
filter: {
where: {
phone: { $eq: phone }
}
},
select: {
$master: true,
}
}
});
console.log("channelRes",channelRes)
if (channelRes.records && channelRes.records.length > 0) {
// 渠道用户登录成功
const channelInfo = channelRes.records[0];
$w.app.dataset.state.currentChannel = channelInfo;
// 渠道用户固定角色,用于门户跳转判断
$w.app.dataset.state.userRoles = ['ROLE_CHANNEL'];
$w.utils.showToast({ title: '渠道登录成功', icon: 'success' });
return;
}
// 2. 根据手机号查询业务库中的用户信息(关联查询部门和岗位)
const userRes = await $w.cloud.callDataSource({
dataSourceName: 'MBA_Users',
methodName: 'wedaGetRecordsV2',
params: {
filter: { where: { phone: { $eq: phone } } },
select: { $master: true, department_id: true, position_id: true }
}
});
if (!userRes.records.length) {
return $w.utils.showToast({ title: '该手机号未在系统中注册,请联系管理员', icon: 'error' });
}
const user = userRes.records[0];
console.log("user",user)
// 3. 异步更新用户的最后登录时间 (不阻塞后续逻辑)
$w.cloud.callDataSource({
dataSourceName: 'MBA_Users',
methodName: 'wedaUpdateV2',
params: {
data: { last_login: Date.now() },
filter: { where: { _id: { $eq: user._id } } }
}
}).catch(e => console.error('更新登录时间失败', e));
// 4. 获取用户关联的角色信息
const roleRes = await $w.cloud.callDataSource({
dataSourceName: 'MBA_RoleUsers',
methodName: 'wedaGetRecordsV2',
params: {
filter: { where: { user_id: { $eq: user._id } } },
select: { $master: true, role_id: true }
}
});
console.log("roleRes",roleRes)
// 提取角色编码 (例如: ['ROLE_ADMIN', 'ROLE_TEACHER'])
const roleCodes = roleRes.records.map(item => item.role_id?.code).filter(Boolean);
console.log("roleCodes",roleCodes)
// 5. 构造全局 User 对象并写入页面状态
const userInfo = {
...user,
deptInfo: user.department_id,
postInfo: user.position_id,
};
$w.app.dataset.state.currentUser = userInfo;
$w.app.dataset.state.userRoles = roleCodes;
} catch (e) {
console.error('初始化门户失败', e);
$w.utils.showToast({ title: '系统加载失败,请刷新重试', icon: 'error' });
} finally {
$w.utils.hideLoading();
}
}
4.2 门户跳转鉴权
在门户页面点击不同工作台按钮时,需要根据用户角色进行权限校验:
javascript
export default function ({ event, data }) {
// 从页面状态中获取当前用户的角色集合
const userRoles = $w.app.dataset.state.userRoles || [];
const targetPortal = data.target; // 从事件入参获取点击的目标工作台
// 定义门户跳转配置:映射目标门户、需要校验的角色编码、跳转页面ID
const portalConfig = {
admin: {
requiredRoles: ['ROLE_SUPER_ADMIN', 'ROLE_ADMIN'],
pageId: 'u_bu_men_guan_li'
},
employee: {
requiredRoles: ['ROLE_USER', 'ROLE_DEPT_MANAGER'],
pageId: 'employee-dashboard'
},
teacher: {
requiredRoles: ['ROLE_TEACHER'],
pageId: 'teacher-dashboard'
},
student: {
requiredRoles: ['ROLE_STUDENT'],
pageId: 'student-app'
},
channel: {
requiredRoles: ['ROLE_CHANNEL'],
pageId: 'u_xian_suo_bao_bao'
}
};
const config = portalConfig[targetPortal];
console.log("config",config)
if (!config) {
return $w.utils.showToast({ title: '无效的工作台入口', icon: 'error' });
}
// 核心鉴权逻辑:判断用户拥有的角色中,是否包含该门户所需的任意一个角色
const hasPermission = config.requiredRoles.some(role => userRoles.includes(role));
if (!hasPermission) {
return $w.utils.showToast({ title: '您没有该工作台的访问权限', icon: 'error' });
}
// 鉴权通过,放行跳转
$w.utils.reLaunch({ pageId: config.pageId });
}
最终效果
打开首页,点击进入渠道工作台

渠道可以进行线索的报备

管理员可以新增渠道信息

总结
本节我们完成了渠道管理模块的核心功能开发:
- 渠道合伙人管理:管理员可以创建、编辑和禁用渠道合伙人账号。
- 渠道端工作台:为渠道合伙人搭建了独立的操作界面。
- 登录鉴权:实现了渠道合伙人的登录验证,并保存登录状态。
- 线索报备:渠道合伙人可以提交潜在客户线索,系统自动关联渠道信息。
下一步,我们将进入【线索审核与分配】的开发!