package controllers

import (
	"encoding/json"
	"fmt"
	"hongze/hz_crm_api/models"
	"hongze/hz_crm_api/models/company"
	"hongze/hz_crm_api/models/system"
	"hongze/hz_crm_api/services"
	"hongze/hz_crm_api/services/company_apply"
	contractService "hongze/hz_crm_api/services/contract"
	"hongze/hz_crm_api/utils"
	"sort"
	"strconv"
	"strings"
	"time"
)

// ApplyServiceUpdate
// @Title 申请服务更新
// @Description 申请服务更新接口
// @Param	request	body company.CompanyApplyServiceUpdateReq true "type json string"
// @Success Ret=200 申请成功
// @router /apply/service/update [post]
func (this *CompanyApplyController) ApplyServiceUpdate() {
	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 company.CompanyApplyServiceUpdateReq
	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
	if err != nil {
		br.Msg = "参数解析异常！"
		br.ErrMsg = "参数解析失败，Err:" + err.Error()
		return
	}
	if req.CompanyId <= 0 {
		br.Msg = "参数错误"
		br.ErrMsg = "参数错误，客户id小于等于0"
		return
	}
	if req.StartDate == "" {
		br.Msg = "请选择合同开始日期"
		return
	}
	if req.EndDate == "" {
		br.Msg = "请选择合同结束日期"
		return
	}
	if req.Money <= 0 {
		br.Msg = "合同金额不能小于等于0"
	}

	if req.ContractType == "" {
		req.ContractType = "续约合同"
		//br.Msg = "请选择合同类型"
		//return
	}
	if req.PermissionIds == "" {
		br.Msg = "请选择权限"
		br.ErrMsg = "请选择权限"
		return
	}

	roleTypeCode := sysUser.RoleTypeCode
	productId := services.GetProductId(roleTypeCode)
	if productId == 0 {
		br.Msg = "参数错误"
		br.ErrMsg = "客户类型为：" + req.CompanyType
		return
	}
	mapPermissionIdUpgrade := make(map[int]int, 0)
	mapPermissionIdExpensive := make(map[int]int, 0)
	var raicontractType string
	if productId == 2 {
		// CRM13.3改-是否为权益内部人员, 非权益内部人员只能勾选行业不能勾选单独的主客观, 勾选行业(即勾选主观的ID需要加入客观的权限ID)
		isRai, e := services.CheckRaiAdmin(sysUser.AdminId)
		if e != nil {
			br.Msg = "获取失败"
			br.ErrMsg = "判断是否为权益内部人员失败, GetRaiAdmin Err: " + e.Error()
			return
		}

		var permissionIdsNew string
		permissionIdsNew, mapPermissionIdUpgrade, mapPermissionIdExpensive, err = services.CheckCompanyUpgradeV2(req.PermissionIds, isRai)
		if err != nil {
			br.Msg = "获取信息失败"
			br.ErrMsg = "获取主观客观权限信息失败,Err:" + err.Error()
			return
		}
		req.PermissionIds = permissionIdsNew

		//权益的新签合同重新定义，如果合同起始时间在新签合同起始日期 1年之内的，仍为新签合同。
		raicontractType = req.ContractType
		if raicontractType != "新签合同" {
			//startDateTime, _ := time.Parse(utils.FormatDate, req.StartDate)
			//startDateTime = startDateTime.AddDate(-1, 0, 0)
			totalLastYear, err := contractService.GetCompanyContractCountRaiByLastYear(req.CompanyId, req.StartDate)
			if err != nil {
				br.Msg = "获取合同信息失败"
				br.ErrMsg = "获取合同信息失败,Err:" + err.Error()
				return
			}
			if totalLastYear > 0 {
				raicontractType = "新签合同"
			}
		}

	} else {
		permissionStr, err := company.GetPermissionIdById(req.PermissionIds)
		if err != nil {
			br.Msg = "获取信息失败"
			br.ErrMsg = "获取主观客观权限信息失败,Err:" + err.Error()
			return
		}
		req.PermissionIds = permissionStr
	}

	//添加缓存，避免多次点击提交
	{
		deleteCache := true
		cacheKey := "CACHE_COMPANY_APPLY_" + strconv.Itoa(req.CompanyId) + "_" + strconv.Itoa(productId)
		defer func() {
			if deleteCache {
				utils.Rc.Delete(cacheKey)
			}
		}()
		if !utils.Rc.SetNX(cacheKey, 1, 30*time.Second) {
			deleteCache = false
			br.Msg = "系统处理中，请勿重复操作"
			br.ErrMsg = "系统处理中，请勿重复操作" + sysUser.RealName + ";data:" + string(this.Ctx.Input.RequestBody)
			return
		}
	}

	approveRoleTypeCode := ""
	if productId == 1 {
		approveRoleTypeCode = utils.ROLE_TYPE_CODE_FICC_ADMIN
	} else {
		approveRoleTypeCode = utils.ROLE_TYPE_CODE_RAI_ADMIN
	}
	companyProduct, err := company.GetCompanyProductByCompanyIdAndProductId(req.CompanyId, productId)
	if err != nil {
		br.Msg = "获取客户信息失败"
		br.ErrMsg = "获取客户信息失败"
		return
	}
	if companyProduct.Status != utils.COMPANY_STATUS_FORMAL && companyProduct.Status != utils.COMPANY_STATUS_TRY_OUT {
		br.Msg = "客户状态为：" + companyProduct.Status + ";不可进行服务更新申请"
		br.ErrMsg = "客户状态为：" + companyProduct.Status + ";不可进行服务更新申请"
		return
	}

	//客户归属判断-当前销售/咨询组共享销售
	if companyProduct.SellerId != sysUser.AdminId && companyProduct.ShareSellerId != sysUser.AdminId {
		br.Msg = "客户信息异常"
		br.ErrMsg = "客户信息异常，不是当前所属销售，客户所属销售：" + companyProduct.SellerName + ";当前销售:" + sysUser.AdminName
		return
	}
	var approveUserId int
	var approveUserRealName string
	applyMethod := 5 //续约服务
	recordApproveContent := `正式客户申请续约`
	approveContent := `申请续约`
	messageContent := "续约申请单"
	operationRemark := `申请续约`
	operation := "service_update"
	//申请类型：1:试用->正式,2:冻结—>试用,3:试用延期,4:原销售申请领取流失客户，5:正式客户申请服务更新，6：正式客户补充协议
	if req.ContractType == "补充协议" {
		applyMethod = 6 //补充协议
		recordApproveContent = `正式客户新增补充协议`
		approveContent = `新增补充协议`
		messageContent = "补充协议申请单"
		operationRemark = `新增补充协议`
		operation = "add_agreement"
	}

	approveUser, err := company.GetApproveUser(approveRoleTypeCode)
	if err != nil && err.Error() != utils.ErrNoRow() {
		br.Msg = "获取审批信息失败"
		br.ErrMsg = "获取审批人信息失败,Err:" + err.Error()
		return
	}
	if approveUser == nil || (err != nil && err.Error() == utils.ErrNoRow()) {
		br.Msg = "审批用户不存在"
		br.ErrMsg = "审批用户不存在"
		return
	}

	var companyApprovalId int
	if req.CompanyApprovalId <= 0 {
		contractCode, err := company.GetCompanyContractCode()
		if err != nil {
			br.Msg = "生成合同编码失败"
			br.ErrMsg = "生成合同编码失败,Err:" + err.Error()
			return
		}
		//当前是否存在待审批的单子
		nowCompanyApprovalInfo, err := company.GetCompanyApprovalById(req.CompanyId, productId)
		if (err == nil || nowCompanyApprovalInfo != nil) || err != nil && err.Error() != utils.ErrNoRow() {
			br.Msg = "此客户已存在待审批的申请单，请在申请单审批完成后重新提交"
			br.ErrMsg = "此客户已存在待审批的申请单，请在申请单审批完成后重新提交"
			return
		}
		//当前待审批的合同，有且只能存在一条
		//count, err := company.GetCompanyContractApproveCount(req.CompanyId, productId)
		//if err != nil {
		//	br.Msg = "获取信息失败"
		//	br.ErrMsg = "判断是否已存在待审批合同失败,Err:" + err.Error()
		//	return
		//}
		//if count > 0 {
		//	br.Msg = "此客户已提交过申请，请在客户审批列表重新提交"
		//	return
		//}
		contract := new(company.CompanyContract)
		contract.CompanyId = req.CompanyId
		contract.ProductId = productId
		contract.ProductName = companyProduct.ProductName
		contract.CompanyProductId = companyProduct.CompanyProductId
		contract.ContractType = req.ContractType
		contract.RaiContractType = raicontractType
		contract.ContractCode = contractCode
		contract.StartDate = req.StartDate
		contract.EndDate = req.EndDate
		contract.Money = req.Money
		contract.PayMethod = req.PayMethod
		contract.PayChannel = req.PayChannel
		contract.ImgUrl = req.ImgUrl
		contract.Status = 0
		contract.Source = "上传附件"
		contract.CreateTime = time.Now()
		contract.ModifyTime = time.Now()
		contract.PackageType = req.PackageType
		contract.RaiPackageType = req.RaiPackageType
		newId, err := company.AddCompanyContract(contract)
		if err != nil {
			br.Msg = "新增合同失败"
			br.ErrMsg = "新增合同失败,Err:" + err.Error()
			return
		}
		permissionArr := strings.Split(req.PermissionIds, ",")
		permissionMap := make(map[int]int) //权限id的map集合，用来避免重复添加权限校验

		permissionNameMap, err := services.GetPermissionNameMap()
		if err != nil {
			br.Msg = "新增合同失败"
			br.ErrMsg = "获取权限名称失败,Err:" + err.Error()
			return
		}
		for _, v := range permissionArr {
			item := new(company.CompanyContractPermission)
			item.CompanyId = req.CompanyId
			item.CompanyContractId = int(newId)

			chartPermissionId, tmpErr := strconv.Atoi(v)
			if tmpErr != nil {
				err = tmpErr
				return
			}

			//权限id判断，避免重复添加权限
			if _, ok := permissionMap[chartPermissionId]; ok {
				continue
			}
			permissionMap[chartPermissionId] = chartPermissionId

			item.ChartPermissionId = chartPermissionId
			item.PermissionName = permissionNameMap[chartPermissionId]
			//如果是研选扣点包的权限，写入扣点点数
			if chartPermissionId == utils.YAN_XUAN_KOU_DIAN_BAO_ID {
				item.Points = req.Points
			}
			item.StartDate = req.StartDate
			item.EndDate = req.EndDate
			item.IsUpgrade = mapPermissionIdUpgrade[chartPermissionId]
			item.ExpensiveYx = mapPermissionIdExpensive[chartPermissionId]
			item.ModifyTime = time.Now()
			item.CreateTime = time.Now()
			err = company.AddCompanyContractPermission(item)
			if err != nil {
				br.Msg = "新增合同失败"
				br.ErrMsg = "新增合同权限失败,Err:" + err.Error()
				return
			}
			//新增日志
			{
				itemLog := new(company.CompanyContractPermissionLog)
				itemLog.CompanyId = req.CompanyId
				itemLog.CompanyContractId = int(newId)
				itemLog.ChartPermissionId = v
				itemLog.StartDate = req.StartDate
				itemLog.EndDate = req.EndDate
				itemLog.ModifyTime = time.Now()
				itemLog.CreateTime = time.Now()
				itemLog.LogCreateTime = time.Now()
				go company.AddCompanyContractPermissionLog(itemLog)
			}
		}

		approval := new(company.CompanyApproval)
		approval.CompanyId = req.CompanyId
		approval.ProductId = productId
		approval.ApproveStatus = "待审批"
		approval.ApproveUserId = 0
		approval.ApproveRoleTypeCode = approveRoleTypeCode
		approval.ApproveRealName = ""
		approval.ApproveTime = time.Now()
		approval.ApproveContent = approveContent
		approval.ApplyMethod = applyMethod
		approval.ApplyReasons = ""
		approval.ApplyUserId = sysUser.AdminId
		approval.ApplyRealName = sysUser.RealName
		approval.CompanyContractId = int(newId)
		approval.CreateTime = time.Now()
		approval.ModifyTime = time.Now()
		approval.IsFormal = companyProduct.IsFormal
		companyApprovalId, err = company.AddCompanyApproval(approval)
		if err != nil {
			br.Msg = "申请失败"
			br.ErrMsg = "申请失败,Err:" + err.Error()
			return
		}
	} else {
		// 有审批单
		recode, err := company.GetCompanyApprovalByApprovalId(req.CompanyApprovalId)
		if err != nil {
			br.Msg = "申请失败"
			br.ErrMsg = "获取审批记录失败,Err:" + err.Error()
			return
		}
		err = company.ModifyCompanyApplyServiceUpdate(&req, productId, recode.CompanyContractId, companyProduct.IsFormal, mapPermissionIdUpgrade, mapPermissionIdExpensive)
		if err != nil {
			br.Msg = "申请失败"
			br.ErrMsg = "申请失败,Err:" + err.Error()
			return
		}
		companyApprovalId = req.CompanyApprovalId
	}
	//新增操作记录
	{
		services.AddCompanyOperationRecord(req.CompanyId, companyProduct.SellerId, sysUser.AdminId, productId, approveUserId, companyProduct.CompanyName,
			companyProduct.ProductName, sysUser.RealName, operationRemark, operation, recordApproveContent, approveUserRealName, "", companyProduct.Status)
	}
	//新增客户产品日志
	{
		logType := "modify"
		go services.AddCompanyProductLog(companyProduct, this.SysUser.AdminId, logType)
	}

	//新增申请单
	err = company_apply.Apply(companyApprovalId, messageContent)
	if err != nil {
		br.Msg = "发起审批异常，请联系管理员"
		br.ErrMsg = "客户审批发起异常,Err:" + err.Error()
		return
	}
	br.Ret = 200
	br.Success = true
	br.Msg = "申请成功"
}

