ferry/apis/process/workOrder.go

576 lines
15 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package process
import (
"encoding/json"
"errors"
"ferry/global/orm"
"ferry/models/process"
"ferry/models/system"
"ferry/pkg/notify"
"ferry/pkg/service"
"ferry/tools"
"ferry/tools/app"
"fmt"
"strconv"
"time"
"github.com/gin-gonic/gin"
)
/*
@Author : lanyulei
*/
// 流程结构包括节点,流转和模版
func ProcessStructure(c *gin.Context) {
processId := c.DefaultQuery("processId", "")
if processId == "" {
app.Error(c, -1, errors.New("参数不正确请确定参数processId是否传递"), "")
return
}
workOrderId := c.DefaultQuery("workOrderId", "0")
if workOrderId == "" {
app.Error(c, -1, errors.New("参数不正确请确定参数workOrderId是否传递"), "")
return
}
workOrderIdInt, _ := strconv.Atoi(workOrderId)
processIdInt, _ := strconv.Atoi(processId)
result, err := service.ProcessStructure(c, processIdInt, workOrderIdInt)
if err != nil {
app.Error(c, -1, err, "")
return
}
if workOrderIdInt != 0 {
currentState := result["workOrder"].(service.WorkOrderData).CurrentState
userAuthority, err := service.JudgeUserAuthority(c, workOrderIdInt, currentState)
if err != nil {
app.Error(c, -1, err, fmt.Sprintf("判断用户是否有权限失败,%v", err.Error()))
return
}
result["userAuthority"] = userAuthority
}
app.OK(c, result, "数据获取成功")
}
// 新建工单
func CreateWorkOrder(c *gin.Context) {
err := service.CreateWorkOrder(c)
if err != nil {
app.Error(c, -1, err, "")
return
}
app.OK(c, "", "成功提交工单申请")
}
// 工单列表
func WorkOrderList(c *gin.Context) {
/*
1. 待办工单
2. 我创建的
3. 我相关的
4. 所有工单
*/
var (
result interface{}
err error
classifyInt int
)
classify := c.DefaultQuery("classify", "")
if classify == "" {
app.Error(c, -1, errors.New("参数错误请确认classify是否传递"), "")
return
}
classifyInt, _ = strconv.Atoi(classify)
w := service.WorkOrder{
Classify: classifyInt,
GinObj: c,
}
result, err = w.WorkOrderList()
if err != nil {
app.Error(c, -1, err, fmt.Sprintf("查询工单数据失败,%v", err.Error()))
return
}
app.OK(c, result, "")
}
// 处理工单
func ProcessWorkOrder(c *gin.Context) {
var (
err error
userAuthority bool
handle service.Handle
params struct {
Tasks []string
TargetState string `json:"target_state"` // 目标状态
SourceState string `json:"source_state"` // 源状态
WorkOrderId int `json:"work_order_id"` // 工单ID
Circulation string `json:"circulation"` // 流转ID
FlowProperties int `json:"flow_properties"` // 流转类型 0 拒绝1 同意2 其他
Remarks string `json:"remarks"` // 处理的备注信息
Tpls []map[string]interface{} `json:"tpls"` // 表单数据
IsExecTask bool `json:"is_exec_task"` // 是否执行任务
}
)
err = c.ShouldBind(&params)
if err != nil {
app.Error(c, -1, err, "")
return
}
// 处理工单
userAuthority, err = service.JudgeUserAuthority(c, params.WorkOrderId, params.SourceState)
if err != nil {
app.Error(c, -1, err, fmt.Sprintf("判断用户是否有权限失败,%v", err.Error()))
return
}
if !userAuthority {
app.Error(c, -1, errors.New("当前用户没有权限进行此操作"), "")
return
}
err = handle.HandleWorkOrder(
c,
params.WorkOrderId, // 工单ID
params.Tasks, // 任务列表
params.TargetState, // 目标节点
params.SourceState, // 源节点
params.Circulation, // 流转标题
params.FlowProperties, // 流转属性
params.Remarks, // 备注信息
params.Tpls, // 工单数据更新
params.IsExecTask, // 是否执行任务
)
if err != nil {
app.Error(c, -1, err, fmt.Sprintf("处理工单失败,%v", err.Error()))
return
}
app.OK(c, nil, "工单处理完成")
}
// 结束工单
func UnityWorkOrder(c *gin.Context) {
var (
err error
workOrderId string
workOrderInfo process.WorkOrderInfo
userInfo system.SysUser
)
workOrderId = c.DefaultQuery("work_oroder_id", "")
if workOrderId == "" {
app.Error(c, -1, errors.New("参数不正确work_oroder_id"), "")
return
}
tx := orm.Eloquent.Begin()
// 查询工单信息
err = tx.Model(&workOrderInfo).
Where("id = ?", workOrderId).
Find(&workOrderInfo).Error
if err != nil {
app.Error(c, -1, err, fmt.Sprintf("查询工单失败,%v", err.Error()))
return
}
if workOrderInfo.IsEnd == 1 {
app.Error(c, -1, errors.New("工单已结束"), "")
return
}
// 更新工单状态
err = tx.Model(&process.WorkOrderInfo{}).
Where("id = ?", workOrderId).
Update("is_end", 1).
Error
if err != nil {
tx.Rollback()
app.Error(c, -1, err, fmt.Sprintf("结束工单失败,%v", err.Error()))
return
}
// 获取当前用户信息
err = tx.Model(&userInfo).
Where("user_id = ?", tools.GetUserId(c)).
Find(&userInfo).Error
if err != nil {
tx.Rollback()
app.Error(c, -1, err, fmt.Sprintf("当前用户查询失败,%v", err.Error()))
return
}
// 写入历史
tx.Create(&process.CirculationHistory{
Title: workOrderInfo.Title,
WorkOrder: workOrderInfo.Id,
State: "结束工单",
Circulation: "结束",
Processor: userInfo.NickName,
ProcessorId: tools.GetUserId(c),
Remarks: "手动结束工单。",
Status: 2,
})
tx.Commit()
app.OK(c, nil, "工单已结束")
}
// 转交工单
func InversionWorkOrder(c *gin.Context) {
var (
cirHistoryValue []process.CirculationHistory
err error
workOrderInfo process.WorkOrderInfo
stateList []map[string]interface{}
stateValue []byte
currentState map[string]interface{}
userInfo system.SysUser
currentUserInfo system.SysUser
costDurationValue int64
params struct {
WorkOrderId int `json:"work_order_id"`
NodeId string `json:"node_id"`
UserId int `json:"user_id"`
Remarks string `json:"remarks"`
}
)
// 获取当前用户信息
err = orm.Eloquent.Model(&currentUserInfo).
Where("user_id = ?", tools.GetUserId(c)).
Find(&currentUserInfo).Error
if err != nil {
app.Error(c, -1, err, fmt.Sprintf("当前用户查询失败,%v", err.Error()))
return
}
err = c.ShouldBind(&params)
if err != nil {
app.Error(c, -1, err, "")
return
}
// 查询工单信息
err = orm.Eloquent.Model(&workOrderInfo).
Where("id = ?", params.WorkOrderId).
Find(&workOrderInfo).Error
if err != nil {
app.Error(c, -1, err, fmt.Sprintf("查询工单信息失败,%v", err.Error()))
return
}
// 序列化节点数据
err = json.Unmarshal(workOrderInfo.State, &stateList)
if err != nil {
app.Error(c, -1, err, fmt.Sprintf("节点数据反序列化失败,%v", err.Error()))
return
}
for _, s := range stateList {
if s["id"].(string) == params.NodeId {
s["processor"] = []interface{}{params.UserId}
s["process_method"] = "person"
currentState = s
break
}
}
stateValue, err = json.Marshal(stateList)
if err != nil {
app.Error(c, -1, err, fmt.Sprintf("节点数据序列化失败,%v", err.Error()))
return
}
tx := orm.Eloquent.Begin()
// 更新数据
err = tx.Model(&process.WorkOrderInfo{}).
Where("id = ?", params.WorkOrderId).
Update("state", stateValue).Error
if err != nil {
app.Error(c, -1, err, fmt.Sprintf("更新节点信息失败,%v", err.Error()))
return
}
// 查询用户信息
err = tx.Model(&system.SysUser{}).
Where("user_id = ?", params.UserId).
Find(&userInfo).Error
if err != nil {
app.Error(c, -1, err, fmt.Sprintf("查询用户信息失败,%v", err.Error()))
return
}
// 流转历史写入
err = orm.Eloquent.Model(&cirHistoryValue).
Where("work_order = ?", params.WorkOrderId).
Find(&cirHistoryValue).
Order("create_time desc").Error
if err != nil {
tx.Rollback()
return
}
for _, t := range cirHistoryValue {
if t.Source != currentState["id"].(string) {
costDuration := time.Since(t.CreatedAt.Time)
costDurationValue = int64(costDuration) / 1000 / 1000 / 1000
}
}
// 添加转交历史
tx.Create(&process.CirculationHistory{
Title: workOrderInfo.Title,
WorkOrder: workOrderInfo.Id,
State: currentState["label"].(string),
Circulation: "转交",
Processor: currentUserInfo.NickName,
ProcessorId: tools.GetUserId(c),
Remarks: fmt.Sprintf("此阶段负责人已转交给《%v》", userInfo.NickName),
Status: 2, // 其他
CostDuration: costDurationValue,
})
tx.Commit()
app.OK(c, nil, "工单已手动结单")
}
// 催办工单
func UrgeWorkOrder(c *gin.Context) {
var (
workOrderInfo process.WorkOrderInfo
sendToUserList []system.SysUser
stateList []interface{}
userInfo system.SysUser
)
workOrderId := c.DefaultQuery("workOrderId", "")
if workOrderId == "" {
app.Error(c, -1, errors.New("参数不正确缺失workOrderId"), "")
return
}
// 查询工单数据
err := orm.Eloquent.Model(&process.WorkOrderInfo{}).Where("id = ?", workOrderId).Find(&workOrderInfo).Error
if err != nil {
app.Error(c, -1, err, fmt.Sprintf("查询工单信息失败,%v", err.Error()))
return
}
// 确认是否可以催办
if workOrderInfo.UrgeLastTime != 0 && (int(time.Now().Unix())-workOrderInfo.UrgeLastTime) < 600 {
app.Error(c, -1, errors.New("十分钟内无法多次催办工单。"), "")
return
}
// 获取当前工单处理人信息
err = json.Unmarshal(workOrderInfo.State, &stateList)
if err != nil {
app.Error(c, -1, err, "")
return
}
sendToUserList, err = service.GetPrincipalUserInfo(stateList, workOrderInfo.Creator)
// 查询创建人信息
err = orm.Eloquent.Model(&system.SysUser{}).Where("user_id = ?", workOrderInfo.Creator).Find(&userInfo).Error
if err != nil {
app.Error(c, -1, err, fmt.Sprintf("创建人信息查询失败,%v", err.Error()))
return
}
// 发送催办提醒
bodyData := notify.BodyData{
SendTo: map[string]interface{}{
"userList": sendToUserList,
},
Subject: "您被催办工单了,请及时处理。",
Description: "您有一条待办工单,请及时处理,工单描述如下",
Classify: []int{1}, // todo 1 表示邮箱,后续添加了其他的在重新补充
ProcessId: workOrderInfo.Process,
Id: workOrderInfo.Id,
Title: workOrderInfo.Title,
Creator: userInfo.NickName,
Priority: workOrderInfo.Priority,
CreatedAt: workOrderInfo.CreatedAt.Format("2006-01-02 15:04:05"),
}
err = bodyData.SendNotify()
if err != nil {
app.Error(c, -1, err, fmt.Sprintf("催办提醒发送失败,%v", err.Error()))
return
}
// 更新数据库
err = orm.Eloquent.Model(&process.WorkOrderInfo{}).Where("id = ?", workOrderInfo.Id).Updates(map[string]interface{}{
"urge_count": workOrderInfo.UrgeCount + 1,
"urge_last_time": int(time.Now().Unix()),
}).Error
if err != nil {
app.Error(c, -1, err, fmt.Sprintf("更新催办信息失败,%v", err.Error()))
return
}
app.OK(c, "", "")
}
// 主动处理
func ActiveOrder(c *gin.Context) {
var (
workOrderId string
err error
stateValue []struct {
ID string `json:"id"`
Label string `json:"label"`
ProcessMethod string `json:"process_method"`
Processor []int `json:"processor"`
}
stateValueByte []byte
)
workOrderId = c.Param("id")
err = c.ShouldBind(&stateValue)
if err != nil {
app.Error(c, -1, err, "")
return
}
stateValueByte, err = json.Marshal(stateValue)
if err != nil {
app.Error(c, -1, fmt.Errorf("转byte失败%v", err.Error()), "")
return
}
err = orm.Eloquent.Model(&process.WorkOrderInfo{}).
Where("id = ?", workOrderId).
Update("state", stateValueByte).Error
if err != nil {
app.Error(c, -1, fmt.Errorf("接单失败,%v", err.Error()), "")
return
}
app.OK(c, "", "接单成功,请及时处理")
}
// 删除工单
func DeleteWorkOrder(c *gin.Context) {
workOrderId := c.Param("id")
err := orm.Eloquent.Delete(&process.WorkOrderInfo{}, workOrderId).Error
if err != nil {
app.Error(c, -1, err, "")
return
}
app.OK(c, "", "工单已删除")
}
// 重开工单
func ReopenWorkOrder(c *gin.Context) {
var (
err error
id string
workOrder process.WorkOrderInfo
processInfo process.Info
structure map[string]interface{}
startId string
label string
jsonState []byte
relatedPerson []byte
newWorkOrder process.WorkOrderInfo
workOrderData []*process.TplData
)
id = c.Param("id")
// 查询当前ID的工单信息
err = orm.Eloquent.Find(&workOrder, id).Error
if err != nil {
app.Error(c, -1, err, fmt.Sprintf("查询工单信息失败, %s", err.Error()))
return
}
// 创建新的工单
err = orm.Eloquent.Find(&processInfo, workOrder.Process).Error
if err != nil {
app.Error(c, -1, err, fmt.Sprintf("查询流程信息失败, %s", err.Error()))
return
}
err = json.Unmarshal(processInfo.Structure, &structure)
if err != nil {
app.Error(c, -1, err, fmt.Sprintf("Json序列化失败, %s", err.Error()))
return
}
for _, node := range structure["nodes"].([]interface{}) {
if node.(map[string]interface{})["clazz"] == "start" {
startId = node.(map[string]interface{})["id"].(string)
label = node.(map[string]interface{})["label"].(string)
}
}
state := []map[string]interface{}{
{"id": startId, "label": label, "processor": []int{tools.GetUserId(c)}, "process_method": "person"},
}
jsonState, err = json.Marshal(state)
if err != nil {
app.Error(c, -1, err, fmt.Sprintf("Json序列化失败, %s", err.Error()))
return
}
relatedPerson, err = json.Marshal([]int{tools.GetUserId(c)})
if err != nil {
app.Error(c, -1, err, fmt.Sprintf("Json序列化失败, %s", err.Error()))
return
}
tx := orm.Eloquent.Begin()
newWorkOrder = process.WorkOrderInfo{
Title: workOrder.Title,
Priority: workOrder.Priority,
Process: workOrder.Process,
Classify: workOrder.Classify,
State: jsonState,
RelatedPerson: relatedPerson,
Creator: tools.GetUserId(c),
}
err = tx.Create(&newWorkOrder).Error
if err != nil {
tx.Rollback()
app.Error(c, -1, err, fmt.Sprintf("新建工单失败, %s", err.Error()))
return
}
// 查询工单数据
err = orm.Eloquent.Model(&process.TplData{}).Where("work_order = ?", id).Find(&workOrderData).Error
if err != nil {
tx.Rollback()
app.Error(c, -1, err, fmt.Sprintf("查询工单数据失败, %s", err.Error()))
return
}
for _, d := range workOrderData {
d.WorkOrder = newWorkOrder.Id
d.Id = 0
err = tx.Create(d).Error
if err != nil {
tx.Rollback()
app.Error(c, -1, err, fmt.Sprintf("创建工单数据失败, %s", err.Error()))
return
}
}
tx.Commit()
app.OK(c, nil, "")
}