HBuilderX

HBuilderX

极客开发工具
uni-app

uni-app

开发一次,多端覆盖
uniCloud

uniCloud

云开发平台
HTML5+

HTML5+

增强HTML5的功能体验
MUI

MUI

上万Star的前端框架

【深圳素与简科技】深圳驾考行业小程序开发方案

解决方案 微信小程序 小程序

  
  随着移动互联网的发展和科技的进步,服务模式的改革创新势在必行;对于现在火热的驾考行业,线上自主学习、培训、练习的形式更受人们的欢迎。如何形成驾考一体化?小程序的出现给了驾校、教练、学员更方便的进行驾照的教学和考试。

  一、驾校小程序开发核心功能

  1、企业展示

  多维度展示公司实力,增强企业品牌效应

  2、预约科目

  预约套餐直观展示,获取信息透明

  3、在线刷题

  小程序刷题、在线考试,随时随地学习

  4、线上交互

  强化客户连接,助力市场开拓

  二、小程序+驾校的优势

  1、传播快

  一键分享,为驾校扩大曝光

  2、类目清楚,方便合理安排

  学习类目清晰明了,推荐产品及时展开,一键预约,一键拨号,一键导航等功能,方便快捷。驾校小程序可以完美解决驾校因为人员的激增,不能合理安排学员与老师的时间、挂科学员的补考、场地安排等问题,为驾校树立良好的口碑。

  3、品牌效应

  紧随时代潮流,用小程序打造驾校专属个性名片,提升驾校知名度

  三、总结

  驾校小程序通过产品展示、案例展示、驾校介绍,提升驾校品牌形象,展示驾校实力。学员可通过驾校小程序进行服务预约、在线考试、在线刷题,有效提升学员的满意度。

  深圳小程序开发推荐深圳素与简科技有限公司(http://www.suyujane.com)多年软件开发经验,海量的开发案例可供参考,看得见的开发经验,让客户更加的省心省力。技术团队都是10年开发工程师,完善的售后服务体系,保障项目开发顺利进行。

继续阅读 »

  
  随着移动互联网的发展和科技的进步,服务模式的改革创新势在必行;对于现在火热的驾考行业,线上自主学习、培训、练习的形式更受人们的欢迎。如何形成驾考一体化?小程序的出现给了驾校、教练、学员更方便的进行驾照的教学和考试。

  一、驾校小程序开发核心功能

  1、企业展示

  多维度展示公司实力,增强企业品牌效应

  2、预约科目

  预约套餐直观展示,获取信息透明

  3、在线刷题

  小程序刷题、在线考试,随时随地学习

  4、线上交互

  强化客户连接,助力市场开拓

  二、小程序+驾校的优势

  1、传播快

  一键分享,为驾校扩大曝光

  2、类目清楚,方便合理安排

  学习类目清晰明了,推荐产品及时展开,一键预约,一键拨号,一键导航等功能,方便快捷。驾校小程序可以完美解决驾校因为人员的激增,不能合理安排学员与老师的时间、挂科学员的补考、场地安排等问题,为驾校树立良好的口碑。

  3、品牌效应

  紧随时代潮流,用小程序打造驾校专属个性名片,提升驾校知名度

  三、总结

  驾校小程序通过产品展示、案例展示、驾校介绍,提升驾校品牌形象,展示驾校实力。学员可通过驾校小程序进行服务预约、在线考试、在线刷题,有效提升学员的满意度。

  深圳小程序开发推荐深圳素与简科技有限公司(http://www.suyujane.com)多年软件开发经验,海量的开发案例可供参考,看得见的开发经验,让客户更加的省心省力。技术团队都是10年开发工程师,完善的售后服务体系,保障项目开发顺利进行。

收起阅读 »

TensorFlow分布式实践

大数据时代,基于单机的建模很难满足企业不断增长的数据量级的需求,开发者需要使用分布式的开发方式,在集群上进行建模。而单机和分布式的开发代码有一定的区别,本文就将为开发者们介绍,基于TensorFlow进行分布式开发的两种方式,帮助开发者在实践的过程中,更好地选择模块的开发方向。

基于TensorFlow原生的分布式开发

分布式开发会涉及到更新梯度的方式,有同步和异步的两个方案,同步更新的方式在模型的表现上能更快地进行收敛,而异步更新时,迭代的速度则会更加快。

TensorFlow是基于ps、work 两种服务器进行分布式的开发。ps服务器可以只用于参数的汇总更新,让各个work进行梯度的计算。

基于TensorFlow原生的分布式开发的具体流程如下:

首先指定ps 服务器启动参数 –job_name=ps:

python distribute.py --ps_hosts=192.168.100.42:2222 --worker_hosts=192.168.100.42:2224,192.168.100.253:2225 --job_name=ps --task_index=0

接着指定work服务器参数(启动两个work 节点) –job_name=work2:

python distribute.py --ps_hosts=192.168.100.42:2222 --worker_hosts=192.168.100.42:2224,192.168.100.253:2225 --job_name=worker --task_index=0  
python distribute.py --ps_hosts=192.168.100.42:2222 --worker_hosts=192.168.100.42:2224,192.168.100.253:2225 --job_name=worker --task_index=1

之后,上述指定的参数 worker_hosts ps_hosts job_name task_index 都需要在py文件中接受使用:

tf.app.flags.DEFINE_string("worker_hosts", "默认值", "描述说明")

接收参数后,需要分别注册ps、work,使他们各司其职:

ps_hosts = FLAGS.ps_hosts.split(",")  
worker_hosts = FLAGS.worker_hosts.split(",")  
cluster = tf.train.ClusterSpec({"ps": ps_hosts, "worker": worker_hosts})  
server = tf.train.Server(cluster,job_name=FLAGS.job_name,task_index=FLAGS.task_index)  

issync = FLAGS.issync  
if FLAGS.job_name == "ps":  
   server.join()  
elif FLAGS.job_name == "worker":  
   with tf.device(tf.train.replica_device_setter(  
                   worker_device="/job:worker/task:%d" % FLAGS.task_index,  
                   cluster=cluster)):

继而更新梯度。

(1)同步更新梯度:

rep_op = tf.train.SyncReplicasOptimizer(optimizer,  
                                               replicas_to_aggregate=len(worker_hosts),  
                                               replica_id=FLAGS.task_index,  
                                               total_num_replicas=len(worker_hosts),  
                                               use_locking=True)  
train_op = rep_op.apply_gradients(grads_and_vars,global_step=global_step)  
init_token_op = rep_op.get_init_tokens_op()  
chief_queue_runner = rep_op.get_chief_queue_runner()

(2)异步更新梯度:

train_op = optimizer.apply_gradients(grads_and_vars,global_step=global_step)

最后,使用tf.train.Supervisor 进行真的迭代

另外,开发者还要注意,如果是同步更新梯度,则还需要加入如下代码:

sv.start_queue_runners(sess, [chief_queue_runner])  
sess.run(init_token_op)

需要注意的是,上述异步的方式需要自行指定集群IP和端口,不过,开发者们也可以借助TensorFlowOnSpark,使用Yarn进行管理。

基于TensorFlowOnSpark的分布式开发

作为个推面向开发者服务的移动APP数据统计分析产品,个数所具有的用户行为预测功能模块,便是基于TensorFlowOnSpark这种分布式来实现的。基于TensorFlowOnSpark的分布式开发使其可以在屏蔽了端口和机器IP的情况下,也能够做到较好的资源申请和分配。而在多个千万级应用同时建模的情况下,集群也有良好的表现,在sparkUI中也能看到相对应的资源和进程的情况。最关键的是,TensorFlowOnSpark可以在单机过度到分布式的情况下,使代码方便修改,且容易部署。

基于TensorFlowOnSpark的分布式开发的具体流程如下:

首先,需要使用spark-submit来提交任务,同时指定spark需要运行的参数(–num-executors 6等)、模型代码、模型超参等,同样需要接受外部参数:

parser = argparse.ArgumentParser()  
parser.add_argument("-i", "--tracks", help="数据集路径")    
args = parser.parse_args()

之后,准备好参数和训练数据(DataFrame),调用模型的API进行启动。

其中,soft_dist.map_fun是要调起的方法,后面均是模型训练的参数。

estimator = TFEstimator(soft_dist.map_fun, args) \  
     .setInputMapping({'tracks': 'tracks', 'label': 'label'}) \  
     .setModelDir(args.model) \  
     .setExportDir(args.serving) \  
     .setClusterSize(args.cluster_size) \  
     .setNumPS(num_ps) \  
     .setEpochs(args.epochs) \  
     .setBatchSize(args.batch_size) \  
     .setSteps(args.max_steps)  
   model = estimator.fit(df)

接下来是soft_dist定义一个 map_fun(args, ctx)的方法:

def map_fun(args, ctx):  
...  
worker_num = ctx.worker_num  # worker数量  
job_name = ctx.job_name  # job名  
task_index = ctx.task_index  # 任务索引  
if job_name == "ps":  # ps节点(主节点)  
  time.sleep((worker_num   1) * 5)  
  cluster, server = TFNode.start_cluster_server(ctx, 1, args.rdma)  
  num_workers = len(cluster.as_dict()['worker'])  
  if job_name == "ps":  
       server.join()  
  elif job_name == "worker":  
       with tf.device(tf.train.replica_device_setter(worker_device="/job:worker/task:%d" % task_index, cluster=cluster)):

之后,可以使用tf.train.MonitoredTrainingSession高级API,进行模型训练和预测。

总结

基于TensorFlow的分布式开发大致就是本文中介绍的两种情况,第二种方式可以用于实际的生产环境,稳定性会更高。

在运行结束的时候,开发者们也可通过设置邮件的通知,及时地了解到模型运行的情况。

同时,如果开发者使用SessionRunHook来保存最后输出的模型,也需要了解到,框架代码中的一个BUG,即它只能在规定的时间内保存,超出规定时间,即使运行没有结束,程序也会被强制结束。如果开发者使用的版本是未修复BUG的版本,则要自行处理,放宽运行时间。

继续阅读 »

大数据时代,基于单机的建模很难满足企业不断增长的数据量级的需求,开发者需要使用分布式的开发方式,在集群上进行建模。而单机和分布式的开发代码有一定的区别,本文就将为开发者们介绍,基于TensorFlow进行分布式开发的两种方式,帮助开发者在实践的过程中,更好地选择模块的开发方向。

基于TensorFlow原生的分布式开发

分布式开发会涉及到更新梯度的方式,有同步和异步的两个方案,同步更新的方式在模型的表现上能更快地进行收敛,而异步更新时,迭代的速度则会更加快。

TensorFlow是基于ps、work 两种服务器进行分布式的开发。ps服务器可以只用于参数的汇总更新,让各个work进行梯度的计算。

基于TensorFlow原生的分布式开发的具体流程如下:

首先指定ps 服务器启动参数 –job_name=ps:

python distribute.py --ps_hosts=192.168.100.42:2222 --worker_hosts=192.168.100.42:2224,192.168.100.253:2225 --job_name=ps --task_index=0

接着指定work服务器参数(启动两个work 节点) –job_name=work2:

python distribute.py --ps_hosts=192.168.100.42:2222 --worker_hosts=192.168.100.42:2224,192.168.100.253:2225 --job_name=worker --task_index=0  
python distribute.py --ps_hosts=192.168.100.42:2222 --worker_hosts=192.168.100.42:2224,192.168.100.253:2225 --job_name=worker --task_index=1

之后,上述指定的参数 worker_hosts ps_hosts job_name task_index 都需要在py文件中接受使用:

tf.app.flags.DEFINE_string("worker_hosts", "默认值", "描述说明")

接收参数后,需要分别注册ps、work,使他们各司其职:

ps_hosts = FLAGS.ps_hosts.split(",")  
worker_hosts = FLAGS.worker_hosts.split(",")  
cluster = tf.train.ClusterSpec({"ps": ps_hosts, "worker": worker_hosts})  
server = tf.train.Server(cluster,job_name=FLAGS.job_name,task_index=FLAGS.task_index)  

issync = FLAGS.issync  
if FLAGS.job_name == "ps":  
   server.join()  
elif FLAGS.job_name == "worker":  
   with tf.device(tf.train.replica_device_setter(  
                   worker_device="/job:worker/task:%d" % FLAGS.task_index,  
                   cluster=cluster)):

继而更新梯度。

(1)同步更新梯度:

rep_op = tf.train.SyncReplicasOptimizer(optimizer,  
                                               replicas_to_aggregate=len(worker_hosts),  
                                               replica_id=FLAGS.task_index,  
                                               total_num_replicas=len(worker_hosts),  
                                               use_locking=True)  
train_op = rep_op.apply_gradients(grads_and_vars,global_step=global_step)  
init_token_op = rep_op.get_init_tokens_op()  
chief_queue_runner = rep_op.get_chief_queue_runner()

(2)异步更新梯度:

train_op = optimizer.apply_gradients(grads_and_vars,global_step=global_step)

最后,使用tf.train.Supervisor 进行真的迭代

另外,开发者还要注意,如果是同步更新梯度,则还需要加入如下代码:

sv.start_queue_runners(sess, [chief_queue_runner])  
sess.run(init_token_op)

需要注意的是,上述异步的方式需要自行指定集群IP和端口,不过,开发者们也可以借助TensorFlowOnSpark,使用Yarn进行管理。

基于TensorFlowOnSpark的分布式开发

作为个推面向开发者服务的移动APP数据统计分析产品,个数所具有的用户行为预测功能模块,便是基于TensorFlowOnSpark这种分布式来实现的。基于TensorFlowOnSpark的分布式开发使其可以在屏蔽了端口和机器IP的情况下,也能够做到较好的资源申请和分配。而在多个千万级应用同时建模的情况下,集群也有良好的表现,在sparkUI中也能看到相对应的资源和进程的情况。最关键的是,TensorFlowOnSpark可以在单机过度到分布式的情况下,使代码方便修改,且容易部署。

基于TensorFlowOnSpark的分布式开发的具体流程如下:

首先,需要使用spark-submit来提交任务,同时指定spark需要运行的参数(–num-executors 6等)、模型代码、模型超参等,同样需要接受外部参数:

parser = argparse.ArgumentParser()  
parser.add_argument("-i", "--tracks", help="数据集路径")    
args = parser.parse_args()

之后,准备好参数和训练数据(DataFrame),调用模型的API进行启动。

其中,soft_dist.map_fun是要调起的方法,后面均是模型训练的参数。

estimator = TFEstimator(soft_dist.map_fun, args) \  
     .setInputMapping({'tracks': 'tracks', 'label': 'label'}) \  
     .setModelDir(args.model) \  
     .setExportDir(args.serving) \  
     .setClusterSize(args.cluster_size) \  
     .setNumPS(num_ps) \  
     .setEpochs(args.epochs) \  
     .setBatchSize(args.batch_size) \  
     .setSteps(args.max_steps)  
   model = estimator.fit(df)

接下来是soft_dist定义一个 map_fun(args, ctx)的方法:

def map_fun(args, ctx):  
...  
worker_num = ctx.worker_num  # worker数量  
job_name = ctx.job_name  # job名  
task_index = ctx.task_index  # 任务索引  
if job_name == "ps":  # ps节点(主节点)  
  time.sleep((worker_num   1) * 5)  
  cluster, server = TFNode.start_cluster_server(ctx, 1, args.rdma)  
  num_workers = len(cluster.as_dict()['worker'])  
  if job_name == "ps":  
       server.join()  
  elif job_name == "worker":  
       with tf.device(tf.train.replica_device_setter(worker_device="/job:worker/task:%d" % task_index, cluster=cluster)):

之后,可以使用tf.train.MonitoredTrainingSession高级API,进行模型训练和预测。

总结

基于TensorFlow的分布式开发大致就是本文中介绍的两种情况,第二种方式可以用于实际的生产环境,稳定性会更高。

在运行结束的时候,开发者们也可通过设置邮件的通知,及时地了解到模型运行的情况。

同时,如果开发者使用SessionRunHook来保存最后输出的模型,也需要了解到,框架代码中的一个BUG,即它只能在规定的时间内保存,超出规定时间,即使运行没有结束,程序也会被强制结束。如果开发者使用的版本是未修复BUG的版本,则要自行处理,放宽运行时间。

收起阅读 »

解决返回操作遇到的坑,监听back键重置返回操作。

返回 mui 返回按键

新人在初次接触开发的时候,搞不清楚多页面以及父子页面之间的关系

为了更好的兼容返回键的时候,采用以下方案

举例说明
常规方案
以首页父子页面结构为例,子页面的创建在父页面(即首页)中完成。

var index = plus.webview.getLaunchWebview();  
var home = plus.webview.create('home.html','home', {  
    top: '50px',  
    bottom: 0  
});  
index.append(home);

想要home页面接下去跳转到外链,或者其他页面实现可返回操作,需要重置mui的返回监听操作
判断如果回到最初页面就提醒退出,一秒之内按两次则退出

//重置mui返回  
mui.back = function(){  
    var first = null;  
    //显示上一个界面;  
    home.canBack(function(e) { //监听webview窗口是否可以返回  
        if (e.canBack) { //可以返回  
            home.back(); //返回上一页面  
        } else { //不可以返回  
             //首次按键,提示‘再按一次退出应用’  
                if (!first) {  
                        first = new Date().getTime();  
                        mui.toast('再按一次退出应用');  
                        setTimeout(function() {  
                                first = null;  
                        }, 1000);  
                } else {  
                        if (new Date().getTime() - first < 1000) {  
                                plus.runtime.quit();  
                        }  
                }  
        }  
    });  
    //继续当前页面原有返回逻辑  
}

如果到指定页面,不让返回操作,执行返回提示退出的话,请先清空历史操作记录,再重新加载这个页面

home.clear();  
home.loadURL('login.html');

这样的方案就很好解决一个封装网页的应用了,兼容有效体验的返回操作。

后期会更用心研究5+App的开发,谢谢大家支持,有好的项目合作,可以联系合作wx:s7team

继续阅读 »

新人在初次接触开发的时候,搞不清楚多页面以及父子页面之间的关系

为了更好的兼容返回键的时候,采用以下方案

举例说明
常规方案
以首页父子页面结构为例,子页面的创建在父页面(即首页)中完成。

var index = plus.webview.getLaunchWebview();  
var home = plus.webview.create('home.html','home', {  
    top: '50px',  
    bottom: 0  
});  
index.append(home);

想要home页面接下去跳转到外链,或者其他页面实现可返回操作,需要重置mui的返回监听操作
判断如果回到最初页面就提醒退出,一秒之内按两次则退出

//重置mui返回  
mui.back = function(){  
    var first = null;  
    //显示上一个界面;  
    home.canBack(function(e) { //监听webview窗口是否可以返回  
        if (e.canBack) { //可以返回  
            home.back(); //返回上一页面  
        } else { //不可以返回  
             //首次按键,提示‘再按一次退出应用’  
                if (!first) {  
                        first = new Date().getTime();  
                        mui.toast('再按一次退出应用');  
                        setTimeout(function() {  
                                first = null;  
                        }, 1000);  
                } else {  
                        if (new Date().getTime() - first < 1000) {  
                                plus.runtime.quit();  
                        }  
                }  
        }  
    });  
    //继续当前页面原有返回逻辑  
}

如果到指定页面,不让返回操作,执行返回提示退出的话,请先清空历史操作记录,再重新加载这个页面

home.clear();  
home.loadURL('login.html');

这样的方案就很好解决一个封装网页的应用了,兼容有效体验的返回操作。

后期会更用心研究5+App的开发,谢谢大家支持,有好的项目合作,可以联系合作wx:s7team

收起阅读 »

windows HBuilderX: 突然启动不了的解决办法

windows HBuilderX 启动不了

问题说明

近来,有几个用户反馈,Windows HBuilderX昨天用的好好的,今天来了,启动不了了。有可能是配置文件坏了。

解决办法:

  1. 进入C:\Users\Administrator\AppData\Roaming\目录,将Administrator换成你自己的用户
  2. 在此目录下,找到HBuilder X目录,注意:将此目录随便重命名一下,不要删除
  3. 然后重启HX
继续阅读 »

问题说明

近来,有几个用户反馈,Windows HBuilderX昨天用的好好的,今天来了,启动不了了。有可能是配置文件坏了。

解决办法:

  1. 进入C:\Users\Administrator\AppData\Roaming\目录,将Administrator换成你自己的用户
  2. 在此目录下,找到HBuilder X目录,注意:将此目录随便重命名一下,不要删除
  3. 然后重启HX
收起阅读 »

解决mui开发安卓App低版本不兼容es6方法

https://blog.csdn.net/wangaiheng/article/details/56481631

参考这篇文章

https://blog.csdn.net/wangaiheng/article/details/56481631

参考这篇文章

深圳素与简科技展会行业小程序开发解决方案

小程序

  
 一、展会小程序概况

  会展小程序的目的在于为展会主办方提供智慧展会全流程数字化解决方案,使展会筹办工作更加聪明。

  会展相关的展商、展品、同期活动以及会展信息可在小程序上随时随地查看,同时还可以提供展馆现场的定位和路线导览等功能。方便用户快速便捷查看展会相关信息。

  二、会展小程序基础功能

  深圳会展小程序定制开发会根据用户需求来制定,通过产品和市场定位以及营销方向来设定功能,但是一般的展会小程序会涉及到以下这些功能:

  1、入场:签到、邀请函、电子票务

  2、推广:信息展示、日程管理、二维码扫描、定位导航

  3、管理:数据分析、问卷调查、活动推广

  三、会展小程序的优势

  1、数字会议全流程

  小程序建设、会议邀约、报名购票、入场签到、现场互动、会场管理、数据分析助您轻松驾驭会议全流程。

  2、观众报名

  观众报名表设置、观众报名信息收集、名单管理、普通观众及专业观众的票种设置、售票规则分类、多种支付方式。

  3、观众注册

  现场注册并制作含RFID芯片的参会证、设置闸机道门,无障碍验证身份入场、展会配套会议或论坛极速签到。

  4、展商数据分析

  展商报名资料下载、参展行为分类查看、参展费结算。

  三、会展小程序应用场景

  1、大型会议

  提供专业的全流程解决方案,贯穿会前、会中、会后,为会务组节省心力、提高效率,并优化参会者的参会体验。

  2、新品发布会

  提供的新品发布会方案,有的放矢地为主办方解决会议营销和客户关系管理的双重问题。

  3、年会活动

  用便捷的会务管理系统和专业的现场互动系统,为您打造一场顺利又精彩的企业年会。

  4、展会活动

  为展会主办方提供智慧展会全流程数字化解决方案,使展会筹办工作更加聪明。

  5、研究会和峰会

  为会议主办公司定制移动会议解决方案,可支持一个小程序多个会议的功能。

  6、教育培训

  如何办好一场培训会,让学员体验与办会效率同时提升,是每家公司的追求,一站式数字会务产品将解决这一问题。

  展会行业小程序开发整合展会采购商和参展商资源,展会行业小程序提供最新的展会新闻、展馆介绍、展品介绍、展会知识以及展览会服务商,为展会服务企业与参展商构筑了一座信息的桥梁。展会行业小程序的诞生顺应时代和中国经济发展的要求,它的出现对展会发展产生了巨大的推动作用。

继续阅读 »

  
 一、展会小程序概况

  会展小程序的目的在于为展会主办方提供智慧展会全流程数字化解决方案,使展会筹办工作更加聪明。

  会展相关的展商、展品、同期活动以及会展信息可在小程序上随时随地查看,同时还可以提供展馆现场的定位和路线导览等功能。方便用户快速便捷查看展会相关信息。

  二、会展小程序基础功能

  深圳会展小程序定制开发会根据用户需求来制定,通过产品和市场定位以及营销方向来设定功能,但是一般的展会小程序会涉及到以下这些功能:

  1、入场:签到、邀请函、电子票务

  2、推广:信息展示、日程管理、二维码扫描、定位导航

  3、管理:数据分析、问卷调查、活动推广

  三、会展小程序的优势

  1、数字会议全流程

  小程序建设、会议邀约、报名购票、入场签到、现场互动、会场管理、数据分析助您轻松驾驭会议全流程。

  2、观众报名

  观众报名表设置、观众报名信息收集、名单管理、普通观众及专业观众的票种设置、售票规则分类、多种支付方式。

  3、观众注册

  现场注册并制作含RFID芯片的参会证、设置闸机道门,无障碍验证身份入场、展会配套会议或论坛极速签到。

  4、展商数据分析

  展商报名资料下载、参展行为分类查看、参展费结算。

  三、会展小程序应用场景

  1、大型会议

  提供专业的全流程解决方案,贯穿会前、会中、会后,为会务组节省心力、提高效率,并优化参会者的参会体验。

  2、新品发布会

  提供的新品发布会方案,有的放矢地为主办方解决会议营销和客户关系管理的双重问题。

  3、年会活动

  用便捷的会务管理系统和专业的现场互动系统,为您打造一场顺利又精彩的企业年会。

  4、展会活动

  为展会主办方提供智慧展会全流程数字化解决方案,使展会筹办工作更加聪明。

  5、研究会和峰会

  为会议主办公司定制移动会议解决方案,可支持一个小程序多个会议的功能。

  6、教育培训

  如何办好一场培训会,让学员体验与办会效率同时提升,是每家公司的追求,一站式数字会务产品将解决这一问题。

  展会行业小程序开发整合展会采购商和参展商资源,展会行业小程序提供最新的展会新闻、展馆介绍、展品介绍、展会知识以及展览会服务商,为展会服务企业与参展商构筑了一座信息的桥梁。展会行业小程序的诞生顺应时代和中国经济发展的要求,它的出现对展会发展产生了巨大的推动作用。

收起阅读 »

uni-app 拍摄视频限制最大长度解决方案

录制视频 uniapp 教程 uni_app uniapp

因为uni-app的平台差异问题,所以无法直接限制视频的长度,类似与微信朋友圈拍摄十秒视频。现在提供一种App端可以实现的解决方案。

安卓解决方案

关联阅读
安卓使用njs来实现视频最大播放时长

      // 安卓关键代码  
const VIDEOZOOM = 200;  
let MediaStore = plus.android.importClass('android.provider.MediaStore');  
let Intent = plus.android.importClass('android.content.Intent');  
// 导入后可以使用new方法创建类的示例对象  
let intent = new Intent('android.media.action.VIDEO_CAPTURE');  
intent.putExtra('android.intent.extra.videoQuality', 1); //0 means low quality, 1 means high quality  
//intent.putExtra("android.provider.MediaStore.EXTRA_OUTPUT", url);  
intent.putExtra('android.intent.extra.durationLimit', 10); //设置录像时间  
let main = plus.android.runtimeMainActivity();  
main.startActivityForResult(intent, VIDEOZOOM);  
//获取返回参数  
main.onActivityResult = function(requestCode, resultCode, data) {  
    let context = main;  
    plus.android.importClass(data);  
    let uri = data.getData();  
    let resolver = context.getContentResolver();  
    plus.android.importClass(resolver);  
    let cursor = resolver.query(uri, null, null, null, null);  
    plus.android.importClass(cursor);  
    cursor.moveToFirst();  
    let column = cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DATA);  
    // 获取录制的视频路径  
    let filePath = cursor.getString(column);  
    // 解析视频文件的属性  
    plus.io.resolveLocalFileSystemURL(  
        filePath,  
        (entry) => {  
            console.log(entry.fullPath)  
            entry.file(function(file) {  
                 console.log("size=="+file.size);   
                 console.log("name=="+file.name);  
            });  
        },  
        (e) => {  
            console.log("Resolve file URL failed: " + e.message);  
        }  
    );  
};  

ios解决方案

关联阅读
ios 直接使用5+ Api 就可以实现相关功能

       // ios关键代码  

let cmr = plus.camera.getCamera();  
let res = cmr.supportedVideoResolutions[0];  
let fmt = cmr.supportedVideoFormats[0];  
cmr.startVideoCapture(  
    function(path) {  
        plus.io.resolveLocalFileSystemURL(  
            path,  
            (entry) => {  
                console.log(entry.fullPath)  
                entry.file(function(file) {  
                  console.log("size=="+file.size);   
                  console.log("name=="+file.name);  
                });  
            },  
            (e) => {}  
        );  
    },  
    function(error) {  
        console.log("Resolve file URL failed: " + e.message);  
    }, {  
        resolution: res,  
        format: fmt,  
        videoMaximumDuration:10  
    }  
);  

Tips

  • 安卓端使用njs,因为不同root的问题会有部分手机不支持

具体使用

详见附件,把代码进行简单整合,并判断平台 ,可以直接调用

video.camera({  
    time: 10,  
    success: e => {  
        console.log("path=="+e.fullPath);   
        console.log("size=="+e.file.size);   
        console.log("name=="+e.file.name);  
        console.log(e);  
    }  
});  
继续阅读 »

因为uni-app的平台差异问题,所以无法直接限制视频的长度,类似与微信朋友圈拍摄十秒视频。现在提供一种App端可以实现的解决方案。

安卓解决方案

关联阅读
安卓使用njs来实现视频最大播放时长

      // 安卓关键代码  
const VIDEOZOOM = 200;  
let MediaStore = plus.android.importClass('android.provider.MediaStore');  
let Intent = plus.android.importClass('android.content.Intent');  
// 导入后可以使用new方法创建类的示例对象  
let intent = new Intent('android.media.action.VIDEO_CAPTURE');  
intent.putExtra('android.intent.extra.videoQuality', 1); //0 means low quality, 1 means high quality  
//intent.putExtra("android.provider.MediaStore.EXTRA_OUTPUT", url);  
intent.putExtra('android.intent.extra.durationLimit', 10); //设置录像时间  
let main = plus.android.runtimeMainActivity();  
main.startActivityForResult(intent, VIDEOZOOM);  
//获取返回参数  
main.onActivityResult = function(requestCode, resultCode, data) {  
    let context = main;  
    plus.android.importClass(data);  
    let uri = data.getData();  
    let resolver = context.getContentResolver();  
    plus.android.importClass(resolver);  
    let cursor = resolver.query(uri, null, null, null, null);  
    plus.android.importClass(cursor);  
    cursor.moveToFirst();  
    let column = cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DATA);  
    // 获取录制的视频路径  
    let filePath = cursor.getString(column);  
    // 解析视频文件的属性  
    plus.io.resolveLocalFileSystemURL(  
        filePath,  
        (entry) => {  
            console.log(entry.fullPath)  
            entry.file(function(file) {  
                 console.log("size=="+file.size);   
                 console.log("name=="+file.name);  
            });  
        },  
        (e) => {  
            console.log("Resolve file URL failed: " + e.message);  
        }  
    );  
};  

