eclipse(idea),mysql5.7(大于5.5),navicat,小程序开发工具
windows操作系统
cpu:2.4GHz
内存:4G
硬盘:100G
windows10操作系统
jdk1.8
mysql5.7
谷歌浏览器
后台开发语言选用java,采用maven构建项目,maven有很多优点,最大得优点就是模块化,依赖自动下载,主要用到springboot框架,springboot框架的有点很多,封装了servlet,提高了开发效率,集成了servlet容器,简单的配置,灵活的应用。还用到了mybatis,mybatis主要封装了jdbc,提供了灵活的sql配置文件。后台管理界面则采用了bootstrap框架,bootstrap扁平化设计,使得界面整体美观大方。js用到vue.js,数据dom绑定,操作更加简单方便。小程序则只用了自身的标签去实现,样式采用了微信官方提供weui样式库。数据库采用mysql,mysql体积小,安装方便灵活,适合中小型项目开发。
会员表(base_member)
字段名称 |
数据类型 |
必填 |
注释 |
id |
int(11) |
是 |
|
openid |
varchar(255) |
否 |
微信openid |
nickname |
varchar(255) |
否 |
昵称 |
avatar_url |
varchar(255) |
否 |
头像 |
gender |
char(1) |
否 |
性别 |
real_name |
varchar(50) |
否 |
姓名 |
mobile |
varchar(50) |
否 |
手机号码 |
login_name |
varchar(50) |
否 |
登录账号 |
password |
varchar(100) |
否 |
密码 |
integral |
int(11) |
否 |
积分 |
create_time |
datetime |
否 |
创建时间 |
图书表(book_book)
字段名称 |
数据类型 |
必填 |
注释 |
id |
int(11) |
是 |
|
book_name |
varchar(255) |
否 |
图书名称 |
category_id |
int(11) |
否 |
分类ID |
press |
varchar(50) |
否 |
出版社 |
author |
varchar(20) |
否 |
作者 |
price |
decimal(10,2) |
否 |
价格 |
pic_url |
varchar(255) |
否 |
图片 |
status |
tinyint(2) |
否 |
上下架 |
stock |
int(11) |
否 |
库存 |
describe |
text |
否 |
描述 |
create_time |
datetime |
否 |
创建时间 |
分类表(book_category)
字段名称 |
数据类型 |
必填 |
注释 |
id |
int(11) |
是 |
|
category_name |
varchar(255) |
否 |
分类名称 |
pic_url |
varchar(255) |
否 |
图片 |
sort |
int(11) |
否 |
排序 |
type |
tinyint(255) |
否 |
类型 |
create_time |
datetime |
否 |
创建时间 |
章节表(book_chapter)
字段名称 |
数据类型 |
必填 |
注释 |
id |
int(11) |
是 |
|
title |
varchar(50) |
否 |
标题 |
content |
longtext |
否 |
内容 |
book_id |
int(11) |
否 |
图书id |
sort |
int(11) |
否 |
排序 |
create_time |
datetime |
否 |
创建时间 |
评价表(book_evaluation)
字段名称 |
数据类型 |
必填 |
注释 |
id |
int(11) |
是 |
主键 |
order_id |
int(11) |
否 |
订单id |
member_id |
int(11) |
否 |
用户id |
content |
varchar(255) |
否 |
评价内容 |
star |
int(11) |
否 |
|
book_id |
int(11) |
否 |
图书id |
create_time |
datetime |
否 |
评价时间 |
阅读历史表(book_history)
字段名称 |
数据类型 |
必填 |
注释 |
id |
int(11) |
是 |
|
book_id |
int(11) |
否 |
图书id |
member_id |
int(11) |
否 |
会员id |
create_time |
datetime |
否 |
创建时间 |
管理员表(sys_user)
字段名称 |
数据类型 |
必填 |
注释 |
id |
bigint(20) |
是 |
|
username |
varchar(50) |
是 |
用户名 |
password |
varchar(100) |
否 |
密码 |
salt |
varchar(20) |
否 |
盐 |
|
varchar(100) |
否 |
邮箱 |
mobile |
varchar(100) |
否 |
手机号 |
status |
tinyint(4) |
否 |
状态 0:禁用 1:正常 |
create_time |
datetime |
否 |
创建时间 |
小程序和后台通信通过wx.request方式
基于springboot小说阅读微信小程序源码
后台管理功能截图:
微信小程序:
后端关键代码:
package com.wfuhui.modules.wechat.controller;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import cn.binarywang.wx.miniapp.bean.WxMaUserInfo;
import me.chanjar.weixin.common.error.WxErrorException;
import com.wfuhui.common.annotation.AuthIgnore;
import com.wfuhui.web.utils.JwtUtils;
import com.wfuhui.common.utils.R;
import com.wfuhui.modules.member.entity.MemberEntity;
import com.wfuhui.modules.member.service.MemberService;
/**
* 微信小程序用户接口
*/
@RestController
@RequestMapping("/api/wechat")
public class WxMaUserController {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@Autowired
private WxMaService wxService;
@Autowired
private MemberService memberService;
@Autowired
private JwtUtils jwtUtils;
/**
* 登陆接口
*/
@AuthIgnore
@GetMapping("login")
public R login(String code) {
if (StringUtils.isBlank(code)) {
return R.error("empty jscode");
}
try {
WxMaJscode2SessionResult session = this.wxService.getUserService().getSessionInfo(code);
this.logger.info(session.getSessionKey());
this.logger.info(session.getOpenid());
//查询用户信息
MemberEntity user = memberService.queryByOpenid(session.getOpenid());
if(user == null) {
String sessionKey = session.getSessionKey();
return R.error(1, "未注册").put("sessionKey", sessionKey);
}
//生成token
String token = jwtUtils.generateToken(user.getId());
Map map = new HashMap();
map.put("token", token);
map.put("userInfo", user);
return R.ok(map);
} catch (Exception e) {
this.logger.error(e.getMessage(), e);
return R.error();
}
}
/**
* 用户注册
*/
@AuthIgnore
@GetMapping("register")
public R register(String avatarUrl, String nickname, String gender, String code) {
try {
String openid = this.wxService.getUserService().getSessionInfo(code).getOpenid();
//查询用户信息
MemberEntity user = memberService.queryByOpenid(openid);
if(user != null) {
return R.ok();
}
//注册
MemberEntity member = new MemberEntity();
member.setAvatarUrl(avatarUrl);
member.setOpenid(openid);
member.setNickname(filterUtf8mb4(nickname));
member.setGender(gender);
member.setCreateTime(new Date());
memberService.save(member);
return R.ok();
} catch (WxErrorException e) {
e.printStackTrace();
return R.error();
}
}
public static String filterUtf8mb4(String str) {
final int LAST_BMP = 0xFFFF;
StringBuilder sb = new StringBuilder(str.length());
for (int i = 0; i < str.length(); i++) {
int codePoint = str.codePointAt(i);
if (codePoint < LAST_BMP) {
sb.appendCodePoint(codePoint);
} else {
i++;
}
}
return sb.toString();
}
}
pom.xml:
4.0.0
org.springframework.boot
spring-boot-starter-parent
2.3.4.RELEASE
com.wfuhui
novel-server
0.0.1-SNAPSHOT
novel-server
novel project for Spring Boot
1.8
3.1.1
1.0.28
8.0.16
1.3.0
2.6
1.3.1
2.5
1.10
1.3.2
0.7.0
0.0.9
org.springframework.boot
spring-boot-starter
org.springframework.boot
spring-boot-starter-web
org.mybatis.spring.boot
mybatis-spring-boot-starter
${mybatis.spring.boot.version}
org.springframework.boot
spring-boot-devtools
true
true
commons-lang
commons-lang
${commons.lang.version}
commons-fileupload
commons-fileupload
${commons.fileupload.version}
commons-io
commons-io
${commons.io.version}
commons-codec
commons-codec
org.apache.shiro
shiro-core
${shiro.version}
org.apache.shiro
shiro-spring
${shiro.version}
com.github.axet
kaptcha
${kaptcha.version}
com.auth0
java-jwt
3.3.0
org.springframework.boot
spring-boot-starter-test
test
org.junit.vintage
junit-vintage-engine
com.alibaba
druid
${druid.version}
mysql
mysql-connector-java
com.github.binarywang
weixin-java-miniapp
3.4.0
com.github.binarywang
weixin-java-pay
3.4.0
org.springframework.boot
spring-boot-maven-plugin
public
aliyun nexus
http://maven.aliyun.com/nexus/content/groups/public/
true
public
aliyun nexus
http://maven.aliyun.com/nexus/content/groups/public/
true
false
//index.js
//获取应用实例
const app = getApp()
var sliderWidth = 57.6; // 需要设置slider的宽度,用于计算中间位置
Page({
data: {
autoplay: true,
interval: 3000,
duration: 1000,
bannerList: [],
categoryList: [{
id: 1,
categoryName: '男生'
},{
id: 2,
categoryName: '女生'
}],
bookList: [],
recommendList: [],
bookEvaluateList: [],
bookHistoryList: [],
isLoad: false,
page: 1,
pageSize: 9,
tabs: ["最新上架", '最多阅读', '最多评价'],
activeIndex: 0
},
onLoad: function() {
this.getAdvert();
//this.getCategory();
//this.getBook();
this.getRecommend();
var that = this;
wx.getSystemInfo({
success: function (res) {
that.setData({
sliderLeft: (res.windowWidth / that.data.tabs.length - sliderWidth) / 2,
sliderOffset: res.windowWidth / that.data.tabs.length * that.data.activeIndex
});
}
});
},
onShow: function(){
},
tabClick: function (e) {
this.setData({
activeIndex: e.currentTarget.id,
sliderOffset: e.currentTarget.offsetLeft,
page: 1
});
if(e.currentTarget.id == 0){
this.getBook()
}else if(e.currentTarget.id == 1){
this.getBookHistory();
}else if(e.currentTarget.id == 2){
this.getBookEvaluate();
}
},
showInput: function () {
wx.navigateTo({
url: '/pages/book/book-list/index',
})
},
getAdvert: function() {
var that = this;
wx.request({
url: app.globalData.domain + '/api/advert/list',
data: {
position: 'shop'
},
success: function(res) {
that.setData({
bannerList: res.data.advertList
});
}
})
},
getCategory(){
var that = this;
wx.request({
url: app.globalData.domain + '/api/category/list',
data: {
},
success: function (res) {
var categoryList = res.data.categoryList;
var categories = ['全部'];
for(var i = 0; i < categoryList.length; i++){
categories.push(categoryList[i].categoryName)
}
that.setData({
categoryList: res.data.categoryList,
tabs: categories
});
wx.getSystemInfo({
success: function (res) {
that.setData({
sliderLeft: (res.windowWidth / that.data.tabs.length - sliderWidth) / 2,
sliderOffset: res.windowWidth / that.data.tabs.length * that.data.activeIndex
});
}
});
}
})
},
getRecommend(){
var that = this;
var categoryId = '';
if (this.data.activeIndex != 0){
categoryId = this.data.categoryList[this.data.activeIndex - 1].id
}
wx.request({
url: app.globalData.domain + '/api/book/list',
data: {
type: categoryId,
page: that.data.page,
limit: that.data.pageSize,
recommend: 1
},
success: function(res) {
that.setData({
recommendList: res.data.bookList
})
}
})
},
getBookEvaluate(){
var that = this;
wx.request({
url: app.globalData.domain + '/api/book/listEvaluate',
data: {
page: that.data.page,
limit: that.data.pageSize
},
success: function(res) {
that.setData({
bookList: res.data.bookList
})
}
})
},
getBookHistory(){
var that = this;
wx.request({
url: app.globalData.domain + '/api/book/listHistory',
data: {
page: that.data.page,
limit: that.data.pageSize
},
success: function(res) {
that.setData({
bookList: res.data.bookList
})
}
})
},
getBook: function() {
var that = this;
var categoryId = '';
if (this.data.activeIndex != 0){
categoryId = this.data.categoryList[this.data.activeIndex - 1].id
}
wx.request({
url: app.globalData.domain + '/api/book/list',
data: {
type: categoryId,
page: that.data.page,
limit: that.data.pageSize
},
success: function(res) {
that.setData({
bookList: res.data.bookList
})
return;
if (that.data.page == 1) {
that.setData({
bookList: []
});
}
if (res.data.code != 0) {
that.setData({
isLoad: false
});
return;
}
if (res.data.bookList.length == 0) {
that.setData({
isLoad: true
});
return;
}
var book = that.data.bookList;
for (var i = 0; i < res.data.bookList.length; i++) {
book.push(res.data.bookList[i]);
}
that.setData({
bookList: book,
isLoad: false
});
}
})
},
loadMore: function () {
return;
console.log("load more")
var that = this;
var isLoad = this.data.isLoad;
console.log(isLoad)
if (!isLoad) {
this.setData({
page: that.data.page + 1
});
this.getBook();
}
},
onPullDownRefresh: function() {
this.setData({
page: 1
});
wx.showNavigationBarLoading()
this.getAdvert();
//this.getCategory();
this.getBook();
setTimeout(function() {
wx.hideNavigationBarLoading() //完成停止加载
wx.stopPullDownRefresh() //停止下拉刷新
}, 1000);
},
onShareAppMessage: function() {
var path = '/pages/index/index';
if (app.globalData.distributor) {
path = path + "?distributor=" + app.globalData.distributor;
}
return {
title: wx.getStorageSync('storeName'),
path: path,
success: function(res) {
// 转发成功
},
fail: function(res) {
// 转发失败
}
}
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function () {
this.loadMore();
}
})
基于java springboot的小说阅读微信小程序含后台管理系统源码