Node.js Graduation Project - Design and Implementation of Online Bookstore Based on Nodejs+Mongodb+WeChat Mini Program (Graduation Thesis + Program Source Code) - Online Bookstore

Design and implementation of online bookstore based on nodejs+mongodb+WeChat applet (graduate thesis + program source code)

Hello everyone, today I will introduce to you the design and implementation of an online bookstore based on nodejs+mongodb+WeChat applet. At the end of the article, the thesis and source code download address of this graduation project are attached. Friends who need to download the proposal report PPT template and thesis defense PPT template, etc., can go to my blog homepage to view the self-service download method in the bottom column on the left.

Article directory:

1. Project introduction

  1. Weishu is an online bookstore based on WeChat Xiaocheng. The bookstore database is stored using mongodb. The bookstore data is crawled from the Internet using nodejs crawler, and loopback is used as the back-end interface framework. Functionally, WeChat implements the following five modules, namely my bookshelf, bookstore, personal heart, H5 reader, and login and registration. There are many sub-modules in these modules, which are connected and coordinated with each other to provide users with a convenient and comfortable reading experience, allowing users to read the books they want to read more easily and without paying. In addition, Weishu also supports book reviews and viewing of book rankings, helping users find their favorite books from the vast sea of ​​books. This paper will introduce the designed micro-book and conduct data analysis and design of this system.


2. Resource details

Project difficulty: medium difficulty
Applicable scenario: graduation project on related topics
Word count of supporting paper: 10619 words and 30 pages< a i=3>Contains: full set of source code + completed thesisRecommended download method for ppt templates such as proposal report, thesis defense, project report, etc.:


Insert image description here


3. Keywords

WeChat applet, H5 reader, web crawler, Loopback, mongodb

4. Introduction to Bishe

Tip: The following is a brief introduction to the graduation thesis. The complete source code of the project and the download address of the complete graduation thesis can be found at the end of the article.

Foreword
1.1 Project Introduction
Mini program is an application that can be used without downloading and installation. It realizes the application "at your fingertips" ” dream, users can open the application by scanning or searching. With the help of mini programs, applications will be everywhere and available at any time, but there is no need to install or uninstall them. On the other hand, in the face of the trend of charging and advertising for reading, we hope to provide users with a free, comfortable and pure reading experience, so that Weidu can become a mobile library for users and use in-depth content to fight against the impetuous world. Combining the above two aspects, we used the WeChat applet as the front-end foundation, nodejs and the database mongodb as the back-end support to build a mobile reading application - Weishu.

1.2 Project Background
With the launch of WeChat mini programs, more and more developers are migrating their products to mini programs, hoping to take advantage of WeChat’s huge traffic and information dissemination Convenience makes your products known. At the same time, the Internet has entered the era of big data. With limited resources and few users, it is difficult for many products to collect large amounts of data. At this time, crawlers can be used as a temporary data source. The development of Weishu is based on the above two points, using nodejs crawler as the data source, WeChat applet as the product display method, and loopback as the back-end support to build a free online bookstore. Using Weishu, you can read many books that you previously had to pay to read. At the same time, the well-designed reader can also give you a comfortable reading experience that is different from web reading.

2 Weishu Bookstore System Analysis
2.1 Demand Analysis
In the era of popularization of the Internet, online reading has entered people's lives. Compared with traditional books, online reading allows users to choose their favorite books more conveniently and quickly. It has a huge library of books that can meet the needs of users in all aspects. At the same time, the network reader can store all of your favorite books in a small mobile phone, and can also save user bookmarks and ideas for easy viewing at any time. A standard online bookstore should help users find and select their favorite books, and provide book management functions such as book list, book update status, bookmarks, etc., as well as an H5 reader for online reading.

The online bookstore should have a front-end and a back-end in its architecture. The front-end mainly provides a beautiful and user-friendly interface, and uses the interface provided by the back-end to display data and provide users with a good reading environment. The backend includes three aspects. The first is database design, which provides fast data query and storage. The second is data sources. If there is no user base in the early stage, you can use web crawlers to crawl existing data from book publishing websites. The third is API. Interface provides the front end with an entrance to obtain data.
The online bookstore should have the following important functions:
(1) For each book in the bookstore, users can click to view the book details and then decide whether to Add to personal bookshelf.
(2) When users view book details, they can see other users' reviews of the book, and they can also write book reviews for this book.
(3) There is a personal bookshelf page to facilitate users to manage their own books. It is best to provide a basic search function so that users can quickly locate the books they are looking for. In addition, there needs to be a link to the bookstore page for users to add new books.
(4) The bookstore can place some information such as recommended topics, categories, and rankings to guide users to quickly choose their favorite books. In addition, it is best to provide a global search function to deal with Users locate the needs of books directly through the book titles.
(5) The bookstore should have basic user management functions, including login and registration, WeChat binding, viewing and updating personal information, reading settings, my messages, etc.

