最近沉迷学习无法自拔,太久没有码字,码一个小程序留言功能实现。先上一波最后效果图:

(删除按钮,是用户自己的留言时才会显示该按钮)

实现技术

后台:SSM框架

数据库:MySQL数据库

数据库设计

评论功能的实现主要涉及三个表

comment:存储留言评论信息,表结构如下:

表中,必须的字段:id,user_id,reply_comment_id,comment,insert_time,source_id

添加了冗余字段username,reply_user_name,userphoto

主要用于存储微信名、回复的微信名、微信头像(这三个字段完全不应该冗余,当小程序用户更换用户名时,该表要跟着更新,可维护性差,不建议存储这些冗余信息,我就是懒得写SQL了)

source:存储你在小程序需要回复的内容。

user:存储小程序使用的用户信息,主要包括用户名、用户头像等微信用户信息。

小程序端

wxml

{{item.userName}}

-> {{item.replyUserName}}

{{item.comment}}

{{item.insertTime}}

回复

删除

回复{{replyUserName}}

取消回复

发送

css

.names {

display: flex;

font-size: 30rpx;

line-height: 40rpx;

}

.input_null {

color: #c9c9c9;

}

.replyAll {

position:absolute;

}

.release {

align-items: flex-end; /*底部对齐*/

box-sizing: border-box;

position: fixed;

left: 0;

bottom: 0;

width: 100%;

padding: 18rpx 0 18rpx 30rpx;

background-color: #f7f8f7;

font-size: 28rpx;

z-index: 999;

}

.replyinfo1{

display: flex;

justify-content: space-between; /*两端对齐*/

font-size: 35rpx;

}

.replyinfo2{

display: flex;

justify-content: space-between; /*两端对齐*/

}

.release textarea {

width: 550rpx;

min-height: 34rpx;

max-height: 102rpx; /*最多显示三行*/

border-width: 15rpx 20rpx; /*使用padding与预期留白不一致,故使用border*/

border-style: solid;

border-color: #fff;

line-height: 34rpx;

font-size: 28rpx;

background-color: #fff;

border-radius: 4rpx;

}

.release .text {

font-size: 40rpx;

color: #c9c9c9;

}

.cancel {

width: 240rpx;

height: 64rpx;

line-height: 64rpx;

text-align: center;

color: #6c0;

margin: 0 3px;

padding: 0;

}

.release .submit {

width: 120rpx;

height: 64rpx;

line-height: 64rpx;

text-align: center;

color: #6c0;

margin: 0 3px;

padding: 0;

}

.pro-box .info .text .delete {

color: #f68135;

border-radius: 50rpx;

border: 1px solid #f68135;

font-size: 28 rpx;

width: 150rpx;

height: 48rpx;

text-align: center;

}

js

// pages/comment/comment.js

const model = require('../cityChoose/cityChoose.js')

const config = require('../../utils/config.js')

const util = require('../../utils/util.js')

const app = getApp()

var mydata = {

end: 0,

replyUserName: ""

}

