精华内容
下载资源
问答
  • 怎么找到以前用过的小程序
    千次阅读
    2020-07-16 10:49:29

    小程序绑定的邮箱应该是知道的吧,点开邮箱,找到提示要冻结的那一条,里面会有原始id的信息。

    更多相关内容
  • 如何找回微信小程序代码今年暑假,把自己电脑重装系统后,发现自己以前好多的程序代码都找不回来了,自己又不想重写,也没有保存到代码仓库,不知道如何是好?最近找到一个反编译的方法,试试能不能找回自己的小程序...

    如何找回微信小程序代码

    今年暑假,把自己电脑重装系统后,发现自己以前好多的程序代码都找不回来了,自己又不想重写,也没有保存到代码仓库,不知道如何是好?

    9f641e1730ad757e7a42e2cbf1c2f108.png

    最近找到一个反编译的方法,试试能不能找回自己的小程序源代码。

    先配置好node.js环境之后,再去下载wxapkg包。

    wxapkg包的链接:https://pan.baidu.com/s/1cLBI6Gw_zYebtbslnQVd2A

    提取码:u3cb

    ps:wxss文件内容已经是最新的了,不会出现wxss编译成html的问题。

    之后再在电脑上使用安卓模拟器,下载微信、QQ以及ES文件管理器。

    使用模拟器登录微信,打开需要反编译的微信小程序。

    之后打开ES文件管理器进入/data/data/com.tencent.mm/MicroMsg/.../appbrand/pkg/目录,找到以.wxapkg结尾的文件,发送到QQ上。

    使用cd命令进入到反编译文件夹,执行以下命令

    npm init
    npm install esprima
    npm install css-tree
    npm install cssbeautify
    npm install vm2
    npm install uglify-es
    npm install js-beautify

    再执行以下命令,更改两个文件的路径,建立采用绝对路径

    node wuWxapkg.js的绝对路径 反编译文件名称.wxapkg的绝对路径

    c2c6aefdb89edaa3167cbe34d2efbdb9.png

    最后再将文件导入到微信小程序开发工具,然后就可以把自己丢失的小程序代码找回来了。

    展开全文
  • 加解密小程序

    2019-03-17 15:41:18
    加解密小程序,是我从很久以前贴吧找到的,可以实现多种密码学的加解密,很适合自己
  • 今天电脑出问题,以前写的微信小程序源代码丢失了,悲剧啊!! 然后就找各种办法数据恢复,但是种种原因恢复不过来了。。。。。。。凉凉。。。。。。 继续想解决办法,结果呢想到了反编译,对,就这样反编译! 先...

    此教程若过时,请看下其他大神评论,以便获取最新方法;若大神有其他更好的方法请在下面评论!!

    今天电脑出问题,以前写的微信小程序源代码丢失了,悲剧啊!!

    然后就找各种办法数据恢复,但是种种原因恢复不过来了。。。。。。。凉凉。。。。。。

    继续想解决办法,结果呢想到了反编译,对,就这样反编译!

    先看下最终结果吧

    找了下大神写的反编译工具,先给地址:wxappUnpacker点击就可以去下载工具;

    记得要安装最新版本的node.js哦

    使用模拟器或者越狱的苹果手机,获得root权限的安卓手机来抓取wxapkg包

    我的是使用苹果手机来抓取包的,需要越狱。这里就不多说了,直接放图:

    使用反编译脚本解包 wxapkg

    • ● 到这里你应该已经将反编译脚本从github下载 或者 clone 到本地某个目录
    • ● 打开nodejs命令窗口,按住shift+右击
    • ● cd 到你clone或者下载好的反编译脚本目录下
    • ● 在node命令窗口中依次安装如下依赖(当然,你也可以选择-g全局安装):
    • 1、npm install esprima

    • 2、npm install css-tree

    • 3、npm install cssbeautify

    • 4、npm install vm2

    • 5、npm install uglify-es

    • 6、npm install js-beautify

    • ● 安装好依赖之后,就是最后一步了,反编译 .wxapkg 文件
    • 在当前目录下输入 node wuWxapkg.js [-d] //files 就是你想要反编译的文件名 例如:我有一个需要反编译的文件 1.wxapkg 已经解压到了C盘根目录下,那么就输出命令 node wuWxapkg.js C:\1.wxapkg

    按照描述进行了反编译,奇迹发生了,果然反编译成功了,但是一跑起来就出问题了,wxcc文件成了.html文件,

    而且发现反编译的时候报错了;错误图:

    不知道咋弄,继续网上搜解决办法,结果没找到。最后想放弃去某宝花钱。去问了一个店铺,我把我遇到的问题给店主描述了下,说要花80元给我搞定。花钱是值得的,但是呢我还是不服气,既然编译了,那得自己尝试么,对吧,然后我问店主,我出现的问题在哪里,店主说github上的有问题,最新的没更新,我这里有新的,300元我给你,我去,你这个也太坑了吧,300元把人家工具给我。我就直接不理他了。

    休息下。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

    然后我把ReferenceError: $gwx is not defined问题谷歌上一搜出来了解决办法,有的到一半就要钱,有的还不全,咋办呢,继续搜,最后在知乎上找到一个wuWxx.js需要修改的代码,提地址:https://zhuanlan.zhihu.com/p/56056561,没删之前赶紧去看看。果然把这个js修改,成功编译到以前的代码,虽然有些变动,但是大部分都正常。

    修改部分代码:

    需要源码或者需要编译指导可以联系我!!第一次写博客,望大家多多支持,谢谢!

    心得就是:动手尝试---------------------------

    展开全文
  • 以前在学习微信小程序时由于网上相关视频和教程不是很多,所以自己颇费了一番功夫去找资料,所以找到了一系列的教程,适合零基础的小白,还有后端源码、视频教程。 各位想学习微信小程序的不要错过了。
  • 1、微信小程序 首先,微信公众平台上注册一个小程序,这里有个大坑,就是一个邮箱只能注册一个小程序,一旦注册就不能注销啦。注册好微信小程序前期就要一个AppID就好。微信公众平台扫码-->微信选择登录的小程序...

    1、打开hbuildx,新建一个uniapp项目,选默认模板就可以,然后运行项目就可以选择

    2、 下载安装微信/支付宝开发者工具,并且记住安装的路径!

    安装好以后在hbuildx的工具-->设置-->运行配置-->开发工具路径里,将路径填上(选上),这样就可以运行项目了,这时运行微信小程序项目会在开发者工具上报错,是因为没有AppID

    3、注册微信小程序

    百度:微信公众平台-->账号分类-->小程序,滑到最底,注册,这里有个大坑,就是一个邮箱只能注册一个小程序,一旦注册就不能注销啦。注册好微信小程序前期就要一个AppID就好。微信公众平台扫码-->微信选择登录的小程序-->开发-->开发管理-->开发设置下就可以找到AppID了,把他复制下来到项目-->manifest.json-->微信小程序配置

    4、注册支付宝小程序

    百度:支付宝开放平台-->创建应用,然后支付宝小程序的AppID跟微信小程序的不一样,位置也不一样,看图,然后复制下来,到hbuildx的项目-->manifest.json-->支付宝小程序配置

     配置好APPID并不是万事大吉啦。要运行到支付宝开发工具必须选对文件夹~~这块也算一个小坑啦。点击运行-->选择支付宝小程,然后等待编译,编译完成以后,你的支付宝开发工具就会自动打开,但是你的项目不会。现在需要点击右上角-->选择项目-->选择你的项目文件夹-->打开-->选择unpackage-->选择dist-->选择dev-->选择mp-alipay。这样就可以在支付宝开发工具打开项目了,不用担心,这边写了代码,支付宝开发工具上也是自动更新的

    上面基本步骤就跑通了,下面就可以写代码了。

    5、写代码

    不分前后,想起一个更新一个

    1、uni.request()在支付宝不能解析responseType(文档上说了),换成my.request,还好我把请求封装了一下,不然真是大麻烦了,下面是uniapp网络请求的封装

    (1)根目录下新建utils文件夹,建index.js内容如下

    const baseUrl = 'https://xxxx.com' // 全局地址
    
    import store from '../store/index.js'// 用来记录登录状态,统一封装token
    
    module.exports = (params) => {
    	let url = params.url; // 请求地址 例如:/api/order/payRevertDevice
    	let method = params.method; // 请求方法
    	let header = params.header || {}; // 请求头
    	let data = params.data || {}; // 参数
    	let isjson = params.isjson || false // 请求头的content-type,默认不是'application/json',如果需要就设置为TRUE
    	
    	if (method) {
    		method = method.toUpperCase(); //	小写转大写
    	}
    	// 请求类型
    	if (!isjson) {
    		header = {
    			"content-type": "application/x-www-form-urlencoded"
    		}
    	}else {
    		header = {
    			"content-type": "application/json"
    		}
    	}
    	// 获取登录状态
    	let token = store.state.token
    	if (token) {
    		header = {
    			...header,
    			token
    		}
    	}
    
    	//	发起请求 加载动画
    	if (!params.hideLoading) {
    		uni.showLoading({
    			title: "加载中"
    		})
    	}
    	
    	
    	// 支付宝小程序不支持res,用my.request
    	// #ifdef MP-ALIPAY
    	my.request({
    		url: baseUrl + url,
    		method: method || "GET",
    		data: data,
    		headers: header,
    		dataType: 'json',
    		success: res => {
    			console.log(res,'http request res')
    			if (res.statusCode && res.statusCode != 200) {
    				//	api错误
    				uni.showModal({
    					// content: res.msg
    					content: res
    				})
    				return;
    			}
    			typeof params.success == "function" && params.success(res.data);
    		},
    		fail: err => {
    			uni.showModal({
    				content: err
    			})
    			typeof params.fail == "function" && params.fail(err.data);
    		},
    		complete: (e) => {
    			// console.log("请求完成");
    			uni.hideLoading()
    			typeof params.complete == "function" && params.complete(e.data);
    			return;
    		}
    	})
    	// #endif
    
    	// 微信小程序的请求 
    	// #ifdef MP-WEIXIN
    	//	发起网络请求
    	uni.request({
    		url: baseUrl + url,
    		method: method || "GET",
    		header: header,
    		data: data,
    		dataType: "json",
    		sslVerify: false, //	是否验证ssl证书
    		success: res => {
    			if (res.statusCode && res.statusCode != 200) {
    				//	api错误
    				uni.showModal({
    					content: res.msg
    				})
    				return;
    			}
    			typeof params.success == "function" && params.success(res.data);
    		},
    		fail: err => {
    			uni.showModal({
    				content: err.msg
    			})
    			typeof params.fail == "function" && params.fail(err.data);
    		},
    		complete: (e) => {
    			// console.log("请求完成");
    			uni.hideLoading()
    			typeof params.complete == "function" && params.complete(e.data);
    			return;
    		}
    	})
    	//  #endif	
    }
    

    (2)在main.js里挂载到vue的原型链上,这样组件就可以使用this.http()啦

    import http from './utils/http.js'
    Vue.prototype.http = http
    
    
    
    import store from './store/index.js'
    //把vuex定义成全局组件
    Vue.prototype.$store = store
    
    
    

    store:这里主要是记录token

    import Vue from 'vue'
    import Vuex from 'vuex'
    Vue.use(Vuex)
    const store = new Vuex.Store({
    	state: {
    		hasLogin: false,
    		token: '',
    	},
    	mutations: {
    		login(state, res) {
    			state.hasLogin = true
    			state.token = res
    		},
    	},
    	actions: {}
    })
    export default store

    使用:以登录为例

    this.http({
    		url: '/api/user/aliLogin',
    		method: 'POST',
    		isjson: true,
    		data: { // 根据接口文档填写参数,我这里目前需要一下四个
    			code,
    			avatar,
    			nickname,
    			userType: 1
    		},
            success: res => {
    			// console.log(res, 'MP-ALIPAY login res')
    			if (res.code === 200) {
    			// 存token 这样以后每次请求就自动带token了
    			this.$store.commit('login', res.data)
                // 再进行其他操作
    
            },
            fail: err =>{}
    })

    2、支付宝小程序的大坑

    以前没有接触过支付宝小程序,坑实在是太多了

    (1)在支付宝开放平台注册支付宝小程序之后,它的环境有两种。一种是沙箱环境,一种是线上环境,这两个是独立的,千万不能混了,而且沙箱环境可调式的能力很少,我都是在线上环境调试的

    但是,线上环境会有各种问题,首先要去支付宝公众平开,配置ip白名单,然后再在这个平台上开通各种能力,或许这样就好了,但是绝对不止这样,具体的流程忘记了,我弄了好几天才坑坑巴巴的调通了。 包括报什么ISV权限不足,然后官方文档说的什么auth_code什么什么的都是垃圾,就好好看看目前的环境,请求的地址,有没有白名单,能力有没有开通,或许就可以了

    3、保存图片到本地

    uni.getFileSystemManager().writeFile()、uni.saveImageToPhotosAlbum方法只能在微信小程序上使用,首先获取授权

    			toSave() {
    				uni.showLoading({
    					title: "正在生成图片",
    					mask: true,
    				});
    
    				uni.getSetting({
    					success: (res) => {
    						if (!res.authSetting["scope.writePhotosAlbum"]) {
    							uni.authorize({
    								scope: "scope.writePhotosAlbum",
    								success: () => { // 授权成功
    									// console.log('授权成功')
    									uni.hideLoading();
    									this.saveImg();
    								},
    
    								fail: (res) => {
    									uni.hideLoading();
    									// console.log('无法保存图片,请先授权')
    									uni.showToast({
    										title: '取消授权',
    										icon: 'error'
    									})
    								},
    							});
    						} else { // 已经授权!
    							// console.log('已经授权!')
    							uni.hideLoading();
    							this.saveImg();
    						}
    					},
    				});
    			},
    			

     this.saveImg(),图片地址使用base64格式

    saveImg() {
    				let _this = this
    				const base64Str = 'base64格式的图片地址'.slice(22), // 注意这里,截掉data:image/png;base64,
    					buffer = uni.base64ToArrayBuffer(base64Str),
    					filePath = wx.env.USER_DATA_PATH + "/wx.png"; // base64src.png 为保存的图片名称
    
    				uni.getFileSystemManager().writeFile({
    					filePath, // 先把文件写到临时目录里
    					// 方式一:
    					data: buffer,
    					encoding: "binary",
    					// 方式二:
    					// data: this.imgBase64.slice(22),
    					// encoding: "base64",
    					success: (res) => {
    						uni.saveImageToPhotosAlbum({
    							filePath, // 将临时文件 保存到相册
    							success: (res) => {
    								uni.showToast({
    									title: '图片保存成功',
    									icon: 'success'
    								})
    								_this.$refs.popup.close()
    							},
    							fail: (error) => {
    								uni.showToast({
    									title: '图片保存失败',
    									icon: 'error'
    								})
    								_this.$refs.popup.close()
    							},
    						});
    					},
    					fail: (error) => {
    						uni.showToast({
    							title: '图片保存失败',
    							icon: 'error'
    						})
    					}
    				});
    			}

    支付宝小程序上用my.saveImage()

    toSave() {
    				uni.showLoading({
    					title: "正在生成图片",
    					mask: true,
    				});
    				let _this = this
    				my.saveImage({
    					url: '图片的网络地址',
    					success: res => {
    						// console.log('saveImage', res)
    						uni.showToast({
    							title: '图片保存成功',
    							icon: 'success'
    						})
    						uni.hideLoading()
    						_this.$refs.popup.close()
    					},
    					fail: err => {
    						uni.hideLoading()
    						uni.showToast({
    							title: '授权失败',
    							icon: 'error'
    						})
    						// console.error('saveImage err', err)
    						_this.$refs.popup.close()
    					}
    				})
    			}

    4、uniapp获取用户信息并且--->微信登录微信小程序、支付宝登录支付宝小程序

    这块的坑不是很多,但是登录功能是必须有的,记录一下

    微信小程序

    login() {
    				let _this = this
    				uni.getSetting({
    					success(res) {
    						// console.log("授权:", res);
    						uni.showModal({
    							title: '授权提醒',
    							content: '请您授权头像、昵称等信息,以便使用全部功能',
    							cancelText: "随便逛逛",
    							confirmText: '确认授权',
    							success: function(showres) {
    								if (showres.confirm) {
    									uni.getUserProfile({
    										desc: '获取您的昵称、头像、地区及性别', // 声明获取用户个人信息后的用途,后续会展示在弹窗中,请谨慎填写
    										lang: "zh_CN",
    										success: (infoRes) => {
    											// console.log('授权信息', infoRes);
    											uni.login({
    												provider: 'weixin',
    												success: (res1) => {
    													_this.weixinlogin(用户信息等参数)
    												},
    												fail: () => {
    													uni.showToast({
    														title: "微信登录授权失败",
    														icon: "none"
    													});
    												}
    											})
    										},
    										fail: err => {
    											// console.log(err, 'getUserProfile err')
    										}
    									})
    								} else if (showres.cancel) {
    									// console.log('用户点击取消');
    								}
    							}
    						})
    					}
    				})
    			},
    
    
    
    weixinlogin(参数) {
    				this.http({
    					url: '接口地址',
    					method: 'POST',
    					isjson: true,
    					data: {
    						登录接口需要的参数
    					},
    					header: {
    						'content-type': 'application/json'
    					},
    					success: res => {
    						// console.log(res, 'weixin login res')
    						if (res.code === 200) {
    							// store里存token,在上面的代码里写过,封装请求的时候将token封装进去
    							this.$store.commit('login', res.data)
    							uni.showToast({
    								title: '登录成功!',
    								icon: 'success'
    							})
    						} else {
    							// console.log('登录失败!')
    							uni.showToast({
    								title: '登录失败!',
    								icon: 'error'
    							})
    						}
    					},

    支付宝小程序获取用户信息登录

    这里有点坑,调试的时候总是调不通,可以从一下几点找问题

    1)确保代码没有问题,我是照着文档写的

    2)支付宝小程序开放平台的各种配置,包括ip白名单、域名白名单、是不是这个小程序的开发者等

    3)后端的秘钥,证书(都是小程序后台生成的)没有问题

    4)APPID

    <view class="my-beijing" @click="alilogin">
    
    
    // 获取用户authCode
    			alilogin() {
    				let _this = this
    				my.getAuthCode({
    					scopes: 'auth_user',
    					success: (res2) => {
    						console.log(res2, 'res.authCode')
    						// return
    						_this.alipaylogin(res2.authCode)
    						// console.log(res2,'res2') , userInfo.avatar, userInfo.nickName || '支付宝用户'
    					},
    					fail: (resfail) => {
    						// 用户取消授权
    					},
    				});
    			},
    
    
    // 支付宝登录
    			alipaylogin(code) {
    				this.http({
    					url: 'login接口地址',
    					method: 'POST',
    					data: {
    						code
    					},
    					success: res => {
    						if (res.code === 200) {
    							// 存token
    							this.$store.commit('login', res.data.token)
    						} else {
    							// console.log('MP-ALIPAY 登录失败!')
    							uni.showToast({
    								title: '登录失败!',
    								icon: 'error'
    							})
    						}
    					},
    					fail: err => {
    						// console.log(err, 'MP-ALIPAY login err')
    						// console.log('登录失败!')
    						uni.showToast({
    							title: '登录失败!',
    							icon: 'error'
    						})
    					}
    				})
    			},

    5、获取180秒倒计时

    <text v-if="!isgetcode" @click="sendMs">发送验证码</text>
    <text v-else>{{content}}</text>
    
    
    
    
    
    data() {
    			return {
                    isgetcode: false,
    				count: 180,
    				canClick: false,
    				content: ''
    			}
    		},
    
    
    methods: {
    			// 获取倒计时
    			daojishi() {
    				if (!this.canClick) return
    				this.canClick = false
    				this.content = this.count + '秒' //这里解决60秒不见了的问题
    				let clock = setInterval(() => {
    					this.count--
    					this.content = this.count + '秒'
    					// console.log(this.content,'this.content')
    					if (this.count <= 0) { //当倒计时小于0时清除定时器
    						clearInterval(clock)
    						this.content = '验证码'
    						this.count = 180
    						this.canClick = true
    						this.isgetcode = false
    					}
    				}, 1000)
    			},
    }

    6、支付

    1)uniapp的微信支付

    流程就是处理页面一些列数据,然后第一步调用后端给你的创建订单接口,第二步就调用uni.requestPayment()拉起支付就好了

    // 创建订单
    commitorder() {
    				// 是否同意协议
    				if (this.agreement_radio) {
    					let query = {
    						创建订单时的参数
    					}
                        //调用创建订单接口
    					this.http({
    						url: '接口地址',
    						method: 'POST',
    						isjson: true,
    						data: query,
    						success: res => {
    							// console.log(res, 'create order res')
    							if (res.code == 200) {
                                    //调用支付
    								this.wxpay(res.data)
    							}
    						},
    						fail: err => {
    							// console.log(err, 'create order error')
    						}
    					})
    				} else {
    					// console.log('未同意协议')
    					this.$nextTick(() => {})
    				}
    			},

    this.wxpay()

    // 拉起微信支付
    			wxpay(data) {
    				let _this = this
    				// console.log(data, 'wxpay data'),uni.requestPayment()需要的参数在创建订单的接口返回,要不然就自己对照文档计算
    				uni.requestPayment({
    					provider: 'wxpay',
    					timeStamp: data.timeStamp,
    					nonceStr: data.nonceStr,
    					package: data.package,
    					signType: data.signType,
    					paySign: data.paySign,
    					success: function(res) {
    						// console.log('success:' + JSON.stringify(res));
    						// 跳转到支付成功页面
    						uni.reLaunch({
    							url: '../Play_Ok/Play_Ok'
    						})
    					},
    					fail: function(err) {
    						// console.log('fail:' + JSON.stringify(err));
    						// 支付失败记得删除订单
    					}
    				});
    			},

    2)uniapp的支付宝支付

    支付宝支付用uni的方法没有成功,所以去看了支付宝支付的文档,最后选择用支付宝预授权来完成支付。步骤还是一样的先创建订单获取支付时的参数(支付宝是tradeNo),然后拉起支付

                // 支付宝支付
    			commitorder_alipay() {
    				// 是否同意协议
    				if (this.agreement_radio) {
    
    					// 是否选择地址
    					if (!this.haseaddr) {
    						uni.showToast({
    							title:'请选择地址',
    							icon:'error'
    						})
    						return
    					}
    
    
    					let query = {
    						// 创建订单参数
    					}
    					let _this = this
    					this.http({
    						url: '创建订单接口',
    						method: 'POST',
    						isjson: true,
    						data: query,
    						success: res => {
                                // 创建订单成功的回调,拉起支付
    							console.log(res, 'create order res')
    							if (res.code == 200) {
                                    //创建订单成功,接口会返回tradeNo,调支付
    								my.tradePay({
    								  tradeNO:res.data.aliPay.tradeNo,
    								  success: (res1) => {
    									  // console.log(res1,'支付成功 res1')
    									  if(res1.resultCode == 9000){
    										  // 文档上说9000是成功,到这里就成功了
    									  }else {
    										 // 支付不成功,具体原因看返回,去对照文档
    									  }
    								  },
    								  fail: (err1) => {
    									 // 支付不成功,具体原因看返回,去对照文档
    								  }
    								});
    							}
    						},
    						fail: err => {
    							// 创建订单失败的回调
    						}
    					})
    				} else {
    					// console.log('未同意协议')
    					this.$nextTick(() => {})
    
    					my.showToast({
    						type: 'none',
    						content: '请阅读并勾选协议',
    						duration: 3000,
    						success: () => {}
    					})
    				}
    			},
    

    7、支付宝小程序图片处理 

    图片的处理看文档就好了支付宝小程序图片的官方文档

    但是,这里有种情况,就是图片的宽度固定,但是高度不固定,一般来说设置image标签的mode属性为scaleToFill就好了,有的时候会出现图片被压缩的情况,这时候就直接设置mode为widthFix直接解决(文档里有)

    2022-7-29更新

    换了一家公司也有uniapp的项目,主要是做企微跟飞书小程序

    1、企微小程序的调试

    微信开发者工具上下一个企微模拟器,然后选择就好了,跟微信小程序一样的

    2、视频标签video

    可以先看官方文档,包括uniapp、微信、飞书的,每个平台对video的支持程度不一样。我接到的需求是接口返回视频列表,而我要让一个个视频看起来像是一个视频在播放,包括自定义进度条、倍速、开始、暂停等控件

    首先这个需求在PC端已经有了实现,我的选择是copy,但是由于我太菜了,没有完成转化,就只能自己写了,当然也有借鉴

    来看文件结构,在pages里新建一个页面咯,没有写成组件

     

     全部的代码,需要注意的是,因为是CV的,所以有很多无关的代码我没时间也没能力去处理,这里只说关键点

    1、看文档,找到不同平台对于video标签的支持程度。这样就可以很好的实现播放、暂停、timeupdate等

    2、获取video实例,小程序里不支持操作DOM,获取video实例是通过API获取哦。这块有个大坑,一定要看好,是xx.createVideoContext方法而不是xx.createAudioContext

      onReady: function (res) {
        this.videoContext = wx.createVideoContext('myVideo', this)
      },

    3、控件的实现,就是去看文档,各种开放的API都有,按照业务逻辑去调用就好了

    4、拖动的进度条,这块是借鉴了之前大佬的写法,具体的代码的movePoint方法

    5、终极大坑,video的层级,高,z-index不好用,那么我下面的写法在微信\企微小程序上是可以盖住video的,但是在飞书小程序就不行了,所以想了一个方法,就是将video的100% - 底下控件的高度,也算是变相解决问题了

    <template>
      <div class="live_detail" @tap="clickTouchend">
        <div class="video-stop" v-show="video.isPause"></div>
        <!-- #ifdef MP-LARK -->
        <video
          :show-play-btn="false"
          x5-playsinline="true"
          x5-video-player-type="h5-page"
          x5-video-player-fullscreen="true"
    	:show-loading="true"
          :controls="false"
          :autoplay="true"
          style="
            object-fit: fill;
            position: absolute;
            width: 100%;
            height: calc(100% - 120px);
            top: 0;
            left: 0;
          "
          id="myVideo"
          :src="videoUrl"
          @pause="bindpause"
          @play="bindplay"
          @timeupdate="timeupdate"
          @error="videoErrorCallback"
          @ended="videoEnd"
        ></video>
        <view class="video-con flex align-center just-center">
          <view class="flex top">
    		  <view></view>
    		  <view class="video-time flex align-center">
    		    <span class="current-time w54">{{ getVideoTime() }}</span>
    		    <span class="line">/</span>
    		    <span class="w54">{{ videoTotalTime() }}</span>
    		  </view>
            <view class="flex just-center progress" @touchmove.native.stop="movePoint">
              <view class="line"></view>
              <view
                class="point"
                :style="{ left: finLeft }"
                @touchstart.native.stop="drag = true"
                unselectable="on"
                onselectstart="return false"
                style="-moz-user-select: none; -webkit-user-select: none; -ms-user-select: none"
              ></view>
            </view>
    	  </view>
          <view class="footer flex">
            <img v-if="roomAbout.avatar" :src="roomAbout.avatar" alt class="head" />
            <img v-else :src="require('@/static/images/head.png')" alt class="head" />
            <view class="f_other flex just-center">
              <view class="title">{{ roomAbout.nickName || '暂无昵称' }}</view>
              <view class="count">
                <span>粉丝数{{ roomAbout.dyfansNum || ' 暂无' }}</span>
                <span>场观{{ roomAbout.watchTimes || ' 暂无' }}</span>
                <span>峰值{{ roomAbout.maxOnlineNum || ' 暂无' }}</span>
              </view>
            </view>
            <view></view>
          </view>
        </view>
        <!-- #endif -->
        <!-- #ifdef MP-WEIXIN -->
        <video
          x5-video-player-type="h5-page"
          :show-loading="true"
          :controls="false"
          :autoplay="true"
          object-fit="fill"
          style="object-fit: fill; position: absolute; width: 100%; height: 100%; top: 0; left: 0"
          id="myVideo"
          :src="videoUrl"
          preload
          @pause="bindpause"
          @play="bindplay"
          @timeupdate="timeupdate"
          @error="videoErrorCallback"
          @ended="videoEnd"
          @canplay="canplay"
          @waiting="videoWaiting"
          @playing="videoPlaying"
          @videoOver="videoOver"
        ></video>
        <!-- 控件 -->
        <div class="video-con flex align-center just-center">
          <div class="flex top">
            <!-- 进度条 -->
            <div class="flex just-center progress" @touchmove.native.stop="movePoint">
              <div class="line"></div>
              <div
                class="point"
                :style="{ left: finLeft }"
                @touchstart.native.stop="drag = true"
                unselectable="on"
                onselectstart="return false"
                style="-moz-user-select: none; -webkit-user-select: none; -ms-user-select: none"
              ></div>
            </div>
            <!-- 时间 -->
            <div class="video-time flex align-center">
              <span class="current-time w54">{{ getVideoTime() }}</span>
              <span class="line">/</span>
              <span class="w54">{{ videoTotalTime() || '00:00:00' }}</span>
            </div>
            <!-- 倍速 -->
            <div class="ratio-play">
              <div class="play-text" @touchend.native.stop="showChooseRatio">
                {{ ratioText() }}
              </div>
              <div
                class="choose-ratio-list flex col"
                @touchend.native.stop="showChooseRatio"
                :class="{ active: isShowChooseRatio }"
              >
                <div class="choose-item" @tap="changeRatio(1.5)">1.5X</div>
                <div class="choose-item" @tap="changeRatio(1.25)">1.25X</div>
                <div class="choose-item" @tap="changeRatio(1)">1.0X</div>
                <div class="choose-item" @tap="changeRatio(0.8)">0.8X</div>
                <div class="choose-item" @tap="changeRatio(0.5)">0.5X</div>
              </div>
            </div>
          </div>
          <div class="footer flex">
            <img v-if="roomAbout.avatar" :src="roomAbout.avatar" alt class="head" />
            <img v-else :src="require('@/static/images/head.png')" alt class="head" />
            <div class="f_other flex just-center">
              <div class="title">{{ roomAbout.nickName || '暂无昵称' }}</div>
              <div class="count">
                <span>粉丝数{{ roomAbout.dyfansNum || ' 暂无' }}</span>
                <span>场观{{ roomAbout.watchTimes || ' 暂无' }}</span>
                <span>峰值{{ roomAbout.maxOnlineNum || ' 暂无' }}</span>
              </div>
            </div>
            <div></div>
          </div>
        </div>
        <!-- #endif -->
      </div>
    </template>
    <script>
    import { getLiveRoom } from '@/api/play-record/play-record.js'
    
    export default {
      name: 'liveDetail',
      data() {
        return {
          roomAbout: {}, // 所有返回
          videoList: [], // 视频列表
          videoListTotal: 0, // 视频列表长度
          totalSeconds: 0, // 视频总长度
          videoUrl: '', // 播放地址
          videoCurrentIndex: 0, // 这个应该是当前播放的视频索引
          ratio: 1, // 视频倍速
          video: {
            //视频有关内容
            currentTime: 0, // 当前时间
            isPause: true, // 是否显示暂停按钮
            timeArr: [], // 存储每个视频长度,目前不知道功能
            isClick: false, // unknow
            copyTime: 0, //unknow
            volume: 1 // unknow
          },
          videoTime: 0, // 不知道作用
          isShowChooseRatio: false, //显示倍速
          left: 0, // 滑动点的位置
          finLeft: 0, // 滑动点的位置
        }
      },
      // 监听视频时间变化
      watch: {
        'video.currentTime': {
          handler(val) {
            this.computeLeft()
            // this.timeupdate()
          }
        }
      },
      onReady: function (res) {
        this.videoContext = wx.createVideoContext('myVideo', this)
      },
      onLoad(options) {
        let query = {
          getRecordUrl: 1,
          getRoomDetail: 1,
          brandId: options.brandId,
          roomId: options.roomId,
          userId: ''
        }
        this.getLive(query)
      },
      methods: {
        videoErrorCallback: function (e) {
          this.$toast(e.detail.errMsg)
        },
    
        bindplay() {
          // // #ifdef MP-LARK
          // this.videoContext.exitFullScreen()
          // //  #endif
          this.video.isPause = false
        },
        bindpause() {
          this.video.isPause = true
        },
        computeLeft() {
          const total = this.videoTime + this.video.currentTime
          const left = (total / this.totalSeconds) * 360
          this.left = left + 'rpx'
          this.finLeft = (total / this.totalSeconds) * 360 + 'rpx'
        },
        movePoint(e) {
          let _this = this
          if (this.drag) {
            const line = uni.createSelectorQuery().in(this).select('.progress')
            line
              .boundingClientRect(function (data) {
                const x = ((e.touches[0].clientX - data.left) / data.width) * _this.totalSeconds
                const max = Math.max(..._this.video.timeArr)
                const item = _this.video.timeArr.find(i => i < x)
                if (item) {
                  // 控制point如果超过最后一个视频,就不能滑动了
                  if (x - item > max) {
                    return
                  }
                  _this.calcVideo(x - item)
                }
              })
              .exec(function (res) {
                // 注意:exec方法必须执行,即便什么也不做,否则不会获取到任何数据
              })
          }
        },
    
        showChooseRatio() {
          if (this.ratioTimer) {
            clearTimeout(this.ratioTimer)
          }
          this.isShowChooseRatio = !this.isShowChooseRatio
        },
        // 获取视频
        getLive(query) {
          getLiveRoom(query).then(res => {
            if (res.code !== 0) return
            // console.log(res, 'res.data.liveRoomVideo')
            this.roomAbout = res.data
            this.videoList = res.data.liveRoomVideo
            this.videoListTotal = res.data.liveRoomVideo.length
            this.videoList.forEach(item => {
              item.videoStartTime = item.videoStartTime / 1000
              item.videoEndTime = item.videoEndTime / 1000
              item.videoTime = item.videoEndTime - item.videoStartTime
            })
            let total = 0
            this.videoList.forEach(item => {
              total += item.videoTime
              this.video.timeArr.push(total)
            })
            this.totalSeconds = total
            if (this.videoList.length > 0) {
              if (this.videoList.length === 1) {
                this.videoUrl = this.videoList[0].videoUrl
                this.videoCurrentIndex = 0
              } else {
                this.videoUrl = this.videoList[1].videoUrl
                this.videoCurrentIndex = 1
                this.calcVideo(this.video.timeArr[0] + 1)
              }
            }
          })
        },
        // 处理视频获取数据
        calcVideo(total, isPlaying = false) {
          if (this.videoList.length === 1) {
            this.video.currentTime = total
            this.videoContext.currentTime = total
            this.video.isPause = true
            return
          }
          if (this.videoList.length === 0) {
            const timeText = this.formatTime(total).split(':').slice(0, 3).join(':')
          }
          let index = -1
          for (let i = 0; i < this.video.timeArr.length - 1; i++) {
            if (this.video.timeArr[0] >= total) {
              if (this.videoCurrentIndex !== i) {
                this.videoUrl = this.videoList[0].videoUrl
              }
              this.videoTime = 0
              this.videoCurrentIndex = 0
              Promise.resolve().then(res => {
                console.log(res, 'calcVideo promise resolve res')
                this.video.currentTime = total
                this.videoContext.currentTime = total
                this.video.isClick = true
                this.video.copyTime = total
              })
              this.video.isPause = true
              index = 0
              break
            }
            if (total >= this.video.timeArr[i] && total <= this.video.timeArr[i + 1]) {
              index = i
              //   this.clickStatus = true
              this.videoUrl = this.videoList[index + 1].videoUrl
              this.videoCurrentIndex = index + 1
              this.videoTime = this.video.timeArr[i]
              this.video.isClick = true
              this.video.copyTime = total - this.video.timeArr[i]
              Promise.resolve().then(() => {
                this.video.currentTime = total - this.video.timeArr[i]
                this.videoContext.currentTime = total - this.video.timeArr[i]
              })
              this.video.isPause = true
              break
            }
            if (
              total >= this.video.timeArr[this.video.timeArr.length - 2] &&
              total <= this.video.timeArr[this.video.timeArr.length - 1]
            ) {
              this.videoUrl = this.videoList[this.videoList.length - 1].videoUrl
              this.videoCurrentIndex = this.videoList.length - 1
              this.videoTime = this.video.timeArr[this.video.timeArr.length - 2]
              //   this.clickStatus = true
              this.video.isClick = true
              this.video.copyTime = total - this.video.timeArr[this.video.timeArr.length - 2]
              Promise.resolve().then(() => {
                this.video.currentTime = total - this.video.timeArr[this.video.timeArr.length - 2]
                this.videoContext.currentTime =
                  total - this.video.timeArr[this.video.timeArr.length - 2]
              })
              this.video.isPause = true
              break
            }
          }
          if (!isPlaying) {
            this.videoContext && this.videoContext.pause()
            this.video.isPause = true
          } else {
            setTimeout(() => {
              this.videoContext && this.videoContext.play()
            }, 100)
            this.video.isPause = false
          }
        },
    
        // 视频播放时
        timeupdate(e) {
          // 视频在播放
          this.video.isPause = false
          if (this.videoContext) {
            this.videoContext.playbackRate = this.ratio //倍速
            this.videoContext.volume = this.video.volume
            this.video.currentTime = parseInt(e.detail.currentTime)
          }
        },
    
        canplay() {
          if (this.video.isClick) {
            this.videoContext.currentTime = this.video.copyTime
            this.video.isClick = false
            this.videoContext.playbackRate = this.ratio
            this.videoContext.volume = this.video.volume
          }
        },
    
        videoEnd() {
          if (this.videoCurrentIndex === this.videoList.length - 1) {
            // alert(1)
            this.videoUrl = this.videoList[0].videoUrl
            this.videoCurrentIndex = 0
            this.videoTime = 0
          } else {
            this.videoTime = this.videoTime + this.video.currentTime
            this.videoCurrentIndex++
            this.videoUrl = this.videoList[this.videoCurrentIndex].videoUrl
          }
          Promise.resolve().then(res => {
            console.log(res, 'videoEnd promise resolve res')
            this.videoContext.play()
            this.video.isPause = false
            this.video.iconShow = false
          })
        },
        videoWaiting() {
          if (!this.video.isPause) {
            this.video.isLoading = true
          }
        },
        videoPlaying() {
          this.video.isLoading = false
        },
        toggleVideoStatus() {
          if (this.video.isPause) {
            this.video.isPause = false
            this.video.coverShow = false
            this.videoContext.play()
          } else {
            this.video.isPause = true
            this.videoContext.pause()
          }
        },
    
        clickTouchend() {
          if (this.video.isPause) {
            // 暂停状态
            this.video.isPause = false
            this.videoContext.play()
          } else {
            this.videoContext.pause()
            this.video.isPause = true
          }
        },
        changeRatio(ratio) {
          this.ratio = ratio
          this.videoContext.playbackRate = ratio
          this.$nextTick(() => {
            this.isShowChooseRatio = false
          })
        },
        // 选择倍速
        ratioText() {
          if (this.ratio === 1) {
            return '倍速'
          } else {
            return this.ratio + 'X'
          }
        },
        // 获取视频总时间
        videoTotalTime() {
          const time = this.totalSeconds
          if (!time) return
          let h = parseInt(time / 60 / 60)
          let m = Math.floor((time % 3600) / 60)
          let s = Math.floor(time % 60)
          // h >= 24 ? h - 24 : h
          h = h >= 10 ? h : `0${h}`
          m = m >= 10 ? m : `0${m}`
          s = s >= 10 ? s : `0${s}`
          return `${h}:${m}:${s}`
        },
        // 获取视频当前播放的时间
        getVideoTime() {
          const total = this.videoTime + this.video.currentTime
          // console.log(this.videoTime, this.video.currentTime)
          return this.formatTime(total)
        },
        formatTime(time) {
          // 格式化时分秒
          let h = Math.floor(time / 3600)
          let m = Math.floor((time % 3600) / 60)
          let s = Math.floor(time % 60)
          // h >= 24 ? h - 24 : h
          h = h >= 10 ? h : `0${h}`
          m = m >= 10 ? m : `0${m}`
          s = s >= 10 ? s : `0${s}`
          return `${h}:${m}:${s}`
        }
      }
    }
    </script>
    <style lang="less" scoped>
    .flex {
      display: flex;
    }
    .warp {
      flex-wrap: wrap;
    }
    .col {
      flex-direction: column;
    }
    .just-center {
      justify-content: center;
    }
    .just-start {
      justify-content: flex-start;
    }
    .just-end {
      justify-content: flex-end;
    }
    .just-a {
      justify-content: space-around;
    }
    .just-b {
      justify-content: space-between;
    }
    .align-center {
      align-items: center;
    }
    .align-end {
      align-items: flex-end;
    }
    .live_detail {
      width: 100vw;
      height: 100vh;
      position: relative;
    
      .video-stop {
        width: 98rpx;
        height: 98rpx;
        position: absolute;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
        z-index: 11;
        background: url(https://tagvvcloud-brandapp-1256030678.cos.ap-guangzhou.myqcloud.com/49e6cf22c7c94c7a92a61288d45d0ec8play.png)
          no-repeat;
        background-size: 100% 100%;
      }
    
      .video-con {
        // #ifdef MP-LARK
        position: fixed;
        align-items: unset !important;
        // #endif
        z-index: 100;
        // #ifdef MP-WEIXIN
        position: absolute;
        // #endif
        left: 0;
        bottom: 0;
        width: 100%;
        height: 240rpx;
        background: rgba(0, 0, 0, 0.5);
        flex-direction: column;
    
        .footer {
          // #ifdef MP-LARK
          margin-left: 24rpx;
          // #endif
          align-items: center;
          font-size: 28rpx;
          font-weight: 400;
          color: #ffffff;
          margin-top: 24rpx;
          .head {
            width: 96rpx;
            height: 96rpx;
            background: #d8d8d8;
            border-radius: 50%;
          }
          .f_other {
            margin-left: 24rpx;
            flex-direction: column;
    
            .count {
              margin-top: 16rpx;
              span {
                display: inline-block;
                margin-right: 80rpx;
                white-space: nowrap;
              }
              span:last-child {
                margin-right: unset;
              }
            }
          }
        }
        > div {
          width: calc(100% - 48rpx);
        }
        .top {
          justify-content: space-between !important;
          align-items: center;
          // #ifdef MP-LARK
          margin-left: 24rpx;
          margin-right: 24rpx;
          // #endif
        }
        .video-time {
          height: 28rpx;
          font-size: 20rpx;
          font-family: PingFangSC-Regular, PingFang SC;
          font-weight: 400;
          color: #ffffff;
          line-height: 28rpx;
          opacity: 0.4;
          .current-time {
            color: #fff;
          }
        }
        .ratio-play {
          position: relative;
          color: rgba(255, 255, 255, 0.6);
          .play-text {
            font-size: 24rpx;
            width: 80rpx;
            height: 40rpx;
            line-height: 40rpx;
            text-align: center;
            background: rgba(0, 0, 0, 0.5);
            border-radius: 6rpx;
          }
          .choose-ratio-list {
            width: 80rpx;
            position: absolute;
            padding: 10rpx 0;
            left: 0rpx;
            top: -234rpx;
            flex-direction: column-reverse;
            background: rgba(0, 0, 0, 0.7);
            border-radius: 2rpx;
            display: none;
            transition: all 0.2s;
            font-size: 20rpx;
            &.active {
              display: block;
            }
            .choose-item {
              text-align: center;
              line-height: 34rpx;
    		  // #ifdef MP-LARK
    			line-height: 42rpx;
    		  // #endif
              width: 80rpx;
              transition: all 0.2s;
            }
          }
        }
        .progress {
          width: 360rpx;
          height: 4rpx;
          line-height: 4rpx;
          background: #ffffff;
          border-radius: 2rpx;
          align-items: center;
          position: relative;
          .line {
            width: 100%;
            height: 4rpx;
            background-color: #fff;
          }
          .point {
            cursor: pointer;
            width: 24rpx;
            height: 16rpx;
            background-color: #fff;
            border-radius: 8rpx;
            position: absolute;
            left: v-bind(left);
            top: 50%;
            transform: translateY(-50%);
          }
        }
      }
    }
    </style>
    

    展开全文
  • 解决方法: 去邮箱里翻邮件(一般邮箱都支持搜索,直接搜 冻结 就行),找到当时的邮件,里面就有原始ID,一般是gh_...解冻的时候是要求填写小程序原始ID号,忘记了,所以通过上面方法找到了ID然后继续激活即可。 ...
  • 最近在帮亲戚做一款微信的点餐小程序以前从没有接触过小程序的我只能现做现卖。一边看文档一边实践尝试,在进行到点菜模块左侧滑动菜单时遇到了小小的阻碍。索性在查找一些资料和教程后主要功能实现了出来。特此...
  • 小程序过期

    2020-06-18 16:44:26
    1.登录:https://mp.weixin.qq.com/ 2. 3.后台与小程序端重新运行 4.真机删除以前小程序重新扫码,帮助砍价者的真机同样删除以前小程序,同样需要扫码小程序 5.分享者就可以分享了
  • 为了背单词,我花了两天写了一款背单词小程序

    万次阅读 多人点赞 2020-05-23 15:52:51
    前言        “要是考试不考英语就好了”         哎,提起英语,都是伤心事。有时候严重怀疑自己不是一块学习英语的...开始还是按照以前的方
  • 微信小程序是当下最为普及、方便以及前沿的一种移动服务方式,微信小程序的开发运用了微信开发者工具,设计并开发图书馆管理小程序,并实现了图书借阅管理、留言管理、图书馆占座管理、预约占座等功能,帮助学生...
  • 近年来,小程序的发展势如破竹,小程序将会在不久遍布大街小巷,毕竟从某种意义上来说,它比公众号更简化,更方便。小程序的确是靠着高质量,高效率,来获取用户的信任。 究其根本,小程序的兴起有两大原因: 第...
  • 微信小程序——图片识别

    万次阅读 多人点赞 2020-01-03 13:55:11
    我的微信小程序 期末大作业——基于百度大脑API的图片识别小程序 具体实现了动物识别、植物识别、车辆识别 三个功能 实验源码已经放到了我的GitHub,欢迎测试修改 下面给大家分享该项目的实验报告???? 目录1 概述...
  • 微信小程序的测试,抓包,模拟
  • 最近要开发小程序了,虽然以前也玩一会,但小程序的开发更新还是很快的,以前不支持npm包,现在支持了,以前没有云开发的,现在也有了,说实话,小程序的云开发真是牛逼。但最近遇到了很蛋疼的问题,构建npm的...
  • 最近要开发小程序了,虽然以前也玩一会,但小程序的开发更新还是很快的,以前不支持npm包,现在支持了,以前没有云开发的,现在也有了,说实话,小程序的云开发真是牛逼。但最近遇到了很蛋疼的问题,构建npm的时候...
  • 为什么微信扫一扫无法获取摄像头?安装微信时,您没有授予微信使用摄像头的权限。...3)单击应用程序权限管理。4)找到微信。5)单击摄像头。6)检查允许。为什么不能通过扫描微信访问摄像头:1。不能...
  • 微信小程序现在用的人非常多,而且带起了一阵潮流之风,如果你还没有用过,那你就是太OUT了。下面我们就来为大家介绍一下技术的方法怎么解决吧。微信小程序怎么复制链接:点击图文链接,就看可以复制跳转;其实和之前...
  • 基于微信小程序校内论坛系统设计与实现(毕业设计论文+数据库脚本+源码+答辩ppt),本科毕业论文,校内论坛系统,vue+java+mysql实现源码,另附毕业答辩ppt
  • 1.什么是AR?AR又称增强现实(Augmented Reality)技术,是一种将虚拟信息与真实世界巧妙融合的技术,广泛运用了多媒体、三维建模、实时跟踪...今日,微信小程序正式开放AR功能。AR试穿、AR逛展……各种体验,都能“身...
  • 以前开发一款小程序或者应用啥的,首先就是申请域名买服务器,这是必不可少的步骤。 现在小程序云开发出来后,又再出现内容管理的这个功能,对于开发一款简单的小程序来说,真的是太简单的了。 现成的后台直接配置,...
  • 微信小程序 谈谈在大学初次写项目的体验

    万次阅读 多人点赞 2020-03-20 09:34:59
    说明:笔者重新规划了博客方向,想更详细的讲解微信小程序的所有技术内容,本文于2020年5月24日已做修改。 同时笔者也欢迎一起合作共赢,愿意写杂志,写书,贡献自己的一份微薄之力! 作为第零篇的讲解,本文主要...
  • 小程序SAAS云,微信小程序一键生成

    千次阅读 2018-11-21 11:41:00
    第一步:注册微信小程序 1、注册微信小程序,一定要自己通过微信官方去注册申请,因为需要... 2、注册小程序下来后,需要实名认证,实名认证提倡以企业(或个体户,个体户也是企业)进行实名,实名认证需要缴纳30...
  • 微信小程序使用dayjs

    千次阅读 2020-04-03 13:22:09
    npm 支持 从小程序基础库版本 2.2.1 或以上、及开发者工具 1.02.1808300 或以上...在很久以前,我一定是先下载dayjs的JS文件,然后src链接到项目中。 不过现在不需要了,微信小程序支持使用npm来管理第三方包,...
  • 修改代码后,点击编译, 编译之后的结果依然是之前的,没有改变。 关闭程序,重新打开,才有。 解决方法: 在设置中找到通用设置,取消勾选“使用新版文件监听模块” 即可。
  • 尽管说小程序依附于微信,但是如果能做好小程序运营,每天的流量和客流都是不可或缺的。为自己的平台带来可观的转化数量,那么小程序运营我们应该注意哪些重要因素呢?怎样才能在实际操作中得到推广,让更多人了解? ...
  • 微信小程序结合云数据库实现点赞功能微信小程序结合云数据库实现点赞功能提示 微信小程序结合云数据库实现点赞功能的实现: 方法很简便:在js中添加onShareTimeline()函数即可,分享到朋友圈的展示形式是小程序logo...
  • 小程序小白入门 最开始的时候,我不知道该如何上传自己的代码。打开微信开发平台,找到“工具”选项,再点击“上传”就好了 ①找到“工具”选项 ②点击“上传” 然后在微信公众微信公众平台|小程序中,我找不到...
  • 微信小程序风靡全国已经好多年了,首先是微信小程序,后面百度等多个平台都发布了自己的小程序了,可我还从未尝试开发一个玩玩,其实对于一个程序员而言,开发一个小程序实在不是什么难事情,所以今天就要聊此心愿...
  • 微信小程序支付详解:

    万次阅读 2018-09-12 18:49:34
    前段时间在公司的开发了一个微信小程序的项目,今天来说...现在来说说我对小程序支付的理解,首先我们在开发文档中找到小程序支付流, 上面的图是我们支付的流程图,下面是开发要调用接口的顺序, 首先第一步......

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 282,100
精华内容 112,840
热门标签
关键字:

怎么找到以前用过的小程序