ios解决方案

关联阅读
ios 直接使用5+ Api 就可以实现相关功能

       // ios关键代码  

let cmr = plus.camera.getCamera();  
let res = cmr.supportedVideoResolutions[0];  
let fmt = cmr.supportedVideoFormats[0];  
cmr.startVideoCapture(  
    function(path) {  
        plus.io.resolveLocalFileSystemURL(  
            path,  
            (entry) => {  
                console.log(entry.fullPath)  
                entry.file(function(file) {  
                  console.log("size=="+file.size);   
                  console.log("name=="+file.name);  
                });  
            },  
            (e) => {}  
        );  
    },  
    function(error) {  
        console.log("Resolve file URL failed: " + e.message);  
    }, {  
        resolution: res,  
        format: fmt,  
        videoMaximumDuration:10  
    }  
);  

Tips

  • 安卓端使用njs,因为不同root的问题会有部分手机不支持

具体使用

详见附件,把代码进行简单整合,并判断平台 ,可以直接调用

video.camera({  
    time: 10,  
    success: e => {  
        console.log("path=="+e.fullPath);   
        console.log("size=="+e.file.size);   
        console.log("name=="+e.file.name);  
        console.log(e);  
    }  
});  
收起阅读 »

关于uni-app的ui库、ui框架、ui组件