2.2 Functional Analysis
Based on the above demand analysis, I divided Weishu into five main modules, namely my bookshelf, book details page, H5 reader, and personal center ,log in Register. The specific description of each functional module is as follows:
My bookshelf: My bookshelf is used to display the books that the user has added to the bookshelf, and provides book update reminders, book classification by time, and search functions.
Book details page: The book details page will display information about the book such as book name, cover, author, introduction, etc., and provide users with "add to bookshelf" and "read now" button. Book reviews are also a major function of the details page, which allows users to express their opinions on the book. It can also help subsequent users better choose their favorite books and provide a platform for user communication.
H5 reader: The reader is an online reading tool for users. It has functions such as left and right sliding page turning, viewing book catalogs, switching reader styles, and changing fonts.
Personal Center: In the Personal Center, users can view their personal information and choose whether to change them. In addition, they can set the reader style, fonts, or make some settings for the software (such as update prompts , prompts you to take a break after reading for a long time, etc.). Users can also view their own book reviews and other users' replies to their messages.
Login and registration: Weishu has its own user management. Some basic information of users can be obtained in the mini program, but this is not enough, so we need to register users as based on the WeChat mini program. Weishu users use their own servers to separately maintain the user's login status.

The picture below is the functional module diagram of Weishu:
Insert image description here

2.3 System use case diagram design
There are three types of Weishu users - mini program users, product operations, and product operation and maintenance. Mini program users scan the 2D of Weishu For those who enter and use Weishu with a code, product operations are responsible for editing bookstore recommended topics, new book columns, and notifying users via email. Product operation and maintenance mainly maintains the normal execution of back-end interfaces, databases, and web crawlers. The following is a use case diagram drawn based on these three types of users:
Insert image description here

2.4 System flow chart design
Users scan the QR code to enter Weishu. They first need to verify whether WeChat is bound. If WeChat is not bound, jump to the WeChat registration page and then log in. Get the login credentials returned by the backend and enter the My Bookshelf page.
The bookshelf page will determine whether the books are already owned and whether the books are updated. If there are already books on the shelf, you can click to enter the H5 reader, otherwise it will be directed to the bookstore page to add them. books.
On the book details page, users can choose to add this book to their own books or remove this book from the bookshelf. In addition, you can add book reviews for this book or comment on other users' book reviews.
If the user enters the H5 reader and starts reading, the system will record the user's reading time and update the reading time when leaving the reader. In the reader, users can switch the reader style to eye protection mode, daylight mode, or night mode, change the reader brightness and font, and view all chapters of the book.
On the personal center page, the user's reading time, accumulated reading days, and books owned will first be displayed. Click on the personal avatar to view your personal information, and select Modify to modify your information. In the settings bar, users can make some of their favorite settings for the reader. These settings will be loaded by default next time the reader is opened. In the personal message bar, messages replied by other users will be displayed. You can also reply directly to others.
The bookstore will load the latest recommended topics, categories, and book rankings to help users better choose their favorite books. The following is the system flow chart of Weishu:
Insert image description here

2.5 System Development Environment
The environment and tools required for Weishu development are as follows:
(1) Operating system used for development: Windows 10 Enterprise Version
(2) Database and tools used for development: Mongodb, Robomongo
(3) Text editor used for development: Sublime Text3
(4) Nodejs debugging tool: Webstorm 2017.3.1
(5) Mini program development tool: WeChat official developer tool

3 Database analysis and design
3.1 Database analysis
Weishu mainly stores some text, while mongo is faster in processing text data. And mongo is closely integrated with nodejs, the main development language used. In addition, mongo has a concept of parent-child documents similar to mysql, and can also easily implement relationship models and joint queries between different documents. Therefore, before development, mongodb is used as a database to save basic book information, chapter information, user information, and ranking information.
3.2 Conceptual design of database
In addition to 5 entities, Weishu planning includes basic information entities of books, chapter information entities, user information entities, ranking information entities, and email message entities. Considering that the amount of chapter information data is relatively large, we do not store all chapter information and basic book information in one document. Instead, we use the mongo parent-child document model to define two tables to store the information of the two separately.
A. The book basic information entity contains the basic information of the book, including book id, book name, book description, book cover image address, book word count, and book chapter array (including all chapters of this book) Array of ids), the latest chapter of the book (used to determine whether the book is updated), and the book update time.
B. The chapter information entity is a sub-document of the basic information entity of the book, and its id is included in the chapter array of the basic information entity. These include chapter id, chapter number (which chapter), chapter title, chapter content, crawl source, and update time.
C. User information entity, including a lot of user information, such as user ID age, birthday, avatar, personal signature, nickname, etc., among which there are some fields that connect other entities, such as my book reviews, My messages, my settings, my emails, and my books will all be added or updated during the user management process.
D. Ranking information entity, used to record the book ranking information sorted by crawlers from Qidian.com and Zongheng.com. This includes the category name, the starting point ranking array, the vertical and horizontal ranking array, and the update time
E. The email information entity is used to record the sent email, including the sender, recipient, and sending time. , email title, email content, etc.
The following is the E-R diagram of these entities:
Insert image description here

