package report_approve

import (
	"encoding/json"
	"eta/eta_mobile/controllers"
	"eta/eta_mobile/models"
	"eta/eta_mobile/models/report_approve"
	"eta/eta_mobile/services"
	"eta/eta_mobile/utils"
	"fmt"
	"github.com/rdlucklib/rdluck_tools/paging"
	"strings"
	"sync"
	"time"
)

// ReportApproveFlowController 报告审批流
type ReportApproveFlowController struct {
	controllers.BaseAuthController
}

// List
// @Title 报告列表
// @Description 报告列表
// @Param   PageSize			query	int		true	"每页数据条数"
// @Param   CurrentIndex		query	int		true	"当前页页码"
// @Param   ReportType			query   int     false	"报告类型：1-中文研报；2-英文研报；3-智能研报"
// @Param   ClassifyIdFirst		query	int		false	"一级分类ID"
// @Param   ClassifyIdSecond	query	int		false	"二级分类ID"
// @Param   Keyword				query	string	false	"搜索关键词"
// @Param   SortRule			query	int		false	"排序方式: 1-正序; 2-倒序(默认)"
// @Success 200 {object} report_approve.ReportApproveFlowListResp
// @router /flow/list [get]
func (this *ReportApproveFlowController) List() {
	br := new(models.BaseResponse).Init()
	defer func() {
		if br.ErrMsg == "" {
			br.IsSendEmail = false
		}
		this.Data["json"] = br
		this.ServeJSON()
	}()
	sysUser := this.SysUser
	if sysUser == nil {
		br.Msg = "请登录"
		br.ErrMsg = "请登录，SysUser Is Empty"
		br.Ret = 408
		return
	}
	params := new(report_approve.ReportApproveFlowListReq)
	if e := this.ParseForm(params); e != nil {
		br.Msg = "获取失败"
		br.ErrMsg = "入参解析失败, Err: " + e.Error()
		return
	}

	var cond, orderRule string
	var pars []interface{}
	cond += fmt.Sprintf(` AND %s = ? `, report_approve.ReportApproveFlowCols.Enabled)
	pars = append(pars, 1)
	// 筛选项
	{
		keyword := strings.TrimSpace(params.Keyword)
		if keyword != "" {
			kw := fmt.Sprint("%", keyword, "%")
			cond += fmt.Sprintf(` AND %s LIKE ?`, report_approve.ReportApproveFlowCols.FlowName)
			pars = append(pars, kw)
		}
		if params.ReportType > 0 && params.ClassifySecondId > 0 {
			cond += fmt.Sprintf(` AND %s = ? AND %s = ?`, report_approve.ReportApproveFlowCols.ReportType, report_approve.ReportApproveFlowCols.ClassifySecondId)
			pars = append(pars, params.ReportType, params.ClassifySecondId)
		}
		if params.ClassifyThirdId > 0 {
			cond += fmt.Sprintf(` AND %s = ? `, report_approve.ReportApproveFlowCols.ClassifyThirdId)
			pars = append(pars, params.ReportType, params.ClassifyThirdId)
		}
		if params.SortRule > 0 {
			orderMap := map[int]string{1: "ASC", 2: "DESC"}
			orderRule = fmt.Sprintf("%s %s", report_approve.ReportApproveFlowCols.CreateTime, orderMap[params.SortRule])
		}
	}

	resp := new(report_approve.ReportApproveFlowListResp)
	flowOb := new(report_approve.ReportApproveFlow)
	total, e := flowOb.GetCountByCondition(cond, pars)
	if e != nil {
		br.Msg = "获取失败"
		br.ErrMsg = "获取审批流总数失败, Err:" + e.Error()
		return
	}
	if total <= 0 {
		page := paging.GetPaging(params.CurrentIndex, params.PageSize, total)
		resp.Paging = page
		br.Ret = 200
		br.Success = true
		br.Msg = "获取成功"
		br.Data = resp
		return
	}

	// 分页列表
	var startSize int
	if params.PageSize <= 0 {
		params.PageSize = utils.PageSize20
	}
	if params.CurrentIndex <= 0 {
		params.CurrentIndex = 1
	}
	startSize = utils.StartIndex(params.CurrentIndex, params.PageSize)

	list, e := flowOb.GetPageItemsByCondition(cond, pars, []string{}, orderRule, startSize, params.PageSize)
	if e != nil {
		br.Msg = "获取失败"
		br.ErrMsg = "获取审批流分页列表失败, Err:" + e.Error()
		return
	}

	// 指标分类
	cnClassifyIdName, enClassifyIdName := make(map[int]string), make(map[int]string)
	cnClassify, e := models.GetAllClassify()
	if e != nil {
		br.Msg = "获取失败"
		br.ErrMsg = "获取中文分类失败, Err: " + e.Error()
		return
	}
	for _, v := range cnClassify {
		cnClassifyIdName[v.Id] = v.ClassifyName
	}
	enClassify, e := models.GetEnglishClassifies()
	if e != nil {
		br.Msg = "获取失败"
		br.ErrMsg = "获取英文分类失败, Err: " + e.Error()
		return
	}
	enRootIdMap := make(map[int]int) // 英文分类的一级分类ID
	for _, v := range enClassify {
		enClassifyIdName[v.Id] = v.ClassifyName
		enRootIdMap[v.Id] = v.RootId
	}

	for _, v := range list {
		t := report_approve.FormatReportApproveFlow2Item(v)
		if v.ReportType == report_approve.FlowReportTypeEnglish {
			t.ReportClassify = fmt.Sprintf("%s/%s/%s/%s", report_approve.FlowReportTypeMap[v.ReportType], enClassifyIdName[enRootIdMap[v.ClassifySecondId]], enClassifyIdName[v.ClassifyFirstId], enClassifyIdName[v.ClassifySecondId])
		} else {
			reportClassify := fmt.Sprintf("%s/%s", report_approve.FlowReportTypeMap[v.ReportType], cnClassifyIdName[v.ClassifyFirstId])
			if v.ClassifySecondId > 0 {
				reportClassify = fmt.Sprintf("%s/%s", reportClassify, cnClassifyIdName[v.ClassifySecondId])
			}
			if v.ClassifyThirdId > 0 {
				reportClassify = fmt.Sprintf("%s/%s", reportClassify, cnClassifyIdName[v.ClassifyThirdId])
			}
			t.ReportClassify = reportClassify
		}
		resp.List = append(resp.List, t)
	}

	page := paging.GetPaging(params.CurrentIndex, params.PageSize, total)
	resp.Paging = page
	br.Ret = 200
	br.Success = true
	br.Msg = "获取成功"
	br.Data = resp
}