Page({

/**

* 页面的初始数据

*/

data: {

list: [],

},

/**

* 生命周期函数--监听页面加载

*/

onLoad: function(options) {

var that = this;

mydata.sourceId = options.sourceId

mydata.commentId = "";

mydata.replyUserName = "";

//设置scroll的高度

wx.getSystemInfo({

success: function(res) {

that.setData({

scrollHeight: res.windowHeight,

userId:app.globalData.haulUserInfo.id

});

}

});

mydata.page = 1;

that.getPageInfo(mydata.page);

},

/**

* 页面下拉刷新事件的处理函数

*/

refresh: function() {

console.log('refresh');

mydata.page = 1

this.getPageInfo(mydata.page, function() {

this.setData({

list: []

})

});

mydata.end = 0;

},

/**

* 页面上拉触底事件的处理函数

*/

bindDownLoad: function() {

console.log("onReachBottom");

var that = this;

if (mydata.end == 0) {

mydata.page++;

that.getPageInfo(mydata.page);

}

},

bindReply: function(e) {

console.log(e);

mydata.commentId = e.target.dataset.commentid;

mydata.replyUserName = e.target.dataset.commentusername;

this.setData({

replyUserName: mydata.replyUserName,

reply: true

})

},

// 合并数组

addArr(arr1, arr2) {

for (var i = 0; i < arr2.length; i++) {

arr1.push(arr2[i]);

}

return arr1;

},

deleteComment:function(e){

console.log(e);

var that = this;

var commentId = e.target.dataset.commentid;

wx.showModal({

title: '删除评论',

content: '请确认是否删除该评论?',

success: function (res) {

if (res.confirm) {

wx.request({

url: config.deleteComment,

method: "POST",

data: {

commentId: commentId

},

header: {

"content-type": "application/x-www-form-urlencoded;charset=utf-8",

},

success: res => {

that.refresh();

wx.showToast({

title: "删除成功"

})

}

})

} else if (res.cancel) {

console.log('用户点击取消')

}

}

})

},

cancleReply: function(e) {

mydata.commentId = "";

mydata.replyUserName = "";

this.setData({

replyUserName: mydata.replyUserName,

reply: false

})

},

// 更新页面信息

// 此处的回调函数在 传入新值之前执行 主要用来清除页面信息

getPageInfo(page, callback) {

var that = this;

util.showLoading();

console.log("getPageInfo");

console.log("page" + page);

var limited = 6;

var offset = (page - 1) * 6;

wx.request({

url: config.getComments,

method: "POST",

data: {

sourceId: mydata.sourceId,

limited: limited,

offset: offset

},

header: {

"content-type": "application/x-www-form-urlencoded;charset=utf-8",

},

success: res => {

console.log(res);

if (page == 1) {

that.data.list = res.data;

that.setData({

list: that.data.list

})

mydata.end = 0;

} else {

// 当前页为其他页

var list = that.data.list;

if (res.data.length != 0) {

list = that.addArr(list, res.data);

that.setData({

list: list

})

mydata.end = 0;

} else {

mydata.end = 1;

}

}

wx.hideLoading();

}

})

},

submitForm(e) {

var form = e.detail.value;

var that = this;

console.log(app.globalData.haulUserInfo);

if(form.comment == ""){

util.showLog('请输入评论');

return;

}

// 提交评论

wx.request({

url: config.insertComment,

method: "POST",

data: {

sourceId: mydata.sourceId,

comment: form.comment,

userId: app.globalData.haulUserInfo.id,

userName: app.globalData.haulUserInfo.userName,

replyCommentId: mydata.commentId,

replyUserName: mydata.replyUserName,

userPhoto: app.globalData.haulUserInfo.userPhoto

},

header: {

"content-type": "application/x-www-form-urlencoded;charset=utf-8",

//token: app.globalData.token

},

success: res => {

console.log(res)

if (res.data.success) {

wx.showToast({

title: "回复成功"

})

that.refresh();

mydata.commentId = "";

mydata.replyUserName = "";

this.setData({

replyUserName: mydata.replyUserName,

reply: false

})

} else {

wx.showToast({

title: '回复失败,请检查您的网络',

})

}

}

})

}

})

后台

后台功能:获取评论、删除评论、插入评论,都是简单的数据库操作,放在一个controller类中实现即可

package com.melon.haul.web;

import java.sql.Date;

import java.text.SimpleDateFormat;

import java.util.ArrayList;

import java.util.HashMap;

import java.util.List;

import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import net.sf.json.JSONObject;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Controller;

import org.springframework.test.context.web.WebAppConfiguration;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RequestMethod;

import org.springframework.web.bind.annotation.RequestParam;

import org.springframework.web.bind.annotation.ResponseBody;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import com.melon.haul.dto.DataUtil;

import com.melon.haul.dto.GetLocation;

import com.melon.haul.dto.Result;

import com.melon.haul.entity.Comment;