3.3 Data logical structure design
Insert image description here
Insert image description here

4 Weishu design and function implementation
4.1 System login and registration module
4.1.1 Login and registration interface design
Insert image description here
Insert image description here

4.1.2 Login and registration logic implementation
A. Login
There are three common mini program login methods, namely logging in with your own account, using Log in with a third-party platform account or log in with a WeChat account. The implementation principles of each login method will be described below.
Registering with a WeChat account is the officially recommended login method. After all, the mini program is based on WeChat. This login method is also more secure than other methods (WeChat has signed and signed the data. encryption). However, since the mini program does not have a cookie mechanism, the login to the mini program and the maintenance of the login status are different from the previous logins. The general process is as follows:

  1. Call wx.login() of the mini program API to obtain the WeChat login credentials.
  2. Use the login credentials to call wx.getUserInfo() of the mini program API to obtain basic user information (such as avatar, nickname, etc.), some sensitive user information, and data signature (will be used for data verification).
  3. Send the certificate wxcode to the backend (third-party server) through the interface written by yourself. The backend sends a code2Session request to the WeChat server, using the code in exchange for the user's unique openid and section_key.
    4. Use the openid and section_key obtained in the previous step as key values, and use a random algorithm to generate a unique id as the key value name sessionid, and then store the key value name and key value in redis , and set the expiration time to 7 days. And provide a method to check whether the sessionid has expired to determine whether the login status is valid.
  4. Return the generated key value name sessionid to the front end, and the front end stores the sessionid in the applet cache.
  5. When the user leaves the mini program and logs in again, first call the backend interface to determine whether the sessionid has expired. If it has not expired, jump to my book list. If it has expired, perform the above operation again.
    The figure below details how the mini program implements login and maintains the login status.
    Insert image description here

Use your own account to log in. This is the same as the common login operation. Query the myAppUser table in the database, check the user name and password. The maintenance of login status is consistent with logging in using WeChat
Use a third-party account to log in. It is worth noting here that the mini program does not support Html pages. Those third-party APIs that require redirection for login need to be modified or cannot be used.

B. Registration
Weishu registration is different from ordinary registration, with the additional step of initializing information before registration. Since Weishu is based on a mini program, we hope that when the user fills in the registration information, the information already in the WeChat account, such as nickname, avatar, and city, will have an initialized value, which will reduce the time it takes for the user to register. Input also seems to be more closely integrated with WeChat. The following introduces the registration process of Weishu:

  1. First, use wx.login() to obtain the login credentials, and then call wx.getUserInfo() to obtain the user's user information in WeChat.
  2. Use this user information as the initialization information of the registration form. Of course, the user can still change this initialization information when registering.
  3. When the user clicks the submit button, regular verification is performed on the information filled in by the user, and the user is prompted for registration items that fail the verification.
  4. If all registration items pass the regular verification, the backend registration interface is called to send the information submitted by the user to the backend, and the backend stores the data in the database to complete the registration.
    Here is the principle of implementing the function of uploading personal avatars. You can use the wx.chooseImage method of the mini program to select a local image and take a photo. After that, this method will return a temporary image address. The third-party image storage server used by Weishu is Qiniu Cloud. Qiniu Cloud first needs to get the upload certificate uploadToken, so here it implements a getUploadToken interface specifically to return the upload certificate field. After that, you only need to send the upload certificate and temporary image address to Qiniu Cloud using wx.request and the upload will be successful. After success, an online address of Qiniu Cloud will be returned. Just update this online address as the user's new image address.

4.2 My bookshelf module
4.2.1 My bookshelf interface design
Insert image description here

4.2.2 My bookshelf logic implementation
My bookshelf page mainly implements the book list and search functions. The implementation principles of these two functions are introduced below.
The book list page displays the books added by the user to the bookshelf, so there is a myBooks field under the myAppuser table in the database to record the user's books and the chapters to be read for each book. number.
Insert image description here

The backend obtains the user's book list array based on the userid passed from the frontend. Then check the basic information table of the book based on the bookid in the array to get the book's cover image address, book title, and latest chapter, combined with the previous book ID and read chapters, and return them to the front end. Finally, the front-end uses a loop to display this information on the page.
Insert image description here

Book list search uses regular expressions to match the search value entered by the user, and will retrieve book names and book descriptions. If there is a matching value, the book is shown, otherwise if there is no matching value, it is set to hidden. In addition, the book list search also adds the function of highlighting matching items. The principle of implementation is that when using the exec method of js regular expressions, the position value of each matching item will be obtained. According to this position value, the position value will be dynamically displayed before and after the string. Add the tag and then style this tag in css.

