HBuilderX

HBuilderX

极客开发工具
uni-app

uni-app

开发一次,多端覆盖
uniCloud

uniCloud

云开发平台
HTML5+

HTML5+

增强HTML5的功能体验
MUI

MUI

上万Star的前端框架

给dcloud官方的一点建议

用户建议

首先来说,我不是来找喷的,我只是希望dcloud越做越好,如有冒犯那就都是我错了。

  1. 建议拥抱开源,而不是疯狂的想把开发者绑定在dcloud的开发环境上。
    • 作为开发者都有自己的开发习惯,和自己喜欢的IDE。比如我是一个全栈,java是主语言,我就带着很多idea的热键习惯去看HBuilder。如果你做不到把ide做的比vs code好或者比idea好,那就试着接受市场的现状。
    • 已经有npm了,那么dcloud的插件市场就显得很多余。而且,你可以认真去看看插件市场的代码质量真的惨不忍睹。同样的,你做不到比npm好用,大厂的前端就不可能给dcloud贡献代码,甚至直接放弃uni-app转手去用cordova。
    • 包管理混乱。傻傻的分不清uni_modles为啥不能用package.json替代。这甚至导致我没办法使用ci工具来完成打包工作,这就又导致用uni-app生态的同学只能局限为外包,难以反哺dcloud社区。而且这种包管理方式非常占用git
继续阅读 »

首先来说,我不是来找喷的,我只是希望dcloud越做越好,如有冒犯那就都是我错了。

  1. 建议拥抱开源,而不是疯狂的想把开发者绑定在dcloud的开发环境上。
    • 作为开发者都有自己的开发习惯,和自己喜欢的IDE。比如我是一个全栈,java是主语言,我就带着很多idea的热键习惯去看HBuilder。如果你做不到把ide做的比vs code好或者比idea好,那就试着接受市场的现状。
    • 已经有npm了,那么dcloud的插件市场就显得很多余。而且,你可以认真去看看插件市场的代码质量真的惨不忍睹。同样的,你做不到比npm好用,大厂的前端就不可能给dcloud贡献代码,甚至直接放弃uni-app转手去用cordova。
    • 包管理混乱。傻傻的分不清uni_modles为啥不能用package.json替代。这甚至导致我没办法使用ci工具来完成打包工作,这就又导致用uni-app生态的同学只能局限为外包,难以反哺dcloud社区。而且这种包管理方式非常占用git
收起阅读 »

app打包后出现拨打电话无反应

APP拨打电话需要勾选两个权限,但文档上只写了一个,对不熟悉app的开发者真是个大坑!
需要添加的另一个权限:<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
希望官方赶紧更新文档!

继续阅读 »

APP拨打电话需要勾选两个权限,但文档上只写了一个,对不熟悉app的开发者真是个大坑!
需要添加的另一个权限:<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
希望官方赶紧更新文档!

收起阅读 »

app中使用subNVue原生子窗体实现全局弹窗,所有页面皆可显示遮罩

定位弹窗 popup 弹窗提示 全局组件

!!!!产品需求描述:

1、所有接口请求时把当前版本号和这个接口是否检查更新参数等加上,后端拿到数据后与当前数据库存储的最新版本号是否一致,不一致则抛错并带有最新版本信息。
2、前端在拦截器中进入判断弹窗弹出流程,(h5页面使用全局组件注册即可,当时以为在App上也可以正常显示,哪知道不行),随即使用subNVue原生子窗体实现。过程中遇到一些问题如下。

!!!!开发过程中问题描述:

1、因在拦截器中做处理,会存在多个请求发出,所以需要定义一个弹窗是否已经显示过弹窗,第一个接口触发版本不对时,未弹起过,则唤起弹窗。反之后面的接口触发版本不对则不再弹起弹窗。
2、注意在index文件中无法获取到最新的vuex内容无法实时更新,所以改用uni.getStorageSync()和uni.setStorageSync(),获取最新的值或内容。
3、subNVue原生子窗体,在每次onLaunch时都会初始化,所以在里面使用vuex数据也是不可靠的。得使用uni.getStorageSync()和uni.setStorageSync(),获取最新的值或内容。
4、2,3条建议用来缓存实现一些不重要比较,变化不频繁的数据。
5、具体更新传递弹窗页面信息,使用页面通信,uni.$on(),uni.$emit()。来实现弹窗内容是最新版本信息。若使用uni.getStorageSync()和uni.setStorageSync(),会导致显示更新内容滞后,显示的其实是上一次的。

此文为实现需求的具体实现思路

1.新建原生子窗体目录文件

a.配置 nvue 文件路径,nvue 文件需放置到使用 subNvue 的页面文件目录下,

b.创建文件,文件路径:pages/subNVue/popup.nvue

2.subNVue 子窗体的 pages.json 配置,建议直接配置在首页路径下,其他配置注意事项查看官方文档

{    
    "pages": [{    
        "path": "pages/index/index", //首页    
        "style": {    
            "app-plus": {    
                "subNVues":[{    
                    "id": "concat", // 唯一标识    
                    "path": "pages/index/subnvue/concat", // 页面路径    
                    /*"type": "popup",  这里不需要*/    
                    "style": {    
                        "position": "absolute",    
                        "dock": "right",    
                        "width": "100rpx",    
                        "height": "150rpx",    
                        "background": "transparent"  //实测在为transparent时,tabbar页面唤起自带遮罩,  
                    }    
                }]    
            }    
        }    
    },  
//放在tabar路径后面  
// #ifdef APP-PLUS  
        {  
            "path": "pages/subnvue/popup",  
            "style": {  
                "navigationBarTitleText": "",  
                "disableScroll": true,  
                "bounce":"none",  
                "navigationStyle": "custom"  
            }  
        },  
// #endif  
    ]    
}

