开发微信小程序代码准备
白羽 2018-06-06 来源 :网络 阅读 996 评论 0

摘要:本文将带你了解开发微信小程序代码准备,希望本文对大家学微信有所帮助。


开发微信小程序流程 接入微信小程序 > 代码开发 > 提交审核和发布

 

接入

接入是指在微信平台注册和相关身份信息认证

1:微信公众平台(https://mp.weixin.qq.com/) 注册小程序,获取唯一标识AppId ,和相关身份信息认证

2:微信商户平台(https://pay.weixin.qq.com/) 注册,获取商户信息,支付场景用到

 

开发准备

·  IDE:官方提供的 微信开发者工具,方便可以直接使用微信提供的各种API,解决自己电脑开发环境需要指定ip,提供平台认证繁琐流程

· 后台API: 安全起见,相关的登录和统一下单支付交由后台后台接口实现, 小程序发送后台请求需要再头部传入token,进行省份信息确认

 

代码开发

  小程序代码结构图

------img 图片资源相关

------pages

.------- 模块代码实现

------utils

      http.js 微信请求包装类

      wx.js 登录包装类

------app.js 主入口,

------app.json 主入口配置

------app.wxss 样式

 

app.js,里面存放全局常量参数,其他模块可以直接通过getApp() 来获取下面信息

//app.js
App({
onLaunch: function () {
//调用API从本地缓存中获取数据
var logs = wx.getStorageSync('logs') || []
logs.unshift(Date.now());
wx.setStorageSync('logs', logs);
},
config: {
baseUrl: "********",
key: "**********",
appid: "**********"
}
})
 
app.json 置顶小程序路由跳转(pages) ,基本信息(window), 底部导航菜单(tabBar)
{
"pages":[
"pages/index/index",
"pages/romance/romance",
"pages/release/release",
],
"window":{
"backgroundTextStyle":"light",
"navigationBarBackgroundColor":"#fea213",
"navigationBarTitleText":"第一个小程序",
"navigationBarTextStyle":"#fff"
},
"tabBar":{
"color":"#dddddd",
"selectedColor":"#3cc51f",
"borderStyle":"white",
"backgroundColor":"#ffffff",
"list":[{
"pagePath":"pages/index/index",
"iconPath":"img/home.png",
"selectedIconPath":"img/home1.png",
"text":"首页"
},
{
"pagePath":"pages/romance/romance",
"iconPath":"img/manager.png",
"selectedIconPath":"img/manager1.png",
"text":"个人中心"
}
]
}
}
 
http.js 封装rest服务包装类,其他模块方便直接调用,不用写繁琐代码
 
classHttp {
app;
constructor() {
this.app =getApp();
}
 
get(url,callback) {
var instance =this;
wx.request({
url: instance.app.config.baseUrl +url,
data: {},
method: 'GET',
header: {
'token':encodeURI(wx.getStorageSync("token")),
'content-type':'application/json'
},
success: function (res) {
if (res.data.errorCode =='user_not_login') {
wx.clearStorageSync();
}
if (callback)callback(res);
},
fail: function (res) {
console.log(res);
}
})
}
 
post(url,data,callback) {
var instance =this;
wx.request({
url: instance.app.config.baseUrl +url,
data: data,
method: 'POST',
header: {
'token':encodeURI(wx.getStorageSync("token")),
'content-type':'application/json'
},
success: function (res) {
if (res.data.errorCode =='user_not_login') {
wx.clearStorageSync();
}
 
if (callback)callback(res);
},
fail: function (res) {
console.log(res);
}
});
}
}
module.exports =Http;
 
wx.js 用来实现微信登录,获取用户基本信息 ,调用后台接口 url: app.config.baseUrl + "user/wxlogin",,取得关键的openId, 
class WxService {
app;
constructor() {
this.app =getApp();
}
 
login(app,callback) {
var page =this;
wx.login({
success: function (re) {
if (re.code) {
wx.getUserInfo({
success: function (res) {
wx.setStorageSync('userInfo',res.userInfo);
var data = {
'username':re.code,
'userSaveBean': {'username':'','password':'','name':res.userInfo.nickName,'birth':newDate().getTime,'address':res.userInfo.city,'mobile':13111111111,'headimg':res.userInfo.avatarUrl }
}
 
wx.request({
url: app.config.baseUrl +"user/wxlogin",
data: data,
method: 'POST',
header: {
'content-type':'application/json'
},
success: function (res) {
var yxNum =res.data.responseBody.username;
wx.setStorageSync('yxNum',yxNum);
wx.setStorageSync('openId',res.data.responseBody.openid);
var token =page.pwd(res.data.responseBody.openid,app.config.code,app.config.key);
wx.setStorageSync('token',token);
 
if (callback)
callback();
},
fail: function (res) {
console.log(res);
}
});
}
});
 
} else {
console.log('获取用户登录态失败!' +res.errMsg)
}
}
})
}
}
module.exports =WxService;

 

 

代码模块实现官网文档有大量详细说明,比如html的编写,组件,样式,和各种api的使用

就不做过多描述,这里说下支付

 

支付分两步 : 统一下单 > 发起字符

通过统一下单接口,获取微信返回的prepay_id ,再把prepay_id和其他相关信息提供支付接口,支付

var preOrderUrl ="order/prepay?amount=1&articleId=" +aid +"&totalFee=" +total_fee +"&openid=" +openid;
http.get(preOrderUrl,function (res) {//调用后台统一下单接口,获取prepay_id
if (res.data.errorCode) {
wx.hideLoading();
wx.showModal({
title: '失败!',
content: res.data.errorMsg.substring(0,res.data.errorMsg),
showCancel: false
})
return;
}
var paymentTS ="" +newDate().getTime();
var paymentNS ="" +newDate().getTime();
var prepayId =res.data.responseBody.prepay_id;
var paymentPack ='prepay_id=' +res.data.responseBody.prepay_id;
var orderId =res.data.responseBody.orderId;
var strPaymentSign ="appId=" +appid +"&nonceStr=" +paymentNS +"&package=" +paymentPack +"&signType=MD5&timeStamp=" +paymentTS +"&key=" +key;
var paySign =ma5Helper.toMd5(strPaymentSign).toUpperCase();
wx.requestPayment(//调用微信支付接口,付款
{
timeStamp: paymentTS,
nonceStr: paymentNS,
package: paymentPack,
signType: 'MD5',
paySign: paySign,
success: function (res) {
 
//提交订单到服务器,保存数据
var orderUrl =app.config.baseUrl +"order";
var orderData = {flag:true,orderId:orderId,prepayId:prepayId,msg:"" };
http.post("order",orderData,function (res) {
wx.hideLoading();
if (res.data.errorCode) {
wx.showModal({
title: '订单提交失败!',
content: res.data.errorMsg.substring(0,res.data.errorMsg.indexOf('[')),
showCancel: false
})
} else {
//支付成功
wx.showToast({
title: '支付成功',
icon: 'success',
duration: 3000,
success: function () {
wx.switchTab({
url: '../romance/romance',
})
}
})
}
});
},
fail: function (res) { },
complete: function (res) { }
})
}

 

统一下单

@GetMapping("/prepay")public ResponseBean createOrderTemp(HttpServletRequest request, @ModelAttribute OrderTempSaveBean saveBean){
    saveBean.setSpbill_create_ip(okhttpService.getIpAddress(request));    return success(orderTempService.createOrderTemp(userFromToken(request),saveBean));}
 
/** * 统一下单 * @param user * @param saveBean * @return */@Transactionalpublic Map createOrderTemp(User user,OrderTempSaveBean saveBean) {
    String orderNumber= (new Random().nextInt(100))+""+DateTime.now().toString(DateUtils.pattern.defualt_2.getContent())+user.getId();   if(saveBean.getTransType() == null)
       throw new BusinessException(ErrorCode.invalid_request,"编码未设置");    OrderTempWithBLOBs orderTemp=new OrderTempWithBLOBs();    orderTemp.setFlag(true);    orderTemp.setStatus(OrderStatus.onCreate.name());    saveBean.setOpenid(user.getOpenid());    saveBean.setNonceStr(orderNumber);    saveBean.setOutTradeNo(orderNumber);    saveBean.setSpbill_create_ip(saveBean.getSpbill_create_ip() == null ? "1.1.1.1": saveBean.getSpbill_create_ip());    if(saveBean.getTotalFee() == null && saveBean.getTotalFee() <=0)
        throw new BusinessException(ErrorCode.invalid_request,"交易金额不对");    if(saveBean.getTransType().equals(TransType.C004)){
 
       if(saveBean.getAmount() == null && saveBean.getAmount() <=0)
           throw new BusinessException(ErrorCode.invalid_request,"数量不对");       Article article = articleMapper.selectByPrimaryKey(saveBean.getArticleId());       if(article ==null)
           throw new BusinessException(ErrorCode.article_not_found,"未找到");       if(new DateTime(article.getEndTime()).compareTo(new DateTime()) <0)
           throw  new BusinessException(ErrorCode.invalid_request,"已经结束") ;       saveBean.setBody("标题-"+article.getThemeTitle());   }else if (saveBean.getTransType().equals(TransType.C001)){
        saveBean.setAmount(1);        saveBean.setArticleId(-9999);        saveBean.setBody("浪漫之旅-充值");    }else{
        throw  new BusinessException(ErrorCode.invalid_request,"无效请求") ;    }
 
    Map unifiedorderMap=null;    try {
        unifiedorderMap= mWxPayService.createOrderTemp(saveBean);        logger.info("=============> createOrderTemp success : "+JSON.toJSONString(unifiedorderMap));        if(!"SUCCESS".equals(unifiedorderMap.get("return_code"))){
            throw new BusinessException(ErrorCode.invalid_request,unifiedorderMap.get("return_msg").toString());        }
        orderTemp.setPrepayId(String.valueOf(unifiedorderMap.get("prepay_id")));    }catch (BusinessException e){
        orderTemp.setFlag(false);        throw new BusinessException(e.getErrorCode(),e.getMessage());    }catch (Exception e){
        orderTemp.setFlag(false);        orderTemp.setMsg(e.getMessage());        e.printStackTrace();        logger.info("=============> createOrderTemp Exception : "+e.getMessage());        throw new BusinessException(ErrorCode.sys_error,"下单失败了!");    }finally {
        orderTemp.setCreateTime(new Timestamp(System.currentTimeMillis()));        orderTemp.setParam(JSONObject.toJSONString(saveBean));        orderTemp.setCreateBy(user.getNickname() ==null ? "":user.getNickname());        orderTemp.setUserId(user.getId());        orderTemp.setOutTradeNo(orderNumber);        orderTemp.setAmount(saveBean.getAmount());        orderTemp.setArticleId(saveBean.getArticleId());        orderTemp.setBody(saveBean.getBody());        orderTemp.setPrice(saveBean.getTotalFee());        orderTemp.setSpbillCreateIp(saveBean.getSpbill_create_ip());        orderTemp.setMsg(JSONObject.toJSONString(unifiedorderMap));        orderTempMapper.insert(orderTemp);        unifiedorderMap.put("orderId",orderTemp.getId());    }
 
    return unifiedorderMap;}
 
mWxPayService.createOrderTemp(saveBean) 实现
public Map createOrderTemp(OrderTempSaveBean saveBean) throws Exception {
    Map reqData = WxPayConfig.genUnifiedorder();    reqData.put("body", saveBean.getBody());    reqData.put("nonce_str", saveBean.getNonceStr());    reqData.put("out_trade_no", saveBean.getOutTradeNo());    reqData.put("total_fee",saveBean.getTotalFee().toString());    reqData.put("spbill_create_ip", saveBean.getSpbill_create_ip());    reqData.put("openid",saveBean.getOpenid());    reqData.put("sign", WXPayUtil.generateSignature(reqData, Const.key, SignType.MD5));    String reqXml = WXPayUtil.mapToXml(reqData);    String response = okhttpService.post(Const.UNIFIEDORDER_URL_SUFFIX, reqXml);    return  WXPayUtil.xmlToMap(response);}
 
 
WXPayUtil.generateSignature(reqData, Const.key, SignType.MD5))实现
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(Const.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)) {
        return HMACSHA256(sb.toString(), key);    }
    else {
        throw new Exception(String.format("Invalid sign_type: %s", signType));    }
}
 
