驚了!個人小程序上線一小時,服務器崩了!

前言

        寒假在家玩的都不想玩了,想着還是應該做些有意思的事情。本來想着過年換臺新電腦,由於疫情原因,還是沒有換。但是舊電腦上的數據還是得整理一下,畢竟C盤已經出現紅色警告了。┭┮﹏┭┮
        學習編程快兩年了,寫了還是比較多的源代碼(大部分都是作業)想着自己做課設,百度,一個類似的源碼都沒有,只有靠自己慢慢查找資料,一步一步寫。那種心酸歷程真的很痛苦(當然最後看着自己的小作品也是很開心的) 這時海轟心想:如果我搭建一個平臺,把自己寫過的一些源代碼都放在上面,有需要的小夥伴直接就可以拿過來借鑑,省去了很多不必要的時間開銷(編程這一塊 如果有朋友指導 可以少踩很多的坑)恰好自己會一點點的微信小程序,而且微信官方是允許個人開發者上線個人小程序的。(剛好海轟很久以前申請了一個賬號 O(∩_∩)O哈哈~)

成果展示

        小程序第一個版本代碼差不多寫了3天【2月13日上線】,後面又不斷修修補補,開發之路非常坎坷啊(主要還是技術太菜 太多bug)【小程序名:海轟Pro】
        小程序上線一小時的後臺數據:
在這裏插入圖片描述
        截止目前爲止的用戶總數:
在這裏插入圖片描述
小程序演示視頻【H33版本】

小程序測試圖
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述

小程序開發之需求

  • 由於海轟的賬號類型屬於個人賬號,基本上社交類型的小程序的不支持發佈上線。而且使用的用戶應該不是很多,所以用雲開發就可以了(主要是免費啊)
  • 使用的免費版的雲數據庫,存儲容量十分有限,所以海轟覺得將所有的源碼放在雲盤,小程序只是作爲一個提供下載鏈接和下載密令的中介平臺。(減輕服務器負擔)
  • 對於存放在雲盤的代碼,如果同一個鏈接下載次數過多,會造成封號,所以採用一定的措施限制流量。這裏海轟給出的方案是:積分制度。用戶每天登陸小程序可以獲得相應的積分,採用積分兌換的方法獲取源碼下載鏈接。
  • 界面簡潔美觀,用戶易於操作

小程序開發之模塊設計

1.首頁輪播圖
        不知道怎麼的,海轟十分喜歡輪播圖這個風格,覺得沒有輪播圖,小程序感覺不是很好看。官方開發文檔給出的swiper組件有點不是很好看,這裏海轟使用的是重新設計後的一個輪播圖組件【借鑑前端大佬的】
JS

// components/theSwiper.js
const db = wx.cloud.database()

Component({
  /**
   * 組件的屬性列表
   */
  properties: {
    imgUrls: Array,
  },

  /**
   * 組件的初始數據
   */
  data: {
    currentIndex: 0
  },
  /**
   * 組件的方法列表
   */
  methods: {
    swiperChange(e) {
      this.setData({
        currentIndex: e.detail.current
      });
    },
  
  }
});

WXML

<swiper indicator-dots="true" 
        autoplay="{{true}}" 
        interval="5000" 
        indicator-dots="{{false}}" 
        indicator-color='#8a8a8a' 
        indicator-active-color='#333' 
        circular="true" 
        class="swiper-block" 
        bindchange="swiperChange" 
        previous-margin="100rpx" 
        next-margin="100rpx" 
        current="{{0}}">
  <block wx:for="{{imgUrls}}"  wx:key="{{index}}">
    <swiper-item class="swiper-item ">
      <image mode="aspectFill" src="{{item}}"  wx:key   class="slide-image {{currentIndex == index ? 'active' : 'common'}}" />
    </swiper-item>
  </block>
</swiper>



WXSS

page{
  background-color: #fff;
}
.swiper-block {
  background: #fff;
  height: 500rpx;
  width: 100%;
}

.swiper-item{
  display: flex;
  flex-direction: column;
  justify-content: start;
  align-items: flex-start;
  overflow: unset;
  width: 550rpx;
  height: 450rpx;
  padding-top: 70rpx;
  padding-bottom: 20rpx;
  box-sizing: border-box;
}

