From 9c2489c0c360c8dda36d3cbe1dba79222096b2dd Mon Sep 17 00:00:00 2001
From: wangpengfei <274878379@qq.com>
Date: 星期一, 07 八月 2023 10:16:39 +0800
Subject: [PATCH] Merge branch 'master' into fly

---
 model/severity.go                      |  135 +
 router/serviceType.go                  |   17 
 constvar/timeSpent.go                  |   12 
 model/request/file.go                  |   23 
 service/faultType.go                   |   66 
 service/priorityLevel.go               |   66 
 model/request/serviceCollectionPlan.go |   18 
 pkg/contextx/contextx.go               |    4 
 router/priorityLevel.go                |   17 
 model/request/serviceOrder.go          |   46 
 model/serviceType.go                   |  135 +
 api/v1/timeSpent.go                    |  110 +
 api/v1/file.go                         |  157 +
 model/serviceFeeManage.go              |   81 
 api/v1/serviceType.go                  |  110 +
 router/faq.go                          |   17 
 model/response/common.go               |    7 
 router/serviceCollectionPlan.go        |   17 
 service/file.go                        |   65 
 model/timeSpent.go                     |  135 +
 router/severity.go                     |   17 
 constvar/file.go                       |   12 
 router/faultType.go                    |   17 
 model/request/priorityLevel.go         |   22 
 model/request/faultType.go             |   22 
 service/serviceFollowup.go             |  104 
 api/v1/paymentType.go                  |  112 +
 model/receipt.go                       |  149 +
 constvar/const.go                      |   60 
 constvar/paymentType.go                |   12 
 model/serviceOrder.go                  |  171 +
 model/paymentType.go                   |  140 +
 api/v1/faq.go                          |  112 +
 api/v1/serviceCollectionPlan.go        |  112 +
 model/index.go                         |   54 
 service/timeSpent.go                   |   66 
 constvar/bankAccount.go                |   12 
 model/faq.go                           |  135 +
 api/v1/serviceFollowup.go              |    3 
 model/request/serviceType.go           |   22 
 model/request/paymentType.go           |   22 
 router/bankAccount.go                  |   17 
 .gitignore                             |    3 
 api/v1/serviceFeeManage.go             |    5 
 service/serviceOrder.go                |   64 
 model/request/serviceFeeManage.go      |    6 
 service/serviceType.go                 |   66 
 model/bankAccount.go                   |  140 +
 constvar/serviceCollectionPlan.go      |   12 
 api/v1/receipt.go                      |  112 +
 service/serviceFeeManage.go            |  157 
 model/serviceFollowup.go               |   41 
 api/v1/bankAccount.go                  |  112 +
 constvar/receipt.go                    |   12 
 .idea/modules.xml                      |    2 
 model/request/serviceFollowup.go       |    5 
 pkg/safe/safe.go                       |    2 
 model/request/severity.go              |   22 
 constvar/severity.go                   |   12 
 constvar/priorityLevel.go              |   12 
 constvar/faq.go                        |   12 
 pkg/structx/structx.go                 |   16 
 constvar/faultType.go                  |   12 
 router/serviceOrder.go                 |   17 
 pkg/httpx/httpx.go                     |   14 
 api/v1/serviceOrder.go                 |  120 +
 model/file.go                          |  152 +
 model/priorityLevel.go                 |  135 +
 router/file.go                         |   15 
 router/paymentType.go                  |   17 
 model/serviceCollectionPlan.go         |  159 +
 service/severity.go                    |   66 
 model/serviceContract.go               |   64 
 /dev/null                              |    4 
 api/v1/saleChance.go                   |    5 
 api/v1/priorityLevel.go                |  110 +
 model/request/receipt.go               |   22 
 router/timeSpent.go                    |   17 
 api/v1/serviceContract.go              |   14 
 model/faultType.go                     |  135 +
 model/request/serviceContract.go       |    5 
 service/bankAccount.go                 |   66 
 service/serviceCollectionPlan.go       |   80 
 constvar/serviceOrder.go               |   12 
 model/request/timeSpent.go             |   22 
 model/request/faq.go                   |   22 
 api/v1/faultType.go                    |  110 +
 router/index.go                        |  338 +-
 constvar/serviceType.go                |   12 
 router/receipt.go                      |   17 
 api/v1/severity.go                     |  110 +
 service/serviceContract.go             |  123 
 model/request/bankAccount.go           |   22 
 service/receipt.go                     |   66 
 service/faq.go                         |   66 
 service/paymentType.go                 |   66 
 96 files changed, 5,232 insertions(+), 427 deletions(-)

diff --git a/.gitignore b/.gitignore
index 8b4ba67..aca55e5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -18,4 +18,5 @@
 *.test
 /logs/aps-admin.info.log
 /logs/aps-admin.err.log