3.在App.vue页面配置,页面注册事件监听方法

onShow: function() {  
            console.log('App Show')  
            // 获取用户信息if  
            // #ifdef APP-PLUS || APP-NVUE  
            // app每次onshow先关闭之前注册的事件监听,然后重新注册  
            uni.$off('popup')  
            // 用于接收原生子窗体页面发出的页面通信事件,用于关闭全局弹窗  
            uni.$on('popup', (data) => {  
                if (!data.isShow) {  
                    const subNVue = uni.getSubNVueById('popup');  
                    subNVue.hide('popup', 300)  
                }  
            })  
            // #endif  
            // #ifdef APP-PLUS  
            hotUpdate.versionAutoUpdate(this.versionCode)//热更新方法  
            // #endif  
        },

4. 拦截器中接口校验到新版本抛错

if (res.statusCode == 412) {  
    // 用于判断是否已经弹过弹窗  
    const isShowPromptPopup = uni.getStorageSync('isShowPromptPopup')  
    // 为第一次检验到,且没有弹过窗走一下校验  
    if (!isShowPromptPopup) {  
        // #ifdef H5  
        setTimeout(() => {  
            promptPopup.open({  
                show: true  
            })  
        }, 1000)  
        // #endif  
        // #ifdef APP-PLUS || APP-NVUE  
        // 处理弹窗title,更新内容  
        let showInfo = {  
            title:'',  
            arr:[],  
            setBac:false  
        }  
        let descCn = res.data.error.desc.split(';')[0]  
        let descEn = res.data.error.desc.split(';')[1]  
        showInfo.title = res.data.error.title  
        if (uni.getStorageSync("lang") == 'ch') {  
            showInfo.arr = descCn.split(',')  
        } else {  
            showInfo.arr = descEn.split(',')  
        }  
        // 在 subNVue/vue 页面触发事件  
        if (store.state.whiteList.findIndex(item => item == route) != -1) {  
                             //因为路由白名单为固定内容,所以可以使用vuex数据,当前路由通过uni的api获取。  
            // 判断路由白名单是否显示遮罩,使用原生子窗体,挂载在tabbar页面的话只能在tabbar页面显示遮罩,这时需要手动控制其他页面额外手动设置遮罩  
            showInfo.setBac = false  
            uni.$emit('subPromptmsg', showInfo);  
        } else {  
            showInfo.setBac = true  
            uni.$emit('subPromptmsg', showInfo);  
        }  
        setTimeout(() => {  
            const subNVue = uni.getSubNVueById('popup');  
            subNVue.show('slide-in-center', 200, () => {})  
        }, 1000)  
        // #endif  
    }  
    uni.setStorageSync('isShowPromptPopup', true)  
    return  
}  

5.原生子窗体页面

<template>  
    <view style="flex-direction: column;align-items: center;justify-content: center;" @click.stop="" :style="setBac?'background-color: rgba(0, 0, 0, 0.5);':''">  
        <view style="width: 540rpx;height: 790rpx;border-radius: 24rpx;" class="">  
            <view style="width: 540rpx;height: 379rpx;">  
                <image style="width: 540rpx;height: 379rpx;" src="../../static/imgs/upDataModel.png"></image>  
            </view>  
            <view  
                style="width: 540rpx;height: 411rpx; background-color: #FFFFFF;border-radius: 0rpx 0rpx 24rpx 24rpx;position: relative;">  
                <view class="" style="flex-direction: row; justify-content: center;">  
                    <view class="title">{{lang == 'ch'?errorInfo.title:'New Version'}}</view>  
                    <view style="width: 32rpx;height: 32rpx;margin-left: 4rpx;">  
                        <image style="width: 32rpx;height: 32rpx;" src="../../static/imgs/upDataTips.png"></image>  
                    </view>  
                </view>  
                <view class="" style="margin-top: 35rpx; padding-left: 50rpx; padding-right: 50rpx;">  
                    <view style="flex-direction: row; width: 440rpx;" v-for="(item,index) in errorInfo.arr" :key="index">  
                        <text class="decs-text" style="width: 18rpx;">{{index 1}}</text>  
                        <text class="decs-text">、</text>  
                        <text class="decs-text" style="width: 400rpx;">{{item}}</text>  
                    </view>  
                </view>  
                <view class="flex_c_m" style="position: absolute;bottom: 40rpx;width: 540rpx;height: max-content;">  
                    <view class="bg-ebuy flex_c_m" style="width: 440rpx; height: 80rpx; border-radius: 10rpx;"  
                        @click="confirmprint">  
                        <text class="btn">{{lang == 'ch'?'立即更新':'Update Now'}}</text>  
                    </view>  
                    <text class="fs-22 pa-t12 fc-999">{{lang == 'ch'?"建议连接wifi更快哦":"It's faster to connect to wifi"}}</text>  
                </view>  
            </view>  
        </view>  
    </view>  
</template>  