.slide-image{
  height: 300rpx;
  width: 450rpx;
  border-radius: 10rpx;
  margin: 0rpx 50rpx ;
  z-index: 1;
  box-shadow: 10rpx 5px 40rpx rgba(0, 0, 0,0.5);
}
.active{
  transform: scale(1.3);
  transition: all .5s ease-in 0s;
  z-index: 20;
  opacity: 1;
}
.common{
  transform: scale(1);
  transition: all .5s ease-in 0s;
  z-index: 0;
  opacity: 0.4;
}

.dots-box{
  display: flex;
  justify-content: center;
  align-items: center;
}

.dots{
  width: 30rpx;
  height: 6rpx;
  margin: 0 4rpx;
  background-color: #aaa;
  margin-top: -80rpx;
}
.bg-333{
  background-color: #333;
}

2.首頁功能選擇
        這個樣式應該是海轟在初學小程序的時候寫了一個小demo吧,感覺還行,這裏就直接拿來用了
WXML

<view class="middle">
<view class="middle_box shadow-blur light shadow-blur animation-scale-up bg-{{item.color}}" wx:for="{{functions}}" bindtap="tofunction" data-id="{{index}}"   >
<view class="box_right">
<view class="box_righttop">{{item.name}}</view>
<view class="box_rightlow"><text style="font-size:50rpx;margin:3rpx;color:red;">{{item.numbers}}</text>{{item.classifier}}</view>
</view>
<view class="box_left">
<image  class="box_img" src="{{item.iconpath}}"></image>
</view>
</view>
</view>

WXSS


.middle{
  
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  justify-content: space-between;
  width: 90%;
  margin: 0 auto;
}
.middle_box{
  width:48%;
  margin-top: 10rpx;
  margin-bottom: 10rpx;
  height: 200rpx;
  background: yellowgreen;
  border-radius: 16rpx;
  display: flex;
  flex-direction: row;
  justify-content: space-between;
}
.box_right{
width: 50%;
display: flex;
flex-direction: column;
align-items: center; /**子view垂直居中*/
vertical-align: center; /**垂直居中*/
justify-content: center; /**內容居中*/
}
.box_righttop{
padding-top: 40rpx;
padding-left: 30rpx;
width: 100%;
height: 100rpx;
font-size:30rpx;
}
.box_rightlow{
width: 110%;
height: 100rpx;
padding-top: 00rpx;
padding-left: 40rpx;
}
.box_left{
width: 50%;
}
.box_img{
  margin-top:50rpx;
  margin-left: 20rpx;
  width: 120rpx;
  height: 120rpx;
}

.bg{
  width: 100%;
  height: 2400px;
}

3.簽到模塊
簽到模塊是小程序中最複雜的一個模塊,涉及的邏輯比較多。

  1. 用戶輸入簽到口令,系統驗證是否正確?若正確,調用簽到函數,用戶積分+1;錯誤,則提示用戶口令錯誤
  2. 簽到函數中需要判斷是否是新用戶?是否授權?
  3. 首先判斷用戶是否授權。若沒有授權,則顯示button,提示用戶進行授權。
  4. 再判斷是否是新用戶。如果是新用戶,則需要在數據庫中添加用戶記錄;反之,則只需要更加用戶的openid更新對應的積分即可
  5. 對於所涉及的所有操作,可以封裝在一個雲函數中。方便調用(雲函數數量好像最多20個)

簽到函數:

