
我觉得老版的搜索功能要好用一些
不知道为啥现在的搜索是一个很小很小的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的时候,就是说明你已经彻底在开发人的心理只是沦为车架子了!
收起阅读 »
app base64 转本地文件
//将base64编码转换成录音文件
dataURL2Audio (base64Str, callback) {
var myArray=new Array();
var myArray = base64Str.split(";base64,");
// console.log(myArray[1]+"base64Str");
base64Str=myArray[1];
// var base64Str = base64Str.replace('data:audio/amr;base64,', '');
var audioName = (new Date()).valueOf() + '.jpg'; // 替换为要转换的文件名即可
plus.io.requestFileSystem(plus.io.PRIVATE_DOC, function(fs) {
fs.root.getFile(audioName, {
create: true
}, function(entry) {
// 获得平台绝对路径
var fullPath = entry.fullPath;
if(false) {
// 读取音频
var Base64 = plus.android.importClass("android.util.Base64");
var FileOutputStream = plus.android.importClass("java.io.FileOutputStream");
try {
var out = new FileOutputStream(fullPath);
var bytes = Base64.decode(base64Str, Base64.DEFAULT);
console.log(bytes+"-------")
out.write(bytes);
out.close();
// 回调
callback && callback(entry);
} catch(e) {
console.log(e.message);
}
} else if(true) {
var NSData = plus.ios.importClass('NSData');
var nsData = new NSData();
nsData = nsData.initWithBase64EncodedStringoptions(base64Str,0);
nsData.plusCallMethod({writeToFile:fullPath,atomically:true});
plus.ios.deleteObject(nsData);
// 回调
callback && callback(entry);
}
})
})
},
aaa () {
// let base64Str = ''
let base64Str = ''
this.dataURL2Audio(base64Str, (entry) => {
var content = entry.toURL();
console.log(content) // 直接使用
})
},
//将base64编码转换成录音文件
dataURL2Audio (base64Str, callback) {
var myArray=new Array();
var myArray = base64Str.split(";base64,");
// console.log(myArray[1]+"base64Str");
base64Str=myArray[1];
// var base64Str = base64Str.replace('data:audio/amr;base64,', '');
var audioName = (new Date()).valueOf() + '.jpg'; // 替换为要转换的文件名即可
plus.io.requestFileSystem(plus.io.PRIVATE_DOC, function(fs) {
fs.root.getFile(audioName, {
create: true
}, function(entry) {
// 获得平台绝对路径
var fullPath = entry.fullPath;
if(false) {
// 读取音频
var Base64 = plus.android.importClass("android.util.Base64");
var FileOutputStream = plus.android.importClass("java.io.FileOutputStream");
try {
var out = new FileOutputStream(fullPath);
var bytes = Base64.decode(base64Str, Base64.DEFAULT);
console.log(bytes+"-------")
out.write(bytes);
out.close();
// 回调
callback && callback(entry);
} catch(e) {
console.log(e.message);
}
} else if(true) {
var NSData = plus.ios.importClass('NSData');
var nsData = new NSData();
nsData = nsData.initWithBase64EncodedStringoptions(base64Str,0);
nsData.plusCallMethod({writeToFile:fullPath,atomically:true});
plus.ios.deleteObject(nsData);
// 回调
callback && callback(entry);
}
})
})
},
aaa () {
// let base64Str = ''
let base64Str = ''
this.dataURL2Audio(base64Str, (entry) => {
var content = entry.toURL();
console.log(content) // 直接使用
})
},
收起阅读 »

