ソースを参照

Merge branch 'master' into eta/1.3

hsun 1 年間 前
コミット
b35fc932de

+ 0 - 100
controllers/cygx/activity_special.go

@@ -1184,103 +1184,3 @@ func (this *ActivitySpecialCoAntroller) Offline() {
 	br.Msg = "操作成功"
 	br.IsAddLog = true
 }
-
-// @Title 发送模版消息
-// @Description 发送模版消息接口
-// @Param	request	body cygx.AddOutboundPersonnelItm true "type json string"
-// @Success 200 操作成功
-// @router /special/trip/tempMsg [post]
-func (this *ActivitySpecialTripCoAntroller) TempMsg() {
-	br := new(models.BaseResponse).Init()
-	defer func() {
-		this.Data["json"] = br
-		this.ServeJSON()
-	}()
-	AdminUser := this.SysUser
-	if AdminUser == nil {
-		br.Msg = "请登录"
-		br.ErrMsg = "请登录,SysUser Is Empty"
-		return
-	}
-	var req cygx.ActivitySpecialSignupTempMsgReq
-	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
-	if err != nil {
-		br.Msg = "参数解析异常!"
-		br.ErrMsg = "参数解析失败,Err:" + err.Error()
-		return
-	}
-	idSlice := strings.Split(req.ActivityIds, ",")
-	for _, sId := range idSlice {
-		id, e := strconv.Atoi(sId)
-		if e != nil {
-			br.Msg = "活动Id参数异常"
-			br.ErrMsg = "参数解析异常, Err:" + e.Error()
-			return
-		}
-		var openIdList []*models.OpenIdList
-		idMap := make(map[string]string, 0)
-		//1已报名
-		if strings.Contains(req.SendGroup, "1") {
-			listSignup, err := cygx.GetCygxActivitySpecialTripListByActivityId(id)
-			if err != nil {
-				br.Msg = "查询报名信息失败失败"
-				br.ErrMsg = "GetCygxActivitySpecialTripListByActivityId,Err:" + err.Error()
-				return
-			}
-			if len(listSignup) == 0 {
-				continue
-			}
-			var mobileArr []string
-			for _, v := range listSignup {
-				if v.Mobile != "" {
-					mobileArr = append(mobileArr, v.Mobile)
-				}
-			}
-			mobileLen := len(mobileArr)
-			var condition string
-			var pars []interface{}
-			if mobileLen > 0 {
-				condition += ` AND u.mobile IN (` + utils.GetOrmInReplace(mobileLen) + `)`
-				pars = append(pars, mobileArr)
-			}
-			list, err := models.GetActivitySpecialOpenIdListMobile(condition, pars)
-			if err != nil {
-				br.Msg = "查询openId失败"
-				br.ErrMsg = "查询openId失败,Err:" + err.Error()
-				return
-			}
-			for _, idList := range list {
-				openIdList = append(openIdList, idList)
-				idMap[idList.OpenId] = idList.OpenId
-			}
-		}
-
-		if len(openIdList) > 0 {
-			openIdArr := make([]string, len(openIdList))
-			for i, v := range openIdList {
-				openIdArr[i] = v.OpenId
-			}
-			sendInfo := new(services.SendWxTemplate)
-			sendInfo.Keyword1 = req.ResearchTheme
-			sendInfo.Keyword2 = req.Content
-			sendInfo.TemplateId = utils.WxMsgTemplateIdActivityChangeApplyXzs
-			sendInfo.RedirectUrl = utils.WX_MSG_PATH_ACTIVITY_SPECIAL_DETAIL + strconv.Itoa(id)
-			if utils.RunMode == "debug" {
-				sendInfo.RedirectUrl = utils.WX_MSG_PATH_ACTIVITY_SPECIAL_DETAIL + strconv.Itoa(110) //测试环境调正式的ID
-			}
-			sendInfo.RedirectTarget = 3
-			sendInfo.Resource = strconv.Itoa(id)
-			sendInfo.SendType = utils.TEMPLATE_MSG_CYGX_ACTIVITY_CUSTOMIZE
-			sendInfo.OpenIdArr = openIdArr
-			e = services.SendTemplateMsg(sendInfo)
-			if e != nil {
-				br.Msg = "推送模板消息失败!"
-				br.ErrMsg = "参数解析失败,Err:" + e.Error()
-				return
-			}
-		}
-	}
-	br.Ret = 200
-	br.Success = true
-	br.Msg = "发送成功"
-}

+ 127 - 0
controllers/cygx/activity_special_trip.go

@@ -8,6 +8,7 @@ import (
 	"hongze/hz_crm_api/models"
 	"hongze/hz_crm_api/models/cygx"
 	"hongze/hz_crm_api/models/system"
+	"hongze/hz_crm_api/services"
 	cygxService "hongze/hz_crm_api/services/cygx"
 	"hongze/hz_crm_api/utils"
 	"os"
@@ -830,3 +831,129 @@ func (this *ActivitySpecialTripCoAntroller) OutboundMobileEdit() {
 	br.Msg = "操作成功"
 	br.IsAddLog = true
 }
+
+// @Title 模版消息发送客户类型列表
+// @Description 模版消息发送客户类型列表接口
+// @Success Ret=200
+// @router /special/trip/tempMsg/sendGroupList [get]
+func (this *ActivitySpecialTripCoAntroller) SendGroupList() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	AdminUser := this.SysUser
+	if AdminUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		return
+	}
+	list := make([]cygx.SendGroup, 0)
+	list = append(list, cygx.SendGroup{
+		Id:   1,
+		Name: "已报名客户",
+	})
+	br.Ret = 200
+	br.Success = true
+	br.Data = list
+}
+
+// @Title 发送模版消息
+// @Description 发送模版消息接口
+// @Param	request	body cygx.AddOutboundPersonnelItm true "type json string"
+// @Success 200 操作成功
+// @router /special/trip/tempMsg [post]
+func (this *ActivitySpecialTripCoAntroller) TempMsg() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	AdminUser := this.SysUser
+	if AdminUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		return
+	}
+	var req cygx.ActivitySpecialSignupTempMsgReq
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+	idSlice := strings.Split(req.ActivityIds, ",")
+	for _, sId := range idSlice {
+		id, e := strconv.Atoi(sId)
+		if e != nil {
+			br.Msg = "活动Id参数异常"
+			br.ErrMsg = "参数解析异常, Err:" + e.Error()
+			return
+		}
+		var openIdList []*models.OpenIdList
+		idMap := make(map[string]string, 0)
+		//1已报名
+		if strings.Contains(req.SendGroup, "1") {
+			listSignup, err := cygx.GetCygxActivitySpecialTripListByActivityId(id)
+			if err != nil {
+				br.Msg = "查询报名信息失败失败"
+				br.ErrMsg = "GetCygxActivitySpecialTripListByActivityId,Err:" + err.Error()
+				return
+			}
+			if len(listSignup) == 0 {
+				continue
+			}
+			var mobileArr []string
+			for _, v := range listSignup {
+				if v.Mobile != "" {
+					mobileArr = append(mobileArr, v.Mobile)
+				}
+			}
+			mobileLen := len(mobileArr)
+			var condition string
+			var pars []interface{}
+			if mobileLen > 0 {
+				condition += ` AND u.mobile IN (` + utils.GetOrmInReplace(mobileLen) + `)`
+				pars = append(pars, mobileArr)
+			}
+			list, err := models.GetActivitySpecialOpenIdListMobile(condition, pars)
+			if err != nil {
+				br.Msg = "查询openId失败"
+				br.ErrMsg = "查询openId失败,Err:" + err.Error()
+				return
+			}
+			for _, idList := range list {
+				openIdList = append(openIdList, idList)
+				idMap[idList.OpenId] = idList.OpenId
+			}
+		}
+
+		if len(openIdList) > 0 {
+			openIdArr := make([]string, len(openIdList))
+			for i, v := range openIdList {
+				openIdArr[i] = v.OpenId
+			}
+			sendInfo := new(services.SendWxTemplate)
+			sendInfo.Keyword1 = req.ResearchTheme
+			sendInfo.Keyword2 = req.Content
+			sendInfo.TemplateId = utils.WxMsgTemplateIdActivityChangeApplyXzs
+			sendInfo.RedirectUrl = utils.WX_MSG_PATH_ACTIVITY_SPECIAL_DETAIL + strconv.Itoa(id)
+			if utils.RunMode == "debug" {
+				sendInfo.RedirectUrl = utils.WX_MSG_PATH_ACTIVITY_SPECIAL_DETAIL + strconv.Itoa(110) //测试环境调正式的ID
+			}
+			sendInfo.RedirectTarget = 3
+			sendInfo.Resource = strconv.Itoa(id)
+			sendInfo.SendType = utils.TEMPLATE_MSG_CYGX_ACTIVITY_CUSTOMIZE
+			sendInfo.OpenIdArr = openIdArr
+			e = services.SendTemplateMsg(sendInfo)
+			if e != nil {
+				br.Msg = "推送模板消息失败!"
+				br.ErrMsg = "参数解析失败,Err:" + e.Error()
+				return
+			}
+		}
+	}
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "发送成功"
+}

+ 43 - 8
controllers/cygx/user.go

@@ -622,7 +622,7 @@ func (this *UserController) TableList() {
 		{PermissionName: "音视频播放", Source: 9, TotalNum: countDetail.RoadshowVideoNum + countDetail.ActivityVideoNum + countDetail.ActivityVoiceNum},
 		{PermissionName: "首页标签点击", Source: 10, TotalNum: countDetail.TagNum}}
 
-resp := new(cygx.CygxUserTableListRep)
+	resp := new(cygx.CygxUserTableListRep)
 	resp.List = List
 	resp.UserName = wxUser.RealName
 	resp.Mobile = wxUser.Mobile
@@ -730,31 +730,67 @@ func (this *UserController) TableDetail() {
 			endDate += " 23:59:59"
 			condition += ` AND r.create_time <= '` + endDate + `' `
 		}
+		if wxUser.Mobile == "" {
+			wxUser.Mobile = wxUser.Email
+		}
 		total, err = cygx.GetCygxArticleHistoryCount(wxUser.Mobile, wxUser.Email, condition)
 		if err != nil {
 			br.Msg = "获取信息失败"
 			br.ErrMsg = "获取用户阅读记录总数失败,Err:" + err.Error()
 			return
 		}
-		list, err = cygx.GetCygxArticleHistoryRecordByUser(wxUser.Mobile, wxUser.Email, condition, startSize, pageSize)
+		list, err = cygx.GetCygxArticleHistoryRecordByUserNew(wxUser.Mobile, wxUser.Email, condition, startSize, pageSize)
 		if err != nil && err.Error() != utils.ErrNoRow() {
 			br.Msg = "获取信息失败"
 			br.ErrMsg = "获取用户阅读记录,Err:" + err.Error()
 			return
 		}
