# 流程集成指南

# 环境准备

@adam/flow和@adam/glink共同压缩引用在一个工程中占据运行内存较大,建议node配置14.0版本以上,node新版支持扩展内存

  • 平台提供流程组件包:@adam/flow
  • 平台提供glink组件包:@adam/glink

# 安装开发工具库

使用 npm 的方式安装,它能更好地和 webpack 打包工具配合使用。

注意:

  1. 安装之前要确保已把 npm registry 设置为公司内网地址,如: registry=http://nexus.gosp.glkyun.com/repository/npm-all/ (opens new window)。 另外此包需要结合webpack配置使用
  2. 依赖包使用固定版本

npm install @adam/flow@0.5.99

npm install @adam/glink@2.1.2

# 使用说明

如使用qiankun,需进行样式隔离,具体可参考- 微前端集成指南-子应用集成说明

主要包括:

  1. 入口配置
  2. 路由配置
  3. 组件及公共方法使用

# 1. 入口配置

环境变量配置

# 路由统一前缀,用于匹配当前微应用,如:
VUE_APP_ROUTER_BASE = '/glink-leave'
1
2

更改入口文件

使用glink-cloud-platform-micro-demo脚手架:

import Vue from 'vue'
import btnAuths from './config'
import store from '@/views/common/store'
import storage from '@/utils/cache'

// 加载icon
import '../assets/icons'

import { default as Element } from 'element-ui'
Vue.use(Element)

// 加载glink组件
import { Glink } from '@adam/glink'
import '@adam/glink/dist/adam-glink.css'

// 加载流程
import { Flow } from '@adam/flow'
import '@adam/flow/dist/adam-flow.css'


const requestOptions = {
  baseURL: '/api/',
  timeout: 16000,
  headers: {
    'x-nepoch-org': storage.getItem('DEPT_ID_CACHE'), // 组织id
    'x-nepoch-tenant': storage.getItem('CURRENT_RENT')?.id || '1527589324236275712', // 租户id
    'x-nepoch-productCode': storage.getItem('PROJECT_INFO')?.productCode || '', // 产品code
    'x-nepoch-productId': storage.getItem('PROJECT_INFO')?.productId || '', // 产品id
    'x-nepoch-subsystemId': storage.getItem('PROJECT_INFO')?.subsystemId || '',  // 子系统id
    'x-nepoch-mode': storage.getItem('PROJECT_INFO')?.functionModelId || '' // 模块id
  }
}

