
15年开发经验 在线全职接单
熟练掌握ps、ai、php和js技术 设计 ui 网站 app 小程序 桌面都可以做 价格优惠 效果好
手机微信同号: 19939057361
QQ:2238267409
熟练掌握ps、ai、php和js技术 设计 ui 网站 app 小程序 桌面都可以做 价格优惠 效果好
手机微信同号: 19939057361
QQ:2238267409

解决H5环境下echarts tooltip无法显示html的问题
我使用的是目前echarts最新版本5.4.3,安装方式是npm
其他帖子说在main.js中添加以下代码,但本人添加后依旧无效
window.wx = undefined
看了源码之后,发现确实是window.wx的问题,echarts识别为微信环境了。
但为什么已经设置为undefined了还是误判了呢?于是我输出了一下加载顺序,发现main.js中此行代码的执行顺序比echarts初始化晚,但我已经放到第一行了。
什么原因呢,我发现import导入模块的执行顺序比其他代码优先,而echarts是在导入时就执行初始化了,所以不管我写在哪就会比echarts初始化晚。
如何解决呢?那就新建一个自定义模块,在自定义模块中设置window.wx就好了嘛,以下为模块代码:
if(window.wx) {
window.wx = undefined
}
export default {
}
然后在main.js第一行导入该模块,刷新一下,html就正常显示啦。
我使用的是目前echarts最新版本5.4.3,安装方式是npm
其他帖子说在main.js中添加以下代码,但本人添加后依旧无效
window.wx = undefined
看了源码之后,发现确实是window.wx的问题,echarts识别为微信环境了。
但为什么已经设置为undefined了还是误判了呢?于是我输出了一下加载顺序,发现main.js中此行代码的执行顺序比echarts初始化晚,但我已经放到第一行了。
什么原因呢,我发现import导入模块的执行顺序比其他代码优先,而echarts是在导入时就执行初始化了,所以不管我写在哪就会比echarts初始化晚。
如何解决呢?那就新建一个自定义模块,在自定义模块中设置window.wx就好了嘛,以下为模块代码:
if(window.wx) {
window.wx = undefined
}
export default {
}
然后在main.js第一行导入该模块,刷新一下,html就正常显示啦。
收起阅读 »
app升级、整包更新和热更新组件 支持vue3 支持打开安卓、苹果应用市场,wgt静默更新
整包更新和热更新组件 支持vue3 支持打开安卓、苹果应用市场,支持wgt静默更新
ui图是采用uniapp官方更新组件的ui,如不满足需要,可自行替换
一键式检查更新,同时支持整包升级与wgt资源包更新 支持打开安卓自带的应用市场和苹果appstore
好看、实用、可自定义的客户端提示框
支持强制更新,无法退出
支持静默更新,下次启动后更新的内容自动生效
支持覆盖原生tabar,原生导航栏
插件地址 :https://ext.dcloud.net.cn/plugin?id=7286
整包更新和热更新组件 支持vue3 支持打开安卓、苹果应用市场,支持wgt静默更新
ui图是采用uniapp官方更新组件的ui,如不满足需要,可自行替换
一键式检查更新,同时支持整包升级与wgt资源包更新 支持打开安卓自带的应用市场和苹果appstore
好看、实用、可自定义的客户端提示框
支持强制更新,无法退出
支持静默更新,下次启动后更新的内容自动生效
支持覆盖原生tabar,原生导航栏
插件地址 :https://ext.dcloud.net.cn/plugin?id=7286

uni-app中nvue如何隐藏滚动条
之前以为在uniapp中使用滚动只能用scroll-view
后面发现nvue可以使用scrolle
r组件来代替 scroll-view
具体参数uniapp官方 没用,得参考weex文档。
以下是使用代码
<scroller class="scroll-view" scroll-direction="horizontal" :show-scrollbar="false">
<fui-data-tag :options="options" :radius="16" activeBgColor="#226ADC" border-color="#226ADC" active-color="#fff"></fui-data-tag>
</scroller>
之前以为在uniapp中使用滚动只能用scroll-view
后面发现nvue可以使用scrolle
r组件来代替 scroll-view
具体参数uniapp官方 没用,得参考weex文档。
以下是使用代码
<scroller class="scroll-view" scroll-direction="horizontal" :show-scrollbar="false">
<fui-data-tag :options="options" :radius="16" activeBgColor="#226ADC" border-color="#226ADC" active-color="#fff"></fui-data-tag>
</scroller>
收起阅读 »

10年编程经验,主力语言PHP,在线接活,价格优惠,服务好
前后端全能,APP、网站、桌面版,小程序都可以做,需要的加我详谈。
微信: Surzace
QQ: 2238267409
前后端全能,APP、网站、桌面版,小程序都可以做,需要的加我详谈。
微信: Surzace
QQ: 2238267409

大家对uni-app x怎么看
https://uniapp.dcloud.net.cn/uni-app-x/
期待在一两年内 uniapp x 能够成熟可靠 让国内开发者逃离痛苦吧
https://uniapp.dcloud.net.cn/uni-app-x/
期待在一两年内 uniapp x 能够成熟可靠 让国内开发者逃离痛苦吧