// 簽到
  signed(e){
    var k=this
    var openid=k.data.openid
    var name=k.data.name
    var img=k.data.img
    var time=k.data.time
   
    wx.showLoading({
      title: '簽到中...',
      mask: true,
    })

    // 防止老用戶 已經授權 但users記錄中沒有該用戶信息
    db.collection('users').where({
      _openid: openid // 填入當前用戶 openid
    }).count().then(res => {
      console.log(res.total)
      // 沒有該用戶
      if(res.total==0)
      {
        // 暱稱爲空 可能發生
        if(name.length==0)
        {
           wx.showToast({
             title: '簽到失敗,請重新簽到',
             icon:"none"
           })
        }
        else{
          db.collection('users').add({
            // data 字段表示需新增的 JSON 數據
            data: {
              user_openid: openid,
              user_name: name,
              user_img: img,
              time: time
            }
          })
            .then(res => {
              console.log("上傳用戶成功,下一步進行積分更新")
              wx.cloud.callFunction({
                // 要調用的雲函數名稱
                name: 'HHPro_functions',
                // 傳遞給雲函數的event參數
                data: {
                  function_name: "update_nums",
                  time: time,
                  openid: openid
                }
              }).then(res => {
                console.log("積分+1")
                k.onLoad()
              }).catch(err => {
              })
            })
            .catch(console.error)
        }
      }
      // 有該用戶 則更新積分 +1
      else{
        wx.cloud.callFunction({
          // 要調用的雲函數名稱
          name: 'HHPro_functions',
          // 傳遞給雲函數的event參數
          data: {
            function_name:"update_nums",
            time:time,
            openid: openid
          }
        }).then(res => {
         console.log("積分+1")
          k.onLoad()
        }).catch(err => {
        })
      }
    })
  },

4.下載模塊

  • 下載模塊相對來說就比較簡單了,本質就是在獲取數據庫中的下載鏈接,同時用戶減去相應的積分即可(注意判斷多種情況)
// 確定 用戶同意消耗1積分 得到下載鏈接
  hideModal_sure(e) {
    var k=this
    var openid=k.data.openid
    var num=k.data.num
    k.setData({
      modalName: null
    })
    wx.showLoading({
      title: '加載中...',
      mask: true
    })
    db.collection('users').where({
      _openid:openid // 填入當前用戶 openid
    }).get().then(res => {
      // 用戶存在 且 積分最少爲1的時候
      if (res.data[0].nums-num>=0)
      {
        // 調用雲函數 積分減一
        wx.cloud.callFunction({
          // 要調用的雲函數名稱
          name: 'HHPro_functions',
          // 傳遞給雲函數的event參數
          data: {
            function_name: "update_nums_dec",
            openid: openid,
            num:num
          }
        }).then(res => {
          console.log("積分-1")
          wx.hideLoading()
          // 顯示下載鏈接
          k.setData({
            modalName_x: "modal",
          })
        }).catch(err => {
        })
      }
      else{
        console.log("無法下載")
        wx.showToast({
          title: '下載失敗!!積分不足or未登錄',
          icon:"none"
        })
      }
    })
  },

5.調色板
在這裏插入圖片描述
wxml

<view class="x"></view>
<view class="card" wx:for="{{color_card}}" bindtap="choice_color" data-color="{{item}}" >
<view class="card_top" >
<view class="cardtop_item"  wx:for="{{item.colors}}"  style="background-color:{{item}}"></view>
</view>
<view class="card_bottom">
<view class="cardbottom_name">{{item.name}}</view>
<view class="cardbottom_img">
<image src="/images/tsb.png"></image>
</view>
</view>
</view>

CSS