ui组件 ui库 ui框架

组件的概念

组件是现代开发的重要里程碑。组件重构了分工模型,让大量的轮子出现,让开发者可以拿来轮子直接用,大幅提升了整个产业的效率。

uni-app是有内置组件的。这和web开发不一样。
web开发基本上不用基础组件,都是找一个三方ui库,全套组件都包含。那是因为html的基础组件默认样式不适配手机风格。
但uni-app体系不是这样,内置组件就是为手机优化的。

但内置组件只能满足基础需求,更多场景,需要扩展组件。
扩展组件是基于内置组件的二次封装,从性能上来讲,扩展组件的性能略低于内置组件,所以开发者切勿抛弃内置组件,直接全套用三方UI组件库。

uni-app的插件市场,有很多扩展组件,有的是单独的,有的是成套的。
有些开发者喜欢成套的组件,但注意成套扩展组件也不可能覆盖所有需求,很多场景还是需要单独下载专业组件。

扩展组件的选择

众多扩展组件如何选择?我们首先要搞清楚组件的分类。
组件分2大类:1、vue组件(文件后缀为vue);2、小程序自定义组件(文件后缀为wxml或其他小程序平台特有后缀名称)

  • vue组件又分为2个细项:only for web、全端兼容
  • 小程序组件又分为:微信/QQ小程序组件、阿里小程序组件、百度小程序组件、字节跳动小程序组件。
    这些组件uni-app都支持,但受组件本身技术特点限制,在不同端有不一样的支持度。
    下面这张表格,可以清楚的表达不同类型的组件的兼容性。

