Selaa lähdekoodia

食品模型增加sub doc

maguohua 8 vuotta sitten
vanhempi
sitoutus
0d1984a224
4 muutettua tiedostoa jossa 323 lisäystä ja 132 poistoa
  1. 252 72
      controller/shopping/food.js
  2. 7 6
      controller/shopping/shop.js
  3. 57 52
      models/shopping/food.js
  4. 7 2
      routes/shopping.js

+ 252 - 72
controller/shopping/food.js

@@ -1,6 +1,7 @@
 'use strict';
 
-import FoodModel from '../../models/shopping/food'
+import {Food as FoodModel, Menu as MenuModel} from '../../models/shopping/food'
+import ShopModel from '../../models/shopping/shop'
 import BaseComponent from '../../prototype/baseComponent'
 import formidable from 'formidable'
 
@@ -13,16 +14,20 @@ class Food extends BaseComponent{
 			icon_url: "5da3872d782f707b4c82ce4607c73d1ajpeg",
 			is_selected: true,
 			type: 1,
+			foods: [],
 		}, {
 			name: '优惠',
 			description: '美味又实惠, 大家快来抢!', 
 			icon_url: "4735c4342691749b8e1a531149a46117jpeg",
 			type: 1,
+			foods: [],
 		}]
 		this.initData = this.initData.bind(this);
 		this.addFood = this.addFood.bind(this);
 		this.getCategory = this.getCategory.bind(this);
 		this.addCategory = this.addCategory.bind(this);