page{
    background-image: url(https://wx3.sinaimg.cn/mw690/006cV2kkgy1gd2q32ifwcj30yi22owfv.jpg);
 background-attachment: fixed;
  background-repeat: no-repeat;
  background-size: cover;
}
.card{
  width: 80%;
  height: 450rpx;
  margin: 50rpx auto;
  background-color:white;
  border-radius: 10rpx;
}
.card_top{

width: 100%;
height: 85%;
padding-top: 20rpx;
padding-right: 20rpx;
padding-left: 20rpx;
padding-bottom: 5rpx;
border-radius: 10rpx;
display: flex;
flex-direction: row;
flex-wrap: wrap;
align-items: flex-start;
}
.cardtop_item{
  width: 20%;
  height: 25%;
}
.card_bottom{
width: 100%;
height: 15%;
display: flex;
flex-direction: row;
}
.cardbottom_name{
width: 85%;
height: 100%;
padding-left: 4%;
padding-top: 10rpx;
font-weight: 500;
font-size: 30rpx;
font-family:'Franklin Gothic Medium', 'Arial Narrow', Arial, sans-serif;
}
.cardbottom_img{
width: 10%;
height: 95%;
margin-bottom: 100px;
padding-top:10rpx;
}
.cardbottom_img image{
  width: 100%;
  height: 100%;
  padding-bottom: 5rpx;
}
.x{
  width: 100%;
  height: 200rpx;
}
.xx{
  width: 100%;
  height: 50rpx;
}

6.作品展示
在這裏插入圖片描述
7.百科答題
在這裏插入圖片描述
在這裏插入圖片描述
代碼(這個比較多 而且很多功能還沒有實現)

toggle(e) {
    var k=this
    k.scrollSteps()
    var time = k.data.nowtime
    var num=k.data.scroll//當前題數 第幾題
    console.log("這是第:"+num+"道題")
    var nums=k.data.titles_nums// 總的題目數量
    console.log("一共有"+nums+"道題")
    if(num==nums)
    {
      k.setData({
        score:k.data.score+1
      })
     console.log("答題完成,跳轉分享界面")
     k.toshare()//跳轉至分享界面
    }
    else{
    
      var key_1 = k.data.titles[k.data.scroll-1].key// 本題正確選項
      var key_2 = e.currentTarget.dataset.id// 選的第幾個選擇
      console.log("本題正確選項是"+key_1)
      var x = "am_" + e.currentTarget.dataset.id
      if (x == "am_1") {
        // 二者相等 則正確
        if (key_1 == key_2) {
          k.setData({
            am_1: "slide-bottom",
            score:k.data.score+1,
            color_1: "green",
            time:time,
            color:"black",
          })
          setTimeout(function () {
            k.setData({
              am_1: '',
              color_1:"",
            })
          }, 500)
        }
        // 錯誤
        else {
          console.log("答錯了,跳轉分享界面")
          k.toshare()//跳轉至分享界面
          k.setData({
            am_1: "shake",
            color_1: "red"
          })
          setTimeout(function () {
            k.setData({
              am_1: '',
              color_1: "",
            })
          }, 500)
        }

      }
      else if (x == "am_2") {
        // 二者相等 則正確
        if (key_1 == key_2) {
          k.setData({
            am_2: "slide-bottom",
            score: k.data.score + 1,
            color_2:"green",
            time: time,
            color: "black",
          })
          setTimeout(function () {
            k.setData({
              am_2: '',
              color_2:""
            })
          }, 500)
        }
        // 錯誤
        else {
          console.log("答錯了,跳轉分享界面")
          k.toshare()//跳轉至分享界面
          k.setData({
            am_2: "shake",
            color_2:"red"
          })
          setTimeout(function () {
            k.setData({
              am_2: '',
              color_2: ""
            })
          }, 500)
        }
      }
      else if (x == "am_3") {
        // 二者相等 則正確
        if (key_1 == key_2) {
          k.setData({
            am_3: "slide-bottom",
            score: k.data.score + 1,
            color_3:"green",
            time: time,
            color: "black",
          })
          setTimeout(function () {
            k.setData({
              am_3: '',
              color_3:""
            })
          }, 500)
        }
        // 錯誤
        else {
          console.log("答錯了,跳轉分享界面")
          k.toshare()//跳轉至分享界面
          k.setData({
            am_3: "shake",
            color_3:"red"
          })
          setTimeout(function () {
            k.setData({
              am_3: '',
              color_3: ""
            })
          }, 500)
        }
      }
      else {
        // 二者相等 則正確
        if (key_1 == key_2) {
          k.setData({
            am_4: "slide-bottom",
            score: k.data.score + 1,
            color_4:"green",
            time: time,
            color: "black",
          })
          setTimeout(function () {
            k.setData({
              am_4: '',
              color_4:""
            })
          }, 500)
        }
        // 錯誤
        else {
          console.log("答錯了,跳轉分享界面")
          k.toshare()//跳轉至分享界面
          k.setData({
            am_4: "shake",
            color_4:"red"
          })
          setTimeout(function () {
            k.setData({
              am_4: '',
              color_4: ""
            })
          }, 500)
        }
      }
    }
    
   
  },

8.分享海報
在這裏插入圖片描述

總結

        雖然用了三天時間,但是看到自己寫的小程序有那麼多人使用。自己也是很開心的O(∩_∩)O哈哈~ 自己的UI寫的不好,這裏就借用了大佬的框架,有一些功能也是看到大神的成果,自己再模仿的。小程序中的一些代碼有海轟自己寫的,也有一些是別人分享的,資料大部分來自於網絡和分享。
        有興趣的小夥伴可以體驗體驗海轟的小程序哦 【小程序名:海轟Pro】

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章