feat(审批流程): 优化审批逻辑并添加抄送功能
重构审批条件判断逻辑,统一使用canApprove和canWithdraw计算属性控制按钮显示 为所有审批详情页添加撤回按钮功能 在审批列表页新增抄送功能,支持多选抄送人 调整提交成功后的跳转路由为/hrm/apply 仅在approverMode为template时设置tplId参数
This commit is contained in:
@@ -295,11 +295,11 @@ export default {
|
||||
],
|
||||
approverRuleOptions: [
|
||||
{ label: '固定人员(选择)', value: 'fixed_user' },
|
||||
{ label: '角色(选择/输入编码)', value: 'role' },
|
||||
{ label: '岗位(选择)', value: 'position' },
|
||||
{ label: '部门负责人(自动)', value: 'dept_leader' },
|
||||
{ label: '发起人本人(自动)', value: 'initiator' },
|
||||
{ label: '表单字段指定(字段名)', value: 'form_field' }
|
||||
// { label: '角色(选择/输入编码)', value: 'role' },
|
||||
// { label: '岗位(选择)', value: 'position' },
|
||||
// { label: '部门负责人(自动)', value: 'dept_leader' },
|
||||
// { label: '发起人本人(自动)', value: 'initiator' },
|
||||
// { label: '表单字段指定(字段名)', value: 'form_field' }
|
||||
],
|
||||
rules: {
|
||||
tplId: [{ required: true, message: '请选择模板', trigger: 'change' }],
|
||||
|
||||
@@ -85,6 +85,7 @@
|
||||
<el-button size="mini" type="text" @click="handleApprove(scope.row)">通过</el-button>
|
||||
<el-button size="mini" type="text" @click="handleReject(scope.row)">驳回</el-button>
|
||||
<el-button size="mini" type="text" @click="handleTransfer(scope.row)">转发</el-button>
|
||||
<el-button size="mini" type="text" @click="handleCc(scope.row)">抄送</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
@@ -114,20 +115,55 @@
|
||||
</div>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 抄送弹窗 -->
|
||||
<el-dialog
|
||||
title="抄送"
|
||||
:visible.sync="ccDialogVisible"
|
||||
width="720px"
|
||||
append-to-body
|
||||
>
|
||||
<el-form :model="ccForm" label-width="90px" size="small">
|
||||
<el-form-item label="抄送人" required>
|
||||
<el-button size="mini" type="primary" plain icon="el-icon-user" @click="openUserMultiSelect">选择抄送人</el-button>
|
||||
<div class="selected-users" v-if="ccForm.selectedUsers && ccForm.selectedUsers.length">
|
||||
<el-tag
|
||||
v-for="u in ccForm.selectedUsers"
|
||||
:key="u.userId"
|
||||
size="mini"
|
||||
closable
|
||||
@close="removeCcUser(u)"
|
||||
>
|
||||
{{ u.nickName || u.userName || ('ID:' + u.userId) }}
|
||||
</el-tag>
|
||||
</div>
|
||||
<div v-else class="muted" style="margin-top:6px;">未选择抄送人</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="说明">
|
||||
<el-input v-model="ccForm.remark" type="textarea" :rows="3" placeholder="可选:抄送说明" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button @click="ccDialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" :loading="actionSubmitting" @click="submitCc">确定抄送</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 转发功能复用 UserSelect 组件 -->
|
||||
<UserSelect ref="userSelect" @onSelected="onManualApproverConfirmed" />
|
||||
|
||||
<UserMultiSelect ref="userMultiSelect" @onSelected="onCcUsersSelected" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { listTodoFlowTask, approveFlowTask, rejectFlowTask, transferFlowTask } from '@/api/hrm/flow'
|
||||
import { listTodoFlowTask, approveFlowTask, rejectFlowTask, transferFlowTask, ccFlowTask } from '@/api/hrm/flow'
|
||||
import { listEmployee } from '@/api/hrm'
|
||||
import UserSelect from '@/components/userSelect/single.vue'
|
||||
import UserMultiSelect from '@/components/userSelect/multi.vue'
|
||||
|
||||
|
||||
export default {
|
||||
name: 'HrmApproval',
|
||||
components: { UserSelect },
|
||||
components: { UserSelect, UserMultiSelect },
|
||||
data() {
|
||||
return {
|
||||
employees: [],
|
||||
@@ -148,7 +184,13 @@ export default {
|
||||
remark: ''
|
||||
},
|
||||
actionSubmitting: false,
|
||||
transferTask: null
|
||||
transferTask: null,
|
||||
ccTask: null,
|
||||
ccForm: {
|
||||
selectedUsers: []
|
||||
},
|
||||
ccDialogVisible: false,
|
||||
actionSubmitting: false
|
||||
}
|
||||
},
|
||||
created() {
|
||||
@@ -330,7 +372,34 @@ export default {
|
||||
this.$message.success('已转发')
|
||||
this.transferTask = null
|
||||
this.loadTodoList()
|
||||
}
|
||||
},
|
||||
handleCc(task) {
|
||||
this.ccTask = task
|
||||
// this.$refs.userMultiSelect.open()
|
||||
this.ccDialogVisible = true
|
||||
},
|
||||
openUserMultiSelect() { this.$refs.userMultiSelect.open() },
|
||||
onCcUsersSelected(users) { this.ccForm.selectedUsers = users || [] },
|
||||
removeCcUser(user) { this.ccForm.selectedUsers = this.ccForm.selectedUsers.filter(u => u.userId !== user.userId) },
|
||||
submitCc() {
|
||||
console.log(this.ccForm.selectedUsers, '抄送')
|
||||
const userIds = this.ccForm.selectedUsers.map(u => u.userId)
|
||||
if (!this.ccTask || userIds.length === 0) return this.$message.warning('请选择至少一个抄送人')
|
||||
const fromUserId = this.$store?.state?.user?.id
|
||||
ccFlowTask({
|
||||
instId: this.ccTask.instId,
|
||||
bizType: this.ccTask.bizType,
|
||||
bizId: this.ccTask.bizId,
|
||||
nodeId: this.ccTask.nodeId,
|
||||
nodeName: `节点#${this.ccTask.nodeId}`,
|
||||
fromUserId,
|
||||
ccUserIds: userIds,
|
||||
readFlag: 0,
|
||||
remark: this.ccForm.remark || '手动抄送'
|
||||
})
|
||||
.then(() => { this.$message.success('抄送成功'); this.ccDialogVisible = false })
|
||||
.catch(() => { this.$message.error('抄送失败') })
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -381,13 +381,16 @@ export default {
|
||||
const payload = {
|
||||
...this.form,
|
||||
status: 'pending',
|
||||
tplId: this.tplId,
|
||||
// tplId: this.tplId,
|
||||
manualAssigneeUserId: this.assigneeUserId
|
||||
}
|
||||
if (this.approverMode === 'template') {
|
||||
payload.tplId = this.tplId
|
||||
}
|
||||
try {
|
||||
await addLeaveReq(payload)
|
||||
this.$message.success('提交成功')
|
||||
this.$router.push('/hrm/requests')
|
||||
this.$router.push('/hrm/apply')
|
||||
} finally {
|
||||
this.submitting = false
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
<!-- 审批操作按钮 -->
|
||||
<el-button
|
||||
v-if="currentTask"
|
||||
v-if="canApprove"
|
||||
type="success"
|
||||
size="mini"
|
||||
:loading="actionLoading"
|
||||
@@ -18,7 +18,7 @@
|
||||
通过
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="currentTask"
|
||||
v-if="canApprove"
|
||||
type="danger"
|
||||
size="mini"
|
||||
:loading="actionLoading"
|
||||
@@ -26,14 +26,14 @@
|
||||
>
|
||||
驳回
|
||||
</el-button>
|
||||
<!-- <el-button
|
||||
<el-button
|
||||
v-if="canWithdraw"
|
||||
size="mini"
|
||||
:loading="actionLoading"
|
||||
@click="handleWithdraw"
|
||||
>
|
||||
撤回
|
||||
</el-button> -->
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -233,6 +233,11 @@ export default {
|
||||
canWithdraw() {
|
||||
// 只有待审批状态且是当前用户提交的才能撤回
|
||||
return this.detail.status === 'pending' && this.detail.createBy === this.$store.getters.name
|
||||
},
|
||||
canApprove() {
|
||||
// 只有待审批状态且是当前用户待审批的才能审批
|
||||
console.log(this.currentTask, this.$store.getters.name, this.$store.getters.id)
|
||||
return this.detail.status === 'pending' && (this.currentTask?.assigneeUserName === this.$store.getters.name || this.currentTask?.assigneeUserId === this.$store.getters.id)
|
||||
}
|
||||
},
|
||||
created() {
|
||||
|
||||
@@ -342,12 +342,15 @@ export default {
|
||||
accessoryReceiptIds: this.normalizeOssIds(this.form.accessoryReceiptIds),
|
||||
remark: this.form.remark,
|
||||
status: 'pending',
|
||||
tplId: this.tplId,
|
||||
// tplId: this.tplId,
|
||||
manualAssigneeUserId: this.assigneeUserId
|
||||
}
|
||||
if (this.approverMode === 'template') {
|
||||
payload.tplId = this.tplId
|
||||
}
|
||||
await addReimburseReq(payload)
|
||||
this.$message.success('提交成功')
|
||||
this.$router.push('/hrm/requests')
|
||||
this.$router.push('/hrm/apply')
|
||||
} catch (err) {
|
||||
// no-op
|
||||
} finally {
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
<!-- 审批操作按钮 -->
|
||||
<el-button
|
||||
v-if="currentTask"
|
||||
v-if="canApprove"
|
||||
type="success"
|
||||
size="mini"
|
||||
:loading="actionLoading"
|
||||
@@ -18,7 +18,7 @@
|
||||
通过
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="currentTask"
|
||||
v-if="canApprove"
|
||||
type="danger"
|
||||
size="mini"
|
||||
:loading="actionLoading"
|
||||
@@ -26,14 +26,14 @@
|
||||
>
|
||||
驳回
|
||||
</el-button>
|
||||
<!-- <el-button
|
||||
<el-button
|
||||
v-if="canWithdraw"
|
||||
size="mini"
|
||||
:loading="actionLoading"
|
||||
@click="handleWithdraw"
|
||||
>
|
||||
撤回
|
||||
</el-button> -->
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -236,8 +236,13 @@ export default {
|
||||
}
|
||||
return empId ? `员工ID:${empId}` : '-'
|
||||
},
|
||||
canApprove() {
|
||||
// 只有待审批状态且是当前用户待审批的才能审批
|
||||
console.log(this.currentTask, this.$store.getters.name, this.$store.getters.id)
|
||||
return this.detail.status === 'pending' && (this.currentTask?.assigneeUserName === this.$store.getters.name || this.currentTask?.assigneeUserId === this.$store.getters.id)
|
||||
},
|
||||
canWithdraw() {
|
||||
return this.detail.status === 'pending' && this.detail.createBy === this.$store.getters.userId
|
||||
return this.detail.status === 'pending' && this.detail.createBy === this.$store.getters.name
|
||||
}
|
||||
},
|
||||
created() {
|
||||
|
||||
@@ -386,13 +386,15 @@ export default {
|
||||
urgentLevel: this.form.urgentLevel,
|
||||
remark,
|
||||
status: 'pending',
|
||||
tplId: this.tplId,
|
||||
// tplId: this.tplId,
|
||||
manualAssigneeUserId: this.normalizeUserId(this.assigneeUserId)
|
||||
}
|
||||
|
||||
if (this.approverMode === 'template') {
|
||||
payload.tplId = this.tplId
|
||||
}
|
||||
await addSealReq(payload)
|
||||
this.$message.success('提交成功')
|
||||
this.$router.push('/hrm/requests')
|
||||
this.$router.push('/hrm/apply')
|
||||
} finally {
|
||||
this.submitting = false
|
||||
}
|
||||
|
||||
@@ -244,9 +244,9 @@
|
||||
<div v-if="currentTask" class="btn-row">
|
||||
<el-input v-model="actionRemark" type="textarea" :rows="3" placeholder="填写审批意见(可选)" />
|
||||
<div class="btn-row mt10">
|
||||
<el-button type="success" :loading="actionSubmitting" @click="submitTaskAction('approve')">通过</el-button>
|
||||
<el-button type="danger" :loading="actionSubmitting" @click="submitTaskAction('reject')">驳回</el-button>
|
||||
<el-button :loading="actionSubmitting" @click="submitTaskAction('withdraw')">撤回</el-button>
|
||||
<el-button type="success" v-if="canApprove" :loading="actionSubmitting" @click="submitTaskAction('approve')">通过</el-button>
|
||||
<el-button type="danger" v-if="canApprove" :loading="actionSubmitting" @click="submitTaskAction('reject')">驳回</el-button>
|
||||
<el-button v-if="canWithdraw" :loading="actionSubmitting" @click="submitTaskAction('withdraw')">撤回</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else class="empty">当前无待办任务(可能已处理完成,或你不是当前审批人)</div>
|
||||
@@ -361,10 +361,18 @@ export default {
|
||||
}
|
||||
return empId ? `员工ID:${empId}` : '-'
|
||||
},
|
||||
canApprove() {
|
||||
// 只有待审批状态且是当前用户待审批的才能审批
|
||||
return this.seal.status === 'pending' && (this.currentTask?.assigneeUserName === this.$store.getters.name || this.currentTask?.assigneeUserId === this.$store.getters.id)
|
||||
},
|
||||
canStamp() {
|
||||
// 审批通过后,且尚未生成回执时,可以盖章
|
||||
return this.seal.status === 'approved' && !this.seal.receiptFileIds && this.targetPdfFile && this.attachmentList.length > 0
|
||||
}
|
||||
},
|
||||
canWithdraw() {
|
||||
console.log(this.seal.createBy, this.$store.getters.name)
|
||||
return this.seal.status === 'running' && this.seal.createBy === this.$store.getters.name
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.loadEmployees()
|
||||
|
||||
@@ -408,13 +408,16 @@ export default {
|
||||
bankName: this.form.bankName,
|
||||
bankAccount: this.form.bankAccount,
|
||||
remark: this.form.remark,
|
||||
tplId: this.tplId,
|
||||
// tplId: this.tplId,
|
||||
manualAssigneeUserId: this.assigneeUserId
|
||||
}
|
||||
if (this.approverMode === 'template') {
|
||||
payload.tplId = this.tplId
|
||||
}
|
||||
try {
|
||||
await addTravelReq(payload)
|
||||
this.$message.success('提交成功')
|
||||
this.$router.push('/hrm/requests')
|
||||
this.$router.push('/hrm/apply')
|
||||
} catch (e) {
|
||||
this.$message.error('提交失败,请稍后重试')
|
||||
} finally {
|
||||
|
||||
@@ -160,9 +160,9 @@
|
||||
<div v-if="currentTask" class="btn-row">
|
||||
<el-input v-model="actionRemark" type="textarea" :rows="3" placeholder="填写审批意见(可选)" />
|
||||
<div class="btn-row mt10">
|
||||
<el-button type="success" :loading="actionSubmitting" @click="submitTaskAction('approve')">通过</el-button>
|
||||
<el-button type="danger" :loading="actionSubmitting" @click="submitTaskAction('reject')">驳回</el-button>
|
||||
<el-button :loading="actionSubmitting" @click="submitTaskAction('withdraw')">撤回</el-button>
|
||||
<el-button type="success" v-if="canApprove" :loading="actionSubmitting" @click="submitTaskAction('approve')">通过</el-button>
|
||||
<el-button type="danger" v-if="canApprove" :loading="actionSubmitting" @click="submitTaskAction('reject')">驳回</el-button>
|
||||
<el-button v-if="canWithdraw" :loading="actionSubmitting" @click="submitTaskAction('withdraw')">撤回</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else class="empty">当前无待办任务(可能已处理完成,或你不是当前审批人)</div>
|
||||
@@ -225,7 +225,14 @@ export default {
|
||||
return `${name || '员工'}${no}${dept}`.trim()
|
||||
}
|
||||
return empId ? `员工ID:${empId}` : '-'
|
||||
}
|
||||
},
|
||||
canApprove() {
|
||||
// 只有待审批状态且是当前用户待审批的才能审批
|
||||
return this.travel.status === 'pending' && (this.currentTask?.assigneeUserName === this.$store.getters.name || this.currentTask?.assigneeUserId === this.$store.getters.id)
|
||||
},
|
||||
canWithdraw() {
|
||||
return this.travel.status === 'pending' && this.travel.createBy === this.$store.getters.name
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.loadEmployees()
|
||||
|
||||
Reference in New Issue
Block a user