Pārlūkot izejas kodu

微信上传名片搜索

张金坤 9 gadi atpakaļ
vecāks
revīzija
fd378e1aaa

+ 6 - 4
core/src/config.json

@@ -28,8 +28,10 @@
     "mailFailureTime": 3,
     "chatServer": "127.0.0.1:83",
     "chatRpc": "127.0.0.1:88",
-	"creditRpc":"127.0.0.1:8765",
-	"pushRpc":"127.0.0.1:8766",
-	"domainName":"http://www.qimingxing.info"
-
+    "creditRpc": "127.0.0.1:8765",
+    "pushRpc": "127.0.0.1:8766",
+    "domainName": "http://www.qimingxing.info",
+    "ocr_uid": "120.25.216.197",
+    "ocr_servicekey": "91e77f8a-cb28-4fc2-96d7-5b08e7dfb6c5",
+    "ocr_servicecode": "cf22e3bb-d41c-47e0-aa44-a92984f5829d"
 }

+ 1 - 1
core/src/message.json

@@ -2,7 +2,7 @@
 	"weixinrpc":"127.0.0.1:82",
 	"swordfishaction":"/swordfish/page",
 	"signature":"/member/credit/myCredit",
-	"entsearchaction":"/wx/search/enterprise/ent.html",
+	"entsearchaction":"/wx/search/enterprise/index.html",
 	"lawsearchaction":"/law/qfw/index",
 	"msiteaction":"/ent/wsite/edit",
 	"wxpushlist":"/wxpush/bidinfo/%s",

+ 3 - 0
core/src/qfw/coreconfig/SysConfig.go

@@ -25,6 +25,9 @@ type config struct {
 	PushRpc         string      `json:"pushRpc"`
 	ElasticPoolSize int         `json:"elasticPoolSize"`
 	DomainName      string      `json:"domainName"`
+	Ocr_uid         string      `json:"orc_uid"`
+	Ocr_servicekey  string      `json:"ocr_servicekey"`
+	Ocr_servicecode string      `json:"ocr_servicecode"`
 }
 type smtp struct {
 	Addr     string `json:"addr"`

+ 42 - 0
core/src/qfw/coreutil/imagemsghandler.go

@@ -0,0 +1,42 @@
+package coreutil
+
+import (
+	"bytes"
+	"encoding/base64"
+	"encoding/json"
+	"fmt"
+	"io/ioutil"
+	"net/http"
+	"os"
+	cf "qfw/coreconfig"
+)
+
+//名片识别
+func CardRecognition(picpath string) []interface{} {
+	comps := []interface{}{}
+	//识别
+	fi, _ := os.Open(picpath)
+	bs, _ := ioutil.ReadAll(fi)
+	fi.Close()
+	hurl := fmt.Sprintf("http://api.hanvon.com/rt/ws/v1/ocr/bcard/recg?key=%s&code=%s",
+		cf.SysConfig.Ocr_servicekey, cf.SysConfig.Ocr_servicecode)
+	body := map[string]interface{}{
+		"uid":   cf.SysConfig.Ocr_uid,
+		"color": "original",
+		"lang":  "auto",
+		"image": base64.StdEncoding.EncodeToString(bs),
+	}
+	bs, _ = json.Marshal(body)
+	client := &http.Client{}
+	req, _ := http.NewRequest("POST", hurl, bytes.NewReader(bs))
+	req.Header.Set("Content-Type", "application/octet-stream")
+	resp, _ := client.Do(req) //发送
+	ret, _ := ioutil.ReadAll(resp.Body)
+	resp.Body.Close()
+	ocr_ret := map[string]interface{}{}
+	json.Unmarshal(ret, &ocr_ret)
+	if v, ok := ocr_ret["comp"]; ok {
+		comps, _ = v.([]interface{})
+	}
+	return comps
+}

+ 18 - 0
core/src/qfw/coreutil/weixinrpc.go

@@ -110,3 +110,21 @@ func GetShareQR(url uint32) string {
 	}, func(e interface{}) {})
 	return ret
 }
+
+//根据mediaid下载图片
+func WxDownloadImg(mediaid string) string {
+	var ret string
+	util.Try(func() {
+		client, err := rpc.DialHTTP("tcp", rpcserver)
+		defer client.Close()
+		if err != nil {
+			log.Println(err.Error())
+			return
+		}
+		err = client.Call("WeiXinRpc.DownloadMingpian", mediaid, &ret)
+		if err != nil {
+			log.Println(err.Error())
+		}
+	}, func(e interface{}) {})
+	return ret
+}