uniapp 集成方法,请求类,分页请求,详情请求,数据渲染,验签请求等方式,让你的开发更简单
文件存储于根目录下common里,当然大家也可以按照自己的想法存储在不同的位置
本集成方法,共设置三个文件依赖md5加密插件
请求接口API模块【api.js】单文件管理接口后期维护成本降低,如更换同一接口地址不用每个文件挨个找了
export const api=($api)=>{
const api={
index:'接口具体参数'
}
return api[$api];
}
集成方法模块【func.js】
此处可以根据个人需求增加所需的方法,让方法可以在多处使用
/* 输出json */
function toJson(option) {
if (typeof(option) == 'object') {
return option;
} else if (typeof(option) == 'string') {
try {
return JSON.parse(option);
} catch (e) {
return option;
}
} else {
return option;
}
}
/** 获取列表数据,支持分页加载*/
function list(othis, param, loading = {
is_loading: false,
loading_title: ''
}, k = 'list', p = 'page', i = 'is_list') {
if (typeof(loading) == 'object' && loading.is_loading == true) {
uni.showLoading({
title: loading.loading_title
})
}
othis.request(param.url, param.data).then(res => {
uni.hideLoading();
othis['is_loading'] = 1;
if (res.code == 1) {
var data = res.data.data;
var page = othis[p];
if (data.length < 1) othis[i] = 0;
var list = page < 2 ? [] : othis[k];
list = list.concat(data);
console.log(list);
othis[k] = list;
uni.stopPullDownRefresh();
} else {
uni.showModal({
title: res.info,
icon: 'none'
})
}
})
}
/**获取详细数据*/
function details(othis, param, k = null, loading = {
is_loading: false,
loading_title: ''
}) {
if (typeof(loading) == 'object' && loading.is_loading == true) {
uni.showLoading({
title: loading.loading_title
})
}
othis.request(param.url, param.data).then(res => {
uni.hideLoading();
othis['is_loading'] = 1;
if (res.code == 1) {
var data = res.data;
if (k == null) {
for (var i in data) {
othis[i] = data[i];
}
} else {
othis[k] = data;
}
} else {
uni.showModal({
title: res.info,
icon: 'none'
})
}
})
}
/**操作请求*/
function action(othis, param, type, confirm, loading = {
is_loading: true,
loading_title: ''
}) {
return new Promise((resolve, reject) => {
if (typeof(confirm) == 'object') {
uni.showModal({
title: confirm.title || '提醒',
content: confirm.content || '确定要操作吗?',
cancelColor: confirm.cancelColor || '#000',
cancelText: confirm.cancelText || '取消',
confirmColor: confirm.confirmColor || '#000',
confirmText: confirm.confirmText || '确认',
success: function(r) {
if (r.confirm) {
do_action(othis, param, type, loading, resolve);
}
}
})
} else {
do_action(othis, param, type, loading, resolve);
}
})
}
function do_action(othis, param, type, loading = {
is_loading: 1,
loading_title: ''
}, resolve) {
if (typeof(loading) == 'object' && loading.is_loading == true) {
uni.showLoading({
title: loading.loading_title
})
}
othis.request(param.url, param.data).then(res => {
uni.hideLoading();
othis['is_loading'] = 1;
if (res.code == 1) {
if (type == undefined || type == '') type = 'back'
var action = ['back', 'remind'];
if (typeof(type) != 'string' || action.indexOf(type) < 0) {
if (typeof(type) != 'object') type = {
type: type
};
var result = Object.assign(type, param, res)
resolve(result);
} else {
if (type == 'back') {
uni.showToast({
title: res.info,
icon: 'none'
})
setTimeout(function() {
uni.navigateBack();
}, 1500)
}
if (type == 'remind') {
uni.showToast({
title: res.info,
icon: 'none'
})
}
}
} else {
uni.showToast({
title: res.info,
icon: 'none'
})
}
})
}
/* 登录 */
function login(othis, link = 'login') {
// #ifdef H5
var pages = getCurrentPages();
var curr_page = pages[pages.length - 1].route;
uni.navigateTo({
url: link
})
uni.setStorageSync('history_page', pages);
// #endif
// #ifdef APP-PLUS
// #endif
// #ifdef MP-WEIXIN
return new Promise((resolve, reject) => {
if(uni.getStorageSync('access_token').length>10){
resolve({code:1,is_login:1})
uni.hideLoading()
return false;
}
var code = uni.getStorageSync('login_code');
uni.login({
success:function(res){
if(code.length<10) code=res.code;
action(othis, {
url: othis.api('wx_' + link),
data: {
code: code
}
}, 'then').then(res => {
uni.showToast({
title: res.info,
icon: 'none'
})
resolve(res);
if (res.code == 1) {
uni.setStorageSync('access_token', res.data.user_token);
}
})
}
})
})
// #endif
}
/* h5 页面登录成功跳转 */
function h5_login(link) {
link = link == undefined ? uni.getStorageSync('history_page') : link;
uni.navigateTo({
url: link
})
}
module.exports = {
toJson: toJson,
fetch: fetch,
list: list,
details: details,
action: action,
login: login
}
请求类库【支持后台验签,让您的数据更安全】
// #ifdef H5
var server = "/";
// #endif
// #ifndef H5
var server = "请求服务器主域";
// #endif
//服务器通过此两个参数验证接口的正确性
const session_id = '服务器加密session_id';
const code = '服务器加密code';
import md5 from '@/js_sdk/js-md5/build/md5.min.js';
import func from '@/common/func.js';
import {api} from '@/common/api.js';
export const _md5=md5;
export const _func=func;
export const _api=api
export const request = (url, data, method) => {
return new Promise((resolve, reject) => {
//生成验签参数
let sign = get_sign(data, code, session_id);
var access_token = uni.getStorageSync('access_token');
var header = {
'content-type': 'application/x-www-form-urlencoded',
sign: sign,
accesstoken: access_token
};
var form_data = data || {};
console.log(form_data);
form_data['at'] = (new Date()).getTime();
uni.request({
url: server + url,
method: method || 'POST',
data: form_data,
header: header,
success: (res) => {
resolve(func.toJson(res.data));
},
fail: (err) => {
console.log(err);
uni.showToast({
title: '嘤嘤嘤!!!网络出错了哦',
icon: 'none'
})
reject(err)
}
})
})
}
export const uploadFile = (url, file, data) => {
return new Promise((resolve, reject) => {
let sign = get_sign(data, code, session_id);
var access_token = uni.getStorageSync('access_token');
var header = {
'Content-Type': 'multipart/form-data',
sign: sign,
accesstoken: access_token
};
uni.uploadFile({
url: server + url,
method: "POST",
header: header,
filePath: file['value'],
name: file['field'],
success: (res) => {
resolve(func.toJson(res.data));
},
fail: (err) => {
uni.showToast({
title: '嘤嘤嘤!!!网络出错了哦',
icon: 'none'
})
reject(err)
}
})
})
}
function get_sign(data, code, session_id) {
var str = '';
for (var a in data) {
str += a + '=' + data[a] + '&';
}
str +=code;
var sign = md5(str);
return session_id + '&' + sign;
}
main.js 设置以下内容
import { request,uploadFile,_md5,_func,_api } from './common/request.js';
Vue.prototype.request= request;
Vue.prototype.uploadFile=uploadFile;
Vue.prototype.md5=_md5;
Vue.prototype.func=_func;
Vue.prototype.api=_api;
这样即可在其他页面调用
请求服务器分页数据仅需要简单代码即可完成
export default {
data() {
return {
page:1,
list:[],
is_list:1
}
},
onLoad() {
this.func.list(this,this.api('index'),{page:this.page})
},
methods: {
}
}
其他方法也是如此请求带弹窗的请求如下
this.func.action(this,
{url:this.api('test'),
data:{abc:'abc'}},'then',{title:'确认提交',content:'提交楼'}).then(res=>{
console.log(res);
})
请求详细数据如下
//接收参数abc直接渲染即可
this.func.details(this,{id:1},'abc');
登录代码,方便开发,也方便直接验证登录操作,如已经登录会直接执行then内方法
this.func.login(this).then(res=>{
console.log(res);
})
文件存储于根目录下common里,当然大家也可以按照自己的想法存储在不同的位置
本集成方法,共设置三个文件依赖md5加密插件
请求接口API模块【api.js】单文件管理接口后期维护成本降低,如更换同一接口地址不用每个文件挨个找了
export const api=($api)=>{
const api={
index:'接口具体参数'
}
return api[$api];
}
集成方法模块【func.js】
此处可以根据个人需求增加所需的方法,让方法可以在多处使用
/* 输出json */
function toJson(option) {
if (typeof(option) == 'object') {
return option;
} else if (typeof(option) == 'string') {
try {
return JSON.parse(option);
} catch (e) {
return option;
}
} else {
return option;
}
}
/** 获取列表数据,支持分页加载*/
function list(othis, param, loading = {
is_loading: false,
loading_title: ''
}, k = 'list', p = 'page', i = 'is_list') {
if (typeof(loading) == 'object' && loading.is_loading == true) {
uni.showLoading({
title: loading.loading_title
})
}
othis.request(param.url, param.data).then(res => {
uni.hideLoading();
othis['is_loading'] = 1;
if (res.code == 1) {
var data = res.data.data;
var page = othis[p];
if (data.length < 1) othis[i] = 0;
var list = page < 2 ? [] : othis[k];
list = list.concat(data);
console.log(list);
othis[k] = list;
uni.stopPullDownRefresh();
} else {
uni.showModal({
title: res.info,
icon: 'none'
})
}
})
}
/**获取详细数据*/
function details(othis, param, k = null, loading = {
is_loading: false,
loading_title: ''
}) {
if (typeof(loading) == 'object' && loading.is_loading == true) {
uni.showLoading({
title: loading.loading_title
})
}
othis.request(param.url, param.data).then(res => {
uni.hideLoading();
othis['is_loading'] = 1;
if (res.code == 1) {
var data = res.data;
if (k == null) {
for (var i in data) {
othis[i] = data[i];
}
} else {
othis[k] = data;
}
} else {
uni.showModal({
title: res.info,
icon: 'none'
})
}
})
}
/**操作请求*/
function action(othis, param, type, confirm, loading = {
is_loading: true,
loading_title: ''
}) {
return new Promise((resolve, reject) => {
if (typeof(confirm) == 'object') {
uni.showModal({
title: confirm.title || '提醒',
content: confirm.content || '确定要操作吗?',
cancelColor: confirm.cancelColor || '#000',
cancelText: confirm.cancelText || '取消',
confirmColor: confirm.confirmColor || '#000',
confirmText: confirm.confirmText || '确认',
success: function(r) {
if (r.confirm) {
do_action(othis, param, type, loading, resolve);
}
}
})
} else {
do_action(othis, param, type, loading, resolve);
}
})
}
function do_action(othis, param, type, loading = {
is_loading: 1,
loading_title: ''
}, resolve) {
if (typeof(loading) == 'object' && loading.is_loading == true) {
uni.showLoading({
title: loading.loading_title
})
}
othis.request(param.url, param.data).then(res => {
uni.hideLoading();
othis['is_loading'] = 1;
if (res.code == 1) {
if (type == undefined || type == '') type = 'back'
var action = ['back', 'remind'];
if (typeof(type) != 'string' || action.indexOf(type) < 0) {
if (typeof(type) != 'object') type = {
type: type
};
var result = Object.assign(type, param, res)
resolve(result);
} else {
if (type == 'back') {
uni.showToast({
title: res.info,
icon: 'none'
})
setTimeout(function() {
uni.navigateBack();
}, 1500)
}
if (type == 'remind') {
uni.showToast({
title: res.info,
icon: 'none'
})
}
}
} else {
uni.showToast({
title: res.info,
icon: 'none'
})
}
})
}
/* 登录 */
function login(othis, link = 'login') {
// #ifdef H5
var pages = getCurrentPages();
var curr_page = pages[pages.length - 1].route;
uni.navigateTo({
url: link
})
uni.setStorageSync('history_page', pages);
// #endif
// #ifdef APP-PLUS
// #endif
// #ifdef MP-WEIXIN
return new Promise((resolve, reject) => {
if(uni.getStorageSync('access_token').length>10){
resolve({code:1,is_login:1})
uni.hideLoading()
return false;
}
var code = uni.getStorageSync('login_code');
uni.login({
success:function(res){
if(code.length<10) code=res.code;
action(othis, {
url: othis.api('wx_' + link),
data: {
code: code
}
}, 'then').then(res => {
uni.showToast({
title: res.info,
icon: 'none'
})
resolve(res);
if (res.code == 1) {
uni.setStorageSync('access_token', res.data.user_token);
}
})
}
})
})
// #endif
}
/* h5 页面登录成功跳转 */
function h5_login(link) {
link = link == undefined ? uni.getStorageSync('history_page') : link;
uni.navigateTo({
url: link
})
}
module.exports = {
toJson: toJson,
fetch: fetch,
list: list,
details: details,
action: action,
login: login
}
请求类库【支持后台验签,让您的数据更安全】
// #ifdef H5
var server = "/";
// #endif
// #ifndef H5
var server = "请求服务器主域";
// #endif
//服务器通过此两个参数验证接口的正确性
const session_id = '服务器加密session_id';
const code = '服务器加密code';
import md5 from '@/js_sdk/js-md5/build/md5.min.js';
import func from '@/common/func.js';
import {api} from '@/common/api.js';
export const _md5=md5;
export const _func=func;
export const _api=api
export const request = (url, data, method) => {
return new Promise((resolve, reject) => {
//生成验签参数
let sign = get_sign(data, code, session_id);
var access_token = uni.getStorageSync('access_token');
var header = {
'content-type': 'application/x-www-form-urlencoded',
sign: sign,
accesstoken: access_token
};
var form_data = data || {};
console.log(form_data);
form_data['at'] = (new Date()).getTime();
uni.request({
url: server + url,
method: method || 'POST',
data: form_data,
header: header,
success: (res) => {
resolve(func.toJson(res.data));
},
fail: (err) => {
console.log(err);
uni.showToast({
title: '嘤嘤嘤!!!网络出错了哦',
icon: 'none'
})
reject(err)
}
})
})
}
export const uploadFile = (url, file, data) => {
return new Promise((resolve, reject) => {
let sign = get_sign(data, code, session_id);
var access_token = uni.getStorageSync('access_token');
var header = {
'Content-Type': 'multipart/form-data',
sign: sign,
accesstoken: access_token
};
uni.uploadFile({
url: server + url,
method: "POST",
header: header,
filePath: file['value'],
name: file['field'],
success: (res) => {
resolve(func.toJson(res.data));
},
fail: (err) => {
uni.showToast({
title: '嘤嘤嘤!!!网络出错了哦',
icon: 'none'
})
reject(err)
}
})
})
}
function get_sign(data, code, session_id) {
var str = '';
for (var a in data) {
str += a + '=' + data[a] + '&';
}
str +=code;
var sign = md5(str);
return session_id + '&' + sign;
}
main.js 设置以下内容
import { request,uploadFile,_md5,_func,_api } from './common/request.js';
Vue.prototype.request= request;
Vue.prototype.uploadFile=uploadFile;
Vue.prototype.md5=_md5;
Vue.prototype.func=_func;
Vue.prototype.api=_api;
这样即可在其他页面调用
请求服务器分页数据仅需要简单代码即可完成
export default {
data() {
return {
page:1,
list:[],
is_list:1
}
},
onLoad() {
this.func.list(this,this.api('index'),{page:this.page})
},
methods: {
}
}
其他方法也是如此请求带弹窗的请求如下
this.func.action(this,
{url:this.api('test'),
data:{abc:'abc'}},'then',{title:'确认提交',content:'提交楼'}).then(res=>{
console.log(res);
})
请求详细数据如下
//接收参数abc直接渲染即可
this.func.details(this,{id:1},'abc');
登录代码,方便开发,也方便直接验证登录操作,如已经登录会直接执行then内方法
this.func.login(this).then(res=>{
console.log(res);
})
收起阅读 »

