Przeglądaj źródła

Merge branch 'hotfix/v4.10.29.1' into feature/v4.10.19

yuelujie 1 miesiąc temu
rodzic
commit
e7da5d4697

+ 183 - 0
src/jfw/front/material.go

@@ -0,0 +1,183 @@
+package front
+
+import (
+	util "app.yhyue.com/moapp/jybase/common"
+	"app.yhyue.com/moapp/jybase/encrypt"
+	"app.yhyue.com/moapp/jybase/go-xweb/xweb"
+	"app.yhyue.com/moapp/jybase/redis"
+	"app.yhyue.com/moapp/jypkg/public"
+	"bytes"
+	"encoding/base64"
+	"encoding/json"
+	"errors"
+	"fmt"
+	"image"
+	"image/jpeg"
+	"image/png"
+	"jy/src/jfw/config"
+	"log"
+	"net/http"
+	"sync"
+	"time"
+)
+
+type Material struct {
+	*xweb.Action
+	//fileDownload xweb.Mapper `xweb:"/material/fileDownload"` //移动端消息三级页
+	linkTransfer xweb.Mapper `xweb:"/material/(\\w+)/(.*)"` //移动端消息三级页 物料id 渠道码
+}
+
+func init() {
+	xweb.AddAction(&Material{})
+	time.AfterFunc(2*time.Minute, SaveLogTask)
+}
+
+func (m *Material) FileDownload() error {
+	ossUrl := m.GetString("ossUrl")
+	if ossUrl == "" {
+		return errors.New("ossUrl参数缺失")
+	}
+	img, imgType, err := downloadImage(ossUrl)
+	if err != nil {
+		log.Println("文件下载失败:", ossUrl)
+		return err
+	}
+	imgBase, err := ImageToBase64(img, imgType)
+	if imgBase != "" && err == nil {
+		m.ServeJson(map[string]interface{}{
+			"imgBase": fmt.Sprintf("data:%s;base64,%s", imgType, imgBase),
+		})
+		return nil
+	}
+	return err
+}
+
+// 物料二维码链接或者图文链接中转接口  //链接格式   /material?mid=
+func (m *Material) LinkTransfer(mid, personChannel string) error {
+	sess := m.Session().GetMultiple()
+	mlid := encrypt.SE.DecodeString(mid)
+	types, _ := m.GetInteger("types")
+
+	realUrl, imgWebpage := "", ""
+	res := public.Mysql.SelectBySql("SELECT qrcode_url,img_webpage FROM bi_service.operating_materials WHERE id = ?", util.IntAll(mlid))
+	if res != nil && len(*res) > 0 {
+		realUrl = util.InterfaceToStr((*res)[0]["qrcode_url"])
+		imgWebpage = util.InterfaceToStr((*res)[0]["img_webpage"])
+	}
+	if realUrl == "" && imgWebpage == "" {
+		return m.Redirect(util.InterfaceToStr(config.Sysconfig["webdomain"]))
+	}
+	redis.Put("limitation", fmt.Sprintf("firstVisitTagByWX_%s", m.Session().Id()), fmt.Sprintf("materials_%s", personChannel), cacheTimeOut) //登录注册 用户标识
+	addLog(sess, m.Request, util.IntAll(mlid), types, personChannel, realUrl)
+	log.Println("重定向链接:", mlid, realUrl, imgWebpage)
+	if types == 1 {
+		return m.Redirect(imgWebpage)
+	} else {
+		return m.Redirect(realUrl)
+	}
+}
+
+func ImageToBase64(img image.Image, format string) (string, error) {
+	var buf bytes.Buffer
+	switch format {
+	case "jpeg", "jpg":
+		if err := jpeg.Encode(&buf, img, &jpeg.Options{Quality: 90}); err != nil {
+			return "", err
+		}
+	case "png":
+		if err := png.Encode(&buf, img); err != nil { // 需导入 image/png
+			return "", err
+		}
+	default:
+		return "", fmt.Errorf("unsupported format: %s", format)
+	}
+	// Base64 编码
+	encoded := base64.StdEncoding.EncodeToString(buf.Bytes())
+	return encoded, nil
+}
+
+// 下载图片
+func downloadImage(url string) (image.Image, string, error) {
+	resp, err := http.Get(url)
+	if err != nil {
+		return nil, "", err
+	}
+	defer resp.Body.Close()
+
+	img, imgType, err := image.Decode(resp.Body)
+	if err != nil {
+		return nil, "", err
+	}
+
+	return img, imgType, nil
+}
+
+// 内存缓存日志数量,超过此数量存库
+var nc = 100
+
+// 内存缓存日志map
+var arr = make([]map[string]interface{}, 0)
+
+// 对map的同步
+var lock sync.Mutex
+
+func addLog(sess map[string]interface{}, req *http.Request, mid, types int, parsonchannel, realUrl string) {
+	//log.Println("存储访问日志")
+	timeNow := time.Now()
+	agent := req.Header.Get("user-agent")
+	md, _ := json.Marshal(req.Form)
+	str := string(md)
+	logs := map[string]interface{}{
+		"types":         types,
+		"materialid":    mid,
+		"personchannel": parsonchannel,
+		"date":          timeNow.Unix(),
+		"ip":            req.Proto,
+		"refer":         req.Referer(),
+		"year":          timeNow.Year(),
+		"month":         timeNow.Month(),
+		"day":           timeNow.Day(),
+		"hour":          timeNow.Hour(),
+		"minutes":       timeNow.Minute(),
+		"mdescribe":     str,
+		"client":        agent,
+		"os":            util.GetOS(agent),
+		"browse":        util.GetBrowse(agent),
+		"method":        req.Method,
+		"url":           req.RequestURI,
+		"realUrl":       realUrl,
+	}
+	if userId := util.InterfaceToStr(sess["mgoUserId"]); userId != "" {
+		logs["userid"] = userId
+		logs["nickname"] = util.InterfaceToStr(sess["s_nickname"])
+		logs["positionid"] = util.IntAll(sess["positionId"])
+	}
+
+	lock.Lock()
+	arr = append(arr, logs)
+	if len(arr) >= nc {
+		tmp := arr
+		arr = make([]map[string]interface{}, 0)
+		go func() {
+			log.Println("save..visit..log", len(tmp))
+			public.Mgo_Log.SaveBulk("material_logs", tmp...)
+		}()
+	}
+	lock.Unlock()
+}
+
+// 定时保存日志
+func SaveLogTask() {
+	lock.Lock()
+	if len(arr) >= 1 {
+		tmp := arr
+		arr = make([]map[string]interface{}, 0)
+		go func() {
+			log.Println("timer..save..visit..log", len(tmp))
+			public.Mgo_Log.SaveBulk("material_logs", tmp...)
+		}()
+	}
+
+	lock.Unlock()
+	time.AfterFunc(5*time.Minute, SaveLogTask)
+}