+		this.getSpecfoods = this.getSpecfoods.bind(this);
+		this.updateFood = this.updateFood.bind(this);
 	}
 	async initData(restaurant_id){
 		for (let i = 0; i < this.defaultData.length; i++) {
@@ -35,7 +40,7 @@ class Food extends BaseComponent{
 			}
 			const defaultData = this.defaultData[i];
 			const Category = {...defaultData, id: category_id, restaurant_id};
-			const newFood = new FoodModel(Category);
+			const newFood = new MenuModel(Category);
 			try{
 				await newFood.save();
 				console.log('初始化食品数据成功');
@@ -48,7 +53,7 @@ class Food extends BaseComponent{
 	async getCategory(req, res, next){
 		const restaurant_id = req.params.restaurant_id;
 		try{
-			const category_list = await FoodModel.find({restaurant_id});
+			const category_list = await MenuModel.find({restaurant_id});
 			res.send({
 				status: 1,
 				category_list,
@@ -72,7 +77,7 @@ class Food extends BaseComponent{
 					throw new Error('餐馆ID错误');
 				}
 			}catch(err){
-				console.log('前台参数错误');
+				console.log(err.message, err);
 				res.send({
 					status: 0,
 					type: 'ERROR_PARAMS',
@@ -96,8 +101,9 @@ class Food extends BaseComponent{
 				description: fields.description, 
 				restaurant_id: fields.restaurant_id, 
 				id: category_id,
+				foods: [],
 			}
-			const newFood = new FoodModel(foodObj);
+			const newFood = new MenuModel(foodObj);
 			try{
 				await newFood.save();
 				res.send({
@@ -140,10 +146,12 @@ class Food extends BaseComponent{
 				return
 			}
 			let category;
+			let restaurant;
 			try{
-				category = await FoodModel.findOne({id: fields.category_id});
+				category = await MenuModel.findOne({id: fields.category_id});
+				restaurant = await ShopModel.findOne({id: fields.restaurant_id});
 			}catch(err){
-				console.log('获取食品类型失败');
+				console.log('获取食品类型和餐馆信息失败');
 				res.send({
 					status: 0,
 					type: 'ERROR_DATA',
@@ -177,7 +185,7 @@ class Food extends BaseComponent{
 				satisfy_rate: Math.ceil(Math.random()*100),
 				satisfy_count: Math.ceil(Math.random()*1000),
 				item_id,
-				rating: (Math.random()*5).toFixed(1),
+				rating: (3 + Math.random()*2).toFixed(1),
 				rating_count,
 				month_sales,
 				tips,
@@ -211,72 +219,22 @@ class Food extends BaseComponent{
 					newFood.attributes.push(attr);
 				})
 			}
-			if (fields.specs.length < 2) {
-
-				let food_id, sku_id;
-				try{
-					sku_id = await this.getId('sku_id');
-					food_id = await this.getId('food_id');
-				}catch(err){
-					console.log('获取sku_id、food_id失败');
-					res.send({
-						status: 0,
-						type: 'ERROR_DATA',
-						message: '添加食品失败'
-					})
-					return
-				}
-				newFood.specfoods.push({
-					packing_fee: fields.specs[0].packing_fee,
-					price: fields.specs[0].price,
-					specs: [],
-					name: fields.name,
-					item_id,
-					sku_id,
-					food_id,
-					restaurant_id: fields.restaurant_id,
-					recent_rating: (Math.random()*5).toFixed(1),
-					recent_popularity: Math.ceil(Math.random()*1000),
-				})
-			}else{
-				newFood.specifications.push({
-					values: [],
-					name: "规格"
+			try{
+				const [specfoods, specifications] = await this.getSpecfoods(fields, item_id);
+				newFood.specfoods = specfoods;
+				newFood.specifications = specifications;
+			}catch(err){
+				console.log('添加specs失败', err);
+				res.send({
+					status: 0,
+					type: 'ERROR_DATA',
+					message: '添加食品失败'
 				})
-				for (let i = 0; i < fields.specs.length; i++) {
-					let food_id, sku_id;
-					try{
-						sku_id = await this.getId('sku_id');
-						food_id = await this.getId('food_id');
-					}catch(err){
-						console.log('获取sku_id、food_id失败');
-						res.send({
-							status: 0,
-							type: 'ERROR_DATA',
-							message: '添加食品失败'
-						})
-						return
-					}
-					newFood.specfoods.push({
-						packing_fee: fields.specs[i].packing_fee,
-						price: fields.specs[i].price,
-						specs: [{
-							name: "规格",
-							value: fields.specs[i].specs
-						}],
-						name: fields.name,
-						item_id,
-						sku_id,
-						food_id,
-						restaurant_id: fields.restaurant_id,
-						recent_rating: (Math.random()*5).toFixed(1),
-						recent_popularity: Math.ceil(Math.random()*1000),
-					})
-					newFood.specifications[0].values.push(fields.specs[i].specs);
-				}
+				return
 			}
 			try{
-				category.foods.push(newFood);
+				const foodEntity = await FoodModel.create(newFood);
+				category.foods.push(foodEntity);
 				category.markModified('foods');
 				await category.save();
 				res.send({
@@ -293,8 +251,66 @@ class Food extends BaseComponent{
 			}
 		})
 	}
+	async getSpecfoods(fields, item_id){
+		let specfoods = [], specifications = [];
+		if (fields.specs.length < 2) {
+			let food_id, sku_id;
+			try{
+				sku_id = await this.getId('sku_id');
+				food_id = await this.getId('food_id');
+			}catch(err){
+				throw new Error('获取sku_id、food_id失败')
+			}
+			specfoods.push({
+				packing_fee: fields.specs[0].packing_fee,
+				price: fields.specs[0].price,
+				specs: [],
+				specs_name: fields.specs[0].specs,
+				name: fields.name,
+				item_id,
+				sku_id,
+				food_id,
+				restaurant_id: fields.restaurant_id,
+				recent_rating: (Math.random()*5).toFixed(1),
+				recent_popularity: Math.ceil(Math.random()*1000),
+			})
+		}else{
+			specifications.push({
+				values: [],
+				name: "规格"
+			})
+			for (let i = 0; i < fields.specs.length; i++) {
+				let food_id, sku_id;
+				try{
+					sku_id = await this.getId('sku_id');
+					food_id = await this.getId('food_id');
+				}catch(err){
+					throw new Error('获取sku_id、food_id失败')
+				}
+				specfoods.push({
+					packing_fee: fields.specs[i].packing_fee,
+					price: fields.specs[i].price,
+					specs: [{
+						name: "规格",
+						value: fields.specs[i].specs
+					}],
+					specs_name: fields.specs[i].specs,
+					name: fields.name,
+					item_id,
+					sku_id,
+					food_id,
+					restaurant_id: fields.restaurant_id,
+					recent_rating: (Math.random()*5).toFixed(1),
+					recent_popularity: Math.ceil(Math.random()*1000),
+				})
+				specifications[0].values.push(fields.specs[i].specs);
+			}
+		}
+		return [specfoods, specifications]
+	}
 	async getMenu(req, res, next){
 		const restaurant_id = req.query.restaurant_id;
+		const allMenu = req.query.allMenu;
 		if (!restaurant_id || !Number(restaurant_id)) {
 			console.log('获取餐馆参数ID错误');
 			res.send({
@@ -304,8 +320,14 @@ class Food extends BaseComponent{
 			})
 			return
 		}
+		let filter;
+		if (allMenu) {
+			filter = {restaurant_id}
+		}else{
+			filter = {restaurant_id, $where: function(){return this.foods.length}};
+		}
 		try{
-			const menu = await FoodModel.find({restaurant_id, $where: function(){return this.foods.length}}, '-_id');
+			const menu = await MenuModel.find(filter, '-_id');
 			res.send(menu);
 		}catch(err){
 			console.log('获取食品数据失败', err);
@@ -316,6 +338,164 @@ class Food extends BaseComponent{
 			})
 		}
 	}
+	async getMenuDetail(req, res, next){
+		const category_id = req.params.category_id;
+		if (!category_id || !Number(category_id)) {
+			console.log('获取Menu详情参数ID错误');
+			res.send({
+				status: 0,
+				type: 'ERROR_PARAMS',
+				message: 'Menu ID参数错误',
+			})
+			return
+		}
+		try{
+			const menu = await MenuModel.findOne({id: category_id}, '-_id');
+			res.send(menu)
+		}catch(err){
+			console.log('获取Menu详情失败', err);
+			res.send({
+				status: 0,
+				type: 'GET_DATA_ERROR',
+				message: '获取Menu详情失败'
+			})
+		}
+	}
+	async getFoods(req, res, next){
+		const {restaurant_id, limit = 20, offset = 0} = req.query;
+		try{
+			let filter = {};
+			if (restaurant_id && Number(restaurant_id)) {
+				filter = {restaurant_id}
+			}
+
+			const foods = await FoodModel.find(filter, '-_id').limit(Number(limit)).skip(Number(offset));
+			res.send(foods);
+		}catch(err){
+			console.log('获取食品数据失败', err);
+			res.send({
+				status: 0,
+				type: 'GET_DATA_ERROR',
+				message: '获取食品数据失败'
+			})
+		}
+	}
+	async getFoodsCount(req, res, next){
+		const restaurant_id = req.query.restaurant_id;
+		try{
+			let filter = {};
+			if (restaurant_id && Number(restaurant_id)) {
+				filter = {restaurant_id}
+			}
+
+			const count = await FoodModel.find(filter).count();
+			res.send({
+				status: 1,
+				count,
+			})
+		}catch(err){
+			console.log('获取食品数量失败', err);
+			res.send({
+				status: 0,
+				type: 'ERROR_TO_GET_COUNT',
+				message: '获取食品数量失败'
+			})
+		}
+	}
+	async updateFood(req, res, next){
+		const form = new formidable.IncomingForm();
+		form.parse(req, async (err, fields, files) => {
+			if (err) {
+				console.log('获取食品信息form出错', err);
+				res.send({
+					status: 0,
+					type: 'ERROR_FORM',
+					message: '表单信息错误',
+				})
+				return 
+			}
+			const {name, item_id, description = "", image_path, category_id, new_category_id} = fields;
+			try{
+				if (!name) {
+					throw new Error('食品名称错误');
+				}else if(!item_id || !Number(item_id)){
+					throw new Error('食品ID错误');
+				}else if(!category_id || !Number(category_id)){
+					throw new Error('食品分类ID错误');
+				}else if(!image_path){
+					throw new Error('食品图片地址错误');
+				}
+				const [specfoods, specifications] = await this.getSpecfoods(fields, item_id);
+				let newData;
+				if (new_category_id !== category_id) {
+					newData = {name, description, image_path, category_id: new_category_id, specfoods, specifications};
+					const food = await FoodModel.findOneAndUpdate({item_id}, {$set: newData});
+
+					const menu = await MenuModel.findOne({id: category_id})
+					const targetmenu = await MenuModel.findOne({id: new_category_id})
+
+					let subFood = menu.foods.id(food._id);
+					subFood.set(newData)
+					targetmenu.foods.push(subFood)
+					targetmenu.markModified('foods');
+					await targetmenu.save()
+					await subFood.remove()
+					await menu.save()
+				}else{
+					newData = {name, description, image_path, specfoods, specifications};
+					const food = await FoodModel.findOneAndUpdate({item_id}, {$set: newData});
+
+					const menu = await MenuModel.findOne({id: category_id})
+					let subFood = menu.foods.id(food._id);
+					subFood.set(newData)
+					await menu.save()
+				}
+
+				res.send({
+					status: 1,
+					success: '修改食品信息成功',
+				})
+			}catch(err){
+				console.log(err.message, err);
+				res.send({
+					status: 0,
+					type: 'ERROR_UPDATE_FOOD',
+					message: '更新食品信息失败',
+				})
+			}
+		})
+	}
+	async deleteFood(req, res, next){
+		const food_id = req.params.food_id;
+		if (!food_id || !Number(food_id)) {
+			console.log('food_id参数错误');
+			res.send({
+				status: 0,
+				type: 'ERROR_PARAMS',
+				message: 'food_id参数错误',
+			})
+			return 
+		}
+		try{
+			const food = await FoodModel.findOne({item_id: food_id});
+			const menu = await MenuModel.findOne({id: food.category_id})
+			let subFood = menu.foods.id(food._id);
+			await subFood.remove()
+			await menu.save()
+			await food.remove()
+			res.send({
+				status: 1,
+				success: '删除食品成功',
+			})
+		}catch(err){
+			console.log('删除食品失败', err);
+			res.send({
+				status: 0,
+				type: 'DELETE_FOOD_FAILED',
+				message: '删除食品失败',
+			})
+		}
+	}
 }
 
 export default new Food()

+ 7 - 6
controller/shopping/shop.js

@@ -374,7 +374,7 @@ class Shop extends AddressComponent{
 		const form = new formidable.IncomingForm();
 		form.parse(req, async (err, fields, files) => {
 			if (err) {
-				console.log('更新商铺信息form出错');
+				console.log('获取商铺信息form出错', err);
 				res.send({
 					status: 0,
 					type: 'ERROR_FORM',
@@ -382,7 +382,7 @@ class Shop extends AddressComponent{
 				})
 				return 
 			}
-			const {name, address, description = "暂无介绍", phone, category, id, latitude, longitude, image_path} = fields;
+			const {name, address, description = "", phone, category, id, latitude, longitude, image_path} = fields;
 			try{
 				if (!name) {
 					throw new Error('餐馆名称错误');
@@ -394,6 +394,8 @@ class Shop extends AddressComponent{
 					throw new Error('餐馆分类错误');
 				}else if(!id || !Number(id)){
 					throw new Error('餐馆ID错误');
+				}else if(!image_path){
+					throw new Error('餐馆图片地址错误');
 				}
 				let newData;
 				if (latitude && longitude) {
@@ -407,13 +409,12 @@ class Shop extends AddressComponent{
 					success: '修改商铺信息成功',
 				})
 			}catch(err){
-				console.log(err.message);
+				console.log(err.message, err);
 				res.send({
 					status: 0,
-					type: 'ERROR_QUERY',
-					message: err.message,
+					type: 'ERROR_UPDATE_RESTAURANT',
+					message: '更新商铺信息失败',
 				})
-				return
 			}
 		})
 	}

+ 57 - 52
models/shopping/food.js

@@ -4,6 +4,58 @@ import mongoose from 'mongoose'
 const Schema = mongoose.Schema;
 
 const foodSchema = new Schema({
+	rating: {type: Number, default: 0},
+	is_featured: {type: Number, default: 0},
+	restaurant_id: {type: Number, isRequired: true},
+	category_id: {type: Number, isRequired: true},
+	pinyin_name: {type: String, default: ''},
+	display_times: {type: Array, default: []},
+	attrs: {type: Array, default: []},
+	description: {type: String, default: ""},
+	month_sales: {type: Number, default: 0},
+	rating_count: {type: Number, default: 0},
+	tips: String,
+	image_path: String,
+	specifications: [Schema.Types.Mixed],
+	server_utc: {type: Date, default: Date.now()},
+	is_essential: {type: Boolean, default: false},
+	attributes: {type: Array, default: []},
+	item_id: {type: Number, isRequired: true},
+	limitation: Schema.Types.Mixed,
+	name: {type: String, isRequired: true},
+	satisfy_count: {type: Number, default: 0},
+	activity: Schema.Types.Mixed,
+	satisfy_rate: {type: Number, default: 0},
+	specfoods: [{
+		original_price: {type: Number, default: 0},
+		sku_id: {type: Number, isRequired: true},
+		name: {type: String, isRequired: true},
+		pinyin_name: {type: String, default: ""},
+		restaurant_id: {type: Number, isRequired: true},
+		food_id: {type: Number, isRequired: true},
+		packing_fee: {type: Number, default: 0},
+		recent_rating: {type: Number, default: 0},
+		promotion_stock: {type: Number, default: -1},
+		price: {type: Number, default: 0},
+		sold_out: {type: Boolean, default: false},
+		recent_popularity: {type: Number, default: 0},
+		is_essential: {type: Boolean, default: false},
+		item_id: {type: Number, isRequired: true},
+		checkout_mode: {type: Number, default: 1},
+		stock: {type: Number, default: 1000},
+		specs_name: String,
+		specs: [
+			{
+				name: String,
+				value: String
+			}
+		]
+	}]
+})
+
+foodSchema.index({item_id: 1});
+
+const menuSchema = new Schema({
 	description: String,
 	is_selected: {type: Boolean, default: true},
 	icon_url: {type: String, default: ''},
@@ -11,60 +63,13 @@ const foodSchema = new Schema({
 	id:  {type: Number, isRequired: true},
 	restaurant_id: {type: Number, isRequired: true},
 	type: {type: Number, default: 1},
-	foods: [
-		{
-			rating: {type: Number, default: 0},
-			is_featured: {type: Number, default: 0},
-			restaurant_id: {type: Number, isRequired: true},
-			pinyin_name: {type: String, default: ''},
-			display_times: {type: Array, default: []},
-			category_id: {type: Number, isRequired: true},
-			attrs: {type: Array, default: []},
-			description: {type: String, default: ""},
-			month_sales: {type: Number, default: 0},
-			rating_count: {type: Number, default: 0},
-			tips: String,
-			image_path: String,
-			specifications: [Schema.Types.Mixed],
-			server_utc: {type: Date, default: Date.now()},
-			is_essential: {type: Boolean, default: false},
-			attributes: {type: Array, default: []},
-			item_id: {type: Number, isRequired: true},
-			limitation: Schema.Types.Mixed,
-			name: {type: String, isRequired: true},
-			satisfy_count: {type: Number, default: 0},
-			activity: Schema.Types.Mixed,
-			satisfy_rate: {type: Number, default: 0},
-			specfoods: [{
-				original_price: {type: Number, default: 0},
-				sku_id: {type: Number, isRequired: true},
-				name: {type: String, isRequired: true},
-				pinyin_name: {type: String, default: ""},
-				restaurant_id: {type: Number, isRequired: true},
-				food_id: {type: Number, isRequired: true},
-				packing_fee: {type: Number, default: 0},
-				recent_rating: {type: Number, default: 0},
-				promotion_stock: {type: Number, default: -1},
-				price: {type: Number, default: 0},
-				sold_out: {type: Boolean, default: false},
-				recent_popularity: {type: Number, default: 0},
-				is_essential: {type: Boolean, default: false},
-				item_id: {type: Number, isRequired: true},
-				checkout_mode: {type: Number, default: 1},
-				stock: {type: Number, default: 1000},
-				specs: [
-					{
-						name: String,
-						value: String
-					}
-				]
-			}]
-		}
-	]
+	foods: [foodSchema]
 });
 
-foodSchema.index({ id: 1 });
+menuSchema.index({ id: 1 });
 
 const Food = mongoose.model('Food', foodSchema);
 
-export default Food
+const Menu = mongoose.model('Menu', menuSchema);
+
+export {Food, Menu}

+ 7 - 2
routes/shopping.js

@@ -8,14 +8,19 @@ const router = express.Router();
 
 router.post('/addshop', Shop.addShop);
 router.get('/restaurants', Shop.getRestaurants);
-router.get('/allrestaurants', Shop.getShopCount);
+router.get('/restaurants/count', Shop.getShopCount);
 router.post('/updateshop', Shop.updateshop);
-router.delete('/resturant/:restaurant_id/delete', Shop.deleteResturant);
+router.delete('/restaurant/:restaurant_id', Shop.deleteResturant);
 router.get('/restaurant/:restaurant_id', Shop.getRestaurantDetail);
 router.post('/addfood', Food.addFood);
 router.get('/getcategory/:restaurant_id', Food.getCategory);
 router.post('/addcategory', Food.addCategory);
 router.get('/v2/menu', Food.getMenu);
+router.get('/v2/menu/:category_id', Food.getMenuDetail);
+router.get('/v2/foods', Food.getFoods);
+router.get('/v2/foods/count', Food.getFoodsCount);
+router.post('/v2/updatefood', Food.updateFood);
+router.delete('/v2/food/:food_id', Food.deleteFood);
 router.get('/v2/restaurant/category', Category.getCategories);
 router.get('/v1/restaurants/delivery_modes', Category.getDelivery);
 router.get('/v1/restaurants/activity_attributes', Category.getActivity);