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 = () => { export const getTodoList = () => {
return request.get({ url: '/project/acceptance/todo' }) 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> <template>
<ContentWrap> <div class="p-4">
<!-- 搜索工作栏 --> <ContentWrap>
<el-form <!-- 搜索工作栏 -->
class="-mb-15px" <el-form
:model="queryParams" class="-mb-15px"
ref="queryFormRef" :model="queryParams"
:inline="true" ref="queryFormRef"
label-width="80px" :inline="true"
> label-width="68px"
<el-form-item label="项目ID" prop="projectId"> >
<el-input <el-form-item label="项目ID" prop="projectId">
v-model="queryParams.projectId" <el-input
placeholder="请输入项目ID" v-model="queryParams.projectId"
clearable placeholder="请输入项目ID"
@keyup.enter="handleQuery" clearable
class="!w-180px" @keyup.enter="handleQuery"
/> class="!w-200px"
</el-form-item> />
<el-form-item label="验收类型" prop="acceptanceType"> </el-form-item>
<el-select <el-form-item label="验收类型" prop="acceptanceType">
v-model="queryParams.acceptanceType" <el-select
placeholder="请选择验收类型" v-model="queryParams.acceptanceType"
clearable placeholder="请选择验收类型"
class="!w-180px" clearable
> class="!w-200px"
<el-option label="预验收" value="PRE" /> >
<el-option label="终验" value="FINAL" /> <el-option label="预验收" value="PRE" />
</el-select> <el-option label="终验" value="FINAL" />
</el-form-item> </el-select>
<el-form-item label="验收状态" prop="status"> </el-form-item>
<el-select <el-form-item label="验收状态" prop="status">
v-model="queryParams.status" <el-select
placeholder="请选择验收状态" v-model="queryParams.status"
clearable placeholder="请选择验收状态"
class="!w-180px" clearable
> class="!w-200px"
<el-option label="待审核" value="10" /> >
<el-option label="审核中" value="20" /> <el-option
<el-option label="待会议" value="30" /> v-for="item in statusList"
<el-option label="待整改" value="40" /> :key="item.code"
<el-option label="已通过" value="80" /> :label="item.name"
<el-option label="已驳回" value="90" /> :value="item.code"
</el-select> />
</el-form-item> </el-select>
<el-form-item label="轮次" prop="round"> </el-form-item>
<el-input-number <el-form-item label="轮次" prop="round">
v-model="queryParams.round" <el-input-number
:min="1" v-model="queryParams.round"
placeholder="轮次" :min="1"
class="!w-120px" placeholder="轮次"
/> controls-position="right"
</el-form-item> class="!w-120px"
<el-form-item label="创建时间" prop="createTime"> />
<el-date-picker </el-form-item>
v-model="queryParams.createTime" <el-form-item>
value-format="YYYY-MM-DD HH:mm:ss" <el-button type="primary" plain @click="handleQuery">
type="datetimerange" <Icon icon="ep:search" class="mr-1" />搜索
start-placeholder="开始日期" </el-button>
end-placeholder="结束日期" <el-button @click="resetQuery">
class="!w-240px" <Icon icon="ep:refresh" class="mr-1" />重置
/> </el-button>
</el-form-item> <el-button
<el-form-item> type="success"
<el-button @click="handleQuery"><Icon icon="ep:search" />搜索</el-button> plain
<el-button @click="resetQuery"><Icon icon="ep:refresh" />重置</el-button> @click="handleExport"
<el-button :loading="exportLoading"
type="success" v-hasPermi="['project:acceptance:export']"
plain >
@click="handleExport" <Icon icon="ep:download" class="mr-1" />导出
:loading="exportLoading" </el-button>
v-hasPermi="['project:acceptance:export']" </el-form-item>
> </el-form>
<Icon icon="ep:download" />导出 </ContentWrap>
</el-button>
</el-form-item>
</el-form>
</ContentWrap>
<!-- 列表 --> <!-- 列表 -->
<ContentWrap> <ContentWrap class="mt-4">
<el-table v-loading="loading" :data="list"> <el-table
<el-table-column label="验收ID" align="center" prop="id" width="80" /> v-loading="loading"
<el-table-column label="项目ID" align="center" prop="projectId" width="80" /> :data="list"
<el-table-column label="验收类型" align="center" prop="acceptanceType" width="100"> :header-cell-style="{ background: '#f8fbfc', color: '#606266', height: '50px' }"
<template #default="scope"> :row-style="{ height: '60px' }"
<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-table-column label="ID" align="center" prop="id" width="80" class-name="font-mono text-gray-500" />
<el-tag v-else>{{ scope.row.acceptanceType }}</el-tag> <el-table-column label="轮次" align="center" prop="round" width="80">
</template> <template #default="scope">
</el-table-column> <span class="font-bold text-gray-600 bg-gray-100 px-2 py-1 rounded">R{{ scope.row.round }}</span>
<el-table-column label="状态" align="center" prop="status" width="100"> </template>
<template #default="scope"> </el-table-column>
<el-tag :type="getStatusType(scope.row.status)">{{ getStatusLabel(scope.row.status) }}</el-tag> <el-table-column label="项目ID" align="center" prop="projectId" width="100" />
</template>
</el-table-column> <el-table-column label="验收类型" align="center" prop="acceptanceType" width="120">
<el-table-column label="轮次" align="center" prop="round" width="80" /> <template #default="scope">
<el-table-column label="流程实例ID" align="center" prop="processInstanceId" :show-overflow-tooltip="true" /> <el-tag v-if="scope.row.acceptanceType === 'PRE'" type="info" effect="plain" class="!border-gray-300 !text-gray-600">
<el-table-column <span class="dot bg-gray-400 mr-1"></span>预验收
label="启动时间" </el-tag>
align="center" <el-tag v-else-if="scope.row.acceptanceType === 'FINAL'" type="primary" effect="plain" class="!border-blue-200 !text-blue-600">
prop="startTime" <span class="dot bg-blue-500 mr-1"></span>终验
:formatter="dateFormatter" </el-tag>
width="180" <el-tag v-else>{{ scope.row.acceptanceType }}</el-tag>
/> </template>
<el-table-column </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>
<!-- 审核表单弹窗 --> <el-table-column label="状态" align="center" prop="status" width="140">
<AcceptanceAuditForm ref="auditFormRef" @success="getList" /> <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> </template>
<style scoped>
.dot {
display: inline-block;
width: 6px;
height: 6px;
border-radius: 50%;
}
</style>
<script lang="ts" setup> <script lang="ts" setup>
import { dateFormatter } from '@/utils/formatTime' import { dateFormatter } from '@/utils/formatTime'
import download from '@/utils/download' import download from '@/utils/download'
@ -193,22 +215,48 @@ const queryParams = reactive({
const queryFormRef = ref() // const queryFormRef = ref() //
const exportLoading = ref(false) // const exportLoading = ref(false) //
// //
const statusMap: Record<string, { label: string; type: string }> = { const statusList = ref<{ code: string; name: string }[]>([])
'10': { label: '待审核', type: 'info' }, const statusMap = ref<Record<string, string>>({})
'20': { label: '审核中', type: 'warning' },
'30': { label: '待会议', type: '' }, /** 获取状态列表 */
'40': { label: '待整改', type: 'danger' }, const getStatusList = async () => {
'80': { label: '已通过', type: 'success' }, try {
'90': { label: '已驳回', type: 'danger' } 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) => { 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) => { 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() getList()
}) })
</script> </script>

View File

@ -81,22 +81,27 @@ const getList = async () => {
const auditFormRef = ref() const auditFormRef = ref()
const handleProcess = (row: AcceptanceApi.AcceptanceTodoVO) => { const handleProcess = (row: AcceptanceApi.AcceptanceTodoVO) => {
// //
// taskType BPMN taskDefinitionKey
const taskType = row.taskType 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({ auditFormRef.value.open({
id: row.acceptanceId, id: row.acceptanceId,
acceptanceType: row.acceptanceType, acceptanceType: row.acceptanceType,
status: row.status status: row.status
}, getAuditType(taskType)) }, 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' } }) 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) handleView(row)
} }
} }
@ -104,12 +109,16 @@ const handleProcess = (row: AcceptanceApi.AcceptanceTodoVO) => {
/** 获取审核类型 */ /** 获取审核类型 */
const getAuditType = (taskType: string) => { const getAuditType = (taskType: string) => {
switch (taskType) { switch (taskType) {
case 'LIAISON_REVIEW': case 'task_pre_liaison_review': //
case 'LEADER_REVIEW': case 'task_pre_leader_review': //
return 'pre-audit' return 'pre-audit'
case 'ADMIN_REVIEW': case 'task_final_admin_review': //
return 'final-admin' 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' return 'expert-check'
default: default:
return 'pre-audit' return 'pre-audit'