From d5c533de0c2ccb5614ea3c600ede9c13da77e127 Mon Sep 17 00:00:00 2001
From: zhangqian <zhangqian@123.com>
Date: 星期二, 08 八月 2023 09:37:51 +0800
Subject: [PATCH] 合并服务管理

---
 service/invoiceStatus.go               |   66 
 constvar/invoiceType.go                |   12 
 model/request/file.go                  |    2 
 api/v1/invoiceType.go                  |  112 +
 model/request/serviceCollectionPlan.go |    2 
 api/v1/invoiceStatus.go                |  112 +
 go.mod                                 |    1 
 constvar/serviceCollectionPlan.go      |   10 
 docs/swagger.yaml                      |  814 +++++++-
 api/v1/file.go                         |   73 
 api/v1/invoice.go                      |  127 +
 router/courierCompany.go               |   17 
 router/invoiceStatus.go                |   17 
 constvar/invoice.go                    |   20 
 router/invoiceType.go                  |   17 
 constvar/invoiceStatus.go              |   12 
 model/invoice.go                       |  160 +
 service/file.go                        |    4 
 model/invoiceType.go                   |  140 +
 service/courierCompany.go              |   66 
 router/invoice.go                      |   17 
 utils/upload/upload.go                 |   35 
 model/file.go                          |   15 
 docs/docs.go                           | 1238 +++++++++++-
 router/file.go                         |    1 
 service/invoice.go                     |   87 
 docs/swagger.json                      | 1238 +++++++++++-
 constvar/courierCompany.go             |   12 
 model/courierCompany.go                |  140 +
 model/request/invoice.go               |   43 
 model/request/invoiceStatus.go         |   22 
 model/serviceCollectionPlan.go         |   41 
 api/v1/courierCompany.go               |  112 +
 model/serviceContract.go               |  374 ++-
 go.sum                                 |   11 
 model/invoiceStatus.go                 |  140 +
 service/invoiceType.go                 |   66 
 service/serviceCollectionPlan.go       |    8 
 api/v1/serviceCollectionPlan.go        |   31 
 router/index.go                        |    7 
 model/request/courierCompany.go        |   22 
 model/request/invoiceType.go           |   22 
 42 files changed, 4,831 insertions(+), 635 deletions(-)

diff --git a/api/v1/courierCompany.go b/api/v1/courierCompany.go
new file mode 100644
index 0000000..a4806b2
--- /dev/null
+++ b/api/v1/courierCompany.go
@@ -0,0 +1,112 @@
+package v1
+
+import (
+	"aps_crm/model/request"
+	"aps_crm/model/response"
+	"aps_crm/pkg/contextx"
+	"aps_crm/pkg/ecode"
+	"aps_crm/service"
+	"github.com/gin-gonic/gin"
+	"strconv"
+)
+
+type CourierCompanyApi struct{}
+
+// Add
+// @Tags		鐗╂祦鍏徃
+// @Summary	娣诲姞鐗╂祦鍏徃
+// @Produce	application/json
+// @Param		object	body		request.AddCourierCompany	true	"鏌ヨ鍙傛暟"
+// @Success	200		{object}	contextx.Response{}
+// @Router		/api/courierCompany/add [post]
+func (s *CourierCompanyApi) Add(c *gin.Context) {
+	var params request.AddCourierCompany
+	ctx, ok := contextx.NewContext(c, &params)
+	if !ok {
+		return
+	}
+
+	errCode := service.NewCourierCompanyService().AddCourierCompany(&params.CourierCompany)
+	if errCode != ecode.OK {
+		ctx.Fail(errCode)
+		return
+	}
+
+	ctx.Ok()
+}
+
+// Delete
+// @Tags		鐗╂祦鍏徃
+// @Summary	鍒犻櫎鐗╂祦鍏徃
+// @Produce	application/json
+// @Param		id	path		int	true	"鏌ヨ鍙傛暟"
+// @Success	200	{object}	contextx.Response{}
+// @Router		/api/courierCompany/delete/{id} [delete]
+func (s *CourierCompanyApi) Delete(c *gin.Context) {
+	ctx, ok := contextx.NewContext(c, nil)
+	if !ok {
+		return
+	}
+
+	id, _ := strconv.Atoi(c.Param("id"))
+	errCode := service.NewCourierCompanyService().DeleteCourierCompany(id)
+	if errCode != ecode.OK {
+		ctx.Fail(errCode)
+		return
+	}
+
+	ctx.Ok()
+}
+
+// Update
+// @Tags		鐗╂祦鍏徃
+// @Summary	鏇存柊鐗╂祦鍏徃
+// @Produce	application/json
+// @Param		object	body		request.UpdateCourierCompany	true	"鏌ヨ鍙傛暟"
+// @Success	200		{object}	contextx.Response{}
+// @Router		/api/courierCompany/update [put]
+func (s *CourierCompanyApi) Update(c *gin.Context) {
+	var params request.UpdateCourierCompany
+	ctx, ok := contextx.NewContext(c, &params)
+	if !ok {
+		return
+	}
+    if params.Id == 0 {
+        ctx.Fail(ecode.ParamsErr)
+    }
+    params.CourierCompany.Id = params.Id
+
+	errCode := service.NewCourierCompanyService().UpdateCourierCompany(&params.CourierCompany)
+	if errCode != ecode.OK {
+		ctx.Fail(errCode)
+		return
+	}
+
+	ctx.Ok()
+}
+
+// List
+// @Tags		鐗╂祦鍏徃
+// @Summary	鑾峰彇鐗╂祦鍏徃鍒楄〃
+// @Produce	application/json
+// @Param		object	query		request.GetCourierCompanyList	true	"鍙傛暟"
+// @Success	200	{object}	response.ListResponse{data=[]model.CourierCompany}
+// @Router		/api/courierCompany/list [get]
+func (s *CourierCompanyApi) List(c *gin.Context) {
+	var params request.GetCourierCompanyList
+	ctx, ok := contextx.NewContext(c, &params)
+	if !ok {
+		return
+	}
+
+	courierCompany, total, errCode := service.NewCourierCompanyService().GetCourierCompanyList()
+	if errCode != ecode.OK {
+		ctx.Fail(errCode)
+		return
+	}
+
+	ctx.OkWithDetailed(response.ListResponse{
+		Data: courierCompany,
+		Count: total,
+	})
+}
diff --git a/api/v1/file.go b/api/v1/file.go
index 1edb6b9..9fbdc78 100644
--- a/api/v1/file.go
+++ b/api/v1/file.go
@@ -8,11 +8,11 @@
 	"aps_crm/pkg/ecode"
 	"aps_crm/pkg/httpx"
 	"aps_crm/service"
-	"github.com/flipped-aurora/gin-vue-admin/server/utils/upload"
+	"aps_crm/utils/upload"
 	"github.com/gin-gonic/gin"
+	"github.com/spf13/cast"
 	"os"
 	"path/filepath"
-	"strconv"
 )
 
 type FileApi struct{}
@@ -21,7 +21,8 @@
 // @Tags		闄勪欢绠$悊
 // @Summary	娣诲姞闄勪欢
 // @Produce	application/json
-// @Param		object	body		request.AddFile	true	"鏌ヨ鍙傛暟"
+// @Param		object	formData	request.AddFile	true	"鏌ヨ鍙傛暟"
+// @Param		file	formData	file	true	"涓婁紶鏂囦欢"
 // @Success	200		{object}	contextx.Response{}
 // @Router		/api/file/add [post]
 func (s *FileApi) Add(c *gin.Context) {
@@ -44,7 +45,7 @@
 		return
 	}
 
-	_, filename := filepath.Split(filePath)
+	_, filename := filepath.Split(header.Filename)
 
 	fileRecord := &model.File{
 		Name:          filename,
@@ -80,17 +81,11 @@
 		return
 	}
 
-	id, _ := strconv.Atoi(c.Param("id"))
-
+	idx := c.Param("id")
+	id := cast.ToUint(idx)
 	file, err := model.NewFileSearch().SetId(id).First()
 	if err != nil {
 		ctx.FailWithMsg(ecode.ParamsErr, "鏌ユ壘鏂囦欢澶辫触")
-		return
-	}
-
-	err = os.Remove(file.FilePath)
-	if err != nil {
-		ctx.FailWithMsg(ecode.ParamsErr, "鍒犻櫎鏂囦欢澶辫触")
 		return
 	}
 
@@ -100,36 +95,42 @@
 		return
 	}
 
-	ctx.Ok()
-}
-
-// Update
-// @Tags		闄勪欢绠$悊
-// @Summary	鏇存柊闄勪欢
-// @Produce	application/json
-// @Param		object	body		request.UpdateFile	true	"鏌ヨ鍙傛暟"
-// @Success	200		{object}	contextx.Response{}
-// @Router		/api/file/update [put]
-func (s *FileApi) Update(c *gin.Context) {
-	var params request.UpdateFile
-	ctx, ok := contextx.NewContext(c, &params)
-	if !ok {
-		return
-	}
-	if params.Id == 0 {
-		ctx.Fail(ecode.ParamsErr)
-	}
-	params.File.Id = params.Id
-
-	errCode := service.NewFileService().UpdateFile(&params.File)
-	if errCode != ecode.OK {
-		ctx.Fail(errCode)
+	err = os.Remove(file.FilePath)
+	if err != nil {
+		ctx.FailWithMsg(ecode.ParamsErr, "鍒犻櫎鏂囦欢澶辫触")
 		return
 	}
 
 	ctx.Ok()
 }
 
+//// Update
+//// @Tags		闄勪欢绠$悊
+//// @Summary	鏇存柊闄勪欢
+//// @Produce	application/json
+//// @Param		object	body		request.UpdateFile	true	"鏌ヨ鍙傛暟"
+//// @Success	200		{object}	contextx.Response{}
+//// @Router		/api/file/update [put]
+//func (s *FileApi) Update(c *gin.Context) {
+//	var params request.UpdateFile
+//	ctx, ok := contextx.NewContext(c, &params)
+//	if !ok {
+//		return
+//	}
+//	if params.Id == 0 {
+//		ctx.Fail(ecode.ParamsErr)
+//	}
+//	params.File.ID = params.Id
+//
+//	errCode := service.NewFileService().UpdateFile(&params.File)
+//	if errCode != ecode.OK {
+//		ctx.Fail(errCode)
+//		return
+//	}
+//
+//	ctx.Ok()
+//}
+
 // List
 // @Tags		闄勪欢绠$悊
 // @Summary	鑾峰彇闄勪欢鍒楄〃
diff --git a/api/v1/invoice.go b/api/v1/invoice.go
new file mode 100644
index 0000000..68f5ecc
--- /dev/null
+++ b/api/v1/invoice.go
@@ -0,0 +1,127 @@
+package v1
+
+import (
+	"aps_crm/model"
+	"aps_crm/model/request"
+	"aps_crm/model/response"
+	"aps_crm/pkg/contextx"
+	"aps_crm/pkg/ecode"
+	"aps_crm/pkg/structx"
+	"aps_crm/service"
+	"github.com/gin-gonic/gin"
+	"strconv"
+)
+
+type InvoiceApi struct{}
+
+// Add
+// @Tags		閿�鍞彂绁�
+// @Summary	娣诲姞閿�鍞彂绁�
+// @Produce	application/json
+// @Param		object	body		request.AddInvoice	true	"鏌ヨ鍙傛暟"
+// @Success	200		{object}	contextx.Response{}
+// @Router		/api/invoice/add [post]
+func (s *InvoiceApi) Add(c *gin.Context) {
+	var params request.AddInvoice
+	ctx, ok := contextx.NewContext(c, &params)
+	if !ok {
+		return
+	}
+	var invoice model.Invoice
+	err := structx.AssignTo(params, &invoice)
+
+	if err != nil {
+		ctx.Fail(ecode.ParamsErr)
+		return
+	}
+
+	errCode := service.NewInvoiceService().AddInvoice(&invoice)
+	if errCode != ecode.OK {
+		ctx.Fail(errCode)
+		return
+	}
+
+	ctx.Ok()
+}
+
+// Delete
+// @Tags		閿�鍞彂绁�
+// @Summary	鍒犻櫎閿�鍞彂绁�
+// @Produce	application/json
+// @Param		id	path		int	true	"鏌ヨ鍙傛暟"
+// @Success	200	{object}	contextx.Response{}
+// @Router		/api/invoice/delete/{id} [delete]
+func (s *InvoiceApi) Delete(c *gin.Context) {
+	ctx, ok := contextx.NewContext(c, nil)
+	if !ok {
+		return
+	}
+
+	id, _ := strconv.Atoi(c.Param("id"))
+	errCode := service.NewInvoiceService().DeleteInvoice(id)
+	if errCode != ecode.OK {
+		ctx.Fail(errCode)
+		return
+	}
+
+	ctx.Ok()
+}
+
+// Update
+// @Tags		閿�鍞彂绁�
+// @Summary	鏇存柊閿�鍞彂绁�
+// @Produce	application/json
+// @Param		object	body		request.UpdateInvoice	true	"鏌ヨ鍙傛暟"
+// @Success	200		{object}	contextx.Response{}
+// @Router		/api/invoice/update [put]
+func (s *InvoiceApi) Update(c *gin.Context) {
+	var params request.UpdateInvoice
+	ctx, ok := contextx.NewContext(c, &params)
+	if !ok {
+		return
+	}
+	if params.Id == 0 {
+		ctx.Fail(ecode.ParamsErr)
+	}
+	var invoice model.Invoice
+	err := structx.AssignTo(params, &invoice)
+
+	if err != nil {
+		ctx.Fail(ecode.ParamsErr)
+		return
+	}
+
+	errCode := service.NewInvoiceService().UpdateInvoice(&invoice)
+	if errCode != ecode.OK {
+		ctx.Fail(errCode)
+		return
+	}
+
+	ctx.Ok()
+}
+
+// List
+// @Tags		閿�鍞彂绁�
+// @Summary	鑾峰彇閿�鍞彂绁ㄥ垪琛�
+// @Produce	application/json
+// @Param		object	query		request.GetInvoiceList	true	"鍙傛暟"
+// @Success	200	{object}	response.ListResponse{data=[]model.Invoice}
+// @Router		/api/invoice/list [get]
+func (s *InvoiceApi) List(c *gin.Context) {
+	var params request.GetInvoiceList
+	ctx, ok := contextx.NewContext(c, &params)
+	if !ok {
+		return
+	}
+
+	invoice, total, errCode := service.NewInvoiceService().GetInvoiceList()
+	if errCode != ecode.OK {
+		ctx.Fail(errCode)
+		return
+	}
+
+	ctx.OkWithDetailed(response.ListResponse{
+		Data:  invoice,
+		Count: total,
+	})
+}
diff --git a/api/v1/invoiceStatus.go b/api/v1/invoiceStatus.go
new file mode 100644
index 0000000..0834088
--- /dev/null
+++ b/api/v1/invoiceStatus.go
@@ -0,0 +1,112 @@
+package v1
+
+import (
+	"aps_crm/model/request"
+	"aps_crm/model/response"
+	"aps_crm/pkg/contextx"
+	"aps_crm/pkg/ecode"
+	"aps_crm/service"
+	"github.com/gin-gonic/gin"
+	"strconv"
+)
+
+type InvoiceStatusApi struct{}
+
+// Add
+// @Tags		鍙戠エ鐘舵��
+// @Summary	娣诲姞鍙戠エ鐘舵��
+// @Produce	application/json
+// @Param		object	body		request.AddInvoiceStatus	true	"鏌ヨ鍙傛暟"
+// @Success	200		{object}	contextx.Response{}
+// @Router		/api/invoiceStatus/add [post]
+func (s *InvoiceStatusApi) Add(c *gin.Context) {
+	var params request.AddInvoiceStatus
+	ctx, ok := contextx.NewContext(c, &params)
+	if !ok {
+		return
+	}
+
+	errCode := service.NewInvoiceStatusService().AddInvoiceStatus(&params.InvoiceStatus)
+	if errCode != ecode.OK {
+		ctx.Fail(errCode)
+		return
+	}
+
+	ctx.Ok()
+}
+
+// Delete
+// @Tags		鍙戠エ鐘舵��
+// @Summary	鍒犻櫎鍙戠エ鐘舵��
+// @Produce	application/json
+// @Param		id	path		int	true	"鏌ヨ鍙傛暟"
+// @Success	200	{object}	contextx.Response{}
+// @Router		/api/invoiceStatus/delete/{id} [delete]
+func (s *InvoiceStatusApi) Delete(c *gin.Context) {
+	ctx, ok := contextx.NewContext(c, nil)
+	if !ok {
+		return
+	}
+
+	id, _ := strconv.Atoi(c.Param("id"))
+	errCode := service.NewInvoiceStatusService().DeleteInvoiceStatus(id)
+	if errCode != ecode.OK {
+		ctx.Fail(errCode)
+		return
+	}
+
+	ctx.Ok()
+}
+
+// Update
+// @Tags		鍙戠エ鐘舵��
+// @Summary	鏇存柊鍙戠エ鐘舵��
+// @Produce	application/json
+// @Param		object	body		request.UpdateInvoiceStatus	true	"鏌ヨ鍙傛暟"
+// @Success	200		{object}	contextx.Response{}
+// @Router		/api/invoiceStatus/update [put]
+func (s *InvoiceStatusApi) Update(c *gin.Context) {
+	var params request.UpdateInvoiceStatus
+	ctx, ok := contextx.NewContext(c, &params)
+	if !ok {
+		return
+	}
+    if params.Id == 0 {
+        ctx.Fail(ecode.ParamsErr)
+    }
+    params.InvoiceStatus.Id = params.Id
+
+	errCode := service.NewInvoiceStatusService().UpdateInvoiceStatus(&params.InvoiceStatus)
+	if errCode != ecode.OK {
+		ctx.Fail(errCode)
+		return
+	}
+
+	ctx.Ok()
+}
+
+// List
+// @Tags		鍙戠エ鐘舵��
+// @Summary	鑾峰彇鍙戠エ鐘舵�佸垪琛�
+// @Produce	application/json
+// @Param		object	query		request.GetInvoiceStatusList	true	"鍙傛暟"
+// @Success	200	{object}	response.ListResponse{data=[]model.InvoiceStatus}
+// @Router		/api/invoiceStatus/list [get]
+func (s *InvoiceStatusApi) List(c *gin.Context) {
+	var params request.GetInvoiceStatusList
+	ctx, ok := contextx.NewContext(c, &params)
+	if !ok {
+		return
+	}
+
+	invoiceStatus, total, errCode := service.NewInvoiceStatusService().GetInvoiceStatusList()
+	if errCode != ecode.OK {
+		ctx.Fail(errCode)
+		return
+	}
+
+	ctx.OkWithDetailed(response.ListResponse{
+		Data: invoiceStatus,
+		Count: total,
+	})
+}
diff --git a/api/v1/invoiceType.go b/api/v1/invoiceType.go
new file mode 100644
index 0000000..673bdf3
--- /dev/null
+++ b/api/v1/invoiceType.go
@@ -0,0 +1,112 @@
+package v1
+
+import (
+	"aps_crm/model/request"
+	"aps_crm/model/response"
+	"aps_crm/pkg/contextx"
+	"aps_crm/pkg/ecode"
+	"aps_crm/service"
+	"github.com/gin-gonic/gin"
+	"strconv"
+)
+
+type InvoiceTypeApi struct{}
+
+// Add
+// @Tags		鍙戠エ绫诲瀷
+// @Summary	娣诲姞鍙戠エ绫诲瀷
+// @Produce	application/json
+// @Param		object	body		request.AddInvoiceType	true	"鏌ヨ鍙傛暟"
+// @Success	200		{object}	contextx.Response{}
+// @Router		/api/invoiceType/add [post]
+func (s *InvoiceTypeApi) Add(c *gin.Context) {
+	var params request.AddInvoiceType
+	ctx, ok := contextx.NewContext(c, &params)
+	if !ok {
+		return
+	}
+
+	errCode := service.NewInvoiceTypeService().AddInvoiceType(&params.InvoiceType)
+	if errCode != ecode.OK {
+		ctx.Fail(errCode)
+		return
+	}
+
+	ctx.Ok()
+}
+
+// Delete
+// @Tags		鍙戠エ绫诲瀷
+// @Summary	鍒犻櫎鍙戠エ绫诲瀷
+// @Produce	application/json
+// @Param		id	path		int	true	"鏌ヨ鍙傛暟"
+// @Success	200	{object}	contextx.Response{}
+// @Router		/api/invoiceType/delete/{id} [delete]
+func (s *InvoiceTypeApi) Delete(c *gin.Context) {
+	ctx, ok := contextx.NewContext(c, nil)
+	if !ok {
+		return
+	}
+
+	id, _ := strconv.Atoi(c.Param("id"))
+	errCode := service.NewInvoiceTypeService().DeleteInvoiceType(id)
+	if errCode != ecode.OK {
+		ctx.Fail(errCode)
+		return
+	}
+
+	ctx.Ok()
+}
+
+// Update
+// @Tags		鍙戠エ绫诲瀷
+// @Summary	鏇存柊鍙戠エ绫诲瀷
+// @Produce	application/json
+// @Param		object	body		request.UpdateInvoiceType	true	"鏌ヨ鍙傛暟"
+// @Success	200		{object}	contextx.Response{}
+// @Router		/api/invoiceType/update [put]
+func (s *InvoiceTypeApi) Update(c *gin.Context) {
+	var params request.UpdateInvoiceType
+	ctx, ok := contextx.NewContext(c, &params)
+	if !ok {
+		return
+	}
+    if params.Id == 0 {
+        ctx.Fail(ecode.ParamsErr)
+    }
+    params.InvoiceType.Id = params.Id
+
+	errCode := service.NewInvoiceTypeService().UpdateInvoiceType(&params.InvoiceType)
+	if errCode != ecode.OK {
+		ctx.Fail(errCode)
+		return
+	}
+
+	ctx.Ok()
+}
+
+// List
+// @Tags		鍙戠エ绫诲瀷
+// @Summary	鑾峰彇鍙戠エ绫诲瀷鍒楄〃
+// @Produce	application/json
+// @Param		object	query		request.GetInvoiceTypeList	true	"鍙傛暟"
+// @Success	200	{object}	response.ListResponse{data=[]model.InvoiceType}
+// @Router		/api/invoiceType/list [get]
+func (s *InvoiceTypeApi) List(c *gin.Context) {
+	var params request.GetInvoiceTypeList
+	ctx, ok := contextx.NewContext(c, &params)
+	if !ok {
+		return
+	}
+
+	invoiceType, total, errCode := service.NewInvoiceTypeService().GetInvoiceTypeList()
+	if errCode != ecode.OK {
+		ctx.Fail(errCode)
+		return
+	}
+
+	ctx.OkWithDetailed(response.ListResponse{
+		Data: invoiceType,
+		Count: total,
+	})
+}
diff --git a/api/v1/serviceCollectionPlan.go b/api/v1/serviceCollectionPlan.go
index 7476dd7..346aec8 100644
--- a/api/v1/serviceCollectionPlan.go
+++ b/api/v1/serviceCollectionPlan.go
@@ -1,6 +1,7 @@
 package v1
 
 import (
+	"aps_crm/constvar"
 	"aps_crm/model/request"
 	"aps_crm/model/response"
 	"aps_crm/pkg/contextx"
@@ -13,8 +14,8 @@
 type ServiceCollectionPlanApi struct{}
 
 // Add
-// @Tags		鏈嶅姟鍚堝悓鏀舵璁″垝绠$悊
-// @Summary	娣诲姞鏈嶅姟鍚堝悓鏀舵璁″垝
+// @Tags		鏀舵璁″垝绠$悊
+// @Summary	娣诲姞鏀舵璁″垝
 // @Produce	application/json
 // @Param		object	body		request.AddServiceCollectionPlan	true	"鏌ヨ鍙傛暟"
 // @Success	200		{object}	contextx.Response{}
@@ -24,6 +25,20 @@
 	ctx, ok := contextx.NewContext(c, &params)
 	if !ok {
 		return
+	}
+
+	for _, plan := range params.List {
+		if plan.SourceType == 0 ||
+			plan.SourceId == 0 ||
+			plan.CollectionType == 0 ||
+			plan.CollectionDate.IsZero() ||
+			plan.Amount.IsZero() ||
+			plan.Percent.IsZero() ||
+			plan.PrincipalId == 0 {
+			ctx.Fail(ecode.ParamsErr)
+			return
+		}
+		plan.Status = constvar.CollectionStatusUnCollected
 	}
 
 	errCode := service.NewServiceCollectionPlanService().AddServiceCollectionPlan(params.List)
@@ -36,8 +51,8 @@
 }
 
 // Delete
-// @Tags		鏈嶅姟鍚堝悓鏀舵璁″垝绠$悊
-// @Summary	鍒犻櫎鏈嶅姟鍚堝悓鏀舵璁″垝
+// @Tags		鏀舵璁″垝绠$悊
+// @Summary	鍒犻櫎鏀舵璁″垝
 // @Produce	application/json
 // @Param		id	path		int	true	"鏌ヨ鍙傛暟"
 // @Success	200	{object}	contextx.Response{}
@@ -59,8 +74,8 @@
 }
 
 // Update
