网海拾贝网络猪 / 软件开发 / Python 开发者的微信小程序开发实践

分享

   

Python 开发者的微信小程序开发实践

2018-06-27  网海拾贝...

导读

在知乎上,有人提问“如何使用 Python 开发微信小程序”。

其实微信小程序作为一个前端的机制,Python 并不能插上边。只不过可以作为后端接口为微信小程序提供数据服务而已。

那么在本篇,我们就将结合微信小程序开发与 Python Web 开发,来完成一个朋友圈神器微信小程序的开发,这个微信小程序作为一个工具型的应用,供用户输入姓名或其他字段,生成一个带有炫耀成分的照片。

比如,移民申请表照片:

高额工资单照片:

豪车订单照片:

下面,就开干吧!

注册一个微信小程序

开发微信小程序,首先肯定需要去微信公众平台上注册一个微信小程序了,我们在微信公众平台的注册页面选择“小程序”进行注册。

接着有三个步骤:邮箱注册、邮箱激活和信息登记:

完成上述三个步骤后,就可以登录进入管理中心:

在基本设置中,我们可以设置微信小程序的名称、头像、说明等基本信息。

在开发设置中,我们可以获取到小程序的 AppID 和 AppSecret,这在后续的开发中会使用到,同时我们可以在此设置小程序服务器的域名:

安装和使用微信 Web 开发者工具

开发微信小程序需要使用到微信 Web 开发工具这一软件。我们下载并安装好。

启动之后,需要我们使用微信扫码进行登录:

之后,新建一个小程序项目:

指定小程序的项目目录、输入小程序的 AppID(管理页面中获取)、输入项目名称,之后我们就进入了微信开发工具的主界面了:

因为我们使用了快速启动的模板,所以自动生成了一个 Hello World 的 Demo。接下来,我们创建我们的票圈神器的小程序页面。

创建微信小程序页面

在创建小程序的页面之前,我们先来了解一下微信小程序的代码结构。

根据微信小程序开发文档的介绍:小程序包含一个描述整体程序的 app 和多个描述各自页面的 page。

一个小程序主体部分由以下三个文件组成,必须放在项目的根目录。

  • app.js(定义小程序的逻辑)
  • app.json(定义小程序的公共配置)
  • app.wxss(定义小程序的公共样式表)

同时,一个小程序的页面由四个文件组成:

  • JavaScript 文件(定义页面逻辑)
  • WXML 文件(定义页面结构)
  • WXSS 文件(定义页面样式)
  • JSON 文件(定义页面配置)

微信小程序的视图层负责页面的展示,由 WXML 文件描述页面结构和 WXSS 文件描述页面的样式。

WXML 和 WXSS 是什么东西呢?我们可以拿 HTML 和 CSS 来与之进行类比。虽然它们不一样,但是它们真的很相似。

WXML 是一套微信定义的可嵌套的标记语言,而 WXSS 则具备 CSS 的大部分特性,并对 CSS 进行了扩充和修改。

接下来我们来规划一下我们的小程序的页面构成:

  • 首页列表页:用于显示可用于制作照片的条目;
  • 详情表单页:用于显示照片效果以及接收用户输入信息;
  • 照片结果页:用于显示生成的照片以及提供保存按钮;

创建页面目录和文件

首先,我们在项目目录结构的 pages 路径下新建一个 detail 目录,其下包含三个同名的 JS 文件、WXML 文件、WXSS 文件;一个 result 目录,其下包含三个同名的 JS 文件、WXML 文件、WXSS 文件;最后 pages 目录下的结构如下图所示:

然后,在创建的 JS 文件中输入以下代码:

Page({

  /**
   * 页面的初始数据
   */
  data: {

  },

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {

  },

  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady: function () {

  },

  /**
   * 生命周期函数--监听页面显示
   */
  onShow: function () {

  },

  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide: function () {

  },

  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload: function () {

  },

  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh: function () {

  },

  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom: function () {

  },

  /**
   * 用户点击右上角分享
   */
  onShareAppMessage: function () {

  }
})