WXPayUtil.mapToXml(reqData) 实现
/** * 将Map转换为XML格式的字符串 * * @param data Map类型数据 * @return XML格式的字符串 * @throws Exception */public static String mapToXml(Map<String, String> data) throws Exception {
    DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();    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) {
    }
    return output;}
 
okhttpService.post(Const.UNIFIEDORDER_URL_SUFFIX, reqXml) 实现
/** * post * @param url * @param json * @return * @throws IOException */public String post(String url, String json) throws IOException {
    RequestBody body = RequestBody.create(JSON, json);    Request request = new Request.Builder()
            .url(url)
            .post(body)
            .build();    try (Response response = client.newCall(request).execute()) {
        return response.body().string();    }
}
 
 
WXPayUtil.xmlToMap(response) 实现
/** * XML格式字符串转换为Map * * @param strXML XML字符串 * @return XML数据转换后的Map * @throws Exception */public static Map<String, String> xmlToMap(String strXML) throws Exception {
    try {
        Map<String, String> data = new HashMap<String, String>();        DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();        DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();        InputStream 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());            }
        }
        try {
            stream.close();        } catch (Exception ex) {
            // do nothing        }
        return data;    } catch (Exception ex) {
        WXPayUtil.getLogger().warn("Invalid XML, can not convert to map. Error message: {}. XML content: {}", ex.getMessage(), strXML);        throw ex;    }
 
}

 


最终效果就是一个支付的页面了,

 

 开发微信小程序代码准备


本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注职坐标移动开发之微信频道!


本文由 @白羽 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程