Browse Source

ADD:合同评审

zoie 7 months ago
parent
commit
dea05a14ca

+ 12 - 1
conf/app.conf

@@ -10,7 +10,6 @@ Sys_Name = "ERP_STORAGE"
 NatsServer_Url = "127.0.0.1:4223"
 NatsSubj_Prefix = "Test_"
 
-
 # Mysql 线上
 MysqlServer_UrlPort = "127.0.0.1:3316"
 MysqlServer_Database = "erp_storage_test"
@@ -19,6 +18,17 @@ MysqlServer_Password = "cHFeFmxFhZJdijDn"
 MysqlServer_MaxIdleConnections = 100
 MysqlServer_MaxOpenConnections = 200
 
+# NatsSubj_Prefix = ""
+
+
+# Mysql 线上
+# MysqlServer_UrlPort = "127.0.0.1:3316"
+# MysqlServer_Database = "erp_storage"
+# MysqlServer_Username = "erp_storage"
+# MysqlServer_Password = "cHFeFmxFhZJdijDn"
+# MysqlServer_MaxIdleConnections = 100
+# MysqlServer_MaxOpenConnections = 200
+
 # Mysql Mqtt
 MysqlMqtt_UrlPort = "127.0.0.1:40306"
 MysqlMqtt_Database = "mqtt"
@@ -39,6 +49,7 @@ FilterOnlyLoginCheckURL =
 ContractApprovalUrl = "/contract"
 VerifyContractUrl = "/contract"
 PercentageApprovalUrl = "/percentage"
+ContractReviewAuditUrl = "/contractReviewList"
 # 财务uuid
 FinanceUuid = "NeGSMvREXA8xDZWo6q1YjLHTm0dJg7zc"
 

+ 2 - 0
conf/config.go

@@ -44,4 +44,6 @@ var ContractApprovalUrl, _ = beego.AppConfig.String("ContractApprovalUrl")
 var VerifyContractUrl, _ = beego.AppConfig.String("VerifyContractUrl")
 var PercentageApprovalUrl, _ = beego.AppConfig.String("PercentageApprovalUrl")
 var MyPercentageUrl, _ = beego.AppConfig.String("MyPercentageUrl")
+var ContractReviewAuditUrl, _ = beego.AppConfig.String("ContractReviewAuditUrl")
+
 var FinanceUuid, _ = beego.AppConfig.String("FinanceUuid")

+ 439 - 1
controllers/ContractReview.go

@@ -1,14 +1,23 @@
 package controllers
 
 import (
+	"ERP_storage/Nats"
 	"ERP_storage/Nats/NatsServer"
+	"ERP_storage/conf"
 	"ERP_storage/dto"
+	"ERP_storage/logs"
 	"ERP_storage/models/Account"
+	models "ERP_storage/models/ContractReview"
 	"ERP_storage/services"
+	"encoding/json"
+	"fmt"
+	natslibs "git.baozhida.cn/ERP_libs/Nats"
 	userlibs "git.baozhida.cn/ERP_libs/User"
 	"git.baozhida.cn/ERP_libs/lib"
 	beego "github.com/beego/beego/v2/server/web"
+	"github.com/xuri/excelize/v2"
 	"math"
+	"os"
 	"strconv"
 )
 
@@ -225,7 +234,7 @@ func (c *ContractReviewController) ServiceItem_Del() {
 	}
 
 	if err := s.Delete(&reqData); err != nil {
-		c.Data["json"] = lib.JSONS{Code: 202, Msg: "删除失败!"}
+		c.Data["json"] = lib.JSONS{Code: 202, Msg: err.Error()}
 		c.ServeJSON()
 		return
 	}
@@ -236,3 +245,432 @@ func (c *ContractReviewController) ServiceItem_Del() {
 	c.ServeJSON()
 	return
 }