-/apsCrm
\ No newline at end of file
+/apsCrm
+.idea/*
\ No newline at end of file
diff --git a/.idea/.gitignore b/.idea/.gitignore
deleted file mode 100644
index 1c2fda5..0000000
--- a/.idea/.gitignore
+++ /dev/null
@@ -1,8 +0,0 @@
-# Default ignored files
-/shelf/
-/workspace.xml
-# Editor-based HTTP Client requests
-/httpRequests/
-# Datasource local storage ignored files
-/dataSources/
-/dataSources.local.xml
diff --git a/.idea/admin.iml b/.idea/admin.iml
deleted file mode 100644
index 62b2204..0000000
--- a/.idea/admin.iml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<module version="4">
-  <component name="Go" enabled="true" />
-</module>
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
index 00e73a1..f55d56a 100644
--- a/.idea/modules.xml
+++ b/.idea/modules.xml
@@ -2,7 +2,7 @@
 <project version="4">
   <component name="ProjectModuleManager">
     <modules>
-      <module fileurl="file://$PROJECT_DIR$/.idea/admin.iml" filepath="$PROJECT_DIR$/.idea/admin.iml" />
+      <module fileurl="file://$PROJECT_DIR$/.idea/crm.iml" filepath="$PROJECT_DIR$/.idea/crm.iml" />
     </modules>
   </component>
 </project>
\ No newline at end of file
diff --git a/api/v1/bankAccount.go b/api/v1/bankAccount.go
new file mode 100644
index 0000000..bf81a94
--- /dev/null
+++ b/api/v1/bankAccount.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 BankAccountApi struct{}
+
+// Add
+// @Tags		閾惰璐︽埛绠$悊
+// @Summary	娣诲姞閾惰璐︽埛
+// @Produce	application/json
+// @Param		object	body		request.AddBankAccount	true	"鏌ヨ鍙傛暟"
+// @Success	200		{object}	contextx.Response{}
+// @Router		/api/bankAccount/add [post]
+func (s *BankAccountApi) Add(c *gin.Context) {
+	var params request.AddBankAccount
+	ctx, ok := contextx.NewContext(c, &params)
+	if !ok {
+		return
+	}
+
+	errCode := service.NewBankAccountService().AddBankAccount(&params.BankAccount)
+	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/bankAccount/delete/{id} [delete]
+func (s *BankAccountApi) Delete(c *gin.Context) {
+	ctx, ok := contextx.NewContext(c, nil)
+	if !ok {
+		return
+	}
+
+	id, _ := strconv.Atoi(c.Param("id"))
+	errCode := service.NewBankAccountService().DeleteBankAccount(id)
+	if errCode != ecode.OK {
+		ctx.Fail(errCode)
+		return
+	}
+
+	ctx.Ok()
+}
+
+// Update
+// @Tags		閾惰璐︽埛绠$悊
+// @Summary	鏇存柊閾惰璐︽埛
+// @Produce	application/json
+// @Param		object	body		request.UpdateBankAccount	true	"鏌ヨ鍙傛暟"
+// @Success	200		{object}	contextx.Response{}
+// @Router		/api/bankAccount/update [put]
+func (s *BankAccountApi) Update(c *gin.Context) {
+	var params request.UpdateBankAccount
+	ctx, ok := contextx.NewContext(c, &params)
+	if !ok {
+		return
+	}
+    if params.Id == 0 {
+        ctx.Fail(ecode.ParamsErr)
+    }
+    params.BankAccount.Id = params.Id
+
+	errCode := service.NewBankAccountService().UpdateBankAccount(&params.BankAccount)
+	if errCode != ecode.OK {
+		ctx.Fail(errCode)
+		return
+	}
+
+	ctx.Ok()
+}
+
+// List
+// @Tags		閾惰璐︽埛绠$悊
+// @Summary	鑾峰彇閾惰璐︽埛鍒楄〃
+// @Produce	application/json
+// @Param		object	query		request.GetBankAccountList	true	"鍙傛暟"
+// @Success	200	{object}	response.ListResponse{data=[]model.BankAccount}
+// @Router		/api/bankAccount/list [get]
+func (s *BankAccountApi) List(c *gin.Context) {
+	var params request.GetBankAccountList
+	ctx, ok := contextx.NewContext(c, &params)
+	if !ok {
+		return
+	}
+
+	bankAccount, total, errCode := service.NewBankAccountService().GetBankAccountList()
+	if errCode != ecode.OK {
+		ctx.Fail(errCode)
+		return
+	}
+
+	ctx.OkWithDetailed(response.ListResponse{
+		Data: bankAccount,
+		Count: total,
+	})
+}
diff --git a/api/v1/faq.go b/api/v1/faq.go
new file mode 100644
index 0000000..350dae2
--- /dev/null
+++ b/api/v1/faq.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 FaqApi struct{}
+
+// Add
+// @Tags		甯歌闂绠$悊
+// @Summary	娣诲姞甯歌闂
+// @Produce	application/json
+// @Param		object	body		request.AddFaq	true	"鏌ヨ鍙傛暟"
+// @Success	200		{object}	contextx.Response{}
+// @Router		/api/faq/add [post]
+func (s *FaqApi) Add(c *gin.Context) {
+	var params request.AddFaq
+	ctx, ok := contextx.NewContext(c, &params)
+	if !ok {
+		return
+	}
+
+	errCode := service.NewFaqService().AddFaq(&params.Faq)
+	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/faq/delete/{id} [delete]
+func (s *FaqApi) Delete(c *gin.Context) {
+	ctx, ok := contextx.NewContext(c, nil)
+	if !ok {
+		return
+	}
+
+	id, _ := strconv.Atoi(c.Param("id"))
+	errCode := service.NewFaqService().DeleteFaq(id)
+	if errCode != ecode.OK {
+		ctx.Fail(errCode)
+		return
+	}
+
+	ctx.Ok()
+}
+
+// Update
+// @Tags		甯歌闂绠$悊
+// @Summary	鏇存柊甯歌闂
+// @Produce	application/json
+// @Param		object	body		request.UpdateFaq	true	"鏌ヨ鍙傛暟"
+// @Success	200		{object}	contextx.Response{}
+// @Router		/api/faq/update [put]
+func (s *FaqApi) Update(c *gin.Context) {
+	var params request.UpdateFaq
+	ctx, ok := contextx.NewContext(c, &params)
+	if !ok {
+		return
+	}
+    if params.Id == 0 {
+        ctx.Fail(ecode.ParamsErr)
+    }
+    params.Faq.Id = params.Id
+
+	errCode := service.NewFaqService().UpdateFaq(&params.Faq)
+	if errCode != ecode.OK {
+		ctx.Fail(errCode)
+		return
+	}
+
+	ctx.Ok()
+}
+
+// List
+// @Tags		甯歌闂绠$悊
+// @Summary	鑾峰彇甯歌闂鍒楄〃
+// @Produce	application/json
+// @Param		object	body		request.GetFaqList	true	"鍙傛暟"
+// @Success	200	{object}	response.ListResponse{data=[]model.Faq}
+// @Router		/api/faq/list [get]
+func (s *FaqApi) List(c *gin.Context) {
+	var params request.GetFaqList
+	ctx, ok := contextx.NewContext(c, params)
+	if !ok {
+		return
+	}
+
+	faq, total, errCode := service.NewFaqService().GetFaqList()
+	if errCode != ecode.OK {
+		ctx.Fail(errCode)
+		return
+	}
+
+	ctx.OkWithDetailed(response.ListResponse{
+		Data: faq,
+		Count: total,
+	})
+}
diff --git a/api/v1/faultType.go b/api/v1/faultType.go
new file mode 100644
index 0000000..233652f
--- /dev/null
+++ b/api/v1/faultType.go
@@ -0,0 +1,110 @@
+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 FaultTypeApi struct{}
+
+// Add
+// @Tags		鏁呴殰绫诲埆绠$悊
+// @Summary	娣诲姞鏁呴殰绫诲埆
+// @Produce	application/json
+// @Param		object	body		request.AddFaultType	true	"鏌ヨ鍙傛暟"
+// @Success	200		{object}	contextx.Response{}
+// @Router		/api/faultType/add [post]
+func (s *FaultTypeApi) Add(c *gin.Context) {
+	var params request.AddFaultType
+	ctx, ok := contextx.NewContext(c, &params)
+	if !ok {
+		return
+	}
+
+	errCode := service.NewFaultTypeService().AddFaultType(&params.FaultType)
+	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/faultType/delete/{id} [delete]
+func (s *FaultTypeApi) Delete(c *gin.Context) {
+	ctx, ok := contextx.NewContext(c, nil)
+	if !ok {
+		return
+	}
+
+	id, _ := strconv.Atoi(c.Param("id"))
+	errCode := service.NewFaultTypeService().DeleteFaultType(id)
+	if errCode != ecode.OK {
+		ctx.Fail(errCode)
+		return
+	}
+
+	ctx.Ok()
+}
+
+// Update
+// @Tags		鏁呴殰绫诲埆绠$悊
+// @Summary	鏇存柊鏁呴殰绫诲埆
+// @Produce	application/json
+// @Param		object	body		request.UpdateFaultType	true	"鏌ヨ鍙傛暟"
+// @Success	200		{object}	contextx.Response{}
+// @Router		/api/faultType/update [put]
+func (s *FaultTypeApi) Update(c *gin.Context) {
+	var params request.UpdateFaultType
+	ctx, ok := contextx.NewContext(c, &params)
+	if !ok {
+		return
+	}
+    if params.Id == 0 {
+        ctx.Fail(ecode.ParamsErr)
+    }
+    params.FaultType.Id = params.Id
+
+	errCode := service.NewFaultTypeService().UpdateFaultType(&params.FaultType)
+	if errCode != ecode.OK {
+		ctx.Fail(errCode)
+		return
+	}
+
+	ctx.Ok()
+}
+
+// List
+// @Tags		鏁呴殰绫诲埆绠$悊
+// @Summary	鑾峰彇鏁呴殰绫诲埆鍒楄〃
+// @Produce	application/json
+// @Success	200	{object}	response.ListResponse{data=[]model.FaultType}
+// @Router		/api/faultType/list [get]
+func (s *FaultTypeApi) List(c *gin.Context) {
+	ctx, ok := contextx.NewContext(c, nil)
+	if !ok {
+		return
+	}
+
+	faultType, total, errCode := service.NewFaultTypeService().GetFaultTypeList()
+	if errCode != ecode.OK {
+		ctx.Fail(errCode)
+		return
+	}
+
+	ctx.OkWithDetailed(response.ListResponse{
+		Data: faultType,
+		Count: total,
+	})
+}
diff --git a/api/v1/file.go b/api/v1/file.go
new file mode 100644
index 0000000..1edb6b9
--- /dev/null
+++ b/api/v1/file.go
@@ -0,0 +1,157 @@
+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/httpx"
+	"aps_crm/service"
+	"github.com/flipped-aurora/gin-vue-admin/server/utils/upload"
+	"github.com/gin-gonic/gin"
+	"os"
+	"path/filepath"
+	"strconv"
+)
+
+type FileApi struct{}
+
+// Add
+// @Tags		闄勪欢绠$悊
+// @Summary	娣诲姞闄勪欢
+// @Produce	application/json
+// @Param		object	body		request.AddFile	true	"鏌ヨ鍙傛暟"
+// @Success	200		{object}	contextx.Response{}
+// @Router		/api/file/add [post]
+func (s *FileApi) Add(c *gin.Context) {
+	var params request.AddFile
+	ctx, ok := contextx.NewContext(c, &params)
+	if !ok {
+		return
+	}
+
+	_, header, err := c.Request.FormFile("file")
+	if err != nil {
+		ctx.Fail(ecode.ParamsErr)
+		return
+	}
+
+	oss := upload.NewOss()
+	filePath, key, uploadErr := oss.UploadFile(header)
+	if uploadErr != nil {
+		ctx.Fail(ecode.ParamsErr)
+		return
+	}
+
+	_, filename := filepath.Split(filePath)
+
+	fileRecord := &model.File{
+		Name:          filename,
+		Size:          header.Size,
+		FilePath:      filePath,
+		Key:           key,
+		DownloadCount: 0,
+		PreviewCount:  0,
+		FileType:      httpx.GetMimeType(filePath),
+		SourceType:    params.SourceType,
+		SourceId:      params.SourceId,
+	}
+
+	errCode := service.NewFileService().AddFile(fileRecord)
+	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/file/delete/{id} [delete]
+func (s *FileApi) Delete(c *gin.Context) {
+	ctx, ok := contextx.NewContext(c, nil)
+	if !ok {
+		return
+	}
+
+	id, _ := strconv.Atoi(c.Param("id"))
+
+	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
+	}
+
+	errCode := service.NewFileService().DeleteFile(id)
+	if errCode != ecode.OK {
+		ctx.Fail(errCode)
+		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	鑾峰彇闄勪欢鍒楄〃
+// @Produce	application/json
+// @Param		object	query		request.GetFileList	true	"鍙傛暟"
+// @Success	200	{object}	response.ListResponse{data=[]model.File}
+// @Router		/api/file/list [get]
+func (s *FileApi) List(c *gin.Context) {
+	var params request.GetFileList
+	ctx, ok := contextx.NewContext(c, &params)
+	if !ok {
+		return
+	}
+
+	file, total, errCode := service.NewFileService().GetFileList()
+	if errCode != ecode.OK {
+		ctx.Fail(errCode)
+		return
+	}
+
+	ctx.OkWithDetailed(response.ListResponse{
+		Data:  file,
+		Count: total,
+	})
+}
diff --git a/api/v1/paymentType.go b/api/v1/paymentType.go
new file mode 100644
index 0000000..28d0dc1
--- /dev/null
+++ b/api/v1/paymentType.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 PaymentTypeApi struct{}
+
+// Add
+// @Tags		鏀粯鏂瑰紡绠$悊
+// @Summary	娣诲姞鏀粯鏂瑰紡
+// @Produce	application/json
+// @Param		object	body		request.AddPaymentType	true	"鏌ヨ鍙傛暟"
+// @Success	200		{object}	contextx.Response{}
+// @Router		/api/paymentType/add [post]
+func (s *PaymentTypeApi) Add(c *gin.Context) {
+	var params request.AddPaymentType
+	ctx, ok := contextx.NewContext(c, &params)
+	if !ok {
+		return
+	}
+
+	errCode := service.NewPaymentTypeService().AddPaymentType(&params.PaymentType)
+	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/paymentType/delete/{id} [delete]
+func (s *PaymentTypeApi) Delete(c *gin.Context) {
+	ctx, ok := contextx.NewContext(c, nil)
+	if !ok {
+		return
+	}
+
+	id, _ := strconv.Atoi(c.Param("id"))
+	errCode := service.NewPaymentTypeService().DeletePaymentType(id)
+	if errCode != ecode.OK {
+		ctx.Fail(errCode)
+		return
+	}
+
+	ctx.Ok()
+}
+
+// Update
+// @Tags		鏀粯鏂瑰紡绠$悊
+// @Summary	鏇存柊鏀粯鏂瑰紡
+// @Produce	application/json
+// @Param		object	body		request.UpdatePaymentType	true	"鏌ヨ鍙傛暟"
+// @Success	200		{object}	contextx.Response{}
+// @Router		/api/paymentType/update [put]
+func (s *PaymentTypeApi) Update(c *gin.Context) {
+	var params request.UpdatePaymentType
+	ctx, ok := contextx.NewContext(c, &params)
+	if !ok {
+		return
+	}
+    if params.Id == 0 {
+        ctx.Fail(ecode.ParamsErr)
+    }
+    params.PaymentType.Id = params.Id
+
+	errCode := service.NewPaymentTypeService().UpdatePaymentType(&params.PaymentType)
+	if errCode != ecode.OK {
+		ctx.Fail(errCode)
+		return
+	}
+
+	ctx.Ok()
+}
+
+// List
+// @Tags		鏀粯鏂瑰紡绠$悊
+// @Summary	鑾峰彇鏀粯鏂瑰紡鍒楄〃
+// @Produce	application/json
+// @Param		object	query		request.GetPaymentTypeList	true	"鍙傛暟"
+// @Success	200	{object}	response.ListResponse{data=[]model.PaymentType}
+// @Router		/api/paymentType/list [get]
+func (s *PaymentTypeApi) List(c *gin.Context) {
+	var params request.GetPaymentTypeList
+	ctx, ok := contextx.NewContext(c, &params)
+	if !ok {
+		return
+	}
+
+	paymentType, total, errCode := service.NewPaymentTypeService().GetPaymentTypeList()
+	if errCode != ecode.OK {
+		ctx.Fail(errCode)
+		return
+	}
+
+	ctx.OkWithDetailed(response.ListResponse{
+		Data: paymentType,
+		Count: total,
+	})
+}
diff --git a/api/v1/priorityLevel.go b/api/v1/priorityLevel.go
new file mode 100644
index 0000000..8017e32
--- /dev/null
+++ b/api/v1/priorityLevel.go
@@ -0,0 +1,110 @@
+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 PriorityLevelApi struct{}
+
+// Add
+// @Tags		浼樺厛绾у埆绠$悊
+// @Summary	娣诲姞浼樺厛绾у埆
+// @Produce	application/json
+// @Param		object	body		request.AddPriorityLevel	true	"鏌ヨ鍙傛暟"
+// @Success	200		{object}	contextx.Response{}
+// @Router		/api/priorityLevel/add [post]
+func (s *PriorityLevelApi) Add(c *gin.Context) {
+	var params request.AddPriorityLevel
+	ctx, ok := contextx.NewContext(c, &params)
+	if !ok {
+		return
+	}
+
+	errCode := service.NewPriorityLevelService().AddPriorityLevel(&params.PriorityLevel)
+	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/priorityLevel/delete/{id} [delete]
+func (s *PriorityLevelApi) Delete(c *gin.Context) {
+	ctx, ok := contextx.NewContext(c, nil)
+	if !ok {
+		return
+	}
+
+	id, _ := strconv.Atoi(c.Param("id"))
+	errCode := service.NewPriorityLevelService().DeletePriorityLevel(id)
+	if errCode != ecode.OK {
+		ctx.Fail(errCode)
+		return
+	}
+
+	ctx.Ok()
+}
+
+// Update
+// @Tags		浼樺厛绾у埆绠$悊
+// @Summary	鏇存柊浼樺厛绾у埆
+// @Produce	application/json
+// @Param		object	body		request.UpdatePriorityLevel	true	"鏌ヨ鍙傛暟"
+// @Success	200		{object}	contextx.Response{}
+// @Router		/api/priorityLevel/update [put]
+func (s *PriorityLevelApi) Update(c *gin.Context) {
+	var params request.UpdatePriorityLevel
+	ctx, ok := contextx.NewContext(c, &params)
+	if !ok {
+		return
+	}
+    if params.Id == 0 {
+        ctx.Fail(ecode.ParamsErr)
+    }
+    params.PriorityLevel.Id = params.Id
+
+	errCode := service.NewPriorityLevelService().UpdatePriorityLevel(&params.PriorityLevel)
+	if errCode != ecode.OK {
+		ctx.Fail(errCode)
+		return
+	}
+
+	ctx.Ok()
+}
+
+// List
+// @Tags		浼樺厛绾у埆绠$悊
+// @Summary	鑾峰彇浼樺厛绾у埆鍒楄〃
+// @Produce	application/json
+// @Success	200	{object}	response.ListResponse{data=[]model.PriorityLevel}
+// @Router		/api/priorityLevel/list [get]
+func (s *PriorityLevelApi) List(c *gin.Context) {
+	ctx, ok := contextx.NewContext(c, nil)
+	if !ok {
+		return
+	}
+
+	priorityLevel, total, errCode := service.NewPriorityLevelService().GetPriorityLevelList()
+	if errCode != ecode.OK {
+		ctx.Fail(errCode)
+		return
+	}
+
+	ctx.OkWithDetailed(response.ListResponse{
+		Data: priorityLevel,
+		Count: total,
+	})
+}
diff --git a/api/v1/receipt.go b/api/v1/receipt.go
new file mode 100644
index 0000000..e507d08
--- /dev/null
+++ b/api/v1/receipt.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 ReceiptApi struct{}
+
+// Add
+// @Tags		鏀舵鍗曠鐞�
+// @Summary	娣诲姞鏀舵鍗�
+// @Produce	application/json
+// @Param		object	body		request.AddReceipt	true	"鏌ヨ鍙傛暟"
+// @Success	200		{object}	contextx.Response{}
+// @Router		/api/receipt/add [post]
+func (s *ReceiptApi) Add(c *gin.Context) {
+	var params request.AddReceipt
+	ctx, ok := contextx.NewContext(c, &params)
+	if !ok {
+		return
+	}
+
+	errCode := service.NewReceiptService().AddReceipt(&params.Receipt)
+	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/receipt/delete/{id} [delete]
+func (s *ReceiptApi) Delete(c *gin.Context) {
+	ctx, ok := contextx.NewContext(c, nil)
+	if !ok {
+		return
+	}
+
+	id, _ := strconv.Atoi(c.Param("id"))
+	errCode := service.NewReceiptService().DeleteReceipt(id)
+	if errCode != ecode.OK {
+		ctx.Fail(errCode)
+		return
+	}
+
+	ctx.Ok()
+}
+
+// Update
+// @Tags		鏀舵鍗曠鐞�
+// @Summary	鏇存柊鏀舵鍗�
+// @Produce	application/json
+// @Param		object	body		request.UpdateReceipt	true	"鏌ヨ鍙傛暟"
+// @Success	200		{object}	contextx.Response{}
+// @Router		/api/receipt/update [put]
+func (s *ReceiptApi) Update(c *gin.Context) {
+	var params request.UpdateReceipt
+	ctx, ok := contextx.NewContext(c, &params)
+	if !ok {
+		return
+	}
+    if params.Id == 0 {
+        ctx.Fail(ecode.ParamsErr)
+    }
+    params.Receipt.Id = params.Id
+
+	errCode := service.NewReceiptService().UpdateReceipt(&params.Receipt)
+	if errCode != ecode.OK {
+		ctx.Fail(errCode)
+		return
+	}
+
+	ctx.Ok()
+}
+
+// List
+// @Tags		鏀舵鍗曠鐞�
+// @Summary	鑾峰彇鏀舵鍗曞垪琛�
+// @Produce	application/json
+// @Param		object	query		request.GetReceiptList	true	"鍙傛暟"
+// @Success	200	{object}	response.ListResponse{data=[]model.Receipt}
+// @Router		/api/receipt/list [get]
+func (s *ReceiptApi) List(c *gin.Context) {
+	var params request.GetReceiptList
+	ctx, ok := contextx.NewContext(c, &params)
+	if !ok {
+		return
+	}
+
+	receipt, total, errCode := service.NewReceiptService().GetReceiptList()
+	if errCode != ecode.OK {
+		ctx.Fail(errCode)
+		return
+	}
+
+	ctx.OkWithDetailed(response.ListResponse{
+		Data: receipt,
+		Count: total,
+	})
+}
diff --git a/api/v1/saleChance.go b/api/v1/saleChance.go
index bce7c90..feb94a0 100644
--- a/api/v1/saleChance.go
+++ b/api/v1/saleChance.go
@@ -104,7 +104,6 @@
 	ctx.Ok()
 }
 
-
 // checkSaleChanceParams
 // 妫�鏌ラ攢鍞満浼氬弬鏁�
 func checkSaleChanceParams(saleChance request.SaleChance) (int, model.SaleChance) {
@@ -191,7 +190,7 @@
 //	@Summary	閿�鍞満浼氬垪琛�
 //	@Produce	application/json
 //	@Param		object	body		request.GetSaleChanceList	true	"鍙傛暟"
-//	@Success	200		{object}	contextx.Response{data=response.SaleChanceResponse}
+// @Success	200		{object}	contextx.Response{data=response.SaleChanceResponse}
 //	@Router		/api/saleChance/list [post]
 func (con *SaleChanceApi) List(c *gin.Context) {
 	var params request.GetSaleChanceList
@@ -207,7 +206,7 @@
 	}
 
 	ctx.OkWithDetailed(response.SaleChanceResponse{
-		List: saleChances,
+		List:  saleChances,
 		Count: int(total),
 	})
 }
\ No newline at end of file
diff --git a/api/v1/serviceCollectionPlan.go b/api/v1/serviceCollectionPlan.go
new file mode 100644
index 0000000..7476dd7
--- /dev/null
+++ b/api/v1/serviceCollectionPlan.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 ServiceCollectionPlanApi struct{}
+
+// Add
+// @Tags		鏈嶅姟鍚堝悓鏀舵璁″垝绠$悊
+// @Summary	娣诲姞鏈嶅姟鍚堝悓鏀舵璁″垝
+// @Produce	application/json
+// @Param		object	body		request.AddServiceCollectionPlan	true	"鏌ヨ鍙傛暟"
+// @Success	200		{object}	contextx.Response{}
+// @Router		/api/serviceCollectionPlan/add [post]
+func (s *ServiceCollectionPlanApi) Add(c *gin.Context) {
+	var params request.AddServiceCollectionPlan
+	ctx, ok := contextx.NewContext(c, &params)
+	if !ok {
+		return
+	}
+
+	errCode := service.NewServiceCollectionPlanService().AddServiceCollectionPlan(params.List)
+	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/serviceCollectionPlan/delete/{id} [delete]
+func (s *ServiceCollectionPlanApi) Delete(c *gin.Context) {
+	ctx, ok := contextx.NewContext(c, nil)
+	if !ok {
+		return
+	}
+
+	id, _ := strconv.Atoi(c.Param("id"))
+	errCode := service.NewServiceCollectionPlanService().DeleteServiceCollectionPlan(id)
+	if errCode != ecode.OK {
+		ctx.Fail(errCode)
+		return
+	}
+
+	ctx.Ok()
+}
+
+// Update
+// @Tags		鏈嶅姟鍚堝悓鏀舵璁″垝绠$悊
+// @Summary	鏇存柊鏈嶅姟鍚堝悓鏀舵璁″垝
+// @Produce	application/json
+// @Param		object	body		request.UpdateServiceCollectionPlan	true	"鏌ヨ鍙傛暟"
+// @Success	200		{object}	contextx.Response{}
+// @Router		/api/serviceCollectionPlan/update [put]
+func (s *ServiceCollectionPlanApi) Update(c *gin.Context) {
+	var params request.UpdateServiceCollectionPlan
+	ctx, ok := contextx.NewContext(c, &params)
+	if !ok {
+		return
+	}
+	if params.Id == 0 {
+		ctx.Fail(ecode.ParamsErr)
+	}
+	params.ServiceCollectionPlan.Id = params.Id
+
+	errCode := service.NewServiceCollectionPlanService().UpdateServiceCollectionPlan(&params.ServiceCollectionPlan)
+	if errCode != ecode.OK {
+		ctx.Fail(errCode)
+		return
+	}
+
+	ctx.Ok()
+}
+
+// List
+// @Tags		鏈嶅姟鍚堝悓鏀舵璁″垝绠$悊
+// @Summary	鑾峰彇鏈嶅姟鍚堝悓鏀舵璁″垝鍒楄〃
+// @Produce	application/json
+// @Param		object	query		request.GetServiceCollectionPlanList	true	"鍙傛暟"
+// @Success	200	{object}	response.ListResponse{data=[]model.ServiceCollectionPlan}
+// @Router		/api/serviceCollectionPlan/list [get]
+func (s *ServiceCollectionPlanApi) List(c *gin.Context) {
+	var params request.GetServiceCollectionPlanList
+	ctx, ok := contextx.NewContext(c, &params)
+	if !ok {
+		return
+	}
+
+	serviceCollectionPlan, total, errCode := service.NewServiceCollectionPlanService().GetServiceCollectionPlanList(params.ServiceContractId)
+	if errCode != ecode.OK {
+		ctx.Fail(errCode)
+		return
+	}
+
+	ctx.OkWithDetailed(response.ListResponse{
+		Data:  serviceCollectionPlan,
+		Count: total,
+	})
+}
diff --git a/api/v1/serviceContract.go b/api/v1/serviceContract.go
index 136c362..38b78f2 100644
--- a/api/v1/serviceContract.go
+++ b/api/v1/serviceContract.go
@@ -150,12 +150,12 @@
 
 // List
 //
-//	@Tags		ServiceContract
-//	@Summary	鐢熸垚璁″垝鍒楄〃
-//	@Produce	application/json
-//	@Param		object	body		request.GetServiceContractList	true	"鍙傛暟"
-//	@Success	200		{object}	contextx.Response{data=response.ServiceContractsResponse}
-//	@Router		/api/serviceContract/list [post]
+// @Tags		ServiceContract
+// @Summary	鐢熸垚璁″垝鍒楄〃
+// @Produce	application/json
+// @Param		object	body		request.GetServiceContractList	true	"鍙傛暟"
+// @Success	200		{object}	contextx.Response{data=response.ServiceContractsResponse}
+// @Router		/api/serviceContract/list [post]
 func (con *ServiceContractApi) List(c *gin.Context) {
 	var params request.GetServiceContractList
 	ctx, ok := contextx.NewContext(c, &params)
@@ -163,7 +163,7 @@
 		return
 	}
 
-	serviceContracts, total, errCode := serviceContractService.GetServiceContractList(params.Page, params.PageSize, params.Keyword)
+	serviceContracts, total, errCode := serviceContractService.GetServiceContractList(params.Page, params.PageSize, params.QueryClass, params.KeywordType, params.Keyword)
 	if errCode != ecode.OK {
 		ctx.Fail(errCode)
 		return
diff --git a/api/v1/serviceFeeManage.go b/api/v1/serviceFeeManage.go
index 2021056..ae338c5 100644
--- a/api/v1/serviceFeeManage.go
+++ b/api/v1/serviceFeeManage.go
@@ -54,7 +54,7 @@
 //	@Tags		ServiceFeeManage
 //	@Summary	鍒犻櫎鏈嶅姟璐圭鐞�
 //	@Produce	application/json
-//	@Param		object	body		request.DeleteServiceFeeManage true	"鏌ヨ鍙傛暟"
+//	@Param		object	body		request.DeleteServiceFeeManage true	"鏌ヨ鍙傛暟"
 //	@Success	200	{object}	contextx.Response{}
 //	@Router		/api/serviceFeeManage/delete [delete]
 func (s *ServiceFeeManageApi) Delete(c *gin.Context) {
@@ -111,7 +111,6 @@
 
 	ctx.Ok()
 }
-
 // checkServiceFeeManageParams
 func checkServiceFeeManageParams(serviceFeeManage request.ServiceFeeManage) (errCode int, result model.ServiceFeeManage) {
 	//if serviceFeeManage.ClientId == 0 {
@@ -152,7 +151,7 @@
 		return
 	}
 
-	serviceFeeManages, total, errCode := serviceFeeManageService.GetServiceFeeManageList(params.Page, params.PageSize, params.Keyword)
+	serviceFeeManages, total, errCode := serviceFeeManageService.GetServiceFeeManageList(params.Page, params.PageSize, params.QueryClass, params.KeywordType, params.Keyword)
 	if errCode != ecode.OK {
 		ctx.Fail(errCode)
 		return
diff --git a/api/v1/serviceFollowup.go b/api/v1/serviceFollowup.go
index 1ca9148..b657e7d 100644
--- a/api/v1/serviceFollowup.go
+++ b/api/v1/serviceFollowup.go
@@ -96,7 +96,6 @@
 
 	ctx.Ok()
 }
-
 // checkServiceFollowupParams
 func checkServiceFollowupParams(serviceFollowup request.ServiceFollowup) (errCode int, serviceFollowupModel model.ServiceFollowup) {
 	//if serviceFollowup.Number == "" {
@@ -141,7 +140,7 @@
 		return
 	}
 
-	serviceFollowups, total, errCode := serviceFollowupService.GetServiceFollowupList(params.Page, params.PageSize, params.Keyword)
+	serviceFollowups, total, errCode := serviceFollowupService.GetServiceFollowupList(params.Page, params.PageSize, params.KeywordType, params.Keyword)
 	if errCode != ecode.OK {
 		ctx.Fail(errCode)
 		return
diff --git a/api/v1/serviceOrder.go b/api/v1/serviceOrder.go
new file mode 100644
index 0000000..426dcef
--- /dev/null
+++ b/api/v1/serviceOrder.go
@@ -0,0 +1,120 @@
+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 ServiceOrderApi struct{}
+
+// Add
+// @Tags		鏈嶅姟鍗曠鐞�
+// @Summary	娣诲姞鏈嶅姟鍗�
+// @Produce	application/json
+// @Param		object	body		request.AddServiceOrder	true	"鏌ヨ鍙傛暟"
+// @Success	200		{object}	contextx.Response{}
+// @Router		/api/serviceOrder/add [post]
+func (s *ServiceOrderApi) Add(c *gin.Context) {
+	var params request.AddServiceOrder
+	ctx, ok := contextx.NewContext(c, &params)
+	if !ok {
+		return
+	}
+
+	serviceOrder := new(model.ServiceOrder)
+	if err := structx.AssignTo(params, serviceOrder); err != nil {
+		ctx.Fail(ecode.ParamsErr)
+		return
+	}
+
+	errCode := service.NewServiceOrderService().AddServiceOrder(serviceOrder)
+	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/serviceOrder/delete/{id} [delete]
+func (s *ServiceOrderApi) Delete(c *gin.Context) {
+	ctx, ok := contextx.NewContext(c, nil)
+	if !ok {
+		return
+	}
+
+	id, _ := strconv.Atoi(c.Param("id"))
+	errCode := service.NewServiceOrderService().DeleteServiceOrder(id)
+	if errCode != ecode.OK {
+		ctx.Fail(errCode)
+		return
+	}
+
+	ctx.Ok()
+}
+
+// Update
+// @Tags		鏈嶅姟鍗曠鐞�
+// @Summary	鏇存柊鏈嶅姟鍗�
+// @Produce	application/json
+// @Param		object	body		request.UpdateServiceOrder	true	"鏌ヨ鍙傛暟"
+// @Success	200		{object}	contextx.Response{}
+// @Router		/api/serviceOrder/update [put]
+func (s *ServiceOrderApi) Update(c *gin.Context) {
+	var params request.UpdateServiceOrder
+	ctx, ok := contextx.NewContext(c, &params)
+	if !ok {
+		return
+	}
+
+	serviceOrder := new(model.ServiceOrder)
+	if err := structx.AssignTo(params, serviceOrder); err != nil {
+		ctx.Fail(ecode.ParamsErr)
+		return
+	}
+
+	errCode := service.NewServiceOrderService().UpdateServiceOrder(serviceOrder)
+	if errCode != ecode.OK {
+		ctx.Fail(errCode)
+		return
+	}
+
+	ctx.Ok()
+}
+
+// List
+// @Tags		鏈嶅姟鍗曠鐞�
+// @Summary	鑾峰彇鏈嶅姟鍗曞垪琛�
+// @Produce	application/json
+// @Success	200	{object}	response.ListResponse{data=[]model.ServiceOrder}
+// @Router		/api/serviceOrder/list [get]
+func (s *ServiceOrderApi) List(c *gin.Context) {
+	ctx, ok := contextx.NewContext(c, nil)
+	if !ok {
+		return
+	}
+
+	serviceOrder, total, errCode := service.NewServiceOrderService().GetServiceOrderList()
+	if errCode != ecode.OK {
+		ctx.Fail(errCode)
+		return
+	}
+
+	ctx.OkWithDetailed(response.ListResponse{
+		Data:  serviceOrder,
+		Count: total,
+	})
+}
diff --git a/api/v1/serviceType.go b/api/v1/serviceType.go
new file mode 100644
index 0000000..5888c23
--- /dev/null
+++ b/api/v1/serviceType.go
@@ -0,0 +1,110 @@
+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 ServiceTypeApi struct{}
+
+// Add
+// @Tags		鏈嶅姟鏂瑰紡绠$悊
+// @Summary	娣诲姞鏈嶅姟鏂瑰紡
+// @Produce	application/json
+// @Param		object	body		request.AddServiceType	true	"鏌ヨ鍙傛暟"
+// @Success	200		{object}	contextx.Response{}
+// @Router		/api/serviceType/add [post]
+func (s *ServiceTypeApi) Add(c *gin.Context) {
+	var params request.AddServiceType
+	ctx, ok := contextx.NewContext(c, &params)
+	if !ok {
+		return
+	}
+
+	errCode := service.NewServiceTypeService().AddServiceType(&params.ServiceType)
+	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/serviceType/delete/{id} [delete]
+func (s *ServiceTypeApi) Delete(c *gin.Context) {
+	ctx, ok := contextx.NewContext(c, nil)
+	if !ok {
+		return
+	}
+
+	id, _ := strconv.Atoi(c.Param("id"))
+	errCode := service.NewServiceTypeService().DeleteServiceType(id)
+	if errCode != ecode.OK {
+		ctx.Fail(errCode)
+		return
+	}
+
+	ctx.Ok()
+}
+
+// Update
+// @Tags		鏈嶅姟鏂瑰紡绠$悊
+// @Summary	鏇存柊鏈嶅姟鏂瑰紡
+// @Produce	application/json
+// @Param		object	body		request.UpdateServiceType	true	"鏌ヨ鍙傛暟"
+// @Success	200		{object}	contextx.Response{}
+// @Router		/api/serviceType/update [put]
+func (s *ServiceTypeApi) Update(c *gin.Context) {
+	var params request.UpdateServiceType
+	ctx, ok := contextx.NewContext(c, &params)
+	if !ok {
+		return
+	}
+    if params.Id == 0 {
+        ctx.Fail(ecode.ParamsErr)
+    }
+    params.ServiceType.Id = params.Id
+
+	errCode := service.NewServiceTypeService().UpdateServiceType(&params.ServiceType)
+	if errCode != ecode.OK {
+		ctx.Fail(errCode)
+		return
+	}
+
+	ctx.Ok()
+}
+
+// List
+// @Tags		鏈嶅姟鏂瑰紡绠$悊
+// @Summary	鑾峰彇鏈嶅姟鏂瑰紡鍒楄〃
+// @Produce	application/json
+// @Success	200	{object}	response.ListResponse{data=[]model.ServiceType}
+// @Router		/api/serviceType/list [get]
+func (s *ServiceTypeApi) List(c *gin.Context) {
+	ctx, ok := contextx.NewContext(c, nil)
+	if !ok {
+		return
+	}
+
+	serviceType, total, errCode := service.NewServiceTypeService().GetServiceTypeList()
+	if errCode != ecode.OK {
+		ctx.Fail(errCode)
+		return
+	}
+
+	ctx.OkWithDetailed(response.ListResponse{
+		Data: serviceType,
+		Count: total,
+	})
+}
diff --git a/api/v1/severity.go b/api/v1/severity.go
new file mode 100644
index 0000000..a6bff7b
--- /dev/null
+++ b/api/v1/severity.go
@@ -0,0 +1,110 @@
+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 SeverityApi struct{}
+
+// Add
+// @Tags		涓ラ噸绋嬪害绠$悊
+// @Summary	娣诲姞涓ラ噸绋嬪害
+// @Produce	application/json
+// @Param		object	body		request.AddSeverity	true	"鏌ヨ鍙傛暟"
+// @Success	200		{object}	contextx.Response{}
+// @Router		/api/severity/add [post]
+func (s *SeverityApi) Add(c *gin.Context) {
+	var params request.AddSeverity
+	ctx, ok := contextx.NewContext(c, &params)
+	if !ok {
+		return
+	}
+
+	errCode := service.NewSeverityService().AddSeverity(&params.Severity)
+	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/severity/delete/{id} [delete]
+func (s *SeverityApi) Delete(c *gin.Context) {
+	ctx, ok := contextx.NewContext(c, nil)
+	if !ok {
+		return
+	}
+
+	id, _ := strconv.Atoi(c.Param("id"))
+	errCode := service.NewSeverityService().DeleteSeverity(id)
+	if errCode != ecode.OK {
+		ctx.Fail(errCode)
+		return
+	}
+
+	ctx.Ok()
+}
+
+// Update
+// @Tags		涓ラ噸绋嬪害绠$悊
+// @Summary	鏇存柊涓ラ噸绋嬪害
+// @Produce	application/json
+// @Param		object	body		request.UpdateSeverity	true	"鏌ヨ鍙傛暟"
+// @Success	200		{object}	contextx.Response{}
+// @Router		/api/severity/update [put]
+func (s *SeverityApi) Update(c *gin.Context) {
+	var params request.UpdateSeverity
+	ctx, ok := contextx.NewContext(c, &params)
+	if !ok {
+		return
+	}
+    if params.Id == 0 {
+        ctx.Fail(ecode.ParamsErr)
+    }
+    params.Severity.Id = params.Id
+
+	errCode := service.NewSeverityService().UpdateSeverity(&params.Severity)
+	if errCode != ecode.OK {
+		ctx.Fail(errCode)
+		return
+	}
+
+	ctx.Ok()
+}
+
+// List
+// @Tags		涓ラ噸绋嬪害绠$悊
+// @Summary	鑾峰彇涓ラ噸绋嬪害鍒楄〃
+// @Produce	application/json
+// @Success	200	{object}	response.ListResponse{data=[]model.Severity}
+// @Router		/api/severity/list [get]
+func (s *SeverityApi) List(c *gin.Context) {
+	ctx, ok := contextx.NewContext(c, nil)
+	if !ok {
+		return
+	}
+
+	severity, total, errCode := service.NewSeverityService().GetSeverityList()
+	if errCode != ecode.OK {
+		ctx.Fail(errCode)
+		return
+	}
+
+	ctx.OkWithDetailed(response.ListResponse{
+		Data: severity,
+		Count: total,
+	})
+}
diff --git a/api/v1/timeSpent.go b/api/v1/timeSpent.go
new file mode 100644
index 0000000..c22f776
--- /dev/null
+++ b/api/v1/timeSpent.go
@@ -0,0 +1,110 @@
+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 TimeSpentApi struct{}
+
+// Add
+// @Tags		鑺辫垂鏃堕棿绠$悊
+// @Summary	娣诲姞鑺辫垂鏃堕棿
+// @Produce	application/json
+// @Param		object	body		request.AddTimeSpent	true	"鏌ヨ鍙傛暟"
+// @Success	200		{object}	contextx.Response{}
+// @Router		/api/timeSpent/add [post]
+func (s *TimeSpentApi) Add(c *gin.Context) {
+	var params request.AddTimeSpent
+	ctx, ok := contextx.NewContext(c, &params)
+	if !ok {
+		return
+	}
+
+	errCode := service.NewTimeSpentService().AddTimeSpent(&params.TimeSpent)
+	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/timeSpent/delete/{id} [delete]
+func (s *TimeSpentApi) Delete(c *gin.Context) {
+	ctx, ok := contextx.NewContext(c, nil)
+	if !ok {
+		return
+	}
+
+	id, _ := strconv.Atoi(c.Param("id"))
+	errCode := service.NewTimeSpentService().DeleteTimeSpent(id)
+	if errCode != ecode.OK {
+		ctx.Fail(errCode)
+		return
+	}
+
+	ctx.Ok()
+}
+
+// Update
+// @Tags		鑺辫垂鏃堕棿绠$悊
+// @Summary	鏇存柊鑺辫垂鏃堕棿
+// @Produce	application/json
+// @Param		object	body		request.UpdateTimeSpent	true	"鏌ヨ鍙傛暟"
+// @Success	200		{object}	contextx.Response{}
+// @Router		/api/timeSpent/update [put]
+func (s *TimeSpentApi) Update(c *gin.Context) {
+	var params request.UpdateTimeSpent
+	ctx, ok := contextx.NewContext(c, &params)
+	if !ok {
+		return
+	}
+    if params.Id == 0 {
+        ctx.Fail(ecode.ParamsErr)
+    }
+    params.TimeSpent.Id = params.Id
+
+	errCode := service.NewTimeSpentService().UpdateTimeSpent(&params.TimeSpent)
+	if errCode != ecode.OK {
+		ctx.Fail(errCode)
+		return
+	}
+
+	ctx.Ok()
+}
+
+// List
+// @Tags		鑺辫垂鏃堕棿绠$悊
+// @Summary	鑾峰彇鑺辫垂鏃堕棿鍒楄〃
+// @Produce	application/json
+// @Success	200	{object}	response.ListResponse{data=[]model.TimeSpent}
+// @Router		/api/timeSpent/list [get]
+func (s *TimeSpentApi) List(c *gin.Context) {
+	ctx, ok := contextx.NewContext(c, nil)
+	if !ok {
+		return
+	}
+
+	timeSpent, total, errCode := service.NewTimeSpentService().GetTimeSpentList()
+	if errCode != ecode.OK {
+		ctx.Fail(errCode)
+		return
+	}
+
+	ctx.OkWithDetailed(response.ListResponse{
+		Data: timeSpent,
+		Count: total,
+	})
+}
diff --git a/constvar/bankAccount.go b/constvar/bankAccount.go
new file mode 100644
index 0000000..4e59333
--- /dev/null
+++ b/constvar/bankAccount.go
@@ -0,0 +1,12 @@
+package constvar
+type BankAccountQueryClass string
+
+const (
+	BankAccountQueryClassExpireLessThen60Days BankAccountQueryClass = ""
+)
+
+type BankAccountKeywordType string
+
+const (
+	BankAccountKeywordCustomerName   BankAccountKeywordType = ""
+)
diff --git a/constvar/const.go b/constvar/const.go
index ace5948..b73c7f0 100644
--- a/constvar/const.go
+++ b/constvar/const.go
@@ -66,3 +66,63 @@
 	VettingTypeSalesChance
 	VettingTypeSalesChanceFollow
 )
+
+type ServiceContractQueryClass string
+
+const (
+	ServiceContractQueryClassExpireAfter30Day   ServiceContractQueryClass = "30澶╁悗杩囨湡"
+	ServiceContractQueryClassExpireAfter60Day   ServiceContractQueryClass = "60澶╁悗杩囨湡"
+	ServiceContractQueryClassExpiredBefore15Day ServiceContractQueryClass = "宸茶繃鏈�15澶�"
+	ServiceContractQueryClassExpiredBefore60Day ServiceContractQueryClass = "宸茶繃鏈�60澶�"
+)
+
+type ServiceContractKeywordType string
+
+const (
+	ServiceContractKeywordContractNo        ServiceContractKeywordType = "鏈嶅姟鍚堝悓缂栧彿"
+	ServiceContractKeywordCustomerName      ServiceContractKeywordType = "瀹㈡埛鍚嶇О"
+	ServiceContractKeywordContractDate      ServiceContractKeywordType = "绛剧害鏃ユ湡"
+	ServiceContractKeywordContractType      ServiceContractKeywordType = "鍚堝悓绫诲瀷"
+	ServiceContractKeywordContractStatus    ServiceContractKeywordType = "鍚堝悓鐘舵��"
+	ServiceContractKeywordPrincipal         ServiceContractKeywordType = "璐熻矗浜�"
+	ServiceContractKeywordProductName       ServiceContractKeywordType = "浜у搧鍚嶇О"
+	ServiceContractKeywordServiceBeginDate  ServiceContractKeywordType = "鏈嶅姟寮�濮嬫棩"
+	ServiceContractKeywordServiceEndDate    ServiceContractKeywordType = "鏈嶅姟鍒版湡鏃�"
+	ServiceContractKeywordServiceTotalPrice ServiceContractKeywordType = "浠风◣鍚堣"
+)
+
+type ServiceFollowupKeywordType string
+
+const (
+	ServiceFollowupKeywordFollowupNo         ServiceFollowupKeywordType = "鍥炶鍗曠紪鍙�"
+	ServiceFollowupKeywordCustomerName       ServiceFollowupKeywordType = "瀹㈡埛鍚嶇О"
+	ServiceFollowupKeywordContactName        ServiceFollowupKeywordType = "鑱旂郴浜哄鍚�"
+	ServiceFollowupKeywordCustomerServiceNo  ServiceFollowupKeywordType = "瀹㈡埛鏈嶅姟鍗�"
+	ServiceFollowupKeywordVisitor            ServiceFollowupKeywordType = "鍥炶浜�"
+	ServiceFollowupKeywordSatisfactionDegree ServiceFollowupKeywordType = "婊℃剰搴�"
+)
+
+type ServiceFeeQueryClass string
+
+const (
+	ServiceFeeQueryClassExpireLessThen60Days ServiceFeeQueryClass = "杩囨湡鏈弧60澶�"
+	ServiceFeeQueryClassExpireLessThen30Days ServiceFeeQueryClass = "杩囨湡鏈弧30澶�"
+	ServiceFeeQueryClassExpireAboutTo60Day   ServiceFeeQueryClass = "鍗冲皢杩囨湡60澶�"
+	ServiceFeeQueryClassExpireAboutTo30Day   ServiceFeeQueryClass = "鍗冲皢杩囨湡30澶�"
+	ServiceFeeQueryClassExpired              ServiceFeeQueryClass = "宸茶繃鏈�"
+	ServiceFeeQueryClassNoService            ServiceFeeQueryClass = "鏃犳湇鍔�"
+)
+
+type ServiceFeeKeywordType string
+
+const (
+	ServiceFeeKeywordCustomerName   ServiceFeeKeywordType = "瀹㈡埛鍚嶇О"
+	ServiceFeeKeywordCustomerType   ServiceFeeKeywordType = "瀹㈡埛绫诲瀷"
+	ServiceFeeKeywordSalesPrincipal ServiceFeeKeywordType = "閿�鍞礋璐d汉"
+	ServiceFeeKeywordCustomerScale  ServiceFeeKeywordType = "瀹㈡埛瑙勬ā"
+	ServiceFeeKeywordClientLevel    ServiceFeeKeywordType = "閲嶈绾у埆"
+	ServiceFeeKeywordCustomerNo     ServiceFeeKeywordType = "瀹㈡埛缂栧彿"
+	ServiceFeeKeywordCustomerStatus ServiceFeeKeywordType = "瀹㈡埛鐘舵��"
+	ServiceFeeKeywordProductName    ServiceFeeKeywordType = "浜у搧鍚嶇О"
+	ServiceFeeKeywordServiceEndDate ServiceFeeKeywordType = "鏈嶅姟鍒版湡鏃�"
+)
diff --git a/constvar/faq.go b/constvar/faq.go
new file mode 100644
index 0000000..df1e10f
--- /dev/null
+++ b/constvar/faq.go
@@ -0,0 +1,12 @@
+package constvar
+type FaqQueryClass string
+
+const (
+	FaqQueryClassExpireLessThen60Days FaqQueryClass = ""
+)
+
+type FaqKeywordType string
+
+const (
+	FaqKeywordCustomerName   FaqKeywordType = ""
+)
diff --git a/constvar/faultType.go b/constvar/faultType.go
new file mode 100644
index 0000000..e522e0a
--- /dev/null
+++ b/constvar/faultType.go
@@ -0,0 +1,12 @@
+package constvar
+type FaultTypeQueryClass string
+
+const (
+	FaultTypeQueryClassExpireLessThen60Days FaultTypeQueryClass = ""
+)
+
+type FaultTypeKeywordType string
+
+const (
+	FaultTypeKeywordCustomerName   FaultTypeKeywordType = ""
+)
diff --git a/constvar/file.go b/constvar/file.go
new file mode 100644
index 0000000..042bbf4
--- /dev/null
+++ b/constvar/file.go
@@ -0,0 +1,12 @@
+package constvar
+type FileQueryClass string
+
+const (
+	FileQueryClassExpireLessThen60Days FileQueryClass = ""
+)
+
+type FileKeywordType string
+
+const (
+	FileKeywordCustomerName   FileKeywordType = ""
+)
diff --git a/constvar/paymentType.go b/constvar/paymentType.go
new file mode 100644
index 0000000..f44593a
--- /dev/null
+++ b/constvar/paymentType.go
@@ -0,0 +1,12 @@
+package constvar
+type PaymentTypeQueryClass string
+
+const (
+	PaymentTypeQueryClassExpireLessThen60Days PaymentTypeQueryClass = ""
+)
+
+type PaymentTypeKeywordType string
+
+const (
+	PaymentTypeKeywordCustomerName   PaymentTypeKeywordType = ""
+)
diff --git a/constvar/priorityLevel.go b/constvar/priorityLevel.go
new file mode 100644
index 0000000..fab4303
--- /dev/null
+++ b/constvar/priorityLevel.go
@@ -0,0 +1,12 @@
+package constvar
+type PriorityLevelQueryClass string
+
+const (
+	PriorityLevelQueryClassExpireLessThen60Days PriorityLevelQueryClass = ""
+)
+
+type PriorityLevelKeywordType string
+
+const (
+	PriorityLevelKeywordCustomerName   PriorityLevelKeywordType = ""
+)
diff --git a/constvar/receipt.go b/constvar/receipt.go
new file mode 100644
index 0000000..df8e86e
--- /dev/null
+++ b/constvar/receipt.go
@@ -0,0 +1,12 @@
+package constvar
+type ReceiptQueryClass string
+
+const (
+	ReceiptQueryClassExpireLessThen60Days ReceiptQueryClass = ""
+)
+
+type ReceiptKeywordType string
+
+const (
+	ReceiptKeywordCustomerName   ReceiptKeywordType = ""
+)
diff --git a/constvar/serviceCollectionPlan.go b/constvar/serviceCollectionPlan.go
new file mode 100644
index 0000000..32450ec
--- /dev/null
+++ b/constvar/serviceCollectionPlan.go
@@ -0,0 +1,12 @@
+package constvar
+type ServiceCollectionPlanQueryClass string
+
+const (
+	ServiceCollectionPlanQueryClassExpireLessThen60Days ServiceCollectionPlanQueryClass = ""
+)
+
+type ServiceCollectionPlanKeywordType string
+
+const (
+	ServiceCollectionPlanKeywordCustomerName   ServiceCollectionPlanKeywordType = ""
+)
diff --git a/constvar/serviceOrder.go b/constvar/serviceOrder.go
new file mode 100644
index 0000000..959e402
--- /dev/null
+++ b/constvar/serviceOrder.go
@@ -0,0 +1,12 @@
+package constvar
+type ServiceOrderQueryClass string
+
+const (
+	ServiceOrderQueryClassExpireLessThen60Days ServiceOrderQueryClass = ""
+)
+
+type ServiceOrderKeywordType string
+
+const (
+	ServiceOrderKeywordCustomerName   ServiceOrderKeywordType = ""
+)
diff --git a/constvar/serviceType.go b/constvar/serviceType.go
new file mode 100644
index 0000000..3a8c856
--- /dev/null
+++ b/constvar/serviceType.go
@@ -0,0 +1,12 @@
+package constvar
+type ServiceTypeQueryClass string
+
+const (
+	ServiceTypeQueryClassExpireLessThen60Days ServiceTypeQueryClass = ""
+)
+
+type ServiceTypeKeywordType string
+
+const (
+	ServiceTypeKeywordCustomerName   ServiceTypeKeywordType = ""
+)
diff --git a/constvar/severity.go b/constvar/severity.go
new file mode 100644
index 0000000..f9781c7
--- /dev/null
+++ b/constvar/severity.go
@@ -0,0 +1,12 @@
+package constvar
+type SeverityQueryClass string
+
+const (
+	SeverityQueryClassExpireLessThen60Days SeverityQueryClass = ""
+)
+
+type SeverityKeywordType string
+
+const (
+	SeverityKeywordCustomerName   SeverityKeywordType = ""
+)
diff --git a/constvar/timeSpent.go b/constvar/timeSpent.go
new file mode 100644
index 0000000..4f38fe2
--- /dev/null
+++ b/constvar/timeSpent.go
@@ -0,0 +1,12 @@
+package constvar
+type TimeSpentQueryClass string
+
+const (
+	TimeSpentQueryClassExpireLessThen60Days TimeSpentQueryClass = ""
+)
+
+type TimeSpentKeywordType string
+
+const (
+	TimeSpentKeywordCustomerName   TimeSpentKeywordType = ""
+)
diff --git a/model/bankAccount.go b/model/bankAccount.go
new file mode 100644
index 0000000..006e9b8
--- /dev/null
+++ b/model/bankAccount.go
@@ -0,0 +1,140 @@
+package model
+
+import (
+	"aps_crm/constvar"
+	"aps_crm/pkg/mysqlx"
+	"errors"
+	"fmt"
+	"gorm.io/gorm"
+)
+
+type (
+	// BankAccount 閾惰璐︽埛
+	BankAccount struct {
+		Id   int    `json:"id" gorm:"column:id;primary_key;AUTO_INCREMENT"`
+		Name   string    `json:"name" gorm:"column:name"`
+	}
+
+	// BankAccountSearch 閾惰璐︽埛鎼滅储鏉′欢
+	BankAccountSearch struct {
+		BankAccount
+		Orm *gorm.DB
+        QueryClass  constvar.BankAccountQueryClass
+        KeywordType constvar.BankAccountKeywordType
+        Keyword     string
+        PageNum  int
+        PageSize int
+	}
+)
+
+func (BankAccount) TableName() string {
+	return "bank_account"
+}
+
+func NewBankAccountSearch() *BankAccountSearch {
+	return &BankAccountSearch{
+		Orm: mysqlx.GetDB(),
+	}
+}
+
+func (slf *BankAccountSearch) build() *gorm.DB {
+	var db = slf.Orm.Model(&BankAccount{})
+	if slf.Id != 0 {
+		db = db.Where("id = ?", slf.Id)
+	}
+
+	return db
+}
+
+func (slf *BankAccountSearch) Create(record *BankAccount) error {
+	var db = slf.build()
+	return db.Create(record).Error
+}
+
+func (slf *BankAccountSearch) CreateBatch(records []*BankAccount) error {
+	var db = slf.build()
+	return db.Create(records).Error
+}
+
+func (slf *BankAccountSearch) Delete() error {
+	var db = slf.build()
+	return db.Delete(&BankAccount{}).Error
+}
+
+func (slf *BankAccountSearch) Update(record *BankAccount) error {
+	var db = slf.build()
+	return db.Updates(record).Error
+}
+
+func (slf *BankAccountSearch) FindAll() ([]*BankAccount, error) {
+	var db = slf.build()
+	var record = make([]*BankAccount, 0)
+	err := db.Find(&record).Error
+	return record, err
+}
+
+func (slf *BankAccountSearch) SetId(id int) *BankAccountSearch {
+	slf.Id = id
+	return slf
+}
+
+func (slf *BankAccountSearch) SetOrm(tx *gorm.DB) *BankAccountSearch {
+	slf.Orm = tx
+	return slf
+}
+
+func (slf *BankAccountSearch) First() (*BankAccount, error) {
+	var db = slf.build()
+	var record = new(BankAccount)
+	err := db.First(record).Error
+	return record, err
+}
+
+func (slf *BankAccountSearch) Updates(values interface{}) error {
+	var db = slf.build()
+	return db.Updates(values).Error
+}
+
+func (slf *BankAccountSearch) Save(record *BankAccount) 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 *BankAccountSearch) Find() ([]*BankAccount, int64, error) {
+	var db = slf.build()
+	var records = make([]*BankAccount, 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 *BankAccountSearch) 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 := []*BankAccount{}
+	return slf.CreateBatch(records)
+}
diff --git a/model/faq.go b/model/faq.go
new file mode 100644
index 0000000..115e1d6
--- /dev/null
+++ b/model/faq.go
@@ -0,0 +1,135 @@
+package model
+
+import (
+	"aps_crm/constvar"
+	"aps_crm/pkg/mysqlx"
+	"errors"
+	"fmt"
+	"gorm.io/gorm"
+)
+
+type (
+	// Faq 甯歌闂
+	Faq struct {
+		Id   int    `json:"id" gorm:"column:id;primary_key;AUTO_INCREMENT"`
+		Name   string    `json:"name" gorm:"column:name"`
+	}
+
+	// FaqSearch 甯歌闂鎼滅储鏉′欢
+	FaqSearch struct {
+		Faq
+		Orm *gorm.DB
+        QueryClass  constvar.FaqQueryClass
+        KeywordType constvar.FaqKeywordType
+        Keyword     string
+        PageNum  int
+        PageSize int
+	}
+)
+
+func (Faq) TableName() string {
+	return "faq"
+}
+
+func NewFaqSearch() *FaqSearch {
+	return &FaqSearch{
+		Orm: mysqlx.GetDB(),
+	}
+}
+
+func (slf *FaqSearch) build() *gorm.DB {
+	var db = slf.Orm.Model(&Faq{})
+	if slf.Id != 0 {
+		db = db.Where("id = ?", slf.Id)
+	}
+
+	return db
+}
+
+func (slf *FaqSearch) Create(record *Faq) error {
+	var db = slf.build()
+	return db.Create(record).Error
+}
+
+func (slf *FaqSearch) CreateBatch(records []*Faq) error {
+	var db = slf.build()
+	return db.Create(records).Error
+}
+
+func (slf *FaqSearch) Delete() error {
+	var db = slf.build()
+	return db.Delete(&Faq{}).Error
+}
+
+func (slf *FaqSearch) Update(record *Faq) error {
+	var db = slf.build()
+	return db.Updates(record).Error
+}
+
+func (slf *FaqSearch) FindAll() ([]*Faq, error) {
+	var db = slf.build()
+	var record = make([]*Faq, 0)
+	err := db.Find(&record).Error
+	return record, err
+}
+
+func (slf *FaqSearch) SetId(id int) *FaqSearch {
+	slf.Id = id
+	return slf
+}
+
+func (slf *FaqSearch) First() (*Faq, error) {
+	var db = slf.build()
+	var record = new(Faq)
+	err := db.First(record).Error
+	return record, err
+}
+
+func (slf *FaqSearch) Updates(values interface{}) error {
+	var db = slf.build()
+	return db.Updates(values).Error
+}
+
+func (slf *FaqSearch) Save(record *Faq) 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 *FaqSearch) Find() ([]*Faq, int64, error) {
+	var db = slf.build()
+	var records = make([]*Faq, 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 *FaqSearch) 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 := []*Faq{}
+	return slf.CreateBatch(records)
+}
diff --git a/model/faultType.go b/model/faultType.go
new file mode 100644
index 0000000..260cc2f
--- /dev/null
+++ b/model/faultType.go
@@ -0,0 +1,135 @@
+package model
+
+import (
+	"aps_crm/constvar"
+	"aps_crm/pkg/mysqlx"
+	"errors"
+	"fmt"
+	"gorm.io/gorm"
+)
+
+type (
+	// FaultType 鏁呴殰绫诲埆
+	FaultType struct {
+		Id   int    `json:"id" gorm:"column:id;primary_key;AUTO_INCREMENT"`
+		Name   string    `json:"name" gorm:"column:name"`
+	}
+
+	// FaultTypeSearch 鏁呴殰绫诲埆鎼滅储鏉′欢
+	FaultTypeSearch struct {
+		FaultType
+		Orm *gorm.DB
+        QueryClass  constvar.FaultTypeQueryClass
+        KeywordType constvar.FaultTypeKeywordType
+        Keyword     string
+        PageNum  int
+        PageSize int
+	}
+)
+
+func (FaultType) TableName() string {
+	return "fault_type"
+}
+
+func NewFaultTypeSearch() *FaultTypeSearch {
+	return &FaultTypeSearch{
+		Orm: mysqlx.GetDB(),
+	}
+}
+
+func (slf *FaultTypeSearch) build() *gorm.DB {
+	var db = slf.Orm.Model(&FaultType{})
+	if slf.Id != 0 {
+		db = db.Where("id = ?", slf.Id)
+	}
+
+	return db
+}
+
+func (slf *FaultTypeSearch) Create(record *FaultType) error {
+	var db = slf.build()
+	return db.Create(record).Error
+}
+
+func (slf *FaultTypeSearch) CreateBatch(records []*FaultType) error {
+	var db = slf.build()
+	return db.Create(records).Error
+}
+
+func (slf *FaultTypeSearch) Delete() error {
+	var db = slf.build()
+	return db.Delete(&FaultType{}).Error
+}
+
+func (slf *FaultTypeSearch) Update(record *FaultType) error {
+	var db = slf.build()
+	return db.Updates(record).Error
+}
+
+func (slf *FaultTypeSearch) FindAll() ([]*FaultType, error) {
+	var db = slf.build()
+	var record = make([]*FaultType, 0)
+	err := db.Find(&record).Error
+	return record, err
+}
+
+func (slf *FaultTypeSearch) SetId(id int) *FaultTypeSearch {
+	slf.Id = id
+	return slf
+}
+
+func (slf *FaultTypeSearch) First() (*FaultType, error) {
+	var db = slf.build()
+	var record = new(FaultType)
+	err := db.First(record).Error
+	return record, err
+}
+
+func (slf *FaultTypeSearch) Updates(values interface{}) error {
+	var db = slf.build()
+	return db.Updates(values).Error
+}
+
+func (slf *FaultTypeSearch) Save(record *FaultType) 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 *FaultTypeSearch) Find() ([]*FaultType, int64, error) {
+	var db = slf.build()
+	var records = make([]*FaultType, 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 *FaultTypeSearch) 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 := []*FaultType{}
+	return slf.CreateBatch(records)
+}
diff --git a/model/file.go b/model/file.go
new file mode 100644
index 0000000..3b919f3
--- /dev/null
+++ b/model/file.go
@@ -0,0 +1,152 @@
+package model
+
+import (
+	"aps_crm/constvar"
+	"aps_crm/pkg/mysqlx"
+	"errors"
+	"fmt"
+	"gorm.io/gorm"
+)
+
+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"`           // 鏂囦欢璺緞
+		Key           string `gorm:"key" json:"key"`                      // 瀵硅薄瀛樺偍key
+		Bucket        string `gorm:"bucket" json:"bucket"`                // 瀵硅薄瀛樺偍bucket
+		DownloadCount int    `gorm:"download_count" json:"downloadCount"` // 涓嬫娆℃暟
+		PreviewCount  int    `gorm:"preview_count" json:"previewCount"`   // 棰勮娆℃暟
+		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"` // 鏂囦欢鍐呭
+	}
+
+	// FileSearch 闄勪欢鎼滅储鏉′欢
+	FileSearch struct {
+		File
+		Orm         *gorm.DB
+		QueryClass  constvar.FileQueryClass
+		KeywordType constvar.FileKeywordType
+		Keyword     string
+		PageNum     int
+		PageSize    int
+	}
+)
+
+func (File) TableName() string {
+	return "file"
+}
+
+func NewFileSearch() *FileSearch {
+	return &FileSearch{
+		Orm: mysqlx.GetDB(),
+	}
+}
+
+func (slf *FileSearch) build() *gorm.DB {
+	var db = slf.Orm.Model(&File{})
+	if slf.Id != 0 {
+		db = db.Where("id = ?", slf.Id)
+	}
+
+	return db
+}
+
+func (slf *FileSearch) Create(record *File) error {
+	var db = slf.build()
+	return db.Create(record).Error
+}
+
+func (slf *FileSearch) CreateBatch(records []*File) error {
+	var db = slf.build()
+	return db.Create(records).Error
+}
+
+func (slf *FileSearch) Delete() error {
+	var db = slf.build()
+	return db.Delete(&File{}).Error
+}
+
+func (slf *FileSearch) Update(record *File) error {
+	var db = slf.build()
+	return db.Updates(record).Error
+}
+
+func (slf *FileSearch) FindAll() ([]*File, error) {
+	var db = slf.build()
+	var record = make([]*File, 0)
+	err := db.Find(&record).Error
+	return record, err
+}
+
+func (slf *FileSearch) SetId(id int) *FileSearch {
+	slf.Id = id
+	return slf
+}
+
+func (slf *FileSearch) SetOrm(tx *gorm.DB) *FileSearch {
+	slf.Orm = tx
+	return slf
+}
+
+func (slf *FileSearch) First() (*File, error) {
+	var db = slf.build()
+	var record = new(File)
+	err := db.First(record).Error
+	return record, err
+}
+
+func (slf *FileSearch) Updates(values interface{}) error {
+	var db = slf.build()
+	return db.Updates(values).Error
+}
+
+func (slf *FileSearch) Save(record *File) 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 *FileSearch) Find() ([]*File, int64, error) {
+	var db = slf.build()
+	var records = make([]*File, 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 *FileSearch) 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 := []*File{}
+	return slf.CreateBatch(records)
+}
diff --git a/model/index.go b/model/index.go
index 8c7b0f7..04856fa 100644
--- a/model/index.go
+++ b/model/index.go
@@ -4,6 +4,8 @@
 	"aps_crm/conf"
 	"aps_crm/pkg/logx"
 	"aps_crm/pkg/mysqlx"
+	"aps_crm/pkg/safe"
+	"gorm.io/gorm/schema"
 )
 
 func Init() error {
@@ -14,7 +16,9 @@
 	if err := RegisterTables(); err != nil {
 		return err
 	}
-
+	safe.Go(func() {
+		InsertDefaultData()
+	})
 	return nil
 }
 
@@ -66,19 +70,39 @@
 		Satisfaction{},
 		TimelyRate{},
 		SolveRate{},
-        IsVisit{},
-        IsVisit{},
-        ReportSource{},
-        OrderType{},
-        ServiceContractStatus{},
-        ServiceContractType{},
-        RefundMethod{},
-        IsInvoice{},
-        AccountId{},
-        SalesReturnStatus{},
-        Repository{},
-        QuotationStatus{},
-        Currency{},
+		IsVisit{},
+		IsVisit{},
+		ReportSource{},
+		OrderType{},
+		ServiceContractStatus{},
+		ServiceContractType{},
+		RefundMethod{},
+		IsInvoice{},
+		AccountId{},
+		SalesReturnStatus{},
+		Repository{},
+		QuotationStatus{},
+		Currency{},
 	)
 	return err
-}
\ No newline at end of file
+}
+
+type InitDefaultData interface {
+	InitDefaultData() error
+}
+
+func InsertDefaultData() {
+	models := []interface{}{
+		NewServiceTypeSearch(),
+		NewPriorityLevelSearch(),
+		NewSeveritySearch(),
+		NewTimeSpentSearch(),
+	}
+	for _, model := range models {
+		if id, ok := model.(InitDefaultData); ok {
+			if err := id.InitDefaultData(); err != nil {
+				logx.Errorf("InitDefaultData for table: %v, err :%v", model.(schema.Tabler).TableName(), err.Error())
+			}
+		}
+	}
+}
diff --git a/model/paymentType.go b/model/paymentType.go
new file mode 100644
index 0000000..e16a84a
--- /dev/null
+++ b/model/paymentType.go
@@ -0,0 +1,140 @@
+package model
+
+import (
+	"aps_crm/constvar"
+	"aps_crm/pkg/mysqlx"
+	"errors"
+	"fmt"
+	"gorm.io/gorm"
+)
+
+type (
+	// PaymentType 鏀粯鏂瑰紡
+	PaymentType struct {
+		Id   int    `json:"id" gorm:"column:id;primary_key;AUTO_INCREMENT"`
+		Name   string    `json:"name" gorm:"column:name"`
+	}
+
+	// PaymentTypeSearch 鏀粯鏂瑰紡鎼滅储鏉′欢
+	PaymentTypeSearch struct {
+		PaymentType
+		Orm *gorm.DB
+        QueryClass  constvar.PaymentTypeQueryClass
+        KeywordType constvar.PaymentTypeKeywordType
+        Keyword     string
+        PageNum  int
+        PageSize int
+	}
+)
+
+func (PaymentType) TableName() string {
+	return "payment_type"
+}
+
+func NewPaymentTypeSearch() *PaymentTypeSearch {
+	return &PaymentTypeSearch{
+		Orm: mysqlx.GetDB(),
+	}
+}
+
+func (slf *PaymentTypeSearch) build() *gorm.DB {
+	var db = slf.Orm.Model(&PaymentType{})
+	if slf.Id != 0 {
+		db = db.Where("id = ?", slf.Id)
+	}
+
+	return db
+}
+
+func (slf *PaymentTypeSearch) Create(record *PaymentType) error {
+	var db = slf.build()
+	return db.Create(record).Error
+}
+
+func (slf *PaymentTypeSearch) CreateBatch(records []*PaymentType) error {
+	var db = slf.build()
+	return db.Create(records).Error
+}
+
+func (slf *PaymentTypeSearch) Delete() error {
+	var db = slf.build()
+	return db.Delete(&PaymentType{}).Error
+}
+
+func (slf *PaymentTypeSearch) Update(record *PaymentType) error {
+	var db = slf.build()
+	return db.Updates(record).Error
+}
+
+func (slf *PaymentTypeSearch) FindAll() ([]*PaymentType, error) {
+	var db = slf.build()
+	var record = make([]*PaymentType, 0)
+	err := db.Find(&record).Error
+	return record, err
+}
+
+func (slf *PaymentTypeSearch) SetId(id int) *PaymentTypeSearch {
+	slf.Id = id
+	return slf
+}
+
+func (slf *PaymentTypeSearch) SetOrm(tx *gorm.DB) *PaymentTypeSearch {
+	slf.Orm = tx
+	return slf
+}
+
+func (slf *PaymentTypeSearch) First() (*PaymentType, error) {
+	var db = slf.build()
+	var record = new(PaymentType)
+	err := db.First(record).Error
+	return record, err
+}
+
+func (slf *PaymentTypeSearch) Updates(values interface{}) error {
+	var db = slf.build()
+	return db.Updates(values).Error
+}
+
+func (slf *PaymentTypeSearch) Save(record *PaymentType) 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 *PaymentTypeSearch) Find() ([]*PaymentType, int64, error) {
+	var db = slf.build()
+	var records = make([]*PaymentType, 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 *PaymentTypeSearch) 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 := []*PaymentType{}
+	return slf.CreateBatch(records)
+}
diff --git a/model/priorityLevel.go b/model/priorityLevel.go
new file mode 100644
index 0000000..fad265d
--- /dev/null
+++ b/model/priorityLevel.go
@@ -0,0 +1,135 @@
+package model
+
+import (
+	"aps_crm/constvar"
+	"aps_crm/pkg/mysqlx"
+	"errors"
+	"fmt"
+	"gorm.io/gorm"
+)
+
+type (
+	// PriorityLevel 浼樺厛绾у埆
+	PriorityLevel struct {
+		Id   int    `json:"id" gorm:"column:id;primary_key;AUTO_INCREMENT"`
+		Name   string    `json:"name" gorm:"column:name"`
+	}
+
+	// PriorityLevelSearch 浼樺厛绾у埆鎼滅储鏉′欢
+	PriorityLevelSearch struct {
+		PriorityLevel
+		Orm *gorm.DB
+        QueryClass  constvar.PriorityLevelQueryClass
+        KeywordType constvar.PriorityLevelKeywordType
+        Keyword     string
+        PageNum  int
+        PageSize int
+	}
+)
+
+func (PriorityLevel) TableName() string {
+	return "priority_level"
+}
+
+func NewPriorityLevelSearch() *PriorityLevelSearch {
+	return &PriorityLevelSearch{
+		Orm: mysqlx.GetDB(),
+	}
+}
+
+func (slf *PriorityLevelSearch) build() *gorm.DB {
+	var db = slf.Orm.Model(&PriorityLevel{})
+	if slf.Id != 0 {
+		db = db.Where("id = ?", slf.Id)
+	}
+
+	return db
+}
+
+func (slf *PriorityLevelSearch) Create(record *PriorityLevel) error {
+	var db = slf.build()
+	return db.Create(record).Error
+}
+
+func (slf *PriorityLevelSearch) CreateBatch(records []*PriorityLevel) error {
+	var db = slf.build()
+	return db.Create(records).Error
+}
+
+func (slf *PriorityLevelSearch) Delete() error {
+	var db = slf.build()
+	return db.Delete(&PriorityLevel{}).Error
+}
+
+func (slf *PriorityLevelSearch) Update(record *PriorityLevel) error {
+	var db = slf.build()
+	return db.Updates(record).Error
+}
+
+func (slf *PriorityLevelSearch) FindAll() ([]*PriorityLevel, error) {
+	var db = slf.build()
+	var record = make([]*PriorityLevel, 0)
+	err := db.Find(&record).Error
+	return record, err
+}
+
+func (slf *PriorityLevelSearch) SetId(id int) *PriorityLevelSearch {
+	slf.Id = id
+	return slf
+}
+
+func (slf *PriorityLevelSearch) First() (*PriorityLevel, error) {
+	var db = slf.build()
+	var record = new(PriorityLevel)
+	err := db.First(record).Error
+	return record, err
+}
+
+func (slf *PriorityLevelSearch) Updates(values interface{}) error {
+	var db = slf.build()
+	return db.Updates(values).Error
+}
+
+func (slf *PriorityLevelSearch) Save(record *PriorityLevel) 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 *PriorityLevelSearch) Find() ([]*PriorityLevel, int64, error) {
+	var db = slf.build()
+	var records = make([]*PriorityLevel, 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 *PriorityLevelSearch) 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 := []*PriorityLevel{}
+	return slf.CreateBatch(records)
+}
diff --git a/model/receipt.go b/model/receipt.go
new file mode 100644
index 0000000..60d1d2a
--- /dev/null
+++ b/model/receipt.go
@@ -0,0 +1,149 @@
+package model
+
+import (
+	"aps_crm/constvar"
+	"aps_crm/pkg/mysqlx"
+	"errors"
+	"fmt"
+	"gorm.io/gorm"
+)
+
+type (
+	// Receipt 鏀舵鍗�
+	Receipt struct {
+		Id            int    `json:"id" gorm:"column:id;primary_key;AUTO_INCREMENT"`
+		ClientId      int    `gorm:"client_id" json:"clientId"`            // 瀹㈡埛id
+		SourceType    int    `gorm:"source_type" json:"sourceType"`        // 鏉ユ簮绫诲瀷锛�1閿�鍞槑缁嗗崟2鏈嶅姟鍚堝悓3閿�鍞彂绁�4鏀舵璁″垝5鍑哄簱鍗曪級
+		SourceId      int    `gorm:"source_id" json:"sourceId"`            // 婧愬崟id
+		PrincipalId   int    `gorm:"principal_id" json:"principalId"`      // 璐熻矗浜篿d
+		ReceiptDate   string `gorm:"receipt_date" json:"receiptDate"`      // 鏀舵鏃ユ湡
+		MoneyType     string `gorm:"money_type" json:"moneyType"`          // 甯佺
+		PaymentTypeId int    `gorm:"payment_type_id" json:"paymentTypeId"` // 鏀舵鏂瑰紡ID
+		BankAccountId int    `gorm:"bank_account_id" json:"bankAccountId"` // 璐︽埛id
+		Remark        string `gorm:"remark" json:"remark"`                 // 澶囨敞
+		FileId        int    `gorm:"file_id" json:"fileId"`                // 闄勪欢id
+	}
+
+	// ReceiptSearch 鏀舵鍗曟悳绱㈡潯浠�
+	ReceiptSearch struct {
+		Receipt
+		Orm         *gorm.DB
+		QueryClass  constvar.ReceiptQueryClass
+		KeywordType constvar.ReceiptKeywordType
+		Keyword     string
+		PageNum     int
+		PageSize    int
+	}
+)
+
+func (Receipt) TableName() string {
+	return "receipt"
+}
+
+func NewReceiptSearch() *ReceiptSearch {
+	return &ReceiptSearch{
+		Orm: mysqlx.GetDB(),
+	}
+}
+
+func (slf *ReceiptSearch) build() *gorm.DB {
+	var db = slf.Orm.Model(&Receipt{})
+	if slf.Id != 0 {
+		db = db.Where("id = ?", slf.Id)
+	}
+
+	return db
+}
+
+func (slf *ReceiptSearch) Create(record *Receipt) error {
+	var db = slf.build()
+	return db.Create(record).Error
+}
+
+func (slf *ReceiptSearch) CreateBatch(records []*Receipt) error {
+	var db = slf.build()
+	return db.Create(records).Error
+}
+
+func (slf *ReceiptSearch) Delete() error {
+	var db = slf.build()
+	return db.Delete(&Receipt{}).Error
+}
+
+func (slf *ReceiptSearch) Update(record *Receipt) error {
+	var db = slf.build()
+	return db.Updates(record).Error
+}
+
+func (slf *ReceiptSearch) FindAll() ([]*Receipt, error) {
+	var db = slf.build()
+	var record = make([]*Receipt, 0)
+	err := db.Find(&record).Error
+	return record, err
+}
+
+func (slf *ReceiptSearch) SetId(id int) *ReceiptSearch {
+	slf.Id = id
+	return slf
+}
+
+func (slf *ReceiptSearch) SetOrm(tx *gorm.DB) *ReceiptSearch {
+	slf.Orm = tx
+	return slf
+}
+
+func (slf *ReceiptSearch) First() (*Receipt, error) {
+	var db = slf.build()
+	var record = new(Receipt)
+	err := db.First(record).Error
+	return record, err
+}
+
+func (slf *ReceiptSearch) Updates(values interface{}) error {
+	var db = slf.build()
+	return db.Updates(values).Error
+}
+
+func (slf *ReceiptSearch) Save(record *Receipt) 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 *ReceiptSearch) Find() ([]*Receipt, int64, error) {
+	var db = slf.build()
+	var records = make([]*Receipt, 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 *ReceiptSearch) 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 := []*Receipt{}
+	return slf.CreateBatch(records)
+}
diff --git a/model/request/bankAccount.go b/model/request/bankAccount.go
new file mode 100644
index 0000000..3eed94e
--- /dev/null
+++ b/model/request/bankAccount.go
@@ -0,0 +1,22 @@
+package request
+
+import (
+    "aps_crm/constvar"
+    "aps_crm/model"
+)
+
+type AddBankAccount struct {
+	model.BankAccount
+}
+
+type UpdateBankAccount struct {
+	Id int `json:"id"`
+	model.BankAccount
+}
+
+type GetBankAccountList struct {
+	PageInfo
+	QueryClass  constvar.BankAccountQueryClass  `json:"queryClass" form:"queryClass"`
+	KeywordType constvar.BankAccountKeywordType `json:"keywordType"  form:"keywordType"`
+	Keyword     string                       `json:"keyword" form:"keyword"`
+}
diff --git a/model/request/faq.go b/model/request/faq.go
new file mode 100644
index 0000000..a7d18b7
--- /dev/null
+++ b/model/request/faq.go
@@ -0,0 +1,22 @@
+package request
+
+import (
+    "aps_crm/constvar"
+    "aps_crm/model"
+)
+
+type AddFaq struct {
+	model.Faq
+}
+
+type UpdateFaq struct {
+	Id int `json:"id"`
+	model.Faq
+}
+
+type GetFaqList struct {
+	PageInfo
+	QueryClass  constvar.FaqQueryClass  `json:"queryClass"`
+	KeywordType constvar.FaqKeywordType `json:"keywordType"`
+	Keyword     string                           `json:"keyword"`
+}
diff --git a/model/request/faultType.go b/model/request/faultType.go
new file mode 100644
index 0000000..06ec614
--- /dev/null
+++ b/model/request/faultType.go
@@ -0,0 +1,22 @@
+package request
+
+import (
+    "aps_crm/constvar"
+    "aps_crm/model"
+)
+
+type AddFaultType struct {
+	model.FaultType
+}
+
+type UpdateFaultType struct {
+	Id int `json:"id"`
+	model.FaultType
+}
+
+type GetFaultTypeList struct {
+	PageInfo
+	QueryClass  constvar.FaultTypeQueryClass  `json:"queryClass"`
+	KeywordType constvar.FaultTypeKeywordType `json:"keywordType"`
+	Keyword     string                           `json:"keyword"`
+}
diff --git a/model/request/file.go b/model/request/file.go
new file mode 100644
index 0000000..5b17b6b
--- /dev/null
+++ b/model/request/file.go
@@ -0,0 +1,23 @@
+package request
+
+import (
+	"aps_crm/constvar"
+	"aps_crm/model"
+)
+
+type AddFile struct {
+	SourceType string `gorm:"source_type" json:"sourceType" form:"sourceType" binding:"required"` // 闄勪欢鏉ユ簮
+	SourceId   int    `gorm:"source_id" json:"sourceId" form:"sourceId"  binding:"required"`      // 鏉ユ簮id
+}
+
+type UpdateFile struct {
+	Id int `json:"id"`
+	model.File
+}
+
+type GetFileList struct {
+	PageInfo
+	QueryClass  constvar.FileQueryClass  `json:"queryClass" form:"queryClass"`
+	KeywordType constvar.FileKeywordType `json:"keywordType"  form:"keywordType"`
+	Keyword     string                   `json:"keyword" form:"keyword"`
+}
diff --git a/model/request/paymentType.go b/model/request/paymentType.go
new file mode 100644
index 0000000..3c9e8ae
--- /dev/null
+++ b/model/request/paymentType.go
@@ -0,0 +1,22 @@
+package request
+
+import (
+    "aps_crm/constvar"
+    "aps_crm/model"
+)
+
+type AddPaymentType struct {
+	model.PaymentType
+}
+
+type UpdatePaymentType struct {
+	Id int `json:"id"`
+	model.PaymentType
+}
+
+type GetPaymentTypeList struct {
+	PageInfo
+	QueryClass  constvar.PaymentTypeQueryClass  `json:"queryClass" form:"queryClass"`
+	KeywordType constvar.PaymentTypeKeywordType `json:"keywordType"  form:"keywordType"`
+	Keyword     string                       `json:"keyword" form:"keyword"`
+}
diff --git a/model/request/priorityLevel.go b/model/request/priorityLevel.go
new file mode 100644
index 0000000..64701ba
--- /dev/null
+++ b/model/request/priorityLevel.go
@@ -0,0 +1,22 @@
+package request
+
+import (
+    "aps_crm/constvar"
+    "aps_crm/model"
+)
+
+type AddPriorityLevel struct {
+	model.PriorityLevel
+}
+
+type UpdatePriorityLevel struct {
+	Id int `json:"id"`
+	model.PriorityLevel
+}
+
+type GetPriorityLevelList struct {
+	PageInfo
+	QueryClass  constvar.PriorityLevelQueryClass  `json:"queryClass"`
+	KeywordType constvar.PriorityLevelKeywordType `json:"keywordType"`
+	Keyword     string                           `json:"keyword"`
+}
diff --git a/model/request/receipt.go b/model/request/receipt.go
new file mode 100644
index 0000000..677d508
--- /dev/null
+++ b/model/request/receipt.go
@@ -0,0 +1,22 @@
+package request
+
+import (
+    "aps_crm/constvar"
+    "aps_crm/model"
+)
+
+type AddReceipt struct {
+	model.Receipt
+}
+
+type UpdateReceipt struct {
+	Id int `json:"id"`
+	model.Receipt
+}
+
+type GetReceiptList struct {
+	PageInfo
+	QueryClass  constvar.ReceiptQueryClass  `json:"queryClass" form:"queryClass"`
+	KeywordType constvar.ReceiptKeywordType `json:"keywordType"  form:"keywordType"`
+	Keyword     string                       `json:"keyword" form:"keyword"`
+}
diff --git a/model/request/serviceCollectionPlan.go b/model/request/serviceCollectionPlan.go
new file mode 100644
index 0000000..b8e4f35
--- /dev/null
+++ b/model/request/serviceCollectionPlan.go
@@ -0,0 +1,18 @@
+package request
+
+import (
+	"aps_crm/model"
+)
+
+type AddServiceCollectionPlan struct {
+	List []*model.ServiceCollectionPlan
+}
+
+type UpdateServiceCollectionPlan struct {
+	Id int `json:"id"`
+	model.ServiceCollectionPlan
+}
+
+type GetServiceCollectionPlanList struct {
+	ServiceContractId int `gorm:"service_contract_id" form:"serviceContractId"` // 鏈嶅姟鍚堝悓id
+}
diff --git a/model/request/serviceContract.go b/model/request/serviceContract.go
index eec41e6..2ad8995 100644
--- a/model/request/serviceContract.go
+++ b/model/request/serviceContract.go
@@ -1,6 +1,7 @@
 package request
 
 import (
+	"aps_crm/constvar"
 	"aps_crm/model"
 )
 
@@ -34,7 +35,9 @@
 
 type GetServiceContractList struct {
 	PageInfo
-	Keyword string `json:"keyword"`
+	QueryClass  constvar.ServiceContractQueryClass  `json:"queryClass"`
+	KeywordType constvar.ServiceContractKeywordType `json:"keywordType"`
+	Keyword     string                              `json:"keyword"`
 }
 
 type DeleteserviceContract struct {
diff --git a/model/request/serviceFeeManage.go b/model/request/serviceFeeManage.go
index 17db48f..4ba0295 100644
--- a/model/request/serviceFeeManage.go
+++ b/model/request/serviceFeeManage.go
@@ -1,5 +1,7 @@
 package request
 
+import "aps_crm/constvar"
+
 type AddServiceFeeManage struct {
 	ServiceFeeManage
 	Client
@@ -20,7 +22,9 @@
 
 type GetServiceFeeManageList struct {
 	PageInfo
-	Keyword string `json:"keyword"`
+	QueryClass  constvar.ServiceFeeQueryClass  `json:"queryClass"`
+	KeywordType constvar.ServiceFeeKeywordType `json:"keywordType"`
+	Keyword     string                         `json:"keyword"`
 }
 
 type DeleteServiceFeeManage struct {
diff --git a/model/request/serviceFollowup.go b/model/request/serviceFollowup.go
index 861389d..e1b5764 100644
--- a/model/request/serviceFollowup.go
+++ b/model/request/serviceFollowup.go
@@ -1,5 +1,7 @@
 package request
 
+import "aps_crm/constvar"
+
 type AddServiceFollowup struct {
 	ServiceFollowup
 }
@@ -27,7 +29,8 @@
 
 type GetServiceFollowupList struct {
 	PageInfo
-	Keyword string `json:"keyword"`
+	KeywordType constvar.ServiceFollowupKeywordType `json:"keywordType"`
+	Keyword     string                              `json:"keyword"`
 }
 
 type DeleteServiceFollowup struct {
diff --git a/model/request/serviceOrder.go b/model/request/serviceOrder.go
new file mode 100644
index 0000000..869fd9a
--- /dev/null
+++ b/model/request/serviceOrder.go
@@ -0,0 +1,46 @@
+package request
+
+import (
+	"aps_crm/constvar"
+)
+
+type AddServiceOrder struct {
+	ServiceNumber   string  `gorm:"service_number" json:"serviceNumber"`      // 鏈嶅姟鍗曠紪鍙�
+	ClientId        int     `gorm:"client_id" json:"clientId"`                // 瀹㈡埛id
+	ContractId      int     `gorm:"contract_id" json:"contractId"`            // 鍚堝悓id
+	OrderId         int     `gorm:"order_id" json:"orderId"`                  // 閿�鍞鍗昳d
+	Subject         string  `gorm:"subject" json:"subject"`                   // 涓婚
+	ProductId       int     `gorm:"product_id" json:"productId"`              // 浜у搧id
+	ServiceTypeId   int     `gorm:"service_type_id" json:"serviceTypeId"`     // 鏈嶅姟鏂瑰紡id
+	ServiceManId    int     `gorm:"service_man_id" json:"serviceManId"`       // 鏈嶅姟浜哄憳
+	ContactId       int     `gorm:"linkman_id" json:"contactId"`              // 鑱旂郴浜篿d
+	Address         string  `gorm:"address" json:"address"`                   // 涓婇棬鍦板潃
+	PriorityLevelId int     `gorm:"priority_level_id" json:"priorityLevelId"` // 浼樺厛绾у埆id
+	AppointmentTime string  `gorm:"appointment_time" json:"appointmentTime"`  // 棰勭害涓婇棬鏃堕棿
+	SaleChanceId    int     `gorm:"sale_leads" json:"saleChanceId"`           // 閿�鍞満浼歩d
+	FaultTypeId     int     `gorm:"severity_id" json:"faultTypeId"`           // 鏁呴殰绫诲埆id
+	SeverityId      int     `gorm:"severity_id" json:"severity"`              // 涓ラ噸绋嬪害id
+	Status          int     `gorm:"status" json:"status"`                     // 澶勭悊鐘舵��
+	ExpectTime      string  `gorm:"expect_time" json:"expectTime"`            // 甯屾湜澶勭悊鏃堕棿
+	RealTime        string  `gorm:"real_time" json:"realTime"`                // 瀹為檯澶勭悊鏃堕棿
+	CarFare         float64 `gorm:"car_fare" json:"carFare"`                  // 浜ら�氳垂
+	ChargeAmount    float64 `gorm:"charge_amount" json:"chargeAmount"`        // 鏀惰垂閲戦
+	TimeSpentId     int     `gorm:"time_spent_id" json:"timeSpentId"`         // 鑺辫垂鏃堕棿
+	FaqId           int     `gorm:"problem_id" json:"faqId"`                  // 甯歌闂id
+	ProblemDesc     string  `gorm:"problem_desc" json:"problemDesc"`          // 闂鎻忚堪
+	Solution        string  `gorm:"solution" json:"solution"`                 // 瑙e喅鏂规硶
+	SolutionRemark  string  `gorm:"solution_remark" json:"solutionRemark"`    // 鍐呴儴澶囨敞
+	Remark          string  `gorm:"remark" json:"remark"`                     // 澶囨敞
+}
+
+type UpdateServiceOrder struct {
+	Id int `json:"id"`
+	AddServiceOrder
+}
+
+type GetServiceOrderList struct {
+	PageInfo
+	QueryClass  constvar.ServiceOrderQueryClass  `json:"queryClass"`
+	KeywordType constvar.ServiceOrderKeywordType `json:"keywordType"`
+	Keyword     string                           `json:"keyword"`
+}
diff --git a/model/request/serviceType.go b/model/request/serviceType.go
new file mode 100644
index 0000000..2eee204
--- /dev/null
+++ b/model/request/serviceType.go
@@ -0,0 +1,22 @@
+package request
+
+import (
+    "aps_crm/constvar"
+    "aps_crm/model"
+)
+
+type AddServiceType struct {
+	model.ServiceType
+}
+
+type UpdateServiceType struct {
+	Id int `json:"id"`
+	model.ServiceType
+}
+
+type GetServiceTypeList struct {
+	PageInfo
+	QueryClass  constvar.ServiceTypeQueryClass  `json:"queryClass"`
+	KeywordType constvar.ServiceTypeKeywordType `json:"keywordType"`
+	Keyword     string                           `json:"keyword"`
+}
diff --git a/model/request/severity.go b/model/request/severity.go
new file mode 100644
index 0000000..70c5eb7
--- /dev/null
+++ b/model/request/severity.go
@@ -0,0 +1,22 @@
+package request
+
+import (
+    "aps_crm/constvar"
+    "aps_crm/model"
+)
+
+type AddSeverity struct {
+	model.Severity
+}
+
+type UpdateSeverity struct {
+	Id int `json:"id"`
+	model.Severity
+}
+
+type GetSeverityList struct {
+	PageInfo
+	QueryClass  constvar.SeverityQueryClass  `json:"queryClass"`
+	KeywordType constvar.SeverityKeywordType `json:"keywordType"`
+	Keyword     string                           `json:"keyword"`
+}
diff --git a/model/request/timeSpent.go b/model/request/timeSpent.go
new file mode 100644
index 0000000..120461a
--- /dev/null
+++ b/model/request/timeSpent.go
@@ -0,0 +1,22 @@
+package request
+
+import (
+    "aps_crm/constvar"
+    "aps_crm/model"
+)
+
+type AddTimeSpent struct {
+	model.TimeSpent
+}
+
+type UpdateTimeSpent struct {
+	Id int `json:"id"`
+	model.TimeSpent
+}
+
+type GetTimeSpentList struct {
+	PageInfo
+	QueryClass  constvar.TimeSpentQueryClass  `json:"queryClass"`
+	KeywordType constvar.TimeSpentKeywordType `json:"keywordType"`
+	Keyword     string                           `json:"keyword"`
+}
diff --git a/model/response/common.go b/model/response/common.go
index b2cbd5a..03433be 100644
--- a/model/response/common.go
+++ b/model/response/common.go
@@ -6,3 +6,10 @@
 	Page     int         `json:"page"`
 	PageSize int         `json:"pageSize"`
 }
+
+type ListResponse struct {
+	Code  int         `json:"code"`
+	Msg   string      `json:"msg"`
+	Data  interface{} `json:"data"`
+	Count int64       `json:"count"`
+}
diff --git a/model/serviceCollectionPlan.go b/model/serviceCollectionPlan.go
new file mode 100644
index 0000000..be9da1b
--- /dev/null
+++ b/model/serviceCollectionPlan.go
@@ -0,0 +1,159 @@
+package model
+
+import (
+	"aps_crm/constvar"
+	"aps_crm/pkg/mysqlx"
+	"errors"
+	"fmt"
+	"gorm.io/gorm"
+)
+
+type (
+	// 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
+	}
+
+	// ServiceCollectionPlanSearch 鏈嶅姟鍚堝悓鏀舵璁″垝鎼滅储鏉′欢
+	ServiceCollectionPlanSearch struct {
+		ServiceCollectionPlan
+		Orm         *gorm.DB
+		QueryClass  constvar.ServiceCollectionPlanQueryClass
+		KeywordType constvar.ServiceCollectionPlanKeywordType
+		Keyword     string
+		PageNum     int
+		PageSize    int
+	}
+)
+
+func (ServiceCollectionPlan) TableName() string {
+	return "service_collection_plan"
+}
+
+func NewServiceCollectionPlanSearch() *ServiceCollectionPlanSearch {
+	return &ServiceCollectionPlanSearch{
+		Orm: mysqlx.GetDB(),
+	}
+}
+
+func (slf *ServiceCollectionPlanSearch) build() *gorm.DB {
+	var db = slf.Orm.Model(&ServiceCollectionPlan{})
+	if slf.Id != 0 {
+		db = db.Where("id = ?", slf.Id)
+	}
+
+	if slf.ServiceContractId != 0 {
+		db = db.Where("service_contract_id = ?", slf.ServiceContractId)
+	}
+
+	return db
+}
+
+func (slf *ServiceCollectionPlanSearch) Create(record *ServiceCollectionPlan) error {
+	var db = slf.build()
+	return db.Create(record).Error
+}
+
+func (slf *ServiceCollectionPlanSearch) CreateBatch(records []*ServiceCollectionPlan) error {
+	var db = slf.build()
+	return db.Create(records).Error
+}
+
+func (slf *ServiceCollectionPlanSearch) Delete() error {
+	var db = slf.build()
+	return db.Delete(&ServiceCollectionPlan{}).Error
+}
+
+func (slf *ServiceCollectionPlanSearch) Update(record *ServiceCollectionPlan) error {
+	var db = slf.build()
+	return db.Updates(record).Error
+}
+
+func (slf *ServiceCollectionPlanSearch) FindAll() ([]*ServiceCollectionPlan, error) {
+	var db = slf.build()
+	var record = make([]*ServiceCollectionPlan, 0)
+	err := db.Find(&record).Error
+	return record, err
+}
+
+func (slf *ServiceCollectionPlanSearch) SetId(id int) *ServiceCollectionPlanSearch {
+	slf.Id = id
+	return slf
+}
+
+func (slf *ServiceCollectionPlanSearch) SetOrm(tx *gorm.DB) *ServiceCollectionPlanSearch {
+	slf.Orm = tx
+	return slf
+}
+
+func (slf *ServiceCollectionPlanSearch) SetServiceContractId(id int) *ServiceCollectionPlanSearch {
+	slf.ServiceContractId = id
+	return slf
+}
+
+func (slf *ServiceCollectionPlanSearch) First() (*ServiceCollectionPlan, error) {
+	var db = slf.build()
+	var record = new(ServiceCollectionPlan)
+	err := db.First(record).Error
+	return record, err
+}
+
+func (slf *ServiceCollectionPlanSearch) Updates(values interface{}) error {
+	var db = slf.build()
+	return db.Updates(values).Error
+}
+
+func (slf *ServiceCollectionPlanSearch) Save(record *ServiceCollectionPlan) 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 *ServiceCollectionPlanSearch) Find() ([]*ServiceCollectionPlan, int64, error) {
+	var db = slf.build()
+	var records = make([]*ServiceCollectionPlan, 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 *ServiceCollectionPlanSearch) 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 := []*ServiceCollectionPlan{}
+	return slf.CreateBatch(records)
+}
diff --git a/model/serviceContract.go b/model/serviceContract.go
index c9f415a..5b20512 100644
--- a/model/serviceContract.go
+++ b/model/serviceContract.go
@@ -1,6 +1,7 @@
 package model
 
 import (
+	"aps_crm/constvar"
 	"aps_crm/pkg/mysqlx"
 	"gorm.io/gorm"
 	"time"
@@ -31,11 +32,13 @@
 	ServiceContractSearch struct {
 		ServiceContract
 
-		Orm      *gorm.DB
-		Keyword  string
-		OrderBy  string
-		PageNum  int
-		PageSize int
+		Orm         *gorm.DB
+		QueryClass  constvar.ServiceContractQueryClass
+		KeywordType constvar.ServiceContractKeywordType
+		Keyword     interface{}
+		OrderBy     string
+		PageNum     int
+		PageSize    int
 	}
 )
 
@@ -51,14 +54,43 @@
 
 func (slf *ServiceContractSearch) build() *gorm.DB {
 	var db = slf.Orm.Model(&ServiceContract{})
-	if slf.Keyword != "" {
-		db = db.Where("name LIKE ?", "%"+slf.Keyword+"%")
-	}
-	if slf.Keyword != "" {
-		db = db.Where("name LIKE ?", "%"+slf.Keyword+"%")
-	}
 	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
@@ -110,6 +142,16 @@
 	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
diff --git a/model/serviceFeeManage.go b/model/serviceFeeManage.go
index 4cea8e9..16ec527 100644
--- a/model/serviceFeeManage.go
+++ b/model/serviceFeeManage.go
@@ -1,6 +1,7 @@
 package model
 
 import (
+	"aps_crm/constvar"
 	"aps_crm/pkg/mysqlx"
 	"gorm.io/gorm"
 	"time"
@@ -20,13 +21,13 @@
 
 	ServiceFeeManageSearch struct {
 		ServiceFeeManage
-
-				Orm      *gorm.DB
-		Keyword  string
-		OrderBy  string
-		PageNum  int
-		PageSize int
-
+		Orm         *gorm.DB
+		QueryClass  constvar.ServiceFeeQueryClass
+		KeywordType constvar.ServiceFeeKeywordType
+		Keyword     string
+		OrderBy     string
+		PageNum     int
+		PageSize    int
 	}
 )
 
@@ -46,14 +47,54 @@
 
 func (slf *ServiceFeeManageSearch) build() *gorm.DB {
 	var db = slf.Orm.Model(&ServiceFeeManage{})
-	if slf.Keyword != "" {
-		db = db.Where("name LIKE ?", "%"+slf.Keyword+"%")
-	}
 	if slf.Id != 0 {
 		db.Where("id = ?", slf.Id)
 	}
 	if slf.ClientId != 0 {
 		db.Where("client_id = ?", slf.ClientId)
+	}
+	switch slf.QueryClass {
+	case constvar.ServiceFeeQueryClassExpireLessThen60Days:
+		db = db.Where("latest_date > ? and latest_date < ?", time.Now(), time.Now().AddDate(0, 0, 60))
+	case constvar.ServiceFeeQueryClassExpireLessThen30Days:
+		db = db.Where("latest_date > ? and latest_date < ?", time.Now(), time.Now().AddDate(0, 0, 30))
+	case constvar.ServiceFeeQueryClassExpireAboutTo60Day:
+		db = db.Where("latest_date = ?", time.Now().AddDate(0, 0, -60))
+	case constvar.ServiceFeeQueryClassExpireAboutTo30Day:
+		db = db.Where("latest_date = ?", time.Now().AddDate(0, 0, -30))
+	case constvar.ServiceFeeQueryClassExpired:
+		db = db.Where("latest_date < ?", time.Now())
+	case constvar.ServiceFeeQueryClassNoService:
+		db = db.Where("latest_date < ?", time.Now().AddDate(0, 0, -60))
+
+	}
+
+	switch slf.KeywordType {
+	case constvar.ServiceFeeKeywordCustomerName:
+		db.Joins("left join clients on clients.id = service_fee_manage.client_id")
+		db = db.Where("clients.name = ?", slf.Keyword)
+	case constvar.ServiceFeeKeywordCustomerType:
+		db.Joins("left join clients on clients.id = service_fee_manage.client_id")
+		db = db.Where("clients.client_type_id = ?", slf.Keyword)
+	case constvar.ServiceFeeKeywordSalesPrincipal:
+		db.Joins("left join clients on clients.id = service_fee_manage.client_id")
+		db = db.Where("clients.member_id = ?", slf.Keyword)
+	case constvar.ServiceFeeKeywordCustomerScale:
+		db.Joins("left join clients on clients.id = service_fee_manage.client_id")
+		db = db.Where("clients.enterprise_scale_id = ?", slf.Keyword)
+	case constvar.ServiceFeeKeywordClientLevel:
+		db.Joins("left join clients on clients.id = service_fee_manage.client_id")
+		db = db.Where("clients.client_level_id = ?", slf.Keyword)
+	case constvar.ServiceFeeKeywordCustomerNo:
+		db.Joins("left join clients on clients.id = service_fee_manage.client_id")
+		db = db.Where("clients.number = ?", slf.Keyword)
+	case constvar.ServiceFeeKeywordCustomerStatus:
+		db.Joins("left join clients on clients.id = service_fee_manage.client_id")
+		db = db.Where("clients.client_status_id = ?", slf.Keyword)
+	case constvar.ServiceFeeKeywordServiceEndDate:
+		db = db.Where("latest_date = ?", slf.Keyword)
+	case constvar.ServiceFeeKeywordProductName:
+		//todo
 	}
 
 	return db
@@ -76,6 +117,21 @@
 
 func (slf *ServiceFeeManageSearch) SetId(id int) *ServiceFeeManageSearch {
 	slf.Id = id
+	return slf
+}
+
+func (slf *ServiceFeeManageSearch) SetKeywordType(keyword constvar.ServiceFeeKeywordType) *ServiceFeeManageSearch {
+	slf.KeywordType = keyword
+	return slf
+}
+
+func (slf *ServiceFeeManageSearch) SetQueryClass(queryClass constvar.ServiceFeeQueryClass) *ServiceFeeManageSearch {
+	slf.QueryClass = queryClass
+	return slf
+}
+
+func (slf *ServiceFeeManageSearch) SetKeyword(keyword string) *ServiceFeeManageSearch {
+	slf.Keyword = keyword
 	return slf
 }
 
@@ -103,11 +159,6 @@
 
 	err := db.Preload("Client").Find(&records).Error
 	return records, total, err
-}
-
-func (slf *ServiceFeeManageSearch) SetKeyword(keyword string) *ServiceFeeManageSearch {
-	slf.Keyword = keyword
-	return slf
 }
 
 func (slf *ServiceFeeManageSearch) SetPage(page, size int) *ServiceFeeManageSearch {
diff --git a/model/serviceFollowup.go b/model/serviceFollowup.go
index 118ae24..d2d4ada 100644
--- a/model/serviceFollowup.go
+++ b/model/serviceFollowup.go
@@ -1,6 +1,7 @@
 package model
 
 import (
+	"aps_crm/constvar"
 	"aps_crm/pkg/mysqlx"
 	"gorm.io/gorm"
 )
@@ -12,6 +13,7 @@
 		Number               string               `json:"number" gorm:"column:number;type:varchar(255);comment:鍚堝悓缂栧彿"`
 		ContactId            int                  `json:"contactId" gorm:"column:contact_id;type:int;comment:鑱旂郴浜篿d"`
 		ServiceId            int                  `json:"serviceId" gorm:"column:service_id;type:int;comment:瀹㈡埛鏈嶅姟鍗昳d"`
+		ServiceOrder         ServiceOrder         `gorm:"foreignKey:ServiceId"`
 		CustomerServiceSheet CustomerServiceSheet `json:"customerServiceSheet" gorm:"foreignKey:ServiceId"`
 		MemberId             int                  `json:"memberId" gorm:"column:member_id;type:int;comment:鏈嶅姟浜哄憳id"`
 		PlanId               int                  `json:"planId" gorm:"column:plan_id;type:int;comment:鏈嶅姟璁″垝id"`
@@ -28,13 +30,12 @@
 
 	ServiceFollowupSearch struct {
 		ServiceFollowup
-
-				Orm      *gorm.DB
-		Keyword  string
-		OrderBy  string
-		PageNum  int
-		PageSize int
-
+		Orm         *gorm.DB
+		KeywordType constvar.ServiceFollowupKeywordType
+		Keyword     interface{}
+		OrderBy     string
+		PageNum     int
+		PageSize    int
 	}
 )
 
@@ -50,11 +51,24 @@
 
 func (slf *ServiceFollowupSearch) build() *gorm.DB {
 	var db = slf.Orm.Model(&ServiceFollowup{})
-	if slf.Keyword != "" {
-		db = db.Where("name LIKE ?", "%"+slf.Keyword+"%")
-	}
 	if slf.Id != 0 {
 		db = db.Where("id = ?", slf.Id)
+	}
+
+	switch slf.KeywordType {
+	case constvar.ServiceFollowupKeywordFollowupNo:
+		db = db.Where("number = ?", slf.Keyword)
+	case constvar.ServiceFollowupKeywordCustomerName:
+		db = db.Where("client_id = ?", slf.Keyword)
+	case constvar.ServiceFollowupKeywordContactName:
+		db = db.Where("contact_id = ?", slf.Keyword)
+	case constvar.ServiceFollowupKeywordCustomerServiceNo:
+		db = db.Where("service_id = ?", slf.Keyword)
+	case constvar.ServiceFollowupKeywordVisitor:
+		db = db.Where("member_id = ?", slf.Keyword)
+	case constvar.ServiceFollowupKeywordSatisfactionDegree:
+		db = db.Where("satisfaction_id = ?", slf.Keyword)
+
 	}
 
 	return db
@@ -97,7 +111,7 @@
 		db = db.Limit(slf.PageSize).Offset((slf.PageNum - 1) * slf.PageSize)
 	}
 
-	err := db.Preload("CustomerServiceSheet").Find(&records).Error
+	err := db.Preload("CustomerServiceSheet").Preload("ServiceOrder").Find(&records).Error
 	return records, total, err
 }
 
@@ -106,7 +120,10 @@
 	return slf
 }
 
-// 鍙兘鎬� 甯佺 褰撳墠鐘舵�侊紙閿�鍞満浼氾級
+func (slf *ServiceFollowupSearch) SetKeywordType(keyword constvar.ServiceFollowupKeywordType) *ServiceFollowupSearch {
+	slf.KeywordType = keyword
+	return slf
+}
 
 func (slf *ServiceFollowupSearch) SetKeyword(keyword string) *ServiceFollowupSearch {
 	slf.Keyword = keyword
diff --git a/model/serviceOrder.go b/model/serviceOrder.go
new file mode 100644
index 0000000..4e30c5a
--- /dev/null
+++ b/model/serviceOrder.go
@@ -0,0 +1,171 @@
+package model
+
+import (
+	"aps_crm/constvar"
+	"aps_crm/pkg/mysqlx"
+	"errors"
+	"fmt"
+	"gorm.io/gorm"
+)
+
+type (
+	// ServiceOrder 鏈嶅姟鍗�
+	ServiceOrder struct {
+		Id              int           `json:"id" gorm:"column:id;primary_key;AUTO_INCREMENT"`
+		ServiceNumber   string        `gorm:"service_number" json:"serviceNumber"` // 鏈嶅姟鍗曠紪鍙�
+		ClientId        int           `gorm:"client_id" json:"clientId"`           // 瀹㈡埛id
+		Client          Client        `gorm:"foreignKey:ClientId"`
+		ContractId      int           `gorm:"contract_id" json:"contractId"` // 鍚堝悓id
+		Contract        Contract      `gorm:"foreignKey:ContractId"`
+		OrderId         int           `gorm:"order_id" json:"orderId"` // 閿�鍞鍗昳d
+		OrderManage     OrderManage   `gorm:"foreignKey:OrderId"`
+		Subject         string        `gorm:"subject" json:"subject"`      // 涓婚
+		ProductId       int           `gorm:"product_id" json:"productId"` // 浜у搧id
+		Product         Product       `gorm:"foreignKey:ProductId"`
+		ServiceTypeId   int           `gorm:"service_type_id" json:"serviceTypeId"` // 鏈嶅姟鏂瑰紡id
+		ServiceType     ServiceType   `gorm:"foreignKey:ServiceTypeId"`
+		ServiceManId    int           `gorm:"service_man_id" json:"serviceManId"` // 鏈嶅姟浜哄憳
+		ContactId       int           `gorm:"linkman_id" json:"contactId"`        // 鑱旂郴浜篿d
+		Contact         Contact       `gorm:"foreignKey:ContactId"`
+		Address         string        `gorm:"address" json:"address"`                   // 涓婇棬鍦板潃
+		PriorityLevelId int           `gorm:"priority_level_id" json:"priorityLevelId"` // 浼樺厛绾у埆id
+		PriorityLevel   PriorityLevel `gorm:"foreignKey:PriorityLevelId"`
+		AppointmentTime string        `gorm:"appointment_time" json:"appointmentTime"` // 棰勭害涓婇棬鏃堕棿
+		SaleChanceId    int           `gorm:"sale_leads" json:"saleChanceId"`          // 閿�鍞満浼歩d
+
+		SaleChance     SaleChance `gorm:"foreignKey:SaleChanceId"`
+		FaultTypeId    int        `gorm:"severity_id" json:"faultTypeId"` // 鏁呴殰绫诲埆id
+		FaultType      FaultType  `gorm:"foreignKey:FaultTypeId"`
+		SeverityId     int        `gorm:"severity_id" json:"severity"` // 涓ラ噸绋嬪害id
+		Severity       Severity   `gorm:"foreignKey:SeverityId"`
+		Status         int        `gorm:"status" json:"status"`              // 澶勭悊鐘舵��
+		ExpectTime     string     `gorm:"expect_time" json:"expectTime"`     // 甯屾湜澶勭悊鏃堕棿
+		RealTime       string     `gorm:"real_time" json:"realTime"`         // 瀹為檯澶勭悊鏃堕棿
+		CarFare        float64    `gorm:"car_fare" json:"carFare"`           // 浜ら�氳垂
+		ChargeAmount   float64    `gorm:"charge_amount" json:"chargeAmount"` // 鏀惰垂閲戦
+		TimeSpentId    int        `gorm:"time_spent_id" json:"timeSpentId"`  // 鑺辫垂鏃堕棿
+		TimeSpent      TimeSpent  `gorm:"foreignKey:TimeSpentId"`
+		FaqId          int        `gorm:"problem_id" json:"faqId"` // 甯歌闂id
+		Faq            Faq        `gorm:"foreignKey:FaqId"`
+		ProblemDesc    string     `gorm:"problem_desc" json:"problemDesc"`       // 闂鎻忚堪
+		Solution       string     `gorm:"solution" json:"solution"`              // 瑙e喅鏂规硶
+		SolutionRemark string     `gorm:"solution_remark" json:"solutionRemark"` // 鍐呴儴澶囨敞
+		Remark         string     `gorm:"remark" json:"remark"`                  // 澶囨敞
+	}
+
+	// ServiceOrderSearch 鏈嶅姟鍗曟悳绱㈡潯浠�
+	ServiceOrderSearch struct {
+		ServiceOrder
+		Orm         *gorm.DB
+		QueryClass  constvar.ServiceOrderQueryClass
+		KeywordType constvar.ServiceOrderKeywordType
+		Keyword     string
+		PageNum     int
+		PageSize    int
+		Preload     bool
+	}
+)
+
+func (ServiceOrder) TableName() string {
+	return "service_order"
+}
+
+func NewServiceOrderSearch() *ServiceOrderSearch {
+	return &ServiceOrderSearch{
+		Orm: mysqlx.GetDB(),
+	}
+}
+
+func (slf *ServiceOrderSearch) build() *gorm.DB {
+	var db = slf.Orm.Model(&ServiceOrder{})
+	if slf.Id != 0 {
+		db = db.Where("id = ?", slf.Id)
+	}
+	if slf.Preload {
+		db = db.
+			Preload("Client").
+			Preload("Contract").
+			Preload("OrderManage").
+			Preload("Product").
+			Preload("ServiceType").
+			Preload("Contact").
+			Preload("SaleChance").
+			Preload("PriorityLevel").
+			Preload("Severity").
+			Preload("Faq")
+	}
+
+	return db
+}
+
+func (slf *ServiceOrderSearch) Create(record *ServiceOrder) error {
+	var db = slf.build()
+	return db.Create(record).Error
+}
+
+func (slf *ServiceOrderSearch) Delete() error {
+	var db = slf.build()
+	return db.Delete(&ServiceOrder{}).Error
+}
+
+func (slf *ServiceOrderSearch) Update(record *ServiceOrder) error {
+	var db = slf.build()
+	return db.Updates(record).Error
+}
+
+func (slf *ServiceOrderSearch) FindAll() ([]*ServiceOrder, error) {
+	var db = slf.build()
+	var record = make([]*ServiceOrder, 0)
+	err := db.Find(&record).Error
+	return record, err
+}
+
+func (slf *ServiceOrderSearch) SetId(id int) *ServiceOrderSearch {
+	slf.Id = id
+	return slf
+}
+
+func (slf *ServiceOrderSearch) SetPreload(preload bool) *ServiceOrderSearch {
+	slf.Preload = preload
+	return slf
+}
+
+func (slf *ServiceOrderSearch) First() (*ServiceOrder, error) {
+	var db = slf.build()
+	var record = new(ServiceOrder)
+	err := db.First(record).Error
+	return record, err
+}
+
+func (slf *ServiceOrderSearch) Updates(values interface{}) error {
+	var db = slf.build()
+	return db.Updates(values).Error
+}
+
+func (slf *ServiceOrderSearch) Save(record *ServiceOrder) 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 *ServiceOrderSearch) Find() ([]*ServiceOrder, int64, error) {
+	var db = slf.build()
+	var records = make([]*ServiceOrder, 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
+}
diff --git a/model/serviceType.go b/model/serviceType.go
new file mode 100644
index 0000000..e5f7214
--- /dev/null
+++ b/model/serviceType.go
@@ -0,0 +1,135 @@
+package model
+
+import (
+	"aps_crm/constvar"
+	"aps_crm/pkg/mysqlx"
+	"errors"
+	"fmt"
+	"gorm.io/gorm"
+)
+
+type (
+	// ServiceType 鏈嶅姟鏂瑰紡
+	ServiceType struct {
+		Id   int    `json:"id" gorm:"column:id;primary_key;AUTO_INCREMENT"`
+		Name   string    `json:"name" gorm:"column:name"`
+	}
+
+	// ServiceTypeSearch 鏈嶅姟鏂瑰紡鎼滅储鏉′欢
+	ServiceTypeSearch struct {
+		ServiceType
+		Orm *gorm.DB
+        QueryClass  constvar.ServiceTypeQueryClass
+        KeywordType constvar.ServiceTypeKeywordType
+        Keyword     string
+        PageNum  int
+        PageSize int
+	}
+)
+
+func (ServiceType) TableName() string {
+	return "service_type"
+}
+
+func NewServiceTypeSearch() *ServiceTypeSearch {
+	return &ServiceTypeSearch{
+		Orm: mysqlx.GetDB(),
+	}
+}
+
+func (slf *ServiceTypeSearch) build() *gorm.DB {
+	var db = slf.Orm.Model(&ServiceType{})
+	if slf.Id != 0 {
+		db = db.Where("id = ?", slf.Id)
+	}
+
+	return db
+}
+
+func (slf *ServiceTypeSearch) Create(record *ServiceType) error {
+	var db = slf.build()
+	return db.Create(record).Error
+}
+
+func (slf *ServiceTypeSearch) CreateBatch(records []*ServiceType) error {
+	var db = slf.build()
+	return db.Create(records).Error
+}
+
+func (slf *ServiceTypeSearch) Delete() error {
+	var db = slf.build()
+	return db.Delete(&ServiceType{}).Error
+}
+
+func (slf *ServiceTypeSearch) Update(record *ServiceType) error {
+	var db = slf.build()
+	return db.Updates(record).Error
+}
+
+func (slf *ServiceTypeSearch) FindAll() ([]*ServiceType, error) {
+	var db = slf.build()
+	var record = make([]*ServiceType, 0)
+	err := db.Find(&record).Error
+	return record, err
+}
+
+func (slf *ServiceTypeSearch) SetId(id int) *ServiceTypeSearch {
+	slf.Id = id
+	return slf
+}
+
+func (slf *ServiceTypeSearch) First() (*ServiceType, error) {
+	var db = slf.build()
+	var record = new(ServiceType)
+	err := db.First(record).Error
+	return record, err
+}
+
+func (slf *ServiceTypeSearch) Updates(values interface{}) error {
+	var db = slf.build()
+	return db.Updates(values).Error
+}
+
+func (slf *ServiceTypeSearch) Save(record *ServiceType) 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 *ServiceTypeSearch) Find() ([]*ServiceType, int64, error) {
+	var db = slf.build()
+	var records = make([]*ServiceType, 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 *ServiceTypeSearch) 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 := []*ServiceType{}
+	return slf.CreateBatch(records)
+}
diff --git a/model/severity.go b/model/severity.go
new file mode 100644
index 0000000..291daa3
--- /dev/null
+++ b/model/severity.go
@@ -0,0 +1,135 @@
+package model
+
+import (
+	"aps_crm/constvar"
+	"aps_crm/pkg/mysqlx"
+	"errors"
+	"fmt"
+	"gorm.io/gorm"
+)
+
+type (
+	// Severity 涓ラ噸绋嬪害
+	Severity struct {
+		Id   int    `json:"id" gorm:"column:id;primary_key;AUTO_INCREMENT"`
+		Name   string    `json:"name" gorm:"column:name"`
+	}
+
+	// SeveritySearch 涓ラ噸绋嬪害鎼滅储鏉′欢
+	SeveritySearch struct {
+		Severity
+		Orm *gorm.DB
+        QueryClass  constvar.SeverityQueryClass
+        KeywordType constvar.SeverityKeywordType
+        Keyword     string
+        PageNum  int
+        PageSize int
+	}
+)
+
+func (Severity) TableName() string {
+	return "severity"
+}
+
+func NewSeveritySearch() *SeveritySearch {
+	return &SeveritySearch{
+		Orm: mysqlx.GetDB(),
+	}
+}
+
+func (slf *SeveritySearch) build() *gorm.DB {
+	var db = slf.Orm.Model(&Severity{})
+	if slf.Id != 0 {
+		db = db.Where("id = ?", slf.Id)
+	}
+
+	return db
+}
+
+func (slf *SeveritySearch) Create(record *Severity) error {
+	var db = slf.build()
+	return db.Create(record).Error
+}
+
+func (slf *SeveritySearch) CreateBatch(records []*Severity) error {
+	var db = slf.build()
+	return db.Create(records).Error
+}
+
+func (slf *SeveritySearch) Delete() error {
+	var db = slf.build()
+	return db.Delete(&Severity{}).Error
+}
+
+func (slf *SeveritySearch) Update(record *Severity) error {
+	var db = slf.build()
+	return db.Updates(record).Error
+}
+
+func (slf *SeveritySearch) FindAll() ([]*Severity, error) {
+	var db = slf.build()
+	var record = make([]*Severity, 0)
+	err := db.Find(&record).Error
+	return record, err
+}
+
+func (slf *SeveritySearch) SetId(id int) *SeveritySearch {
+	slf.Id = id
+	return slf
+}
+
+func (slf *SeveritySearch) First() (*Severity, error) {
+	var db = slf.build()
+	var record = new(Severity)
+	err := db.First(record).Error
+	return record, err
+}
+
+func (slf *SeveritySearch) Updates(values interface{}) error {
+	var db = slf.build()
+	return db.Updates(values).Error
+}
+
+func (slf *SeveritySearch) Save(record *Severity) 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 *SeveritySearch) Find() ([]*Severity, int64, error) {
+	var db = slf.build()
+	var records = make([]*Severity, 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 *SeveritySearch) 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 := []*Severity{}
+	return slf.CreateBatch(records)
+}
diff --git a/model/timeSpent.go b/model/timeSpent.go
new file mode 100644
index 0000000..de29623
--- /dev/null
+++ b/model/timeSpent.go
@@ -0,0 +1,135 @@
+package model
+
+import (
+	"aps_crm/constvar"
+	"aps_crm/pkg/mysqlx"
+	"errors"
+	"fmt"
+	"gorm.io/gorm"
+)
+
+type (
+	// TimeSpent 鑺辫垂鏃堕棿
+	TimeSpent struct {
+		Id   int    `json:"id" gorm:"column:id;primary_key;AUTO_INCREMENT"`
+		Name   string    `json:"name" gorm:"column:name"`
+	}
+
+	// TimeSpentSearch 鑺辫垂鏃堕棿鎼滅储鏉′欢
+	TimeSpentSearch struct {
+		TimeSpent
+		Orm *gorm.DB
+        QueryClass  constvar.TimeSpentQueryClass
+        KeywordType constvar.TimeSpentKeywordType
+        Keyword     string
+        PageNum  int
+        PageSize int
+	}
+)
+
+func (TimeSpent) TableName() string {
+	return "time_spent"
+}
+
+func NewTimeSpentSearch() *TimeSpentSearch {
+	return &TimeSpentSearch{
+		Orm: mysqlx.GetDB(),
+	}
+}
+
+func (slf *TimeSpentSearch) build() *gorm.DB {
+	var db = slf.Orm.Model(&TimeSpent{})
+	if slf.Id != 0 {
+		db = db.Where("id = ?", slf.Id)
+	}
+
+	return db
+}
+
+func (slf *TimeSpentSearch) Create(record *TimeSpent) error {
+	var db = slf.build()
+	return db.Create(record).Error
+}
+
+func (slf *TimeSpentSearch) CreateBatch(records []*TimeSpent) error {
+	var db = slf.build()
+	return db.Create(records).Error
+}
+
+func (slf *TimeSpentSearch) Delete() error {
+	var db = slf.build()
+	return db.Delete(&TimeSpent{}).Error
+}
+
+func (slf *TimeSpentSearch) Update(record *TimeSpent) error {
+	var db = slf.build()
+	return db.Updates(record).Error
+}
+
+func (slf *TimeSpentSearch) FindAll() ([]*TimeSpent, error) {
+	var db = slf.build()
+	var record = make([]*TimeSpent, 0)
+	err := db.Find(&record).Error
+	return record, err
+}
+
+func (slf *TimeSpentSearch) SetId(id int) *TimeSpentSearch {
+	slf.Id = id
+	return slf
+}
+
+func (slf *TimeSpentSearch) First() (*TimeSpent, error) {
+	var db = slf.build()
+	var record = new(TimeSpent)
+	err := db.First(record).Error
+	return record, err
+}
+
+func (slf *TimeSpentSearch) Updates(values interface{}) error {
+	var db = slf.build()
+	return db.Updates(values).Error
+}
+
+func (slf *TimeSpentSearch) Save(record *TimeSpent) 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 *TimeSpentSearch) Find() ([]*TimeSpent, int64, error) {
+	var db = slf.build()
+	var records = make([]*TimeSpent, 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 *TimeSpentSearch) 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 := []*TimeSpent{}
+	return slf.CreateBatch(records)
+}
diff --git a/pkg/contextx/contextx.go b/pkg/contextx/contextx.go
index ff1d839..95a29c6 100644
--- a/pkg/contextx/contextx.go
+++ b/pkg/contextx/contextx.go
@@ -83,6 +83,10 @@
 	slf.Result(errCode, map[string]interface{}{}, ecode.GetMsg(errCode))
 }
 
+func (slf *Context) FailWithMsg(errCode int, msg string) {
+	slf.Result(errCode, map[string]interface{}{}, msg)
+}
+
 func (slf *Context) FailWithDetailed(errCode int, data interface{}) {
 	slf.Result(errCode, data, ecode.GetMsg(errCode))
 }
diff --git a/pkg/httpx/httpx.go b/pkg/httpx/httpx.go
index 94336ff..00ed1c4 100644
--- a/pkg/httpx/httpx.go
+++ b/pkg/httpx/httpx.go
@@ -5,6 +5,7 @@
 	"encoding/json"
 	"io/ioutil"
 	"net/http"
+	"os"
 	"time"
 )
 
@@ -39,3 +40,16 @@
 	}
 	return respBytes, nil
 }
+
+func GetMimeType(filePath string) string {
+	file, err := os.Open(filePath)
+	if err != nil {
+		return ""
+	}
+	buffer := make([]byte, 512)
+	_, _ = file.Read(buffer)
+	if len(buffer) == 0 {
+		return ""
+	}
+	return http.DetectContentType(buffer)
+}
diff --git a/pkg/safe/safe.go b/pkg/safe/safe.go
index 95855cf..a3e4ee4 100644
--- a/pkg/safe/safe.go
+++ b/pkg/safe/safe.go
@@ -1,7 +1,7 @@
 package safe
 
 import (
-	"aps_admin/pkg/logx"
+	"aps_crm/pkg/logx"
 	"runtime/debug"
 )
 
diff --git a/pkg/structx/structx.go b/pkg/structx/structx.go
new file mode 100644
index 0000000..e038656
--- /dev/null
+++ b/pkg/structx/structx.go
@@ -0,0 +1,16 @@
+package structx
+
+import "encoding/json"
+
+func AssignTo(from interface{}, to interface{}) error {
+	data, err := json.Marshal(from)
+	if err != nil {
+		return err
+	}
+
+	err = json.Unmarshal(data, to)
+	if err != nil {
+		return err
+	}
+	return nil
+}
diff --git a/router/bankAccount.go b/router/bankAccount.go
new file mode 100644
index 0000000..d5adf98
--- /dev/null
+++ b/router/bankAccount.go
@@ -0,0 +1,17 @@
+package router
+
+import (
+	v1 "aps_crm/api/v1"
+	"github.com/gin-gonic/gin"
+)
+
+func InitBankAccountRouter(router *gin.RouterGroup) {
+	BankAccountRouter := router.Group("bankAccount")
+	BankAccountApi := v1.BankAccountApi{}
+	{
+		BankAccountRouter.POST("add", BankAccountApi.Add)             // 娣诲姞閾惰璐︽埛
+		BankAccountRouter.DELETE("delete/:id", BankAccountApi.Delete) // 鍒犻櫎閾惰璐︽埛
+		BankAccountRouter.PUT("update", BankAccountApi.Update)        // 鏇存柊閾惰璐︽埛
+		BankAccountRouter.GET("list", BankAccountApi.List)            // 鑾峰彇閾惰璐︽埛鍒楄〃
+	}
+}
diff --git a/router/faq.go b/router/faq.go
new file mode 100644
index 0000000..7d13fd1
--- /dev/null
+++ b/router/faq.go
@@ -0,0 +1,17 @@
+package router
+
+import (
+	v1 "aps_crm/api/v1"
+	"github.com/gin-gonic/gin"
+)
+
+func InitFaqRouter(router *gin.RouterGroup) {
+	FaqRouter := router.Group("faq")
+	FaqApi := v1.FaqApi{}
+	{
+		FaqRouter.POST("add", FaqApi.Add)             // 娣诲姞甯歌闂
+		FaqRouter.DELETE("delete/:id", FaqApi.Delete) // 鍒犻櫎甯歌闂
+		FaqRouter.PUT("update", FaqApi.Update)        // 鏇存柊甯歌闂
+		FaqRouter.GET("list", FaqApi.List)            // 鑾峰彇甯歌闂鍒楄〃
+	}
+}
diff --git a/router/faultType.go b/router/faultType.go
new file mode 100644
index 0000000..4d8d1d5
--- /dev/null
+++ b/router/faultType.go
@@ -0,0 +1,17 @@
+package router
+
+import (
+	v1 "aps_crm/api/v1"
+	"github.com/gin-gonic/gin"
+)
+
+func InitFaultTypeRouter(router *gin.RouterGroup) {
+	FaultTypeRouter := router.Group("faultType")
+	FaultTypeApi := v1.FaultTypeApi{}
+	{
+		FaultTypeRouter.POST("add", FaultTypeApi.Add)             // 娣诲姞鏁呴殰绫诲埆
+		FaultTypeRouter.DELETE("delete/:id", FaultTypeApi.Delete) // 鍒犻櫎鏁呴殰绫诲埆
+		FaultTypeRouter.PUT("update", FaultTypeApi.Update)        // 鏇存柊鏁呴殰绫诲埆
+		FaultTypeRouter.GET("list", FaultTypeApi.List)            // 鑾峰彇鏁呴殰绫诲埆鍒楄〃
+	}
+}
diff --git a/router/file.go b/router/file.go
new file mode 100644
index 0000000..60757b4
--- /dev/null
+++ b/router/file.go
@@ -0,0 +1,15 @@
+package router
+
+import (
+	v1 "aps_crm/api/v1"
+	"github.com/gin-gonic/gin"
+)
+
+func InitFileRouter(router *gin.RouterGroup) {
+	FileRouter := router.Group("file")
+	FileApi := v1.FileApi{}
+	{
+		FileRouter.POST("add", FileApi.Add)             // 娣诲姞闄勪欢
+		FileRouter.DELETE("delete/:id", FileApi.Delete) // 鍒犻櫎闄勪欢
+	}
+}
diff --git a/router/index.go b/router/index.go
index 7062b5a..e40f7c7 100644
--- a/router/index.go
+++ b/router/index.go
@@ -1,164 +1,174 @@
-package router
-
-import (
-	"aps_crm/conf"
-	_ "aps_crm/docs"
-	"github.com/gin-contrib/cors"
-	"github.com/gin-gonic/gin"
-	swaggerFiles "github.com/swaggo/files"
-	ginSwagger "github.com/swaggo/gin-swagger"
-	"net/http"
-)
-
-type Group struct {
-	CurrencyRouter
-	QuotationStatusRouter
-	RepositoryRouter
-	SalesReturnStatusRouter
-	AccountIdRouter
-	IsInvoiceRouter
-	RefundMethodRouter
-	ServiceContractTypeRouter
-	ServiceContractStatusRouter
-	OrderTypeRouter
-	ReportSourceRouter
-	IsVisitRouter
-	SolveRateRouter
-	TimelyRateRouter
-	BaseRouter
-	UserRouter
-	JwtRouter
-	CountryRouter
-	ProvinceRouter
-	CityRouter
-	RegionRouter
-	ContactRouter
-	ClientRouter
-	ClientStatusRouter
-	ClientTypeRouter
-	ClientOriginRouter
-	ClientLevelRouter
-	IndustryRouter
-	EnterpriseNatureRouter
-	RegisteredCapitalRouter
-	EnterpriseScaleRouter
-	SalesLeadsRouter
-	SalesSourcesRouter
-	FollowRecordRouter
-	SaleChanceRouter
-	SaleStageRouter
-	SaleTypeRouter
-	RegularCustomersRouter
-	PossibilityRouter
-	StatusRouter
-	QuotationRouter
-	MasterOrderRouter
-	SubOrderRouter
-	SalesDetailsRouter
-	SalesReturnRouter
-	SalesRefundRouter
-	ContractRouter
-	PlanRouter
-	ServiceContractRouter
-	OrderManageRouter
-	ServiceFollowupRouter
-	CustomerServiceSheetRouter
-	ServiceFeeManageRouter
-	AuthorityRouter
-	MenuRouter
-	DataRouter
-	DepartmentRouter
-	SatisfactionRouter
-	AssignRouter
-}
-
-func InitRouter() *gin.Engine {
-	gin.SetMode(gin.ReleaseMode)
-
-	Router := gin.Default()
-	Router.Use(gin.Recovery())
-	if conf.Conf.System.Env == "develop" {
-		Router.Use(gin.Logger())
-	}
-	Router.Use(cors.Default())
-	Router.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
-
-	routerGroup := new(Group)
-	PublicGroup := Router.Group("api")
-	{
-		// 鍋ュ悍鐩戞祴
-		PublicGroup.GET("/health", func(c *gin.Context) {
-			c.JSON(http.StatusOK, "ok")
-		})
-	}
-	{
-		routerGroup.InitBaseRouter(PublicGroup)  // 娉ㄥ唽鍩虹鍔熻兘璺敱 涓嶅仛閴存潈
-		routerGroup.InitImageRouter(PublicGroup) // 鍥惧儚鍔熻兘璺敱
-	}
-
-	PrivateGroup := Router.Group("api")
-	//PrivateGroup.Use(middleware.JWTAuth()).Use(middleware.CasbinHandler())
-	//PrivateGroup.Use(middleware.JWTAuth())
-	//PrivateGroup.Use(middleware.CasbinHandler())
-	{
-		routerGroup.InitJwtRouter(PrivateGroup)                  // jwt鐩稿叧璺敱
-		routerGroup.InitUserRouter(PrivateGroup)                 // 娉ㄥ唽鐢ㄦ埛璺敱
-		routerGroup.InitCountryRouter(PrivateGroup)              // 娉ㄥ唽country璺敱
-		routerGroup.InitProvinceRouter(PrivateGroup)             // 娉ㄥ唽province璺敱
-		routerGroup.InitCityRouter(PrivateGroup)                 // 娉ㄥ唽city璺敱
-		routerGroup.InitRegionRouter(PrivateGroup)               // 娉ㄥ唽region璺敱
-		routerGroup.InitContactRouter(PrivateGroup)              // 娉ㄥ唽contact璺敱
-		routerGroup.InitClientRouter(PrivateGroup)               // 娉ㄥ唽client璺敱
-		routerGroup.InitClientStatusRouter(PrivateGroup)         // 娉ㄥ唽clientStatus璺敱
-		routerGroup.InitClientTypeRouter(PrivateGroup)           // 娉ㄥ唽clientType璺敱
-		routerGroup.InitClientOriginRouter(PrivateGroup)         // 娉ㄥ唽clientOrigin璺敱
-		routerGroup.InitClientLevelRouter(PrivateGroup)          // 娉ㄥ唽clientLevel璺敱
-		routerGroup.InitIndustryRouter(PrivateGroup)             // 娉ㄥ唽industry璺敱
-		routerGroup.InitEnterpriseNatureRouter(PrivateGroup)     // 娉ㄥ唽enterpriseNature璺敱
-		routerGroup.InitRegisteredCapitalRouter(PrivateGroup)    // 娉ㄥ唽registeredCapital璺敱
-		routerGroup.InitEnterpriseScaleRouter(PrivateGroup)      // 娉ㄥ唽enterpriseScale璺敱
-		routerGroup.InitSalesLeadsRouter(PrivateGroup)           // 娉ㄥ唽salesLeads璺敱
-		routerGroup.InitSalesSourcesRouter(PrivateGroup)         // 娉ㄥ唽salesSources璺敱
-		routerGroup.InitFollowRecordRouter(PrivateGroup)         // 娉ㄥ唽followRecord璺敱
-		routerGroup.InitSaleChanceRouter(PrivateGroup)           // 娉ㄥ唽saleChance璺敱
-		routerGroup.InitSaleStageRouter(PrivateGroup)            // 娉ㄥ唽saleStage璺敱
-		routerGroup.InitSaleTypeRouter(PrivateGroup)             // 娉ㄥ唽saleType璺敱
-		routerGroup.InitRegularCustomersRouter(PrivateGroup)     // 娉ㄥ唽regularCustomers璺敱
-		routerGroup.InitPossibilityRouter(PrivateGroup)          // 娉ㄥ唽possibility璺敱
-		routerGroup.InitStatusRouter(PrivateGroup)               // 娉ㄥ唽status璺敱
-		routerGroup.InitQuotationRouter(PrivateGroup)            // 娉ㄥ唽quotation璺敱
-		routerGroup.InitMasterOrderRouter(PrivateGroup)          // 娉ㄥ唽masterOrder璺敱
-		routerGroup.InitSubOrderRouter(PrivateGroup)             // 娉ㄥ唽subOrder璺敱
-		routerGroup.InitSalesDetailsRouter(PrivateGroup)         // 娉ㄥ唽salesDetails璺敱
-		routerGroup.InitSalesReturnRouter(PrivateGroup)          // 娉ㄥ唽salesReturn璺敱
-		routerGroup.InitSalesRefundRouter(PrivateGroup)          // 娉ㄥ唽salesRefund璺敱
-		routerGroup.InitContractRouter(PrivateGroup)             // 娉ㄥ唽contract璺敱
-		routerGroup.InitPlanRouter(PrivateGroup)                 // 娉ㄥ唽plan璺敱
-		routerGroup.InitServiceContractRouter(PrivateGroup)      // 娉ㄥ唽serviceContract璺敱
-		routerGroup.InitOrderManageRouter(PrivateGroup)          // 娉ㄥ唽orderManage璺敱
-		routerGroup.InitServiceFollowupRouter(PrivateGroup)      // 娉ㄥ唽serviceFollowup璺敱
-		routerGroup.InitCustomerServiceSheetRouter(PrivateGroup) // 娉ㄥ唽customerServiceSheet璺敱
-		routerGroup.InitServiceFeeManageRouter(PrivateGroup)     // 娉ㄥ唽serviceFeeManage璺敱
-		routerGroup.InitAuthorityRouter(PrivateGroup)            // 娉ㄥ唽authority璺敱
-		routerGroup.InitMenuRouter(PrivateGroup)                 // 娉ㄥ唽menu璺敱
-		routerGroup.InitDataRouter(PrivateGroup)                 // 娉ㄥ唽data璺敱
-		routerGroup.InitDepartmentRouter(PrivateGroup)           // 娉ㄥ唽department璺敱
-		routerGroup.InitSatisfactionRouter(PrivateGroup)         // 娉ㄥ唽satisfaction璺敱
-		routerGroup.InitTimelyRateRouter(PrivateGroup)
-		routerGroup.InitSolveRateRouter(PrivateGroup)
-		routerGroup.InitIsVisitRouter(PrivateGroup)
-		routerGroup.InitReportSourceRouter(PrivateGroup)
-		routerGroup.InitOrderTypeRouter(PrivateGroup)
-		routerGroup.InitServiceContractStatusRouter(PrivateGroup)
-		routerGroup.InitServiceContractTypeRouter(PrivateGroup)
-		routerGroup.InitRefundMethodRouter(PrivateGroup)
-		routerGroup.InitIsInvoiceRouter(PrivateGroup)
-		routerGroup.InitAccountIdRouter(PrivateGroup)
-		routerGroup.InitSalesReturnStatusRouter(PrivateGroup)
-		routerGroup.InitRepositoryRouter(PrivateGroup)
-		routerGroup.InitQuotationStatusRouter(PrivateGroup)
-		routerGroup.InitCurrencyRouter(PrivateGroup)
-		routerGroup.InitAssignRouter(PrivateGroup)
-	}
-	return Router
-}
+package router
+
+import (
+	"aps_crm/conf"
+	_ "aps_crm/docs"
+	"github.com/gin-contrib/cors"
+	"github.com/gin-gonic/gin"
+	swaggerFiles "github.com/swaggo/files"
+	ginSwagger "github.com/swaggo/gin-swagger"
+	"net/http"
+)
+
+type Group struct {
+	CurrencyRouter
+	QuotationStatusRouter
+	RepositoryRouter
+	SalesReturnStatusRouter
+	AccountIdRouter
+	IsInvoiceRouter
+	RefundMethodRouter
+	ServiceContractTypeRouter
+	ServiceContractStatusRouter
+	OrderTypeRouter
+	ReportSourceRouter
+	IsVisitRouter
+	SolveRateRouter
+	TimelyRateRouter
+	BaseRouter
+	UserRouter
+	JwtRouter
+	CountryRouter
+	ProvinceRouter
+	CityRouter
+	RegionRouter
+	ContactRouter
+	ClientRouter
+	ClientStatusRouter
+	ClientTypeRouter
+	ClientOriginRouter
+	ClientLevelRouter
+	IndustryRouter
+	EnterpriseNatureRouter
+	RegisteredCapitalRouter
+	EnterpriseScaleRouter
+	SalesLeadsRouter
+	SalesSourcesRouter
+	FollowRecordRouter
+	SaleChanceRouter
+	SaleStageRouter
+	SaleTypeRouter
+	RegularCustomersRouter
+	PossibilityRouter
+	StatusRouter
+	QuotationRouter
+	MasterOrderRouter
+	SubOrderRouter
+	SalesDetailsRouter
+	SalesReturnRouter
+	SalesRefundRouter
+	ContractRouter
+	PlanRouter
+	ServiceContractRouter
+	OrderManageRouter
+	ServiceFollowupRouter
+	CustomerServiceSheetRouter
+	ServiceFeeManageRouter
+	AuthorityRouter
+	MenuRouter
+	DataRouter
+	DepartmentRouter
+	SatisfactionRouter
+	AssignRouter
+}
+
+func InitRouter() *gin.Engine {
+	gin.SetMode(gin.ReleaseMode)
+
+	Router := gin.Default()
+	Router.Use(gin.Recovery())
+	if conf.Conf.System.Env == "develop" {
+		Router.Use(gin.Logger())
+	}
+	Router.Use(cors.Default())
+	Router.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
+
+	routerGroup := new(Group)
+	PublicGroup := Router.Group("api")
+	{
+		// 鍋ュ悍鐩戞祴
+		PublicGroup.GET("/health", func(c *gin.Context) {
+			c.JSON(http.StatusOK, "ok")
+		})
+	}
+	{
+		routerGroup.InitBaseRouter(PublicGroup)  // 娉ㄥ唽鍩虹鍔熻兘璺敱 涓嶅仛閴存潈
+		routerGroup.InitImageRouter(PublicGroup) // 鍥惧儚鍔熻兘璺敱
+	}
+
+	PrivateGroup := Router.Group("api")
+	//PrivateGroup.Use(middleware.JWTAuth()).Use(middleware.CasbinHandler())
+	//PrivateGroup.Use(middleware.JWTAuth())
+	//PrivateGroup.Use(middleware.CasbinHandler())
+	{
+		routerGroup.InitJwtRouter(PrivateGroup)                  // jwt鐩稿叧璺敱
+		routerGroup.InitUserRouter(PrivateGroup)                 // 娉ㄥ唽鐢ㄦ埛璺敱
+		routerGroup.InitCountryRouter(PrivateGroup)              // 娉ㄥ唽country璺敱
+		routerGroup.InitProvinceRouter(PrivateGroup)             // 娉ㄥ唽province璺敱
+		routerGroup.InitCityRouter(PrivateGroup)                 // 娉ㄥ唽city璺敱
+		routerGroup.InitRegionRouter(PrivateGroup)               // 娉ㄥ唽region璺敱
+		routerGroup.InitContactRouter(PrivateGroup)              // 娉ㄥ唽contact璺敱
+		routerGroup.InitClientRouter(PrivateGroup)               // 娉ㄥ唽client璺敱
+		routerGroup.InitClientStatusRouter(PrivateGroup)         // 娉ㄥ唽clientStatus璺敱
+		routerGroup.InitClientTypeRouter(PrivateGroup)           // 娉ㄥ唽clientType璺敱
+		routerGroup.InitClientOriginRouter(PrivateGroup)         // 娉ㄥ唽clientOrigin璺敱
+		routerGroup.InitClientLevelRouter(PrivateGroup)          // 娉ㄥ唽clientLevel璺敱
+		routerGroup.InitIndustryRouter(PrivateGroup)             // 娉ㄥ唽industry璺敱
+		routerGroup.InitEnterpriseNatureRouter(PrivateGroup)     // 娉ㄥ唽enterpriseNature璺敱
+		routerGroup.InitRegisteredCapitalRouter(PrivateGroup)    // 娉ㄥ唽registeredCapital璺敱
+		routerGroup.InitEnterpriseScaleRouter(PrivateGroup)      // 娉ㄥ唽enterpriseScale璺敱
+		routerGroup.InitSalesLeadsRouter(PrivateGroup)           // 娉ㄥ唽salesLeads璺敱
+		routerGroup.InitSalesSourcesRouter(PrivateGroup)         // 娉ㄥ唽salesSources璺敱
+		routerGroup.InitFollowRecordRouter(PrivateGroup)         // 娉ㄥ唽followRecord璺敱
+		routerGroup.InitSaleChanceRouter(PrivateGroup)           // 娉ㄥ唽saleChance璺敱
+		routerGroup.InitSaleStageRouter(PrivateGroup)            // 娉ㄥ唽saleStage璺敱
+		routerGroup.InitSaleTypeRouter(PrivateGroup)             // 娉ㄥ唽saleType璺敱
+		routerGroup.InitRegularCustomersRouter(PrivateGroup)     // 娉ㄥ唽regularCustomers璺敱
+		routerGroup.InitPossibilityRouter(PrivateGroup)          // 娉ㄥ唽possibility璺敱
+		routerGroup.InitStatusRouter(PrivateGroup)               // 娉ㄥ唽status璺敱
+		routerGroup.InitQuotationRouter(PrivateGroup)            // 娉ㄥ唽quotation璺敱
+		routerGroup.InitMasterOrderRouter(PrivateGroup)          // 娉ㄥ唽masterOrder璺敱
+		routerGroup.InitSubOrderRouter(PrivateGroup)             // 娉ㄥ唽subOrder璺敱
+		routerGroup.InitSalesDetailsRouter(PrivateGroup)         // 娉ㄥ唽salesDetails璺敱
+		routerGroup.InitSalesReturnRouter(PrivateGroup)          // 娉ㄥ唽salesReturn璺敱
+		routerGroup.InitSalesRefundRouter(PrivateGroup)          // 娉ㄥ唽salesRefund璺敱
+		routerGroup.InitContractRouter(PrivateGroup)             // 娉ㄥ唽contract璺敱
+		routerGroup.InitPlanRouter(PrivateGroup)                 // 娉ㄥ唽plan璺敱
+		routerGroup.InitServiceContractRouter(PrivateGroup)      // 娉ㄥ唽serviceContract璺敱
+		routerGroup.InitOrderManageRouter(PrivateGroup)          // 娉ㄥ唽orderManage璺敱
+		routerGroup.InitServiceFollowupRouter(PrivateGroup)      // 娉ㄥ唽serviceFollowup璺敱
+		routerGroup.InitCustomerServiceSheetRouter(PrivateGroup) // 娉ㄥ唽customerServiceSheet璺敱
+		routerGroup.InitServiceFeeManageRouter(PrivateGroup)     // 娉ㄥ唽serviceFeeManage璺敱
+		routerGroup.InitAuthorityRouter(PrivateGroup)            // 娉ㄥ唽authority璺敱
+		routerGroup.InitMenuRouter(PrivateGroup)                 // 娉ㄥ唽menu璺敱
+		routerGroup.InitDataRouter(PrivateGroup)                 // 娉ㄥ唽data璺敱
+		routerGroup.InitDepartmentRouter(PrivateGroup)           // 娉ㄥ唽department璺敱
+		routerGroup.InitSatisfactionRouter(PrivateGroup)         // 娉ㄥ唽satisfaction璺敱
+		routerGroup.InitTimelyRateRouter(PrivateGroup)
+		routerGroup.InitSolveRateRouter(PrivateGroup)
+		routerGroup.InitIsVisitRouter(PrivateGroup)
+		routerGroup.InitReportSourceRouter(PrivateGroup)
+		routerGroup.InitOrderTypeRouter(PrivateGroup)
+		routerGroup.InitServiceContractStatusRouter(PrivateGroup)
+		routerGroup.InitServiceContractTypeRouter(PrivateGroup)
+		routerGroup.InitRefundMethodRouter(PrivateGroup)
+		routerGroup.InitIsInvoiceRouter(PrivateGroup)
+		routerGroup.InitAccountIdRouter(PrivateGroup)
+		routerGroup.InitSalesReturnStatusRouter(PrivateGroup)
+		routerGroup.InitRepositoryRouter(PrivateGroup)
+		routerGroup.InitQuotationStatusRouter(PrivateGroup)
+		routerGroup.InitCurrencyRouter(PrivateGroup)
+		routerGroup.InitAssignRouter(PrivateGroup)
+		InitServiceOrderRouter(PrivateGroup)
+		InitFaqRouter(PrivateGroup)
+		InitPriorityLevelRouter(PrivateGroup)
+		InitServiceTypeRouter(PrivateGroup)
+		InitSeverityRouter(PrivateGroup)
+		InitTimeSpentRouter(PrivateGroup)
+		InitFaultTypeRouter(PrivateGroup)
+		InitServiceCollectionPlanRouter(PrivateGroup)
+		InitReceiptRouter(PrivateGroup)
+		InitBankAccountRouter(PrivateGroup)
+	}
+	return Router
+}
diff --git a/router/paymentType.go b/router/paymentType.go
new file mode 100644
index 0000000..a320b69
--- /dev/null
+++ b/router/paymentType.go
@@ -0,0 +1,17 @@
+package router
+
+import (
+	v1 "aps_crm/api/v1"
+	"github.com/gin-gonic/gin"
+)
+
+func InitPaymentTypeRouter(router *gin.RouterGroup) {
+	PaymentTypeRouter := router.Group("paymentType")
+	PaymentTypeApi := v1.PaymentTypeApi{}
+	{
+		PaymentTypeRouter.POST("add", PaymentTypeApi.Add)             // 娣诲姞鏀粯鏂瑰紡
+		PaymentTypeRouter.DELETE("delete/:id", PaymentTypeApi.Delete) // 鍒犻櫎鏀粯鏂瑰紡
+		PaymentTypeRouter.PUT("update", PaymentTypeApi.Update)        // 鏇存柊鏀粯鏂瑰紡
+		PaymentTypeRouter.GET("list", PaymentTypeApi.List)            // 鑾峰彇鏀粯鏂瑰紡鍒楄〃
+	}
+}
diff --git a/router/priorityLevel.go b/router/priorityLevel.go
new file mode 100644
index 0000000..1adf38d
--- /dev/null
+++ b/router/priorityLevel.go
@@ -0,0 +1,17 @@
+package router
+
+import (
+	v1 "aps_crm/api/v1"
+	"github.com/gin-gonic/gin"
+)
+
+func InitPriorityLevelRouter(router *gin.RouterGroup) {
+	PriorityLevelRouter := router.Group("priorityLevel")
+	PriorityLevelApi := v1.PriorityLevelApi{}
+	{
+		PriorityLevelRouter.POST("add", PriorityLevelApi.Add)             // 娣诲姞浼樺厛绾у埆
+		PriorityLevelRouter.DELETE("delete/:id", PriorityLevelApi.Delete) // 鍒犻櫎浼樺厛绾у埆
+		PriorityLevelRouter.PUT("update", PriorityLevelApi.Update)        // 鏇存柊浼樺厛绾у埆
+		PriorityLevelRouter.GET("list", PriorityLevelApi.List)            // 鑾峰彇浼樺厛绾у埆鍒楄〃
+	}
+}
diff --git a/router/receipt.go b/router/receipt.go
new file mode 100644
index 0000000..eea9a00
--- /dev/null
+++ b/router/receipt.go
@@ -0,0 +1,17 @@
+package router
+
+import (
+	v1 "aps_crm/api/v1"
+	"github.com/gin-gonic/gin"
+)
+
+func InitReceiptRouter(router *gin.RouterGroup) {
+	ReceiptRouter := router.Group("receipt")
+	ReceiptApi := v1.ReceiptApi{}
+	{
+		ReceiptRouter.POST("add", ReceiptApi.Add)             // 娣诲姞鏀舵鍗�
+		ReceiptRouter.DELETE("delete/:id", ReceiptApi.Delete) // 鍒犻櫎鏀舵鍗�
+		ReceiptRouter.PUT("update", ReceiptApi.Update)        // 鏇存柊鏀舵鍗�
+		ReceiptRouter.GET("list", ReceiptApi.List)            // 鑾峰彇鏀舵鍗曞垪琛�
+	}
+}
diff --git a/router/serviceCollectionPlan.go b/router/serviceCollectionPlan.go
new file mode 100644
index 0000000..68c20f7
--- /dev/null
+++ b/router/serviceCollectionPlan.go
@@ -0,0 +1,17 @@
+package router
+
+import (
+	v1 "aps_crm/api/v1"
+	"github.com/gin-gonic/gin"
+)
+
+func InitServiceCollectionPlanRouter(router *gin.RouterGroup) {
+	ServiceCollectionPlanRouter := router.Group("serviceCollectionPlan")
+	ServiceCollectionPlanApi := v1.ServiceCollectionPlanApi{}
+	{
+		ServiceCollectionPlanRouter.POST("add", ServiceCollectionPlanApi.Add)             // 娣诲姞鏈嶅姟鍚堝悓鏀舵璁″垝
+		ServiceCollectionPlanRouter.DELETE("delete/:id", ServiceCollectionPlanApi.Delete) // 鍒犻櫎鏈嶅姟鍚堝悓鏀舵璁″垝
+		ServiceCollectionPlanRouter.PUT("update", ServiceCollectionPlanApi.Update)        // 鏇存柊鏈嶅姟鍚堝悓鏀舵璁″垝
+		ServiceCollectionPlanRouter.GET("list", ServiceCollectionPlanApi.List)            // 鑾峰彇鏈嶅姟鍚堝悓鏀舵璁″垝鍒楄〃
+	}
+}
diff --git a/router/serviceOrder.go b/router/serviceOrder.go
new file mode 100644
index 0000000..8efdc84
--- /dev/null
+++ b/router/serviceOrder.go
@@ -0,0 +1,17 @@
+package router
+
+import (
+	v1 "aps_crm/api/v1"
+	"github.com/gin-gonic/gin"
+)
+
+func InitServiceOrderRouter(router *gin.RouterGroup) {
+	ServiceOrderRouter := router.Group("serviceOrder")
+	ServiceOrderApi := v1.ServiceOrderApi{}
+	{
+		ServiceOrderRouter.POST("add", ServiceOrderApi.Add)             // 娣诲姞鏈嶅姟鍗�
+		ServiceOrderRouter.DELETE("delete/:id", ServiceOrderApi.Delete) // 鍒犻櫎鏈嶅姟鍗�
+		ServiceOrderRouter.PUT("update", ServiceOrderApi.Update)        // 鏇存柊鏈嶅姟鍗�
+		ServiceOrderRouter.GET("list", ServiceOrderApi.List)            // 鑾峰彇鏈嶅姟鍗曞垪琛�
+	}
+}
diff --git a/router/serviceType.go b/router/serviceType.go
new file mode 100644
index 0000000..c396bcf
--- /dev/null
+++ b/router/serviceType.go
@@ -0,0 +1,17 @@
+package router
+
+import (
+	v1 "aps_crm/api/v1"
+	"github.com/gin-gonic/gin"
+)
+
+func InitServiceTypeRouter(router *gin.RouterGroup) {
+	ServiceTypeRouter := router.Group("serviceType")
+	ServiceTypeApi := v1.ServiceTypeApi{}
+	{
+		ServiceTypeRouter.POST("add", ServiceTypeApi.Add)             // 娣诲姞鏈嶅姟鏂瑰紡
+		ServiceTypeRouter.DELETE("delete/:id", ServiceTypeApi.Delete) // 鍒犻櫎鏈嶅姟鏂瑰紡
+		ServiceTypeRouter.PUT("update", ServiceTypeApi.Update)        // 鏇存柊鏈嶅姟鏂瑰紡
+		ServiceTypeRouter.GET("list", ServiceTypeApi.List)            // 鑾峰彇鏈嶅姟鏂瑰紡鍒楄〃
+	}
+}
diff --git a/router/severity.go b/router/severity.go
new file mode 100644
index 0000000..78e6dfc
--- /dev/null
+++ b/router/severity.go
@@ -0,0 +1,17 @@
+package router
+
+import (
+	v1 "aps_crm/api/v1"
+	"github.com/gin-gonic/gin"
+)
+
+func InitSeverityRouter(router *gin.RouterGroup) {
+	SeverityRouter := router.Group("severity")
+	SeverityApi := v1.SeverityApi{}
+	{
+		SeverityRouter.POST("add", SeverityApi.Add)             // 娣诲姞涓ラ噸绋嬪害
+		SeverityRouter.DELETE("delete/:id", SeverityApi.Delete) // 鍒犻櫎涓ラ噸绋嬪害
+		SeverityRouter.PUT("update", SeverityApi.Update)        // 鏇存柊涓ラ噸绋嬪害
+		SeverityRouter.GET("list", SeverityApi.List)            // 鑾峰彇涓ラ噸绋嬪害鍒楄〃
+	}
+}
diff --git a/router/timeSpent.go b/router/timeSpent.go
new file mode 100644
index 0000000..5b537c7
--- /dev/null
+++ b/router/timeSpent.go
@@ -0,0 +1,17 @@
+package router
+
+import (
+	v1 "aps_crm/api/v1"
+	"github.com/gin-gonic/gin"
+)
+
+func InitTimeSpentRouter(router *gin.RouterGroup) {
+	TimeSpentRouter := router.Group("timeSpent")
+	TimeSpentApi := v1.TimeSpentApi{}
+	{
+		TimeSpentRouter.POST("add", TimeSpentApi.Add)             // 娣诲姞鑺辫垂鏃堕棿
+		TimeSpentRouter.DELETE("delete/:id", TimeSpentApi.Delete) // 鍒犻櫎鑺辫垂鏃堕棿
+		TimeSpentRouter.PUT("update", TimeSpentApi.Update)        // 鏇存柊鑺辫垂鏃堕棿
+		TimeSpentRouter.GET("list", TimeSpentApi.List)            // 鑾峰彇鑺辫垂鏃堕棿鍒楄〃
+	}
+}
diff --git a/service/bankAccount.go b/service/bankAccount.go
new file mode 100644
index 0000000..4516672
--- /dev/null
+++ b/service/bankAccount.go
@@ -0,0 +1,66 @@
+package service
+
+import (
+	"aps_crm/model"
+	"aps_crm/model/request"
+	"aps_crm/pkg/ecode"
+)
+
+type BankAccountService struct{}
+
+func NewBankAccountService() BankAccountService {
+	return BankAccountService{}
+}
+
+func (BankAccountService) AddBankAccount(bankAccount *model.BankAccount) int {
+	err := model.NewBankAccountSearch().Create(bankAccount)
+	if err != nil {
+		return ecode.DBErr
+	}
+
+	return ecode.OK
+}
+
+func (BankAccountService) DeleteBankAccount(id int) int {
+	err := model.NewBankAccountSearch().SetId(id).Delete()
+	if err != nil {
+		return ecode.DBErr
+	}
+	return ecode.OK
+}
+
+func (BankAccountService) GetBankAccountList() ([]*model.BankAccount, int64, int) {
+	list, total, err := model.NewBankAccountSearch().Find()
+	if err != nil {
+		return nil, 0, ecode.DBErr
+	}
+
+	return list, total, ecode.OK
+}
+
+func (BankAccountService) UpdateBankAccounts(BankAccounts []*request.UpdateBankAccount) int {
+	for _, v := range BankAccounts {
+		// check BankAccount exist
+		_, err := model.NewBankAccountSearch().SetId(v.Id).First()
+		if err != nil {
+			return ecode.DBErr
+		}
+
+		err = model.NewBankAccountSearch().SetId(v.Id).Updates(map[string]interface{}{
+
+		})
+		if err != nil {
+			return ecode.DBErr
+		}
+	}
+
+	return ecode.OK
+}
+
+func (BankAccountService) UpdateBankAccount(bankAccount *model.BankAccount) int {
+		err := model.NewBankAccountSearch().SetId(bankAccount.Id).Save(bankAccount)
+		if err != nil {
+			return ecode.DBErr
+		}
+	return ecode.OK
+}
diff --git a/service/faq.go b/service/faq.go
new file mode 100644
index 0000000..bd01165
--- /dev/null
+++ b/service/faq.go
@@ -0,0 +1,66 @@
+package service
+
+import (
+	"aps_crm/model"
+	"aps_crm/model/request"
+	"aps_crm/pkg/ecode"
+)
+
+type FaqService struct{}
+
+func NewFaqService() FaqService {
+	return FaqService{}
+}
+
+func (FaqService) AddFaq(faq *model.Faq) int {
+	err := model.NewFaqSearch().Create(faq)
+	if err != nil {
+		return ecode.DBErr
+	}
+
+	return ecode.OK
+}
+
+func (FaqService) DeleteFaq(id int) int {
+	err := model.NewFaqSearch().SetId(id).Delete()
+	if err != nil {
+		return ecode.DBErr
+	}
+	return ecode.OK
+}
+
+func (FaqService) GetFaqList() ([]*model.Faq, int64, int) {
+	list, total, err := model.NewFaqSearch().Find()
+	if err != nil {
+		return nil, 0, ecode.DBErr
+	}
+
+	return list, total, ecode.OK
+}
+
+func (FaqService) UpdateFaqs(Faqs []*request.UpdateFaq) int {
+	for _, v := range Faqs {
+		// check Faq exist
+		_, err := model.NewFaqSearch().SetId(v.Id).First()
+		if err != nil {
+			return ecode.DBErr
+		}
+
+		err = model.NewFaqSearch().SetId(v.Id).Updates(map[string]interface{}{
+
+		})
+		if err != nil {
+			return ecode.DBErr
+		}
+	}
+
+	return ecode.OK
+}
+
+func (FaqService) UpdateFaq(faq *model.Faq) int {
+		err := model.NewFaqSearch().SetId(faq.Id).Save(faq)
+		if err != nil {
+			return ecode.DBErr
+		}
+	return ecode.OK
+}
diff --git a/service/faultType.go b/service/faultType.go
new file mode 100644
index 0000000..141ac23
--- /dev/null
+++ b/service/faultType.go
@@ -0,0 +1,66 @@
+package service
+
+import (
+	"aps_crm/model"
+	"aps_crm/model/request"
+	"aps_crm/pkg/ecode"
+)
+
+type FaultTypeService struct{}
+
+func NewFaultTypeService() FaultTypeService {
+	return FaultTypeService{}
+}
+
+func (FaultTypeService) AddFaultType(FaultType *model.FaultType) int {
+	err := model.NewFaultTypeSearch().Create(FaultType)
+	if err != nil {
+		return ecode.DBErr
+	}
+
+	return ecode.OK
+}
+
+func (FaultTypeService) DeleteFaultType(id int) int {
+	err := model.NewFaultTypeSearch().SetId(id).Delete()
+	if err != nil {
+		return ecode.DBErr
+	}
+	return ecode.OK
+}
+
+func (FaultTypeService) GetFaultTypeList() ([]*model.FaultType, int64, int) {
+	list, total, err := model.NewFaultTypeSearch().Find()
+	if err != nil {
+		return nil, 0, ecode.DBErr
+	}
+
+	return list, total, ecode.OK
+}
+
+func (FaultTypeService) UpdateFaultTypes(FaultTypes []*request.UpdateFaultType) int {
+	for _, v := range FaultTypes {
+		// check FaultType exist
+		_, err := model.NewFaultTypeSearch().SetId(v.Id).First()
+		if err != nil {
+			return ecode.DBErr
+		}
+
+		err = model.NewFaultTypeSearch().SetId(v.Id).Updates(map[string]interface{}{
+
+		})
+		if err != nil {
+			return ecode.DBErr
+		}
+	}
+
+	return ecode.OK
+}
+
+func (FaultTypeService) UpdateFaultType(faultType *model.FaultType) int {
+		err := model.NewFaultTypeSearch().SetId(faultType.Id).Save(faultType)
+		if err != nil {
+			return ecode.DBErr
+		}
+	return ecode.OK
+}
diff --git a/service/file.go b/service/file.go
new file mode 100644
index 0000000..af78875
--- /dev/null
+++ b/service/file.go
@@ -0,0 +1,65 @@
+package service
+
+import (
+	"aps_crm/model"
+	"aps_crm/model/request"
+	"aps_crm/pkg/ecode"
+)
+
+type FileService struct{}
+
+func NewFileService() FileService {
+	return FileService{}
+}
+
+func (FileService) AddFile(fileRecord *model.File) int {
+
+	err := model.NewFileSearch().Create(fileRecord)
+	if err != nil {
+		return ecode.DBErr
+	}
+
+	return ecode.OK
+}
+
+func (FileService) DeleteFile(id int) int {
+	err := model.NewFileSearch().SetId(id).Delete()
+	if err != nil {
+		return ecode.DBErr
+	}
+	return ecode.OK
+}
+
+func (FileService) GetFileList() ([]*model.File, int64, int) {
+	list, total, err := model.NewFileSearch().Find()
+	if err != nil {
+		return nil, 0, ecode.DBErr
+	}
+
+	return list, total, ecode.OK
+}
+
+func (FileService) UpdateFiles(Files []*request.UpdateFile) int {
+	for _, v := range Files {
+		// check File exist
+		_, err := model.NewFileSearch().SetId(v.Id).First()
+		if err != nil {
+			return ecode.DBErr
+		}
+
+		err = model.NewFileSearch().SetId(v.Id).Updates(map[string]interface{}{})
+		if err != nil {
+			return ecode.DBErr
+		}
+	}
+
+	return ecode.OK
+}
+
+func (FileService) UpdateFile(file *model.File) int {
+	err := model.NewFileSearch().SetId(file.Id).Save(file)
+	if err != nil {
+		return ecode.DBErr
+	}
+	return ecode.OK
+}
diff --git a/service/paymentType.go b/service/paymentType.go
new file mode 100644
index 0000000..83ec447
--- /dev/null
+++ b/service/paymentType.go
@@ -0,0 +1,66 @@
+package service
+
+import (
+	"aps_crm/model"
+	"aps_crm/model/request"
+	"aps_crm/pkg/ecode"
+)
+
+type PaymentTypeService struct{}
+
+func NewPaymentTypeService() PaymentTypeService {
+	return PaymentTypeService{}
+}
+
+func (PaymentTypeService) AddPaymentType(paymentType *model.PaymentType) int {
+	err := model.NewPaymentTypeSearch().Create(paymentType)
+	if err != nil {
+		return ecode.DBErr
+	}
+
+	return ecode.OK
+}
+
+func (PaymentTypeService) DeletePaymentType(id int) int {
+	err := model.NewPaymentTypeSearch().SetId(id).Delete()
+	if err != nil {
+		return ecode.DBErr
+	}
+	return ecode.OK
+}
+
+func (PaymentTypeService) GetPaymentTypeList() ([]*model.PaymentType, int64, int) {
+	list, total, err := model.NewPaymentTypeSearch().Find()
+	if err != nil {
+		return nil, 0, ecode.DBErr
+	}
+
+	return list, total, ecode.OK
+}
+
+func (PaymentTypeService) UpdatePaymentTypes(PaymentTypes []*request.UpdatePaymentType) int {
+	for _, v := range PaymentTypes {
+		// check PaymentType exist
+		_, err := model.NewPaymentTypeSearch().SetId(v.Id).First()
+		if err != nil {
+			return ecode.DBErr
+		}
+
+		err = model.NewPaymentTypeSearch().SetId(v.Id).Updates(map[string]interface{}{
+
+		})
+		if err != nil {
+			return ecode.DBErr
+		}
+	}
+
+	return ecode.OK
+}
+
+func (PaymentTypeService) UpdatePaymentType(paymentType *model.PaymentType) int {
+		err := model.NewPaymentTypeSearch().SetId(paymentType.Id).Save(paymentType)
+		if err != nil {
+			return ecode.DBErr
+		}
+	return ecode.OK
+}
diff --git a/service/priorityLevel.go b/service/priorityLevel.go
new file mode 100644
index 0000000..9b2b3d3
--- /dev/null
+++ b/service/priorityLevel.go
@@ -0,0 +1,66 @@
+package service
+
+import (
+	"aps_crm/model"
+	"aps_crm/model/request"
+	"aps_crm/pkg/ecode"
+)
+
+type PriorityLevelService struct{}
+
+func NewPriorityLevelService() PriorityLevelService {
+	return PriorityLevelService{}
+}
+
+func (PriorityLevelService) AddPriorityLevel(PriorityLevel *model.PriorityLevel) int {
+	err := model.NewPriorityLevelSearch().Create(PriorityLevel)
+	if err != nil {
+		return ecode.DBErr
+	}
+
+	return ecode.OK
+}
+
+func (PriorityLevelService) DeletePriorityLevel(id int) int {
+	err := model.NewPriorityLevelSearch().SetId(id).Delete()
+	if err != nil {
+		return ecode.DBErr
+	}
+	return ecode.OK
+}
+
+func (PriorityLevelService) GetPriorityLevelList() ([]*model.PriorityLevel, int64, int) {
+	list, total, err := model.NewPriorityLevelSearch().Find()
+	if err != nil {
+		return nil, 0, ecode.DBErr
+	}
+
+	return list, total, ecode.OK
+}
+
+func (PriorityLevelService) UpdatePriorityLevels(PriorityLevels []*request.UpdatePriorityLevel) int {
+	for _, v := range PriorityLevels {
+		// check PriorityLevel exist
+		_, err := model.NewPriorityLevelSearch().SetId(v.Id).First()
+		if err != nil {
+			return ecode.DBErr
+		}
+
+		err = model.NewPriorityLevelSearch().SetId(v.Id).Updates(map[string]interface{}{
+
+		})
+		if err != nil {
+			return ecode.DBErr
+		}
+	}
+
+	return ecode.OK
+}
+
+func (PriorityLevelService) UpdatePriorityLevel(priorityLevel *model.PriorityLevel) int {
+		err := model.NewPriorityLevelSearch().SetId(priorityLevel.Id).Save(priorityLevel)
+		if err != nil {
+			return ecode.DBErr
+		}
+	return ecode.OK
+}
diff --git a/service/receipt.go b/service/receipt.go
new file mode 100644
index 0000000..834c6df
--- /dev/null
+++ b/service/receipt.go
@@ -0,0 +1,66 @@
+package service
+
+import (
+	"aps_crm/model"
+	"aps_crm/model/request"
+	"aps_crm/pkg/ecode"
+)
+
+type ReceiptService struct{}
+
+func NewReceiptService() ReceiptService {
+	return ReceiptService{}
+}
+
+func (ReceiptService) AddReceipt(receipt *model.Receipt) int {
+	err := model.NewReceiptSearch().Create(receipt)
+	if err != nil {
+		return ecode.DBErr
+	}
+
+	return ecode.OK
+}
+
+func (ReceiptService) DeleteReceipt(id int) int {
+	err := model.NewReceiptSearch().SetId(id).Delete()
+	if err != nil {
+		return ecode.DBErr
+	}
+	return ecode.OK
+}
+
+func (ReceiptService) GetReceiptList() ([]*model.Receipt, int64, int) {
+	list, total, err := model.NewReceiptSearch().Find()
+	if err != nil {
+		return nil, 0, ecode.DBErr
+	}
+
+	return list, total, ecode.OK
+}
+
+func (ReceiptService) UpdateReceipts(Receipts []*request.UpdateReceipt) int {
+	for _, v := range Receipts {
+		// check Receipt exist
+		_, err := model.NewReceiptSearch().SetId(v.Id).First()
+		if err != nil {
+			return ecode.DBErr
+		}
+
+		err = model.NewReceiptSearch().SetId(v.Id).Updates(map[string]interface{}{
+
+		})
+		if err != nil {
+			return ecode.DBErr
+		}
+	}
+
+	return ecode.OK
+}
+
+func (ReceiptService) UpdateReceipt(receipt *model.Receipt) int {
+		err := model.NewReceiptSearch().SetId(receipt.Id).Save(receipt)
+		if err != nil {
+			return ecode.DBErr
+		}
+	return ecode.OK
+}
diff --git a/service/serviceCollectionPlan.go b/service/serviceCollectionPlan.go
new file mode 100644
index 0000000..fdaa235
--- /dev/null
+++ b/service/serviceCollectionPlan.go
@@ -0,0 +1,80 @@
+package service
+
+import (
+	"aps_crm/model"
+	"aps_crm/model/request"
+	"aps_crm/pkg/ecode"
+	"gorm.io/gorm"
+)
+
+type ServiceCollectionPlanService struct{}
+
+func NewServiceCollectionPlanService() ServiceCollectionPlanService {
+	return ServiceCollectionPlanService{}
+}
+
+func (ServiceCollectionPlanService) AddServiceCollectionPlan(serviceCollectionPlan []*model.ServiceCollectionPlan) int {
+	if len(serviceCollectionPlan) == 0 {
+		return ecode.ParamsErr
+	}
+	contractId := serviceCollectionPlan[0].ServiceContractId
+	err := model.WithTransaction(func(db *gorm.DB) error {
+		err := model.NewServiceCollectionPlanSearch().SetOrm(db).SetServiceContractId(contractId).Delete()
+		if err != nil {
+			return err
+		}
+		err = model.NewServiceCollectionPlanSearch().SetOrm(db).CreateBatch(serviceCollectionPlan)
+		if err != nil {
+			return err
+		}
+		return nil
+	})
+
+	if err != nil {
+		return ecode.DBErr
+	}
+
+	return ecode.OK
+}
+
+func (ServiceCollectionPlanService) DeleteServiceCollectionPlan(id int) int {
+	err := model.NewServiceCollectionPlanSearch().SetId(id).Delete()
+	if err != nil {
+		return ecode.DBErr
+	}
+	return ecode.OK
+}
+
+func (ServiceCollectionPlanService) GetServiceCollectionPlanList(contractId int) ([]*model.ServiceCollectionPlan, int64, int) {
+	list, total, err := model.NewServiceCollectionPlanSearch().SetServiceContractId(contractId).Find()
+	if err != nil {
+		return nil, 0, ecode.DBErr
+	}
+
+	return list, total, ecode.OK
+}
+
+func (ServiceCollectionPlanService) UpdateServiceCollectionPlans(ServiceCollectionPlans []*request.UpdateServiceCollectionPlan) int {
+	for _, v := range ServiceCollectionPlans {
+		// check ServiceCollectionPlan exist
+		_, err := model.NewServiceCollectionPlanSearch().SetId(v.Id).First()
+		if err != nil {
+			return ecode.DBErr
+		}
+
+		err = model.NewServiceCollectionPlanSearch().SetId(v.Id).Updates(map[string]interface{}{})
+		if err != nil {
+			return ecode.DBErr
+		}
+	}
+
+	return ecode.OK
+}
+
+func (ServiceCollectionPlanService) UpdateServiceCollectionPlan(serviceCollectionPlan *model.ServiceCollectionPlan) int {
+	err := model.NewServiceCollectionPlanSearch().SetId(serviceCollectionPlan.Id).Save(serviceCollectionPlan)
+	if err != nil {
+		return ecode.DBErr
+	}
+	return ecode.OK
+}
diff --git a/service/serviceContract.go b/service/serviceContract.go
index 2175971..45907c8 100644
--- a/service/serviceContract.go
+++ b/service/serviceContract.go
@@ -1,59 +1,64 @@
-package service
-
-import (
-	"aps_crm/model"
-	"aps_crm/pkg/ecode"
-)
-
-type SContractService struct{}
-
-func (SContractService) AddServiceContract(serviceContract *model.ServiceContract) int {
-	err := model.NewServiceContractSearch().Create(serviceContract)
-	if err != nil {
-		return ecode.SContractExist
-	}
-
-	return ecode.OK
-}
-
-func (SContractService) UpdateServiceContract(serviceContract *model.ServiceContract) int {
-	// check serviceContract exist
-	_, err := model.NewServiceContractSearch().SetId(serviceContract.Id).Find()
-	if err != nil {
-		return ecode.SContractNotExist
-	}
-
-	err = model.NewServiceContractSearch().SetId(serviceContract.Id).Update(serviceContract)
-	if err != nil {
-		return ecode.SContractSetErr
-	}
-
-	return ecode.OK
-}
-
-//func (SContractService) GetServiceContractByContractId(contractId int) ([]*model.ServiceContract, int) {
-//	list, err := model.NewServiceContractSearch().SetId(contractId).FindAll()
-//	if err != nil {
-//		return nil, ecode.SContractListErr
-//	}
-//
-//	return list, ecode.OK
-//}
-
-func (SContractService) GetServiceContractList(page, pageSize int, keyword string) ([]*model.ServiceContract, int64, int) {
-	// get contact list
-	contacts, total, err := model.NewServiceContractSearch().SetKeyword(keyword).SetPage(page, pageSize).FindAll()
-	if err != nil {
-		return nil, 0, ecode.SContractListErr
-	}
-	return contacts, total, ecode.OK
-}
-
-func (SContractService) DeleteServiceContract(ids []int) int {
-	// delete client
-	err := model.NewServiceContractSearch().SetIds(ids).Delete()
-	if err != nil {
-		return ecode.SContractDeleteErr
-	}
-	return ecode.OK
-}
+package service
+
+import (
+	"aps_crm/constvar"
+	"aps_crm/model"
+	"aps_crm/pkg/ecode"
+)
+
+type SContractService struct{}
+
+func (SContractService) AddServiceContract(serviceContract *model.ServiceContract) int {
+	err := model.NewServiceContractSearch().Create(serviceContract)
+	if err != nil {
+		return ecode.SContractExist
+	}
+
+	return ecode.OK
+}
+
+func (SContractService) UpdateServiceContract(serviceContract *model.ServiceContract) int {
+	// check serviceContract exist
+	_, err := model.NewServiceContractSearch().SetId(serviceContract.Id).Find()
+	if err != nil {
+		return ecode.SContractNotExist
+	}
+
+	err = model.NewServiceContractSearch().SetId(serviceContract.Id).Update(serviceContract)
+	if err != nil {
+		return ecode.SContractSetErr
+	}
+
+	return ecode.OK
+}
+
+//func (SContractService) GetServiceContractByContractId(contractId int) ([]*model.ServiceContract, int) {
+//	list, err := model.NewServiceContractSearch().SetId(contractId).FindAll()
+//	if err != nil {
+//		return nil, ecode.SContractListErr
+//	}
+//
+//	return list, ecode.OK
+//}
+
+func (SContractService) DeleteServiceContract(ids []int) int {
+	// delete client
+	err := model.NewServiceContractSearch().SetIds(ids).Delete()
+	if err != nil {
+		return ecode.SContractDeleteErr
+	}
+	return ecode.OK
+}
+
+func (SContractService) GetServiceContractList(page, pageSize int, queryClass constvar.ServiceContractQueryClass, keywordType constvar.ServiceContractKeywordType, keyword string) ([]*model.ServiceContract, int64, int) {
+	// get contact list
+	contacts, total, err := model.NewServiceContractSearch().
+		SetKeyword(keyword).
+		SetKeywordType(keywordType).
+		SetQueryClass(queryClass).
+		SetPage(page, pageSize).FindAll()
+	if err != nil {
+		return nil, 0, ecode.SContractListErr
+	}
+	return contacts, total, ecode.OK
+}
diff --git a/service/serviceFeeManage.go b/service/serviceFeeManage.go
index 54c8b8f..49fa66c 100644
--- a/service/serviceFeeManage.go
+++ b/service/serviceFeeManage.go
@@ -1,76 +1,81 @@
-package service
-
-import (
-	"aps_crm/model"
-	"aps_crm/pkg/ecode"
-	"aps_crm/pkg/mysqlx"
-)
-
-type FeeManageService struct{}
-
-func (FeeManageService) AddServiceFeeManage(serviceFeeManage *model.ServiceFeeManage) int {
-
-	tx := mysqlx.GetDB().Begin()
-
-	err := model.NewClientSearch(tx).Create(serviceFeeManage.Client)
-	if err != nil {
-		tx.Rollback()
-		return ecode.ClientExist
-	}
-
-	serviceFeeManage.ClientId = serviceFeeManage.Client.Id
-	err = model.NewServiceFeeManageSearch(tx).Create(serviceFeeManage)
-	if err != nil {
-		tx.Rollback()
-		return ecode.ServiceFeeManageExist
-	}
-
-	tx.Commit()
-
-	return ecode.OK
-}
-
-func (FeeManageService) UpdateServiceFeeManage(serviceFeeManage *model.ServiceFeeManage) int {
-	// check serviceFeeManage exist
-	_, err := model.NewServiceFeeManageSearch(nil).SetId(serviceFeeManage.Id).Find()
-	if err != nil {
-		return ecode.ServiceFeeManageNotExist
-	}
-
-	tx := mysqlx.GetDB().Begin()
-
-	err = model.NewServiceFeeManageSearch(tx).SetId(serviceFeeManage.Id).Update(serviceFeeManage)
-	if err != nil {
-		tx.Rollback()
-		return ecode.ServiceFeeManageSetErr
-	}
-
-	// update client
-	err = model.NewClientSearch(tx).SetId(serviceFeeManage.ClientId).Update(serviceFeeManage.Client)
-	if err != nil {
-		tx.Rollback()
-		return ecode.ClientUpdateErr
-	}
-
-	tx.Commit()
-
-	return ecode.OK
-}
-
-func (FeeManageService) GetServiceFeeManageList(page, pageSize int, keyword string) ([]*model.ServiceFeeManage, int64, int) {
-	// get contact list
-	contacts, total, err := model.NewServiceFeeManageSearch(nil).SetKeyword(keyword).SetPage(page, pageSize).FindAll()
-	if err != nil {
-		return nil, 0, ecode.ServiceFeeManageListErr
-	}
-	return contacts, total, ecode.OK
-}
-
-func (FeeManageService) DeleteServiceFeeManage(ids []int) int {
-	// delete client
-	err := model.NewServiceFeeManageSearch(nil).SetIds(ids).Delete()
-	if err != nil {
-		return ecode.ServiceFeeManageDeleteErr
-	}
-	return ecode.OK
-}
+package service
+
+import (
+	"aps_crm/constvar"
+	"aps_crm/model"
+	"aps_crm/pkg/ecode"
+	"aps_crm/pkg/mysqlx"
+)
+
+type FeeManageService struct{}
+
+func (FeeManageService) AddServiceFeeManage(serviceFeeManage *model.ServiceFeeManage) int {
+
+	tx := mysqlx.GetDB().Begin()
+
+	err := model.NewClientSearch(tx).Create(serviceFeeManage.Client)
+	if err != nil {
+		tx.Rollback()
+		return ecode.ClientExist
+	}
+
+	serviceFeeManage.ClientId = serviceFeeManage.Client.Id
+	err = model.NewServiceFeeManageSearch(tx).Create(serviceFeeManage)
+	if err != nil {
+		tx.Rollback()
+		return ecode.ServiceFeeManageExist
+	}
+
+	tx.Commit()
+
+	return ecode.OK
+}
+
+func (FeeManageService) UpdateServiceFeeManage(serviceFeeManage *model.ServiceFeeManage) int {
+	// check serviceFeeManage exist
+	_, err := model.NewServiceFeeManageSearch(nil).SetId(serviceFeeManage.Id).Find()
+	if err != nil {
+		return ecode.ServiceFeeManageNotExist
+	}
+
+	tx := mysqlx.GetDB().Begin()
+
+	err = model.NewServiceFeeManageSearch(tx).SetId(serviceFeeManage.Id).Update(serviceFeeManage)
+	if err != nil {
+		tx.Rollback()
+		return ecode.ServiceFeeManageSetErr
+	}
+
+	// update client
+	err = model.NewClientSearch(tx).SetId(serviceFeeManage.ClientId).Update(serviceFeeManage.Client)
+	if err != nil {
+		tx.Rollback()
+		return ecode.ClientUpdateErr
+	}
+
+	tx.Commit()
+
+	return ecode.OK
+}
+
+func (FeeManageService) DeleteServiceFeeManage(ids []int) int {
+	// delete client
+	err := model.NewServiceFeeManageSearch(nil).SetIds(ids).Delete()
+	if err != nil {
+		return ecode.ServiceFeeManageDeleteErr
+	}
+	return ecode.OK
+}
+
+func (FeeManageService) GetServiceFeeManageList(page, pageSize int, queryClass constvar.ServiceFeeQueryClass, keywordType constvar.ServiceFeeKeywordType, keyword string) ([]*model.ServiceFeeManage, int64, int) {
+	// get contact list
+	contacts, total, err := model.NewServiceFeeManageSearch(nil).
+		SetQueryClass(queryClass).
+		SetKeywordType(keywordType).
+		SetKeyword(keyword).
+		SetPage(page, pageSize).FindAll()
+	if err != nil {
+		return nil, 0, ecode.ServiceFeeManageListErr
+	}
+	return contacts, total, ecode.OK
+}
diff --git a/service/serviceFollowup.go b/service/serviceFollowup.go
index 43f0a2c..bdcb710 100644
--- a/service/serviceFollowup.go
+++ b/service/serviceFollowup.go
@@ -1,50 +1,54 @@
-package service
-
-import (
-	"aps_crm/model"
-	"aps_crm/pkg/ecode"
-)
-
-type FollowupService struct{}
-
-func (FollowupService) AddServiceFollowup(serviceFollowup *model.ServiceFollowup) int {
-	err := model.NewServiceFollowupSearch().Create(serviceFollowup)
-	if err != nil {
-		return ecode.ServiceFollowupExist
-	}
-
-	return ecode.OK
-}
-
-func (FollowupService) UpdateServiceFollowup(serviceFollowup *model.ServiceFollowup) int {
-	// check serviceFollowup exist
-	_, err := model.NewServiceFollowupSearch().SetId(serviceFollowup.Id).Find()
-	if err != nil {
-		return ecode.ServiceFollowupNotExist
-	}
-
-	err = model.NewServiceFollowupSearch().SetId(serviceFollowup.Id).Update(serviceFollowup)
-	if err != nil {
-		return ecode.ServiceFollowupSetErr
-	}
-
-	return ecode.OK
-}
-
-func (FollowupService) GetServiceFollowupList(page, pageSize int, keyword string) ([]*model.ServiceFollowup, int64, int) {
-	// get contact list
-	contacts, total, err := model.NewServiceFollowupSearch().SetKeyword(keyword).SetPage(page, pageSize).FindAll()
-	if err != nil {
-		return nil, 0, ecode.ServiceFollowupListErr
-	}
-	return contacts, total, ecode.OK
-}
-
-func (FollowupService) DeleteServiceFollowup(ids []int) int {
-	// delete client
-	err := model.NewServiceFollowupSearch().SetIds(ids).Delete()
-	if err != nil {
-		return ecode.ServiceFollowupDeleteErr
-	}
-	return ecode.OK
-}
+package service
+
+import (
+	"aps_crm/constvar"
+	"aps_crm/model"
+	"aps_crm/pkg/ecode"
+)
+
+type FollowupService struct{}
+
+func (FollowupService) AddServiceFollowup(serviceFollowup *model.ServiceFollowup) int {
+	err := model.NewServiceFollowupSearch().Create(serviceFollowup)
+	if err != nil {
+		return ecode.ServiceFollowupExist
+	}
+
+	return ecode.OK
+}
+
+func (FollowupService) UpdateServiceFollowup(serviceFollowup *model.ServiceFollowup) int {
+	// check serviceFollowup exist
+	_, err := model.NewServiceFollowupSearch().SetId(serviceFollowup.Id).Find()
+	if err != nil {
+		return ecode.ServiceFollowupNotExist
+	}
+
+	err = model.NewServiceFollowupSearch().SetId(serviceFollowup.Id).Update(serviceFollowup)
+	if err != nil {
+		return ecode.ServiceFollowupSetErr
+	}
+
+	return ecode.OK
+}
+
+func (FollowupService) DeleteServiceFollowup(ids []int) int {
+	// delete client
+	err := model.NewServiceFollowupSearch().SetIds(ids).Delete()
+	if err != nil {
+		return ecode.ServiceFollowupDeleteErr
+	}
+	return ecode.OK
+}
+
+func (FollowupService) GetServiceFollowupList(page, pageSize int, keywordType constvar.ServiceFollowupKeywordType, keyword string) ([]*model.ServiceFollowup, int64, int) {
+	// get contact list
+	contacts, total, err := model.NewServiceFollowupSearch().
+		SetKeywordType(keywordType).
+		SetKeyword(keyword).
+		SetPage(page, pageSize).FindAll()
+	if err != nil {
+		return nil, 0, ecode.ServiceFollowupListErr
+	}
+	return contacts, total, ecode.OK
+}
diff --git a/service/serviceOrder.go b/service/serviceOrder.go
new file mode 100644
index 0000000..c33f292
--- /dev/null
+++ b/service/serviceOrder.go
@@ -0,0 +1,64 @@
+package service
+
+import (
+	"aps_crm/model"
+	"aps_crm/model/request"
+	"aps_crm/pkg/ecode"
+)
+
+type ServiceOrderService struct{}
+
+func NewServiceOrderService() ServiceOrderService {
+	return ServiceOrderService{}
+}
+
+func (ServiceOrderService) AddServiceOrder(ServiceOrder *model.ServiceOrder) int {
+	err := model.NewServiceOrderSearch().Create(ServiceOrder)
+	if err != nil {
+		return ecode.DBErr
+	}
+
+	return ecode.OK
+}
+
+func (ServiceOrderService) DeleteServiceOrder(id int) int {
+	err := model.NewServiceOrderSearch().SetId(id).Delete()
+	if err != nil {
+		return ecode.DBErr
+	}
+	return ecode.OK
+}
+
+func (ServiceOrderService) GetServiceOrderList() ([]*model.ServiceOrder, int64, int) {
+	list, total, err := model.NewServiceOrderSearch().SetPreload(true).Find()
+	if err != nil {
+		return nil, 0, ecode.DBErr
+	}
+
+	return list, total, ecode.OK
+}
+
+func (ServiceOrderService) UpdateServiceOrders(ServiceOrders []*request.UpdateServiceOrder) int {
+	for _, v := range ServiceOrders {
+		// check ServiceOrder exist
+		_, err := model.NewServiceOrderSearch().SetId(v.Id).First()
+		if err != nil {
+			return ecode.DBErr
+		}
+
+		err = model.NewServiceOrderSearch().SetId(v.Id).Updates(map[string]interface{}{})
+		if err != nil {
+			return ecode.DBErr
+		}
+	}
+
+	return ecode.OK
+}
+
+func (ServiceOrderService) UpdateServiceOrder(serviceOrder *model.ServiceOrder) int {
+	err := model.NewServiceOrderSearch().SetId(serviceOrder.Id).Save(serviceOrder)
+	if err != nil {
+		return ecode.DBErr
+	}
+	return ecode.OK
+}
diff --git a/service/serviceType.go b/service/serviceType.go
new file mode 100644
index 0000000..59989e4
--- /dev/null
+++ b/service/serviceType.go
@@ -0,0 +1,66 @@
+package service
+
+import (
+	"aps_crm/model"
+	"aps_crm/model/request"
+	"aps_crm/pkg/ecode"
+)
+
+type ServiceTypeService struct{}
+
+func NewServiceTypeService() ServiceTypeService {
+	return ServiceTypeService{}
+}
+
+func (ServiceTypeService) AddServiceType(ServiceType *model.ServiceType) int {
+	err := model.NewServiceTypeSearch().Create(ServiceType)
+	if err != nil {
+		return ecode.DBErr
+	}
+
+	return ecode.OK
+}
+
+func (ServiceTypeService) DeleteServiceType(id int) int {
+	err := model.NewServiceTypeSearch().SetId(id).Delete()
+	if err != nil {
+		return ecode.DBErr
+	}
+	return ecode.OK
+}
+
+func (ServiceTypeService) GetServiceTypeList() ([]*model.ServiceType, int64, int) {
+	list, total, err := model.NewServiceTypeSearch().Find()
+	if err != nil {
+		return nil, 0, ecode.DBErr
+	}
+
+	return list, total, ecode.OK
+}
+
+func (ServiceTypeService) UpdateServiceTypes(ServiceTypes []*request.UpdateServiceType) int {
+	for _, v := range ServiceTypes {
+		// check ServiceType exist
+		_, err := model.NewServiceTypeSearch().SetId(v.Id).First()
+		if err != nil {
+			return ecode.DBErr
+		}
+
+		err = model.NewServiceTypeSearch().SetId(v.Id).Updates(map[string]interface{}{
+
+		})
+		if err != nil {
+			return ecode.DBErr
+		}
+	}
+
+	return ecode.OK
+}
+
+func (ServiceTypeService) UpdateServiceType(serviceType *model.ServiceType) int {
+		err := model.NewServiceTypeSearch().SetId(serviceType.Id).Save(serviceType)
+		if err != nil {
+			return ecode.DBErr
+		}
+	return ecode.OK
+}
diff --git a/service/severity.go b/service/severity.go
new file mode 100644
index 0000000..73176f4
--- /dev/null
+++ b/service/severity.go
@@ -0,0 +1,66 @@
+package service
+
+import (
+	"aps_crm/model"
+	"aps_crm/model/request"
+	"aps_crm/pkg/ecode"
+)
+
+type SeverityService struct{}
+
+func NewSeverityService() SeverityService {
+	return SeverityService{}
+}
+
+func (SeverityService) AddSeverity(Severity *model.Severity) int {
+	err := model.NewSeveritySearch().Create(Severity)
+	if err != nil {
+		return ecode.DBErr
+	}
+
+	return ecode.OK
+}
+
+func (SeverityService) DeleteSeverity(id int) int {
+	err := model.NewSeveritySearch().SetId(id).Delete()
+	if err != nil {
+		return ecode.DBErr
+	}
+	return ecode.OK
+}
+
+func (SeverityService) GetSeverityList() ([]*model.Severity, int64, int) {
+	list, total, err := model.NewSeveritySearch().Find()
+	if err != nil {
+		return nil, 0, ecode.DBErr
+	}
+
+	return list, total, ecode.OK
+}
+
+func (SeverityService) UpdateSeveritys(Severitys []*request.UpdateSeverity) int {
+	for _, v := range Severitys {
+		// check Severity exist
+		_, err := model.NewSeveritySearch().SetId(v.Id).First()
+		if err != nil {
+			return ecode.DBErr
+		}
+
+		err = model.NewSeveritySearch().SetId(v.Id).Updates(map[string]interface{}{
+
+		})
+		if err != nil {
+			return ecode.DBErr
+		}
+	}
+
+	return ecode.OK
+}
+
+func (SeverityService) UpdateSeverity(severity *model.Severity) int {
+		err := model.NewSeveritySearch().SetId(severity.Id).Save(severity)
+		if err != nil {
+			return ecode.DBErr
+		}
+	return ecode.OK
+}
diff --git a/service/timeSpent.go b/service/timeSpent.go
new file mode 100644
index 0000000..24450da
--- /dev/null
+++ b/service/timeSpent.go
@@ -0,0 +1,66 @@
+package service
+
+import (
+	"aps_crm/model"
+	"aps_crm/model/request"
+	"aps_crm/pkg/ecode"
+)
+
+type TimeSpentService struct{}
+
+func NewTimeSpentService() TimeSpentService {
+	return TimeSpentService{}
+}
+
+func (TimeSpentService) AddTimeSpent(TimeSpent *model.TimeSpent) int {
+	err := model.NewTimeSpentSearch().Create(TimeSpent)
+	if err != nil {
+		return ecode.DBErr
+	}
+
+	return ecode.OK
+}
+
+func (TimeSpentService) DeleteTimeSpent(id int) int {
+	err := model.NewTimeSpentSearch().SetId(id).Delete()
+	if err != nil {
+		return ecode.DBErr
+	}
+	return ecode.OK
+}
+
+func (TimeSpentService) GetTimeSpentList() ([]*model.TimeSpent, int64, int) {
+	list, total, err := model.NewTimeSpentSearch().Find()
+	if err != nil {
+		return nil, 0, ecode.DBErr
+	}
+
+	return list, total, ecode.OK
+}
+
+func (TimeSpentService) UpdateTimeSpents(TimeSpents []*request.UpdateTimeSpent) int {
+	for _, v := range TimeSpents {
+		// check TimeSpent exist
+		_, err := model.NewTimeSpentSearch().SetId(v.Id).First()
+		if err != nil {
+			return ecode.DBErr
+		}
+
+		err = model.NewTimeSpentSearch().SetId(v.Id).Updates(map[string]interface{}{
+
+		})
+		if err != nil {
+			return ecode.DBErr
+		}
+	}
+
+	return ecode.OK
+}
+
+func (TimeSpentService) UpdateTimeSpent(timeSpent *model.TimeSpent) int {
+		err := model.NewTimeSpentSearch().SetId(timeSpent.Id).Save(timeSpent)
+		if err != nil {
+			return ecode.DBErr
+		}
+	return ecode.OK
+}

--
Gitblit v1.8.0