// ApplyTurnPositive
// @Title 申请转正
// @Description 申请转正接口
// @Param	request	body company.CompanyApplyTurnPositiveReq true "type json string"
// @Success Ret=200 申请成功
// @router /apply/turn/positive [post]
func (this *CompanyApplyController) ApplyTurnPositive() {
	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 company.CompanyApplyTurnPositiveReq
	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
	if err != nil {
		br.Msg = "参数解析异常！"
		br.ErrMsg = "参数解析失败，Err:" + err.Error()
		return
	}
	if req.CompanyId <= 0 {
		br.Msg = "参数错误"
		br.ErrMsg = "参数错误，客户id小于等于0"
		return
	}
	if req.StartDate == "" {
		br.Msg = "请选择合同开始日期"
		return
	}
	if req.EndDate == "" {
		br.Msg = "请选择合同结束日期"
		return
	}

	if req.Money <= 0 {
		br.Msg = "合同金额不能小于等于0"
		return
	}
	if req.PermissionIds == "" {
		br.Msg = "请选择权限"
		return
	}
	roleTypeCode := sysUser.RoleTypeCode
	productId := services.GetProductId(roleTypeCode)
	if productId == 0 {
		br.Msg = "参数错误"
		br.ErrMsg = "客户类型为：" + roleTypeCode
		return
	}

	//添加缓存，避免多次点击提交
	{
		deleteCache := true
		cacheKey := "CACHE_COMPANY_APPLY_" + strconv.Itoa(req.CompanyId) + "_" + strconv.Itoa(productId)
		defer func() {
			if deleteCache {
				utils.Rc.Delete(cacheKey)
			}
		}()
		if !utils.Rc.SetNX(cacheKey, 1, 30*time.Second) {
			deleteCache = false
			br.Msg = "系统处理中，请勿重复操作"
			br.ErrMsg = "系统处理中，请勿重复操作" + sysUser.RealName + ";data:" + string(this.Ctx.Input.RequestBody)
			return
		}
	}
	companyProduct, err := company.GetCompanyProductByCompanyIdAndProductId(req.CompanyId, productId)
	if err != nil {
		br.Msg = "获取客户信息失败"
		br.ErrMsg = "获取客户信息失败"
		return
	}
	if companyProduct == nil {
		br.Msg = "获取客户信息失败"
		br.ErrMsg = "客户不存在，不可提交审批：companyId:" + strconv.Itoa(req.CompanyId) + ";productId:" + strconv.Itoa(productId)
		return
	}
	if companyProduct.Status != utils.COMPANY_STATUS_TRY_OUT && companyProduct.InitStatus != utils.COMPANY_STATUS_FOREVER {
		br.Msg = "客户状态为：" + companyProduct.Status + ";不可进行转正申请"
		br.ErrMsg = "客户状态为：" + companyProduct.Status + ";不可进行转正申请"
		return
	}

	mapPermissionIdUpgrade := make(map[int]int) // 权益主客观、行业升级、买方研选的处理
	permissionNameMap := make(map[int]string)   // 权益行业名称处理
	permissionNames := req.PermissionNames
	expensiveYx := 0
	if productId == 2 {
		// 给升级的产业ID加一个极大值判断处理
		permissionSlice := strings.Split(req.PermissionIds, ",")
		mapPermissionId := make(map[int]int)
		//var permissionIdsNew string
		var permissionIdOnly int //处理普通权限与升级权限同时勾选的时候的拦截
		expId := utils.PERMISSION_ID_YANXUAN_DIFF + utils.CHART_PERMISSION_ID_YANXUAN

		// 获取行业主观对应的客观ID
		subObjMap, e := services.GetRaiSubObjPermissionIdMap()
		if e != nil {
			br.Msg = "操作失败"
			br.ErrMsg = "获取行业主观对应的客观ID失败, Err: " + e.Error()
			return
		}
		strPermissionIdArr := make([]string, 0) // 最终过滤后的权限IDs
		for _, v := range permissionSlice {
			permissionId, _ := strconv.Atoi(v)
			// 研选5w的处理
			if permissionId == expId {
				//permissionIdsNew += strconv.Itoa(utils.CHART_PERMISSION_ID_YANXUAN) + ","
				strPermissionIdArr = append(strPermissionIdArr, strconv.Itoa(utils.CHART_PERMISSION_ID_YANXUAN))
				expensiveYx = 1
				continue
			}

			// 研选10w的处理
			if permissionId == utils.PERMISSION_ID_YANXUAN_10W_DIFF {
				//permissionIdsNew += strconv.Itoa(utils.CHART_PERMISSION_ID_YANXUAN) + ","
				strPermissionIdArr = append(strPermissionIdArr, strconv.Itoa(utils.CHART_PERMISSION_ID_YANXUAN))
				expensiveYx = 2
				continue
			}

			if permissionId > utils.PERMISSION_ID_UPGRADE {
				//permissionIdsNew += strconv.Itoa(permissionId-utils.PERMISSION_ID_UPGRADE) + ","
				permissionIdOnly = permissionId - utils.PERMISSION_ID_UPGRADE
				// 升级权限, 需要加入客观的权限
				subId := permissionId - utils.PERMISSION_ID_UPGRADE
				strPermissionIdArr = append(strPermissionIdArr, strconv.Itoa(subId))
				if subObjMap[subId] > 0 {
					strPermissionIdArr = append(strPermissionIdArr, strconv.Itoa(subObjMap[subId]))
				}
			} else {
				//permissionIdsNew += strconv.Itoa(permissionId) + ","
				strPermissionIdArr = append(strPermissionIdArr, v)
				permissionIdOnly = permissionId
			}
			//权益的永续客户主客观权限都开
			if companyProduct.InitStatus == utils.COMPANY_STATUS_FOREVER && subObjMap[permissionId] > 0 {
				strPermissionIdArr = append(strPermissionIdArr, strconv.Itoa(subObjMap[permissionId]))
			}
			if _, ok := mapPermissionId[permissionIdOnly]; ok {
				br.Msg = "权限设置有误，请重新选择"
				br.ErrMsg = "升级权限与普通权限重复选择！" + req.PermissionIds
				return
			}
			mapPermissionId[permissionIdOnly] = permissionIdOnly
		}
		req.PermissionIds = strings.Join(strPermissionIdArr, ",")
		//req.PermissionIds = strings.TrimRight(permissionIdsNew, ",")

		// 是否为权益内部人员, 非权益内部人员只能勾选行业不能勾选单独的主客观, 需要通过主观的ID去查客观的ID
		//isRai, e := services.CheckRaiAdmin(sysUser.AdminId)
		//if e != nil {
		//	br.Msg = "获取失败"
		//	br.ErrMsg = "判断是否为权益内部人员失败, GetRaiAdmin Err: " + e.Error()
		//	return
		//}
		//if !isRai {
		//permissionStr, err := company.GetPermissionIdById(req.PermissionIds)
		//if err != nil {
		//	br.Msg = "获取信息失败"
		//	br.ErrMsg = "获取主观客观权限信息失败,Err:" + err.Error()
		//	return
		//}
		//req.PermissionIds = permissionStr
		//}

		// 升级map
		if permissionNames != "" {
			mapPermissionIdUpgrade, err = services.PermissionIdUpgrade(permissionNames)
			if err != nil {
				br.Msg = "获取信息失败"
				br.ErrMsg = "处理升级信息失败,Err:" + err.Error()
				return
			}
		}

		permissionNameMap, err = services.GetPermissionNameMap()
		if err != nil {
			br.Msg = "新增合同失败"
			br.ErrMsg = "获取权限名称失败,Err:" + err.Error()
			return
		}
	}

	//客户归属判断
	if companyProduct.SellerId != sysUser.AdminId && companyProduct.ShareSellerId != sysUser.AdminId {
		br.Msg = "客户信息异常"
		br.ErrMsg = "客户信息异常，不是当前所属销售，客户所属销售：" + companyProduct.SellerName + ";当前销售:" + sysUser.AdminName
		return
	}

	if companyProduct.ApproveStatus == "待审批" {
		br.Msg = "存在待审批订单，不可重复提交"
		return
	}
	approveContent := `试用转正式`
	var approveUserId int
	var approveUserRealName string
	approveRoleTypeCode := ""
	if productId == 1 {
		approveRoleTypeCode = utils.ROLE_TYPE_CODE_FICC_ADMIN
	} else {
		approveRoleTypeCode = utils.ROLE_TYPE_CODE_RAI_ADMIN
	}
	approveUser, err := company.GetApproveUser(approveRoleTypeCode)
	if err != nil && err.Error() != utils.ErrNoRow() {
		br.Msg = "获取审批信息失败"
		br.ErrMsg = "获取审批人信息失败,Err:" + err.Error()
		return
	}
	if approveUser == nil || (err != nil && err.Error() == utils.ErrNoRow()) {
		br.Msg = "审批用户不存在"
		br.ErrMsg = "审批用户不存在"
		return
	}

	// 合同类型
	contractType := req.ContractType
	var raicontractType string // 权益合同类型
	{
		if contractType == "" {
			contractType = "新签合同"
		}
		var condition string
		var pars []interface{}
		condition += " AND product_id = ?"
		pars = append(pars, productId)
		condition += " AND status = ?"
		pars = append(pars, 1)
		list, e := company.GetCompanyContractListByCompanyId(req.CompanyId, condition, pars)
		if e != nil {
			br.Msg = "获取合同信息失败"
			br.ErrMsg = "获取合同信息失败,Err:" + e.Error()
			return
		}
		if len(list) > 0 {
			contractType = "续约合同"
		}

		if productId == 2 {
			//权益的新签合同重新定义，如果合同起始时间在新签合同起始日期 1年之内的，仍为新签合同。
			raicontractType = contractType
			if raicontractType != "新签合同" {
				//startDateTime, _ := time.Parse(utils.FormatDate, req.StartDate)
				//startDateTime = startDateTime.AddDate(-1, 0, 0)
				totalLastYear, err := contractService.GetCompanyContractCountRaiByLastYear(req.CompanyId, req.StartDate)
				if err != nil {
					br.Msg = "获取合同信息失败"
					br.ErrMsg = "获取合同信息失败,Err:" + err.Error()
					return
				}
				if totalLastYear > 0 {
					raicontractType = "新签合同"
				}
			}
		}

		// 若上面的判断不是续约合同, 则继续查询是否存在正式转试用的记录，如果存在，那么合同类型是续约合同
		if contractType != "续约合同" {
			total, e := company.GetCompanyProductOperationRecordCount(companyProduct.CompanyId, companyProduct.ProductId)
			if e != nil {
				br.Msg = "查询用户信息异常"
				br.ErrMsg = "查询用户变更记录异常, GetCompanyProductOperationRecordCount err: " + e.Error()
				return
			}
			if total > 0 {
				contractType = "续约合同"
			}
		}
	}

	var companyApprovalId int
	// 全新的申请转正
	if req.CompanyApprovalId <= 0 {
		contractCode, err := company.GetCompanyContractCode()
		if err != nil {
			br.Msg = "生成合同编码失败"
			br.ErrMsg = "生成合同编码失败,Err:" + err.Error()
			return
		}
		//当前是否存在待审批的单子
		nowCompanyApprovalInfo, err := company.GetCompanyApprovalById(req.CompanyId, productId)
		if (err == nil || nowCompanyApprovalInfo != nil) || err != nil && err.Error() != utils.ErrNoRow() {
			br.Msg = "此客户已存在待审批的申请单，请在申请单审批完成后重新提交"
			br.ErrMsg = "此客户已存在待审批的申请单，请在申请单审批完成后重新提交"
			return
		}

		//当前待审批的合同，有且只能存在一条
		//count, err := company.GetCompanyContractApproveCount(req.CompanyId, productId)
		//if err != nil {
		//	br.Msg = "获取信息失败"
		//	br.ErrMsg = "判断是否已存在待审批合同失败,Err:" + err.Error()
		//	return
		//}
		//if count > 0 {
		//	br.Msg = "此客户已提交过申请，请在客户审批列表重新提交"
		//	return
		//}
		contract := new(company.CompanyContract)
		contract.CompanyId = req.CompanyId
		contract.ProductId = productId
		contract.ContractType = contractType
		contract.RaiContractType = raicontractType
		contract.ProductName = companyProduct.ProductName
		contract.CompanyProductId = companyProduct.CompanyProductId
		contract.ContractCode = contractCode
		contract.StartDate = req.StartDate
		contract.EndDate = req.EndDate
		contract.Money = req.Money
		contract.PayMethod = req.PayMethod
		contract.PayChannel = req.PayChannel
		contract.ImgUrl = req.ImgUrl
		contract.Status = 0
		contract.Source = "上传附件"
		contract.PackageType = req.PackageType
		contract.RaiPackageType = req.RaiPackageType
		contract.CreateTime = time.Now()
		contract.ModifyTime = time.Now()
		newId, err := company.AddCompanyContract(contract)
		if err != nil {
			br.Msg = "新增合同失败"
			br.ErrMsg = "新增合同失败,Err:" + err.Error()
			return
		}
		permissionArr := strings.Split(req.PermissionIds, ",")
		permissionMap := make(map[int]int) //权限id的map集合，用来避免重复添加权限校验
		permissionItems := make([]*company.CompanyContractPermission, 0)
		permissionLogs := make([]*company.CompanyContractPermissionLog, 0)

		for _, v := range permissionArr {
			item := new(company.CompanyContractPermission)
			item.CompanyId = req.CompanyId
			item.CompanyContractId = int(newId)

			chartPermissionId, tmpErr := strconv.Atoi(v)
			if tmpErr != nil {
				err = tmpErr
				return
			}

			//权限id判断，避免重复添加权限
			if _, ok := permissionMap[chartPermissionId]; ok {
				continue
			}
			permissionMap[chartPermissionId] = chartPermissionId

			item.ChartPermissionId = chartPermissionId

			if _, ok := mapPermissionIdUpgrade[chartPermissionId]; ok {
				item.IsUpgrade = 1
			}
			if chartPermissionId == utils.CHART_PERMISSION_ID_YANXUAN {
				item.ExpensiveYx = expensiveYx
			}
			//如果是研选扣点包，这个行业权限的ID；那么就对点数进行赋值。目前就研选扣点包 这一个行业有点数，先不用数组类型处理。v:查研观向13.2
			if chartPermissionId == utils.YAN_XUAN_KOU_DIAN_BAO_ID {
				if req.Points <= 0 {
					br.Msg = "点数不能为空"
					return
				}
				item.Points = req.Points
			}

			item.PermissionName = permissionNameMap[chartPermissionId]

			item.StartDate = req.StartDate
			item.EndDate = req.EndDate
			item.ModifyTime = time.Now()
			item.CreateTime = time.Now()
			permissionItems = append(permissionItems, item)

			//新增日志
			itemLog := new(company.CompanyContractPermissionLog)
			itemLog.CompanyId = req.CompanyId
			itemLog.CompanyContractId = int(newId)
			itemLog.ChartPermissionId = v
			itemLog.StartDate = req.StartDate
			itemLog.EndDate = req.EndDate
			itemLog.ModifyTime = time.Now()
			itemLog.CreateTime = time.Now()
			itemLog.LogCreateTime = time.Now()
			permissionLogs = append(permissionLogs, itemLog)
		}

		// 批量新增company_contract_permission和log
		if e := company.MultiAddCompanyContractPermission(permissionItems); e != nil {
			br.Msg = "新增合同失败"
			br.ErrMsg = "批量新增合同权限失败, MultiAddCompanyContractPermission Err:" + e.Error()
			return
		}
		go company.MultiAddCompanyContractPermissionLog(permissionLogs)

		applyMethod := 1
		approval := new(company.CompanyApproval)
		approval.CompanyId = req.CompanyId
		approval.ProductId = productId
		approval.ApproveStatus = "待审批"
		approval.ApproveUserId = 0
		approval.ApproveRoleTypeCode = approveRoleTypeCode
		approval.ApproveRealName = ""
		approval.ApproveTime = time.Now()
		approval.ApproveContent = "试用转正式"
		approval.ApplyMethod = applyMethod
		approval.ApplyReasons = ""
		approval.ApplyUserId = sysUser.AdminId
		approval.ApplyRealName = sysUser.RealName
		approval.CreateTime = time.Now()
		approval.ModifyTime = time.Now()
		approval.CompanyContractId = int(newId)
		approval.IsFormal = companyProduct.IsFormal
		companyApprovalId, err = company.AddCompanyApproval(approval)
		if err != nil {
			br.Msg = "申请失败"
			br.ErrMsg = "申请失败,Err:" + err.Error()
			return
		}
	} else {
		// 重新申请
		recode, err := company.GetCompanyApprovalByApprovalId(req.CompanyApprovalId)
		if err != nil {
			br.Msg = "申请失败"
			br.ErrMsg = "获取审批记录失败,Err:" + err.Error()
			return
		}
		err = company.ModifyCompanyTurnPositive(&req, productId, recode.CompanyContractId, companyProduct.IsFormal, mapPermissionIdUpgrade, expensiveYx)
		if err != nil {
			br.Msg = "申请失败"
			br.ErrMsg = "申请失败,Err:" + err.Error()
			return
		}
		companyApprovalId = req.CompanyApprovalId
	}
	//新增操作记录
	{
		remark := "申请转正"
		operation := "turn_positive"
		services.AddCompanyOperationRecord(req.CompanyId, companyProduct.SellerId, sysUser.AdminId, productId, approveUserId, companyProduct.CompanyName,
			companyProduct.ProductName, sysUser.RealName, remark, operation, approveContent, approveUserRealName, "", companyProduct.Status)
	}
	//新增客户产品日志
	{
		logType := "modify"
		go services.AddCompanyProductLog(companyProduct, this.SysUser.AdminId, logType)
	}

	//新增申请单
	err = company_apply.Apply(companyApprovalId, "试用转正式申请单")
	if err != nil {
		br.Msg = "发起审批异常，请联系管理员"
		br.ErrMsg = "客户审批发起异常,Err:" + err.Error()
		return
	}

	br.Ret = 200
	br.Success = true
	br.Msg = "申请成功"
}