+ 6 - 1
src/jfw/modules/app/src/app/front/shorturl.go

@@ -202,7 +202,7 @@ func (s *Short) Article(contentType, stype, id string) error {
 	if len(ips) > 0 {
 		ipTrue = config.IpList.Match(ips[0])
 	}
-	log.Printf("三级页userid:%s ips %v", userId, ips)
+	log.Printf("三级页userid:%s, ips %v, ipTrue:%v, refer:%s, url:%s", userId, ips, ipTrue, s.Refer(), s.Url())
 	if sid != "" {
 		obj = wxvisitD(sid, userId, (isVip && isOldVip) || isEntniche || isMember)
 	}
@@ -426,6 +426,11 @@ func (s *Short) Article(contentType, stype, id string) error {
 			}
 			s.T["currentLocation"] = currentLocation
 		}
+		//中标候选人
+		obj["isCandidate"] = false
+		if obj["winnerorder"] != nil {
+			obj["isCandidate"] = true
+		}
 		s.T["obj"] = obj
 		s.T["isIosExam"], s.T["isIosExamPhone"], _, _ = IosExamInfo(s.Action, false, false)
 		content, err := s.Render4Cache("/weixin/wxinfocontent.html", &s.T)

+ 1 - 1
src/jfw/modules/app/src/app/front/swordfish.go

