前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >通过SCF做一个性格测试的小程序

通过SCF做一个性格测试的小程序

原创
作者头像
None-xiaomi
发布2019-10-08 10:18:29
2.6K1
发布2019-10-08 10:18:29
举报

十一在家期间,我看了九型人格这本书,觉得很不错,想要做一下测试,测试的时候就是去网上搜了一下相关的测试,就开始了。但是转念一想,能不能做一个专门测试的小程序,里面可以增加各种各样的测试题目?于是,“国庆没去旅游的我”就开始了基于SCF的测试小程序的编写。

当然,不适太会写小程序,所以代码也未必好看。前端就是微信小程序,用了WEUI,后端就是Python,数据库用了腾讯云的CDB。

废话不多说,直接上干货。

前端页面设计

由于我只是个人开发一个小工具,所以也没有设置原型图,就是根据看的WEUI进行了一些简单的拼装。先发一下效果图:

整体来说,勉勉强强,还可以看,这个前端,基本上就是使用了WEUI的那些组件,基本上和拼图类似,例如首页:

wxml:

代码语言:javascript
复制
<!--pages/index/index.wxml-->
<view>
  <view class="page__bd">
    <view>
      <swiper class="swiper" autoplay="true" interval="2000">
        <swiper-item wx:for="{{hot_test}}" wx:key="item">
          <image src="{{item.src}}" data-Tid='{{item.tid}}' bindtap='hotClick' mode="aspectFill" class="img"></image>
          <view class="child">{{item.title}}</view>
        </swiper-item>
      </swiper>
    </view>
  </view>
  <view class="page__bd">
    <view class="weui-cells  weui-grids">
      <block wx:for="{{category}}" wx:key="item">
        <navigator url="{{item.url}}" class="weui-grid" hover-class="weui-grid_active">
          <image class="weui-grid__icon" src="{{item.src}}" />
          <view class="weui-grid__label">{{item.title}}</view>
        </navigator>
      </block>
    </view>
  </view>
  
  <view class="weui-cells weui-cells_after-title">
  <view class="page__hd">
        <view class="page__title">热门测试</view>
  </view>
        <block wx:for="{{content}}" wx:key="item">
          <navigator url="/pages/content/index?tid={{item.tid}}" class="weui-cell weui-cell_access" hover-class="weui-cell_active">
            <block wx:if="{{item.type}}">
              <view class="weui-cell__hd">
                <image src="/image/content/{{item.icon}}.png" style="margin-right: 16px;vertical-align: middle;width:20px; height: 20px;"></image>
              </view>
              <view class="weui-cell__bd">{{item.title}}</view>
            </block>
            <block wx:else>
              <view class="weui-cell__hd">
                <image src="/image/content/{{item.icon}}.png" style="margin-right: 16px;vertical-align: middle;width:20px; height: 20px;" />
              </view>
              <view class="weui-cell__bd">
                <view>{{item.title}}</view>
                <view style="font-size: 13px;color: #888888;">{{item.desc}}</view>
              </view>
            </block>
          </navigator>
        </block>
      </view>
      <text>\n</text>
  <view class="weui-footer">
    <view class="weui-footer__text">爱测试 Copyright © 2019</view>
  </view>
  <text>\n\n\n</text>
  <view class="page__bd">
    <view class="weui-tabbar">
      <view class="weui-tabbar__item weui-bar__item_on">
        <view style="position: relative;display:inline-block;">
          <image src="/image/tabbar/test_1.png" class="weui-tabbar__icon"></image>
        </view>
        <view class="weui-tabbar__label">测试首页</view>
      </view>
      <view class="weui-tabbar__item" bindtap='toRandom'>
        <view style="position: relative;display:inline-block;">
          <image src="/image/tabbar/random.png" class="weui-tabbar__icon"></image>
        </view>
        <view class="weui-tabbar__label">随机一测</view>
      </view>
      <view class="weui-tabbar__item" bindtap='toUser'>
        <view style="position: relative;display:inline-block;">
          <image src="/image/tabbar/user_1.png" class="weui-tabbar__icon"></image>
        </view>
        <view class="weui-tabbar__label">我的测试</view>
      </view>
    </view>
  </view>
</view>

wxss:

代码语言:javascript
复制
/* pages/index/index.wxss */
.weui-tabbar{
  position:fixed;
  bottom:0;
  left:0;
  right:0;
}
.child {
  width: 100%;
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  margin: auto;
  text-align: left;
  background: white;
  opacity: 0.8
}  
.img {
  width: 100%;
}

当然,这一部分更多还是学习的过程。我只是在WEUI中找到几个木块,例如九宫格、例如列表以及尾部(Footer)。

整个前端包括:

用户打开小程序,进入到首页,在首页选择好测试内容或者通过分类选择测试内容,并且进入到测试页面,测试将以选择题形式出现,每个选项都有分数,用户选择好之后,提交到结果页面,在结果页面可以查看到测试结果。用户也可以在用户管理页面,看到自己的测试历史信息。如果没有登录可以在登录页面进行登录。

当然以首页为例,在做这一部分的时候,我其实就已经定义好了,大概的接口内容,以及部分结构。

例如分类列表部分,这一部分的结构是:

代码语言:javascript
复制
category: [
      {
        'title': "热门",
        'src': "/image/category/fire.png",
        'url': "/pages/list/index?type=fire"
      },
      {
        'title': "情感",
        'src': "/image/category/heart.png",
        'url': "/pages/list/index?type=heart"
      },
      {
        'title': "性格",
        'src': "/image/category/cross.png",
        'url': "/pages/list/index?type=cross"
      },
      {
        'title': "健康",
        'src': "/image/category/health.png",
        'url': "/pages/list/index?type=health"
      },
      {
        'title': "职场",
        'src': "/image/category/work.png",
        'url': "/pages/list/index?type=work"
      },
      {
        'title': "人际",
        'src': "/image/category/group.png",
        'url': "/pages/list/index?type=group"
      },
      {
        'title': "能力",
        'src': "/image/category/do.png",
        'url': "/pages/list/index?type=do"
      },
      {
        'title': "亲子",
        'src': "/image/category/family.png",
        'url': "/pages/list/index?type=family"
      },
      {
        'title': "其他",
        'src': "/image/category/detail.png",
        'url': "/pages/list/index?type=others"
      }
    ]

整个项目,使用最多的函数/方法应该就是后端的数据交互了,就是request,以获取首页热门测试为例:

