wzh 3 lat temu
rodzic
commit
9bc0763337

+ 11 - 2
README.md

@@ -1,3 +1,12 @@
-# CargoOwner_WxApp
+# 云开发 quickstart
+
+这是云开发的快速启动指引,其中演示了如何上手使用云开发的三大基础能力:
+
+- 数据库:一个既可在小程序前端操作,也能在云函数中读写的 JSON 文档型数据库
+- 文件存储:在小程序前端直接上传/下载云端文件,在云开发控制台可视化管理
+- 云函数:在云端运行的代码,微信私有协议天然鉴权,开发者只需编写业务逻辑代码
+
+## 参考文档
+
+- [云开发文档](https://developers.weixin.qq.com/miniprogram/dev/wxcloud/basis/getting-started.html)
 
-汇很多货主小程序

+ 36 - 0
cloudfunctions/api/WXBizDataCrypt.js

@@ -0,0 +1,36 @@
+var crypto = require('crypto')
+
+function WXBizDataCrypt(appId, sessionKey) {
+  this.appId = appId
+  this.sessionKey = sessionKey
+}
+
+WXBizDataCrypt.prototype.decryptData = function (encryptedData, iv) {
+  // base64 decode
+  var sessionKey = new Buffer(this.sessionKey, 'base64')
+  encryptedData = new Buffer(encryptedData, 'base64')
+  iv = new Buffer(iv, 'base64')
+
+  try {
+    // 解密
+    var decipher = crypto.createDecipheriv('aes-128-cbc', sessionKey, iv)
+    // 设置自动 padding 为 true,删除填充补位
+    decipher.setAutoPadding(true)
+    // var decoded = decipher.update(encryptedData, 'binary', 'utf8')
+    var decoded = decipher.update(encryptedData, '', 'utf8')
+    decoded += decipher.final('utf8')
+
+    decoded = JSON.parse(decoded)
+
+  } catch (err) {
+    throw new Error('Illegal Buffer')
+  }
+
+  if (decoded.watermark.appid !== this.appId) {
+    throw new Error('Illegal Buffer')
+  }
+
+  return decoded
+}
+
+module.exports = WXBizDataCrypt

+ 6 - 0
cloudfunctions/api/config.json

@@ -0,0 +1,6 @@
+{
+  "permissions": {
+    "openapi": [
+    ]
+  }
+}

+ 117 - 0
cloudfunctions/api/index.js

@@ -0,0 +1,117 @@
+// 云函数入口文件
+const cloud = require('wx-server-sdk')
+const TcbRouter = require("tcb-router")
+const got = require('got')
+const md5 = require("md5")
+const APPID = "wxf22759845920b6f3"
+const SECRET = "149873f78958781cd1693c1238deaebc"
+const WXBizDataCrypt = require('./WXBizDataCrypt')
+
+cloud.init()
+
+const db = cloud.database()
+const errorLogs = db.collection("huihenduo_error_log")
+
+// 云函数入口函数
+exports.main = async (event, context) => {
+  const wxContext = cloud.getWXContext()
+  const _openid = wxContext.OPENID
+
+  const app = new TcbRouter({
+    event
+  });
+
+  console.log('Event', event)
+
+  app.use(async (ctx, next) => {
+    ctx.data = {};
+    await next();
+  });
+
+
+  app.router("getWxPhoneNumber", async (ctx, next) => {
+    let {
+      cloudID,
+      encryptedData,
+      errMsg,
+      iv,
+      session_key
+    } = event
+    console.log(event)
+
+    let pc = new WXBizDataCrypt(APPID, session_key)
+
+    let data = pc.decryptData(encryptedData, iv)
+
+    ctx.body = {
+      phone: data.phoneNumber,
+      _openid
+    }
+    await next()
+  })
+
+  app.router("getOpenId", async (ctx, next) => {
+    ctx.body = {
+      openId: _openid
+    }
+    await next()
+  })
+  app.router("sendError", async (ctx, next) => {
+    delete event.$url
+    delete event.userInfo
+    let res = await errorLogs.add({
+      data: {
+        createTime: db.serverDate(),
+        ...event,
+        _openid,
+      }
+    })
+    await next()
+  })
+
+  app.router("base", async (ctx, next) => {
+
+    await next()
+  })
+
+  app.router("code2Session", async (ctx, next) => {
+    let JSCODE = event.JSCODE
+    let url = `https://api.weixin.qq.com/sns/jscode2session?appid=${APPID}&secret=${SECRET}&js_code=${JSCODE}&grant_type=authorization_code`
+
+    let res = await got(url)
+    let result = JSON.parse(res.body)
+    ctx.body = {
+      ...result,
+      _openid
+    }
+
+    await next()
+  })
+
+
+
+  app.router("getAccessToken", async (ctx, next) => {
+    let tokenUrl = `https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=${APPID}&secret=${SECRET}`
+
+
+    let res = await got(tokenUrl)
+    let {
+      access_token
+    } = JSON.parse(res.body)
+    console.log(access_token)
+    ctx.data = {
+      access_token
+    }
+    await next();
+  });
+
+
+  app.router("getOpenId", async (ctx, next) => {
+    ctx.data = {
+      openId: _openid
+    }
+    await next();
+  });
+
+  return app.serve();
+}

+ 17 - 0
cloudfunctions/api/package.json

@@ -0,0 +1,17 @@
+{
+  "name": "api",
+  "version": "1.0.0",
+  "main": "index.js",
+  "scripts": {
+    "test": "echo \"Error: no test specified\" && exit 1"
+  },
+  "author": "",
+  "license": "ISC",
+  "dependencies": {
+    "wx-server-sdk": "~2.5.3",
+    "md5": "^2.3.0",
+    "got": "^11.8.2",
+    "tcb-router": "^1.1.2"
+  },
+  "description": ""
+}

+ 17 - 0
miniprogram/apis/api.js

@@ -0,0 +1,17 @@
+const {
+  api
+} = require("./apiConfig")
+
+function getApi(url, data) {
+  return api(url, data, "get")
+}
+
+function postApi(url, data) {
+  return api(url, data, "post")
+
+}
+
+module.exports = {
+  getApi,
+  postApi
+}

+ 23 - 0
miniprogram/apis/apiConfig.js

@@ -0,0 +1,23 @@
+let v = wx.getAccountInfoSync()
+let apiUrl = `${v.miniProgram.envVersion == 'release'?'https://interface.huihenduo.com.cn/hhd-pat-cargo-app/':'https://interface.huihenduo.com.cn/hhd-pat-cargo-app-dev/'}`
+
+function api(url, data, method) {
+  return new Promise((resolve, reject) => {
+    wx.request({
+      url: `${apiUrl}/${url}`,
+      method,
+      data,
+      dataType: 'json',
+      header: {
+        'content-type': 'application/json'
+      },
+      success: resolve,
+      fail: reject
+    })
+  })
+}
+
+module.exports = {
+  apiUrl,
+  api
+}

+ 22 - 0
miniprogram/apis/cloudApi.js

@@ -0,0 +1,22 @@
+module.exports = async function cloudApi($url, data) {
+  if ($url == "sendError") {
+    let res = getCurrentPages()
+    let v = wx.getAccountInfoSync()
+    data.path = res[res.length - 1].route
+    data.env = v.miniProgram.envVersion
+
+    if (data.error) {
+      data.error = data.error.toString()
+    }
+    if (v.miniProgram.version) {
+      data.appVersion = v.miniProgram.version
+    }
+  }
+  return await wx.cloud.callFunction({
+    name: "api",
+    data: {
+      $url,
+      ...data
+    }
+  })
+}

+ 32 - 0
miniprogram/app.js

@@ -0,0 +1,32 @@
+App({
+  onLaunch: function () {
+    const updateManager = wx.getUpdateManager()
+
+    updateManager.onCheckForUpdate(function (res) {
+      // 请求完新版本信息的回调
+    })
+
+    updateManager.onUpdateReady(function () {
+      wx.showModal({
+        title: '更新提示',
+        content: '新版本已经准备好,是否重启应用?',
+        success: function (res) {
+          if (res.confirm) {
+            // 新的版本已经下载好,调用 applyUpdate 应用新版本并重启
+            updateManager.applyUpdate()
+          }
+        }
+      })
+    })
+
+    updateManager.onUpdateFailed(function () {
+      // 新版本下载失败
+    })
+
+
+    wx.cloud.init({
+      traceUser: true
+    })
+    this.globalData = {}
+  },
+})

+ 37 - 0
miniprogram/app.json

@@ -0,0 +1,37 @@
+{
+  "pages": [
+    "pages/index/index",
+    "pages/voyages/voyages",
+    "pages/me/me",
+    "pages/login/login"
+  ],
+  "window": {
+    "backgroundColor": "#F6F6F6",
+    "backgroundTextStyle": "light",
+    "navigationBarBackgroundColor": "#F6F6F6",
+    "navigationBarTitleText": "汇很多",
+    "navigationBarTextStyle": "black"
+  },
+  "tabBar": {
+    "list": [{
+        "pagePath": "pages/index/index",
+        "text": "首页"
+      },
+      {
+        "pagePath": "pages/voyages/voyages",
+        "text": "航次"
+      },
+      {
+        "pagePath": "pages/me/me",
+        "text": "我"
+      }
+    ]
+  },
+  "permission": {
+    "scope.userLocation": {
+      "desc": "你的位置信息将用于小程序位置接口的效果展示"
+    }
+  },
+  "sitemapLocation": "sitemap.json",
+  "style": "v2"
+}

+ 153 - 0
miniprogram/app.wxss

@@ -0,0 +1,153 @@
+page {
+  width: 100%;
+  height: 100%;
+  background: #e7e6e6;
+}
+
+view {
+  box-sizing: border-box
+}
+
+.df {
+  display: flex;
+}
+
+.jcsb {
+  justify-content: space-between;
+}
+
+.jcc {
+  justify-content: center;
+}
+
+.jcfe {
+  justify-content: flex-end;
+}
+
+.jcsa {
+  justify-content: space-around;
+}
+
+.aic {
+  align-items: center;
+}
+
+.m10a {
+  margin: 10rpx auto;
+}
+
+.m20a {
+  margin: 20rpx auto;
+}
+
+.m30a {
+  margin: 30rpx auto;
+}
+
+.m40a {
+  margin: 40rpx auto;
+}
+
+.m50a {
+  margin: 50rpx auto;
+}
+
+.mt10 {
+  margin-top: 10rpx;
+}
+
+.mt20 {
+  margin-top: 20rpx;
+}
+
+.mt30 {
+  margin-top: 30rpx;
+}
+
+.mt40 {
+  margin-top: 40rpx;
+}
+
+.mt50 {
+  margin-top: 50rpx;
+}
+
+.mr10 {
+  margin-right: 10rpx;
+}
+
+.mr20 {
+  margin-right: 20rpx;
+}
+
+.mr30 {
+  margin-right: 30rpx;
+}
+
+.mr40 {
+  margin-right: 40rpx;
+}
+
+.mr50 {
+  margin-right: 50rpx;
+}
+
+.mb10 {
+  margin-bottom: 10rpx;
+}
+
+.mb20 {
+  margin-bottom: 20rpx;
+}
+
+.mb30 {
+  margin-bottom: 30rpx;
+}
+
+.mb40 {
+  margin-bottom: 40rpx;
+}
+
+.mb50 {
+  margin-bottom: 50rpx;
+}
+
+.ml10 {
+  margin-left: 10rpx;
+}
+
+.ml20 {
+  margin-left: 20rpx;
+}
+
+.ml30 {
+  margin-left: 30rpx;
+}
+
+.ml40 {
+  margin-left: 40rpx;
+}
+
+.ml50 {
+  margin-left: 50rpx;
+}
+
+.p10 {
+  padding: 10rpx;
+}
+
+.p20 {
+  padding: 20rpx;
+}
+
+.p30 {
+  padding: 30rpx;
+}
+
+.p40 {
+  padding: 40rpx;
+}
+
+.p50 {
+  padding: 50rpx;
+}

+ 6 - 0
miniprogram/envList.js

@@ -0,0 +1,6 @@
+const envList = [{"envId":"huihenduo-0gwuxs6d1c6824e4","alias":"huihenduo"}]
+const isMac = true
+module.exports = {
+    envList,
+    isMac
+}

+ 22 - 0
miniprogram/pages/index/index.js

@@ -0,0 +1,22 @@
+// pages/index/index.js
+import {
+  getApi,
+  postApi
+} from "../../apis/api"
+import cloudApi from "../../apis/cloudApi"
+Page({
+  data: {
+    indexInfo:{}
+  },
+  async getIndexInfo() {
+    let res = await postApi('/voyage/index', {
+      cargoOwnerId: wx.getStorageSync('cargoOwnerId')
+    })
+    this.setData({
+      indexInfo:res.data.result
+    })
+  },
+  onLoad() {
+    this.getIndexInfo()
+  }
+})

+ 3 - 0
miniprogram/pages/index/index.json

@@ -0,0 +1,3 @@
+{
+  "usingComponents": {}
+}

+ 27 - 0
miniprogram/pages/index/index.wxml

@@ -0,0 +1,27 @@
+<view>
+  <view class="block-line df aic">
+    <view>
+      <view>运输中船舶数量</view>
+      <view>{{indexInfo.transShipCount}}</view>
+    </view>
+    <view>
+      <view>卸货中船舶数量</view>
+      <view>{{indexInfo.dischargeShipCount}}</view>
+    </view>
+  </view>
+  <view class="block-line df aic">
+    <view>
+      <view>在卸吨位</view>
+      <view>{{indexInfo.dischargeTons}}/{{indexInfo.totalDischargeTons}}</view>
+    </view>
+    <view>
+      <view>已完成卸货吨位</view>
+      <view>{{indexInfo.finshDischargeTons}}</view>
+    </view>
+  </view>
+</view>
+<input class="p10 m30a" style="border: 1rpx solid grey;width: 80%;background: #fff;" type="text" placeholder="搜索船舶信息" />
+<view class="df aic jcsa">
+  <view>运输中</view>
+  <view>卸货中</view>
+</view>

+ 30 - 0
miniprogram/pages/index/index.wxss

@@ -0,0 +1,30 @@
+.block-line>view {
+  width: 50%;
+  text-align: center;
+  color: #fff;
+  height: 200rpx;
+}
+
+.block-line:first-child>view:first-child {
+  background: purple;
+}
+
+.block-line:first-child>view:last-child {
+  background: red;
+}
+
+.block-line:last-child>view:first-child {
+  background: blue;
+}
+
+.block-line:last-child>view:last-child {
+  background: green;
+}
+
+.block-line>view>view:first-child {
+  margin-top: 40rpx;
+  margin-bottom: 30rpx;
+}
+
+
+.block-line>view>view:last-child {}

+ 30 - 0
miniprogram/pages/login/login.js

@@ -0,0 +1,30 @@
+// pages/login/login.js
+import {
+  getApi,
+  postApi
+} from "../../apis/api"
+import cloudApi from "../../apis/cloudApi"
+Page({
+  data: {
+
+  },
+  async register() {
+
+  },
+
+  async login() {
+    wx.setStorageSync('cargoOwnerId', 1)
+    wx.switchTab({
+      url: '/pages/index/index',
+    })
+    return
+    let res = await cloudApi('getOpenId')
+    console.log(res)
+    let {
+      openId
+    } = res.result
+    let res0 = postApi('/user/wx/openId/login', {
+      openId
+    })
+  }
+})

+ 3 - 0
miniprogram/pages/login/login.json

@@ -0,0 +1,3 @@
+{
+  "usingComponents": {}
+}

+ 1 - 0
miniprogram/pages/login/login.wxml

@@ -0,0 +1 @@
+<button bindtap="login">login</button>

+ 1 - 0
miniprogram/pages/login/login.wxss

@@ -0,0 +1 @@
+/* pages/login/login.wxss */

+ 14 - 0
miniprogram/pages/me/me.js

@@ -0,0 +1,14 @@
+// pages/me/me.js
+import {
+  getApi,
+  postApi
+} from "../../apis/api"
+import cloudApi from "../../apis/cloudApi"
+Page({
+  data: {
+
+  },
+  async getCargoOwnerInfo() {
+
+  }
+})

+ 3 - 0
miniprogram/pages/me/me.json

@@ -0,0 +1,3 @@
+{
+  "usingComponents": {}
+}

+ 2 - 0
miniprogram/pages/me/me.wxml

@@ -0,0 +1,2 @@
+<!--pages/me/me.wxml-->
+<text>pages/me/me.wxml</text>

+ 1 - 0
miniprogram/pages/me/me.wxss

@@ -0,0 +1 @@
+/* pages/me/me.wxss */

+ 66 - 0
miniprogram/pages/voyages/voyages.js

@@ -0,0 +1,66 @@
+// pages/voyages/voyages.js
+Page({
+
+  /**
+   * 页面的初始数据
+   */
+  data: {
+
+  },
+
+  /**
+   * 生命周期函数--监听页面加载
+   */
+  onLoad: function (options) {
+
+  },
+
+  /**
+   * 生命周期函数--监听页面初次渲染完成
+   */
+  onReady: function () {
+
+  },
+
+  /**
+   * 生命周期函数--监听页面显示
+   */
+  onShow: function () {
+
+  },
+
+  /**
+   * 生命周期函数--监听页面隐藏
+   */
+  onHide: function () {
+
+  },
+
+  /**
+   * 生命周期函数--监听页面卸载
+   */
+  onUnload: function () {
+
+  },
+
+  /**
+   * 页面相关事件处理函数--监听用户下拉动作
+   */
+  onPullDownRefresh: function () {
+
+  },
+
+  /**
+   * 页面上拉触底事件的处理函数
+   */
+  onReachBottom: function () {
+
+  },
+
+  /**
+   * 用户点击右上角分享
+   */
+  onShareAppMessage: function () {
+
+  }
+})

+ 3 - 0
miniprogram/pages/voyages/voyages.json

@@ -0,0 +1,3 @@
+{
+  "usingComponents": {}
+}

+ 2 - 0
miniprogram/pages/voyages/voyages.wxml

@@ -0,0 +1,2 @@
+<!--pages/voyages/voyages.wxml-->
+<text>pages/voyages/voyages.wxml</text>

+ 1 - 0
miniprogram/pages/voyages/voyages.wxss

@@ -0,0 +1 @@
+/* pages/voyages/voyages.wxss */

+ 7 - 0
miniprogram/sitemap.json

@@ -0,0 +1,7 @@
+{
+  "desc": "关于本文件的更多信息,请参考文档 https://developers.weixin.qq.com/miniprogram/dev/framework/sitemap.html",
+  "rules": [{
+    "action": "allow",
+    "page": "*"
+  }]
+}

+ 22 - 0
miniprogram/utils/upload.js

@@ -0,0 +1,22 @@
+import {
+  apiUrl
+} from "../apis/apiConfig"
+
+function uploadFile(filePath, formData) {
+  return new Promise((resolve, reject) => {
+    wx.uploadFile({
+      url: `${apiUrl}/cos/upload`,
+      filePath,
+      name: 'file',
+      formData,
+      success: e => {
+        resolve(JSON.parse(e.data))
+      },
+      fail: reject
+    })
+  })
+}
+
+module.exports = {
+  uploadFile
+}

+ 57 - 0
miniprogram/utils/wxUtils.js

@@ -0,0 +1,57 @@
+import cloudApi from "../apis/cloudApi"
+
+function wxSetSessionKey() {
+  return new Promise((resolve, reject) => {
+    wx.login({
+      success: async res => {
+        let res1 = await cloudApi('code2Session', {
+          JSCODE: res.code
+        })
+        wx.setStorageSync('session_key', res1.result.session_key)
+        wx.setStorageSync('openId', res1.result._openid)
+        resolve({
+          session_key: res1.result.session_key,
+          openId: res1.result._openid
+        })
+      }
+    })
+  })
+
+}
+
+function getUserProfile() {
+  return new Promise((resolve, reject) => {
+    wx.getUserProfile({
+      desc: "'用于完善用户信息",
+      success: e => {
+        let {
+          userInfo
+        } = e
+        resolve({
+          status: 0,
+          userInfo
+        })
+      },
+      fail: e => {
+        resolve({
+          errMsg: e.errMsg,
+          status: 1
+        })
+      }
+    })
+  })
+}
+
+function getOpenId() {
+  return new Promise(async (resolve, reject) => {
+    let res1 = await cloudApi('getOpenId')
+    resolve(res1.result.openId)
+  })
+
+}
+
+module.exports = {
+  wxSetSessionKey,
+  getUserProfile,
+  getOpenId
+}

+ 85 - 0
project.config.json

@@ -0,0 +1,85 @@
+{
+  "description": "项目配置文件,详见文档:https://developers.weixin.qq.com/miniprogram/dev/devtools/projectconfig.html",
+  "miniprogramRoot": "miniprogram/",
+  "cloudfunctionRoot": "cloudfunctions/",
+  "setting": {
+    "urlCheck": true,
+    "es6": true,
+    "enhance": true,
+    "postcss": true,
+    "preloadBackgroundData": false,
+    "minified": true,
+    "newFeature": true,
+    "coverView": true,
+    "nodeModules": false,
+    "autoAudits": false,
+    "showShadowRootInWxmlPanel": true,
+    "scopeDataCheck": false,
+    "uglifyFileName": false,
+    "checkInvalidKey": true,
+    "checkSiteMap": true,
+    "uploadWithSourceMap": true,
+    "compileHotReLoad": false,
+    "lazyloadPlaceholderEnable": false,
+    "useMultiFrameRuntime": false,
+    "useApiHook": false,
+    "useApiHostProcess": false,
+    "babelSetting": {
+      "ignore": [],
+      "disablePlugins": [],
+      "outputPath": ""
+    },
+    "useIsolateContext": false,
+    "userConfirmedBundleSwitch": false,
+    "packNpmManually": false,
+    "packNpmRelationList": [],
+    "minifyWXSS": true,
+    "disableUseStrict": false,
+    "minifyWXML": true,
+    "showES6CompileOption": false,
+    "useCompilerPlugins": false,
+    "ignoreUploadUnusedFiles": true
+  },
+  "appid": "wxf22759845920b6f3",
+  "projectname": "%E6%B1%9F%E8%BF%90%E9%9A%8F%E6%89%8B%E6%8B%8D2.0",
+  "libVersion": "2.19.6",
+  "cloudfunctionTemplateRoot": "cloudfunctionTemplate/",
+  "condition": {
+    "search": {
+      "list": []
+    },
+    "conversation": {
+      "list": []
+    },
+    "plugin": {
+      "list": []
+    },
+    "game": {
+      "list": []
+    },
+    "miniprogram": {
+      "list": [
+        {
+          "id": -1,
+          "name": "db guide",
+          "pathName": "pages/databaseGuide/databaseGuide"
+        }
+      ]
+    }
+  },
+  "compileType": "miniprogram",
+  "scripts": {},
+  "packOptions": {
+    "ignore": [],
+    "include": []
+  },
+  "watchOptions": {
+    "ignore": []
+  },
+  "debugOptions": {
+    "hidedInDevtools": []
+  },
+  "staticServerOptions": {
+    "servePath": ""
+  }
+}

+ 66 - 0
project.private.config.json

@@ -0,0 +1,66 @@
+{
+  "condition": {
+    "plugin": {
+      "current": -1,
+      "list": []
+    },
+    "game": {
+      "current": -1,
+      "list": []
+    },
+    "gamePlugin": {
+      "current": -1,
+      "list": []
+    },
+    "miniprogram": {
+      "list": [
+        {
+          "name": "",
+          "pathName": "pages/me/me",
+          "query": "",
+          "launchMode": "default",
+          "scene": null
+        },
+        {
+          "name": "",
+          "pathName": "pages/login/login",
+          "query": "",
+          "scene": null,
+          "launchMode": "default"
+        }
+      ]
+    }
+  },
+  "setting": {
+    "urlCheck": true,
+    "coverView": true,
+    "es6": true,
+    "postcss": true,
+    "compileHotReLoad": false,
+    "lazyloadPlaceholderEnable": false,
+    "preloadBackgroundData": false,
+    "minified": true,
+    "autoAudits": false,
+    "uglifyFileName": false,
+    "uploadWithSourceMap": true,
+    "enhance": true,
+    "useMultiFrameRuntime": false,
+    "showShadowRootInWxmlPanel": true,
+    "packNpmManually": false,
+    "packNpmRelationList": [],
+    "minifyWXSS": true,
+    "minifyWXML": true,
+    "useStaticServer": true,
+    "showES6CompileOption": false,
+    "checkInvalidKey": true,
+    "babelSetting": {
+      "ignore": [],
+      "disablePlugins": [],
+      "outputPath": ""
+    },
+    "disableUseStrict": false,
+    "useCompilerPlugins": false,
+    "ignoreUploadUnusedFiles": true
+  },
+  "description": "项目私有配置文件。此文件中的内容将覆盖 project.config.json 中的相同字段。项目的改动优先同步到此文件中。详见文档:https://developers.weixin.qq.com/miniprogram/dev/devtools/projectconfig.html"
+}

+ 1 - 0
uploadCloudFunction.sh

@@ -0,0 +1 @@
+"/Applications/wechatwebdevtools.app/Contents/MacOS/cli" cloud functions deploy --e huihenduo-0gwuxs6d1c6824e4 --n quickstartFunctions --r --project "/Users/wangzhihui/Desktop/汇很多/weapp/JiangYunPhotos" --report_first --report

+ 21 - 0
隐私协议.txt

@@ -0,0 +1,21 @@
+本隐私政策介绍本公司的隐私数据相关政策和惯例,包括在使用汇很多小程序时上传至云端的数据将受到保护,防止以及追究某些非法手段获取本公司所保管的关于您的数据资料。请你仔细阅读我们的隐私政策。
+一、本公司如何收集您的个人信息
+汇很多小程序以个人电话号码作为唯一身份识别方式,用于个人登录使用以及密码遗忘、找回的唯一途径。
+当您使用本公司的微信小程序,注册过程中我们将仅收集您的电话号码作为唯一身份识别,使用期间终身有效。
+二、本公司如何使用您的个人信息
+1、通过您的手机号码实现密码找回功能。
+2、本公司不会向任何无关第三方提供、出售、出租、分享或交易您的个人信息,除非事先得到您的许可,或该第三方和本公司单独或共同为您提供服务,且在该服务结束后,其将被禁止访问包括其以前能够访问的所有这些信息。
+三、个人信息安全
+保证您的数据的安全对我们来说至关重要。当您在本公司的微信小程序中注册输入个人信息时,我们对这些信息进行加密。
+在数据传输和数据保管两个阶段里,我们会通过广为接受的行业标准(如防火墙、加密和数据隐私法律要求)来保护您向我们提交的信息。
+然而,没有任何一种互联网传输或电子存储方法是100%安全的。因此,尽管我们通过商业上可接受的方式来保护您的个人信息,但仍无法保证信息的绝对安全。
+四、本公司会将个人信息保存多久
+一般来说,本公司仅在您使用本公司微信小程序期间保留您的个人信息,同时将遵守适用法律规定的数据保留期限。
+五、法律免责声明
+在法律要求的情况下(如协助公安机关)或遵守司法程序、法院指令,以及因用户行为而致使本公司的法定权益收到威胁,或适用于本公司的微信小程序的法律程序时,我们有权透露您的个人信息。
+如果本公司确定为了执行本公司的条款和条件或保护我们的经营,披露是合理必须的,则我们可能会披露与您有关的信息。
+六、本隐私政策的更改
+本公司会根据国家法律法规不定时更改本政策协议。修改执行之前,本公司将会在小程序用户协议、以及本公司网站通知本次政策更改,以便您了解我们如何收集、使用您的个人信息,哪些人可以访问这些信息,以及在什么情况下我们会披露这些信息。
+本公司保留随时修改本政策的权利,因此请经常查看。
+七、隐私问题
+如果你对本公司的隐私政策或数据处理有任何问题或顾虑,请通过+86 18049981341与本公司联系。