ios打包后,<image>标签读取不到本地上传的临时图片地址,报404 Not Found
<image :src="imageUrl" @error="loadImgError" @click="choseImage" />
vue-cli 命令创建的项目
@dcloudio/uvm版本 --- 3.8.11 alpha
根据uni.chooseImage上传图片,拿到临时路径放到image标签展示,ios打包后在某些操作下,报如下错误,见附件, @error事件捕获(本地基座调试无发复现)
复现1:一开始给与全部权限,可上传成功,杀掉进程后,重新进入APP上传,image报404
复现2:一开始基于部分图片权限,可上传成功,后续从上传提示中进入手机设置给予全部权限,image报404
解决方法:把@dcloudio/uvm降级到3.8.7
<image :src="imageUrl" @error="loadImgError" @click="choseImage" />
vue-cli 命令创建的项目
@dcloudio/uvm版本 --- 3.8.11 alpha
根据uni.chooseImage上传图片,拿到临时路径放到image标签展示,ios打包后在某些操作下,报如下错误,见附件, @error事件捕获(本地基座调试无发复现)
复现1:一开始给与全部权限,可上传成功,杀掉进程后,重新进入APP上传,image报404
复现2:一开始基于部分图片权限,可上传成功,后续从上传提示中进入手机设置给予全部权限,image报404
解决方法:把@dcloudio/uvm降级到3.8.7
收起阅读 »
6年全栈开发_全职接单_寻求合作机会
个人全职全栈开发,拥有6年丰富开发经验。目前时间充裕,怀着诚意寻求合作机会。
作为个人全职开发者,我熟练掌握vue、uniapp、thinkphp、fastadmin等框架。
另外:还比较擅长原型及UI设计,技能全面覆盖
如果您有开发各端小程序、APP、网页登需求,欢迎随时联系我细聊:V:yzhua006。
个人全职全栈开发,拥有6年丰富开发经验。目前时间充裕,怀着诚意寻求合作机会。
作为个人全职开发者,我熟练掌握vue、uniapp、thinkphp、fastadmin等框架。
另外:还比较擅长原型及UI设计,技能全面覆盖
如果您有开发各端小程序、APP、网页登需求,欢迎随时联系我细聊:V:yzhua006。
收起阅读 »
聚合查询,多表统计数据的demo
个人也是小白,想实现多表统计功能,一直看不懂官方文档,今天找了大佬写了一个demo,有需要的可以了解一下。
我想实现的效果

