purchase.go 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681
  1. package service
  2. import (
  3. MC "app.yhyue.com/moapp/jybase/common"
  4. "app.yhyue.com/moapp/jybase/date"
  5. "app.yhyue.com/moapp/jybase/encrypt"
  6. elastic "app.yhyue.com/moapp/jybase/es"
  7. "app.yhyue.com/moapp/jybase/redis"
  8. "app.yhyue.com/moapp/jypkg/common/src/qfw/util/jy"
  9. "bp.jydev.jianyu360.cn/BaseService/jyMicroservices/jyBXCore/entity"
  10. IC "bp.jydev.jianyu360.cn/BaseService/jyMicroservices/jyBXCore/rpc/init"
  11. "bp.jydev.jianyu360.cn/BaseService/jyMicroservices/jyBXCore/rpc/model/es"
  12. "bp.jydev.jianyu360.cn/BaseService/jyMicroservices/jyBXCore/rpc/type/bxcore"
  13. "bp.jydev.jianyu360.cn/BaseService/jyMicroservices/jyBXCore/rpc/util"
  14. "encoding/json"
  15. "fmt"
  16. "github.com/zeromicro/go-zero/core/logx"
  17. "log"
  18. "strconv"
  19. "strings"
  20. "time"
  21. )
  22. type Purchase struct {
  23. AppId string ` json:"appId,omitempty"` //剑鱼默认10000
  24. UserId string ` json:"userId,omitempty"` //用户id
  25. Phone string ` json:"phone,omitempty"` //手机号
  26. BaseUserId int64 ` json:"baseUserId,omitempty"` //base_user_id 新用户id
  27. EntId int64 ` json:"entId,omitempty"` //企业id 没有企业 企业id=0
  28. EntUserId int64 ` json:"entUserId,omitempty"` //企业用户id 当前企业下的员工id 没有企业默认0
  29. AccountId int64 ` json:"accountId,omitempty"` //账户id
  30. EntAccountId int64 ` json:"entAccountId,omitempty"` //企业账户id
  31. PositionType int64 ` json:"positionType,omitempty"` //职位类型 0个人 1企业
  32. PositionId int64 ` json:"positionId,omitempty"` //职位id
  33. MgoUserId string ` json:"mgoUserId,omitempty"` //原userId
  34. PageNum int64 ` json:"pageNum,omitempty"` //当前页码
  35. PageSize int64 ` json:"pageSize,omitempty"` //每页数量
  36. PublishTime string ` json:"publishTime,omitempty"` //发布时间
  37. SelectType string ` json:"selectType,omitempty"` //搜索范围:
  38. DomainFirstType string ` json:"domainFirstType,omitempty"` //领域 一级
  39. DomainSecondType string ` json:"domainSecondType,omitempty"` //领域 二级
  40. DomainThirdType string ` json:"domainThirdType,omitempty"` //领域 三级
  41. DeadlineStatus int64 ` json:"deadlineStatus,omitempty"` //报名截止状态
  42. DeadlineTime string ` json:"deadlineTime,omitempty"` //报名截止时间
  43. DeadlineStart int64 ` json:"deadlineStart,omitempty"` //报名截止时间-开始
  44. DeadlineEnd int64 ` json:"deadlineEnd,omitempty"` //报名截止时间-结束
  45. DeliveryArea string ` json:"deliveryArea,omitempty"` //交付地点-省份
  46. DeliveryCity string ` json:"deliveryCity,omitempty"` //交付地点-城市
  47. DeliveryDistrict string ` json:"deliveryDistrict,omitempty"` //交付地点-县区
  48. ProjectArea string ` json:"projectArea,omitempty"` //项目地区-省份
  49. ProjectCity string ` json:"projectCity,omitempty"` //项目地区-城市
  50. ProjectDistrict string ` json:"projectDistrict,omitempty"` //项目地区-县区
  51. Industry string ` json:"industry,omitempty"` //行业
  52. FileExists int64 ` json:"fileExists,omitempty"` //是否有附件
  53. Publisher int64 ` json:"publisher,omitempty"` //发布者:可选:全部、用户发布:1、平台发布:2。
  54. KeyWords string ` json:"keyWords,omitempty"` //关键词:多个空格隔开(主)
  55. AdditionalWords string ` json:"additionalWords,omitempty"` //关键词:附加关键词(副:五组,每组最多15个字符)
  56. SearchMode int64 ` json:"searchMode,omitempty"` //搜索模式:0:精准搜索;1:模糊搜索
  57. WordsMode int64 ` json:"wordsMode,omitempty"` //搜索关键词模式;默认0:包含所有,1:包含任意
  58. UserAgent string ` json:"userAgent,omitempty"` //请求头信息
  59. Platform string ` json:"platform,omitempty"` //请求平台
  60. TipMsg string `json:"tipMsg"` //关键词提示信息
  61. HighlightWords string `json:"highlightWords"` //需要高亮的词,多个,号分割
  62. Total int64 `json:"total"` //数据总量
  63. IsPay bool `json:"isPay"` //是否是付费用户
  64. IsPower bool `json:"isPower"` //是否有权限
  65. }
  66. func NewPurchase(in *bxcore.PurchaseReq) *Purchase {
  67. baseUserId, _ := strconv.ParseInt(in.NewUserId, 10, 64)
  68. accountId, _ := strconv.ParseInt(in.AccountId, 10, 64)
  69. positionId, _ := strconv.ParseInt(in.PositionId, 10, 64)
  70. return &Purchase{
  71. AppId: in.AppId,
  72. UserId: in.UserId,
  73. Phone: in.Phone,
  74. BaseUserId: baseUserId,
  75. EntId: in.EntId,
  76. EntUserId: in.EntUserId,
  77. AccountId: accountId,
  78. EntAccountId: in.EntAccountId,
  79. PositionType: in.PositionType,
  80. PositionId: positionId,
  81. MgoUserId: in.MgoUserId,
  82. PageNum: in.PageNum,
  83. PageSize: in.PageSize,
  84. PublishTime: in.PublishTime,
  85. SelectType: in.SelectType,
  86. DomainFirstType: in.DomainFirstType,
  87. DomainSecondType: in.DomainSecondType,
  88. DomainThirdType: in.DomainThirdType,
  89. DeadlineStatus: in.DeadlineStatus,
  90. DeadlineTime: in.DeadlineTime,
  91. DeliveryArea: in.DeliveryArea,
  92. DeliveryCity: in.DeliveryCity,
  93. DeliveryDistrict: in.DeliveryDistrict,
  94. ProjectArea: in.ProjectArea,
  95. ProjectCity: in.ProjectCity,
  96. ProjectDistrict: in.ProjectDistrict,
  97. Industry: in.Industry,
  98. FileExists: in.FileExists,
  99. Publisher: in.Publisher,
  100. KeyWords: in.KeyWords,
  101. AdditionalWords: in.AdditionalWords,
  102. SearchMode: in.SearchMode,
  103. WordsMode: in.WordsMode,
  104. UserAgent: in.UserAgent,
  105. Platform: in.Platform,
  106. }
  107. }
  108. var (
  109. AreaLabelLink = "/list/%s/%s.html"
  110. noPower = "点击查看"
  111. )
  112. // 缓存
  113. func (p *Purchase) HistoryKeywords() {
  114. var (
  115. cacheKey = fmt.Sprintf("history_purchase_v_%s", p.UserId)
  116. keys []string
  117. code = "other"
  118. isExist = map[string]bool{}
  119. duplicateRemoval = func(values []string) (keys []string) {
  120. for _, kv := range values {
  121. kv = strings.TrimSpace(kv)
  122. if isExist[kv] {
  123. continue
  124. }
  125. isExist[kv] = true
  126. keys = append(keys, kv)
  127. }
  128. return
  129. }
  130. )
  131. values := redis.GetStr(code, cacheKey)
  132. if values != "" {
  133. keys = append(keys, duplicateRemoval(strings.Split(values, ","))...)
  134. }
  135. if p.KeyWords != "" {
  136. keys = append(keys, duplicateRemoval(strings.Split(p.KeyWords, ","))...)
  137. }
  138. if p.AdditionalWords != "" {
  139. keys = append(keys, duplicateRemoval(strings.Split(p.AdditionalWords, ","))...)
  140. }
  141. if len(keys) > 10 {
  142. keys = keys[len(keys)-10:]
  143. }
  144. ok := redis.Put(code, cacheKey, strings.Join(keys, ","), -1)
  145. if !ok {
  146. logx.Info(" history keywords err:", keys)
  147. }
  148. }
  149. // 格式化
  150. func (p *Purchase) PurchaseListFormat(res []map[string]interface{}) (list []*bxcore.PurchaseList) {
  151. for _, rv := range res {
  152. logx.Info("title:", MC.InterfaceToStr(rv["title"]))
  153. id := MC.InterfaceToStr(rv["_id"])
  154. area := MC.InterfaceToStr(rv["area"])
  155. city := MC.InterfaceToStr(rv["city"])
  156. district := MC.InterfaceToStr(rv["district"])
  157. regionUrl := ""
  158. if district != "" && IC.DistrictMap[district] != "" {
  159. regionUrl = fmt.Sprintf(AreaLabelLink, "city", IC.DistrictMap[district])
  160. } else if city != "" && IC.CityMap[city] != "" {
  161. regionUrl = fmt.Sprintf(AreaLabelLink, "city", IC.CityMap[city])
  162. } else if area != "" && IC.AreaMap[area] != "" {
  163. regionUrl = fmt.Sprintf(AreaLabelLink, "area", IC.AreaMap[area])
  164. }
  165. var price int64
  166. if budget, ok := rv["budget"].(float64); ok && budget > 0 { //预算
  167. price = int64(budget)
  168. }
  169. if bidAmount, ok := rv["bidamount"].(float64); ok && bidAmount > 0 { //中标金额
  170. price = int64(bidAmount)
  171. }
  172. signEndTime := "" //报名截止时间
  173. if set := MC.Int64All(rv["signendtime"]); set > 0 {
  174. signEndTime = date.FormatDateByInt64(&set, "2006-01-02 15:04")
  175. }
  176. //deliver_area 交付省份//deliver_city 交付城市//deliver_district 交付区县
  177. deliveryLoc := fmt.Sprintf("%s-%s-%s", MC.InterfaceToStr(rv["deliver_area"]), MC.InterfaceToStr(rv["deliver_city"]), MC.InterfaceToStr(rv["deliver_district"]))
  178. buyer := noPower
  179. buyerTel := noPower
  180. if p.IsPower {
  181. buyer = MC.InterfaceToStr(rv["buyer"])
  182. buyerTel = MC.InterfaceToStr(rv["buyertel"])
  183. }
  184. isValidFile, _ := rv["isValidFile"].(bool)
  185. buyerPerson := MC.InterfaceToStr(rv["buyerperson"])
  186. agency := MC.InterfaceToStr(rv["agency"])
  187. agencyTel := MC.InterfaceToStr(rv["agencytel"])
  188. agencyPerson := MC.InterfaceToStr(rv["agencyperson"])
  189. //s_winner := MC.InterfaceToStr(rv["s_winner"])
  190. //winnertel := MC.InterfaceToStr(rv["winnertel"])
  191. //winnerperson := MC.InterfaceToStr(rv["winnerperson"])
  192. //entidlist := MC.InterfaceToStr(rv["entidlist"])
  193. //projectinfo := MC.InterfaceToStr(rv["projectinfo"])
  194. //中标信息
  195. var winnerInfo []*bxcore.WinnerInfo
  196. winnerList := MC.ObjToString(rv["s_winner"]) //中标企业名称集合
  197. if winnerList != "" && len(strings.Split(winnerList, ",")) > 0 {
  198. for wk, wv := range strings.Split(winnerList, ",") {
  199. var (
  200. winnerId = ""
  201. )
  202. if rv["entidlist"] != nil {
  203. if entIdList := MC.ObjArrToStringArr(rv["entidlist"].([]interface{})); len(entIdList) > wk { //中标企业id集合
  204. winnerId = entIdList[wk]
  205. }
  206. }
  207. if IC.C.SearchWinner.Switch && winnerId == "" {
  208. continue
  209. }
  210. if entity.RegWinner.MatchString(wv) {
  211. continue
  212. }
  213. winnerInfo = append(winnerInfo, &bxcore.WinnerInfo{
  214. Winner: wv, //中标企业 需要单独处理
  215. WinnerTel: MC.ObjToString(rv["winnertel"]), //中标企业联系电话
  216. WinnerPerson: MC.ObjToString(rv["winnerperson"]), //中标企业联系人
  217. WinnerId: MC.If(winnerId != "" && len([]rune(winnerId)) > 12, encrypt.EncodeArticleId2ByCheck(winnerId), "").(string), //中标企业加密id 存在winnerId 异常的情况
  218. })
  219. }
  220. }
  221. list = append(list, &bxcore.PurchaseList{
  222. Id: encrypt.EncodeArticleId2ByCheck(id),
  223. Area: MC.InterfaceToStr(rv["area"]),
  224. City: MC.InterfaceToStr(rv["city"]),
  225. District: MC.InterfaceToStr(rv["district"]),
  226. RegionUrl: regionUrl,
  227. BuyerClass: MC.InterfaceToStr(rv["buyerclass"]),
  228. PublishTime: MC.Int64All(rv["publishtime"]),
  229. FileExists: isValidFile,
  230. Title: MC.InterfaceToStr(rv["title"]),
  231. Price: price,
  232. Buyer: buyer,
  233. BuyerTel: buyerTel,
  234. DeadlineTime: signEndTime,
  235. DeliveryLoc: deliveryLoc,
  236. Industry: util.IndustryFormat(p.Industry, strings.Trim(MC.ObjToString(rv["s_subscopeclass"]), ",")),
  237. BuyerPerson: buyerPerson,
  238. Agency: agency,
  239. AgencyTel: agencyTel,
  240. AgencyPerson: agencyPerson,
  241. WinnerInfo: winnerInfo,
  242. BidEndTime: MC.Int64All(rv["bidendtime"]),
  243. BidOpenTime: MC.Int64All(rv["bidopentime"]), //开标时间,
  244. })
  245. }
  246. return
  247. }
  248. func (p *Purchase) PurchaseQuery() (query string) {
  249. var (
  250. wordsMusts, wordsShould, must, mustNot []string
  251. selectTypeArr = strings.Split(p.SelectType, ",")
  252. selectType = fmt.Sprintf(`"%s"`, strings.Join(selectTypeArr, "\",\""))
  253. )
  254. //发布时间
  255. if len(strings.Split(p.PublishTime, "-")) > 1 {
  256. var (
  257. timeQuery string
  258. startTime, endTime = strings.Split(p.PublishTime, "-")[0], strings.Split(p.PublishTime, "-")[1]
  259. )
  260. if startTime != "" || endTime != "" {
  261. timeQuery += `{"range":{"publishtime":{`
  262. if startTime != "" {
  263. timeQuery += `"gte":` + startTime
  264. }
  265. if startTime != "" && endTime != "" {
  266. timeQuery += `,`
  267. }
  268. if endTime != "" {
  269. timeQuery += `"lt":` + endTime
  270. }
  271. timeQuery += `}}}`
  272. }
  273. if timeQuery != "" {
  274. must = append(must, timeQuery)
  275. }
  276. }
  277. // 关键词
  278. if p.KeyWords != "" {
  279. var (
  280. keyWordsMusts []string
  281. )
  282. for _, v := range strings.Split(p.KeyWords, IC.C.JYKeyMark) {
  283. if elastic.ReplaceYH(v) == "" {
  284. continue
  285. }
  286. keyWordsMusts = append(keyWordsMusts, fmt.Sprintf(fmt.Sprintf(es.MultiMatch, "%s", selectType), elastic.ReplaceYH(v)))
  287. }
  288. //搜索关键词模式;默认0:包含所有,1:包含任意
  289. if p.WordsMode == 1 {
  290. wordsShould = append(wordsShould, fmt.Sprintf(elastic.NgramMust, strings.Join(keyWordsMusts, ",")))
  291. } else {
  292. wordsMusts = append(wordsMusts, keyWordsMusts...)
  293. }
  294. }
  295. //附加词
  296. if p.AdditionalWords != "" {
  297. for _, aws := range strings.Split(p.AdditionalWords, ",") {
  298. //多组附加词,每组间,号隔开。每组内如果关键词中间有空格,自动分词
  299. var (
  300. addWordsMusts []string
  301. )
  302. for _, v := range strings.Split(aws, IC.C.JYKeyMark) {
  303. if elastic.ReplaceYH(v) == "" {
  304. continue
  305. }
  306. addWordsStr := fmt.Sprintf(fmt.Sprintf(es.MultiMatch, "%s", selectType), elastic.ReplaceYH(v))
  307. if p.WordsMode == 0 {
  308. wordsMusts = append(wordsMusts, addWordsStr)
  309. } else {
  310. addWordsMusts = append(addWordsMusts, addWordsStr)
  311. }
  312. }
  313. //搜索关键词模式;默认0:包含所有,1:包含任意
  314. if len(addWordsMusts) > 0 {
  315. wordsShould = append(wordsShould, fmt.Sprintf(elastic.NgramMust, strings.Join(addWordsMusts, ",")))
  316. }
  317. }
  318. }
  319. //搜索关键词模式;默认0:包含所有,1:包含任意
  320. //包含任意一组
  321. if len(wordsShould) > 0 {
  322. must = append(must, fmt.Sprintf(es.QueryBoolShould, strings.Join(wordsShould, ",")))
  323. } else if len(wordsMusts) > 0 {
  324. must = append(must, fmt.Sprintf(elastic.NgramMust, strings.Join(wordsMusts, ",")))
  325. }
  326. //行业
  327. if p.Industry != "" {
  328. must = append(must, fmt.Sprintf(es.QueryBoolMustA, "s_subscopeclass", `"`+strings.ReplaceAll(p.Industry, ",", `","`)+`"`))
  329. }
  330. //附件
  331. if p.FileExists != 0 {
  332. switch p.FileExists {
  333. case 1: //有附件
  334. must = append(must, fmt.Sprintf(es.QueryBoolMustTermBool, "isValidFile", true))
  335. case -1: //无附件
  336. mustNot = append(mustNot, fmt.Sprintf(es.QueryBoolMustTermBool, "isValidFile", true))
  337. }
  338. }
  339. //项目地区
  340. var (
  341. areaQuery []string
  342. areaTerms = `{"terms":{"%s":["%s"]}}`
  343. )
  344. if p.ProjectArea != "" {
  345. areaQuery = append(areaQuery, fmt.Sprintf(areaTerms, "area", strings.ReplaceAll(p.ProjectArea, ",", "\",\"")))
  346. }
  347. if p.ProjectCity != "" {
  348. areaQuery = append(areaQuery, fmt.Sprintf(areaTerms, "city", strings.ReplaceAll(p.ProjectCity, ",", "\",\"")))
  349. }
  350. if p.ProjectDistrict != "" {
  351. for _, v := range strings.Split(p.ProjectDistrict, ",") {
  352. if len(strings.Split(v, "_")) > 1 {
  353. cityName := strings.Split(v, "_")[0]
  354. districtName := strings.Split(v, "_")[1]
  355. queryBoolMustAndDistrict := `{"bool":{"must":[{"terms":{"city":["%s"]}},{"terms":{"district":["%s"]}}]}}`
  356. areaQuery = append(areaQuery, fmt.Sprintf(queryBoolMustAndDistrict, cityName, districtName))
  357. }
  358. }
  359. }
  360. if len(areaQuery) > 0 {
  361. must = append(must, fmt.Sprintf(es.QueryBoolShould, strings.Join(areaQuery, ",")))
  362. }
  363. //交付地点
  364. areaQuery = []string{}
  365. if p.DeliveryArea != "" {
  366. areaQuery = append(areaQuery, fmt.Sprintf(areaTerms, "deliver_area", strings.ReplaceAll(p.DeliveryArea, ",", "\",\"")))
  367. }
  368. if p.DeliveryCity != "" {
  369. areaQuery = append(areaQuery, fmt.Sprintf(areaTerms, "deliver_city", strings.ReplaceAll(p.DeliveryCity, ",", "\",\"")))
  370. }
  371. if p.DeliveryDistrict != "" {
  372. for _, v := range strings.Split(p.DeliveryDistrict, ",") {
  373. if len(strings.Split(v, "_")) > 1 {
  374. cityName := strings.Split(v, "_")[0]
  375. districtName := strings.Split(v, "_")[1]
  376. queryBoolMustAndDistrict := `{"bool":{"must":[{"terms":{"deliver_city":["%s"]}},{"terms":{"deliver_district":["%s"]}}]}}`
  377. areaQuery = append(areaQuery, fmt.Sprintf(queryBoolMustAndDistrict, cityName, districtName))
  378. }
  379. }
  380. }
  381. if len(areaQuery) > 0 {
  382. must = append(must, fmt.Sprintf(es.QueryBoolShould, strings.Join(areaQuery, ",")))
  383. }
  384. //发布方式
  385. if p.Publisher > 0 {
  386. must = append(must, fmt.Sprintf(es.QueryBoolMustTerm, "public_type", fmt.Sprintf("%d", p.Publisher)))
  387. }
  388. //截止时间
  389. if p.DeadlineStart > 0 || p.DeadlineEnd > 0 {
  390. var timeQuery string
  391. timeQuery += `{"range":{"signendtime":{`
  392. if p.DeadlineStart > 0 {
  393. timeQuery += fmt.Sprintf(`"gte":%d`, p.DeadlineStart)
  394. }
  395. if p.DeadlineStart > 0 && p.DeadlineEnd > 0 {
  396. timeQuery += `,`
  397. }
  398. if p.DeadlineEnd > 0 {
  399. timeQuery += fmt.Sprintf(`"lt":%d`, p.DeadlineEnd)
  400. }
  401. timeQuery += `}}}`
  402. must = append(must, timeQuery)
  403. }
  404. //领域
  405. areaQuery = []string{}
  406. if p.DomainFirstType != "" {
  407. areaQuery = append(areaQuery, fmt.Sprintf(areaTerms, "domain_firsttype", strings.ReplaceAll(p.DomainFirstType, ",", "\",\"")))
  408. }
  409. if p.DomainSecondType != "" {
  410. areaQuery = append(areaQuery, fmt.Sprintf(areaTerms, "domain_secondtype", strings.ReplaceAll(p.DomainSecondType, ",", "\",\"")))
  411. }
  412. if p.DomainThirdType != "" {
  413. areaQuery = append(areaQuery, fmt.Sprintf(areaTerms, "domain_thirdtype", strings.ReplaceAll(p.DomainThirdType, ",", "\",\"")))
  414. }
  415. if len(areaQuery) > 0 {
  416. must = append(must, fmt.Sprintf(es.QueryBoolShould, strings.Join(areaQuery, ",")))
  417. }
  418. //直采 采购信息 搜索
  419. query = fmt.Sprintf(es.Query, strings.Join(must, ","), strings.Join(mustNot, ","))
  420. log.Println("zc-query:", query)
  421. return
  422. }
  423. func (p *Purchase) FindDataFromES() (int64, []map[string]interface{}, error) {
  424. var (
  425. start = int((p.PageNum - 1) * p.PageSize)
  426. total int64
  427. list *[]map[string]interface{}
  428. err error
  429. fields = es.PurchaseBaseFieldForPayer
  430. )
  431. biddingSearch := es.SearchByES{
  432. Index: es.PurchaseIndex,
  433. IType: es.PurchaseType,
  434. Query: p.PurchaseQuery(),
  435. FindFields: p.SelectType,
  436. Order: es.PurchaseSearchSort,
  437. Fields: fields,
  438. Start: start,
  439. Limit: int(p.PageSize),
  440. Count: 0, //高亮正文数量
  441. HighLight: false, //是否高亮正文
  442. }
  443. total, list = biddingSearch.GetAllByNgramWithCount(es.LoginTypePay)
  444. fmt.Println(total, "-------------------", list)
  445. p.Total = total
  446. total = int64(util.SearchPageSize * util.SearchMaxPageNum)
  447. if p.Total > total {
  448. p.Total = total
  449. }
  450. if total == 0 || list == nil {
  451. return 0, nil, fmt.Errorf("暂无数据")
  452. }
  453. return total, *list, err
  454. }
  455. var (
  456. redisCode = "newother"
  457. purchaseCacheKey = "purchase_cache_data"
  458. purchaseCacheExpire = 4 * 60 * 60
  459. )
  460. func (p *Purchase) GetPurchaseData() (list []*bxcore.PurchaseList, err error) {
  461. var (
  462. res []map[string]interface{}
  463. total int64
  464. )
  465. if p.IsEmptySearch() {
  466. //查缓存
  467. cacheBytes, err := redis.GetBytes(redisCode, purchaseCacheKey)
  468. start := int((p.PageNum - 1) * p.PageSize)
  469. pageSize := p.PageSize
  470. if err == nil && len(*cacheBytes) > start {
  471. end := int(p.PageNum * p.PageSize)
  472. if end > len(*cacheBytes) {
  473. end = len(*cacheBytes)
  474. }
  475. err = json.Unmarshal((*cacheBytes)[start:end], res)
  476. }
  477. if len(res) == 0 {
  478. p.PageNum = 1
  479. p.PageSize = int64(util.SearchPageSize * util.SearchMaxPageNum)
  480. total, res, err = p.FindDataFromES()
  481. log.Println(total, "----------缓存数据:", len(res))
  482. if total > 0 && res != nil {
  483. var b []byte
  484. b, err = json.Marshal(res)
  485. log.Println(b, "----------------002---------------------", err)
  486. if err == nil && len(b) > 0 {
  487. err = redis.PutBytes(redisCode, purchaseCacheKey, &b, purchaseCacheExpire)
  488. }
  489. }
  490. }
  491. res = (res)[start:pageSize]
  492. } else {
  493. //实时查询
  494. _, res, err = p.FindDataFromES()
  495. }
  496. if len(res) > 0 {
  497. list = p.PurchaseListFormat(res)
  498. }
  499. return
  500. }
  501. // 关键词 附加词 行业
  502. func (p *Purchase) IsEmptySearch() bool {
  503. if p.KeyWords != "" || p.AdditionalWords != "" || p.Industry != "" {
  504. return false
  505. }
  506. return true
  507. }
  508. var (
  509. purchaseSelectTypeMap = map[string]bool{
  510. "title": true,
  511. "purchasing": true,
  512. }
  513. tipMsg = "“%s“及其后面的字词均被忽略,因为剑鱼标讯的查询限制在%d个汉字以内。"
  514. )
  515. // 筛选条件格式化
  516. func (p *Purchase) FilterCriteriaFormat() {
  517. if p.UserId != "" {
  518. //判断用户身份
  519. userInfo := IC.Middleground.PowerCheckCenter.Check(p.AppId, p.MgoUserId, p.BaseUserId, p.AccountId, p.EntId, p.PositionType, p.PositionId)
  520. if userInfo != nil {
  521. p.IsPay = !userInfo.Free.IsFree
  522. }
  523. res := IC.Middleground.ResourceCenter.Haspowers(p.AccountId, p.EntAccountId, p.EntId, p.EntUserId)
  524. if res != nil {
  525. p.IsPower = strings.Contains(strings.Join(res.Powers, ","), IC.C.PurchaseCode)
  526. }
  527. }
  528. //搜索范围
  529. if p.SelectType != "" {
  530. var selectTypes []string
  531. for _, sv := range strings.Split(p.SelectType, ",") {
  532. if purchaseSelectTypeMap[sv] {
  533. selectTypes = append(selectTypes, sv)
  534. }
  535. }
  536. if len(selectTypes) > 0 {
  537. p.SelectType = strings.Join(selectTypes, ",")
  538. }
  539. }
  540. if p.SelectType == "" {
  541. p.SelectType = "title"
  542. }
  543. // p.SearchMode 搜索模式:0:精准搜索;1:模糊搜索
  544. // 精准搜索:不分词,完全匹配;(中间带空格的关键词组自动分词)
  545. // 模糊搜索:对用户输入的单个关键词进行分词处理,但必须都存在;
  546. if p.SearchMode < 0 || p.SearchMode > 1 {
  547. p.SearchMode = 0
  548. }
  549. // p.WordsMode 搜索关键词模式;默认0:包含所有,1:包含任意
  550. if p.WordsMode < 0 || p.WordsMode > 1 {
  551. p.WordsMode = 0
  552. }
  553. //发布时间--默认最近一年
  554. if p.PublishTime == "" {
  555. p.PublishTime = fmt.Sprintf("%d-%d", time.Now().AddDate(-1, 0, 0).Unix(), time.Now().Unix())
  556. }
  557. //默认每页数据量
  558. if p.PageSize <= 0 || p.PageSize > 100 {
  559. p.PageSize = 50
  560. }
  561. //第一页
  562. if p.PageNum <= 0 || p.PageNum > int64(IC.C.DefaultBidInfo.Count)/p.PageSize {
  563. p.PageNum = 1
  564. }
  565. //行业
  566. if p.Industry != "" {
  567. p.Industry = strings.TrimSpace(p.Industry)
  568. //P510 行业:其它
  569. if qt := jy.IndustryHandle(p.Industry); len(qt) > 0 {
  570. p.Industry = fmt.Sprintf("%s,%s", p.Industry, strings.Join(qt, ","))
  571. }
  572. }
  573. var (
  574. searchWords []string
  575. )
  576. //关键词
  577. if p.KeyWords != "" {
  578. p.KeyWords = strings.TrimSpace(p.KeyWords)
  579. _, p.TipMsg, p.KeyWords = util.InterceptSearchKW(p.KeyWords, MC.IntAllDef(IC.C.KeywordsLimit, 35), true)
  580. if p.TipMsg != "" {
  581. p.TipMsg = fmt.Sprintf(tipMsg, p.TipMsg, MC.IntAllDef(IC.C.KeywordsLimit, 35))
  582. }
  583. // in.SearchMode 搜索模式:0:精准搜索;1:模糊搜索
  584. // 精准搜索:不分词,完全匹配;(中间带空格的关键词组自动分词)
  585. // 模糊搜索:对用户输入的单个关键词进行分词处理,但必须都存在;
  586. //主关键词词组
  587. if p.SearchMode == 1 {
  588. if ikWords := util.HttpEs(p.KeyWords, "ik_smart", IC.DB.Es.Addr); ikWords != "" {
  589. p.KeyWords = jy.KeywordsProcessing(ikWords, IC.C.JYKeyMark)
  590. }
  591. }
  592. searchWords = append(searchWords, p.KeyWords)
  593. }
  594. //附加词 每组附加词不能超过15个字符
  595. if p.AdditionalWords != "" {
  596. var additionalWords []string
  597. for _, ak := range strings.Split(p.AdditionalWords, ",") {
  598. if len([]rune(ak)) > 15 {
  599. additionalWords = append(additionalWords, string([]rune(ak)[:15]))
  600. } else {
  601. additionalWords = append(additionalWords, ak)
  602. }
  603. }
  604. p.AdditionalWords = strings.Join(additionalWords, ",") //分组不变
  605. //多组附加词,每组间,号隔开。每组内如果关键词中间有空格,自动分词
  606. if p.SearchMode == 1 {
  607. var (
  608. addWords []string
  609. )
  610. for _, awv := range strings.Split(p.AdditionalWords, ",") {
  611. if strings.TrimSpace(awv) != "" {
  612. if ikWords := util.HttpEs(awv, "ik_smart", IC.DB.Es.Addr); ikWords != "" {
  613. addWords = append(addWords, jy.KeywordsProcessing(ikWords, IC.C.JYKeyMark))
  614. }
  615. }
  616. }
  617. if len(addWords) > 0 {
  618. p.AdditionalWords = strings.Join(addWords, ",")
  619. }
  620. }
  621. searchWords = append(searchWords, strings.Split(p.AdditionalWords, ",")...)
  622. }
  623. p.HighlightWords = strings.Join(searchWords, ",")
  624. //报名截止
  625. if p.DeadlineStatus < 0 || p.DeadlineStatus > 2 {
  626. p.DeadlineStatus = 0
  627. }
  628. if len(strings.Split(p.DeadlineTime, "-")) > 1 {
  629. p.DeadlineStart, _ = strconv.ParseInt(strings.Split(p.DeadlineTime, "-")[0], 10, 64)
  630. p.DeadlineEnd, _ = strconv.ParseInt(strings.Split(p.DeadlineTime, "-")[1], 10, 64)
  631. if p.DeadlineEnd < p.DeadlineStart {
  632. var deadline = p.DeadlineStart
  633. p.DeadlineStart = p.DeadlineEnd
  634. p.DeadlineEnd = deadline
  635. }
  636. }
  637. switch p.DeadlineStatus {
  638. case 1: //未截止
  639. if p.DeadlineEnd < time.Now().Unix() {
  640. p.DeadlineStart = time.Now().Unix()
  641. p.DeadlineEnd = 0
  642. }
  643. case 2: //已截止
  644. if p.DeadlineEnd == 0 || p.DeadlineEnd > time.Now().Unix() {
  645. p.DeadlineStart = 0
  646. p.DeadlineEnd = time.Now().Unix()
  647. }
  648. }
  649. //空搜索 其它筛选条件 无效
  650. if p.IsEmptySearch() {
  651. //
  652. p.DomainFirstType = ""
  653. p.DomainSecondType = ""
  654. p.DomainThirdType = ""
  655. p.DeadlineStatus = 0
  656. p.DeadlineStart = 0
  657. p.DeadlineEnd = 0
  658. p.DeliveryArea = ""
  659. p.DeliveryCity = ""
  660. p.DeliveryDistrict = ""
  661. p.ProjectArea = ""
  662. p.ProjectCity = ""
  663. p.ProjectDistrict = ""
  664. p.FileExists = 0
  665. p.Publisher = 0
  666. }
  667. }