while (regExp.exec(tempStr) != null) {
    
    
  console.log(++count);
  lastIndex = regExp.lastIndex + 13 * (count - 1);
  //每次循环notChageStr并非不变,而是多了<code></code>共计13个字符,所以为了保证后续循环中lastindex的正确性应该将lastindex自增13
  leftStr = notChageStr.substring(0, lastIndex - searchString.length);
  rightStr = notChageStr.substring(lastIndex);
  notChageStr = leftStr + '<code>' + searchString + '</code>' + rightStr;
}

4.3 H5 reader module
4.3.1 Reader interface design

4.3.2 Reader paging
When using the front end to do reader paging, you need to pay attention to three issues:
A. Character paging< a i=3> Line height (line-height), font size (font-size), and font type (font-family) affect how many characters a page can accommodate (including text, symbols, spaces, line breaks, etc.) main factors. Let’s take a look at the definitions of the three and their relationships.  Font size (font-size), which sets the height of the character box in the font. Different fonts of the same size on a page have different actual heights.


Insert image description here

 Line-heigth will affect the layout of the line box. When applied to a block-level element, it defines the minimum distance between baselines in that element rather than the maximum distance. The calculated difference between line-height and font-size is divided in half and added to the top and bottom of a line of text. The smallest box that can contain this content is the line box (content-area). When line-height is set to 1, which is 100%, line-height is equal to the content area. In addition, line height is not the distance between font baselines.
Insert image description here

 Font type (font-family), different fonts have different default values ​​for line height, generally between 1 and 1.2. After changing the font type of the page, the paging algorithm needs to be re-executed.
The above are the three main factors that affect paging. Here is how to accurately paginate based on the chapter content passed from the backend. Let’s first talk about the implementation principle of paging. Paging actually uses a column attribute of CSS3 - columns. Column can split text between different columns. If we set each column to exactly one page, You can initially achieve the paging effect. Therefore, implementing paging is actually to calculate the maximum number of pages based on the word count of the chapter content passed from the backend (the last page is also counted as one page if it is not full), and then dynamically set the column-count of the html element that carries the text content. The attribute value is the maximum number of pages.
Insert image description here

To calculate the maximum number of pages based on the chapter content, first use regular rules to divide the chapter content into paragraphs of text according to the blank line character \n, then call wx.getSystemInfo to obtain the height and width information of the device, and calculate each paragraph of text separately according to the screen width. The maximum number of rows that can be occupied. Then use this number of lines multiplied by line-height to get the actual height of each paragraph of text. Add these actual heights, and then add the height of the blank line to get the total height of this chapter. Divide this height by the screen height. Rounding up and adding one gives the maximum number of pages. The following is the flow chart of the algorithm:
Insert image description here

Part of the source code is posted below:

function countPageNum(str, fontSize, lineHeight, windowW, windowH, pixelRatio) {
    
    
  var returnNum = 0;
  fontSize = fontSize / pixelRatio;
  lineHeight = lineHeight / pixelRatio;
  //将str根据’\n‘截成数组
  var strArray = str.split(/\n+/);
  var splitArray = [];
  var reg = new RegExp('\n+', 'igm');
  var result = '';
  //这里写一个for循环去记录每处分隔符的\n的个数,这将会影响到计算换行的高度
  while ((result = reg.exec(str)) != null) {
    
    
    splitArray.push(result.toString().match(/\n/img).length);
  }
  //spliArray比strArray少一,这里加一项使之数量一样
  splitArray.push(0);
  var totalHeight = 0;
  strArray.forEach(function (item, index) {
    
    
    //拒绝最后一项0
    var huanhangNum = (splitArray[index] - 1) > 0 ? (splitArray[index] - 1) > 0 : 0;
    totalHeight += Math.ceil(item.length / Math.floor((windowW - 80 / pixelRatio) / fontSize)) * lineHeight + huanhangNum * lineHeight;
  });
  return Math.ceil(totalHeight / windowH) + 1;
}

B. Performance issues
Although columns can initially simulate the paging effect, there are still many problems. First: the pages formed by columns are arranged continuously and can support sliding. operation, but it does not support the simulated page turning effect. Second: If there are too many columns, the performance will be poor (there will be obvious performance degradation after about 20 to 30 columns). Fortunately, the columns used are only the contents of one chapter, so in theory there won't be much performance problems.
C. How to detect user gestures
There are three user gestures supported by the reader. One is to click on the right side of the reader to turn back, and click on the left side to turn forward. The second is to swipe right on the touch screen to scroll back, and swipe left to scroll forward. The third is to tap the center of the screen to bring up the reader control bar. First, we bind the three events touchstart, touchmove, and touchend to the reading control. The three events are triggered sequentially in a touch screen event. These three events have an array of touches, which respectively contains the x coordinate of the touch screen start position. and y coordinates, the x coordinates and y coordinates of the current position when the touch screen slides, and the x coordinates and y coordinates of the end position of the touch screen.
For the first page turning operation, if touchmove is not triggered in a touch screen action, it is considered that the user clicked the screen, and then the distance between the click position and the left and right sides of the screen is compared. Determine whether the reader is turning pages forward or backward.
For the second page turning operation, under the premise that touchmove is triggered, compare the x coordinate of the starting position of the touch screen with the x coordinate of the current position during the touch screen sliding process. If the touch screen slides During the process, if the x-coordinate of the current position becomes larger, it is considered that the user has slid to the right, and the reader needs to turn the page forward. On the contrary, if the x-coordinate of the current position becomes smaller when the touch screen ends, it is considered that the user has slid to the left, and the reader needs to turn the page backward. Turn the page.