import com.melon.haul.entity.District;

import com.melon.haul.entity.Source;

import com.melon.haul.service.CommentService;

import com.melon.haul.service.DistrictService;

import com.melon.haul.service.SourceService;

@Controller

@WebAppConfiguration

@RequestMapping("/Comment")

public class CommentController {

private Logger logger = LoggerFactory.getLogger(this.getClass());

@Autowired

private CommentService commentService;

@RequestMapping(value = "/getComments", method = RequestMethod.POST)

private @ResponseBody List getComments(@RequestParam("sourceId") int sourceId,

@RequestParam("limited") int limited,@RequestParam("offset") int offset) {

logger.info("getComments");

List list = new ArrayList();

try{

list = commentService.getComment(sourceId, limited, offset);

}catch(Exception e){

}

return list;

}

@RequestMapping(value = "/insertComment", method = RequestMethod.POST)

private @ResponseBody

Result>insertComment(@RequestParam("sourceId") String sourceId,

@RequestParam("comment") String comment,@RequestParam("userId") int userId,

@RequestParam("userName") String userName,@RequestParam("replyCommentId") String replyCommentId,

@RequestParam("replyUserName") String replyUserName,@RequestParam("userPhoto")String userPhoto) {

logger.info("insertComment");

Map resultMap = new HashMap();

try{

Integer rCId = -1;

if(!replyCommentId.equals(""))

rCId = Integer.parseInt(replyCommentId);

commentService.insertComment(Integer.parseInt(sourceId), comment, userId,userName,rCId,replyUserName,userPhoto);

resultMap.put("msg", "insertComment success");

}catch(Exception e){

System.out.print(e);

resultMap.put("msg", "insertComment error");

}

return new Result>(true, resultMap);

}

@RequestMapping(value = "/deleteComment", method = RequestMethod.POST)

private @ResponseBody

Result>deleteComment(@RequestParam("commentId") String commentId) {

logger.info("deleteComment");

Map resultMap = new HashMap();

try{

commentService.deleteComment(commentId);

resultMap.put("msg", "deleteComment success");

}catch(Exception e){

System.out.print(e);

resultMap.put("msg", "deleteComment error");

}

return new Result>(true, resultMap);

}

}

公共CSS(app.wxss)

/**app.wxss**/

.container {

height: 100%;

display: flex;

flex-direction: column;

align-items: center;

justify-content: space-between;

padding: 200rpx 0;

box-sizing: border-box;

}

/* large button style */

.large-btn{

background: #f68135;

border-radius: 50rpx;

border: 1px solid #f68135;

color: #fff;

height: 100rpx;

line-height: 100rpx;

margin: 0 auto;

width: 96%;

text-align: center;

}

.large-btn.empty{

background: transparent;

color: #f68135;

margin-top: 50rpx;

}

.large-btn.disabled{

border-color: #ccc;

background: #ccc;

color: #fff;

}

/* public style to clear default styles */

.fl{

float: left;

}

.fr{

float: right;

}

.fc{

float:none;

}

.col-gray{

color: #999!important;

}

/* the message of auction about goods & cars */

.pro-con{

padding: 20rpx;

background: #f1f1f1;

}

.pro-box{

background: #fff;

padding: 20rpx;

box-sizing: border-box;

border-radius: 10rpx;

margin-bottom: 20rpx;

}

.pro-box .img{

display: inline-block;

vertical-align: top;

width: 80rpx;

height: 80rpx;

border-radius: 50%;

overflow: hidden;

margin-right: 10rpx;

}

.pro-box .box{

display: inline-block;

vertical-align: top;

width: calc(98% - 80rpx);

}

.pro-box .shead{

padding-bottom: 20rpx;

}

.pro-box .shead .name{

font-size: 30rpx;

line-height: 40rpx;

}

.pro-box .shead .stxt{

font-size: 26rpx;

color: #999;

}

.pro-box .shead .fr{

padding-top: 10rpx;

}

.pro-box .shead .fr navigator{

font-size: 0;

}

