浏览代码

Merge branch 'fms_2.6' into 2.8

# Conflicts:
#	controller/census/invoice_payment.go
ziwen 1 年之前
父节点
当前提交
5a5a99d3e5
共有 4 个文件被更改,包括 3440 次插入11 次删除
  1. 3270 0
      controller/census/invoice_payment.go
  2. 55 10
      models/fms/contract_invoice.go
  3. 112 1
      models/fms/invoice_payment_summary.go
  4. 3 0
      routers/census.go

+ 3270 - 0
controller/census/invoice_payment.go

@@ -1,2 +1,3272 @@
 package census
 
+import (
+	"bytes"
+	"fmt"
+	"github.com/gin-gonic/gin"
+	"github.com/go-playground/validator/v10"
+	"github.com/tealeg/xlsx"
+	"hongze/fms_api/controller/resp"
+	"hongze/fms_api/global"
+	"hongze/fms_api/models"
+	"hongze/fms_api/models/base"
+	"hongze/fms_api/models/crm"
+	"hongze/fms_api/models/fms"
+	"hongze/fms_api/services/alarm_msg"
+	crmService "hongze/fms_api/services/crm"
+	fmsService "hongze/fms_api/services/fms"
+	"hongze/fms_api/utils"
+	"net/http"
+	"sort"
+	"strconv"
+	"strings"
+	"sync"
+	"time"
+)
+
+// InvoicePaymentController 商品到款统计
+type InvoicePaymentController struct{}
+
+// List2 原版(已废弃)
+//func (ct *InvoicePaymentController) List2(c *gin.Context) {
+//	var req fms.InvoicePaymentCensusListReq
+//	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 := `1 = 1`
+//	pars := make([]interface{}, 0)
+//	// 合同编号/客户姓名/销售
+//	if req.Keyword != "" {
+//		kw := "%" + req.Keyword + "%"
+//		cond += ` AND b.company_name LIKE ? OR a.seller_name LIKE ?`
+//		pars = append(pars, kw, kw)
+//	}
+//	if req.SellGroupId > 0 {
+//		cond += ` AND a.seller_group_id = ?`
+//		pars = append(pars, req.SellGroupId)
+//	}
+//	// 套餐筛选
+//	if req.ServiceType != 0 {
+//		registerIds, e := fms.GetContractRegisterIdsByTempId(req.ServiceType)
+//		if e != nil {
+//			resp.FailMsg("获取失败", "获取合同登记IDs失败, Err: "+e.Error(), c)
+//			return
+//		}
+//		if len(registerIds) > 0 {
+//			cond += ` AND b.contract_register_id IN ?`
+//			pars = append(pars, registerIds)
+//		} else {
+//			cond += ` AND 1 = 2`
+//		}
+//	}
+//	// 开票到款日期
+//	if req.TimeType > 0 && req.StartDate != "" && req.EndDate != "" {
+//		st := fmt.Sprint(req.StartDate, " 00:00:00")
+//		ed := fmt.Sprint(req.EndDate, " 23:59:59")
+//		cond += ` AND a.invoice_type = ? AND (a.invoice_time BETWEEN ? AND ?)`
+//		pars = append(pars, req.TimeType, st, ed)
+//	}
+//	// 已开票
+//	if req.HasInvoice == 1 && req.HasPayment == 0 {
+//		cond += ` AND a.invoice_type = 1`
+//	}
+//	// 已到款
+//	if req.HasInvoice == 0 && req.HasPayment == 1 {
+//		cond += ` AND a.invoice_type = 2`
+//	}
+//
+//	page := new(base.Page)
+//	page.SetPageSize(req.PageSize)
+//	page.SetCurrent(req.Current)
+//	page.AddOrderItem(base.OrderItem{Column: "a.create_time", Asc: false})
+//	page.AddOrderItem(base.OrderItem{Column: "b.contract_register_id", Asc: true})
+//	if req.IsExport == 1 {
+//		page.SetPageSize(10000)
+//		page.SetCurrent(1)
+//	}
+//
+//	list, allRegisterIds, e := fms.GetInvoicePaymentCensusPageList(page, cond, pars)
+//	if e != nil {
+//		resp.FailMsg("获取失败", "获取商品到款统计列表失败, Err: "+e.Error(), c)
+//		return
+//	}
+//	total := int64(len(allRegisterIds))
+//	registerIds := make([]int, 0)
+//	for i := range list {
+//		registerIds = append(registerIds, list[i].ContractRegisterId)
+//	}
+//
+//	results := new(fms.InvoicePaymentCensusResp)
+//	if len(registerIds) > 0 {
+//		// 获取开票到款列表
+//		ivCond := `contract_register_id IN ?`
+//		ivPars := make([]interface{}, 0)
+//		ivPars = append(ivPars, registerIds)
+//		iv := new(fms.ContractInvoice)
+//		invoiceList, e := iv.List(ivCond, ivPars, "")
+//		if e != nil {
+//			resp.FailMsg("获取失败", "获取开票到款列表失败, Err: "+e.Error(), c)
+//			return
+//		}
+//		// 取出开票、到款
+//		invoiceMap := make(map[int][]*fms.ContractInvoice, 0)
+//		paymentMap := make(map[int][]*fms.ContractInvoice, 0)
+//		paymentIds := make([]int, 0)
+//		for i := range invoiceList {
+//			if invoiceMap[invoiceList[i].ContractRegisterId] == nil {
+//				invoiceMap[invoiceList[i].ContractRegisterId] = make([]*fms.ContractInvoice, 0)
+//			}
+//			if paymentMap[invoiceList[i].ContractRegisterId] == nil {
+//				paymentMap[invoiceList[i].ContractRegisterId] = make([]*fms.ContractInvoice, 0)
+//			}
+//			if invoiceList[i].InvoiceType == fms.ContractInvoiceTypeMake {
+//				invoiceMap[invoiceList[i].ContractRegisterId] = append(invoiceMap[invoiceList[i].ContractRegisterId], invoiceList[i])
+//			}
+//			if invoiceList[i].InvoiceType == fms.ContractInvoiceTypePay {
+//				paymentMap[invoiceList[i].ContractRegisterId] = append(paymentMap[invoiceList[i].ContractRegisterId], invoiceList[i])
+//				paymentIds = append(paymentIds, invoiceList[i].ContractInvoiceId)
+//			}
+//		}
+//
+//		// 合同套餐
+//		contractServiceCond := `contract_register_id IN ?`
+//		contractServicePars := make([]interface{}, 0)
+//		contractServicePars = append(contractServicePars, registerIds)
+//		contractServiceOB := new(fms.ContractService)
+//		contractServiceList, e := contractServiceOB.List(contractServiceCond, contractServicePars)
+//		if e != nil {
+//			resp.FailMsg("获取失败", "获取合同套餐列表失败, Err:"+e.Error(), c)
+//			return
+//		}
+//		contractServiceMap := make(map[int][]*fms.ContractService, 0)
+//		servicesNameMap := make(map[int][]string, 0)
+//		for i := range contractServiceList {
+//			if contractServiceMap[contractServiceList[i].ContractRegisterId] == nil {
+//				contractServiceMap[contractServiceList[i].ContractRegisterId] = make([]*fms.ContractService, 0)
+//			}
+//			contractServiceMap[contractServiceList[i].ContractRegisterId] = append(contractServiceMap[contractServiceList[i].ContractRegisterId], contractServiceList[i])
+//			servicesNameMap[contractServiceList[i].ContractRegisterId] = append(servicesNameMap[contractServiceList[i].ContractRegisterId], contractServiceList[i].Title)
+//		}
+//
+//		// 到款套餐分配
+//		serviceAmountMap := make(map[int][]*fms.ContractPaymentServiceAmount, 0)
+//		if len(paymentIds) > 0 {
+//			serviceAmountCond := `contract_payment_id IN ?`
+//			serviceAmountPars := make([]interface{}, 0)
+//			serviceAmountPars = append(serviceAmountPars, paymentIds)
+//			serviceAmountOB := new(fms.ContractPaymentServiceAmount)
+//			serviceAmountList, e := serviceAmountOB.List(serviceAmountCond, serviceAmountPars)
+//			if e != nil {
+//				resp.FailMsg("获取失败", "获取到款套餐分配列表失败, Err:"+e.Error(), c)
+//				return
+//			}
+//			for i := range serviceAmountList {
+//				if serviceAmountMap[serviceAmountList[i].ContractRegisterId] == nil {
+//					serviceAmountMap[serviceAmountList[i].ContractRegisterId] = make([]*fms.ContractPaymentServiceAmount, 0)
+//				}
+//				serviceAmountMap[serviceAmountList[i].ContractRegisterId] = append(serviceAmountMap[serviceAmountList[i].ContractRegisterId], serviceAmountList[i])
+//			}
+//		}
+//
+//		// 整合响应数据
+//		respList := make([]*fms.InvoicePaymentCensusItem, 0)
+//		for i := range list {
+//			v := new(fms.InvoicePaymentCensusItem)
+//			v.ContractRegisterId = list[i].ContractRegisterId
+//			v.CompanyName = list[i].CompanyName
+//			v.NewCompany = list[i].NewCompany
+//			v.StartDate = list[i].StartDate.Format(utils.FormatDate)
+//			v.EndDate = list[i].EndDate.Format(utils.FormatDate)
+//			svList := servicesNameMap[list[i].ContractRegisterId]
+//			v.ServicesName = strings.Join(svList, ",")
+//			// 格式化(合并)开票到款数据
+//			v.InvoicePaymentList = fmsService.MergeInvoiceList2InvoicePaymentCensusInfo(invoiceMap[list[i].ContractRegisterId], paymentMap[list[i].ContractRegisterId],
+//				contractServiceMap[list[i].ContractRegisterId], serviceAmountMap[list[i].ContractRegisterId])
+//			respList = append(respList, v)
+//		}
+//
+//		// 开票到款金额合计(换算后)
+//		amountTotalCond := `contract_register_id IN ?`
+//		amountTotalPars := make([]interface{}, 0)
+//		amountTotalPars = append(amountTotalPars, allRegisterIds)
+//		amountTotalList, e := fms.GetContractInvoiceAmountTotal(amountTotalCond, amountTotalPars)
+//		if e != nil {
+//			resp.FailMsg("获取失败", "获取开票到款金额合计失败, Err:"+e.Error(), c)
+//			return
+//		}
+//		amountTotalMap := make(map[int]float64)
+//		for i := range amountTotalList {
+//			amountTotalMap[amountTotalList[i].InvoiceType] = amountTotalList[i].TotalAmount
+//		}
+//		invoiceTotal, _ := strconv.ParseFloat(fmt.Sprintf("%.2f", amountTotalMap[fms.ContractInvoiceTypeMake]), 64)
+//		paymentTotal, _ := strconv.ParseFloat(fmt.Sprintf("%.2f", amountTotalMap[fms.ContractInvoiceTypePay]), 64)
+//
+//		// 分币种金额统计
+//		currencyOB := new(fms.CurrencyUnit)
+//		currencyCond := `enable = 1`
+//		currencyPars := make([]interface{}, 0)
+//		currencyList, e := currencyOB.List(currencyCond, currencyPars)
+//		if e != nil {
+//			resp.FailMsg("获取失败", "获取货币列表失败, Err: "+e.Error(), c)
+//			return
+//		}
+//		unitMap := make(map[string]string)
+//		invoiceCurrencyTotals := make([]*fms.InvoiceListCurrencyTotal, 0)
+//		paymentCurrencyTotals := make([]*fms.InvoiceListCurrencyTotal, 0)
+//		for i := range currencyList {
+//			unitMap[currencyList[i].Code] = currencyList[i].UnitName
+//			invoiceCurrencyTotals = append(invoiceCurrencyTotals, &fms.InvoiceListCurrencyTotal{
+//				Name:     currencyList[i].Name,
+//				UnitName: currencyList[i].UnitName,
+//				Code:     currencyList[i].Code,
+//				FlagImg:  currencyList[i].FlagImg,
+//			})
+//			paymentCurrencyTotals = append(paymentCurrencyTotals, &fms.InvoiceListCurrencyTotal{
+//				Name:     currencyList[i].Name,
+//				UnitName: currencyList[i].UnitName,
+//				Code:     currencyList[i].Code,
+//				FlagImg:  currencyList[i].FlagImg,
+//			})
+//		}
+//		sumList, e := fms.GetInvoiceListCurrencySum(amountTotalCond, amountTotalPars, "currency_unit, invoice_type")
+//		if e != nil {
+//			resp.FailMsg("获取失败", "获取商品到款统计货币合计金额失败, Err: "+e.Error(), c)
+//			return
+//		}
+//		invoiceSumMap := make(map[string]float64)
+//		paymentSumMap := make(map[string]float64)
+//		for i := range sumList {
+//			if sumList[i].InvoiceType == fms.ContractInvoiceTypeMake {
+//				invoiceSumMap[sumList[i].CurrencyUnit] = sumList[i].OriginAmountTotal
+//				continue
+//			}
+//			if sumList[i].InvoiceType == fms.ContractInvoiceTypePay {
+//				paymentSumMap[sumList[i].CurrencyUnit] = sumList[i].OriginAmountTotal
+//			}
+//		}
+//		for i := range invoiceCurrencyTotals {
+//			a, _ := strconv.ParseFloat(fmt.Sprintf("%.2f", invoiceSumMap[invoiceCurrencyTotals[i].Code]), 64)
+//			invoiceCurrencyTotals[i].Amount = a
+//		}
+//		for i := range paymentCurrencyTotals {
+//			a, _ := strconv.ParseFloat(fmt.Sprintf("%.2f", paymentSumMap[paymentCurrencyTotals[i].Code]), 64)
+//			paymentCurrencyTotals[i].Amount = a
+//		}
+//
+//		results.DataList = respList
+//		results.InvoiceTotal = invoiceTotal
+//		results.PaymentTotal = paymentTotal
+//		results.InvoiceCurrencyTotal = invoiceCurrencyTotals
+//		results.PaymentCurrencyTotal = paymentCurrencyTotals
+//	}
+//
+//	// 是否导出
+//	if req.IsExport == 1 {
+//		ExportInvoicePaymentCensusList(c, results)
+//		return
+//	}
+//	page.SetTotal(total)
+//	baseData := new(base.BaseData)
+//	baseData.SetPage(page)
+//	baseData.SetList(results)
+//	resp.OkData("获取成功", baseData, c)
+//}
+
+// ExportInvoicePaymentCensusList 导出商品到款统计列表
+func ExportInvoicePaymentCensusList(c *gin.Context, results *fms.InvoicePaymentCensusResp) {
+	list := results.DataList
+	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
+	}
+	_ = sheet.SetColWidth(1, 1, 30)
+	_ = sheet.SetColWidth(3, 3, 30)
+
+	// 前三行-开票金额合计
+	rowA := sheet.AddRow()
+	cellAA := rowA.AddCell()
+	cellAA.SetString(fmt.Sprintf("已开票合计金额(换算后):%.2f(元)", results.InvoiceTotal))
+	rowBData := "已开票金额:"
+	for _, v := range results.InvoiceCurrencyTotal {
+		rowBData += fmt.Sprintf("%s%.2f(%s)  ", v.Name, v.Amount, v.UnitName)
+	}
+	rowB := sheet.AddRow()
+	rowB.AddCell().SetString(rowBData)
+	sheet.AddRow()
+
+	// 四至六-到款金额合计
+	rowD := sheet.AddRow()
+	cellDA := rowD.AddCell()
+	cellDA.SetString(fmt.Sprintf("已到款合计金额(换算后):%.2f(元)", results.PaymentTotal))
+	rowEData := "已到款金额:"
+	for _, v := range results.PaymentCurrencyTotal {
+		rowEData += fmt.Sprintf("%s%.2f(%s)  ", v.Name, v.Amount, v.UnitName)
+	}
+	rowE := sheet.AddRow()
+	rowE.AddCell().SetString(rowEData)
+	sheet.AddRow()
+
+	// 表头, 套餐动态获取
+	rowTitle := []string{"序号", "客户名称", "是否新客户", "合同有效期", "开票日", "开票金额", "到款日", "到款金额", "付款方式", "销售",
+		"销售组别", "销售类型"}
+	serviceTempCond := ``
+	serviceTempPars := make([]interface{}, 0)
+	serviceTempOB := new(fms.ContractServiceTemplate)
+	serviceTempList, e := serviceTempOB.List(serviceTempCond, serviceTempPars)
+	if e != nil {
+		resp.FailData("获取套餐模板列表失败", "Err:"+e.Error(), c)
+		return
+	}
+	serviceTempListMap := make(map[int]*fms.ContractServiceTemplate)
+	var serviceTempShow []*fms.ContractServiceTemplate
+	for i := range serviceTempList {
+		serviceTempListMap[serviceTempList[i].ServiceTemplateId] = serviceTempList[i]
+	}
+	for i := range serviceTempList {
+		if serviceTempList[i].ProductId == 1 {
+			rowTitle = append(rowTitle, serviceTempList[i].Title)
+			serviceTempShow = append(serviceTempShow, serviceTempList[i])
+		} else if serviceTempList[i].ProductId == 2 {
+			if serviceTempList[i].Title == "行业套餐" || serviceTempList[i].Title == "权益大套餐" || (serviceTempList[i].Title == "策略" && serviceTempListMap[serviceTempList[i].Pid].Pid == 0) {
+			} else if serviceTempList[i].Title == "医药" || serviceTempList[i].Title == "消费" || serviceTempList[i].Title == "科技" || serviceTempList[i].Title == "智造" {
+			} else {
+				serviceTempShow = append(serviceTempShow, serviceTempList[i])
+			}
+			if serviceTempList[i].Title == "行业套餐" || serviceTempList[i].Title == "45万" || serviceTempList[i].Title == "70万" {
+				continue
+			}
+
+			if serviceTempList[i].Pid > 0 && serviceTempListMap[serviceTempList[i].Pid].Pid > 0 {
+				continue
+			}
+
+			rowTitle = append(rowTitle, serviceTempList[i].Title)
+		}
+	}
+
+	hi := 0
+	insertHi := 0
+	titleRow := sheet.AddRow()
+	for i := range rowTitle {
+		v := titleRow.AddCell()
+		v.SetString(rowTitle[i])
+		v.SetStyle(style)
+		if rowTitle[i] != "权益大套餐" && rowTitle[i] != "医药" && rowTitle[i] != "消费" && rowTitle[i] != "科技" && rowTitle[i] != "智造" {
+			v.VMerge = 1
+			hi++
+		} else {
+			if insertHi == 0 {
+				insertHi = hi
+			}
+			v.HMerge = 1
+			titleRow.AddCell().SetString("")
+		}
+	}
+
+	// 新增一行放主观和客观
+	specialRow := sheet.AddRow()
+	for i := 0; i < hi; i++ {
+		if i == insertHi {
+			v1 := specialRow.AddCell()
+			v1.SetString("45万")
+			v1.SetStyle(style)
+			v1 = specialRow.AddCell()
+			v1.SetString("70万")
+			v1.SetStyle(style)
+			for j := 0; j < 8; j++ {
+				if j%2 == 0 {
+					v1 = specialRow.AddCell()
+					v1.SetString("主观")
+					v1.SetStyle(style)
+				} else {
+					v1 = specialRow.AddCell()
+					v1.SetString("客观")
+					v1.SetStyle(style)
+				}
+			}
+		} else {
+			v := specialRow.AddCell()
+			v.SetString("")
+		}
+	}
+
+	newCompanyMap := map[int]string{0: "/", 1: "是", 2: "否"}
+	sellerTypeMap := map[int]string{1: "FICC销售", 2: "权益销售"}
+	for k, v := range list {
+		dataRow := sheet.AddRow()
+		// 前四个单元格根据每行开票到款条数向下合并
+		l := len(v.InvoicePaymentList)
+		mergeRowNum := l - 1
+		// 序号
+		sortNum := k + 1
+		colA := dataRow.AddCell()
+		colA.VMerge = mergeRowNum
+		colA.SetString(fmt.Sprint(sortNum))
+		// 客户名称
+		colB := dataRow.AddCell()
+		colB.VMerge = mergeRowNum
+		colB.SetString(v.CompanyName)
+		// 是否新客户
+		colC := dataRow.AddCell()
+		colC.VMerge = mergeRowNum
+		colC.SetString(newCompanyMap[v.ContractType])
+		// 合同有效期
+		colD := dataRow.AddCell()
+		colD.VMerge = mergeRowNum
+		colD.SetString(fmt.Sprint(v.StartDate, "至", v.EndDate))
+		// 开票到款信息
+		for k2, v2 := range v.InvoicePaymentList {
+			rowData := []string{
+				v2.InvoiceDate,                                // 开票日
+				fmt.Sprint(v2.InvoiceAmount),                  // 开票金额
+				v2.PaymentDate,                                // 到款日
+				fmt.Sprint(v2.PaymentAmount),                  // 到款金额
+				fms.ContractPaymentPayTypeNameMap[v2.PayType], // 付款方式
+				v2.SellerName,                                 // 销售
+				v2.SellerGroupName,                            // 组别
+				sellerTypeMap[v2.SellerType],                  // 销售类型
+			}
+			// 套餐金额信息
+			serviceTempShowAmount := make(map[int]string)
+			for i := range serviceTempShow {
+				for s2 := range v2.ServiceAmountList {
+					item := v2.ServiceAmountList[s2]
+					if item.ServiceTemplateId == serviceTempShow[i].ServiceTemplateId {
+						serviceTempShowAmount[serviceTempShow[i].ServiceTemplateId] = fmt.Sprint(item.Amount)
+						break
+					} else if serviceTempShow[i].Pid == item.ServiceTemplateId {
+						serviceTempShowAmount[serviceTempShow[i].ServiceTemplateId] = fmt.Sprint(item.Amount / 2)
+						break
+					}
+				}
+			}
+			for i := range serviceTempShow {
+				sa := ""
+				if am, ok := serviceTempShowAmount[serviceTempShow[i].ServiceTemplateId]; ok {
+					sa = am
+				}
+				rowData = append(rowData, sa)
+			}
+			// 首行开票到款
+			if k2 == 0 {
+				for i := range rowData {
+					dataRow.AddCell().SetString(rowData[i])
+				}
+				continue
+			}
+			// 其他行开票到款, 加四列空的单元格用于合并
+			dataRowExtra := sheet.AddRow()
+			for i := 0; i < 4; i++ {
+				dataRowExtra.AddCell()
+			}
+			for i := range rowData {
+				dataRowExtra.AddCell().SetString(rowData[i])
+			}
+		}
+	}
+
+	// 输出文件
+	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)
+}
+
+// List
+// @Title 商品到款统计列表
+// @Description 商品到款统计列表
+// @Param   Keyword			query	string	false	"关键词"
+// @Param   SellGroupId		query	int		false	"销售组别ID"
+// @Param   ServiceType		query	int		false	"套餐类型"
+// @Param   StartDate		query	string	false	"合同开始日期"
+// @Param   EndDate			query	string	false	"合同结束日期"
+// @Param   TimeType		query	int		false	"时间类型: 1-开票时间; 2-到款时间"
+// @Param   HasInvoice		query	string		false	"是否已开票: 0-否; 1-是; 空-全部"
+// @Param   HasPayment		query	string		false	"是否已到款: 0-否; 1-是; 空-全部"
+// @Param   IsExport		query	int		false	"是否导出: 0-否; 1-是"
+// @Param   ListParam		query	int		false	"套餐类型: 0-全部; 1-ficc; 2-权益"
+// @Param   SortParam       query   string  false      "排序字段参数,用来排序的字段, 枚举值:'invoice_time':开票日 、 'payment_date':到款日"
+// @Param   SortType        query   string  true       "如何排序,是正序还是倒序,枚举值:`asc 正序`,`desc 倒叙`"
+// @Success 200 {object} fms.ContractRegisterItem
+// @router /census/invoice_payment/list [get]
+func (ct *InvoicePaymentController) List(c *gin.Context) {
+	var req fms.InvoicePaymentCensusListReq
+	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 := `1 = 1`
+	pars := make([]interface{}, 0)
+	// 客户姓名/销售
+	if req.Keyword != "" {
+		kw := "%" + req.Keyword + "%"
+		cond += ` AND b.company_name LIKE ?`
+		pars = append(pars, kw)
+	}
+	if req.SellerIds != "" {
+		sellerIds := strings.Split(req.SellerIds, ",")
+		cond += ` AND (c.seller_id in ? OR d.seller_id in ?)`
+		pars = append(pars, sellerIds, sellerIds)
+	}
+	// 套餐筛选
+	if req.ServiceTypes != "" {
+		serviceTypes := strings.Split(req.ServiceTypes, ",")
+		tempRegisterIds, e := fms.GetContractRegisterIdsByTempId(serviceTypes)
+		if e != nil {
+			resp.FailMsg("获取失败", "获取合同登记IDs失败, Err: "+e.Error(), c)
+			return
+		}
+		if len(tempRegisterIds) > 0 {
+			cond += ` AND a.register_id IN ?`
+			pars = append(pars, tempRegisterIds)
+		} else {
+			cond += ` AND 1 = 2`
+		}
+	}
+
+	if req.ListParam == 1 {
+		cond += ` AND a.service_product_id = 1 `
+	} else if req.ListParam == 2 {
+		cond += ` AND a.service_product_id = 2 `
+	}
+
+	// 开票到款日期
+	if req.TimeType != 0 {
+		if req.TimeType == 1 && req.StartDate != "" && req.EndDate != "" {
+			st := fmt.Sprint(req.StartDate, " 00:00:00")
+			ed := fmt.Sprint(req.EndDate, " 23:59:59")
+			cond += ` AND (c.invoice_time BETWEEN ? AND ?) `
+			pars = append(pars, st, ed)
+		} else if req.TimeType == 2 && req.StartDate != "" && req.EndDate != "" {
+			st := fmt.Sprint(req.StartDate, " 00:00:00")
+			ed := fmt.Sprint(req.EndDate, " 23:59:59")
+			cond += ` AND (d.invoice_time BETWEEN ? AND ?) `
+			pars = append(pars, st, ed)
+		} else if req.TimeType == 3 && req.StartDate != "" && req.EndDate != "" {
+			st := fmt.Sprint(req.StartDate, " 00:00:00")
+			ed := fmt.Sprint(req.EndDate, " 23:59:59")
+			cond += ` AND (c.invoice_time BETWEEN ? AND ?) AND (d.invoice_time BETWEEN ? AND ?) `
+			pars = append(pars, st, ed, st, ed)
+		}
+	} else if req.StartDate != "" && req.EndDate != "" {
+		st := fmt.Sprint(req.StartDate, " 00:00:00")
+		ed := fmt.Sprint(req.EndDate, " 23:59:59")
+		if req.SellerIds != "" {
+			sellerIds := strings.Split(req.SellerIds, ",")
+			cond += ` AND (c.seller_id in ? OR d.seller_id in ?)`
+			pars = append(pars, sellerIds, sellerIds)
+			cond += ` AND ((c.seller_id in ? AND a.invoice_id <> 0 AND c.invoice_time BETWEEN ? AND ?)`
+			cond += `OR (d.seller_id in ? AND a.payment_id <> 0 AND a.invoice_id = 0 AND d.invoice_time BETWEEN ? AND ?))`
+			pars = append(pars, sellerIds, st, ed, sellerIds, st, ed)
+		} else {
+			cond += ` AND ((a.invoice_id <> 0 AND c.invoice_time BETWEEN ? AND ?)`
+			cond += `OR (a.payment_id <> 0 AND a.invoice_id = 0 AND d.invoice_time BETWEEN ? AND ?))`
+			pars = append(pars, st, ed, st, ed)
+		}
+	}
+
+	if req.HasInvoice == "1" {
+		cond += ` AND a.invoice_id > 0 `
+	} else if req.HasInvoice == "0" {
+		cond += ` AND a.invoice_id = 0 `
+	}
+
+	if req.HasPayment == "1" {
+		cond += ` AND a.payment_id > 0 `
+	} else if req.HasPayment == "0" {
+		cond += ` AND a.payment_id = 0 `
+	}
+
+	page := new(base.Page)
+	page.SetPageSize(req.PageSize)
+	page.SetCurrent(req.Current)
+	//排序
+	if req.SortType == "" {
+		req.SortType = "desc"
+	}
+	if req.SortType != "desc" && req.SortType != "asc" {
+		resp.Fail("排序类型不正确", c)
+		return
+	}
+	if req.SortParam == "" {
+		page.AddOrderItem(base.OrderItem{Column: "sort_invoice_id", Asc: true})
+		page.AddOrderItem(base.OrderItem{Column: "sort_payment_id", Asc: false})
+		page.AddOrderItem(base.OrderItem{Column: "c.invoice_time", Asc: false})
+		page.AddOrderItem(base.OrderItem{Column: "c.amount", Asc: false})
+		page.AddOrderItem(base.OrderItem{Column: "a.create_time", Asc: false})
+	} else if req.SortParam == "invoice_time" {
+		if req.SortType == "asc" {
+			page.AddOrderItem(base.OrderItem{Column: "sort_invoice_id", Asc: false})
+			page.AddOrderItem(base.OrderItem{Column: "c.invoice_time", Asc: true})
+			page.AddOrderItem(base.OrderItem{Column: "c.amount", Asc: true})
+			page.AddOrderItem(base.OrderItem{Column: "a.create_time", Asc: true})
+		} else {
+			page.AddOrderItem(base.OrderItem{Column: "sort_invoice_id", Asc: true})
+			page.AddOrderItem(base.OrderItem{Column: "c.invoice_time", Asc: false})
+			page.AddOrderItem(base.OrderItem{Column: "c.amount", Asc: false})
+			page.AddOrderItem(base.OrderItem{Column: "a.create_time", Asc: false})
+		}
+	} else if req.SortParam == "payment_date" {
+		if req.SortType == "asc" {
+			page.AddOrderItem(base.OrderItem{Column: "sort_payment_id", Asc: false})
+			page.AddOrderItem(base.OrderItem{Column: "d.invoice_time", Asc: true})
+			page.AddOrderItem(base.OrderItem{Column: "d.amount", Asc: true})
+			page.AddOrderItem(base.OrderItem{Column: "a.create_time", Asc: true})
+		} else {
+			page.AddOrderItem(base.OrderItem{Column: "sort_payment_id", Asc: true})
+			page.AddOrderItem(base.OrderItem{Column: "d.invoice_time", Asc: false})
+			page.AddOrderItem(base.OrderItem{Column: "d.amount", Asc: false})
+			page.AddOrderItem(base.OrderItem{Column: "a.create_time", Asc: false})
+		}
+	} else {
+		resp.Fail("排序字段不正确", c)
+		return
+	}
+
+	if req.IsExport == 1 {
+		page.SetPageSize(10000)
+		page.SetCurrent(1)
+	}
+
+	registerList, total, e := fms.GetInvoicePaymentCensusPageList(page, cond, pars)
+	if e != nil {
+		resp.FailMsg("获取失败", "获取商品到款统计列表总数失败, Err: "+e.Error(), c)
+		return
+	}
+	queryRegisterIds := make([]int, 0)
+	for i := range registerList {
+		queryRegisterIds = append(queryRegisterIds, registerList[i].ContractRegisterId)
+	}
+
+	//fmt.Println("queryRegisterIds:",queryRegisterIds)
+	results := new(fms.InvoicePaymentCensusResp)
+	if len(queryRegisterIds) > 0 {
+		// 获取汇总数据IDs, 用于查询合计数据
+		summaryIdsCond := cond
+		summaryIdsPars := pars
+		summaryIds, e := fms.GetInvoicePaymentCensusSummaryDataIds(summaryIdsCond, summaryIdsPars)
+		if e != nil {
+			resp.FailMsg("获取失败", "获取商品到款汇总IDs失败, Err: "+e.Error(), c)
+			return
+		}
+
+		//fmt.Println("summaryIds:",summaryIds)
+		var listErr, totalErr, totalGroupErr error
+		wg := sync.WaitGroup{}
+
+		// 响应列表
+		respList := make([]*fms.InvoicePaymentCensusItem, 0)
+		summaryList := make([]*fms.InvoicePaymentSummaryItem, 0)
+		wg.Add(1)
+		go func() {
+			defer wg.Done()
+
+			// 获取汇总数据
+			summaryCond := cond
+			summaryCond += ` AND a.register_id IN ?`
+			summaryPars := pars
+			summaryPars = append(summaryPars, queryRegisterIds)
+			summaryData, e := fms.GetInvoicePaymentCensusSummaryData(summaryCond, summaryPars)
+			if e != nil {
+				resp.FailMsg("获取失败", "获取商品到款汇总列表失败, Err: "+e.Error(), c)
+				return
+			}
+			summaryList = summaryData
+			//summaryIds := make([]int, 0)
+			paymentIds := make([]int, 0)
+			for i := range summaryList {
+				//summaryIds = append(summaryIds, summaryList[i].SummaryId)
+				if summaryList[i].PaymentId > 0 {
+					paymentIds = append(paymentIds, summaryList[i].PaymentId)
+				}
+			}
+
+			// 合同套餐
+			/*contractServiceCond := `contract_register_id IN ?`
+			contractServicePars := make([]interface{}, 0)
+			contractServicePars = append(contractServicePars, queryRegisterIds)
+			contractServiceOB := new(fms.ContractService)
+			contractServiceList, e := contractServiceOB.List(contractServiceCond, contractServicePars)
+			if e != nil {
+				listErr = fmt.Errorf("获取合同套餐列表失败, Err: %s", e.Error())
+				return
+			}
+			contractServiceMap := make(map[int][]*fms.ContractService, 0)
+			servicesNameMap := make(map[int][]string, 0)
+			for i := range contractServiceList {
+				if contractServiceMap[contractServiceList[i].ContractRegisterId] == nil {
+					contractServiceMap[contractServiceList[i].ContractRegisterId] = make([]*fms.ContractService, 0)
+				}
+				contractServiceMap[contractServiceList[i].ContractRegisterId] = append(contractServiceMap[contractServiceList[i].ContractRegisterId], contractServiceList[i])
+				servicesNameMap[contractServiceList[i].ContractRegisterId] = append(servicesNameMap[contractServiceList[i].ContractRegisterId], contractServiceList[i].Title)
+			}
+			*/
+			servicesNameMap, serviceFormatMap, e := fmsService.GetContractServiceNameFormat(queryRegisterIds)
+			if e != nil {
+				listErr = fmt.Errorf("获取合同套餐列表失败, Err: %s", e.Error())
+				return
+			}
+			// 到款套餐分配
+			serviceAmountMap := make(map[int][]*fms.ContractPaymentServiceAmount, 0)
+			if len(paymentIds) > 0 {
+				serviceAmountCond := `contract_payment_id IN ?`
+				serviceAmountPars := make([]interface{}, 0)
+				serviceAmountPars = append(serviceAmountPars, paymentIds)
+				serviceAmountOB := new(fms.ContractPaymentServiceAmount)
+				serviceAmountList, e := serviceAmountOB.List(serviceAmountCond, serviceAmountPars)
+				if e != nil {
+					listErr = fmt.Errorf("获取到款套餐分配列表失败, Err: %s", e.Error())
+					return
+				}
+				for i := range serviceAmountList {
+					if serviceAmountMap[serviceAmountList[i].ContractPaymentId] == nil {
+						serviceAmountMap[serviceAmountList[i].ContractPaymentId] = make([]*fms.ContractPaymentServiceAmount, 0)
+					}
+					serviceAmountMap[serviceAmountList[i].ContractPaymentId] = append(serviceAmountMap[serviceAmountList[i].ContractPaymentId], serviceAmountList[i])
+				}
+			}
+
+			// 重组汇总数据
+			summaryMap := make(map[int][]*fms.InvoicePaymentCensusInfo)
+			amountMap := make(map[string]*fms.ContractPaymentServiceAmount)
+			for i := range summaryList {
+				v := new(fms.InvoicePaymentCensusInfo)
+				v.InvoiceId = summaryList[i].InvoiceId
+				v.InvoiceDate = utils.TimeTransferString(utils.FormatDate, summaryList[i].InvoiceDate)
+				v.InvoiceAmount = summaryList[i].InvoiceAmount
+				v.SellerId = summaryList[i].SellerId
+				v.SellerName = summaryList[i].SellerName
+				v.SellerGroupId = summaryList[i].SellerGroupId
+				v.SellerGroupName = summaryList[i].SellerGroupName
+				v.SellerType = summaryList[i].ServiceProductId
+				v.PaymentId = summaryList[i].PaymentId
+				v.PaymentDate = utils.TimeTransferString(utils.FormatDate, summaryList[i].PaymentDate)
+				v.PaymentAmount = summaryList[i].PaymentAmount
+				v.PayType = summaryList[i].PayType
+				// 套餐到款分配
+				svaList := make([]*fms.ContractPaymentServiceAmountItem, 0)
+				amountList := serviceAmountMap[summaryList[i].PaymentId]
+				if amountList != nil {
+					for i := range amountList {
+						k := fmt.Sprintf("%d-%d", amountList[i].ContractPaymentId, amountList[i].ServiceTemplateId)
+						amountMap[k] = amountList[i]
+					}
+				}
+				// 合同对应的所有套餐
+				svList := serviceFormatMap[summaryList[i].RegisterId]
+				if svList != nil {
+					for ii := range svList {
+						vv := new(fms.ContractPaymentServiceAmountItem)
+						vv.ServiceTemplateId = svList[ii].ServiceTemplateId
+						vv.ServiceTemplateName = svList[ii].FormatTitle
+						vv.ServiceTemplatePid = svList[ii].ServiceTemplatePid
+						vv.ServiceProductId = svList[ii].ServiceProductId
+						k2 := fmt.Sprintf("%d-%d", summaryList[i].PaymentId, svList[ii].ServiceTemplateId)
+						a := amountMap[k2]
+						if a != nil {
+							vv.ContractPaymentServiceAmountId = a.ContractPaymentServiceAmountId
+							vv.ContractPaymentId = a.ContractPaymentId
+							vv.Amount = a.Amount
+						}
+						svaList = append(svaList, vv)
+					}
+				}
+				v.ServiceAmountList = svaList
+
+				summaryMap[summaryList[i].SummaryId] = append(summaryMap[summaryList[i].SummaryId], v)
+			}
+
+			// 响应列表
+			for i := range registerList {
+				v := new(fms.InvoicePaymentCensusItem)
+				v.SummaryId = registerList[i].SummaryId
+				v.ContractRegisterId = registerList[i].ContractRegisterId
+				v.CompanyName = registerList[i].CompanyName
+				v.NewCompany = registerList[i].NewCompany
+				v.StartDate = utils.TimeTransferString(utils.FormatDate, registerList[i].StartDate)
+				v.EndDate = utils.TimeTransferString(utils.FormatDate, registerList[i].EndDate)
+				v.ServicesName = servicesNameMap[registerList[i].ContractRegisterId]
+				v.InvoicePaymentList = summaryMap[registerList[i].SummaryId]
+				v.ContractType = registerList[i].ContractType
+				v.ActualPayCompanies = registerList[i].ActualPayCompanies
+				respList = append(respList, v)
+			}
+		}()
+
+		// 开票到款金额合计(换算后)
+		var invoiceTotal, paymentTotal, amountTotal float64
+		wg.Add(1)
+		go func() {
+			defer wg.Done()
+
+			if len(summaryIds) == 0 {
+				return
+			}
+			amountTotalCond := `a.id IN ?`
+			amountTotalPars := make([]interface{}, 0)
+			amountTotalPars = append(amountTotalPars, summaryIds)
+			invoiceSum, e := fms.GetContractSummaryInvoicePaymentAmountTotal(amountTotalCond, amountTotalPars, 1)
+			if e != nil {
+				totalErr = fmt.Errorf("获取汇总开票金额合计失败, Err: %s", e.Error())
+				return
+			}
+			invoiceTotal, _ = strconv.ParseFloat(fmt.Sprintf("%.2f", invoiceSum), 64)
+			paymentSum, e := fms.GetContractSummaryInvoicePaymentAmountTotal(amountTotalCond, amountTotalPars, 2)
+			if e != nil {
+				totalErr = fmt.Errorf("获取汇总到款金额合计失败, Err: %s", e.Error())
+				return
+			}
+			paymentTotal, _ = strconv.ParseFloat(fmt.Sprintf("%.2f", paymentSum), 64)
+
+			amountCond := `a.id IN ? AND (a.invoice_id <> 0 OR (a.payment_id <> 0 AND a.invoice_id =0))`
+			amountPars := make([]interface{}, 0)
+			amountPars = append(amountPars, summaryIds)
+			amountSum, e := fms.GetContractSummaryInvoicePaymentAmount(amountCond, amountPars)
+			if e != nil {
+				totalErr = fmt.Errorf("获取汇总金额合计失败, Err: %s", e.Error())
+				return
+			}
+			amountTotal, _ = strconv.ParseFloat(fmt.Sprintf("%.2f", amountSum), 64)
+		}()
+
+		// 分币种金额统计
+		invoiceCurrencyTotals := make([]*fms.InvoiceListCurrencyTotal, 0)
+		paymentCurrencyTotals := make([]*fms.InvoiceListCurrencyTotal, 0)
+		wg.Add(1)
+		go func() {
+			defer wg.Done()
+
+			currencyOB := new(fms.CurrencyUnit)
+			currencyCond := `enable = 1`
+			currencyPars := make([]interface{}, 0)
+			currencyList, e := currencyOB.List(currencyCond, currencyPars)
+			if e != nil {
+				totalGroupErr = fmt.Errorf("获取货币列表失败, Err: %s", e.Error())
+				return
+			}
+			unitMap := make(map[string]string)
+			for i := range currencyList {
+				unitMap[currencyList[i].Code] = currencyList[i].UnitName
+				invoiceCurrencyTotals = append(invoiceCurrencyTotals, &fms.InvoiceListCurrencyTotal{
+					Name:     currencyList[i].Name,
+					UnitName: currencyList[i].UnitName,
+					Code:     currencyList[i].Code,
+					FlagImg:  currencyList[i].FlagImg,
+				})
+				paymentCurrencyTotals = append(paymentCurrencyTotals, &fms.InvoiceListCurrencyTotal{
+					Name:     currencyList[i].Name,
+					UnitName: currencyList[i].UnitName,
+					Code:     currencyList[i].Code,
+					FlagImg:  currencyList[i].FlagImg,
+				})
+			}
+
+			if len(summaryIds) == 0 {
+				return
+			}
+			totalGroupCond := `a.id IN ?`
+			totalGroupPars := make([]interface{}, 0)
+			totalGroupPars = append(totalGroupPars, summaryIds)
+			invoiceSumGroup, e := fms.GetSummaryListCurrencySum(totalGroupCond, totalGroupPars, 1)
+			if e != nil {
+				totalGroupErr = fmt.Errorf("获取汇总货币合计开票金额失败, Err: %s", e.Error())
+				return
+			}
+			paymentSumGroup, e := fms.GetSummaryListCurrencySum(totalGroupCond, totalGroupPars, 2)
+			if e != nil {
+				totalGroupErr = fmt.Errorf("获取汇总货币合计到款金额失败, Err: %s", e.Error())
+				return
+			}
+			invoiceSumMap := make(map[string]float64)
+			paymentSumMap := make(map[string]float64)
+			for i := range invoiceSumGroup {
+				invoiceSumMap[invoiceSumGroup[i].CurrencyUnit] = invoiceSumGroup[i].OriginAmountTotal
+				continue
+			}
+			for i := range paymentSumGroup {
+				paymentSumMap[paymentSumGroup[i].CurrencyUnit] = paymentSumGroup[i].OriginAmountTotal
+				continue
+			}
+			for i := range invoiceCurrencyTotals {
+				a, _ := strconv.ParseFloat(fmt.Sprintf("%.2f", invoiceSumMap[invoiceCurrencyTotals[i].Code]), 64)
+				invoiceCurrencyTotals[i].Amount = a
+			}
+			for i := range paymentCurrencyTotals {
+				a, _ := strconv.ParseFloat(fmt.Sprintf("%.2f", paymentSumMap[paymentCurrencyTotals[i].Code]), 64)
+				paymentCurrencyTotals[i].Amount = a
+			}
+		}()
+
+		wg.Wait()
+
+		if listErr != nil {
+			resp.FailMsg("获取失败", listErr.Error(), c)
+			return
+		}
+		if totalErr != nil {
+			resp.FailMsg("获取失败", totalErr.Error(), c)
+			return
+		}
+		if totalGroupErr != nil {
+			resp.FailMsg("获取失败", totalGroupErr.Error(), c)
+			return
+		}
+
+		results.DataList = respList
+		results.InvoiceTotal = invoiceTotal
+		results.PaymentTotal = paymentTotal
+		results.AmountTotal = amountTotal
+		results.InvoiceCurrencyTotal = invoiceCurrencyTotals
+		results.PaymentCurrencyTotal = paymentCurrencyTotals
+	}
+
+	// 是否导出
+	if req.IsExport == 1 {
+		ExportInvoicePaymentCensusList(c, results)
+		return
+	}
+	page.SetTotal(total)
+	baseData := new(base.BaseData)
+	baseData.SetPage(page)
+	baseData.SetList(results)
+	resp.OkData("获取成功", baseData, c)
+}
+
+// List
+// @Title 未开票统计列表
+// @Description 未开票统计列表
+// @Param   Keyword			query	string	false	"关键词"
+// @Param   SellGroupId		query	int		false	"销售组别ID"
+// @Param   ServiceType		query	int		false	"套餐类型"
+// @Param   StartDate		query	string	false	"合同开始日期"
+// @Param   EndDate			query	string	false	"合同结束日期"
+// @Param   TimeType		query	int		false	"时间类型: 1-开票时间; 2-到款时间"
+// @Param   HasInvoice		query	string		false	"是否已开票: 0-否; 1-是; 空-全部"
+// @Param   HasPayment		query	string		false	"是否已到款: 0-否; 1-是; 空-全部"
+// @Param   IsExport		query	int		false	"是否导出: 0-否; 1-是"
+// @Param   ListParam		query	int		false	"套餐类型: 0-全部; 1-ficc; 2-权益"
+// @Param   SortParam       query   string  false      "排序字段参数,用来排序的字段, 枚举值:'start_date':开票日 、 'end_date':到款日"
+// @Param   SortType        query   string  true       "如何排序,是正序还是倒序,枚举值:`asc 正序`,`desc 倒叙`"
+// @Success 200 {object} fms.ContractRegisterItem
+// @router /census/invoice_payment/not_invoice/list [get]
+func (ct *InvoicePaymentController) NotInvoiceList(c *gin.Context) {
+	var req fms.InvoicePaymentCensusListReq
+	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 := `1 = 1`
+	pars := make([]interface{}, 0)
+	// 客户姓名/合同编号
+	if req.Keyword != "" {
+		kw := "%" + req.Keyword + "%"
+		cond += ` AND (b.company_name LIKE ? OR b.contract_code LIKE ?)`
+		pars = append(pars, kw, kw)
+	}
+	if req.SellerIds != "" {
+		sellerIds := strings.Split(req.SellerIds, ",")
+		cond += ` AND (c.seller_id in ?)`
+		pars = append(pars, sellerIds)
+	}
+	// 套餐筛选
+	if req.ServiceTypes != "" {
+		serviceTypes := strings.Split(req.ServiceTypes, ",")
+		tempRegisterIds, e := fms.GetContractRegisterIdsByTempId(serviceTypes)
+		if e != nil {
+			resp.FailMsg("获取失败", "获取合同登记IDs失败, Err: "+e.Error(), c)
+			return
+		}
+		if len(tempRegisterIds) > 0 {
+			cond += ` AND a.register_id IN ?`
+			pars = append(pars, tempRegisterIds)
+		} else {
+			cond += ` AND 1 = 2`
+		}
+	}
+
+	if req.ListParam == 1 {
+		cond += ` AND a.service_product_id = 1 `
+	} else if req.ListParam == 2 {
+		cond += ` AND a.service_product_id = 2 `
+	}
+
+	// 开票到款日期
+	//if req.TimeType != 0 {
+	//	if req.TimeType == 1 &&  req.StartDate != "" && req.EndDate != "" {
+	//		st := fmt.Sprint(req.StartDate, " 00:00:00")
+	//		ed := fmt.Sprint(req.EndDate, " 23:59:59")
+	//		cond += ` AND (c.invoice_time BETWEEN ? AND ?) `
+	//		pars = append(pars, st, ed)
+	//	}else if req.TimeType == 2 &&  req.StartDate != "" && req.EndDate != "" {
+	//		st := fmt.Sprint(req.StartDate, " 00:00:00")
+	//		ed := fmt.Sprint(req.EndDate, " 23:59:59")
+	//		cond += ` AND (d.invoice_time BETWEEN ? AND ?) `
+	//		pars = append(pars, st, ed)
+	//	}else if req.TimeType == 3 &&  req.StartDate != "" && req.EndDate != "" {
+	//		st := fmt.Sprint(req.StartDate, " 00:00:00")
+	//		ed := fmt.Sprint(req.EndDate, " 23:59:59")
+	//		cond += ` AND (c.invoice_time BETWEEN ? AND ?) AND (d.invoice_time BETWEEN ? AND ?) `
+	//		pars = append(pars, st, ed, st, ed)
+	//	}
+	//} else if req.StartDate != "" && req.EndDate != "" {
+	//	st := fmt.Sprint(req.StartDate, " 00:00:00")
+	//	ed := fmt.Sprint(req.EndDate, " 23:59:59")
+	//	cond += ` AND ((c.invoice_time BETWEEN ? AND ?) or (d.invoice_time BETWEEN ? AND ?))`
+	//	pars = append(pars, st, ed, st, ed)
+	//}
+
+	//if req.HasInvoice == "1" {
+	//	cond += ` AND a.invoice_id > 0 `
+	//}else if req.HasInvoice == "0" {
+	//	cond += ` AND a.invoice_id = 0 `
+	//}
+	//
+	//if req.HasPayment == "1" {
+	//	cond += ` AND a.payment_id > 0 `
+	//}else if req.HasPayment == "0" {
+	//	cond += ` AND a.payment_id = 0 `
+	//}
+
+	page := new(base.Page)
+	page.SetPageSize(req.PageSize)
+	page.SetCurrent(req.Current)
+	//排序
+	if req.SortType == "" {
+		req.SortType = "desc"
+	}
+	if req.SortType != "desc" && req.SortType != "asc" {
+		resp.Fail("排序类型不正确", c)
+		return
+	}
+	if req.SortParam == "" {
+		page.AddOrderItem(base.OrderItem{Column: "e.start_date", Asc: false})
+	} else if req.SortParam == "start_date" {
+		if req.SortType == "asc" {
+			page.AddOrderItem(base.OrderItem{Column: "e.start_date", Asc: true})
+		} else {
+			page.AddOrderItem(base.OrderItem{Column: "e.start_date", Asc: false})
+		}
+	} else if req.SortParam == "end_date" {
+		if req.SortType == "asc" {
+			page.AddOrderItem(base.OrderItem{Column: "e.end_date", Asc: true})
+		} else {
+			page.AddOrderItem(base.OrderItem{Column: "e.end_date", Asc: false})
+		}
+	} else {
+		resp.Fail("排序字段不正确", c)
+		return
+	}
+
+	if req.IsExport == 1 {
+		page.SetPageSize(10000)
+		page.SetCurrent(1)
+	}
+
+	registerList, total, e := fms.GetInvoiceCensusPageList(page, cond, pars)
+	if e != nil {
+		resp.FailMsg("获取失败", "获取商品到款统计列表总数失败, Err: "+e.Error(), c)
+		return
+	}
+	queryRegisterIds := make([]int, 0)
+	for i := range registerList {
+		queryRegisterIds = append(queryRegisterIds, registerList[i].ContractRegisterId)
+	}
+
+	//fmt.Println("queryRegisterIds:",queryRegisterIds)
+	results := new(fms.NotInvoicePaymentCensusResp)
+	if len(queryRegisterIds) > 0 {
+		// 获取汇总数据IDs, 用于查询合计数据
+		summaryIdsCond := cond
+		summaryIdsPars := pars
+		if req.SellerIds != "" {
+			sellerIds := strings.Split(req.SellerIds, ",")
+			summaryIdsCond += ` AND c.seller_id in ? AND a.payment_id <> 0 AND a.invoice_id = 0  AND (c.origin_amount > d.origin_amount OR d.origin_amount IS NULL) `
+			summaryIdsPars = append(summaryIdsPars, sellerIds)
+		} else {
+			summaryIdsCond += ` AND a.payment_id <> 0 AND a.invoice_id = 0  AND (c.origin_amount > d.origin_amount OR d.origin_amount IS NULL) `
+			summaryIdsPars = append(summaryIdsPars)
+		}
+		summaryIds, e := fms.GetInvoicePaymentCensusSummaryDataIds(summaryIdsCond, summaryIdsPars)
+		if e != nil {
+			resp.FailMsg("获取失败", "获取商品到款汇总IDs失败, Err: "+e.Error(), c)
+			return
+		}
+
+		//fmt.Println("summaryIds:",summaryIds)
+		var listErr, totalErr, totalGroupErr error
+		wg := sync.WaitGroup{}
+
+		// 响应列表
+		respList := make([]*fms.NotPaymentCensusItem, 0)
+		summaryList := make([]*fms.InvoicePaymentSummaryItem, 0)
+		wg.Add(1)
+		go func() {
+			defer wg.Done()
+
+			// 获取汇总数据
+			summaryCond := cond
+			summaryCond += ` AND a.register_id IN ?`
+			summaryPars := pars
+			summaryPars = append(summaryPars, queryRegisterIds)
+			if req.SellerIds != "" {
+				sellerIds := strings.Split(req.SellerIds, ",")
+				summaryCond += ` AND d.seller_id in ? AND a.payment_id <> 0 AND a.invoice_id = 0 `
+				summaryPars = append(summaryPars, sellerIds, sellerIds)
+			} else {
+				summaryCond += ` AND a.payment_id <> 0 AND a.invoice_id = 0 `
+				summaryPars = append(summaryPars)
+			}
+
+			summaryData, e := fms.GetInvoicePaymentCensusSummaryData(summaryCond, summaryPars)
+			if e != nil {
+				resp.FailMsg("获取失败", "获取商品到款汇总列表失败, Err: "+e.Error(), c)
+				return
+			}
+			summaryList = summaryData
+			//summaryIds := make([]int, 0)
+			paymentIds := make([]int, 0)
+			for i := range summaryList {
+				//summaryIds = append(summaryIds, summaryList[i].SummaryId)
+				if summaryList[i].PaymentId > 0 {
+					paymentIds = append(paymentIds, summaryList[i].PaymentId)
+				}
+			}
+			fmt.Println("paymentIds:", paymentIds)
+			// 合同套餐
+			/*contractServiceCond := `contract_register_id IN ?`
+			contractServicePars := make([]interface{}, 0)
+			contractServicePars = append(contractServicePars, queryRegisterIds)
+			contractServiceOB := new(fms.ContractService)
+			contractServiceList, e := contractServiceOB.List(contractServiceCond, contractServicePars)
+			if e != nil {
+				listErr = fmt.Errorf("获取合同套餐列表失败, Err: %s", e.Error())
+				return
+			}
+			contractServiceMap := make(map[int][]*fms.ContractService, 0)
+			servicesNameMap := make(map[int][]string, 0)
+			for i := range contractServiceList {
+				if contractServiceMap[contractServiceList[i].ContractRegisterId] == nil {
+					contractServiceMap[contractServiceList[i].ContractRegisterId] = make([]*fms.ContractService, 0)
+				}
+				contractServiceMap[contractServiceList[i].ContractRegisterId] = append(contractServiceMap[contractServiceList[i].ContractRegisterId], contractServiceList[i])
+				servicesNameMap[contractServiceList[i].ContractRegisterId] = append(servicesNameMap[contractServiceList[i].ContractRegisterId], contractServiceList[i].Title)
+			}
+			*/
+			servicesNameMap, serviceFormatMap, e := fmsService.GetContractServiceNameFormat(queryRegisterIds)
+			if e != nil {
+				listErr = fmt.Errorf("获取合同套餐列表失败, Err: %s", e.Error())
+				return
+			}
+			// 到款套餐分配
+			serviceAmountMap := make(map[int][]*fms.ContractPaymentServiceAmount, 0)
+			if len(paymentIds) > 0 {
+				serviceAmountCond := `contract_payment_id IN ?`
+				serviceAmountPars := make([]interface{}, 0)
+				serviceAmountPars = append(serviceAmountPars, paymentIds)
+				serviceAmountOB := new(fms.ContractPaymentServiceAmount)
+				serviceAmountList, e := serviceAmountOB.List(serviceAmountCond, serviceAmountPars)
+				if e != nil {
+					listErr = fmt.Errorf("获取到款套餐分配列表失败, Err: %s", e.Error())
+					return
+				}
+				for i := range serviceAmountList {
+					if serviceAmountMap[serviceAmountList[i].ContractPaymentId] == nil {
+						serviceAmountMap[serviceAmountList[i].ContractPaymentId] = make([]*fms.ContractPaymentServiceAmount, 0)
+					}
+					serviceAmountMap[serviceAmountList[i].ContractPaymentId] = append(serviceAmountMap[serviceAmountList[i].ContractPaymentId], serviceAmountList[i])
+				}
+			}
+
+			// 重组汇总数据
+			summaryMap := make(map[int][]*fms.NotPaymentCensusInfo)
+			amountMap := make(map[string]*fms.ContractPaymentServiceAmount)
+			for i := range summaryList {
+				v := new(fms.NotPaymentCensusInfo)
+				v.InvoiceId = summaryList[i].InvoiceId
+				v.InvoiceDate = utils.TimeTransferString(utils.FormatDate, summaryList[i].InvoiceDate)
+				v.InvoiceAmount = summaryList[i].InvoiceAmount
+				v.SellerId = summaryList[i].SellerId
+				v.SellerName = summaryList[i].SellerName
+				v.SellerGroupId = summaryList[i].SellerGroupId
+				v.SellerGroupName = summaryList[i].SellerGroupName
+				v.SellerType = summaryList[i].ServiceProductId
+				v.PaymentId = summaryList[i].PaymentId
+				v.PaymentDate = utils.TimeTransferString(utils.FormatDate, summaryList[i].PaymentDate)
+				v.PaymentAmount = summaryList[i].PaymentAmount
+				v.PayType = summaryList[i].PayType
+				// 套餐到款分配
+				svaList := make([]*fms.ContractPaymentServiceAmountItem, 0)
+				amountList := serviceAmountMap[summaryList[i].PaymentId]
+				if amountList != nil {
+					for i := range amountList {
+						k := fmt.Sprintf("%d-%d", amountList[i].ContractPaymentId, amountList[i].ServiceTemplateId)
+						amountMap[k] = amountList[i]
+					}
+				}
+				// 合同对应的所有套餐
+				svList := serviceFormatMap[summaryList[i].RegisterId]
+				if svList != nil {
+					for ii := range svList {
+						vv := new(fms.ContractPaymentServiceAmountItem)
+						vv.ServiceTemplateId = svList[ii].ServiceTemplateId
+						vv.ServiceTemplateName = svList[ii].FormatTitle
+						vv.ServiceTemplatePid = svList[ii].ServiceTemplatePid
+						k2 := fmt.Sprintf("%d-%d", summaryList[i].PaymentId, svList[ii].ServiceTemplateId)
+						a := amountMap[k2]
+						if a != nil {
+							vv.ContractPaymentServiceAmountId = a.ContractPaymentServiceAmountId
+							vv.ContractPaymentId = a.ContractPaymentId
+							vv.Amount = a.Amount
+						}
+						svaList = append(svaList, vv)
+					}
+				}
+				v.ServiceAmountList = svaList
+
+				summaryMap[summaryList[i].SummaryId] = append(summaryMap[summaryList[i].SummaryId], v)
+			}
+
+			// 货币列表
+			currencyOB := new(fms.CurrencyUnit)
+			currencyCond := `enable = 1`
+			currencyPars := make([]interface{}, 0)
+			currencyList, e := currencyOB.List(currencyCond, currencyPars)
+			if e != nil {
+				resp.FailMsg("获取失败", "获取货币列表失败, Err: "+e.Error(), c)
+				return
+			}
+			unitMap := make(map[string]string)
+			for i := range currencyList {
+				unitMap[currencyList[i].Code] = currencyList[i].UnitName
+			}
+
+			// 响应列表
+			for i := range registerList {
+				v := new(fms.NotPaymentCensusItem)
+				v.SummaryId = registerList[i].SummaryId
+				v.ContractRegisterId = registerList[i].ContractRegisterId
+				v.CompanyName = registerList[i].CompanyName
+				v.NewCompany = registerList[i].NewCompany
+				v.StartDate = utils.TimeTransferString(utils.FormatDate, registerList[i].StartDate)
+				v.EndDate = utils.TimeTransferString(utils.FormatDate, registerList[i].EndDate)
+				v.ServicesName = servicesNameMap[registerList[i].ContractRegisterId]
+				v.InvoicePaymentList = summaryMap[registerList[i].SummaryId]
+				v.ContractType = registerList[i].ContractType
+				v.ContractCode = registerList[i].ContractCode
+				v.ContractAmount = registerList[i].ContractAmount
+				v.UnitName = unitMap[registerList[i].CurrencyUnit]
+				v.ProductIds = registerList[i].ProductIds
+				v.NotInvoiceTotal = registerList[i].ContractAmount - registerList[i].InvoicedAmount
+				respList = append(respList, v)
+			}
+		}()
+
+		// 开票到款金额合计(换算后)
+		var invoiceTotal, paymentTotal, contractAmount float64
+		wg.Add(1)
+		go func() {
+			defer wg.Done()
+
+			if len(summaryIds) == 0 {
+				return
+			}
+			amountTotalCond := `a.id IN ?`
+			amountTotalPars := make([]interface{}, 0)
+			amountTotalPars = append(amountTotalPars, summaryIds)
+			invoiceSum, e := fms.GetContractSummaryInvoicePaymentAmountTotal(amountTotalCond, amountTotalPars, 1)
+			if e != nil {
+				totalErr = fmt.Errorf("获取汇总开票金额合计失败, Err: %s", e.Error())
+				return
+			}
+			invoiceTotal, _ = strconv.ParseFloat(fmt.Sprintf("%.2f", invoiceSum), 64)
+			paymentSum, e := fms.GetContractSummaryInvoicePaymentAmountTotal(amountTotalCond, amountTotalPars, 2)
+			if e != nil {
+				totalErr = fmt.Errorf("获取汇总到款金额合计失败, Err: %s", e.Error())
+				return
+			}
+			paymentTotal, _ = strconv.ParseFloat(fmt.Sprintf("%.2f", paymentSum), 64)
+		}()
+
+		// 分币种金额统计
+		invoiceCurrencyTotals := make([]*fms.InvoiceListCurrencyTotal, 0)
+		paymentCurrencyTotals := make([]*fms.InvoiceListCurrencyTotal, 0)
+		contractAmountCurrencyTotals := make([]*fms.InvoiceListCurrencyTotal, 0)
+		wg.Add(1)
+		go func() {
+			defer wg.Done()
+
+			currencyOB := new(fms.CurrencyUnit)
+			currencyCond := `enable = 1`
+			currencyPars := make([]interface{}, 0)
+			currencyList, e := currencyOB.List(currencyCond, currencyPars)
+			if e != nil {
+				totalGroupErr = fmt.Errorf("获取货币列表失败, Err: %s", e.Error())
+				return
+			}
+			unitMap := make(map[string]string)
+			for i := range currencyList {
+				unitMap[currencyList[i].Code] = currencyList[i].UnitName
+				invoiceCurrencyTotals = append(invoiceCurrencyTotals, &fms.InvoiceListCurrencyTotal{
+					Name:     currencyList[i].Name,
+					UnitName: currencyList[i].UnitName,
+					Code:     currencyList[i].Code,
+					FlagImg:  currencyList[i].FlagImg,
+				})
+				paymentCurrencyTotals = append(paymentCurrencyTotals, &fms.InvoiceListCurrencyTotal{
+					Name:     currencyList[i].Name,
+					UnitName: currencyList[i].UnitName,
+					Code:     currencyList[i].Code,
+					FlagImg:  currencyList[i].FlagImg,
+				})
+				contractAmountCurrencyTotals = append(contractAmountCurrencyTotals, &fms.InvoiceListCurrencyTotal{
+					Name:     currencyList[i].Name,
+					UnitName: currencyList[i].UnitName,
+					Code:     currencyList[i].Code,
+					FlagImg:  currencyList[i].FlagImg,
+				})
+			}
+
+			if len(summaryIds) == 0 {
+				return
+			}
+			totalGroupCond := `a.id IN ?`
+			totalGroupPars := make([]interface{}, 0)
+			totalGroupPars = append(totalGroupPars, summaryIds)
+			invoiceSumGroup, e := fms.GetSummaryListCurrencySum(totalGroupCond, totalGroupPars, 1)
+			if e != nil {
+				totalGroupErr = fmt.Errorf("获取汇总货币合计开票金额失败, Err: %s", e.Error())
+				return
+			}
+			paymentSumGroup, e := fms.GetSummaryListCurrencySum(totalGroupCond, totalGroupPars, 2)
+			if e != nil {
+				totalGroupErr = fmt.Errorf("获取汇总货币合计到款金额失败, Err: %s", e.Error())
+				return
+			}
+			invoiceSumMap := make(map[string]float64)
+			paymentSumMap := make(map[string]float64)
+			contractSumMap := make(map[string]float64)
+
+			for i := range invoiceSumGroup {
+				invoiceSumMap[invoiceSumGroup[i].CurrencyUnit] = invoiceSumGroup[i].OriginAmountTotal
+				continue
+			}
+			for i := range paymentSumGroup {
+				paymentSumMap[paymentSumGroup[i].CurrencyUnit] = paymentSumGroup[i].OriginAmountTotal
+				continue
+			}
+			for i := range invoiceCurrencyTotals {
+				a, _ := strconv.ParseFloat(fmt.Sprintf("%.2f", invoiceSumMap[invoiceCurrencyTotals[i].Code]), 64)
+				invoiceCurrencyTotals[i].Amount = a
+			}
+			for i := range paymentCurrencyTotals {
+				a, _ := strconv.ParseFloat(fmt.Sprintf("%.2f", paymentSumMap[paymentCurrencyTotals[i].Code]), 64)
+				paymentCurrencyTotals[i].Amount = a
+			}
+
+			contractRegisters, err := fms.GetContractInfoByRegisterIds(queryRegisterIds)
+			if err != nil {
+				resp.FailMsg("查询合同信息失败", "查询合同信息失败, Err: "+err.Error(), c)
+				return
+			}
+			for _, v := range contractRegisters {
+				if v.RMBRate == 0.0 {
+					v.RMBRate = 1
+				}
+				amount, _ := strconv.ParseFloat(fmt.Sprintf("%.2f", v.ContractAmount/v.RMBRate), 64)
+				contractAmount += amount
+				contractSumMap[v.CurrencyUnit] = v.ContractAmount
+			}
+			for _, v := range contractAmountCurrencyTotals {
+				v.Amount = contractSumMap[v.Code] - invoiceSumMap[v.Code]
+			}
+
+		}()
+
+		wg.Wait()
+
+		if listErr != nil {
+			resp.FailMsg("获取失败", listErr.Error(), c)
+			return
+		}
+		if totalErr != nil {
+			resp.FailMsg("获取失败", totalErr.Error(), c)
+			return
+		}
+		if totalGroupErr != nil {
+			resp.FailMsg("获取失败", totalGroupErr.Error(), c)
+			return
+		}
+		results.DataList = respList
+		results.InvoiceTotal = invoiceTotal
+		results.PaymentTotal = paymentTotal
+		results.NotInvoiceTotal = contractAmount - invoiceTotal
+		results.InvoiceCurrencyTotal = invoiceCurrencyTotals
+		results.PaymentCurrencyTotal = paymentCurrencyTotals
+		results.NotInvoiceCurrencyTotal = contractAmountCurrencyTotals
+	}
+
+	// 是否导出
+	if req.IsExport == 1 {
+		ExportNotInvoiceCensusList(c, results)
+		return
+	}
+	page.SetTotal(total)
+	baseData := new(base.BaseData)
+	baseData.SetPage(page)
+	baseData.SetList(results)
+	resp.OkData("获取成功", baseData, c)
+}
+
+
+// List
+// @Title 开票未到款统计列表
+// @Description 开票未到款统计列表
+// @Param   Keyword			query	string	false	"关键词"
+// @Param   SellGroupId		query	int		false	"销售组别ID"
+// @Param   ServiceType		query	int		false	"套餐类型"
+// @Param   StartDate		query	string	false	"合同开始日期"
+// @Param   EndDate			query	string	false	"合同结束日期"
+// @Param   TimeType		query	int		false	"时间类型: 1-开票时间; 2-到款时间"
+// @Param   HasInvoice		query	string		false	"是否已开票: 0-否; 1-是; 空-全部"
+// @Param   HasPayment		query	string		false	"是否已到款: 0-否; 1-是; 空-全部"
+// @Param   IsExport		query	int		false	"是否导出: 0-否; 1-是"
+// @Param   ListParam		query	int		false	"套餐类型: 0-全部; 1-ficc; 2-权益"
+// @Param   SortParam       query   string  false      "排序字段参数,用来排序的字段, 枚举值:'invoice_time':开票日 、 'payment_date':到款日"
+// @Param   SortType        query   string  true       "如何排序,是正序还是倒序,枚举值:`asc 正序`,`desc 倒叙`"
+// @Success 200 {object} fms.ContractRegisterItem
+// @router /census/invoice_payment/not_payment/list [get]
+func (ct *InvoicePaymentController) NotPaymentList(c *gin.Context) {
+	var req fms.InvoicePaymentCensusListReq
+	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 := `1 = 1`
+	pars := make([]interface{}, 0)
+	// 客户姓名/销售
+	if req.Keyword != "" {
+		kw := "%" + req.Keyword + "%"
+		cond += ` AND (b.company_name LIKE ? OR b.contract_code LIKE ?)`
+		pars = append(pars, kw, kw)
+	}
+	if req.SellerIds != "" {
+		sellerIds := strings.Split(req.SellerIds, ",")
+		cond += ` AND (c.seller_id in ?)`
+		pars = append(pars, sellerIds)
+	}
+	// 套餐筛选
+	if req.ServiceTypes != "" {
+		serviceTypes := strings.Split(req.ServiceTypes, ",")
+		tempRegisterIds, e := fms.GetContractRegisterIdsByTempId(serviceTypes)
+		if e != nil {
+			resp.FailMsg("获取失败", "获取合同登记IDs失败, Err: "+e.Error(), c)
+			return
+		}
+		if len(tempRegisterIds) > 0 {
+			cond += ` AND a.register_id IN ?`
+			pars = append(pars, tempRegisterIds)
+		} else {
+			cond += ` AND 1 = 2`
+		}
+	}
+
+	if req.ListParam == 1 {
+		cond += ` AND a.service_product_id = 1 `
+	} else if req.ListParam == 2 {
+		cond += ` AND a.service_product_id = 2 `
+	}
+
+	// 开票到款日期
+	//if req.TimeType != 0 {
+	//	if req.TimeType == 1 &&  req.StartDate != "" && req.EndDate != "" {
+	//		st := fmt.Sprint(req.StartDate, " 00:00:00")
+	//		ed := fmt.Sprint(req.EndDate, " 23:59:59")
+	//		cond += ` AND (c.invoice_time BETWEEN ? AND ?) `
+	//		pars = append(pars, st, ed)
+	//	}else if req.TimeType == 2 &&  req.StartDate != "" && req.EndDate != "" {
+	//		st := fmt.Sprint(req.StartDate, " 00:00:00")
+	//		ed := fmt.Sprint(req.EndDate, " 23:59:59")
+	//		cond += ` AND (d.invoice_time BETWEEN ? AND ?) `
+	//		pars = append(pars, st, ed)
+	//	}else if req.TimeType == 3 &&  req.StartDate != "" && req.EndDate != "" {
+	//		st := fmt.Sprint(req.StartDate, " 00:00:00")
+	//		ed := fmt.Sprint(req.EndDate, " 23:59:59")
+	//		cond += ` AND (c.invoice_time BETWEEN ? AND ?) AND (d.invoice_time BETWEEN ? AND ?) `
+	//		pars = append(pars, st, ed, st, ed)
+	//	}
+	//} else if req.StartDate != "" && req.EndDate != "" {
+	//	st := fmt.Sprint(req.StartDate, " 00:00:00")
+	//	ed := fmt.Sprint(req.EndDate, " 23:59:59")
+	//	cond += ` AND ((c.invoice_time BETWEEN ? AND ?) or (d.invoice_time BETWEEN ? AND ?))`
+	//	pars = append(pars, st, ed, st, ed)
+	//}
+
+	//if req.HasInvoice == "1" {
+	//	cond += ` AND a.invoice_id > 0 `
+	//}else if req.HasInvoice == "0" {
+	//	cond += ` AND a.invoice_id = 0 `
+	//}
+	//
+	//if req.HasPayment == "1" {
+	//	cond += ` AND a.payment_id > 0 `
+	//}else if req.HasPayment == "0" {
+	//	cond += ` AND a.payment_id = 0 `
+	//}
+
+	page := new(base.Page)
+	page.SetPageSize(req.PageSize)
+	page.SetCurrent(req.Current)
+	//排序
+	if req.SortType == "" {
+		req.SortType = "asc"
+	}
+	if req.SortType != "desc" && req.SortType != "asc" {
+		resp.Fail("排序类型不正确", c)
+		return
+	}
+	if req.SortType == "asc" {
+		page.AddOrderItem(base.OrderItem{Column: "e.invoice_time", Asc: true})
+	} else {
+		page.AddOrderItem(base.OrderItem{Column: "e.invoice_time", Asc: false})
+	}
+
+	if req.IsExport == 1 {
+		page.SetPageSize(10000)
+		page.SetCurrent(1)
+	}
+
+	registerList, total, e := fms.GetNoPaymentCensusPageList(page, cond, pars)
+	if e != nil {
+		resp.FailMsg("获取失败", "获取商品到款统计列表总数失败, Err: "+e.Error(), c)
+		return
+	}
+	queryRegisterIds := make([]int, 0)
+	for i := range registerList {
+		queryRegisterIds = append(queryRegisterIds, registerList[i].ContractRegisterId)
+	}
+
+	//fmt.Println("queryRegisterIds:",queryRegisterIds)
+	results := new(fms.NotInvoicePaymentCensusResp)
+	if len(queryRegisterIds) > 0 {
+		// 获取汇总数据IDs, 用于查询合计数据
+		summaryIdsCond := cond
+		summaryIdsPars := pars
+		if req.SellerIds != "" {
+			sellerIds := strings.Split(req.SellerIds, ",")
+			summaryIdsCond += ` AND c.seller_id in ? AND a.invoice_id <> 0  AND (c.origin_amount > d.origin_amount OR d.origin_amount IS NULL) `
+			summaryIdsPars = append(summaryIdsPars, sellerIds)
+		} else {
+			summaryIdsCond += ` AND a.invoice_id <> 0  AND (c.origin_amount > d.origin_amount OR d.origin_amount IS NULL) `
+			summaryIdsPars = append(summaryIdsPars)
+		}
+		summaryIds, e := fms.GetInvoicePaymentCensusSummaryDataIds(summaryIdsCond, summaryIdsPars)
+		if e != nil {
+			resp.FailMsg("获取失败", "获取商品到款汇总IDs失败, Err: "+e.Error(), c)
+			return
+		}
+
+		//fmt.Println("summaryIds:",summaryIds)
+		var listErr, totalErr, totalGroupErr error
+		wg := sync.WaitGroup{}
+
+		// 响应列表
+		respList := make([]*fms.NotPaymentCensusItem, 0)
+		summaryList := make([]*fms.InvoicePaymentSummaryItem, 0)
+		wg.Add(1)
+		go func() {
+			defer wg.Done()
+
+			// 获取汇总数据
+			summaryCond := cond
+			summaryCond += ` AND a.register_id IN ?`
+			summaryPars := pars
+			summaryPars = append(summaryPars, queryRegisterIds)
+			if req.SellerIds != "" {
+				sellerIds := strings.Split(req.SellerIds, ",")
+				summaryCond += ` AND c.seller_id in ? AND a.invoice_id <> 0  AND (c.origin_amount > d.origin_amount OR d.origin_amount IS NULL) `
+				summaryPars = append(summaryPars, sellerIds)
+			} else {
+				summaryCond += ` AND a.invoice_id <> 0  AND (c.origin_amount > d.origin_amount OR d.origin_amount IS NULL) `
+				summaryPars = append(summaryPars)
+			}
+			summaryData, e := fms.GetInvoicePaymentCensusSummaryData(summaryCond, summaryPars)
+			if e != nil {
+				resp.FailMsg("获取失败", "获取商品到款汇总列表失败, Err: "+e.Error(), c)
+				return
+			}
+			summaryList = summaryData
+			//summaryIds := make([]int, 0)
+			//for i := range summaryList {
+			//	//summaryIds = append(summaryIds, summaryList[i].SummaryId)
+			//
+			//}
+
+			//// 获取合同的套餐金额信息
+			//serviceAmountList, e := fms.GetContractServiceAmountByContractRegisterIds(queryRegisterIds)
+			//if e != nil {
+			//	resp.FailData("获取合同的套餐金额信息失败", "Err:"+e.Error(), c)
+			//	return
+			//}
+			//serviceAmountMap := make(map[int]map[int]*fms.ContractServiceAmount, 0)
+			//for _, v := range serviceAmountList {
+			//	if _, ok := serviceAmountMap[v.ContractRegisterId]; !ok {
+			//		serviceAmountMap[v.ContractRegisterId] = make(map[int]*fms.ContractServiceAmount)
+			//	}
+			//	serviceAmountMap[v.ContractRegisterId][v.ProductId] = v
+			//}
+
+			// 重组汇总数据
+			summaryMap := make(map[int][]*fms.NotPaymentCensusInfo)
+			for i := range summaryList {
+				v := new(fms.NotPaymentCensusInfo)
+				v.InvoiceId = summaryList[i].InvoiceId
+				v.InvoiceDate = utils.TimeTransferString(utils.FormatDate, summaryList[i].InvoiceDate)
+				v.InvoiceAmount = summaryList[i].InvoiceAmount
+				v.SellerId = summaryList[i].SellerId
+				v.SellerName = summaryList[i].SellerName
+				v.SellerGroupId = summaryList[i].SellerGroupId
+				v.SellerGroupName = summaryList[i].SellerGroupName
+				v.SellerType = summaryList[i].ServiceProductId
+				v.PaymentId = summaryList[i].PaymentId
+				v.PaymentDate = utils.TimeTransferString(utils.FormatDate, summaryList[i].PaymentDate)
+				v.PaymentAmount = summaryList[i].PaymentAmount
+				v.PayType = summaryList[i].PayType
+				v.NotPaymentAmount = summaryList[i].InvoiceAmount - summaryList[i].PaymentAmount
+
+				summaryMap[summaryList[i].SummaryId] = append(summaryMap[summaryList[i].SummaryId], v)
+			}
+
+			// 货币列表
+			currencyOB := new(fms.CurrencyUnit)
+			currencyCond := `enable = 1`
+			currencyPars := make([]interface{}, 0)
+			currencyList, e := currencyOB.List(currencyCond, currencyPars)
+			if e != nil {
+				resp.FailMsg("获取失败", "获取货币列表失败, Err: "+e.Error(), c)
+				return
+			}
+			unitMap := make(map[string]string)
+			for i := range currencyList {
+				unitMap[currencyList[i].Code] = currencyList[i].UnitName
+			}
+
+			// 响应列表
+			for i := range registerList {
+				v := new(fms.NotPaymentCensusItem)
+				v.SummaryId = registerList[i].SummaryId
+				v.ContractRegisterId = registerList[i].ContractRegisterId
+				v.CompanyName = registerList[i].CompanyName
+				v.NewCompany = registerList[i].NewCompany
+				v.StartDate = utils.TimeTransferString(utils.FormatDate, registerList[i].StartDate)
+				v.EndDate = utils.TimeTransferString(utils.FormatDate, registerList[i].EndDate)
+				v.InvoicePaymentList = summaryMap[registerList[i].SummaryId]
+				v.ContractType = registerList[i].ContractType
+				v.ContractCode = registerList[i].ContractCode
+				v.ContractAmount = registerList[i].ContractAmount
+				v.UnitName = unitMap[registerList[i].CurrencyUnit]
+				v.ProductIds = registerList[i].ProductIds
+				respList = append(respList, v)
+			}
+		}()
+
+		// 开票到款金额合计(换算后)
+		var invoiceTotal, paymentTotal float64
+		wg.Add(1)
+		go func() {
+			defer wg.Done()
+
+			if len(summaryIds) == 0 {
+				return
+			}
+			amountTotalCond := `a.id IN ?`
+			amountTotalPars := make([]interface{}, 0)
+			amountTotalPars = append(amountTotalPars, summaryIds)
+			invoiceSum, e := fms.GetContractSummaryInvoicePaymentAmountTotal(amountTotalCond, amountTotalPars, 1)
+			if e != nil {
+				totalErr = fmt.Errorf("获取汇总开票金额合计失败, Err: %s", e.Error())
+				return
+			}
+			invoiceTotal, _ = strconv.ParseFloat(fmt.Sprintf("%.2f", invoiceSum), 64)
+			paymentSum, e := fms.GetContractSummaryInvoicePaymentAmountTotal(amountTotalCond, amountTotalPars, 2)
+			if e != nil {
+				totalErr = fmt.Errorf("获取汇总到款金额合计失败, Err: %s", e.Error())
+				return
+			}
+			paymentTotal, _ = strconv.ParseFloat(fmt.Sprintf("%.2f", paymentSum), 64)
+		}()
+
+		// 分币种金额统计
+		invoiceCurrencyTotals := make([]*fms.InvoiceListCurrencyTotal, 0)
+		paymentCurrencyTotals := make([]*fms.InvoiceListCurrencyTotal, 0)
+		notpaymentCurrencyTotals := make([]*fms.InvoiceListCurrencyTotal, 0)
+		//contractAmountCurrencyTotals := make([]*fms.InvoiceListCurrencyTotal, 0)
+		wg.Add(1)
+		go func() {
+			defer wg.Done()
+
+			currencyOB := new(fms.CurrencyUnit)
+			currencyCond := `enable = 1`
+			currencyPars := make([]interface{}, 0)
+			currencyList, e := currencyOB.List(currencyCond, currencyPars)
+			if e != nil {
+				totalGroupErr = fmt.Errorf("获取货币列表失败, Err: %s", e.Error())
+				return
+			}
+			unitMap := make(map[string]string)
+			for i := range currencyList {
+				unitMap[currencyList[i].Code] = currencyList[i].UnitName
+				invoiceCurrencyTotals = append(invoiceCurrencyTotals, &fms.InvoiceListCurrencyTotal{
+					Name:     currencyList[i].Name,
+					UnitName: currencyList[i].UnitName,
+					Code:     currencyList[i].Code,
+					FlagImg:  currencyList[i].FlagImg,
+				})
+				paymentCurrencyTotals = append(paymentCurrencyTotals, &fms.InvoiceListCurrencyTotal{
+					Name:     currencyList[i].Name,
+					UnitName: currencyList[i].UnitName,
+					Code:     currencyList[i].Code,
+					FlagImg:  currencyList[i].FlagImg,
+				})
+				notpaymentCurrencyTotals = append(notpaymentCurrencyTotals, &fms.InvoiceListCurrencyTotal{
+					Name:     currencyList[i].Name,
+					UnitName: currencyList[i].UnitName,
+					Code:     currencyList[i].Code,
+					FlagImg:  currencyList[i].FlagImg,
+				})
+				//contractAmountCurrencyTotals = append(contractAmountCurrencyTotals, &fms.InvoiceListCurrencyTotal{
+				//	Name:     currencyList[i].Name,
+				//	UnitName: currencyList[i].UnitName,
+				//	Code:     currencyList[i].Code,
+				//	FlagImg:  currencyList[i].FlagImg,
+				//})
+			}
+
+			if len(summaryIds) == 0 {
+				return
+			}
+			totalGroupCond := `a.id IN ?`
+			totalGroupPars := make([]interface{}, 0)
+			totalGroupPars = append(totalGroupPars, summaryIds)
+			invoiceSumGroup, e := fms.GetSummaryListCurrencySum(totalGroupCond, totalGroupPars, 1)
+			if e != nil {
+				totalGroupErr = fmt.Errorf("获取汇总货币合计开票金额失败, Err: %s", e.Error())
+				return
+			}
+			paymentSumGroup, e := fms.GetSummaryListCurrencySum(totalGroupCond, totalGroupPars, 2)
+			if e != nil {
+				totalGroupErr = fmt.Errorf("获取汇总货币合计到款金额失败, Err: %s", e.Error())
+				return
+			}
+			invoiceSumMap := make(map[string]float64)
+			paymentSumMap := make(map[string]float64)
+			//contractSumMap := make(map[string]float64)
+
+			for i := range invoiceSumGroup {
+				invoiceSumMap[invoiceSumGroup[i].CurrencyUnit] = invoiceSumGroup[i].OriginAmountTotal
+				continue
+			}
+			for i := range paymentSumGroup {
+				paymentSumMap[paymentSumGroup[i].CurrencyUnit] = paymentSumGroup[i].OriginAmountTotal
+				continue
+			}
+			for i := range invoiceCurrencyTotals {
+				a, _ := strconv.ParseFloat(fmt.Sprintf("%.2f", invoiceSumMap[invoiceCurrencyTotals[i].Code]), 64)
+				invoiceCurrencyTotals[i].Amount = a
+			}
+			for i := range paymentCurrencyTotals {
+				a, _ := strconv.ParseFloat(fmt.Sprintf("%.2f", paymentSumMap[paymentCurrencyTotals[i].Code]), 64)
+				paymentCurrencyTotals[i].Amount = a
+			}
+			for i := range notpaymentCurrencyTotals {
+				a, _ := strconv.ParseFloat(fmt.Sprintf("%.2f", invoiceSumMap[invoiceCurrencyTotals[i].Code] - paymentSumMap[paymentCurrencyTotals[i].Code]), 64)
+				notpaymentCurrencyTotals[i].Amount = a
+			}
+
+			//contractRegisters, err := fms.GetContractInfoByRegisterIds(queryRegisterIds)
+			//if err != nil {
+			//	resp.FailMsg("查询合同信息失败", "查询合同信息失败, Err: "+err.Error(), c)
+			//	return
+			//}
+			//for _, v := range contractRegisters {
+			//	if v.RMBRate == 0.0 {
+			//		v.RMBRate = 1
+			//	}
+			//	amount, _ := strconv.ParseFloat(fmt.Sprintf("%.2f", v.ContractAmount/v.RMBRate), 64)
+			//	contractAmount += amount
+			//	contractSumMap[v.CurrencyUnit] = v.ContractAmount
+			//}
+			//for _, v := range contractAmountCurrencyTotals {
+			//	v.Amount = contractSumMap[v.Code] - invoiceSumMap[v.Code]
+			//}
+
+		}()
+
+		wg.Wait()
+
+		if listErr != nil {
+			resp.FailMsg("获取失败", listErr.Error(), c)
+			return
+		}
+		if totalErr != nil {
+			resp.FailMsg("获取失败", totalErr.Error(), c)
+			return
+		}
+		if totalGroupErr != nil {
+			resp.FailMsg("获取失败", totalGroupErr.Error(), c)
+			return
+		}
+		results.DataList = respList
+		results.InvoiceTotal = invoiceTotal
+		results.PaymentTotal = paymentTotal
+		results.NotPaymentTotal = invoiceTotal - paymentTotal
+		results.NotPaymentCurrencyTotal = notpaymentCurrencyTotals
+	}
+	// 是否导出
+	if req.IsExport == 1 {
+		ExportNotPaymentCensusList(c, results)
+		return
+	}
+	page.SetTotal(total)
+	baseData := new(base.BaseData)
+	baseData.SetPage(page)
+	baseData.SetList(results)
+	resp.OkData("获取成功", baseData, c)
+}
+// ExportNotInvoiceCensusList 导出未开票统计列表
+func ExportNotInvoiceCensusList(c *gin.Context, results *fms.NotInvoicePaymentCensusResp) {
+	list := results.DataList
+	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
+	}
+	_ = sheet.SetColWidth(1, 1, 30)
+	_ = sheet.SetColWidth(3, 3, 30)
+
+	// 前三行-开票金额合计
+	rowA := sheet.AddRow()
+	cellAA := rowA.AddCell()
+	cellAA.SetString(fmt.Sprintf("未开票合计金额(换算后):%.2f(元)", results.NotInvoiceTotal))
+	rowBData := "未开票金额:"
+	for _, v := range results.NotInvoiceCurrencyTotal {
+		rowBData += fmt.Sprintf("%s%.2f(%s)  ", v.Name, v.Amount, v.UnitName)
+	}
+	rowB := sheet.AddRow()
+	rowB.AddCell().SetString(rowBData)
+	sheet.AddRow()
+
+	// 表头, 套餐动态获取
+	rowTitle := []string{"序号", "客户名称", "是否新客户", "合同有效期", "开票日", "开票金额", "到款日", "到款金额", "付款方式", "销售",
+		"销售组别", "销售类型"}
+	serviceTempCond := ``
+	serviceTempPars := make([]interface{}, 0)
+	serviceTempOB := new(fms.ContractServiceTemplate)
+	serviceTempList, e := serviceTempOB.List(serviceTempCond, serviceTempPars)
+	if e != nil {
+		resp.FailData("获取套餐模板列表失败", "Err:"+e.Error(), c)
+		return
+	}
+	serviceTempListMap := make(map[int]*fms.ContractServiceTemplate)
+	var serviceTempShow []*fms.ContractServiceTemplate
+	for i := range serviceTempList {
+		serviceTempListMap[serviceTempList[i].ServiceTemplateId] = serviceTempList[i]
+	}
+	for i := range serviceTempList {
+		if serviceTempList[i].ProductId == 1 {
+			rowTitle = append(rowTitle, serviceTempList[i].Title)
+			serviceTempShow = append(serviceTempShow, serviceTempList[i])
+		} else if serviceTempList[i].ProductId == 2 {
+			if serviceTempList[i].Title == "行业套餐" || serviceTempList[i].Title == "权益大套餐" || (serviceTempList[i].Title == "策略" && serviceTempListMap[serviceTempList[i].Pid].Pid == 0) {
+			} else if serviceTempList[i].Title == "医药" || serviceTempList[i].Title == "消费" || serviceTempList[i].Title == "科技" || serviceTempList[i].Title == "智造" {
+			} else {
+				serviceTempShow = append(serviceTempShow, serviceTempList[i])
+			}
+			if serviceTempList[i].Title == "行业套餐" || serviceTempList[i].Title == "45万" || serviceTempList[i].Title == "70万" {
+				continue
+			}
+
+			if serviceTempList[i].Pid > 0 && serviceTempListMap[serviceTempList[i].Pid].Pid > 0 {
+				continue
+			}
+
+			rowTitle = append(rowTitle, serviceTempList[i].Title)
+		}
+	}
+
+	hi := 0
+	insertHi := 0
+	titleRow := sheet.AddRow()
+	for i := range rowTitle {
+		v := titleRow.AddCell()
+		v.SetString(rowTitle[i])
+		v.SetStyle(style)
+		if rowTitle[i] != "权益大套餐" && rowTitle[i] != "医药" && rowTitle[i] != "消费" && rowTitle[i] != "科技" && rowTitle[i] != "智造" {
+			v.VMerge = 1
+			hi++
+		} else {
+			if insertHi == 0 {
+				insertHi = hi
+			}
+			v.HMerge = 1
+			titleRow.AddCell().SetString("")
+		}
+	}
+
+	// 新增一行放主观和客观
+	specialRow := sheet.AddRow()
+	for i := 0; i < hi; i++ {
+		if i == insertHi {
+			v1 := specialRow.AddCell()
+			v1.SetString("45万")
+			v1.SetStyle(style)
+			v1 = specialRow.AddCell()
+			v1.SetString("70万")
+			v1.SetStyle(style)
+			for j := 0; j < 8; j++ {
+				if j%2 == 0 {
+					v1 = specialRow.AddCell()
+					v1.SetString("主观")
+					v1.SetStyle(style)
+				} else {
+					v1 = specialRow.AddCell()
+					v1.SetString("客观")
+					v1.SetStyle(style)
+				}
+			}
+		} else {
+			v := specialRow.AddCell()
+			v.SetString("")
+		}
+	}
+
+	newCompanyMap := map[int]string{0: "否", 1: "是"}
+	sellerTypeMap := map[int]string{1: "FICC销售", 2: "权益销售"}
+	for k, v := range list {
+		dataRow := sheet.AddRow()
+		// 前四个单元格根据每行开票到款条数向下合并
+		l := len(v.InvoicePaymentList)
+		mergeRowNum := l - 1
+		// 序号
+		sortNum := k + 1
+		colA := dataRow.AddCell()
+		colA.VMerge = mergeRowNum
+		colA.SetString(fmt.Sprint(sortNum))
+		// 客户名称
+		colB := dataRow.AddCell()
+		colB.VMerge = mergeRowNum
+		colB.SetString(v.CompanyName)
+		// 是否新客户
+		colC := dataRow.AddCell()
+		colC.VMerge = mergeRowNum
+		colC.SetString(newCompanyMap[v.NewCompany])
+		// 合同有效期
+		colD := dataRow.AddCell()
+		colD.VMerge = mergeRowNum
+		colD.SetString(fmt.Sprint(v.StartDate, "至", v.EndDate))
+		// 开票到款信息
+		for k2, v2 := range v.InvoicePaymentList {
+			rowData := []string{
+				v2.InvoiceDate,                                // 开票日
+				fmt.Sprint(v2.InvoiceAmount),                  // 开票金额
+				v2.PaymentDate,                                // 到款日
+				fmt.Sprint(v2.PaymentAmount),                  // 到款金额
+				fms.ContractPaymentPayTypeNameMap[v2.PayType], // 付款方式
+				v2.SellerName,                                 // 销售
+				v2.SellerGroupName,                            // 组别
+				sellerTypeMap[v2.SellerType],                  // 销售类型
+			}
+			// 套餐金额信息
+			serviceTempShowAmount := make(map[int]string)
+			for i := range serviceTempShow {
+				for s2 := range v2.ServiceAmountList {
+					item := v2.ServiceAmountList[s2]
+					if item.ServiceTemplateId == serviceTempShow[i].ServiceTemplateId {
+						serviceTempShowAmount[serviceTempShow[i].ServiceTemplateId] = fmt.Sprint(item.Amount)
+						break
+					} else if serviceTempShow[i].Pid == item.ServiceTemplateId {
+						serviceTempShowAmount[serviceTempShow[i].ServiceTemplateId] = fmt.Sprint(item.Amount / 2)
+						break
+					}
+				}
+			}
+			for i := range serviceTempShow {
+				sa := ""
+				if am, ok := serviceTempShowAmount[serviceTempShow[i].ServiceTemplateId]; ok {
+					sa = am
+				}
+				rowData = append(rowData, sa)
+			}
+			// 首行开票到款
+			if k2 == 0 {
+				for i := range rowData {
+					dataRow.AddCell().SetString(rowData[i])
+				}
+				continue
+			}
+			// 其他行开票到款, 加四列空的单元格用于合并
+			dataRowExtra := sheet.AddRow()
+			for i := 0; i < 4; i++ {
+				dataRowExtra.AddCell()
+			}
+			for i := range rowData {
+				dataRowExtra.AddCell().SetString(rowData[i])
+			}
+		}
+	}
+
+	// 输出文件
+	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)
+}
+
+// IncomeList
+// @Title 业务收入统计表
+// @Description 获取业务收入统计表接口
+// @Param   ListParam		query	int		false	"套餐类型: 0-月度; 1-季度; 2-半年度;3-年度;4-月度累计"
+// @Success 200 {object} fms.CensusIncomeChartResp
+// @router /census/income/list [get]
+func (this *InvoicePaymentController) IncomeList(c *gin.Context) {
+	var req fms.IncomeListReq
+	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
+	}
+	//收入统计
+	var incomeList models.CensusIncomeChartResp
+	ch := make(chan models.CensusIncomeChartResp, 1)
+	go getCensusIncomeListV2(ch, req)
+
+	for v := range ch {
+		incomeList = v
+		close(ch)
+	}
+	// 是否导出
+	if req.IsExport == 1 {
+		ExportIncomeList(c, incomeList.DataList)
+		return
+	}
+	resp.OkData("获取成功", incomeList, c)
+}
+
+func getCensusIncomeListV2(ch chan models.CensusIncomeChartResp, req fms.IncomeListReq) (incomeChart models.CensusIncomeChartResp, err error) {
+	defer func() {
+		if err != nil {
+			global.LOG.Error(err)
+			if err != utils.ErrNoRow{
+				go alarm_msg.SendAlarmMsg("获取业务收入金额统计数据异常,Err:"+err.Error(), 3)
+			}
+		}
+		ch <- incomeChart
+	}()
+	//todayStr := utils.GetToday("20060102")
+	//key := "admin:home:fmsIncomeList:" + todayStr
+	//
+	//redisJsonData, redisErr := global.Redis.Get(context.TODO(), key).Result()
+	//if redisErr != nil {
+
+	//获取最新的开票到款日期
+	cond := ``
+	historyCond := ``
+	pars := make([]interface{}, 0)
+	historyPars := make([]interface{}, 0)
+
+	if req.SellerIds != "" {
+		sellerIds := strings.Split(req.SellerIds, ",")
+		cond += ` AND (a.seller_id in ? )`
+		historyCond += ` AND (seller_id in ? )`
+		pars = append(pars, sellerIds)
+		historyPars = append(historyPars, sellerIds)
+	}
+	if req.CompanyType == 1 {
+		cond += ` AND b.contract_type = 1 `
+		historyCond += ` AND new_company = 1`
+	} else if req.CompanyType == 2 {
+		cond += ` AND b.contract_type IN (2,3,4) `
+		historyCond += ` AND new_company = 0`
+	}
+
+	var latestTime time.Time
+
+	invoiceItem, err := fms.GetLatestIncome(cond, pars)
+	if err != nil && err != utils.ErrNoRow {
+		err = fmt.Errorf("获取最新的开票或到款日期, Err: %s", err.Error())
+		return
+	}
+	latestTime = invoiceItem.InvoiceDate
+
+	if err == utils.ErrNoRow {
+		historyItem, e := fms.GetLatestHistoryIncome(historyCond, historyPars)
+		if e != nil && e != utils.ErrNoRow {
+			err = fmt.Errorf("获取最新的历史开票或到款日期, Err: %s", err.Error())
+			return
+		}
+		latestTime = historyItem.InvoiceDate
+	}
+
+	if latestTime.IsZero() {
+		latestTime = time.Now()
+	}
+
+	latestTime = latestTime.AddDate(0, 0, -latestTime.Day()+1)
+
+	var dateSlice []string
+	var totalMoneySlice, prevTotalMoneySlice []float64
+	var yoySlice []string
+	var yearNum, monthNum int
+	var reqStartDate, reqEndDate time.Time
+	historyTime, _ := time.Parse(utils.FormatDate, "2023-04-01")
+
+	if req.StartDate != "" && req.EndDate != "" {
+		st := fmt.Sprint(req.StartDate, "-01 00:00:00")
+		ed := fmt.Sprint(req.EndDate, "-01 23:59:59")
+		reqStartDate, _ = time.Parse(utils.FormatDateTime, st)
+		reqEndDate, _ = time.Parse(utils.FormatDateTime, ed)
+		if reqEndDate.After(latestTime) {
+			yearNum = latestTime.Year() - reqStartDate.Year()
+			monthNum = int(latestTime.Month() - reqStartDate.Month())
+		} else {
+			yearNum = reqEndDate.Year() - reqStartDate.Year()
+			monthNum = int(reqEndDate.Month() - reqStartDate.Month())
+		}
+	} else {
+		yearNum = latestTime.Year() - 2020
+		monthNum = int(latestTime.Month() - 1)
+	}
+
+	if yearNum < 0 {
+		yearNum = -yearNum
+	}
+	if monthNum < 0 {
+		monthNum = -monthNum
+	}
+	numMonth := yearNum*12 + monthNum //共存在多少个月
+	//if req.ListParam == "1" {
+	//	numMonth = numMonth / 3
+	//} else if req.ListParam == "2" {
+	//	numMonth = numMonth / 6
+	//} else if req.ListParam == "3" {
+	//	numMonth = numMonth / 12
+	//}
+	// 累计值
+	var accumulate float64
+	var partAccumulate float64
+	var historyAccumulate float64
+	var partHistoryAccumulate float64
+	//dataList := make([]*fms.IncomeSummaryItem, 0)
+	//historydataList := make([]*fms.IncomeSummaryItem, 0)
+	fmt.Println("numMonth:", numMonth)
+	fmt.Println("InvoiceDate:", latestTime)
+
+	var j int
+	for i := 0; i <= numMonth; i++ {
+		//timeNow, _ := time.Parse("2006-01", time.Now().Format("2006-01"))
+
+		var endDateTime time.Time
+		var prevEndDateTime time.Time
+		var prevStartDate, prevEndDate string
+		var startDate, endDate string
+		//开始日期
+		if req.StartDate != "" && req.EndDate != "" {
+			startDate = reqStartDate.AddDate(0, i, 0).Format("2006-01")
+			prevStartDate = reqStartDate.AddDate(-1, i, 0).Format("2006-01")
+		} else {
+			startDate = latestTime.AddDate(0, i-numMonth, 0).Format("2006-01")
+			prevStartDate = latestTime.AddDate(-1, i-numMonth, 0).Format("2006-01")
+		}
+		startDate = fmt.Sprint(startDate, "-01")
+		prevStartDate = fmt.Sprint(prevStartDate, "-01")
+		startDateTime, _ := time.Parse(utils.FormatDate, startDate)
+		prevStartDateTime, _ := time.Parse(utils.FormatDate, prevStartDate)
+
+		//结束日期
+		if req.StartDate != "" && req.EndDate != "" {
+			endDateTime = reqStartDate.AddDate(0, i+1, -1)
+			prevEndDateTime = reqStartDate.AddDate(-1, i+1, -1)
+			if reqEndDate.After(latestTime) {
+				endDateTime = latestTime.AddDate(0, i-numMonth+1, -1)
+				prevEndDateTime = latestTime.AddDate(-1, i-numMonth+1, -1)
+			}
+		} else {
+			endDateTime = latestTime.AddDate(0, i-numMonth+1, -1)
+			prevEndDateTime = latestTime.AddDate(-1, i-numMonth+1, -1)
+		}
+		endDate = endDateTime.Format(utils.FormatDate)
+		prevEndDate = prevEndDateTime.Format(utils.FormatDate)
+
+		cond := `1 = 1`
+		histrtyCond := `1 = 1`
+		pars := make([]interface{}, 0)
+		historyPars := make([]interface{}, 0)
+
+		prevCond := `1 = 1`
+		prevHistoryCond := `1 = 1`
+		prevPars := make([]interface{}, 0)
+		prevHistoryPars := make([]interface{}, 0)
+
+		if req.CompanyType == 1 {
+			cond += ` AND b.contract_type = 1 `
+			prevCond += ` AND b.contract_type = 1 `
+			histrtyCond += ` AND new_company = 1 `
+			prevHistoryCond += ` AND new_company = 1 `
+		} else if req.CompanyType == 2 {
+			cond += ` AND b.contract_type IN (2,3,4) `
+			prevCond += ` AND b.contract_type IN (2,3,4) `
+			histrtyCond += ` AND new_company = 0 `
+			prevHistoryCond += ` AND new_company = 0 `
+		}
+
+		if req.SellerIds != "" {
+			sellerIds := strings.Split(req.SellerIds, ",")
+			cond += ` AND (c.seller_id in ? OR d.seller_id in ?)`
+			pars = append(pars, sellerIds, sellerIds)
+			prevCond += ` AND (c.seller_id in ? OR d.seller_id in ?)`
+			prevPars = append(prevPars, sellerIds, sellerIds)
+			histrtyCond += ` AND seller_id in ? `
+			prevHistoryCond += ` AND seller_id in ? `
+			historyPars = append(historyPars, sellerIds)
+			prevHistoryPars = append(prevHistoryPars, sellerIds)
+		}
+		//fmt.Println("i:",i)
+		//fmt.Println("j:",j)
+		{
+			//本期
+			st := fmt.Sprint(startDate, " 00:00:00")
+			ed := fmt.Sprint(endDate, " 23:59:59")
+			//校验日期,分段查询
+			if startDateTime.After(historyTime) || startDateTime.Equal(historyTime) {
+				//全部走新查询
+				//fmt.Println("新查询")
+				cond += ` AND ((c.invoice_time BETWEEN ? AND ?) or (d.invoice_time BETWEEN ? AND ?))`
+				pars = append(pars, st, ed, st, ed)
+				summaryIds, e := fms.GetInvoicePaymentCensusSummaryDataIds(cond, pars)
+				if e != nil {
+					return
+				}
+
+				// 开票到款金额合计(换算后)
+				var amountTotal float64
+
+				if len(summaryIds) > 0 {
+					amountCond := `a.id IN ? `
+					amountPars := make([]interface{}, 0)
+					amountPars = append(amountPars, summaryIds)
+					if req.SellerIds != "" {
+						sellerIds := strings.Split(req.SellerIds, ",")
+						amountCond += ` AND (( b.seller_id IN ? AND a.invoice_id <> 0 AND b.invoice_time BETWEEN ? AND ?)`
+						amountCond += `OR ( d.seller_id IN ? AND  a.payment_id <> 0 AND a.invoice_id = 0 AND d.invoice_time BETWEEN ? AND ?)) `
+						amountPars = append(amountPars, sellerIds,st, ed, sellerIds,st, ed)
+					} else {
+						amountCond += ` AND ((a.invoice_id <> 0 AND b.invoice_time BETWEEN ? AND ?)`
+						amountCond += `OR (a.payment_id <> 0 AND a.invoice_id = 0 AND d.invoice_time BETWEEN ? AND ?))`
+						amountPars = append(amountPars, st, ed, st, ed)
+					}
+					results, e := fms.GetContractSummaryIncomeAmount(amountCond, amountPars)
+					if e != nil {
+						err = fmt.Errorf("获取汇总数据失败, Err: %s", e.Error())
+						return
+					}
+					//dataList = append(dataList, results...)
+					var amountSum float64
+					for _, result := range results {
+						incomeChart.DataList = append(incomeChart.DataList, result)
+						amountSum += result.Amount
+						fmt.Println("result.Amount:", result.Amount)
+					}
+					amountTotal, _ = strconv.ParseFloat(fmt.Sprintf("%.2f", amountSum), 64)
+					accumulate += amountTotal
+					partAccumulate += amountTotal
+				}
+				if i == j || i == numMonth {
+					if req.ListParam == "4" {
+						totalMoneySlice = append(totalMoneySlice, accumulate)
+						if startDateTime.Month() == 12 {
+							accumulate = 0
+						}
+					} else if req.ListParam == "0" {
+						totalMoneySlice = append(totalMoneySlice, amountTotal)
+					} else if i > 0 || i == numMonth {
+						totalMoneySlice = append(totalMoneySlice, partAccumulate)
+						fmt.Println("partAccumulate:", partAccumulate)
+						partAccumulate = 0.0
+					}
+				}
+			} else if endDateTime.Before(historyTime) || endDateTime.Equal(historyTime) {
+				//全部走旧查询
+				//fmt.Println("旧查询")
+				//fmt.Println("st:",st)
+				//fmt.Println("ed:",ed)
+				histrtyCond += ` AND (invoice_time BETWEEN ? AND ? )`
+				historyPars = append(historyPars, st, ed)
+				//fmt.Println("st:",st)
+				//fmt.Println("ed:",ed)
+				// 开票到款金额合计(换算后)
+				var amountTotal float64
+				results, e := fms.GetIncomeHistory(histrtyCond, historyPars)
+				if e != nil {
+					err = fmt.Errorf("获取汇总数据失败, Err: %s", e.Error())
+					return
+				}
+				var amountSum float64
+				//dataList = append(dataList, results...)
+				for _, result := range results {
+					incomeChart.DataList = append(incomeChart.DataList, result)
+					amountSum += result.Amount
+				}
+				amountTotal, _ = strconv.ParseFloat(fmt.Sprintf("%.2f", amountSum), 64)
+				accumulate += amountTotal
+				partAccumulate += amountTotal
+
+				if i == j || i == numMonth {
+					if req.ListParam == "4" {
+						totalMoneySlice = append(totalMoneySlice, accumulate)
+						if startDateTime.Month() == 12 {
+							accumulate = 0
+						}
+					} else if req.ListParam == "0" {
+						totalMoneySlice = append(totalMoneySlice, amountTotal)
+					} else if i > 0 || i == numMonth {
+						totalMoneySlice = append(totalMoneySlice, partAccumulate)
+						partAccumulate = 0.0
+					}
+				}
+
+				//fmt.Println("partAccumulate:",partAccumulate)
+			}
+
+		}
+
+		{ //去年同期,用于计算同比值
+			prevSt := fmt.Sprint(prevStartDate, " 00:00:00")
+			prevEd := fmt.Sprint(prevEndDate, " 23:59:59")
+
+			//校验日期,分段查询
+			if prevStartDateTime.After(historyTime) || prevStartDateTime.Equal(historyTime) {
+				//全部走新查询
+				prevCond += ` AND ((b.invoice_time BETWEEN ? AND ?) or (d.invoice_time BETWEEN ? AND ?))`
+				prevPars = append(prevPars, prevSt, prevEd, prevSt, prevEd)
+				prevSummaryIds, e := fms.GetInvoicePaymentCensusSummaryDataIds(prevCond, prevPars)
+				if e != nil {
+					return
+				}
+
+				// 开票到款金额合计(换算后)
+				var prevAmountTotal float64
+
+				if len(prevSummaryIds) > 0 {
+					amountCond := `a.id IN ? `
+					amountPars := make([]interface{}, 0)
+					amountPars = append(amountPars, prevSummaryIds)
+					if req.SellerIds != "" {
+						sellerIds := strings.Split(req.SellerIds, ",")
+						amountCond += ` AND (( b.seller_id IN ? AND a.invoice_id <> 0 AND b.invoice_time BETWEEN ? AND ?)`
+						amountCond += `OR ( d.seller_id IN ? AND  a.payment_id <> 0 AND a.invoice_id = 0 AND d.invoice_time BETWEEN ? AND ?)) `
+						amountPars = append(amountPars, sellerIds,prevSt, prevEd, sellerIds,prevSt, prevEd)
+					} else {
+						amountCond += ` AND ((a.invoice_id <> 0 AND b.invoice_time BETWEEN ? AND ?)`
+						amountCond += `OR (a.payment_id <> 0 AND a.invoice_id = 0 AND d.invoice_time BETWEEN ? AND ?))`
+						amountPars = append(amountPars, prevSt, prevEd)
+					}
+					results, e := fms.GetContractSummaryIncomeAmount(amountCond, amountPars)
+					if e != nil {
+						err = fmt.Errorf("获取汇总数据失败, Err: %s", e.Error())
+						return
+					}
+					var amountSum float64
+					//historydataList = append(historydataList, results...)
+					for _, result := range results {
+						amountSum += result.Amount
+					}
+					prevAmountTotal, _ = strconv.ParseFloat(fmt.Sprintf("%.2f", amountSum), 64)
+					historyAccumulate += prevAmountTotal
+					partHistoryAccumulate += prevAmountTotal
+				}
+				if i == j || i == numMonth {
+					if req.ListParam == "4" {
+						prevTotalMoneySlice = append(prevTotalMoneySlice, historyAccumulate)
+						if prevStartDateTime.Month() == 12 {
+							historyAccumulate = 0
+						}
+					} else if req.ListParam == "0" {
+						prevTotalMoneySlice = append(prevTotalMoneySlice, prevAmountTotal)
+					} else if i > 0 || i == numMonth {
+						prevTotalMoneySlice = append(prevTotalMoneySlice, partHistoryAccumulate)
+						fmt.Println("partHistoryAccumulate:", partHistoryAccumulate)
+						partHistoryAccumulate = 0.0
+					}
+				}
+			} else if prevEndDateTime.Before(historyTime) || prevEndDateTime.Equal(historyTime) {
+				//全部走旧查询
+				fmt.Println("prevSt:", prevSt)
+				fmt.Println("prevEd:", prevEd)
+				prevHistoryCond += ` AND (invoice_time BETWEEN ? AND ?)`
+				prevHistoryPars = append(prevHistoryPars, prevSt, prevEd)
+				// 开票到款金额合计(换算后)
+				var amountTotal float64
+				results, e := fms.GetIncomeHistory(prevHistoryCond, prevHistoryPars)
+				if e != nil {
+					err = fmt.Errorf("获取汇总数据失败, Err: %s", e.Error())
+					return
+				}
+				//historydataList = append(historydataList, results...)
+				var amountSum float64
+				for _, result := range results {
+					amountSum += result.Amount
+				}
+				amountTotal, _ = strconv.ParseFloat(fmt.Sprintf("%.2f", amountSum), 64)
+				historyAccumulate += amountTotal
+				partHistoryAccumulate += amountTotal
+
+				if i == j || i == numMonth {
+					if req.ListParam == "4" {
+						prevTotalMoneySlice = append(prevTotalMoneySlice, historyAccumulate)
+						if prevStartDateTime.Month() == 12 {
+							historyAccumulate = 0
+						}
+					} else if req.ListParam == "0" {
+						prevTotalMoneySlice = append(prevTotalMoneySlice, amountTotal)
+					} else if i > 0 || i == numMonth {
+						prevTotalMoneySlice = append(prevTotalMoneySlice, partHistoryAccumulate)
+						fmt.Println("partHistoryAccumulate:", partHistoryAccumulate)
+						partHistoryAccumulate = 0.0
+					}
+				}
+				//fmt.Println("partHistoryAccumulate:",partHistoryAccumulate)
+			}
+			if req.ListParam == "1" && i == j {
+				if i == 0 {
+					dateSlice = append(dateSlice, startDateTime.AddDate(0, 2, 0).Format("06/01"))
+					j = j + 2
+				} else {
+					dateSlice = append(dateSlice, startDateTime.AddDate(0, 3, 0).Format("06/01"))
+					j = j + 3
+				}
+			} else if req.ListParam == "2" && i == j {
+				if i == 0 {
+					dateSlice = append(dateSlice, startDateTime.AddDate(0, 5, 0).Format("06/01"))
+					j = j + 5
+				} else {
+					dateSlice = append(dateSlice, startDateTime.AddDate(0, 6, 0).Format("06/01"))
+					j = j + 6
+				}
+			} else if req.ListParam == "3" && i == j {
+				if i == 0 {
+					dateSlice = append(dateSlice, startDateTime.AddDate(0, 11, 0).Format("06/01"))
+					j = j + 11
+				} else {
+					dateSlice = append(dateSlice, startDateTime.AddDate(0, 12, 0).Format("06/01"))
+					j = j + 12
+				}
+			} else if i == j {
+				dateSlice = append(dateSlice, startDateTime.Format("06/01"))
+				j++
+			}
+		}
+	}
+
+	fmt.Println("prevTotalMoneySlice:", len(prevTotalMoneySlice))
+	fmt.Println("totalMoneySlice:", len(totalMoneySlice))
+
+	//计算同比值
+	for i := range prevTotalMoneySlice {
+		var yoy float64
+		var yoyStr string
+		//fmt.Println("1:", prevTotalMoneySlice[i])
+		//fmt.Println("2:", totalMoneySlice[i])
+		//fmt.Println("3:", totalMoneySlice[i]-prevTotalMoneySlice[i])
+		totalMoneySlice[i], _ = strconv.ParseFloat(fmt.Sprintf("%.2f", totalMoneySlice[i]), 64)
+		if prevTotalMoneySlice[i] != 0 && totalMoneySlice[i] != 0 {
+			yoy = (totalMoneySlice[i] - prevTotalMoneySlice[i]) / prevTotalMoneySlice[i]
+			yoyStr = fmt.Sprintf("%.4f", yoy)
+
+			if i == len(prevTotalMoneySlice)-1 && i > 0 && req.ListParam == "3" {
+				fmt.Println("totalMoneySlice[i-1]:", totalMoneySlice[i-1])
+				yoy = (totalMoneySlice[i] - totalMoneySlice[i-1]) / totalMoneySlice[i-1]
+				yoyStr = fmt.Sprintf("%.4f", yoy)
+			}
+		}
+		yoySlice = append(yoySlice, yoyStr)
+	}
+
+	incomeChart.Title = "开票到款统计图"
+	incomeChart.Date = dateSlice
+	incomeChart.TotalMoney = totalMoneySlice
+	incomeChart.PrevTotalMoney = prevTotalMoneySlice
+	incomeChart.Yoy = yoySlice
+
+	//redisJsonData, err := json.Marshal(incomeChart)
+	//if err == nil {
+	//	global.Redis.SetEX(context.TODO(), key, string(redisJsonData), time.Minute*30)
+	//}
+	//} else {
+	//	err = json.Unmarshal([]byte(redisJsonData), &incomeChart)
+	//	if err != nil {
+	//		fmt.Println("近两年的收入统计数据,json转换失败")
+	//	}
+	//}
+
+	return
+}
+
+// ExportIncomeList 导出业务收入统计列表
+func ExportIncomeList(c *gin.Context, list []*fms.IncomeSummaryItem) {
+	// 生成Excel文件
+	xlsxFile := xlsx.NewFile()
+	style := xlsx.NewStyle()
+	alignment := xlsx.Alignment{
+		Horizontal: "center",
+		Vertical:   "center",
+		WrapText:   true,
+	}
+	style.Alignment = alignment
+	style.ApplyAlignment = true
+
+	sheetName := "业务收入统计表"
+	sheet, err := xlsxFile.AddSheet(sheetName)
+	if err != nil {
+		resp.FailData("新增Sheet失败", "Err:"+err.Error(), c)
+		return
+	}
+
+	// 数据表头
+	rowTitle := []string{"开票日期", "新客户(1)", "客户名称", "金额", "销售"}
+	titleRow := sheet.AddRow()
+	for i := range rowTitle {
+		v := titleRow.AddCell()
+		v.SetString(rowTitle[i])
+		v.SetStyle(style)
+	}
+	incomeSummaryItemList := make(fms.IncomeSummaryItemList, 0)
+	incomeSummaryItemList = list
+	sort.Sort(incomeSummaryItemList)
+	// 填充数据
+	for _, v := range incomeSummaryItemList {
+		dataRow := sheet.AddRow()
+		dataRow.AddCell().SetString(v.InvoiceDate.Format(utils.FormatDate)) // 开票日期
+		newCompany := 0
+		if v.ContractType == 1 {
+			newCompany = 1
+		}
+		dataRow.AddCell().SetString(strconv.Itoa(newCompany)) // 新客户
+		dataRow.AddCell().SetString(v.CompanyName)            // 客户名称
+		dataRow.AddCell().SetString(fmt.Sprint(v.Amount))     // 金额
+		dataRow.AddCell().SetString(v.SellerName)             // 销售员
+	}
+
+	// 输出文件
+	var buffer bytes.Buffer
+	_ = xlsxFile.Write(&buffer)
+	content := bytes.NewReader(buffer.Bytes())
+	randStr := time.Now().Format(utils.FormatDateTimeUnSpace)
+	fileName := sheetName + 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)
+}
+
+
+// ExportNotPaymentCensusList 导出开票未到款统计列表
+func ExportNotPaymentCensusList(c *gin.Context, results *fms.NotInvoicePaymentCensusResp) {
+	list := results.DataList
+	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
+	}
+	_ = sheet.SetColWidth(1, 1, 30)
+	_ = sheet.SetColWidth(3, 3, 30)
+
+	// 前三行-开票金额合计
+	rowA := sheet.AddRow()
+	cellAA := rowA.AddCell()
+	cellAA.SetString(fmt.Sprintf("开票未到款合计金额(换算后):%.2f(元)", results.InvoiceTotal))
+	rowBData := "已开票金额:"
+	for _, v := range results.InvoiceCurrencyTotal {
+		rowBData += fmt.Sprintf("%s%.2f(%s)  ", v.Name, v.Amount, v.UnitName)
+	}
+	rowB := sheet.AddRow()
+	rowB.AddCell().SetString(rowBData)
+	sheet.AddRow()
+
+	// 表头, 套餐动态获取
+	rowTitle := []string{"序号", "客户名称", "是否新客户", "合同有效期", "开票日", "开票金额", "到款日", "到款金额", "付款方式", "销售",
+		"销售组别", "销售类型"}
+	serviceTempCond := ``
+	serviceTempPars := make([]interface{}, 0)
+	serviceTempOB := new(fms.ContractServiceTemplate)
+	serviceTempList, e := serviceTempOB.List(serviceTempCond, serviceTempPars)
+	if e != nil {
+		resp.FailData("获取套餐模板列表失败", "Err:"+e.Error(), c)
+		return
+	}
+	serviceTempListMap := make(map[int]*fms.ContractServiceTemplate)
+	var serviceTempShow [] *fms.ContractServiceTemplate
+	for i := range serviceTempList {
+		serviceTempListMap[serviceTempList[i].ServiceTemplateId] = serviceTempList[i]
+	}
+	for i := range serviceTempList {
+		if serviceTempList[i].ProductId == 1 {
+			rowTitle = append(rowTitle, serviceTempList[i].Title)
+			serviceTempShow = append(serviceTempShow, serviceTempList[i])
+		}else if serviceTempList[i].ProductId == 2{
+			if serviceTempList[i].Title == "行业套餐" || serviceTempList[i].Title == "权益大套餐" || (serviceTempList[i].Title == "策略" && serviceTempListMap[serviceTempList[i].Pid].Pid==0){
+			}else if serviceTempList[i].Title == "医药" || serviceTempList[i].Title == "消费" || serviceTempList[i].Title == "科技" || serviceTempList[i].Title == "智造" {
+			}else {
+				serviceTempShow = append(serviceTempShow, serviceTempList[i])
+			}
+			if serviceTempList[i].Title == "行业套餐" || serviceTempList[i].Title == "45万" ||  serviceTempList[i].Title == "70万" {
+				continue
+			}
+
+			if serviceTempList[i].Pid > 0 &&  serviceTempListMap[serviceTempList[i].Pid].Pid > 0 {
+				continue
+			}
+
+			rowTitle = append(rowTitle, serviceTempList[i].Title)
+		}
+	}
+
+	hi := 0
+	insertHi := 0
+	titleRow := sheet.AddRow()
+	for i := range rowTitle {
+		v := titleRow.AddCell()
+		v.SetString(rowTitle[i])
+		v.SetStyle(style)
+		if rowTitle[i] != "权益大套餐" && rowTitle[i] != "医药" && rowTitle[i] != "消费" && rowTitle[i] != "科技" && rowTitle[i] != "智造" {
+			v.VMerge = 1
+			hi ++
+		}else{
+			if insertHi == 0 {
+				insertHi = hi
+			}
+			v.HMerge = 1
+			titleRow.AddCell().SetString("")
+		}
+	}
+
+	// 新增一行放主观和客观
+	specialRow := sheet.AddRow()
+	for i:=0; i< hi; i++ {
+		if i == insertHi {
+			v1 := specialRow.AddCell()
+			v1.SetString("45万")
+			v1.SetStyle(style)
+			v1 = specialRow.AddCell()
+			v1.SetString("70万")
+			v1.SetStyle(style)
+			for j:=0; j<8;j++ {
+				if j%2 ==0 {
+					v1 = specialRow.AddCell()
+					v1.SetString("主观")
+					v1.SetStyle(style)
+				}else{
+					v1 = specialRow.AddCell()
+					v1.SetString("客观")
+					v1.SetStyle(style)
+				}
+			}
+		}else{
+			v := specialRow.AddCell()
+			v.SetString("")
+		}
+	}
+
+	newCompanyMap := map[int]string{0: "否", 1: "是"}
+	sellerTypeMap := map[int]string{1:"FICC销售", 2:"权益销售"}
+	for k, v := range list {
+		dataRow := sheet.AddRow()
+		// 前四个单元格根据每行开票到款条数向下合并
+		l := len(v.InvoicePaymentList)
+		mergeRowNum := l - 1
+		// 序号
+		sortNum := k + 1
+		colA := dataRow.AddCell()
+		colA.VMerge = mergeRowNum
+		colA.SetString(fmt.Sprint(sortNum))
+		// 客户名称
+		colB := dataRow.AddCell()
+		colB.VMerge = mergeRowNum
+		colB.SetString(v.CompanyName)
+		// 是否新客户
+		colC := dataRow.AddCell()
+		colC.VMerge = mergeRowNum
+		colC.SetString(newCompanyMap[v.NewCompany])
+		// 合同有效期
+		colD := dataRow.AddCell()
+		colD.VMerge = mergeRowNum
+		colD.SetString(fmt.Sprint(v.StartDate, "至", v.EndDate))
+		// 开票到款信息
+		for k2, v2 := range v.InvoicePaymentList {
+			rowData := []string{
+				v2.InvoiceDate,                                // 开票日
+				fmt.Sprint(v2.InvoiceAmount),                  // 开票金额
+				v2.PaymentDate,                                // 到款日
+				fmt.Sprint(v2.PaymentAmount),                  // 到款金额
+				fms.ContractPaymentPayTypeNameMap[v2.PayType], // 付款方式
+				v2.SellerName,                                 // 销售
+				v2.SellerGroupName,                            // 组别
+				sellerTypeMap[v2.SellerType],                  // 销售类型
+			}
+			// 套餐金额信息
+			serviceTempShowAmount := make(map[int]string)
+			for i := range serviceTempShow {
+				for s2 := range v2.ServiceAmountList {
+					item := v2.ServiceAmountList[s2]
+					if item.ServiceTemplateId == serviceTempShow[i].ServiceTemplateId {
+						serviceTempShowAmount[serviceTempShow[i].ServiceTemplateId] = fmt.Sprint(item.Amount)
+						break
+					}else if serviceTempShow[i].Pid == item.ServiceTemplateId {
+						serviceTempShowAmount[serviceTempShow[i].ServiceTemplateId] = fmt.Sprint(item.Amount/2)
+						break
+					}
+				}
+			}
+			for i := range serviceTempShow {
+				sa := ""
+				if am, ok :=  serviceTempShowAmount[serviceTempShow[i].ServiceTemplateId]; ok {
+					sa = am
+				}
+				rowData = append(rowData, sa)
+			}
+			// 首行开票到款
+			if k2 == 0 {
+				for i := range rowData {
+					dataRow.AddCell().SetString(rowData[i])
+				}
+				continue
+			}
+			// 其他行开票到款, 加四列空的单元格用于合并
+			dataRowExtra := sheet.AddRow()
+			for i := 0; i < 4; i++ {
+				dataRowExtra.AddCell()
+			}
+			for i := range rowData {
+				dataRowExtra.AddCell().SetString(rowData[i])
+			}
+		}
+	}
+
+	// 输出文件
+	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)
+}
+
+func (ct *InvoicePaymentController) NotInvoiceList2(c *gin.Context) {
+	var req fms.InvoicePaymentCensusListReq
+	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 := `1 = 1`
+	pars := make([]interface{}, 0)
+	// 客户姓名/合同编号
+	if req.Keyword != "" {
+		kw := "%" + req.Keyword + "%"
+		cond += ` AND (b.company_name LIKE ? OR b.contract_code LIKE ?)`
+		pars = append(pars, kw, kw)
+	}
+	if req.SellerIds != "" {
+		sellerIds := strings.Split(req.SellerIds, ",")
+		cond += ` AND (c.seller_id in ?)`
+		pars = append(pars, sellerIds)
+	}
+	// 套餐筛选
+	if req.ServiceTypes != "" {
+		serviceTypes := strings.Split(req.ServiceTypes, ",")
+		tempRegisterIds, e := fms.GetContractRegisterIdsByTempId(serviceTypes)
+		if e != nil {
+			resp.FailMsg("获取失败", "获取合同登记IDs失败, Err: "+e.Error(), c)
+			return
+		}
+		if len(tempRegisterIds) > 0 {
+			cond += ` AND a.register_id IN ?`
+			pars = append(pars, tempRegisterIds)
+		} else {
+			cond += ` AND 1 = 2`
+		}
+	}
+
+	if req.ListParam == 1 {
+		cond += ` AND a.service_product_id = 1 `
+	} else if req.ListParam == 2 {
+		cond += ` AND a.service_product_id = 2 `
+	}
+
+	// 开票到款日期
+	//if req.TimeType != 0 {
+	//	if req.TimeType == 1 &&  req.StartDate != "" && req.EndDate != "" {
+	//		st := fmt.Sprint(req.StartDate, " 00:00:00")
+	//		ed := fmt.Sprint(req.EndDate, " 23:59:59")
+	//		cond += ` AND (c.invoice_time BETWEEN ? AND ?) `
+	//		pars = append(pars, st, ed)
+	//	}else if req.TimeType == 2 &&  req.StartDate != "" && req.EndDate != "" {
+	//		st := fmt.Sprint(req.StartDate, " 00:00:00")
+	//		ed := fmt.Sprint(req.EndDate, " 23:59:59")
+	//		cond += ` AND (d.invoice_time BETWEEN ? AND ?) `
+	//		pars = append(pars, st, ed)
+	//	}else if req.TimeType == 3 &&  req.StartDate != "" && req.EndDate != "" {
+	//		st := fmt.Sprint(req.StartDate, " 00:00:00")
+	//		ed := fmt.Sprint(req.EndDate, " 23:59:59")
+	//		cond += ` AND (c.invoice_time BETWEEN ? AND ?) AND (d.invoice_time BETWEEN ? AND ?) `
+	//		pars = append(pars, st, ed, st, ed)
+	//	}
+	//} else if req.StartDate != "" && req.EndDate != "" {
+	//	st := fmt.Sprint(req.StartDate, " 00:00:00")
+	//	ed := fmt.Sprint(req.EndDate, " 23:59:59")
+	//	cond += ` AND ((c.invoice_time BETWEEN ? AND ?) or (d.invoice_time BETWEEN ? AND ?))`
+	//	pars = append(pars, st, ed, st, ed)
+	//}
+
+	//if req.HasInvoice == "1" {
+	//	cond += ` AND a.invoice_id > 0 `
+	//}else if req.HasInvoice == "0" {
+	//	cond += ` AND a.invoice_id = 0 `
+	//}
+	//
+	//if req.HasPayment == "1" {
+	//	cond += ` AND a.payment_id > 0 `
+	//}else if req.HasPayment == "0" {
+	//	cond += ` AND a.payment_id = 0 `
+	//}
+
+	page := new(base.Page)
+	page.SetPageSize(req.PageSize)
+	page.SetCurrent(req.Current)
+	//排序
+	if req.SortType == "" {
+		req.SortType = "asc"
+	}
+	if req.SortType != "desc" && req.SortType != "asc" {
+		resp.Fail("排序类型不正确", c)
+		return
+	}
+	if req.SortParam == "" {
+		page.AddOrderItem(base.OrderItem{Column: "e.start_date", Asc: true})
+	} else if req.SortParam == "start_date" {
+		if req.SortType == "asc" {
+			page.AddOrderItem(base.OrderItem{Column: "e.start_date", Asc: true})
+		} else {
+			page.AddOrderItem(base.OrderItem{Column: "e.start_date", Asc: false})
+		}
+	} else if req.SortParam == "end_date" {
+		if req.SortType == "asc" {
+			page.AddOrderItem(base.OrderItem{Column: "e.end_date", Asc: true})
+		} else {
+			page.AddOrderItem(base.OrderItem{Column: "e.end_date", Asc: false})
+		}
+	} else {
+		resp.Fail("排序字段不正确", c)
+		return
+	}
+
+	if req.IsExport == 1 {
+		page.SetPageSize(10000)
+		page.SetCurrent(1)
+	}
+
+	cond += ` AND b.payment_amount > b.invoiced_amount AND b.contract_amount <> b.invoiced_amount `
+	registerList, total, e := fms.GetInvoiceCensusPageList(page, cond, pars)
+	if e != nil {
+		resp.FailMsg("获取失败", "获取商品到款统计列表总数失败, Err: "+e.Error(), c)
+		return
+	}
+	queryRegisterIds := make([]int, 0)
+	for _, v := range registerList {
+		queryRegisterIds = append(queryRegisterIds, v.ContractRegisterId)
+	}
+	//fmt.Println("queryRegisterIds:",queryRegisterIds)
+	results := new(fms.NotInvoicePaymentCensusResp)
+	if len(queryRegisterIds) > 0 {
+		// 获取合同的套餐金额信息
+		serviceAmountList, e := fms.GetContractServiceAmountByContractRegisterIds(queryRegisterIds)
+		if e != nil {
+			resp.FailData("获取合同的套餐金额信息失败", "Err:"+e.Error(), c)
+			return
+		}
+		serviceAmountMap := make(map[int]map[int]*fms.ContractServiceAmount, 0)
+		for _, v := range serviceAmountList {
+			if _, ok := serviceAmountMap[v.ContractRegisterId]; !ok {
+				serviceAmountMap[v.ContractRegisterId] = make(map[int]*fms.ContractServiceAmount)
+			}
+			serviceAmountMap[v.ContractRegisterId][v.ProductId] = v
+		}
+
+		// 获取汇总数据IDs, 用于查询合计数据
+		summaryIdsCond := cond
+		summaryIdsPars := pars
+		if req.SellerIds != "" {
+			sellerIds := strings.Split(req.SellerIds, ",")
+			summaryIdsCond += ` AND c.seller_id in ? AND a.payment_id <> 0 AND (d.origin_amount > c.origin_amount OR c.origin_amount IS NULL) `
+			summaryIdsPars = append(summaryIdsPars, sellerIds)
+		} else {
+			summaryIdsCond += ` AND a.payment_id <> 0  AND (d.origin_amount > c.origin_amount OR c.origin_amount IS NULL) `
+			summaryIdsPars = append(summaryIdsPars)
+		}
+		summaryIds, e := fms.GetInvoicePaymentCensusSummaryDataIds(summaryIdsCond, summaryIdsPars)
+		if e != nil {
+			resp.FailMsg("获取失败", "获取商品到款汇总IDs失败, Err: "+e.Error(), c)
+			return
+		}
+
+		//fmt.Println("summaryIds:",summaryIds)
+		var listErr, totalErr, totalGroupErr error
+		wg := sync.WaitGroup{}
+
+		// 响应列表
+		respList := make([]*fms.NotPaymentCensusItem, 0)
+		summaryList := make([]*fms.NotInvoicePaymentSummaryItem, 0)
+		wg.Add(1)
+		go func() {
+			defer wg.Done()
+
+			// 获取汇总数据
+			summaryCond := cond
+			summaryCond += ` AND a.register_id IN ?`
+			summaryPars := pars
+			summaryPars = append(summaryPars, queryRegisterIds)
+			//if req.SellerIds != "" {
+			//	sellerIds := strings.Split(req.SellerIds, ",")
+			//	summaryCond += ` AND c.seller_id in ? AND a.payment_id <> 0 AND (d.origin_amount > c.origin_amount OR c.origin_amount IS NULL) `
+			//	summaryPars = append(summaryPars, sellerIds, sellerIds)
+			//} else {
+			//	summaryCond += ` AND a.payment_id <> 0 AND (d.origin_amount > c.origin_amount OR c.origin_amount IS NULL) `
+			//	summaryPars = append(summaryPars)
+			//}
+
+			summaryData, e := fms.GetNotInvoicePaymentCensusSummaryData(summaryCond, summaryPars)
+			if e != nil {
+				resp.FailMsg("获取失败", "获取商品到款汇总列表失败, Err: "+e.Error(), c)
+				return
+			}
+			summaryList = summaryData
+			//summaryIds := make([]int, 0)
+			//paymentIds := make([]int, 0)
+			//for i := range summaryList {
+			//	//summaryIds = append(summaryIds, summaryList[i].SummaryId)
+			//}
+			NotInvoiceSummaryMap := make(map[int][]*fms.NotInvoicePaymentSummaryItem, 0)
+			for _, v := range summaryList {
+				NotInvoiceSummaryMap[v.RegisterId] = append(NotInvoiceSummaryMap[v.RegisterId], v)
+			}
+
+			// 重组汇总数据
+			summaryMap := make(map[int][]*fms.NotPaymentCensusInfo)
+			sellerList, e := crmService.GetSellerDepartmentListWithGroupAndTeam()
+			if e != nil {
+				resp.FailData("获取销售失败", "Err:"+e.Error(), c)
+				return
+			}
+			sellerMap := make(map[int]*crm.SellerAdminWithGroupTeam)
+			for i := range sellerList {
+				sellerMap[sellerList[i].SellerId] = sellerList[i]
+			}
+
+
+
+			// 货币列表
+			currencyOB := new(fms.CurrencyUnit)
+			currencyCond := `enable = 1`
+			currencyPars := make([]interface{}, 0)
+			currencyList, e := currencyOB.List(currencyCond, currencyPars)
+			if e != nil {
+				resp.FailMsg("获取失败", "获取货币列表失败, Err: "+e.Error(), c)
+				return
+			}
+			unitMap := make(map[string]string)
+			for i := range currencyList {
+				unitMap[currencyList[i].Code] = currencyList[i].UnitName
+			}
+
+			for registerId, list := range NotInvoiceSummaryMap {
+				for _, v := range list {
+					v.NotInvoicedAmountTotal = serviceAmountMap[registerId][v.ServiceProductId].ServiceAmount - v.InvoiceAmountTotal
+					if v.ServiceProductId == 1 {
+						v.SellerGroupId = sellerMap[v.SellerId].GroupId
+						v.SellerGroupName = sellerMap[v.SellerId].GroupName
+					} else {
+						v.RaiSellerGroupId = sellerMap[v.RaiSellerId].GroupId
+						v.RaiSellerGroupName = sellerMap[v.RaiSellerId].GroupName
+					}
+				}
+			}
+
+			// 响应列表
+			for i := range registerList {
+				v := new(fms.NotPaymentCensusItem)
+				v.SummaryId = registerList[i].SummaryId
+				v.ContractRegisterId = registerList[i].ContractRegisterId
+				v.CompanyName = registerList[i].CompanyName
+				v.NewCompany = registerList[i].NewCompany
+				v.StartDate = utils.TimeTransferString(utils.FormatDate, registerList[i].StartDate)
+				v.EndDate = utils.TimeTransferString(utils.FormatDate, registerList[i].EndDate)
+				v.InvoicePaymentList = summaryMap[registerList[i].SummaryId]
+				v.ContractType = registerList[i].ContractType
+				v.ContractCode = registerList[i].ContractCode
+				v.ContractAmount = registerList[i].ContractAmount
+				v.UnitName = unitMap[registerList[i].CurrencyUnit]
+				v.ProductIds = registerList[i].ProductIds
+				v.NotInvoiceTotal = registerList[i].ContractAmount - registerList[i].InvoicedAmount
+				v.NotInvoiceList = NotInvoiceSummaryMap[summaryList[i].RegisterId]
+				respList = append(respList, v)
+			}
+		}()
+
+		// 开票到款金额合计(换算后)
+		var invoiceTotal, paymentTotal, contractAmount float64
+		wg.Add(1)
+		go func() {
+			defer wg.Done()
+
+			if len(summaryIds) == 0 {
+				return
+			}
+			amountTotalCond := `a.id IN ?`
+			amountTotalPars := make([]interface{}, 0)
+			amountTotalPars = append(amountTotalPars, summaryIds)
+			invoiceSum, e := fms.GetContractSummaryInvoicePaymentAmountTotal(amountTotalCond, amountTotalPars, 1)
+			if e != nil {
+				totalErr = fmt.Errorf("获取汇总开票金额合计失败, Err: %s", e.Error())
+				return
+			}
+			invoiceTotal, _ = strconv.ParseFloat(fmt.Sprintf("%.2f", invoiceSum), 64)
+			paymentSum, e := fms.GetContractSummaryInvoicePaymentAmountTotal(amountTotalCond, amountTotalPars, 2)
+			if e != nil {
+				totalErr = fmt.Errorf("获取汇总到款金额合计失败, Err: %s", e.Error())
+				return
+			}
+			paymentTotal, _ = strconv.ParseFloat(fmt.Sprintf("%.2f", paymentSum), 64)
+		}()
+
+		// 分币种金额统计
+		invoiceCurrencyTotals := make([]*fms.InvoiceListCurrencyTotal, 0)
+		paymentCurrencyTotals := make([]*fms.InvoiceListCurrencyTotal, 0)
+		contractAmountCurrencyTotals := make([]*fms.InvoiceListCurrencyTotal, 0)
+		wg.Add(1)
+		go func() {
+			defer wg.Done()
+
+			currencyOB := new(fms.CurrencyUnit)
+			currencyCond := `enable = 1`
+			currencyPars := make([]interface{}, 0)
+			currencyList, e := currencyOB.List(currencyCond, currencyPars)
+			if e != nil {
+				totalGroupErr = fmt.Errorf("获取货币列表失败, Err: %s", e.Error())
+				return
+			}
+			unitMap := make(map[string]string)
+			for i := range currencyList {
+				unitMap[currencyList[i].Code] = currencyList[i].UnitName
+				invoiceCurrencyTotals = append(invoiceCurrencyTotals, &fms.InvoiceListCurrencyTotal{
+					Name:     currencyList[i].Name,
+					UnitName: currencyList[i].UnitName,
+					Code:     currencyList[i].Code,
+					FlagImg:  currencyList[i].FlagImg,
+				})
+				paymentCurrencyTotals = append(paymentCurrencyTotals, &fms.InvoiceListCurrencyTotal{
+					Name:     currencyList[i].Name,
+					UnitName: currencyList[i].UnitName,
+					Code:     currencyList[i].Code,
+					FlagImg:  currencyList[i].FlagImg,
+				})
+				contractAmountCurrencyTotals = append(contractAmountCurrencyTotals, &fms.InvoiceListCurrencyTotal{
+					Name:     currencyList[i].Name,
+					UnitName: currencyList[i].UnitName,
+					Code:     currencyList[i].Code,
+					FlagImg:  currencyList[i].FlagImg,
+				})
+			}
+
+			if len(summaryIds) == 0 {
+				return
+			}
+			totalGroupCond := `a.id IN ?`
+			totalGroupPars := make([]interface{}, 0)
+			totalGroupPars = append(totalGroupPars, summaryIds)
+			invoiceSumGroup, e := fms.GetSummaryListCurrencySum(totalGroupCond, totalGroupPars, 1)
+			if e != nil {
+				totalGroupErr = fmt.Errorf("获取汇总货币合计开票金额失败, Err: %s", e.Error())
+				return
+			}
+			paymentSumGroup, e := fms.GetSummaryListCurrencySum(totalGroupCond, totalGroupPars, 2)
+			if e != nil {
+				totalGroupErr = fmt.Errorf("获取汇总货币合计到款金额失败, Err: %s", e.Error())
+				return
+			}
+			invoiceSumMap := make(map[string]float64)
+			paymentSumMap := make(map[string]float64)
+			contractSumMap := make(map[string]float64)
+
+			for i := range invoiceSumGroup {
+				invoiceSumMap[invoiceSumGroup[i].CurrencyUnit] = invoiceSumGroup[i].OriginAmountTotal
+				continue
+			}
+			for i := range paymentSumGroup {
+				paymentSumMap[paymentSumGroup[i].CurrencyUnit] = paymentSumGroup[i].OriginAmountTotal
+				continue
+			}
+			for i := range invoiceCurrencyTotals {
+				a, _ := strconv.ParseFloat(fmt.Sprintf("%.2f", invoiceSumMap[invoiceCurrencyTotals[i].Code]), 64)
+				invoiceCurrencyTotals[i].Amount = a
+			}
+			for i := range paymentCurrencyTotals {
+				a, _ := strconv.ParseFloat(fmt.Sprintf("%.2f", paymentSumMap[paymentCurrencyTotals[i].Code]), 64)
+				paymentCurrencyTotals[i].Amount = a
+			}
+
+			contractRegisters, err := fms.GetContractInfoByRegisterIds(queryRegisterIds)
+			if err != nil {
+				resp.FailMsg("查询合同信息失败", "查询合同信息失败, Err: "+err.Error(), c)
+				return
+			}
+			for _, v := range contractRegisters {
+				if v.RMBRate == 0.0 {
+					v.RMBRate = 1
+				}
+				amount, _ := strconv.ParseFloat(fmt.Sprintf("%.2f", v.ContractAmount/v.RMBRate), 64)
+				contractAmount += amount
+				contractSumMap[v.CurrencyUnit] = v.ContractAmount
+			}
+			for _, v := range contractAmountCurrencyTotals {
+				v.Amount = contractSumMap[v.Code] - invoiceSumMap[v.Code]
+			}
+
+		}()
+
+		wg.Wait()
+
+		if listErr != nil {
+			resp.FailMsg("获取失败", listErr.Error(), c)
+			return
+		}
+		if totalErr != nil {
+			resp.FailMsg("获取失败", totalErr.Error(), c)
+			return
+		}
+		if totalGroupErr != nil {
+			resp.FailMsg("获取失败", totalGroupErr.Error(), c)
+			return
+		}
+		results.DataList = respList
+		results.InvoiceTotal = invoiceTotal
+		results.PaymentTotal = paymentTotal
+		results.NotInvoiceTotal = contractAmount - invoiceTotal
+		results.InvoiceCurrencyTotal = invoiceCurrencyTotals
+		results.PaymentCurrencyTotal = paymentCurrencyTotals
+		results.NotInvoiceCurrencyTotal = contractAmountCurrencyTotals
+	}
+
+	// 是否导出
+	if req.IsExport == 1 {
+		ExportNotInvoiceCensusList(c, results)
+		return
+	}
+	page.SetTotal(total)
+	baseData := new(base.BaseData)
+	baseData.SetPage(page)
+	baseData.SetList(results)
+	resp.OkData("获取成功", baseData, c)

+ 55 - 10
models/fms/contract_invoice.go

@@ -348,6 +348,11 @@ type InvoicePaymentCensusItem struct {
 	ContractType       int                         `json:"contract_type" description:"合同类型: 0-无 1-新签; 2-续约"`
 	ActualPayCompanies string                      `json:"actual_pay_companies" description:"该合同关联的所有代付方, 英文逗号拼接"`
 	InvoicePaymentList []*InvoicePaymentCensusInfo `json:"invoice_payment_list" description:"开票到款列表"`
+	ContractCode       string                      `gorm:"column:contract_code" json:"contract_code" description:"合同编号"`
+	ContractAmount     float64                     `gorm:"column:contract_amount" json:"contract_amount" description:"合同金额"`
+	UnitName           string                      `gorm:"unit_name" json:"unit_name" description:"单位名称"`
+	ProductIds         string                      `gorm:"column:product_ids" json:"product_ids" description:"产品ID:1-FICC; 2-权益, 如果两者都有,则用英文逗号拼接"`
+	NotInvoiceTotal    float64                     `json:"not_invoice_total" description:"未开票总金额(换算后)"`
 }
 
 // InvoicePaymentCensusInfo 开票到款统计信息
@@ -605,7 +610,7 @@ func GetDuplicateContractInvoiceDetailItemListWithType(companyName, startDate, e
 	err = global.DEFAULT_MYSQL.Table("contract_invoice as a ").
 		Select(" a.* ").
 		Joins(" JOIN contract_register as b ON a.contract_register_id = b.contract_register_id ").
-		Where(fmt.Sprintf("a.is_deleted = 0 AND b.company_name = '%s' AND b.start_date= '%s' AND b.end_date= '%s' AND b.is_deleted=0 AND (a.invoice_type=3 OR a.invoice_type=4) AND a.invoice_type = %v ",companyName, startDate, endDate, invoiceType)).
+		Where(fmt.Sprintf("a.is_deleted = 0 AND b.company_name = '%s' AND b.start_date= '%s' AND b.end_date= '%s' AND b.is_deleted=0 AND (a.invoice_type=3 OR a.invoice_type=4) AND a.invoice_type = %v ", companyName, startDate, endDate, invoiceType)).
 		Order("a.contract_invoice_id ASC").
 		Find(&list).Error
 	if err != nil {
@@ -631,7 +636,7 @@ func GetDuplicateContractInvoiceDetailItemList(companyName, startDate, endDate s
 		Select(" a.*,GROUP_CONCAT(c.service_template_id ORDER BY c.service_template_id ) AS template_ids ").
 		Joins(" JOIN contract_register as b ON a.contract_register_id = b.contract_register_id ").
 		Joins("JOIN contract_service AS c ON a.contract_register_id = c.contract_register_id").
-		Where(fmt.Sprintf("a.is_deleted = 0 AND b.company_name = '%s' AND b.start_date= '%s' AND b.end_date= '%s' AND b.is_deleted=0 AND (a.invoice_type=3 OR a.invoice_type=4) ",companyName, startDate, endDate)).
+		Where(fmt.Sprintf("a.is_deleted = 0 AND b.company_name = '%s' AND b.start_date= '%s' AND b.end_date= '%s' AND b.is_deleted=0 AND (a.invoice_type=3 OR a.invoice_type=4) ", companyName, startDate, endDate)).
 		Group("a.contract_register_id").
 		Order("a.contract_invoice_id ASC").
 		Find(&list).Error
@@ -642,15 +647,15 @@ func GetDuplicateContractInvoiceDetailItemList(companyName, startDate, endDate s
 }
 
 type IncomeListReq struct {
-	SellerIds    string `json:"seller_ids" form:"seller_ids" description:"销售ID,多个ID之间用逗号拼接"`
-	StartDate    string `json:"start_date" form:"start_date" binding:"omitempty,datetime=2006-01" description:"开始日期"`
-	EndDate      string `json:"end_date" form:"end_date" binding:"omitempty,datetime=2006-01" description:"结束日期"`
-	IsExport     int    `json:"is_export" form:"is_export" description:"是否导出: 0-否; 1-是"`
-	ListParam    string    `json:"list_param" form:"list_param" description:"套餐类型: 0-月度; 1-季度; 2-半年度;3-年度;4-月度累计"`
-	CompanyType     int    `json:"company_type" form:"company_type" description:"客户类型 0全部 1新客户 2老客户"`
+	SellerIds   string `json:"seller_ids" form:"seller_ids" description:"销售ID,多个ID之间用逗号拼接"`
+	StartDate   string `json:"start_date" form:"start_date" binding:"omitempty,datetime=2006-01" description:"开始日期"`
+	EndDate     string `json:"end_date" form:"end_date" binding:"omitempty,datetime=2006-01" description:"结束日期"`
+	IsExport    int    `json:"is_export" form:"is_export" description:"是否导出: 0-否; 1-是"`
+	ListParam   string `json:"list_param" form:"list_param" description:"套餐类型: 0-月度; 1-季度; 2-半年度;3-年度;4-月度累计"`
+	CompanyType int    `json:"company_type" form:"company_type" description:"客户类型 0全部 1新客户 2老客户"`
 }
 
-//获取最新的开票或到款日期
+// 获取最新的开票或到款日期
 func GetLatestIncome(condition string, pars []interface{}) (result *ContractInvoice, err error) {
 	sql := `SELECT
 	a.* 
@@ -663,4 +668,44 @@ WHERE
 	sql += `ORDER BY a.invoice_time DESC  `
 	err = global.DEFAULT_MYSQL.Raw(sql, pars...).First(&result).Error
 	return
-}
+}
+
+// NotPaymentCensusItem 商品到款统计信息
+type NotPaymentCensusItem struct {
+	SummaryId          int                     `json:"summary_id" description:"汇总ID"`
+	ContractRegisterId int                     `json:"contract_register_id" description:"登记ID"`
+	CompanyName        string                  `json:"company_name" description:"客户名称"`
+	NewCompany         int                     `json:"new_company" description:"是否为新客户: 0-否; 1-是"`
+	StartDate          string                  `json:"start_date" description:"合同开始日期"`
+	EndDate            string                  `json:"end_date" description:"合同结束日期"`
+	ServicesName       string                  `json:"services_name" description:"套餐信息字符串拼接"`
+	ContractType       int                     `json:"contract_type" description:"合同类型: 0-无 1-新签; 2-续约"`
+	ActualPayCompanies string                  `json:"actual_pay_companies" description:"该合同关联的所有代付方, 英文逗号拼接"`
+	InvoicePaymentList []*NotPaymentCensusInfo `json:"invoice_payment_list" description:"开票到款列表"`
+	ContractCode       string                  `gorm:"column:contract_code" json:"contract_code" description:"合同编号"`
+	ContractAmount     float64                 `gorm:"column:contract_amount" json:"contract_amount" description:"合同金额"`
+	UnitName           string                  `gorm:"unit_name" json:"unit_name" description:"单位名称"`
+	ProductIds         string                  `gorm:"column:product_ids" json:"product_ids" description:"产品ID:1-FICC; 2-权益, 如果两者都有,则用英文逗号拼接"`
+	NotInvoiceTotal    float64                 `json:"not_invoice_total" description:"未开票总金额(换算后)"`
+	NotInvoiceList    []*NotInvoicePaymentSummaryItem     `json:"not_invoice_list" description:"未开票invoice列表"`
+}
+
+// NotPaymentCensusInfo 开票到款统计信息
+type NotPaymentCensusInfo struct {
+	InvoiceId         int                                 `json:"invoice_id" description:"开票ID"`
+	InvoiceDate       string                              `json:"invoice_time" description:"开票日期"`
+	InvoiceAmount     float64                             `json:"invoice_amount" description:"开票金额"`
+	SellerId          int                                 `json:"seller_id" description:"销售ID"`
+	SellerName        string                              `json:"seller_name" description:"销售名称"`
+	SellerGroupId     int                                 `json:"seller_group_id" description:"销售组别ID"`
+	SellerGroupName   string                              `json:"seller_group_name" description:"销售组别名称"`
+	PaymentId         int                                 `json:"payment_id" description:"到款ID"`
+	PaymentDate       string                              `json:"payment_date" description:"到款日期"`
+	PaymentAmount     float64                             `json:"payment_amount" description:"到款金额"`
+	PayType           int                                 `json:"pay_type" description:"付款方式:0-无;1-年付;2-半年付;3-季付;4-次付;5-异常"`
+	ServiceAmountList []*ContractPaymentServiceAmountItem `json:"service_amount_list" description:"到款套餐金额分配信息"`
+	SellerType        int                                 `json:"seller_type" description:"销售类型:1ficc销售,2权益销售"`
+	NotPaymentAmount  float64                             `json:"not_payment_amount" description:"开票未到款金额"`
+}
+
+

+ 112 - 1
models/fms/invoice_payment_summary.go

@@ -92,6 +92,10 @@ type InvoicePaymentSummaryItem struct {
 	PaymentAmount    float64   `json:"payment_amount" description:"到款金额"`
 	PayType          int       `json:"pay_type" description:"付款方式:0-无;1-年付;2-半年付;3-季付;4-次付;5-异常"`
 	ServiceProductId int       `json:"service_product_id" description:"套餐类型:1ficc套餐,2权益套餐"`
+	ContractAmount   float64   `gorm:"column:contract_amount" json:"contract_amount" description:"合同金额"`
+	InvoicedAmount   float64   `gorm:"column:invoiced_amount" json:"invoiced_amount" description:"开票金额"`
+	CurrencyUnit     string    `gorm:"column:currency_unit" json:"currency_unit" description:"货币国际代码"`
+	RMBRate          float64   `gorm:"column:rmb_rate" json:"rmb_rate" description:"人民币汇率(create_time当日)"`
 }
 
 // GetInvoicePaymentCensusSummaryData 获取商品到款统计列表-汇总数据
@@ -209,6 +213,71 @@ func GetContractSummaryIncomeAmount(condition string, pars []interface{}) (resul
 	return
 }
 
+type InvoiceSummary struct {
+	SummaryId           int     `json:"summary_id" description:"汇总ID"`
+	PaymentAmountCount  float64 `gorm:"column:payment_amount_count" json:"payment_amount_count" description:"到款金额"`
+	InvoicedAmountCount float64 `gorm:"column:invoiced_amount_count" json:"invoiced_amount_count" description:"开票金额"`
+	ContractRegister
+}
+
+// GetInvoiceCensusPageList 获取未开票统计列表-总数
+func GetInvoiceCensusPageList(page base.IPage, condition string, pars []interface{}) (results []*InvoiceSummary, count int64, err error) {
+	query := global.DEFAULT_MYSQL.Table("invoice_payment_summary AS a").
+		Select("b.*, a.id as summary_id, IF(a.invoice_id >0, 1,0) as sort_invoice_id, IF(a.payment_id >0, 1,0) as sort_payment_id, COALESCE(SUM( c.amount ),0) AS invoiced_amount_count,COALESCE(SUM( d.amount ),0) AS payment_amount_count ").
+		Joins("JOIN contract_register AS b ON a.register_id = b.contract_register_id AND b.is_deleted = 0").
+		Joins("LEFT JOIN contract_invoice AS c ON a.invoice_id = c.contract_invoice_id AND c.is_deleted = 0").
+		Joins("LEFT JOIN contract_invoice AS d ON a.payment_id = d.contract_invoice_id AND d.is_deleted = 0").
+		Where(condition, pars...).Group("contract_register_id")
+
+	nq := global.DEFAULT_MYSQL.Table("(?) AS e", query).
+		Select("*").Where(" e.invoiced_amount_count <>  e.contract_amount ")
+	nq.Count(&count)
+	if len(page.GetOrderItemsString()) > 0 {
+		nq = nq.Order(page.GetOrderItemsString())
+	}
+	err = nq.Limit(int(page.GetPageSize())).Offset(int(page.Offset())).Find(&results).Error
+	if err != nil {
+		return
+	}
+	return
+}
+
+// GetNoPaymentCensusPageList 获取开票未到款统计计列表-总数
+func GetNoPaymentCensusPageList(page base.IPage, condition string, pars []interface{}) (results []*InvoiceSummary, count int64, err error) {
+	query := global.DEFAULT_MYSQL.Table("invoice_payment_summary AS a").
+		Select("b.*, a.id as summary_id, IF(a.invoice_id >0, 1,0) as sort_invoice_id, IF(a.payment_id >0, 1,0) as sort_payment_id, COALESCE(SUM( c.amount ),0) AS invoiced_amount_count,COALESCE(SUM( d.amount ),0) AS payment_amount_count "+
+			" ,c.invoice_time ").
+		Joins("JOIN contract_register AS b ON a.register_id = b.contract_register_id AND b.is_deleted = 0").
+		Joins("LEFT JOIN contract_invoice AS c ON a.invoice_id = c.contract_invoice_id AND c.is_deleted = 0").
+		Joins("LEFT JOIN contract_invoice AS d ON a.payment_id = d.contract_invoice_id AND d.is_deleted = 0").
+		Where(condition, pars...).Group("contract_register_id")
+
+	nq := global.DEFAULT_MYSQL.Table("(?) AS e", query).
+		Select("*")
+	nq.Count(&count)
+	if len(page.GetOrderItemsString()) > 0 {
+		nq = nq.Order(page.GetOrderItemsString())
+	}
+	err = nq.Limit(int(page.GetPageSize())).Offset(int(page.Offset())).Find(&results).Error
+	if err != nil {
+		return
+	}
+	return
+}
+
+// NotInvoicePaymentCensusResp 未开票到款到款统计响应体
+type NotInvoicePaymentCensusResp struct {
+	DataList                []*NotPaymentCensusItem     `json:"data_list"`
+	InvoiceTotal            float64                     `json:"invoice_total" description:"开票总金额(换算后)"`
+	PaymentTotal            float64                     `json:"payment_total" description:"到款总金额(换算后)"`
+	InvoiceCurrencyTotal    []*InvoiceListCurrencyTotal `json:"invoice_currency_total" description:"开票-分币种总金额"`
+	PaymentCurrencyTotal    []*InvoiceListCurrencyTotal `json:"payment_currency_total" description:"到款-分币种总金额"`
+	NotInvoiceTotal         float64                     `json:"not_invoice_total" description:"未开票总金额(换算后)"`
+	NotInvoiceCurrencyTotal []*InvoiceListCurrencyTotal `json:"not_invoice_currency_total" description:"未开票-分币种总金额"`
+	NotPaymentTotal         float64                     `json:"not_payment_total" description:"未开票总金额(换算后)"`
+	NotPaymentCurrencyTotal []*InvoiceListCurrencyTotal `json:"not_payment_currency_total" description:"未开票-分币种总金额"`
+}
+
 type IncomeSummaryItemList []*IncomeSummaryItem
 
 func (c IncomeSummaryItemList) Len() int {
@@ -221,4 +290,46 @@ func (c IncomeSummaryItemList) Less(i, j int) bool {
 
 func (c IncomeSummaryItemList) Swap(i, j int) {
 	c[i], c[j] = c[j], c[i]
-}
+}
+
+type NotInvoicePaymentSummaryItem struct {
+	SummaryId              int       `json:"summary_id" description:"汇总ID"`
+	RegisterId             int       `json:"register_id" description:"登记ID"`
+	NewCompany             int       `json:"new_company" description:"是否为新客户: 0-否; 1-是"`
+	InvoiceId              int       `json:"invoice_id" description:"开票ID"`
+	InvoiceDate            time.Time `json:"invoice_time" description:"开票日期"`
+	InvoiceAmount          float64   `json:"invoice_amount" description:"开票金额"`
+	SellerGroupId          int       `json:"seller_group_id" description:"销售组别ID"`
+	SellerGroupName        string    `json:"seller_group_name" description:"销售组别名称"`
+	RaiSellerGroupId       int       `json:"rai_seller_group_id" description:"销售组别ID"`
+	RaiSellerGroupName     string    `json:"rai_seller_group_name" description:"销售组别名称"`
+	PaymentId              int       `json:"payment_id" description:"到款ID"`
+	PaymentDate            time.Time `json:"payment_date" description:"到款日期"`
+	PaymentAmount          float64   `json:"payment_amount" description:"到款金额"`
+	PayType                int       `json:"pay_type" description:"付款方式:0-无;1-年付;2-半年付;3-季付;4-次付;5-异常"`
+	ServiceProductId       int       `json:"service_product_id" description:"套餐类型:1ficc套餐,2权益套餐"`
+	ContractAmount         float64   `gorm:"column:contract_amount" json:"contract_amount" description:"合同金额"`
+	InvoicedAmount         float64   `gorm:"column:invoiced_amount" json:"invoiced_amount" description:"开票金额"`
+	CurrencyUnit           string    `gorm:"column:currency_unit" json:"currency_unit" description:"货币国际代码"`
+	RMBRate                float64   `gorm:"column:rmb_rate" json:"rmb_rate" description:"人民币汇率(create_time当日)"`
+	PaymentAmountTotal     float64   `gorm:"column:payment_amount_total" json:"payment_amount_total" description:"合同金额"`
+	InvoiceAmountTotal     float64   `gorm:"column:invoice_amount_total" json:"invoice_amount_total" description:"开票金额"`
+	NotInvoicedAmountTotal float64   ` json:"not_invoiced_amount_total" description:"未开票金额"`
+	ContractRegister
+}
+
+// GetNotInvoicePaymentCensusSummaryData 获取商品到款统计列表-汇总数据
+func GetNotInvoicePaymentCensusSummaryData(condition string, pars []interface{}) (results []*NotInvoicePaymentSummaryItem, err error) {
+	fields := []string{"a.id AS summary_id", "a.register_id", "a.invoice_id", "a.payment_id", "a.service_product_id", "b.*",
+		"c.origin_amount AS invoice_amount", "c.invoice_time AS invoice_date", "d.origin_amount AS payment_amount", "d.invoice_time AS payment_date",
+		"d.pay_type", "COALESCE(SUM( c.origin_amount ),0) AS invoice_amount_total", "COALESCE(SUM( d.origin_amount ),0) AS payment_amount_total",
+	}
+	query := global.DEFAULT_MYSQL.Table("invoice_payment_summary AS a").
+		Select(strings.Join(fields, ",")).
+		Joins("JOIN contract_register AS b ON a.register_id = b.contract_register_id AND b.is_deleted = 0").
+		Joins("LEFT JOIN contract_invoice AS c ON a.invoice_id = c.contract_invoice_id AND c.is_deleted = 0").
+		Joins("LEFT JOIN contract_invoice AS d ON a.payment_id = d.contract_invoice_id AND d.is_deleted = 0").
+		Where(condition, pars...).Group("a.register_id,service_product_id")
+	query.Find(&results)
+	return
+}

+ 3 - 0
routers/census.go

@@ -11,8 +11,11 @@ func InitCensus(rg *gin.RouterGroup) {
 	inv := new(census.InvoicePaymentController)
 	invGroup := rg.Group("invoice_payment/").Use(middleware.Token())
 	invGroup.GET("list", inv.List)
+	invGroup.GET("not_invoice/list", inv.NotInvoiceList2)
+	invGroup.GET("not_payment/list", inv.NotPaymentList)
 	invGroup.GET("income/list", inv.IncomeList)
 
+
 	// 销售
 	sel := new(census.SellerController)
 	selGroup := rg.Group("seller/").Use(middleware.Token())