代码语言:javascript
复制
wx.request({
      url: '',
      data: {
        category: "fire",
      },
      method: "POST",
      header: {
        "Content-Type": "application/x-www-form-json"
      },
      success: function (res) {
        that.setData({ content: res.data.result });
        console.log("result len: ", res.data.result.length)
        console.log("result: ", res.data.result)
        if (res.data.result.length == 0) {
          that.setData({ has_data: false });
        }
      },
    })

这其中,入参实际已经被定义为:category:"fire"

出参则是:

tid: int 测试索引

title: str 测试题目

icon: str 测试图标

type: bool 测试类型(是否是单个内容的测试)

desc: str 测试题描述

Index

wxml

代码语言:javascript
复制
<!--pages/index/index.wxml-->
<view>
  <view class="page__bd">
    <view>
      <swiper class="swiper" autoplay="true" interval="2000">
        <swiper-item wx:for="{{hot_test}}" wx:key="item">
          <image src="{{item.src}}" data-Tid='{{item.tid}}' bindtap='hotClick' mode="aspectFill" class="img"></image>
          <view class="child">{{item.title}}</view>
        </swiper-item>
      </swiper>
    </view>
  </view>
  <view class="page__bd">
    <view class="weui-cells  weui-grids">
      <block wx:for="{{category}}" wx:key="item">
        <navigator url="{{item.url}}" class="weui-grid" hover-class="weui-grid_active">
          <image class="weui-grid__icon" src="{{item.src}}" />
          <view class="weui-grid__label">{{item.title}}</view>
        </navigator>
      </block>
    </view>
  </view>
  
  <view class="weui-cells weui-cells_after-title">
  <view class="page__hd">
        <view class="page__title">热门测试</view>
  </view>
        <block wx:for="{{content}}" wx:key="item">
          <navigator url="/pages/content/index?tid={{item.tid}}" class="weui-cell weui-cell_access" hover-class="weui-cell_active">
            <block wx:if="{{item.type}}">
              <view class="weui-cell__hd">
                <image src="/image/content/{{item.icon}}.png" style="margin-right: 16px;vertical-align: middle;width:20px; height: 20px;"></image>
              </view>
              <view class="weui-cell__bd">{{item.title}}</view>
            </block>
            <block wx:else>
              <view class="weui-cell__hd">
                <image src="/image/content/{{item.icon}}.png" style="margin-right: 16px;vertical-align: middle;width:20px; height: 20px;" />
              </view>
              <view class="weui-cell__bd">
                <view>{{item.title}}</view>
                <view style="font-size: 13px;color: #888888;">{{item.desc}}</view>
              </view>
            </block>
          </navigator>
        </block>
      </view>
      <text>\n</text>
  <view class="weui-footer">
    <view class="weui-footer__text">爱测试 Copyright © 2019</view>
  </view>
  <text>\n\n\n</text>
  <view class="page__bd">
    <view class="weui-tabbar">
      <view class="weui-tabbar__item weui-bar__item_on">
        <view style="position: relative;display:inline-block;">
          <image src="/image/tabbar/test_1.png" class="weui-tabbar__icon"></image>
        </view>
        <view class="weui-tabbar__label">测试首页</view>
      </view>
      <view class="weui-tabbar__item" bindtap='toRandom'>
        <view style="position: relative;display:inline-block;">
          <image src="/image/tabbar/random.png" class="weui-tabbar__icon"></image>
        </view>
        <view class="weui-tabbar__label">随机一测</view>
      </view>
      <view class="weui-tabbar__item" bindtap='toUser'>
        <view style="position: relative;display:inline-block;">
          <image src="/image/tabbar/user_1.png" class="weui-tabbar__icon"></image>
        </view>
        <view class="weui-tabbar__label">我的测试</view>
      </view>
    </view>
  </view>
</view>

wxss

代码语言:javascript
复制
/* pages/index/index.wxss */
.weui-tabbar{
  position:fixed;
  bottom:0;
  left:0;
  right:0;
}
.child {
  width: 100%;
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  margin: auto;
  text-align: left;
  background: white;
  opacity: 0.8
}  
.img {
  width: 100%;
}

js

代码语言:javascript
复制
// pages/index/index.js
Page({

  /**
   * 页面的初始数据
   */
  data: {
    hot_test: [],
    content: [],
    category: [
      {
        'title': "热门",
        'src': "/image/category/fire.png",
        'url': "/pages/list/index?type=fire"
      },
      {
        'title': "情感",
        'src': "/image/category/heart.png",
        'url': "/pages/list/index?type=heart"
      },
      {
        'title': "性格",
        'src': "/image/category/cross.png",
        'url': "/pages/list/index?type=cross"
      },
      {
        'title': "健康",
        'src': "/image/category/health.png",
        'url': "/pages/list/index?type=health"
      },
      {
        'title': "职场",
        'src': "/image/category/work.png",
        'url': "/pages/list/index?type=work"
      },
      {
        'title': "人际",
        'src': "/image/category/group.png",
        'url': "/pages/list/index?type=group"
      },
      {
        'title': "能力",
        'src': "/image/category/do.png",
        'url': "/pages/list/index?type=do"
      },
      {
        'title': "亲子",
        'src': "/image/category/family.png",
        'url': "/pages/list/index?type=family"
      },
      {
        'title': "其他",
        'src': "/image/category/detail.png",
        'url': "/pages/list/index?type=others"
      }
    ]
  },

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {
    var that = this
    wx.setNavigationBarTitle({
      title: '爱测试'  //修改title
    })
    wx.request({
      url: '',
      data: {
      },
      method: "POST",
      header: {
        "Content-Type": "application/x-www-form-json"
      },
      success: function (res) {
        that.setData({ hot_test: res.data.result });
        console.log("result len: ", res.data.result.length)
        console.log("result: ", res.data.result)
      }
    })
    wx.request({
      url: '',
      data: {
        category: "fire",
      },
      method: "POST",
      header: {
        "Content-Type": "application/x-www-form-json"
      },
      success: function (res) {
        that.setData({ content: res.data.result });
        console.log("result len: ", res.data.result.length)
        console.log("result: ", res.data.result)
        if (res.data.result.length == 0) {
          that.setData({ has_data: false });
        }
      },
    })
  },

  hotClick: function (e) {
    wx.navigateTo({
      url: '/pages/content/index?tid=' + e.currentTarget.dataset.tid,
    })
  },

  toUser: function(e){
    wx.redirectTo({
      url: '/pages/user/index',
    })
  },
  toRandom: function (e) {
    wx.request({
      url: '',
      data: {
      },
      header: {
        "Content-Type": "application/x-www-form-json"
      },
      method: "POST",
      success: (res) => {
        console.log(res)
        wx.navigateTo({
          url: '/pages/content/index?tid=' + res.data.result.tid,
        })
      },
      fail: (res) => {
        wx.navigateTo({
          url: '/pages/content/index?tid=0',
        })
      }
    })
  },
})