user表
[
{
"_id": "64c22b3e189f866d65c3d0eb",
"name": "张三",
"sex": 1
},
{
"_id": "64c22b5a337a9f4db7882114",
"name": "王五",
"sex": 1
},
{
"_id": "64c22b5055b337825753d977",
"name": "李娇",
"sex": 0
},
{
"_id": "64c22b6bbd0220bf8c7051c5",
"name": "六花",
"sex": 0
}
]
sp表
[
{
"_id": "64c22cbe99c6246543bbfe9d",
"je": 20,
"name_id": "64c22b5055b337825753d977",
"sp": "李娇的商品1"
},
{
"_id": "64c22ce36e5d2d8f64af3f8e",
"je": 20,
"name_id": "64c22b5a337a9f4db7882114",
"sp": "王五的商品4"
},
{
"_id": "64c22cd97ad52ddc6482f40a",
"je": 20,
"name_id": "64c22b5a337a9f4db7882114",
"sp": "王五的商品2"
},
{
"_id": "64c22c766e5d2d8f64af2804",
"je": 20,
"name_id": "64c22b3e189f866d65c3d0eb",
"sp": "张三的商品2"
},
{
"_id": "64c22cf7f08210d515b35a86",
"je": 20,
"name_id": "64c22b6bbd0220bf8c7051c5",
"sp": "六花的商品1"
},
{
"_id": "64c22cd421821b2af5b6b48a",
"je": 20,
"name_id": "64c22b5a337a9f4db7882114",
"sp": "王五的商品1"
},
{
"_id": "64c22cdf337a9f4db78875c8",
"je": 20,
"name_id": "64c22b5a337a9f4db7882114",
"sp": "王五的商品3"
},
{
"_id": "64c22c71e0ec19bea1b13e15",
"je": 20,
"name_id": "64c22b3e189f866d65c3d0eb",
"sp": "张三的商品1"
},
{
"_id": "64c22cc27ad52ddc6482eecb",
"je": 20,
"name_id": "64c22b5055b337825753d977",
"sp": "李娇的商品2"
},
{
"_id": "64c22c7aa09a9bd68ba01823",
"je": 20,
"name_id": "64c22b3e189f866d65c3d0eb",
"sp": "张三的商品3"
}
]
wz表
[
{
"_id": "64c22f43337a9f4db788fdd8",
"name_id": "64c22b3e189f866d65c3d0eb",
"wzdz": 12,
"wzname": "六花的文章2"
},
{
"_id": "64c22f5ffe975fba5a5e51ef",
"name_id": "64c22b5055b337825753d977",
"wzdz": 34,
"wzname": "李娇的文章2"
},
{
"_id": "64c22f57337a9f4db7890253",
"name_id": "64c22b5055b337825753d977",
"wzdz": 3,
"wzname": "李娇的文章1"
},
{
"_id": "64c22f3ef08210d515b3e212",
"name_id": "64c22b3e189f866d65c3d0eb",
"wzdz": 12,
"wzname": "六花的文章1"
},
{
"_id": "64c22f7b6e5d2d8f64afdba0",
"name_id": "64c22b5a337a9f4db7882114",
"wzdz": 54,
"wzname": "王五的文章2"
},
{
"_id": "64c22f739755e344ab9c51ce",
"name_id": "64c22b5a337a9f4db7882114",
"wzdz": 11,
"wzname": "王五的文章1"
},
{
"_id": "64c235cd466d416d30844f4e",
"name_id": "64c22b5a337a9f4db7882114",
"wzdz": 13,
"wzname": "王五的文章3"
}
]
最终结果
张三 商品3 点赞24
李 商品2 点赞37
王五 商品4 点赞65
六花 商品1 点赞0
聚合查询代码
const db = uniCloud.database()
const dbCmd = db.command
const $ = dbCmd.aggregate
exports.main = async (event, context) => {
const {data}=await db.collection(`user`).aggregate()
.lookup({
from:`sp`,
let:{
user_id:`$_id`,
},
pipeline:$.pipeline()
.match(
dbCmd.expr(
$.eq(['$name_id','$$user_id'])
)
)
.group({
_id:'$name_id',
count: $.sum(1),
})
.done(),
as: 'sp_list',
})
.lookup({
from:`wz`,
let:{
user_id:`$_id`,
},
pipeline:$.pipeline()
.match(
dbCmd.expr(
$.eq(['$name_id','$$user_id'])
)
)
.group({
_id:'$name_id',
wzdz:$.sum('$wzdz'),
})
.done(),
as: 'wz_list',
})
.end();
return {
data:data
}
};
个人也是小白,想实现多表统计功能,一直看不懂官方文档,今天找了大佬写了一个demo,有需要的可以了解一下。
我想实现的效果
user表
[
{
"_id": "64c22b3e189f866d65c3d0eb",
"name": "张三",
"sex": 1
},
{
"_id": "64c22b5a337a9f4db7882114",
"name": "王五",
"sex": 1
},
{
"_id": "64c22b5055b337825753d977",
"name": "李娇",
"sex": 0
},
{
"_id": "64c22b6bbd0220bf8c7051c5",
"name": "六花",
"sex": 0
}
]
sp表
[
{
"_id": "64c22cbe99c6246543bbfe9d",
"je": 20,
"name_id": "64c22b5055b337825753d977",
"sp": "李娇的商品1"
},
{
"_id": "64c22ce36e5d2d8f64af3f8e",
"je": 20,
"name_id": "64c22b5a337a9f4db7882114",
"sp": "王五的商品4"
},
{
"_id": "64c22cd97ad52ddc6482f40a",
"je": 20,
"name_id": "64c22b5a337a9f4db7882114",
"sp": "王五的商品2"
},
{
"_id": "64c22c766e5d2d8f64af2804",
"je": 20,
"name_id": "64c22b3e189f866d65c3d0eb",
"sp": "张三的商品2"
},
{
"_id": "64c22cf7f08210d515b35a86",
"je": 20,
"name_id": "64c22b6bbd0220bf8c7051c5",
"sp": "六花的商品1"
},
{
"_id": "64c22cd421821b2af5b6b48a",
"je": 20,
"name_id": "64c22b5a337a9f4db7882114",
"sp": "王五的商品1"
},
{
"_id": "64c22cdf337a9f4db78875c8",
"je": 20,
"name_id": "64c22b5a337a9f4db7882114",
"sp": "王五的商品3"
},
{
"_id": "64c22c71e0ec19bea1b13e15",
"je": 20,
"name_id": "64c22b3e189f866d65c3d0eb",
"sp": "张三的商品1"
},
{
"_id": "64c22cc27ad52ddc6482eecb",
"je": 20,
"name_id": "64c22b5055b337825753d977",
"sp": "李娇的商品2"
},
{
"_id": "64c22c7aa09a9bd68ba01823",
"je": 20,
"name_id": "64c22b3e189f866d65c3d0eb",
"sp": "张三的商品3"
}
]
wz表
[
{
"_id": "64c22f43337a9f4db788fdd8",
"name_id": "64c22b3e189f866d65c3d0eb",
"wzdz": 12,
"wzname": "六花的文章2"
},
{
"_id": "64c22f5ffe975fba5a5e51ef",
"name_id": "64c22b5055b337825753d977",
"wzdz": 34,
"wzname": "李娇的文章2"
},
{
"_id": "64c22f57337a9f4db7890253",
"name_id": "64c22b5055b337825753d977",
"wzdz": 3,
"wzname": "李娇的文章1"
},
{
"_id": "64c22f3ef08210d515b3e212",
"name_id": "64c22b3e189f866d65c3d0eb",
"wzdz": 12,
"wzname": "六花的文章1"
},
{
"_id": "64c22f7b6e5d2d8f64afdba0",
"name_id": "64c22b5a337a9f4db7882114",
"wzdz": 54,
"wzname": "王五的文章2"
},
{
"_id": "64c22f739755e344ab9c51ce",
"name_id": "64c22b5a337a9f4db7882114",
"wzdz": 11,
"wzname": "王五的文章1"
},
{
"_id": "64c235cd466d416d30844f4e",
"name_id": "64c22b5a337a9f4db7882114",
"wzdz": 13,
"wzname": "王五的文章3"
}
]
最终结果
张三 商品3 点赞24
李 商品2 点赞37
王五 商品4 点赞65
六花 商品1 点赞0
聚合查询代码
const db = uniCloud.database()
const dbCmd = db.command
const $ = dbCmd.aggregate
exports.main = async (event, context) => {
const {data}=await db.collection(`user`).aggregate()
.lookup({
from:`sp`,
let:{
user_id:`$_id`,
},
pipeline:$.pipeline()
.match(
dbCmd.expr(
$.eq(['$name_id','$$user_id'])
)
)
.group({
_id:'$name_id',
count: $.sum(1),
})
.done(),
as: 'sp_list',
})
.lookup({
from:`wz`,
let:{
user_id:`$_id`,
},
pipeline:$.pipeline()
.match(
dbCmd.expr(
$.eq(['$name_id','$$user_id'])
)
)
.group({
_id:'$name_id',
wzdz:$.sum('$wzdz'),
})
.done(),
as: 'wz_list',
})
.end();
return {
data:data
}
};
收起阅读 »

