You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

327 lines
12 KiB

  1. <template>
  2. <view class="page">
  3. <!-- 顶部页签 -->
  4. <l-nav v-model="tab" :items="['表单信息', '流程信息']" type="flex" class="solid-bottom" />
  5. <!-- Tab #1:表单页 -->
  6. <view v-if="ready && tab === 0" class="form">
  7. <!-- 表单 -->
  8. <l-customform :initFormValue="formValue" :editMode="editMode" :scheme="scheme" rel="rel" ref="form" />
  9. <!-- 操作区按钮 -->
  10. <l-workflow-action
  11. @audit="audit"
  12. @action="action"
  13. :type="type"
  14. :currentNode="currentNode"
  15. :currentTask="currentTask"
  16. />
  17. </view>
  18. <!-- Tab #2:流程图页 -->
  19. <view v-if="ready && tab === 1" class="progress"><l-workflow-timeline :processList="processList" /></view>
  20. </view>
  21. </template>
  22. <script>
  23. import get from 'lodash/get'
  24. import pick from 'lodash/pick'
  25. import workflowFormMixins from '../workflow.js'
  26. export default {
  27. data() {
  28. return {
  29. tab: 0,
  30. editMode: false,
  31. type: 'view',
  32. ready: false,
  33. code: null,
  34. currentTask: null,
  35. taskId: null,
  36. processList: [],
  37. processId: null,
  38. processInfo: null,
  39. currentNode: null,
  40. scheme: [],
  41. formValue: {},
  42. rel: {}
  43. }
  44. },
  45. mixins: [workflowFormMixins],
  46. async onLoad({ type }) {
  47. await this.init(type)
  48. },
  49. // 小程序专有,分享任务到聊天
  50. // #ifdef MP
  51. onShareAppMessage() {
  52. const props = ['F_Id', 'F_Title', 'F_TaskId', 'F_ProcessId', 'F_IsStart', 'F_IsFinished', 'F_EnabledMark']
  53. const taskInfo = { ...pick(this.currentTask, props), mark: 'pre' }
  54. // 获取页面参数
  55. const queryString = this.MP_SHARE_ENCODE(taskInfo, { type: this.type })
  56. return {
  57. title: `${this.GET_GLOBAL('loginUser').realName}发起的${this.currentTask.F_Title}工作流程`,
  58. desc: '我发起了一个工作流程,快来看看吧',
  59. path: `pages/home?${queryString}`
  60. }
  61. },
  62. // #endif
  63. methods: {
  64. // 页面初始化
  65. async init(type = 'view') {
  66. // type 表示打开方式:view=查看普通流程,child=子流程,refer=审阅
  67. // 当前任务相关信息用 GET_PARAM 获取
  68. // 需要字段: F_Title、F_Id、F_TaskId、F_ProcessId、F_IsFinished、F_IsStart、F_EnabledMark
  69. // 需要字段: mark (是 my 或者不是,表示是否自「我的」列打开)
  70. this.type = type
  71. this.currentTask = this.GET_PARAM()
  72. this.LOADING('加载表单中…')
  73. this.SET_TITLE(this.currentTask.F_Title)
  74. // 未完成的子流程,可以编辑
  75. if (get(this.currentTask, 'mark') !== 'maked' && this.type === 'child') {
  76. this.editMode = true
  77. }
  78. // 如果是代办任务是可编辑的
  79. if (get(this.currentTask, 'mark') === 'pre' ) {
  80. this.editMode = true
  81. }
  82. // 获得流程信息
  83. this.processId = this.currentTask.F_Id
  84. this.taskId = this.currentTask.F_TaskId
  85. this.processInfo = await this.fetchProcessInfo({
  86. processId: this.processId,
  87. taskId: this.taskId
  88. })
  89. this.currentTask = {
  90. ...this.currentTask,
  91. F_TaskType:(this.processInfo.task&&this.processInfo.task[0])?this.processInfo.task[0].F_Type:undefined,
  92. }
  93. this.currentNode = this.getCurrentNode(this.processInfo)
  94. this.processList = get(this.processInfo, 'info.TaskLogList', [])
  95. // wfForms 的数组成员 t,表示表单数据项(TAB页)
  96. // t.formId 使用表单,根据这个 formId 来获取 scheme 等信息
  97. // t.appurl 使用移动页面,直接跳转到本地的页面;表单结构等均写死在页面里
  98. const { wfForms } = this.currentNode
  99. // 处理没有有效表单的情况,停止加载
  100. if (!wfForms || wfForms.every(t => !t.formId && !t.appurl)) {
  101. this.HIDE_LOADING()
  102. this.TOAST('移动表单数据(wfForms)中无有效表单')
  103. return
  104. }
  105. const fetchFolderkeyData=await this.fetchFolderkeyData(this.currentNode , this.processId);
  106. uni.setStorageSync('guids',JSON.stringify(fetchFolderkeyData));
  107. // // 处理移动端本地表单(也就是系统表单)的情况,直接跳转过去
  108. // const appSysPage = wfForms.find(t => t.appurl)
  109. // if (this.type !== 'child' && appSysPage) {
  110. // this.sysFormJump(appSysPage.appurl, {
  111. // currentNode: this.currentNode,
  112. // currentTask: this.currentTask,
  113. // logList: this.processList,
  114. // processInfo:this.processInfo
  115. // })
  116. // return
  117. // }
  118. if (this.type === 'child') {
  119. // 发起子流程的场合
  120. // 获取子流程的流程信息,提取出时间线和表单模板 code
  121. const childProcessInfo = await this.fetchProcessInfo({ processId: this.processId })
  122. this.processList = get(childProcessInfo, 'info.TaskLogList', [])
  123. this.code = this.currentNode.childFlow
  124. // 提取出子流程 Id;因为是发起新的流程,所以 processInfo 只传入表单模板 code
  125. const childProcessId = this.processInfo.info.childProcessId
  126. const childCurrentNode = this.getCurrentNode(await this.fetchProcessInfo({ code: this.code }))
  127. // 处理系统表单跳转,使用子流程相关信息
  128. if (appSysPage) {
  129. this.sysFormJump(appSysPage.appurl, {
  130. currentNode: this.currentNode,
  131. currentTask: this.currentTask,
  132. parentProcessId: this.processId,
  133. logList: this.processList
  134. })
  135. return
  136. }
  137. const schemeData = await this.fetchSchemeData(childCurrentNode)
  138. const formData = await this.fetchFormData(childCurrentNode, childProcessId)
  139. const { formValue, scheme, rel, options } = await this.getCustomForm({
  140. formData,
  141. schemeData,
  142. currentNode: childCurrentNode,
  143. processId: childProcessId,
  144. code: this.code,
  145. useDefault: true
  146. })
  147. // 处理移动端本地表单(也就是系统表单)的情况,直接跳转过去
  148. const appSysPage = wfForms.find(t => t.appurl)
  149. if (this.type !== 'child' && appSysPage) {
  150. this.sysFormJump(appSysPage.appurl, {
  151. currentNode: this.currentNode,
  152. currentTask: this.currentTask,
  153. logList: this.processList,
  154. processInfo:this.processInfo,
  155. formValue,
  156. scheme,
  157. })
  158. return
  159. }
  160. this.scheme = scheme
  161. this.formValue = formValue
  162. this.rel = rel
  163. } else {
  164. // 不是子流程,可以直接渲染
  165. const schemeData = await this.fetchSchemeData(this.currentNode)
  166. const formData = await this.fetchFormData(this.currentNode, this.processId)
  167. const { formValue, scheme, rel } = await this.getCustomForm({
  168. formData,
  169. schemeData,
  170. currentNode: this.currentNode,
  171. processId: this.processId,
  172. code: null
  173. })
  174. // 处理移动端本地表单(也就是系统表单)的情况,直接跳转过去
  175. const appSysPage = wfForms.find(t => t.appurl)
  176. if (this.type !== 'child' && appSysPage) {
  177. this.sysFormJump(appSysPage.appurl, {
  178. currentNode: this.currentNode,
  179. currentTask: this.currentTask,
  180. logList: this.processList,
  181. processInfo:this.processInfo,
  182. formValue,
  183. scheme,
  184. })
  185. return
  186. }
  187. this.scheme = scheme
  188. this.formValue = formValue
  189. this.rel = rel
  190. }
  191. this.ready = true
  192. this.HIDE_LOADING()
  193. },
  194. // 跳转到系统表单页面
  195. sysFormJump(url, param) {
  196. this.HIDE_LOADING()
  197. this.TOAST('跳转至移动端本地表单(即系统表单)')
  198. let pagePath = url || ''
  199. if (!pagePath.startsWith('/pages')) {
  200. pagePath = '/pages' + pagePath
  201. }
  202. this.JUMP_TO(`${pagePath}?type=${this.type}`, param, true)
  203. },
  204. // 点击操作按钮(非审批类按钮)
  205. async action(taskType) {
  206. switch (taskType) {
  207. // 点击「催办」/「撤销流程」/「标记已阅」按钮
  208. case 'urge':
  209. case 'revoke':
  210. case 'refer':
  211. const actionText = { urge: '催办', revoke: '撤销', refer: '已阅' }[taskType]
  212. const actionUrl = { urge: '/urge', revoke: '/revoke', refer: '/refer' }[taskType]
  213. let actionData = this.processId
  214. if (taskType === 'refer') {
  215. actionData = { processId: this.processId, taskId: this.taskId }
  216. }
  217. if (!(await this.CONFIRM(`${actionText}确认`, `确定要提交${actionText}吗?`, true))) {
  218. return
  219. }
  220. this.LOADING(`提交${actionText}中…`)
  221. this.HTTP_POST(`/learun/adms/newwf${actionUrl}`, actionData, `提交${actionText}失败`).then(success => {
  222. this.HIDE_LOADING()
  223. if (success) {
  224. this.EMIT('task-list-change')
  225. this.TOAST(`成功提交${actionText}`, 'success')
  226. if (taskType === 'revoke') {
  227. this.NAV_BACK()
  228. }
  229. }
  230. })
  231. break
  232. // 点击「提交草稿」按钮
  233. case 'draft':
  234. if (!(await this.CONFIRM('提交确认', '确定要提交草稿吗?', true))) {
  235. return
  236. }
  237. this.LOADING('正在提交…')
  238. const draftFormValue = this.$refs.form.getFormValue()
  239. const draftPostData = await this.getPostData(draftFormValue, this.scheme)
  240. this.HTTP_POST('/learun/adms/newwf/draft', draftPostData, '提交草稿失败').then(success => {
  241. this.HIDE_LOADING()
  242. if (success) {
  243. this.EMIT('task-list-change')
  244. this.NAV_BACK()
  245. this.TOAST('草稿已保存', 'success')
  246. }
  247. })
  248. break
  249. // 点击「发起流程」按钮
  250. case 'submit':
  251. const verifyResult = this.$refs.form.verifyValue()
  252. if (verifyResult.length > 0) {
  253. this.CONFIRM('表单验证失败', verifyResult.join('\n'))
  254. return
  255. }
  256. if (!(await this.CONFIRM('提交确认', '确定要发起流程吗?', true))) {
  257. return
  258. }
  259. this.LOADING('正在提交…')
  260. const formValue = this.$refs.form.getFormValue()
  261. const postData = await this.getPostData(formValue, this.scheme)
  262. postData.auditors = JSON.stringify({})
  263. if (this.type === 'child') {
  264. postData.parentProcessId = this.processId
  265. postData.parentTaskId = this.taskId
  266. }
  267. const errorTips = '流程发起失败'
  268. this.HTTP_POST('/learun/adms/newwf/createchildflow', postData, errorTips).then(success => {
  269. this.HIDE_LOADING()
  270. if (success) {
  271. this.EMIT('task-list-change')
  272. this.NAV_BACK()
  273. this.TOAST('流程发起成功', 'success')
  274. }
  275. })
  276. break
  277. default:
  278. break
  279. }
  280. },
  281. // 点击审批相关按钮
  282. async audit(action) {
  283. this.LOADING('加载中…')
  284. const currentTask = this.processInfo.task.find(t => t.F_NodeId === this.currentNode.id)
  285. const postData = await this.getPostData(this.formValue, this.scheme)
  286. const pageParam = {
  287. type: 'sign',
  288. processId: currentTask.F_ProcessId,
  289. taskId: currentTask.F_Id,
  290. formreq: postData.formreq,
  291. taskName: this.currentTask.F_Title,
  292. currentNode:this.currentNode,
  293. schemeCode:this.code||''
  294. }
  295. // 不是加签
  296. if (action.code !== '__sign__') {
  297. Object.assign(pageParam, action)
  298. pageParam.type = 'verify'
  299. pageParam.auditors = JSON.stringify({})
  300. pageParam.isFromSignAudit = Number(this.currentTask.F_TaskType) === 3
  301. }
  302. this.HIDE_LOADING()
  303. this.NAV_TO('./sign', pageParam, true)
  304. }
  305. }
  306. }
  307. </script>