Переглянути джерело

feature:公海客户添加导入功能

sunxinyuan 1 рік тому
батько
коміт
403c70e9d7

+ 1 - 0
opms_admin/app/model/sys_user.go

@@ -61,6 +61,7 @@ type SetUserReq struct {
 	Phone    string `p:"phone" v:"required|phone#手机号不能为空|手机号格式错误"`
 	Sex      string `p:"sex" v:"in:10,20,30#性别只能为10、20、30"`
 	Status   string `p:"status" v:"required|in:10,20#状态不能为空|状态只能为10或20"`
+	WechatId string `p:"wechatId"` // 微信账号
 	Remark   string `p:"remark"`
 	IsAdmin  int    `p:"isAdmin"` // 是否后台管理员 1 是  0   否
 	RoleIds  []int  `p:"roleIds"`

+ 20 - 0
opms_parent/app/handler/cust/customer.go

@@ -2,6 +2,7 @@ package cust
 
 import (
 	"context"
+	"dashoo.cn/micro/app/model/contract"
 
 	"dashoo.cn/common_definition/comm_def"
 	"dashoo.cn/opms_libary/myerrors"
@@ -73,6 +74,25 @@ func (c *CustomerHeader) Create(ctx context.Context, req *model.CustomerAddSeq,
 	return nil
 }
 
+// Swagger:Customer 客户 导入客户并创建联系人
+func (c *CustomerHeader) Import(ctx context.Context, req *contract.ExcelImportReq, rsp *comm_def.CommonMsg) error {
+	if err := gvalid.CheckStruct(ctx, req, nil); err != nil {
+		return err
+	}
+	s, err := server.NewCustomerService(ctx)
+	if err != nil {
+
+		return err
+
+	}
+	err = s.Import(ctx, req)
+	if err != nil {
+
+		return err
+	}
+	return nil
+}
+
 // Swagger:Customer 客户 修改客户
 func (c *CustomerHeader) UpdateById(ctx context.Context, req *model.UpdateCustomer, rsp *comm_def.CommonMsg) error {
 	s, err := server.NewCustomerService(ctx)

+ 30 - 0
opms_parent/app/model/cust/cust_customer.go

@@ -79,6 +79,36 @@ type Information struct {
 	Remark     string `p:"remark"      json:"remark"   `                                     // 备注
 }
 
+type ImportFile struct {
+	Url string `json:"url"`
+}
+
+// CustomerAddSeq 导入客户信息表
+type CustomerAddImport struct {
+	CustName     string `import:"客户名称"  p:"custName"        json:"custName"      v:"required#客户名称不能为空"`    // 客户名称
+	AbbrName     string `import:"助计名"  p:"abbrName"        json:"abbrName"   `                             // 助计名
+	CustAddress  string `import:"详细地址" p:"custAddress"     json:"custAddress"   `                          // 详细地址
+	CustProvince string `import:"所在省" json:"custProvince"`                                                 // 所在省
+	CustCity     string `import:"所在市" json:"custCity"`                                                     // 所在市
+	CustRegion   string `import:"所在区县" json:"custRegion"`                                                  // 所在区县
+	CustIndustry string `import:"客户行业" p:"custIndustry"    json:"custIndustry"  v:"required#客户行业不能为空"`     // 客户行业
+	CustSource   string `import:"客户来源" p:"custSource"      json:"custSource"        v:"required#客户来源不能为空"` // 客户来源
+	Keyword      string `import:"招标关键字" json:"keyword"`                                                    // 招标关键字
+	Remark       string `import:"备注" p:"remark"          json:"remark"`                                    // 备注
+
+	CuctName       string `import:"姓名" p:"cuctName"     json:"cuctName"  v:"required#联系人名字不能为空"`                         // 姓名
+	CuctGender     string `import:"性别" p:"cuctGender"    json:"cuctGender"  v:"required|in:10,20#性别不能为空|填写错误"`           // 性别(10男20女)
+	Telephone      string `import:"电话" p:"telephone"    json:"telephone"  v:"phone#手机号格式错误"`                             // 电话
+	Wechat         string `import:"微信" p:"wechat"    json:"wechat"`                                                      // 微信
+	Email          string `import:"邮箱" p:"email"    json:"email" v:"email#邮箱格式错误"`                                       // 邮箱
+	Dept           string `import:"部门" p:"dept"            json:"dept"`                                                  // 部门
+	Postion        string `import:"职位" p:"postion"    json:"postion"   v:"required#岗位不能为空" `                             // 职位
+	OfficeLocation string `import:"办公地点" p:"officeLocation" json:"officeLocation"`                                       // 办公地点
+	IsDecision     string `import:"是否关键决策人" p:"isDecision"     json:"isDecision" v:"required|in:10,20#是否关键决策人不能为空|填写错误"` // 关键决策人(10是20否)
+	ContactRemark  string `import:"联系人备注" p:"contactRemark"          json:"contactRemark"`                               // 备注
+
+}
+
 //返回信息
 
 type CustList struct {

+ 193 - 0
opms_parent/app/service/cust/cust_customer.go

@@ -3,9 +3,14 @@ package cust
 import (
 	"bytes"
 	"context"
+	"dashoo.cn/micro/app/model/base"
+	"dashoo.cn/micro/app/model/contract"
+	sbase "dashoo.cn/micro/app/service/base"
+	"dashoo.cn/micro/app/service/partner"
 	"encoding/json"
 	"fmt"
 	"github.com/gogf/gf/container/garray"
+	"github.com/gogf/gf/util/gvalid"
 	"math"
 	"strconv"
 	"strings"
@@ -227,6 +232,194 @@ func (s *CustomerService) Create(req *model.CustomerAddSeq) (insertId int64, err
 	return insertId, err
 }
 
+func reverseMap(originalMap map[string]string) map[string]string {
+	reversedMap := make(map[string]string)
+	for key, value := range originalMap {
+		reversedMap[value] = key
+	}
+	return reversedMap
+}
+
+// Create 导入客户
+func (s *CustomerService) Import(ctx context.Context, req *contract.ExcelImportReq) (err error) {
+	validErr := gvalid.CheckStruct(ctx, req, nil)
+	if validErr != nil {
+		return myerrors.TipsError(validErr.Current().Error())
+	}
+
+	// 下载文件
+	buf, err := partner.DownFile(req.ExcelUrl)
+	if err != nil {
+		return myerrors.TipsError(fmt.Sprintf("下载 excel 异常 %s", err.Error()))
+	}
+
+	// 解析excel,构造销售目标数据
+	excelData, err := s.parseExcel(buf)
+	if err != nil {
+		return myerrors.TipsError(fmt.Sprintf("解析 excel 异常 %s", err.Error()))
+	}
+	//客户类型
+	idyMap, err := service.GetDictDataByType(ctx, "cust_idy")
+	idyMap = reverseMap(idyMap)
+	//客户来源
+	sourceMap, err := service.GetDictDataByType(ctx, "cust_source")
+	sourceMap = reverseMap(sourceMap)
+
+	//关键字
+	keywordsMap, err := service.GetDictDataByType(ctx, "customer_bidding_keywords")
+	keywordsMap = reverseMap(keywordsMap)
+	svc, err := sbase.NewDistrictService(ctx)
+	treeList, err := svc.GetProvincesList(0)
+	fmt.Println("treeList", treeList)
+	//insertContactList := make([]*model.CustCustomerContactSeq, 0)
+	contactService, err := NewCustomerContactService(ctx)
+	if err != nil {
+		return err
+	}
+	CustomerService, err := NewCustomerService(ctx)
+	if err != nil {
+		return err
+	}
+	yesOrNoMap := map[string]string{
+		"是": "10",
+		"否": "20",
+	}
+	genderMap := map[string]string{
+		"男": "10",
+		"女": "20",
+	}
+
+	e := s.Dao.Transaction(ctx, func(ctx context.Context, tx *gdb.TX) error {
+		for _, data := range excelData {
+			var province *base.ProvincesTree
+			var city *base.ProvincesTree
+			var region *base.ProvincesTree
+
+			keywords := strings.Split(data.Keyword, ",")
+			for _, keyword := range keywords {
+				if _, ok := keywordsMap[keyword]; !ok {
+					return myerrors.TipsError(fmt.Sprintf("关键字 %s 不存在", keyword))
+				}
+			}
+			if data.CustProvince == "" {
+				return myerrors.TipsError("客户省份不能为空")
+			}
+
+			for _, tree := range treeList {
+				if tree.DistName == data.CustProvince {
+					province = tree
+					if data.CustCity != "" {
+						for _, cityData := range province.Children {
+							if cityData.DistName == data.CustCity {
+								city = cityData
+								if data.CustRegion != "" {
+									for _, RegionData := range cityData.Children {
+										if RegionData.DistName == data.CustRegion {
+											region = RegionData
+										}
+									}
+								}
+							}
+						}
+					}
+				}
+			}
+			if (province.Id == 0) || (city.Id == 0 && data.CustCity != "") || (region.Id == 0 && data.CustRegion != "") {
+				return myerrors.TipsError("省市区填写错误,请检查后重试")
+			}
+
+			insertCustomer := &model.CustomerAddSeq{
+				CustName:       data.CustName,
+				AbbrName:       data.AbbrName,
+				CustAddress:    data.CustAddress,
+				CustProvinceId: province.Id,
+				CustProvince:   data.CustProvince,
+				CustCityId:     city.Id,
+				CustCity:       data.CustCity,
+				CustRegionId:   region.Id,
+				CustRegion:     data.CustRegion,
+				CustIndustry:   idyMap[data.CustIndustry],
+				CustSource:     sourceMap[data.CustSource],
+				CustDistCode:   province.Id,
+				Remark:         data.Remark,
+				Keyword:        keywords,
+			}
+			id, err := s.Create(insertCustomer)
+			if err != nil {
+				return err
+			}
+			s.CreateDynamics("创建客户", req, id)
+
+			seq := model.CustCustomerContactSeq{
+				CustId:         int(id),
+				CuctName:       data.CuctName,
+				CuctGender:     genderMap[data.CuctGender],
+				Telephone:      data.Telephone,
+				Wechat:         data.Wechat,
+				Email:          data.Email,
+				Dept:           data.Dept,
+				Postion:        data.Postion,
+				OfficeLocation: data.OfficeLocation,
+				IsDecision:     yesOrNoMap[data.IsDecision],
+				Remark:         data.ContactRemark,
+			}
+			err = contactService.Create(&seq)
+			if err != nil {
+				return err
+			}
+
+			CustomerService.CreateDynamics("创建联系人", req, gconv.Int64(seq.CustId))
+		}
+		return nil
+	})
+
+	return e
+}
+
+// excel解构为数据
+func (s CustomerService) parseExcel(b []byte) ([]*model.CustomerAddImport, error) {
+	f, err := excelize.OpenReader(bytes.NewBuffer(b))
+	if err != nil {
+		return nil, err
+	}
+	sheet := "Sheet1"
+	rows := f.GetRows(sheet)
+	if err != nil {
+		return nil, err
+	}
+
+	// 客户名称 助计名 所在地区 详细地址 所在省 所在市 所在区县 客户行业 客户级别 客户来源 备注 销售名称 开票抬头 关联客户 姓名 性别 电话 微信 邮箱 部门 职位 办公地点 是否关键决策人 招标关键字
+	var saleTargets []*model.CustomerAddImport
+	for _, row := range rows[1:] {
+		temp := &model.CustomerAddImport{
+			CustName:       row[0],
+			AbbrName:       row[1],
+			CustAddress:    row[2],
+			CustProvince:   row[3],
+			CustCity:       row[4],
+			CustRegion:     row[5],
+			CustIndustry:   row[6],
+			CustSource:     row[7],
+			Keyword:        row[8],
+			Remark:         row[9],
+			CuctName:       row[10],
+			CuctGender:     row[11],
+			Telephone:      row[12],
+			Wechat:         row[13],
+			Email:          row[14],
+			Dept:           row[15],
+			Postion:        row[16],
+			OfficeLocation: row[17],
+			IsDecision:     row[18],
+			ContactRemark:  row[19],
+		}
+
+		saleTargets = append(saleTargets, temp)
+	}
+
+	return saleTargets, nil
+}
+
 // CreateBelong 创建客户归属信息
 func (s *CustomerService) CreateBelong(custId int) (err error) {
 	belong := new(model.CustomerBelongAddSeq)