HBuilderX

HBuilderX

极客开发工具
uni-app

uni-app

开发一次,多端覆盖
uniCloud

uniCloud

云开发平台
HTML5+

HTML5+

增强HTML5的功能体验
MUI

MUI

上万Star的前端框架

tabar的实现,从他们官网拿下来的,精简得很

tab

新建一个uni_app,把下面的代码复制到pages.json文件里去就可以用了

{
"pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
{
"path": "pages/index/index",
"style": {
"navigationBarTitleText": "uni-app"
}
}
],
"globalStyle": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "uni-app",
"navigationBarBackgroundColor": "#F8F8F8",
"backgroundColor": "#F8F8F8"
},
"tabBar": {
"borderStyle": "black",
"backgroundColor": "#333",
"color": "#8F8F94",
"selectedColor": "#f33e54",
"list": [{
"pagePath": "pages/index/index",
"iconPath": "static/img/tabbar/home.png",
"selectedIconPath": "static/img/tabbar/homeactive.png",
"text": "首页"
},
{
"pagePath": "pages/index/index",
"iconPath": "static/img/tabbar/guanzhu.png",
"selectedIconPath": "static/img/tabbar/guanzhuactive.png",
"text": "关注"
},
//#ifdef MP-WEIXIN
{
"pagePath": "pages/index/index",
"iconPath": "static/img/tabbar/add.png",
"selectedIconPath": "static/img/tabbar/addactive.png",
"text": "发布"
},
//#endif
//#ifndef MP-WEIXIN
{
"pagePath": "pages/index/index",
"iconPath": "static/img/tabbar/add.png",
"selectedIconPath": "static/img/tabbar/addactive.png"
},
//#endif
{
"pagePath": "pages/index/index",
"iconPath": "static/img/tabbar/news.png",
"selectedIconPath": "static/img/tabbar/newsactive.png",
"text": "消息"
},
{
"pagePath": "pages/index/index",
"iconPath": "static/img/tabbar/me.png",
"selectedIconPath": "static/img/tabbar/meactive.png",
"text": "我"
}
]
}
}

继续阅读 »

新建一个uni_app,把下面的代码复制到pages.json文件里去就可以用了

{
"pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
{
"path": "pages/index/index",
"style": {
"navigationBarTitleText": "uni-app"
}
}
],
"globalStyle": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "uni-app",
"navigationBarBackgroundColor": "#F8F8F8",
"backgroundColor": "#F8F8F8"
},
"tabBar": {
"borderStyle": "black",
"backgroundColor": "#333",
"color": "#8F8F94",
"selectedColor": "#f33e54",
"list": [{
"pagePath": "pages/index/index",
"iconPath": "static/img/tabbar/home.png",
"selectedIconPath": "static/img/tabbar/homeactive.png",
"text": "首页"
},
{
"pagePath": "pages/index/index",
"iconPath": "static/img/tabbar/guanzhu.png",
"selectedIconPath": "static/img/tabbar/guanzhuactive.png",
"text": "关注"
},
//#ifdef MP-WEIXIN
{
"pagePath": "pages/index/index",
"iconPath": "static/img/tabbar/add.png",
"selectedIconPath": "static/img/tabbar/addactive.png",
"text": "发布"
},
//#endif
//#ifndef MP-WEIXIN
{
"pagePath": "pages/index/index",
"iconPath": "static/img/tabbar/add.png",
"selectedIconPath": "static/img/tabbar/addactive.png"
},
//#endif
{
"pagePath": "pages/index/index",
"iconPath": "static/img/tabbar/news.png",
"selectedIconPath": "static/img/tabbar/newsactive.png",
"text": "消息"
},
{
"pagePath": "pages/index/index",
"iconPath": "static/img/tabbar/me.png",
"selectedIconPath": "static/img/tabbar/meactive.png",
"text": "我"
}
]
}
}

收起阅读 »

力谱云V3.3新发布,会员推荐机制新优化,助力电商软件开发

5+App开发

力谱云V3.3新发布,会员推荐机制新优化,助力电商软件开发

力谱云V3.3已正式上线!在本期版本中,电商软件开发平台——力谱云将围绕会员等级、会员推荐店铺入驻机制、BBC商城管理、商品管理等方面进行功能提升!共计7大功能更新,并4处细节优化!详情如下:

力谱云V3.3新发布,会员推荐机制新优化,助力电商软件开发

> 会员优化
功能描述:会员自动升级逻辑,新增“或”选项!让您的会员等级管理,更富人性化!

力谱云会员自动升级

商品返利优化
功能描述:商品返利支持黑名单!通过商品组功能,把不同“类” 的商品整合到一个商品组,在针对该商品组进行单独的分销(或返利)比例设置。
场景:平台有普通商品和一些急需处理的商品。急需处理的商品本身已让利客户,为了不把分销利润再分割出去,就可以把这些急需处理的商品整合到“急需处理”商品组,再针对该商品组进行分销设置,该商品组的分销比例就可以稍稍设置低一些。
设置商品组:


设置具体的分销/返利比例:


会员推荐机制优化
功能描述:会员推荐BBC店铺成功入驻,可获得该店铺的营业额提成。
1 创建推荐关系:
同时需要选择,该会员是否能永久获得提成
1 入驻推荐人:入驻推荐收益期限仅一次,则不允许修改和删除
2 入驻推荐人:入驻推荐收益期限为始终,则允许修改和删除

2 BBC店铺管理,增加子菜单,支持查看会员推荐店铺的具体情况

3 APP端申请入驻,支持推荐码输入

BBC平台管理优化
功能描述:BBC平台管理,支持设置店铺可上传的商品分类,以此对店铺方加以把控,防止餐饮店铺贩卖服装等运营场景。

商品分类组件优化
功能描述:商品分类组件,支持更多排版!

店铺分类界面优化
功能描述:店铺分类界面,新增平铺模式。

收银台消费优化
功能描述:BC和BBC商城支持,在收银台订单中,使用余额、第三方均可产生消费奖励。注意设置获得比例,如没有设置特殊的返还比例,则会使用统一的默认比例。