uniapp编译小程序 slot出现将异常
自定义组件中使用了slot插槽,page页使用自定义组件时,将page页面的其他标签元素都渲染进自定义组件插槽
自定义组件中使用了slot插槽,page页使用自定义组件时,将page页面的其他标签元素都渲染进自定义组件插槽

关于HBuilder X打包的APP按返回键退出的问题(解决办法)
前一段时间,我也是被这个问题困扰了很多次,在论坛和百度上也找了很多,只是都没有仔细的说明怎么调用,
今天我在这里给大家说明一下怎么调用
首先先创建一个文件,命名为:houtui.js
放在文件的JS目录里,或者随意,记住路径就行,
js文件内容
document.addEventListener('plusready', function() {
var first = null;
var webview = plus.webview.currentWebview();
plus.key.addEventListener('backbutton', function() {
webview.canBack(function(e) {
if (e.canBack) {
webview.back(); //这里不建议修改自己跳转的路径
} else {
//首次按键,提示‘再按一次退出应用’
if (!first) {
first = new Date().getTime(); //获取第一次点击的时间戳
// console.log('再按一次退出应用');//用自定义toast提示最好
// toast('双击返回键退出应用'); //调用自己写的吐丝提示 函数
plus.nativeUI.toast("再按一次退出应用", {
duration: 'short'
}); //通过H5+ API 调用Android 上的toast 提示框
setTimeout(function() {
first = null;
}, 1000);
} else {
if (new Date().getTime() - first < 1000) { //获取第二次点击的时间戳, 两次之差 小于 1000ms 说明1s点击了两次,
plus.runtime.quit(); //退出应用
}
}
}
})
});
});
之后再H5网站的首页,添加
<body>
<script src=/h5/static/js/houtui01.js></script>
</body>
需要注意的是,你5+app 调用的是 域名链接,就得在网站源码里下载
你要是调用的app,要在HBuilder X设置调用好就行
前一段时间,我也是被这个问题困扰了很多次,在论坛和百度上也找了很多,只是都没有仔细的说明怎么调用,
今天我在这里给大家说明一下怎么调用
首先先创建一个文件,命名为:houtui.js
放在文件的JS目录里,或者随意,记住路径就行,
js文件内容
document.addEventListener('plusready', function() {
var first = null;
var webview = plus.webview.currentWebview();
plus.key.addEventListener('backbutton', function() {
webview.canBack(function(e) {
if (e.canBack) {
webview.back(); //这里不建议修改自己跳转的路径
} else {
//首次按键,提示‘再按一次退出应用’
if (!first) {
first = new Date().getTime(); //获取第一次点击的时间戳
// console.log('再按一次退出应用');//用自定义toast提示最好
// toast('双击返回键退出应用'); //调用自己写的吐丝提示 函数
plus.nativeUI.toast("再按一次退出应用", {
duration: 'short'
}); //通过H5+ API 调用Android 上的toast 提示框
setTimeout(function() {
first = null;
}, 1000);
} else {
if (new Date().getTime() - first < 1000) { //获取第二次点击的时间戳, 两次之差 小于 1000ms 说明1s点击了两次,
plus.runtime.quit(); //退出应用
}
}
}
})
});
});
之后再H5网站的首页,添加
<body>
<script src=/h5/static/js/houtui01.js></script>
</body>
需要注意的是,你5+app 调用的是 域名链接,就得在网站源码里下载
你要是调用的app,要在HBuilder X设置调用好就行
收起阅读 »
nvue 做首页时候,会出现空白
只要在onLoad(){setTimeout(()=>{
uni.switchTab({
url:'/pages/discover_index/index'
})
},1000);} 重新进一次当前启动页就好了
只要在onLoad(){setTimeout(()=>{
uni.switchTab({
url:'/pages/discover_index/index'
})
},1000);} 重新进一次当前启动页就好了

#creatcavascontext这个是小程序的废弃接口
creatcavascontext这个是小程序的废弃接口
https://uniapp.dcloud.net.cn/api/canvas/createCanvasContext.html#createcanvascontext
https://developers.weixin.qq.com/miniprogram/dev/api/canvas/wx.createCanvasContext.html
creatcavascontext这个是小程序的废弃接口
https://uniapp.dcloud.net.cn/api/canvas/createCanvasContext.html#createcanvascontext
https://developers.weixin.qq.com/miniprogram/dev/api/canvas/wx.createCanvasContext.html