// ApplyBySystemContract
// @Title 通过系统合同申请转正/服务更新
// @Description 通过系统合同申请转正/服务更新接口
// @Param	request	body company.CompanyApplyBySystemContractReq true "type json string"
// @Success Ret=200 申请成功
// @router /apply/systemContract [post]
func (this *CompanyApplyController) ApplyBySystemContract() {
	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 company.CompanyApplyBySystemContractReq
	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
	if err != nil {
		br.Msg = "参数解析异常！"
		br.ErrMsg = "参数解析失败，Err:" + err.Error()
		return
	}
	if req.CompanyId <= 0 {
		br.Msg = "参数错误"
		br.ErrMsg = "参数错误，客户id小于等于0"
		return
	}

	//获取客户信息
	companyInfo, err := company.GetCompanyById(req.CompanyId)
	if err != nil {
		br.Msg = "获取客户信息失败"
		br.ErrMsg = "获取客户信息失败"
		return
	}

	roleTypeCode := sysUser.RoleTypeCode
	productId := services.GetProductId(roleTypeCode)
	if productId == 0 {
		br.Msg = "参数错误"
		br.ErrMsg = "客户类型为：" + roleTypeCode
		return
	}

	//添加缓存，避免多次点击提交
	{
		deleteCache := true
		cacheKey := "CACHE_COMPANY_APPLY_" + strconv.Itoa(req.CompanyId) + "_" + strconv.Itoa(productId)
		defer func() {
			if deleteCache {
				utils.Rc.Delete(cacheKey)
			}
		}()
		if !utils.Rc.SetNX(cacheKey, 1, 30*time.Second) {
			deleteCache = false
			br.Msg = "系统处理中，请勿重复操作"
			br.ErrMsg = "系统处理中，请勿重复操作" + sysUser.RealName + ";data:" + string(this.Ctx.Input.RequestBody)
			return
		}
	}

	companyProduct, err := company.GetCompanyProductByCompanyIdAndProductId(req.CompanyId, productId)
	if err != nil {
		br.Msg = "获取客户信息失败"
		br.ErrMsg = "获取客户信息失败"
		return
	}
	if companyProduct == nil {
		br.Msg = "获取客户信息失败"
		br.ErrMsg = "客户不存在，不可提交审批：companyId:" + strconv.Itoa(req.CompanyId) + ";productId:" + strconv.Itoa(productId)
		return
	}
	if companyProduct.SellerId != sysUser.AdminId && companyProduct.ShareSellerId != sysUser.AdminId {
		br.Msg = "客户信息异常"
		br.ErrMsg = "客户信息异常，不是当前所属销售，客户所属销售：" + companyProduct.SellerName + ";当前销售:" + sysUser.AdminName
		return
	}

	if companyProduct.ApproveStatus == "待审批" {
		br.Msg = "存在待审批订单，不可重复提交"
		return
	}
	var approveUserId int
	var approveUserRealName string
	approveRoleTypeCode := ""
	if productId == 1 {
		approveRoleTypeCode = utils.ROLE_TYPE_CODE_FICC_ADMIN
	} else {
		approveRoleTypeCode = utils.ROLE_TYPE_CODE_RAI_ADMIN
	}
	approveUser, err := company.GetApproveUser(approveRoleTypeCode)
	if err != nil && err.Error() != utils.ErrNoRow() {
		br.Msg = "获取审批信息失败"
		br.ErrMsg = "获取审批人信息失败,Err:" + err.Error()
		return
	}
	if approveUser == nil || (err != nil && err.Error() == utils.ErrNoRow()) {
		br.Msg = "审批用户不存在"
		br.ErrMsg = "审批用户不存在"
		return
	}

	//获取合同详情
	contractDetail, err := contractService.GetContractDetail(req.ContractId)
	if err != nil {
		br.Msg = "查询合同异常"
		br.ErrMsg = fmt.Sprint("查询合同异常，合同id:", req.ContractId, ";Err:", err.Error())
		return
	}
	if contractDetail.ContractBusinessType != "业务合同" {
		br.Msg = "合同类型异常"
		br.ErrMsg = "合同类型异常，当前合同类型为:" + contractDetail.ContractBusinessType
		return
	}

	//判断产品类型是否一致
	if productId != contractDetail.ProductId {
		br.Msg = "合同产品类型异常"
		br.ErrMsg = fmt.Sprint("合同产品类型异常，合同产品类型Id:", contractDetail.ProductId)
		return
	}

	//判断销售归属
	if contractDetail.SellerId != sysUser.AdminId {
		br.Msg = "合同异常"
		br.ErrMsg = fmt.Sprint("合同归属人异常，合同申请人Id:", contractDetail.SellerId, ";当前账号：", sysUser.AdminId)
		return
	}

	//判断合同是否该客户的（组织社会信用代码是否一致）
	if contractDetail.CreditCode != companyInfo.CreditCode {
		br.Msg = "合同异常，请选择社会信用码一致的合同"
		br.ErrMsg = fmt.Sprint("该合同组织社会信用码与客户不符，合同的社会信用码:", contractDetail.CreditCode, ";客户的社会信用码：", companyInfo.CreditCode)
		return
	}
	if contractDetail.Status != "已签回" {
		br.Msg = "合同状态异常"
		br.ErrMsg = fmt.Sprint("合同状态异常，合同状态:", contractDetail.Status)
		return
	}

	//当前客户需要的合同状态
	needContractType, err := services.GetApplyTurnContractType(req.CompanyId, productId)
	if err != nil {
		br.Msg = "获取失败"
		br.ErrMsg = "获取合同类型失败，Err:" + err.Error()
		return
	}
	//判断 系统需要的合同类型 与 实际提交的合同类型是否一致，如果不一致，那么不支持
	if needContractType != "新签合同" && contractDetail.ContractType == "新签合同" {
		br.Msg = "申请失败，该客户曾经开通过正式服务，不允许签署新签合同"
		br.ErrMsg = "申请失败，该客户曾经开通过正式服务，不允许签署新签合同"
		return
	}

	if contractDetail.ContractType == "新签合同" {
		if companyProduct.Status != utils.COMPANY_STATUS_TRY_OUT {
			br.Msg = "客户状态为：" + companyProduct.Status + ";不可进行转正申请"
			br.ErrMsg = "客户状态为：" + companyProduct.Status + ";不可进行转正申请"
			return
		}
	} else {
		if companyProduct.Status != utils.COMPANY_STATUS_FORMAL && companyProduct.Status != utils.COMPANY_STATUS_TRY_OUT {
			br.Msg = "客户状态为：" + companyProduct.Status + ";不可进行服务更新申请"
			br.ErrMsg = "客户状态为：" + companyProduct.Status + ";不可进行服务更新申请"
			return
		}
	}

	//合同类型
	contractType := contractDetail.ContractType

	var hasContract bool //是否已经存在合同，如果存在，那么就不能是新签合同
	var condition string
	var pars []interface{}
	condition += " AND product_id = ?"
	pars = append(pars, productId)
	condition += " AND status = ?"
	pars = append(pars, 1)
	list, err := company.GetCompanyContractListByCompanyId(req.CompanyId, condition, pars)
	if err != nil {
		br.Msg = "获取合同信息失败"
		br.ErrMsg = "获取合同信息失败,Err:" + err.Error()
		return
	}
	if len(list) > 0 {
		hasContract = true
	}
	//查询是否存在正式转试用的记录，如果存在，那么合同类型是续约合同
	total, err := company.GetCompanyProductOperationRecordCount(companyProduct.CompanyId, companyProduct.ProductId)
	if err != nil {
		br.Msg = "查询用户信息异常"
		br.ErrMsg = "查询用户变更记录异常"
		return
	}
	if total > 0 {
		hasContract = true
	}
	if hasContract && contractType == "新签合同" {
		br.Msg = "客户已存在老合同，不允许签署新签合同"
		br.ErrMsg = "客户已存在老合同，不允许签署新签合同"
		return
	}
	//合同类型 end

	//获取权限id列表
	permissionMap, err := contractService.GetServicePermissionMap(contractDetail.Service)
	permissionArr := make([]int, 0)
	for _, permissionId := range permissionMap {
		permissionArr = append(permissionArr, permissionId)
	}
	//对权限排序
	sort.Ints(permissionArr)
	// CRM8.8-权益主客观此处拆分成了三级套餐, 根据contract_service写权限
	// CRM8.8-如果是权益客户那么主观客观权限一起带上(暂弃)
	//if companyProduct.ProductId == 2 {
	//	var permissionIds string
	//	var permissionNames string
	//	for _, v := range permissionArr {
	//		permissionIds += strconv.Itoa(v) + ","
	//	}
	//	permissionIds = strings.TrimRight(permissionIds, ",")
	//	listSandO, err := company.GetPermissionLookItemsSandO(permissionIds)
	//	if err != nil {
	//		br.Msg = "获取现有的合同权限信息失败"
	//		br.ErrMsg = "获取现有的合同权限ID信息失败,Err:" + err.Error()
	//		return
	//	}
	//	for _, v := range listSandO {
	//		permissionNames += "'" + v.PermissionName + "'" + ","
	//	}
	//	permissionNames = strings.TrimRight(permissionNames, ",")
	//	listPermissionByname, err := company.GetPermissionLookItemsSandOByName(permissionNames)
	//	if err != nil {
	//		br.Msg = "获取现有的合同权限信息失败"
	//		br.ErrMsg = "通过名称获取主观客观权限ID信息失败,Err:" + err.Error()
	//		return
	//	}
	//	permissionArr = make([]int, 0)
	//	for _, v := range listPermissionByname {
	//		permissionArr = append(permissionArr, v.ChartPermissionId)
	//	}
	//	//对权限排序
	//	sort.Ints(permissionArr)
	//}

	//当前已经存在的权限
	currPermissionMap, err := services.GetLastContractPermissionList(companyProduct.CompanyId, companyProduct.ProductId)
	if err != nil {
		br.Msg = "获取现有的合同权限信息失败"
		br.ErrMsg = "获取现有的合同权限信息失败,Err:" + err.Error()
		return
	}
	//权限内日期判断校验
	for _, permissionId := range permissionArr {
		//研选服务不做校验
		if permissionId == 31 {
			continue
		}
		if currPermission, ok := currPermissionMap[permissionId]; ok {
			currStartDate, _ := time.Parse(utils.FormatDate, currPermission.StartDate)
			currEndDate, _ := time.Parse(utils.FormatDate, currPermission.EndDate)

			if !(contractDetail.StartDate.After(currEndDate) || currStartDate.After(contractDetail.EndDate)) {
				br.Msg = currPermission.PermissionName + "合同日期存在重复，不允许申请"
				br.ErrMsg = "权限合同日期存在重复，不允许申请"
				return
			}
		}
	}

	//获取客户产品套餐类型（大套餐、小套餐、无）
	packageType, err := contractService.GetServicePackageType(contractDetail.Service)
	raiPackageType := contractService.GetRaiServicePackageType(contractDetail.Service)

	recordApproveContent := `试用转正式`
	applyMethod := 1
	approveContent := "试用转正式"
	operationRemark := `申请转正`
	operation := "turn_positive"
	messageContent := "试用转正式申请单"
	//申请类型：1:试用->正式,2:冻结—>试用,3:试用延期,4:原销售申请领取流失客户，5:正式客户申请服务更新，6：正式客户补充协议
	if contractType != "新签合同" {
		if contractType == "补充协议" {
			applyMethod = 6 //补充协议
			recordApproveContent = `正式客户新增补充协议`
			approveContent = `新增补充协议`
			operationRemark = `新增补充协议`
			operation = "add_agreement"
			messageContent = "补充协议申请单"
		} else {
			applyMethod = 5 //续约服务
			recordApproveContent = `正式客户申请续约`
			approveContent = `申请续约`
			operationRemark = `申请续约`
			operation = "service_update"
			messageContent = "续约申请单"
		}
	}

	var raicontractType string
	if productId == 2 {
		//权益的新签合同重新定义，如果合同起始时间在新签合同起始日期 1年之内的，仍为新签合同。
		raicontractType = contractType
		if raicontractType != "新签合同" {
			//startDateTime := contractDetail.StartDate.AddDate(-1, 0, 0)
			totalLastYear, err := contractService.GetCompanyContractCountRaiByLastYear(req.CompanyId, contractDetail.StartDate.Format(utils.FormatDate))
			if err != nil {
				br.Msg = "获取合同信息失败"
				br.ErrMsg = "获取合同信息失败,Err:" + err.Error()
				return
			}
			if totalLastYear > 0 {
				raicontractType = "新签合同"
			}
		}
	}

	var companyApprovalId int
	if req.CompanyApprovalId <= 0 {
		//当前是否存在待审批的单子
		nowCompanyApprovalInfo, err := company.GetCompanyApprovalById(req.CompanyId, productId)
		if (err == nil || nowCompanyApprovalInfo != nil) || err != nil && err.Error() != utils.ErrNoRow() {
			br.Msg = "此客户已存在待审批的申请单，请在申请单审批完成后重新提交"
			br.ErrMsg = "此客户已存在待审批的申请单，请在申请单审批完成后重新提交"
			return
		}
		////当前待审批的合同，有且只能存在一条
		//count, err := company.GetCompanyContractApproveCount(req.CompanyId, productId)
		//if err != nil {
		//	br.Msg = "获取信息失败"
		//	br.ErrMsg = "判断是否已存在待审批合同失败,Err:" + err.Error()
		//	return
		//}
		//if count > 0 {
		//	br.Msg = "此客户已提交过申请，请在客户审批列表重新提交"
		//	return
		//}
		companyContract := &company.CompanyContract{
			CompanyId:        req.CompanyId,
			ProductId:        contractDetail.ProductId,
			ContractType:     contractType,
			RaiContractType:  raicontractType,
			ProductName:      companyProduct.ProductName,
			CompanyProductId: companyProduct.CompanyProductId,
			ContractCode:     contractDetail.ContractCode,
			StartDate:        contractDetail.StartDate.Format(utils.FormatDate),
			EndDate:          contractDetail.EndDate.Format(utils.FormatDate),
			Money:            contractDetail.Price,
			PayMethod:        contractDetail.PayRemark,
			PayChannel:       contractDetail.PayChannel,
			ImgUrl:           contractDetail.CheckBackFileUrl,
			Status:           0,
			Source:           "系统合同",
			PackageType:      packageType,
			RaiPackageType:   raiPackageType,
			CreateTime:       time.Now(),
			ModifyTime:       time.Now(),
		}
		newId, err := company.AddCompanyContract(companyContract)
		if err != nil {
			br.Msg = "新增合同失败"
			br.ErrMsg = "新增合同失败,Err:" + err.Error()
			return
		}
		upgradeMap := make(map[int]int)
		if utils.RunMode == "release" {
			upgradeMap = map[int]int{22: 39, 21: 38, 20: 37, 19: 36}
		} else {
			upgradeMap = map[int]int{22: 37, 21: 36, 20: 35, 19: 34}
		}

		for _, chartPermissionId := range permissionArr {
			if chartPermissionId < utils.PERMISSION_ID_UPGRADE {
				item := new(company.CompanyContractPermission)
				item.CompanyId = req.CompanyId
				item.CompanyContractId = int(newId)

				item.ChartPermissionId = chartPermissionId

				item.StartDate = contractDetail.StartDate.Format(utils.FormatDate)
				item.EndDate = contractDetail.EndDate.Format(utils.FormatDate)
				item.ModifyTime = time.Now()
				item.CreateTime = time.Now()
				err = company.AddCompanyContractPermission(item)
				if err != nil {
					br.Msg = "新增合同失败"
					br.ErrMsg = "新增合同权限失败,Err:" + err.Error()
					return
				}

				//新增日志
				{
					itemLog := new(company.CompanyContractPermissionLog)
					itemLog.CompanyId = req.CompanyId
					itemLog.CompanyContractId = int(newId)
					itemLog.ChartPermissionId = strconv.Itoa(chartPermissionId)
					itemLog.StartDate = contractDetail.StartDate.Format(utils.FormatDate)
					itemLog.EndDate = contractDetail.EndDate.Format(utils.FormatDate)
					itemLog.ModifyTime = time.Now()
					itemLog.CreateTime = time.Now()
					itemLog.LogCreateTime = time.Now()
					go company.AddCompanyContractPermissionLog(itemLog)
				}
			} else {
				// 升级套餐，手动补充主客观套餐
				chartPermissionId -= utils.PERMISSION_ID_UPGRADE
				item := new(company.CompanyContractPermission)
				item.CompanyId = req.CompanyId
				item.CompanyContractId = int(newId)

				item.ChartPermissionId = chartPermissionId
				item.IsUpgrade = 1
				item.StartDate = contractDetail.StartDate.Format(utils.FormatDate)
				item.EndDate = contractDetail.EndDate.Format(utils.FormatDate)
				item.ModifyTime = time.Now()
				item.CreateTime = time.Now()
				err = company.AddCompanyContractPermission(item)
				if err != nil {
					br.Msg = "新增合同失败"
					br.ErrMsg = "新增合同权限失败,Err:" + err.Error()
					return
				}

				//新增日志
				{
					itemLog := new(company.CompanyContractPermissionLog)
					itemLog.CompanyId = req.CompanyId
					itemLog.CompanyContractId = int(newId)
					itemLog.ChartPermissionId = strconv.Itoa(chartPermissionId)
					itemLog.StartDate = contractDetail.StartDate.Format(utils.FormatDate)
					itemLog.EndDate = contractDetail.EndDate.Format(utils.FormatDate)
					itemLog.ModifyTime = time.Now()
					itemLog.CreateTime = time.Now()
					itemLog.LogCreateTime = time.Now()
					go company.AddCompanyContractPermissionLog(itemLog)
				}

				// 客观
				upgradeChartPermissionId := upgradeMap[chartPermissionId]
				upItem := new(company.CompanyContractPermission)
				upItem.CompanyId = req.CompanyId
				upItem.CompanyContractId = int(newId)

				upItem.ChartPermissionId = upgradeChartPermissionId
				upItem.IsUpgrade = 1
				upItem.StartDate = contractDetail.StartDate.Format(utils.FormatDate)
				upItem.EndDate = contractDetail.EndDate.Format(utils.FormatDate)
				upItem.ModifyTime = time.Now()
				upItem.CreateTime = time.Now()
				err = company.AddCompanyContractPermission(upItem)
				if err != nil {
					br.Msg = "新增合同失败"
					br.ErrMsg = "新增合同权限失败,Err:" + err.Error()
					return
				}

				//新增日志
				{
					itemLog := new(company.CompanyContractPermissionLog)
					itemLog.CompanyId = req.CompanyId
					itemLog.CompanyContractId = int(newId)
					itemLog.ChartPermissionId = strconv.Itoa(upgradeChartPermissionId)
					itemLog.StartDate = contractDetail.StartDate.Format(utils.FormatDate)
					itemLog.EndDate = contractDetail.EndDate.Format(utils.FormatDate)
					itemLog.ModifyTime = time.Now()
					itemLog.CreateTime = time.Now()
					itemLog.LogCreateTime = time.Now()
					go company.AddCompanyContractPermissionLog(itemLog)
				}

			}
		}

		approval := new(company.CompanyApproval)
		approval.CompanyId = req.CompanyId
		approval.ProductId = productId
		approval.ApproveStatus = "待审批"
		approval.ApproveUserId = 0
		approval.ApproveRoleTypeCode = approveRoleTypeCode
		approval.ApproveRealName = ""
		approval.ApproveTime = time.Now()
		approval.ApproveContent = approveContent
		approval.ApplyMethod = applyMethod
		approval.ApplyReasons = ""
		approval.ApplyUserId = sysUser.AdminId
		approval.ApplyRealName = sysUser.RealName
		approval.CreateTime = time.Now()
		approval.ModifyTime = time.Now()
		approval.CompanyContractId = int(newId)
		approval.IsFormal = companyProduct.IsFormal
		companyApprovalId, err = company.AddCompanyApproval(approval)
		if err != nil {
			br.Msg = "申请失败"
			br.ErrMsg = "申请失败,Err:" + err.Error()
			return
		}
	} else {
		recode, err := company.GetCompanyApprovalByApprovalId(req.CompanyApprovalId)
		if err != nil {
			br.Msg = "申请失败"
			br.ErrMsg = "获取审批记录失败,Err:" + err.Error()
			return
		}
		err = company.ModifyCompanyTurnPositiveBySystemContract(contractDetail, permissionArr, req.CompanyId, productId, req.CompanyApprovalId, recode.CompanyContractId, companyProduct.IsFormal, packageType, raiPackageType)
		if err != nil {
			br.Msg = "申请失败"
			br.ErrMsg = "申请失败,Err:" + err.Error()
			return
		}
		companyApprovalId = req.CompanyApprovalId
	}
	//新增操作记录
	{
		services.AddCompanyOperationRecord(req.CompanyId, companyProduct.SellerId, sysUser.AdminId, productId, approveUserId, companyProduct.CompanyName,
			companyProduct.ProductName, sysUser.RealName, operationRemark, operation, recordApproveContent, approveUserRealName, "", companyProduct.Status)
	}
	//新增客户产品日志
	{
		logType := "modify"
		go services.AddCompanyProductLog(companyProduct, this.SysUser.AdminId, logType)
	}

	err = company_apply.Apply(companyApprovalId, messageContent)
	if err != nil {
		br.Msg = "发起审批异常，请联系管理员"
		br.ErrMsg = "客户审批发起异常,Err:" + err.Error()
		return
	}
	//待办通知
	//{
	//	for _, v := range approveUser {
	//		approveUserId = v.AdminId
	//		approveUserRealName = v.RealName
	//		mobile := v.Mobile
	//		err = services.AddCompanyApprovalMessage(sysUser.AdminId, approveUserId, req.CompanyId, companyApprovalId, 1, 1, 1, companyProduct.CompanyName, messageContent, messageContent, mobile)
	//		if err != nil {
	//			br.Msg = "申请失败"
	//			br.ErrMsg = "新增待办通知失败,Err:" + err.Error()
	//			return
	//		}
	//	}
	//}
	br.Ret = 200
	br.Success = true
	br.Msg = "申请成功"
}

