entdataexport.go 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439
  1. package dataexport
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "io/ioutil"
  6. "log"
  7. "net/http"
  8. "os"
  9. "strconv"
  10. "strings"
  11. "sync"
  12. "time"
  13. util "app.yhyue.com/moapp/jybase/common"
  14. . "app.yhyue.com/moapp/jybase/date"
  15. . "app.yhyue.com/moapp/jybase/encrypt"
  16. elastic "app.yhyue.com/moapp/jybase/esv1"
  17. "app.yhyue.com/moapp/jybase/mongodb"
  18. mg "app.yhyue.com/moapp/jybase/mongodb"
  19. "app.yhyue.com/moapp/jybase/mysql"
  20. "github.com/tealeg/xlsx"
  21. "go.mongodb.org/mongo-driver/bson"
  22. )
  23. // 作者:一组开发
  24. type Filters struct {
  25. FilterId string
  26. }
  27. func GetEntDataExportCount(sim, bid mg.MongodbSim, bidMgoDBName, elasticAddress, _id string, entId, entUserId int, isFirst bool, url string, maxCount int) (count, newCount int, data *[]map[string]interface{}) {
  28. defer util.Catch()
  29. var (
  30. searchsWaitGroup = &sync.WaitGroup{}
  31. )
  32. count = GetDataExportSearchCountByScdId(sim, bid, bidMgoDBName, elasticAddress, _id)
  33. if count > maxCount || count == -1 {
  34. count = maxCount
  35. }
  36. log.Println("count", count)
  37. dataType := "2"
  38. //数据导出数据查询
  39. res, err := GetDataExportSearchResultByScdId(sim, bid, bidMgoDBName, elasticAddress, _id, dataType, count)
  40. if err != nil {
  41. log.Println("企业数据导出错误 ", err)
  42. return 0, 0, nil
  43. }
  44. // 20210716 由原来的redis判重改为调用判重中台接口进行判重
  45. m := map[string]bool{}
  46. infoIdList := []string{}
  47. insertFlag := "false"
  48. if !isFirst {
  49. insertFlag = "true"
  50. }
  51. for _, v := range *res {
  52. if util.IntAll(v["signendtime"]) != 0 {
  53. date := v["signendtime"]
  54. v["signendtime"] = FormatDateWithObj(&date, Date_Short_Layout)
  55. }
  56. if util.IntAll(v["signendtime"]) != 0 {
  57. date := v["signendtime"]
  58. v["signendtime"] = FormatDateWithObj(&date, Date_Short_Layout)
  59. }
  60. id := util.ObjToString(v["_id"])
  61. if m[id] {
  62. continue
  63. }
  64. m[id] = true
  65. // 20210716 redis判重调整为调用判重中台接口 每一千个调用一次
  66. infoIdList = append(infoIdList, id)
  67. if len(infoIdList) > 1000 {
  68. // 调接口
  69. rs, err5 := Post(url, map[string]string{
  70. "personId": "0", // 没有使用这个参数
  71. "infoId": strings.Join(infoIdList, ","),
  72. "entId": fmt.Sprintf("%d", entId),
  73. "isInsert": insertFlag,
  74. "isEnt": "true",
  75. })
  76. log.Println("响应结果:", rs)
  77. if err5 != nil || util.IntAll(rs["code"]) != 0 {
  78. log.Println("企业订阅数据导出接口判重失败", err5)
  79. log.Println("企业订阅数据导出接口判重失败rs:", rs)
  80. log.Println("企业订阅数据导出接口判重失败rs[code]:", rs["code"])
  81. log.Println("企业订阅数据导出接口判重失败code是否为0", util.IntAll(rs["code"]) != 0)
  82. log.Println("企业订阅数据导出接口判重失败", err5, "rs:", rs, " rs[code]:", rs["code"], " ", util.IntAll(rs["code"]), "code是否为0", util.IntAll(rs["code"]) != 0)
  83. } else {
  84. log.Println("企业订阅数据导出")
  85. // 置空
  86. infoIdList = []string{}
  87. // 本次数据累计
  88. returnData := rs["data"].(map[string]interface{})
  89. log.Println(newCount, "加之前")
  90. newCount += util.IntAll(returnData["newCount"])
  91. //newCount += int(returnData["newCount"].(float64))
  92. log.Println(newCount, "加之后")
  93. }
  94. }
  95. if !isFirst {
  96. delete(v, "_id")
  97. v["entid"] = entId
  98. v["userid"] = entUserId
  99. v["infoid"] = id
  100. v["createtime"] = time.Now().Unix()
  101. }
  102. }
  103. if len(infoIdList) > 0 {
  104. rs, err5 := Post(url, map[string]string{
  105. "personId": "0", // 没有使用这个参数
  106. "infoId": strings.Join(infoIdList, ","),
  107. "entId": fmt.Sprintf("%d", entId),
  108. "isInsert": insertFlag,
  109. "isEnt": "true",
  110. })
  111. log.Println(rs)
  112. if err5 != nil || util.IntAll(rs["code"]) != 0 {
  113. log.Println("企业订阅数据导出接口判重失败", err5)
  114. log.Println("企业订阅数据导出接口判重失败rs:", rs)
  115. log.Println("企业订阅数据导出接口判重失败rs[code]:", rs["code"])
  116. log.Println("企业订阅数据导出接口判重失败code是否为0", util.IntAll(rs["code"]) != 0)
  117. log.Println("企业订阅数据导出接口判重失败", err5, "rs:", rs, " rs[code]:", rs["code"], " ", util.IntAll(rs["code"]), "code是否为0", util.IntAll(rs["code"]) != 0)
  118. } else {
  119. log.Println("企业订阅数据导出")
  120. // 置空
  121. infoIdList = []string{}
  122. // 本次数据累计
  123. returnData := rs["data"].(map[string]interface{})
  124. log.Println(newCount, "加之前")
  125. newCount += util.IntAll(returnData["newCount"])
  126. //newCount += int(returnData["newCount"].(float64))
  127. log.Println(newCount, "加之后")
  128. }
  129. }
  130. searchsWaitGroup.Wait()
  131. log.Println("企业数据导出--数据遍历完成")
  132. //newCount = len(newCountPool)
  133. log.Println("new", newCount)
  134. data = res
  135. return
  136. }
  137. func FormatExportDatas(Mgo_Ent mongodb.MongodbSim, data *[]map[string]interface{}, webdomain string, dataType string, entId int) *[]map[string]interface{} {
  138. //格式化输出
  139. var (
  140. entexportPool = make(chan bool, 20)
  141. entexportWaitGroup = &sync.WaitGroup{}
  142. )
  143. log.Println("补充信息开始")
  144. for _, v := range *data {
  145. entexportWaitGroup.Add(1)
  146. entexportPool <- true
  147. go func(v map[string]interface{}) {
  148. defer func() {
  149. entexportWaitGroup.Done()
  150. <-entexportPool
  151. }()
  152. //有中标企业 且 高级字段查询
  153. if dataType == "2" {
  154. //查询企业公示 法人 公司电话 公司邮箱地址
  155. s_winner := strings.Split(util.ObjToString(v["s_winner"]), ",")[0]
  156. if entData, ok := Mgo_Ent.Find("winner_enterprise", bson.M{"company_name": s_winner}, nil,
  157. `{"company_name":1,"company_email":1,"legal_person":1,"company_phone":1}`, false, -1, -1); ok {
  158. if entData != nil && *entData != nil && len(*entData) > 0 {
  159. for _, ev := range *entData {
  160. if v["s_winner"] == ev["company_name"] {
  161. legal_person := ""
  162. if ev["legal_person"] != nil {
  163. legal_person = ev["legal_person"].(string)
  164. }
  165. company_phone := ""
  166. if ev["company_phone"] != nil {
  167. company_phone = ev["company_phone"].(string)
  168. }
  169. company_email := ""
  170. if ev["company_email"] != nil && ev["company_email"] != "无" {
  171. company_email = ev["company_email"].(string)
  172. }
  173. v["legal_person"] = legal_person
  174. v["company_phone"] = company_phone
  175. v["company_email"] = company_email
  176. }
  177. }
  178. }
  179. }
  180. }
  181. //====================字段补漏=========================
  182. if v["toptype"] == "结果" && dataType == "2" && !(v["agency"] != nil && v["budget"] != nil && v["buyerperson"] != nil && v["buyertel"] != nil) {
  183. r := elastic.Get("projectset", "projectset", fmt.Sprintf(`{"query":{"term":{"list.infoid":"%s"}},"_source": ["list"]}`, v["_id"]))
  184. if len(*r) > 0 {
  185. MsgList := (*r)[0]["list"]
  186. if MsgList != nil {
  187. list := util.ObjArrToMapArr(MsgList.([]interface{}))
  188. for _, vv := range list {
  189. if vv["subtype"] == "招标" {
  190. if v["agency"] == nil && vv["agency"] != nil {
  191. v["agency"] = vv["agency"]
  192. }
  193. if v["budget"] == nil && vv["budget"] != nil {
  194. v["budget"] = vv["budget"]
  195. }
  196. if v["buyerperson"] == nil && vv["buyerperson"] != nil {
  197. v["buyerperson"] = vv["buyerperson"]
  198. }
  199. if v["buyertel"] == nil && vv["buyertel"] != nil {
  200. v["buyertel"] = vv["buyertel"]
  201. }
  202. break
  203. }
  204. }
  205. }
  206. }
  207. }
  208. if v["area"] == "A" {
  209. v["area"] = "全国"
  210. }
  211. if v["publishtime"] != nil {
  212. date := v["publishtime"]
  213. v["publishtime"] = FormatDateWithObj(&date, Date_Short_Layout)
  214. }
  215. if v["bidopentime"] != nil {
  216. date := v["bidopentime"]
  217. v["bidopentime"] = FormatDateWithObj(&date, Date_Short_Layout)
  218. }
  219. if util.IntAll(v["signendtime"]) != 0 {
  220. date := v["signendtime"]
  221. v["signendtime"] = FormatDateWithObj(&date, Date_Short_Layout)
  222. }
  223. if v["currency"] == "" || v["currency"] == nil {
  224. v["currency"] = "人民币"
  225. }
  226. if v["subtype"] == nil && v["toptype"] != nil {
  227. v["subtype"] = v["toptype"]
  228. }
  229. if v["detail"] != "" && v["detail"] != nil {
  230. str := ClearHtml.ReplaceAllString(v["detail"].(string), "")
  231. str = ClearOther.ReplaceAllString(str, "")
  232. str = strings.Replace(str, " ", "", -1)
  233. v["detail"] = str
  234. }
  235. if v["infoid"] != nil {
  236. v["url"] = webdomain + "/article/content/" + CommonEncodeArticle("content", v["infoid"].(string)) + ".html"
  237. }
  238. }(v)
  239. }
  240. entexportWaitGroup.Wait()
  241. log.Println("补充信息结束")
  242. return data
  243. }
  244. func Post(url string, form map[string]string) (data map[string]interface{}, err error) {
  245. str := ""
  246. for k, v := range form {
  247. str += "&" + k + "=" + v
  248. }
  249. //log.Println(str)
  250. res, err1 := http.Post(url, "application/x-www-form-urlencoded", strings.NewReader(str))
  251. log.Println(res)
  252. if err1 != nil {
  253. log.Println("post err:", err1.Error())
  254. return nil, err1
  255. } else if res.Body != nil {
  256. defer res.Body.Close()
  257. bs, _ := ioutil.ReadAll(res.Body)
  258. err2 := json.Unmarshal(bs, &data)
  259. if err2 != nil {
  260. return nil, err2
  261. }
  262. }
  263. return data, nil
  264. }
  265. // 生成xlsx
  266. func GetXlsx(mMap []map[string]interface{}, entId, entUserId int, filePath string) string {
  267. xf, err := xlsx.OpenFile("./web/staticres/fields.xlsx")
  268. if err != nil {
  269. log.Println("fields file not foud", err.Error())
  270. }
  271. sh := xf.Sheets[1]
  272. for _, v := range mMap {
  273. row := sh.AddRow()
  274. row.AddCell().SetValue(v["keyword"])
  275. row.AddCell().SetValue(v["area"])
  276. row.AddCell().SetValue(v["city"])
  277. row.AddCell().SetValue(v["district"])
  278. row.AddCell().SetValue(v["title"])
  279. row.AddCell().SetValue(v["subtype"])
  280. row.AddCell().SetValue(v["detail"])
  281. if v["publishtime"] != nil {
  282. row.AddCell().SetValue(v["publishtime"])
  283. } else {
  284. row.AddCell()
  285. }
  286. row.AddCell().SetValue(v["href"])
  287. row.AddCell().SetValue(v["url"])
  288. row.AddCell().SetValue(v["projectname"])
  289. row.AddCell().SetValue(v["projectcode"])
  290. row.AddCell().SetValue(v["projectscope"])
  291. if v["budget"] != nil {
  292. row.AddCell().SetFloat(util.Float64All(v["budget"]))
  293. } else {
  294. row.AddCell()
  295. }
  296. if v["bidamount"] != nil {
  297. row.AddCell().SetFloat(util.Float64All(v["bidamount"]))
  298. } else {
  299. row.AddCell()
  300. }
  301. if v["signendtime"] != nil {
  302. row.AddCell().SetValue(v["signendtime"])
  303. } else {
  304. row.AddCell()
  305. }
  306. if v["bidopentime"] != nil {
  307. row.AddCell().SetValue(v["bidopentime"])
  308. } else {
  309. row.AddCell()
  310. }
  311. if v["bidendtime"] != nil {
  312. row.AddCell().SetValue(v["bidendtime"])
  313. } else {
  314. row.AddCell()
  315. }
  316. row.AddCell().SetValue(v["buyer"])
  317. row.AddCell().SetValue(v["buyerperson"])
  318. row.AddCell().SetValue(v["buyertel"])
  319. row.AddCell().SetValue(v["buyeraddr"])
  320. row.AddCell().SetValue(v["agency"])
  321. row.AddCell().SetValue(v["s_winner"])
  322. row.AddCell().SetValue(v["winnerperson"])
  323. row.AddCell().SetValue(v["winnertel"])
  324. row.AddCell().SetValue(v["legal_person"])
  325. row.AddCell().SetValue(v["company_phone"])
  326. row.AddCell().SetValue(v["company_email"])
  327. }
  328. xf.Sheets = xf.Sheets[1:2]
  329. xf.Sheets[0].Name = "数据导出"
  330. //生文件
  331. t := strconv.FormatInt(time.Now().Unix(), 10)
  332. entIds := strconv.Itoa(entId)
  333. entUserIds := strconv.Itoa(entUserId)
  334. dir := filePath + "/entsearchexport/" + entIds + "_" + entUserIds + "_" + t + "/"
  335. if b, _ := PathExists(dir); !b {
  336. err1 := os.MkdirAll(dir, os.ModePerm)
  337. if err1 != nil {
  338. log.Println("mkdir err", dir)
  339. }
  340. }
  341. fname := entIds + "_" + entUserIds + "_" + "entdataexport.xlsx"
  342. download_url := "/entsearchexport/" + entIds + "_" + entUserIds + "_" + t + "/" + fname
  343. err = xf.Save(dir + fname)
  344. if err != nil {
  345. log.Println("xls error", fname)
  346. return ""
  347. }
  348. return download_url
  349. }
  350. func PathExists(path string) (bool, error) {
  351. _, err := os.Stat(path)
  352. if err == nil {
  353. return true, nil
  354. }
  355. if os.IsNotExist(err) {
  356. return false, nil
  357. }
  358. return false, err
  359. }
  360. func SaveExportLog(mysqlSess *mysql.Mysql, entId, entUserId, count, newCount, remain_nums, export_nums int, xlsxUrl, types, filterStr string, exportPhone, exportEmail string) {
  361. query := map[string]interface{}{
  362. "id": entUserId,
  363. "ent_id": entId,
  364. }
  365. set := map[string]interface{}{
  366. "remain_nums": remain_nums - newCount,
  367. "export_nums": export_nums + newCount,
  368. }
  369. ok := mysqlSess.Update("entniche_export_limit", map[string]interface{}{"ent_id": entId, "user_id": entUserId}, set)
  370. if !ok {
  371. log.Println("修改导出条数失败", query, remain_nums, newCount)
  372. }
  373. userData := mysqlSess.FindOne("entniche_user", query, "name,phone", "")
  374. if userData != nil {
  375. name := util.ObjToString((*userData)["name"])
  376. phone := util.ObjToString((*userData)["phone"])
  377. now := time.Now()
  378. mysqlSess.Insert("entniche_export_log", map[string]interface{}{
  379. "user_name": name,
  380. "export_time": FormatDate(&now, Date_Full_Layout),
  381. "data_source": "2",
  382. "export_num": count,
  383. "deduct_num": newCount,
  384. "download_url": xlsxUrl,
  385. "ent_id": entId,
  386. "phone": phone,
  387. "user_id": entUserId,
  388. "filter": filterStr,
  389. "export_phone": exportPhone,
  390. "export_mail": exportEmail,
  391. })
  392. }
  393. }
  394. func DeductNum(m *mysql.Mysql, qyfw mongodb.MongodbSim, entId, newCount int) {
  395. query := map[string]interface{}{
  396. "id": entId,
  397. }
  398. userData := m.FindOne("entniche_info", query, "name,phone", "")
  399. if userData != nil {
  400. name := util.ObjToString((*userData)["name"])
  401. phone := util.ObjToString((*userData)["phone"])
  402. qyfw.Update("user", map[string]interface{}{"phone": phone, "username": name}, map[string]interface{}{
  403. "$inc": map[string]interface{}{
  404. "plan.current": -newCount,
  405. },
  406. }, false, false)
  407. }
  408. }
  409. func GetCurrentCount(m *mysql.Mysql, qyfw mongodb.MongodbSim, entId int) int {
  410. count := 0
  411. userData := m.FindOne("entniche_info", map[string]interface{}{"id": entId}, "name,phone", "")
  412. if userData == nil {
  413. return count
  414. }
  415. current, ok := qyfw.FindOne("user", map[string]interface{}{"phone": util.ObjToString((*userData)["phone"]), "username": util.ObjToString((*userData)["name"])})
  416. if current == nil || !ok {
  417. return count
  418. }
  419. plan, _ := (*current)["plan"].(map[string]interface{})
  420. count = util.IntAll(plan["current"])
  421. return count
  422. }