H5+ zebra打印机(ZPL指令)打印标签
公司新增一台打印机需求,与之前的打印机指令不一致,需要用到斑马的ZPL指令
之前的打印机由前同事开发,用到的是JPL的打印机,封装的jar包
本次参考了网上的教程,结合之前打印机获取蓝牙设备
可以直接打印结果
打印机:Zebra 斑马打印机 ZD421
手机:PDA - C500 (安卓12)
功能:扫描周围蓝牙设备加入列表,点击未配对设备,自动配对设备,点击已配对设备,进行打印测试
先上html
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>打印测试</title>
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
<link href="../../css/mui.min.css" rel="stylesheet" />
<link rel="stylesheet" type="text/css" href="../../css/GLBcustom.css" />
<link rel="stylesheet" type="text/css" href="../../css/iconfont-download.css" />
<link rel="stylesheet" type="text/css" href="../../css/icons-extra.css" />
<style type="text/css">
#scroll1 {
position: absolute;
z-index: 2;
bottom: 44px;
left: 0;
overflow: hidden;
width: 100%;
}
#scroll2 {
position: absolute;
z-index: 2;
bottom: 44px;
left: 0;
overflow: hidden;
width: 100%;
}
#scroll3 {
position: absolute;
z-index: 2;
bottom: 44px;
left: 0;
overflow: hidden;
width: 100%;
}
/*扫描记录 单独定制样式,不需要分组*/
/* .mui-btn-green, .mui-btn-positive, .mui-btn-success {
border: 1px solid #4cd964 !important;
padding: 2px;
}*/
.mui-popup {
position: fixed;
z-index: 10000;
top: 50%;
left: 50%;
display: none;
overflow: hidden;
width: 80%;
-webkit-transition-property: -webkit-transform,opacity;
transition-property: transform,opacity;
-webkit-transform: translate3d(-50%,-50%,0) scale(1.185);
transform: translate3d(-50%,-50%,0) scale(1.185);
text-align: left;
opacity: 0;
color: #000000;
border-radius: 13px;
}
.mui-popup-inner {
position: relative;
padding:15px;
border-radius: 13px 13px 0 0;
background: rgba(255,255,255,1);
}
.mui-popup-title {
font-size: 15px;
font-weight: 500;
text-align: center;
}
.mui-popup-title+.mui-popup-text {
font-family: inherit;
font-size: 14px;
margin: 5px 0 0;
}
.mui-popup-buttons {
position: relative;
display: -webkit-box;
display: -webkit-flex;
display: flex;
height: 30px;
-webkit-box-pack: center;
-webkit-justify-content: center;
justify-content: center;
}
.mui-popup-button {
font-size: 15px;
line-height: 30px;
position: relative;
display: block;
overflow: hidden;
box-sizing: border-box;
width: 100%;
height: 30px;
padding: 0 5px;
cursor: pointer;
text-align: center;
white-space: nowrap;
text-overflow: ellipsis;
color: #000000;
/*background: rgba(49,112,143,1);*/
background: rgba(255,255,255,1);
-webkit-box-flex: 1;
}
.mui-popup-title{
background-color: transparent !important;
}
.mui-popup-text{
background-color: #FFFFFF;
min-height: 30px;
line-height: 30px;
}
.mui-table-view-cell-a{
padding-left: 10px !important;
}
</style>
</head>
<body>
<div id="bledevice" v-show="hide" class="mui-popup mui-popup-in" style="display: block;">
<div class="mui-popup-inner" style="height: 300px;">
<div class="mui-popup-title">
<span lang='zh-cn' class="i18n" data-textid="选择打印机">选择打印机</span>
</div>
<div class="mui-popup-text" style="position: relative;height: 259px;">
<div id="scroll6" class="mui-scroll-wrapper">
<div class="mui-scroll">
<div class="mui-popup-text">
<span lang='zh-cn' class="i18n" data-textid="已配对设备">已配对设备</span>
</div>
<div class="mui-popup-select">
<ul class="mui-table-view">
<li v-for="obj in bound" class="mui-table-view-cell">
<a class="mui-table-view-cell-a" @click="connect" v-bind:mac="obj.value" v-text="obj.text+' -- '+obj.value">
obj.text
</a>
</li>
</ul>
</div>
<div class="mui-popup-text">
<span lang='zh-cn' class="i18n" data-textid="未配对设备">未配对设备</span>
</div>
<div class="mui-popup-select">
<ul class="mui-table-view">
<li v-for="obj in unbound" class="mui-table-view-cell">
<a class="mui-table-view-cell-a" @click="pairconnect" v-bind:mac="obj.value" v-text="obj.text+' -- '+obj.value">
ss
</a>
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
<div class="mui-popup-buttons">
<span class="mui-popup-button mui-popup-button-bold i18n" data-textid="重新扫描" @click="rescan">重新扫描</span>
<span class="mui-popup-button mui-popup-button-bold i18n" data-textid="关闭" @click="close">关闭</span>
</div>
</div>
<script type="text/javascript" src="../../js/i18n/zh_cn.js" ></script>
<script src="../../js/mui.min.js"></script>
<script src="../../js/mui.picker.js"></script>
<script type="text/javascript" src="../../js/jquery-3.2.1.min.js"></script>
<script type="text/javascript" src="../../js/vue.js"></script>
<script type="text/javascript" src="../../js/app.js"></script>
<script src="../../js/mui.poppicker.js"></script>
<script src="../../js/JPL.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript" src="js/print.js"></script>
<script type="text/javascript">
</script>
</body>
</html>
下面是js文件
mui.init({
swipeBack: false //启用右滑关闭功能
});
var menban = false;
var mask = mui.createMask(function() {
return menban;
}); //callback为用户点击蒙版时自动执行的回调;
//mask.show(); //显示遮罩
var hybird = true; //表示当前是混合开发状态,可以调用java,true,false状态表示是H5,不调用蓝牙
mui.plusReady(function() {
if(hybird){
plus.nativeUI.showWaiting("加载已绑定蓝牙设备");
//获取已绑定设备
var bounded = plus.JPLplugin.getBoundedBleDevice();
bluetooth.bound = bounded.bounded;
plus.nativeUI.closeWaiting();
}
});
var bluetooth = new Vue({
el: '#bledevice',
data: {
hide: true,
mac_address: '',
bound: [],
unbound: [],
},
methods: {
close: function() {
if(hybird){
if(this.mac_address == ''){
mui.toast('请选择一个蓝牙设备');
return;
}else{
this.hide = false;
menban = true;
mask.close();
}
}else{
this.hide = false;
menban = true;
mask.close();
}
},
rescan: function(e) {
//扫描未绑定设备
plus.nativeUI.showWaiting("正在搜索蓝牙设备");
var list = plus.JPLplugin.scanBleDevice();
this.unbound = list.unbonded;
plus.nativeUI.closeWaiting();
},
connect: function(e) {
var target = e.target;
console.log(target.getAttribute('mac'));
this.mac_address = target.getAttribute('mac');
//连接打印机
//plus.nativeUI.showWaiting('正在连接打印机');
plus.nativeUI.showWaiting(_DEVICE_PRINTER_);
setTimeout(function(){
if(!plus.JPLplugin.OpenPrinter(bluetooth.mac_address)) {
//mui.toast("打印机连接失败,请再试一次");
mui.toast(_DEVICE_AGAIN_);
plus.nativeUI.closeWaiting();
return;
}else{
//mui.toast("打印机连接成功");
mui.toast(_DEVICE_SUCCESS_);
plus.nativeUI.closeWaiting();
//document.getElementById('bledevice').style.display = "none";
bluetooth.hide = false;
menban = true;
mask.close();
//连接成功后,获取打印机状态
if(plus.JPLplugin.getPrinterState()){
print();
}
}
},200);
},
pairconnect: function(e) {
var target = e.target;
var flag = plus.JPLplugin.pairBle($(target).attr('mac'));
if(flag) {
this.mac_address = target.getAttribute('mac');
this.hide = false;
menban = true;
mask.close();
$('#search').focus();
} else {
//mui.toast("配对失败");
mui.toast(_DEVICE_FAIL_);
}
}
}
});
function print() {
if (!bluetooth.mac_address) {
mui.toast('请选择蓝牙打印机');
return;
}
main = plus.android.runtimeMainActivity();
BluetoothAdapter = plus.android.importClass("android.bluetooth.BluetoothAdapter");
UUID = plus.android.importClass("java.util.UUID");
uuid = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
BAdapter = BluetoothAdapter.getDefaultAdapter();
device = BAdapter.getRemoteDevice(bluetooth.mac_address);
plus.android.importClass(device);
bluetoothSocket = device.createInsecureRfcommSocketToServiceRecord(uuid);
plus.android.importClass(bluetoothSocket);
if (!bluetoothSocket.isConnected()) {
console.log('检测到设备未连接,尝试连接....');
bluetoothSocket.connect();
}
console.log(bluetoothSocket.isConnected());
if (bluetoothSocket.isConnected()) {
var outputStream = bluetoothSocket.getOutputStream();
plus.android.importClass(outputStream);
var string = "^XA" + //开始标签
"^JMA^LL1800^PW1000^MD10^PR2^PON^LRN^LH0,0" + "\r\n" + //毫米单位 宽
"^FO0,100" + "\r\n" + "^A0,N,50,50" + "\r\n" + "^FDDescription:^FS" + "\r\n" +
"^FO0,180" + "\r\n" + "^A0,N,50,50" + "\r\n" + "^FDGW 40V 2.0Ah 8-in. GEN II Polesaw w/ B&C^FS" + "\r\n" +
"^FO0,350" + "\r\n" + "^A0,N,50,50" + "\r\n" + "^FDITEM#: ^FS" + "\r\n" +
"^FO300,350" + "\r\n" + "^A0,N,50,50" + "\r\n" + "^FD1403702^FS" + "\r\n" +
"^FO00,410^BY3" + "\r\n" + "^BCN,100,Y,N,N" + "\r\n" + "^FD 1403702 ^FS" + "\r\n" +
"^FO0,600" + "\r\n" + "^A0,N,50,50" + "\r\n" + "^FDQTY: ^FS" + "\r\n" +
"^FO400,600" + "\r\n" + "^A0,N,50,50" + "\r\n" + "^FDPCS: ^FS" + "\r\n" +
"^FO00,700" + "\r\n" + "^A0,N,50,50" + "\r\n" + "^FDG.W: ^FS" + "\r\n" +
"^FO400,700" + "\r\n" + "^A0,N,50,50" + "\r\n" + "^FDKGS ^FS" + "\r\n" +
"^FO550,700" + "\r\n" + "^A0,N,50,50" + "\r\n" + "^FDN.W: ^FS" + "\r\n" +
"^FO910,700" + "\r\n" + "^A0,N,50,50" + "\r\n" + "^FDKGS ^FS" + "\r\n" +
"^FO00,800" + "\r\n" + "^A0,N,50,50" + "\r\n" + "^FDMade in China ^FS" + "\r\n" +
"^FO00,900" + "\r\n" + "^A0,N,50,50" + "\r\n" + "^FDPallet Code: PA1122061500000011^FS" + "\r\n" +
"^FO00,1000^BY3" + "\r\n" + "^BCN,200,Y,N,N" + "\r\n" + "^FD PA1122061500000011 ^FS" + "\r\n" +
"^XZ"; //横线
var bytes = plus.android.invoke(string, 'getBytes', 'UTF-8');
outputStream.write(bytes);
outputStream.flush();
device = null //这里关键
bluetoothSocket.close(); //必须关闭蓝牙连接否则意外断开的话打印错误
}
};
mui.back = function() {
var flag = false;
for(var key in item_one.records) {
flag = true;
break;
}
if(flag) {
var btnArray = [_NO_, _YES_];
mui.confirm(_WDDCH_QUIT_CONFIRM_, _NULL_TITLE_, btnArray, function(e) {
if(e.index == 1) { //退出
plus.webview.currentWebview().close();
} else {
//return false;
}
}, 'div');
} else {
plus.webview.currentWebview().close();
}
}
公司新增一台打印机需求,与之前的打印机指令不一致,需要用到斑马的ZPL指令
之前的打印机由前同事开发,用到的是JPL的打印机,封装的jar包
本次参考了网上的教程,结合之前打印机获取蓝牙设备
可以直接打印结果
打印机:Zebra 斑马打印机 ZD421
手机:PDA - C500 (安卓12)
功能:扫描周围蓝牙设备加入列表,点击未配对设备,自动配对设备,点击已配对设备,进行打印测试
先上html
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>打印测试</title>
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
<link href="../../css/mui.min.css" rel="stylesheet" />
<link rel="stylesheet" type="text/css" href="../../css/GLBcustom.css" />
<link rel="stylesheet" type="text/css" href="../../css/iconfont-download.css" />
<link rel="stylesheet" type="text/css" href="../../css/icons-extra.css" />
<style type="text/css">
#scroll1 {
position: absolute;
z-index: 2;
bottom: 44px;
left: 0;
overflow: hidden;
width: 100%;
}
#scroll2 {
position: absolute;
z-index: 2;
bottom: 44px;
left: 0;
overflow: hidden;
width: 100%;
}
#scroll3 {
position: absolute;
z-index: 2;
bottom: 44px;
left: 0;
overflow: hidden;
width: 100%;
}
/*扫描记录 单独定制样式,不需要分组*/
/* .mui-btn-green, .mui-btn-positive, .mui-btn-success {
border: 1px solid #4cd964 !important;
padding: 2px;
}*/
.mui-popup {
position: fixed;
z-index: 10000;
top: 50%;
left: 50%;
display: none;
overflow: hidden;
width: 80%;
-webkit-transition-property: -webkit-transform,opacity;
transition-property: transform,opacity;
-webkit-transform: translate3d(-50%,-50%,0) scale(1.185);
transform: translate3d(-50%,-50%,0) scale(1.185);
text-align: left;
opacity: 0;
color: #000000;
border-radius: 13px;
}
.mui-popup-inner {
position: relative;
padding:15px;
border-radius: 13px 13px 0 0;
background: rgba(255,255,255,1);
}
.mui-popup-title {
font-size: 15px;
font-weight: 500;
text-align: center;
}
.mui-popup-title+.mui-popup-text {
font-family: inherit;
font-size: 14px;
margin: 5px 0 0;
}
.mui-popup-buttons {
position: relative;
display: -webkit-box;
display: -webkit-flex;
display: flex;
height: 30px;
-webkit-box-pack: center;
-webkit-justify-content: center;
justify-content: center;
}
.mui-popup-button {
font-size: 15px;
line-height: 30px;
position: relative;
display: block;
overflow: hidden;
box-sizing: border-box;
width: 100%;
height: 30px;
padding: 0 5px;
cursor: pointer;
text-align: center;
white-space: nowrap;
text-overflow: ellipsis;
color: #000000;
/*background: rgba(49,112,143,1);*/
background: rgba(255,255,255,1);
-webkit-box-flex: 1;
}
.mui-popup-title{
background-color: transparent !important;
}
.mui-popup-text{
background-color: #FFFFFF;
min-height: 30px;
line-height: 30px;
}
.mui-table-view-cell-a{
padding-left: 10px !important;
}
</style>
</head>
<body>
<div id="bledevice" v-show="hide" class="mui-popup mui-popup-in" style="display: block;">
<div class="mui-popup-inner" style="height: 300px;">
<div class="mui-popup-title">
<span lang='zh-cn' class="i18n" data-textid="选择打印机">选择打印机</span>
</div>
<div class="mui-popup-text" style="position: relative;height: 259px;">
<div id="scroll6" class="mui-scroll-wrapper">
<div class="mui-scroll">
<div class="mui-popup-text">
<span lang='zh-cn' class="i18n" data-textid="已配对设备">已配对设备</span>
</div>
<div class="mui-popup-select">
<ul class="mui-table-view">
<li v-for="obj in bound" class="mui-table-view-cell">
<a class="mui-table-view-cell-a" @click="connect" v-bind:mac="obj.value" v-text="obj.text+' -- '+obj.value">
obj.text
</a>
</li>
</ul>
</div>
<div class="mui-popup-text">
<span lang='zh-cn' class="i18n" data-textid="未配对设备">未配对设备</span>
</div>
<div class="mui-popup-select">
<ul class="mui-table-view">
<li v-for="obj in unbound" class="mui-table-view-cell">
<a class="mui-table-view-cell-a" @click="pairconnect" v-bind:mac="obj.value" v-text="obj.text+' -- '+obj.value">
ss
</a>
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
<div class="mui-popup-buttons">
<span class="mui-popup-button mui-popup-button-bold i18n" data-textid="重新扫描" @click="rescan">重新扫描</span>
<span class="mui-popup-button mui-popup-button-bold i18n" data-textid="关闭" @click="close">关闭</span>
</div>
</div>
<script type="text/javascript" src="../../js/i18n/zh_cn.js" ></script>
<script src="../../js/mui.min.js"></script>
<script src="../../js/mui.picker.js"></script>
<script type="text/javascript" src="../../js/jquery-3.2.1.min.js"></script>
<script type="text/javascript" src="../../js/vue.js"></script>
<script type="text/javascript" src="../../js/app.js"></script>
<script src="../../js/mui.poppicker.js"></script>
<script src="../../js/JPL.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript" src="js/print.js"></script>
<script type="text/javascript">
</script>
</body>
</html>
下面是js文件
mui.init({
swipeBack: false //启用右滑关闭功能
});
var menban = false;
var mask = mui.createMask(function() {
return menban;
}); //callback为用户点击蒙版时自动执行的回调;
//mask.show(); //显示遮罩
var hybird = true; //表示当前是混合开发状态,可以调用java,true,false状态表示是H5,不调用蓝牙
mui.plusReady(function() {
if(hybird){
plus.nativeUI.showWaiting("加载已绑定蓝牙设备");
//获取已绑定设备
var bounded = plus.JPLplugin.getBoundedBleDevice();
bluetooth.bound = bounded.bounded;
plus.nativeUI.closeWaiting();
}
});
var bluetooth = new Vue({
el: '#bledevice',
data: {
hide: true,
mac_address: '',
bound: [],
unbound: [],
},
methods: {
close: function() {
if(hybird){
if(this.mac_address == ''){
mui.toast('请选择一个蓝牙设备');
return;
}else{
this.hide = false;
menban = true;
mask.close();
}
}else{
this.hide = false;
menban = true;
mask.close();
}
},
rescan: function(e) {
//扫描未绑定设备
plus.nativeUI.showWaiting("正在搜索蓝牙设备");
var list = plus.JPLplugin.scanBleDevice();
this.unbound = list.unbonded;
plus.nativeUI.closeWaiting();
},
connect: function(e) {
var target = e.target;
console.log(target.getAttribute('mac'));
this.mac_address = target.getAttribute('mac');
//连接打印机
//plus.nativeUI.showWaiting('正在连接打印机');
plus.nativeUI.showWaiting(_DEVICE_PRINTER_);
setTimeout(function(){
if(!plus.JPLplugin.OpenPrinter(bluetooth.mac_address)) {
//mui.toast("打印机连接失败,请再试一次");
mui.toast(_DEVICE_AGAIN_);
plus.nativeUI.closeWaiting();
return;
}else{
//mui.toast("打印机连接成功");
mui.toast(_DEVICE_SUCCESS_);
plus.nativeUI.closeWaiting();
//document.getElementById('bledevice').style.display = "none";
bluetooth.hide = false;
menban = true;
mask.close();
//连接成功后,获取打印机状态
if(plus.JPLplugin.getPrinterState()){
print();
}
}
},200);
},
pairconnect: function(e) {
var target = e.target;
var flag = plus.JPLplugin.pairBle($(target).attr('mac'));
if(flag) {
this.mac_address = target.getAttribute('mac');
this.hide = false;
menban = true;
mask.close();
$('#search').focus();
} else {
//mui.toast("配对失败");
mui.toast(_DEVICE_FAIL_);
}
}
}
});
function print() {
if (!bluetooth.mac_address) {
mui.toast('请选择蓝牙打印机');
return;
}
main = plus.android.runtimeMainActivity();
BluetoothAdapter = plus.android.importClass("android.bluetooth.BluetoothAdapter");
UUID = plus.android.importClass("java.util.UUID");
uuid = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
BAdapter = BluetoothAdapter.getDefaultAdapter();
device = BAdapter.getRemoteDevice(bluetooth.mac_address);
plus.android.importClass(device);
bluetoothSocket = device.createInsecureRfcommSocketToServiceRecord(uuid);
plus.android.importClass(bluetoothSocket);
if (!bluetoothSocket.isConnected()) {
console.log('检测到设备未连接,尝试连接....');
bluetoothSocket.connect();
}
console.log(bluetoothSocket.isConnected());
if (bluetoothSocket.isConnected()) {
var outputStream = bluetoothSocket.getOutputStream();
plus.android.importClass(outputStream);
var string = "^XA" + //开始标签
"^JMA^LL1800^PW1000^MD10^PR2^PON^LRN^LH0,0" + "\r\n" + //毫米单位 宽
"^FO0,100" + "\r\n" + "^A0,N,50,50" + "\r\n" + "^FDDescription:^FS" + "\r\n" +
"^FO0,180" + "\r\n" + "^A0,N,50,50" + "\r\n" + "^FDGW 40V 2.0Ah 8-in. GEN II Polesaw w/ B&C^FS" + "\r\n" +
"^FO0,350" + "\r\n" + "^A0,N,50,50" + "\r\n" + "^FDITEM#: ^FS" + "\r\n" +
"^FO300,350" + "\r\n" + "^A0,N,50,50" + "\r\n" + "^FD1403702^FS" + "\r\n" +
"^FO00,410^BY3" + "\r\n" + "^BCN,100,Y,N,N" + "\r\n" + "^FD 1403702 ^FS" + "\r\n" +
"^FO0,600" + "\r\n" + "^A0,N,50,50" + "\r\n" + "^FDQTY: ^FS" + "\r\n" +
"^FO400,600" + "\r\n" + "^A0,N,50,50" + "\r\n" + "^FDPCS: ^FS" + "\r\n" +
"^FO00,700" + "\r\n" + "^A0,N,50,50" + "\r\n" + "^FDG.W: ^FS" + "\r\n" +
"^FO400,700" + "\r\n" + "^A0,N,50,50" + "\r\n" + "^FDKGS ^FS" + "\r\n" +
"^FO550,700" + "\r\n" + "^A0,N,50,50" + "\r\n" + "^FDN.W: ^FS" + "\r\n" +
"^FO910,700" + "\r\n" + "^A0,N,50,50" + "\r\n" + "^FDKGS ^FS" + "\r\n" +
"^FO00,800" + "\r\n" + "^A0,N,50,50" + "\r\n" + "^FDMade in China ^FS" + "\r\n" +
"^FO00,900" + "\r\n" + "^A0,N,50,50" + "\r\n" + "^FDPallet Code: PA1122061500000011^FS" + "\r\n" +
"^FO00,1000^BY3" + "\r\n" + "^BCN,200,Y,N,N" + "\r\n" + "^FD PA1122061500000011 ^FS" + "\r\n" +
"^XZ"; //横线
var bytes = plus.android.invoke(string, 'getBytes', 'UTF-8');
outputStream.write(bytes);
outputStream.flush();
device = null //这里关键
bluetoothSocket.close(); //必须关闭蓝牙连接否则意外断开的话打印错误
}
};
mui.back = function() {
var flag = false;
for(var key in item_one.records) {
flag = true;
break;
}
if(flag) {
var btnArray = [_NO_, _YES_];
mui.confirm(_WDDCH_QUIT_CONFIRM_, _NULL_TITLE_, btnArray, function(e) {
if(e.index == 1) { //退出
plus.webview.currentWebview().close();
} else {
//return false;
}
}, 'div');
} else {
plus.webview.currentWebview().close();
}
}
收起阅读 »