从表格中可以很明显看出,更推荐使用的是全端兼容的uni规范组件。

很多人容易搞错2个问题:

  1. 同样是vue组件,only for web的和全端的有什么区别?
    传统的vue组件,比如elementUI,都是only for web的,里面有大量dom和window对象操作。但小程序和App是没有dom这些api的,自然无法跨端使用。
    想要跨端,其实也不难,做一套无dom的vue组件即可。官方的uni-ui即是如此。还有众多开发者在插件市场提交了更多这种类型的库。
  2. vant是分web版和weapp版的,千万别搞混
    vant的web版操作了dom,所以只能用于web端;而vant weapp是微信小程序组件规范,可以用于微信、App、H5;vant自身并没有提供全端可用的无dom vue组件。

除了兼容性,在性能和生态完善度层面,不同类型组件有什么差别?

  1. 性能:
    • vue组件性能好于小程序自定义组件。这是因为uni-app在底层对vue数据更新使用了自动差量更新的机制。而小程序自定义组件,默认的setData写法是没有差量数据更新的,需要写代码手动实现差量更新才能达到相同性能。
  2. 生态完善度
    • 首先除了微信小程序,其他几个平台的小程序几乎是没有三方组件和模板生态的。开发其他端小程序,得靠uni-app的生态
    • 再说微信小程序生态,之前在微信小程序平台上一些有名的库(比如wxParse、wx-Echart),实际上在性能、功能、技术支持上,大多做的不如uni-app生态下的新库好。而vant、iview的weapp版,其性能也均不如uni ui。
  3. 其他指标
    • vue doc:HBuilderX支持vue doc,组件作者在vue组件源码里编写vue doc,可以让组件使用者写代码时得到良好的代码提示。
    • easycom:uni-app支持easycom,可以大幅简化组件的使用
    • nvue支持:如果开发App,可能会涉及到nvue原生渲染页面,这种渲染方式支持的css有限,此时就要甄别组件是否兼容nvue。

