resourceChannel.go 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391
  1. package resourceChannel
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "github.com/aliyun/aliyun-oss-go-sdk/oss"
  6. "github.com/go-redis/redis"
  7. "golang.org/x/net/context"
  8. "io/ioutil"
  9. "log"
  10. "os"
  11. "strconv"
  12. "strings"
  13. "time"
  14. )
  15. func redisCli() *redis.Client {
  16. client := redis.NewClient(&redis.Options{
  17. Addr: coo.RedisHost, // Redis地址
  18. //Addr: "192.168.204.193:6379", // Redis地址
  19. Password: "", // Redis密码,默认为空
  20. DB: 1, // 使用哪个数据库,默认为0
  21. })
  22. _, cancel := context.WithTimeout(context.Background(), 500*time.Millisecond)
  23. defer cancel()
  24. return client
  25. }
  26. type ResourceAssessment struct {
  27. ID uint `gorm:"primaryKey" json:"id"` // 留学评估表
  28. DataType uint8 `json:"data_type"` // 1.网课 2.api资源 3.专题页 4.工作台录入 5.后台录入 6 小程序
  29. ChatID string `json:"chat_id"` // 会话id
  30. Channel int `json:"channel"` // 渠道id
  31. Category int `json:"category"` // 分类id
  32. CreatedAt time.Time `json:"created_at"` // 数据创建时间
  33. ReferPageURL string `json:"refer_page_url"` // 来源网址
  34. URL string `json:"url"` // 落地页地址
  35. ChatURL string `json:"chat_url"` // 对话发起页
  36. GrUserId string `json:"gr_user_id"` // 神策distinct_id
  37. JsonPath string `json:"json_path"`
  38. }
  39. type SemJsChatRecord struct {
  40. ChatID int64 `gorm:"column:CHAT_ID"`
  41. CreateTime time.Time `gorm:"column:CREATE_TIME"`
  42. ReferPage string `gorm:"type:text;column:REFER_PAGE"`
  43. ChatURL string `gorm:"type:text;column:CHAT_URL"`
  44. ChannleID int `gorm:"column:CHANNLE_ID"`
  45. CategoryID int `gorm:"column:CATEGORY_ID"`
  46. GrUserID string `gorm:"column:gr_user_id"`
  47. SourceUrl string `gorm:"column:source_url"`
  48. JsonPath string `json:"json_path"`
  49. }
  50. type ChannelCategory struct {
  51. Channel int
  52. Category int
  53. }
  54. // GetChannel 表单渠道归因处理
  55. func GetChannel(assessment ResourceAssessment) ChannelCategory {
  56. log.Printf("%v", assessment)
  57. // 获取神策URL(不包含utm)
  58. cc, _ := redisCli().Get("website:" + assessment.GrUserId).Result()
  59. var websiteUrl SensorsData
  60. json.Unmarshal([]byte(cc), &websiteUrl)
  61. // 到梦解析
  62. if !strings.Contains(assessment.URL, "utm") && !strings.Contains(assessment.ChatURL, "utm") && !strings.Contains(assessment.ReferPageURL, "utm") && (strings.Contains(assessment.ReferPageURL, "daomeng") || strings.Contains(assessment.ChatURL, "daomeng")) {
  63. log.Printf("解析到梦")
  64. assessment.Channel = 38
  65. assessment.Category = getCategory(201, assessment.JsonPath)
  66. return ChannelCategory{assessment.Channel, assessment.Category}
  67. }
  68. // 网课解析
  69. if assessment.DataType == 1 {
  70. log.Printf("解析网课")
  71. assessment.Channel = 26
  72. assessment.Category = getCategory(121, assessment.JsonPath)
  73. return ChannelCategory{assessment.Channel, assessment.Category}
  74. }
  75. // 小程序解析
  76. if strings.Contains(assessment.ChatURL, "pages") && strings.Split(strings.Split(assessment.ChatURL, "?")[1], "=")[0] == "miniapp" && (strings.Contains(assessment.ChatURL, "baidu") || strings.Contains(assessment.ChatURL, "wechat")) {
  77. log.Printf("解析小程序")
  78. appType := strings.Split(strings.Split(strings.Split(assessment.ChatURL, "?")[1], "=")[1], "_")[1]
  79. if appType == "baidu" {
  80. assessment.Channel = 1
  81. assessment.Category = getCategory(30, assessment.JsonPath)
  82. } else if appType == "wechat" {
  83. assessment.Channel = 8
  84. assessment.Category = getCategory(32, assessment.JsonPath)
  85. }
  86. return ChannelCategory{assessment.Channel, assessment.Category}
  87. }
  88. // URL解析
  89. if strings.Contains(assessment.URL, "link=") || strings.Contains(assessment.ReferPageURL, "link=") || strings.Contains(assessment.ChatURL, "link=") {
  90. log.Printf("解析URL")
  91. if strings.Contains(assessment.URL, "link=") && len(strings.Split(strings.Split(assessment.URL, "link=")[1], "_")) == 3 {
  92. var category, _ = strconv.Atoi(strings.Split(strings.Split(assessment.URL, "link=")[1], "_")[1])
  93. if category > 10000 {
  94. assessment.Channel = category
  95. assessment.Category = category
  96. }
  97. } else if strings.Contains(assessment.ReferPageURL, "link=") && len(strings.Split(strings.Split(assessment.ReferPageURL, "link=")[1], "_")) == 3 {
  98. var category, _ = strconv.Atoi(strings.Split(strings.Split(assessment.ReferPageURL, "link=")[1], "_")[1])
  99. if category > 10000 {
  100. assessment.Channel = category
  101. assessment.Category = category
  102. }
  103. } else if strings.Contains(assessment.ChatURL, "link=") && len(strings.Split(strings.Split(assessment.ChatURL, "link=")[1], "_")) == 3 {
  104. var category, _ = strconv.Atoi(strings.Split(strings.Split(assessment.ChatURL, "link=")[1], "_")[1])
  105. if category > 10000 {
  106. assessment.Channel = category
  107. assessment.Category = category
  108. }
  109. } else {
  110. if strings.Contains(assessment.URL, "link=") {
  111. split := strings.Split(assessment.URL, "link")
  112. if strings.Contains(split[1], "form") || strings.Contains(split[1], "from") {
  113. assessment.Channel, _ = strconv.Atoi(strings.Split(strings.Split(strings.Split(assessment.URL, "link")[1], "form")[0], "_")[1])
  114. var category, _ = strconv.Atoi(strings.Split(strings.Split(strings.Split(assessment.URL, "link")[1], "form")[0], "_")[2])
  115. assessment.Category = getCategory(category, assessment.JsonPath)
  116. } else {
  117. assessment.Channel = 5
  118. assessment.Category = getCategory(11, assessment.JsonPath)
  119. }
  120. } else if strings.Contains(assessment.ReferPageURL, "link=") {
  121. split := strings.Split(assessment.ReferPageURL, "link")
  122. if strings.Contains(split[1], "form") || strings.Contains(split[1], "from") {
  123. assessment.Channel, _ = strconv.Atoi(strings.Split(strings.Split(strings.Split(assessment.ReferPageURL, "link")[1], "form")[0], "_")[1])
  124. var category, _ = strconv.Atoi(strings.Split(strings.Split(strings.Split(assessment.ReferPageURL, "link")[1], "form")[0], "_")[2])
  125. assessment.Category = getCategory(category, assessment.JsonPath)
  126. } else {
  127. assessment.Channel = 5
  128. assessment.Category = getCategory(11, assessment.JsonPath)
  129. }
  130. } else {
  131. split := strings.Split(assessment.ChatURL, "link")
  132. if strings.Contains(split[1], "form") || strings.Contains(split[1], "from") {
  133. assessment.Channel, _ = strconv.Atoi(strings.Split(strings.Split(strings.Split(assessment.ChatURL, "link")[1], "form")[0], "_")[1])
  134. var category, _ = strconv.Atoi(strings.Split(strings.Split(strings.Split(assessment.ChatURL, "link")[1], "form")[0], "_")[2])
  135. assessment.Category = getCategory(category, assessment.JsonPath)
  136. } else {
  137. assessment.Channel = 5
  138. assessment.Category = getCategory(11, assessment.JsonPath)
  139. }
  140. }
  141. }
  142. // 百度惠生活渠道合并
  143. if assessment.Category == 239 {
  144. assessment.Category = getCategory(292, assessment.JsonPath)
  145. }
  146. return ChannelCategory{assessment.Channel, assessment.Category}
  147. }
  148. // 获取神策url(包含utm)
  149. cc1, _ := redisCli().Get("sensors:" + assessment.GrUserId).Result()
  150. var utmUrl SensorsData
  151. json.Unmarshal([]byte(cc1), &utmUrl)
  152. // 神策解析
  153. if utmUrl.Url != "" && !strings.Contains(assessment.URL, "link=") && !strings.Contains(assessment.ReferPageURL, "link=") && !strings.Contains(assessment.ChatURL, "link=") {
  154. log.Printf("解析神策")
  155. assessment.Channel = utmUrl.Channel
  156. assessment.Category = utmUrl.Category
  157. // 百度惠生活渠道合并
  158. if assessment.Category == 239 {
  159. assessment.Category = getCategory(292, assessment.JsonPath)
  160. }
  161. return ChannelCategory{assessment.Channel, assessment.Category}
  162. }
  163. // 搜索引擎SEO,外链解析
  164. if assessment.ReferPageURL != "" && !strings.Contains(assessment.ReferPageURL, "https://www.jjl.cn/") && !strings.Contains(assessment.ReferPageURL, "https://m.jjl.cn/") {
  165. log.Printf("解析SEO")
  166. assessment.Channel = 5
  167. assessment.Category = getCategory(11, assessment.JsonPath)
  168. return ChannelCategory{assessment.Channel, assessment.Category}
  169. }
  170. // 官网自然访问解析
  171. if strings.Contains(assessment.URL, "https://www.jjl.cn/") || strings.Contains(assessment.URL, "https://m.jjl.cn/") ||
  172. strings.Contains(assessment.ReferPageURL, "https://www.jjl.cn/") || strings.Contains(assessment.ReferPageURL, "https://m.jjl.cn/") ||
  173. strings.Contains(assessment.ChatURL, "https://www.jjl.cn/") || strings.Contains(assessment.ChatURL, "https://m.jjl.cn/") ||
  174. strings.Contains(utmUrl.Url, "https://www.jjl.cn/") || strings.Contains(utmUrl.Url, "https://m.jjl.cn/") {
  175. log.Printf("解析官网")
  176. assessment.Channel = 7
  177. assessment.Category = getCategory(126, assessment.JsonPath)
  178. return ChannelCategory{assessment.Channel, assessment.Category}
  179. }
  180. log.Printf("默认解析为SEO")
  181. assessment.Channel = 5
  182. assessment.Category = getCategory(11, assessment.JsonPath)
  183. return ChannelCategory{assessment.Channel, assessment.Category}
  184. }
  185. // GetChatChannel 会话渠道归因处理
  186. func GetChatChannel(chat SemJsChatRecord) ChannelCategory {
  187. log.Printf("%v", chat)
  188. // 获取神策URL(不包含utm)
  189. cc, _ := redisCli().Get("website:" + chat.GrUserID).Result()
  190. var websiteUrl SensorsData
  191. json.Unmarshal([]byte(cc), &websiteUrl)
  192. // 小程序解析
  193. if strings.Contains(chat.ChatURL, "pages") && strings.Split(strings.Split(chat.ChatURL, "?")[1], "=")[0] == "miniapp" && (strings.Contains(chat.ChatURL, "baidu") || strings.Contains(chat.ChatURL, "wechat")) {
  194. log.Printf("小程序解析")
  195. log.Printf(chat.ChatURL)
  196. appType := strings.Split(strings.Split(strings.Split(chat.ChatURL, "?")[1], "=")[1], "_")[1]
  197. if appType == "baidu" {
  198. chat.ChannleID = 1
  199. chat.CategoryID = getCategory(30, chat.JsonPath)
  200. } else if appType == "wechat" {
  201. chat.ChannleID = 8
  202. chat.CategoryID = getCategory(32, chat.JsonPath)
  203. }
  204. return ChannelCategory{chat.ChannleID, chat.CategoryID}
  205. }
  206. // 到梦解析
  207. if !strings.Contains(chat.ReferPage, "utm") && !strings.Contains(chat.ChatURL, "utm") && (strings.Contains(chat.ReferPage, "daomeng") || strings.Contains(chat.ChatURL, "daomeng")) {
  208. log.Printf("到梦解析")
  209. chat.ChannleID = 38
  210. chat.CategoryID = getCategory(201, chat.JsonPath)
  211. return ChannelCategory{chat.ChannleID, chat.CategoryID}
  212. }
  213. // URL解析
  214. if strings.Contains(chat.ChatURL, "link=") || strings.Contains(chat.ReferPage, "link=") {
  215. log.Printf("解析CHATURL")
  216. if strings.Contains(chat.ChatURL, "link=") && len(strings.Split(strings.Split(chat.ChatURL, "link=")[1], "_")) == 3 {
  217. var category, _ = strconv.Atoi(strings.Split(strings.Split(chat.ChatURL, "link=")[1], "_")[1])
  218. if category > 10000 {
  219. chat.ChannleID = category
  220. chat.CategoryID = category
  221. }
  222. } else if strings.Contains(chat.ReferPage, "link=") && len(strings.Split(strings.Split(chat.ReferPage, "link=")[1], "_")) == 3 {
  223. var category, _ = strconv.Atoi(strings.Split(strings.Split(chat.ReferPage, "link=")[1], "_")[1])
  224. if category > 10000 {
  225. chat.ChannleID = category
  226. chat.CategoryID = category
  227. }
  228. } else {
  229. if strings.Contains(chat.ChatURL, "link=") {
  230. split := strings.Split(chat.ChatURL, "link=")
  231. if strings.Contains(split[1], "form") || strings.Contains(split[1], "from") {
  232. chat.ChannleID, _ = strconv.Atoi(strings.Split(strings.Split(strings.Split(chat.ChatURL, "link")[1], "form")[0], "_")[1])
  233. var category, _ = strconv.Atoi(strings.Split(strings.Split(strings.Split(chat.ChatURL, "link")[1], "form")[0], "_")[2])
  234. chat.CategoryID = getCategory(category, chat.JsonPath)
  235. } else {
  236. chat.ChannleID = 5
  237. chat.CategoryID = getCategory(11, chat.JsonPath)
  238. }
  239. } else {
  240. split := strings.Split(chat.ReferPage, "link=")
  241. if strings.Contains(split[01], "form") || strings.Contains(split[1], "from") {
  242. chat.ChannleID, _ = strconv.Atoi(strings.Split(strings.Split(strings.Split(chat.ReferPage, "link")[1], "form")[0], "_")[1])
  243. var category, _ = strconv.Atoi(strings.Split(strings.Split(strings.Split(chat.ReferPage, "link")[1], "form")[0], "_")[2])
  244. chat.CategoryID = getCategory(category, chat.JsonPath)
  245. } else {
  246. chat.ChannleID = 5
  247. chat.CategoryID = getCategory(11, chat.JsonPath)
  248. }
  249. }
  250. }
  251. // 百度惠生活渠道合并
  252. if chat.CategoryID == 239 {
  253. chat.CategoryID = getCategory(292, chat.JsonPath)
  254. }
  255. return ChannelCategory{chat.ChannleID, chat.CategoryID}
  256. }
  257. // 获取神策url(包含utm)
  258. cc1, _ := redisCli().Get("sensors:" + assessment.GrUserId).Result()
  259. var utmUrl SensorsData
  260. json.Unmarshal([]byte(cc1), &utmUrl)
  261. // 神策解析
  262. if utmUrl.Url != "" && !strings.Contains(assessment.URL, "link=") && !strings.Contains(assessment.ReferPageURL, "link=") && !strings.Contains(assessment.ChatURL, "link=") {
  263. log.Printf("解析神策")
  264. assessment.Channel = utmUrl.Channel
  265. assessment.Category = utmUrl.Category
  266. // 百度惠生活渠道合并
  267. if assessment.Category == 239 {
  268. assessment.Category = getCategory(292, assessment.JsonPath)
  269. }
  270. return ChannelCategory{assessment.Channel, assessment.Category}
  271. }
  272. // 搜索引擎SEO,外链解析
  273. if chat.ReferPage != "" && !strings.Contains(chat.ReferPage, "https://www.jjl.cn/") && !strings.Contains(chat.ReferPage, "https://m.jjl.cn/") {
  274. log.Printf("解析SEO")
  275. chat.ChannleID = 5
  276. chat.CategoryID = getCategory(11, chat.JsonPath)
  277. return ChannelCategory{chat.ChannleID, chat.CategoryID}
  278. }
  279. // 官网自然访问解析
  280. if strings.Contains(chat.ReferPage, "https://www.jjl.cn/") || strings.Contains(chat.ReferPage, "https://m.jjl.cn/") ||
  281. strings.Contains(chat.ChatURL, "https://www.jjl.cn/") || strings.Contains(chat.ChatURL, "https://m.jjl.cn/") ||
  282. strings.Contains(utmUrl.Url, "https://www.jjl.cn/") || strings.Contains(utmUrl.Url, "https://m.jjl.cn/") {
  283. log.Printf("解析官网")
  284. chat.ChannleID = 7
  285. chat.CategoryID = getCategory(126, chat.JsonPath)
  286. return ChannelCategory{chat.ChannleID, chat.CategoryID}
  287. }
  288. log.Printf("默认解析为SEO")
  289. chat.ChannleID = 5
  290. chat.CategoryID = getCategory(11, chat.JsonPath)
  291. return ChannelCategory{chat.ChannleID, chat.CategoryID}
  292. }
  293. type SensorsData struct {
  294. DistinctId string `json:"distinctID"`
  295. Channel int `json:"channel"`
  296. Category int `json:"category"`
  297. Url string `json:"url"`
  298. }
  299. type SysChannel struct {
  300. OriginalCategory string `json:"original_category"` // 主键ID
  301. CategoryId string `json:"category_id"` // 备注
  302. }
  303. func getOssCategory(OriginalCategory int) int {
  304. endpoint := "oss-cn-beijing.aliyuncs.com" // 例如 "oss-cn-hangzhou.aliyuncs.com"
  305. accessKeyID := "LTAI5t7iAtrYaUgGgK8ws54e"
  306. accessKeySecret := "j4A6llCRqZBMzXLQ7ms84LdKl9l0IS"
  307. bucketName := "jjl-prod-bucket"
  308. objectName := "channel/category_mapper.json"
  309. client, err := oss.New(endpoint, accessKeyID, accessKeySecret)
  310. if err != nil {
  311. log.Fatalf("创建OSS客户端失败: %v", err)
  312. }
  313. // 获取存储空间
  314. bucket, err := client.Bucket(bucketName)
  315. if err != nil {
  316. log.Fatalf("获取Bucket失败: %v", err)
  317. }
  318. // 获取对象
  319. body, err := bucket.GetObject(objectName)
  320. if err != nil {
  321. log.Fatalf("获取对象失败: %v", err)
  322. }
  323. defer body.Close()
  324. // 读取对象内容
  325. var channel []SysChannel
  326. decoder := json.NewDecoder(body)
  327. if err := decoder.Decode(&channel); err != nil {
  328. log.Fatalf("解析JSON失败: %v", err)
  329. }
  330. for i := range channel {
  331. ori, _ := strconv.Atoi(channel[i].OriginalCategory)
  332. if ori == OriginalCategory {
  333. category, _ := strconv.Atoi(channel[i].CategoryId)
  334. return category
  335. }
  336. }
  337. return -1
  338. }
  339. //func getCurrentPath() string {
  340. // _, filename, _, _ := runtime.Caller(1)
  341. // return path.Dir(filename)
  342. //}
  343. func getCategory(OriginalCategory int, jsonPath string) int {
  344. // 打开JSON文件
  345. jsonFile, err := os.Open(jsonPath)
  346. //jsonFile, err := os.Open("category_mapper.json")
  347. if err != nil {
  348. fmt.Println(err)
  349. return -1
  350. }
  351. defer jsonFile.Close()
  352. // 读取文件内容
  353. byteValue, err := ioutil.ReadAll(jsonFile)
  354. if err != nil {
  355. fmt.Println(err)
  356. return -1
  357. }
  358. // 解析JSON数据
  359. var channel []SysChannel
  360. if err := json.Unmarshal(byteValue, &channel); err != nil {
  361. fmt.Println(err)
  362. return -1
  363. }
  364. println(channel)
  365. for i := range channel {
  366. ori, _ := strconv.Atoi(channel[i].OriginalCategory)
  367. if ori == OriginalCategory {
  368. category, _ := strconv.Atoi(channel[i].CategoryId)
  369. return category
  370. }
  371. }
  372. return -1
  373. }