// ApplyThaw
// @Title 申请解冻
// @Description 申请解冻接口
// @Param	request	body company.CompanyApplyThawReq true "type json string"
// @Success Ret=200 申请成功
// @router /apply/thaw [post]
func (this *CompanyApplyController) ApplyThaw() {
	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 company.CompanyApplyThawReq
	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
	if err != nil {
		br.Msg = "参数解析异常！"
		br.ErrMsg = "参数解析失败，Err:" + err.Error()
		return
	}
	if req.CompanyId <= 0 {
		br.Msg = "参数错误"
		br.ErrMsg = "参数错误，客户id小于等于0"
		return
	}
	roleTypeCode := sysUser.RoleTypeCode
	productId := services.GetProductId(roleTypeCode)
	if productId == 0 {
		br.Msg = "参数错误"
		br.ErrMsg = "客户类型为：" + roleTypeCode
		return
	}
	if productId == utils.COMPANY_PRODUCT_FICC_ID && req.PermissionIds == "" {
		br.Msg = "请勾选需要解冻的品种"
		br.ErrMsg = "请勾选需要解冻的品种"
		return
	}

	// 查询当前销售是否有重新申请的权限
	receiveEnabled, _ := services.CheckCompanyReceiveButton(sysUser.AdminId)
	if !receiveEnabled {
		br.Msg = "无权申请"
		br.ErrMsg = "无权申请"
		return
	}
	//添加缓存，避免多次点击提交
	{
		deleteCache := true
		cacheKey := "CACHE_COMPANY_APPLY_" + strconv.Itoa(req.CompanyId) + "_" + strconv.Itoa(productId)
		defer func() {
			if deleteCache {
				utils.Rc.Delete(cacheKey)
			}
		}()
		if !utils.Rc.SetNX(cacheKey, 1, 30*time.Second) {
			deleteCache = false
			br.Msg = "系统处理中，请勿重复操作"
			br.ErrMsg = "系统处理中，请勿重复操作" + sysUser.RealName + ";data:" + string(this.Ctx.Input.RequestBody)
			return
		}
	}
	var companyApprovalCount int //某一客户申请的次数
	approveRoleTypeCode := ""
	if productId == 1 {
		approveRoleTypeCode = utils.ROLE_TYPE_CODE_FICC_ADMIN
	} else {
		approveRoleTypeCode = utils.ROLE_TYPE_CODE_RAI_ADMIN
		companyApprovalCount, err = company.GetCompanyApprovalCount(req.CompanyId, productId, 2)
		if err != nil {
			br.Msg = "获取客户信息失败"
			br.ErrMsg = "获取客户申请的次数失败,Err:" + err.Error()
			return
		}

		permissionArr := strings.Split(req.PermissionIds, ",")
		//如果所选行业不属于研选订阅跟研选扣点包，那就是非研选试用客户
		var isNoResearch bool
		for _, v := range permissionArr {
			if v != strconv.Itoa(utils.CHART_PERMISSION_ID_YANXUAN) && v != strconv.Itoa(utils.YAN_XUAN_KOU_DIAN_BAO_ID) {
				isNoResearch = true
				continue
			}
		}
		if isNoResearch {
			tryOutCountRai, err := company.GetRaiCompanyTryOutCountNoResearch(sysUser.AdminId)
			if err != nil {
				br.Msg = "判断试用客户量失败"
				br.ErrMsg = "判断试用客户量失败,Err:" + err.Error()
				return
			}
			if tryOutCountRai >= utils.COMPANY_STATUS_TRY_OUT_COUNT_RAI {
				br.Msg = "非研选试用客户最多40家"
				return
			}
		}
	}
	companyProduct, err := company.GetCompanyProductByCompanyIdAndProductId(req.CompanyId, productId)
	if err != nil {
		br.Msg = "获取客户信息失败"
		br.ErrMsg = "获取客户信息失败"
		return
	}
	if companyProduct == nil {
		br.Msg = "获取客户信息失败"
		br.ErrMsg = "客户不存在，不可提交审批：companyId:" + strconv.Itoa(req.CompanyId) + ";productId:" + strconv.Itoa(productId)
		return
	}
	if companyProduct.Status != utils.COMPANY_STATUS_FREEZE {
		br.Msg = "客户状态为：" + companyProduct.Status + ";不可进行解冻申请"
		br.ErrMsg = "客户状态为：" + companyProduct.Status + ";不可进行解冻申请"
		return
	}

	if companyProduct.ApproveStatus == utils.COMPANY_APPROVE_STATUS {
		br.Msg = "存在待审批订单，不可重复提交"
		return
	}

	//客户归属判断
	if companyProduct.SellerId != sysUser.AdminId && companyProduct.ShareSellerId != sysUser.AdminId {
		br.Msg = "客户信息异常"
		br.ErrMsg = "客户信息异常，不是当前所属销售，客户所属销售：" + companyProduct.SellerName + ";当前销售:" + sysUser.AdminName
		return
	}

	// CRM8.8(仅针对权益客户)-此处同申请试用的逻辑
	if companyProduct.ProductId == utils.COMPANY_PRODUCT_RAI_ID {
		reportPermissions, e := company.GetCompanyReportPermission(req.CompanyId, utils.COMPANY_PRODUCT_RAI_ID)
		if e != nil {
			br.Msg = "客户权限信息异常"
			br.ErrMsg = "客户权限信息异常, Err: " + e.Error()
			return
		}
		reportPermissionArr := make([]string, 0)
		for i := range reportPermissions {
			reportPermissionArr = append(reportPermissionArr, strconv.Itoa(reportPermissions[i].ChartPermissionId))
		}
		if len(reportPermissionArr) > 0 {
			req.PermissionIds = strings.Join(reportPermissionArr, ",")
		}
	}

	approveUser, err := company.GetApproveUser(approveRoleTypeCode)
	if err != nil && err.Error() != utils.ErrNoRow() {
		br.Msg = "获取审批信息失败"
		br.ErrMsg = "获取审批人信息失败,Err:" + err.Error()
		return
	}
	if approveUser == nil || (err != nil && err.Error() == utils.ErrNoRow()) {
		br.Msg = "审批用户不存在"
		br.ErrMsg = "审批用户不存在"
		return
	}
	//申请类型：1:试用->正式,2:冻结—>试用,3:试用延期,4:原销售申请领取流失客户，5:正式客户申请服务更新，6：正式客户补充协议
	approveContent := `冻结转试用`
	var companyApprovalId int
	if req.CompanyApprovalId <= 0 {
		applyMethod := 2
		approval := new(company.CompanyApproval)
		approval.CompanyId = req.CompanyId
		approval.ProductId = productId
		approval.ApproveStatus = "待审批"
		approval.ApproveUserId = 0
		approval.ApproveRoleTypeCode = approveRoleTypeCode
		approval.ApproveRealName = ""
		approval.ApproveTime = time.Now()
		approval.ApproveContent = approveContent
		approval.ApplyMethod = applyMethod
		approval.ApplyReasons = req.ApplyRemark
		approval.ApplyUserId = sysUser.AdminId
		approval.ApplyRealName = sysUser.RealName
		approval.CreateTime = time.Now()
		approval.ModifyTime = time.Now()
		companyApprovalId, err = company.AddCompanyApproval(approval)
		if err != nil {
			br.Msg = "申请失败"
			br.ErrMsg = "申请失败,Err:" + err.Error()
			return
		}
	} else {
		err = company.ModifyCompanyApproval(req.CompanyId, productId, req.CompanyApprovalId, approveContent, req.ApplyRemark)
		if err != nil {
			br.Msg = "申请失败"
			br.ErrMsg = "申请失败,Err:" + err.Error()
			return
		}
		companyApprovalId = req.CompanyApprovalId

		//先删除之前申请的权限
		_ = company.DeleteCompanyDelayPermission(req.CompanyApprovalId)
	}

	//处理权限
	{
		if req.PermissionIds != "" {
			// CRM8.8(仅针对权益客户)-此处不再去查询主观对应的客观, 而是根据客户之前拥有的权限来操作
			//permissionStr, err := company.GetPermissionIdById(req.PermissionIds)
			//if err != nil {
			//	br.Msg = "获取信息失败"
			//	br.ErrMsg = "获取主观客观权限信息失败,Err:" + err.Error()
			//	return
			//}
			//req.PermissionIds = permissionStr
			permissionArr := strings.Split(req.PermissionIds, ",")
			for _, v := range permissionArr {
				//fmt.Println(k, v)
				//新增
				if v != "" {
					permissionId, err := strconv.Atoi(v)
					if err != nil {
						br.Msg = "申请失败"
						br.ErrMsg = "权限格式转换失败,Err:" + err.Error()
						return
					}
					delayItem := new(company.CompanyDelayPermission)
					delayItem.CompanyId = req.CompanyId
					delayItem.CompanyApplyId = companyApprovalId
					delayItem.ChartPermissionId = permissionId
					delayItem.StartDate = time.Now().Format(utils.FormatDate)
					delayItem.EndDate = time.Now().AddDate(0, 2, 0).Format(utils.FormatDate)
					delayItem.CreateTime = time.Now()
					delayItem.ModifyTime = time.Now()
					err = company.AddCompanyDelayPermission(delayItem)
					if err != nil {
						br.Msg = "申请失败"
						br.ErrMsg = "新增冻结转试用审批权限失败,Err:" + err.Error()
						return
					}
				}
			}
		}
	}
	//新增操作记录
	{
		remark := "申请解冻"
		operation := "thaw"
		services.AddCompanyOperationRecord(req.CompanyId, companyProduct.SellerId, sysUser.AdminId, productId, 0, companyProduct.CompanyName,
			companyProduct.ProductName, sysUser.RealName, remark, operation, approveContent, "", "", companyProduct.Status)
	}
	//新增客户产品日志
	{
		logType := "modify"
		go services.AddCompanyProductLog(companyProduct, this.SysUser.AdminId, logType)
	}
	err = company_apply.Apply(companyApprovalId, "冻结转试用申请单")
	if err != nil {
		br.Msg = "发起审批异常，请联系管理员"
		br.ErrMsg = "客户审批发起异常,Err:" + err.Error()
		return
	}
	if companyApprovalCount == 0 && productId == 2 {
		//获取王芳信息，自动审批使用
		approvalUserInfo, err := system.CheckSysUserByName("王芳", utils.ROLE_TYPE_CODE_RAI_ADMIN)
		if err != nil {
			br.Msg = "权益客户自动审批失败，请联系管理员"
			br.ErrMsg = "审批失败,Err:" + err.Error()
			return
		}
		//数据校验（校验是否具有审批权限）
		_, _, approvalRecord, err := company_apply.CheckApproveAuth(req.CompanyId, productId, approvalUserInfo)
		if err != nil {
			br.Msg = "权益客户自动审批失败，请联系管理员"
			br.ErrMsg = "校验是否具有审批权限失败,Err:" + err.Error()
			return
		}
		err = company_apply.Approved(approvalRecord, approvalUserInfo, "权益客首次申请解冻自动审批通过")
		if err != nil {
			br.Msg = "权益客户自动审批失败，请联系管理员！"
			br.ErrMsg = "审核失败，Err:" + err.Error()
			return
		}
	}
	br.Ret = 200
	br.Success = true
	br.Msg = "申请成功"
}