细节优化
1 移动端商品详情页,支持上下滑动切换tab——商品、评价、详情;预订底部按钮,UI新调整
2 海外预订项目详情,不显示项目位置
3 预付卡充值记录和导出记录,新增会员ID和手机号
4 由实时解冻改为定时任务去解冻
1 )冻结操作不可逆
2 )每天00:30执行解冻任务,对前一天达到解冻标准的款项执行解冻操作

最后,感谢各位新老用户对力谱云平台的鼎力支持!电商软件开发平台——力谱云,支持社交电商、社区团购、服务预订、B2B订货等多种商业场景,并可助力企业高效打造原生iOS App、安卓App、小程序、微商城及移动网站等。企业只需通过力谱云,即可轻松越过移动技术壁垒,快速、低成本抢占移动蓝海红利!
力谱云,让您的移动电商平台,更富前沿营销力!

继续阅读 »

力谱云V3.3新发布,会员推荐机制新优化,助力电商软件开发

力谱云V3.3已正式上线!在本期版本中,电商软件开发平台——力谱云将围绕会员等级、会员推荐店铺入驻机制、BBC商城管理、商品管理等方面进行功能提升!共计7大功能更新,并4处细节优化!详情如下:

力谱云V3.3新发布,会员推荐机制新优化,助力电商软件开发

> 会员优化
功能描述:会员自动升级逻辑,新增“或”选项!让您的会员等级管理,更富人性化!

力谱云会员自动升级

商品返利优化
功能描述:商品返利支持黑名单!通过商品组功能,把不同“类” 的商品整合到一个商品组,在针对该商品组进行单独的分销(或返利)比例设置。
场景:平台有普通商品和一些急需处理的商品。急需处理的商品本身已让利客户,为了不把分销利润再分割出去,就可以把这些急需处理的商品整合到“急需处理”商品组,再针对该商品组进行分销设置,该商品组的分销比例就可以稍稍设置低一些。
设置商品组:


设置具体的分销/返利比例:


会员推荐机制优化
功能描述:会员推荐BBC店铺成功入驻,可获得该店铺的营业额提成。
1 创建推荐关系:
同时需要选择,该会员是否能永久获得提成
1 入驻推荐人:入驻推荐收益期限仅一次,则不允许修改和删除
2 入驻推荐人:入驻推荐收益期限为始终,则允许修改和删除

2 BBC店铺管理,增加子菜单,支持查看会员推荐店铺的具体情况

3 APP端申请入驻,支持推荐码输入

BBC平台管理优化
功能描述:BBC平台管理,支持设置店铺可上传的商品分类,以此对店铺方加以把控,防止餐饮店铺贩卖服装等运营场景。

商品分类组件优化
功能描述:商品分类组件,支持更多排版!

店铺分类界面优化
功能描述:店铺分类界面,新增平铺模式。

收银台消费优化
功能描述:BC和BBC商城支持,在收银台订单中,使用余额、第三方均可产生消费奖励。注意设置获得比例,如没有设置特殊的返还比例,则会使用统一的默认比例。

细节优化
1 移动端商品详情页,支持上下滑动切换tab——商品、评价、详情;预订底部按钮,UI新调整
2 海外预订项目详情,不显示项目位置
3 预付卡充值记录和导出记录,新增会员ID和手机号
4 由实时解冻改为定时任务去解冻
1 )冻结操作不可逆
2 )每天00:30执行解冻任务,对前一天达到解冻标准的款项执行解冻操作

最后,感谢各位新老用户对力谱云平台的鼎力支持!电商软件开发平台——力谱云,支持社交电商、社区团购、服务预订、B2B订货等多种商业场景,并可助力企业高效打造原生iOS App、安卓App、小程序、微商城及移动网站等。企业只需通过力谱云,即可轻松越过移动技术壁垒,快速、低成本抢占移动蓝海红利!
力谱云,让您的移动电商平台,更富前沿营销力!

收起阅读 »

抓住三四线城市人口红利,在力谱云制作专属电商APP

5+App开发

纵观2018年,是拼多多等社交电商App彻底崛起的日子,他们的成功,很大一部分原因归根于对三四五线城市人口红利的深挖。力谱云,作为致力于开发移动电商APP制作的云平台,在开发APP的过程中也在推陈出新,时刻关注着有助于APP开发拉新的亮点,下面就为各位揭秘一下想要抄底三四线城市人口红利,专属开发制作APP时,可以关注的几个指南!

力谱云开发新零售电商app

> 当新零售碰撞社交App开发,吸金指数势不可挡

随着手机业务的全面性覆盖,在未来的日子中,相信无论是下至幼儿,或是上至中老年,都将通过一部小巧精致的手机,联系整个世界。传统零售企业面对这样的市场冲击,也早早开创了自己转型升级的新商业模式——新零售。所谓新,除了借助一定的移动技术手段,其实更多的是新思路、新商业模式、新流量渠道的创新。目前,电商行业已经为逐渐走向成熟的新零售行业,提供了充分的养料土场。力谱云了解到,想要充分收割一波三四五线城市人口红利,想必开发一款新零售+电商App的商业模式,将深受接下来各路乡县企业家的青睐。目前,通过力谱云平台上线的新零售解决方案中,行业多种多样,有商超类、生鲜电商类、服装大卖场等等。

> 当同城服务入驻三四五线城市,赚钱将指日可待

随着人们消费水平的提升,许多传统三四五线城市的消费主力人口,对服务水平的需求正在逐日提升。特别是小镇青年们,除了喜欢通过手机APP观看短视频、游戏直播、手游、阅读新媒体之外,他们在生活中,也倾向于通过手机APP,点外卖、购买电影劵、预约餐饮娱乐场所、上门服务等等。目前,力谱云所推出的互联网生活服务移动APP解决方案,支持类似的58到家模式,可以让小地方的企业家也能快速、高性价比地打造出一款可以为用户提供专业、便捷、安心的标准化到家服务。
>
力谱云:开发一个电商App,就这么简单、低成本、高效

