shorturl.go 59 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667
  1. package front
  2. import (
  3. "context"
  4. "database/sql"
  5. "errors"
  6. "fmt"
  7. "github.com/gogf/gf/v2/frame/g"
  8. "io"
  9. "jy/src/jfw/config"
  10. "jy/src/jfw/wx"
  11. "log"
  12. "math/rand"
  13. "net/http"
  14. "net/url"
  15. "strconv"
  16. "sync"
  17. "github.com/gogf/gf/v2/util/gconv"
  18. "jy/src/jfw/jyutil"
  19. "app.yhyue.com/moapp/jypkg/public"
  20. util "app.yhyue.com/moapp/jybase/common"
  21. "app.yhyue.com/moapp/jybase/date"
  22. mg "app.yhyue.com/moapp/jybase/mongodb"
  23. "regexp"
  24. "strings"
  25. "time"
  26. elastic "app.yhyue.com/moapp/jybase/es"
  27. "app.yhyue.com/moapp/jybase/encrypt"
  28. "app.yhyue.com/moapp/jybase/go-xweb/xweb"
  29. "app.yhyue.com/moapp/jybase/redis"
  30. "app.yhyue.com/moapp/jypkg/common/src/qfw/util/jy"
  31. "github.com/SKatiyar/qr"
  32. "go.mongodb.org/mongo-driver/bson"
  33. )
  34. type Short struct {
  35. *xweb.Action
  36. article xweb.Mapper `xweb:"/article/(\\w+)/(.*).html"` //([pm])
  37. qr xweb.Mapper `xweb:"/biddetail/(\\w+)/qr/(.+)"`
  38. replication xweb.Mapper `xweb:"/front/shorturl/replication"` //用户复制操作记录入库
  39. nologinArticle xweb.Mapper `xweb:"/nologin/(\\w+)/(.*).html"` //([pm]) 无需登录
  40. whiteList xweb.Mapper `xweb:"/initialize/whiteList"` //白名单初始化
  41. clearCache xweb.Mapper `xweb:"/front/free/clearCache"` //清楚缓存
  42. notFindPage xweb.Mapper `xweb:"/front/notFind"` //清楚缓存
  43. }
  44. var (
  45. mobileReg = regexp.MustCompile("(?i)(Android|Mobile|Phone)")
  46. DateFullLayout = "2006-01-02 15:04:05"
  47. Map_stype = map[string]bool{
  48. "content": true,
  49. "entservice": true,
  50. "bdprivate": true,
  51. "mailprivate": true,
  52. "bdcontent": true,
  53. "indexcontent": true,
  54. "advancedProject": true,
  55. }
  56. //seoAgentReg = regexp.MustCompile("Baiduspider|360Spider|bingbot|Googlebot")
  57. detailNeedMosaic map[string]interface{}
  58. TypeCodeMap = map[string]string{
  59. "拟建": "拟建项目",
  60. "采购意向": "采购意向",
  61. "预告": "招标预告",
  62. "预审": "资格预审",
  63. "预审结果": "资格预审结果",
  64. "论证意见": "论证意见",
  65. "需求公示": "需求公示",
  66. "招标": "公开招标",
  67. "邀标": "邀请招标",
  68. "询价": "询价采购",
  69. "竞谈": "竞争性谈判",
  70. "单一": "单一来源采购",
  71. "竞价": "竞价公告",
  72. "变更": "变更公告",
  73. "中标": "中标公示",
  74. "成交": "成交公告",
  75. "废标": "废标公告",
  76. "流标": "流标公告",
  77. "合同": "合同公告信息",
  78. "验收": "验收公告信息",
  79. "违规": "违规信息",
  80. }
  81. PageTypeCheck = map[string]bool{
  82. "content": false,
  83. "entservice": false,
  84. "bdprivate": true,
  85. "mailprivate": false,
  86. "bdcontent": false,
  87. "indexcontent": true, //老首页 seo入口 供爬虫使用
  88. "advancedProject": false,
  89. }
  90. cacheIndex = []byte{}
  91. cacheLock = sync.Mutex{}
  92. )
  93. func (s *Short) NotFindPage() error {
  94. return s.Render("/pc/tags/404.html")
  95. }
  96. func (s *Short) ClearCache() {
  97. defer util.Catch()
  98. cacheLock.Lock()
  99. defer cacheLock.Unlock()
  100. log.Println("before cacheIndex:", string(cacheIndex))
  101. var (
  102. data = string(cacheIndex)
  103. )
  104. if len(cacheIndex) > 0 {
  105. cacheIndex = []byte{}
  106. }
  107. log.Println("after cacheIndex:", string(cacheIndex))
  108. s.ServeJson(map[string]interface{}{
  109. "state": len(cacheIndex),
  110. "index": data,
  111. })
  112. }
  113. func (s *Short) WhiteList() error {
  114. ipInitAuthentication := s.GetString("ipInitAuthentication")
  115. if ipInitAuthentication == config.Sysconfig["ipInitAuthentication"] {
  116. config.IpInit()
  117. log.Println("初始化ipInit配置")
  118. }
  119. return nil
  120. }
  121. func (s *Short) Article(stype, id string) error {
  122. //是否是移动端
  123. bm := mobileReg.MatchString(s.Header("User-Agent"))
  124. //是否是微信浏览器
  125. isWxB := public.CheckWxBrowser(s.Request)
  126. //userId, _ := s.GetSession("userId").(string)
  127. sess := s.Session().GetMultiple()
  128. //未登录用户是否访问的微信浏览器
  129. userId, _ := sess["userId"].(string)
  130. if strings.Contains(id, "/") {
  131. id = url.QueryEscape(id)
  132. }
  133. if userId == "" {
  134. if IsWxBrowserContent[stype] {
  135. if s.GetString("state") == "wx" {
  136. //微信跳回来的
  137. if code := s.GetString("code"); code != "" {
  138. if openid := jyutil.Getopenid(code); openid != "" {
  139. if CheckUserIsSubscribe(openid) {
  140. FindUserAndCreateSess(openid, s.Session(), "wx", false, true)
  141. //生session后 重新获取一下
  142. //userId, _ = s.GetSession("userId").(string)
  143. sess = s.Session().GetMultiple()
  144. experienceBinding := util.Int64All(sess["experience_binding"])
  145. userId, _ = sess["userId"].(string)
  146. //新关注微信公众号用户是否绑定手机号
  147. phone, ok := sess["phone"].(string)
  148. if ok && phone == "" && experienceBinding != 1 { //微信用户 体验绑定手机号
  149. //注册时间
  150. regTime := util.Int64All(s.GetSession("registedate"))
  151. //新用户时间
  152. accountMergeOnline, _ := config.Sysconfig["accountMergeOnline"].(string)
  153. if accountMergeOnline != "" && regTime > 0 {
  154. reg := time.Unix(regTime, 0)
  155. onLineTime, _ := time.ParseInLocation(date.Date_Full_Layout, accountMergeOnline, time.Local)
  156. //如果未绑定手机号,老用户不用强制绑定;新用户需要绑定手机号
  157. if onLineTime.Before(reg) {
  158. return s.Redirect("/swordfish/frontPage/userMerge/sess/bind?from=detail")
  159. }
  160. }
  161. }
  162. } else if !bm { //未关注用户 pc端到关注页面
  163. log.Println("PC微信端浏览器 未关注用户 访问地址----")
  164. s.Request.Header.Del("Referer")
  165. return s.Redirect("/swordfish/frontPage/user/free/redirect-wx")
  166. } //未关注用户 移动端下面处理
  167. }
  168. }
  169. } else if isWxB {
  170. //所有参数都不再使用,跳到微信验证用户
  171. return s.Redirect(fmt.Sprintf(config.Wxoauth, url.QueryEscape(s.Site()+s.Url()), "wx"), 302)
  172. }
  173. }
  174. }
  175. //PC端未登录用户程序走此逻辑 WX端走原来逻辑
  176. if !bm && (stype == "content" || stype == "indexcontent" || stype == "mailprivate") && userId == "" {
  177. sids := encrypt.CommonDecodeArticle(stype, id)
  178. if len(sids) == 0 || (len(sids) > 0 && sids[0] == "") {
  179. return s.Redirect(getErrPageUrl(bm, DecodeErr), 302)
  180. }
  181. //2024.11.26 增加新标讯未登录 /article/content 302 到seo/nologin/content
  182. if mgoId := sids[0]; stype == "content" && mgoId != "" {
  183. if bid := mg.StringTOBsonId(mgoId); bid.Timestamp().Unix() > 1732550400 {
  184. return s.Redirect(fmt.Sprintf("/nologin/content/%s.html", id), 302)
  185. }
  186. }
  187. return s.NologinCommon("", stype, id, sids[0], bm)
  188. }
  189. return s.LoginCommon(sess, stype, id, bm)
  190. }
  191. const (
  192. DecodeErr = iota + 1
  193. QueryErr
  194. UndefinedType
  195. )
  196. func getErrPageUrl(isMobile bool, t int) string {
  197. if isMobile {
  198. return fmt.Sprintf("/jyapp/notFind?t=%d", t)
  199. }
  200. return fmt.Sprintf("/front/notFind?t=%d", t)
  201. }
  202. func (s *Short) LoginCommon(sess map[string]interface{}, stype, id string, bm bool) error {
  203. userId, _ := sess["userId"].(string)
  204. log.Println(stype, "----stype:---", id, "---userId---:", userId, "----", bm)
  205. //电脑端 剑鱼快照页面访问
  206. if !bm {
  207. //工作桌面内嵌 快照页
  208. //老地址(地址不包含aside)且非工作桌面地址
  209. if !strings.Contains(s.Request.URL.String(), "aside") && !strings.Contains(s.Request.URL.String(), "page_workDesktop") {
  210. tg := &Tags{} //415 第二版 添加右侧推荐 工作台外登录 不在重定向跳转
  211. s.T["newBidInfoList"] = tg.GetNewBidInfo()
  212. s.T["industryInfoList"] = tg.GetConsult()
  213. s.T["hotLabelList"] = tg.GetHotLabel(30)
  214. }
  215. if inWorkDesktop, _ := s.GetInt("inWorkDesktop"); inWorkDesktop == 1 && !strings.Contains(s.Request.URL.String(), "page_workDesktop") {
  216. return s.Redirect(fmt.Sprintf("%s%s%s", config.Sysconfig["workDesktopUrl"].(string), config.Sysconfig["webdomain"].(string), url.QueryEscape(strings.Replace(s.Request.URL.String(), "inWorkDesktop=1", "inWorkDesktop=0", 1))))
  217. }
  218. //P406登录用户标讯详情页改版
  219. if userId != "" {
  220. sids := encrypt.CommonDecodeArticle(stype, id)
  221. if len(sids) == 0 || (len(sids) > 0 && sids[0] == "") {
  222. s.Redirect(getErrPageUrl(bm, DecodeErr), 302)
  223. return nil
  224. }
  225. s.T["title"], s.T["keywords"], s.T["description"] = GetTDK(stype, sids[0])
  226. return s.Render("/pc/detail/biddetail_login.html", &s.T)
  227. }
  228. } else if userId != "" { //移动端登录
  229. //mobileHtmlKey := "jy_mobile_index_wx"
  230. var loginPageInfo = func() (body []byte) {
  231. // 获取页面内容
  232. mobileUrl := fmt.Sprintf("%s%s", config.Sysconfig["webdomain"].(string), "/jy_mobile/index.html")
  233. log.Println("article --- mobileUrl :", mobileUrl)
  234. req, err := http.NewRequest("GET", mobileUrl, nil)
  235. if err != nil {
  236. log.Println(s.ResponseWriter, "Failed to fetch page", http.StatusInternalServerError)
  237. return
  238. }
  239. req.Header.Set("mobile_index", "wx")
  240. req.Header.Set("X-Forwarded-For", util.GetIp(s.Request))
  241. client := &http.Client{}
  242. // 使用 Do 方法处理请求
  243. resp, err := client.Do(req)
  244. if err != nil {
  245. log.Println(s.ResponseWriter, "Failed to create client", http.StatusInternalServerError)
  246. return
  247. }
  248. defer resp.Body.Close()
  249. body, err = io.ReadAll(resp.Body)
  250. if err != nil {
  251. log.Println(s.ResponseWriter, "Failed to read response body", http.StatusInternalServerError)
  252. return
  253. }
  254. //err = redis.PutBytes(redisLimitation, mobileHtmlKey, &body, 3*24*60*60)
  255. //if err != nil {
  256. // log.Println("mobile html redis cache err :", err.Error())
  257. //}
  258. return
  259. }
  260. // 将页面内容返回给前端
  261. s.ResponseWriter.Header().Set("Content-Type", "text/html; charset=utf-8")
  262. cacheLock.Lock()
  263. if len(cacheIndex) == 0 {
  264. cacheIndex = loginPageInfo()
  265. }
  266. cacheLock.Unlock()
  267. s.ResponseWriter.Write(cacheIndex)
  268. return nil
  269. }
  270. //getsession := s.Session().GetMultiple()
  271. //先判断是否有session
  272. source := s.GetString("source")
  273. disWord := s.GetString("disWord")
  274. aboutUrl := "/swordfish/about"
  275. //是否已经检查过,默认是检查过-true,分享过来的是未检查过-false
  276. // checkIsSubscribeFlag := true
  277. // if source == "app_infocontentshare" || source == "wx_infocontentshare" {
  278. // checkIsSubscribeFlag = false
  279. // }
  280. from_userid := ""
  281. if source != "" {
  282. aboutUrl += "?source=" + source
  283. if strings.Contains(source, "wx_infocontentshare") {
  284. decodeArr := encrypt.DecodeArticleId2ByCheck(id)
  285. if len(decodeArr) > 1 {
  286. from_userid = se.Encode2Hex(GetUserId(decodeArr[1])) //加密用户userid
  287. }
  288. } else if strings.Contains(source, "app_infocontentshare") {
  289. if from := s.GetString("from"); from != "" {
  290. from_userid = from
  291. }
  292. }
  293. aboutUrl += "&from=" + from_userid
  294. }
  295. if !Map_stype[stype] {
  296. return s.Redirect(getErrPageUrl(bm, UndefinedType), 302)
  297. } else if stype == "content" || stype == "bdcontent" || stype == "advancedProject" {
  298. if userId == "" { //} && !regclient.MatchString(client) { //没有用户session //搜索引擎让过
  299. s.Session().Set("referer", s.Request.RequestURI)
  300. if bm { //是否是移动端访问
  301. s.Redirect(aboutUrl, 302)
  302. return nil
  303. } else {
  304. if stype == "bdcontent" {
  305. var retMap = make(map[string]interface{})
  306. stype = "content"
  307. sids := encrypt.CommonDecodeArticle(stype, id)
  308. if len(sids) == 0 || (len(sids) > 0 && sids[0] == "") {
  309. return s.Redirect(getErrPageUrl(bm, DecodeErr), 302)
  310. }
  311. _, _, _, obj := pcVRT(sids[0], "", stype, true, true)
  312. if obj != nil && len(obj) > 0 {
  313. retMap["_id"] = url.QueryEscape(id)
  314. retMap["title"], _ = obj["title"].(string)
  315. retMap["area"], _ = obj["area"].(string)
  316. retMap["subtype"], _ = obj["subtype"].(string)
  317. retMap["subscopeclass"], _ = obj["s_subscopeclass"].(string)
  318. retMap["publishtime"] = util.IntAll(obj["publishtime"])
  319. retMap["keywords"] = KeyWordHandle(obj)
  320. retMap["description"] = DescriptionHandle(stype, obj)
  321. }
  322. s.T["shareid"] = config.Seoconfig["baiduSEM-p"].(string)
  323. s.T["logid"] = config.Seoconfig["baiduSEM-p"].(string)
  324. s.T["obj"] = retMap
  325. s.Render("/pc/biddetail_bd.html", &s.T)
  326. } else {
  327. s.Redirect(getErrPageUrl(bm, UndefinedType), 302)
  328. }
  329. }
  330. return nil
  331. } else if disWord != "" {
  332. from_userid = disWordNil(disWord, userId)
  333. }
  334. if stype == "bdcontent" {
  335. stype = "content"
  336. }
  337. } else if stype == "entservice" { //大客户数据快照展示
  338. //se := util.SimpleEncrypt{"entservice"}
  339. sid := encrypt.SE3.DecodeString(id)
  340. log.Println("----sid:---", sid)
  341. if len(sid) == 0 || (len(sid) > 0 && sid == "") { //未登录用户没有权限访问---userId == "" || 未登录可以访问来自陈 11.29
  342. return s.Redirect(getErrPageUrl(bm, DecodeErr), 302)
  343. }
  344. catchKey := fmt.Sprintf("jypcdetail_%s_%s_%s", userId, stype, sid)
  345. if res := redis.Get(redisLimitation, catchKey); res == nil || res == "" {
  346. industry := s.GetString("industry")
  347. var shareid = s.GetString("id")
  348. if len(shareid) == 0 {
  349. shareid = "10"
  350. }
  351. s.T["logid"] = config.Seoconfig["jysskzy"].(string)
  352. s.T["shareid"] = se.EncodeString(shareid)
  353. s.T["keywords"] = s.GetString("kds")
  354. ssOpenid := sess["s_m_openid"]
  355. po, bo, wo, obj := pcVRT(sid, industry, stype, true, true)
  356. if obj != nil && len(obj) > 0 {
  357. if len(po) > 0 {
  358. s.T["projectOther"] = po
  359. }
  360. if len(bo) > 0 {
  361. s.T["buyerOther"] = bo
  362. }
  363. if len(wo) > 0 {
  364. s.T["winnerOther"] = wo
  365. }
  366. obj["urlpath"] = s.Uri()
  367. obj["industry"] = industry
  368. if ssOpenid != nil {
  369. obj["ucbsId"] = encrypt.EncodeArticleId2ByCheck("ucbs#" + ssOpenid.(string) + "#" + id)
  370. }
  371. //if false && isbid(obj["subtype"]) {
  372. // //bidding表有数据就有,没有不再查此中标企业得其他信息--需求来自数据和质量
  373. // obj["winner_enttel"] = "" //getwinnertel(obj["winner"])
  374. //}
  375. //判断时间 //如果是seo页面超过时间访问的进入首页
  376. comeinTime := time.Unix(util.Int64All(obj["comeintime"]), 0)
  377. if stype == "indexcontent" {
  378. if count := public.MQFW.Count("seobidding", map[string]interface{}{"bid": sid}); count <= 0 && comeinTime.Before(time.Now().Add(time.Duration(-util.IntAll(config.Sysconfig["seoBeforeTimeHour"]))*time.Hour)) {
  379. return s.Redirect("/")
  380. }
  381. }
  382. FieldProcessing(obj, ssOpenid, industry, id, from_userid, userId, stype, false)
  383. if obj["projectname"] != nil {
  384. s.SetSession("projectname", obj["projectname"])
  385. }
  386. if obj["entidlist"] != nil { //大会员中标企业跳转至画像
  387. s_winner := util.ObjToString(obj["s_winner"])
  388. idObjs, _ := obj["entidlist"].([]interface{})
  389. winnerIdArr := []string{}
  390. for _, v := range strings.Split(s_winner, ",") {
  391. if v == "-" || !isInStringArr(util.ObjArrToStringArr(idObjs), v) {
  392. continue
  393. }
  394. winnerIdArr = append(winnerIdArr, encrypt.EncodeArticleId2ByCheck(v))
  395. obj["entIds"] = winnerIdArr
  396. }
  397. }
  398. if obj["publishtime"] != nil {
  399. obj["publishtimeShorDate"] = time.Unix(util.Int64All(obj["publishtime"]), 0).Format(date.Date_Short_Layout)
  400. }
  401. s.T["url"] = s.Uri()
  402. obj["keywords"] = KeyWordHandle(obj)
  403. obj["description"] = DescriptionHandle(stype, obj)
  404. s.T["obj"] = obj
  405. content, _ := s.Render4Cache("/pc/biddetail_rec.html", &s.T)
  406. redis.Put(redisLimitation, catchKey, string(content), 60*20)
  407. return s.SetBody(content)
  408. } else {
  409. return s.Redirect(getErrPageUrl(bm, QueryErr), 302)
  410. }
  411. } else {
  412. return s.SetBody([]byte(res.(string)))
  413. }
  414. }
  415. ssOpenid := sess["s_m_openid"]
  416. var (
  417. res *map[string]interface{}
  418. ok bool
  419. )
  420. if userId == "" && ssOpenid != nil {
  421. res, ok = mongodb.FindOneByField("user", bson.M{"s_m_openid": ssOpenid, "s_unionid": bson.M{"$ne": ssOpenid}}, `{"i_vip_status":1,"i_member_status":1,"s_m_phone":1,"s_phone":1,"l_vip_starttime":1}`)
  422. if ok {
  423. userId = mg.BsonIdToSId((*res)["_id"])
  424. }
  425. } else if userId != "" {
  426. //判断用户是否是vip
  427. res = jyutil.Compatible.Select(userId, `{"i_vip_status":1,"i_member_status":1,"s_m_phone":1,"s_phone":1,"l_vip_starttime":1}`)
  428. }
  429. userPower := jy.GetBigVipUserBaseMsg(s.Session(), *config.Middleground)
  430. var (
  431. isEntnicheNew = userPower.EntIsNew //新版超级订阅
  432. isOldVip = false //新购超级订阅不能查看拟建项目详情页
  433. isVip = userPower.VipStatus > 0 //超级订阅
  434. isMember = userPower.Status > 0 //大会员
  435. isEntniche = userPower.EntnicheStatus > 0 //商机管理
  436. privatedata = userPower.PrivateGD //广东移动DICT 用户
  437. isEntService = userPower.Data.Ent.PowerSource > 0 && userPower.Data.Entniche.IsEntPower > 0 //商机管理服务
  438. newCanRead = false
  439. )
  440. if res != nil && len(*res) > 0 {
  441. if isVip && util.Int64All((*res)["l_vip_starttime"]) < util.Int64All(config.Sysconfig["contextOldVipLimit"]) {
  442. isOldVip = true
  443. }
  444. }
  445. //entid := util.Int64All(s.GetSession("entId"))
  446. entId := util.IntAll(sess["entId"])
  447. if entId > 0 && userPower.EntInfo[entId] != nil {
  448. isEntniche = userPower.EntInfo[entId].Status == 1 && userPower.EntInfo[entId].IsPower
  449. isEntnicheNew = userPower.EntInfo[entId].IsNew && isEntniche
  450. if isEntService = userPower.EntInfo[entId].IsService && userPower.EntInfo[entId].IsPower; isEntService {
  451. isEntnicheNew = false
  452. isEntniche = false
  453. }
  454. }
  455. if !isEntniche && privatedata {
  456. isEntniche = true
  457. }
  458. s.T["isVip"] = isVip
  459. s.T["isMember"] = isMember
  460. s.T["isEntniche"] = isEntniche
  461. s.T["isEntnicheNew"] = isEntnicheNew
  462. s.T["isEntService"] = isEntService
  463. if bm {
  464. //判断有没有取关,取关的话,跳转到关于剑鱼标讯页面
  465. if ssOpenid != nil && ssOpenid != "" {
  466. isSubscribe := CheckUserIsSubscribe(ssOpenid.(string))
  467. if !isSubscribe {
  468. return s.Redirect(aboutUrl, 302)
  469. }
  470. //之前sessionkeep.go中没有放userId,造成关注有问题
  471. if userId == "" {
  472. FindUserAndCreateSess(ssOpenid.(string), s.Session(), "wx", false, true)
  473. }
  474. }
  475. surl := s.GetString("url")
  476. kds := s.GetString("keywords")
  477. industry := s.GetString("industry")
  478. var shareopenid, sid string
  479. sid_openid := encrypt.CommonDecodeArticle(stype, id)
  480. switch len(sid_openid) {
  481. case 0:
  482. return s.Redirect(getErrPageUrl(bm, DecodeErr), 302)
  483. default:
  484. shareopenid, sid = SwiDef(sid_openid)
  485. }
  486. if stype == "advancedProject" {
  487. //判断此用户是否有打开的权限
  488. //newUserId := s.GetSession("base_user_id")
  489. newUserId := sess["base_user_id"]
  490. pushData := public.BaseMysql.FindOne("leadproject_push", map[string]interface{}{"user_id": newUserId, "info_id": sid}, "id", "")
  491. //访问次数加1
  492. if pushData == nil {
  493. newCanRead = false
  494. } else {
  495. public.BaseMysql.UpdateOrDeleteBySql("UPDATE leadproject_push SET visit_count=visit_count+1 ,lastvisit_time=? WHERE id = ?", time.Now().Format("2006-01-02 15:04:05"), (*pushData)["id"])
  496. newCanRead = true
  497. }
  498. }
  499. s.T["keywords"] = kds
  500. if shareopenid != "" {
  501. s.T["shareopenid"] = shareopenid
  502. }
  503. myopenid, _ := sess["s_m_openid"].(string)
  504. if myopenid == "" {
  505. myopenid = shareopenid
  506. s.T["openid"] = myopenid //"-1"
  507. } else {
  508. s.T["openid"] = se.EncodeString(myopenid) //"-1"
  509. }
  510. //mynickname, _ := s.GetSession("s_nickname").(string)
  511. //myavatar, _ := s.GetSession("s_avatar").(string)
  512. mynickname := util.ObjToString(sess["s_nickname"])
  513. myavatar := util.ObjToString(sess["s_avatar"])
  514. s.T["nickname"] = mynickname
  515. s.T["avatar"] = myavatar
  516. s.T["signature"] = wx.SignJSSDK(s.Site() + s.Url())
  517. obj := wxvisitD(sid, userId, myopenid, stype, (isVip && isOldVip) || isMember || isEntniche || newCanRead)
  518. canRead := false
  519. if ((isVip && isOldVip) || isMember || isEntniche) || //老版本vip、大会员、商机管理
  520. ((isVip && !isOldVip) && (!(util.ObjToString(obj["subtype"]) == "拟建" || util.ObjToString(obj["subtype"]) == "采购意向"))) || //新超级订阅非采购意向”和“拟建项目”
  521. stype == "mailprivate" || stype == "indexcontent" || stype == "bdprivate" { //邮箱推送
  522. canRead = true
  523. } else {
  524. canRead = SeeDetailLimit(obj, userId, sid)
  525. }
  526. if newCanRead {
  527. canRead = newCanRead
  528. s.T["canRead"] = canRead
  529. }
  530. if len(obj) > 0 {
  531. if canRead {
  532. FieldProcessing(obj, ssOpenid, industry, id, from_userid, userId, stype, true)
  533. //免费用户正文手机号替换
  534. if obj["site"] == "剑鱼信息发布平台" && !isMember {
  535. //采购电话中标单位电话置空
  536. if util.InterfaceToStr(obj["buyertel"]) != "" {
  537. obj["buyertel"] = "freeView"
  538. }
  539. if util.InterfaceToStr(obj["winnertel"]) != "" {
  540. obj["winnertel"] = "freeView"
  541. }
  542. //正文电话 手机号 邮箱处理
  543. if detail, _ := obj["detail"].(string); detail != "" {
  544. //手机号
  545. re1 := regexp.MustCompile("1[345789]{1}\\d{9}")
  546. detail1 := re1.ReplaceAllString(detail, `<span class="freeView">点击查看</span>`)
  547. code := util.InterfaceToStr(obj["projectcode"])
  548. if code != "" {
  549. detail1 = strings.ReplaceAll(detail1, code, "*********")
  550. }
  551. //座机
  552. re2 := regexp.MustCompile("((0\\d{2,3})-)(\\d{7,8})(-(\\d{3,}))?")
  553. detail2 := re2.ReplaceAllString(detail1, `<span class="freeView">点击查看</span>`)
  554. re4 := regexp.MustCompile("((400)-)(\\d{3,4}-)(\\d{3,})")
  555. detail4 := re4.ReplaceAllString(detail2, `<span class="freeView">点击查看</span>`)
  556. //邮箱
  557. re3 := regexp.MustCompile("([a-zA-Z0-9_\\-\\.]+)@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.)|(([a-zA-Z0-9\\-]+\\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\\]?)")
  558. detail3 := re3.ReplaceAllString(detail4, `<span class="freeView">点击查看</span>`)
  559. obj["detail"] = strings.ReplaceAll(strings.ReplaceAll(detail3, `<span class="freeView">点击查看</span><span class="freeView">点击查看</span>`, `<span class="freeView">点击查看</span>`), "*********", code)
  560. }
  561. }
  562. if obj["entidlist"] != nil { //大会员中标企业跳转至画像
  563. s_winner := util.ObjToString(obj["s_winner"])
  564. idObjs, _ := obj["entidlist"].([]interface{})
  565. winnerIdArr := []string{}
  566. for _, v := range strings.Split(s_winner, ",") {
  567. if v == "-" || !isInStringArr(util.ObjArrToStringArr(idObjs), v) {
  568. continue
  569. }
  570. winnerIdArr = append(winnerIdArr, encrypt.EncodeArticleId2ByCheck(v))
  571. obj["entIds"] = winnerIdArr
  572. }
  573. }
  574. //原 拟建类型可以进入,进行打码操作,后根据需求改成遮罩
  575. if !canRead { //登录拟建&采购不展示遮罩 只打码
  576. //canRead = true
  577. //打码显示引导
  578. otherFilter(obj, userId != "")
  579. }
  580. s.T["advertcode"] = s.GetString("advertcode")
  581. } else {
  582. obj = map[string]interface{}{
  583. "title": obj["title"],
  584. "_id": obj["_id"],
  585. "subtype": obj["subtype"],
  586. "originalShow": false,
  587. }
  588. }
  589. //纠错随机回复
  590. recoveryRight, _ := config.Sysconfig["recoveryRight"].([]interface{})
  591. recVal := rand.New(rand.NewSource(time.Now().UnixNano())).Intn(len(recoveryRight))
  592. s.T["recVal"] = util.ObjToString(recoveryRight[recVal])
  593. s.T["advertImg"] = config.Sysconfig["advertImg"]
  594. s.T["advertName"] = config.Sysconfig["advertName"]
  595. s.T["advertUrl"] = config.Sysconfig["advertUrl"]
  596. s.T["canRead"] = canRead
  597. obj["industry"] = industry
  598. obj["keywords"] = KeyWordHandle(obj)
  599. obj["description"] = DescriptionHandle(stype, obj)
  600. s.T["obj"] = obj
  601. //获取打赏文案
  602. s.T["rewardText"], s.T["advertText"] = getRewardText()
  603. content, _ := s.Render4Cache("/weixin/wxinfocontent_rec.html", &s.T)
  604. return s.SetBody(content)
  605. } else if surl == "" {
  606. return s.Redirect(getErrPageUrl(bm, QueryErr), 302)
  607. } else {
  608. return s.Redirect(surl)
  609. }
  610. } else {
  611. sids := encrypt.CommonDecodeArticle(stype, id)
  612. if len(sids) == 0 || (len(sids) > 0 && sids[0] == "") {
  613. return s.Redirect(getErrPageUrl(bm, DecodeErr), 302)
  614. }
  615. sid := sids[0]
  616. //免费用户浏览三级页判断留资与浏览次数
  617. //indust := s.GetString("industry")
  618. if userId != "" && stype == "indexcontent" { //已登录用户直接跳转至正常三级页
  619. return s.Redirect(fmt.Sprintf("/article/content/%s.html", encrypt.EncodeArticleId2ByCheck(sid)))
  620. }
  621. if stype == "advancedProject" {
  622. //判断此用户是否有打开的权限
  623. //newUserId := s.GetSession("base_user_id")
  624. newUserId := sess["base_user_id"]
  625. pushData := public.BaseMysql.FindOne("leadproject_push", map[string]interface{}{"user_id": newUserId, "info_id": sid}, "id", "")
  626. //访问次数加1
  627. if pushData == nil {
  628. newCanRead = false
  629. } else {
  630. public.BaseMysql.UpdateOrDeleteBySql("UPDATE leadproject_push SET visit_count=visit_count+1 ,lastvisit_time=? WHERE id = ?", time.Now().Format("2006-01-02 15:04:05"), (*pushData)["id"])
  631. newCanRead = true
  632. }
  633. }
  634. var detailKey = func() string {
  635. if (isVip && isOldVip) || isMember || isEntniche || newCanRead || stype == "mailprivate" || stype == "indexcontent" || stype == "bdprivate" {
  636. return "pay" //可以看全部
  637. } else if isVip && !isOldVip {
  638. return "new_vip_pay" //新版超级订阅不能看 采购意向
  639. } else if SeeDetailLimit(nil, userId, sid) {
  640. return "saleLeads_free" //未留资 三篇非采购意向信息;留资后同pay
  641. } else {
  642. return "free" //已经免费查看三篇招标信息,且未留资。任何信息都不能看 有遮罩
  643. }
  644. }()
  645. catchKey := fmt.Sprintf("jypcdetail_%s_%s_%s", detailKey, stype, sid)
  646. if res := redis.Get(redisLimitation, catchKey); res == nil || res == "" {
  647. redisTimeOut := util.If((isVip && isOldVip) || isMember || isEntniche || newCanRead, detailRedisByPayTimeOut, detailRedisByFreeTimeOut).(int)
  648. industry := s.GetString("industry")
  649. var shareid = s.GetString("id")
  650. if len(shareid) == 0 {
  651. shareid = "10"
  652. }
  653. s.T["logid"] = config.Seoconfig["jysskzy"].(string)
  654. s.T["shareid"] = se.EncodeString(shareid)
  655. s.T["keywords"] = s.GetString("kds")
  656. s.DisableHttpCache()
  657. po, bo, wo, obj := pcVRT(sid, industry, stype, isVip || isMember || isEntniche || newCanRead, true)
  658. if obj != nil && len(obj) > 0 {
  659. var node bool
  660. if ((isVip && isOldVip) || isMember || isEntniche) || //老版本vip、大会员、商机管理 白名单
  661. ((isVip && !isOldVip) && (!(util.ObjToString(obj["subtype"]) == "拟建" || util.ObjToString(obj["subtype"]) == "采购意向"))) || //新超级订阅非采购意向”和“拟建项目”
  662. stype == "mailprivate" || stype == "indexcontent" || stype == "bdprivate" { //邮箱推送
  663. node = true
  664. } else {
  665. //_, _, _, objc := pcVRT(sid, indust, stype, isVip || isMember || isEntniche)
  666. node = SeeDetailLimit(obj, userId, sid)
  667. }
  668. if obj["publishtime"] != nil {
  669. obj["publishtimeShorDate"] = time.Unix(util.Int64All(obj["publishtime"]), 0).Format(date.Date_Short_Layout)
  670. }
  671. s.T["canRead"] = node
  672. if newCanRead {
  673. s.T["canRead"] = newCanRead
  674. node = newCanRead
  675. }
  676. if node {
  677. if len(po) > 0 {
  678. s.T["projectOther"] = po
  679. }
  680. if len(bo) > 0 {
  681. s.T["buyerOther"] = bo
  682. }
  683. if len(wo) > 0 {
  684. s.T["winnerOther"] = wo
  685. }
  686. //判断时间 //如果是seo页面超过时间访问的进入首页
  687. comeinTime := time.Unix(util.Int64All(obj["comeintime"]), 0)
  688. if stype == "indexcontent" {
  689. if count := public.MQFW.Count("seobidding", map[string]interface{}{"bid": sid}); count <= 0 && comeinTime.Before(time.Now().Add(time.Duration(-util.IntAll(config.Sysconfig["seoBeforeTimeHour"]))*time.Hour)) {
  690. return s.Redirect("/")
  691. }
  692. }
  693. FieldProcessing(obj, ssOpenid, industry, id, from_userid, userId, stype, false)
  694. //免费用户正文手机号替换
  695. if obj["site"] == "剑鱼信息发布平台" && !isMember {
  696. //采购电话中标单位电话置空
  697. if util.InterfaceToStr(obj["buyertel"]) != "" {
  698. obj["buyertel"] = "freeView"
  699. }
  700. if util.InterfaceToStr(obj["winnertel"]) != "" {
  701. obj["winnertel"] = "freeView"
  702. }
  703. //正文电话 手机号 邮箱处理
  704. if detail, _ := obj["detail"].(string); detail != "" {
  705. //手机号
  706. re1 := regexp.MustCompile("1[345789]{1}\\d{9}")
  707. detail1 := re1.ReplaceAllString(detail, `<span class="freeView">点击查看</span>`)
  708. code := util.InterfaceToStr(obj["projectcode"])
  709. if code != "" {
  710. detail1 = strings.ReplaceAll(detail1, code, "*********")
  711. }
  712. //座机
  713. re2 := regexp.MustCompile("((0\\d{2,3})-)(\\d{7,8})(-(\\d{3,}))?")
  714. detail2 := re2.ReplaceAllString(detail1, `<span class="freeView">点击查看</span>`)
  715. re4 := regexp.MustCompile("((400)-)(\\d{3,4}-)(\\d{3,})")
  716. detail4 := re4.ReplaceAllString(detail2, `<span class="freeView">点击查看</span>`)
  717. //邮箱
  718. re3 := regexp.MustCompile("([a-zA-Z0-9_\\-\\.]+)@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.)|(([a-zA-Z0-9\\-]+\\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\\]?)")
  719. detail3 := re3.ReplaceAllString(detail4, `<span class="freeView">点击查看</span>`)
  720. obj["detail"] = strings.ReplaceAll(strings.ReplaceAll(detail3, `<span class="freeView">点击查看</span><span class="freeView">点击查看</span>`, `<span class="freeView">点击查看</span>`), "*********", code)
  721. }
  722. }
  723. if obj["projectname"] != nil {
  724. s.SetSession("projectname", obj["projectname"])
  725. }
  726. if obj["entidlist"] != nil { //大会员中标企业跳转至画像
  727. s_winner := util.ObjToString(obj["s_winner"])
  728. idObjs, _ := obj["entidlist"].([]interface{})
  729. winnerIdArr := []string{}
  730. for _, v := range strings.Split(s_winner, ",") {
  731. if v == "-" || !isInStringArr(util.ObjArrToStringArr(idObjs), v) {
  732. continue
  733. }
  734. winnerIdArr = append(winnerIdArr, encrypt.EncodeArticleId2ByCheck(v))
  735. obj["entIds"] = winnerIdArr
  736. }
  737. }
  738. if !node {
  739. //打码遮罩
  740. //s.T["canRead"] = true
  741. otherFilter(obj, userId != "")
  742. }
  743. } else {
  744. obj = map[string]interface{}{
  745. "title": obj["title"],
  746. "_id": obj["_id"],
  747. "subtype": obj["subtype"],
  748. "stypeadd": obj["stypeadd"],
  749. "originalShow": false,
  750. }
  751. }
  752. obj["urlpath"] = s.Uri()
  753. obj["industry"] = industry
  754. if ssOpenid != nil {
  755. obj["ucbsId"] = encrypt.EncodeArticleId2ByCheck("ucbs#" + ssOpenid.(string) + "#" + id)
  756. }
  757. obj["keywords"] = KeyWordHandle(obj)
  758. obj["description"] = DescriptionHandle(stype, obj)
  759. s.T["obj"] = obj
  760. s.T["url"] = s.Uri()
  761. content, _ := s.Render4Cache("/pc/biddetail_rec.html", &s.T)
  762. redis.Put(redisLimitation, catchKey, string(content), redisTimeOut)
  763. return s.SetBody(content)
  764. //return s.Render("/pc/biddetail_rec.html", &s.T)
  765. } else {
  766. return s.Redirect(getErrPageUrl(bm, QueryErr), 302)
  767. }
  768. } else {
  769. return s.SetBody([]byte(res.(string)))
  770. }
  771. }
  772. return nil
  773. }
  774. func CNode(userId string) bool {
  775. if hasRetainedCapital(userId, []string{"jyarticle_see3_plus", "jyarticle_see3_plus_pc", "jyarticle_see3_plus_wx", "jyarticle_see3_plus_app", "pc_article_member_freeuse", "app_article_member_freeuse", "app_article_member_freeuse", "wx_article_member_freeuse", "h5_article_member_freeuse"}) {
  776. return true
  777. }
  778. rM := map[string]interface{}{}
  779. rdata, ok := mongodb.Find("saleLeads", map[string]interface{}{
  780. "userid": userId,
  781. }, `{"createtime":-1}`, nil, false, 0, 10)
  782. if rdata != nil && len(*rdata) > 0 && ok {
  783. for _, v := range *rdata {
  784. for kk, vv := range v {
  785. if vv == nil {
  786. continue
  787. }
  788. if rM[kk] != nil {
  789. continue
  790. }
  791. rM[kk] = vv
  792. }
  793. }
  794. delete(rM, "_id")
  795. delete(rM, "userid")
  796. delete(rM, "createtime")
  797. delete(rM, "client")
  798. }
  799. if userinfo := jyutil.Compatible.Select(userId, `{"s_phone":1,"s_m_phone":1,"s_myemail":1,"s_company":1,"o_jy":1,"o_vipjy":1}`); userinfo != nil && len(*userinfo) > 0 {
  800. s_phone := util.ObjToString((*userinfo)["s_phone"])
  801. phone := util.If(s_phone == "", util.ObjToString((*userinfo)["s_m_phone"]), s_phone)
  802. if rM["phone"] == nil || rM["phone"] == "" {
  803. rM["phone"] = phone
  804. }
  805. if rM["company"] == nil || rM["company"] == "" {
  806. rM["company"] = util.ObjToString((*userinfo)["s_company"])
  807. }
  808. }
  809. if rM["name"] != nil && rM["name"] != "" && rM["phone"] != nil && rM["phone"] != "" && rM["company"] != nil && rM["company"] != "" && rM["position"] != nil && rM["position"] != "" && rM["companyType"] != "" {
  810. if rM["position"] != "总裁" && rM["position"] != "总经理" && (rM["branch"] == nil || rM["branch"] == "") {
  811. return false
  812. }
  813. return true
  814. }
  815. return false
  816. }
  817. // 查看公告详情次数限制
  818. func SeeDetailLimit(obj map[string]interface{}, userId, sid string) bool {
  819. watchKey := fmt.Sprintf("article_count_%d_%s_%d_%s", time.Now().Year(), time.Now().Month(), time.Now().Day(), userId)
  820. subTypeStr, _ := obj["subtype"].(string)
  821. if strings.Contains(subTypeStr, "拟建") || strings.Contains(subTypeStr, "采购意向") {
  822. return false
  823. } else {
  824. //检验是否留资
  825. if CNode(userId) {
  826. return true
  827. }
  828. if seeRes := redis.Get(redisLimitation, watchKey); seeRes != nil && seeRes != "" {
  829. if resVal, _ := seeRes.(string); resVal != "" {
  830. sidss := strings.Split(resVal, "_")
  831. canRead := config.Sysconfig["canReadNotice"]
  832. if len(sidss) < util.IntAll(canRead) {
  833. sidss = append(sidss, sid)
  834. arrs := RemoveDuplicatesAndEmpty(sidss)
  835. newVal := strings.Join(arrs, "_")
  836. redis.Put(redisLimitation, watchKey, newVal, jy.GetExpire())
  837. return true
  838. } else {
  839. for _, v := range sidss {
  840. if sid == v {
  841. return true
  842. }
  843. }
  844. return false
  845. }
  846. }
  847. } else {
  848. redis.Put(redisLimitation, watchKey, sid, jy.GetExpire())
  849. return true
  850. }
  851. }
  852. return false
  853. }
  854. func SwiDef(sid_openid []string) (string, string) {
  855. var shareopenid, sid string
  856. if len(sid_openid) > 1 {
  857. sid = sid_openid[0]
  858. shareopenid = sid_openid[1]
  859. } else {
  860. sid = sid_openid[0]
  861. }
  862. return shareopenid, sid
  863. }
  864. // user 权限获取
  865. func UserPermission(userId string, ssOpenid interface{}) (bool, bool, bool) {
  866. var (
  867. res *map[string]interface{}
  868. isVip, isMember, isEntniche, privatedata bool
  869. )
  870. if userId == "" && ssOpenid != nil {
  871. res, _ = mongodb.FindOneByField("user", bson.M{"s_m_openid": ssOpenid, "s_unionid": bson.M{"$ne": ssOpenid}}, `{"i_vip_status":1,"i_member_status":1,"s_m_phone":1,"s_phone":1}`)
  872. userId = mg.BsonIdToSId((*res)["_id"])
  873. } else {
  874. //判断用户是否是vip
  875. res = jyutil.Compatible.Select(userId, `{"i_vip_status":1,"i_member_status":1,"s_m_phone":1,"s_phone":1}`)
  876. }
  877. isVip = util.IntAll((*res)["i_vip_status"]) == 1 || util.IntAll((*res)["i_vip_status"]) == 2
  878. isMember = util.IntAll((*res)["i_member_status"]) > 0
  879. if phone, _ := util.If(util.ObjToString((*res)["s_phone"]) != "", util.ObjToString((*res)["s_phone"]), util.ObjToString((*res)["s_m_phone"])).(string); phone != "" {
  880. isEntniche = public.Mysql.CountBySql(`SELECT count(1) from entniche_user a INNER JOIN entniche_info b on (a.phone=? and a.power=1 and a.ent_id=b.id and b.status>0)`, phone) > 0
  881. privatedata = public.Mysql.CountBySql(`select count(1) from privatedata where phone = ?`, phone) > 0
  882. }
  883. if !isEntniche && privatedata {
  884. isEntniche = true
  885. }
  886. return isVip, isMember, isEntniche
  887. }
  888. // pc 移动共用字段处理
  889. func FieldProcessing(obj map[string]interface{}, ssOpenid interface{}, industry, id, from_userid, userId, stype string, b bool) {
  890. obj["industry"] = industry
  891. if ssOpenid != nil {
  892. obj["ucbsId"] = encrypt.EncodeArticleId2ByCheck("ucbs#" + ssOpenid.(string) + "#" + id)
  893. }
  894. //判断是否公开联系人信息
  895. if util.Int64All(obj["buyerhint"]) == 2 {
  896. obj["buyerperson"] = ""
  897. obj["buyertel"] = ""
  898. }
  899. href, _ := obj["href"].(string)
  900. if !b {
  901. href = strings.Replace(href, "\n", "", -1)
  902. if href != "" && !strings.HasPrefix(href, "http") {
  903. href = "http://" + href
  904. }
  905. obj["url"] = href
  906. obj["buyerSeoId"] = EsSeoId(false, util.InterfaceToStr(obj["buyer"]))
  907. }
  908. //P385 查看原文
  909. obj["originalShow"] = false
  910. if href != "" && userId != "" {
  911. obj["originalShow"] = true
  912. }
  913. //大会员中标企业跳转至画像
  914. if obj["entidlist"] != nil {
  915. if s_winner := util.ObjToString(obj["s_winner"]); s_winner != "" {
  916. entIdArr, winnerMap, winnerSeoMap := []string{}, map[string]interface{}{}, map[string]interface{}{}
  917. swinnerArr := strings.Split(s_winner, ",")
  918. eidList, _ := obj["entidlist"].([]interface{})
  919. //先查询entlist 如果长度和s_winner不一致 根据企业名称查询id
  920. if len(eidList) != len(swinnerArr) {
  921. for _, v := range swinnerArr {
  922. winnerMap[v] = ""
  923. //临时更改为企业名称查询企业id
  924. rData := elastic.Get("qyxy", "qyxy", fmt.Sprintf(`{"query":{"bool":{"should":[{"term":{"company_name":"%s"}},{"term":{"hname":"%s"}}],"minimum_should_match":1}},"_source":["name","_id","nseo_id","capital","company_phone"],"size":1}`, v, v))
  925. if rData != nil && len(*rData) == 1 {
  926. if entId := util.ObjToString((*rData)[0]["_id"]); entId != "" {
  927. entIdArr = append(entIdArr, encrypt.EncodeArticleId2ByCheck(util.ObjToString((*rData)[0]["_id"])))
  928. winnerMap[v] = encrypt.EncodeArticleId2ByCheck(util.ObjToString((*rData)[0]["_id"]))
  929. if !b {
  930. winnerSeoMap[v] = (*rData)[0]["nseo_id"]
  931. }
  932. }
  933. }
  934. }
  935. } else {
  936. for k, v := range eidList {
  937. vstr := util.ObjToString(v)
  938. if vstr == "-" || vstr == "" {
  939. continue
  940. }
  941. winnerMap[swinnerArr[k]] = encrypt.EncodeArticleId2ByCheck(vstr)
  942. if !b {
  943. winnerSeoMap[swinnerArr[k]] = EsSeoId(true, vstr)
  944. }
  945. }
  946. }
  947. obj["entId"] = entIdArr
  948. obj["winnerMap"] = winnerMap
  949. obj["winnerSeoMap"] = winnerSeoMap
  950. }
  951. }
  952. //移动端需要处理--剑鱼币
  953. if b && from_userid != "" && se.Decode4Hex(from_userid) != "" && se.Decode4Hex(from_userid) != userId && util.ObjToString(obj["subtype"]) != "拟建" { //分享开打的
  954. article_id := encrypt.CommonDecodeArticle(stype, id)[0]
  955. key := fmt.Sprintf("integral_article_%s_%s_%s", article_id, from_userid, userId)
  956. if redis.Incr(redisLimitation, key) == 1 {
  957. redis.SetExpire(redisLimitation, key, 60*60*24)
  958. err := jy.Publish(public.Mgo_Log, config.Sysconfig["nsq"].(string), config.Sysconfig["nsq_topic"].(string), jy.Jyweb_article_open, se.Decode4Hex(from_userid), jy.Jywx_node1, nil)
  959. if err != nil {
  960. log.Println("nsq队列写入失败-->", jy.Jyweb_article_open, se.Decode4Hex(from_userid))
  961. }
  962. }
  963. }
  964. }
  965. // disWord 为空时处理
  966. func disWordNil(disWord, userId string) string {
  967. var from_userid string
  968. redisDis := redis.GetStr(redisLimitation, "DIS_"+disWord[1:])
  969. if redisDis != "" {
  970. suffix := disWord[len(disWord)-3:]
  971. //公告三级页处理
  972. if suffix == suffix_msgt {
  973. effectiveTimeStr := strings.Split(redisDis, "##")[3]
  974. effectiveTime, _ := strconv.ParseInt(effectiveTimeStr, 10, 64)
  975. //是否计算佣金
  976. if time.Now().Unix() <= effectiveTime {
  977. belongUserId := strings.Split(redisDis, "##")[1]
  978. //if (belongUserId != userId) {
  979. public.Mysql.ExecTx("口号使用", func(tx *sql.Tx) bool {
  980. //口号是否使用过
  981. wordInfo := public.Mysql.Find("dis_word", map[string]interface{}{"userId": userId, "password": disWord}, "id", "", 0, 0)
  982. if len(*wordInfo) == 0 {
  983. //新增口号使用
  984. start_time := time.Now().Format(DateFullLayout)
  985. termValidityInt, _ := strconv.Atoi(fmt.Sprint(config.Sysconfig["termValidity"]))
  986. stop_time := TimeProcessing(time.Now().Format(DateFullLayout), termValidityInt).Format(DateFullLayout)
  987. insert := map[string]interface{}{
  988. "password": disWord,
  989. "userId": userId,
  990. "belong_userid": belongUserId,
  991. "start_time": start_time,
  992. "stop_time": stop_time,
  993. }
  994. insert_1 := public.Mysql.InsertByTx(tx, "dis_word", insert) //口号使用表
  995. log.Println("插入口号使用表", insert_1)
  996. from_userid = se.Encode2Hex(belongUserId)
  997. }
  998. return true
  999. })
  1000. }
  1001. //}
  1002. }
  1003. }
  1004. return from_userid
  1005. }
  1006. // 检查用户是否关注
  1007. func CheckUserIsSubscribe(openid string) bool {
  1008. user, ok := mongodb.FindOneByField("user", map[string]interface{}{
  1009. "i_appid": 2,
  1010. "s_m_openid": openid,
  1011. "s_unionid": map[string]interface{}{"$ne": openid},
  1012. }, `{"i_ispush":1}`)
  1013. if ok && user != nil {
  1014. if (*user)["_id"] == nil || util.IntAllDef((*user)["i_ispush"], 1) == 0 {
  1015. return false
  1016. } else {
  1017. return true
  1018. }
  1019. }
  1020. return false
  1021. }
  1022. func (s *Short) Qr(t, id string) error {
  1023. w := s.ResponseWriter
  1024. w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate")
  1025. w.Header().Set("Pragma", "no-cache")
  1026. w.Header().Set("Expires", "0")
  1027. w.Header().Set("Content-Type", "image/png")
  1028. kds := s.GetString("kds")
  1029. industry := s.GetString("industry")
  1030. param := "?scan_source=pc"
  1031. if t == "force" {
  1032. param += "&ispcforceshare=1"
  1033. }
  1034. if kds != "" {
  1035. param += "&keywords=" + kds
  1036. }
  1037. if industry != "" {
  1038. param += "&industry=" + industry
  1039. }
  1040. ///article/bdprivate/BXXXX 详情页
  1041. if strings.Contains(s.Refer(), "bdprivate") {
  1042. bdprivateId := encrypt.EncodeArticleId2ByCheck(encrypt.CommonDecodeArticle("bdprivate", id)[0])
  1043. if bdprivateId != "" {
  1044. id = bdprivateId
  1045. }
  1046. }
  1047. data := config.Sysconfig["webdomain"].(string) + "/article/content/" + url.QueryEscape(id) + ".html" + param
  1048. r, _ := qr.Encode(data, qr.M)
  1049. pngdat := r.PNG()
  1050. _, err := w.Write(pngdat)
  1051. return err
  1052. }
  1053. func (s *Short) Replication() {
  1054. userId, OK := s.GetSession("userId").(string)
  1055. if OK && userId != "" {
  1056. mongodb.Save("copyaction", map[string]interface{}{
  1057. "userid": userId,
  1058. "createtime": time.Now().Unix(),
  1059. "url": s.Request.Referer(),
  1060. "client": s.Header("User-Agent"),
  1061. })
  1062. }
  1063. }
  1064. func isbid(typ interface{}) bool {
  1065. if typ != nil {
  1066. subtype := util.ObjToString(typ)
  1067. if subtype == "中标" || subtype == "合同" || subtype == "成交" {
  1068. return true
  1069. }
  1070. }
  1071. return false
  1072. }
  1073. // 中标企业库
  1074. func getwinnertel(company interface{}) string {
  1075. if company != nil {
  1076. data, _ := public.Mgo_Ent.FindOne("winner_enterprise", map[string]interface{}{
  1077. "company_name": util.ObjToString(company),
  1078. })
  1079. if (*data)["company_phone"] != nil {
  1080. return util.ObjToString((*data)["company_phone"])
  1081. }
  1082. }
  1083. return ""
  1084. }
  1085. func GetUserId(openid string) string {
  1086. data, ok := public.MQFW.FindOne("user", map[string]interface{}{"s_m_openid": openid})
  1087. if data != nil && len(*data) > 0 && ok {
  1088. userid := mg.BsonIdToSId((*data)["_id"])
  1089. return userid
  1090. }
  1091. return ""
  1092. }
  1093. func RemoveDuplicatesAndEmpty(a []string) (ret []string) {
  1094. a_len := len(a)
  1095. for i := 0; i < a_len; i++ {
  1096. if (i > 0 && a[i-1] == a[i]) || len(a[i]) == 0 {
  1097. continue
  1098. }
  1099. ret = append(ret, a[i])
  1100. }
  1101. return
  1102. }
  1103. // 该节点是否留资
  1104. func hasRetainedCapital(uid string, source []string) bool {
  1105. if count, err := mongodb.CountByErr("saleLeads", map[string]interface{}{"userid": uid, "source": map[string]interface{}{"$in": source}}); err != nil || count > 0 {
  1106. return true
  1107. }
  1108. return false
  1109. }
  1110. func isInStringArr(arr []string, key string) bool {
  1111. for _, v := range arr {
  1112. if v == key {
  1113. return true
  1114. }
  1115. }
  1116. return false
  1117. }
  1118. func ReplaceStringByRegex(str, rule, replace string) (string, error) {
  1119. reg, err := regexp.Compile(rule)
  1120. if reg == nil || err != nil {
  1121. return "", errors.New("正则MustCompile错误:" + err.Error())
  1122. }
  1123. return reg.ReplaceAllString(str, replace), nil
  1124. }
  1125. // 未登录用户进行数据过滤 name 配置文件
  1126. func Filter(obj map[string]interface{}) map[string]interface{} {
  1127. detail := fmt.Sprint(obj["detail"])
  1128. mosaicText := fmt.Sprintf(`<span style="color:#2ABED1;">%s</span>`, util.ObjToString(config.Sysconfig["detailMosaic"]))
  1129. detailText := fmt.Sprintf(`<span class="noLoginMosaic" style="color: #2ABED1;">%s</span>`, util.ObjToString(config.Sysconfig["detailMosaic"]))
  1130. //for k, _ := range obj {
  1131. // if ok, _ := detailNeedMosaic[k].(bool); ok {
  1132. // if util.ObjToString(obj[k]) != "" {
  1133. // detail = strings.ReplaceAll(detail, util.ObjToString(obj[k]), detailText)
  1134. // }
  1135. // //中标企业信息
  1136. // if k == "winnerMap" && obj[k] != nil {
  1137. // winnerNewMap := map[string]interface{}{}
  1138. // winnerMap := util.ObjToMap(obj[k])
  1139. // for _, wv := range *winnerMap {
  1140. // winnerNewMap[mosaicText] = wv
  1141. // }
  1142. // obj[k] = winnerNewMap
  1143. // } else {
  1144. // obj[k] = mosaicText
  1145. // }
  1146. // }
  1147. //}
  1148. //
  1149. if detailNeedMosaic == nil {
  1150. detailNeedMosaic, _ = config.Sysconfig["detailNeedMosaic"].(map[string]interface{})
  1151. }
  1152. for dk, dv := range detailNeedMosaic {
  1153. if !dv.(bool) {
  1154. continue
  1155. }
  1156. if obj["package"] != nil {
  1157. pk := util.ObjToMap(obj["package"])
  1158. for _, pv := range *pk {
  1159. if pv != nil {
  1160. if page := util.ObjToMap(pv); page != nil {
  1161. if (*page)[dk] != nil {
  1162. (*page)[dk] = mosaicText
  1163. }
  1164. delete(*page, "text")
  1165. }
  1166. }
  1167. }
  1168. }
  1169. //if util.ObjToString(obj[dk]) != "" {
  1170. // detail = strings.ReplaceAll(detail, util.ObjToString(obj[dk]), detailText)
  1171. //}
  1172. if util.InterfaceToStr(obj[dk]) != "" {
  1173. value, b := obj[dk].(float64)
  1174. if b {
  1175. replaceStr := fmt.Sprintf("%v", int64(value))
  1176. detail = strings.ReplaceAll(detail, replaceStr, detailText)
  1177. } else {
  1178. detail = strings.ReplaceAll(detail, util.InterfaceToStr(obj[dk]), detailText)
  1179. }
  1180. }
  1181. //中标企业信息
  1182. if dk == "winnerMap" {
  1183. winnerNewMap := map[string]interface{}{}
  1184. if obj[dk] != nil {
  1185. winnerMap := util.ObjToMap(obj[dk])
  1186. for _, wv := range *winnerMap {
  1187. winnerNewMap[mosaicText] = wv
  1188. }
  1189. }
  1190. obj[dk] = winnerNewMap
  1191. } else {
  1192. obj[dk] = mosaicText
  1193. }
  1194. }
  1195. obj["detail"] = detail
  1196. return obj
  1197. }
  1198. // 拟建采购意向用户进行数据过滤 name 配置文件
  1199. func otherFilter(obj map[string]interface{}, isLogin bool) map[string]interface{} {
  1200. txt := util.If(isLogin, "解锁会员查看", "登陆后解锁会员查看").(string)
  1201. detail := fmt.Sprint(obj["detail"])
  1202. mosaicText := fmt.Sprintf(`<span class="highlight-text otherMosaic">%s</span>`, txt)
  1203. detailText := fmt.Sprintf(`<span class="highlight-text otherMosaic">%s</span>`, txt)
  1204. var (
  1205. projectinfo map[string]interface{}
  1206. )
  1207. var otherMosaic map[string]interface{}
  1208. if obj["subtype"] == "拟建" {
  1209. otherMosaic, _ = config.Sysconfig["planBuildMosaic"].(map[string]interface{})
  1210. projectinfo, _ = obj["projectinfo"].(map[string]interface{}) //1.项目信息打码处理
  1211. } else if obj["subtype"] == "采购意向" {
  1212. otherMosaic, _ = config.Sysconfig["purchaseMosaic"].(map[string]interface{})
  1213. procurementlist, _ := obj["procurementlist"].([]interface{})
  1214. for _, vs := range procurementlist { //1.采购意向清单数据集打码处理
  1215. vsMap, _ := vs.(map[string]interface{})
  1216. for _, vsq := range vsMap {
  1217. if vs1, ok := vsq.(string); ok && vs1 != "" {
  1218. detail = strings.ReplaceAll(detail, util.InterfaceToStr(vsq), detailText)
  1219. }
  1220. }
  1221. }
  1222. delete(obj, "procurementlist")
  1223. }
  1224. for dk, dv := range otherMosaic {
  1225. if !dv.(bool) {
  1226. continue
  1227. }
  1228. if vs, ok := projectinfo[dk]; ok && vs != nil && vs != "" {
  1229. detail = strings.ReplaceAll(detail, util.InterfaceToStr(vs), detailText)
  1230. projectinfo[dk] = mosaicText
  1231. }
  1232. if vs, ok := obj[dk]; ok && vs != nil && vs != "" {
  1233. value, b := obj[dk].(float64)
  1234. if b {
  1235. replaceStr := fmt.Sprintf("%v", int64(value))
  1236. detail = strings.ReplaceAll(detail, replaceStr, detailText)
  1237. } else {
  1238. detail = strings.ReplaceAll(detail, util.InterfaceToStr(obj[dk]), detailText)
  1239. }
  1240. }
  1241. obj[dk] = mosaicText
  1242. }
  1243. if obj["subtype"] == "拟建" {
  1244. for k := range projectinfo {
  1245. if _, ok := otherMosaic[k]; !ok {
  1246. delete(projectinfo, k)
  1247. }
  1248. }
  1249. obj["projectinfo"] = projectinfo
  1250. }
  1251. obj["detail"] = detail
  1252. return obj
  1253. }
  1254. // 未登录用户进行数据过滤 name 配置文件
  1255. func SearchFilter(obj map[string]interface{}) map[string]interface{} {
  1256. //detail := fmt.Sprint(obj["detail"])
  1257. //mosaicText := fmt.Sprintf(`<span style="cursor:pointer;">%s</span>`, util.ObjToString(config.Sysconfig["detailMosaic"]))
  1258. //for k, _ := range obj {
  1259. // needMosaic, _ := config.Sysconfig["detailNeedMosaic"].(map[string]interface{})
  1260. // if ok, _ := needMosaic[k].(bool); ok {
  1261. // //if util.ObjToString(obj[k]) != "" {
  1262. // // detail = strings.ReplaceAll(detail, util.ObjToString(obj[k]), mosaicText)
  1263. // // //敏感词过滤
  1264. // //}
  1265. // if k == "winnerMap" {
  1266. // winnerMap, _ := obj[k].(map[string]interface{})
  1267. // mosaicMap := map[string]interface{}{}
  1268. // for i := 0; i < len(winnerMap); i++ {
  1269. // mosaicMap[mosaicText] = mosaicText
  1270. // }
  1271. // obj["winnerMap"] = mosaicMap
  1272. // } else {
  1273. // obj[k] = mosaicText
  1274. // }
  1275. //
  1276. // }
  1277. //}
  1278. //数字打码
  1279. //detail = RegDetail(detail)
  1280. //detail = fsw.Repl(detail)
  1281. //obj["detail"] = detail
  1282. if detailNeedMosaic == nil {
  1283. detailNeedMosaic, _ = config.Sysconfig["detailNeedMosaic"].(map[string]interface{})
  1284. }
  1285. for dk, dv := range detailNeedMosaic {
  1286. if !dv.(bool) {
  1287. continue
  1288. }
  1289. //中标企业信息
  1290. if dk == "winnerMap" {
  1291. winnerNewMap := map[string]interface{}{}
  1292. if obj[dk] != nil {
  1293. winnerMap := util.ObjToMap(obj[dk])
  1294. for _, wv := range *winnerMap {
  1295. winnerNewMap[util.ObjToString(config.Sysconfig["detailMosaic"])] = wv
  1296. }
  1297. }
  1298. obj[dk] = winnerNewMap
  1299. } else {
  1300. obj[dk] = util.ObjToString(config.Sysconfig["detailMosaic"])
  1301. }
  1302. }
  1303. return obj
  1304. }
  1305. func (s *Short) NologinArticle(stype, id string) error {
  1306. sess := s.Session().GetMultiple()
  1307. userId := util.ObjToString(sess["userId"])
  1308. sids := encrypt.CommonDecodeArticle(stype, id)
  1309. bm := mobileReg.MatchString(s.Header("User-Agent"))
  1310. if len(sids) == 0 || (len(sids) > 0 && sids[0] == "") {
  1311. return s.Redirect(getErrPageUrl(bm, DecodeErr), 302)
  1312. }
  1313. if detailNeedMosaic == nil {
  1314. detailNeedMosaic, _ = config.Sysconfig["detailNeedMosaic"].(map[string]interface{})
  1315. }
  1316. if userId != "" { //已登录用户直接跳转至正常三级页
  1317. return s.LoginCommon(sess, stype, id, bm) //是否是移动端
  1318. }
  1319. return s.NologinCommon(userId, stype, id, sids[0], bm)
  1320. }
  1321. func (s *Short) NologinCommon(userId, stype, id, sid string, isMobile bool) error {
  1322. tg := &Tags{}
  1323. var ipTrue bool
  1324. ips := strings.Split(util.GetIp(s.Request), ",")
  1325. if len(ips) > 0 {
  1326. ipTrue = config.IpList.Match(ips[0])
  1327. }
  1328. catchKey := fmt.Sprintf("jypcdetail_nologin_%s_%s_%v", stype, sid, ipTrue)
  1329. if res := redis.Get(redisLimitation, catchKey); res == nil || res == "" {
  1330. industry := s.GetString("industry")
  1331. var shareid = s.GetString("id")
  1332. if len(shareid) == 0 {
  1333. shareid = "10"
  1334. }
  1335. s.T["canRead"] = true
  1336. s.T["logid"] = config.Seoconfig["jysskzy"].(string)
  1337. s.T["shareid"] = se.EncodeString(shareid)
  1338. //s.T["keywords"] = s.GetString("kds")
  1339. s.DisableHttpCache()
  1340. po, bo, wo, obj := pcVRT(sid, industry, stype, false, false)
  1341. if obj != nil && len(obj) > 0 {
  1342. //阳光采购 网站的数据 未登录不能访问
  1343. if util.InterfaceToStr(obj["infoattribute"]) == "zc_cgxx" { //&& util.IntAll(obj["is_yg_new"]) == 1
  1344. return s.Redirect("/", 301)
  1345. }
  1346. // p397 未登录不能查看拟建项目
  1347. if !ipTrue && (obj["subtype"] == "采购意向" || obj["subtype"] == "拟建") { //未登录拟建 采购意向 遮罩
  1348. obj = map[string]interface{}{
  1349. "winnerTitle": obj["winner"],
  1350. "buyerTitle": obj["buyer"],
  1351. "projectnameTitle": obj["projectname"],
  1352. "projectcodeTitle": obj["projectcode"],
  1353. "title": obj["title"],
  1354. "_id": obj["_id"],
  1355. "subtype": obj["subtype"],
  1356. "stypeadd": obj["stypeadd"],
  1357. "originalShow": false,
  1358. }
  1359. s.T["canRead"] = false
  1360. } else {
  1361. FieldProcessing(obj, "", industry, id, "", userId, stype, false)
  1362. if userId == "" {
  1363. obj["winnerTitle"] = obj["winner"]
  1364. obj["buyerTitle"] = obj["buyer"]
  1365. obj["projectnameTitle"] = obj["projectname"]
  1366. obj["projectcodeTitle"] = obj["projectcode"]
  1367. if !ipTrue { //非白名单用户
  1368. obj = Filter(obj)
  1369. }
  1370. //obj["description"] = fmt.Sprintf("%s,%s。", obj["title"], baseInfo(obj))
  1371. }
  1372. obj["agency"] = ""
  1373. if obj["publishtime"] != nil {
  1374. obj["publishtimeShorDate"] = time.Unix(util.Int64All(obj["publishtime"]), 0).Format(date.Date_Short_Layout)
  1375. }
  1376. }
  1377. if len(po) > 0 {
  1378. s.T["projectOther"] = po
  1379. }
  1380. if len(bo) > 0 {
  1381. s.T["buyerOther"] = bo
  1382. }
  1383. if len(wo) > 0 {
  1384. s.T["winnerOther"] = wo
  1385. }
  1386. obj["urlpath"] = s.Uri()
  1387. obj["industry"] = industry
  1388. obj["keywords"] = KeyWordHandle(obj)
  1389. obj["description"] = DescriptionHandle("nologin", obj)
  1390. s.T["obj"] = obj
  1391. s.T["url"] = s.Uri()
  1392. s.T["newBidInfoList"] = tg.GetNewBidInfo()
  1393. s.T["industryInfoList"] = tg.GetConsult()
  1394. s.T["hotLabelList"] = tg.GetHotLabel(30)
  1395. s.T["simpleTemplateData"] = map[string]interface{}{
  1396. "obj": obj,
  1397. }
  1398. content, _ := s.Render4Cache("/pc/tags/detail.html", &s.T)
  1399. redis.Put(redisLimitation, catchKey, string(content), 60*2)
  1400. return s.SetBody(content)
  1401. } else {
  1402. return s.Redirect(getErrPageUrl(isMobile, QueryErr), 302)
  1403. }
  1404. } else {
  1405. return s.SetBody([]byte(res.(string)))
  1406. }
  1407. }
  1408. /*
  1409. TDK description
  1410. */
  1411. func baseInfo(obj map[string]interface{}) string {
  1412. info := ""
  1413. info += "省份:"
  1414. //{{if eq .T.obj.area "A"}}全国{{else}}{{.T.obj.area}}{{end}}
  1415. if area := util.ObjToString(obj["area"]); area == "A" {
  1416. info += "全国"
  1417. } else {
  1418. info += area
  1419. }
  1420. info += ",城市:" + util.ObjToString(obj["city"])
  1421. info += ",招标代理机构:" + util.ObjToString(obj["agency"])
  1422. info += ",项目名称:" + util.ObjToString(obj["projectname"])
  1423. info += ",采购单位:" + util.ObjToString(obj["buyer"])
  1424. info += ",采购联系人:" + util.ObjToString(obj["buyerperson"])
  1425. info += ",采购电话:" + util.ObjToString(obj["buyertel"])
  1426. if obj["package"] == nil {
  1427. info += ",项目预算(元):" + util.ObjToString(obj["budget"])
  1428. }
  1429. if util.ObjToString(obj["subtype"]) == "单一" && util.ObjToString(obj["package"]) == "" {
  1430. info += ",拟定单一来源采购供应商:" + util.ObjToString(obj["winner"])
  1431. }
  1432. subtype := util.ObjToString(obj["subtype"])
  1433. if subtype == "中标" || subtype == "成交" || subtype == "合同" {
  1434. if obj["winnerMap"] != nil {
  1435. info += ",中标单位:"
  1436. i := 0
  1437. for k := range *util.ObjToMap(obj["winnerMap"]) {
  1438. i++
  1439. info += k
  1440. if i != len(*util.ObjToMap(obj["winnerMap"])) {
  1441. info += "、"
  1442. }
  1443. }
  1444. }
  1445. if obj["bidamount"] != nil {
  1446. info += ",中标金额(元):" + util.ObjToString(obj["bidamount"])
  1447. }
  1448. if obj["bidamount"] != nil {
  1449. info += ",联系方式:" + util.ObjToString(obj["bidamount"])
  1450. }
  1451. }
  1452. return info
  1453. }
  1454. // 分段匹配数字打码
  1455. func RegDetail(html string) string {
  1456. mosaicText := util.ObjToString(config.Sysconfig["detailMosaicTxt"])
  1457. reg := regexp.MustCompile("<[^<>]{1,1000}>") //分段正则
  1458. s := reg.FindAllStringIndex(html, -1) //全文匹配分段
  1459. if len(s) > 0 { //走分段替换
  1460. arr := []string{}
  1461. index := 0
  1462. for _, v := range s {
  1463. if len(v) == 2 {
  1464. // log.Println(html[index:v[0]])
  1465. txt, _ := ReplaceStringByRegex(html[index:v[0]], "[0-9]+", mosaicText)
  1466. arr = append(arr, txt) //替换
  1467. arr = append(arr, html[v[0]:v[1]])
  1468. index = v[1]
  1469. }
  1470. }
  1471. return strings.Join(arr, "")
  1472. }
  1473. return ""
  1474. }
  1475. func KeyWordHandle(obj map[string]interface{}) string {
  1476. keywordArr := []string{}
  1477. owner := util.InterfaceToStr(obj["owner"])
  1478. buyer := util.InterfaceToStr(obj["buyer"])
  1479. if buyer == "" {
  1480. buyer = owner
  1481. }
  1482. if buyer != "" && buyer != config.Sysconfig["detailMosaicTxt"] {
  1483. keywordArr = append(keywordArr, buyer)
  1484. }
  1485. if util.InterfaceToStr(obj["s_winner"]) != "" && util.InterfaceToStr(obj["s_winner"]) != config.Sysconfig["detailMosaicTxt"] {
  1486. keywordArr = append(keywordArr, util.InterfaceToStr(obj["s_winner"]))
  1487. }
  1488. if obj["purchasinglist"] != nil && obj["purchasinglist"] != "" {
  1489. i := 0
  1490. for _, v := range gconv.SliceMap(obj["purchasinglist"]) {
  1491. if i == 5 {
  1492. break
  1493. }
  1494. if util.InterfaceToStr(v["itemname"]) != "" && util.InterfaceToStr(obj["s_winner"]) != config.Sysconfig["detailMosaicTxt"] {
  1495. keywordArr = append(keywordArr, util.InterfaceToStr(v["itemname"]))
  1496. i++
  1497. }
  1498. }
  1499. }
  1500. if util.InterfaceToStr(obj["subtype"]) != "" && util.InterfaceToStr(obj["subtype"]) != "其它" {
  1501. keywordArr = append(keywordArr, TypeCodeMap[util.InterfaceToStr(obj["subtype"])])
  1502. }
  1503. if util.InterfaceToStr(obj["area"]) != "" {
  1504. keywordArr = append(keywordArr, util.InterfaceToStr(obj["area"])+"招标")
  1505. }
  1506. if util.InterfaceToStr(obj["city"]) != "" {
  1507. keywordArr = append(keywordArr, util.InterfaceToStr(obj["city"])+"招标")
  1508. }
  1509. keywordArr = append(keywordArr, "剑鱼标讯")
  1510. keyword := strings.Join(keywordArr, ",")
  1511. return keyword
  1512. }
  1513. func DescriptionHandle(stype string, obj map[string]interface{}) string {
  1514. description := ""
  1515. publishtime := util.Int64All(obj["l_publishtime"])
  1516. if publishtime == 0 {
  1517. publishtime = util.Int64All(obj["publishtime"])
  1518. }
  1519. pushTime := time.Unix(publishtime, 0)
  1520. title := util.InterfaceToStr(obj["title"])
  1521. owner := util.InterfaceToStr(obj["owner"])
  1522. buyer := util.InterfaceToStr(obj["buyer"])
  1523. if buyer == "" {
  1524. buyer = owner
  1525. }
  1526. s_winner := util.InterfaceToStr(obj["s_winner"])
  1527. area := util.InterfaceToStr(obj["area"])
  1528. city := util.InterfaceToStr(obj["city"])
  1529. if stype == "bdprivate" {
  1530. //bdprivate
  1531. //{项目标题},采购单位:{采购单位名称},成交供应商:{中标企业名称},公告日期:{公告日期}。
  1532. descriptionArr := []string{}
  1533. if title != "" {
  1534. descriptionArr = append(descriptionArr, strLimitRune(title, g.Cfg().MustGet(context.TODO(), "seo.description.titleLimit", 48).Int()))
  1535. }
  1536. if buyer != "" {
  1537. descriptionArr = append(descriptionArr, fmt.Sprintf("采购单位:%s", buyer))
  1538. }
  1539. if s_winner != "" {
  1540. descriptionArr = append(descriptionArr, fmt.Sprintf("成交供应商:%s", s_winner))
  1541. }
  1542. if publishtime != 0 {
  1543. descriptionArr = append(descriptionArr, fmt.Sprintf("公告日期:%s", pushTime.Format("2006年01月02日")))
  1544. }
  1545. descriptionArr = append(descriptionArr, "查看该项目信息详情请访问剑鱼标讯官网。")
  1546. description = strings.Join(descriptionArr, ",")
  1547. } else {
  1548. //descriptionStr = "%s,项目所属地区是%s%s,项目采购单位是%s,项目发布时间是%s"
  1549. descriptionArr := []string{}
  1550. if title != "" {
  1551. descriptionArr = append(descriptionArr, strLimitRune(title, g.Cfg().MustGet(context.TODO(), "seo.description.titleLimit", 48).Int()))
  1552. }
  1553. if area != "" || city != "" {
  1554. descriptionArr = append(descriptionArr, fmt.Sprintf("项目所属地区是%s%s", area, city))
  1555. }
  1556. if buyer != "" {
  1557. descriptionArr = append(descriptionArr, fmt.Sprintf("项目采购单位是%s", buyer))
  1558. }
  1559. if publishtime != 0 {
  1560. descriptionArr = append(descriptionArr, fmt.Sprintf("项目发布时间是%s", pushTime.Format("2006年01月02日")))
  1561. }
  1562. descriptionArr = append(descriptionArr, "查看该项目信息详情请访问剑鱼标讯官网。")
  1563. description = strings.Join(descriptionArr, ",")
  1564. }
  1565. return description
  1566. }
  1567. func strLimitRune(str string, length int, suffix ...string) string {
  1568. runes := []rune(str)
  1569. if len(runes) < length {
  1570. return str
  1571. }
  1572. suffixStr := "..."
  1573. if len(suffix) > 0 {
  1574. suffixStr = suffix[0]
  1575. }
  1576. return string(runes[0:length]) + suffixStr
  1577. }
  1578. func GetTDK(pageType, sid string) (t, k, d string) {
  1579. tdkCacheKey := fmt.Sprintf("detail_tkd_%s_%s", pageType, sid)
  1580. if tdk := redis.GetStr(redisLimitation, tdkCacheKey); tdk != "" {
  1581. tdks := strings.Split(tdk, "##")
  1582. if len(tdks) == 3 {
  1583. t = tdks[0]
  1584. k = tdks[1]
  1585. d = tdks[2]
  1586. return
  1587. }
  1588. }
  1589. obj, ok := public.Mgo_Bidding.FindById(public.DbConf.Mongodb.Bidding.Collection, sid, nil)
  1590. if ok && (obj == nil || *obj == nil || len(*obj) == 0) {
  1591. obj, ok = public.Mgo_Bidding.FindById(public.DbConf.Mongodb.Bidding.Collection_back, sid, nil)
  1592. }
  1593. if ok && obj != nil && len(*obj) > 2 {
  1594. t = util.InterfaceToStr((*obj)["title"])
  1595. k = KeyWordHandle(*obj)
  1596. d = DescriptionHandle(pageType, *obj)
  1597. } else {
  1598. t = "全国招标信息-招标采购公告大全-剑鱼标讯"
  1599. k = "招标网站,招标信息查询,剑鱼标讯,招标采购信息,招标大数据平台"
  1600. d = "剑鱼标讯是国内专业的招标大数据服务平台,专注于全国招标采购信息的搜索查询、订阅推送和数据定制化服务。提供涵盖拟在建项目、招标预告、招标公告、中标公告、政府采购、企业工商信息等多种信息类型,帮助企业全方位掌握市场动态变化。招投标大数据平台就用剑鱼标讯。"
  1601. }
  1602. redis.Put(redisLimitation, tdkCacheKey, fmt.Sprintf("%s##%s##%s", t, k, d), 24*60*60)
  1603. return
  1604. }