// ApplyDelay
// @Title 申请延期
// @Description 申请延期接口
// @Param	request	body company.CompanyApplyDelayReq true "type json string"
// @Success Ret=200 申请成功
// @router /apply/delay [post]
func (this *CompanyApplyController) ApplyDelay() {
	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 company.CompanyApplyDelayReq
	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
	if err != nil {
		br.Msg = "参数解析异常！"
		br.ErrMsg = "参数解析失败，Err:" + err.Error()
		return
	}
	if req.CompanyId <= 0 {
		br.Msg = "参数错误"
		br.ErrMsg = "参数错误，客户id小于等于0"
		return
	}
	roleTypeCode := sysUser.RoleTypeCode
	productId := services.GetProductId(roleTypeCode)
	if productId == 0 {
		br.Msg = "参数错误"
		br.ErrMsg = "客户类型为：" + roleTypeCode
		return
	}
	if productId == utils.COMPANY_PRODUCT_FICC_ID && req.PermissionIds == "" {
		br.Msg = "请勾选需要延期的品种"
		br.ErrMsg = "请勾选需要延期的品种"
		return
	}

	//添加缓存，避免多次点击提交
	{
		deleteCache := true
		cacheKey := "CACHE_COMPANY_APPLY_" + strconv.Itoa(req.CompanyId) + "_" + strconv.Itoa(productId)
		defer func() {
			if deleteCache {
				utils.Rc.Delete(cacheKey)
			}
		}()
		if !utils.Rc.SetNX(cacheKey, 1, 30*time.Second) {
			deleteCache = false
			br.Msg = "系统处理中，请勿重复操作"
			br.ErrMsg = "系统处理中，请勿重复操作" + sysUser.RealName + ";data:" + string(this.Ctx.Input.RequestBody)
			return
		}
	}

	approveRoleTypeCode := ""
	if productId == 1 {
		approveRoleTypeCode = utils.ROLE_TYPE_CODE_FICC_ADMIN
	} else {
		approveRoleTypeCode = utils.ROLE_TYPE_CODE_RAI_ADMIN
	}
	companyProduct, err := company.GetCompanyProductByCompanyIdAndProductId(req.CompanyId, productId)
	if err != nil {
		br.Msg = "获取客户信息失败"
		br.ErrMsg = "获取客户信息失败"
		return
	}
	if companyProduct == nil {
		br.Msg = "获取客户信息失败"
		br.ErrMsg = "客户不存在，不可提交审批：companyId:" + strconv.Itoa(req.CompanyId) + ";productId:" + strconv.Itoa(productId)
		return
	}
	if companyProduct.Status != utils.COMPANY_STATUS_TRY_OUT {
		br.Msg = "客户状态为：" + companyProduct.Status + ";不可进行延期申请"
		br.ErrMsg = "客户状态为：" + companyProduct.Status + ";不可进行延期申请"
		return
	}

	if companyProduct.ApproveStatus == "待审批" {
		br.Msg = "存在待审批订单，不可重复提交"
		return
	}

	//客户归属判断
	if companyProduct.SellerId != sysUser.AdminId && companyProduct.ShareSellerId != sysUser.AdminId {
		br.Msg = "客户信息异常"
		br.ErrMsg = "客户信息异常，不是当前所属销售，客户所属销售：" + companyProduct.SellerName + ";当前销售:" + sysUser.AdminName
		return
	}

	// CRM8.8(仅针对权益客户)-申请延期的权限不再进行选择, 而是自动将所有的试用权限延期
	if companyProduct.ProductId == utils.COMPANY_PRODUCT_RAI_ID {
		reportPermissions, e := company.GetCompanyReportPermission(req.CompanyId, utils.COMPANY_PRODUCT_RAI_ID)
		if e != nil {
			br.Msg = "客户权限信息异常"
			br.ErrMsg = "客户权限信息异常, Err: " + e.Error()
			return
		}
		reportPermissionArr := make([]string, 0)
		for i := range reportPermissions {
			reportPermissionArr = append(reportPermissionArr, strconv.Itoa(reportPermissions[i].ChartPermissionId))
		}
		if len(reportPermissionArr) > 0 {
			req.PermissionIds = strings.Join(reportPermissionArr, ",")
		}
	}

	approveUser, err := company.GetApproveUser(approveRoleTypeCode)
	if err != nil && err.Error() != utils.ErrNoRow() {
		br.Msg = "获取审批信息失败"
		br.ErrMsg = "获取审批人信息失败,Err:" + err.Error()
		return
	}

	if approveUser == nil || (err != nil && err.Error() == utils.ErrNoRow()) {
		br.Msg = "审批用户不存在"
		br.ErrMsg = "审批用户不存在"
		return
	}
	//申请类型：1:试用->正式,2:冻结—>试用,3:试用延期,4:原销售申请领取流失客户，5:正式客户申请服务更新，6：正式客户补充协议
	approveContent := `试用延期`
	var companyApprovalId int
	utils.FileLog.Info("试用延期申请：%d", req.CompanyApprovalId)
	if req.CompanyApprovalId > 0 {
		utils.FileLog.Info("试用延期申请：%d", req.CompanyApprovalId)
		err = company.ModifyCompanyApproval(req.CompanyId, productId, req.CompanyApprovalId, approveContent, req.ApplyRemark)
		if err != nil {
			br.Msg = "申请失败"
			br.ErrMsg = "申请失败,Err:" + err.Error()
			return
		}
		companyApprovalId = req.CompanyApprovalId
	} else {
		applyMethod := 3
		approval := new(company.CompanyApproval)
		approval.CompanyId = req.CompanyId
		approval.ProductId = productId
		approval.ApproveStatus = "待审批"
		approval.ApproveUserId = 0
		approval.ApproveRoleTypeCode = approveRoleTypeCode
		approval.ApproveRealName = ""
		approval.ApproveTime = time.Now()
		approval.ApproveContent = "试用延期"
		approval.ApplyMethod = applyMethod
		approval.ApplyReasons = req.ApplyRemark
		approval.ApplyUserId = sysUser.AdminId
		approval.ApplyRealName = sysUser.RealName
		approval.CreateTime = time.Now()
		approval.ModifyTime = time.Now()
		companyApprovalId, err = company.AddCompanyApproval(approval)
		if err != nil {
			br.Msg = "申请失败"
			br.ErrMsg = "申请失败,Err:" + err.Error()
			return
		}
	}
	//处理权限
	{
		if req.PermissionIds != "" {
			// CRM8.8(仅针对权益客户)-此处不再去查询主观对应的客观, 而是根据客户之前拥有的权限来操作
			//permissionStr, err := company.GetPermissionIdById(req.PermissionIds)
			//if err != nil {
			//	br.Msg = "获取信息失败"
			//	br.ErrMsg = "获取主观客观权限信息失败,Err:" + err.Error()
			//	return
			//}
			//req.PermissionIds = permissionStr
			permissionArr := strings.Split(req.PermissionIds, ",")
			//如果是编辑的话，删除原先相关的所有品种权限
			if req.CompanyApprovalId > 0 {
				err = company.DeleteCompanyDelayPermission(req.CompanyApprovalId)
				if err != nil {
					br.Msg = "申请失败"
					br.ErrMsg = "删除之前的申请记录失败,Err:" + err.Error()
					return
				}
			}
			for k, v := range permissionArr {
				fmt.Println(k, v)
				permissionId, _ := strconv.Atoi(v)
				//companyId, companyApplyId, chartPermissionId int
				count, err := company.GetDelayPermissionCount(req.CompanyId, companyApprovalId, permissionId)
				if err != nil && err.Error() != utils.ErrNoRow() {
					br.Msg = "申请失败"
					br.ErrMsg = "判断权限是否存在失败,Err:" + err.Error()
					return
				}
				if count > 0 { //修改
					err = company.ModifyCompanyDelayPermission(req.CompanyId, companyApprovalId, permissionId)
					if err != nil {
						br.Msg = "申请失败"
						br.ErrMsg = "修改权限失败,Err:" + err.Error()
						return
					}
				} else { //新增
					if v != "" {
						permissionId, err := strconv.Atoi(v)
						if err != nil {
							br.Msg = "申请失败"
							br.ErrMsg = "权限格式转换失败,Err:" + err.Error()
							return
						}
						delayItem := new(company.CompanyDelayPermission)
						delayItem.CompanyId = req.CompanyId
						delayItem.CompanyApplyId = companyApprovalId
						delayItem.ChartPermissionId = permissionId
						delayItem.StartDate = time.Now().Format(utils.FormatDate)
						delayItem.EndDate = time.Now().AddDate(0, 2, 0).Format(utils.FormatDate)
						delayItem.CreateTime = time.Now()
						delayItem.ModifyTime = time.Now()
						err = company.AddCompanyDelayPermission(delayItem)
						if err != nil {
							br.Msg = "申请失败"
							br.ErrMsg = "新增延期审批权限失败,Err:" + err.Error()
							return
						}
					}
				}
			}
		}
	}
	//新增操作记录
	{
		remark := "申请延期"
		operation := "delay"
		go services.AddCompanyOperationRecord(req.CompanyId, companyProduct.SellerId, sysUser.AdminId, productId, 0, companyProduct.CompanyName,
			companyProduct.ProductName, sysUser.RealName, remark, operation, approveContent, "", "", companyProduct.Status)
	}
	//新增客户产品日志
	{
		logType := "modify"
		go services.AddCompanyProductLog(companyProduct, this.SysUser.AdminId, logType)
	}

	err = company_apply.Apply(companyApprovalId, "试用延期申请单")
	if err != nil {
		br.Msg = "发起审批异常，请联系管理员"
		br.ErrMsg = "客户审批发起异常,Err:" + err.Error()
		return
	}
	br.Ret = 200
	br.Success = true
	br.Msg = "申请成功"
}

