瀏覽代碼

线索自动分配

xuzhiheng 2 年之前
父節點
當前提交
4f355268fa
共有 7 個文件被更改,包括 506 次插入87 次删除
  1. 二進制
      clueSync/clueSync
  2. 25 10
      clueSync/config.go
  3. 26 10
      clueSync/config.yaml
  4. 2 2
      clueSync/go.mod
  5. 17 0
      clueSync/go.sum
  6. 382 35
      clueSync/job.go
  7. 54 30
      clueSync/main.go

二進制
clueSync/clueSync


+ 25 - 10
clueSync/config.go

@@ -2,9 +2,13 @@ package main
 
 type (
 	Config struct {
-		CornExp  string `yaml:"cornexp"`
-		LastTime int64  `yaml:"lastTime"`
-		TiDb     struct {
+		CornExp1    string `yaml:"cornexp1"`
+		CornExp2    string `yaml:"cornexp2"`
+		CornExp3    string `yaml:"cornexp3"`
+		LastOrderId int    `yaml:"lastOrderId"`
+		LastUserId  string `yaml:"lastUserId"`
+		LastId      string `yaml:"lastId"`
+		TiDb        struct {
 			Host        string `yaml:"host"`
 			Port        int    `yaml:"port"`
 			Database    string `yaml:"database"`
@@ -14,6 +18,16 @@ type (
 			MaxIdle     int    `yaml:"maxidle"`
 			MaxLeftTime int    `yaml:"maxleft"`
 		} `yaml:"tiDb"`
+		BaseService struct {
+			Host        string `yaml:"host"`
+			Port        int    `yaml:"port"`
+			Database    string `yaml:"database"`
+			User        string `yaml:"user"`
+			Password    string `yaml:"password"`
+			PollSize    int    `yaml:"poolsize"`
+			MaxIdle     int    `yaml:"maxidle"`
+			MaxLeftTime int    `yaml:"maxleft"`
+		} `yaml:"baseService"`
 		Mysql struct {
 			Host        string `yaml:"host"`
 			Port        int    `yaml:"port"`
@@ -25,12 +39,13 @@ type (
 			MaxLeftTime int    `yaml:"maxleft"`
 		} `yaml:"mysql"`
 		Mgo struct {
-			Address  string `json:"address"`
-			DbName   string `json:"dbName"`
-			DbSize   int    `json:"dbSize"`
-			UserName string `json:"username"`
-			Password string `json:"password"`
-			ReplSet  string `json:"replSet"`
-		}
+			Address string `yaml:"address"`
+			DbName  string `yaml:"dbName"`
+			DbSize  int    `yaml:"dbSize"`
+		} `yaml:"mgo"`
+		Es struct {
+			Address string `yaml:"address"`
+			DbSize  int    `yaml:"dbSize"`
+		} `yaml:"es"`
 	}
 )

+ 26 - 10
clueSync/config.yaml

@@ -1,24 +1,40 @@
-cornexp: "0 0 0 * * ?"
-lastTime: 1660438800,
+cornexp1: "0 */30 * * * ?"
+cornexp2: "0 */10 * * * ?"
+cornexp3: "0 */5 * * * ?"
+lastOrderId: 1660438800
+lastUserId: 5751076de3ec62b1697b737e
+lastId: 5751076de3ec62b1697b737e
 tiDb:
-  host: 192.168.3.217
+  host: 127.0.0.1
   port: 4000
   database: Jianyu_subjectdb
   user: root
   password: "=PDT49#80Z!RVv52_z"
-  poolsize: 30
-  maxidle: 100
-  maxlife: 100
+  poolsize: 10
+  maxidle: 20
+  maxleft: 20
+baseService:
+  host: 127.0.0.1
+  port: 4000
+  database: base_service
+  user: root
+  password: "=PDT49#80Z!RVv52_z"
+  poolsize: 10
+  maxidle: 20
+  maxleft: 20
 mysql:
   host: 192.168.3.11
   port: 3366
   database: jianyu
   user: root
   password: Topnet123
-  poolsize: 30
-  maxidle: 100
-  maxlife: 100
+  poolsize: 10
+  maxidle: 20
+  maxleft: 20
 mgo:
   address: 192.168.3.206:27080
 	dbName: qfw
-	dbSize: 20
+	dbSize: 20
+es:
+	address: http://172.17.4.184:19800
+	dbSize": 10

+ 2 - 2
clueSync/go.mod

@@ -1,9 +1,9 @@
-module ConvertLabSync
+module clueSync
 
 go 1.14
 
 require (
-	app.yhyue.com/moapp/jybase v0.0.0-20221010080805-39dc6a853eff
+	app.yhyue.com/moapp/jybase v0.0.0-20230405040249-a36a23595798
 	app.yhyue.com/zhp/util v0.0.0-20211207072713-d9f1393203de
 	github.com/nsqio/go-nsq v1.1.0
 	github.com/robfig/cron v1.2.0

+ 17 - 0
clueSync/go.sum

@@ -1,6 +1,9 @@
+app.yhyue.com/moapp/esv1 v0.0.0-20220414031211-3da4123e648d h1:WPsYuuptAd3UEgN+jPzpnsDe/OvcshDUUtOTZPYGSJ8=
 app.yhyue.com/moapp/esv1 v0.0.0-20220414031211-3da4123e648d/go.mod h1:91/lSD/hS+ckMVP3WdidRzDhC60lLMdyce9QHy0cSMA=
 app.yhyue.com/moapp/jybase v0.0.0-20221010080805-39dc6a853eff h1:uYssVU5ODQHRdRpUt8jSVuJPFdbxQ+0G3CH6I7seRwU=
 app.yhyue.com/moapp/jybase v0.0.0-20221010080805-39dc6a853eff/go.mod h1:HelrO6tcD9TcKb/HOP2BLbzppyDz2kpQSFhPMQTUgbQ=
+app.yhyue.com/moapp/jybase v0.0.0-20230405040249-a36a23595798 h1:seczpucZNVIcwMpHN/tr1t9l7Qf533nm69FqJLq24qs=
+app.yhyue.com/moapp/jybase v0.0.0-20230405040249-a36a23595798/go.mod h1:zB47XTeJvpcbtBRYgkQuxOICWNexiZfbUO+7aUf6mNs=
 app.yhyue.com/zhp/util v0.0.0-20211207072713-d9f1393203de h1:rNF/1bv1Zi1p/4tqFi2H3KeM5ba9ttKsUy8bSD1qPQU=
 app.yhyue.com/zhp/util v0.0.0-20211207072713-d9f1393203de/go.mod h1:4z3uUIlwLA3B0BD3jwJRVTrwwDc/lCArDIsYAVRjxos=
 cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
@@ -91,6 +94,7 @@ github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:ma
 github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/dchest/captcha v0.0.0-20200903113550-03f5f0333e1f h1:q/DpyjJjZs94bziQ7YkBmIlpqbVP7yw179rnzoNVX1M=
 github.com/dchest/captcha v0.0.0-20200903113550-03f5f0333e1f/go.mod h1:QGrK8vMWWHQYQ3QU9bw9Y9OPNfxccGzfb41qjvVeXtY=
 github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
 github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE=
@@ -145,6 +149,7 @@ github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG
 github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
 github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE=
 github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
+github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
 github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
 github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
 github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
@@ -184,6 +189,7 @@ github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4=
 github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
 github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
 github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
+github.com/gomodule/redigo v1.8.9/go.mod h1:7ArFNvsTjH8GMMzB4uy1snslv2BwmginuMs06a1uzZE=
 github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
 github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
 github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA=
@@ -265,6 +271,7 @@ github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8
 github.com/justinas/alice v1.2.0/go.mod h1:fN5HRH/reO/zrUflLfTN43t3vXvKzvZIENsNEe7i7qA=
 github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
 github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
+github.com/klauspost/compress v1.13.6 h1:P76CopJELS0TiO2mebmnzgWaajssP/EszplttgQxcgc=
 github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
 github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
 github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
@@ -309,6 +316,7 @@ github.com/nsqio/go-nsq v1.1.0/go.mod h1:vKq36oyeVXgsS5Q8YEO7WghqidAVXQlcFxzQbQT
 github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
 github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
 github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
+github.com/olivere/elastic v6.2.37+incompatible h1:UfSGJem5czY+x/LqxgeCBgjDn6St+z8OnsCuxwD3L0U=
 github.com/olivere/elastic v6.2.37+incompatible/go.mod h1:J+q1zQJTgAz9woqsbVRqGeB5G1iqDKVBWLNSYW8yfJ8=
 github.com/olivere/elastic/v7 v7.0.22/go.mod h1:VDexNy9NjmtAkrjNoI7tImv7FR4tf5zUA3ickqu5Pc8=
 github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
@@ -335,6 +343,7 @@ github.com/pierrec/lz4 v2.6.1+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi
 github.com/pierrec/lz4/v4 v4.1.15/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
 github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
 github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
 github.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U=
@@ -399,9 +408,13 @@ github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhV
 github.com/tklauser/go-sysconf v0.3.10/go.mod h1:C8XykCvCb+Gn0oNCWPIlcb0RuglQTYaQ2hGm7jmxEFk=
 github.com/tklauser/numcpus v0.4.0/go.mod h1:1+UI3pD8NW14VMwdgJNJ1ESk2UnwhAnz5hMwiKKqXCQ=
 github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI=
+github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c=
 github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
+github.com/xdg-go/scram v1.0.2 h1:akYIkZ28e6A96dkWNJQu3nmCzH3YfwMPQExUYDaRv7w=
 github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs=
+github.com/xdg-go/stringprep v1.0.2 h1:6iq84/ryjjeRmMJwxutI51F2GIPlP5BfTvXHeYjyhBc=
 github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM=
+github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d h1:splanxYIlg+5LfHAM6xpdFEAYOk8iySO56hMFq6uLyA=
 github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA=
 github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
 github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
@@ -414,6 +427,7 @@ github.com/zeromicro/go-zero v1.3.5/go.mod h1:wh4o794b7Ul3W0k35Pw9nc3iB4O0OpaQTM
 go.etcd.io/etcd/api/v3 v3.5.4/go.mod h1:5GB2vv4A4AOn3yk7MftYGHkUfGtDHnEraIjym4dYz5A=
 go.etcd.io/etcd/client/pkg/v3 v3.5.4/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g=
 go.etcd.io/etcd/client/v3 v3.5.4/go.mod h1:ZaRkVgBZC+L+dLCjTcF1hRXpgZXQPOvnA/Ak/gq3kiY=
+go.mongodb.org/mongo-driver v1.9.1 h1:m078y9v7sBItkt1aaoe2YlvWEXcD263e1a4E1fBrJ1c=
 go.mongodb.org/mongo-driver v1.9.1/go.mod h1:0sQWfOeY63QTntERDJJ/0SuKK0T1uVSgKCuAROlKEPY=
 go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
 go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
@@ -448,6 +462,7 @@ golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPh
 golang.org/x/crypto v0.0.0-20201112155050-0c6587e931a9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
 golang.org/x/crypto v0.0.0-20201216223049-8b5274cf687f/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
 golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
+golang.org/x/crypto v0.0.0-20210920023735-84f357641f63 h1:kETrAMYZq6WVGPa8IIixL0CaEcIUNi+1WX7grUoi3y8=
 golang.org/x/crypto v0.0.0-20210920023735-84f357641f63/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
 golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
 golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
@@ -536,6 +551,7 @@ golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJ
 golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ=
 golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -608,6 +624,7 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
 golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
 golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
 golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=

+ 382 - 35
clueSync/job.go

@@ -1,79 +1,426 @@
 package main
 
 import (
+	"database/sql"
+	"fmt"
 	"log"
-)
+	"time"
 
-func runJob(mode int) {
-	log.Println("定时任务开始")
-	orders()
-	users()
-	saleleads()
-	log.Println("定时任务结束")
-}
+	"app.yhyue.com/moapp/jybase/common"
+	"app.yhyue.com/moapp/jybase/mongodb"
+)
 
-// 未支付订单
+// 未支付订单 30分钟一次
 func orders() {
-	//一个小时未支付进入线索
-	lastOrderId := 100000
-	Mysql.SelectByBath(500, func(l *[]map[string]interface{}) {
-		for _, v := range *l {
-			groupid := fmt.Sprint(v["groupid"])
-			customerid := fmt.Sprint(v["customerid"])
-			log.Println(groupid + "_" + customerid)
-			dataMap1[groupid+"_"+customerid] = true
-			log.Println(len(dataMap1))
-		}
-	}, `select * from dataexport_order where order_status = 0 and id >= `+lastOrderId)
+	//一个小时未支付进入线索 A
+	log.Println("未支付订单定时任务开始")
+	lastOrderId := cfg.LastOrderId
+	selectTimeStart := time.Unix(time.Now().Unix()-7200, 0).Format("2006-01-02 15:04:05")
+	selectTimeEnd := time.Unix(time.Now().Unix()-3600, 0).Format("2006-01-02 15:04:05")
+	sql := fmt.Sprintf(`select * from dataexport_order where order_status = 0 and product_type in ("大会员","VIP订阅","数据流量包","历史数据") and create_time <= "%s" and create_time >= "%s" and id > %s`, selectTimeEnd, selectTimeStart, fmt.Sprint(lastOrderId))
+	data := Mysql.SelectBySql(sql)
+	if data != nil && *data != nil && len(*data) > 0 {
+		for k, v := range *data {
+			FormatData(v, "orders")
+			if k == len(*data)-1 {
+				lastOrderId = common.IntAll(v["id"])
+			}
+		}
+	}
+	cfg.LastOrderId = lastOrderId
+	log.Println("未支付订单定时任务结束")
 }
 
-// 新注册用户
+// 新注册用户 5分钟一次
 func users() {
-	//新用户注册后5分钟内进入线索
+	//新用户注册后5分钟内进入线索 C
+	log.Println("新注册用户定时任务开始")
 	session := Mgo.GetMgoConn()
-	lastUserId := ""
-	count := 0
+	lastUserId := cfg.LastUserId
 	defer func() {
 		Mgo.DestoryMongoConn(session)
 	}()
 	query := map[string]interface{}{}
-	if LastFlag.LastId != "" {
-		query["_id"] = bson.M{"$gt": bson.ObjectIdHex(LastFlag.LastId)}
+	if lastUserId != "" {
+		query["_id"] = map[string]interface{}{"$gt": mongodb.StringTOBsonId(lastUserId)}
 	}
+	query["_id"] = map[string]interface{}{"$gt": mongodb.StringTOBsonId("63877e000000000000000000"), "$lte": mongodb.StringTOBsonId("63af0b000000000000000000")}
 	log.Println("query :", query)
-
 	iter := session.DB(cfg.Mgo.DbName).C("user").Find(&query).Sort("_id").Iter()
 	thisData := map[string]interface{}{}
 
 	for {
 		if !iter.Next(&thisData) {
+			lastUserId = mongodb.BsonIdToSId(thisData["_id"])
 			break
 		}
+		FormatData(thisData, "users")
 	}
+	cfg.LastUserId = lastUserId
+	log.Println("新注册用户定时任务结束")
 }
 
-// 留资
-func saleleads() {
+// 留资 5分钟一次
+func saleLeads() {
 	//留资后5分钟内进入线索
-	//分为免费留资和付费留资
+	//分为免费留资和付费留资 付费B 免费C
+	log.Println("用户留资定时任务开始")
 	session := Mgo.GetMgoConn()
-	lastId := ""
-	count := 0
+	lastId := cfg.LastId
 	defer func() {
 		Mgo.DestoryMongoConn(session)
 	}()
 	query := map[string]interface{}{}
-	if LastFlag.LastId != "" {
-		query["_id"] = bson.M{"$gt": bson.ObjectIdHex(LastFlag.LastId)}
+	if lastId != "" {
+		query["_id"] = map[string]interface{}{"$gt": mongodb.StringTOBsonId(lastId)}
 	}
+	query["_id"] = map[string]interface{}{"$gt": mongodb.StringTOBsonId("63877e000000000000000000"), "$lte": mongodb.StringTOBsonId("63af0b000000000000000000")}
 	log.Println("query :", query)
 
-	iter := session.DB(cfg.Mgo.DbName).C("saleleads").Find(&query).Sort("_id").Iter()
+	iter := session.DB(cfg.Mgo.DbName).C("saleLeads").Find(&query).Sort("_id").Iter()
 	thisData := map[string]interface{}{}
 
 	for {
 		if !iter.Next(&thisData) {
+			lastId = mongodb.BsonIdToSId(thisData["_id"])
 			break
 		}
+		FormatData(thisData, "saleLeads")
+	}
+	cfg.LastId = lastId
+	log.Println("用户留资定时任务结束")
+}
+
+func FormatData(data map[string]interface{}, item string) {
+	userId, uId, positionId, source, cluename, phone := common.ObjToString(data["user_id"]), "", "", 0, "", ""
+	role, industry, department, position, name, top_cluetype, sub_cluetype, follow_project_area, level := "", "", "", "", "", "", "", "", ""
+	query := map[string]interface{}{}
+	if item == "orders" {
+		if !mongodb.IsObjectIdHex(userId) {
+			positionId = userId
+			userMapping := TiDb.FindOne("dwd_f_userbase_id_mapping", map[string]interface{}{"position_id": userId}, "", "")
+			if userMapping != nil && len(*userMapping) > 0 {
+				userId = common.ObjToString((*userMapping)["userid"])
+			}
+		}
+		query["userid"] = userId
+		userInfo := TiDb.FindOne("dwd_f_userbase_baseinfo", query, "", "")
+		if userInfo != nil && len(*userInfo) > 0 {
+			uId = common.ObjToString((*userInfo)["uid"])
+			source = common.IntAll((*userInfo)["source"])
+		}
+		//cluename --> company_name
+		cluename = common.ObjToString(data["company_name"])
+		phone = common.ObjToString(data["user_phone"])
+	} else if item == "users" {
+		userId = mongodb.BsonIdToSId(data["_id"])
+		//新用户没有uid、source要等5分钟
+		query["userid"] = userId
+		userInfo := TiDb.FindOne("dwd_f_userbase_baseinfo", query, "", "")
+		if userInfo != nil && len(*userInfo) > 0 {
+			uId = common.ObjToString((*userInfo)["uid"])
+			source = common.IntAll((*userInfo)["source"])
+		}
+		cluename = common.ObjToString(data["s_company"])
+		phone = common.ObjToString(data["s_phone"])
+		if phone == "" {
+			phone = common.ObjToString(data["s_m_phone"])
+		}
+	} else if item == "saleLeads" {
+		userId = common.ObjToString(data["userid"])
+		if !mongodb.IsObjectIdHex(userId) {
+			positionId = userId
+			userMapping := TiDb.FindOne("dwd_f_userbase_id_mapping", map[string]interface{}{"position_id": userId}, "", "")
+			if userMapping != nil && len(*userMapping) > 0 {
+				userId = common.ObjToString((*userMapping)["userid"])
+			}
+		}
+		query["userid"] = userId
+		userInfo := TiDb.FindOne("dwd_f_userbase_baseinfo", query, "", "")
+		if userInfo != nil && len(*userInfo) > 0 {
+			uId = common.ObjToString((*userInfo)["uid"])
+			source = common.IntAll((*userInfo)["source"])
+		}
+		cluename = common.ObjToString(data["company"])
+		phone = common.ObjToString(data["phone"])
+		role = common.ObjToString(data["companyType"])
+		industry = common.ObjToString(data["industry"])
+		department = common.ObjToString(data["branch"])
+		position = common.ObjToString(data["position"])
+		name = common.ObjToString(data["name"])
+		// sourceCode = common.ObjToString(data["source"])
+	}
+	//域外用户和内部用户,不存线索
+	if source == 5 || source == 6 {
+		return
+	}
+	//不是留资的要查一遍留资
+	if item == "orders" {
+		qid := positionId
+		if qid == "" {
+			qid = userId
+		}
+		saleLeadsData, ok := Mgo.Find("saleLeads", map[string]interface{}{"userid": qid}, map[string]interface{}{"_id": -1}, nil, false, 0, 1)
+		if ok && saleLeadsData != nil && len(*saleLeadsData) > 0 {
+			sdata := (*saleLeadsData)[0]
+			role = common.ObjToString(sdata["companyType"])
+			industry = common.ObjToString(sdata["industry"])
+			department = common.ObjToString(sdata["branch"])
+			position = common.ObjToString(sdata["position"])
+			name = common.ObjToString(sdata["name"])
+		}
+	}
+
+	//top_cluetype
+	top_cluetype, sub_cluetype, level = getClueType(item, data)
+	//follow_project_area --> follow_project_monitor
+	follow_project_area = getAreaCode(userId)
+	//TODO seatNumber position_id
+	//自动分配规则暂不确定
+	log.Println("data +++", top_cluetype, sub_cluetype, level, follow_project_area)
+	position_id, seatNumber, saleName := autoDraw(level)
+	log.Println("data -------", position_id, seatNumber, saleName)
+	if position_id > 0 && seatNumber != "" {
+		uCount := TiDb.Count("dwd_f_crm_clue_info", map[string]interface{}{"uid": uId})
+		if uCount > 0 {
+			SaveClue(item, userId, uId, top_cluetype, sub_cluetype, cluename, name, saleName, phone, position, department, industry, follow_project_area, role, seatNumber, position_id)
+		} else {
+			SaveClue(item, userId, uId, top_cluetype, sub_cluetype, cluename, name, saleName, phone, position, department, industry, follow_project_area, role, seatNumber, position_id)
+		}
+	}
+}
+
+func SaveClue(item, userId, uId, top_cluetype, sub_cluetype, cluename, name, saleName, phone, position, department, industry, follow_project_area, role, seatNumber string, positionId int64) {
+	nowTime := time.Now().Format("2006-01-02 15:04:05")
+	nowTimes := time.Unix(time.Now().Unix()+3600*12, 0).Format("2006-01-02 15:04:05")
+	// BCPCID := common.GetRandom(32)
+	TiDb.ExecTx("保存线索", func(tx *sql.Tx) bool {
+		//线索
+		clueId := TiDb.InsertByTx(tx, "dwd_f_crm_clue_info", map[string]interface{}{
+			"userid":              userId,
+			"uid":                 uId,
+			"seatNumber":          seatNumber,
+			"position_id":         positionId,
+			"is_assign":           1,
+			"comeintime":          nowTime,
+			"createtime":          nowTime,
+			"updatetime":          nowTime,
+			"cluename":            cluename,
+			"top_cluetype":        top_cluetype,
+			"sub_cluetype":        sub_cluetype,
+			"trailstatus":         "01",
+			"name":                name,
+			"phone":               phone,
+			"position":            position,
+			"department":          department,
+			"industry":            industry,
+			"follow_project_area": follow_project_area,
+			"role":                role,
+		})
+		//私海 --> 任务车
+		seaId := TiDb.InsertByTx(tx, "dwd_f_crm_private_sea", map[string]interface{}{
+			"clue_id":      clueId,
+			"seatNumber":   seatNumber,
+			"position_id":  positionId,
+			"comeintime":   nowTime,
+			"comeinsource": 2,
+			"is_task":      1,
+			"task_time":    nowTime,
+			"tasktime":     common.If(item == "users", nowTimes, nowTime),
+			"taskstatus":   0,
+			"tasksource":   "线索自动分配" + "-" + top_cluetype + "-" + sub_cluetype,
+		})
+		//变更记录
+		uodateId1 := TiDb.InsertByTx(tx, "dwd_f_crm_clue_change_record", map[string]interface{}{
+			"clue_id":     clueId,
+			"position_id": positionId,
+			"change_type": "创建线索",
+			"new_value":   "系统自动创建",
+			"createtime":  nowTime,
+			"BCPCID":      common.GetRandom(32),
+			"operator_id": -1,
+		})
+		uodateId2 := TiDb.InsertByTx(tx, "dwd_f_crm_clue_change_record", map[string]interface{}{
+			"clue_id":      clueId,
+			"position_id":  positionId,
+			"change_field": "position_id",
+			"change_type":  "所属人变更",
+			"old_value":    "/",
+			"new_value":    saleName,
+			"createtime":   nowTime,
+			"BCPCID":       common.GetRandom(32),
+			"operator_id":  -1,
+		})
+		uodateId3 := TiDb.InsertByTx(tx, "dwd_f_crm_clue_change_record", map[string]interface{}{
+			"clue_id":      clueId,
+			"position_id":  positionId,
+			"change_field": "trailstatus",
+			"change_type":  "基本信息变更",
+			"new_value":    "新增",
+			"createtime":   nowTime,
+			"BCPCID":       common.GetRandom(32),
+			"operator_id":  -1,
+		})
+		uodateId4 := TiDb.InsertByTx(tx, "dwd_f_crm_clue_change_record", map[string]interface{}{
+			"clue_id":     clueId,
+			"position_id": positionId,
+			"change_type": "加入任务车",
+			"new_value":   "线索自动分配" + "-" + top_cluetype + "-" + sub_cluetype,
+			"createtime":  nowTime,
+			"BCPCID":      common.GetRandom(32),
+			"operator_id": -1,
+		})
+		return clueId > 0 && seaId > 0 && uodateId1 > 0 && uodateId2 > 0 && uodateId3 > 0 && uodateId4 > 0
+	})
+}
+
+func UpdateClue(item, userId, uId, top_cluetype, sub_cluetype, cluename, name, phone, position, department, industry, follow_project_area, role, seatNumber string, positionId int64) {
+	nowTime := time.Now().Format("2006-01-02 15:04:05")
+	// nowTimes := time.Unix(time.Now().Unix()+3600*12, 0).Format("2006-01-02 15:04:05")
+	TiDb.ExecTx("更新线索", func(tx *sql.Tx) bool {
+		//线索
+		ok := TiDb.UpdateByTx(tx, "dwd_f_crm_clue_info", map[string]interface{}{"uid": uId}, map[string]interface{}{
+			"seatNumber":          seatNumber,
+			"position_id":         positionId,
+			"is_assign":           1,
+			"updatetime":          nowTime,
+			"cluename":            cluename,
+			"top_cluetype":        top_cluetype,
+			"sub_cluetype":        sub_cluetype,
+			"trailstatus":         "01",
+			"name":                name,
+			"phone":               phone,
+			"position":            position,
+			"department":          department,
+			"industry":            industry,
+			"follow_project_area": follow_project_area,
+			"role":                role,
+		})
+		return ok
+	})
+}
+
+func getAreaCode(userId string) (code string) {
+	followData := Base.FindOne("follow_project_monitor", map[string]interface{}{"s_userid": userId}, "", "")
+	if followData != nil && len(*followData) > 0 {
+		infoId := common.ObjToString((*followData)["s_id"])
+		biddingData := Es.GetByIdField("bidding", "bidding", infoId, "")
+		if biddingData != nil && len(*biddingData) > 0 {
+			area := common.ObjToString((*biddingData)["area"])
+			address := common.ObjToString((*biddingData)["city"])
+			if address == "" {
+				address = area
+			}
+			areaData := TiDb.FindOne("d_area_code", map[string]interface{}{"name": address}, "", "")
+			if areaData != nil && len(*areaData) > 0 {
+				code = common.ObjToString((*areaData)["code"])
+			}
+		}
+	}
+	return
+}
+
+func getClueType(item string, data map[string]interface{}) (pcode, code, level string) {
+	if item == "orders" {
+		productType := common.ObjToString(data["product_type"])
+		pcode = "1"
+		level = "A"
+		if productType == "VIP订阅" {
+			code = "6"
+		} else if productType == "大会员" {
+			code = "7"
+		} else if productType == "数据流量包" {
+			code = "8"
+		} else if productType == "历史数据" {
+			code = "9"
+		}
+	} else if item == "users" {
+		pcode = "4"
+		code = "154"
+		level = "C"
+	} else if item == "saleLeads" {
+		sourceCode := common.ObjToString(data["source"])
+		if sourceCode != "" {
+			codeData := TiDb.FindOne("dwd_d_crm_cluetype_code", map[string]interface{}{"source": sourceCode}, "", "")
+			if codeData != nil && len(*codeData) > 0 {
+				pcode = common.ObjToString((*codeData)["pcode"])
+				code = common.ObjToString((*codeData)["code"])
+				level = common.ObjToString((*codeData)["clue_level"])
+			}
+		}
+	}
+	return
+}
+
+// 获取自动分配的人
+func autoDraw(mode string) (positionId int64, seatNumber, saleName string) {
+	query := `select * from jy_salesperson_info where status = 0 and position != 0`
+	if mode == "A" || mode == "B" {
+		query += ` and is_complete = 1`
+	}
+	data := TiDb.SelectBySql(query)
+	if data != nil && len(*data) > 0 {
+		sql := "select * from dwd_f_crm_clue_autodraw_record where clue_level = ?"
+		countData := TiDb.SelectBySql(sql, mode)
+		if countData != nil && len(*countData) > 0 {
+			for _, v := range *data {
+				//判断是否有新员工
+				isOk := false
+				for _, vv := range *countData {
+					if common.ObjToString(v["seatNumber"]) == common.ObjToString(vv["seatNumber"]) {
+						isOk = true
+					}
+				}
+				//有新员工直接分给新员工
+				if !isOk {
+					seatNumber = common.ObjToString(v["seatNumber"])
+					saleName = common.ObjToString(v["name"])
+					rData := TiDb.FindOne("dwd_f_crm_clue_autodraw_record", map[string]interface{}{"clue_level": mode}, "", "count asc")
+					TiDb.Insert("dwd_f_crm_clue_autodraw_record", map[string]interface{}{
+						"position_id": positionId,
+						"seatNumber":  seatNumber,
+						"clue_level":  mode,
+						"count":       common.Int64All((*rData)["count"]),
+					})
+					break
+				}
+			}
+			if seatNumber == "" {
+				res := int64(0)
+				for k, v := range *countData {
+					if k == 0 {
+						res = common.Int64All(v["count"])
+						seatNumber = common.ObjToString(v["seatNumber"])
+					} else {
+						if common.Int64All(v["count"]) <= res {
+							res = common.Int64All(v["count"])
+							seatNumber = common.ObjToString(v["seatNumber"])
+						}
+					}
+				}
+			}
+		}
+		for _, v := range *data {
+			if seatNumber == common.ObjToString(v["seatNumber"]) {
+				positionId = getPositionId(common.ObjToString(v["phone"]))
+				saleName = common.ObjToString(v["name"])
+			}
+		}
+		if positionId > 0 {
+			TiDb.UpdateOrDeleteBySql(`update dwd_f_crm_clue_autodraw_record set count = count + 1 where seatNumber = ? and clue_level = ?`, seatNumber, mode)
+		}
+	}
+	return
+}
+
+func getPositionId(phone string) (positionId int64) {
+	userData, ok := Mgo.FindOne("user", map[string]interface{}{"s_phone": phone})
+	if ok && userData != nil && len(*userData) > 0 {
+		userId := common.Int64All((*userData)["base_user_id"])
+		positionData := Base.FindOne("base_position", map[string]interface{}{"type": 1, "ent_id": 25917, "user_id": userId}, "", "") //TODO ent_id
+		if positionData != nil && len(*positionData) > 0 {
+			positionId = common.Int64All((*positionData)["id"])
+		}
 	}
+	return
 }

+ 54 - 30
clueSync/main.go

@@ -1,21 +1,14 @@
 package main
 
 import (
-	"database/sql"
 	"flag"
 	"fmt"
-	"log"
-	"strconv"
-	"strings"
-	"sync"
-	"time"
 
 	"app.yhyue.com/moapp/jybase/mongodb"
 
+	elastic "app.yhyue.com/moapp/jybase/esv1"
 	"app.yhyue.com/moapp/jybase/mysql"
 	"app.yhyue.com/zhp/util/config"
-
-	dbUtil "app.yhyue.com/zhp/util/db"
 	"github.com/robfig/cron"
 )
 
@@ -23,44 +16,75 @@ var (
 	cfg        = new(Config)
 	Mysql      *mysql.Mysql
 	TiDb       *mysql.Mysql
+	Base       *mysql.Mysql
+	Es         *elastic.Elastic
 	Mgo        *mongodb.MongodbSim
 	configFile = flag.String("c", "./config.yaml", "配置文件")
 	mode       = flag.Int("m", 1, "")
 )
 
-func init() {
+func main() {
 	flag.Parse()
 	_ = config.LoadConfigWithYaml(*configFile, cfg)
-	var err error
 	TiDb = &mysql.Mysql{
-		Address:      cfg.Db.Host + ":" + fmt.Sprint(cfg.Db.Port),
-		UserName:     cfg.Db.User,
-		PassWord:     cfg.Db.Password,
-		DBName:       cfg.Db.Database,
-		MaxOpenConns: cfg.Db.PollSize,
-		MaxIdleConns: cfg.Db.MaxIdle,
+		Address:      cfg.TiDb.Host + ":" + fmt.Sprint(cfg.TiDb.Port),
+		UserName:     cfg.TiDb.User,
+		PassWord:     cfg.TiDb.Password,
+		DBName:       cfg.TiDb.Database,
+		MaxOpenConns: cfg.TiDb.PollSize,
+		MaxIdleConns: cfg.TiDb.MaxIdle,
 	}
 	TiDb.Init()
 	Mysql = &mysql.Mysql{
-		Address:      cfg.Db.Host + ":" + fmt.Sprint(cfg.Db.Port),
-		UserName:     cfg.Db.User,
-		PassWord:     cfg.Db.Password,
-		DBName:       cfg.Db.Database,
-		MaxOpenConns: cfg.Db.PollSize,
-		MaxIdleConns: cfg.Db.MaxIdle,
+		Address:      cfg.Mysql.Host + ":" + fmt.Sprint(cfg.Mysql.Port),
+		UserName:     cfg.Mysql.User,
+		PassWord:     cfg.Mysql.Password,
+		DBName:       cfg.Mysql.Database,
+		MaxOpenConns: cfg.Mysql.PollSize,
+		MaxIdleConns: cfg.Mysql.MaxIdle,
 	}
-	TiDb.Init()
-	Mgo = mongodb.NewMgo(cfg.Db.Address, cfg.Db.DbName, cfg.Db.DbSize)
-}
-
-func main() {
+	Mysql.Init()
+	Base = &mysql.Mysql{
+		Address:      cfg.BaseService.Host + ":" + fmt.Sprint(cfg.BaseService.Port),
+		UserName:     cfg.BaseService.User,
+		PassWord:     cfg.BaseService.Password,
+		DBName:       cfg.BaseService.Database,
+		MaxOpenConns: cfg.BaseService.PollSize,
+		MaxIdleConns: cfg.BaseService.MaxIdle,
+	}
+	Base.Init()
+	Es = &elastic.Elastic{
+		S_esurl: cfg.Es.Address,
+		I_size:  cfg.Es.DbSize,
+	}
+	Es.InitElasticSize()
+	Mgo = mongodb.NewMgo(cfg.Mgo.Address, cfg.Mgo.DbName, cfg.Mgo.DbSize)
 	if *mode == 1 {
-		runJob(*mode)
+		// 未支付订单 30分钟一次
+		orders()
+		a := cron.New()
+		a.AddFunc(cfg.CornExp1, func() {
+			orders()
+		})
+		a.Start()
+		// 新注册用户 5分钟一次
+		users()
+		b := cron.New()
+		b.AddFunc(cfg.CornExp2, func() {
+			users()
+		})
+		b.Start()
+		// 留资 5分钟一次
+		saleLeads()
 		c := cron.New()
-		c.AddFunc(cfg.CornExp, func() {
-			runJob(*mode)
+		c.AddFunc(cfg.CornExp3, func() {
+			saleLeads()
 		})
 		c.Start()
 		select {}
+	} else if *mode == 2 {
+		users()
+	} else if *mode == 3 {
+		saleLeads()
 	}
 }