// Add
// @Title 新增审批流
// @Description 新增审批流
// @Param	request	body report_approve.ReportApproveFlowAddReq true "type json string"
// @Success 200 {object} report_approve.ReportApproveFlowDetailItem
// @router /flow/add [post]
func (this *ReportApproveFlowController) Add() {
	br := new(models.BaseResponse).Init()
	defer func() {
		if br.ErrMsg == "" {
			br.IsSendEmail = false
		}
		this.Data["json"] = br
		this.ServeJSON()
	}()
	sysUser := this.SysUser
	if sysUser == nil {
		br.Msg = "请登录"
		br.ErrMsg = "请登录，SysUser Is Empty"
		br.Ret = 408
		return
	}
	var req report_approve.ReportApproveFlowAddReq
	if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
		br.Msg = "参数有误"
		br.ErrMsg = "参数解析失败, Err: " + e.Error()
		return
	}
	req.FlowName = strings.TrimSpace(req.FlowName)
	if req.FlowName == "" {
		br.Msg = "请输入审批流名称"
		return
	}
	if len([]rune(req.FlowName)) > 20 {
		br.Msg = "审批流名称最多输入20个字符"
		return
	}
	reportTypes := []int{report_approve.FlowReportTypeChinese, report_approve.FlowReportTypeEnglish, report_approve.FlowReportTypeSmart}
	if !utils.InArrayByInt(reportTypes, req.ReportType) {
		br.Msg = "审批流报告类型有误"
		br.ErrMsg = fmt.Sprintf("审批流报告类型有误, ReportType: %d", req.ReportType)
		return
	}
	if req.ClassifyFirstId <= 0 && req.ClassifySecondId <= 0 && req.ClassifyThirdId <= 0 {
		br.Msg = "请选择报告分类"
		return
	}
	if len(req.Nodes) <= 0 {
		br.Msg = "请添加审批流程"
		return
	}
	approveTypes := []int{report_approve.NodeApproveTypeRoll, report_approve.NodeApproveTypeAll, report_approve.NodeApproveTypeAny}
	approveUserTypes := []string{report_approve.NodeUserTypeNormal, report_approve.NodeUserTypeRole}
	for _, v := range req.Nodes {
		if !utils.InArrayByInt(approveTypes, v.ApproveType) {
			br.Msg = "审批流类型有误"
			br.ErrMsg = fmt.Sprintf("审批流类型有误, ApproveType: %d", v.ApproveType)
			return
		}
		for _, v2 := range v.Users {
			if !utils.InArrayByStr(approveUserTypes, v2.UserType) {
				br.Msg = "审批流用户类型有误"
				br.ErrMsg = fmt.Sprintf("审批流用户类型有误, UserType: %d", v2.UserType)
				return
			}
		}
	}

	// 审批流是否已存在
	{
		flowOb := new(report_approve.ReportApproveFlow)
		existCond := fmt.Sprintf(` AND %s = ? AND %s = ? AND %s = ? AND %s = ?`, report_approve.ReportApproveFlowCols.ReportType, report_approve.ReportApproveFlowCols.ClassifyFirstId, report_approve.ReportApproveFlowCols.ClassifySecondId, report_approve.ReportApproveFlowCols.ClassifyThirdId)
		existPars := make([]interface{}, 0)
		existPars = append(existPars, req.ReportType, req.ClassifyFirstId, req.ClassifySecondId, req.ClassifyThirdId)
		exist, e := flowOb.GetItemByCondition(existCond, existPars, "")
		if e != nil && e.Error() != utils.ErrNoRow() {
			br.Msg = "获取失败"
			br.ErrMsg = "获取审批流是否已存在失败, Err: " + e.Error()
			return
		}
		if exist != nil {
			br.Msg = "该分类已有审批流, 请勿重复添加"
			return
		}
	}

	flowItem := new(report_approve.ReportApproveFlow)
	flowItem.FlowName = req.FlowName
	flowItem.ReportType = req.ReportType
	flowItem.ClassifyFirstId = req.ClassifyFirstId
	flowItem.ClassifySecondId = req.ClassifySecondId
	flowItem.ClassifyThirdId = req.ClassifyThirdId
	flowItem.CurrVersion = 1
	flowItem.Enabled = 1
	flowItem.CreateTime = time.Now().Local()
	flowItem.ModifyTime = time.Now().Local()

	nodeItems := make([]*report_approve.ReportApproveNode, 0)
	for _, v := range req.Nodes {
		n := new(report_approve.ReportApproveNode)
		n.ApproveType = v.ApproveType
		n.CurrVersion = flowItem.CurrVersion
		j, _ := json.Marshal(v.Users)
		n.Users = string(j)
		n.CreateTime = time.Now().Local()
		nodeItems = append(nodeItems, n)
	}

	// 新增审批流和节点
	if e := flowItem.CreateFlowAndNodes(flowItem, nodeItems); e != nil {
		br.Msg = "操作失败"
		br.ErrMsg = "新增审批流和节点失败, Err: " + e.Error()
		return
	}

	// 返回详情
	detail, e := report_approve.FormatFlowAndNodesItem2Detail(flowItem, nodeItems)
	if e != nil {
		br.Msg = "获取失败"
		br.ErrMsg = "获取审批详情失败, Err: " + e.Error()
		return
	}

	// 更新审批对应的报告状态：未发布->待提交
	go func() {
		_ = services.FlowOperateResetReportState(flowItem.ReportType, flowItem.ClassifyFirstId, flowItem.ClassifySecondId, flowItem.ClassifyThirdId, models.ReportStateUnpublished, models.ReportStateWaitSubmit)
	}()

	br.Data = detail
	br.Ret = 200
	br.Success = true
	br.Msg = "操作成功"
}

