v1流程下修复所有bug

pull/874/head
wh 2026-02-08 21:02:37 +08:00
parent c66abdf33e
commit 949725ffc6
4 changed files with 940 additions and 452 deletions

View File

@ -159,3 +159,8 @@ export const cancelAcceptance = (acceptanceId: number, reason: string) => {
export const getTodoList = () => {
return request.get({ url: '/project/acceptance/todo' })
}
// 获取验收状态列表
export const getStatusList = () => {
return request.get<{ code: string; name: string }[]>({ url: '/project/acceptance/status-list' })
}

File diff suppressed because it is too large Load Diff

View File

@ -1,171 +1,193 @@
<template>
<ContentWrap>
<!-- 搜索工作栏 -->
<el-form
class="-mb-15px"
:model="queryParams"
ref="queryFormRef"
:inline="true"
label-width="80px"
>
<el-form-item label="项目ID" prop="projectId">
<el-input
v-model="queryParams.projectId"
placeholder="请输入项目ID"
clearable
@keyup.enter="handleQuery"
class="!w-180px"
/>
</el-form-item>
<el-form-item label="验收类型" prop="acceptanceType">
<el-select
v-model="queryParams.acceptanceType"
placeholder="请选择验收类型"
clearable
class="!w-180px"
>
<el-option label="预验收" value="PRE" />
<el-option label="终验" value="FINAL" />
</el-select>
</el-form-item>
<el-form-item label="验收状态" prop="status">
<el-select
v-model="queryParams.status"
placeholder="请选择验收状态"
clearable
class="!w-180px"
>
<el-option label="待审核" value="10" />
<el-option label="审核中" value="20" />
<el-option label="待会议" value="30" />
<el-option label="待整改" value="40" />
<el-option label="已通过" value="80" />
<el-option label="已驳回" value="90" />
</el-select>
</el-form-item>
<el-form-item label="轮次" prop="round">
<el-input-number
v-model="queryParams.round"
:min="1"
placeholder="轮次"
class="!w-120px"
/>
</el-form-item>
<el-form-item label="创建时间" prop="createTime">
<el-date-picker
v-model="queryParams.createTime"
value-format="YYYY-MM-DD HH:mm:ss"
type="datetimerange"
start-placeholder="开始日期"
end-placeholder="结束日期"
class="!w-240px"
/>
</el-form-item>
<el-form-item>
<el-button @click="handleQuery"><Icon icon="ep:search" />搜索</el-button>
<el-button @click="resetQuery"><Icon icon="ep:refresh" />重置</el-button>
<el-button
type="success"
plain
@click="handleExport"
:loading="exportLoading"
v-hasPermi="['project:acceptance:export']"
>
<Icon icon="ep:download" />导出
</el-button>
</el-form-item>
</el-form>
</ContentWrap>
<div class="p-4">
<ContentWrap>
<!-- 搜索工作栏 -->
<el-form
class="-mb-15px"
:model="queryParams"
ref="queryFormRef"
:inline="true"
label-width="68px"
>
<el-form-item label="项目ID" prop="projectId">
<el-input
v-model="queryParams.projectId"
placeholder="请输入项目ID"
clearable
@keyup.enter="handleQuery"
class="!w-200px"
/>
</el-form-item>
<el-form-item label="验收类型" prop="acceptanceType">
<el-select
v-model="queryParams.acceptanceType"
placeholder="请选择验收类型"
clearable
class="!w-200px"
>
<el-option label="预验收" value="PRE" />
<el-option label="终验" value="FINAL" />
</el-select>
</el-form-item>
<el-form-item label="验收状态" prop="status">
<el-select
v-model="queryParams.status"
placeholder="请选择验收状态"
clearable
class="!w-200px"
>
<el-option
v-for="item in statusList"
:key="item.code"
:label="item.name"
:value="item.code"
/>
</el-select>
</el-form-item>
<el-form-item label="轮次" prop="round">
<el-input-number
v-model="queryParams.round"
:min="1"
placeholder="轮次"
controls-position="right"
class="!w-120px"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" plain @click="handleQuery">
<Icon icon="ep:search" class="mr-1" />搜索
</el-button>
<el-button @click="resetQuery">
<Icon icon="ep:refresh" class="mr-1" />重置
</el-button>
<el-button
type="success"
plain
@click="handleExport"
:loading="exportLoading"
v-hasPermi="['project:acceptance:export']"
>
<Icon icon="ep:download" class="mr-1" />导出
</el-button>
</el-form-item>
</el-form>
</ContentWrap>
<!-- 列表 -->
<ContentWrap>
<el-table v-loading="loading" :data="list">
<el-table-column label="验收ID" align="center" prop="id" width="80" />
<el-table-column label="项目ID" align="center" prop="projectId" width="80" />
<el-table-column label="验收类型" align="center" prop="acceptanceType" width="100">
<template #default="scope">
<el-tag v-if="scope.row.acceptanceType === 'PRE'" type="info"></el-tag>
<el-tag v-else-if="scope.row.acceptanceType === 'FINAL'" type="primary">终验</el-tag>
<el-tag v-else>{{ scope.row.acceptanceType }}</el-tag>
</template>
</el-table-column>
<el-table-column label="状态" align="center" prop="status" width="100">
<template #default="scope">
<el-tag :type="getStatusType(scope.row.status)">{{ getStatusLabel(scope.row.status) }}</el-tag>
</template>
</el-table-column>
<el-table-column label="轮次" align="center" prop="round" width="80" />
<el-table-column label="流程实例ID" align="center" prop="processInstanceId" :show-overflow-tooltip="true" />
<el-table-column
label="启动时间"
align="center"
prop="startTime"
:formatter="dateFormatter"
width="180"
/>
<el-table-column
label="完成时间"
align="center"
prop="endTime"
:formatter="dateFormatter"
width="180"
/>
<el-table-column
label="创建时间"
align="center"
prop="createTime"
:formatter="dateFormatter"
width="180"
/>
<el-table-column label="操作" align="center" width="200" fixed="right">
<template #default="scope">
<el-button
link
type="primary"
@click="handleView(scope.row)"
>
查看
</el-button>
<el-button
link
type="primary"
@click="openAuditForm(scope.row)"
v-if="canAudit(scope.row)"
>
审核
</el-button>
<el-button
link
type="warning"
@click="handleForceArchive(scope.row)"
v-hasPermi="['project:acceptance:force-archive']"
>
强制归档
</el-button>
<el-button
link
type="danger"
@click="handleCancel(scope.row)"
v-hasPermi="['project:acceptance:cancel']"
>
取消
</el-button>
</template>
</el-table-column>
</el-table>
<!-- 分页 -->
<Pagination
:total="total"
v-model:page="queryParams.pageNo"
v-model:limit="queryParams.pageSize"
@pagination="getList"
/>
</ContentWrap>
<!-- 列表 -->
<ContentWrap class="mt-4">
<el-table
v-loading="loading"
:data="list"
:header-cell-style="{ background: '#f8fbfc', color: '#606266', height: '50px' }"
:row-style="{ height: '60px' }"
>
<el-table-column label="ID" align="center" prop="id" width="80" class-name="font-mono text-gray-500" />
<el-table-column label="轮次" align="center" prop="round" width="80">
<template #default="scope">
<span class="font-bold text-gray-600 bg-gray-100 px-2 py-1 rounded">R{{ scope.row.round }}</span>
</template>
</el-table-column>
<el-table-column label="项目ID" align="center" prop="projectId" width="100" />
<el-table-column label="验收类型" align="center" prop="acceptanceType" width="120">
<template #default="scope">
<el-tag v-if="scope.row.acceptanceType === 'PRE'" type="info" effect="plain" class="!border-gray-300 !text-gray-600">
<span class="dot bg-gray-400 mr-1"></span>预验收
</el-tag>
<el-tag v-else-if="scope.row.acceptanceType === 'FINAL'" type="primary" effect="plain" class="!border-blue-200 !text-blue-600">
<span class="dot bg-blue-500 mr-1"></span>终验
</el-tag>
<el-tag v-else>{{ scope.row.acceptanceType }}</el-tag>
</template>
</el-table-column>
<!-- 审核表单弹窗 -->
<AcceptanceAuditForm ref="auditFormRef" @success="getList" />
<el-table-column label="状态" align="center" prop="status" width="140">
<template #default="scope">
<div class="flex items-center justify-center">
<el-tag
:type="getStatusType(scope.row.status)"
effect="light"
round
class="!border-0 !px-3 font-medium"
>
{{ getStatusLabel(scope.row.status) }}
</el-tag>
</div>
</template>
</el-table-column>
<el-table-column label="时间信息" min-width="250">
<template #default="scope">
<div class="flex flex-col gap-1 text-xs text-gray-500">
<div class="flex items-center">
<span class="w-16 text-right mr-2">启动时间:</span>
<span class="text-gray-700">{{ scope.row.startTime ? dateFormatter(scope.row, null, scope.row.startTime) : '-' }}</span>
</div>
<div v-if="scope.row.endTime" class="flex items-center">
<span class="w-16 text-right mr-2">完成时间:</span>
<span class="text-gray-700">{{ scope.row.endTime ? dateFormatter(scope.row, null, scope.row.endTime) : '-' }}</span>
</div>
</div>
</template>
</el-table-column>
<el-table-column label="操作" align="center" width="260" fixed="right">
<template #default="scope">
<el-button link type="primary" @click="handleView(scope.row)">
<Icon icon="ep:view" class="mr-1" /> 查看
</el-button>
<el-button
v-if="canAudit(scope.row)"
link
type="primary"
@click="openAuditForm(scope.row)"
v-hasRole="['acceptance-admin']"
>
<Icon icon="ep:check" class="mr-1" /> 审核
</el-button>
<el-button
link
type="warning"
@click="handleForceArchive(scope.row)"
v-hasPermi="['project:acceptance:force-archive']"
v-hasRole="['acceptance-admin']"
>
<Icon icon="ep:folder-checked" class="mr-1" /> 归档
</el-button>
<el-button
link
type="danger"
@click="handleCancel(scope.row)"
v-hasRole="['acceptance-admin']"
>
<Icon icon="ep:circle-close" class="mr-1" /> 取消
</el-button>
</template>
</el-table-column>
</el-table>
<!-- 分页 -->
<Pagination
:total="total"
v-model:page="queryParams.pageNo"
v-model:limit="queryParams.pageSize"
@pagination="getList"
/>
</ContentWrap>
<!-- 审核表单弹窗 -->
<AcceptanceAuditForm ref="auditFormRef" @success="getList" />
</div>
</template>
<style scoped>
.dot {
display: inline-block;
width: 6px;
height: 6px;
border-radius: 50%;
}
</style>
<script lang="ts" setup>
import { dateFormatter } from '@/utils/formatTime'
import download from '@/utils/download'
@ -193,22 +215,48 @@ const queryParams = reactive({
const queryFormRef = ref() //
const exportLoading = ref(false) //
//
const statusMap: Record<string, { label: string; type: string }> = {
'10': { label: '待审核', type: 'info' },
'20': { label: '审核中', type: 'warning' },
'30': { label: '待会议', type: '' },
'40': { label: '待整改', type: 'danger' },
'80': { label: '已通过', type: 'success' },
'90': { label: '已驳回', type: 'danger' }
//
const statusList = ref<{ code: string; name: string }[]>([])
const statusMap = ref<Record<string, string>>({})
/** 获取状态列表 */
const getStatusList = async () => {
try {
const data = await AcceptanceApi.getStatusList()
statusList.value = data
// statusMap
statusMap.value = {}
data.forEach((item: { code: string; name: string }) => {
statusMap.value[item.code] = item.name
})
} catch (error) {
console.error('获取状态列表失败', error)
}
}
const getStatusLabel = (status: string) => {
return statusMap[status]?.label || status
return statusMap.value[status] || status
}
// tag
const statusTypeMap: Record<string, string> = {
'00': 'info',
'05': 'warning',
'10': 'primary',
'11': 'danger',
'20': 'primary',
'30': 'info',
'40': 'primary',
'50': 'info',
'60': 'danger',
'61': 'warning',
'62': 'warning',
'98': 'info',
'99': 'success'
}
const getStatusType = (status: string) => {
return statusMap[status]?.type || 'info'
return statusTypeMap[status] || 'info'
}
/** 判断是否可以审核 */
@ -297,7 +345,8 @@ const handleExport = async () => {
}
/** 初始化 **/
onMounted(() => {
onMounted(async () => {
await getStatusList()
getList()
})
</script>

View File

@ -81,22 +81,27 @@ const getList = async () => {
const auditFormRef = ref()
const handleProcess = (row: AcceptanceApi.AcceptanceTodoVO) => {
//
// taskType BPMN taskDefinitionKey
const taskType = row.taskType
if (['LIAISON_REVIEW', 'LEADER_REVIEW', 'ADMIN_REVIEW', 'EXPERT_CHECK'].includes(taskType)) {
//
//
if (['task_pre_liaison_review', 'task_pre_leader_review', 'task_expert_check', 'task_rectify_review', 'task_meeting_review'].includes(taskType)) {
auditFormRef.value.open({
id: row.acceptanceId,
acceptanceType: row.acceptanceType,
status: row.status
}, getAuditType(taskType))
} else if (taskType === 'RECTIFY_SUBMIT' || taskType === 'task_pre_rectify' || taskType === 'task_final_rectify') {
// tab
}
//
else if (taskType === 'task_final_admin_review') {
router.push({ path: '/project/acceptance/detail/' + row.acceptanceId, query: { tab: 'info' } })
}
// tab
else if (['task_liaison_submit', 'task_pre_rectify', 'task_final_rectify', 'task_final_apply'].includes(taskType)) {
router.push({ path: '/project/acceptance/detail/' + row.acceptanceId, query: { tab: 'materials' } })
} else if (taskType === 'LIAISON_SUBMIT' || taskType === 'task_liaison_submit') {
// tab
router.push({ path: '/project/acceptance/detail/' + row.acceptanceId, query: { tab: 'materials' } })
} else {
//
}
//
else {
handleView(row)
}
}
@ -104,12 +109,16 @@ const handleProcess = (row: AcceptanceApi.AcceptanceTodoVO) => {
/** 获取审核类型 */
const getAuditType = (taskType: string) => {
switch (taskType) {
case 'LIAISON_REVIEW':
case 'LEADER_REVIEW':
case 'task_pre_liaison_review': //
case 'task_pre_leader_review': //
return 'pre-audit'
case 'ADMIN_REVIEW':
case 'task_final_admin_review': //
return 'final-admin'
case 'EXPERT_CHECK':
case 'task_meeting_review': //
return 'meeting-review'
case 'task_rectify_review': //
return 'rectify-review'
case 'task_expert_check': //
return 'expert-check'
default:
return 'pre-audit'