var currentX = event.touches[0].pageX;
var currentY = event.touches[0].pageY;
// 判断用没有滑动而是点击屏幕的动作
hasRunTouchMove = true;
var direction = 0;
if ((currentX - self.data.touches.lastX) < 0){
    
    
  direction = 0; // 左滑
}else if(((currentX - self.data.touches.lastX) > 0)){
    
    
  direction = 1; // 右滑
}

For the third type, detect whether the user clicks on the center of the screen, which is the user's operation to bring up the reader control bar. The principle is roughly the same as that of detecting the sliding direction. The difference is that the touch point position of touchstart used to detect the sliding direction is compared with the current touch point position coordinates of touchmove. The detection of whether the user clicks on the center of the screen is the comparison of the touch point position of touchstart and touchend. Comparison of the coordinates of the end position of the touch point. If the x coordinate difference and y coordinate difference are both within the tolerance range of the center point of the screen (the setting in the H5 reader is [-50rpx, 50rpx]), the user is considered to have clicked. In the center of the screen, hide or show the control bar based on whether the current control bar is already displayed.

// 判断用户的点击事件,决定是否显示控制栏
if(hasRunTouchMove == false){
    
    
  var y = self.data.touches.lastY;
  var x = self.data.touches.lastX;
  var h = self.data.windows.windows_height/2;
  var w = self.data.windows.windows_width/2;
  if(x && y && y >= (h-50) && y <= (h+50) && x >= (w-60) && x <= (w+60)){
    
    
    self.setData({
    
    control: {
    
    all: self.data.control.all == '0'? '1': '0', control_tab: 1, control_detail: 0, target: ''}, isShowFontSelector: 0});
    return;
  }
}

4.3.3 Implementation of left and right sliding page turning animation
As mentioned earlier, paging is actually using the column attribute to divide a large section of text into several columns. The width of each column is The width of the screen is one, so how to implement the animation of content slowly moving in from right to left when swiping left? First, we set the positioning of the HTML element carrying the chapter content to relative positioning, so that we can slide the content left or right by setting the left attribute of the element.
Insert image description here

The sliding animation has two parts. One is that during the touch screen process, the finger does not leave the screen and slides left and right. At this time, page turning will not be triggered, but the page needs to move the same distance as the finger slides. To achieve this effect, you only need to compare the distance between the finger touch point and the actual position of touchstart during the sliding process in the touchmove event, and increase or decrease the left value by the corresponding value. Once the finger leaves the screen, the touchend event is triggered and page turning begins.
The second is the page turning effect. Here we just implement a simple animation of slowly sliding from left to right to the specified position. The principle is also very simple, that is, using a js timer to set the value of left Slowly change from the starting value to the target value. The specific code is implemented as follows:

targetLeftValue = (-1) * self.data.windows.windows_width * currentIndex;
pingjunValue = Math.abs(targetLeftValue - self.data.leftValue) / 4;
//500ms其实函数只执行了4次,第一次会等待100ms才会开始函数
isMoving = 1; //开始计时的时候将标志置1
//使用计时器实现动画效果
moveTime = setInterval(function () {
    
    
  ++leftTimmerCount;
  var currentLeftValue = self.data.leftValue;
//如果达到了目标值,立即停止计时器
//调试发现有些时候这个if的跳转会莫名的不成立,所以做个限制,函数被执行了4次之后,无论条件是否成立,将leftValue设置为目标值,并结束计时器
  if (leftTimmerCount == 4) {
    
    
    clearInterval(moveTime);
    isMoving = 0;
    leftTimmerCount = 0;
    self.setData({
    
    leftValue: targetLeftValue});
    return;
  }
  if (currentLeftValue == targetLeftValue) {
    
    
    clearInterval(moveTime);
    isMoving = 0;
    leftTimmerCount = 0;
// console.log('向 左 滑动的计时器结束了,isMoving为0');
    return;
  }
  self.setData({
    
    leftValue: currentLeftValue - pingjunValue});
}, 75);

4.3.4 Reader style switching, font settings, and directory viewing
H5 reader defines four styles, day style, night style, eye protection mode, and coffee mode. You can choose your preferred reading style by tapping the center of the screen. Store the attribute values ​​that need to be adapted to the style in an attribute of data. When the user clicks to select the style, the correct style attribute value will be added to the corresponding wxml element. In addition, the icon color is switched using a sprite image. First, the icons of various styles are written as the class names of the sprite image, and then when the user selects the style, the class name of the icon element is changed to the class name of the corresponding style. The following are the attribute values ​​​​of some styles:

