分享
 
 
 

.NET微信公众号开发-6.0模板消息

王朝学院·作者佚名  2016-08-27
窄屏简体版  字體: |||超大  

一.前言 为了保证用户不受到骚扰,在开发者出现需要主动提醒、通知用户时,才允许开发者在公众平台网站中模板消息库中选择模板,选择后获得模板ID,再根据模板ID向用户主动推送提醒、通知消息。这个意思也就是,我们作为微信商户,不能主动的给用户推送消息,如果这个功能完全开放,那么用户有可能会受到大量的垃圾信息,为了做一个很好的控制,微信那边给我们开放了一个模板消息,通过模板消息我们可以友好的给用户发送一些相关的消息提醒。

二.开发前的准备 1.0模板消息官方文档地址

2.0查看我们的模板消息是否申请成功。申请成功后你可以看到如下图片:

三.开始编码 一般我们在客户支付成功订单以后,会有一个支付的跳转页面,在我们前面的代码中也有相应的页面,代码如下:

<script type="text/javascript">//调用微信JS api 支付function jsApiCall()

{

WeixinJSBridge.invoke('getBrandWCPayRequest',<%=wxJsApiParam%>,//josn串function (res)

{if(res.err_msg =="get_brand_wcpay_request:ok")

{varOrderId=$("#OrderId").val();varorderPRoductName=$("#orderProductName").val();varorderMoneySum=$("#orderMoneySum").val();

window.location.href="http://www.baidu.com/PaySkip.aspx?OrderId="+OrderId+"&orderMoneySum="+orderMoneySum+"&orderProductName="+orderProductName;//支付成功后的跳转页面}else{

WeixinJSBridge.call('closeWindow');

}

}

);

}

function callpay()

{if(typeofWeixinJSBridge =="undefined")

{if(document.addEventListener)

{

document.addEventListener('WeixinJSBridgeReady', jsApiCall,false);

}elseif(document.attachEvent)

{

document.attachEvent('WeixinJSBridgeReady', jsApiCall);

document.attachEvent('onWeixinJSBridgeReady', jsApiCall);

}

}else{

jsApiCall();

}

}</script>

在上一篇,微信支付成功后,我们有这样一个支付跳转页面,在这个支付跳转页面里,我们可以写一些我们自己的业务逻辑,比如我们今天的主角,模板消息提醒:直接上代码

#region发送支付成功的消息ErrorMessage errorMessage;stringusername = System.Configuration.ConfigurationManager.AppSettings["weixinid"].ToString();stringtemplateId = System.Configuration.ConfigurationManager.AppSettings["templateId"].ToString();stringfirst ="您已成功付费,欢迎下次光临。";stringorderMoneySum = Request["orderMoneySum"] ??"0";stringorderProductName = Request["orderProductName"] ??"有位停车付费系统测试";stringRemark ="如有问题请致电400-6238-136或直接在微信留言,我们将第一时间为您服务!";

Color color=Color.Red;

Tuple<string,string, Color>[] data =newTuple<string,string, Color>[]{newTuple<string,string,Color>("first",first,Color.Blue),newTuple<string,string,Color>("orderMoneySum",orderMoneySum,Color.Red),newTuple<string,string,Color>("orderProductName",orderProductName,Color.Orange),newTuple<string,string,Color>("Remark",Remark,Color.Green)

};longmsgId =TemplateMessage.Send(username, openId, templateId,"", color, data,outerrorMessage);if(errorMessage.IsSuccess)

{

Response.Write("errorMessage"+ errorMessage.errmsg +"<br/>");

}else{

Response.Write("errorMessage.errmsg:"+ errorMessage.errmsg +"<br/>");

}#endregion

从上面的代码中我们可以看到TemplateMessage.Send()这个方法是我们发送消息的关键,我们来看看这个方法是怎样的:

