feat(审批流程): 优化审批逻辑并添加抄送功能
重构审批条件判断逻辑,统一使用canApprove和canWithdraw计算属性控制按钮显示 为所有审批详情页添加撤回按钮功能 在审批列表页新增抄送功能,支持多选抄送人 调整提交成功后的跳转路由为/hrm/apply 仅在approverMode为template时设置tplId参数
This commit is contained in:
@@ -295,11 +295,11 @@ export default {
|
|||||||
],
|
],
|
||||||
approverRuleOptions: [
|
approverRuleOptions: [
|
||||||
{ label: '固定人员(选择)', value: 'fixed_user' },
|
{ label: '固定人员(选择)', value: 'fixed_user' },
|
||||||
{ label: '角色(选择/输入编码)', value: 'role' },
|
// { label: '角色(选择/输入编码)', value: 'role' },
|
||||||
{ label: '岗位(选择)', value: 'position' },
|
// { label: '岗位(选择)', value: 'position' },
|
||||||
{ label: '部门负责人(自动)', value: 'dept_leader' },
|
// { label: '部门负责人(自动)', value: 'dept_leader' },
|
||||||
{ label: '发起人本人(自动)', value: 'initiator' },
|
// { label: '发起人本人(自动)', value: 'initiator' },
|
||||||
{ label: '表单字段指定(字段名)', value: 'form_field' }
|
// { label: '表单字段指定(字段名)', value: 'form_field' }
|
||||||
],
|
],
|
||||||
rules: {
|
rules: {
|
||||||
tplId: [{ required: true, message: '请选择模板', trigger: 'change' }],
|
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="handleApprove(scope.row)">通过</el-button>
|
||||||
<el-button size="mini" type="text" @click="handleReject(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="handleTransfer(scope.row)">转发</el-button>
|
||||||
|
<el-button size="mini" type="text" @click="handleCc(scope.row)">抄送</el-button>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
@@ -114,20 +115,55 @@
|
|||||||
</div>
|
</div>
|
||||||
</el-dialog>
|
</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 组件 -->
|
||||||
<UserSelect ref="userSelect" @onSelected="onManualApproverConfirmed" />
|
<UserSelect ref="userSelect" @onSelected="onManualApproverConfirmed" />
|
||||||
|
<UserMultiSelect ref="userMultiSelect" @onSelected="onCcUsersSelected" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<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 { listEmployee } from '@/api/hrm'
|
||||||
import UserSelect from '@/components/userSelect/single.vue'
|
import UserSelect from '@/components/userSelect/single.vue'
|
||||||
|
import UserMultiSelect from '@/components/userSelect/multi.vue'
|
||||||
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'HrmApproval',
|
name: 'HrmApproval',
|
||||||
components: { UserSelect },
|
components: { UserSelect, UserMultiSelect },
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
employees: [],
|
employees: [],
|
||||||
@@ -148,7 +184,13 @@ export default {
|
|||||||
remark: ''
|
remark: ''
|
||||||
},
|
},
|
||||||
actionSubmitting: false,
|
actionSubmitting: false,
|
||||||
transferTask: null
|
transferTask: null,
|
||||||
|
ccTask: null,
|
||||||
|
ccForm: {
|
||||||
|
selectedUsers: []
|
||||||
|
},
|
||||||
|
ccDialogVisible: false,
|
||||||
|
actionSubmitting: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
@@ -330,7 +372,34 @@ export default {
|
|||||||
this.$message.success('已转发')
|
this.$message.success('已转发')
|
||||||
this.transferTask = null
|
this.transferTask = null
|
||||||
this.loadTodoList()
|
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>
|
</script>
|
||||||
|
|||||||
@@ -381,13 +381,16 @@ export default {
|
|||||||
const payload = {
|
const payload = {
|
||||||
...this.form,
|
...this.form,
|
||||||
status: 'pending',
|
status: 'pending',
|
||||||
tplId: this.tplId,
|
// tplId: this.tplId,
|
||||||
manualAssigneeUserId: this.assigneeUserId
|
manualAssigneeUserId: this.assigneeUserId
|
||||||
}
|
}
|
||||||
|
if (this.approverMode === 'template') {
|
||||||
|
payload.tplId = this.tplId
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
await addLeaveReq(payload)
|
await addLeaveReq(payload)
|
||||||
this.$message.success('提交成功')
|
this.$message.success('提交成功')
|
||||||
this.$router.push('/hrm/requests')
|
this.$router.push('/hrm/apply')
|
||||||
} finally {
|
} finally {
|
||||||
this.submitting = false
|
this.submitting = false
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
<!-- 审批操作按钮 -->
|
<!-- 审批操作按钮 -->
|
||||||
<el-button
|
<el-button
|
||||||
v-if="currentTask"
|
v-if="canApprove"
|
||||||
type="success"
|
type="success"
|
||||||
size="mini"
|
size="mini"
|
||||||
:loading="actionLoading"
|
:loading="actionLoading"
|
||||||
@@ -18,7 +18,7 @@
|
|||||||
通过
|
通过
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button
|
<el-button
|
||||||
v-if="currentTask"
|
v-if="canApprove"
|
||||||
type="danger"
|
type="danger"
|
||||||
size="mini"
|
size="mini"
|
||||||
:loading="actionLoading"
|
:loading="actionLoading"
|
||||||
@@ -26,14 +26,14 @@
|
|||||||
>
|
>
|
||||||
驳回
|
驳回
|
||||||
</el-button>
|
</el-button>
|
||||||
<!-- <el-button
|
<el-button
|
||||||
v-if="canWithdraw"
|
v-if="canWithdraw"
|
||||||
size="mini"
|
size="mini"
|
||||||
:loading="actionLoading"
|
:loading="actionLoading"
|
||||||
@click="handleWithdraw"
|
@click="handleWithdraw"
|
||||||
>
|
>
|
||||||
撤回
|
撤回
|
||||||
</el-button> -->
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -233,6 +233,11 @@ export default {
|
|||||||
canWithdraw() {
|
canWithdraw() {
|
||||||
// 只有待审批状态且是当前用户提交的才能撤回
|
// 只有待审批状态且是当前用户提交的才能撤回
|
||||||
return this.detail.status === 'pending' && this.detail.createBy === this.$store.getters.name
|
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() {
|
created() {
|
||||||
|
|||||||
@@ -342,12 +342,15 @@ export default {
|
|||||||
accessoryReceiptIds: this.normalizeOssIds(this.form.accessoryReceiptIds),
|
accessoryReceiptIds: this.normalizeOssIds(this.form.accessoryReceiptIds),
|
||||||
remark: this.form.remark,
|
remark: this.form.remark,
|
||||||
status: 'pending',
|
status: 'pending',
|
||||||
tplId: this.tplId,
|
// tplId: this.tplId,
|
||||||
manualAssigneeUserId: this.assigneeUserId
|
manualAssigneeUserId: this.assigneeUserId
|
||||||
}
|
}
|
||||||
|
if (this.approverMode === 'template') {
|
||||||
|
payload.tplId = this.tplId
|
||||||
|
}
|
||||||
await addReimburseReq(payload)
|
await addReimburseReq(payload)
|
||||||
this.$message.success('提交成功')
|
this.$message.success('提交成功')
|
||||||
this.$router.push('/hrm/requests')
|
this.$router.push('/hrm/apply')
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
// no-op
|
// no-op
|
||||||
} finally {
|
} finally {
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
<!-- 审批操作按钮 -->
|
<!-- 审批操作按钮 -->
|
||||||
<el-button
|
<el-button
|
||||||
v-if="currentTask"
|
v-if="canApprove"
|
||||||
type="success"
|
type="success"
|
||||||
size="mini"
|
size="mini"
|
||||||
:loading="actionLoading"
|
:loading="actionLoading"
|
||||||
@@ -18,7 +18,7 @@
|
|||||||
通过
|
通过
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button
|
<el-button
|
||||||
v-if="currentTask"
|
v-if="canApprove"
|
||||||
type="danger"
|
type="danger"
|
||||||
size="mini"
|
size="mini"
|
||||||
:loading="actionLoading"
|
:loading="actionLoading"
|
||||||
@@ -26,14 +26,14 @@
|
|||||||
>
|
>
|
||||||
驳回
|
驳回
|
||||||
</el-button>
|
</el-button>
|
||||||
<!-- <el-button
|
<el-button
|
||||||
v-if="canWithdraw"
|
v-if="canWithdraw"
|
||||||
size="mini"
|
size="mini"
|
||||||
:loading="actionLoading"
|
:loading="actionLoading"
|
||||||
@click="handleWithdraw"
|
@click="handleWithdraw"
|
||||||
>
|
>
|
||||||
撤回
|
撤回
|
||||||
</el-button> -->
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -236,8 +236,13 @@ export default {
|
|||||||
}
|
}
|
||||||
return empId ? `员工ID:${empId}` : '-'
|
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() {
|
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() {
|
created() {
|
||||||
|
|||||||
@@ -386,13 +386,15 @@ export default {
|
|||||||
urgentLevel: this.form.urgentLevel,
|
urgentLevel: this.form.urgentLevel,
|
||||||
remark,
|
remark,
|
||||||
status: 'pending',
|
status: 'pending',
|
||||||
tplId: this.tplId,
|
// tplId: this.tplId,
|
||||||
manualAssigneeUserId: this.normalizeUserId(this.assigneeUserId)
|
manualAssigneeUserId: this.normalizeUserId(this.assigneeUserId)
|
||||||
}
|
}
|
||||||
|
if (this.approverMode === 'template') {
|
||||||
|
payload.tplId = this.tplId
|
||||||
|
}
|
||||||
await addSealReq(payload)
|
await addSealReq(payload)
|
||||||
this.$message.success('提交成功')
|
this.$message.success('提交成功')
|
||||||
this.$router.push('/hrm/requests')
|
this.$router.push('/hrm/apply')
|
||||||
} finally {
|
} finally {
|
||||||
this.submitting = false
|
this.submitting = false
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -244,9 +244,9 @@
|
|||||||
<div v-if="currentTask" class="btn-row">
|
<div v-if="currentTask" class="btn-row">
|
||||||
<el-input v-model="actionRemark" type="textarea" :rows="3" placeholder="填写审批意见(可选)" />
|
<el-input v-model="actionRemark" type="textarea" :rows="3" placeholder="填写审批意见(可选)" />
|
||||||
<div class="btn-row mt10">
|
<div class="btn-row mt10">
|
||||||
<el-button type="success" :loading="actionSubmitting" @click="submitTaskAction('approve')">通过</el-button>
|
<el-button type="success" v-if="canApprove" :loading="actionSubmitting" @click="submitTaskAction('approve')">通过</el-button>
|
||||||
<el-button type="danger" :loading="actionSubmitting" @click="submitTaskAction('reject')">驳回</el-button>
|
<el-button type="danger" v-if="canApprove" :loading="actionSubmitting" @click="submitTaskAction('reject')">驳回</el-button>
|
||||||
<el-button :loading="actionSubmitting" @click="submitTaskAction('withdraw')">撤回</el-button>
|
<el-button v-if="canWithdraw" :loading="actionSubmitting" @click="submitTaskAction('withdraw')">撤回</el-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-else class="empty">当前无待办任务(可能已处理完成,或你不是当前审批人)</div>
|
<div v-else class="empty">当前无待办任务(可能已处理完成,或你不是当前审批人)</div>
|
||||||
@@ -361,10 +361,18 @@ export default {
|
|||||||
}
|
}
|
||||||
return empId ? `员工ID:${empId}` : '-'
|
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() {
|
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() {
|
||||||
|
console.log(this.seal.createBy, this.$store.getters.name)
|
||||||
|
return this.seal.status === 'running' && this.seal.createBy === this.$store.getters.name
|
||||||
|
},
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
this.loadEmployees()
|
this.loadEmployees()
|
||||||
|
|||||||
@@ -408,13 +408,16 @@ export default {
|
|||||||
bankName: this.form.bankName,
|
bankName: this.form.bankName,
|
||||||
bankAccount: this.form.bankAccount,
|
bankAccount: this.form.bankAccount,
|
||||||
remark: this.form.remark,
|
remark: this.form.remark,
|
||||||
tplId: this.tplId,
|
// tplId: this.tplId,
|
||||||
manualAssigneeUserId: this.assigneeUserId
|
manualAssigneeUserId: this.assigneeUserId
|
||||||
}
|
}
|
||||||
|
if (this.approverMode === 'template') {
|
||||||
|
payload.tplId = this.tplId
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
await addTravelReq(payload)
|
await addTravelReq(payload)
|
||||||
this.$message.success('提交成功')
|
this.$message.success('提交成功')
|
||||||
this.$router.push('/hrm/requests')
|
this.$router.push('/hrm/apply')
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
this.$message.error('提交失败,请稍后重试')
|
this.$message.error('提交失败,请稍后重试')
|
||||||
} finally {
|
} finally {
|
||||||
|
|||||||
@@ -160,9 +160,9 @@
|
|||||||
<div v-if="currentTask" class="btn-row">
|
<div v-if="currentTask" class="btn-row">
|
||||||
<el-input v-model="actionRemark" type="textarea" :rows="3" placeholder="填写审批意见(可选)" />
|
<el-input v-model="actionRemark" type="textarea" :rows="3" placeholder="填写审批意见(可选)" />
|
||||||
<div class="btn-row mt10">
|
<div class="btn-row mt10">
|
||||||
<el-button type="success" :loading="actionSubmitting" @click="submitTaskAction('approve')">通过</el-button>
|
<el-button type="success" v-if="canApprove" :loading="actionSubmitting" @click="submitTaskAction('approve')">通过</el-button>
|
||||||
<el-button type="danger" :loading="actionSubmitting" @click="submitTaskAction('reject')">驳回</el-button>
|
<el-button type="danger" v-if="canApprove" :loading="actionSubmitting" @click="submitTaskAction('reject')">驳回</el-button>
|
||||||
<el-button :loading="actionSubmitting" @click="submitTaskAction('withdraw')">撤回</el-button>
|
<el-button v-if="canWithdraw" :loading="actionSubmitting" @click="submitTaskAction('withdraw')">撤回</el-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-else class="empty">当前无待办任务(可能已处理完成,或你不是当前审批人)</div>
|
<div v-else class="empty">当前无待办任务(可能已处理完成,或你不是当前审批人)</div>
|
||||||
@@ -225,7 +225,14 @@ export default {
|
|||||||
return `${name || '员工'}${no}${dept}`.trim()
|
return `${name || '员工'}${no}${dept}`.trim()
|
||||||
}
|
}
|
||||||
return empId ? `员工ID:${empId}` : '-'
|
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() {
|
created() {
|
||||||
this.loadEmployees()
|
this.loadEmployees()
|
||||||
|
|||||||
Reference in New Issue
Block a user