Page() 函数用来注册一个页面。接受一个 object 参数,以指定页面的初始数据、生命周期函数、事件处理函数等。

使用微信开发者工具的智能提示可以快速生成这些代码:

完成这一步之后,我们打开项目根目录的 app.json 文件:

在pages列表中添加如下代码:

"pages/detail/detail",
"pages/result/result",

最后 app.json 文件中 pages 列表的值应该为:

[
    "pages/index/index",
    "pages/detail/detail",
    "pages/result/result",
    "pages/logs/logs"
  ],

编辑列表页面

首先,我们在列表页面放置一个轮播图,让我们的页面不显单调。准备三张图片:

在项目根路径下新建一个名为 imgs 的目录,将三张轮播图片复制进去:

在 index.js 文件的 Page 实例中,在 data 字典添加一个键值对,用于指定本地轮播图片的位置:

删除 index.wxml 文件中的所有代码,输入以下代码以创建一个轮播图:

<swiper class="swiper" indicator-dots="true" autoplay="true" interval="5000" duration="1000">  
   <block wx:for="{{headimg}}" wx:for-index="index">  
    <swiper-item>  
     <image src="{{item.url}}" class="slide-image" mode="aspectFill"/>  
    </swiper-item>  
   </block>  
</swiper>

其中:

  • swiper 标签表示滑块视图容器;
  • swiper-item 标签则表示滑块的条目;
  • block 标签表示一个标签块

我们可以看到,在 block 标签中,我们为其设置了 wx:for 属性,这个属性用于列表渲染,绑定了 Page 的 data 中的 headimg 数组(在微信小程序中,WXML 中的动态数据都来自于对应 JS 文件 Page 中的 data 数据)。

接着,调整轮播图的样式,在 index.wxss 文件中输入以下代码:

.swiper {
 height: 400rpx;
 width: 100%;
}
.swiper image {
 height: 100%;
 width: 100%;
}

最后保存文件,在微信开发者工具中可以预览到我们的轮播图已经创建成功:

创建完轮播图之后,我们继续编辑创建图片列表结构。

<view class="temp_box">
  <block wx:for="{{templist}}">
    <view class="temp_item">
      <navigator url="../detail/detail?tid={{item.id}}">
        <image src="https://www.huabandata.com/{{item.icon}}"></image>
        <view class="content">
          <text>{{item.name}}</text>
        </view>
      </navigator>
    </view>
  </block>
</view>

在页面的列表结构中,我们使用一个 view 标签作为外部容器,里面定义了一个 block 标签用于遍历图片模板数据生成多个图片信息,定义渲染的数组为 templist,这个我们将在 index.js 文件中进行定义和声明。

同时使用了 navigator 标签,用于页面的跳转,设置一个参数 tid 并将模板的 id 作为值,使其能够跳转到具体模板的详情页面。

然后在 index.wxss 文件中添加以下样式:

/* 模板图片列表 */
.temp_box {
    margin: 3px;
    width: 100%;
}
.temp_item {
    display: inline-block;
    width: 48%;
    margin: 0.5%;
    background-color: white;
}
.temp_item image {
    width: 100%;
    height: 160px;
}
.temp_item .content {
    width: 100%;
    height: 32px;
    margin: 5px;
}
.temp_item .content text {
    font-size: 12px;
    line-height: 16px;
    overflow: hidden;
    text-overflow: ellipsis;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
}

如果 templist 数组有合适的数据,那么其渲染出来的页面应该是下面这样的:

编辑详情页面

详情页面相较于列表页面简单很多,由两个结构组成:

  • 图片模板;
  • 表单输入框;
  • 提交按钮;

所以我们的详情页面 detail.wxml 的结构为:

<view class='temp'>
  <image src='https://www.xxx.com/{{tempData.img}}'></image>
</view>
<form bindsubmit='generate'>
  <view class="form">
    <view class='li'>
      <image class='icon' src='http://www.xxx.com/media/resume/icon_user.png'></image>
      <input class='input' placeholder='请输入{{tempData.hint}}' name='content'></input>
    </view>