#region发送模板消息///<summary>///发送模板消息///</summary>///<param name="userName">公众号</param>///<param name="touser">接收消息的账号</param>///<param name="templateId">模板id</param>///<param name="detailUrl">详情地址</param>///<param name="topColor">顶端颜色</param>///<param name="data">数据</param>///<param name="errorMessage">返回发送是否成功</param>///<returns>返回消息id;如果发送失败,返回-1。</returns>publicstaticlongSend(stringuserName,stringtouser,stringtemplateId,stringdetailUrl, Color topColor,

Tuple<string,string, Color>[] data,outErrorMessage errorMessage)

{

errorMessage=newErrorMessage(ErrorMessage.ExceptionCode,"");longid = -1;//校验参数if(string.IsNullOrWhiteSpace(touser))

{

errorMessage.errmsg="接收消息的账号不能为空。";returnid;

}if(string.IsNullOrWhiteSpace(templateId))

{

errorMessage.errmsg="模板id不能为空。";returnid;

}if(data ==null|| data.Length ==0)

{

errorMessage.errmsg="模板数据不能为空。";returnid;

}foreach(Tuple<string,string, Color> itemindata)

{if(string.IsNullOrWhiteSpace(item.Item1) ||string.IsNullOrWhiteSpace(item.Item2))

{

errorMessage.errmsg="模板数据不能为空。";returnid;

}

}//获取许可令牌accessToken token =AccessToken.Get(userName);if(token ==null)

{

errorMessage.errmsg="获取许可令牌失败。";returnid;

}stringurl =string.Format(urlForSending, token.access_token);//生成待发送的数据dynamic postData =newExpandoObject();

postData.touser=touser;

postData.template_id=templateId;

postData.url= detailUrl ??string.Empty;

postData.topcolor=Utility.GetColorString(topColor);

postData.data=newExpandoObject();

IDictionary<string,object> dataDict = (IDictionary<string,object>)postData.data;foreach(Tuple<string,string, Color> itemindata)

{

dataDict.Add(item.Item1,new{ value = item.Item2, color =Utility.GetColorString(item.Item3) });

}stringjson =JsonConvert.SerializeObject(postData);//发送数据stringresponseContent;if(!HttpHelper.Request(url,outresponseContent, httpMethod, json))

{

errorMessage.errmsg="提交数据到微信服务器失败。";returnid;

}//解析结果JObject jo =JObject.Parse(responseContent);

JToken jt;if(jo.TryGetValue("errcode",outjt) && jo.TryGetValue("errmsg",outjt))

{

errorMessage.errcode= (int)jo["errcode"];

errorMessage.errmsg= (string)jo["errmsg"];if(jo.TryGetValue("msgid",outjt))

id= (long)jt;

}elseerrorMessage.errmsg="解析返回结果失败。";returnid;

}#endregion

AccessToken token =AccessToken.Get(userName);获取许可令牌上一篇文章中我们已经说过这个类,这里就不多说了,HttpHelper帮助类的代码如下:

///<summary>///HttpHelper:http请求与响应辅助类///</summary>publicstaticclassHttpHelper

