优化审批流

This commit is contained in:
hero920103 committed 2026-10-07 22:56:35 +08:00
1 parent ffaadc26ae
commit 438145cae7
17 files changed
+1131 -187

No files matched your search

+90 -37
View File
@@ -10,6 +10,7 @@ import (
"server/models"
"server/services"
approvalEngine "server/services/approval"
"github.com/beego/beego/v2/client/orm"
beego "github.com/beego/beego/v2/server/web"
@@ -62,16 +63,17 @@ func (c *BackendApprovalController) FlowList() {
cnt, _ := models.Orm.QueryTable(new(models.TenantApprovalNode)).
Filter("flow_id", r.ID).Filter("is_deleted", 0).Count()
list = append(list, approvalFlowView{
ID: r.ID,
ModuleCode: r.ModuleCode,
BizType: r.BizType,
FlowCode: r.FlowCode,
FlowName: r.FlowName,
Description: r.Description,
IsDefault: r.IsDefault,
Status: r.Status,
NodeCount: int(cnt),
CreateTime: r.CreateTime.Format("2006-01-02 15:04:05"),
ID: r.ID,
ModuleCode: r.ModuleCode,
BizType: r.BizType,
FlowCode: r.FlowCode,
FlowName: r.FlowName,
Description: r.Description,
IsDefault: r.IsDefault,
Status: r.Status,
NodeCount: int(cnt),
CreateTime: r.CreateTime.Format("2006-01-02 15:04:05"),
ApplyDeptIDs: parseIDSlice(r.ApplyDeptIDs),
})
}
c.Data["json"] = map[string]interface{}{"code": 200, "msg": "ok", "data": list}
@@ -105,17 +107,18 @@ func tenantFlowToView(f models.TenantApprovalFlow) approvalFlowView {
Filter("flow_id", f.ID).Filter("is_deleted", 0).
OrderBy("sort", "id").All(&nodes)
view := approvalFlowView{
ID: f.ID,
ModuleCode: f.ModuleCode,
BizType: f.BizType,
FlowCode: f.FlowCode,
FlowName: f.FlowName,
Description: f.Description,
IsDefault: f.IsDefault,
Status: f.Status,
NodeCount: len(nodes),
CreateTime: f.CreateTime.Format("2006-01-02 15:04:05"),
Nodes: make([]approvalNodePayload, 0, len(nodes)),
ID: f.ID,
ModuleCode: f.ModuleCode,
BizType: f.BizType,
FlowCode: f.FlowCode,
FlowName: f.FlowName,
Description: f.Description,
IsDefault: f.IsDefault,
Status: f.Status,
NodeCount: len(nodes),
CreateTime: f.CreateTime.Format("2006-01-02 15:04:05"),
ApplyDeptIDs: parseIDSlice(f.ApplyDeptIDs),
Nodes: make([]approvalNodePayload, 0, len(nodes)),
}
edgeNodes := make([]flowEdgeNode, 0, len(nodes))
for _, n := range nodes {
@@ -176,6 +179,18 @@ func (c *BackendApprovalController) FlowSave() {
g := buildGraph(p.Nodes, p.Edges)
now := time.Now()
// 适用部门写入前校验:需全部属于当前租户(空列表=全公司通用,直接放行)
if len(p.ApplyDeptIDs) > 0 {
count, _ := models.Orm.QueryTable(new(models.BackendOrganization)).
Filter("tid", tid).Filter("id__in", p.ApplyDeptIDs).Filter("delete_time__isnull", true).
Count()
if int(count) != len(p.ApplyDeptIDs) {
jsonErr(&c.Controller, 400, 400, "适用部门包含非本租户组织,请重新选择")
return
}
}
applyDeptCSV := joinIDs(p.ApplyDeptIDs)
o := models.Orm
var flowID uint64
var flowCode string
@@ -190,13 +205,14 @@ func (c *BackendApprovalController) FlowSave() {
flowCode = exist.FlowCode
_, err := o.QueryTable(new(models.TenantApprovalFlow)).
Filter("id", flowID).Filter("tid", tid).Update(orm.Params{
"module_code": p.ModuleCode,
"biz_type": p.BizType,
"flow_name": p.FlowName,
"description": p.Description,
"is_default": p.IsDefault,
"status": p.Status,
"update_time": now,
"module_code": p.ModuleCode,
"biz_type": p.BizType,
"flow_name": p.FlowName,
"description": p.Description,
"is_default": p.IsDefault,
"status": p.Status,
"apply_dept_ids": applyDeptCSV,
"update_time": now,
})
if err != nil {
jsonErr(&c.Controller, 500, 500, "保存失败: "+err.Error())
@@ -204,14 +220,15 @@ func (c *BackendApprovalController) FlowSave() {
}
} else {
row := models.TenantApprovalFlow{
Tid: tid,
ModuleCode: p.ModuleCode,
BizType: p.BizType,
FlowName: p.FlowName,
Description: p.Description,
IsDefault: p.IsDefault,
Status: p.Status,
CreateTime: now,
Tid: tid,
ModuleCode: p.ModuleCode,
BizType: p.BizType,
FlowName: p.FlowName,
Description: p.Description,
IsDefault: p.IsDefault,
Status: p.Status,
ApplyDeptIDs: applyDeptCSV,
CreateTime: now,
}
id, err := o.Insert(&row)
if err != nil {
@@ -305,6 +322,7 @@ func (c *BackendApprovalController) Pick() {
list := make([]map[string]interface{}, 0, len(rows))
for _, r := range rows {
list = append(list, map[string]interface{}{
"id": r.ID,
"module_code": r.ModuleCode,
"flow_code": r.FlowCode,
"flow_name": r.FlowName,
@@ -404,7 +422,10 @@ func (c *BackendApprovalController) Options() {
OrderBy("sort", "id").All(&og)
orgList := make([]map[string]interface{}, 0, len(og))
for _, o := range og {
orgList = append(orgList, map[string]interface{}{"id": o.ID, "name": o.OrgName})
orgList = append(orgList, map[string]interface{}{
"id": o.ID, "name": o.OrgName,
"parent_id": o.ParentID, "is_company": o.IsCompany,
})
}
var ps []models.BackendPosition
@@ -429,6 +450,38 @@ func (c *BackendApprovalController) Options() {
_ = c.ServeJSON()
}
// AvailableFlows GET /backend/approval/flow/available?biz_type=reimburse
// 业务侧“发起前拉可用流”:基于当前登录用户的部门,过滤启用的流程。
// 前端基于返回结果判定:空则提示配置;一条自动带入;多条下拉选。
func (c *BackendApprovalController) AvailableFlows() {
claims, err := requireBackend(&c.Controller)
if err != nil {
jsonErr(&c.Controller, 401, 401, err.Error())
return
}
tid := uint64(claims.TenantId)
bizType := strings.TrimSpace(c.GetString("biz_type"))
if bizType == "" {
jsonErr(&c.Controller, 400, 400, "缺少 biz_type 参数")
return
}
// 取当前登录用户的部门(未分配时 OrgID=0,仅命中“全公司通用”流)
var tu models.SystemTenantUser
var userOrgID uint64
if e := models.Orm.QueryTable(new(models.SystemTenantUser)).
Filter("tid", tid).Filter("uid", claims.UserID).Filter("delete_time__isnull", true).
One(&tu); e == nil {
userOrgID = tu.OrgID
}
list, err := approvalEngine.ListAvailableFlows(models.ApprovalScopeTenant, tid, bizType, userOrgID)
if err != nil {
jsonErr(&c.Controller, 500, 500, "查询失败: "+err.Error())
return
}
c.Data["json"] = map[string]interface{}{"code": 200, "msg": "ok", "data": list}
_ = c.ServeJSON()
}
// ============================ 辅助函数 ============================
// firstNonEmptyStr 取字符串指针/普通字符串中第一个非空值