<script>  
    import {  
        mapState  
    } from 'vuex';  
    import hotUpdate from '@/js_sdk/hot-update.js'  
    export default {  
        data() {  
            return {  
                setBac:false,  
                errorInfo:{  
                    title:'',  
                    arr:[]  
                }  
            }  
        },  
        computed: {  
            ...mapState({  
                lang: 'lang',  
            }),  
        },  
        created() {  
            // 在 subNVue/vue 页面注册事件监听方法    
            // $on(eventName, callback)    
            // 使用 uni.$off 移除之前事件监听器。  
            uni.$off('subPromptmsg', () => {})    
            // 用于接收拦截器发出的页面通信事件,用于接受拦截器发出的最新版本信息  
            uni.$on('subPromptmsg', (data) => {    
              this.setBac = data.setBac  
              this.errorInfo = data  
            })    
        },  
        methods: {  
            closeShowPopup() {  
                uni.$emit('popup', {  
                    isShow: false,  
                });  
            },  
                         //确认更新  
            confirmprint() {  
                uni.showLoading({  
                    title: this.lang == 'ch' ? '更新中...' : 'updating...'  
                })  
                uni.$emit('popup', {  
                    isShow: false,  
                });  
                hotUpdate.versionAutoUpdate(this.versionCode)  
            }  
        }  
    }  
</script>  

<style>  
    .btn {  
        font-size: 32rpx;  
        font-weight: 500;  
        color: #FFFFFF;  
        line-height: 45rpx;  
    }  

    .title {  
        font-size: 40rpx;  
        font-weight: 600;  
        color: #000000;  
        line-height: 56rpx;  
        /* #ifndef APP-NVUE */  
        letter-spacing: 4rpx;  
        /* #endif */  
    }  

    .decs-text {  
        font-size: 24rpx;  
        font-weight: 500;  
        color: #666666;  
        line-height: 40rpx;  
    }  
</style>  

仅为个人实现需求的方法,如有不对之处。欢迎大家进行审查和指正,并尽可能给出一些反馈和建议,以便改进代码的质量和可用性。

继续阅读 »

!!!!产品需求描述:

1、所有接口请求时把当前版本号和这个接口是否检查更新参数等加上,后端拿到数据后与当前数据库存储的最新版本号是否一致,不一致则抛错并带有最新版本信息。
2、前端在拦截器中进入判断弹窗弹出流程,(h5页面使用全局组件注册即可,当时以为在App上也可以正常显示,哪知道不行),随即使用subNVue原生子窗体实现。过程中遇到一些问题如下。

!!!!开发过程中问题描述:

1、因在拦截器中做处理,会存在多个请求发出,所以需要定义一个弹窗是否已经显示过弹窗,第一个接口触发版本不对时,未弹起过,则唤起弹窗。反之后面的接口触发版本不对则不再弹起弹窗。
2、注意在index文件中无法获取到最新的vuex内容无法实时更新,所以改用uni.getStorageSync()和uni.setStorageSync(),获取最新的值或内容。
3、subNVue原生子窗体,在每次onLaunch时都会初始化,所以在里面使用vuex数据也是不可靠的。得使用uni.getStorageSync()和uni.setStorageSync(),获取最新的值或内容。
4、2,3条建议用来缓存实现一些不重要比较,变化不频繁的数据。
5、具体更新传递弹窗页面信息,使用页面通信,uni.$on(),uni.$emit()。来实现弹窗内容是最新版本信息。若使用uni.getStorageSync()和uni.setStorageSync(),会导致显示更新内容滞后,显示的其实是上一次的。

此文为实现需求的具体实现思路

1.新建原生子窗体目录文件

a.配置 nvue 文件路径,nvue 文件需放置到使用 subNvue 的页面文件目录下,

b.创建文件,文件路径:pages/subNVue/popup.nvue

2.subNVue 子窗体的 pages.json 配置,建议直接配置在首页路径下,其他配置注意事项查看官方文档

{    
    "pages": [{    
        "path": "pages/index/index", //首页    
        "style": {    
            "app-plus": {    
                "subNVues":[{    
                    "id": "concat", // 唯一标识    
                    "path": "pages/index/subnvue/concat", // 页面路径    
                    /*"type": "popup",  这里不需要*/    
                    "style": {    
                        "position": "absolute",    
                        "dock": "right",    
                        "width": "100rpx",    
                        "height": "150rpx",    
                        "background": "transparent"  //实测在为transparent时,tabbar页面唤起自带遮罩,  
                    }    
                }]    
            }    
        }    
    },  
//放在tabar路径后面  
// #ifdef APP-PLUS  
        {  
            "path": "pages/subnvue/popup",  
            "style": {  
                "navigationBarTitleText": "",  
                "disableScroll": true,  
                "bounce":"none",  
                "navigationStyle": "custom"  
            }  
        },  
// #endif  
    ]    
}

3.在App.vue页面配置,页面注册事件监听方法

onShow: function() {  
            console.log('App Show')  
            // 获取用户信息if  
            // #ifdef APP-PLUS || APP-NVUE  
            // app每次onshow先关闭之前注册的事件监听,然后重新注册  
            uni.$off('popup')  
            // 用于接收原生子窗体页面发出的页面通信事件,用于关闭全局弹窗  
            uni.$on('popup', (data) => {  
                if (!data.isShow) {  
                    const subNVue = uni.getSubNVueById('popup');  
                    subNVue.hide('popup', 300)  
                }  
            })  
            // #endif  
            // #ifdef APP-PLUS  
            hotUpdate.versionAutoUpdate(this.versionCode)//热更新方法  
            // #endif  
        },

4. 拦截器中接口校验到新版本抛错

