package service import ( "encoding/json" "fmt" "io/ioutil" "log" "net/http" "os" qu "qfw/util" gm "qfw/util/mail" "qfw/util/redis" "regexp" "strings" "time" "unicode/utf8" . "util" "github.com/go-xweb/xweb" "github.com/tealeg/xlsx" "gopkg.in/mgo.v2/bson" ) var ( phonereg *regexp.Regexp = regexp.MustCompile(`0?(13|14|15|17|18|19)[0-9]{9}`) telreg *regexp.Regexp = regexp.MustCompile(`[0-9-()()]{7,18}`) emailreg *regexp.Regexp = regexp.MustCompile(`\w[-\w.+]*@([A-Za-z0-9][-A-Za-z0-9]+\.)+[A-Za-z]{2,14}`) pre *regexp.Regexp = regexp.MustCompile("https://www.jianyu360.com/article/content/") suf *regexp.Regexp = regexp.MustCompile("(.html).*") ) type Private struct { *xweb.Action keydatademo xweb.Mapper `xweb:"/private/keydatademo/(.*)"` //加密串 keydataoption xweb.Mapper `xweb:"/private/keydataoption/(.*)"` //加密串 } func (f *Private) Keydatademo(world string) { tmp := make(map[string]interface{}) destr := SEPreview.DecodeString(world) typeStr := f.GetString("type") qu.Debug(destr) if len(destr) > 10 { var tagfield *map[string]interface{} if typeStr == "private" { tagfield, _ = Mgo.FindOne("entniche_rule", bson.M{"s_dataid": world}) customer := JyMysql.FindOne("entniche_info", map[string]interface{}{"id": qu.IntAll((*tagfield)["entId"])}, "name", "") (*tagfield)["s_customer"] = (*customer)["name"] } entId := qu.IntAll((*tagfield)["entId"]) entUserId := qu.IntAll((*tagfield)["entUserId"]) dataConfig, _ := Mgo.FindOne("datatag_export_config", map[string]interface{}{"ent_id": entId}) current := GetCurrentCount2(entId, entUserId) log.Println("数据余额", current) tmp["current"] = current if (*tagfield) != nil && len(*tagfield) > 0 { if qu.IntAll((*dataConfig)["dataType"]) == Standard { tmp["fieldtype"] = Standardstr } else if qu.IntAll((*dataConfig)["dataType"]) == Advanced { tmp["fieldtype"] = Advancedstr } else { f.ServeJson(map[string]string{ "err": "参数失效", }) return } tmp["fields"] = (*dataConfig)["fields"] tmp["total"] = qu.Int64All((*tagfield)["i_estotal"]) tmp["customername"] = qu.ObjToString((*tagfield)["s_customer"]) datas, _ := Mgo.Find("tagsdata", bson.M{"s_dataid": world}, `{"publishtime":-1}`, nil, false, -1, -1) if (*datas) != nil && len(*datas) > 0 { matchskey := make(map[string]bool) rdata := make([]map[string]interface{}, 0) for _, v := range *datas { for _, mv := range strings.Split(qu.ObjToString(v["s_matchkey"]), ",") { matchskey[mv] = true } delete(v, "_id") delete(v, "s_dataid") delete(v, "i_createtime") if v["bidamount"] != nil { v["bidamount"] = qu.Float64All(fmt.Sprintf("%f", qu.Float64All(v["bidamount"]))) } if v["budget"] != nil { v["budget"] = qu.Float64All(fmt.Sprintf("%f", qu.Float64All(v["budget"]))) } if v["publishtime"] != nil { v["publishtime"] = time.Unix(qu.Int64All(v["publishtime"]), 0).Format("2006-01-02") } if v["bidopentime"] != nil { v["bidopentime"] = time.Unix(qu.Int64All(v["bidopentime"]), 0).Format("2006-01-02") } if v["bidendtime"] != nil { v["bidendtime"] = time.Unix(qu.Int64All(v["bidendtime"]), 0).Format("2006-01-02 15:04:05") } if utf8.RuneCountInString(qu.ObjToString(v["title"])) > 60 { title := string([]rune(qu.ObjToString(v["title"]))[:60]) v["title"] = title + "..." } if utf8.RuneCountInString(qu.ObjToString(v["detail"])) > 150 { detail := string([]rune(qu.ObjToString(v["detail"]))[:150]) v["detail"] = detail + "..." } if qu.Int64All((*tagfield)["i_extfieldstype"]) == Advanced { legal_person := strings.TrimSpace(qu.ObjToString(v["legal_person"])) if utf8.RuneCountInString(legal_person) > 1 { legal_person := []rune(legal_person) v["legal_person"] = string(legal_person[:1]) + "**" } cemail := strings.TrimSpace(qu.ObjToString(v["company_email"])) if emailreg.MatchString(cemail) { v["company_email"] = "********" + cemail[strings.Index(cemail, "@"):] } else { v["company_email"] = "" } company_phone := strings.TrimSpace(qu.ObjToString(v["company_phone"])) if telreg.MatchString(company_phone) || phonereg.MatchString(company_phone) { company_phone = company_phone[:len(company_phone)-5] + "****" v["company_phone"] = company_phone } else { v["company_phone"] = "" } } if v["filehref"] != nil { if filehrefs, ok := v["filehref"].([]map[string]interface{}); ok { urlArr := []string{} for _, href := range filehrefs { url := qu.ObjToString(href["url"]) urlArr = append(urlArr, url) } v["filehref"] = strings.Join(urlArr, ",") } else if filehrefs, ok := v["filehref"].([]interface{}); ok { urlArr := []string{} for _, href := range filehrefs { if hrefs, oks := href.(map[string]interface{}); oks { url := qu.ObjToString(hrefs["url"]) urlArr = append(urlArr, url) } } v["filehref"] = strings.Join(urlArr, ",") } } deletefields(qu.IntAll((*tagfield)["i_extfieldstype"]), &v) rdata = append(rdata, v) } tmp["keylist"] = []string{} for k := range matchskey { if k == "" { continue } tmp["keylist"] = append(tmp["keylist"].([]string), k) } tmp["data"] = rdata } } } f.ServeJson(tmp) } func (f *Private) Keydataoption(world string) { // destr := qu.SE.DecodeString(world) tmp := make(map[string]interface{}) idMap := make(map[string]bool) infoArr := []map[string]interface{}{} bytes := f.Body() err := json.Unmarshal(bytes, &tmp) newCount := 0 datas, _ := Mgo.FindOne("entniche_rule", bson.M{"s_dataid": world}) entId := qu.IntAll((*datas)["entId"]) entUserId := qu.IntAll((*datas)["entUserId"]) dataConfig, _ := Mgo.FindOne("datatag_export_config", map[string]interface{}{"ent_id": entId}) current := GetCurrentCount2(entId, entUserId) userData := JyMysql.FindOne("entniche_user", map[string]interface{}{"id": entUserId}, "phone", "") phone := "" if userData != nil && len(*userData) > 0 { phone = qu.ObjToString((*userData)["phone"]) } log.Println("数据余额", current) filterStr := "" isFirst := tmp["isFirst"].(bool) newIdArr := []string{} if err == nil { if idArr, ok := tmp["urls"].([]interface{}); ok { // idsArr := []string{} for _, v := range idArr { // idsArr = append(idsArr, v.(string)) idMap[v.(string)] = true } // filterStr = strings.Join(idsArr, ",") } res, ok := Mgo.Find("tagsdata", bson.M{"s_dataid": world}, `{"publishtime":-1}`, nil, false, -1, -1) if ok && res != nil && *res != nil && len(*res) > 0 { for _, v := range *res { infoid := qu.ObjToString(v["info_id"]) if idMap[infoid] { isExist, err := redis.Exists("export", "entexportdata_"+infoid+"_"+fmt.Sprintln(entId)) if err != nil { log.Println("企业订阅数据导出redis判重失败") } else if isExist { log.Println("数据重复,id ", infoid, "entid ", entId, "userid ", entUserId) } else { newCount++ } if !isFirst { v["id"] = infoid v["jybxhref"] = v["s_jyhref"] v["createtime"] = time.Now().Unix() v["phone"] = phone delete(v, "_id") newIdArr = append(newIdArr, infoid) } infoArr = append(infoArr, v) } } } } log.Println("数据量", len(infoArr)) log.Println("新导出", newCount) isExport := true if newCount > current { isExport = false } else { go func() { for _, v := range newIdArr { redis.Put("export", "entexportdata_"+v+"_"+fmt.Sprintln(entId), 1, -1) } }() } res := map[string]interface{}{ "count": len(infoArr), "newCount": newCount, "current": current, "isExport": isExport, } if !isFirst { if len(infoArr) > 0 { fields := []map[string]interface{}{} dataType := qu.IntAll((*dataConfig)["dataType"]) if (*dataConfig)["fields"] != nil { fieldsArr := qu.ObjArrToMapArr((*dataConfig)["fields"].([]interface{})) fields = fieldsArr } s_name := qu.ObjToString((*datas)["s_name"]) xlsxUrl := GetXlsxfile(infoArr, dataType, s_name, fields) log.Println("生成完成", xlsxUrl) exportId := SaveExportLog2(entId, entUserId, len(infoArr), newCount, xlsxUrl, "1", filterStr) DeductNum2(entId, newCount, entUserId, exportId) go func() { for k, _ := range infoArr { MgoSave.Save(SaveUserMail, infoArr[k]) } }() res["xlsxUrl"] = xlsxUrl } } f.ServeJson(res) } func GetXlsxfile(mMap []map[string]interface{}, dataType int, fn string, fields []map[string]interface{}) string { xf, err := xlsx.OpenFile("web/res/fields.xlsx") if err != nil { log.Println("fields file not foud", err.Error()) } style := xlsx.NewStyle() style.Font.Size = 12 style.Font.Bold = true style.Alignment.Vertical = "center" style.Alignment.Horizontal = "center" if dataType == 1 { sh := xf.Sheets[0] if len(fields) > 0 { for _, v := range fields { for _, vv := range v { cell := sh.Rows[0].AddCell() cell.SetValue(vv) cell.SetStyle(style) } } } for i, v := range mMap { row := sh.AddRow() row.AddCell().SetInt(i + 1) row.AddCell().SetValue(v["s_matchkey"]) row.AddCell().SetValue(v["area"]) row.AddCell().SetValue(v["city"]) row.AddCell().SetValue(v["title"]) row.AddCell().SetValue(v["subtype"]) if v["publishtime"] != nil { row.AddCell().SetValue(time.Unix(qu.Int64All(v["publishtime"]), 0).Format("2006-01-02")) } else { row.AddCell() } row.AddCell().SetValue(v["buyer"]) row.AddCell().SetValue(v["winner"]) if v["bidamount"] != nil { row.AddCell().SetFloat(qu.Float64All(v["bidamount"])) } else { row.AddCell() } row.AddCell().SetValue(v["projectname"]) row.AddCell().SetValue(v["detail"]) row.AddCell().SetValue(v["jybxhref"]) ids := SE.EncodeString(qu.ObjToString(v["id"])) row.AddCell().SetValue(ids) if len(fields) > 0 { for _, vv := range fields { for kk, _ := range vv { if v[kk] != nil { if kk == "filehref" { if filehrefs, ok := v["filehref"].([]interface{}); ok { urlArr := "" for _, href := range filehrefs { if hrefs, oks := href.(map[string]interface{}); oks { url := qu.ObjToString(hrefs["url"]) + "\n" urlArr += url } } row.AddCell().SetValue(urlArr) } } else if kk == "bidopentime" || kk == "bidendtime" { row.AddCell().SetValue(time.Unix(qu.Int64All(v[kk]), 0).Format("2006-01-02")) } else { row.AddCell().SetValue(v[kk]) } } else { row.AddCell() } } } } } xf.Sheets = xf.Sheets[0:1] } else if dataType == 2 { sh := xf.Sheets[1] if len(fields) > 0 { for _, v := range fields { for _, vv := range v { cell := sh.Rows[0].AddCell() cell.SetValue(vv) cell.SetStyle(style) } } } for _, v := range mMap { row := sh.AddRow() row.AddCell().SetValue(v["s_matchkey"]) row.AddCell().SetValue(v["area"]) row.AddCell().SetValue(v["city"]) row.AddCell().SetValue(v["title"]) row.AddCell().SetValue(v["subtype"]) row.AddCell().SetValue(v["detail"]) if v["publishtime"] != nil { row.AddCell().SetValue(time.Unix(qu.Int64All(v["publishtime"]), 0).Format("2006-01-02")) } else { row.AddCell() } row.AddCell().SetValue(v["href"]) row.AddCell().SetValue(v["jybxhref"]) row.AddCell().SetValue(v["projectname"]) row.AddCell().SetValue(v["projectcode"]) row.AddCell().SetValue(v["projectscope"]) if v["budget"] != nil { row.AddCell().SetFloat(qu.Float64All(v["budget"])) } else { row.AddCell() } if v["bidamount"] != nil { row.AddCell().SetFloat(qu.Float64All(v["bidamount"])) } else { row.AddCell() } if v["bidopentime"] != nil { row.AddCell().SetValue(time.Unix(qu.Int64All(v["bidopentime"]), 0).Format("2006-01-02")) } else { row.AddCell() } row.AddCell().SetValue(v["buyer"]) row.AddCell().SetValue(v["buyerperson"]) row.AddCell().SetValue(v["buyertel"]) row.AddCell().SetValue(v["agency"]) row.AddCell().SetValue(v["s_winner"]) row.AddCell().SetValue(v["winnerperson"]) row.AddCell().SetValue(v["winnertel"]) row.AddCell().SetValue(v["legal_person"]) row.AddCell().SetValue(v["company_phone"]) row.AddCell().SetValue(v["company_email"]) ids := SE.EncodeString(qu.ObjToString(v["id"])) row.AddCell().SetValue(ids) if len(fields) > 0 { for _, vv := range fields { for kk, _ := range vv { if v[kk] != nil { if kk == "filehref" { if filehrefs, ok := v["filehref"].([]interface{}); ok { urlArr := "" for _, href := range filehrefs { if hrefs, oks := href.(map[string]interface{}); oks { url := qu.ObjToString(hrefs["url"]) + "\n" urlArr += url } } row.AddCell().SetValue(urlArr) } } else if kk == "bidopentime" || kk == "bidendtime" { row.AddCell().SetValue(time.Unix(qu.Int64All(v[kk]), 0).Format("2006-01-02")) } else { row.AddCell().SetValue(v[kk]) } } else { row.AddCell() } } } } } xf.Sheets = xf.Sheets[1:2] } xf.Sheets[0].Name = "详细数据" //生文件 //t := strconv.FormatInt(time.Now().Unix(), 10) t := time.Now().Format("20060102") dir := "./web/res/xlsx/" + t + "/" if b, _ := PathExists(dir); !b { err1 := os.MkdirAll(dir, os.ModePerm) if err1 != nil { log.Println("mkdir err", dir) } } //fname := t + ".xlsx" fname := fmt.Sprintf("%s_%s_%s.xlsx", fn, t, qu.GetRandom(4)) log.Println("fname", fname) err = xf.Save(dir + fname) xlsxUrls := "/xlsx/" + t + "/" + fname return xlsxUrls } func PathExists(path string) (bool, error) { _, err := os.Stat(path) if err == nil { return true, nil } if os.IsNotExist(err) { return false, nil } return false, err } type keynum struct { Key string Num int } var gmail *gm.GmailAuth func urlToId(url string) string { url = pre.ReplaceAllString(url, "") url = suf.ReplaceAllString(url, "") return qu.CommonDecodeArticle("content", url)[0] } func deletefields(fieldnum int, data *map[string]interface{}) map[string]interface{} { rdata := make(map[string]interface{}) one, _ := Mgo.FindOne("code_fields", bson.M{}) if one != nil && len(*one) > 0 { for _, v := range (*one)[fmt.Sprintf("%d", fieldnum)].([]interface{}) { if (*data)[qu.ObjToString(v)] != nil { rdata[qu.ObjToString(v)] = (*data)[qu.ObjToString(v)] } } } return rdata } func sendMail(tag map[string]interface{}, option string) { jkmail, _ := Sysconfig["jkmail"].(map[string]interface{}) title := "标签系统" + qu.ObjToString(tag["s_customername"]) + "反馈信息" content := "客户姓名:" + qu.ObjToString(tag["s_customername"]) + "
" + "标签名称:" + qu.ObjToString(tag["s_name"]) + "
" + "销售经理:" + qu.ObjToString(tag["s_salesperson"]) + "
" + "反馈内容:" + option if jkmail != nil { tomail, _ := jkmail["to"].(string) api, _ := jkmail["api"].(string) log.Println("start send", tomail, Sysconfig["jkmail"]) res, err := http.Get(fmt.Sprintf("%s?to=%s&title=%s&body=%s", api, tomail, title, content)) if err == nil { defer res.Body.Close() read, err := ioutil.ReadAll(res.Body) log.Println("邮件发送:", string(read), err) } } }