+
+// 合同评审-用户
+func (c *ContractReviewController) List() {
+	s := services.ContractReview{}
+	reqData := dto.ContractReviewPageReq{}
+	if err := c.ParseForm(&reqData); err != nil {
+		c.Data["json"] = lib.JSONS{Code: 202, Msg: "参数错误"}
+		c.ServeJSON()
+		return
+	}
+	if err := Validate(&reqData); err != nil {
+		c.Data["json"] = lib.JSONS{Code: 202, Msg: err.Error()}
+		c.ServeJSON()
+		return
+	}
+
+	userList, _ := NatsServer.Read_User_List_All()
+	Account.Read_User_All_Map(userList)
+	reqData.T_submit = c.User.T_uuid
+	R_List, R_cnt := s.GetPage(&reqData)
+
+	var r_jsons lib.R_JSONS
+	r_jsons.Num = R_cnt
+	r_jsons.Data = R_List
+	r_jsons.Page = reqData.Page
+	r_jsons.Page_size = int(math.Ceil(float64(R_cnt) / float64(reqData.PageSize)))
+
+	c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!", Data: r_jsons}
+	c.ServeJSON()
+	return
+}
+
+// 合同评审-财务
+func (c *ContractReviewController) Finance_List() {
+	s := services.ContractReview{}
+	reqData := dto.ContractReviewPageReq{}
+	if err := c.ParseForm(&reqData); err != nil {
+		c.Data["json"] = lib.JSONS{Code: 202, Msg: "参数错误"}
+		c.ServeJSON()
+		return
+	}
+	if err := Validate(&reqData); err != nil {
+		c.Data["json"] = lib.JSONS{Code: 202, Msg: err.Error()}
+		c.ServeJSON()
+		return
+	}
+
+	userList, _ := NatsServer.Read_User_List_All()
+	Account.Read_User_All_Map(userList)
+	R_List, R_cnt := s.GetFinancePage(&reqData)
+
+	var r_jsons lib.R_JSONS
+	r_jsons.Num = R_cnt
+	r_jsons.Data = R_List
+	r_jsons.Page = reqData.Page
+	r_jsons.Page_size = int(math.Ceil(float64(R_cnt) / float64(reqData.PageSize)))
+
+	c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!", Data: r_jsons}
+	c.ServeJSON()
+	return
+}
+
+// 合同评审-财务
+func (c *ContractReviewController) Manager_List() {
+	s := services.ContractReview{}
+	reqData := dto.ContractReviewPageReq{}
+	if err := c.ParseForm(&reqData); err != nil {
+		c.Data["json"] = lib.JSONS{Code: 202, Msg: "参数错误"}
+		c.ServeJSON()
+		return
+	}
+	if err := Validate(&reqData); err != nil {
+		c.Data["json"] = lib.JSONS{Code: 202, Msg: err.Error()}
+		c.ServeJSON()
+		return
+	}
+
+	userList, _ := NatsServer.Read_User_List_All()
+	Account.Read_User_All_Map(userList)
+	R_List, R_cnt := s.GetManagerPage(&reqData)
+
+	var r_jsons lib.R_JSONS
+	r_jsons.Num = R_cnt
+	r_jsons.Data = R_List
+	r_jsons.Page = reqData.Page
+	r_jsons.Page_size = int(math.Ceil(float64(R_cnt) / float64(reqData.PageSize)))
+
+	c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!", Data: r_jsons}
+	c.ServeJSON()
+	return
+}
+
+// 负责人列表
+func (c *ContractReviewController) Submit_User_List() {
+	s := services.ContractReview{}
+	reqData := dto.ContractReviewSubmitUserPageReq{}
+	if err := c.ParseForm(&reqData); err != nil {
+		c.Data["json"] = lib.JSONS{Code: 202, Msg: "参数错误"}
+		c.ServeJSON()
+		return
+	}
+	if err := Validate(&reqData); err != nil {
+		c.Data["json"] = lib.JSONS{Code: 202, Msg: err.Error()}
+		c.ServeJSON()
+		return
+	}
+	userList, _ := NatsServer.Read_User_List_All()
+	Account.Read_User_All_Map(userList)
+	R_List, R_cnt := s.GetSubmitUserPage(&reqData)
+
+	var r_jsons lib.R_JSONS
+	r_jsons.Num = R_cnt
+	r_jsons.Data = R_List
+
+	c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!", Data: r_jsons}
+	c.ServeJSON()
+	return
+}
+func (c *ContractReviewController) Add() {
+	s := services.ContractReview{}
+
+	reqData := dto.ContractReviewInsertReq{}
+
+	if err := c.ParseForm(&reqData); err != nil {
+		c.Data["json"] = lib.JSONS{Code: 202, Msg: "参数错误"}
+		c.ServeJSON()
+		return
+	}
+	if err := json.Unmarshal([]byte(reqData.ServiceItems), &reqData.ServiceItemList); err != nil {
+		c.Data["json"] = lib.JSONS{Code: 202, Msg: "服务内容 参数错误"}
+		c.ServeJSON()
+		return
+	}
+	if err := Validate(&reqData); err != nil {
+		c.Data["json"] = lib.JSONS{Code: 202, Msg: err.Error()}
+		c.ServeJSON()
+		return
+	}
+	reqData.T_submit = c.User.T_uuid
+	Id, err := s.Insert(&reqData)
+	if err != nil {
+		c.Data["json"] = lib.JSONS{Code: 203, Msg: "添加失败"}
+		c.ServeJSON()
+		return
+	}
+
+	NatsServer.AddUserLogs(c.User.T_uuid, "合同评审", "添加", reqData)
+
+	c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!", Data: Id}
+	c.ServeJSON()
+	return
+}
+func (c *ContractReviewController) Edit() {
+	s := services.ContractReview{}
+	reqData := dto.ContractReviewUpdateReq{}
+	if err := c.ParseForm(&reqData); err != nil {
+		c.Data["json"] = lib.JSONS{Code: 202, Msg: "参数错误"}
+		c.ServeJSON()
+		return
+	}
+	if err := json.Unmarshal([]byte(reqData.ServiceItems), &reqData.ServiceItemList); err != nil {
+		c.Data["json"] = lib.JSONS{Code: 202, Msg: "服务内容 参数错误"}
+		c.ServeJSON()
+		return
+	}
+	if err := Validate(&reqData); err != nil {
+		c.Data["json"] = lib.JSONS{Code: 202, Msg: err.Error()}
+		c.ServeJSON()
+		return
+	}
+
+	if err := s.Update(&reqData); err != nil {
+		c.Data["json"] = lib.JSONS{Code: 203, Msg: err.Error()}
+		c.ServeJSON()
+		return
+	}
+
+	NatsServer.AddUserLogs(c.User.T_uuid, "合同评审", "修改", reqData)
+
+	c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!"}
+	c.ServeJSON()
+	return
+}
+
+// 提交审核
+func (c *ContractReviewController) Submit_Audit() {
+	s := services.ContractReview{}
+	reqData := dto.ContractReviewGetReq{}
+	if err := c.ParseForm(&reqData); err != nil {
+		c.Data["json"] = lib.JSONS{Code: 202, Msg: "参数错误"}
+		c.ServeJSON()
+		return
+	}
+	if err := Validate(&reqData); err != nil {
+		c.Data["json"] = lib.JSONS{Code: 202, Msg: err.Error()}
+		c.ServeJSON()
+		return
+	}
+
+	if err := s.SubmitAudit(&reqData); err != nil {
+		c.Data["json"] = lib.JSONS{Code: 203, Msg: err.Error()}
+		c.ServeJSON()
+		return
+	}
+
+	NatsServer.AddUserLogs(c.User.T_uuid, "合同评审", "提交审核", reqData)
+
+	c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!"}
+	c.ServeJSON()
+	return
+}
+
+// 财务审核
+func (c *ContractReviewController) Finance_Audit() {
+	s := services.ContractReview{}
+	reqData := dto.ContractReviewAuditReq{}
+	if err := c.ParseForm(&reqData); err != nil {
+		c.Data["json"] = lib.JSONS{Code: 202, Msg: "参数错误"}
+		c.ServeJSON()
+		return
+	}
+	if err := Validate(&reqData); err != nil {
+		c.Data["json"] = lib.JSONS{Code: 202, Msg: err.Error()}
+		c.ServeJSON()
+		return
+	}
+	if !(reqData.T_audit == 3 || reqData.T_audit == 4) {
+		c.Data["json"] = lib.JSONS{Code: 202, Msg: "状态参数错误"}
+		c.ServeJSON()
+		return
+	}
+
+	if err := s.FinanceAudit(&reqData); err != nil {
+		c.Data["json"] = lib.JSONS{Code: 203, Msg: err.Error()}
+		c.ServeJSON()
+		return
+	}
+
+	NatsServer.AddUserLogs(c.User.T_uuid, "合同评审", "财务审核", reqData)
+
+	c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!"}
+	c.ServeJSON()
+	return
+}
+
+// 管理员审核
+func (c *ContractReviewController) Manager_Audit() {
+	s := services.ContractReview{}
+	reqData := dto.ContractReviewAuditReq{}
+	if err := c.ParseForm(&reqData); err != nil {
+		c.Data["json"] = lib.JSONS{Code: 202, Msg: "参数错误"}
+		c.ServeJSON()
+		return
+	}
+	if err := Validate(&reqData); err != nil {
+		c.Data["json"] = lib.JSONS{Code: 202, Msg: err.Error()}
+		c.ServeJSON()
+		return
+	}
+	if !(reqData.T_audit == 5 || reqData.T_audit == 6) {
+		c.Data["json"] = lib.JSONS{Code: 202, Msg: "状态参数错误"}
+		c.ServeJSON()
+		return
+	}
+
+	if err := s.ManagerAudit(&reqData); err != nil {
+		c.Data["json"] = lib.JSONS{Code: 203, Msg: err.Error()}
+		c.ServeJSON()
+		return
+	}
+
+	NatsServer.AddUserLogs(c.User.T_uuid, "合同评审", "总经理审核", reqData)
+
+	c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!"}
+	c.ServeJSON()
+	return
+}
+func (c *ContractReviewController) Del() {
+	s := services.ContractReview{}
+	reqData := dto.ContractReviewDeleteReq{}
+	if err := c.ParseForm(&reqData); err != nil {
+		c.Data["json"] = lib.JSONS{Code: 202, Msg: "参数错误"}
+		c.ServeJSON()
+		return
+	}
+	if err := Validate(&reqData); err != nil {
+		c.Data["json"] = lib.JSONS{Code: 202, Msg: err.Error()}
+		c.ServeJSON()
+		return
+	}
+
+	if err := s.Delete(&reqData); err != nil {
+		c.Data["json"] = lib.JSONS{Code: 202, Msg: err.Error()}
+		c.ServeJSON()
+		return
+	}
+
+	NatsServer.AddUserLogs(c.User.T_uuid, "合同评审", "删除", strconv.Itoa(reqData.T_id))
+
+	c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!"}
+	c.ServeJSON()
+	return
+}
+
+func (c *ContractReviewController) Stock_Detail_Excel() {
+	s := services.ContractReview{}
+	reqData := dto.ContractReviewPageReq{}
+	if err := c.ParseForm(&reqData); err != nil {
+		c.Data["json"] = lib.JSONS{Code: 202, Msg: "参数错误"}
+		c.ServeJSON()
+		return
+	}
+	if err := Validate(&reqData); err != nil {
+		c.Data["json"] = lib.JSONS{Code: 202, Msg: err.Error()}
+		c.ServeJSON()
+		return
+	}
+
+	userList, _ := NatsServer.Read_User_List_All()
+	Account.Read_User_All_Map(userList)
+	reqData.PageSize = 9999
+	R_List, _ := s.GetFinancePage(&reqData)
+
+	filename := fmt.Sprintf("合同评审统计表(%s)", lib.GetRandstring(6, "0123456789", 0))
+
+	f := excelize.NewFile() // 设置单元格的值
+	Style1, _ := f.NewStyle(
+		&excelize.Style{
+			Font:      &excelize.Font{Bold: true, Size: 12, Family: "宋体"},
+			Alignment: &excelize.Alignment{Horizontal: "center", Vertical: "center"},
+		})
+
+	Style2, _ := f.NewStyle(
+		&excelize.Style{
+			Font:      &excelize.Font{Bold: true, Size: 10, Family: "宋体"},
+			Alignment: &excelize.Alignment{Horizontal: "center", Vertical: "center", WrapText: true},
+			Border: []excelize.Border{
+				{Type: "left", Color: "000000", Style: 1},
+				{Type: "top", Color: "000000", Style: 1},
+				{Type: "bottom", Color: "000000", Style: 1},
+				{Type: "right", Color: "000000", Style: 1},
+			},
+		})
+
+	f.MergeCell("Sheet1", "A1", "I1")
+	f.SetRowStyle("Sheet1", 1, 1, Style1)
+	f.SetCellValue("Sheet1", "A1", fmt.Sprintf("宝智达科技合同评审统计表"))
+	f.SetRowHeight("Sheet1", 1, 30)
+	// 这里设置表头
+	f.SetCellStyle("Sheet1", "A2", "I2", Style2)
+	f.SetRowHeight("Sheet1", 2, 20)
+
+	f.SetCellValue("Sheet1", "A2", "序号")
+	f.SetCellValue("Sheet1", "B2", "状态")
+	f.SetCellValue("Sheet1", "C2", "项目名称")
+	f.SetCellValue("Sheet1", "D2", "项目地址")
+	f.SetCellValue("Sheet1", "E2", "项目负责人")
+	f.SetCellValue("Sheet1", "F2", "预计签约时间")
+	f.SetCellValue("Sheet1", "G2", "总金额")
+	f.SetCellValue("Sheet1", "H2", "是否有居间费")
+	f.SetCellValue("Sheet1", "I2", "居间费金额")
+	// 设置列宽
+	f.SetColWidth("Sheet1", "A", "A", 10)
+	f.SetColWidth("Sheet1", "B", "B", 10)
+	f.SetColWidth("Sheet1", "C", "D", 15)
+	f.SetColWidth("Sheet1", "D", "D", 20)
+	f.SetColWidth("Sheet1", "E", "E", 12)
+	f.SetColWidth("Sheet1", "F", "F", 12)
+	f.SetColWidth("Sheet1", "G", "G", 10)
+	f.SetColWidth("Sheet1", "H", "H", 12)
+	f.SetColWidth("Sheet1", "I", "I", 10)
+	line := 2
+
+	// 循环写入数据
+	for _, v := range R_List {
+		line++
+
+		f.SetCellValue("Sheet1", fmt.Sprintf("A%d", line), line-2)
+		f.SetCellValue("Sheet1", fmt.Sprintf("B%d", line), models.Get_T_audit_name(v.T_audit))
+		f.SetCellValue("Sheet1", fmt.Sprintf("C%d", line), v.T_name)
+		f.SetCellValue("Sheet1", fmt.Sprintf("D%d", line), v.T_address)
+		f.SetCellValue("Sheet1", fmt.Sprintf("E%d", line), v.T_submit_name)
+		f.SetCellValue("Sheet1", fmt.Sprintf("F%d", line), v.T_predict_sign_time)
+		f.SetCellValue("Sheet1", fmt.Sprintf("G%d", line), v.T_money)
+		T_have_brokerage_fee_str := "否"
+		if v.T_have_brokerage_fee == true {
+			T_have_brokerage_fee_str = "是"
+		}
+		f.SetCellValue("Sheet1", fmt.Sprintf("H%d", line), T_have_brokerage_fee_str)
+		f.SetCellValue("Sheet1", fmt.Sprintf("I%d", line), v.T_brokerage_fee_money)
+
+	}
+	Style4, _ := f.NewStyle(
+		&excelize.Style{
+			Font:      &excelize.Font{Size: 10, Family: "宋体"},
+			Alignment: &excelize.Alignment{Horizontal: "center", Vertical: "center", WrapText: true},
+			Border: []excelize.Border{
+				{Type: "left", Color: "000000", Style: 1},
+				{Type: "top", Color: "000000", Style: 1},
+				{Type: "bottom", Color: "000000", Style: 1},
+				{Type: "right", Color: "000000", Style: 1},
+			},
+		})
+
+	f.SetCellStyle("Sheet1", "A2", fmt.Sprintf("I%d", line), Style4)
+
+	// 保存文件
+	if err := f.SaveAs("ofile/" + filename + ".xlsx"); err != nil {
+		fmt.Println(err)
+	}
+	var url string
+	//// 上传 OSS
+	nats := natslibs.NewNats(Nats.Nats, conf.NatsSubj_Prefix)
+	url, is := nats.Qiniu_UploadFile(lib.GetCurrentDirectory()+"/ofile/"+filename+".xlsx", "ofile/"+filename+".xlsx")
+	if !is {
+		c.Data["json"] = lib.JSONS{Code: 202, Msg: "oss!"}
+		c.ServeJSON()
+		return
+	}
+	//删除目录
+	err := os.Remove("ofile/" + filename + ".xlsx")
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+	}
+
+	c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!", Data: url}
+	c.ServeJSON()
+	return
+}