// ApplyReceive
// @Title 申请领取
// @Description 申请领取接口
// @Param	request	body company.CompanyApplyReceiveReq true "type json string"
// @Success Ret=200 申请成功
// @router /apply/receive [post]
func (this *CompanyApplyController) ApplyReceive() {
	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 company.CompanyApplyReceiveReq
	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
	if err != nil {
		br.Msg = "参数解析异常！"
		br.ErrMsg = "参数解析失败，Err:" + err.Error()
		return
	}
	if req.CompanyId <= 0 {
		br.Msg = "参数错误"
		br.ErrMsg = "参数错误，客户id小于等于0"
		return
	}
	// 查询当前销售是否有领取客户的权限
	receiveEnabled, _ := services.CheckCompanyReceiveButton(sysUser.AdminId)
	if !receiveEnabled {
		br.Msg = "领取失败，您目前没有领取客户的权限"
		br.ErrMsg = "领取失败，您目前没有领取客户的权限"
		return
	}
	roleTypeCode := sysUser.RoleTypeCode
	productId := services.GetProductId(roleTypeCode)
	if productId == 0 {
		br.Msg = "参数错误"
		br.ErrMsg = "客户类型为：" + roleTypeCode
		return
	}

	//如果是权益客户,在选择非研选行业试用时，需要判断当前有多少非研选的试用客户（试用状态，且行业是非研选）
	if productId == utils.COMPANY_PRODUCT_RAI_ID {
		permissionArr := strings.Split(req.PermissionIds, ",")
		//如果所选行业不属于研选订阅跟研选扣点包，那就是非研选试用客户
		var isNoResearch bool
		for _, v := range permissionArr {
			if v != strconv.Itoa(utils.CHART_PERMISSION_ID_YANXUAN) && v != strconv.Itoa(utils.YAN_XUAN_KOU_DIAN_BAO_ID) {
				isNoResearch = true
				continue
			}
		}
		if isNoResearch {
			tryOutCountRai, err := company.GetRaiCompanyTryOutCountNoResearch(sysUser.AdminId)
			if err != nil {
				br.Msg = "判断试用客户量失败"
				br.ErrMsg = "判断试用客户量失败,Err:" + err.Error()
				return
			}
			if tryOutCountRai >= utils.COMPANY_STATUS_TRY_OUT_COUNT_RAI {
				br.Msg = "非研选试用客户最多40家"
				return
			}
		}
	}

	//添加缓存，避免多次点击提交
	{
		deleteCache := true
		cacheKey := "CACHE_COMPANY_APPLY_" + strconv.Itoa(req.CompanyId) + "_" + strconv.Itoa(productId)
		defer func() {
			if deleteCache {
				utils.Rc.Delete(cacheKey)
			}
		}()
		if !utils.Rc.SetNX(cacheKey, 1, 30*time.Second) {
			deleteCache = false
			br.Msg = "系统处理中，请勿重复操作"
			br.ErrMsg = "系统处理中，请勿重复操作" + sysUser.RealName + ";data:" + string(this.Ctx.Input.RequestBody)
			return
		}
	}

	approveRoleTypeCode := ""
	if productId == 1 {
		approveRoleTypeCode = utils.ROLE_TYPE_CODE_FICC_ADMIN
	} else {
		approveRoleTypeCode = utils.ROLE_TYPE_CODE_RAI_ADMIN
	}
	companyProduct, err := company.GetCompanyProductByCompanyIdAndProductId(req.CompanyId, productId)
	if err != nil {
		br.Msg = "获取客户信息失败"
		br.ErrMsg = "获取客户信息失败"
		return
	}

	if companyProduct == nil {
		br.Msg = "获取客户信息失败"
		br.ErrMsg = "客户不存在，不可提交审批：companyId:" + strconv.Itoa(req.CompanyId) + ";productId:" + strconv.Itoa(productId)
		return
	}

	if companyProduct.Status != utils.COMPANY_STATUS_LOSE {
		br.Msg = "客户状态为：" + companyProduct.Status + ";不可进行延期申请"
		br.ErrMsg = "客户状态为：" + companyProduct.Status + ";不可进行延期申请"
		return
	}

	if companyProduct.ApproveStatus == "待审批" {
		br.Msg = "存在待审批订单，不可重复提交"
		return
	}

	approveUser, err := company.GetApproveUser(approveRoleTypeCode)
	if err != nil && err.Error() != utils.ErrNoRow() {
		br.Msg = "获取审批信息失败"
		br.ErrMsg = "获取审批人信息失败,Err:" + err.Error()
		return
	}

	if approveUser == nil || (err != nil && err.Error() == utils.ErrNoRow()) {
		br.Msg = "审批用户不存在"
		br.ErrMsg = "审批用户不存在"
		return
	}

	approveContent := `原销售申领客户`
	applyMethod := 4
	var companyApprovalId int
	//申请类型：1:试用->正式,2:冻结—>试用,3:试用延期,4:原销售申请领取流失客户，5:正式客户申请服务更新，6：正式客户补充协议
	if req.CompanyApprovalId <= 0 {
		approval := new(company.CompanyApproval)
		approval.CompanyId = req.CompanyId
		approval.ProductId = productId
		approval.ApproveStatus = "待审批"
		approval.ApproveUserId = 0
		approval.ApproveRoleTypeCode = approveRoleTypeCode
		approval.ApproveRealName = ""
		approval.ApproveTime = time.Now()
		approval.ApproveContent = approveContent
		approval.ApplyMethod = applyMethod
		approval.ApplyReasons = req.ApplyRemark
		approval.ApplyUserId = sysUser.AdminId
		approval.ApplyRealName = sysUser.RealName
		approval.CreateTime = time.Now()
		approval.ModifyTime = time.Now()
		companyApprovalId, err = company.AddCompanyApproval(approval)
		if err != nil {
			br.Msg = "申请失败"
			br.ErrMsg = "申请失败,Err:" + err.Error()
			return
		}
	} else {
		err = company.ModifyCompanyApproval(req.CompanyId, productId, req.CompanyApprovalId, approveContent, req.ApplyRemark)
		if err != nil {
			br.Msg = "申请失败"
			br.ErrMsg = "申请失败,Err:" + err.Error()
			return
		}
		companyApprovalId = req.CompanyApprovalId

		//先删除之前申请的权限
		_ = company.DeleteCompanyDelayPermission(req.CompanyApprovalId)
	}

	//处理权限
	{
		if req.PermissionIds != "" {
			permissionStr, err := company.GetPermissionIdById(req.PermissionIds)
			if err != nil {
				br.Msg = "获取信息失败"
				br.ErrMsg = "获取主观客观权限信息失败,Err:" + err.Error()
				return
			}
			req.PermissionIds = permissionStr
			permissionArr := strings.Split(req.PermissionIds, ",")
			for _, v := range permissionArr {
				if v != "" {
					permissionId, err := strconv.Atoi(v)
					if err != nil {
						br.Msg = "申请失败"
						br.ErrMsg = "权限格式转换失败,Err:" + err.Error()
						return
					}
					delayItem := new(company.CompanyDelayPermission)
					delayItem.CompanyId = req.CompanyId
					delayItem.CompanyApplyId = companyApprovalId
					delayItem.ChartPermissionId = permissionId
					delayItem.StartDate = time.Now().Format(utils.FormatDate)
					delayItem.EndDate = time.Now().AddDate(0, 2, 0).Format(utils.FormatDate)
					delayItem.CreateTime = time.Now()
					delayItem.ModifyTime = time.Now()
					err = company.AddCompanyDelayPermission(delayItem)
					if err != nil {
						br.Msg = "申请失败"
						br.ErrMsg = "新增领取客户审批权限失败,Err:" + err.Error()
						return
					}
				}
			}
		}
	}

	//新增操作记录
	{
		remark := "申请领取"
		operation := "apply_receive"
		services.AddCompanyOperationRecord(req.CompanyId, companyProduct.SellerId, sysUser.AdminId, productId, 0, companyProduct.CompanyName,
			companyProduct.ProductName, sysUser.RealName, remark, operation, approveContent, "", "", companyProduct.Status)
	}
	//新增客户产品日志
	{
		logType := "modify"
		go services.AddCompanyProductLog(companyProduct, this.SysUser.AdminId, logType)
	}

	err = company_apply.Apply(companyApprovalId, "申请领取申请单")
	if err != nil {
		br.Msg = "发起审批异常，请联系管理员"
		br.ErrMsg = "客户审批发起异常,Err:" + err.Error()
		return
	}
	br.Ret = 200
	br.Success = true
	br.Msg = "申请成功"
}