再来看看各种成套UI的优劣分析

uni ui

DCloud官方出了一套扩展组件,即uni-ui
这些扩展组件支持单个组件从插件市场下载,也支持npm引入uni ui,当然更方便的是在HBuilderX新建项目时直接选择uni ui项目模板
uni ui有如下优势:

  1. 优化逻辑层和视图层的通信折损:非H5端的各个平台,包括App和各种小程序,其逻辑层和视图层是分离的,两层之间通信交互会有折损,导致诸如跟手滑动不流畅。uni ui在底层会利用wxs等技术,把适当的js代码运行在视图层,减少通信折损,保证诸如swiperAction左滑菜单等跟手操作流畅顺滑
  2. 自动差量diff数据:在uni-app下,开发App和小程序,不需要手动setData,底层自动会差量更新数据。但如果使用了小程序组件,则需要按小程序的setData方式来更新数据,很难做到自动diff更新数据。
  3. 背景停止:很多ui组件是会一直动的,比如轮播图、跑马灯。即便这个窗体被新窗体挡住,它在背景层仍然在消耗着硬件资源。在Android的webview版本为chrome66以上,背景操作ui会引发很严重的性能问题,造成前台界面明显卡顿。而uni ui的组件,会自动判断自己的显示状态,在组件不再可见时,不会再做动画消耗硬件资源。
  4. 纯vue语法:uni ui的引用、开发都是纯vue方式。而小程序组件的引用注册、开发都是小程序语法,两种语法混合在一个工程,写的也不舒服,维护也麻烦。
  5. uni统计自动整合:比如使用uni ui的导航栏组件,就不需要写统计的自定义事件来触发页面标题上报。uni统计会自动识别导航栏组件的标题。类似的,收藏组件、购物车组件,都可以免打点直接使用。
  6. uni ui兼容Android 4.4等低端机webview,没有浏览器兼容问题。
  7. uni ui支持nvue:App端,uni-app同时支持webview渲染和原生渲染,而uni ui是可以一套代码同时支持webview渲染和原生渲染的。为了兼容原生渲染,uni ui也做到了纯flex布局。
  8. uni ui内置vue doc,使用组件时有良好的代码提示
  9. 支持easycom规范,使用非常简单
  10. 支持datacom规范,云端一体全部封装掉
  11. 支持uni_module规范,方便插件的更新

推荐在HBuilderX新建项目时,直接选择uni ui项目模板,然后在代码里直接敲u,所有组件都拉出来,不用引用、不用注册,直接就用。


插件市场更多组件

插件市场,https://ext.dcloud.net.cn,有各种玲琅满目的组件、模板。
其中成套的全端兼容ui库包括:

其他

  • 如果你仍坚持使用微信小程序的自定义组件ui,插件市场也有很多vant weapp版的集成示例https://ext.dcloud.net.cn/search?q=vant。同时要注意,小程序自定义组件的性能不如vue组件。
  • 如果你的nvue文件使用weex编译模式,也支持weex ui。三方商业ui库有graceUI weex版。但weex编译模式属于被淘汰技术,不再提供技术支持,nvue开发请使用uni-app编译模式。