+ 111 - 0
dto/ContractReview.go

@@ -0,0 +1,111 @@
+package dto
+
+import (
+	models "ERP_storage/models/ContractReview"
+)
+
+// ContractReviewPageReq 列表或者搜索使用结构体
+type ContractReviewPageReq struct {
+	Pagination `search:"-"`
+	T_name     string `form:"T_name" search:"type:contains;column:t_name;table:contract_review"`  // 名称
+	T_submit   string `form:"T_submit" search:"type:exact;column:t_submit;table:contract_review"` // 负责人
+	T_audit    string `form:"T_audit" search:"type:exact;column:t_audit;table:contract_review"`   // 审核状态
+	ContractReviewOrder
+}
+type ContractReviewOrder struct {
+	IdOrder string `search:"type:order;column:id;table:contract_review" form:"T_id" default:"desc"`
+}
+
+func (m *ContractReviewPageReq) GetNeedSearch() interface{} {
+	return *m
+}
+
+type ContractReviewSubmitUserPageReq struct {
+	T_type string `form:"T_type" search:"-"` // 类型 财务Finance 总经理Manager
+}
+type ContractReviewSubmitUserPageRes struct {
+	T_submit string
+	T_name   string
+}
+
+// ContractReviewInsertReq 增使用的结构体
+type ContractReviewInsertReq struct {
+	T_name                string  `form:"T_name" vd:"len($)>0;msg:'项目名称不能为空'"` // 项目名称
+	T_address             string  `form:"T_address"`                           // 项目地址
+	T_submit              string  `json:"T_submit"`                            // 合同负责人
+	T_predict_sign_time   string  `form:"T_predict_sign_time"`                 // 预计签约时间
+	T_money               float64 `form:"T_money"`                             // 总金额
+	T_have_brokerage_fee  bool    `form:"T_have_brokerage_fee"`                // 是否有居间费
+	T_brokerage_fee_money float64 `form:"T_brokerage_fee_money"`               // 是否有居间费
+
+	ServiceItems    string                             `json:"ServiceItems"`    // 服务内容
+	ServiceItemList []models.ContractReviewServiceItem `json:"ServiceItemList"` // 服务内容
+}
+
+func (s *ContractReviewInsertReq) Generate(model *models.ContractReview) {
+	model.T_name = s.T_name
+	model.T_address = s.T_address
+	model.T_submit = s.T_submit
+	model.T_predict_sign_time = s.T_predict_sign_time
+	model.T_money = s.T_money
+	model.T_have_brokerage_fee = s.T_have_brokerage_fee
+	model.T_brokerage_fee_money = s.T_brokerage_fee_money
+	model.T_audit = 1
+	model.T_State = 1
+}
+
+// ContractReviewUpdateReq 改使用的结构体
+type ContractReviewUpdateReq struct {
+	T_id                  int     `form:"T_id"  example:"1"`
+	T_name                string  `form:"T_name" vd:"len($)>0;msg:'项目名称不能为空'"` // 项目名称
+	T_address             string  `form:"T_address"`                           // 项目地址
+	T_predict_sign_time   string  `form:"T_predict_sign_time"`                 // 预计签约时间
+	T_money               float64 `form:"T_money"`                             // 总金额
+	T_have_brokerage_fee  bool    `form:"T_have_brokerage_fee"`                // 是否有居间费
+	T_brokerage_fee_money float64 `form:"T_brokerage_fee_money"`               // 是否有居间费
+
+	ServiceItems    string                             `json:"ServiceItems"`    // 服务内容
+	ServiceItemList []models.ContractReviewServiceItem `json:"ServiceItemList"` // 服务内容
+}
+
+func (s *ContractReviewUpdateReq) Generate(model *models.ContractReview) {
+	model.Id = s.T_id
+	model.T_name = s.T_name
+	model.T_address = s.T_address
+	model.T_predict_sign_time = s.T_predict_sign_time
+	model.T_money = s.T_money
+	model.T_have_brokerage_fee = s.T_have_brokerage_fee
+	model.T_brokerage_fee_money = s.T_brokerage_fee_money
+}
+
+func (s *ContractReviewUpdateReq) GetId() interface{} {
+	return s.T_id
+}
+
+// ContractReviewGetReq 获取单个的结构体
+type ContractReviewGetReq struct {
+	T_id int `form:"T_id"`
+}
+
+func (s *ContractReviewGetReq) GetId() interface{} {
+	return s.T_id
+}
+
+// ContractReviewDeleteReq 删除的结构体
+type ContractReviewDeleteReq struct {
+	T_id int `form:"T_id"`
+}
+
+func (s *ContractReviewDeleteReq) GetId() interface{} {
+	return s.T_id
+}
+
+type ContractReviewAuditReq struct {
+	T_id               int    `form:"T_id"  example:"1"`
+	T_audit            int    `form:"T_audit" vd:"$>0;msg:'项目名称不能为空'"` // 审核 财务通过3 财务驳回4 总经理通过5 总经理驳回6
+	T_approval_opinion string `form:"T_approval_opinion"`              // 审批意见
+}
+
+func (s *ContractReviewAuditReq) GetId() interface{} {
+	return s.T_id
+}

