feat: 采购申请完结功能移到批次主行,与出库审批一致
- 移除展开行内的单条完结按钮(需点开),改为主行'完结本批'直接可见 - 后端 batch-approve 支持 action=close(批次内已通过→已完结) - 超管/库管在主行操作列即可看到并完结
This commit is contained in:
@ -273,20 +273,23 @@ def batch_approve_purchase():
|
|||||||
action = data.get('action', 'approve')
|
action = data.get('action', 'approve')
|
||||||
reject_reason = data.get('reject_reason')
|
reject_reason = data.get('reject_reason')
|
||||||
|
|
||||||
# 若传 batch_key(request_no 去掉末尾流水号的前缀),查出该批次所有待审批记录
|
# 若传 batch_key(request_no 去掉末尾流水号的前缀),查出该批次对应状态的记录
|
||||||
if batch_key:
|
if batch_key:
|
||||||
from app.models.purchase import PurchaseRequest
|
from app.models.purchase import PurchaseRequest
|
||||||
|
# 完结本批 → 找「已通过(1)」的单;审批/驳回 → 找「待审批(0)」的单
|
||||||
|
target_status = 1 if action == 'close' else 0
|
||||||
records = PurchaseRequest.query.filter(
|
records = PurchaseRequest.query.filter(
|
||||||
PurchaseRequest.request_no.like(f"{batch_key}-%"),
|
PurchaseRequest.request_no.like(f"{batch_key}-%"),
|
||||||
PurchaseRequest.status == 0
|
PurchaseRequest.status == target_status
|
||||||
).all()
|
).all()
|
||||||
ids = [r.id for r in records]
|
ids = [r.id for r in records]
|
||||||
if not ids:
|
if not ids:
|
||||||
return jsonify({'code': 400, 'msg': '该批次没有待审批的记录'}), 400
|
status_text = '已通过' if action == 'close' else '待审批'
|
||||||
|
return jsonify({'code': 400, 'msg': f'该批次没有{status_text}的记录'}), 400
|
||||||
|
|
||||||
if not ids or not isinstance(ids, list):
|
if not ids or not isinstance(ids, list):
|
||||||
return jsonify({'code': 400, 'msg': 'ids 或 batch_key 不能为空'}), 400
|
return jsonify({'code': 400, 'msg': 'ids 或 batch_key 不能为空'}), 400
|
||||||
if action not in ('approve', 'reject'):
|
if action not in ('approve', 'reject', 'close'):
|
||||||
return jsonify({'code': 400, 'msg': '无效的审批操作'}), 400
|
return jsonify({'code': 400, 'msg': '无效的审批操作'}), 400
|
||||||
if action == 'reject' and not reject_reason:
|
if action == 'reject' and not reject_reason:
|
||||||
return jsonify({'code': 400, 'msg': '驳回时必须提供原因'}), 400
|
return jsonify({'code': 400, 'msg': '驳回时必须提供原因'}), 400
|
||||||
|
|||||||
@ -58,9 +58,6 @@
|
|||||||
<el-button type="success" link size="small" @click="handleApprove(it)">通过</el-button>
|
<el-button type="success" link size="small" @click="handleApprove(it)">通过</el-button>
|
||||||
<el-button type="danger" link size="small" @click="openRejectDialog(it)">驳回</el-button>
|
<el-button type="danger" link size="small" @click="openRejectDialog(it)">驳回</el-button>
|
||||||
</template>
|
</template>
|
||||||
<template v-else-if="it.status === 1 && canClose">
|
|
||||||
<el-button type="danger" plain link size="small" @click="handleCloseRequest(it)">完结</el-button>
|
|
||||||
</template>
|
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
@ -119,6 +116,10 @@
|
|||||||
<el-button type="success" link size="small" :loading="batchLoading" @click="handleApproveBatch(row.batchKey)">审批本批</el-button>
|
<el-button type="success" link size="small" :loading="batchLoading" @click="handleApproveBatch(row.batchKey)">审批本批</el-button>
|
||||||
<el-button type="danger" link size="small" :loading="batchLoading" @click="openRejectBatchDialog(row.batchKey)">驳回本批</el-button>
|
<el-button type="danger" link size="small" :loading="batchLoading" @click="openRejectBatchDialog(row.batchKey)">驳回本批</el-button>
|
||||||
</template>
|
</template>
|
||||||
|
<!-- ★ 完结本批:批次内已通过的单,库管可直接完结(仿出库审批,主行可见) -->
|
||||||
|
<template v-if="batchHasClosable(row) && canClose">
|
||||||
|
<el-button type="danger" plain link size="small" :loading="batchLoading" @click="handleCloseBatch(row.batchKey)">完结本批</el-button>
|
||||||
|
</template>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
@ -485,6 +486,34 @@ const handleApproveBatch = async (batchKey: string) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ★ 批次内是否存在「已通过」的单(可完结)
|
||||||
|
const batchHasClosable = (row: any) => (row.items || []).some((it: any) => it.status === 1)
|
||||||
|
|
||||||
|
// ★ 完结本批:一键完结批次内所有「已通过」记录(仿出库审批)
|
||||||
|
const handleCloseBatch = async (batchKey: string) => {
|
||||||
|
const batch = list.value.find(b => b.batchKey === batchKey)
|
||||||
|
const closable = batch ? (batch.items || []).filter((it: any) => it.status === 1) : []
|
||||||
|
if (!closable.length) return ElMessage.warning('本批没有已通过记录可完结')
|
||||||
|
try {
|
||||||
|
await ElMessageBox.confirm(
|
||||||
|
`确定强制完结批次【${batchKey}】中 ${closable.length} 条已通过的记录吗?\n\n此操作不可恢复。`,
|
||||||
|
'⚠️ 完结本批确认',
|
||||||
|
{ confirmButtonText: '确认完结', cancelButtonText: '取消', type: 'warning' }
|
||||||
|
)
|
||||||
|
} catch { return }
|
||||||
|
|
||||||
|
batchLoading.value = true
|
||||||
|
try {
|
||||||
|
const res: any = await batchApprovePurchase({ batch_key: batchKey, action: 'close' })
|
||||||
|
ElMessage.success(res?.msg || '本批已完结')
|
||||||
|
await fetchData()
|
||||||
|
} catch (err: any) {
|
||||||
|
ElMessage.error(err?.msg || err?.message || '完结失败')
|
||||||
|
} finally {
|
||||||
|
batchLoading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ★ 驳回本批:批次内所有待审批记录统一驳回
|
// ★ 驳回本批:批次内所有待审批记录统一驳回
|
||||||
const rejectBatchKey = ref('')
|
const rejectBatchKey = ref('')
|
||||||
const rejectBatchDialogVisible = ref(false)
|
const rejectBatchDialogVisible = ref(false)
|
||||||
|
|||||||
Reference in New Issue
Block a user