content_bg:页面背景,styleNum:样式编号, slider_bg:工具栏底色,control_fontColor:工具栏字体颜色
colorStyle: {
    
    content_bg: '#f5f9fc', styleNum:1, slider_bg: '#fd9941', slider_none_bg: '#dbdbdb', control_bg: '#ffffff', control_fontColor: '#fd9941'},
colorStyle: {
    
    content_bg: '#f5f0da', styleNum:2, slider_bg: '#a6832f', slider_none_bg: '#dbd6c3', control_bg: '#f8f3e0', control_fontColor: '#a6832f'},
colorStyle: {
    
    content_bg: '#c0edc6', styleNum:3, slider_bg: '#359112', slider_none_bg: '#a7ccab', control_bg: '#ccf1d0', control_fontColor: '#359112'},
colorStyle: {
    
    content_bg: '#1a1e21', styleNum:4, slider_bg: '#bb7333', slider_none_bg: '#212528', control_bg: '#101417', control_fontColor: '#bb7333'}}

The switching principle of font is the same as that of switching style. Let’s talk about the function of viewing the directory. Considering that a book may have many chapters, paging is required when viewing chapters. That is, each requested chapter only has 20 chapters before and after the current chapter. When the user turns to the 15th chapter after the current chapter, the next 40 chapters are loaded. Chapter to ensure smooth page turning. The front-end implementation of paging is actually done by the back-end interface. The back-end first retrieves all chapters of a certain book from the database in chapter order, and then returns the 20 chapters before and after this chapter based on the current chapter passed by the front-end.
4.3.1 Book details page interface design
4.3.2 Implementation of book review and like functions
Let’s talk about the like function first. It's relatively simple. You just need to add a field with the number of likes in the data structure of each comment. Every time the user likes the comment, add one to the field. The front-end switches the like icon to the liked state after the user likes it.
The implementation of book reviews is based on tree implementation. Let's first discuss how to store all the comments of a book, as shown in the figure below. Assume that the comment structure of a book is as shown in the figure below. We first convert the interface displayed on this page into the form of a tree. The root node of the tree represents this book. The direct child nodes of the root node are the book reviews that directly comment on this book. The other nodes under the direct child nodes are the user's replies to this book review.
Although the comment structure is converted into a tree structure, js does not recognize the tree structure, so in order to store these comments, we need to convert the tree into an array and store it in mongo. The most common method of storing trees in data structures is parent notation, that is, each node is numbered and stored in an array in order of numbers. Each item in the array has a field that records the number of the parent node of the current node, as follows As shown in the table of Fig. In addition, each book review in the array records the user ID, nickname, avatar address, comment time, book review content, and its parent node number (that is, who replied to it, the root node is -1) who posted the review.

"comments" : [
  {
    
    
    "commentid" : "141fd910-244e-11e7-9f8e-993ad69b9f3d",
    "userid" : "58f6321eb9bdeb2966753b20",
    "nickname" : "月光倾城",
    "avatar" :  "http://wx.qlogo.cn/mmopen/vi_32/SWkKED0AiblNkMpCibSWpicqtesj9sviaL2AHQEz9fibo5lRvfp7sICqjQ0z8WqpQUmFQHVjiafPfX2YpK8Y3lgKgk4Q/0?imageView2/1/w/60/h/60/format/jpg/interlace/1/q/75|imageslim",
    "time" : 1492530342177,
    "father" : "root",
    "content" : "好书,推荐",
    "likenum" : 0
  }
]

Insert image description here

Once stored, it needs to be retrieved. How to process the already stored comment array into a data format that is easy to use in the previous section? The looping of lists in WeChat mini programs is implemented through the wx;for instruction.

<view wx:for="{
    
    {[1, 2, 3, 4, 5, 6, 7, 8, 9]}}" wx:for-item="i">
  <view wx:for="{
    
    {[1, 2, 3, 4, 5, 6, 7, 8, 9]}}" wx:for-item="j">
    <view wx:if="{
    
    {i <= j}}">
      {
    
    {
    
    i}} * {
    
    {
    
    j}} = {
    
    {
    
    i * j}}
    </view>
  </view>
</view>

We can think of book reviews as two parts. The first part is a direct comment on a certain book, such as comment 1, comment 5, and comment 7. The other part is a reply to other people's comments, such as comment 2 and comment 3. When doing the display in the previous paragraph, the first choice is to display the comments that directly comment on a certain book, and then add a view more button under these comments to prompt the user to view the comments that replied to this comment. In this way, the format of the data that needs to be returned by the backend in the front end will be very clear. Comments need to be sorted according to the time when they were posted and the order of replies. Comments that reply to each other should be adjacent, and irrelevant comments should be sorted according to time.
Insert image description here