+		var articleIds string
+		var articleIdArr []int
 		if len(list) > 0 {
+			articleIds = ""
+			mapAricleId := make(map[int]int)
+			mapAricleIndustrialSubjectName := make(map[int]*cygx.ArticleIndustrialSubjectNameResp)
 			for k, v := range list {
-				list[k].RegisterPlatform = cygxService.GetArticleSourcePlatform(v.SourcePlatform)
 				if v.ArticleId >= utils.SummaryArticleId {
 					list[k].ArticleType = 1
 				} else {
 					list[k].ArticleType = 2
 				}
-				if list[k].PermissionName == "" {
-					list[k].PermissionName = v.CategoryName
+				if mapAricleId[v.ArticleId] == 0 {
+					articleIds += strconv.Itoa(v.ArticleId) + ","
+					mapAricleId[v.ArticleId] = v.ArticleId
 				}
+				list[k].RegisterPlatform = cygxService.GetArticleSourcePlatform(v.SourcePlatform)
+				articleIdArr = append(articleIdArr, v.ArticleId)
+			}
+			articleIds = strings.TrimRight(articleIds, ",")
+
+			listArticleIndustrialSubjectList, err := cygx.GetCygxArticleIndustrialSubjectName(articleIds)
+			if err != nil && err.Error() != utils.ErrNoRow() {
+				br.Msg = "获取信息失败"
+				br.ErrMsg = "获取用户阅读记录,Err:" + err.Error()
+				return
+			}
+			if len(listArticleIndustrialSubjectList) > 0 {
+				for _, v := range listArticleIndustrialSubjectList {
+					mapAricleIndustrialSubjectName[v.ArticleId] = v
+				}
+				for k, v := range list {
+					if mapAricleIndustrialSubjectName[v.ArticleId] != nil {
+						list[k].IndustryName = mapAricleIndustrialSubjectName[v.ArticleId].IndustryName     // 产业
+						list[k].SubjectNameStr = mapAricleIndustrialSubjectName[v.ArticleId].SubjectNameStr // 标的
+					}
+				}
+			}
+
+			//行业
+			mapPerssionName := cygxService.GetCygxArticlePerssionNameListMap(articleIdArr)
+			for k, v := range list {
+				list[k].PermissionName = mapPerssionName[v.ArticleId]
 			}
 		}
+
 	} else if source == 2 {
 		if mobile != "" {
 			condition = ` AND s.mobile = '` + mobile + `' `
@@ -1919,7 +1955,7 @@ func (this *UserController) CompanyTableList() {
 		br.ErrMsg = "获取搜索记录失败,Err:" + err.Error()
 		return
 	}
-	tagNum, err := cygx.GetCygxTagHistoryCountByCompanyId(companyId,"")
+	tagNum, err := cygx.GetCygxTagHistoryCountByCompanyId(companyId, "")
 	if err != nil {
 		br.ErrMsg = "获取信息失败,Err:" + err.Error()
 		br.Msg = "获取搜索记录失败"
@@ -4163,7 +4199,7 @@ func (this *UserController) TableCompanyList() {
 		br.ErrMsg = "获取搜索记录失败,Err:" + err.Error()
 		return
 	}
-	tagNum, err := cygx.GetCygxTagHistoryCountByCompanyIds(companyCondition,"")
+	tagNum, err := cygx.GetCygxTagHistoryCountByCompanyIds(companyCondition, "")
 	if err != nil {
 		br.ErrMsg = "获取信息失败,Err:" + err.Error()
 		br.Msg = "获取搜索记录失败"
@@ -4319,4 +4355,3 @@ func (this *UserController) UserRemind() {
 	br.Success = true
 	br.Data = resp
 }
-

+ 12 - 3
controllers/data_manage/excel_info.go

@@ -1242,12 +1242,21 @@ func (this *ExcelInfoController) Calculate() {
 		br.ErrMsg = "计算失败:计算结果是:NAN;formulaStr:" + formulaFormStr
 		return
 	}
-	calVal := calResult.String()
-	if err != nil {
+	// 计算结果格式化
+	calFloat, e := calResult.Float64()
+	if e != nil {
 		br.Msg = "计算失败"
-		br.ErrMsg = "计算失败,结果转 string 失败:Err:" + err.Error() + ";formulaStr:" + formulaFormStr
+		br.ErrMsg = "计算失败, Err: " + e.Error()
 		return
 	}
+	calVal := utils.FormatTableDataShowValue(calFloat)
+
+	//calVal := calResult.String()
+	//if err != nil {
+	//	br.Msg = "计算失败"
+	//	br.ErrMsg = "计算失败,结果转 string 失败:Err:" + err.Error() + ";formulaStr:" + formulaFormStr
+	//	return
+	//}
 
 	br.Ret = 200
 	br.Success = true

+ 1195 - 0
controllers/eta_business/eta_business.go

@@ -0,0 +1,1195 @@
+package eta_business
+
+import (
+	"encoding/json"
+	"fmt"
+	"github.com/rdlucklib/rdluck_tools/paging"
+	"hongze/hz_crm_api/controllers"
+	"hongze/hz_crm_api/models"
+	"hongze/hz_crm_api/models/eta_business"
+	etaBusinessService "hongze/hz_crm_api/services/eta_business"
+	"hongze/hz_crm_api/utils"
+	"strconv"
+	"strings"
+	"time"
+)
+
+// EtaBusinessController ETA商家
+type EtaBusinessController struct {
+	controllers.BaseAuthController
+}
+
+// PageList
+// @Title 商家列表-分页
+// @Description 商家列表-分页
+// @Param   Keyword			query	string	false	"关键词: 商家名称/社会信用码/商家编码"
+// @Param   SellerIds		query	string	false	"销售IDs"
+// @Param   SigningStatus	query	string	false	"签约状态: 1-首次签约; 2-续约中; 3-已终止"
+// @Param   Province		query	string	false	"省份筛选"
+// @Param   City			query	string	false	"城市筛选"
+// @Param   IndustryId		query	int	false	"行业ID"
+// @Param   SortParam		query	int	false	"排序字段: 1-签约时间; 2-到期时间; 3-创建时间; 4-用户上限"
+// @Param   SortType		query	int	false	"排序类型: 1-正序; 2-倒序"
+// @Success 200 Ret=200 获取成功
+// @router /page_list [get]
+func (this *EtaBusinessController) PageList() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		if br.ErrMsg == "" {
+			br.IsSendEmail = false
+		}
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	sysUser := this.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+
+	// 分页
+	pageSize, _ := this.GetInt("PageSize")
+	currentIndex, _ := this.GetInt("CurrentIndex")
+	var startSize int
+	if pageSize <= 0 {
+		pageSize = utils.PageSize20
+	}
+	if currentIndex <= 0 {
+		currentIndex = 1
+	}
+	startSize = utils.StartIndex(currentIndex, pageSize)
+
+	// 权限校验
+	resp := new(eta_business.EtaBusinessListResp)
+	ok, e := etaBusinessService.CheckEtaBusinessOperateAuth(sysUser.RoleTypeCode)
+	if e != nil {
+		br.Msg = "操作失败"
+		br.ErrMsg = "操作权限校验失败, ErrMsg: " + e.Error()
+		return
+	}
+	if !ok {
+		resp.Paging = paging.GetPaging(currentIndex, pageSize, 0)
+		br.Data = resp
+		br.Ret = 200
+		br.Success = true
+		br.Msg = "获取成功"
+		return
+	}
+
+	cond := ``
+	pars := make([]interface{}, 0)
+	// 筛选项
+	{
+		// 关键词
+		keyword := this.GetString("Keyword", "")
+		keyword = strings.TrimSpace(keyword)
+		if keyword != "" {
+			kw := fmt.Sprint("%", keyword, "%")
+			cond += fmt.Sprintf(` AND (%s LIKE ? OR %s LIKE ? OR %s LIKE ?)`, eta_business.EtaBusinessColumns.BusinessName, eta_business.EtaBusinessColumns.BusinessCode, eta_business.EtaBusinessColumns.CreditCode)
+			pars = append(pars, kw, kw, kw)
+		}
+
+		// 销售
+		sellerIds := this.GetString("SellerIds", "")
+		if sellerIds != "" {
+			arr := strings.Split(sellerIds, ",")
+			ids := make([]int, 0)
+			for _, s := range arr {
+				v, e := strconv.Atoi(s)
+				if e != nil {
+					br.Msg = "销售ID有误"
+					return
+				}
+				ids = append(ids, v)
+			}
+			if len(ids) == 0 {
+				resp.Paging = paging.GetPaging(currentIndex, pageSize, 0)
+				br.Data = resp
+				br.Ret = 200
+				br.Success = true
+				br.Msg = "获取成功"
+				return
+			}
+			cond += fmt.Sprintf(` AND %s IN (%s)`, eta_business.EtaBusinessColumns.SellerId, utils.GetOrmInReplace(len(ids)))
+			pars = append(pars, ids)
+		}
+
+		// 签约状态
+		signingStatus, _ := this.GetInt("SigningStatus", 0)
+		if signingStatus > 0 {
+			cond += fmt.Sprintf(` AND %s = ?`, eta_business.EtaBusinessColumns.SigningStatus)
+			pars = append(pars, signingStatus)
+		}
+
+		// 商家地址
+		province := this.GetString("Province", "")
+		province = strings.TrimSpace(province)
+		if province != "" {
+			provinceArr := strings.Split(province, ",")
+			if len(provinceArr) == 0 {
+				resp.Paging = paging.GetPaging(currentIndex, pageSize, 0)
+				br.Data = resp
+				br.Ret = 200
+				br.Success = true
+				br.Msg = "获取成功"
+				return
+			}
+			cond += fmt.Sprintf(` AND %s IN (%s)`, eta_business.EtaBusinessColumns.Province, utils.GetOrmInReplace(len(provinceArr)))
+			pars = append(pars, provinceArr)
+		}
+		city := this.GetString("City", "")
+		city = strings.TrimSpace(city)
+		if city != "" {
+			cityArr := strings.Split(city, ",")
+			if len(cityArr) == 0 {
+				resp.Paging = paging.GetPaging(currentIndex, pageSize, 0)
+				br.Data = resp
+				br.Ret = 200
+				br.Success = true
+				br.Msg = "获取成功"
+				return
+			}
+			cond += fmt.Sprintf(` AND %s IN (%s)`, eta_business.EtaBusinessColumns.City, utils.GetOrmInReplace(len(cityArr)))
+			pars = append(pars, cityArr)
+		}
+
+		// 行业
+		industryId, _ := this.GetInt("IndustryId", 0)
+		if industryId > 0 {
+			cond += fmt.Sprintf(` AND %s = ?`, eta_business.EtaBusinessColumns.IndustryId)
+			pars = append(pars, industryId)
+		}
+	}
+
+	order := ``
+	// 排序
+	{
+		fieldArr := []int{1, 2, 3, 4}
+		typeArr := []int{1, 2}
+		fieldMap := map[int]string{
+			1: "signing_time",
+			2: "expired_time",
+			3: "create_time",
+			4: "user_max",
+		}
+		typeMap := map[int]string{
+			1: "ASC",
+			2: "DESC",
+		}
+
+		sortParam, _ := this.GetInt("SortParam", 0)
+		sortType, _ := this.GetInt("SortType", 0)
+		if utils.InArrayByInt(fieldArr, sortParam) && utils.InArrayByInt(typeArr, sortType) {
+			order = fmt.Sprintf("%s %s", fieldMap[sortParam], typeMap[sortType])
+		}
+		fmt.Println("order: ", order)
+	}
+
+	// 获取列表
+	businessOb := new(eta_business.EtaBusiness)
+	total, e := businessOb.GetCountByCondition(cond, pars)
+	if e != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取商家总数失败, Err: " + e.Error()
+		return
+	}
+	list, e := businessOb.GetPageItemsByCondition(cond, pars, []string{}, order, startSize, pageSize)
+	if e != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取商家列表失败, Err: " + e.Error()
+		return
+	}
+	items := make([]*eta_business.EtaBusinessItem, 0)
+	for _, v := range list {
+		b := new(eta_business.EtaBusinessItem)
+		b.EtaBusinessId = v.EtaBusinessId
+		b.BusinessName = v.BusinessName
+		b.BusinessCode = v.BusinessCode
+		b.CreditCode = v.CreditCode
+		b.RegionType = v.RegionType
+		b.Province = v.Province
+		b.City = v.City
+		b.Address = v.Address
+		b.SellerId = v.SellerId
+		b.SellerName = v.SellerName
+		b.Leader = v.Leader
+		b.IndustryId = v.IndustryId
+		b.IndustryName = v.IndustryName
+		b.CapitalScale = v.CapitalScale
+		b.ResearchTeamSize = v.ResearchTeamSize
+		b.UserMax = v.UserMax
+		b.SigningStatus = v.SigningStatus
+		b.Enable = v.Enable
+		b.ContractId = v.ContractId
+		b.SigningTime = v.SigningTime.Format(utils.FormatDate)
+		b.ExpiredTime = v.ExpiredTime.Format(utils.FormatDate)
+		b.CreateTime = v.CreateTime.Format(utils.FormatDateTime)
+		b.ModifyTime = v.ModifyTime.Format(utils.FormatDateTime)
+		items = append(items, b)
+	}
+
+	resp.List = items
+	resp.Paging = paging.GetPaging(currentIndex, pageSize, total)
+	br.Data = resp
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+}
+
+// Add
+// @Title 新增商家
+// @Description 新增商家
+// @Param	request	body eta_business.EtaBusinessAddReq true "type json string"
+// @Success 200 Ret=200 操作成功
+// @router /add [post]
+func (this *EtaBusinessController) Add() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		if br.ErrMsg == "" {
+			br.IsSendEmail = false
+		}
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	sysUser := this.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+
+	// 操作权限校验
+	ok, e := etaBusinessService.CheckEtaBusinessOperateAuth(sysUser.RoleTypeCode)
+	if e != nil {
+		br.Msg = "操作失败"
+		br.ErrMsg = "操作权限校验失败, ErrMsg: " + e.Error()
+		return
+	}
+	if !ok {
+		br.Msg = "无权操作"
+		return
+	}
+
+	// 参数校验
+	var req eta_business.EtaBusinessAddReq
+	if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + e.Error()
+		return
+	}
+	req.BusinessName = strings.TrimSpace(req.BusinessName)
+	if req.BusinessName == "" {
+		br.Msg = "商家名称不可为空"
+		return
+	}
+	if req.CreditCode == "" {
+		br.Msg = "社会统一信用码不可为空"
+		return
+	}
+	req.Province = strings.TrimSpace(req.Province)
+	if req.Province == "" {
+		br.Msg = "省份不可为空"
+		return
+	}
+	req.City = strings.TrimSpace(req.City)
+	if req.City == "" {
+		br.Msg = "城市不可为空"
+		return
+	}
+	req.Leader = strings.TrimSpace(req.Leader)
+	if req.Leader == "" {
+		br.Msg = "决策人不可为空"
+		return
+	}
+	if req.IndustryId <= 0 || req.IndustryName == "" {
+		br.Msg = "所属行业不可为空"
+		return
+	}
+	if req.ResearchTeamSize == "" {
+		br.Msg = "研究团队规模不可为空"
+		return
+	}
+	if req.UserMax <= 0 {
+		br.Msg = "用户上限不可小于0"
+		return
+	}
+	req.CapitalScale = strings.TrimSpace(req.CapitalScale)
+
+	// 如果仅校验不新增, 那么不做第二页签约时间的校验
+	var signTime, expiredTime time.Time
+	if !req.IsCheck {
+		if req.SigningTime == "" {
+			br.Msg = "签约时间不可为空"
+			return
+		}
+		if req.ExpiredTime == "" {
+			br.Msg = "到期时间不可为空"
+			return
+		}
+		signTime, e = time.ParseInLocation(utils.FormatDate, req.SigningTime, time.Local)
+		if e != nil {
+			br.Msg = "签约时间格式有误"
+			br.ErrMsg = "签约时间格式有误, Err: " + e.Error()
+			return
+		}
+		expiredTime, e = time.ParseInLocation(utils.FormatDate, req.ExpiredTime, time.Local)
+		if e != nil {
+			br.Msg = "到期时间格式有误"
+			br.ErrMsg = "到期时间格式有误, Err: " + e.Error()
+			return
+		}
+		if !expiredTime.After(signTime) {
+			br.Msg = "到期时间不得早于签约时间"
+			return
+		}
+	}
+
+	// 重名校验
+	{
+		item := new(eta_business.EtaBusiness)
+		cond := fmt.Sprintf(` AND %s = ?`, eta_business.EtaBusinessColumns.BusinessName)
+		pars := make([]interface{}, 0)
+		pars = append(pars, req.BusinessName)
+		exist, e := item.GetItemByCondition(cond, pars)
+		if e != nil && e.Error() != utils.ErrNoRow() {
+			br.Msg = "操作失败"
+			br.ErrMsg = "获取重名商家失败, Err: " + e.Error()
+			return
+		}
+		if exist != nil {
+			br.Msg = "商家名称已存在"
+			return
+		}
+	}
+
+	// 社会信用码重复校验
+	{
+		item := new(eta_business.EtaBusiness)
+		cond := fmt.Sprintf(` AND %s = ?`, eta_business.EtaBusinessColumns.CreditCode)
+		pars := make([]interface{}, 0)
+		pars = append(pars, req.CreditCode)
+		exist, e := item.GetItemByCondition(cond, pars)
+		if e != nil && e.Error() != utils.ErrNoRow() {
+			br.Msg = "操作失败"
+			br.ErrMsg = "获取重复信用码商家失败, Err: " + e.Error()
+			return
+		}
+		if exist != nil {
+			br.Msg = "商家社会信用码已存在"
+			return
+		}
+	}
+
+	// 如果只做校验不新增, 此处校验通过后直接返回true
+	if req.IsCheck {
+		br.Data = true
+		br.Ret = 200
+		br.Success = true
+		br.Msg = "校验通过"
+		return
+	}
+
+	// 商家编码
+	businessCode, e := eta_business.CreateEtaBusinessCode()
+	if e != nil {
+		br.Msg = "操作失败"
+		br.ErrMsg = "生成商家编码失败, Err: " + e.Error()
+		return
+	}
+
+	now := time.Now().Local()
+	// 若当前时间不在首次签约时间内, 也算作已终止, 进入合约期时会由定时任务改为首次签约
+	status := eta_business.EtaBusinessSigningStatusFirst
+	isTerminate := true
+	if now.Equal(signTime) || now.Equal(expiredTime) {
+		isTerminate = false
+	}
+	if now.After(signTime) && now.Before(expiredTime) {
+		isTerminate = false
+	}
+	if isTerminate {
+		status = eta_business.EtaBusinessSigningStatusTerminate
+	}
+
+	// 新增商家和签约
+	businessItem := new(eta_business.EtaBusiness)
+	businessItem.BusinessName = req.BusinessName
+	businessItem.BusinessCode = businessCode
+	businessItem.CreditCode = req.CreditCode
+	businessItem.RegionType = req.RegionType
+	businessItem.Province = req.Province
+	businessItem.City = req.City
+	businessItem.Address = req.Province + req.City
+	businessItem.SellerId = req.SellerId
+	businessItem.SellerName = req.SellerName
+	businessItem.Leader = req.Leader
+	businessItem.IndustryId = req.IndustryId
+	businessItem.IndustryName = req.IndustryName
+	businessItem.CapitalScale = req.CapitalScale
+	businessItem.ResearchTeamSize = req.ResearchTeamSize
+	businessItem.UserMax = req.UserMax
+	businessItem.Enable = 1
+	businessItem.SigningStatus = status
+	businessItem.SigningTime = signTime
+	businessItem.ExpiredTime = expiredTime
+	businessItem.CreateTime = now
+	businessItem.ModifyTime = now
+	contractItem := new(eta_business.EtaBusinessContract)
+	contractItem.SigningTime = signTime
+	contractItem.ExpiredTime = expiredTime
+	contractItem.IsFirst = 1
+	contractItem.CreateTime = now
+	contractItem.ModifyTime = now
+	if e = eta_business.CreateEtaBusinessAndContract(businessItem, contractItem); e != nil {
+		br.Msg = "操作失败"
+		br.ErrMsg = "新增商家和签约失败, Err: " + e.Error()
+		return
+	}
+
+	// 操作日志
+	go func() {
+		recordOb := new(eta_business.EtaBusinessOperationRecord)
+		recordOb.EtaBusinessId = businessItem.EtaBusinessId
+		recordOb.SellerId = businessItem.SellerId
+		recordOb.SysUserId = sysUser.AdminId
+		recordOb.SysRealName = sysUser.RealName
+		recordOb.OperationType = eta_business.EtaBusinessOperationTypeAdd
+		recordOb.OperationRemark = fmt.Sprintf("%s新增商户", sysUser.RealName)
+		recordOb.CreateTime = time.Now().Local()
+		_ = recordOb.Create()
+	}()
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "操作成功"
+}
+
+// Edit
+// @Title 编辑商家
+// @Description 编辑商家
+// @Param	request	body eta_business.EtaBusinessEditReq true "type json string"
+// @Success 200 Ret=200 操作成功
+// @router /edit [post]
+func (this *EtaBusinessController) Edit() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		if br.ErrMsg == "" {
+			br.IsSendEmail = false
+		}
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	sysUser := this.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+	var req eta_business.EtaBusinessEditReq
+	if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + e.Error()
+		return
+	}
+	if req.EtaBusinessId <= 0 {
+		br.Msg = "参数有误"
+		br.ErrMsg = "参数有误, 商家ID为空"
+		return
+	}
+	req.Province = strings.TrimSpace(req.Province)
+	if req.Province == "" {
+		br.Msg = "省份不可为空"
+		return
+	}
+	req.City = strings.TrimSpace(req.City)
+	if req.City == "" {
+		br.Msg = "城市不可为空"
+		return
+	}
+	req.Leader = strings.TrimSpace(req.Leader)
+	if req.Leader == "" {
+		br.Msg = "决策人不可为空"
+		return
+	}
+	if req.IndustryId <= 0 || req.IndustryName == "" {
+		br.Msg = "所属行业不可为空"
+		return
+	}
+	if req.ResearchTeamSize == "" {
+		br.Msg = "研究团队规模不可为空"
+		return
+	}
+	if req.UserMax <= 0 {
+		br.Msg = "用户上限不可小于0"
+		return
+	}
+	req.CapitalScale = strings.TrimSpace(req.CapitalScale)
+
+	// 权限校验
+	ok, e := etaBusinessService.CheckEtaBusinessOperateAuth(sysUser.RoleTypeCode)
+	if e != nil {
+		br.Msg = "操作失败"
+		br.ErrMsg = "操作权限校验失败, ErrMsg: " + e.Error()
+		return
+	}
+	if !ok {
+		br.Msg = "无权操作"
+		return
+	}
+
+	ob := new(eta_business.EtaBusiness)
+	item, e := ob.GetItemById(req.EtaBusinessId)
+	if e != nil {
+		if e.Error() == utils.ErrNoRow() {
+			br.Msg = "商家不存在, 请刷新页面"
+			return
+		}
+		br.Msg = "操作失败"
+		br.ErrMsg = "获取商家信息失败, Err: " + e.Error()
+		return
+	}
+	item.Province = req.Province
+	item.City = req.City
+	item.Address = req.Province + req.City
+	item.Leader = req.Leader
+	item.IndustryId = req.IndustryId
+	item.IndustryName = req.IndustryName
+	item.CapitalScale = req.CapitalScale
+	item.ResearchTeamSize = req.ResearchTeamSize
+	item.UserMax = req.UserMax
+	item.ModifyTime = time.Now().Local()
+	cols := []string{
+		"Province", "City", "Address", "Leader", "IndustryId", "IndustryName", "CapitalScale", "ResearchTeamSize", "UserMax", "ModifyTime",
+	}
+	if e := item.Update(cols); e != nil {
+		br.Msg = "操作失败"
+		br.ErrMsg = "编辑商家失败, Err: " + e.Error()
+		return
+	}
+
+	// 操作日志
+	go func() {
+		recordOb := new(eta_business.EtaBusinessOperationRecord)
+		recordOb.EtaBusinessId = item.EtaBusinessId
+		recordOb.SellerId = item.SellerId
+		recordOb.SysUserId = sysUser.AdminId
+		recordOb.SysRealName = sysUser.RealName
+		recordOb.OperationType = eta_business.EtaBusinessOperationTypeEdit
+		recordOb.OperationRemark = fmt.Sprintf("%s编辑商户", sysUser.RealName)
+		recordOb.CreateTime = time.Now().Local()
+		_ = recordOb.Create()
+	}()
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "操作成功"
+}
+
+// Signing
+// @Title 签约续约
+// @Description 签约续约(业务上仅用于续约, 兼容首次签约)
+// @Param	request	body eta_business.EtaBusinessSigningReq true "type json string"
+// @Success 200 Ret=200 操作成功
+// @router /signing [post]
+func (this *EtaBusinessController) Signing() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		if br.ErrMsg == "" {
+			br.IsSendEmail = false
+		}
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	sysUser := this.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+	var req eta_business.EtaBusinessSigningReq
+	if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + e.Error()
+		return
+	}
+	if req.EtaBusinessId <= 0 {
+		br.Msg = "参数有误"
+		br.ErrMsg = "参数有误, 商家ID为空"
+		return
+	}
+	if req.SigningTime == "" {
+		br.Msg = "签约时间不可为空"
+		return
+	}
+	if req.ExpiredTime == "" {
+		br.Msg = "到期时间不可为空"
+		return
+	}
+	signTime, e := time.ParseInLocation(utils.FormatDate, req.SigningTime, time.Local)
+	if e != nil {
+		br.Msg = "签约时间格式有误"
+		br.ErrMsg = "签约时间格式有误, Err: " + e.Error()
+		return
+	}
+	expiredTime, e := time.ParseInLocation(utils.FormatDate, req.ExpiredTime, time.Local)
+	if e != nil {
+		br.Msg = "到期时间格式有误"
+		br.ErrMsg = "到期时间格式有误, Err: " + e.Error()
+		return
+	}
+	if !expiredTime.After(signTime) {
+		br.Msg = "到期时间不得早于签约时间"
+		return
+	}
+
+	// 权限校验
+	ok, e := etaBusinessService.CheckEtaBusinessOperateAuth(sysUser.RoleTypeCode)
+	if e != nil {
+		br.Msg = "操作失败"
+		br.ErrMsg = "操作权限校验失败, ErrMsg: " + e.Error()
+		return
+	}
+	if !ok {
+		br.Msg = "无权操作"
+		return
+	}
+
+	// 获取商家信息
+	businessOb := new(eta_business.EtaBusiness)
+	business, e := businessOb.GetItemById(req.EtaBusinessId)
+	if e != nil {
+		if e.Error() == utils.ErrNoRow() {
+			br.Msg = "商家不存在, 请刷新页面"
+			return
+		}
+		br.Msg = "操作失败"
+		br.ErrMsg = "获取商家信息失败, Err: " + e.Error()
+		return
+	}
+
+	// 续约不可早于当前生效合约的到期时间
+	if business.ContractId > 0 {
+		{
+			ob := new(eta_business.EtaBusinessContract)
+			item, e := ob.GetItemById(business.ContractId)
+			if e != nil {
+				br.Msg = "操作失败"
+				br.ErrMsg = "获取商家当前合同失败, Err: " + e.Error()
+				return
+			}
+			if !signTime.After(item.ExpiredTime) {
+				br.Msg = "签约时间不可早于当前合同的到期时间"
+				return
+			}
+		}
+	}
+
+	// 获取历史签约, 签约日期不可交叠
+	contract := new(eta_business.EtaBusinessContract)
+	cond := fmt.Sprintf(` AND %s = ?`, eta_business.EtaBusinessContractColumns.EtaBusinessId)
+	pars := make([]interface{}, 0)
+	pars = append(pars, req.EtaBusinessId)
+	contracts, e := contract.GetItemsByCondition(cond, pars, []string{}, "")
+	if e != nil {
+		br.Msg = "操作失败"
+		br.ErrMsg = "获取商家签约列表失败, Err: " + e.Error()
+		return
+	}
+
+	// 校验签约时间是否重叠
+	isFirst := true // 是否为首次签约
+	if len(contracts) > 0 {
+		isFirst = false
+		for _, c := range contracts {
+			pass := false
+			if expiredTime.Before(c.SigningTime) {
+				pass = true
+			}
+			if signTime.After(c.ExpiredTime) {
+				pass = true
+			}
+			if !pass {
+				br.Msg = "签约时间在存续期内, 请检查"
+				return
+			}
+		}
+	}
+
+	// 新增签约
+	contract.EtaBusinessId = req.EtaBusinessId
+	contract.SigningTime = signTime
+	contract.ExpiredTime = expiredTime
+	contract.CreateTime = time.Now().Local()
+	contract.ModifyTime = time.Now().Local()
+	if isFirst {
+		contract.IsFirst = 1
+	}
+	if e = contract.Create(); e != nil {
+		br.Msg = "操作失败"
+		br.ErrMsg = "新增签约失败, Err: " + e.Error()
+		return
+	}
+
+	// 签约后续操作
+	go func() {
+		_ = etaBusinessService.UpdateEtaBusinessAfterSigning(business.EtaBusinessId)
+	}()
+
+	// 续约操作日志
+	if !isFirst {
+		go func() {
+			recordOb := new(eta_business.EtaBusinessOperationRecord)
+			recordOb.EtaBusinessId = business.EtaBusinessId
+			recordOb.SellerId = business.SellerId
+			recordOb.SysUserId = sysUser.AdminId
+			recordOb.SysRealName = sysUser.RealName
+			recordOb.OperationType = eta_business.EtaBusinessOperationTypeRenewalContract
+			recordOb.OperationRemark = fmt.Sprintf("%s添加续约", sysUser.RealName)
+			recordOb.CreateTime = time.Now().Local()
+			_ = recordOb.Create()
+		}()
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "操作成功"
+}
+
+// Enable
+// @Title 禁用启用
+// @Description 禁用启用
+// @Param	request	body eta_business.EtaBusinessEnableReq true "type json string"
+// @Success 200 Ret=200 操作成功
+// @router /enable [post]
+func (this *EtaBusinessController) Enable() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		if br.ErrMsg == "" {
+			br.IsSendEmail = false
+		}
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	sysUser := this.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+	var req eta_business.EtaBusinessEnableReq
+	if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + e.Error()
+		return
+	}
+	if req.EtaBusinessId <= 0 {
+		br.Msg = "参数有误"
+		br.ErrMsg = "参数有误, 商家ID为空"
+		return
+	}
+
+	// 权限校验
+	ok, e := etaBusinessService.CheckEtaBusinessOperateAuth(sysUser.RoleTypeCode)
+	if e != nil {
+		br.Msg = "操作失败"
+		br.ErrMsg = "操作权限校验失败, ErrMsg: " + e.Error()
+		return
+	}
+	if !ok {
+		br.Msg = "无权操作"
+		return
+	}
+
+	// 获取商家信息
+	businessOb := new(eta_business.EtaBusiness)
+	business, e := businessOb.GetItemById(req.EtaBusinessId)
+	if e != nil {
+		if e.Error() == utils.ErrNoRow() {
+			br.Msg = "商家不存在, 请刷新页面"
+			return
+		}
+		br.Msg = "操作失败"
+		br.ErrMsg = "获取商家信息失败, Err: " + e.Error()
+		return
+	}
+
+	// 禁启用
+	typeMap := map[int]int{
+		0: eta_business.EtaBusinessOperationTypeEnable,
+		1: eta_business.EtaBusinessOperationTypeDisable,
+	}
+	typeRemarkMap := map[int]string{
+		0: "启用",
+		1: "禁用",
+	}
+	operateType := typeMap[business.Enable]
+	operateRemark := typeRemarkMap[business.Enable]
+
+	business.Enable = business.Enable ^ 1
+	business.ModifyTime = time.Now().Local()
+	cols := []string{"Enable", "ModifyTime"}
+	if e = business.Update(cols); e != nil {
+		br.Msg = "操作失败"
+		br.ErrMsg = "更新商家状态失败, Err: " + e.Error()
+		return
+	}
+
+	// 操作日志
+	go func() {
+		recordOb := new(eta_business.EtaBusinessOperationRecord)
+		recordOb.EtaBusinessId = business.EtaBusinessId
+		recordOb.SellerId = business.SellerId
+		recordOb.SysUserId = sysUser.AdminId
+		recordOb.SysRealName = sysUser.RealName
+		recordOb.OperationType = operateType
+		recordOb.OperationRemark = fmt.Sprintf("%s%s商户", sysUser.RealName, operateRemark)
+		recordOb.CreateTime = time.Now().Local()
+		_ = recordOb.Create()
+	}()
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "操作成功"
+}
+
+// MoveSeller
+// @Title 移动销售
+// @Description 移动销售
+// @Param	request	body eta_business.EtaBusinessMoveSellerReq true "type json string"
+// @Success 200 Ret=200 操作成功
+// @router /move_seller [post]
+func (this *EtaBusinessController) MoveSeller() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		if br.ErrMsg == "" {
+			br.IsSendEmail = false
+		}
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	sysUser := this.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+	var req eta_business.EtaBusinessMoveSellerReq
+	if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + e.Error()
+		return
+	}
+	if req.EtaBusinessId <= 0 {
+		br.Msg = "参数有误"
+		br.ErrMsg = "参数有误, 商家ID为空"
+		return
+	}
+	if req.SellerId <= 0 || req.SellerName == "" {
+		br.Msg = "销售不可为空"
+		return
+	}
+
+	// 权限校验
+	ok, e := etaBusinessService.CheckEtaBusinessOperateAuth(sysUser.RoleTypeCode)
+	if e != nil {
+		br.Msg = "操作失败"
+		br.ErrMsg = "操作权限校验失败, ErrMsg: " + e.Error()
+		return
+	}
+	if !ok {
+		br.Msg = "无权操作"
+		return
+	}
+
+	// 获取商家信息
+	businessOb := new(eta_business.EtaBusiness)
+	business, e := businessOb.GetItemById(req.EtaBusinessId)
+	if e != nil {
+		if e.Error() == utils.ErrNoRow() {
+			br.Msg = "商家不存在, 请刷新页面"
+			return
+		}
+		br.Msg = "操作失败"
+		br.ErrMsg = "获取商家信息失败, Err: " + e.Error()
+		return
+	}
+
+	// 更新销售
+	business.SellerId = req.SellerId
+	business.SellerName = req.SellerName
+	business.ModifyTime = time.Now().Local()
+	cols := []string{"SellerId", "SellerName", "ModifyTime"}
+	if e = business.Update(cols); e != nil {
+		br.Msg = "操作失败"
+		br.ErrMsg = "移动至销售失败, Err: " + e.Error()
+		return
+	}
+
+	// 操作日志
+	go func() {
+		recordOb := new(eta_business.EtaBusinessOperationRecord)
+		recordOb.EtaBusinessId = business.EtaBusinessId
+		recordOb.SellerId = req.SellerId
+		recordOb.SysUserId = sysUser.AdminId
+		recordOb.SysRealName = sysUser.RealName
+		recordOb.OperationType = eta_business.EtaBusinessOperationTypeMoveSeller
+		recordOb.OperationRemark = fmt.Sprintf("%s移动到: %s", sysUser.RealName, req.SellerName)
+		recordOb.CreateTime = time.Now().Local()
+		_ = recordOb.Create()
+	}()
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "操作成功"
+}
+
+// Detail
+// @Title 商家详情
+// @Description 商家详情
+// @Param   EtaBusinessId	query	int		true	"商家ID"
+// @Success 200 Ret=200 获取成功
+// @router /detail [get]
+func (this *EtaBusinessController) Detail() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		if br.ErrMsg == "" {
+			br.IsSendEmail = false
+		}
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	sysUser := this.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+	// 权限校验
+	ok, e := etaBusinessService.CheckEtaBusinessOperateAuth(sysUser.RoleTypeCode)
+	if e != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "操作权限校验失败, ErrMsg: " + e.Error()
+		return
+	}
+	if !ok {
+		br.Ret = 200
+		br.Success = true
+		br.Msg = "获取成功"
+		return
+	}
+	businessId, _ := this.GetInt("EtaBusinessId", 0)
+	if businessId <= 0 {
+		br.Msg = "参数有误"
+		br.ErrMsg = "参数有误, 商家ID"
+		return
+	}
+
+	businessOb := new(eta_business.EtaBusiness)
+	item, e := businessOb.GetItemById(businessId)
+	if e != nil {
+		if e.Error() == utils.ErrNoRow() {
+			br.Msg = "商家不存在, 请刷新页面"
+			return
+		}
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取商家信息失败, Err: " + e.Error()
+		return
+	}
+
+	resp := new(eta_business.EtaBusinessItem)
+	resp.EtaBusinessId = item.EtaBusinessId
+	resp.BusinessName = item.BusinessName
+	resp.BusinessCode = item.BusinessCode
+	resp.CreditCode = item.CreditCode
+	resp.RegionType = item.RegionType
+	resp.Province = item.Province
+	resp.City = item.City
+	resp.Address = item.Address
+	resp.SellerId = item.SellerId
+	resp.SellerName = item.SellerName
+	resp.Leader = item.Leader
+	resp.IndustryId = item.IndustryId
+	resp.IndustryName = item.IndustryName
+	resp.CapitalScale = item.CapitalScale
+	resp.ResearchTeamSize = item.ResearchTeamSize
+	resp.UserMax = item.UserMax
+	resp.SigningStatus = item.SigningStatus
+	resp.Enable = item.Enable
+	resp.ContractId = item.ContractId
+	resp.SigningTime = item.SigningTime.Format(utils.FormatDate)
+	resp.ExpiredTime = item.ExpiredTime.Format(utils.FormatDate)
+	resp.CreateTime = item.CreateTime.Format(utils.FormatDateTime)
+	resp.ModifyTime = item.ModifyTime.Format(utils.FormatDateTime)
+
+	br.Data = resp
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+}
+
+// ContractList
+// @Title 商家签约列表
+// @Description 商家签约列表
+// @Param   EtaBusinessId	query	int		true	"商家ID"
+// @Success 200 Ret=200 获取成功
+// @router /contract_list [get]
+func (this *EtaBusinessController) ContractList() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		if br.ErrMsg == "" {
+			br.IsSendEmail = false
+		}
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	sysUser := this.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+	// 权限校验
+	resp := make([]*eta_business.EtaBusinessContractItem, 0)
+	ok, e := etaBusinessService.CheckEtaBusinessOperateAuth(sysUser.RoleTypeCode)
+	if e != nil {
+		br.Msg = "操作失败"
+		br.ErrMsg = "操作权限校验失败, ErrMsg: " + e.Error()
+		return
+	}
+	if !ok {
+		br.Data = resp
+		br.Ret = 200
+		br.Success = true
+		br.Msg = "获取成功"
+		return
+	}
+	businessId, _ := this.GetInt("EtaBusinessId", 0)
+	if businessId <= 0 {
+		br.Msg = "参数有误"
+		br.ErrMsg = "参数有误, 商家ID"
+		return
+	}
+
+	cond := fmt.Sprintf(` AND %s = ?`, eta_business.EtaBusinessContractColumns.EtaBusinessId)
+	pars := make([]interface{}, 0)
+	pars = append(pars, businessId)
+	order := `signing_time DESC`
+
+	contractOb := new(eta_business.EtaBusinessContract)
+	list, e := contractOb.GetItemsByCondition(cond, pars, []string{}, order)
+	if e != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取商家签约列表失败, Err: " + e.Error()
+		return
+	}
+	now := time.Now().Local()
+	for _, v := range list {
+		b := new(eta_business.EtaBusinessContractItem)
+		b.EtaBusinessContractId = v.EtaBusinessContractId
+		b.EtaBusinessId = v.EtaBusinessId
+		b.SigningTime = v.SigningTime.Format(utils.FormatDate)
+		b.ExpiredTime = v.ExpiredTime.Format(utils.FormatDate)
+		// 到期天数, 终止日按当天的23:59:59算
+		strEnd := v.ExpiredTime.Format(utils.FormatDate)
+		strEnd = strEnd + " 23:59:59"
+		endTime, e := time.ParseInLocation(utils.FormatDateTime, strEnd, time.Local)
+		if e != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = "签约日期有误, Err: " + e.Error()
+			return
+		}
+		b.ExpireDay = "-"
+		if now.After(v.SigningTime) && now.Before(endTime) {
+			diff := utils.GetDiffDays(v.ExpiredTime, now)
+			b.ExpireDay = strconv.Itoa(diff)
+			b.Using = true
+		}
+		resp = append(resp, b)
+	}
+
+	br.Data = resp
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+}
+
+// OperateRecordList
+// @Title 操作日志列表
+// @Description 操作日志列表
+// @Param   EtaBusinessId	query	int		true	"商家ID"
+// @Success 200 Ret=200 获取成功
+// @router /operate_record_list [get]
+func (this *EtaBusinessController) OperateRecordList() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		if br.ErrMsg == "" {
+			br.IsSendEmail = false
+		}
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	sysUser := this.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+	// 权限校验
+	resp := make([]*eta_business.EtaBusinessOperationRecordItem, 0)
+	ok, e := etaBusinessService.CheckEtaBusinessOperateAuth(sysUser.RoleTypeCode)
+	if e != nil {
+		br.Msg = "操作失败"
+		br.ErrMsg = "操作权限校验失败, ErrMsg: " + e.Error()
+		return
+	}
+	if !ok {
+		br.Data = resp
+		br.Ret = 200
+		br.Success = true
+		br.Msg = "获取成功"
+		return
+	}
+	businessId, _ := this.GetInt("EtaBusinessId", 0)
+	if businessId <= 0 {
+		br.Msg = "参数有误"
+		br.ErrMsg = "参数有误, 商家ID"
+		return
+	}
+
+	cond := fmt.Sprintf(` AND %s = ?`, eta_business.EtaBusinessOperationRecordColumns.EtaBusinessId)
+	pars := make([]interface{}, 0)
+	pars = append(pars, businessId)
+
+	recordOb := new(eta_business.EtaBusinessOperationRecord)
+	list, e := recordOb.GetItemsByCondition(cond, pars, []string{}, "")
+	if e != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取商家操作日志列表失败, Err: " + e.Error()
+		return
+	}
+	for _, v := range list {
+		r := new(eta_business.EtaBusinessOperationRecordItem)
+		r.EtaBusinessId = v.EtaBusinessId
+		r.SysUserId = v.SysUserId
+		r.SysRealName = v.SysRealName
+		r.OperationType = v.OperationType
+		r.OperationRemark = v.OperationRemark
+		r.CreateTime = v.CreateTime.Format(utils.FormatDateTime)
+		resp = append(resp, r)
+	}
+
+	br.Data = resp
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+}

