這是其餘幾篇的地址:
記《高校考勤系統》小程序(1)
記《高校考勤系統》小程序(2)
記《高校考勤系統》小程序(3)
html
- 校園通知這裏主要分爲兩塊:
1.管理員信息發佈,頂部公告的設置.(主要涉及圖片的上傳,數據的增長)
2.用戶查看.(主要涉及上拉加載,下拉刷新,點擊查看詳細信息)
- 這裏的話須要用到上傳圖片這個功能,上傳功能案例咱們也能夠在新建一個項目中查看到,這裏也有詳細的代碼.
(1)頂部標題,咱們能夠在.json文件中加入 navigationBarTitleText 這個屬性.前端
{
"navigationBarTitleText": "校園消息編輯",
"usingComponents": {}
}
複製代碼
(2)頁面佈局搭建,校園通知須要有標題,內容,發佈人,以及封面圖片,固然你也能夠根據你的需求添加或刪除.git
page{
width: 100%;
height: 100%;
}
.title, .cont {
display: flex;
justify-content: start;
background-color: white;
border-bottom: 1px solid #f6f6f6;
}
.tit_tit, .cont_tit, .upphoto_tit {
margin-left: 20rpx;
margin-right: 30rpx;
line-height: 100rpx;
}
.tit_input {
width: 500rpx;
height: 60rpx;
line-height: 60rpx;
padding: 20rpx;
}
.cont_cont {
margin-top: 14rpx;
padding: 20rpx;
}
.upphoto {
background-color: white;
padding-bottom: 30rpx;
}
.photo {
width: 200rpx;
height: 200rpx;
}
.photo_box {
width: 200rpx;
height: 200rpx;
border: 3rpx dashed;
margin-left: 20rpx;
overflow: hidden;
}
.up {
width: 200rpx;
height: 200rpx;
}
.btn {
width: 300rpx;
margin-top: 100rpx;
background-color: #07c160;
color: white;
}
複製代碼
<view class="title">
<text class="tit_tit">標題</text>
<input class="tit_input" placeholder="請輸入標題" bindinput="bindKeyInput"></input>
</view>
<view class="cont">
<text class="cont_tit">內容</text>
<textarea class="cont_cont" placeholder="請輸入內容" bindinput="bindKeyInput2" maxlength="-1"></textarea>
</view>
<view class="title">
<text class="tit_tit">發佈人</text>
<input class="tit_input" placeholder="請輸入發佈人" bindinput="bindKeyInput3"></input>
</view>
<view class="upphoto">
<text class="upphoto_tit">封面圖片</text>
<!-- 上傳圖片 -->
<view class="photo">
<view class="photo_box" bindtap="doUpload">
<image class="up" hidden="{{ upview }}" src="../../images/up.png"></image>
<image class="up" hidden="{{ upview2 }}" src="{{ filePath }}"></image>
</view>
</view>
</view>
<button class="btn" bindtap="btn">肯定</button>
複製代碼
(3)功能實現,js編寫.
github
- 首先咱們須要將 input 框中輸入的值存儲到 data 中
data: {
filePath: '', //圖片路勁
title: '', //標題
article: '', // 內容
user: '', //發佈人
},
bindKeyInput(e) { //標題輸入
this.title = e.detail.value
console.log(this.title)
},
bindKeyInput2(e) { //內容輸入
this.article = e.detail.value
},
bindKeyInput3(e) { //發佈人輸入
this.user = e.detail.value
},
複製代碼
- 而後是上傳圖片功能的實現.詳細的步驟寫在註釋中
// 上傳圖片
doUpload: function() {
let timestamp = (new Date()).valueOf(); //1.建立時間戳,方便後面文件命名
wx.chooseImage({
count: 1, //2.一次選擇的圖片數量,這裏限制一張,最多九張
sizeType: ['compressed'],
sourceType: ['album', 'camera'], //3.圖片來源選擇,分爲兩個1相冊選擇(album),2相機拍攝(camera)
success: (res) => {
wx.showLoading({ //4.添加提示框,提高視覺效果
title: '上傳中',
})
const filePath = res.tempFilePaths[0] //當前存儲圖片地址
const cloudPath = timestamp + '.png' //5.用時間戳命名圖片名稱
wx.cloud.uploadFile({ //將圖片上傳至雲存儲空間
cloudPath,// 指定上傳到的雲路徑
filePath,// 指定要上傳的文件的小程序臨時文件路徑
success: res => {
this.filePath = res.fileID //5.成功後回調,res.fileID就是咱們在雲存儲中的路徑,能夠直接用這個路徑來獲取圖片並顯示
this.setData({ //圖片上傳顯示,這裏由於原來有圖片,因此當上傳圖片成功後隱藏原來圖片,顯示用戶上傳的圖片
upview: true,
filePath: this.filePath,
upview2: false
})
app.globalData.fileID = res.fileID
app.globalData.cloudPath = cloudPath
app.globalData.imagePath = filePath
},
fail: e => {
wx.showToast({
icon: 'none',
title: '上傳失敗',
})
},
complete: () => {
wx.hideLoading()//完成後隱藏提示框
}
})
},
fail: e => {
console.error(e)
}
})
},
複製代碼
到這裏圖片上傳功能就作好啦,是否是並無想象中的複雜😄數據庫
(4)提交數據到數據庫中.
json
- 首先咱們肯定存入數據庫中單條數據的json格式
{
"_id": "00a6cea35dca27980575500975c25248",
"_openid": "oQnNa5NJfKqSZntKFLGZWnZuXNbo",
"title": "標題",
"article": "文章內容",
"user": "發佈人",
"filePath": "圖片上傳成功後的雲路徑",
"timestamp": "發佈時間"
}
複製代碼
btn(e) {
this.timestamp = (new Date()).valueOf(); //獲取時間戳
var date = new Date(this.timestamp); //這裏是想作一個發佈時間存儲
var Y = date.getFullYear() + '-';
var M = (date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1) + '-';
var D = date.getDate() + ' ';
var h = date.getHours() + ':';
var m = date.getMinutes() + ':';
var s = date.getSeconds();
this.timestamp = Y + M + D + h + m + s; //時間拼接 0000-00-00 00:00:00 格式
const db = wx.cloud.database({ //數據庫新增用戶註冊信息
env: '***'
})
db.collection('***').add({ //向指定集合添加數據
data: {
title: this.title,
article: this.article,
user: this.user,
filePath: this.filePath,
timestamp: this.timestamp
},
success: res => {
wx.showToast({
icon: 'success',
title: '發佈成功',
})
}
})
},
複製代碼
- 這裏主要注意的地方仍是以前提到過的雲開發中的限制,也就是每次獲取數據上限是 20條 ,固然你能夠搭配雲函數來提升每次獲取到的數據條數,不過也不建議每次獲取過多數據,大量的數據會使加載變慢,下降性能.
- 那麼這裏我是沒有使用雲函數的,最多展現20條數據,若是想要展現更多,後面有功能會講到如何使用雲函數開發.
首先仍是頁面的佈局,這裏樣式用了 colorUI 中的邊框陰影.初始咱們只取前6條數據.小程序
page {
width: 100%;
position: relative;
}
.cont_box {
width: 90%;
height: 160rpx;
background-color: white;
padding: 20rpx;
margin: 0 auto;
margin-top: 20rpx;
margin-bottom: 10rpx;
border-radius: 16rpx;
display: flex;
justify-content: space-between;
box-shadow: 0 0 10rpx rgba(0, 0, 0, 0.1);
position: relative;
}
.cont_box::before, .cont_box::after {
position: absolute;
content: "";
top: 20rpx;
bottom: 30rpx;
left: 20rpx;
width: 50%;
box-shadow: 0 30rpx 20rpx rgba(0, 0, 0, 0.2);
transform: rotate(-3deg);
z-index: -1;
}
.cont_box::after {
right: 20rpx;
left: auto;
transform: rotate(3deg);
}
.cont_left {
width: 75%;
height: 100%;
position: relative;
}
.cont_tit {
font-size: 28rpx;
}
.cont_time {
position: absolute;
right: 30rpx;
bottom: 20rpx;
font-size: 24rpx;
}
.cont_img {
width: 160rpx;
height: 160rpx;
}
.bottom {
width: 100%;
text-align: center;
font-size: 24rpx;
color: #ddd;
display: inline-block;
padding: 30rpx 0;
}
.bottom text {
margin-left: 20rpx;
margin-right: 20rpx;
color: #9b9b9b;
}
複製代碼
<view class="cont_box" hidden="{{cont_box}}" wx:for="{{ campusNews }}" wx:key="{{index}}" data-index="{{ index }}" bindtap="contBtn">
<view class="cont_left">
<view class="cont_tit">{{ item.title }}</view>
<text class="cont_time">{{ item.timestamp }}</text>
</view>
<image class="cont_img" src="{{ item.filePath }}"></image>
</view>
<view class="bottom" hidden="{{bottom}}">
————
<text>我是有底線的</text> ————
</view>
複製代碼
const db = wx.cloud.database({
env: '***'
})
db.collection('***').get().then(res => {
this.campusNews = res.data.reverse()//逆序排序,讓新添加的數據排在最前面,將數據存儲在data中,方便處理
for(let i = 0; i < 6 ; i++){
this.data.arr.push(this.campusNews[i]) //每次取前6條數據,添加到新數組中進行渲染
}
})
複製代碼
通知詳情查看:數組
- 在上面,咱們已經獲取校園通知的數據,怎麼查看相對應的數據呢 ?也是經過獲取點擊數據的下標來判斷
- 咱們在 for 循環中添加 data-index="{{ index }}" 就能夠賦值下標,如上代碼已經寫出👆👆
- 這裏我是經過下標來獲取數據,在經過url傳參來傳遞數據(由於數據相對較少)
contBtn(e) {
var id = e.currentTarget.dataset.index //獲取當前點擊下標
wx.navigateTo({
url: "/pages/newsPage/newsPage?title=" + this.campusNews[id].title + "&&article=" + this.campusNews[id].article
})
},
複製代碼
跳轉頁面後,咱們在跳轉頁面 .js 的 onLoad() 中就能夠獲取到數據,最後渲染就ok了. 由於樣式都是統一的,因此只用一張頁面就能夠了,只是每次跳轉url攜帶的參數不一樣罷了微信
onLoad: function (options) {
console.log(options)
},
複製代碼
例如我點擊效果圖中第一條信息,跳轉頁面得到的數據以下:網絡
下拉刷新:首先須要在 .json 中開啓這個功能,還有其餘能夠修改的屬性能夠查看 官方文檔
- 下拉刷新的原理其實和頁面加載時獲取數據的原理差很少,固然你也也能夠在下拉函數中直接 this.onLoad() ,即下拉時再次執行 onLoad() 函數,成功獲取數據後隱藏加載框就行.
onPullDownRefresh: function() {
var arr = [] //聲明一個空數組
wx.showNavigationBarLoading(); //顯示導航欄加載框
const db = wx.cloud.database({
env: '****'
})
//獲取校園消息數據
db.collection('***').get().then(res => {
this.campusNews = res.data.reverse()
for (let i = 0; i < 6; i++) {
arr.push(this.campusNews[i]) //每次渲染6條數據
}
this.setData({
campusNews: arr //前端渲染
})
}).then(res => { //等上一步數據獲取成功,執行下面
wx.hideNavigationBarLoading();// 隱藏導航欄加載框
wx.stopPullDownRefresh();// 中止下拉動做
})
},
複製代碼
上拉加載:
data: {
campusNews: [],
num: 1,//一次獲取的數據
arr:[]
},
onReachBottom: function() {
wx.showLoading({
title: '加載中',
});
this.data.arr = [] //重置清空數組,由於加載頁面中數組中已有數據
this.data.num ++ //上拉一次num加1
setTimeout(res=>{ //延時觸發判斷
if (this.campusNews.length - 6 * this.data.num > 0) { //判斷 數組長度 - 6*下拉次數是否大於0,如上大於0則輸出6*下拉次數條數據
for (let i = 0; i < 6 * this.data.num; i++) {
this.data.arr.push(this.campusNews[i])
}
this.setData({
campusNews: this.data.arr
})
wx.hideLoading();
} else if (this.data.campusNews.length - 6 * this.data.num <= 0) { // 小於等於0,則所有輸出
this.setData({
bottom: false,
campusNews: this.campusNews
})
wx.hideLoading();
}
},1000)
},
複製代碼
- 這張頁面主要功能就是對已經發布的通知進行管理,能夠進行查看、修改及刪除. 效果圖以下:
- 在此以前該頁面的增刪改查功能以及所有講過了,這裏就講講大體流程,具體實現方法能夠查看以前的文章😊
1.首先是從頁面結構的搭建,在從數據庫中獲取數據,渲染到頁面.
2.編輯功能其實和課程表中的編輯一致,獲取當前點擊的數據,賦值到 input 中的 value 中.
3.修改功能須要用到雲函數,也是由於雲開發權限不足,沒法修改別人上傳的數據.
(這裏不足的是尚未作分頁功能,因此只能查看前20條數據,後續會考慮增長分頁)
若是這裏有疑問的能夠留言或私信,一塊兒交流😀
- 由於要作普通用戶和管理員的區分,因此我在這裏加了管理員按鈕方便操做
這裏就用到了以前講的在頁面加載時,判斷數據庫中用戶的操做權限,userstatus 爲 '0' 是普通用戶,按鈕隱藏;爲 '3' 是管理員,按鈕顯示.
page {
width: 100%;
height: 100%;
position: relative;
}
.lodingBox {
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
}
.loding {
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
}
.cont {
width: 100%;
height: 100%;
}
.top {
width: 100%;
height: 520rpx;
position: relative;
}
.top_bg {
width: 100%;
height: 380rpx;
}
.avatarUrl {
width: 160rpx;
height: 160rpx;
border-radius: 80rpx;
background-size: 100% 100%;
position: absolute;
left: calc(50% - 80rpx);
bottom: 80rpx;
box-shadow: 4rpx 4rpx 8rpx rgba(26, 26, 26, 0.4);
z-index: 99;
}
.nickName {
margin-top: 74rpx;
text-align: center;
}
.adminBtn{
margin-top: 20rpx;
}
.kfBtn {
width: 100%;
height: 44px;
position: relative;
}
.kfBtn .kf{
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
}
.water{
width: 100%;
position: absolute;
margin: 0;
bottom: 134rpx;
}
.bg-gradual-green {
background-image: none;
color: var(--white);
}
.gif-black{
mix-blend-mode: screen;
}
複製代碼
<view class="cont" hidden="{{cont}}">
<view class="top">
<image class="top_bg" src="../../images/users.png"></image>
<image class="avatarUrl" src="{{ avatarUrl }}"></image>
<view class="nickName">{{ nickName }}</view>
<view class="water">
<view class="margin radius bg-gradual-green shadow-blur">
<image src="https://user-gold-cdn.xitu.io/2019/11/29/16eb67bab5042a77?w=540&h=100&f=gif&s=978506" mode="scaleToFill" class="gif-black response" style="height:100rpx"></image>
</view>
</view>
</view>
<van-cell title="受權管理" icon="https://pic.yupoo.com/1145338926/445b711b/7cde2620.png" bindtap="openSetting" is-link />
<view class="kfBtn">
<van-cell title="在線聯繫" icon="https://pic.yupoo.com/1145338926/d5dd143f/4ef73555.png" bindtap="" is-link />
<button class="kf" open-type="contact"></button>
</view>
<van-cell title="項目日誌" icon="https://pic.yupoo.com/1145338926/3e003634/e4313e02.png" bindtap="timeline" is-link />
<view hidden="{{ adminBtn }}" class="adminBtn">
<van-cell title="管理員" icon="https://pic.yupoo.com/1145338926/cae3dee7/0573c27b.png" is-link bindtap="openAdmin" />
</view>
</view>
複製代碼
const app = getApp()
Page({
data: {
avatarUrl: '',
nickName: '',
userInfo: {},
open_id: '', //用戶id
adminStatus: '', // 用戶狀態
adminBtn: '' //是否顯示管理員按鈕
},
openSetting() {
wx.openSetting()
},
openAdmin() {
wx.navigateTo({ //跳轉管理員界面
url: "/pages/adminChoose/adminChoose"
})
},
timeline(){
wx.navigateTo({ //跳轉管理員界面
url: "/pages/timeline/timeline"
})
},
onLoad: function(options) {
this.setData({
adminBtn: true,
cont:true,
loding:false
})
setTimeout(res => {
wx.stopPullDownRefresh(); //結束下拉刷新動畫
if (this.adminStatus == '3') { //判斷用戶權限狀態
this.setData({
adminBtn: false,
loding: true ,
cont: false,
})
} else {
this.setData({
adminBtn: true,
loding: true,
cont: false,
})
}
},1300)
wx.cloud.callFunction({
name: 'login',
data: {},
success: res => {
this.open_id = res.result.openid
const db = wx.cloud.database({ //數據庫查詢用戶信息
env: 'env-urae8'
})
db.collection('users').where({ //數據庫查詢用戶權限信息
_openid: this.open_id
}).get({
success: res => {
this.adminStatus = res.data[0].userStatus
}
})
},
fail: err => {
wx.showToast({
icon: 'none',
title: '用戶信息獲取失敗,請檢查網絡',
})
})
// 獲取用戶信息
wx.getSetting({
success: res => {
if (res.authSetting['scope.userInfo']) {
// 已經受權,能夠直接調用 getUserInfo 獲取頭像暱稱,不會彈框
wx.getUserInfo({
success: res => {
this.setData({
avatarUrl: res.userInfo.avatarUrl,
nickName: res.userInfo.nickName,
userInfo: res.userInfo
})
}
})
}
}
})
}
)}
複製代碼
- 在線聯繫功能:
1.在微信公衆平臺,客服中添加須要綁定的客服微信號.
2.在 button 組件中設置 open-type='contact' 便可打開客服消息.
3.而後在手機上搜索 ‘客服小助手’ ,綁定的的小程序就能夠實如今線客服功能 .
這樣就綁定好了客服😊