- 聚合操作的match阶段,操作符nin后的数组达到100个后开始报错(数组由云数据库_id组成)
相关代码如下: getCustomerInfoWhenReachBottom: function () { let that = this const _ = db.command db.collection('customerInfo') .aggregate() .geoNear({ distanceField: 'distance', // 输出的每个记录中 distance 即是与给定点的距离 spherical: true, near: db.Geo.Point(Number(that.data.longitude), Number(that.data.latitude)), distanceMultiplier: 1 / 1000, //将米换算为千米 key: 'location', // 若只有 location 一个地理位置索引的字段,则不需填 includeLocs: 'location', // 若只有 location 一个是地理位置,则不需填 }) .match({ createTime: _.lt(that.data.refreshTimestamp), distance:_.gte(that.data.currentMaxDistance), _id: _.nin(that.data.customerInfoIdOnScreen) }) .limit(10) .end() .then((data) => { that.data.currentMaxDistance=data.list[data.list.length-1].distance that.setData({ arrayCustomerInfo: that.data.arrayCustomerInfo.concat(data.list) }) for (let index = 0; index <data.list.length; index++) { that.data.customerInfoIdOnScreen.push(data.list[index]._id) } }) }, 其中that.data.customerInfoIdOnScreen是个数组,该数组由云数据库中自动生成的_id组成。 在数组that.data.customerInfoIdOnScreen的长度达到100之前,运行正常,长度达到100后,聚合操作失败。 请问如何解决?
2021-01-16 - 云函数 geoNear() 分页只能输出前100条
代码如下: let res = await db.collection('cars') .aggregate() .geoNear({ distanceField: 'distance', // 输出的每个记录中 distance 即是与给定点的距离 spherical: true, distanceMultiplier: 0.001, near: db.Geo.Point(event.longitude, event.latitude), key: 'location', // 若只有 location 一个地理位置索引的字段,则不需填 includeLocs: 'location', // 若只有 location 一个是地理位置,则不需填 }) .skip((page-1) * pageSize) .limit(pageSize) .lookup({ from: 'shops', localField: 'shopId', foreignField: '_id', as: 'shop', }) .end() 此代码前100条的分页都正常,但是100条之后,返回的都是空数组 想用geoNear()的limit ,可是 geoNear() 只有limit 并没有skip 想把skip和limit 放geoNear前面,但geoNear必须跟在aggregate后面第一个,不然会报错 这个要怎么解决啊?官方是不是给geoNear 少了个skip字段啊?
2019-12-19 - 云开发Aggregate.geoNear聚合查询没有skip?
Aggregate.geoNear(options: Object): AggregateAggregate聚合查询的参数没有skip,请问如何分页查询? [代码]db.collection('users') .aggregate() .skip(5) .end()[代码]是先查出多少条再剔除多少条,如果数据库记录数大于100我就无法拿到100之后的数据了(因为最大只能取100条记录);分页应该是先剔除前几条再查询后面的多少条(skip应该在limit前面) 已解决: result = await db.collection('tableName').aggregate() .geoNear({ distanceField: 'distance', // 输出的每个记录中 distance 即是与给定点的距离 spherical: true, near: db.Geo.Point(lng, lat), query: { id: id, }, //limit: 10 geoNear里面也有limit,我就是加了这个才没达到效果 }).skip(currentPage * 10).limit(10).end()
2019-12-17 - 关于自定义客服会话contact同时兼容自动和人工客服使用
首先,我们知道,可以通过button中的属性open-type="contact",实现小程序用户和小程序所有者客服对话。
2020-08-12 - 云开发 Aggregate返回条数?
云开发 Aggregate返回条数有限制吗?
2020-01-01 - 云开发中 关于 aggregate sort 的性能问题?
打算用 aggregate sort来实现当日排行榜的 ‘总体排名’ 和 ‘超过xxx%的玩家’ ,请问 aggregate sort支持多少数据量的排序,或者说可以使用其他什么方法来实现这个需求
2019-08-12 - 分享一个固定头和列的 table 组件的简单实现
本案案例基于 WePY 实现,大家可根据自身需要进行更改扩展。 代码地址>> 演示 [图片] 演示视频地址>> 实现原理 [图片] 橙色和紫色区域组成了横向滚动的 [代码]scroll-view[代码]。 红色虚线区域是纵向滚动的 [代码]scroll-view[代码]。但由于绿色区域设置了 [代码]pointer-events: none;[代码],即实际只能触摸橙色区域。通过在橙色区域绑定的 [代码]scroll[代码] 事件(纵向),实时设置绿色虚线区域的 [代码]scrollTop[代码]。 紫色区域是固定头部,绿色区域是固定列。左上角的绿色区域是横向与纵向共同固定的区域。 实现要点 绑定了 [代码]scroll[代码] 事件的 [代码]scroll-view[代码] 要指定 [代码]throttle: false[代码],否则回调函数有可能取不到最终位置的 [代码]scrollTop[代码] 值。官方文档目前未提及此属性,参考资料>>。 固定列需要设置 [代码]pointer-events: none;[代码],实现点击穿透。使得 [代码]tbody[代码] 能触发 [代码]scroll[代码] 事件,而不是为固定列也绑定 [代码]scroll[代码] 事件。 找出每列的最大单元格作为该列的宽度,当然你也可以显示设置。 peace out!👋 小程序 Bug 2019.09.03 更新 当将该组件至于 Popup 弹框,且该弹框通过 [代码]visibility: hidden/visible[代码] 切换,那么在 iOS 中,会使固定列([代码].table__fixed-columns[代码])的 [代码]pointer-events: none[代码] 失效。
2019-09-03 - 微信小程序实现多图片的上传。
1.在微信小程序上,实现多图片的上传在wxml文件中实现页面布局。 [图片] [代码]<view style="width:100%;float:left;margin-top:25rpx;margin-left:40rpx;padding-bottom:120rpx;" class="weui-uploader__bd"> <view class="weui-uploader__files"> <block wx:for="{{pics}}" wx:for-item="image" wx:key="item"> <view class="weui-uploader__file"> <image src="../../../images/warehouse/scanCode_delete.png" wx:if="{{image!=''}}" bindtap="img_delete" class="image_view_css" data-index="{{index}}" data-sign="{{disabl}}"></image> <image class="weui-uploader__img" wx:if="{{image!=''}}" src="{{filters.updateImag(httpURL,deURL,image)}}" bindtap="previewImage"></image> </view> </block> </view> <view class="weui-uploader__input-box {{isShow?'true':'hideTrue'}}"> <view class="weui-uploader__input" bindtap="chooseImage" data-sign="{{disabl}}"></view> </view> </view> [代码] 2.这里页面样式的布局实现。 [图片] [图片] [图片] [代码].weui-uploader__bd { margin-bottom: -4px; margin-right: -9px; overflow: hidden; } .weui-uploader__file { float: left; margin-right: 15px; margin-bottom: 9px; } .image_view_css{ width:60rpx; height: 60rpx; position: absolute; z-index: 5; margin-left: 65px; margin-top: -25rpx } .weui-uploader__img { display: block; width: 79px; height: 79px; } .weui-uploader__input-box { float: left; position: relative; margin-right: 9px; margin-bottom: 9px; width: 77px; height: 77px; border: 1px solid #d9d9d9; } .weui-uploader__input-box:before, .weui-uploader__input-box:after { content: " "; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); background-color: #d9d9d9; } .weui-uploader__input-box:before { width: 2px; height: 39.5px; } .weui-uploader__input-box:after { width: 39.5px; height: 2px; } .weui-uploader__input { position: absolute; z-index: 1; top: 0; left: 0; width: 100%; height: 100%; opacity: 0; } .hideTrue { display: none } [代码] 3.在js层的实现中在在data变量中先定义好 pics: [], count: [1, 2, 3], isShow:true, 变量 1)onload的方法中首先要加载 [代码]isShow: (options.isShow == "true" ? true : false) [代码] 2)页面布局形成的为: [图片] 3)在实现图片的选择上传中点击空白的页面增加图片调用执行方法 [图片] 在 图片的上传后success成功返回值中在开发工具上是以http://开头返回图片文路径,手机上返回的是wxfile:// 开头的 [图片] [图片] 4)而实现图片的预览调用的方法是: [代码] previewImage: function (e) { var current = e.target.dataset.src wx.previewImage({ current: current, urls: this.data.pics }) }, [代码] 实现将图片上传到后台的服务器上,在js中调用的方法 //对保存了图片数组pics做一个for循环。 [代码] wx.uploadFile({ url: url + "/WxController/upload", filePath: pics[0], //这里微信的调用方法只能每次上传一张图片所以可以再调用方法前做对数组pics的一个迭代循环。 name: 'file', formData: { coNo: app.globalData.staff.coNo, lastFolder: 'ProdPaperWx' }, dataType: 'json', success: function (res) { if (res.statusCode == 200) { console.log("成功返回值:",res) } } }) [代码] [图片] 后台接口方法/WxController/upload 用java执行 [代码] public Map<String,Object> upload(HttpServletRequest request, @RequestParam(value = "file", required = false) MultipartFile file) throws IOException { Map<String,Object> map=new HashMap<String, Object>(); String msg="",ret="success",path="",type=null; request.setCharacterEncoding("UTF-8"); String coNo=request.getParameter("coNo"); String lastFolder =request.getParameter("lastFolder"); if(!file.isEmpty()){ String fileName = file.getOriginalFilename(); type = fileName.indexOf(".") != -1 ? fileName.substring(fileName.lastIndexOf(".") + 1, fileName.length()) : null; if(type!=null){ if("PNG".equals(type.toUpperCase())||"JPG".equals(type.toUpperCase())) { // 项目在容器中实际发布运行的根路径 String realPath=BaseController.getCustFilePath()+"image/"+coNo+ "/" + lastFolder + "/"; //这图片存放的路径采用了在指定的方式,在BaseController的getCustFilePath()方法中指定好了 File myFilePath = new File(realPath); if (!myFilePath.exists()){//文件夹不存在,生成一个文件夹 myFilePath.mkdirs(); } // 自定义的文件名称 String trueFileName=coNo+String.valueOf(System.currentTimeMillis())+"."+type; // 设置存放图片文件的路径 path=realPath+trueFileName; file.transferTo(new File(path));ret="success";msg=""; }else { msg="不是我们想要的文件类型,请按要求重新上传!";ret="error";path=""; } }else{ msg="文件类型为空!";ret="error";path=""; } }else { msg="没有找到相对应的文件!";ret="error";path=""; } map.put("ret",ret); map.put("msg",msg); map.put("path",path); return map; } [代码] 这里是BaseController类内的一个指定图片存放路径的方法。 [代码]public class BaseController { //客户文件存放路径 public static String getCustFilePath(){ return "D:/lqb/imge/"; } } [代码]
2019-11-15 - 小程序将小程序码与图片结合生成海报分享朋友圈
样例参考(瑞幸咖啡小程序) [图片][图片][图片] 需求分析 服务器端会返回不确认的图片资源到前端 前端将返回的每张图片都要贴上小程序码 将贴上小程序码的图片使用 swiper 组件轮播 用户点击保存时,将图片保存至相册。 至于点击保存如何保存至相册(wx.saveImageToPhotosAlbuml 了解一下,注意一下授权问题即可) 碰到的问题 canvas为原生组件, 而原生组件的层级是最高的,所以页面中的其他组件无论设置 z-index 为多少,都无法盖在原生组件上。 [代码]采用方法: 通过定位,将其移除到不在可视范围,如iphone6 .canvas { position: relative; left: -375px; } [代码] 绘制多张图片时, 一个canvas 标签只能对应画一张图片 (目前我测试的是这样,如有其它方法,欢迎评论交流) [代码]采用方法: 1. html端循环要生成的图片张数,对应循环出多个 canvas 组件,分别设置不同的 canvasId 区分 2. 封装一个绘制海报的函数,返回一个Promise对象,用于后面绘制完所有的图片,统一赋值渲染,避免多次触发数据更新 3. js端 循环执行一次 绘制海豹函数,存于一个数组列表 4. 使用 Promise.all 函数,统一绘制完毕将生产图片路径赋值 html: <canvas v-for="u in m.urlList" :key="u" :canvas-id="'poster'+index" class="canvas" style="width:100%; height:100%;"> </canvas> <swiper :indicator-dots="true" :circular="true" :autoplay="true" indicator-color="rgba(255,255,255,.2)" indicator-active-color="#fff" class="swiper"> <swiper-item v-for="f in m.filePaths" :key="index"> <image :src="f"> </swiper-item> </swiper> js: // 数据 (mpvue 开发) function data(){ return { m : { urlLIst: [ // 图片资源 '/static/poster0.jpg', '/static/poster1.jpg' ], filePaths: [], // 生成图片(贴上小程序码) } } } try { let res = wx.getSystemInfoSync(); // 同步获取系统信息 let w = res.windowWidth; // 手机可用区域宽度 let h = res.windowHeight; // 手机可用区域高度 let codeUrl = '/static/code.jpg'; // 小程序码 let drawList = []; // 用于保存绘制海报图Promise对象 m.urlList.forEach( (u, i)=> { // 传入canvas组件ID,图片路径(测试使用的是本地路径) drawList.push(drawPoster('poster'+i, u, codeUrl)); }) // 统一更新数据 Promise.all(drawList).then((valuse)=>{ m.filePaths = valuse; }); // 封装绘制图片函数 function drawPoster(canvasId, bgUrl, codeUrl){ return new Promise( (resolve, reject) => { // 创建画布实例 let ctx = wx.createCanvasContext(canvasId); // 绘制背景图: 图片路径,x坐标,y坐标,宽,高 ctx.drawImage(bgUrl, 0, 0, w, h); // 绘制小程序码 ctx.drawImage(codeUrl, w-120, h-120, 100, 100); // 绘制 ctx.draw(false, ()=>{ // 该通过函数将canvas绘制导出为图片 wx.canvasToTempFilePath({ x: 0, y: 0, width: w, height: h, canvasId: canvasId, success(res){ resolve(res.tempFilePath); } }); }); } }catch(e){ // 自己封装了一成 wx.$toast(e); } [代码] 最终demo效果图 [图片][图片] 在社区中暂未看到多张海报实现的方案,如果有更好的实现方案,欢迎交流
2019-07-30