{"id":17242922,"url":"https://github.com/imcuttle/book-shopping","last_synced_at":"2025-07-05T02:34:51.357Z","repository":{"id":45112928,"uuid":"61466053","full_name":"imcuttle/book-shopping","owner":"imcuttle","description":"书窝，基于node express4.x","archived":false,"fork":false,"pushed_at":"2022-01-07T14:39:02.000Z","size":12252,"stargazers_count":8,"open_issues_count":1,"forks_count":7,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-25T14:09:37.442Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/imcuttle.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-06-19T05:30:54.000Z","updated_at":"2022-09-30T01:42:51.000Z","dependencies_parsed_at":"2022-09-22T17:12:07.794Z","dependency_job_id":null,"html_url":"https://github.com/imcuttle/book-shopping","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/imcuttle/book-shopping","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/imcuttle%2Fbook-shopping","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/imcuttle%2Fbook-shopping/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/imcuttle%2Fbook-shopping/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/imcuttle%2Fbook-shopping/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/imcuttle","download_url":"https://codeload.github.com/imcuttle/book-shopping/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/imcuttle%2Fbook-shopping/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":263671802,"owners_count":23494042,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-15T06:14:24.140Z","updated_at":"2025-07-05T02:34:51.338Z","avatar_url":"https://github.com/imcuttle.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 图书销售系统 —— 书窝\n\n[**书窝线上地址**](http://bookshop.moyuyc.xyz)\n[**GitHub地址**](https://github.com/moyuyc/book-shopping)\n由于时间有限，事务较重，系统实现只好从简。\n\n---\n## 需求分析\n\u003e 需交课程设计报告和软件（源代码）。课程设计报告将存档。报告内容包括：需求分析、算法思想描述、数据流图、E-R图、数据字典、程序结构、收获与体会等。\n\u003e 功能要求：实现一个基于web的网上图书的销售管理系统，能提供多种条件的查询，还应具有会员管理、意见反馈、销售分析等功能。将留言板、图表分析、文件上传等思想纳入其中。\n\n\u003c!--more--\u003e\n### 用户系统\n 需要用户系统，用户是系统的根源，是数据的源头，该系统的用户就是要求中所说的会员，所以需要提供如下功能：\n+ 用户注册\n+ 用户登录\n+ 用户信息查看\n+ 用户既可以是卖家，亦可以是买家\n\n### 用户留言(信息反馈)\n为了逐渐完善系统，提供用户与建站者的交流通道，并且该通道不仅限于用户与建站者，用户与用户之间也能够互相交流，提高趣味性。具体功能如下：\n+ 用户留言\n+ 留言查看\n\n### 卖家买家系统\n买卖离不开卖家买家，该系统亦是如此，需要如下功能列表：\n- 卖家\n - 图书上架\n - 图书修改\n - 图书查看\n - 销售情况图表\n- 买家\n - 图书查看购买\n - 买书记录查看\n - 图书评论与删除\n\n---\n\n## 设计文档\n该部分将涉及整个系统从无到有的设计思路，自底向上有\n1. 数据库选择和设计\n2. 服务器框架选择和设计\n3. 前端框架选择和设计\n\n并且将针对具体细节给出相关表示，如数据字典，ER图，数据流图，算法设计等。\n### 数据库选择和设计\n#### 选择与原因\n该系统我选择了`MySQL`数据库，具体原因如下：\n1. `MySQL`十分轻量，相比课堂上讲的`SQL Server`数据库，一个安装包2GB，MySQL的500MB简直小巫见大巫（最近看到属于`NoSQL`的`MongoDB`居然只有100MB）。\n2. 短时间需要完成该系统，同时对于`MySQL`十分熟悉，之前做在线订票系统，在线考试系统等都是建立在MySQL上。\n3. 具有`SQLYog`这种强大方便的图形操作软件，轻松导入导出数据，轻松连接远程服务器传递数据。\n\n基于以上原因，因此选择了`MySQL`。\n#### 数据字典\n 用户\n\n| 字段 |类型|备注|\n|--|--|--|\n|username|varchar(12)|  用户名,唯一, 6-12位|\n|email|varchar(20)|电子邮箱,唯一|\n|password|varchar(12)|密码,6-12位|\n|registerDate|date |注册日期|\n 留言\n\n| 字段 |类型|备注|\n|--|--|--|\n|username|varchar(12)|留言者用户名|\n|content|text|留言内容|\n|datetime|datetime|留言时间|\n 图书\n\n| 字段 |类型|备注|\n|--|--|--|\n|bookID|char(8)|图书ID,唯一,如BK123456|\n|title|varchar(25)|书名|\n|author|varchar(25)|作者|\n|press|varchar(25)|出版社|\n|price|decimal(10,1)|价格,保留小数点后一位|\n|quantity|int(11)|库存量(本)|\n|image|mediumblob|封面图片|\n|seller|varchar(12)|卖家用户名|\n|importDate|date|上架日期|\n 图书评论\n\n| 字段 |类型|备注|\n|--|--|--|\n|username|varchar(12)|评论人用户名\n|bookID|char(8)|被评论图书|\n|datetime|datetime|评论时间|\n|content|text|评论内容|\n 交易\n**因为交易完成后，卖家仍然可以对图书进行修改，所以我将买进时图书信息都存放在此表中，表示买进时图书的信息。**\n\n| 字段 |类型|备注|\n|--|--|--|\n|tradeID|char(10)|交易记录ID,唯一,如TD12345678|\n|tradeDate|date|交易日期|\n|buyer|varchar(12)|买家用户名|\n|bookID|char(8)|书本ID|\n|title|varchar(25)|书名|\n|author|varchar(25)|作者|\n|press|varchar(25)|出版社|\n|price|decimal(10,1)|买进价格|\n|quantity|int(11)|库存|\n|image|mediumblob|封面|\n|seller|varchar(12)|卖家|\n\n#### E-R图\n![ER](./public/images/ER.png)\n\n### 服务器框架选择和设计\n#### 选择与原因\n作为`JS`动态语言的受益者，我服务器肯定就选择`nodejs`了。\n1. 未使用过`nodejs`开发一个相对完整的系统，打算就将该系统作为入门了。\n2. `nodejs`非常适合IO密集型的应用，采用的是异步事件队列的机制。\n3. `JS`语言简洁灵活有趣。\n\n#### `nodejs`与`express`\n- `nodejs`\n 基于ChromeV8引擎，以`JS`作为宿主语言的一个虚拟环境，`JS`于`NodeJs`可以看做是`Java`于`JVM`，`NodeJs`现在正在不断发展中，目标是与`Java`一样，能够形成一套十分完备的库，目前`NodeJs`的生态环境非常好，第三方模块层出不穷，而且由于`npm`，这些包是否方便管理与下载。\n- `express`\n介绍完`nodejs`，那么`express`是什么呢？`express`是`nodejs`的一个第三方Web框架，开发者可以用该框架非常方便有效的建立`HTTP`服务。\n\n#### 结构设计\n##### 文件结构\n![files](./public/images/files.png) \n`db/` 所有数据库操作代码\n`public/` 静态资源库，如js,css\n`routes/` 路由操作diam，对应url\n`utils/` 工具包代码\n`views/` Jade模板文件\n`app.js` 系统入口\n`mysql.sql` mysql数据文件，可导入\n\n##### 部分数据流图\n- 用户留言\n![用户留言](./public/images/datastream3.png)\n- 卖家添加图书\n![卖家添加图书](./public/images/datastream1.png)\n- 买家购书\n![买家购书](./public/images/datastream2.png)\n\n##### 部分算法设计\n首先对于留言评论，防止恶意用户刷留言评论，设置了定时销毁器。\n算法设计如下：\n```javascript\nvar _timer = {};\n\nvar Timer = {\n    set : function (key,mill) { //设置定时器的关键字与销毁时间\n        this.remove(key);\n        _timer[key] ={mill:mill};\n        _timer[key].code = setTimeout(function () {\n            delete _timer[key];\n        },mill);\n    },\n    isExist : function(key){\n        return !!_timer[key];\n    },\n    remove : function(key){\n        if(this.isExist(key)){\n            clearTimeout(_timer[key].code);\n            delete _timer[key];\n            return true;\n        }\n        return false;\n    }\n}\n```\n该系统具有销售分析，如某卖家所有销售情况的折线图，x轴表示日期，y轴表示该日售出书籍数目。\n算法设计如下：\n```javascript\n// all 表示所有卖家销售记录，0-N 时间从现在到以前\nfunction makeLineChart(all) {\n    if(all==null || all.length==0)\n        return;\n    //返回数据中 keys表示日期数组，data表示对应keys日期的销售量\n    return all.reduceRight((p,n)=\u003e{ // 从右向左归并\n        var date = n.tradeDate;\n        if(p.keys[p.keys.length-1]!=date){\n            p.keys.push(date);\n            p.data.push(1);\n        }else{\n            p.data[p.data.length-1]++;\n        }\n        return p;         \t\n    },{keys:[],data:[]});\n}\n```\n销售分析中还具有周最受欢迎图书饼图，表示一周内各个图书销售情况。\n算法设计如下：\n```javascript\n// all 表示所有卖家销售记录，0-N 时间从现在到以前\nfunction makePieChart(all) {\n    if(all==null || all.length==0)\n        return;\n    var pivot = all[all.length-1];  // 取出最后一个交易记录，也就是最近的\n    var end = new Date(pivot.tradeDate).setHours(24); // 根据最近时间的时间得到第二天0点时间\n    var start = new Date(end - 1000*60*60*24*7); // 减去7天毫秒数，得到七天前时间\n    var data = {keys:[pivot.title],data:[1]},titleMap = {};\n    titleMap[pivot.title]=0; //初始化参数\n    for(var i=all.length-2;i\u003e=0;i--){\n        if(new Date(all[i].tradeDate)\u003cstart) // 如果时间再七天之前，跳出循环\n            break;\n        var title = all[i].title;\n        if(titleMap[title]==null){\n            titleMap[title] = data.keys.length;\n            data.keys.push(title);\n            data.data.push(1);\n        }else\n            data.data[titleMap[title]]++;\n    }\n    return data;\n}\n```\n### 前端框架选择和设计\n#### 选择与原因\n针对于用户之间接触的前端界面，我选择了`Bootstrap3.0 UI`，`jQuery`，`marked.js`，`highlight.js`，`pace.js`，下面做出相关介绍与说明：\n- `BootStrap3.0` \n一套完备的UI框架，包括美观的css样式和一些基于jQuery的组件。可以让开发者用最少的时间建立一个美观的界面。\n- `jQuery`\n因为`BootStrap`组件需要，而且能够方便进行DOM操作，强大的选择器与链式调用。\n- `marked.js`\n一个将`markdown`文本翻译为HTML的库，api简单。\n- `highlight.js`\n与`marked.js`配套使用，能够将代码段解析为具有样式类的库。\n- `pace.js`\n通过检查浏览器加载的状态，判断文档加载进度，并且提供了一系列的css样式，能够在页面加载的时候显示页面加载进度。\n\n#### 文件结构\n```\npublic/\n├── javascripts/\n│   ├── addbook.js\n│   ├── Ajaxdelete.js\n│   ├── indexjs.js\n│   ├── msgAnimate.js\n│   ├── msgjs.js\n│   ├── popImage.js\n│   ├── search.js\n│   ├── selljs.js\n│   ├── utils.js\n└── stylesheets/\n    ├── bootstrap/\n    ├── style.less\n    ├── style.css\n    ├── hljs-github-min.css\n    └── markdown.less\n```\n`stylesheets/`文件夹放的是样式文件，其中的`style.less`是入口，`style.css`是利用node模块压缩后真正传送的样式文件\n#### 特殊功能说明\n1. 提示框动态固定显示\n![msg.png](./public/images/msg.png)\n方法一：（固定width）\n```less\n.messages{\n  .box-shadow(0px 0px 8px 3px #bbb);\n  z-index: 10000;\n  position: fixed;\n  width: 340px;\n  height: 50px;\n  left: 50%;\n  top : -50px;\n  margin-left: -170px;\n\n  -webkit-transition: all 2s;\n  -moz-transition: all 2s;\n  -ms-transition: all 2s;\n  -o-transition: all 2s;\n  transition: all 2s;\n  opacity:0;\n}\n```\n```js\nwindow.onload = function () {\n    $('.messages')\n        .css({'transform':'translate(0,120px)',opacity:1})\n}\n```\n方法二：width自适应\n```less\n.messages{\n  .box-shadow(0px 0px 8px 3px #bbb);\n  z-index: 10000;\n  position: fixed;\n  left: 50%;\n  top : 0px;\n  -webkit-transform: translate(-50%,-50%);\n  -moz-transform: translate(-50%,-50%);\n  -ms-transform: translate(-50%,-50%);\n  -o-transform: translate(-50%,-50%);\n  transform: translate(-50%,-50%);\n\n  -webkit-transition: all 2s;\n  -moz-transition: all 2s;\n  -ms-transition: all 2s;\n  -o-transition: all 2s;\n  transition: all 2s;\n  opacity:0;\n}\n```\n```js\nwindow.onload = function () {\n    $('.messages')\n        // .css({'transform':'translate(0,120px)',opacity:1})\n        .css({'margin-top':'140px',opacity:1})\n}\n```\n\n2. 跳至评论，评论区高亮\n![blink.png](./public/images/blink.png)\n```less\n@keyframes blinking {\n    0% {\n        //opacity: 0;\n    }\n    30%{\n        background-color: #fcf8e3;\n    }\n    100% {\n        background-color: #fcf8e3;\n        //opacity: 1;\n    }\n}\n.blink{\n    .animation(blinking 2.8s)\n}\n```\n```js\n$('[role=link-msg]').click(function (e) {\n        var x = $(this.hash).next().children().removeClass('blink')\n        setTimeout(function () {\n            x.addClass('blink').children('textarea').focus();\n        },0)\n    });\n```\n3. markdown编辑区可粘贴网络图片\n```js\ninput.onpaste = function (e) {\n        var clipboardData, pastedData;\n\n        // Get pasted data via clipboard API\n        clipboardData = e.clipboardData || window.clipboardData;\n        var text = clipboardData.getData('text/plain');\n        if(!text){\n            var img = clipboardData.getData('text/html');\n            img.replace(/\u003cimg.+src=\"(.+?)\"/g,(m,c)=\u003e{\n                e.preventDefault();\n                // 调用\n                document.execCommand('insertText', false, \"![ClipboardImage](\"+c+\")\");\n            })\n        }\n    };\n```\n4. 代码段右上角显示语言\n![prebefore.png](./public/images/prebefore.png)\n\n---\n\n## 系统截图\n![png](./public/images/p1.png)\n\n![png](./public/images/p2.png)\n\n![png](./public/images/p3.png)\n\n![png](./public/images/p4.png)\n\n![png](./public/images/p5.png)\n\n![png](./public/images/p6.png)\n\n![png](./public/images/p7.png)\n\n![png](./public/images/p8.png)\n\n![png](./public/images/p9.png)\n\n![png](./public/images/p10.png)\n\n---\n## 收获与体会\n- 感受到了`nodejs`与`express`的魅力\n- 增强了系统的整体把控架构能力\n- 掌握了一些常见具体问题的处理方式\n- 不足在于后端异步结构代码比较冗杂，难于管理\n\n## 参考资料\n- [nodejs express4.x 文件上传](http://www.cnblogs.com/kongxianghai/archive/2015/02/15/4293139.html)\n- [Jade 完整教程](http://jade-lang.com/reference/attributes/)\n- [page.js](http://www.jiawin.com/pace-js-automatic-page-load-progress-bar)\n- [javascript-get-clipboard-data-on-paste-event-cross-browser](http://stackoverflow.com/questions/2176861/javascript-get-clipboard-data-on-paste-event-cross-browser)\n- [www.haorooms.com/post/jq_js_xxjdt](http://www.haorooms.com/post/jq_js_xxjdt)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fimcuttle%2Fbook-shopping","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fimcuttle%2Fbook-shopping","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fimcuttle%2Fbook-shopping/lists"}