Browse Source

Merge branch 'feature/项目管理' into develop

# Conflicts:
#	doc/订单全流程管理平台.pdma.json
ZZH-wl 2 years ago
parent
commit
0676ff4b92

+ 43 - 43
doc/订单全流程管理平台.pdma.json

@@ -2,9 +2,9 @@
   "name": "订单全流程管理平台",
   "describe": "订单全流程管理平台",
   "avatar": "",
-  "version": "4.1.1",
-  "createdTime": "2022-12-6 07:35:33",
-  "updatedTime": "2023-1-9 17:45:35",
+  "version": "4.2.2",
+  "createdTime": "2023-1-6 11:43:05",
+  "updatedTime": "2023-1-9 18:04:10",
   "dbConns": [],
   "profile": {
     "default": {
@@ -4342,6 +4342,23 @@
           "domain": "54611CCC-CA4B-42E1-9F32-4944C85B85A6",
           "id": "D5F6B035-7403-4482-B3A1-63A4D1BA2905"
         },
+        {
+          "defKey": "obtain_time",
+          "defName": "获取时间",
+          "comment": "",
+          "type": "",
+          "len": "",
+          "scale": "",
+          "primaryKey": false,
+          "notNull": false,
+          "autoIncrement": false,
+          "defaultValue": "",
+          "hideInGraph": false,
+          "refDict": "",
+          "extProps": {},
+          "domain": "7CFFA0D3-6A93-4DDC-BC10-DF21211064DC",
+          "id": "30FCF2FC-D42F-43CF-B810-6816468E5596"
+        },
         {
           "defKey": "final_follow_time",
           "defName": "最后跟进时间",
@@ -11653,14 +11670,14 @@
           "id": "812C6609-3FE8-454F-BE38-1829D55490C9"
         },
         {
-          "defKey": "name",
+          "defKey": "prod_name",
           "defName": "产品名称",
           "comment": "",
           "type": "",
           "len": "",
           "scale": "",
           "primaryKey": false,
-          "notNull": false,
+          "notNull": true,
           "autoIncrement": false,
           "defaultValue": "",
           "hideInGraph": false,
@@ -11670,59 +11687,42 @@
           "id": "A8A38DDB-F1EF-4100-B14A-3B159C840D38"
         },
         {
-          "defKey": "category",
-          "defName": "产品类别",
-          "comment": "",
-          "type": "",
-          "len": "",
-          "scale": "",
-          "primaryKey": false,
-          "notNull": false,
-          "autoIncrement": false,
-          "defaultValue": "",
-          "hideInGraph": false,
-          "refDict": "",
-          "extProps": {},
-          "domain": "9092C4E0-1A54-4859-ABBB-5B62DBC27573",
-          "id": "759387D2-9D32-4180-90E9-465E4E59104F"
-        },
-        {
-          "defKey": "unit",
-          "defName": "单位",
+          "defKey": "prod_code",
+          "defName": "产品编码",
           "comment": "",
           "type": "",
           "len": "",
           "scale": "",
           "primaryKey": false,
-          "notNull": false,
+          "notNull": true,
           "autoIncrement": false,
           "defaultValue": "",
           "hideInGraph": false,
           "refDict": "",
           "extProps": {},
-          "domain": "9092C4E0-1A54-4859-ABBB-5B62DBC27573",
-          "id": "4410E2FE-1F3F-42B5-906F-DAD2BC0075F1"
+          "domain": "5E66BDBA-BED9-4D9C-A364-3AE85B30D071",
+          "id": "DEC06D76-4CEB-49DD-B4A9-29690B3141EE"
         },
         {
-          "defKey": "original_price",
-          "defName": "原价",
+          "defKey": "prod_class",
+          "defName": "产品分类",
           "comment": "",
           "type": "",
           "len": "",
           "scale": "",
           "primaryKey": false,
-          "notNull": false,
+          "notNull": true,
           "autoIncrement": false,
           "defaultValue": "",
           "hideInGraph": false,
           "refDict": "",
           "extProps": {},
-          "domain": "C3B1681B-99F9-4818-9E80-DE1652A51D85",
-          "id": "3A8526D9-EBBA-4DA0-A6CD-71B224D17702"
+          "domain": "73FD2BAD-2358-4336-B96D-45DC897BD792",
+          "id": "759387D2-9D32-4180-90E9-465E4E59104F"
         },
         {
-          "defKey": "selling_price",
-          "defName": "售价",
+          "defKey": "prod_unit",
+          "defName": "产品单位",
           "comment": "",
           "type": "",
           "len": "",
@@ -11734,18 +11734,18 @@
           "hideInGraph": false,
           "refDict": "",
           "extProps": {},
-          "domain": "C3B1681B-99F9-4818-9E80-DE1652A51D85",
-          "id": "EA13B6AB-39D6-440F-B7DD-2BFF30F68038"
+          "domain": "9092C4E0-1A54-4859-ABBB-5B62DBC27573",
+          "id": "4410E2FE-1F3F-42B5-906F-DAD2BC0075F1"
         },
         {
-          "defKey": "quantity",
-          "defName": "数量",
+          "defKey": "prod_num",
+          "defName": "产品数量",
           "comment": "",
           "type": "",
           "len": "",
           "scale": "",
           "primaryKey": false,
-          "notNull": false,
+          "notNull": true,
           "autoIncrement": false,
           "defaultValue": "",
           "hideInGraph": false,
@@ -11755,21 +11755,21 @@
           "id": "3645772F-029B-4F2F-9B4B-821C98E34B0A"
         },
         {
-          "defKey": "discount",
-          "defName": "折扣",
+          "defKey": "prod_price",
+          "defName": "产品单价",
           "comment": "",
           "type": "",
           "len": "",
           "scale": "",
           "primaryKey": false,
-          "notNull": false,
+          "notNull": true,
           "autoIncrement": false,
           "defaultValue": "",
           "hideInGraph": false,
           "refDict": "",
           "extProps": {},
           "domain": "C3B1681B-99F9-4818-9E80-DE1652A51D85",
-          "id": "DEC06D76-4CEB-49DD-B4A9-29690B3141EE"
+          "id": "EA13B6AB-39D6-440F-B7DD-2BFF30F68038"
         },
         {
           "defKey": "total_price",

+ 77 - 0
opms_libary/utils/convert.go

@@ -3,6 +3,7 @@ package utils
 import (
 	"container/list"
 	"encoding/json"
+	"github.com/gogf/gf/frame/g"
 	"strings"
 
 	"github.com/gogf/gf/container/gvar"
@@ -201,3 +202,79 @@ func ListToArray(list *list.List) []interface{} {
 	}
 	return arr
 }
+
+// Map key字符串转驼峰
+func MapKeySnakeCamelCase(oldMap g.Map, convType ...string) g.Map {
+	newMap := make(g.Map)
+	for k, v := range oldMap {
+		if len(convType) == 0 {
+			newMap[camelString(k)] = v
+		} else {
+			if convType[0] == "snake" {
+				newMap[camelString(k)] = v
+			} else if convType[0] == "upperCamel" {
+				newMap[camelString(k, "upperCamel")] = v
+			} else {
+				newMap[camelString(k)] = v
+			}
+		}
+	}
+	return newMap
+}
+
+// 驼峰转下划线
+func snakeString(s string) string {
+	if s == "" {
+		return ""
+	}
+	data := make([]byte, 0, len(s)*2)
+	j := false
+	num := len(s)
+	for i := 0; i < num; i++ {
+		d := s[i]
+		// or通过ASCII码进行大小写的转化
+		// 65-90(A-Z),97-122(a-z)
+		//判断如果字母为大写的A-Z就在前面拼接一个_
+		if i > 0 && d >= 'A' && d <= 'Z' && j {
+			data = append(data, '_')
+		}
+		if d != '_' {
+			j = true
+		}
+		data = append(data, d)
+	}
+	//ToLower把大写字母统一转小写
+	return strings.ToLower(string(data[:]))
+}
+
+// 下划线转驼峰
+func camelString(s string, convType ...string) string {
+	if s == "" {
+		return ""
+	}
+	data := make([]byte, 0, len(s))
+	j := false
+	k := false
+	num := len(s) - 1
+	for i := 0; i <= num; i++ {
+		d := s[i]
+		if k == false && d >= 'A' && d <= 'Z' {
+			k = true
+		}
+		if d >= 'a' && d <= 'z' && (j || k == false) {
+			d = d - 32
+			j = false
+			k = true
+		}
+		if k && d == '_' && num > i && s[i+1] >= 'a' && s[i+1] <= 'z' {
+			j = true
+			continue
+		}
+		data = append(data, d)
+	}
+	if len(convType) > 0 {
+		return string(data[:])
+	}
+	data[0] += 32
+	return string(data[:])
+}

+ 4 - 1
opms_parent/app/dao/proj/internal/proj_business.go

@@ -34,7 +34,7 @@ type projBusinessColumns struct {
 	NboPhase         string // 项目阶段(暂不起用)
 	NboSource        string // 项目来源
 	NboBudget        string // 项目预算
-	ApproStatus      string // 审批状态(10待审批20审批中30审批通过40审批退回60审批拒绝)
+	ApproStatus      string // 审批状态(10待提交20审批中30审批通过40审批退回60审批拒绝)
 	ContactId        string // 关联联系人
 	ContactName      string // 联系人姓名
 	ContactPostion   string // 联系人岗位
@@ -48,6 +48,7 @@ type projBusinessColumns struct {
 	SaleName         string // 销售姓名
 	DistributorId    string // 经销商/代理商ID
 	DistributorName  string // 经销商/代理商名称
+	ObtainTime       string // 获取时间
 	FinalFollowTime  string // 最后跟进时间
 	NextFollowTime   string // 下次跟进时间
 	PlanPurchaseTime string // 计划采购时间
@@ -98,6 +99,7 @@ var (
 			SaleName:         "sale_name",
 			DistributorId:    "distributor_id",
 			DistributorName:  "distributor_name",
+			ObtainTime:       "obtain_time",
 			FinalFollowTime:  "final_follow_time",
 			NextFollowTime:   "next_follow_time",
 			PlanPurchaseTime: "plan_purchase_time",
@@ -150,6 +152,7 @@ func NewProjBusinessDao(tenant string) ProjBusinessDao {
 			SaleName:         "sale_name",
 			DistributorId:    "distributor_id",
 			DistributorName:  "distributor_name",
+			ObtainTime:       "obtain_time",
 			FinalFollowTime:  "final_follow_time",
 			NextFollowTime:   "next_follow_time",
 			PlanPurchaseTime: "plan_purchase_time",

+ 54 - 54
opms_parent/app/dao/proj/internal/proj_business_product.go

@@ -26,24 +26,24 @@ type ProjBusinessProductDao struct {
 
 // ProjBusinessProductColumns defines and stores column names for table proj_business_product.
 type projBusinessProductColumns struct {
-	Id            string // 主键
-	BusId         string // 关联项目
-	Name          string // 产品名称
-	Category      string // 产品类别
-	Unit          string // 单位
-	OriginalPrice string // 原价
-	SellingPrice  string // 售价
-	Quantity      string // 数量
-	Discount      string // 折扣
-	TotalPrice    string // 总价
-	Remark        string // 备注
-	CreatedBy     string // 创建者
-	CreatedName   string // 创建人
-	CreatedTime   string // 创建时间
-	UpdatedBy     string // 更新者
-	UpdatedName   string // 更新人
-	UpdatedTime   string // 更新时间
-	DeletedTime   string // 删除时间
+	Id          string // 主键
+	BusId       string // 关联项目
+	ProdId      string // 关联产品
+	ProdName    string // 产品名称
+	ProdCode    string // 产品编码
+	ProdClass   string // 产品分类
+	ProdUnit    string // 产品单位
+	ProdNum     string // 产品数量
+	ProdPrice   string // 产品单价
+	TotalPrice  string // 总价
+	Remark      string // 备注
+	CreatedBy   string // 创建者
+	CreatedName string // 创建人
+	CreatedTime string // 创建时间
+	UpdatedBy   string // 更新者
+	UpdatedName string // 更新人
+	UpdatedTime string // 更新时间
+	DeletedTime string // 删除时间
 }
 
 var (
@@ -53,24 +53,24 @@ var (
 		DB:    g.DB("default"),
 		Table: "proj_business_product",
 		Columns: projBusinessProductColumns{
-			Id:            "id",
-			BusId:         "bus_id",
-			Name:          "name",
-			Category:      "category",
-			Unit:          "unit",
-			OriginalPrice: "original_price",
-			SellingPrice:  "selling_price",
-			Quantity:      "quantity",
-			Discount:      "discount",
-			TotalPrice:    "total_price",
-			Remark:        "remark",
-			CreatedBy:     "created_by",
-			CreatedName:   "created_name",
-			CreatedTime:   "created_time",
-			UpdatedBy:     "updated_by",
-			UpdatedName:   "updated_name",
-			UpdatedTime:   "updated_time",
-			DeletedTime:   "deleted_time",
+			Id:          "id",
+			BusId:       "bus_id",
+			ProdId:      "prod_id",
+			ProdName:    "prod_name",
+			ProdCode:    "prod_code",
+			ProdClass:   "prod_class",
+			ProdUnit:    "prod_unit",
+			ProdNum:     "prod_num",
+			ProdPrice:   "prod_price",
+			TotalPrice:  "total_price",
+			Remark:      "remark",
+			CreatedBy:   "created_by",
+			CreatedName: "created_name",
+			CreatedTime: "created_time",
+			UpdatedBy:   "updated_by",
+			UpdatedName: "updated_name",
+			UpdatedTime: "updated_time",
+			DeletedTime: "deleted_time",
 		},
 	}
 )
@@ -82,24 +82,24 @@ func NewProjBusinessProductDao(tenant string) ProjBusinessProductDao {
 		DB:    g.DB(tenant),
 		Table: "proj_business_product",
 		Columns: projBusinessProductColumns{
-			Id:            "id",
-			BusId:         "bus_id",
-			Name:          "name",
-			Category:      "category",
-			Unit:          "unit",
-			OriginalPrice: "original_price",
-			SellingPrice:  "selling_price",
-			Quantity:      "quantity",
-			Discount:      "discount",
-			TotalPrice:    "total_price",
-			Remark:        "remark",
-			CreatedBy:     "created_by",
-			CreatedName:   "created_name",
-			CreatedTime:   "created_time",
-			UpdatedBy:     "updated_by",
-			UpdatedName:   "updated_name",
-			UpdatedTime:   "updated_time",
-			DeletedTime:   "deleted_time",
+			Id:          "id",
+			BusId:       "bus_id",
+			ProdId:      "prod_id",
+			ProdName:    "prod_name",
+			ProdCode:    "prod_code",
+			ProdClass:   "prod_class",
+			ProdUnit:    "prod_unit",
+			ProdNum:     "prod_num",
+			ProdPrice:   "prod_price",
+			TotalPrice:  "total_price",
+			Remark:      "remark",
+			CreatedBy:   "created_by",
+			CreatedName: "created_name",
+			CreatedTime: "created_time",
+			UpdatedBy:   "updated_by",
+			UpdatedName: "updated_name",
+			UpdatedTime: "updated_time",
+			DeletedTime: "deleted_time",
 		},
 	}
 	return dao

+ 59 - 1
opms_parent/app/handler/proj/business.go

@@ -40,7 +40,7 @@ func (p *BusinessHandler) GetEntityById(ctx context.Context, req *comm_def.IdReq
 	if err != nil {
 		return gerror.New("系统异常,请重新尝试")
 	}
-	_, err = businessService.GetEntityById(req.Id)
+	rsp.Data, err = businessService.GetEntityById(req.Id)
 	_, err, rsp.Code, rsp.Msg = myerrors.CheckError(err)
 	if err != nil {
 		return err
@@ -66,11 +66,51 @@ func (p *BusinessHandler) GetBusinessProduct(ctx context.Context, req *comm_def.
 	return nil
 }
 
+func (p *BusinessHandler) GetBusinessDynamics(ctx context.Context, req *projModel.BusinessReq, rsp *comm_def.CommonMsg) error {
+	if req.BusId == 0 {
+		return gerror.New("参数为空,操作失败")
+	}
+	businessService, err := projSrv.NewBusinessService(ctx)
+	if err != nil {
+		return err
+	}
+	total, list, err := businessService.GetBusinessDynamics(req)
+	_, err, rsp.Code, rsp.Msg = myerrors.CheckError(err)
+	if err != nil {
+		return err
+	}
+	rsp.Data = g.Map{"list": list, "total": total}
+	return nil
+}
+
+func (p *BusinessHandler) GetBusinessDynamicsList(ctx context.Context, req *projModel.BusinessReq, rsp *comm_def.CommonMsg) error {
+	if req.BusId == 0 {
+		return gerror.New("参数为空,操作失败")
+	}
+	businessService, err := projSrv.NewBusinessService(ctx)
+	if err != nil {
+		return err
+	}
+	total, list, err := businessService.GetBusinessDynamicsList(req)
+	_, err, rsp.Code, rsp.Msg = myerrors.CheckError(err)
+	if err != nil {
+		return err
+	}
+	rsp.Data = g.Map{"list": list, "total": total}
+	return nil
+}
+
 func (p *BusinessHandler) Create(ctx context.Context, req *projModel.AddProjBusinessReq, rsp *comm_def.CommonMsg) error {
 	// 参数校验
 	if err := gvalid.CheckStruct(ctx, req, nil); err != nil {
 		return err
 	}
+	// 校验产品数据
+	for _, v := range req.Products {
+		if err := gvalid.CheckStruct(ctx, v, nil); err != nil {
+			return err
+		}
+	}
 	businessService, err := projSrv.NewBusinessService(ctx)
 	if err != nil {
 		return err
@@ -148,3 +188,21 @@ func (p *BusinessHandler) BusinessTransfer(ctx context.Context, req *projModel.B
 	}
 	return nil
 }
+
+// SetPrimacyContact 设置首要联系人
+func (p *BusinessHandler) SetPrimacyContact(ctx context.Context, req *projModel.BusinessPrimacyContactReq, rsp *comm_def.CommonMsg) error {
+	// 参数校验
+	if err := gvalid.CheckStruct(ctx, req, nil); err != nil {
+		return err
+	}
+	businessService, err := projSrv.NewBusinessService(ctx)
+	if err != nil {
+		return gerror.New("系统异常,请重新尝试")
+	}
+	err = businessService.SetPrimacyContact(req)
+	_, err, rsp.Code, rsp.Msg = myerrors.CheckError(err)
+	if err != nil {
+		return err
+	}
+	return nil
+}

+ 1 - 1
opms_parent/app/handler/proj/business_contact.go

@@ -21,7 +21,7 @@ func (p *BusinessContactHandler) GetList(ctx context.Context, req *projModel.Bus
 	if err != nil {
 		return err
 	}
-	list, err := contactService.GetList(req.BusId)
+	list, err := contactService.GetList(req)
 	_, err, rsp.Code, rsp.Msg = myerrors.CheckError(err)
 	if err != nil {
 		return err

+ 0 - 32
opms_parent/app/handler/proj/business_dynamics.go

@@ -1,32 +0,0 @@
-package base
-
-import (
-	"context"
-	"github.com/gogf/gf/errors/gerror"
-
-	"dashoo.cn/common_definition/comm_def"
-	"dashoo.cn/opms_libary/myerrors"
-
-	projModel "dashoo.cn/micro/app/model/proj"
-	projSrv "dashoo.cn/micro/app/service/proj"
-)
-
-type BusinessDynamicsHandler struct{}
-
-// GetList 获取列表
-func (p *BusinessDynamicsHandler) GetList(ctx context.Context, req *projModel.BusinessReq, rsp *comm_def.CommonMsg) error {
-	if req.BusId == 0 {
-		return gerror.New("参数为空,操作失败")
-	}
-	businessService, err := projSrv.NewBusinessDynamicsService(ctx)
-	if err != nil {
-		return err
-	}
-	list, err := businessService.GetList(req.BusId)
-	_, err, rsp.Code, rsp.Msg = myerrors.CheckError(err)
-	if err != nil {
-		return err
-	}
-	rsp.Data = list
-	return nil
-}

+ 2 - 1
opms_parent/app/model/proj/internal/proj_business.go

@@ -18,7 +18,7 @@ type ProjBusiness struct {
 	NboPhase         string      `orm:"nbo_phase"          json:"nboPhase"`         // 项目阶段(暂不起用)
 	NboSource        string      `orm:"nbo_source"         json:"nboSource"`        // 项目来源
 	NboBudget        float64     `orm:"nbo_budget"         json:"nboBudget"`        // 项目预算
-	ApproStatus      string      `orm:"appro_status"       json:"approStatus"`      // 审批状态(10待审批20审批中30审批通过40审批退回60审批拒绝)
+	ApproStatus      string      `orm:"appro_status"       json:"approStatus"`      // 审批状态(10待提交20审批中30审批通过40审批退回60审批拒绝)
 	ContactId        int         `orm:"contact_id"         json:"contactId"`        // 关联联系人
 	ContactName      string      `orm:"contact_name"       json:"contactName"`      // 联系人姓名
 	ContactPostion   string      `orm:"contact_postion"    json:"contactPostion"`   // 联系人岗位
@@ -32,6 +32,7 @@ type ProjBusiness struct {
 	SaleName         string      `orm:"sale_name"          json:"saleName"`         // 销售姓名
 	DistributorId    int         `orm:"distributor_id"     json:"distributorId"`    // 经销商/代理商ID
 	DistributorName  string      `orm:"distributor_name"   json:"distributorName"`  // 经销商/代理商名称
+	ObtainTime       *gtime.Time `orm:"obtain_time"        json:"obtainTime"`       // 获取时间
 	FinalFollowTime  *gtime.Time `orm:"final_follow_time"  json:"finalFollowTime"`  // 最后跟进时间
 	NextFollowTime   *gtime.Time `orm:"next_follow_time"   json:"nextFollowTime"`   // 下次跟进时间
 	PlanPurchaseTime *gtime.Time `orm:"plan_purchase_time" json:"planPurchaseTime"` // 计划采购时间

+ 18 - 18
opms_parent/app/model/proj/internal/proj_business_product.go

@@ -10,22 +10,22 @@ import (
 
 // ProjBusinessProduct is the golang structure for table proj_business_product.
 type ProjBusinessProduct struct {
-	Id            int         `orm:"id,primary"     json:"id"`            // 主键
-	BusId         int         `orm:"bus_id"         json:"busId"`         // 关联项目
-	Name          string      `orm:"name"           json:"name"`          // 产品名称
-	Category      string      `orm:"category"       json:"category"`      // 产品类别
-	Unit          string      `orm:"unit"           json:"unit"`          // 单位
-	OriginalPrice int         `orm:"original_price" json:"originalPrice"` // 原价
-	SellingPrice  int         `orm:"selling_price"  json:"sellingPrice"`  // 售价
-	Quantity      int         `orm:"quantity"       json:"quantity"`      // 数量
-	Discount      int         `orm:"discount"       json:"discount"`      // 折扣
-	TotalPrice    int         `orm:"total_price"    json:"totalPrice"`    // 总价
-	Remark        string      `orm:"remark"         json:"remark"`        // 备注
-	CreatedBy     int         `orm:"created_by"     json:"createdBy"`     // 创建者
-	CreatedName   string      `orm:"created_name"   json:"createdName"`   // 创建人
-	CreatedTime   *gtime.Time `orm:"created_time"   json:"createdTime"`   // 创建时间
-	UpdatedBy     int         `orm:"updated_by"     json:"updatedBy"`     // 更新者
-	UpdatedName   string      `orm:"updated_name"   json:"updatedName"`   // 更新人
-	UpdatedTime   *gtime.Time `orm:"updated_time"   json:"updatedTime"`   // 更新时间
-	DeletedTime   *gtime.Time `orm:"deleted_time"   json:"deletedTime"`   // 删除时间
+	Id          int         `orm:"id,primary"   json:"id"`          // 主键
+	BusId       int         `orm:"bus_id"       json:"busId"`       // 关联项目
+	ProdId      int         `orm:"prod_id"      json:"prodId"`      // 关联产品
+	ProdName    string      `orm:"prod_name"    json:"prodName"`    // 产品名称
+	ProdCode    float64     `orm:"prod_code"    json:"prodCode"`    // 产品编码
+	ProdClass   string      `orm:"prod_class"   json:"prodClass"`   // 产品分类
+	ProdUnit    string      `orm:"prod_unit"    json:"prodUnit"`    // 产品单位
+	ProdNum     int         `orm:"prod_num"     json:"prodNum"`     // 产品数量
+	ProdPrice   float64     `orm:"prod_price"   json:"prodPrice"`   // 产品单价
+	TotalPrice  float64     `orm:"total_price"  json:"totalPrice"`  // 总价
+	Remark      string      `orm:"remark"       json:"remark"`      // 备注
+	CreatedBy   int         `orm:"created_by"   json:"createdBy"`   // 创建者
+	CreatedName string      `orm:"created_name" json:"createdName"` // 创建人
+	CreatedTime *gtime.Time `orm:"created_time" json:"createdTime"` // 创建时间
+	UpdatedBy   int         `orm:"updated_by"   json:"updatedBy"`   // 更新者
+	UpdatedName string      `orm:"updated_name" json:"updatedName"` // 更新人
+	UpdatedTime *gtime.Time `orm:"updated_time" json:"updatedTime"` // 更新时间
+	DeletedTime *gtime.Time `orm:"deleted_time" json:"deletedTime"` // 删除时间
 }

+ 52 - 61
opms_parent/app/model/proj/proj_business.go

@@ -15,44 +15,6 @@ type ProjBusiness internal.ProjBusiness
 
 // Fill with you ideas below.
 
-// 添加数据
-type ProjBusinessReq struct {
-	NboName          string      `json:"nboName"        v:"required#项目名称不能为空"`                        // 项目名称
-	CustId           int         `json:"custId"        v:"required#关联客户不能为空"`                         // 关联客户
-	CustName         string      `json:"custName"        v:"required#关联客户不能为空"`                       // 客户名称
-	NboType          string      `json:"nboType"        v:"required|in:A,B,C#项目类别不能为空|项目类别只能为A、B、C"`  // 项目类别(A类B类C类)
-	NboPhase         string      `json:"nboPhase"`                                                    // 项目阶段(暂不起用)
-	NboSource        string      `json:"nboSource"        v:"required#关联客户不能为空"`                      // 项目来源
-	NboBudget        float64     `json:"nboBudget"`                                                   // 项目预算
-	ApproStatus      string      `json:"approStatus"        v:"in:10,20,30,40,60#审批状态错误"`             // 审批状态(10待审批20审批中30审批通过40审批退回60审批拒绝)
-	ContactId        int         `json:"contactId"        v:"required#关联联系人不能为空"`                     // 关联联系人
-	ContactName      string      `json:"contactName"        v:"required#关联联系人不能为空"`                   // 联系人姓名
-	ContactPostion   string      `json:"contactPostion"        v:"required#联系人岗位不能为空"`                // 联系人岗位
-	ContactTelephone string      `json:"contactTelephone"        v:"required#联系人岗位不能为空"`              // 联系人电话
-	MakerId          int         `json:"makerId"        v:"required#关联决策人不能为空"`                       // 关联决策人
-	MakerName        string      `json:"makerName"        v:"required#决策人姓名不能为空"`                     // 决策人姓名
-	MakerPost        string      `json:"makerPost"        v:"required#决策人岗位不能为空"`                     // 决策人岗位
-	MakerTelephone   string      `json:"makerTelephone"        v:"required#决策人电话不能为空"`                // 决策人电话
-	SalesModel       string      `json:"salesModel"        v:"required|in:10,20,30#销售模式不能为空|销售模式不存在"` // 销售模式(10直销20经销30代理)
-	SaleId           int         `json:"saleId"        v:"required#归属销售不能为空"`                         // 归属销售
-	SaleName         string      `json:"saleName"        v:"required#归属销售不能为空"`                       // 销售姓名
-	DistributorId    int         `json:"distributorId"`                                               // 经销商/代理商ID
-	DistributorName  string      `json:"distributorName"`                                             // 经销商/代理商名称
-	FinalFollowTime  *gtime.Time `json:"finalFollowTime"`                                             // 最后跟进时间
-	NextFollowTime   *gtime.Time `json:"nextFollowTime"`                                              // 下次跟进时间
-	PlanPurchaseTime *gtime.Time `json:"planPurchaseTime"`                                            // 计划采购时间
-	EstTransTime     *gtime.Time `json:"estTransTime"`                                                // 预计成交时间
-	EstTransPrice    float64     `json:"estTransPrice"`                                               // 预计成交价格
-	RiskProfile      string      `json:"riskProfile"`                                                 // 风险情况
-	Difficulty       string      `json:"difficulty"`                                                  // 困难点
-	Competitor       string      `json:"competitor"`                                                  // 竞争公司
-	Intervention     string      `json:"intervention"`                                                // 介入情况
-	DeptId           int         `json:"deptId"`                                                      // 所属部门ID
-	DeptName         string      `json:"deptName"`                                                    // 所属部门
-	Remark           string      `json:"remark"`                                                      // 备注
-
-}
-
 type ProjBusinessSearchReq struct {
 	NboName  string `json:"nboName"`  // 项目名称
 	CustName string `json:"custName"` // 客户名称
@@ -62,14 +24,29 @@ type ProjBusinessSearchReq struct {
 }
 
 type AddProjBusinessReq struct {
-	NboName        string            `json:"nboName"        v:"required#项目名称不能为空"`  // 项目名称
-	CustId         int               `json:"custId"        v:"required#关联客户不能为空"`   // 关联客户
-	CustName       string            `json:"custName"        v:"required#关联客户不能为空"` // 客户名称
-	EstTransTime   *gtime.Time       `json:"estTransTime"`                          // 预计成交时间
-	EstTransPrice  float64           `json:"estTransPrice"`                         // 预计成交价格
-	NextFollowTime *gtime.Time       `json:"nextFollowTime"`                        // 下次跟进时间
-	Remark         string            `json:"remark"`                                // 备注
-	Products       []BusinessProduct `json:"products"`                              // 产品列表
+	NboName          string      `json:"nboName"        v:"required#项目名称不能为空"`                                   // 项目名称
+	CustId           int         `json:"custId"        v:"required#关联客户不能为空"`                                    // 关联客户
+	CustName         string      `json:"custName"        v:"required#关联客户不能为空"`                                  // 客户名称
+	ObtainTime       *gtime.Time `orm:"obtain_time"        json:"obtainTime"`                                    // 获取时间
+	NboSource        string      `json:"nboSource"        v:"required#项目来源不能为空"`                                 // 项目来源
+	ContactId        int         `json:"contactId"        v:"required#关联联系人不能为空"`                                // 关联联系人
+	ContactName      string      `json:"contactName"        v:"required#联系人姓名不能为空"`                              // 联系人姓名
+	ContactPostion   string      `json:"contactPostion"`                                                         // 联系人岗位
+	ContactTelephone string      `json:"contactTelephone"`                                                       // 联系人电话
+	SaleId           int         `json:"saleId"        v:"required#归属销售不能为空"`                                    // 归属销售
+	SaleName         string      `json:"saleName"        v:"required#销售姓名不能为空"`                                  // 销售姓名
+	SalesModel       string      `json:"salesModel"        v:"required|in:10,20,30#销售模式不能为空|销售模式不存在"`            // 销售模式(10直销20经销30代理)
+	DistributorId    int         `json:"distributorId"        v:"required-unless:salesModel,10#经销商/代理商不能为空"`     // 经销商/代理商ID
+	DistributorName  string      `json:"distributorName"        v:"required-unless:salesModel,10#经销商/代理商名称不能为空"` // 经销商/代理商名称
+	Remark           string      `json:"remark"`                                                                 // 备注
+
+	// 跟进日程
+	FollowTime     *gtime.Time `json:"followTime"       v:"required#跟进时间不能为空"`    // 跟进时间
+	FollowUserId   int         `json:"followUserId"`                              // 关联跟进负责人
+	FollowUserName string      `json:"followUserName"`                            // 跟进负责人姓名
+	FollowContent  string      `json:"followContent"       v:"required#跟进内容不能为空"` // 跟进内容
+
+	Products []BusinessProduct `json:"products"` // 产品列表
 }
 
 type UpdateProjBusinessReq struct {
@@ -77,27 +54,28 @@ type UpdateProjBusinessReq struct {
 	*AddProjBusinessReq
 }
 
-// 项目产品
+// BusinessProduct 项目产品
 type BusinessProduct struct {
-	Id            int    `json:"id"`                                   // 主键
-	Name          string `json:"name"           v:"required#产品名称不能为空"` // 产品名称
-	Category      string `json:"category"       v:"required#产品类别不能为空"` // 产品类别
-	Unit          string `json:"unit"           v:"required#单位不能为空"`   // 单位
-	OriginalPrice int    `json:"originalPrice"  v:"required#原价不能为空"`   // 原价
-	SellingPrice  int    `json:"sellingPrice"   v:"required#售价不能为空"`   // 售价
-	Quantity      int    `json:"quantity"       v:"required#数量不能为空"`   // 数量
-	Discount      int    `json:"discount"       v:"required#折扣不能为空"`   // 折扣
-	TotalPrice    int    `json:"totalPrice"`                           // 总价
-	Remark        string `json:"remark"`                               // 备注
+	Id         int     `json:"id"`                                   // 主键
+	BusId      int     `json:"busId"`                                // 关联项目
+	ProdId     int     `json:"prodId"         v:"required#关联产品不能为空"` // 关联产品
+	ProdName   string  `json:"prodName"       v:"required#产品名称不能为空"` // 产品名称
+	ProdCode   string  `json:"prodCode"       v:"required#产品编码不能为空"` // 产品编码
+	ProdClass  string  `json:"prodClass"      v:"required#产品类别不能为空"` // 产品类别
+	ProdPrice  float64 `json:"prodPrice"      v:"required#产品单价不能为空"` // 产品单价
+	ProdNum    int     `json:"prodNum"        v:"required#产品数量不能为空"` // 产品数量
+	ProdUnit   string  `json:"prodUnit"`                             // 产品单位
+	TotalPrice int     `json:"totalPrice"`                           // 总价
+	Remark     string  `json:"remark"`                               // 备注
 }
 
-// 项目调级请求
+// BusinessGradationReq 项目调级请求
 type BusinessGradationReq struct {
 	Id      int    `json:"id"        v:"required# id不能为空"`                             // 主键
 	NboType string `json:"nboType"        v:"required|in:A,B,C#项目类别不能为空|项目类别只能为A、B、C"` // 项目类别(A类B类C类)
 }
 
-// 项目转移请求
+// BusinessTransferReq 项目转移请求
 type BusinessTransferReq struct {
 	Id       int    `json:"id"        v:"required# id不能为空"`        // 主键
 	UserId   int    `json:"userId"        v:"required# 负责人不能为空"`   // 负责人
@@ -105,7 +83,20 @@ type BusinessTransferReq struct {
 	Remark   string `json:"remark"`                                // 备注
 }
 
-// 获取项目关联信息
+// BusinessPrimacyContactReq 设置首要联系人请求
+type BusinessPrimacyContactReq struct {
+	Id               int    `json:"id"        v:"required# id不能为空"`            // 主键
+	ContactId        int    `json:"contactId"        v:"required#关联联系人不能为空"`   // 关联联系人
+	ContactName      string `json:"contactName"        v:"required#联系人姓名不能为空"` // 联系人姓名
+	ContactPostion   string `json:"contactPostion"`                            // 联系人岗位
+	ContactTelephone string `json:"contactTelephone"`                          // 联系人电话
+	Remark           string `json:"remark"`                                    // 备注
+}
+
+// BusinessReq 获取项目关联信息
 type BusinessReq struct {
-	BusId int64 `json:"busId"        v:"required# 关联项目不能为空"` // 主键
+	BusId    int64  `json:"busId"        v:"required# 关联项目不能为空"` // 主键
+	CuctName string `json:"cuctName"`                            // 客户联系人姓名
+	OpnType  string `json:"opnType"`                             // 操作类型
+	request.PageReq
 }

+ 176 - 56
opms_parent/app/service/proj/business.go

@@ -2,16 +2,17 @@ package proj
 
 import (
 	"context"
+	projDao "dashoo.cn/micro/app/dao/proj"
+	model "dashoo.cn/micro/app/model/proj"
+	"dashoo.cn/micro/app/service"
+	"dashoo.cn/opms_libary/myerrors"
+	"dashoo.cn/opms_libary/utils"
 	"github.com/gogf/gf/database/gdb"
 	"github.com/gogf/gf/errors/gerror"
 	"github.com/gogf/gf/frame/g"
 	"github.com/gogf/gf/os/gtime"
 	"github.com/gogf/gf/util/gconv"
 	"strings"
-
-	projDao "dashoo.cn/micro/app/dao/proj"
-	model "dashoo.cn/micro/app/model/proj"
-	"dashoo.cn/micro/app/service"
 )
 
 type businessService struct {
@@ -64,6 +65,66 @@ func (p *businessService) GetBusinessProduct(id int64) (productList []*model.Pro
 	return
 }
 
+func (p *businessService) GetBusinessDynamics(req *model.BusinessReq) (total int, result g.ListStrAny, err error) {
+	result = make(g.ListStrAny, 0)
+	dynamicsDao := projDao.NewProjBusinessDynamicsDao(p.Tenant).ProjBusinessDynamicsDao.Where(projDao.ProjBusinessDynamics.Columns.BusId, req.BusId)
+	total, err = dynamicsDao.Count()
+	if err != nil {
+		g.Log().Error(err)
+		return
+	}
+	dynamicsList, err := dynamicsDao.Page(req.GetPage()).Order("created_time desc").All()
+	if err != nil || len(dynamicsList) == 0 {
+		g.Log().Error(err)
+		return
+	}
+	// 数据树格式转换
+	opnDateFlag := gtime.New(dynamicsList[0].OpnDate).Format("Y-m-d")
+	for k, v := range dynamicsList {
+		opnDate := gtime.New(v.OpnDate).Format("Y-m-d")
+		if opnDateFlag == opnDate && k != 0 {
+			result[len(result)-1][opnDate] = append(result[len(result)-1][opnDate].(g.ListStrAny), g.Map{
+				"opnPeople":  v.OpnPeople,
+				"opnDate":    v.OpnDate,
+				"opnType":    v.OpnType,
+				"opnContent": gconv.Map(v.OpnContent),
+			})
+		} else {
+			temp := make(g.ListStrAny, 0)
+			temp = append(temp, g.Map{
+				"opnPeople":  v.OpnPeople,
+				"opnDate":    v.OpnDate,
+				"opnType":    v.OpnType,
+				"opnContent": gconv.Map(v.OpnContent),
+			})
+			result = append(result, g.Map{
+				opnDate: temp,
+			})
+		}
+	}
+	return
+}
+
+func (p *businessService) GetBusinessDynamicsList(req *model.BusinessReq) (total int, list []map[string]interface{}, err error) {
+	dynamicsDao := projDao.NewProjBusinessDynamicsDao(p.Tenant).ProjBusinessDynamicsDao.Where(projDao.ProjBusinessDynamics.Columns.BusId, req.BusId)
+	if req.OpnType != "" {
+		dynamicsDao = dynamicsDao.Where(projDao.ProjBusinessDynamics.Columns.OpnType+" = ?", req.OpnType)
+	}
+	total, err = dynamicsDao.Count()
+	if err != nil {
+		g.Log().Error(err)
+		return
+	}
+
+	dynamicsList, err := dynamicsDao.Page(req.GetPage()).Order("created_time desc").All()
+	for _, v := range dynamicsList {
+		val := gconv.Map(v)
+		val["opnContent"] = gconv.Map(v.OpnContent)
+		list = append(list, val)
+	}
+	return
+}
+
 func (p *businessService) Create(req *model.AddProjBusinessReq) (err error) {
 	businessData := new(model.ProjBusiness)
 	if err = gconv.Struct(req, businessData); err != nil {
@@ -73,20 +134,27 @@ func (p *businessService) Create(req *model.AddProjBusinessReq) (err error) {
 	if err = gconv.Structs(req.Products, &products); err != nil {
 		return
 	}
+	var totalPrice float64
+	for _, v := range products {
+		v.TotalPrice = v.ProdPrice * float64(v.ProdNum)
+		totalPrice += v.TotalPrice
+		service.SetCreatedInfo(v, p.GetCxtUserId(), p.GetCxtUserName())
+	}
 
+	businessData.NboType = "C"
+	businessData.ApproStatus = "10"
+	businessData.EstTransPrice = totalPrice
+	businessData.DeptId = p.GetCxtUserDeptId()
 	service.SetCreatedInfo(businessData, p.GetCxtUserId(), p.GetCxtUserName())
 	err = p.Dao.Transaction(context.TODO(), func(ctx context.Context, tx *gdb.TX) error {
 		// 添加项目
-		res, err := p.Dao.TX(tx).Insert(businessData)
+		lastId, err := p.Dao.TX(tx).InsertAndGetId(businessData)
 		if err != nil {
 			return err
 		}
 		// 处理项目产品信息
-		lastId, _ := res.LastInsertId()
 		for _, v := range products {
 			v.BusId = int(lastId)
-			v.TotalPrice = v.SellingPrice * v.Quantity
-			service.SetCreatedInfo(v, p.GetCxtUserId(), p.GetCxtUserName())
 		}
 		// 添加项目产品
 		_, err = projDao.NewProjBusinessProductDao(p.Tenant).TX(tx).Insert(products)
@@ -95,15 +163,11 @@ func (p *businessService) Create(req *model.AddProjBusinessReq) (err error) {
 		}
 		// 添加项目动态
 		dynamics := model.ProjBusinessDynamics{
-			OpnPeopleId: p.GetCxtUserId(),
-			OpnPeople:   p.GetCxtUserName(),
-			OpnDate:     gtime.Now(),
-			OpnType:     "CREATED",
-			OpnContent:  "创建项目",
-			Remark:      gconv.String(businessData),
+			BusId:   int(lastId),
+			OpnType: "10",
+			Remark:  businessData.Remark,
 		}
-		service.SetCreatedInfo(dynamics, p.GetCxtUserId(), p.GetCxtUserName())
-		_, err = projDao.NewProjBusinessDao(p.Tenant).TX(tx).Insert(&dynamics)
+		err = p.CreateProjBusinessDynamics(tx, dynamics, businessData)
 		return err
 	})
 
@@ -130,15 +194,11 @@ func (p *businessService) UpdateById(req *model.UpdateProjBusinessReq) (err erro
 		}
 		// 添加项目动态
 		dynamics := model.ProjBusinessDynamics{
-			OpnPeopleId: p.GetCxtUserId(),
-			OpnPeople:   p.GetCxtUserName(),
-			OpnDate:     gtime.Now(),
-			OpnType:     "UPDATED",
-			OpnContent:  "编辑项目",
-			Remark:      gconv.String(businessData),
+			BusId:   req.Id,
+			OpnType: "20",
+			Remark:  businessData.Remark,
 		}
-		service.SetCreatedInfo(dynamics, p.GetCxtUserId(), p.GetCxtUserName())
-		_, err = projDao.NewProjBusinessDao(p.Tenant).TX(tx).Insert(&dynamics)
+		err = p.CreateProjBusinessDynamics(tx, dynamics, businessData)
 		return err
 	})
 	return
@@ -149,75 +209,135 @@ func (p *businessService) DeleteByIds(ids []int64) (err error) {
 	return
 }
 
-// 项目调级
+// BusinessTransfer 项目转移
+func (p *businessService) BusinessTransfer(req *model.BusinessTransferReq) error {
+	business, err := p.Dao.WherePri(req.Id).One()
+	if err != nil {
+		return err
+	}
+	if business == nil {
+		return myerrors.NewMsgError(nil, "项目不存在")
+	}
+	businessMap := g.Map{
+		p.Dao.Columns.SaleId:   req.UserId,
+		p.Dao.Columns.SaleName: req.UserName,
+		p.Dao.Columns.Remark:   req.Remark,
+	}
+	service.SetUpdatedInfo(businessMap, p.GetCxtUserId(), p.GetCxtUserName())
+
+	opnContent := businessMap
+	opnContent["origSaleId"] = business.SaleId
+	opnContent["origSaleName"] = business.SaleName
+	err = p.Dao.Transaction(context.TODO(), func(ctx context.Context, tx *gdb.TX) error {
+		// 更新项目
+		_, err = p.Dao.TX(tx).WherePri(projDao.ProjBusiness.Columns.Id, req.Id).Data(businessMap).Update()
+		if err != nil {
+			return err
+		}
+		// 添加项目动态
+		dynamics := model.ProjBusinessDynamics{
+			BusId:   req.Id,
+			OpnType: "30",
+			Remark:  req.Remark,
+		}
+		err = p.CreateProjBusinessDynamics(tx, dynamics, opnContent)
+		return err
+	})
+	return err
+}
+
+// BusinessGradation 项目调级
 func (p *businessService) BusinessGradation(req *model.BusinessGradationReq) error {
-	var business model.ProjBusiness
-	err := p.Dao.Where(projDao.ProjBusiness.Columns.Id, req.Id).Scan(&business)
+	business, err := p.Dao.Where(projDao.ProjBusiness.Columns.Id, req.Id).One()
 	if err != nil {
 		return err
 	}
+	if business == nil {
+		return myerrors.NewMsgError(nil, "项目不存在")
+	}
 	if business.NboType == req.NboType {
-		return gerror.New("同级无法进行调级。")
+		return myerrors.NewMsgError(nil, "同级无法进行调级。")
 	}
+	opnType := "40"
 	opnContent := "项目升级 " + business.NboType + " => " + req.NboType
 	// A < B return -1 项目降级
 	if strings.Compare(business.NboType, req.NboType) < 0 {
 		opnContent = "项目降级 " + business.NboType + " => " + req.NboType
+		opnType = "50"
 	}
-	business.NboType = req.NboType
-	service.SetUpdatedInfo(business, p.GetCxtUserId(), p.GetCxtUserName())
 
+	businessMap := g.Map{
+		p.Dao.Columns.NboType: req.NboType,
+	}
+	service.SetUpdatedInfo(businessMap, p.GetCxtUserId(), p.GetCxtUserName())
 	err = p.Dao.Transaction(context.TODO(), func(ctx context.Context, tx *gdb.TX) error {
 		// 更新项目调级
-		_, err = p.Dao.TX(tx).Fields(p.Dao.Columns.NboType).WherePri(projDao.ProjBusiness.Columns.Id, req.Id).Update(business)
+		_, err = p.Dao.TX(tx).WherePri(projDao.ProjBusiness.Columns.Id, req.Id).Data(businessMap).Update()
 		if err != nil {
 			return err
 		}
 		// 添加项目动态
 		dynamics := model.ProjBusinessDynamics{
-			OpnPeopleId: p.GetCxtUserId(),
-			OpnPeople:   p.GetCxtUserName(),
-			OpnDate:     gtime.Now(),
-			OpnType:     "UPDATED",
-			OpnContent:  opnContent,
+			BusId:   business.Id,
+			OpnType: opnType,
 		}
-		service.SetCreatedInfo(dynamics, p.GetCxtUserId(), p.GetCxtUserName())
-		_, err = projDao.NewProjBusinessDao(p.Tenant).TX(tx).Insert(&dynamics)
+		err = p.CreateProjBusinessDynamics(tx, dynamics, opnContent)
 		return err
 	})
 	return err
 }
 
-// 项目转移
-func (p *businessService) BusinessTransfer(req *model.BusinessTransferReq) error {
-	var business model.ProjBusiness
-	err := p.Dao.Where(projDao.ProjBusiness.Columns.Id, req.Id).Scan(&business)
+// SetPrimacyContact 项目设置首要联系人
+func (p *businessService) SetPrimacyContact(req *model.BusinessPrimacyContactReq) (err error) {
+	business, err := p.Dao.Where(projDao.ProjBusiness.Columns.Id, req.Id).One()
 	if err != nil {
 		return err
 	}
-	business.SaleId = req.UserId
-	business.SaleName = req.UserName
-	business.Remark = req.Remark
-	service.SetUpdatedInfo(business, p.GetCxtUserId(), p.GetCxtUserName())
+	if business == nil {
+		return myerrors.NewMsgError(nil, "项目不存在")
+	}
+	businessMap := g.Map{
+		p.Dao.Columns.ContactId:        req.ContactId,
+		p.Dao.Columns.ContactName:      req.ContactName,
+		p.Dao.Columns.ContactPostion:   req.ContactPostion,
+		p.Dao.Columns.ContactTelephone: req.ContactTelephone,
+	}
+	service.SetUpdatedInfo(businessMap, p.GetCxtUserId(), p.GetCxtUserName())
 
+	opnContent := businessMap
+	opnContent["origContactId"] = business.ContactId
+	opnContent["origContactName"] = business.ContactName
+	opnContent["origContactPostion"] = business.ContactPostion
+	opnContent["origContactTelephone"] = business.ContactTelephone
 	err = p.Dao.Transaction(context.TODO(), func(ctx context.Context, tx *gdb.TX) error {
-		// 更新项目调级
-		_, err = p.Dao.TX(tx).Fields(p.Dao.Columns.SaleId, p.Dao.Columns.SaleName).WherePri(projDao.ProjBusiness.Columns.Id, req.Id).Update(business)
+		// 更新项目
+		_, err = p.Dao.TX(tx).WherePri(projDao.ProjBusiness.Columns.Id, req.Id).Data(businessMap).Update()
 		if err != nil {
 			return err
 		}
 		// 添加项目动态
 		dynamics := model.ProjBusinessDynamics{
-			OpnPeopleId: p.GetCxtUserId(),
-			OpnPeople:   p.GetCxtUserName(),
-			OpnDate:     gtime.Now(),
-			OpnType:     "UPDATED",
-			OpnContent:  "项目转移",
-			Remark:      gconv.String(business),
+			BusId:   req.Id,
+			OpnType: "60",
+			Remark:  req.Remark,
 		}
-		service.SetCreatedInfo(dynamics, p.GetCxtUserId(), p.GetCxtUserName())
-		_, err = projDao.NewProjBusinessDao(p.Tenant).TX(tx).Insert(&dynamics)
+		err = p.CreateProjBusinessDynamics(tx, dynamics, opnContent)
 		return err
 	})
 	return err
 }
+
+// CreateProjBusinessDynamics 创建项目动态
+func (p *businessService) CreateProjBusinessDynamics(tx *gdb.TX, dynamics model.ProjBusinessDynamics, opnContent interface{}) error {
+	if v, ok := opnContent.(g.Map); ok {
+		opnContent = utils.MapKeySnakeCamelCase(v)
+	}
+	// 添加项目动态
+	dynamics.OpnPeopleId = p.GetCxtUserId()
+	dynamics.OpnPeople = p.GetCxtUserName()
+	dynamics.OpnDate = gtime.Now()
+	dynamics.OpnContent = gconv.String(opnContent)
+	service.SetCreatedInfo(&dynamics, p.GetCxtUserId(), p.GetCxtUserName())
+	_, err := projDao.NewProjBusinessDynamicsDao(p.Tenant).TX(tx).Insert(&dynamics)
+	return err
+}

+ 7 - 3
opms_parent/app/service/proj/business_contact.go

@@ -22,9 +22,13 @@ func NewBusinessContactService(ctx context.Context) (svc *businessContactService
 	return svc, nil
 }
 
-func (p *businessContactService) GetList(busId int64) (contactList []*projModel.BusinessContact, err error) {
-	err = p.Dao.As("bus").LeftJoin(custDao.CustCustomerContact.Table, "contact", "bus.contact_id=contact.id").
-		Where(p.Dao.Columns.BusId, busId).Fields("bus.id AS id, bus.*, contact.*").Scan(&contactList)
+func (p *businessContactService) GetList(req *projModel.BusinessReq) (contactList []*projModel.BusinessContact, err error) {
+	db := p.Dao.As("bus").LeftJoin(custDao.CustCustomerContact.Table, "contact", "bus.contact_id=contact.id").
+		Where("bus."+p.Dao.Columns.BusId, req.BusId).Fields("bus.id AS id, bus.*, contact.*")
+	if req.CuctName != "" {
+		db = db.Where("contact.cuct_name", req.BusId)
+	}
+	err = db.Scan(&contactList)
 	return
 }
 

+ 0 - 43
opms_parent/app/service/proj/business_dynamics.go

@@ -1,43 +0,0 @@
-package proj
-
-import (
-	"context"
-	projDao "dashoo.cn/micro/app/dao/proj"
-	model "dashoo.cn/micro/app/model/proj"
-	"dashoo.cn/micro/app/service"
-	"github.com/gogf/gf/database/gdb"
-)
-
-type businessDynamicsService struct {
-	*service.ContextService
-	Dao *projDao.ProjBusinessDynamicsDao
-}
-
-func NewBusinessDynamicsService(ctx context.Context) (svc *businessDynamicsService, err error) {
-	svc = new(businessDynamicsService)
-	if svc.ContextService, err = svc.Init(ctx); err != nil {
-		return nil, err
-	}
-	svc.Dao = projDao.NewProjBusinessDynamicsDao(svc.Tenant)
-	return svc, nil
-}
-
-func (p *businessDynamicsService) GetList(busId int64) (businessList []*model.ProjBusinessDynamics, err error) {
-	err = p.Dao.Where(p.Dao.Columns.BusId, busId).Order("id desc").Scan(&businessList)
-	return
-}
-
-func (p *businessDynamicsService) GetEntityById(id int64) (business *model.ProjBusinessDynamics, err error) {
-	err = p.Dao.Where(projDao.ProjBusinessDynamics.Columns.Id, id).Scan(&business)
-	return
-}
-
-func (p *businessDynamicsService) Create(businessData *model.ProjBusinessDynamics, tenant string, tx *gdb.TX) (err error) {
-	_, err = projDao.NewProjBusinessDao(tenant).TX(tx).Insert(businessData)
-	return
-}
-
-func (p *businessDynamicsService) DeleteByIds(ids []int64) (err error) {
-	_, err = p.Dao.WhereIn(projDao.ProjBusinessDynamics.Columns.Id, ids).Delete()
-	return
-}

+ 0 - 1
opms_parent/main.go

@@ -40,7 +40,6 @@ func main() {
 
 	s.RegisterName("Business", new(projHandler.BusinessHandler), "")
 	s.RegisterName("BusinessContact", new(projHandler.BusinessContactHandler), "")
-	s.RegisterName("BusinessDynamics", new(projHandler.BusinessDynamicsHandler), "")
 	s.RegisterName("BusinessFile", new(projHandler.BusinessFileHandler), "")
 	s.RegisterName("BusinessTeam", new(projHandler.BusinessTeamHandler), "")
 	s.RegisterName("CtrContract", new(contract.CtrContract), "")