</view>
<button class="button" form-type='submit'>立刻生成照片</button>
</form>

在这里,我们通过 <view> 标签包裹着 <image> 标签来显示图像,然后用一个 form 表单标签包裹着 input 输入框和 button 提交按钮。

在 button 按钮中,我们通过设置 form-type 属性为 submit,使得点击这个按钮时会提交表单。

表单的提交处理由 <form> 标签的 bindsubmit 属性来控制,在此我们指定了处理函数为 generate,我们将在 detail.js 中对 generate 函数进行定义。

然后,在 detail.wxss 中对其进行样式设计:

page{background-color: #efeff4}
.temp{
  background-color: white;
  border: #e5e5e5 solid 1px; 
  display: flex; 
  align-items: center;
  justify-content:center;
}
.temp image{
   height: 320px;
}
.form{
  margin-top: 20rpx; 
  background-color: white;
  border: #e5e5e5 solid 1px; 
  border-right: none;  
  border-left: none;  }
.li{
  height: 100rpx; 
  border-bottom: #e5e5e5 solid 1px; 
  width: 90%; 
  margin: auto; 
  display: flex; 
  align-items: center }
.input{padding-left: 20rpx;  width: 94%; color: black}
.icon{
  width: 50rpx;
  height: 50rpx;
}
.button{
    background-color: #09bb07; 
    margin: auto; 
    margin-top:20rpx;
    margin-bottom: 20rpx;  
    width: 90%; 
    color: white 
}

如果 tempData 数组中有正确的数据,那么详情页面的显示效果如下所示:

编辑结果页面

结果页面与详情页面类似,同样是显示一个图片,和一个按钮(用于保存照片至本地),所以将 detail 页面的结构和样式稍作修改即可。

result.wxml:

<view class='temp'>
  <image src='https://www.xxx.com/{{imgurl}}'></image>
</view>
<button class="button" form-type='submit' bindtap='savePhoto'>保存照片</button>

reault.wxss:

page{background-color: #efeff4}
.temp{
  background-color: white;
  border: #e5e5e5 solid 1px; 
  display: flex; 
  align-items: center;
  justify-content:center;
}
.temp image{
   height: 320px;
}
.button{
    background-color: #09bb07; 
    margin: auto; 
    margin-top:20rpx;
    margin-bottom: 20rpx;  
    width: 90%; 
    color: white 
}

如果 imgurl 数组有正确的数据,那么结果页面的显示效果如下所示:

创建 Django 应用

在小程序的页面创建和设计好之后,我们需要创建一个 API 数据接口,供小程序请求获取,以生成供 WXML 页面进行渲染的数组。

因为本篇讲的是《Python 开发者的微信小程序开发实践》,自然使用的是 Python 语言,而我对 Django 相对比较熟悉,所以我们使用的是 Django 框架来对小程序提供 API 接口。

我已经有一个 Django 项目在运行,所以在此直接在此项目下创建 Django App:

python3 manage.py startapp pyq_tool

通过 PIL 模块合成一张装 X 照片

要生成一张那样可用来炫耀的图片,其实很简单,利用图像处理模块,在图片上添加相应字体的文字即可。

在 Python 中,我们使用 PIL 模块对图像进行处理,其可以通过 pip 命令进行安装:

pip install pillow

下面我们介绍一下使用 PIL 库生成一张装 X 图片的过程:

(1)引入核心模块:

from PIL import Image,ImageDraw,ImageFont

其中,Image 是图像类的包装器,ImageDraw 用于对图片界面进行操作,ImageFont 用于进行光栅字体管理。

(2)根据图片大小,创建一个新的图像:

bg = Image.new("RGB",(640,853))

(3)打开图片:

im = Image.open(r"toutu3.jpg")

(4)合并两个图片为一个新的图像:

draw2 = Image.blend(bg,im,1.0)

(5)创建一个图像绘制对象:

draw = ImageDraw.Draw(draw2)

(6)添加一个字体并指定字体大小:

ttfont = ImageFont.truetype(r"gb.ttf",30)

(7)在图像绘制对象中添加文字:

draw.text((230,120),'州的现实', fill=(20,20,20),font=ttfont)

(8)最后显示图像:

draw2.show()

这样,我们就使用 Python 的 PIL 模块完成了图像的操作从而制作出了一个新的图像,结果为:

如果我们需要保存图像,则第8步改成:

draw2.save()

创建应用数据模型、视图函数和 URL路由

创建数据模型

根据上面生成照片的代码,我们可以发现不同照片之间共同的部分和不同的部分,共同的部分就是代码的结构和图像处理的逻辑,不同的部分则是图片、图片的大小,字体的类型和大小,文本的内容和颜色等。

将这些不同之处,提取出来,我们可以创建一个数据模型用于保存不同模板图片的信息,以根据不同的模板,使用同一台代码生成不同的照片。所以,我们在 pyq_tool 目录下的 models.py 文件中创建一个数据模型来保存不同模板图片的数据:

from django.db import models

# Create your models here.
class Tempinfo(models.Model):
    name = models.CharField(max_length=20,verbose_name="模板名称")
    font = models.CharField(max_length=5,verbose_name='字体代码')
    fontsize = models.IntegerField(verbose_name="字体大小")
    img = models.ImageField(upload_to='pyq_tool',verbose_name="模板图片")
    imgsize = models.CharField(max_length=10,verbose_name='图片大小')
    icon = models.ImageField(upload_to='pyq_tool',verbose_name="图标")
    hint = models.CharField(max_length=10,verbose_name="输入提示")
    textcolor = models.CharField(max_length=15,verbose_name='文本颜色')
    textplace = models.CharField(max_length=10,verbose_name='文本位置')
    text2 = models.CharField(max_length=15,verbose_name='日期文本',null=True,blank=True)
    text2hint = models.CharField(max_length=10,verbose_name="文本2提示",null=True,blank=True)
    text2place = models.CharField(max_length=10,verbose_name='日期位置',null=True,blank=True)

    def __str__(self):
        return self.name

    class Meta:
        verbose_name = '票圈神器'
        verbose_name_plural = verbose_name

然后将 pyqtool 添加进 settings.py 文件中的 INSTALLEDAPPS 列表中,使用 makemigrations 和 migrate 命令生成数据模型。最后,每一个图片模板的信息如下图所示:

根据收集好的装 X 图片模板,向数据库中添加几条数据:

创建视图函数

在数据库中有了数据之后,我们来创建视图函数,在创建具体视图函数之前,我们先引入需要使用到的模块:

from django.shortcuts import render
from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt
from .models import Tempinfo
from dss.Serializer import serializer
from django.views.generic import ListView
from dss.Mixin import MultipleJsonResponseMixin
from PIL import Image,ImageDraw,ImageFont
import datetime
import os

为了简单快捷的序列化模型数据,在此我们使用一个第三方的 Django 序列化模块——Django Simple Serializer,一个由国人开发的 Django 数据快速序列化方案。

首先是模板列表视图,用于返回一个多条数据组成数组供小程序的首页列表页进行渲染 WXML:

# 获取模板列表
class GetTempList(MultipleJsonResponseMixin,ListView):
    model = Tempinfo
    queryset = Tempinfo.objects.all()
    paginate_by = 6

创建一个基于类的视图,借助 Django Simple Serializer 生成一个分页接口,每页6条数据。

然后是模板详情视图,根据模板 id 查询并返回模板的数据:

@csrf_exempt
def get_temp_detail(request):
    if request.method == 'POST':
        id = request.POST.get('tid','')
        if id is not '':
            try:
                detail = Tempinfo.objects.get(id=id)
                detail = serializer(detail,datetime_format='string')
                return JsonResponse({'sucess':True,'data':detail})
            except Exception as e:
                return JsonResponse({'success':False,'data':str(e)})
        else:
            return JsonResponse({'success':False,'data':'没有数据'})

最后是照片的生成视图:

@csrf_exempt
def generate_photo(request):
    if request.method == 'POST':
        id = request.POST.get('tid','')
        content = request.POST.get('content','')
        if id != '' and content != '':
            try:
                temp = Tempinfo.objects.get(id=id)
                fontpath = os.path.join(BASE_DIR,'media/pyq_font/{font}.ttf'.format(font=temp.font))
                ttfont = ImageFont.truetype(fontpath,int(temp.fontsize))
                # 图片大小
                imgsize = temp.imgsize.split(",")
                try:
                    bg = Image.new("RGB",(int(imgsize[0]),int(imgsize[1])))
                except Exception as e:
                    return JsonResponse({'success':False,'data':'图片大小出错:'+str(e)})
                im = Image.open(temp.img)
                draw2 = Image.blend(bg,im,1.0)
                draw = ImageDraw.Draw(draw2)
                try:
                    textplace = temp.textplace.split(",")
                    textcolor = temp.textcolor.split(",")
                    draw.text((int(textplace[0]), int(textplace[1])),content, fill=(int(textcolor[0]), int(textcolor[1]), int(textcolor[2])),font=ttfont)
                except Exception as e:
                    return JsonResponse({'success':False,'data':'文字颜色位置出错:'+str(e)})
                if temp.text2 != '':
                    text2place = temp.text2place.split(",")
                    draw.text((int(text2place[0]), int(text2place[1])),
                              datetime.date.strftime(datetime.date.today(),"%Y-%m-%d"),
                              fill=(int(textcolor[0]), int(textcolor[1]), int(textcolor[2])),
                              font=ttfont)
                filename = str(datetime.datetime.today()).replace(':','-').replace(' ','-').replace('.','')
                photoname = os.path.join(BASE_DIR,'media/pyq_photo/{0}.jpg'.format(filename))
                draw2.save(photoname)
                return JsonResponse({'success':True,'data':'media/pyq_photo/{0}.jpg'.format(filename)})
            except Exception as e:
                return JsonResponse({'success':False,'data':str(e)})
        else:
            return JsonResponse({'success':False,'data':'不能为空'})

我们的小程序目前只需要使用到这三个视图函数。接下来创建 URL 路由。

创建 URL 路由

在 views.py 同级目录下新建一个 pqy_tool 应用的 urls.py 文件,将以下代码写入:

from django.conf.urls import url, include
from . import views

urlpatterns = [
    url(r'^templist/',views.GetTempList.as_view()),
    url(r'^tempdetail/',views.get_temp_detail),
    url(r'^generate/',views.generate_photo),
]

然后,再在 settings.py 文件同级目录下的 urls.py 中,将 pyq_tool 应用的 urls.py 包含进项目的 URl 路由中:

# 票圈神器
    url(r'^pyq/',include('pyq_tool.urls')),

完成这一步,我们的 Django API 接口就完成了。测试一下列表接口,结果显示正常:

微信小程序请求 Django 接口

在完成后台 API 数据接口的创建之后,我们需要做的就是让微信小程序请求这些接口并解析数据。这些步骤,都分别在 index.js、detai.js 和 result.js 中完成。

列表页面数据请求

在 index.js 文件中,我们在 data 字典中定义两个空的变量:

  data: {
    headimg: [
      { url: '/imgs/head1.png' },
      { url: '/imgs/head2.png' },
      { url: '/imgs/head3.png' },
    ],
    templist:[],
    next:''
  },

templist 用于填充模板列表数据,next 用于标识分页。

然后在 onload() 函数中,使用小程序的网络请求接口 wx.request() 方法对模板列表的 API 进行请求,将获取到的数据赋值给 templist 和 next:

onLoad: function () {
    var that = this;
    //获取模板列表
    wx.request({
      url: 'https://www.huabandata.com/pyq/templist/',
      method: 'GET', // OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, CONNECT
      header: { 'content-type': 'application/x-www-form-urlencoded' }, // 设置请求的 header
      success: function (res) {
        console.log(res)
        // success
        if (res.data) {
          that.setData({
            templist: res.data.tempinfo_list,
            next: res.data.page_obj.next
          })
          console.log(that.data)
        } else {
          wx.showToast({
            title: '服务器开了小差,下拉刷新一下',
            icon: 'waring',
            duration: 3000
          })
        }
      },
      fail: function (res) {
        // fail
        wx.showToast({
          title: '服务器开了小差,下拉刷新一下',
          icon: 'waring',
          duration: 3000
        })
      },
      complete: function (res) {
        // complete
      }
    })
  },

完成这一步,我们就可以在首页看到通过 wx.request 请求、经由 WXML 的 wx:for 属性渲染后的数据了:

这样,列表页面的功能基本实现了,我们还需要添加一个下拉刷新和上拉加载下一页的功能。首先在 app.json 中的 window 字典中添加:

"enablePullDownRefresh": true

以开启下拉刷新的功能。然后在 index.js 的 onPullDownRefresh 函数中添加下拉刷新的代码,与 onLoad() 函数的代码类似:

  onPullDownRefresh: function (i) {
    var that = this;
    wx.request({
      url: 'https://www.huabandata.com/pyq/templist/',
      method: 'GET', // OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, CONNECT
      header: { 'content-type': 'application/x-www-form-urlencoded' }, // 设置请求的 header
      success: function (res) {
        console.log(res)
        // success
        if (res.data) {
          that.setData({
            templist: res.data.tempinfo_list,
            next: res.data.page_obj.next
          })
          console.log(that.data)
        } else {
          wx.showToast({
            title: '服务器开了小差,下拉刷新一下',
            icon: 'waring',
            duration: 3000
          })
        }
      },
      fail: function (res) {
        // fail
        wx.showToast({
          title: '服务器开了小差,下拉刷新一下',
          icon: 'waring',
          duration: 3000
        })
      },
      complete: function (res) {
        // complete
      }
    })
    wx.showToast({
      title: '刷新成功',
      icon: 'success',
      duration: 2000
    })
    console.log('刷新')
  },

再是上拉加载下一页的 onReachBottom() 函数,通过 next 来判断是否存在下一次,如果存在则传入页面参数并请求,如果不存在则提示“没有更多了”:

  onReachBottom: function (i) {
    var that = this;
    if (that.data.next != null) {
      wx.request({
        url: 'https://www.huabandata.com/pyq/templist/',
        data: {
          'page': that.data.next
        },
        method: 'GET', // OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, CONNECT
        header: { 'content-type': 'application/x-www-form-urlencoded' }, // 设置请求的 header
        success: function (res) {
          console.log(res)
          // success
          if (res.data.is_paginated) {
            that.setData({
              templist: that.data.templist.concat(res.data.tempinfo_list),
              next: res.data.page_obj.next
            })
            console.log(that.data)
          } else {
            wx.showToast({
              title: '服务器开了小差,下拉刷新一下',
              icon: 'waring',
              duration: 3000
            })
          }
        },
        fail: function (res) {
          // fail
          wx.showToast({
            title: '服务器开了小差,下拉刷新一下',
            icon: 'waring',
            duration: 3000
          })
        },
        complete: function (res) {
          // complete
        }
      })
    } else {
      wx.showToast({
        title: '没有更多了',
        icon: 'info',
        duration: 2000
      })
    }

    console.log('加载下一页')
  },
})