.pro-box .shead .fr image{

width: 48rpx;

height: 48rpx;

}

.pro-box .sharebtn{

height:48rpx;

background: #f68135;

border-radius: 50rpx;

border: 1px solid #f68135;

color: #fff;

text-align: center;

line-height: 50rpx;

font-size:30rpx;

}

.pro-box .addr-info{

align-items: center;

justify-content: space-between;

border-bottom: 1px dashed #ccc;

margin: 0 -20rpx;

margin-bottom: 20rpx;

padding-bottom: 20rpx;

padding-left: 20rpx;

padding-right: 20rpx;

display: inline-block;

}

.pro-box .addr-info .addr-text{

font-size: 35rpx;

line-height: 40rpx;

width:100%;

}

.pro-box .addr-info .addr-text .color1{

color:lightskyblue;

border-color: #ccc;

border: 1px solid lightskyblue;

border-radius:15px;

margin-right: 5px;

padding: 0rpx,2rpx,0rpx,2rpx;

}

.pro-box .addr-info .addr-text .color2{

color: #f68135;

border-color: #ccc;

border: 1px solid #f68135;

border-radius:10px;

margin-right: 5px;

margin-left: 5px;

padding: 0rpx,2rpx,0rpx,2rpx;

}

.pro-box .position{

width: 48rpx;

height: 48rpx;

}

.pro-box .comment{

width: 55rpx;

height: 48rpx;

}

.pro-box .addr{

align-items: center;

justify-content: space-between;

border-bottom: 1px dashed #ccc;

margin: 0 -20rpx;

margin-bottom: 20rpx;

padding-bottom: 20rpx;

padding-left: 20rpx;

padding-right: 20rpx;

display: flex;

}

.pro-box .addr .addr-text{

font-size: 34rpx;

line-height: 40rpx;

max-width: 240rpx;

min-width:200rpx;

overflow: hidden;

text-overflow: ellipsis;

white-space: nowrap;

}

.pro-box .addr .addr-text .color-text{

color: #f68135;

}

.pro-box .addr .time{

font-size: 26rpx;

line-height: 36rpx;

text-align: center;

}

.pro-box .addr .line{

background: #ccc;

height: 1px;

margin: 6rpx -20rpx;

position: relative;

}

.pro-box .info{

display: flex;

align-items: center;

justify-content: space-between;

}

.pro-box .info .text{

vertical-align:text-top;

font-size: 26rpx;

}

.pro-box .info .text .delete{

color: #f68135;

border-radius: 50rpx;

border: 1px solid #f68135;

width: 100rpx;

height: 48rpx;

text-align: center;

}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