目前的主流App开发方向,除了以上两点之外,更重要的是社交+电商的活学活用。何为社交?通过微信等渠道进行低成本的客源获取。在这个基础之上,社交电商App,可以为企业注入无限量的线上流量红利。目前,力谱云从小红书、云集微店、拼多多、松鼠拼拼等各类社交电商App平台中的佼佼者身上,总结了一系列社交分销、社区团购的移动电商解决方案。如果你的企业正身处三四线城市,如果你的模式仍旧守旧,如果你的事业亟待突破,那么就来选择力谱云吧!

力谱云简单、低成本、高效开发制作电商App

力谱云,支持App+小程序+微商城+移动网站等多平台开发制作,从研发到运营、销售,企业所需技术支持,全程护航。只需一位会电脑的运营小白,即可轻松上手App制作运营,并有团队专业培训带领。选择力谱云,让你2019年的事业快快起飞吧!

继续阅读 »

纵观2018年,是拼多多等社交电商App彻底崛起的日子,他们的成功,很大一部分原因归根于对三四五线城市人口红利的深挖。力谱云,作为致力于开发移动电商APP制作的云平台,在开发APP的过程中也在推陈出新,时刻关注着有助于APP开发拉新的亮点,下面就为各位揭秘一下想要抄底三四线城市人口红利,专属开发制作APP时,可以关注的几个指南!

力谱云开发新零售电商app

> 当新零售碰撞社交App开发,吸金指数势不可挡

随着手机业务的全面性覆盖,在未来的日子中,相信无论是下至幼儿,或是上至中老年,都将通过一部小巧精致的手机,联系整个世界。传统零售企业面对这样的市场冲击,也早早开创了自己转型升级的新商业模式——新零售。所谓新,除了借助一定的移动技术手段,其实更多的是新思路、新商业模式、新流量渠道的创新。目前,电商行业已经为逐渐走向成熟的新零售行业,提供了充分的养料土场。力谱云了解到,想要充分收割一波三四五线城市人口红利,想必开发一款新零售+电商App的商业模式,将深受接下来各路乡县企业家的青睐。目前,通过力谱云平台上线的新零售解决方案中,行业多种多样,有商超类、生鲜电商类、服装大卖场等等。

> 当同城服务入驻三四五线城市,赚钱将指日可待

随着人们消费水平的提升,许多传统三四五线城市的消费主力人口,对服务水平的需求正在逐日提升。特别是小镇青年们,除了喜欢通过手机APP观看短视频、游戏直播、手游、阅读新媒体之外,他们在生活中,也倾向于通过手机APP,点外卖、购买电影劵、预约餐饮娱乐场所、上门服务等等。目前,力谱云所推出的互联网生活服务移动APP解决方案,支持类似的58到家模式,可以让小地方的企业家也能快速、高性价比地打造出一款可以为用户提供专业、便捷、安心的标准化到家服务。
>
力谱云:开发一个电商App,就这么简单、低成本、高效

目前的主流App开发方向,除了以上两点之外,更重要的是社交+电商的活学活用。何为社交?通过微信等渠道进行低成本的客源获取。在这个基础之上,社交电商App,可以为企业注入无限量的线上流量红利。目前,力谱云从小红书、云集微店、拼多多、松鼠拼拼等各类社交电商App平台中的佼佼者身上,总结了一系列社交分销、社区团购的移动电商解决方案。如果你的企业正身处三四线城市,如果你的模式仍旧守旧,如果你的事业亟待突破,那么就来选择力谱云吧!

力谱云简单、低成本、高效开发制作电商App

力谱云,支持App+小程序+微商城+移动网站等多平台开发制作,从研发到运营、销售,企业所需技术支持,全程护航。只需一位会电脑的运营小白,即可轻松上手App制作运营,并有团队专业培训带领。选择力谱云,让你2019年的事业快快起飞吧!

收起阅读 »

微信公众号H5,实现微信支付

微信支付

最近看到有朋友问公众号内怎么实现微信支付和登陆,正好前些时候有做过,其实和普通H5网站实现是差不多的。今天有空,暂时先写下支付流程。

前提

  1. 已经申请成为微信商户
  2. 开通JSAPI支付

支付需要对接两个API

  1. 服务端,调用统一下单API,获得prepay_id 。官方文档 https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_1
  2. 客户端(即H5),调用微信JS ,唤起微信支付。 官方文档 https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_7&index=6
  3. 不建议使用JSSDK,示例代码:
export default {  
    isWechat:function(){  
        var ua = window.navigator.userAgent.toLowerCase();  
        if(ua.match(/micromessenger/i) == 'micromessenger'){  
            return true;  
        }else{  
            return false;  
        }  
    },  
    jsApiCall(data ,callback_succ_func ,callback_error_func){  
        //使用原生的,避免初始化appid问题  
        WeixinJSBridge.invoke('getBrandWCPayRequest', {  
            appId:data['appId'],  
            timeStamp: data['timeStamp'],  
            nonceStr: data['nonceStr'], // 支付签名随机串,不长于 32 位  
            package: data['package'], // 统一支付接口返回的prepay_id参数值,提交格式如:prepay_id=\*\*\*)  
            signType: data['signType'], // 签名方式,默认为'SHA1',使用新版支付需传入'MD5'  
            paySign: data['paySign'], // 支付签名  
        },  
        function(res) {  
            var msg = res.err_msg ?res.err_msg :res.errMsg;  
            //WeixinJSBridge.log(msg);  
            switch (msg) {  
                case 'get_brand_wcpay_request:ok': //支付成功时  
                    if(callback_succ_func){  
                        callback_succ_func(res);  
                    }  
                    break;  
                default: //支付失败时  
                    WeixinJSBridge.log('支付失败!'+msg+',请返回重试.');  
                    if(callback_error_func){  
                        callback_error_func({msg:msg});  
                    }  
                    break;  
            }  
        })  
    },  
    payment:function(data ,callback_succ_func ,callback_error_func){  
        if(!this.isWechat()){  
            return ;  
        }  
        if (typeof WeixinJSBridge == "undefined") {  
            if (document.addEventListener) {  
                document.addEventListener('WeixinJSBridgeReady', this.jsApiCall, false);  
            } else if (document.attachEvent) {  
                document.attachEvent('WeixinJSBridgeReady', this.jsApiCall);  
                document.attachEvent('onWeixinJSBridgeReady', this.jsApiCall);  
            }  
        } else {  
            this.jsApiCall(data ,callback_succ_func ,callback_error_func);  
        }  
    }  
}