// glink
Vue.use(Glink, {
  requestOptions: requestOptions,
  auths: btnAuths.setting_button /* 定义了一些按钮权限的配置*/,
  lookupType: true, // 字典选项是否只输出字符串,设置false即把字典中的"1"输出为Number类型,字典中的"true"输出为Boolean
  model: require(`./config/glink_config`),
  productName: storage.getItem('PROJECT_INFO')?.productCode // 产品code,从sessionStorage中取PROJECT_INFO,需要进行JSON.parse解析
})

 // 流程模块
 Vue.use(Flow, {
  store, // 必传参数,项目中的vuex
  requestOptions: requestOptions, // 必传参数
  columnsIsExpand: false, // 非必传参数:默认false,true-列表显示审批类型、节点类型、审批人
  processInstIdIsShow:false, // 非必传参数:默认false,true-处理记录列表显示流程实例id
  lookupType: true,// 非必传参数,默认true,字典选项是否只输出字符串,false-即把字典中的"1"输出为Number类型,字典中的"true"输出为Boolean
  model: require(`./config/glink_config`), // 非必传参数,模式区分,默认local,铁建-crec
  baseRouterUrl:process.env.VUE_APP_ROUTER_BASE, // 必传参数,微应用的路由前缀
  productName: storage.getItem('PROJECT_INFO')?.productCode // 必传参数,产品code,从sessionStorage中取PROJECT_INFO,需要进行JSON.parse解析
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53

不使用glink-cloud-platform-micro-demo脚手架:

import Vue from 'vue'
// 项目中vuex的store
import store from '@/views/common/store'

import { default as Element } from 'element-ui'
Vue.use(Element)

// 加载glink组件
import { Glink } from '@adam/glink'
import '@adam/glink/dist/adam-glink.css'

// 加载流程
import { Flow } from '@adam/flow'
import '@adam/flow/dist/adam-flow.css'

// sessionStorage缓存
const storage = {
  setItem(key, value) {
    window.sessionStorage.setItem(key, JSON.stringify(value))
  },
  getItem(key) {
    const value = window.sessionStorage.getItem(key)
    if (value && value != 'undefined') {
      return JSON.parse(value)
    }
  },
  removeItem(key) {
    window.sessionStorage.removeItem(key)
  },
  clear() {
    window.sessionStorage.clear()
  }
}

const glinkConfig = {
  GdForm: {
    needAuth: true, //是否默认控权
  },
  GdTable: {
    dialogBoxHeight: '450px', //dialog内部table高度
    needAuth: false, //是否默认控权,GdAttament
  },
  GdTree: {
    needAuth: false, //是否默认控权
  }
}

const requestOptions = {
  baseURL: '/api/',
  timeout: 16000,
  headers: {
    'x-nepoch-org': storage.getItem('DEPT_ID_CACHE'), // 组织id
    'x-nepoch-tenant': storage.getItem('CURRENT_RENT')?.id || '1527589324236275712', // 租户id
    'x-nepoch-productCode': storage.getItem('PROJECT_INFO')?.productCode || '', // 产品code
    'x-nepoch-productId': storage.getItem('PROJECT_INFO')?.productId || '', // 产品id
    'x-nepoch-subsystemId': storage.getItem('PROJECT_INFO')?.subsystemId || '',  // 子系统id
    'x-nepoch-mode': storage.getItem('PROJECT_INFO')?.functionModelId || '' // 模块id
  }
}

// glink
Vue.use(Glink, {
  requestOptions: requestOptions,
  auths: {} /* 定义了一些按钮权限的配置*/,
  lookupType: true, // 字典选项是否只输出字符串,设置false即把字典中的"1"输出为Number类型,字典中的"true"输出为Boolean
  model: glinkConfig,
  productName: storage.getItem('PROJECT_INFO')?.productCode // 产品code,从sessionStorage中取PROJECT_INFO,需要进行JSON.parse解析
})

//流程模块
Vue.use(Flow, {
  store, // 必传参数,项目中vuex的实例
  requestOptions: requestOptions, // 必传参数
  columnsIsExpand: false, // 非必传参数:默认false,true-列表显示审批类型、节点类型、审批人
  processInstIdIsShow:false, // 非必传参数:默认false,true-处理记录列表显示流程实例id
  lookupType: true, // 非必传参数,默认true,字典选项是否只输出字符串,false-即把字典中的"1"输出为Number类型,字典中的"true"输出为Boolean
  model: require(`./config/glink_config`), // 非必传参数,模式区分,默认local,铁建-crec
  baseRouterUrl:process.env.VUE_APP_ROUTER_BASE, // 必传参数,微应用的路由前缀
  productName: storage.getItem('PROJECT_INFO')?.productCode // 必传参数,产品code,从sessionStorage中取PROJECT_INFO,需要进行JSON.parse解析
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80

# 2. 路由配置

import { transactionRouterWrap } from @adam/flow

// 添加审批页面路由
const transactionRouter = transactionRouterWrap(layout, routes)

// 此处旨在给流程组件路由增加路由前缀
// 如使用glink-cloud-platform-micro-demo脚手架,此处省略
// 开始
const public_path = process.env.VUE_APP_ROUTER_BASE
transactionRouter[0].children.map(item=>{
  if(item.path.indexOf(public_path) === -1){
    item.path = public_path + item.path
  }
})
// 结束

routes.push(...transactionRouter[0].children)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

注意:在待办、已办、发起的详情页面,配置其路由时,需要增加meta参数 {isFlow: true}。例如:

// 如果使用@adam/flow中的待办、已办、发起页面,需在其对应的审批页面路由添加参数meta:{isFlow: true},如:
{
  path: '/leave/leave-edit',
  component: () => import('@business/views/leave/add-edit'),
  name: 'LeaveDetail',
  meta: {
    title: '请假申请详情',
    isFlow: true,
    root: 'Leave'
  }
}
1
2
3
4
5
6
7
8
9
10
11

审批表单地址配置:

如使用@adam/flow的审批页面,在流程设计器中对应审批节点配置【PC处理表单】,配置规则为:【路由前缀+/transaction/edit+业务页面路由】;

如使用自定义审批页面,则配置【PC处理URL】。

详情表单地址配置

# 3.组件及公共方法使用

流程提交方法

import { handleSubmit } from '@adam/flow'
// sessionStorage缓存
const storage = {
  setItem(key, value) {
    window.sessionStorage.setItem(key, JSON.stringify(value))
  },
  getItem(key) {
    const value = window.sessionStorage.getItem(key)
    if (value && value != 'undefined') {
      return JSON.parse(value)
    }
  },
  removeItem(key) {
    window.sessionStorage.removeItem(key)
  },
  clear() {
    window.sessionStorage.clear()
  }
}

// 提交
handleSubmit(row) {
  // 业务主键
  row.businessId = row.id
  // 业务编码
  row.businessCode = row.leaveNo
  // 业务类型编码
  row.businessTypeCode = FLOW_LEAVE_DECLARE
  // 业务页面参数:页面上表单参数
  row.businessPageParam = null
  //业务配置扩展字段
  row.businessExtendData = row.leaveDays + '天'
  // 申请人主键
  row.approvalPersonId = storage.getItem('USER_ID_CACHE') || ''
  // 申请人
  row.approvalPerson = storage.getItem('USER_NAME_CACHE') || ''
  // 申请部门主键
  row.approvalDeptId = storage.getItem('USER_DEPT_ID_CACHE') || '1529706568714043392'
  // 申请部门
  row.approvalDept = storage.getItem('USER_DEPT_NAME_CACHE') || '广联达天下集团'
  const obj = {}
  // 转化this
  obj.that = this
  // 提交表单内容
  obj.row = row
  // 提交接口
  obj.submitMethod = submitLeaveDetails
  // 提交成功后回调函数
  obj.submitCallback = this.submitCallback
  handleSubmit(obj)
},
// 提交成功后的回调函数:业务自己定,此处仅为示例
submitCallback(data) {
  if (data) {
    this._load()
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57

组件:处理轨迹-路由跳转形式

// 点击【处理轨迹】按钮
handleTrack(row) {
  if (!row) {
    this.$message({
      type: 'warning',
      message: '请选择要操作的数据'
    })
    return
  }
  if (row.status === 1) {
    this.$message({
      message: '请先提交流程',
      type: 'warning'
    })
    return
  }
  // 放弃弹窗,改用路由跳转
  this.$router.push({
    path: '/transaction/track',
    query: {
      recordId: row.id, // 业务主键
      code: FLOW_LEAVE_DECLARE, // 业务类型编码
      backTitle: '处理轨迹'
    }
  })
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

组件:处理轨迹-iframe嵌套形式

import { GdTrack } from '@adam/flow'
<!-- 
  recordId:业务主键
  code:业务类型编码
  contentHeight:页面高度,可以取localStorage.getItem('LAYOUT_CONTAINER_HEIGHT') + 'px'
-->
<gd-track
  v-if="activeName == 'track'"
  :record-id.sync="recordId"
  :code="code"
  showType="iframe"
  :height="contentHeight"
/>

1
2
3
4
5
6
7
8
9
10
11
12
13
14

组件:处理记录弹框

// 流程处理记录 GdRecord
import { GdRecord } from '@adam/flow'

// 业务使用示例
import { GdRecord } from '@adam/flow'
<!-- 处理记录弹框 -->
<!-- 
  showRecord: 处理记录弹框显示标识
  recordId: 业务主键
  code: 业务类型编码
  businessRowData: {} //当前先传次值
-->
<gd-record
  :visible.sync="showRecord"
  :record-id.sync="recordId"
  :code="code"
  :businessRowData="businessRowData"
/>

// 点击【处理记录】按钮:处理记录弹框显示
handleRecord(row) { 
  this.showRecord = true
  this.recordId = row[0].id
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

方法:审批按钮点击前回调方法

使用eventBus中央事件总线传递方法:审批按钮点击时发送事件,业务系统接收。

注意:业务系统接收事件后,必须返回一个Promise对象,以确保能够同步进行

技术栈:

// @adam/flow组件 源码
eventBus
    .emit(BEFORE_TRANSACTION_APPROVE_EVENT)
    .then(() => {
    // 通过
    this[flag]()
    console.log('校验通过')
})
    .catch(reject => {
    this.$message.warning('请先处理表单!')
    // 失败
    console.log('校验失败')
})
1
2
3
4
5
6
7
8
9
10
11
12
13

示例:业务系统使用,此处仅为示例

// 引入eventBus和事件名称
import { eventBus, BEFORE_TRANSACTION_APPROVE_EVENT } from '@adam/flow'

// 接收事件传递,常在created、mounted中
eventBus.on(
    BEFORE_TRANSACTION_APPROVE_EVENT,
    () => {
 // !!! 此处需返回一个Promise !!!
 // 接收到后做业务系统操作,此处仅为示例
    return this.transactionAgree()
    },
    true // 同步参数,必须传递
)

// 调用校验方法:
transactionAgree() {
    return new Promise((resolve, reject) => {
        this.$refs.form.validate((valid, formData) => {
            if (valid) {
                resolve(formData)
            } else {
             reject(valid)
            }
        })
    })
}

// 销毁事件,在beforeDestroy中
eventBus.off(BEFORE_TRANSACTION_APPROVE_EVENT)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

# 常见问题

# 1. 处理记录页面展示异常或者页面字典未展示

查看注册flow和glink组件时,productName是否传递正确,同时注意,从sessionStorage中取到后务必进行JSON.parse解析
1

# 2. @adam/flow组件页面样式不正确

微应用需要加样式隔离
1