Bladeren bron

add订单api

maguohua 8 jaren geleden
bovenliggende
commit
49e914399c
13 gewijzigde bestanden met toevoegingen van 354 en 38 verwijderingen
  1. 2 2
      README.md
  2. 19 26
      controller/v1/carts.js
  3. 139 0
      controller/v1/order.js
  4. 89 0
      models/bos/order.js
  5. 2 2
      models/ids.js
  6. 89 0
      models/v1/cart.js
  7. 1 1
      package.json
  8. 1 1
      prototype/baseComponent.js
  9. 0 4
      public/img/default/.gitignore
  10. BIN
      public/img/default/default.jpg
  11. 6 1
      routes/bos.js
  12. 3 1
      routes/index.js
  13. 3 0
      routes/v1.js

+ 2 - 2
README.md

@@ -62,8 +62,8 @@ npm run dev (需开启本地mongodb,如果没有安装mongodb,可以运行 n
 - [x] 修改密码
 - [x] 用户信息
 - [x] 添加、删除、修改收货地址
-- [ ] 下单功能 
-- [ ] 订单列表
+- [x] 下单功能 
+- [x] 订单列表
 - [ ] 订单详情
 - [ ] 下载App
 - [ ] 帐户信息

+ 19 - 26
controller/v1/carts.js

@@ -4,6 +4,7 @@ import AddressComponent from '../../prototype/addressComponent'
 import formidable from 'formidable'
 import PaymentsModel from '../../models/v1/payments'
 import ShopModel from '../../models/shopping/shop'
+import CartModel from '../../models/v1/cart'
 
 class Carts extends AddressComponent{
 	constructor(){
@@ -11,7 +12,7 @@ class Carts extends AddressComponent{
 		this.extra = [{
 			description: '',
 			name: '餐盒',
-			price: 2,
+			price: 0,
 			quantity: 1,
 			type: 0,
 		}]
@@ -67,6 +68,9 @@ class Carts extends AddressComponent{
 			let deliver_amount = 0; //食品价格
 			entities[0].map(item => {
 				deliver_amount += item.price * item.quantity;
+				if (item.packing_fee) {
+					this.extra.price += item.packing_fee*item.quantity;
+				}
 				if (item.specs[0]) {
 					return item.name = item.name + '-' + item.specs[0];
 				}
@@ -87,49 +91,38 @@ class Carts extends AddressComponent{
 				}
 			})
 			const checkoutInfo = {
+				id: cart_id,
 				cart: {
 					id: cart_id,
 					groups: entities,
 					extra: this.extra,
 					deliver_amount,
-					deliver_time: '',
-					discount_amount: '',
-					dist_info: '',
-					is_address_too_far: false,
 					is_deliver_by_fengniao: !!restaurant.delivery_mode,
-					is_online_paid: 1,
-					is_ontime_available: 0,
-					must_new_user: 0,
-					must_pay_online: 0,
-					ontime_status: 0,
-					ontime_unavailable_reason: '',
 					original_total: total,
 					phone: restaurant.phone,
-					promise_delivery_time: 0,
 					restaurant_id,
 					restaurant_info: restaurant,
 					restaurant_minimum_order_amount: restaurant.float_minimum_order_amount,
-					restaurant_name_for_url: '',
-					restaurant_status: 1,
-					service_fee_explanation: 0,
 					total,
 					user_id: UID,
 				},
 				delivery_reach_time,
 				invoice,
-				sig: "8d65fd81cb962c1f64cd162c6ac5728f",
-				current_address: {},
+				sig: Math.ceil(Math.random()*1000000).toString(),
 				payments,
-				deliver_times: [],
-				deliver_times_v2: [],
-				merchant_coupon_info: {},
-				number_of_meals: {},
-				discount_rule: {},
-				hongbao_info: {},
-				is_support_coupon: false,
-				is_support_ninja: 1,
 			}
-			res.send(checkoutInfo)	
+			try{
+				const newCart = new CartModel(checkoutInfo);
+				const cart = await newCart.save();
+				res.send(cart)
+			}catch(err){
+				console.log('保存购物车数据失败');
+				res.send({
+					status: 0,
+					type: 'ERROR_TO_SAVE_CART',
+					message: '加入购物车失败'
+				})
+			}
 		})
 	}
 }

+ 139 - 0
controller/v1/order.js

@@ -0,0 +1,139 @@
+'use strict';
+
+import BaseComponent from '../../prototype/baseComponent'
+import formidable from 'formidable'
+import OrderModel from '../../models/bos/order'
+import CartModel from '../../models/v1/cart'
+import timestamp from 'time-stamp'
+
+class Order extends BaseComponent{
+	constructor(){
+		super()
+		this.postOrder = this.postOrder.bind(this);
+	}
+	async postOrder(req, res, next){
+		const form = new formidable.IncomingForm();
+		form.parse(req, async (err, fields, files) => {
+			if (err) {
+				console.log('formidable解析出错', err);
+				res.send({
+					status: 1,
+					message: '下单失败'
+				})
+				return 
+			}
+			const {user_id, cart_id} = req.params;
+			const {address_id, come_from = 'mobile_web', deliver_time = '', description, entities, geohash, paymethod_id = 1} = fields;
+			try{
+				if(!(entities instanceof Array) || !entities.length){
+					throw new Error('entities参数错误')
+				}else if(!(entities[0] instanceof Array) || !entities[0].length){
+					throw new Error('entities参数错误')
+				}else if(!address_id){
+					throw new Error('address_id参数错误')
+				}else if(!user_id || !Number(user_id)){
+					throw new Error('user_id参数错误')
+				}else if(!cart_id || !Number(cart_id)){
+					throw new Error('cart_id参数错误')
+				}else if(!user_id){
+					throw new Error('未登录')
+				}
+			}catch(err){
+				console.log(err.message, err);
+				res.send({
+					status: 0,
+					type: 'ERROR_PARAMS',
+					message: err.message
+				})
+				return 
+			}
+			let cart;
+			let order_id;
+			try{
+				cart = await CartModel.findOne({id: cart_id});
+				order_id = await this.getId('order_id');
+			}catch(err){
+				console.log('获取数据失败', err);
+				res.send({
+					status: 0,
+					type: 'ERROR_GET_DATA',
+					message: '获取订单失败',
+				})
+				return 
+			}
+			const orderObj = {
+				basket: {
+					group: entities,
+					packing_fee: {
+						name: cart.cart.extra[0].name,
+						price: cart.cart.extra[0].price,
+						quantity: cart.cart.extra[0].quantity,
+					}
+				},
+				restaurant_id: cart.cart.restaurant_id,
+				restaurant_image_url: cart.cart.restaurant_info.image_path,
+				restaurant_name:  cart.cart.restaurant_info.name,
+				formatted_created_at: new Date().getTime(),
+				status_bar: {
+					color: 'f60',
+					image_type: '',
+					sub_title: '15分钟内支付',
+					title: '等待支付',
+				},
+				total_amount: cart.cart.total,
+				total_quantity: entities[0].length,
+				unique_id: order_id,
+				id: order_id,
+				user_id,
+				address_id,
+			}
+			try{
+				await OrderModel.create(orderObj);
+				res.send({
+					need_validation: false,
+				})
+			}catch(err){
+				console.log('保存订单数据失败');
+				res.send({
+					status: 0,
+					type: 'ERROR_SAVE_ORDER',
+					message: '保存订单失败'
+				})
+			}
+		})
+	}
+	async getOrders(req, res, next){
+		const user_id = req.params.user_id;
+		const {limit = 0, offset = 0} = req.query;
+		try{
+			if(!user_id || !Number(user_id)){
+				throw new Error('user_id参数错误')
+			}else if(!Number(limit)){
+				throw new Error('limit参数错误')
+			}else if(typeof Number(offset) !== 'number'){
+				throw new Error('offset参数错误')
+			}
+		}catch(err){
+			console.log(err.message, err);
+			res.send({
+				status: 0,
+				type: 'ERROR_PARAMS',
+				message: err.message
+			})
+			return 
+		}
+		try{
+			const orders = await OrderModel.find({user_id}, '-_id').limit(Number(limit)).skip(Number(offset));
+			res.send(orders);
+		}catch(err){
+			console.log('获取订单列表失败', err);
+			res.send({
+				status: 0,
+				type: 'ERROR_GET_ORDER_LIST',
+				message: '获取订单列表失败'
+			})
+		}
+	}
+}
+
+export default new Order()

+ 89 - 0
models/bos/order.js

@@ -0,0 +1,89 @@
+'use strict';
+
+import mongoose from 'mongoose'
+
+const Schema = mongoose.Schema;
+
+const orderSchema = new Schema({
+	basket: {
+		abandoned_extra: [
+			{
+				category_id: Number,
+				name: {type: String, default: ''},
+				price: {type: Number, default: 0},
+				quantity: {type: Number, default: 0},
+			}
+		],
+		deliver_fee: {
+			category_id: {type: Number, default: 2},
+			name: {type: String, default: '配送费'},
+			price: {type: Number, default: 4},
+			quantity: {type: Number, default: 1},
+		},
+		extra: [],
+		group: [
+			[
+				{
+					attrs: [],
+					new_specs: [],
+					name: String,
+					price: Number,
+					quantity: Number,
+					specs: [String]
+				}
+			]
+		],
+		packing_fee: {
+			category_id: {type: Number, default: 1},
+			name: {type: String, default: '餐盒'},
+			price: Number,
+			quantity: Number
+		},
+		pindan_map: []
+	},
+	formatted_created_at: String,
+	id: Number,
+	is_brand: {type: Number, default: 0},
+	is_deletable: {type: Number, default: 1},
+	is_new_pay: {type: Number, default: 1},
+	is_pindan: {type: Number, default: 0},
+	operation_confirm: {type: Number, default: 0},
+	operation_pay: {type: Number, default: 0},
+	operation_rate: {type: Number, default: 0},
+	operation_rebuy: {type: Number, default: 2},
+	operation_upload_photo: {type: Number, default: 0},
+	pay_remain_seconds: {type: Number, default: 0},
+	rated_point: {type: Number, default: 0},
+	remind_reply_count: {type: Number, default: 0},
+	restaurant_id: Number,
+	restaurant_image_hash: String,
+	restaurant_image_url: String,
+	restaurant_name: String,
+	restaurant_type: {type: Number, default: 0},
+	status_bar: {
+		color: String,
+		image_type: String,
+		sub_title: String,
+		title: String,
+	},
+	status_code: {type: Number, default: 0},
+	timeline_node: {
+		actions: [],
+		description: String,
+		in_processing: {type: Number, default: 0},
+		sub_description: String,
+		title: String,
+	},
+	top_show: {type: Number, default: 0},
+	total_amount: Number,
+	total_quantity: Number,
+	unique_id: Number,
+	user_id: Number,
+	address_id: Number,
+})
+
+orderSchema.index({id: 1});
+
+const Order = mongoose.model('Order', orderSchema);
+
+export default Order

+ 2 - 2
models/ids.js

@@ -5,7 +5,7 @@ import mongoose from 'mongoose'
 const idsSchema = new mongoose.Schema({
 	restaurant_id: Number,
 	food_id: Number,
-	orderId: Number,
+	order_id: Number,
 	user_id: Number,
 	address_id: Number,
 	cart_id: Number,
@@ -22,7 +22,7 @@ Ids.findOne((err, data) => {
 		const newIds = new Ids({
 			restaurant_id: 0,
 			food_id: 0,
-			orderId: 0,
+			order_id: 0,
 			user_id: 0,
 			address_id: 0,
 			cart_id: 0,

+ 89 - 0
models/v1/cart.js

@@ -0,0 +1,89 @@
+'use strict';
+
+import mongoose from 'mongoose'
+
+const Schema = mongoose.Schema;
+
+const cartSchema = Schema({
+	id: Number,
+	cart: {
+		id: Number,
+		groups: [
+			[
+				{
+					attrs: [],
+					extra: [],
+					id: Number,
+					new_specs: [],
+					name: String,
+					price: Number,
+					quantity: Number,
+					specs: [String],
+					packing_fee: Number,
+					sku_id: Number,
+					stock: Number,
+				}
+			]
+		],
+		extra: [{
+			description: String,
+			name: {type: String, default: '餐盒'},
+			price: {type: Number, default: 0},
+			quantity: {type: Number, default: 0},
+			type: {type: Number, default: 0},
+		}],
+		deliver_amount: Number,
+		deliver_time: String,
+		discount_amount: String,
+		dist_info: String,
+		is_address_too_far: {type: Boolean, default: false},
+		is_deliver_by_fengniao: Boolean,
+		is_online_paid: {type: Number, default: 1},
+		is_ontime_available: {type: Number, default: 0},
+		must_new_user: {type: Number, default: 0},
+		must_pay_online: {type: Number, default: 0},
+		ontime_status: {type: Number, default: 0},
+		ontime_unavailable_reason: String,
+		original_total: Number,
+		phone: String,
+		promise_delivery_time: {type: Number, default: 0},
+		restaurant_id: Number,
+		restaurant_info: Schema.Types.Mixed,
+		restaurant_minimum_order_amount: Number,
+		restaurant_name_for_url: String,
+		restaurant_status: {type: Number, default: 1},
+		service_fee_explanation: {type: Number, default: 0},
+		total: Number,
+		user_id: Number,
+	},
+	delivery_reach_time: String,
+	invoice: {
+		is_available: {type: Boolean, default: false},
+		status_text: String,
+	},
+	sig: String,
+	current_address: {},
+	payments: [{
+		description: String,
+		disabled_reason: String,
+		id: Number,
+		is_online_payment: {type: Boolean, default: true},
+		name: String,
+		promotion:[],
+		select_state: Number,
+	}],
+	deliver_times: [],
+	deliver_times_v2: [],
+	merchant_coupon_info: {},
+	number_of_meals: {},
+	discount_rule: {},
+	hongbao_info: {},
+	is_support_coupon: {type: Boolean, default: false},
+	is_support_ninja: {type: Number, default: 1},
+})
+
+cartSchema.index({id: 1});
+
+const Cart = mongoose.model('Cart', cartSchema);
+
+export default Cart

+ 1 - 1
package.json

@@ -26,7 +26,6 @@
     "babel-register": "^6.24.0",
     "bluebird": "^3.5.0",
     "captchapng": "0.0.1",
-    "ccap": "^0.6.10",
     "config-lite": "^1.5.0",
     "connect-flash": "^0.1.1",
     "connect-mongo": "^1.3.2",
@@ -45,6 +44,7 @@
     "pm2": "^2.4.6",
     "sha1": "^1.1.1",
     "supervisor": "^0.12.0",
+    "time-stamp": "^2.0.0",
     "winston": "^2.3.1"
   },
   "devDependencies": {

+ 1 - 1
prototype/baseComponent.js

@@ -7,7 +7,7 @@ import gm from 'gm'
 
 export default class BaseComponent {
 	constructor(){
-		this.idList = ['restaurant_id', 'food_id', 'orderId', 'user_id', 'address_id', 'cart_id', 'img_id', 'category_id', 'item_id', 'sku_id'];
+		this.idList = ['restaurant_id', 'food_id', 'order_id', 'user_id', 'address_id', 'cart_id', 'img_id', 'category_id', 'item_id', 'sku_id'];
 		this.imgTypeList = ['shop', 'food', 'avatar','default'];
 		this.uploadImg = this.uploadImg.bind(this)
 	}

+ 0 - 4
public/img/default/.gitignore

@@ -1,4 +0,0 @@
-# Ignore everything in this directory
-*
-# Except this file
-!.gitignore

BIN
public/img/default/default.jpg


+ 6 - 1
routes/bos.js

@@ -1,4 +1,9 @@
 'use strict';
 
 import express from 'express';
-const router = express.Router();
+import Order from '../controller/v1/order'
+const router = express.Router();
+
+router.get('/v2/users/:user_id/orders', Order.getOrders)
+
+export default router

+ 3 - 1
routes/index.js

@@ -1,10 +1,11 @@
 'use strict';
 
-import home from './home';
+import home from './home'
 import v1 from './v1'
 import v2 from './v2'
 import v4 from './v4'
 import ugc from './ugc'
+import bos from './bos'
 import shopping from './shopping'
 
 export default app => {
@@ -16,5 +17,6 @@ export default app => {
 	app.use('/v2', v2);
 	app.use('/v4', v4);
 	app.use('/ugc', ugc);
+	app.use('/bos', bos);
 	app.use('/shopping', shopping);
 }

+ 3 - 0
routes/v1.js

@@ -9,6 +9,7 @@ import Remark from '../controller/v1/remark'
 import BaseComponent from '../prototype/baseComponent'
 import Captchas from '../controller/v1/captchas'
 import User from '../controller/v2/user'
+import Order from '../controller/v1/order'
 const baseHandle = new BaseComponent();
 const router = express.Router();
 
@@ -24,6 +25,8 @@ router.get('/user', User.getInfo);
 router.get('/users/:user_id/addresses', Address.getAddress);
 router.post('/users/:user_id/addresses', Address.addAddress);
 router.delete('/users/:user_id/addresses/:address_id', Address.deleteAddress);
+router.post('/users/:user_id/carts/:cart_id/orders', Order.postOrder);
+
 
  
 export default router