在发起支付的页面,调用payment方法 。data参数需要从服务端获取。

继续阅读 »

最近看到有朋友问公众号内怎么实现微信支付和登陆,正好前些时候有做过,其实和普通H5网站实现是差不多的。今天有空,暂时先写下支付流程。

前提

  1. 已经申请成为微信商户
  2. 开通JSAPI支付

支付需要对接两个API

  1. 服务端,调用统一下单API,获得prepay_id 。官方文档 https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_1
  2. 客户端(即H5),调用微信JS ,唤起微信支付。 官方文档 https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_7&index=6
  3. 不建议使用JSSDK,示例代码:
export default {  
    isWechat:function(){  
        var ua = window.navigator.userAgent.toLowerCase();  
        if(ua.match(/micromessenger/i) == 'micromessenger'){  
            return true;  
        }else{  
            return false;  
        }  
    },  
    jsApiCall(data ,callback_succ_func ,callback_error_func){  
        //使用原生的,避免初始化appid问题  
        WeixinJSBridge.invoke('getBrandWCPayRequest', {  
            appId:data['appId'],  
            timeStamp: data['timeStamp'],  
            nonceStr: data['nonceStr'], // 支付签名随机串,不长于 32 位  
            package: data['package'], // 统一支付接口返回的prepay_id参数值,提交格式如:prepay_id=\*\*\*)  
            signType: data['signType'], // 签名方式,默认为'SHA1',使用新版支付需传入'MD5'  
            paySign: data['paySign'], // 支付签名  
        },  
        function(res) {  
            var msg = res.err_msg ?res.err_msg :res.errMsg;  
            //WeixinJSBridge.log(msg);  
            switch (msg) {  
                case 'get_brand_wcpay_request:ok': //支付成功时  
                    if(callback_succ_func){  
                        callback_succ_func(res);  
                    }  
                    break;  
                default: //支付失败时  
                    WeixinJSBridge.log('支付失败!'+msg+',请返回重试.');  
                    if(callback_error_func){  
                        callback_error_func({msg:msg});  
                    }  
                    break;  
            }  
        })  
    },  
    payment:function(data ,callback_succ_func ,callback_error_func){  
        if(!this.isWechat()){  
            return ;  
        }  
        if (typeof WeixinJSBridge == "undefined") {  
            if (document.addEventListener) {  
                document.addEventListener('WeixinJSBridgeReady', this.jsApiCall, false);  
            } else if (document.attachEvent) {  
                document.attachEvent('WeixinJSBridgeReady', this.jsApiCall);  
                document.attachEvent('onWeixinJSBridgeReady', this.jsApiCall);  
            }  
        } else {  
            this.jsApiCall(data ,callback_succ_func ,callback_error_func);  
        }  
    }  
}

在发起支付的页面,调用payment方法 。data参数需要从服务端获取。

收起阅读 »

解决PC端访问时,页面字体过大导致页面十分丑的问题

解决方案很简单,设置下window.innerWidth。
在自定义的h5 template文件head中,加入下面代码。

<script>  
if(window.innerWidth>750){  
    window.innerWidth=750;  
}  
</script>

当然了,这里的750可以自行根据情况调整。

注意,如果某些地方的样式,如果使用了750upx来作为自适应宽度,需要调整成100%。

有更好解决方案的,也希望大家分享下哦。

继续阅读 »

解决方案很简单,设置下window.innerWidth。
在自定义的h5 template文件head中,加入下面代码。

<script>  
if(window.innerWidth>750){  
    window.innerWidth=750;  
}  
</script>

当然了,这里的750可以自行根据情况调整。

注意,如果某些地方的样式,如果使用了750upx来作为自适应宽度,需要调整成100%。

有更好解决方案的,也希望大家分享下哦。

收起阅读 »

关于阿里百川得一些见解

http://ext.dcloud.net.cn/plugin?id=359

http://ext.dcloud.net.cn/plugin?id=359

HbuilderX占有资源算严重吗?

HBuilderX

在使用HbuilderX过程中,经常崩溃,而且占内存452MB,算是很严重吗?

在使用HbuilderX过程中,经常崩溃,而且占内存452MB,算是很严重吗?

【解决方式】当前环境无法运行启用“自定义组件模式”的uni-app应用问题

自定义组件模式

出现无法运行启用自定义组件模式的错误,可以把manifest.json里的"usingComponents": true,这个去掉就行了

出现无法运行启用自定义组件模式的错误,可以把manifest.json里的"usingComponents": true,这个去掉就行了

mui框架写的金融行业app模板

App mui

用mui框架写的一款简单的金融行业app模板,有一些比较基本的页面,新手可以学习研究

模板下载:https://www.sucaihuo.com/templates/503.html

继续阅读 »

用mui框架写的一款简单的金融行业app模板,有一些比较基本的页面,新手可以学习研究

模板下载:https://www.sucaihuo.com/templates/503.html

收起阅读 »

HBuilderX打开文件标签卡与左侧项目管理器的关联定位策略说明

自动关联

右侧打开的标签卡,切换时,左侧项目管理器是否自动定位和展开目录?这个习惯不同人不一样。

HBuilderX提供了3种策略,供用户选择。

如上图,在项目管理器右上角,点开悬浮菜单-与编辑器同步,里面有3个选项。

  • 单项目时自动关联:就是左侧只有一个项目时,自动关联定位
  • 从不关联:不管右侧如何切换,项目管理器都不会跟随变化。此时可以在编辑器区域点右键,选“在项目管理器中定位”
  • 总是关联:右侧标签卡一旦切换,左侧项目管理器自动关联定位

在HBuilderX 1.9.3及以下,默认策略是“总是关联”。但项目一多,左侧长长的树让很多开发者烦恼。