// Edit
// @Title 编辑审批流
// @Description 编辑审批流
// @Param	request	body report_approve.ReportApproveFlowEditReq true "type json string"
// @Success 200 {object} report_approve.ReportApproveFlowDetailItem
// @router /flow/edit [post]
func (this *ReportApproveFlowController) Edit() {
	br := new(models.BaseResponse).Init()
	defer func() {
		if br.ErrMsg == "" {
			br.IsSendEmail = false
		}
		this.Data["json"] = br
		this.ServeJSON()
	}()
	sysUser := this.SysUser
	if sysUser == nil {
		br.Msg = "请登录"
		br.ErrMsg = "请登录，SysUser Is Empty"
		br.Ret = 408
		return
	}
	var req report_approve.ReportApproveFlowEditReq
	if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
		br.Msg = "参数有误"
		br.ErrMsg = "参数解析失败, Err: " + e.Error()
		return
	}
	if req.ReportApproveFlowId <= 0 {
		br.Msg = "参数有误"
		br.ErrMsg = fmt.Sprintf("参数有误, ReportApproveFlowId: %d", req.ReportApproveFlowId)
		return
	}
	req.FlowName = strings.TrimSpace(req.FlowName)
	if req.FlowName == "" {
		br.Msg = "请输入审批流名称"
		return
	}
	if len([]rune(req.FlowName)) > 20 {
		br.Msg = "审批流名称最多输入20个字符"
		return
	}
	reportTypes := []int{report_approve.FlowReportTypeChinese, report_approve.FlowReportTypeEnglish, report_approve.FlowReportTypeSmart}
	if !utils.InArrayByInt(reportTypes, req.ReportType) {
		br.Msg = "审批流报告类型有误"
		br.ErrMsg = fmt.Sprintf("审批流报告类型有误, ReportType: %d", req.ReportType)
		return
	}
	if req.ClassifyFirstId <= 0 && req.ClassifySecondId <= 0 && req.ClassifyThirdId <= 0 {
		br.Msg = "请选择报告分类"
		return
	}
	if len(req.Nodes) <= 0 {
		br.Msg = "请添加审批流程"
		return
	}
	approveTypes := []int{report_approve.NodeApproveTypeRoll, report_approve.NodeApproveTypeAll, report_approve.NodeApproveTypeAny}
	approveUserTypes := []string{report_approve.NodeUserTypeNormal, report_approve.NodeUserTypeRole}
	for _, v := range req.Nodes {
		if !utils.InArrayByInt(approveTypes, v.ApproveType) {
			br.Msg = "审批流类型有误"
			br.ErrMsg = fmt.Sprintf("审批流类型有误, ApproveType: %d", v.ApproveType)
			return
		}
		for _, v2 := range v.Users {
			if !utils.InArrayByStr(approveUserTypes, v2.UserType) {
				br.Msg = "审批流用户类型有误"
				br.ErrMsg = fmt.Sprintf("审批流用户类型有误, UserType: %d", v2.UserType)
				return
			}
		}
	}

	flowOb := new(report_approve.ReportApproveFlow)
	flowItem, e := flowOb.GetItemById(req.ReportApproveFlowId)
	if e != nil {
		if e.Error() == utils.ErrNoRow() {
			br.Msg = "审批流已被删除, 请刷新页面"
			return
		}
		br.Msg = "操作失败"
		br.ErrMsg = "获取审批流信息失败, Err: " + e.Error()
		return
	}

	// 审批流是否已存在
	{
		existCond := fmt.Sprintf(` AND %s = ? AND %s = ? AND %s = ?  AND %s = ? AND %s <> ?`, report_approve.ReportApproveFlowCols.ReportType, report_approve.ReportApproveFlowCols.ClassifyFirstId, report_approve.ReportApproveFlowCols.ClassifySecondId, report_approve.ReportApproveFlowCols.ClassifyThirdId, report_approve.ReportApproveFlowCols.ReportApproveFlowId)
		existPars := make([]interface{}, 0)
		existPars = append(existPars, req.ReportType, req.ClassifyFirstId, req.ClassifySecondId, req.ClassifyThirdId, req.ReportApproveFlowId)
		exist, e := flowOb.GetItemByCondition(existCond, existPars, "")
		if e != nil && e.Error() != utils.ErrNoRow() {
			br.Msg = "操作失败"
			br.ErrMsg = "获取审批流是否已存在失败, Err: " + e.Error()
			return
		}
		if exist != nil {
			br.Msg = "该分类已有审批流, 请勿重复添加"
			return
		}
	}

	// 校验审批流是否关联了进行中的审批
	{
		approvingOb := new(report_approve.ReportApprove)
		approvingCond := fmt.Sprintf(` AND %s = ? AND %s = ? AND %s = ?`, report_approve.ReportApproveCols.FlowId, report_approve.ReportApproveCols.FlowVersion, report_approve.ReportApproveCols.State)
		approvingPars := make([]interface{}, 0)
		approvingPars = append(approvingPars, flowItem.ReportApproveFlowId, flowItem.CurrVersion, report_approve.ReportApproveStateApproving)
		count, e := approvingOb.GetCountByCondition(approvingCond, approvingPars)
		if e != nil {
			br.Msg = "操作失败"
			br.ErrMsg = "获取审批流关联进行中的审批数失败. Err: " + e.Error()
			return
		}
		if count > 0 {
			br.Msg = "当前有未走完流程的报告，请走完流程后再做变更"
			return
		}
	}

	// 变更了报告分类时, 判断是否允许变更
	if req.ReportType != flowItem.ReportType || req.ClassifyFirstId != flowItem.ClassifyFirstId || req.ClassifySecondId != flowItem.ClassifySecondId || req.ClassifyThirdId != flowItem.ClassifyThirdId {
		checkOk, e := services.CheckReportApproveFlowChange(flowItem.ReportType, flowItem.ClassifyFirstId, flowItem.ClassifySecondId, flowItem.ClassifyThirdId)
		if e != nil {
			br.Msg = "操作失败"
			br.ErrMsg = "校验审批流是否可变更失败, Err: " + e.Error()
			return
		}
		if !checkOk {
			br.Msg = "当前有未走完流程的报告, 请走完流程后再做变更"
			return
		}
	}

	flowItem.FlowName = req.FlowName
	flowItem.ReportType = req.ReportType
	flowItem.ClassifyFirstId = req.ClassifyFirstId
	flowItem.ClassifySecondId = req.ClassifySecondId
	flowItem.ClassifyThirdId = req.ClassifyThirdId
	flowItem.CurrVersion += 1
	flowItem.ModifyTime = time.Now().Local()

	nodeItems := make([]*report_approve.ReportApproveNode, 0)
	for _, v := range req.Nodes {
		n := new(report_approve.ReportApproveNode)
		n.ApproveType = v.ApproveType
		n.CurrVersion = flowItem.CurrVersion
		j, _ := json.Marshal(v.Users)
		n.Users = string(j)
		n.CreateTime = time.Now().Local()
		nodeItems = append(nodeItems, n)
	}

	// 更新审批流和节点
	if e := flowItem.UpdateFlowAndNodes(flowItem, nodeItems); e != nil {
		br.Msg = "操作失败"
		br.ErrMsg = "更新审批流和节点失败, Err: " + e.Error()
		return
	}

	// 返回详情
	detail, e := report_approve.FormatFlowAndNodesItem2Detail(flowItem, nodeItems)
	if e != nil {
		br.Msg = "获取失败"
		br.ErrMsg = "获取审批详情失败, Err: " + e.Error()
		return
	}
	br.Data = detail
	br.Ret = 200
	br.Success = true
	br.Msg = "操作成功"
}

