Forráskód Böngészése

Merge branch 'debug' of http://8.136.199.33:3000/hongze/hongze_mobile_admin into debug

xingzai 1 éve
szülő
commit
2ac9eb96e2

+ 8 - 8
models/db_init.go

@@ -24,6 +24,7 @@ import (
 	"hongze/hongze_mobile_admin/models/tables/company_product_try_out_update_log"
 	"hongze/hongze_mobile_admin/models/tables/company_product_try_out_update_permission_log"
 	"hongze/hongze_mobile_admin/models/tables/company_product_update_log"
+	"hongze/hongze_mobile_admin/models/tables/company_renewal_record"
 	"hongze/hongze_mobile_admin/models/tables/company_report_permission"
 	"hongze/hongze_mobile_admin/models/tables/contract"
 	"hongze/hongze_mobile_admin/models/tables/contract_approval"
@@ -70,7 +71,6 @@ func init() {
 	report_db, _ := orm.GetDB("rddp")
 	report_db.SetConnMaxLifetime(10 * time.Minute)
 
-
 	_ = orm.RegisterDataBase("hz_cygx", "mysql", utils.MYSQL_URL_CYGX)
 	orm.SetMaxIdleConns("hz_cygx", 50)
 	orm.SetMaxOpenConns("hz_cygx", 100)
@@ -124,14 +124,14 @@ func init() {
 		new(chart_permission.ChartPermission),                                 // 品种权限表
 		new(company_product_try_out_update_log.CompanyProductTryOutUpdateLog), //客户产品试用变更状态表
 		new(company_product_try_out_update_permission_log.CompanyProductTryOutUpdatePermissionLog), //客户产品试用变更品种详情表
-		new(english_company.EnglishCompany), // 英文客户表
-		new(cygx_company_user_type.CygxCompanyUserType), // 英文客户表
-		new(cygx.CygxActivitySpecialTripBill), // 专项调研确定行程活动报名流水表
-		new(cygx_allocation_company_contract.CygxAllocationCompanyContract), //权益合同派点(研究员)
-		new(cygx_allocation_company_contract.CygxAllocationCompanyContractLog), //权益合同派点日志(研究员)
-		new(cygx_allocation_company_contract.CygxAllocationCompanyContractPermission), //权益合同派点(行业)
+		new(english_company.EnglishCompany),                                              // 英文客户表
+		new(cygx_company_user_type.CygxCompanyUserType),                                  // 英文客户表
+		new(cygx.CygxActivitySpecialTripBill),                                            // 专项调研确定行程活动报名流水表
+		new(cygx_allocation_company_contract.CygxAllocationCompanyContract),              //权益合同派点(研究员)
+		new(cygx_allocation_company_contract.CygxAllocationCompanyContractLog),           //权益合同派点日志(研究员)
+		new(cygx_allocation_company_contract.CygxAllocationCompanyContractPermission),    //权益合同派点(行业)
 		new(cygx_allocation_company_contract.CygxAllocationCompanyContractPermissionLog), //权益合同派点日志(行业)
-
+		new(company_renewal_record.CompanyRenewalRecord),                                 // 客户续约状态记录表
 	)
 
 	// 社区问答相关

+ 8 - 0
models/tables/company_contract/company_contract.go

@@ -116,3 +116,11 @@ func UpdateCompanyContractPackageDifference(packageDifference string, companyCon
 	return
 }
 
+// GetLastContractListByEndDate 通过最近一份合同的日期获取早于该合同的最晚一份合同
+func GetLastContractListByEndDate(companyId, productId int, endDate string) (item *CompanyContract, err error) {
+	o := orm.NewOrm()
+	sql := "SELECT * FROM company_contract where company_id = ? AND product_id= ? end_date < ? AND status = 1 ORDER BY end_date desc"
+	err = o.Raw(sql, companyId, productId, endDate).QueryRow(&item)
+
+	return
+}

+ 65 - 1
models/tables/company_product/company_product.go

@@ -46,9 +46,73 @@ func GetCompanyProductByCompanyIdAndProductId(companyId, productId int) (item *C
 	return
 }
 
-//更新客户产品信息
+// 更新客户产品信息
 func (companyProduct *CompanyProduct) Update(cols []string) (err error) {
 	o := orm.NewOrm()
 	_, err = o.Update(companyProduct, cols...)
 	return
 }
+
+// CompanyProductItem
+// @Description: 客户品种
+type CompanyProductItem struct {
+	CompanyProductId int       `orm:"column(company_product_id);pk" description:"客户产品id"`
+	CompanyId        int       `description:"客户id"`
+	ProductId        int       `description:"产品id"`
+	ProductName      string    `description:"产品名称"`
+	CompanyName      string    `description:"客户名称"`
+	Source           string    `description:"来源"`
+	Reasons          string    `description:"新增理由"`
+	Status           string    `description:"客户状态"`
+	IndustryId       int       `description:"行业id"`
+	IndustryName     string    `description:"行业名称"`
+	SellerId         int       `description:"销售id"`
+	SellerName       string    `description:"销售名称"`
+	GroupId          int       `description:"销售分组id"`
+	DepartmentId     int       `description:"销售部门id"`
+	IsSuspend        int       `description:"1:暂停,0:启用"`
+	SuspendTime      time.Time `description:"暂停启用时间"`
+	ApproveStatus    string    `description:"审批状态:'审批中','通过','驳回'"`
+	FreezeTime       time.Time `description:"冻结时间"`
+	Remark           string    `description:"备注信息"`
+	CreateTime       time.Time `description:"创建时间"`
+	ModifyTime       time.Time `description:"修改时间"`
+	StartDate        string    `description:"开始日期"`
+	EndDate          string    `description:"结束日期"`
+	ContractEndDate  string    `description:"合同结束日期"`
+	LoseReason       string    `description:"流失原因"`
+	LossTime         time.Time `description:"流失时间"`
+	CompanyType      string    `description:"客户类型"`
+	OpenCode         string    `description:"开放给第三方的编码,不让第三方定位我们的客户信息"`
+	Scale            string    `description:"管理规模,空不填,1::50亿以下,2:50~100亿,3:100亿以上。"`
+	ViewTotal        int       `description:"总阅读次数"`
+	RoadShowTotal    int       `description:"累计路演次数"`
+	LastViewTime     time.Time `description:"最后一次阅读时间"`
+	PackageType      int       `description:"套餐类型,0:无,1:大套餐,2:小套餐"`
+	IsFormal         int       `description:"是否已经转正式,0是没有转正式,1是已经转过正式"`
+	TodoStatus       string    `description:"任务处理状态;枚举值:'无任务','未完成','已完成'"`
+	TodoCreateTime   time.Time `description:"任务创建时间"`
+	TodoApproveTime  time.Time `description:"任务审批时间"`
+	TryStage         int       `description:"试用客户子标签:1未分类、2  推进、3 跟踪、4 预备"`
+	IsShare          int       `description:"0:非共享用户,1:共享客户"`
+	ShareSeller      string    `description:"共享销售员"`
+	ShareSellerId    int       `description:"共享销售员id"`
+}
+
+// GetCompanyProductItemByCompanyId
+// @Description: 根据客户ID获取客户产品列表
+// @author: Roc
+// @datetime 2023-12-07 11:06:58
+// @param companyIdList []int
+// @param productId int
+// @return items []*CompanyProductItem
+// @return err error
+func GetCompanyProductItemByCompanyId(companyId int, productId int) (items *CompanyProductItem, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT a.*,b.is_share,b.share_seller,b.share_seller_id FROM company_product as a 
+         JOIN company b on a.company_id=b.company_id
+         WHERE a.company_id = ? AND a.product_id = ? `
+	_, err = o.Raw(sql, companyId, productId).QueryRows(&items)
+
+	return
+}

+ 61 - 0
models/tables/company_renewal_record/company_renewal_record.go

@@ -0,0 +1,61 @@
+package company_renewal_record
+
+import (
+	"github.com/beego/beego/v2/client/orm"
+	"time"
+)
+
+// CompanyRenewalRecord
+// @Description: 客户续约状态记录表
+type CompanyRenewalRecord struct {
+	Id              int       `orm:"column(id);pk"`
+	CompanyId       int       `description:"客户id"`
+	ProductId       int       `description:"产品id"`
+	Source          int       `description:"类型,枚举值,1:续约异常客户;2:续约正常客户;3:超时续约客户"`
+	SellerId        int       `description:"销售id"`
+	SellerName      string    `description:"销售名称"`
+	ShareSellerId   int       `description:"共享销售id"`
+	ShareSellerName string    `description:"共享销售名称"`
+	CreateTime      time.Time `description:"创建时间"`
+	ModifyTime      time.Time `description:"修改时间"`
+}
+
+// GetUnusualRenewCompanyList 获取销售未续约数据
+func GetUnusualRenewCompanyList(startDate, endDate time.Time, productId int) (list []*CompanyRenewalRecord, err error) {
+	o := orm.NewOrm()
+	sql := `	SELECT
+	a.seller_id,a.share_seller_id,
+	count(
+	DISTINCT ( a.company_id )) num,
+	GROUP_CONCAT( DISTINCT a.company_id SEPARATOR ',' ) AS company_ids 
+	FROM
+	company_renewal_record as a
+WHERE
+	a.modify_time BETWEEN ? 
+	AND ? 
+    AND a.source = 1 
+	AND a.product_id = ?
+GROUP BY
+	a.seller_id;
+`
+	_, err = o.Raw(sql, startDate, endDate, productId).QueryRows(&list)
+
+	return
+}
+
+// Add
+// @Description: 添加续约用户记录
+// @author: Roc
+// @datetime 2023-12-07 14:16:37
+// @param item *CompanyRenewalRecord
+// @return err error
+func (item *CompanyRenewalRecord) Add() (err error) {
+	o := orm.NewOrm()
+	lastId, err := o.Insert(item)
+	if err != nil {
+		return
+	}
+	item.Id = int(lastId)
+
+	return
+}

+ 79 - 2
services/company_approval/company_approval.go

@@ -17,6 +17,7 @@ import (
 	"hongze/hongze_mobile_admin/models/tables/company_product_log"
 	"hongze/hongze_mobile_admin/models/tables/company_product_try_out_update_log"
 	"hongze/hongze_mobile_admin/models/tables/company_product_update_log"
+	"hongze/hongze_mobile_admin/models/tables/company_renewal_record"
 	"hongze/hongze_mobile_admin/models/tables/company_report_permission"
 	"hongze/hongze_mobile_admin/models/tables/contract_approval"
 	"hongze/hongze_mobile_admin/models/tables/contract_approval_record"
@@ -437,8 +438,8 @@ func Approved(approvalRecord *contract_approval_record.ContractApprovalRecord, o
 				//客户研选行业转正时(王芳审批通过),模板消息提醒汪洋
 				services.AddCompanyApprovalMessageWangYang(recordInfo.CompanyId, recordInfo.CompanyContractId, recordInfo.ApplyRealName, companyInfo.CompanyName)
 
-				cygxService.YanXuanCompanyApproval(recordInfo.CompanyId) //研选审批通过的时候研选扣点更新
-				cygxService.HandleAllocationCompanyContractByYanXuan(recordInfo.CompanyContractId)   //如果合同只有研选的时候,自动处理派点
+				cygxService.YanXuanCompanyApproval(recordInfo.CompanyId)                           //研选审批通过的时候研选扣点更新
+				cygxService.HandleAllocationCompanyContractByYanXuan(recordInfo.CompanyContractId) //如果合同只有研选的时候,自动处理派点
 				cygxService.HandleCompanyContractPackageDifference(recordInfo.CompanyContractId)   // 更新与上一份合同的金额的对比 '增加套餐','减少套餐','维持套餐'
 				cygxService.HandleCompanyContractPermissionContractType(recordInfo.CompanyContractId)   // 更新合同权限表中的权限名称,以及对应的行业权限类型(行业新签、行业续约)
 			}
@@ -769,6 +770,9 @@ func afterApproved(companyApprovalId int, opUserId int, opUserName string) (err
 
 		//如果合同时间小于等于今天,那么立马执行合同内容
 		if time.Now().After(contractStartDate) {
+			// 合同处理完成后的续约异常记录
+			contactHandleCompanyRenewalRecord(contractInfo)
+
 			companyReportPermissionList, err = company_approval.ApplyServiceUpdate(recodeInfo.CompanyId, recodeInfo.ProductId, opUser.AdminId, recodeInfo.CompanyApprovalId, recodeInfo.CompanyContractId, companyProduct.StartDate, contractInfo.EndDate, opUser.RealName, companyProduct.ProductName, contractInfo.PackageType, contractInfo.RaiPackageType)
 			if tmpErr != nil {
 				err = errors.New(fmt.Sprint("正式客户申请服务更新失败,执行失败;Err:" + tmpErr.Error()))
@@ -897,6 +901,79 @@ func afterApproved(companyApprovalId int, opUserId int, opUserName string) (err
 	return
 }
 
+// contactHandleCompanyRenewalRecord
+// @Description: 合同处理完成后的续约异常记录
+// @author: Roc
+// @datetime 2023-12-07 14:24:44
+// @param contractInfo *company_contract.CompanyContract
+// @param day string
+// @return err error
+func contactHandleCompanyRenewalRecord(contractInfo *company_contract.CompanyContractDetail) {
+	var err error
+	defer func() {
+		if err != nil {
+			utils.FileLog.Error("合同处理完成后的续约异常记录," + err.Error())
+		}
+	}()
+	// 判断合同类型是否是续约合同,如果不是的话,就不往下走了
+	if contractInfo.ContractType != `续约合同` {
+		return
+	}
+
+	day := time.Now().Format(utils.FormatDate)
+
+	// 获取早于当前合同结束日期的上一份合同
+	lastContract, tmpErr := company_contract.GetLastContractListByEndDate(contractInfo.CompanyId, contractInfo.ProductId, contractInfo.EndDate)
+	if tmpErr != nil {
+		err = errors.New(fmt.Sprint("合同id:", contractInfo.CompanyContractId, ";通过最近一份合同的日期获取早于该合同的最晚一份合同失败,ERR:", tmpErr))
+		return
+	}
+	// 校验 上一份合同的结束日期 与 今天 相隔的天数
+	betweenDay, tmpErr := utils.GetDaysBetween2Date(utils.FormatDate, day, lastContract.EndDate)
+	if tmpErr != nil {
+		err = errors.New(fmt.Sprint("合同id:", contractInfo.CompanyContractId, ";计算两个日期相差的天数失败,ERR:", tmpErr))
+		return
+	}
+
+	source := 2 // 正常续约
+	// 如果间隔时间超过60天,那么标记为超时续约
+	if betweenDay > 60 {
+		source = 3 // 超时续约
+	}
+
+	// 如果间隔时间超过60天,那么标记为超时续约
+	companyProductItem, tmpErr := company_product.GetCompanyProductItemByCompanyId(contractInfo.CompanyId, contractInfo.ProductId)
+	if tmpErr != nil {
+		err = errors.New(fmt.Sprint("合同id:", contractInfo.CompanyContractId, ";GetCompanyProductItemByCompanyId失败,ERR:", tmpErr))
+		return
+	}
+
+	var shareSellerId int
+	var shareSellerName string
+	if companyProductItem.IsShare == 1 {
+		shareSellerId = companyProductItem.ShareSellerId
+		shareSellerName = companyProductItem.ShareSeller
+	}
+	item := &company_renewal_record.CompanyRenewalRecord{
+		Id:              0,
+		CompanyId:       contractInfo.CompanyId,
+		ProductId:       contractInfo.ProductId,
+		Source:          source,
+		SellerId:        companyProductItem.SellerId,
+		SellerName:      companyProductItem.SellerName,
+		ShareSellerId:   shareSellerId,
+		ShareSellerName: shareSellerName,
+		CreateTime:      time.Now(),
+		ModifyTime:      time.Now(),
+	}
+	tmpErr = item.Add()
+	if tmpErr != nil {
+		err = errors.New(fmt.Sprint("合同id:", contractInfo.CompanyContractId, ";添加续约异常记录失败,ERR:", tmpErr))
+	}
+
+	return
+}
+
 // afterReject 驳回完成后操作
 func afterReject(companyApprovalId, opUserId int, opUserName, remark string) (err error) {
 	defer func() {

+ 16 - 0
utils/common.go

@@ -943,3 +943,19 @@ func GetNowYearLastDay() time.Time {
 	nowYearLastDay := time.Date(time.Now().Year(), 12, 31, 23, 59, 59, 0, time.Now().Location())
 	return nowYearLastDay
 }
+
+// GetDaysBetween2Date 计算两个日期之间相差几天
+func GetDaysBetween2Date(format, date1Str, date2Str string) (int, error) {
+	// 将字符串转化为Time格式
+	date1, err := time.ParseInLocation(format, date1Str, time.Local)
+	if err != nil {
+		return 0, err
+	}
+	// 将字符串转化为Time格式
+	date2, err := time.ParseInLocation(format, date2Str, time.Local)
+	if err != nil {
+		return 0, err
+	}
+	//计算相差天数
+	return int(date1.Sub(date2).Hours() / 24), nil
+}