前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >支付宝小程序开发准备工作

支付宝小程序开发准备工作

作者头像
冬夜先生
修改2021-10-28 10:11:10
3610
修改2021-10-28 10:11:10
举报
文章被收录于专栏:csicocsico

在正式开发支付宝小程序之前,我们要做一些准备工作,比如说封装一下config文件、request请求、api接口集中定义,自定义的工具脚本等。文末还有彩蛋哈~

第一步:在支付宝开发者工具中新增支付宝小程序。

第二步:在小程序文件的根目录创建utils目录。

创建自定义的相关js文件(或者直接从以前定义好的项目中拷贝过来),如apis.js、config.js、tools.js、http.js、tools.sjs

1.小程序中调用接口的集中展示,加上备注信息,这样在后台查看的时候方便一些吧。

代码语言:javascript
复制
//apis.js
//此处为封装的请求方法
import { getJSON } from './http'


const apis = {
    // 用户登录
    userLogin(params, method = 'GET') {
        return getJSON('/api/login?r=' + new Date().getTime(), params, method)
    },
}

module.exports = apis

 2.配置文件,开发的时候难免遇到接口地址切换开发环境、测试环境、生产环境等各种环境,我们事先配置好文件,在切换的时候直接修改环境参数即可。

代码语言:javascript
复制
// 后台不同环境
const ENV = {
    SIT: 'sit',
    UAT: 'uat',
    PRD: 'prd'
};

//后台环境对应的接口目录
const BUILD_INFO = {
    sit: {
        api: 'http://127.0.0.1:8080',
        domain: ''
    },
    uat: {
        api: 'https://**.com',
        domain: 'https://**.com'
    },
    prd: {
        api: 'https://**.com',
        domain: 'https://**.com'
    }
}
// 小程序APP_id
const APP_ID = {
    sit: '',
    uat: '',
    prd: ''
}

// 不同环境的版本
const VERSION = {
    sit: '1.2.1',
    uat: '1.0.1',
    prd: '1.0.16'
}

//实际使用的后台环境
const env = ENV.PRD;

const config = {
    ENV: env,
    API_URL: BUILD_INFO[env].api,
    APP_ID: APP_ID[env],
    DOMAIN_URL: BUILD_INFO[env].domain,
    VERSION: VERSION[env]
};

module.exports = config;

 3.封装一些常用的工具函数以便我们提升开发效率。比如小程序中的页面跳转一般情况下要绑定事件,然后定义事件方法,在其中定义跳转的页面,此处我封装了一个go2page的方法,这样就不用在小程序页面的脚本中定义各种跳转事件了。不过就是需要在引用go2page的地方添加参数到data中。

在使用go2page方法进行页面跳转后,我们需要从query中提取参数。使用下面的curPagePath方法即可。

