ziwen před 2 roky
rodič
revize
db3c1ac5a0

+ 122 - 0
controller/contract/pre_payment.go

@@ -0,0 +1,122 @@
+package contract
+
+import (
+	"fmt"
+	"github.com/gin-gonic/gin"
+	"github.com/go-playground/validator/v10"
+	"hongze/fms_api/controller/resp"
+	"hongze/fms_api/global"
+	"hongze/fms_api/models/base"
+	"hongze/fms_api/models/fms"
+)
+
+// // RegisterController 合同登记
+type PrePaymentController struct{}
+
+// List
+// @Title 到款预登记列表
+// @Description 到款预登记列表
+// @Param   Keyword			query	string	false	"关键词"
+// @Param   StartDate		query	string	false	"合同开始日期"
+// @Param   EndDate			query	string	false	"合同结束日期"
+// @Param   SortType   		query   string  true       "如何排序,是正序还是倒序,枚举值:`asc 正序`,`desc 倒叙`"
+// @Success 200 {object} fms.ContractRegisterItem
+// @router /contract/pre_pay/list [get]
+func (rg *PrePaymentController) List(c *gin.Context) {
+	var req fms.PrePayListReq
+	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 (company_name LIKE ? OR contract_code LIKE ? OR seller_name LIKE ? OR actual_company_name LIKE ?)`
+		pars = append(pars, kw, kw, kw, kw)
+	}
+	if req.StartDate != "" && req.EndDate != "" {
+		st := fmt.Sprint(req.StartDate, " 00:00:00")
+		ed := fmt.Sprint(req.EndDate, " 23:59:59")
+		cond += ` AND (create_time BETWEEN ? AND ?)`
+		pars = append(pars, st, ed)
+	}
+
+
+	page := new(base.Page)
+	page.SetPageSize(req.PageSize)
+	page.SetCurrent(req.Current)
+	page.AddOrderItem(base.OrderItem{Column: "create_time", Asc: false})
+
+	total, list, e := fms.GetContractRegisterItemPageList(page, cond, pars)
+	if e != nil {
+		resp.FailMsg("获取失败", "获取合同登记列表失败, Err: "+e.Error(), c)
+		return
+	}
+	registerIds := make([]int, 0)
+	for i := range list {
+		registerIds = append(registerIds, list[i].ContractRegisterId)
+	}
+
+	serviceMap := make(map[int]string, 0)
+	invoiceMap := make(map[int][]*fms.ContractInvoiceItem, 0)
+	paymentMap := make(map[int][]*fms.ContractInvoiceItem, 0)
+	if len(registerIds) > 0 {
+		// 获取服务套餐
+		servicesNameList, e := fms.GetContractRegisterServicesNameByRegisterIds(registerIds)
+		if e != nil {
+			resp.FailMsg("获取失败", "获取套餐拼接字符串失败, Err: "+e.Error(), c)
+			return
+		}
+		for i := range servicesNameList {
+			serviceMap[servicesNameList[i].ContractRegisterId] = servicesNameList[i].ServicesName
+		}
+
+		// 获取开票/到款列表
+		invoiceCond := `contract_register_id IN ?`
+		invoicePars := make([]interface{}, 0)
+		invoicePars = append(invoicePars, registerIds)
+		invoiceList, e := fms.GetContractInvoiceItemList(invoiceCond, invoicePars)
+		if e != nil {
+			resp.FailMsg("获取失败", "获取开票/到款列表失败, Err: "+e.Error(), c)
+			return
+		}
+		for i := range invoiceList {
+			if invoiceMap[invoiceList[i].ContractRegisterId] == nil {
+				invoiceMap[invoiceList[i].ContractRegisterId] = make([]*fms.ContractInvoiceItem, 0)
+			}
+			if paymentMap[invoiceList[i].ContractRegisterId] == nil {
+				paymentMap[invoiceList[i].ContractRegisterId] = make([]*fms.ContractInvoiceItem, 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])
+			}
+		}
+	}
+
+	respList := make([]*fms.ContractRegisterList, 0)
+	for i := range list {
+		v := new(fms.ContractRegisterList)
+		v.ContractRegisterItem = list[i]
+		v.ServicesName = serviceMap[list[i].ContractRegisterId]
+		v.InvoiceList = invoiceMap[list[i].ContractRegisterId]
+		v.PaymentList = paymentMap[list[i].ContractRegisterId]
+		respList = append(respList, v)
+	}
+
+	page.SetTotal(total)
+	baseData := new(base.BaseData)
+	baseData.SetPage(page)
+	baseData.SetList(respList)
+	resp.OkData("获取成功", baseData, c)
+}

+ 107 - 0
controller/statistic.go

@@ -0,0 +1,107 @@
+package controller
+
+import (
+	"context"
+	"encoding/json"
+	"fmt"
+	"github.com/gin-gonic/gin"
+	"hongze/fms_api/controller/resp"
+	"hongze/fms_api/global"
+	"hongze/fms_api/models"
+	"hongze/fms_api/services/alarm_msg"
+	"hongze/fms_api/utils"
+	"time"
+)
+
+// // StatisticController 统计报告
+type StatisticController struct{}
+
+
+// Home
+// @Title 获取首页工作台数据
+// @Description 获取首页工作台数据接口
+// @Success 200 {object} response.WorktopResp
+// @router /statistic [get]
+func (this *StatisticController) Statistic(c *gin.Context) {
+
+	//近6收入统计
+	var incomeList models.IncomeChartResp
+	ch := make(chan models.IncomeChartResp, 1)
+	go getIncomeList(ch)
+
+	for v := range ch {
+		incomeList = v
+		close(ch)
+	}
+
+	resp.OkData("获取成功", incomeList, c)
+}
+
+//获取收入统计
+func getIncomeList(ch chan models.IncomeChartResp) (incomeChart models.IncomeChartResp, err error) {
+	defer func() {
+		if err != nil {
+			go alarm_msg.SendAlarmMsg("获取近两年的收入统计数据异常,Err:"+err.Error(), 3)
+			//go utils.SendEmail(utils.APPNAME+"获取近12个月的收入统计数据异常:"+time.Now().Format("2006-01-02 15:04:05"), err.Error(), utils.EmailSendToUsers)
+		}
+		ch <- incomeChart
+	}()
+	todayStr := utils.GetToday("20060102")
+	key := "admin:home:incomeList:" + todayStr
+
+	redisJsonData, redisErr := global.Redis.Get(context.TODO(), key).Result()
+	if redisErr != nil {
+		var dateSlice []string
+		var contractMoneySlice []float64
+		var ArrivalMoneySlice []float64
+
+		yearNum := time.Now().Year() - time.Now().AddDate(-2, 0, 0).Year()
+		monthNum := time.Now().Month() - 1
+		numMonth := yearNum*12 + int(monthNum) //距离2021-01存在多少个月
+
+		for i := numMonth; i >= 0; i-- {
+			timeNow, _ := time.Parse("2006-01", time.Now().Format("2006-01"))
+			dateSlice = append(dateSlice, timeNow.AddDate(0, -i, 0).Format("06/01"))
+			//开始日期
+			startDate := timeNow.AddDate(0, -i, 0).Format("2006-01")
+			startDate = fmt.Sprint(startDate, "-01")
+
+			//结束日期
+			endDateTime := timeNow.AddDate(0, -i+1, 0)
+			endDate := endDateTime.Format("2006-01")
+
+			//因为就算是当月的后续事件还没到,也要计入数据统计,所以不做限制到当天处理
+			//if endDateTime.After(time.Now()) {
+			//	endDate = time.Now().AddDate(0, 0, 1).Format(utils.FormatDate)
+			//} else {
+			//	endDate = fmt.Sprint(endDate, "-01")
+			//}
+			endDate = fmt.Sprint(endDate, "-01")
+			cond := ` AND create_time >= '`+startDate +`' AND create_time < '`+endDate +`' `
+
+			item, countErr := models.GetIncomeListCount(cond)
+			if countErr != nil && countErr != utils.ErrNoRow {
+				err = countErr
+				return
+			}
+			contractMoneySlice = append(contractMoneySlice, item.ContractMoney)
+			ArrivalMoneySlice = append(contractMoneySlice, item.ArrivalMoney)
+		}
+		incomeChart.Title = "开票到款统计图"
+		incomeChart.Date = dateSlice
+		incomeChart.ContractMoney = contractMoneySlice
+		incomeChart.ArrivalMoney = ArrivalMoneySlice
+
+		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("近6个月的收入统计数据,json转换失败")
+		}
+	}
+
+	return
+}

+ 1 - 1
go.mod

@@ -15,7 +15,7 @@ require (
 	github.com/go-redis/redis/v8 v8.11.4
 	github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0
 	github.com/jonboulle/clockwork v0.2.2 // indirect
-	github.com/json-iterator/go v1.1.12 // indirect
+	github.com/json-iterator/go v1.1.12
 	github.com/lestrrat-go/file-rotatelogs v2.4.0+incompatible
 	github.com/lestrrat-go/strftime v1.0.5 // indirect
 	github.com/mattn/go-isatty v0.0.14 // indirect

+ 4 - 0
init_serve/router.go

@@ -44,5 +44,9 @@ func InitRouter() (r *gin.Engine) {
 	// 统计相关路由
 	censusGroup := rBase.Group("census/")
 	routers.InitCensus(censusGroup)
+
+	// 统计报告
+	routers.InitStatistic(rBase)
+
 	return
 }

+ 149 - 0
models/fms/contract_pre_payment.go

@@ -0,0 +1,149 @@
+package fms
+
+import (
+	"hongze/fms_api/models/base"
+	"time"
+)
+
+// ContractInvoice 合同开票表
+type ContractPrePayment struct {
+	ContractInvoiceId  int       `gorm:"primaryKey;column:contract_invoice_id" json:"contract_invoice_id" description:"开票ID"`
+	ContractRegisterId int       `gorm:"column:contract_register_id" json:"contract_register_id" description:"登记ID"`
+	ContractCode       string    `gorm:"column:contract_code" json:"contract_code" description:"合同编号"`
+	Amount             float64   `gorm:"column:amount" json:"amount" description:"换算后的金额(人民币)"`
+	OriginAmount       float64   `gorm:"column:origin_amount" json:"origin_amount" description:"开票/到款金额"`
+	CurrencyUnit       string    `gorm:"column:currency_unit" json:"currency_unit" description:"货币国际代码"`
+	InvoiceType        int       `gorm:"column:invoice_type" json:"invoice_type" description:"类型: 1-开票登记; 2-到款登记"`
+	InvoiceDate        time.Time `gorm:"column:invoice_time" json:"invoice_time" description:"开票日期/到款月"`
+	SellerId           int       `gorm:"column:seller_id" json:"seller_id" description:"销售ID"`
+	SellerName         string    `gorm:"column:seller_name" json:"seller_name" description:"销售名称"`
+	SellerGroupId      int       `gorm:"column:seller_group_id" json:"seller_group_id" description:"销售分组ID"`
+	SellerGroupName    string    `gorm:"column:seller_group_name" json:"seller_group_name" description:"销售分组名称"`
+	SellerTeamId       int       `gorm:"column:seller_team_id" json:"seller_team_id" description:"销售小组ID"`
+	SellerTeamName     string    `gorm:"column:seller_team_name" json:"seller_team_name" description:"销售小组名称"`
+	PayType            int       `gorm:"column:pay_type" json:"pay_type" description:"付款方式:0-无;1-年付;2-半年付;3-季付;4-次付;5-异常"`
+	AdminId            int       `gorm:"column:admin_id" json:"admin_id" description:"操作人ID"`
+	AdminName          string    `gorm:"column:admin_name" json:"admin_name" description:"操作人姓名"`
+	Remark             string    `gorm:"column:remark" json:"remark" description:"备注信息"`
+	IsDeleted          int       `gorm:"column:is_deleted" json:"is_deleted" description:"是否已删除: 0-正常; 1-已删除"`
+	base.TimeBase
+}
+
+func (c *ContractPrePayment) TableName() string {
+	return "contract_pre_payment"
+}
+
+//// ContractInvoiceItem 合同开票/到款
+//type ContractInvoiceItem struct {
+//	ContractInvoiceId  int     `gorm:"column:contract_invoice_id" json:"contract_invoice_id" description:"开票ID"`
+//	ContractRegisterId int     `gorm:"column:contract_register_id" json:"contract_register_id" description:"登记ID"`
+//	ContractCode       string  `gorm:"column:contract_code" json:"contract_code" description:"合同编号"`
+//	Amount             float64 `gorm:"column:amount" json:"amount" description:"换算金额"`
+//	OriginAmount       float64 `gorm:"column:origin_amount" json:"origin_amount" description:"开票/到款金额"`
+//	CurrencyUnit       string  `gorm:"column:currency_unit" json:"currency_unit" description:"货币国际代码"`
+//	UnitName           string  `json:"unit_name" description:"货币单位名称"`
+//	InvoiceType        int     `gorm:"column:invoice_type" json:"invoice_type" description:"类型: 1-开票登记; 2-到款登记"`
+//	InvoiceDate        string  `gorm:"column:invoice_time" json:"invoice_time" description:"开票日期/到款月"`
+//	SellerId           int     `gorm:"column:seller_id" json:"seller_id" description:"销售ID"`
+//	SellerName         string  `gorm:"column:seller_name" json:"seller_name" description:"销售名称"`
+//	PayType            int     `gorm:"column:pay_type" json:"pay_type" description:"付款方式:0-无;1-年付;2-半年付;3-季付;4-次付;5-异常"`
+//	Remark             string  `gorm:"column:remark" json:"remark" description:"备注信息"`
+//	CreateTime         string  `gorm:"column:create_time" json:"create_time" description:"创建时间"`
+//}
+//
+//func (c *ContractInvoice) Create() (err error) {
+//	err = global.DEFAULT_MYSQL.Create(c).Error
+//	return
+//}
+//
+//func (c *ContractInvoice) AddInBatches(list []*ContractInvoice) (err error) {
+//	err = global.DEFAULT_MYSQL.CreateInBatches(list, len(list)).Error
+//	return
+//}
+//
+//func (c *ContractInvoice) Update(updateCols []string) (err error) {
+//	err = global.DEFAULT_MYSQL.Model(c).Select(updateCols).Updates(c).Error
+//	return
+//}
+//
+//func (c *ContractInvoice) Fetch(id int) (item *ContractInvoice, err error) {
+//	err = global.DEFAULT_MYSQL.Model(c).Where("is_deleted = 0 AND contract_invoice_id = ?", id).First(&item).Error
+//	return
+//}
+//
+//func (c *ContractInvoice) Sum(field, condition string, pars []interface{}) (total float64, err error) {
+//	totalList := make([]float64, 0)
+//	err = global.DEFAULT_MYSQL.Model(c).
+//		Where("is_deleted = 0").
+//		Where(condition, pars...).
+//		Pluck(field, &totalList).Error
+//	for i := range totalList {
+//		total += totalList[i]
+//	}
+//	return
+//}
+//
+//func (c *ContractInvoice) List(condition string, pars []interface{}, orderRule string) (list []*ContractInvoice, err error) {
+//	list = make([]*ContractInvoice, 0)
+//	query := global.DEFAULT_MYSQL.Model(c).
+//		Where("is_deleted = 0").
+//		Where(condition, pars...)
+//	if orderRule != "" {
+//		query.Order(orderRule)
+//	} else {
+//		query.Order("contract_invoice_id ASC")
+//	}
+//	err = query.Find(&list).Error
+//	return
+//}
+//
+//func (c *ContractInvoice) PageList(page base.IPage, condition string, pars []interface{}) (count int64, results []*ContractInvoice, err error) {
+//	results = make([]*ContractInvoice, 0)
+//	query := global.DEFAULT_MYSQL.Model(c).
+//		Where("is_deleted = 0").
+//		Where(condition, pars...)
+//	query.Count(&count)
+//	if len(page.GetOrderItemsString()) > 0 {
+//		query = query.Order(page.GetOrderItemsString())
+//	}
+//	err = query.Limit(int(page.GetPageSize())).Offset(int(page.Offset())).Find(&results).Error
+//	return
+//}
+//
+//// DeleteAndCreateNewInvoice 删除并新增登记
+//func (c *ContractInvoice) DeleteAndCreateNewInvoice(contractRegisterId, invoiceType int, deleteInvoiceIds []int, invoices []*ContractInvoice) (err error) {
+//	tx := global.DEFAULT_MYSQL.Begin()
+//	defer func() {
+//		if err != nil {
+//			tx.Rollback()
+//		} else {
+//			tx.Commit()
+//		}
+//	}()
+//
+//	if len(deleteInvoiceIds) > 0 {
+//		err = tx.Model(c).
+//			Where("contract_register_id = ? AND invoice_type = ? AND contract_invoice_id IN (?)", contractRegisterId, invoiceType, deleteInvoiceIds).
+//			UpdateColumn("is_deleted", 1).Error
+//		if err != nil {
+//			return
+//		}
+//	}
+//	if len(invoices) > 0 {
+//		err = tx.CreateInBatches(invoices, len(invoices)).Error
+//		if err != nil {
+//			return
+//		}
+//	}
+//	return
+//}
+
+
+// ContractRegisterListReq 合同登记列表请求体
+type PrePayListReq struct {
+	Keyword        string `json:"keyword" form:"keyword" binding:"omitempty" description:"关键词"`
+	StartDate      string `json:"start_date" form:"start_date" binding:"omitempty,datetime=2006-01-02" description:"合同开始日期"`
+	EndDate        string `json:"end_date" form:"end_date" binding:"omitempty,datetime=2006-01-02" description:"合同结束日期"`
+	base.PageReq
+}
+

+ 27 - 0
models/statistic.go

@@ -0,0 +1,27 @@
+package models
+
+import (
+	"hongze/fms_api/global"
+)
+
+// 收入统计图表数据
+type IncomeChartResp struct {
+	Title         string    `description:"图表名称"`
+	Date          []string  `description:"月份"`
+	ContractMoney []float64 `description:"开票金额"`
+	ArrivalMoney  []float64 `description:"到款金额"`
+}
+
+type IncomeItem struct {
+	ContractMoney float64 `description:"开票金额"`
+	ArrivalMoney  float64 `description:"到款金额"`
+}
+
+func GetIncomeListCount(cond string) (results *IncomeItem, err error) {
+	sql := `SELECT a.contract_money, b.arrival_money FROM (
+SELECT SUM(amount) contract_money  FROM contract_invoice  WHERE is_deleted = 0 AND invoice_type = 1 `+cond+` ) AS a,
+(SELECT SUM(amount) arrival_money FROM  contract_invoice  WHERE is_deleted = 0 AND invoice_type = 2 `+cond+` ) AS b WHERE 1=1 `
+
+	err = global.DEFAULT_MYSQL.Raw(sql).First(&results).Error
+	return
+}

+ 5 - 0
routers/contract.go

@@ -33,4 +33,9 @@ func InitContract(rg *gin.RouterGroup) {
 	payGroup := rg.Group("payment/").Use(middleware.Token())
 	payGroup.POST("update_pay_type", pay.UpdatePaymentPayType)
 	payGroup.POST("distribute_service_amount", pay.DistributePaymentServiceAmount)
+
+	//到款预登记
+	prepay := new(contract.PrePaymentController)
+	prepayGroup := rg.Group("pre_payment/").Use(middleware.Token())
+	prepayGroup.GET("list", prepay.List)
 }

+ 13 - 0
routers/statistic.go

@@ -0,0 +1,13 @@
+package routers
+
+import (
+	"github.com/gin-gonic/gin"
+	"hongze/fms_api/controller"
+)
+
+func InitStatistic(baseGroup *gin.RouterGroup) {
+	//统计报告
+	statisticController := new(controller.StatisticController)
+	statisticGroup := baseGroup.Group("home/")
+	statisticGroup.GET("statistic", statisticController.Statistic)
+}