├── meituan-backend-master ├── .babelrc ├── .gitignore ├── app.js ├── config.js ├── controller │ ├── admin │ │ ├── admin.js │ │ └── auth.js │ └── v1 │ │ ├── cites.js │ │ ├── comment.js │ │ ├── foods.js │ │ ├── order.js │ │ ├── pay.js │ │ ├── qiniu.js │ │ ├── restaurant.js │ │ └── statistic.js ├── db │ └── meituan │ │ ├── addresses.bson │ │ ├── addresses.metadata.json │ │ ├── admins.bson │ │ ├── admins.metadata.json │ │ ├── categories.bson │ │ ├── categories.metadata.json │ │ ├── cities.bson │ │ ├── cities.metadata.json │ │ ├── comments.bson │ │ ├── comments.metadata.json │ │ ├── foods.bson │ │ ├── foods.metadata.json │ │ ├── ids.bson │ │ ├── ids.metadata.json │ │ ├── orders.bson │ │ ├── orders.metadata.json │ │ ├── pays.bson │ │ ├── pays.metadata.json │ │ ├── restaurants.bson │ │ ├── restaurants.metadata.json │ │ ├── shoppingcarts.bson │ │ └── shoppingcarts.metadata.json ├── index.js ├── models │ ├── admin │ │ ├── address.js │ │ └── admin.js │ ├── ids.js │ └── v1 │ │ ├── category.js │ │ ├── comment.js │ │ ├── foods.js │ │ ├── order.js │ │ ├── pay.js │ │ └── restaurant.js ├── mongodb │ └── db.js ├── package-lock.json ├── package.json ├── prototype │ └── baseClass.js ├── public │ └── upload_imgs │ │ ├── 1554474335788微信图片_20170624085750.jpg │ │ ├── 1554623168889wx496bb03151ace7f0.o6zAJs_OBU9LZatGfY0c825yeQAA.Hz2JAIXcgxbtd3c7d7652b20173bed83dbaa05fcd0fd.jpg │ │ └── 1554623228203wx496bb03151ace7f0.o6zAJs_OBU9LZatGfY0c825yeQAA.SKBr1nVRxYMhd3c7d7652b20173bed83dbaa05fcd0fd.jpg ├── routes │ ├── admin.js │ ├── index.js │ ├── service.js │ ├── statistics.js │ └── v1.js └── screenshots │ ├── alipay.jpg │ └── weChat.jpg └── vue-meituan-master ├── .eslintignore ├── .gitignore ├── README.md ├── babel.config.js ├── package-lock.json ├── package.json ├── public ├── favicon.ico └── index.html ├── src ├── App.vue ├── api │ ├── index.js │ ├── location.js │ ├── order.js │ ├── request.js │ ├── restaurant.js │ ├── upload.js │ └── user.js ├── assets │ ├── default-avatar.png │ ├── friend_img.png │ ├── home-active.png │ ├── home.png │ ├── index-active.png │ ├── index.png │ ├── loading.gif │ ├── logo.png │ ├── my.png │ ├── nothing.png │ ├── order-active.png │ ├── order.png │ ├── pay_adv.png │ ├── restaurant.jpg │ ├── shoploading.png │ ├── skeleton_restaurant.jpg │ ├── star24_half@2x.png │ ├── star24_off@2x.png │ ├── star24_on@2x.png │ ├── user-banner.png │ └── 我的收藏.jpg ├── components │ ├── addressInfo.vue │ ├── alertTip.vue │ ├── bottom.vue │ ├── head.vue │ ├── littleCart.vue │ ├── loading.vue │ ├── search.vue │ ├── selector.vue │ └── star.vue ├── config.js ├── main.js ├── plugins │ └── qrcode.js ├── router │ └── index.js ├── stores │ ├── index.js │ ├── modules │ │ ├── address.js │ │ ├── cart.js │ │ └── restaurant.js │ └── mutation-types.js ├── style │ ├── common.scss │ └── mixin.scss ├── utils │ └── auth.js └── views │ ├── 404 │ └── error.vue │ ├── Index │ ├── Index.vue │ ├── nav.vue │ └── nearby_shops.vue │ ├── cart │ └── cart.vue │ ├── category │ └── category.vue │ ├── confirm_order │ ├── children │ │ ├── address.vue │ │ └── children │ │ │ └── add_address.vue │ └── confirm_order.vue │ ├── home │ ├── children │ │ ├── address.vue │ │ ├── collection.vue │ │ ├── comment.vue │ │ ├── footprint.vue │ │ ├── friend.vue │ │ └── thank_record.vue │ └── home.vue │ ├── location │ └── location.vue │ ├── login │ └── login.vue │ ├── order │ ├── comment.vue │ ├── order.vue │ ├── order_detail.vue │ └── star.vue │ ├── pay │ ├── pay.vue │ └── scan.vue │ ├── search │ └── search.vue │ └── store │ ├── comment │ └── comment.vue │ ├── menu │ ├── bottom.vue │ └── menu.vue │ ├── seller │ └── seller.vue │ ├── store.vue │ └── store_detail.vue └── vue.config.js /meituan-backend-master/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | "env","stage-3" 4 | ], 5 | "plugins": [[ 6 | "transform-runtime", 7 | { 8 | "helpers": false, 9 | "polyfill": false, 10 | "regenerator": true, 11 | "moduleName": "babel-runtime" 12 | } 13 | ]] 14 | } -------------------------------------------------------------------------------- /meituan-backend-master/.gitignore: -------------------------------------------------------------------------------- 1 | .idea/* 2 | node_modules -------------------------------------------------------------------------------- /meituan-backend-master/app.js: -------------------------------------------------------------------------------- 1 | import express from 'express'; 2 | import './mongodb/db.js'; 3 | import router from './routes/index.js'; 4 | import cookieParser from 'cookie-parser' 5 | import session from 'express-session'; 6 | import connectMongo from 'connect-mongo'; 7 | import bodyParser from 'body-parser' 8 | import multer from 'multer'; 9 | // import history from 'connect-history-api-fallback'; 10 | import config from './config' 11 | import path from 'path'; 12 | 13 | const app = express(); 14 | 15 | app.use(express.static(path.join(__dirname, 'public'))); 16 | 17 | let storage = multer.diskStorage({ 18 | destination: function (req, file, cb) { 19 | cb(null, './public/upload_imgs') 20 | }, 21 | filename: function (req, file, cb) { 22 | cb(null, Date.now() + file.originalname) 23 | } 24 | }); 25 | 26 | let upload = multer({storage: storage}); 27 | 28 | 29 | app.all('*', (req, res, next) => { 30 | res.header("Access-Control-Allow-Origin", req.headers.origin || '*'); 31 | res.header("Access-Control-Allow-Headers", "Content-Type, Authorization, X-Requested-With"); 32 | res.header("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS"); 33 | res.header("Access-Control-Allow-Credentials", true); //可以带cookies 34 | res.header("X-Powered-By", '3.2.1'); 35 | res.header("Cache-Control", "public,max-age=60000"); 36 | if (req.method === 'OPTIONS') { 37 | res.sendStatus(200); 38 | } else { 39 | next(); 40 | } 41 | }); 42 | 43 | const MongoStore = connectMongo(session); 44 | app.use(bodyParser.urlencoded({extended: false})) 45 | app.use(bodyParser.json({})); 46 | app.use(cookieParser()); 47 | app.use(session({ 48 | name: 'mt-session', 49 | secret: 'meituan', 50 | resave: true, 51 | saveUninitialized: false, 52 | cookie: { 53 | httpOnly: true, 54 | secure: false, 55 | maxAge: 365 * 24 * 60 * 60 * 1000, 56 | }, 57 | store: new MongoStore({ 58 | url: config.sessionStorageURL 59 | }) 60 | })); 61 | router(app); 62 | // app.use(history()); 63 | console.log('*********************************') 64 | console.log(`service start on ${config.port}`) 65 | console.log('*********************************') 66 | app.listen(config.port); 67 | 68 | module.exports = app; 69 | -------------------------------------------------------------------------------- /meituan-backend-master/config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | port: 3000, //启动端口 3 | DB_URL: 'mongodb://127.0.0.1:27017/takeaway', //数据库地址 4 | notifyUrl: 'http://39.108.3.12:3000/v1/notify_url', //支付异步通知地址 5 | synNotifyUrl: 'http://39.108.3.12', //客户端同步跳转 6 | sessionStorageURL: 'mongodb://127.0.0.1:27017/session', //数据库存放session地址 7 | Bucket: 'meituan-74', //七牛云bucket 8 | AccessKey: 'SYG3SptaNRuuj-bihv8pglHgM4Y00U37-Fmh84i9', //七牛云accessKey 9 | SecretKey: '35lEerajvWbjyQR_gCE7y-MU29f5SpFWPg-OlUSa', //七牛云secretKey 10 | tencentkey: 'YDSBZ-B7AKK-NH3JC-AUJLJ-5QTY3-H4FD5', //腾讯位置secreKey 11 | tencentkey2: '', //腾讯位置服务secreKey 12 | wechatAppid: '', // 微信小程序appid 13 | wecahatSecret: '' // 微信小程序密钥 14 | }; 15 | 16 | 17 | -------------------------------------------------------------------------------- /meituan-backend-master/controller/admin/auth.js: -------------------------------------------------------------------------------- 1 | class Auth { 2 | authUser(req, res, next) { //验证用户 3 | if (!req.session.user_id) { 4 | res.send({ 5 | status: 403, 6 | message: '未登录' 7 | }) 8 | console.log("66666666666666666666") 9 | } else { 10 | next(); 11 | } 12 | } 13 | 14 | authAdmin(req, res, next) { //验证管理者 15 | if (!req.session.admin_id) { 16 | res.send({ 17 | status: 403, 18 | message: '未登录' 19 | }) 20 | console.log("77777777777777777777777777") 21 | 22 | } else { 23 | next(); 24 | } 25 | } 26 | 27 | auth(req, res, next) { 28 | if (!req.session.admin_id && !req.session.user_id) { 29 | res.send({ 30 | status: 403, 31 | message: '未登录' 32 | }) 33 | console.log("4444444444444444444444444") 34 | } else { 35 | next(); 36 | } 37 | } 38 | } 39 | 40 | export default new Auth(); -------------------------------------------------------------------------------- /meituan-backend-master/controller/v1/cites.js: -------------------------------------------------------------------------------- 1 | import BaseClass from '../../prototype/baseClass' 2 | 3 | class Cites extends BaseClass { 4 | constructor() { 5 | super(); 6 | this.suggestion = this.suggestion.bind(this); 7 | this.location = this.location.bind(this); 8 | this.detailLocation = this.detailLocation.bind(this); 9 | } 10 | 11 | //输入地址关键词找位置 12 | async suggestion(req, res, next) { 13 | let {keyword} = req.query; 14 | if (!keyword) { 15 | res.send({ 16 | status: -1, 17 | message: '位置搜索失败,参数有误!' 18 | }) 19 | return; 20 | } 21 | try { 22 | let data = await this.locationSearch(keyword) 23 | res.send({ 24 | status: 200, 25 | message: "获取位置信息成功", 26 | data: data 27 | } 28 | ) 29 | } catch (err) { 30 | console.log('获取位置信息失败', err); 31 | res.send({ 32 | status: -1, 33 | message: '获取位置信息失败' 34 | }) 35 | } 36 | } 37 | 38 | //定位当前位置 39 | async location(req, res, next) { 40 | let result = await this.getLocation(req, res); 41 | let data = await this.getDetailPosition(result, res, (data) => { 42 | res.send({ 43 | status: 200, 44 | message: "获取位置信息成功", 45 | data 46 | } 47 | ) 48 | }); 49 | } 50 | 51 | async detailLocation(req, res, next) { 52 | let location = req.query.location; 53 | console.log('location', location) 54 | let data = await this.getDetailPosition(location) 55 | res.send({ 56 | status: 200, 57 | message: "获取位置信息成功", 58 | data 59 | } 60 | ) 61 | 62 | } 63 | } 64 | 65 | export default new Cites(); -------------------------------------------------------------------------------- /meituan-backend-master/controller/v1/comment.js: -------------------------------------------------------------------------------- 1 | import BaseClass from '../../prototype/baseClass' 2 | import AdminModel from '../../models/admin/admin'; 3 | import OrderModel from '../../models/v1/order' 4 | import CommentModel from '../../models/v1/comment' 5 | import RestaurantModel from '../../models/v1/restaurant' 6 | import moment from 'moment'; 7 | 8 | class Comment extends BaseClass { 9 | constructor() { 10 | super(); 11 | this.makeComment = this.makeComment.bind(this); 12 | } 13 | 14 | //评论 15 | async makeComment(req, res, next) { 16 | let {order_id, comment_data, food_score = 0, delivery_score = 0, quality_score = 0, pic_url = []} = req.body; 17 | if (!order_id || !comment_data) { 18 | res.send({ 19 | status: -1, 20 | message: '评论失败,参数有误' 21 | }); 22 | return; 23 | } 24 | try { 25 | let order = await OrderModel.findOne({id: order_id}, '-_id').populate([ 26 | {path: 'restaurant'}, {path: 'user_id'}]); 27 | 28 | //判断订单能否评价 29 | let user = await AdminModel.findOne({id: order.user_id.id}); 30 | let user_id = req.session.user_id; 31 | if (user.id !== user_id || order.code !== 200) { 32 | res.send({ 33 | status: -1, 34 | message: '评价失败,该订单不能评论!' 35 | }); 36 | return; 37 | } 38 | // console.log('user', user); 39 | let comment_id = await this.getId('comment_id'); 40 | let data = { 41 | user_id: user_id, 42 | id: comment_id, 43 | user_name: user.username, 44 | avatar: user.avatar, 45 | restaurant_id: order.restaurant.id, 46 | restaurant: order.restaurant._id, 47 | pic_url:pic_url, 48 | comment_data: comment_data, 49 | order_id: order_id, 50 | food_score: food_score, 51 | delivery_score:delivery_score, 52 | }; 53 | console.log(data.user_id) 54 | console.log("aaaaaaaaaaaaa"); 55 | 56 | let comment = await new CommentModel(data).save(); 57 | /*修改商品评分begin*/ 58 | let restaurant = order.restaurant; 59 | let comment_number = restaurant.comment_number; 60 | restaurant.wm_poi_score = ((restaurant.wm_poi_score * comment_number + food_score ) / (comment_number + 1)).toFixed(1); 61 | restaurant.delivery_score = ((restaurant.delivery_score * comment_number + delivery_score) / (comment_number + 1)).toFixed(1); 62 | restaurant.comment_number++; 63 | await restaurant.save(); 64 | /*修改商品评分end*/ 65 | /* order.has_comment = !order.has_comment; 66 | await order.save();*/ 67 | await OrderModel.update({id: order_id}, {has_comment: true}); 68 | res.send({ 69 | status: 200, 70 | message: '评论成功' 71 | }) 72 | } catch (err) { 73 | 74 | console.log('评论失败', err); 75 | res.send({ 76 | status: -1, 77 | message: '评论失败' 78 | }) 79 | } 80 | } 81 | 82 | // 后台添加评论 83 | async _makeComment(req, res, next) { 84 | let comment = req.body.comment; 85 | for (var i = 0; i < comment.length; i++) { 86 | let comment_data = new CommentModel(comment[i]); 87 | await comment_data.save(); 88 | } 89 | res.send({ 90 | status: 1 91 | }) 92 | } 93 | 94 | //获取餐馆评论 95 | async getComment(req, res, next) { 96 | let {restaurant_id, offset = 0, limit = 5} = req.query; 97 | if (!restaurant_id) { 98 | res.send({ 99 | status: -1, 100 | message: '获取餐馆评论失败,参数有误!' 101 | }); 102 | return; 103 | } 104 | try { 105 | let comments = await CommentModel.find({restaurant_id}, '-_id').skip(offset * limit).limit(Number(limit)).sort({'comment_time': -1}); 106 | res.send({ 107 | status: 200, 108 | message: '获取餐馆评论成功', 109 | data: comments 110 | }) 111 | } catch (err) { 112 | console.log('获取餐馆评论失败', err); 113 | res.send({ 114 | status: -1, 115 | message: '获取餐馆评论失败' 116 | }) 117 | } 118 | } 119 | 120 | //获取我的评论 121 | async myComment(req, res, next) { 122 | try { 123 | let comments = await CommentModel.find({user_id: req.session.user_id}).populate({path: 'restaurant'}); 124 | res.send({ 125 | status: 200, 126 | data: comments, 127 | message: '获取我的评论成功' 128 | }) 129 | } catch (err) { 130 | console.log('获取我的评论失败', err); 131 | res.send({ 132 | status: -1, 133 | message: '获取我的评论失败' 134 | }) 135 | } 136 | } 137 | 138 | //商家获取我的店铺的用户评论 139 | async myRestaurantComment(req, res, next) { 140 | let user_id = req.session.admin_id; 141 | try { 142 | let restaurant = await RestaurantModel.findOne({user_id}); 143 | if (!restaurant) { 144 | res.send({ 145 | status: -1, 146 | message: '没有餐馆' 147 | }); 148 | return false; 149 | } 150 | let comments = await CommentModel.find({restaurant_id: restaurant.id}, '-_id').sort({_id: -1}); 151 | 152 | for (let i=0;i { 10 | console.log('Connecting to the database Successfully') 11 | }) 12 | 13 | db.on('error', function (error) { 14 | console.error('Error in MongoDb connection: ' + error); 15 | mongoose.disconnect(); 16 | }); 17 | 18 | db.on('close', function () { 19 | console.log('The database is disconnected and try to reconnect the database'); 20 | mongoose.connect(config.DB_URL, {server: {auto_reconnect: true}}); 21 | }); 22 | 23 | export default db; 24 | -------------------------------------------------------------------------------- /meituan-backend-master/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "meituan-back", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "dev": "cross-env NODE_ENV=dev nodemon index.js", 8 | "test": " mocha test/v1/user.test.js --compilers js:babel-register" 9 | }, 10 | "author": "zwStar", 11 | "license": "ISC", 12 | "devDependencies": { 13 | "babel-cli": "^6.26.0", 14 | "babel-plugin-transform-runtime": "^6.23.0", 15 | "babel-preset-env": "^1.6.1", 16 | "babel-preset-stage-3": "^6.24.1", 17 | "babel-register": "^6.26.0", 18 | "babel-runtime": "^6.26.0", 19 | "blueimp-md5": "^2.10.0", 20 | "body-parser": "^1.18.2", 21 | "connect-mongo": "^2.0.0", 22 | "cookie-parser": "^1.4.3", 23 | "cross-env": "^6.0.3", 24 | "crypto": "^1.0.1", 25 | "express": "^4.16.2", 26 | "express-session": "^1.15.6", 27 | "form-data": "^2.3.2", 28 | "moment": "^2.20.1", 29 | "mongoose": "^4.13.7", 30 | "node-fetch": "^1.7.3", 31 | "qiniu": "^7.1.2", 32 | "request": "^2.83.0", 33 | "time-formater": "^1.0.1" 34 | }, 35 | "dependencies": { 36 | "multer": "^1.4.1" 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /meituan-backend-master/prototype/baseClass.js: -------------------------------------------------------------------------------- 1 | import fetch from 'node-fetch'; 2 | import Ids from '../models/ids' 3 | import config from '../config' 4 | 5 | export default class BaseClass { 6 | constructor() { 7 | this.tencentkey = config.tencentkey; 8 | this.tencentkey2 = config.tencentkey2; 9 | this.idList = ['restaurant_id', 'food_id', 'order_id', 'user_id', 'address_id', 'category_id', 'sku_id', 'admin_id', 'pay_id', 'comment_id']; 10 | } 11 | 12 | async fetch(url = '', data = {}, type = 'GET', resType = 'JSON') { 13 | type = type.toUpperCase(); 14 | resType = resType.toUpperCase(); 15 | if (type == 'GET') { 16 | let dataStr = ''; //数据拼接字符串 17 | Object.keys(data).forEach(key => { 18 | dataStr += key + '=' + data[key] + '&'; 19 | }); 20 | 21 | if (dataStr !== '') { 22 | dataStr = dataStr.substr(0, dataStr.lastIndexOf('&')); 23 | url = url + '?' + dataStr; 24 | } 25 | } 26 | 27 | let requestConfig = { 28 | method: type, 29 | headers: { 30 | 'Accept': 'application/json', 31 | 'Content-Type': 'application/json' 32 | }, 33 | } 34 | 35 | if (type == 'POST') { 36 | Object.defineProperty(requestConfig, 'body', { 37 | value: JSON.stringify(data) 38 | }) 39 | } 40 | let responseJson; 41 | try { 42 | const response = await fetch(url, requestConfig); 43 | if (resType === 'TEXT') { 44 | responseJson = await response.text(); 45 | } else { 46 | responseJson = await response.json(); 47 | } 48 | } catch (err) { 49 | console.log('获取http数据失败', err); 50 | throw new Error(err) 51 | } 52 | return responseJson 53 | } 54 | 55 | //获取id列表 56 | async getId(type_id) { 57 | if (!this.idList.includes(type_id)) { 58 | throw new Error('id类型错误'); 59 | return 60 | } 61 | try { 62 | const idData = await Ids.findOneAndUpdate({}, {'$inc': {[type_id]: 1}}); 63 | return ++idData[type_id]; //返回当前类型id数量*/ 64 | } catch (err) { 65 | console.log('获取ID数据失败'); 66 | throw new Error(err) 67 | } 68 | } 69 | 70 | //根据ip定位定位 只能获取到经纬度和省份城市 不能获取到具体位置 还需要调用下面接口获取具体位置 71 | async getLocation(req, res, next) { 72 | let ip = req.ip; 73 | const ipArr = ip.split(':'); //切割字符串提取ip 74 | ip = ipArr[ipArr.length - 1]; 75 | if (process.env.NODE_ENV == 'dev') { //开发环境 76 | ip = '222.191.244.250'; 77 | } 78 | 79 | try { 80 | let result; 81 | //根据ip地址请求获取数据 82 | result = await this.fetch('http://apis.map.qq.com/ws/location/v1/ip', { 83 | ip, 84 | key: this.tencentkey, 85 | }); 86 | 87 | 88 | 89 | if (result.status !== 0) { 90 | result = await this.fetch('http://apis.map.qq.com/ws/location/v1/ip', { 91 | ip, 92 | key: this.tencentkey2, 93 | }) 94 | } 95 | 96 | //status===0表示请求成功 97 | if (result.status === 0) { 98 | const cityInfo = { 99 | lat: result.result.location.lat, //纬度 100 | lng: result.result.location.lng, //经度 101 | city: result.result.ad_info.city, 102 | }; 103 | cityInfo.city = cityInfo.city.replace(/市$/, ''); 104 | return cityInfo; 105 | } else { 106 | /* console.log('定位失败', result) 107 | res.send({ 108 | status: -1, 109 | message: '定位失败' 110 | })*/ 111 | return {lat: 23.02067, lng: 113.75179, city: '东莞市'} 112 | 113 | } 114 | } catch (err) { 115 | console.log('定位失败', err); 116 | res.send({ 117 | status: -1, 118 | message: '定位失败' 119 | }) 120 | } 121 | } 122 | 123 | //根据经纬度获取详细地址信息 124 | async getDetailPosition(location, res, successFn) { 125 | try { 126 | if (location) { 127 | let cityInfo = await this.fetch('http://apis.map.qq.com/ws/geocoder/v1', { 128 | location: location.lat + ',' + location.lng, 129 | key: this.tencentkey 130 | }, 'GET'); 131 | let address = cityInfo.result.address.replace(/^.{2}省.{2}市/, ''); 132 | successFn({ 133 | address, 134 | location 135 | }); 136 | } 137 | } catch (err) { 138 | console.log('获取位置失败', err); 139 | res.send({ 140 | status: -1, 141 | message: '获取定位失败' 142 | }) 143 | } 144 | 145 | } 146 | 147 | //根据关键词搜索位置 148 | async locationSearch(keyword) { 149 | try { 150 | let reqData = { 151 | keyword: encodeURI(keyword), 152 | key: this.tencentkey, 153 | policy: 1 154 | } 155 | let data = await this.fetch('http://apis.map.qq.com/ws/place/v1/suggestion', reqData, "GET"); 156 | return data; 157 | } catch (err) { 158 | console.log('搜索位置出错', err); 159 | 160 | } 161 | } 162 | } -------------------------------------------------------------------------------- /meituan-backend-master/public/upload_imgs/1554474335788微信图片_20170624085750.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunying128/Vue/92a843d2c4dab4167610404b2ca52fae80790ced/meituan-backend-master/public/upload_imgs/1554474335788微信图片_20170624085750.jpg -------------------------------------------------------------------------------- /meituan-backend-master/public/upload_imgs/1554623168889wx496bb03151ace7f0.o6zAJs_OBU9LZatGfY0c825yeQAA.Hz2JAIXcgxbtd3c7d7652b20173bed83dbaa05fcd0fd.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunying128/Vue/92a843d2c4dab4167610404b2ca52fae80790ced/meituan-backend-master/public/upload_imgs/1554623168889wx496bb03151ace7f0.o6zAJs_OBU9LZatGfY0c825yeQAA.Hz2JAIXcgxbtd3c7d7652b20173bed83dbaa05fcd0fd.jpg -------------------------------------------------------------------------------- /meituan-backend-master/public/upload_imgs/1554623228203wx496bb03151ace7f0.o6zAJs_OBU9LZatGfY0c825yeQAA.SKBr1nVRxYMhd3c7d7652b20173bed83dbaa05fcd0fd.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunying128/Vue/92a843d2c4dab4167610404b2ca52fae80790ced/meituan-backend-master/public/upload_imgs/1554623228203wx496bb03151ace7f0.o6zAJs_OBU9LZatGfY0c825yeQAA.SKBr1nVRxYMhd3c7d7652b20173bed83dbaa05fcd0fd.jpg -------------------------------------------------------------------------------- /meituan-backend-master/routes/admin.js: -------------------------------------------------------------------------------- 1 | import express from 'express' 2 | import Auth from '../controller/admin/auth' 3 | import Admin from '../controller/admin/admin' 4 | 5 | const router = express.Router() 6 | 7 | router.post('/user_login', Admin.userLogin); //用户登录 8 | router.post('/admin_login', Admin.adminLogin); //管理登录 9 | router.post('/wechat_login', Admin.wechatLogin); // 微信登录 10 | router.get('/user_info', Admin.userInfo, Auth.authUser); //获取用户信息 11 | router.post('/user_info', Auth.authUser, Admin.setUserInfo); // 设置获取用户 12 | router.post('/change_avatar', Auth.authUser, Admin.changeAvatar) //改头像 13 | router.post('/logout', Admin.logout); //退出 14 | router.post('/address', Auth.authUser, Admin.addAddress); //添加收货地址 15 | router.get('/all_address', Auth.authUser, Admin.getAllAddress) //获取用户所有地址 16 | router.get('/address', Auth.authUser, Admin.getAddress); //管理端获取所有地址 17 | router.post('/update_address', Auth.authUser, Admin.updateAddress); //更新地址 18 | router.delete('/address', Auth.authUser, Admin.deleteAddress); //删除收获地址 19 | router.get('/user_statistic', Auth.authUser, Admin.userStatistic); //用户信息 20 | router.post('/add_user', Auth.authUser, Admin.addUser); // 新增用户 21 | router.post('/update_passwd', Auth.authUser, Admin.updatePasswd); // 修改密码 22 | export default router; -------------------------------------------------------------------------------- /meituan-backend-master/routes/index.js: -------------------------------------------------------------------------------- 1 | import v1 from './v1' 2 | import admin from './admin' 3 | import statistics from './statistics' 4 | import service from './service' 5 | export default app => { 6 | app.use('/v1', v1); 7 | app.use('/admin', admin); 8 | app.use('/statistics',statistics); 9 | app.use('/service',service); 10 | } -------------------------------------------------------------------------------- /meituan-backend-master/routes/service.js: -------------------------------------------------------------------------------- 1 | import express from 'express' 2 | import Qiniu from '../controller/v1/qiniu' 3 | import Auth from '../controller/admin/auth' 4 | 5 | const router = express.Router(); 6 | 7 | //七牛云上次凭证 8 | router.get('/uploadtoken', Auth.auth, Qiniu.uploadToken); 9 | export default router; -------------------------------------------------------------------------------- /meituan-backend-master/routes/statistics.js: -------------------------------------------------------------------------------- 1 | import express from 'express' 2 | import Statistic from '../controller/v1/statistic' 3 | import Auth from '../controller/admin/auth' 4 | 5 | const router = express.Router(); 6 | router.get('/count/user', Auth.authAdmin, Statistic.userCount); //获取当天新增用户数量 7 | router.get('/count/order', Auth.authAdmin, Statistic.orderCount); //获取当天新增订单数量 8 | 9 | router.get('/all/user', Auth.authAdmin, Statistic.allUserCount); //获取所有用户数量 10 | router.get('/all/order', Auth.authAdmin, Statistic.allOrderCount); //获取所有订单数量 11 | 12 | router.get('/count/restaurant', Auth.authAdmin, Statistic.restaurantCount); //餐馆数量 13 | 14 | router.get('/my_order', Auth.authAdmin, Statistic.myOrder); 15 | router.get('/my_order_price', Auth.authAdmin, Statistic.myOrderPrice); 16 | 17 | 18 | export default router; -------------------------------------------------------------------------------- /meituan-backend-master/routes/v1.js: -------------------------------------------------------------------------------- 1 | import express from 'express'; 2 | import Cites from '../controller/v1/cites'; 3 | import Restaurant from '../controller/v1/restaurant'; 4 | import Order from '../controller/v1/order'; 5 | import Comment from '../controller/v1/comment'; 6 | import Foods from '../controller/v1/foods'; 7 | import Pay from '../controller/v1/pay'; 8 | import Auth from '../controller/admin/auth'; 9 | import Category from '../models/v1/category'; 10 | 11 | const router = express.Router(); 12 | router.get('/suggestion', Cites.suggestion); //地址位置搜索 13 | router.get('/location', Cites.location); //定位 14 | router.get('/detailLocation', Cites.detailLocation); // 根据lat,lng获取详情位置 15 | router.get('/restaurants', Restaurant.getRestaurants); //获取多家餐馆 16 | router.get('/all_restaurant', Auth.authAdmin, Restaurant.allRestaurant); // 获取全部餐馆 17 | router.get('/my_category', Auth.authAdmin, Restaurant.getMyCategory); // 获取我的分类 18 | router.post('/update_category', Auth.authAdmin, Restaurant.updateCategory); // 更新category分类 19 | router.delete('/category', Auth.authAdmin, Restaurant.deleteCategory); // 删除分类 20 | router.get('/restaurant/:restaurant_id', Restaurant.getRestaurant); //获取指定餐馆信息 21 | router.post('/restaurant', Auth.authAdmin, Restaurant.addRestaurant); //添加商家 22 | router.get('/search/restaurant', Restaurant.searchRestaurant); //搜索商家 23 | router.get('/my_restaurant', Auth.authAdmin, Restaurant.myRestaurant); //获取我的餐馆 24 | 25 | router.post('/category', Foods.addCategory); //添加食物分类 26 | router.get('/category/:restaurant_id', Restaurant.getCategory); //获取指定餐馆食物分类 27 | 28 | router.post('/food', Auth.authAdmin, Foods.addFood); //添加食物 29 | 30 | router.get('/food/:restaurant_id', Restaurant.getFoods); //获取指定餐馆食物列表 31 | router.get('/my_foods',Auth.authAdmin, Restaurant.getMyFoods); // 获取我的餐馆食物 32 | router.delete('/food/:food_id', Auth.authAdmin, Foods.deleteFood); //删除食物 33 | router.post('/update_foods', Auth.authAdmin, Foods.updateFoods); // 更新食物 34 | 35 | //评价 36 | router.get('/comment', Comment.getComment); //获取餐馆评论 37 | router.post('/comment', Auth.authUser, Comment.makeComment); //评论 38 | router.post('/_comment', Comment._makeComment); //添加评论 39 | router.get('/my_comment', Auth.authUser, Comment.myComment); //获取我的评论 40 | router.get('/comment_count', Comment.commentCount); //获取评论数量 41 | router.get('/my_restaurant_comment', Auth.authAdmin, Comment.myRestaurantComment); //获取我的餐馆评论 42 | router.delete('/comment', Auth.authUser, Comment.deleteComment); //删除评论 43 | router.post('/reply_comment', Auth.authAdmin, Comment.replyComment); // 商家回复评论 44 | //订单 45 | router.post('/order', Auth.authUser, Order.makeOrder); //下订单 46 | router.post('/wxorder', Auth.authUser, Order.makeWXOrder); // 下微信订单 47 | router.get('/orders', Auth.authUser, Order.getOrders); //获取订单列表 48 | router.get('/my_restaurant_order', Auth.authAdmin, Order.getMyRestaurantOrder); // 获取我的餐馆订单 49 | router.get('/order/:order_id', Auth.authUser, Order.getOrder); //获取指定订单 50 | router.post('/order_confirm', Auth.authAdmin, Order.confirmOrder); // 商家确认订单 51 | 52 | //支付 53 | router.post('/pay', Auth.authUser, Pay.initPay); //初始化支付 54 | router.post('/notify_url', Pay.payNotice); //支付异步通知 55 | router.get('/listen_status', Auth.authUser, Pay.listenStatus); //监听扫描结果 56 | export default router; 57 | -------------------------------------------------------------------------------- /meituan-backend-master/screenshots/alipay.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunying128/Vue/92a843d2c4dab4167610404b2ca52fae80790ced/meituan-backend-master/screenshots/alipay.jpg -------------------------------------------------------------------------------- /meituan-backend-master/screenshots/weChat.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunying128/Vue/92a843d2c4dab4167610404b2ca52fae80790ced/meituan-backend-master/screenshots/weChat.jpg -------------------------------------------------------------------------------- /vue-meituan-master/.eslintignore: -------------------------------------------------------------------------------- 1 | node_modules/* 2 | src/plugins/* -------------------------------------------------------------------------------- /vue-meituan-master/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /dist 4 | 5 | # local env files 6 | .env.local 7 | .env.*.local 8 | 9 | # Log files 10 | npm-debug.log* 11 | yarn-debug.log* 12 | yarn-error.log* 13 | 14 | # Editor directories and files 15 | .idea 16 | .vscode 17 | *.suo 18 | *.ntvs* 19 | *.njsproj 20 | *.sln 21 | *.sw? 22 | -------------------------------------------------------------------------------- /vue-meituan-master/README.md: -------------------------------------------------------------------------------- 1 | ## 更新(2019/6/5) ## 2 | 项目已经发布一年多的时间,vue-cli已经升级到3.0,很多依赖也都更新了导致项目跑不起来,这里简单的把项目升级到vue-cli3版本,接下来准备发布小程序版本的,感谢大家的支持。 3 | 4 | ## 关于 ## 5 | 好再来是一款类似美团外卖的项目,是根据外卖战应运而生,前端的vue+vuex+vue-router+axios,因为需要用到定位和支付等功能,需要后端配合,而且想要做真正数据交互,所以用express(基于nodejs的框架)做后台,数据库用NOSQL的mongodb。 前端项目包含20多个路由,涉及到vue文件有40个,功能设计登录,定位,浏览商品,加购物车,下订单,支付(支持微信和支付宝的扫码支付和调起app支付),评价,个人信息更改,是一个较为完整的项目。 6 | 7 | ### 注意:此项目为个人开发实践练习,不作为任何商业用途 8 | 9 | ## 功能 ## 10 | - 登录/注销 11 | - IP定位 12 | - 搜索地址 13 | - 获取商店(计算当前位置和商店的距离) 14 | - 加购物车 15 | - 下订单 16 | - 支付(支持微信和支付宝的扫码支付和调起app支付) 17 | - 评价 18 | - 头像上传(用了七牛云存储) 19 | - 图片懒加载 20 | 21 | 22 | ## 技术栈 ## 23 | - Webpack-cli搭建项目 24 | - Vue全家桶(vue+vuex+vue-router) 25 | - CSS预处理器SCSS 26 | - axios与后端进行请求数据 27 | - 七牛云存储图片 28 | - 支付宝和微信支付 29 | - 使用better-scroll滚动 30 | - Express搭建后端服务 31 | - Mongoose对MongoDB进行便捷操作 32 | - 使用Charles抓取数据 33 | 34 | 35 | ## 效果演示 36 | ### 主界面 ### 37 | ![主界面](screenshots/index3.gif) 38 | ### 定位和搜索 ### 39 | ![定位](screenshots/location.gif) 40 | ### 扫码支付 ### 41 | ![扫码支付](screenshots/scan_pay.gif) 42 | ### APP支付 ### 43 | ![调用APP支付](screenshots/app_pay.gif) 44 | ### 我的购物车 ### 45 | ![购物车](screenshots/cart.gif) 46 | ### 清除购物车 ### 47 | ![清除购物车](screenshots/clearCart.gif) 48 | ### 评论 ### 49 | ![评论](screenshots/comment.gif) 50 | ### 其它 ### 51 | ![其它](screenshots/other.gif) 52 | ### 还有一些其它功能就不放图了哈 ### 53 | 54 | ## 线上地址 ## 55 | http://39.108.3.12 56 | 请用谷歌浏览器然后开启移动端浏览,如果要调用APP支付就需要用手机自带浏览器打开,然后支付时选择调起APP支付 57 | 58 | ## 未完待续 ## 59 | 还有商家管理PC端还没写完,等写完再开源出来 60 | 61 | ## 项目部署 62 | 63 | 阿里云 CentOS 7.4 64位 64 | 65 | ## 项目运行 66 | 67 | ``` 68 | 项目运行之前,请确保系统已经安装以下应用 69 | 1、node 70 | 2、mongodb 71 | ``` 72 | 73 | ``` 74 | git clone https://github.com/zwStar/vue-meituan.git 75 | 76 | cd vue-meituan 77 | 78 | npm install 79 | 80 | npm run serve 81 | 82 | 访问: http://localhost:8080 (确保后端项目服务已开启) 83 | 84 | ``` 85 | 86 | # 项目布局 87 | 88 | ``` 89 | . 90 | ├── api 后端接口 91 | ├── config.js 运行配置 92 | ├── assets 静态资源 93 | ├── components 全局组件 94 | ├── router 路由 95 | ├── store vuex 96 | ├── styles 全局样式 97 | ├── views 页面 98 | ├── App.vue 入口页面 99 | ├── main.js 入口 100 | ├── .babelrc babel-loader 配置 101 | ├── .gitignore git 忽略项 102 | ├── favicon.ico favicon图标 103 | ├── index.html html模板 104 | └── package.json package.json 105 | . 106 | 107 | ``` 108 | 109 | # License 110 | MIT 111 | 112 | 113 | 114 | 115 | 116 | 117 | -------------------------------------------------------------------------------- /vue-meituan-master/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | '@vue/app' 4 | ], 5 | plugins: [ 6 | [ 7 | 'component', 8 | { 9 | 'libraryName': 'mint-ui', 10 | 'style': true 11 | } 12 | ] 13 | ] 14 | }; -------------------------------------------------------------------------------- /vue-meituan-master/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue-meituan", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "serve": "vue-cli-service serve", 7 | "build": "vue-cli-service build", 8 | "lint": "vue-cli-service lint" 9 | }, 10 | "dependencies": { 11 | "axios": "^0.18.0", 12 | "better-scroll": "^1.15.2", 13 | "core-js": "^2.6.5", 14 | "fastclick": "^1.0.6", 15 | "less-loader": "^5.0.0", 16 | "mint-ui": "^2.2.13", 17 | "vue": "^2.6.10", 18 | "vue-router": "^3.0.6", 19 | "vuex": "^3.1.1" 20 | }, 21 | "devDependencies": { 22 | "@vue/cli-plugin-babel": "^3.8.0", 23 | "@vue/cli-plugin-eslint": "^3.8.0", 24 | "@vue/cli-service": "^3.8.0", 25 | "babel-eslint": "^10.0.1", 26 | "babel-plugin-component": "^1.1.1", 27 | "eslint": "^5.16.0", 28 | "eslint-plugin-vue": "^5.0.0", 29 | "node-sass": "^4.12.0", 30 | "sass-loader": "^7.1.0", 31 | "vue-template-compiler": "^2.6.10" 32 | }, 33 | "eslintConfig": { 34 | "root": true, 35 | "env": { 36 | "node": true 37 | }, 38 | "extends": [ 39 | "plugin:vue/essential", 40 | "eslint:recommended" 41 | ], 42 | "rules": { 43 | "no-console": 2, 44 | "no-debugger": 2 45 | }, 46 | "parserOptions": { 47 | "parser": "babel-eslint" 48 | } 49 | }, 50 | "postcss": { 51 | "plugins": { 52 | "autoprefixer": {} 53 | } 54 | }, 55 | "browserslist": [ 56 | "> 1%", 57 | "last 2 versions" 58 | ] 59 | } 60 | -------------------------------------------------------------------------------- /vue-meituan-master/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunying128/Vue/92a843d2c4dab4167610404b2ca52fae80790ced/vue-meituan-master/public/favicon.ico -------------------------------------------------------------------------------- /vue-meituan-master/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | vue-meituan 9 | 10 | 11 | 14 |
15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /vue-meituan-master/src/App.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 22 | 23 | 30 | -------------------------------------------------------------------------------- /vue-meituan-master/src/api/index.js: -------------------------------------------------------------------------------- 1 | import config from '../config' 2 | import router from '@/router' 3 | import {removeInfo} from '@/utils/auth' 4 | 5 | const baseURL = config.baseURL; 6 | 7 | const axios = require('axios').create({ 8 | baseURL: baseURL, //api请求的baseURL 9 | timeout: 0, 10 | withCredentials: true, // 允许跨域 cookie 11 | headers: {'X-Requested-With': 'XMLHttpRequest'}, 12 | maxContentLength: 2000, 13 | transformResponse: [function (data) { 14 | try { 15 | data = JSON.parse(data); 16 | } catch (e) { 17 | data = {}; 18 | } 19 | if (data.status === 403) { 20 | removeInfo(); 21 | router.push('/login'); 22 | } 23 | return data; 24 | }] 25 | }) 26 | 27 | 28 | // get 29 | export const _get = (req) => { 30 | return axios.get(req.url, {params: req.data}) 31 | } 32 | 33 | // post 34 | export const _post = (req) => { 35 | return axios({method: 'post', url: `/${req.url}`, data: req.data}) 36 | } 37 | 38 | //patch 39 | export const _put = (req) => { 40 | return axios({method: 'put', url: `/${req.url}`, data: req.data}) 41 | } 42 | 43 | //delete 44 | export const _delete = (req) => { 45 | return axios({method: 'delete', url: `/${req.url}`, data: req.data}) 46 | } 47 | 48 | //post and no withCredentials 49 | export const _postNoWithCredentials = (req) => { 50 | return axios({method: 'post', url: `/${req.url}`, data: req.data,withCredentials:false}) 51 | } 52 | -------------------------------------------------------------------------------- /vue-meituan-master/src/api/location.js: -------------------------------------------------------------------------------- 1 | import {_get} from './index' 2 | 3 | //定位搜索建议 4 | export const suggestion = (data) =>{ 5 | let req = { 6 | data:data 7 | }; 8 | req.url = 'v1/suggestion' 9 | return _get(req); 10 | } 11 | 12 | //定位当前位置 13 | export const location = (data) =>{ 14 | let req = { 15 | data 16 | } 17 | req.url = 'v1/location' 18 | return _get(req) 19 | } 20 | -------------------------------------------------------------------------------- /vue-meituan-master/src/api/order.js: -------------------------------------------------------------------------------- 1 | import {_get, _post} from './index' 2 | 3 | //提交订单 4 | export const submitOrder = (data) => { 5 | let req = { 6 | data, 7 | url: 'v1/order' 8 | }; 9 | return _post(req); 10 | } 11 | 12 | //准备支付 13 | export const initPay = (data) => { 14 | let req = { 15 | data, 16 | url: 'v1/pay' 17 | } 18 | return _post(req); 19 | } 20 | 21 | //获取订单信息 22 | export const orderInfo = (data) => { 23 | let req = { 24 | url: `v1/order/${data.order_id}` 25 | } 26 | return _get(req); 27 | } 28 | 29 | //获取我的订单 30 | export const orders = (data) => { 31 | let req = { 32 | data, 33 | url: 'v1/orders?time='+new Date() 34 | } 35 | return _get(req); 36 | } 37 | 38 | //订单评论 39 | export const makeComment = (data) => { 40 | let req = { 41 | data, 42 | url: 'v1/comment' 43 | } 44 | return _post(req) 45 | } 46 | 47 | 48 | //请求支付 49 | export const requestPay = (data) => { 50 | let req = { 51 | data, 52 | url: '/https://pay.ispay.cn/core/api/request/pay/' 53 | } 54 | return _post(req) 55 | } 56 | 57 | //监听扫码支付状态 58 | export const listenStatus = (data) => { 59 | let req = { 60 | data, 61 | url: 'v1/listen_status' 62 | } 63 | return _get(req) 64 | } 65 | 66 | -------------------------------------------------------------------------------- /vue-meituan-master/src/api/request.js: -------------------------------------------------------------------------------- 1 | import {_get, _post, _put} from './index' 2 | 3 | export const sendLogin = (data) => { 4 | let req = { 5 | data 6 | }; 7 | req.url = 'admin/login' 8 | return _post(req); 9 | } 10 | //获取某个商家具体信息 11 | export const getRestaurant = (data) => { 12 | let req = { 13 | data 14 | }; 15 | req.url = 'v1/restaurant' 16 | return _get(req); 17 | } 18 | //获取一定数量的商家 19 | export const getRestaurants = (data) => { 20 | let req = { 21 | data 22 | }; 23 | req.url = 'v1/restaurants' 24 | return _get(req); 25 | } 26 | 27 | //新增收货地址 28 | export const addAddress = (data) => { 29 | let req = { 30 | data 31 | }; 32 | req.url = 'admin/address' 33 | return _post(req); 34 | }; 35 | 36 | //获取收货地址 37 | export const getAddress = (data) => { 38 | let req = {data}; 39 | req.url = 'admin/address' 40 | return _get(req); 41 | }; 42 | 43 | //添加进购物车 44 | export const addShoppingCart = (data) => { 45 | let req = { 46 | data 47 | }; 48 | req.url = 'v1/cart' 49 | return _post(req); 50 | } 51 | 52 | //从购物车减少商品数量 53 | export const reduceShoppingCart = (data) => { 54 | let req = { 55 | data 56 | }; 57 | req.url = 'v1/cart' 58 | return _put(req); 59 | } 60 | 61 | //获取订单 62 | export const getOrder = (data) => { 63 | let req = { 64 | data 65 | }; 66 | req.url = 'v1/order' 67 | return _get(req); 68 | } 69 | -------------------------------------------------------------------------------- /vue-meituan-master/src/api/restaurant.js: -------------------------------------------------------------------------------- 1 | import {_get, _put} from './index' 2 | 3 | //获取一定数量的商家 4 | export const getRestaurants = (data) => { 5 | let req = { 6 | data: data, 7 | url: 'v1/restaurants' 8 | }; 9 | return _get(req); 10 | } 11 | 12 | 13 | //获取某个商家具体信息 14 | export const getRestaurant = (data) => { 15 | let req = { 16 | url: `v1/restaurant/${data.restaurant_id}` 17 | }; 18 | return _get(req); 19 | } 20 | 21 | //获取食物 22 | export const getFoods = (data) => { 23 | let req = { 24 | url: `v1/food/${data.restaurant_id}` 25 | }; 26 | return _get(req); 27 | } 28 | 29 | //从购物车减少商品数量 30 | export const reduceShoppingCart = (data) => { 31 | let req = { 32 | data, 33 | url: 'v1/cart' 34 | }; 35 | return _put(req); 36 | } 37 | 38 | //输入关键词搜索餐馆 39 | export const searchRestaurant = (data) => { 40 | let req = { 41 | data, 42 | url: 'v1/search/restaurant' 43 | } 44 | return _get(req); 45 | } 46 | 47 | //获取评论 48 | export const restaurantComment = (data) => { 49 | let req = { 50 | data, 51 | url: 'v1/comment' 52 | }; 53 | return _get(req); 54 | } 55 | 56 | -------------------------------------------------------------------------------- /vue-meituan-master/src/api/upload.js: -------------------------------------------------------------------------------- 1 | import {_get, _postNoWithCredentials} from './index' 2 | //获取七牛云上次凭证 3 | export const uploadToken = (data) => { 4 | let req = { 5 | data, 6 | url: 'service/uploadtoken' 7 | }; 8 | return _get(req); 9 | } 10 | 11 | //上传 12 | export const upload = (data) => { 13 | let formData = new FormData(); 14 | Object.keys(data).forEach(key => { 15 | formData.append(key, data[key]) 16 | }) 17 | let req = { 18 | data: formData, 19 | url: '/upload-z2.qiniup.com/' 20 | } 21 | return _postNoWithCredentials(req); 22 | } 23 | -------------------------------------------------------------------------------- /vue-meituan-master/src/api/user.js: -------------------------------------------------------------------------------- 1 | import {_get, _post, _delete} from './index' 2 | 3 | //获取用户所有地址 4 | export const getAllAddress = (data) => { 5 | let req = { 6 | data, 7 | url: 'admin/all_address?time='+new Date() 8 | }; 9 | return _get(req); 10 | } 11 | 12 | //获取指定收货地址 13 | export const getAddress = (data) => { 14 | let req = { 15 | data, 16 | url: 'admin/address' 17 | } 18 | return _get(req) 19 | } 20 | 21 | //添加收获地址 22 | export const add_address = (data) => { 23 | let req = { 24 | data, 25 | url: 'admin/address' 26 | } 27 | return _post(req); 28 | } 29 | 30 | export const updateAddress = (data) =>{ 31 | let req = { 32 | data, 33 | url: 'admin/update_address' 34 | } 35 | return _post(req) 36 | } 37 | 38 | //删除收货地址 39 | export const deleteAddress = (data) => { 40 | let req = { 41 | data, 42 | url: 'admin/address' 43 | } 44 | return _delete(req) 45 | } 46 | 47 | //登录 48 | export const login = (data) => { 49 | let req = { 50 | data, 51 | url: 'admin/user_login' 52 | } 53 | return _post(req); 54 | } 55 | 56 | //获取用户信息 57 | export const userInfo = (data) => { 58 | let req = { 59 | data, 60 | url: 'admin/user_info' 61 | } 62 | return _get(req); 63 | } 64 | 65 | //改变用户头像 66 | export const changeAvatar = (data) => { 67 | let req = { 68 | data, 69 | url: 'admin/change_avatar' 70 | } 71 | return _post(req) 72 | } 73 | 74 | //获取我的评论 75 | export const comment = (data) => { 76 | let req = { 77 | data, 78 | url: 'v1/my_comment' 79 | } 80 | return _get(req); 81 | } 82 | 83 | export const deleteComment = (data) => { 84 | let req = { 85 | data, 86 | url: 'v1/comment' 87 | } 88 | return _delete(req); 89 | } 90 | 91 | -------------------------------------------------------------------------------- /vue-meituan-master/src/assets/default-avatar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunying128/Vue/92a843d2c4dab4167610404b2ca52fae80790ced/vue-meituan-master/src/assets/default-avatar.png -------------------------------------------------------------------------------- /vue-meituan-master/src/assets/friend_img.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunying128/Vue/92a843d2c4dab4167610404b2ca52fae80790ced/vue-meituan-master/src/assets/friend_img.png -------------------------------------------------------------------------------- /vue-meituan-master/src/assets/home-active.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunying128/Vue/92a843d2c4dab4167610404b2ca52fae80790ced/vue-meituan-master/src/assets/home-active.png -------------------------------------------------------------------------------- /vue-meituan-master/src/assets/home.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunying128/Vue/92a843d2c4dab4167610404b2ca52fae80790ced/vue-meituan-master/src/assets/home.png -------------------------------------------------------------------------------- /vue-meituan-master/src/assets/index-active.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunying128/Vue/92a843d2c4dab4167610404b2ca52fae80790ced/vue-meituan-master/src/assets/index-active.png -------------------------------------------------------------------------------- /vue-meituan-master/src/assets/index.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunying128/Vue/92a843d2c4dab4167610404b2ca52fae80790ced/vue-meituan-master/src/assets/index.png -------------------------------------------------------------------------------- /vue-meituan-master/src/assets/loading.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunying128/Vue/92a843d2c4dab4167610404b2ca52fae80790ced/vue-meituan-master/src/assets/loading.gif -------------------------------------------------------------------------------- /vue-meituan-master/src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunying128/Vue/92a843d2c4dab4167610404b2ca52fae80790ced/vue-meituan-master/src/assets/logo.png -------------------------------------------------------------------------------- /vue-meituan-master/src/assets/my.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunying128/Vue/92a843d2c4dab4167610404b2ca52fae80790ced/vue-meituan-master/src/assets/my.png -------------------------------------------------------------------------------- /vue-meituan-master/src/assets/nothing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunying128/Vue/92a843d2c4dab4167610404b2ca52fae80790ced/vue-meituan-master/src/assets/nothing.png -------------------------------------------------------------------------------- /vue-meituan-master/src/assets/order-active.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunying128/Vue/92a843d2c4dab4167610404b2ca52fae80790ced/vue-meituan-master/src/assets/order-active.png -------------------------------------------------------------------------------- /vue-meituan-master/src/assets/order.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunying128/Vue/92a843d2c4dab4167610404b2ca52fae80790ced/vue-meituan-master/src/assets/order.png -------------------------------------------------------------------------------- /vue-meituan-master/src/assets/pay_adv.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunying128/Vue/92a843d2c4dab4167610404b2ca52fae80790ced/vue-meituan-master/src/assets/pay_adv.png -------------------------------------------------------------------------------- /vue-meituan-master/src/assets/restaurant.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunying128/Vue/92a843d2c4dab4167610404b2ca52fae80790ced/vue-meituan-master/src/assets/restaurant.jpg -------------------------------------------------------------------------------- /vue-meituan-master/src/assets/shoploading.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunying128/Vue/92a843d2c4dab4167610404b2ca52fae80790ced/vue-meituan-master/src/assets/shoploading.png -------------------------------------------------------------------------------- /vue-meituan-master/src/assets/skeleton_restaurant.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunying128/Vue/92a843d2c4dab4167610404b2ca52fae80790ced/vue-meituan-master/src/assets/skeleton_restaurant.jpg -------------------------------------------------------------------------------- /vue-meituan-master/src/assets/star24_half@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunying128/Vue/92a843d2c4dab4167610404b2ca52fae80790ced/vue-meituan-master/src/assets/star24_half@2x.png -------------------------------------------------------------------------------- /vue-meituan-master/src/assets/star24_off@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunying128/Vue/92a843d2c4dab4167610404b2ca52fae80790ced/vue-meituan-master/src/assets/star24_off@2x.png -------------------------------------------------------------------------------- /vue-meituan-master/src/assets/star24_on@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunying128/Vue/92a843d2c4dab4167610404b2ca52fae80790ced/vue-meituan-master/src/assets/star24_on@2x.png -------------------------------------------------------------------------------- /vue-meituan-master/src/assets/user-banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunying128/Vue/92a843d2c4dab4167610404b2ca52fae80790ced/vue-meituan-master/src/assets/user-banner.png -------------------------------------------------------------------------------- /vue-meituan-master/src/assets/我的收藏.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunying128/Vue/92a843d2c4dab4167610404b2ca52fae80790ced/vue-meituan-master/src/assets/我的收藏.jpg -------------------------------------------------------------------------------- /vue-meituan-master/src/components/addressInfo.vue: -------------------------------------------------------------------------------- 1 | 49 | 50 | 66 | 67 | 155 | -------------------------------------------------------------------------------- /vue-meituan-master/src/components/alertTip.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 19 | 20 | 59 | -------------------------------------------------------------------------------- /vue-meituan-master/src/components/bottom.vue: -------------------------------------------------------------------------------- 1 | 2 | 32 | 33 | 45 | 46 | 81 | -------------------------------------------------------------------------------- /vue-meituan-master/src/components/head.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 48 | 49 | 78 | -------------------------------------------------------------------------------- /vue-meituan-master/src/components/littleCart.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 25 | 26 | 56 | -------------------------------------------------------------------------------- /vue-meituan-master/src/components/loading.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 9 | 10 | 29 | -------------------------------------------------------------------------------- /vue-meituan-master/src/components/search.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 33 | 34 | 79 | -------------------------------------------------------------------------------- /vue-meituan-master/src/components/selector.vue: -------------------------------------------------------------------------------- 1 | 12 | 50 | 51 | 95 | -------------------------------------------------------------------------------- /vue-meituan-master/src/components/star.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 30 | 31 | 56 | -------------------------------------------------------------------------------- /vue-meituan-master/src/config.js: -------------------------------------------------------------------------------- 1 | export default { 2 | baseURL: 'http://106.54.72.62:3000', //后端地址 3 | // baseURL: 'http://127.0.0.1:3000', 4 | domain: 'http://q15hna1jf.bkt.clouddn.com/', //七牛云存储地址 5 | } -------------------------------------------------------------------------------- /vue-meituan-master/src/main.js: -------------------------------------------------------------------------------- 1 | // The Vue build version to load with the `import` command 2 | // (runtime-only or standalone) has been set in webpack.base.conf with an alias. 3 | import Vue from 'vue' 4 | import App from './App' 5 | import router from './router' 6 | import store from './stores' 7 | 8 | import Head from '@/components/head' 9 | import Bottom from '@/components/bottom' 10 | import Star from '@/components/star' 11 | import AlertTip from '@/components/alertTip' 12 | import Loading from '@/components/loading' 13 | import FastClick from 'fastclick' 14 | 15 | //全局注册组件 16 | Vue.component('v-head', Head); 17 | Vue.component('v-bottom', Bottom); 18 | Vue.component('v-star', Star); 19 | Vue.component('alert-tip', AlertTip); 20 | Vue.component('v-loading',Loading); 21 | 22 | Vue.config.productionTip = false 23 | 24 | if ('addEventListener' in document) { 25 | document.addEventListener('DOMContentLoaded', function() { 26 | FastClick.attach(document.body); 27 | }, false); 28 | } 29 | 30 | 31 | /* eslint-disable no-new */ 32 | new Vue({ 33 | router, 34 | store, 35 | render: h => h(App), 36 | }).$mount('#app') 37 | -------------------------------------------------------------------------------- /vue-meituan-master/src/router/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Router from 'vue-router' 3 | 4 | Vue.use(Router) 5 | 6 | export default new Router({ 7 | routes: [ 8 | { 9 | path: '/', 10 | redirect: '/index' 11 | }, 12 | { 13 | path: '/index', 14 | name: '首页', 15 | component: r => require.ensure([], () => r(require('@/views/Index/Index')), 'Index'), 16 | meta: {keepAlive: true}, 17 | }, 18 | { 19 | path: '/category', 20 | name: '分类', 21 | component: r => require.ensure([], () => r(require('@/views/category/category'), 'CATEGORY')) 22 | }, 23 | { 24 | path: '/order', 25 | name: '我的订单', 26 | component: r => require.ensure([], () => r(require('@/views/order/order'), 'Order')), 27 | children: [ 28 | { 29 | path: 'comment', 30 | name: '作评价', 31 | component: r => require.ensure([], () => r(require('@/views/order/comment'), 'MakeComment')) 32 | } 33 | ] 34 | }, 35 | { 36 | path: '/search', 37 | name: '搜索商家', 38 | component: r => require.ensure([], () => r(require('@/views/search/search')), 'Search') 39 | }, 40 | { 41 | path: '/location', 42 | name: '定位', 43 | component: r => require.ensure([], () => r(require('@/views/location/location'), 'Location')) 44 | }, 45 | { 46 | path: '/add_address', 47 | name: '添加地址', 48 | component: r => require.ensure([], () => r(require('@/views/confirm_order/children/children/add_address'), 'Add_Address')), 49 | children: [ 50 | { 51 | path: 'location', 52 | name: '地址定位', 53 | component: r => require.ensure([], () => r(require('@/views/location/location'), 'Location')) 54 | } 55 | ] 56 | }, 57 | { 58 | path: '/home', 59 | name: '我的', 60 | component: r => require.ensure([], () => r(require('@/views/home/home'), 'Home')), 61 | keepAlive: true, 62 | children: [ 63 | { 64 | path: 'address', 65 | name: '我的收获地址', 66 | component: r => require.ensure([], () => r(require('@/views/home/children/address'), 'MyAddress')) 67 | }, 68 | { 69 | path: 'collection', 70 | name: '我的收藏', 71 | component: r => require.ensure([], () => r(require('@/views/home/children/collection'), 'Collection')) 72 | }, 73 | { 74 | path: 'thank', 75 | name: '答谢记录', 76 | component: r => require.ensure([], () => r(require('@/views/home/children/thank_record'), 'ThankRecord')) 77 | }, 78 | { 79 | path: 'footprint', 80 | name: '我的足迹', 81 | component: r => require.ensure([], () => r(require('@/views/home/children/footprint'), 'FootPrint')) 82 | }, 83 | { 84 | path: 'friend', 85 | name: '我的好友', 86 | component: r => require.ensure([], () => r(require('@/views/home/children/friend'), 'Friend')) 87 | }, 88 | { 89 | path: 'comment', 90 | name: '我的评论', 91 | component: r => require.ensure([], () => r(require('@/views/home/children/comment'), 'MyComment')) 92 | } 93 | ] 94 | }, 95 | { 96 | path: '/login', 97 | name: '登录', 98 | component: r => require.ensure([], () => r(require('@/views/login/login'), 'Login')) 99 | }, 100 | { 101 | path: '/confirm_order', 102 | name: '确认订单', 103 | component: r => require.ensure([], () => r(require('@/views/confirm_order/confirm_order'), 'ConfirmOrder')), 104 | children: [{ 105 | path: 'address', 106 | name: '订单收货地址', 107 | component: r => require.ensure([], () => r(require('@/views/confirm_order/children/address'), 'Address')) 108 | }] 109 | }, 110 | { 111 | path: '/store', 112 | component: r => require.ensure([], () => r(require('@/views/store/store'), 'Store')), 113 | children: [ 114 | { 115 | path: 'menu', 116 | name: '菜单', 117 | component: r => require.ensure([], () => r(require('@/views/store/menu/menu'), 'Menu')) 118 | }, 119 | { 120 | path: 'comment', 121 | name: '评论', 122 | component: r => require.ensure([], () => r(require('@/views/store/comment/comment'), 'Comment')) 123 | }, 124 | { 125 | path: 'seller', 126 | name: '商家信息中心', 127 | component: r => require.ensure([], () => r(require('@/views/store/seller/seller'), 'Seller')) 128 | }, 129 | { 130 | path: '', 131 | redirect: '/store/menu' 132 | } 133 | ] 134 | }, 135 | { 136 | path: '/cart', 137 | name: '购物车', 138 | component: r => require.ensure([], () => r(require('@/views/cart/cart'), 'CART')) 139 | }, 140 | { 141 | path: '/pay', 142 | name: '支付', 143 | component: r => require.ensure([], () => r(require('@/views/pay/pay'), 'PAY')) 144 | }, 145 | { 146 | path: '/order_detail', 147 | name: '订单详情', 148 | component: r => require.ensure([], () => r(require('@/views/order/order_detail'), 'OrderDetail')) 149 | }, 150 | { 151 | path: '/error', 152 | name: '找不到该页面', 153 | component: r => require.ensure([], () => r(require('@/views/404/error'), 'Error')) 154 | }, 155 | { 156 | path: '*', 157 | redirect: '/error' 158 | } 159 | ] 160 | }) 161 | -------------------------------------------------------------------------------- /vue-meituan-master/src/stores/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Vuex from 'vuex' 3 | Vue.use(Vuex) 4 | import cart from './modules/cart' 5 | import address from './modules/address' 6 | import restaurant from './modules/restaurant' 7 | 8 | export default new Vuex.Store({ 9 | modules: { 10 | cart, 11 | address, 12 | restaurant 13 | } 14 | }) 15 | -------------------------------------------------------------------------------- /vue-meituan-master/src/stores/modules/address.js: -------------------------------------------------------------------------------- 1 | import * as types from '../mutation-types' 2 | import {location} from '@/api/location' 3 | 4 | const state = { 5 | lat: '', // 当前位置纬度 6 | lng: '', // 当前位置经度 7 | address: { 8 | address: '定位中...', 9 | lat: '', 10 | lng: '', 11 | }, 12 | locationReady: false, //定位是否完成 13 | deliveryAddress: {} 14 | }; 15 | 16 | const getters = { 17 | address: state => state.address, 18 | locationReady: state => state.locationReady, 19 | deliveryAddress: state => state.deliveryAddress 20 | }; 21 | 22 | const actions = { 23 | clearAddress({commit}) { 24 | commit(types.CLEAR_ADDRESS); 25 | }, 26 | location({commit}) { 27 | location().then((response) => { 28 | if (response.data.status === 200) { 29 | let data = response.data.data; 30 | commit(types.RECORD_ADDRESS, {address: data.address, ...data.location}); //保存title 和 经纬度到VUEX中 31 | commit(types.LOCATION_READY, true); //定位完成 拉取商店 32 | } 33 | }) 34 | }, 35 | recordAddress({commit}, address) { 36 | commit(types.RECORD_ADDRESS, address); //保存title 和 经纬度到VUEX中 37 | commit(types.LOCATION_READY, true); //定位完成 拉取商店 38 | }, 39 | locationReady({commit}, boolean) { 40 | commit(types.LOCATION_READY, boolean); //定位完成 拉取商店 41 | }, 42 | recodeDeliveryAddress({commit}, address) { 43 | commit(types.RECORD_DELIVERY_ADDRESS, address); //定位完成 拉取商店 44 | }, 45 | failLocation({commit}) { //定位失败 46 | commit(types.FAIL_LOCATION); 47 | } 48 | }; 49 | 50 | const mutations = { 51 | [types.CLEAR_ADDRESS](state) { 52 | let address = {address: '定位中...', lat: '', lng: ''}; 53 | state.address = {...address}; 54 | }, 55 | [types.RECORD_ADDRESS](state, address) { 56 | state.address = {...address} 57 | }, 58 | //定位完成拉取附近餐馆 59 | [types.LOCATION_READY](state, boolean) { 60 | state.locationReady = boolean; 61 | }, 62 | [types.RECORD_DELIVERY_ADDRESS](state, address) { 63 | state.deliveryAddress = {...address}; 64 | }, 65 | [types.FAIL_LOCATION](state) { 66 | let address = {address: '定位失败...', lat: '', lng: ''} 67 | state.address = {...address}; 68 | } 69 | }; 70 | 71 | export default { 72 | state, 73 | getters, 74 | actions, 75 | mutations 76 | } 77 | -------------------------------------------------------------------------------- /vue-meituan-master/src/stores/modules/cart.js: -------------------------------------------------------------------------------- 1 | import * as types from '../mutation-types' 2 | 3 | 4 | const state = { 5 | cartList: {}, //加入购物车列表 6 | ballInCart: false 7 | } 8 | 9 | //getters 10 | const getters = { 11 | cartList: state => state.cartList, 12 | ballInCart: state => state.ballInCart 13 | } 14 | 15 | //actions 16 | const actions = { 17 | addCart({commit}, {restaurant_id, restaurant_name, pic_url, food_id, price, name, foods_pic}) { 18 | commit('ADD_CART', {restaurant_id, restaurant_name, pic_url, food_id, price, name, foods_pic}) 19 | }, 20 | reduceCart({commit}, {restaurant_id, food_id}) { 21 | commit('REDUCE_CART', {restaurant_id, food_id}) 22 | }, 23 | deleteFood({commit}, {restaurant_id, food_id}) { 24 | commit('DELETE_CART', {restaurant_id, food_id}) 25 | }, 26 | emptyCart({commit}, {restaurant_id}) { 27 | commit('EMPTY_CART', {restaurant_id}); 28 | }, 29 | ballInCart({commit}, boolean) { 30 | commit(types.BALL_IN_CART, boolean); 31 | }, 32 | updateCart({commit}, {cartList}) { 33 | commit(types.UPDATE_CART, {cartList}); 34 | } 35 | } 36 | 37 | //mutations 38 | const mutations = { 39 | [types.ADD_CART](state, {restaurant_id, restaurant_name, pic_url, food_id, price, name, foods_pic}) { 40 | let cart = state.cartList; 41 | let restaurant; 42 | if (!cart[restaurant_id]) { //如果该商店还没有添加任何商品 进行初始化 43 | restaurant = cart[restaurant_id] = { 44 | totalPrice: 0, //总价格 45 | totalNum: 0, //总数量 46 | restaurant_name, //餐馆名 47 | pic_url //餐馆图片 48 | }; 49 | } else { 50 | restaurant = cart[restaurant_id]; 51 | } 52 | restaurant.totalPrice = (Number(restaurant.totalPrice) + Number(price)).toFixed(2); //计算总价格 53 | restaurant.totalNum++; //数量加一 54 | if (restaurant[food_id]) { //如果该食物已经在保存了 数量加1 55 | restaurant[food_id].num++; 56 | } else { 57 | restaurant[food_id] = { //初始化该食物 58 | name, 59 | price, 60 | foods_pic, 61 | num: 1, 62 | id: food_id, 63 | } 64 | } 65 | //触发更新 66 | state.cartList = {...cart} 67 | localStorage.setItem('cartList', JSON.stringify(state.cartList)); 68 | }, 69 | //减购物车 70 | [types.REDUCE_CART](state, {restaurant_id, food_id}) { 71 | let cart = state.cartList; 72 | let restaurant = cart[restaurant_id]; 73 | //修改购物车总价格 74 | restaurant.totalPrice = Number((restaurant.totalPrice - restaurant[food_id].price).toFixed(2)); 75 | restaurant.totalNum--; 76 | if (restaurant.totalNum === 0) { 77 | delete(cart[restaurant_id]); 78 | } else if (restaurant[food_id].num === 1) { 79 | delete(restaurant[food_id]); 80 | } else { 81 | restaurant[food_id].num--; 82 | } 83 | state.cartList = {...cart}; 84 | localStorage.setItem('cartList', JSON.stringify(state.cartList)); 85 | }, 86 | //删除食物 87 | [types.DELETE_CART](state, {restaurant_id, food_id}) { 88 | let cart = state.cartList; 89 | let restaurant = cart[restaurant_id]; 90 | let num = restaurant[food_id].num; 91 | let price = restaurant[food_id].price; 92 | restaurant.totalNum -= num; 93 | delete(restaurant[food_id]); 94 | if (restaurant.totalNum === 0) { 95 | delete(cart[restaurant_id]); 96 | } else { 97 | restaurant.totalPrice = Number((restaurant.totalPrice - price * num).toFixed(2)); //修改价格 98 | } 99 | state.cartList = {...cart}; 100 | localStorage.setItem('cartList', JSON.stringify(state.cartList)); 101 | }, 102 | //更新购物车记录 103 | [types.UPDATE_CART](state, {cartList}) { 104 | state.cartList = {...cartList}; 105 | }, 106 | //清空购物车 107 | [types.EMPTY_CART](state, {restaurant_id}) { 108 | let cart = state.cartList; 109 | delete cart[restaurant_id]; 110 | state.cartList = {...cart}; 111 | localStorage.setItem('cartList', JSON.stringify(state.cartList)); 112 | }, 113 | //小球进入购物车 114 | [types.BALL_IN_CART](state, boolean) { 115 | state.ballInCart = boolean; 116 | } 117 | } 118 | 119 | export default { 120 | state, 121 | getters, 122 | actions, 123 | mutations 124 | } 125 | -------------------------------------------------------------------------------- /vue-meituan-master/src/stores/modules/restaurant.js: -------------------------------------------------------------------------------- 1 | import * as types from '../mutation-types' 2 | 3 | import {getRestaurant} from '@/api/restaurant' 4 | 5 | const state = { 6 | poi_info: {}, 7 | restaurant_info: {}, //商店的信息 包括 售卖的食物 8 | }; 9 | 10 | //getters 11 | const getters = { 12 | restaurant_info: state => state.restaurant_info, 13 | poi_info: state => state.poi_info 14 | }; 15 | 16 | //actions 17 | const actions = { 18 | getRestaurant({commit}, restaurant_id) { 19 | getRestaurant({restaurant_id}).then((response) => { 20 | let poi_info = response.data.data; 21 | commit('RECORD_RESTAURANT', poi_info) 22 | }) 23 | } 24 | }; 25 | 26 | //mutations 27 | const mutations = { 28 | //记录当前商店的信息 29 | [types.RECORD_RESTAURANT](state, poi_info) { 30 | state.poi_info = {...poi_info} 31 | }, 32 | }; 33 | 34 | export default { 35 | state, 36 | getters, 37 | actions, 38 | mutations 39 | } 40 | -------------------------------------------------------------------------------- /vue-meituan-master/src/stores/mutation-types.js: -------------------------------------------------------------------------------- 1 | export const ADD_CART = 'ADD_CART' //加入购物车 2 | export const EMPTY_CART = 'EMPTY_CART' //清空购物车 3 | export const BALL_IN_CART = 'BALL_IN_CART' //小球进入购物车 4 | export const RECORD_ADDRESS = 'RECORD_ADDRESS' 5 | export const CLEAR_ADDRESS = 'CLEAR_ADDRESS' //重新定位时 清空原来定位信息 6 | export const FAIL_LOCATION = 'FAIL_LOCATION' //定位失败 7 | export const RECORD_SUGGESTION = 'RECORD_SUGGESTION' 8 | export const REDUCE_CART = 'REDUCE_CART' //减少购物车 9 | export const RECORD_DELIVERY_ADDRESS = 'RECORD_DELIVERY_ADDRESS' //配送地址 10 | export const RECORD_RESTAURANT = 'RECORD_RESTAURANT' 11 | export const UPDATE_CART = 'UPDATE_CART' //页面刷新时 更新购物车信息 12 | export const LOCATION_READY = 'LOCATION_READY' // 拉取餐馆信息 13 | export const DELETE_CART = 'DELETE_CART' //删除购物车某种食物 14 | export const SAVE_PATH = 'SAVE_PATH' //保存路由路径 15 | export const RESET_PATH = 'RESET_PATH' //重置路径 16 | 17 | -------------------------------------------------------------------------------- /vue-meituan-master/src/style/common.scss: -------------------------------------------------------------------------------- 1 | body, div, span, header, footer, nav, section, aside, article, ul, dl, dt, dd, li, a, p, h1, h2, h3, h4,h5, h6, i, b, textarea, button, input, select, figure, figcaption{ 2 | padding: 0; 3 | margin: 0; 4 | list-style: none; 5 | font-style: normal; 6 | text-decoration: none; 7 | border: none; 8 | font-weight: normal; 9 | box-sizing: border-box; 10 | -webkit-tap-highlight-color:transparent; 11 | -webkit-font-smoothing: antialiased; 12 | &:hover{ 13 | outline: none; 14 | } 15 | } 16 | a{ 17 | color:#333; 18 | } 19 | html,body{ 20 | width: 100%; 21 | height:100%; 22 | line-height:1; 23 | } 24 | //iconfont 25 | @font-face { 26 | font-family: 'iconfont'; /* project id 407663 */ 27 | src: url('//at.alicdn.com/t/font_407663_9ufqp98dcmw5qaor.eot'); 28 | src: url('//at.alicdn.com/t/font_407663_9ufqp98dcmw5qaor.eot?#iefix') format('embedded-opentype'), 29 | url('//at.alicdn.com/t/font_407663_9ufqp98dcmw5qaor.woff') format('woff'), 30 | url('//at.alicdn.com/t/font_407663_9ufqp98dcmw5qaor.ttf') format('truetype'), 31 | url('//at.alicdn.com/t/font_407663_9ufqp98dcmw5qaor.svg#iconfont') format('svg'); 32 | } 33 | @mixin clearfix{ 34 | &:after{ 35 | content:""; 36 | display:table; 37 | clear:both; 38 | } 39 | } 40 | 41 | .swiper-pagination-bullet-active{ 42 | background: rgb(248,203,57) !important; 43 | } 44 | .swiper-pagination-bullet{ 45 | border-radius:0 ; 46 | } 47 | 48 | .iconfont{ 49 | font-style:normal; 50 | font-family: iconfont; 51 | } 52 | 53 | //自动填写密码出现的黄色背景 54 | input:-webkit-autofill { 55 | -webkit-box-shadow: 0 0 0 1000px white inset !important; 56 | } 57 | //focus产生黄色边框 58 | input:focus{ outline:none; } 59 | -------------------------------------------------------------------------------- /vue-meituan-master/src/style/mixin.scss: -------------------------------------------------------------------------------- 1 | $mtYellow: #ffd161; 2 | $bottomLine: rgb(228, 228, 228); 3 | $mtGrey: rgb(214, 214, 214); 4 | 5 | $baseFontSize: 75; //基于视觉稿横屏尺寸/100得出的基准font-size 6 | @mixin px2rem($name, $px) { //用sass计算从px到rem的转换 7 | #{$name}: $px / $baseFontSize * 1rem; 8 | } 9 | 10 | @mixin loading { 11 | /*loading部分*/ 12 | background: #fff; 13 | text-align: center; 14 | font-size: 14px; 15 | height: 26px; 16 | line-height: 26px; 17 | .loading:before { 18 | content: ""; 19 | display: inline-block; 20 | position: relative; 21 | left: -11px; 22 | padding: 0; 23 | border: 0; 24 | background: 0; 25 | width: 2px; 26 | height: 2px; 27 | border-radius: 100%; 28 | box-shadow: 0 -7px 0 0.9px #666, 7px 0 #999, 0 7px #999, -7px 0 #999, -5px -5px 0 0.4px #999, 5px -5px 0 1.1px #666, 5px 5px #999, -5px 5px #999; 29 | animation: spin 1.5s linear infinite; 30 | -webkit-animation: spin 1.5s linear infinite; 31 | top: -4px; 32 | } 33 | @keyframes spin { 34 | from { 35 | transform: rotate(0deg) 36 | } 37 | to { 38 | transform: rotate(360deg) 39 | } 40 | } 41 | } 42 | 43 | @mixin ellipsis{ 44 | overflow: hidden; 45 | text-overflow:ellipsis; 46 | white-space: nowrap; 47 | } 48 | -------------------------------------------------------------------------------- /vue-meituan-master/src/utils/auth.js: -------------------------------------------------------------------------------- 1 | const userInfo = 'mt-username' 2 | 3 | export function getInfo() { 4 | return localStorage.getItem(userInfo) 5 | } 6 | 7 | export function setInfo(username) { 8 | return localStorage.setItem(userInfo, username) 9 | } 10 | 11 | export function removeInfo() { 12 | return localStorage.removeItem(userInfo) 13 | } 14 | 15 | -------------------------------------------------------------------------------- /vue-meituan-master/src/views/404/error.vue: -------------------------------------------------------------------------------- 1 | 12 | 63 | -------------------------------------------------------------------------------- /vue-meituan-master/src/views/Index/Index.vue: -------------------------------------------------------------------------------- 1 | 2 | 34 | 35 | 71 | 72 | 152 | -------------------------------------------------------------------------------- /vue-meituan-master/src/views/Index/nav.vue: -------------------------------------------------------------------------------- 1 | 2 | 20 | 21 | 105 | 106 | 171 | -------------------------------------------------------------------------------- /vue-meituan-master/src/views/category/category.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 30 | 31 | 37 | -------------------------------------------------------------------------------- /vue-meituan-master/src/views/confirm_order/children/address.vue: -------------------------------------------------------------------------------- 1 | 2 | 25 | 26 | 60 | 61 | 132 | -------------------------------------------------------------------------------- /vue-meituan-master/src/views/confirm_order/children/children/add_address.vue: -------------------------------------------------------------------------------- 1 | 2 | 14 | 15 | 78 | 79 | 98 | -------------------------------------------------------------------------------- /vue-meituan-master/src/views/home/children/address.vue: -------------------------------------------------------------------------------- 1 | 2 | 30 | 31 | 67 | 68 | 151 | -------------------------------------------------------------------------------- /vue-meituan-master/src/views/home/children/collection.vue: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 37 | -------------------------------------------------------------------------------- /vue-meituan-master/src/views/home/children/comment.vue: -------------------------------------------------------------------------------- 1 | 2 | 56 | 57 | 99 | 100 | 228 | -------------------------------------------------------------------------------- /vue-meituan-master/src/views/home/children/footprint.vue: -------------------------------------------------------------------------------- 1 | 2 | 12 | 13 | 43 | -------------------------------------------------------------------------------- /vue-meituan-master/src/views/home/children/friend.vue: -------------------------------------------------------------------------------- 1 | 2 | 26 | 27 | 36 | 37 | 122 | -------------------------------------------------------------------------------- /vue-meituan-master/src/views/home/children/thank_record.vue: -------------------------------------------------------------------------------- 1 | 2 | 12 | 13 | 15 | 16 | 46 | -------------------------------------------------------------------------------- /vue-meituan-master/src/views/home/home.vue: -------------------------------------------------------------------------------- 1 | 2 | 51 | 52 | 196 | 197 | 296 | -------------------------------------------------------------------------------- /vue-meituan-master/src/views/location/location.vue: -------------------------------------------------------------------------------- 1 | 2 | 21 | 22 | 67 | 68 | 117 | -------------------------------------------------------------------------------- /vue-meituan-master/src/views/login/login.vue: -------------------------------------------------------------------------------- 1 | 2 | 35 | 36 | 80 | 81 | 150 | -------------------------------------------------------------------------------- /vue-meituan-master/src/views/order/order.vue: -------------------------------------------------------------------------------- 1 | 2 | 53 | 54 | 83 | 84 | 219 | -------------------------------------------------------------------------------- /vue-meituan-master/src/views/order/star.vue: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 24 | 25 | 46 | -------------------------------------------------------------------------------- /vue-meituan-master/src/views/pay/scan.vue: -------------------------------------------------------------------------------- 1 | 2 | 26 | 27 | 93 | 94 | 138 | -------------------------------------------------------------------------------- /vue-meituan-master/src/views/search/search.vue: -------------------------------------------------------------------------------- 1 | 2 | 22 | 23 | 65 | 66 | 100 | -------------------------------------------------------------------------------- /vue-meituan-master/src/views/store/menu/menu.vue: -------------------------------------------------------------------------------- 1 | 2 | 48 | 49 | 151 | 152 | 261 | -------------------------------------------------------------------------------- /vue-meituan-master/src/views/store/seller/seller.vue: -------------------------------------------------------------------------------- 1 | 2 | 51 | 52 | 66 | 67 | 146 | -------------------------------------------------------------------------------- /vue-meituan-master/src/views/store/store.vue: -------------------------------------------------------------------------------- 1 | 2 | 61 | 62 | 102 | 103 | 248 | -------------------------------------------------------------------------------- /vue-meituan-master/src/views/store/store_detail.vue: -------------------------------------------------------------------------------- 1 | 2 | 35 | 36 | 54 | 55 | 153 | -------------------------------------------------------------------------------- /vue-meituan-master/vue.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | 3 | function resolve(dir) { 4 | return path.join(__dirname, dir); 5 | } 6 | module.exports = { 7 | lintOnSave: true, 8 | chainWebpack: (config) => { 9 | config.resolve.alias 10 | .set('@', resolve('src')) 11 | .set('@assets',resolve('src/assets')) 12 | }, 13 | }; 14 | --------------------------------------------------------------------------------