-// @Tags		鏈嶅姟鍚堝悓鏀舵璁″垝绠$悊
-// @Summary	鏇存柊鏈嶅姟鍚堝悓鏀舵璁″垝
+// @Tags		鏀舵璁″垝绠$悊
+// @Summary	鏇存柊鏀舵璁″垝
 // @Produce	application/json
 // @Param		object	body		request.UpdateServiceCollectionPlan	true	"鏌ヨ鍙傛暟"
 // @Success	200		{object}	contextx.Response{}
@@ -86,8 +101,8 @@
 }
 
 // List
-// @Tags		鏈嶅姟鍚堝悓鏀舵璁″垝绠$悊
-// @Summary	鑾峰彇鏈嶅姟鍚堝悓鏀舵璁″垝鍒楄〃
+// @Tags		鏀舵璁″垝绠$悊
+// @Summary	鑾峰彇鏀舵璁″垝鍒楄〃
 // @Produce	application/json
 // @Param		object	query		request.GetServiceCollectionPlanList	true	"鍙傛暟"
 // @Success	200	{object}	response.ListResponse{data=[]model.ServiceCollectionPlan}
diff --git a/constvar/courierCompany.go b/constvar/courierCompany.go
new file mode 100644
index 0000000..648d18a
--- /dev/null
+++ b/constvar/courierCompany.go
@@ -0,0 +1,12 @@
+package constvar
+type CourierCompanyQueryClass string
+
+const (
+	CourierCompanyQueryClassExpireLessThen60Days CourierCompanyQueryClass = ""
+)
+
+type CourierCompanyKeywordType string
+
+const (
+	CourierCompanyKeywordCustomerName   CourierCompanyKeywordType = ""
+)
diff --git a/constvar/invoice.go b/constvar/invoice.go
new file mode 100644
index 0000000..687d301
--- /dev/null
+++ b/constvar/invoice.go
@@ -0,0 +1,20 @@
+package constvar
+
+type InvoiceQueryClass string
+
+const (
+	InvoiceQueryClassExpireLessThen60Days InvoiceQueryClass = ""
+)
+
+type InvoiceKeywordType string
+
+const (
+	InvoiceKeywordCustomerName InvoiceKeywordType = ""
+)
+
+type InvoiceSourceType int
+
+const (
+	InvoiceSourceTypeSaleDetail      InvoiceSourceType = 1
+	InvoiceSourceTypeServiceContract InvoiceSourceType = 2
+)
diff --git a/constvar/invoiceStatus.go b/constvar/invoiceStatus.go
new file mode 100644
index 0000000..068f4d6
--- /dev/null
+++ b/constvar/invoiceStatus.go
@@ -0,0 +1,12 @@
+package constvar
+type InvoiceStatusQueryClass string
+
+const (
+	InvoiceStatusQueryClassExpireLessThen60Days InvoiceStatusQueryClass = ""
+)
+
+type InvoiceStatusKeywordType string
+
+const (
+	InvoiceStatusKeywordCustomerName   InvoiceStatusKeywordType = ""
+)
diff --git a/constvar/invoiceType.go b/constvar/invoiceType.go
new file mode 100644
index 0000000..fb019b6
--- /dev/null
+++ b/constvar/invoiceType.go
@@ -0,0 +1,12 @@
+package constvar
+type InvoiceTypeQueryClass string
+
+const (
+	InvoiceTypeQueryClassExpireLessThen60Days InvoiceTypeQueryClass = ""
+)
+
+type InvoiceTypeKeywordType string
+
+const (
+	InvoiceTypeKeywordCustomerName   InvoiceTypeKeywordType = ""
+)
diff --git a/constvar/serviceCollectionPlan.go b/constvar/serviceCollectionPlan.go
index 32450ec..6f32e72 100644
--- a/constvar/serviceCollectionPlan.go
+++ b/constvar/serviceCollectionPlan.go
@@ -1,4 +1,5 @@
 package constvar
+
 type ServiceCollectionPlanQueryClass string
 
 const (
@@ -8,5 +9,12 @@
 type ServiceCollectionPlanKeywordType string
 
 const (
-	ServiceCollectionPlanKeywordCustomerName   ServiceCollectionPlanKeywordType = ""
+	ServiceCollectionPlanKeywordCustomerName ServiceCollectionPlanKeywordType = ""
+)
+
+type CollectionStatus int
+
+const (
+	CollectionStatusUnCollected CollectionStatus = 1 //寰呮敹娆�
+	CollectionStatusCollected   CollectionStatus = 2 //宸叉敹娆�
 )
diff --git a/docs/docs.go b/docs/docs.go
index 972bdd5..54c4026 100644
--- a/docs/docs.go
+++ b/docs/docs.go
@@ -1625,6 +1625,169 @@
                 }
             }
         },
