approvedContent.vue 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695
  1. <template>
  2. <div class="flow-detail-content">
  3. <div class="flow-detail-container">
  4. <!-- 值为空 -->
  5. <div v-if="!currentTaskRow.instanceId" class="flow-empty-detail-box">
  6. <el-empty description="暂无数据" />
  7. </div>
  8. <!-- 值不为空 -->
  9. <template v-if="currentTaskRow.instanceId">
  10. <!-- 1、头部信息 -->
  11. <div class="flow-status-stamp">
  12. <div class="flow-stamp-container">
  13. <FlowStatusStamp :status="currentTaskRow.instanceState" />
  14. </div>
  15. </div>
  16. <div class="flow-header-box">
  17. <div class="flow-no">编号:{{ currentTaskRow.instanceId }}</div>
  18. <div class="action-area">
  19. <div class="action-item"></div>
  20. </div>
  21. </div>
  22. <!-- 2、内容体 -->
  23. <div class="flow-detail-box">
  24. <!--头部-->
  25. <div class="header-box">
  26. <div class="summary-info">
  27. <div class="title">{{ currentTaskRow.processName }}</div>
  28. <FlowStatusTag :status="currentTaskRow.instanceState" />
  29. </div>
  30. <div class="initiator-info">
  31. <FlowNodeAvatar :name="currentTaskRow.createBy" />
  32. <div class="begin-time">{{ currentTaskRow.createTime }} 提交</div>
  33. </div>
  34. </div>
  35. <el-tabs v-model="tabName">
  36. <el-tab-pane v-for="v of tabList" :key="v.value" :label="v.label" :name="v.value" />
  37. </el-tabs>
  38. <!-- 审批信息 -->
  39. <div v-show="tabName === 'ApprovalInfo'" class="scroll-wrap">
  40. <!-- 表单 -->
  41. <div v-loading="validateForm.loading" class="form-wrap self-Everright-formEditor">
  42. <er-form-preview
  43. v-show="validateForm.rule.length"
  44. ref="EReditorRef"
  45. :file-upload-u-r-i="uploadFileApi"
  46. :is-show-complete-button="false"
  47. />
  48. <LeNoData v-if="!validateForm.rule.length" message="表单无数据" />
  49. </div>
  50. <div class="area-divider"></div>
  51. <!--审批流-->
  52. <el-timeline style="margin-left: 50px">
  53. <el-timeline-item v-for="active in activeData" :key="active.id" hollow :timestamp="active.local_timestamp">
  54. <template #dot>
  55. <FlowTypeDot :status="active.id ? 0 : 1" :type="active.type" :name="active.createBy" />
  56. </template>
  57. <div v-show="active.type === 0" class="timeline-box flex-1">
  58. <span style="color: #86909c; display: block; margin-bottom: 3px; padding-left: 4px">评论</span>
  59. <div class="flex flex-align-center">
  60. <div class="timeline-box-user flex-1">
  61. <span style="padding-left: 4px">{{ active.createBy }}</span>
  62. <div v-if="active.local_content" class="comment">
  63. <div class="comment-content">{{ active.local_content }}</div>
  64. </div>
  65. </div>
  66. <span class="timeline-box-date">{{ formatTimestamp(active.finishTime) }}</span>
  67. </div>
  68. </div>
  69. <div v-show="active.type !== 0" class="timeline-box flex-1">
  70. <span style="display: block" class="pl-1.5 mb-0">{{ active.taskName }}</span>
  71. <div class="flex flex-align-center">
  72. <div class="timeline-box-user flex-1">
  73. <span v-if="active.id" class="text-gray-500 pl-1.5">
  74. {{ active.createBy }}
  75. </span>
  76. <span v-if="active.type === 22">
  77. 发起的子流程<el-tooltip content="点击查看详情">
  78. <a class="el-button el-button--primary is-link" style="padding-top: 0" @click="lookSubProcess(active)">
  79. ({{ active.content.callProcess.split(':')[1] }})
  80. </a>
  81. </el-tooltip>
  82. </span>
  83. <div style="display: flex; gap: 6px; margin-top: 3px">
  84. <FlowNodeAvatar v-for="nodeUser in active.local_nodeUserList" :key="nodeUser.id" :name="nodeUser.name" />
  85. <FlowNodeAvatar v-for="nodeRole in active.local_nodeRoleList" :key="nodeRole.id" :name="nodeRole.name">
  86. <template #avatar>
  87. <svg-icon icon-class="flow-group" color="#fff" />
  88. </template>
  89. </FlowNodeAvatar>
  90. </div>
  91. <div v-if="active.local_content" class="comment">
  92. <div class="comment-content">{{ active.local_content }}</div>
  93. </div>
  94. </div>
  95. <span class="timeline-box-date">{{ formatTimestamp(active.finishTime) }}</span>
  96. </div>
  97. </div>
  98. </el-timeline-item>
  99. </el-timeline>
  100. </div>
  101. <!-- 流程图 -->
  102. <div v-show="tabName === 'FlowChart'" class="scroll-wrap">
  103. <div class="tags-desc">
  104. <!--0: 已执行 1正在执行-->
  105. <el-tag style="margin-left: 4px" type="success" size="small">已执行</el-tag>
  106. <el-tag style="margin-left: 4px" type="warning" size="small">执行中</el-tag>
  107. <el-tag style="margin-left: 4px" type="info" size="small">未执行</el-tag>
  108. </div>
  109. <ScWorkflow style="overflow-x: auto" :model-value="modelContentConfig" disabled />
  110. </div>
  111. </div>
  112. <!-- 3、底部操作按钮 审批拒绝 强制终止不展示操作按钮-->
  113. <!--
  114. 1、已审批的任务不显示操作按钮
  115. 2、我的申请显示撤回按钮
  116. 3、认领任务显示认领按钮
  117. 4、我收到的任务显示评论
  118. -->
  119. <div v-if="currentTaskRow.instanceState === 0" class="flow-actions">
  120. <el-button :icon="ChatLineSquare" @click="openComment('reviewVisible', 'review')">评论</el-button>
  121. <template v-if="currentTaskType !== 'myReceived' || currentTaskType !== 'approved'">
  122. <el-button
  123. v-if="currentTaskType === 'pendingApproval'"
  124. :icon="Check"
  125. type="primary"
  126. @click="openComment('consentOrRefuseVisible', 'agree')"
  127. >同意</el-button
  128. >
  129. <el-button
  130. v-if="currentTaskType === 'pendingApproval' && allowReject"
  131. :icon="Close"
  132. type="danger"
  133. @click="openComment('consentOrRefuseVisible', 'reject')"
  134. >拒绝</el-button
  135. >
  136. <el-button
  137. v-if="currentTaskType === 'myApplication' && allowRevocation"
  138. :icon="Close"
  139. type="danger"
  140. @click="openComment('reviewVisible', 'revoke')"
  141. >撤回</el-button
  142. >
  143. <el-button v-if="currentTaskType === 'pendingClaim'" :icon="Close" @click="claimTaskEv">认领</el-button>
  144. <el-dropdown
  145. v-if="currentTaskType === 'pendingApproval' && (allowTransfer || allowRollback || allowAppendNode)"
  146. style="margin-left: 12px"
  147. >
  148. <el-button :icon="More">更多</el-button>
  149. <template #dropdown>
  150. <el-dropdown-menu>
  151. <el-dropdown-item v-if="allowTransfer" @click.native="openComment('deliverToReviewVisible')">
  152. <el-icon><DArrowLeft /></el-icon>
  153. 转交
  154. </el-dropdown-item>
  155. <el-dropdown-item v-if="allowRollback" @click.native="openComment('rollbackVisible')">
  156. <el-icon><Switch /></el-icon>
  157. 回退
  158. </el-dropdown-item>
  159. <el-dropdown-item v-if="allowAppendNode" @click.native="openComment('addSignVisible')">
  160. <el-icon><Plus /></el-icon>
  161. 加签
  162. </el-dropdown-item>
  163. <el-dropdown-item v-if="false" @click.native="openComment('loseSignVisible')">
  164. <el-icon><Minus /></el-icon>
  165. 减签
  166. </el-dropdown-item>
  167. </el-dropdown-menu>
  168. </template>
  169. </el-dropdown>
  170. </template>
  171. </div>
  172. </template>
  173. </div>
  174. <!-- 评论弹窗-->
  175. <review-dialog
  176. v-if="reviewVisible"
  177. v-model="reviewVisible"
  178. :instance-id="currentTaskRow.instanceId"
  179. :task-id="taskId"
  180. :current-type="currentType"
  181. @success-cb="closeDetailEv"
  182. ></review-dialog>
  183. <!-- 加签弹窗 -->
  184. <add-sign-dialog v-if="addSignVisible" v-model="addSignVisible" :task-id="taskId" @success-cb="closeDetailEv"></add-sign-dialog>
  185. <!-- 同意或拒绝弹窗 -->
  186. <consent-or-refuse-dialog
  187. v-if="consentOrRefuseVisible"
  188. v-model="consentOrRefuseVisible"
  189. :task-id="taskId"
  190. :current-type="currentType"
  191. :form-data="currentFormData"
  192. @success-cb="closeDetailEv"
  193. ></consent-or-refuse-dialog>
  194. <!-- 转交审批弹窗 -->
  195. <deliver-to-review-dialog
  196. v-if="deliverToReviewVisible"
  197. v-model="deliverToReviewVisible"
  198. :task-id="taskId"
  199. @success-cb="closeDetailEv"
  200. ></deliver-to-review-dialog>
  201. <!-- 减签弹窗 -->
  202. <lose-sign-dialog v-if="loseSignVisible" v-model="loseSignVisible" :task-id="taskId" @success-cb="closeDetailEv"></lose-sign-dialog>
  203. <!-- 回退弹窗 -->
  204. <rollback-dialog v-if="rollbackVisible" v-model="rollbackVisible" :task-id="taskId" @success-cb="closeDetailEv"></rollback-dialog>
  205. <!-- 查看子流程表单 -->
  206. <ViewProcessDialog v-if="processInfo.visible" v-model="processInfo.visible" :processInfo="processInfo" />
  207. </div>
  208. </template>
  209. <script setup>
  210. import useTaskProcessStore from '@/store/modules/taskProcess'
  211. import { computed, ref, nextTick, watch } from 'vue'
  212. import FlowStatusStamp from '@/components/Flow/FlowStatusStamp.vue'
  213. import FlowStatusTag from '@/components/Flow/FlowStatusTag.vue'
  214. import FlowNodeAvatar from '@/components/Flow/FlowNodeAvatar.vue'
  215. import FlowTypeDot from '@/components/Flow/FlowTypeDot.vue'
  216. import { ChatLineSquare, Check, Close, Switch, DArrowLeft, Plus, Minus, More } from '@element-plus/icons-vue'
  217. import { processTaskApprovalInfo, processClaimTaskApi } from '@/api/flow/processTask'
  218. import { formatTimestamp } from '@/utils/datetime'
  219. import ReviewDialog from './reviewDialog'
  220. import AddSignDialog from './addSignDialog'
  221. import ConsentOrRefuseDialog from './consentOrRefuseDialog'
  222. import DeliverToReviewDialog from './deliverToReviewDialog'
  223. import LoseSignDialog from './loseSignDialog'
  224. import RollbackDialog from './rollbackDialog'
  225. import ViewProcessDialog from './ViewProcessDialog.vue'
  226. import { storeToRefs } from 'pinia'
  227. import { ElMessage, ElMessageBox } from 'element-plus'
  228. import { erFormPreview } from '@ER/formEditor'
  229. const { VITE_APP_BASE_API } = import.meta.env
  230. const uploadFileApi = ref(`${VITE_APP_BASE_API}/v1/oss/upload`)
  231. import { package_modelContentConfig } from './config.ts'
  232. const props = defineProps({
  233. /**
  234. * pendingApproval 待审批
  235. * myApplication 我的申请
  236. * myReceived 我收到的
  237. * pendingClaim 认领任务
  238. * approved 已审批
  239. */
  240. currentTaskType: {
  241. type: String,
  242. default: ''
  243. }
  244. })
  245. const tabName = ref('ApprovalInfo')
  246. const tabList = computed(() => {
  247. const list = [
  248. {
  249. label: '审批信息',
  250. value: 'ApprovalInfo'
  251. },
  252. {
  253. label: '流程图',
  254. value: 'FlowChart'
  255. }
  256. ]
  257. /*// 待审批 去掉流程图 todo?
  258. if (props.currentTaskType === 'pendingApproval') {
  259. list.splice(1, 1)
  260. }*/
  261. return list
  262. })
  263. // store值
  264. const taskProcessInfo = useTaskProcessStore()
  265. const { currentTaskRow } = storeToRefs(taskProcessInfo)
  266. // 各种操作弹窗显示隐藏 start
  267. const reviewVisible = ref(false)
  268. const addSignVisible = ref(false)
  269. const consentOrRefuseVisible = ref(false)
  270. const deliverToReviewVisible = ref(false)
  271. const loseSignVisible = ref(false)
  272. const rollbackVisible = ref(false)
  273. const allowReject = ref(false)
  274. const allowRevocation = ref(false)
  275. // 各种操作弹窗显示隐藏 end
  276. const activeData = ref([])
  277. const currentType = ref(null)
  278. const currentFormData = ref({})
  279. // 当前form 表单数据字符串
  280. let cur_processForm_str = ''
  281. const EReditorRef = ref()
  282. const taskId = computed(() => {
  283. return currentTaskRow.value.taskId || ''
  284. })
  285. const validateForm = ref({
  286. rule: [],
  287. loading: false
  288. })
  289. // 允许转交
  290. const allowTransfer = ref(true)
  291. // 允许加减签
  292. const allowAppendNode = ref(true)
  293. // 允许回退
  294. const allowRollback = ref(true)
  295. const modelContentConfig = ref({})
  296. /**
  297. * 详情按钮各个操作弹窗
  298. * @param visibleType 评论 拒绝 同意等
  299. */
  300. const openComment = async (visibleType, item) => {
  301. switch (visibleType) {
  302. case 'reviewVisible':
  303. currentType.value = item
  304. reviewVisible.value = !reviewVisible.value
  305. break
  306. case 'addSignVisible':
  307. addSignVisible.value = !addSignVisible.value
  308. break
  309. case 'consentOrRefuseVisible':
  310. currentFormData.value = {}
  311. // 点击同意
  312. let bool = true
  313. if (item === 'agree') {
  314. const form = EReditorRef.value.getSelfFormRef()
  315. bool = await form.validate(valid => {
  316. if (valid) {
  317. // 表单验证通过 进行保存
  318. const formData = EReditorRef.value.getData()
  319. let processForm = JSON.parse(cur_processForm_str)
  320. processForm = { ...processForm, formData }
  321. currentFormData.value = { processForm: JSON.stringify(processForm) }
  322. console.log('验证通过')
  323. }
  324. })
  325. // const api = validateForm.value.api
  326. // bool = await api.validate((valid, fail) => {
  327. // if (valid) {
  328. // // 表单验证通过
  329. // const values = api.formData()
  330. // const processForm = JSON.parse(cur_processForm_str)
  331. // processForm.forEach(v => {
  332. // // 填写的数据存储(local_: 本地数据处理标识)
  333. // v.local_value = values[v.field]
  334. // })
  335. // console.warn(processForm, 'processForm')
  336. // // 流程表单JSON内容 & local_value 保存
  337. // currentFormData.value = { processForm: JSON.stringify(processForm) }
  338. // }
  339. // })
  340. }
  341. if (!bool) return
  342. currentType.value = item
  343. consentOrRefuseVisible.value = !consentOrRefuseVisible.value
  344. break
  345. case 'deliverToReviewVisible':
  346. deliverToReviewVisible.value = !deliverToReviewVisible.value
  347. break
  348. case 'loseSignVisible':
  349. loseSignVisible.value = !loseSignVisible.value
  350. break
  351. case 'rollbackVisible':
  352. rollbackVisible.value = !rollbackVisible.value
  353. break
  354. }
  355. }
  356. /**
  357. * 获取taskId对应的详情
  358. */
  359. const getTaskDetail = () => {
  360. const cur = currentTaskRow.value || {}
  361. // 提交的表单 数据展示
  362. validateForm.value.loading = true
  363. processTaskApprovalInfo({
  364. taskId: cur.taskId,
  365. instanceId: cur.instanceId,
  366. instanceState: cur.instanceState
  367. })
  368. .then(data => {
  369. const activeList = data.processApprovals
  370. activeList.forEach(v => {
  371. v.local_timestamp = v.id && formatTimestamp(v.createTime)
  372. const _content = v.content
  373. v.local_nodeUserList = _content?.nodeUserList || []
  374. v.local_nodeRoleList = _content?.nodeRoleList || []
  375. v.local_content = _content?.opinion
  376. })
  377. activeData.value = activeList
  378. // todo 获取当前的操作权限,进行赋值
  379. try {
  380. const modelContent = JSON.parse(data.modelContent || '{}')
  381. const modelContent_config = modelContent.nodeConfig // ?? modelContent.childNode
  382. if (modelContent_config) {
  383. package_modelContentConfig(modelContent_config, data.renderNodes || {})
  384. }
  385. modelContentConfig.value = modelContent_config || {}
  386. window.modelContentConfig = modelContentConfig
  387. if (props.currentTaskType === 'pendingApproval') {
  388. allowTransfer.value = data?.allowTransfer
  389. allowAppendNode.value = data?.allowAppendNode
  390. allowRollback.value = data?.allowRollback
  391. }
  392. if (data?.taskType !== 0) {
  393. allowReject.value = true
  394. }
  395. if (props.currentTaskType === 'myApplication') {
  396. allowRevocation.value = data.processSetting.allowRevocation
  397. }
  398. /*descItemsData.value.list = JSON.parse(data.formContent).map(item => {
  399. const showLabel = item.title
  400. let showValue = item.local_value
  401. const options = item.options
  402. if (Array.isArray(options) && showValue !== undefined) {
  403. if (Array.isArray(showValue)) {
  404. showValue = showValue.reduce(val => {
  405. const cur = options.find(option => option.value === val)
  406. return cur?.label || val
  407. }, [])
  408. } else {
  409. const cur = options.find(option => option.value === showValue)
  410. showValue = cur?.label || showValue
  411. }
  412. }
  413. return {
  414. showLabel,
  415. showValue
  416. }
  417. })*/
  418. cur_processForm_str = data.formContent
  419. const { formStructure, formData } = JSON.parse(cur_processForm_str)
  420. const formConfig = data.formConfig || []
  421. let newFormStructure = formStructure // 存储一份
  422. let newFields = newFormStructure.fields
  423. let newFieldsList = newFormStructure.list
  424. // pendingApproval, 除了[待审批]这个状态, 其余只能读取
  425. if (props.currentTaskType !== 'pendingApproval') {
  426. newFields.map(item1 => (item1.options.disabled = true))
  427. } else {
  428. // data.formConfig
  429. newFields.forEach(item => {
  430. const matchingFormItem = formConfig.find(formItem => formItem.id == item.id)
  431. // 如果找到匹配的对象,且opera为'2',则删除newFields中的对象
  432. if (matchingFormItem && matchingFormItem.opera === '2') {
  433. newFields = newFields.filter(t => t.id !== item.id)
  434. } else if (matchingFormItem) {
  435. // 否则,将opera属性添加到newFields中的对象
  436. item.opera = matchingFormItem.opera
  437. // '0': 只读 '1': 编辑 '2': 隐藏
  438. item.options.disabled = ['0', '1'].indexOf(matchingFormItem.opera) > -1 ? !Number(matchingFormItem.opera) : false
  439. }
  440. })
  441. newFieldsList.forEach(item => {
  442. const matchingFormItem = formConfig.find(formItem => formItem.id == item.id)
  443. // 如果找到匹配的对象,且opera为'2',则删除newFields中的对象
  444. if (matchingFormItem && matchingFormItem.opera === '2') {
  445. newFieldsList = newFieldsList.filter(t => t.id !== item.id)
  446. }
  447. })
  448. }
  449. newFormStructure = {
  450. ...newFormStructure,
  451. fields: newFields,
  452. list: newFieldsList
  453. }
  454. EReditorRef.value.setData(newFormStructure, formData)
  455. validateForm.value.rule = newFields
  456. } catch (e) {
  457. console.error('解析 descItems 数据出现问题', e)
  458. // descItemsData.value.list = []
  459. validateForm.value.rule = []
  460. }
  461. })
  462. .finally(() => {
  463. validateForm.value.loading = false
  464. })
  465. }
  466. const processInfo = ref({ name: '', id: '', instanceId: '', visible: false })
  467. const lookSubProcess = item => {
  468. const [id, name, instanceId] = item.content.callProcess.split(':')
  469. processInfo.value = {
  470. name,
  471. id,
  472. instanceId,
  473. visible: true
  474. }
  475. }
  476. /**
  477. * 详情页面操作按钮回调
  478. */
  479. const closeDetailEv = () => {
  480. ElMessage({
  481. message: '操作成功',
  482. type: 'success'
  483. })
  484. setTimeout(() => {
  485. if (currentType.value === 'review') {
  486. // 评论按钮,不要刷新左侧的列表,只更新右侧的详情即可
  487. getTaskDetail()
  488. return
  489. }
  490. taskProcessInfo.refresh = true
  491. taskProcessInfo.setCurrentTaskRow({})
  492. }, 1000)
  493. }
  494. /** 认领任务 **/
  495. const claimTaskEv = async () => {
  496. ElMessageBox.confirm('确定认领当前审批流程?', '提示', {
  497. confirmButtonText: '确认',
  498. cancelButtonText: '取消',
  499. type: 'warning',
  500. buttonSize: 'default'
  501. })
  502. .then(async () => {
  503. const data = await processClaimTaskApi(currentTaskRow.value.taskId)
  504. if (!data) return
  505. closeDetailEv()
  506. })
  507. .catch(() => {
  508. console.log('取消')
  509. })
  510. }
  511. /**
  512. * 监听同级子组件的instanceId的值变化 这里可能也有实例Id
  513. * 1、监听instanceId的值变化,如果值有变化,则重新获取审批详情
  514. * 2、如果instanceId没有值,则不请求接口,暂时暂无数据img
  515. */
  516. watch(
  517. () => currentTaskRow.value.instanceId,
  518. (nValue, oValue) => {
  519. if (!nValue) return
  520. nextTick(() => {
  521. getTaskDetail()
  522. })
  523. }
  524. )
  525. </script>
  526. <style scoped lang="scss">
  527. .flow-detail-content {
  528. height: 100%;
  529. overflow: hidden;
  530. background: var(--el-bg-color);
  531. border-radius: 6px;
  532. flex: auto;
  533. .flow-detail-container {
  534. display: flex;
  535. flex-direction: column;
  536. position: relative;
  537. height: 100%;
  538. overflow: hidden;
  539. }
  540. // 通过、不通过样式
  541. .flow-status-stamp {
  542. position: absolute;
  543. right: 10px;
  544. top: 10px;
  545. z-index: 99;
  546. }
  547. // 头部
  548. .flow-header-box {
  549. font-weight: 400;
  550. font-size: 13px;
  551. border-bottom: 1px solid var(--el-border-color);
  552. padding: 0 20px;
  553. height: 39px;
  554. display: flex;
  555. align-items: center;
  556. justify-content: space-between;
  557. color: var(--el-color-info);
  558. .action-area {
  559. display: flex;
  560. gap: 4px;
  561. .action-item {
  562. cursor: pointer;
  563. padding: 4px;
  564. border-radius: 6px;
  565. width: fit-content;
  566. height: fit-content;
  567. }
  568. }
  569. }
  570. // 内容体
  571. .flow-detail-box {
  572. //height: calc(100% - 92px);
  573. //overflow: hidden;
  574. //overflow-y: auto;
  575. flex: 1;
  576. min-height: 0;
  577. padding: 0 20px;
  578. display: flex;
  579. flex-direction: column;
  580. height: 100%;
  581. .header-box {
  582. display: flex;
  583. flex-direction: column;
  584. justify-content: center;
  585. padding-bottom: 10px;
  586. // padding-top: 20px;
  587. .summary-info {
  588. display: flex;
  589. align-items: center;
  590. padding-top: 10px;
  591. font-size: 24px;
  592. .title {
  593. font-family: PingFangSC-Semibold, PingFang SC;
  594. color: var(--el-text-color-primary);
  595. }
  596. }
  597. .initiator-info {
  598. display: flex;
  599. align-items: center;
  600. margin-top: 16px;
  601. .begin-time {
  602. margin-left: 16px;
  603. font-weight: 350;
  604. color: var(--el-text-color-placeholder);
  605. font-size: 13px;
  606. -webkit-user-select: none;
  607. user-select: none;
  608. }
  609. }
  610. }
  611. .area-divider {
  612. border-bottom: 1px solid var(--el-border-color);
  613. margin: 20px 0;
  614. //position: relative;
  615. }
  616. .scroll-wrap {
  617. position: relative;
  618. overflow: hidden;
  619. overflow-y: auto;
  620. flex: 1;
  621. .tags-desc {
  622. position: absolute;
  623. left: 6px;
  624. top: 10px;
  625. z-index: 1;
  626. }
  627. :deep(.zoom-scale) {
  628. position: absolute;
  629. top: 16px;
  630. right: 16px;
  631. }
  632. }
  633. }
  634. // 底部
  635. .flow-actions {
  636. display: flex;
  637. align-items: center;
  638. justify-content: flex-end;
  639. height: 52px;
  640. //border-top: 1px solid var(--color-neutral-3);
  641. border-top: 1px solid var(--el-border-color-light);
  642. background: var(--el-bg-color);
  643. padding: 0 20px;
  644. }
  645. }
  646. .comment-content {
  647. user-select: none;
  648. margin-top: 4px;
  649. padding: 8px;
  650. border-radius: 4px;
  651. background-color: var(--el-bg-color-page);
  652. }
  653. .timeline-box {
  654. margin-left: 5px;
  655. }
  656. :deep(.el-timeline-item__timestamp) {
  657. margin-left: 6px;
  658. }
  659. // 修改everright 表单的样式
  660. .self-Everright-formEditor {
  661. :deep(.Everright-formEditor-selectElement) {
  662. padding: 0px 16px;
  663. }
  664. }
  665. </style>