if (res.statusCode == 412) {  
    // 用于判断是否已经弹过弹窗  
    const isShowPromptPopup = uni.getStorageSync('isShowPromptPopup')  
    // 为第一次检验到,且没有弹过窗走一下校验  
    if (!isShowPromptPopup) {  
        // #ifdef H5  
        setTimeout(() => {  
            promptPopup.open({  
                show: true  
            })  
        }, 1000)  
        // #endif  
        // #ifdef APP-PLUS || APP-NVUE  
        // 处理弹窗title,更新内容  
        let showInfo = {  
            title:'',  
            arr:[],  
            setBac:false  
        }  
        let descCn = res.data.error.desc.split(';')[0]  
        let descEn = res.data.error.desc.split(';')[1]  
        showInfo.title = res.data.error.title  
        if (uni.getStorageSync("lang") == 'ch') {  
            showInfo.arr = descCn.split(',')  
        } else {  
            showInfo.arr = descEn.split(',')  
        }  
        // 在 subNVue/vue 页面触发事件  
        if (store.state.whiteList.findIndex(item => item == route) != -1) {  
                             //因为路由白名单为固定内容,所以可以使用vuex数据,当前路由通过uni的api获取。  
            // 判断路由白名单是否显示遮罩,使用原生子窗体,挂载在tabbar页面的话只能在tabbar页面显示遮罩,这时需要手动控制其他页面额外手动设置遮罩  
            showInfo.setBac = false  
            uni.$emit('subPromptmsg', showInfo);  
        } else {  
            showInfo.setBac = true  
            uni.$emit('subPromptmsg', showInfo);  
        }  
        setTimeout(() => {  
            const subNVue = uni.getSubNVueById('popup');  
            subNVue.show('slide-in-center', 200, () => {})  
        }, 1000)  
        // #endif  
    }  
    uni.setStorageSync('isShowPromptPopup', true)  
    return  
}  

5.原生子窗体页面

<template>  
    <view style="flex-direction: column;align-items: center;justify-content: center;" @click.stop="" :style="setBac?'background-color: rgba(0, 0, 0, 0.5);':''">  
        <view style="width: 540rpx;height: 790rpx;border-radius: 24rpx;" class="">  
            <view style="width: 540rpx;height: 379rpx;">  
                <image style="width: 540rpx;height: 379rpx;" src="../../static/imgs/upDataModel.png"></image>  
            </view>  
            <view  
                style="width: 540rpx;height: 411rpx; background-color: #FFFFFF;border-radius: 0rpx 0rpx 24rpx 24rpx;position: relative;">  
                <view class="" style="flex-direction: row; justify-content: center;">  
                    <view class="title">{{lang == 'ch'?errorInfo.title:'New Version'}}</view>  
                    <view style="width: 32rpx;height: 32rpx;margin-left: 4rpx;">  
                        <image style="width: 32rpx;height: 32rpx;" src="../../static/imgs/upDataTips.png"></image>  
                    </view>  
                </view>  
                <view class="" style="margin-top: 35rpx; padding-left: 50rpx; padding-right: 50rpx;">  
                    <view style="flex-direction: row; width: 440rpx;" v-for="(item,index) in errorInfo.arr" :key="index">  
                        <text class="decs-text" style="width: 18rpx;">{{index 1}}</text>  
                        <text class="decs-text">、</text>  
                        <text class="decs-text" style="width: 400rpx;">{{item}}</text>  
                    </view>  
                </view>  
                <view class="flex_c_m" style="position: absolute;bottom: 40rpx;width: 540rpx;height: max-content;">  
                    <view class="bg-ebuy flex_c_m" style="width: 440rpx; height: 80rpx; border-radius: 10rpx;"  
                        @click="confirmprint">  
                        <text class="btn">{{lang == 'ch'?'立即更新':'Update Now'}}</text>  
                    </view>  
                    <text class="fs-22 pa-t12 fc-999">{{lang == 'ch'?"建议连接wifi更快哦":"It's faster to connect to wifi"}}</text>  
                </view>  
            </view>  
        </view>  
    </view>  
</template>  

<script>  
    import {  
        mapState  
    } from 'vuex';  
    import hotUpdate from '@/js_sdk/hot-update.js'  
    export default {  
        data() {  
            return {  
                setBac:false,  
                errorInfo:{  
                    title:'',  
                    arr:[]  
                }  
            }  
        },  
        computed: {  
            ...mapState({  
                lang: 'lang',  
            }),  
        },  
        created() {  
            // 在 subNVue/vue 页面注册事件监听方法    
            // $on(eventName, callback)    
            // 使用 uni.$off 移除之前事件监听器。  
            uni.$off('subPromptmsg', () => {})    
            // 用于接收拦截器发出的页面通信事件,用于接受拦截器发出的最新版本信息  
            uni.$on('subPromptmsg', (data) => {    
              this.setBac = data.setBac  
              this.errorInfo = data  
            })    
        },  
        methods: {  
            closeShowPopup() {  
                uni.$emit('popup', {  
                    isShow: false,  
                });  
            },  
                         //确认更新  
            confirmprint() {  
                uni.showLoading({  
                    title: this.lang == 'ch' ? '更新中...' : 'updating...'  
                })  
                uni.$emit('popup', {  
                    isShow: false,  
                });  
                hotUpdate.versionAutoUpdate(this.versionCode)  
            }  
        }  
    }  
</script>  

