├── .babelrc ├── data.json ├── index.html ├── mock └── mock-server.js ├── package-lock.json ├── package.json ├── src ├── App.jsx ├── App.less ├── common │ ├── font │ │ ├── icomoon.eot │ │ ├── icomoon.svg │ │ ├── icomoon.ttf │ │ └── icomoon.woff │ ├── imgs │ │ ├── brand@2x.png │ │ ├── brand@3x.png │ │ ├── bulletin@2x.png │ │ ├── bulletin@3x.png │ │ ├── decrease_1@2x.png │ │ ├── decrease_1@3x.png │ │ ├── decrease_2@2x.png │ │ ├── decrease_2@3x.png │ │ ├── decrease_3@2x.png │ │ ├── decrease_3@3x.png │ │ ├── decrease_4@2x.png │ │ ├── decrease_4@3x.png │ │ ├── discount_1@2x.png │ │ ├── discount_1@3x.png │ │ ├── discount_2@2x.png │ │ ├── discount_2@3x.png │ │ ├── discount_3@2x.png │ │ ├── discount_3@3x.png │ │ ├── discount_4@2x.png │ │ ├── discount_4@3x.png │ │ ├── guarantee_1@2x.png │ │ ├── guarantee_1@3x.png │ │ ├── guarantee_2@2x.png │ │ ├── guarantee_2@3x.png │ │ ├── guarantee_3@2x.png │ │ ├── guarantee_3@3x.png │ │ ├── guarantee_4@2x.png │ │ ├── guarantee_4@3x.png │ │ ├── invoice_1@2x.png │ │ ├── invoice_1@3x.png │ │ ├── invoice_2@2x.png │ │ ├── invoice_2@3x.png │ │ ├── invoice_3@2x.png │ │ ├── invoice_3@3x.png │ │ ├── invoice_4@2x.png │ │ ├── invoice_4@3x.png │ │ ├── special_1@2x.png │ │ ├── special_1@3x.png │ │ ├── special_2@2x.png │ │ ├── special_2@3x.png │ │ ├── special_3@2x.png │ │ ├── special_3@3x.png │ │ ├── special_4@2x.png │ │ ├── special_4@3x.png │ │ ├── star24_half@2x.png │ │ ├── star24_half@3x.png │ │ ├── star24_off@2x.png │ │ ├── star24_off@3x.png │ │ ├── star24_on@2x.png │ │ ├── star24_on@3x.png │ │ ├── star36_half@2x.png │ │ ├── star36_half@3x.png │ │ ├── star36_off@2x.png │ │ ├── star36_off@3x.png │ │ ├── star36_on@2x.png │ │ ├── star36_on@3x.png │ │ ├── star48_half@2x.png │ │ ├── star48_half@3x.png │ │ ├── star48_off@2x.png │ │ ├── star48_off@3x.png │ │ ├── star48_on@2x.png │ │ └── star48_on@3x.png │ ├── js │ │ ├── code_res.js │ │ └── config.js │ └── less │ │ ├── base.less │ │ ├── icon.less │ │ ├── index.less │ │ └── mixin.less ├── components │ ├── base │ │ ├── cartcontrol │ │ │ ├── cartcontrol.jsx │ │ │ └── cartcontrol.less │ │ └── discount │ │ │ ├── discount.jsx │ │ │ └── discount.less │ ├── cart │ │ ├── cart.jsx │ │ └── cart.less │ ├── commentselect │ │ ├── commentselect.jsx │ │ └── commentselect.less │ ├── goodcontent │ │ ├── goodcontent.jsx │ │ └── goodcontent.less │ ├── goods │ │ ├── goods.jsx │ │ └── goods.less │ ├── header │ │ ├── header.jsx │ │ └── header.less │ ├── navbar │ │ ├── navbar.jsx │ │ └── navbar.less │ └── star │ │ ├── star.jsx │ │ └── star.less └── index.js ├── static ├── css │ └── reset.css └── js │ └── rem.js └── webpack.config.js /.babelrc: -------------------------------------------------------------------------------- 1 | /** 2 | .babelrc 3 | */ 4 | 5 | { 6 | "presets": [ 7 | "es2015", "react" 8 | ], 9 | "plugins": [ 10 | ["import", { libraryName: "antd", style: true}] 11 | ] 12 | } -------------------------------------------------------------------------------- /data.json: -------------------------------------------------------------------------------- 1 | { 2 | "seller": { 3 | "name": "粥品香坊(回龙观)", 4 | "description": "蜂鸟专送", 5 | "deliveryTime": 38, 6 | "score": 4.2, 7 | "serviceScore": 4.1, 8 | "foodScore": 4.3, 9 | "rankRate": 69.2, 10 | "minPrice": 20, 11 | "deliveryPrice": 4, 12 | "ratingCount": 24, 13 | "sellCount": 90, 14 | "bulletin": "粥品香坊其烹饪粥料的秘方源于中国千年古法,在融和现代制作工艺,由世界烹饪大师屈浩先生领衔研发。坚守纯天然、0添加的良心品质深得消费者青睐,发展至今成为粥类的引领品牌。是2008年奥运会和2013年园博会指定餐饮服务商。", 15 | "supports": [ 16 | { 17 | "type": 0, 18 | "description": "在线支付满28减5" 19 | }, 20 | { 21 | "type": 1, 22 | "description": "VC无限橙果汁全场8折" 23 | }, 24 | { 25 | "type": 2, 26 | "description": "单人精彩套餐" 27 | }, 28 | { 29 | "type": 3, 30 | "description": "该商家支持发票,请下单写好发票抬头" 31 | }, 32 | { 33 | "type": 4, 34 | "description": "已加入“外卖保”计划,食品安全保障" 35 | } 36 | ], 37 | "avatar": "http://static.galileo.xiaojukeji.com/static/tms/seller_avatar_256px.jpg", 38 | "pics": [ 39 | "http://fuss10.elemecdn.com/8/71/c5cf5715740998d5040dda6e66abfjpeg.jpeg?imageView2/1/w/180/h/180", 40 | "http://fuss10.elemecdn.com/b/6c/75bd250e5ba69868f3b1178afbda3jpeg.jpeg?imageView2/1/w/180/h/180", 41 | "http://fuss10.elemecdn.com/f/96/3d608c5811bc2d902fc9ab9a5baa7jpeg.jpeg?imageView2/1/w/180/h/180", 42 | "http://fuss10.elemecdn.com/6/ad/779f8620ff49f701cd4c58f6448b6jpeg.jpeg?imageView2/1/w/180/h/180" 43 | ], 44 | "infos": [ 45 | "该商家支持发票,请下单写好发票抬头", 46 | "品类:其他菜系,包子粥店", 47 | "北京市昌平区回龙观西大街龙观置业大厦底商B座102单元1340", 48 | "营业时间:10:00-20:30" 49 | ] 50 | }, 51 | "goods": [ 52 | { 53 | "name": "热销榜", 54 | "type": -1, 55 | "foods": [ 56 | { 57 | "name": "皮蛋瘦肉粥", 58 | "price": 10, 59 | "oldPrice": "36", 60 | "description": "咸粥", 61 | "sellCount": 229, 62 | "rating": 100, 63 | "info": "一碗皮蛋瘦肉粥,总是我到粥店时的不二之选。香浓软滑,饱腹暖心,皮蛋的Q弹与瘦肉的滑嫩伴着粥香溢于满口,让人喝这样的一碗粥也觉得心满意足", 64 | "ratings": [ 65 | { 66 | "username": "3******c", 67 | "rateTime": 1469281964000, 68 | "rateType": 0, 69 | "text": "很喜欢的粥", 70 | "avatar": "http://static.galileo.xiaojukeji.com/static/tms/default_header.png" 71 | }, 72 | { 73 | "username": "2******3", 74 | "rateTime": 1469271264000, 75 | "rateType": 0, 76 | "text": "", 77 | "avatar": "http://static.galileo.xiaojukeji.com/static/tms/default_header.png" 78 | }, 79 | { 80 | "username": "3******b", 81 | "rateTime": 1469261964000, 82 | "rateType": 1, 83 | "text": "", 84 | "avatar": "http://static.galileo.xiaojukeji.com/static/tms/default_header.png" 85 | } 86 | ], 87 | "icon": "http://fuss10.elemecdn.com/c/cd/c12745ed8a5171e13b427dbc39401jpeg.jpeg?imageView2/1/w/114/h/114", 88 | "image": "http://fuss10.elemecdn.com/c/cd/c12745ed8a5171e13b427dbc39401jpeg.jpeg?imageView2/1/w/750/h/750" 89 | }, 90 | { 91 | "name": "扁豆焖面", 92 | "price": 14, 93 | "oldPrice": "", 94 | "description": "", 95 | "sellCount": 188, 96 | "rating": 96, 97 | "ratings": [ 98 | { 99 | "username": "3******c", 100 | "rateTime": 1469281964000, 101 | "rateType": 0, 102 | "text": "", 103 | "avatar": "http://static.galileo.xiaojukeji.com/static/tms/default_header.png" 104 | }, 105 | { 106 | "username": "2******3", 107 | "rateTime": 1469271264000, 108 | "rateType": 0, 109 | "text": "", 110 | "avatar": "http://static.galileo.xiaojukeji.com/static/tms/default_header.png" 111 | }, 112 | { 113 | "username": "3******b", 114 | "rateTime": 1469261964000, 115 | "rateType": 1, 116 | "text": "", 117 | "avatar": "http://static.galileo.xiaojukeji.com/static/tms/default_header.png" 118 | } 119 | ], 120 | "info": "", 121 | "icon": "http://fuss10.elemecdn.com/c/6b/29e3d29b0db63d36f7c500bca31d8jpeg.jpeg?imageView2/1/w/114/h/114", 122 | "image": "http://fuss10.elemecdn.com/c/6b/29e3d29b0db63d36f7c500bca31d8jpeg.jpeg?imageView2/1/w/750/h/750" 123 | }, 124 | { 125 | "name": "葱花饼", 126 | "price": 10, 127 | "oldPrice": "", 128 | "description": "", 129 | "sellCount": 124, 130 | "rating": 85, 131 | "info": "", 132 | "ratings": [ 133 | { 134 | "username": "3******c", 135 | "rateTime": 1469281964000, 136 | "rateType": 1, 137 | "text": "没啥味道", 138 | "avatar": "http://static.galileo.xiaojukeji.com/static/tms/default_header.png" 139 | }, 140 | { 141 | "username": "2******3", 142 | "rateTime": 1469271264000, 143 | "rateType": 1, 144 | "text": "很一般啊", 145 | "avatar": "http://static.galileo.xiaojukeji.com/static/tms/default_header.png" 146 | }, 147 | { 148 | "username": "3******b", 149 | "rateTime": 1469261964000, 150 | "rateType": 0, 151 | "text": "", 152 | "avatar": "http://static.galileo.xiaojukeji.com/static/tms/default_header.png" 153 | } 154 | ], 155 | "icon": "http://fuss10.elemecdn.com/f/28/a51e7b18751bcdf871648a23fd3b4jpeg.jpeg?imageView2/1/w/114/h/114", 156 | "image": "http://fuss10.elemecdn.com/f/28/a51e7b18751bcdf871648a23fd3b4jpeg.jpeg?imageView2/1/w/750/h/750" 157 | }, 158 | { 159 | "name": "牛肉馅饼", 160 | "price": 14, 161 | "oldPrice": "", 162 | "description": "", 163 | "sellCount": 114, 164 | "rating": 91, 165 | "info": "", 166 | "ratings": [ 167 | { 168 | "username": "3******c", 169 | "rateTime": 1469281964000, 170 | "rateType": 1, 171 | "text": "难吃不推荐", 172 | "avatar": "http://static.galileo.xiaojukeji.com/static/tms/default_header.png" 173 | }, 174 | { 175 | "username": "2******3", 176 | "rateTime": 1469271264000, 177 | "rateType": 0, 178 | "text": "", 179 | "avatar": "http://static.galileo.xiaojukeji.com/static/tms/default_header.png" 180 | }, 181 | { 182 | "username": "3******b", 183 | "rateTime": 1469261964000, 184 | "rateType": 0, 185 | "text": "", 186 | "avatar": "http://static.galileo.xiaojukeji.com/static/tms/default_header.png" 187 | } 188 | ], 189 | "icon": "http://fuss10.elemecdn.com/d/b9/bcab0e8ad97758e65ae5a62b2664ejpeg.jpeg?imageView2/1/w/114/h/114", 190 | "image": "http://fuss10.elemecdn.com/d/b9/bcab0e8ad97758e65ae5a62b2664ejpeg.jpeg?imageView2/1/w/750/h/750" 191 | }, 192 | { 193 | "name": "招牌猪肉白菜锅贴/10个", 194 | "price": 17, 195 | "oldPrice": "", 196 | "description": "", 197 | "sellCount": 101, 198 | "rating": 78, 199 | "info": "", 200 | "ratings": [ 201 | { 202 | "username": "3******c", 203 | "rateTime": 1469281964000, 204 | "rateType": 1, 205 | "text": "不脆,不好吃", 206 | "avatar": "http://static.galileo.xiaojukeji.com/static/tms/default_header.png" 207 | }, 208 | { 209 | "username": "2******3", 210 | "rateTime": 1469271264000, 211 | "rateType": 0, 212 | "text": "", 213 | "avatar": "http://static.galileo.xiaojukeji.com/static/tms/default_header.png" 214 | }, 215 | { 216 | "username": "3******b", 217 | "rateTime": 1469261964000, 218 | "rateType": 0, 219 | "text": "", 220 | "avatar": "http://static.galileo.xiaojukeji.com/static/tms/default_header.png" 221 | } 222 | ], 223 | "icon": "http://fuss10.elemecdn.com/7/72/9a580c1462ca1e4d3c07e112bc035jpeg.jpeg?imageView2/1/w/114/h/114", 224 | "image": "http://fuss10.elemecdn.com/7/72/9a580c1462ca1e4d3c07e112bc035jpeg.jpeg?imageView2/1/w/750/h/750" 225 | }, 226 | { 227 | "name": "南瓜粥", 228 | "price": 9, 229 | "oldPrice": "", 230 | "description": "甜粥", 231 | "sellCount": 91, 232 | "rating": 100, 233 | "ratings": [ 234 | { 235 | "username": "3******c", 236 | "rateTime": 1469281964000, 237 | "rateType": 0, 238 | "text": "", 239 | "avatar": "http://static.galileo.xiaojukeji.com/static/tms/default_header.png" 240 | }, 241 | { 242 | "username": "2******3", 243 | "rateTime": 1469271264000, 244 | "rateType": 0, 245 | "text": "", 246 | "avatar": "http://static.galileo.xiaojukeji.com/static/tms/default_header.png" 247 | }, 248 | { 249 | "username": "3******b", 250 | "rateTime": 1469261964000, 251 | "rateType": 0, 252 | "text": "", 253 | "avatar": "http://static.galileo.xiaojukeji.com/static/tms/default_header.png" 254 | } 255 | ], 256 | "icon": "http://fuss10.elemecdn.com/8/a6/453f65f16b1391942af11511b7a90jpeg.jpeg?imageView2/1/w/114/h/114", 257 | "image": "http://fuss10.elemecdn.com/8/a6/453f65f16b1391942af11511b7a90jpeg.jpeg?imageView2/1/w/750/h/750" 258 | }, 259 | { 260 | "name": "红豆薏米美肤粥", 261 | "price": 12, 262 | "oldPrice": "", 263 | "description": "甜粥", 264 | "sellCount": 86, 265 | "rating": 100, 266 | "info": "", 267 | "ratings": [ 268 | { 269 | "username": "3******c", 270 | "rateTime": 1469281964000, 271 | "rateType": 0, 272 | "text": "", 273 | "avatar": "http://static.galileo.xiaojukeji.com/static/tms/default_header.png" 274 | }, 275 | { 276 | "username": "2******3", 277 | "rateTime": 1469271264000, 278 | "rateType": 0, 279 | "text": "", 280 | "avatar": "http://static.galileo.xiaojukeji.com/static/tms/default_header.png" 281 | }, 282 | { 283 | "username": "3******b", 284 | "rateTime": 1469261964000, 285 | "rateType": 0, 286 | "text": "", 287 | "avatar": "http://static.galileo.xiaojukeji.com/static/tms/default_header.png" 288 | } 289 | ], 290 | "icon": "http://fuss10.elemecdn.com/d/22/260bd78ee6ac6051136c5447fe307jpeg.jpeg?imageView2/1/w/114/h/114", 291 | "image": "http://fuss10.elemecdn.com/d/22/260bd78ee6ac6051136c5447fe307jpeg.jpeg?imageView2/1/w/750/h/750" 292 | }, 293 | { 294 | "name": "八宝酱菜", 295 | "price": 4, 296 | "oldPrice": "", 297 | "description": "", 298 | "sellCount": 84, 299 | "rating": 100, 300 | "info": "", 301 | "ratings": [ 302 | { 303 | "username": "3******c", 304 | "rateTime": 1469281964000, 305 | "rateType": 0, 306 | "text": "", 307 | "avatar": "http://static.galileo.xiaojukeji.com/static/tms/default_header.png" 308 | }, 309 | { 310 | "username": "2******3", 311 | "rateTime": 1469271264000, 312 | "rateType": 0, 313 | "text": "", 314 | "avatar": "http://static.galileo.xiaojukeji.com/static/tms/default_header.png" 315 | }, 316 | { 317 | "username": "3******b", 318 | "rateTime": 1469261964000, 319 | "rateType": 0, 320 | "text": "", 321 | "avatar": "http://static.galileo.xiaojukeji.com/static/tms/default_header.png" 322 | } 323 | ], 324 | "icon": "http://fuss10.elemecdn.com/9/b5/469d8854f9a3a03797933fd01398bjpeg.jpeg?imageView2/1/w/114/h/114", 325 | "image": "http://fuss10.elemecdn.com/9/b5/469d8854f9a3a03797933fd01398bjpeg.jpeg?imageView2/1/w/750/h/750" 326 | }, 327 | { 328 | "name": "红枣山药糙米粥", 329 | "price": 10, 330 | "oldPrice": "", 331 | "description": "", 332 | "sellCount": 81, 333 | "rating": 91, 334 | "info": "", 335 | "ratings": [ 336 | { 337 | "username": "3******c", 338 | "rateTime": 1469281964000, 339 | "rateType": 0, 340 | "text": "", 341 | "avatar": "http://static.galileo.xiaojukeji.com/static/tms/default_header.png" 342 | }, 343 | { 344 | "username": "2******3", 345 | "rateTime": 1469271264000, 346 | "rateType": 0, 347 | "text": "", 348 | "avatar": "http://static.galileo.xiaojukeji.com/static/tms/default_header.png" 349 | }, 350 | { 351 | "username": "3******b", 352 | "rateTime": 1469261964000, 353 | "rateType": 0, 354 | "text": "", 355 | "avatar": "http://static.galileo.xiaojukeji.com/static/tms/default_header.png" 356 | } 357 | ], 358 | "icon": "http://fuss10.elemecdn.com/9/b5/469d8854f9a3a03797933fd01398bjpeg.jpeg?imageView2/1/w/114/h/114", 359 | "image": "http://fuss10.elemecdn.com/9/b5/469d8854f9a3a03797933fd01398bjpeg.jpeg?imageView2/1/w/750/h/750" 360 | }, 361 | { 362 | "name": "糊塌子", 363 | "price": 10, 364 | "oldPrice": "", 365 | "description": "", 366 | "sellCount": 80, 367 | "rating": 93, 368 | "info": "", 369 | "ratings": [ 370 | { 371 | "username": "3******c", 372 | "rateTime": 1469281964000, 373 | "rateType": 0, 374 | "text": "", 375 | "avatar": "http://static.galileo.xiaojukeji.com/static/tms/default_header.png" 376 | }, 377 | { 378 | "username": "2******3", 379 | "rateTime": 1469271264000, 380 | "rateType": 0, 381 | "text": "", 382 | "avatar": "http://static.galileo.xiaojukeji.com/static/tms/default_header.png" 383 | }, 384 | { 385 | "username": "3******b", 386 | "rateTime": 1469261964000, 387 | "rateType": 0, 388 | "text": "", 389 | "avatar": "http://static.galileo.xiaojukeji.com/static/tms/default_header.png" 390 | } 391 | ], 392 | "icon": "http://fuss10.elemecdn.com/0/05/097a2a59fd2a2292d08067e16380cjpeg.jpeg?imageView2/1/w/114/h/114", 393 | "image": "http://fuss10.elemecdn.com/0/05/097a2a59fd2a2292d08067e16380cjpeg.jpeg?imageView2/1/w/750/h/750" 394 | } 395 | ] 396 | }, 397 | { 398 | "name": "单人精彩套餐", 399 | "type": 2, 400 | "foods": [ 401 | { 402 | "name": "红枣山药粥套餐", 403 | "price": 29, 404 | "oldPrice": 36, 405 | "description": "红枣山药糙米粥,素材包,爽口莴笋丝,四川泡菜或八宝酱菜,配菜可备注", 406 | "sellCount": 17, 407 | "rating": 100, 408 | "info": "", 409 | "ratings": [ 410 | { 411 | "username": "2******3", 412 | "rateTime": 1469271264000, 413 | "rateType": 0, 414 | "text": "", 415 | "avatar": "http://static.galileo.xiaojukeji.com/static/tms/default_header.png" 416 | } 417 | ], 418 | "icon": "http://fuss10.elemecdn.com/6/72/cb844f0bb60c502c6d5c05e0bddf5jpeg.jpeg?imageView2/1/w/114/h/114", 419 | "image": "http://fuss10.elemecdn.com/6/72/cb844f0bb60c502c6d5c05e0bddf5jpeg.jpeg?imageView2/1/w/750/h/750" 420 | } 421 | ] 422 | }, 423 | { 424 | "name": "冰爽饮品限时特惠", 425 | "type": 1, 426 | "foods": [ 427 | { 428 | "name": "VC无限橙果汁", 429 | "price": 8, 430 | "oldPrice": 10, 431 | "description": "", 432 | "sellCount": 15, 433 | "rating": 100, 434 | "info": "", 435 | "ratings": [ 436 | { 437 | "username": "3******c", 438 | "rateTime": 1469281964000, 439 | "rateType": 0, 440 | "text": "还可以", 441 | "avatar": "http://static.galileo.xiaojukeji.com/static/tms/default_header.png" 442 | }, 443 | { 444 | "username": "2******3", 445 | "rateTime": 1469271264000, 446 | "rateType": 0, 447 | "text": "", 448 | "avatar": "http://static.galileo.xiaojukeji.com/static/tms/default_header.png" 449 | } 450 | ], 451 | "icon": "http://fuss10.elemecdn.com/e/c6/f348e811772016ae24e968238bcbfjpeg.jpeg?imageView2/1/w/114/h/114", 452 | "image": "http://fuss10.elemecdn.com/e/c6/f348e811772016ae24e968238bcbfjpeg.jpeg?imageView2/1/w/750/h/750" 453 | } 454 | ] 455 | }, 456 | { 457 | "name": "精选热菜", 458 | "type": -1, 459 | "foods": [ 460 | { 461 | "name": "娃娃菜炖豆腐", 462 | "price": 17, 463 | "oldPrice": "", 464 | "description": "", 465 | "sellCount": 43, 466 | "rating": 92, 467 | "info": "", 468 | "ratings": [ 469 | { 470 | "username": "3******c", 471 | "rateTime": 1469281964000, 472 | "rateType": 0, 473 | "text": "菜量还可以,味道还可以", 474 | "avatar": "http://static.galileo.xiaojukeji.com/static/tms/default_header.png" 475 | }, 476 | { 477 | "username": "2******3", 478 | "rateTime": 1469271264000, 479 | "rateType": 0, 480 | "text": "", 481 | "avatar": "http://static.galileo.xiaojukeji.com/static/tms/default_header.png" 482 | } 483 | ], 484 | "icon": "http://fuss10.elemecdn.com/d/2d/b1eb45b305635d9dd04ddf157165fjpeg.jpeg?imageView2/1/w/114/h/114", 485 | "image": "http://fuss10.elemecdn.com/d/2d/b1eb45b305635d9dd04ddf157165fjpeg.jpeg?imageView2/1/w/750/h/750" 486 | }, 487 | { 488 | "name": "手撕包菜", 489 | "price": 16, 490 | "oldPrice": "", 491 | "description": "", 492 | "sellCount": 29, 493 | "rating": 100, 494 | "info": "", 495 | "ratings": [ 496 | { 497 | "username": "3******c", 498 | "rateTime": 1469281964000, 499 | "rateType": 0, 500 | "text": "", 501 | "avatar": "http://static.galileo.xiaojukeji.com/static/tms/default_header.png" 502 | }, 503 | { 504 | "username": "2******3", 505 | "rateTime": 1469271264000, 506 | "rateType": 0, 507 | "text": "", 508 | "avatar": "http://static.galileo.xiaojukeji.com/static/tms/default_header.png" 509 | } 510 | ], 511 | "icon": "http://fuss10.elemecdn.com/9/c6/f3bc84468820121112e79583c24efjpeg.jpeg?imageView2/1/w/114/h/114", 512 | "image": "http://fuss10.elemecdn.com/9/c6/f3bc84468820121112e79583c24efjpeg.jpeg?imageView2/1/w/750/h/750" 513 | }, 514 | { 515 | "name": "香酥黄金鱼/3条", 516 | "price": 11, 517 | "oldPrice": "", 518 | "description": "", 519 | "sellCount": 15, 520 | "rating": 100, 521 | "info": "", 522 | "ratings": [ 523 | { 524 | "username": "3******c", 525 | "rateTime": 1469281964000, 526 | "rateType": 0, 527 | "text": "", 528 | "avatar": "http://static.galileo.xiaojukeji.com/static/tms/default_header.png" 529 | }, 530 | { 531 | "username": "2******3", 532 | "rateTime": 1469271264000, 533 | "rateType": 0, 534 | "text": "", 535 | "avatar": "http://static.galileo.xiaojukeji.com/static/tms/default_header.png" 536 | } 537 | ], 538 | "icon": "http://fuss10.elemecdn.com/4/e7/8277a6a2ea0a2e97710290499fc41jpeg.jpeg?imageView2/1/w/114/h/114", 539 | "image": "http://fuss10.elemecdn.com/4/e7/8277a6a2ea0a2e97710290499fc41jpeg.jpeg?imageView2/1/w/750/h/750" 540 | } 541 | ] 542 | }, 543 | { 544 | "name": "爽口凉菜", 545 | "type": -1, 546 | "foods": [ 547 | { 548 | "name": "八宝酱菜", 549 | "price": 4, 550 | "oldPrice": "", 551 | "description": "", 552 | "sellCount": 84, 553 | "rating": 100, 554 | "info": "", 555 | "ratings": [ 556 | { 557 | "username": "3******c", 558 | "rateTime": 1469281964000, 559 | "rateType": 0, 560 | "text": "", 561 | "avatar": "http://static.galileo.xiaojukeji.com/static/tms/default_header.png" 562 | }, 563 | { 564 | "username": "2******3", 565 | "rateTime": 1469271264000, 566 | "rateType": 0, 567 | "text": "", 568 | "avatar": "http://static.galileo.xiaojukeji.com/static/tms/default_header.png" 569 | }, 570 | { 571 | "username": "3******b", 572 | "rateTime": 1469261964000, 573 | "rateType": 0, 574 | "text": "", 575 | "avatar": "http://static.galileo.xiaojukeji.com/static/tms/default_header.png" 576 | } 577 | ], 578 | "icon": "http://fuss10.elemecdn.com/9/b5/469d8854f9a3a03797933fd01398bjpeg.jpeg?imageView2/1/w/114/h/114", 579 | "image": "http://fuss10.elemecdn.com/9/b5/469d8854f9a3a03797933fd01398bjpeg.jpeg?imageView2/1/w/750/h/750" 580 | }, 581 | { 582 | "name": "拍黄瓜", 583 | "price": 9, 584 | "oldPrice": "", 585 | "description": "", 586 | "sellCount": 28, 587 | "rating": 100, 588 | "info": "", 589 | "ratings": [ 590 | { 591 | "username": "3******c", 592 | "rateTime": 1469281964000, 593 | "rateType": 0, 594 | "text": "", 595 | "avatar": "http://static.galileo.xiaojukeji.com/static/tms/default_header.png" 596 | }, 597 | { 598 | "username": "2******3", 599 | "rateTime": 1469271264000, 600 | "rateType": 0, 601 | "text": "", 602 | "avatar": "http://static.galileo.xiaojukeji.com/static/tms/default_header.png" 603 | }, 604 | { 605 | "username": "3******b", 606 | "rateTime": 1469261964000, 607 | "rateType": 0, 608 | "text": "", 609 | "avatar": "http://static.galileo.xiaojukeji.com/static/tms/default_header.png" 610 | } 611 | ], 612 | "icon": "http://fuss10.elemecdn.com/6/54/f654985b4e185f06eb07f8fa2b2e8jpeg.jpeg?imageView2/1/w/114/h/114", 613 | "image": "http://fuss10.elemecdn.com/6/54/f654985b4e185f06eb07f8fa2b2e8jpeg.jpeg?imageView2/1/w/750/h/750" 614 | } 615 | ] 616 | }, 617 | { 618 | "name": "精选套餐", 619 | "type": -1, 620 | "foods": [ 621 | { 622 | "name": "红豆薏米粥套餐", 623 | "price": 37, 624 | "oldPrice": "", 625 | "description": "红豆薏米粥,三鲜干蒸烧卖,拍黄瓜", 626 | "sellCount": 3, 627 | "rating": 100, 628 | "info": "", 629 | "ratings": [ 630 | { 631 | "username": "2******3", 632 | "rateTime": 1469271264000, 633 | "rateType": 0, 634 | "text": "", 635 | "avatar": "http://static.galileo.xiaojukeji.com/static/tms/default_header.png" 636 | } 637 | ], 638 | "icon": "http://fuss10.elemecdn.com/f/49/27f26ed00c025b2200a9ccbb7e67ejpeg.jpeg?imageView2/1/w/114/h/114", 639 | "image": "http://fuss10.elemecdn.com/f/49/27f26ed00c025b2200a9ccbb7e67ejpeg.jpeg?imageView2/1/w/750/h/750" 640 | }, 641 | { 642 | "name": "皮蛋瘦肉粥套餐", 643 | "price": 31, 644 | "oldPrice": "", 645 | "description": "", 646 | "sellCount": 12, 647 | "rating": 100, 648 | "info": "", 649 | "ratings": [ 650 | { 651 | "username": "2******3", 652 | "rateTime": 1469271264000, 653 | "rateType": 0, 654 | "text": "", 655 | "avatar": "http://static.galileo.xiaojukeji.com/static/tms/default_header.png" 656 | } 657 | ], 658 | "icon": "http://fuss10.elemecdn.com/8/96/f444a8087f0e940ef264617f9d98ajpeg.jpeg?imageView2/1/w/114/h/114", 659 | "image": "http://fuss10.elemecdn.com/8/96/f444a8087f0e940ef264617f9d98ajpeg.jpeg?imageView2/1/w/750/h/750" 660 | } 661 | ] 662 | }, 663 | { 664 | "name": "果拼果汁", 665 | "type": -1, 666 | "foods": [ 667 | { 668 | "name": "蜜瓜圣女萝莉杯", 669 | "price": 6, 670 | "oldPrice": "", 671 | "description": "", 672 | "sellCount": 1, 673 | "rating": "", 674 | "info": "", 675 | "ratings": [], 676 | "icon": "http://fuss10.elemecdn.com/b/5f/b3b04c259d5ec9fa52e1856ee50dajpeg.jpeg?imageView2/1/w/114/h/114", 677 | "image": "http://fuss10.elemecdn.com/b/5f/b3b04c259d5ec9fa52e1856ee50dajpeg.jpeg?imageView2/1/w/750/h/750" 678 | }, 679 | { 680 | "name": "加多宝", 681 | "price": 6, 682 | "oldPrice": "", 683 | "description": "", 684 | "sellCount": 7, 685 | "rating": 100, 686 | "info": "", 687 | "ratings": [ 688 | { 689 | "username": "3******c", 690 | "rateTime": 1469281964000, 691 | "rateType": 0, 692 | "text": "", 693 | "avatar": "http://static.galileo.xiaojukeji.com/static/tms/default_header.png" 694 | }, 695 | { 696 | "username": "2******3", 697 | "rateTime": 1469271264000, 698 | "rateType": 0, 699 | "text": "", 700 | "avatar": "http://static.galileo.xiaojukeji.com/static/tms/default_header.png" 701 | }, 702 | { 703 | "username": "3******b", 704 | "rateTime": 1469261964000, 705 | "rateType": 0, 706 | "text": "", 707 | "avatar": "http://static.galileo.xiaojukeji.com/static/tms/default_header.png" 708 | } 709 | ], 710 | "icon": "http://fuss10.elemecdn.com/b/9f/5e6c99c593cf65229225c5661bcdejpeg.jpeg?imageView2/1/w/114/h/114", 711 | "image": "http://fuss10.elemecdn.com/b/9f/5e6c99c593cf65229225c5661bcdejpeg.jpeg?imageView2/1/w/750/h/750" 712 | }, 713 | { 714 | "name": "VC无限橙果汁", 715 | "price": 8, 716 | "oldPrice": 10, 717 | "description": "", 718 | "sellCount": 15, 719 | "rating": 100, 720 | "info": "", 721 | "ratings": [ 722 | { 723 | "username": "3******c", 724 | "rateTime": 1469281964000, 725 | "rateType": 0, 726 | "text": "还可以", 727 | "avatar": "http://static.galileo.xiaojukeji.com/static/tms/default_header.png" 728 | }, 729 | { 730 | "username": "2******3", 731 | "rateTime": 1469271264000, 732 | "rateType": 0, 733 | "text": "", 734 | "avatar": "http://static.galileo.xiaojukeji.com/static/tms/default_header.png" 735 | } 736 | ], 737 | "icon": "http://fuss10.elemecdn.com/e/c6/f348e811772016ae24e968238bcbfjpeg.jpeg?imageView2/1/w/114/h/114", 738 | "image": "http://fuss10.elemecdn.com/e/c6/f348e811772016ae24e968238bcbfjpeg.jpeg?imageView2/1/w/750/h/750" 739 | } 740 | ] 741 | }, 742 | { 743 | "name": "小吃主食", 744 | "type": -1, 745 | "foods": [ 746 | { 747 | "name": "扁豆焖面", 748 | "price": 14, 749 | "oldPrice": "", 750 | "description": "", 751 | "sellCount": 188, 752 | "rating": 96, 753 | "info": "", 754 | "ratings": [ 755 | { 756 | "username": "3******c", 757 | "rateTime": 1469281964000, 758 | "rateType": 0, 759 | "text": "", 760 | "avatar": "http://static.galileo.xiaojukeji.com/static/tms/default_header.png" 761 | }, 762 | { 763 | "username": "2******3", 764 | "rateTime": 1469271264000, 765 | "rateType": 0, 766 | "text": "", 767 | "avatar": "http://static.galileo.xiaojukeji.com/static/tms/default_header.png" 768 | }, 769 | { 770 | "username": "3******b", 771 | "rateTime": 1469261964000, 772 | "rateType": 1, 773 | "text": "", 774 | "avatar": "http://static.galileo.xiaojukeji.com/static/tms/default_header.png" 775 | } 776 | ], 777 | "icon": "http://fuss10.elemecdn.com/c/6b/29e3d29b0db63d36f7c500bca31d8jpeg.jpeg?imageView2/1/w/114/h/114", 778 | "image": "http://fuss10.elemecdn.com/c/6b/29e3d29b0db63d36f7c500bca31d8jpeg.jpeg?imageView2/1/w/750/h/750" 779 | }, 780 | { 781 | "name": "葱花饼", 782 | "price": 10, 783 | "oldPrice": "", 784 | "description": "", 785 | "sellCount": 124, 786 | "rating": 85, 787 | "info": "", 788 | "ratings": [ 789 | { 790 | "username": "3******c", 791 | "rateTime": 1469281964000, 792 | "rateType": 1, 793 | "text": "没啥味道", 794 | "avatar": "http://static.galileo.xiaojukeji.com/static/tms/default_header.png" 795 | }, 796 | { 797 | "username": "2******3", 798 | "rateTime": 1469271264000, 799 | "rateType": 1, 800 | "text": "很一般啊", 801 | "avatar": "http://static.galileo.xiaojukeji.com/static/tms/default_header.png" 802 | }, 803 | { 804 | "username": "3******b", 805 | "rateTime": 1469261964000, 806 | "rateType": 0, 807 | "text": "", 808 | "avatar": "http://static.galileo.xiaojukeji.com/static/tms/default_header.png" 809 | } 810 | ], 811 | "icon": "http://fuss10.elemecdn.com/f/28/a51e7b18751bcdf871648a23fd3b4jpeg.jpeg?imageView2/1/w/114/h/114", 812 | "image": "http://fuss10.elemecdn.com/f/28/a51e7b18751bcdf871648a23fd3b4jpeg.jpeg?imageView2/1/w/750/h/750" 813 | }, 814 | { 815 | "name": "牛肉馅饼", 816 | "price": 14, 817 | "oldPrice": "", 818 | "description": "", 819 | "sellCount": 114, 820 | "rating": 91, 821 | "info": "", 822 | "ratings": [ 823 | { 824 | "username": "3******c", 825 | "rateTime": 1469281964000, 826 | "rateType": 1, 827 | "text": "难吃不推荐", 828 | "avatar": "http://static.galileo.xiaojukeji.com/static/tms/default_header.png" 829 | }, 830 | { 831 | "username": "2******3", 832 | "rateTime": 1469271264000, 833 | "rateType": 0, 834 | "text": "", 835 | "avatar": "http://static.galileo.xiaojukeji.com/static/tms/default_header.png" 836 | }, 837 | { 838 | "username": "3******b", 839 | "rateTime": 1469261964000, 840 | "rateType": 0, 841 | "text": "", 842 | "avatar": "http://static.galileo.xiaojukeji.com/static/tms/default_header.png" 843 | } 844 | ], 845 | "icon": "http://fuss10.elemecdn.com/d/b9/bcab0e8ad97758e65ae5a62b2664ejpeg.jpeg?imageView2/1/w/114/h/114", 846 | "image": "http://fuss10.elemecdn.com/d/b9/bcab0e8ad97758e65ae5a62b2664ejpeg.jpeg?imageView2/1/w/750/h/750" 847 | }, 848 | { 849 | "name": "招牌猪肉白菜锅贴/10个", 850 | "price": 17, 851 | "oldPrice": "", 852 | "description": "", 853 | "sellCount": 101, 854 | "rating": 78, 855 | "info": "", 856 | "ratings": [ 857 | { 858 | "username": "3******c", 859 | "rateTime": 1469281964000, 860 | "rateType": 1, 861 | "text": "不脆,不好吃", 862 | "avatar": "http://static.galileo.xiaojukeji.com/static/tms/default_header.png" 863 | }, 864 | { 865 | "username": "2******3", 866 | "rateTime": 1469271264000, 867 | "rateType": 0, 868 | "text": "", 869 | "avatar": "http://static.galileo.xiaojukeji.com/static/tms/default_header.png" 870 | }, 871 | { 872 | "username": "3******b", 873 | "rateTime": 1469261964000, 874 | "rateType": 0, 875 | "text": "", 876 | "avatar": "http://static.galileo.xiaojukeji.com/static/tms/default_header.png" 877 | } 878 | ], 879 | "icon": "http://fuss10.elemecdn.com/7/72/9a580c1462ca1e4d3c07e112bc035jpeg.jpeg?imageView2/1/w/114/h/114", 880 | "image": "http://fuss10.elemecdn.com/7/72/9a580c1462ca1e4d3c07e112bc035jpeg.jpeg?imageView2/1/w/750/h/750" 881 | }, 882 | { 883 | "name": "糊塌子", 884 | "price": 10, 885 | "oldPrice": "", 886 | "description": "", 887 | "sellCount": 80, 888 | "rating": 93, 889 | "info": "", 890 | "ratings": [ 891 | { 892 | "username": "3******c", 893 | "rateTime": 1469281964000, 894 | "rateType": 0, 895 | "text": "", 896 | "avatar": "http://static.galileo.xiaojukeji.com/static/tms/default_header.png" 897 | }, 898 | { 899 | "username": "2******3", 900 | "rateTime": 1469271264000, 901 | "rateType": 0, 902 | "text": "", 903 | "avatar": "http://static.galileo.xiaojukeji.com/static/tms/default_header.png" 904 | }, 905 | { 906 | "username": "3******b", 907 | "rateTime": 1469261964000, 908 | "rateType": 0, 909 | "text": "", 910 | "avatar": "http://static.galileo.xiaojukeji.com/static/tms/default_header.png" 911 | } 912 | ], 913 | "icon": "http://fuss10.elemecdn.com/0/05/097a2a59fd2a2292d08067e16380cjpeg.jpeg?imageView2/1/w/114/h/114", 914 | "image": "http://fuss10.elemecdn.com/0/05/097a2a59fd2a2292d08067e16380cjpeg.jpeg?imageView2/1/w/750/h/750" 915 | } 916 | ] 917 | }, 918 | { 919 | "name": "特色粥品", 920 | "type": -1, 921 | "foods": [ 922 | { 923 | "name": "皮蛋瘦肉粥", 924 | "price": 10, 925 | "oldPrice": "", 926 | "description": "咸粥", 927 | "sellCount": 229, 928 | "rating": 100, 929 | "ratings": [ 930 | { 931 | "username": "3******c", 932 | "rateTime": 1469281964000, 933 | "rateType": 0, 934 | "text": "很喜欢的粥", 935 | "avatar": "http://static.galileo.xiaojukeji.com/static/tms/default_header.png" 936 | }, 937 | { 938 | "username": "2******3", 939 | "rateTime": 1469271264000, 940 | "rateType": 0, 941 | "text": "", 942 | "avatar": "http://static.galileo.xiaojukeji.com/static/tms/default_header.png" 943 | }, 944 | { 945 | "username": "3******b", 946 | "rateTime": 1469261964000, 947 | "rateType": 1, 948 | "text": "", 949 | "avatar": "http://static.galileo.xiaojukeji.com/static/tms/default_header.png" 950 | } 951 | ], 952 | "icon": "http://fuss10.elemecdn.com/c/cd/c12745ed8a5171e13b427dbc39401jpeg.jpeg?imageView2/1/w/114/h/114", 953 | "image": "http://fuss10.elemecdn.com/c/cd/c12745ed8a5171e13b427dbc39401jpeg.jpeg?imageView2/1/w/750/h/750" 954 | }, 955 | { 956 | "name": "南瓜粥", 957 | "price": 9, 958 | "oldPrice": "", 959 | "description": "甜粥", 960 | "sellCount": 91, 961 | "rating": 100, 962 | "info": "", 963 | "ratings": [ 964 | { 965 | "username": "3******c", 966 | "rateTime": 1469281964000, 967 | "rateType": 0, 968 | "text": "", 969 | "avatar": "http://static.galileo.xiaojukeji.com/static/tms/default_header.png" 970 | }, 971 | { 972 | "username": "2******3", 973 | "rateTime": 1469271264000, 974 | "rateType": 0, 975 | "text": "", 976 | "avatar": "http://static.galileo.xiaojukeji.com/static/tms/default_header.png" 977 | }, 978 | { 979 | "username": "3******b", 980 | "rateTime": 1469261964000, 981 | "rateType": 0, 982 | "text": "", 983 | "avatar": "http://static.galileo.xiaojukeji.com/static/tms/default_header.png" 984 | } 985 | ], 986 | "icon": "http://fuss10.elemecdn.com/8/a6/453f65f16b1391942af11511b7a90jpeg.jpeg?imageView2/1/w/114/h/114", 987 | "image": "http://fuss10.elemecdn.com/8/a6/453f65f16b1391942af11511b7a90jpeg.jpeg?imageView2/1/w/750/h/750" 988 | }, 989 | { 990 | "name": "红豆薏米美肤粥", 991 | "price": 12, 992 | "oldPrice": "", 993 | "description": "甜粥", 994 | "sellCount": 86, 995 | "rating": 100, 996 | "info": "", 997 | "ratings": [ 998 | { 999 | "username": "3******c", 1000 | "rateTime": 1469281964000, 1001 | "rateType": 0, 1002 | "text": "", 1003 | "avatar": "http://static.galileo.xiaojukeji.com/static/tms/default_header.png" 1004 | }, 1005 | { 1006 | "username": "2******3", 1007 | "rateTime": 1469271264000, 1008 | "rateType": 0, 1009 | "text": "", 1010 | "avatar": "http://static.galileo.xiaojukeji.com/static/tms/default_header.png" 1011 | }, 1012 | { 1013 | "username": "3******b", 1014 | "rateTime": 1469261964000, 1015 | "rateType": 0, 1016 | "text": "", 1017 | "avatar": "http://static.galileo.xiaojukeji.com/static/tms/default_header.png" 1018 | } 1019 | ], 1020 | "icon": "http://fuss10.elemecdn.com/d/22/260bd78ee6ac6051136c5447fe307jpeg.jpeg?imageView2/1/w/114/h/114", 1021 | "image": "http://fuss10.elemecdn.com/d/22/260bd78ee6ac6051136c5447fe307jpeg.jpeg?imageView2/1/w/750/h/750" 1022 | }, 1023 | { 1024 | "name": "红枣山药糙米粥", 1025 | "price": 10, 1026 | "oldPrice": "", 1027 | "description": "", 1028 | "sellCount": 81, 1029 | "rating": 91, 1030 | "info": "", 1031 | "ratings": [ 1032 | { 1033 | "username": "3******c", 1034 | "rateTime": 1469281964000, 1035 | "rateType": 0, 1036 | "text": "", 1037 | "avatar": "http://static.galileo.xiaojukeji.com/static/tms/default_header.png" 1038 | }, 1039 | { 1040 | "username": "2******3", 1041 | "rateTime": 1469271264000, 1042 | "rateType": 0, 1043 | "text": "", 1044 | "avatar": "http://static.galileo.xiaojukeji.com/static/tms/default_header.png" 1045 | }, 1046 | { 1047 | "username": "3******b", 1048 | "rateTime": 1469261964000, 1049 | "rateType": 0, 1050 | "text": "", 1051 | "avatar": "http://static.galileo.xiaojukeji.com/static/tms/default_header.png" 1052 | } 1053 | ], 1054 | "icon": "http://fuss10.elemecdn.com/9/b5/469d8854f9a3a03797933fd01398bjpeg.jpeg?imageView2/1/w/114/h/114", 1055 | "image": "http://fuss10.elemecdn.com/9/b5/469d8854f9a3a03797933fd01398bjpeg.jpeg?imageView2/1/w/750/h/750" 1056 | }, 1057 | { 1058 | "name": "鲜蔬菌菇粥", 1059 | "price": 11, 1060 | "oldPrice": "", 1061 | "description": "咸粥", 1062 | "sellCount": 56, 1063 | "rating": 100, 1064 | "info": "", 1065 | "ratings": [ 1066 | { 1067 | "username": "3******c", 1068 | "rateTime": 1469281964000, 1069 | "rateType": 0, 1070 | "text": "", 1071 | "avatar": "http://static.galileo.xiaojukeji.com/static/tms/default_header.png" 1072 | }, 1073 | { 1074 | "username": "2******3", 1075 | "rateTime": 1469271264000, 1076 | "rateType": 0, 1077 | "text": "" 1078 | }, 1079 | { 1080 | "username": "3******b", 1081 | "rateTime": 1469261964000, 1082 | "rateType": 0, 1083 | "text": "", 1084 | "avatar": "http://static.galileo.xiaojukeji.com/static/tms/default_header.png" 1085 | } 1086 | ], 1087 | "icon": "http://fuss10.elemecdn.com/e/a3/5317c68dd618929b6ac05804e429ajpeg.jpeg?imageView2/1/w/114/h/114", 1088 | "image": "http://fuss10.elemecdn.com/e/a3/5317c68dd618929b6ac05804e429ajpeg.jpeg?imageView2/1/w/750/h/750" 1089 | }, 1090 | { 1091 | "name": "田园蔬菜粥", 1092 | "price": 10, 1093 | "oldPrice": "", 1094 | "description": "咸粥", 1095 | "sellCount": 33, 1096 | "rating": 100, 1097 | "info": "", 1098 | "ratings": [ 1099 | { 1100 | "username": "3******c", 1101 | "rateTime": 1469281964000, 1102 | "rateType": 0, 1103 | "text": "", 1104 | "avatar": "http://static.galileo.xiaojukeji.com/static/tms/default_header.png" 1105 | }, 1106 | { 1107 | "username": "2******3", 1108 | "rateTime": 1469271264000, 1109 | "rateType": 0, 1110 | "text": "", 1111 | "avatar": "http://static.galileo.xiaojukeji.com/static/tms/default_header.png" 1112 | }, 1113 | { 1114 | "username": "3******b", 1115 | "rateTime": 1469261964000, 1116 | "rateType": 0, 1117 | "text": "", 1118 | "avatar": "http://static.galileo.xiaojukeji.com/static/tms/default_header.png" 1119 | } 1120 | ], 1121 | "icon": "http://fuss10.elemecdn.com/a/94/7371083792c19df00e546b29e344cjpeg.jpeg?imageView2/1/w/114/h/114", 1122 | "image": "http://fuss10.elemecdn.com/a/94/7371083792c19df00e546b29e344cjpeg.jpeg?imageView2/1/w/750/h/750" 1123 | } 1124 | ] 1125 | } 1126 | ], 1127 | "ratings": [ 1128 | { 1129 | "username": "3******c", 1130 | "rateTime": 1469281964000, 1131 | "deliveryTime": 30, 1132 | "score": 5, 1133 | "rateType": 0, 1134 | "text": "不错,粥很好喝,我经常吃这一家,非常赞,以后也会常来吃,强烈推荐.", 1135 | "avatar": "http://static.galileo.xiaojukeji.com/static/tms/default_header.png", 1136 | "recommend": [ 1137 | "南瓜粥", 1138 | "皮蛋瘦肉粥", 1139 | "扁豆焖面", 1140 | "娃娃菜炖豆腐", 1141 | "牛肉馅饼" 1142 | ] 1143 | }, 1144 | { 1145 | "username": "2******3", 1146 | "rateTime": 1469271264000, 1147 | "deliveryTime": "", 1148 | "score": 4, 1149 | "rateType": 0, 1150 | "deliveryTime": "", 1151 | "text": "服务态度不错", 1152 | "avatar": "http://static.galileo.xiaojukeji.com/static/tms/default_header.png", 1153 | "recommend": [ 1154 | "扁豆焖面" 1155 | ] 1156 | }, 1157 | { 1158 | "username": "3******b", 1159 | "rateTime": 1469261964000, 1160 | "score": 3, 1161 | "rateType": 1, 1162 | "text": "", 1163 | "avatar": "http://static.galileo.xiaojukeji.com/static/tms/default_header.png", 1164 | "recommend": [] 1165 | }, 1166 | { 1167 | "username": "1******c", 1168 | "rateTime": 1469261864000, 1169 | "deliveryTime": 20, 1170 | "score": 5, 1171 | "rateType": 0, 1172 | "text": "良心店铺", 1173 | "avatar": "http://static.galileo.xiaojukeji.com/static/tms/default_header.png", 1174 | "recommend": [] 1175 | }, 1176 | { 1177 | "username": "2******d", 1178 | "rateTime": 1469251264000, 1179 | "deliveryTime": 10, 1180 | "score": 4, 1181 | "rateType": 0, 1182 | "text": "", 1183 | "avatar": "http://static.galileo.xiaojukeji.com/static/tms/default_header.png", 1184 | "recommend": [] 1185 | }, 1186 | { 1187 | "username": "9******0", 1188 | "rateTime": 1469241964000, 1189 | "deliveryTime": 70, 1190 | "score": 1, 1191 | "rateType": 1, 1192 | "text": "送货速度蜗牛一样", 1193 | "avatar": "http://static.galileo.xiaojukeji.com/static/tms/default_header.png", 1194 | "recommend": [] 1195 | }, 1196 | { 1197 | "username": "d******c", 1198 | "rateTime": 1469231964000, 1199 | "deliveryTime": 30, 1200 | "score": 5, 1201 | "rateType": 0, 1202 | "text": "很喜欢的粥店", 1203 | "avatar": "http://static.galileo.xiaojukeji.com/static/tms/default_header.png", 1204 | "recommend": [] 1205 | }, 1206 | { 1207 | "username": "2******3", 1208 | "rateTime": 1469221264000, 1209 | "deliveryTime": "", 1210 | "score": 4, 1211 | "rateType": 0, 1212 | "text": "量给的还可以", 1213 | "avatar": "http://static.galileo.xiaojukeji.com/static/tms/default_header.png", 1214 | "recommend": [] 1215 | }, 1216 | { 1217 | "username": "3******8", 1218 | "rateTime": 1469211964000, 1219 | "deliveryTime": "", 1220 | "score": 3, 1221 | "rateType": 1, 1222 | "text": "", 1223 | "avatar": "http://static.galileo.xiaojukeji.com/static/tms/default_header.png", 1224 | "recommend": [] 1225 | }, 1226 | { 1227 | "username": "a******a", 1228 | "rateTime": 1469201964000, 1229 | "deliveryTime": "", 1230 | "score": 4, 1231 | "rateType": 0, 1232 | "text": "孩子喜欢吃这家", 1233 | "avatar": "http://static.galileo.xiaojukeji.com/static/tms/default_header.png", 1234 | "recommend": [ 1235 | "南瓜粥" 1236 | ] 1237 | }, 1238 | { 1239 | "username": "3******3", 1240 | "rateTime": 1469191264000, 1241 | "deliveryTime": "", 1242 | "score": 4, 1243 | "rateType": 0, 1244 | "text": "粥挺好吃的", 1245 | "avatar": "http://static.galileo.xiaojukeji.com/static/tms/default_header.png", 1246 | "recommend": [] 1247 | }, 1248 | { 1249 | "username": "t******b", 1250 | "rateTime": 1469181964000, 1251 | "deliveryTime": "", 1252 | "score": 3, 1253 | "rateType": 1, 1254 | "text": "", 1255 | "avatar": "http://static.galileo.xiaojukeji.com/static/tms/default_header.png", 1256 | "recommend": [] 1257 | }, 1258 | { 1259 | "username": "f******c", 1260 | "rateTime": 1469171964000, 1261 | "deliveryTime": 15, 1262 | "score": 5, 1263 | "rateType": 0, 1264 | "text": "送货速度很快", 1265 | "avatar": "http://static.galileo.xiaojukeji.com/static/tms/default_header.png", 1266 | "recommend": [] 1267 | }, 1268 | { 1269 | "username": "k******3", 1270 | "rateTime": 1469161264000, 1271 | "deliveryTime": "", 1272 | "score": 4, 1273 | "rateType": 0, 1274 | "text": "", 1275 | "avatar": "http://static.galileo.xiaojukeji.com/static/tms/default_header.png", 1276 | "recommend": [] 1277 | }, 1278 | { 1279 | "username": "u******b", 1280 | "rateTime": 1469151964000, 1281 | "deliveryTime": "", 1282 | "score": 4, 1283 | "rateType": 0, 1284 | "text": "下雨天给快递小哥点个赞", 1285 | "avatar": "http://static.galileo.xiaojukeji.com/static/tms/default_header.png", 1286 | "recommend": [] 1287 | }, 1288 | { 1289 | "username": "s******c", 1290 | "rateTime": 1469141964000, 1291 | "deliveryTime": "", 1292 | "score": 4, 1293 | "rateType": 0, 1294 | "text": "好", 1295 | "avatar": "http://static.galileo.xiaojukeji.com/static/tms/default_header.png", 1296 | "recommend": [] 1297 | }, 1298 | { 1299 | "username": "z******3", 1300 | "rateTime": 1469131264000, 1301 | "deliveryTime": "", 1302 | "score": 5, 1303 | "rateType": 0, 1304 | "text": "吃了还想再吃", 1305 | "avatar": "http://static.galileo.xiaojukeji.com/static/tms/default_header.png", 1306 | "recommend": [] 1307 | }, 1308 | { 1309 | "username": "n******b", 1310 | "rateTime": 1469121964000, 1311 | "deliveryTime": "", 1312 | "score": 3, 1313 | "rateType": 1, 1314 | "text": "发票开的不对", 1315 | "avatar": "http://static.galileo.xiaojukeji.com/static/tms/default_header.png", 1316 | "recommend": [] 1317 | }, 1318 | { 1319 | "username": "m******c", 1320 | "rateTime": 1469111964000, 1321 | "deliveryTime": 30, 1322 | "score": 5, 1323 | "rateType": 0, 1324 | "text": "好吃", 1325 | "avatar": "http://static.galileo.xiaojukeji.com/static/tms/default_header.png", 1326 | "recommend": [] 1327 | }, 1328 | { 1329 | "username": "l******3", 1330 | "rateTime": 1469101264000, 1331 | "deliveryTime": 40, 1332 | "score": 5, 1333 | "rateType": 0, 1334 | "text": "还不错吧", 1335 | "avatar": "http://static.galileo.xiaojukeji.com/static/tms/default_header.png", 1336 | "recommend": [] 1337 | }, 1338 | { 1339 | "username": "3******o", 1340 | "rateTime": 1469091964000, 1341 | "deliveryTime": "", 1342 | "score": 2, 1343 | "rateType": 1, 1344 | "text": "", 1345 | "avatar": "http://static.galileo.xiaojukeji.com/static/tms/default_header.png", 1346 | "recommend": [] 1347 | }, 1348 | { 1349 | "username": "3******p", 1350 | "rateTime": 1469081964000, 1351 | "deliveryTime": "", 1352 | "score": 4, 1353 | "rateType": 0, 1354 | "text": "很喜欢的粥", 1355 | "avatar": "http://static.galileo.xiaojukeji.com/static/tms/default_header.png", 1356 | "recommend": [] 1357 | }, 1358 | { 1359 | "username": "o******k", 1360 | "rateTime": 1469071264000, 1361 | "deliveryTime": "", 1362 | "score": 5, 1363 | "rateType": 0, 1364 | "text": "", 1365 | "avatar": "http://static.galileo.xiaojukeji.com/static/tms/default_header.png", 1366 | "recommend": [] 1367 | }, 1368 | { 1369 | "username": "k******b", 1370 | "rateTime": 1469061964000, 1371 | "deliveryTime": "", 1372 | "score": 4, 1373 | "rateType": 0, 1374 | "text": "", 1375 | "avatar": "http://static.galileo.xiaojukeji.com/static/tms/default_header.png", 1376 | "recommend": [] 1377 | } 1378 | ] 1379 | } -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | blog 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /mock/mock-server.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const app = new express(); 3 | const fs = require('fs'); 4 | 5 | const appData = require('../data.json'); 6 | const seller = appData.seller; 7 | const goods = appData.goods; 8 | const ratings = appData.ratings; 9 | 10 | app.get('/api/seller', function(req, res){ 11 | res.header({'Access-Control-Allow-Origin' : '*'}); 12 | res.json({ 13 | code: 0, 14 | data: seller 15 | }); 16 | }); 17 | 18 | app.get('/api/goods', function(req, res){ 19 | res.header({'Access-Control-Allow-Origin': '*'}); 20 | res.json({ 21 | code: 0, 22 | data: goods 23 | }); 24 | }); 25 | 26 | app.get('/api/ratings', function(req, res){ 27 | res.header({'Access-Control-Allow-Origin': '*'}); 28 | res.json({ 29 | code: 0, 30 | data: ratings 31 | }); 32 | }); 33 | 34 | app.listen(3000); -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "blog-app", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "start": "webpack-dev-server --history-api-fallback", 9 | "build": "webpack -p" 10 | }, 11 | "author": "", 12 | "license": "ISC", 13 | "dependencies": { 14 | "alloytouch": "^0.2.5", 15 | "antd": "^2.12.2", 16 | "axios": "^0.16.2", 17 | "babel-core": "^6.25.0", 18 | "babel-loader": "^7.1.1", 19 | "babel-plugin-import": "^1.2.1", 20 | "babel-preset-es2015": "^6.24.1", 21 | "babel-preset-react": "^6.24.1", 22 | "better-scroll": "^0.4.0", 23 | "classnames": "^2.2.5", 24 | "css-loader": "^0.28.4", 25 | "express": "^4.15.3", 26 | "extract-text-webpack-plugin": "^3.0.0", 27 | "file-loader": "^0.11.2", 28 | "html-webpack-plugin": "^2.29.0", 29 | "less": "^2.7.2", 30 | "less-loader": "^4.0.5", 31 | "path": "^0.12.7", 32 | "react": "^15.6.1", 33 | "react-addons-css-transition-group": "^15.6.0", 34 | "react-dom": "^15.6.1", 35 | "react-router": "^4.1.2", 36 | "react-router-dom": "^4.1.2", 37 | "url-loader": "^0.5.9", 38 | "webpack": "^3.4.1", 39 | "webpack-dev-server": "^2.7.1" 40 | }, 41 | "theme": { 42 | "primary-color": "#1DA57A" 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/App.jsx: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import { 3 | BrowserRouter as Router, Link, Route, Redirect, withRouter, Switch 4 | } from 'react-router-dom'; 5 | import ReactCSSTransitionGroup from 'react-addons-css-transition-group'; 6 | import { Header } from './components/header/header.jsx'; 7 | import { Navbar } from './components/navbar/navbar.jsx'; 8 | import { Goods } from './components/goods/goods.jsx'; 9 | import { base_url } from './common/js/config.js'; 10 | import { SUCCESS_CODE } from './common/js/code_res.js'; 11 | import axios from 'axios'; 12 | import './App.less'; 13 | 14 | 15 | const Comment = () => ( 16 |

I'm Comment

17 | ) 18 | 19 | const Seller = () => ( 20 |

I'm Seller

21 | //
22 | // 23 | //

{"I'm seller"}

24 | //
25 | //
26 | ) 27 | 28 | 29 | 30 | export class App extends Component { 31 | constructor(props){ 32 | super(props); 33 | this.state = { 34 | seller: null, 35 | } 36 | } 37 | 38 | componentDidMount() { 39 | const url = base_url + '/api/seller'; 40 | axios.get(url) 41 | .then(response => { 42 | const res = response.data; 43 | if(res.code === SUCCESS_CODE) { 44 | this.setState({ 45 | seller: res.data 46 | }); 47 | } 48 | }); 49 | } 50 | 51 | render() { 52 | const seller = this.state.seller; 53 | return ( 54 |
55 |
56 | 57 |
58 | 59 | 60 | 61 | ( 62 | 63 | )}/> 64 | 65 | 66 |
67 |
68 |
69 | ); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/App.less: -------------------------------------------------------------------------------- 1 | // .example-enter{ 2 | // opacity: 0.1; 3 | // } 4 | 5 | // .example-enter.example-enter-active{ 6 | // opacity: 1; 7 | // transition: opacity 500ms ease-in; 8 | // } 9 | 10 | // .example-leave{ 11 | // opacity: 1; 12 | // } 13 | 14 | // .example-leave.example-leave-active{ 15 | // opacity: 0.01; 16 | // transition: opacity 300ms ease-out; 17 | // } 18 | 19 | .example-appear{ 20 | opacity: 0.01; 21 | 22 | &.example-appear-active{ 23 | opacity: 2; 24 | transition: opacity 5s ease-in; 25 | } 26 | } 27 | 28 | 29 | -------------------------------------------------------------------------------- /src/common/font/icomoon.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laizimo/element-react-project/6e09c75f6ecbf4f46b5e4574bd043fa1b04ba1db/src/common/font/icomoon.eot -------------------------------------------------------------------------------- /src/common/font/icomoon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Generated by IcoMoon 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /src/common/font/icomoon.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laizimo/element-react-project/6e09c75f6ecbf4f46b5e4574bd043fa1b04ba1db/src/common/font/icomoon.ttf -------------------------------------------------------------------------------- /src/common/font/icomoon.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laizimo/element-react-project/6e09c75f6ecbf4f46b5e4574bd043fa1b04ba1db/src/common/font/icomoon.woff -------------------------------------------------------------------------------- /src/common/imgs/brand@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laizimo/element-react-project/6e09c75f6ecbf4f46b5e4574bd043fa1b04ba1db/src/common/imgs/brand@2x.png -------------------------------------------------------------------------------- /src/common/imgs/brand@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laizimo/element-react-project/6e09c75f6ecbf4f46b5e4574bd043fa1b04ba1db/src/common/imgs/brand@3x.png -------------------------------------------------------------------------------- /src/common/imgs/bulletin@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laizimo/element-react-project/6e09c75f6ecbf4f46b5e4574bd043fa1b04ba1db/src/common/imgs/bulletin@2x.png -------------------------------------------------------------------------------- /src/common/imgs/bulletin@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laizimo/element-react-project/6e09c75f6ecbf4f46b5e4574bd043fa1b04ba1db/src/common/imgs/bulletin@3x.png -------------------------------------------------------------------------------- /src/common/imgs/decrease_1@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laizimo/element-react-project/6e09c75f6ecbf4f46b5e4574bd043fa1b04ba1db/src/common/imgs/decrease_1@2x.png -------------------------------------------------------------------------------- /src/common/imgs/decrease_1@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laizimo/element-react-project/6e09c75f6ecbf4f46b5e4574bd043fa1b04ba1db/src/common/imgs/decrease_1@3x.png -------------------------------------------------------------------------------- /src/common/imgs/decrease_2@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laizimo/element-react-project/6e09c75f6ecbf4f46b5e4574bd043fa1b04ba1db/src/common/imgs/decrease_2@2x.png -------------------------------------------------------------------------------- /src/common/imgs/decrease_2@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laizimo/element-react-project/6e09c75f6ecbf4f46b5e4574bd043fa1b04ba1db/src/common/imgs/decrease_2@3x.png -------------------------------------------------------------------------------- /src/common/imgs/decrease_3@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laizimo/element-react-project/6e09c75f6ecbf4f46b5e4574bd043fa1b04ba1db/src/common/imgs/decrease_3@2x.png -------------------------------------------------------------------------------- /src/common/imgs/decrease_3@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laizimo/element-react-project/6e09c75f6ecbf4f46b5e4574bd043fa1b04ba1db/src/common/imgs/decrease_3@3x.png -------------------------------------------------------------------------------- /src/common/imgs/decrease_4@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laizimo/element-react-project/6e09c75f6ecbf4f46b5e4574bd043fa1b04ba1db/src/common/imgs/decrease_4@2x.png -------------------------------------------------------------------------------- /src/common/imgs/decrease_4@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laizimo/element-react-project/6e09c75f6ecbf4f46b5e4574bd043fa1b04ba1db/src/common/imgs/decrease_4@3x.png -------------------------------------------------------------------------------- /src/common/imgs/discount_1@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laizimo/element-react-project/6e09c75f6ecbf4f46b5e4574bd043fa1b04ba1db/src/common/imgs/discount_1@2x.png -------------------------------------------------------------------------------- /src/common/imgs/discount_1@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laizimo/element-react-project/6e09c75f6ecbf4f46b5e4574bd043fa1b04ba1db/src/common/imgs/discount_1@3x.png -------------------------------------------------------------------------------- /src/common/imgs/discount_2@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laizimo/element-react-project/6e09c75f6ecbf4f46b5e4574bd043fa1b04ba1db/src/common/imgs/discount_2@2x.png -------------------------------------------------------------------------------- /src/common/imgs/discount_2@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laizimo/element-react-project/6e09c75f6ecbf4f46b5e4574bd043fa1b04ba1db/src/common/imgs/discount_2@3x.png -------------------------------------------------------------------------------- /src/common/imgs/discount_3@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laizimo/element-react-project/6e09c75f6ecbf4f46b5e4574bd043fa1b04ba1db/src/common/imgs/discount_3@2x.png -------------------------------------------------------------------------------- /src/common/imgs/discount_3@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laizimo/element-react-project/6e09c75f6ecbf4f46b5e4574bd043fa1b04ba1db/src/common/imgs/discount_3@3x.png -------------------------------------------------------------------------------- /src/common/imgs/discount_4@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laizimo/element-react-project/6e09c75f6ecbf4f46b5e4574bd043fa1b04ba1db/src/common/imgs/discount_4@2x.png -------------------------------------------------------------------------------- /src/common/imgs/discount_4@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laizimo/element-react-project/6e09c75f6ecbf4f46b5e4574bd043fa1b04ba1db/src/common/imgs/discount_4@3x.png -------------------------------------------------------------------------------- /src/common/imgs/guarantee_1@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laizimo/element-react-project/6e09c75f6ecbf4f46b5e4574bd043fa1b04ba1db/src/common/imgs/guarantee_1@2x.png -------------------------------------------------------------------------------- /src/common/imgs/guarantee_1@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laizimo/element-react-project/6e09c75f6ecbf4f46b5e4574bd043fa1b04ba1db/src/common/imgs/guarantee_1@3x.png -------------------------------------------------------------------------------- /src/common/imgs/guarantee_2@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laizimo/element-react-project/6e09c75f6ecbf4f46b5e4574bd043fa1b04ba1db/src/common/imgs/guarantee_2@2x.png -------------------------------------------------------------------------------- /src/common/imgs/guarantee_2@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laizimo/element-react-project/6e09c75f6ecbf4f46b5e4574bd043fa1b04ba1db/src/common/imgs/guarantee_2@3x.png -------------------------------------------------------------------------------- /src/common/imgs/guarantee_3@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laizimo/element-react-project/6e09c75f6ecbf4f46b5e4574bd043fa1b04ba1db/src/common/imgs/guarantee_3@2x.png -------------------------------------------------------------------------------- /src/common/imgs/guarantee_3@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laizimo/element-react-project/6e09c75f6ecbf4f46b5e4574bd043fa1b04ba1db/src/common/imgs/guarantee_3@3x.png -------------------------------------------------------------------------------- /src/common/imgs/guarantee_4@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laizimo/element-react-project/6e09c75f6ecbf4f46b5e4574bd043fa1b04ba1db/src/common/imgs/guarantee_4@2x.png -------------------------------------------------------------------------------- /src/common/imgs/guarantee_4@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laizimo/element-react-project/6e09c75f6ecbf4f46b5e4574bd043fa1b04ba1db/src/common/imgs/guarantee_4@3x.png -------------------------------------------------------------------------------- /src/common/imgs/invoice_1@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laizimo/element-react-project/6e09c75f6ecbf4f46b5e4574bd043fa1b04ba1db/src/common/imgs/invoice_1@2x.png -------------------------------------------------------------------------------- /src/common/imgs/invoice_1@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laizimo/element-react-project/6e09c75f6ecbf4f46b5e4574bd043fa1b04ba1db/src/common/imgs/invoice_1@3x.png -------------------------------------------------------------------------------- /src/common/imgs/invoice_2@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laizimo/element-react-project/6e09c75f6ecbf4f46b5e4574bd043fa1b04ba1db/src/common/imgs/invoice_2@2x.png -------------------------------------------------------------------------------- /src/common/imgs/invoice_2@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laizimo/element-react-project/6e09c75f6ecbf4f46b5e4574bd043fa1b04ba1db/src/common/imgs/invoice_2@3x.png -------------------------------------------------------------------------------- /src/common/imgs/invoice_3@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laizimo/element-react-project/6e09c75f6ecbf4f46b5e4574bd043fa1b04ba1db/src/common/imgs/invoice_3@2x.png -------------------------------------------------------------------------------- /src/common/imgs/invoice_3@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laizimo/element-react-project/6e09c75f6ecbf4f46b5e4574bd043fa1b04ba1db/src/common/imgs/invoice_3@3x.png -------------------------------------------------------------------------------- /src/common/imgs/invoice_4@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laizimo/element-react-project/6e09c75f6ecbf4f46b5e4574bd043fa1b04ba1db/src/common/imgs/invoice_4@2x.png -------------------------------------------------------------------------------- /src/common/imgs/invoice_4@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laizimo/element-react-project/6e09c75f6ecbf4f46b5e4574bd043fa1b04ba1db/src/common/imgs/invoice_4@3x.png -------------------------------------------------------------------------------- /src/common/imgs/special_1@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laizimo/element-react-project/6e09c75f6ecbf4f46b5e4574bd043fa1b04ba1db/src/common/imgs/special_1@2x.png -------------------------------------------------------------------------------- /src/common/imgs/special_1@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laizimo/element-react-project/6e09c75f6ecbf4f46b5e4574bd043fa1b04ba1db/src/common/imgs/special_1@3x.png -------------------------------------------------------------------------------- /src/common/imgs/special_2@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laizimo/element-react-project/6e09c75f6ecbf4f46b5e4574bd043fa1b04ba1db/src/common/imgs/special_2@2x.png -------------------------------------------------------------------------------- /src/common/imgs/special_2@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laizimo/element-react-project/6e09c75f6ecbf4f46b5e4574bd043fa1b04ba1db/src/common/imgs/special_2@3x.png -------------------------------------------------------------------------------- /src/common/imgs/special_3@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laizimo/element-react-project/6e09c75f6ecbf4f46b5e4574bd043fa1b04ba1db/src/common/imgs/special_3@2x.png -------------------------------------------------------------------------------- /src/common/imgs/special_3@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laizimo/element-react-project/6e09c75f6ecbf4f46b5e4574bd043fa1b04ba1db/src/common/imgs/special_3@3x.png -------------------------------------------------------------------------------- /src/common/imgs/special_4@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laizimo/element-react-project/6e09c75f6ecbf4f46b5e4574bd043fa1b04ba1db/src/common/imgs/special_4@2x.png -------------------------------------------------------------------------------- /src/common/imgs/special_4@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laizimo/element-react-project/6e09c75f6ecbf4f46b5e4574bd043fa1b04ba1db/src/common/imgs/special_4@3x.png -------------------------------------------------------------------------------- /src/common/imgs/star24_half@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laizimo/element-react-project/6e09c75f6ecbf4f46b5e4574bd043fa1b04ba1db/src/common/imgs/star24_half@2x.png -------------------------------------------------------------------------------- /src/common/imgs/star24_half@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laizimo/element-react-project/6e09c75f6ecbf4f46b5e4574bd043fa1b04ba1db/src/common/imgs/star24_half@3x.png -------------------------------------------------------------------------------- /src/common/imgs/star24_off@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laizimo/element-react-project/6e09c75f6ecbf4f46b5e4574bd043fa1b04ba1db/src/common/imgs/star24_off@2x.png -------------------------------------------------------------------------------- /src/common/imgs/star24_off@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laizimo/element-react-project/6e09c75f6ecbf4f46b5e4574bd043fa1b04ba1db/src/common/imgs/star24_off@3x.png -------------------------------------------------------------------------------- /src/common/imgs/star24_on@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laizimo/element-react-project/6e09c75f6ecbf4f46b5e4574bd043fa1b04ba1db/src/common/imgs/star24_on@2x.png -------------------------------------------------------------------------------- /src/common/imgs/star24_on@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laizimo/element-react-project/6e09c75f6ecbf4f46b5e4574bd043fa1b04ba1db/src/common/imgs/star24_on@3x.png -------------------------------------------------------------------------------- /src/common/imgs/star36_half@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laizimo/element-react-project/6e09c75f6ecbf4f46b5e4574bd043fa1b04ba1db/src/common/imgs/star36_half@2x.png -------------------------------------------------------------------------------- /src/common/imgs/star36_half@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laizimo/element-react-project/6e09c75f6ecbf4f46b5e4574bd043fa1b04ba1db/src/common/imgs/star36_half@3x.png -------------------------------------------------------------------------------- /src/common/imgs/star36_off@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laizimo/element-react-project/6e09c75f6ecbf4f46b5e4574bd043fa1b04ba1db/src/common/imgs/star36_off@2x.png -------------------------------------------------------------------------------- /src/common/imgs/star36_off@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laizimo/element-react-project/6e09c75f6ecbf4f46b5e4574bd043fa1b04ba1db/src/common/imgs/star36_off@3x.png -------------------------------------------------------------------------------- /src/common/imgs/star36_on@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laizimo/element-react-project/6e09c75f6ecbf4f46b5e4574bd043fa1b04ba1db/src/common/imgs/star36_on@2x.png -------------------------------------------------------------------------------- /src/common/imgs/star36_on@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laizimo/element-react-project/6e09c75f6ecbf4f46b5e4574bd043fa1b04ba1db/src/common/imgs/star36_on@3x.png -------------------------------------------------------------------------------- /src/common/imgs/star48_half@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laizimo/element-react-project/6e09c75f6ecbf4f46b5e4574bd043fa1b04ba1db/src/common/imgs/star48_half@2x.png -------------------------------------------------------------------------------- /src/common/imgs/star48_half@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laizimo/element-react-project/6e09c75f6ecbf4f46b5e4574bd043fa1b04ba1db/src/common/imgs/star48_half@3x.png -------------------------------------------------------------------------------- /src/common/imgs/star48_off@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laizimo/element-react-project/6e09c75f6ecbf4f46b5e4574bd043fa1b04ba1db/src/common/imgs/star48_off@2x.png -------------------------------------------------------------------------------- /src/common/imgs/star48_off@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laizimo/element-react-project/6e09c75f6ecbf4f46b5e4574bd043fa1b04ba1db/src/common/imgs/star48_off@3x.png -------------------------------------------------------------------------------- /src/common/imgs/star48_on@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laizimo/element-react-project/6e09c75f6ecbf4f46b5e4574bd043fa1b04ba1db/src/common/imgs/star48_on@2x.png -------------------------------------------------------------------------------- /src/common/imgs/star48_on@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laizimo/element-react-project/6e09c75f6ecbf4f46b5e4574bd043fa1b04ba1db/src/common/imgs/star48_on@3x.png -------------------------------------------------------------------------------- /src/common/js/code_res.js: -------------------------------------------------------------------------------- 1 | export const SUCCESS_CODE = 0; -------------------------------------------------------------------------------- /src/common/js/config.js: -------------------------------------------------------------------------------- 1 | export const base_url = 'http://127.0.0.1:3000'; -------------------------------------------------------------------------------- /src/common/less/base.less: -------------------------------------------------------------------------------- 1 | .border-1px { 2 | &:after{ 3 | @media (-webkit-min-device-pixel-ratio: 1.5), (min-device-pixel-ratio: 1.5) { 4 | -webkit-transform: scaleX(0.7); 5 | transform: scaleY(0.7); 6 | } 7 | 8 | @media (-webkit-min-device-pixel-ratio: 2.0), (min-device-pixel-ratio: 2.0) { 9 | -webkit-transform: scaleY(0.5); 10 | transform: scaleY(0.5); 11 | } 12 | } 13 | } 14 | 15 | .clearfix{ 16 | display: inline-block; 17 | &:after{ 18 | display: block; 19 | content: " "; 20 | height: 0; 21 | clear: both; 22 | visibility: hidden; 23 | line-height: 0; 24 | } 25 | } -------------------------------------------------------------------------------- /src/common/less/icon.less: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: 'icomoon'; 3 | src: url('../font/icomoon.eot?r8nslp'); 4 | src: url('../font/icomoon.eot?r8nslp#iefix') format('embedded-opentype'), 5 | url('../font/icomoon.ttf?r8nslp') format('truetype'), 6 | url('../font/icomoon.woff?r8nslp') format('woff'), 7 | url('../font/icomoon.svg?r8nslp#icomoon') format('svg'); 8 | font-weight: normal; 9 | font-style: normal; 10 | } 11 | 12 | [class^="icon-"], [class*=" icon-"] { 13 | /* use !important to prevent issues with browser extensions that change fonts */ 14 | font-family: 'icomoon' !important; 15 | speak: none; 16 | font-style: normal; 17 | font-weight: normal; 18 | font-variant: normal; 19 | text-transform: none; 20 | line-height: 1; 21 | 22 | /* Better Font Rendering =========== */ 23 | -webkit-font-smoothing: antialiased; 24 | -moz-osx-font-smoothing: grayscale; 25 | } 26 | 27 | .icon-add_circle:before { 28 | content: "\e900"; 29 | } 30 | .icon-arrow_lift:before { 31 | content: "\e901"; 32 | } 33 | .icon-check_circle:before { 34 | content: "\e902"; 35 | } 36 | .icon-close:before { 37 | content: "\e903"; 38 | } 39 | .icon-favorite:before { 40 | content: "\e904"; 41 | } 42 | .icon-keyboard_arrow_right:before { 43 | content: "\e905"; 44 | } 45 | .icon-remove_circle_outline:before { 46 | content: "\e906"; 47 | } 48 | .icon-shopping_cart:before { 49 | content: "\e907"; 50 | } 51 | .icon-thumb_down:before { 52 | content: "\e908"; 53 | } 54 | .icon-thumb_up:before { 55 | content: "\e909"; 56 | } 57 | -------------------------------------------------------------------------------- /src/common/less/index.less: -------------------------------------------------------------------------------- 1 | @import './base.less'; 2 | @import './icon.less'; 3 | @import './mixin.less'; -------------------------------------------------------------------------------- /src/common/less/mixin.less: -------------------------------------------------------------------------------- 1 | #border-1px(@color) { 2 | position: relative; 3 | 4 | &:after{ 5 | content: ' '; 6 | width: 100%; 7 | border-top: 1px solid @color; 8 | position: absolute; 9 | display: block; 10 | left: 0; 11 | bottom: 0; 12 | } 13 | } 14 | 15 | 16 | #bg-image(@img) { 17 | background-image: url('../imgs/@{img}@2x.png'); 18 | 19 | @media (-webkit-min-device-pixel-radio: 3), (min-device-pixel-radio: 3) { 20 | background-image: url('../imgs/@{img}@3x.png'); 21 | } 22 | } -------------------------------------------------------------------------------- /src/components/base/cartcontrol/cartcontrol.jsx: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import ReactCSSTransitionGroup from 'react-addons-css-transition-group'; 3 | import './cartcontrol.less'; 4 | 5 | 6 | export const CartControl = props => { 7 | return ( 8 |
9 | 10 | { 11 | props.number !== 0 &&
12 | 13 | {props.number} 14 |
15 | } 16 |
17 | 18 |
19 | ); 20 | } -------------------------------------------------------------------------------- /src/components/base/cartcontrol/cartcontrol.less: -------------------------------------------------------------------------------- 1 | .cart-control{ 2 | display: block; 3 | 4 | .sub-enter{ 5 | opacity: 0; 6 | transform: translateX(100%); 7 | 8 | &.sub-enter-active{ 9 | opacity: 1; 10 | transform: translateX(0); 11 | transition: all .3s ease-in; 12 | } 13 | } 14 | 15 | .sub-leave{ 16 | opacity: 1; 17 | transform: translateX(0); 18 | 19 | &.sub-leave-active{ 20 | opacity: 0; 21 | transform: translateX(100%); 22 | transition: all .3s ease-out; 23 | } 24 | } 25 | 26 | .sub-number{ 27 | display: inline-block; 28 | vertical-align: top; 29 | 30 | .sub{ 31 | font-size: 24px; 32 | color: rgb(0, 160, 220); 33 | line-height: 24px; 34 | } 35 | 36 | .number{ 37 | display: inline-block; 38 | vertical-align: top; 39 | margin-left: .24rem; 40 | margin-right: .24rem; 41 | font-size: 10px; 42 | line-height: 24px; 43 | color: rgb(147, 153, 159); 44 | } 45 | } 46 | 47 | .add{ 48 | font-size: 24px; 49 | color: rgb(0, 160, 220); 50 | line-height: 24px; 51 | } 52 | } -------------------------------------------------------------------------------- /src/components/base/discount/discount.jsx: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import classNames from 'classnames'; 3 | import './discount.less'; 4 | 5 | const classMap = ['decrease', 'discount', 'special', 'invoice', 'guarantee']; 6 | 7 | export const Discount = props => ( 8 |
9 | 10 | {props.description} 11 |
12 | ); 13 | -------------------------------------------------------------------------------- /src/components/base/discount/discount.less: -------------------------------------------------------------------------------- 1 | @import '../../../common/less/mixin.less'; 2 | 3 | .type{ 4 | display: inline-block; 5 | vertical-align: top; 6 | background-size: 100% 100%; 7 | background-repeat: no-repeat; 8 | 9 | &.decrease{ 10 | #bg-image('decrease_1'); 11 | } 12 | 13 | &.discount{ 14 | #bg-image('discount_1'); 15 | } 16 | 17 | &.guarantee{ 18 | #bg-image('guarantee_1'); 19 | } 20 | 21 | &.invoice{ 22 | #bg-image('invoice_1'); 23 | } 24 | 25 | &.special{ 26 | #bg-image('special_1'); 27 | } 28 | } 29 | 30 | .description{ 31 | color: rgb(255, 255, 255); 32 | } -------------------------------------------------------------------------------- /src/components/cart/cart.jsx: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import classNames from 'classnames'; 3 | import ReactCSSTransitionGroup from 'react-addons-css-transition-group'; 4 | import { CartControl } from '../base/cartcontrol/cartcontrol.jsx'; 5 | import BScroll from 'better-scroll'; 6 | import './cart.less'; 7 | 8 | 9 | export class Cart extends Component { 10 | constructor(props) { 11 | super(props); 12 | 13 | this.handleShowClick = this.handleShowClick.bind(this); 14 | 15 | this.state = { 16 | isShow: false 17 | }; 18 | } 19 | 20 | handleShowClick() { 21 | const isShow = this.state.isShow; 22 | if(isShow) { 23 | this.setState({ 24 | isShow: false 25 | }); 26 | }else { 27 | this.setState({ 28 | isShow: true 29 | }); 30 | } 31 | } 32 | 33 | componentWillReceiveProps(nextProps){ 34 | const cart = nextProps.cart; 35 | const isShow = this.state.isShow; 36 | if(cart.length === 0){ 37 | if(isShow){ 38 | this.setState({ 39 | isShow: false 40 | }); 41 | } 42 | } 43 | } 44 | 45 | componentDidUpdate() { 46 | const cart = this.props.cart; 47 | const isShow = this.state.isShow; 48 | if(cart.length !== 0){ 49 | if(isShow){ 50 | if(!this.cartScroll){ 51 | this.__initScroll(); 52 | }else{ 53 | this.cartScroll.refresh(); 54 | } 55 | } 56 | } 57 | } 58 | 59 | __initScroll() { 60 | const cartFood = this.refs.cartWrapper; 61 | this.cartScroll = new BScroll(cartFood, { 62 | click: true, 63 | }); 64 | } 65 | 66 | getNumber(name) { 67 | const cart = this.props.cart; 68 | let exist = false; 69 | if(cart){ 70 | for(const value of cart) { 71 | if(value.name === name) { 72 | return value.count; 73 | } 74 | } 75 | if(!exist) { 76 | return 0; 77 | } 78 | }else{ 79 | return 0; 80 | } 81 | } 82 | 83 | 84 | render() { 85 | const { cart, deliveryPrice, minPrice, handleClear, handleAddClick, handleSubClick } = this.props; 86 | const { isShow } = this.state; 87 | let sum = 0, price = 0, satisfy; 88 | if(cart) { 89 | for(const food of cart) { 90 | sum += food.count; 91 | price += food.price * food.count; 92 | } 93 | } 94 | 95 | if(price === 0) { 96 | satisfy = `¥${minPrice}起送`; 97 | }else if(price >= 0 && price < minPrice) { 98 | satisfy = `还差¥${minPrice - price}起送`; 99 | }else{ 100 | satisfy = '去结算'; 101 | } 102 | 103 | 104 | const cartFood = cart.map((item, index) => 105 | (
  • 106 | {item.name} 107 | 108 | ¥{item.price * item.count} 109 | 110 | 111 |
  • ) 112 | ); 113 | 114 | return ( 115 |
    116 |
    117 |
    118 |
    119 |
    0 ? 'active' : '')} onClick={price > 0 ? this.handleShowClick : ''}> 120 | 121 |
    122 | { 123 | price > 0 && {sum} 124 | } 125 |
    126 |
    127 | ¥{price} 128 | 129 | 另需配送费¥{this.props.deliveryPrice}元 130 |
    131 |
    132 |
    = minPrice ? 'satisfy' : '')}> 133 | {satisfy} 134 |
    135 |
    136 | 137 | { 138 | isShow && 139 |
    140 |
    141 | 购物车 142 | 清空 143 |
    144 |
    145 |
      146 | { 147 | cartFood 148 | } 149 |
    150 |
    151 |
    152 | } 153 |
    154 | { 155 | isShow &&
    156 | } 157 |
    158 | 159 | ); 160 | } 161 | } -------------------------------------------------------------------------------- /src/components/cart/cart.less: -------------------------------------------------------------------------------- 1 | @import '../../common/less/mixin.less'; 2 | 3 | .shopping-cart{ 4 | position: fixed; 5 | width: 100%; 6 | height: .96rem; 7 | left: 0; 8 | bottom: 0; 9 | z-index: 50; 10 | display: flex; 11 | background: #141d27; 12 | 13 | 14 | .cart{ 15 | flex: 1; 16 | padding: .24rem; 17 | 18 | .cart-control{ 19 | position: absolute; 20 | bottom: 0; 21 | width: 1.16rem; 22 | height: 1.16rem; 23 | border-radius: 50%; 24 | margin-left: .2rem; 25 | margin-right: .2rem; 26 | background: #141d27; 27 | padding: .16rem; 28 | box-sizing: border-box; 29 | 30 | .cart-container{ 31 | width: .88rem; 32 | height: .88rem; 33 | border-radius: 50%; 34 | background: rgba(255, 255, 255, 0.2); 35 | text-align: center; 36 | 37 | .icon-shopping_cart{ 38 | font-size: 24px; 39 | color: rgba(255, 255, 255, 0.4); 40 | line-height: .88rem; 41 | } 42 | } 43 | 44 | .active { 45 | background: rgb(0, 160, 220); 46 | 47 | .icon-shopping_cart{ 48 | color: rgb(255, 255, 255); 49 | } 50 | } 51 | 52 | .food-count{ 53 | position: absolute; 54 | z-index: 51; 55 | width: .48rem; 56 | height: .32rem; 57 | background-color: rgb(240, 20, 20); 58 | color: rgb(255, 255, 255); 59 | text-align: center; 60 | line-height: .32rem; 61 | font-size: 9px; 62 | box-shadow: 0px 2px 4px 0px rgba(0, 0, 0, 0.4); 63 | border-radius: 40%; 64 | top: .05rem; 65 | right: 0; 66 | } 67 | } 68 | 69 | .cart-content{ 70 | margin-left: 1.36rem; 71 | .cart-price{ 72 | font-size: 16px; 73 | color: rgba(255, 255, 255, 0.4); 74 | font-weight: 700; 75 | line-height: .48rem; 76 | } 77 | 78 | .line{ 79 | border-left: 1px solid rgba(255, 255, 255, 0.4); 80 | height: .48rem; 81 | margin: 0 .24rem 0; 82 | } 83 | 84 | .deliverPrice{ 85 | font-size: 12px; 86 | color: rgba(255, 255, 255, 0.4); 87 | line-height: .48rem; 88 | } 89 | } 90 | } 91 | 92 | .cart-settle{ 93 | flex: 0 0 2.1rem; 94 | background-color: rgba(255, 255, 255, 0.2); 95 | padding-left: .16rem; 96 | padding-right: .16rem; 97 | text-align: center; 98 | 99 | .min-price{ 100 | color: rgba(255, 255, 255, 0.4); 101 | font-size: 16px; 102 | font-weight: 700; 103 | line-height: .96rem; 104 | } 105 | 106 | &.satisfy{ 107 | background-color: #00b43c; 108 | 109 | .min-price{ 110 | color: rgb(255, 255, 255); 111 | } 112 | } 113 | } 114 | } 115 | 116 | .fold-enter{ 117 | transform: translateY(100%); 118 | 119 | &.fold-enter-active{ 120 | transform: translateY(0); 121 | transition: all .5s ease-in; 122 | } 123 | } 124 | 125 | .fold-leave{ 126 | transform: translateY(0); 127 | 128 | &.fold-leave-active{ 129 | transform: translateY(100%); 130 | transition: all .5s ease-out; 131 | } 132 | } 133 | 134 | .shoppingcart-container{ 135 | left: 0; 136 | width: 100%; 137 | position: absolute; 138 | bottom: 0.88rem; 139 | z-index: 49; 140 | background: rgb(255, 255, 255); 141 | 142 | 143 | 144 | .shoppingcart-head{ 145 | height: .8rem; 146 | padding-left: .36rem; 147 | padding-right: .36rem; 148 | background: #f3f5f7; 149 | border-bottom: 1px solid rgba(7, 17, 27, 0.1); 150 | 151 | .shoppingcart-name{ 152 | font-size: 14px; 153 | font-weight: 200; 154 | color: rgb(7, 17, 27); 155 | line-height: .8rem; 156 | } 157 | 158 | .shoppingcart-clear{ 159 | font-size: 12px; 160 | float: right; 161 | line-height: .8rem; 162 | color: rgb(0, 160, 220); 163 | } 164 | } 165 | 166 | .cart-wrapper{ 167 | overflow: hidden; 168 | max-height: 3.84rem; 169 | 170 | .food-list{ 171 | width: 100%; 172 | 173 | .food-item{ 174 | height: .96rem; 175 | padding: .24rem .36rem; 176 | display: flex; 177 | background: rgb(255, 255, 255); 178 | box-sizing: border-box; 179 | 180 | .food-name{ 181 | flex: 1; 182 | font-size: 14px; 183 | color: rgb(7, 17, 27); 184 | line-height: .48rem; 185 | } 186 | 187 | .food-option{ 188 | 189 | .food-price{ 190 | font-size: 14px; 191 | font-weight: 700; 192 | color: rgb(240, 20, 20); 193 | line-height: .48rem; 194 | display: inline-block; 195 | vertical-align: top; 196 | } 197 | 198 | .cart-control{ 199 | margin-left: .36rem; 200 | display: inline-block; 201 | } 202 | } 203 | } 204 | } 205 | } 206 | } 207 | 208 | .shoppingcart-mask{ 209 | position: fixed; 210 | top: 0; 211 | left: 0; 212 | width: 100%; 213 | height: 100%; 214 | z-index: 48; 215 | background-color: rgba(7,17,27,0.6); 216 | } 217 | 218 | -------------------------------------------------------------------------------- /src/components/commentselect/commentselect.jsx: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import classNames from 'classnames'; 3 | import './commentselect.less'; 4 | 5 | 6 | export const CommentSelect = ({count, isContent, handleClickAll, handleClickRecommand, handleClickComplaint, checkContent, filter}) => ( 7 |
    8 |
    9 |
    10 | 11 | 12 | 13 |
    14 |
    15 | 16 | 只看有内容的评价 17 |
    18 |
    19 |
    20 | ); 21 | -------------------------------------------------------------------------------- /src/components/commentselect/commentselect.less: -------------------------------------------------------------------------------- 1 | 2 | .comment{ 3 | width: 100%; 4 | position: relative; 5 | 6 | header{ 7 | padding: .24rem .36rem; 8 | width: 100%; 9 | box-sizing: border-box; 10 | position: relative; 11 | border-bottom: 1px solid rgba(7, 17, 27, 0.1); 12 | 13 | .tab-group{ 14 | width: 100%; 15 | overflow: hidden; 16 | border-bottom: 1px solid rgba(7, 17, 27, 0.1); 17 | padding-bottom: .36rem; 18 | 19 | &:after{ 20 | content: ""; 21 | display: block; 22 | clear: both; 23 | } 24 | 25 | .btn{ 26 | padding: .16rem .24rem; 27 | color: rgb(77, 85, 93); 28 | line-height: .32rem; 29 | font-size: 12px; 30 | border-radius: .02rem; 31 | position: relative; 32 | float: left; 33 | outline: none; 34 | border: none; 35 | 36 | .count{ 37 | font-size: 8px; 38 | } 39 | } 40 | 41 | .filter-all{ 42 | background-color: rgb(0, 160, 220); 43 | } 44 | 45 | .filter-recommand{ 46 | background-color: rgba(0, 160, 220, 0.2); 47 | margin-left: .16rem; 48 | } 49 | 50 | .filter-complaint{ 51 | background-color: rgba(77, 85, 93, 0.1); 52 | margin-left: .16rem; 53 | } 54 | 55 | .active{ 56 | color: #fff; 57 | } 58 | } 59 | 60 | .check-content{ 61 | padding: .24rem 0; 62 | font-size: 12px; 63 | color: rgb(147, 153, 159); 64 | line-height: .48rem; 65 | 66 | .text{ 67 | margin-left: .08rem; 68 | } 69 | 70 | &.on{ 71 | .icon-check_circle{ 72 | color: rgb(0, 160, 220); 73 | } 74 | } 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /src/components/goodcontent/goodcontent.jsx: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import { CommentSelect } from '../commentselect/commentselect.jsx'; 3 | import { CartControl } from '../base/cartcontrol/cartcontrol.jsx'; 4 | import classNames from 'classnames'; 5 | import ReactCSSTransitionGroup from 'react-addons-css-transition-group'; 6 | import './goodcontent.less'; 7 | 8 | 9 | export class GoodContent extends Component { 10 | constructor(props){ 11 | super(props); 12 | 13 | this.handleClickAll = this.handleClickAll.bind(this); 14 | this.handleClickComplaint = this.handleClickComplaint.bind(this); 15 | this.handleClickRecommand = this.handleClickRecommand.bind(this); 16 | this.checkContent = this.checkContent.bind(this); 17 | 18 | this.state = { 19 | filter: 2, 20 | isContent: false 21 | }; 22 | } 23 | 24 | 25 | handleClickAll(){ 26 | this.setState({ 27 | filter : 2 28 | }); 29 | } 30 | 31 | handleClickRecommand(){ 32 | this.setState({ 33 | filter: 0 34 | }); 35 | } 36 | 37 | handleClickComplaint(){ 38 | this.setState({ 39 | filter: 1, 40 | isContent: false 41 | }); 42 | } 43 | 44 | filterRate(filter, ratings){ 45 | switch(filter){ 46 | case 0: 47 | return ratings.filter(item => item.rateType === 0); 48 | case 1: 49 | return ratings.filter(item => item.rateType === 1); 50 | case 2: 51 | return ratings; 52 | default: 53 | return ratings; 54 | } 55 | } 56 | getRateCount(ratings){ 57 | let count = { 58 | sum: 0, 59 | recommand: 0, 60 | complaint: 0 61 | }; 62 | count.recommand = ratings.filter(item => item.rateType === 0).length; 63 | count.complaint = ratings.filter(item => item.rateType === 1).length; 64 | count.sum = count.recommand + count.complaint; 65 | return count; 66 | } 67 | 68 | getRateContent(isContent, ratings){ 69 | if(isContent){ 70 | return ratings.filter(i => i.text === ''); 71 | }else{ 72 | return ratings; 73 | } 74 | } 75 | 76 | checkContent(){ 77 | this.setState((prevState) => { 78 | isContent: !prevState.isContent 79 | }); 80 | } 81 | 82 | getNumber(name) { 83 | const cart = this.props.cart; 84 | let exist = false; 85 | if(cart){ 86 | for(const value of cart) { 87 | if(value.name === name) { 88 | return value.count; 89 | } 90 | } 91 | if(!exist) { 92 | return 0; 93 | } 94 | }else{ 95 | return 0; 96 | } 97 | } 98 | 99 | render() { 100 | if(this.props.food){ 101 | var { image, name, sellCount, rating, price, oldPrice, info, ratings } = this.props.food; 102 | } 103 | const showDetail = this.props.show; 104 | const closeDetail = this.props.closeDetail; 105 | const { cart , handleAddClick, handleSubClick, handleAdd } = this.props; 106 | const { filter, isContent } = this.state; 107 | 108 | 109 | const ratingsCount = ratings && this.getRateCount(ratings); 110 | const filterRate = ratings && this.filterRate(filter, ratings); 111 | const rateContent = ratings && this.getRateContent(isContent, filterRate); 112 | 113 | const number = this.getNumber(name); 114 | 115 | const rateList = ratings && rateContent.map((item, index) => ( 116 |
  • 117 |
    118 |
    {new Date().setTime(item.rateTime)}
    119 |
    120 | 121 | {item.text} 122 |
    123 |
    124 |
    125 | {item.username} 126 | user avater 127 |
    128 |
  • 129 | )); 130 | 131 | return ( 132 | 133 | { 134 | showDetail &&
    135 |
    136 | 137 | 138 | 139 | food image 140 |
    141 |
    {name}
    142 |
    143 | 月售{sellCount}份 144 | 好评率{rating} 145 |
    146 |
    147 | {price} 148 | {oldPrice} 149 |
    150 | 152 | 153 | { 154 | number === 0 && 155 | 158 | } 159 | 160 |
    161 |
    162 |
    163 |
    商品介绍
    164 |
    {info}
    165 |
    166 |
    167 |
    商品评价
    168 | 170 |
    171 | 176 |
    177 |
    178 |
    179 | } 180 |
    181 | ) 182 | } 183 | } -------------------------------------------------------------------------------- /src/components/goodcontent/goodcontent.less: -------------------------------------------------------------------------------- 1 | .content-enter{ 2 | transform: translateX(100%); 3 | 4 | &.content-enter-active{ 5 | transform: translateX(0); 6 | transition: all .3s ease-in; 7 | } 8 | } 9 | 10 | .content-leave{ 11 | transform: translateX(0); 12 | 13 | &.content-leave-active{ 14 | transform: translateX(100%); 15 | 16 | transition: all .3s ease-out; 17 | } 18 | } 19 | 20 | .food-detail{ 21 | width: 100%; 22 | height: auto; 23 | background: #f3f5f7; 24 | position: absolute; 25 | left: 0; 26 | top: 0; 27 | z-index: 10; 28 | 29 | header{ 30 | width: 100%; 31 | position: relative; 32 | background: #fff; 33 | height: auto; 34 | border-bottom: rgba(7, 17, 27, .1); 35 | 36 | .close{ 37 | position: absolute; 38 | font-size: 20px; 39 | left: .3rem; 40 | top: .3rem; 41 | } 42 | 43 | .food-image{ 44 | width: 100%; 45 | height: 7.5rem; 46 | } 47 | 48 | .food-content{ 49 | width: 100%; 50 | padding: .36rem; 51 | box-sizing: border-box; 52 | position: relative; 53 | 54 | .food-title{ 55 | font-size: 14px; 56 | font-weight: 700; 57 | color: rgb(7, 17, 27); 58 | line-height: .28rem; 59 | } 60 | 61 | .food-record{ 62 | margin-top: .16rem; 63 | font-size: 10px; 64 | color: rgb(147, 153, 159); 65 | 66 | span:last-child{ 67 | margin-left: .24rem; 68 | } 69 | } 70 | 71 | .food-sell{ 72 | margin-top: .36rem; 73 | line-height: .48rem; 74 | 75 | .food-price{ 76 | font-size: 14px; 77 | color: rgb(240, 20, 20); 78 | font-weight: 700; 79 | } 80 | 81 | .food-oldprice{ 82 | font-size: 10px; 83 | color: rgb(147, 153, 159); 84 | font-weight: 700; 85 | text-decoration: line-through; 86 | margin-left: .16rem; 87 | } 88 | } 89 | 90 | .add-cart{ 91 | position: absolute; 92 | width: 1.48rem; 93 | height: .48rem; 94 | border-radius: .24rem; 95 | background: rgb(0, 160, 220); 96 | font-size: 10px; 97 | line-height: .24rem; 98 | color: #fff; 99 | right: .36rem; 100 | bottom: .36rem; 101 | border: none; 102 | outline: none; 103 | overflow: hidden; 104 | } 105 | 106 | .cart-control{ 107 | position: absolute; 108 | bottom: .36rem; 109 | right: .36rem; 110 | } 111 | 112 | .cartbtn-enter{ 113 | width: .48rem; 114 | color: rgb(0, 160, 220); 115 | 116 | &.cartbtn-enter-active{ 117 | width: 1.48rem; 118 | color: rgb(0, 160, 220); 119 | transition: all .3s ease-in; 120 | } 121 | } 122 | 123 | .cartbtn-leave{ 124 | width: 1.48rem; 125 | color: rgb(0, 160, 220); 126 | 127 | &.cartbtn-leave-active{ 128 | width: .48rem; 129 | color: rgb(0, 160, 220); 130 | transition: all .3s ease-out; 131 | } 132 | } 133 | } 134 | } 135 | 136 | .content{ 137 | width: 100%; 138 | margin-top: .32rem; 139 | padding: .36rem; 140 | box-sizing: border-box; 141 | position: relative; 142 | background: #fff; 143 | border:1px solid rgba(7, 17, 27, .1); 144 | 145 | .title{ 146 | font-size: 14px; 147 | font-weight: 200; 148 | color: rgb(7, 17, 27); 149 | line-height: .56rem; 150 | } 151 | 152 | .food-info{ 153 | padding: .12rem .16rem 0; 154 | font-size: 12px; 155 | font-weight: 200; 156 | color: rgb(77, 85, 93); 157 | line-height: .48rem; 158 | } 159 | } 160 | 161 | .rate-list{ 162 | width: 100%; 163 | height: auto; 164 | padding: 0 .36rem; 165 | box-sizing: border-box; 166 | position: relative; 167 | list-style: none; 168 | background: #fff; 169 | 170 | .rate-item{ 171 | display: flex; 172 | width: 100%; 173 | padding: .32rem 0; 174 | border-bottom: 1px solid rgba(7, 17, 27, .1); 175 | 176 | .rate-content{ 177 | flex: 1; 178 | 179 | .rate-time{ 180 | font-size: 10px; 181 | color: rgb(147, 153, 159); 182 | line-height: .24rem; 183 | } 184 | 185 | .rate-text{ 186 | margin-top: .12rem; 187 | font-size: 12px; 188 | color: rgb(7, 17, 27); 189 | line-height: .48rem; 190 | 191 | .icon-thumb_up{ 192 | color: rgb(0, 160, 220); 193 | } 194 | 195 | .icon-thumb_down{ 196 | color: rgb(147, 153, 159); 197 | } 198 | 199 | .text{ 200 | margin-left: .08rem; 201 | } 202 | } 203 | } 204 | 205 | .rate-user{ 206 | flex: 0 0 1rem; 207 | 208 | .user-name{ 209 | font-size: 10px; 210 | color: rgb(147, 153, 159); 211 | line-height: .24rem; 212 | } 213 | 214 | .user-avatar{ 215 | width: .24rem; 216 | height: .24rem; 217 | border-radius: 50%; 218 | margin-left: .12rem; 219 | } 220 | } 221 | } 222 | } 223 | 224 | .block{ 225 | width: 100%; 226 | height: 1.16rem; 227 | background: #fff; 228 | } 229 | } 230 | 231 | -------------------------------------------------------------------------------- /src/components/goods/goods.jsx: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import axios from 'axios'; 3 | import { base_url } from '../../common/js/config.js'; 4 | import { SUCCESS_CODE } from '../../common/js/code_res.js'; 5 | import classNames from 'classnames'; 6 | import BScroll from 'better-scroll'; 7 | import { Cart } from '../cart/cart.jsx'; 8 | import AlloyTouch from 'alloytouch'; 9 | import { CartControl } from '../base/cartcontrol/cartcontrol.jsx'; 10 | import { GoodContent } from '../goodcontent/goodcontent.jsx'; 11 | import './goods.less'; 12 | 13 | class GoodItem extends Component{ 14 | constructor(props){ 15 | super(props); 16 | 17 | this.state = { 18 | number: 0 19 | }; 20 | } 21 | 22 | getNumber(name) { 23 | const cart = this.props.cart; 24 | let exist = false; 25 | if(cart){ 26 | for(const value of cart) { 27 | if(value.name === name) { 28 | return value.count; 29 | } 30 | } 31 | if(!exist) { 32 | return 0; 33 | } 34 | }else{ 35 | return 0; 36 | } 37 | } 38 | 39 | render() { 40 | const { food: { name, image, description, sellCount, rating, price, oldPrice }, handleAddClick, handleSubClick, showContent} = this.props; 41 | // console.log(showContent); 42 | 43 | return ( 44 |
    45 | foodPic 46 |
    47 |
    {name}
    48 |
    {description}
    49 |
    50 | {`月售${sellCount}份`} 51 | {`好评率 ${rating}%`} 52 |
    53 |
    54 | {price && `¥${price}`} 55 | {oldPrice && `¥${oldPrice}`} 56 |
    57 |
    58 | 60 |
    61 | ); 62 | } 63 | } 64 | 65 | const GoodsList = props => ( 66 | 76 | ) 77 | 78 | const GoodsWrapper = props => ( 79 | 87 | ) 88 | 89 | 90 | export class Goods extends Component { 91 | constructor(props){ 92 | super(props); 93 | 94 | this.handleClickIndex = this.handleClickIndex.bind(this); 95 | this.handleSubClick = this.handleSubClick.bind(this); 96 | this.handleAddClick = this.handleAddClick.bind(this); 97 | this.handleCartClear = this.handleCartClear.bind(this); 98 | this.showContent = this.showContent.bind(this); 99 | this.closeDetail = this.closeDetail.bind(this); 100 | this.handleAdd = this.handleAdd.bind(this); 101 | 102 | this.state = { 103 | goods: [], 104 | classMap: ['decrease', 'discount', 'special', 'invoice', 'guarantee'], 105 | currentIndex: 0, 106 | number: {}, 107 | cart: [], 108 | showDetail: false, 109 | foodDetail: null 110 | } 111 | } 112 | 113 | componentDidMount() { 114 | axios.get(`${base_url}/api/goods`) 115 | .then(response => { 116 | const res = response.data; 117 | if(res.code === SUCCESS_CODE) { 118 | this.setState({ 119 | goods: res.data 120 | }); 121 | this._initScroll(); 122 | } 123 | }); 124 | } 125 | 126 | handleClickIndex(e) { 127 | const el = e.currentTarget; 128 | const index = el.getAttribute('data-id'); 129 | const foodList = document.getElementsByClassName('goods-item'); 130 | this.setState({ 131 | currentIndex: index 132 | }); 133 | this.foodScroll.scrollToElement(foodList[index]); 134 | } 135 | 136 | _initScroll() { 137 | this.menuScroll = new BScroll(this.refs.menuWrapper,{ 138 | click: true 139 | }); 140 | 141 | this.foodScroll = new BScroll(this.refs.goods, { 142 | click: true, 143 | probeType: 3 144 | }); 145 | } 146 | 147 | handleSubClick(e) { 148 | let foodName = e.target; 149 | while(true){ 150 | if(foodName.getAttribute('data-name')){ 151 | foodName = foodName.getAttribute('data-name'); 152 | break; 153 | } 154 | foodName = foodName.parentNode; 155 | } 156 | const cart = this.state.cart; 157 | for(const index in cart) { 158 | if(cart[index].name === foodName) { 159 | if(cart[index].count === 1) { 160 | cart.splice(index, 1); 161 | }else{ 162 | cart[index].count--; 163 | } 164 | } 165 | } 166 | this.setState({ 167 | cart: cart 168 | }); 169 | e.stopPropagation(); 170 | } 171 | 172 | handleAddClick(e) { 173 | const foodName = e.target.parentNode.getAttribute('data-name'); 174 | const foodPrice = e.target.parentNode.getAttribute('data-price'); 175 | const cart = this.state.cart; 176 | let exist = false; 177 | if(cart.length === 0) { 178 | cart.push({name: foodName, price: foodPrice, count: 1}); 179 | }else{ 180 | for(const value of cart) { 181 | if(foodName === value.name) { 182 | value.count++; 183 | exist = true; 184 | } 185 | } 186 | if(!exist) { 187 | cart.push({name: foodName, price: foodPrice, count: 1}); 188 | } 189 | } 190 | this.setState({ 191 | cart: cart 192 | }); 193 | e.stopPropagation(); 194 | } 195 | 196 | handleAdd(foodname, price) { 197 | const cart = this.state.cart; 198 | let exist = false; 199 | if(cart.length === 0) { 200 | cart.push({name: foodname, price: price, count: 1}); 201 | }else{ 202 | for(const value of cart) { 203 | if(foodname === value.name) { 204 | value.count++; 205 | exist = true; 206 | } 207 | } 208 | if(!exist) { 209 | cart.push({name: foodname, price: price, count: 1}); 210 | } 211 | } 212 | this.setState({ 213 | cart: cart 214 | }); 215 | } 216 | 217 | handleCartClear() { 218 | const cart = []; 219 | this.setState({ 220 | cart: cart 221 | }); 222 | } 223 | 224 | showContent(food){ 225 | this.setState({ 226 | showDetail: true, 227 | foodDetail: food 228 | }); 229 | } 230 | 231 | closeDetail(){ 232 | this.setState({ 233 | showDetail: false, 234 | foodDetail: null 235 | }); 236 | } 237 | 238 | render() { 239 | const { goods, classMap, currentIndex, showDetail, foodDetail } = this.state; 240 | const seller = this.props.seller; 241 | if(seller){ 242 | var {deliveryPrice, minPrice} = seller; 243 | } 244 | 245 | const menu = goods.length > 0 && 246 | goods.map((item, index) => ( 247 |
  • 249 | 250 | {item.type !== -1 && } 251 | {item.name} 252 |
  • 253 | )); 254 | 255 | return ( 256 |
    257 |
    258 | 263 |
    264 | 265 |
    266 |
    267 | 268 | 270 |
    271 | ); 272 | } 273 | } -------------------------------------------------------------------------------- /src/components/goods/goods.less: -------------------------------------------------------------------------------- 1 | @import '../../common/less/mixin.less'; 2 | 3 | .goods{ 4 | position: absolute; 5 | top: 3.58rem; 6 | bottom: 1.16rem; 7 | display: flex; 8 | overflow: hidden; 9 | width: 100%; 10 | 11 | .menu-wrapper{ 12 | flex: 0 0 1.6rem; 13 | width: 1.6rem; 14 | background-color: #f3f5f7; 15 | 16 | .menu-list{ 17 | 18 | .menu-item{ 19 | height: 1.08rem; 20 | width: 1.12rem; 21 | padding-left: .24rem; 22 | padding-right: .24rem; 23 | border-bottom: 1px solid rgba(7, 17, 27, .1); 24 | display: table; 25 | 26 | &.current{ 27 | background: rgb(255, 255, 255); 28 | } 29 | 30 | .type{ 31 | width: .24rem; 32 | height: .24rem; 33 | display: inline-block; 34 | vertical-align: top; 35 | 36 | &.decrease{ 37 | #bg-image('decrease_1'); 38 | } 39 | 40 | &.discount{ 41 | #bg-image('discount_1'); 42 | } 43 | 44 | &.guarantee{ 45 | #bg-image('guarantee_1'); 46 | } 47 | 48 | &.invoice{ 49 | #bg-image('invoice_1'); 50 | } 51 | 52 | &.special{ 53 | #bg-image('special_1'); 54 | } 55 | } 56 | 57 | .name{ 58 | font-size: 12px; 59 | color: rgb(24, 20, 20); 60 | font-weight: 200; 61 | line-height: 14px; 62 | width: 1.12rem; 63 | display: table-cell; 64 | vertical-align: middle; 65 | } 66 | } 67 | } 68 | } 69 | 70 | .goods-wrapper{ 71 | flex: 1; 72 | 73 | .goods-list{ 74 | width: 100%; 75 | position: relative; 76 | 77 | .goods-item{ 78 | width:100%; 79 | 80 | .goods-title{ 81 | width: 100%; 82 | height: .52rem; 83 | line-height: .52rem; 84 | padding-left: .28rem; 85 | border-left: 1px solid #d9dde1; 86 | background-color: #f3f5f7; 87 | font-size: 12px; 88 | color: rgb(147, 153, 159); 89 | } 90 | 91 | .foods-list{ 92 | width: 100%; 93 | 94 | .foods-item{ 95 | width: 100%; 96 | padding: .36rem; 97 | box-sizing: border-box; 98 | #border-1px(rgba(7,17,27,0.1)); 99 | 100 | .food{ 101 | width: 100%; 102 | display: flex; 103 | position: relative; 104 | 105 | .food-image{ 106 | 107 | width: 1.14rem; 108 | height: 1.14rem; 109 | } 110 | 111 | .food-content{ 112 | flex: 1; 113 | padding-left: .2rem; 114 | padding-top: .04rem; 115 | 116 | .food-name{ 117 | font-size: 14px; 118 | color: rgb(7, 17, 27); 119 | line-height: 14px; 120 | height: 14px; 121 | } 122 | 123 | .food-description{ 124 | margin-top: .16rem; 125 | font-size: 10px; 126 | color: rgb(147, 153, 159); 127 | line-height: 10px; 128 | } 129 | 130 | .food-info{ 131 | margin-top: .16rem; 132 | font-size: 10px; 133 | color: rgb(147, 153, 159); 134 | line-height: 10px; 135 | 136 | .food-rating{ 137 | margin-left: .24rem; 138 | } 139 | } 140 | 141 | .food-price{ 142 | margin-top: .16rem; 143 | 144 | .current{ 145 | font-size: 14px; 146 | color: rgb(240, 20, 20); 147 | } 148 | 149 | .old{ 150 | font-size: 10px; 151 | color: rgb(147, 153, 159); 152 | text-decoration: line-through; 153 | margin-left: .16rem; 154 | } 155 | } 156 | } 157 | 158 | .cart-control{ 159 | position: absolute; 160 | bottom: -0.3rem; 161 | right: 0; 162 | } 163 | } 164 | } 165 | } 166 | } 167 | } 168 | } 169 | } -------------------------------------------------------------------------------- /src/components/header/header.jsx: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import axios from 'axios'; 3 | import classNames from 'classnames'; 4 | import './header.less'; 5 | import ReactCSSTransitionGroup from 'react-addons-css-transition-group'; 6 | import Star from '../star/star.jsx'; 7 | import { Discount } from '../base/discount/discount.jsx'; 8 | 9 | const SUCCESS_CODE = 0; 10 | 11 | const Title = ({ info }) => { 12 | return ( 13 |
    14 | 15 | {info} 16 | 17 |
    18 | ); 19 | } 20 | 21 | const DiscountInfo = ({ supports, classMap }) => { 22 | const support = supports.map((item, index) => ( 23 | 25 | )); 26 | return ( 27 | 30 | ); 31 | } 32 | 33 | export class Header extends React.Component { 34 | constructor(props){ 35 | super(props); 36 | 37 | this.handleShowClick = this.handleShowClick.bind(this); 38 | this.handleHiddenClick = this.handleHiddenClick.bind(this); 39 | 40 | this.state = { 41 | classMap: ['decrease', 'discount', 'special', 'invoice', 'guarantee'], 42 | isDetail: false, 43 | titleInfo: ['优惠信息', '商家公告'] 44 | }; 45 | } 46 | 47 | handleShowClick() { 48 | this.setState({ 49 | isDetail: true 50 | }); 51 | } 52 | 53 | handleHiddenClick() { 54 | this.setState({ 55 | isDetail: false 56 | }); 57 | } 58 | 59 | render() { 60 | const seller = this.props.seller; 61 | if(seller){ 62 | var {avatar, supports = null, bulletin, name, score, description, deliveryTime} = this.props.seller; 63 | } 64 | const classMap = this.state.classMap; 65 | const [ discountInfo, sellerBulletin ] = this.state.titleInfo; 66 | let supportDiv, supportCount; 67 | 68 | if(supports) { 69 | supportDiv = ( 70 | 72 | ); 73 | 74 | supportCount = ( 75 |
    76 | {supports.length}个 77 | 78 |
    79 | ); 80 | }else { 81 | supportDiv = ( 82 |
    83 | ); 84 | 85 | supportCount = ( 86 |
    87 | ); 88 | } 89 | 90 | 91 | return ( 92 |
    93 |
    94 |
    95 | avatar 96 |
    97 |
    98 |
    99 | 100 | {name} 101 |
    102 |
    103 | {description}/{deliveryTime}分钟送达 104 |
    105 | {supportDiv} 106 |
    107 | {supportCount} 108 |
    109 |
    110 | 111 | {bulletin} 112 | 113 |
    114 |
    115 | avatar 116 |
    117 | 118 | { 119 | this.state.isDetail && 120 |
    121 |
    122 |
    123 | {name} 124 | 125 | 126 | <DiscountInfo supports={supports} classMap={classMap}/> 127 | <Title info={sellerBulletin}/> 128 | <span className="bulletin-content">{bulletin}</span> 129 | </div> 130 | </div> 131 | <div className="detail-close" onClick={this.handleHiddenClick}> 132 | <i className="icon-close"></i> 133 | </div> 134 | </div> 135 | } 136 | </ReactCSSTransitionGroup> 137 | </header> 138 | ); 139 | } 140 | } -------------------------------------------------------------------------------- /src/components/header/header.less: -------------------------------------------------------------------------------- 1 | @import '../../common/less/mixin.less'; 2 | 3 | header { 4 | position: relative; 5 | height: 2.78rem; 6 | background-size: 100% 100%; 7 | background-color: rgba(7, 17, 27, .5); 8 | color: #fff; 9 | overflow: hidden; 10 | 11 | .content-wrap { 12 | position: relative; 13 | padding: .48rem .24rem .36rem .48rem; 14 | 15 | .avatar{ 16 | position: relative; 17 | width: 1.28rem; 18 | height: 1.28rem; 19 | display: inline-block; 20 | 21 | img{ 22 | width: 100%; 23 | border-radius: 5px; 24 | } 25 | } 26 | 27 | .content{ 28 | position: relative; 29 | margin-left: .32rem; 30 | display: inline-block; 31 | vertical-align: top; 32 | 33 | .title{ 34 | margin: .04rem 0 .16rem 0; 35 | height: .36rem; 36 | 37 | .brand{ 38 | #bg-image('brand'); 39 | width: .6rem; 40 | height: .36rem; 41 | display: inline-block; 42 | background-size: 100% 100%; 43 | vertical-align: top; 44 | } 45 | 46 | .name { 47 | margin-left: .12rem; 48 | font-size: 16px; 49 | color: rgb(255, 255, 255); 50 | font-weight: bold; 51 | line-height: 18px; 52 | display: inline-block; 53 | vertical-align: top; 54 | } 55 | } 56 | 57 | .description { 58 | display: block; 59 | margin-top: .16rem; 60 | font-size: 12px; 61 | color: rgb(255, 255, 255); 62 | font-weight: 200; 63 | line-height: 12px; 64 | margin-bottom: .2rem; 65 | } 66 | 67 | .support{ 68 | margin-bottom: .04rem; 69 | height: .24rem; 70 | .type{ 71 | display: inline-block; 72 | vertical-align: top; 73 | width: .24rem; 74 | height: .24rem; 75 | } 76 | 77 | .description { 78 | display: inline-block; 79 | font-size: 10px; 80 | vertical-align: top; 81 | margin: 0; 82 | margin-left: .08rem; 83 | } 84 | } 85 | } 86 | 87 | .support-count{ 88 | position: absolute; 89 | height: .48rem; 90 | background-color: rgba(0, 0, 0, 0.2); 91 | right: .24rem; 92 | bottom: .28rem; 93 | padding: 0 .16rem; 94 | line-height: .48rem; 95 | border-radius: .28rem; 96 | text-align: center; 97 | 98 | .number{ 99 | vertical-align: top; 100 | font-size: 10px; 101 | } 102 | 103 | .icon-keyboard_arrow_right{ 104 | margin-left: .04rem; 105 | line-height: .48rem; 106 | font-size: 10px; 107 | } 108 | } 109 | } 110 | 111 | .bulletin-wrapper{ 112 | height: .56rem; 113 | background-color: rgba(7, 17, 27, 0.2); 114 | padding: 0 .44rem 0 .24rem; 115 | line-height: .56rem; 116 | position: relative; 117 | overflow: hidden; 118 | text-overflow: ellipsis; 119 | white-space: nowrap; 120 | 121 | .bulletin{ 122 | display: inline-block; 123 | vertical-align: top; 124 | width: .44rem; 125 | height: .24rem; 126 | #bg-image('bulletin'); 127 | margin-top: .16rem; 128 | background-size: 100% 100%; 129 | } 130 | 131 | .bulletin-content{ 132 | font-size: 10px; 133 | line-height: .56rem; 134 | margin: 0 .08rem; 135 | } 136 | 137 | .icon-keyboard_arrow_right{ 138 | position: absolute; 139 | right: .24rem; 140 | top: .08rem; 141 | line-height: .56rem; 142 | font-size: 10px; 143 | } 144 | } 145 | 146 | .background { 147 | position: absolute; 148 | top: 0; 149 | left: 0; 150 | width: 100%; 151 | height: 100%; 152 | z-index: -1; 153 | filter: blur(10px); 154 | 155 | img { 156 | width: 100%; 157 | height: 100%; 158 | } 159 | } 160 | 161 | .detail{ 162 | position: fixed; 163 | top: 0; 164 | left: 0; 165 | width: 100%; 166 | height: 100%; 167 | overflow: hidden; 168 | background-color: rgba(7, 17, 27, 0.8); 169 | text-align: center; 170 | z-index: 100; 171 | 172 | .detail-wrapper{ 173 | height: 100%; 174 | min-height: 100%; 175 | 176 | .detail-main{ 177 | margin-top: 1.28rem; 178 | padding-bottom: 1.28rem; 179 | .title{ 180 | display: block; 181 | font-size: 16px; 182 | font-weight: 700; 183 | line-height: 16px; 184 | margin: 0 auto; 185 | } 186 | 187 | .stars{ 188 | height: .48rem; 189 | margin-top: .32rem; 190 | } 191 | 192 | .info-content{ 193 | display: block; 194 | margin-top: .56rem; 195 | 196 | .line { 197 | vertical-align: middle; 198 | width: 2.24rem; 199 | font-size: 0; 200 | border-top: 1px solid rgba(255, 255, 255, 0.2); 201 | } 202 | 203 | .info{ 204 | font-size: 14px; 205 | font-weight: 700; 206 | margin-left: .24rem; 207 | margin-right: .24rem; 208 | } 209 | } 210 | 211 | .discount-list{ 212 | display: block; 213 | margin-top: .48rem; 214 | text-align: left; 215 | margin-left: .96rem; 216 | 217 | .support{ 218 | margin-top: .24rem; 219 | display: block; 220 | 221 | .type{ 222 | width: .32rem; 223 | height: .32rem; 224 | display: inline-block; 225 | margin-right: .12rem; 226 | } 227 | 228 | .description{ 229 | font-size: 12px; 230 | font-weight: 200; 231 | line-height: 12px; 232 | } 233 | } 234 | } 235 | 236 | .bulletin-content{ 237 | display: block; 238 | padding: .48rem .96rem 0; 239 | font-size: 12px; 240 | font-weight: 200; 241 | line-height: 24px; 242 | text-align: left; 243 | } 244 | } 245 | } 246 | 247 | .detail-close{ 248 | position: relative; 249 | width: .64rem; 250 | height: .64rem; 251 | font-size: 32px; 252 | margin: -1.28rem auto 0 auto; 253 | bottom: 0; 254 | clear: both; 255 | } 256 | 257 | } 258 | 259 | .detail-enter{ 260 | opacity: 0.1; 261 | 262 | &.detail-enter-active{ 263 | opacity: 1; 264 | transition: opacity 500ms ease-in; 265 | } 266 | } 267 | 268 | .detail-leave{ 269 | opacity: 1; 270 | 271 | &.detail-leave-active{ 272 | opacity: 0.1; 273 | transition: opacity 300ms ease-out; 274 | } 275 | } 276 | } -------------------------------------------------------------------------------- /src/components/navbar/navbar.jsx: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import { NavLink, BrowserRouter as Router} from 'react-router-dom'; 3 | import './navbar.less' 4 | 5 | export class Navbar extends Component { 6 | constructor(props) { 7 | super(props); 8 | 9 | this.state = { 10 | goods: '商品', 11 | comment: '评价', 12 | seller: '商家' 13 | }; 14 | } 15 | 16 | render() { 17 | return ( 18 | <nav className="navbar border-1px"> 19 | <ul> 20 | <li className="nav-options"><NavLink activeClassName="active" to="/goods">{this.state.goods}</NavLink></li> 21 | <li className="nav-options"><NavLink activeClassName="active" to="/comment">{this.state.comment}</NavLink></li> 22 | <li className="nav-options"><NavLink activeClassName="active" to="/seller">{this.state.seller}</NavLink></li> 23 | </ul> 24 | </nav> 25 | ) 26 | } 27 | } -------------------------------------------------------------------------------- /src/components/navbar/navbar.less: -------------------------------------------------------------------------------- 1 | @import '../../common/less/mixin.less'; 2 | 3 | .navbar{ 4 | height: .8rem; 5 | position: relative; 6 | line-height: .8rem; 7 | #border-1px(rgba(7,17,27,0.1)); 8 | 9 | ul{ 10 | display: flex; 11 | justify-content: center; 12 | height: 100%; 13 | 14 | .nav-options{ 15 | flex: 1; 16 | text-align: center; 17 | 18 | a{ 19 | display: block; 20 | font-size: 14px; 21 | color: rgb(77, 85, 93); 22 | 23 | &.active{ 24 | color: rgb(240, 20, 20); 25 | } 26 | } 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /src/components/star/star.jsx: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import classNames from 'classnames'; 3 | import './star.less'; 4 | 5 | const LENGTH = 5; 6 | const TYPE_ON = 'on'; 7 | const TYPE_HALF = 'half'; 8 | const TYPE_OFF = 'off'; 9 | 10 | function starJudge(score) { 11 | const res = []; 12 | const onNumber = Math.floor(score); 13 | for(let i = 0; i < onNumber; i++){ 14 | res.push(TYPE_ON); 15 | } 16 | if(score >= onNumber + 0.5) { 17 | res.push(TYPE_HALF); 18 | for(let i = 0; i < LENGTH - onNumber - 1; i++) { 19 | res.push(TYPE_OFF); 20 | } 21 | }else { 22 | for(let i = 0; i < LENGTH - onNumber; i++) { 23 | res.push(TYPE_OFF); 24 | } 25 | } 26 | return res; 27 | } 28 | 29 | const Star = ({ size, score }) => { 30 | const classMap = starJudge(score); 31 | const starSize = 'star-' + size; 32 | 33 | return ( 34 | <ul className="stars"> 35 | {classMap.map((item, index) => ( 36 | <li key={index} className={classNames(starSize, `${starSize}-${item}`)}></li> 37 | ))} 38 | </ul> 39 | ); 40 | } 41 | 42 | export default Star; -------------------------------------------------------------------------------- /src/components/star/star.less: -------------------------------------------------------------------------------- 1 | @import '../../common/less/mixin.less'; 2 | 3 | ul { 4 | display: block; 5 | position: relative; 6 | 7 | &.comment-48{ 8 | height: .48rem; 9 | } 10 | 11 | li{ 12 | display: inline-block; 13 | background-size: 100% 100%; 14 | vertical-align: top; 15 | 16 | &.star-24{ 17 | width: .2rem; 18 | height: .2rem; 19 | margin-right: .6rem; 20 | } 21 | 22 | &.star-24-on{ 23 | #bg-image('star24_on'); 24 | } 25 | 26 | &.star-24-half{ 27 | #bg-image('star24_half'); 28 | } 29 | 30 | &.star-24-off{ 31 | #bg-image('star24_off'); 32 | } 33 | 34 | &.star-36{ 35 | width: .3rem; 36 | height: .3rem; 37 | margin-right: .12rem; 38 | } 39 | 40 | &.star-36-on{ 41 | #bg-image('star36_on'); 42 | } 43 | 44 | &.star-36-half{ 45 | #bg-image('star36_half'); 46 | } 47 | 48 | &.star-36-off{ 49 | #bg-image('star36_off'); 50 | } 51 | 52 | &.star-48{ 53 | width: .4rem; 54 | height: .4rem; 55 | margin-right: .44rem; 56 | } 57 | 58 | &.star-48-on{ 59 | #bg-image('star48_on'); 60 | } 61 | 62 | &.star-48-half{ 63 | #bg-image('star48_half'); 64 | } 65 | 66 | &.star-48-off{ 67 | #bg-image('star48_off'); 68 | } 69 | } 70 | } -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import { App } from './App.jsx'; 4 | import './common/less/index.less'; 5 | 6 | 7 | ReactDOM.render(<App />, document.getElementById('root')); -------------------------------------------------------------------------------- /static/css/reset.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Eric Meyer's Reset CSS v2.0 (http://meyerweb.com/eric/tools/css/reset/) 3 | * http://cssreset.com 4 | */ 5 | html, body, div, span, applet, object, iframe, 6 | h1, h2, h3, h4, h5, h6, p, blockquote, pre, 7 | a, abbr, acronym, address, big, cite, code, 8 | del, dfn, em, img, ins, kbd, q, s, samp, 9 | small, strike, strong, sub, sup, tt, var, 10 | b, u, i, center, 11 | dl, dt, dd, ol, ul, li, 12 | fieldset, form, label, legend, 13 | table, caption, tbody, tfoot, thead, tr, th, td, 14 | article, aside, canvas, details, embed, 15 | figure, figcaption, footer, header, 16 | menu, nav, output, ruby, section, summary, 17 | time, mark, audio, video, input { 18 | margin: 0; 19 | padding: 0; 20 | border: 0; 21 | font-weight: normal; 22 | vertical-align: baseline; 23 | } 24 | 25 | /* HTML5 display-role reset for older browsers */ 26 | article, aside, details, figcaption, figure, 27 | footer, header, menu, nav, section { 28 | display: block; 29 | } 30 | 31 | body { 32 | font-size: 0.14rem; 33 | line-height: 1; 34 | } 35 | 36 | blockquote, q { 37 | quotes: none; 38 | } 39 | 40 | blockquote:before, blockquote:after, 41 | q:before, q:after { 42 | content: none; 43 | } 44 | 45 | table { 46 | border-collapse: collapse; 47 | border-spacing: 0; 48 | } 49 | 50 | /* custom */ 51 | a { 52 | color: #7e8c8d; 53 | text-decoration: none; 54 | -webkit-backface-visibility: hidden; 55 | } 56 | 57 | li { 58 | list-style: none; 59 | } 60 | 61 | ::-webkit-scrollbar { 62 | width: 5px; 63 | height: 5px; 64 | } 65 | 66 | ::-webkit-scrollbar-track-piece { 67 | background-color: rgba(0, 0, 0, 0.2); 68 | -webkit-border-radius: 6px; 69 | } 70 | 71 | ::-webkit-scrollbar-thumb:vertical { 72 | height: 5px; 73 | background-color: rgba(125, 125, 125, 0.7); 74 | -webkit-border-radius: 6px; 75 | } 76 | 77 | ::-webkit-scrollbar-thumb:horizontal { 78 | width: 5px; 79 | background-color: rgba(125, 125, 125, 0.7); 80 | -webkit-border-radius: 6px; 81 | } 82 | 83 | html, body { 84 | width: 100%; 85 | } 86 | 87 | body { 88 | -webkit-text-size-adjust: none; 89 | -webkit-tap-highlight-color: rgba(0, 0, 0, 0); 90 | } 91 | -------------------------------------------------------------------------------- /static/js/rem.js: -------------------------------------------------------------------------------- 1 | (function(win, doc){ 2 | const docEl = document.documentElement, 3 | resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize', 4 | recalc = function() { 5 | var clientWidth = docEl.clientWidth; 6 | if(!clientWidth) return; 7 | docEl.style.fontSize = clientWidth / 7.5 + 'px'; 8 | }; 9 | 10 | if(!doc.addEventListener) return; 11 | 12 | doc.addEventListener(resizeEvt, recalc, false); 13 | doc.addEventListener('DOMContentLoaded', recalc, false); 14 | })(window, document); -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const ExtractTextPlugin = require('extract-text-webpack-plugin'); 3 | const HTMLWebpackPlugin = require('html-webpack-plugin'); 4 | const extractText = new ExtractTextPlugin({ 5 | filename: 'bundle.css' 6 | }); 7 | 8 | const htmlPlugin = new HTMLWebpackPlugin({ 9 | template: './index.html', 10 | filename: 'index.html', 11 | inject: 'body' 12 | }); 13 | 14 | module.exports = { 15 | entry: './src/index.js', 16 | 17 | output: { 18 | filename: 'bundle.js', 19 | path: path.resolve(__dirname, 'dist'), 20 | publicPath: '/dist' 21 | }, 22 | 23 | module: { 24 | rules: [ 25 | { 26 | test: /\.(js|jsx)$/, 27 | loader: 'babel-loader', 28 | exclude: /node_modules/ 29 | }, 30 | { 31 | test: /\.(css|less)$/, 32 | use: extractText.extract({ 33 | use: ['css-loader', 'less-loader'] 34 | }) 35 | }, 36 | { 37 | test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, 38 | loader: 'url-loader?limit=10000&name=./static/imgs/[hash].[ext]' 39 | }, 40 | { 41 | test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, 42 | loader: 'url-loader?limit=10000' 43 | } 44 | ] 45 | }, 46 | 47 | plugins: [ 48 | extractText, 49 | htmlPlugin 50 | ] 51 | } --------------------------------------------------------------------------------