代码语言:javascript
复制
const tools = {
    isObject(obj) {
        if (Object.prototype.toString.call(obj) === '[object Object]') {
            return true
        }
        return false
    },
    isDefine(str) {
        if (str === 0) {
            return true
        }
        if (str == '' || (!str)) {
            return false
        }
        return true
    },
    isIDCard(str) {
        const reg = /^(^[1-9]\d{7}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}$)|(^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])((\d{4})|\d{3}[Xx])$)$/
        return reg.test(str)
    },
    isPhone(str) {
        const myreg = /^1[3|4|5|6|7|8|9][0-9]\d{8}$/
        return myreg.test(str)
    },
    isFullName(str) {
        const reg = /^[\u4E00-\u9FA5\uf900-\ufa2d·s]{2,20}$/
        return reg.test(str)
    },
    getUrlParam(href) {
        const indexWen = href.indexOf('?')
        const indexJing = href.indexOf('#')
        const theRequest = {}
        if (indexWen === -1) {
            return theRequest
        }

        if (indexJing < indexWen) { // 如果#号在问好前面
            href = href.substring(indexWen + 1)
        } else {
            href = href.substring(indexWen + 1, indexJing)
        }
        const strArr = href.split('&')
        for (let i = 0; i < strArr.length; i++) {
            theRequest[strArr[i].split('=')[0]] = unescape(strArr[i].split('=')[1])
        }
        return theRequest
    },
    stringifyParam(param = {}) {
        let paramString = ''
        for (let key in param) {
            if (paramString === '') {
                paramString += key + '=' + param[key]
            } else {
                paramString += '&' + key + '=' + param[key]
            }
        }
        return paramString
    },
    // 生成随机码
    getRandom(num) {
        const char = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
        const result = []
        for (let i = 0; i < num - 1; i++) {
            const index = Math.random() * char.length - 1
            const value = char.charAt(index)
            result.push(value)
        }
        return result.join('')
    },
    desensitizing(str = '', from = 0, length = 0, replaceStr = '*') { // 隐藏某些字符串
        if (str.length === 0) {
            return str
        }
        // 变成数组
        const strArr = str.split('')
        // 更改数组
        strArr.splice(from, length, replaceStr.repeat(length))
        return strArr.join('')
    },
    htmlEncode(str = '') {
        if (str === '') {
            return str
        }
        let s = str.replace(/&/g, '&')
        s = s.replace(/</g, '<')
        s = s.replace(/>/g, '>')
        s = s.replace(/\'/g, ''')
        s = s.replace(/\"/g, '"')
        return s
    },
    getDay(day) {
        var today = new Date();
        var targetday_milliseconds = today.getTime() + 1000 * 60 * 60 * 24 * day;
        today.setTime(targetday_milliseconds); //注意,这行是关键代码
        var tYear = today.getFullYear();
        var tMonth = today.getMonth();
        var tDate = today.getDate();
        tMonth = this.doHandleMonth(tMonth + 1);
        tDate = this.doHandleMonth(tDate);
        return tYear + "-" + tMonth + "-" + tDate;
    },
    doHandleMonth(month) {
        var m = month;
        if (month.toString().length == 1) {
            m = "0" + month;
        }
        return m;
    },
    getWeek(dateString) {
        var dateArray = dateString.split("-");
        var date = new Date(dateArray[0], parseInt(dateArray[1] - 1), dateArray[2]);
        return "周" + "日一二三四五六".charAt(date.getDay());
    },
    getUserInfo() {
        my.getStorage({
            key: 'userInfo',
            success: function (res) {
                console.log('获取缓存中用户信息', res)
                return res.data
            },
            fail: function (res) {
                console.log('获取缓存中用户信息失败', res)
                return {}
            }
        });

    },
    checkToken(callback, param = {}) {
        let that = this
        var app = getApp()
        if (app.globalData.userId) {
            callback.call(this, param);
        } else {
            setTimeout(function () {
                param = Object.assign(param, app.globalData)
                that.checkToken(callback, param);
            }, 200);
        }
    },
    go2page(e) {
        const { dataset } = e.target
        let params = []
        for (let key in dataset) {
            if (key != 'url') {
                params.push(key + '=' + dataset[key])
            }
        }
        if (!this.isDefine(e.target.dataset.url)) {
            my.showToast({
                type: 'success',
                content: '建设中,敬请期待',
                duration: 3000,
                success: () => {
                },
            });
        } else {
            let url = e.target.dataset.url
            if (params.length > 0) {
                url = url + '?' + params.join('&')
            }

            my.navigateTo({
                url: url
            });
        }
    },
    round(str) {
        if(!str){return ''}
        return str.toFixed(2)
    },
    curPagePath(query){
        let pages = getCurrentPages();
        let currPage = null;
        // console.log(pages) 的到一个数组
        if (pages.length) {
        // 获取当前页面的对象(上边所获得的数组中最后一项就是当前页面的对象)
        currPage = pages[pages.length - 1];
        }
        // 获取当前页面的路由
        let route = currPage.route
        let params = []
        if(query){
            for (let key in query) {
                params.push(key + '=' + query[key])
            }
        }
        if(params.length>0){
            route += '?' + params.join('&') 
        }
        console.log('当前页面路径==>',route)
    },
    getTimeList(start, end, step,restStart,restEnd,selectDate) {
        var curDate = new Date(),
            curFullYear = curDate.getFullYear(),
            curMonth = curDate.getMonth() + 1,
            curDay = curDate.getDate()
        curMonth = curMonth < 10 ? '0' + curMonth : curMonth
        curDay = curDay < 10 ? '0' + curDay : curDay
        var ymd = curFullYear + '/' + curMonth + '/' + curDay
        selectDate = selectDate.replace(/-/g,'/')

        console.log('selectDate',selectDate)

        var startTime = new Date(ymd + ' ' + start).getTime(),
            endTime = new Date(ymd + ' ' + end).getTime(),
            restStartTime = new Date(ymd + ' ' + restStart).getTime(),
            restEndTime = new Date(ymd + ' ' + restEnd).getTime()
        var returnArr = []
        while (startTime + step * 60 * 1000 <= endTime) {
            // 中途休息的时间阶段
            if(startTime + step * 60 * 1000>restStartTime && startTime + step * 60 * 1000<=restEndTime){
                startTime += step * 60 * 1000
                continue
            }
            // 如果时间小于当前时间则跳过显示
            if(startTime + step * 60 * 1000<new Date().getTime() && ymd == selectDate){
                startTime += step * 60 * 1000
                continue
            }
            returnArr.push(this.getTime(startTime) + '-' + this.getTime(startTime+step*60*1000))
            startTime += step * 60 * 1000
        }

        return returnArr

    },

    getTime(timestamp) {
        var date = new Date(timestamp);//时间戳为10位需*1000,时间戳为13位的话不需乘1000
        var Y = date.getFullYear() + '-';
        var M = (date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1) + '-';
        var D = (date.getDate() < 10 ? '0' + date.getDate() : date.getDate()) + ' ';
        var h = (date.getHours() < 10 ? '0' + date.getHours() : date.getHours()) + ':';
        var m = (date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes()) + '';
        var s = date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds();
        return h + m;
    },
    isIphoneX(){
        var u = navigator.userAgent;
        var isIOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/);
        if (isIOS) {
            if (screen.height == 812 && screen.width == 375) {
                return true;
            }
            else {
                return false;
            }
        }
    }

}
module.exports = tools;