完成这两个函数的编写,那么效果将如下所示:

详情页面数据请求

详情页面在 detail.js 中主要有两个函数进行数据请求:

  • 获取从列表页跳转来模板 id,对 id 请求具体的模板数据;
  • 传递模板 id 和表达文本内容以生成照片。

第一个请求我们直接可以在 onLoad() 函数中完成:

  onLoad: function (options) {
    var that = this;
    var tid = options.tid
    //获取模板详情
    wx.request({
      url: 'https://www.huabandata.com/pyq/tempdetail/',
      data:{
        'tid':tid
      },
      method:'POST',
      header: { 'content-type': 'application/x-www-form-urlencoded' },
      success:function(res){
        console.log(res)
        that.setData({
          tempData:res.data.data
        })
      },fail:function(res){
        //fail
      },complete:function(res){
        //complete
      }
    })
  },

对表单数据的提交,我们在 detail.wxml 文件的 form 标签中绑定了 generate 函数,所以,我们在 detail.js 文件的 Page() 中新建一个 generate() 函数,将模板 id 和表达内容传递给照片生成的 URL,如果请求成功获取到了照片的 URL,那么使用小程序的重定向方法 wx.wx.redirectTo() 附带上照片的 URL 跳转到结果页面,如果请求失败则提示生成出错:

  generate:function(e){
    var that = this;
    console.log('提交的表单信息为', e)
    console.log('当前数据为:', that.data)
    var tid = that.data.tempData.id;
    var content = e.detail.value.content;
    //显示加载框
    wx.showLoading({
      title: '照片制作中',
    })
    wx.request({
      url: 'https://www.huabandata.com/pyq/generate/',
      method:'POST',
      data:{'tid':tid,'content':content},
      header: { 'content-type': 'application/x-www-form-urlencoded' },
      success: function (res) {
        console.log(res)
        if(res.data.success){
          wx.hideLoading()
          wx.redirectTo({
            url: '../result/result?imgurl=' + res.data.data
          })
        }else{
          wx.hideLoading()
          wx.showToast({
            title: '生成出错'
          })
        }
      }, fail: function (res) {
        //fail
        wx.hideLoading()
        wx.showToast({
          title: '生成出错'
        })
      }, complete: function (res) {
        //complete
      }
    })
  },