content

wxml

代码语言:javascript
复制
<!--pages/content/index.wxml-->
<view class="page">
  <view class="page__bd">
  <block wx:for="{{question}}" wx:key="item">
    <view class="weui-panel">
      <view class="weui-panel__hd">{{item.question}}</view>
      <view class="weui-panel__bd">
        <view class="weui-media-box weui-media-box_small-appmsg">
          <view class="weui-cells weui-cells_in-small-appmsg">
            <view class="weui-cells weui-cells_after-title">
            <radio-group bindchange="radioChange">
                <label class="weui-cell weui-check__label" wx:for="{{item.selection}}"  wx:for-item="selection" wx:key="item">
                    <radio class="weui-check" value="{{item.index}}-{{selection.value}}" checked="{{selection.checked}}"/>
                    <view class="weui-cell__bd">{{selection.value}}</view>
                    <view class="weui-cell__ft weui-cell__ft_in-radio" wx:if="{{selection.checked}}">
                        <icon class="weui-icon-radio" type="success_no_circle" size="16"></icon>
                    </view>
                </label>
            </radio-group>
        </view>
          </view>
        </view>
      </view>
    </view>
</block>
<text>\n</text>
<button class="weui-btn" type="primary" disabled="{{button_disabled}}" bindtap='buttonClick'>{{button_content}}</button>
  </view>
</view>

wxss

代码语言:javascript
复制
/* pages/content/index.wxss */
.weui-btn{
  margin-left: 10px;
  margin-right: 10px;
}

js

代码语言:javascript
复制
// pages/content/index.js
const app = getApp()

Page({

  /**
   * 页面的初始数据
   */
  data: {
    page_title: "测试",
    button_content: "提交测试",
    button_disabled: false,
    tid: 0,
    question: []
  },

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function(options) {
    var that = this
    wx.setNavigationBarTitle({
      title: this.data.page_title,
    })
    that.setData({
      tid: options['tid']
    })
    wx.request({
      url: '',
      data: {
        test: options['tid'],
      },
      method: "POST",
      header: {
        "Content-Type": "application/x-www-form-json"
      },
      success: function (res) {
        that.setData({ question: res.data.result });
        console.log("result len: ", res.data.result.length)
        console.log("result: ", res.data.result)
      },
      fail: function (res) {
        wx.showToast({
          title: '获取测试题失败',
        })
        wx.redirectTo({
          url: '/pages/index/index',
        })
      }
    })
  },

  radioChange: function(e) {
    console.log(e.detail.value)
    var that = this
    var question = this.data.question;
    var selection_list = e.detail.value.split("-")
    var change_quesetion = question[parseInt(selection_list[0])]
    console.log(change_quesetion)
    for (var j = 0, len = change_quesetion['selection'].length; j < len; ++j) {
      change_quesetion['selection'][j].checked = change_quesetion['selection'][j].value == selection_list[1];
    }
    question[parseInt(selection_list[0])] = change_quesetion
    that.setData({
      question: question
    });
  },

  buttonClick: function(e){
    console.log("click")
    var that = this
    that.setData({
      button_disabled: true,
      button_content: "已经提交,请等待"
    })
    var sum = 0
    var question = this.data.question
    for (var j = 0, arr_len = question.length; j < arr_len; ++j) {
      for (var i = 0, len = question[j]['selection'].length; i < len; ++i) {
        if (question[j]['selection'][i].checked ){
          sum = sum + question[j]['selection'][i].score
          console.log(sum)
        }
      }
    }
    
    var tid = this.data.tid
    wx.request({
      url: '',
      data: {
        test: tid,
        score: sum,
        user: app.globalData.openID,
      },
      method: "POST",
      header: {
        "Content-Type": "application/x-www-form-json"
      },
      success: function (res) {
        console.log(res)
        wx.redirectTo({
          url: '/pages/result/index?tid=' + tid + '&rid=' + res.data.result.rid,
        })
      },
      fail: function (res) {
        wx.showToast({
          title: '获取测试结果失败,请稍后再试',
        })
        wx.redirectTo({
          url: '/pages/index/index',
        })
      }
    })
  },
})

list

wxml

代码语言:javascript
复制
<!--pages/list/index.wxml-->
<view>
  <view class="page__bd">
    <block wx:if="{{has_data}}">
      <view class="weui-cells weui-cells_after-title">
        <block wx:for="{{content}}" wx:key="item">
          <navigator url="/pages/content/index?tid={{item.tid}}" class="weui-cell weui-cell_access" hover-class="weui-cell_active">
            <block wx:if="{{item.type}}">
              <view class="weui-cell__hd">
                <image src="/image/content/{{item.icon}}.png" style="margin-right: 16px;vertical-align: middle;width:20px; height: 20px;"></image>
              </view>
              <view class="weui-cell__bd">{{item.title}}</view>
            </block>
            <block wx:else>
              <view class="weui-cell__hd">
                <image src="/image/content/{{item.icon}}.png" style="margin-right: 16px;vertical-align: middle;width:20px; height: 20px;" />
              </view>
              <view class="weui-cell__bd">
                <view>{{item.title}}</view>
                <view style="font-size: 13px;color: #888888;">{{item.desc}}</view>
              </view>
            </block>
          </navigator>
        </block>
      </view>
    </block>
    <block wx:else>
      <view class="weui-loadmore weui-loadmore_line">
        <view class="weui-loadmore__tips weui-loadmore__tips_in-line">暂无数据</view>
      </view>
    </block>
  </view>
  <view class="weui-footer">
    <view class="weui-footer__text">爱测试 Copyright © 2019</view>
  </view>
</view>

js

