feat(borrow): 借库审批补「完结」能力(对齐出库 status=4)

- mark_completed 改为 1→4 已完结(真正扫码借出完成仍为 status=3)
- 前端审批页新增「已完结」筛选项与状态映射;审批信息列对 3/4 显示审批人
This commit is contained in:
yueli
2026-09-10 09:47:07 +08:00
parent da5357acb3
commit 1dbf74b7bc
3 changed files with 12 additions and 8 deletions

View File

@ -307,7 +307,7 @@ def approve_borrow_request(request_id):
@permission_required('op_borrow_approval') @permission_required('op_borrow_approval')
def close_borrow_request(request_id): def close_borrow_request(request_id):
""" """
手动完结已通过的借库审批单(status 1-已通过 → 3-已完成) 手动完结已通过的借库审批单(status 1-已通过 → 4-已完结)
参照出库审批的完结逻辑,供库管/主管在未走扫码借出时强制完结 参照出库审批的完结逻辑,供库管/主管在未走扫码借出时强制完结
""" """
try: try:

View File

@ -464,18 +464,21 @@ class BorrowApprovalService:
@staticmethod @staticmethod
def mark_completed(request_id): def mark_completed(request_id):
"""标记审批单为已完成(借库执行完成后调用)""" """
手动完结已通过的借库审批单(status 1-已通过 → 4-已完结,对齐出库审批的完结语义)。
注意:真正“扫码借出执行完成”走 trans_service.execute_dispatch,置 status=3(已完成)。
"""
approval = BorrowApproval.query.get(request_id) approval = BorrowApproval.query.get(request_id)
if not approval: if not approval:
return False, "审批单不存在", None return False, "审批单不存在", None
if approval.status != 1: if approval.status != 1:
return False, f"只有已通过的审批单才能标记为完成 (当前状态: {approval.status})", None return False, f"只有已通过的审批单才能标记为完结 (当前状态: {approval.status})", None
try: try:
approval.status = 3 # 已完成 approval.status = 4 # 已完结
db.session.commit() db.session.commit()
return True, "审批单已完成", approval return True, "审批单已完结", approval
except Exception as e: except Exception as e:
db.session.rollback() db.session.rollback()
return False, f"操作失败: {str(e)}", None return False, f"操作失败: {str(e)}", None

View File

@ -10,6 +10,7 @@
<el-radio-button :label="1">已通过</el-radio-button> <el-radio-button :label="1">已通过</el-radio-button>
<el-radio-button :label="2">已驳回</el-radio-button> <el-radio-button :label="2">已驳回</el-radio-button>
<el-radio-button :label="3">已完成</el-radio-button> <el-radio-button :label="3">已完成</el-radio-button>
<el-radio-button :label="4">已完结</el-radio-button>
</el-radio-group> </el-radio-group>
<el-button type="primary" :icon="Refresh" @click="fetchData">刷新</el-button> <el-button type="primary" :icon="Refresh" @click="fetchData">刷新</el-button>
</div> </div>
@ -108,7 +109,7 @@
<el-icon style="margin-left: 4px; cursor: pointer;"><Warning /></el-icon> <el-icon style="margin-left: 4px; cursor: pointer;"><Warning /></el-icon>
</el-tooltip> </el-tooltip>
</template> </template>
<template v-else-if="row.status === 3"> <template v-else-if="row.status === 3 || row.status === 4">
<span style="color: #909399;">{{ getApproverName(row.actual_approver_id) }}</span> <span style="color: #909399;">{{ getApproverName(row.actual_approver_id) }}</span>
</template> </template>
<span v-else style="color: #c0c4cc;">-</span> <span v-else style="color: #c0c4cc;">-</span>
@ -254,14 +255,14 @@ const userNameCache = ref<Record<number, string>>({})
// --- 工具函数 --- // --- 工具函数 ---
const statusText = (status: number) => { const statusText = (status: number) => {
const map: Record<number, string> = { const map: Record<number, string> = {
0: '待审批', 1: '已通过', 2: '已驳回', 3: '已完成' 0: '待审批', 1: '已通过', 2: '已驳回', 3: '已完成', 4: '已完结'
} }
return map[status] ?? '-' return map[status] ?? '-'
} }
const statusTagType = (status: number) => { const statusTagType = (status: number) => {
const map: Record<number, string> = { const map: Record<number, string> = {
0: 'warning', 1: 'success', 2: 'danger', 3: 'info' 0: 'warning', 1: 'success', 2: 'danger', 3: 'info', 4: 'info'
} }
return map[status] ?? 'info' return map[status] ?? 'info'
} }