{///<summary>///向微信服务器发送请求时的编码///</summary>publicstaticreadonlyEncoding RequestEncoding =Encoding.UTF8;///<summary>///微信服务器响应的编码///</summary>publicstaticreadonlyEncoding ResponseEncoding =Encoding.UTF8;///<summary>///向微信服务器提交数据,并获取微信服务器响应的数据///</summary>///<param name="url">服务器地址</param>///<param name="responseData">返回响应数据</param>//////<param name="httpMethod">http方法</param>///<param name="data">数据</param>///<returns>返回是否提交成功</returns>publicstaticboolRequest(stringurl,outbyte[] responseData,stringhttpMethod = WebRequestMethods.Http.Get,byte[] data =null)

{boolsuccess =false;

responseData=null;

Stream requestStream=null;

HttpWebResponse response=null;

Stream responseStream=null;

MemoryStream ms=null;try{

HttpWebRequest request=(HttpWebRequest)WebRequest.Create(url);

request.Method=httpMethod;if(data !=null&& data.Length >0)

{

request.ContentLength=data.Length;

requestStream=request.GetRequestStream();

requestStream.Write(data,0, data.Length);

}

response=(HttpWebResponse)request.GetResponse();//由于微信服务器的响应有时没有正确设置ContentLength,这里不检查ContentLength//if (response.ContentLength > 0){

ms=newMemoryStream();

responseStream=response.GetResponseStream();intbufferLength =2048;byte[] buffer =newbyte[bufferLength];intsize = responseStream.Read(buffer,0, bufferLength);while(size >0)

{

ms.Write(buffer,0, size);

size= responseStream.Read(buffer,0, bufferLength);

}

responseData=ms.ToArray();

}

success=true;

}finally{if(requestStream !=null)

requestStream.Close();if(responseStream !=null)

responseStream.Close();if(ms !=null)

ms.Close();if(response !=null)

response.Close();

}returnsuccess;

}///<summary>///向微信服务器提交数据,并获取微信服务器响应的数据///</summary>///<param name="url">服务器地址</param>///<param name="responseData">返回响应数据</param>//////<param name="httpMethod">http方法</param>///<param name="data">数据</param>///<returns>返回是否提交成功</returns>publicstaticboolRequest(stringurl,outbyte[] responseData,stringhttpMethod = WebRequestMethods.Http.Get,stringdata =null)

{byte[] bytes =string.IsNullOrEmpty(data) ?null: RequestEncoding.GetBytes(data);returnRequest(url,outresponseData, httpMethod, (byte[])bytes);

}///<summary>///向微信服务器提交数据,并获取微信服务器响应的内容///</summary>///<param name="url">服务器地址</param>///<param name="responseContent">返回响应内容</param>//////<param name="httpMethod">http方法</param>///<param name="data">数据</param>///<returns>返回是否提交成功</returns>publicstaticboolRequest(stringurl,outstringresponseContent,stringhttpMethod = WebRequestMethods.Http.Get,byte[] data =null)

{byte[] responseData;

responseContent=string.Empty;boolsuccess = Request(url,outresponseData, httpMethod, data);if(success && responseData !=null&& responseData.Length >0)

responseContent=ResponseEncoding.GetString(responseData);returnsuccess;

}///<summary>///向微信服务器提交数据,并获取微信服务器响应的内容///</summary>///<param name="url">服务器地址</param>///<param name="responseContent">返回响应内容</param>//////<param name="httpMethod">http方法</param>///<param name="data">数据</param>///<returns>返回是否提交成功</returns>publicstaticboolRequest(stringurl,outstringresponseContent,stringhttpMethod = WebRequestMethods.Http.Get,stringdata =null)

{byte[] bytes =string.IsNullOrEmpty(data) ?null: RequestEncoding.GetBytes(data);returnRequest(url,outresponseContent, httpMethod, (byte[])bytes);

}///<summary>///向微信服务器提交数据///</summary>///<param name="url">服务器地址</param>//////<param name="httpMethod">http方法</param>///<param name="data">数据</param>///<returns>返回是否提交成功</returns>publicstaticboolRequest(stringurl,stringhttpMethod = WebRequestMethods.Http.Get,byte[] data =null)

{boolsuccess =false;

Stream requestStream=null;

HttpWebResponse response=null;try{

HttpWebRequest request=(HttpWebRequest)WebRequest.Create(url);

request.Method=httpMethod;if(data !=null&& data.Length >0)

{

request.ContentLength=data.Length;

requestStream=request.GetRequestStream();

requestStream.Write(data,0, data.Length);

}

response=(HttpWebResponse)request.GetResponse();

success=true;

}finally{if(requestStream !=null)

requestStream.Close();if(response !=null)

response.Close();

}returnsuccess;

}///<summary>///组合url,发送数据,然后返回响应字符串///</summary>///<param name="urlFormat">url格式字符串,第一个参数为userName获取到的许可令牌,然后依次为parameters中的参数</param>///<param name="userName">公众号</param>///<param name="urlParameters">参数</param>///<param name="httpMethod">执行请求的http方法</param>///<param name="data">请求的内容</param>///<returns>返回响应内容;如果请求失败,或者发生错误,返回空字符串</returns>publicstaticstringRequestResponseContent(stringurlFormat,stringuserName, IEnumerable<object> urlParameters =null,stringhttpMethod = WebRequestMethods.Http.Get,stringdata =null)

