优化审批功能

This commit is contained in:
hero920103 committed 2026-10-16 22:40:02 +08:00
1 parent 184d5b0403
commit 395c7f717e
15 files changed
+2997 -16

No files matched your search

+121
View File
@@ -985,6 +985,127 @@ func finishInstance(instID uint64, status int8) {
"finish_time": now,
"update_time": now,
})
SyncBizResult(instID, status)
}
// 报销单状态(与 yz_backend_reimbursements.status / 前端字典 oa_reimburse_status 一致)
const (
reimburseStatusApproved int8 = 2 // 已通过
reimburseStatusRejected int8 = 3 // 已驳回
reimburseStatusWithdrawn int8 = 4 // 已撤回
)
// BizTypeLegacyOA 早期报销单提交进审批引擎时写入的 biz_type(按模块 code 记录)。
// 与 ApprovalBizReimburse 一并识别,保证按老写法产生的在途/历史单据也能正常回写。
const BizTypeLegacyOA = "oa"
// IsReimburseBizType 判断审批实例是否属于 OA 报销单
func IsReimburseBizType(bizType string) bool {
switch strings.TrimSpace(bizType) {
case models.ApprovalBizReimburse, BizTypeLegacyOA:
return true
}
return false
}
// SyncBizResult 把审批实例的最终结果回写到对应业务单据,保证「审批中心」与业务列表状态一致。
//
// 目前覆盖 OA 报销单(biz_type=reimburse / 老写法 oa):按实例状态同步
// yz_backend_reimbursements.status,并补一条审批记录供业务详情页时间线展示。
// 撤回入口(不走 finishInstance)也会显式调用本函数,重复调用按最终态幂等。
func SyncBizResult(instID uint64, status int8) {
if instID == 0 {
return
}
var inst models.ApprovalInstance
if err := models.Orm.QueryTable(new(models.ApprovalInstance)).
Filter("id", instID).One(&inst); err != nil {
return
}
// 无业务单据ID的实例(纯手工审批)不回写任何业务表
if inst.BizID == 0 || !IsReimburseBizType(inst.BizType) {
return
}
syncReimburseResult(&inst, status)
}
// bizTenantID 业务单据所属租户:平台侧实例的 tid 恒为 0,来源租户记在 biz_tid。
func bizTenantID(inst *models.ApprovalInstance) uint64 {
if inst.Scope == models.ApprovalScopePlatform && inst.BizTid != 0 {
return inst.BizTid
}
return inst.Tid
}
// syncReimburseResult 回写报销单状态:审批通过/驳回/撤回分别对应业务状态 2/3/4。
func syncReimburseResult(inst *models.ApprovalInstance, status int8) {
var bizStatus, action int8
switch status {
case models.ApprovalInstanceApproved:
bizStatus, action = reimburseStatusApproved, models.ApprovalActionApprove
case models.ApprovalInstanceRejected:
bizStatus, action = reimburseStatusRejected, models.ApprovalActionReject
case models.ApprovalInstanceWithdrawn:
bizStatus, action = reimburseStatusWithdrawn, models.ApprovalActionWithdraw
default:
return
}
tid := bizTenantID(inst)
if tid == 0 {
return
}
var row models.BackendReimbursement
if err := models.Orm.QueryTable(new(models.BackendReimbursement)).
Filter("id", inst.BizID).Filter("tid", tid).
Filter("is_deleted", 0).One(&row); err != nil {
return
}
// 已是目标状态说明同步过,避免重复插入审批记录
if row.Status == bizStatus {
return
}
now := time.Now()
if _, err := models.Orm.QueryTable(new(models.BackendReimbursement)).
Filter("id", inst.BizID).Filter("tid", tid).
Update(orm.Params{"status": bizStatus, "update_time": now}); err != nil {
return
}
// 业务详情页的时间线读 yz_backend_approval_records,这里补记一条审批结果
actorID, actorName, comment := lastApprovalActor(inst)
_, _ = models.Orm.Insert(&models.BackendApprovalRecord{
Tid: tid, UID: approvalUint64Ptr(actorID), ReimbursementID: inst.BizID,
ApproverID: actorID, ApproverName: actorName, Action: action,
Comment: approvalStringPtr(comment),
})
}
// lastApprovalActor 取实例上最近一次通过/驳回的审批人(撤回等场景回退到发起人)。
func lastApprovalActor(inst *models.ApprovalInstance) (uint64, string, string) {
var task models.ApprovalTask
if err := models.Orm.QueryTable(new(models.ApprovalTask)).
Filter("instance_id", inst.ID).
Filter("status__in", models.ApprovalTaskApproved, models.ApprovalTaskRejected).
OrderBy("-finish_time", "-id").One(&task); err == nil {
return task.ApproverID, task.ApproverName, task.Comment
}
return inst.SubmitUserID, inst.SubmitUserName, ""
}
func approvalUint64Ptr(v uint64) *uint64 {
if v == 0 {
return nil
}
return &v
}
func approvalStringPtr(s string) *string {
if s == "" {
return nil
}
return &s
}
// ============================ 运行时:审批 ============================