uni-simple-router 优雅实现服务端控制页面权限动态路由
权限访问管理在日常开发中扮演着重要角色。无论是控制不同角色访问特定页面、模块,还是管理按钮级别的权限,都需要一个灵活的方案来实现。在uni-app
中,我们可以结合uni-simple-router来达成这个目标。
现在我们假设系统中我们有三个不同的角色,分别是:管理员(admin)、经理(manager)和员工(employee)。然后根据不同角色拥有不同的权限来举例详细说明,假设我们有以下三个页面:Dashboard
、UserManagement
和Settings
。
角色权限定义
- 管理员(admin):拥有访问所有页面的权限。
- 经理(manager):可以访问
Dashboard
和UserManagement
页面。 - 员工(employee):只能访问
Dashboard
页面。
定义路由表
当准备让后台控制所有页面权限时,首先需要与后台人员约定好权限数据结构,以便有效管理和控制用户权限。为了简化示例并降低复杂度,我们可以采用一个最简单的示例来演示整个流程。
首先我们可观察到三个用户之间都共享一个名为Dashboard
的页面,但每个用户还有各自专属的页面。
为了实现页面权限的动态管理,我们可以将Dashboard
作为应用的起始静态页面,这意味着所有用户都可以访问它。其他用户专属页面可以在用户完成登录后,通过异步加载的方式动态添加到路由管理器中,从而实现按需加载的效果。
我们先构建最基本的路由表及插件配置如下:
routes.js
import {
__dynamicImportComponent__
} from '@/uni-simple-router'
const Dashboard = __dynamicImportComponent__(`@/pages/dashboard.vue`,{ pageType:`top` })
const Settings = __dynamicImportComponent__(`@/pages/settings.vue`,{ pageType:`top` })
const UserManagement = __dynamicImportComponent__(`@/pages/userManagement.vue`,{ pageType:`top` })
export const NotFound404 = __dynamicImportComponent__(`@/pages/404.vue`,{ pageType:`top` })
export const Login = __dynamicImportComponent__(`@/pages/login.vue`,{ pageType:`top` })
export const routesMap = {
'dashboard':{
path:`/dashboard`,
name:`dashboard`,
component:Dashboard,
},
'settings':{
path:`/settings`,
name:`settings`,
component:Settings,
},
'userManagement':{
path:`/userManagement`,
name:`userManagement`,
component:UserManagement,
},
}
router.js
import {
createRouter
} from '@/uni-simple-router'
import {
NotFound404,
Login
} from '@/router/routes.js'
/**
* 实例化路由插件
*/
const router = createRouter({
platform: process.env.VUE_APP_PLATFORM,
routeNotFound:(to)=> {
return {name:`404`}
},
routes:[
{
path:`/login`,
name:`login`,
component:Login
},
{
path:`/404`,
name:`404`,
component:NotFound404
}
]
})
export default router
在上述配置中,我们实例化了路由插件,并创建了两个基本的路由表:dashboard
和404
。这里,dashboard
是用户登录后访问的起始页面,而404
页面用于展示未授权或无匹配权限时的访问状态,以提供更直观的提示信息。
通过这种设置,当用户成功登录后,系统将自动跳转到dashboard
页面,因为它是应用的起始静态页面,对所有用户开放。而其他用户专属页面将在用户登录后,通过异步加载的方式动态添加到路由管理器中。
当用户尝试访问没有权限的页面时,系统将显示404
页面,提示用户当前操作未被授权或者访问的页面不存在。这样的用户体验能够帮助用户清楚地知道他们的权限范围,并且减少混淆和不必要的请求。
与后端人员约定数据结构
在实际开发中,权限数据结构的复杂程度通常会根据项目的具体情况和需求来进行约定。如果项目涉及多个角色和嵌套路由页面,那么约定的权限数据结构可能会更加复杂。然而,为了简化示例,我们仍然采用最简单的方式来呈现。根据上一步的路由定义,我们可以让后端人员在登录完成后返回如下数据结构:
- 管理员(admin):拥有访问所有页面的权限。
auth:[`dashboard`,`settings`,`userManagement`]
- 经理(manager):可以访问
Dashboard
和UserManagement
页面。auth:[`dashboard`,`userManagement`]
- 员工(employee):只能访问
Dashboard
页面。auth:[`dashboard`]
上面的权限列表是根据路由表的name
字段约定而成,根据不同角色拥有的权限来生成对应的auth
字段。
根据权限名生成对应的路由
如上,我们已经与后台约定好了数据结构,并且也定义了基础的路由结构。现在,我们只需要将对应的路由表根据权限动态加载进路由插件即可。
router.js
import {
createRouter
} from '@/uni-simple-router'
import {
currentUserInfo
} from '@/state.js'
import {
NotFound404,
Login,
addAuthList,
routesMap
} from '@/router/routes.js'
/**
* 实例化路由插件
*/
const router = createRouter({
platform: process.env.VUE_APP_PLATFORM,
routeNotFound:(to)=> {
const authList = currentUserInfo.value.auth
if(authList){
const {locationRawToMatched} = router.initEnvOptions.matcher
addAuthList(router,authList);
const matcher = locationRawToMatched(to)
if( Object.prototype.toString.call(matcher) === `[object Array]` ){
return {...to}
}
}
return {name:`404`}
},
routes:[
{
path:`/login`,
name:`login`,
component:Login
},
{
path:`/404`,
name:`404`,
component:NotFound404
}
]
})
export default router
routes.js
routes.js
中的配置非常简单,我们只需要再额外添加一个函数即可,如下:
export function addAuthList (router,authList){
const {nameToRecordMatcher} = router.initEnvOptions.matcher
for(let i = 0 ;i<authList.length;i++){
const name = authList[i];
const route = routesMap[name];
if(!nameToRecordMatcher(name)){
router.addRoute(route);
}
}
}
uni-simple-router
相比vue-router
确实在动态添加路由方面更加简单,我们已经尽可能地抹平了一些潜在的陷阱,以确保在开发过程中不会因为这些细小问题而扰乱心智。在示例中,我们展示了常规的动态路由页面,包括添加页面、删除页面以及404页面捕捉等功能。如果需要了解更多细节,可以参考该demo,里面包含了完整的演示代码。
最终示例效果展示