{stringresponseContent =string.Empty;

AccessToken token=AccessToken.Get(userName);if(token ==null)returnresponseContent;stringurl;if(urlParameters ==null)

url=string.Format(urlFormat, token.access_token);else{

List<object> paramList =newList<object>(urlParameters);

paramList.Insert(0, token.access_token);

url=string.Format(urlFormat, paramList.ToArray());

}

HttpHelper.Request(url,outresponseContent, httpMethod, (string)data);returnresponseContent;

}///<summary>///组合url,发送数据,然后返回响应的错误消息。///注:错误消息不一定代表失败或者错误。///</summary>///<param name="urlFormat">url格式字符串,第一个参数为userName获取到的许可令牌,然后依次为parameters中的参数</param>///<param name="userName">公众号</param>///<param name="urlParameters">参数</param>///<param name="httpMethod">执行请求的http方法</param>///<param name="data">请求的内容</param>///<returns>返回响应的错误消息</returns>publicstaticErrorMessage RequestErrorMessage(stringurlFormat,stringuserName, IEnumerable<object> urlParameters =null,stringhttpMethod = WebRequestMethods.Http.Get,stringdata =null)

{stringresponseContent =RequestResponseContent(urlFormat, userName, urlParameters, httpMethod, data);if(string.IsNullOrWhiteSpace(responseContent))returnnewErrorMessage(ErrorMessage.ExceptionCode,"请求失败。");elseif(ErrorMessage.IsErrorMessage(responseContent))returnErrorMessage.Parse(responseContent);elsereturnnewErrorMessage(ErrorMessage.ExceptionCode,"解析响应失败。");

}///<summary>///组合url,发送数据,然后返回结果。///注:结果为需要解析的类。///</summary>///<typeparam name="T">返回结果的类型</typeparam>///<param name="urlFormat">url格式字符串,第一个参数为userName获取到的许可令牌,然后依次为parameters中的参数</param>///<param name="userName">公众号</param>///<param name="errorMessage">返回请求是否成功</param>///<param name="urlParameters">参数</param>///<param name="httpMethod">执行请求的http方法</param>///<param name="data">请求的内容</param>///<returns>返回结果;如果请求失败,或者发生错误,返回null。</returns>publicstaticT RequestParsableResult<T>(stringurlFormat,stringuserName,outErrorMessage errorMessage, IEnumerable<object> urlParameters =null,stringhttpMethod = WebRequestMethods.Http.Get,stringdata =null)whereT : IParsable,new()

{

T result=default(T);

errorMessage=newErrorMessage(ErrorMessage.ExceptionCode,"请求失败。");stringresponseContent =RequestResponseContent(urlFormat, userName, urlParameters, httpMethod, data);if(string.IsNullOrWhiteSpace(responseContent))returnresult;if(ErrorMessage.IsErrorMessage(responseContent))

errorMessage=ErrorMessage.Parse(responseContent);else{try{

result= Utility.Parse<T>(responseContent);if(result !=null)

errorMessage=newErrorMessage(ErrorMessage.SuccessCode,"请求成功。");elseerrorMessage=newErrorMessage(ErrorMessage.ExceptionCode,"解析失败。");

}catch{

errorMessage=newErrorMessage(ErrorMessage.ExceptionCode,"解析失败。");

}

}returnresult;

}///<summary>///组合url,发送数据,然后返回结果。///注:结果为已知的简单值类型。///</summary>///<typeparam name="T">返回结果的类型</typeparam>///<param name="urlFormat">url格式字符串,第一个参数为userName获取到的许可令牌,然后依次为parameters中的参数</param>///<param name="userName">公众号</param>///<param name="propertyNameInJson">返回结果在json中的键名</param>///<param name="errorMessage">返回请求是否成功</param>///<param name="urlParameters">参数</param>///<param name="httpMethod">执行请求的http方法</param>///<param name="data">请求的内容</param>///<returns>返回结果;如果请求失败,或者发生错误,返回default(T)。</returns>publicstaticT RequestValueTypeResult<T>(stringurlFormat,stringuserName,stringpropertyNameInJson,outErrorMessage errorMessage, IEnumerable<object> urlParameters =null,stringhttpMethod = WebRequestMethods.Http.Get,stringdata =null)whereT :struct{