How to get the correct format of data by traversing the comment array in the database? The basic idea is to do two traversals. The first pass traverses the entire array, finds all direct child nodes, that is, the nodes with a father field of 0, removes these selected items to obtain a new subarray, and then for each direct child node Traverse the subarray and find all word comment nodes whose father is the direct child node. Search recursively until a node no longer contains child comment nodes.
Omitted

4.4 Bookstore module
4.4.1 Book details page interface design
4.4.2 Recommended topics and rankings
Weishu has placed a book recommendation topic in the bookstore. We will regularly place excellent books related to the topic in it. If the user happens to be interested in this topic, recommended topics can help the user find a large number of books of interest. The implementation principle is to create a separate table. In addition to storing the topic name, release time, and cover image, there is an array to store the book ID of the novel basic information table, representing all the books that appear in this topic. On the topic page, users can click on each book to view book details, or bookmark the topic. The collected topics will appear in the user's personal center, allowing users to browse to their previous books at any time even if the topic is not available. Collection of topics. To implement user favorite topics, it is also necessary to add a myTopic field in myAppUser to record user topic data
The ranking list refers to the Qidian novel ranking list and the Zongheng novel ranking list. Each of them They all include six categories of novels: general list, fantasy, history, romance, martial arts, and science and technology. The rankings under each category include the top ten novels in this category. There are not many difficulties in implementing the front-end of the ranking version. The data source of the ranking will be explained in detail in the next crawler.

4.5 Personal Center Module
4.5.1 Personal Center Interface Design
4.5.2 Personal Information
In order to reduce Except for the three required fields of password, username, and email address, the user input during registration does not need to be filled in. After user registration is completed, you can click on your avatar in the personal center to complete your personal information. The personal information page requires the backend to provide two interfaces, one is to obtain existing personal information getUserInfo, and the other is the interface updateUserInfo to update user information. The user's viewing and updating of information is not implemented in separate pages. Secondly, when the user enters the page for the first time, it is considered to be viewing personal information. Click the modify button at the bottom to switch to the state of modifying personal information. When the user clicks submit to submit the information, he will return. Check the status of personal information.
4.5.3 Personal settings
Personal settings mainly provide users with reader style settings, as well as common settings such as book update push and cache clearing. All these settings will be updated to the user's setting object after being changed. After entering the user's WeChat account, obtain these settings and apply them to reading.
4.5.4 My Messages
Personal messages are messages from other users in book reviews that reply to the current user. Weishu does not provide a direct chat function, but we will integrate it Comments and replies received and sent by users, and message prompts are given to users when they enter Weishu. Comment messages are stored in the comments field of the novel's basic information table. When there are many comments, it is unwise to search all comments to find user-related comments. You can submit and accept when the user publishes a book review. The ID of the user who commented and the content of the comment are entered into the user's personal message field. This ensures the timeliness of the message and avoids a large number of searches.

  1. Crawler
    All book information in Weishu is crawled from novel publishing websites. It is necessary to introduce the crawler implementation principle here. We divide Weishu's crawler into the following modules: crawler configuration, main program, data storage, and tool categories. The following is their detailed introduction:
  2. Crawler configuration
    The crawler configuration is config.js in the root directory. This js defines the link information of the database, the Qiniu cloud server configuration for uploading images, and the novel publishing website address and hosting The html element class name of key information. This is mainly to cope with the updates and revisions of the novel source site. The actual crawler code reads this information from the configuration. Once the origin site is revised, only these key information need to be revised, and the crawler can continue to execute.
var websiteConfig = [
  {
    
    
    factionName: '大主宰',
    des: 'xxxx',
    headerImage: 'http://qiniu.andylistudio.com/myblog/images/dazhuzai.jpg',
    author: '烟雨江南',
    allResources: [
      {
    
    
        sourceName: '爱下电子书',
        url: 'http://read.ixdzs.com/66/66485/',
        coreUrl: 'http://read.ixdzs.com/66/66485/',
        des: '爱下电子书-大主宰,再给出的页面中罗列了所有的小说章节,在爬取的时候得分不同的情况',
        firstSign: '.catalog .chapter > a',
        inWhatAttr: 'href',//链接存储的属性
        secondSign: '.content'
      }
    ]
  }
];
  1. Main program
    The main program is the core module of the crawler. It is divided into timing control module, search module, basic information crawling module, crawling chapter content module, and logging module< /span>
    Timing control module: Use the node-schedule package to control the crawler execution time. It is currently updated regularly at 6 o'clock every night. The following is the time definition format of node-schedule.

┬ ┬ ┬ ┬ ┬ ┬
│ │ │ │ │ |
│ │ │ │ │ └ day of week (0 - 7) (0 or 7 is Sun)
│ │ │ │ └───── month (1 - 12)
│ │ │ └────────── day of month (1 - 31)
│ │ └─────────────── hour (0 - 23)
│ └──────────────────── minute (0 - 59)
└───────────────────────── second (0 - 59, OPTIONAL)