权限访问管理在日常开发中扮演着重要角色。无论是控制不同角色访问特定页面、模块,还是管理按钮级别的权限,都需要一个灵活的方案来实现。在uni-app
中,我们可以结合uni-simple-router来达成这个目标。
现在我们假设系统中我们有三个不同的角色,分别是:管理员(admin)、经理(manager)和员工(employee)。然后根据不同角色拥有不同的权限来举例详细说明,假设我们有以下三个页面:Dashboard
、UserManagement
和Settings
。
角色权限定义
- 管理员(admin):拥有访问所有页面的权限。
- 经理(manager):可以访问
Dashboard
和UserManagement
页面。 - 员工(employee):只能访问
Dashboard
页面。
定义路由表
当准备让后台控制所有页面权限时,首先需要与后台人员约定好权限数据结构,以便有效管理和控制用户权限。为了简化示例并降低复杂度,我们可以采用一个最简单的示例来演示整个流程。
首先我们可观察到三个用户之间都共享一个名为Dashboard
的页面,但每个用户还有各自专属的页面。
为了实现页面权限的动态管理,我们可以将Dashboard
作为应用的起始静态页面,这意味着所有用户都可以访问它。其他用户专属页面可以在用户完成登录后,通过异步加载的方式动态添加到路由管理器中,从而实现按需加载的效果。
我们先构建最基本的路由表及插件配置如下:
routes.js
import {
__dynamicImportComponent__
} from '@/uni-simple-router'
const Dashboard = __dynamicImportComponent__(`@/pages/dashboard.vue`,{ pageType:`top` })
const Settings = __dynamicImportComponent__(`@/pages/settings.vue`,{ pageType:`top` })
const UserManagement = __dynamicImportComponent__(`@/pages/userManagement.vue`,{ pageType:`top` })
export const NotFound404 = __dynamicImportComponent__(`@/pages/404.vue`,{ pageType:`top` })
export const Login = __dynamicImportComponent__(`@/pages/login.vue`,{ pageType:`top` })
export const routesMap = {
'dashboard':{
path:`/dashboard`,
name:`dashboard`,
component:Dashboard,
},
'settings':{
path:`/settings`,
name:`settings`,
component:Settings,
},
'userManagement':{
path:`/userManagement`,
name:`userManagement`,
component:UserManagement,
},
}
router.js
import {
createRouter
} from '@/uni-simple-router'
import {
NotFound404,
Login
} from '@/router/routes.js'
/**
* 实例化路由插件
*/
const router = createRouter({
platform: process.env.VUE_APP_PLATFORM,
routeNotFound:(to)=> {
return {name:`404`}
},
routes:[
{
path:`/login`,
name:`login`,
component:Login
},
{
path:`/404`,
name:`404`,
component:NotFound404
}
]
})
export default router
在上述配置中,我们实例化了路由插件,并创建了两个基本的路由表:dashboard
和404
。这里,dashboard
是用户登录后访问的起始页面,而404
页面用于展示未授权或无匹配权限时的访问状态,以提供更直观的提示信息。
通过这种设置,当用户成功登录后,系统将自动跳转到dashboard
页面,因为它是应用的起始静态页面,对所有用户开放。而其他用户专属页面将在用户登录后,通过异步加载的方式动态添加到路由管理器中。
当用户尝试访问没有权限的页面时,系统将显示404
页面,提示用户当前操作未被授权或者访问的页面不存在。这样的用户体验能够帮助用户清楚地知道他们的权限范围,并且减少混淆和不必要的请求。
与后端人员约定数据结构
在实际开发中,权限数据结构的复杂程度通常会根据项目的具体情况和需求来进行约定。如果项目涉及多个角色和嵌套路由页面,那么约定的权限数据结构可能会更加复杂。然而,为了简化示例,我们仍然采用最简单的方式来呈现。根据上一步的路由定义,我们可以让后端人员在登录完成后返回如下数据结构:
- 管理员(admin):拥有访问所有页面的权限。
auth:[`dashboard`,`settings`,`userManagement`]
- 经理(manager):可以访问
Dashboard
和UserManagement
页面。auth:[`dashboard`,`userManagement`]
- 员工(employee):只能访问
Dashboard
页面。auth:[`dashboard`]
上面的权限列表是根据路由表的name
字段约定而成,根据不同角色拥有的权限来生成对应的auth
字段。
根据权限名生成对应的路由
如上,我们已经与后台约定好了数据结构,并且也定义了基础的路由结构。现在,我们只需要将对应的路由表根据权限动态加载进路由插件即可。
router.js
import {
createRouter
} from '@/uni-simple-router'
import {
currentUserInfo
} from '@/state.js'
import {
NotFound404,
Login,
addAuthList,
routesMap
} from '@/router/routes.js'
/**
* 实例化路由插件
*/
const router = createRouter({
platform: process.env.VUE_APP_PLATFORM,
routeNotFound:(to)=> {
const authList = currentUserInfo.value.auth
if(authList){
const {locationRawToMatched} = router.initEnvOptions.matcher
addAuthList(router,authList);
const matcher = locationRawToMatched(to)
if( Object.prototype.toString.call(matcher) === `[object Array]` ){
return {...to}
}
}
return {name:`404`}
},
routes:[
{
path:`/login`,
name:`login`,
component:Login
},
{
path:`/404`,
name:`404`,
component:NotFound404
}
]
})
export default router
routes.js
routes.js
中的配置非常简单,我们只需要再额外添加一个函数即可,如下:
export function addAuthList (router,authList){
const {nameToRecordMatcher} = router.initEnvOptions.matcher
for(let i = 0 ;i<authList.length;i++){
const name = authList[i];
const route = routesMap[name];
if(!nameToRecordMatcher(name)){
router.addRoute(route);
}
}
}
uni-simple-router
相比vue-router
确实在动态添加路由方面更加简单,我们已经尽可能地抹平了一些潜在的陷阱,以确保在开发过程中不会因为这些细小问题而扰乱心智。在示例中,我们展示了常规的动态路由页面,包括添加页面、删除页面以及404页面捕捉等功能。如果需要了解更多细节,可以参考该demo,里面包含了完整的演示代码。
最终示例效果展示
收起阅读 »
我觉得老版的搜索功能要好用一些
不知道为啥现在的搜索是一个很小很小的logo,不说触发很难点击,就算用快捷键搜索了之后,切换回项目列表都变得很难受,老版本的搜索功能不是挺好用的么,不知道为什么非得改的这么不好使,多少有点恶心人了
不知道为啥现在的搜索是一个很小很小的logo,不说触发很难点击,就算用快捷键搜索了之后,切换回项目列表都变得很难受,老版本的搜索功能不是挺好用的么,不知道为什么非得改的这么不好使,多少有点恶心人了