代码语言:javascript
复制
// pages/list/index.js
Page({

  /**
   * 页面的初始数据
   */
  data: {
    has_data: true, 
    category: {
      'fire': "热门",
      'heart': "情感",
      'cross': "性格",
      'health': "健康",
      'work': "职场",
      'group': "人际",
      'do': "能力",
      'family': "亲子",
      'others': "其他",
    },
    content: []
  },

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function(options) {
    var that = this
    var page_type = options['type']
    wx.setNavigationBarTitle({
      title: this.data.category[page_type] //修改title
    })
    wx.request({
      url: '',
      data: {
        category: page_type,
      },
      method: "POST",
      header: {
        "Content-Type": "application/x-www-form-json"
      },
      success: function (res) {
        that.setData({ content: res.data.result });
        console.log("result len: ", res.data.result.length)
        console.log("result: ", res.data.result)
        if (res.data.result.length==0){
          that.setData({ has_data: false });
        }
      },
      fail: function (res) {
        wx.showToast({
          title: '获取列表失败',
        })
        wx.redirectTo({
          url: '/pages/index/index',
        })
      }
    })
  },
})

login

wxml

代码语言:javascript
复制
<!--index.wxml-->
<view class="container">
  <view class="userinfo">
    <button wx:if="{{!hasUserInfo && canIUse}}" open-type="getUserInfo" bindgetuserinfo="getUserInfo"> 点击授权登陆 </button>
    <block wx:else>
      <image bindtap="bindViewTap" class="userinfo-avatar" src="{{userInfo.avatarUrl}}" mode="cover"></image>
      <text class="userinfo-nickname">{{userInfo.nickName}}</text>
    </block>
  </view>
  <view class="weui-footer">
    <view class="weui-footer__text">爱测试 Copyright © 2019</view>
  </view>
</view>

wxss

代码语言:javascript
复制
/**index.wxss**/
.userinfo {
  display: flex;
  flex-direction: column;
  align-items: center;
}

.userinfo-avatar {
  width: 128rpx;
  height: 128rpx;
  margin: 20rpx;
  border-radius: 50%;
}

.userinfo-nickname {
  color: #aaa;
}

.usermotto {
  margin-top: 200px;
}

js

代码语言:javascript
复制
//index.js
//获取应用实例
const app = getApp()

Page({
  data: {
    userInfo: {},
    hasUserInfo: false,
    canIUse: wx.canIUse('button.open-type.getUserInfo')

  },
  //事件处理函数
  bindViewTap: function() {
    wx.navigateTo({
      url: '../logs/logs'
    })
  },
  onLoad: function () {
    wx.setNavigationBarTitle({
      title: '授权登录',
    })
    if (app.globalData.userInfo) {
      this.setData({
        userInfo: app.globalData.userInfo,
        hasUserInfo: true
      })
    } else if (this.data.canIUse){
      // 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回
      // 所以此处加入 callback 以防止这种情况
      app.userInfoReadyCallback = res => {
        this.setData({
          userInfo: res.userInfo,
          hasUserInfo: true
        })
      }
    } else {
      // 在没有 open-type=getUserInfo 版本的兼容处理
      wx.getUserInfo({
        success: res => {
          app.globalData.userInfo = res.userInfo
          this.setData({
            userInfo: res.userInfo,
            hasUserInfo: true
          })
        }
      })
    }
  },
  getUserInfo: function(e) {
    console.log(e)
    app.globalData.userInfo = e.detail.userInfo
    this.setData({
      userInfo: e.detail.userInfo,
      hasUserInfo: true
    })
    console.log("openID: ", app.globalData.openID)
    console.log("nickName: ", app.globalData.userInfo.nickName)
    wx.request({
      url: '',
      data: {
        "wechat": app.globalData.openID,
        "nickname": app.globalData.userInfo.nickName,
        "remark": app.globalData.userInfo,
        "pic": app.globalData.userInfo.avatarUrl,
        "local": app.globalData.userInfo.country + "-" + app.globalData.userInfo.province + "-" + app.globalData.userInfo.city,
      },
      header: {
        "Content-Type": "application/x-www-form-json"
      },
      method: "POST",
      success: (res) => {
        console.log("Success: ", res.data)
        if (res.data.result != true) {
          this.setData({
            userInfo: null,
            hasUserInfo: false
          })
        } else {
          console.log("result is true")
          this.setData({
            hasUserInfo: true
          })
          wx.redirectTo({
            url: '/pages/user/index',
          })
        }
      },
      fail: (res) => {
        console.log("Faild: ", res.data)
        this.setData({
          userInfo: null,
          hasUserInfo: false
        })
        wx.showToast({
          title: "注册/登录失败,请稍后再试",
        })
        wx.redirectTo({
          url: '/pages/user/index',
        })
      }
    })
  }
})

result

wxml

代码语言:javascript
复制
<!--pages/result/index.wxml-->
<import src="../../dependence/wxParse/wxParse.wxml" />
<view class="page">
  <view class="page__hd">
    <view class="page__title">{{page_title}}</view>
    <view class="page__desc">* 本结果仅供参考</view>
  </view>
  <view class="page__bd">
    <view class="weui-article">
      <template is="wxParse" data="{{wxParseData:insertData.nodes}}" />
    </view>
  </view>
  <button class="weui-btn" type="primary" bindtap='buttonClick'>再测一次</button>
  <view class="page__bd">
    <view class="weui-tabbar">
      <view class="weui-tabbar__item" bindtap='toIndex'>
        <view style="position: relative;display:inline-block;">
          <image src="/image/tabbar/test_1.png" class="weui-tabbar__icon"></image>
        </view>
        <view class="weui-tabbar__label">测试首页</view>
      </view>
      <view class="weui-tabbar__item" bindtap='toRandom'>
        <view style="position: relative;display:inline-block;">
          <image src="/image/tabbar/random.png" class="weui-tabbar__icon"></image>
        </view>
        <view class="weui-tabbar__label">随机一测</view>
      </view>
      <view class="weui-tabbar__item" bindtap='toUser'>
        <view style="position: relative;display:inline-block;">
          <image src="/image/tabbar/user_1.png" class="weui-tabbar__icon"></image>
        </view>
        <view class="weui-tabbar__label">我的测试</view>
      </view>
    </view>
  </view>
</view>

wxss

代码语言:javascript
复制
/* pages/result/index.wxss */
@import "/dependence/wxParse/wxParse.wxss";
page{
    background-color: #FFFFFF;
}
image{
    margin: 4px 0;
}
.weui-tabbar{
  position:fixed;
  bottom:0;
  left:0;
  right:0;
}

.weui-btn{
  margin-left: 10px;
  margin-right: 10px;
}

