h5对接jssdk支付分并调用开启支付分页面
1、ws.config签名 调用ticket等获取ws.config的签名,下面会调用方法再调用方法时需要再次按照调用方法的签名
wx.config({
debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
appId: '', // 必填,公众号的唯一标识
timestamp: , // 必填,生成签名的时间戳
nonceStr: '', // 必填,生成签名的随机串
signature: '',// 必填,签名
jsApiList: [] // 必填,需要使用的JS接口列表
});
jsapi_ticket
生成签名之前必须先了解一下jsapi_ticket,jsapi_ticket是公众号用于调用微信JS接口的临时票据。正常情况下,jsapi_ticket的有效期为7200秒,通过access_token来获取。由于获取jsapi_ticket的api调用次数非常有限,频繁刷新jsapi_ticket会导致api调用受限,影响自身业务,开发者必须在自己的服务全局缓存jsapi_ticket 。
1、获取access_token(有效期7200秒,开发者必须在自己的服务全局缓存access_token):
http请求方式: GET
https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=appID&secret=appsecret
2、用第一步拿到的access_token 采用http GET方式请求获得jsapi_ticket(有效期7200秒,api 调用次数非常有限,频繁刷新api_ticket 会导致api调用受限,影响自身业务,开发者必须在自己的服务全局缓存jsapi_ticket):https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi
成功返回如下JSON:
{
"errcode":0,
"errmsg":"ok",
"ticket":"bxLdikRXVbTPdHSM05e5u5sUoXNKd8-41ZO3MhKoyN5OfkWITDGgnr2fwJ0m9E8NYzWKVZvdVtaUgWvsdshFKA",
"expires_in":7200
}
1
2
3
4
5
6
https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=27_1JoR00pdKD26t0IbR_kPzC5FbCChBLVmoRTkJPQ6b3SbHO2D-IfeaCe1-iBI-kFCjZ58QCSffv9IEVhv0PfmfCsT4ZAEDNcwfO8zYEtB05SOM-mY8pspfKJsz_V8LJnqhMWJO-R9ymZhBj00UWRdACAIKF&type=jsapi
获得jsapi_ticket之后,就可以生成JS-SDK权限验证的签名了。
https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=wx954f1899ef15d2ea&secret=9af198bddb8db015e9113ed7379cbcdf
微信 JS 接口签名校验工具:
https://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=jsapisign
微信支付接口签名校验工具
https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=20_
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://res.wx.qq.com/open/js/jweixin-1.5.0.js"></script>
<script src="jquery-3.4.1.min.js"></script>
<script src="vconsole.min.js"></script>
<script type="text/javascript">
var vConsole = new VConsole();
window.vConsole = new window.VConsole();
var appidG = "";
var timestampG = "";
var nonceStrG = "";
var signatureG = ""; $(function () {
var signUrl = window.location.href.split('#')[0];
console.log("signUrl:" + signUrl);
$.ajax({
url: "/index/test",
method: "post",
data: {
signUrl: signUrl
},
success: function (data) {
console.log("data:" + data);
var dataJson = JSON.parse(data);
// console.log("dataJson.appid:"+dataJson.appid);
console.log("wx.config() ---> 接收后台返回的参数");
appidG = dataJson.appid;
timestampG = dataJson.timestamp;
nonceStrG = dataJson.nonceStr;
signatureG = dataJson.signature;
wx.config({
debug: true,
appId: dataJson.appid,
timestamp: dataJson.timestamp,
nonceStr: dataJson.nonceStr,
signature: dataJson.signature,
jsApiList: ['onMenuShareAppMessage', 'openBusinessView']
})
}
});
}); function getLocation() {
wx.ready(function () {
wx.getLocation({
type: 'gcj02', // 默认为wgs84的gps坐标,如果要返回直接给openLocation用的火星坐标,可传入'gcj02'
success: function (res) {
var latitude = res.latitude; // 纬度,浮点数,范围为90 ~ -90
var longitude = res.longitude; // 经度,浮点数,范围为180 ~ -180。
var speed = res.speed; // 速度,以米/每秒计
var accuracy = res.accuracy; // 位置精度
alert('纬度:' + latitude + '------经度:' + longitude)
},
fail: function (res) {
console.log('未开启定位功能');
},
cancel: function (res) {
console.log('用户拒绝授权获取地理位置');
}
});
});
} /**
* 跳转微信支付分
*/
function goToWXScore() {
console.log("appidG:" + appidG);
console.log("timestampG:" + timestampG);
console.log("nonceStrG:" + nonceStrG);
console.log("signatureG:" + signatureG);
$.ajax({
url: "/index/generateSignature",
method: "post",
data: {
timestamp: timestampG,
nonce_str:nonceStrG
},
success: function (sign) {
console.log("sign:" + sign);
wx.ready(function () {
wx.checkJsApi({
jsApiList: ['openBusinessView'], // 需要检测的JS接口列表
success: function (res) {
// 以键值对的形式返回,可用的api值true,不可用为false
// 如:{"checkResult":{"openBusinessView":true},"errMsg":"checkJsApi:ok"}
if (res.checkResult.openBusinessView) {
wx.invoke(
'openBusinessView', {
businessType: 'wxpayScoreEnable',
queryString: "mch_id=1518750531&service_id=00004000000000704283351234894845&out_request_no=1234323JKHDFE1243259×tamp=" + timestampG + "" +
"&nonce_str=" + nonceStrG + "&sign_type=HMAC-SHA256&sign=" + sign + ""
},
function (res) {
// 从微信侧小程序返回时会执行这个回调函数
if (parseInt(res.err_code) === 0) {
s
// 返回成功
} else {
// 返回失败
}
});
}
}
});
});
}
}); } </script>
</head>
<body>
<div>
<!--<button id="snap1" onclick="goToWXScore()">goToWXScore</button>-->
<button id="pay" onclick="goToWXScore()" value="跳转支付分">跳转支付分</button>
<button id="snap2" onclick="getLocation()" value="获取地区">获取地区</button> <!--<button id="snap3" onclick="onBridgeReady()">支付</button>-->
</div>
</body>
</html>
后端接口
@ResponseBody
@RequestMapping("/test")
@Login(required = false)
public String test(String signUrl) {
System.out.println("signUrl:"+signUrl);
//String res = HttpGetMethod.doGet("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=wx954f1899ef15d2ea&secret=acb8ad2a46765766c7881ea37237c1c7", "utf8", null);
String jsapi_ticket = "HoagFKDcsGMVCIY2vOjf9kjcHCRqLoF8k77O2dyyZiMTaOwxLTQ9nHU3fa4jfiEj2XW4NsvQG53gZZgVMkQdJA";
//String url = "http://localhost/h5/weixinexer.html";
Map<String, String> ret = com.jd.mrd.m.nc.web.utils.Sign.sign(jsapi_ticket, signUrl);
ret.put("appid","wx954f1899ef15d2ea");
for (Map.Entry entry : ret.entrySet()) {
System.out.println(entry.getKey() + ", " + entry.getValue());
}
return JSON.toJSONString(ret);
} /**
* 获取签名
* @param timestamp
* @param nonce_str
* @return
* @throws Exception
*/
@ResponseBody
@RequestMapping("/generateSignature")
@Login(required = false)
public String generateSignature(String timestamp,String nonce_str) throws Exception {
HashMap<String, String> stringStringHashMap = new HashMap<String, String>();
stringStringHashMap.put("mch_id","1518750531");
stringStringHashMap.put("service_id","00004000000000704283351234894845");
stringStringHashMap.put("out_request_no","1234323JKHDFE1243259");
stringStringHashMap.put("timestamp",timestamp);
stringStringHashMap.put("nonce_str",nonce_str);
stringStringHashMap.put("sign_type","HMAC-SHA256");
String signature = WeChatUtils.generateSignature(stringStringHashMap, "acb8ad2a46765766c7881ea37237c1c7", WeChatConstant.SignType.HMACSHA256);
return signature;
} @RequestMapping(value = "generateImage")
@ResponseBody
@Login(required = false)
public String generateImage(HttpServletRequest request, String base64) throws IOException { //String base64=request.getParameter("base64");;
File directory = new File("");//设定为当前文件夹
URL resource = IndexController.class.getResource("/");
String clasFilePath = resource.getPath();
System.out.println(clasFilePath);//获取标准的路径
File file = new File(clasFilePath);
String strParentDirectory = file.getParent();
System.out.println(strParentDirectory);
file = new File(strParentDirectory);
strParentDirectory = file.getParent();
System.out.println(strParentDirectory);
strParentDirectory = strParentDirectory + "/h5/img";
System.out.println(strParentDirectory); String fileName = CommonUtils.generateUUID() + ".jpg";
String fileUrl = strParentDirectory + "/" + fileName;
String imgStr = base64.split(",")[1];
Base64Utils.GenerateImage(imgStr, fileUrl);
System.out.println(fileUrl);
System.out.println(request.getServerName() + "/h5/img/" + fileName);
return request.getServerName() + "/h5/img/" + fileName; // JSONObject json =new JSONObject();
// json.put("result",fileUrl);
// response.setCharacterEncoding("utf-8");
// response.setContentType("application/json;charset=utf-8");
// PrintWriter out = null;
// out = response.getWriter();
// out.write(json.toString());
// return json.toJSONString();
} @RequestMapping(value = "testPost")
@ResponseBody
@Login(required = false)
public String testPost(HttpServletRequest request, String base64) { return ""; }
package com.jd.lestore.payment.common.utils; import com.jd.lestore.payment.common.constant.WeChatConstant;
import com.jd.lestore.payment.common.constant.WeChatConstant.SignType;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList; import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.StringWriter;
import java.security.MessageDigest;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Set; public class WeChatUtils { /**
* 生成新的请求序列号
*
* @return
*/
public static Integer getNewRequestSerial() {
String timestamp = String.valueOf( System.currentTimeMillis()/1000 );
return Integer.valueOf(timestamp).intValue();
} public static String generateSignature(final Map<String, String> data, String key) throws Exception {
return generateSignature(data, key, SignType.MD5);
} public static String generateHMACSHA256Signature(final Map<String, String> data, String key) throws Exception {
return generateSignature(data, key, SignType.HMACSHA256);
} /**
* 生成签名
*
* @param data
* @param key
* @return
* @throws Exception 规则
* 第一步,设所有发送或者接收到的数据为集合M,将集合M内非空参数值的参数按照参数名ASCII码从小到大排序(字典序),使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串stringA。
* <p>
* 特别注意以下重要规则:
* <p>
* ◆ 参数名ASCII码从小到大排序(字典序);
* ◆ 如果参数的值为空不参与签名;
* ◆ 参数名区分大小写;
* ◆ 验证调用返回或微信主动通知签名时,传送的sign参数不参与签名,将生成的签名与该sign值作校验。
* ◆ 微信接口可能增加字段,验证签名时必须支持增加的扩展字段
* <p>
* 第二步,在stringA最后拼接上key得到stringSignTemp字符串,并对stringSignTemp进行MD5运算,再将得到的字符串所有字符转换为大写,得到sign值signValue。
*/
public static String generateSignature(final Map<String, String> data, String key, SignType signType) throws Exception { Set<String> keySet = data.keySet();
String[] keyArray = keySet.toArray(new String[keySet.size()]);
Arrays.sort(keyArray);
StringBuilder sb = new StringBuilder();
for (String k : keyArray) {
if (k.equals(WeChatConstant.FIELD_SIGN)) {
continue;
}
if (data.get(k).trim().length() > 0) // 参数值为空,则不参与签名
sb.append(k).append("=").append(data.get(k).trim()).append("&");
}
sb.append("key=").append(key); if (SignType.MD5.equals(signType)) {
return MD5(sb.toString()).toUpperCase();
} else if (SignType.HMACSHA256.equals(signType)) {
System.out.println("HMACSHA256 original text: " + sb.toString());
return HMACSHA256(sb.toString(), key);
} else {
throw new Exception(String.format("Invalid sign_type: %s", signType));
}
} /**
* 生成 MD5
*
* @param data 待处理数据
* @return MD5结果
*/
public static String MD5(String data) throws Exception {
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] array = md.digest(data.getBytes("UTF-8"));
StringBuilder sb = new StringBuilder();
for (byte item : array) {
sb.append(Integer.toHexString((item & 0xFF) | 0x100).substring(1, 3));
}
return sb.toString().toUpperCase();
} /**
* 生成 HMACSHA256
*
* @param data 待处理数据
* @param key 密钥
* @return 加密结果
* @throws Exception
*/
public static String HMACSHA256(String data, String key) throws Exception {
Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
SecretKeySpec secret_key = new SecretKeySpec(key.getBytes("UTF-8"), "HmacSHA256");
sha256_HMAC.init(secret_key);
byte[] array = sha256_HMAC.doFinal(data.getBytes("UTF-8"));
StringBuilder sb = new StringBuilder();
for (byte item : array) {
sb.append(Integer.toHexString((item & 0xFF) | 0x100).substring(1, 3));
}
return sb.toString().toUpperCase();
} /**
* 获取当前时间戳,单位秒
*
* @return
*/
public static long getCurrentTimestamp() {
return System.currentTimeMillis() / 1000;
} /**
* 获取当前时间戳,单位毫秒
*
* @return
*/
public static long getCurrentTimestampMs() {
return System.currentTimeMillis();
} /**
* XML格式字符串转换为Map
*
* @param strXML XML字符串
* @return XML数据转换后的Map
* @throws Exception
*/
public static Map<String, String> xmlToMap(String strXML) throws Exception {
InputStream stream = null;
try {
Map<String, String> data = new HashMap<String, String>();
DocumentBuilderFactory documentBuilderFactory = setWechatPaySafeCode();
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
stream = new ByteArrayInputStream(strXML.getBytes("UTF-8"));
org.w3c.dom.Document doc = documentBuilder.parse(stream);
doc.getDocumentElement().normalize();
NodeList nodeList = doc.getDocumentElement().getChildNodes();
for (int idx = 0; idx < nodeList.getLength(); ++idx) {
Node node = nodeList.item(idx);
if (node.getNodeType() == Node.ELEMENT_NODE) {
org.w3c.dom.Element element = (org.w3c.dom.Element) node;
data.put(element.getNodeName(), element.getTextContent());
}
}
return data;
} finally {
try {
stream.close();
} catch (Exception ex) {
ex.printStackTrace();
}
} } private static DocumentBuilderFactory setWechatPaySafeCode( ) {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
// 禁 用 DOCTYPE
try{
dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
//该 feature 的作用是配置是否包含外部的参数,包括外部 DTD 子集,设置false 禁用参数实体
dbf.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
//该 feature 的功能指是否包含外部生成的实体,设置 false 禁用外部实体
dbf.setFeature("http://xml.org/sax/features/external-general-entities", false);
dbf.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
dbf.setXIncludeAware(false);
dbf.setExpandEntityReferences(false);
}catch ( Exception e ){
e.printStackTrace();
}
return dbf;
} /**
* XML格式字符串转换为Map
*
* @param strXML XML字符串
* @return XML数据转换后的Map
* @throws Exception
*/
public static Map<String, String> xmlClildToMap(String strXML) throws Exception {
InputStream stream = null;
try {
Map<String, String> data = new HashMap<String, String>();
DocumentBuilderFactory documentBuilderFactory = setWechatPaySafeCode();
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
stream = new ByteArrayInputStream(strXML.getBytes("UTF-8"));
org.w3c.dom.Document doc = documentBuilder.parse(stream);
doc.getDocumentElement().normalize();
NodeList nodeList = doc.getDocumentElement().getChildNodes();
for (int idx = 0; idx < nodeList.getLength(); ++idx) {
Node node = nodeList.item(idx);
if (node.getNodeType() == Node.ELEMENT_NODE) {
org.w3c.dom.Element element = (org.w3c.dom.Element) node;
if(element.hasChildNodes()){//对于三级子项处理
for(int i = 0 ; i < element.getChildNodes().getLength();i++){
Node nodeChild = element.getChildNodes().item(i);
data.put(nodeChild.getNodeName(),nodeChild.getTextContent());
}
}else {
data.put(element.getNodeName(), element.getTextContent());
}
}
}
return data;
} finally {
try {
stream.close();
} catch (Exception ex) {
ex.printStackTrace();
}
} } /**
* 将Map转换为XML格式的字符串
*
* @param data Map类型数据
* @return XML格式的字符串
* @throws Exception
*/
public static String mapToXml(Map<String, String> data) throws Exception {
DocumentBuilderFactory documentBuilderFactory = setWechatPaySafeCode();
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
org.w3c.dom.Document document = documentBuilder.newDocument();
org.w3c.dom.Element root = document.createElement("xml");
document.appendChild(root);
for (String key : data.keySet()) {
String value = data.get(key);
if (value == null) {
value = "";
}
value = value.trim();
org.w3c.dom.Element filed = document.createElement(key);
filed.appendChild(document.createTextNode(value));
root.appendChild(filed);
}
TransformerFactory tf = TransformerFactory.newInstance();
Transformer transformer = tf.newTransformer();
DOMSource source = new DOMSource(document);
transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
StringWriter writer = new StringWriter();
StreamResult result = new StreamResult(writer);
transformer.transform(source, result);
String output = writer.getBuffer().toString(); //.replaceAll("\n|\r", "");
try {
writer.close();
} catch (Exception ex) {
ex.printStackTrace();
}
return output;
} /**
* 将Map转换为XML格式的字符串
*
* @param data Map类型数据
* @return XML格式的字符串
* @throws Exception
*/
public static String mapToXmlROOT(Map<String, String> data,String xmlRoot) throws Exception {
DocumentBuilderFactory documentBuilderFactory = setWechatPaySafeCode();
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
org.w3c.dom.Document document = documentBuilder.newDocument();
document.setXmlStandalone(true);
org.w3c.dom.Element root = document.createElement(xmlRoot);
document.appendChild(root);
for (String key : data.keySet()) {
String value = data.get(key);
if (value == null) {
value = "";
}
value = value.trim();
org.w3c.dom.Element filed = document.createElement(key);
filed.appendChild(document.createTextNode(value));
root.appendChild(filed);
}
TransformerFactory tf = TransformerFactory.newInstance();
Transformer transformer = tf.newTransformer();
DOMSource source = new DOMSource(document);
transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
StringWriter writer = new StringWriter();
StreamResult result = new StreamResult(writer);
transformer.transform(source, result);
String output = writer.getBuffer().toString(); //.replaceAll("\n|\r", "");
try {
writer.close();
} catch (Exception ex) {
ex.printStackTrace();
}
return output;
} }
h5对接jssdk支付分并调用开启支付分页面的更多相关文章
- TP5调用小程序微信支付,回调,在待支付中再次调用微信支付
1,必须要有 $mch_id $key $appid这三个值,是需要去申请的,我是直接用公司的2,购买商品订单号用户openid统一下单名称商品价格(必须以分为单位,调起微信支付)服务器的ip地址(没 ...
- 前端如何在h5页面调用微信支付?
在微信服务号开发的时候经常会遇到微信支付的功能实现,通过实际经验自己总结了一下,前端在H5页面调起微信支付有两种办法,一是利用内置对象,二是通过引用微信的js sdk,亲测都能支付成功,从写法上来看用 ...
- 微信公众号内H5调用微信支付国内服务商模式
最近在折微信公众号内H5用JSAPI调用微信支付,境内服务商版支付,微信支付给出的官方文档以及SDK不够详细,导至我们走了一些弯路,把他分享出来,我这边主要是用PHP开发,所以未加说的话示例都是PHP ...
- h5内嵌微信小程序,调用微信支付功能
在小程序中不能使用之前在浏览器中配置的支付功能,只能调用小程序专属的api进行支付. 因为需要在现在实现的基础上,再添加在小程序中调用微信支付功能,所以我的思路是这样的 1.在点击支付按钮时,判断是不 ...
- 微信支付配置信息,JSAPI接口,H5调用微信js接口支付,微信公众号支付
微信支付已经做完了,没接触过微信的我,经历了非常艰难的3天,才把微信支付给做出来,对于专业的人来说,估计就是一小时就搞定的事情了,虽然说做了很长时间,但是确实也学到东西了,也收获了不少,下面跟大家分享 ...
- H5调用微信支付
这里用的是 vue项目; 首先在mounted中判断是否有openId,如果没有,则去获取 let openid = localStorage.getItem('openid'); if (!open ...
- 微信支付-微信公众号支付,微信H5支付,微信APP支付,微信扫码支付
在支付前,如果使用第三方MVC框架,则使用重写模式,服务器也需要配置该项 if (!-e $request_filename){ rewrite ^/(.*)$ /index.php/$ last; ...
- 微信支付(PC扫码支付和H5公众号支付)
最近在做微信支付,微信支付比较坑,官方居然只有.NET.C#.PHP的demo居然没有java的demo.然后微信支付是不提供测试账号的需要直接用正式的公众号.首先来介绍下微信扫码支付吧,微信扫码有两 ...
- Phonegap 之 iOS银联在线支付(js调用ios端银联支付控件)
Phonegap项目,做支付的时候,当把网站打包到ios或android端成app后,在app上通过wap调用银联在线存在一个问题: 就是当从银联支付成功后,再从服务器返回到app客户端就很难实现. ...
随机推荐
- NX二次开发-UFUN将目录与文件名组合在一起uc4575
NX11+VS2013 #include <uf.h> #include <uf_ui.h> #include <uf_cfi.h> UF_initialize() ...
- C++从string中删除所有的某个特定字符【转载】
转载自https://www.cnblogs.com/7z7chn/p/6341453.html C++中要从string中删除所有某个特定字符, 可用如下代码 str.erase(std::remo ...
- iOS 获取音频或是视频的时间
AVURLAsset* audioAsset =[AVURLAssetURLAssetWithURL:audioFileURL options:nil]; CMTime audioDuration = ...
- C 函数指针详解
一 通常的函数调用 一个通常的函数调用的例子://自行包含头文件 void MyFun(int x); //此处的申明也可写成:void MyFun( int ); int main(int a ...
- c实现swap函数陷阱
swap函数陷阱 使用c实现一个交换两个数的函数,代码很简单: void swap(int *a, int *b) { *a ^= *b; *b ^= *a; *a ^= *b; } 只有3行代码,且 ...
- Python3 From Zero——{最初的意识:008~初级实例演练}
一.构显国际橡棋8x8棋盘 #!/usr/bin/env python3 #-*- coding:utf-8 -*- color_0="\033[41m \033[00m" col ...
- 自动化测试工具2-testcomplete
今天来说说testcomplete的使用 录了一个简单案例视频,网址如下:https://v.qq.com/x/page/f05116a062y.html 第一步是创建一个工程: 输入工程名,和选择工 ...
- ubuntu 删除 mysql (转)
1 sudo apt-get autoremove --purge mysql-server-5.0 2 sudo apt-get remove mysql-server 3 sudo apt-get ...
- sql实现取汉字大写首字母
)) ) AS BEGIN DECLARE @py TABLE( ch ), hz1 ) COLLATE Chinese_PRC_CS_AS_KS_WS, hz2 ) COLLATE Chinese_ ...
- 读取数据库的数据并转换成List<>
一.在有帮助类DbHelperSQL的时候 1.下为其中返回SqlDataReader的方法 /// <summary> /// 执行查询语句,返回SqlDataReader ( 注意:调 ...