// ApplyRevoke
// @Title 申请撤回
// @Description 申请撤回接口
// @Param	request	body company.CompanyApplyRevokeReq true "type json string"
// @Success Ret=200 成功
// @router /apply/revoke [post]
func (this *CompanyApprovalController) ApplyRevoke() {
	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 company.CompanyApplyRevokeReq
	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
	if err != nil {
		br.Msg = "参数解析异常！"
		br.ErrMsg = "参数解析失败，Err:" + err.Error()
		return
	}
	if req.CompanyId <= 0 {
		br.Msg = "参数错误"
		br.ErrMsg = "客户Id小于等于0："
		return
	}
	roleTypeCode := sysUser.RoleTypeCode
	productId := services.GetProductId(roleTypeCode)
	if productId == 0 {
		br.Msg = "参数错误"
		br.ErrMsg = "客户类型为：" + roleTypeCode
		return
	}

	//添加缓存，避免多次点击提交
	{
		deleteCache := true
		cacheKey := "CACHE_COMPANY_APPLY_" + strconv.Itoa(req.CompanyId) + "_" + strconv.Itoa(productId)
		defer func() {
			if deleteCache {
				utils.Rc.Delete(cacheKey)
			}
		}()
		if !utils.Rc.SetNX(cacheKey, 1, 30*time.Second) {
			deleteCache = false
			br.Msg = "系统处理中，请勿重复操作"
			br.ErrMsg = "系统处理中，请勿重复操作" + sysUser.RealName + ";data:" + string(this.Ctx.Input.RequestBody)
			return
		}
	}

	companyProduct, err := company.GetCompanyProductByCompanyIdAndProductId(req.CompanyId, productId)
	if err != nil {
		br.Msg = "获取客户信息失败"
		br.ErrMsg = "获取客户信息失败"
		return
	}

	if companyProduct == nil {
		br.Msg = "获取客户信息失败"
		br.ErrMsg = "客户不存在，不可提交审批：companyId:" + strconv.Itoa(req.CompanyId) + ";productId:" + strconv.Itoa(productId)
		return
	}

	approvalItem, err := company.GetCompanyApprovalById(req.CompanyId, productId)
	if err != nil {
		if err.Error() == utils.ErrNoRow() {
			br.Msg = "待审批信息不存在"
			br.ErrMsg = "待审批信息不存在,CompanyId:" + strconv.Itoa(req.CompanyId) + ";productId:" + strconv.Itoa(productId)
			return
		}
		br.Msg = "获取信息失败"
		br.ErrMsg = "获取信息失败,Err:" + err.Error()
		return
	}
	if approvalItem == nil {
		br.Msg = "待审批信息不存在"
		br.ErrMsg = "待审批信息不存在,CompanyId:" + strconv.Itoa(req.CompanyId) + ";productId:" + strconv.Itoa(productId)
		return
	}

	if approvalItem.ApproveStatus != "待审批" {
		br.Msg = "客户状态为：" + companyProduct.Status + ";不可进行撤回操作"
		br.ErrMsg = "客户状态为：" + companyProduct.Status + ";不可进行撤回操作"
		return
	}
	//撤回审批单
	err = company_apply.CancelApply(approvalItem, sysUser.AdminId)
	if err != nil {
		br.Msg = "撤回失败"
		br.ErrMsg = "撤回失败,Err:" + err.Error()
		return
	}

	//真正撤回操作
	err = company.ApplyRevoke(approvalItem.CompanyApprovalId, approvalItem.CompanyId, approvalItem.ProductId)
	if err != nil {
		br.Msg = "撤回失败"
		br.ErrMsg = "撤回失败,Err:" + err.Error()
		return
	}
	//新增操作记录
	{
		remark := "撤回"
		operation := "apply_revoke"
		services.AddCompanyOperationRecord(req.CompanyId, companyProduct.SellerId, sysUser.AdminId, productId, 0, companyProduct.CompanyName,
			companyProduct.ProductName, sysUser.RealName, remark, operation, "", "", "", companyProduct.Status)
	}
	br.Ret = 200
	br.Success = true
	br.Msg = "撤回成功"
}
