如今微信公衆號留言功能不開通真的很麻煩,與讀者之間缺乏了不少的互動,因此小鹿就花費了一個月的時間,作了一款留言小程序,嵌入到公衆號文章底部,點擊進入用戶便可進行留言,和原有的留言功能相同。javascript
效果圖: 前端
不少小夥伴加我微信問我關於這個小程序的問題,我在這裏也統一說一下。若是隻想單單的給公衆號加一個留言功能,我建議不必本身去作了,由於不少熱你都沒有編程基礎,要想作出來,必須從基礎開始看,這個過程很是考驗你的學習能力的。由於個人《小鹿留言助手》已經發布,能夠關聯多個公衆號,前提是粉絲量大於 1000 能夠關聯哦!由於服務器費用都是小鹿本身掏腰包,我仍是個學生,沒什麼收入來源,小程序也是免費關聯的,因此粉絲很少的前期留言不怎麼重要,仍是好好作內容吧。java
另外一方面就是,若是你想用小程序留言來學習小程序,能夠親自動手根據小鹿提供的源碼本身寫一個,說實話,我是從零開始學習小程序的,包括後臺的代碼都是自學的,由於如今所在的大學是三流大學,只能靠本身去學習研究,服務器、數據庫須要本身配置。因此說,若是可以本身作出來,我相信你會在編程技術上會有很大的收穫的。mysql
※ 體驗留言小程序,可在微信小程序頁面便可搜索:小鹿留言助手sql
下面是留言小程序的主要目錄結構,目錄中的具體結構和代碼以及對應的頁面示意圖會在下方詳細標記。數據庫
images:
此目錄下爲小程序中所用到的圖片文件。編程
artical:
用戶文章列表頁面。index:
主頁面。lookmessage:
留言篩選、回覆、刪除頁面。message:
留言顯示頁面。myartical:
後臺篩選文章的列表頁面。mycenter:
後臺文章發佈、編輯、刪除頁面。select:
後臺留言管理、文章管理選擇頁面。write:
寫留言頁面。pages:
此路徑下存放的爲小程序的頁面文件(每一個頁面對應一個文件夾)。小程序
serverAPI:
服務器端 API ,配置好數據庫,放入服務器便可運行。微信小程序
wxSearch:
頁面搜索框的組件。服務器
下面詳細介紹各個頁面以及對應的目錄文件,下面的頁面都存在於
pages
文件夾中。
此頁面是小程序兩個入口之一的主頁面。該頁面的功能主要顯示關聯小程序的公衆號信息,圖中的右下角的對勾是進入後臺管理,每一個公衆號主都有超級管理員設置的惟一密碼,輸入密碼便可進入。點擊頁面中的公衆號信息,便可進入該公衆號的文章列表頁面(
artical
頁面)。
這裏涉及到一個頁面用戶受權登陸,具體邏輯參照根據微信小程序文檔。
1)該頁面的 js 中
postOpenid
函數做用爲上傳用戶的 openID。
該頁面共有三個 API 接口:
一、驗證後臺登陸密碼;
二、從服務器獲取關聯的公衆號信息;
三、上傳用戶的
openID
(若是不知道這個是什麼,能夠去微信小程序官網瞭解,這裏不詳細說了)。
// 驗證登陸密碼(只有關聯的公衆號主才能進行登陸)
getIdentifyId: function () {
var that = this;
wx.request({
url: '本身服務器API', //f服務器驗證密碼的 API
data: {
password: that.data.inputContent //獲取輸入框中的密碼
},
......
// 獲取公衆號信息顯示到頁面
getGongInfo: function () {
var that = this;
wx.request({
url: '本身服務器API', //獲取公衆號信息的 API
data: {
},
......
// 上傳管理員 openid
postOpenid: function () {
var that = this;
wx.request({
url: '本身服務器API', // 上傳 openid 的 API
data: {
openid: wx.getStorageSync('openid'),
id: that.data.id
},
複製代碼
該頁面主要顯示進入該公衆號的歷史文章列表。
該頁面是用戶點擊主頁面的某個公衆號跳轉進來的,主要顯示該公衆號的歷史文章列表,點擊某一文章便可查看該篇文章的已篩選的留言內容(
message
頁面)。
該頁面的接口只有一個:
一、獲取該公衆號的歷史文章列表。
// 獲取文章列表
wx.request({
url: '本身服務器API', //獲取文章列表API
data: {
type: '1',//獲取列表標識
id: g_id //公衆號id
},
......
複製代碼
主要呈現給用戶某篇文章已經篩選過的留言內容。
**注意:**這個頁面也是用戶進入小程序留言的第二個頁面入口,由於咱們的小程序留言會嵌入在公衆號文章中,而後用戶點擊某篇文章的內的小程序連接,頁面直接跳轉到用戶留言顯示頁面。而不是從主頁面進入,提升交互體驗。
該頁面是用戶點擊某篇文章跳轉進來的,用於顯示某篇文章的留言。能夠點擊該頁面的右上角的寫留言,便可進入寫留言的頁面(
write
頁面)。
該頁面共有兩個 API 接口:
一、獲取服務器的精選留言。
二、上傳點讚的數量。
//獲取已精選留言內容
getChooseCotent: function (){
var that = this;
wx.request({
url: '本身服務器API', //獲取已精選留言內容
data: {
no: that.data.no, //文章編號
ischeckmessage: '1', //留言是否通過篩選
g_id: that.data.g_id, //公衆號 id
openid: wx.getStorageSync('openid'), //用戶惟一標識
},
......
// 得到一個贊
that.getChooseCotent();
wx.request({
url: '本身服務器API', //url
data: {
p_id: that.data.messages[u_index].p_id,//用戶的 id
openid: wx.getStorageSync('openid'),//點贊用戶
status: 1, //得到一個贊
no: that.data.no, //文章編號
g_id: that.data.g_id, //公衆號 id
},
......
複製代碼
用戶留言上傳服務器,該公衆號主能夠在後臺對用戶留言進行篩選,防止不文明留言顯示給用戶
經過獲取到用戶輸入框內的留言內容,在頁面退出的時候上傳服務器,若是用戶在本頁面刪除了該留言,退出頁面不會上傳服務器。
該頁面只有一個上傳的 API 接口:
一、上傳留言內容,以及用戶的相關信息。
/** * 生命週期函數--監聽頁面卸載 */
onUnload: function () {
var that = this;
if(that.data.messages==""){
console.log("沒有留言數據!")
}else{
console.log("formid" + that.data.formId)
wx.request({
url: '本身服務器API', //上傳留言內容API
data: {
username: wx.getStorageSync('username'),//用戶名
avatarUrl: wx.getStorageSync('headpath'),//頭像
messages: that.data.messages,//留言內容
title: that.data.title,// 標題
ischeck: '0', //做者是否已回覆
no: that.data.no, //文章編號
openid: wx.getStorageSync('openid'), //用戶惟一標識
g_id: that.data.g_id, //公衆號標識
form_id: that.data.formId,//表單id
token: wx.getStorageSync('token')//token
},
......
複製代碼
當已關聯的公衆號主輸入密碼進入後臺管理界面,能夠進行一些文章的發佈、編輯以及留言篩選、回覆、置頂等操做。
基本的邏輯就是在主界面右下角輸入密碼。如圖:
只有一個 API 接口:
一、上傳密碼在服務器進行驗證(在主界面已經介紹過了)。
服務器驗證經過後,進入操做選擇界面(select
頁面)。
進入文章管理頁面(mycenter
頁面),能夠進行發佈文章,發佈文章按鈕是能夠摺疊的。以下:
該頁面只有兩個 API:
一、上傳文章相關信息的 API
二、上傳照片的 API
//上傳照片
post_image: function () {
var that = this;
console.log("照片路徑"+that.data.tempFilePath)
//上傳服務器
wx: wx.showToast({
title: '上傳中',
icon: 'loading'
})
wx.uploadFile({
url: '本身服務器API',
......
// 上傳文章信息的 API
wx.request({
url: '本身服務器API', //url
data: {
title: this.data.title, //標題
describe: this.data.describe, //描述
id: that.data.id,//公衆號id
isheck: 0 //標識
},
.......
複製代碼
文章的配圖、標題、描述,而後便可上傳服務器。收起發佈文章的摺疊按鈕,下方即將顯示已經發布的歷史文章。以下:
咱們經過長按路徑,在公衆號發表文章的時候便可將路徑填入小程序的連接中,用戶點擊留言,直接跳轉到該文章的留言頁面進行留言。
返回咱們選擇進入留言管理頁面,進入留言篩選,首先要知道你要篩選那個文章下的留言,因此先出現一個篩選文章列表,點擊該列表進入對該文章的留言篩選,(myartical
頁面爲文章篩選列表)。如圖:
該頁面只有一個 API:
一、獲取該公衆號的文章列表
wx.request({
url: '本身服務器API', //獲取文章列表
data: {
type: '1', //操做類型
id: that.data.id //公衆號id
},
......
複製代碼
其實該頁面和用戶想進入哪篇文章進行留言的頁面是同樣的,知識後臺管理人員進入某篇文章下進行留言篩選、回覆、置頂等功能操做。
下面進入某篇文章下的留言篩選頁面(lookmessage
頁面)。如圖:
管理員能夠在頁面進行篩選、置頂、回覆等操做了。
該頁面只有四個 API:
一、獲取留言列表
二、回覆留言 API
三、設置精選留言 API (取消精選同一 API)
四、刪除留言 API
五、留言置頂 API (取消置頂同一 API)
// 在已進入頁面就獲取留言列表
onLoad: function (options) {
var that = this;
var title = options.title;//文章標題
var nos = options.no; //文章編號
var ids = options.id;//公衆號id
that.setData({
no: nos,
title: title,
id: ids
})
wx: wx.showToast({
title: '正在獲取數據',
icon: 'loading'
})
wx.request({
url: '本身服務器API', //獲取留言列表
data: {
ischeckmessage: 0,
no: that.data.no,
id: that.data.id
},
......
//做者回復API
replay: function () {
var that = this;
var l = '本身服務器API';//信息用戶本身接收
console.log("更新forim"+that.data.formId)
var d = {
p_id: that.data.messages[that.data.index2].p_id,//用戶留言編號
page: '/pages/message/message?g_id=' + that.data.messages[that.data.index2].g_id + '&no=' + that.data.messages[that.data.index2].no + '&title=' + that.data.title,//跳轉頁面
title: that.data.messages[that.data.index2].title,//文章標題
message: that.data.messages[that.data.index2].userMesContent,//留言內容
replyMes: that.data.inputContent,//回覆內容
formid: that.data.formId, //更新formid
g_id: that.data.id //公衆號id
}
wx: wx.showToast({
title: '正在回覆中',
icon: 'loading'
})
wx.request({
url: '本身服務器API', //做者回復
data: {
id: that.data.messages[that.data.index2].p_id,//用戶編號
replyContent: that.data.inputContent, //回覆內容
isCheckChoess: '0' //是否篩選(否)
},
......
//精選留言 API
choose: function (event) {
var that = this;
var j_index = event.currentTarget.dataset.index;
console.log("精選索引:" + event.currentTarget.dataset.index)
wx: wx.showToast({
title: '正在設置中',
icon: 'loading'
})
wx.request({
url: '本身服務器API', //設置爲精選留言
data: {
id: that.data.messages[j_index].p_id,//留言用戶id
type: '1' //精選留言標識
},
......
//刪除留言 API
deleteMessage: function (event) {
var that = this;
var j_index = event.currentTarget.dataset.index;
console.log("精選索引:" + event.currentTarget.dataset.index)
wx: wx.showToast({
title: '正在刪除',
icon: 'loading'
})
wx.request({
url: '本身服務器API', //刪除留言
data: {
id: that.data.messages[j_index].p_id,//留言用戶id
type: '0' //精選留言標識
},
......
// 置頂留言 API
settop: function (event) {
var that = this;
var j_index = event.currentTarget.dataset.index;
console.log("置頂索引:" + event.currentTarget.dataset.index)
wx: wx.showToast({
title: '正在設置中',
icon: 'loading'
})
wx.request({
url: '本身服務器API', //留言置頂
data: {
id: that.data.messages[j_index].p_id,//留言用戶id
type: '1' //置頂留言標識
},
......
複製代碼
由於個人專業方向是前端,因此後臺接觸的不是很深,也沒有用到框架去開發,因此不管是在設計數據庫上仍是在代碼邏輯上多多少少不少欠缺,因此說有能力的小夥伴能夠後臺好久我提供的邏輯,從新把表和後臺代碼邏輯梳理一遍。
共有五張數據庫表,分別如此下:
該表存儲的是公衆號關聯的相關信息表,字段包括 id(主鍵ID)、name(公衆號名)、headpath(公衆號頭像路徑)、describes(公衆號描述)、password(後臺密碼)、openid(公衆號主的openID惟一標識)、fromid(模板ID)、token(token 驗證字段)。表的設計結構以下:
該表主要存儲的是每篇文章的相關信息,字段包括 no(主鍵,文章編號)、title(文章標題)、describ(文章描述)、imageTitle(文章配圖)、date(文章日期)、g_id(公衆號id)——這裏沒有關聯兩個表,從新建立的與另外一個表的 ID。表的設計結構以下:
**特別注意:**該表主要存儲留言相關信息。因爲起初沒有學習事後臺,因此在建表的時候,沒有將表分離關聯,因此用戶信息和留言信息直接寫到一個表中了。後期也沒有改,因此回後臺的小夥伴能夠本身更改過來。
字段包括 p_id(主鍵)、title(文章標題)、username(用戶名)、headimage(用戶頭像路徑)、userMesContent(用戶留言內容)、authorMesContent(做者回復內容)、no(文章編號)、isCheck(是否精選)、goodnum(可去掉)、ispraise(可去掉)、isTop(置頂標識)、g_id(公衆號id)、zanCount(點贊數量)、fromid(模板id)、token(token驗證值)。
com.xiaolu
下的包命名介紹:
- bean:實體類
- dao: dao 層
- servlet:接口類,全部對外小程序的接口。
- ThreadGetdata: 線程類,獲取 token
- util:工具類,連接數據庫之類的。
注意: 在 servlet 中每一個接口的功能在這裏不作介紹了,都在每一個代碼的開頭標記清除了,可自行查看。
在後臺代碼中的
util
包中的Util.java
類中配置鏈接數據庫的相關信息。
public class Util {
//jdbc:mysql://這裏寫上你服務器的 IP 地址和端口號/數據庫名?useUnicode=true&characterEncoding=UTF-8
private static final String URL = "...";
private static final String DRIVER = "com.mysql.jdbc.Driver";
private static final String USER = "...";// 數據庫用戶名
private static final String PASS = "...";// 數據庫密碼
private static Connection conn = null;
public static Connection getConnection() {
try {
if (conn == null || conn.isClosed()) {
Class.forName(DRIVER);
conn = DriverManager.getConnection(URL, USER, PASS);
}
} catch (SQLException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return conn;
}
}
複製代碼
在
servlet
包中的AppIDCodeServlet.java
類中配置小程序的APPID
和AppScret
(小程序官網後臺獲取)。
@WebServlet("/AppIDCodeServlet")
public class AppIDCodeServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
public static final String appID = ""; // 填寫你小程序的 APPid
public static final String appScret = "";// 你小程序的 AppScret(微信小程序官網獲取)
public static String openid = ""; // 空
public static String token = ""; // 空
public AppIDCodeServlet() {
super();
}
......
複製代碼