package cust import ( "bytes" "context" "encoding/json" "fmt" "math" "strconv" "strings" "dashoo.cn/common_definition/comm_def" "dashoo.cn/opms_libary/micro_srv" "dashoo.cn/opms_libary/plugin/dingtalk/workflow" "dashoo.cn/opms_libary/request" "dashoo.cn/opms_libary/utils" "dashoo.cn/opms_libary/myerrors" "dashoo.cn/opms_libary/plugin/dingtalk/message" "github.com/360EntSecGroup-Skylar/excelize" "github.com/gogf/gf/database/gdb" "github.com/gogf/gf/encoding/gjson" "github.com/gogf/gf/frame/g" "github.com/gogf/gf/os/gtime" "github.com/gogf/gf/util/gconv" "github.com/mozillazg/go-pinyin" "dashoo.cn/micro/app/dao/cust" platdao "dashoo.cn/micro/app/dao/plat" model "dashoo.cn/micro/app/model/cust" workflowModel "dashoo.cn/micro/app/model/workflow" "dashoo.cn/micro/app/service" workflowService "dashoo.cn/micro/app/service/workflow" ) type CustomerService struct { *service.ContextService Dao *cust.CustCustomerDao BelongDao *cust.CustCustomerBelongDao DynamicsDao *cust.CustCustomerDynamicsDao ContactDao *cust.CustCustomerContactDao FollowDao *platdao.PlatFollowupDao BelongServer *CustomerbelongService ContanctServer *CustomercontactService } var isPublic, noPublic = "10", "20" // 公海,非公海 var AllocaTion, OperaTion, Receive, Merge = "10", "20", "30", "40" // 10分配20转移30领取40合并 type OpnType struct { OperaTion string } func NewCustomerService(ctx context.Context) (svc *CustomerService, err error) { svc = new(CustomerService) if svc.ContextService, err = svc.Init(ctx); err != nil { return nil, err } svc.Dao = cust.NewCustCustomerDao(svc.Tenant) svc.BelongDao = cust.NewCustCustomerBelongDao(svc.Tenant) svc.DynamicsDao = cust.NewCustCustomerDynamicsDao(svc.Tenant) svc.ContactDao = cust.NewCustCustomerContactDao(svc.Tenant) svc.FollowDao = platdao.NewPlatFollowupDao(svc.Tenant) svc.BelongServer, _ = NewCustomerBelongService(ctx) svc.ContanctServer, _ = NewCustomerContactService(ctx) return svc, nil } // GetList 客户列表列表 func (s *CustomerService) GetList(req *model.CustCustomerSearchReq) (total int, customerList []*model.CustList, err error) { Model := s.Dao.DataScope(s.Ctx, "sales_id") if req.TargetType == "" { if !req.IsPublic { Model = Model.Where(s.Dao.C.SalesId, s.CxtUser.Id).Where(s.Dao.C.IsPublic, noPublic) } else { Model = Model.Where(s.Dao.C.IsPublic, isPublic) } } //客户名称 if req.CustName != "" { Model = Model.Where(s.Dao.C.CustName+" like ?", "%"+req.CustName+"%") } //客户编码 if req.CustCode != "" { Model = Model.Where(s.Dao.C.CustCode+" like ?", "%"+req.CustCode+"%") } //客户行业 if req.CustIndustry != "" { Model = Model.Where(s.Dao.C.CustIndustry+" like ?", "%"+req.CustIndustry+"%") } //客户级别 if req.CustLevel != "" { Model = Model.Where(s.Dao.C.CustLevel, req.CustLevel) } // if req.FollowUpDate != "" { Model = Model.Where(s.Dao.C.FollowUpDate+" like ? ", req.FollowUpDate+"%") } if req.IsRemovePage { Model = Model } else { Model = Model.Page(req.GetPage()) } total, err = Model.Count() if err != nil { g.Log().Error(err) err = myerrors.DbError("获取总行数失败。") return } err = Model.Order("id desc").Scan(&customerList) if err != nil { g.Log().Error(err) return } return } func (s *CustomerService) customerCode(province, industry string) (string, error) { sequence, err := service.Sequence(s.Dao.DB, "customer_code") if err != nil { return "", err } return s.customerProvinceCode(province) + industry + sequence, nil } func (s *CustomerService) customerProvinceCode(province string) string { province = strings.Trim(province, "市") province = strings.Trim(province, "省") province = strings.Trim(province, "特别行政区") province = strings.Trim(province, "自治区") province = strings.Trim(province, "壮族") province = strings.Trim(province, "回族") province = strings.Trim(province, "维吾尔") pinyinArg := pinyin.NewArgs() pinyinArg.Style = pinyin.FIRST_LETTER provincePinyin := pinyin.Pinyin(province, pinyinArg) provinceFirstletter := []string{} for _, i := range provincePinyin { provinceFirstletter = append(provinceFirstletter, i[0]) } provinceCode := strings.Join(provinceFirstletter, "") provinceCode = strings.ToUpper(provinceCode) fmt.Println(provincePinyin, provinceFirstletter, provinceCode) return provinceCode } // Create 创建客户 func (s *CustomerService) Create(req *model.CustomerAddSeq) (insertId int64, err error) { cusTomer := new(model.CustCustomer) count, err := s.Dao.Where(s.Dao.C.CustName, req.CustName).Count() if err != nil { g.Log().Error(err) return } if count > 0 { return 0, myerrors.TipsError("该客户信息已存在,不可重复添加") } if err = gconv.Struct(req, cusTomer); err != nil { return } service.SetCreatedInfo(cusTomer, s.GetCxtUserId(), s.CxtUser.NickName) custCode, err := s.customerCode(req.CustProvince, req.CustIndustryCode) if err != nil { return 0, err } cusTomer.CustCode = custCode cusTomer.CustStatus = "10" roles := s.GetCxtUserRoles() isSales := false for _, v := range roles { if v == "Sales" { // 销售角色 isSales = true break } } // 销售角色 if isSales { cusTomer.IsPublic = noPublic cusTomer.SalesId = s.GetCxtUserId() cusTomer.SalesName = s.CxtUser.NickName insertId, err = s.Dao.InsertAndGetId(cusTomer) if err != nil { g.Log().Error(err) return 0, err } s.CreateBelong(gconv.Int(insertId)) return } else { cusTomer.IsPublic = isPublic insertId, err = s.Dao.InsertAndGetId(cusTomer) if err != nil { g.Log().Error(err) return 0, err } } return insertId, err } // CreateBelong 创建客户归属信息 func (s *CustomerService) CreateBelong(custId int) (err error) { belong := new(model.CustomerBelongAddSeq) belong.CustId = custId belong.SaleName = s.CxtUser.NickName belong.OpnType = AllocaTion belong.OpnPeople = s.CxtUser.NickName err = s.BelongServer.Create(belong) if err != nil { g.Log().Error(err) return } return } // 删除客户 func (s *CustomerService) DeleteByIds(Ids []int64) (err error) { customerCount, err := s.Dao.Where(" id in (?)", Ids).Count() if err != nil { g.Log().Error(err) return } if customerCount == 0 { err = myerrors.TipsError("客户信息不存在") return } //删除客户表 s.Dao.Transaction(context.TODO(), func(ctx context.Context, tx *gdb.TX) error { //客户表 _, err = s.Dao.TX(tx).Where("id in (?)", Ids).Delete() if err != nil { g.Log().Error(err) return err } //客户联系人表 _, err = s.ContactDao.Where("cust_id in (?)", Ids).Delete() if err != nil { g.Log().Error(err) return err } //客户归属表 _, err = s.BelongDao.Where("cust_id in (?)", Ids).Delete() if err != nil { g.Log().Error(err) return err } return nil }) return } // UpdateById 修改客户 func (s *CustomerService) UpdateById(req *model.UpdateCustomer) (err error) { //判断数据是否存在 count, err := s.Dao.Where("id = ", req.Id).Count() if err != nil { g.Log().Error(err) return } if count == 0 { return } //新的客户名字是否存在 num, err := s.Dao.Where(s.Dao.C.CustName, req.CustName).WhereNot(s.Dao.C.Id, req.Id).Count() if err != nil { g.Log().Error(err) return err } if num > 0 { return myerrors.TipsError(fmt.Sprintf("客户名称[%s]已存在", req.CustName)) } CustomertData := new(model.CustomerAddSeq) if err = gconv.Struct(req, CustomertData); err != nil { return } service.SetUpdatedInfo(CustomertData, s.GetCxtUserId(), s.CxtUser.NickName) _, err = s.Dao.FieldsEx(s.Dao.C.CreatedTime, s.Dao.C.CreatedBy, s.Dao.C.CreatedName, s.Dao.C.Id, s.Dao.C.CustCode, s.Dao.C.SalesName, s.Dao.C.SalesId). WherePri(s.Dao.C.Id, req.Id).Update(CustomertData) if err != nil { g.Log().Error(err) return } return } var AssignCustomerRequestProcessCode = "PROC-FE42B2D1-6097-4DE8-8AC5-23541B7D5C8A" // BizCode: 11 var MoveToPubicRequestProcessCode = "PROC-C030BD3D-74A3-4FE5-9EBA-DF3BA9F8AEF9" // BizCode: 12 var TransCustomerRequestProcessCode = "PROC-03BE93D3-9A44-43A1-BA6D-D1BB75702542" // BizCode: 13 // AssignCustomerRequest 领取客户申请 func (s *CustomerService) AssignCustomerRequest(ctx context.Context, req *model.AssignCustomerReq) error { if req.ApplyRemark == "" { return myerrors.TipsError("请输入申请说明") } data, err := s.Dao.Where("id in (?)", req.Ids).LockShared().All() if err != nil { return err } if len(data) == 0 { return myerrors.TipsError("领取用户不能为空") } for _, v := range data { if v.CustStatus != "10" { return myerrors.TipsError(fmt.Sprintf("客户: %s 已被领取", v.CustName)) } if v.CustProvince == "" { return myerrors.TipsError(fmt.Sprintf("请先完善客户: %s 的所在省信息", v.CustName)) } if v.CustCity == "" { return myerrors.TipsError(fmt.Sprintf("请先完善客户: %s 的所在市信息", v.CustName)) } if v.CustIndustry == "" { return myerrors.TipsError(fmt.Sprintf("请先完善客户: %s 的客户类型信息", v.CustName)) } } remark, err := json.Marshal(map[string]string{ "applyUserId": strconv.Itoa(s.GetCxtUserId()), "applyUserName": s.GetCxtUserName(), }) if err != nil { return err } workflowSrv, err := workflowService.NewFlowService(ctx) if err != nil { return err } for _, u := range data { bizCode := strconv.Itoa(u.Id) + ":" + strconv.Itoa(s.GetCxtUserId()) _, err = workflowSrv.StartProcessInstance(bizCode, "11", string(remark), &workflow.StartProcessInstanceRequest{ ProcessCode: &AssignCustomerRequestProcessCode, FormComponentValues: []*workflow.StartProcessInstanceRequestFormComponentValues{ { Id: utils.String("TextField_1QEXO83G7GDC0"), Name: utils.String("客户编码"), Value: utils.String(u.CustCode), }, { Id: utils.String("TextField_13MDZ97RV16K0"), Name: utils.String("客户名称"), Value: utils.String(u.CustName), }, { Id: utils.String("TextField_Q32G87K9Y680"), Name: utils.String("所在省"), Value: utils.String(u.CustProvince), }, { Id: utils.String("TextField_1C81AAVZELY80"), Name: utils.String("所在市"), Value: utils.String(u.CustCity), }, { Id: utils.String("TextField_7EF74WG6AJ40"), Name: utils.String("客户类别"), Value: utils.String(u.CustIndustry), }, { Id: utils.String("TextField_1ZY48VZY6WG00"), Name: utils.String("申请人"), Value: utils.String(s.GetCxtUserName()), }, { Id: utils.String("TextareaField_5U6VKA6N1VK0"), Name: utils.String("申请说明"), Value: utils.String(req.ApplyRemark), }, }, }) if err != nil { return err } _, err = s.Dao.Where("id = ?", u.Id).Data(map[string]interface{}{ "is_public": noPublic, "cust_status": "20", }).Update() if err != nil { return err } } return nil } func (s *CustomerService) AssignCustomerRequestApproval(flow *workflowModel.PlatWorkflow, msg *message.MixMessage) error { remark := map[string]string{} err := json.Unmarshal([]byte(flow.Remark), &remark) if err != nil { return err } userName := remark["applyUserName"] bizCode := strings.Split(flow.BizCode, ":") if len(bizCode) != 2 { return fmt.Errorf("客户领取审批 bizCode 不合法:%s Id: %d", flow.BizCode, flow.Id) } custId, err := strconv.Atoi(bizCode[0]) if err != nil { return fmt.Errorf("客户领取审批 bizCode 不合法:%s Id: %d", flow.BizCode, flow.Id) } userId, err := strconv.Atoi(bizCode[1]) if err != nil { return fmt.Errorf("客户领取审批 bizCode 不合法:%s Id: %d", flow.BizCode, flow.Id) } cust, err := s.Dao.Where("id = ?", custId).One() if err != nil { return err } if cust == nil { return fmt.Errorf("客户不存在:%s Id: %d", flow.BizCode, flow.Id) } if msg.ProcessType != "finish" && msg.ProcessType != "terminate" { return fmt.Errorf("无法识别的 ProcessType :%s", msg.ProcessType) } if msg.Result != "agree" && msg.Result != "refuse" && msg.Result != "" { return fmt.Errorf("无法识别的 Result :%s", msg.Result) } if msg.ProcessType == "terminate" { _, err = s.Dao.Where("id = ?", custId).Data(map[string]interface{}{ "is_public": isPublic, "cust_status": "10", }).Update() return err } pass := msg.Result == "agree" if !pass { _, err = s.Dao.Where("id = ?", custId).Data(map[string]interface{}{ "is_public": isPublic, "cust_status": "10", }).Update() return err } s.CxtUser = &request.UserInfo{Id: userId, UserName: userName} err = s.ChangeCustBelong([]int64{int64(custId)}, int64(userId), remark["applyUserName"]) if err != nil { return err } err = s.BatchCreatebelong([]*model.CustCustomer{cust}, &model.AssignCustomerReq{ Ids: []int64{int64(custId)}, SalesId: int64(userId), SalesName: userName, Remark: "", Receive: Receive, }) if err != nil { return err } s.CxtUser = &request.UserInfo{Id: userId, UserName: userName} return s.CreateDynamics("领取客户", map[string]interface{}{ "userId": userId, "custId": cust.Id, }, int64(cust.Id)) } // 移回公海 func (s *CustomerService) MoveToPublicRequest(ctx context.Context, req *model.MoveToPubicRep) error { if req.Remark == "" { return myerrors.TipsError("请输入移回原因") } data, err := s.Dao.Where("id in (?)", req.Ids).All() if err != nil { return err } if len(data) == 0 { return myerrors.TipsError("移回用户不能为空") } for _, v := range data { if v.CustStatus == "10" { return myerrors.TipsError(fmt.Sprintf("客户: %s 已被移回公海", v.CustName)) } if v.CustStatus == "20" { return myerrors.TipsError(fmt.Sprintf("客户: %s 正在等待审批", v.CustName)) } if v.CustProvince == "" { return myerrors.TipsError(fmt.Sprintf("请先完善客户: %s 的所在省信息", v.CustName)) } if v.CustCity == "" { return myerrors.TipsError(fmt.Sprintf("请先完善客户: %s 的所在市信息", v.CustName)) } if v.CustIndustry == "" { return myerrors.TipsError(fmt.Sprintf("请先完善客户: %s 的客户类型信息", v.CustName)) } } remark, err := json.Marshal(map[string]string{ "applyUserId": strconv.Itoa(s.GetCxtUserId()), "applyUserName": s.GetCxtUserName(), }) if err != nil { return err } workflowSrv, err := workflowService.NewFlowService(ctx) if err != nil { return err } for _, u := range data { bizCode := strconv.Itoa(u.Id) + ":" + strconv.Itoa(s.GetCxtUserId()) _, err = workflowSrv.StartProcessInstance(bizCode, "12", string(remark), &workflow.StartProcessInstanceRequest{ ProcessCode: &MoveToPubicRequestProcessCode, FormComponentValues: []*workflow.StartProcessInstanceRequestFormComponentValues{ { Id: utils.String("TextField_JFWRAP0D1IO0"), Name: utils.String("客户编码"), Value: utils.String(u.CustCode), }, { Id: utils.String("TextField-K2AD4O5B"), Name: utils.String("客户名称"), Value: utils.String(u.CustName), }, { Id: utils.String("TextField_1THUAFLY5RGG0"), Name: utils.String("所在省"), Value: utils.String(u.CustProvince), }, { Id: utils.String("TextField_15SRKAQIYY680"), Name: utils.String("所在市"), Value: utils.String(u.CustCity), }, { Id: utils.String("TextField_S966SSJHCCG0"), Name: utils.String("客户类别"), Value: utils.String(u.CustIndustry), }, { Id: utils.String("TextField_Y3EQ11P49LC0"), Name: utils.String("申请人"), Value: utils.String(s.GetCxtUserName()), }, { Id: utils.String("TextareaField_1790F8J2SPJ40"), Name: utils.String("移回原因"), Value: utils.String(req.Remark), }, }, }) if err != nil { return err } _, err = s.Dao.Where("id = ?", u.Id).Data(map[string]interface{}{ "cust_status": "20", }).Update() if err != nil { return err } } return nil } // 移入公海回调 func (s *CustomerService) MoveToPublicApproval(flow *workflowModel.PlatWorkflow, msg *message.MixMessage) error { remark := map[string]string{} err := json.Unmarshal([]byte(flow.Remark), &remark) if err != nil { return err } userName := remark["applyUserName"] bizCode := strings.Split(flow.BizCode, ":") if len(bizCode) != 2 { return fmt.Errorf("客户移回审批 bizCode 不合法:%s Id: %d", flow.BizCode, flow.Id) } custId, err := strconv.Atoi(bizCode[0]) if err != nil { return fmt.Errorf("客户移回审批 bizCode 不合法:%s Id: %d", flow.BizCode, flow.Id) } userId, err := strconv.Atoi(bizCode[1]) if err != nil { return fmt.Errorf("客户移回审批 bizCode 不合法:%s Id: %d", flow.BizCode, flow.Id) } cust, err := s.Dao.Where("id = ?", custId).One() if err != nil { return err } if cust == nil { return fmt.Errorf("客户不存在:%s Id: %d", flow.BizCode, flow.Id) } if msg.ProcessType != "finish" && msg.ProcessType != "terminate" { return fmt.Errorf("无法识别的 ProcessType :%s", msg.ProcessType) } if msg.Result != "agree" && msg.Result != "refuse" && msg.Result != "" { return fmt.Errorf("无法识别的 Result :%s", msg.Result) } if msg.ProcessType == "terminate" { _, err = s.Dao.Where("id = ?", custId).Data(map[string]interface{}{ "cust_status": "30", }).Update() return err } pass := msg.Result == "agree" if !pass { _, err = s.Dao.Where("id = ?", custId).Data(map[string]interface{}{ "cust_status": "30", }).Update() return err } now := gtime.Now() err = s.Dao.Transaction(context.TODO(), func(ctx context.Context, tx *gdb.TX) error { //更新客户信息 _, err = s.Dao.TX(tx).Data(g.Map{ "cust_status": "10", "is_public": isPublic, "sales_id": 0, "dept_id": 0, "dept_name": "", "updated_time": now, }).Where("id = ?", cust.Id).Update() if err != nil { return err } //更新销售归属表结束时间 _, err = s.BelongDao.TX(tx).Data(g.Map{ "end_date": now, }).Where("cust_id = ?", cust.Id).Update() if err != nil { return err } return nil }) if err != nil { return err } s.CxtUser = &request.UserInfo{Id: userId, UserName: userName} return s.CreateDynamics("移入公海", map[string]interface{}{ "userId": userId, "custId": cust.Id, }, int64(cust.Id)) } // 转移客户 func (s *CustomerService) TransCustomerRequest(ctx context.Context, req *model.AssignCustomerReq) error { if req.Remark == "" { return myerrors.TipsError("请输入转移原因") } data, err := s.Dao.Where("id in (?)", req.Ids).All() if err != nil { return err } if len(data) == 0 { return myerrors.TipsError("转移用户不能为空") } for _, v := range data { if v.CustStatus == "10" { return myerrors.TipsError(fmt.Sprintf("客户: %s 为公海客户", v.CustName)) } if v.CustStatus == "20" { return myerrors.TipsError(fmt.Sprintf("客户: %s 正在等待审批", v.CustName)) } if v.CustProvince == "" { return myerrors.TipsError(fmt.Sprintf("请先完善客户: %s 的所在省信息", v.CustName)) } if v.CustCity == "" { return myerrors.TipsError(fmt.Sprintf("请先完善客户: %s 的所在市信息", v.CustName)) } if v.CustIndustry == "" { return myerrors.TipsError(fmt.Sprintf("请先完善客户: %s 的客户类型信息", v.CustName)) } } remark, err := json.Marshal(map[string]string{ "applyUserId": strconv.Itoa(s.GetCxtUserId()), "applyUserName": s.GetCxtUserName(), "toUserId": strconv.FormatInt(req.SalesId, 10), "toUserName": req.SalesName, }) if err != nil { return err } workflowSrv, err := workflowService.NewFlowService(ctx) if err != nil { return err } for _, u := range data { bizCode := strings.Join([]string{ strconv.Itoa(u.Id), strconv.Itoa(s.GetCxtUserId()), strconv.FormatInt(req.SalesId, 10), }, ":") _, err = workflowSrv.StartProcessInstance(bizCode, "13", string(remark), &workflow.StartProcessInstanceRequest{ ProcessCode: &TransCustomerRequestProcessCode, FormComponentValues: []*workflow.StartProcessInstanceRequestFormComponentValues{ { Id: utils.String("TextField-K2AD4O5B"), Name: utils.String("客户编码"), Value: utils.String(u.CustCode), }, { Id: utils.String("TextField_HMF1CTLP55S0"), Name: utils.String("客户名称"), Value: utils.String(u.CustName), }, { Id: utils.String("TextField_SAITVT7MNF40"), Name: utils.String("所在省"), Value: utils.String(u.CustProvince), }, { Id: utils.String("TextField_12DGEUTR74NK0"), Name: utils.String("所在市"), Value: utils.String(u.CustCity), }, { Id: utils.String("TextField_16FDRGG3URCW0"), Name: utils.String("客户类别"), Value: utils.String(u.CustIndustry), }, { Id: utils.String("TextField_1JSO6EU9XQCG0"), Name: utils.String("申请人"), Value: utils.String(s.GetCxtUserName()), }, { Id: utils.String("TextareaField_1ZSSTZFCT0G00"), Name: utils.String("转移原因"), Value: utils.String(req.Remark), }, }, }) if err != nil { return err } _, err = s.Dao.Where("id = ?", u.Id).Data(map[string]interface{}{ "cust_status": "20", }).Update() if err != nil { return err } } return nil } // 转移客户回调 func (s *CustomerService) TransCustomerApproval(flow *workflowModel.PlatWorkflow, msg *message.MixMessage) error { remark := map[string]string{} err := json.Unmarshal([]byte(flow.Remark), &remark) if err != nil { return err } userName := remark["applyUserName"] toUserName := remark["toUserName"] bizCode := strings.Split(flow.BizCode, ":") if len(bizCode) != 3 { return fmt.Errorf("转移客户审批 bizCode 不合法:%s Id: %d", flow.BizCode, flow.Id) } custId, err := strconv.Atoi(bizCode[0]) if err != nil { return fmt.Errorf("转移客户审批 bizCode 不合法:%s Id: %d", flow.BizCode, flow.Id) } userId, err := strconv.Atoi(bizCode[1]) if err != nil { return fmt.Errorf("转移客户审批 bizCode 不合法:%s Id: %d", flow.BizCode, flow.Id) } toUserId, err := strconv.Atoi(bizCode[2]) if err != nil { return fmt.Errorf("转移客户审批 bizCode 不合法:%s Id: %d", flow.BizCode, flow.Id) } // user, err := s.UserDao.Where("id = ?", userId).One() // if err != nil { // return err // } // if user == nil { // return fmt.Errorf("用户不存在:%s Id: %d", flow.BizCode, flow.Id) // } // toUser, err := s.UserDao.Where("id = ?", toUserId).One() // if err != nil { // return err // } // if toUser == nil { // return fmt.Errorf("用户不存在:%s Id: %d", flow.BizCode, flow.Id) // } cust, err := s.Dao.Where("id = ?", custId).One() if err != nil { return err } if cust == nil { return fmt.Errorf("客户不存在:%s Id: %d", flow.BizCode, flow.Id) } if msg.ProcessType != "finish" && msg.ProcessType != "terminate" { return fmt.Errorf("无法识别的 ProcessType :%s", msg.ProcessType) } if msg.Result != "agree" && msg.Result != "refuse" && msg.Result != "" { return fmt.Errorf("无法识别的 Result :%s", msg.Result) } if msg.ProcessType == "terminate" { _, err = s.Dao.Where("id = ?", custId).Data(map[string]interface{}{ "cust_status": "30", }).Update() return err } pass := msg.Result == "agree" if !pass { _, err = s.Dao.Where("id = ?", custId).Data(map[string]interface{}{ "cust_status": "30", }).Update() return err } s.CxtUser = &request.UserInfo{Id: userId, UserName: userName} err = s.ChangeCustBelong([]int64{int64(custId)}, int64(toUserId), toUserName) if err != nil { return err } err = s.BatchCreatebelong([]*model.CustCustomer{cust}, &model.AssignCustomerReq{ Ids: []int64{int64(custId)}, SalesId: int64(toUserId), SalesName: toUserName, Remark: "", Receive: OperaTion, }) if err != nil { return err } s.CxtUser = &request.UserInfo{Id: userId, UserName: userName} return s.CreateDynamics("转移客户", map[string]interface{}{ "userId": userId, "custId": cust.Id, "toUserId": toUserId, }, int64(cust.Id)) } // AssignCustomer 分配客户 func (s *CustomerService) AssignCustomer(ctx context.Context, req *model.AssignCustomerReq) (err error) { if req.Receive != "" { return s.AssignCustomerRequest(ctx, req) } data, err := s.Dao.Where("id in (?)", req.Ids).LockShared().All() if err != nil { g.Log().Error(err) return } if len(data) == 0 { return myerrors.TipsError("无可分配客户") } for _, v := range data { if v.SalesId != 0 { return myerrors.TipsError(fmt.Sprintf("客户名称[%s]已被领取或分配", v.CustName)) } } err = s.ChangeCustBelong(req.Ids, req.SalesId, req.SalesName) if err != nil { return } req.Receive = AllocaTion err = s.BatchCreatebelong(data, req) if err != nil { return err } return s.CreateDynamics("分配客户", req, req.Ids...) } // GetEntityById 客户详情 func (s *CustomerService) GetEntityById(Ids []int64) (entityInfo []*model.CustList, err error) { Model := s.Dao // err = Model.Where(" id in (?)", Ids).Scan(&entityInfo) if err != nil { g.Log().Error(err) return } return } // GetCustNameIsExist 判断客户名称是否存在 func (s *CustomerService) GetCustNameIsExist(req *model.IsExistsCustName) (exist bool, err error) { custDao := s.Dao.M if req.Id > 0 { custDao = custDao.Where("cust_name = ", req.CustName).WhereNot(" id ", req.Id) } else { custDao = custDao.Where("cust_name = ", req.CustName) } count, err := custDao.Count() if err != nil { g.Log().Error(err) return } exist = false if count > 0 { exist = true } return } // CustAbstract 客户摘要 func (s *CustomerService) CustAbstract(Id int64) (followInfo *model.Follow, err error) { count, err := s.FollowDao.Where(s.FollowDao.C.CustId, Id).Count() if err != nil { g.Log().Error(err) return } followInfo = new(model.Follow) followInfo.FollowCount = count followTime, err := s.Dao.Fields(s.Dao.C.FollowUpDate, s.Dao.C.CreatedTime).FindOne(Id) if err != nil { g.Log().Error(err) return } if followTime == nil { err = myerrors.TipsError("获取客户信息不存在") return } now := gtime.Now() var hours float64 if followTime.FollowUpDate == nil { poor := now.Sub(gtime.New(followTime.CreatedTime)) hours = float64(poor.Hours() / 24) } else { poor := now.Sub(gtime.New(followTime.FollowUpDate)) hours = float64(poor.Hours() / 24) } if hours < 0 { followInfo.NotFollowDay = 0 } else { followInfo.NotFollowDay = int(math.Floor(hours)) } return } // // TransCustomer 转移客户 // func (s *CustomerService) TransCustomer(req *model.AssignCustomerReq) (err error) { // data, err := s.Dao.Fields("sales_id,sales_name,id").Where("id in (?)", req.Ids).All() // if err != nil { // g.Log().Error(err) // return err // } // if len(data) == 0 { // return myerrors.TipsError("数据不存在") // } // err = s.ChangeCustBelong(req.Ids, req.SalesId, req.SalesName) // if err != nil { // g.Log().Error(err) // return // } // req.Receive = OperaTion // s.BatchCreatebelong(data, req) // return // } // ChangeCustBelong 变更客户所属关系 func (s *CustomerService) ChangeCustBelong(Ids []int64, salesId int64, salesName string) (err error) { _, err = s.Dao.Data(g.Map{ "cust_status": "30", "sales_id": salesId, "is_public": noPublic, "sales_name": salesName, "updated_by": s.GetCxtUserId(), "updated_name": s.GetCxtUserName(), "updated_time": gtime.Now(), }).Where("id in (?)", Ids).Update() return err } // CreateDynamics 创建客户动态信息 func (s *CustomerService) CreateDynamics(opnTpye string, content interface{}, ids ...int64) (err error) { datas := make([]*model.CustCustomerDynamics, 0) for _, id := range ids { dynameics := new(model.CustCustomerDynamics) dynameics.CustId = int(id) dynameics.OpnPeopleId = s.GetCxtUserId() dynameics.OpnPeople = s.GetCxtUserName() dynameics.OpnDate = gtime.Now() dynameics.OpnType = opnTpye v, _ := gjson.Encode(content) dynameics.OpnContent = gconv.String(v) service.SetCreatedInfo(dynameics, s.GetCxtUserId(), s.GetCxtUserName()) datas = append(datas, dynameics) } _, err = s.DynamicsDao.Insert(datas) if err != nil { g.Log().Error(err) return } return } // GetDynamicsList 客户动态 func (s *CustomerService) GetDynamicsList(req *model.CustomerDynameicsReq) (total int, result []interface{}, err error) { total, err = s.DynamicsDao.Where("cust_id = ", req.CustId).Count() if err != nil { g.Log().Error(err) return } dynamics := []*model.CustomerDynameicsRep{} err = s.DynamicsDao.Where("cust_id = ", req.CustId).Order("created_time desc").Scan(&dynamics) if err != nil { g.Log().Error(err) return } dynamicsList := make(map[string][]*model.CustomerDynameicsRep) for _, v := range dynamics { opnDate := gtime.New(v.OpnDate).Format("Y-m-d") dynamicsList[opnDate] = append(dynamicsList[opnDate], &model.CustomerDynameicsRep{ OpnPeople: v.OpnPeople, OpnDate: v.OpnDate, OpnType: v.OpnType, OpnContent: v.OpnContent, }) } result = append(result, dynamicsList) return } // MergeCustomer 合并客户 func (s *CustomerService) MergeCustomer(req *model.MergeCustomerRep) (err error) { //当前目标客户是否存在并取出合并前的销售 customer, err := s.Dao.Where("id = ", req.Id).One() if err != nil { g.Log().Error(err) return } if customer == nil { return myerrors.TipsError("该客户不存在") } _, err = s.ContactDao.Where(" cust_id in (?)", req.ChooseId).Delete() if err != nil { g.Log().Error(err) return } CustomertData := new(model.CustomerAddSeq) if err = gconv.Struct(req, CustomertData); err != nil { g.Log().Error(err) return } service.SetUpdatedInfo(CustomertData, s.GetCxtUserId(), s.GetCxtUserName()) _, err = s.Dao.FieldsEx(s.Dao.C.CreatedTime, s.Dao.C.CreatedBy, s.Dao.C.CreatedName, s.Dao.C.Id, s.Dao.C.CustCode).WherePri(s.Dao.C.Id, req.Id).Update(CustomertData) if err != nil { g.Log().Error(err) return } //删除被合并的客户信息 _, err = s.Dao.Where(" id in (?)", req.ChooseId).Delete() if err != nil { g.Log().Error(err) return } //删除 所选客户销售联系人 _, err = s.BelongDao.Where(" cust_id in (?)", req.ChooseId).Delete() if err != nil { g.Log().Error(err) return } //插入一条合并成功的归属记录 //更新销售归属表销售结束时间 _, err = s.BelongDao.Data( g.Map{ "updated_by": s.GetCxtUserId(), "updated_name": s.GetCxtUserName(), "end_date": gtime.Now(), }).WhereIn(s.BelongDao.C.CustId, req.Id).Update() if err != nil { g.Log().Error(err) return } req.CustomerBelongAddSeq.CustId = int(req.Id) req.CustomerBelongAddSeq.OpnType = Merge req.CustomerBelongAddSeq.OpnPeople = s.GetCxtUserName() req.CustomerBelongAddSeq.OrigSaleName = customer.SalesName req.CustomerBelongAddSeq.SaleName = req.SalesName s.BelongServer.Create(req.CustomerBelongAddSeq) return } // CreateContact 联系人(合并)预留 func (s *CustomerService) CreateContact(Ids []int64, req *model.CustCustomerContactSeq) (err error) { _, err = s.ContactDao.Where(" cust_id in (?)", Ids).Delete() if err != nil { g.Log().Error(err) return } s.ContanctServer.Create(req) return } // BatchCreatebelong 批量插入客户归属记录表 func (s *CustomerService) BatchCreatebelong(rep []*model.CustCustomer, req *model.AssignCustomerReq, n ...interface{}) (err error) { //更新销售归属表销售结束时间 _, err = s.BelongDao.Data( g.Map{ "updated_by": s.GetCxtUserId(), "updated_name": s.GetCxtUserName(), "end_date": gtime.Now(), }).WhereIn(s.BelongDao.C.CustId, req.Ids).Update() if err != nil { return err } var belongData []*model.CustCustomerBelong userName := s.GetCxtUserName() for _, v := range rep { orig_sale_name := v.SalesName belong := new(model.CustCustomerBelong) belong.CustId = v.Id belong.SaleName = req.SalesName belong.OrigSaleName = orig_sale_name belong.OpnType = req.Receive belong.OpnPeople = userName belong.CreatedName = userName belong.StartDate = gtime.Now() //新增开始时间 belong.OpnDatetime = gtime.Now() belong.Remark = req.Remark belong.CreatedBy = s.GetCxtUserId() belongData = append(belongData, belong) } _, err = s.BelongDao.Insert(belongData) return err } // 导出数据 func (s *CustomerService) Export(req *model.CustCustomerExport) (content *model.CustExport, err error) { var con model.CustExport req.IsRemovePage = true // 去掉分页标识 total, data, err := s.GetList(&req.CustCustomerSearchReq) if err != nil { return } f := excelize.NewFile() index := f.NewSheet("Sheet1") for index, item := range req.Columns { sheetPosition := service.Div(index+1) + "1" f.SetCellValue("Sheet1", sheetPosition, item) } if total > 0 { for ck, item := range data { for index, v := range req.Columns { if v == "客户编码" { f.SetCellValue("Sheet1", service.Div(index+1)+strconv.Itoa(ck+2), item.CustCode) } if v == "客户名称" { f.SetCellValue("Sheet1", service.Div(index+1)+strconv.Itoa(ck+2), item.CustName) } if v == "助记名" { f.SetCellValue("Sheet1", service.Div(index+1)+strconv.Itoa(ck+2), item.AbbrName) } if v == "助记名" { f.SetCellValue("Sheet1", service.Div(index+1)+strconv.Itoa(ck+2), item.AbbrName) } if v == "所在地区" { f.SetCellValue("Sheet1", service.Div(index+1)+strconv.Itoa(ck+2), item.CustLocation) } if v == "客户行业" { f.SetCellValue("Sheet1", service.Div(index+1)+strconv.Itoa(ck+2), item.CustIndustry) } if v == "客户级别" { f.SetCellValue("Sheet1", service.Div(index+1)+strconv.Itoa(ck+2), item.CustLevel) } if v == "客户状态" { var CustStatus string CustStatus = "正常" if item.CustStatus != "10" { CustStatus = "异常" } f.SetCellValue("Sheet1", service.Div(index+1)+strconv.Itoa(ck+2), CustStatus) } if v == "创建人" { f.SetCellValue("Sheet1", service.Div(index+1)+strconv.Itoa(ck+2), item.CreatedName) } if v == "最后跟进时间" { f.SetCellValue("Sheet1", service.Div(index+1)+strconv.Itoa(ck+2), item.FollowUpDate) } if v == "创建时间" { f.SetCellValue("Sheet1", service.Div(index+1)+strconv.Itoa(ck+2), item.CreatedTime) } } } } f.SetActiveSheet(index) var buffer *bytes.Buffer buffer, _ = f.WriteToBuffer() con.Content = buffer.Bytes() return &con, err } func GetUser(ctx context.Context, id int) error { srv := micro_srv.InitMicroSrvClient("User", "micro_srv.auth") defer srv.Close() resp := &comm_def.CommonMsg{} err := srv.Call(ctx, "GetUserInfo", &comm_def.IdReq{ Id: int64(id), }, resp) if err != nil { return fmt.Errorf("获取用户信息 %d %s", id, err.Error()) } fmt.Println(resp.Data) fmt.Println("---------------") fmt.Println(resp.Data.(map[string]interface{})["entity"]) return nil }