+ 2 - 2
core/src/qfw/filemanage/uploadfile.go

@@ -44,7 +44,7 @@ func (m *Files) Upload() error {
 				if fileInfo.Size() > FileSize {
 					res["msg"] = "上传文件大小超出限制"
 				} else {
-					temp := getfilepath(str[len(str)-1])
+					temp := Getfilepath(str[len(str)-1])
 					err := m.SaveToFile(filetype, temp)
 					if err != nil {
 						log.Error(err.Error())
@@ -107,7 +107,7 @@ type Size interface {
 }
 
 //获取文件路径、名称
-func getfilepath(str string) (s string) {
+func Getfilepath(str string) (s string) {
 	var strs = time.Now().Format("20060102150405001")
 	var name = strs + util.GetRandom(5) + "." + str
 	var paht = "./web/staticres/upload/" + strs[:4] + "/" + strs[4:6] + "/" + strs[6:8] + "/"

+ 5 - 0
core/src/qfw/search/wxsearch.go

@@ -5,14 +5,19 @@ package search
 
 import (
 	"github.com/go-xweb/xweb"
+	"regexp"
 )
 
 type Wxsearch struct {
 	*xweb.Action
+	wxEnterprise        xweb.Mapper `xweb:"/wx/search/enterprise/index.html"`             //查询首页
+	wxMingpian          xweb.Mapper `xweb:"/wx/search/enterprise/mingpian"`               //获取名片
 	wxgetEnterpriseList xweb.Mapper `xweb:"/wx/search/enterprise/([^.]*)ent([^.]*).html"` //查询企业列表
 	wxsearchEntSer      xweb.Mapper `xweb:"/wx/searchEntSer/(.*)"`                        //获取企业的服务列表
 }
 
+var mpian_reg *regexp.Regexp //名片
 func init() {
+	mpian_reg, _ = regexp.Compile("公司|集团|厂|企业|投资")
 	xweb.AddAction(&Wxsearch{})
 }

+ 32 - 1
core/src/qfw/search/wxsearchservice.go

@@ -7,8 +7,10 @@ import (
 	"github.com/go-xweb/xweb"
 	"html/template"
 	"log"
+	"qfw/coreutil"
 	"qfw/front"
 	. "qfw/member"
+	"qfw/mobile"
 	. "qfw/util"
 	"qfw/util/consts"
 	"qfw/util/elastic"
@@ -17,9 +19,38 @@ import (
 	"qfw/util/redis"
 	"strconv"
 	"strings"
-	_ "strings"
 )
 
+//微信企业查询首页
+func (s *Wxsearch) WxEnterprise() error {
+	s.T["signature"] = mobile.GetSignature(s.Url())
+	log.Println("signature", s.T["signature"])
+	return s.Render("/search/wxent.html", &s.T)
+}
+
+//获取名片名称
+func (s *Wxsearch) WxMingpian() error {
+	res := make(map[string]string)
+	if s.GetSession("s_m_openid") != nil {
+		serverId := s.GetString("serverId")
+		picpath := coreutil.WxDownloadImg(serverId)
+		log.Println("picpath", picpath)
+		names := coreutil.CardRecognition(picpath)
+		for k, v := range names {
+			name := fmt.Sprint(v)
+			if mpian_reg.MatchString(name) {
+				res["name"] = name
+				break
+			}
+			if k == len(names)-1 {
+				res["name"] = name
+			}
+		}
+	}
+	s.ServeJson(&res)
+	return nil
+}
+
 //获取某个企业服务列表数据
 func (search *Wxsearch) WxsearchEntSer(id string) error {
 	if search.Method() == "POST" {

+ 107 - 0
core/src/web/templates/search/wxent.html

@@ -0,0 +1,107 @@
+<html>
+<head>
+<title>{{Msg "seo" "qfw.enterprise.title"}}</title>
+<meta name="msvalidate.01" content="D5F3ADC7EB4E65FFB8BF943AD56DD1F7" />
+{{include "/common/inc.html"}}
+<link href="/css/entcommunity.css" rel="stylesheet">
+<meta name="Keywords" content="{{Msg "seo" "qfw.enterprise.key"}}"/>
+<meta name="Description" content="{{Msg "seo" "qfw.enterprise.description"}}"/>
+<script type="text/javascript" src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>
+<script>
+var signature = {{.T.signature}};
+var shareTitle = "企业社区";
+var shareLink = "http://www.qimingxing.info/wx/search/enterprise/wxent.html";
+var shareIcon = "";
+if(typeof(signature) != "undefined" && signature != null && signature.length == 4){
+	wx.config({
+	    debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
+	    appId: signature[0], // 必填,公众号的唯一标识
+	    timestamp:signature[1], // 必填,生成签名的时间戳
+	    nonceStr: signature[2], // 必填,生成签名的随机串
+	    signature: signature[3],// 必填,签名,见附录1
+	    jsApiList: ['onMenuShareTimeline','onMenuShareAppMessage',
+					'chooseImage','uploadImage','downloadImage']
+	});
+	wx.ready(function () {
+        wx.onMenuShareTimeline({
+		    title: shareTitle, // 分享标题
+		    link: shareLink, // 分享链接
+		    imgUrl: shareIcon, // 分享图标
+		    success: function () { 
+		       //alert('分享成功');
+		    },
+		    cancel: function () { 
+		       //alert('分享失败,或用户取消了');
+		    }
+		});
+
+		wx.onMenuShareAppMessage({
+		    title: shareTitle, // 分享标题
+		    desc: '企明星企业', // 分享描述
+		    link:  shareLink,// 分享链接
+		    imgUrl: shareIcon, // 分享图标
+		    type: 'link', // 分享类型,music、video或link,不填默认为link'
+		    dataUrl: '', // 如果type是music或video,则要提供数据链接,默认为空
+		    success: function () { 
+		        //alert('分享成功');
+		    },
+		    cancel: function () { 
+				//alert('分享失败,或用户取消了');
+		    }
+		});
+		
+		
+    });
+}	
+</script>
+</head>
+<body>
+<div class="b-content container-fluid">
+	 <div class="b-com-third input-group">
+		<input type="text" class="form-control" name="entIndexSearch" id="header-searchInput" placeholder="找企业"  aria-describedby="search-btn" value=""> 
+		<span class="input-group-addon" id="search-btn"><span class="glyphicon sousuo"></span>照相</span>
+	</div>
+ <img src="" id="testimg"/>
+
+</div>
+<script>
+$("#search-btn").click(function(){
+	wx.chooseImage({
+	    count: 1, // 默认9
+	    sizeType: ['compressed'], // 可以指定是原图还是压缩图,默认二者都有
+	    sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有
+	    success: function (res) {
+	        var localIds = res.localIds; // 返回选定照片的本地ID列表,localId可以作为img标签的src属性显示图片
+			uploadImage(localIds[0]);
+	 	}
+	});
+})
+function uploadImage(localId){
+	wx.uploadImage({
+	    localId: localId, // 需要上传的图片的本地ID,由chooseImage接口获得
+	    isShowProgressTips: 1, // 默认为1,显示进度提示
+	    success: function (res) {
+	        var serverId = res.serverId; // 返回图片的服务器端ID
+			alert(serverId);
+			//document.write(serverId);
+			getmpname(serverId);
+	 	}
+	});
+} 
+ 
+//获取企业名称
+function getmpname(serverId){
+	$.ajax({ 
+        type: 'post', 
+        url: '/wx/search/enterprise/mingpian', 
+		data:{serverId:serverId},
+        cache: false, 
+        error: function(){return false;}, 
+        success:function(obj){
+			alert(obj["name"]);
+        } 
+    }); 
+}
+</script>
+</body>
+</html>

+ 0 - 102
weixin/src/qfw/weixin/imagemsghandler.go

@@ -1,15 +1,6 @@
 package weixin
 
 import (
-	"bytes"
-	"encoding/base64"
-	"encoding/json"
-	"fmt"
-	"github.com/disintegration/imaging"
-	"io/ioutil"
-	"math"
-	"net/http"
-
 	"log"
 	"os"
 	"qfw/util"
@@ -18,14 +9,6 @@ import (
 	"time"
 )
 
-const (
-	OCR_SERVERKEY   = "1fb48799-5379-485c-9047-f886b535759b"
-	OCR_SERVICECODE = "cf22e3bb-d41c-47e0-aa44-a92984f5829d"
-)
-
-var upload_lock chan bool = make(chan bool, 500) //支持500并发
-var max_size float64 = 1200                      //最大1200像素
-
 //微信图像处理
 func ImageMsgHandler(w ResponseWriter, r *Request) {
 	//TODO 先验证是否存在用户,
@@ -36,13 +19,7 @@ func ImageMsgHandler(w ResponseWriter, r *Request) {
 			return
 		}
 		processIndenfyUpload(us, openid, w, r)
-	} else { //走的是名片识别
-		//TODO 需要加上调用次数限制
-		upload_lock <- true
-		go cardRecognition(r.MediaId, r.FromUserName)
-		w.ReplyOK()
 	}
-
 }
 
 func processIndenfyUpload(us *usersession, openid string, w ResponseWriter, r *Request) {
@@ -78,82 +55,3 @@ func getSavePath() string {
 
 	return path + name
 }
-
-//名片识别
-func cardRecognition(mediaid, openid string) {
-	defer func() {
-		<-upload_lock
-	}()
-	//下载
-	picpath := getSavePath()
-	err := Mux.DownloadMediaToFile(mediaid, wf.SysConfig.Imgpath+picpath)
-	if err != nil {
-		log.Println(err.Error())
-		return
-	}
-	//图像处理
-	fi, _ := os.Open(wf.SysConfig.Imgpath + picpath)
-	srcimg, err := imaging.Decode(fi)
-	fi.Close()
-	if err != nil {
-		log.Println("read image file:::", err.Error())
-	}
-	bound := srcimg.Bounds().Size()
-	log.Println(bound.X, bound.Y)
-	w, h := bound.X, bound.Y
-	if max := math.Max(float64(w), float64(h)); max > max_size {
-		bl := max / max_size
-		w = int(float64(w) / bl)
-		h = int(float64(h) / bl)
-	}
-	small_file := wf.SysConfig.Imgpath + getSavePath()
-	destimg := imaging.Resize(srcimg, w, h, imaging.Linear)
-	imaging.Save(destimg, small_file)
-	//识别
-	fi, _ = os.Open(small_file)
-	bs, _ := ioutil.ReadAll(fi)
-	fi.Close()
-	hurl := fmt.Sprintf("http://api.hanvon.com/rt/ws/v1/ocr/bcard/recg?key=%s&code=%s",
-		OCR_SERVERKEY, OCR_SERVICECODE)
-	body := map[string]interface{}{
-		"uid":   "123.160.231.13",
-		"color": "original",
-		"lang":  "auto",
-		"image": base64.StdEncoding.EncodeToString(bs),
-	}
-	bs, _ = json.Marshal(body)
-	//
-	client := &http.Client{}
-	req, _ := http.NewRequest("POST", hurl, bytes.NewReader(bs))
-	req.Header.Set("Content-Type", "application/octet-stream")
-	resp, _ := client.Do(req) //发送
-	ret, _ := ioutil.ReadAll(resp.Body)
-	resp.Body.Close()
-	log.Println(string(ret))
-	ocr_ret := map[string]interface{}{}
-	json.Unmarshal(ret, &ocr_ret)
-	if v, ok := ocr_ret["comp"]; ok {
-		comps, _ := v.([]interface{})
-		if len(comps) > 0 {
-			searchcomp := comps[0].(string)
-			//发送客服消息
-			var msg struct {
-				ToUser  string `json:"touser"`
-				MsgType string `json:"msgtype"`
-				Text    struct {
-					Content string `json:"content"`
-				} `json:"text"`
-			}
-			msg.ToUser = openid
-			msg.MsgType = "text"
-			msg.Text.Content = searchcomp
-			bs, err := Mux.PostCustomMsg("https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=", msg)
-			if err != nil {
-				log.Println(err.Error())
-			} else {
-				log.Println(string(bs))
-			}
-		}
-	}
-
-}

+ 34 - 0
weixin/src/qfw/weixin/rpc/downimg.go

@@ -0,0 +1,34 @@
+// downloadimg
+package rpc
+
+import (
+	"log"
+	"os"
+	"qfw/util"
+	wf "qfw/weixinconfig"
+	"time"
+)
+
+func (wxrpc *WeiXinRpc) DownloadMingpian(mediaid string, picpath *string) error {
+	*picpath = getSavePath()
+	err := wxrpc.wx.DownloadMediaToFile(mediaid, *picpath)
+	if err != nil {
+		log.Println("DownloadMingpian err", err.Error())
+		*picpath = ""
+	} else {
+		log.Println("图片路径", *picpath)
+	}
+	return nil
+}
+
+func getSavePath() string {
+	strs := time.Now().Format("20060102150405001")
+	name := strs + util.GetRandom(5) + ".jpg"
+	path := "/upload/" + strs[:4] + "/" + strs[4:6] + "/" + strs[6:8] + "/"
+	fs, err := os.Open(wf.SysConfig.Imgpath + path)
+	if err != nil {
+		os.MkdirAll(wf.SysConfig.Imgpath+path, 0700)
+	}
+	defer fs.Close()
+	return wf.SysConfig.Imgpath + path + name
+}