综上,官方对组件的使用建议是:

  1. 首先使用内置组件
  2. 然后使用uni ui扩展组件
  3. 其他需求依靠插件市场其他组件灵活补充
继续阅读 »

组件的概念

组件是现代开发的重要里程碑。组件重构了分工模型,让大量的轮子出现,让开发者可以拿来轮子直接用,大幅提升了整个产业的效率。

uni-app是有内置组件的。这和web开发不一样。
web开发基本上不用基础组件,都是找一个三方ui库,全套组件都包含。那是因为html的基础组件默认样式不适配手机风格。
但uni-app体系不是这样,内置组件就是为手机优化的。

但内置组件只能满足基础需求,更多场景,需要扩展组件。
扩展组件是基于内置组件的二次封装,从性能上来讲,扩展组件的性能略低于内置组件,所以开发者切勿抛弃内置组件,直接全套用三方UI组件库。

uni-app的插件市场,有很多扩展组件,有的是单独的,有的是成套的。
有些开发者喜欢成套的组件,但注意成套扩展组件也不可能覆盖所有需求,很多场景还是需要单独下载专业组件。

扩展组件的选择

众多扩展组件如何选择?我们首先要搞清楚组件的分类。
组件分2大类:1、vue组件(文件后缀为vue);2、小程序自定义组件(文件后缀为wxml或其他小程序平台特有后缀名称)

  • vue组件又分为2个细项:only for web、全端兼容
  • 小程序组件又分为:微信/QQ小程序组件、阿里小程序组件、百度小程序组件、字节跳动小程序组件。
    这些组件uni-app都支持,但受组件本身技术特点限制,在不同端有不一样的支持度。
    下面这张表格,可以清楚的表达不同类型的组件的兼容性。

从表格中可以很明显看出,更推荐使用的是全端兼容的uni规范组件。

很多人容易搞错2个问题:

  1. 同样是vue组件,only for web的和全端的有什么区别?
    传统的vue组件,比如elementUI,都是only for web的,里面有大量dom和window对象操作。但小程序和App是没有dom这些api的,自然无法跨端使用。
    想要跨端,其实也不难,做一套无dom的vue组件即可。官方的uni-ui即是如此。还有众多开发者在插件市场提交了更多这种类型的库。
  2. vant是分web版和weapp版的,千万别搞混
    vant的web版操作了dom,所以只能用于web端;而vant weapp是微信小程序组件规范,可以用于微信、App、H5;vant自身并没有提供全端可用的无dom vue组件。

除了兼容性,在性能和生态完善度层面,不同类型组件有什么差别?

  1. 性能:
    • vue组件性能好于小程序自定义组件。这是因为uni-app在底层对vue数据更新使用了自动差量更新的机制。而小程序自定义组件,默认的setData写法是没有差量数据更新的,需要写代码手动实现差量更新才能达到相同性能。
  2. 生态完善度
    • 首先除了微信小程序,其他几个平台的小程序几乎是没有三方组件和模板生态的。开发其他端小程序,得靠uni-app的生态
    • 再说微信小程序生态,之前在微信小程序平台上一些有名的库(比如wxParse、wx-Echart),实际上在性能、功能、技术支持上,大多做的不如uni-app生态下的新库好。而vant、iview的weapp版,其性能也均不如uni ui。
  3. 其他指标
    • vue doc:HBuilderX支持vue doc,组件作者在vue组件源码里编写vue doc,可以让组件使用者写代码时得到良好的代码提示。
    • easycom:uni-app支持easycom,可以大幅简化组件的使用
    • nvue支持:如果开发App,可能会涉及到nvue原生渲染页面,这种渲染方式支持的css有限,此时就要甄别组件是否兼容nvue。

再来看看各种成套UI的优劣分析

uni ui

DCloud官方出了一套扩展组件,即uni-ui
这些扩展组件支持单个组件从插件市场下载,也支持npm引入uni ui,当然更方便的是在HBuilderX新建项目时直接选择uni ui项目模板
uni ui有如下优势:

  1. 优化逻辑层和视图层的通信折损:非H5端的各个平台,包括App和各种小程序,其逻辑层和视图层是分离的,两层之间通信交互会有折损,导致诸如跟手滑动不流畅。uni ui在底层会利用wxs等技术,把适当的js代码运行在视图层,减少通信折损,保证诸如swiperAction左滑菜单等跟手操作流畅顺滑
  2. 自动差量diff数据:在uni-app下,开发App和小程序,不需要手动setData,底层自动会差量更新数据。但如果使用了小程序组件,则需要按小程序的setData方式来更新数据,很难做到自动diff更新数据。
  3. 背景停止:很多ui组件是会一直动的,比如轮播图、跑马灯。即便这个窗体被新窗体挡住,它在背景层仍然在消耗着硬件资源。在Android的webview版本为chrome66以上,背景操作ui会引发很严重的性能问题,造成前台界面明显卡顿。而uni ui的组件,会自动判断自己的显示状态,在组件不再可见时,不会再做动画消耗硬件资源。
  4. 纯vue语法:uni ui的引用、开发都是纯vue方式。而小程序组件的引用注册、开发都是小程序语法,两种语法混合在一个工程,写的也不舒服,维护也麻烦。
  5. uni统计自动整合:比如使用uni ui的导航栏组件,就不需要写统计的自定义事件来触发页面标题上报。uni统计会自动识别导航栏组件的标题。类似的,收藏组件、购物车组件,都可以免打点直接使用。
  6. uni ui兼容Android 4.4等低端机webview,没有浏览器兼容问题。
  7. uni ui支持nvue:App端,uni-app同时支持webview渲染和原生渲染,而uni ui是可以一套代码同时支持webview渲染和原生渲染的。为了兼容原生渲染,uni ui也做到了纯flex布局。
  8. uni ui内置vue doc,使用组件时有良好的代码提示
  9. 支持easycom规范,使用非常简单
  10. 支持datacom规范,云端一体全部封装掉
  11. 支持uni_module规范,方便插件的更新

推荐在HBuilderX新建项目时,直接选择uni ui项目模板,然后在代码里直接敲u,所有组件都拉出来,不用引用、不用注册,直接就用。


插件市场更多组件

插件市场,https://ext.dcloud.net.cn,有各种玲琅满目的组件、模板。
其中成套的全端兼容ui库包括:

其他

  • 如果你仍坚持使用微信小程序的自定义组件ui,插件市场也有很多vant weapp版的集成示例https://ext.dcloud.net.cn/search?q=vant。同时要注意,小程序自定义组件的性能不如vue组件。
  • 如果你的nvue文件使用weex编译模式,也支持weex ui。三方商业ui库有graceUI weex版。但weex编译模式属于被淘汰技术,不再提供技术支持,nvue开发请使用uni-app编译模式。

综上,官方对组件的使用建议是:

  1. 首先使用内置组件
  2. 然后使用uni ui扩展组件
  3. 其他需求依靠插件市场其他组件灵活补充
收起阅读 »

uni-app调用uni.chooseImage等API报错解决方案

api uni_app uniapp

最近uni-app 在调用 uni.chooseImage() 、 uni.chooseLocation() 等api的时候 ,在控制台会有如下报错提示。



报错文章地址

解决方案: 这个问题应该是微信小程序的调试基础库导致的,并不影响正常使用。如果不想看到这个报错,把微信小程序开发工具的调试基础库版本切换到 2.4.3以下即可(包含2.4.3)。

继续阅读 »

最近uni-app 在调用 uni.chooseImage() 、 uni.chooseLocation() 等api的时候 ,在控制台会有如下报错提示。



报错文章地址