errorMessage=newErrorMessage(ErrorMessage.ExceptionCode,"请求失败。");stringresponseContent =RequestResponseContent(urlFormat, userName, urlParameters, httpMethod, data);returnConvertValueTypeResult<T>(responseContent, propertyNameInJson,outerrorMessage);

}///<summary>///获取值类型的结果///</summary>///<typeparam name="T">返回结果的类型</typeparam>///<param name="responseContent">响应内容</param>///<param name="propertyNameInJson">返回结果在json中的键名</param>///<param name="errorMessage">返回请求是否成功</param>///<returns>返回结果;如果请求失败,或者发生错误,返回default(T)。</returns>privatestaticT ConvertValueTypeResult<T>(stringresponseContent,stringpropertyNameInJson,outErrorMessage errorMessage)whereT :struct{if(string.IsNullOrWhiteSpace(responseContent))

{

errorMessage=newErrorMessage(ErrorMessage.ExceptionCode,"请求失败。");returndefault(T);

}if(ErrorMessage.IsErrorMessage(responseContent))

errorMessage=ErrorMessage.Parse(responseContent);elseerrorMessage=newErrorMessage(ErrorMessage.SuccessCode,"请求成功。");

JObject jo=JObject.Parse(responseContent);

JToken jt;if(jo.TryGetValue(propertyNameInJson,outjt))returnConvertValueTypeResult<T>((string)jt);elsereturndefault(T);

}///<summary>///获取值类型的结果///</summary>///<typeparam name="T">返回结果的类型</typeparam>///<param name="responseContent">响应内容</param>///<param name="propertyNameInJson">返回结果在json中的键名</param>///<param name="errorMessage">返回请求是否成功</param>///<returns>返回结果;如果请求失败,或者发生错误,返回default(T)。</returns>privatestaticT ConvertValueTypeResult<T>(stringvalue)whereT :struct{

Type type=typeof(T);if(type.IsEnum)return(T)Enum.Parse(type, value);elseif(type ==typeof(sbyte))return(T)(object)Convert.ToSByte(value);elseif(type ==typeof(byte))return(T)(object)Convert.ToByte(value);elseif(type ==typeof(char))return(T)(object)Convert.ToChar(value);elseif(type ==typeof(short))return(T)(object)Convert.ToInt16(value);elseif(type ==typeof(ushort))return(T)(object)Convert.ToUInt16(value);elseif(type ==typeof(int))return(T)(object)Convert.ToInt32(value);elseif(type ==typeof(uint))return(T)(object)Convert.ToUInt32(value);elseif(type ==typeof(long))return(T)(object)Convert.ToInt64(value);elseif(type ==typeof(ulong))return(T)(object)Convert.ToUInt64(value);elseif(type ==typeof(float))return(T)(object)Convert.ToSingle(value);elseif(type ==typeof(double))return(T)(object)Convert.ToDouble(value);elseif(type ==typeof(decimal))return(T)(object)Convert.ToDecimal(value);elseif(type ==typeof(bool))return(T)(object)Convert.ToBoolean(value);elsethrownewArgumentException("不支持的值类型。");

}///<summary>///向微信服务器提交数据///</summary>///<param name="url">服务器地址</param>//////<param name="httpMethod">http方法</param>///<param name="data">数据</param>///<returns>返回是否提交成功</returns>publicstaticboolRequest(stringurl,stringhttpMethod = WebRequestMethods.Http.Get,stringdata =null)