Search module: When the crawler crawls books, the only parameter that needs to be passed is the name of the book. That is to say, as long as the book name is specified, the crawler will automatically find the book address, crawl its content, and store it in the database. The search module is used to find the address of the novel. The implementation principle is to use superagent to simulate search actions to find the most appropriate search results and get the address to access the book. There are two possible search results. One is a unique search result, that is, only one book with the same name is found through the source site. This will directly return the access address of the book. The other is a situation with multiple search results. For this kind of situation, we have added a new sub-crawler to crawl every book that matches the result, compare the popularity value of each book, and select the book with the highest popularity value as the search result. .
Omitted

  1. Basic information crawling module: used to obtain the book title, cover image, author, book description, and the address to access its chapter list. The principle is similar to search. Use superagent to simulate accessing the book address obtained by search, use cheerio to parse the obtained html, and then obtain the correct data from the Html element.
  2. Chapter list crawling module: The difference between the chapter list and the basic information module is that you need to use regular rules to filter out the number of chapters and chapter names of each chapter. Another difference is that you need to use eventproxy to concurrently crawl the content of each chapter. However, not every concurrent thread will return correctly. This requires good judgment and re-crawling failed chapters.
var sectionTitleReg = /(^\d+(\.)*( )*([零一二三四五六七八九十百千万0-9]+))|(^[零一二三四五六七八九十百千万0-9]+)|(^[零一二三四五六七八九十百千万])|(^\d+(\.)*[^零一二三四五六七八九十百千万0-9])/igm;
var matchResult = aText.match(sectionTitleReg);
//当且仅当titile通过正则检测,并且章节数大于最新章节数,才会被加到待访问队列中
if (matchResult != null && matchResult.length > 0) {
    
    
  allSections.push({
    
    
    sectionNum: chinese_parseInt(myAppTools.removeNaN(matchResult[0])),
    sectionTitle: aText.replace(sectionTitleReg, '').trim(),
    contentUrl: url + $element.attr('href')
  })
}
  1. Log module: This module mainly records the log output of the crawler execution and writes it to the local log file to facilitate the search for crawler execution errors. We use the logger tool. Here is a screenshot of the looger execution:

  2. Database operation module
    This module is mainly used to define the table structure, initialize the database, and store the crawler results. Use the mongoose database operation package to query, update, and delete data. This module does a lot of encapsulation of data operations. The following encapsulation functions:
    exports.configLog = configLog; // Configuration log
    exports.initDB = initDB ; // Initialize the database
    exports.saveFaction = saveFaction; // Store the crawled chapter content
    exports.updateSectionList = updateSectionList; // Update the chapter list< /span> exports.getSlipSection = getSlipSection; // Get discontinuous chapters exports. emptyFaction = emptyFaction; // Empty a novel exports.updateRank = updateRank; // Update the rankings
    exports.getNewestSectionNum = getNewestSectionNum; // Get the latest chapter


  3. Tool class
    This js packs some commonly used data manipulation functions, including removing duplicates, cloning objects, removing non-digits, connecting json objects, and comparing two jsons. Same etc.

2.1 Business level
The positioning of Weishu’s products is to meet the needs of users for free reading without downloading. The adapted user groups are mainly urban office workers. In their free time, they can use WeChat to read some of their favorite books without paying. The convenient experience and timely message reminders brought by WeChat mini programs allow users to understand them at the first time. The updated status of the book.
2.2 Product level
Weishu mainly consists of modules such as my bookshelf, bookstore, personal center, H5 reader, book details page, login and registration. In the design, the bottom tab switching recommended by the mini program is used. Orange is chosen as the main color for the overall color, and the left and right sliding animation is used for page switching. The product function structure diagram is shown in Figure 1:

Insert image description here

Figure 1. Product function structure diagram

2.3 Technical level
For the back-end, Weishu chose the loopback framework, which is very productive abroad. Loopback is a nodejs full-stack framework because there are already small programs as front-end technology. , so the framework mainly uses its API interface management and its interaction with the database mongo. In terms of databases, since the storage is mainly text data such as book chapters, using mongo to store these data is very convenient in database query, and mongo, as an unstructured database, has great advantages when storing relatively scattered data such as books. . In terms of front-end, the recently popular mini program is used as the main technology to implement the front end. The MVC-based architecture of the mini program and some APIs provided by WeChat make it the technical prerequisite for building large-scale applications. At the same time, its own convenience also makes it possible to build large-scale applications based on WeChat. Mini program products have more opportunities to be known and used.


5. Resource download

The source code and complete paper of this project are as follows. Friends in need can click to download. If the link does not work, you can click on the card below to scan the code and download it yourself.

serial number A complete set of graduation project resources (click to download)
Source code of this project Design and implementation of online bookstore based on nodejs+mongodb+WeChat applet (source code + documentation)_WeChat applet__Online bookstore.zip

6. More JAVA graduation project projects

Selected 83 sets of JAVA graduation projects - source code + complete resources of thesis

Guess you like

Origin blog.csdn.net/m0_66238867/article/details/131125946