@@ -538,7 +538,7 @@ func wxvisitD(sid, userId string, isPayUser bool) (objdata map[string]interface{
 			if !isPayUser && (util.ObjToString(obj["subtype"]) == "拟建" || util.ObjToString(obj["subtype"]) == "采购意向") {
 				for k := range obj {
 					if k != "title" && k != "area" && k != "subtype" && k != "detail" && k != "procurementlist" && k != "toptype" && k != "publishtime" && k != "budget" && k != "bidamount" && k != "site" && k != "spidercode" && k != "recommended_service" && k != "projectinfo" &&
-						k != "buyerclass" && k != "owner" && k != "total_investment" && k != "projectaddr" && k != "projectperiod" && k != "approvedept" && k != "approvecontent" && k != "approvecode" && k != "approvenumber" && k != "approvetime" && k != "approvestatus" && k != "project_scale" && k != "projectname" {
+						k != "buyerclass" && k != "owner" && k != "total_investment" && k != "projectaddr" && k != "projectperiod" && k != "approvedept" && k != "approvecontent" && k != "approvecode" && k != "approvenumber" && k != "approvetime" && k != "approvestatus" && k != "project_scale" && k != "projectname" && k != "winnerorder" {
 						delete(obj, k)
 					}
 				}

+ 11 - 3
src/jfw/modules/app/src/web/templates/weixin/wxinfocontent.html

@@ -900,7 +900,11 @@
                         </ul>
                     </div>
                 </div>
-                <div class="explain" style="display:none;">*以上摘要信息由剑鱼标讯智能提取。如有误差,请联系客服进行处理。</div>
+      {{if .T.obj.isCandidate }}
+			        <div class="explain" style="display:none;">*该信息为<span style="color: #FF3A20">候选人公示</span>,具体<span style="color: #FF3A20">中标信息未确认</span>,请以实际中标通知为准!如有误差,请联系客服处理。</div>
+			{{else}}
+            <div class="explain" style="display:none;">*以上摘要信息由剑鱼标讯智能提取。如有误差,请联系客服进行处理。</div>
+      {{end}}
                 <div class="lead-btn" style="height: 1.2rem;background: #F5F6F7;border-radius: 8px; color:#2cb7ca;margin: 16px 0;display:none; align-items: center;padding: 0 .32rem;" onclick="adv_statistics(this)">
                     <a class="adv_dataexprt" style="width: .48rem; height: .48rem;margin-right: .24rem;display: flex;"></a>
                     <a class="adv_center" style="display: flex;flex-direction: column;flex: 1;">
@@ -1200,6 +1204,10 @@
     var isVIP={{.T.isVip}};
     var hsn = {{.T.obj.hasSession}};
     var id = {{.T.obj._id}}; // 招标信息id
+    var hasWaitWinnerState = {{.T.obj.isCandidate}}
+    var fixWinnerLabel = hasWaitWinnerState ? '中标候选人' : '中标单位'
+    var fixWinnerMoneyLabel = hasWaitWinnerState ? '投标金额(元)' : '中标金额(元)'
+//
     var title = {{.T.obj.title}};
     var s_words = {{.T.keywords}};
     var url = {{.T.obj.href}};
@@ -2985,7 +2993,7 @@
           }
 
           if(count>=5){
-            	var bidInfohtml='<li><p class="name">中标单位</p><div style="flex: 1;">'
+            	var bidInfohtml='<li><p class="name">'+fixWinnerLabel+'</p><div style="flex: 1;">'
               var indexN =0;
               var winnerArr =[];
                 $("#bidInfoTitle").show();
@@ -3001,7 +3009,7 @@
                     }
                 }
               }
-              bidInfohtml +='<li class="bbm0 needLogin"><p class="name">中标金额(元)</p><p class="textcontent">'+rerbidamount+'</p></li>'
+              bidInfohtml +='<li class="bbm0 needLogin"><p class="name">'+fixWinnerMoneyLabel+'</p><p class="textcontent">'+rerbidamount+'</p></li>'
               if(winnertel!=""){
                   bidInfohtml +='<li class="bbm0 winnertel bigwinnertel needLogin" style="position: relative; margin-bottom: 10px;border-bottom: 0px !important"><p class="name">联系方式</p>'
                   if ((isVIP!=null&&isVIP)||(isEntniche!=null&&isEntniche)){

+ 1 - 0
src/jfw/modules/publicapply/src/main.go

@@ -34,6 +34,7 @@ import (
 	_ "jy/src/jfw/modules/publicapply/src/entCreditReport"
 	_ "jy/src/jfw/modules/publicapply/src/feedback"
 	_ "jy/src/jfw/modules/publicapply/src/history"
+	_ "jy/src/jfw/modules/publicapply/src/material"
 	_ "jy/src/jfw/modules/publicapply/src/shareFission"
 	_ "jy/src/jfw/modules/publicapply/src/subscribe"
 	_ "jy/src/jfw/modules/publicapply/src/subscribePush"

+ 78 - 0
src/jfw/modules/publicapply/src/material/material.go

@@ -0,0 +1,78 @@
+package material
+
+import (
+	"app.yhyue.com/moapp/jybase/go-xweb/xweb"
+	"bytes"
+	"encoding/base64"
+	"errors"
+	"fmt"
+	"image"
+	"image/jpeg"
+	"image/png"
+	"log"
+	"net/http"
+)
+
+type Material struct {
+	*xweb.Action
+	fileDownload xweb.Mapper `xweb:"/material/fileDownload"` //移动端消息三级页
+}
+
+func init() {
+	xweb.AddAction(&Material{})
+}
+
+func (m *Material) FileDownload() error {
+	ossUrl := m.GetString("ossUrl")
+	if ossUrl == "" {
+		return errors.New("ossUrl参数缺失")
+	}
+	img, imgType, err := downloadImage(ossUrl)
+	if err != nil {
+		log.Println("文件下载失败:", ossUrl)
+		return err
+	}
+	imgBase, err := ImageToBase64(img, imgType)
+	if imgBase != "" && err == nil {
+		m.ServeJson(map[string]interface{}{
+			"imgBase": fmt.Sprintf("data:%s;base64,%s", imgType, imgBase),
+		})
+		return nil
+	}
+	return err
+}
+
+func ImageToBase64(img image.Image, format string) (string, error) {
+	var buf bytes.Buffer
+	switch format {
+	case "jpeg", "jpg":
+		if err := jpeg.Encode(&buf, img, &jpeg.Options{Quality: 90}); err != nil {
+			return "", err
+		}
+	case "png":
+		if err := png.Encode(&buf, img); err != nil { // 需导入 image/png
+			return "", err
+		}
+	default:
+		return "", fmt.Errorf("unsupported format: %s", format)
+	}
+	// Base64 编码
+	encoded := base64.StdEncoding.EncodeToString(buf.Bytes())
+	return encoded, nil
+}
+
+// 下载图片
+func downloadImage(url string) (image.Image, string, error) {
+	resp, err := http.Get(url)
+	if err != nil {
+		return nil, "", err
+	}
+	defer resp.Body.Close()
+
+	img, imgType, err := image.Decode(resp.Body)
+	if err != nil {
+		return nil, "", err
+	}
+
+	return img, imgType, nil
+}

+ 1 - 1
src/web/templates/areaPack/pc/page_order.html

@@ -276,7 +276,7 @@
                     $('.filter_data .replace_text[name="type"]').text(formatAreaTextBefore(filterObj.ordertype))
                     $('.filter_data .replace_text[name="area"]').text(formatAreaText(filterObj.num, filterObj.OldNum))
                     $('.filter_data .replace_text[name="cycle"]').text(filterObj.ordertype === 2 ? '不延期' : formatCycleText(filterObj.cycleunit))
-                    $('.filter_data .replace_text[name="time"]').text(formatTimeText(r.data.order.vip_endtime) + '到期')
+                    $('.filter_data .replace_text[name="time"]').text(formatTimeText(r.data.order.vip_endtime || r.data.order.service_endtime) + '到期')
                     if (r.data.order.order_status == 1) {
                         $(".realTimeText").show()
                     }

+ 11 - 4
src/web/templates/weixin/wxinfocontent_rec.html

@@ -1345,7 +1345,11 @@ body .loading_ p span {
 					</ul>
 				</div>
 			</div>
+      {{if .T.obj.isCandidate }}
+			  <div class="explain" style="display:none;">*该信息为<span style="color: #FF3A20">候选人公示</span>,具体<span style="color: #FF3A20">中标信息未确认</span>,请以实际中标通知为准!如有误差,请联系客服处理。</div>
+			{{else}}
 			  <div class="explain" style="display:none;">*以上摘要信息由剑鱼标讯智能提取。如有误差,请联系客服进行处理。</div>
+      {{end}}
 			<div class="lead-btn" style="height: 1.2rem;background: #F5F6F7;border-radius: 8px; color:#2cb7ca;margin: 16px 0;display:none; align-items: center;padding: 0 .32rem;" onclick="adv_statistics(this)">
 				<a class="adv_dataexprt" style="width: .48rem; height: .48rem;margin-right: .24rem;display: flex;"></a>
 				<a class="adv_center" style="display: flex;flex-direction: column;flex: 1;">
@@ -1600,6 +1604,9 @@ var reg =""
 var winner_con = "";
 var title = {{.T.obj.title}};
 var id = {{.T.obj._id}};
+var hasWaitWinnerState = {{.T.obj.isCandidate}}
+var fixWinnerLabel = hasWaitWinnerState ? '中标候选人' : '中标单位'
+var fixWinnerMoneyLabel = hasWaitWinnerState ? '投标金额(元)' : '中标金额(元)'
 //
 var s_words = {{.T.keywords}};
 s_words=decodeURIComponent(getParameter("keywords"));
@@ -3036,7 +3043,7 @@ $(function(){
     }
     if(count>=5){
 		$("#bidInfoTitle").show();
-    	var bidInfohtml='<li><p class="name">中标单位</p><div style="flex: 1;">'
+    	var bidInfohtml='<li><p class="name">'+fixWinnerLabel+'</p><div style="flex: 1;">'
       var indexN =0;
       console.log(rerwinner)
       var winnerArr =[];
@@ -3052,7 +3059,7 @@ $(function(){
       }
       bidInfohtml+='</div><a dataName="中标单位" dataCont="'+x+'" dataCode="winner" onClick="recoveryAction(this)">纠错</a></li>'
 
-  		bidInfohtml +='<li class="bbm0"><p class="name">中标金额(元)</p><p class="textcontent">'+rerbidamount+'</p><a dataName="中标金额(元)" dataCont="'+rerbidamount+'" dataCode="bidamount" onClick="recoveryAction(this)">纠错</a></li>'
+  		bidInfohtml +='<li class="bbm0"><p class="name">'+fixWinnerMoneyLabel+'</p><p class="textcontent">'+rerbidamount+'</p><a dataName="中标金额(元)" dataCont="'+rerbidamount+'" dataCode="bidamount" onClick="recoveryAction(this)">纠错</a></li>'
       if(winnertel!=""){
         bidInfohtml +='<li class="bbm0 winnertel"><p class="name">联系方式</p>';
         bidInfohtml +='<div class="tel-group"><div class="tel-item"><p>'+winnertel+'</p><a href="tel:'+winnertel+'" class="border-tel" style="display:block;position: static;"><div class="tel"></div></a></div><div class="tel-source">'+tel_source+'</div></div>'
@@ -3108,8 +3115,8 @@ $(function(){
 					pkchtml+='<li><p class="name">拟定单一来源采购供应商</p><p class="textcontent">'+pckwinner+'</p><a dataName="拟定单一来源采购供应商" dataCont="'+pckwinner+'"  dataCode="'+n+'-winner" onClick="recoveryAction(this)">纠错</a></li>'
 					pkchtml+='<li class="bbm0"><p class="name">项目预算(元)</p><p class="textcontent">'+pckbidamount+'</p><a dataName="项目预算(元)" dataCont="'+pckbidamount+'"  dataCode="'+n+'-bidamount" onClick="recoveryAction(this)">纠错</a></li>'
 				}else{
-					pkchtml+='<li><p class="name">中标单位</p><p class="textcontent">'+pckwinner+'</p><a dataName="中标单位" dataCont="'+pckwinner+'"  dataCode="'+n+'-winner" onClick="recoveryAction(this)">纠错</a></li>'
-					pkchtml+='<li class="bbm0"><p class="name">中标金额(元)</p><p class="textcontent">'+pckbidamount+'</p><a dataName="中标金额(元)" dataCont="'+pckbidamount+'"  dataCode="'+n+'-bidamount" onClick="recoveryAction(this)">纠错</a></li>'
+					pkchtml+='<li><p class="name">'+fixWinnerLabel+'</p><p class="textcontent">'+pckwinner+'</p><a dataName="中标单位" dataCont="'+pckwinner+'"  dataCode="'+n+'-winner" onClick="recoveryAction(this)">纠错</a></li>'
+					pkchtml+='<li class="bbm0"><p class="name">'+fixWinnerMoneyLabel+'</p><p class="textcontent">'+pckbidamount+'</p><a dataName="中标金额(元)" dataCont="'+pckbidamount+'"  dataCode="'+n+'-bidamount" onClick="recoveryAction(this)">纠错</a></li>'
 				}
 			}