shorturl.go 43 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248
  1. package front
  2. import (
  3. "database/sql"
  4. "errors"
  5. "fmt"
  6. "github.com/gogf/gf/v2/util/gconv"
  7. "jy/src/jfw/config"
  8. "jy/src/jfw/wx"
  9. "log"
  10. "math/rand"
  11. "net/url"
  12. "strconv"
  13. "jy/src/jfw/jyutil"
  14. "app.yhyue.com/moapp/jypkg/public"
  15. util "app.yhyue.com/moapp/jybase/common"
  16. "app.yhyue.com/moapp/jybase/date"
  17. . "app.yhyue.com/moapp/jybase/mongodb"
  18. elastic "app.yhyue.com/moapp/jybase/es"
  19. "app.yhyue.com/moapp/jybase/fsw"
  20. "regexp"
  21. "strings"
  22. "time"
  23. "app.yhyue.com/moapp/jybase/encrypt"
  24. "app.yhyue.com/moapp/jybase/go-xweb/xweb"
  25. "app.yhyue.com/moapp/jybase/redis"
  26. "app.yhyue.com/moapp/jypkg/common/src/qfw/util/jy"
  27. "github.com/SKatiyar/qr"
  28. "go.mongodb.org/mongo-driver/bson"
  29. )
  30. type Short struct {
  31. *xweb.Action
  32. article xweb.Mapper `xweb:"/article/(\\w+)/(.*).html"` //([pm])
  33. qr xweb.Mapper `xweb:"/biddetail/(\\w+)/qr/(.+)"`
  34. replication xweb.Mapper `xweb:"/front/shorturl/replication"` //用户复制操作记录入库
  35. nologinArticle xweb.Mapper `xweb:"/nologin/(\\w+)/(.*).html"` //([pm]) 无需登录
  36. }
  37. var mobileReg = regexp.MustCompile("(?i)(Android|Mobile|Phone)")
  38. var DateFullLayout = "2006-01-02 15:04:05"
  39. var Map_stype = map[string]bool{
  40. "content": true,
  41. "entservice": true,
  42. "bdprivate": true,
  43. "mailprivate": true,
  44. "bdcontent": true,
  45. "indexcontent": true,
  46. "advancedProject": true,
  47. }
  48. var TypeCodeMap = map[string]string{
  49. "拟建": "拟建项目",
  50. "采购意向": "采购意向",
  51. "预告": "招标预告",
  52. "预审": "资格预审",
  53. "预审结果": "资格预审结果",
  54. "论证意见": "论证意见",
  55. "需求公示": "需求公示",
  56. "招标": "公开招标",
  57. "邀标": "邀请招标",
  58. "询价": "询价采购",
  59. "竞谈": "竞争性谈判",
  60. "单一": "单一来源采购",
  61. "竞价": "竞价公告",
  62. "变更": "变更公告",
  63. "中标": "中标公示",
  64. "成交": "成交公告",
  65. "废标": "废标公告",
  66. "流标": "流标公告",
  67. "合同": "合同公告信息",
  68. "验收": "验收公告信息",
  69. "违规": "违规信息",
  70. }
  71. var seoAgentReg = regexp.MustCompile("Baiduspider|360Spider|bingbot|Googlebot")
  72. func (s *Short) Article(stype, id string) error {
  73. userId, _ := s.GetSession("userId").(string)
  74. if (stype == "content" || stype == "indexcontent") && userId == "" {
  75. if seoAgentReg.MatchString(s.UserAgent()) {
  76. sids := encrypt.CommonDecodeArticle(stype, id)
  77. return s.NologinCommon("", stype, id, sids[0])
  78. } else {
  79. return s.Redirect("/notin/page")
  80. }
  81. }
  82. return s.LoginCommon(userId, stype, id)
  83. }
  84. func (s *Short) LoginCommon(userId, stype, id string) error {
  85. client := s.Header("User-Agent")
  86. bm := mobileReg.MatchString(client)
  87. //电脑端 剑鱼快照页面访问
  88. if stype == "content" && !bm {
  89. //工作桌面内嵌 快照页
  90. //老地址(地址不包含aside)且非工作桌面地址
  91. if !strings.Contains(s.Request.URL.String(), "aside") && !strings.Contains(s.Request.URL.String(), "page_workDesktop") {
  92. paramSuffix := ".html?aside=0"
  93. replaceStr := ".html"
  94. if strings.Contains(s.Request.URL.String(), "?") {
  95. replaceStr = ".html?"
  96. paramSuffix = ".html?aside=0&"
  97. }
  98. return s.Redirect(fmt.Sprintf("%s%s%s", config.Sysconfig["workDesktopUrl"].(string), config.Sysconfig["webdomain"].(string), url.QueryEscape(strings.Replace(s.Request.URL.String(), replaceStr, paramSuffix, 1))))
  99. }
  100. }
  101. //先判断是否有session
  102. source := s.GetString("source")
  103. disWord := s.GetString("disWord")
  104. aboutUrl := "/swordfish/about"
  105. //是否已经检查过,默认是检查过-true,分享过来的是未检查过-false
  106. // checkIsSubscribeFlag := true
  107. // if source == "app_infocontentshare" || source == "wx_infocontentshare" {
  108. // checkIsSubscribeFlag = false
  109. // }
  110. from_userid := ""
  111. if source != "" {
  112. aboutUrl += "?source=" + source
  113. if strings.Contains(source, "wx_infocontentshare") {
  114. decodeArr := encrypt.DecodeArticleId2ByCheck(id)
  115. if len(decodeArr) > 1 {
  116. from_userid = se.Encode2Hex(GetUserId(decodeArr[1])) //加密用户userid
  117. }
  118. } else if strings.Contains(source, "app_infocontentshare") {
  119. if from := s.GetString("from"); from != "" {
  120. from_userid = from
  121. }
  122. }
  123. aboutUrl += "&from=" + from_userid
  124. }
  125. if !Map_stype[stype] {
  126. s.Redirect("/not/nottype", 302)
  127. return nil
  128. } else if stype == "content" || stype == "bdcontent" || stype == "advancedProject" {
  129. if userId == "" {
  130. if s.GetString("state") == "wx" {
  131. //微信跳回来的
  132. if code := s.GetString("code"); code != "" {
  133. if openid := jyutil.Getopenid(code); openid != "" {
  134. if CheckUserIsSubscribe(openid) {
  135. FindUserAndCreateSess(openid, s.Session(), "wx", false, true)
  136. }
  137. }
  138. }
  139. } else if public.CheckWxBrowser(s.Request) {
  140. //所有参数都不再使用,跳到微信验证用户
  141. return s.Redirect(fmt.Sprintf(config.Wxoauth, url.QueryEscape(s.Site()+s.Url()), "wx"), 302)
  142. }
  143. }
  144. if disWord != "" {
  145. from_userid = disWordNil(disWord, userId)
  146. }
  147. if userId == "" { //} && !regclient.MatchString(client) { //没有用户session //搜索引擎让过
  148. s.Session().Set("referer", s.Request.RequestURI)
  149. if bm { //是否是移动端访问
  150. s.Redirect(aboutUrl, 302)
  151. } else {
  152. if stype == "bdcontent" {
  153. var retMap = make(map[string]interface{})
  154. stype = "content"
  155. _id := encrypt.CommonDecodeArticle(stype, id)[0]
  156. _, _, _, obj := pcVRT(_id, "", stype, true)
  157. if obj != nil && len(obj) > 0 {
  158. retMap["_id"] = id
  159. retMap["title"], _ = obj["title"].(string)
  160. retMap["area"], _ = obj["area"].(string)
  161. retMap["subtype"], _ = obj["subtype"].(string)
  162. retMap["subscopeclass"], _ = obj["s_subscopeclass"].(string)
  163. retMap["publishtime"] = util.IntAll(obj["publishtime"])
  164. retMap["keywords"] = KeyWordHandle(obj)
  165. retMap["description"] = DescriptionHandle(stype, obj)
  166. }
  167. s.T["shareid"] = config.Seoconfig["baiduSEM-p"].(string)
  168. s.T["logid"] = config.Seoconfig["baiduSEM-p"].(string)
  169. s.T["obj"] = retMap
  170. s.Render("/pc/biddetail_bd.html", &s.T)
  171. } else {
  172. s.Redirect("/notin/page", 302)
  173. }
  174. }
  175. return nil
  176. }
  177. if stype == "bdcontent" {
  178. stype = "content"
  179. }
  180. } else if stype == "entservice" { //大客户数据快照展示
  181. //se := util.SimpleEncrypt{"entservice"}
  182. sid := encrypt.SE3.DecodeString(id)
  183. if len(sid) == 0 || (len(sid) > 0 && sid == "") {
  184. s.Redirect("/notin/page", 302)
  185. return nil
  186. }
  187. catchKey := fmt.Sprintf("jypcdetail_%s_%s_%s", userId, stype, sid)
  188. if res := redis.Get("newother", catchKey); res == nil || res == "" {
  189. industry := s.GetString("industry")
  190. var shareid = s.GetString("id")
  191. if len(shareid) == 0 {
  192. shareid = "10"
  193. }
  194. s.T["logid"] = config.Seoconfig["jysskzy"].(string)
  195. s.T["shareid"] = se.EncodeString(shareid)
  196. s.T["keywords"] = s.GetString("kds")
  197. ssOpenid := s.Session().Get("s_m_openid")
  198. po, bo, wo, obj := pcVRT(sid, industry, stype, true)
  199. if obj != nil && len(obj) > 0 {
  200. if len(po) > 0 {
  201. s.T["projectOther"] = po
  202. }
  203. if len(bo) > 0 {
  204. s.T["buyerOther"] = bo
  205. }
  206. if len(wo) > 0 {
  207. s.T["winnerOther"] = wo
  208. }
  209. obj["urlpath"] = s.Uri()
  210. obj["industry"] = industry
  211. if ssOpenid != nil {
  212. obj["ucbsId"] = encrypt.EncodeArticleId2ByCheck("ucbs#" + ssOpenid.(string) + "#" + id)
  213. }
  214. //if false && isbid(obj["subtype"]) {
  215. // //bidding表有数据就有,没有不再查此中标企业得其他信息--需求来自数据和质量
  216. // obj["winner_enttel"] = "" //getwinnertel(obj["winner"])
  217. //}
  218. //判断时间 //如果是seo页面超过时间访问的进入首页
  219. comeinTime := time.Unix(util.Int64All(obj["comeintime"]), 0)
  220. if stype == "indexcontent" {
  221. 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)) {
  222. return s.Redirect("/")
  223. }
  224. }
  225. FieldProcessing(obj, ssOpenid, industry, id, from_userid, userId, stype, false)
  226. if obj["projectname"] != nil {
  227. s.SetSession("projectname", obj["projectname"])
  228. }
  229. if obj["entidlist"] != nil { //大会员中标企业跳转至画像
  230. s_winner := util.ObjToString(obj["s_winner"])
  231. idObjs, _ := obj["entidlist"].([]interface{})
  232. winnerIdArr := []string{}
  233. for _, v := range strings.Split(s_winner, ",") {
  234. if v == "-" || !isInStringArr(util.ObjArrToStringArr(idObjs), v) {
  235. continue
  236. }
  237. winnerIdArr = append(winnerIdArr, encrypt.EncodeArticleId2ByCheck(v))
  238. obj["entIds"] = winnerIdArr
  239. }
  240. }
  241. if obj["publishtime"] != nil {
  242. obj["publishtimeShorDate"] = time.Unix(util.Int64All(obj["publishtime"]), 0).Format(date.Date_Short_Layout)
  243. }
  244. s.T["url"] = s.Uri()
  245. obj["keywords"] = KeyWordHandle(obj)
  246. obj["description"] = DescriptionHandle(stype, obj)
  247. s.T["obj"] = obj
  248. content, _ := s.Render4Cache("/pc/biddetail_rec.html", &s.T)
  249. redis.Put("newother", catchKey, string(content), 60*20)
  250. return s.SetBody(content)
  251. }
  252. } else {
  253. return s.SetBody([]byte(res.(string)))
  254. }
  255. }
  256. ssOpenid := s.Session().Get("s_m_openid")
  257. var (
  258. res *map[string]interface{}
  259. ok bool
  260. )
  261. if userId == "" && ssOpenid != nil {
  262. 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}`)
  263. if ok {
  264. userId = BsonIdToSId((*res)["_id"])
  265. }
  266. } else if userId != "" {
  267. //判断用户是否是vip
  268. res = jyutil.Compatible.Select(userId, `{"i_vip_status":1,"i_member_status":1,"s_m_phone":1,"s_phone":1,"l_vip_starttime":1}`)
  269. }
  270. entid := util.Int64All(s.GetSession("entId"))
  271. userPower := jy.GetBigVipUserBaseMsg(s.Session(), *config.Middleground)
  272. var (
  273. isEntnicheNew bool = userPower.EntIsNew //新版超级订阅
  274. isOldVip bool = false //新购超级订阅不能查看拟建项目详情页
  275. isVip bool = userPower.VipStatus > 0 //超级订阅
  276. isMember bool = userPower.Status > 0 //大会员
  277. isEntniche bool = userPower.EntnicheStatus > 0 //商机管理
  278. privatedata bool = userPower.PrivateGD //广东移动DICT 用户
  279. isEntService bool = userPower.Data.Ent.PowerSource > 0 && userPower.Data.Entniche.IsEntPower > 0 //商机管理服务
  280. )
  281. if res != nil && len(*res) > 0 {
  282. if isVip && util.Int64All((*res)["l_vip_starttime"]) < util.Int64All(config.Sysconfig["contextOldVipLimit"]) {
  283. isOldVip = true
  284. }
  285. }
  286. entId := util.IntAll(entid)
  287. if entId > 0 && userPower.EntInfo[entId] != nil {
  288. isEntniche = userPower.EntInfo[entId].Status == 1 && userPower.EntInfo[entId].IsPower
  289. isEntnicheNew = userPower.EntInfo[entId].IsNew && isEntniche
  290. if isEntService = userPower.EntInfo[entId].IsService && userPower.EntInfo[entId].IsPower; isEntService {
  291. isEntnicheNew = false
  292. isEntniche = false
  293. }
  294. }
  295. if !isEntniche && privatedata {
  296. isEntniche = true
  297. }
  298. s.T["isVip"] = isVip
  299. s.T["isMember"] = isMember
  300. s.T["isEntniche"] = isEntniche
  301. s.T["isEntnicheNew"] = isEntnicheNew
  302. s.T["isEntService"] = isEntService
  303. if bm {
  304. //判断有没有取关,取关的话,跳转到关于剑鱼标讯页面
  305. if ssOpenid != nil && ssOpenid != "" {
  306. isSubscribe := CheckUserIsSubscribe(ssOpenid.(string))
  307. if !isSubscribe {
  308. return s.Redirect(aboutUrl, 302)
  309. }
  310. //之前sessionkeep.go中没有放userId,造成关注有问题
  311. if userId == "" {
  312. FindUserAndCreateSess(ssOpenid.(string), s.Session(), "wx", false, true)
  313. }
  314. }
  315. surl := s.GetString("url")
  316. kds := s.GetString("keywords")
  317. industry := s.GetString("industry")
  318. var shareopenid, sid string
  319. sid_openid := encrypt.CommonDecodeArticle(stype, id)
  320. switch len(sid_openid) {
  321. case 0:
  322. s.Redirect(aboutUrl, 302)
  323. return nil
  324. default:
  325. shareopenid, sid = SwiDef(sid_openid)
  326. }
  327. s.T["keywords"] = kds
  328. if shareopenid != "" {
  329. s.T["shareopenid"] = shareopenid
  330. }
  331. myopenid, _ := s.Session().Get("s_m_openid").(string)
  332. if myopenid == "" {
  333. myopenid = shareopenid
  334. s.T["openid"] = myopenid //"-1"
  335. } else {
  336. s.T["openid"] = se.EncodeString(myopenid) //"-1"
  337. }
  338. mynickname, _ := s.GetSession("s_nickname").(string)
  339. myavatar, _ := s.GetSession("s_avatar").(string)
  340. s.T["nickname"] = mynickname
  341. s.T["avatar"] = myavatar
  342. s.T["signature"] = wx.SignJSSDK(s.Site() + s.Url())
  343. obj := wxvisitD(sid, userId, myopenid, stype, (isVip && isOldVip) || isMember || isEntniche)
  344. canRead := false
  345. if ((isVip && isOldVip) || isMember || isEntniche) || //老版本vip、大会员、商机管理
  346. ((isVip && !isOldVip) && (!(util.ObjToString(obj["subtype"]) == "拟建" || util.ObjToString(obj["subtype"]) == "采购意向"))) || //新超级订阅非采购意向”和“拟建项目”
  347. stype == "mailprivate" || stype == "indexcontent" || stype == "bdprivate" { //邮箱推送
  348. canRead = true
  349. } else {
  350. canRead = SeeDetailLimit(obj, userId, sid)
  351. }
  352. if stype == "advancedProject" {
  353. newCanRead := false
  354. //判断此用户是否有打开的权限
  355. newUserId := s.GetSession("base_user_id")
  356. pushData := public.BaseMysql.FindOne("leadproject_push", map[string]interface{}{"user_id": newUserId, "info_id": sid}, "id", "")
  357. //访问次数加1
  358. if pushData == nil {
  359. newCanRead = false
  360. } else {
  361. 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"])
  362. newCanRead = true
  363. }
  364. if newCanRead || canRead {
  365. obj = wxvisitD(sid, userId, myopenid, stype, true)
  366. canRead = true
  367. }
  368. s.T["canRead"] = canRead
  369. }
  370. if len(obj) > 0 {
  371. if canRead {
  372. FieldProcessing(obj, ssOpenid, industry, id, from_userid, userId, stype, true)
  373. //免费用户正文手机号替换
  374. if obj["site"] == "剑鱼信息发布平台" && !isMember {
  375. //采购电话中标单位电话置空
  376. if util.InterfaceToStr(obj["buyertel"]) != "" {
  377. obj["buyertel"] = "freeView"
  378. }
  379. if util.InterfaceToStr(obj["winnertel"]) != "" {
  380. obj["winnertel"] = "freeView"
  381. }
  382. //正文电话 手机号 邮箱处理
  383. if detail, _ := obj["detail"].(string); detail != "" {
  384. //手机号
  385. re1 := regexp.MustCompile("1[345789]{1}\\d{9}")
  386. detail1 := re1.ReplaceAllString(detail, `<span class="freeView">点击查看</span>`)
  387. code := util.InterfaceToStr(obj["projectcode"])
  388. if code != "" {
  389. detail1 = strings.ReplaceAll(detail1, code, "*********")
  390. }
  391. //座机
  392. re2 := regexp.MustCompile("((0\\d{2,3})-)(\\d{7,8})(-(\\d{3,}))?")
  393. detail2 := re2.ReplaceAllString(detail1, `<span class="freeView">点击查看</span>`)
  394. re4 := regexp.MustCompile("((400)-)(\\d{3,4}-)(\\d{3,})")
  395. detail4 := re4.ReplaceAllString(detail2, `<span class="freeView">点击查看</span>`)
  396. //邮箱
  397. 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})(\\]?)")
  398. detail3 := re3.ReplaceAllString(detail4, `<span class="freeView">点击查看</span>`)
  399. obj["detail"] = strings.ReplaceAll(strings.ReplaceAll(detail3, `<span class="freeView">点击查看</span><span class="freeView">点击查看</span>`, `<span class="freeView">点击查看</span>`), "*********", code)
  400. }
  401. }
  402. if obj["entidlist"] != nil { //大会员中标企业跳转至画像
  403. s_winner := util.ObjToString(obj["s_winner"])
  404. idObjs, _ := obj["entidlist"].([]interface{})
  405. winnerIdArr := []string{}
  406. for _, v := range strings.Split(s_winner, ",") {
  407. if v == "-" || !isInStringArr(util.ObjArrToStringArr(idObjs), v) {
  408. continue
  409. }
  410. winnerIdArr = append(winnerIdArr, encrypt.EncodeArticleId2ByCheck(v))
  411. obj["entIds"] = winnerIdArr
  412. }
  413. }
  414. s.T["advertcode"] = s.GetString("advertcode")
  415. } else {
  416. obj = map[string]interface{}{
  417. "title": obj["title"],
  418. "_id": obj["_id"],
  419. "subtype": obj["subtype"],
  420. }
  421. }
  422. //纠错随机回复
  423. recoveryRight, _ := config.Sysconfig["recoveryRight"].([]interface{})
  424. recVal := rand.New(rand.NewSource(time.Now().UnixNano())).Intn(len(recoveryRight))
  425. s.T["recVal"] = util.ObjToString(recoveryRight[recVal])
  426. s.T["advertImg"] = config.Sysconfig["advertImg"]
  427. s.T["advertName"] = config.Sysconfig["advertName"]
  428. s.T["advertUrl"] = config.Sysconfig["advertUrl"]
  429. s.T["canRead"] = canRead
  430. obj["industry"] = industry
  431. obj["keywords"] = KeyWordHandle(obj)
  432. obj["description"] = DescriptionHandle(stype, obj)
  433. s.T["obj"] = obj
  434. //获取打赏文案
  435. s.T["rewardText"], s.T["advertText"] = getRewardText()
  436. content, _ := s.Render4Cache("/weixin/wxinfocontent_rec.html", &s.T)
  437. return s.SetBody(content)
  438. }
  439. if surl != "" {
  440. return s.Redirect(surl)
  441. }
  442. } else {
  443. sids := encrypt.CommonDecodeArticle(stype, id)
  444. if len(sids) == 0 || (len(sids) > 0 && sids[0] == "") {
  445. s.Redirect("/notin/page", 302)
  446. return nil
  447. }
  448. sid := sids[0]
  449. //免费用户浏览三级页判断留资与浏览次数
  450. indust := s.GetString("industry")
  451. if userId != "" && stype == "indexcontent" { //已登录用户直接跳转至正常三级页
  452. return s.Redirect(fmt.Sprintf("/article/content/%s.html", encrypt.CommonEncodeArticle("content", sid)))
  453. }
  454. industry := s.GetString("industry")
  455. var shareid = s.GetString("id")
  456. if len(shareid) == 0 {
  457. shareid = "10"
  458. }
  459. s.T["logid"] = config.Seoconfig["jysskzy"].(string)
  460. s.T["shareid"] = se.EncodeString(shareid)
  461. s.T["keywords"] = s.GetString("kds")
  462. s.DisableHttpCache()
  463. po, bo, wo, obj := pcVRT(sid, industry, stype, isVip || isMember || isEntniche)
  464. if obj != nil && len(obj) > 0 {
  465. var node bool
  466. if ((isVip && isOldVip) || isMember || isEntniche) || //老版本vip、大会员、商机管理
  467. ((isVip && !isOldVip) && (!(util.ObjToString(obj["subtype"]) == "拟建" || util.ObjToString(obj["subtype"]) == "采购意向"))) || //新超级订阅非采购意向”和“拟建项目”
  468. stype == "mailprivate" || stype == "indexcontent" || stype == "bdprivate" { //邮箱推送
  469. node = true
  470. } else {
  471. _, _, _, objc := pcVRT(sid, indust, stype, isVip || isMember || isEntniche)
  472. node = SeeDetailLimit(objc, userId, sid)
  473. }
  474. if obj["publishtime"] != nil {
  475. obj["publishtimeShorDate"] = time.Unix(util.Int64All(obj["publishtime"]), 0).Format(date.Date_Short_Layout)
  476. }
  477. s.T["canRead"] = node
  478. if stype == "advancedProject" {
  479. canRead := false
  480. //判断此用户是否有打开的权限
  481. newUserId := s.GetSession("base_user_id")
  482. pushData := public.BaseMysql.FindOne("leadproject_push", map[string]interface{}{"user_id": newUserId, "info_id": sid}, "id", "")
  483. //访问次数加1
  484. if pushData == nil {
  485. canRead = false
  486. } else {
  487. 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"])
  488. canRead = true
  489. }
  490. if canRead || node {
  491. _, _, _, obj = pcVRT(sid, indust, stype, true)
  492. canRead = true
  493. node = canRead
  494. }
  495. s.T["canRead"] = canRead
  496. }
  497. if node {
  498. if len(po) > 0 {
  499. s.T["projectOther"] = po
  500. }
  501. if len(bo) > 0 {
  502. s.T["buyerOther"] = bo
  503. }
  504. if len(wo) > 0 {
  505. s.T["winnerOther"] = wo
  506. }
  507. //判断时间 //如果是seo页面超过时间访问的进入首页
  508. comeinTime := time.Unix(util.Int64All(obj["comeintime"]), 0)
  509. if stype == "indexcontent" {
  510. 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)) {
  511. return s.Redirect("/")
  512. }
  513. }
  514. FieldProcessing(obj, ssOpenid, industry, id, from_userid, userId, stype, false)
  515. //免费用户正文手机号替换
  516. if obj["site"] == "剑鱼信息发布平台" && !isMember {
  517. //采购电话中标单位电话置空
  518. if util.InterfaceToStr(obj["buyertel"]) != "" {
  519. obj["buyertel"] = "freeView"
  520. }
  521. if util.InterfaceToStr(obj["winnertel"]) != "" {
  522. obj["winnertel"] = "freeView"
  523. }
  524. //正文电话 手机号 邮箱处理
  525. if detail, _ := obj["detail"].(string); detail != "" {
  526. //手机号
  527. re1 := regexp.MustCompile("1[345789]{1}\\d{9}")
  528. detail1 := re1.ReplaceAllString(detail, `<span class="freeView">点击查看</span>`)
  529. code := util.InterfaceToStr(obj["projectcode"])
  530. if code != "" {
  531. detail1 = strings.ReplaceAll(detail1, code, "*********")
  532. }
  533. //座机
  534. re2 := regexp.MustCompile("((0\\d{2,3})-)(\\d{7,8})(-(\\d{3,}))?")
  535. detail2 := re2.ReplaceAllString(detail1, `<span class="freeView">点击查看</span>`)
  536. re4 := regexp.MustCompile("((400)-)(\\d{3,4}-)(\\d{3,})")
  537. detail4 := re4.ReplaceAllString(detail2, `<span class="freeView">点击查看</span>`)
  538. //邮箱
  539. 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})(\\]?)")
  540. detail3 := re3.ReplaceAllString(detail4, `<span class="freeView">点击查看</span>`)
  541. obj["detail"] = strings.ReplaceAll(strings.ReplaceAll(detail3, `<span class="freeView">点击查看</span><span class="freeView">点击查看</span>`, `<span class="freeView">点击查看</span>`), "*********", code)
  542. }
  543. }
  544. if obj["projectname"] != nil {
  545. s.SetSession("projectname", obj["projectname"])
  546. }
  547. if obj["entidlist"] != nil { //大会员中标企业跳转至画像
  548. s_winner := util.ObjToString(obj["s_winner"])
  549. idObjs, _ := obj["entidlist"].([]interface{})
  550. winnerIdArr := []string{}
  551. for _, v := range strings.Split(s_winner, ",") {
  552. if v == "-" || !isInStringArr(util.ObjArrToStringArr(idObjs), v) {
  553. continue
  554. }
  555. winnerIdArr = append(winnerIdArr, encrypt.EncodeArticleId2ByCheck(v))
  556. obj["entIds"] = winnerIdArr
  557. }
  558. }
  559. } else {
  560. obj = map[string]interface{}{
  561. "title": obj["title"],
  562. "_id": obj["_id"],
  563. "subtype": obj["subtype"],
  564. "stypeadd": obj["stypeadd"],
  565. }
  566. }
  567. obj["urlpath"] = s.Uri()
  568. obj["industry"] = industry
  569. if ssOpenid != nil {
  570. obj["ucbsId"] = encrypt.EncodeArticleId2ByCheck("ucbs#" + ssOpenid.(string) + "#" + id)
  571. }
  572. obj["keywords"] = KeyWordHandle(obj)
  573. obj["description"] = DescriptionHandle(stype, obj)
  574. s.T["obj"] = obj
  575. s.T["url"] = s.Uri()
  576. return s.Render("/pc/biddetail_rec.html", &s.T)
  577. }
  578. }
  579. return nil
  580. }
  581. func CNode(userId string) bool {
  582. if hasRetainedCapital(userId, "jyarticle_see3_plus") {
  583. return true
  584. }
  585. rM := map[string]interface{}{}
  586. rdata, ok := mongodb.Find("saleLeads", map[string]interface{}{
  587. "userid": userId,
  588. }, `{"createtime":-1}`, nil, false, 0, 10)
  589. if rdata != nil && len(*rdata) > 0 && ok {
  590. for _, v := range *rdata {
  591. for kk, vv := range v {
  592. if vv == nil {
  593. continue
  594. }
  595. if rM[kk] != nil {
  596. continue
  597. }
  598. rM[kk] = vv
  599. }
  600. }
  601. delete(rM, "_id")
  602. delete(rM, "userid")
  603. delete(rM, "createtime")
  604. delete(rM, "client")
  605. }
  606. 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 {
  607. s_phone := util.ObjToString((*userinfo)["s_phone"])
  608. phone := util.If(s_phone == "", util.ObjToString((*userinfo)["s_m_phone"]), s_phone)
  609. if rM["phone"] == nil || rM["phone"] == "" {
  610. rM["phone"] = phone
  611. }
  612. if rM["company"] == nil || rM["company"] == "" {
  613. rM["company"] = util.ObjToString((*userinfo)["s_company"])
  614. }
  615. }
  616. if rM["name"] != nil && rM["name"] != "" && rM["phone"] != nil && rM["phone"] != "" && rM["company"] != nil && rM["company"] != "" && rM["position"] != nil && rM["position"] != "" && rM["companyType"] != "" {
  617. if rM["position"] != "总裁" && rM["position"] != "总经理" && (rM["branch"] == nil || rM["branch"] == "") {
  618. return false
  619. }
  620. return true
  621. }
  622. return false
  623. }
  624. // 查看公告详情次数限制
  625. func SeeDetailLimit(obj map[string]interface{}, userId, sid string) bool {
  626. watchKey := fmt.Sprintf("article_count_%d_%s_%d_%s", time.Now().Year(), time.Now().Month(), time.Now().Day(), userId)
  627. subTypeStr, _ := obj["subtype"].(string)
  628. if strings.Contains(subTypeStr, "拟建") || strings.Contains(subTypeStr, "采购意向") {
  629. return false
  630. } else {
  631. //检验是否留资
  632. if CNode(userId) {
  633. return true
  634. }
  635. if seeRes := redis.Get("other", watchKey); seeRes != nil && seeRes != "" {
  636. if resVal, _ := seeRes.(string); resVal != "" {
  637. sidss := strings.Split(resVal, "_")
  638. canRead := config.Sysconfig["canReadNotice"]
  639. if len(sidss) < util.IntAll(canRead) {
  640. sidss = append(sidss, sid)
  641. arrs := RemoveDuplicatesAndEmpty(sidss)
  642. newVal := strings.Join(arrs, "_")
  643. redis.Put("other", watchKey, newVal, jy.GetExpire())
  644. return true
  645. } else {
  646. for _, v := range sidss {
  647. if sid == v {
  648. return true
  649. }
  650. }
  651. return false
  652. }
  653. }
  654. } else {
  655. redis.Put("other", watchKey, sid, jy.GetExpire())
  656. return true
  657. }
  658. }
  659. return false
  660. }
  661. func SwiDef(sid_openid []string) (string, string) {
  662. var shareopenid, sid string
  663. if len(sid_openid) > 1 {
  664. sid = sid_openid[0]
  665. shareopenid = sid_openid[1]
  666. } else {
  667. sid = sid_openid[0]
  668. }
  669. return shareopenid, sid
  670. }
  671. // user 权限获取
  672. func UserPermission(userId string, ssOpenid interface{}) (bool, bool, bool) {
  673. var (
  674. res *map[string]interface{}
  675. isVip, isMember, isEntniche, privatedata bool
  676. )
  677. if userId == "" && ssOpenid != nil {
  678. 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}`)
  679. userId = BsonIdToSId((*res)["_id"])
  680. } else {
  681. //判断用户是否是vip
  682. res = jyutil.Compatible.Select(userId, `{"i_vip_status":1,"i_member_status":1,"s_m_phone":1,"s_phone":1}`)
  683. }
  684. isVip = util.IntAll((*res)["i_vip_status"]) == 1 || util.IntAll((*res)["i_vip_status"]) == 2
  685. isMember = util.IntAll((*res)["i_member_status"]) > 0
  686. if phone, _ := util.If(util.ObjToString((*res)["s_phone"]) != "", util.ObjToString((*res)["s_phone"]), util.ObjToString((*res)["s_m_phone"])).(string); phone != "" {
  687. 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
  688. privatedata = public.Mysql.CountBySql(`select count(1) from privatedata where phone = ?`, phone) > 0
  689. }
  690. if !isEntniche && privatedata {
  691. isEntniche = true
  692. }
  693. return isVip, isMember, isEntniche
  694. }
  695. // pc 移动共用字段处理
  696. func FieldProcessing(obj map[string]interface{}, ssOpenid interface{}, industry, id, from_userid, userId, stype string, b bool) {
  697. obj["industry"] = industry
  698. if ssOpenid != nil {
  699. obj["ucbsId"] = encrypt.EncodeArticleId2ByCheck("ucbs#" + ssOpenid.(string) + "#" + id)
  700. }
  701. //判断是否公开联系人信息
  702. if util.Int64All(obj["buyerhint"]) == 2 {
  703. obj["buyerperson"] = ""
  704. obj["buyertel"] = ""
  705. }
  706. if !b {
  707. href, _ := obj["href"].(string)
  708. href = strings.Replace(href, "\n", "", -1)
  709. if href != "" && !strings.HasPrefix(href, "http") {
  710. href = "http://" + href
  711. }
  712. obj["url"] = href
  713. }
  714. //大会员中标企业跳转至画像
  715. if obj["entidlist"] != nil {
  716. if s_winner := util.ObjToString(obj["s_winner"]); s_winner != "" {
  717. entIdArr, winnerMap := []string{}, map[string]interface{}{}
  718. swinnerArr := strings.Split(s_winner, ",")
  719. eidList, _ := obj["entidlist"].([]interface{})
  720. //先查询entlist 如果长度和s_winner不一致 根据企业名称查询id
  721. if len(eidList) != len(swinnerArr) {
  722. for _, v := range swinnerArr {
  723. winnerMap[v] = ""
  724. //临时更改为企业名称查询企业id
  725. rData := elastic.Get("qyxy", "qyxy", fmt.Sprintf(`{"query":{"bool":{"should":[{"term":{"company_name":"%s"}},{"term":{"hname":"%s"}}],"minimum_should_match":1}},"_source":["name","_id","capital","company_phone"],"size":1}`, v, v))
  726. if rData != nil && len(*rData) == 1 {
  727. if entId := util.ObjToString((*rData)[0]["_id"]); entId != "" {
  728. entIdArr = append(entIdArr, encrypt.EncodeArticleId2ByCheck(util.ObjToString((*rData)[0]["_id"])))
  729. winnerMap[v] = encrypt.EncodeArticleId2ByCheck(util.ObjToString((*rData)[0]["_id"]))
  730. }
  731. }
  732. }
  733. } else {
  734. for k, v := range eidList {
  735. vstr := util.ObjToString(v)
  736. if vstr == "-" {
  737. continue
  738. }
  739. winnerMap[swinnerArr[k]] = encrypt.EncodeArticleId2ByCheck(vstr)
  740. }
  741. }
  742. obj["entId"] = entIdArr
  743. obj["winnerMap"] = winnerMap
  744. }
  745. }
  746. //移动端需要处理--剑鱼币
  747. if b && from_userid != "" && se.Decode4Hex(from_userid) != "" && se.Decode4Hex(from_userid) != userId && util.ObjToString(obj["subtype"]) != "拟建" { //分享开打的
  748. article_id := encrypt.CommonDecodeArticle(stype, id)[0]
  749. key := fmt.Sprintf("integral_article_%s_%s_%s", article_id, from_userid, userId)
  750. if redis.Incr("other", key) == 1 {
  751. redis.SetExpire("other", key, 60*60*24)
  752. 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)
  753. if err != nil {
  754. log.Println("nsq队列写入失败-->", jy.Jyweb_article_open, se.Decode4Hex(from_userid))
  755. }
  756. }
  757. }
  758. }
  759. // disWord 为空时处理
  760. func disWordNil(disWord, userId string) string {
  761. var from_userid string
  762. redisDis := redis.GetStr("other", "DIS_"+disWord[1:])
  763. if redisDis != "" {
  764. suffix := disWord[len(disWord)-3:]
  765. //公告三级页处理
  766. if suffix == suffix_msgt {
  767. effectiveTimeStr := strings.Split(redisDis, "##")[3]
  768. effectiveTime, _ := strconv.ParseInt(effectiveTimeStr, 10, 64)
  769. //是否计算佣金
  770. if time.Now().Unix() <= effectiveTime {
  771. belongUserId := strings.Split(redisDis, "##")[1]
  772. //if (belongUserId != userId) {
  773. public.Mysql.ExecTx("口号使用", func(tx *sql.Tx) bool {
  774. //口号是否使用过
  775. wordInfo := public.Mysql.Find("dis_word", map[string]interface{}{"userId": userId, "password": disWord}, "id", "", 0, 0)
  776. if len((*wordInfo)) == 0 {
  777. //新增口号使用
  778. start_time := time.Now().Format(DateFullLayout)
  779. termValidityInt, _ := strconv.Atoi(fmt.Sprint(config.Sysconfig["termValidity"]))
  780. stop_time := TimeProcessing(time.Now().Format(DateFullLayout), termValidityInt).Format(DateFullLayout)
  781. insert := map[string]interface{}{
  782. "password": disWord,
  783. "userId": userId,
  784. "belong_userid": belongUserId,
  785. "start_time": start_time,
  786. "stop_time": stop_time,
  787. }
  788. insert_1 := public.Mysql.InsertByTx(tx, "dis_word", insert) //口号使用表
  789. log.Println("插入口号使用表", insert_1)
  790. from_userid = se.Encode2Hex(belongUserId)
  791. }
  792. return true
  793. })
  794. }
  795. //}
  796. }
  797. }
  798. return from_userid
  799. }
  800. // 检查用户是否关注
  801. func CheckUserIsSubscribe(openid string) bool {
  802. user, ok := mongodb.FindOneByField("user", map[string]interface{}{
  803. "i_appid": 2,
  804. "s_m_openid": openid,
  805. "s_unionid": map[string]interface{}{"$ne": openid},
  806. }, `{"i_ispush":1}`)
  807. if ok && user != nil {
  808. if (*user)["_id"] == nil || util.IntAllDef((*user)["i_ispush"], 1) == 0 {
  809. return false
  810. } else {
  811. return true
  812. }
  813. }
  814. return false
  815. }
  816. func (s *Short) Qr(t, id string) error {
  817. w := s.ResponseWriter
  818. w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate")
  819. w.Header().Set("Pragma", "no-cache")
  820. w.Header().Set("Expires", "0")
  821. w.Header().Set("Content-Type", "image/png")
  822. kds := s.GetString("kds")
  823. industry := s.GetString("industry")
  824. param := "?scan_source=pc"
  825. if t == "force" {
  826. param += "&ispcforceshare=1"
  827. }
  828. if kds != "" {
  829. param += "&keywords=" + kds
  830. }
  831. if industry != "" {
  832. param += "&industry=" + industry
  833. }
  834. data := config.Sysconfig["webdomain"].(string) + "/article/content/" + id + ".html" + param
  835. r, _ := qr.Encode(data, qr.M)
  836. pngdat := r.PNG()
  837. _, err := w.Write(pngdat)
  838. return err
  839. }
  840. func (s *Short) Replication() {
  841. userId, OK := s.GetSession("userId").(string)
  842. if OK && userId != "" {
  843. mongodb.Save("copyaction", map[string]interface{}{
  844. "userid": userId,
  845. "createtime": time.Now().Unix(),
  846. "url": s.Request.Referer(),
  847. "client": s.Header("User-Agent"),
  848. })
  849. }
  850. }
  851. func isbid(typ interface{}) bool {
  852. if typ != nil {
  853. subtype := util.ObjToString(typ)
  854. if subtype == "中标" || subtype == "合同" || subtype == "成交" {
  855. return true
  856. }
  857. }
  858. return false
  859. }
  860. // 中标企业库
  861. func getwinnertel(company interface{}) string {
  862. if company != nil {
  863. data, _ := public.Mgo_Ent.FindOne("winner_enterprise", map[string]interface{}{
  864. "company_name": util.ObjToString(company),
  865. })
  866. if (*data)["company_phone"] != nil {
  867. return util.ObjToString((*data)["company_phone"])
  868. }
  869. }
  870. return ""
  871. }
  872. func GetUserId(openid string) string {
  873. data, ok := public.MQFW.FindOne("user", map[string]interface{}{"s_m_openid": openid})
  874. if data != nil && len(*data) > 0 && ok {
  875. userid := BsonIdToSId((*data)["_id"])
  876. return userid
  877. }
  878. return ""
  879. }
  880. func RemoveDuplicatesAndEmpty(a []string) (ret []string) {
  881. a_len := len(a)
  882. for i := 0; i < a_len; i++ {
  883. if (i > 0 && a[i-1] == a[i]) || len(a[i]) == 0 {
  884. continue
  885. }
  886. ret = append(ret, a[i])
  887. }
  888. return
  889. }
  890. // 该节点是否留资
  891. func hasRetainedCapital(uid, source string) bool {
  892. if count, err := mongodb.CountByErr("saleLeads", map[string]interface{}{"userid": uid, "source": source}); err != nil || count > 0 {
  893. return true
  894. }
  895. return false
  896. }
  897. func isInStringArr(arr []string, key string) bool {
  898. for _, v := range arr {
  899. if v == key {
  900. return true
  901. }
  902. }
  903. return false
  904. }
  905. func ReplaceStringByRegex(str, rule, replace string) (string, error) {
  906. reg, err := regexp.Compile(rule)
  907. if reg == nil || err != nil {
  908. return "", errors.New("正则MustCompile错误:" + err.Error())
  909. }
  910. return reg.ReplaceAllString(str, replace), nil
  911. }
  912. // 未登录用户进行数据过滤 name 配置文件
  913. func Filter(obj map[string]interface{}) map[string]interface{} {
  914. detail := fmt.Sprint(obj["detail"])
  915. mosaicText := util.ObjToString(config.Sysconfig["detailMosaicTxt"])
  916. for k, _ := range obj {
  917. needMosaic, _ := config.Sysconfig["needMosaic"].(map[string]interface{})
  918. if ok, _ := needMosaic[k].(bool); ok {
  919. if util.ObjToString(obj[k]) != "" {
  920. detail = strings.ReplaceAll(detail, util.ObjToString(obj[k]), mosaicText)
  921. //敏感词过滤
  922. }
  923. if k == "winnerMap" {
  924. winnerMap, _ := obj[k].(map[string]interface{})
  925. mosaicMap := map[string]interface{}{}
  926. for i := 0; i < len(winnerMap); i++ {
  927. mosaicMap[mosaicText] = mosaicText
  928. }
  929. obj["winnerMap"] = mosaicMap
  930. } else {
  931. obj[k] = mosaicText
  932. }
  933. }
  934. }
  935. //数字打码
  936. detail = RegDetail(detail)
  937. detail = fsw.Repl(detail)
  938. obj["detail"] = detail
  939. return obj
  940. }
  941. // 未登录用户进行数据过滤 name 配置文件
  942. func SearchFilter(obj map[string]interface{}) map[string]interface{} {
  943. //detail := fmt.Sprint(obj["detail"])
  944. mosaicText := util.ObjToString(config.Sysconfig["detailMosaicTxt"])
  945. for k, _ := range obj {
  946. needMosaic, _ := config.Sysconfig["searchMosaic"].(map[string]interface{})
  947. if ok, _ := needMosaic[k].(bool); ok {
  948. //if util.ObjToString(obj[k]) != "" {
  949. // detail = strings.ReplaceAll(detail, util.ObjToString(obj[k]), mosaicText)
  950. // //敏感词过滤
  951. //}
  952. if k == "winnerMap" {
  953. winnerMap, _ := obj[k].(map[string]interface{})
  954. mosaicMap := map[string]interface{}{}
  955. for i := 0; i < len(winnerMap); i++ {
  956. mosaicMap[mosaicText] = mosaicText
  957. }
  958. obj["winnerMap"] = mosaicMap
  959. } else {
  960. obj[k] = mosaicText
  961. }
  962. }
  963. }
  964. //数字打码
  965. //detail = RegDetail(detail)
  966. //detail = fsw.Repl(detail)
  967. //obj["detail"] = detail
  968. return obj
  969. }
  970. func (s *Short) NologinArticle(stype, id string) error {
  971. userId := util.ObjToString(s.GetSession("userId"))
  972. sids := encrypt.CommonDecodeArticle(stype, id)
  973. if len(sids) == 0 || (len(sids) > 0 && sids[0] == "") {
  974. s.Redirect("/notin/page", 302)
  975. return nil
  976. }
  977. if userId != "" { //已登录用户直接跳转至正常三级页
  978. return s.LoginCommon(userId, stype, id)
  979. }
  980. return s.NologinCommon(userId, stype, id, sids[0])
  981. }
  982. func (s *Short) NologinCommon(userId, stype, id, sid string) error {
  983. tg := &Tags{}
  984. catchKey := fmt.Sprintf("jypcdetail_nologin_%s_%s", stype, sid)
  985. if res := redis.Get("newother", catchKey); res == nil || res == "" {
  986. industry := s.GetString("industry")
  987. var shareid = s.GetString("id")
  988. if len(shareid) == 0 {
  989. shareid = "10"
  990. }
  991. s.T["logid"] = config.Seoconfig["jysskzy"].(string)
  992. s.T["shareid"] = se.EncodeString(shareid)
  993. //s.T["keywords"] = s.GetString("kds")
  994. s.DisableHttpCache()
  995. po, bo, wo, obj := pcVRT(sid, industry, stype, false || false || false)
  996. if obj != nil && len(obj) > 0 {
  997. if len(po) > 0 {
  998. s.T["projectOther"] = po
  999. }
  1000. if len(bo) > 0 {
  1001. s.T["buyerOther"] = bo
  1002. }
  1003. if len(wo) > 0 {
  1004. s.T["winnerOther"] = wo
  1005. }
  1006. FieldProcessing(obj, "", industry, id, "", userId, stype, false)
  1007. obj["urlpath"] = s.Uri()
  1008. obj["industry"] = industry
  1009. if userId == "" {
  1010. obj["winnerTitle"] = obj["winner"]
  1011. obj["buyerTitle"] = obj["buyer"]
  1012. obj["projectnameTitle"] = obj["projectname"]
  1013. obj["projectcodeTitle"] = obj["projectcode"]
  1014. log.Println(time.Now().UnixNano())
  1015. obj = Filter(obj)
  1016. //obj["description"] = fmt.Sprintf("%s,%s。", obj["title"], baseInfo(obj))
  1017. }
  1018. if obj["publishtime"] != nil {
  1019. obj["publishtimeShorDate"] = time.Unix(util.Int64All(obj["publishtime"]), 0).Format(date.Date_Short_Layout)
  1020. }
  1021. obj["keywords"] = KeyWordHandle(obj)
  1022. obj["description"] = DescriptionHandle("nologin", obj)
  1023. s.T["obj"] = obj
  1024. s.T["url"] = s.Uri()
  1025. s.T["newBidInfoList"] = tg.GetNewBidInfo()
  1026. s.T["industryInfoList"] = tg.GetConsult()
  1027. s.T["hotLabelList"] = tg.GetHotLabel(30)
  1028. content, _ := s.Render4Cache("/pc/tags/detail.html", &s.T)
  1029. redis.Put("newother", catchKey, string(content), 60*2)
  1030. return s.SetBody(content)
  1031. }
  1032. } else {
  1033. return s.SetBody([]byte(res.(string)))
  1034. }
  1035. return nil
  1036. }
  1037. /*
  1038. TDK description
  1039. */
  1040. func baseInfo(obj map[string]interface{}) string {
  1041. info := ""
  1042. info += "省份:"
  1043. //{{if eq .T.obj.area "A"}}全国{{else}}{{.T.obj.area}}{{end}}
  1044. if area := util.ObjToString(obj["area"]); area == "A" {
  1045. info += "全国"
  1046. } else {
  1047. info += area
  1048. }
  1049. info += ",城市:" + util.ObjToString(obj["city"])
  1050. info += ",招标代理机构:" + util.ObjToString(obj["agency"])
  1051. info += ",项目名称:" + util.ObjToString(obj["projectname"])
  1052. info += ",采购单位:" + util.ObjToString(obj["buyer"])
  1053. info += ",采购联系人:" + util.ObjToString(obj["buyerperson"])
  1054. info += ",采购电话:" + util.ObjToString(obj["buyertel"])
  1055. if obj["package"] == nil {
  1056. info += ",项目预算(元):" + util.ObjToString(obj["budget"])
  1057. }
  1058. if util.ObjToString(obj["subtype"]) == "单一" && util.ObjToString(obj["package"]) == "" {
  1059. info += ",拟定单一来源采购供应商:" + util.ObjToString(obj["winner"])
  1060. }
  1061. subtype := util.ObjToString(obj["subtype"])
  1062. if subtype == "中标" || subtype == "成交" || subtype == "合同" {
  1063. if obj["winnerMap"] != nil {
  1064. info += ",中标单位:"
  1065. i := 0
  1066. for k, _ := range *util.ObjToMap(obj["winnerMap"]) {
  1067. i++
  1068. info += k
  1069. if i != len(*util.ObjToMap(obj["winnerMap"])) {
  1070. info += "、"
  1071. }
  1072. }
  1073. }
  1074. if obj["bidamount"] != nil {
  1075. info += ",中标金额(元):" + util.ObjToString(obj["bidamount"])
  1076. }
  1077. if obj["bidamount"] != nil {
  1078. info += ",联系方式:" + util.ObjToString(obj["bidamount"])
  1079. }
  1080. }
  1081. return info
  1082. }
  1083. // 分段匹配数字打码
  1084. func RegDetail(html string) string {
  1085. mosaicText := util.ObjToString(config.Sysconfig["detailMosaicTxt"])
  1086. reg := regexp.MustCompile("<[^<>]{1,1000}>") //分段正则
  1087. s := reg.FindAllStringIndex(html, -1) //全文匹配分段
  1088. if len(s) > 0 { //走分段替换
  1089. arr := []string{}
  1090. index := 0
  1091. for _, v := range s {
  1092. if len(v) == 2 {
  1093. // log.Println(html[index:v[0]])
  1094. txt, _ := ReplaceStringByRegex(html[index:v[0]], "[0-9]+", mosaicText)
  1095. arr = append(arr, txt) //替换
  1096. arr = append(arr, html[v[0]:v[1]])
  1097. index = v[1]
  1098. }
  1099. }
  1100. return strings.Join(arr, "")
  1101. }
  1102. return ""
  1103. }
  1104. func KeyWordHandle(obj map[string]interface{}) string {
  1105. keywordArr := []string{}
  1106. owner := util.InterfaceToStr(obj["owner"])
  1107. buyer := util.InterfaceToStr(obj["buyer"])
  1108. if buyer == "" {
  1109. buyer = owner
  1110. }
  1111. if buyer != "" && buyer != config.Sysconfig["detailMosaicTxt"] {
  1112. keywordArr = append(keywordArr, buyer)
  1113. }
  1114. if util.InterfaceToStr(obj["s_winner"]) != "" && util.InterfaceToStr(obj["s_winner"]) != config.Sysconfig["detailMosaicTxt"] {
  1115. keywordArr = append(keywordArr, util.InterfaceToStr(obj["s_winner"]))
  1116. }
  1117. if obj["purchasinglist"] != nil && obj["purchasinglist"] != "" {
  1118. i := 0
  1119. for _, v := range gconv.SliceMap(obj["purchasinglist"]) {
  1120. if i == 5 {
  1121. break
  1122. }
  1123. if util.InterfaceToStr(v["itemname"]) != "" && util.InterfaceToStr(obj["s_winner"]) != config.Sysconfig["detailMosaicTxt"] {
  1124. keywordArr = append(keywordArr, util.InterfaceToStr(v["itemname"]))
  1125. i++
  1126. }
  1127. }
  1128. }
  1129. if util.InterfaceToStr(obj["subtype"]) != "" && util.InterfaceToStr(obj["subtype"]) != "其它" {
  1130. keywordArr = append(keywordArr, TypeCodeMap[util.InterfaceToStr(obj["subtype"])])
  1131. }
  1132. if util.InterfaceToStr(obj["area"]) != "" {
  1133. keywordArr = append(keywordArr, util.InterfaceToStr(obj["area"])+"招标")
  1134. }
  1135. if util.InterfaceToStr(obj["city"]) != "" {
  1136. keywordArr = append(keywordArr, util.InterfaceToStr(obj["city"])+"招标")
  1137. }
  1138. keywordArr = append(keywordArr, "剑鱼标讯")
  1139. keyword := strings.Join(keywordArr, ",")
  1140. return keyword
  1141. }
  1142. func DescriptionHandle(stype string, obj map[string]interface{}) string {
  1143. description := ""
  1144. publishtime := util.Int64All(obj["l_publishtime"])
  1145. if publishtime == 0 {
  1146. publishtime = util.Int64All(obj["publishtime"])
  1147. }
  1148. pushTime := time.Unix(publishtime, 0)
  1149. title := util.InterfaceToStr(obj["title"])
  1150. owner := util.InterfaceToStr(obj["owner"])
  1151. buyer := util.InterfaceToStr(obj["buyer"])
  1152. if buyer == "" {
  1153. buyer = owner
  1154. }
  1155. s_winner := util.InterfaceToStr(obj["s_winner"])
  1156. area := util.InterfaceToStr(obj["area"])
  1157. city := util.InterfaceToStr(obj["city"])
  1158. if stype == "bdprivate" {
  1159. //bdprivate
  1160. //{项目标题},采购单位:{采购单位名称},成交供应商:{中标企业名称},公告日期:{公告日期}。
  1161. descriptionArr := []string{}
  1162. if title != "" {
  1163. descriptionArr = append(descriptionArr, title)
  1164. }
  1165. if buyer != "" {
  1166. descriptionArr = append(descriptionArr, fmt.Sprintf("采购单位:%s", buyer))
  1167. }
  1168. if s_winner != "" {
  1169. descriptionArr = append(descriptionArr, fmt.Sprintf("成交供应商:%s", s_winner))
  1170. }
  1171. if publishtime != 0 {
  1172. descriptionArr = append(descriptionArr, fmt.Sprintf("公告日期:%s", pushTime.Format("2006年01月02日")))
  1173. }
  1174. descriptionArr = append(descriptionArr, "查看该项目信息详情请访问剑鱼标讯官网。")
  1175. description = strings.Join(descriptionArr, ",")
  1176. } else {
  1177. //descriptionStr = "%s,项目所属地区是%s%s,项目采购单位是%s,项目发布时间是%s"
  1178. descriptionArr := []string{}
  1179. if title != "" {
  1180. descriptionArr = append(descriptionArr, title)
  1181. }
  1182. if area != "" || city != "" {
  1183. descriptionArr = append(descriptionArr, fmt.Sprintf("项目所属地区是%s%s", area, city))
  1184. }
  1185. if buyer != "" {
  1186. descriptionArr = append(descriptionArr, fmt.Sprintf("项目采购单位是%s", buyer))
  1187. }
  1188. if publishtime != 0 {
  1189. descriptionArr = append(descriptionArr, fmt.Sprintf("项目发布时间是%s", pushTime.Format("2006年01月02日")))
  1190. }
  1191. descriptionArr = append(descriptionArr, "查看该项目信息详情请访问剑鱼标讯官网。")
  1192. description = strings.Join(descriptionArr, ",")
  1193. }
  1194. return description
  1195. }