从HBuilderX 1.9.4起,默认策略调整为“单项目时自动关联”,如果有多个项目,默认不再自动关联。开发者可以调整这个策略,也可以点右键定位。

继续阅读 »

右侧打开的标签卡,切换时,左侧项目管理器是否自动定位和展开目录?这个习惯不同人不一样。

HBuilderX提供了3种策略,供用户选择。

如上图,在项目管理器右上角,点开悬浮菜单-与编辑器同步,里面有3个选项。

  • 单项目时自动关联:就是左侧只有一个项目时,自动关联定位
  • 从不关联:不管右侧如何切换,项目管理器都不会跟随变化。此时可以在编辑器区域点右键,选“在项目管理器中定位”
  • 总是关联:右侧标签卡一旦切换,左侧项目管理器自动关联定位

在HBuilderX 1.9.3及以下,默认策略是“总是关联”。但项目一多,左侧长长的树让很多开发者烦恼。

从HBuilderX 1.9.4起,默认策略调整为“单项目时自动关联”,如果有多个项目,默认不再自动关联。开发者可以调整这个策略,也可以点右键定位。

收起阅读 »

消息 推送:uni-app开发之unipush推送踩坑填坑之旅

推送 推送插件配置指南 unipush

最近需要开发app,经过多方对比,最终选择了使用dcloud的uni-app,一套代码可以编译七个平台,最主要就是相比于apicloud来说支持本地打包,减少了很多可能会带来的限制。
也就想着,它最大的诟病是说社区不活跃,可是社区氛围也是需要大家一块积极贡献的,那么我们团队加进来也给他增加一点活跃度。

做app免不了会需要推送,从服务器主动给客户端发信息联系,这是客户端app相对来说非常大的一个优势。

刚刚把uni-app在安卓端的推送走通,此处记录一下经验以方便后来者参考。

1. 开通UniPush推送服务

UniPush仅支持uni-app类型项目,其它类型项目暂不支持
点此查看如何开通UniPush推送服务

在Hbuilder中修改mainfest.json文件配置

勾选DCloud UniPush,然后点击配置按钮会进入uniPush的后端配置,需要先认证,认证通过后,可以在我创建的应用列表中查看自己当前的应用。如果有多个项目,此处可以根据列表中的App_id和本地的appid关联查看
https://dev.dcloud.net.cn/#/pages/app/list


点击当前项目,进入对应项目的管理页面,选择上方uniPush选项,点击厂商推送设置,填写自己想要指定的包名及根据本地证书生成的签名信息(如果要使用官方的证书,那就按提示填写官方签名信息)

配置完可进入uniPush的“通知消息”测试页面

自定义基座

要想实现推送功能,需要先自定义基座(因为推送也是需要依赖包名等信息的,官方说过,推送必须要用自定义基座才行)


选择自定义基座,然后会有弹窗提示

这里可以选择使用公用证书,也可以使用自己之前已经生成的自有证书签名,填写必要的信息,然后选择打包;此处要注意这里填写的包名要和上面unipush管理页面中配置的一样。

填写完成后,点击打包按钮,等待。完成后会在控制台提示

我们按照提示,选择自己之前定义的基座即可。这个时候再点击运行到手机或模拟器,然后在后台测试推送即可

测试推送

进入unipush推送通知的页面创建推送,填写通知标题和通知内容,此处如果有客户端之前运行成功,那么预计人数会不是0人,如果是0人的话确定按钮会无法点击,因为无人可推;即使在目标选择中根据客户端输出的clientid选择了特定用户,手机端也是无法推送的。此处如果不行,就再去检查包名配置和基座选择是否有问题。

因为这个系统就是个推给dcloud的私有部署,所以如果有疑问的方面也可以到个推官方注册一个账号,下载demo试试,增加一点成就感。并且后续的开发sdk、文档等都可以根据个推的做。

服务端推送快速入门

我们在本地建一个maven项目,在pom.xml的dependencies中增加一个推送sdk的依赖包配置

<dependency>  
    <groupId>com.gexin.platform</groupId>  
    <artifactId>gexin-rp-sdk-http</artifactId>  
    <version>4.1.0.1</version>  
</dependency>

如果下载有问题,可以在project的下层添加一个库位置

<repositories>  
    <repository>  
        <id>getui-nexus</id>  
        <url>http://mvn.gt.igexin.com/nexus/content/repositories/releases/</url>  
    </repository>  
 </repositories>

然后建测试类如下,把其中的appid、appkey、masterSecret换成自己的,url不用换;
经过测试推测,虽然在unipush中有私有部署系统,但是推送的消息队列还是在个推云。大概是OEM

import com.gexin.rp.sdk.base.IPushResult;  
import com.gexin.rp.sdk.base.impl.AppMessage;  
import com.gexin.rp.sdk.http.IGtPush;  
import com.gexin.rp.sdk.template.LinkTemplate;  

import java.io.IOException;  
import java.util.ArrayList;  
import java.util.List;  

public class AppPush {  

    //定义常量, appId、appKey、masterSecret 采用本文档 "第二步 获取访问凭证 "中获得的应用配置  
    private static String appId = "你的appid";  
    private static String appKey = "你的appkey";  
    private static String masterSecret = "你的masterSecret";  
    private static String url = "http://sdk.open.api.igexin.com/apiex.htm";  

    public static void main(String[] args) throws IOException {  

        IGtPush push = new IGtPush(url, appKey, masterSecret);  

        // 定义"点击链接打开通知模板",并设置标题、内容、链接  
        LinkTemplate template = new LinkTemplate();  
        template.setAppId(appId);  
        template.setAppkey(appKey);  
        template.setTitle("你好你好");  
        template.setText("哦,好吧");  
        template.setUrl("http://getui.com");  

        List<String> appIds = new ArrayList<String>();  
        appIds.add(appId);  

        // 定义"AppMessage"类型消息对象,设置消息内容模板、发送的目标App列表、是否支持离线发送、以及离线消息有效期(单位毫秒)  
        AppMessage message = new AppMessage();  
        message.setData(template);  
        message.setAppIdList(appIds);  
        message.setOffline(true);  
        message.setOfflineExpireTime(1000 * 600);  

        IPushResult ret = push.pushMessageToApp(message);  
        System.out.println(ret.getResponse().toString());  
    }  
}

