package contract

import (
	"encoding/json"
	"fmt"
	"github.com/rdlucklib/rdluck_tools/paging"
	"github.com/shopspring/decimal"
	"github.com/tealeg/xlsx"
	"hongze/hz_crm_api/controllers"
	"hongze/hz_crm_api/models"
	"hongze/hz_crm_api/models/company"
	"hongze/hz_crm_api/models/contract"
	"hongze/hz_crm_api/models/contract/request"
	"hongze/hz_crm_api/models/contract/response"
	"hongze/hz_crm_api/services"
	contractService "hongze/hz_crm_api/services/contract"
	"hongze/hz_crm_api/services/seal"
	"hongze/hz_crm_api/utils"
	"os"
	"path"
	"path/filepath"
	"strconv"
	"strings"
	"time"
)

// 合同管理
type ContractController struct {
	controllers.BaseAuthController
}

// GetServiceTemplateList
// @Title 获取服务套餐列表
// @Description 获取服务套餐列表
// @Param   ProductId   query   int  false       "客户类型：传0或者不传为当前账号权限,1 代表是：ficc；2 代表是：权益"
// @Param   ContractType   query   string  false       "合同类型：枚举值：'新签合同','续约合同','补充协议'"
// @Success 200 {object} []contract.ContractServiceTemplateMapItems
// @router /service/template/list [get]
func (this *ContractController) GetServiceTemplateList() {
	br := new(models.BaseResponse).Init()
	defer func() {
		this.Data["json"] = br
		this.ServeJSON()
	}()

	productId, _ := this.GetInt("ProductId")
	contractType := this.GetString("ContractType")

	//没有传参时，默认是从账号中获取
	if productId == 0 {
		productId = services.GetProductId(this.SysUser.RoleTypeCode)
	}
	if productId == 0 {
		br.Msg = "参数异常"
		br.ErrMsg = "获取参数异常，获取合同类型异常，当前RoleTypeCode:" + this.SysUser.RoleTypeCode
		return
	}

	list, err := contract.GetContractServiceTemplateMapByProductId(productId)
	if err != nil {
		br.Msg = "获取失败"
		br.ErrMsg = "获取数据失败，Err:" + err.Error()
		return
	}
	for i := 0; i < len(list); i++ {
		item := list[i]
		tmpList, err := contract.GetContractServiceTemplateMapByParentId(item.ServiceTemplateId)
		if err != nil {
			br.Msg = "获取失败"
			br.ErrMsg = "获取数据失败，Err:" + err.Error()
			return
		}
		secondLen := len(tmpList)
		for j := 0; j < secondLen; j++ {
			detail, err := contract.GetContractServiceDetailByTemplateId(tmpList[j].ServiceTemplateId)
			if err != nil {
				br.Msg = "获取失败"
				br.ErrMsg = "获取详情模板失败，Err:" + err.Error()
				return
			}

			tmpList[j].Detail = detail
			// 权益存在第三级主客观套餐-CRM8.8
			thirdList, e := contract.GetContractServiceTemplateMapByParentId(tmpList[j].ServiceTemplateId)
			if e != nil {
				br.Msg = "获取失败"
				br.ErrMsg = "获取三级套餐失败, Err: " + e.Error()
				return
			}
			tmpList[j].Children = thirdList
			//if len(thirdList) > 0 {
			//	if utils.InArrayByInt([]int{19, 20, 21, 22}, thirdList[0].ChartPermissionId) {
			//	}
			//}
		}
		// 权益获取升级套餐-CRM13.2
		if productId == 2 {
			newTempList := make([]*contract.ContractServiceTemplateMapItems, 0)
			upgradeMap := make(map[int]*contract.ContractServiceTemplateMapItems)
			upgradeList, err := contract.GetContractServiceTemplateMapByChartPermissionId()
			if err != nil {
				br.Msg = "获取失败"
				br.ErrMsg = "获取数据失败，Err:" + err.Error()
				return
			}
			for _, v := range upgradeList {
				upgradeMap[v.ChartPermissionId-100000] = v
				fmt.Println("v.ChartPermissionId-10000:", v.ChartPermissionId-100000)
			}
			for _, v := range tmpList {
				newTempList = append(newTempList, v)
				if len(v.Children) > 0 {
					if utils.InArrayByInt([]int{19, 20, 21, 22}, v.Children[0].ChartPermissionId) {
						newTempList = append(newTempList, upgradeMap[v.Children[0].ChartPermissionId])
					}
				}
			}
			tmpList = newTempList
		}

		detail, err := contract.GetContractServiceDetailByTemplateId(list[i].ServiceTemplateId)
		if err != nil {
			br.Msg = "获取失败"
			br.ErrMsg = "获取详情模板失败，Err:" + err.Error()
			return
		}
		if productId == 1 && list[i].ServiceTemplateId == 2 {
			// 特殊处理Ficc周报、商品双周报、数据点评的套餐显示
			// 把detail转成go struct
			// 查询默认的公有权限
			publicPermissionList, tmpE := models.GetFiccPermissionSecondPublic()
			if tmpE != nil {
				br.Msg = "获取失败"
				br.ErrMsg = "获取默认的公有权限失败，Err:" + tmpE.Error()
				return
			}
			publicPermissionIds := make([]int, 0)
			publicPermissionNames := make([]string, 0)
			for _, v := range publicPermissionList {
				publicPermissionIds = append(publicPermissionIds, v.ChartPermissionId)
				publicPermissionNames = append(publicPermissionNames, v.PermissionName)
			}
			for k, v := range detail {
				if v.Id == 4 || v.Id == 5 || v.Id == 6 {
					detailStruct := new(contract.ServiceTemplateDetailCol2)
					e := json.Unmarshal([]byte(v.Col2), detailStruct)
					if e != nil {
						br.Msg = "获取失败"
						br.ErrMsg = "获取套餐信息失败, json.Unmarshal Err: " + e.Error()
						return
					}
					//替换默认品种
					detailStruct.ValueId = publicPermissionIds
					detailStruct.Value = strings.Join(publicPermissionNames, ",")
					newCol2, e := json.Marshal(detailStruct)
					if e != nil {
						br.Msg = "获取失败"
						br.ErrMsg = "获取套餐信息失败, json.Marshal Err: " + e.Error()
						return
					}
					detail[k].Col2 = string(newCol2)
				}
			}
		}
		if productId == 1 && contractType == "补充协议" {
			for _, v := range detail {
				//ficc 的合同模板的 补充协议需要将默认的宏观经济给移除掉
				if utils.InArrayByInt([]int{4, 5, 6}, v.Id) {
					var tableCel request.AddContractServiceDetailReq
					tmpErr := json.Unmarshal([]byte(v.Col2), &tableCel)
					if tmpErr != nil {
						br.Msg = "获取失败"
						br.ErrMsg = "配置解析失败，Err:" + tmpErr.Error()
						return
					}
					tableCel.ValueId = make([]int, 0)
					tableCel.Value = ``
					//contract.
					tmpStr, tmpErr := json.Marshal(tableCel)
					if tmpErr != nil {
						br.Msg = "获取失败"
						br.ErrMsg = "修改json配置后，转字符串失败，Err:" + tmpErr.Error()
						return
					}
					v.Col2 = string(tmpStr)
				}
				//v.Col1
			}
		}
		list[i].Detail = detail

		list[i].Children = tmpList
	}

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

// GetContractTemplateList
// @Title 获取合同模板列表
// @Description 获取合同模板列表
// @Success 200 {object} []contract.ContractTemplate
// @router /template/list [get]
func (this *ContractController) GetContractTemplateList() {
	br := new(models.BaseResponse).Init()
	defer func() {
		this.Data["json"] = br
		this.ServeJSON()
	}()

	productId := services.GetProductId(this.SysUser.RoleTypeCode)

	list, err := contract.GetContractTemplateMapByProductId(productId)
	if err != nil {
		br.Msg = "获取失败"
		br.ErrMsg = "获取数据失败，Err:" + err.Error()
		return
	}

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

// GetPayChannel
// @Title 获取合同模板列表
// @Description 获取合同模板列表
// @Param   Keyword   query   string  true   "关键字"
// @Success 200 {object} []contract.PayChannel
// @router /pay_channel/list [get]
func (this *ContractController) GetPayChannel() {
	br := new(models.BaseResponse).Init()
	defer func() {
		this.Data["json"] = br
		this.ServeJSON()
	}()

	keyword := this.GetString("Keyword", "")
	list, err := contract.GetPayChannelList(keyword)
	if err != nil {
		br.Msg = "获取失败"
		br.ErrMsg = "获取数据失败，Err:" + err.Error()
		return
	}

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

// AddContract
// @Title 新增合同
// @Description 新增合同接口
// @Param	request	body request.AddContractReq true "type json string"
// @Success 200 {object} response.AddContractResp
// @router /add [post]
func (this *ContractController) AddContract() {
	br := new(models.BaseResponse).Init()
	defer func() {
		this.Data["json"] = br
		this.ServeJSON()
	}()
	sysUser := this.SysUser
	if sysUser == nil {
		br.Msg = "请登录"
		br.ErrMsg = "请登录，SysUser Is Empty"
		br.Ret = 408
		return
	}
	productId := services.GetProductId(sysUser.RoleTypeCode)
	if productId == 0 {
		br.Msg = "账户异常"
		br.ErrMsg = "账户异常，当前账户类型为：" + sysUser.RoleTypeCode
		br.Ret = 408
		return
	}
	var req request.AddContractReq
	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
	if err != nil {
		br.Msg = "参数解析异常！"
		br.ErrMsg = "参数解析失败，Err:" + err.Error()
		return
	}
	// 限制一下合同金额, 目前只支持人民币转大写只支持到千亿, 虽然生产使用中不可能到这么大, 但还是加上吧 =_=!
	maxPrice := float64(1000000000000)
	if req.OriginalPrice >= maxPrice || req.Price >= maxPrice {
		br.Msg = "合同金额过大, 请核验金额"
		return
	}
	contractInfo, err, errMsg := contractService.AddContract(req, sysUser.AdminId, productId, sysUser.RealName)
	if err != nil {
		br.Msg = "保存合同失败！"
		if errMsg != "" {
			br.Msg = errMsg
		}
		br.ErrMsg = "保存合同失败，Err:" + err.Error()
		return
	}
	msg := "添加成功"
	//如果是直接发起审批，那么
	if req.IsAudit {
		tmpErr, errMsg := contractService.Apply(contractInfo.ContractId)
		if tmpErr != nil {
			br.Msg = "提交审批失败！"
			if errMsg != "" {
				br.Msg = errMsg
			}
			br.ErrMsg = "提交审批失败，Err:" + tmpErr.Error()
			return
		}
		msg = "提交审批成功"
	}
	br.Ret = 200
	br.Success = true
	br.Msg = msg
	br.Data = response.AddContractResp{
		ContractId: contractInfo.ContractId,
	}
}

// List
// @Title 合同列表
// @Description 合同列表接口
// @Param   ContractBusinessType   query   string  false       "合同业务类型，枚举值：'业务合同','代付合同'"
// @Param   ContractType   query   string  false       "合同类型，枚举值：'新签合同','续约合同','补充协议'"
// @Param   ContractStatus   query   string  false       "合同状态，枚举值：'待提交','待审批','已撤回','已审批','已驳回','已作废'"
// @Param   ProductId   query   int  false       "客户类型：传0或者不传为当前账号权限,1 代表是：ficc；2 代表是：权益"
// @Param   ModifyStartTime   query   string  false       "服务更新时间的选择开始时间，格式：2021-05-23 00:00:00"
// @Param   ModifyEndTime   query   string  false       "服务更新时间的选择结束时间，格式：2021-05-26 23:59:59"
// @Param   SellerId   query   string  false       "选择的销售id"
// @Param   KeywordType   query   string  false       "搜索关键字类型，枚举值：'使用方','代付方'"
// @Param   Keyword   query   string  false       "搜索关键字"
// @Param   IsExport   query   bool  false       "是否导出excel，默认是false"
// @Success 200 {object} response.ContractListResp
// @router /list [get]
func (this *ContractController) List() {
	br := new(models.BaseResponse).Init()
	defer func() {
		this.Data["json"] = br
		this.ServeJSON()
	}()
	sysUser := this.SysUser
	if sysUser == nil {
		br.Msg = "请登录"
		br.ErrMsg = "请登录，SysUser Is Empty"
		br.Ret = 408
		return
	}

	//合同类型、产品类型、合同状态、更新时间、所选销售
	//关键字：合同编号、客户名称，社会信用码
	contractType := this.GetString("ContractType")
	contractBusinessType := this.GetString("ContractBusinessType")
	contractStatus := this.GetString("ContractStatus")
	productId, _ := this.GetInt("ProductId")
	modifyStartTime := this.GetString("ModifyStartTime")
	modifyEndTime := this.GetString("ModifyEndTime")
	sellerIds := this.GetString("SellerId")
	keyword := this.GetString("Keyword")
	keywordType := this.GetString("KeywordType")

	condition := ""
	pars := make([]interface{}, 0)
	joinStr := ""                  //表连接
	productSlice := make([]int, 0) //需要下载的 产品 切片

	//如果不是超管或者合规，那么只能查看自己的合同
	if sysUser.RoleTypeCode == utils.ROLE_TYPE_CODE_FICC_ADMIN {
		condition += ` AND a.product_id = 1 AND a.status not in ("待提交","已撤回") `
	} else if sysUser.RoleTypeCode == utils.ROLE_TYPE_CODE_RAI_ADMIN {
		condition += ` AND a.product_id = 2 AND a.status not in ("待提交","已撤回") `
	} else if sysUser.RoleTypeCode == utils.ROLE_TYPE_CODE_ADMIN || sysUser.RoleTypeCode == utils.ROLE_TYPE_CODE_FINANCE { //超管可查看所有状态的合同（除过已撤回、待提交状态合同），可下载所有状态的合同
		condition += ` AND a.status not in ("待提交","已撤回") `
	} else {
		if sysUser.RoleTypeCode != utils.ROLE_TYPE_CODE_COMPLIANCE && sysUser.RoleTypeCode != utils.ROLE_TYPE_CODE_ADMIN && sysUser.RoleTypeCode != utils.ROLE_TYPE_CODE_FINANCE {
			condition += ` AND a.seller_id = ? `
			pars = append(pars, sysUser.AdminId)
		}
	}
	//合同类型、、更新时间、所选销售
	//关键字：合同编号、客户名称，社会信用码
	if contractBusinessType != "" { //合同业务类型
		condition += ` AND a.contract_business_type = ? `
		pars = append(pars, contractBusinessType)
	}

	if contractType != "" {
		condition += ` AND a.contract_type = ? `
		pars = append(pars, contractType)
	}
	//合同状态
	if contractStatus != "" {
		condition += ` AND a.status = ? `
		pars = append(pars, contractStatus)
	}
	//产品类型
	if productId > 0 {
		condition += ` AND a.product_id = ? `
		pars = append(pars, productId)

		productSlice = append(productSlice, productId)
	} else {
		nowProductId := services.GetProductId(sysUser.RoleTypeCode)
		if nowProductId > 0 {
			productSlice = append(productSlice, nowProductId)
		} else {
			productSlice = append(productSlice, 1)
			productSlice = append(productSlice, 2)
		}
	}
	//所选销售
	if sellerIds != "" {
		condition += ` AND a.seller_id IN (` + sellerIds + `) `
	}
	//更新开始时间
	if modifyStartTime != "" {
		condition += ` AND a.modify_time >= ? `
		pars = append(pars, modifyStartTime)
	}
	//更新结束时间
	if modifyEndTime != "" {
		condition += ` AND a.modify_time <= ? `
		pars = append(pars, modifyEndTime)
	}
	//关键字
	//if keyword != "" {
	//	condition += ` AND (contract_code LIKE '%` + keyword + `%' OR company_name LIKE '%` + keyword + `%' OR credit_code LIKE '%` + keyword + `%' ) `
	//}
	//搜索关键字和搜索类型同时不为空
	if keywordType != "" && keyword != "" {
		switch contractBusinessType {
		case "业务合同":
			if keywordType == "使用方" {
				condition += ` AND (a.contract_code LIKE '%` + keyword + `%' OR a.company_name LIKE '%` + keyword + `%' OR a.credit_code LIKE '%` + keyword + `%' ) `
			} else {
				joinStr = " join contract_relation b on a.contract_id=b.contract_id join contract c on b.payment_on_behalf_contract_id=c.contract_id "

				condition += ` AND (c.contract_code LIKE '%` + keyword + `%' OR c.company_name LIKE '%` + keyword + `%' OR c.credit_code LIKE '%` + keyword + `%' ) `
				//关联合同的查询条件
				condition += ` AND c.status in ("已签回","已审批") AND c.is_delete = 0 `
			}
		case "代付合同":
			if keywordType == "代付方" {
				condition += ` AND (a.contract_code LIKE '%` + keyword + `%' OR a.company_name LIKE '%` + keyword + `%' OR a.credit_code LIKE '%` + keyword + `%' ) `
			} else {
				joinStr = " join contract_relation b on a.contract_id=b.payment_on_behalf_contract_id join contract c on b.contract_id=c.contract_id "

				condition += ` AND (c.contract_code LIKE '%` + keyword + `%' OR c.company_name LIKE '%` + keyword + `%' OR c.credit_code LIKE '%` + keyword + `%' ) `
				//关联合同的查询条件
				condition += ` AND c.status in ("已签回","已审批") AND c.is_delete = 0 `
			}
		}
	}

	pageSize, _ := this.GetInt("PageSize")
	currentIndex, _ := this.GetInt("CurrentIndex")

	var startSize int
	if pageSize <= 0 {
		pageSize = utils.PageSize20
	}
	if currentIndex <= 0 {
		currentIndex = 1
	}
	startSize = paging.StartIndex(currentIndex, pageSize)

	//是否导出报表
	isExport, _ := this.GetBool("IsExport")
	if isExport {
		pageSize = 10000
		currentIndex = 1
	}

	total, err := contract.GetContractListCount(condition, joinStr, pars)
	if err != nil {
		br.Msg = "获取失败"
		br.ErrMsg = "获取数据总数失败，Err:" + err.Error()
		return
	}

	list, err := contract.GetContractList(condition, joinStr, pars, startSize, pageSize)
	if err != nil {
		br.Msg = "获取合同列表失败！"
		br.ErrMsg = "获取合同列表失败，Err:" + err.Error()
		return
	}
	//获取合同套餐服务列表
	serviceTemplateList, err := contract.GetAllContractServiceTemplateList()
	if err != nil {
		br.Msg = "获取合同套餐服务列表失败！"
		br.ErrMsg = "获取合同套餐服务列表失败，Err:" + err.Error()
		return
	}
	templateTitleMap := make(map[int]string)
	for _, serviceTemplate := range serviceTemplateList {
		templateTitleMap[serviceTemplate.ServiceTemplateId] = serviceTemplate.Title
	}

	//业务合同的关联合同id集合
	businessContractIdList := make([]string, 0)
	//代付合同的关联合同id集合
	paymentOnBehalfContractIdList := make([]string, 0)
	//所有合同id集合（用于查询服务内容）
	allServiceContractIdList := make([]string, 0)
	//基础合同的关联合同数据
	contractRelationMap := make(map[int][]*contract.RelationContractList)
	// 权益合同map
	equityContractMap := make(map[int]bool)

	for _, v := range list {
		//合同id
		allServiceContractIdList = append(allServiceContractIdList, fmt.Sprint(v.ContractId))

		switch v.ContractBusinessType {
		case "业务合同":
			businessContractIdList = append(businessContractIdList, fmt.Sprint(v.ContractId))
		case "代付合同":
			paymentOnBehalfContractIdList = append(paymentOnBehalfContractIdList, fmt.Sprint(v.ContractId))
		}
		// 权益合同
		if v.ProductId == 2 {
			equityContractMap[v.ContractId] = true
		}
	}

	//业务合同的关联合同
	if len(businessContractIdList) > 0 {
		contractIdStr := strings.Join(businessContractIdList, ",")
		businessContractList, err := contract.GetContractRelationListByRelationContractIds(contractIdStr)
		if err != nil {
			br.Msg = "获取失败"
			br.ErrMsg = "获取业务关联合同失败，Err:" + err.Error()
			return
		}
		for _, v := range businessContractList {
			//代付合同id
			allServiceContractIdList = append(allServiceContractIdList, fmt.Sprint(v.PaymentOnBehalfContractId))

			if _, ok := contractRelationMap[v.ContractId]; ok {
				contractRelationMap[v.ContractId] = append(contractRelationMap[v.ContractId], v)
			} else {
				tmpList := make([]*contract.RelationContractList, 0)
				contractRelationMap[v.ContractId] = append(tmpList, v)
			}
		}
	}

	//代付合同的关联合同
	if len(paymentOnBehalfContractIdList) > 0 {
		paymentOnBehalfContractIdStr := strings.Join(paymentOnBehalfContractIdList, ",")
		paymentOnBehalfContractList, err := contract.GetContractRelationListByPaymentOnBehalfContractIds(paymentOnBehalfContractIdStr)
		if err != nil {
			br.Msg = "获取失败"
			br.ErrMsg = "获取代付关联合同失败，Err:" + err.Error()
			return
		}
		for _, v := range paymentOnBehalfContractList {
			//业务合同id
			allServiceContractIdList = append(allServiceContractIdList, fmt.Sprint(v.ContractId))

			if _, ok := contractRelationMap[v.PaymentOnBehalfContractId]; ok {
				contractRelationMap[v.PaymentOnBehalfContractId] = append(contractRelationMap[v.PaymentOnBehalfContractId], v)
			} else {
				tmpList := make([]*contract.RelationContractList, 0)
				contractRelationMap[v.PaymentOnBehalfContractId] = append(tmpList, v)
			}
		}
	}

	//合同套餐服务列表
	serviceListMap := make(map[int][]*contract.ContractServiceAndDetail, 0)
	// 权益合同
	if len(allServiceContractIdList) > 0 {
		allRelationIdStr := strings.Join(allServiceContractIdList, ",")
		tmpServiceList, err := contract.GetContractServiceAndDetailListByIds(allRelationIdStr)
		if err != nil {
			br.Msg = "获取失败"
			br.ErrMsg = "获取关联合同服务详情失败，Err:" + err.Error()
			return
		}

		allContractServiceIdList := make([]string, 0)
		serviceDetailListMap := make(map[int][]*contract.ContractServiceDetail, 0)
		for _, service := range tmpServiceList {
			if service.HasDetail == "是" {
				allContractServiceIdList = append(allContractServiceIdList, strconv.Itoa(service.ContractServiceId))
			}
		}
		if len(allContractServiceIdList) > 0 {
			allContractServiceIdStr := strings.Join(allContractServiceIdList, ",")
			list, detailErr := contract.GetContractServiceDetailListByServiceIds(allContractServiceIdStr)
			if detailErr != nil {
				br.Msg = "获取失败"
				br.ErrMsg = "查找合同服务详情异常，Err:" + detailErr.Error()
				return
			}
			for _, v := range list {
				if _, ok := serviceDetailListMap[v.ContractServiceId]; ok {
					serviceDetailListMap[v.ContractServiceId] = append(serviceDetailListMap[v.ContractServiceId], v)
				} else {
					tmpList := make([]*contract.ContractServiceDetail, 0)
					serviceDetailListMap[v.ContractServiceId] = append(tmpList, v)
				}
			}
		}

		for _, service := range tmpServiceList {
			if service.HasDetail == "是" {
				if serviceDetailList, ok := serviceDetailListMap[service.ContractServiceId]; ok {
					service.DetailList = serviceDetailList
				}
				//套餐名称
				if title, ok := templateTitleMap[service.ServiceTemplateId]; ok {
					service.Title = title
				}
			}

			//服务列表
			if _, ok := serviceListMap[service.ContractId]; ok {
				serviceListMap[service.ContractId] = append(serviceListMap[service.ContractId], service)
			} else {
				tmpList := make([]*contract.ContractServiceAndDetail, 0)
				serviceListMap[service.ContractId] = append(tmpList, service)
			}
		}
		// CRM8.8-权益合同主客观合并
		for k, v := range serviceListMap {
			if equityContractMap[k] {
				mergeList := contractService.EquityMergeSubjectAndObject(v)
				serviceListMap[k] = mergeList
			}
		}
	}

	//关联合同
	for _, contractRelationList := range contractRelationMap {
		for _, contractRelation := range contractRelationList {
			//服务权限列表
			// 关联合同同样合并
			if serviceList, ok := serviceListMap[contractRelation.ContractId]; ok {
				relationMergeList := contractService.EquityMergeSubjectAndObject(serviceList)
				contractRelation.Service = relationMergeList
			}
		}
	}

	for i := 0; i < len(list); i++ {
		//合同操作权限
		var opButton contract.ContractOpButton

		item := list[i]
		list[i].StartDateStr = item.StartDate.Format(utils.FormatDate)
		list[i].EndDateStr = item.EndDate.Format(utils.FormatDate)

		list[i].CreateTimeStr = item.CreateTime.Format(utils.FormatDateTime)
		list[i].ModifyTimeStr = item.ModifyTime.Format(utils.FormatDateTime)
		list[i].ApproveTimeStr = item.ApproveTime.Format(utils.FormatDateTime)
		list[i].InvalidTimeStr = item.InvalidTime.Format(utils.FormatDateTime)
		list[i].CheckBackFileTimeStr = item.CheckBackFileTime.Format(utils.FormatDateTime)
		list[i].RescindTimeStr = item.RescindTime.Format(utils.FormatDateTime)

		//服务列表
		if serviceList, ok := serviceListMap[item.ContractId]; ok {
			item.Service = serviceList
		}
		//serviceList, err := contract.GetContractServiceAndDetailList(item.ContractId)
		//if err != nil {
		//	br.Msg = "获取失败"
		//	br.ErrMsg = "查找合同服务异常，Err:" + err.Error()
		//	return
		//}
		//for i := 0; len(serviceList) > i; i++ {
		//	if serviceList[i].HasDetail == "是" {
		//		list, detailErr := contract.GetContractServiceDetailListByServiceId(serviceList[i].ContractServiceId)
		//		if detailErr != nil {
		//			br.Msg = "获取失败"
		//			br.ErrMsg = "查找合同服务详情异常，Err:" + err.Error()
		//			return
		//		}
		//
		//		//套餐名称
		//		serviceList[i].DetailList = list
		//		if title, ok := templateTitleMap[serviceList[i].ServiceTemplateId]; ok {
		//			serviceList[i].Title = title
		//		}
		//	}
		//}
		//list[i].Service = serviceList

		if item.Status == "待审批" {
			approvalInfo, tmpErr := contract.GetLastContractApprovalByContractId(item.ContractId, "contract")
			if tmpErr != nil {
				//err= tmpErr
				//return
				continue
			}
			//如果合同归属是当前账号，且处于第一级审批
			if item.SellerId == sysUser.AdminId && approvalInfo.CurrNodeId == approvalInfo.StartNodeId {
				opButton.Cancel = true
			}
		}
		//更新附件权限
		if item.SellerId == sysUser.AdminId && item.Status == "已审批" {
			opButton.UpdateFile = true
		}
		list[i].OpButton = opButton

		//关联合同
		if relationContractList, ok := contractRelationMap[item.ContractId]; ok {
			item.RelationContractList = relationContractList
			//list[i].RelationContractList = relationContractList
		}
	}

	page := paging.GetPaging(currentIndex, pageSize, total)

	//导出excel
	if isExport {
		contractListExport(this, list, productSlice, contractBusinessType, br)
		return
	}
	br.Ret = 200
	br.Success = true
	br.Msg = "获取成功"
	br.Data = response.ContractListResp{
		List:   list,
		Paging: page,
	}
}

// contractListExport 合同列表数据导出
func contractListExport(this *ContractController, list []*contract.ContractList, productSlice []int, contractBusinessType string, br *models.BaseResponse) {
	//产品类型

	//获取合同套餐服务列表
	serviceTemplateList, err := contract.GetAllContractServiceTemplateList()
	if err != nil {
		br.Msg = "获取合同套餐服务列表失败！"
		br.ErrMsg = "获取合同套餐服务列表失败，Err:" + err.Error()
		return
	}
	templateTitleMap := make(map[int]string)
	for _, serviceTemplate := range serviceTemplateList {
		templateTitleMap[serviceTemplate.ServiceTemplateId] = serviceTemplate.Title
	}

	//生成excel文件
	dir, err := os.Executable()
	exPath := filepath.Dir(dir)
	downLoadnFilePath := exPath + "/" + time.Now().Format(utils.FormatDateTimeUnSpace) + ".xlsx"
	xlsxFile := xlsx.NewFile()
	if err != nil {
		br.Msg = "生成文件失败"
		br.ErrMsg = "生成文件失败"
		return
	}

	//设置默认字体和文字大小
	xlsx.SetDefaultFont(12, "宋体")

	//定义边框样式
	border := xlsx.NewBorder("thin", "thin", "thin", "thin")
	//定义文字排版样式
	alignment := xlsx.Alignment{
		Horizontal: "center",
		Vertical:   "center",
		WrapText:   true,
	}

	//普通样式
	style := xlsx.NewStyle()
	style.Alignment = alignment
	style.ApplyAlignment = true
	style.Border = *border

	//标红文字，便于查看哪些产品被勾选
	redStyle := xlsx.NewStyle()
	redStyle.Alignment = alignment
	redStyle.ApplyAlignment = true
	redStyle.Font.Color = "ff0000"
	//定义底色需要标黄的 单元格颜色
	redFill := xlsx.Fill{"solid", "ffff00", "ffff00"}
	redStyle.Fill = redFill
	redStyle.Border = *border

	//标题样式
	titleStyle := xlsx.NewStyle()
	titleFont := xlsx.NewFont(14, "宋体")
	titleFont.Bold = true
	titleStyle.Font = *titleFont
	titleStyle.Alignment = alignment
	titleStyle.Border = *border

	//titleStyle.ApplyAlignment = true

	//表头
	headerStyle := xlsx.NewStyle()
	headerFont := xlsx.NewFont(12, "宋体")
	headerFont.Bold = true
	headerStyle.Font = *headerFont
	headerStyle.Alignment = alignment
	headerStyle.ApplyAlignment = true
	headerStyle.Border = *border

	defer func() {
		os.Remove(downLoadnFilePath)
	}()

	//遍历所拥有的的产品权限，然后插入到对应的sheet表单中
	for pidIndex := 0; pidIndex < len(productSlice); pidIndex++ {
		productId := productSlice[pidIndex]
		//表单名称
		sheetName := "合同数据"
		switch productId {
		case 1:
			sheetName = "ficc合同信息"
		case 2:
			sheetName = "权益合同信息"
		}
		//新增一个sheet表单
		sheel, err := xlsxFile.AddSheet(sheetName)
		if err != nil {
			br.Msg = "新增Sheet失败"
			br.ErrMsg = "新增Sheet失败,Err:" + err.Error()
			return
		}
		//设置列宽
		sheel.SetColWidth(0, 0, 28)
		sheel.SetColWidth(1, 1, 30)
		sheel.SetColWidth(2, 2, 18)
		sheel.SetColWidth(3, 3, 18)
		sheel.SetColWidth(4, 4, 35)
		sheel.SetColWidth(5, 6, 20)
		sheel.SetColWidth(7, 7, 40)

		//合同信息列
		endContractInfoColIndex := 8
		sheel.SetColWidth(8, 8, 40)
		//权限列
		sheel.SetColWidth(endContractInfoColIndex, endContractInfoColIndex+18, 30)

		//标题行
		titleRow := sheel.AddRow()
		titleRow.SetHeight(30)

		//合同信息列
		titleCell := titleRow.AddCell()
		titleCell.HMerge = endContractInfoColIndex //向右合并列数，不包括自身列
		//遍历去添加需要合并的列
		for i := 0; i < endContractInfoColIndex; i++ {
			titleRow.AddCell()
		}

		//报表标题名称
		titleCell.SetValue("合同信息")
		titleCell.SetStyle(titleStyle)

		startI := endContractInfoColIndex + 1
		customStartCellI := endContractInfoColIndex + 1

		serviceSlice := make([]string, 0)
		serviceCellMap := make(map[string]int)

		//获取所有套餐列表
		{
			serviceList, err := getServiceTemplateList(productId)
			if err != nil {
				br.Msg = "查询套餐类型失败"
				br.ErrMsg = "新增Sheet失败,Err:" + err.Error()
				return
			}
			for i := 0; i < len(serviceList); i++ {
				//需要向右合并添加的列数
				addCellNum := 0

				item := serviceList[i]
				//套餐服务列
				servicesCell := titleRow.AddCell()
				//套餐名称
				servicesCell.SetValue(item.Title)
				servicesCell.SetStyle(titleStyle)

				//ficc小套餐
				if item.ServiceTemplateId == 2 {
					productPermission := make(map[int]string)
					productPermission[1] = "每日宏观商品复盘"
					productPermission[2] = "能化专栏《化里化外》"
					productPermission[3] = "股债日评"
					productPermission[4] = "黑色专栏《知白守黑》"
					productPermission[5] = "有色专栏《有声有色》"
					for id, name := range productPermission {
						key := fmt.Sprint(item.ServiceTemplateId, "_product_permission_", id)
						serviceCellMap[key] = startI
						serviceSlice = append(serviceSlice, name)
						startI++
						addCellNum++
					}

					permissionList := make([]*company.PermissionSetItem, 0)
					allPermissions, permissionMap, e := services.GetBaseFiccPermissionSetItem()
					if e != nil {
						br.Msg = "查询基础权限失败"
						br.ErrMsg = "查询基础权限失败,Err:" + e.Error()
						return
					}
					//遍历获取
					for _, v := range allPermissions {
						if v.ParentId == 0 {
							items, ok := permissionMap[v.ChartPermissionId]
							if ok {
								permissionList = append(permissionList, items...)
							}
						}
					}

					//权限列表
					for j := 0; j < len(permissionList); j++ {
						key := fmt.Sprint(item.ServiceTemplateId, "_permission_", permissionList[j].ChartPermissionId)
						serviceCellMap[key] = startI
						serviceSlice = append(serviceSlice, permissionList[j].PermissionName)
						startI++
						addCellNum++
					}
					//因为自己本身有一列了，所以在最后增加列的时候，需要减去自身列
					addCellNum = addCellNum - 1
					if addCellNum > 0 {
						for tmpAddCellNum := 0; tmpAddCellNum < addCellNum; tmpAddCellNum++ {
							titleRow.AddCell()
						}
						servicesCell.HMerge = addCellNum //向右合并列数，不包括自身列
					}
					continue
				} else {
					if item.Children != nil && len(item.Children) > 0 {
						for j := 0; j < len(item.Children); j++ {
							key := fmt.Sprint("service_template_", item.Children[j].ServiceTemplateId)
							serviceCellMap[key] = startI
							serviceSlice = append(serviceSlice, item.Children[j].Title)
							startI++
							addCellNum++
						}
						//因为自己本身有一列了，所以在最后增加列的时候，需要减去自身列
						addCellNum = addCellNum - 1
						if addCellNum > 0 {
							for tmpAddCellNum := 0; tmpAddCellNum < addCellNum; tmpAddCellNum++ {
								titleRow.AddCell()
							}
							servicesCell.HMerge = addCellNum //向右合并列数，不包括自身列
						}
					} else {
						key := fmt.Sprint("service_template_", item.ServiceTemplateId)
						serviceCellMap[key] = startI
						serviceSlice = append(serviceSlice, item.Title)
						startI++
					}
				}
			}
		}

		//表头
		headerRow := sheel.AddRow()
		headerRow.SetHeight(24)

		//合同基础信息
		{
			codeHeaderCell := headerRow.AddCell()
			codeHeaderCell.SetValue("合同编号")
			codeHeaderCell.SetStyle(headerStyle)

			companyHeaderCell := headerRow.AddCell()
			companyHeaderStr := "客户名称"
			if contractBusinessType == "代付合同" {
				companyHeaderStr = "代付方"
			}
			companyHeaderCell.SetValue(companyHeaderStr)
			companyHeaderCell.SetStyle(headerStyle)

			typeHeaderCell := headerRow.AddCell()
			typeHeaderCell.SetValue("合同类型")
			typeHeaderCell.SetStyle(headerStyle)

			priceHeaderCell := headerRow.AddCell()
			priceHeaderCell.SetValue("合同金额")
			priceHeaderCell.SetStyle(headerStyle)

			dateHeaderCell := headerRow.AddCell()
			dateHeaderCell.SetValue("合同有效期")
			dateHeaderCell.SetStyle(headerStyle)

			sellerHeaderCell := headerRow.AddCell()
			sellerHeaderCell.SetValue("销售")
			sellerHeaderCell.SetStyle(headerStyle)

			statusHeaderCell := headerRow.AddCell()
			statusHeaderCell.SetValue("合同状态")
			statusHeaderCell.SetStyle(headerStyle)

			//关联合同信息
			payHeaderCell := headerRow.AddCell()
			payHeaderStr := "付款方"
			if contractBusinessType == "代付合同" {
				payHeaderStr = "客户名称"
			}
			payHeaderCell.SetValue(payHeaderStr)
			payHeaderCell.SetStyle(headerStyle)

			remarkHeaderCell := headerRow.AddCell()
			remarkHeaderCell.SetValue("备注")
			remarkHeaderCell.SetStyle(headerStyle)
		}

		//添加服务套餐名称
		for _, service := range serviceSlice {
			cell := headerRow.AddCell()
			cell.SetValue(service)
			cell.SetStyle(headerStyle)
		}

		for _, v := range list {
			//如果当前合同不是该产品
			if v.ProductId != productId {
				continue
			}

			dataRow := sheel.AddRow()
			dataRow.SetHeight(24)

			//合同基础信息
			{
				codeCell := dataRow.AddCell()
				codeCell.SetValue(v.ContractCode)
				codeCell.SetStyle(style)

				companyCell := dataRow.AddCell()
				companyCell.SetValue(v.CompanyName)
				companyCell.SetStyle(style)

				typeCell := dataRow.AddCell()
				typeCell.SetValue(v.ContractType)
				typeCell.SetStyle(style)

				priceCell := dataRow.AddCell()
				priceCell.SetValue(v.Price)
				priceCell.SetStyle(style)

				dateCell := dataRow.AddCell()
				dateCell.SetValue(fmt.Sprint(v.StartDate.Format(utils.FormatDate), " 至 ", v.EndDate.Format(utils.FormatDate)))
				dateCell.SetStyle(style)

				sellerCell := dataRow.AddCell()
				sellerCell.SetValue(v.SellerName)
				sellerCell.SetStyle(style)

				//合同状态
				statusCell := dataRow.AddCell()
				statusCell.SetValue(v.Status)
				statusCell.SetStyle(style)

				//关联合同客户信息
				relationCompanyName := ``
				if v.RelationContractList != nil && len(v.RelationContractList) > 0 {
					payCompanyNameList := make([]string, 0)
					for _, relationContract := range v.RelationContractList {
						payCompanyNameList = append(payCompanyNameList, relationContract.CompanyName)
					}
					relationCompanyName = strings.Join(payCompanyNameList, ",")
				} else {
					relationCompanyName = v.PayChannel
				}

				payCell := dataRow.AddCell()
				payCell.SetValue(relationCompanyName)
				payCell.SetStyle(style)

				//备注：该字段由三部分拼接：服务内容中的补充内容+赠送时间+优惠金额
				//补充内容直接取该字段内容；
				//赠送时间以年为单位，超过整年的月份作为赠送月份，如14个月即为赠送2个月；
				//优惠金额等于原价-优惠后价格=优惠价格

				//补充内容
				var remark string
				if v.Remark != "" {
					remark += "补充内容：" + v.Remark
				}

				//赠送时间
				//合同结束日期与合同开始日期的时间差（小时差）
				newDecimal := decimal.NewFromFloat(v.EndDate.Sub(v.StartDate).Hours())
				//分母为365天 * 24 小时
				newDecimal2 := decimal.NewFromInt(24 * 365)
				//计算出来相差多少年，保留一位小数（四舍五入）
				numYearDecimal := newDecimal.Div(newDecimal2).Round(1).Mul(decimal.NewFromInt(10))
				//如果大于1年，那么才去判断是否赠送
				numYear, _ := numYearDecimal.Float64()
				if numYear > 10 {
					//获取多出来的整数年数据
					numYearDecimal = numYearDecimal.Mod(decimal.NewFromInt(10)).Div(decimal.NewFromInt(10))
					//计算赠送出来的月份
					numMonthDecimal := numYearDecimal.Mul(decimal.NewFromInt(12)).Round(0)
					numMonth, _ := numMonthDecimal.Float64()
					if numMonth > 0 {
						if remark != "" {
							remark += "；"
						}
						remark += "赠送时间为：" + numMonthDecimal.String() + "个月"
					}
				}
				//优惠金额
				if v.OriginalPrice > v.Price {
					differencePrice := v.OriginalPrice - v.Price
					differencePriceDecimal := decimal.NewFromFloat(differencePrice)

					if remark != "" {
						remark += "；"
					}
					remark += "优惠金额：" + differencePriceDecimal.String() + "元。"
				}
				remarkCell := dataRow.AddCell()
				remarkCell.SetValue(remark)
				remarkCell.SetStyle(style)
			}

			//服务套餐
			{
				tmpServiceList := v.Service
				if contractBusinessType == "代付合同" {
					if v.RelationContractList != nil && len(v.RelationContractList) > 0 {
						tmpServiceList = v.RelationContractList[0].Service
					}
				}
				cellServiceMap := make(map[int]string)
				for _, cellI := range serviceCellMap {
					cellServiceMap[cellI] = "否"
				}

				if tmpServiceList != nil && len(tmpServiceList) > 0 {
					permissionValues := []string{
						"FICC周报", "商品双周报+线上电话会讨论会<br/>（由弘则的研究员主持线上讨论）", "数据点评", "深度月报：包括宏观经济月报和下游草根调研月报+电话会讨论会<br/>（由弘则的研究员主持线上讨论）",
					}
					for _, item := range tmpServiceList {
						//ficc小套餐
						if item.ServiceTemplateId == 2 {
							for _, detail := range item.DetailList {
								var tableCel request.AddContractServiceDetailReq
								tmpErr := json.Unmarshal([]byte(detail.Col1), &tableCel)
								if tmpErr != nil {
									err = tmpErr
									return
								}
								if tableCel.Value == "商品复盘" {
									var tableCel2 request.AddContractServiceDetailReq
									//获取品种列数据
									tmpErr := contractService.GetProductCelData(*detail, &tableCel2)
									if tmpErr != nil {
										err = tmpErr
										return
									}
									//tableCel2.Tag
									for _, serviceId := range tableCel2.ValueId {
										key := fmt.Sprint(item.ServiceTemplateId, "_product_permission_", serviceId)
										if cellI, ok := serviceCellMap[key]; ok {
											cellServiceMap[cellI] = "是"
										}
									}

								} else if strings.Contains(strings.Join(permissionValues, ","), tableCel.Value) {
									//获取品种列数据
									var tableCel2 request.AddContractServiceDetailReq
									tmpErr := contractService.GetProductCelData(*detail, &tableCel2)
									if tmpErr != nil {
										err = tmpErr
										return
									}
									for _, serviceId := range tableCel2.ValueId {
										key := fmt.Sprint(item.ServiceTemplateId, "_permission_", serviceId)
										if cellI, ok := serviceCellMap[key]; ok {
											cellServiceMap[cellI] = "是"
										}
									}
								}
							}
						} else {
							key := fmt.Sprint("service_template_", item.ServiceTemplateId)
							if cellI, ok := serviceCellMap[key]; ok {
								cellServiceMap[cellI] = "是"
							}
						}
					}
				}

				//遍历所有套餐
				for tmpStartCellI := customStartCellI; tmpStartCellI < startI; tmpStartCellI++ {
					servicesCell := dataRow.AddCell()
					cellValue, ok := cellServiceMap[tmpStartCellI]
					if ok == false {
						cellValue = "否"
					}
					servicesCell.SetValue(cellValue)
					if cellValue == "是" { //勾选了话，标红处理
						servicesCell.SetStyle(redStyle)
					} else {
						servicesCell.SetStyle(style)
					}
				}
			}

		}
	}
	err = xlsxFile.Save(downLoadnFilePath)
	if err != nil {
		br.Msg = "保存文件失败"
		br.ErrMsg = "保存文件失败"
		return
	}
	randStr := time.Now().Format(utils.FormatDateTimeUnSpace)
	downloadFileName := "合同列表" + randStr + ".xlsx"
	this.Ctx.Output.Download(downLoadnFilePath, downloadFileName)
	br.Ret = 200
	br.Success = true
	br.Msg = "导出成功"
}

// OperationList
// @Title 获取合同操作记录
// @Description 合同操作记录接口
// @Param   ContractId   query   int  true       "合同id编号"
// @Success 200 {object} response.ContractOperationListResp
// @router /operation/list [get]
func (this *ContractController) OperationList() {
	br := new(models.BaseResponse).Init()
	defer func() {
		this.Data["json"] = br
		this.ServeJSON()
	}()
	sysUser := this.SysUser
	if sysUser == nil {
		br.Msg = "请登录"
		br.ErrMsg = "请登录，SysUser Is Empty"
		br.Ret = 408
		return
	}

	//合同类型、产品类型、合同状态、更新时间、所选销售
	//关键字：合同编号、客户名称，社会信用码
	contractId, err := this.GetInt("ContractId")
	if err != nil {
		br.Msg = "获取合同编号失败"
		br.ErrMsg = "获取合同编号失败，err：" + err.Error()
		return
	}
	if contractId <= 0 {
		br.Msg = "请传入合同编号"
		br.ErrMsg = "请传入合同编号"
		return
	}

	list, err := contract.GetContractOperationRListByContractId(contractId)
	if err != nil {
		br.Msg = "获取合同操作记录列表失败！"
		br.ErrMsg = "获取合同操作记录列表失败，Err:" + err.Error()
		return
	}
	contractOperationRecordList := make([]response.ContractOperationRecordListResp, 0)
	for i := 0; i < len(list); i++ {
		contractOperationRecord := response.ContractOperationRecordListResp{
			Id:               list[i].Id,
			ContractId:       list[i].ContractId,
			Operation:        list[i].Operation,
			OpUserId:         list[i].OpUserId,
			OpUserName:       list[i].OpUserName,
			Remark:           list[i].Remark,
			ApprovalRecordId: list[i].ApprovalRecordId,
			CreateTime:       list[i].CreateTime,
			CreateTimeStr:    list[i].CreateTime.Format(utils.FormatDateTime),
		}
		contractOperationRecordList = append(contractOperationRecordList, contractOperationRecord)
	}
	br.Ret = 200
	br.Success = true
	br.Msg = "获取成功"
	br.Data = response.ContractOperationListResp{
		List: contractOperationRecordList,
	}
}

// EditContract
// @Title 编辑合同
// @Description 编辑合同接口
// @Param	request	body request.EditContractReq true "type json string"
// @Success 200 {object} response.AddContractResp
// @router /edit [post]
func (this *ContractController) EditContract() {
	br := new(models.BaseResponse).Init()
	defer func() {
		this.Data["json"] = br
		this.ServeJSON()
	}()
	sysUser := this.SysUser
	if sysUser == nil {
		br.Msg = "请登录"
		br.ErrMsg = "请登录，SysUser Is Empty"
		br.Ret = 408
		return
	}
	productId := services.GetProductId(sysUser.RoleTypeCode)
	if productId == 0 {
		br.Msg = "账户异常"
		br.ErrMsg = "账户异常，当前账户类型为：" + sysUser.RoleTypeCode
		br.Ret = 408
		return
	}
	var req request.EditContractReq
	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
	if err != nil {
		br.Msg = "参数解析异常！"
		br.ErrMsg = "参数解析失败，Err:" + err.Error()
		return
	}
	if req.ContractId <= 0 {
		br.Msg = "合同编号必传！"
		br.ErrMsg = "合同编号必传！"
		return
	}
	// 限制一下合同金额, 目前只支持人民币转大写只支持到千亿, 虽然生产使用中不可能到这么大, 但还是加上吧 =_=!
	maxPrice := float64(1000000000000)
	if req.OriginalPrice >= maxPrice || req.Price >= maxPrice {
		br.Msg = "合同金额过大, 请核验金额"
		return
	}
	contractInfo, err, errMsg := contractService.EditContract(req, sysUser)
	if err != nil {
		br.Msg = "修改合同失败！"
		if errMsg != "" {
			br.Msg = errMsg
		}
		br.ErrMsg = "修改合同失败，Err:" + err.Error()
		return
	}
	msg := "修改成功"
	//如果发起重新审核，那么
	if req.ReAudit {
		tmpErr, errMsg := contractService.Apply(contractInfo.ContractId)
		if tmpErr != nil {
			br.Msg = "发起重申失败！"
			if errMsg != "" {
				br.Msg = errMsg
			}
			br.ErrMsg = "发起重申失败，Err:" + tmpErr.Error()
			return
		}
		msg = "发起重申成功"
	}
	br.Ret = 200
	br.Success = true
	br.Msg = msg
	br.Data = response.AddContractResp{
		ContractId: contractInfo.ContractId,
	}
}

// Delete
// @Title 删除合同
// @Description 删除合同接口
// @Param   ContractId   query   int  true       "合同id"
// @Success Ret=200 删除成功
// @router /delete [get]
func (this *ContractController) Delete() {
	br := new(models.BaseResponse).Init()
	defer func() {
		this.Data["json"] = br
		this.ServeJSON()
	}()
	sysUser := this.SysUser
	if sysUser == nil {
		br.Msg = "请登录"
		br.ErrMsg = "请登录，SysUser Is Empty"
		br.Ret = 408
		return
	}

	contractId, _ := this.GetInt("ContractId")
	//合同id
	if contractId <= 0 {
		br.Msg = "合同id必传！"
		br.ErrMsg = "合同id必传"
		return
	}

	err := contractService.DeleteContract(contractId, sysUser)
	if err != nil {
		br.Msg = "修改合同失败！"
		br.ErrMsg = "修改合同失败，Err:" + err.Error()
		return
	}

	br.Ret = 200
	br.Success = true
	br.Msg = "删除成功"
	return
}

// Invalid
// @Title 作废合同
// @Description 作废合同接口
// @Param   ContractId   query   int  true       "合同id"
// @Success Ret=200 作废成功
// @router /invalid [get]
func (this *ContractController) Invalid() {
	br := new(models.BaseResponse).Init()
	defer func() {
		this.Data["json"] = br
		this.ServeJSON()
	}()
	sysUser := this.SysUser
	if sysUser == nil {
		br.Msg = "请登录"
		br.ErrMsg = "请登录，SysUser Is Empty"
		br.Ret = 408
		return
	}

	contractId, _ := this.GetInt("ContractId")
	//合同id
	if contractId <= 0 {
		br.Msg = "合同id必传！"
		br.ErrMsg = "合同id必传"
		return
	}

	err := contractService.InvalidContract(contractId, sysUser)
	if err != nil {
		br.Msg = "修改合同失败！"
		br.ErrMsg = "修改合同失败，Err:" + err.Error()
		return
	}

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

// UploadCheckBackFile
// @Title 上传签回附件
// @Description 上传签回附件接口
// @Param	request	body request.UploadCheckBackFileReq true "type json string"
// @Success Ret=200 上传成功
// @router /upload_check_back_file [post]
func (this *ContractController) UploadCheckBackFile() {
	br := new(models.BaseResponse).Init()
	defer func() {
		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 request.UploadCheckBackFileReq
	//err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
	//if err != nil {
	//	br.Msg = "参数解析异常！"
	//	br.ErrMsg = "参数解析失败，Err:" + err.Error()
	//	return
	//}
	////合同编号
	//if req.ContractId <= 0 {
	//	br.Msg = "请传入合同编号！"
	//	br.ErrMsg = "请传入合同编号"
	//	return
	//}
	//
	//if req.FileUrl == "" {
	//	br.Msg = "请先上传附件！"
	//	br.ErrMsg = "请先上传附件"
	//	return
	//}

	contractIdStr := this.Ctx.Request.Form.Get("ContractId")
	if contractIdStr == "" {
		br.Msg = "合同ID必传！"
		br.ErrMsg = "合同ID必传，Err"
		return
	}
	contractId, err := strconv.Atoi(contractIdStr)
	if err != nil {
		br.Msg = "合同ID异常！"
		br.ErrMsg = "合同ID异常，Err:" + err.Error()
		return
	}
	fileMulti, h, err := this.GetFile("file")
	if err != nil {
		br.Msg = "获取资源信息失败"
		br.ErrMsg = "获取资源信息失败,Err:" + err.Error()
		return
	}
	//合同编号
	if contractId <= 0 {
		br.Msg = "请传入合同编号！"
		br.ErrMsg = "请传入合同编号"
		return
	}
	ext := path.Ext(h.Filename)
	resourceUrl, err := contractService.UploadCheckBackFile(contractId, ext, fileMulti, this.SysUser)
	if err != nil {
		br.Msg = "更新失败！"
		br.ErrMsg = "更新失败" + err.Error()
		return
	}
	//更新用印中的签回合同
	_, _ = seal.UploadCheckBackFile(contractId, resourceUrl, this.SysUser)

	br.Ret = 200
	br.Success = true
	br.Msg = "上传成功"
}

// UploadRescindFile
// @Title 上传解约附件
// @Description 上传解约附件接口
// @Param	request	body request.UploadRescindFileReq true "type json string"
// @Success Ret=200 上传成功
// @router /upload_rescind_file [post]
func (this *ContractController) UploadRescindFile() {
	br := new(models.BaseResponse).Init()
	defer func() {
		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 request.UploadRescindFileReq
	//err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
	//if err != nil {
	//	br.Msg = "参数解析异常！"
	//	br.ErrMsg = "参数解析失败，Err:" + err.Error()
	//	return
	//}
	////合同编号
	//if req.ContractId <= 0 {
	//	br.Msg = "请传入合同编号！"
	//	br.ErrMsg = "请传入合同编号"
	//	return
	//}
	//
	//if req.FileUrl == "" {
	//	br.Msg = "请先上传附件！"
	//	br.ErrMsg = "请先上传附件"
	//	return
	//}
	contractIdStr := this.Ctx.Request.Form.Get("ContractId")
	if contractIdStr == "" {
		br.Msg = "合同ID必传！"
		br.ErrMsg = "合同ID必传，Err"
		return
	}
	contractId, err := strconv.Atoi(contractIdStr)
	if err != nil {
		br.Msg = "合同ID异常！"
		br.ErrMsg = "合同ID异常，Err:" + err.Error()
		return
	}
	fileMulti, h, err := this.GetFile("file")
	if err != nil {
		br.Msg = "获取资源信息失败"
		br.ErrMsg = "获取资源信息失败,Err:" + err.Error()
		return
	}
	//合同编号
	if contractId <= 0 {
		br.Msg = "请传入合同编号！"
		br.ErrMsg = "请传入合同编号"
		return
	}
	ext := path.Ext(h.Filename)
	err = contractService.UploadRescindFile(contractId, ext, fileMulti, this.SysUser)

	br.Ret = 200
	br.Success = true
	br.Msg = "上传成功"
}

// Detail
// @Title 获取合同详情
// @Description 获取合同详情接口
// @Param   ContractId   query   int  true       "合同id"
// @Success 200 {object} contract.ContractDetail
// @router /detail [get]
func (this *ContractController) Detail() {
	br := new(models.BaseResponse).Init()
	defer func() {
		this.Data["json"] = br
		this.ServeJSON()
	}()
	sysUser := this.SysUser
	if sysUser == nil {
		br.Msg = "请登录"
		br.ErrMsg = "请登录，SysUser Is Empty"
		br.Ret = 408
		return
	}

	//合同类型、产品类型、合同状态、更新时间、所选销售
	//关键字：合同编号、客户名称，社会信用码
	contractId, _ := this.GetInt("ContractId")
	//合同id
	if contractId <= 0 {
		br.Msg = "合同id必传！"
		br.ErrMsg = "合同id必传"
		return
	}
	contractInfo, err := contractService.GetContractDetail(contractId)
	if err != nil {
		br.Msg = "获取合同详情失败！"
		br.ErrMsg = "获取合同详情失败,ERR:" + err.Error()
		return
	}
	// CRM8.8-权益主客观合并
	if contractInfo.ProductId == 2 {
		mergeList := contractService.EquityMergeSubjectAndObject(contractInfo.Service)
		contractInfo.Service = mergeList
		// 关联合同同样合并
		for i, v := range contractInfo.RelationContractDetailList {
			relationMergeList := contractService.EquityMergeSubjectAndObject(v.Service)
			contractInfo.RelationContractDetailList[i].Service = relationMergeList
		}
	}

	contractInfo.StartDateStr = contractInfo.StartDate.Format(utils.FormatDate)
	contractInfo.EndDateStr = contractInfo.EndDate.Format(utils.FormatDate)
	contractInfo.ModifyTimeStr = contractInfo.ModifyTime.Format(utils.FormatDateTime)
	contractInfo.CreateTimeStr = contractInfo.CreateTime.Format(utils.FormatDateTime)

	//合同中包含的产品权限
	isNeedPermission := false //是否需要列出来套餐中的详细权限
	for _, service := range contractInfo.Service {
		if service.ServiceTemplateId == 2 { //小套餐才需要列出来详细的权限
			isNeedPermission = true
		}
	}
	var permissionLookListResp = make([]*contract.PermissionLookList, 0)
	if isNeedPermission {
		checkPermissionMap, tErr := contractService.GetServicePermissionMap(contractInfo.Service)
		if tErr == nil {
			permissionLookListMap := make(map[int][]*contract.PermissionLookItem)
			var permissionIds []string
			for _, v := range checkPermissionMap {
				permissionIds = append(permissionIds, strconv.Itoa(v))
			}
			permissionIdStr := strings.Join(permissionIds, ",")
			charPermissions, tErr1 := company.GetPermissionLookItemsSandO(permissionIdStr)
			if tErr1 == nil {
				for _, v := range charPermissions {
					tmp := new(contract.PermissionLookItem)
					tmp.ClassifyName = v.ClassifyName
					tmp.PermissionName = v.PermissionName
					tmp.ChartPermissionId = v.ChartPermissionId
					permissionLookListMap[v.ParentId] = append(permissionLookListMap[v.ParentId], tmp)
				}
				classifyNameList, tErr2 := company.GetChartPermissionFirst()
				if tErr2 == nil {
					for _, v := range classifyNameList {
						if perList, ok := permissionLookListMap[v.ChartPermissionId]; ok {
							permissionLookListRespItem := &contract.PermissionLookList{
								ClassifyName: v.ClassifyName,
								Items:        perList,
							}
							permissionLookListResp = append(permissionLookListResp, permissionLookListRespItem)
						}
					}
				}
			}
		}
	}
	contractInfo.PermissionLookList = permissionLookListResp
	br.Ret = 200
	br.Success = true
	br.Msg = "获取成功"
	br.Data = contractInfo
}

//Export
//@Title 合同列表数据导出
//@Description 合同列表数据导出接口
//@Description 合同列表接口
//@Param   ContractType   query   string  false       "合同类型，枚举值：'新签合同','续约合同','补充协议'"
//@Param   ContractStatus   query   string  false       "合同状态，枚举值：'待提交','待审批','已撤回','已审批','已驳回','已作废'"
//@Param   ProductId   query   int  false       "客户类型：传0或者不传为当前账号权限,1 代表是：ficc；2 代表是：权益"
//@Param   ModifyStartTime   query   string  false       "服务更新时间的选择开始时间，格式：2021-05-23 00:00:00"
//@Param   ModifyEndTime   query   string  false       "服务更新时间的选择结束时间，格式：2021-05-26 23:59:59"
//@Param   SellerId   query   string  false       "选择的销售id"
//@Param   Keyword   query   string  false       "搜索关键字"
//@Success 200 {object} response.ContractListResp
//@router /export [get]

//func (this *ContractController) Export() {
//	br := new(models.BaseResponse).Init()
//	defer func() {
//		this.Data["json"] = br
//		this.ServeJSON()
//	}()
//	sysUser := this.SysUser
//	if sysUser == nil {
//		br.Msg = "请登录"
//		br.ErrMsg = "请登录，SysUser Is Empty"
//		br.Ret = 408
//		return
//	}
//
//	contractType := this.GetString("ContractType")
//	contractStatus := this.GetString("ContractStatus")
//	productId, _ := this.GetInt("ProductId")
//	modifyStartTime := this.GetString("ModifyStartTime")
//	modifyEndTime := this.GetString("ModifyEndTime")
//	sellerIds := this.GetString("SellerId")
//	keyword := this.GetString("Keyword")
//
//	condition := ""
//	pars := make([]interface{}, 0)
//
//	//如果不是超管或者合规，那么只能查看自己的合同
//	if sysUser.RoleTypeCode == utils.ROLE_TYPE_CODE_FICC_ADMIN {
//		condition += ` AND product_id = 1 AND status not in ("待提交","已撤回") `
//	} else if sysUser.RoleTypeCode == utils.ROLE_TYPE_CODE_RAI_ADMIN {
//		condition += ` AND product_id = 2 AND status not in ("待提交","已撤回") `
//	} else if sysUser.RoleTypeCode == utils.ROLE_TYPE_CODE_ADMIN { //超管可查看所有状态的合同（除过已撤回、待提交状态合同），可下载所有状态的合同
//		condition += ` AND status not in ("待提交","已撤回") `
//	} else {
//		if sysUser.RoleTypeCode != utils.ROLE_TYPE_CODE_COMPLIANCE && sysUser.RoleTypeCode != utils.ROLE_TYPE_CODE_ADMIN {
//			condition += ` AND seller_id = ? `
//			pars = append(pars, sysUser.AdminId)
//		}
//	}
//
//	//需要下载的 产品 切片
//	productSlice := make([]int, 0)
//
//	//合同类型、、更新时间、所选销售
//	//关键字：合同编号、客户名称，社会信用码
//	if contractType != "" {
//		condition += ` AND contract_type = ? `
//		pars = append(pars, contractType)
//	}
//	//合同状态
//	if contractStatus != "" {
//		condition += ` AND status = ? `
//		pars = append(pars, contractStatus)
//	}
//
//	//产品类型
//	if productId > 0 {
//		condition += ` AND product_id = ? `
//		pars = append(pars, productId)
//
//		productSlice = append(productSlice, productId)
//	} else {
//		nowProductId := services.GetProductId(sysUser.RoleTypeCode)
//		if nowProductId > 0 {
//			productSlice = append(productSlice, nowProductId)
//		} else {
//			productSlice = append(productSlice, 1)
//			productSlice = append(productSlice, 2)
//		}
//	}
//	//所选销售
//	if sellerIds != "" {
//		condition += ` AND seller_id IN (` + sellerIds + `) `
//	}
//	//更新开始时间
//	if modifyStartTime != "" {
//		condition += ` AND modify_time >= ? `
//		pars = append(pars, modifyStartTime)
//	}
//	//更新结束时间
//	if modifyEndTime != "" {
//		condition += ` AND modify_time <= ? `
//		pars = append(pars, modifyEndTime)
//	}
//	//关键字
//	if keyword != "" {
//		condition += ` AND (contract_code LIKE '%` + keyword + `%' OR company_name LIKE '%` + keyword + `%' OR credit_code LIKE '%` + keyword + `%' ) `
//	}
//
//	//取 一万 条合同数据
//	list, err := contract.GetContractList(condition, pars, 0, 10000)
//	if err != nil {
//		br.Msg = "获取合同列表失败！"
//		br.ErrMsg = "获取合同列表失败，Err:" + err.Error()
//		return
//	}
//	//获取合同套餐服务列表
//	serviceTemplateList, err := contract.GetAllContractServiceTemplateList()
//	if err != nil {
//		br.Msg = "获取合同套餐服务列表失败！"
//		br.ErrMsg = "获取合同套餐服务列表失败，Err:" + err.Error()
//		return
//	}
//	templateTitleMap := make(map[int]string)
//	for _, serviceTemplate := range serviceTemplateList {
//		templateTitleMap[serviceTemplate.ServiceTemplateId] = serviceTemplate.Title
//	}
//
//	for i := 0; i < len(list); i++ {
//		item := list[i]
//		list[i].StartDateStr = item.StartDate.Format(utils.FormatDate)
//		list[i].EndDateStr = item.EndDate.Format(utils.FormatDate)
//
//		list[i].CreateTimeStr = item.CreateTime.Format(utils.FormatDateTime)
//		list[i].ModifyTimeStr = item.ModifyTime.Format(utils.FormatDateTime)
//
//		//服务列表
//		serviceList, err := contract.GetContractServiceAndDetailList(item.ContractId)
//		if err != nil {
//			br.Msg = "获取失败"
//			br.ErrMsg = "查找合同服务异常，Err:" + err.Error()
//			return
//		}
//		for i := 0; len(serviceList) > i; i++ {
//			if serviceList[i].HasDetail == "是" {
//				list, detailErr := contract.GetContractServiceDetailListByServiceId(serviceList[i].ContractServiceId)
//				if detailErr != nil {
//					br.Msg = "获取失败"
//					br.ErrMsg = "查找合同服务详情异常，Err:" + err.Error()
//					return
//				}
//
//				//套餐名称
//				serviceList[i].DetailList = list
//				if title, ok := templateTitleMap[serviceList[i].ServiceTemplateId]; ok {
//					serviceList[i].Title = title
//				}
//			}
//		}
//		list[i].Service = serviceList
//	}
//
//	//生成excel文件
//	dir, err := os.Executable()
//	exPath := filepath.Dir(dir)
//	downLoadnFilePath := exPath + "/" + time.Now().Format(utils.FormatDateTimeUnSpace) + ".xlsx"
//	xlsxFile := xlsx.NewFile()
//	if err != nil {
//		br.Msg = "生成文件失败"
//		br.ErrMsg = "生成文件失败"
//		return
//	}
//
//	//设置默认字体和文字大小
//	xlsx.SetDefaultFont(12, "宋体")
//
//	//定义边框样式
//	border := xlsx.NewBorder("thin", "thin", "thin", "thin")
//	//定义文字排版样式
//	alignment := xlsx.Alignment{
//		Horizontal: "center",
//		Vertical:   "center",
//		WrapText:   true,
//	}
//
//	//普通样式
//	style := xlsx.NewStyle()
//	style.Alignment = alignment
//	style.ApplyAlignment = true
//	style.Border = *border
//
//	//标红文字，便于查看哪些产品被勾选
//	redStyle := xlsx.NewStyle()
//	redStyle.Alignment = alignment
//	redStyle.ApplyAlignment = true
//	redStyle.Font.Color = "ff0000"
//	//定义底色需要标黄的 单元格颜色
//	redFill := xlsx.Fill{"solid", "ffff00", "ffff00"}
//	redStyle.Fill = redFill
//	redStyle.Border = *border
//
//	//标题样式
//	titleStyle := xlsx.NewStyle()
//	titleFont := xlsx.NewFont(14, "宋体")
//	titleFont.Bold = true
//	titleStyle.Font = *titleFont
//	titleStyle.Alignment = alignment
//	titleStyle.Border = *border
//
//	//titleStyle.ApplyAlignment = true
//
//	//表头
//	headerStyle := xlsx.NewStyle()
//	headerFont := xlsx.NewFont(12, "宋体")
//	headerFont.Bold = true
//	headerStyle.Font = *headerFont
//	headerStyle.Alignment = alignment
//	headerStyle.ApplyAlignment = true
//	headerStyle.Border = *border
//
//	defer func() {
//		os.Remove(downLoadnFilePath)
//	}()
//
//	//遍历所拥有的的产品权限，然后插入到对应的sheet表单中
//	for pidIndex := 0; pidIndex < len(productSlice); pidIndex++ {
//		productId = productSlice[pidIndex]
//		//表单名称
//		sheetName := "合同数据"
//		switch productId {
//		case 1:
//			sheetName = "ficc合同信息"
//		case 2:
//			sheetName = "权益合同信息"
//		}
//		//新增一个sheet表单
//		sheel, err := xlsxFile.AddSheet(sheetName)
//		if err != nil {
//			br.Msg = "新增Sheet失败"
//			br.ErrMsg = "新增Sheet失败,Err:" + err.Error()
//			return
//		}
//		//设置列宽
//		sheel.SetColWidth(0, 0, 28)
//		sheel.SetColWidth(1, 1, 30)
//		sheel.SetColWidth(2, 2, 18)
//		sheel.SetColWidth(3, 3, 18)
//		sheel.SetColWidth(4, 4, 35)
//		sheel.SetColWidth(5, 6, 20)
//		sheel.SetColWidth(7, 7, 40)
//		sheel.SetColWidth(7, 35, 30)
//
//		//标题行
//		titleRow := sheel.AddRow()
//		titleRow.SetHeight(30)
//
//		//合同信息列
//		titleCell := titleRow.AddCell()
//		titleCell.HMerge = 7 //向右合并列数，不包括自身列
//		//遍历去添加需要合并的列
//		for i := 0; i < 7; i++ {
//			titleRow.AddCell()
//		}
//
//		//报表标题名称
//		titleCell.SetValue("合同信息")
//		titleCell.SetStyle(titleStyle)
//
//		startI := 8
//		customStartCellI := 8
//
//		serviceSlice := make([]string, 0)
//		serviceCellMap := make(map[string]int)
//
//		//获取所有套餐列表
//		{
//			serviceList, err := getServiceTemplateList(productId)
//			if err != nil {
//				br.Msg = "查询套餐类型失败"
//				br.ErrMsg = "新增Sheet失败,Err:" + err.Error()
//				return
//			}
//			for i := 0; i < len(serviceList); i++ {
//				//需要向右合并添加的列数
//				addCellNum := 0
//
//				item := serviceList[i]
//				//套餐服务列
//				servicesCell := titleRow.AddCell()
//				//套餐名称
//				servicesCell.SetValue(item.Title)
//				servicesCell.SetStyle(titleStyle)
//
//				//ficc小套餐
//				if item.ServiceTemplateId == 2 {
//					productPermission := make(map[int]string)
//					productPermission[1] = "每日宏观商品复盘"
//					productPermission[2] = "能化专栏《化里化外》"
//					productPermission[3] = "股债日评"
//					productPermission[4] = "黑色专栏《知白守黑》"
//					productPermission[5] = "有色专栏《有声有色》"
//					for id, name := range productPermission {
//						key := fmt.Sprint(item.ServiceTemplateId, "_product_permission_", id)
//						serviceCellMap[key] = startI
//						serviceSlice = append(serviceSlice, name)
//						startI++
//						addCellNum++
//					}
//
//					permissionList := make([]*company.PermissionSetItem, 0)
//					for _, v := range utils.PermissionFiccClassifyArr {
//						items, err := company.GetPermissionSetItems(1, v)
//						if err != nil {
//							br.Msg = "获取失败"
//							br.ErrMsg = "获取权限信息失败，Err:" + err.Error()
//							return
//						}
//						permissionList = append(permissionList, items...)
//					}
//
//					//权限列表
//					for j := 0; j < len(permissionList); j++ {
//						key := fmt.Sprint(item.ServiceTemplateId, "_permission_", permissionList[j].ChartPermissionId)
//						serviceCellMap[key] = startI
//						serviceSlice = append(serviceSlice, permissionList[j].PermissionName)
//						startI++
//						addCellNum++
//					}
//					//因为自己本身有一列了，所以在最后增加列的时候，需要减去自身列
//					addCellNum = addCellNum - 1
//					if addCellNum > 0 {
//						for tmpAddCellNum := 0; tmpAddCellNum < addCellNum; tmpAddCellNum++ {
//							titleRow.AddCell()
//						}
//						servicesCell.HMerge = addCellNum //向右合并列数，不包括自身列
//					}
//					continue
//				} else {
//					if item.Children != nil && len(item.Children) > 0 {
//						for j := 0; j < len(item.Children); j++ {
//							key := fmt.Sprint("service_template_", item.Children[j].ServiceTemplateId)
//							serviceCellMap[key] = startI
//							serviceSlice = append(serviceSlice, item.Children[j].Title)
//							startI++
//							addCellNum++
//						}
//						//因为自己本身有一列了，所以在最后增加列的时候，需要减去自身列
//						addCellNum = addCellNum - 1
//						if addCellNum > 0 {
//							for tmpAddCellNum := 0; tmpAddCellNum < addCellNum; tmpAddCellNum++ {
//								titleRow.AddCell()
//							}
//							servicesCell.HMerge = addCellNum //向右合并列数，不包括自身列
//						}
//					} else {
//						key := fmt.Sprint("service_template_", item.ServiceTemplateId)
//						serviceCellMap[key] = startI
//						serviceSlice = append(serviceSlice, item.Title)
//						startI++
//					}
//				}
//			}
//		}
//
//		//表头
//		headerRow := sheel.AddRow()
//		headerRow.SetHeight(24)
//
//		//合同基础信息
//		{
//			codeHeaderCell := headerRow.AddCell()
//			codeHeaderCell.SetValue("合同编号")
//			codeHeaderCell.SetStyle(headerStyle)
//
//			companyHeaderCell := headerRow.AddCell()
//			companyHeaderCell.SetValue("客户名称")
//			companyHeaderCell.SetStyle(headerStyle)
//
//			typeHeaderCell := headerRow.AddCell()
//			typeHeaderCell.SetValue("合同类型")
//			typeHeaderCell.SetStyle(headerStyle)
//
//			priceHeaderCell := headerRow.AddCell()
//			priceHeaderCell.SetValue("合同金额")
//			priceHeaderCell.SetStyle(headerStyle)
//
//			dateHeaderCell := headerRow.AddCell()
//			dateHeaderCell.SetValue("合同有效期")
//			dateHeaderCell.SetStyle(headerStyle)
//
//			sellerHeaderCell := headerRow.AddCell()
//			sellerHeaderCell.SetValue("销售")
//			sellerHeaderCell.SetStyle(headerStyle)
//
//			statusHeaderCell := headerRow.AddCell()
//			statusHeaderCell.SetValue("合同状态")
//			statusHeaderCell.SetStyle(headerStyle)
//
//			remarkHeaderCell := headerRow.AddCell()
//			remarkHeaderCell.SetValue("备注")
//			remarkHeaderCell.SetStyle(headerStyle)
//		}
//
//		//添加服务套餐名称
//		for _, service := range serviceSlice {
//			cell := headerRow.AddCell()
//			cell.SetValue(service)
//			cell.SetStyle(headerStyle)
//		}
//
//		for _, v := range list {
//			//如果当前合同不是该产品
//			if v.ProductId != productId {
//				continue
//			}
//			dataRow := sheel.AddRow()
//			dataRow.SetHeight(24)
//
//			//合同基础信息
//			{
//				codeCell := dataRow.AddCell()
//				codeCell.SetValue(v.ContractCode)
//				codeCell.SetStyle(style)
//
//				companyCell := dataRow.AddCell()
//				companyCell.SetValue(v.CompanyName)
//				companyCell.SetStyle(style)
//
//				typeCell := dataRow.AddCell()
//				typeCell.SetValue(v.ContractType)
//				typeCell.SetStyle(style)
//
//				priceCell := dataRow.AddCell()
//				priceCell.SetValue(v.Price)
//				priceCell.SetStyle(style)
//
//				dateCell := dataRow.AddCell()
//				dateCell.SetValue(fmt.Sprint(v.StartDate.Format(utils.FormatDate), " 至 ", v.EndDate.Format(utils.FormatDate)))
//				dateCell.SetStyle(style)
//
//				sellerCell := dataRow.AddCell()
//				sellerCell.SetValue(v.SellerName)
//				sellerCell.SetStyle(style)
//
//				statusCell := dataRow.AddCell()
//				statusCell.SetValue(v.Status)
//				statusCell.SetStyle(style)
//
//				//备注：该字段由三部分拼接：服务内容中的补充内容+赠送时间+优惠金额
//				//补充内容直接取该字段内容；
//				//赠送时间以年为单位，超过整年的月份作为赠送月份，如14个月即为赠送2个月；
//				//优惠金额等于原价-优惠后价格=优惠价格
//
//				//补充内容
//				var remark string
//				if v.Remark != "" {
//					remark += "补充内容：" + v.Remark
//				}
//
//				//赠送时间
//				//合同结束日期与合同开始日期的时间差（小时差）
//				newDecimal := decimal.NewFromFloat(v.EndDate.Sub(v.StartDate).Hours())
//				//分母为365天 * 24 小时
//				newDecimal2 := decimal.NewFromInt(24 * 365)
//				//计算出来相差多少年，保留一位小数（四舍五入）
//				numYearDecimal := newDecimal.Div(newDecimal2).Round(1).Mul(decimal.NewFromInt(10))
//				//如果大于1年，那么才去判断是否赠送
//				numYear, _ := numYearDecimal.Float64()
//				if numYear > 10 {
//					//获取多出来的整数年数据
//					numYearDecimal = numYearDecimal.Mod(decimal.NewFromInt(10)).Div(decimal.NewFromInt(10))
//					//计算赠送出来的月份
//					numMonthDecimal := numYearDecimal.Mul(decimal.NewFromInt(12)).Round(0)
//					numMonth, _ := numMonthDecimal.Float64()
//					if numMonth > 0 {
//						if remark != "" {
//							remark += "；"
//						}
//						remark += "赠送时间为：" + numMonthDecimal.String() + "个月"
//					}
//				}
//				//优惠金额
//				if v.OriginalPrice > v.Price {
//					differencePrice := v.OriginalPrice - v.Price
//					differencePriceDecimal := decimal.NewFromFloat(differencePrice)
//
//					if remark != "" {
//						remark += "；"
//					}
//					remark += "优惠金额：" + differencePriceDecimal.String() + "元。"
//				}
//				remarkCell := dataRow.AddCell()
//				remarkCell.SetValue(remark)
//				remarkCell.SetStyle(style)
//			}
//
//			//服务套餐
//			{
//				cellServiceMap := make(map[int]string)
//				for _, cellI := range serviceCellMap {
//					cellServiceMap[cellI] = "否"
//				}
//
//				if v.Service != nil && len(v.Service) > 0 {
//					permissionValues := []string{
//						"FICC周报", "商品双周报+线上电话会讨论会<br/>（由弘则的研究员主持线上讨论）", "数据点评", "深度月报：包括宏观经济月报和下游草根调研月报+电话会讨论会<br/>（由弘则的研究员主持线上讨论）",
//					}
//					for _, item := range v.Service {
//						//ficc小套餐
//						if item.ServiceTemplateId == 2 {
//							for _, detail := range item.DetailList {
//								var tableCel request.AddContractServiceDetailReq
//								tmpErr := json.Unmarshal([]byte(detail.Col1), &tableCel)
//								if tmpErr != nil {
//									err = tmpErr
//									return
//								}
//								if tableCel.Value == "商品复盘" {
//									var tableCel2 request.AddContractServiceDetailReq
//									//获取品种列数据
//									tmpErr := contractService.GetProductCelData(*detail, &tableCel2)
//									if tmpErr != nil {
//										err = tmpErr
//										return
//									}
//									//tableCel2.Tag
//									for _, serviceId := range tableCel2.ValueId {
//										key := fmt.Sprint(item.ServiceTemplateId, "_product_permission_", serviceId)
//										if cellI, ok := serviceCellMap[key]; ok {
//											cellServiceMap[cellI] = "是"
//										}
//									}
//
//								} else if strings.Contains(strings.Join(permissionValues, ","), tableCel.Value) {
//									//获取品种列数据
//									var tableCel2 request.AddContractServiceDetailReq
//									tmpErr := contractService.GetProductCelData(*detail, &tableCel2)
//									if tmpErr != nil {
//										err = tmpErr
//										return
//									}
//									for _, serviceId := range tableCel2.ValueId {
//										key := fmt.Sprint(item.ServiceTemplateId, "_permission_", serviceId)
//										if cellI, ok := serviceCellMap[key]; ok {
//											cellServiceMap[cellI] = "是"
//										}
//									}
//								}
//							}
//						} else {
//							key := fmt.Sprint("service_template_", item.ServiceTemplateId)
//							if cellI, ok := serviceCellMap[key]; ok {
//								cellServiceMap[cellI] = "是"
//							}
//						}
//					}
//				}
//
//				//遍历所有套餐
//				for tmpStartCellI := customStartCellI; tmpStartCellI < startI; tmpStartCellI++ {
//					servicesCell := dataRow.AddCell()
//					cellValue, ok := cellServiceMap[tmpStartCellI]
//					if ok == false {
//						cellValue = "否"
//					}
//					servicesCell.SetValue(cellValue)
//					if cellValue == "是" { //勾选了话，标红处理
//						servicesCell.SetStyle(redStyle)
//					} else {
//						servicesCell.SetStyle(style)
//					}
//				}
//			}
//
//		}
//	}
//	err = xlsxFile.Save(downLoadnFilePath)
//	if err != nil {
//		br.Msg = "保存文件失败"
//		br.ErrMsg = "保存文件失败"
//		return
//	}
//	randStr := time.Now().Format(utils.FormatDateTimeUnSpace)
//	downloadFileName := "合同列表" + randStr + ".xlsx"
//	this.Ctx.Output.Download(downLoadnFilePath, downloadFileName)
//	br.Ret = 200
//	br.Success = true
//	br.Msg = "导出成功"
//}

// Preview
// @Title 预览合同
// @Description 预览合同接口v
// @Param	request	body request.AddContractReq true "type json string"
// @Success 200 {object} response.ContractPreviewResp
// @router /preview [post]
func (this *ContractController) Preview() {
	br := new(models.BaseResponse).Init()
	defer func() {
		this.Data["json"] = br
		this.ServeJSON()
	}()
	sysUser := this.SysUser
	if sysUser == nil {
		br.Msg = "请登录"
		br.ErrMsg = "请登录，SysUser Is Empty"
		br.Ret = 408
		return
	}
	productId := services.GetProductId(sysUser.RoleTypeCode)
	if productId == 0 {
		br.Msg = "账户异常"
		br.ErrMsg = "账户异常，当前账户类型为：" + sysUser.RoleTypeCode
		br.Ret = 408
		return
	}

	var req request.AddContractReq
	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
	if err != nil {
		br.Msg = "参数解析异常！"
		br.ErrMsg = "参数解析失败，Err:" + err.Error()
		return
	}
	// 限制一下合同金额, 目前只支持人民币转大写只支持到千亿, 虽然生产使用中不可能到这么大, 但还是加上吧 =_=!
	maxPrice := float64(1000000000000)
	if req.OriginalPrice >= maxPrice || req.Price >= maxPrice {
		br.Msg = "合同金额过大, 请核验金额"
		return
	}
	contractInfo, err := contractService.GetContractDetailByAddContractReq(req, sysUser.AdminId, productId, sysUser.RealName)
	if err != nil {
		br.Msg = "获取合同数据失败！"
		br.ErrMsg = "获取合同数据失败，Err:" + err.Error()
		return
	}
	// CMR8.8-合并权益主客观
	if contractInfo.ProductId == 2 {
		mergeList := contractService.EquityMergeSubjectAndObject(contractInfo.Service)
		contractInfo.Service = mergeList
	}
	contractHtml, err := services.GetHtmlByContractDetail(contractInfo, "html")
	if err != nil {
		br.Msg = "生成预览合同失败！"
		br.ErrMsg = "生成预览合同失败，Err:" + err.Error()
		return
	}

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

	br.Data = response.ContractPreviewResp{
		Html: contractHtml,
	}
}

// PreviewByContractId
// @Title 预览合同
// @Description 预览合同接口
// @Param   ContractId   query   int  true       "合同id"
// @Success 200 {object} response.ContractPreviewResp
// @router /previewByContractId [get]
func (this *ContractController) PreviewByContractId() {
	br := new(models.BaseResponse).Init()
	defer func() {
		this.Data["json"] = br
		this.ServeJSON()
	}()
	sysUser := this.SysUser
	if sysUser == nil {
		br.Msg = "请登录"
		br.ErrMsg = "请登录，SysUser Is Empty"
		br.Ret = 408
		return
	}

	contractId, _ := this.GetInt("ContractId")
	//合同id
	if contractId <= 0 {
		br.Msg = "合同id必传！"
		br.ErrMsg = "合同id必传"
		return
	}
	contractInfo, err := contractService.GetContractDetail(contractId)
	if err != nil {
		br.Msg = "获取合同详情失败！"
		br.ErrMsg = "获取合同详情失败,ERR:" + err.Error()
		return
	}
	// 限制一下合同金额, 目前只支持人民币转大写只支持到千亿, 虽然生产使用中不可能到这么大, 但还是加上吧 =_=!
	maxPrice := float64(1000000000000)
	if contractInfo.OriginalPrice >= maxPrice || contractInfo.Price >= maxPrice {
		br.Msg = "合同金额过大, 请核验金额"
		return
	}
	// CMR8.8-合并权益主客观
	if contractInfo.ProductId == 2 {
		mergeList := contractService.EquityMergeSubjectAndObject(contractInfo.Service)
		contractInfo.Service = mergeList
	}
	contractHtml, err := services.GetHtmlByContractDetail(contractInfo, "html")
	if err != nil {
		br.Msg = "生成预览合同失败！"
		br.ErrMsg = "生成预览合同失败，Err:" + err.Error()
		return
	}
	br.Ret = 200
	br.Success = true
	br.Msg = "获取成功"
	br.Data = response.ContractPreviewResp{
		Html: contractHtml,
	}
}

// DownLoadTmpContract
// @Title 下载临时合同
// @Description 下载临时合同接口
// @Param   ContractId   query   int  true       "合同id"
// @router /downLoad/tmpContract [get]
func (this *ContractController) DownLoadTmpContract() {
	br := new(models.BaseResponse).Init()
	defer func() {
		this.Data["json"] = br
		this.ServeJSON()
	}()
	sysUser := this.SysUser
	if sysUser == nil {
		br.Msg = "请登录"
		br.ErrMsg = "请登录，SysUser Is Empty"
		br.Ret = 408
		return
	}

	//合同类型、产品类型、合同状态、更新时间、所选销售
	//关键字：合同编号、客户名称，社会信用码
	contractId, _ := this.GetInt("ContractId")
	//合同id
	if contractId <= 0 {
		br.Msg = "合同id必传！"
		br.ErrMsg = "合同id必传"
		return
	}
	contractInfo, err := contractService.GetContractDetail(contractId)
	if err != nil {
		br.Msg = "获取合同详情失败！"
		br.ErrMsg = "获取合同详情失败,ERR:" + err.Error()
		return
	}
	// 限制一下合同金额, 目前只支持人民币转大写只支持到千亿, 虽然生产使用中不可能到这么大, 但还是加上吧 =_=!
	maxPrice := float64(1000000000000)
	if contractInfo.OriginalPrice >= maxPrice || contractInfo.Price >= maxPrice {
		br.Msg = "合同金额过大, 请核验金额"
		return
	}
	// CMR8.8-合并权益主客观
	if contractInfo.ProductId == 2 {
		mergeList := contractService.EquityMergeSubjectAndObject(contractInfo.Service)
		contractInfo.Service = mergeList
	}

	//合同下载权限校验
	if (sysUser.RoleTypeCode == utils.ROLE_TYPE_CODE_FICC_SELLER || sysUser.RoleTypeCode == utils.ROLE_TYPE_CODE_RAI_SELLER) && contractInfo.SellerId != sysUser.AdminId {
		br.Msg = "合同异常！"
		br.ErrMsg = "合同异常"
		return
	}
	//contractHtml, tmpErr := services.GetHtmlByContractDetail(contractInfo, "pdf")
	//if tmpErr != nil {
	//	err = tmpErr
	//	return
	//}

	//生成pdf
	//pdfPath := fmt.Sprint("./static/word/系统生成合同_", contractId, ".pdf")
	//tmpErr = services.Html2Pdf(contractHtml, pdfPath)
	//if tmpErr != nil {
	//	err = tmpErr
	//	return
	//}
	//defer func() {
	//	os.Remove(pdfPath)
	//}()
	//downloadFileName := "合同草稿_" + contractInfo.ContractCode + ".pdf"

	wordPath := fmt.Sprint("./static/word/系统生成合同_", contractId, ".docx")
	tmpErr := services.GenerateWordV2(contractInfo, wordPath)
	if tmpErr != nil {
		err = tmpErr
		return
	}
	defer func() {
		os.Remove(wordPath)
	}()

	downloadFileName := contractInfo.CompanyName + "_" + contractInfo.ContractCode + "(草稿).docx"
	this.Ctx.Output.Download(wordPath, downloadFileName)
	br.Ret = 200
	br.Success = true
	br.Msg = "下载成功"
}

// getServiceTemplateList 获取系统服务列表
func getServiceTemplateList(productId int) (list []*contract.ContractServiceTemplateMapItems, err error) {
	list, err = contract.GetContractServiceTemplateMapByProductId(productId)
	if err != nil {

		return
	}
	for i := 0; i < len(list); i++ {
		item := list[i]
		tmpList, tmpErr := contract.GetContractServiceTemplateMapByParentId(item.ServiceTemplateId)
		if tmpErr != nil {
			err = tmpErr
			return
		}
		for j := 0; j < len(tmpList); j++ {
			detail, tmpErr := contract.GetContractServiceDetailByTemplateId(tmpList[j].ServiceTemplateId)
			if tmpErr != nil {
				err = tmpErr
				return
			}
			tmpList[j].Detail = detail
		}
		detail, tmpErr := contract.GetContractServiceDetailByTemplateId(list[i].ServiceTemplateId)
		if tmpErr != nil {
			err = tmpErr
			return
		}
		list[i].Detail = detail

		list[i].Children = tmpList
	}
	return
}

// BusinessContractCompanyList
// @Title 业务合同客户名称列表
// @Description 业务合同客户名称列表接口
// @Param   Keyword   query   string  true       "搜索关键字"
// @Success 200 {object} []string
// @router /business_contract/company_name/list/ [get]
func (this *ContractController) BusinessContractCompanyList() {
	br := new(models.BaseResponse).Init()
	defer func() {
		this.Data["json"] = br
		this.ServeJSON()
	}()
	sysUser := this.SysUser
	if sysUser == nil {
		br.Msg = "请登录"
		br.ErrMsg = "请登录，SysUser Is Empty"
		br.Ret = 408
		return
	}
	condition := ""
	pars := make([]interface{}, 0)

	condition += ` AND a.contract_business_type ="业务合同" AND a.status ="已签回" `
	//如果不是超管或者合规，那么只能查看自己的合同
	//if sysUser.RoleTypeCode == utils.ROLE_TYPE_CODE_FICC_ADMIN {
	//	condition += ` AND a.product_id = 1 `
	//} else if sysUser.RoleTypeCode == utils.ROLE_TYPE_CODE_RAI_ADMIN {
	//	condition += ` AND product_id = 2 `
	//} else {
	//	if sysUser.RoleTypeCode != utils.ROLE_TYPE_CODE_COMPLIANCE && sysUser.RoleTypeCode != utils.ROLE_TYPE_CODE_ADMIN {
	//		condition += ` AND a.seller_id = ? `
	//		pars = append(pars, sysUser.AdminId)
	//	}
	//}
	condition += ` AND a.seller_id = ? `
	pars = append(pars, sysUser.AdminId)

	//关键字
	keyword := this.GetString("Keyword")
	keyword = strings.TrimSpace(keyword)
	if keyword == "" {
		br.Msg = "请输入客户名称"
		br.ErrMsg = "请输入客户名称"
		return
	}
	kw := fmt.Sprint("%", keyword, "%")
	condition += ` AND (contract_code LIKE ? OR company_name LIKE ? OR credit_code LIKE ? ) `
	pars = append(pars, kw, kw, kw)

	list, err := contract.GetContractCompanyNameList(condition, pars)
	if err != nil {
		br.Msg = "获取合同列表失败！"
		br.ErrMsg = "获取合同列表失败，Err:" + err.Error()
		return
	}

	companyNameList := make([]string, 0)
	for _, v := range list {
		companyNameList = append(companyNameList, v.CompanyName)
	}

	// 13.6正式共享客户的处理
	{
		// 通过关键词获取分配给当前销售的正式共享客户
		cond := ` AND share_seller_id = ? AND is_share = 1 AND company_name LIKE ?`
		pars := make([]interface{}, 0)
		pars = append(pars, sysUser.AdminId, kw)
		shares, e := company.GetCompanyProductList(cond, pars)
		if e != nil {
			br.Msg = "获取失败"
			br.ErrMsg = "获取共享客户信息失败, Err: " + e.Error()
			return
		}
		for _, v := range shares {
			if !utils.InArrayByStr(companyNameList, v.CompanyName) {
				companyNameList = append(companyNameList, v.CompanyName)
			}
		}
	}

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

// BusinessContractListByCompanyName
// @Title 根据客户名称获取所有已签回的业务合同列表
// @Description 根据客户名称获取所有已签回的业务合同列表接口
// @Param   CompanyName   query   string  false       "客户名称"
// @Success 200 {object} response.ContractListResp
// @router /business_contract/list/ [get]
func (this *ContractController) BusinessContractListByCompanyName() {
	br := new(models.BaseResponse).Init()
	defer func() {
		this.Data["json"] = br
		this.ServeJSON()
	}()
	sysUser := this.SysUser
	if sysUser == nil {
		br.Msg = "请登录"
		br.ErrMsg = "请登录，SysUser Is Empty"
		br.Ret = 408
		return
	}

	condition := ""
	pars := make([]interface{}, 0)

	condition += ` AND a.contract_business_type ="业务合同" AND a.status ="已签回" and a.price>a.paid_price `
	//如果不是超管或者合规，那么只能查看自己的合同
	//if sysUser.RoleTypeCode == utils.ROLE_TYPE_CODE_FICC_ADMIN {
	//	condition += ` AND a.product_id = 1 `
	//} else if sysUser.RoleTypeCode == utils.ROLE_TYPE_CODE_RAI_ADMIN {
	//	condition += ` AND product_id = 2 `
	//} else {
	//	if sysUser.RoleTypeCode != utils.ROLE_TYPE_CODE_COMPLIANCE && sysUser.RoleTypeCode != utils.ROLE_TYPE_CODE_ADMIN {
	//		condition += ` AND a.seller_id = ? `
	//		pars = append(pars, sysUser.AdminId)
	//	}
	//}
	//condition += ` AND a.seller_id = ? `
	//pars = append(pars, sysUser.AdminId)

	// 13.6正式共享客户-可以选择分配给自己的共享客户下的非自己创建的合同
	joinStr := ` LEFT JOIN company_product AS b ON a.company_name = b.company_name `
	condition += ` AND (a.seller_id = ? OR (b.is_share = 1 AND b.share_seller_id = ?))`
	pars = append(pars, sysUser.AdminId, sysUser.AdminId)

	//关键字
	companyName := this.GetString("CompanyName")
	if companyName == "" {
		br.Msg = "请输入客户名称"
		br.ErrMsg = "请输入客户名称"
		return
	}
	condition += ` AND a.company_name = ? `
	pars = append(pars, companyName)

	pageSize, _ := this.GetInt("PageSize")
	currentIndex, _ := this.GetInt("CurrentIndex")

	var startSize int
	if pageSize <= 0 {
		pageSize = utils.PageSize20
	}
	if currentIndex <= 0 {
		currentIndex = 1
	}
	startSize = paging.StartIndex(currentIndex, pageSize)

	total, err := contract.GetContractListCount(condition, joinStr, pars)
	if err != nil {
		br.Msg = "获取失败"
		br.ErrMsg = "获取数据总数失败，Err:" + err.Error()
		return
	}

	list, err := contract.GetContractList(condition, joinStr, pars, startSize, pageSize)
	if err != nil {
		br.Msg = "获取合同列表失败！"
		br.ErrMsg = "获取合同列表失败，Err:" + err.Error()
		return
	}
	//获取合同套餐服务列表
	serviceTemplateList, err := contract.GetAllContractServiceTemplateList()
	if err != nil {
		br.Msg = "获取合同套餐服务列表失败！"
		br.ErrMsg = "获取合同套餐服务列表失败，Err:" + err.Error()
		return
	}
	templateTitleMap := make(map[int]string)
	for _, serviceTemplate := range serviceTemplateList {
		templateTitleMap[serviceTemplate.ServiceTemplateId] = serviceTemplate.Title
	}

	//业务合同的关联合同id集合
	businessContractIdList := make([]string, 0)
	//代付合同的关联合同id集合
	paymentOnBehalfContractIdList := make([]string, 0)

	//基础合同的关联合同数据
	contractRelationMap := make(map[int][]*contract.RelationContractList)

	for _, v := range list {
		switch v.ContractBusinessType {
		case "业务合同":
			businessContractIdList = append(businessContractIdList, fmt.Sprint(v.ContractId))
		case "代付合同":
			paymentOnBehalfContractIdList = append(paymentOnBehalfContractIdList, fmt.Sprint(v.ContractId))
		}
	}

	//业务合同的关联合同
	if len(businessContractIdList) > 0 {
		contractIdStr := strings.Join(businessContractIdList, ",")
		businessContractList, err := contract.GetContractRelationListByRelationContractIds(contractIdStr)
		if err != nil {
			br.Msg = "获取失败"
			br.ErrMsg = "获取业务关联合同失败，Err:" + err.Error()
			return
		}
		for _, v := range businessContractList {
			if _, ok := contractRelationMap[v.ContractId]; ok {
				contractRelationMap[v.ContractId] = append(contractRelationMap[v.ContractId], v)
			} else {
				tmpList := make([]*contract.RelationContractList, 0)
				contractRelationMap[v.ContractId] = append(tmpList, v)
			}
		}
	}

	//代付合同的关联合同
	if len(paymentOnBehalfContractIdList) > 0 {
		paymentOnBehalfContractIdStr := strings.Join(paymentOnBehalfContractIdList, ",")
		paymentOnBehalfContractList, err := contract.GetContractRelationListByPaymentOnBehalfContractIds(paymentOnBehalfContractIdStr)
		if err != nil {
			br.Msg = "获取失败"
			br.ErrMsg = "获取代付关联合同失败，Err:" + err.Error()
			return
		}
		for _, v := range paymentOnBehalfContractList {
			if _, ok := contractRelationMap[v.PaymentOnBehalfContractId]; ok {
				contractRelationMap[v.PaymentOnBehalfContractId] = append(contractRelationMap[v.PaymentOnBehalfContractId], v)
			} else {
				tmpList := make([]*contract.RelationContractList, 0)
				contractRelationMap[v.PaymentOnBehalfContractId] = append(tmpList, v)
			}
		}
	}

	for i := 0; i < len(list); i++ {
		//合同操作权限
		var opButton contract.ContractOpButton

		item := list[i]
		list[i].StartDateStr = item.StartDate.Format(utils.FormatDate)
		list[i].EndDateStr = item.EndDate.Format(utils.FormatDate)

		list[i].CreateTimeStr = item.CreateTime.Format(utils.FormatDateTime)
		list[i].ModifyTimeStr = item.ModifyTime.Format(utils.FormatDateTime)
		list[i].ApproveTimeStr = item.ApproveTime.Format(utils.FormatDateTime)
		list[i].InvalidTimeStr = item.InvalidTime.Format(utils.FormatDateTime)
		list[i].CheckBackFileTimeStr = item.CheckBackFileTime.Format(utils.FormatDateTime)
		list[i].RescindTimeStr = item.RescindTime.Format(utils.FormatDateTime)

		//服务列表
		serviceList, err := contract.GetContractServiceAndDetailList(item.ContractId)
		if err != nil {
			br.Msg = "获取失败"
			br.ErrMsg = "查找合同服务异常，Err:" + err.Error()
			return
		}
		for i := 0; len(serviceList) > i; i++ {
			if serviceList[i].HasDetail == "是" {
				list, detailErr := contract.GetContractServiceDetailListByServiceId(serviceList[i].ContractServiceId)
				if detailErr != nil {
					br.Msg = "获取失败"
					br.ErrMsg = "查找合同服务详情异常，Err:" + err.Error()
					return
				}

				//套餐名称
				serviceList[i].DetailList = list
				if title, ok := templateTitleMap[serviceList[i].ServiceTemplateId]; ok {
					serviceList[i].Title = title
				}
			}
		}
		list[i].Service = serviceList

		if item.Status == "待审批" {
			approvalInfo, tmpErr := contract.GetLastContractApprovalByContractId(item.ContractId, "contract")
			if tmpErr != nil {
				//err= tmpErr
				//return
				continue
			}
			//如果合同归属是当前账号，且处于第一级审批
			if item.SellerId == sysUser.AdminId && approvalInfo.CurrNodeId == approvalInfo.StartNodeId {
				opButton.Cancel = true
			}
		}
		list[i].OpButton = opButton

		if relationContractList, ok := contractRelationMap[item.ContractId]; ok {
			list[i].RelationContractList = relationContractList
		}
	}

	page := paging.GetPaging(currentIndex, pageSize, total)

	br.Ret = 200
	br.Success = true
	br.Msg = "获取成功"
	br.Data = response.ContractListResp{
		List:   list,
		Paging: page,
	}
	return
}

// UpdateFile
// @Title 更新合同附件（用于非标）
// @Description 更新合同附件接口
// @Param	request	body request.UploadFileReq true "type json string"
// @Success Ret=200 上传成功
// @router /update_file [post]
func (this *ContractController) UpdateFile() {
	br := new(models.BaseResponse).Init()
	defer func() {
		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 request.UploadFileReq
	//err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
	//if err != nil {
	//	br.Msg = "参数解析异常！"
	//	br.ErrMsg = "参数解析失败，Err:" + err.Error()
	//	return
	//}
	contractIdStr := this.Ctx.Request.Form.Get("ContractId")
	if contractIdStr == "" {
		br.Msg = "合同ID必传！"
		br.ErrMsg = "合同ID必传，Err"
		return
	}
	contractId, err := strconv.Atoi(contractIdStr)
	if err != nil {
		br.Msg = "合同ID异常！"
		br.ErrMsg = "合同ID异常，Err:" + err.Error()
		return
	}
	fileMulti, h, err := this.GetFile("file")
	if err != nil {
		br.Msg = "获取资源信息失败"
		br.ErrMsg = "获取资源信息失败,Err:" + err.Error()
		return
	}
	//合同编号
	if contractId <= 0 {
		br.Msg = "请传入合同编号！"
		br.ErrMsg = "请传入合同编号"
		return
	}
	ext := path.Ext(h.Filename)

	err = contractService.UploadFile(contractId, ext, fileMulti, this.SysUser)

	br.Ret = 200
	br.Success = true
	br.Msg = "上传成功"
}

// GetListBySeal
// @Title 获取用印所需合同列表
// @Description 获取用印所需合同列表
// @Param   Keyword   query   string  false       "搜索关键字"
// @Success 200 {object} response.ContractListBySealResp
// @router /getListBySeal [get]
func (this *ContractController) GetListBySeal() {
	br := new(models.BaseResponse).Init()
	defer func() {
		this.Data["json"] = br
		this.ServeJSON()
	}()
	sysUser := this.SysUser
	if sysUser == nil {
		br.Msg = "请登录"
		br.ErrMsg = "请登录，SysUser Is Empty"
		br.Ret = 408
		return
	}

	keyword := this.GetString("Keyword")
	condition := ` AND a.status = "已审批"`
	pars := make([]interface{}, 0)
	if keyword != "" {
		kw := fmt.Sprint("%", keyword, "%")
		condition += ` AND (a.company_name LIKE ?) `
		pars = append(pars, kw)
	}

	// 13.6正式共享客户
	joinStr := ` LEFT JOIN company_product AS b ON a.company_name = b.company_name `
	// 非合规角色可查看自己的合同或是自己的共享客户下的非自己创建的合同
	if sysUser.RoleTypeCode != utils.ROLE_TYPE_CODE_COMPLIANCE {
		condition += ` AND (a.seller_id = ? OR (b.is_share = 1 AND b.share_seller_id = ?))`
		pars = append(pars, sysUser.AdminId, sysUser.AdminId)
	}
	list, e := contract.GetContractList(condition, joinStr, pars, 0, 100)
	if e != nil {
		br.Msg = "获取失败"
		br.ErrMsg = "获取合同列表失败, Err:" + e.Error()
		return
	}
	//list, err := contract.GetSearchListBySeal(condition, pars)
	//if err != nil {
	//	br.Msg = "获取失败"
	//	br.ErrMsg = "获取数据失败，Err:" + err.Error()
	//	return
	//}

	newList := make([]response.ContractListBySealResp, 0)
	if len(list) > 0 {
		// 代付合同查询代付用户名称
		contractIdSlice := make([]string, 0)
		for i := 0; i < len(list); i++ {
			if list[i].ContractBusinessType == "代付合同" {
				contractIdSlice = append(contractIdSlice, strconv.Itoa(list[i].ContractId))
			}
		}
		userCompanyNameMap := make(map[int]string, 0)
		if len(contractIdSlice) > 0 {
			contractIdStr := strings.Join(contractIdSlice, ",")
			contractList, err := contract.GetContractRelationListByPaymentOnBehalfContractIds(contractIdStr)
			if err != nil {
				br.Msg = "获取失败"
				br.ErrMsg = "获取代付合同对应的合同数据失败，Err:" + err.Error()
				return
			}
			for i := 0; i < len(contractList); i++ {
				userCompanyNameMap[contractList[i].PaymentOnBehalfContractId] = contractList[i].CompanyName
			}
		}

		for _, item := range list {
			var tempItem response.ContractListBySealResp
			tempItem.ContractId = item.ContractId
			tempItem.ContractCode = item.ContractCode
			tempItem.CompanyName = item.CompanyName
			tempItem.FileUrl = item.FileUrl
			tempItem.Price = item.Price
			tempItem.CreditCode = item.CreditCode
			tempItem.ContractBusinessType = item.ContractBusinessType
			if item.ContractBusinessType == "代付合同" {
				tempItem.ContractType = "代付合同"
				tempItem.UserCompanyName = userCompanyNameMap[item.ContractId]
			} else {
				tempItem.ContractType = item.ContractType
			}
			newList = append(newList, tempItem)
		}
	}

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

// DetailMerge
// @Title 获取合同详情-有套餐合并，用于审批单回显等
// @Description 获取合同详情接口
// @Param   ContractId   query   int  true       "合同id"
// @Success 200 {object} contract.ContractDetail
// @router /detail/merge [get]
func (this *ContractController) DetailMerge() {
	br := new(models.BaseResponse).Init()
	defer func() {
		this.Data["json"] = br
		this.ServeJSON()
	}()
	sysUser := this.SysUser
	if sysUser == nil {
		br.Msg = "请登录"
		br.ErrMsg = "请登录，SysUser Is Empty"
		br.Ret = 408
		return
	}

	//合同类型、产品类型、合同状态、更新时间、所选销售
	//关键字：合同编号、客户名称，社会信用码
	contractId, _ := this.GetInt("ContractId")
	//合同id
	if contractId <= 0 {
		br.Msg = "合同id必传！"
		br.ErrMsg = "合同id必传"
		return
	}
	contractInfo, err := contractService.GetContractDetail(contractId)
	if err != nil {
		br.Msg = "获取合同详情失败！"
		br.ErrMsg = "获取合同详情失败,ERR:" + err.Error()
		return
	}
	// CRM8.8-权益主客观合并
	if contractInfo.ProductId == 2 {
		mergeList := contractService.EquityMergeSubjectAndObject(contractInfo.Service)
		contractInfo.Service = mergeList
		// 关联合同同样合并
		for i, v := range contractInfo.RelationContractDetailList {
			relationMergeList := contractService.EquityMergeSubjectAndObject(v.Service)
			contractInfo.RelationContractDetailList[i].Service = relationMergeList
		}
	}

	contractInfo.StartDateStr = contractInfo.StartDate.Format(utils.FormatDate)
	contractInfo.EndDateStr = contractInfo.EndDate.Format(utils.FormatDate)
	contractInfo.ModifyTimeStr = contractInfo.ModifyTime.Format(utils.FormatDateTime)
	contractInfo.CreateTimeStr = contractInfo.CreateTime.Format(utils.FormatDateTime)

	//合同中包含的产品权限
	isNeedPermission := false //是否需要列出来套餐中的详细权限
	for _, service := range contractInfo.Service {
		if service.ServiceTemplateId == 2 { //小套餐才需要列出来详细的权限
			isNeedPermission = true
		}
	}
	var permissionLookListResp = make([]*contract.PermissionLookList, 0)
	if isNeedPermission {
		checkPermissionMap, tErr := contractService.GetServicePermissionMap(contractInfo.Service)
		if tErr == nil {
			permissionLookListMap := make(map[int][]*contract.PermissionLookItem)
			var permissionIds []string
			for _, v := range checkPermissionMap {
				permissionIds = append(permissionIds, strconv.Itoa(v))
			}
			permissionIdStr := strings.Join(permissionIds, ",")
			charPermissions, tErr1 := company.GetPermissionLookItemsSandO(permissionIdStr)
			if tErr1 == nil {
				for _, v := range charPermissions {
					tmp := new(contract.PermissionLookItem)
					tmp.ClassifyName = v.ClassifyName
					tmp.PermissionName = v.PermissionName
					tmp.ChartPermissionId = v.ChartPermissionId
					permissionLookListMap[v.ParentId] = append(permissionLookListMap[v.ParentId], tmp)
				}
				classifyNameList, tErr2 := company.GetChartPermissionFirst()
				if tErr2 == nil {
					for _, v := range classifyNameList {
						if perList, ok := permissionLookListMap[v.ChartPermissionId]; ok {
							permissionLookListRespItem := &contract.PermissionLookList{
								ClassifyName: v.ClassifyName,
								Items:        perList,
							}
							permissionLookListResp = append(permissionLookListResp, permissionLookListRespItem)
						}
					}
				}
			}
		}
	}
	contractInfo.PermissionLookList = permissionLookListResp
	br.Ret = 200
	br.Success = true
	br.Msg = "获取成功"
	br.Data = contractInfo
}