<style>  
    .btn {  
        font-size: 32rpx;  
        font-weight: 500;  
        color: #FFFFFF;  
        line-height: 45rpx;  
    }  

    .title {  
        font-size: 40rpx;  
        font-weight: 600;  
        color: #000000;  
        line-height: 56rpx;  
        /* #ifndef APP-NVUE */  
        letter-spacing: 4rpx;  
        /* #endif */  
    }  

    .decs-text {  
        font-size: 24rpx;  
        font-weight: 500;  
        color: #666666;  
        line-height: 40rpx;  
    }  
</style>  

仅为个人实现需求的方法,如有不对之处。欢迎大家进行审查和指正,并尽可能给出一些反馈和建议,以便改进代码的质量和可用性。

收起阅读 »

Dcloud 一键认证常见问题

一键登录

Dcloud 一键认证常见问题

一、基础问题

1.隐私政策声明参考

https://ask.dcloud.net.cn/article/39484

2.错误码:-20102,"errMsg": "preLogin:fail -20102其他错误","errCode": 30004, "code": 30004

Android:证书签名和添加应用时候的签名不一样,直接用最新生成的证书中这个签名,提交应用
Ios: 包名不对应;重新打自定义基座

3.错误码:-10003,"errMsg": "preLogin:fail -10003预登录失败","errCode": 30005,"code": 30005

网络问题,关闭然后打开飞行模式,或者使用4g网络重新试下