Hbuildx编辑器的问题,望Hbuildx团队能看到
我说Hbuildx的开发团队门,你们能不能把测试周期延长,把问题解决再上线,一个问题解决了,又出现新问题,你们好歹也算是知名企业了,就做出来个这个ide给开发人用????一段代码给我卡崩ide 5-7次,敲个回车换行,光标能给我跑本行代码上边再敲一下跑代码的下一行,你们研发团队写的代码神操作啊!ide代码提示很随意,想出来的时候就出,不想出就不出!要么你就别有这功能!我靠脑子记能记得住!对待自己产品严谨点行不!!!实在不行你们把hbuildx测试交给第三来做也行!咱把用户习惯先不表,望Hbuildx能出来一款能抗能打的产品!现在版本实在是受够一堆堆更新,一堆堆问题!不更吧,安卓这还出问题,更新吧,写代码习惯硬生生被ide问题牵着走!别等全体开发人员只把你当成运行的工具,用vscode编辑的uniapp的时候,就是说明你已经彻底在开发人的心理只是沦为车架子了!
我说Hbuildx的开发团队门,你们能不能把测试周期延长,把问题解决再上线,一个问题解决了,又出现新问题,你们好歹也算是知名企业了,就做出来个这个ide给开发人用????一段代码给我卡崩ide 5-7次,敲个回车换行,光标能给我跑本行代码上边再敲一下跑代码的下一行,你们研发团队写的代码神操作啊!ide代码提示很随意,想出来的时候就出,不想出就不出!要么你就别有这功能!我靠脑子记能记得住!对待自己产品严谨点行不!!!实在不行你们把hbuildx测试交给第三来做也行!咱把用户习惯先不表,望Hbuildx能出来一款能抗能打的产品!现在版本实在是受够一堆堆更新,一堆堆问题!不更吧,安卓这还出问题,更新吧,写代码习惯硬生生被ide问题牵着走!别等全体开发人员只把你当成运行的工具,用vscode编辑的uniapp的时候,就是说明你已经彻底在开发人的心理只是沦为车架子了!
收起阅读 »