├── .bowerrc ├── .editorconfig ├── .gitignore ├── LICENSE ├── README.md ├── bower.json ├── deploy.sh ├── package.json ├── src ├── components │ ├── empty.vue │ └── navigation.vue ├── index.template.html ├── main.js ├── store │ └── index.js └── views │ ├── 404.vue │ ├── advance │ ├── activity.vue │ ├── award.vue │ ├── cart.vue │ ├── coupon.vue │ ├── customize.vue │ ├── customize_decoration.vue │ ├── customize_house.vue │ ├── ecard.vue │ ├── ecard_intro.vue │ ├── ecard_vip.vue │ ├── plus.vue │ ├── qa.vue │ ├── record.vue │ ├── redpacket.vue │ ├── redpacket_rule.vue │ ├── reservation.vue │ ├── voucher.vue │ ├── voucher_detail.vue │ ├── wallet.vue │ └── wallet_record.vue │ ├── app.vue │ ├── config.js │ ├── flow │ ├── index.vue │ ├── order.vue │ ├── order_detail.vue │ ├── refund.vue │ ├── wait_delivery.vue │ ├── wait_evaluate.vue │ ├── wait_pay.vue │ └── wait_receive.vue │ └── own │ ├── address.vue │ ├── address_edit.vue │ ├── password.vue │ ├── phone_verify.vue │ └── setting.vue ├── static ├── images │ ├── 200x200.png │ ├── avatar.png │ └── icons │ │ ├── advance │ │ ├── activity.svg │ │ ├── award.svg │ │ ├── cart.svg │ │ ├── coupon.svg │ │ ├── customize.svg │ │ ├── ecard.svg │ │ ├── more.svg │ │ ├── qa.svg │ │ ├── record.svg │ │ ├── redpacket.svg │ │ ├── reservation.svg │ │ ├── voucher.svg │ │ └── wallet.svg │ │ ├── ask.svg │ │ ├── avatar.svg │ │ ├── circle-money.svg │ │ ├── circle-safe.svg │ │ ├── circle-ship.svg │ │ ├── flow │ │ ├── delivery.svg │ │ ├── evaluate.svg │ │ ├── pay.svg │ │ ├── receive.svg │ │ └── refund.svg │ │ ├── form-checkbox_checked.svg │ │ ├── form-checkbox_unchecked.svg │ │ ├── form-delete.svg │ │ ├── form-edit.svg │ │ ├── form-radio_checked.svg │ │ ├── form-radio_unchecked.svg │ │ ├── form-warn.svg │ │ ├── material-desktop.svg │ │ ├── material-tablet.svg │ │ └── vip.svg └── sass │ ├── _variable.scss │ ├── base │ └── _custom.scss │ ├── main.scss │ ├── pages │ ├── _alpha.scss │ ├── _ecard.scss │ ├── _home.scss │ ├── _info.scss │ └── _voucher.scss │ └── util │ ├── _button.scss │ ├── _ellipsis.scss │ ├── _form.scss │ ├── _grid.scss │ └── _icon.scss └── webpack.config.js /.bowerrc: -------------------------------------------------------------------------------- 1 | { 2 | "directory": "./bower_components" 3 | } 4 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | 2 | # EditorConfig is awesome: http://EditorConfig.org 3 | 4 | # top-most EditorConfig file 5 | root = true 6 | 7 | # Unix-style newlines with a newline ending every file 8 | [*] 9 | end_of_line = lf 10 | insert_final_newline = true 11 | 12 | # 4 space indentation 13 | [*.html] 14 | indent_style = space 15 | indent_size = 4 16 | 17 | # Indentation override for all JS under lib directory 18 | [*.js] 19 | indent_style = space 20 | indent_size = 2 21 | 22 | # charset (supported values: latin1, utf-8, utf-16be, utf-16le) 23 | [*] 24 | charset = utf-8 -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | .DS_Store 3 | .map 4 | /_draft 5 | 6 | /bower_components 7 | /build 8 | /release 9 | /node_modules 10 | /index.html 11 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # 单页面SPA with Vue.js 3 | 4 | ## Overview 5 | 6 | 基于 Vue.js框架部署的单页面web应用程序。 7 | 8 | 同时,模块以nodejs风格编码并使用ES6语法,显得编码更加简洁易懂。 9 | 10 | ## ES6 11 | 12 | 通过 babel 预编译 ES6 语法的js。而vue文件已经默认对ES6进行预编译。那么意味着可以通过ES6 语法来编写js和vue文件。见[babel](https://github.com/babel/babel-loader) 和 [vue-loader](https://github.com/vuejs/vue-loader) 配置和使用。 13 | 14 | ## SVG sprites 15 | 16 | 通过 webpack 的加载器 [svg-sprite-loader](https://github.com/kisenka/svg-sprite-loader) 引用svg文件。 17 | 18 | ## Usage 19 | 20 | ``` 21 | $ bower install # install bower package for first 22 | $ npm install # install npm package for first 23 | $ npm run build # build for dev 24 | 25 | $ NODE_ENV=production npm run build # build for product/release 26 | $ npm run server # go to the URL: http://localhost 27 | $ npm run watch # extra watch files 28 | ``` 29 | 30 | *Note: 对于本项目的自动发布流程脚本,大多数情况只适用当前部署环境 31 | 32 | ## Plugin 33 | 34 | - [vue-router](https://github.com/vuejs/vue-router) Vue.js 官方路由。与 Vue.js 内核深度整合,让构建单页应用易如反掌。 35 | - [vue-resource](https://github.com/vuejs/vue-resource) 通过 XMLHttpRequest 或 JSONP 发起请求并处理响应。 36 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "webapp-Vue", 3 | "description": "", 4 | "main": "index.js", 5 | "license": "ISC", 6 | "homepage": "", 7 | "moduleType": [], 8 | "ignore": [ 9 | "**/.*", 10 | "node_modules", 11 | "bower_components", 12 | "test", 13 | "tests", 14 | "./bower_components" 15 | ], 16 | "dependencies": { 17 | "vue": "~1.0.16", 18 | "vue-router": "~0.7.5", 19 | "vue-resource": "~0.1.17", 20 | "normalize-css": "~3.0.3" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /deploy.sh: -------------------------------------------------------------------------------- 1 | 2 | git checkout master 3 | 4 | NODE_ENV=production npm run build 5 | 6 | # cache the new files 7 | mkdir ./.temp 8 | mv ./index.html ./.temp/index.html 9 | mv ./release ./.temp/release 10 | 11 | # remove old files 12 | git checkout gh-pages && git pull -pf 13 | git rm ./index.html 14 | git rm -rf ./release 15 | git commit -m "ready to release" 16 | 17 | # use new files 18 | mv ./.temp/index.html ./index.html 19 | mv ./.temp/release ./ 20 | rmdir ./.temp 21 | 22 | git add ./index.html 23 | git add ./release/* 24 | 25 | git commit -am "release a beta" 26 | git push -u origin gh-pages:gh-pages 27 | 28 | # go back 29 | git checkout -f master 30 | 31 | echo "Enter exit..." 32 | read enter 33 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "i", 3 | "version": "1.0.0", 4 | "description": "make the SPA with Vue.js, vue-router", 5 | "main": "./src/main.js", 6 | "scripts": { 7 | "watch": "webpack --watch", 8 | "server": "webpack-dev-server --inline --port 80 --hot --quiet", 9 | "build": "webpack --progress --hide-modules" 10 | }, 11 | "author": "", 12 | "license": "ISC", 13 | "devDependencies": { 14 | "babel-core": "^6.6.5", 15 | "babel-loader": "^6.2.4", 16 | "babel-preset-es2015": "^6.6.0", 17 | "babel-runtime": "^5.8.35", 18 | "css-loader": "^0.23.1", 19 | "extract-text-webpack-plugin": "^0.9.1", 20 | "file-loader": "^0.8.5", 21 | "html-webpack-plugin": "^2.9.0", 22 | "image-webpack-loader": "^1.6.3", 23 | "node-sass": "^3.4.2", 24 | "sass-loader": "^3.1.2", 25 | "style-loader": "^0.13.0", 26 | "svg-sprite-loader": "0.0.18", 27 | "vue-hot-reload-api": "^1.3.2", 28 | "vue-loader": "^8.2.2", 29 | "vue-style-loader": "^1.0.0", 30 | "webpack": "^1.12.14", 31 | "webpack-dev-server": "^1.14.1" 32 | }, 33 | "repository": { 34 | "type": "git", 35 | "url": " " 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/components/empty.vue: -------------------------------------------------------------------------------- 1 | 2 | 28 | 29 | 42 | 43 | 70 | -------------------------------------------------------------------------------- /src/components/navigation.vue: -------------------------------------------------------------------------------- 1 | 2 | 21 | 22 | 33 | 34 | 47 | -------------------------------------------------------------------------------- /src/index.template.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 我的家 6 | {{htmlHead.title}} - 我的家 7 | 45 | 46 | 47 | <% for(var i=0; i < htmlWebpackPlugin.files.css.length; ++i){ %> 48 | 49 | <% } %> 50 | 51 | 52 | 53 | 54 |
55 | 60 |
61 |

