bugfix
This commit is contained in:
commit
dd001f63b4
76
README.md
Normal file
76
README.md
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
# 跨模块审批流程模块
|
||||||
|
|
||||||
|
## 概述
|
||||||
|
跨模块审批流程模块提供统一的审批工作流管理,支持客户管理、商机管理、合同管理和财务管理模块的审批需求。
|
||||||
|
|
||||||
|
## 功能特性
|
||||||
|
|
||||||
|
### 1. 工作流定义
|
||||||
|
- **可视化配置**: 通过CRUD界面定义审批工作流
|
||||||
|
- **条件触发**: 支持基于业务规则自动触发审批
|
||||||
|
- **多租户支持**: 组织级别的工作流隔离
|
||||||
|
|
||||||
|
### 2. 审批步骤管理
|
||||||
|
- **多种审批类型**: 单人审批、多人会签、顺序审批、并行审批
|
||||||
|
- **灵活审批人**: 支持用户、角色、部门、动态表达式
|
||||||
|
- **超时控制**: 可配置审批超时时间
|
||||||
|
|
||||||
|
### 3. 审批实例管理
|
||||||
|
- **跨模块集成**: 自动与客户、商机、合同、财务模块集成
|
||||||
|
- **状态跟踪**: 实时跟踪审批进度和状态
|
||||||
|
- **审计日志**: 完整的审批历史记录
|
||||||
|
|
||||||
|
### 4. 移动端适配
|
||||||
|
- **响应式设计**: 适配手机和平板设备
|
||||||
|
- **简化操作**: 移动端优化的审批操作界面
|
||||||
|
- **离线支持**: 关键操作的离线缓存
|
||||||
|
|
||||||
|
## 技术架构
|
||||||
|
|
||||||
|
### 数据库设计
|
||||||
|
- **approval_workflow**: 工作流定义表
|
||||||
|
- **approval_step**: 审批步骤表
|
||||||
|
- **approval_instance**: 审批实例表
|
||||||
|
- **approval_task**: 审批任务表
|
||||||
|
|
||||||
|
### 前端实现
|
||||||
|
- **Bricks Framework**: JSON驱动的组件化UI
|
||||||
|
- **移动端布局**: 专门的mobile_base.ui布局
|
||||||
|
- **响应式组件**: 适配不同屏幕尺寸
|
||||||
|
|
||||||
|
### 后端实现
|
||||||
|
- **异步设计**: 基于async/await的非阻塞架构
|
||||||
|
- **RBAC集成**: 与现有权限系统无缝集成
|
||||||
|
- **AppBase集成**: 使用编码管理系统
|
||||||
|
|
||||||
|
## 使用说明
|
||||||
|
|
||||||
|
### 工作流配置
|
||||||
|
1. 进入"工作流管理"标签页
|
||||||
|
2. 创建新的审批工作流
|
||||||
|
3. 添加审批步骤并配置审批人
|
||||||
|
4. 设置触发条件(可选)
|
||||||
|
|
||||||
|
### 审批操作
|
||||||
|
1. 在移动端或桌面端访问审批中心
|
||||||
|
2. 查看待处理的审批任务
|
||||||
|
3. 查看审批详情并做出决策
|
||||||
|
4. 系统自动推进到下一步或完成审批
|
||||||
|
|
||||||
|
### 集成方式
|
||||||
|
- **客户模块**: 客户交接、重要信息变更
|
||||||
|
- **商机模块**: 大额商机创建、阶段变更
|
||||||
|
- **合同模块**: 合同创建、条款修改、金额变更
|
||||||
|
- **财务模块**: 大额支出、特殊收款处理
|
||||||
|
|
||||||
|
## 扩展性
|
||||||
|
|
||||||
|
- **自定义条件**: 支持复杂的触发条件表达式
|
||||||
|
- **通知集成**: 可扩展邮件、短信、微信通知
|
||||||
|
- **API接口**: 提供RESTful API供外部系统调用
|
||||||
|
- **报表分析**: 审批效率和瓶颈分析
|
||||||
|
|
||||||
|
## 版本信息
|
||||||
|
- **版本**: 1.0.0
|
||||||
|
- **状态**: 生产就绪
|
||||||
|
- **兼容性**: 遵循所有模块开发规范
|
||||||
116
init/data.json
Normal file
116
init/data.json
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
{
|
||||||
|
"appcodes": [
|
||||||
|
{
|
||||||
|
"id": "APPROVER_TYPE",
|
||||||
|
"name": "审批人类型",
|
||||||
|
"hierarchy_flg": "0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "APPROVAL_TYPE",
|
||||||
|
"name": "审批类型",
|
||||||
|
"hierarchy_flg": "0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "APPROVAL_STATUS",
|
||||||
|
"name": "审批状态",
|
||||||
|
"hierarchy_flg": "0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "TASK_STATUS",
|
||||||
|
"name": "任务状态",
|
||||||
|
"hierarchy_flg": "0"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"appcodes_kv": [
|
||||||
|
{
|
||||||
|
"id": "APPROVER_TYPE",
|
||||||
|
"parentid": "",
|
||||||
|
"k": "user",
|
||||||
|
"v": "指定用户"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "APPROVER_TYPE",
|
||||||
|
"parentid": "",
|
||||||
|
"k": "role",
|
||||||
|
"v": "角色"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "APPROVER_TYPE",
|
||||||
|
"parentid": "",
|
||||||
|
"k": "department",
|
||||||
|
"v": "部门"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "APPROVER_TYPE",
|
||||||
|
"parentid": "",
|
||||||
|
"k": "dynamic",
|
||||||
|
"v": "动态表达式"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "APPROVAL_TYPE",
|
||||||
|
"parentid": "",
|
||||||
|
"k": "single",
|
||||||
|
"v": "单人审批"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "APPROVAL_TYPE",
|
||||||
|
"parentid": "",
|
||||||
|
"k": "multiple",
|
||||||
|
"v": "多人会签"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "APPROVAL_TYPE",
|
||||||
|
"parentid": "",
|
||||||
|
"k": "sequential",
|
||||||
|
"v": "顺序审批"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "APPROVAL_TYPE",
|
||||||
|
"parentid": "",
|
||||||
|
"k": "parallel",
|
||||||
|
"v": "并行审批"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "APPROVAL_STATUS",
|
||||||
|
"parentid": "",
|
||||||
|
"k": "pending",
|
||||||
|
"v": "审批中"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "APPROVAL_STATUS",
|
||||||
|
"parentid": "",
|
||||||
|
"k": "approved",
|
||||||
|
"v": "已批准"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "APPROVAL_STATUS",
|
||||||
|
"parentid": "",
|
||||||
|
"k": "rejected",
|
||||||
|
"v": "已拒绝"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "APPROVAL_STATUS",
|
||||||
|
"parentid": "",
|
||||||
|
"k": "cancelled",
|
||||||
|
"v": "已取消"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "TASK_STATUS",
|
||||||
|
"parentid": "",
|
||||||
|
"k": "pending",
|
||||||
|
"v": "待处理"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "TASK_STATUS",
|
||||||
|
"parentid": "",
|
||||||
|
"k": "approved",
|
||||||
|
"v": "已批准"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "TASK_STATUS",
|
||||||
|
"parentid": "",
|
||||||
|
"k": "rejected",
|
||||||
|
"v": "已拒绝"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
35
json/approval_instance.json
Normal file
35
json/approval_instance.json
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
{
|
||||||
|
"tblname": "approval_instance",
|
||||||
|
"title": "审批实例",
|
||||||
|
"params": {
|
||||||
|
"sortby": "created_at DESC",
|
||||||
|
"logined_userorgid": "org_id",
|
||||||
|
"browserfields": {
|
||||||
|
"exclouded": ["id", "workflow_id", "module_record_id", "org_id"]
|
||||||
|
},
|
||||||
|
"editexclouded": ["id", "workflow_id", "module_record_id", "org_id", "current_step_id"],
|
||||||
|
"alterations": [
|
||||||
|
{
|
||||||
|
"field": "status",
|
||||||
|
"widgettype": "Select",
|
||||||
|
"options": {
|
||||||
|
"data": "get_code('APPROVAL_STATUS')"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"field": "module_type",
|
||||||
|
"widgettype": "Text",
|
||||||
|
"options": {
|
||||||
|
"readonly": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"subtables": [
|
||||||
|
{
|
||||||
|
"field": "id",
|
||||||
|
"title": "审批任务",
|
||||||
|
"subtable": "approval_task"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
28
json/approval_step.json
Normal file
28
json/approval_step.json
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
{
|
||||||
|
"tblname": "approval_step",
|
||||||
|
"title": "审批步骤",
|
||||||
|
"params": {
|
||||||
|
"sortby": "step_order",
|
||||||
|
"logined_userorgid": "org_id",
|
||||||
|
"browserfields": {
|
||||||
|
"exclouded": ["id", "workflow_id", "org_id"]
|
||||||
|
},
|
||||||
|
"editexclouded": ["id", "workflow_id", "org_id"],
|
||||||
|
"alterations": [
|
||||||
|
{
|
||||||
|
"field": "approver_type",
|
||||||
|
"widgettype": "Select",
|
||||||
|
"options": {
|
||||||
|
"data": "get_code('APPROVER_TYPE')"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"field": "approval_type",
|
||||||
|
"widgettype": "Select",
|
||||||
|
"options": {
|
||||||
|
"data": "get_code('APPROVAL_TYPE')"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
28
json/approval_task.json
Normal file
28
json/approval_task.json
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
{
|
||||||
|
"tblname": "approval_task",
|
||||||
|
"title": "审批任务",
|
||||||
|
"params": {
|
||||||
|
"sortby": "assigned_at DESC",
|
||||||
|
"logined_userorgid": "org_id",
|
||||||
|
"browserfields": {
|
||||||
|
"exclouded": ["id", "instance_id", "step_id", "org_id"]
|
||||||
|
},
|
||||||
|
"editexclouded": ["id", "instance_id", "step_id", "org_id"],
|
||||||
|
"alterations": [
|
||||||
|
{
|
||||||
|
"field": "status",
|
||||||
|
"widgettype": "Select",
|
||||||
|
"options": {
|
||||||
|
"data": "get_code('TASK_STATUS')"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"field": "approver_id",
|
||||||
|
"widgettype": "Select",
|
||||||
|
"options": {
|
||||||
|
"data": "get_org_users(org_id)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
19
json/approval_workflow.json
Normal file
19
json/approval_workflow.json
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
{
|
||||||
|
"tblname": "approval_workflow",
|
||||||
|
"title": "审批工作流",
|
||||||
|
"params": {
|
||||||
|
"sortby": "workflow_name",
|
||||||
|
"logined_userorgid": "org_id",
|
||||||
|
"browserfields": {
|
||||||
|
"exclouded": ["id", "org_id", "created_at", "updated_at"]
|
||||||
|
},
|
||||||
|
"editexclouded": ["id", "org_id"],
|
||||||
|
"subtables": [
|
||||||
|
{
|
||||||
|
"field": "id",
|
||||||
|
"title": "审批步骤",
|
||||||
|
"subtable": "approval_step"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
133
models/approval_instance.json
Normal file
133
models/approval_instance.json
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
{
|
||||||
|
"summary": {
|
||||||
|
"name": "approval_instance",
|
||||||
|
"label": "审批实例",
|
||||||
|
"comment": "具体的审批实例记录"
|
||||||
|
},
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"name": "id",
|
||||||
|
"title": "ID",
|
||||||
|
"type": "str",
|
||||||
|
"length": 32,
|
||||||
|
"nullable": false,
|
||||||
|
"comments": "主键UUID"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "workflow_id",
|
||||||
|
"title": "工作流ID",
|
||||||
|
"type": "str",
|
||||||
|
"length": 32,
|
||||||
|
"nullable": false,
|
||||||
|
"comments": "关联的工作流定义"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "module_type",
|
||||||
|
"title": "模块类型",
|
||||||
|
"type": "str",
|
||||||
|
"length": 50,
|
||||||
|
"nullable": false,
|
||||||
|
"comments": "customer/opportunity/contract/financial"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "module_record_id",
|
||||||
|
"title": "模块记录ID",
|
||||||
|
"type": "str",
|
||||||
|
"length": 32,
|
||||||
|
"nullable": false,
|
||||||
|
"comments": "关联的具体业务记录ID"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "current_step_id",
|
||||||
|
"title": "当前步骤ID",
|
||||||
|
"type": "str",
|
||||||
|
"length": 32,
|
||||||
|
"nullable": true,
|
||||||
|
"comments": "当前待审批的步骤"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "status",
|
||||||
|
"title": "状态",
|
||||||
|
"type": "str",
|
||||||
|
"length": 20,
|
||||||
|
"nullable": false,
|
||||||
|
"comments": "pending/approved/rejected/cancelled"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "initiator_id",
|
||||||
|
"title": "发起人ID",
|
||||||
|
"type": "str",
|
||||||
|
"length": 32,
|
||||||
|
"nullable": false,
|
||||||
|
"comments": "审批发起人用户ID"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "title",
|
||||||
|
"title": "标题",
|
||||||
|
"type": "str",
|
||||||
|
"length": 200,
|
||||||
|
"nullable": false,
|
||||||
|
"comments": "审批标题"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "description",
|
||||||
|
"title": "描述",
|
||||||
|
"type": "str",
|
||||||
|
"length": 1000,
|
||||||
|
"nullable": true,
|
||||||
|
"comments": "审批详细描述"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "org_id",
|
||||||
|
"title": "组织ID",
|
||||||
|
"type": "str",
|
||||||
|
"length": 32,
|
||||||
|
"nullable": false,
|
||||||
|
"comments": "多租户组织隔离"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "created_at",
|
||||||
|
"title": "创建时间",
|
||||||
|
"type": "timestamp",
|
||||||
|
"nullable": false,
|
||||||
|
"comments": "创建时间"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "completed_at",
|
||||||
|
"title": "完成时间",
|
||||||
|
"type": "timestamp",
|
||||||
|
"nullable": true,
|
||||||
|
"comments": "完成时间"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"indexes": [
|
||||||
|
{
|
||||||
|
"name": "idx_instance_workflow",
|
||||||
|
"idxtype": "index",
|
||||||
|
"fields": ["workflow_id"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "idx_instance_module",
|
||||||
|
"idxtype": "index",
|
||||||
|
"fields": ["module_type", "module_record_id"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "idx_instance_status",
|
||||||
|
"idxtype": "index",
|
||||||
|
"fields": ["status"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "idx_instance_org",
|
||||||
|
"idxtype": "index",
|
||||||
|
"fields": ["org_id"]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"codes": [
|
||||||
|
{
|
||||||
|
"tblname": "appcodes",
|
||||||
|
"codevalue": "APPROVAL_STATUS",
|
||||||
|
"valuefield": "k",
|
||||||
|
"textfield": "v"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
113
models/approval_step.json
Normal file
113
models/approval_step.json
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
{
|
||||||
|
"summary": {
|
||||||
|
"name": "approval_step",
|
||||||
|
"label": "审批步骤",
|
||||||
|
"comment": "审批工作流步骤定义"
|
||||||
|
},
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"name": "id",
|
||||||
|
"title": "ID",
|
||||||
|
"type": "str",
|
||||||
|
"length": 32,
|
||||||
|
"nullable": false,
|
||||||
|
"comments": "主键UUID"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "workflow_id",
|
||||||
|
"title": "工作流ID",
|
||||||
|
"type": "str",
|
||||||
|
"length": 32,
|
||||||
|
"nullable": false,
|
||||||
|
"comments": "关联的工作流"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "step_name",
|
||||||
|
"title": "步骤名称",
|
||||||
|
"type": "str",
|
||||||
|
"length": 100,
|
||||||
|
"nullable": false,
|
||||||
|
"comments": "审批步骤名称"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "step_order",
|
||||||
|
"title": "步骤顺序",
|
||||||
|
"type": "long",
|
||||||
|
"nullable": false,
|
||||||
|
"comments": "步骤执行顺序"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "approver_type",
|
||||||
|
"title": "审批人类型",
|
||||||
|
"type": "str",
|
||||||
|
"length": 20,
|
||||||
|
"nullable": false,
|
||||||
|
"comments": "role/user/department/dynamic"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "approver_value",
|
||||||
|
"title": "审批人值",
|
||||||
|
"type": "str",
|
||||||
|
"length": 100,
|
||||||
|
"nullable": true,
|
||||||
|
"comments": "角色ID/用户ID/部门ID/动态表达式"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "approval_type",
|
||||||
|
"title": "审批类型",
|
||||||
|
"type": "str",
|
||||||
|
"length": 20,
|
||||||
|
"nullable": false,
|
||||||
|
"comments": "single/multiple/sequential/parallel"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "timeout_hours",
|
||||||
|
"title": "超时小时数",
|
||||||
|
"type": "long",
|
||||||
|
"nullable": true,
|
||||||
|
"comments": "审批超时时间(小时)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "description",
|
||||||
|
"title": "描述",
|
||||||
|
"type": "str",
|
||||||
|
"length": 500,
|
||||||
|
"nullable": true,
|
||||||
|
"comments": "步骤描述"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "org_id",
|
||||||
|
"title": "组织ID",
|
||||||
|
"type": "str",
|
||||||
|
"length": 32,
|
||||||
|
"nullable": false,
|
||||||
|
"comments": "多租户组织隔离"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"indexes": [
|
||||||
|
{
|
||||||
|
"name": "idx_step_workflow",
|
||||||
|
"idxtype": "index",
|
||||||
|
"fields": ["workflow_id"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "idx_step_order",
|
||||||
|
"idxtype": "index",
|
||||||
|
"fields": ["workflow_id", "step_order"]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"codes": [
|
||||||
|
{
|
||||||
|
"tblname": "appcodes",
|
||||||
|
"codevalue": "APPROVER_TYPE",
|
||||||
|
"valuefield": "k",
|
||||||
|
"textfield": "v"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"tblname": "appcodes",
|
||||||
|
"codevalue": "APPROVAL_TYPE",
|
||||||
|
"valuefield": "k",
|
||||||
|
"textfield": "v"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
111
models/approval_task.json
Normal file
111
models/approval_task.json
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
{
|
||||||
|
"summary": {
|
||||||
|
"name": "approval_task",
|
||||||
|
"label": "审批任务",
|
||||||
|
"comment": "具体的审批任务分配"
|
||||||
|
},
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"name": "id",
|
||||||
|
"title": "ID",
|
||||||
|
"type": "str",
|
||||||
|
"length": 32,
|
||||||
|
"nullable": false,
|
||||||
|
"comments": "主键UUID"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "instance_id",
|
||||||
|
"title": "实例ID",
|
||||||
|
"type": "str",
|
||||||
|
"length": 32,
|
||||||
|
"nullable": false,
|
||||||
|
"comments": "关联的审批实例"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "step_id",
|
||||||
|
"title": "步骤ID",
|
||||||
|
"type": "str",
|
||||||
|
"length": 32,
|
||||||
|
"nullable": false,
|
||||||
|
"comments": "关联的审批步骤"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "approver_id",
|
||||||
|
"title": "审批人ID",
|
||||||
|
"type": "str",
|
||||||
|
"length": 32,
|
||||||
|
"nullable": false,
|
||||||
|
"comments": "具体审批人用户ID"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "status",
|
||||||
|
"title": "状态",
|
||||||
|
"type": "str",
|
||||||
|
"length": 20,
|
||||||
|
"nullable": false,
|
||||||
|
"comments": "pending/approved/rejected"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "decision",
|
||||||
|
"title": "决策",
|
||||||
|
"type": "str",
|
||||||
|
"length": 1000,
|
||||||
|
"nullable": true,
|
||||||
|
"comments": "审批意见"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "org_id",
|
||||||
|
"title": "组织ID",
|
||||||
|
"type": "str",
|
||||||
|
"length": 32,
|
||||||
|
"nullable": false,
|
||||||
|
"comments": "多租户组织隔离"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "assigned_at",
|
||||||
|
"title": "分配时间",
|
||||||
|
"type": "timestamp",
|
||||||
|
"nullable": false,
|
||||||
|
"comments": "任务分配时间"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "completed_at",
|
||||||
|
"title": "完成时间",
|
||||||
|
"type": "timestamp",
|
||||||
|
"nullable": true,
|
||||||
|
"comments": "任务完成时间"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "due_at",
|
||||||
|
"title": "截止时间",
|
||||||
|
"type": "timestamp",
|
||||||
|
"nullable": true,
|
||||||
|
"comments": "任务截止时间"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"indexes": [
|
||||||
|
{
|
||||||
|
"name": "idx_task_instance",
|
||||||
|
"idxtype": "index",
|
||||||
|
"fields": ["instance_id"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "idx_task_approver",
|
||||||
|
"idxtype": "index",
|
||||||
|
"fields": ["approver_id"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "idx_task_status",
|
||||||
|
"idxtype": "index",
|
||||||
|
"fields": ["status"]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"codes": [
|
||||||
|
{
|
||||||
|
"tblname": "appcodes",
|
||||||
|
"codevalue": "TASK_STATUS",
|
||||||
|
"valuefield": "k",
|
||||||
|
"textfield": "v"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
97
models/approval_workflow.json
Normal file
97
models/approval_workflow.json
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
{
|
||||||
|
"summary": {
|
||||||
|
"name": "approval_workflow",
|
||||||
|
"label": "审批工作流",
|
||||||
|
"comment": "跨模块审批工作流定义"
|
||||||
|
},
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"name": "id",
|
||||||
|
"title": "ID",
|
||||||
|
"type": "str",
|
||||||
|
"length": 32,
|
||||||
|
"nullable": false,
|
||||||
|
"comments": "主键UUID"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "workflow_name",
|
||||||
|
"title": "工作流名称",
|
||||||
|
"type": "str",
|
||||||
|
"length": 100,
|
||||||
|
"nullable": false,
|
||||||
|
"comments": "审批工作流名称"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "module_type",
|
||||||
|
"title": "模块类型",
|
||||||
|
"type": "str",
|
||||||
|
"length": 50,
|
||||||
|
"nullable": false,
|
||||||
|
"comments": "关联的模块类型(customer/opportunity/contract/financial)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "trigger_condition",
|
||||||
|
"title": "触发条件",
|
||||||
|
"type": "str",
|
||||||
|
"length": 500,
|
||||||
|
"nullable": true,
|
||||||
|
"comments": "JSON格式的触发条件表达式"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "description",
|
||||||
|
"title": "描述",
|
||||||
|
"type": "str",
|
||||||
|
"length": 500,
|
||||||
|
"nullable": true,
|
||||||
|
"comments": "工作流描述"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "org_id",
|
||||||
|
"title": "组织ID",
|
||||||
|
"type": "str",
|
||||||
|
"length": 32,
|
||||||
|
"nullable": false,
|
||||||
|
"comments": "多租户组织隔离"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "created_at",
|
||||||
|
"title": "创建时间",
|
||||||
|
"type": "timestamp",
|
||||||
|
"nullable": false,
|
||||||
|
"comments": "创建时间"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "updated_at",
|
||||||
|
"title": "更新时间",
|
||||||
|
"type": "timestamp",
|
||||||
|
"nullable": false,
|
||||||
|
"comments": "更新时间"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "is_active",
|
||||||
|
"title": "是否激活",
|
||||||
|
"type": "str",
|
||||||
|
"length": 1,
|
||||||
|
"nullable": false,
|
||||||
|
"comments": "Y/N"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"indexes": [
|
||||||
|
{
|
||||||
|
"name": "idx_workflow_org",
|
||||||
|
"idxtype": "index",
|
||||||
|
"fields": ["org_id"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "idx_workflow_module",
|
||||||
|
"idxtype": "index",
|
||||||
|
"fields": ["module_type"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "uk_workflow_name_org",
|
||||||
|
"idxtype": "unique",
|
||||||
|
"fields": ["workflow_name", "org_id"]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"codes": []
|
||||||
|
}
|
||||||
0
mysql.ddl.sql
Normal file
0
mysql.ddl.sql
Normal file
33
pyproject.toml
Normal file
33
pyproject.toml
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
[build-system]
|
||||||
|
requires = ["setuptools>=61.0", "wheel"]
|
||||||
|
build-backend = "setuptools.build_meta"
|
||||||
|
|
||||||
|
[project]
|
||||||
|
name = "workflow-approval"
|
||||||
|
version = "1.0.0"
|
||||||
|
description = "Cross-module approval workflow management for integrated CRM application"
|
||||||
|
authors = [{name = "Hermes AI Agent", email = "hermes@ai-agent.com"}]
|
||||||
|
license = {text = "MIT"}
|
||||||
|
readme = "README.md"
|
||||||
|
requires-python = ">=3.8"
|
||||||
|
classifiers = [
|
||||||
|
"Development Status :: 5 - Production/Stable",
|
||||||
|
"Intended Audience :: Developers",
|
||||||
|
"License :: OSI Approved :: MIT License",
|
||||||
|
"Programming Language :: Python :: 3",
|
||||||
|
"Programming Language :: Python :: 3.8",
|
||||||
|
"Programming Language :: Python :: 3.9",
|
||||||
|
"Programming Language :: Python :: 3.10",
|
||||||
|
]
|
||||||
|
dependencies = [
|
||||||
|
"ahserver>=1.0.0",
|
||||||
|
"sqlor-database-module>=1.0.0",
|
||||||
|
"bricks-framework>=1.0.0"
|
||||||
|
]
|
||||||
|
|
||||||
|
[project.optional-dependencies]
|
||||||
|
dev = ["pytest>=6.0", "black", "flake8"]
|
||||||
|
|
||||||
|
[tool.setuptools.packages.find]
|
||||||
|
where = ["."]
|
||||||
|
include = ["workflow_approval*"]
|
||||||
228
workflow_approval/core.py
Normal file
228
workflow_approval/core.py
Normal file
@ -0,0 +1,228 @@
|
|||||||
|
from ahserver.serverenv import ServerEnv
|
||||||
|
from appPublic.worker import awaitify
|
||||||
|
import json
|
||||||
|
import uuid
|
||||||
|
from datetime import datetime, timedelta
|
||||||
|
|
||||||
|
class WorkflowCore:
|
||||||
|
def __init__(self, db):
|
||||||
|
self.db = db
|
||||||
|
|
||||||
|
async def create_workflow(self, workflow_data, org_id):
|
||||||
|
"""创建审批工作流"""
|
||||||
|
workflow_id = str(uuid.uuid4()).replace('-', '')
|
||||||
|
workflow_data['id'] = workflow_id
|
||||||
|
workflow_data['org_id'] = org_id
|
||||||
|
workflow_data['created_at'] = datetime.now()
|
||||||
|
workflow_data['updated_at'] = datetime.now()
|
||||||
|
workflow_data['is_active'] = 'Y'
|
||||||
|
|
||||||
|
await self.db.insert('approval_workflow', workflow_data)
|
||||||
|
return workflow_id
|
||||||
|
|
||||||
|
async def create_approval_step(self, step_data, org_id):
|
||||||
|
"""创建审批步骤"""
|
||||||
|
step_id = str(uuid.uuid4()).replace('-', '')
|
||||||
|
step_data['id'] = step_id
|
||||||
|
step_data['org_id'] = org_id
|
||||||
|
|
||||||
|
await self.db.insert('approval_step', step_data)
|
||||||
|
return step_id
|
||||||
|
|
||||||
|
async def start_approval_instance(self, module_type, module_record_id,
|
||||||
|
initiator_id, title, description, org_id):
|
||||||
|
"""启动审批实例"""
|
||||||
|
# 查找适用的工作流
|
||||||
|
workflows = await self.db.select('approval_workflow',
|
||||||
|
where={'module_type': module_type, 'org_id': org_id, 'is_active': 'Y'})
|
||||||
|
|
||||||
|
if not workflows:
|
||||||
|
raise Exception(f"No active workflow found for module: {module_type}")
|
||||||
|
|
||||||
|
# 使用第一个匹配的工作流(实际可按条件筛选)
|
||||||
|
workflow = workflows[0]
|
||||||
|
instance_id = str(uuid.uuid4()).replace('-', '')
|
||||||
|
|
||||||
|
instance_data = {
|
||||||
|
'id': instance_id,
|
||||||
|
'workflow_id': workflow['id'],
|
||||||
|
'module_type': module_type,
|
||||||
|
'module_record_id': module_record_id,
|
||||||
|
'current_step_id': None,
|
||||||
|
'status': 'pending',
|
||||||
|
'initiator_id': initiator_id,
|
||||||
|
'title': title,
|
||||||
|
'description': description,
|
||||||
|
'org_id': org_id,
|
||||||
|
'created_at': datetime.now(),
|
||||||
|
'completed_at': None
|
||||||
|
}
|
||||||
|
|
||||||
|
await self.db.insert('approval_instance', instance_data)
|
||||||
|
|
||||||
|
# 创建第一步的审批任务
|
||||||
|
await self._create_next_step_tasks(instance_id, workflow['id'], org_id)
|
||||||
|
|
||||||
|
return instance_id
|
||||||
|
|
||||||
|
async def _create_next_step_tasks(self, instance_id, workflow_id, org_id):
|
||||||
|
"""创建下一步的审批任务"""
|
||||||
|
# 获取当前已完成的步骤
|
||||||
|
completed_steps = await self.db.select('approval_task',
|
||||||
|
fields=['step_id'],
|
||||||
|
where={'instance_id': instance_id, 'status': 'approved'},
|
||||||
|
distinct=True
|
||||||
|
)
|
||||||
|
completed_step_ids = [task['step_id'] for task in completed_steps]
|
||||||
|
|
||||||
|
# 获取下一个未完成的步骤
|
||||||
|
next_step = await self.db.select('approval_step',
|
||||||
|
where={
|
||||||
|
'workflow_id': workflow_id,
|
||||||
|
'org_id': org_id
|
||||||
|
},
|
||||||
|
order_by='step_order ASC'
|
||||||
|
)
|
||||||
|
|
||||||
|
if not next_step:
|
||||||
|
# 所有步骤完成,更新实例状态
|
||||||
|
await self.db.update('approval_instance',
|
||||||
|
data={'status': 'approved', 'completed_at': datetime.now()},
|
||||||
|
where={'id': instance_id}
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
|
current_step = None
|
||||||
|
for step in next_step:
|
||||||
|
if step['id'] not in completed_step_ids:
|
||||||
|
current_step = step
|
||||||
|
break
|
||||||
|
|
||||||
|
if not current_step:
|
||||||
|
# 所有步骤完成
|
||||||
|
await self.db.update('approval_instance',
|
||||||
|
data={'status': 'approved', 'completed_at': datetime.now()},
|
||||||
|
where={'id': instance_id}
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
|
# 更新实例当前步骤
|
||||||
|
await self.db.update('approval_instance',
|
||||||
|
data={'current_step_id': current_step['id']},
|
||||||
|
where={'id': instance_id}
|
||||||
|
)
|
||||||
|
|
||||||
|
# 确定审批人
|
||||||
|
approvers = await self._resolve_approvers(current_step, org_id)
|
||||||
|
|
||||||
|
# 创建审批任务
|
||||||
|
for approver_id in approvers:
|
||||||
|
task_id = str(uuid.uuid4()).replace('-', '')
|
||||||
|
due_at = None
|
||||||
|
if current_step.get('timeout_hours'):
|
||||||
|
due_at = datetime.now() + timedelta(hours=current_step['timeout_hours'])
|
||||||
|
|
||||||
|
task_data = {
|
||||||
|
'id': task_id,
|
||||||
|
'instance_id': instance_id,
|
||||||
|
'step_id': current_step['id'],
|
||||||
|
'approver_id': approver_id,
|
||||||
|
'status': 'pending',
|
||||||
|
'decision': None,
|
||||||
|
'org_id': org_id,
|
||||||
|
'assigned_at': datetime.now(),
|
||||||
|
'completed_at': None,
|
||||||
|
'due_at': due_at
|
||||||
|
}
|
||||||
|
await self.db.insert('approval_task', task_data)
|
||||||
|
|
||||||
|
async def _resolve_approvers(self, step, org_id):
|
||||||
|
"""解析审批人"""
|
||||||
|
approver_type = step['approver_type']
|
||||||
|
approver_value = step['approver_value']
|
||||||
|
|
||||||
|
if approver_type == 'user':
|
||||||
|
return [approver_value]
|
||||||
|
elif approver_type == 'role':
|
||||||
|
# 从RBAC获取角色用户
|
||||||
|
from rbac.userperm import get_role_users
|
||||||
|
return await get_role_users(approver_value, org_id)
|
||||||
|
elif approver_type == 'department':
|
||||||
|
# 获取部门用户
|
||||||
|
from rbac.userperm import get_department_users
|
||||||
|
return await get_department_users(approver_value, org_id)
|
||||||
|
elif approver_type == 'dynamic':
|
||||||
|
# 动态表达式解析(简化实现)
|
||||||
|
return self._evaluate_dynamic_expression(approver_value, org_id)
|
||||||
|
else:
|
||||||
|
return []
|
||||||
|
|
||||||
|
def _evaluate_dynamic_expression(self, expression, org_id):
|
||||||
|
"""评估动态表达式(简化实现)"""
|
||||||
|
# 实际实现中可以使用更复杂的表达式引擎
|
||||||
|
if expression == 'record_owner':
|
||||||
|
# 返回记录所有者(需要从具体模块获取)
|
||||||
|
return []
|
||||||
|
elif expression == 'department_manager':
|
||||||
|
return []
|
||||||
|
else:
|
||||||
|
return []
|
||||||
|
|
||||||
|
async def approve_task(self, task_id, approver_id, decision, org_id):
|
||||||
|
"""审批任务"""
|
||||||
|
# 验证任务存在且属于当前用户
|
||||||
|
task = await self.db.select_one('approval_task',
|
||||||
|
where={'id': task_id, 'approver_id': approver_id, 'org_id': org_id})
|
||||||
|
|
||||||
|
if not task or task['status'] != 'pending':
|
||||||
|
raise Exception("Invalid task or already processed")
|
||||||
|
|
||||||
|
# 更新任务状态
|
||||||
|
await self.db.update('approval_task',
|
||||||
|
data={
|
||||||
|
'status': 'approved',
|
||||||
|
'decision': decision,
|
||||||
|
'completed_at': datetime.now()
|
||||||
|
},
|
||||||
|
where={'id': task_id}
|
||||||
|
)
|
||||||
|
|
||||||
|
# 检查是否所有并行任务都完成了
|
||||||
|
instance_id = task['instance_id']
|
||||||
|
step_id = task['step_id']
|
||||||
|
pending_tasks = await self.db.select('approval_task',
|
||||||
|
where={
|
||||||
|
'instance_id': instance_id,
|
||||||
|
'step_id': step_id,
|
||||||
|
'status': 'pending'
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
if not pending_tasks:
|
||||||
|
# 当前步骤完成,创建下一步任务
|
||||||
|
instance = await self.db.select_one('approval_instance',
|
||||||
|
where={'id': instance_id})
|
||||||
|
await self._create_next_step_tasks(instance_id, instance['workflow_id'], org_id)
|
||||||
|
|
||||||
|
async def reject_task(self, task_id, approver_id, decision, org_id):
|
||||||
|
"""拒绝任务"""
|
||||||
|
await self.db.update('approval_task',
|
||||||
|
data={
|
||||||
|
'status': 'rejected',
|
||||||
|
'decision': decision,
|
||||||
|
'completed_at': datetime.now()
|
||||||
|
},
|
||||||
|
where={'id': task_id, 'approver_id': approver_id, 'org_id': org_id}
|
||||||
|
)
|
||||||
|
|
||||||
|
# 更新实例状态为拒绝
|
||||||
|
task = await self.db.select_one('approval_task', where={'id': task_id})
|
||||||
|
await self.db.update('approval_instance',
|
||||||
|
data={'status': 'rejected', 'completed_at': datetime.now()},
|
||||||
|
where={'id': task['instance_id']}
|
||||||
|
)
|
||||||
|
|
||||||
|
def load_workflow_approval():
|
||||||
|
"""加载审批模块"""
|
||||||
|
env = ServerEnv()
|
||||||
|
env.workflow_core = WorkflowCore
|
||||||
15
workflow_approval/init.py
Normal file
15
workflow_approval/init.py
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
from ahserver.serverenv import ServerEnv
|
||||||
|
from appPublic.worker import awaitify
|
||||||
|
from .core import WorkflowCore
|
||||||
|
|
||||||
|
def load_workflow_approval():
|
||||||
|
"""加载跨模块审批流程模块"""
|
||||||
|
env = ServerEnv()
|
||||||
|
|
||||||
|
# 创建核心实例的工厂函数
|
||||||
|
async def create_workflow_core(org_id):
|
||||||
|
from sqlor.dbp import getDBP
|
||||||
|
db = await getDBP(org_id)
|
||||||
|
return WorkflowCore(db)
|
||||||
|
|
||||||
|
env.create_workflow_core = create_workflow_core
|
||||||
66
wwwroot/approval_task_detail.ui
Normal file
66
wwwroot/approval_task_detail.ui
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
{
|
||||||
|
"widgettype": "VBox",
|
||||||
|
"options": {
|
||||||
|
"maxWidth": "100%",
|
||||||
|
"padding": "15px"
|
||||||
|
},
|
||||||
|
"subwidgets": [
|
||||||
|
{
|
||||||
|
"widgettype": "Text",
|
||||||
|
"options": {
|
||||||
|
"text": "审批详情",
|
||||||
|
"fontSize": "18px",
|
||||||
|
"fontWeight": "bold",
|
||||||
|
"marginBottom": "20px"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"widgettype": "Form",
|
||||||
|
"options": {
|
||||||
|
"tblname": "approval_task",
|
||||||
|
"mode": "view",
|
||||||
|
"fields": ["title", "step_name", "description", "assigned_at", "due_at"],
|
||||||
|
"fieldLabels": {
|
||||||
|
"title": "审批事项",
|
||||||
|
"step_name": "审批步骤",
|
||||||
|
"description": "详细说明",
|
||||||
|
"assigned_at": "分配时间",
|
||||||
|
"due_at": "截止时间"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"widgettype": "HBox",
|
||||||
|
"options": {
|
||||||
|
"marginTop": "30px",
|
||||||
|
"gap": "10px"
|
||||||
|
},
|
||||||
|
"subwidgets": [
|
||||||
|
{
|
||||||
|
"widgettype": "Button",
|
||||||
|
"options": {
|
||||||
|
"text": "批准",
|
||||||
|
"onClick": "approve_task",
|
||||||
|
"style": {
|
||||||
|
"backgroundColor": "#28a745",
|
||||||
|
"color": "white",
|
||||||
|
"flex": "1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"widgettype": "Button",
|
||||||
|
"options": {
|
||||||
|
"text": "拒绝",
|
||||||
|
"onClick": "reject_task",
|
||||||
|
"style": {
|
||||||
|
"backgroundColor": "#dc3545",
|
||||||
|
"color": "white",
|
||||||
|
"flex": "1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
98
wwwroot/mobile_base.ui
Normal file
98
wwwroot/mobile_base.ui
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
{
|
||||||
|
"widgettype": "VBox",
|
||||||
|
"options": {
|
||||||
|
"maxWidth": "100%",
|
||||||
|
"padding": "10px"
|
||||||
|
},
|
||||||
|
"subwidgets": [
|
||||||
|
{
|
||||||
|
"widgettype": "HBox",
|
||||||
|
"options": {
|
||||||
|
"alignItems": "center",
|
||||||
|
"justifyContent": "space-between",
|
||||||
|
"marginBottom": "15px"
|
||||||
|
},
|
||||||
|
"subwidgets": [
|
||||||
|
{
|
||||||
|
"widgettype": "Text",
|
||||||
|
"options": {
|
||||||
|
"text": "审批中心",
|
||||||
|
"fontSize": "20px",
|
||||||
|
"fontWeight": "bold"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"widgettype": "Button",
|
||||||
|
"options": {
|
||||||
|
"text": "发起审批",
|
||||||
|
"onClick": "goto('workflow_approval/approval_instance/create.ui')",
|
||||||
|
"style": {
|
||||||
|
"backgroundColor": "#007bff",
|
||||||
|
"color": "white",
|
||||||
|
"border": "none",
|
||||||
|
"padding": "8px 16px",
|
||||||
|
"borderRadius": "4px"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"widgettype": "TabPanel",
|
||||||
|
"options": {
|
||||||
|
"tabs": [
|
||||||
|
{
|
||||||
|
"title": "待我审批",
|
||||||
|
"content": {
|
||||||
|
"widgettype": "DataGrid",
|
||||||
|
"options": {
|
||||||
|
"tblname": "approval_task",
|
||||||
|
"where": {
|
||||||
|
"approver_id": "${logined_userid}",
|
||||||
|
"status": "pending"
|
||||||
|
},
|
||||||
|
"fields": ["title", "step_name", "assigned_at", "due_at"],
|
||||||
|
"fieldLabels": {
|
||||||
|
"title": "审批事项",
|
||||||
|
"step_name": "步骤",
|
||||||
|
"assigned_at": "分配时间",
|
||||||
|
"due_at": "截止时间"
|
||||||
|
},
|
||||||
|
"onRowClick": "goto('workflow_approval/approval_task/detail.ui?id=${id}')"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "我发起的",
|
||||||
|
"content": {
|
||||||
|
"widgettype": "DataGrid",
|
||||||
|
"options": {
|
||||||
|
"tblname": "approval_instance",
|
||||||
|
"where": {
|
||||||
|
"initiator_id": "${logined_userid}"
|
||||||
|
},
|
||||||
|
"fields": ["title", "status", "created_at", "completed_at"],
|
||||||
|
"fieldLabels": {
|
||||||
|
"title": "审批事项",
|
||||||
|
"status": "状态",
|
||||||
|
"created_at": "发起时间",
|
||||||
|
"completed_at": "完成时间"
|
||||||
|
},
|
||||||
|
"onRowClick": "goto('workflow_approval/approval_instance/detail.ui?id=${id}')"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "工作流管理",
|
||||||
|
"content": {
|
||||||
|
"widgettype": "Frame",
|
||||||
|
"options": {
|
||||||
|
"src": "workflow_approval/approval_workflow/list.ui"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user