透传消息

考虑到推送通知只在android端可以使用,为了以后ios推送少改,所以此处我们也使用透传消息推送;又知透传消息的格式当满足

t.setTransmissionContent("{title:\"标题\",content:\"内容\",payload:\"自定义数据\"}");

时,会在安卓端自动转为通知消息,所以我们此处就按这种方式推送透传消息。
其中payload的值既可以是字符串,又可以是对象;这里的示例数据我写的是字符串,但实际使用时可以修改格式来符合自身业务逻辑的处理,比如

{title:"标题",content:"内容",payload:{type:1,fId:1}}

对于代码的修改主要是要改动消息模板,即将上面的LinkTemplate改成TransmissionTemplate,
代码如下:

public static void main(String[] args) throws IOException {  

        IGtPush push = new IGtPush(url, appKey, masterSecret);  

        TransmissionTemplate t = new TransmissionTemplate();  
        t.setAppId(appId);  
        t.setAppkey(appKey);  
        t.setTransmissionContent("{title:\"标题\",content:\"内容\",payload:\"自定义数据\"}");  
        t.setTransmissionType(1);  

        // 定义"点击链接打开通知模板",并设置标题、内容、链接  
//        LinkTemplate template = new LinkTemplate();  
//        template.setAppId(appId);  
//        template.setAppkey(appKey);  
//        template.setTitle("你好你好");  
//        template.setText("哦,好吧");  
//        template.setLogoUrl("");  
//        template.setUrl("http://getui.com");  

        List<String> appIds = new ArrayList<String>();  
        appIds.add(appId);  

        // 定义"AppMessage"类型消息对象,设置消息内容模板、发送的目标App列表、是否支持离线发送、以及离线消息有效期(单位毫秒)  
        AppMessage message = new AppMessage();  
        message.setData(t);  
        message.setAppIdList(appIds);  
        message.setOffline(true);  
        message.setOfflineExpireTime(1000 * 600);  

        IPushResult ret = push.pushMessageToApp(message);  
        System.out.println(ret.getResponse().toString());  
}

怎么监听通知点击事件

注意条件编译

// #ifdef APP-PLUS  
            // #ifdef APP-PLUS  
            plus.push.addEventListener('click', function(msg) {  
                console.log(JSON.stringify(msg.payload.fId))  
                switch (msg.payload.type) {  
                    case 1:  
                        uni.navigateTo({  
                            url: '/pages/listDetail/alarmDetail?id=' + msg.payload.fId,  
                            success: res => {},  
                            fail: () => {},  
                            complete: () => {}  
                        });  
                        break;  
                    case 2:  
                        uni.navigateTo({  
                            url: '/pages/workStation/inspection/deal/deal?inspectId=' + msg.payload.fId  
                        })  
                        break;  
                    case 3:  
                        uni.navigateTo({  
                            url: '/pages/listDetail/orderDetail?oid=' + msg.payload.fId,  
                            success: res => {},  
                            fail: () => {},  
                        })  
                        break;  
                    case 4:  
                        uni.navigateTo({  
                            url: '/pages/auth/check?authId=' + msg.payload.fId,  
                            success: res => {},  
                            fail: () => {},  
                        })  
                        break;  
                }  
            }, false);  

            //监听接收透传消息事件    
            plus.push.addEventListener('receive', function(msg) {  
                console.log(JSON.stringify(msg))  
                // plus.nativeUI.alert(msg)  
                //处理透传消息的业务逻辑代码    
            }, false);  
            // #endif

本地编译

作为专业的客户端开发人员,最好还是在本地有完整的编译环境。这也是我们在dcloud和apicloud之间选择当前技术栈的原因。

为了简单起见,可以把官方提供的实例项目HBuilder-Hello先在本地打包,然后用官方实例的壳,将里面h5的一些生成文件替换。此处操作流程如下:

  1. 生成本地打包App资源

  2. 将生成的资源放进实例项目app\src\main\assets\apps文件夹下,将之前的Hello H5删掉即可,
    然后将此路径下的dcloud_control.xml中的appid的值改为apps下一层即www上一层文件夹的名称

  • 此时已经可以打包成app并且正常打开,但是还不能推送 *
  1. 修改src/main/java文件夹下的包名为自己之前填写的包名,修改src/main下AndroidManifest.xml中package包名,修改AndroidManifest.xml中的推送参数配置

然后debug或打包即可。

问题解答

问:

  1. 请问服务端的代码还是只能用个推的吗,也就是说需要去个推开发者中心去注册账号拿到appid、appkey、masterSecret吗?那么使用uni-push的优势有什么呢?单纯使用个推也能完成推送功能
  2. 如果我想要给特定的某些/单个用户发消息,之前尝试了可以使用cid进行区别发送,我看你的教程里面没有使用cid,所以我想要知道在服务端代码上如何实现

答:

个推只是其中一个方案,你如果用jpush之类的,社区也有其他人做的教程;不过这个毕竟是dcloud官方给的推荐方案,所以没什么特殊情况,我们还是选用这个。

uni-push集成了个推,unipush的管理界面其实就是用的个推的系统,甚至据我推测,推送服务也是用的个推云。
不过不用取个推再注册,按unipush中的账号使用即可。

单个推送部分代码示例:

// 指定向哪儿推  
Target target = new Target();  
target.setAppId(appId);  
target.setClientId(cId);  

IGtPush push = new IGtPush(url, appKey, masterSecret);  
IPushResult ret = push.pushMessageToSingle(message, target);
继续阅读 »

最近需要开发app,经过多方对比,最终选择了使用dcloud的uni-app,一套代码可以编译七个平台,最主要就是相比于apicloud来说支持本地打包,减少了很多可能会带来的限制。
也就想着,它最大的诟病是说社区不活跃,可是社区氛围也是需要大家一块积极贡献的,那么我们团队加进来也给他增加一点活跃度。

做app免不了会需要推送,从服务器主动给客户端发信息联系,这是客户端app相对来说非常大的一个优势。