个人中心

62 |

{{htmlHead.title}}

63 |
64 | 69 |
70 | 71 |
72 |

Loading...

73 |
74 | 75 | 78 | 79 | 80 | <% for(var i=0; i < htmlWebpackPlugin.files.js.length; ++i){ %> 81 | 82 | <% } %> 83 | 84 | 85 | 95 | 96 | 97 | -------------------------------------------------------------------------------- /src/main.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | // just for style 4 | require("../static/sass/main.scss"); 5 | 6 | import Vue from "vue" 7 | import VueRouter from "vue-router" 8 | import VueResource from "vue-resource" 9 | import configRouter from "./views/config" 10 | import store from "./store/" 11 | 12 | // true => just for debug 13 | Vue.config.debug = false; 14 | 15 | // install plugin 16 | Vue.use(VueRouter); 17 | Vue.use(VueResource); 18 | 19 | var router = new VueRouter({ 20 | history: false, 21 | // saveScrollPosition: true, // just for history: true 22 | }); 23 | 24 | configRouter(Vue, router); 25 | 26 | var userApp = Vue.extend({ 27 | data(){ 28 | return store.getData() 29 | }, 30 | methods: { 31 | goBack(){ 32 | history.back() 33 | } 34 | } 35 | }); 36 | 37 | // start router 38 | router.start(userApp,"html"); 39 | 40 | // just for debugging 41 | window.router = router 42 | -------------------------------------------------------------------------------- /src/store/index.js: -------------------------------------------------------------------------------- 1 | 2 | let data = { 3 | year: new Date().getFullYear(), 4 | htmlHead: { 5 | title: "我的家" 6 | } 7 | } 8 | 9 | export default { 10 | getData(){ 11 | return data; 12 | }, 13 | // setHtmlHead(options){ 14 | // data.htmlHead = _.extend(data.htmlHead, options) 15 | // }, 16 | setHtmlTitle(val){ 17 | data.htmlHead.title = !!val ? val : data.htmlHead.title 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/views/404.vue: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 23 | -------------------------------------------------------------------------------- /src/views/advance/activity.vue: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 41 | -------------------------------------------------------------------------------- /src/views/advance/award.vue: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 39 | -------------------------------------------------------------------------------- /src/views/advance/cart.vue: -------------------------------------------------------------------------------- 1 | 2 | 27 | 28 | 93 | 94 | 222 | -------------------------------------------------------------------------------- /src/views/advance/coupon.vue: -------------------------------------------------------------------------------- 1 | 2 | 28 | 29 | 67 | -------------------------------------------------------------------------------- /src/views/advance/customize.vue: -------------------------------------------------------------------------------- 1 | 2 | 56 | 57 | 77 | -------------------------------------------------------------------------------- /src/views/advance/customize_decoration.vue: -------------------------------------------------------------------------------- 1 | 2 | 48 | 49 | 87 | -------------------------------------------------------------------------------- /src/views/advance/customize_house.vue: -------------------------------------------------------------------------------- 1 | 2 | 49 | 50 | 87 | -------------------------------------------------------------------------------- /src/views/advance/ecard.vue: -------------------------------------------------------------------------------- 1 | 2 | 14 | 15 | 68 | 69 | 110 | -------------------------------------------------------------------------------- /src/views/advance/ecard_intro.vue: -------------------------------------------------------------------------------- 1 | 2 | 61 | 62 | 111 | -------------------------------------------------------------------------------- /src/views/advance/ecard_vip.vue: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 44 | 45 | 74 | -------------------------------------------------------------------------------- /src/views/advance/plus.vue: -------------------------------------------------------------------------------- 1 | 2 | 18 | 19 | 29 | -------------------------------------------------------------------------------- /src/views/advance/qa.vue: -------------------------------------------------------------------------------- 1 | 2 | 41 | 42 | 60 | 61 | 87 | -------------------------------------------------------------------------------- /src/views/advance/record.vue: -------------------------------------------------------------------------------- 1 | 2 | 16 | 17 | 43 | 44 | 122 | -------------------------------------------------------------------------------- /src/views/advance/redpacket.vue: -------------------------------------------------------------------------------- 1 | 2 | 30 | 31 | 60 | 61 | 104 | -------------------------------------------------------------------------------- /src/views/advance/redpacket_rule.vue: -------------------------------------------------------------------------------- 1 | 2 | 21 | 22 | 33 | -------------------------------------------------------------------------------- /src/views/advance/reservation.vue: -------------------------------------------------------------------------------- 1 | 2 | 28 | 29 | 39 | -------------------------------------------------------------------------------- /src/views/advance/voucher.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 34 | 35 | 72 | -------------------------------------------------------------------------------- /src/views/advance/voucher_detail.vue: -------------------------------------------------------------------------------- 1 | 2 | 86 | 87 | 101 | -------------------------------------------------------------------------------- /src/views/advance/wallet.vue: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 22 | -------------------------------------------------------------------------------- /src/views/advance/wallet_record.vue: -------------------------------------------------------------------------------- 1 | 2 | 13 | 14 | 48 | -------------------------------------------------------------------------------- /src/views/app.vue: -------------------------------------------------------------------------------- 1 | 2 | 247 | 248 | 308 | -------------------------------------------------------------------------------- /src/views/config.js: -------------------------------------------------------------------------------- 1 | 2 | export default function(Vue, router){ 3 | router.map({ 4 | "/": { 5 | // name: "home", 6 | component: require("./app.vue") 7 | }, 8 | 9 | // own 10 | "/own": { 11 | name: "own", 12 | component: Vue.extend({template: ""}), 13 | subRoutes: { 14 | 15 | "/": { component: require("./own/setting.vue") }, 16 | 17 | "/password": { 18 | name: "password", 19 | component: require("./own/password.vue") 20 | }, 21 | 22 | "/verify": { 23 | name: "verify", 24 | component: require("./own/phone_verify.vue") 25 | }, 26 | 27 | "/address": { 28 | name: "address", 29 | component: Vue.extend({template: ""}), 30 | subRoutes: { 31 | "/": { component:require("./own/address.vue") }, 32 | "/edit": { component:require("./own/address_edit.vue") }, 33 | "/new": { component:require("./own/address_edit.vue") } 34 | } 35 | }, 36 | 37 | } 38 | }, 39 | 40 | // flow 41 | "/flow": { 42 | name: "flow", 43 | // component: Vue.extend({template: ""}), 44 | component: require("./flow/index.vue"), 45 | subRoutes: { 46 | 47 | "/order": { 48 | name: "order", 49 | component: Vue.extend({template: ""}), 50 | subRoutes: { 51 | "/": { component: require("./flow/order.vue") }, 52 | "/:id/detail": { component: require("./flow/order_detail.vue") } 53 | } 54 | }, 55 | 56 | "/refund": { 57 | name: "refund", 58 | component: require("./flow/refund.vue") 59 | }, 60 | 61 | "/wait/delivery": { 62 | name: "delivery", 63 | component: require("./flow/wait_delivery.vue") 64 | }, 65 | 66 | "/wait/evaluate": { 67 | name: "evaluate", 68 | component: require("./flow/wait_evaluate.vue") 69 | }, 70 | 71 | "/wait/pay": { 72 | name: "pay", 73 | component: require("./flow/wait_pay.vue") 74 | }, 75 | 76 | "/wait/receive": { 77 | name: "receive", 78 | component: require("./flow/wait_receive.vue") 79 | }, 80 | 81 | /*"/wait": { 82 | name: "wait", 83 | component: Vue.extend({template: ""}), 84 | subRoutes: { 85 | "/delivery": { component: require("./flow/wait_delivery.vue") }, 86 | "/pay": { component: require("./flow/wait_pay.vue") }, 87 | "/receive": { component: require("./flow/wait_receive.vue") }, 88 | } 89 | },*/ 90 | 91 | } 92 | }, 93 | 94 | // advance 95 | "/av": { 96 | name: "advance", 97 | component: Vue.extend({template: ""}), 98 | subRoutes: { 99 | 100 | "/activity": { 101 | name: "activity", 102 | component: require("./advance/activity.vue") 103 | }, 104 | 105 | "/award": { 106 | name: "award", 107 | component: require("./advance/award.vue") 108 | }, 109 | 110 | "/cart": { 111 | name: "cart", 112 | component: require("./advance/cart.vue") 113 | }, 114 | 115 | "/coupon": { 116 | name: "coupon", 117 | component: require("./advance/coupon.vue") 118 | }, 119 | 120 | "/customize": { 121 | name: "customize", 122 | component: Vue.extend({template: ""}), 123 | subRoutes: { 124 | "/": { component: require("./advance/customize.vue") }, 125 | "/edit/house": { 126 | name: "house", 127 | component: require("./advance/customize_house.vue") 128 | }, 129 | "/edit/decoration":{ 130 | name: "decoration", 131 | component: require("./advance/customize_decoration.vue") 132 | } 133 | } 134 | }, 135 | 136 | "/ecard": { 137 | name: "ecard", 138 | component: Vue.extend({template: ""}), 139 | subRoutes: { 140 | "/": { 141 | component: require("./advance/ecard.vue") 142 | }, 143 | "/vip": { 144 | component: require("./advance/ecard_vip.vue") 145 | }, 146 | "/intro/:type": { 147 | name: "intro", 148 | component: require("./advance/ecard_intro.vue") 149 | } 150 | } 151 | }, 152 | 153 | "/plus": { 154 | name: "plus", 155 | component: require("./advance/plus.vue") 156 | }, 157 | 158 | "/qa": { 159 | name: "QA", 160 | component: require("./advance/qa.vue") 161 | }, 162 | 163 | "/record": { 164 | name: "record", 165 | component: require("./advance/record.vue") 166 | }, 167 | 168 | "/redpacket": { 169 | name: "redpacket", 170 | component: Vue.extend({template: ""}), 171 | subRoutes: { 172 | "/": { component: require("./advance/redpacket.vue") }, 173 | "/rule": { 174 | name: "rule", 175 | component: require("./advance/redpacket_rule.vue") 176 | } 177 | } 178 | 179 | }, 180 | 181 | "/reservation": { 182 | name: "reservation", 183 | component: require("./advance/reservation.vue") 184 | }, 185 | 186 | "/voucher": { 187 | name: "voucher", 188 | component: Vue.extend({template: ""}), 189 | subRoutes: { 190 | "/": { 191 | component: require("./advance/voucher.vue") 192 | }, 193 | "/detail/:barcode": { 194 | name: "detail", 195 | component: require("./advance/voucher_detail.vue") 196 | } 197 | } 198 | }, 199 | 200 | "/wallet": { 201 | name: "wallet", 202 | component: Vue.extend({template: ""}), 203 | subRoutes: { 204 | "/": { 205 | component: require("./advance/wallet.vue") 206 | }, 207 | "/record": { 208 | component: require("./advance/wallet_record.vue") 209 | } 210 | } 211 | }, 212 | 213 | } 214 | }, 215 | 216 | "*": { component: require("./404.vue") } 217 | }); 218 | 219 | } 220 | -------------------------------------------------------------------------------- /src/views/flow/index.vue: -------------------------------------------------------------------------------- 1 | 2 | 12 | 13 | 20 | 21 | 39 | -------------------------------------------------------------------------------- /src/views/flow/order.vue: -------------------------------------------------------------------------------- 1 | 21 | 22 | 46 | 47 | 80 | -------------------------------------------------------------------------------- /src/views/flow/order_detail.vue: -------------------------------------------------------------------------------- 1 | 2 | 26 | 27 | 38 | -------------------------------------------------------------------------------- /src/views/flow/refund.vue: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 40 | -------------------------------------------------------------------------------- /src/views/flow/wait_delivery.vue: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 40 | -------------------------------------------------------------------------------- /src/views/flow/wait_evaluate.vue: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 40 | -------------------------------------------------------------------------------- /src/views/flow/wait_pay.vue: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 13 | 41 | -------------------------------------------------------------------------------- /src/views/flow/wait_receive.vue: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 40 | -------------------------------------------------------------------------------- /src/views/own/address.vue: -------------------------------------------------------------------------------- 1 | 2 | 36 | 37 | 102 | -------------------------------------------------------------------------------- /src/views/own/address_edit.vue: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 23 | -------------------------------------------------------------------------------- /src/views/own/password.vue: -------------------------------------------------------------------------------- 1 | 2 | 31 | 32 | 67 | -------------------------------------------------------------------------------- /src/views/own/phone_verify.vue: -------------------------------------------------------------------------------- 1 | 2 | 33 | 34 | 93 | 94 | 139 | -------------------------------------------------------------------------------- /src/views/own/setting.vue: -------------------------------------------------------------------------------- 1 | 2 | 72 | 73 | 115 | -------------------------------------------------------------------------------- /static/images/200x200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imjeen/i/79415f1957917af41c5a7b5dace8dd677d727e37/static/images/200x200.png -------------------------------------------------------------------------------- /static/images/avatar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imjeen/i/79415f1957917af41c5a7b5dace8dd677d727e37/static/images/avatar.png -------------------------------------------------------------------------------- /static/images/icons/advance/activity.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /static/images/icons/advance/award.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /static/images/icons/advance/cart.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /static/images/icons/advance/coupon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /static/images/icons/advance/customize.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /static/images/icons/advance/ecard.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /static/images/icons/advance/more.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /static/images/icons/advance/qa.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /static/images/icons/advance/record.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /static/images/icons/advance/redpacket.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /static/images/icons/advance/reservation.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /static/images/icons/advance/voucher.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /static/images/icons/advance/wallet.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /static/images/icons/ask.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /static/images/icons/avatar.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /static/images/icons/circle-money.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /static/images/icons/circle-safe.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /static/images/icons/circle-ship.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /static/images/icons/flow/delivery.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /static/images/icons/flow/evaluate.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /static/images/icons/flow/pay.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /static/images/icons/flow/receive.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /static/images/icons/flow/refund.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /static/images/icons/form-checkbox_checked.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /static/images/icons/form-checkbox_unchecked.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /static/images/icons/form-delete.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /static/images/icons/form-edit.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /static/images/icons/form-radio_checked.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /static/images/icons/form-radio_unchecked.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /static/images/icons/form-warn.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /static/images/icons/material-desktop.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /static/images/icons/material-tablet.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /static/images/icons/vip.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /static/sass/_variable.scss: -------------------------------------------------------------------------------- 1 | 2 | 3 | // pixel per rem 4 | $ppr: 720px / 16 / 1rem; 5 | -------------------------------------------------------------------------------- /static/sass/base/_custom.scss: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | 3 | :root{ 4 | font-size: $ppr * 1rem; 5 | } 6 | 7 | html{ 8 | height: 100%; 9 | font-family: "Microsoft YaHei", "Helvetical"; 10 | } 11 | 12 | body{ 13 | background-color: #f6f6f6; 14 | font-size: 14px/$ppr; 15 | min-height: 100%; 16 | min-height: 100vh; 17 | } 18 | 19 | h1,h2,h3,h4,h5, 20 | dl,dt,dd, 21 | p, 22 | figure{ 23 | margin: 0; 24 | } 25 | 26 | ul,ol,li{ 27 | list-style: none; 28 | padding: 0; 29 | margin: 0; 30 | } 31 | 32 | input,textarea{ 33 | font-family: inherit; 34 | font-size: 100%; 35 | width: inherit; 36 | box-sizing: border-box; 37 | margin: 0; 38 | padding: 0; 39 | border: 0; 40 | outline: none 0; 41 | vertical-align: baseline; 42 | font-weight: 500; 43 | -webkit-tap-highlight-color: rgba(0, 0, 0, 0); 44 | } 45 | 46 | 47 | *, 48 | *:before,*:after{ 49 | box-sizing: border-box; 50 | } 51 | 52 | .cf{ zoom: 1; } 53 | .cf:before, 54 | .cf:after{ 55 | content: ""; 56 | display: table; 57 | } 58 | .cf:after{ 59 | clear: both; 60 | overflow: hidden; 61 | } 62 | 63 | .text-center{ text-align: center; } 64 | 65 | a{ text-decoration: none;} 66 | 67 | 68 | .height-inherit{ 69 | height: inherit; 70 | } 71 | 72 | .table-center-wrap{ 73 | display: table; 74 | table-layout: fixed; 75 | .table-center{ 76 | display: table-cell; 77 | vertical-align: middle; 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /static/sass/main.scss: -------------------------------------------------------------------------------- 1 | 2 | /*base style*/ 3 | @import "../../bower_components/normalize-css/normalize.css"; 4 | 5 | /*variable*/ 6 | @import "variable"; 7 | 8 | /*base style*/ 9 | @import "base/custom"; 10 | 11 | /* util */ 12 | @import "util/grid"; 13 | @import "util/ellipsis"; 14 | @import "util/button"; 15 | @import "util/icon"; 16 | @import "util/form"; 17 | 18 | /* pages */ 19 | @import "pages/alpha"; 20 | @import "pages/home"; 21 | @import "pages/info"; 22 | @import "pages/ecard"; 23 | @import "pages/voucher"; 24 | -------------------------------------------------------------------------------- /static/sass/pages/_alpha.scss: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | 3 | .header{ 4 | box-shadow: 0 1px 3px rgba(0,0,0,.14); 5 | background: hsla(0,0%,100%,.9); 6 | position: relative; 7 | line-height: 45px/$ppr; 8 | height: 45px/$ppr; 9 | 10 | h1{ font-size: 24px/$ppr; } 11 | 12 | } 13 | 14 | .footer{ 15 | height: 50px/$ppr; 16 | background: #efefef; 17 | padding-top: 10px/$ppr; 18 | .footer__copyright{ 19 | color: #aaa9a9; 20 | text-align: center; 21 | padding: 10px/$ppr; 22 | } 23 | } 24 | 25 | 26 | .jumbotron-main{ 27 | margin: auto; 28 | max-width: 540px/$ppr; 29 | min-height: calc(100vh - #{45px/$ppr} - #{50px/$ppr}); 30 | } 31 | 32 | .normal-layer{ 33 | background-color: #fff; 34 | margin-bottom: 12px/$ppr; 35 | padding: 0 12px/$ppr; 36 | border-top: 1px solid #DEDEDE; 37 | border-bottom: 1px solid #DEDEDE; 38 | 39 | &.no-padding-layer{ padding: 0; } 40 | 41 | &.no-border-layer{ border: none; } 42 | 43 | &.inherit-background-layer{ background-color: inherit; } 44 | 45 | &:first-of-type{ border: none; } 46 | 47 | &:last-of-type{ 48 | margin-bottom: 0; 49 | } 50 | 51 | } 52 | 53 | // -------------------------------- 54 | // just for list feature item 55 | // -------------------------------- 56 | .feature-list{ 57 | 58 | .tip-right{ float: right; } 59 | .text-gray{ color: #999; } 60 | .text-black{ color: #000; } 61 | 62 | .feature-item-title{ 63 | color: #666; 64 | border-bottom: 1px solid #eee; 65 | } 66 | 67 | .inner-bar{ 68 | padding: 14px/$ppr 12px/$ppr; 69 | display: block; 70 | &.select-bar{ 71 | position: relative; 72 | display: block; 73 | select{ 74 | position: absolute; 75 | top: 0; 76 | right: 0; 77 | bottom: 0; 78 | left: 0; 79 | opacity: 0; 80 | width: 100%; 81 | } 82 | } 83 | &.label-bar{ 84 | position: relative; 85 | display: block; 86 | .label-field{ 87 | position: absolute; 88 | top: 0; 89 | right: 0; 90 | bottom: 0; 91 | left: 0; 92 | opacity: 0; 93 | width: 100%; 94 | } 95 | } 96 | } 97 | 98 | @at-root{ 99 | // gap 100 | .border-gap-list .feature-item{ 101 | border-bottom: 1px solid #eee; 102 | &:last-of-type{ border-bottom: 0; } 103 | } 104 | 105 | // active 106 | .interaction-list .feature-item:not(.no-interaction-item):active{ 107 | -webkit-tap-highlight-color: rgba(0, 0, 0, 0); 108 | background-color: #f0f0f0; 109 | } 110 | 111 | } 112 | 113 | } 114 | 115 | // -------------------------------- 116 | // ticket list 117 | // -------------------------------- 118 | 119 | $ticket-color-maps: ( 120 | gold: #F3D430, 121 | red: #EC274C, 122 | gray: #A7A5A5, 123 | ); 124 | 125 | .ticket-list{ 126 | .ticket-item{ 127 | background-color: #fff; 128 | margin: 10px/$ppr 0; 129 | /* box-shadow: 5px/$ppr 2px/$ppr 4px/$ppr -1px/$ppr rgba(0, 0, 0, 0.2); */ 130 | } 131 | .ticket-figure{ 132 | 133 | background-size: 06px/$ppr 12px/$ppr ; 134 | background-repeat: repeat-y; 135 | position: relative; 136 | min-height: 80px/$ppr; 137 | 138 | @each $ticket-keyword, $ticket-color in $ticket-color-maps{ 139 | 140 | &.ticket-figure--#{$ticket-keyword}{ 141 | color: #fff; 142 | background-color: $ticket-color; 143 | background-image: radial-gradient(circle at left, #efefef 50%, $ticket-color 50%); 144 | } 145 | 146 | } 147 | 148 | strong{ 149 | display: flex; 150 | justify-content: center; 151 | align-items: center; 152 | position: absolute; 153 | height: 100%; 154 | width: 100%; 155 | font-size: 30px/$ppr; 156 | } 157 | } 158 | .ticket-caption{ 159 | padding: 10px/$ppr; 160 | text-align: center; 161 | } 162 | h2{ margin-bottom: 5px/$ppr } 163 | } 164 | -------------------------------------------------------------------------------- /static/sass/pages/_ecard.scss: -------------------------------------------------------------------------------- 1 | 2 | 3 | @charset "UTF-8"; 4 | 5 | .ecard-feature-list{ 6 | .inner-bar{ padding: 08px/$ppr 12px/$ppr;} 7 | } 8 | 9 | // open vip 10 | .ecard-vip-form{ 11 | .field-title{ 12 | font-size: 12px/$ppr; 13 | padding: 0 12px/$ppr; 14 | margin-top: 12px/$ppr; 15 | margin-bottom: 12px/$ppr; 16 | } 17 | .ecard-input-field{ 18 | display: block; 19 | position: relative; 20 | margin-bottom: 12px/$ppr; 21 | padding: 12px/$ppr 12px/$ppr 12px/$ppr 42px/$ppr; 22 | border-top: 1px solid #e0e0e0; 23 | border-bottom: 1px solid #e0e0e0; 24 | background-color: #fff; 25 | input{ width: 100%; } 26 | .svg-icon{ 27 | color: #D00; 28 | font-size: 18px/$ppr; 29 | position: absolute; 30 | top: 50%; 31 | left: 0; 32 | margin-left: 12px/$ppr; 33 | transform: translateY(-50%); 34 | } 35 | } 36 | } 37 | 38 | // list rule for ecard 39 | .ecard-rule-list{ 40 | .item-title{ 41 | font-size: 12px/$ppr; 42 | border-bottom: 1px solid #e2e2e2; 43 | background-color: #efefef; 44 | padding: 07px/$ppr 10px/$ppr; 45 | line-height: 22px/$ppr; 46 | } 47 | .item-desc{ 48 | background-color: #fff; 49 | padding: 06px/$ppr 10px/$ppr; 50 | font-size: 12px/$ppr; 51 | color: #666; 52 | } 53 | .highlinght{ color: #F66; } 54 | } 55 | 56 | // ------------------------------- 57 | // vip ecard 58 | 59 | .ecard-masthead{ 60 | /*padding: 0 0 10px/$ppr 0;*/ 61 | .ecard-tip{ 62 | background-color: #ffdfe0; 63 | font-size:11px/$ppr; 64 | color: #666; 65 | border-bottom: 1px solid #efd0d0; 66 | padding: 06px/$ppr 12px/$ppr; 67 | .svg-icon{ 68 | float: left; 69 | margin-right: 10px/$ppr; 70 | color: #F55; 71 | } 72 | } 73 | .ecard-figure{ 74 | margin-bottom: 15px/$ppr; 75 | padding: 12px/$ppr 0; 76 | text-align: center; 77 | background-color: #fff; 78 | position: relative; 79 | /*z-index: 1;*/ 80 | 81 | &:before,&:after{ 82 | content: ""; 83 | position: absolute; 84 | top: 10%; 85 | bottom: 15px/$ppr; 86 | z-index: -1; 87 | width: 50%; 88 | box-shadow: 0 15px/$ppr 10px/$ppr rgba(0,0,0,0.5); 89 | } 90 | &:before{ 91 | left: 04px/$ppr; 92 | transform: rotate(-3deg); 93 | } 94 | &:after{ 95 | right: 04px/$ppr; 96 | transform: rotate(3deg); 97 | } 98 | 99 | } 100 | .ecard-barcode{ 101 | text-align: center; 102 | } 103 | } 104 | 105 | .ecard-equity-list{ 106 | padding: 12px/$ppr 0; 107 | & > li{ 108 | float: left; 109 | width: 1 / 3 * 100%; 110 | text-align: center; 111 | font-size:11px/$ppr; 112 | & > .svg-icon{ 113 | width: 40px/$ppr; 114 | height: 40px/$ppr; 115 | color: #FF2B2B; 116 | } 117 | & > p{ padding-top: 05px/$ppr; } 118 | } 119 | } 120 | 121 | -------------------------------------------------------------------------------- /static/sass/pages/_home.scss: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | 3 | 4 | //================================================ 5 | 6 | // -------------------------------- 7 | // masthead 8 | .masthead-section{ 9 | color: #fff; 10 | padding-left: 12px/$ppr; 11 | padding-right: 12px/$ppr; 12 | min-height: 132px/$ppr; 13 | 14 | background: -moz-linear-gradient(90deg, #FF2B1C 0, #FF426E 100%);/* FF3.6+ */ 15 | background: -webkit-gradient(linear, 90deg, color-stop(0, FF2B1C), color-stop(100%, FF426E));/* Chrome,Safari4+ */ 16 | background: -webkit-linear-gradient(90deg, #FF2B1C 0, #FF426E 100%);/* Chrome10+,Safari5.1+ */ 17 | background: -o-linear-gradient(90deg, #FF2B1C 0, #FF426E 100%);/* Opera 11.10+ */ 18 | background: -ms-linear-gradient(90deg, #FF2B1C 0, #FF426E 100%);/* IE10+ */ 19 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#1301FE', endColorstr='#F4F60C', GradientType='1'); /* for IE */ 20 | background: linear-gradient(90deg, #FF2B1C 0, #FF426E 100%);/* W3C */ 21 | 22 | a { color: inherit; } 23 | .masthead-nologin{ 24 | text-align: center; 25 | .masthead-title{ 26 | padding-top: 12px/$ppr; 27 | } 28 | .masthead-button{ 29 | display: inline-block; 30 | width: 80px/$ppr; 31 | height: 30px/$ppr; 32 | margin: 20px/$ppr auto; 33 | line-height: 30px/$ppr; 34 | color: #ff4545; 35 | font-size: 14px/$ppr; 36 | border-radius: 4px/$ppr; 37 | border: 1px solid #fff; 38 | background: #ffe5e5; 39 | } 40 | } 41 | .masthead-login{ 42 | position: relative; 43 | padding-top: 15px/$ppr; 44 | .masthead-figure{ 45 | margin: 0; 46 | float: left; 47 | height: 100px/$ppr; 48 | width: 100px/$ppr; 49 | max-width: 100px/$ppr; 50 | border-radius: 50%; 51 | overflow: hidden; 52 | background-image: url("../images/avatar.png"); 53 | background-repeat: no-repeat; 54 | background-size: contain; 55 | margin-right: 10px/$ppr; 56 | } 57 | .masthead-caption{ 58 | margin-top: 10px/$ppr; 59 | & > h3{ 60 | font-size: 27px/$ppr; 61 | padding: 6px/$ppr 0; 62 | } 63 | } 64 | .masthead-setting{ 65 | text-align: right; 66 | margin-top: 14px/$ppr; 67 | color: #ffe0dc; 68 | } 69 | } 70 | } 71 | 72 | // -------------------------------- 73 | // service 74 | .service-section{ 75 | .service-list{ 76 | border-top: 1px solid #eee; 77 | padding-top: 5px/$ppr; 78 | .service-item{ 79 | float: left; 80 | width: 20%; 81 | } 82 | } 83 | .service-cell{ 84 | padding: 8px/$ppr 0; 85 | color: #666; 86 | font-size: 13px/$ppr; 87 | text-align: center; 88 | } 89 | .service-icon{ 90 | display: inline-block; 91 | width: 30px/$ppr; 92 | height: 30px/$ppr; 93 | color: #999; 94 | } 95 | .icon-area{ 96 | display: inline-block; 97 | position: relative; 98 | .icon-tip{ 99 | position: absolute; 100 | top: 0; 101 | right: 0; 102 | font-style: normal; 103 | font-size: 12px/$ppr; 104 | line-height: 20px/$ppr; 105 | display: inline-block; 106 | width: 20px/$ppr; 107 | height: 20px/$ppr; 108 | border-radius: 50%; 109 | background-color: rgba(255,255,255,0.6); 110 | color: #ff3333; 111 | border: 1px solid #ff3333; 112 | margin-top: -6px/$ppr; 113 | margin-right: -6px/$ppr; 114 | } 115 | } 116 | 117 | } 118 | 119 | 120 | // -------------------------------- 121 | // advance 122 | .advance-section{ 123 | 124 | $columnNumber: 4; 125 | $border: 1px solid rgba(211,211,211,0.6); 126 | 127 | overflow: hidden; 128 | // border-top: $border; 129 | // border-bottom: $border; 130 | 131 | .advance-list{ 132 | margin-right: -1px; 133 | margin-bottom: -1px; 134 | .advance-item{ 135 | float: left; 136 | width: (1 / $columnNumber) * 100%; 137 | box-sizing: border-box; 138 | border-bottom: $border; 139 | border-right: $border; 140 | 141 | &:nth-of-type(#{$columnNumber}n){ 142 | border-right: 0; 143 | } 144 | &:active{ 145 | -webkit-tap-highlight-color: rgba(0, 0, 0, 0); 146 | background-color: #f0f0f0; 147 | } 148 | } 149 | } 150 | .advance-cell{ 151 | display: block; 152 | text-align: center; 153 | padding-top: 12px/$ppr; 154 | padding-bottom: 10px/$ppr; 155 | .advance-icon{ 156 | width: 30px/$ppr; 157 | height: 30px/$ppr; 158 | display: inline-block; 159 | } 160 | .advance-text{ 161 | display: block; 162 | color: #333; 163 | font-size: 14px/$ppr; 164 | line-height: 1.8; 165 | overflow: hidden; 166 | white-space: nowrap; 167 | text-overflow: ellipsis; 168 | } 169 | .advance-tip{ 170 | display: block; 171 | color: #999; 172 | font-size: 12px/$ppr; 173 | line-height: 1; 174 | } 175 | } 176 | } 177 | -------------------------------------------------------------------------------- /static/sass/pages/_info.scss: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | 3 | .info-section{ 4 | .info-list{ 5 | /*.inner-bar{ padding: 10px/$ppr 12px/$ppr; }*/ 6 | .avatar-item{ 7 | line-height: 80px/$ppr; 8 | .avatar-figure{ 9 | float: right; 10 | font-size: 0; 11 | height: 80px/$ppr; 12 | width: 80px/$ppr; 13 | background-image: url("../images/avatar.png"); 14 | background-repeat: no-repeat; 15 | background-size: contain; 16 | border-radius: 50%; 17 | overflow: hidden; 18 | } 19 | } 20 | } 21 | 22 | } 23 | 24 | 25 | //============================================= 26 | // -------------------------------- 27 | // phone 28 | 29 | /* verify step */ 30 | .verify-mobile-wrap{ 31 | 32 | $step-number: 3 !default; 33 | $banner-background-color: #efefef !default; 34 | $step-color: #ccc !default; 35 | $step-color-active: #dd0000 !default; 36 | $step-color-verified: #008000 !default; 37 | 38 | padding: 15px/$ppr 12px/$ppr; 39 | 40 | .verify-mobile-step{ 41 | overflow: hidden; 42 | counter-reset: rule-counter 0; 43 | .step-item{ 44 | width: (1 / $step-number) * 100%; 45 | float: left; 46 | position: relative; 47 | overflow: hidden; 48 | text-align: center; 49 | strong{ 50 | display: inline-block; 51 | position: relative; 52 | font-weight: normal; 53 | text-align: center; 54 | background-color: $banner-background-color; 55 | color: #666; 56 | font-size: 14px/$ppr; 57 | } 58 | &:before{ 59 | content: ""; 60 | display: inline-block; 61 | width: 100%; 62 | border-top: 1px dashed #000; 63 | position: absolute; 64 | top: 25%; 65 | left: 0; 66 | right: 0; 67 | z-index: 1; 68 | } 69 | 70 | } 71 | .step-icon{ 72 | position: absolute; 73 | z-index: 2; 74 | display: block; 75 | left: 50%; 76 | margin-left: -10px/$ppr; 77 | height: 100%; 78 | background-color: $banner-background-color; 79 | &:after{ 80 | content: counter(rule-counter); 81 | counter-increment: rule-counter; 82 | display: inline-block; 83 | width: 20px/$ppr; 84 | height: 20px/$ppr; 85 | border-radius: 50%; 86 | background-color: $step-color; 87 | color: #fff; 88 | } 89 | } 90 | 91 | .step-num{ 92 | display: block; 93 | position: relative; 94 | height: 20px/$ppr; 95 | } 96 | 97 | // first 98 | li:first-of-type{ 99 | text-align: left; 100 | .step-icon{ 101 | left: 0; 102 | right: auto; 103 | width: 50%; 104 | height: 100%; 105 | margin-left: auto; 106 | &:after{ 107 | position: absolute; 108 | right: 0; 109 | transform: translateX(50%); 110 | } 111 | } 112 | } 113 | 114 | // last 115 | li:last-of-type{ 116 | text-align: right; 117 | .step-icon{ 118 | left: auto; 119 | right: 0; 120 | width: 50%; 121 | height: 100%; 122 | margin-left: auto; 123 | &:after{ 124 | position: absolute; 125 | left: 0; 126 | transform: translateX(-50%); 127 | } 128 | } 129 | } 130 | 131 | // active 132 | li.step-active{ 133 | strong{ 134 | color: $step-color-active; 135 | } 136 | &:before{ border-top-color: $step-color-active; } 137 | .step-icon:after{ 138 | background-color: $step-color-active; 139 | color: #fff; 140 | } 141 | } 142 | 143 | // verified 144 | li.step-verified{ 145 | strong{ 146 | color: $step-color-verified; 147 | } 148 | &:before{ border-top-color: $step-color-verified; } 149 | .step-icon:after{ 150 | background-color: $step-color-verified; 151 | color: #fff; 152 | } 153 | } 154 | 155 | } 156 | } 157 | 158 | // -------------------------------- 159 | // address 160 | 161 | /* list item address */ 162 | .address-list{ 163 | .address-item{ 164 | padding-left: 12px/$ppr; 165 | padding-right: 12px/$ppr; 166 | margin-bottom: 12px/$ppr; 167 | background-color: #fff; 168 | &.default{ 169 | background-color: #FDF2F4; 170 | } 171 | } 172 | 173 | .text-right{ text-align: right;} 174 | 175 | .address-title{ 176 | padding-top: 10px/$ppr; 177 | padding-bottom: 8px/$ppr; 178 | font-weight: normal; 179 | font-size: 16px/$ppr; 180 | } 181 | .address-text{ 182 | color: #666; 183 | font-size: 14px/$ppr; 184 | margin-bottom: 5px/$ppr; 185 | } 186 | .address-action{ 187 | font-size: 14px/$ppr; 188 | padding: 10px/$ppr 0; 189 | border-top: 1px solid #eee; 190 | a{ 191 | color: #666; 192 | display: inline-block; 193 | } 194 | } 195 | } 196 | 197 | 198 | 199 | 200 | //============================================= 201 | // -------------------------------- 202 | // custom 203 | .notice-warn{ 204 | padding: 21px/$ppr; 205 | font-size: 12px/$ppr; 206 | color: #666; 207 | .icon-warning{ color: #dd0000;} 208 | } 209 | -------------------------------------------------------------------------------- /static/sass/pages/_voucher.scss: -------------------------------------------------------------------------------- 1 | 2 | // ---------------------------- 3 | // voucher detail 4 | 5 | .voucher-masthead{ 6 | margin-top: 08px/$ppr; 7 | margin-left: 12px/$ppr; 8 | margin-right: 12px/$ppr; 9 | margin-bottom: 15px/$ppr; 10 | background-color: #fff; 11 | position: relative; 12 | z-index: 1; 13 | &.voucher-masthead--failed{ 14 | .ticket-failed{ 15 | position: absolute; 16 | top: 0; 17 | right: 0; 18 | bottom: 0; 19 | left: 0; 20 | background-color: rgba(211,211,211,0.5); 21 | &:after{ 22 | content: attr(arial-failed); 23 | display: inline-block; 24 | position: absolute; 25 | top: -05px/$ppr; 26 | right: 0; 27 | height: 60px/$ppr; 28 | width: 60px/$ppr; 29 | font-size: 14px/$ppr; 30 | line-height: 60px/$ppr; 31 | text-align: center; 32 | color: #999; 33 | background-color: #fafafa; 34 | border: 1px solid #ddd; 35 | border-radius: 50%; 36 | transform: rotate(-30deg); 37 | box-shadow: 0px 0px 0px 03px/$ppr rgba(140, 140, 140, 0.5); 38 | } 39 | } 40 | .voucher-ticket{ 41 | background-color: #999; 42 | background-image: radial-gradient(circle at top, #efefef 50%, #999 50%); 43 | } 44 | } 45 | .voucher-ticket{ 46 | padding: 20px/$ppr 10px/$ppr; 47 | color: #fff; 48 | background-color: #F3D430; 49 | background-image: radial-gradient(circle at top, #efefef 50%, #F3D430 50%); 50 | background-size: 12px/$ppr 06px/$ppr; 51 | background-repeat: repeat-x; 52 | 53 | .ticket-price{ 54 | float: left; 55 | margin-right: 15px/$ppr; 56 | font-size: 21px/$ppr; 57 | big{ 58 | font-size: 60px/$ppr; 59 | line-height: 0.8; 60 | vertical-align: text-top; 61 | font-family: Arial; 62 | font-weight: bold; 63 | } 64 | } 65 | 66 | h3{ 67 | font-size: 14px/$ppr; 68 | margin-bottom: 05px/$ppr; 69 | } 70 | p{ font-size: 12px/$ppr; } 71 | 72 | } 73 | .voucher-barcode{ 74 | background-color: #fff; 75 | padding-top: 12px/$ppr; 76 | padding-bottom: 06px/$ppr; 77 | text-align: center; 78 | .barcode{ 79 | margin: 0 auto; 80 | } 81 | } 82 | &:before,&:after{ 83 | content: ""; 84 | position: absolute; 85 | top: 10%; 86 | bottom: 15px/$ppr; 87 | z-index: -1; 88 | width: 50%; 89 | box-shadow: 0 15px/$ppr 10px/$ppr rgba(0,0,0,0.5); 90 | 91 | } 92 | &:before{ 93 | left: 04px/$ppr; 94 | transform: rotate(-3deg); 95 | } 96 | &:after{ 97 | right: 04px/$ppr; 98 | transform: rotate(3deg); 99 | } 100 | } 101 | 102 | /* .voucher-content{ 103 | font-size: 12px/$ppr; 104 | & > h4{ 105 | color: #999; 106 | margin-bottom: 05px/$ppr; 107 | margin-top: 15px/$ppr; 108 | &:first-child{ margin-top: 0; } 109 | } 110 | .text-red{ color: #dd0000; } 111 | .text-gray{ color: #999; } 112 | } 113 | 114 | // voucher modal 115 | .voucher-modal{ 116 | 117 | .font-size-12{ font-size: 12px/$ppr; } 118 | 119 | .modal-box-tip{ 120 | background: rgba(0, 0, 0, 0.5); 121 | text-align: center; 122 | width: auto; 123 | min-width: 0; 124 | margin-top: 50px/$ppr; 125 | color: #fff; 126 | } 127 | 128 | .modal-box-success{ 129 | .i-icon{ 130 | vertical-align: middle; 131 | font-size: 36px/$ppr; 132 | color: #6C0; 133 | } 134 | .highlight{ color: #dd0000; } 135 | } 136 | 137 | } 138 | 139 | */ -------------------------------------------------------------------------------- /static/sass/util/_button.scss: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | 3 | button.plain{ 4 | padding: 0; 5 | border: none; 6 | background: none; 7 | } 8 | 9 | .btn-wrap{ 10 | margin: 12px/$ppr 0; 11 | padding: 0 12px/$ppr; 12 | } 13 | 14 | .btn[type="button"], 15 | .btn[role="button"]{ 16 | display: inline-block; 17 | padding: 6px/$ppr 15px/$ppr; 18 | margin-bottom: 0; 19 | font-size: 15px/$ppr; 20 | font-weight: normal; 21 | line-height: 1.4; 22 | text-align: center; 23 | white-space: nowrap; 24 | vertical-align: middle; 25 | // -ms-touch-action: manipulation; 26 | // touch-action: manipulation; 27 | cursor: pointer; 28 | // -webkit-user-select: none; 29 | // -moz-user-select: none; 30 | // -ms-user-select: none; 31 | // user-select: none; 32 | background-image: none; 33 | border: 1px solid rgba(0, 0, 0, 0); 34 | border-radius: 4px/$ppr; 35 | box-sizing: border-box; 36 | &.btn-block{ 37 | display: block; 38 | width: 100%; 39 | } 40 | &.btn-danger{ 41 | color: #fff; 42 | background-color: #D00; 43 | border-color: #D00; 44 | } 45 | &.btn-simple{ 46 | color: #D00; 47 | background-color: #fff; 48 | border-color: #D00; 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /static/sass/util/_ellipsis.scss: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | 3 | @mixin ellipsis($line){ 4 | overflow : hidden; 5 | text-overflow: ellipsis; 6 | display: -webkit-box; 7 | -webkit-line-clamp: $line; 8 | -webkit-box-orient: vertical; 9 | } 10 | 11 | .ellipsis--1-line{ @include ellipsis(1); } 12 | .ellipsis--2-line{ @include ellipsis(2); } 13 | -------------------------------------------------------------------------------- /static/sass/util/_form.scss: -------------------------------------------------------------------------------- 1 | 2 | .form-group{ 3 | 4 | padding: 10px/$ppr 0; 5 | 6 | input{ 7 | width: 100%; 8 | box-sizing: border-box; 9 | padding: 6px/$ppr 8px/$ppr; 10 | background-color: inherit; 11 | } 12 | 13 | .form-field{ 14 | position: relative; 15 | margin-bottom: 12px/$ppr; 16 | } 17 | 18 | .border-adorn{ 19 | display: block; 20 | height: 5px/$ppr; 21 | border: 1px/$ppr solid #797979; 22 | border-top: none; 23 | /*margin-left: -1px/$ppr; 24 | margin-right: -1px/$ppr;*/ 25 | margin-top: -3px/$ppr; 26 | } 27 | 28 | input:focus ~ .border-adorn{ border-color: #d00; } 29 | 30 | .right-adorn{ 31 | position: absolute; 32 | right: 0; 33 | top: 0; 34 | bottom: 0; 35 | } 36 | .clear-icon{ 37 | font-style: normal; 38 | font-size: 18px/$ppr; 39 | color: #999; 40 | display: table-cell; 41 | padding: 4px/$ppr 9px/$ppr; 42 | text-align: center; 43 | cursor: pointer; 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /static/sass/util/_grid.scss: -------------------------------------------------------------------------------- 1 | /* GRID */ 2 | 3 | .i-grid{ 4 | display: flex; 5 | flex-direction: row; 6 | flex-wrap: wrap; 7 | /*flex-flow: row wrap; */ 8 | margin: 0 auto; 9 | align-items: stretch; 10 | 11 | &.i-grid--between{ 12 | justify-content: space-between; 13 | } 14 | 15 | &.i-grid--no-spacing{ 16 | padding: 0; 17 | } 18 | } 19 | 20 | .i-cell{ box-sizing: border-box; } 21 | 22 | .i-cell--top{ align-self: flex-start; } 23 | 24 | .i-cell--middle{ align-self: center; } 25 | 26 | .i-cell--bottom{ align-self: flex-end; } 27 | 28 | .i-cell--stretch{ align-self: stretch; } 29 | 30 | 31 | 32 | @for $i from 1 through (12 - 1){ 33 | 34 | .i-cell--#{$i}-col{ 35 | 36 | width: calc( #{($i / 12) * 100 + "%"} - 0px ); 37 | 38 | .i-grid--no-spacing > & { 39 | width: #{($i / 12) * 100 + "%"}; 40 | } 41 | 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /static/sass/util/_icon.scss: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | 3 | .svg-icon{ 4 | display: block; 5 | height: 24px/$ppr; 6 | width: 24px/$ppr; 7 | margin: auto; 8 | 9 | &.svg-icon--middle{ 10 | display: inline-block; 11 | vertical-align: middle; 12 | } 13 | 14 | } 15 | 16 | 17 | 18 | .svg-icon svg, 19 | .svg-icon img, 20 | .svg-icon--middle svg, 21 | .svg-icon--middle img { 22 | display: block; 23 | width: inherit; 24 | height: inherit; 25 | fill: currentColor; 26 | } 27 | 28 | /* fix the svg sprites for svg-sprites-loader */ 29 | svg path{ fill: currentColor; } 30 | 31 | //------------------------------------ 32 | // direction icon 33 | 34 | @mixin icon-direction($dir, $size: 2px/$ppr, $color: #fff){ 35 | @if $dir == top{ 36 | border-left: $size solid $color; 37 | border-top: $size solid $color; 38 | }@else if $dir == right{ 39 | border-right: $size solid $color; 40 | border-top: $size solid $color; 41 | }@else if $dir == left{ 42 | border-left: $size solid $color; 43 | border-bottom: $size solid $color; 44 | }@else if $dir == bottom{ 45 | border-right: $size solid $color; 46 | border-bottom: $size solid $color; 47 | } 48 | 49 | } 50 | 51 | .dir-icon{ 52 | display: inline-block; 53 | &:after{ 54 | content: ""; 55 | width: 10px/$ppr; 56 | height: 10px/$ppr; 57 | display: inline-block; 58 | transform: rotate(45deg); 59 | margin-top: -2px/$ppr; 60 | text-indent: -9999px; 61 | overflow: hidden; 62 | vertical-align: middle; 63 | } 64 | 65 | &.top-dir-icon:after{ 66 | @include icon-direction("top",2px/$ppr, #d8d8d8); 67 | } 68 | &.right-dir-icon:after{ 69 | @include icon-direction("right",2px/$ppr, #d8d8d8); 70 | } 71 | &.bottom-dir-icon:after{ 72 | @include icon-direction("bottom",2px/$ppr, #d8d8d8); 73 | } 74 | &.left-dir-icon:after{ 75 | @include icon-direction("left",2px/$ppr, #d8d8d8); 76 | } 77 | 78 | &.inherit-color:after{ 79 | border-color: inherit; 80 | } 81 | 82 | } 83 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | var webpack = require('webpack'); 2 | var ExtractTextPlugin = require("extract-text-webpack-plugin"); 3 | var HtmlWebpackPlugin = require('html-webpack-plugin'); 4 | 5 | module.exports = { 6 | entry:{ 7 | main: ['./src/main.js'], 8 | // vendor: ['vue','vue-router','vue-resource'] 9 | }, 10 | 11 | output: { 12 | publicPath: process.env.NODE_ENV === 'production' ? "http://imjeen.github.io/i/release/" : "/build/", 13 | path: __dirname + (process.env.NODE_ENV === 'production' ? "/release/" : "/build/"), 14 | filename: "[name].js", 15 | chunkFilename: "[chunkhash].js" 16 | }, 17 | 18 | module: { 19 | loaders: [ 20 | /* #image */ 21 | { 22 | test: /\.png$/, 23 | loaders: [ 24 | 'file?hash=sha512&digest=hex&name=images/[name].[ext]?[hash]', 25 | 'image-webpack?{progressive:true, optimizationLevel: 7, interlaced: false, pngquant:{quality: "65-90", speed: 4}}' 26 | ] 27 | }, 28 | { 29 | test: /\.svg$/, 30 | loader: 'svg-sprite?' + JSON.stringify({ 31 | name: '[name]_[hash]', 32 | prefixize: true, 33 | // spriteModule: './static/images/' 34 | }) 35 | }, 36 | /* #font */ 37 | // { test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/, loader: "url-loader?limit=10000&mimetype=application/font-woff" }, 38 | // { test: /\.(ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/, loader: "file-loader" }, 39 | /* #vue */ 40 | { test: /\.vue$/, loader: "vue-loader" }, 41 | /* #js */ 42 | { 43 | test: /\.js$/, 44 | exclude: /(node_modules|bower_components)/, 45 | loader: 'babel', 46 | query: { 47 | cacheDirectory: true, 48 | plugins: ['transform-runtime'], 49 | presets: ['es2015'] 50 | } 51 | }, 52 | 53 | ] 54 | }, 55 | 56 | plugins: [ 57 | new ExtractTextPlugin("[name].css",{ allChunks: true }), 58 | new webpack.optimize.CommonsChunkPlugin('common.js'), 59 | ], 60 | 61 | resolve: { 62 | extensions: ['', '.js'], 63 | alias:{ 64 | 'vue': __dirname + "/bower_components/vue/dist/vue.js", 65 | 'vue-router': __dirname + "/bower_components/vue-router/dist/vue-router.js", 66 | 'vue-resource': __dirname + "/bower_components/vue-resource/dist/vue-resource.js", 67 | } 68 | } 69 | 70 | }; 71 | 72 | if(process.env.NODE_ENV === 'production'){ 73 | 74 | module.exports.plugins 75 | && module.exports.plugins.push( 76 | new webpack.DefinePlugin({ 77 | 'process.env': { 78 | NODE_ENV: '"production"' 79 | } 80 | }), 81 | new webpack.optimize.UglifyJsPlugin({ 82 | compress: { 83 | warnings: false 84 | } 85 | }), 86 | new webpack.optimize.OccurenceOrderPlugin(), 87 | new HtmlWebpackPlugin({ 88 | filename: '../index.html', 89 | template: './src/index.template.html', 90 | inject: false, 91 | minify: { 92 | removeComments: true, 93 | collapseWhitespace: true, 94 | minifyJS: true, 95 | minifyCSS: true, 96 | }, 97 | }) 98 | ); 99 | 100 | // for style 101 | module.exports.module.loaders 102 | && module.exports.module.loaders.push( 103 | { test: /\.css$/, loader: ExtractTextPlugin.extract("style-loader","css-loader") }, 104 | { test: /\.scss$/, loader: ExtractTextPlugin.extract("style-loader","css-loader!sass-loader") } 105 | ); 106 | 107 | }else{ 108 | 109 | module.exports.devtool = 'source-map'; 110 | 111 | module.exports.plugins 112 | && module.exports.plugins.push( 113 | new HtmlWebpackPlugin({ 114 | filename: '../index.html', 115 | template: './src/index.template.html', 116 | inject: false 117 | }) 118 | ); 119 | 120 | module.exports.module.loaders 121 | && module.exports.module.loaders.push( 122 | { test: /\.css$/, loader: ExtractTextPlugin.extract("style-loader","css-loader?sourceMap") }, 123 | { test: /\.scss$/, loader: ExtractTextPlugin.extract("style-loader","css-loader?sourceMap!sass-loader?sourceMap") } 124 | ); 125 | 126 | } 127 | --------------------------------------------------------------------------------