Преглед изворни кода

Merge branch 'dev_v1.0.40_wh' of BaseService/biService into feature/v1.0.40

王浩 пре 1 недеља
родитељ
комит
fe9572c5a9
5 измењених фајлова са 458 додато и 159 уклоњено
  1. 18 6
      entity/entity.go
  2. 2 3
      rpc/biservice.go
  3. 13 6
      rpc/etc/biservice.yaml
  4. 1 0
      rpc/internal/config/config.go
  5. 424 144
      service/acceptance.go

+ 18 - 6
entity/entity.go

@@ -27,6 +27,7 @@ var (
 	CallTidb         *mysql.Mysql
 	CallTidb         *mysql.Mysql
 	BiService        *mysql.Mysql
 	BiService        *mysql.Mysql
 	WorkOrder        *mysql.Mysql
 	WorkOrder        *mysql.Mysql
+	CrmService       *mysql.Mysql
 	Mgo              *mongodb.MongodbSim
 	Mgo              *mongodb.MongodbSim
 	Bidding          *mongodb.MongodbSim
 	Bidding          *mongodb.MongodbSim
 	MgoQyxy          *mongodb.MongodbSim
 	MgoQyxy          *mongodb.MongodbSim
@@ -76,9 +77,10 @@ type HlyjS struct {
 type Handler struct {
 type Handler struct {
 }
 }
 type ProductMap struct {
 type ProductMap struct {
-	Product     string
-	ProductCode string
-	PersonArr   []Person
+	Product        string
+	ProductCode    string
+	PersonArr      []Person
+	IsAddMarketing bool
 }
 }
 type Person struct {
 type Person struct {
 	Name     string
 	Name     string
@@ -86,8 +88,9 @@ type Person struct {
 	IsResign bool
 	IsResign bool
 }
 }
 type SelectProductMap struct {
 type SelectProductMap struct {
-	Product   []string
-	PersonArr []Person
+	Product        []string
+	PersonArr      []Person
+	IsAddMarketing bool
 }
 }
 
 
 func InitMail(GmailAuthArr []struct {
 func InitMail(GmailAuthArr []struct {
@@ -106,7 +109,7 @@ func InitMail(GmailAuthArr []struct {
 		GmailAuth = append(GmailAuth, mail1)
 		GmailAuth = append(GmailAuth, mail1)
 	}
 	}
 }
 }
-func InitMysql(n, x, y, z, s, m, a, w *mysql.Mysql) {
+func InitMysql(n, x, y, z, s, m, a, w, o *mysql.Mysql) {
 	JyMysql = &mysql.Mysql{
 	JyMysql = &mysql.Mysql{
 		Address:      n.Address,
 		Address:      n.Address,
 		UserName:     n.UserName,
 		UserName:     n.UserName,
@@ -179,6 +182,15 @@ func InitMysql(n, x, y, z, s, m, a, w *mysql.Mysql) {
 		MaxIdleConns: w.MaxIdleConns,
 		MaxIdleConns: w.MaxIdleConns,
 	}
 	}
 	WorkOrder.Init()
 	WorkOrder.Init()
+	CrmService = &mysql.Mysql{
+		Address:      o.Address,
+		UserName:     o.UserName,
+		PassWord:     o.PassWord,
+		DBName:       o.DBName,
+		MaxOpenConns: o.MaxOpenConns,
+		MaxIdleConns: o.MaxIdleConns,
+	}
+	CrmService.Init()
 	logx.Info("初始化mysql")
 	logx.Info("初始化mysql")
 }
 }
 
 

+ 2 - 3
rpc/biservice.go

@@ -23,13 +23,12 @@ var configFile = flag.String("f", "etc/biservice.yaml", "the config file")
 
 
 func main() {
 func main() {
 	flag.Parse()
 	flag.Parse()
-
-	conf.MustLoad(*configFile, &IC.IC)
+	err := conf.Load(*configFile, &IC.IC)
 	ctx := svc.NewServiceContext(IC.IC)
 	ctx := svc.NewServiceContext(IC.IC)
 	srv := server.NewBiServiceServer(ctx)
 	srv := server.NewBiServiceServer(ctx)
 	logx.MustSetup(IC.IC.Logx)
 	logx.MustSetup(IC.IC.Logx)
 	entity.PublicKey = IC.IC.PublicKey
 	entity.PublicKey = IC.IC.PublicKey
-	entity.InitMysql(IC.IC.Mysql.JianYu, IC.IC.Mysql.JyDoc, IC.IC.Mysql.Bi, IC.IC.Mysql.Tidb, IC.IC.Mysql.BiTidb, IC.IC.Mysql.CallTidb, IC.IC.Mysql.BiService, IC.IC.Mysql.WorkOrder)
+	entity.InitMysql(IC.IC.Mysql.JianYu, IC.IC.Mysql.JyDoc, IC.IC.Mysql.Bi, IC.IC.Mysql.Tidb, IC.IC.Mysql.BiTidb, IC.IC.Mysql.CallTidb, IC.IC.Mysql.BiService, IC.IC.Mysql.WorkOrder, IC.IC.Mysql.Crm)
 	entity.InitMail(IC.IC.Mail)
 	entity.InitMail(IC.IC.Mail)
 	entity.InitMongo(IC.IC.Mongo.Qfw.MongodbAddr, IC.IC.Mongo.Qfw.DbName, IC.IC.Mongo.Qfw.Size)
 	entity.InitMongo(IC.IC.Mongo.Qfw.MongodbAddr, IC.IC.Mongo.Qfw.DbName, IC.IC.Mongo.Qfw.Size)
 	entity.InitBiddingMgo(IC.IC.Mongo.Bidding.MongodbAddr, IC.IC.Mongo.Bidding.DbName, IC.IC.Mongo.Bidding.UserName, IC.IC.Mongo.Bidding.Password, IC.IC.Mongo.Bidding.Size)
 	entity.InitBiddingMgo(IC.IC.Mongo.Bidding.MongodbAddr, IC.IC.Mongo.Bidding.DbName, IC.IC.Mongo.Bidding.UserName, IC.IC.Mongo.Bidding.Password, IC.IC.Mongo.Bidding.Size)

+ 13 - 6
rpc/etc/biservice.yaml

@@ -63,6 +63,13 @@ Mysql:
     PassWord: "Topnet123"
     PassWord: "Topnet123"
     MaxOpenConns: 5
     MaxOpenConns: 5
     MaxIdleConns: 5
     MaxIdleConns: 5
+  Crm:
+    DBName: crm
+    Address: 172.20.45.129:4000
+    UserName: root
+    PassWord: "=PDT49#80Z!RVv52_z"
+    MaxOpenConns: 5
+    MaxIdleConns: 5
 Mongo:
 Mongo:
   Qfw:
   Qfw:
     MongodbAddr: 127.0.0.1:27002,172.20.45.130:27080
     MongodbAddr: 127.0.0.1:27002,172.20.45.130:27080
@@ -147,18 +154,15 @@ entId: 25917
 productArr:
 productArr:
   - product: 数据流量包,结构化数据,API接口,广告服务,市场分析报告
   - product: 数据流量包,结构化数据,API接口,广告服务,市场分析报告
     productCode: dk
     productCode: dk
+    isAddMarketing: true
     personArr:
     personArr:
       - name: 孙振杰
       - name: 孙振杰
         phone: '19838689199'
         phone: '19838689199'
         isResign: false
         isResign: false
-      - name: 朱凤超
-        phone: '18539272857'
-        isResign: false
-      - name: 郭静
-        phone: '13203888592'
-        isResign: true
+
   - product: 物业专版
   - product: 物业专版
     productCode: scdk
     productCode: scdk
+    isAddMarketing: true
     personArr:
     personArr:
       - name: 朱凤超
       - name: 朱凤超
         phone: '18539272857'
         phone: '18539272857'
@@ -168,12 +172,14 @@ productArr:
         isResign: false
         isResign: false
   - product: 咨询服务
   - product: 咨询服务
     productCode: zx
     productCode: zx
+    isAddMarketing: false
     personArr:
     personArr:
       - name: 张鹏
       - name: 张鹏
         phone: '13001173386'
         phone: '13001173386'
         isResign: false
         isResign: false
   - product: 渠道合作
   - product: 渠道合作
     productCode: sc
     productCode: sc
+    isAddMarketing: false
     personArr:
     personArr:
       - name: 郑爽
       - name: 郑爽
         phone: '18595618858'
         phone: '18595618858'
@@ -183,6 +189,7 @@ productArr:
         isResign: false
         isResign: false
   - product: 三方服务
   - product: 三方服务
     productCode: sc1
     productCode: sc1
+    isAddMarketing: false
     personArr:
     personArr:
       - name: 郑爽
       - name: 郑爽
         phone: '18595618858'
         phone: '18595618858'

+ 1 - 0
rpc/internal/config/config.go

@@ -27,6 +27,7 @@ type Config struct {
 		CallTidb  *mysql.Mysql
 		CallTidb  *mysql.Mysql
 		BiService *mysql.Mysql
 		BiService *mysql.Mysql
 		WorkOrder *mysql.Mysql
 		WorkOrder *mysql.Mysql
+		Crm       *mysql.Mysql
 	}
 	}
 	Mongo struct {
 	Mongo struct {
 		Qfw struct {
 		Qfw struct {

+ 424 - 144
service/acceptance.go

@@ -8,6 +8,7 @@ import (
 	. "bp.jydev.jianyu360.cn/BaseService/biService/entity"
 	. "bp.jydev.jianyu360.cn/BaseService/biService/entity"
 	"bp.jydev.jianyu360.cn/BaseService/biService/rpc/biservice"
 	"bp.jydev.jianyu360.cn/BaseService/biService/rpc/biservice"
 	"database/sql"
 	"database/sql"
+	"encoding/json"
 	"fmt"
 	"fmt"
 	"github.com/gogf/gf/v2/util/gconv"
 	"github.com/gogf/gf/v2/util/gconv"
 	"github.com/zeromicro/go-zero/core/logx"
 	"github.com/zeromicro/go-zero/core/logx"
@@ -16,14 +17,27 @@ import (
 	"time"
 	"time"
 )
 )
 
 
+// AddAcceptance 处理受理单新增逻辑
+// 参数:
+//
+//	in - 受理单请求数据
+//	productMap - 产品映射关系
+//	entId - 企业ID
+//
+// 返回值:
+//
+//	成功返回受理单编号,失败返回空字符串
 func AddAcceptance(in *biservice.AcceptanceReq, productMap []ProductMap, entId int64) string {
 func AddAcceptance(in *biservice.AcceptanceReq, productMap []ProductMap, entId int64) string {
+	// 清理参数数据中的换行符
 	in.ParamData = strings.ReplaceAll(in.ParamData, "\n", "")
 	in.ParamData = strings.ReplaceAll(in.ParamData, "\n", "")
 	nowTime := time.Now().Format(date.Date_Full_Layout)
 	nowTime := time.Now().Format(date.Date_Full_Layout)
-	//编号处理
+
+	// 线索标识初始化
 	is_clue := 1
 	is_clue := 1
 	deptName := ""
 	deptName := ""
+
+	// 如果有部门ID,查询部门名称
 	if in.DeptId != "" {
 	if in.DeptId != "" {
-		//部门名称查询
 		deptData := JyMysql.FindOne("entniche_department", map[string]interface{}{
 		deptData := JyMysql.FindOne("entniche_department", map[string]interface{}{
 			"id": in.DeptId,
 			"id": in.DeptId,
 		}, "name", "")
 		}, "name", "")
@@ -31,39 +45,49 @@ func AddAcceptance(in *biservice.AcceptanceReq, productMap []ProductMap, entId i
 			deptName = gconv.String((*deptData)["name"])
 			deptName = gconv.String((*deptData)["name"])
 		}
 		}
 	}
 	}
+
+	// 生成受理单编号:SLD+年月日+4位序号
 	acceptance_no := fmt.Sprintf("SLD%s%s", time.Now().Format(date.Date_yyyyMMdd), FindNumber("sld"))
 	acceptance_no := fmt.Sprintf("SLD%s%s", time.Now().Format(date.Date_yyyyMMdd), FindNumber("sld"))
+
+	// 准备受理单主表数据
 	acceptanceMap := map[string]interface{}{
 	acceptanceMap := map[string]interface{}{
-		"acceptance_no":         acceptance_no,
-		"propose_type":          in.ProposeType,
-		"propose_time":          in.ProposeTime,
-		"channel":               in.Channel,
-		"acceptance_type":       in.AcceptanceType,
-		"status":                in.Status,
-		"initiator_name":        in.EntUserName,
-		"initiator_position_id": in.PositionId,
-		"department_no":         in.DeptId,
-		"remark":                in.Remark,
-		"is_delete":             1,
-		"creator_name":          in.EntUserName,
-		"creator_position_id":   in.PositionId,
-		"creator_time":          nowTime,
-		"department_name":       deptName,
+		"acceptance_no":         acceptance_no,     // 受理单编号
+		"propose_type":          in.ProposeType,    // 提出类型
+		"propose_time":          in.ProposeTime,    // 提出时间
+		"channel":               in.Channel,        // 渠道
+		"acceptance_type":       in.AcceptanceType, // 受理类型
+		"status":                in.Status,         // 状态
+		"initiator_name":        in.EntUserName,    // 发起人姓名
+		"initiator_position_id": in.PositionId,     // 发起人职位ID
+		"department_no":         in.DeptId,         // 部门编号
+		"remark":                in.Remark,         // 备注
+		"is_delete":             1,                 // 删除标识
+		"creator_name":          in.EntUserName,    // 创建人姓名
+		"creator_position_id":   in.PositionId,     // 创建人职位ID
+		"creator_time":          nowTime,           // 创建时间
+		"department_name":       deptName,          // 部门名称
 	}
 	}
+
+	// 开启事务处理
 	ok := WorkOrder.ExecTx("受理单处理", func(tx *sql.Tx) bool {
 	ok := WorkOrder.ExecTx("受理单处理", func(tx *sql.Tx) bool {
-		//新增受理单子单
+		// 处理受理单子表数据
 		childMap := gconv.Map(in.ParamData)
 		childMap := gconv.Map(in.ParamData)
 		if childMap != nil && len(childMap) > 0 {
 		if childMap != nil && len(childMap) > 0 {
-			phone := ""
-			company := ""
-			innerArr := []interface{}{}
+			phone := ""                 // 客户联系方式
+			company := ""               // 公司名称
+			innerArr := []interface{}{} // 子表数据数组
 			innerStr := []string{"acceptance_no", "field_name", "field_value", "creator_name", "creator_position_id", "creator_time"}
 			innerStr := []string{"acceptance_no", "field_name", "field_value", "creator_name", "creator_position_id", "creator_time"}
+
+			// 遍历子表字段
 			for k, v := range childMap {
 			for k, v := range childMap {
-				innerArr = append(innerArr, acceptance_no)
-				innerArr = append(innerArr, k)
-				innerArr = append(innerArr, v)
-				innerArr = append(innerArr, in.EntUserName)
-				innerArr = append(innerArr, in.PositionId)
-				innerArr = append(innerArr, nowTime)
+				innerArr = append(innerArr, acceptance_no)  // 受理单编号
+				innerArr = append(innerArr, k)              // 字段名
+				innerArr = append(innerArr, v)              // 字段值
+				innerArr = append(innerArr, in.EntUserName) // 创建人
+				innerArr = append(innerArr, in.PositionId)  // 职位ID
+				innerArr = append(innerArr, nowTime)        // 创建时间
+
+				// 特殊字段处理
 				switch k {
 				switch k {
 				case "公司名称":
 				case "公司名称":
 					company = gconv.String(v)
 					company = gconv.String(v)
@@ -71,139 +95,205 @@ func AddAcceptance(in *biservice.AcceptanceReq, productMap []ProductMap, entId i
 					phone = gconv.String(v)
 					phone = gconv.String(v)
 				}
 				}
 			}
 			}
+
+			// 批量插入子表数据
 			if len(innerArr) > 0 {
 			if len(innerArr) > 0 {
 				ok2, ok3 := WorkOrder.InsertBatchByTx(tx, "order_acceptance_children", innerStr, innerArr)
 				ok2, ok3 := WorkOrder.InsertBatchByTx(tx, "order_acceptance_children", innerStr, innerArr)
 				if ok2 <= 0 && ok3 <= 0 {
 				if ok2 <= 0 && ok3 <= 0 {
 					return false
 					return false
 				}
 				}
 			}
 			}
-			//判断是否创建工单
-			selectedProductMap := map[string]SelectProductMap{}
-			productArr := []string{}
+
+			// 处理产品信息
+			selectedProductMap := map[string]SelectProductMap{} // 选中的产品映射
+			productArr := []string{}                            // 产品数组
+
+			// 如果有咨询产品字段
 			if _, isOk := childMap["咨询产品"]; isOk {
 			if _, isOk := childMap["咨询产品"]; isOk {
+				// 分割产品字符串
 				for _, v := range strings.Split(gconv.String(childMap["咨询产品"]), ",") {
 				for _, v := range strings.Split(gconv.String(childMap["咨询产品"]), ",") {
+					// 匹配产品信息
 					for _, product := range productMap {
 					for _, product := range productMap {
 						if strings.Contains(product.Product, v) {
 						if strings.Contains(product.Product, v) {
 							selectedProduct := selectedProductMap[product.ProductCode]
 							selectedProduct := selectedProductMap[product.ProductCode]
 							selectedProduct.PersonArr = product.PersonArr
 							selectedProduct.PersonArr = product.PersonArr
 							selectedProduct.Product = append(selectedProduct.Product, v)
 							selectedProduct.Product = append(selectedProduct.Product, v)
+							selectedProduct.IsAddMarketing = product.IsAddMarketing
 							productArr = append(productArr, v)
 							productArr = append(productArr, v)
 							selectedProductMap[product.ProductCode] = selectedProduct
 							selectedProductMap[product.ProductCode] = selectedProduct
 							continue
 							continue
 						}
 						}
 					}
 					}
-
 				}
 				}
+				// 检查是否所有产品都匹配成功
 				if len(strings.Split(gconv.String(childMap["咨询产品"]), ",")) != len(productArr) {
 				if len(strings.Split(gconv.String(childMap["咨询产品"]), ",")) != len(productArr) {
-					is_clue = 2
+					is_clue = 2 // 设置为线索
 				}
 				}
 			}
 			}
+
+			// 为每个产品创建工单
 			for k, v := range selectedProductMap {
 			for k, v := range selectedProductMap {
-				if !AddOrderWork(k, acceptance_no, nowTime, phone, company, tx, in, v, entId) {
+				ok, positionId, product, dkPerson := AddOrderWork(k, acceptance_no, nowTime, phone, company, tx, in, v, entId)
+				if !ok {
 					return false
 					return false
+				} else {
+					// 如果需要加入营销
+					if v.IsAddMarketing {
+						go MarketingSave(in, positionId, product, dkPerson)
+					}
 				}
 				}
 			}
 			}
 		}
 		}
-		//先新增受理单主单
+
+		// 设置线索标识并插入受理单主表
 		acceptanceMap["is_clue"] = is_clue
 		acceptanceMap["is_clue"] = is_clue
 		ok1 := WorkOrder.InsertByTx(tx, "order_acceptance", acceptanceMap)
 		ok1 := WorkOrder.InsertByTx(tx, "order_acceptance", acceptanceMap)
 		if ok1 <= 0 {
 		if ok1 <= 0 {
 			logx.Info("受理单创建失败")
 			logx.Info("受理单创建失败")
 			return false
 			return false
 		}
 		}
-		//工单处理
 		return true
 		return true
 	})
 	})
+
 	if ok {
 	if ok {
 		return acceptance_no
 		return acceptance_no
 	}
 	}
 	return ""
 	return ""
-
 }
 }
-func AddOrderWork(orderType, acceptance_no, nowTime, phone, company string, tx *sql.Tx, in *biservice.AcceptanceReq, selectPersonMap SelectProductMap, entId int64) bool {
-	dkPerson := ""
-	dkdeptName := ""
-	dkdeptId := ""
-	dkPositionId := int64(0)
-	personMap := map[string]interface{}{}
-	personMap = FindCandidate(selectPersonMap.PersonArr, entId, orderType)
-	dkPositionId = gconv.Int64(personMap["positionId"])
-	dkPerson = gconv.String(personMap["name"])
-	dkdeptId = gconv.String(personMap["deptId"])
-	dkdeptName = gconv.String(personMap["deptName"])
+
+// AddOrderWork 创建工单
+// 参数:
+//
+//	orderType - 工单类型
+//	acceptance_no - 受理单编号
+//	nowTime - 当前时间
+//	phone - 联系电话
+//	company - 公司名称
+//	tx - 事务对象
+//	in - 受理单请求数据
+//	selectPersonMap - 选择的人员映射
+//	entId - 企业ID
+//
+// 返回值:
+//
+//	bool - 是否成功
+//	int64 - 职位ID
+//	string - 产品信息
+//	string - 处理人员姓名
+func AddOrderWork(orderType, acceptance_no, nowTime, phone,
+	company string, tx *sql.Tx, in *biservice.AcceptanceReq, selectPersonMap SelectProductMap, entId int64) (bool, int64, string, string) {
+	dkPerson := ""           // 大客人员姓名
+	dkdeptName := ""         // 部门名称
+	dkdeptId := int64(0)     // 部门ID
+	dkPositionId := int64(0) // 职位ID
+
+	// 查找候选人
+	personMap := FindCandidate(selectPersonMap.PersonArr, entId, orderType)
+	dkPositionId = personMap.PositionId
+	dkPerson = personMap.Name
+	dkdeptId = personMap.DeptId
+	dkdeptName = personMap.DeptName
+
+	// 如果有有效的职位ID
 	if dkPositionId != 0 {
 	if dkPositionId != 0 {
+		// 生成工单编号:GD+年月日+4位序号
 		work_order_no := fmt.Sprintf("GD%s%s", time.Now().Format(date.Date_yyyyMMdd), FindNumber("gd"))
 		work_order_no := fmt.Sprintf("GD%s%s", time.Now().Format(date.Date_yyyyMMdd), FindNumber("gd"))
+
+		// 准备工单数据
 		orderWorkMap := map[string]interface{}{
 		orderWorkMap := map[string]interface{}{
-			"work_order_no":         work_order_no,
-			"acceptance_no":         acceptance_no,
-			"type":                  strings.Join(selectPersonMap.Product, ","),
-			"status":                1,
-			"initiator_name":        in.EntUserName,
-			"initiator_position_id": in.PositionId,
-			"current_name":          dkPerson,
-			"current_position_id":   dkPositionId,
-			"is_delete":             1,
-			"creator_name":          in.EntUserName,
-			"creator_position_id":   in.PositionId,
-			"creator_time":          nowTime,
-			"two_type":              orderType,
-			"department_no":         dkdeptId,
-			"department_name":       dkdeptName,
-			"update_time":           nil,
+			"work_order_no":         work_order_no,                              // 工单编号
+			"acceptance_no":         acceptance_no,                              // 受理单编号
+			"type":                  strings.Join(selectPersonMap.Product, ","), // 工单类型
+			"status":                1,                                          // 状态
+			"initiator_name":        in.EntUserName,                             // 发起人姓名
+			"initiator_position_id": in.PositionId,                              // 发起人职位ID
+			"current_name":          dkPerson,                                   // 当前处理人
+			"current_position_id":   dkPositionId,                               // 当前处理人职位ID
+			"is_delete":             1,                                          // 删除标识
+			"creator_name":          in.EntUserName,                             // 创建人
+			"creator_position_id":   in.PositionId,                              // 创建人职位ID
+			"creator_time":          nowTime,                                    // 创建时间
+			"two_type":              orderType,                                  // 二级类型
+			"department_no":         dkdeptId,                                   // 部门编号
+			"department_name":       dkdeptName,                                 // 部门名称
+			"update_time":           nil,                                        // 更新时间
 		}
 		}
+
 		logx.Info(orderWorkMap, "11111", selectPersonMap)
 		logx.Info(orderWorkMap, "11111", selectPersonMap)
+
+		// 插入工单数据
 		ok3 := WorkOrder.InsertByTx(tx, "order_work", orderWorkMap)
 		ok3 := WorkOrder.InsertByTx(tx, "order_work", orderWorkMap)
 		if ok3 <= 0 {
 		if ok3 <= 0 {
 			log.Println("工单保存失败")
 			log.Println("工单保存失败")
-			return false
+			return false, 0, "", ""
 		}
 		}
-		//发送邮件
-		//日志添加
+
+		// 准备审批记录数据
 		approvalRecordMap := map[string]interface{}{
 		approvalRecordMap := map[string]interface{}{
-			"work_order_no":       work_order_no,
-			"status":              1,
-			"new_status":          nil,
-			"handle_name":         dkPerson,
-			"handle_position_id":  dkPositionId,
-			"handle_dept_id":      dkdeptId,
-			"handle_dept_name":    dkdeptName,
-			"creator_name":        in.EntUserName,
-			"creator_position_id": in.PositionId,
-			"is_delete":           1,
-			"creator_time":        nowTime,
+			"work_order_no":       work_order_no,  // 工单编号
+			"status":              1,              // 状态
+			"new_status":          nil,            // 新状态
+			"handle_name":         dkPerson,       // 处理人姓名
+			"handle_position_id":  dkPositionId,   // 处理人职位ID
+			"handle_dept_id":      dkdeptId,       // 处理部门ID
+			"handle_dept_name":    dkdeptName,     // 处理部门名称
+			"creator_name":        in.EntUserName, // 创建人
+			"creator_position_id": in.PositionId,  // 创建人职位ID
+			"is_delete":           1,              // 删除标识
+			"creator_time":        nowTime,        // 创建时间
 		}
 		}
+
 		log.Println(approvalRecordMap)
 		log.Println(approvalRecordMap)
+
+		// 插入审批记录
 		ok4 := WorkOrder.InsertByTx(tx, "approval_record", approvalRecordMap)
 		ok4 := WorkOrder.InsertByTx(tx, "approval_record", approvalRecordMap)
 		if ok4 <= 0 {
 		if ok4 <= 0 {
 			log.Println("工单记录保存失败")
 			log.Println("工单记录保存失败")
-			return false
+			return false, 0, "", ""
 		}
 		}
+
 		log.Println(personMap)
 		log.Println(personMap)
 		log.Println(GmailAuth, personMap, strings.Join(selectPersonMap.Product, ","), dkPerson, in.EntUserName, nowTime, work_order_no, phone, company)
 		log.Println(GmailAuth, personMap, strings.Join(selectPersonMap.Product, ","), dkPerson, in.EntUserName, nowTime, work_order_no, phone, company)
+
+		// 发送工作邮件
 		WorkMail(GmailAuth, personMap, strings.Join(selectPersonMap.Product, ","), dkPerson, in.EntUserName, nowTime, work_order_no, phone, company)
 		WorkMail(GmailAuth, personMap, strings.Join(selectPersonMap.Product, ","), dkPerson, in.EntUserName, nowTime, work_order_no, phone, company)
 	}
 	}
-	return true
-
+	return true, dkPositionId, strings.Join(selectPersonMap.Product, ","), dkPerson
 }
 }
 
 
+// PersonJson 人员信息结构体
 type PersonJson struct {
 type PersonJson struct {
-	Name       string
-	Phone      string
-	Mail       string
-	DeptId     int64
-	DeptName   string
-	PositionId int64
-	IsResign   bool
+	Name                    string // 姓名
+	Phone                   string // 电话
+	Mail                    string // 邮箱
+	DeptId                  int64  // 部门ID
+	DeptName                string // 部门名称
+	PositionId              int64  // 职位ID
+	IsResign                bool   // 是否离职
+	EntUserId               int64  // 企业用户ID
+	DeptPersonMail          string // 部门负责人邮箱
+	DeptPersonName          string // 部门负责人姓名
+	SuperiorDepthPersonMail string // 上级部门负责人邮箱
+	SuperiorDepthPersonName string // 上级部门负责人姓名
 }
 }
 
 
-// 大客人员选择
-func FindCandidate(personArr []Person, entId int64, orderType string) map[string]interface{} {
-	person := map[string]interface{}{}
+// FindCandidate 查找候选人
+// 参数:
+//
+//	personArr - 人员数组
+//	entId - 企业ID
+//	orderType - 工单类型
+//
+// 返回值:
+//
+//	PersonJson - 找到的候选人信息
+func FindCandidate(personArr []Person, entId int64, orderType string) PersonJson {
 	personEntity := PersonJson{}
 	personEntity := PersonJson{}
-	personMap := make(map[string]map[string]interface{})
-	phoneArr := make([]string, len(personArr))
-	persons := make([]PersonJson, len(personArr))
-	// Populate phoneArr and personMap
+	personMap := make(map[string]map[string]interface{}) // 人员信息映射
+	phoneArr := make([]string, len(personArr))           // 电话号码数组
+	persons := make([]PersonJson, len(personArr))        // 人员信息数组
+
+	// 初始化人员信息和电话数组
 	for k, v := range personArr {
 	for k, v := range personArr {
 		phone := gconv.String(v.Phone)
 		phone := gconv.String(v.Phone)
 		phoneArr[k] = fmt.Sprintf(`"%s"`, phone)
 		phoneArr[k] = fmt.Sprintf(`"%s"`, phone)
@@ -217,30 +307,33 @@ func FindCandidate(personArr []Person, entId int64, orderType string) map[string
 		}
 		}
 	}
 	}
 
 
-	// Fetch personal email and department information
+	// 查询人员邮箱和部门信息
 	entUserArr := JyMysql.SelectBySql(fmt.Sprintf(`
 	entUserArr := JyMysql.SelectBySql(fmt.Sprintf(`
-		SELECT a.name, a.mail, b.dept_id AS deptId, a.phone, c.name AS deptName
+		SELECT a.name, a.mail, b.dept_id AS deptId, a.phone, c.name AS deptName,a.id as  entUserId
 		FROM entniche_user a
 		FROM entniche_user a
 		INNER JOIN entniche_department_user b ON a.ent_id = %d AND a.phone IN %s AND a.id = b.user_id 
 		INNER JOIN entniche_department_user b ON a.ent_id = %d AND a.phone IN %s AND a.id = b.user_id 
 		INNER JOIN entniche_department c ON b.dept_id = c.id
 		INNER JOIN entniche_department c ON b.dept_id = c.id
 	`, entId, fmt.Sprintf("(%s)", strings.Join(phoneArr, ","))))
 	`, entId, fmt.Sprintf("(%s)", strings.Join(phoneArr, ","))))
 
 
+	// 填充人员邮箱和部门信息
 	if entUserArr != nil {
 	if entUserArr != nil {
 		for _, v := range *entUserArr {
 		for _, v := range *entUserArr {
 			phone := gconv.String(v["phone"])
 			phone := gconv.String(v["phone"])
 			personMap[phone]["mail"] = gconv.String(v["mail"])
 			personMap[phone]["mail"] = gconv.String(v["mail"])
 			personMap[phone]["deptId"] = gconv.String(v["deptId"])
 			personMap[phone]["deptId"] = gconv.String(v["deptId"])
 			personMap[phone]["deptName"] = gconv.String(v["deptName"])
 			personMap[phone]["deptName"] = gconv.String(v["deptName"])
+			personMap[phone]["entUserId"] = gconv.String(v["entUserId"])
 		}
 		}
 	}
 	}
 
 
-	// Fetch position information
+	// 查询职位信息
 	positionArrMap := JyMysql.SelectBySql(fmt.Sprintf(`
 	positionArrMap := JyMysql.SelectBySql(fmt.Sprintf(`
 		SELECT a.phone, b.id
 		SELECT a.phone, b.id
 		FROM base_service.base_user a
 		FROM base_service.base_user a
 		INNER JOIN base_service.base_position b ON b.ent_id = %d AND a.phone IN %s AND b.user_id = a.id AND b.type = 1
 		INNER JOIN base_service.base_position b ON b.ent_id = %d AND a.phone IN %s AND b.user_id = a.id AND b.type = 1
 	`, entId, fmt.Sprintf("(%s)", strings.Join(phoneArr, ","))))
 	`, entId, fmt.Sprintf("(%s)", strings.Join(phoneArr, ","))))
 
 
+	// 填充职位信息
 	if positionArrMap != nil {
 	if positionArrMap != nil {
 		for _, v := range *positionArrMap {
 		for _, v := range *positionArrMap {
 			phone := gconv.String(v["phone"])
 			phone := gconv.String(v["phone"])
@@ -248,7 +341,7 @@ func FindCandidate(personArr []Person, entId int64, orderType string) map[string
 		}
 		}
 	}
 	}
 
 
-	// Update personArr with additional information
+	// 更新人员数组中的完整信息
 	for k, v := range persons {
 	for k, v := range persons {
 		phone := v.Phone
 		phone := v.Phone
 		if info, exists := personMap[phone]; exists {
 		if info, exists := personMap[phone]; exists {
@@ -256,18 +349,21 @@ func FindCandidate(personArr []Person, entId int64, orderType string) map[string
 			persons[k].DeptId = gconv.Int64(info["deptId"])
 			persons[k].DeptId = gconv.Int64(info["deptId"])
 			persons[k].DeptName = gconv.String(info["deptName"])
 			persons[k].DeptName = gconv.String(info["deptName"])
 			persons[k].PositionId = gconv.Int64(info["positionId"])
 			persons[k].PositionId = gconv.Int64(info["positionId"])
+			persons[k].EntUserId = gconv.Int64(info["entUserId"])
 		}
 		}
 	}
 	}
 
 
-	// Query the last person who created an order
+	// 查询最近创建的工单
 	orderWorkMap := WorkOrder.SelectBySql(fmt.Sprintf(`
 	orderWorkMap := WorkOrder.SelectBySql(fmt.Sprintf(`
 		SELECT * FROM order_work WHERE two_type = "%s" ORDER BY creator_time DESC LIMIT 1
 		SELECT * FROM order_work WHERE two_type = "%s" ORDER BY creator_time DESC LIMIT 1
 	`, orderType))
 	`, orderType))
 
 
 	var k int
 	var k int
+	// 如果没有工单记录,从第一个人员开始
 	if orderWorkMap == nil || len(*orderWorkMap) == 0 {
 	if orderWorkMap == nil || len(*orderWorkMap) == 0 {
 		k = findNextPersonIndex(persons, 0)
 		k = findNextPersonIndex(persons, 0)
 	} else {
 	} else {
+		// 否则查找上次处理人,并找下一个
 		currentName := gconv.String((*orderWorkMap)[0]["current_name"])
 		currentName := gconv.String((*orderWorkMap)[0]["current_name"])
 		k = findPersonIndexByName(persons, currentName)
 		k = findPersonIndexByName(persons, currentName)
 		k = findNextPersonIndex(persons, k)
 		k = findNextPersonIndex(persons, k)
@@ -275,115 +371,170 @@ func FindCandidate(personArr []Person, entId int64, orderType string) map[string
 
 
 	personEntity = persons[k]
 	personEntity = persons[k]
 
 
-	// Set person details
-	person["positionId"] = personEntity.PositionId
-	person["deptName"] = personEntity.DeptName
-	person["deptId"] = personEntity.DeptId
-	person["name"] = personEntity.Name
-	person["mail"] = personEntity.Mail
-
-	// Fetch department admin
-	fetchDeptAdmin(person, personEntity.DeptId)
+	// 查询部门管理员信息
+	fetchDeptAdmin(personEntity)
 
 
-	// Fetch superior admin
-	fetchSuperiorAdmin(person, personEntity.DeptId)
+	// 查询上级部门管理员信息
+	fetchSuperiorAdmin(personEntity)
 
 
-	return person
+	return personEntity
 }
 }
 
 
-// Helper function to find the next person index
+// findNextPersonIndex 查找下一个人员索引
+// 参数:
+//
+//	personArr - 人员数组
+//	startIndex - 起始索引
+//
+// 返回值:
+//
+//	下一个未离职人员的索引
 func findNextPersonIndex(personArr []PersonJson, startIndex int) int {
 func findNextPersonIndex(personArr []PersonJson, startIndex int) int {
 	n := len(personArr)
 	n := len(personArr)
-	// 如果当前索引是最后一个,则从 0 开始
+	// 如果当前索引是最后一个,则从0开始
 	if startIndex >= n-1 {
 	if startIndex >= n-1 {
-		startIndex = -1 // 设置为 -1 以便在下次循环中变为 0
+		startIndex = -1 // 设置为-1以便在下次循环中变为0
 	}
 	}
-	for count := 0; count < n; count++ { // 限制最大循环次数
-		startIndex++ // 先加 1
+
+	// 循环查找下一个未离职人员
+	for count := 0; count < n; count++ {
+		startIndex++
 		if startIndex >= n {
 		if startIndex >= n {
-			startIndex = 0 // 如果超出范围,则重置为 0
+			startIndex = 0
 		}
 		}
 		if !personArr[startIndex].IsResign {
 		if !personArr[startIndex].IsResign {
-			return startIndex // 找到未辞职的员工,返回索引
+			return startIndex
 		}
 		}
 	}
 	}
-	return 0 // 如果没有找到,返回 -1
+	return 0
 }
 }
 
 
-// Helper function to find a person's index by name
+// findPersonIndexByName 根据姓名查找人员索引
+// 参数:
+//
+//	personArr - 人员数组
+//	name - 要查找的姓名
+//
+// 返回值:
+//
+//	找到的索引,没找到返回0
 func findPersonIndexByName(personArr []PersonJson, name string) int {
 func findPersonIndexByName(personArr []PersonJson, name string) int {
 	for i, v := range personArr {
 	for i, v := range personArr {
 		if v.Name == name {
 		if v.Name == name {
 			return i
 			return i
 		}
 		}
 	}
 	}
-	return 0 // Default to the first index if not found
+	return 0
 }
 }
 
 
-// Fetch department admin details
-func fetchDeptAdmin(person map[string]interface{}, deptId int64) {
+// fetchDeptAdmin 获取部门管理员信息
+// 参数:
+//
+//	person - 人员信息(会被修改)
+func fetchDeptAdmin(person PersonJson) {
 	deptMap := JyMysql.SelectBySql(`SELECT c.name AS name, c.mail AS mail
 	deptMap := JyMysql.SelectBySql(`SELECT c.name AS name, c.mail AS mail
 		FROM entniche_department_user a
 		FROM entniche_department_user a
 		INNER JOIN entniche_user_role b ON a.dept_id = ? AND a.user_id = b.user_id AND b.role_id != ""
 		INNER JOIN entniche_user_role b ON a.dept_id = ? AND a.user_id = b.user_id AND b.role_id != ""
-		INNER JOIN entniche_user c ON a.user_id = c.id`, deptId)
+		INNER JOIN entniche_user c ON a.user_id = c.id`, person.DeptId)
 
 
 	if deptMap != nil && len(*deptMap) > 0 {
 	if deptMap != nil && len(*deptMap) > 0 {
-		person["deptPersonName"] = gconv.String((*deptMap)[0]["name"])
-		person["deptPersonMail"] = gconv.String((*deptMap)[0]["mail"])
+		person.DeptPersonName = gconv.String((*deptMap)[0]["name"])
+		person.DeptPersonMail = gconv.String((*deptMap)[0]["mail"])
 	}
 	}
 }
 }
 
 
-// Fetch superior admin details
-func fetchSuperiorAdmin(person map[string]interface{}, deptId int64) {
+// fetchSuperiorAdmin 获取上级部门管理员信息
+// 参数:
+//
+//	person - 人员信息(会被修改)
+func fetchSuperiorAdmin(person PersonJson) {
 	superiorMap := JyMysql.SelectBySql(`SELECT c.*
 	superiorMap := JyMysql.SelectBySql(`SELECT c.*
 		FROM entniche_department d
 		FROM entniche_department d
 		INNER JOIN entniche_department_user a ON d.id = ? AND d.pid = a.dept_id
 		INNER JOIN entniche_department_user a ON d.id = ? AND d.pid = a.dept_id
 		INNER JOIN entniche_user_role b ON a.user_id = b.user_id AND b.role_id != ""
 		INNER JOIN entniche_user_role b ON a.user_id = b.user_id AND b.role_id != ""
-		INNER JOIN entniche_user c ON a.user_id = c.id`, deptId)
+		INNER JOIN entniche_user c ON a.user_id = c.id`, person.DeptId)
 
 
 	if superiorMap != nil && len(*superiorMap) > 0 {
 	if superiorMap != nil && len(*superiorMap) > 0 {
-		person["superiorDepthPersonName"] = gconv.String((*superiorMap)[0]["name"])
-		person["superiorDepthPersonMail"] = gconv.String((*superiorMap)[0]["mail"])
+		person.SuperiorDepthPersonName = gconv.String((*superiorMap)[0]["name"])
+		person.SuperiorDepthPersonMail = gconv.String((*superiorMap)[0]["mail"])
 	}
 	}
 }
 }
 
 
-// 编号查询
+// FindNumber 获取编号
+// 参数:
+//
+//	moudle - 模块标识
+//
+// 返回值:
+//
+//	4位序号字符串
 func FindNumber(moudle string) string {
 func FindNumber(moudle string) string {
 	today := time.Now().Format("2006-01-02")
 	today := time.Now().Format("2006-01-02")
 	yesterday := time.Now().AddDate(0, 0, -1).Format("2006-01-02")
 	yesterday := time.Now().AddDate(0, 0, -1).Format("2006-01-02")
 	key := fmt.Sprintf("%s_%s", today, moudle)
 	key := fmt.Sprintf("%s_%s", today, moudle)
 	yesterdayKey := fmt.Sprintf("%s_%s", yesterday, moudle)
 	yesterdayKey := fmt.Sprintf("%s_%s", yesterday, moudle)
+
+	// 删除昨天的缓存
 	if ok, _ := redis.Exists("newother", yesterdayKey); ok {
 	if ok, _ := redis.Exists("newother", yesterdayKey); ok {
-		//删除之前数据
 		redis.Del("newother", yesterdayKey)
 		redis.Del("newother", yesterdayKey)
 	}
 	}
+
+	// 自增获取序号
 	count := redis.Incr("newother", key)
 	count := redis.Incr("newother", key)
 	log.Println("编号获取", moudle, fmt.Sprintf("%04d", count))
 	log.Println("编号获取", moudle, fmt.Sprintf("%04d", count))
 	return fmt.Sprintf("%04d", count)
 	return fmt.Sprintf("%04d", count)
 }
 }
-func WorkMail(gmailAuth []*mail.GmailAuth, personMap map[string]interface{}, productStr string, personName1, personName2, createTimeStr, acceptance_no, phone, company string) {
+
+// WorkMail 发送工作邮件
+// 参数:
+//
+//	gmailAuth - Gmail认证信息
+//	personMap - 人员信息
+//	productStr - 产品字符串
+//	personName1 - 处理人姓名
+//	personName2 - 发起人姓名
+//	createTimeStr - 创建时间字符串
+//	acceptance_no - 受理单编号
+//	phone - 联系电话
+//	company - 公司名称
+func WorkMail(gmailAuth []*mail.GmailAuth, personMap PersonJson, productStr string, personName1, personName2, createTimeStr, acceptance_no, phone, company string) {
 	orderType := fmt.Sprintf(`客户咨询线索(%s)`, productStr)
 	orderType := fmt.Sprintf(`客户咨询线索(%s)`, productStr)
 	title := fmt.Sprintf("%s通知", orderType)
 	title := fmt.Sprintf("%s通知", orderType)
-	if personName1 == gconv.String(personMap["deptPersonName"]) {
-		personMap["deptPersonMail"] = ""
+
+	// 避免重复发送给同一个人
+	if personName1 == personMap.DeptPersonName {
+		personMap.DeptPersonMail = ""
 	}
 	}
-	if personName1 == gconv.String(personMap["superiorDepthPersonName"]) {
-		personMap["superiorDepthPersonMail"] = ""
+	if personName1 == personMap.SuperiorDepthPersonName {
+		personMap.SuperiorDepthPersonMail = ""
 	}
 	}
-	content := fmt.Sprintf(`%s,您好,“%s”于%s新增了1条"%s”(工单编号:%s)%s%s,请及时前往【剑鱼PC工作台-受理-工单管理-我负责的】进行工单处理。`, personName1, personName2, createTimeStr, orderType, acceptance_no, gconv.String(common.If(phone == "", "", fmt.Sprintf(`,客户联系方式为:%s`, phone))), gconv.String(common.If(company == "", "", fmt.Sprintf(`,公司名称:%s`, company))))
-	toMail := gconv.String(personMap["mail"])
+
+	// 构建邮件内容
+	content := fmt.Sprintf(`%s,您好,“%s”于%s新增了1条"%s”(工单编号:%s)%s%s,请及时前往【剑鱼PC工作台-受理-工单管理-我负责的】进行工单处理。`,
+		personName1, personName2, createTimeStr, orderType, acceptance_no,
+		gconv.String(common.If(phone == "", "", fmt.Sprintf(`,客户联系方式为:%s`, phone))),
+		gconv.String(common.If(company == "", "", fmt.Sprintf(`,公司名称:%s`, company))))
+
+	toMail := personMap.Mail
 	mailArr := []string{}
 	mailArr := []string{}
-	if gconv.String(common.If(gconv.String(personMap["deptPersonMail"]) == "", "", gconv.String(personMap["deptPersonMail"]))) != "" {
-		mailArr = append(mailArr, gconv.String(common.If(gconv.String(personMap["deptPersonMail"]) == "", "", gconv.String(personMap["deptPersonMail"]))))
+
+	// 添加抄送人
+	if gconv.String(common.If(personMap.DeptPersonMail == "", "", personMap.DeptPersonMail)) != "" {
+		mailArr = append(mailArr, gconv.String(common.If(personMap.DeptPersonMail == "", "", personMap.DeptPersonMail)))
 	}
 	}
-	if gconv.String(common.If(gconv.String(personMap["superiorDepthPersonMail"]) == "", "", gconv.String(personMap["superiorDepthPersonMail"]))) != "" {
-		mailArr = append(mailArr, gconv.String(common.If(gconv.String(personMap["superiorDepthPersonMail"]) == "", "", gconv.String(personMap["superiorDepthPersonMail"]))))
+	if gconv.String(common.If(personMap.SuperiorDepthPersonMail == "", "", personMap.SuperiorDepthPersonMail)) != "" {
+		mailArr = append(mailArr, gconv.String(common.If(personMap.SuperiorDepthPersonMail == "", "", personMap.SuperiorDepthPersonMail)))
 	}
 	}
+
+	// 设置抄送
 	toCc := strings.Join(mailArr, ",")
 	toCc := strings.Join(mailArr, ",")
 	if len(mailArr) > 0 {
 	if len(mailArr) > 0 {
 		toMail = fmt.Sprintf("%s|%s", toMail, toCc)
 		toMail = fmt.Sprintf("%s|%s", toMail, toCc)
 	}
 	}
+
 	log.Println(toMail, title, content)
 	log.Println(toMail, title, content)
+
+	// 尝试使用多个Gmail账号发送
 	for k, v := range gmailAuth {
 	for k, v := range gmailAuth {
 		fool := mail.GSendMail_q("剑鱼标讯", toMail, "", "", title, content, "", "", v)
 		fool := mail.GSendMail_q("剑鱼标讯", toMail, "", "", title, content, "", "", v)
 		if fool {
 		if fool {
@@ -398,3 +549,132 @@ func WorkMail(gmailAuth []*mail.GmailAuth, personMap map[string]interface{}, pro
 		time.Sleep(time.Second * 3)
 		time.Sleep(time.Second * 3)
 	}
 	}
 }
 }
+
+// MarketingSave 营销线索保存
+// 参数:
+//
+//	in - 受理单请求数据
+//	positionId - 职位ID
+//	product - 产品信息
+//	dkPerson - 大客人员姓名
+func MarketingSave(in *biservice.AcceptanceReq, positionId int64, product, dkPerson string) {
+	// 查询用户系统映射
+	userMapping := JyMysql.FindOne("data_service.user_system", map[string]interface{}{"position_id": positionId, "status": 1}, "", "")
+	if userMapping == nil || len(*userMapping) == 0 {
+		log.Println("大客用户信息获取失败")
+		return
+	}
+
+	log.Println(in)
+	entId := gconv.Int64((*userMapping)["ent_id"])
+	entUserId := gconv.Int64((*userMapping)["ent_user_id"])
+
+	// 开启事务处理营销线索
+	CrmService.ExecTx("线索进营销保存", func(tx *sql.Tx) bool {
+		childMap := gconv.Map(in.ParamData)
+		company := ""      // 公司名称
+		phone := ""        // 联系电话
+		demand := ""       // 客户需求
+		remark := ""       // 备注
+		customerName := "" // 客户姓名
+		channel := ""
+		//渠道查询
+		channelMap := WorkOrder.FindOne("dictionaries", map[string]interface{}{
+			"id": in.Channel,
+		}, "", "")
+		if channelMap == nil || len(*channelMap) == 0 {
+			log.Println(in.Channel, "渠道查询不到")
+		} else {
+			channel = gconv.String((*channelMap)["name"])
+		}
+		// 提取关键字段
+		for k, v := range childMap {
+			switch k {
+			case "公司名称":
+				company = gconv.String(v)
+			case "联系方式num":
+				phone = gconv.String(v)
+			case "客户需求":
+				demand = gconv.String(v)
+			case "备注":
+				remark = gconv.String(v)
+			case "客户姓名":
+				customerName = gconv.String(v)
+			}
+		}
+
+		// 构建备注JSON
+		remarkJson := map[string]interface{}{
+			"提出时间":   time.Now().Format(time.DateTime),
+			"销售线索来源": "主动咨询客服留资客户",
+			"姓名":     common.If(customerName == "", phone, customerName),
+			"联系方式":   phone,
+			"公司名称":   company,
+			"咨询产品":   product,
+			"客户需求":   demand,
+			"备注":     remark,
+		}
+
+		// 保存销售线索
+		clueId := CrmService.InsertByTx(tx, "sale_clue", map[string]interface{}{
+			"position_id":           positionId,                               // 职位ID
+			"ent_id":                entId,                                    // 企业ID
+			"ent_user_id":           entUserId,                                // 企业用户ID
+			"employ_info_id":        0,                                        // 雇佣信息ID
+			"name":                  common.If(company == "", phone, company), // 名称
+			"source_BAK":            "",                                       // 来源备份
+			"summary":               common.If(company == "", phone, company), // 摘要
+			"is_close":              0,                                        // 是否关闭
+			"close_reason_classify": nil,                                      // 关闭原因分类
+			"close_reason_desc":     nil,                                      // 关闭原因描述
+			"create_person":         dkPerson,                                 // 创建人
+			"create_time":           time.Now().Format(date.Date_Full_Layout), // 创建时间
+			"channel":               channel,                                  // 渠道
+			"source":                "主动咨询客服留资客户",                             // 来源
+		})
+
+		// 保存任务
+		filter, _ := json.Marshal(remarkJson)
+		filterStr := gconv.String(filter)
+		filterStr = strings.ReplaceAll(filterStr, "{", "")
+		filterStr = strings.ReplaceAll(filterStr, "}", "")
+		filterStr = strings.ReplaceAll(filterStr, ",", "\n")
+		filterStr = strings.ReplaceAll(filterStr, `"`, `  `)
+		taskId := CrmService.InsertByTx(tx, "task", map[string]interface{}{
+			"ent_id":            entId,                                              // 企业ID
+			"name":              common.If(customerName == "", phone, customerName), // 任务名称
+			"source":            1,                                                  // 来源类型
+			"source_id":         clueId,                                             // 来源ID
+			"create_way":        2,                                                  // 创建方式
+			"status":            2,                                                  // 状态
+			"create_time":       time.Now().Format(date.Date_Full_Layout),           // 创建时间
+			"join_task_vehicle": 0,                                                  // 是否加入任务车辆
+			"remark":            filterStr,                                          // 备注
+		})
+
+		if taskId <= 0 {
+			return false
+		}
+
+		// 保存任务划转记录
+		CrmService.InsertByTx(tx, "task_transfer", map[string]interface{}{
+			"task_id":        taskId,                                   // 任务ID
+			"transfer_id":    positionId,                               // 划转ID
+			"responsible_id": positionId,                               // 负责人ID
+			"is_transfer":    0,                                        // 是否划转
+			"create_time":    time.Now().Format(date.Date_Full_Layout), // 创建时间
+		})
+
+		// 保存任务团队
+		CrmService.InsertByTx(tx, "task_team", map[string]interface{}{
+			"task_id":     taskId,                                   // 任务ID
+			"position_id": positionId,                               // 职位ID
+			"ent_user_id": entUserId,                                // 企业用户ID
+			"name":        dkPerson,                                 // 姓名
+			"role":        1,                                        // 角色
+			"create_time": time.Now().Format(date.Date_Full_Layout), // 创建时间
+		})
+		return true
+	})
+	return
+}