+        "/api/courierCompany/add": {
+            "post": {
+                "produces": [
+                    "application/json"
+                ],
+                "tags": [
+                    "鐗╂祦鍏徃"
+                ],
+                "summary": "娣诲姞鐗╂祦鍏徃",
+                "parameters": [
+                    {
+                        "description": "鏌ヨ鍙傛暟",
+                        "name": "object",
+                        "in": "body",
+                        "required": true,
+                        "schema": {
+                            "$ref": "#/definitions/request.AddCourierCompany"
+                        }
+                    }
+                ],
+                "responses": {
+                    "200": {
+                        "description": "OK",
+                        "schema": {
+                            "$ref": "#/definitions/contextx.Response"
+                        }
+                    }
+                }
+            }
+        },
+        "/api/courierCompany/delete/{id}": {
+            "delete": {
+                "produces": [
+                    "application/json"
+                ],
+                "tags": [
+                    "鐗╂祦鍏徃"
+                ],
+                "summary": "鍒犻櫎鐗╂祦鍏徃",
+                "parameters": [
+                    {
+                        "type": "integer",
+                        "description": "鏌ヨ鍙傛暟",
+                        "name": "id",
+                        "in": "path",
+                        "required": true
+                    }
+                ],
+                "responses": {
+                    "200": {
+                        "description": "OK",
+                        "schema": {
+                            "$ref": "#/definitions/contextx.Response"
+                        }
+                    }
+                }
+            }
+        },
+        "/api/courierCompany/list": {
+            "get": {
+                "produces": [
+                    "application/json"
+                ],
+                "tags": [
+                    "鐗╂祦鍏徃"
+                ],
+                "summary": "鑾峰彇鐗╂祦鍏徃鍒楄〃",
+                "parameters": [
+                    {
+                        "type": "string",
+                        "name": "keyword",
+                        "in": "query"
+                    },
+                    {
+                        "enum": [
+                            ""
+                        ],
+                        "type": "string",
+                        "x-enum-varnames": [
+                            "CourierCompanyKeywordCustomerName"
+                        ],
+                        "name": "keywordType",
+                        "in": "query"
+                    },
+                    {
+                        "type": "integer",
+                        "description": "椤电爜",
+                        "name": "page",
+                        "in": "query"
+                    },
+                    {
+                        "type": "integer",
+                        "description": "姣忛〉澶у皬",
+                        "name": "pageSize",
+                        "in": "query"
+                    },
+                    {
+                        "enum": [
+                            ""
+                        ],
+                        "type": "string",
+                        "x-enum-varnames": [
+                            "CourierCompanyQueryClassExpireLessThen60Days"
+                        ],
+                        "name": "queryClass",
+                        "in": "query"
+                    }
+                ],
+                "responses": {
+                    "200": {
+                        "description": "OK",
+                        "schema": {
+                            "allOf": [
+                                {
+                                    "$ref": "#/definitions/response.ListResponse"
+                                },
+                                {
+                                    "type": "object",
+                                    "properties": {
+                                        "data": {
+                                            "type": "array",
+                                            "items": {
+                                                "$ref": "#/definitions/model.CourierCompany"
+                                            }
+                                        }
+                                    }
+                                }
+                            ]
+                        }
+                    }
+                }
+            }
+        },
+        "/api/courierCompany/update": {
+            "put": {
+                "produces": [
+                    "application/json"
+                ],
+                "tags": [
+                    "鐗╂祦鍏徃"
+                ],
+                "summary": "鏇存柊鐗╂祦鍏徃",
+                "parameters": [
+                    {
+                        "description": "鏌ヨ鍙傛暟",
+                        "name": "object",
+                        "in": "body",
+                        "required": true,
+                        "schema": {
+                            "$ref": "#/definitions/request.UpdateCourierCompany"
+                        }
+                    }
+                ],
+                "responses": {
+                    "200": {
+                        "description": "OK",
+                        "schema": {
+                            "$ref": "#/definitions/contextx.Response"
+                        }
+                    }
+                }
+            }
+        },
         "/api/currency/add": {
             "post": {
                 "produces": [
@@ -2505,13 +2668,25 @@
                 "summary": "娣诲姞闄勪欢",
                 "parameters": [
                     {
-                        "description": "鏌ヨ鍙傛暟",
-                        "name": "object",
-                        "in": "body",
-                        "required": true,
-                        "schema": {
-                            "$ref": "#/definitions/request.AddFile"
-                        }
+                        "type": "integer",
+                        "description": "鏉ユ簮id",
+                        "name": "sourceId",
+                        "in": "formData",
+                        "required": true
+                    },
+                    {
+                        "type": "string",
+                        "description": "闄勪欢鏉ユ簮",
+                        "name": "sourceType",
+                        "in": "formData",
+                        "required": true
+                    },
+                    {
+                        "type": "file",
+                        "description": "涓婁紶鏂囦欢",
+                        "name": "file",
+                        "in": "formData",
+                        "required": true
                     }
                 ],
                 "responses": {
@@ -2622,36 +2797,6 @@
                                     }
                                 }
                             ]
-                        }
-                    }
-                }
-            }
-        },
-        "/api/file/update": {
-            "put": {
-                "produces": [
-                    "application/json"
-                ],
-                "tags": [
-                    "闄勪欢绠$悊"
-                ],
-                "summary": "鏇存柊闄勪欢",
-                "parameters": [
-                    {
-                        "description": "鏌ヨ鍙傛暟",
-                        "name": "object",
-                        "in": "body",
-                        "required": true,
-                        "schema": {
-                            "$ref": "#/definitions/request.UpdateFile"
-                        }
-                    }
-                ],
-                "responses": {
-                    "200": {
-                        "description": "OK",
-                        "schema": {
-                            "$ref": "#/definitions/contextx.Response"
                         }
                     }
                 }
@@ -2926,6 +3071,495 @@
                         "required": true,
                         "schema": {
                             "$ref": "#/definitions/request.UpdateIndustries"
+                        }
+                    }
+                ],
+                "responses": {
+                    "200": {
+                        "description": "OK",
+                        "schema": {
+                            "$ref": "#/definitions/contextx.Response"
+                        }
+                    }
+                }
+            }
+        },
+        "/api/invoice/add": {
+            "post": {
+                "produces": [
+                    "application/json"
+                ],
+                "tags": [
+                    "閿�鍞彂绁�"
+                ],
+                "summary": "娣诲姞閿�鍞彂绁�",
+                "parameters": [
+                    {
+                        "description": "鏌ヨ鍙傛暟",
+                        "name": "object",
+                        "in": "body",
+                        "required": true,
+                        "schema": {
+                            "$ref": "#/definitions/request.AddInvoice"
+                        }
+                    }
+                ],
+                "responses": {
+                    "200": {
+                        "description": "OK",
+                        "schema": {
+                            "$ref": "#/definitions/contextx.Response"
+                        }
+                    }
+                }
+            }
+        },
+        "/api/invoice/delete/{id}": {
+            "delete": {
+                "produces": [
+                    "application/json"
+                ],
+                "tags": [
+                    "閿�鍞彂绁�"
+                ],
+                "summary": "鍒犻櫎閿�鍞彂绁�",
+                "parameters": [
+                    {
+                        "type": "integer",
+                        "description": "鏌ヨ鍙傛暟",
+                        "name": "id",
+                        "in": "path",
+                        "required": true
+                    }
+                ],
+                "responses": {
+                    "200": {
+                        "description": "OK",
+                        "schema": {
+                            "$ref": "#/definitions/contextx.Response"
+                        }
+                    }
+                }
+            }
+        },
+        "/api/invoice/list": {
+            "get": {
+                "produces": [
+                    "application/json"
+                ],
+                "tags": [
+                    "閿�鍞彂绁�"
+                ],
+                "summary": "鑾峰彇閿�鍞彂绁ㄥ垪琛�",
+                "parameters": [
+                    {
+                        "type": "string",
+                        "name": "keyword",
+                        "in": "query"
+                    },
+                    {
+                        "enum": [
+                            ""
+                        ],
+                        "type": "string",
+                        "x-enum-varnames": [
+                            "InvoiceKeywordCustomerName"
+                        ],
+                        "name": "keywordType",
+                        "in": "query"
+                    },
+                    {
+                        "type": "integer",
+                        "description": "椤电爜",
+                        "name": "page",
+                        "in": "query"
+                    },
+                    {
+                        "type": "integer",
+                        "description": "姣忛〉澶у皬",
+                        "name": "pageSize",
+                        "in": "query"
+                    },
+                    {
+                        "enum": [
+                            ""
+                        ],
+                        "type": "string",
+                        "x-enum-varnames": [
+                            "InvoiceQueryClassExpireLessThen60Days"
+                        ],
+                        "name": "queryClass",
+                        "in": "query"
+                    }
+                ],
+                "responses": {
+                    "200": {
+                        "description": "OK",
+                        "schema": {
+                            "allOf": [
+                                {
+                                    "$ref": "#/definitions/response.ListResponse"
+                                },
+                                {
+                                    "type": "object",
+                                    "properties": {
+                                        "data": {
+                                            "type": "array",
+                                            "items": {
+                                                "$ref": "#/definitions/model.Invoice"
+                                            }
+                                        }
+                                    }
+                                }
+                            ]
+                        }
+                    }
+                }
+            }
+        },
+        "/api/invoice/update": {
+            "put": {
+                "produces": [
+                    "application/json"
+                ],
+                "tags": [
+                    "閿�鍞彂绁�"
+                ],
+                "summary": "鏇存柊閿�鍞彂绁�",
+                "parameters": [
+                    {
+                        "description": "鏌ヨ鍙傛暟",
+                        "name": "object",
+                        "in": "body",
+                        "required": true,
+                        "schema": {
+                            "$ref": "#/definitions/request.UpdateInvoice"
+                        }
+                    }
+                ],
+                "responses": {
+                    "200": {
+                        "description": "OK",
+                        "schema": {
+                            "$ref": "#/definitions/contextx.Response"
+                        }
+                    }
+                }
+            }
+        },
+        "/api/invoiceStatus/add": {
+            "post": {
+                "produces": [
+                    "application/json"
+                ],
+                "tags": [
+                    "鍙戠エ鐘舵��"
+                ],
+                "summary": "娣诲姞鍙戠エ鐘舵��",
+                "parameters": [
+                    {
+                        "description": "鏌ヨ鍙傛暟",
+                        "name": "object",
+                        "in": "body",
+                        "required": true,
+                        "schema": {
+                            "$ref": "#/definitions/request.AddInvoiceStatus"
+                        }
+                    }
+                ],
+                "responses": {
+                    "200": {
+                        "description": "OK",
+                        "schema": {
+                            "$ref": "#/definitions/contextx.Response"
+                        }
+                    }
+                }
+            }
+        },
+        "/api/invoiceStatus/delete/{id}": {
+            "delete": {
+                "produces": [
+                    "application/json"
+                ],
+                "tags": [
+                    "鍙戠エ鐘舵��"
+                ],
+                "summary": "鍒犻櫎鍙戠エ鐘舵��",
+                "parameters": [
+                    {
+                        "type": "integer",
+                        "description": "鏌ヨ鍙傛暟",
+                        "name": "id",
+                        "in": "path",
+                        "required": true
+                    }
+                ],
+                "responses": {
+                    "200": {
+                        "description": "OK",
+                        "schema": {
+                            "$ref": "#/definitions/contextx.Response"
+                        }
+                    }
+                }
+            }
+        },
+        "/api/invoiceStatus/list": {
+            "get": {
+                "produces": [
+                    "application/json"
+                ],
+                "tags": [
+                    "鍙戠エ鐘舵��"
+                ],
+                "summary": "鑾峰彇鍙戠エ鐘舵�佸垪琛�",
+                "parameters": [
+                    {
+                        "type": "string",
+                        "name": "keyword",
+                        "in": "query"
+                    },
+                    {
+                        "enum": [
+                            ""
+                        ],
+                        "type": "string",
+                        "x-enum-varnames": [
+                            "InvoiceStatusKeywordCustomerName"
+                        ],
+                        "name": "keywordType",
+                        "in": "query"
+                    },
+                    {
+                        "type": "integer",
+                        "description": "椤电爜",
+                        "name": "page",
+                        "in": "query"
+                    },
+                    {
+                        "type": "integer",
+                        "description": "姣忛〉澶у皬",
+                        "name": "pageSize",
+                        "in": "query"
+                    },
+                    {
+                        "enum": [
+                            ""
+                        ],
+                        "type": "string",
+                        "x-enum-varnames": [
+                            "InvoiceStatusQueryClassExpireLessThen60Days"
+                        ],
+                        "name": "queryClass",
+                        "in": "query"
+                    }
+                ],
+                "responses": {
+                    "200": {
+                        "description": "OK",
+                        "schema": {
+                            "allOf": [
+                                {
+                                    "$ref": "#/definitions/response.ListResponse"
+                                },
+                                {
+                                    "type": "object",
+                                    "properties": {
+                                        "data": {
+                                            "type": "array",
+                                            "items": {
+                                                "$ref": "#/definitions/model.InvoiceStatus"
+                                            }
+                                        }
+                                    }
+                                }
+                            ]
+                        }
+                    }
+                }
+            }
+        },
+        "/api/invoiceStatus/update": {
+            "put": {
+                "produces": [
+                    "application/json"
+                ],
+                "tags": [
+                    "鍙戠エ鐘舵��"
+                ],
+                "summary": "鏇存柊鍙戠エ鐘舵��",
+                "parameters": [
+                    {
+                        "description": "鏌ヨ鍙傛暟",
+                        "name": "object",
+                        "in": "body",
+                        "required": true,
+                        "schema": {
+                            "$ref": "#/definitions/request.UpdateInvoiceStatus"
+                        }
+                    }
+                ],
+                "responses": {
+                    "200": {
+                        "description": "OK",
+                        "schema": {
+                            "$ref": "#/definitions/contextx.Response"
+                        }
+                    }
+                }
+            }
+        },
+        "/api/invoiceType/add": {
+            "post": {
+                "produces": [
+                    "application/json"
+                ],
+                "tags": [
+                    "鍙戠エ绫诲瀷"
+                ],
+                "summary": "娣诲姞鍙戠エ绫诲瀷",
+                "parameters": [
+                    {
+                        "description": "鏌ヨ鍙傛暟",
+                        "name": "object",
+                        "in": "body",
+                        "required": true,
+                        "schema": {
+                            "$ref": "#/definitions/request.AddInvoiceType"
+                        }
+                    }
+                ],
+                "responses": {
+                    "200": {
+                        "description": "OK",
+                        "schema": {
+                            "$ref": "#/definitions/contextx.Response"
+                        }
+                    }
+                }
+            }
+        },
+        "/api/invoiceType/delete/{id}": {
+            "delete": {
+                "produces": [
+                    "application/json"
+                ],
+                "tags": [
+                    "鍙戠エ绫诲瀷"
+                ],
+                "summary": "鍒犻櫎鍙戠エ绫诲瀷",
+                "parameters": [
+                    {
+                        "type": "integer",
+                        "description": "鏌ヨ鍙傛暟",
+                        "name": "id",
+                        "in": "path",
+                        "required": true
+                    }
+                ],
+                "responses": {
+                    "200": {
+                        "description": "OK",
+                        "schema": {
+                            "$ref": "#/definitions/contextx.Response"
+                        }
+                    }
+                }
+            }
+        },
+        "/api/invoiceType/list": {
+            "get": {
+                "produces": [
+                    "application/json"
+                ],
+                "tags": [
+                    "鍙戠エ绫诲瀷"
+                ],
+                "summary": "鑾峰彇鍙戠エ绫诲瀷鍒楄〃",
+                "parameters": [
+                    {
+                        "type": "string",
+                        "name": "keyword",
+                        "in": "query"
+                    },
+                    {
+                        "enum": [
+                            ""
+                        ],
+                        "type": "string",
+                        "x-enum-varnames": [
+                            "InvoiceTypeKeywordCustomerName"
+                        ],
+                        "name": "keywordType",
+                        "in": "query"
+                    },
+                    {
+                        "type": "integer",
+                        "description": "椤电爜",
+                        "name": "page",
+                        "in": "query"
+                    },
+                    {
+                        "type": "integer",
+                        "description": "姣忛〉澶у皬",
+                        "name": "pageSize",
+                        "in": "query"
+                    },
+                    {
+                        "enum": [
+                            ""
+                        ],
+                        "type": "string",
+                        "x-enum-varnames": [
+                            "InvoiceTypeQueryClassExpireLessThen60Days"
+                        ],
+                        "name": "queryClass",
+                        "in": "query"
+                    }
+                ],
+                "responses": {
+                    "200": {
+                        "description": "OK",
+                        "schema": {
+                            "allOf": [
+                                {
+                                    "$ref": "#/definitions/response.ListResponse"
+                                },
+                                {
+                                    "type": "object",
+                                    "properties": {
+                                        "data": {
+                                            "type": "array",
+                                            "items": {
+                                                "$ref": "#/definitions/model.InvoiceType"
+                                            }
+                                        }
+                                    }
+                                }
+                            ]
+                        }
+                    }
+                }
+            }
+        },
+        "/api/invoiceType/update": {
+            "put": {
+                "produces": [
+                    "application/json"
+                ],
+                "tags": [
+                    "鍙戠エ绫诲瀷"
+                ],
+                "summary": "鏇存柊鍙戠エ绫诲瀷",
+                "parameters": [
+                    {
+                        "description": "鏌ヨ鍙傛暟",
+                        "name": "object",
+                        "in": "body",
+                        "required": true,
+                        "schema": {
+                            "$ref": "#/definitions/request.UpdateInvoiceType"
                         }
                     }
                 ],
@@ -6701,9 +7335,9 @@
                     "application/json"
                 ],
                 "tags": [
-                    "鏈嶅姟鍚堝悓鏀舵璁″垝绠$悊"
+                    "鏀舵璁″垝绠$悊"
                 ],
-                "summary": "娣诲姞鏈嶅姟鍚堝悓鏀舵璁″垝",
+                "summary": "娣诲姞鏀舵璁″垝",
                 "parameters": [
                     {
                         "description": "鏌ヨ鍙傛暟",
@@ -6731,9 +7365,9 @@
                     "application/json"
                 ],
                 "tags": [
-                    "鏈嶅姟鍚堝悓鏀舵璁″垝绠$悊"
+                    "鏀舵璁″垝绠$悊"
                 ],
-                "summary": "鍒犻櫎鏈嶅姟鍚堝悓鏀舵璁″垝",
+                "summary": "鍒犻櫎鏀舵璁″垝",
                 "parameters": [
                     {
                         "type": "integer",
@@ -6759,9 +7393,9 @@
                     "application/json"
                 ],
                 "tags": [
-                    "鏈嶅姟鍚堝悓鏀舵璁″垝绠$悊"
+                    "鏀舵璁″垝绠$悊"
                 ],
-                "summary": "鑾峰彇鏈嶅姟鍚堝悓鏀舵璁″垝鍒楄〃",
+                "summary": "鑾峰彇鏀舵璁″垝鍒楄〃",
                 "parameters": [
                     {
                         "type": "integer",
@@ -6801,9 +7435,9 @@
                     "application/json"
                 ],
                 "tags": [
-                    "鏈嶅姟鍚堝悓鏀舵璁″垝绠$悊"
+                    "鏀舵璁″垝绠$悊"
                 ],
-                "summary": "鏇存柊鏈嶅姟鍚堝悓鏀舵璁″垝",
+                "summary": "鏇存柊鏀舵璁″垝",
                 "parameters": [
                     {
                         "description": "鏌ヨ鍙傛暟",
@@ -8755,6 +9389,39 @@
                 "BankAccountQueryClassExpireLessThen60Days"
             ]
         },
+        "constvar.CollectionStatus": {
+            "type": "integer",
+            "enum": [
+                1,
+                2
+            ],
+            "x-enum-comments": {
+                "CollectionStatusCollected": "宸叉敹娆�",
+                "CollectionStatusUnCollected": "寰呮敹娆�"
+            },
+            "x-enum-varnames": [
+                "CollectionStatusUnCollected",
+                "CollectionStatusCollected"
+            ]
+        },
+        "constvar.CourierCompanyKeywordType": {
+            "type": "string",
+            "enum": [
+                ""
+            ],
+            "x-enum-varnames": [
+                "CourierCompanyKeywordCustomerName"
+            ]
+        },
+        "constvar.CourierCompanyQueryClass": {
+            "type": "string",
+            "enum": [
+                ""
+            ],
+            "x-enum-varnames": [
+                "CourierCompanyQueryClassExpireLessThen60Days"
+            ]
+        },
         "constvar.FaqKeywordType": {
             "type": "string",
             "enum": [
@@ -8789,6 +9456,71 @@
             ],
             "x-enum-varnames": [
                 "FileQueryClassExpireLessThen60Days"
+            ]
+        },
+        "constvar.InvoiceKeywordType": {
+            "type": "string",
+            "enum": [
+                ""
+            ],
+            "x-enum-varnames": [
+                "InvoiceKeywordCustomerName"
+            ]
+        },
+        "constvar.InvoiceQueryClass": {
+            "type": "string",
+            "enum": [
+                ""
+            ],
+            "x-enum-varnames": [
+                "InvoiceQueryClassExpireLessThen60Days"
+            ]
+        },
+        "constvar.InvoiceSourceType": {
+            "type": "integer",
+            "enum": [
+                1,
+                2
+            ],
+            "x-enum-varnames": [
+                "InvoiceSourceTypeSaleDetail",
+                "InvoiceSourceTypeServiceContract"
+            ]
+        },
+        "constvar.InvoiceStatusKeywordType": {
+            "type": "string",
+            "enum": [
+                ""
+            ],
+            "x-enum-varnames": [
+                "InvoiceStatusKeywordCustomerName"
+            ]
+        },
+        "constvar.InvoiceStatusQueryClass": {
+            "type": "string",
+            "enum": [
+                ""
+            ],
+            "x-enum-varnames": [
+                "InvoiceStatusQueryClassExpireLessThen60Days"
+            ]
+        },
+        "constvar.InvoiceTypeKeywordType": {
+            "type": "string",
+            "enum": [
+                ""
+            ],
+            "x-enum-varnames": [
+                "InvoiceTypeKeywordCustomerName"
+            ]
+        },
+        "constvar.InvoiceTypeQueryClass": {
+            "type": "string",
+            "enum": [
+                ""
+            ],
+            "x-enum-varnames": [
+                "InvoiceTypeQueryClassExpireLessThen60Days"
             ]
         },
         "constvar.PaymentTypeKeywordType": {
@@ -9405,6 +10137,17 @@
                 }
             }
         },
+        "model.CourierCompany": {
+            "type": "object",
+            "properties": {
+                "id": {
+                    "type": "integer"
+                },
+                "name": {
+                    "type": "string"
+                }
+            }
+        },
         "model.Currency": {
             "type": "object",
             "properties": {
@@ -9504,14 +10247,6 @@
                     "description": "瀵硅薄瀛樺偍bucket",
                     "type": "string"
                 },
-                "content": {
-                    "description": "鏂囦欢鍐呭",
-                    "type": "string"
-                },
-                "createTime": {
-                    "description": "鍒涘缓鏃堕棿",
-                    "type": "string"
-                },
                 "downloadCount": {
                     "description": "涓嬫娆℃暟",
                     "type": "integer"
@@ -9523,9 +10258,6 @@
                 "fileType": {
                     "description": "鏂囦欢绫诲瀷",
                     "type": "string"
-                },
-                "id": {
-                    "type": "integer"
                 },
                 "key": {
                     "description": "瀵硅薄瀛樺偍key",
@@ -9548,9 +10280,6 @@
                 },
                 "sourceType": {
                     "description": "闄勪欢鏉ユ簮",
-                    "type": "string"
-                },
-                "updateTime": {
                     "type": "string"
                 }
             }
@@ -9612,6 +10341,100 @@
             }
         },
         "model.Industry": {
+            "type": "object",
+            "properties": {
+                "id": {
+                    "type": "integer"
+                },
+                "name": {
+                    "type": "string"
+                }
+            }
+        },
+        "model.Invoice": {
+            "type": "object",
+            "properties": {
+                "client": {
+                    "$ref": "#/definitions/model.Client"
+                },
+                "clientId": {
+                    "description": "瀹㈡埛id",
+                    "type": "integer"
+                },
+                "courierCompany": {
+                    "$ref": "#/definitions/model.CourierCompany"
+                },
+                "courierCompanyId": {
+                    "description": "鐗╂祦鍏徃",
+                    "type": "integer"
+                },
+                "courierNumber": {
+                    "description": "鐗╂祦鍗曞彿",
+                    "type": "string"
+                },
+                "id": {
+                    "type": "integer"
+                },
+                "invoiceDate": {
+                    "description": "寮�绁ㄦ棩鏈�",
+                    "type": "string"
+                },
+                "invoiceNumber": {
+                    "description": "鍙戠エ鍙风爜",
+                    "type": "string"
+                },
+                "invoiceStatus": {
+                    "$ref": "#/definitions/model.InvoiceStatus"
+                },
+                "invoiceStatusId": {
+                    "description": "鍙戠エ鐘舵�乮d",
+                    "type": "integer"
+                },
+                "invoiceType": {
+                    "$ref": "#/definitions/model.InvoiceType"
+                },
+                "invoiceTypeId": {
+                    "description": "鍙戠エ绫诲瀷id",
+                    "type": "integer"
+                },
+                "principalId": {
+                    "description": "閿�鍞礋璐d汉id",
+                    "type": "integer"
+                },
+                "sourceId": {
+                    "description": "婧愬崟id",
+                    "type": "integer"
+                },
+                "sourceType": {
+                    "description": "婧愬崟绫诲瀷(1閿�鍞槑缁嗗崟2鏈嶅姟鍚堝悓)",
+                    "allOf": [
+                        {
+                            "$ref": "#/definitions/constvar.InvoiceSourceType"
+                        }
+                    ]
+                },
+                "subject": {
+                    "description": "涓婚",
+                    "type": "string"
+                },
+                "taxpayerIdNumber": {
+                    "description": "绾崇◣璇嗗埆鍙�",
+                    "type": "string"
+                }
+            }
+        },
+        "model.InvoiceStatus": {
+            "type": "object",
+            "properties": {
+                "id": {
+                    "type": "integer"
+                },
+                "name": {
+                    "type": "string"
+                }
+            }
+        },
+        "model.InvoiceType": {
             "type": "object",
             "properties": {
                 "id": {
@@ -10459,13 +11282,21 @@
                     "description": "澶囨敞",
                     "type": "string"
                 },
-                "serviceContractId": {
-                    "description": "鏈嶅姟鍚堝悓id",
+                "sourceId": {
+                    "description": "婧愬崟id",
+                    "type": "integer"
+                },
+                "sourceType": {
+                    "description": "婧愬崟绫诲瀷锛�1閿�鍞槑缁�2鏈嶅姟鍚堝悓3閿�鍞彂绁級",
                     "type": "integer"
                 },
                 "status": {
                     "description": "鐘舵�侊紙1鏈敹2宸叉敹锛�",
-                    "type": "integer"
+                    "allOf": [
+                        {
+                            "$ref": "#/definitions/constvar.CollectionStatus"
+                        }
+                    ]
                 },
                 "term": {
                     "description": "鏈熸",
@@ -10476,6 +11307,18 @@
         "model.ServiceContract": {
             "type": "object",
             "properties": {
+                "amountInvoiced": {
+                    "description": "宸插紑绁ㄩ噾棰�",
+                    "type": "number"
+                },
+                "amountReceivable": {
+                    "description": "搴旀敹閲戦",
+                    "type": "number"
+                },
+                "amountReceived": {
+                    "description": "宸叉敹閲戦",
+                    "type": "number"
+                },
                 "clientId": {
                     "type": "integer"
                 },
@@ -11203,6 +12046,17 @@
                 }
             }
         },
+        "request.AddCourierCompany": {
+            "type": "object",
+            "properties": {
+                "id": {
+                    "type": "integer"
+                },
+                "name": {
+                    "type": "string"
+                }
+            }
+        },
         "request.AddCurrency": {
             "type": "object",
             "required": [
@@ -11289,23 +12143,6 @@
                 }
             }
         },
-        "request.AddFile": {
-            "type": "object",
-            "required": [
-                "sourceId",
-                "sourceType"
-            ],
-            "properties": {
-                "sourceId": {
-                    "description": "鏉ユ簮id",
-                    "type": "integer"
-                },
-                "sourceType": {
-                    "description": "闄勪欢鏉ユ簮",
-                    "type": "string"
-                }
-            }
-        },
         "request.AddFollowRecord": {
             "type": "object",
             "required": [
@@ -11323,6 +12160,85 @@
                 "name"
             ],
             "properties": {
+                "name": {
+                    "type": "string"
+                }
+            }
+        },
+        "request.AddInvoice": {
+            "type": "object",
+            "properties": {
+                "clientId": {
+                    "description": "瀹㈡埛id",
+                    "type": "integer"
+                },
+                "courierCompanyId": {
+                    "description": "鐗╂祦鍏徃",
+                    "type": "integer"
+                },
+                "courierNumber": {
+                    "description": "鐗╂祦鍗曞彿",
+                    "type": "string"
+                },
+                "invoiceDate": {
+                    "description": "寮�绁ㄦ棩鏈�",
+                    "type": "string"
+                },
+                "invoiceNumber": {
+                    "description": "鍙戠エ鍙风爜",
+                    "type": "string"
+                },
+                "invoiceStatusId": {
+                    "description": "鍙戠エ鐘舵�乮d",
+                    "type": "integer"
+                },
+                "invoiceTypeId": {
+                    "description": "鍙戠エ绫诲瀷id",
+                    "type": "integer"
+                },
+                "principalId": {
+                    "description": "閿�鍞礋璐d汉id",
+                    "type": "integer"
+                },
+                "sourceId": {
+                    "description": "婧愬崟id",
+                    "type": "integer"
+                },
+                "sourceType": {
+                    "description": "婧愬崟绫诲瀷(1閿�鍞槑缁嗗崟2鏈嶅姟鍚堝悓)",
+                    "allOf": [
+                        {
+                            "$ref": "#/definitions/constvar.InvoiceSourceType"
+                        }
+                    ]
+                },
+                "subject": {
+                    "description": "涓婚",
+                    "type": "string"
+                },
+                "taxpayerIdNumber": {
+                    "description": "绾崇◣璇嗗埆鍙�",
+                    "type": "string"
+                }
+            }
+        },
+        "request.AddInvoiceStatus": {
+            "type": "object",
+            "properties": {
+                "id": {
+                    "type": "integer"
+                },
+                "name": {
+                    "type": "string"
+                }
+            }
+        },
+        "request.AddInvoiceType": {
+            "type": "object",
+            "properties": {
+                "id": {
+                    "type": "integer"
+                },
                 "name": {
                     "type": "string"
                 }
@@ -11855,6 +12771,9 @@
         },
         "request.AddServiceCollectionPlan": {
             "type": "object",
+            "required": [
+                "list"
+            ],
             "properties": {
                 "list": {
                     "type": "array",
@@ -13611,6 +14530,17 @@
                 }
             }
         },
+        "request.UpdateCourierCompany": {
+            "type": "object",
+            "properties": {
+                "id": {
+                    "type": "integer"
+                },
+                "name": {
+                    "type": "string"
+                }
+            }
+        },
         "request.UpdateCurrency": {
             "type": "object",
             "required": [
@@ -13766,64 +14696,6 @@
                 }
             }
         },
-        "request.UpdateFile": {
-            "type": "object",
-            "properties": {
-                "bucket": {
-                    "description": "瀵硅薄瀛樺偍bucket",
-                    "type": "string"
-                },
-                "content": {
-                    "description": "鏂囦欢鍐呭",
-                    "type": "string"
-                },
-                "createTime": {
-                    "description": "鍒涘缓鏃堕棿",
-                    "type": "string"
-                },
-                "downloadCount": {
-                    "description": "涓嬫娆℃暟",
-                    "type": "integer"
-                },
-                "filePath": {
-                    "description": "鏂囦欢璺緞",
-                    "type": "string"
-                },
-                "fileType": {
-                    "description": "鏂囦欢绫诲瀷",
-                    "type": "string"
-                },
-                "id": {
-                    "type": "integer"
-                },
-                "key": {
-                    "description": "瀵硅薄瀛樺偍key",
-                    "type": "string"
-                },
-                "name": {
-                    "type": "string"
-                },
-                "previewCount": {
-                    "description": "棰勮娆℃暟",
-                    "type": "integer"
-                },
-                "size": {
-                    "description": "鏂囦欢澶у皬",
-                    "type": "integer"
-                },
-                "sourceId": {
-                    "description": "鏉ユ簮id",
-                    "type": "integer"
-                },
-                "sourceType": {
-                    "description": "闄勪欢鏉ユ簮",
-                    "type": "string"
-                },
-                "updateTime": {
-                    "type": "string"
-                }
-            }
-        },
         "request.UpdateFollowRecord": {
             "type": "object",
             "required": [
@@ -13858,6 +14730,84 @@
                 "id",
                 "name"
             ],
+            "properties": {
+                "id": {
+                    "type": "integer"
+                },
+                "name": {
+                    "type": "string"
+                }
+            }
+        },
+        "request.UpdateInvoice": {
+            "type": "object",
+            "properties": {
+                "clientId": {
+                    "description": "瀹㈡埛id",
+                    "type": "integer"
+                },
+                "courierCompanyId": {
+                    "description": "鐗╂祦鍏徃",
+                    "type": "integer"
+                },
+                "courierNumber": {
+                    "description": "鐗╂祦鍗曞彿",
+                    "type": "string"
+                },
+                "id": {
+                    "type": "integer"
+                },
+                "invoiceDate": {
+                    "description": "寮�绁ㄦ棩鏈�",
+                    "type": "integer"
+                },
+                "invoiceNumber": {
+                    "description": "鍙戠エ鍙风爜",
+                    "type": "string"
+                },
+                "invoiceStatusId": {
+                    "description": "鍙戠エ鐘舵�乮d",
+                    "type": "integer"
+                },
+                "invoiceTypeId": {
+                    "description": "鍙戠エ绫诲瀷id",
+                    "type": "integer"
+                },
+                "principalId": {
+                    "description": "閿�鍞礋璐d汉id",
+                    "type": "integer"
+                },
+                "sourceId": {
+                    "description": "婧愬崟id",
+                    "type": "integer"
+                },
+                "sourceType": {
+                    "description": "婧愬崟绫诲瀷(1閿�鍞槑缁嗗崟2鏈嶅姟鍚堝悓)",
+                    "type": "integer"
+                },
+                "subject": {
+                    "description": "涓婚",
+                    "type": "string"
+                },
+                "taxpayerIdNumber": {
+                    "description": "绾崇◣璇嗗埆鍙�",
+                    "type": "string"
+                }
+            }
+        },
+        "request.UpdateInvoiceStatus": {
+            "type": "object",
+            "properties": {
+                "id": {
+                    "type": "integer"
+                },
+                "name": {
+                    "type": "string"
+                }
+            }
+        },
+        "request.UpdateInvoiceType": {
+            "type": "object",
             "properties": {
                 "id": {
                     "type": "integer"
@@ -14756,13 +15706,21 @@
                     "description": "澶囨敞",
                     "type": "string"
                 },
-                "serviceContractId": {
-                    "description": "鏈嶅姟鍚堝悓id",
+                "sourceId": {
+                    "description": "婧愬崟id",
+                    "type": "integer"
+                },
+                "sourceType": {
+                    "description": "婧愬崟绫诲瀷锛�1閿�鍞槑缁�2鏈嶅姟鍚堝悓3閿�鍞彂绁級",
                     "type": "integer"
                 },
                 "status": {
                     "description": "鐘舵�侊紙1鏈敹2宸叉敹锛�",
-                    "type": "integer"
+                    "allOf": [
+                        {
+                            "$ref": "#/definitions/constvar.CollectionStatus"
+                        }
+                    ]
                 },
                 "term": {
                     "description": "鏈熸",
diff --git a/docs/swagger.json b/docs/swagger.json
index 5aaf83b..3957900 100644
--- a/docs/swagger.json
+++ b/docs/swagger.json
@@ -1613,6 +1613,169 @@
                 }
             }
         },
+        "/api/courierCompany/add": {
+            "post": {
+                "produces": [
+                    "application/json"
+                ],
+                "tags": [
+                    "鐗╂祦鍏徃"
+                ],
+                "summary": "娣诲姞鐗╂祦鍏徃",
+                "parameters": [
+                    {
+                        "description": "鏌ヨ鍙傛暟",
+                        "name": "object",
+                        "in": "body",
+                        "required": true,
+                        "schema": {
+                            "$ref": "#/definitions/request.AddCourierCompany"
+                        }
+                    }
+                ],
+                "responses": {
+                    "200": {
+                        "description": "OK",
+                        "schema": {
+                            "$ref": "#/definitions/contextx.Response"
+                        }
+                    }
+                }
+            }
+        },
+        "/api/courierCompany/delete/{id}": {
+            "delete": {
+                "produces": [
+                    "application/json"
+                ],
+                "tags": [
+                    "鐗╂祦鍏徃"
+                ],
+                "summary": "鍒犻櫎鐗╂祦鍏徃",
+                "parameters": [
+                    {
+                        "type": "integer",
+                        "description": "鏌ヨ鍙傛暟",
+                        "name": "id",
+                        "in": "path",
+                        "required": true
+                    }
+                ],
+                "responses": {
+                    "200": {
+                        "description": "OK",
+                        "schema": {
+                            "$ref": "#/definitions/contextx.Response"
+                        }
+                    }
+                }
+            }
+        },
+        "/api/courierCompany/list": {
+            "get": {
+                "produces": [
+                    "application/json"
+                ],
+                "tags": [
+                    "鐗╂祦鍏徃"
+                ],
+                "summary": "鑾峰彇鐗╂祦鍏徃鍒楄〃",
+                "parameters": [
+                    {
+                        "type": "string",
+                        "name": "keyword",
+                        "in": "query"
+                    },
+                    {
+                        "enum": [
+                            ""
+                        ],
+                        "type": "string",
+                        "x-enum-varnames": [
+                            "CourierCompanyKeywordCustomerName"
+                        ],
+                        "name": "keywordType",
+                        "in": "query"
+                    },
+                    {
+                        "type": "integer",
+                        "description": "椤电爜",
+                        "name": "page",
+                        "in": "query"
+                    },
+                    {
+                        "type": "integer",
+                        "description": "姣忛〉澶у皬",
+                        "name": "pageSize",
+                        "in": "query"
+                    },
+                    {
+                        "enum": [
+                            ""
+                        ],
+                        "type": "string",
+                        "x-enum-varnames": [
+                            "CourierCompanyQueryClassExpireLessThen60Days"
+                        ],
+                        "name": "queryClass",
+                        "in": "query"
+                    }
+                ],
+                "responses": {
+                    "200": {
+                        "description": "OK",
+                        "schema": {
+                            "allOf": [
+                                {
+                                    "$ref": "#/definitions/response.ListResponse"
+                                },
+                                {
+                                    "type": "object",
+                                    "properties": {
+                                        "data": {
+                                            "type": "array",
+                                            "items": {
+                                                "$ref": "#/definitions/model.CourierCompany"
+                                            }
+                                        }
+                                    }
+                                }
+                            ]
+                        }
+                    }
+                }
+            }
+        },
+        "/api/courierCompany/update": {
+            "put": {
+                "produces": [
+                    "application/json"
+                ],
+                "tags": [
+                    "鐗╂祦鍏徃"
+                ],
+                "summary": "鏇存柊鐗╂祦鍏徃",
+                "parameters": [
+                    {
+                        "description": "鏌ヨ鍙傛暟",
+                        "name": "object",
+                        "in": "body",
+                        "required": true,
+                        "schema": {
+                            "$ref": "#/definitions/request.UpdateCourierCompany"
+                        }
+                    }
+                ],
+                "responses": {
+                    "200": {
+                        "description": "OK",
+                        "schema": {
+                            "$ref": "#/definitions/contextx.Response"
+                        }
+                    }
+                }
+            }
+        },
         "/api/currency/add": {
             "post": {
                 "produces": [
@@ -2493,13 +2656,25 @@
                 "summary": "娣诲姞闄勪欢",
                 "parameters": [
                     {
-                        "description": "鏌ヨ鍙傛暟",
-                        "name": "object",
-                        "in": "body",
-                        "required": true,
-                        "schema": {
-                            "$ref": "#/definitions/request.AddFile"
-                        }
+                        "type": "integer",
+                        "description": "鏉ユ簮id",
+                        "name": "sourceId",
+                        "in": "formData",
+                        "required": true
+                    },
+                    {
+                        "type": "string",
+                        "description": "闄勪欢鏉ユ簮",
+                        "name": "sourceType",
+                        "in": "formData",
+                        "required": true
+                    },
+                    {
+                        "type": "file",
+                        "description": "涓婁紶鏂囦欢",
+                        "name": "file",
+                        "in": "formData",
+                        "required": true
                     }
                 ],
                 "responses": {
@@ -2610,36 +2785,6 @@
                                     }
                                 }
                             ]
-                        }
-                    }
-                }
-            }
-        },
-        "/api/file/update": {
-            "put": {
-                "produces": [
-                    "application/json"
-                ],
-                "tags": [
-                    "闄勪欢绠$悊"
-                ],
-                "summary": "鏇存柊闄勪欢",
-                "parameters": [
-                    {
-                        "description": "鏌ヨ鍙傛暟",
-                        "name": "object",
-                        "in": "body",
-                        "required": true,
-                        "schema": {
-                            "$ref": "#/definitions/request.UpdateFile"
-                        }
-                    }
-                ],
-                "responses": {
-                    "200": {
-                        "description": "OK",
-                        "schema": {
-                            "$ref": "#/definitions/contextx.Response"
                         }
                     }
                 }
@@ -2914,6 +3059,495 @@
                         "required": true,
                         "schema": {
                             "$ref": "#/definitions/request.UpdateIndustries"
+                        }
+                    }
+                ],
+                "responses": {
+                    "200": {
+                        "description": "OK",
+                        "schema": {
+                            "$ref": "#/definitions/contextx.Response"
+                        }
+                    }
+                }
+            }
+        },
+        "/api/invoice/add": {
+            "post": {
+                "produces": [
+                    "application/json"
+                ],
+                "tags": [
+                    "閿�鍞彂绁�"
+                ],
+                "summary": "娣诲姞閿�鍞彂绁�",
+                "parameters": [
+                    {
+                        "description": "鏌ヨ鍙傛暟",
+                        "name": "object",
+                        "in": "body",
+                        "required": true,
+                        "schema": {
+                            "$ref": "#/definitions/request.AddInvoice"
+                        }
+                    }
+                ],
+                "responses": {
+                    "200": {
+                        "description": "OK",
+                        "schema": {
+                            "$ref": "#/definitions/contextx.Response"
+                        }
+                    }
+                }
+            }
+        },
+        "/api/invoice/delete/{id}": {
+            "delete": {
+                "produces": [
+                    "application/json"
+                ],
+                "tags": [
+                    "閿�鍞彂绁�"
+                ],
+                "summary": "鍒犻櫎閿�鍞彂绁�",
+                "parameters": [
+                    {
+                        "type": "integer",
+                        "description": "鏌ヨ鍙傛暟",
+                        "name": "id",
+                        "in": "path",
+                        "required": true
+                    }
+                ],
+                "responses": {
+                    "200": {
+                        "description": "OK",
+                        "schema": {
+                            "$ref": "#/definitions/contextx.Response"
+                        }
+                    }
+                }
+            }
+        },
+        "/api/invoice/list": {
+            "get": {
+                "produces": [
+                    "application/json"
+                ],
+                "tags": [
+                    "閿�鍞彂绁�"
+                ],
+                "summary": "鑾峰彇閿�鍞彂绁ㄥ垪琛�",
+                "parameters": [
+                    {
+                        "type": "string",
+                        "name": "keyword",
+                        "in": "query"
+                    },
+                    {
+                        "enum": [
+                            ""
+                        ],
+                        "type": "string",
+                        "x-enum-varnames": [
+                            "InvoiceKeywordCustomerName"
+                        ],
+                        "name": "keywordType",
+                        "in": "query"
+                    },
+                    {
+                        "type": "integer",
+                        "description": "椤电爜",
+                        "name": "page",
+                        "in": "query"
+                    },
+                    {
+                        "type": "integer",
+                        "description": "姣忛〉澶у皬",
+                        "name": "pageSize",
+                        "in": "query"
+                    },
+                    {
+                        "enum": [
+                            ""
+                        ],
+                        "type": "string",
+                        "x-enum-varnames": [
+                            "InvoiceQueryClassExpireLessThen60Days"
+                        ],
+                        "name": "queryClass",
+                        "in": "query"
+                    }
+                ],
+                "responses": {
+                    "200": {
+                        "description": "OK",
+                        "schema": {
+                            "allOf": [
+                                {
+                                    "$ref": "#/definitions/response.ListResponse"
+                                },
+                                {
+                                    "type": "object",
+                                    "properties": {
+                                        "data": {
+                                            "type": "array",
+                                            "items": {
+                                                "$ref": "#/definitions/model.Invoice"
+                                            }
+                                        }
+                                    }
+                                }
+                            ]
+                        }
+                    }
+                }
+            }
+        },
+        "/api/invoice/update": {
+            "put": {
+                "produces": [
+                    "application/json"
+                ],
+                "tags": [
+                    "閿�鍞彂绁�"
+                ],
+                "summary": "鏇存柊閿�鍞彂绁�",
+                "parameters": [
+                    {
+                        "description": "鏌ヨ鍙傛暟",
+                        "name": "object",
+                        "in": "body",
+                        "required": true,
+                        "schema": {
+                            "$ref": "#/definitions/request.UpdateInvoice"
+                        }
+                    }
+                ],
+                "responses": {
+                    "200": {
+                        "description": "OK",
+                        "schema": {
+                            "$ref": "#/definitions/contextx.Response"
+                        }
+                    }
+                }
+            }
+        },
+        "/api/invoiceStatus/add": {
+            "post": {
+                "produces": [
+                    "application/json"
+                ],
+                "tags": [
+                    "鍙戠エ鐘舵��"
+                ],
+                "summary": "娣诲姞鍙戠エ鐘舵��",
+                "parameters": [
+                    {
+                        "description": "鏌ヨ鍙傛暟",
+                        "name": "object",
+                        "in": "body",
+                        "required": true,
+                        "schema": {
+                            "$ref": "#/definitions/request.AddInvoiceStatus"
+                        }
+                    }
+                ],
+                "responses": {
+                    "200": {
+                        "description": "OK",
+                        "schema": {
+                            "$ref": "#/definitions/contextx.Response"
+                        }
+                    }
+                }
+            }
+        },
+        "/api/invoiceStatus/delete/{id}": {
+            "delete": {
+                "produces": [
+                    "application/json"
+                ],
+                "tags": [
+                    "鍙戠エ鐘舵��"
+                ],
+                "summary": "鍒犻櫎鍙戠エ鐘舵��",
+                "parameters": [
+                    {
+                        "type": "integer",
+                        "description": "鏌ヨ鍙傛暟",
+                        "name": "id",
+                        "in": "path",
+                        "required": true
+                    }
+                ],
+                "responses": {
+                    "200": {
+                        "description": "OK",
+                        "schema": {
+                            "$ref": "#/definitions/contextx.Response"
+                        }
+                    }
+                }
+            }
+        },
+        "/api/invoiceStatus/list": {
+            "get": {
+                "produces": [
+                    "application/json"
+                ],
+                "tags": [
+                    "鍙戠エ鐘舵��"
+                ],
+                "summary": "鑾峰彇鍙戠エ鐘舵�佸垪琛�",
+                "parameters": [
+                    {
+                        "type": "string",
+                        "name": "keyword",
+                        "in": "query"
+                    },
+                    {
+                        "enum": [
+                            ""
+                        ],
+                        "type": "string",
+                        "x-enum-varnames": [
+                            "InvoiceStatusKeywordCustomerName"
+                        ],
+                        "name": "keywordType",
+                        "in": "query"
+                    },
+                    {
+                        "type": "integer",
+                        "description": "椤电爜",
+                        "name": "page",
+                        "in": "query"
+                    },
+                    {
+                        "type": "integer",
+                        "description": "姣忛〉澶у皬",
+                        "name": "pageSize",
+                        "in": "query"
+                    },
+                    {
+                        "enum": [
+                            ""
+                        ],
+                        "type": "string",
+                        "x-enum-varnames": [
+                            "InvoiceStatusQueryClassExpireLessThen60Days"
+                        ],
+                        "name": "queryClass",
+                        "in": "query"
+                    }
+                ],
+                "responses": {
+                    "200": {
+                        "description": "OK",
+                        "schema": {
+                            "allOf": [
+                                {
+                                    "$ref": "#/definitions/response.ListResponse"
+                                },
+                                {
+                                    "type": "object",
+                                    "properties": {
+                                        "data": {
+                                            "type": "array",
+                                            "items": {
+                                                "$ref": "#/definitions/model.InvoiceStatus"
+                                            }
+                                        }
+                                    }
+                                }
+                            ]
+                        }
+                    }
+                }
+            }
+        },
+        "/api/invoiceStatus/update": {
+            "put": {
+                "produces": [
+                    "application/json"
+                ],
+                "tags": [
+                    "鍙戠エ鐘舵��"
+                ],
+                "summary": "鏇存柊鍙戠エ鐘舵��",
+                "parameters": [
+                    {
+                        "description": "鏌ヨ鍙傛暟",
+                        "name": "object",
+                        "in": "body",
+                        "required": true,
+                        "schema": {
+                            "$ref": "#/definitions/request.UpdateInvoiceStatus"
+                        }
+                    }
+                ],
+                "responses": {
+                    "200": {
+                        "description": "OK",
+                        "schema": {
+                            "$ref": "#/definitions/contextx.Response"
+                        }
+                    }
+                }
+            }
+        },
+        "/api/invoiceType/add": {
+            "post": {
+                "produces": [
+                    "application/json"
+                ],
+                "tags": [
+                    "鍙戠エ绫诲瀷"
+                ],
+                "summary": "娣诲姞鍙戠エ绫诲瀷",
+                "parameters": [
+                    {
+                        "description": "鏌ヨ鍙傛暟",
+                        "name": "object",
+                        "in": "body",
+                        "required": true,
+                        "schema": {
+                            "$ref": "#/definitions/request.AddInvoiceType"
+                        }
+                    }
+                ],
+                "responses": {
+                    "200": {
+                        "description": "OK",
+                        "schema": {
+                            "$ref": "#/definitions/contextx.Response"
+                        }
+                    }
+                }
+            }
+        },
+        "/api/invoiceType/delete/{id}": {
+            "delete": {
+                "produces": [
+                    "application/json"
+                ],
+                "tags": [
+                    "鍙戠エ绫诲瀷"
+                ],
+                "summary": "鍒犻櫎鍙戠エ绫诲瀷",
+                "parameters": [
+                    {
+                        "type": "integer",
+                        "description": "鏌ヨ鍙傛暟",
+                        "name": "id",
+                        "in": "path",
+                        "required": true
+                    }
+                ],
+                "responses": {
+                    "200": {
+                        "description": "OK",
+                        "schema": {
+                            "$ref": "#/definitions/contextx.Response"
+                        }
+                    }
+                }
+            }
+        },
+        "/api/invoiceType/list": {
+            "get": {
+                "produces": [
+                    "application/json"
+                ],
+                "tags": [
+                    "鍙戠エ绫诲瀷"
+                ],
+                "summary": "鑾峰彇鍙戠エ绫诲瀷鍒楄〃",
+                "parameters": [
+                    {
+                        "type": "string",
+                        "name": "keyword",
+                        "in": "query"
+                    },
+                    {
+                        "enum": [
+                            ""
+                        ],
+                        "type": "string",
+                        "x-enum-varnames": [
+                            "InvoiceTypeKeywordCustomerName"
+                        ],
+                        "name": "keywordType",
+                        "in": "query"
+                    },
+                    {
+                        "type": "integer",
+                        "description": "椤电爜",
+                        "name": "page",
+                        "in": "query"
+                    },
+                    {
+                        "type": "integer",
+                        "description": "姣忛〉澶у皬",
+                        "name": "pageSize",
+                        "in": "query"
+                    },
+                    {
+                        "enum": [
+                            ""
+                        ],
+                        "type": "string",
+                        "x-enum-varnames": [
+                            "InvoiceTypeQueryClassExpireLessThen60Days"
+                        ],
+                        "name": "queryClass",
+                        "in": "query"
+                    }
+                ],
+                "responses": {
+                    "200": {
+                        "description": "OK",
+                        "schema": {
+                            "allOf": [
+                                {
+                                    "$ref": "#/definitions/response.ListResponse"
+                                },
+                                {
+                                    "type": "object",
+                                    "properties": {
+                                        "data": {
+                                            "type": "array",
+                                            "items": {
+                                                "$ref": "#/definitions/model.InvoiceType"
+                                            }
+                                        }
+                                    }
+                                }
+                            ]
+                        }
+                    }
+                }
+            }
+        },
+        "/api/invoiceType/update": {
+            "put": {
+                "produces": [
+                    "application/json"
+                ],
+                "tags": [
+                    "鍙戠エ绫诲瀷"
+                ],
+                "summary": "鏇存柊鍙戠エ绫诲瀷",
+                "parameters": [
+                    {
+                        "description": "鏌ヨ鍙傛暟",
+                        "name": "object",
+                        "in": "body",
+                        "required": true,
+                        "schema": {
+                            "$ref": "#/definitions/request.UpdateInvoiceType"
                         }
                     }
                 ],
@@ -6689,9 +7323,9 @@
                     "application/json"
                 ],
                 "tags": [
-                    "鏈嶅姟鍚堝悓鏀舵璁″垝绠$悊"
+                    "鏀舵璁″垝绠$悊"
                 ],
-                "summary": "娣诲姞鏈嶅姟鍚堝悓鏀舵璁″垝",
+                "summary": "娣诲姞鏀舵璁″垝",
                 "parameters": [
                     {
                         "description": "鏌ヨ鍙傛暟",
@@ -6719,9 +7353,9 @@
                     "application/json"
                 ],
                 "tags": [
-                    "鏈嶅姟鍚堝悓鏀舵璁″垝绠$悊"
+                    "鏀舵璁″垝绠$悊"
                 ],
-                "summary": "鍒犻櫎鏈嶅姟鍚堝悓鏀舵璁″垝",
+                "summary": "鍒犻櫎鏀舵璁″垝",
                 "parameters": [
                     {
                         "type": "integer",
@@ -6747,9 +7381,9 @@
                     "application/json"
                 ],
                 "tags": [
-                    "鏈嶅姟鍚堝悓鏀舵璁″垝绠$悊"
+                    "鏀舵璁″垝绠$悊"
                 ],
-                "summary": "鑾峰彇鏈嶅姟鍚堝悓鏀舵璁″垝鍒楄〃",
+                "summary": "鑾峰彇鏀舵璁″垝鍒楄〃",
                 "parameters": [
                     {
                         "type": "integer",
@@ -6789,9 +7423,9 @@
                     "application/json"
                 ],
                 "tags": [
-                    "鏈嶅姟鍚堝悓鏀舵璁″垝绠$悊"
+                    "鏀舵璁″垝绠$悊"
                 ],
-                "summary": "鏇存柊鏈嶅姟鍚堝悓鏀舵璁″垝",
+                "summary": "鏇存柊鏀舵璁″垝",
                 "parameters": [
                     {
                         "description": "鏌ヨ鍙傛暟",
@@ -8743,6 +9377,39 @@
                 "BankAccountQueryClassExpireLessThen60Days"
             ]
         },
+        "constvar.CollectionStatus": {
+            "type": "integer",
+            "enum": [
+                1,
+                2
+            ],
+            "x-enum-comments": {
+                "CollectionStatusCollected": "宸叉敹娆�",
+                "CollectionStatusUnCollected": "寰呮敹娆�"
+            },
+            "x-enum-varnames": [
+                "CollectionStatusUnCollected",
+                "CollectionStatusCollected"
+            ]
+        },
+        "constvar.CourierCompanyKeywordType": {
+            "type": "string",
+            "enum": [
+                ""
+            ],
+            "x-enum-varnames": [
+                "CourierCompanyKeywordCustomerName"
+            ]
+        },
+        "constvar.CourierCompanyQueryClass": {
+            "type": "string",
+            "enum": [
+                ""
+            ],
+            "x-enum-varnames": [
+                "CourierCompanyQueryClassExpireLessThen60Days"
+            ]
+        },
         "constvar.FaqKeywordType": {
             "type": "string",
             "enum": [
@@ -8777,6 +9444,71 @@
             ],
             "x-enum-varnames": [
                 "FileQueryClassExpireLessThen60Days"
+            ]
+        },
+        "constvar.InvoiceKeywordType": {
+            "type": "string",
+            "enum": [
+                ""
+            ],
+            "x-enum-varnames": [
+                "InvoiceKeywordCustomerName"
+            ]
+        },
+        "constvar.InvoiceQueryClass": {
+            "type": "string",
+            "enum": [
+                ""
+            ],
+            "x-enum-varnames": [
+                "InvoiceQueryClassExpireLessThen60Days"
+            ]
+        },
+        "constvar.InvoiceSourceType": {
+            "type": "integer",
+            "enum": [
+                1,
+                2
+            ],
+            "x-enum-varnames": [
+                "InvoiceSourceTypeSaleDetail",
+                "InvoiceSourceTypeServiceContract"
+            ]
+        },
+        "constvar.InvoiceStatusKeywordType": {
+            "type": "string",
+            "enum": [
+                ""
+            ],
+            "x-enum-varnames": [
+                "InvoiceStatusKeywordCustomerName"
+            ]
+        },
+        "constvar.InvoiceStatusQueryClass": {
+            "type": "string",
+            "enum": [
+                ""
+            ],
+            "x-enum-varnames": [
+                "InvoiceStatusQueryClassExpireLessThen60Days"
+            ]
+        },
+        "constvar.InvoiceTypeKeywordType": {
+            "type": "string",
+            "enum": [
+                ""
+            ],
+            "x-enum-varnames": [
+                "InvoiceTypeKeywordCustomerName"
+            ]
+        },
+        "constvar.InvoiceTypeQueryClass": {
+            "type": "string",
+            "enum": [
+                ""
+            ],
+            "x-enum-varnames": [
+                "InvoiceTypeQueryClassExpireLessThen60Days"
             ]
         },
         "constvar.PaymentTypeKeywordType": {
@@ -9393,6 +10125,17 @@
                 }
             }
         },
+        "model.CourierCompany": {
+            "type": "object",
+            "properties": {
+                "id": {
+                    "type": "integer"
+                },
+                "name": {
+                    "type": "string"
+                }
+            }
+        },
         "model.Currency": {
             "type": "object",
             "properties": {
@@ -9492,14 +10235,6 @@
                     "description": "瀵硅薄瀛樺偍bucket",
                     "type": "string"
                 },
-                "content": {
-                    "description": "鏂囦欢鍐呭",
-                    "type": "string"
-                },
-                "createTime": {
-                    "description": "鍒涘缓鏃堕棿",
-                    "type": "string"
-                },
                 "downloadCount": {
                     "description": "涓嬫娆℃暟",
                     "type": "integer"
@@ -9511,9 +10246,6 @@
                 "fileType": {
                     "description": "鏂囦欢绫诲瀷",
                     "type": "string"
-                },
-                "id": {
-                    "type": "integer"
                 },
                 "key": {
                     "description": "瀵硅薄瀛樺偍key",
@@ -9536,9 +10268,6 @@
                 },
                 "sourceType": {
                     "description": "闄勪欢鏉ユ簮",
-                    "type": "string"
-                },
-                "updateTime": {
                     "type": "string"
                 }
             }
@@ -9600,6 +10329,100 @@
             }
         },
         "model.Industry": {
+            "type": "object",
+            "properties": {
+                "id": {
+                    "type": "integer"
+                },
+                "name": {
+                    "type": "string"
+                }
+            }
+        },
+        "model.Invoice": {
+            "type": "object",
+            "properties": {
+                "client": {
+                    "$ref": "#/definitions/model.Client"
+                },
+                "clientId": {
+                    "description": "瀹㈡埛id",
+                    "type": "integer"
+                },
+                "courierCompany": {
+                    "$ref": "#/definitions/model.CourierCompany"
+                },
+                "courierCompanyId": {
+                    "description": "鐗╂祦鍏徃",
+                    "type": "integer"
+                },
+                "courierNumber": {
+                    "description": "鐗╂祦鍗曞彿",
+                    "type": "string"
+                },
+                "id": {
+                    "type": "integer"
+                },
+                "invoiceDate": {
+                    "description": "寮�绁ㄦ棩鏈�",
+                    "type": "string"
+                },
+                "invoiceNumber": {
+                    "description": "鍙戠エ鍙风爜",
+                    "type": "string"
+                },
+                "invoiceStatus": {
+                    "$ref": "#/definitions/model.InvoiceStatus"
+                },
+                "invoiceStatusId": {
+                    "description": "鍙戠エ鐘舵�乮d",
+                    "type": "integer"
+                },
+                "invoiceType": {
+                    "$ref": "#/definitions/model.InvoiceType"
+                },
+                "invoiceTypeId": {
+                    "description": "鍙戠エ绫诲瀷id",
+                    "type": "integer"
+                },
+                "principalId": {
+                    "description": "閿�鍞礋璐d汉id",
+                    "type": "integer"
+                },
+                "sourceId": {
+                    "description": "婧愬崟id",
+                    "type": "integer"
+                },
+                "sourceType": {
+                    "description": "婧愬崟绫诲瀷(1閿�鍞槑缁嗗崟2鏈嶅姟鍚堝悓)",
+                    "allOf": [
+                        {
+                            "$ref": "#/definitions/constvar.InvoiceSourceType"
+                        }
+                    ]
+                },
+                "subject": {
+                    "description": "涓婚",
+                    "type": "string"
+                },
+                "taxpayerIdNumber": {
+                    "description": "绾崇◣璇嗗埆鍙�",
+                    "type": "string"
+                }
+            }
+        },
+        "model.InvoiceStatus": {
+            "type": "object",
+            "properties": {
+                "id": {
+                    "type": "integer"
+                },
+                "name": {
+                    "type": "string"
+                }
+            }
+        },
+        "model.InvoiceType": {
             "type": "object",
             "properties": {
                 "id": {
@@ -10447,13 +11270,21 @@
                     "description": "澶囨敞",
                     "type": "string"
                 },
-                "serviceContractId": {
-                    "description": "鏈嶅姟鍚堝悓id",
+                "sourceId": {
+                    "description": "婧愬崟id",
+                    "type": "integer"
+                },
+                "sourceType": {
+                    "description": "婧愬崟绫诲瀷锛�1閿�鍞槑缁�2鏈嶅姟鍚堝悓3閿�鍞彂绁級",
                     "type": "integer"
                 },
                 "status": {
                     "description": "鐘舵�侊紙1鏈敹2宸叉敹锛�",
-                    "type": "integer"
+                    "allOf": [
+                        {
+                            "$ref": "#/definitions/constvar.CollectionStatus"
+                        }
+                    ]
                 },
                 "term": {
                     "description": "鏈熸",
@@ -10464,6 +11295,18 @@
         "model.ServiceContract": {
             "type": "object",
             "properties": {
+                "amountInvoiced": {
+                    "description": "宸插紑绁ㄩ噾棰�",
+                    "type": "number"
+                },
+                "amountReceivable": {
+                    "description": "搴旀敹閲戦",
+                    "type": "number"
+                },
+                "amountReceived": {
+                    "description": "宸叉敹閲戦",
+                    "type": "number"
+                },
                 "clientId": {
                     "type": "integer"
                 },
@@ -11191,6 +12034,17 @@
                 }
             }
         },
+        "request.AddCourierCompany": {
+            "type": "object",
+            "properties": {
+                "id": {
+                    "type": "integer"
+                },
+                "name": {
+                    "type": "string"
+                }
+            }
+        },
         "request.AddCurrency": {
             "type": "object",
             "required": [
@@ -11277,23 +12131,6 @@
                 }
             }
         },
-        "request.AddFile": {
-            "type": "object",
-            "required": [
-                "sourceId",
-                "sourceType"
-            ],
-            "properties": {
-                "sourceId": {
-                    "description": "鏉ユ簮id",
-                    "type": "integer"
-                },
-                "sourceType": {
-                    "description": "闄勪欢鏉ユ簮",
-                    "type": "string"
-                }
-            }
-        },
         "request.AddFollowRecord": {
             "type": "object",
             "required": [
@@ -11311,6 +12148,85 @@
                 "name"
             ],
             "properties": {
+                "name": {
+                    "type": "string"
+                }
+            }
+        },
+        "request.AddInvoice": {
+            "type": "object",
+            "properties": {
+                "clientId": {
+                    "description": "瀹㈡埛id",
+                    "type": "integer"
+                },
+                "courierCompanyId": {
+                    "description": "鐗╂祦鍏徃",
+                    "type": "integer"
+                },
+                "courierNumber": {
+                    "description": "鐗╂祦鍗曞彿",
+                    "type": "string"
+                },
+                "invoiceDate": {
+                    "description": "寮�绁ㄦ棩鏈�",
+                    "type": "string"
+                },
+                "invoiceNumber": {
+                    "description": "鍙戠エ鍙风爜",
+                    "type": "string"
+                },
+                "invoiceStatusId": {
+                    "description": "鍙戠エ鐘舵�乮d",
+                    "type": "integer"
+                },
+                "invoiceTypeId": {
+                    "description": "鍙戠エ绫诲瀷id",
+                    "type": "integer"
+                },
+                "principalId": {
+                    "description": "閿�鍞礋璐d汉id",
+                    "type": "integer"
+                },
+                "sourceId": {
+                    "description": "婧愬崟id",
+                    "type": "integer"
+                },
+                "sourceType": {
+                    "description": "婧愬崟绫诲瀷(1閿�鍞槑缁嗗崟2鏈嶅姟鍚堝悓)",
+                    "allOf": [
+                        {
+                            "$ref": "#/definitions/constvar.InvoiceSourceType"
+                        }
+                    ]
+                },
+                "subject": {
+                    "description": "涓婚",
+                    "type": "string"
+                },
+                "taxpayerIdNumber": {
+                    "description": "绾崇◣璇嗗埆鍙�",
+                    "type": "string"
+                }
+            }
+        },
+        "request.AddInvoiceStatus": {
+            "type": "object",
+            "properties": {
+                "id": {
+                    "type": "integer"
+                },
+                "name": {
+                    "type": "string"
+                }
+            }
+        },
+        "request.AddInvoiceType": {
+            "type": "object",
+            "properties": {
+                "id": {
+                    "type": "integer"
+                },
                 "name": {
                     "type": "string"
                 }
@@ -11843,6 +12759,9 @@
         },
         "request.AddServiceCollectionPlan": {
             "type": "object",
+            "required": [
+                "list"
+            ],
             "properties": {
                 "list": {
                     "type": "array",
@@ -13599,6 +14518,17 @@
                 }
             }
         },
+        "request.UpdateCourierCompany": {
+            "type": "object",
+            "properties": {
+                "id": {
+                    "type": "integer"
+                },
+                "name": {
+                    "type": "string"
+                }
+            }
+        },
         "request.UpdateCurrency": {
             "type": "object",
             "required": [
@@ -13754,64 +14684,6 @@
                 }
             }
         },
-        "request.UpdateFile": {
-            "type": "object",
-            "properties": {
-                "bucket": {
-                    "description": "瀵硅薄瀛樺偍bucket",
-                    "type": "string"
-                },
-                "content": {
-                    "description": "鏂囦欢鍐呭",
-                    "type": "string"
-                },
-                "createTime": {
-                    "description": "鍒涘缓鏃堕棿",
-                    "type": "string"
-                },
-                "downloadCount": {
-                    "description": "涓嬫娆℃暟",
-                    "type": "integer"
-                },
-                "filePath": {
-                    "description": "鏂囦欢璺緞",
-                    "type": "string"
-                },
-                "fileType": {
-                    "description": "鏂囦欢绫诲瀷",
-                    "type": "string"
-                },
-                "id": {
-                    "type": "integer"
-                },
-                "key": {
-                    "description": "瀵硅薄瀛樺偍key",
-                    "type": "string"
-                },
-                "name": {
-                    "type": "string"
-                },
-                "previewCount": {
-                    "description": "棰勮娆℃暟",
-                    "type": "integer"
-                },
-                "size": {
-                    "description": "鏂囦欢澶у皬",
-                    "type": "integer"
-                },
-                "sourceId": {
-                    "description": "鏉ユ簮id",
-                    "type": "integer"
-                },
-                "sourceType": {
-                    "description": "闄勪欢鏉ユ簮",
-                    "type": "string"
-                },
-                "updateTime": {
-                    "type": "string"
-                }
-            }
-        },
         "request.UpdateFollowRecord": {
             "type": "object",
             "required": [
@@ -13846,6 +14718,84 @@
                 "id",
                 "name"
             ],
+            "properties": {
+                "id": {
+                    "type": "integer"
+                },
+                "name": {
+                    "type": "string"
+                }
+            }
+        },
+        "request.UpdateInvoice": {
+            "type": "object",
+            "properties": {
+                "clientId": {
+                    "description": "瀹㈡埛id",
+                    "type": "integer"
+                },
+                "courierCompanyId": {
+                    "description": "鐗╂祦鍏徃",
+                    "type": "integer"
+                },
+                "courierNumber": {
+                    "description": "鐗╂祦鍗曞彿",
+                    "type": "string"
+                },
+                "id": {
+                    "type": "integer"
+                },
+                "invoiceDate": {
+                    "description": "寮�绁ㄦ棩鏈�",
+                    "type": "integer"
+                },
+                "invoiceNumber": {
+                    "description": "鍙戠エ鍙风爜",
+                    "type": "string"
+                },
+                "invoiceStatusId": {
+                    "description": "鍙戠エ鐘舵�乮d",
+                    "type": "integer"
+                },
+                "invoiceTypeId": {
+                    "description": "鍙戠エ绫诲瀷id",
+                    "type": "integer"
+                },
+                "principalId": {
+                    "description": "閿�鍞礋璐d汉id",
+                    "type": "integer"
+                },
+                "sourceId": {
+                    "description": "婧愬崟id",
+                    "type": "integer"
+                },
+                "sourceType": {
+                    "description": "婧愬崟绫诲瀷(1閿�鍞槑缁嗗崟2鏈嶅姟鍚堝悓)",
+                    "type": "integer"
+                },
+                "subject": {
+                    "description": "涓婚",
+                    "type": "string"
+                },
+                "taxpayerIdNumber": {
+                    "description": "绾崇◣璇嗗埆鍙�",
+                    "type": "string"
+                }
+            }
+        },
+        "request.UpdateInvoiceStatus": {
+            "type": "object",
+            "properties": {
+                "id": {
+                    "type": "integer"
+                },
+                "name": {
+                    "type": "string"
+                }
+            }
+        },
+        "request.UpdateInvoiceType": {
+            "type": "object",
             "properties": {
                 "id": {
                     "type": "integer"
@@ -14744,13 +15694,21 @@
                     "description": "澶囨敞",
                     "type": "string"
                 },
-                "serviceContractId": {
-                    "description": "鏈嶅姟鍚堝悓id",
+                "sourceId": {
+                    "description": "婧愬崟id",
+                    "type": "integer"
+                },
+                "sourceType": {
+                    "description": "婧愬崟绫诲瀷锛�1閿�鍞槑缁�2鏈嶅姟鍚堝悓3閿�鍞彂绁級",
                     "type": "integer"
                 },
                 "status": {
                     "description": "鐘舵�侊紙1鏈敹2宸叉敹锛�",
-                    "type": "integer"
+                    "allOf": [
+                        {
+                            "$ref": "#/definitions/constvar.CollectionStatus"
+                        }
+                    ]
                 },
                 "term": {
                     "description": "鏈熸",
diff --git a/docs/swagger.yaml b/docs/swagger.yaml
index 9b8cfae..f8a7c7f 100644
--- a/docs/swagger.yaml
+++ b/docs/swagger.yaml
@@ -11,6 +11,29 @@
     type: string
     x-enum-varnames:
     - BankAccountQueryClassExpireLessThen60Days
+  constvar.CollectionStatus:
+    enum:
+    - 1
+    - 2
+    type: integer
+    x-enum-comments:
+      CollectionStatusCollected: 宸叉敹娆�
+      CollectionStatusUnCollected: 寰呮敹娆�
+    x-enum-varnames:
+    - CollectionStatusUnCollected
+    - CollectionStatusCollected
+  constvar.CourierCompanyKeywordType:
+    enum:
+    - ""
+    type: string
+    x-enum-varnames:
+    - CourierCompanyKeywordCustomerName
+  constvar.CourierCompanyQueryClass:
+    enum:
+    - ""
+    type: string
+    x-enum-varnames:
+    - CourierCompanyQueryClassExpireLessThen60Days
   constvar.FaqKeywordType:
     enum:
     - ""
@@ -35,6 +58,50 @@
     type: string
     x-enum-varnames:
     - FileQueryClassExpireLessThen60Days
+  constvar.InvoiceKeywordType:
+    enum:
+    - ""
+    type: string
+    x-enum-varnames:
+    - InvoiceKeywordCustomerName
+  constvar.InvoiceQueryClass:
+    enum:
+    - ""
+    type: string
+    x-enum-varnames:
+    - InvoiceQueryClassExpireLessThen60Days
+  constvar.InvoiceSourceType:
+    enum:
+    - 1
+    - 2
+    type: integer
+    x-enum-varnames:
+    - InvoiceSourceTypeSaleDetail
+    - InvoiceSourceTypeServiceContract
+  constvar.InvoiceStatusKeywordType:
+    enum:
+    - ""
+    type: string
+    x-enum-varnames:
+    - InvoiceStatusKeywordCustomerName
+  constvar.InvoiceStatusQueryClass:
+    enum:
+    - ""
+    type: string
+    x-enum-varnames:
+    - InvoiceStatusQueryClassExpireLessThen60Days
+  constvar.InvoiceTypeKeywordType:
+    enum:
+    - ""
+    type: string
+    x-enum-varnames:
+    - InvoiceTypeKeywordCustomerName
+  constvar.InvoiceTypeQueryClass:
+    enum:
+    - ""
+    type: string
+    x-enum-varnames:
+    - InvoiceTypeQueryClassExpireLessThen60Days
   constvar.PaymentTypeKeywordType:
     enum:
     - ""
@@ -468,6 +535,13 @@
           $ref: '#/definitions/model.Province'
         type: array
     type: object
+  model.CourierCompany:
+    properties:
+      id:
+        type: integer
+      name:
+        type: string
+    type: object
   model.Currency:
     properties:
       id:
@@ -532,12 +606,6 @@
       bucket:
         description: 瀵硅薄瀛樺偍bucket
         type: string
-      content:
-        description: 鏂囦欢鍐呭
-        type: string
-      createTime:
-        description: 鍒涘缓鏃堕棿
-        type: string
       downloadCount:
         description: 涓嬫娆℃暟
         type: integer
@@ -547,8 +615,6 @@
       fileType:
         description: 鏂囦欢绫诲瀷
         type: string
-      id:
-        type: integer
       key:
         description: 瀵硅薄瀛樺偍key
         type: string
@@ -565,8 +631,6 @@
         type: integer
       sourceType:
         description: 闄勪欢鏉ユ簮
-        type: string
-      updateTime:
         type: string
     type: object
   model.FollowRecord:
@@ -607,6 +671,70 @@
         type: string
     type: object
   model.Industry:
+    properties:
+      id:
+        type: integer
+      name:
+        type: string
+    type: object
+  model.Invoice:
+    properties:
+      client:
+        $ref: '#/definitions/model.Client'
+      clientId:
+        description: 瀹㈡埛id
+        type: integer
+      courierCompany:
+        $ref: '#/definitions/model.CourierCompany'
+      courierCompanyId:
+        description: 鐗╂祦鍏徃
+        type: integer
+      courierNumber:
+        description: 鐗╂祦鍗曞彿
+        type: string
+      id:
+        type: integer
+      invoiceDate:
+        description: 寮�绁ㄦ棩鏈�
+        type: string
+      invoiceNumber:
+        description: 鍙戠エ鍙风爜
+        type: string
+      invoiceStatus:
+        $ref: '#/definitions/model.InvoiceStatus'
+      invoiceStatusId:
+        description: 鍙戠エ鐘舵�乮d
+        type: integer
+      invoiceType:
+        $ref: '#/definitions/model.InvoiceType'
+      invoiceTypeId:
+        description: 鍙戠エ绫诲瀷id
+        type: integer
+      principalId:
+        description: 閿�鍞礋璐d汉id
+        type: integer
+      sourceId:
+        description: 婧愬崟id
+        type: integer
+      sourceType:
+        allOf:
+        - $ref: '#/definitions/constvar.InvoiceSourceType'
+        description: 婧愬崟绫诲瀷(1閿�鍞槑缁嗗崟2鏈嶅姟鍚堝悓)
+      subject:
+        description: 涓婚
+        type: string
+      taxpayerIdNumber:
+        description: 绾崇◣璇嗗埆鍙�
+        type: string
+    type: object
+  model.InvoiceStatus:
+    properties:
+      id:
+        type: integer
+      name:
+        type: string
+    type: object
+  model.InvoiceType:
     properties:
       id:
         type: integer
@@ -1167,18 +1295,31 @@
       remark:
         description: 澶囨敞
         type: string
-      serviceContractId:
-        description: 鏈嶅姟鍚堝悓id
+      sourceId:
+        description: 婧愬崟id
+        type: integer
+      sourceType:
+        description: 婧愬崟绫诲瀷锛�1閿�鍞槑缁�2鏈嶅姟鍚堝悓3閿�鍞彂绁級
         type: integer
       status:
+        allOf:
+        - $ref: '#/definitions/constvar.CollectionStatus'
         description: 鐘舵�侊紙1鏈敹2宸叉敹锛�
-        type: integer
       term:
         description: 鏈熸
         type: integer
     type: object
   model.ServiceContract:
     properties:
+      amountInvoiced:
+        description: 宸插紑绁ㄩ噾棰�
+        type: number
+      amountReceivable:
+        description: 搴旀敹閲戦
+        type: number
+      amountReceived:
+        description: 宸叉敹閲戦
+        type: number
       clientId:
         type: integer
       contactId:
@@ -1677,6 +1818,13 @@
         description: 鍥藉鍚嶇О
         type: string
     type: object
+  request.AddCourierCompany:
+    properties:
+      id:
+        type: integer
+      name:
+        type: string
+    type: object
   request.AddCurrency:
     properties:
       name:
@@ -1732,18 +1880,6 @@
       name:
         type: string
     type: object
-  request.AddFile:
-    properties:
-      sourceId:
-        description: 鏉ユ簮id
-        type: integer
-      sourceType:
-        description: 闄勪欢鏉ユ簮
-        type: string
-    required:
-    - sourceId
-    - sourceType
-    type: object
   request.AddFollowRecord:
     properties:
       follow_record:
@@ -1757,6 +1893,60 @@
         type: string
     required:
     - name
+    type: object
+  request.AddInvoice:
+    properties:
+      clientId:
+        description: 瀹㈡埛id
+        type: integer
+      courierCompanyId:
+        description: 鐗╂祦鍏徃
+        type: integer
+      courierNumber:
+        description: 鐗╂祦鍗曞彿
+        type: string
+      invoiceDate:
+        description: 寮�绁ㄦ棩鏈�
+        type: string
+      invoiceNumber:
+        description: 鍙戠エ鍙风爜
+        type: string
+      invoiceStatusId:
+        description: 鍙戠エ鐘舵�乮d
+        type: integer
+      invoiceTypeId:
+        description: 鍙戠エ绫诲瀷id
+        type: integer
+      principalId:
+        description: 閿�鍞礋璐d汉id
+        type: integer
+      sourceId:
+        description: 婧愬崟id
+        type: integer
+      sourceType:
+        allOf:
+        - $ref: '#/definitions/constvar.InvoiceSourceType'
+        description: 婧愬崟绫诲瀷(1閿�鍞槑缁嗗崟2鏈嶅姟鍚堝悓)
+      subject:
+        description: 涓婚
+        type: string
+      taxpayerIdNumber:
+        description: 绾崇◣璇嗗埆鍙�
+        type: string
+    type: object
+  request.AddInvoiceStatus:
+    properties:
+      id:
+        type: integer
+      name:
+        type: string
+    type: object
+  request.AddInvoiceType:
+    properties:
+      id:
+        type: integer
+      name:
+        type: string
     type: object
   request.AddIsInvoice:
     properties:
@@ -2111,6 +2301,8 @@
         items:
           $ref: '#/definitions/model.ServiceCollectionPlan'
         type: array
+    required:
+    - list
     type: object
   request.AddServiceContract:
     properties:
@@ -3310,6 +3502,13 @@
         description: 鍥藉鍚嶇О
         type: string
     type: object
+  request.UpdateCourierCompany:
+    properties:
+      id:
+        type: integer
+      name:
+        type: string
+    type: object
   request.UpdateCurrency:
     properties:
       id:
@@ -3411,48 +3610,6 @@
       name:
         type: string
     type: object
-  request.UpdateFile:
-    properties:
-      bucket:
-        description: 瀵硅薄瀛樺偍bucket
-        type: string
-      content:
-        description: 鏂囦欢鍐呭
-        type: string
-      createTime:
-        description: 鍒涘缓鏃堕棿
-        type: string
-      downloadCount:
-        description: 涓嬫娆℃暟
-        type: integer
-      filePath:
-        description: 鏂囦欢璺緞
-        type: string
-      fileType:
-        description: 鏂囦欢绫诲瀷
-        type: string
-      id:
-        type: integer
-      key:
-        description: 瀵硅薄瀛樺偍key
-        type: string
-      name:
-        type: string
-      previewCount:
-        description: 棰勮娆℃暟
-        type: integer
-      size:
-        description: 鏂囦欢澶у皬
-        type: integer
-      sourceId:
-        description: 鏉ユ簮id
-        type: integer
-      sourceType:
-        description: 闄勪欢鏉ユ簮
-        type: string
-      updateTime:
-        type: string
-    type: object
   request.UpdateFollowRecord:
     properties:
       follow_record:
@@ -3480,6 +3637,61 @@
     required:
     - id
     - name
+    type: object
+  request.UpdateInvoice:
+    properties:
+      clientId:
+        description: 瀹㈡埛id
+        type: integer
+      courierCompanyId:
+        description: 鐗╂祦鍏徃
+        type: integer
+      courierNumber:
+        description: 鐗╂祦鍗曞彿
+        type: string
+      id:
+        type: integer
+      invoiceDate:
+        description: 寮�绁ㄦ棩鏈�
+        type: integer
+      invoiceNumber:
+        description: 鍙戠エ鍙风爜
+        type: string
+      invoiceStatusId:
+        description: 鍙戠エ鐘舵�乮d
+        type: integer
+      invoiceTypeId:
+        description: 鍙戠エ绫诲瀷id
+        type: integer
+      principalId:
+        description: 閿�鍞礋璐d汉id
+        type: integer
+      sourceId:
+        description: 婧愬崟id
+        type: integer
+      sourceType:
+        description: 婧愬崟绫诲瀷(1閿�鍞槑缁嗗崟2鏈嶅姟鍚堝悓)
+        type: integer
+      subject:
+        description: 涓婚
+        type: string
+      taxpayerIdNumber:
+        description: 绾崇◣璇嗗埆鍙�
+        type: string
+    type: object
+  request.UpdateInvoiceStatus:
+    properties:
+      id:
+        type: integer
+      name:
+        type: string
+    type: object
+  request.UpdateInvoiceType:
+    properties:
+      id:
+        type: integer
+      name:
+        type: string
     type: object
   request.UpdateIsInvoice:
     properties:
@@ -4074,12 +4286,16 @@
       remark:
         description: 澶囨敞
         type: string
-      serviceContractId:
-        description: 鏈嶅姟鍚堝悓id
+      sourceId:
+        description: 婧愬崟id
+        type: integer
+      sourceType:
+        description: 婧愬崟绫诲瀷锛�1閿�鍞槑缁�2鏈嶅姟鍚堝悓3閿�鍞彂绁級
         type: integer
       status:
+        allOf:
+        - $ref: '#/definitions/constvar.CollectionStatus'
         description: 鐘舵�侊紙1鏈敹2宸叉敹锛�
-        type: integer
       term:
         description: 鏈熸
         type: integer
@@ -6041,6 +6257,107 @@
       summary: 鏇存柊鍥藉
       tags:
       - Country
+  /api/courierCompany/add:
+    post:
+      parameters:
+      - description: 鏌ヨ鍙傛暟
+        in: body
+        name: object
+        required: true
+        schema:
+          $ref: '#/definitions/request.AddCourierCompany'
+      produces:
+      - application/json
+      responses:
+        "200":
+          description: OK
+          schema:
+            $ref: '#/definitions/contextx.Response'
+      summary: 娣诲姞鐗╂祦鍏徃
+      tags:
+      - 鐗╂祦鍏徃
+  /api/courierCompany/delete/{id}:
+    delete:
+      parameters:
+      - description: 鏌ヨ鍙傛暟
+        in: path
+        name: id
+        required: true
+        type: integer
+      produces:
+      - application/json
+      responses:
+        "200":
+          description: OK
+          schema:
+            $ref: '#/definitions/contextx.Response'
+      summary: 鍒犻櫎鐗╂祦鍏徃
+      tags:
+      - 鐗╂祦鍏徃
+  /api/courierCompany/list:
+    get:
+      parameters:
+      - in: query
+        name: keyword
+        type: string
+      - enum:
+        - ""
+        in: query
+        name: keywordType
+        type: string
+        x-enum-varnames:
+        - CourierCompanyKeywordCustomerName
+      - description: 椤电爜
+        in: query
+        name: page
+        type: integer
+      - description: 姣忛〉澶у皬
+        in: query
+        name: pageSize
+        type: integer
+      - enum:
+        - ""
+        in: query
+        name: queryClass
+        type: string
+        x-enum-varnames:
+        - CourierCompanyQueryClassExpireLessThen60Days
+      produces:
+      - application/json
+      responses:
+        "200":
+          description: OK
+          schema:
+            allOf:
+            - $ref: '#/definitions/response.ListResponse'
+            - properties:
+                data:
+                  items:
+                    $ref: '#/definitions/model.CourierCompany'
+                  type: array
+              type: object
+      summary: 鑾峰彇鐗╂祦鍏徃鍒楄〃
+      tags:
+      - 鐗╂祦鍏徃
+  /api/courierCompany/update:
+    put:
+      parameters:
+      - description: 鏌ヨ鍙傛暟
+        in: body
+        name: object
+        required: true
+        schema:
+          $ref: '#/definitions/request.UpdateCourierCompany'
+      produces:
+      - application/json
+      responses:
+        "200":
+          description: OK
+          schema:
+            $ref: '#/definitions/contextx.Response'
+      summary: 鏇存柊鐗╂祦鍏徃
+      tags:
+      - 鐗╂祦鍏徃
   /api/currency/add:
     post:
       parameters:
@@ -6578,12 +6895,21 @@
   /api/file/add:
     post:
       parameters:
-      - description: 鏌ヨ鍙傛暟
-        in: body
-        name: object
+      - description: 鏉ユ簮id
+        in: formData
+        name: sourceId
         required: true
-        schema:
-          $ref: '#/definitions/request.AddFile'
+        type: integer
+      - description: 闄勪欢鏉ユ簮
+        in: formData
+        name: sourceType
+        required: true
+        type: string
+      - description: 涓婁紶鏂囦欢
+        in: formData
+        name: file
+        required: true
+        type: file
       produces:
       - application/json
       responses:
@@ -6655,25 +6981,6 @@
                   type: array
               type: object
       summary: 鑾峰彇闄勪欢鍒楄〃
-      tags:
-      - 闄勪欢绠$悊
-  /api/file/update:
-    put:
-      parameters:
-      - description: 鏌ヨ鍙傛暟
-        in: body
-        name: object
-        required: true
-        schema:
-          $ref: '#/definitions/request.UpdateFile'
-      produces:
-      - application/json
-      responses:
-        "200":
-          description: OK
-          schema:
-            $ref: '#/definitions/contextx.Response'
-      summary: 鏇存柊闄勪欢
       tags:
       - 闄勪欢绠$悊
   /api/followRecord/add:
@@ -6847,6 +7154,309 @@
       summary: 鏇存柊琛屼笟
       tags:
       - Industry
+  /api/invoice/add:
+    post:
+      parameters:
+      - description: 鏌ヨ鍙傛暟
+        in: body
+        name: object
+        required: true
+        schema:
+          $ref: '#/definitions/request.AddInvoice'
+      produces:
+      - application/json
+      responses:
+        "200":
+          description: OK
+          schema:
+            $ref: '#/definitions/contextx.Response'
+      summary: 娣诲姞閿�鍞彂绁�
+      tags:
+      - 閿�鍞彂绁�
+  /api/invoice/delete/{id}:
+    delete:
+      parameters:
+      - description: 鏌ヨ鍙傛暟
+        in: path
+        name: id
+        required: true
+        type: integer
+      produces:
+      - application/json
+      responses:
+        "200":
+          description: OK
+          schema:
+            $ref: '#/definitions/contextx.Response'
+      summary: 鍒犻櫎閿�鍞彂绁�
+      tags:
+      - 閿�鍞彂绁�
+  /api/invoice/list:
+    get:
+      parameters:
+      - in: query
+        name: keyword
+        type: string
+      - enum:
+        - ""
+        in: query
+        name: keywordType
+        type: string
+        x-enum-varnames:
+        - InvoiceKeywordCustomerName
+      - description: 椤电爜
+        in: query
+        name: page
+        type: integer
+      - description: 姣忛〉澶у皬
+        in: query
+        name: pageSize
+        type: integer
+      - enum:
+        - ""
+        in: query
+        name: queryClass
+        type: string
+        x-enum-varnames:
+        - InvoiceQueryClassExpireLessThen60Days
+      produces:
+      - application/json
+      responses:
+        "200":
+          description: OK
+          schema:
+            allOf:
+            - $ref: '#/definitions/response.ListResponse'
+            - properties:
+                data:
+                  items:
+                    $ref: '#/definitions/model.Invoice'
+                  type: array
+              type: object
+      summary: 鑾峰彇閿�鍞彂绁ㄥ垪琛�
+      tags:
+      - 閿�鍞彂绁�
+  /api/invoice/update:
+    put:
+      parameters:
+      - description: 鏌ヨ鍙傛暟
+        in: body
+        name: object
+        required: true
+        schema:
+          $ref: '#/definitions/request.UpdateInvoice'
+      produces:
+      - application/json
+      responses:
+        "200":
+          description: OK
+          schema:
+            $ref: '#/definitions/contextx.Response'
+      summary: 鏇存柊閿�鍞彂绁�
+      tags:
+      - 閿�鍞彂绁�
+  /api/invoiceStatus/add:
+    post:
+      parameters:
+      - description: 鏌ヨ鍙傛暟
+        in: body
+        name: object
+        required: true
+        schema:
+          $ref: '#/definitions/request.AddInvoiceStatus'
+      produces:
+      - application/json
+      responses:
+        "200":
+          description: OK
+          schema:
+            $ref: '#/definitions/contextx.Response'
+      summary: 娣诲姞鍙戠エ鐘舵��
+      tags:
+      - 鍙戠エ鐘舵��
+  /api/invoiceStatus/delete/{id}:
+    delete:
+      parameters:
+      - description: 鏌ヨ鍙傛暟
+        in: path
+        name: id
+        required: true
+        type: integer
+      produces:
+      - application/json
+      responses:
+        "200":
+          description: OK
+          schema:
+            $ref: '#/definitions/contextx.Response'
+      summary: 鍒犻櫎鍙戠エ鐘舵��
+      tags:
+      - 鍙戠エ鐘舵��
+  /api/invoiceStatus/list:
+    get:
+      parameters:
+      - in: query
+        name: keyword
+        type: string
+      - enum:
+        - ""
+        in: query
+        name: keywordType
+        type: string
+        x-enum-varnames:
+        - InvoiceStatusKeywordCustomerName
+      - description: 椤电爜
+        in: query
+        name: page
+        type: integer
+      - description: 姣忛〉澶у皬
+        in: query
+        name: pageSize
+        type: integer
+      - enum:
+        - ""
+        in: query
+        name: queryClass
+        type: string
+        x-enum-varnames:
+        - InvoiceStatusQueryClassExpireLessThen60Days
+      produces:
+      - application/json
+      responses:
+        "200":
+          description: OK
+          schema:
+            allOf:
+            - $ref: '#/definitions/response.ListResponse'
+            - properties:
+                data:
+                  items:
+                    $ref: '#/definitions/model.InvoiceStatus'
+                  type: array
+              type: object
+      summary: 鑾峰彇鍙戠エ鐘舵�佸垪琛�
+      tags:
+      - 鍙戠エ鐘舵��
+  /api/invoiceStatus/update:
+    put:
+      parameters:
+      - description: 鏌ヨ鍙傛暟
+        in: body
+        name: object
+        required: true
+        schema:
+          $ref: '#/definitions/request.UpdateInvoiceStatus'
+      produces:
+      - application/json
+      responses:
+        "200":
+          description: OK
+          schema:
+            $ref: '#/definitions/contextx.Response'
+      summary: 鏇存柊鍙戠エ鐘舵��
+      tags:
+      - 鍙戠エ鐘舵��
+  /api/invoiceType/add:
+    post:
+      parameters:
+      - description: 鏌ヨ鍙傛暟
+        in: body
+        name: object
+        required: true
+        schema:
+          $ref: '#/definitions/request.AddInvoiceType'
+      produces:
+      - application/json
+      responses:
+        "200":
+          description: OK
+          schema:
+            $ref: '#/definitions/contextx.Response'
+      summary: 娣诲姞鍙戠エ绫诲瀷
+      tags:
+      - 鍙戠エ绫诲瀷
+  /api/invoiceType/delete/{id}:
+    delete:
+      parameters:
+      - description: 鏌ヨ鍙傛暟
+        in: path
+        name: id
+        required: true
+        type: integer
+      produces:
+      - application/json
+      responses:
+        "200":
+          description: OK
+          schema:
+            $ref: '#/definitions/contextx.Response'
+      summary: 鍒犻櫎鍙戠エ绫诲瀷
+      tags:
+      - 鍙戠エ绫诲瀷
+  /api/invoiceType/list:
+    get:
+      parameters:
+      - in: query
+        name: keyword
+        type: string
+      - enum:
+        - ""
+        in: query
+        name: keywordType
+        type: string
+        x-enum-varnames:
+        - InvoiceTypeKeywordCustomerName
+      - description: 椤电爜
+        in: query
+        name: page
+        type: integer
+      - description: 姣忛〉澶у皬
+        in: query
+        name: pageSize
+        type: integer
+      - enum:
+        - ""
+        in: query
+        name: queryClass
+        type: string
+        x-enum-varnames:
+        - InvoiceTypeQueryClassExpireLessThen60Days
+      produces:
+      - application/json
+      responses:
+        "200":
+          description: OK
+          schema:
+            allOf:
+            - $ref: '#/definitions/response.ListResponse'
+            - properties:
+                data:
+                  items:
+                    $ref: '#/definitions/model.InvoiceType'
+                  type: array
+              type: object
+      summary: 鑾峰彇鍙戠エ绫诲瀷鍒楄〃
+      tags:
+      - 鍙戠エ绫诲瀷
+  /api/invoiceType/update:
+    put:
+      parameters:
+      - description: 鏌ヨ鍙傛暟
+        in: body
+        name: object
+        required: true
+        schema:
+          $ref: '#/definitions/request.UpdateInvoiceType'
+      produces:
+      - application/json
+      responses:
+        "200":
+          description: OK
+          schema:
+            $ref: '#/definitions/contextx.Response'
+      summary: 鏇存柊鍙戠エ绫诲瀷
+      tags:
+      - 鍙戠エ绫诲瀷
   /api/isInvoice/add:
     post:
       parameters:
@@ -9173,9 +9783,9 @@
           description: OK
           schema:
             $ref: '#/definitions/contextx.Response'
-      summary: 娣诲姞鏈嶅姟鍚堝悓鏀舵璁″垝
+      summary: 娣诲姞鏀舵璁″垝
       tags:
-      - 鏈嶅姟鍚堝悓鏀舵璁″垝绠$悊
+      - 鏀舵璁″垝绠$悊
   /api/serviceCollectionPlan/delete/{id}:
     delete:
       parameters:
@@ -9191,9 +9801,9 @@
           description: OK
           schema:
             $ref: '#/definitions/contextx.Response'
-      summary: 鍒犻櫎鏈嶅姟鍚堝悓鏀舵璁″垝
+      summary: 鍒犻櫎鏀舵璁″垝
       tags:
-      - 鏈嶅姟鍚堝悓鏀舵璁″垝绠$悊
+      - 鏀舵璁″垝绠$悊
   /api/serviceCollectionPlan/list:
     get:
       parameters:
@@ -9215,9 +9825,9 @@
                     $ref: '#/definitions/model.ServiceCollectionPlan'
                   type: array
               type: object
-      summary: 鑾峰彇鏈嶅姟鍚堝悓鏀舵璁″垝鍒楄〃
+      summary: 鑾峰彇鏀舵璁″垝鍒楄〃
       tags:
-      - 鏈嶅姟鍚堝悓鏀舵璁″垝绠$悊
+      - 鏀舵璁″垝绠$悊
   /api/serviceCollectionPlan/update:
     put:
       parameters:
@@ -9234,9 +9844,9 @@
           description: OK
           schema:
             $ref: '#/definitions/contextx.Response'
-      summary: 鏇存柊鏈嶅姟鍚堝悓鏀舵璁″垝
+      summary: 鏇存柊鏀舵璁″垝
       tags:
-      - 鏈嶅姟鍚堝悓鏀舵璁″垝绠$悊
+      - 鏀舵璁″垝绠$悊
   /api/serviceContract/add:
     post:
       parameters:
diff --git a/go.mod b/go.mod
index 99e593f..b9fcfe1 100644
--- a/go.mod
+++ b/go.mod
@@ -16,6 +16,7 @@
 	github.com/mojocn/base64Captcha v1.3.5
 	github.com/pkg/errors v0.9.1
 	github.com/robfig/cron/v3 v3.0.1
+	github.com/shopspring/decimal v1.3.1
 	github.com/songzhibin97/gkit v1.2.11
 	github.com/spf13/viper v1.16.0
 	github.com/stretchr/testify v1.8.4
diff --git a/go.sum b/go.sum
index 9a0e61d..dd321fd 100644
--- a/go.sum
+++ b/go.sum
@@ -50,6 +50,8 @@
 github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc=
 github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE=
 github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
+github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
+github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
 github.com/QcloudApi/qcloud_sign_golang v0.0.0-20141224014652-e4130a326409/go.mod h1:1pk82RBxDY/JZnPQrtqHlUFfCctgdorsd9M06fMynOM=
 github.com/aliyun/aliyun-oss-go-sdk v2.1.6+incompatible h1:Ft+KeWIJxFP76LqgJbvtOA1qBIoC8vGkTV3QeCOeJC4=
 github.com/aliyun/aliyun-oss-go-sdk v2.1.6+incompatible/go.mod h1:T/Aws4fEfogEE9v+HPhhw+CntffsBHJ8nXQCwKr0/g8=
@@ -165,6 +167,7 @@
 github.com/go-sql-driver/mysql v1.7.1 h1:lUIinVbN1DY0xBg0eMOzmmtGoHwWBbvnWubQUrtU8EI=
 github.com/go-sql-driver/mysql v1.7.1/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
 github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
+github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
 github.com/goccy/go-json v0.9.7/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
 github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
 github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
@@ -259,6 +262,8 @@
 github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM=
 github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
 github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
+github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
+github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
 github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
 github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
 github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
@@ -379,6 +384,7 @@
 github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
 github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
 github.com/mattn/go-sqlite3 v1.14.12/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
+github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
 github.com/microsoft/go-mssqldb v1.1.0 h1:jsV+tpvcPTbNNKW0o3kiCD69kOHICsfjZ2VcVu2lKYc=
 github.com/microsoft/go-mssqldb v1.1.0/go.mod h1:LzkFdl4z2Ck+Hi+ycGOTbL56VEfgoyA2DvYejrNGbRk=
 github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
@@ -396,6 +402,7 @@
 github.com/mozillazg/go-httpheader v0.2.1/go.mod h1:jJ8xECTlalr6ValeXYdOF8fFUISeBAdw6E61aqQma60=
 github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
 github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
+github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
 github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
 github.com/onsi/gomega v1.27.4 h1:Z2AnStgsdSayCMDiCU42qIz+HLqEPcgiOCXjAU/w+8E=
 github.com/onsi/gomega v1.27.4/go.mod h1:riYq/GJKh8hhoM01HN6Vmuy93AarCXCBGpvFDK3q3fQ=
@@ -435,6 +442,8 @@
 github.com/shirou/gopsutil/v3 v3.22.5/go.mod h1:so9G9VzeHt/hsd0YwqprnjHnfARAUktauykSbr+y2gA=
 github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4=
 github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
+github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8=
+github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
 github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
 github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
 github.com/songzhibin97/gkit v1.2.11 h1:O8+l6eLMrZ2yNbT6Vohc6ggWnH5zt4P8/3ZEkf8jUL4=
@@ -580,6 +589,7 @@
 golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
 golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
 golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
+golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
 golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
 golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
 golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
@@ -925,6 +935,7 @@
 gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce h1:+JknDZhAj8YMt7GC73Ei8pv4MzjDUNPHgQWJdtMAaDU=
 gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce/go.mod h1:5AcXVHNjg+BDxry382+8OKon8SEWiKktQR07RKPsv1c=
 gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
+gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
 gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
diff --git a/model/courierCompany.go b/model/courierCompany.go
new file mode 100644
index 0000000..e78f481
--- /dev/null
+++ b/model/courierCompany.go
@@ -0,0 +1,140 @@
+package model
+
+import (
+	"aps_crm/constvar"
+	"aps_crm/pkg/mysqlx"
+	"errors"
+	"fmt"
+	"gorm.io/gorm"
+)
+
+type (
+	// CourierCompany 鐗╂祦鍏徃
+	CourierCompany struct {
+		Id   int    `json:"id" gorm:"column:id;primary_key;AUTO_INCREMENT"`
+		Name   string    `json:"name" gorm:"column:name"`
+	}
+
+	// CourierCompanySearch 鐗╂祦鍏徃鎼滅储鏉′欢
+	CourierCompanySearch struct {
+		CourierCompany
+		Orm *gorm.DB
+        QueryClass  constvar.CourierCompanyQueryClass
+        KeywordType constvar.CourierCompanyKeywordType
+        Keyword     string
+        PageNum  int
+        PageSize int
+	}
+)
+
+func (CourierCompany) TableName() string {
+	return "courier_company"
+}
+
+func NewCourierCompanySearch() *CourierCompanySearch {
+	return &CourierCompanySearch{
+		Orm: mysqlx.GetDB(),
+	}
+}
+
+func (slf *CourierCompanySearch) build() *gorm.DB {
+	var db = slf.Orm.Model(&CourierCompany{})
+	if slf.Id != 0 {
+		db = db.Where("id = ?", slf.Id)
+	}
+
+	return db
+}
+
+func (slf *CourierCompanySearch) Create(record *CourierCompany) error {
+	var db = slf.build()
+	return db.Create(record).Error
+}
+
+func (slf *CourierCompanySearch) CreateBatch(records []*CourierCompany) error {
+	var db = slf.build()
+	return db.Create(records).Error
+}
+
+func (slf *CourierCompanySearch) Delete() error {
+	var db = slf.build()
+	return db.Delete(&CourierCompany{}).Error
+}
+
+func (slf *CourierCompanySearch) Update(record *CourierCompany) error {
+	var db = slf.build()
+	return db.Updates(record).Error
+}
+
+func (slf *CourierCompanySearch) FindAll() ([]*CourierCompany, error) {
+	var db = slf.build()
+	var record = make([]*CourierCompany, 0)
+	err := db.Find(&record).Error
+	return record, err
+}
+
+func (slf *CourierCompanySearch) SetId(id int) *CourierCompanySearch {
+	slf.Id = id
+	return slf
+}
+
+func (slf *CourierCompanySearch) SetOrm(tx *gorm.DB) *CourierCompanySearch {
+	slf.Orm = tx
+	return slf
+}
+
+func (slf *CourierCompanySearch) First() (*CourierCompany, error) {
+	var db = slf.build()
+	var record = new(CourierCompany)
+	err := db.First(record).Error
+	return record, err
+}
+
+func (slf *CourierCompanySearch) Updates(values interface{}) error {
+	var db = slf.build()
+	return db.Updates(values).Error
+}
+
+func (slf *CourierCompanySearch) Save(record *CourierCompany) error {
+	if record.Id == 0 {
+		return errors.New("id涓虹┖")
+	}
+	var db = slf.build()
+
+	if err := db.Save(record).Error; err != nil {
+		return fmt.Errorf("save err: %v, record: %+v", err, record)
+	}
+
+	return nil
+}
+
+func (slf *CourierCompanySearch) Find() ([]*CourierCompany, int64, error) {
+	var db = slf.build()
+	var records = make([]*CourierCompany, 0)
+	var total int64
+	if err := db.Count(&total).Error; err != nil {
+		return records, total, err
+	}
+	if slf.PageNum > 0 && slf.PageSize > 0 {
+		db = db.Limit(slf.PageSize).Offset((slf.PageNum - 1) * slf.PageSize)
+	}
+
+	err := db.Find(&records).Error
+	return records, total, err
+}
+
+// InitDefaultData 鍒濆鍖栨暟鎹�
+func (slf *CourierCompanySearch) InitDefaultData() error {
+	var (
+		db          = slf.Orm.Table(slf.TableName())
+		total int64 = 0
+	)
+	if err := db.Count(&total).Error; err != nil {
+		return err
+	}
+	if total != 0 {
+		return nil
+	}
+	records := []*CourierCompany{}
+	return slf.CreateBatch(records)
+}
diff --git a/model/file.go b/model/file.go
index 3b919f3..bd1c46a 100644
--- a/model/file.go
+++ b/model/file.go
@@ -11,7 +11,6 @@
 type (
 	// File 闄勪欢
 	File struct {
-		Id            int    `json:"id" gorm:"column:id;primary_key;AUTO_INCREMENT"`
 		Name          string `gorm:"name" json:"name"`
 		Size          int64  `gorm:"size" json:"size"`                    // 鏂囦欢澶у皬
 		FilePath      string `gorm:"file_path" json:"filePath"`           // 鏂囦欢璺緞
@@ -22,9 +21,7 @@
 		FileType      string `gorm:"file_type" json:"fileType"`           // 鏂囦欢绫诲瀷
 		SourceType    string `gorm:"source_type" json:"sourceType"`       // 闄勪欢鏉ユ簮
 		SourceId      int    `gorm:"source_id" json:"sourceId"`           // 鏉ユ簮id
-		CreateTime    string `gorm:"create_time" json:"createTime"`       // 鍒涘缓鏃堕棿
-		UpdateTime    string `gorm:"update_time" json:"updateTime"`
-		Content       string `gorm:"content" json:"content"` // 鏂囦欢鍐呭
+		gorm.Model    `json:"-"`
 	}
 
 	// FileSearch 闄勪欢鎼滅储鏉′欢
@@ -51,8 +48,8 @@
 
 func (slf *FileSearch) build() *gorm.DB {
 	var db = slf.Orm.Model(&File{})
-	if slf.Id != 0 {
-		db = db.Where("id = ?", slf.Id)
+	if slf.ID != 0 {
+		db = db.Where("id = ?", slf.ID)
 	}
 
 	return db
@@ -85,8 +82,8 @@
 	return record, err
 }
 
-func (slf *FileSearch) SetId(id int) *FileSearch {
-	slf.Id = id
+func (slf *FileSearch) SetId(id uint) *FileSearch {
+	slf.ID = id
 	return slf
 }
 
@@ -108,7 +105,7 @@
 }
 
 func (slf *FileSearch) Save(record *File) error {
-	if record.Id == 0 {
+	if record.ID == 0 {
 		return errors.New("id涓虹┖")
 	}
 	var db = slf.build()
diff --git a/model/invoice.go b/model/invoice.go
new file mode 100644
index 0000000..ef97ed8
--- /dev/null
+++ b/model/invoice.go
@@ -0,0 +1,160 @@
+package model
+
+import (
+	"aps_crm/constvar"
+	"aps_crm/pkg/mysqlx"
+	"errors"
+	"fmt"
+	"gorm.io/gorm"
+)
+
+type (
+	// Invoice 閿�鍞彂绁�
+	Invoice struct {
+		Id               int                        `json:"id" gorm:"column:id;primary_key;AUTO_INCREMENT"`
+		ClientId         int                        `gorm:"client_id" json:"clientId"` // 瀹㈡埛id
+		Client           Client                     `gorm:"foreignKey:ClientId"`
+		InvoiceTypeId    int                        `gorm:"invoice_type_id" json:"invoiceTypeId"` // 鍙戠エ绫诲瀷id
+		InvoiceType      InvoiceType                `gorm:"foreignKey:InvoiceTypeId"`
+		PrincipalId      int                        `gorm:"principal_id" json:"principalId"`          // 閿�鍞礋璐d汉id
+		Subject          string                     `gorm:"subject" json:"subject"`                   // 涓婚
+		InvoiceStatusId  int                        `gorm:"invoice_status_id" json:"invoiceStatusId"` // 鍙戠エ鐘舵�乮d
+		InvoiceStatus    InvoiceStatus              `gorm:"foreignKey:InvoiceStatusId"`
+		SourceType       constvar.InvoiceSourceType `gorm:"source_type" json:"sourceType"`              // 婧愬崟绫诲瀷(1閿�鍞槑缁嗗崟2鏈嶅姟鍚堝悓)
+		SourceId         int                        `gorm:"source_id" json:"sourceId"`                  // 婧愬崟id
+		TaxpayerIdNumber string                     `gorm:"taxpayer_id_number" json:"taxpayerIdNumber"` // 绾崇◣璇嗗埆鍙�
+		InvoiceNumber    string                     `gorm:"invoice_number" json:"invoiceNumber"`        // 鍙戠エ鍙风爜
+		InvoiceDate      string                     `gorm:"invoice_date" json:"invoiceDate"`            // 寮�绁ㄦ棩鏈�
+		CourierNumber    string                     `gorm:"courier_number" json:"courierNumber"`        // 鐗╂祦鍗曞彿
+		CourierCompanyId int                        `gorm:"courier_company_id" json:"courierCompanyId"` // 鐗╂祦鍏徃
+		CourierCompany   CourierCompany             `gorm:"foreignKey:CourierCompanyId"`
+	}
+
+	// InvoiceSearch 閿�鍞彂绁ㄦ悳绱㈡潯浠�
+	InvoiceSearch struct {
+		Invoice
+		Orm         *gorm.DB
+		QueryClass  constvar.InvoiceQueryClass
+		KeywordType constvar.InvoiceKeywordType
+		Keyword     string
+		PageNum     int
+		PageSize    int
+	}
+)
+
+func (Invoice) TableName() string {
+	return "invoice"
+}
+
+func NewInvoiceSearch() *InvoiceSearch {
+	return &InvoiceSearch{
+		Orm: mysqlx.GetDB(),
+	}
+}
+
+func (slf *InvoiceSearch) build() *gorm.DB {
+	var db = slf.Orm.Model(&Invoice{})
+	if slf.Id != 0 {
+		db = db.Where("id = ?", slf.Id)
+	}
+
+	return db
+}
+
+func (slf *InvoiceSearch) Create(record *Invoice) error {
+	var db = slf.build()
+	return db.Create(record).Error
+}
+
+func (slf *InvoiceSearch) CreateBatch(records []*Invoice) error {
+	var db = slf.build()
+	return db.Create(records).Error
+}
+
+func (slf *InvoiceSearch) Delete() error {
+	var db = slf.build()
+	return db.Delete(&Invoice{}).Error
+}
+
+func (slf *InvoiceSearch) Update(record *Invoice) error {
+	var db = slf.build()
+	return db.Updates(record).Error
+}
+
+func (slf *InvoiceSearch) FindAll() ([]*Invoice, error) {
+	var db = slf.build()
+	var record = make([]*Invoice, 0)
+	err := db.Find(&record).Error
+	return record, err
+}
+
+func (slf *InvoiceSearch) SetId(id int) *InvoiceSearch {
+	slf.Id = id
+	return slf
+}
+
+func (slf *InvoiceSearch) SetOrm(tx *gorm.DB) *InvoiceSearch {
+	slf.Orm = tx
+	return slf
+}
+
+func (slf *InvoiceSearch) First() (*Invoice, error) {
+	var db = slf.build()
+	var record = new(Invoice)
+	err := db.First(record).Error
+	return record, err
+}
+
+func (slf *InvoiceSearch) Updates(values interface{}) error {
+	var db = slf.build()
+	return db.Updates(values).Error
+}
+
+func (slf *InvoiceSearch) Save(record *Invoice) error {
+	if record.Id == 0 {
+		return errors.New("id涓虹┖")
+	}
+	var db = slf.build()
+
+	if err := db.Save(record).Error; err != nil {
+		return fmt.Errorf("save err: %v, record: %+v", err, record)
+	}
+
+	return nil
+}
+
+func (slf *InvoiceSearch) Find() ([]*Invoice, int64, error) {
+	var db = slf.build()
+	var records = make([]*Invoice, 0)
+	var total int64
+	if err := db.Count(&total).Error; err != nil {
+		return records, total, err
+	}
+	if slf.PageNum > 0 && slf.PageSize > 0 {
+		db = db.Limit(slf.PageSize).Offset((slf.PageNum - 1) * slf.PageSize)
+	}
+
+	err := db.
+		Preload("Client").
+		Preload("InvoiceType").
+		Preload("InvoiceStatus").
+		Preload("CourierCompany").
+		Find(&records).Error
+	return records, total, err
+}
+
+// InitDefaultData 鍒濆鍖栨暟鎹�
+func (slf *InvoiceSearch) InitDefaultData() error {
+	var (
+		db          = slf.Orm.Table(slf.TableName())
+		total int64 = 0
+	)
+	if err := db.Count(&total).Error; err != nil {
+		return err
+	}
+	if total != 0 {
+		return nil
+	}
+	records := []*Invoice{}
+	return slf.CreateBatch(records)
+}
diff --git a/model/invoiceStatus.go b/model/invoiceStatus.go
new file mode 100644
index 0000000..dadfe4e
--- /dev/null
+++ b/model/invoiceStatus.go
@@ -0,0 +1,140 @@
+package model
+
+import (
+	"aps_crm/constvar"
+	"aps_crm/pkg/mysqlx"
+	"errors"
+	"fmt"
+	"gorm.io/gorm"
+)
+
+type (
+	// InvoiceStatus 鍙戠エ鐘舵��
+	InvoiceStatus struct {
+		Id   int    `json:"id" gorm:"column:id;primary_key;AUTO_INCREMENT"`
+		Name   string    `json:"name" gorm:"column:name"`
+	}
+
+	// InvoiceStatusSearch 鍙戠エ鐘舵�佹悳绱㈡潯浠�
+	InvoiceStatusSearch struct {
+		InvoiceStatus
+		Orm *gorm.DB
+        QueryClass  constvar.InvoiceStatusQueryClass
+        KeywordType constvar.InvoiceStatusKeywordType
+        Keyword     string
+        PageNum  int
+        PageSize int
+	}
+)
+
+func (InvoiceStatus) TableName() string {
+	return "invoice_status"
+}
+
+func NewInvoiceStatusSearch() *InvoiceStatusSearch {
+	return &InvoiceStatusSearch{
+		Orm: mysqlx.GetDB(),
+	}
+}
+
+func (slf *InvoiceStatusSearch) build() *gorm.DB {
+	var db = slf.Orm.Model(&InvoiceStatus{})
+	if slf.Id != 0 {
+		db = db.Where("id = ?", slf.Id)
+	}
+
+	return db
+}
+
+func (slf *InvoiceStatusSearch) Create(record *InvoiceStatus) error {
+	var db = slf.build()
+	return db.Create(record).Error
+}
+
+func (slf *InvoiceStatusSearch) CreateBatch(records []*InvoiceStatus) error {
+	var db = slf.build()
+	return db.Create(records).Error
+}
+
+func (slf *InvoiceStatusSearch) Delete() error {
+	var db = slf.build()
+	return db.Delete(&InvoiceStatus{}).Error
+}
+
+func (slf *InvoiceStatusSearch) Update(record *InvoiceStatus) error {
+	var db = slf.build()
+	return db.Updates(record).Error
+}
+
+func (slf *InvoiceStatusSearch) FindAll() ([]*InvoiceStatus, error) {
+	var db = slf.build()
+	var record = make([]*InvoiceStatus, 0)
+	err := db.Find(&record).Error
+	return record, err
+}
+
+func (slf *InvoiceStatusSearch) SetId(id int) *InvoiceStatusSearch {
+	slf.Id = id
+	return slf
+}
+
+func (slf *InvoiceStatusSearch) SetOrm(tx *gorm.DB) *InvoiceStatusSearch {
+	slf.Orm = tx
+	return slf
+}
+
+func (slf *InvoiceStatusSearch) First() (*InvoiceStatus, error) {
+	var db = slf.build()
+	var record = new(InvoiceStatus)
+	err := db.First(record).Error
+	return record, err
+}
+
+func (slf *InvoiceStatusSearch) Updates(values interface{}) error {
+	var db = slf.build()
+	return db.Updates(values).Error
+}
+
+func (slf *InvoiceStatusSearch) Save(record *InvoiceStatus) error {
+	if record.Id == 0 {
+		return errors.New("id涓虹┖")
+	}
+	var db = slf.build()
+
+	if err := db.Save(record).Error; err != nil {
+		return fmt.Errorf("save err: %v, record: %+v", err, record)
+	}
+
+	return nil
+}
+
+func (slf *InvoiceStatusSearch) Find() ([]*InvoiceStatus, int64, error) {
+	var db = slf.build()
+	var records = make([]*InvoiceStatus, 0)
+	var total int64
+	if err := db.Count(&total).Error; err != nil {
+		return records, total, err
+	}
+	if slf.PageNum > 0 && slf.PageSize > 0 {
+		db = db.Limit(slf.PageSize).Offset((slf.PageNum - 1) * slf.PageSize)
+	}
+
+	err := db.Find(&records).Error
+	return records, total, err
+}
+
+// InitDefaultData 鍒濆鍖栨暟鎹�
+func (slf *InvoiceStatusSearch) InitDefaultData() error {
+	var (
+		db          = slf.Orm.Table(slf.TableName())
+		total int64 = 0
+	)
+	if err := db.Count(&total).Error; err != nil {
+		return err
+	}
+	if total != 0 {
+		return nil
+	}
+	records := []*InvoiceStatus{}
+	return slf.CreateBatch(records)
+}
diff --git a/model/invoiceType.go b/model/invoiceType.go
new file mode 100644
index 0000000..55eced6
--- /dev/null
+++ b/model/invoiceType.go
@@ -0,0 +1,140 @@
+package model
+
+import (
+	"aps_crm/constvar"
+	"aps_crm/pkg/mysqlx"
+	"errors"
+	"fmt"
+	"gorm.io/gorm"
+)
+
+type (
+	// InvoiceType 鍙戠エ绫诲瀷
+	InvoiceType struct {
+		Id   int    `json:"id" gorm:"column:id;primary_key;AUTO_INCREMENT"`
+		Name   string    `json:"name" gorm:"column:name"`
+	}
+
+	// InvoiceTypeSearch 鍙戠エ绫诲瀷鎼滅储鏉′欢
+	InvoiceTypeSearch struct {
+		InvoiceType
+		Orm *gorm.DB
+        QueryClass  constvar.InvoiceTypeQueryClass
+        KeywordType constvar.InvoiceTypeKeywordType
+        Keyword     string
+        PageNum  int
+        PageSize int
+	}
+)
+
+func (InvoiceType) TableName() string {
+	return "invoice_type"
+}
+
+func NewInvoiceTypeSearch() *InvoiceTypeSearch {
+	return &InvoiceTypeSearch{
+		Orm: mysqlx.GetDB(),
+	}
+}
+
+func (slf *InvoiceTypeSearch) build() *gorm.DB {
+	var db = slf.Orm.Model(&InvoiceType{})
+	if slf.Id != 0 {
+		db = db.Where("id = ?", slf.Id)
+	}
+
+	return db
+}
+
+func (slf *InvoiceTypeSearch) Create(record *InvoiceType) error {
+	var db = slf.build()
+	return db.Create(record).Error
+}
+
+func (slf *InvoiceTypeSearch) CreateBatch(records []*InvoiceType) error {
+	var db = slf.build()
+	return db.Create(records).Error
+}
+
+func (slf *InvoiceTypeSearch) Delete() error {
+	var db = slf.build()
+	return db.Delete(&InvoiceType{}).Error
+}
+
+func (slf *InvoiceTypeSearch) Update(record *InvoiceType) error {
+	var db = slf.build()
+	return db.Updates(record).Error
+}
+
+func (slf *InvoiceTypeSearch) FindAll() ([]*InvoiceType, error) {
+	var db = slf.build()
+	var record = make([]*InvoiceType, 0)
+	err := db.Find(&record).Error
+	return record, err
+}
+
+func (slf *InvoiceTypeSearch) SetId(id int) *InvoiceTypeSearch {
+	slf.Id = id
+	return slf
+}
+
+func (slf *InvoiceTypeSearch) SetOrm(tx *gorm.DB) *InvoiceTypeSearch {
+	slf.Orm = tx
+	return slf
+}
+
+func (slf *InvoiceTypeSearch) First() (*InvoiceType, error) {
+	var db = slf.build()
+	var record = new(InvoiceType)
+	err := db.First(record).Error
+	return record, err
+}
+
+func (slf *InvoiceTypeSearch) Updates(values interface{}) error {
+	var db = slf.build()
+	return db.Updates(values).Error
+}
+
+func (slf *InvoiceTypeSearch) Save(record *InvoiceType) error {
+	if record.Id == 0 {
+		return errors.New("id涓虹┖")
+	}
+	var db = slf.build()
+
+	if err := db.Save(record).Error; err != nil {
+		return fmt.Errorf("save err: %v, record: %+v", err, record)
+	}
+
+	return nil
+}
+
+func (slf *InvoiceTypeSearch) Find() ([]*InvoiceType, int64, error) {
+	var db = slf.build()
+	var records = make([]*InvoiceType, 0)
+	var total int64
+	if err := db.Count(&total).Error; err != nil {
+		return records, total, err
+	}
+	if slf.PageNum > 0 && slf.PageSize > 0 {
+		db = db.Limit(slf.PageSize).Offset((slf.PageNum - 1) * slf.PageSize)
+	}
+
+	err := db.Find(&records).Error
+	return records, total, err
+}
+
+// InitDefaultData 鍒濆鍖栨暟鎹�
+func (slf *InvoiceTypeSearch) InitDefaultData() error {
+	var (
+		db          = slf.Orm.Table(slf.TableName())
+		total int64 = 0
+	)
+	if err := db.Count(&total).Error; err != nil {
+		return err
+	}
+	if total != 0 {
+		return nil
+	}
+	records := []*InvoiceType{}
+	return slf.CreateBatch(records)
+}
diff --git a/model/request/courierCompany.go b/model/request/courierCompany.go
new file mode 100644
index 0000000..b01d559
--- /dev/null
+++ b/model/request/courierCompany.go
@@ -0,0 +1,22 @@
+package request
+
+import (
+    "aps_crm/constvar"
+    "aps_crm/model"
+)
+
+type AddCourierCompany struct {
+	model.CourierCompany
+}
+
+type UpdateCourierCompany struct {
+	Id int `json:"id"`
+	model.CourierCompany
+}
+
+type GetCourierCompanyList struct {
+	PageInfo
+	QueryClass  constvar.CourierCompanyQueryClass  `json:"queryClass" form:"queryClass"`
+	KeywordType constvar.CourierCompanyKeywordType `json:"keywordType"  form:"keywordType"`
+	Keyword     string                       `json:"keyword" form:"keyword"`
+}
diff --git a/model/request/file.go b/model/request/file.go
index 5b17b6b..096675b 100644
--- a/model/request/file.go
+++ b/model/request/file.go
@@ -11,7 +11,7 @@
 }
 
 type UpdateFile struct {
-	Id int `json:"id"`
+	Id uint `json:"id"`
 	model.File
 }
 
diff --git a/model/request/invoice.go b/model/request/invoice.go
new file mode 100644
index 0000000..1b1eddd
--- /dev/null
+++ b/model/request/invoice.go
@@ -0,0 +1,43 @@
+package request
+
+import (
+	"aps_crm/constvar"
+)
+
+type AddInvoice struct {
+	ClientId         int                        `gorm:"client_id" json:"clientId"`                  // 瀹㈡埛id
+	InvoiceTypeId    int                        `gorm:"invoice_type_id" json:"invoiceTypeId"`       // 鍙戠エ绫诲瀷id
+	PrincipalId      int                        `gorm:"principal_id" json:"principalId"`            // 閿�鍞礋璐d汉id
+	Subject          string                     `gorm:"subject" json:"subject"`                     // 涓婚
+	InvoiceStatusId  int                        `gorm:"invoice_status_id" json:"invoiceStatusId"`   // 鍙戠エ鐘舵�乮d
+	SourceType       constvar.InvoiceSourceType `gorm:"source_type" json:"sourceType"`              // 婧愬崟绫诲瀷(1閿�鍞槑缁嗗崟2鏈嶅姟鍚堝悓)
+	SourceId         int                        `gorm:"source_id" json:"sourceId"`                  // 婧愬崟id
+	TaxpayerIdNumber string                     `gorm:"taxpayer_id_number" json:"taxpayerIdNumber"` // 绾崇◣璇嗗埆鍙�
+	InvoiceNumber    string                     `gorm:"invoice_number" json:"invoiceNumber"`        // 鍙戠エ鍙风爜
+	InvoiceDate      string                     `gorm:"invoice_date" json:"invoiceDate"`            // 寮�绁ㄦ棩鏈�
+	CourierNumber    string                     `gorm:"courier_number" json:"courierNumber"`        // 鐗╂祦鍗曞彿
+	CourierCompanyId int                        `gorm:"courier_company_id" json:"courierCompanyId"` // 鐗╂祦鍏徃
+}
+
+type UpdateInvoice struct {
+	Id               int    `json:"id"`
+	ClientId         int    `gorm:"client_id" json:"clientId"`                  // 瀹㈡埛id
+	InvoiceTypeId    int    `gorm:"invoice_type_id" json:"invoiceTypeId"`       // 鍙戠エ绫诲瀷id
+	PrincipalId      int    `gorm:"principal_id" json:"principalId"`            // 閿�鍞礋璐d汉id
+	Subject          string `gorm:"subject" json:"subject"`                     // 涓婚
+	InvoiceStatusId  int    `gorm:"invoice_status_id" json:"invoiceStatusId"`   // 鍙戠エ鐘舵�乮d
+	SourceType       int    `gorm:"source_type" json:"sourceType"`              // 婧愬崟绫诲瀷(1閿�鍞槑缁嗗崟2鏈嶅姟鍚堝悓)
+	SourceId         int    `gorm:"source_id" json:"sourceId"`                  // 婧愬崟id
+	TaxpayerIdNumber string `gorm:"taxpayer_id_number" json:"taxpayerIdNumber"` // 绾崇◣璇嗗埆鍙�
+	InvoiceNumber    string `gorm:"invoice_number" json:"invoiceNumber"`        // 鍙戠エ鍙风爜
+	InvoiceDate      int    `gorm:"invoice_date" json:"invoiceDate"`            // 寮�绁ㄦ棩鏈�
+	CourierNumber    string `gorm:"courier_number" json:"courierNumber"`        // 鐗╂祦鍗曞彿
+	CourierCompanyId int    `gorm:"courier_company_id" json:"courierCompanyId"` // 鐗╂祦鍏徃
+}
+
+type GetInvoiceList struct {
+	PageInfo
+	QueryClass  constvar.InvoiceQueryClass  `json:"queryClass" form:"queryClass"`
+	KeywordType constvar.InvoiceKeywordType `json:"keywordType"  form:"keywordType"`
+	Keyword     string                      `json:"keyword" form:"keyword"`
+}
diff --git a/model/request/invoiceStatus.go b/model/request/invoiceStatus.go
new file mode 100644
index 0000000..608e149
--- /dev/null
+++ b/model/request/invoiceStatus.go
@@ -0,0 +1,22 @@
+package request
+
+import (
+    "aps_crm/constvar"
+    "aps_crm/model"
+)
+
+type AddInvoiceStatus struct {
+	model.InvoiceStatus
+}
+
+type UpdateInvoiceStatus struct {
+	Id int `json:"id"`
+	model.InvoiceStatus
+}
+
+type GetInvoiceStatusList struct {
+	PageInfo
+	QueryClass  constvar.InvoiceStatusQueryClass  `json:"queryClass" form:"queryClass"`
+	KeywordType constvar.InvoiceStatusKeywordType `json:"keywordType"  form:"keywordType"`
+	Keyword     string                       `json:"keyword" form:"keyword"`
+}
diff --git a/model/request/invoiceType.go b/model/request/invoiceType.go
new file mode 100644
index 0000000..24d3ea5
--- /dev/null
+++ b/model/request/invoiceType.go
@@ -0,0 +1,22 @@
+package request
+
+import (
+    "aps_crm/constvar"
+    "aps_crm/model"
+)
+
+type AddInvoiceType struct {
+	model.InvoiceType
+}
+
+type UpdateInvoiceType struct {
+	Id int `json:"id"`
+	model.InvoiceType
+}
+
+type GetInvoiceTypeList struct {
+	PageInfo
+	QueryClass  constvar.InvoiceTypeQueryClass  `json:"queryClass" form:"queryClass"`
+	KeywordType constvar.InvoiceTypeKeywordType `json:"keywordType"  form:"keywordType"`
+	Keyword     string                       `json:"keyword" form:"keyword"`
+}
diff --git a/model/request/serviceCollectionPlan.go b/model/request/serviceCollectionPlan.go
index b8e4f35..a1a9a11 100644
--- a/model/request/serviceCollectionPlan.go
+++ b/model/request/serviceCollectionPlan.go
@@ -5,7 +5,7 @@
 )
 
 type AddServiceCollectionPlan struct {
-	List []*model.ServiceCollectionPlan
+	List []*model.ServiceCollectionPlan `json:"list" binding:"required"`
 }
 
 type UpdateServiceCollectionPlan struct {
diff --git a/model/serviceCollectionPlan.go b/model/serviceCollectionPlan.go
index be9da1b..cb15770 100644
--- a/model/serviceCollectionPlan.go
+++ b/model/serviceCollectionPlan.go
@@ -5,27 +5,30 @@
 	"aps_crm/pkg/mysqlx"
 	"errors"
 	"fmt"
+	"github.com/shopspring/decimal"
 	"gorm.io/gorm"
+	"time"
 )
 
 type (
-	// ServiceCollectionPlan 鏈嶅姟鍚堝悓鏀舵璁″垝
+	// ServiceCollectionPlan 鏀舵璁″垝
 	ServiceCollectionPlan struct {
-		Id                int     `json:"id" gorm:"column:id;primary_key;AUTO_INCREMENT"`
-		CollectionType    int     `gorm:"collection_type" json:"collectionType"`        // 绫诲瀷锛�1 璁″垝鏀舵鏃ユ湡 2 椤圭洰鐘舵�侊級
-		ServiceContractId int     `gorm:"service_contract_id" json:"serviceContractId"` // 鏈嶅姟鍚堝悓id
-		PrincipalId       int     `gorm:"principal_id" json:"principalId"`              // 鏀舵璐熻矗浜篒D
-		Term              int     `gorm:"term" json:"term"`                             // 鏈熸
-		Percent           float64 `gorm:"percent" json:"percent"`                       // 姣斾緥
-		Amount            float64 `gorm:"amount" json:"amount"`                         // 閲戦
-		MoneyType         string  `gorm:"money_type" json:"moneyType"`                  // 甯佺
-		CollectionDate    string  `gorm:"collection_date" json:"collectionDate"`        // 璁″垝鏀舵鏃ユ湡
-		Remark            string  `gorm:"remark" json:"remark"`                         // 澶囨敞
-		Status            int     `gorm:"status" json:"status"`                         // 鐘舵�侊紙1鏈敹2宸叉敹锛�
-		FileId            int     `gorm:"file_id" json:"fileId"`                        // 闄勪欢id
+		Id             int                       `json:"id" gorm:"column:id;primary_key;AUTO_INCREMENT"`
+		CollectionType int                       `gorm:"collection_type" json:"collectionType"` // 绫诲瀷锛�1 璁″垝鏀舵鏃ユ湡 2 椤圭洰鐘舵�侊級
+		SourceType     int                       `gorm:"source_type" json:"sourceType"`         // 婧愬崟绫诲瀷锛�1閿�鍞槑缁�2鏈嶅姟鍚堝悓3閿�鍞彂绁級
+		SourceId       int                       `gorm:"source_id" json:"sourceId"`             // 婧愬崟id
+		PrincipalId    int                       `gorm:"principal_id" json:"principalId"`       // 鏀舵璐熻矗浜篒D
+		Term           int                       `gorm:"term" json:"term"`                      // 鏈熸
+		Percent        decimal.Decimal           `gorm:"percent" json:"percent"`                // 姣斾緥
+		Amount         decimal.Decimal           `gorm:"amount" json:"amount"`                  // 閲戦
+		MoneyType      string                    `gorm:"money_type" json:"moneyType"`           // 甯佺
+		CollectionDate time.Time                 `gorm:"collection_date" json:"collectionDate"` // 璁″垝鏀舵鏃ユ湡
+		Remark         string                    `gorm:"remark" json:"remark"`                  // 澶囨敞
+		Status         constvar.CollectionStatus `gorm:"status" json:"status"`                  // 鐘舵�侊紙1鏈敹2宸叉敹锛�
+		FileId         int                       `gorm:"file_id" json:"fileId"`                 // 闄勪欢id
 	}
 
-	// ServiceCollectionPlanSearch 鏈嶅姟鍚堝悓鏀舵璁″垝鎼滅储鏉′欢
+	// ServiceCollectionPlanSearch 鏀舵璁″垝鎼滅储鏉′欢
 	ServiceCollectionPlanSearch struct {
 		ServiceCollectionPlan
 		Orm         *gorm.DB
@@ -38,7 +41,7 @@
 )
 
 func (ServiceCollectionPlan) TableName() string {
-	return "service_collection_plan"
+	return "collection_plan"
 }
 
 func NewServiceCollectionPlanSearch() *ServiceCollectionPlanSearch {
@@ -53,8 +56,8 @@
 		db = db.Where("id = ?", slf.Id)
 	}
 
-	if slf.ServiceContractId != 0 {
-		db = db.Where("service_contract_id = ?", slf.ServiceContractId)
+	if slf.SourceId != 0 {
+		db = db.Where("source_id = ?", slf.SourceId)
 	}
 
 	return db
@@ -97,8 +100,8 @@
 	return slf
 }
 
-func (slf *ServiceCollectionPlanSearch) SetServiceContractId(id int) *ServiceCollectionPlanSearch {
-	slf.ServiceContractId = id
+func (slf *ServiceCollectionPlanSearch) SetSourceId(id int) *ServiceCollectionPlanSearch {
+	slf.SourceId = id
 	return slf
 }
 
diff --git a/model/serviceContract.go b/model/serviceContract.go
index 5b20512..5c5a497 100644
--- a/model/serviceContract.go
+++ b/model/serviceContract.go
@@ -1,172 +1,202 @@
-package model
-
-import (
-	"aps_crm/constvar"
-	"aps_crm/pkg/mysqlx"
-	"gorm.io/gorm"
-	"time"
-)
-
-type (
-	ServiceContract struct {
-		Id                      int       `json:"id" gorm:"column:id;primary_key;AUTO_INCREMENT"`
-		ClientId                int       `json:"clientId" gorm:"column:client_id;type:int;comment:瀹㈡埛id"`
-		Number                  string    `json:"number" gorm:"column:number;type:varchar(255);comment:鍚堝悓缂栧彿"`
-		MemberId                int       `json:"memberId" gorm:"column:member_id;type:int;comment:璐熻矗浜篿d"`
-		ContactId               int       `json:"contactId" gorm:"column:contact_id;type:int;comment:鑱旂郴浜篿d"`
-		SaleChanceId            int       `json:"saleChanceId" gorm:"column:sale_chance_id;type:int;comment:閿�鍞満浼歩d"`
-		ContractId              int       `json:"contractId" gorm:"column:contract_id;type:int;comment:鍚堝悓id"`
-		QuotationId             int       `json:"quotationId" gorm:"column:quotation_id;type:int;comment:鎶ヤ环鍗昳d"`
-		ServiceContractTypeId   int       `json:"serviceContractTypeId" gorm:"column:service_contract_type_id;type:int;comment:鍚堝悓绫诲瀷id"`
-		SignTime                time.Time `json:"signTime" gorm:"column:sign_time;type:datetime;comment:绛剧害鏃堕棿"`
-		StartTime               time.Time `json:"startTime" gorm:"column:start_time;type:datetime;comment:寮�濮嬫椂闂�"`
-		EndTime                 time.Time `json:"endTime" gorm:"column:end_time;type:datetime;comment:缁撴潫鏃堕棿"`
-		ServiceContractStatusId int       `json:"serviceContractStatusId" gorm:"column:service_contract_status_id;type:int;comment:鍚堝悓鐘舵�乮d"`
-		ServiceTimes            int       `json:"serviceTimes" gorm:"column:service_times;type:int;comment:鏈嶅姟娆℃暟"`
-		Terms                   string    `json:"terms" gorm:"column:terms;type:text;comment:鏉℃"`
-		Remark                  string    `json:"remark" gorm:"column:remark;type:text;comment:澶囨敞"`
-		Products                []Product `json:"products" gorm:"many2many:serviceContract_product;"`
-		gorm.Model              `json:"-"`
-	}
-
-	ServiceContractSearch struct {
-		ServiceContract
-
-		Orm         *gorm.DB
-		QueryClass  constvar.ServiceContractQueryClass
-		KeywordType constvar.ServiceContractKeywordType
-		Keyword     interface{}
-		OrderBy     string
-		PageNum     int
-		PageSize    int
-	}
-)
-
-func (ServiceContract) TableName() string {
-	return "service_contract"
-}
-
-func NewServiceContractSearch() *ServiceContractSearch {
-	return &ServiceContractSearch{
-		Orm: mysqlx.GetDB(),
-	}
-}
-
-func (slf *ServiceContractSearch) build() *gorm.DB {
-	var db = slf.Orm.Model(&ServiceContract{})
-	if slf.Id != 0 {
-		db = db.Where("id = ?", slf.Id)
-	}
-	switch slf.QueryClass {
-	case constvar.ServiceContractQueryClassExpireAfter30Day:
-		db = db.Where("end_time > ?", time.Now(), time.Now().AddDate(0, 0, 30))
-	case constvar.ServiceContractQueryClassExpireAfter60Day:
-		db = db.Where("end_time > ?", time.Now(), time.Now().AddDate(0, 0, 60))
-	case constvar.ServiceContractQueryClassExpiredBefore15Day:
-		db = db.Where("end_time < ?", time.Now().AddDate(0, 0, -15))
-	case constvar.ServiceContractQueryClassExpiredBefore60Day:
-		db = db.Where("end_time < ?", time.Now().AddDate(0, 0, -60))
-
-	}
-	switch slf.KeywordType {
-	case constvar.ServiceContractKeywordContractNo:
-		db = db.Where("number = ?", slf.Keyword)
-	case constvar.ServiceContractKeywordCustomerName:
-		db = db.Where("client_id = ?", slf.Keyword)
-	case constvar.ServiceContractKeywordContractDate:
-		db = db.Where("sign_time = ?", slf.Keyword)
-	case constvar.ServiceContractKeywordContractType:
-		db = db.Where("service_contract_type_id = ?", slf.Keyword)
-	case constvar.ServiceContractKeywordContractStatus:
-		db = db.Where("service_contract_status_id = ?", slf.Keyword)
-	case constvar.ServiceContractKeywordPrincipal:
-		db = db.Where("member_id = ?", slf.Keyword)
-	case constvar.ServiceContractKeywordProductName:
-		subQuery := db.Table("service_contract_id").Select("product_id").Where("product_id = ?", slf.Keyword)
-		db = db.Where("id = ?", subQuery)
-	case constvar.ServiceContractKeywordServiceBeginDate:
-		db = db.Where("start_time = ?", slf.Keyword)
-	case constvar.ServiceContractKeywordServiceEndDate:
-		db = db.Where("end_time = ?", slf.Keyword)
-	case constvar.ServiceContractKeywordServiceTotalPrice:
-		//todo
-
-	}
-
-	return db
-}
-
-func (slf *ServiceContractSearch) Create(record *ServiceContract) error {
-	var db = slf.build()
-	return db.Create(record).Error
-}
-
-func (slf *ServiceContractSearch) Update(record *ServiceContract) error {
-	var db = slf.build()
-	return db.Updates(record).Error
-}
-
-func (slf *ServiceContractSearch) Delete() error {
-	var db = slf.build()
-	return db.Delete(&ServiceContract{}).Error
-}
-
-func (slf *ServiceContractSearch) Find() (*ServiceContract, error) {
-	var db = slf.build()
-	var record = &ServiceContract{}
-	err := db.First(record).Error
-	return record, err
-}
-
-func (slf *ServiceContractSearch) FindAll() ([]*ServiceContract, int64, error) {
-	var db = slf.build()
-	var records = make([]*ServiceContract, 0)
-	var total int64
-	if err := db.Count(&total).Error; err != nil {
-		return records, total, err
-	}
-	if slf.PageNum > 0 && slf.PageSize > 0 {
-		db = db.Limit(slf.PageSize).Offset((slf.PageNum - 1) * slf.PageSize)
-	}
-
-	if slf.PageNum > 0 && slf.PageSize > 0 {
-		db = db.Limit(slf.PageSize).Offset((slf.PageNum - 1) * slf.PageSize)
-	}
-
-	err := db.Preload("Products").Find(&records).Error
-	return records, total, err
-}
-
-func (slf *ServiceContractSearch) SetId(id int) *ServiceContractSearch {
-	slf.Id = id
-	return slf
-}
-
-func (slf *ServiceContractSearch) SetKeywordType(keyword constvar.ServiceContractKeywordType) *ServiceContractSearch {
-	slf.KeywordType = keyword
-	return slf
-}
-
-func (slf *ServiceContractSearch) SetQueryClass(queryClass constvar.ServiceContractQueryClass) *ServiceContractSearch {
-	slf.QueryClass = queryClass
-	return slf
-}
-
-func (slf *ServiceContractSearch) SetKeyword(keyword string) *ServiceContractSearch {
-	slf.Keyword = keyword
-	return slf
-}
-
-func (slf *ServiceContractSearch) SetPage(page, size int) *ServiceContractSearch {
-	slf.PageNum, slf.PageSize = page, size
-	return slf
-}
-
-func (slf *ServiceContractSearch) SetOrder(order string) *ServiceContractSearch {
-	slf.OrderBy = order
-	return slf
-}
-func (slf *ServiceContractSearch) SetIds(ids []int) *ServiceContractSearch {
-	slf.Orm = slf.Orm.Where("id in (?)", ids)
-	return slf
-}
+package model
+
+import (
+	"aps_crm/constvar"
+	"aps_crm/pkg/mysqlx"
+	"fmt"
+	"github.com/shopspring/decimal"
+	"gorm.io/gorm"
+	"time"
+)
+
+type (
+	ServiceContract struct {
+		Id                      int             `json:"id" gorm:"column:id;primary_key;AUTO_INCREMENT"`
+		ClientId                int             `json:"clientId" gorm:"column:client_id;type:int;comment:瀹㈡埛id"`
+		Number                  string          `json:"number" gorm:"column:number;type:varchar(255);comment:鍚堝悓缂栧彿"`
+		MemberId                int             `json:"memberId" gorm:"column:member_id;type:int;comment:璐熻矗浜篿d"`
+		ContactId               int             `json:"contactId" gorm:"column:contact_id;type:int;comment:鑱旂郴浜篿d"`
+		SaleChanceId            int             `json:"saleChanceId" gorm:"column:sale_chance_id;type:int;comment:閿�鍞満浼歩d"`
+		ContractId              int             `json:"contractId" gorm:"column:contract_id;type:int;comment:鍚堝悓id"`
+		QuotationId             int             `json:"quotationId" gorm:"column:quotation_id;type:int;comment:鎶ヤ环鍗昳d"`
+		ServiceContractTypeId   int             `json:"serviceContractTypeId" gorm:"column:service_contract_type_id;type:int;comment:鍚堝悓绫诲瀷id"`
+		SignTime                time.Time       `json:"signTime" gorm:"column:sign_time;type:datetime;comment:绛剧害鏃堕棿"`
+		StartTime               time.Time       `json:"startTime" gorm:"column:start_time;type:datetime;comment:寮�濮嬫椂闂�"`
+		EndTime                 time.Time       `json:"endTime" gorm:"column:end_time;type:datetime;comment:缁撴潫鏃堕棿"`
+		ServiceContractStatusId int             `json:"serviceContractStatusId" gorm:"column:service_contract_status_id;type:int;comment:鍚堝悓鐘舵�乮d"`
+		ServiceTimes            int             `json:"serviceTimes" gorm:"column:service_times;type:int;comment:鏈嶅姟娆℃暟"`
+		Terms                   string          `json:"terms" gorm:"column:terms;type:text;comment:鏉℃"`
+		Remark                  string          `json:"remark" gorm:"column:remark;type:text;comment:澶囨敞"`
+		AmountReceivable        decimal.Decimal `gorm:"amount_receivable" json:"amountReceivable"` // 搴旀敹閲戦
+		AmountReceived          decimal.Decimal `gorm:"amount_received" json:"amountReceived"`     // 宸叉敹閲戦
+		AmountInvoiced          decimal.Decimal `gorm:"amount_invoiced" json:"amountInvoiced"`     // 宸插紑绁ㄩ噾棰�
+		Products                []Product       `json:"products" gorm:"many2many:serviceContract_product;"`
+		gorm.Model              `json:"-"`
+	}
+
+	ServiceContractSearch struct {
+		ServiceContract
+
+		Orm         *gorm.DB
+		QueryClass  constvar.ServiceContractQueryClass
+		KeywordType constvar.ServiceContractKeywordType
+		Keyword     interface{}
+		OrderBy     string
+		PageNum     int
+		PageSize    int
+	}
+)
+
+func (ServiceContract) TableName() string {
+	return "service_contract"
+}
+
+func NewServiceContractSearch() *ServiceContractSearch {
+	return &ServiceContractSearch{
+		Orm: mysqlx.GetDB(),
+	}
+}
+
+func (slf *ServiceContractSearch) build() *gorm.DB {
+	var db = slf.Orm.Model(&ServiceContract{})
+	if slf.Id != 0 {
+		db = db.Where("id = ?", slf.Id)
+	}
+	switch slf.QueryClass {
+	case constvar.ServiceContractQueryClassExpireAfter30Day:
+		db = db.Where("end_time > ?", time.Now(), time.Now().AddDate(0, 0, 30))
+	case constvar.ServiceContractQueryClassExpireAfter60Day:
+		db = db.Where("end_time > ?", time.Now(), time.Now().AddDate(0, 0, 60))
+	case constvar.ServiceContractQueryClassExpiredBefore15Day:
+		db = db.Where("end_time < ?", time.Now().AddDate(0, 0, -15))
+	case constvar.ServiceContractQueryClassExpiredBefore60Day:
+		db = db.Where("end_time < ?", time.Now().AddDate(0, 0, -60))
+
+	}
+	switch slf.KeywordType {
+	case constvar.ServiceContractKeywordContractNo:
+		db = db.Where("number = ?", slf.Keyword)
+	case constvar.ServiceContractKeywordCustomerName:
+		db = db.Where("client_id = ?", slf.Keyword)
+	case constvar.ServiceContractKeywordContractDate:
+		db = db.Where("sign_time = ?", slf.Keyword)
+	case constvar.ServiceContractKeywordContractType:
+		db = db.Where("service_contract_type_id = ?", slf.Keyword)
+	case constvar.ServiceContractKeywordContractStatus:
+		db = db.Where("service_contract_status_id = ?", slf.Keyword)
+	case constvar.ServiceContractKeywordPrincipal:
+		db = db.Where("member_id = ?", slf.Keyword)
+	case constvar.ServiceContractKeywordProductName:
+		subQuery := db.Table("service_contract_id").Select("product_id").Where("product_id = ?", slf.Keyword)
+		db = db.Where("id = ?", subQuery)
+	case constvar.ServiceContractKeywordServiceBeginDate:
+		db = db.Where("start_time = ?", slf.Keyword)
+	case constvar.ServiceContractKeywordServiceEndDate:
+		db = db.Where("end_time = ?", slf.Keyword)
+	case constvar.ServiceContractKeywordServiceTotalPrice:
+		//todo
+
+	}
+
+	return db
+}
+
+func (slf *ServiceContractSearch) Create(record *ServiceContract) error {
+	var db = slf.build()
+	return db.Create(record).Error
+}
+
+func (slf *ServiceContractSearch) Update(record *ServiceContract) error {
+	var db = slf.build()
+	return db.Updates(record).Error
+}
+
+func (slf *ServiceContractSearch) Delete() error {
+	var db = slf.build()
+	return db.Delete(&ServiceContract{}).Error
+}
+
+func (slf *ServiceContractSearch) Find() (*ServiceContract, error) {
+	var db = slf.build()
+	var record = &ServiceContract{}
+	err := db.First(record).Error
+	return record, err
+}
+
+func (slf *ServiceContractSearch) FindAll() ([]*ServiceContract, int64, error) {
+	var db = slf.build()
+	var records = make([]*ServiceContract, 0)
+	var total int64
+	if err := db.Count(&total).Error; err != nil {
+		return records, total, err
+	}
+	if slf.PageNum > 0 && slf.PageSize > 0 {
+		db = db.Limit(slf.PageSize).Offset((slf.PageNum - 1) * slf.PageSize)
+	}
+
+	if slf.PageNum > 0 && slf.PageSize > 0 {
+		db = db.Limit(slf.PageSize).Offset((slf.PageNum - 1) * slf.PageSize)
+	}
+
+	err := db.Preload("Products").Find(&records).Error
+	return records, total, err
+}
+
+func (slf *ServiceContractSearch) SetId(id int) *ServiceContractSearch {
+	slf.Id = id
+	return slf
+}
+
+func (slf *ServiceContractSearch) SetKeywordType(keyword constvar.ServiceContractKeywordType) *ServiceContractSearch {
+	slf.KeywordType = keyword
+	return slf
+}
+
+func (slf *ServiceContractSearch) SetQueryClass(queryClass constvar.ServiceContractQueryClass) *ServiceContractSearch {
+	slf.QueryClass = queryClass
+	return slf
+}
+
+func (slf *ServiceContractSearch) SetKeyword(keyword string) *ServiceContractSearch {
+	slf.Keyword = keyword
+	return slf
+}
+
+func (slf *ServiceContractSearch) SetPage(page, size int) *ServiceContractSearch {
+	slf.PageNum, slf.PageSize = page, size
+	return slf
+}
+
+func (slf *ServiceContractSearch) SetOrder(order string) *ServiceContractSearch {
+	slf.OrderBy = order
+	return slf
+}
+func (slf *ServiceContractSearch) SetIds(ids []int) *ServiceContractSearch {
+	slf.Orm = slf.Orm.Where("id in (?)", ids)
+	return slf
+}
+
+func (slf *ServiceContractSearch) UpdateByMap(upMap map[string]interface{}) error {
+	var (
+		db = slf.build()
+	)
+
+	if err := db.Updates(upMap).Error; err != nil {
+		return fmt.Errorf("update by map err: %v, upMap: %+v", err, upMap)
+	}
+
+	return nil
+}
+
+func (slf *ServiceContractSearch) First() (*ServiceContract, error) {
+	var (
+		record = new(ServiceContract)
+		db     = slf.build()
+	)
+
+	if err := db.First(record).Error; err != nil {
+		return record, err
+	}
+
+	return record, nil
+}
diff --git a/router/courierCompany.go b/router/courierCompany.go
new file mode 100644
index 0000000..0356787
--- /dev/null
+++ b/router/courierCompany.go
@@ -0,0 +1,17 @@
+package router
+
+import (
+	v1 "aps_crm/api/v1"
+	"github.com/gin-gonic/gin"
+)
+
+func InitCourierCompanyRouter(router *gin.RouterGroup) {
+	CourierCompanyRouter := router.Group("courierCompany")
+	CourierCompanyApi := v1.CourierCompanyApi{}
+	{
+		CourierCompanyRouter.POST("add", CourierCompanyApi.Add)             // 娣诲姞鐗╂祦鍏徃
+		CourierCompanyRouter.DELETE("delete/:id", CourierCompanyApi.Delete) // 鍒犻櫎鐗╂祦鍏徃
+		CourierCompanyRouter.PUT("update", CourierCompanyApi.Update)        // 鏇存柊鐗╂祦鍏徃
+		CourierCompanyRouter.GET("list", CourierCompanyApi.List)            // 鑾峰彇鐗╂祦鍏徃鍒楄〃
+	}
+}
diff --git a/router/file.go b/router/file.go
index 60757b4..3946e5d 100644
--- a/router/file.go
+++ b/router/file.go
@@ -11,5 +11,6 @@
 	{
 		FileRouter.POST("add", FileApi.Add)             // 娣诲姞闄勪欢
 		FileRouter.DELETE("delete/:id", FileApi.Delete) // 鍒犻櫎闄勪欢
+		FileRouter.GET("list", FileApi.List)            // 闄勪欢鍒楄〃
 	}
 }
diff --git a/router/index.go b/router/index.go
index e40f7c7..8d830e5 100644
--- a/router/index.go
+++ b/router/index.go
@@ -169,6 +169,13 @@
 		InitServiceCollectionPlanRouter(PrivateGroup)
 		InitReceiptRouter(PrivateGroup)
 		InitBankAccountRouter(PrivateGroup)
+		InitPaymentTypeRouter(PrivateGroup)
+		InitFileRouter(PrivateGroup)
+		InitInvoiceRouter(PrivateGroup)
+		InitInvoiceStatusRouter(PrivateGroup)
+		InitInvoiceTypeRouter(PrivateGroup)
+		InitCourierCompanyRouter(PrivateGroup)
+
 	}
 	return Router
 }
diff --git a/router/invoice.go b/router/invoice.go
new file mode 100644
index 0000000..d60183b
--- /dev/null
+++ b/router/invoice.go
@@ -0,0 +1,17 @@
+package router
+
+import (
+	v1 "aps_crm/api/v1"
+	"github.com/gin-gonic/gin"
+)
+
+func InitInvoiceRouter(router *gin.RouterGroup) {
+	InvoiceRouter := router.Group("invoice")
+	InvoiceApi := v1.InvoiceApi{}
+	{
+		InvoiceRouter.POST("add", InvoiceApi.Add)             // 娣诲姞閿�鍞彂绁�
+		InvoiceRouter.DELETE("delete/:id", InvoiceApi.Delete) // 鍒犻櫎閿�鍞彂绁�
+		InvoiceRouter.PUT("update", InvoiceApi.Update)        // 鏇存柊閿�鍞彂绁�
+		InvoiceRouter.GET("list", InvoiceApi.List)            // 鑾峰彇閿�鍞彂绁ㄥ垪琛�
+	}
+}
diff --git a/router/invoiceStatus.go b/router/invoiceStatus.go
new file mode 100644
index 0000000..3b3a3cd
--- /dev/null
+++ b/router/invoiceStatus.go
@@ -0,0 +1,17 @@
+package router
+
+import (
+	v1 "aps_crm/api/v1"
+	"github.com/gin-gonic/gin"
+)
+
+func InitInvoiceStatusRouter(router *gin.RouterGroup) {
+	InvoiceStatusRouter := router.Group("invoiceStatus")
+	InvoiceStatusApi := v1.InvoiceStatusApi{}
+	{
+		InvoiceStatusRouter.POST("add", InvoiceStatusApi.Add)             // 娣诲姞鍙戠エ鐘舵��
+		InvoiceStatusRouter.DELETE("delete/:id", InvoiceStatusApi.Delete) // 鍒犻櫎鍙戠エ鐘舵��
+		InvoiceStatusRouter.PUT("update", InvoiceStatusApi.Update)        // 鏇存柊鍙戠エ鐘舵��
+		InvoiceStatusRouter.GET("list", InvoiceStatusApi.List)            // 鑾峰彇鍙戠エ鐘舵�佸垪琛�
+	}
+}
diff --git a/router/invoiceType.go b/router/invoiceType.go
new file mode 100644
index 0000000..387b10b
--- /dev/null
+++ b/router/invoiceType.go
@@ -0,0 +1,17 @@
+package router
+
+import (
+	v1 "aps_crm/api/v1"
+	"github.com/gin-gonic/gin"
+)
+
+func InitInvoiceTypeRouter(router *gin.RouterGroup) {
+	InvoiceTypeRouter := router.Group("invoiceType")
+	InvoiceTypeApi := v1.InvoiceTypeApi{}
+	{
+		InvoiceTypeRouter.POST("add", InvoiceTypeApi.Add)             // 娣诲姞鍙戠エ绫诲瀷
+		InvoiceTypeRouter.DELETE("delete/:id", InvoiceTypeApi.Delete) // 鍒犻櫎鍙戠エ绫诲瀷
+		InvoiceTypeRouter.PUT("update", InvoiceTypeApi.Update)        // 鏇存柊鍙戠エ绫诲瀷
+		InvoiceTypeRouter.GET("list", InvoiceTypeApi.List)            // 鑾峰彇鍙戠エ绫诲瀷鍒楄〃
+	}
+}
diff --git a/service/courierCompany.go b/service/courierCompany.go
new file mode 100644
index 0000000..01b1e2d
--- /dev/null
+++ b/service/courierCompany.go
@@ -0,0 +1,66 @@
+package service
+
+import (
+	"aps_crm/model"
+	"aps_crm/model/request"
+	"aps_crm/pkg/ecode"
+)
+
+type CourierCompanyService struct{}
+
+func NewCourierCompanyService() CourierCompanyService {
+	return CourierCompanyService{}
+}
+
+func (CourierCompanyService) AddCourierCompany(courierCompany *model.CourierCompany) int {
+	err := model.NewCourierCompanySearch().Create(courierCompany)
+	if err != nil {
+		return ecode.DBErr
+	}
+
+	return ecode.OK
+}
+
+func (CourierCompanyService) DeleteCourierCompany(id int) int {
+	err := model.NewCourierCompanySearch().SetId(id).Delete()
+	if err != nil {
+		return ecode.DBErr
+	}
+	return ecode.OK
+}
+
+func (CourierCompanyService) GetCourierCompanyList() ([]*model.CourierCompany, int64, int) {
+	list, total, err := model.NewCourierCompanySearch().Find()
+	if err != nil {
+		return nil, 0, ecode.DBErr
+	}
+
+	return list, total, ecode.OK
+}
+
+func (CourierCompanyService) UpdateCourierCompanys(CourierCompanys []*request.UpdateCourierCompany) int {
+	for _, v := range CourierCompanys {
+		// check CourierCompany exist
+		_, err := model.NewCourierCompanySearch().SetId(v.Id).First()
+		if err != nil {
+			return ecode.DBErr
+		}
+
+		err = model.NewCourierCompanySearch().SetId(v.Id).Updates(map[string]interface{}{
+
+		})
+		if err != nil {
+			return ecode.DBErr
+		}
+	}
+
+	return ecode.OK
+}
+
+func (CourierCompanyService) UpdateCourierCompany(courierCompany *model.CourierCompany) int {
+		err := model.NewCourierCompanySearch().SetId(courierCompany.Id).Save(courierCompany)
+		if err != nil {
+			return ecode.DBErr
+		}
+	return ecode.OK
+}
diff --git a/service/file.go b/service/file.go
index af78875..584aa11 100644
--- a/service/file.go
+++ b/service/file.go
@@ -22,7 +22,7 @@
 	return ecode.OK
 }
 
-func (FileService) DeleteFile(id int) int {
+func (FileService) DeleteFile(id uint) int {
 	err := model.NewFileSearch().SetId(id).Delete()
 	if err != nil {
 		return ecode.DBErr
@@ -57,7 +57,7 @@
 }
 
 func (FileService) UpdateFile(file *model.File) int {
-	err := model.NewFileSearch().SetId(file.Id).Save(file)
+	err := model.NewFileSearch().SetId(file.ID).Save(file)
 	if err != nil {
 		return ecode.DBErr
 	}
diff --git a/service/invoice.go b/service/invoice.go
new file mode 100644
index 0000000..9bd1b91
--- /dev/null
+++ b/service/invoice.go
@@ -0,0 +1,87 @@
+package service
+
+import (
+	"aps_crm/model"
+	"aps_crm/model/request"
+	"aps_crm/pkg/ecode"
+	"gorm.io/gorm"
+)
+
+type InvoiceService struct{}
+
+func NewInvoiceService() InvoiceService {
+	return InvoiceService{}
+}
+
+func (InvoiceService) AddInvoice(invoice *model.Invoice) int {
+
+	err := model.WithTransaction(func(db *gorm.DB) error {
+		err := model.NewInvoiceSearch().Create(invoice)
+		if err != nil {
+			return err
+		}
+		//if invoice.SourceType == constvar.InvoiceSourceTypeServiceContract {
+		//	contract,err := model.NewServiceContractSearch().SetId(invoice.SourceId).First()
+		//	if err != nil {
+		//		return err
+		//	}
+		//	AmountInvoiced := contract.AmountReceived.Add()
+		//	err := model.NewServiceContractSearch().SetId(invoice.SourceId).UpdateByMap(map[string]interface{}{
+		//		"amount_received" :
+		//	})
+		//	if err != nil {
+		//		return err
+		//	}
+		//}
+
+		return nil
+	})
+
+	if err != nil {
+		return ecode.DBErr
+	}
+
+	return ecode.OK
+}
+
+func (InvoiceService) DeleteInvoice(id int) int {
+	err := model.NewInvoiceSearch().SetId(id).Delete()
+	if err != nil {
+		return ecode.DBErr
+	}
+	return ecode.OK
+}
+
+func (InvoiceService) GetInvoiceList() ([]*model.Invoice, int64, int) {
+	list, total, err := model.NewInvoiceSearch().Find()
+	if err != nil {
+		return nil, 0, ecode.DBErr
+	}
+
+	return list, total, ecode.OK
+}
+
+func (InvoiceService) UpdateInvoices(Invoices []*request.UpdateInvoice) int {
+	for _, v := range Invoices {
+		// check Invoice exist
+		_, err := model.NewInvoiceSearch().SetId(v.Id).First()
+		if err != nil {
+			return ecode.DBErr
+		}
+
+		err = model.NewInvoiceSearch().SetId(v.Id).Updates(map[string]interface{}{})
+		if err != nil {
+			return ecode.DBErr
+		}
+	}
+
+	return ecode.OK
+}
+
+func (InvoiceService) UpdateInvoice(invoice *model.Invoice) int {
+	err := model.NewInvoiceSearch().SetId(invoice.Id).Save(invoice)
+	if err != nil {
+		return ecode.DBErr
+	}
+	return ecode.OK
+}
diff --git a/service/invoiceStatus.go b/service/invoiceStatus.go
new file mode 100644
index 0000000..4b42bf8
--- /dev/null
+++ b/service/invoiceStatus.go
@@ -0,0 +1,66 @@
+package service
+
+import (
+	"aps_crm/model"
+	"aps_crm/model/request"
+	"aps_crm/pkg/ecode"
+)
+
+type InvoiceStatusService struct{}
+
+func NewInvoiceStatusService() InvoiceStatusService {
+	return InvoiceStatusService{}
+}
+
+func (InvoiceStatusService) AddInvoiceStatus(invoiceStatus *model.InvoiceStatus) int {
+	err := model.NewInvoiceStatusSearch().Create(invoiceStatus)
+	if err != nil {
+		return ecode.DBErr
+	}
+
+	return ecode.OK
+}
+
+func (InvoiceStatusService) DeleteInvoiceStatus(id int) int {
+	err := model.NewInvoiceStatusSearch().SetId(id).Delete()
+	if err != nil {
+		return ecode.DBErr
+	}
+	return ecode.OK
+}
+
+func (InvoiceStatusService) GetInvoiceStatusList() ([]*model.InvoiceStatus, int64, int) {
+	list, total, err := model.NewInvoiceStatusSearch().Find()
+	if err != nil {
+		return nil, 0, ecode.DBErr
+	}
+
+	return list, total, ecode.OK
+}
+
+func (InvoiceStatusService) UpdateInvoiceStatuss(InvoiceStatuss []*request.UpdateInvoiceStatus) int {
+	for _, v := range InvoiceStatuss {
+		// check InvoiceStatus exist
+		_, err := model.NewInvoiceStatusSearch().SetId(v.Id).First()
+		if err != nil {
+			return ecode.DBErr
+		}
+
+		err = model.NewInvoiceStatusSearch().SetId(v.Id).Updates(map[string]interface{}{
+
+		})
+		if err != nil {
+			return ecode.DBErr
+		}
+	}
+
+	return ecode.OK
+}
+
+func (InvoiceStatusService) UpdateInvoiceStatus(invoiceStatus *model.InvoiceStatus) int {
+		err := model.NewInvoiceStatusSearch().SetId(invoiceStatus.Id).Save(invoiceStatus)
+		if err != nil {
+			return ecode.DBErr
+		}
+	return ecode.OK
+}
diff --git a/service/invoiceType.go b/service/invoiceType.go
new file mode 100644
index 0000000..1c43d92
--- /dev/null
+++ b/service/invoiceType.go
@@ -0,0 +1,66 @@
+package service
+
+import (
+	"aps_crm/model"
+	"aps_crm/model/request"
+	"aps_crm/pkg/ecode"
+)
+
+type InvoiceTypeService struct{}
+
+func NewInvoiceTypeService() InvoiceTypeService {
+	return InvoiceTypeService{}
+}
+
+func (InvoiceTypeService) AddInvoiceType(invoiceType *model.InvoiceType) int {
+	err := model.NewInvoiceTypeSearch().Create(invoiceType)
+	if err != nil {
+		return ecode.DBErr
+	}
+
+	return ecode.OK
+}
+
+func (InvoiceTypeService) DeleteInvoiceType(id int) int {
+	err := model.NewInvoiceTypeSearch().SetId(id).Delete()
+	if err != nil {
+		return ecode.DBErr
+	}
+	return ecode.OK
+}
+
+func (InvoiceTypeService) GetInvoiceTypeList() ([]*model.InvoiceType, int64, int) {
+	list, total, err := model.NewInvoiceTypeSearch().Find()
+	if err != nil {
+		return nil, 0, ecode.DBErr
+	}
+
+	return list, total, ecode.OK
+}
+
+func (InvoiceTypeService) UpdateInvoiceTypes(InvoiceTypes []*request.UpdateInvoiceType) int {
+	for _, v := range InvoiceTypes {
+		// check InvoiceType exist
+		_, err := model.NewInvoiceTypeSearch().SetId(v.Id).First()
+		if err != nil {
+			return ecode.DBErr
+		}
+
+		err = model.NewInvoiceTypeSearch().SetId(v.Id).Updates(map[string]interface{}{
+
+		})
+		if err != nil {
+			return ecode.DBErr
+		}
+	}
+
+	return ecode.OK
+}
+
+func (InvoiceTypeService) UpdateInvoiceType(invoiceType *model.InvoiceType) int {
+		err := model.NewInvoiceTypeSearch().SetId(invoiceType.Id).Save(invoiceType)
+		if err != nil {
+			return ecode.DBErr
+		}
+	return ecode.OK
+}
diff --git a/service/serviceCollectionPlan.go b/service/serviceCollectionPlan.go
index fdaa235..f87f5a4 100644
--- a/service/serviceCollectionPlan.go
+++ b/service/serviceCollectionPlan.go
@@ -17,9 +17,9 @@
 	if len(serviceCollectionPlan) == 0 {
 		return ecode.ParamsErr
 	}
-	contractId := serviceCollectionPlan[0].ServiceContractId
+	sourceId := serviceCollectionPlan[0].SourceId
 	err := model.WithTransaction(func(db *gorm.DB) error {
-		err := model.NewServiceCollectionPlanSearch().SetOrm(db).SetServiceContractId(contractId).Delete()
+		err := model.NewServiceCollectionPlanSearch().SetOrm(db).SetSourceId(sourceId).Delete()
 		if err != nil {
 			return err
 		}
@@ -45,8 +45,8 @@
 	return ecode.OK
 }
 
-func (ServiceCollectionPlanService) GetServiceCollectionPlanList(contractId int) ([]*model.ServiceCollectionPlan, int64, int) {
-	list, total, err := model.NewServiceCollectionPlanSearch().SetServiceContractId(contractId).Find()
+func (ServiceCollectionPlanService) GetServiceCollectionPlanList(sourceId int) ([]*model.ServiceCollectionPlan, int64, int) {
+	list, total, err := model.NewServiceCollectionPlanSearch().SetSourceId(sourceId).Find()
 	if err != nil {
 		return nil, 0, ecode.DBErr
 	}
diff --git a/utils/upload/upload.go b/utils/upload/upload.go
new file mode 100644
index 0000000..a6823ac
--- /dev/null
+++ b/utils/upload/upload.go
@@ -0,0 +1,35 @@
+package upload
+
+import (
+	"mime/multipart"
+)
+
+// OSS 瀵硅薄瀛樺偍鎺ュ彛
+// Author [SliverHorn](https://github.com/SliverHorn)
+// Author [ccfish86](https://github.com/ccfish86)
+type OSS interface {
+	UploadFile(file *multipart.FileHeader) (string, string, error)
+	DeleteFile(key string) error
+}
+
+type ossType string
+
+const (
+	ossTypeLocal   ossType = "local"
+	currentOssType         = ossTypeLocal
+)
+
+// NewOss OSS鐨勫疄渚嬪寲鏂规硶
+// Author [SliverHorn](https://github.com/SliverHorn)
+// Author [ccfish86](https://github.com/ccfish86)
+func NewOss() OSS {
+	switch currentOssType {
+	case ossTypeLocal:
+		return &Local{
+			StorePath: "/data/uploads/file",
+			Path:      "/data/uploads/file",
+		}
+	default:
+		return &Local{}
+	}
+}

--
Gitblit v1.8.0