feat(flow): 添加流程实例更新功能并禁用撤回操作
添加updateFlowInstance API用于更新流程实例 在所有详情页面禁用撤回功能 修改审批状态从pending到running 在抄送页面添加详情跳转功能
This commit is contained in:
@@ -9,6 +9,14 @@ export function listFlowTask(query) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function updateFlowInstance(data) {
|
||||||
|
return request({
|
||||||
|
url: '/hrm/flow/instance',
|
||||||
|
method: 'put',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
export function listTodoFlowTask(assigneeUserId) {
|
export function listTodoFlowTask(assigneeUserId) {
|
||||||
return request({
|
return request({
|
||||||
url: '/hrm/flow/task/todo',
|
url: '/hrm/flow/task/todo',
|
||||||
|
|||||||
@@ -21,43 +21,31 @@
|
|||||||
<el-tab-pane label="已读" name="read" />
|
<el-tab-pane label="已读" name="read" />
|
||||||
</el-tabs>
|
</el-tabs>
|
||||||
|
|
||||||
<el-table
|
<el-table v-loading="loading" :data="ccList" border style="width: 100%" :row-class-name="tableRowClassName">
|
||||||
v-loading="loading"
|
|
||||||
:data="ccList"
|
|
||||||
border
|
|
||||||
style="width: 100%"
|
|
||||||
:row-class-name="tableRowClassName"
|
|
||||||
>
|
|
||||||
<el-table-column label="业务" prop="bizTypeName" width="150" />
|
<el-table-column label="业务" prop="bizTypeName" width="150" />
|
||||||
<el-table-column label="内容" prop="bizTitle" min-width="300" show-overflow-tooltip />
|
<el-table-column label="内容" prop="bizTitle" min-width="300" show-overflow-tooltip />
|
||||||
<el-table-column label="节点" prop="nodeName" width="180" />
|
<el-table-column label="节点" prop="nodeName" width="180" />
|
||||||
<el-table-column label="抄送人" prop="createBy" >
|
<el-table-column label="抄送人" prop="createBy">
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="抄送时间" prop="createTime" width="180">
|
<el-table-column label="抄送时间" prop="createTime" width="180">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
{{ parseTime(scope.row.createTime) }}
|
{{ parseTime(scope.row.createTime) }}
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="操作" width="100" fixed="right" v-if="activeTab === 'unread'">
|
<el-table-column label="操作" width="100" fixed="right">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-link
|
<el-link v-if="activeTab === 'unread'" type="primary" @click.stop="handleRead(scope.row)">
|
||||||
v-if="scope.row.readFlag === 0"
|
|
||||||
type="primary"
|
|
||||||
@click.stop="handleRead(scope.row)"
|
|
||||||
>
|
|
||||||
标记已读
|
标记已读
|
||||||
</el-link>
|
</el-link>
|
||||||
|
<el-link type="primary" @click.stop="handleDetail(scope.row)">
|
||||||
|
详情
|
||||||
|
</el-link>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
|
|
||||||
<pagination
|
<pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize"
|
||||||
v-show="total > 0"
|
@pagination="getList" />
|
||||||
:total="total"
|
|
||||||
:page.sync="queryParams.pageNum"
|
|
||||||
:limit.sync="queryParams.pageSize"
|
|
||||||
@pagination="getList"
|
|
||||||
/>
|
|
||||||
</el-card>
|
</el-card>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -100,6 +88,34 @@ export default {
|
|||||||
this.queryParams.readFlag = this.activeTab === 'read' ? 1 : 0
|
this.queryParams.readFlag = this.activeTab === 'read' ? 1 : 0
|
||||||
this.getList()
|
this.getList()
|
||||||
},
|
},
|
||||||
|
handleDetail(row) {
|
||||||
|
if (!row || !row.bizId || !row.bizType) {
|
||||||
|
this.$message.warning('缺少businessKey,无法打开详情')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const { bizId, bizType: type } = row
|
||||||
|
if (!bizId) {
|
||||||
|
this.$message.warning('businessKey格式不正确,无法解析业务ID')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const pathMap = {
|
||||||
|
leave: '/hrm/HrmLeaveDetail',
|
||||||
|
travel: '/hrm/HrmTravelDetail',
|
||||||
|
seal: '/hrm/HrmSealDetail',
|
||||||
|
reimburse: '/hrm/HrmReimburseDetail'
|
||||||
|
}
|
||||||
|
const routePath = pathMap[type]
|
||||||
|
|
||||||
|
if (routePath) {
|
||||||
|
this.$router.push({
|
||||||
|
path: routePath,
|
||||||
|
query: { bizId: bizId }
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
this.$message.warning('无法确定申请类型对应的详情页面')
|
||||||
|
}
|
||||||
|
},
|
||||||
getList() {
|
getList() {
|
||||||
this.loading = true
|
this.loading = true
|
||||||
listCc({ ...this.queryParams, ccUserId: this.currentUserId })
|
listCc({ ...this.queryParams, ccUserId: this.currentUserId })
|
||||||
@@ -131,21 +147,26 @@ export default {
|
|||||||
.flow-cc-container {
|
.flow-cc-container {
|
||||||
padding: 20px 20px 0 20px;
|
padding: 20px 20px 0 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.card-header {
|
.card-header {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
height: 32px;
|
height: 32px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.card-title {
|
.card-title {
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
}
|
}
|
||||||
|
|
||||||
.badge {
|
.badge {
|
||||||
margin-left: 6px;
|
margin-left: 6px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 未读行高亮(柔和背景,不用渐变) */
|
/* 未读行高亮(柔和背景,不用渐变) */
|
||||||
.row-unread td {
|
.row-unread td {
|
||||||
background-color: #fdf6ec !important; /* Element UI warning-light */
|
background-color: #fdf6ec !important;
|
||||||
|
/* Element UI warning-light */
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -55,7 +55,7 @@
|
|||||||
>
|
>
|
||||||
<el-option label="全部" value="" />
|
<el-option label="全部" value="" />
|
||||||
<el-option label="草稿" value="draft" />
|
<el-option label="草稿" value="draft" />
|
||||||
<el-option label="审批中" value="pending" />
|
<el-option label="审批中" value="running" />
|
||||||
<el-option label="已通过" value="approved" />
|
<el-option label="已通过" value="approved" />
|
||||||
<el-option label="已驳回" value="rejected" />
|
<el-option label="已驳回" value="rejected" />
|
||||||
</el-select>
|
</el-select>
|
||||||
@@ -82,7 +82,8 @@
|
|||||||
</el-table-column> -->
|
</el-table-column> -->
|
||||||
<el-table-column label="类型/目的" min-width="140">
|
<el-table-column label="类型/目的" min-width="140">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
{{ getTypeDetail(scope.row) }}
|
<el-input v-model="scope.row.remark" placeholder="请输入类型/目的便于审批或查看" @change="handleRemarkChange(scope.row)"></el-input>
|
||||||
|
<!-- {{ getTypeDetail(scope.row) }} -->
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<!-- <el-table-column label="开始时间" prop="startTime" min-width="160">
|
<!-- <el-table-column label="开始时间" prop="startTime" min-width="160">
|
||||||
@@ -125,7 +126,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { listMyFlowInstance } from '@/api/hrm/flow'
|
import { listMyFlowInstance, updateFlowInstance } from '@/api/hrm/flow'
|
||||||
import { getEmployeeByUserId } from '@/api/hrm/employee'
|
import { getEmployeeByUserId } from '@/api/hrm/employee'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
@@ -185,6 +186,21 @@ export default {
|
|||||||
const dept = emp.deptName ? ` · ${emp.deptName}` : ''
|
const dept = emp.deptName ? ` · ${emp.deptName}` : ''
|
||||||
return `${name || '员工'}${no}${dept}`.trim()
|
return `${name || '员工'}${no}${dept}`.trim()
|
||||||
},
|
},
|
||||||
|
handleRemarkChange(row) {
|
||||||
|
updateFlowInstance(row).then(response => {
|
||||||
|
if (response.code === 200) {
|
||||||
|
this.$message({
|
||||||
|
message: '更新成功',
|
||||||
|
type: 'success'
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
this.$message({
|
||||||
|
message: `更新失败: ${response.msg || '未知错误'}`,
|
||||||
|
type: 'error'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
formatEmpDisplay(userId) {
|
formatEmpDisplay(userId) {
|
||||||
// The API returns startUserId, which is a user ID, not an empId.
|
// The API returns startUserId, which is a user ID, not an empId.
|
||||||
// We can display the current user's name if the ID matches.
|
// We can display the current user's name if the ID matches.
|
||||||
@@ -303,7 +319,7 @@ export default {
|
|||||||
pageNum: this.historyQuery.pageNum,
|
pageNum: this.historyQuery.pageNum,
|
||||||
pageSize: this.historyQuery.pageSize,
|
pageSize: this.historyQuery.pageSize,
|
||||||
bizType: this.historyQuery.type || undefined, // 业务类型:leave/travel/seal/reimburse
|
bizType: this.historyQuery.type || undefined, // 业务类型:leave/travel/seal/reimburse
|
||||||
status: this.historyQuery.status || undefined // 状态:draft/pending/approved/rejected
|
status: this.historyQuery.status || undefined // 状态:draft/running/approved/rejected
|
||||||
}
|
}
|
||||||
const res = await listMyFlowInstance(params)
|
const res = await listMyFlowInstance(params)
|
||||||
if (res.code === 200) {
|
if (res.code === 200) {
|
||||||
|
|||||||
@@ -231,6 +231,7 @@ export default {
|
|||||||
return typeMap[this.detail.status] || 'info'
|
return typeMap[this.detail.status] || 'info'
|
||||||
},
|
},
|
||||||
canWithdraw() {
|
canWithdraw() {
|
||||||
|
return false;
|
||||||
// 只有待审批状态且是当前用户提交的才能撤回
|
// 只有待审批状态且是当前用户提交的才能撤回
|
||||||
return this.detail.status === 'pending' && this.detail.createBy === this.$store.getters.name
|
return this.detail.status === 'pending' && this.detail.createBy === this.$store.getters.name
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -242,6 +242,7 @@ export default {
|
|||||||
return this.detail.status === 'pending' && (this.currentTask?.assigneeUserName === this.$store.getters.name || this.currentTask?.assigneeUserId === this.$store.getters.id)
|
return this.detail.status === 'pending' && (this.currentTask?.assigneeUserName === this.$store.getters.name || this.currentTask?.assigneeUserId === this.$store.getters.id)
|
||||||
},
|
},
|
||||||
canWithdraw() {
|
canWithdraw() {
|
||||||
|
return false;
|
||||||
return this.detail.status === 'pending' && this.detail.createBy === this.$store.getters.name
|
return this.detail.status === 'pending' && this.detail.createBy === this.$store.getters.name
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -362,15 +362,16 @@ export default {
|
|||||||
return empId ? `员工ID:${empId}` : '-'
|
return empId ? `员工ID:${empId}` : '-'
|
||||||
},
|
},
|
||||||
canApprove() {
|
canApprove() {
|
||||||
|
console.log(this.currentTask, this.$store.getters.id, this.$store.getters.name)
|
||||||
// 只有待审批状态且是当前用户待审批的才能审批
|
// 只有待审批状态且是当前用户待审批的才能审批
|
||||||
return this.seal.status === 'pending' && (this.currentTask?.assigneeUserName === this.$store.getters.name || this.currentTask?.assigneeUserId === this.$store.getters.id)
|
return this.seal.status === 'running' && (this.currentTask?.assigneeUserName === this.$store.getters.name || this.currentTask?.assigneeUserId === this.$store.getters.id)
|
||||||
},
|
},
|
||||||
canStamp() {
|
canStamp() {
|
||||||
// 审批通过后,且尚未生成回执时,可以盖章
|
// 审批通过后,且尚未生成回执时,可以盖章
|
||||||
return this.seal.status === 'approved' && !this.seal.receiptFileIds && this.targetPdfFile && this.attachmentList.length > 0
|
return this.seal.status === 'approved' && !this.seal.receiptFileIds && this.targetPdfFile && this.attachmentList.length > 0
|
||||||
},
|
},
|
||||||
canWithdraw() {
|
canWithdraw() {
|
||||||
console.log(this.seal.createBy, this.$store.getters.name)
|
return false;
|
||||||
return this.seal.status === 'running' && this.seal.createBy === this.$store.getters.name
|
return this.seal.status === 'running' && this.seal.createBy === this.$store.getters.name
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -385,11 +386,11 @@ export default {
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
statusText(status) {
|
statusText(status) {
|
||||||
const map = { pending: '审批中', draft: '草稿', approved: '已通过', rejected: '已驳回', canceled: '已撤销' }
|
const map = { running: '审批中', draft: '草稿', approved: '已通过', rejected: '已驳回', canceled: '已撤销' }
|
||||||
return map[status] || status || '-'
|
return map[status] || status || '-'
|
||||||
},
|
},
|
||||||
statusType(status) {
|
statusType(status) {
|
||||||
const map = { pending: 'warning', draft: 'info', approved: 'success', rejected: 'danger', canceled: 'info' }
|
const map = { running: 'warning', draft: 'info', approved: 'success', rejected: 'danger', canceled: 'info' }
|
||||||
return map[status] || 'info'
|
return map[status] || 'info'
|
||||||
},
|
},
|
||||||
formatDate(val) {
|
formatDate(val) {
|
||||||
|
|||||||
@@ -231,6 +231,7 @@ export default {
|
|||||||
return this.travel.status === 'pending' && (this.currentTask?.assigneeUserName === this.$store.getters.name || this.currentTask?.assigneeUserId === this.$store.getters.id)
|
return this.travel.status === 'pending' && (this.currentTask?.assigneeUserName === this.$store.getters.name || this.currentTask?.assigneeUserId === this.$store.getters.id)
|
||||||
},
|
},
|
||||||
canWithdraw() {
|
canWithdraw() {
|
||||||
|
return false;
|
||||||
return this.travel.status === 'pending' && this.travel.createBy === this.$store.getters.name
|
return this.travel.status === 'pending' && this.travel.createBy === this.$store.getters.name
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user