// Detail
// @Title 审批流详情
// @Description 审批流详情
// @Param   ReportApproveFlowId  query  int  true  "审批流ID"
// @Success 200 {object} report_approve.ReportApproveFlowDetailItem
// @router /flow/detail [get]
func (this *ReportApproveFlowController) Detail() {
	br := new(models.BaseResponse).Init()
	defer func() {
		if br.ErrMsg == "" {
			br.IsSendEmail = false
		}
		this.Data["json"] = br
		this.ServeJSON()
	}()
	sysUser := this.SysUser
	if sysUser == nil {
		br.Msg = "请登录"
		br.ErrMsg = "请登录，SysUser Is Empty"
		br.Ret = 408
		return
	}
	flowId, _ := this.GetInt("ReportApproveFlowId")
	if flowId <= 0 {
		br.Msg = "参数有误"
		br.ErrMsg = fmt.Sprintf("参数有误, ReportApproveFlowId: %d", flowId)
		return
	}

	flowOb := new(report_approve.ReportApproveFlow)
	flowItem, e := flowOb.GetItemById(flowId)
	if e != nil {
		if e.Error() == utils.ErrNoRow() {
			br.Msg = "审批流已被删除, 请刷新页面"
			return
		}
		br.Msg = "获取失败"
		br.ErrMsg = "获取审批流信息失败, Err: " + e.Error()
		return
	}

	// 审批节点
	nodeOb := new(report_approve.ReportApproveNode)
	nodeCond := fmt.Sprintf(` AND %s = ? AND %s = ?`, report_approve.ReportApproveNodeCols.ReportApproveFlowId, report_approve.ReportApproveNodeCols.CurrVersion)
	nodePars := make([]interface{}, 0)
	nodePars = append(nodePars, flowItem.ReportApproveFlowId, flowItem.CurrVersion)
	nodes, e := nodeOb.GetItemsByCondition(nodeCond, nodePars, []string{}, "")
	if e != nil {
		br.Msg = "获取失败"
		br.ErrMsg = "获取审批节点失败, Err: " + e.Error()
		return
	}

	detail, e := report_approve.FormatFlowAndNodesItem2Detail(flowItem, nodes)
	if e != nil {
		br.Msg = "获取失败"
		br.ErrMsg = "获取审批详情失败, Err: " + e.Error()
		return
	}
	br.Data = detail
	br.Ret = 200
	br.Success = true
	br.Msg = "获取成功"
}