4.常用的请求方法,根据实际项目中约定的接口规范进行修改。

代码语言:javascript
复制
import config from './config';

function isApiSuccess(result) {
    const status = result.success || result.stat || result.status || ''; // 接口状态字段
    if (status == true || status == '000' || status === 'ok' || status === 'success' || status === 'succeed') {
        return true;
    } else {
        return false;
    }
}

export function getJSON(url, params, method = 'GET', mockSetting = {}) {
    let path = '';
    const { on = false, mockData = {} } = mockSetting;
    if (url.indexOf('http') > -1 || url.indexOf('https') > -1) {
        path = url;
    } else {
        path = config.API_URL + url;
    }
    return new Promise((resolve, reject) => {
        my.showLoading();
        if (on) {
            console.log('-------返回 mock 数据-------', url, params, mockData);
            if (isApiSuccess(mockData)) {
                resolve(mockData);
            } else {
                reject(mockData);
            }
            my.hideLoading();
            return;
        }

        let token = params.token
        let headers = {
            "Content-Type": "application/json",
        }

        if (params.headers) {
            headers = Object.assign(headers, params.headers)
            delete params.headers
        }
        if (token) {
            headers['Authorization'] = 'Bearer ' + token
            delete params.token
        }
        if (method.toLocaleLowerCase() != 'get') {
            headers['content-type'] = 'application/json'
        }

        if (method.toLocaleLowerCase() == 'delete') {
            headers['content-type'] = 'application/x-www-form-urlencoded'
        }

        my.request({
            url: path,
            method: method,
            data: params,
            dataType: 'json',
            headers: headers,
            success: (result) => {
                // console.log(`--返回数据--接口地址=>${url},结果=>${JSON.stringify(result)}`);
                my.hideLoading();
                if (isApiSuccess(result.data)) {
                    resolve(result.data);
                } else {
                    reject(result.data);
                }
            },
            fail: (err) => {
                console.log('-------返回错误-------', url, err);
                my.hideLoading();
                if (err.status == 401) {
                    console.log('未登录权限')
                }
                my.showToast({
                    type: 'fail',
                    content: '请求异常,请稍后再试!'
                });
                reject(err);
            },
        });
    });
}

5.在页面中引用方法时需要用到sjs文件。

代码语言:javascript
复制
const desensitizing = (str,from,length,replaceStr = '*')=>{
    if (str.length === 0) {
        return str
    }
    // 变成数组
    const strArr = str.split('')
    let replace_str = ''
    for(var i=0;i<length;i++){
        replace_str += replaceStr
    }
    // 更改数组
    strArr.splice(from, length, replace_str)
    return strArr.join('')
}
const repeat = (length,repeatStr='*') =>{
    var str = ''
    for(let i=0;i<length;i++){
        str += repeatStr
    }
    return str
}
const desensitizing2 = (str,type,isdes=false,replaceStr = '*')=>{
    if(!isdes){
        return str
    }
    if(str == '' || !str){
        return ''
    }
    switch(type){
        case 'name':
            str = str.replace(getRegExp('·','g'),replaceStr);
            if(str.length == 1){
                return replaceStr
            }
            if(str.length>=2){
                if(str.length>=5){
                    return repeat(4,replaceStr) + str[str.length-1]
                }
                return desensitizing(str,0,str.length-1)
            }
            return replaceStr;
            break;
        case 'sfz':
            return desensitizing(str,1,str.length-2)
            break;
        case 'phone':
            return desensitizing(str,3,6)
            break;
    }
}