java小程序知乎,微信小程序仿知乎实现评论留言功能相关推荐

  1. 知乎微信小程序广告真的猛的一塌糊涂

    知乎的App广告多, 小程序广告也多,而且做了一些恶意的设计,让用户很容易误触广告. 知乎微信小程序广告真的猛的一塌糊涂 知乎这哪里是问答社区, 根本就是广告社区. 知乎-刚下飞机人在美国公众号是XX ...

  2. java+SpringBoot+HTML+Mysq基于微信小程序的掌上博物馆游览

    详细功能设计:请点击下面链接查看 java+SpringBoot+HTML+Mysq基于微信小程序的掌上博物馆游览_哔哩哔哩_bilibili 源码+论文获取: 源码+论文获取请私信获取 摘  要 本 ...

  3. java计算机毕业设计基于安卓/微信小程序的大学生心理测试咨询管理系统app

    项目介绍 随着社会经济的发展,医疗卫生事业取得了巨大进步,在健康中心理健康占据越来越重要的地位,什么是心理健康:心理健康,从广义上讲,是指一种高效而满意的.持续的心理状态.从狭义上讲,心理健康是指人的 ...

  4. 基于java springboot的小说阅读微信小程序含后台管理系统源码

    系统运行环境 开发工具 eclipse(idea),mysql5.7(大于5.5),navicat,小程序开发工具 硬件要求 windows操作系统 cpu:2.4GHz 内存:4G 硬盘:100G ...

  5. 微信小程序获取用户手机号码,Java后台servlet解密(微信小程序调用微信支付也是大致的流程)

    本篇记录说明 微信小程序获取用户手机号码,Java后台servlet解密(微信小程序调用微信支付也是大致的流程,详细内容可私信交流) (第一次写博客,写得不好的地方见谅,面向新手,大佬请无视,不喜勿喷 ...

  6. 微信小程序开发学习笔记001--认识微信小程序,第一个微信小程序

    第一天,认识微信小程序,第一个微信小程序 1.什么是微信小程序? 是h5网页嘛?不是 微信张小龙说: 小程序是一种不需要下载安装即可使用的应用, 它实现了应用"触手可及"的梦想,用 ...

  7. 在线电子书阅读小程序,微信小程序电子书阅读,微信小程序小说阅读器毕业设计作品

    项目背景和意义 目的:本课题主要目标是设计并能够实现一个基于微信小程序在线电子书阅读系统,前台用户使用小程序,后台管理使用基Java+MySql技术:通过后台录入电子书信息.书目录信息,用户通过小程序 ...

  8. 小程序获取sessionkey_微信小程序 获取session_key和openid的实例

    微信小程序 获取session_key和openid的实例 说说获取session_key和openid的条件 1.AppID(小程序ID); 2.AppSecret(小程序密钥); 3.登录时获取c ...

  9. 【微信小程序系列】微信小程序连接后端数据库(SSM)案例

    [微信小程序系列]微信小程序连接后端数据库(SSM)案例 登录页面 login.wxml <view class="page"><loading hidden=& ...

  10. 微信小程序之目前为止史上最全的微信小程序项目实例, 微信小程序实战学习

    wx-gesture-lock  微信小程序的手势密码 WXCustomSwitch 微信小程序自定义 Switch 组件模板 WeixinAppBdNovel 微信小程序demo:百度小说搜索 sh ...

最新文章

  1. ubuntu下vscode调试开发踩过的坑
  2. Boost:align对齐的测试程序
  3. 利用UDEV服务解决RAC ASM存储设备名
  4. java中vi是什么意思_java中的public void是什么意思?
  5. django-后台传图0912
  6. 正则表达式中原子的5种类型
  7. VScode加文件头的方式
  8. cydia多开微信_苹果ios怎么多开微信分身?
  9. 测试工具ApiPost和Postman及Apifox
  10. WinAPI 数据类型
  11. linux输出文件首行,Linux:提取文件的第一行
  12. Java 实现 n 阶行列式的求解
  13. Compose Modifier.swipeable() 写个侧拉组件
  14. 新的一年,红包走起!
  15. poj 1383 Labyrinth 树的直径
  16. 歌曲光辉岁月和弦走向探究
  17. 反序列化漏洞-JAVA
  18. 凉宫春日的忧郁第一章
  19. 使用NSIS制作安装文件
  20. [DeploymentService:290066]Error occurred while downloading files from admin server for deployment re

热门文章

  1. iacr是什么会议_什么才算计算机的顶级会议?
  2. matlab中文论坛有手机版吗,MATLAB中文论坛常见问题归纳
  3. MAC文件误删怎么办?mac数据恢复,亲测很好用的方法
  4. react函数组件 更新自动展示和暴露方法给父组件
  5. 轻质泡沫板的全球与中国市场2022-2028年:技术、参与者、趋势、市场规模及占有率研究报告
  6. 无法启动此应用因为计算机丢失,解决提示“无法启动此程序,因为计算机中丢失chrome_elf.dll”的问题...
  7. 写给大忙人看的 - Java中图片压缩上传至MinIO服务器(4)
  8. 银湖网更改手机号那极致糟糕的体验
  9. SMB交换机、接入交换机、汇聚交换机、核心交换机
  10. 以 回车键 为结束标志的输入