// Remove
// @Title 删除审批流
// @Description 删除审批流
// @Param	request	body report_approve.ReportApproveFlowRemoveReq true "type json string"
// @Success 200 string "操作成功"
// @router /flow/remove [post]
func (this *ReportApproveFlowController) Remove() {
	br := new(models.BaseResponse).Init()
	defer func() {
		if br.ErrMsg == "" {
			br.IsSendEmail = false
		}
		this.Data["json"] = br
		this.ServeJSON()
	}()
	sysUser := this.SysUser
	if sysUser == nil {
		br.Msg = "请登录"
		br.ErrMsg = "请登录，SysUser Is Empty"
		br.Ret = 408
		return
	}
	var req report_approve.ReportApproveFlowRemoveReq
	if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
		br.Msg = "参数有误"
		br.ErrMsg = "参数解析失败, Err: " + e.Error()
		return
	}
	if req.ReportApproveFlowId <= 0 {
		br.Msg = "参数有误"
		br.ErrMsg = fmt.Sprintf("参数有误, ReportApproveFlowId: %d", req.ReportApproveFlowId)
		return
	}

	flowOb := new(report_approve.ReportApproveFlow)
	flowItem, e := flowOb.GetItemById(req.ReportApproveFlowId)
	if e != nil {
		if e.Error() == utils.ErrNoRow() {
			br.Msg = "审批流已被删除, 请刷新页面"
			return
		}
		br.Msg = "操作失败"
		br.ErrMsg = "获取审批流信息失败, Err: " + e.Error()
		return
	}

	// 校验是否允许删除
	checkOk, e := services.CheckReportApproveFlowChange(flowItem.ReportType, flowItem.ClassifyFirstId, flowItem.ClassifySecondId, flowItem.ClassifyThirdId)
	if e != nil {
		br.Msg = "操作失败"
		br.ErrMsg = "校验审批流是否可变更失败, Err: " + e.Error()
		return
	}
	if !checkOk {
		br.Msg = "当前有未走完流程的报告, 请走完流程后再做删除!"
		return
	}

	// 删除审批流, 保留审批节点, 历史审批回显会用得到
	if e = flowItem.Del(); e != nil {
		br.Msg = "操作失败"
		br.ErrMsg = "删除审批流失败, Err: " + e.Error()
		return
	}

	// 更新审批对应的报告状态：待提交->未发布
	go func() {
		_ = services.FlowOperateResetReportState(flowItem.ReportType, flowItem.ClassifyFirstId, flowItem.ClassifySecondId, flowItem.ClassifyThirdId, models.ReportStateWaitSubmit, models.ReportStateUnpublished)
	}()

	br.Ret = 200
	br.Success = true
	br.Msg = "操作成功"
}