刚刚把uni-app在安卓端的推送走通,此处记录一下经验以方便后来者参考。

1. 开通UniPush推送服务

UniPush仅支持uni-app类型项目,其它类型项目暂不支持
点此查看如何开通UniPush推送服务

在Hbuilder中修改mainfest.json文件配置

勾选DCloud UniPush,然后点击配置按钮会进入uniPush的后端配置,需要先认证,认证通过后,可以在我创建的应用列表中查看自己当前的应用。如果有多个项目,此处可以根据列表中的App_id和本地的appid关联查看
https://dev.dcloud.net.cn/#/pages/app/list


点击当前项目,进入对应项目的管理页面,选择上方uniPush选项,点击厂商推送设置,填写自己想要指定的包名及根据本地证书生成的签名信息(如果要使用官方的证书,那就按提示填写官方签名信息)

配置完可进入uniPush的“通知消息”测试页面

自定义基座

要想实现推送功能,需要先自定义基座(因为推送也是需要依赖包名等信息的,官方说过,推送必须要用自定义基座才行)


选择自定义基座,然后会有弹窗提示

这里可以选择使用公用证书,也可以使用自己之前已经生成的自有证书签名,填写必要的信息,然后选择打包;此处要注意这里填写的包名要和上面unipush管理页面中配置的一样。

填写完成后,点击打包按钮,等待。完成后会在控制台提示

我们按照提示,选择自己之前定义的基座即可。这个时候再点击运行到手机或模拟器,然后在后台测试推送即可

测试推送

进入unipush推送通知的页面创建推送,填写通知标题和通知内容,此处如果有客户端之前运行成功,那么预计人数会不是0人,如果是0人的话确定按钮会无法点击,因为无人可推;即使在目标选择中根据客户端输出的clientid选择了特定用户,手机端也是无法推送的。此处如果不行,就再去检查包名配置和基座选择是否有问题。

因为这个系统就是个推给dcloud的私有部署,所以如果有疑问的方面也可以到个推官方注册一个账号,下载demo试试,增加一点成就感。并且后续的开发sdk、文档等都可以根据个推的做。

服务端推送快速入门

我们在本地建一个maven项目,在pom.xml的dependencies中增加一个推送sdk的依赖包配置

<dependency>  
    <groupId>com.gexin.platform</groupId>  
    <artifactId>gexin-rp-sdk-http</artifactId>  
    <version>4.1.0.1</version>  
</dependency>

如果下载有问题,可以在project的下层添加一个库位置

<repositories>  
    <repository>  
        <id>getui-nexus</id>  
        <url>http://mvn.gt.igexin.com/nexus/content/repositories/releases/</url>  
    </repository>  
 </repositories>

然后建测试类如下,把其中的appid、appkey、masterSecret换成自己的,url不用换;
经过测试推测,虽然在unipush中有私有部署系统,但是推送的消息队列还是在个推云。大概是OEM

import com.gexin.rp.sdk.base.IPushResult;  
import com.gexin.rp.sdk.base.impl.AppMessage;  
import com.gexin.rp.sdk.http.IGtPush;  
import com.gexin.rp.sdk.template.LinkTemplate;  

import java.io.IOException;  
import java.util.ArrayList;  
import java.util.List;  

public class AppPush {  

    //定义常量, appId、appKey、masterSecret 采用本文档 "第二步 获取访问凭证 "中获得的应用配置  
    private static String appId = "你的appid";  
    private static String appKey = "你的appkey";  
    private static String masterSecret = "你的masterSecret";  
    private static String url = "http://sdk.open.api.igexin.com/apiex.htm";  

    public static void main(String[] args) throws IOException {  

        IGtPush push = new IGtPush(url, appKey, masterSecret);  

        // 定义"点击链接打开通知模板",并设置标题、内容、链接  
        LinkTemplate template = new LinkTemplate();  
        template.setAppId(appId);  
        template.setAppkey(appKey);  
        template.setTitle("你好你好");  
        template.setText("哦,好吧");  
        template.setUrl("http://getui.com");  

        List<String> appIds = new ArrayList<String>();  
        appIds.add(appId);  

        // 定义"AppMessage"类型消息对象,设置消息内容模板、发送的目标App列表、是否支持离线发送、以及离线消息有效期(单位毫秒)  
        AppMessage message = new AppMessage();  
        message.setData(template);  
        message.setAppIdList(appIds);  
        message.setOffline(true);  
        message.setOfflineExpireTime(1000 * 600);  

        IPushResult ret = push.pushMessageToApp(message);  
        System.out.println(ret.getResponse().toString());  
    }  
}

透传消息

考虑到推送通知只在android端可以使用,为了以后ios推送少改,所以此处我们也使用透传消息推送;又知透传消息的格式当满足

t.setTransmissionContent("{title:\"标题\",content:\"内容\",payload:\"自定义数据\"}");

时,会在安卓端自动转为通知消息,所以我们此处就按这种方式推送透传消息。
其中payload的值既可以是字符串,又可以是对象;这里的示例数据我写的是字符串,但实际使用时可以修改格式来符合自身业务逻辑的处理,比如

{title:"标题",content:"内容",payload:{type:1,fId:1}}

对于代码的修改主要是要改动消息模板,即将上面的LinkTemplate改成TransmissionTemplate,
代码如下:

public static void main(String[] args) throws IOException {  

        IGtPush push = new IGtPush(url, appKey, masterSecret);  

        TransmissionTemplate t = new TransmissionTemplate();  
        t.setAppId(appId);  
        t.setAppkey(appKey);  
        t.setTransmissionContent("{title:\"标题\",content:\"内容\",payload:\"自定义数据\"}");  
        t.setTransmissionType(1);  

        // 定义"点击链接打开通知模板",并设置标题、内容、链接  
//        LinkTemplate template = new LinkTemplate();  
//        template.setAppId(appId);  
//        template.setAppkey(appKey);  
//        template.setTitle("你好你好");  
//        template.setText("哦,好吧");  
//        template.setLogoUrl("");  
//        template.setUrl("http://getui.com");  

        List<String> appIds = new ArrayList<String>();  
        appIds.add(appId);  

        // 定义"AppMessage"类型消息对象,设置消息内容模板、发送的目标App列表、是否支持离线发送、以及离线消息有效期(单位毫秒)  
        AppMessage message = new AppMessage();  
        message.setData(t);  
        message.setAppIdList(appIds);  
        message.setOffline(true);  
        message.setOfflineExpireTime(1000 * 600);  

        IPushResult ret = push.pushMessageToApp(message);  
        System.out.println(ret.getResponse().toString());  
}

