feat: 借库审批支持手动完结——已通过(status=1)单可强制完结,库管/主管/超管可见

This commit is contained in:
yueli
2026-09-04 14:52:31 +08:00
parent 0daf50ac21
commit 3bd19c1ab5
3 changed files with 76 additions and 2 deletions

View File

@ -277,6 +277,29 @@ def approve_borrow_request(request_id):
return jsonify({'code': 500, 'msg': f'服务器内部错误: {str(e)}'}), 500 return jsonify({'code': 500, 'msg': f'服务器内部错误: {str(e)}'}), 500
@trans_bp.route('/borrow/request/<int:request_id>/close', methods=['POST'])
@jwt_required()
@permission_required('op_borrow_approval')
def close_borrow_request(request_id):
"""
手动完结已通过的借库审批单(status 1-已通过 → 3-已完成)
参照出库审批的完结逻辑,供库管/主管在未走扫码借出时强制完结
"""
try:
user_id, _ = get_current_user_info()
if not user_id:
return jsonify({'code': 401, 'msg': '用户未登录'}), 401
success, message, approval = BorrowApprovalService.mark_completed(request_id)
if not success:
return jsonify({'code': 400, 'msg': message}), 400
return jsonify({'code': 200, 'msg': message, 'data': approval.to_dict() if approval else None}), 200
except Exception as e:
traceback.print_exc()
return jsonify({'code': 500, 'msg': f'服务器内部错误: {str(e)}'}), 500
# --- 获取借库审批单列表 --- # --- 获取借库审批单列表 ---
@trans_bp.route('/borrow/request', methods=['GET']) @trans_bp.route('/borrow/request', methods=['GET'])
@jwt_required() @jwt_required()

View File

@ -174,6 +174,14 @@ export function approveBorrowRequest(id: number, data: { action: 'approve' | 're
}) })
} }
// 手动完结已通过的借库审批单(status 1 → 3)
export function closeBorrowRequest(id: number) {
return request({
url: `/v1/transactions/borrow/request/${id}/close`,
method: 'post'
})
}
/** /**
* 借库选单专用库存列表(独立权限 op_borrow_apply) * 借库选单专用库存列表(独立权限 op_borrow_apply)
*/ */

View File

@ -137,6 +137,19 @@
驳回 驳回
</el-button> </el-button>
</template> </template>
<!-- ★ 已通过的申请单:库管/主管可手动完结 -->
<template v-else-if="row.status === 1">
<el-button
v-if="canCompleteRequest"
type="danger"
plain
size="small"
:loading="row._closing"
@click="handleComplete(row)"
>
完结
</el-button>
</template>
<span v-else style="color: #c0c4cc;">-</span> <span v-else style="color: #c0c4cc;">-</span>
</template> </template>
</el-table-column> </el-table-column>
@ -182,14 +195,44 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, onMounted } from 'vue' import { ref, computed, onMounted } from 'vue'
import { Refresh, Warning } from '@element-plus/icons-vue' import { Refresh, Warning } from '@element-plus/icons-vue'
import { ElMessage, ElMessageBox } from 'element-plus' import { ElMessage, ElMessageBox } from 'element-plus'
import { getBorrowApprovalList, approveBorrowRequest } from '@/api/transaction' import { getBorrowApprovalList, approveBorrowRequest, closeBorrowRequest } from '@/api/transaction'
import { useUserStore } from '@/stores/user' import { useUserStore } from '@/stores/user'
const userStore = useUserStore() const userStore = useUserStore()
// ★ 完结权限:超管 / 审批操作(op_borrow_approval:operation) / 借库执行(op_borrow:operation)
const canCompleteRequest = computed(() =>
userStore.role === 'SUPER_ADMIN' ||
userStore.hasPermission('op_borrow_approval:operation') ||
userStore.hasPermission('op_borrow:operation') ||
userStore.username === 'IRIS'
)
// ★ 手动完结已通过的借库审批单(status 1 → 3,仿出库审批)
const handleComplete = (row: any) => {
ElMessageBox.confirm(
`确定强制完结审批单【${row.request_no}】吗?\n\n完结后该单标记为「已完成」,不可再扫码借出。`,
'⚠️ 强制完结确认',
{ confirmButtonText: '确认完结', cancelButtonText: '取消', type: 'warning' }
)
.then(async () => {
row._closing = true
try {
await closeBorrowRequest(row.id)
ElMessage.success('审批单已完结')
fetchData()
} catch (e: any) {
ElMessage.error(e?.response?.data?.msg || e?.msg || e?.message || '完结失败')
} finally {
row._closing = false
}
})
.catch(() => {})
}
// --- 状态 --- // --- 状态 ---
const list = ref<any[]>([]) const list = ref<any[]>([])
const loading = ref(false) const loading = ref(false)