解决方案: 这个问题应该是微信小程序的调试基础库导致的,并不影响正常使用。如果不想看到这个报错,把微信小程序开发工具的调试基础库版本切换到 2.4.3以下即可(包含2.4.3)。

收起阅读 »

美容美业小程序开发解决方案

解决方案 小程序

  美容美业小程序开发解决方案

  一、小程序概述

  美容小程序通过移动客户端为客户提供美容资讯推送、服务预定等相关服务,同时对接线上服务平台与线下服务门店共同发展,让美容行业经营模式转化成O2O商业模式。商家通过开发美容小程序,能给用户提供移动化便捷的个性服务,同时为行业商家带来新的管理模式、新的营销方式、新的发展空间。

  二、行业发展痛点

  因为线下服务场景的限制,很多传统美容行业的商家无法全面不了解消费者需求,缺乏对市场需求的分析调查,只能凭经验去做出经营对策。利用美容小程序去服务于美容行业,则能实现市场数据的沉淀与分析,为美容行业的商家制定经营策略提供科学的数据化的参考。

  美容行业的大部分实体点商家的宣传方式仍旧停留在海报、电视媒体等比较传统的手法上,滞后的宣传手法带来的效益难以保障。通过开发美容小程序,可以将线上场景作为主要宣传平台,结合线上二维码推广,用符合时下潮流的营销手段提高营销利益。传统的客户信息保存手段,不利于美容门店在发起营销活动时,将客户信息直接与营销活动对接,容易造成营销对象选择错误、营销资源投入的浪费。而使用美容小程序,则可以通过开发会员管理系统,实现CRM客户管理与维护,高效率管理价值客户,精准化进行营销。

  对于连锁美容实体门店来说,在管理上受时间、空间限制,容易出现信息传输慢、沟通有误等问题,造成门店信息展示存在误差或不对称的情况。美容小程序中可以开发门店美容小程序功能,实现统一管理美业门店,保证每个门店特色化发展,同时又保障信息展示的同步。

  三、开发价值

  针对用户来说对用户来说,用户在美容小程序中及时了解美容门店的动态信息、产品服务以及美业常识等。并且在使用美容小程序的时候,用户能实时关注美容门店的新品上线活动、优惠促销活动,实时了解优惠活动资讯,参与优惠活动,来带给自己更优惠的价值与利益。针对企业来说对企业来说,美容小程序是通过开发线上管理系统来实现业务管理,能专业系统化塑造行业门店形象,提升美容行业的信誉,帮助美业门店朝品牌化、连锁化发展。通过小程序与其他平台连接,可以拓宽商家的营销渠道,将各个平台的流量引入到小程序中为己所用。

  四、主要功能开发

  1、在线预约时间

  支持用户在线预约美容服务时间,让用户能弹性预约服务,错开服务高峰期,减少耗费时间等待服务的可能,同时也能让加上有一定的服务准备时间,提前做好服务准备。

  2、效果预览

  在美容小程序中展示一些美容和美发的样式供用户参考选择,让客户得以根据样式库来选择自己喜欢的样式进行美容美发服务,通过用户的自主选择来提升服务质量。

  3、社群交流

  针对有共同需求的用户去创建交流社群,帮助商家获取精准客户信息,针对不同需求的客户来实施不同的营销策略,让营销投入能得到更高的回报。并且,通过将有共同需求的客户变成相同社群人员,还能通过客户之间的分享交流,提升用户的活跃度。?

  4、会员管理

  以会员管理功能,来为用户提供建立会员卡、会员优惠券发放、会员积分管理、卡帐管理与监控、财务结算等服务,为商家的针对性维护客户、精准性营销带来可能。

  5、地图导航

  基于LBS技术定位用户所在位置,为用户提供门店位置导航或者附近门店查询服务,让用户能通过线路规划推送或线路导航更快找到门店,同时让附近连锁门店的曝光率提高。

  6、资讯推送

  利用资讯推送功能,将美容小程序的优惠促销信息以及美容行业的知识等资讯推送出去,让优惠内容被更多用户所见,也通过提供小知识来为小程序增值,提高吸引力。