{byte[] bytes =string.IsNullOrEmpty(data) ?null: RequestEncoding.GetBytes(data);returnRequest(url, httpMethod, (byte[])bytes);

}///<summary>///上传文件///</summary>///<param name="url">服务器地址</param>///<param name="filename">文件名(不包含路径)</param>///<param name="fileData">文件数据</param>///<param name="formData">表单数据</param>///<returns>返回服务器的响应字符串</returns>publicstaticstringUpload(stringurl,stringfilename,byte[] fileData, NameValueCollection formData =null)

{stringresponseContent =string.Empty;if(string.IsNullOrWhiteSpace(url) ||string.IsNullOrWhiteSpace(filename) || fileData ==null|| fileData.Length ==0)returnresponseContent;//边界符stringboundary ="AaB03xAaB03x";//开始边界符byte[] beginBoundary = Encoding.ASCII.GetBytes("--"+ boundary +"\r\n");//结束符byte[] endBoundary = Encoding.ASCII.GetBytes("--"+ boundary +"--\r\n");//换行byte[] newLine = Encoding.ASCII.GetBytes("\r\n");

MemoryStream ms=null;

Stream stream=null;

HttpWebResponse response=null;

StreamReader sr=null;try{

HttpWebRequest request=(HttpWebRequest)WebRequest.Create(url);

request.Method=WebRequestMethods.Http.Post;

request.ContentType="multipart/form-data; boundary="+boundary;//写入文件stringheader =string.Format("Content-Disposition: form-data; filename=\"{0}\"\r\n"+"Content-Type:application/octet-stream\r\n\r\n",

filename);byte[] headerbytes =Encoding.UTF8.GetBytes(header);

ms=newMemoryStream();

ms.Write(beginBoundary,0, beginBoundary.Length);

ms.Write(headerbytes,0, headerbytes.Length);

ms.Write(fileData,0, fileData.Length);//写入表单数据if(formData !=null&& formData.Count >0)

{varformItem ="\r\n--"+ boundary +"\r\nContent-Disposition: form-data; name=\"{0}\""+"\r\n\r\n{1}\r\n";foreach(stringkeyinformData.Keys)

{stringvalue =formData[key];byte[] bytes = Encoding.UTF8.GetBytes(string.Format(formItem, key, value));

ms.Write(bytes,0, bytes.Length);

}

}//写入结束边界符ms.Write(newLine,0, newLine.Length);

ms.Write(endBoundary,0, endBoundary.Length);

request.ContentLength=ms.Length;

stream=request.GetRequestStream();

stream.Write(ms.ToArray(),0, (int)ms.Length);//获取响应response =(HttpWebResponse)request.GetResponse();

sr=newStreamReader(response.GetResponseStream(), HttpHelper.ResponseEncoding);

responseContent=sr.ReadToEnd();

}finally{if(ms !=null)

ms.Close();if(stream !=null)

stream.Close();if(sr !=null)

sr.Close();if(response !=null)

response.Close();

}returnresponseContent;

}///<summary>///上传文件///</summary>///<param name="url">服务器地址</param>///<param name="pathname">包含路径的文件名</param>///<param name="formData">表单数据</param>///<returns>返回服务器的响应字符串</returns>publicstaticstringUpload(stringurl,stringpathname, NameValueCollection formData =null)

{stringfilename =Path.GetFileName(pathname);byte[] data =null;

FileStream fs=null;

MemoryStream ms=null;try{

fs=newFileStream(pathname, FileMode.Open, FileAccess.Read);

ms=newMemoryStream();intbufferLength =2048;byte[] buffer =newbyte[bufferLength];intsize = fs.Read(buffer,0, bufferLength);while(size >0)

{

ms.Write(buffer,0, size);

size= fs.Read(buffer,0, bufferLength);

}

data=ms.ToArray();

}finally{if(fs !=null)

fs.Close();if(ms !=null)

ms.Close();

}returnUpload(url, filename, data, formData);

}

}

HttpHelper

四.最终效果如下:

五.微信公众号开发系列导航1.0初始微信公众号

2.0创建自定义菜单

3.0查询自定义菜单

4.0公众号消息处理

5.0微信支付

6.0模板消息

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有