todolist - 微信小程序 - 云开发

简介:

1、微信登录

2、微信用户todolist管理

3、根据todolist发送消息推送

4、根据todolist发送邮件提醒

1、准备工具

2、项目准备

       获取到创建项目时使用的AppID

  • 项目创建(根据上一步生成的AppID创建项目)

 

  • 云环境创建

环境名称:test。一个小程序最多可以有2个隔离的云环境,通常来说测试环境取名为 test,以后的正式环境可取名为 release。

付费方式:按量付费,具有一定的免费额度。在少量用户时等同于免费。

  • 云环境中创建数据库

云开发->数据库->"+"按钮->"todo" 确认 

  • 小程序打开消息订阅功能(可选,适用于待办事项消息推送)

  • 邮箱打开POP3/IMAP/SMTP/Exchange/CardDAV/CalDAV服务(可选,适用于发送待办事项邮件推送)
    设置 - 账户 - 开启 POP3/SMTP 服务

    更具提示生成授权码(后续要用)

 

 

 

3、项目结构

 

  • cloudfunctions/ 云函数目录 (配置项目配置文件project.config.json后产生)

  • getList/ 云函数getList (右键cloudfunctions "新建Node.js" 名称为 getList生成)

  • pushNotify/ 云函数pushNotify 同上 (包含触发器)

  • sendEmail/ 云函数sendEmail 同上

  • updateCheck/ 云函数updateCheck 同上

  • page/ 页面配置目录

  • page/index/ 主页配置目录

  • page/log/ 日志配置目录

  • app.js 应用主逻辑文件(js编程)

  • app.json 应用整体配置文件(json格式,主要环境变量等)

  • index.wxml 应用页面框架(和html页面相同,主要定页面框架)

  • app.wxss 应用渲染(可以理解为css渲染)

注意
1、page/index/ 目录中同样存在.js .json .wxml .wxss文件和app主目录相同,主要编写逻辑部分,及js文件。其他云函数和页面类似。
2、云函数编辑完成后需要右键 "上传并部署:云端安装依赖..."
3、包含触发器的云函数编辑上传后,需要 右键 "上传触发器"

4、项目源码

本地代码部分

app.js

// app.js
App({
  onLaunch () {
    // Do something initial when launch.
    //初始云化
    this.initcloud()
    this.globalData = {
      // 用于存储待办记录的集合名称
      collection: 'todo',	// 填写数据库中创建的collection
    }
  },

  // 初始化云开发环境
  initcloud() {
    wx.cloud.init({
      traceUser: true,
      // 填写你的云环境id
      env: "**********************" // 请填写你云环境的ID 云开发->概览->环境ID(右上角)
    })
    // 装载云函数操作对象返回方法
    this.cloud = () => {
      return wx.cloud // 直接返回 wx.cloud
    }
  },

  // 获取云数据库的实例
  async database() {
    return (await this.cloud()).database()
  },

  onShow (options) {
    // Do something when show.
  },
  onHide () {
    // Do something when hide.
  },
  onError (msg) {
    console.log(msg)
  },
  globalData: 'I am global data'
})

app.json

{
  "pages": [
      "pages/index/index",
      "pages/logs/logs"
  ],
  "window": {
      "navigationBarBackgroundColor": "#6495ED",
      "navigationBarTitleText": "Todo-List"
  },
  "style": "v2",
  "sitemapLocation": "sitemap.json",
  "useExtendedLib": {
    "weui": true
  }
}

project.config.json

{
  "appid": "****************", // 请填写申请的微信小程序AppId 开发工具->详情->基本信息 或微信小程序主页设置中查找
  "compileType": "miniprogram",
  "libVersion": "2.32.2",
  "packOptions": {
    "ignore": [],
    "include": []
  },
  "setting": {
    "coverView": true,
    "es6": true,
    "postcss": true,
    "minified": true,
    "enhance": true,
    "showShadowRootInWxmlPanel": true,
    "packNpmRelationList": [],
    "babelSetting": {
      "ignore": [],
      "disablePlugins": [],
      "outputPath": ""
    },
    "condition": false
  },
  "condition": {},
  "editorSetting": {
    "tabIndent": "insertSpaces",
    "tabSize": 2
  },
  "cloudfunctionRoot": "cloudfunctions/",
  "cloudfunctionTemplateRoot": "cloudfunctionTemplate/"
}

page\index\index.wxml