+ 3 - 2
dto/ServiceItem.go

@@ -7,8 +7,9 @@ import (
 // ServiceItemPageReq 列表或者搜索使用结构体
 type ServiceItemPageReq struct {
 	Pagination        `search:"-"`
-	T_name            string `form:"T_name" search:"type:contains;column:t_name;table:service_item"`                       // 服务内容
-	T_service_type_id int    `form:"T_service_type_id" search:"type:contains;column:T_service_type_id;table:service_item"` // 服务类型id
+	T_name            string `form:"T_name" search:"type:contains;column:t_name;table:service_item"`                    // 服务内容
+	T_service_type_id int    `form:"T_service_type_id" search:"type:exact;column:t_service_type_id;table:service_item"` // 服务类型id
+	T_sale_type       string `form:"T_sale_type" search:"type:contains;column:t_sale_type;table:service_item"`          // 销售类型
 }
 
 func (m *ServiceItemPageReq) GetNeedSearch() interface{} {

+ 1 - 1
dto/ServiceType.go

@@ -16,7 +16,7 @@ func (m *ServiceTypePageReq) GetNeedSearch() interface{} {
 
 // ServiceTypeInsertReq 增使用的结构体
 type ServiceTypeInsertReq struct {
-	T_name string `form:"T_name" example:"服务类型" valid:"MinSize(1)"` //服务类型
+	T_name string `form:"T_name" example:"服务类型"  vd:"len($)>0;msg:'服务类型不能为空'"` //服务类型
 }
 
 func (s *ServiceTypeInsertReq) Generate(model *models.ServiceType) {

+ 3 - 0
dto/search.go

@@ -90,6 +90,9 @@ func MakeCondition(q interface{}) func(db *gorm.DB) *gorm.DB {
 
 func Paginate(pageSize, pageIndex int) func(db *gorm.DB) *gorm.DB {
 	return func(db *gorm.DB) *gorm.DB {
+		if pageSize == 9999 {
+			return db
+		}
 		offset := (pageIndex - 1) * pageSize
 		if offset < 0 {
 			offset = 0

+ 5 - 1
go.mod

@@ -8,9 +8,11 @@ require (
 	git.baozhida.cn/ERP_libs v0.0.0-00010101000000-000000000000
 	github.com/astaxie/beego v1.12.3
 	github.com/beego/beego/v2 v2.0.7
+	github.com/bytedance/go-tagexpr/v2 v2.9.11
 	github.com/go-sql-driver/mysql v1.7.0
 	github.com/nats-io/nats.go v1.23.0
 	github.com/robfig/cron/v3 v3.0.1
+	github.com/smartystreets/goconvey v1.8.1
 	github.com/vmihailenco/msgpack/v5 v5.3.5
 	github.com/xuri/excelize/v2 v2.7.1
 	gorm.io/driver/mysql v1.5.7
@@ -21,13 +23,14 @@ require (
 	github.com/andeya/ameda v1.5.3 // indirect
 	github.com/andeya/goutil v1.0.1 // indirect
 	github.com/beorn7/perks v1.0.1 // indirect
-	github.com/bytedance/go-tagexpr/v2 v2.9.11 // indirect
 	github.com/cespare/xxhash/v2 v2.1.2 // indirect
 	github.com/golang/protobuf v1.5.4 // indirect
 	github.com/gomodule/redigo v2.0.0+incompatible // indirect
+	github.com/gopherjs/gopherjs v1.17.2 // indirect
 	github.com/hashicorp/golang-lru v0.5.4 // indirect
 	github.com/jinzhu/inflection v1.0.0 // indirect
 	github.com/jinzhu/now v1.1.5 // indirect
+	github.com/jtolds/gls v4.20.0+incompatible // indirect
 	github.com/klauspost/compress v1.15.15 // indirect
 	github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect
 	github.com/minio/highwayhash v1.0.2 // indirect
@@ -50,6 +53,7 @@ require (
 	github.com/shiena/ansicolor v0.0.0-20200904210342-c7312218db18 // indirect
 	github.com/shopspring/decimal v1.3.1 // indirect
 	github.com/signintech/gopdf v0.16.1 // indirect
+	github.com/smarty/assertions v1.15.0 // indirect
 	github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
 	github.com/xuri/efp v0.0.0-20220603152613-6918739fd470 // indirect
 	github.com/xuri/nfp v0.0.0-20220409054826-5e722a1d9e22 // indirect

+ 9 - 7
go.sum

@@ -136,7 +136,6 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD
 github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
 github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
 github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
-github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
 github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
 github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
 github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
@@ -169,6 +168,8 @@ github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hf
 github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
 github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
 github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
+github.com/gopherjs/gopherjs v1.17.2 h1:fQnZVsXk8uxXIStYb0N4bGk7jeyTalG/wsZjQ25dO0g=
+github.com/gopherjs/gopherjs v1.17.2/go.mod h1:pRRIvn/QzFLrKfvEz3qUuEhtE/zLCWfreZ6J5gM2i+k=
 github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
 github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
 github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc=
@@ -186,6 +187,8 @@ github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/
 github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
 github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
 github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
+github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
+github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
 github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
 github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
 github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
@@ -308,6 +311,10 @@ github.com/signintech/gopdf v0.16.1/go.mod h1:wrLtZoWaRNrS4hphED0oflFoa6IWkOu6M3
 github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
 github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
 github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
+github.com/smarty/assertions v1.15.0 h1:cR//PqUBUiQRakZWqBiFFQ9wb8emQGDb0HeGdqGByCY=
+github.com/smarty/assertions v1.15.0/go.mod h1:yABtdzeQs6l1brC900WlRNwj6ZR55d7B+E8C6HtKdec=
+github.com/smartystreets/goconvey v1.8.1 h1:qGjIddxOk4grTu9JPOU31tVfq3cNdBlNa5sSznIX1xY=
+github.com/smartystreets/goconvey v1.8.1/go.mod h1:+/u4qLyY6x1jReYOp7GOM2FSt8aP9CzCZL03bI28W60=
 github.com/ssdb/gossdb v0.0.0-20180723034631-88f6b59b84ec/go.mod h1:QBvMkMya+gXctz3kmljlUCu/yB3GZ6oee+dUozsezQE=
 github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
 github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
@@ -318,8 +325,8 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P
 github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
 github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
 github.com/stretchr/testify v1.7.5/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
-github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
 github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
+github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
 github.com/syndtr/goleveldb v0.0.0-20160425020131-cfa635847112/go.mod h1:Z4AUp2Km+PwemOoO/VB5AOx9XSsIItzFjoJlOSiYmn0=
 github.com/syndtr/goleveldb v0.0.0-20181127023241-353a9fca669c/go.mod h1:Z4AUp2Km+PwemOoO/VB5AOx9XSsIItzFjoJlOSiYmn0=
 github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
@@ -445,7 +452,6 @@ golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJ
 golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
 golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
 golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
@@ -510,8 +516,6 @@ golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
 golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
 golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
-golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
-golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
 golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
 golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
 golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
@@ -640,8 +644,6 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba
 google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
 google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
 google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
-google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w=
-google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
 google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
 google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
 gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=

+ 4 - 3
main.go

@@ -70,9 +70,10 @@ func main() {
 	beego.BConfig.RecoverPanic = true
 	beego.BConfig.RecoverFunc = RecoverPanic
 
-	go Basic.Read_ProductClass_All_Map()  // 初始化产品类型
-	go controllers.Cron_StockMonth()      // 库存明细详情定时任务
-	go controllers.Cron_VerifyContract()  // 验证合同状态修改定时任务
+	go Basic.Read_ProductClass_All_Map() // 初始化产品类型
+	go controllers.Cron_StockMonth()     // 库存明细详情定时任务
+	go controllers.Cron_VerifyContract() // 验证合同状态修改定时任务
+	//go controllers.Cron_Device_Add()      // 重写设备表 只执行一次
 	go controllers.CheckPowerUniformity() // 检查角色是否与用户系统一致,不存在则添加
 	beego.Run()
 

+ 22 - 7
models/ContractReview/ServiceItem.go

@@ -7,16 +7,16 @@ import (
 // 服务内容
 type ServiceItem struct {
 	Id                int    `json:"Id" gorm:"primaryKey;autoIncrement;comment:主键编码"` // 主键编码
-	T_name            string `json:"T_name" gorm:"size:128" `                             // 服务内容
-	T_service_type_id int    `json:"T_service_type_id" gorm:"size:128" `                  // 服务类型id
-	T_sale_type       string `json:"T_sale_type" gorm:"size:128"`                         // 销售类型
-	T_model           string `json:"T_model" gorm:"size:128"`                             // 型号
-	T_spec            string `json:"T_spec" gorm:"size:128"`                              // 规格
+	T_name            string `json:"T_name" gorm:"size:128" `                         // 服务内容
+	T_service_type_id int    `json:"T_service_type_id" gorm:"size:128" `              // 服务类型id
+	T_sale_type       string `json:"T_sale_type" gorm:"size:128"`                     // 销售类型
+	T_model           string `json:"T_model" gorm:"size:128"`                         // 型号
+	T_spec            string `json:"T_spec" gorm:"size:128"`                          // 规格
 
 	ServiceType ServiceTypeOmit `json:"ServiceType" gorm:"->;foreignkey:T_service_type_id;references:Id"` // 角色
 
-	T_State    int     `json:"T_State" gorm:"column:t__state;size(2);default(1)"`                        // 0 删除(伪删除)   1 正常
-	CreateTime db.Time `json:"CreateTime" gorm:"column:create_time;autoCreateTime;comment:创建时间"`     // 创建时间
+	T_State    int     `json:"T_State" gorm:"column:t__state;size(2);default(1)"`                  // 0 删除(伪删除)   1 正常
+	CreateTime db.Time `json:"CreateTime" gorm:"column:create_time;autoCreateTime;comment:创建时间"`   // 创建时间
 	UpdateTime db.Time `json:"UpdateTime" gorm:"column:update_time;autoUpdateTime;comment:最后更新时间"` // 最后更新时间
 
 }
@@ -24,3 +24,18 @@ type ServiceItem struct {
 func (e *ServiceItem) TableName() string {
 	return "service_item"
 }
+
+type ServiceItemOmit struct {
+	Id                int    `json:"Id" gorm:"primaryKey;autoIncrement;comment:主键编码"` // 主键编码
+	T_name            string `json:"T_name" gorm:"size:128" `                         // 服务内容
+	T_service_type_id int    `json:"T_service_type_id" gorm:"size:128" `              // 服务类型id
+	T_sale_type       string `json:"T_sale_type" gorm:"size:128"`                     // 销售类型
+	T_model           string `json:"T_model" gorm:"size:128"`                         // 型号
+	T_spec            string `json:"T_spec" gorm:"size:128"`                          // 规格
+
+	ServiceType ServiceTypeOmit `json:"ServiceType" gorm:"->;foreignkey:T_service_type_id;references:Id"` // 角色
+}
+
+func (e *ServiceItemOmit) TableName() string {
+	return "service_item"
+}

+ 67 - 0
models/ContractReview/contractReview.go

@@ -1 +1,68 @@
 package ContractReview
+
+import db "ERP_storage/initialize"
+
+func Get_T_audit_name(T_audt int) string {
+	switch T_audt {
+	case 1:
+		return "待提交审核"
+	case 2:
+		return "待审核"
+	case 3:
+		return "财务通过"
+	case 4:
+		return "财务驳回"
+	case 5:
+		return "总经理通过"
+	case 6:
+		return "总经理驳回"
+	default:
+		return ""
+	}
+
+}
+
+type ContractReview struct {
+	Id                         int     `json:"Id" gorm:"primaryKey;autoIncrement;comment:主键编码"` // 主键编码
+	T_name                     string  `json:"T_name" gorm:"size:128"`                              // 项目名称
+	T_address                  string  `json:"T_address" gorm:"size:128"`                           // 项目地址
+	T_submit                   string  `json:"T_submit" gorm:"size:128"`                            // 合同负责人
+	T_predict_sign_time        string  `json:"T_predict_sign_time" gorm:"size:128"`                 // 预计签约时间
+	T_money                    float64 `json:"T_money" gorm:"type:decimal(10,2)"`                   // 总金额
+	T_have_brokerage_fee       bool    `json:"T_have_brokerage_fee" gorm:"size:4"`                  // 是否有居间费
+	T_brokerage_fee_money      float64 `json:"T_brokerage_fee_money" gorm:"type:decimal(10,2)"`     // 是否有居间费
+	T_audit                    int     `json:"T_audit" gorm:"size:4"`                               // 审核状态 待提交审核1 待审核2 财务通过3 财务驳回4 总经理通过5 总经理驳回6
+	T_finance_approval_opinion string  `json:"T_finance_approval_opinion" gorm:"size:text"`         // 财务审批意见
+	T_manager_approval_opinion string  `json:"T_manager_approval_opinion" gorm:"size:text"`         // 总经理审批意见
+
+	ServiceItemList []ContractReviewServiceItem `json:"ServiceItemList" gorm:"->;foreignkey:T_contract_review_id;references:Id"` // 角色
+
+	T_State    int     `json:"T_State" gorm:"column:t__state;size(2);default(1)"`                        // 0 删除(伪删除)   1 正常
+	CreateTime db.Time `json:"CreateTime" gorm:"column:create_time;autoCreateTime;comment:创建时间"`     // 创建时间
+	UpdateTime db.Time `json:"UpdateTime" gorm:"column:update_time;autoUpdateTime;comment:最后更新时间"` // 最后更新时间
+
+	T_submit_name string `json:"T_submit_name" gorm:"-"` // 合同负责人名称
+
+}
+
+func (e *ContractReview) TableName() string {
+	return "contract_review"
+}
+
+type ContractReviewServiceItem struct {
+	Id                   int             `json:"Id" gorm:"primaryKey;autoIncrement;comment:主键编码"` // 主键编码
+	T_contract_review_id int             `json:"T_contract_review_id" gorm:"size:128"`
+	T_service_item_id    int             `json:"T_service_item_id" gorm:"size:128"`      // 服务内容id
+	T_quantity           int             `json:"T_quantity" gorm:"size:128"`             // 数量
+	T_unit_price         float64         `json:"T_unit_price" gorm:"type:decimal(10,2)"` // 单价
+	T_remark             string          `json:"T_remark" gorm:"type:text"`              // 备注
+	ServiceItem          ServiceItemOmit `json:"ServiceItem" gorm:"->;foreignkey:T_service_item_id;references:Id"`
+
+	T_State    int     `json:"T_State" gorm:"column:t__state;size(2);default(1)"`               // 0 删除(伪删除)   1 正常
+	CreateTime db.Time `json:"-" gorm:"column:create_time;autoCreateTime;comment:创建时间"`     // 创建时间
+	UpdateTime db.Time `json:"-" gorm:"column:update_time;autoUpdateTime;comment:最后更新时间"` // 最后更新时间
+}
+
+func (e *ContractReviewServiceItem) TableName() string {
+	return "contract_review_service_item"
+}

+ 2 - 0
models/init.go

@@ -17,6 +17,8 @@ func AutoMigrateDB() {
 		AutoMigrate(
 			&ContractReview.ServiceType{},
 			&ContractReview.ServiceItem{},
+			&ContractReview.ContractReview{},
+			&ContractReview.ContractReviewServiceItem{},
 		)
 	if err != nil {
 		log.Fatalf("migrate db fail: %v", err)

+ 13 - 11
routers/ContractReview.go

@@ -18,17 +18,19 @@ func init() {
 		beego.NSRouter("/Edit", &controllers.ContractReviewController{}, "*:ServiceItem_Edit"), // 编辑服务内容
 		beego.NSRouter("/Del", &controllers.ContractReviewController{}, "*:ServiceItem_Del"),   // 删除服务内容
 	)
-	contractReview := beego.NewNamespace("/ContractReview") //beego.NSRouter("/List", &controllers.ContractReviewController{}, "*:Contract_List"),                 // 服务评审列表
-	//beego.NSRouter("/User_List", &controllers.ContractReviewController{}, "*:Contract_User_List"),       // 服务评审列表 - 销售人员
-	//beego.NSRouter("/Get", &controllers.ContractReviewController{}, "*:Contract_Get"),                   // 服务评审详情
-	//beego.NSRouter("/Approval", &controllers.ContractReviewController{}, "*:Contract_Approval"),         // 服务评审详情
-	//beego.NSRouter("/Add", &controllers.ContractReviewController{}, "*:Contract_Add"),                   // 添加服务评审
-	//beego.NSRouter("/Edit", &controllers.ContractReviewController{}, "*:Contract_Edit"),                 // 编辑服务评审
-	//beego.NSRouter("/Del", &controllers.ContractReviewController{}, "*:Contract_Del"),                   // 删除服务评审
-	//beego.NSRouter("/Product_List", &controllers.ContractReviewController{}, "*:Contract_Product_List"), // 服务评审产品列表
-	//beego.NSRouter("/Out_List", &controllers.ContractReviewController{}, "*:Contract_List_For_Out"),     // 服务评审产品列表
-	//beego.NSRouter("/Gen_Number", &controllers.ContractReviewController{}, "*:Contract_GenT_number"),    // 生成服务评审编号
-	//beego.NSRouter("/Stat", &controllers.ContractReviewController{}, "*:Contract_Stat"),                 // 统计服务评审金额
+	contractReview := beego.NewNamespace("/ContractReview",
+		beego.NSRouter("/List", &controllers.ContractReviewController{}, "*:List"),                             // 合同评审列表
+		beego.NSRouter("/Finance_List", &controllers.ContractReviewController{}, "*:Finance_List"),             // 合同评审列表 - 财务
+		beego.NSRouter("/Manager_List", &controllers.ContractReviewController{}, "*:Manager_List"),             // 合同评审列表 - 总经理
+		beego.NSRouter("/Submit_User_List", &controllers.ContractReviewController{}, "*:Submit_User_List"),     // 负责人列表
+		beego.NSRouter("/Add", &controllers.ContractReviewController{}, "*:Add"),                               // 添加合同评审
+		beego.NSRouter("/Edit", &controllers.ContractReviewController{}, "*:Edit"),                             // 编辑合同评审
+		beego.NSRouter("/Del", &controllers.ContractReviewController{}, "*:Del"),                               // 删除合同评审
+		beego.NSRouter("/Submit_Audit", &controllers.ContractReviewController{}, "*:Submit_Audit"),             // 提交审核
+		beego.NSRouter("/Finance_Audit", &controllers.ContractReviewController{}, "*:Finance_Audit"),           // 财务审核
+		beego.NSRouter("/Manager_Audit", &controllers.ContractReviewController{}, "*:Manager_Audit"),           // 总经理审核
+		beego.NSRouter("/Stock_Detail_Excel", &controllers.ContractReviewController{}, "*:Stock_Detail_Excel"), // 财务导出
 
+	)
 	beego.AddNamespace(serviceType, serviceItem, contractReview)
 }

+ 340 - 0
services/ContractReview.go

@@ -0,0 +1,340 @@
+package services
+
+import (
+	"ERP_storage/Nats/NatsServer"
+	"ERP_storage/conf"
+	"ERP_storage/dto"
+	db "ERP_storage/initialize"
+	"ERP_storage/logs"
+	"ERP_storage/models/Account"
+	models "ERP_storage/models/ContractReview"
+	"errors"
+	"fmt"
+	"git.baozhida.cn/ERP_libs/lib"
+)
+
+type ContractReview struct {
+}
+
+func (e *ContractReview) GetPage(c *dto.ContractReviewPageReq) (list []models.ContractReview, cnt int64) {
+
+	var err error
+
+	err = db.DB.Model(&models.ContractReview{}).
+		Scopes(
+			dto.MakeCondition(c.GetNeedSearch()),
+			dto.Paginate(c.GetPageSize(), c.GetPageIndex()),
+			dto.WithNormalState(),
+		).
+		Preload("ServiceItemList", "t__state = ?", 1).
+		Preload("ServiceItemList.ServiceItem.ServiceType").
+		Find(&list).Limit(-1).Offset(-1).
+		Count(&cnt).Error
+
+	if err != nil {
+		logs.Error("db error: %s ", err)
+		return
+	}
+	for i := 0; i < len(list); i++ {
+		list[i].T_submit_name = Account.Read_User_T_name_Get(list[i].T_submit)
+	}
+
+	return
+}
+func (e *ContractReview) GetFinancePage(c *dto.ContractReviewPageReq) (list []models.ContractReview, cnt int64) {
+
+	var err error
+
+	err = db.DB.Model(&models.ContractReview{}).
+		Scopes(
+			dto.MakeCondition(c.GetNeedSearch()),
+			dto.Paginate(c.GetPageSize(), c.GetPageIndex()),
+			dto.WithNormalState(),
+		).
+		Where("t_audit in (?)", []int{2, 3, 4, 5, 6}).
+		Preload("ServiceItemList", "t__state = ?", 1).
+		Preload("ServiceItemList.ServiceItem.ServiceType").
+		Find(&list).Limit(-1).Offset(-1).
+		Count(&cnt).Error
+
+	if err != nil {
+		logs.Error("db error: %s ", err)
+		return
+	}
+	for i := 0; i < len(list); i++ {
+		list[i].T_submit_name = Account.Read_User_T_name_Get(list[i].T_submit)
+	}
+
+	return
+}
+func (e *ContractReview) GetManagerPage(c *dto.ContractReviewPageReq) (list []models.ContractReview, cnt int64) {
+
+	var err error
+
+	err = db.DB.Model(&models.ContractReview{}).
+		Scopes(
+			dto.MakeCondition(c.GetNeedSearch()),
+			dto.Paginate(c.GetPageSize(), c.GetPageIndex()),
+			dto.WithNormalState(),
+		).
+		Where("t_audit in (?)", []int{3, 5, 6}).
+		Preload("ServiceItemList", "t__state = ?", 1).
+		Preload("ServiceItemList.ServiceItem.ServiceType").
+		Find(&list).Limit(-1).Offset(-1).
+		Count(&cnt).Error
+
+	if err != nil {
+		logs.Error("db error: %s ", err)
+		return
+	}
+	for i := 0; i < len(list); i++ {
+		list[i].T_submit_name = Account.Read_User_T_name_Get(list[i].T_submit)
+	}
+
+	return
+}
+func (e *ContractReview) GetSubmitUserPage(c *dto.ContractReviewSubmitUserPageReq) (list []dto.ContractReviewSubmitUserPageRes, cnt int64) {
+
+	var err error
+	if c.T_type == "Manager" {
+		err = db.DB.Model(&models.ContractReview{}).
+			Select("Distinct t_submit").
+			Scopes(
+				dto.WithNormalState(),
+			).
+			Where("t_audit in (?)", []int{3, 5, 6}).
+			Find(&list).
+			Count(&cnt).Error
+	}
+	if c.T_type == "Finance" {
+		err = db.DB.Model(&models.ContractReview{}).
+			Select("Distinct t_submit").
+			Scopes(
+				dto.WithNormalState(),
+			).
+			Where("t_audit in (?)", []int{2, 3, 4, 5, 6}).
+			Find(&list).
+			Count(&cnt).Error
+	}
+
+	if err != nil {
+		logs.Error("db error: %s ", err)
+		return
+	}
+	for i := 0; i < len(list); i++ {
+		list[i].T_name = Account.Read_User_T_name_Get(list[i].T_submit)
+	}
+
+	return
+}
+
+func (e *ContractReview) Get(Id int) (r models.ContractReview, err error) {
+	err = db.DB.Scopes(dto.WithNormalState()).First(&r, Id).Error
+	if err != nil {
+		logs.Error("db error: %s", err)
+		return
+	}
+	return
+}
+
+// 添加
+func (e *ContractReview) Insert(c *dto.ContractReviewInsertReq) (id int, err error) {
+	var data models.ContractReview
+
+	tx := db.DB.Begin()
+	defer func() {
+		if err != nil {
+			tx.Rollback()
+		} else {
+			tx.Commit()
+		}
+	}()
+	c.Generate(&data)
+	err = tx.Create(&data).Error
+	if err != nil {
+		logs.Error("db error: %s", err)
+		return
+	}
+	// 添加 服务内容
+	for i := 0; i < len(c.ServiceItemList); i++ {
+		c.ServiceItemList[i].T_contract_review_id = data.Id
+		c.ServiceItemList[i].T_State = 1
+	}
+	err = tx.Create(&c.ServiceItemList).Error
+	if err != nil {
+		logs.Error("db error: %s", err)
+		return
+	}
+	id = data.Id
+	return
+
+}
+
+// 修改
+func (e *ContractReview) Update(c *dto.ContractReviewUpdateReq) error {
+	var contractReview = models.ContractReview{}
+	err := db.DB.Scopes(dto.WithNormalState()).First(&contractReview, c.GetId()).Error
+	if err != nil {
+		logs.Error("db error: %s", err)
+		return dto.GetFailedErr
+	}
+	// 财务审核通过3 总经理审核通过5 不可修改
+	if contractReview.T_audit == 3 || contractReview.T_audit == 5 {
+		logs.Error("db error: %s", err)
+		return errors.New("审核通过后不可修改")
+	}
+	tx := db.DB.Begin()
+	defer func() {
+		if err != nil {
+			tx.Rollback()
+		} else {
+			tx.Commit()
+		}
+	}()
+	c.Generate(&contractReview)
+	err = tx.Save(&contractReview).Error
+	if err != nil {
+		logs.Error("db error: %s", err)
+		return err
+	}
+
+	// 删除之前的服务内容
+	err = tx.Model(models.ContractReviewServiceItem{}).Where("t_contract_review_id = ?", contractReview.Id).
+		Updates(map[string]interface{}{
+			"t__state": 0,
+		}).Error
+	if err != nil {
+		logs.Error("db error: %s", err)
+		return err
+	}
+
+	// 添加 新的服务内容
+	for i := 0; i < len(c.ServiceItemList); i++ {
+		c.ServiceItemList[i].Id = 0
+		c.ServiceItemList[i].T_contract_review_id = contractReview.Id
+		c.ServiceItemList[i].T_State = 1
+	}
+	err = tx.Create(&c.ServiceItemList).Error
+	if err != nil {
+		logs.Error("db error: %s", err)
+		return err
+	}
+
+	return nil
+
+}
+func (e *ContractReview) SubmitAudit(c *dto.ContractReviewGetReq) error {
+	var contractReview = models.ContractReview{}
+	err := db.DB.Scopes(dto.WithNormalState()).First(&contractReview, c.GetId()).Error
+	if err != nil {
+		logs.Error("db error: %s", err)
+		return dto.GetFailedErr
+	}
+	// 财务审核通过3 总经理审核通过5 不可修改
+	if contractReview.T_audit == 3 || contractReview.T_audit == 5 {
+		logs.Error("db error: %s", err)
+		return errors.New("审核通过后不可提交")
+	}
+	tx := db.DB.Begin()
+	defer func() {
+		if err != nil {
+			tx.Rollback()
+		} else {
+			tx.Commit()
+		}
+	}()
+	// 提交审核后修改为待审核
+	contractReview.T_audit = 2
+	err = tx.Save(&contractReview).Error
+	if err != nil {
+		logs.Error("db error: %s", err)
+		return err
+	}
+
+	return nil
+
+}
+func (e *ContractReview) FinanceAudit(c *dto.ContractReviewAuditReq) error {
+	var contractReview = models.ContractReview{}
+	err := db.DB.Scopes(dto.WithNormalState()).First(&contractReview, c.GetId()).Error
+	if err != nil {
+		logs.Error("db error: %s", err)
+		return dto.GetFailedErr
+	}
+	// 财务审核通过3 总经理审核通过5 不可修改
+	if contractReview.T_audit != 2 {
+		logs.Error("db error: %s", err)
+		return errors.New("审核通过后不可提交")
+	}
+	// 财务审核
+	contractReview.T_audit = c.T_audit
+	contractReview.T_finance_approval_opinion = c.T_approval_opinion
+	err = db.DB.Save(&contractReview).Error
+	if err != nil {
+		logs.Error("db error: %s", err)
+		return err
+	}
+
+	if c.T_audit == 3 {
+		NatsServer.AddNews(contractReview.T_submit, fmt.Sprintf("【合同评审】您提交的合同评审(%s)财务审核已通过", contractReview.T_name), conf.ContractReviewAuditUrl)
+	}
+	if c.T_audit == 4 {
+		NatsServer.AddNews(contractReview.T_submit, fmt.Sprintf("【合同评审】您提交的合同评审(%s)财务审核已驳回", contractReview.T_name), conf.ContractReviewAuditUrl)
+	}
+
+	return nil
+
+}
+func (e *ContractReview) ManagerAudit(c *dto.ContractReviewAuditReq) error {
+	var contractReview = models.ContractReview{}
+	err := db.DB.Scopes(dto.WithNormalState()).First(&contractReview, c.GetId()).Error
+	if err != nil {
+		logs.Error("db error: %s", err)
+		return dto.GetFailedErr
+	}
+
+	// 财务审核通过3 总经理审核通过5 不可修改
+	if contractReview.T_audit != 3 {
+		logs.Error("db error: %s", err)
+		return errors.New("审核通过后不可提交")
+	}
+
+	// 管理员审核
+	contractReview.T_audit = c.T_audit
+	contractReview.T_manager_approval_opinion = c.T_approval_opinion
+	err = db.DB.Save(&contractReview).Error
+	if err != nil {
+		logs.Error("db error: %s", err)
+		return err
+	}
+
+	if c.T_audit == 5 {
+		NatsServer.AddNews(contractReview.T_submit, fmt.Sprintf("【合同评审】您提交的合同评审(%s)总经理审核已通过", contractReview.T_name), conf.ContractReviewAuditUrl)
+	}
+	if c.T_audit == 6 {
+		NatsServer.AddNews(contractReview.T_submit, fmt.Sprintf("【合同评审】您提交的合同评审(%s)总经理审核已驳回", contractReview.T_name), conf.ContractReviewAuditUrl)
+	}
+
+	return nil
+
+}
+
+// 删除
+func (e *ContractReview) Delete(c *dto.ContractReviewDeleteReq) error {
+	var contractReview = models.ContractReview{}
+	err := db.DB.Scopes(dto.WithNormalState()).First(&contractReview, c.GetId()).Error
+	if err != nil {
+		logs.Error("db error: %s", err)
+		return dto.GetFailedErr
+	}
+	if contractReview.T_audit == 3 || contractReview.T_audit == 5 {
+		return errors.New("审核通过后不可删除")
+	}
+	contractReview.T_State = 0
+	err = db.DB.Save(&contractReview).Error
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+		return dto.DeleteFailedErr
+	}
+	return nil
+}

+ 26 - 22
services/ServiceItem.go

@@ -16,26 +16,16 @@ type ServiceItem struct {
 func (e *ServiceItem) GetPage(c *dto.ServiceItemPageReq) (list []models.ServiceItem, cnt int64) {
 
 	var err error
-	if c.GetPageSize() == 9999 {
-		err = db.DB.Model(&models.ServiceItem{}).
-			Scopes(
-				dto.MakeCondition(c.GetNeedSearch()),
-				dto.WithNormalState(),
-			).
-			Preload("ServiceType").
-			Find(&list).Limit(-1).Offset(-1).
-			Count(&cnt).Error
-	} else {
-		err = db.DB.Model(&models.ServiceItem{}).
-			Scopes(
-				dto.MakeCondition(c.GetNeedSearch()),
-				dto.Paginate(c.GetPageSize(), c.GetPageIndex()),
-				dto.WithNormalState(),
-			).
-			Preload("ServiceType").
-			Find(&list).Limit(-1).Offset(-1).
-			Count(&cnt).Error
-	}
+
+	err = db.DB.Model(&models.ServiceItem{}).
+		Scopes(
+			dto.MakeCondition(c.GetNeedSearch()),
+			dto.Paginate(c.GetPageSize(), c.GetPageIndex()),
+			dto.WithNormalState(),
+		).
+		Preload("ServiceType").
+		Find(&list).Limit(-1).Offset(-1).
+		Count(&cnt).Error
 
 	if err != nil {
 		logs.Error("db error: %s ", err)
@@ -100,12 +90,26 @@ func (e *ServiceItem) Delete(c *dto.ServiceItemDeleteReq) error {
 	err := db.DB.Scopes(dto.WithNormalState()).First(&serviceItem, c.GetId()).Error
 	if err != nil {
 		logs.Error("db error: %s", err)
-		return err
+		return dto.GetFailedErr
 	}
+	var ContractReviewServiceItemCount int64
+	err = db.DB.Model(&models.ContractReviewServiceItem{}).
+		Scopes(dto.WithNormalState()).
+		Where("t_service_item_id = ?", serviceItem.Id).
+		Count(&ContractReviewServiceItemCount).Error
+	if err != nil {
+		logs.Error("db error: %s", err)
+		return dto.GetFailedErr
+	}
+
+	if ContractReviewServiceItemCount > 0 {
+		return errors.New("存在已关联的合同评审,无法删除!")
+	}
+
 	serviceItem.T_State = 0
 	err = db.DB.Save(&serviceItem).Error
 	if err != nil {
 		logs.Error(lib.FuncName(), err)
 	}
-	return err
+	return dto.DeleteFailedErr
 }

+ 13 - 18
services/ServiceType.go

@@ -16,24 +16,15 @@ type ServiceType struct {
 func (e *ServiceType) GetPage(c *dto.ServiceTypePageReq) (list []models.ServiceType, cnt int64) {
 
 	var err error
-	if c.GetPageSize() == 9999 {
-		err = db.DB.Model(&models.ServiceType{}).
-			Scopes(
-				dto.MakeCondition(c.GetNeedSearch()),
-				dto.WithNormalState(),
-			).
-			Find(&list).Limit(-1).Offset(-1).
-			Count(&cnt).Error
-	} else {
-		err = db.DB.Model(&models.ServiceType{}).
-			Scopes(
-				dto.MakeCondition(c.GetNeedSearch()),
-				dto.Paginate(c.GetPageSize(), c.GetPageIndex()),
-				dto.WithNormalState(),
-			).
-			Find(&list).Limit(-1).Offset(-1).
-			Count(&cnt).Error
-	}
+
+	err = db.DB.Model(&models.ServiceType{}).
+		Scopes(
+			dto.MakeCondition(c.GetNeedSearch()),
+			dto.Paginate(c.GetPageSize(), c.GetPageIndex()),
+			dto.WithNormalState(),
+		).
+		Find(&list).Limit(-1).Offset(-1).
+		Count(&cnt).Error
 
 	if err != nil {
 		logs.Error("db error: %s ", err)
@@ -106,6 +97,10 @@ func (e *ServiceType) Delete(c *dto.ServiceTypeDeleteReq) error {
 		Scopes(dto.WithNormalState()).
 		Where("t_service_type_id = ?", serviceType.Id).
 		Count(&ServiceItemCount).Error
+	if err != nil {
+		logs.Error("db error: %s", err)
+		return dto.GetFailedErr
+	}
 
 	if ServiceItemCount > 0 {
 		return errors.New("存在已关联的服务内容,无法删除!")