js

代码语言:javascript
复制
// pages/result/index.js
var WxParse = require('../../dependence/wxParse/wxParse.js');

Page({

  /**
   * 页面的初始数据
   */
  data: {
    page_title: "测试结果",
    tid: 0,
    rid: 0,
  },

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {
    var that = this;
    wx.setNavigationBarTitle({
      title: this.data.page_title,
    })
    that.setData({
      tid: options['tid'],
      rid: options['rid']
    })

    wx.request({
      url: '',
      data: {
        result: options['rid'],
      },
      method: "POST",
      header: {
        "Content-Type": "application/x-www-form-json"
      },
      success: function (res) {
        /**
        * WxParse.wxParse(bindName , type, data, target,imagePadding)
        * 1.bindName绑定的数据名(必填)
        * 2.type可以为html或者md(必填)
        * 3.data为传入的具体数据(必填)
        * 4.target为Page对象,一般为this(必填)
        * 5.imagePadding为当图片自适应是左右的单一padding(默认为0,可选)
        */
        console.log(res.data.result.content)
        WxParse.wxParse('insertData', 'html', res.data.result.content, that);
      },
      fail: function (res) {
        wx.showToast({
          title: '获取结果失败,请稍后再试',
        })
        wx.redirectTo({
          url: '/pages/index/index',
        })
      }
    })
  },

  toUser: function (e) {
    wx.redirectTo({
      url: '/pages/user/index',
    })
  },

  toIndex: function (e) {
    wx.redirectTo({
      url: '/pages/index/index',
    })
  },

  buttonClick: function (e) {
    console.log("click")
    wx.redirectTo({
      url: '/pages/content/index?tid=' + this.data.tid,
    })
  },
  toRandom: function (e) {
    wx.request({
      url: '',
      data: {
      },
      header: {
        "Content-Type": "application/x-www-form-json"
      },
      method: "POST",
      success: (res) => {
        console.log(res)
        wx.navigateTo({
          url: '/pages/content/index?tid=' + res.data.result.tid,
        })
      },
      fail: (res) => {
        wx.navigateTo({
          url: '/pages/content/index?tid=0',
        })
      }
    })
  },
})

user

wxml

代码语言:javascript
复制
<!--pages/user/index.wxml-->
<view class="page">
  <view class="page__bd">
    <view class="weui-panel weui-panel_access">
      <view class="weui-panel__bd">
        <navigator url="{{login_url}}" class="weui-media-box weui-media-box_appmsg" hover-class="weui-cell_active">
          <view class="weui-media-box__hd weui-media-box__hd_in-appmsg">
            <image class="weui-media-box__thumb" src="{{user_pic}}" />
          </view>
          <view class="weui-media-box__bd weui-media-box__bd_in-appmsg">
            <view class="weui-media-box__title">{{user_name}}</view>
            <view class="weui-media-box__desc">{{user_local}}</view>
          </view>
        </navigator>
      </view>
    </view>
    <view class="weui-loadmore weui-loadmore_line" wx:if="{{!login}}">
      <view class="weui-loadmore__tips weui-loadmore__tips_in-line">登陆查看历史测试</view>
    </view>
    <view class="weui-cells weui-cells_after-title" wx:else>
      <view class="weui-cell" wx:for="{{history}}" wx:key="item">
        <navigator url="/pages/result/index?tid={{item.tid}}&rid={{item.rid}}">
          <view class="weui-cell__bd">
            <view>{{item.title}}</view>
            <view style="font-size: 13px;color: #888888;">{{item.desc}}</view>
          </view>
        </navigator>
      </view>
    </view>
  </view>
  <view class="weui-footer">
    <view class="weui-footer__text">爱测试 Copyright © 2019</view>
  </view>
  <view class="page__bd">
    <view class="weui-tabbar">
      <view class="weui-tabbar__item" bindtap='toIndex'>
        <view style="position: relative;display:inline-block;">
          <image src="/image/tabbar/test_1.png" class="weui-tabbar__icon"></image>
        </view>
        <view class="weui-tabbar__label">测试首页</view>
      </view>
      <view class="weui-tabbar__item" bindtap='toRandom'>
        <view style="position: relative;display:inline-block;">
          <image src="/image/tabbar/random.png" class="weui-tabbar__icon"></image>
        </view>
        <view class="weui-tabbar__label">随机一测</view>
      </view>
      <view class="weui-tabbar__item weui-bar__item_on">
        <view style="position: relative;display:inline-block;">
          <image src="/image/tabbar/user_1.png" class="weui-tabbar__icon"></image>
        </view>
        <view class="weui-tabbar__label">我的测试</view>
      </view>
    </view>
  </view>
</view>

wxss

代码语言:javascript
复制
/* pages/user/index.wxss */
.weui-tabbar{
  position:fixed;
  bottom:0;
  left:0;
  right:0;
}

js

代码语言:javascript
复制
// pages/user/index.js
const app = getApp()
Page({

  /**
   * 页面的初始数据
   */
  data: {
    user_pic: "/image/others/user.png",
    user_name: "点击登录",
    user_local: "中国-广东-深圳",
    login_url: "/pages/login/index",
    login: false,
    userInfo: {},
    history: []
  },
  toIndex: function (e) {
    wx.redirectTo({
      url: '/pages/index/index',
    })
  },

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function(options) {
    var that = this
    wx.setNavigationBarTitle({
      title: '个人中心',
    })
    if (app.globalData.userInfo) {
      this.setData({
        userInfo: app.globalData.userInfo,
        login: true,
        user_pic: app.globalData.userInfo.avatarUrl,
        user_name: app.globalData.userInfo.nickName,
        user_local: app.globalData.userInfo.country + "-" + app.globalData.userInfo.province + "-" + app.globalData.userInfo.city,
        login_url: ""
      })
      this.getHistory()
    } else if (this.data.canIUse) {
      // 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回
      // 所以此处加入 callback 以防止这种情况
      app.userInfoReadyCallback = res => {
        this.setData({
          userInfo: res.userInfo,
          login: true,
          user_pic: res.userInfo.avatarUrl,
          user_name: res.userInfo.nickName,
          user_local: res.userInfo.country + "-" + res.userInfo.province + "-" + res.userInfo.city,
          login_url: ""
        })
        this.getHistory()
      }
    } else {
      // 在没有 open-type=getUserInfo 版本的兼容处理
      wx.getUserInfo({
        success: res => {
          app.globalData.userInfo = res.userInfo
          this.setData({
            userInfo: res.userInfo,
            login: true,
            user_pic: res.userInfo.avatarUrl,
            user_name: res.userInfo.nickName,
            user_local: res.userInfo.country + "-" + res.userInfo.province + "-" + res.userInfo.city,
            login_url: ""
          })
          this.getHistory()
        }
      })
    }
  },
  getHistory: function(){
    var that = this
    wx.request({
      url: '',
      data: {
        "wechat": app.globalData.openID,
      },
      header: {
        "Content-Type": "application/x-www-form-json"
      },
      method: "POST",
      success: (res) => {
        that.setData({ history: res.data.result })
      }
    })
  },
  toRandom: function (e) {
    wx.request({
      url: '',
      data: {
      },
      header: {
        "Content-Type": "application/x-www-form-json"
      },
      method: "POST",
      success: (res) => {
        console.log(res)
        wx.navigateTo({
          url: '/pages/content/index?tid=' + res.data.result.tid,
        })
      },
      fail: (res) => {
        wx.navigateTo({
          url: '/pages/content/index?tid=0',
        })
      }
    })
  },
})