<view class="container">
  <!-- 在container的头部添加新代码 -->
  <view class="list-input">
    <!-- 输入框本体 -->
    <view class="weui-cell weui-cell_input">
      <input 
             value="{{inputedValue}}" 
             bind:input="keyInput" 
             class="weui-input" 
             maxlength="50" 
             placeholder="请输入待办事项" 
             />
    </view>
      
    <!-- 分割线 -->
    <view class="line"></view>
      
 <!-- 提交按钮 -->
    <button 
            bind:tap="inputSubmit" 
            class="weui-btn" 
            type="default" 
            style="color: gray;"
            >提交</button>
  </view>


  <view class="weui-cells weui-cells_after-title">
    <checkbox-group bind:change="checkboxChange">
      <label class="weui-cell weui-check__label" wx:for="{{items}}" wx:key="id">
        <view class="weui-cell__hd">
          <checkbox value="{{item.id}}" checked="{{item.checked}}" />
        </view>
        <view class="weui-cell__bd">
          {{item.content}}
        </view>
      </label>
    </checkbox-group>
  </view>

</view>

page\index\index.wxss

.list-input {
  padding-top: 30rpx;
  padding-bottom: 50rpx;
}

.line {
  width: 100%;
  height: 3rpx;
  background: #ddd;
  margin-bottom: 20rpx;
}

page\index\index.js

// pages/index/index.js
Component({
  // 页面持有的数据
  data:{
    // todo-list 数据
    items: [],
    // 输入框当前内容
    inputedValue: "",
  },

  lifetimes: {
    attached() {
      getApp().cloud().callFunction({
        name: 'getList',
        complete: res => {
          // console.log('callFunction result: ', res)
          this.setData({
            items: res.result.data
          })
        }
      })
    },
  },

  methods: {
    // 辅助函数,生成一个随机的id
    getUUID(randomLength = 12) {
      return Math.random().toString().substr(2,randomLength) + Date.now().toString(36)
    },

    // 监听输入框按键
    keyInput(e){
      this.setData({
        inputedValue: e.detail.value
      })
    },

    // 提交数据
    inputSubmit(){
      // 设置条目的id
      const newID = this.getUUID()
      const newItem = {
        id: newID,
        content: this.data.inputedValue,
        checked: false,
        // 新增是否订阅数据代码
        pushed: false,
      }
      // 将新条目更新到iteams状态中
      // 并将输入框的值清空
      let items = JSON.parse(JSON.stringify(this.data.items))
      items.unshift(newItem);
      this.setData({
        items: items,
        inputedValue: "",
      })
      // 将items提交到云数据库
      this.uploadData(newItem)
      // 订阅服务
      this.subscribe()
      // 发送邮件服务
      console.log('发送邮件!!!')
      getApp().cloud().callFunction({
        name: 'sendEmail',
        data: {
          content: newItem.content
        },
      })
    },

    // 上传数据到云数据库
    async uploadData(item) {
      const db = await getApp().database()
      db.collection('todo').add({
        data: item
      })
    },

    // 更新待办事项的完成状态
    checkboxChange(e){
      let items = JSON.parse(JSON.stringify(this.data.items))
      // 遍历items状态,找到checked状态变化的元素
      for (const [index,item] of items.entries()){
        if (item.checked !== e.detail.value.includes(item.id)){
          // setData 状态修改数据元素的一种方法
          const key = `items[${index}].checked`
          const checked = !items.checked
          this.setData({
            // 注意这里要加括号 []
            [key]: checked
          })
          // 调用云函数,更新数据库
          getApp().cloud().callFunction({
            name: 'updateCheck',
            data: {
              id: item.id,
              checked: checked
            }
          })
          break
        }
      }
    },

    // 新增方法
    // 向用户申请推送服务
    subscribe(){
      // 填写你自己的模板id
      const templateId = '****************************' // 请填写订阅事件模板ID
      // 仅显示了主流程
      // 正式环境中,需考虑到用户可能会点击'拒绝','永久拒绝'等情况
      // 并弹出对应的反馈,如弹窗等
      wx.requestSubscribeMessage({
        tmplIds: [templateId],
        success (res) {
          console.log('订阅成功',res)
        },
        fail (err) {
          console.log('订阅失败',err)
        }
      })
    },

  },
})

云函数部分

cloudfunctions\getList\index.js

// 云函数入口文件
const cloud = require('wx-server-sdk')
cloud.init({env: cloud.DYNAMIC_CURRENT_ENV})
// 获取云数据库对象
const db = cloud.database()

// 云函数入口函数
exports.main = async (event,context) => {
  // 获取微信用户的 openID
  const openID = cloud.getWXContext().OPENID
  // 查询当前用户的所有待办数据
  const fetchResult = await db.collection('todo').where({
    _openid: openID,
    checked: false,
  }).get()
  return fetchResult
}

cloudfunctions\pushNotify\index.js

const cloud = require('wx-server-sdk')
// 初始化 cloud
cloud.init({
  // API 调用都保持和云函数当前所在环境一致
  // 不加此参数就默认为第一个创建的云环境
  env: cloud.DYNAMIC_CURRENT_ENV
})

const db = cloud.database()
const kTableName = 'todo'