+ 19 - 2
controllers/eta_trial.go

@@ -240,6 +240,7 @@ func (this *ETATrialController) Add() {
 	resp := new(eta_trial.ETATrialListResp)
 
 	//提交审批
+	approvalIds := make([]int, 0)
 	for _, v := range req.List {
 		if v.CompanyName == "" {
 			br.Msg = "请填写公司名称"
@@ -381,7 +382,7 @@ func (this *ETATrialController) Add() {
 		msgItem := new(company.CompanyApprovalMessage)
 		msgItem.CreateUserId = sysUser.AdminId
 		msgItem.ReceiveUserId = -1
-		msgItem.MessageStatus = 0
+		msgItem.MessageStatus = 1 // 已读, 不再亮红点, 但是消息要有
 		msgItem.Remark = seller.RealName + "申请试用账号"
 		msgItem.Content = seller.RealName + "申请试用账号"
 		msgItem.CompanyName = v.CompanyName
@@ -393,6 +394,17 @@ func (this *ETATrialController) Add() {
 		msgItem.SourceType = 9     //消息来源
 		msgItem.ApprovalStatus = 1 //审批状态,1:待审批,2:已审批,3:已驳回
 		err = company.AddCompanyApprovalMessage(msgItem)
+
+		approvalIds = append(approvalIds, int(approvalId))
+	}
+
+	// 2023-08-01默认审批通过, 不再进行人工审批, 也不发送待办消息
+	if len(approvalIds) > 0 {
+		go func() {
+			for _, v := range approvalIds {
+				_ = services.ApprovalApply(v)
+			}
+		}()
 	}
 
 	br.Ret = 200
@@ -484,7 +496,7 @@ func (this *ETATrialController) ApplyEnable() {
 	msgItem := new(company.CompanyApprovalMessage)
 	msgItem.CreateUserId = sysUser.AdminId
 	msgItem.ReceiveUserId = -1
-	msgItem.MessageStatus = 0
+	msgItem.MessageStatus = 1 // 已读, 不再亮红点, 但是消息要有
 	msgItem.Remark = seller.RealName + "申请账号启用"
 	msgItem.Content = seller.RealName + "申请账号启用"
 	msgItem.CompanyName = req.CompanyName
@@ -497,6 +509,11 @@ func (this *ETATrialController) ApplyEnable() {
 	msgItem.ApprovalStatus = 1 //审批状态,1:待审批,2:已审批,3:已驳回
 	err = company.AddCompanyApprovalMessage(msgItem)
 
+	// 2023-08-01默认审批通过, 不再进行人工审批
+	go func() {
+		_ = services.ApprovalApply(int(approvalId))
+	}()
+
 	br.Ret = 200
 	br.Success = true
 	br.Msg = "提交成功"

+ 27 - 3
models/cygx/cygx_user.go

@@ -332,7 +332,6 @@ type UserInteraction struct {
 	SubjectNames          string `orm:"column(subject_names);NOT NULL"`  // 标的
 }
 
-
 // 查研观向图表
 type CygxChartResp struct {
 	Title       string `description:"标题"`
@@ -354,8 +353,8 @@ type CygxChartResp struct {
 // 获取阅读记录数量
 func GetCygxArticleHistoryCount(mobile, email, condition string) (count int, err error) {
 	o := orm.NewOrm()
-	sqlCount := ` SELECT COUNT(1) AS count  FROM cygx_article_history_record_all as r  INNER JOIN cygx_article  as art  ON  art.article_id = r.article_id  WHERE   r.mobile  = ?  AND is_del = 0 ` + condition + `  OR ( email = ? AND email <> ''  AND is_del = 0  ` + condition + `) `
-	err = o.Raw(sqlCount, mobile, email).QueryRow(&count)
+	sqlCount := ` SELECT COUNT(1) AS count  FROM cygx_article_history_record_all as r  INNER JOIN cygx_article  as art  ON  art.article_id = r.article_id  WHERE   r.mobile  = '` + mobile + `'  AND is_del = 0 ` + condition
+	err = o.Raw(sqlCount).QueryRow(&count)
 	return
 }
 
@@ -404,6 +403,31 @@ func GetCygxArticleHistoryRecordByUser(mobile, email, condition string, startSiz
 	return
 }
 
+// 用户阅读记录列表 2023-08-02 优化拆分
+func GetCygxArticleHistoryRecordByUserNew(mobile, email, condition string, startSize, pageSize int) (items []*UserInteraction, err error) {
+	o := orm.NewOrm()
+	sql := ` SELECT
+			art.title,
+			art.article_id,
+			art.article_id_md5,
+			art.publish_date,
+			art.category_name,
+			r.create_time,
+			r.stop_time,
+			r.source as source_platform
+		FROM
+			cygx_article_history_record_all AS r
+			INNER JOIN cygx_article AS art ON art.article_id = r.article_id
+		WHERE
+			 r.mobile  = ?  AND is_del = 0 ` + condition + `  OR ( email = ? AND email <>''  AND is_del = 0 ` + condition + `  )
+			 ORDER BY  r.create_time DESC   `
+	if startSize > 0 || pageSize > 0 {
+		sql += ` LIMIT ` + strconv.Itoa(startSize) + "," + strconv.Itoa(pageSize)
+	}
+	_, err = o.Raw(sql, mobile, email).QueryRows(&items)
+	return
+}
+
 // 收藏列表数量
 func GetCygxArticleCollectCount(uid int) (count int, err error) {
 	o := orm.NewOrm()

+ 0 - 18
models/cygx/report_article.go

@@ -1270,24 +1270,6 @@ type CygxCelueArticleHistoryRecord struct {
 	RealName       string    `description:"用户姓名"`
 }
 
-func GetArticleHistoryRecordMobile(articleIds string) (mobiles string, err error) {
-	sql := `SELECT  GROUP_CONCAT( DISTINCT mobile SEPARATOR ',' ) as mobiles   FROM cygx_article_history_record_newpv WHERE article_id IN (` + articleIds + `) AND mobile!= ''`
-	o := orm.NewOrm()
-	err = o.Raw(sql).QueryRow(&mobiles)
-	return
-}
-
-func GetCygxCelueArticleHistoryRecordPv(articleIds, mobiles string) (item []*ArticleHistoryRep, err error) {
-	o := orm.NewOrm()
-	sql := `SELECT * FROM cygx_celue_article_history_record WHERE article_id IN ( ` + articleIds + ` ) AND  `
-	if mobiles != "" {
-		sql += `	AND mobile NOT IN ( ` + mobiles + `)`
-	}
-	sql += ` ORDER BY create_time DESC  `
-	_, err = o.Raw(sql).QueryRows(&item)
-	return
-}
-
 func GetCygxCelueArticleHistoryRecordPvAll(articleIds string) (item []*ArticleHistoryRep, err error) {
 	o := orm.NewOrm()
 	sql := `SELECT * FROM cygx_article_history_record_all as  h WHERE article_id IN ( ` + articleIds + ` )  AND   h.is_del = 0   AND h.platfor = 2 `

+ 38 - 0
models/cygx/report_mapping_celue.go

@@ -21,6 +21,22 @@ type CygxReportMappingCelue struct {
 	ModifyTime          time.Time `description:"更新时间"`
 }
 
+type CygxReportMappingCelueResp struct {
+	Id                  int       `orm:"column(id);pk" description:"id"`
+	ChartPermissionId   int       `description:"行业ID"`
+	CategoryId          int       `description:"分类ID"`
+	ChartPermissionName string    `description:"行业名称"`
+	SubCategoryName     string    `description:"主题"`
+	ReportType          int       `description:"报告类型,2产业报告,1行业报告"`
+	Sort                int       `description:"排序"`
+	IsCustom            int       `description:"是否属于自定义的匹配类型 ,1是,0否"`
+	IsSummary           int       `description:"是否是纪要库,1是,0否"`
+	IsReport            int       `description:"是否是报告,1是,0否"`
+	PermissionType      int       `description:"1主观,2客观"`
+	CreateTime          time.Time `description:"创建时间"`
+	ModifyTime          time.Time `description:"更新时间"`
+}
+
 // 获取category_id 最大的值,进行累加
 func GetCygxReportMappingCelueMaxDetail() (item *CygxReportMappingCelue, err error) {
 	o := orm.NewOrm()
@@ -28,3 +44,25 @@ func GetCygxReportMappingCelueMaxDetail() (item *CygxReportMappingCelue, err err
 	err = o.Raw(sql).QueryRow(&item)
 	return
 }
+
+// 列表
+func GetCygxReportMappingList(condition string, pars []interface{}) (items []*CygxReportMappingCelueResp, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT * FROM cygx_report_mapping   WHERE 1= 1 `
+	if condition != "" {
+		sql += condition
+	}
+	_, err = o.Raw(sql, pars).QueryRows(&items)
+	return
+}
+
+// 列表
+func GetCygxReportMappingCelueList(condition string, pars []interface{}) (items []*CygxReportMappingCelueResp, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT * FROM cygx_report_mapping_celue   WHERE 1= 1 `
+	if condition != "" {
+		sql += condition
+	}
+	_, err = o.Raw(sql, pars).QueryRows(&items)
+	return
+}

+ 13 - 0
models/db.go

@@ -15,6 +15,7 @@ import (
 	future_good2 "hongze/hz_crm_api/models/data_manage/future_good"
 	"hongze/hz_crm_api/models/data_manage/supply_analysis"
 	"hongze/hz_crm_api/models/day_new"
+	"hongze/hz_crm_api/models/eta_business"
 	"hongze/hz_crm_api/models/eta_trial"
 	"hongze/hz_crm_api/models/roadshow"
 	"hongze/hz_crm_api/models/seal"
@@ -183,6 +184,9 @@ func init() {
 	//AI 聊天记录
 	initAiChat()
 
+	// ETA商家
+	initEtaBusiness()
+
 	// ETA版本更新日志
 	initEtaVersionUpdateLog()
 }
@@ -635,6 +639,15 @@ func initAiChat() {
 	)
 }
 
+// initEtaBusiness ETA商家相关表
+func initEtaBusiness() {
+	orm.RegisterModel(
+		new(eta_business.EtaBusiness),                // ETA商家表
+		new(eta_business.EtaBusinessContract),        // ETA合同表
+		new(eta_business.EtaBusinessOperationRecord), // ETA操作记录表
+	)
+}
+
 // initEtaVersionUpdateLog ETA版本更新日志
 func initEtaVersionUpdateLog() {
 	orm.RegisterModel(

+ 324 - 0
models/eta_business/eta_business.go

@@ -0,0 +1,324 @@
+package eta_business
+
+import (
+	"fmt"
+	"github.com/beego/beego/v2/client/orm"
+	"github.com/rdlucklib/rdluck_tools/paging"
+	"hongze/hz_crm_api/utils"
+	"strings"
+	"time"
+)
+
+const (
+	EtaBusinessSigningStatusFirst = iota + 1
+	EtaBusinessSigningStatusContinue
+	EtaBusinessSigningStatusTerminate
+)
+
+type EtaBusiness struct {
+	EtaBusinessId    int       `orm:"column(eta_business_id);pk"`
+	BusinessName     string    `description:"商家名称"`
+	BusinessCode     string    `description:"商家编码"`
+	CreditCode       string    `description:"社会统一信用码"`
+	RegionType       string    `description:"所属区域:国内;海外"`
+	Province         string    `description:"省份"`
+	City             string    `description:"城市"`
+	Address          string    `description:"商家地址"`
+	SellerId         int       `description:"销售ID"`
+	SellerName       string    `description:"销售名称"`
+	Leader           string    `description:"决策人"`
+	IndustryId       int       `description:"行业ID"`
+	IndustryName     string    `description:"行业名称"`
+	CapitalScale     string    `description:"资金规模"`
+	ResearchTeamSize string    `description:"研究团队规模"`
+	UserMax          int       `description:"用户上限"`
+	SigningStatus    int       `description:"签约状态:1-首次签约;2-续约中;3-已终止"`
+	Enable           int       `description:"状态:0-禁用;1-启用"`
+	ContractId       int       `description:"当前合约ID"`
+	SigningTime      time.Time `description:"当前合约的签约时间"`
+	ExpiredTime      time.Time `description:"当前合约的到期时间"`
+	CreateTime       time.Time `description:"创建时间"`
+	ModifyTime       time.Time `description:"更新时间"`
+}
+
+func (m *EtaBusiness) TableName() string {
+	return "eta_business"
+}
+
+func (m *EtaBusiness) PrimaryId() string {
+	return EtaBusinessColumns.EtaBusinessId
+}
+
+var EtaBusinessColumns = struct {
+	EtaBusinessId    string
+	BusinessName     string
+	BusinessCode     string
+	CreditCode       string
+	RegionType       string
+	Province         string
+	City             string
+	Address          string
+	SellerId         string
+	SellerName       string
+	Leader           string
+	IndustryId       string
+	IndustryName     string
+	CapitalScale     string
+	ResearchTeamSize string
+	UserMax          string
+	SigningStatus    string
+	Enable           string
+	ContractId       string
+	SigningTime      string
+	ExpiredTime      string
+	CreateTime       string
+	ModifyTime       string
+}{
+	EtaBusinessId:    "eta_business_id",
+	BusinessName:     "business_name",
+	BusinessCode:     "business_code",
+	CreditCode:       "credit_code",
+	RegionType:       "region_type",
+	Province:         "province",
+	City:             "city",
+	Address:          "address",
+	SellerId:         "seller_id",
+	SellerName:       "seller_name",
+	Leader:           "leader",
+	IndustryId:       "industry_id",
+	IndustryName:     "industry_name",
+	CapitalScale:     "capital_scale",
+	ResearchTeamSize: "research_team_size",
+	UserMax:          "user_max",
+	SigningStatus:    "signing_status",
+	Enable:           "enable",
+	ContractId:       "contract_id",
+	SigningTime:      "signing_time",
+	ExpiredTime:      "expired_time",
+	CreateTime:       "create_time",
+	ModifyTime:       "modify_time",
+}
+
+func (m *EtaBusiness) Create() (err error) {
+	o := orm.NewOrm()
+	id, err := o.Insert(m)
+	if err != nil {
+		return
+	}
+	m.EtaBusinessId = int(id)
+	return
+}
+
+func (m *EtaBusiness) CreateMulti(items []*EtaBusiness) (err error) {
+	if len(items) == 0 {
+		return
+	}
+	o := orm.NewOrm()
+	_, err = o.InsertMulti(len(items), items)
+	return
+}
+
+func (m *EtaBusiness) Update(cols []string) (err error) {
+	o := orm.NewOrm()
+	_, err = o.Update(m, cols...)
+	return
+}
+
+func (m *EtaBusiness) Del() (err error) {
+	o := orm.NewOrm()
+	sql := fmt.Sprintf(`DELETE FROM %s WHERE %s = ? LIMIT 1`, m.TableName(), m.PrimaryId())
+	_, err = o.Raw(sql, m.EtaBusinessId).Exec()
+	return
+}
+
+func (m *EtaBusiness) GetItemById(id int) (item *EtaBusiness, err error) {
+	o := orm.NewOrm()
+	sql := fmt.Sprintf(`SELECT * FROM %s WHERE %s = ? LIMIT 1`, m.TableName(), m.PrimaryId())
+	err = o.Raw(sql, id).QueryRow(&item)
+	return
+}
+
+func (m *EtaBusiness) GetItemByCondition(condition string, pars []interface{}) (item *EtaBusiness, err error) {
+	o := orm.NewOrm()
+	sql := fmt.Sprintf(`SELECT * FROM %s WHERE 1=1 %s LIMIT 1`, m.TableName(), condition)
+	err = o.Raw(sql, pars).QueryRow(&item)
+	return
+}
+
+func (m *EtaBusiness) GetCountByCondition(condition string, pars []interface{}) (count int, err error) {
+	o := orm.NewOrm()
+	sql := fmt.Sprintf(`SELECT COUNT(1) FROM %s WHERE 1=1 %s`, m.TableName(), condition)
+	err = o.Raw(sql, pars).QueryRow(&count)
+	return
+}
+
+func (m *EtaBusiness) GetItemsByCondition(condition string, pars []interface{}, fieldArr []string, orderRule string) (items []*EtaBusiness, err error) {
+	o := orm.NewOrm()
+	fields := strings.Join(fieldArr, ",")
+	if len(fieldArr) == 0 {
+		fields = `*`
+	}
+	order := `ORDER BY create_time DESC`
+	if orderRule != "" {
+		order = ` ORDER BY ` + orderRule
+	}
+	sql := fmt.Sprintf(`SELECT %s FROM %s WHERE 1=1 %s %s`, fields, m.TableName(), condition, order)
+	_, err = o.Raw(sql, pars).QueryRows(&items)
+	return
+}
+
+func (m *EtaBusiness) GetPageItemsByCondition(condition string, pars []interface{}, fieldArr []string, orderRule string, startSize, pageSize int) (items []*EtaBusiness, err error) {
+	o := orm.NewOrm()
+	fields := strings.Join(fieldArr, ",")
+	if len(fieldArr) == 0 {
+		fields = `*`
+	}
+	order := `ORDER BY create_time DESC`
+	if orderRule != "" {
+		order = ` ORDER BY ` + orderRule
+	}
+	sql := fmt.Sprintf(`SELECT %s FROM %s WHERE 1=1 %s %s LIMIT ?,?`, fields, m.TableName(), condition, order)
+	_, err = o.Raw(sql, pars, startSize, pageSize).QueryRows(&items)
+	return
+}
+
+// CreateEtaBusinessAndContract 新增商家和签约
+func CreateEtaBusinessAndContract(businessItem *EtaBusiness, contractItem *EtaBusinessContract) (err error) {
+	if businessItem == nil || contractItem == nil {
+		err = fmt.Errorf("item empty")
+		return
+	}
+
+	o := orm.NewOrm()
+	tx, err := o.Begin()
+	if err != nil {
+		return
+	}
+	defer func() {
+		if err != nil {
+			_ = tx.Rollback()
+			return
+		}
+		_ = tx.Commit()
+	}()
+
+	// 商家
+	businessId, e := tx.Insert(businessItem)
+	if e != nil {
+		err = fmt.Errorf("business insert err: %s", e.Error())
+		return
+	}
+	businessItem.EtaBusinessId = int(businessId)
+
+	// 签约
+	contractItem.EtaBusinessId = businessItem.EtaBusinessId
+	contractId, e := tx.Insert(contractItem)
+	if e != nil {
+		err = fmt.Errorf("contract insert err: %s", e.Error())
+		return
+	}
+
+	// 更新商家当前签约ID
+	businessItem.ContractId = int(contractId)
+	cols := []string{"ContractId"}
+	_, err = tx.Update(businessItem, cols...)
+	return
+}
+
+// EtaBusinessAddReq 新增商家请求体
+type EtaBusinessAddReq struct {
+	BusinessName     string `description:"商家名称"`
+	CreditCode       string `description:"社会统一信用码"`
+	RegionType       string `description:"所属区域:国内;海外"`
+	Province         string `description:"省份"`
+	City             string `description:"城市"`
+	SellerId         int    `description:"销售ID"`
+	SellerName       string `description:"销售名称"`
+	Leader           string `description:"决策人"`
+	IndustryId       int    `description:"行业ID"`
+	IndustryName     string `description:"行业名称"`
+	CapitalScale     string `description:"资金规模"`
+	ResearchTeamSize string `description:"研究团队规模"`
+	UserMax          int    `description:"用户上限"`
+	SigningTime      string `description:"签约时间"`
+	ExpiredTime      string `description:"到期时间"`
+	IsCheck          bool   `description:"是否只做校验而不实际新增(业务操作上基础信息和签约时间分成两个步骤了)"`
+}
+
+// EtaBusinessEditReq 编辑商家请求体
+type EtaBusinessEditReq struct {
+	EtaBusinessId    int    `description:"商家ID"`
+	Province         string `description:"省份"`
+	City             string `description:"城市"`
+	Leader           string `description:"决策人"`
+	IndustryId       int    `description:"行业ID"`
+	IndustryName     string `description:"行业名称"`
+	CapitalScale     string `description:"资金规模"`
+	ResearchTeamSize string `description:"研究团队规模"`
+	UserMax          int    `description:"用户上限"`
+}
+
+// EtaBusinessSigningReq 商家签约请求体
+type EtaBusinessSigningReq struct {
+	EtaBusinessId int    `description:"商家ID"`
+	SigningTime   string `description:"当前合约的签约时间"`
+	ExpiredTime   string `description:"当前合约的到期时间"`
+}
+
+// EtaBusinessEnableReq 禁启用商家请求体
+type EtaBusinessEnableReq struct {
+	EtaBusinessId int `description:"商家ID"`
+}
+
+// EtaBusinessMoveSellerReq 移动商家销售请求体
+type EtaBusinessMoveSellerReq struct {
+	EtaBusinessId int    `description:"商家ID"`
+	SellerId      int    `description:"销售ID"`
+	SellerName    string `description:"销售名称"`
+}
+
+// CreateEtaBusinessCode 生成ETA商家编码
+func CreateEtaBusinessCode() (code string, err error) {
+	var num int
+	o := orm.NewOrm()
+	sql := `SELECT COUNT(1) AS num FROM eta_business WHERE create_time >= ? `
+	err = o.Raw(sql, time.Now().Format(utils.FormatDate)).QueryRow(&num)
+	if err != nil {
+		return
+	}
+	code = "E" + time.Now().Format("20060102") + fmt.Sprintf("%02d", num)
+	return
+}
+
+// EtaBusinessListResp 商家分页列表响应体
+type EtaBusinessListResp struct {
+	List   []*EtaBusinessItem `description:"商家列表数据"`
+	Paging *paging.PagingItem `description:"分页数据"`
+}
+
+// EtaBusinessItem ETA商家信息
+type EtaBusinessItem struct {
+	EtaBusinessId    int
+	BusinessName     string `description:"商家名称"`
+	BusinessCode     string `description:"商家编码"`
+	CreditCode       string `description:"社会统一信用码"`
+	RegionType       string `description:"所属区域:国内;海外"`
+	Province         string `description:"省份"`
+	City             string `description:"城市"`
+	Address          string `description:"商家地址"`
+	SellerId         int    `description:"销售ID"`
+	SellerName       string `description:"销售名称"`
+	Leader           string `description:"决策人"`
+	IndustryId       int    `description:"行业ID"`
+	IndustryName     string `description:"行业名称"`
+	CapitalScale     string `description:"资金规模"`
+	ResearchTeamSize string `description:"研究团队规模"`
+	UserMax          int    `description:"用户上限"`
+	SigningStatus    int    `description:"签约状态:1-首次签约;2-续约中;3-已终止"`
+	Enable           int    `description:"状态:0-禁用;1-启用"`
+	ContractId       int    `description:"当前合约ID"`
+	SigningTime      string `description:"当前合约的签约时间"`
+	ExpiredTime      string `description:"当前合约的到期时间"`
+	CreateTime       string `description:"创建时间"`
+	ModifyTime       string `description:"更新时间"`
+}

+ 123 - 0
models/eta_business/eta_business_contract.go

@@ -0,0 +1,123 @@
+package eta_business
+
+import (
+	"fmt"
+	"github.com/beego/beego/v2/client/orm"
+	"strings"
+	"time"
+)
+
+// EtaBusinessContract ETA商家合同表
+type EtaBusinessContract struct {
+	EtaBusinessContractId int       `orm:"column(eta_business_contract_id);pk"`
+	EtaBusinessId         int       `description:"ETA商家ID"`
+	SigningTime           time.Time `description:"签约时间"`
+	ExpiredTime           time.Time `description:"到期时间"`
+	IsFirst               int       `description:"是否为首份签约"`
+	CreateTime            time.Time `description:"创建时间"`
+	ModifyTime            time.Time `description:"更新时间"`
+}
+
+func (m *EtaBusinessContract) TableName() string {
+	return "eta_business_contract"
+}
+
+func (m *EtaBusinessContract) PrimaryId() string {
+	return EtaBusinessContractColumns.EtaBusinessContractId
+}
+
+var EtaBusinessContractColumns = struct {
+	EtaBusinessContractId string
+	EtaBusinessId         string
+	SigningTime           string
+	ExpiredTime           string
+	IsFirst               string
+	CreateTime            string
+	ModifyTime            string
+}{
+	EtaBusinessContractId: "eta_business_contract_id",
+	EtaBusinessId:         "eta_business_id",
+	SigningTime:           "signing_time",
+	ExpiredTime:           "expired_time",
+	IsFirst:               "is_first",
+	CreateTime:            "create_time",
+	ModifyTime:            "modify_time",
+}
+
+func (m *EtaBusinessContract) Create() (err error) {
+	o := orm.NewOrm()
+	id, err := o.Insert(m)
+	if err != nil {
+		return
+	}
+	m.EtaBusinessContractId = int(id)
+	return
+}
+
+func (m *EtaBusinessContract) CreateMulti(items []*EtaBusinessContract) (err error) {
+	if len(items) == 0 {
+		return
+	}
+	o := orm.NewOrm()
+	_, err = o.InsertMulti(len(items), items)
+	return
+}
+
+func (m *EtaBusinessContract) Update(cols []string) (err error) {
+	o := orm.NewOrm()
+	_, err = o.Update(m, cols...)
+	return
+}
+
+func (m *EtaBusinessContract) Del() (err error) {
+	o := orm.NewOrm()
+	sql := fmt.Sprintf(`DELETE FROM %s WHERE %s = ? LIMIT 1`, m.TableName(), m.PrimaryId())
+	_, err = o.Raw(sql, m.EtaBusinessContractId).Exec()
+	return
+}
+
+func (m *EtaBusinessContract) GetItemById(id int) (item *EtaBusinessContract, err error) {
+	o := orm.NewOrm()
+	sql := fmt.Sprintf(`SELECT * FROM %s WHERE %s = ? LIMIT 1`, m.TableName(), m.PrimaryId())
+	err = o.Raw(sql, id).QueryRow(&item)
+	return
+}
+
+func (m *EtaBusinessContract) GetItemByCondition(condition string, pars []interface{}) (err error) {
+	o := orm.NewOrm()
+	sql := fmt.Sprintf(`SELECT * FROM %s WHERE 1=1 %s LIMIT 1`, m.TableName(), condition)
+	err = o.Raw(sql, pars).QueryRow(&m)
+	return
+}
+
+func (m *EtaBusinessContract) GetCountByCondition(condition string, pars []interface{}) (count int, err error) {
+	o := orm.NewOrm()
+	sql := fmt.Sprintf(`SELECT COUNT(1) FROM %s WHERE 1=1 %s`, m.TableName(), condition)
+	err = o.Raw(sql, pars).QueryRow(&count)
+	return
+}
+
+func (m *EtaBusinessContract) GetItemsByCondition(condition string, pars []interface{}, fieldArr []string, orderRule string) (items []*EtaBusinessContract, err error) {
+	o := orm.NewOrm()
+	fields := strings.Join(fieldArr, ",")
+	if len(fieldArr) == 0 {
+		fields = `*`
+	}
+	order := `ORDER BY create_time DESC`
+	if orderRule != "" {
+		order = ` ORDER BY ` + orderRule
+	}
+	sql := fmt.Sprintf(`SELECT %s FROM %s WHERE 1=1 %s %s`, fields, m.TableName(), condition, order)
+	_, err = o.Raw(sql, pars).QueryRows(&items)
+	return
+}
+
+// EtaBusinessContractItem 商家签约信息
+type EtaBusinessContractItem struct {
+	EtaBusinessContractId int
+	EtaBusinessId         int    `description:"ETA商家ID"`
+	SigningTime           string `description:"签约时间"`
+	ExpiredTime           string `description:"到期时间"`
+	ExpireDay             string `description:"到期天数"`
+	Using                 bool   `description:"是否当前合约"`
+}

+ 136 - 0
models/eta_business/eta_business_operation_record.go

@@ -0,0 +1,136 @@
+package eta_business
+
+import (
+	"fmt"
+	"github.com/beego/beego/v2/client/orm"
+	"strings"
+	"time"
+)
+
+// 操作类型
+const (
+	EtaBusinessOperationTypeAdd = iota + 1
+	EtaBusinessOperationTypeEdit
+	EtaBusinessOperationTypeDisable
+	EtaBusinessOperationTypeEnable
+	EtaBusinessOperationTypeMoveSeller
+	EtaBusinessOperationTypeRenewalContract
+)
+
+// EtaBusinessOperationRecord ETA商家操作日志表
+type EtaBusinessOperationRecord struct {
+	Id              int       `orm:"column(id);pk"`
+	EtaBusinessId   int       `description:"ETA商家ID"`
+	SellerId        int       `description:"操作时所对应的销售ID"`
+	SysUserId       int       `description:"操作人ID"`
+	SysRealName     string    `description:"操作人姓名"`
+	OperationType   int       `description:"操作类型:1-新增;2-编辑;3-禁用;4-启用;5-移动销售;6-添加续约"`
+	OperationRemark string    `description:"操作内容"`
+	CreateTime      time.Time `description:"创建时间"`
+}
+
+func (m *EtaBusinessOperationRecord) TableName() string {
+	return "eta_business_operation_record"
+}
+
+func (m *EtaBusinessOperationRecord) PrimaryId() string {
+	return EtaBusinessOperationRecordColumns.Id
+}
+
+var EtaBusinessOperationRecordColumns = struct {
+	Id              string
+	EtaBusinessId   string
+	SellerId        string
+	SysUserId       string
+	SysRealName     string
+	OperationType   string
+	OperationRemark string
+	CreateTime      string
+}{
+	Id:              "id",
+	EtaBusinessId:   "eta_business_id",
+	SellerId:        "seller_id",
+	SysUserId:       "sys_user_id",
+	SysRealName:     "sys_real_name",
+	OperationType:   "operation_type",
+	OperationRemark: "operation_remark",
+	CreateTime:      "create_time",
+}
+
+func (m *EtaBusinessOperationRecord) Create() (err error) {
+	o := orm.NewOrm()
+	id, err := o.Insert(m)
+	if err != nil {
+		return
+	}
+	m.Id = int(id)
+	return
+}
+
+func (m *EtaBusinessOperationRecord) CreateMulti(items []*EtaBusinessOperationRecord) (err error) {
+	if len(items) == 0 {
+		return
+	}
+	o := orm.NewOrm()
+	_, err = o.InsertMulti(len(items), items)
+	return
+}
+
+func (m *EtaBusinessOperationRecord) Update(cols []string) (err error) {
+	o := orm.NewOrm()
+	_, err = o.Update(m, cols...)
+	return
+}
+
+func (m *EtaBusinessOperationRecord) Del() (err error) {
+	o := orm.NewOrm()
+	sql := fmt.Sprintf(`DELETE FROM %s WHERE %s = ? LIMIT 1`, m.TableName(), m.PrimaryId())
+	_, err = o.Raw(sql, m.Id).Exec()
+	return
+}
+
+func (m *EtaBusinessOperationRecord) GetItemById(id int) (item *EtaBusinessOperationRecord, err error) {
+	o := orm.NewOrm()
+	sql := fmt.Sprintf(`SELECT * FROM %s WHERE %s = ? LIMIT 1`, m.TableName(), m.PrimaryId())
+	err = o.Raw(sql, id).QueryRow(&item)
+	return
+}
+
+func (m *EtaBusinessOperationRecord) GetItemByCondition(condition string, pars []interface{}) (err error) {
+	o := orm.NewOrm()
+	sql := fmt.Sprintf(`SELECT * FROM %s WHERE 1=1 %s LIMIT 1`, m.TableName(), condition)
+	err = o.Raw(sql, pars).QueryRow(&m)
+	return
+}
+
+func (m *EtaBusinessOperationRecord) GetCountByCondition(condition string, pars []interface{}) (count int, err error) {
+	o := orm.NewOrm()
+	sql := fmt.Sprintf(`SELECT COUNT(1) FROM %s WHERE 1=1 %s`, m.TableName(), condition)
+	err = o.Raw(sql, pars).QueryRow(&count)
+	return
+}
+
+func (m *EtaBusinessOperationRecord) GetItemsByCondition(condition string, pars []interface{}, fieldArr []string, orderRule string) (items []*EtaBusinessOperationRecord, err error) {
+	o := orm.NewOrm()
+	fields := strings.Join(fieldArr, ",")
+	if len(fieldArr) == 0 {
+		fields = `*`
+	}
+	order := `ORDER BY create_time DESC`
+	if orderRule != "" {
+		order = ` ORDER BY ` + orderRule
+	}
+	sql := fmt.Sprintf(`SELECT %s FROM %s WHERE 1=1 %s %s`, fields, m.TableName(), condition, order)
+	_, err = o.Raw(sql, pars).QueryRows(&items)
+	return
+}
+
+// EtaBusinessOperationRecordItem ETA商家操作日志信息
+type EtaBusinessOperationRecordItem struct {
+	EtaBusinessId   int    `description:"ETA商家ID"`
+	SysUserId       int    `description:"操作人ID"`
+	SysRealName     string `description:"操作人姓名"`
+	OperationType   int    `description:"操作类型:1-新增;2-编辑;3-禁用;4-启用;5-移动销售;6-添加续约"`
+	OperationRemark string `description:"操作内容"`
+	CreateTime      string `description:"创建时间"`
+}

+ 90 - 0
routers/commentsRouter.go

@@ -1132,6 +1132,15 @@ func init() {
             Filters: nil,
             Params: nil})
 
+    beego.GlobalControllerRouter["hongze/hz_crm_api/controllers/cygx:ActivitySpecialTripCoAntroller"] = append(beego.GlobalControllerRouter["hongze/hz_crm_api/controllers/cygx:ActivitySpecialTripCoAntroller"],
+        beego.ControllerComments{
+            Method: "SendGroupList",
+            Router: `/special/trip/tempMsg/sendGroupList`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
     beego.GlobalControllerRouter["hongze/hz_crm_api/controllers/cygx:ActivitySpecialTripCoAntroller"] = append(beego.GlobalControllerRouter["hongze/hz_crm_api/controllers/cygx:ActivitySpecialTripCoAntroller"],
         beego.ControllerComments{
             Method: "TripList",
@@ -6460,6 +6469,87 @@ func init() {
             Filters: nil,
             Params: nil})
 
+    beego.GlobalControllerRouter["hongze/hz_crm_api/controllers/eta_business:EtaBusinessController"] = append(beego.GlobalControllerRouter["hongze/hz_crm_api/controllers/eta_business:EtaBusinessController"],
+        beego.ControllerComments{
+            Method: "Add",
+            Router: `/add`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["hongze/hz_crm_api/controllers/eta_business:EtaBusinessController"] = append(beego.GlobalControllerRouter["hongze/hz_crm_api/controllers/eta_business:EtaBusinessController"],
+        beego.ControllerComments{
+            Method: "ContractList",
+            Router: `/contract_list`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["hongze/hz_crm_api/controllers/eta_business:EtaBusinessController"] = append(beego.GlobalControllerRouter["hongze/hz_crm_api/controllers/eta_business:EtaBusinessController"],
+        beego.ControllerComments{
+            Method: "Detail",
+            Router: `/detail`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["hongze/hz_crm_api/controllers/eta_business:EtaBusinessController"] = append(beego.GlobalControllerRouter["hongze/hz_crm_api/controllers/eta_business:EtaBusinessController"],
+        beego.ControllerComments{
+            Method: "Edit",
+            Router: `/edit`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["hongze/hz_crm_api/controllers/eta_business:EtaBusinessController"] = append(beego.GlobalControllerRouter["hongze/hz_crm_api/controllers/eta_business:EtaBusinessController"],
+        beego.ControllerComments{
+            Method: "Enable",
+            Router: `/enable`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["hongze/hz_crm_api/controllers/eta_business:EtaBusinessController"] = append(beego.GlobalControllerRouter["hongze/hz_crm_api/controllers/eta_business:EtaBusinessController"],
+        beego.ControllerComments{
+            Method: "MoveSeller",
+            Router: `/move_seller`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["hongze/hz_crm_api/controllers/eta_business:EtaBusinessController"] = append(beego.GlobalControllerRouter["hongze/hz_crm_api/controllers/eta_business:EtaBusinessController"],
+        beego.ControllerComments{
+            Method: "OperateRecordList",
+            Router: `/operate_record_list`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["hongze/hz_crm_api/controllers/eta_business:EtaBusinessController"] = append(beego.GlobalControllerRouter["hongze/hz_crm_api/controllers/eta_business:EtaBusinessController"],
+        beego.ControllerComments{
+            Method: "PageList",
+            Router: `/page_list`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["hongze/hz_crm_api/controllers/eta_business:EtaBusinessController"] = append(beego.GlobalControllerRouter["hongze/hz_crm_api/controllers/eta_business:EtaBusinessController"],
+        beego.ControllerComments{
+            Method: "Signing",
+            Router: `/signing`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
     beego.GlobalControllerRouter["hongze/hz_crm_api/controllers/roadshow:CalendarController"] = append(beego.GlobalControllerRouter["hongze/hz_crm_api/controllers/roadshow:CalendarController"],
         beego.ControllerComments{
             Method: "Accept",

+ 6 - 0
routers/router.go

@@ -21,6 +21,7 @@ import (
 	"hongze/hz_crm_api/controllers/data_manage/line_feature"
 	"hongze/hz_crm_api/controllers/data_manage/supply_analysis"
 	"hongze/hz_crm_api/controllers/english_report"
+	"hongze/hz_crm_api/controllers/eta_business"
 	"hongze/hz_crm_api/controllers/roadshow"
 	"hongze/hz_crm_api/controllers/seal"
 	"hongze/hz_crm_api/controllers/yb"
@@ -299,6 +300,11 @@ func init() {
 				&english_report.EnPermissionController{},
 			),
 		),
+		web.NSNamespace("/eta_business",
+			web.NSInclude(
+				&eta_business.EtaBusinessController{},
+			),
+		),
 		web.NSNamespace("/eta_version_update_log",
 			web.NSInclude(
 				&controllers.EtaVersionUpdateLogController{},

+ 46 - 0
services/cygx/report_mapping.go

@@ -1,9 +1,11 @@
 package cygx
 
 import (
+	"errors"
 	"fmt"
 	"hongze/hz_crm_api/models/cygx"
 	"hongze/hz_crm_api/services/alarm_msg"
+	"hongze/hz_crm_api/utils"
 )
 
 // 报告匹配类型映射
@@ -27,3 +29,47 @@ func GetCygxReportMappingCygxListMap() (mapResp map[int]string) {
 	}
 	return
 }
+
+// 根据文章ID获取文章行业分类
+func GetCygxArticlePerssionNameListMap(articleIdArr []int) (mapResp map[int]string) {
+	lenArr := len(articleIdArr)
+	if lenArr == 0 {
+		return
+	}
+	var err error
+	defer func() {
+		if err != nil {
+			fmt.Println(err)
+			go alarm_msg.SendAlarmMsg("根据文章ID获取文章行业分类,信息失败,GetCygxArticlePerssionNameListMap Err:"+err.Error(), 3)
+		}
+	}()
+	var condition string
+	var pars []interface{}
+	//获取分类名称
+	perssionNameList, e := cygx.GetCygxReportMappingList(condition, pars)
+	if e != nil {
+		err = errors.New("GetCygxReportMappingCelueList, Err: " + e.Error())
+		return
+	}
+	mapName := make(map[int]string)
+	for _, v := range perssionNameList {
+		mapName[v.CategoryId] = v.ChartPermissionName
+	}
+	pars = make([]interface{}, 0)
+	condition = ` AND  article_id IN (` + utils.GetOrmInReplace(lenArr) + `)`
+	pars = append(pars, articleIdArr)
+	listArticle, e := cygx.GetArticlList(condition, pars, 0, 999)
+	if e != nil && e.Error() != utils.ErrNoRow() {
+		err = errors.New("GetArticlList, Err: " + e.Error())
+		return
+	}
+	mapResp = make(map[int]string, 0)
+	for _, v := range listArticle {
+		if v.CategoryId == 0 {
+			mapResp[v.ArticleId] = utils.CHART_PERMISSION_NAME_MF_YANXUAN
+		} else {
+			mapResp[v.ArticleId] = mapName[v.CategoryId]
+		}
+	}
+	return
+}

+ 0 - 24
services/cygx/special_wx_msg.go

@@ -157,30 +157,6 @@ func DetermineTripCancel(activityId int) (err error) {
 	if len(openIdList) == 0 {
 		return
 	}
-	//sendMap := make(map[string]interface{})
-	//sendData := make(map[string]interface{})
-	//var first string
-	//var keyword1 string
-	//var keyword2 string
-	//first = "【" + activityInfo.ResearchTheme + "】专项调研因专家安排变动,本次调研活动延期举办,具体时间另行通知"
-	//keyword1 = activityInfo.ResearchTheme
-	//keyword2 = "已取消"
-	//
-	//redirectUrl := ""
-	//sendData["first"] = map[string]interface{}{"value": first, "color": "#173177"}
-	//sendData["keyword1"] = map[string]interface{}{"value": keyword1, "color": "#173177"}
-	//sendData["keyword2"] = map[string]interface{}{"value": keyword2, "color": "#173177"}
-	//sendUrl := "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + accessToken
-	//if utils.RunMode == "release" {
-	//	sendMap["template_id"] = utils.WxMsgTemplateIdActivityChangeApplyXzs
-	//} else {
-	//	sendMap["template_id"] = utils.WxMsgTemplateIdActivityChangeApply
-	//}
-	//sendMap["url"] = redirectUrl
-	//sendMap["data"] = sendData
-	//sendMap["miniprogram"] = map[string]interface{}{"appid": utils.WxCygxAppId, "pagepath": "activityPages/specialDetail/specialDetail?id=" + strconv.Itoa(activityId)}
-	//services.PublicsendTemplateMsg(sendUrl, sendMap, openIdList, strconv.Itoa(activityId), utils.TEMPLATE_MSG_CYGX_ACTIVITY_UPDATE)
-
 	openIdArr := make([]string, len(openIdList))
 	for i, v := range openIdList {
 		openIdArr[i] = v.OpenId

+ 23 - 1
services/data/excel_info.go

@@ -752,6 +752,28 @@ func GetDataByTableDataConfig(tableDataConfig TableDataConfig) (resultResp reque
 		data = append(data, tmpEdbInfoData)
 	}
 
+	// 处理一下数据格式
+	for _, d := range data {
+		for k2, d2 := range d.Data {
+			// 可能有ShowValue非数值, 转换一下报错则continue
+			vf, e := strconv.ParseFloat(d2.ShowValue, 64)
+			if e != nil {
+				continue
+			}
+			d.Data[k2].ShowValue = utils.FormatTableDataShowValue(vf)
+		}
+	}
+	for _, d := range textRowListDataResp {
+		for k2, d2 := range d {
+			// 可能有ShowValue非数值, 转换一下报错则continue
+			vf, e := strconv.ParseFloat(d2.ShowValue, 64)
+			if e != nil {
+				continue
+			}
+			d[k2].ShowValue = utils.FormatTableDataShowValue(vf)
+		}
+	}
+
 	resultResp = request.TableDataReq{
 		EdbInfoIdList: edbInfoIdList,
 		Sort:          tableDataConfig.Sort,
@@ -1259,7 +1281,7 @@ func GetMixedTableCellData(config [][]request.MixedTableCellDataReq) (newMixedTa
 			} else if cell.DataType == 4 {
 				if dateValMap, ok := edbDataListMap[cell.EdbInfoId]; ok {
 					if val, ok2 := dateValMap[cell.DataTime]; ok2 {
-						cell.ShowValue = fmt.Sprint(val)
+						cell.ShowValue = utils.FormatTableDataShowValue(val)
 					}
 				}
 			}

+ 106 - 0
services/eta_business/eta_business.go

@@ -0,0 +1,106 @@
+package eta_business
+
+import (
+	"fmt"
+	"hongze/hz_crm_api/models/company"
+	"hongze/hz_crm_api/models/eta_business"
+	"hongze/hz_crm_api/services/alarm_msg"
+	"hongze/hz_crm_api/utils"
+	"strings"
+	"time"
+)
+
+// CheckEtaBusinessOperateAuth 校验ETA商家操作权限
+func CheckEtaBusinessOperateAuth(roleCode string) (ok bool, err error) {
+	confKey := "eta_business_auth_role"
+	conf, e := company.GetConfigDetailByCode(confKey)
+	if e != nil {
+		err = fmt.Errorf("获取权限配置失败, Err: %s", e.Error())
+		return
+	}
+	if conf.ConfigValue == "" {
+		err = fmt.Errorf("权限配置信息有误")
+		return
+	}
+	authArr := strings.Split(conf.ConfigValue, ",")
+	if utils.InArrayByStr(authArr, roleCode) {
+		ok = true
+	}
+	return
+}
+
+// UpdateEtaBusinessAfterSigning 签约后的后置操作
+func UpdateEtaBusinessAfterSigning(businessId int) (err error) {
+	if businessId <= 0 {
+		return
+	}
+	defer func() {
+		if err != nil {
+			tips := "签约后更新商家信息失败, Err: " + err.Error()
+			utils.FileLog.Info("%s", tips)
+			go alarm_msg.SendAlarmMsg(tips, 3)
+		}
+	}()
+
+	businessOb := new(eta_business.EtaBusiness)
+	business, e := businessOb.GetItemById(businessId)
+	if e != nil {
+		err = fmt.Errorf("获取商家信息失败, Err: %s", e.Error())
+		return
+	}
+
+	contracts := make([]*eta_business.EtaBusinessContract, 0)
+	{
+		ob := new(eta_business.EtaBusinessContract)
+		cond := fmt.Sprintf(` AND %s = ?`, eta_business.EtaBusinessContractColumns.EtaBusinessId)
+		pars := make([]interface{}, 0)
+		pars = append(pars, businessId)
+		list, e := ob.GetItemsByCondition(cond, pars, []string{}, "")
+		if e != nil {
+			err = fmt.Errorf("获取商家合同列表失败, Err: " + e.Error())
+			return
+		}
+		contracts = list
+	}
+	if len(contracts) == 0 {
+		return
+	}
+
+	strToday := time.Now().Format(utils.FormatDate)
+	today, _ := time.ParseInLocation(utils.FormatDate, strToday, time.Local)
+	using := false // 是否在任一存续期内
+	for _, c := range contracts {
+		// 当前合约
+		if today.Equal(c.SigningTime) || today.Equal(c.ExpiredTime) || (today.After(c.SigningTime) && today.Before(c.ExpiredTime)) {
+			business.ContractId = c.EtaBusinessContractId
+			business.SigningTime = c.SigningTime
+			business.ExpiredTime = c.ExpiredTime
+			business.ModifyTime = time.Now().Local()
+			// 是否为首次签约
+			if c.IsFirst == 1 {
+				business.SigningStatus = eta_business.EtaBusinessSigningStatusFirst
+			} else {
+				business.SigningStatus = eta_business.EtaBusinessSigningStatusContinue
+			}
+			using = true
+			break
+		}
+	}
+	// 不存在任一合同期内, 当前合同不变, 更新状态
+	if !using {
+		business.SigningStatus = eta_business.EtaBusinessSigningStatusTerminate
+		business.ModifyTime = time.Now().Local()
+		cols := []string{"SigningStatus", "ModifyTime"}
+		if e = business.Update(cols); e != nil {
+			err = fmt.Errorf("更新商家信息失败, Err: %s", e.Error())
+			return
+		}
+		return
+	}
+	// 合同期内
+	cols := []string{"ContractId", "SigningStatus", "SigningTime", "ExpiredTime", "ModifyTime"}
+	if e = business.Update(cols); e != nil {
+		err = fmt.Errorf("更新商家信息失败, Err: %s", e.Error())
+	}
+	return
+}

+ 148 - 0
services/eta_trial.go

@@ -2,8 +2,13 @@ package services
 
 import (
 	"fmt"
+	"github.com/mozillazg/go-pinyin"
+	"hongze/hz_crm_api/models/company"
 	"hongze/hz_crm_api/models/eta_trial"
 	"hongze/hz_crm_api/services/alarm_msg"
+	"hongze/hz_crm_api/utils"
+	"strconv"
+	"time"
 )
 
 // UpdateOldTrialUsersManualAuth 更新原试用客户手工录入权限(一次性)
@@ -73,3 +78,146 @@ func CreateTrialUserManualAuth(adminId int, adminRealName string) (err error) {
 	}
 	return
 }
+
+// ApprovalApply 同意审批
+func ApprovalApply(approvalId int) (err error) {
+	defer func() {
+		if err != nil {
+			tips := fmt.Sprintf("ETA试用-自动审批失败, ApprovalId: %d, Err: %s", approvalId, err.Error())
+			utils.FileLog.Info("%s", tips)
+			go alarm_msg.SendAlarmMsg(tips, 3)
+		}
+	}()
+
+	// 获取审批
+	approval, e := eta_trial.GetETATrialApprovalById(approvalId)
+	if e != nil {
+		err = fmt.Errorf("获取审批失败, Err: %s", e.Error())
+		return
+	}
+
+	// 更新审批
+	if e = eta_trial.ApprovalTrial(approvalId); e != nil {
+		err = fmt.Errorf("更新审批失败, Err: %s", e.Error())
+		return
+	}
+
+	// 如果是新客户申请就新增,旧客户更改账号状态即可
+	if approval.ApplyMethod == 2 {
+		if e = eta_trial.UpdateETATrialEnable(approval.Mobile); e != nil {
+			err = fmt.Errorf("启用失败, Err: %s", e.Error())
+			return
+		}
+		if e = eta_trial.UpdateAdminEnable(approval.Mobile); e != nil {
+			err = fmt.Errorf("启用用户失败, Err: %s", e.Error())
+			return
+		}
+	} else {
+		//新增客户
+		newItem := eta_trial.EtaTrial{
+			UserName:    approval.UserName,
+			CompanyName: approval.CompanyName,
+			Position:    approval.Position,
+			Mobile:      approval.Mobile,
+			Enabled:     1,
+			SellerId:    approval.SellerId,
+			Seller:      approval.Seller,
+			CreateTime:  time.Now(),
+			ModifyTime:  time.Now(),
+		}
+
+		strResult := ""
+		a := pinyin.NewArgs()
+		rows := pinyin.Pinyin(newItem.UserName, a)
+		for i := 0; i < len(rows); i++ {
+			strResult += rows[i][0]
+		}
+
+		//若非中文
+		if strResult == "" {
+			strResult = newItem.UserName
+		}
+		list, e := eta_trial.GetETATrialByAccount(strResult)
+		if e != nil && e.Error() != utils.ErrNoRow() {
+			err = fmt.Errorf("获取ETA试用账号失败, Err: %s", e.Error())
+			return
+		}
+		if list != nil && len(list) > 0 {
+			newItem.Account = strResult + strconv.Itoa(len(list))
+		} else {
+			newItem.Account = strResult
+		}
+
+		// 初始密码固定
+		newItem.Password = "123456a"
+
+		_, e = eta_trial.AddETATrial(&newItem)
+		if e != nil {
+			err = fmt.Errorf("新增ETA试用账号失败, Err: %s", e.Error())
+			return
+		}
+
+		// 新增至试用平台的Admin
+		adminItem, e := eta_trial.GetSysUserByRoleAndDepartment("试用", "ETA试用客户")
+		if e != nil {
+			err = fmt.Errorf("获取ETA试用admin失败, Err: %s", e.Error())
+			return
+		}
+
+		admin := new(eta_trial.ETATrialAdmin)
+		admin.AdminName = newItem.Account
+		admin.RealName = newItem.UserName
+		admin.Password = utils.MD5(newItem.Password)
+		admin.LastUpdatedPasswordTime = time.Now().Format(utils.FormatDateTime)
+		admin.Enabled = 1
+		admin.LastLoginTime = time.Now().Format(utils.FormatDateTime)
+		admin.CreatedTime = time.Now()
+		admin.LastUpdatedTime = time.Now().Format(utils.FormatDateTime)
+		admin.Mobile = newItem.Mobile
+		admin.RoleType = 0
+		admin.RoleId = adminItem.RoleId
+		admin.RoleName = "试用"
+		admin.RoleTypeCode = "管理员"
+		admin.DepartmentId = adminItem.DepartmentId
+		admin.DepartmentName = "ETA试用客户"
+		admin.Role = "admin"
+		admin.Position = approval.Position
+
+		newId, e := eta_trial.AddAdmin(admin)
+		if e != nil {
+			err = fmt.Errorf("新增ETA试用admin失败, Err: %s", e.Error())
+			return
+		}
+
+		// 新增试用客户手工权限
+		go func() {
+			_ = CreateTrialUserManualAuth(newId, admin.RealName)
+		}()
+	}
+
+	// 推送消息给销售
+	msgItem := new(company.CompanyApprovalMessage)
+	msgItem.CreateUserId = 0 // 系统自动创建的消息
+	msgItem.ReceiveUserId = approval.SellerId
+	msgItem.MessageStatus = 0
+	msgItem.Remark = approval.UserName + approval.ApprovalContent + "通过"
+	msgItem.Content = approval.UserName + approval.ApprovalContent + "通过"
+	msgItem.CompanyName = approval.CompanyName
+	msgItem.CreateTime = time.Now()
+	msgItem.ModifyTime = time.Now()
+	msgItem.CompanyApprovalId = approvalId
+	msgItem.OperationStatus = 1
+	msgItem.MessageType = 2    //1:申请消息,2:审批结果,3:文字消息
+	msgItem.SourceType = 9     //消息来源
+	msgItem.ApprovalStatus = 2 //审批状态,1:待审批,2:已审批,3:已驳回
+	err = company.AddCompanyApprovalMessage(msgItem)
+
+	// 更新审批消息(发给所有管理员的)为已读
+	//go func() {
+	//	cond := ` AND company_approval_id = ? AND source_type = ? AND message_status = ? AND receive_user_id = -1 `
+	//	pars := make([]interface{}, 0)
+	//	pars = append(pars, approvalId, 9, 0)
+	//	_ = company.ModifyCompanyApprovalMessageStatusByCond(cond, pars)
+	//}()
+	return
+}

+ 73 - 0
utils/common.go

@@ -2014,3 +2014,76 @@ func GetPredictEdbDayListByNum(startDate time.Time, num int, frequency string) (
 	}
 	return
 }
+
+// GetDiffDays 计算两个日期相差的天数
+func GetDiffDays(t1, t2 time.Time) int {
+	t1 = time.Date(t1.Year(), t1.Month(), t1.Day(), 0, 0, 0, 0, time.Local)
+	t2 = time.Date(t2.Year(), t2.Month(), t2.Day(), 0, 0, 0, 0, time.Local)
+	return int(t1.Sub(t2).Hours() / 24)
+}
+
+// FormatTableDataShowValue 格式化自定表格显示数据
+func FormatTableDataShowValue(x float64) (res string) {
+	if x > 1 || x < -1 {
+		res = decimal.NewFromFloat(x).Round(2).String()
+		return
+	}
+	// 介于-1到1之间
+	xStr := strconv.FormatFloat(x, 'f', -10, 64)
+
+	// 使用 strings.Split 函数将小数拆分为整数部分和小数部分
+	xParts := strings.Split(xStr, ".")
+	if len(xParts) < 2 {
+		res = fmt.Sprint(x)
+		return
+	}
+
+	// 计算小数部分的长度,即小数点后面的位数
+	xDecimals := len(xParts[1])
+	if xDecimals > 2 {
+		parts := xParts[1]
+		// 小数点后小于等于两位, 直接拼接返回
+		partLen := len(xParts[1])
+		if partLen <= 2 {
+			res = xParts[0] + "." + parts
+			return
+		}
+		// 找出第一个有效数字, 算出n
+		one := 0
+		for k, p := range parts {
+			// 48->0
+			if p != 48 {
+				if one == 0 {
+					one = k + 1
+				}
+			}
+		}
+		n := partLen - one
+		if n >= 1 {
+			n -= 1
+		} else {
+			one -= 1
+		}
+
+		var partFloat float64
+		partInt, _ := strconv.Atoi(parts)
+		partFloat, _ = decimal.NewFromInt(int64(partInt)).Div(decimal.NewFromFloat(math.Pow(10, float64(n)))).Float64()
+		partFloat = math.Round(partFloat)
+		partFloat, _ = decimal.NewFromFloat(partFloat).Div(decimal.NewFromFloat(math.Pow(10, float64(one+1)))).Float64()
+		resParts := strings.Split(fmt.Sprint(partFloat), ".")
+		resPart := ""
+		if len(resParts) > 1 {
+			resPart = resParts[1]
+		} else {
+			resPart = resParts[0]
+		}
+		res = xParts[0] + "." + resPart
+	}
+
+	if xDecimals < 2 {
+		xDecimalsStr := xParts[1]
+		x, _ = strconv.ParseFloat(xParts[0]+"."+xDecimalsStr, 64)
+		res = xParts[0] + "." + xDecimalsStr
+	}
+	return
+}