// ReportClassifyTree
// @Title 报告分类树
// @Description 报告分类树
// @Param   ReportApproveFlowId  query  int  false  "审批流ID"
// @Success 200 {object} report_approve.ReportClassifyTreeItem
// @router /report/classify_tree [get]
func (this *ReportApproveFlowController) ReportClassifyTree() {
	br := new(models.BaseResponse).Init()
	defer func() {
		if br.ErrMsg == "" {
			br.IsSendEmail = false
		}
		this.Data["json"] = br
		this.ServeJSON()
	}()
	sysUser := this.SysUser
	if sysUser == nil {
		br.Msg = "请登录"
		br.ErrMsg = "请登录，SysUser Is Empty"
		br.Ret = 408
		return
	}
	flowId, _ := this.GetInt("ReportApproveFlowId")

	// 获取审批流信息, 用于查询分类是否可选
	var flowKey string
	if flowId > 0 {
		flowOb := new(report_approve.ReportApproveFlow)
		flowItem, e := flowOb.GetItemById(flowId)
		if e != nil {
			if e.Error() == utils.ErrNoRow() {
				br.Msg = "审批流已被删除, 请刷新页面"
				return
			}
			br.Msg = "获取失败"
			br.ErrMsg = "获取审批流信息失败, Err: " + e.Error()
			return
		}
		flowKey = fmt.Sprintf("%d-%d-%d", flowItem.ReportType, flowItem.ClassifyFirstId, flowItem.ClassifySecondId)
	}

	// 获取审批流列表
	flowOb := new(report_approve.ReportApproveFlow)
	flows, e := flowOb.GetItemsByCondition(``, make([]interface{}, 0), []string{}, "")
	if e != nil {
		br.Msg = "获取失败"
		br.ErrMsg = "获取审批流列表失败, Err: " + e.Error()
		return
	}
	hasFlowMap := make(map[string]bool)
	for _, v := range flows {
		k := fmt.Sprintf("%d-%d-%d-%d", v.ReportType, v.ClassifyFirstId, v.ClassifySecondId, v.ClassifyThirdId)
		if k == flowKey {
			// 当前审批流对应的分类标记为可选状态
			continue
		}
		hasFlowMap[k] = true
	}

	resp, cnTree, enTree := make([]*report_approve.ReportClassifyTreeItem, 0), make([]*report_approve.ReportClassifyTreeItem, 0), make([]*report_approve.ReportClassifyTreeItem, 0)

	var cnErr, enErr error
	wg := sync.WaitGroup{}
	wg.Add(2)

	// 中文/智能研报分类
	go func() {
		defer func() {
			wg.Done()
		}()

		classify, e := models.GetAllClassify()
		if e != nil {
			cnErr = fmt.Errorf("GetAllClassify err: %s", e.Error())
			return
		}
		cnTree = services.GetReportClassifyTreeRecursive(classify, 0)
		for _, v := range cnTree {
			k1 := fmt.Sprintf("%d-%d-%d-%d", report_approve.FlowReportTypeChinese, v.ClassifyId, 0, 0)
			v.HasFlow = hasFlowMap[k1]

			for _, v2 := range v.Children {
				k2 := fmt.Sprintf("%d-%d-%d-%d", report_approve.FlowReportTypeChinese, v.ClassifyId, v2.ClassifyId, 0)
				v2.HasFlow = hasFlowMap[k2]
				for _, v3 := range v2.Children {
					k3 := fmt.Sprintf("%d-%d-%d-%d", report_approve.FlowReportTypeChinese, v.ClassifyId, v2.ClassifyId, v3.ClassifyId)
					v3.HasFlow = hasFlowMap[k3]
				}
			}
		}
	}()

	// 英文研报分类
	go func() {
		defer func() {
			wg.Done()
		}()

		classify, e := models.GetAllEnglishClassify()
		if e != nil {
			enErr = fmt.Errorf("GetAllEnglishClassify err: %s", e.Error())
			return
		}
		enTree = services.GetReportClassifyTreeRecursive(classify, 0)
		for _, v := range enTree {
			for _, v2 := range v.Children {
				k := fmt.Sprintf("%d-%d-%d-%d", report_approve.FlowReportTypeEnglish, v.ClassifyId, v2.ClassifyId, 0)
				v2.HasFlow = hasFlowMap[k]
			}
		}
	}()

	wg.Wait()

	if cnErr != nil {
		br.Msg = "获取失败"
		br.ErrMsg = "获取中文分类失败, Err: " + cnErr.Error()
		return
	}
	if enErr != nil {
		br.Msg = "获取失败"
		br.ErrMsg = "获取英文分类失败, Err: " + enErr.Error()
		return
	}

	if this.Lang == utils.EnLangVersion {
		resp = append(resp, &report_approve.ReportClassifyTreeItem{
			ClassifyId:   report_approve.FlowReportTypeChinese,
			ClassifyName: "Report list",
			Children:     cnTree,
		}, &report_approve.ReportClassifyTreeItem{
			ClassifyId:   report_approve.FlowReportTypeEnglish,
			ClassifyName: "English Report",
			Children:     enTree,
		})
	} else {
		resp = append(resp, &report_approve.ReportClassifyTreeItem{
			ClassifyId:   report_approve.FlowReportTypeChinese,
			ClassifyName: "研报",
			Children:     cnTree,
		}, &report_approve.ReportClassifyTreeItem{
			ClassifyId:   report_approve.FlowReportTypeEnglish,
			ClassifyName: "英文研报",
			Children:     enTree,
		})
	}

	br.Data = resp
	br.Ret = 200
	br.Success = true
	br.Msg = "获取成功"
}
