├── _image ├── 1.png ├── 2.png ├── 3.png ├── 4.png ├── 5.png ├── 6.png ├── 7.png ├── 8.png ├── 9.png ├── 10.png ├── 11.png ├── qr_code.png └── simple-logic.png ├── server ├── login │ ├── yunpian-sdk-php │ │ └── .readme │ ├── forget-password.php │ ├── update-userinfo.php │ ├── signup.php │ ├── get-auth-code.php │ └── login.php ├── get-help-message.php ├── submit-order.php ├── randomword.js ├── backend │ ├── js │ │ ├── manage.js │ │ ├── manual.js │ │ └── scan.js │ ├── css │ │ ├── manual.css │ │ ├── login.css │ │ ├── manage.css │ │ └── scan.css │ ├── index.html │ ├── manage.php │ ├── message.php │ └── operate.php ├── getdata.php └── database_details.sql ├── src ├── common │ ├── error.png │ ├── loading.gif │ ├── senddata.js │ ├── fullscreen.js │ └── getdata.js ├── router │ └── routes.js ├── components │ ├── login-css │ │ ├── login-signup.css │ │ ├── login-forget-password.css │ │ ├── login-userinfo.css │ │ ├── login-login.css │ │ └── login-normal.css │ ├── overlay.vue │ ├── container.vue │ ├── content │ │ ├── book-item.vue │ │ ├── book-card.vue │ │ └── content.vue │ ├── loading.vue │ ├── menu │ │ ├── help.vue │ │ ├── setting.vue │ │ ├── menu.vue │ │ └── book-list.vue │ ├── header.vue │ └── login.vue ├── main.js ├── vuex │ └── store.js └── app.vue ├── index.html ├── package.json ├── webpack.config.js ├── additional.md └── README.md /_image/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/percy507/vue-book/HEAD/_image/1.png -------------------------------------------------------------------------------- /_image/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/percy507/vue-book/HEAD/_image/2.png -------------------------------------------------------------------------------- /_image/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/percy507/vue-book/HEAD/_image/3.png -------------------------------------------------------------------------------- /_image/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/percy507/vue-book/HEAD/_image/4.png -------------------------------------------------------------------------------- /_image/5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/percy507/vue-book/HEAD/_image/5.png -------------------------------------------------------------------------------- /_image/6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/percy507/vue-book/HEAD/_image/6.png -------------------------------------------------------------------------------- /_image/7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/percy507/vue-book/HEAD/_image/7.png -------------------------------------------------------------------------------- /_image/8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/percy507/vue-book/HEAD/_image/8.png -------------------------------------------------------------------------------- /_image/9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/percy507/vue-book/HEAD/_image/9.png -------------------------------------------------------------------------------- /_image/10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/percy507/vue-book/HEAD/_image/10.png -------------------------------------------------------------------------------- /_image/11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/percy507/vue-book/HEAD/_image/11.png -------------------------------------------------------------------------------- /server/login/yunpian-sdk-php/.readme: -------------------------------------------------------------------------------- 1 | Put your yunpian-sdk-php files inside this folder. -------------------------------------------------------------------------------- /_image/qr_code.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/percy507/vue-book/HEAD/_image/qr_code.png -------------------------------------------------------------------------------- /src/common/error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/percy507/vue-book/HEAD/src/common/error.png -------------------------------------------------------------------------------- /src/common/loading.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/percy507/vue-book/HEAD/src/common/loading.gif -------------------------------------------------------------------------------- /_image/simple-logic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/percy507/vue-book/HEAD/_image/simple-logic.png -------------------------------------------------------------------------------- /src/router/routes.js: -------------------------------------------------------------------------------- 1 | const routes = [{ 2 | path: '/', 3 | redirect: '/home' 4 | }]; 5 | 6 | export default routes; -------------------------------------------------------------------------------- /src/components/login-css/login-signup.css: -------------------------------------------------------------------------------- 1 | .signup-page .form { 2 | padding-top: 20%; 3 | } 4 | 5 | .signup-page .return { 6 | position: absolute; 7 | z-index: 333; 8 | top: 20px; 9 | left: 20px; 10 | color: rgba(255, 255, 255, 0.6); 11 | font-size: 16px; 12 | } -------------------------------------------------------------------------------- /src/components/login-css/login-forget-password.css: -------------------------------------------------------------------------------- 1 | .forget-password-page .form { 2 | padding-top: 20%; 3 | } 4 | 5 | .forget-password-page .form-item:nth-last-child(1) input { 6 | color: #F79D2D; 7 | } 8 | 9 | .forget-password-page .return { 10 | position: absolute; 11 | z-index: 333; 12 | top: 20px; 13 | right: 20px; 14 | color: rgba(255, 255, 255, 0.6); 15 | font-size: 16px; 16 | } -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 | 6 | 7 | 8 |请使用手机打开此页面哦~
"; 19 | } 20 | }); 21 | 22 | Vue.use(VueRouter); 23 | 24 | Vue.use(VueLazyload, { 25 | preLoad: 1.3, 26 | error: './public/error.png', 27 | loading: './public/loading.gif', 28 | attempt: 1 29 | }); 30 | 31 | const router = new VueRouter({ 32 | routes 33 | }); 34 | 35 | new Vue({ 36 | router, 37 | store, 38 | render: h => h(App) 39 | }).$mount('#app'); 40 | 41 | 42 | /* 43 | // 通用的关闭页面时提示,对微信内置浏览器无效 44 | window.addEventListener("beforeunload", function() { 45 | var message = "你真的要离开吗?"; 46 | event.returnValue = message; 47 | return message; 48 | }, false); 49 | */ -------------------------------------------------------------------------------- /src/common/fullscreen.js: -------------------------------------------------------------------------------- 1 | // 兼容各个浏览器 2 | 3 | const launchFullscreen = function(element) { 4 | if (element.requestFullscreen) { 5 | element.requestFullscreen(); 6 | } else if (element.mozRequestFullScreen) { 7 | element.mozRequestFullScreen(); 8 | } else if (element.msRequestFullscreen) { 9 | element.msRequestFullscreen(); 10 | } else if (element.webkitRequestFullscreen) { 11 | element.webkitRequestFullScreen(); 12 | } 13 | }; 14 | 15 | const exitFullscreen = function() { 16 | if (document.exitFullscreen) { 17 | document.exitFullscreen(); 18 | } else if (document.msExitFullscreen) { 19 | document.msExitFullscreen(); 20 | } else if (document.mozCancelFullScreen) { 21 | document.mozCancelFullScreen(); 22 | } else if (document.webkitExitFullscreen) { 23 | document.webkitExitFullscreen(); 24 | } 25 | }; 26 | 27 | const registFullscreenChangeEvent = function(handler) { 28 | document.addEventListener("fullscreenchange", handler); 29 | document.addEventListener("webkitfullscreenchange", handler); 30 | document.addEventListener("mozfullscreenchange", handler); 31 | document.addEventListener("MSFullscreenChange", handler); 32 | }; 33 | 34 | export default { 35 | launch: launchFullscreen, 36 | exit: exitFullscreen, 37 | registChangeEvent: registFullscreenChangeEvent 38 | } -------------------------------------------------------------------------------- /src/components/content/book-item.vue: -------------------------------------------------------------------------------- 1 | 2 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 | ## Build Setup
34 |
35 | ``` bash
36 | # install dependencies
37 | npm install
38 |
39 | # serve with hot reload at localhost:8080
40 | npm run dev
41 |
42 | # build for production with minification
43 | npm run build
44 | ```
45 |
46 | > 我在本地测试用的服务器是 [WAMP Server](http://www.wampserver.com/en/)。
47 |
48 | 为了方便大家阅读源码,我列出了前后端数据交互时比较重要一些的接口,方便大家进行参考
49 |
50 | ## 项目目录说明
51 |
52 | ```bash
53 | Vue-book directory
54 | |
55 | ├── server # 存放服务端操作的文件夹
56 | | ├── backend
57 | | ├── css # 存放后台样式文件
58 | | ├── login.css # 登录后台页面的样式
59 | | ├── manage.css # 后台操作页面的一部分样式
60 | | ├── manual.css # 后台手动操作的样式
61 | | └── scan.css # 后台扫码操作的样式
62 | | ├── js
63 | | ├── manage.js # 进入管理界面的效果脚本
64 | | ├── manual.js # 后台手动操作的脚本
65 | | └── scan.js # 后台扫码操作的脚本
66 | | ├── index.html # 后台登录页面
67 | | ├── manage.php # 登录后台成功后返回的管理页面
68 | | ├── message.php # 后台更改前台公告的脚本
69 | | └── operate.php # 定义后台操作与数据库交互的逻辑
70 | | ├── login
71 | | ├── yunpian-sdk-php # 存放云片网的 SDK(外包短信服务)
72 | | ├── forget-password.php # 忘记密码时的后台脚本
73 | | ├── get-auth-code.php # 获取验证码时的后台脚本
74 | | ├── login.php # 前台登录时的后台验证脚本
75 | | ├── signup.php # 注册时的后台脚本
76 | | └── update-userinfo.php # 完善或更新个人信息时的后台脚本
77 | | ├── database_details.sql # 数据库表的定义
78 | | ├── randomword.js # 生成指定数量随机数据的脚本(测试时可用)
79 | | ├── get-help-message.php # 前端获取公告时的后端脚本
80 | | ├── getdata.php # 前端获取书籍时的后端脚本
81 | | └── submit-order.php # 前端提交书单(订单)的后端脚本
82 | ├── src # 存放前端源码
83 | | ├── common
84 | | ├── error.png # 图片加载失败时默认显示的图片
85 | | ├── fullscreen.js # 全屏显示脚本
86 | | ├── getdata.js # Ajax GET 获取数据脚本
87 | | ├── loading.gif # 图片加载中时默认显示的图片
88 | | └── senddata.js # Ajax POST 发送数据脚本
89 | | ├── components # 盛放各种组件
90 | | ├── content
91 | | ├── book-card.vue # 书籍详细信息
92 | | ├── book-item.vue # 书籍简要信息
93 | | └── content.vue # 内容块
94 | | ├── menu
95 | | ├── book-list.vue # 我的书单
96 | | ├── help.vue # 帮助
97 | | ├── menu.vue # 菜单
98 | | └── setting.vue # 设置
99 | | ├── login-css # 定义前台登录界面的 css
100 | | ├── login-forget-password.css
101 | | ├── login-login.css
102 | | ├── login-normal.css
103 | | ├── login-signup.css
104 | | └── login-userinfo.css
105 | | ├── login.vue # 前台登录
106 | | ├── container.vue # 大包含块
107 | | ├── header.vue # 页面头
108 | | ├── loading.vue # 载入中
109 | | └── overlay.vue # 覆盖层(显示侧边栏时出现)
110 | | ├── router
111 | | └── routes.js # 路由(好吧,好像我没怎么用)
112 | | └── vuex
113 | | └── store.js # Vuex 状态管理
114 | | ├── app.vue
115 | | ├── main.js # 程序入口文件
116 | ├── additional.md # 前后数据交互接口简要说明文件
117 | ├── index.html
118 | ├── package.json # 程序的相关依赖
119 | ├── README.md
120 | └── webpack.config.js # Webpack 配置相关信息
121 | ```
122 |
123 | ## 实现的功能
124 |
125 | * 前台用户手机验证码注册、登录以及忘记密码
126 | * 前台数据图片懒加载
127 | * 前台向后台请求数据时有数量限定(比如一次返回 20 条数据)
128 | * 搜索功能
129 | * sessionStorage 实现我的书单功能(类似购物车)
130 | * 使用时间戳以及 cookie 实现一小时内自动登录
131 | * 增加全屏显示菜单(因为项目在微信上用,所以全屏显示的代码先被注释掉了)
132 | * 扫条形码录入录出书籍(书籍信息基于豆瓣书籍 API)
133 | * 手动录入录出书籍
134 | * 后台登录更改公告信息
135 |
136 | ## 未解决问题
137 |
138 | * 切换内容页面时,自动滚动到内容最顶部(content.vue)
139 | * 退出页面时提示(浏览器上可以监听 beforeunload 事件,但是微信上不行)
140 |
141 | ## 心得与遗憾
142 |
143 | * 要是在写代码之前先认认真真地把项目各个模块的流程图(或逻辑流程图)先画出来的话,感觉写代码效率会大大提高。(或者说写代码之前先把产品整体的构思与架构先画个图表示出来)
144 | * 遗憾是,项目虽然引入了 vue-router,但是基本上没用到,整个页面都是基于事件开发出来的,没有路由,那就下个项目再用 vue-router 吧 ~
145 |
146 | ## Licence
147 |
148 | MIT Licence
149 |
--------------------------------------------------------------------------------
/server/backend/message.php:
--------------------------------------------------------------------------------
1 | 更新公告';
16 | } else {
17 | echo "wrong";
18 | }
19 | } elseif (isset($_POST['textarea'])) {
20 | $text = $_POST['textarea'];
21 |
22 | // 验证数据的合法性
23 | if (preg_match("/(select)|(delete)|(create)|(update)|(like)|(drop)/i", $text)) {
24 | echo "出现了非法关键词,请重新输入 ~";
25 | exit();
26 | };
27 |
28 | // 连接数据库
29 | $servername = "p:localhost";
30 | $username = "root";
31 | $password = "";
32 | $db_name = "qingong_db";
33 | $table_name = "qingong_message";
34 |
35 | // 创建与数据库系统的连接
36 | $mysqli = new mysqli($servername, $username, $password, $db_name);
37 |
38 | // 设置默认的客户端字符集
39 | $mysqli->set_charset("utf8");
40 |
41 | $sql = "INSERT INTO $table_name(message) VALUES('$text')";
42 |
43 | if ($mysqli->query($sql)) {
44 | echo "success";
45 | $mysqli->close();
46 | exit();
47 | } else {
48 | echo "未知错误 ~";
49 | $mysqli->close();
50 | exit();
51 | }
52 | } else {
53 | ?>
54 |
55 |
56 |
57 |
58 | ‸
176 |返回
177 |