|
@@ -0,0 +1,842 @@
|
|
|
+package util
|
|
|
+
|
|
|
+import (
|
|
|
+ "bytes"
|
|
|
+ "encoding/json"
|
|
|
+ "encoding/xml"
|
|
|
+ "fmt"
|
|
|
+ "jfw/config"
|
|
|
+ "log"
|
|
|
+ "net/rpc"
|
|
|
+ "qfw/util"
|
|
|
+ "qfw/util/mail"
|
|
|
+ "regexp"
|
|
|
+ "strings"
|
|
|
+ "sync"
|
|
|
+ "time"
|
|
|
+)
|
|
|
+
|
|
|
+var ExConf *DataexportConfig
|
|
|
+var WxStruct *WeixinStruct
|
|
|
+
|
|
|
+//价格配置文件
|
|
|
+type DataexportConfig struct {
|
|
|
+ UnitPrice_normal float64 `json:"unitPrice_normal"`
|
|
|
+ UnitPrice_senior float64 `json:"unitPrice_senior"`
|
|
|
+ Discount float64 `json:"discount"`
|
|
|
+ OrderMinPrice float64 `json:"orderMinPrice"`
|
|
|
+ MsgMaxCount int `json:"msgMaxCount"`
|
|
|
+ Standard_Fields *Dataexport_Field `json:"standard"`
|
|
|
+ Senior_Fields *Dataexport_Field `json:"senior"`
|
|
|
+ Mail_attach_content string `json:"mail_attach_content"`
|
|
|
+ Mail_attach_content_key string `json:"mail_attach_content_key"`
|
|
|
+ Mail_notice_content string `json:"mail_notice_content"`
|
|
|
+ Mail_notice_title string `json:"mail_notice_title"`
|
|
|
+ Mail_retry int `json:"mail_retry"`
|
|
|
+ AuditPersons []string `json:"auditPersons"`
|
|
|
+ Font Font `json:"font"`
|
|
|
+ Mail_invoice_finance_content string `json:"mail_invoice_finance_content"` //to北京财务订单内容
|
|
|
+ Mail_order_finance_content string `json:"mail_order_finance_content"` //to北京财务申请发票内容
|
|
|
+ Finance_emails []string `json:"finance_emails"`
|
|
|
+ Qmxdomain string `json:"qmxdomain"`
|
|
|
+ DataReportContent string `json:"dataReportContent"`
|
|
|
+}
|
|
|
+type Dataexport_Field struct {
|
|
|
+ Names []string `json:"names"`
|
|
|
+ Fields []string `json:"fields"`
|
|
|
+ Widths []float64 `json:"widths"`
|
|
|
+}
|
|
|
+
|
|
|
+type Font struct {
|
|
|
+ Enabled bool `json:"enabled"`
|
|
|
+ ConvertVersionDefault string `json:"convertVersionDefault"`
|
|
|
+ UnConvertVersionDefault string `json:"unConvertVersionDefault"`
|
|
|
+ MappingFileExt string `json:"mappingFileExt"`
|
|
|
+ MappingFilePath string `json:"mappingFilePath"`
|
|
|
+ RedisPool string `json:"redisPool"`
|
|
|
+ RedisKey string `json:"redisKey"`
|
|
|
+}
|
|
|
+
|
|
|
+type WeixinStruct struct {
|
|
|
+ Appid string
|
|
|
+ Mchid string
|
|
|
+ Key string
|
|
|
+ Dashang_attachmsg string
|
|
|
+ Dashang_bodymsg string
|
|
|
+ Dashang_detailmsg string
|
|
|
+ Sjdc_attachmsg string
|
|
|
+ Sjdc_bodymsg string
|
|
|
+ Sjdc_detailmsg string
|
|
|
+ Sjbg_msg string
|
|
|
+ Subvip_msg string
|
|
|
+ OpenidSwitch *map[string]interface{}
|
|
|
+}
|
|
|
+
|
|
|
+/*筛选条件--关键词*/
|
|
|
+type KeyWord struct {
|
|
|
+ Keyword string `json:"keyword"` //关键词
|
|
|
+ Appended []string `json:"appended"` //附加词
|
|
|
+ Exclude []string `json:"exclude"` //排除词
|
|
|
+}
|
|
|
+
|
|
|
+/*筛选条件*/
|
|
|
+type SieveCondition struct {
|
|
|
+ Id string `json:"id"`
|
|
|
+ PublishTime string `json:"publishtime"` //发布时间
|
|
|
+ Area []string `json:"area"` //地区-省份
|
|
|
+ City []string `json:"city"` //地区-城市
|
|
|
+ Region []string `json:"region"` //地区-省份+城市
|
|
|
+ Industry []string `json:"industry"` //行业
|
|
|
+ Keyword []KeyWord `json:"keywords"` //关键词
|
|
|
+ Buyer []string `json:"buyer"` //招标单位(采购单位)
|
|
|
+ Winner []string `json:"winner"` //中标单位
|
|
|
+ ComeInTime int64 `json:"comeintime"` //入库时间(秒)
|
|
|
+ OpenId string `json:"openid"` //用户openid
|
|
|
+ MinPrice string `json:"minprice"` //金额——最少
|
|
|
+ MaxPrice string `json:"maxprice"` //金额——最多
|
|
|
+ SelectType string `json:"selectType"` //筛选(正文 or 标题)
|
|
|
+ Subtype string `json:"subtype"` //信息类型
|
|
|
+ Comeinfrom string `json:"comeinfrom"` //查询来源
|
|
|
+}
|
|
|
+
|
|
|
+func (w *WeixinStruct) GetTradeno(tp string) string {
|
|
|
+ return fmt.Sprintf("%s_%d%s%s", tp, time.Now().UnixNano(), util.GetRandom(5), util.GetLetterRandom(6))
|
|
|
+}
|
|
|
+
|
|
|
+//tradeno a:打赏 b:pc端数据导出 c:移动端微信数据导出 C:app数据导出 d:微信端数据报告 D:app端数据报告
|
|
|
+func (w *WeixinStruct) CreatePrepayOrder(weixinrpc, tradeno, ip, openid, detailmsg string, totalfee int) (string, *map[string]string) {
|
|
|
+ defer util.Catch()
|
|
|
+ attachmsg, bodymsg := "", ""
|
|
|
+ tradeType := ""
|
|
|
+ notifyUrl := ""
|
|
|
+
|
|
|
+ if tradeno == "a" { //打赏
|
|
|
+ tradeType = "JSAPI"
|
|
|
+ attachmsg, bodymsg = w.Dashang_attachmsg, w.Dashang_bodymsg
|
|
|
+ notifyUrl = config.Sysconfig["webdomain"].(string) + "/weixin/pay/callback"
|
|
|
+ } else if tradeno == "b" { //数据导出
|
|
|
+ tradeType = "NATIVE"
|
|
|
+ attachmsg, bodymsg, detailmsg = w.Sjdc_attachmsg, w.Sjdc_bodymsg, w.Sjdc_detailmsg
|
|
|
+ notifyUrl = config.Sysconfig["webdomain"].(string) + "/weixin/pay/callback"
|
|
|
+ } else if tradeno == "c" || tradeno == "C" { //移动端数据导出支付C:APP c:wx
|
|
|
+ if tradeno == "c" {
|
|
|
+ tradeType = "JSAPI"
|
|
|
+ notifyUrl = config.Sysconfig["webdomain"].(string) + "/weixin/pay/callback"
|
|
|
+ } else {
|
|
|
+ tradeType = "APP"
|
|
|
+ notifyUrl = config.Sysconfig["webdomain"].(string) + "/jyapp/dataExport/wxpay/callback"
|
|
|
+ }
|
|
|
+ attachmsg, bodymsg, detailmsg = w.Sjdc_attachmsg, w.Sjdc_bodymsg, w.Sjdc_detailmsg
|
|
|
+ } else if tradeno == "d" || tradeno == "D" { //数据报告 d:公众号支付 D:App
|
|
|
+ attachmsg, bodymsg, detailmsg = w.Sjbg_msg, w.Sjbg_msg, w.Sjbg_msg
|
|
|
+ if tradeno == "d" {
|
|
|
+ tradeType = "JSAPI"
|
|
|
+ notifyUrl = config.Sysconfig["webdomain"].(string) + "/front/dataReport/payCallback"
|
|
|
+ } else {
|
|
|
+ tradeType = "APP"
|
|
|
+ notifyUrl = config.Sysconfig["webdomain"].(string) + "/jyapp/dataReport/wxpay/callback"
|
|
|
+ }
|
|
|
+ } else if tradeno == "e" || tradeno == "E" { //vip订阅
|
|
|
+ attachmsg, bodymsg, detailmsg = w.Subvip_msg, w.Subvip_msg, w.Subvip_msg
|
|
|
+ if tradeno == "e" {
|
|
|
+ tradeType = "JSAPI"
|
|
|
+ notifyUrl = config.Sysconfig["webdomain"].(string) + "/weixin/pay/callback"
|
|
|
+ } else if tradeno == "E" {
|
|
|
+ tradeType = "APP"
|
|
|
+ notifyUrl = config.Sysconfig["webdomain"].(string) + "/jyapp/dataReport/wxpay/callback"
|
|
|
+ }
|
|
|
+ }
|
|
|
+ tradeno = w.GetTradeno(tradeno)
|
|
|
+ //测试环境微信支付需要转换对应的正式环境的openid
|
|
|
+ if w.OpenidSwitch != nil {
|
|
|
+ if oid, ok := (*(w.OpenidSwitch))[openid]; ok {
|
|
|
+ openid = oid.(string)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //获取预订单号
|
|
|
+ ret, _ := w.GetPrepayId(weixinrpc, map[string]string{
|
|
|
+ "attachmsg": attachmsg,
|
|
|
+ "bodymsg": bodymsg,
|
|
|
+ "detailmsg": detailmsg,
|
|
|
+ "useropenid": openid,
|
|
|
+ "tradeno": tradeno,
|
|
|
+ "userip": ip,
|
|
|
+ "totalfee": fmt.Sprint(totalfee),
|
|
|
+ "mchid": w.Mchid,
|
|
|
+ "key": w.Key,
|
|
|
+ "notifyUrl": notifyUrl,
|
|
|
+ "appid": w.Appid,
|
|
|
+ "tradeType": tradeType, //NATIVE JSAPI APP
|
|
|
+ })
|
|
|
+ return tradeno, ret
|
|
|
+}
|
|
|
+
|
|
|
+//取得预生成订单编号,我们的系统要控制下,别订单重复了
|
|
|
+func (w *WeixinStruct) GetPrepayId(weixinrpc string, param map[string]string) (res *map[string]string, e error) {
|
|
|
+ util.Try(func() {
|
|
|
+ client, err := rpc.DialHTTP("tcp", weixinrpc)
|
|
|
+ defer client.Close()
|
|
|
+ if err != nil {
|
|
|
+ e = err
|
|
|
+ log.Println(err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ var ret []byte
|
|
|
+ err = client.Call("WeiXinRpc.GetPrepayId", param, &ret)
|
|
|
+ if err != nil {
|
|
|
+ e = err
|
|
|
+ log.Println(err.Error())
|
|
|
+ } else {
|
|
|
+ json.Unmarshal(ret, &res)
|
|
|
+ }
|
|
|
+ }, func(e interface{}) {})
|
|
|
+ return
|
|
|
+}
|
|
|
+
|
|
|
+func init() {
|
|
|
+ util.ReadConfig("./dataexport.json", &ExConf)
|
|
|
+}
|
|
|
+
|
|
|
+type myWrite struct {
|
|
|
+ Byte *bytes.Buffer
|
|
|
+}
|
|
|
+
|
|
|
+func (m *myWrite) Write(p []byte) (n int, err error) {
|
|
|
+ n, err = m.Byte.Write(p)
|
|
|
+ return
|
|
|
+}
|
|
|
+
|
|
|
+//发送邮箱验证码
|
|
|
+func SendMailIdentCode(to, code string, auth []*mail.GmailAuth) bool {
|
|
|
+ html := fmt.Sprintf(`<div>
|
|
|
+ <div>
|
|
|
+ %s,您好!
|
|
|
+ </div>
|
|
|
+ <div style="padding: 20px 70px 10px 70px;">
|
|
|
+ <p>您正在进行导出邮箱地址验证,请在邮件验证码输入框输入下方验证码:</p>
|
|
|
+ <span style="font-weight: bold;font-size: x-large;">%s</span>
|
|
|
+ <p>请勿向任何人泄露您收到的验证码。</p>
|
|
|
+ <p>如果您没有使用剑鱼标讯,请忽略此邮件。</p>
|
|
|
+ <p>此为系统邮件,请勿回复。</p>
|
|
|
+ <p>如有疑问,请联系客服 400-108-6670。</p>
|
|
|
+ </div>
|
|
|
+ <div>
|
|
|
+ <p>此致</p>
|
|
|
+ <p>剑鱼标讯</p>
|
|
|
+ </div>
|
|
|
+ </div>`, to, code)
|
|
|
+
|
|
|
+ for k, v := range auth {
|
|
|
+ if mail.GSendMail("剑鱼标讯", to, "", "", "剑鱼标讯邮箱校验", html, "", "", v) {
|
|
|
+ log.Println(to, fmt.Sprintf("使用%s发送邮件成功", v.User))
|
|
|
+ return true
|
|
|
+ }
|
|
|
+ if k < len(auth)-1 {
|
|
|
+ log.Println(to, fmt.Sprintf("使用%s发送邮件失败!3s后使用其他邮箱尝试", v.User))
|
|
|
+ } else {
|
|
|
+ log.Println(to, fmt.Sprintf("使用%s发送邮件失败!", v.User))
|
|
|
+ }
|
|
|
+ time.Sleep(time.Second * 3)
|
|
|
+ }
|
|
|
+
|
|
|
+ return false
|
|
|
+}
|
|
|
+
|
|
|
+//发送通知
|
|
|
+func SendNotice(order *map[string]interface{}, order_money float64, pay_time, download_url string, auth []*mail.GmailAuth) {
|
|
|
+ //order_id := util.Int64All((*order)["id"])
|
|
|
+ order_code := util.ObjToString((*order)["order_code"])
|
|
|
+ user_mail := util.ObjToString((*order)["user_mail"])
|
|
|
+ //data_spec := util.ObjToString((*order)["data_spec"])
|
|
|
+ //data_count := util.IntAll((*order)["data_count"])
|
|
|
+ url := fmt.Sprintf("%s%s", config.Sysconfig["webdomain"].(string), download_url)
|
|
|
+ // content := fmt.Sprintf(ExConf.Mail_notice_content, order_id, order_code, data_count, data_spec, order_money, pay_time, user_mail, url, url)
|
|
|
+ for _, audit := range ExConf.AuditPersons {
|
|
|
+ if regexp.MustCompile("^\\d+$").MatchString(audit) {
|
|
|
+ SendSMS("2828100", audit, map[string]string{
|
|
|
+ "name": order_code,
|
|
|
+ "username": user_mail,
|
|
|
+ "tel": url,
|
|
|
+ })
|
|
|
+ } else {
|
|
|
+ // if SendRetryMail(5, audit, ExConf.Mail_notice_title, content, "", nil, auth) {
|
|
|
+ // log.Println(audit, "数据导出通知邮件发送成功")
|
|
|
+ // }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+var finaceLock *sync.Mutex = &sync.Mutex{}
|
|
|
+
|
|
|
+//给北京财务人员发邮件
|
|
|
+func SendMailToBJFinance(order *map[string]interface{}, pay_time, transaction_id string, mailType int, auth []*mail.GmailAuth) {
|
|
|
+ defer util.Catch()
|
|
|
+ finaceLock.Lock()
|
|
|
+ defer finaceLock.Unlock()
|
|
|
+ order_code := util.ObjToString((*order)["order_code"])
|
|
|
+ user_mail := util.ObjToString((*order)["user_mail"])
|
|
|
+ user_phone := util.ObjToString((*order)["user_phone"])
|
|
|
+ data_spec := util.ObjToString((*order)["data_spec"])
|
|
|
+ data_count := util.IntAll((*order)["data_count"])
|
|
|
+ pay_way := util.ObjToString((*order)["pay_way"])
|
|
|
+
|
|
|
+ if strings.Contains(pay_way, "wx") {
|
|
|
+ pay_way = "微信"
|
|
|
+ } else if strings.Contains(pay_way, "ali") {
|
|
|
+ pay_way = "支付宝"
|
|
|
+ }
|
|
|
+
|
|
|
+ create_time := util.ObjToString((*order)["create_time"])
|
|
|
+ if create_time != "" {
|
|
|
+ create_time = strings.Replace(create_time, "-", ".", -1)
|
|
|
+ create_time = regexp.MustCompile(":[^:]+$").ReplaceAllString(create_time, "")
|
|
|
+ }
|
|
|
+ //
|
|
|
+ product_type := util.ObjToString((*order)["product_type"]) + "导出"
|
|
|
+ //
|
|
|
+ order_money := float64(util.IntAll((*order)["order_money"])) / 100
|
|
|
+
|
|
|
+ if transaction_id == "" {
|
|
|
+ transaction_id = func() string {
|
|
|
+ table := ""
|
|
|
+ if pay_way == "微信" {
|
|
|
+ table = "weixin_pay"
|
|
|
+ } else if pay_way == "支付宝" {
|
|
|
+ table = "ali_pay"
|
|
|
+ } else {
|
|
|
+ return ""
|
|
|
+ }
|
|
|
+ out_trade_no := util.ObjToString((*order)["out_trade_no"])
|
|
|
+ wxpaydata := Mysql.FindOne(table, map[string]interface{}{
|
|
|
+ "out_trade_no": out_trade_no,
|
|
|
+ }, "transaction_id", "")
|
|
|
+ if wxpaydata != nil && len(*wxpaydata) > 0 { //线下支付没有微信订单编号
|
|
|
+ return util.ObjToString((*wxpaydata)["transaction_id"])
|
|
|
+ }
|
|
|
+ return ""
|
|
|
+ }()
|
|
|
+ }
|
|
|
+ isShowTransaction := "" //支付订单号为空,邮件不显示此字段
|
|
|
+ if transaction_id == "" {
|
|
|
+ isShowTransaction = "none"
|
|
|
+ }
|
|
|
+ mailcontent := ""
|
|
|
+ var mail_title = ""
|
|
|
+ selectType := "title"
|
|
|
+ if mailType == 1 { //支付完成后给北京财务发送导出数据接口信息的邮件
|
|
|
+ filter := util.ObjToString((*order)["filter"])
|
|
|
+ buyer, winner, subtype := "", "", ""
|
|
|
+ publishtime, region, industry, keys := "", "", "", ""
|
|
|
+ sc_money := ""
|
|
|
+ sc := new(SieveCondition)
|
|
|
+ err := json.Unmarshal([]byte(filter), &sc)
|
|
|
+ if err == nil && sc != nil {
|
|
|
+ selectType = util.ObjToString(sc.SelectType)
|
|
|
+ if selectType == "title" {
|
|
|
+ selectType = "标题匹配"
|
|
|
+ } else {
|
|
|
+ selectType = "全文匹配"
|
|
|
+ }
|
|
|
+ //
|
|
|
+ if pay_time != "" {
|
|
|
+ pay_time = strings.Replace(pay_time, "-", ".", -1)
|
|
|
+ pay_time = regexp.MustCompile(":[^:]+$").ReplaceAllString(pay_time, "")
|
|
|
+ }
|
|
|
+ sc_money = GetPriceDes_SieveCondition(sc.MinPrice, sc.MaxPrice)
|
|
|
+ pts := strings.Split(sc.PublishTime, "_")
|
|
|
+ if len(pts) == 2 {
|
|
|
+ startTime, endTime := util.Int64All(pts[0]), util.Int64All(pts[1])
|
|
|
+ if startTime != 0 && endTime != 0 {
|
|
|
+ publishtime = fmt.Sprintf("%s-%s", util.FormatDateByInt64(&startTime, util.Date_yyyyMMdd_Point), util.FormatDateByInt64(&endTime, util.Date_yyyyMMdd_Point))
|
|
|
+ } else if startTime == 0 && endTime != 0 {
|
|
|
+ publishtime = fmt.Sprintf("%s前全部", util.FormatDateByInt64(&endTime, util.Date_yyyyMMdd_Point))
|
|
|
+ } else if startTime != 0 && endTime == 0 {
|
|
|
+ publishtime = fmt.Sprintf("%s-%s", util.FormatDateByInt64(&startTime, util.Date_yyyyMMdd_Point), create_time[:10])
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //超级搜索页面 筛选区域为 area 没有region 移动端数据导出改
|
|
|
+ if sc.Region == nil {
|
|
|
+ region = strings.Join(sc.Area, " ")
|
|
|
+ } else {
|
|
|
+ region = strings.Join(sc.Region, " ")
|
|
|
+ }
|
|
|
+ var industryBuffer bytes.Buffer
|
|
|
+ for k, v := range sc.Industry {
|
|
|
+ if k > 0 {
|
|
|
+ industryBuffer.WriteString(" ")
|
|
|
+ }
|
|
|
+ vs := strings.Split(v, "_")
|
|
|
+ if len(vs) == 1 {
|
|
|
+ industryBuffer.WriteString(vs[0])
|
|
|
+ } else {
|
|
|
+ industryBuffer.WriteString(vs[1])
|
|
|
+ }
|
|
|
+ }
|
|
|
+ industry = industryBuffer.String()
|
|
|
+ var keysBuffer bytes.Buffer
|
|
|
+ for _, v := range sc.Keyword {
|
|
|
+ keysBuffer.WriteString(fmt.Sprintf(ExConf.Mail_attach_content_key, v.Keyword, strings.Join(v.Appended, " "), strings.Join(v.Exclude, " ")))
|
|
|
+ }
|
|
|
+ keys = keysBuffer.String()
|
|
|
+ buyer = strings.Join(sc.Buyer, " ")
|
|
|
+ winner = strings.Join(sc.Winner, " ")
|
|
|
+ subtype = strings.Replace(sc.Subtype, ",", " ", -1)
|
|
|
+ } else {
|
|
|
+ log.Println("用户筛选条件错误", err, sc)
|
|
|
+ }
|
|
|
+ mail_title = "剑鱼标讯历史数据订单【" + order_code + "】,请查收"
|
|
|
+ mailcontent = fmt.Sprintf(ExConf.Mail_order_finance_content, order_code, create_time, pay_time, product_type, isShowTransaction, pay_way, transaction_id, data_spec, data_count, order_money, user_mail, user_phone, publishtime, region, industry, keys, selectType, sc_money, subtype, buyer, winner)
|
|
|
+ } else if mailType == 2 {
|
|
|
+ //申请发票
|
|
|
+ pay_time = util.ObjToString((*order)["pay_time"])
|
|
|
+ if pay_time != "" {
|
|
|
+ pay_time = strings.Replace(pay_time, "-", ".", -1)
|
|
|
+ pay_time = regexp.MustCompile(":[^:]+$").ReplaceAllString(pay_time, "")
|
|
|
+ }
|
|
|
+ applybill_type := util.IntAll((*order)["applybill_type"])
|
|
|
+ bill_title := "个人"
|
|
|
+ bill_company := ""
|
|
|
+ bill_taxnum := ""
|
|
|
+ company_flag := "none"
|
|
|
+ taxnum_flag := "none"
|
|
|
+ if applybill_type != 0 {
|
|
|
+ bill_title = "单位"
|
|
|
+ bill_company = util.ObjToString((*order)["applybill_company"])
|
|
|
+ bill_taxnum = util.ObjToString((*order)["applybill_taxnum"])
|
|
|
+ company_flag = "flex"
|
|
|
+ taxnum_flag = "flex"
|
|
|
+ }
|
|
|
+ //线下支付获取凭证照片
|
|
|
+ offlineImgSrc := ""
|
|
|
+ if (*order)["pay_way"] == "线下支付" {
|
|
|
+ offlinePayMap := map[string]interface{}{}
|
|
|
+ offlinePayMap["out_trade_no"] = (*order)["out_trade_no"]
|
|
|
+ offlinePay := Mysql.FindOne("offline_pay", offlinePayMap, "", "create_time desc")
|
|
|
+ if imgs := util.ObjToString((*offlinePay)["img_src"]); imgs != "" {
|
|
|
+ ImgArr := strings.Split(imgs, ",")
|
|
|
+ offlineImgSrc = "<p style='margin: 0px 0px 1px; font-size: 14px; color: rgb(29, 29, 29);'>线下支付凭证:%s</p>"
|
|
|
+ for k, v := range ImgArr {
|
|
|
+ var add = ",%s"
|
|
|
+ if k == len(ImgArr)-1 {
|
|
|
+ add = ""
|
|
|
+ }
|
|
|
+ pz := fmt.Sprintf("<a href='%s'>凭证%d</a>%s", ExConf.Qmxdomain+v, k+1, add)
|
|
|
+ offlineImgSrc = fmt.Sprintf(offlineImgSrc, pz)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ mail_title = "电子发票申请,剑鱼标讯历史数据订单【" + order_code + "】,请查收"
|
|
|
+ mailcontent = fmt.Sprintf(ExConf.Mail_invoice_finance_content, bill_title, company_flag, bill_company, taxnum_flag, bill_taxnum, order_code, create_time, pay_time, product_type, isShowTransaction, pay_way, transaction_id, offlineImgSrc, data_spec, data_count, order_money, user_mail, user_phone)
|
|
|
+ } else if mailType == 3 {
|
|
|
+ //2.8.5给北京财务发邮件内容
|
|
|
+ }
|
|
|
+ //发送邮件
|
|
|
+ for _, finance_mail := range ExConf.Finance_emails {
|
|
|
+ if regexp.MustCompile("^\\d+$").MatchString(finance_mail) {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ if finance_mail != "" {
|
|
|
+ finance_remark := "剑鱼标讯历史数据订单支付邮件"
|
|
|
+ if mailType == 2 {
|
|
|
+ finance_remark = "剑鱼标讯历史数据订单发票申请邮件"
|
|
|
+ }
|
|
|
+ if SendRetryMail(ExConf.Mail_retry, finance_mail, mail_title, mailcontent, "", nil, auth) {
|
|
|
+ log.Println(finance_mail, "北京财务:"+finance_remark+"发送成功!")
|
|
|
+ } else {
|
|
|
+ log.Println(finance_mail, "北京财务:"+finance_remark+"发送失败!")
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ log.Println(finance_mail, "北京财务:邮件地址为空")
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+////给已经付费的用户发邮件
|
|
|
+//func SendMailToPayUser(order *map[string]interface{}, order_money float64, pay_time, filename, download_url string, auth []*mail.GmailAuth) {
|
|
|
+// defer util.Catch()
|
|
|
+// log.Println("给已经付费的用户发邮件")
|
|
|
+// order_id := util.Int64All((*order)["id"])
|
|
|
+// order_code := util.ObjToString((*order)["order_code"])
|
|
|
+// user_mail := util.ObjToString((*order)["user_mail"])
|
|
|
+// user_phone := util.ObjToString((*order)["user_phone"])
|
|
|
+// data_spec := util.ObjToString((*order)["data_spec"])
|
|
|
+// data_count := util.IntAll((*order)["data_count"])
|
|
|
+// //
|
|
|
+// filter_id := util.ObjToString((*order)["filter_id"])
|
|
|
+// filter := util.ObjToString((*order)["filter"])
|
|
|
+// product_type := util.ObjToString((*order)["product_type"]) + "导出"
|
|
|
+// //
|
|
|
+// create_time := util.ObjToString((*order)["create_time"])
|
|
|
+// if create_time != "" {
|
|
|
+// create_time = strings.Replace(create_time, "-", ".", -1)
|
|
|
+// create_time = regexp.MustCompile(":[^:]+$").ReplaceAllString(create_time, "")
|
|
|
+// }
|
|
|
+// //
|
|
|
+// file := xlsx.NewFile()
|
|
|
+// sheet, _ := file.AddSheet("Sheet1")
|
|
|
+// var row *xlsx.Row
|
|
|
+// var cell *xlsx.Cell
|
|
|
+// //边框
|
|
|
+// border := xlsx.Border{
|
|
|
+// Left: "thin",
|
|
|
+// LeftColor: "00A6A6A6",
|
|
|
+// Right: "thin",
|
|
|
+// RightColor: "00A6A6A6",
|
|
|
+// Top: "thin",
|
|
|
+// TopColor: "00A6A6A6",
|
|
|
+// Bottom: "thin",
|
|
|
+// BottomColor: "00A6A6A6",
|
|
|
+// }
|
|
|
+// //对齐方式
|
|
|
+// alignment := xlsx.Alignment{
|
|
|
+// Horizontal: "center",
|
|
|
+// Vertical: "center",
|
|
|
+// WrapText: true,
|
|
|
+// }
|
|
|
+// //增加标题
|
|
|
+// row = sheet.AddRow()
|
|
|
+// row.SetHeight(30)
|
|
|
+// var names []string
|
|
|
+// var fields []string
|
|
|
+// var widths []float64
|
|
|
+// dataType := "1"
|
|
|
+// if data_spec == "标准字段包" {
|
|
|
+// names = ExConf.Standard_Fields.Names
|
|
|
+// fields = ExConf.Standard_Fields.Fields
|
|
|
+// widths = ExConf.Standard_Fields.Widths
|
|
|
+// } else if data_spec == "高级字段包" {
|
|
|
+// dataType = "2"
|
|
|
+// names = ExConf.Senior_Fields.Names
|
|
|
+// fields = ExConf.Senior_Fields.Fields
|
|
|
+// widths = ExConf.Senior_Fields.Widths
|
|
|
+// }
|
|
|
+// style1 := &xlsx.Style{
|
|
|
+// Fill: *xlsx.NewFill("solid", "00DDD9C4", "00DDD9C4"),
|
|
|
+// Border: border,
|
|
|
+// Alignment: alignment,
|
|
|
+// }
|
|
|
+// for k, name := range names {
|
|
|
+// cell = row.AddCell()
|
|
|
+// cell.SetString(name)
|
|
|
+// cell.SetStyle(style1)
|
|
|
+// if k < len(widths) {
|
|
|
+// sheet.Col(k).Width = widths[k]
|
|
|
+// }
|
|
|
+// }
|
|
|
+// //增加其他
|
|
|
+// style2 := &xlsx.Style{
|
|
|
+// Border: border,
|
|
|
+// Alignment: alignment,
|
|
|
+// }
|
|
|
+// list, _ := GetDataExportSearchResultUseId(filter_id, dataType, data_count)
|
|
|
+// if list != nil {
|
|
|
+// for _, v := range *list {
|
|
|
+// row = sheet.AddRow()
|
|
|
+// row.SetHeight(50)
|
|
|
+// for _, field := range fields {
|
|
|
+// cell = row.AddCell()
|
|
|
+// cell.SetValue(v[field])
|
|
|
+// cell.SetStyle(style2)
|
|
|
+// }
|
|
|
+// }
|
|
|
+// } else {
|
|
|
+// log.Println(user_mail, "数据导出邮件没有获取到数据!")
|
|
|
+// }
|
|
|
+// dir := "./web/staticres/res/dataexport"
|
|
|
+// if strings.Contains(download_url, "jyapp") {
|
|
|
+// dir = "./web/staticres/jyapp/res/dataexport"
|
|
|
+// }
|
|
|
+// _, path_error := os.Stat(dir)
|
|
|
+// if path_error != nil && os.IsNotExist(path_error) {
|
|
|
+// // 创建文件夹
|
|
|
+// os.MkdirAll(dir, os.ModePerm)
|
|
|
+// }
|
|
|
+// err := file.Save(dir + "/" + filename)
|
|
|
+// if err != nil {
|
|
|
+// log.Println(user_mail, filename, "生成附件文件错误:", err)
|
|
|
+// }
|
|
|
+// // mw := &myWrite{
|
|
|
+// // Byte: &bytes.Buffer{},
|
|
|
+// // }
|
|
|
+// // err = file.Write(mw)
|
|
|
+// // if err != nil {
|
|
|
+// // log.Println(user_mail, "数据导出生成excel失败!", err)
|
|
|
+// // }
|
|
|
+// // bt := mw.Byte.Bytes()
|
|
|
+// now := time.Now()
|
|
|
+// //fname := fmt.Sprintf("%s.xlsx", order_code)
|
|
|
+// //
|
|
|
+// mailcontent := ""
|
|
|
+// buyer, winner, subtype := "", "", ""
|
|
|
+// publishtime, region, industry, keys := "", "", "", ""
|
|
|
+// sc_money := ""
|
|
|
+// sc := new(SieveCondition)
|
|
|
+// err = json.Unmarshal([]byte(filter), &sc)
|
|
|
+// selectType := "title"
|
|
|
+// if err == nil && sc != nil {
|
|
|
+// selectType = util.ObjToString(sc.SelectType)
|
|
|
+// if selectType == "title" {
|
|
|
+// selectType = "标题匹配"
|
|
|
+// } else {
|
|
|
+// selectType = "全文匹配"
|
|
|
+// }
|
|
|
+// //
|
|
|
+// if pay_time != "" {
|
|
|
+// pay_time = strings.Replace(pay_time, "-", ".", -1)
|
|
|
+// pay_time = regexp.MustCompile(":[^:]+$").ReplaceAllString(pay_time, "")
|
|
|
+// }
|
|
|
+// sc_money = GetPriceDes_SieveCondition(sc.MinPrice, sc.MaxPrice)
|
|
|
+// pts := strings.Split(sc.PublishTime, "_")
|
|
|
+// if len(pts) == 2 {
|
|
|
+// startTime, endTime := util.Int64All(pts[0]), util.Int64All(pts[1])
|
|
|
+// if startTime != 0 && endTime != 0 {
|
|
|
+// publishtime = fmt.Sprintf("%s-%s", util.FormatDateByInt64(&startTime, util.Date_yyyyMMdd_Point), util.FormatDateByInt64(&endTime, util.Date_yyyyMMdd_Point))
|
|
|
+// } else if startTime == 0 && endTime != 0 {
|
|
|
+// publishtime = fmt.Sprintf("%s前全部", util.FormatDateByInt64(&endTime, util.Date_yyyyMMdd_Point))
|
|
|
+// } else if startTime != 0 && endTime == 0 {
|
|
|
+// publishtime = fmt.Sprintf("%s-%s", util.FormatDateByInt64(&startTime, util.Date_yyyyMMdd_Point), create_time[:10])
|
|
|
+// }
|
|
|
+// }
|
|
|
+// //超级搜索页面 筛选区域为 area 没有region 移动端数据导出改
|
|
|
+// if sc.Region == nil {
|
|
|
+// region = strings.Join(sc.Area, " ")
|
|
|
+// } else {
|
|
|
+// region = strings.Join(sc.Region, " ")
|
|
|
+// }
|
|
|
+// var industryBuffer bytes.Buffer
|
|
|
+// for k, v := range sc.Industry {
|
|
|
+// if k > 0 {
|
|
|
+// industryBuffer.WriteString(" ")
|
|
|
+// }
|
|
|
+// vs := strings.Split(v, "_")
|
|
|
+// if len(vs) == 1 {
|
|
|
+// industryBuffer.WriteString(vs[0])
|
|
|
+// } else {
|
|
|
+// industryBuffer.WriteString(vs[1])
|
|
|
+// }
|
|
|
+// }
|
|
|
+// industry = industryBuffer.String()
|
|
|
+// var keysBuffer bytes.Buffer
|
|
|
+// for _, v := range sc.Keyword {
|
|
|
+// keysBuffer.WriteString(fmt.Sprintf(ExConf.Mail_attach_content_key, v.Keyword, strings.Join(v.Appended, " "), strings.Join(v.Exclude, " ")))
|
|
|
+// }
|
|
|
+// keys = keysBuffer.String()
|
|
|
+// buyer = strings.Join(sc.Buyer, " ")
|
|
|
+// winner = strings.Join(sc.Winner, " ")
|
|
|
+// subtype = strings.Replace(sc.Subtype, ",", " ", -1)
|
|
|
+// } else {
|
|
|
+// log.Println("用户筛选条件错误", err, sc)
|
|
|
+// }
|
|
|
+// downloadurl := fmt.Sprintf("%s%s", config.Sysconfig["webdomain"].(string), download_url)
|
|
|
+// mailcontent = fmt.Sprintf(ExConf.Mail_attach_content, downloadurl, order_code, create_time, pay_time, product_type, data_spec, data_count, order_money, user_mail, user_phone, publishtime, region, industry, keys, selectType, sc_money, subtype, buyer, winner)
|
|
|
+// //发送邮件
|
|
|
+// if user_mail != "" {
|
|
|
+// if SendRetryMail(ExConf.Mail_retry, user_mail, "历史数据", mailcontent, "", nil, auth) {
|
|
|
+// log.Println(user_mail, "用户:数据导出附件邮件发送成功!")
|
|
|
+// Mysql.Update("dataexport_order", map[string]interface{}{
|
|
|
+// "id": order_id,
|
|
|
+// }, map[string]interface{}{
|
|
|
+// "service_status": 1,
|
|
|
+// "service_time": util.FormatDate(&now, util.Date_Full_Layout),
|
|
|
+// })
|
|
|
+// } else {
|
|
|
+// log.Println(user_mail, "用户:数据导出邮件发送失败!")
|
|
|
+// }
|
|
|
+// } else {
|
|
|
+// log.Println(user_mail, "用户:用户邮件地址为空")
|
|
|
+// }
|
|
|
+// for _, audit := range ExConf.AuditPersons {
|
|
|
+// if regexp.MustCompile("^\\d+$").MatchString(audit) {
|
|
|
+// continue
|
|
|
+// }
|
|
|
+// if SendRetryMail(ExConf.Mail_retry, audit, "历史数据", mailcontent, "", nil, auth) {
|
|
|
+// log.Println(audit, "管理员:数据导出附件邮件发送成功!")
|
|
|
+// } else {
|
|
|
+// log.Println(audit, "管理员:数据导出邮件发送失败!")
|
|
|
+// }
|
|
|
+// }
|
|
|
+//}
|
|
|
+
|
|
|
+func GetWaitPayToken(orderid int64, order_money int, ordercode, payway, userid string) string {
|
|
|
+ return util.GetMd5String(fmt.Sprintf("%d_%d_%s_%s_%s", orderid, order_money, ordercode, payway, userid))
|
|
|
+}
|
|
|
+func GetOrderCode_(id string) string {
|
|
|
+ return fmt.Sprintf("%s%s", time.Now().Format("150405"), util.GetRandom(6))
|
|
|
+}
|
|
|
+func SendRetryMail(retry int, user_mail, subject, content, fname string, bt []byte, auth []*mail.GmailAuth) bool {
|
|
|
+ for i := 1; i <= retry; i++ {
|
|
|
+ for _, v := range auth { //使用多个邮箱尝试发送
|
|
|
+ if mail.GSendMail_B("剑鱼标讯", user_mail, "", "", subject, content, fname, bt, v) {
|
|
|
+ return true
|
|
|
+ }
|
|
|
+ t := time.Duration(i) * 30 * time.Second
|
|
|
+ log.Println(user_mail, fmt.Sprintf("第%d轮,使用%s发送邮件失败!%v后重试", i, v.User, t))
|
|
|
+ time.Sleep(t)
|
|
|
+ }
|
|
|
+ if i == retry {
|
|
|
+ log.Println(user_mail, fmt.Sprintf("发送邮件失败"))
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return false
|
|
|
+}
|
|
|
+
|
|
|
+/*
|
|
|
+ 获取-筛选条件-金额
|
|
|
+*/
|
|
|
+func GetPriceDes_SieveCondition(minPrice, maxPrice string) string {
|
|
|
+ des := ""
|
|
|
+ unit := "万元"
|
|
|
+ if minPrice != "" && maxPrice != "" {
|
|
|
+ des = minPrice + unit + "—" + maxPrice + unit
|
|
|
+ } else if minPrice != "" {
|
|
|
+ des = "大于" + minPrice + unit
|
|
|
+ } else if maxPrice != "" {
|
|
|
+ des = "小于" + maxPrice + unit
|
|
|
+ }
|
|
|
+ return des
|
|
|
+}
|
|
|
+
|
|
|
+//微信支付订单关闭
|
|
|
+func (w *WeixinStruct) CloseOrder(weixinrpc, tradeno string) (r bool) {
|
|
|
+ util.Try(func() {
|
|
|
+ client, err := rpc.DialHTTP("tcp", weixinrpc)
|
|
|
+ defer client.Close()
|
|
|
+ if err != nil {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ err = client.Call("WeiXinRpc.CloseOrder",
|
|
|
+ map[string]string{
|
|
|
+ "tradeno": tradeno,
|
|
|
+ "key": w.Key,
|
|
|
+ "mchid": w.Mchid,
|
|
|
+ "appid": w.Appid,
|
|
|
+ }, &r)
|
|
|
+ if err != nil {
|
|
|
+ log.Println(err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ }, func(e interface{}) {})
|
|
|
+ return r
|
|
|
+}
|
|
|
+
|
|
|
+//微信js支付获取支付参数
|
|
|
+func (w *WeixinStruct) GetWxjsPaySign(prepayid string) string {
|
|
|
+ timestamp := time.Now().Unix()
|
|
|
+ nonceStr := util.GetRandom(16) + util.GetLetterRandom(16)
|
|
|
+ sign := util.WxSign(fmt.Sprintf("appId=%s&nonceStr=%s&package=%s&signType=%s&timeStamp=%d&key=%s", w.Appid, nonceStr, "prepay_id="+prepayid, "MD5", timestamp, w.Key))
|
|
|
+ res := map[string]interface{}{
|
|
|
+ "appId": w.Appid,
|
|
|
+ "timestamp": fmt.Sprint(timestamp),
|
|
|
+ "signType": "MD5",
|
|
|
+ "sign": sign,
|
|
|
+ "nonceStr": nonceStr,
|
|
|
+ "prepayId": "prepay_id=" + prepayid,
|
|
|
+ }
|
|
|
+ byteArr, _ := json.Marshal(res)
|
|
|
+ return string(byteArr)
|
|
|
+}
|
|
|
+
|
|
|
+//微信app支付 获取支付串
|
|
|
+func (wx *WeixinStruct) GetAppWxPayStr(prepayid string) string {
|
|
|
+ data := struct {
|
|
|
+ XMLName xml.Name `xml:"xml"`
|
|
|
+ Appid string `xml:"appid"`
|
|
|
+ Partnerid string `xml:"partnerid"` //微信支付分配的商户号
|
|
|
+ Prepayid string `xml:"prepayid"` //微信返回的支付交易会话ID
|
|
|
+ PackageStr string `xml:"package"` //暂填写固定值Sign=WXPay
|
|
|
+ Noncestr string `xml:"noncestr"` //随机字符串,不长于32位。
|
|
|
+ Timestamp string `xml:"timestamp"` //时间戳
|
|
|
+ Sign string `xml:"sign"` //签名
|
|
|
+ }{
|
|
|
+ Appid: wx.Appid,
|
|
|
+ Partnerid: wx.Mchid,
|
|
|
+ Prepayid: prepayid,
|
|
|
+ PackageStr: "Sign=WXPay",
|
|
|
+ Noncestr: util.GetRandom(16) + util.GetLetterRandom(16),
|
|
|
+ Timestamp: fmt.Sprintf("%d", time.Now().Unix()),
|
|
|
+ }
|
|
|
+ data.Sign = util.CreateWxSign(fmt.Sprintf("&key=%s", wx.Key), data)
|
|
|
+
|
|
|
+ byteArr, err := json.Marshal(data)
|
|
|
+ if err != nil {
|
|
|
+ log.Printf("CreatePrepayOrder Marshal %v\n", err)
|
|
|
+ return ""
|
|
|
+ }
|
|
|
+ return string(byteArr)
|
|
|
+}
|
|
|
+
|
|
|
+//数据报告发送邮件
|
|
|
+func SendDatareportMailToPayUser(report_id int, out_trade_no, user_mail string, auth []*mail.GmailAuth) {
|
|
|
+ res := Mysql.FindOne("jy_datareport", map[string]interface{}{
|
|
|
+ "report_id": report_id,
|
|
|
+ }, "s_url", "")
|
|
|
+ if res == nil || (*res)["s_url"] == "" {
|
|
|
+ log.Println("%d:未知数据报告\n", report_id)
|
|
|
+ return
|
|
|
+ }
|
|
|
+ mailcontent := fmt.Sprintf(ExConf.DataReportContent, config.Sysconfig["webdomain"].(string)+(*res)["s_url"].(string))
|
|
|
+ if SendRetryMail(ExConf.Mail_retry, user_mail, "数据报告", mailcontent, "", nil, auth) {
|
|
|
+ log.Printf("用户%s:数据报告附件邮件发送成功!数据报告id:%d\n", user_mail, report_id)
|
|
|
+ now := time.Now()
|
|
|
+ Mysql.Update("jy_datareport_order", map[string]interface{}{
|
|
|
+ "out_trade_no": out_trade_no,
|
|
|
+ "report_id": report_id,
|
|
|
+ }, map[string]interface{}{
|
|
|
+ "service_status": 1,
|
|
|
+ "service_time": util.FormatDate(&now, util.Date_Full_Layout),
|
|
|
+ })
|
|
|
+ } else {
|
|
|
+ log.Printf("%s数据报告发送邮件出错,数据报告id:%d\n", out_trade_no, report_id)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+//数据报告回显信息
|
|
|
+func GetBrforeMsg(userId, openId string) (name, phone, company, email string) {
|
|
|
+ order := Mysql.FindOne("jy_datareport_order", map[string]interface{}{
|
|
|
+ "user_id": userId,
|
|
|
+ }, "user_name,user_mail,user_phone,user_company", "create_time desc")
|
|
|
+ if order != nil {
|
|
|
+ name = util.ObjToString((*order)["user_name"])
|
|
|
+ phone = util.ObjToString((*order)["user_phone"])
|
|
|
+ company = util.ObjToString((*order)["user_company"])
|
|
|
+ email = util.ObjToString((*order)["user_mail"])
|
|
|
+ } else {
|
|
|
+ //之前没有数据报告订单查询数据导出 带出公司 手机号 邮箱字段
|
|
|
+ res := Mysql.FindOne("dataexport_order", map[string]interface{}{
|
|
|
+ "user_id": userId,
|
|
|
+ }, "user_mail,user_phone,applybill_company", "create_time desc")
|
|
|
+ if res != nil {
|
|
|
+ email = util.ObjToString((*res)["user_mail"])
|
|
|
+ phone = util.ObjToString((*res)["user_phone"])
|
|
|
+ company = util.ObjToString((*res)["applybill_company"])
|
|
|
+ log.Println(email, ",", phone)
|
|
|
+ }
|
|
|
+ if email == "" || phone == "" || openId == "" {
|
|
|
+ userData, _ := MQFW.FindById("user", userId, `{"o_jy":1,"s_phone":1,"s_m_openid":1}`)
|
|
|
+ if userData != nil {
|
|
|
+ if email == "" {
|
|
|
+ o_jy := util.ObjToMap((*userData)["o_jy"])
|
|
|
+ email = util.ObjToString((*o_jy)["s_email"])
|
|
|
+ }
|
|
|
+ if phone == "" {
|
|
|
+ phone = util.ObjToString((*userData)["s_phone"])
|
|
|
+ }
|
|
|
+ if openId == "" {
|
|
|
+ openId = util.ObjToString((*userData)["s_m_openid"])
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //查询开通推送公司名称
|
|
|
+ if openId != "" && (company == "" || phone == "") {
|
|
|
+ if myapply, ok := MQFW.FindOne("applysub_user", `{"s_openid":"`+openId+`"}`); ok {
|
|
|
+ if company == "" {
|
|
|
+ company = util.ObjToString((*myapply)["s_company"])
|
|
|
+ }
|
|
|
+ if phone == "" {
|
|
|
+ phone = util.ObjToString((*myapply)["s_phone"])
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return
|
|
|
+}
|