APP

js

代码语言:javascript
复制
//app.js
App({
  onLaunch: function () {
    // 展示本地存储能力
    var logs = wx.getStorageSync('logs') || []
    logs.unshift(Date.now())
    wx.setStorageSync('logs', logs)

    wx.login({
      success: function (res) {
        if (res.code) {
          console.log("res: " + res.code)
          wx.request({
            url: '',
            data: {
              code: res.code,
            },
            header: {
              "Content-Type": "application/x-www-form-json"
            },
            method: 'POST',
            success: function (res) {
              console.log('Success_1:', res)
              var data = res.data.openid
              console.log(data)
              if (data) {
                getApp().globalData.openID = data
                wx.getUserInfo({
                  success: function (res) {
                    console.log('Success_2:', res)
                  }
                })
              } else {
                console.log('Faild', res)
              }
            },
            fail: function (res) {
              console.log('Faild', res)
            }
          })
        } else {
          console.log('获取用户登录态失败!' + res.errMsg)
        }
      }
    });
    // 获取用户信息
    wx.getSetting({
      success: res => {
        if (res.authSetting['scope.userInfo']) {
          // 已经授权,可以直接调用 getUserInfo 获取头像昵称,不会弹框
          wx.getUserInfo({
            success: res => {
              // 可以将 res 发送给后台解码出 unionId
              this.globalData.userInfo = res.userInfo

              // 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回
              // 所以此处加入 callback 以防止这种情况
              if (this.userInfoReadyCallback) {
                this.userInfoReadyCallback(res)
              }
            }
          })
        }
      }
    })
  },
  globalData: {
    userInfo: null,
    userAuth: false,
    testAccount: false,
    openID: null
  }
})

小结

由于我真的不会写js,写的代码也比较难看,所以还请各位看官大老爷多多理解。而且这个代码也不算优雅,有很多的wxss的样式和js的方法没有进行复用(但是作为demo问题不大,哈哈哈哈)

数据库开发

数据库,也就是边建表,边思考,边修改,大概就是这样:

数据库的设计,貌似也不是很好,我是将评价/测试/问题/选项/分类等分开建立了表,这样在用户多的时候可能会出现比较多的跨表查询,所以可能也不是很好,但是更多优化可以各位大佬来自己实现一下。

后端接口

后端接口主要是SCF的函数。并没有什么特殊的,基本就是数据库的增删改查。

YAML

代码语言:javascript
复制
Resources:
  iceshi:
    Type: TencentCloud::Serverless::Namespace
    login:
      Type: TencentCloud::Serverless::Function
      Properties:
        CodeUri: login
        Type: Event
        Description: This is a template function
        Role: QCS_SCFExcuteRole
        Environment:
          Variables:
            ENV_FIRST: env1
            ENV_SECOND: env2
        Handler: index.main_handler
        MemorySize: 128
        Runtime: Python3.6
        Timeout: 3
        Events:
          hello_world_apigw:  # ${FunctionName} + '_apigw'
            Type: APIGW
            Properties:
              StageName: release
              ServiceId: service-n9j2nmdg
              HttpMethod: ANY
    get_list:
      Type: TencentCloud::Serverless::Function
      Properties:
        CodeUri: get_list
        Type: Event
        Description: This is a template function
        Role: QCS_SCFExcuteRole
        Environment:
          Variables:
            ENV_FIRST: env1
            ENV_SECOND: env2
        Handler: index.main_handler
        MemorySize: 128
        Runtime: Python3.6
        Timeout: 3
        Events:
          hello_world_apigw:  # ${FunctionName} + '_apigw'
            Type: APIGW
            Properties:
              StageName: release
              ServiceId: service-n9j2nmdg
              HttpMethod: ANY
    get_index:
      Type: TencentCloud::Serverless::Function
      Properties:
        CodeUri: get_index
        Type: Event
        Description: This is a template function
        Role: QCS_SCFExcuteRole
        Environment:
          Variables:
            ENV_FIRST: env1
            ENV_SECOND: env2
        Handler: index.main_handler
        MemorySize: 128
        Runtime: Python3.6
        Timeout: 3
        Events:
          hello_world_apigw:  # ${FunctionName} + '_apigw'
            Type: APIGW
            Properties:
              StageName: release
              ServiceId: service-n9j2nmdg
              HttpMethod: ANY
    get_question:
      Type: TencentCloud::Serverless::Function
      Properties:
        CodeUri: get_question
        Type: Event
        Description: This is a template function
        Role: QCS_SCFExcuteRole
        Environment:
          Variables:
            ENV_FIRST: env1
            ENV_SECOND: env2
        Handler: index.main_handler
        MemorySize: 128
        Runtime: Python3.6
        Timeout: 3
        Events:
          hello_world_apigw:  # ${FunctionName} + '_apigw'
            Type: APIGW
            Properties:
              StageName: release
              ServiceId: service-n9j2nmdg
              HttpMethod: ANY
    get_result:
      Type: TencentCloud::Serverless::Function
      Properties:
        CodeUri: get_result
        Type: Event
        Description: This is a template function
        Role: QCS_SCFExcuteRole
        Environment:
          Variables:
            ENV_FIRST: env1
            ENV_SECOND: env2
        Handler: index.main_handler
        MemorySize: 128
        Runtime: Python3.6
        Timeout: 3
        Events:
          hello_world_apigw:  # ${FunctionName} + '_apigw'
            Type: APIGW
            Properties:
              StageName: release
              ServiceId: service-n9j2nmdg
              HttpMethod: ANY
    get_result_content:
      Type: TencentCloud::Serverless::Function
      Properties:
        CodeUri: get_result_content
        Type: Event
        Description: This is a template function
        Role: QCS_SCFExcuteRole
        Environment:
          Variables:
            ENV_FIRST: env1
            ENV_SECOND: env2
        Handler: index.main_handler
        MemorySize: 128
        Runtime: Python3.6
        Timeout: 3
        Events:
          hello_world_apigw:  # ${FunctionName} + '_apigw'
            Type: APIGW
            Properties:
              StageName: release
              ServiceId: service-n9j2nmdg
              HttpMethod: ANY
    get_openid:
      Type: TencentCloud::Serverless::Function
      Properties:
        CodeUri: get_openid
        Type: Event
        Description: This is a template function
        Role: QCS_SCFExcuteRole
        Environment:
          Variables:
            ENV_FIRST: env1
            ENV_SECOND: env2
        Handler: index.main_handler
        MemorySize: 128
        Runtime: Python3.6
        Timeout: 3
        Events:
          hello_world_apigw:  # ${FunctionName} + '_apigw'
            Type: APIGW
            Properties:
              StageName: release
              ServiceId: service-n9j2nmdg
              HttpMethod: ANY
    get_history:
      Type: TencentCloud::Serverless::Function
      Properties:
        CodeUri: get_history
        Type: Event
        Description: This is a template function
        Role: QCS_SCFExcuteRole
        Environment:
          Variables:
            ENV_FIRST: env1
            ENV_SECOND: env2
        Handler: index.main_handler
        MemorySize: 128
        Runtime: Python3.6
        Timeout: 3
        Events:
          hello_world_apigw:  # ${FunctionName} + '_apigw'
            Type: APIGW
            Properties:
              StageName: release
              ServiceId: service-n9j2nmdg
              HttpMethod: ANY
    get_random:
      Type: TencentCloud::Serverless::Function
      Properties:
        CodeUri: get_random
        Type: Event
        Description: This is a template function
        Role: QCS_SCFExcuteRole
        Environment:
          Variables:
            ENV_FIRST: env1
            ENV_SECOND: env2
        Handler: index.main_handler
        MemorySize: 128
        Runtime: Python3.6
        Timeout: 3
        Events:
          hello_world_apigw:  # ${FunctionName} + '_apigw'
            Type: APIGW
            Properties:
              StageName: release
              ServiceId: service-n9j2nmdg
              HttpMethod: ANY

