customerRule.go 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511
  1. package client
  2. import (
  3. "app.yhyue.com/moapp/jybase/common"
  4. "app.yhyue.com/moapp/jybase/encrypt"
  5. "app.yhyue.com/moapp/jybase/go-xweb/xweb"
  6. "app.yhyue.com/moapp/jybase/log"
  7. "app.yhyue.com/moapp/jybase/mongodb"
  8. "cmplatform/util"
  9. "encoding/json"
  10. "fmt"
  11. "github.com/lauyoume/gopinyin"
  12. "go.mongodb.org/mongo-driver/bson"
  13. "go.uber.org/zap"
  14. "io"
  15. "regexp"
  16. "strings"
  17. "time"
  18. )
  19. type CustomerRule struct {
  20. *xweb.Action
  21. cuserRuleCreate xweb.Mapper `xweb:"/customerRule/cuser/rule/create"` //新建规则
  22. ruleImport xweb.Mapper `xweb:"/customerRule/rule/import"` //导入关键词 导入文件excel
  23. productData xweb.Mapper `xweb:"/customerRule/cuser/produce"` //生成预览数据
  24. demoData xweb.Mapper `xweb:"/customerRule/rule/preview"` //预览数据
  25. dataTest xweb.Mapper `xweb:"/customerRule/rule/dataTest/(.*)"` //规则测试
  26. }
  27. var (
  28. replaceField_detail = map[string]bool{`"title"`: true, `"projectname.pname"`: true}
  29. reg_detail = regexp.MustCompile("\"fields\":\\[([^]]*detail[^]]*)\\]")
  30. reg_single = regexp.MustCompile("\"query\":\"[^\"{:]\"")
  31. )
  32. func (c *CustomerRule) CuserRuleCreate() {
  33. defer common.Catch()
  34. ids := strings.Split(c.GetString("ids"), ",")
  35. if c.Method() == "POST" {
  36. user := c.GetSession("user").(map[string]interface{})
  37. data := util.GetPostForm(c.Request)
  38. o_rules := []map[string]interface{}{}
  39. o_rulesStr := data["o_rules"].(string)
  40. json.Unmarshal([]byte(o_rulesStr), &o_rules)
  41. data["o_rules"] = o_rules
  42. id := common.ObjToString(data["id"])
  43. delete(data, "id")
  44. delete(data, "ids")
  45. if common.IntAll(data["i_esquerytype"]) == 1 { //自动生成es
  46. esStr := util.Utiltags(data)
  47. data["s_esquery"] = esStr
  48. data["s_esquery_search"] = filter(esStr)
  49. }
  50. i_createtime := time.Now().Unix()
  51. data["i_updatetime"] = i_createtime
  52. data["s_updateuser"] = user["name"]
  53. var rep = false
  54. if id == "" { //新建
  55. data["s_userid"] = ids[1]
  56. data["s_departid"] = ids[0]
  57. data["i_createtime"] = i_createtime
  58. data["s_createuser"] = user["name"]
  59. s_namekey := gopinyin.Convert(common.ObjToString(data["s_name"]), false)
  60. data["s_namekey"] = s_namekey
  61. data["b_delete"] = false
  62. data["s_dataid"] = encrypt.SE.EncodeString(fmt.Sprintf("%v", i_createtime) + s_namekey + ids[0])
  63. id = util.Mgo.Save("cuserdepartrule", data)
  64. if id != "" {
  65. rep = true
  66. } else {
  67. rep = false
  68. }
  69. } else {
  70. query := bson.M{
  71. "_id": mongodb.StringTOBsonId(id),
  72. }
  73. rep = util.Mgo.Update("cuserdepartrule", query, bson.M{"$set": data}, false, false)
  74. }
  75. c.ServeJson(map[string]interface{}{
  76. "id": id,
  77. "rep": rep,
  78. "s_esquery": data["s_esquery"],
  79. "s_dataid": data["s_dataid"],
  80. })
  81. } else {
  82. c.T["did"] = ids[0] //部门id
  83. c.T["cid"] = ids[1] //客户id
  84. c.T["ids"] = c.GetString("ids")
  85. c.T["province"] = util.Province
  86. c.T["city"] = util.ProvinceCitys
  87. c.T["district"] = util.CityDistricts
  88. c.T["topTypeArr"] = util.TopTypeArr
  89. c.T["subTypeArr"] = util.SubTypeArr
  90. c.T["matchTypeMap"] = util.MatchTypeMap
  91. c.T["matchTypeMap2"] = util.MatchTypeMap2
  92. c.T["existField"] = util.ExistFiled
  93. c.T["buyerClass"] = util.BuyerClass
  94. c.T["buyerClassMap"] = util.BuyerClassMap
  95. c.T["scopeClass"] = util.ScopeClassMap
  96. c.T["siteArr"] = util.SiteArr
  97. /*userId := ids[1]
  98. cuser, _ := util.Mgo.FindById("cuser", userId, `{"s_appid":1}`)
  99. appid := common.ObjToString((*cuser)["s_appid"])
  100. user, _ := MgoCus.FindOneByField("user", map[string]interface{}{"appid": appid}, `{"plan":1}`)
  101. _plan := (*user)["plan"]
  102. if _plan != nil {
  103. plan := _plan.(map[string]interface{})
  104. fieldstype := common.ObjToString(plan["name"])
  105. if strings.Contains(fieldstype, "B") || strings.Contains(fieldstype, "D") {
  106. c.T["i_extfieldstype"] = 2
  107. } else {
  108. c.T["i_extfieldstype"] = 1
  109. }
  110. }*/
  111. c.Render("client/cuser_rule_create.html", &c.T)
  112. }
  113. }
  114. func filter(sql string) string {
  115. if !checkSingleWord(sql) {
  116. replace_map := checkDetail(sql)
  117. for k, v := range replace_map {
  118. // sql = regexp.MustCompile(k).ReplaceAllString(sql, v)
  119. sql = strings.ReplaceAll(sql, k, v)
  120. }
  121. }
  122. return sql
  123. }
  124. // 匹配包含detail的组
  125. func checkDetail(sql string) (arrMap map[string]string) {
  126. arrMap = map[string]string{}
  127. res := reg_detail.FindAllStringSubmatch(sql, -1)
  128. for _, v := range res {
  129. if len(v) == 2 {
  130. if v[1] != makeReplace(v[1]) {
  131. arrMap[v[1]] = makeReplace(v[1])
  132. }
  133. }
  134. }
  135. return
  136. }
  137. // 校验是否有单字
  138. func checkSingleWord(sql string) bool {
  139. return len(reg_single.FindStringSubmatch(sql)) > 0
  140. }
  141. // 计算每组字段的替换值
  142. func makeReplace(s_match string) (s_replace string) {
  143. arr := []string{}
  144. for _, v := range strings.Split(s_match, ",") {
  145. if !replaceField_detail[v] {
  146. arr = append(arr, v)
  147. }
  148. }
  149. return strings.Join(arr, ",")
  150. }
  151. // 导入关键词
  152. func (r *CustomerRule) RuleImport() {
  153. defer common.Catch()
  154. if r.Method() == "POST" {
  155. mf, _, err := r.GetFile("xlsx")
  156. if err == nil {
  157. binary, err := io.ReadAll(mf)
  158. if err == nil {
  159. rdata, err := util.Parsxlsx(binary)
  160. if err == nil {
  161. //id, rep := updateDbXf("", rdata)
  162. //common.Debug("import data:", rdata)
  163. r.ServeJson(map[string]interface{}{
  164. "rdata": rdata,
  165. "id": "",
  166. "rep": true,
  167. })
  168. return
  169. }
  170. }
  171. }
  172. r.ServeJson(map[string]interface{}{
  173. "rep": false,
  174. })
  175. }
  176. }
  177. // 生成预览数据
  178. func (c *CustomerRule) ProductData() {
  179. defer common.Catch()
  180. if c.Method() == "POST" {
  181. rep := false
  182. id := c.GetString("id")
  183. dataType := c.GetString("dataType")
  184. user := c.GetSession("user").(map[string]interface{})
  185. userId := common.ObjToString(user["id"])
  186. tag, ok := util.Mgo.FindById("cuserdepartrule", id, `{}`)
  187. if !ok {
  188. c.ServeJson(map[string]interface{}{
  189. "rep": false,
  190. "msg": "规则获取失败",
  191. })
  192. return
  193. }
  194. s_esquery := common.ObjToString((*tag)["s_esquery"])
  195. if util.IsNewSql != 0 {
  196. s_esquery = common.ObjToString((*tag)["s_esquery_search"])
  197. }
  198. s_startTime := common.IntAll((*tag)["i_starttime"])
  199. s_endTime := common.IntAll((*tag)["i_endtime"])
  200. totalCount := 0
  201. multiMatchcount := strings.Count(s_esquery, "multi_match")
  202. termsCount := strings.Count(s_esquery, "terms")
  203. rangeCount := strings.Count(s_esquery, "range")
  204. if multiMatchcount != -1 {
  205. totalCount += multiMatchcount
  206. }
  207. if termsCount != -1 {
  208. totalCount += termsCount
  209. }
  210. if rangeCount != -1 {
  211. totalCount += rangeCount
  212. }
  213. log.Debug("multi_match", zap.Int("multiMatchcount", multiMatchcount), zap.String("s_esquery", s_esquery))
  214. if totalCount > 1000 && (s_startTime == 0 || s_endTime == 0) {
  215. c.ServeJson(map[string]interface{}{
  216. "rep": false,
  217. "msg": "查询过多,请限制开始时间及结束时间",
  218. })
  219. return
  220. }
  221. if totalCount > 8000 {
  222. c.ServeJson(map[string]interface{}{
  223. "rep": false,
  224. "msg": "查询过多,无法执行",
  225. })
  226. return
  227. }
  228. // 其他的分隔
  229. // 1000<=总个数<4000,将时间(publishtime)按照每3个月进行分割,然后查询到的数据量进行求和。
  230. // 4000<=总个数<8000,将时间(publishtime)按照每1个月进行分割,然后查询到的数据量进行求和
  231. var err error
  232. var count int64
  233. var dataTypes string
  234. // var n int
  235. // 小于1000的直接查
  236. // if totalCount < 1000 {
  237. err, dataTypes, count = util.UtilEsFind1(*tag, dataType, userId)
  238. // } else {
  239. // if totalCount >= 1000 && totalCount < 4000 {
  240. // n = 3
  241. // }
  242. // if totalCount >= 4000 && totalCount < 8000 {
  243. // n = 1
  244. // }
  245. // err, count = UtilEsFind2(*tag, n)
  246. // }
  247. var msg string
  248. if err == nil {
  249. rep = true
  250. msg = "数据生成成功"
  251. } else {
  252. rep = false
  253. msg = "数据生成失败,请稍后再试"
  254. if err.Error() == "请设置开始结束时间" {
  255. msg = "请设置开始结束时间"
  256. }
  257. }
  258. c.ServeJson(map[string]interface{}{
  259. "rep": rep,
  260. "count": count,
  261. "msg": msg,
  262. "dataType": dataTypes,
  263. })
  264. }
  265. }
  266. func (r *CustomerRule) DemoData() {
  267. defer common.Catch()
  268. if r.Method() == "POST" {
  269. sDataid := r.GetString("s_dataid")
  270. start, _ := r.GetInt("start")
  271. limit, _ := r.GetInt("length")
  272. draw, _ := r.GetInt("draw")
  273. dataType := r.GetString("dataType")
  274. index := util.InterimIndex
  275. if dataType != "1" {
  276. index = util.TotalIndex
  277. }
  278. query := bson.M{
  279. "s_dataid": sDataid,
  280. "esIndex": index,
  281. }
  282. data, _ := util.Mgo.Find("tagsdata", query, `{"publishtime":-1}`, nil, false, int(start), int(limit))
  283. count := util.Mgo.Count("tagsdata", query)
  284. for _, v := range *data {
  285. if v["budget"] != nil {
  286. v["budget"] = common.Float64All(fmt.Sprintf("%f", common.Float64All(v["budget"])/10000))
  287. }
  288. if v["bidamount"] != nil {
  289. v["bidamount"] = common.Float64All(fmt.Sprintf("%f", common.Float64All(v["bidamount"])/10000))
  290. }
  291. }
  292. r.ServeJson(map[string]interface{}{
  293. "data": data,
  294. "draw": draw,
  295. "recordsFiltered": count,
  296. "recordsTotal": count,
  297. })
  298. }
  299. }
  300. func (this *CustomerRule) DataTest(id string) {
  301. //获取数据
  302. title := this.GetString("title")
  303. detail := this.GetString("detail")
  304. fmt.Println(title, detail)
  305. if title == "" && detail == "" {
  306. this.ServeJson(map[string]interface{}{
  307. "status": false,
  308. "data": "",
  309. "message": "标题和正文至少要有一个",
  310. })
  311. return
  312. }
  313. article := map[string]interface{}{
  314. "title": title,
  315. "detail": detail,
  316. }
  317. log.Debug("测试数据是否匹配开始...")
  318. //加载一个客户
  319. customer, _ := util.Mgo.Find("cuserdepartrule", map[string]interface{}{"_id": mongodb.StringTOBsonId(id)}, nil, nil, false, -1, -1)
  320. if len(*customer) == 1 {
  321. c := (*customer)[0]
  322. s_globaladdkey := common.ObjToString(c["s_globaladdkey"])
  323. s_globaladdkeymatch := common.ObjToString(c["s_globaladdkeymatch"])
  324. s_globalnotkey := common.ObjToString(c["s_globalnotkey"])
  325. s_globalnotkeymatch := common.ObjToString(c["s_globalnotkeymatch"])
  326. s_globalclearkey := common.ObjToString(c["s_globalclearkey"])
  327. s_globalclearkeymatch := common.ObjToString(c["s_globalclearkeymatch"])
  328. //清理词匹配方式
  329. cwmArr := []string{}
  330. for _, mv := range strings.Split(s_globalclearkeymatch, ",") {
  331. if field := common.ObjToString(MatchType[mv]); field != "" {
  332. cwmArr = append(cwmArr, field)
  333. }
  334. }
  335. //清理词正则
  336. cwkArr := []*regexp.Regexp{}
  337. for _, kv := range strings.Split(s_globalclearkey, ",") {
  338. if LetterCase.MatchString(kv) { //字母转大写
  339. kv = strings.ToUpper(kv)
  340. }
  341. reg := regexp.MustCompile(kv)
  342. cwkArr = append(cwkArr, reg)
  343. }
  344. //清理清理词
  345. for _, cwm := range cwmArr {
  346. if text := common.ObjToString(article[cwm]); text != "" {
  347. for _, gcw_reg := range cwkArr {
  348. text = gcw_reg.ReplaceAllString(text, "")
  349. }
  350. article[cwm] = text
  351. }
  352. }
  353. o_rule, ok := c["o_rules"].([]interface{})
  354. if !ok {
  355. o_rule = []interface{}{}
  356. }
  357. o_rules := common.ObjArrToMapArr(o_rule)
  358. matchKey := ""
  359. if s_globaladdkey != "" {
  360. gKey := TestMactchKeys(s_globaladdkeymatch, s_globaladdkey, article)
  361. if gKey == "" {
  362. this.ServeJson(map[string]interface{}{
  363. "status": true,
  364. "data": map[string]interface{}{
  365. "result": false,
  366. "info": "全局附加词没有匹配成功",
  367. "data": s_globaladdkey,
  368. },
  369. "message": "测试成功",
  370. })
  371. return
  372. } else {
  373. matchKey = gKey
  374. }
  375. }
  376. if s_globalnotkey != "" {
  377. gNKey := TestMactchKeys(s_globalnotkeymatch, s_globalnotkey, article)
  378. if gNKey != "" {
  379. this.ServeJson(map[string]interface{}{
  380. "status": true,
  381. "data": map[string]interface{}{
  382. "result": false,
  383. "info": "被全局排除词排除",
  384. "data": gNKey,
  385. },
  386. "message": "测试成功",
  387. })
  388. return
  389. }
  390. }
  391. var resultList []interface{}
  392. for _, v := range o_rules {
  393. matchKey = ""
  394. key := common.ObjToString(v["s_matchkey"])
  395. keymatch := common.ObjToString(v["s_keymatch"])
  396. addkey := common.ObjToString(v["s_addkey"])
  397. addkeymatch := common.ObjToString(v["s_addkeymatch"])
  398. notkey := common.ObjToString(v["s_notkey"])
  399. notkeymatch := common.ObjToString(v["s_notkeymatch"])
  400. var tempData = map[string]interface{}{
  401. "key": key,
  402. "keymatch": keymatch,
  403. "addkey": addkey,
  404. "addkeymatch": addkeymatch,
  405. "notkey": notkey,
  406. "notkeymatch": notkeymatch,
  407. }
  408. if notkey != "" {
  409. nKey := TestMactchKeys(notkeymatch, notkey, article)
  410. if nKey != "" {
  411. tempData["status"] = false
  412. tempData["info"] = "排除词排除"
  413. tempData["data"] = nKey
  414. resultList = append(resultList, tempData)
  415. continue
  416. }
  417. }
  418. if key != "" {
  419. sKey := TestMactchKeys(keymatch, key, article)
  420. aKey := ""
  421. if addkey != "" {
  422. aKey = TestMactchKeys(addkeymatch, addkey, article)
  423. if aKey != "" && sKey != "" {
  424. matchKey = aKey + "," + sKey
  425. tempData["status"] = true
  426. tempData["info"] = "匹配成功"
  427. tempData["data"] = matchKey
  428. resultList = append(resultList, tempData)
  429. } else if aKey == "" {
  430. tempData["status"] = false
  431. tempData["info"] = "附加词匹配失败"
  432. tempData["data"] = ""
  433. resultList = append(resultList, tempData)
  434. } else if sKey == "" {
  435. tempData["status"] = false
  436. tempData["info"] = "关键词匹配失败"
  437. tempData["data"] = ""
  438. resultList = append(resultList, tempData)
  439. }
  440. } else {
  441. if sKey != "" {
  442. matchKey = sKey
  443. tempData["status"] = true
  444. tempData["info"] = "匹配成功"
  445. tempData["data"] = matchKey
  446. resultList = append(resultList, tempData)
  447. } else {
  448. matchKey = sKey
  449. tempData["status"] = false
  450. tempData["info"] = "关键词匹配失败"
  451. tempData["data"] = matchKey
  452. resultList = append(resultList, tempData)
  453. }
  454. }
  455. }
  456. }
  457. if resultList == nil {
  458. this.ServeJson(map[string]interface{}{
  459. "status": true,
  460. "data": map[string]interface{}{
  461. "result": true,
  462. "info": "全局附加词匹配成功" + matchKey,
  463. "data": "",
  464. },
  465. "message": "测试成功",
  466. })
  467. return
  468. } else {
  469. this.ServeJson(map[string]interface{}{
  470. "status": true,
  471. "data": resultList,
  472. "message": "测试成功",
  473. })
  474. }
  475. return
  476. } else {
  477. this.ServeJson(map[string]interface{}{
  478. "status": true,
  479. "data": "",
  480. "message": "初始化客户信息失败",
  481. })
  482. return
  483. }
  484. log.Debug("测试数据是否匹配结束...")
  485. }