4.错误码:-20203,{"errMsg": "login: fail-20203预登录失败”,"errCode": 30005 "code": 30005},未能获取当前用户信息:当前用户为匿名身份

不支持的运营商。OneLogin 仅支持在大陆地区支持三大运营商。
必须使用真机调试,模拟器没有手机卡,是不能获取到运营商信息的

5.msg=参数错误, result=40032

排查一下token ,对应的token不对

继续阅读 »

Dcloud 一键认证常见问题

一、基础问题

1.隐私政策声明参考

https://ask.dcloud.net.cn/article/39484

2.错误码:-20102,"errMsg": "preLogin:fail -20102其他错误","errCode": 30004, "code": 30004

Android:证书签名和添加应用时候的签名不一样,直接用最新生成的证书中这个签名,提交应用
Ios: 包名不对应;重新打自定义基座

3.错误码:-10003,"errMsg": "preLogin:fail -10003预登录失败","errCode": 30005,"code": 30005

网络问题,关闭然后打开飞行模式,或者使用4g网络重新试下

4.错误码:-20203,{"errMsg": "login: fail-20203预登录失败”,"errCode": 30005 "code": 30005},未能获取当前用户信息:当前用户为匿名身份

不支持的运营商。OneLogin 仅支持在大陆地区支持三大运营商。
必须使用真机调试,模拟器没有手机卡,是不能获取到运营商信息的

5.msg=参数错误, result=40032

排查一下token ,对应的token不对

收起阅读 »

uni.push后台配置ios证书一直报证书环境错误排除方案

Push

如果您在使用uni-push配置iOS证书时遇到了证书环境错误的问题,可能是因为以下原因之一:

证书文件格式不正确:证书文件应该是PEM格式或P12格式。如果您的证书文件不是这两种格式,就会导致证书环境错误。

证书文件密码错误:如果您的证书文件设置了密码,并且您在配置证书时输入了错误的密码,就会导致证书环境错误。

证书文件与App ID不匹配:在配置iOS证书时,需要确保证书文件与您的App ID匹配。如果证书文件与App ID不匹配,就会导致证书环境错误。

针对这些问题,您可以尝试以下解决方案:

检查证书文件格式是否正确:您可以通过打开证书文件并查看其内容,来确定证书文件的格式。如果证书文件不是PEM格式或P12格式,可以尝试将其转换为正确的格式。

确认证书文件密码是否正确:如果您在配置证书时输入了密码,可以尝试重新输入密码,并确保密码正确。

确认证书文件与App ID是否匹配:您可以登录苹果开发者中心,检查您的证书文件是否与App ID匹配。如果不匹配,可以尝试重新生成证书文件。

除此之外,您还可以尝试在UniPush后台重新上传证书文件,或者联系UniPush官方客服获取进一步帮助。

继续阅读 »

如果您在使用uni-push配置iOS证书时遇到了证书环境错误的问题,可能是因为以下原因之一:

证书文件格式不正确:证书文件应该是PEM格式或P12格式。如果您的证书文件不是这两种格式,就会导致证书环境错误。

证书文件密码错误:如果您的证书文件设置了密码,并且您在配置证书时输入了错误的密码,就会导致证书环境错误。

证书文件与App ID不匹配:在配置iOS证书时,需要确保证书文件与您的App ID匹配。如果证书文件与App ID不匹配,就会导致证书环境错误。

针对这些问题,您可以尝试以下解决方案:

检查证书文件格式是否正确:您可以通过打开证书文件并查看其内容,来确定证书文件的格式。如果证书文件不是PEM格式或P12格式,可以尝试将其转换为正确的格式。

确认证书文件密码是否正确:如果您在配置证书时输入了密码,可以尝试重新输入密码,并确保密码正确。

确认证书文件与App ID是否匹配:您可以登录苹果开发者中心,检查您的证书文件是否与App ID匹配。如果不匹配,可以尝试重新生成证书文件。

除此之外,您还可以尝试在UniPush后台重新上传证书文件,或者联系UniPush官方客服获取进一步帮助。

收起阅读 »

plus.runtime.launchApplication安卓调用其他app code为-99

h5+

plus.runtime.launchApplication 是在 HBuilderX 开发环境中的 mui 扩展 API,用于调用其他应用程序。code -99 的返回值通常表示应用程序未能成功启动。

这个问题可能是由以下原因导致的:

您可能没有将要启动的应用程序正确地安装在您的设备上。请检查应用程序是否已成功安装,并且您正在调用正确的应用程序包名。

应用程序可能需要特定的权限才能启动。如果您的应用程序需要这些权限,请确保在 AndroidManifest.xml 文件中声明了这些权限。

应用程序可能需要更高的安卓版本才能运行。请检查您的设备是否满足应用程序的最低版本要求。

您可能正在调用一个无效的应用程序 URI。请确保您正在使用正确的 URI,并且您正在调用支持 URI 的应用程序。

您可以通过调用应用程序的 URI 来启动应用程序,如下所示:

var uri = "weixin://";  
mui.plusReady(function() {  
  plus.runtime.launchApplication({  
    action: uri  
  }, function(e) {  
    console.log("启动失败");  
    console.log(JSON.stringify(e));  
  });  
});

我们调用微信应用程序。您可以根据需要更改 URI。如果应用程序已安装且可用,它应该会启动。如果应用程序未能启动,请检查您的应用程序是否存在以上列出的问题。

继续阅读 »

plus.runtime.launchApplication 是在 HBuilderX 开发环境中的 mui 扩展 API,用于调用其他应用程序。code -99 的返回值通常表示应用程序未能成功启动。

这个问题可能是由以下原因导致的:

您可能没有将要启动的应用程序正确地安装在您的设备上。请检查应用程序是否已成功安装,并且您正在调用正确的应用程序包名。

应用程序可能需要特定的权限才能启动。如果您的应用程序需要这些权限,请确保在 AndroidManifest.xml 文件中声明了这些权限。

应用程序可能需要更高的安卓版本才能运行。请检查您的设备是否满足应用程序的最低版本要求。

您可能正在调用一个无效的应用程序 URI。请确保您正在使用正确的 URI,并且您正在调用支持 URI 的应用程序。

您可以通过调用应用程序的 URI 来启动应用程序,如下所示:

var uri = "weixin://";  
mui.plusReady(function() {  
  plus.runtime.launchApplication({  
    action: uri  
  }, function(e) {  
    console.log("启动失败");  
    console.log(JSON.stringify(e));  
  });  
});

我们调用微信应用程序。您可以根据需要更改 URI。如果应用程序已安装且可用,它应该会启动。如果应用程序未能启动,请检查您的应用程序是否存在以上列出的问题。

收起阅读 »

无货源电商玩法赚钱新方式!比淘宝还赚钱

话不多说,上干货——

想美团无货源开店的老板请咨询v:hiwang01
常见的线上轻创业项目有下面几种:

1.微商

微商基本是最早的大众轻创业项目了。

微商又能分为两类:

一类是把自有产品放到线上售卖,这种适合自己有稳定货源的朋友来做;

另一类是加盟微商,比如经常看到的某某品牌护肤品、某某品牌减肥产品等,这种适合没有一手货源的朋友。

大家在做微商时,需要注意考察产品品质和供应商。经营生意其实是经营客户对自己的信任度,所以一定要选质量有保证、用户口碑好的产品。

想美团无货源开店的老板请咨询v:hiwang01
2.团购

由于疫情的影响,社区团购成为了一个新型的产业。如果你身边有很集中的客户群体,可以考虑做社区团购,集中服务身边的一批用户。

另外还有一种全国范围内的团购产业,团长在线上开店,把微信好友召集到自己的社群里,推广线上的一些产品。

3.保险金融

这一类涉及到比较专业的知识和fl规则,要慎重选择

4.直播或短视频带货

比如李佳琦、薇娅等,现在也有很多商家也加入了直播卖货。

5.自媒体变现

例如各路网红、博主,以及很多的素人vlog主等

6.知识变现

知识变现,顾名思义就是把你的知识变成钱。

!!!划重点:这里说的知识,并不是单指我们从书本上学到的知识,而是指我们生活中的一切技能、特长。

想美团无货源开店的老板请咨询v:hiwang01
有人会写作,他可以发挥技能投稿挣钱,也可以把写作的技能交给他人从而变现;

有人会做饭,他可以教别人怎样能做出色香味俱全的美食,也可以研究食物怎样搭配更加营养健康;

有人把自己拾掇的美美的非常精致,她可以分享自己的穿搭、护肤经验,做成自己的产品来赚钱……

记住一句话:你觉得易如反掌的事情,一定会有很多人望尘莫及!所有你的特长和优势,都可以变成

想美团无货源开店的老板请咨询v:hiwang01

继续阅读 »

话不多说,上干货——

想美团无货源开店的老板请咨询v:hiwang01
常见的线上轻创业项目有下面几种:

1.微商

微商基本是最早的大众轻创业项目了。

微商又能分为两类:

一类是把自有产品放到线上售卖,这种适合自己有稳定货源的朋友来做;

另一类是加盟微商,比如经常看到的某某品牌护肤品、某某品牌减肥产品等,这种适合没有一手货源的朋友。

大家在做微商时,需要注意考察产品品质和供应商。经营生意其实是经营客户对自己的信任度,所以一定要选质量有保证、用户口碑好的产品。

想美团无货源开店的老板请咨询v:hiwang01
2.团购

由于疫情的影响,社区团购成为了一个新型的产业。如果你身边有很集中的客户群体,可以考虑做社区团购,集中服务身边的一批用户。

另外还有一种全国范围内的团购产业,团长在线上开店,把微信好友召集到自己的社群里,推广线上的一些产品。

3.保险金融

这一类涉及到比较专业的知识和fl规则,要慎重选择

4.直播或短视频带货

比如李佳琦、薇娅等,现在也有很多商家也加入了直播卖货。

5.自媒体变现

例如各路网红、博主,以及很多的素人vlog主等

6.知识变现

知识变现,顾名思义就是把你的知识变成钱。

!!!划重点:这里说的知识,并不是单指我们从书本上学到的知识,而是指我们生活中的一切技能、特长。

想美团无货源开店的老板请咨询v:hiwang01
有人会写作,他可以发挥技能投稿挣钱,也可以把写作的技能交给他人从而变现;

有人会做饭,他可以教别人怎样能做出色香味俱全的美食,也可以研究食物怎样搭配更加营养健康;

有人把自己拾掇的美美的非常精致,她可以分享自己的穿搭、护肤经验,做成自己的产品来赚钱……

记住一句话:你觉得易如反掌的事情,一定会有很多人望尘莫及!所有你的特长和优势,都可以变成

想美团无货源开店的老板请咨询v:hiwang01

收起阅读 »

美团无货源店铺怎么开-美团不用囤货的创业模式-很赚钱

在美团上开个店铺可能一般人都会认为需要线下店铺先开起来才能开美团线上店铺,其实不然,美团无货源店铺模式正是弥补了这个缺点,让更多想要创业想要在美团上开店的人们有了开店的保障,也因为无货源的模式让更多的商家们减少了运营成本,房租、水电、囤货、甚至人员成本等都得到了节约。

降本增效说的就是这样的方式。

美团无货源创业开店

美团无货源店铺怎么开?

智慧云仓采用云仓建设的方式在全国成本热门商圈位置建设,建设好之后美团上的发货就有云仓直接配送到需求者手中,而我们则需要在想要的城市周围开设一个美团店铺即可。

这样一来囤货这一个大部分商家头疼的问题就基本上得到解决。

云仓囤货降低商家囤货成本

无货源店铺如何进行运营,现在无货源店铺越来越多,怎么才能抢占商机?

美团创业上的对手就是其他商家,而现在大部分的商家都是拥有实体店,很多商家都是线上线下一起运营,这样她所下的功夫就是二分之一,各占一半,甚至因为线下实体店收拾起来比较费时间的时候线上的美团店铺就基本不管。这些的商家就会被我们给后来居上,因为我们运营一个店铺所花费的时间要比其他人多得多,那我们的美团店铺就能后来居上成为佼佼者。

美团店铺的运营说白点就是细节比较重要,市面上一大堆什么美团运营技巧,很多人看了就是看了都不会仔细对自己的店铺认真打理,智慧云仓运营细节才会使让商家店铺比较好。

美团不用囤货的方式可以录用餐饮、美妆、医药、奶茶、百货等。

美团无货源店铺创业V:hiwang01

美团外卖送啥都快

美团与其他平台相比送货更加实时,如美团与某宝、某东、某多相比,同件物品或者餐饮都要快的多,用户选择肯定是选择更加快的一方,而不是等个几天才能收到的。

想美团无货源开店的老板请咨询v:hiwang01

阅读我的更多文章

继续阅读 »

在美团上开个店铺可能一般人都会认为需要线下店铺先开起来才能开美团线上店铺,其实不然,美团无货源店铺模式正是弥补了这个缺点,让更多想要创业想要在美团上开店的人们有了开店的保障,也因为无货源的模式让更多的商家们减少了运营成本,房租、水电、囤货、甚至人员成本等都得到了节约。

降本增效说的就是这样的方式。

美团无货源创业开店

美团无货源店铺怎么开?

智慧云仓采用云仓建设的方式在全国成本热门商圈位置建设,建设好之后美团上的发货就有云仓直接配送到需求者手中,而我们则需要在想要的城市周围开设一个美团店铺即可。

这样一来囤货这一个大部分商家头疼的问题就基本上得到解决。

云仓囤货降低商家囤货成本

无货源店铺如何进行运营,现在无货源店铺越来越多,怎么才能抢占商机?

美团创业上的对手就是其他商家,而现在大部分的商家都是拥有实体店,很多商家都是线上线下一起运营,这样她所下的功夫就是二分之一,各占一半,甚至因为线下实体店收拾起来比较费时间的时候线上的美团店铺就基本不管。这些的商家就会被我们给后来居上,因为我们运营一个店铺所花费的时间要比其他人多得多,那我们的美团店铺就能后来居上成为佼佼者。

美团店铺的运营说白点就是细节比较重要,市面上一大堆什么美团运营技巧,很多人看了就是看了都不会仔细对自己的店铺认真打理,智慧云仓运营细节才会使让商家店铺比较好。

美团不用囤货的方式可以录用餐饮、美妆、医药、奶茶、百货等。

美团无货源店铺创业V:hiwang01

美团外卖送啥都快

美团与其他平台相比送货更加实时,如美团与某宝、某东、某多相比,同件物品或者餐饮都要快的多,用户选择肯定是选择更加快的一方,而不是等个几天才能收到的。

想美团无货源开店的老板请咨询v:hiwang01

阅读我的更多文章

收起阅读 »

美团无货源电商可以做预制菜和成人用品你知道吗?

今天我用最简单的方式讲一下“无货源电商”到底是个什么意思。真正想了解的,一定要仔细阅读完,你不做,了解一下也是很好的电商谈资。

无货源电商:只是说店主不需囤货、压货,而不是说不需要货源。所以我觉得叫“零库存电商”更加贴切一些。想美团无货源开店的老板请咨询v:hiwang01


无货源电商有两种模式:

1、一件代发

这个比较好理解,就是找一个供应商(最好是源头供应商,能确保货源充足和低价),和他们谈妥,你负责卖货,他负责帮你发货。你从中赚取差价利润。

2、倒卖想美团无货源开店的老板请咨询v:hiwang01

在别人不知情的情况下,把人家在网上出售的商品搬到你自己店里,加一点利润开卖。这种方式会涉及到一些问题,比如产品图片可能会被投诉侵权,等你卖出了,你的上家突然提价了,或者售后服务得不到保障。

想美团无货源开店的老板请咨询v:hiwang01
所以现在倒卖的模式已经很难做了,我们就此略过。

下面详细说一下“一件代发”模式

什么人适合做“一件代发”的生意?

1、想兼职增加收入的人

2、对开网店感兴趣的人

3、网店新手卖家

4、有买手经验的人(选品经验丰富的人更好)

“一件代发”的生意简单吗?

只要你有兴趣,会电脑,一件代发的生意其实是电商中最简单的方式,因为不需要进货,不需要囤货,不需要客服和专业的售后话术,也无须投入昂贵的直通车推广费用,更不需要去刷单作弊,首先看看他的基本步骤:

1、先开通一家网店(如果已经有了就更方便了)

2、到你的供应商产品库选品

3、上架宝贝开始销售

4、管理优化店铺,提高转化率,维护好客户资源

想美团无货源开店的老板请咨询v:hiwang01
不要看开实体店铺多挣钱,您不要盲目的去大额投资,可能您做一年的实体比外卖店多赚几倍,但是不一定会包赚不赔的吧,而且我们现在的这种模式投资小,利润空间大,省去了您的房租、人工、以及不需要您亲历亲为的外卖新模式,目前我们的加盟商家在全国有近1000家,别人在赚钱的时候,您还在想着考虑实体经济是不是落后了,现在不管哪个行业都是做互联网经济,足不出户的人都选择在网上购买,选择很重要。
想美团无货源开店的老板请咨询v:hiwang01

继续阅读 »

今天我用最简单的方式讲一下“无货源电商”到底是个什么意思。真正想了解的,一定要仔细阅读完,你不做,了解一下也是很好的电商谈资。

无货源电商:只是说店主不需囤货、压货,而不是说不需要货源。所以我觉得叫“零库存电商”更加贴切一些。想美团无货源开店的老板请咨询v:hiwang01


无货源电商有两种模式:

1、一件代发

这个比较好理解,就是找一个供应商(最好是源头供应商,能确保货源充足和低价),和他们谈妥,你负责卖货,他负责帮你发货。你从中赚取差价利润。

2、倒卖想美团无货源开店的老板请咨询v:hiwang01

在别人不知情的情况下,把人家在网上出售的商品搬到你自己店里,加一点利润开卖。这种方式会涉及到一些问题,比如产品图片可能会被投诉侵权,等你卖出了,你的上家突然提价了,或者售后服务得不到保障。

想美团无货源开店的老板请咨询v:hiwang01
所以现在倒卖的模式已经很难做了,我们就此略过。

下面详细说一下“一件代发”模式

什么人适合做“一件代发”的生意?

1、想兼职增加收入的人

2、对开网店感兴趣的人

3、网店新手卖家

4、有买手经验的人(选品经验丰富的人更好)

“一件代发”的生意简单吗?

只要你有兴趣,会电脑,一件代发的生意其实是电商中最简单的方式,因为不需要进货,不需要囤货,不需要客服和专业的售后话术,也无须投入昂贵的直通车推广费用,更不需要去刷单作弊,首先看看他的基本步骤:

1、先开通一家网店(如果已经有了就更方便了)

2、到你的供应商产品库选品

3、上架宝贝开始销售

4、管理优化店铺,提高转化率,维护好客户资源

想美团无货源开店的老板请咨询v:hiwang01
不要看开实体店铺多挣钱,您不要盲目的去大额投资,可能您做一年的实体比外卖店多赚几倍,但是不一定会包赚不赔的吧,而且我们现在的这种模式投资小,利润空间大,省去了您的房租、人工、以及不需要您亲历亲为的外卖新模式,目前我们的加盟商家在全国有近1000家,别人在赚钱的时候,您还在想着考虑实体经济是不是落后了,现在不管哪个行业都是做互联网经济,足不出户的人都选择在网上购买,选择很重要。
想美团无货源开店的老板请咨询v:hiwang01

收起阅读 »

app 开启分包加载 会导致不能正常跳转uni-upgrade-center-app 中自动升级页

App升级

页面复制到主包中(不要在uni_modules中)修改跳转路径后就可以正常跳转

页面复制到主包中(不要在uni_modules中)修改跳转路径后就可以正常跳转

7年前端在线求职

求职

掌握nodejs、vue、uniapp、angular、webpack、vite等,可以做组件封装,也可以基于项目重新设计架构。

有需要的可以详聊v:17704208307

掌握nodejs、vue、uniapp、angular、webpack、vite等,可以做组件封装,也可以基于项目重新设计架构。

有需要的可以详聊v:17704208307

为什么{}+[]=0(数据类型自动转换)

1.{}-->NaN-->false-->0,[]-->0
所以{}+[]= 0+0 = 0

1.{}-->NaN-->false-->0,[]-->0
所以{}+[]= 0+0 = 0