Browse Source

财务1.1

hsun 2 years ago
parent
commit
01cf6ccab8

+ 278 - 35
controller/contract/register.go

@@ -6,6 +6,7 @@ import (
 	"fmt"
 	"github.com/gin-gonic/gin"
 	"github.com/go-playground/validator/v10"
+	"github.com/shopspring/decimal"
 	"github.com/tealeg/xlsx"
 	"hongze/fms_api/controller/resp"
 	"hongze/fms_api/global"
@@ -45,12 +46,12 @@ func (rg *RegisterController) List(c *gin.Context) {
 		return
 	}
 
-	// TODO:代付方
 	cond := `1 = 1`
 	pars := make([]interface{}, 0)
+	// 合同编号/客户姓名/销售/代付方
 	if req.Keyword != "" {
 		kw := "%" + req.Keyword + "%"
-		cond += ` AND (company_name LIKE ? OR contract_code LIKE ? OR seller_name LIKE ?)`
+		cond += ` AND (company_name LIKE ? OR contract_code LIKE ? OR seller_name LIKE ? OR pay_company_name LIKE ?)`
 		pars = append(pars, kw, kw, kw)
 	}
 	if req.StartDate != "" && req.EndDate != "" {
@@ -206,12 +207,13 @@ func (rg *RegisterController) Add(c *gin.Context) {
 		return
 	}
 
-	// TODO:代付、补充协议
 	nowTime := time.Now().Local()
 	ob.ContractCode = req.ContractCode
+	ob.PayContractCode = req.PayContractCode
 	ob.CrmContractId = req.CrmContractId
 	ob.ContractSource = req.ContractSource
 	ob.CompanyName = req.CompanyName
+	ob.PayCompanyName = req.PayCompanyName
 	ob.ProductId = req.ProductId
 	ob.SellerId = req.SellerId
 	ob.SellerName = req.SellerName
@@ -225,6 +227,10 @@ func (rg *RegisterController) Add(c *gin.Context) {
 	ob.RegisterStatus = fms.ContractRegisterStatusIng
 	ob.Remark = req.Remark
 	ob.Set()
+	// 补充协议直接完成
+	if req.ContractType == fms.ContractTypePlus {
+		ob.RegisterStatus = fms.ContractRegisterStatusComplete
+	}
 
 	// 套餐信息
 	serviceList, e := fmsService.HandleContractServiceAndDetail(req.ProductId, req.Services, true)
@@ -326,9 +332,11 @@ func (rg *RegisterController) Edit(c *gin.Context) {
 
 	nowTime := time.Now().Local()
 	item.ContractCode = req.ContractCode
+	item.PayContractCode = req.PayContractCode
 	item.CrmContractId = req.CrmContractId
 	item.ContractSource = req.ContractSource
 	item.CompanyName = req.CompanyName
+	item.PayCompanyName = req.PayCompanyName
 	item.SellerId = req.SellerId
 	item.SellerName = req.SellerName
 	item.ContractType = req.ContractType
@@ -339,6 +347,10 @@ func (rg *RegisterController) Edit(c *gin.Context) {
 	item.AgreedPayTime = req.AgreedPayTime
 	item.ContractStatus = req.ContractStatus
 	item.RegisterStatus = fms.ContractRegisterStatusIng
+	// 补充协议直接完成
+	if req.ContractType == fms.ContractTypePlus {
+		item.RegisterStatus = fms.ContractRegisterStatusComplete
+	}
 	item.Remark = req.Remark
 	item.ModifyTime = nowTime
 	updateCols := []string{
@@ -360,8 +372,10 @@ func (rg *RegisterController) Edit(c *gin.Context) {
 		return
 	}
 
-	// 校验金额-是否修改状态
-	go fmsService.CheckContractRegisterAmount(item.ContractRegisterId)
+	// 非补充协议校验金额-是否修改状态
+	if item.ContractType != fms.ContractTypePlus {
+		go fmsService.CheckContractRegisterAmount(item.ContractRegisterId)
+	}
 
 	// 操作日志
 	go func() {
@@ -561,8 +575,10 @@ func (rg *RegisterController) UpdateStatus(c *gin.Context) {
 		return
 	}
 
-	// 校验金额-是否修改状态
-	go fmsService.CheckContractRegisterAmount(req.ContractRegisterId)
+	// 非补充协议校验金额-是否修改状态
+	if item.ContractType != fms.ContractTypePlus {
+		go fmsService.CheckContractRegisterAmount(req.ContractRegisterId)
+	}
 
 	// 操作日志
 	go func() {
@@ -609,6 +625,22 @@ func (rg *RegisterController) Invoice(c *gin.Context) {
 	claims, _ := c.Get("adminInfo")
 	adminInfo := claims.(*system.SysAdmin)
 
+	registerOB := new(fms.ContractRegister)
+	item, e := registerOB.Fetch(req.ContractRegisterId)
+	if e != nil {
+		if e == utils.ErrNoRow {
+			resp.Fail("合同登记不存在或已被删除", c)
+			return
+		}
+		resp.FailMsg("获取合同登记失败", "Err:"+e.Error(), c)
+		return
+	}
+	if item.ContractType == fms.ContractTypePlus {
+		resp.Fail("补充协议不允许添加开票/到款登记", c)
+		return
+	}
+
+	noChangeInvoiceIds := make([]int, 0)
 	newInvoice := make([]*fms.ContractInvoice, 0)
 	if len(req.AmountList) > 0 {
 		for i := range req.AmountList {
@@ -625,22 +657,84 @@ func (rg *RegisterController) Invoice(c *gin.Context) {
 				resp.FailData("日期格式有误", "Err:"+e.Error(), c)
 				return
 			}
-			v := &fms.ContractInvoice{
+			if req.AmountList[i].InvoiceId > 0 {
+				noChangeInvoiceIds = append(noChangeInvoiceIds, req.AmountList[i].InvoiceId)
+			} else {
+				v := &fms.ContractInvoice{
+					ContractRegisterId: req.ContractRegisterId,
+					ContractCode:       item.ContractCode,
+					Amount:             req.AmountList[i].Amount,
+					InvoiceType:        req.InvoiceType,
+					InvoiceDate:        t,
+					AdminId:            int(adminInfo.AdminId),
+					AdminName:          adminInfo.RealName,
+				}
+				v.Set()
+				newInvoice = append(newInvoice, v)
+			}
+		}
+	}
+
+	// 获取原有的登记信息
+	invoiceCond := `contract_register_id = ? AND invoice_type = ?`
+	invoicePars := make([]interface{}, 0)
+	invoicePars = append(invoicePars, req.ContractRegisterId, req.InvoiceType)
+	originInvoiceList, e := fms.GetContractInvoiceItemList(invoiceCond, invoicePars)
+	if e != nil {
+		resp.FailMsg("获取失败", "获取开票/到款列表失败, Err: "+e.Error(), c)
+		return
+	}
+	// 比对原有和现有的登记信息
+	logList := make([]*fms.ContractRegisterLog, 0)
+	opData := ""
+	opDataByte, e := json.Marshal(req)
+	if e != nil {
+		return
+	}
+	opData = string(opDataByte)
+	opType := fms.ContractRegisterOpTypeInvoice
+	if req.InvoiceType == fms.ContractInvoiceTypePay {
+		opType = fms.ContractRegisterOpTypePayment
+	}
+	nowTime := time.Now().Local()
+	// 需要删除的记录
+	deleteInvoiceIds := make([]int, 0)
+	for i := range originInvoiceList {
+		if !utils.InArrayByInt(noChangeInvoiceIds, originInvoiceList[i].ContractInvoiceId) {
+			deleteInvoiceIds = append(deleteInvoiceIds, originInvoiceList[i].ContractInvoiceId)
+			logList = append(logList, &fms.ContractRegisterLog{
 				ContractRegisterId: req.ContractRegisterId,
-				Amount:             req.AmountList[i].Amount,
-				InvoiceType:        req.InvoiceType,
-				InvoiceDate:        t,
 				AdminId:            int(adminInfo.AdminId),
 				AdminName:          adminInfo.RealName,
-			}
-			v.Set()
-			newInvoice = append(newInvoice, v)
+				OpData:             opData,
+				OpType:             opType,
+				CreateTime:         nowTime,
+				Remark:             fmt.Sprint(adminInfo.RealName, " 删除", fms.ContractInvoiceKeyNameMap[opType], "金额", originInvoiceList[i].Amount, "元"),
+			})
 		}
 	}
+	// 新增的记录
+	if len(newInvoice) > 0 {
+		newAmount := decimal.NewFromFloat(0).Round(2)
+		for i := range newInvoice {
+			a := decimal.NewFromFloat(newInvoice[i].Amount).Round(2)
+			newAmount = newAmount.Add(a)
+		}
+		ia, _ := newAmount.Round(2).Float64()
+		logList = append(logList, &fms.ContractRegisterLog{
+			ContractRegisterId: req.ContractRegisterId,
+			AdminId:            int(adminInfo.AdminId),
+			AdminName:          adminInfo.RealName,
+			OpData:             opData,
+			OpType:             opType,
+			CreateTime:         nowTime,
+			Remark:             fmt.Sprint(adminInfo.RealName, " 新增", fms.ContractInvoiceKeyNameMap[opType], "金额", ia, "元"),
+		})
+	}
 
 	// 删除并新增登记
 	ob := new(fms.ContractInvoice)
-	if e := ob.DeleteAndCreateNewInvoice(req.ContractRegisterId, req.InvoiceType, newInvoice); e != nil {
+	if e := ob.DeleteAndCreateNewInvoice(req.ContractRegisterId, req.InvoiceType, deleteInvoiceIds, newInvoice); e != nil {
 		resp.FailData("日期格式有误", "Err:"+e.Error(), c)
 		return
 	}
@@ -650,25 +744,8 @@ func (rg *RegisterController) Invoice(c *gin.Context) {
 
 	// 操作日志
 	go func() {
-		opData := ""
-		opDataByte, e := json.Marshal(req)
-		if e != nil {
-			return
-		}
-		opData = string(opDataByte)
-		opType := fms.ContractRegisterOpTypeInvoice
-		if req.InvoiceType == fms.ContractInvoiceTypePay {
-			opType = fms.ContractRegisterOpTypePayment
-		}
-
-		logItem := new(fms.ContractRegisterLog)
-		logItem.ContractRegisterId = req.ContractRegisterId
-		logItem.AdminId = int(adminInfo.AdminId)
-		logItem.AdminName = adminInfo.RealName
-		logItem.OpData = opData
-		logItem.OpType = opType
-		logItem.CreateTime = time.Now().Local()
-		if e = logItem.Create(); e != nil {
+		logOB := new(fms.ContractRegisterLog)
+		if e := logOB.AddInBatches(logList); e != nil {
 			return
 		}
 	}()
@@ -808,7 +885,7 @@ func (rg *RegisterController) Export(c *gin.Context) {
 
 		// 获取开票/到款详情, 并取最大的开票/到款数(用于动态扩展第二列表头)
 		ci := new(fms.ContractInvoice)
-		invoiceList, e := ci.List(csCond, csPars)
+		invoiceList, e := ci.List(csCond, csPars, "")
 		if e != nil {
 			resp.FailData("获取开票/到款列表失败", "Err:"+e.Error(), c)
 			return
@@ -950,6 +1027,7 @@ func (rg *RegisterController) Export(c *gin.Context) {
 		row2NameKeyMap[row2Title[i]] = i
 	}
 
+	// TODO:代付和补充协议
 	contractTMap := map[int]int{
 		fms.ContractTypeNew:   1,
 		fms.ContractTypeRenew: 0,
@@ -1078,3 +1156,168 @@ func (rg *RegisterController) Export(c *gin.Context) {
 	c.Writer.Header().Add("Content-Type", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
 	http.ServeContent(c.Writer, c.Request, fileName, time.Now(), content)
 }
+
+// InvoiceList
+// @Title 开票/到款列表
+// @Description 开票/到款列表
+// @Param   InvoiceType		query	int		false	"类型: 1-开票登记; 2-到款登记"
+// @Param   ContractCode	query	string	false	"合同编号"
+// @Param   StartDate		query	string	false	"开始日期"
+// @Param   EndDate			query	string	false	"结束日期"
+// @Param   MinAmount		query	float64	false	"开票金额区间-最小值"
+// @Param   MaxAmount		query	float64	false	"开票金额区间-最大值"
+// @Success 200 {object} fms.ContractInvoiceItem
+// @router /contract/register/invoice_list [get]
+func (rg *RegisterController) InvoiceList(c *gin.Context) {
+	var req fms.ContractInvoiceListReq
+	if e := c.BindQuery(&req); e != nil {
+		err, ok := e.(validator.ValidationErrors)
+		if !ok {
+			resp.FailData("参数解析失败", "Err:"+e.Error(), c)
+			return
+		}
+		resp.FailData("参数解析失败", err.Translate(global.Trans), c)
+		return
+	}
+
+	cond := `invoice_type = ?`
+	pars := make([]interface{}, 0)
+	pars = append(pars, req.InvoiceType)
+	// 合同编号
+	if req.ContractCode != "" {
+		cond += ` AND contract_code = ?`
+		pars = append(pars, req.ContractCode)
+	}
+	if req.StartDate != "" && req.EndDate != "" {
+		st := fmt.Sprint(req.StartDate, " 00:00:00")
+		ed := fmt.Sprint(req.EndDate, " 23:59:59")
+		cond += ` AND (create_time BETWEEN ? AND ?)`
+		pars = append(pars, st, ed)
+	}
+	if req.MinAmount > 0 && req.MaxAmount > 0 {
+		cond += ` AND (amount BETWEEN ? AND ?)`
+		pars = append(pars, req.MinAmount, req.MaxAmount)
+	}
+
+	page := new(base.Page)
+	page.SetPageSize(req.PageSize)
+	page.SetCurrent(req.Current)
+	page.AddOrderItem(base.OrderItem{Column: "invoice_time", Asc: false})
+
+	total, list, e := fms.GetContractInvoiceItemPageList(page, cond, pars)
+	if e != nil {
+		resp.FailMsg("获取失败", "获取合同开票/到款列表失败, Err: "+e.Error(), c)
+		return
+	}
+
+	page.SetTotal(total)
+	baseData := new(base.BaseData)
+	baseData.SetPage(page)
+	baseData.SetList(list)
+	resp.OkData("获取成功", baseData, c)
+}
+
+// InvoiceExport
+// @Title 开票/到款列表-导出
+// @Description 合同登记-导出
+// @Param   InvoiceType		query	int		false	"类型: 1-开票登记; 2-到款登记"
+// @Param   ContractCode	query	string	false	"合同编号"
+// @Param   StartDate		query	string	false	"开始日期"
+// @Param   EndDate			query	string	false	"结束日期"
+// @Param   MinAmount		query	float64	false	"开票金额区间-最小值"
+// @Param   MaxAmount		query	float64	false	"开票金额区间-最大值"
+// @Success 200 string "操作成功"
+// @router /contract/register/invoice_export [get]
+func (rg *RegisterController) InvoiceExport(c *gin.Context) {
+	var req fms.ContractInvoiceListReq
+	if e := c.BindQuery(&req); e != nil {
+		err, ok := e.(validator.ValidationErrors)
+		if !ok {
+			resp.FailData("参数解析失败", "Err:"+e.Error(), c)
+			return
+		}
+		resp.FailData("参数解析失败", err.Translate(global.Trans), c)
+		return
+	}
+
+	cond := `invoice_type = ?`
+	pars := make([]interface{}, 0)
+	pars = append(pars, req.InvoiceType)
+	// 合同编号
+	if req.ContractCode != "" {
+		cond += ` AND contract_code = ?`
+		pars = append(pars, req.ContractCode)
+	}
+	if req.StartDate != "" && req.EndDate != "" {
+		st := fmt.Sprint(req.StartDate, " 00:00:00")
+		ed := fmt.Sprint(req.EndDate, " 23:59:59")
+		cond += ` AND (create_time BETWEEN ? AND ?)`
+		pars = append(pars, st, ed)
+	}
+	if req.MinAmount > 0 && req.MaxAmount > 0 {
+		cond += ` AND (amount BETWEEN ? AND ?)`
+		pars = append(pars, req.MinAmount, req.MaxAmount)
+	}
+
+	// 获取列表数据
+	cr := new(fms.ContractInvoice)
+	orderRule := `invoice_time DESC`
+	list, e := cr.List(cond, pars, orderRule)
+	if e != nil {
+		resp.FailData("获取开票/到款列表失败", "Err:"+e.Error(), c)
+		return
+	}
+	if len(list) == 0 {
+		resp.Fail("无有效数据可导出", c)
+		return
+	}
+
+	// 生成Excel文件
+	xlsxFile := xlsx.NewFile()
+	style := xlsx.NewStyle()
+	alignment := xlsx.Alignment{
+		Horizontal: "center",
+		Vertical:   "center",
+		WrapText:   true,
+	}
+	style.Alignment = alignment
+	style.ApplyAlignment = true
+
+	sheet, err := xlsxFile.AddSheet("开票列表")
+	if err != nil {
+		resp.FailData("新增Sheet失败", "Err:"+err.Error(), c)
+		return
+	}
+
+	// 表头
+	titleRow := sheet.AddRow()
+	titleRow.SetHeight(40)
+	cell1 := titleRow.AddCell()
+	cell1.SetValue("合同编号")
+	cell1.SetStyle(style)
+	cell2 := titleRow.AddCell()
+	cell2.SetValue("开票金额")
+	cell2.SetStyle(style)
+	cell3 := titleRow.AddCell()
+	cell3.SetValue("开票日期")
+	cell3.SetStyle(style)
+
+	for _, v := range list {
+		dataRow := sheet.AddRow()
+		dataRow.SetHeight(20)
+		dataRow.AddCell().SetString(v.ContractCode)
+		dataRow.AddCell().SetString(fmt.Sprint(v.Amount))
+		dataRow.AddCell().SetString(utils.TimeTransferString("2006-01-02", v.InvoiceDate))
+	}
+
+	// 输出文件
+	var buffer bytes.Buffer
+	_ = xlsxFile.Write(&buffer)
+	content := bytes.NewReader(buffer.Bytes())
+	randStr := time.Now().Format(utils.FormatDateTimeUnSpace)
+	fileName := "开票列表_" + randStr + ".xlsx"
+
+	c.Writer.Header().Add("Content-Disposition", fmt.Sprintf(`attachment; filename="%s"`, fileName))
+	c.Writer.Header().Add("Content-Type", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
+	http.ServeContent(c.Writer, c.Request, fileName, time.Now(), content)
+}

+ 49 - 6
controller/crm/contract.go

@@ -1,13 +1,16 @@
 package crm
 
 import (
+	"fmt"
 	"github.com/gin-gonic/gin"
 	"github.com/go-playground/validator/v10"
 	"hongze/fms_api/controller/resp"
 	"hongze/fms_api/global"
 	"hongze/fms_api/models/base"
 	"hongze/fms_api/models/crm"
+	"hongze/fms_api/models/fms"
 	"hongze/fms_api/models/system"
+	crmService "hongze/fms_api/services/crm"
 	"hongze/fms_api/utils"
 	"strings"
 )
@@ -34,9 +37,7 @@ func (rg *ContractController) SearchList(c *gin.Context) {
 		return
 	}
 
-	// TODO:代付、补充协议
-	// 补充协议暂不查询
-	cond := `status IN ('已审批', '已签回') AND contract_type IN ('新签合同', '续约合同')`
+	cond := `status IN ('已审批', '已签回') AND contract_type IN ('新签合同', '续约合同', '补充协议')`
 	pars := make([]interface{}, 0)
 	if req.Keyword != "" {
 		kw := "%" + req.Keyword + "%"
@@ -55,7 +56,7 @@ func (rg *ContractController) SearchList(c *gin.Context) {
 	ob := new(crm.Contract)
 	total, list, e := ob.PageList(page, cond, pars)
 	if e != nil {
-		resp.FailMsg("获取失败", "获取合同登记列表, Err: "+e.Error(), c)
+		resp.FailMsg("获取失败", "获取合同列表失败, Err: "+e.Error(), c)
 		return
 	}
 
@@ -66,7 +67,8 @@ func (rg *ContractController) SearchList(c *gin.Context) {
 			peyContractIds = append(peyContractIds, list[i].ContractId)
 		}
 	}
-	payCompanyMap := make(map[int]string, 0)
+	payCompanyMap := make(map[int]string, 0)      // 代付合同实际使用方
+	payContractCodeMap := make(map[int]string, 0) // 代付合同实际使用方合同编号
 	if len(peyContractIds) > 0 {
 		payCond := `a.status IN ('已签回', '已审批') AND b.payment_on_behalf_contract_id IN ?`
 		payPars := make([]interface{}, 0)
@@ -78,20 +80,27 @@ func (rg *ContractController) SearchList(c *gin.Context) {
 		}
 		for i := range payList {
 			payCompanyMap[payList[i].PayOnBehalfContractId] = payList[i].CompanyName
+			payContractCodeMap[payList[i].PayOnBehalfContractId] = payList[i].ContractCode
 		}
 	}
 
 	respList := make([]*crm.ContractSearchListResp, 0)
 	for i := range list {
+		contractTypeKey := crm.ContractTypeFmsMap[list[i].ContractType]
+		if list[i].ContractBusinessType == "代付合同" {
+			contractTypeKey = fms.ContractTypeAgentPay
+		}
+
 		respList = append(respList, &crm.ContractSearchListResp{
 			ContractId:      list[i].ContractId,
 			ContractCode:    list[i].ContractCode,
 			ProductId:       list[i].ProductId,
 			CompanyName:     list[i].CompanyName,
+			PayContractCode: payContractCodeMap[list[i].ContractId],
 			PayCompanyName:  payCompanyMap[list[i].ContractId],
 			SellerId:        list[i].SellerId,
 			SellerName:      list[i].SellerName,
-			ContractTypeKey: crm.ContractTypeFmsMap[list[i].ContractType],
+			ContractTypeKey: contractTypeKey,
 			ContractType:    list[i].ContractType,
 			Price:           list[i].Price,
 			StartDate:       utils.TimeTransferString(utils.FormatDate, list[i].StartDate),
@@ -204,3 +213,37 @@ func (rg *ContractController) PermissionList(c *gin.Context) {
 	}
 	resp.OkData("获取成功", respList, c)
 }
+
+// ServiceDetail
+// @Title 获取合同的套餐及品种权限
+// @Description 获取合同的套餐及品种权限
+// @Param   ContractId  query  int  true  "合同ID"
+// @Success 200 {object} crm.ContractDetail
+// @router /crm/contract/service_detail [get]
+func (rg *ContractController) ServiceDetail(c *gin.Context) {
+	var req crm.ContractServiceDetailReq
+	if e := c.BindQuery(&req); e != nil {
+		err, ok := e.(validator.ValidationErrors)
+		if !ok {
+			resp.FailData("参数解析失败", "Err:"+e.Error(), c)
+			return
+		}
+		resp.FailData("参数解析失败", err.Translate(global.Trans), c)
+		return
+	}
+
+	contractDetail, e := crmService.GetContractDetail(req.ContractId)
+	if e != nil {
+		resp.FailMsg("获取失败", "获取合同套餐及品种信息失败, Err: "+e.Error(), c)
+		return
+	}
+
+	chartPermissionMap, e := crmService.GetServicePermissionMap(contractDetail.Service)
+	if e != nil {
+		resp.FailMsg("获取失败", "获取合同服务中的权限ID失败, Err: "+e.Error(), c)
+		return
+	}
+	fmt.Println(chartPermissionMap)
+
+	resp.OkData("获取成功", contractDetail, c)
+}

+ 26 - 0
models/crm/chart_permission.go

@@ -73,3 +73,29 @@ func GetPermissionSetItemsByCondition(condition string, pars []interface{}) (ite
 type ContractPermissionListReq struct {
 	ProductId int `json:"product_id" form:"product_id" description:"产品: 1-FICC; 2-权益"`
 }
+
+type CompanyPermissionLookItem struct {
+	ChartPermissionId  int    `description:"权限id"`
+	PermissionName     string `description:"权限名称"`
+	StartDate          string `description:"权限开始日期"`
+	EndDate            string `description:"权限结束日期"`
+	Status             string `description:"'正式','试用','关闭'"`
+	ExpireDay          string `description:"到期天数"`
+	ClassifyName       string `description:"分类"`
+	PermissionType     int    `description:"1主观,2客观"`
+	PermissionTypeName string `description:"主观、客观"`
+	Checked            bool   `description:"选中状态"`
+	Remark             string `description:"备注"`
+	IsMerge            bool   `description:"是否合并行业, 给前端的标识, 暂时仅权益使用"`
+	RaiBothHas         bool   `description:"权益-是否主客观都有"`
+	IsUpgrade          int    `description:"是否升级,1是,0否"`
+}
+
+func GetPermissionLookItems(productId int, classifyName string) (items []*CompanyPermissionLookItem, err error) {
+	items = make([]*CompanyPermissionLookItem, 0)
+	err = global.MYSQL["report"].Model(ChartPermission{}).
+		Where("enabled = 1 AND product_id = ? AND classify_name = ?", productId, classifyName).
+		Order("sort ASC").
+		Find(&items).Error
+	return
+}

+ 2 - 0
models/crm/constants.go

@@ -40,10 +40,12 @@ const (
 	// 合同类型
 	ContractTypeNew   = "新签合同" // 新签
 	ContractTypeRenew = "续约合同" // 续约
+	ContractTypePlus  = "补充协议" // 补充
 )
 
 // ContractTypeFmsMap CRM系统合同类型/FMS系统合同类型
 var ContractTypeFmsMap = map[string]int{
 	ContractTypeNew:   1,
 	ContractTypeRenew: 2,
+	ContractTypePlus:  4,
 }

+ 51 - 2
models/crm/contract.go

@@ -80,10 +80,11 @@ type ContractSearchListResp struct {
 	ContractCode    string  `json:"contract_code" description:"合同编号"`
 	ProductId       int     `json:"product_id" description:"产品ID"`
 	CompanyName     string  `json:"company_name" description:"客户名称"`
+	PayContractCode string  `json:"pay_contract_code" description:"代付合同编号"`
 	PayCompanyName  string  `json:"pay_company_name" description:"代付客户名称"`
 	SellerId        int     `json:"seller_id" description:"销售ID"`
 	SellerName      string  `json:"seller_name" description:"销售名称"`
-	ContractTypeKey int     `json:"contract_type_key" description:"FMS合同类型: 1-新签; 2-续约; 0-补充协议(暂无);"`
+	ContractTypeKey int     `json:"contract_type_key" description:"FMS合同类型: 1-新签; 2-续约; 3-代付; 4-补充协议;"`
 	ContractType    string  `json:"contract_type" description:"CRM合同类型: 新签合同; 续约合同; 补充协议;"`
 	Price           float64 `json:"price" description:"合同金额"`
 	StartDate       string  `json:"start_date" description:"合同开始日期"`
@@ -93,6 +94,7 @@ type ContractSearchListResp struct {
 // PayCompanyRelation 代付合同
 type PayCompanyRelation struct {
 	ContractId            int    `description:"代付合同ID"`
+	ContractCode          string `description:"代付合同编号"`
 	CompanyName           string `description:"代付方名称"`
 	PayOnBehalfContractId int    `description:"实际使用方合同ID"`
 }
@@ -102,10 +104,57 @@ func GetPayCompanyByContractIds(condition string, pars []interface{}) (results [
 	results = make([]*PayCompanyRelation, 0)
 	query := global.MYSQL["report"].
 		Table("contract as a").
-		Select("a.contract_id, a.company_name, b.payment_on_behalf_contract_id").
+		Select("a.contract_id, a.contract_code, a.company_name, b.payment_on_behalf_contract_id").
 		Joins("JOIN contract_relation b ON a.contract_id = b.contract_id").
 		Where("a.is_delete = 0").
 		Where(condition, pars...)
 	err = query.Find(&results).Error
 	return
 }
+
+// ContractDetail 合同详情信息(包含服务信息等)
+type ContractDetail struct {
+	Contract
+	StartDateStr               string `description:"合同起始时间(字符串形式)"`
+	EndDateStr                 string `description:"合同结束时间(字符串形式)"`
+	ApproveTimeStr             string `description:"审批时间(字符串形式)"`
+	InvalidTimeStr             string `description:"作废时间(字符串形式)"`
+	CheckBackFileTimeStr       string `description:"合同签回时间(字符串形式)"`
+	RescindTimeStr             string `description:"解约时间(字符串形式)"`
+	ModifyTimeStr              string `description:"最近一次更新时间(字符串形式)"`
+	CreateTimeStr              string `description:"合同添加时间(字符串形式)"`
+	Service                    []*ContractServiceAndDetail
+	RelationContractDetailList []*ContractDetail     `description:"关联合同详情"`
+	PermissionLookList         []*PermissionLookList `description:"合同里面的权限列表"`
+}
+
+type PermissionLookList struct {
+	ClassifyName string `description:"分类"`
+	Items        []*PermissionLookItem
+}
+
+type PermissionLookItem struct {
+	ChartPermissionId int    `description:"权限id"`
+	PermissionName    string `description:"权限名称"`
+	ClassifyName      string `description:"分类"`
+}
+
+// GetContractDetailById 根据合同ID获取合同详情信息
+func GetContractDetailById(contractId int) (detail *ContractDetail, err error) {
+	detail = new(ContractDetail)
+	item := new(Contract)
+	query := global.MYSQL["report"].
+		Model(Contract{}).
+		Where("contract_id = ?", contractId)
+	err = query.Find(&item).Error
+	if err != nil {
+		return
+	}
+	detail.Contract = *item
+	return
+}
+
+// ContractServiceDetailReq CRM系统合同-合同套餐及品种权限详情请求体
+type ContractServiceDetailReq struct {
+	ContractId int `json:"contract_id" form:"contract_id" binding:"required,gte=1" description:"合同ID"`
+}

+ 71 - 0
models/crm/contract_relation.go

@@ -0,0 +1,71 @@
+package crm
+
+import "hongze/fms_api/global"
+
+// ContractRelation 合同关系表结构体
+type ContractRelation struct {
+	ContractId                int `description:"业务合同id"`
+	PaymentOnBehalfContractId int `description:"代付合同id"`
+}
+
+type RelationContractQuery struct {
+	ContractId                int    `description:"合同id"`
+	CompanyName               string `description:"甲方名称"`
+	PaymentOnBehalfContractId int    `description:"代付合同id"`
+}
+
+type RelationContractList struct {
+	ContractId                int     `description:"合同id"`
+	CompanyName               string  `description:"甲方名称"`
+	PaymentOnBehalfContractId int     `description:"代付合同id"`
+	Price                     float64 `description:"付款金额"`
+	Service                   []*ContractServiceAndDetail
+}
+
+// GetContractRelationListByRelationContractId 根据业务合同id获取对应的代付合同基础信息
+func GetContractRelationListByRelationContractId(contractId int) (list []*RelationContractList, err error) {
+	results := make([]*RelationContractQuery, 0)
+	list = make([]*RelationContractList, 0)
+	query := global.MYSQL["report"].
+		Table("contract AS a").
+		Select("b.contract_id, a.company_name, b.payment_on_behalf_contract_id").
+		Joins("JOIN contract_relation b ON a.contract_id = b.payment_on_behalf_contract_id").
+		Where("a.status IN ('已签回','已审批') AND a.is_delete = 0 AND b.contract_id = ?", contractId).
+		Order("a.contract_id ASC")
+	err = query.Find(&results).Error
+	if err != nil {
+		return
+	}
+	for i := range results {
+		list = append(list, &RelationContractList{
+			ContractId:                results[i].ContractId,
+			CompanyName:               results[i].CompanyName,
+			PaymentOnBehalfContractId: results[i].PaymentOnBehalfContractId,
+		})
+	}
+	return
+}
+
+// GetContractRelationListByPaymentOnBehalfContractId 根据代付合同id获取对应的业务合同基础信息
+func GetContractRelationListByPaymentOnBehalfContractId(contractId int) (list []*RelationContractList, err error) {
+	results := make([]*RelationContractQuery, 0)
+	list = make([]*RelationContractList, 0)
+	query := global.MYSQL["report"].
+		Table("contract AS a").
+		Select("a.contract_id, a.company_name, b.payment_on_behalf_contract_id").
+		Joins("JOIN contract_relation b ON a.contract_id = b.payment_on_behalf_contract_id").
+		Where("a.status IN ('已签回','已审批') AND a.is_delete = 0 AND b.payment_on_behalf_contract_id = ?", contractId).
+		Order("a.contract_id ASC")
+	err = query.Find(&results).Error
+	if err != nil {
+		return
+	}
+	for i := range results {
+		list = append(list, &RelationContractList{
+			ContractId:                results[i].ContractId,
+			CompanyName:               results[i].CompanyName,
+			PaymentOnBehalfContractId: results[i].PaymentOnBehalfContractId,
+		})
+	}
+	return
+}

+ 56 - 0
models/crm/contract_service.go

@@ -0,0 +1,56 @@
+package crm
+
+import "hongze/fms_api/global"
+
+// ContractServiceAndDetail 合同的服务内容
+type ContractServiceAndDetail struct {
+	ContractServiceId  int    `description:"套餐ID"`
+	ContractId         int    `description:"合同id"`
+	ProductId          int    `description:"产品id,1:ficc;2:权益"`
+	ServiceTemplateId  int    `description:"合同服务模板id"`
+	Title              string `description:"套餐标题"`
+	Value              string `description:"套餐的值"`
+	HasDetail          string `description:"是否有详情,枚举值:是、否;默认:否"`
+	TableValue         string `description:"表格数据,用于word生成时的json数据"`
+	ChartPermissionId  int    `description:"权限id"`
+	ChartPermissionIds []int  `description:"小套餐-权限IDs"`
+	DetailList         []*ContractServiceDetail
+}
+
+type ContractServiceAndDetailQueryItem struct {
+	ContractServiceId int    `description:"套餐ID"`
+	ContractId        int    `description:"合同id"`
+	ProductId         int    `description:"产品id,1:ficc;2:权益"`
+	ServiceTemplateId int    `description:"合同服务模板id"`
+	Title             string `description:"套餐标题"`
+	Value             string `description:"套餐的值"`
+	HasDetail         string `description:"是否有详情,枚举值:是、否;默认:否"`
+	TableValue        string `description:"表格数据,用于word生成时的json数据"`
+	ChartPermissionId int    `description:"权限id"`
+}
+
+func GetContractServiceAndDetailList(contractId int) (list []*ContractServiceAndDetail, err error) {
+	results := make([]*ContractServiceAndDetailQueryItem, 0)
+	list = make([]*ContractServiceAndDetail, 0)
+	query := global.MYSQL["report"].
+		Table("contract_service").
+		Where("contract_id = ?", contractId)
+	err = query.Find(&results).Error
+	if err != nil {
+		return
+	}
+	for i := range results {
+		list = append(list, &ContractServiceAndDetail{
+			ContractServiceId: results[i].ContractServiceId,
+			ContractId:        results[i].ContractId,
+			ProductId:         results[i].ProductId,
+			ServiceTemplateId: results[i].ServiceTemplateId,
+			Title:             results[i].Title,
+			Value:             results[i].Value,
+			HasDetail:         results[i].HasDetail,
+			TableValue:        results[i].TableValue,
+			ChartPermissionId: results[i].ChartPermissionId,
+		})
+	}
+	return
+}

+ 31 - 0
models/crm/contract_service_detail.go

@@ -0,0 +1,31 @@
+package crm
+
+import (
+	"hongze/fms_api/global"
+	"time"
+)
+
+type ContractServiceDetail struct {
+	Id                int       `description:"id"`
+	ContractServiceId int       `description:"合同服务id"`
+	ContractId        int       `description:"合同id"`
+	ServiceTemplateId int       `description:"服务模板id"`
+	Col1              string    `gorm:"column:col_1" description:"第1列数据"`
+	Col2              string    `gorm:"column:col_2" description:"第2列数据"`
+	Col3              string    `gorm:"column:col_3" description:"第3列数据"`
+	Col4              string    `gorm:"column:col_4" description:"第4列数据"`
+	Col5              string    `gorm:"column:col_5" description:"第5列数据"`
+	Col6              string    `gorm:"column:col_6" description:"第6列数据"`
+	Col7              string    `gorm:"column:col_7" description:"第7列数据"`
+	CreateTime        time.Time `description:"数据添加时间"`
+}
+
+// GetContractServiceDetailListByServiceId 根据合同服务id获取对应的套餐表格数据详情
+func GetContractServiceDetailListByServiceId(contractServiceId int) (list []*ContractServiceDetail, err error) {
+	list = make([]*ContractServiceDetail, 0)
+	err = global.MYSQL["report"].Table("contract_service_detail").
+		Where("contract_service_id = ?", contractServiceId).
+		Order("id ASC").
+		Find(&list).Error
+	return
+}

+ 9 - 2
models/fms/constants.go

@@ -2,8 +2,10 @@ package fms
 
 const (
 	// 合同类型
-	ContractTypeNew   = 1 // 新签
-	ContractTypeRenew = 2 // 续约
+	ContractTypeNew      = 1 // 新签
+	ContractTypeRenew    = 2 // 续约
+	ContractTypeAgentPay = 3 // 代付
+	ContractTypePlus     = 4 // 补充协议
 
 	// 合同状态
 	ContractStatusApproved    = 1 // 已审批
@@ -32,3 +34,8 @@ var ContractStatusKeyNameMap = map[int]string{
 	ContractStatusSendOut:     "单章寄出",
 	ContractStatusCheckedBack: "已签回",
 }
+
+var ContractInvoiceKeyNameMap = map[int]string{
+	ContractRegisterOpTypeInvoice: "开票",
+	ContractRegisterOpTypePayment: "到款",
+}

+ 65 - 11
models/fms/contract_invoice.go

@@ -11,6 +11,7 @@ import (
 type ContractInvoice struct {
 	ContractInvoiceId  int       `gorm:"primaryKey;column:contract_invoice_id" json:"contract_invoice_id" description:"开票ID"`
 	ContractRegisterId int       `gorm:"column:contract_register_id" json:"contract_register_id" description:"登记ID"`
+	ContractCode       string    `gorm:"column:contract_code" json:"contract_code" description:"合同编号"`
 	Amount             float64   `gorm:"column:amount" json:"amount" description:"金额"`
 	InvoiceType        int       `gorm:"column:invoice_type" json:"invoice_type" description:"类型: 1-开票登记; 2-到款登记"`
 	InvoiceDate        time.Time `gorm:"column:invoice_time" json:"invoice_time" description:"开票日期/到款月"`
@@ -29,6 +30,7 @@ func (c *ContractInvoice) TableName() string {
 type ContractInvoiceItem struct {
 	ContractInvoiceId  int     `gorm:"column:contract_invoice_id" json:"contract_invoice_id" description:"开票ID"`
 	ContractRegisterId int     `gorm:"column:contract_register_id" json:"contract_register_id" description:"登记ID"`
+	ContractCode       string  `gorm:"column:contract_code" json:"contract_code" description:"合同编号"`
 	Amount             float64 `gorm:"column:amount" json:"amount" description:"金额"`
 	InvoiceType        int     `gorm:"column:invoice_type" json:"invoice_type" description:"类型: 1-开票登记; 2-到款登记"`
 	InvoiceDate        string  `gorm:"column:invoice_time" json:"invoice_time" description:"开票日期/到款月"`
@@ -51,13 +53,17 @@ func (c *ContractInvoice) Update(updateCols []string) (err error) {
 	return
 }
 
-func (c *ContractInvoice) List(condition string, pars []interface{}) (list []*ContractInvoice, err error) {
+func (c *ContractInvoice) List(condition string, pars []interface{}, orderRule string) (list []*ContractInvoice, err error) {
 	list = make([]*ContractInvoice, 0)
-	err = global.DEFAULT_MYSQL.Model(c).
+	query := global.DEFAULT_MYSQL.Model(c).
 		Where("is_deleted = 0").
-		Where(condition, pars...).
-		Order("contract_invoice_id ASC").
-		Find(&list).Error
+		Where(condition, pars...)
+	if orderRule != "" {
+		query.Order(orderRule)
+	} else {
+		query.Order("contract_invoice_id ASC")
+	}
+	err = query.Find(&list).Error
 	return
 }
 
@@ -75,7 +81,7 @@ func (c *ContractInvoice) PageList(page base.IPage, condition string, pars []int
 }
 
 // DeleteAndCreateNewInvoice 删除并新增登记
-func (c *ContractInvoice) DeleteAndCreateNewInvoice(contractRegisterId, invoiceType int, invoices []*ContractInvoice) (err error) {
+func (c *ContractInvoice) DeleteAndCreateNewInvoice(contractRegisterId, invoiceType int, deleteInvoiceIds []int, invoices []*ContractInvoice) (err error) {
 	tx := global.DEFAULT_MYSQL.Begin()
 	defer func() {
 		if err != nil {
@@ -85,11 +91,13 @@ func (c *ContractInvoice) DeleteAndCreateNewInvoice(contractRegisterId, invoiceT
 		}
 	}()
 
-	err = tx.Model(c).
-		Where("contract_register_id = ? AND invoice_type = ?", contractRegisterId, invoiceType).
-		UpdateColumn("is_deleted", 1).Error
-	if err != nil {
-		return
+	if len(deleteInvoiceIds) > 0 {
+		err = tx.Model(c).
+			Where("contract_register_id = ? AND invoice_type = ? AND contract_invoice_id IN (?)", contractRegisterId, invoiceType, deleteInvoiceIds).
+			UpdateColumn("is_deleted", 1).Error
+		if err != nil {
+			return
+		}
 	}
 	if len(invoices) > 0 {
 		err = tx.CreateInBatches(invoices, len(invoices)).Error
@@ -136,6 +144,7 @@ func formatContractInvoice2ItemList(list []*ContractInvoice) (itemList []*Contra
 		itemList = append(itemList, &ContractInvoiceItem{
 			ContractInvoiceId:  list[i].ContractInvoiceId,
 			ContractRegisterId: list[i].ContractRegisterId,
+			ContractCode:       list[i].ContractCode,
 			Amount:             list[i].Amount,
 			InvoiceType:        list[i].InvoiceType,
 			InvoiceDate:        utils.TimeTransferString(utils.FormatDate, list[i].InvoiceDate),
@@ -145,3 +154,48 @@ func formatContractInvoice2ItemList(list []*ContractInvoice) (itemList []*Contra
 	}
 	return
 }
+
+// ContractInvoiceListReq 合同开票/到款登记列表请求体
+type ContractInvoiceListReq struct {
+	InvoiceType  int     `json:"invoice_type" form:"invoice_type" binding:"oneof=1 2" description:"类型: 1-开票登记; 2-到款登记"`
+	ContractCode string  `json:"contract_code" form:"contract_code" binding:"omitempty" description:"合同编号"`
+	StartDate    string  `json:"start_date" form:"start_date" binding:"omitempty,datetime=2006-01-02" description:"开始日期"`
+	EndDate      string  `json:"end_date" form:"end_date" binding:"omitempty,datetime=2006-01-02" description:"结束日期"`
+	MinAmount    float64 `json:"min_amount" form:"min_amount" description:"开票金额区间-最小值"`
+	MaxAmount    float64 `json:"max_amount" form:"max_amount" description:"开票金额区间-最大值"`
+	base.PageReq
+}
+
+// GetContractInvoiceItemPageList 获取合同开票/到款列表-分页
+func GetContractInvoiceItemPageList(page base.IPage, condition string, pars []interface{}) (count int64, results []*ContractInvoiceItem, err error) {
+	list := make([]*ContractInvoice, 0)
+	query := global.DEFAULT_MYSQL.Table("contract_invoice").
+		Where("is_deleted = 0").
+		Where(condition, pars...)
+	query.Count(&count)
+	if len(page.GetOrderItemsString()) > 0 {
+		query = query.Order(page.GetOrderItemsString())
+	}
+	err = query.Limit(int(page.GetPageSize())).Offset(int(page.Offset())).Find(&list).Error
+	if err != nil {
+		return
+	}
+	for i := range list {
+		results = append(results, formatContractInvoice2Item(list[i]))
+	}
+	return
+}
+
+// formatContractInvoice2Item 格式化ContractInvoiceItem
+func formatContractInvoice2Item(item *ContractInvoice) (formatItem *ContractInvoiceItem) {
+	formatItem = new(ContractInvoiceItem)
+	formatItem.ContractInvoiceId = item.ContractInvoiceId
+	formatItem.ContractRegisterId = item.ContractRegisterId
+	formatItem.ContractCode = item.ContractCode
+	formatItem.Amount = item.Amount
+	formatItem.InvoiceType = item.InvoiceType
+	formatItem.InvoiceDate = utils.TimeTransferString(utils.FormatDate, item.InvoiceDate)
+	formatItem.Remark = item.Remark
+	formatItem.CreateTime = utils.TimeTransferString(utils.FormatDateTime, item.CreateTime)
+	return
+}

+ 44 - 40
models/fms/contract_register.go

@@ -11,13 +11,15 @@ import (
 type ContractRegister struct {
 	ContractRegisterId int       `gorm:"primaryKey;column:contract_register_id" json:"contract_register_id" description:"登记ID"`
 	ContractCode       string    `gorm:"column:contract_code" json:"contract_code" description:"合同编号"`
+	PayContractCode    string    `gorm:"column:pay_contract_code" json:"pay_contract_code" description:"代付合同编号"`
 	CrmContractId      int       `gorm:"column:crm_contract_id" json:"crm_contract_id" description:"CRM系统-合同ID"`
 	ContractSource     int       `gorm:"column:contract_source" json:"contract_source" description:"合同来源: 0-非系统合同导入; 1-CRM合同导入"`
 	CompanyName        string    `gorm:"column:company_name" json:"company_name" description:"客户名称"`
+	PayCompanyName     string    `gorm:"column:pay_company_name" json:"pay_company_name" description:"代付方-客户名称"`
 	ProductId          int       `gorm:"column:product_id" json:"product_id" description:"产品ID: 1-FICC; 2-权益"`
 	SellerId           int       `gorm:"column:seller_id" json:"seller_id" description:"CRM系统-销售ID"`
 	SellerName         string    `gorm:"column:seller_name" json:"seller_name" description:"CRM系统-销售名称"`
-	ContractType       int       `gorm:"column:contract_type" json:"contract_type" description:"合同类型: 1-新签; 2-续约"`
+	ContractType       int       `gorm:"column:contract_type" json:"contract_type" description:"合同类型: 1-新签; 2-续约; 3-代付; 4-补充协议"`
 	ContractAmount     float64   `gorm:"column:contract_amount" json:"contract_amount" description:"合同金额"`
 	InvoicedAmount     float64   `gorm:"column:invoiced_amount" json:"invoiced_amount" description:"开票金额"`
 	PaymentAmount      float64   `gorm:"column:payment_amount" json:"payment_amount" description:"到款金额"`
@@ -142,23 +144,25 @@ type ContractRegisterUpdateStatusReq struct {
 
 // ContractRegisterAddReq 新增合同登记请求体
 type ContractRegisterAddReq struct {
-	ContractCode   string                  `json:"contract_code" binding:"required" description:"合同编号"`
-	CrmContractId  int                     `json:"crm_contract_id" description:"CRM系统-合同ID"`
-	ContractSource int                     `json:"contract_source" binding:"oneof=0 1" description:"合同来源: 0-非系统合同导入; 1-CRM合同导入"`
-	CompanyName    string                  `json:"company_name" binding:"required" description:"客户名称"`
-	SellerId       int                     `json:"seller_id" binding:"required" description:"CRM系统-销售ID"`
-	SellerName     string                  `json:"seller_name" binding:"required" description:"CRM系统-销售名称"`
-	ContractType   int                     `json:"contract_type" binding:"oneof=1 2" description:"合同类型: 1-新签; 2-续约"`
-	ContractAmount float64                 `json:"contract_amount" binding:"required" description:"合同金额"`
-	StartDate      string                  `json:"start_date" binding:"required" description:"合同开始日期"`
-	EndDate        string                  `json:"end_date" binding:"required" description:"合同结束日期"`
-	SignDate       string                  `json:"sign_date" binding:"required" description:"合同签订日期"`
-	AgreedPayTime  string                  `json:"agreed_pay_time" binding:"required" description:"约定付款时间(如:生效日起10日内)"`
-	ContractStatus int                     `json:"contract_status" binding:"oneof=1 2 3" description:"合同状态: 1-已审批; 2-单章寄出; 3-已签回"`
-	Remark         string                  `json:"remark" description:"备注信息"`
-	ProductId      int                     `json:"product_id" binding:"oneof=1 2" description:"产品ID"`
-	ServiceRemark  string                  `json:"service_remark" description:"套餐备注"`
-	Services       []ContractServiceAddReq `json:"services" description:"服务套餐内容"`
+	ContractCode    string                  `json:"contract_code" binding:"required" description:"合同编号"`
+	PayContractCode string                  `json:"pay_contract_code" description:"代付合同编号"`
+	CrmContractId   int                     `json:"crm_contract_id" description:"CRM系统-合同ID"`
+	ContractSource  int                     `json:"contract_source" binding:"oneof=0 1" description:"合同来源: 0-非系统合同导入; 1-CRM合同导入"`
+	CompanyName     string                  `json:"company_name" binding:"required" description:"客户名称"`
+	PayCompanyName  string                  `json:"pay_company_name" description:"代付方客户名称"`
+	SellerId        int                     `json:"seller_id" binding:"required" description:"CRM系统-销售ID"`
+	SellerName      string                  `json:"seller_name" binding:"required" description:"CRM系统-销售名称"`
+	ContractType    int                     `json:"contract_type" binding:"oneof=1 2 3 4" description:"合同类型: 1-新签; 2-续约; 3-代付; 4-补充协议"`
+	ContractAmount  float64                 `json:"contract_amount" binding:"required" description:"合同金额"`
+	StartDate       string                  `json:"start_date" binding:"required" description:"合同开始日期"`
+	EndDate         string                  `json:"end_date" binding:"required" description:"合同结束日期"`
+	SignDate        string                  `json:"sign_date" description:"合同签订日期"`
+	AgreedPayTime   string                  `json:"agreed_pay_time" description:"约定付款时间(如:生效日起10日内)"`
+	ContractStatus  int                     `json:"contract_status" binding:"oneof=1 2 3" description:"合同状态: 1-已审批; 2-单章寄出; 3-已签回"`
+	Remark          string                  `json:"remark" description:"备注信息"`
+	ProductId       int                     `json:"product_id" binding:"oneof=1 2" description:"产品ID"`
+	ServiceRemark   string                  `json:"service_remark" description:"套餐备注"`
+	Services        []ContractServiceAddReq `json:"services" description:"服务套餐内容"`
 }
 
 // ContractRegisterEditReq 编辑合同登记请求体
@@ -181,7 +185,7 @@ func CreateContractRegisterAndServices(item *ContractRegister, serviceDetail []*
 	// 合同登记
 	tx.Create(item)
 
-	nowTime := time.Now().Local()
+	//nowTime := time.Now().Local()
 	for i := 0; i < len(serviceDetail); i++ {
 		// 合同服务
 		t := serviceDetail[i]
@@ -199,16 +203,16 @@ func CreateContractRegisterAndServices(item *ContractRegister, serviceDetail []*
 		contractService.Set()
 		tx.Create(contractService)
 
-		// 合同服务详情
-		for j := 0; j < len(t.Detail); j++ {
-			contractServiceDetail := t.Detail[j]
-			contractServiceDetail.ContractServiceId = contractService.ContractServiceId
-			contractServiceDetail.ContractRegisterId = item.ContractRegisterId
-			contractServiceDetail.ServiceTemplateId = contractService.ServiceTemplateId
-			contractServiceDetail.CreateTime = nowTime
-			tx.Create(contractServiceDetail)
-			t.Detail[j] = contractServiceDetail
-		}
+		//// 合同服务详情
+		//for j := 0; j < len(t.Detail); j++ {
+		//	contractServiceDetail := t.Detail[j]
+		//	contractServiceDetail.ContractServiceId = contractService.ContractServiceId
+		//	contractServiceDetail.ContractRegisterId = item.ContractRegisterId
+		//	contractServiceDetail.ServiceTemplateId = contractService.ServiceTemplateId
+		//	contractServiceDetail.CreateTime = nowTime
+		//	tx.Create(contractServiceDetail)
+		//	t.Detail[j] = contractServiceDetail
+		//}
 	}
 	return
 }
@@ -237,7 +241,7 @@ func UpdateContractRegisterAndServices(item *ContractRegister, updateCols []stri
 	tx.Exec(sql, item.ContractRegisterId)
 
 	// 新增合同服务
-	nowTime := time.Now().Local()
+	//nowTime := time.Now().Local()
 	for i := 0; i < len(serviceDetail); i++ {
 		// 合同服务
 		t := serviceDetail[i]
@@ -255,16 +259,16 @@ func UpdateContractRegisterAndServices(item *ContractRegister, updateCols []stri
 		contractService.Set()
 		tx.Create(contractService)
 
-		// 合同服务详情
-		for j := 0; j < len(t.Detail); j++ {
-			contractServiceDetail := t.Detail[j]
-			contractServiceDetail.ContractServiceId = contractService.ContractServiceId
-			contractServiceDetail.ContractRegisterId = item.ContractRegisterId
-			contractServiceDetail.ServiceTemplateId = contractService.ServiceTemplateId
-			contractServiceDetail.CreateTime = nowTime
-			tx.Create(contractServiceDetail)
-			t.Detail[j] = contractServiceDetail
-		}
+		//// 合同服务详情
+		//for j := 0; j < len(t.Detail); j++ {
+		//	contractServiceDetail := t.Detail[j]
+		//	contractServiceDetail.ContractServiceId = contractService.ContractServiceId
+		//	contractServiceDetail.ContractRegisterId = item.ContractRegisterId
+		//	contractServiceDetail.ServiceTemplateId = contractService.ServiceTemplateId
+		//	contractServiceDetail.CreateTime = nowTime
+		//	tx.Create(contractServiceDetail)
+		//	t.Detail[j] = contractServiceDetail
+		//}
 	}
 	return
 }

+ 16 - 16
models/fms/contract_service.go

@@ -34,11 +34,11 @@ func (c *ContractService) List(condition string, pars []interface{}) (list []*Co
 
 // ContractServiceAddReq 新增合同套餐请求体
 type ContractServiceAddReq struct {
-	ServiceTemplateId  int                             `json:"service_template_id" description:"服务套餐id"`
-	Title              string                          `json:"title" description:"服务套餐名称"`
-	Value              string                          `json:"value" description:"服务套餐内容"`
-	Detail             [][]ContractServiceDetailAddReq `json:"detail" description:"详情数据"`
-	ChartPermissionIds string                          `json:"chart_permission_ids" description:"品种权限"`
+	ServiceTemplateId  int    `json:"service_template_id" description:"服务套餐id"`
+	Title              string `json:"title" description:"服务套餐名称"`
+	Value              string `json:"value" description:"服务套餐内容"`
+	ChartPermissionIds string `json:"chart_permission_ids" description:"品种权限"`
+	//Detail             [][]ContractServiceDetailAddReq `json:"detail" description:"详情数据"`
 }
 
 // ContractServiceItem 合同的服务内容
@@ -57,17 +57,17 @@ type ContractServiceItem struct {
 
 // ContractServiceAndDetail 合同的服务内容及详情
 type ContractServiceAndDetail struct {
-	ContractServiceId  int                      `json:"contract_service_id" description:"合同服务ID"`
-	ContractRegisterId int                      `json:"contract_register_id" description:"合同登记ID"`
-	ProductId          int                      `json:"product_id" description:"产品id,1:ficc;2:权益"`
-	ServiceTemplateId  int                      `json:"service_template_id" description:"合同服务模板id"`
-	Title              string                   `json:"title" description:"套餐标题"`
-	Value              string                   `json:"value" description:"套餐的值"`
-	HasDetail          string                   `json:"has_detail" description:"是否有详情,枚举值:是、否;默认:否"`
-	TableValue         string                   `json:"table_value" description:"表格数据,用于word生成时的json数据"`
-	ChartPermissionId  int                      `json:"chart_permission_id" description:"权限id"`
-	ChartPermissionIds string                   `json:"chart_permission_ids" description:"品种权限-小套餐"`
-	Detail             []*ContractServiceDetail `json:"detail"`
+	ContractServiceId  int    `json:"contract_service_id" description:"合同服务ID"`
+	ContractRegisterId int    `json:"contract_register_id" description:"合同登记ID"`
+	ProductId          int    `json:"product_id" description:"产品id,1:ficc;2:权益"`
+	ServiceTemplateId  int    `json:"service_template_id" description:"合同服务模板id"`
+	Title              string `json:"title" description:"套餐标题"`
+	Value              string `json:"value" description:"套餐的值"`
+	HasDetail          string `json:"has_detail" description:"是否有详情,枚举值:是、否;默认:否"`
+	TableValue         string `json:"table_value" description:"表格数据,用于word生成时的json数据"`
+	ChartPermissionId  int    `json:"chart_permission_id" description:"权限id"`
+	ChartPermissionIds string `json:"chart_permission_ids" description:"品种权限-小套餐"`
+	//Detail             []*ContractServiceDetail `json:"detail"`
 }
 
 // GetContractServiceAndDetailList 根据id获取合同列表数据

+ 2 - 0
routers/contract.go

@@ -19,6 +19,8 @@ func InitContract(rg *gin.RouterGroup) {
 	crGroup.GET("export", cr.Export)
 	crGroup.POST("invoice", cr.Invoice)
 	crGroup.POST("payment", cr.Invoice) // 与开票登记用同一个func, 路由作区分划分权限
+	crGroup.GET("invoice_list", cr.InvoiceList)
+	crGroup.GET("invoice_export", cr.InvoiceExport)
 
 	// 合同套餐
 	sr := new(contract.ServiceController)

+ 1 - 0
routers/crm.go

@@ -12,6 +12,7 @@ func InitCrm(rg *gin.RouterGroup) {
 	crGroup := rg.Group("contract/").Use(middleware.Token())
 	crGroup.GET("search_list", ct.SearchList)
 	crGroup.GET("permission_list", ct.PermissionList)
+	crGroup.GET("service_detail", ct.ServiceDetail)
 
 	// 销售
 	sl := new(crm.CompanySellerController)

+ 244 - 0
services/crm/contract.go

@@ -0,0 +1,244 @@
+package crm
+
+import (
+	"encoding/json"
+	"errors"
+	"fmt"
+	"hongze/fms_api/models/crm"
+	"hongze/fms_api/models/system"
+	"hongze/fms_api/utils"
+	"reflect"
+	"strings"
+)
+
+// GetContractDetail 根据id获取合同详情(包含服务)
+func GetContractDetail(contractId int) (contractDetail *crm.ContractDetail, err error) {
+	contractDetail, err = getContractDetail(contractId)
+	if err != nil {
+		if err == utils.ErrNoRow {
+			err = errors.New("找不到该合同")
+		}
+		return
+	}
+	relationContractDetailList := make([]*crm.ContractDetail, 0)
+
+	switch contractDetail.ContractBusinessType {
+	case "业务合同":
+		tmpList, tmpErr := crm.GetContractRelationListByRelationContractId(contractDetail.ContractId)
+		if tmpErr != nil {
+			err = errors.New("查询业务关联合同异常:" + tmpErr.Error())
+			return
+		}
+
+		// 获取所有关联合同详情
+		for _, relationContract := range tmpList {
+			tmpContractDetail, tmpErr := getContractDetail(relationContract.PaymentOnBehalfContractId)
+			if tmpErr != nil {
+				err = errors.New("查询业务关联合同详情异常:" + tmpErr.Error())
+				return
+			}
+			relationContractDetailList = append(relationContractDetailList, tmpContractDetail)
+		}
+	case "代付合同":
+		tmpList, tmpErr := crm.GetContractRelationListByPaymentOnBehalfContractId(contractDetail.ContractId)
+		if tmpErr != nil {
+			err = errors.New("查询代付关联合同异常:" + tmpErr.Error())
+			return
+		}
+
+		// 获取所有关联合同详情
+		for _, relationContract := range tmpList {
+			tmpContractDetail, tmpErr := getContractDetail(relationContract.ContractId)
+			if tmpErr != nil {
+				err = errors.New("查询业务关联合同详情异常:" + tmpErr.Error())
+				return
+			}
+			relationContractDetailList = append(relationContractDetailList, tmpContractDetail)
+		}
+	}
+	contractDetail.RelationContractDetailList = relationContractDetailList
+	return
+}
+
+// getContractDetail 根据id获取合同详情(包含服务)
+func getContractDetail(contractId int) (contractDetail *crm.ContractDetail, err error) {
+	// 获取合同基础信息详情
+	contractDetail, err = crm.GetContractDetailById(contractId)
+	if err != nil {
+		if err == utils.ErrNoRow {
+			err = errors.New("找不到该合同")
+		}
+		return
+	}
+	// 获取合同服务内容详情
+	serviceList, err := getContractServiceAndDetailList(contractId)
+	if err != nil {
+		err = errors.New(fmt.Sprint("查找合同服务异常", err))
+		return
+	}
+	contractDetail.Service = serviceList
+	return
+}
+
+// getContractServiceAndDetailList 根据合同Id获取服务详情列表
+func getContractServiceAndDetailList(contractId int) (serviceList []*crm.ContractServiceAndDetail, err error) {
+	serviceList, err = crm.GetContractServiceAndDetailList(contractId)
+	if err != nil {
+		err = errors.New(fmt.Sprint("查找合同服务异常", err))
+		return
+	}
+	newLen := len(serviceList)
+	for i := 0; newLen > i; i++ {
+		if serviceList[i].HasDetail == "是" {
+			list, detailErr := crm.GetContractServiceDetailListByServiceId(serviceList[i].ContractServiceId)
+			if detailErr != nil {
+				err = errors.New(fmt.Sprint("查找合同服务详情异常", detailErr))
+				return
+			}
+			for aaa := range list {
+				fmt.Println("list[aaa].Col1", list[aaa].Col1)
+			}
+			serviceList[i].DetailList = list
+		}
+	}
+	return
+}
+
+// GetServicePermissionMap 获取合同服务中的权限id  map
+func GetServicePermissionMap(serviceList []*crm.ContractServiceAndDetail) (checkPermissionIdMap map[int]int, err error) {
+	checkPermissionIdMap = make(map[int]int)
+
+	// 获取品种分类配置
+	sysConf := new(system.SysConfig)
+	confCond := `config_code = ?`
+	confPars := make([]interface{}, 0)
+	confPars = append(confPars, system.ConfigKeyCrmPermissionFiccClassify)
+	confItem, e := sysConf.FetchByCondition(confCond, confPars)
+	if e != nil {
+		err = errors.New("获取品种分类配置失败")
+		return
+	}
+	if confItem.ConfigValue == "" {
+		err = errors.New("FICC品种分类配置为空")
+		return
+	}
+	classifyArr := strings.Split(confItem.ConfigValue, ",")
+	if len(classifyArr) == 0 {
+		err = errors.New("FICC品种分类配置为空")
+		return
+	}
+
+	// 获取已经勾选的的权限
+	for _, contractService := range serviceList {
+		// 看看系统中有没有映射对应的权限,如果有的话,那么直接返回,没有那么可能是特殊服务,需要去遍历
+		if contractService.ChartPermissionId > 0 {
+			checkPermissionIdMap[contractService.ChartPermissionId] = contractService.ChartPermissionId
+			continue
+		}
+		switch contractService.ServiceTemplateId {
+		case 1: //ficc 大套餐
+			for _, v := range classifyArr {
+				//大套餐中 市场策略暂时不作为勾选项
+				if v == "市场策略" {
+					continue
+				}
+				items, tmpErr := crm.GetPermissionLookItems(1, v)
+				if tmpErr != nil {
+					err = tmpErr
+					return
+				}
+				for _, n := range items {
+					checkPermissionIdMap[n.ChartPermissionId] = n.ChartPermissionId
+				}
+			}
+		case 2: //ficc小套餐
+			permissionValues := []string{
+				"FICC周报", "商品双周报+线上电话会讨论会<br/>(由弘则的研究员主持线上讨论)", "数据点评",
+			}
+			chartPermissionIds := make([]int, 0)
+			for _, detail := range contractService.DetailList {
+				var tableCel AddContractServiceDetailReq
+				fmt.Println("detail.Col1", detail.Col1)
+				tmpErr := json.Unmarshal([]byte(detail.Col1), &tableCel)
+				if tmpErr != nil {
+					fmt.Println(111)
+					err = tmpErr
+					return
+				}
+				if strings.Contains(strings.Join(permissionValues, ","), tableCel.Value) {
+					//获取品种列数据
+					var tableCel2 AddContractServiceDetailReq
+					tmpErr := GetProductCelData(*detail, &tableCel2)
+					if tmpErr != nil {
+						err = tmpErr
+						return
+					}
+					for _, serviceId := range tableCel2.ValueId {
+						checkPermissionIdMap[serviceId] = serviceId
+					}
+				}
+			}
+			for k := range checkPermissionIdMap {
+				chartPermissionIds = append(chartPermissionIds, checkPermissionIdMap[k])
+			}
+			contractService.ChartPermissionIds = chartPermissionIds
+		case 4, 5, 6: //权益大套餐
+			permissionFiccClassifyArr := []string{"权益"}
+			for _, v := range permissionFiccClassifyArr {
+				items, tmpErr := crm.GetPermissionLookItems(2, v)
+				if tmpErr != nil {
+					err = tmpErr
+					return
+				}
+				for _, n := range items {
+					//如果是专家行业,那么 结束当前循环,进入下一循环(产品需求:专家行业不在里面)
+					if n.ChartPermissionId == 29 || n.ChartPermissionId == 31 {
+						continue
+					}
+					checkPermissionIdMap[n.ChartPermissionId] = n.ChartPermissionId
+				}
+			}
+		}
+	}
+	return
+}
+
+type AddContractServiceDetailReq struct {
+	CanEdit    bool   `json:"CanEdit" description:"是否可编辑"`
+	Type       string `json:"Type" description:"类型"`
+	Value      string `json:"Value" description:"值"`
+	ValueId    []int  `json:"ValueId" description:"类型"`
+	HeadName   string `json:"HeadName" description:"表头名称"`
+	Tag        string `json:"Tag" description:"表头名称"`
+	RowDisable bool   `json:"RowDisable" description:"该行是否禁用操作"`
+	RowName    string `json:"RowName" description:"该行关联名称"`
+	Name       string `json:"Name" description:"行名称"`
+}
+
+// GetProductCelData 获取品种列数据(因为前端可以随意插入列数据,所以需要根据列名来搜索对应的品种列)
+func GetProductCelData(detail crm.ContractServiceDetail, tableCel *AddContractServiceDetailReq) (err error) {
+	t := reflect.TypeOf(detail)
+	v := reflect.ValueOf(detail)
+	for k := 0; k < t.NumField(); k++ {
+		//获取结构体的参数名
+		tmpName := t.Field(k).Name
+		if strings.Contains(tmpName, "Col") {
+			//获取结构体该参数名的值
+			tmpValue := v.Field(k).String()
+			//如果值不为空的话,那么做下json转换
+			if tmpValue != "" {
+				tmpErr := json.Unmarshal([]byte(tmpValue), tableCel)
+				if tmpErr != nil {
+					fmt.Println(222)
+					err = tmpErr
+					continue
+				}
+				if tableCel.HeadName == "品种" {
+					err = nil
+					return
+				}
+			}
+		}
+	}
+	return
+}

+ 109 - 110
services/fms/contract_register.go

@@ -1,7 +1,6 @@
 package fms
 
 import (
-	"encoding/json"
 	"errors"
 	"fmt"
 	"github.com/shopspring/decimal"
@@ -38,7 +37,7 @@ func CheckContractRegisterAmount(registerId int) {
 	invoicePars := make([]interface{}, 0)
 	invoicePars = append(invoicePars, registerId)
 	ci := new(fms.ContractInvoice)
-	invoiceList, e := ci.List(invoiceCond, invoicePars)
+	invoiceList, e := ci.List(invoiceCond, invoicePars, "")
 	if e != nil {
 		err = errors.New("获取开票到款信息失败, Err: " + e.Error())
 		return
@@ -83,102 +82,102 @@ func HandleContractServiceAndDetail(productId int, serviceList []fms.ContractSer
 	}
 	for i := 0; i < len(serviceList); i++ {
 		item := serviceList[i]
-		detail := item.Detail
-
-		detailList := make([]*fms.ContractServiceDetail, 0)
-		if len(detail) > 0 {
-			for j := 0; j < len(detail); j++ {
-				detailItem := detail[j]
-				cellMap := make(map[string]string)
-				for k := 0; k < len(detailItem); k++ {
-					key := fmt.Sprint("cell_", k+1)
-					v, e := json.Marshal(detailItem[k])
-					if e != nil {
-						err = errors.New(fmt.Sprint("json转换失败:", e))
-						return
-					}
-					cellMap[key] = string(v)
-				}
-				contractServiceDetail := &fms.ContractServiceDetail{
-					Col1: func(cellMap map[string]string) string {
-						v, ok := cellMap["cell_1"]
-						if ok {
-							return v
-						} else {
-							return ""
-						}
-					}(cellMap),
-					Col2: func(cellMap map[string]string) string {
-						v, ok := cellMap["cell_2"]
-						if ok {
-							return v
-						} else {
-							return ""
-						}
-					}(cellMap),
-					Col3: func(cellMap map[string]string) string {
-						v, ok := cellMap["cell_3"]
-						if ok {
-							return v
-						} else {
-							return ""
-						}
-					}(cellMap),
-					Col4: func(cellMap map[string]string) string {
-						v, ok := cellMap["cell_4"]
-						if ok {
-							return v
-						} else {
-							return ""
-						}
-					}(cellMap),
-					Col5: func(cellMap map[string]string) string {
-						v, ok := cellMap["cell_5"]
-						if ok {
-							return v
-						} else {
-							return ""
-						}
-					}(cellMap),
-					Col6: func(cellMap map[string]string) string {
-						v, ok := cellMap["cell_6"]
-						if ok {
-							return v
-						} else {
-							return ""
-						}
-					}(cellMap),
-					Col7: func(cellMap map[string]string) string {
-						v, ok := cellMap["cell_7"]
-						if ok {
-							return v
-						} else {
-							return ""
-						}
-					}(cellMap),
-					ServiceTemplateId: item.ServiceTemplateId,
-					CreateTime:        time.Now(),
-				}
-				detailList = append(detailList, contractServiceDetail)
-			}
-		}
+		//detail := item.Detail
+		//
+		//detailList := make([]*fms.ContractServiceDetail, 0)
+		//if len(detail) > 0 {
+		//	for j := 0; j < len(detail); j++ {
+		//		detailItem := detail[j]
+		//		cellMap := make(map[string]string)
+		//		for k := 0; k < len(detailItem); k++ {
+		//			key := fmt.Sprint("cell_", k+1)
+		//			v, e := json.Marshal(detailItem[k])
+		//			if e != nil {
+		//				err = errors.New(fmt.Sprint("json转换失败:", e))
+		//				return
+		//			}
+		//			cellMap[key] = string(v)
+		//		}
+		//		contractServiceDetail := &fms.ContractServiceDetail{
+		//			Col1: func(cellMap map[string]string) string {
+		//				v, ok := cellMap["cell_1"]
+		//				if ok {
+		//					return v
+		//				} else {
+		//					return ""
+		//				}
+		//			}(cellMap),
+		//			Col2: func(cellMap map[string]string) string {
+		//				v, ok := cellMap["cell_2"]
+		//				if ok {
+		//					return v
+		//				} else {
+		//					return ""
+		//				}
+		//			}(cellMap),
+		//			Col3: func(cellMap map[string]string) string {
+		//				v, ok := cellMap["cell_3"]
+		//				if ok {
+		//					return v
+		//				} else {
+		//					return ""
+		//				}
+		//			}(cellMap),
+		//			Col4: func(cellMap map[string]string) string {
+		//				v, ok := cellMap["cell_4"]
+		//				if ok {
+		//					return v
+		//				} else {
+		//					return ""
+		//				}
+		//			}(cellMap),
+		//			Col5: func(cellMap map[string]string) string {
+		//				v, ok := cellMap["cell_5"]
+		//				if ok {
+		//					return v
+		//				} else {
+		//					return ""
+		//				}
+		//			}(cellMap),
+		//			Col6: func(cellMap map[string]string) string {
+		//				v, ok := cellMap["cell_6"]
+		//				if ok {
+		//					return v
+		//				} else {
+		//					return ""
+		//				}
+		//			}(cellMap),
+		//			Col7: func(cellMap map[string]string) string {
+		//				v, ok := cellMap["cell_7"]
+		//				if ok {
+		//					return v
+		//				} else {
+		//					return ""
+		//				}
+		//			}(cellMap),
+		//			ServiceTemplateId: item.ServiceTemplateId,
+		//			CreateTime:        time.Now(),
+		//		}
+		//		detailList = append(detailList, contractServiceDetail)
+		//	}
+		//}
 		hasDetail := "否"
-		if len(detailList) > 0 {
-			hasDetail = "是"
-		}
-		// 报价单图片地址
-		newValue := item.Value
-		if base642Image {
-			b, _ := regexp.MatchString(`^data:\s*image\/(\w+);base64,`, newValue)
-			if b {
-				imageUrl, e := UploadImageBase64(newValue)
-				if e != nil {
-					err = errors.New(fmt.Sprint("base64图片上传失败:", e))
-					return
-				}
-				newValue = imageUrl
-			}
-		}
+		//if len(detailList) > 0 {
+		//	hasDetail = "是"
+		//}
+		//// 报价单图片地址
+		//newValue := item.Value
+		//if base642Image {
+		//	b, _ := regexp.MatchString(`^data:\s*image\/(\w+);base64,`, newValue)
+		//	if b {
+		//		imageUrl, e := UploadImageBase64(newValue)
+		//		if e != nil {
+		//			err = errors.New(fmt.Sprint("base64图片上传失败:", e))
+		//			return
+		//		}
+		//		newValue = imageUrl
+		//	}
+		//}
 
 		// 合同模板
 		serviceTemp, e := fms.GetContractServiceTemplateById(item.ServiceTemplateId)
@@ -189,13 +188,13 @@ func HandleContractServiceAndDetail(productId int, serviceList []fms.ContractSer
 		serviceDetail := &fms.ContractServiceAndDetail{
 			ServiceTemplateId:  item.ServiceTemplateId,
 			Title:              item.Title,
-			Value:              newValue,
+			Value:              item.Value,
 			ProductId:          productId,
 			HasDetail:          hasDetail,
 			TableValue:         serviceTemp.TableValue,
-			Detail:             detailList,
 			ChartPermissionId:  serviceTemp.ChartPermissionId,
 			ChartPermissionIds: item.ChartPermissionIds,
+			//Detail:             detailList,
 		}
 		serviceDetailList = append(serviceDetailList, serviceDetail)
 	}
@@ -210,17 +209,17 @@ func GetContractServiceAndDetail(contractRegisterId int) (serviceList []*fms.Con
 		return
 	}
 	serviceList = list
-	newLen := len(serviceList)
-	for i := 0; newLen > i; i++ {
-		if serviceList[i].HasDetail == "是" {
-			detail, e := fms.GetContractServiceDetailByServiceId(serviceList[i].ContractServiceId)
-			if e != nil {
-				err = errors.New(fmt.Sprint("查找合同服务详情异常", e))
-				return
-			}
-			serviceList[i].Detail = detail
-		}
-	}
+	//newLen := len(serviceList)
+	//for i := 0; newLen > i; i++ {
+	//	if serviceList[i].HasDetail == "是" {
+	//		detail, e := fms.GetContractServiceDetailByServiceId(serviceList[i].ContractServiceId)
+	//		if e != nil {
+	//			err = errors.New(fmt.Sprint("查找合同服务详情异常", e))
+	//			return
+	//		}
+	//		serviceList[i].Detail = detail
+	//	}
+	//}
 	return
 }
 

+ 22 - 0
utils/common.go

@@ -1050,4 +1050,26 @@ func JoinStr2IntArr(str, sep string) (arr []int) {
 		arr = append(arr, v)
 	}
 	return
+}
+
+// InArrayByInt php中的in_array(判断Int类型的切片中是否存在该int值)
+func InArrayByInt(idIntList []int, searchId int) (has bool) {
+	for _, id := range idIntList {
+		if id == searchId {
+			has = true
+			return
+		}
+	}
+	return
+}
+
+// InArrayByStr php中的in_array(判断String类型的切片中是否存在该string值)
+func InArrayByStr(idStrList []string, searchId string) (has bool) {
+	for _, id := range idStrList {
+		if id == searchId {
+			has = true
+			return
+		}
+	}
+	return
 }