// 云函数入口函数
exports.main = async (event, context) => {
  try {
    // --- 步骤1 ---
    // 从云开发数据库中查询等待发送的消息列表
    const msgArr = await db
      .collection(kTableName)
      // 查询条件
      .where({
        checked: false,
        pushed: false,
      })
      .get()

    // --- 步骤2 ---
    for (const msgData of msgArr.data) {
      // 发送订阅消息
      await cloud.openapi.subscribeMessage.send({
        touser: msgData._openid, // 要发送用户的openid
        page: 'pages/index/index', // 用户通过消息通知点击进入小程序的页面
        lang: 'zh_CN',
        // 订阅消息模板ID
        // 替换为你的模板id!
        templateId: '****************************', // 请填写订阅事件模板ID
        // 跳转小程序类型:developer为开发版;trial为体验版;formal为正式版;默认为正式版
        // 正式版删除此行
        miniprogramState: 'developer',
        // 要发送的数据,要和模板一致
        data: {
          // 待办的主题
          thing1: {
            value: msgData.content === '' ? '无' : sliceBodyStr(msgData.content, 16)
          },
          // 待办的详情
          thing4: {
            value: '别忘了待办事项哟'
          },
        }
      })
        
      // --- 步骤3 ---
      // 发送成功后将pushed数据状态重置
      db
        .collection(kTableName)
        .doc(msgData._id)
        .update({
          data: {
            pushed: true
          },
        })
    }
      
    // --- 步骤4 ---
    return msgArr
  } catch (e) {
    return e
  }
}

// 将太长的文本截短
function sliceBodyStr(str, length) {
  if (str.length <= length) {
    return str
  } else {
    return str.slice(0, length) + '...'
  }
}

cloudfunctions\pushNotify\config.json (触发器部分)

{
  "permissions": {
    "openapi": ["subscribeMessage.send"]
  },
  "triggers": [{
    "name": "myTimer",
    "type": "timer",
    "config": "*/50 * * * * * *"
  }]
}

cloudfunctions\sendEmail\index.js

// 云函数入口文件
const cloud = require('wx-server-sdk')

cloud.init({ env: cloud.DYNAMIC_CURRENT_ENV }) // 使用当前云环境

// 引入nodemailer
const nodemailer = require('nodemailer')
// 创建一个SMTP客户端配置
const config = {
  host: 'smtp.qq.com', // 邮箱smtp服务,不同厂家地址不一样
  port: 465, // 邮箱端口,不同厂家可能不一样
  auth: {
    user: '这里填写你的邮箱',// 邮箱账户 这里填写你的邮箱
    pass: '这里填写你的邮箱授权码' // 邮箱授权码 这里填写你的邮箱授权码
  }
};

// 创建一个SMTP客户端对象
var transporter = nodemailer.createTransport(config);

// 云函数入口函数
exports.main = async (event, context) => {
  // 创建一个邮件对象
  var mail = {
    // 发件人,填写发件人邮箱
    from: '来露娜 <******@***.***>',
    // 主题
    subject: 'Weapp [待办清单] 用户反馈',
    // 收件人
    to: '******@***.***',	// 请填写收件人邮箱
    // 邮件内容,text或者html格式
    text: event.content
  };

  let res = await transporter.sendMail(mail);
  return res;
}

cloudfunctions\updateCheck\index.js

// 云函数入口文件
const cloud = require('wx-server-sdk')

cloud.init({ env: cloud.DYNAMIC_CURRENT_ENV }) // 使用当前云环境

// 获取云数据库
const db = cloud.database()

// 云函数入口函数
exports.main = async (event, context) => {
  const openID = cloud.getWXContext().OPENID
  try{
    return await db.collection('todo').where({
      id : event.id,
      _openid: openID,
    })
    .update({
      data: {
        checked: event.checked
      },
    })
  } catch(e){
    console.error(e)
  }
}

注意

1、需要修改如下信息

app.js
// 填写你的云环境id
env: "**********************" // 请填写你云环境的ID 云开发->概览->环境ID(右上角)

project.config.json
"appid": "****************", // 请填写申请的微信小程序AppId 开发工具->详情->基本信息 或微信小程序主页设置中查找

page\index\index.js
// 填写你自己的模板id
const templateId = '****************************' // 请填写订阅事件模板ID

cloudfunctions\pushNotify\index.js
// 替换为你的模板id!
templateId: '****************************', // 请填写订阅事件模板ID

cloudfunctions\sendEmail\index.js
user: '这里填写你的邮箱',// 邮箱账户 这里填写你的邮箱
pass: '这里填写你的邮箱授权码' // 邮箱授权码 这里填写你的邮箱授权码
// 收件人
to: '******@***.***',	// 请填写收件人邮箱

2、其余文件均初始化后不用修改 

5、项目发布

微信小程序开发工具

上传-> 确认 -> 填写: 版本号、项目备注 -> 上传

 

上传后显示上传成功

微信小程序管理网页

 

版本管理(鼠标向下滑动)->开发版本->提交审核->阅读协议->下一步->继续提交->提交审核

 

审核通过后,提交发布

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值