123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411 |
- <!-- todo 无用页面 可以删除了-->
- <template>
- <div>
- <el-drawer v-model="visibleDialog" class="custom-adrawer" direction="rtl" size="900" @close="handleCancel">
- <template #header>
- <div class="flow-header-box">
- <div class="flow-no">编号:{{ taskId }}</div>
- </div>
- </template>
- <div class="flow-detail-container">
- <div class="flow-status-stamp">
- <FlowStatusStamp :status="0" />
- </div>
- <div class="flow-detail-box">
- <!--头部-->
- <div class="header-box">
- <div class="summary-info">
- <div class="title">{{ taskObj.processName }}</div>
- <FlowStatusTag :status="0" />
- </div>
- <div class="initiator-info">
- <FlowNodeAvatar id="1" />
- <div class="begin-time">{{ taskObj.createTime }} 提交</div>
- </div>
- </div>
- <div class="area-divider"></div>
- <!-- 表单 -->
- <div v-loading="validateForm.loading" class="form-wrap">
- <FormCreate v-show="validateForm.rule.length" v-model:api="validateForm.api" :option="validateForm.option" :rule="validateForm.rule" />
- <LeNoData v-if="!validateForm.rule.length" message="表单无数据" />
- </div>
- <div class="area-divider"></div>
- <!--审批流-->
- <el-timeline style="margin-left: 50px">
- <el-timeline-item v-for="active in activeData" :key="active.id" hollow :timestamp="active.taskName" placement="top">
- <template #dot>
- <FlowTypeDot :status="active.taskState" :type="active.taskType" />
- </template>
- <div class="timeline-box flex-1">
- <div class="flex flex-align-center">
- <div class="timeline-box-user flex-1">
- <FlowNodeAvatar id="1" />
- <div class="comment">
- <div class="comment-content">{{ active.duration }}</div>
- </div>
- </div>
- <span class="timeline-box-date">{{ formatTimestamp(active.finishTime) }}</span>
- </div>
- </div>
- </el-timeline-item>
- </el-timeline>
- </div>
- </div>
- <template #footer>
- <div class="flow-actions">
- <el-button :icon="ChatLineSquare" @click="openComment('reviewVisible')">评论</el-button>
- <el-button :icon="Check" type="success" @click="openComment('consentOrRefuseVisible', 'agree')">同意</el-button>
- <el-button :icon="Close" type="danger" @click="openComment('consentOrRefuseVisible', 'reject')">拒绝</el-button>
- <el-dropdown style="margin-left: 12px">
- <el-button :icon="More">更多</el-button>
- <template #dropdown>
- <el-dropdown-menu>
- <el-dropdown-item @click.native="openComment('deliverToReviewVisible')">
- <el-icon><DArrowLeft /></el-icon>
- 转交
- </el-dropdown-item>
- <el-dropdown-item @click.native="openComment('rollbackVisible')">
- <el-icon><Switch /></el-icon>
- 回退
- </el-dropdown-item>
- <el-dropdown-item @click.native="openComment('addSignVisible')">
- <el-icon><Plus /></el-icon>
- 加签
- </el-dropdown-item>
- <el-dropdown-item @click.native="openComment('loseSignVisible')">
- <el-icon><Minus /></el-icon>
- 减签
- </el-dropdown-item>
- </el-dropdown-menu>
- </template>
- </el-dropdown>
- </div>
- </template>
- </el-drawer>
- <!-- 评论弹窗-->
- <review-dialog v-if="reviewVisible" v-model="reviewVisible" :task-id="taskId"></review-dialog>
- <!-- 加签弹窗 -->
- <add-sign-dialog v-if="addSignVisible" v-model="addSignVisible" :task-id="taskId"></add-sign-dialog>
- <!-- 同意或拒绝弹窗 -->
- <consent-or-refuse-dialog
- v-if="consentOrRefuseVisible"
- v-model="consentOrRefuseVisible"
- :task-id="taskId"
- :current-type="currentDialog"
- ></consent-or-refuse-dialog>
- <!-- 转交审批弹窗 -->
- <deliver-to-review-dialog v-if="deliverToReviewVisible" v-model="deliverToReviewVisible" :task-id="taskId"></deliver-to-review-dialog>
- <!-- 减签弹窗 -->
- <lose-sign-dialog v-if="loseSignVisible" v-model="loseSignVisible" :task-id="taskId"></lose-sign-dialog>
- <!-- 回退弹窗 -->
- <rollback-dialog v-if="rollbackVisible" v-model="rollbackVisible" :task-id="taskId"></rollback-dialog>
- </div>
- </template>
- <script setup>
- import { computed, ref, onMounted, nextTick } from 'vue'
- import FlowStatusStamp from '@/components/Flow/FlowStatusStamp.vue'
- import FlowStatusTag from '@/components/Flow/FlowStatusTag.vue'
- import FlowNodeAvatar from '@/components/Flow/FlowNodeAvatar.vue'
- import FlowTypeDot from '@/components/Flow/FlowTypeDot.vue'
- import { ChatLineSquare, Check, Close, Switch, DArrowLeft, Plus, Minus, More } from '@element-plus/icons-vue'
- import { processApprovalInfoApi, processTaskApprovalInfo } from '@/api/flow/processTask'
- import { formatTimestamp } from '@/utils/datetime'
- import ReviewDialog from '../components/reviewDialog'
- import AddSignDialog from '../components/addSignDialog'
- import ConsentOrRefuseDialog from '../components/consentOrRefuseDialog'
- import DeliverToReviewDialog from '../components/deliverToReviewDialog'
- import LoseSignDialog from '../components/loseSignDialog'
- import RollbackDialog from '../components/rollbackDialog'
- import viewForm from '@/utils/form'
- const props = defineProps({
- modelValue: {
- type: Boolean,
- default: false
- },
- taskObj: {
- type: Object,
- default: () => ({})
- }
- })
- const emit = defineEmits(['update:modelValue', 'successFn'])
- // 各种操作弹窗显示隐藏 start
- const reviewVisible = ref(false)
- const addSignVisible = ref(false)
- const consentOrRefuseVisible = ref(false)
- const deliverToReviewVisible = ref(false)
- const loseSignVisible = ref(false)
- const rollbackVisible = ref(false)
- // 各种操作弹窗显示隐藏 end
- const activeData = ref([])
- const currentDialog = ref(null)
- const visibleDialog = computed({
- get() {
- return props.modelValue
- },
- set(val) {
- emit('update:modelValue', val)
- }
- })
- const taskId = computed(() => {
- return props.taskObj.taskId || ''
- })
- const FormCreate = viewForm.$form()
- const validateForm = ref({
- api: {},
- option: {
- submitBtn: false
- },
- rule: [],
- loading: false
- })
- // 关闭按钮
- const closeDrawer = () => {
- emit('successFn')
- emit('update:modelValue', false)
- }
- const handleCancel = () => {
- closeDrawer()
- }
- // 操作按钮
- const openComment = (type, item) => {
- switch (type) {
- case 'reviewVisible':
- reviewVisible.value = !reviewVisible.value
- break
- case 'addSignVisible':
- addSignVisible.value = !addSignVisible.value
- break
- case 'consentOrRefuseVisible':
- // 点击同意
- if (item === 'agree') {
- debugger
- // 验证表单 todo...
- const api = validateForm.value.api
- api.validate((valid, fail) => {
- if (valid) {
- const values = api.formData()
- console.warn(values, 'values')
- //todo 表单验证通过
- } else {
- //todo 表单验证未通过
- }
- })
- // return
- }
- currentDialog.value = item
- consentOrRefuseVisible.value = !consentOrRefuseVisible.value
- break
- case 'deliverToReviewVisible':
- deliverToReviewVisible.value = !deliverToReviewVisible.value
- break
- case 'loseSignVisible':
- loseSignVisible.value = !loseSignVisible.value
- break
- case 'rollbackVisible':
- rollbackVisible.value = !rollbackVisible.value
- break
- }
- }
- nextTick(() => {
- const cur = props.taskObj || {}
- processApprovalInfoApi(cur.taskId).then(data => {
- // console.log(JSON.stringify(data))
- activeData.value = data
- })
- // 提交的表单 数据展示
- validateForm.value.loading = true
- processTaskApprovalInfo(cur.taskId)
- .then(data => {
- console.log(data, 'data.......')
- // validateForm.value.origin = data
- try {
- /*descItemsData.value.list = JSON.parse(data.formContent).map(item => {
- const showLabel = item.title
- let showValue = item.local_value
- const options = item.options
- if (Array.isArray(options) && showValue !== undefined) {
- if (Array.isArray(showValue)) {
- showValue = showValue.reduce(val => {
- const cur = options.find(option => option.value === val)
- return cur?.label || val
- }, [])
- } else {
- const cur = options.find(option => option.value === showValue)
- showValue = cur?.label || showValue
- }
- }
- return {
- showLabel,
- showValue
- }
- })*/
- const forms = JSON.parse(data.formContent)
- if (Array.isArray(forms)) {
- validateForm.value.rule = forms
- const api = validateForm.value.api
- api.setValue(
- forms.reduce((obj, item) => {
- obj[item.field] = item.local_value
- return obj
- }, {})
- )
- api.nextTick(() => {
- // 是否有编辑权限 操作
- api.disabled(false /*true*/)
- })
- }
- } catch (e) {
- console.error('解析 descItems 数据出现问题', e)
- // descItemsData.value.list = []
- validateForm.value.rule = []
- }
- })
- .finally(() => {
- validateForm.value.loading = false
- })
- })
- </script>
- <style scoped lang="scss">
- .flow-detail-container {
- height: 100%;
- }
- .flow-status-stamp {
- position: absolute;
- right: 50px;
- top: 30px;
- }
- .flow-header-box {
- font-weight: 400;
- font-size: 14px;
- border-bottom: 1px solid #e5e6ec;
- padding: 0 16px;
- height: 39px;
- display: flex;
- align-items: center;
- justify-content: space-between;
- color: #86909c;
- }
- .flow-detail-box {
- height: calc(100% - 92px);
- overflow: hidden;
- overflow-y: auto;
- padding: 0 20px;
- .header-box {
- display: flex;
- flex-direction: column;
- justify-content: center;
- // padding-top: 20px;
- .summary-info {
- display: flex;
- align-items: center;
- .title {
- font-size: 24px;
- font-family: PingFangSC-Semibold, PingFang SC;
- color: #1d2129;
- }
- }
- .initiator-info {
- display: flex;
- align-items: center;
- margin-top: 16px;
- .begin-time {
- margin-left: 16px;
- font-weight: 350;
- color: #86909c;
- font-size: 13px;
- -webkit-user-select: none;
- user-select: none;
- }
- }
- }
- .area-divider {
- border-bottom: 1px solid rgba(229, 230, 235, 1);
- margin: 20px 0;
- position: relative;
- }
- }
- .flow-actions {
- display: flex;
- align-items: center;
- justify-content: flex-end;
- }
- // 时间线样式
- .timeline-box {
- padding-left: 8px;
- &-user {
- .name {
- color: #1d2129;
- font-weight: 400;
- }
- .comment {
- width: 100%;
- -webkit-user-select: none;
- user-select: none;
- margin: 4px 0 16px;
- padding: 8px 16px;
- border-radius: 4px;
- background-color: #f8f8fa;
- .comment-content {
- font-weight: 500;
- color: #1d2129;
- }
- }
- }
- &-date {
- margin-left: 10px;
- left: 0;
- padding-right: 32px;
- text-align: right;
- transform: translate(-100%);
- position: absolute;
- top: 0;
- box-sizing: border-box;
- max-width: 100px;
- color: #86909c;
- font-size: 12px;
- line-height: 1.667;
- }
- }
- :deep(.el-drawer__header) {
- padding: 0px;
- margin-bottom: 0 !important;
- }
- :deep(.el-drawer__footer) {
- padding-top: 20px;
- border-top: 1px solid rgba(229, 230, 235, 1);
- }
- :deep(.el-timeline .el-timeline-item__timestamp) {
- padding-left: 8px;
- }
- </style>
|