- 小程序图文编辑器页面制作
[图片] wxml [代码]<view class='ceng' hidden='{{!showceng}}' catchtouchmove='true'></view> <!-- editTxt-titt --> <view class='edit-txt' hidden='{{!showedittitt}}' catchtouchmove='true'> <textarea placeholder='请编辑文字' value='{{edittitt}}' bindconfirm="editedtitt" maxlength="300" /> </view> <!-- editTxt-content --> <view class='edit-txt' hidden='{{!showeditcontent}}' catchtouchmove='true'> <textarea placeholder='请编辑文字' value='{{editcontent}}' bindconfirm="editedcontent" maxlength="300" /> </view> <!-- reditTxt-content 标题输入,首编辑输入,重新编辑输入是分别使用三个不同的编辑框实现--> <view class='edit-txt' hidden='{{!showreditcontent}}' catchtouchmove='true'> <textarea placeholder='请编辑文字' value='{{reditcontent}}' bindconfirm="reditedcontent" maxlength="300" /> </view> <view class='k-bai'> <view class='txt titt' data-name='titt' bindtap='towrite'> {{titt}} <image src='/images/delet.png' class='delet-icon' data-name='titt' catchtap='ondelettitt' wx:if='{{titt!="请输入标题文字"}}'></image> </view> </view> <view class='content k-bai' wx:for="{{content}}" wx:key="" data-leixing='{{item.leixing}}' data-index='{{index}}' bindtap='redit'> <view class='txt' wx:if="{{item.leixing=='txt'}}">{{item.neirong}}</view> <image src='{{item.url}}' class='image' mode="widthFix" wx:if="{{item.leixing=='img'}}"></image> <image src='/images/delet.png' class='delet-icon' data-index='{{index}}' catchtap='ondelet' wx:if="{{content[index]!=''}}"></image> </view> <view class='add'> <image src='/images/add_06.png' bindtap='addtxt'></image> <image src='/images/add_03.png' bindtap='addimg'></image> </view> <view class='save-btn' bindtap='onsave'>上传</view> [代码] js [代码]// pages/edit/edit.js Page({ /** * 页面的初始数据 */ data: { titt: '请输入标题文字', showceng: false, showedittitt: false, showeditcontent: false, showreditcontent: false, edittitt: '', editcontent: '', reditcontent: '', target: '', content: [{ leixing: 'txt', neirong: '我爱你' }, { leixing: 'img', url: 'http://wechatpx.oss-cn-beijing.aliyuncs.com/card1_03.png' } ], }, /** * 生命周期函数--监听页面加载 */ towrite: function(e) { var that = this var target = e.currentTarget.dataset.name that.setData({ showceng: true, showedittitt: true, target: target, edittitt: '' }) }, editedtitt: function(e) { var that = this var target = that.target that.setData({ titt: e.detail.value, showceng: false, showedittitt: false, [target]: e.detail.value }) }, ondelettitt: function(e) { var that = this wx.showModal({ title: '重置标题', content: '您确定要重置标题吗?', success(res) { if (res.confirm) { that.setData({ titt: '请输入标题文字' }) } else if (res.cancel) { } }, confirmColor: '#5677fc' }) }, ondelet: function(e) { var that = this var index = e.currentTarget.dataset.index var content = that.data.content wx.showModal({ title: '删除提示', content: '您确定要删除这段编辑吗?', success(res) { if (res.confirm) { content.splice(index, 1) that.setData({ content: content }) } else if (res.cancel) {} }, confirmColor: '#5677fc' }) }, addtxt: function() { var that = this var content = that.data.content that.setData({ editcontent:'', showceng: true, showeditcontent: true }) }, editedcontent: function(e) { var that = this var input = new Object input.leixing = 'txt' input.neirong = e.detail.value var content = that.data.content content.push(input) that.setData({ content:content, showceng: false, showeditcontent: false }) }, redit:function(e){ var that = this var index = e.currentTarget.dataset.index var leixing = e.currentTarget.dataset.leixing var target = that.data.target if(leixing=='txt'){ target = "content["+index+"].neirong" that.setData({ reditcontent:'', showceng: true, showreditcontent: true, target: target }) }else if(leixing=='img'){ wx.chooseImage({ count: 1, sizeType: ['original', 'compressed'], sourceType: ['album', 'camera'], success(res) { const tempFilePaths = res.tempFilePaths target = "content[" + index + "].url" that.setData({ [target]: tempFilePaths }) } }) } }, reditedcontent: function (e) { var that = this var target = that.data.target that.setData({ [target]: e.detail.value, showceng: false, showreditcontent: false, }) }, addimg:function(){ var that = this wx.chooseImage({ count: 1, sizeType: ['original', 'compressed'], sourceType: ['album', 'camera'], success(res) { const tempFilePaths = res.tempFilePaths var input = new Object input.leixing = 'img' input.url = tempFilePaths var content = that.data.content content.push(input) that.setData({ content: content, }) } }) }, onsave:function(){ wx.showToast({ title: '上传成功!', }) }, onLoad: function(options) { }, /** * 生命周期函数--监听页面初次渲染完成 */ onReady: function() { }, /** * 生命周期函数--监听页面显示 */ onShow: function() { }, /** * 生命周期函数--监听页面隐藏 */ onHide: function() { }, /** * 生命周期函数--监听页面卸载 */ onUnload: function() { }, /** * 页面相关事件处理函数--监听用户下拉动作 */ onPullDownRefresh: function() { }, /** * 页面上拉触底事件的处理函数 */ onReachBottom: function() { }, /** * 用户点击右上角分享 */ onShareAppMessage: function() { } }) [代码] wxss [代码]/* pages/edit/edit.wxss */ page { background-color: #f1f1f1; font-size: 28rpx; padding-bottom: 150rpx; } .k-bai { background-color: #fff; padding: 30rpx; color: #666; } .txt { padding: 30rpx; border: 1rpx solid #eee; margin-top: 20rpx; position: relative; } .delet-icon { display: block; width: 50rpx; height: 50rpx; border-radius: 50rpx; position: absolute; right: -20rpx; top: -20rpx; z-index: 10; } .ceng { width: 750rpx; height: 1334rpx; position: fixed; left: 0; top: 0; z-index: 50; background-color: rgba(0, 0, 0, 0.3); } .edit-txt { width: 660rpx; background-color: #fff; padding: 30rpx; margin: 0 auto; position: fixed; left: 50%; margin-left: -360rpx; top: 220rpx; z-index: 60; } .edit-txt .save-btn { display: block; width: 450rpx; height: 80rpx; border-radius: 80rpx; background-color: #5677fc; color: #fff; text-align: center; line-height: 80rpx; position: absolute; left: 50%; margin-left: -225rpx; bottom: -40rpx; box-shadow: 0 0 10rpx rgba(0, 0, 0, 0.2); } .edit-txt textarea { width: 660rpx; height: 500rpx; } .add { position: relative; padding: 20rpx 0; width: 200rpx; margin: 0 auto; height: 70rpx; background-color: #fff; border-radius: 0 0 20rpx 20rpx; box-shadow: 0 7rpx 5rpx rgba(0, 0, 0, 0.1); } .add image { display: inline-block; width: 70rpx; height: 70rpx; } .add image:first-child { margin-right: 20rpx; margin-left: 20rpx; } .content { margin-top: 30rpx; position: relative; } .content .delet-icon { right: 12rpx; top: 25rpx; } .content .image { display: block; padding: 30rpx; border: 1rpx solid #eee; margin-top: 20rpx; position: relative; width: 630rpx; } .save-btn { width: 690rpx; height: 90rpx; text-align: center; line-height: 90rpx; background-color: #5677fc; color: #fff; font-size: 34rpx; border-radius: 90rpx; position: fixed; left: 50%; margin-left: -345rpx; bottom: 30rpx; z-index: 100; } [代码]
2019-07-29 - 小程序云开发支付,没有我自己的服务器。怎样用一个云函数收到支付回调通知?
我的小程序纯粹云开发,用云数据库,没有自己的服务器。 业务需求:微信购物,支付,成功后更改商品状态(比如“待支付”变成“已支付”)。 目前用的是这个tenpay (https://blog.csdn.net/qiushi_1990/article/details/99347580),完成下单,其实tenpay背后应该是用了“统一下单API (https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_1)”,可以指定一个“通知地址 notify_url 参数”但是必须是我自己的服务器网址,比如http://hello-world.com/。但是我没有自己的服务器,也就意味着我无法获得用户支付成功的通知,也不能靠这个来触发回调函数(比如更改商品状态)。 客户端支付的代码是这个API: https://developers.weixin.qq.com/miniprogram/dev/api/open-api/payment/wx.requestPayment.html。在这个客户端我可以写一个支付成功的success回调函数,比如 success(){ /* 从客户端触发云函数,更改商品状态为“已支付” */ call_cloud_function_to_change_products_to_paid_status(); } 如果这样做就意味着第一步:用户A进行了支付。第二步:用户A自己通知后台“我已经付了钱了。请发货。”由于这2步代码都在前端,那么黑客岂不是可以直接触发第二步函数,骗商家发货。理想方法应该是第一步:用户A支付。第二步:腾讯主动触发我的云函数X,通知我继续发货等。请问该怎么解决我的问题? 另外,我也注意到,如果用CloudPay.unifiedOrder() https://developers.weixin.qq.com/miniprogram/dev/wxcloud/reference-sdk-api/open/pay/CloudPay.unifiedOrder.html 则可以指定一个云函数作为支付成功后的回调,但是它需要 sub_mch_id (子商户号)而不能用 mch_id 或 merchant_id (商户号)。目前我的情况是只有一个商户号,没有子商户号。我是否应该去弄一个子商户号?
2020-12-06 - 微信小程序 云开发 生成带参数小程序二维码
1. 云开发新建云函数getQrCode // 云函数入口文件 const cloud = require('wx-server-sdk'); cloud.init() // 云函数入口函数 exports.main = async (event, context) => { const full_path = event.page + '?' + event.scene; try { // 生成小程序码 const wxacodeResult = await cloud.openapi.wxacode.getUnlimited({ scene: event.scene, page: event.page, width: 240 }) // return wxacodeResult; if (wxacodeResult.errCode != 0) { // 生成二维码失败,返回错误信息 return wxacodeResult; } // 上传到云存储 const uploadResult = await cloud.uploadFile({ cloudPath: 'qr/' + new Date().getTime() + '.jpg', fileContent: wxacodeResult.buffer, }); // return uploadResult; if (!uploadResult.fileID) { //上传失败,返回错误信息 return uploadResult; } // 获取图片临时路径 getURLReault = await cloud.getTempFileURL({ fileList: [uploadResult.fileID] }); fileObj = getURLReault.fileList[0]; fileObj.fromCache = false; // 上传成功,获取文件临时url,返回临时路径的查询结果 return fileObj; } catch (err) { return err } } 2. 前端js调用并显示 onPreview(e) { wx.cloud.callFunction({ name: "getQrCode", data: { page: 'pages/index/index', scene: 'id=6666', thumbs_up_task_id: 111 }, success: res => { console.log(res) wx.previewImage({ urls: [res.result.fileID], }) } }) } 3. 效果图 [图片]
2020-08-20