小程序开发推荐深圳素与简科技有限公司(http://www.suyujane.com)多年软件开发经验,海量的开发案例可供参考,看得见的开发经验,让客户更加的省心省力。技术团队都是10年开发工程师,完善的售后服务体系,保障项目开发顺利进行。  
继续阅读 »

  美容美业小程序开发解决方案

  一、小程序概述

  美容小程序通过移动客户端为客户提供美容资讯推送、服务预定等相关服务,同时对接线上服务平台与线下服务门店共同发展,让美容行业经营模式转化成O2O商业模式。商家通过开发美容小程序,能给用户提供移动化便捷的个性服务,同时为行业商家带来新的管理模式、新的营销方式、新的发展空间。

  二、行业发展痛点

  因为线下服务场景的限制,很多传统美容行业的商家无法全面不了解消费者需求,缺乏对市场需求的分析调查,只能凭经验去做出经营对策。利用美容小程序去服务于美容行业,则能实现市场数据的沉淀与分析,为美容行业的商家制定经营策略提供科学的数据化的参考。

  美容行业的大部分实体点商家的宣传方式仍旧停留在海报、电视媒体等比较传统的手法上,滞后的宣传手法带来的效益难以保障。通过开发美容小程序,可以将线上场景作为主要宣传平台,结合线上二维码推广,用符合时下潮流的营销手段提高营销利益。传统的客户信息保存手段,不利于美容门店在发起营销活动时,将客户信息直接与营销活动对接,容易造成营销对象选择错误、营销资源投入的浪费。而使用美容小程序,则可以通过开发会员管理系统,实现CRM客户管理与维护,高效率管理价值客户,精准化进行营销。

  对于连锁美容实体门店来说,在管理上受时间、空间限制,容易出现信息传输慢、沟通有误等问题,造成门店信息展示存在误差或不对称的情况。美容小程序中可以开发门店美容小程序功能,实现统一管理美业门店,保证每个门店特色化发展,同时又保障信息展示的同步。

  三、开发价值

  针对用户来说对用户来说,用户在美容小程序中及时了解美容门店的动态信息、产品服务以及美业常识等。并且在使用美容小程序的时候,用户能实时关注美容门店的新品上线活动、优惠促销活动,实时了解优惠活动资讯,参与优惠活动,来带给自己更优惠的价值与利益。针对企业来说对企业来说,美容小程序是通过开发线上管理系统来实现业务管理,能专业系统化塑造行业门店形象,提升美容行业的信誉,帮助美业门店朝品牌化、连锁化发展。通过小程序与其他平台连接,可以拓宽商家的营销渠道,将各个平台的流量引入到小程序中为己所用。

  四、主要功能开发

  1、在线预约时间

  支持用户在线预约美容服务时间,让用户能弹性预约服务,错开服务高峰期,减少耗费时间等待服务的可能,同时也能让加上有一定的服务准备时间,提前做好服务准备。

  2、效果预览

  在美容小程序中展示一些美容和美发的样式供用户参考选择,让客户得以根据样式库来选择自己喜欢的样式进行美容美发服务,通过用户的自主选择来提升服务质量。

  3、社群交流

  针对有共同需求的用户去创建交流社群,帮助商家获取精准客户信息,针对不同需求的客户来实施不同的营销策略,让营销投入能得到更高的回报。并且,通过将有共同需求的客户变成相同社群人员,还能通过客户之间的分享交流,提升用户的活跃度。?

  4、会员管理

  以会员管理功能,来为用户提供建立会员卡、会员优惠券发放、会员积分管理、卡帐管理与监控、财务结算等服务,为商家的针对性维护客户、精准性营销带来可能。

  5、地图导航

  基于LBS技术定位用户所在位置,为用户提供门店位置导航或者附近门店查询服务,让用户能通过线路规划推送或线路导航更快找到门店,同时让附近连锁门店的曝光率提高。

  6、资讯推送

  利用资讯推送功能,将美容小程序的优惠促销信息以及美容行业的知识等资讯推送出去,让优惠内容被更多用户所见,也通过提供小知识来为小程序增值,提高吸引力。

小程序开发推荐深圳素与简科技有限公司(http://www.suyujane.com)多年软件开发经验,海量的开发案例可供参考,看得见的开发经验,让客户更加的省心省力。技术团队都是10年开发工程师,完善的售后服务体系,保障项目开发顺利进行。  
收起阅读 »

【素与简科技】实体店为什么要做小程序?

小程序

实体店为什么要做小程序?

实体店铺面临的各种竞争和成本压力,越来越多的选择采用互联网的模式结合实体店经营。

那么实体店为什么要做小程序呢?小程序能给实体店带来什么好处呢?

深圳素与简科技专业小程序开发,今天为您解答:

一:互联网趋势

近几年互联网的趋势如火如荼,特别是移动互联网的发达,对实体店铺的冲击非常巨大。

实体店各种局限会影响业务发展,必须结合互联网,采用线上线下互通的方式,才能改变颓势。

做APP或者入驻各大平台,都是方式,但越来越多的人选择开发自己的小程序,这是必然的趋势。

二:小程序与大平台的区别

1.成本:

饿了么、美团、大众点评,这类平台,除了入驻费,还有每笔销售高达15%、甚至是20%的佣金;

但是小程序呢,只有前期开发费用,较少的服务费,再无其他费用,更不会抽取实体店的营业佣金。

2.拥有自己的客户

饿了么、美团、大众点评上面来的客户,都是平台自己的,而不是商家的。

但是小程序客户是商家自己的,客户完全属于自己,并且依赖微信平台有更多的裂变方式和客户来源。

3.推广方式

平台的推广费用是非常贵的,并且依赖性很强,竞争激烈。

小程序的推广方式却不一样,可以通过附近小程序功能,好友分享,扫码等等,结合实体店进行有效推广。

三:推广宣传更容易

小程序可以通过附近搜索,完全免费,并且可以使用二维码结合实体店,到店客户可以扫码关注。

并且小程序不需要复杂的步骤就可以很好的让客户使用,结合优惠活动,分享减免等等,裂变起来比较轻松。

四:更好的客户体验,更能留存客户

小程序可以根据扫码支付就自动关注了,并且通过点餐,订餐就已经直接留在客户的微信里。

客户下次使用直接查看用过的小程序就可以轻松找到店铺,使用感受良好,自然留存率更高。

继续阅读 »

实体店为什么要做小程序?

实体店铺面临的各种竞争和成本压力,越来越多的选择采用互联网的模式结合实体店经营。

那么实体店为什么要做小程序呢?小程序能给实体店带来什么好处呢?

深圳素与简科技专业小程序开发,今天为您解答:

一:互联网趋势

近几年互联网的趋势如火如荼,特别是移动互联网的发达,对实体店铺的冲击非常巨大。

实体店各种局限会影响业务发展,必须结合互联网,采用线上线下互通的方式,才能改变颓势。

做APP或者入驻各大平台,都是方式,但越来越多的人选择开发自己的小程序,这是必然的趋势。

二:小程序与大平台的区别

1.成本:

饿了么、美团、大众点评,这类平台,除了入驻费,还有每笔销售高达15%、甚至是20%的佣金;

但是小程序呢,只有前期开发费用,较少的服务费,再无其他费用,更不会抽取实体店的营业佣金。

2.拥有自己的客户

饿了么、美团、大众点评上面来的客户,都是平台自己的,而不是商家的。

但是小程序客户是商家自己的,客户完全属于自己,并且依赖微信平台有更多的裂变方式和客户来源。

3.推广方式

平台的推广费用是非常贵的,并且依赖性很强,竞争激烈。

小程序的推广方式却不一样,可以通过附近小程序功能,好友分享,扫码等等,结合实体店进行有效推广。

三:推广宣传更容易

小程序可以通过附近搜索,完全免费,并且可以使用二维码结合实体店,到店客户可以扫码关注。

并且小程序不需要复杂的步骤就可以很好的让客户使用,结合优惠活动,分享减免等等,裂变起来比较轻松。

四:更好的客户体验,更能留存客户

小程序可以根据扫码支付就自动关注了,并且通过点餐,订餐就已经直接留在客户的微信里。

客户下次使用直接查看用过的小程序就可以轻松找到店铺,使用感受良好,自然留存率更高。

收起阅读 »

iOS平台--离线打包制作自定义基座

iOS平台离线生成自定义基座

1、在原生工程里找到 control.xml文件,在HBuilder节点里查看是否有这2个: debug="true" syncDebug="true" 配置,没有的话增加上,然后保存,如需查看log日志需要将libliblog.a库添加到工程。


2、 确保Xcode工程的Bundle identifier不为 io.dcloud.HBuidler。
3、在原生工程里找到info.plist文件并增加一项,如下图:

4、确保原生工程里Pandora文件夹下的apps文件夹下只有一个文件夹(文件夹的名称和里面js项目的manifest的id值相同)
5、确保control.xml文件里的appid的值和apps目录下的第一个文件夹的名称一致
6、确保HBuilderX里要调试的项目的manifest.json的appid和control.xml的appid值一致
7、使用Xcode的Product下的archive 打包,然后生成ipa,并把ipa名称命名为:iOS_debug.ipa
8、在js工程里主目录下新建一个名称为unpackage的文件夹(如果有不用新建),再在unpackage文件夹下新建一个名称为debug文件夹,并把生成的iOS_debug.ipa包放入debug文件夹。
9、在HBuildX里,找到之前appid相同的js工程准备调试,点击“运行” --“运行到手机或模拟器“--“使用自定义基座运行(iOS)”,等待连接成功之后就可以调试了。

注意:自定义基座包只能用于调试,不能直接上传 App Store,打正式包时请将 第一条说明中 control.xml 中的 debug syncDebug 置为 false 或者直接删除这个两个属性,同时移除 libliblog.a 库。

提示:离线sdk制作的自定义基座不支持在HX中调试,如需调试请使用HX提交自定义基座打包

继续阅读 »

1、在原生工程里找到 control.xml文件,在HBuilder节点里查看是否有这2个: debug="true" syncDebug="true" 配置,没有的话增加上,然后保存,如需查看log日志需要将libliblog.a库添加到工程。


2、 确保Xcode工程的Bundle identifier不为 io.dcloud.HBuidler。
3、在原生工程里找到info.plist文件并增加一项,如下图:

4、确保原生工程里Pandora文件夹下的apps文件夹下只有一个文件夹(文件夹的名称和里面js项目的manifest的id值相同)
5、确保control.xml文件里的appid的值和apps目录下的第一个文件夹的名称一致
6、确保HBuilderX里要调试的项目的manifest.json的appid和control.xml的appid值一致
7、使用Xcode的Product下的archive 打包,然后生成ipa,并把ipa名称命名为:iOS_debug.ipa
8、在js工程里主目录下新建一个名称为unpackage的文件夹(如果有不用新建),再在unpackage文件夹下新建一个名称为debug文件夹,并把生成的iOS_debug.ipa包放入debug文件夹。
9、在HBuildX里,找到之前appid相同的js工程准备调试,点击“运行” --“运行到手机或模拟器“--“使用自定义基座运行(iOS)”,等待连接成功之后就可以调试了。

注意:自定义基座包只能用于调试,不能直接上传 App Store,打正式包时请将 第一条说明中 control.xml 中的 debug syncDebug 置为 false 或者直接删除这个两个属性,同时移除 libliblog.a 库。

提示:离线sdk制作的自定义基座不支持在HX中调试,如需调试请使用HX提交自定义基座打包

收起阅读 »