Globals:
  Function:
    Timeout: 10

get_index的核心:

代码语言:javascript
复制
def getTestList(connection):
    try:
        connection.ping(reconnect=True)
        cursor = connection.cursor()
        search_stmt = (
            "SELECT * FROM `test` WHERE remark=0"
        )
        data = ()
        cursor.execute(search_stmt, data)
        cursor.close()
        test_list = []
        total = 5
        for eve_test in cursor.fetchall():
            icon = 'page'
            if eve_test["times"] > 50:
                icon = 'fire'
            else:
                if total > 0:
                    icon = 'new'
                    total = total - 1

            test = {
                "tid": eve_test["tid"],
                "title": eve_test["name"],
                "src": eve_test["pic"],
            }
            test_list.append(test)

        return test_list

    except Exception as e:
        print("getTestList", e)
        return []

get_history的核心:

代码语言:javascript
复制
def getHistoryList(connection, wechat):
    try:
        connection.ping(reconnect=True)
        cursor = connection.cursor()
        search_stmt = (
            "SELECT * FROM `result` LEFT JOIN test on test.tid=result.test "
            "WHERE user=(SELECT uid FROM user WHERE wechat=%s) ORDER BY -rid"
        )
        data = (wechat)
        cursor.execute(search_stmt, data)
        cursor.close()
        return [{"tid": eve_history["tid"], "rid": eve_history["rid"], "title": eve_history["name"],
                 "desc": eve_history["description"] if len(eve_history["description"]) > 10 else eve_history[
                                                                                                     "description"][
                                                                                                 0:10] + "..."} for
                eve_history in cursor.fetchall()]

    except Exception as e:
        print("getHistoryList", e)
        return []

get_list的核心:

代码语言:javascript
复制
def getTestList(connection, category):
    try:
        connection.ping(reconnect=True)
        cursor = connection.cursor()
        if category == "fire":
            search_stmt = (
                "SELECT * FROM `test` ORDER BY -times Limit 0,100"
            )
            data = ()
        else:
            search_stmt = (
                "SELECT * FROM `test` WHERE category=(SELECT cid FROM `category` WHERE remark=%s) ORDER BY -tid"
            )
            data = (category)
        cursor.execute(search_stmt, data)
        cursor.close()
        test_list = []
        total = 5
        for eve_test in cursor.fetchall():
            icon = 'page'
            if eve_test["times"] > 50:
                icon = 'fire'
            else:
                if total > 0:
                    icon = 'new'
                    total = total - 1

            test = {
                "tid": eve_test["tid"],
                "title": eve_test["name"],
                "icon": icon,
                "type": False if eve_test["description"] else True,
                "desc": eve_test["description"] if len(eve_test["description"]) > 40 else eve_test["description"][0:40] + "..."
            }
            test_list.append(test)

        return test_list

    except Exception as e:
        print("getTestList", e)
        return []

get_openid的核心:

代码语言:javascript
复制
def main_handler(event, context):
    url = "https://api.weixin.qq.com/sns/jscode2session"
    data = {
        'appid': AppId,
        'secret': AppSecret,
        'js_code': json.loads(event["body"])["code"],
        'grant_type': 'authorization_code'
    }
    post_data = urllib.parse.urlencode(data).encode("utf-8")
    req = urllib.request.Request(url=url, data=post_data)
    resp = urllib.request.urlopen(req).read().decode("utf-8")
    try:
        return {
            "openid": json.loads(resp)["openid"],
        }
    except:
        return {
            "openid": False
        }

get_question的核心:

