# 业务单根据状态进入不同的子模块
# 概述
本功能用于实现不同状态的数据自动归类到不同的列表页签中。例如合同管理中,起草中的合同进入“起草中”页签,审批中的合同进入“审批中”页签,待签署的合同进入“待签署”页签。
# 一、示例演示:合同管理
# 演示路径
- 访问地址:应用中心
- 模块名称:合同管理
# 业务处理效果
全部合同列表(共6个合同):
- 合同100:起草中
- 合同101:审批中
- 合同102:待签署
- 合同103:已生效
- 合同104:已完成
- 合同105:已终止
分类列表:
- 起草中:仅显示合同100
- 审批中:仅显示合同101
- 待签署:仅显示合同102
动态变化:
- 将合同100的状态从“起草中”改为“审批中”并保存
- 合同100从“起草中”列表消失
- 合同100出现在“审批中”列表中
# 二、实现方法
# 后台服务实现
文件路径:Web项目\Apps\Controllers
每个状态对应一个独立的控制器,通过重载ApplyDataIsolationFilter过滤对应状态的数据。
起草中控制器:SampleContractsDraftController.cs
// 第26-29行:过滤起草中的合同
protected override IQueryable<SampleContract> ApplyDataIsolationFilter(
IQueryable<SampleContract> query,
HttpContext httpContext)
{
return query.Where(x => x.Status == SampleContractStatus.Draft);
}
审批中控制器:SampleContractsApprovingController.cs
// 第26-29行:过滤审批中的合同
protected override IQueryable<SampleContract> ApplyDataIsolationFilter(
IQueryable<SampleContract> query,
HttpContext httpContext)
{
return query.Where(x => x.Status == SampleContractStatus.Approving);
}
代码说明:
- 每个控制器重载
ApplyDataIsolationFilter函数 - 通过
Where条件筛选特定状态的数据 - 其他状态(待签署、已生效、已完成、已终止)的实现方式相同
# 前台配置
文件路径:wwwroot\Apps\samples
每个状态对应一个独立的前台文件,通过serviceUrl指定对应的后台服务。
起草中前台:ContractsDraft.js
Ext.define('Apps.samples.ContractsDraft', {
extend: 'Apps.samples.ContractsAbstract', // 继承公共基类
serviceUrl: Yiez.$url('app/samples/contracts/draft') // 指定后台服务
});
审批中前台:ContractsApproving.js
Ext.define('Apps.samples.ContractsApproving', {
extend: 'Apps.samples.ContractsAbstract', // 继承公共基类
serviceUrl: Yiez.$url('app/samples/contracts/approving') // 指定后台服务
});
代码说明:
- 每个前台文件仅5行代码
- 继承公共基类
ContractsAbstract,复用列表配置 - 通过
serviceUrl指定对应的后台服务地址
# 模块菜单配置
文件路径:Web项目\Apps\Navigator\Samples\ConceptController.cs
// 第115-146行:合同管理二级模块配置
new {
id = "Sample.合同管理",
text = "合同管理",
expanded = true,
children = new object[]{ // 二级模块配置
new {
id = "Sample.合同管理.起草中",
text = "起草中",
title = "起草中的合同",
glyph = 0xec07,
xclass = "Apps.samples.ContractsDraft" // 关联前台类
},
new {
id = "Sample.合同管理.审批中",
text = "审批中",
title = "正在审批的合同",
glyph = 0xea96,
xclass = "Apps.samples.ContractsApproving" // 关联前台类
},
new {
id = "Sample.合同管理.待签署",
text = "待签署",
title = "审批完成等待签署",
glyph = 0xec08,
xclass = "Apps.samples.ContractsPendingSignature"
},
new {
id = "Sample.合同管理.全部合同",
text = "全部合同",
glyph = 0xeb0d,
xclass = "Apps.samples.ContractsAll"
}
}
}
代码说明:
- 第119行:
children属性实现二级模块结构 - 如需使用标签页,将
children改为tabs即可
# 三、核心原理
# 实现架构
| 层级 | 作用 | 实现方式 |
|---|---|---|
| 后台控制器 | 数据过滤 | 重载ApplyDataIsolationFilter,按状态过滤 |
| 前台脚本 | 指定数据源 | 通过serviceUrl指定对应的后台服务 |
| 公共基类 | 复用代码 | 列表布局等公共配置在基类中统一实现 |
| 模块配置 | 菜单组织 | 使用children或tabs组织二级结构 |
# 数据流向
- 用户点击“起草中”菜单
- 加载
ContractsDraft.js前台脚本 - 脚本通过
serviceUrl调用/app/samples/contracts/draft服务 - 后台
SampleContractsDraftController过滤出状态为Draft的数据 - 返回过滤后的数据并在列表中显示
# 四、配置步骤
# 操作步骤
- 创建后台控制器:为每个状态创建独立的控制器,重载
ApplyDataIsolationFilter过滤对应状态 - 创建前台脚本:为每个状态创建独立的前台文件,指定对应的
serviceUrl - 提取公共基类:将列表公共配置提取到基类中,避免重复代码
- 配置模块菜单:在
ConceptController.cs中使用children或tabs组织二级结构
# 关键要点
- 数据过滤:通过
ApplyDataIsolationFilter实现状态筛选 - 代码复用:公共部分提取到基类,子类仅需指定服务地址
- 菜单结构:使用
children实现二级菜单,tabs实现标签页
# 五、常见应用场景
| 场景 | 分类方式 | 过滤条件 |
|---|---|---|
| 合同管理 | 按合同状态 | x.Status == Draft/Approving/PendingSignature |
| 订单管理 | 按订单状态 | x.OrderStatus == New/Processing/Completed |
| 任务管理 | 按任务状态 | x.TaskStatus == Todo/Doing/Done |
| 审批流程 | 按审批节点 | x.ApprovalNode == DeptManager/HR/Finance |
# 六、注意事项
- 状态一致性:前后台使用的状态值必须保持一致
- 基类复用:相同列表配置应提取到基类,避免重复代码
- 菜单结构:根据需求选择
children(二级菜单)或tabs(标签页) - 性能考虑:状态字段建议添加数据库索引
# 七、总结
不同状态的单子进入不同的标签页实现非常便捷:
- ✅ 核心机制:使用
ApplyDataIsolationFilter按状态过滤数据 - ✅ 代码复用:公共部分提取到基类,子类只需指定服务地址
- ✅ 灵活组织:支持
children二级菜单和tabs标签页两种结构 - ✅ 动态更新:修改状态后数据自动移动到对应分类
类似的功能,其核心就是数据的分类显示,使用ApplyDataIsolationFilter方法对不同子模块的数据进行过滤就能实现。子模块排布可以用二级模块(children),也可以用标签页(tabs)。