const substring = (str,from,length=0)=>{
    if(str.length == 0){
        return ''
    }
    return str.substring(from,from+length)
}
const isDefine = (str)=>{
    if (str === '' || !str) {
            return false
    }
    return true
}
const round = (str,len=2)=>{
    if(!str){return ''}
    let point_index = str.lastIndexOf('.')
    if(len == 0){
        return str.substring(0,1) 
    }
    if(str.length > len + point_index + 1){
        return str.substring(0,len + point_index + 1)
    }
    return str
}
const str2date = (str,separater='-') => {
    if(str === '' || !str || str.length<8) {
        return ''
    }

    return str.substring(0,4) + separater + str.substring(4,6) + separater + str.substring(6,8)

}
export default {
    desensitizing,
    substring,
    isDefine,
    round,
    desensitizing2,
    str2date
}

 以上准备工作完成之后,需要引用一下支付宝小程序的ui组件,我用的是mini-ali-ui。

 这下终于可以开发愉快地写页面了吧。此时此刻你在想什么呢。

作为一个经常使用mac、linux系统的程序猿,想借助于开发工具中的控制台进行页面创建,怎么办呢?

这时候要用到node的功能了,在根目录下添加package.json

代码语言:javascript
复制
{
  "dependencies": {
    "iconv-lite": "^0.6.3"
  },
  "scripts": {
    "page": "node scripts/page"
  }
}

 然后在根目录添加scripts目录,在scripts目录中添加page.js

示例代码如下:此程序仅支持 “pages/分组名称/页面名称”这种结构的页面创建,若需要减小层级或增加层级自行修改哈。

代码语言:javascript
复制
/**
 * pages页面快速生成脚本 
 * 用法:npm run tep `文件名`
 * npm run page product/ProductClass
 */

const fs = require('fs');
var iconv = require('iconv-lite');

const dirName = process.argv[2];
const cover = process.argv[3];
console.log(dirName)
const dirNameArr = dirName.split('/')
const folder = dirNameArr[0]
const fileName = dirNameArr[1]
const capPirName = dirName.substring(0, 1).toUpperCase() + dirName.substring(1);
console.log(folder, fileName, capPirName, __dirname)
if (!dirName) {
    console.log('文件夹名称不能为空!');
    console.log('示例:npm run page product/ProductClas');
    process.exit(0);
}

var curPath = __dirname.substring(0, __dirname.lastIndexOf('/'))
console.log('curPath==', curPath)

function loadjson(filepath) {
    var data;
    try {
        var jsondata = iconv.decode(fs.readFileSync(curPath + '/' + filepath, "binary"), "utf8");
        data = JSON.parse(jsondata);
    }
    catch (err) {
        console.log(err);
    }

    return data;
}


function savejson(filepath, data) {
    var datastr = JSON.stringify(data, null, 4);

    if (datastr) {
        try {
            fs.writeFileSync(curPath + '/' + filepath, datastr);
        }
        catch (err) {

        }
    }
}

//model模板

const wxmlTemp = `
    <view>
    </view>
`
const jsTemp = `
import tools from '/utils/tools'
import { getJSON } from '/utils/http'
import apis from '/utils/apis'
const app = getApp()
Page({

    data: {

    },

    onLoad: function (options) {
        tools.curPagePath(options)
    },

    onShow: function () {

    },
    go2page(e){
        tools.go2page(e)
    }
})
`
const wxssTemp = `

`
const jsonTemp = `
{
    "usingComponents": {}
}
`
if (!fs.existsSync(`pages/${folder}`)) {
    fs.mkdirSync(`pages/${folder}`)
}

if (!fs.existsSync(`pages/${folder}/${fileName}`)) {
    fs.mkdirSync(`pages/${folder}/${fileName}`)
} else {
    // 如果文件夹存在则说明页面已创建,不能再操作了,否则会覆盖已有页面
    if (cover && cover != 1) {
        process.exit(0);
    }
}

process.chdir(`pages/${folder}/${fileName}`); // cd $1


fs.writeFileSync(`${fileName}.axml`, wxmlTemp)
fs.writeFileSync(`${fileName}.json`, jsonTemp)
fs.writeFileSync(`${fileName}.acss`, wxssTemp)
fs.writeFileSync(`${fileName}.js`, jsTemp)

var jsonPath = 'app.json'
var appJson = loadjson(jsonPath)
if (appJson) {
    var pages = appJson.pages
    if (pages.indexOf(`pages/${folder}/${fileName}/${fileName}`) == -1) {
        pages.push(`pages/${folder}/${fileName}/${fileName}`)
    }

    savejson(jsonPath, appJson)


}

process.exit(0);

本文系转载,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文系转载前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云开发 CloudBase
云开发(Tencent CloudBase,TCB)是腾讯云提供的云原生一体化开发环境和工具平台,为200万+企业和开发者提供高可用、自动弹性扩缩的后端云服务,可用于云端一体化开发多种端应用(小程序、公众号、Web 应用等),避免了应用开发过程中繁琐的服务器搭建及运维,开发者可以专注于业务逻辑的实现,开发门槛更低,效率更高。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档