代码语言:javascript
复制
def getQuestionList(connection, test):
    try:
        connection.ping(reconnect=True)
        cursor = connection.cursor()
        search_stmt = (
            "SELECT * FROM question LEFT JOIN selection on question.qid=selection.question WHERE test=%s"
        )
        data = (test)
        cursor.execute(search_stmt, data)
        cursor.close()
        question_dict = {}
        question = []
        for eve_question in cursor.fetchall():
            print(eve_question)
            if eve_question['qid'] not in question_dict:
                question_dict[eve_question['qid']] = {
                    "qid": eve_question['qid'],
                    "question": eve_question['content'],
                    "selection": []
                }
            question_dict[eve_question['qid']]["selection"].append(
                {
                    "score": eve_question["score"],
                    "value": eve_question["selection.content"],
                    "checked": True if len(question_dict[eve_question['qid']]["selection"]) == 0 else False
                })
        index_data = 0
        for eve_key, eve_value in question_dict.items():
            eve_value['index'] = index_data
            question.append(eve_value)
            index_data = index_data + 1

        return question

    except Exception as e:
        print("getQuestionList", e)
        return []


def addNumber(connection, test):
    try:
        connection.ping(reconnect=True)
        cursor = connection.cursor()
        search_stmt = (
            "UPDATE `test` SET times=times+1 WHERE tid=%s"
        )
        data = (test)
        cursor.execute(search_stmt, data)
        cursor.close()
        return True
    except Exception as e:
        print("addNumber", e)
        return False

get_random的核心:

代码语言:javascript
复制
def getRandom(connection):
    try:
        connection.ping(reconnect=True)
        cursor = connection.cursor()
        search_stmt = (
            "select * from test order by rand() LIMIT 1"
        )
        data = ()
        cursor.execute(search_stmt, data)
        cursor.close()
        return {"tid": cursor.fetchall()[0]["tid"]}

    except Exception as e:
        print("getRandom", e)
        return {"tid": 0}

get_result的核心:

代码语言:javascript
复制
def getEvaluateList(connection, score, test, user):
    try:
        connection.ping(reconnect=True)
        cursor = connection.cursor()
        search_stmt = (
            "INSERT INTO `result` (`rid`, `user`, `test`, `evaluate`, `remark`, `date`) VALUES "
            "(NULL, (SELECT uid FROM `user` WHERE wechat=%s), %s, (SELECT eid FROM `evaluate` "
            "WHERE %s>=score_min and %s<=score_max and test=%s), '', CURRENT_TIMESTAMP);"
        )
        data = (user, test, score, score, test)
        cursor.execute(search_stmt, data)
        cursor.close()
        result = cursor.lastrowid
        return {"rid": result}

    except Exception as e:
        print("getEvaluateList", e)
        return {}

get_result_content的核心:

代码语言:javascript
复制
def getEvaluateList(connection, rid):
    try:
        connection.ping(reconnect=True)
        cursor = connection.cursor()
        search_stmt = (
            "SELECT * FROM evaluate WHERE eid=(SELECT evaluate FROM `result` WHERE rid=%s)"
        )
        data = (rid)
        cursor.execute(search_stmt, data)
        cursor.close()
        try:
            result = cursor.fetchall()[0]
        except:
            result = "暂无数据,请稍后再试"
        return {"content": result["content"]}

    except Exception as e:
        print("getEvaluateList", e)
        return {}

login:

代码语言:javascript
复制
def getUserInfor(connection, wechat):
    try:
        connection.ping(reconnect=True)
        cursor = connection.cursor()
        search_stmt = (
            "SELECT * FROM `user` WHERE `wechat`=%s"
        )
        data = (wechat)
        cursor.execute(search_stmt, data)
        cursor.close()
        result = cursor.fetchall()
        return len(result)
    except Exception as e:
        print("getUserInfor", e)
        return False

def addUserInfor(connection, wechat,username,local,pic):
    try:
        connection.ping(reconnect=True)
        cursor = connection.cursor()
        insert_stmt = (
            "INSERT INTO user(`wechat`,`username`,`local`,`pic`) "
            "VALUES (%s,%s,%s,%s)"
        )
        data = (wechat,username,local,pic)
        cursor.execute(insert_stmt, data)
        cursor.close()
        connection.close()
        return True
    except Exception as e:
        print("addUserInfor", e)
        return False

总结

这个小程序是我当天早晨开始做,因为实在不会写小程序,所以小程序部分比较费时间,大约用了一上午,中午吃个饭,弄了一下数据库,下午和老爹老妈出去溜达一圈,晚上回来写了后台,并进行了调试和部分BUG的修复,晚上算是完成了这个小程序的开发。我不清楚,作为一个小菜鸟,如果从头开始开发一个小程序要多久,但是通过这样一个例子,我可以说,在SCF的帮助下,真的可以很简单。

简答1: 小程序部分使用了WEUI更多就像用拼图,可以很快拼凑出自己想要的或者基本满足自身需求的UI,整个一个数据交互,逻辑基本一致,只是用了request的方法。

简单2: 按照道理来说,我使用前后端数据分离,那么后端提供接口的时候就要有一个WEB服务,但是通过SCF,我们不需要考虑这个WEB服务,我们只需要处理好自己的逻辑,就可以根据固定的入参出参,与API网关结合,实现传统的可能要我们自己配置Nginx,Apache等软件才能实现的WEB服务。

简单3: 我不需要配置服务器,我只需要用Python写好数据库的增删改查逻辑,并将参数传入,结果返回即可。

简单4: 我不需要评估服务器规模,这是一个简单的Demo,我如果想用起来,我可能要买一个服务器,或者云主机等。但是这就涉及到一笔开销,也需要评估一个规格配置,但是,使用SCF是按量付费,无需考虑这些,自动伸缩等功能都是供应商来实现,相对更便利。

简单5: 真的很方便……

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前端页面设计
    • Index
      • wxml
      • wxss
      • js
    • content
      • wxml
      • wxss
      • js
    • list
      • wxml
      • js
    • login
      • wxml
      • wxss
      • js
    • result
      • wxml
      • wxss
      • js
    • user
      • wxml
      • wxss
      • js
    • APP
      • js
    • 小结
    • 数据库开发
    • 后端接口
    • 总结
    相关产品与服务
    云函数
    云函数(Serverless Cloud Function,SCF)是腾讯云为企业和开发者们提供的无服务器执行环境,帮助您在无需购买和管理服务器的情况下运行代码。您只需使用平台支持的语言编写核心代码并设置代码运行的条件,即可在腾讯云基础设施上弹性、安全地运行代码。云函数是实时文件处理和数据处理等场景下理想的计算平台。
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档