详情页面最后呈现为:

结果页面

结果页面相对比较简单,获取到页面跳转过来附带的照片 URL 将其赋值给imgURL,就可以完成生成后的照片的显示:

  onLoad: function (options) {
    var that = this
    console.log(options)
    console.log('点击某个模板跳转到', options.imgurl)
    const imgurl = options.imgurl
    that.setData({ imgurl: imgurl })
  },

接着,定义保存照片的函数 savePhoto(),在微信小程序中,保存一个图片需要两个步骤:

  1. 使用 wx.getImageInfo() 方法传递一个图片文件路径(相对路径、临时文件路径、存储文件路径、网络图片路径)获取图片的信息,其结果会返回图片的本地路径;
  2. 再使用 wx.saveImageToPhotosAlbum() 方法传递一个图片文件路径(不支持网络图片路径)以保存图片到系统相册

所以,我们的 savePhoto() 函数为:

  savePhoto:function(i){
    var that = this;
    // wx.authorize({
    //   scope: 'scope.writePhotosAlbum',
    // })
    wx.getImageInfo({
      src: 'https://www.huabandata.com/'+that.data.imgurl,
      success:function(i){
        var path = i.path;
        wx.saveImageToPhotosAlbum({
          filePath: path,
          success(result){
            console.log(result)
            wx.showToast({
              title: '保存成功',
              icon: 'success',
              duration: 2000
            })
          }
        })
      }
    })
  },

其效果如下所示:

上架

到了这一步,我们的票圈神器小程序就开发完成了,接下来可以进行上传和上架了。

点击微信开发者工具工具栏的“上传”按钮:

image.png

其会提示我们上传成功后,需要将本次上传的版本设置为体验版:

接着输入此次上传的版本信息:

提示上传成功后,我们就可以在微信小程序管理后台的“开发管理”栏目下看到了:

我们可以直接提交审核,或者是将其选为体验版本,供指定的体验者进行前提体验测试。

我们直接提交审核,会要求我们填写相关的信息:

接着点击“提交审核”按钮即可。完成提交后,我们就可以在“开发管理”的审核版本中看到我们刚刚提交的版本了:

耐心等待审核通过吧。

如果不通过怎么办?嗯,改内容呗,毕竟:


    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多
    喜欢该文的人也喜欢 更多

    ×
    ×

    ¥.00

    微信或支付宝扫码支付:

    开通即同意《个图VIP服务协议》

    全部>>