航天信息内容推送微信小程序

(2021.9.1 已终止)

一、主要内容及功能

  1. 推送航天信息内容
  2. 小程序前后台交互
  3. 播放视频
  4. 收藏及浏览历史

总体设计


二、效果及主要实现代码

  1. 浏览页
    浏览页
  • 点击过渡动画
    过渡动画
  • 详情页
    • 收藏文章
      历史
      收藏
      说明:如果未点击收藏则仅为历史记录(key前加0标记)。

    • 点赞
      点赞
      数据库

  • 浏览页代码
    • wxml
    <!--pages/viewer/index.wxml-->
    <!-- 加载界面 -->
    <view class="loading" hidden="{{isLoaded}}">
        <image src="/imgs/satellite.png" width="widthFix"></image>
        <view class="slogan">我们的征程是星辰大海</view>
    </view>
    <view>
      <!-- 轮播图 -->
      <view>
        <swiper indicator-dots circular autoplay indicator-active-color="#666ccc" interval='4000' duration='500'>
          <swiper-item wx:for="{{swiperPic}}" wx:key='id'>
            <image mode="widthFix" src="{{url}}{{item}}"></image>
          </swiper-item>
        </swiper>
      </view>
      <!-- 列表 -->
      <view class="list">
        <view hover-class="click" wx:for='{{list}}' wx:key='id' bindtap="gotoDetails" data-val='{{item}}'>
          <view class="listItem">
            <text>{{item.tit}}</text>
          </view>
          <view class='plus'>{{item.type}} {{item.date}}</view>
        </view>
      </view>
    </view>
    
    • js
      // pages/viewer/index.js
      const app = getApp();
      Page({
        /**
         * 页面的初始数据
         */
        data: {
          url: app.globalData.url
        },
      
        /**
         * 生命周期函数--监听页面加载
         */
        onLoad: function (options) {
          var url = this.data.url;
          // 列表
          wx:wx.request({
            url: url+'list.php',
            complete: (res) => {
              this.setData({list: res.data})
              // console.log(res.data)
            }
          })
          // 轮播图
          wx:wx.request({
            url: url+'swiper.php',
            complete: (res) => {
              this.setData({swiperPic: res.data.swiper})
              // console.log(this.data.swiperPic)
            }
          })
        },
        // 前往详情页
        gotoDetails: function(choice) {
          this.setData({isLoaded: false})
          // 传递数组
          wx.navigateTo({
            url: '/pages/details/details?obj='+JSON.stringify(choice.currentTarget.dataset.val)
          })
          // console.log(choice.currentTarget.dataset.val)
        },
        /**
         * 生命周期函数--监听页面显示   从details界面返回时,需重置加载
         */
        onShow: function () {
          this.setData({isLoaded: true})
          var url = this.data.url;
          // 列表
          wx:wx.request({
            url: url+'list.php',
            complete: (res) => {
              this.setData({list: res.data})
              // console.log(res.data)
            }
          })
        }
      })
      
  • 详情页主要代码
    • wxml
    <!--pages/details/details.wxml-->
    <view class="contain">
      <!-- 第二个容器 -->
      <view class="contain2">
      <!-- 标题 -->
        <view class='tit'>{{item.tit}}</view>
        <!-- 判断是否有图片 -->
        <view wx:if="{{item.pic}}">
          <view class='source'>来源:国家航天局</view>
          <image src="{{url}}{{item.pic}}" mode="widthFix"></image>    
        </view>
        <!-- 判断是否有视频 -->
        <view wx:elif="{{item.video}}">
          <view class='source'>来源:央视网</view>
          <video id="Video" src="{{url}}{{item.video}}" controls></video>
        </view>
        <!-- 文字内容 -->
        <view class="content">{{item.content}}</view>
        <!-- 日期 -->
        <view class='data'>时间:{{item.date}}</view>    
      </view>
      <!-- 底部点赞 和 收藏样式 -->
      <view class="bottom">
        <block>
          <button hover-class="none" wx:if='{{collected}}' bindtap="cancelFavorites" style="width:150rpx;height:140rpx;right:100rpx;"><image src="/imgs/collection2.png" ></image>收藏</button>
          <button hover-class="none" wx:else bindtap="addFavorites" style="width:150rpx;height:140rpx;right:100rpx;"><image src="/imgs/collection1.png"></image>收藏</button>    
        </block>
        <block>
          <button hover-class="none" style="width:150rpx;height:150rpx;right:0rpx;" bindtap="liker">
            <image wx:if="{{liked}}" src="/imgs/like1.png"></image>
            <image wx:else src="/imgs/like.png"></image>{{liker}}</button>
        </block>
      </view>
    </view>
    
    • js
    // pages/details/details.js
    const app = getApp();
    Page({
      /**
       * 页面的初始数据
       */
      data: {
        url: app.globalData.url,
        collected: false,
        liked: false
      },
      // 添加收藏,重置浏览历史记录(去0)
      addFavorites: function() {
        wx.removeStorageSync("0"+this.data.item.tit)
        wx.setStorageSync(this.data.item.tit, this.data.item)
        this.setData({collected: true})
      },
      // 取消收藏,重置浏览历史记录(加0)
      cancelFavorites: function() {
        wx.setStorageSync("0"+this.data.item.tit, this.data.item)
        wx.removeStorageSync(this.data.item.tit)
        this.setData({collected: false})
      },
      /**
       * 生命周期函数--监听页面加载
       */
      onLoad: function (options) {
        var obj = JSON.parse(options.obj)
        // console.log(obj)
        this.setData({item: obj})
        var article = wx.getStorageSync(obj.tit)
        if (article != "") {
          this.setData({
            collected: true
          })
        } else {
          // 浏览历史
          wx.setStorageSync("0"+this.data.item.tit, this.data.item)      
        }
    
        var liker = this.data.item.liker
        this.setData({liker: liker})
      },
      // 点赞功能
      liker:function() {
        var liker = Number(this.data.liker) + 1
        wx:wx.request({
          url: this.data.url+'liker.php?get='+this.data.item.tit,
          complete: (res) => {
            this.setData({
              liked: true,
              liker: liker+""
            })
          }
        })
      }
    })
    
    • wxss
    /* pages/details/details.wxss */
    .contain, .bottom {
      width: 100%;
    }
    .contain2 {
      margin: 20rpx;
    }
    image, video {
      width: 100%;
    }
    .tit {
      text-align: center;
      margin: 40rpx;
      font-size: 50rpx;
    }
    .content {
      text-indent: 2em;
    }
    .data {
      text-align: right;
      margin-top: 20rpx;
    }
    .source {
      text-align: center;
      color: #aeaeae;
    }
    .bottom {
      /* display: flex;
      flex-direction: row; */
      width: 100%;
      margin-top: 40rpx;
    }
    .bottom image {
      width: 50rpx;
      height: 50rpx;
    }
    button {
      background: none;
      position: absolute;
    }
    
  1. 个人页
  • 流星动画效果
    动画效果

  • 登录
    在这里插入图片描述

  • 足迹(浏览历史页)
    浏览历史

  • 收藏页
    收藏记录

  • 个人页主要代码

    • wxml
    <!--pages/user/index.wxml-->
    <!-- 加载界面 -->
    <view class="loading" hidden="{{isLoaded}}">
        <image src="/imgs/satellite.png" width="widthFix"></image>
        <view class="slogan">我们的征程是星辰大海</view>
    </view>
    <!-- 顶部样式:点击头像登录,显示头像和昵称 -->
    <view>
      <!-- 流星动画效果 -->
      <view class="star"><image src="/imgs/star.png"></image></view>
      <view class="topBarBackground"></view>
      <view class="topBar">
        <button class="btn" open-type='getUserInfo' bindgetuserinfo='getInfo' style="width:200rpx;height:200rpx" disabled="{{isLogin}}">
          <image src="{{avatar}}" mode="widthFix" class="avatar" style="border-radius:{{avatar_radius}}"></image> 
        </button>
        <text>{{nickName}}</text>
      </view>
      <!-- 登录后导航栏 及 退出键 -->
      <view wx:if="{{isLogin}}" class="navContain">
          <!-- 中部导航栏 -->
          <view class="midNav">
            <view hover-class="click">
              <image src="/imgs/num.png" mode="widthFix"></image>
              <text>我的行星编号: {{planet.name}}</text>        
            </view>
            <view hover-class="click" bindtap="planetInfo" data-val="{{num}}">
              <image src="/imgs/log.png" mode="widthFix"></image>
              <text>行星信息</text>        
            </view>
          </view>
          <!-- 底部导航栏 -->
          <view class="bottomNav">
            <navigator wx:for="{{botNav}}" url="{{item.path}}" wx:key='id' bindtap="introduction">
              <image src="{{item.img}}"></image>
              <text>{{item.name}}</text>
            </navigator>
          </view>
      </view>
    </view>
    
    • js
    // pages/user/index.js
    var util = require("../../utils/util.js");
    Page({
      /**
       * 页面的初始数据
       */
      data: {
        avatar: '/imgs/avatar.png',
        nickName: '点击头像登录',
        avatar_radius: '0%',
        isLogin: false,
        botNav: [
          {
            path: "/pages/list/list?type=0",
            img: "/imgs/history.png",
            name: "足迹",
          },
          {
            path: "/pages/list/list?type=1",
            img: "/imgs/collection.png",
            name: "收藏",
          },
          {
            path: "/pages/introduction/introduction",
            img: "/imgs/about.png",
            name: "关于",
          }
        ],
        planet: []
      },
      /**
       * 获取用户信息 及 生成行星编号
       */
      getInfo: function(e) {
        let info = e.detail.userInfo;
        this.setData({
          nickName: "你好," + info.nickName,
          avatar: info.avatarUrl,
          avatar_radius: '100%',
          isLogin: true,
          planet: util.getPlanetInfo()
        })
        // console.log(info)
        // console.log(this.data.planet)
      },
      /**
       * 点击 “关于”导航栏 跳转介绍界面
       */
      introduction: function() {
        this.setData({isLoaded:false})
      },
      /**
       * 行星信息弹窗
       */
      planetInfo: function() {
        var planet = this.data.planet;
        // console.log(planet)
        wx.showModal({
          title: planet.name,
          content: "Discovered in: "+planet.discovered+"\nMass: "+planet.mass+"\nOrbital Period: "+planet.OrbitalPeriod+"\n Radius: "+planet.Radius,
          showCancel: false
        })
      },
      /**
       * 生命周期函数--监听页面显示 从introduction界面返回时,需重置加载
       */
      onShow: function () {
        this.setData({isLoaded: true})
      }
    })
    
    • wxss
    /* pages/user/index.wxss */
    .topBar, .midNav, .midNav view, navigator{
      display: flex;
      align-items: center;
    }
    /* 高斯模糊 */
    .topBarBackground {
      background: linear-gradient(#003472,#0388f6,#fff);
      position: absolute;
      width: 100%;
      height: 500rpx;
      left: 0;
      top: 0;
      z-index: -2;
      filter: blur(15rpx);
      transform: scale(1.2);
    }
    /* 顶部样式 */
    .topBar {
      height: 500rpx;
      width: 100%;
      flex-direction: column;
      justify-content: center;
      color: #fff;
      font-weight: 800;
      font-size: large;
    }
    /* 头像 */
    .avatar {
      width: 100%;
      height: 100%;
    }
    /* 登录按键 */
    .btn {
      background: none;
      padding: 10rpx;
      border-radius: 50%;
    }
    .btn:active {
      background: #eee;
    }
    /* 流星动画 */
    .star {
      z-index: -1;
      width: 50rpx;
      height: 50rpx;
      margin-top: 25rpx;
      position: absolute;
      animation: y 6s infinite ease-in-out;
    }
    .star image {
      z-index: 2;
      width: 50rpx;
      height: 50rpx;
      animation: x 6s infinite ease-in-out;
    }
    @keyframes y {
      to{transform: translateY(90rpx);}  
    }
    @keyframes x {
      0% {opacity: 0;}
      60% {opacity: 1;}
      100% {opacity: 0;}
      to {transform: translateX(500rpx);}
    }
    /* 中部导航栏 */
    .midNav, .midNav view {
      border-radius: 10rpx;
    }
    .midNav {
      background: #fff;
      height: 140rpx;
      box-shadow: 0px 3px 10px 1px #e7e7e7;
      margin-top: -80rpx;
      justify-content: space-around;
    }
    .midNav view {
      width: 50%;
      padding: 5%;
      height: 50%;
    }
    .midNav image {
      width: 70rpx;
      height: 70rpx;
    }
    .midNav text {
      margin-left: 10rpx;
    }
    /* 底部导航栏 */
    .midNav, .bottomNav {
      width: 90%;
      margin-left: 5%;
      margin-right: 5%;
    }
    .bottomNav {
      margin-top: 50rpx;
      box-shadow: 0px 3px 10px 1px #e7e7e7;
    }
    navigator {
      line-height: 60rpx;
      background: #fff;
      border-bottom: 1px solid #eee;
      padding: 15rpx;
    }
    navigator image {
      width: 50rpx;
      height: 50rpx;
      margin-right: 30rpx;
    }
    
  • 收藏及足迹页主要代码

    • wxml
    <!--pages/list/list.wxml-->
    <!-- 加载界面 -->
    <view class="loading" hidden="{{isLoaded}}">
        <image src="/imgs/satellite.png" width="widthFix"></image>
        <view class="slogan">我们的征程是星辰大海</view>
    </view>
    
    <view class="list">
      <view hover-class="click" wx:for='{{list}}' wx:key='id' bindtap="gotoDetails" data-val='{{item}}'>
        <view class="listItem">
          <text>{{item.tit}}</text>
        </view>
        <view class='plus'>{{item.type}} {{item.date}}</view>
      </view>
    </view>
    
    • js
    // pages/list/list.js
    Page({
      /**
       * 页面的初始数据
       */
      data: {
        type: "0"
      },
      /**
       * 生命周期函数--监听页面加载
       */
      onLoad: function (options) {
        var type = options.type
        this.showList(type)
      },
      onShow: function(options) {
        var type = options.type
        this.showList(type)
      },
      // 生成列表
      showList: function(type) {
        let barTit = "浏览历史"
        // 获取模式
        this.setData({type: type})
        let info = wx.getStorageInfoSync()
        let keys = info.keys
        let list = []
        if (type == 1) {
          barTit = "我的收藏"
        }
        // 获取收藏
        for (var i = 1; i < keys.length; i++) {
          let obj = wx.getStorageSync(keys[i])
          // 略过属于收藏的浏览历史
          if (type == 1 && keys[i].substring(0,1) == "0") { continue; }
          list.push(obj)
        }
        this.setData({list: list})
        //设置标题栏
        wx.setNavigationBarTitle({
          title: barTit
        });
      },
      // 前往详情页
      gotoDetails: function(choice) {
        this.setData({isLoaded: false})
        // 传递数组
        wx.navigateTo({
          url: '/pages/details/details?obj='+JSON.stringify(choice.currentTarget.dataset.val)
        })
        // console.log(choice.currentTarget.dataset.val)
      },
      /**
       * 生命周期函数--监听页面显示
       */
      onShow: function () {
        this.setData({isLoaded: true})
      }
    })
    

三、全局设置

  • app.wxss
/**app.wxss**/
page { 
  background-color: #f4f4f4;
}
.container {
  height: 100%;
} 
/* 轮播图 */
swiper, swiper image {
  height: 400rpx;
  width: 100%;
}
/* 模块点击效果: 背景灰度 */
.click {
  background: #eee;
}
/* 加载效果 */
.loading {
  display: flex;
  justify-content: center;
  align-items: center;
  z-index: 2;
  width: 100%;
  height: 100vh;
  flex-direction: column;
}
.loading image {
  width: 50rpx;
  height: 50rpx;
  animation: rotate 2s linear infinite;
  margin-bottom: 50rpx;
}
@keyframes rotate {
  from {transform: rotate(0deg)} to {transform: rotate(360deg)}
}
/* 字体样式 */
.slogan, .nav, .tit, .list {
  font-family: "华文新魏";
}
/* 列表 */
.list {
  margin: 20rpx;
  background: #fff;
  box-shadow: 0px 3px 10px 1px #e7e7e7;
}
.listItem {
  height: 50rpx;
  padding: 10rpx;
  display: flex;
  align-items: center;
}
/* 列表中备注类型和日期样式 */
.plus {
  height: 20rpx;
  width: 100%;
  color: #aeaeae;
  border-bottom: 1px solid #eee;
  text-align: right;
  font-size: 20rpx;
}
  • app.json
{
  "pages":[
    "pages/index/index",
    "pages/viewer/index",
    "pages/user/index",
    "pages/introduction/introduction",
    "pages/details/details",
    "pages/list/list",
    "pages/logs/logs"
  ],
  "window":{
    "backgroundTextStyle":"light",
    "navigationBarBackgroundColor": "#003472",
    "navigationBarTitleText": "观星者",
    "navigationBarTextStyle":"white"
  },
  "tabBar": {
    "list": [{
      "pagePath": "pages/index/index",
      "text": "主页",
      "iconPath": "/imgs/home1.png",
      "selectedIconPath": "/imgs/home2.png"
    },{
      "pagePath": "pages/viewer/index",
      "text": "浏览",
      "iconPath": "imgs/viewer1.png",
      "selectedIconPath": "/imgs/viewer2.png"
    },{
      "pagePath": "pages/user/index",
      "text": "我的",
      "iconPath": "imgs/user1.png",
      "selectedIconPath": "imgs/user2.png"
    }]
  },
  "style": "v2",
  "sitemapLocation": "sitemap.json"
}

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

    // 登录
    wx.login({
      success: res => {
        // 发送 res.code 到后台换取 openId, sessionKey, unionId
      }
    })
    // 获取用户信息
    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,
    // 服务端后台地址
    url: "",
    arcticl: ""
  }
})
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值