怎么监听通知点击事件

注意条件编译

// #ifdef APP-PLUS  
            // #ifdef APP-PLUS  
            plus.push.addEventListener('click', function(msg) {  
                console.log(JSON.stringify(msg.payload.fId))  
                switch (msg.payload.type) {  
                    case 1:  
                        uni.navigateTo({  
                            url: '/pages/listDetail/alarmDetail?id=' + msg.payload.fId,  
                            success: res => {},  
                            fail: () => {},  
                            complete: () => {}  
                        });  
                        break;  
                    case 2:  
                        uni.navigateTo({  
                            url: '/pages/workStation/inspection/deal/deal?inspectId=' + msg.payload.fId  
                        })  
                        break;  
                    case 3:  
                        uni.navigateTo({  
                            url: '/pages/listDetail/orderDetail?oid=' + msg.payload.fId,  
                            success: res => {},  
                            fail: () => {},  
                        })  
                        break;  
                    case 4:  
                        uni.navigateTo({  
                            url: '/pages/auth/check?authId=' + msg.payload.fId,  
                            success: res => {},  
                            fail: () => {},  
                        })  
                        break;  
                }  
            }, false);  

            //监听接收透传消息事件    
            plus.push.addEventListener('receive', function(msg) {  
                console.log(JSON.stringify(msg))  
                // plus.nativeUI.alert(msg)  
                //处理透传消息的业务逻辑代码    
            }, false);  
            // #endif

本地编译

作为专业的客户端开发人员,最好还是在本地有完整的编译环境。这也是我们在dcloud和apicloud之间选择当前技术栈的原因。

为了简单起见,可以把官方提供的实例项目HBuilder-Hello先在本地打包,然后用官方实例的壳,将里面h5的一些生成文件替换。此处操作流程如下:

  1. 生成本地打包App资源

  2. 将生成的资源放进实例项目app\src\main\assets\apps文件夹下,将之前的Hello H5删掉即可,
    然后将此路径下的dcloud_control.xml中的appid的值改为apps下一层即www上一层文件夹的名称

  • 此时已经可以打包成app并且正常打开,但是还不能推送 *
  1. 修改src/main/java文件夹下的包名为自己之前填写的包名,修改src/main下AndroidManifest.xml中package包名,修改AndroidManifest.xml中的推送参数配置

然后debug或打包即可。

问题解答

问:

  1. 请问服务端的代码还是只能用个推的吗,也就是说需要去个推开发者中心去注册账号拿到appid、appkey、masterSecret吗?那么使用uni-push的优势有什么呢?单纯使用个推也能完成推送功能
  2. 如果我想要给特定的某些/单个用户发消息,之前尝试了可以使用cid进行区别发送,我看你的教程里面没有使用cid,所以我想要知道在服务端代码上如何实现

答:

个推只是其中一个方案,你如果用jpush之类的,社区也有其他人做的教程;不过这个毕竟是dcloud官方给的推荐方案,所以没什么特殊情况,我们还是选用这个。

uni-push集成了个推,unipush的管理界面其实就是用的个推的系统,甚至据我推测,推送服务也是用的个推云。
不过不用取个推再注册,按unipush中的账号使用即可。

单个推送部分代码示例:

// 指定向哪儿推  
Target target = new Target();  
target.setAppId(appId);  
target.setClientId(cId);  

IGtPush push = new IGtPush(url, appKey, masterSecret);  
IPushResult ret = push.pushMessageToSingle(message, target);
收起阅读 »

5+小米推送设置别名

HTML5+ Native.JS 小米推送

根据这篇个推的别名设置文章做了对应的小米推送的版本,
MIPushTool.js

function MIPushTool(){
var isAndorid, PushManager, context, MiPushSDK;
if(plus.os.name == 'Android') {
isAndorid = true;
} else {
isAndorid = false;
}
if(isAndorid) {
PushManager = plus.android.importClass("com.xiaomi.mipush.sdk.MiPushClient");
context = plus.android.runtimeMainActivity().getContext();
} else {
MiPushSDK = plus.ios.importClass("MiPushSDK");
}
this.bindAlias = function(alias) {
if(isAndorid) {
PushManager.setAlias(context, alias,'');
} else {
MiPushSDK.setAlias(alias);
}
}
this.unbindAlias = function(alias) {
if(isAndorid) {
PushManager.unsetAlias(context, alias,'');
} else {
MiPushSDK.unsetAlias(alias);
}
}
}

//调用

mui.plusReady(function() {
var tool = new MIPushTool();
tool.bindAlias(ename);
})

继续阅读 »

根据这篇个推的别名设置文章做了对应的小米推送的版本,
MIPushTool.js

function MIPushTool(){
var isAndorid, PushManager, context, MiPushSDK;
if(plus.os.name == 'Android') {
isAndorid = true;
} else {
isAndorid = false;
}
if(isAndorid) {
PushManager = plus.android.importClass("com.xiaomi.mipush.sdk.MiPushClient");
context = plus.android.runtimeMainActivity().getContext();
} else {
MiPushSDK = plus.ios.importClass("MiPushSDK");
}
this.bindAlias = function(alias) {
if(isAndorid) {
PushManager.setAlias(context, alias,'');
} else {
MiPushSDK.setAlias(alias);
}
}
this.unbindAlias = function(alias) {
if(isAndorid) {
PushManager.unsetAlias(context, alias,'');
} else {
MiPushSDK.unsetAlias(alias);
}
}
}

//调用

mui.plusReady(function() {
var tool = new MIPushTool();
tool.bindAlias(ename);
})

收起阅读 »