123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395 |
- package maycur
- import (
- "crypto/hmac"
- "crypto/md5"
- "encoding/hex"
- "encoding/json"
- "fmt"
- "github.com/rdlucklib/rdluck_tools/common"
- "hongze/hz_crm_api/models"
- "hongze/hz_crm_api/services/alarm_msg"
- "hongze/hz_crm_api/utils"
- "io/ioutil"
- "net/http"
- "net/url"
- "sort"
- "strconv"
- "strings"
- "time"
- )
- const (
- ShanghaiCRMCompanyListUrl = `/v2/Customer/basicSaleCustomerRelation`
- ShanghaiCRMSellerListUrl = `/v2/AdminUser/EquitySaleDeptMemberList`
- ShanghaiCRMCompanyListUrlRelease = `https://crm.hzinsights.com/openapi/v2/Customer/basicSaleCustomerRelation`
- ShanghaiCRMSellerListUrlRelease = `https://crm.hzinsights.com/openapi/v2/AdminUser/EquitySaleDeptMemberList`
- )
- // openApiParamsBuild 生成Api参数(含签名)
- func openApiParamsBuild(paramMap map[string]string) (params url.Values) {
- // 公共参数
- strRand := utils.GetRandStringNoSpecialChar(32)
- timestamp := fmt.Sprint(time.Now().Unix())
- values := map[string]string{
- "app_key": utils.CRM_OPEN_API_APP_KEY,
- "nonce_str": strRand,
- "timestamp": timestamp,
- }
- // ASCII排序
- keys := make([]string, 0)
- keys = append(keys, "app_key", "nonce_str", "timestamp")
- for k, v := range paramMap {
- keys = append(keys, k)
- values[k] = v
- }
- sort.Strings(keys)
- params = make(map[string][]string)
- signArr := make([]string, 0) // 参与签名生成的参数
- for _, k := range keys {
- params.Add(k, values[k])
- signArr = append(signArr, fmt.Sprint(k, "=", values[k]))
- }
- // 签名
- strA := strings.Join(signArr, "&")
- h := hmac.New(md5.New, []byte(utils.CRM_OPEN_API_APP_SECRET))
- h.Write([]byte(strA))
- strB := hex.EncodeToString(h.Sum([]byte("")))
- strD := common.UrlEncode(strB)
- params.Add("signature", strD)
- return
- }
- // PublicOfferingCompanyApiResp 客户列表响应体
- type PublicOfferingCompanyApiResp struct {
- Code int `description:"状态码: 1-成功; 0-失败; >1-指定错误"`
- Msg string `description:"提示信息"`
- Time int64 `description:"时间戳"`
- Data struct {
- Paginator struct {
- Total int `description:"数据总量"`
- CurrentPage int `description:"当前页码" json:"current_page"`
- ListRow int `description:"每页数据量" json:"list_row"`
- LastPage int `description:"最后一页页码" json:"last_page"`
- } `description:"分页信息"`
- Data []struct {
- Name string `description:"公司名称"`
- ShortName string `description:"公司简称" json:"short_name"`
- Social string `description:"公司社会信用码"`
- UserId string `description:"销售ID" json:"user_id"`
- Username string `description:"销售名称"`
- } `description:"公司列表"`
- } `description:"响应数据"`
- }
- // CurlPublicOfferingCompanyApi 请求客户列表接口
- func CurlPublicOfferingCompanyApi(strParams string) (body []byte, err error) {
- //curlUrl := fmt.Sprintf("%s%s?%s", utils.CRM_OPEN_API_URL, ShanghaiCRMCompanyListUrl, strParams)
- curlUrl := fmt.Sprintf("%s?%s", ShanghaiCRMCompanyListUrlRelease, strParams)
- res, e := http.Get(curlUrl)
- if e != nil {
- err = fmt.Errorf("http get err: %s", e.Error())
- return
- }
- defer func() {
- _ = res.Body.Close()
- }()
- body, e = ioutil.ReadAll(res.Body)
- if e != nil {
- err = fmt.Errorf("http body err: %s", e.Error())
- return
- }
- //utils.FileLog.Info("open api http resp: %s", string(body))
- return
- }
- // PublicOfferingSaleApiResp 销售列表响应体
- type PublicOfferingSaleApiResp struct {
- Code int `description:"状态码: 1-成功; 0-失败; >1-指定错误"`
- Msg string `description:"提示信息"`
- Time int64 `description:"时间戳"`
- Data []struct {
- Mobile string `description:"手机号"`
- Nickname string `description:"销售姓名"`
- DeptText string `description:"部门描述" json:"dept_text"`
- IsLeader int `description:"是否为负责人: 0-否; 1-是" json:"is_leader"`
- } `description:"响应数据"`
- }
- // CurlEquitySaleListApi 请求公募销售列表接口
- func CurlEquitySaleListApi(strParams string) (body []byte, err error) {
- //curlUrl := fmt.Sprintf("%s%s?%s", utils.CRM_OPEN_API_URL, ShanghaiCRMSellerListUrl, strParams)
- curlUrl := fmt.Sprintf("%s?%s", ShanghaiCRMSellerListUrlRelease, strParams)
- res, e := http.Get(curlUrl)
- if e != nil {
- err = fmt.Errorf("http get err: %s", e.Error())
- return
- }
- defer func() {
- _ = res.Body.Close()
- }()
- body, e = ioutil.ReadAll(res.Body)
- if e != nil {
- err = fmt.Errorf("http body err: %s", e.Error())
- return
- }
- utils.FileLog.Info("open api http resp: %s", string(body))
- return
- }
- // SyncPublicOfferingSale 同步公募销售
- func SyncPublicOfferingSale() (err error) {
- defer func() {
- if err != nil {
- msg := fmt.Sprintf("每刻-同步公募销售失败, ErrMsg: %s", err.Error())
- utils.FileLog.Error(msg)
- go alarm_msg.SendAlarmMsg(msg, 3)
- }
- }()
- paramMap := make(map[string]string)
- params := openApiParamsBuild(paramMap)
- strParams := params.Encode()
- res, e := CurlEquitySaleListApi(strParams)
- if e != nil {
- err = fmt.Errorf("获取公募销售列表失败, Err: %s", e.Error())
- return
- }
- if len(res) == 0 {
- err = fmt.Errorf("公募销售数据为空")
- return
- }
- var resp PublicOfferingSaleApiResp
- if e := json.Unmarshal(res, &resp); e != nil {
- err = fmt.Errorf("解析公募销售数据失败, Err: %s; Body: %s", e.Error(), string(res))
- return
- }
- if resp.Code != 1 {
- err = fmt.Errorf("获取公募销售数据失败, Body: %s", string(res))
- return
- }
- sales := resp.Data
- // 去重
- saleOB := new(models.MaycurPublicOfferingSale)
- saleCond := ``
- salePars := make([]interface{}, 0)
- origins, e := saleOB.GetItemsByCondition(saleCond, salePars, []string{}, "")
- if e != nil {
- err = fmt.Errorf("获取公募销售留档失败, Err: %s", e.Error())
- return
- }
- salesNameVal := make(map[string]*models.MaycurPublicOfferingSale)
- for _, s := range origins {
- salesNameVal[s.Nickname] = s
- }
- // 新增
- inserts := make([]*models.MaycurPublicOfferingSale, 0)
- updateCols := []string{"Mobile", "DeptText", "IsLeader", "ModifyTime"}
- for _, v := range sales {
- s := salesNameVal[v.Nickname]
- if s != nil {
- s.Mobile = v.Mobile
- s.DeptText = v.DeptText
- s.IsLeader = v.IsLeader
- s.ModifyTime = time.Now().Local()
- if e = s.Update(updateCols); e != nil {
- err = fmt.Errorf("更新公募销售信息失败, Err: %s", e.Error())
- return
- }
- continue
- }
- inserts = append(inserts, &models.MaycurPublicOfferingSale{
- Mobile: v.Mobile,
- Nickname: v.Nickname,
- CreateTime: time.Now().Local(),
- ModifyTime: time.Now().Local(),
- })
- }
- if e = saleOB.CreateMulti(inserts); e != nil {
- err = fmt.Errorf("新增公募销售失败, Err: %s", e.Error())
- return
- }
- return
- }
- // SyncPublicOfferingCompany 同步客户列表, 过滤出公募客户入库留档
- func SyncPublicOfferingCompany() (err error) {
- defer func() {
- if err != nil {
- msg := fmt.Sprintf("每刻-同步公募客户失败, ErrMsg: %s", err.Error())
- utils.FileLog.Error(msg)
- go alarm_msg.SendAlarmMsg(msg, 3)
- }
- }()
- // 去重
- companyOB := new(models.MaycurPublicOfferingCompany)
- companyCond := ``
- companyPars := make([]interface{}, 0)
- origins, e := companyOB.GetItemsByCondition(companyCond, companyPars, []string{}, "")
- if e != nil {
- err = fmt.Errorf("获取公募客户留档失败, Err: %s", e.Error())
- return
- }
- companyCodeVal := make(map[string]*models.MaycurPublicOfferingCompany)
- for _, s := range origins {
- companyCodeVal[s.Social] = s
- }
- // 获取公募销售
- saleOB := new(models.MaycurPublicOfferingSale)
- sales, e := saleOB.GetItemsByCondition(``, make([]interface{}, 0), []string{}, "")
- if e != nil {
- err = fmt.Errorf("获取公募销售列表失败, Err: %s", e.Error())
- return
- }
- saleArr := make([]string, 0)
- for _, s := range sales {
- saleArr = append(saleArr, s.Nickname)
- }
- currentPage := 1
- pageSize := 100
- updateCols := []string{"SaleNames", "ModifyTime"}
- codeSales := make(map[string][]string)
- for {
- paramMap := make(map[string]string)
- paramMap["limit"] = strconv.Itoa(pageSize)
- paramMap["f_e"] = "Equity"
- paramMap["page"] = strconv.Itoa(currentPage)
- params := openApiParamsBuild(paramMap)
- strParams := params.Encode()
- res, e := CurlPublicOfferingCompanyApi(strParams)
- if e != nil {
- err = fmt.Errorf("获取公募销售列表失败, Err: %s", e.Error())
- return
- }
- if len(res) == 0 {
- err = fmt.Errorf("公募销售数据为空")
- return
- }
- var resp PublicOfferingCompanyApiResp
- if e := json.Unmarshal(res, &resp); e != nil {
- err = fmt.Errorf("解析公募客户数据失败, Err: %s; Body: %s", e.Error(), string(res))
- return
- }
- if resp.Code != 1 {
- err = fmt.Errorf("获取公募客户数据失败, Body: %s", string(res))
- return
- }
- data := resp.Data
- companies := data.Data
- codeCompany := make(map[string]*models.MaycurPublicOfferingCompany)
- for _, c := range companies {
- // 过滤测试客户
- if strings.Contains(c.Name, "测试") || strings.Contains(strings.ToLower(c.Name), "test") {
- continue
- }
- // 如果该客户的销售中无公募销售, 则忽略
- if !utils.InArrayByStr(saleArr, c.Username) {
- continue
- }
- if codeCompany[c.Social] == nil {
- v := &models.MaycurPublicOfferingCompany{
- Name: c.Name,
- ShortName: c.ShortName,
- Social: c.Social,
- CreateTime: time.Now().Local(),
- ModifyTime: time.Now().Local(),
- }
- codeCompany[c.Social] = v
- }
- if c.Username != "" && !utils.InArrayByStr(codeSales[c.Social], c.Username) {
- codeSales[c.Social] = append(codeSales[c.Social], c.Username)
- }
- }
- inserts := make([]*models.MaycurPublicOfferingCompany, 0)
- for _, c := range codeCompany {
- saleNames := strings.Join(codeSales[c.Social], ",")
- ex := companyCodeVal[c.Social]
- if ex != nil {
- // 更新销售
- ex.SaleNames = saleNames
- ex.ModifyTime = time.Now().Local()
- if e = ex.Update(updateCols); e != nil {
- err = fmt.Errorf("更新客户信息失败, Err: %s", e.Error())
- return
- }
- continue
- }
- c.SaleNames = saleNames
- inserts = append(inserts, c)
- // 本次新增的客户也加入map, 因为可能出现下一页有上一页的客户, 下一次循环时更新
- companyCodeVal[c.Social] = c
- }
- ob := new(models.MaycurPublicOfferingCompany)
- if e = ob.CreateMulti(inserts); e != nil {
- err = fmt.Errorf("批量新增客户信息失败, Err: %s", e.Error())
- return
- }
- // 最后一页
- if data.Paginator.LastPage == currentPage {
- break
- }
- currentPage += 1
- }
- return
- }
- // GetPublicOfferingSaleLeader 获取公募销售对应的组长
- func GetPublicOfferingSaleLeader() (leaderMap map[string][]string, err error) {
- saleOB := new(models.MaycurPublicOfferingSale)
- sales, e := saleOB.GetItemsByCondition(``, make([]interface{}, 0), []string{}, "")
- if e != nil {
- err = fmt.Errorf("获取公募销售列表失败, Err: %s", e.Error())
- return
- }
- if sales == nil {
- return
- }
- if len(sales) == 0 {
- return
- }
- // 销售组组长
- groupsLeader := make(map[string][]string)
- for _, s := range sales {
- // 存在这种数据->北京组、上海组
- gs := strings.Split(s.DeptText, "、")
- for _, g := range gs {
- if s.IsLeader == 1 {
- groupsLeader[g] = append(groupsLeader[g], s.Nickname)
- }
- }
- }
- // 销售对应组长
- leaderMap = make(map[string][]string)
- for _, s := range sales {
- // 组长置空
- ls := make([]string, 0)
- if s.IsLeader == 1 {
- leaderMap[s.Nickname] = ls
- continue
- }
- // 组员
- gs := strings.Split(s.DeptText, "、")
- for _, g := range gs {
- if len(groupsLeader[g]) > 0 {
- for _, l := range groupsLeader[g] {
- if !utils.InArrayByStr(ls, l) {
- ls = append(ls, l)
- }
- }
- }
- }
- leaderMap[s.Nickname] = ls
- }
- return
- }
|