瀏覽代碼

增加商店接口优化

maguohua 8 年之前
父節點
當前提交
20dfe17149
共有 10 個文件被更改,包括 275 次插入127 次删除
  1. 2 10
      app.js
  2. 134 66
      controller/shopping/shop.js
  3. 20 30
      controller/v1/cities.js
  4. 6 14
      controller/v1/search.js
  5. 29 0
      models/ids.js
  6. 5 5
      models/shopping/shop.js
  7. 1 0
      package.json
  8. 65 0
      prototype/addressComponent.js
  9. 12 1
      prototype/baseComponent.js
  10. 1 1
      routes/shopping.js

+ 2 - 10
app.js

@@ -4,7 +4,6 @@ import config from 'config-lite';
 import router from './routes/index.js';
 import session from 'express-session';
 import connectMongo from 'connect-mongo';
-import flash from 'connect-flash';
 import winston from 'winston';
 import expressWinston from 'express-winston';
 import path from 'path';
@@ -14,15 +13,15 @@ const app = express();
 app.use(express.static('./public'));
 
 app.all('*', (req, res, next) => {
-  	res.header("Access-Control-Allow-Origin", "*");
+  	res.header("Access-Control-Allow-Origin", req.headers.origin);
   	res.header("Access-Control-Allow-Headers", "Content-Type, Authorization, X-Requested-With");
   	res.header("Access-Control-Allow-Methods","PUT,POST,GET,DELETE,OPTIONS");
+    res.header("Access-Control-Allow-Credentials", true); //可以带cookies
   	res.header("X-Powered-By",' 3.2.1')
   	if(req.method=="OPTIONS") res.send(200);/*让options请求快速返回*/
   	else  next();
 });
 
-app.use(flash());
 const MongoStore = connectMongo(session);
 
 app.use(session({
@@ -36,13 +35,6 @@ app.use(session({
   	})
 }))
 
-app.use((req, res, next) => {
-    res.locals.user = req.session.user;
-    res.locals.success = req.flash('success').toString();
-    res.locals.error = req.flash('error').toString();
-    next();
-});
-
 // app.use(expressWinston.logger({
 //     transports: [
 //         new (winston.transports.Console)({

+ 134 - 66
controller/shopping/shop.js

@@ -1,79 +1,147 @@
 'use strict';
 
 import ShopModel from '../../models/shopping/shop';
-import BaseComponent from '../../prototype/baseComponent'
+import AddressComponent from '../../prototype/addressComponent'
+import formidable from 'formidable'
 
-class Shop extends BaseComponent{
+class Shop extends AddressComponent{
 	constructor(){
 		super()
+		this.addShop = this.addShop.bind(this);
 	}
 	async addShop(req, res, next){
-		const ifHas = await ShopModel.findOne();
-		if (ifHas) {
-			res.send(ifHas)
+		let shopId;
+		try{
+			shopId = await this.getId('shopId');
+		}catch(err){
+			res.send({
+				type: 'ERROR_DATA',
+				message: '获取数据失败'
+			})
 			return
 		}
-		const newShop = new ShopModel({
-			name: "萨伦意大利冰淇淋",
-			address: "上海市闵行区颛桥镇鑫都路2508号302-1",
-			description: '',
-			float_delivery_fee: 5,
-			float_minimum_order_amount: 20,
-			id: 1825954,
-			is_premium: false,
-			is_new: false,
-			latitude: 31.056997,
-			longitude: 121.396113,
-			opening_hours: ["10:30/20:30"],
-			phone: "15921357769",
-			promotion_info: "欢迎光临,用餐高峰请提前下单,谢谢",
-			rating: 4.8,
-			rating_count: 34,
-			recent_order_num: 61,
-			status: 0,
-			image_path: "287de218d8026a725bda5a00e274db7cjpeg",
-			piecewise_agent_fee: {
-				tips: "配送费约¥5"
-			},
-			delivery_mode: {
-				color: "57A9FF",
-				id: 1,
-				is_solid: true,
-				text: "蜂鸟专送"
-			},
-			activities: [{
-				description: '满30减5,满60减8',
-				icon_color: "f07373",
-				icon_name: "减",
-				id: 26393397,
-				name: "满减优惠",
-			}],
-			supports: [{
-				description: "已加入“外卖保”计划,食品安全有保障",
-				icon_color: "999999",
-				icon_name: "保",
-				id: 7,
-				name: "外卖保"
-			}],
-			license: {
-				business_license_image: "3c982023d49d68caf61f41a156626426jpeg",
-				catering_service_license_image: "db299ee4218ed72c188bf59ba306868ejpeg",
-			},
-			identification: {
-				company_name: "上海市闵行区茹琪饮品店",
-				identificate_agency: "",
-				identificate_date: "2016-10-10T00:00:00+0800",
-				legal_person: "",
-				licenses_date: "",
-				licenses_number: "JY23101120002977",
-				licenses_scope: "",
-				operation_period: "",
-				registered_address: "上海市闵行区鑫都路2508号302-1",
-				registered_number: "",
-			},
-		});
-		const saveData = await newShop.save();
-		res.send(saveData)
+		const form = new formidable.IncomingForm();
+		form.uploadDir = './img/shop';
+		form.parse(req, async (err, fields, files) => {
+			try{
+				if (!fields.name) {
+					throw new Error('必须填写商店名称');
+				}else if(!fields.address){
+					throw new Error('必须填写商店地址');
+				}else if(!fields.phone){
+					throw new Error('必须填写联系电话');
+				}else if(!fields.latitude || !fields.longitude){
+					throw new Error('商店位置信息错误');
+				}
+			}catch(err){
+				res.send({
+					type: 'ERROR_PARAMS',
+					message: err.message
+				})
+				return
+			}
+			const opening_hours = fields.startTime&&fields.endTime? fields.startTime + '/' + fields.endTime : "8:30/20:30";
+			const newShop = {
+				name: fields.name,
+				address: fields.address,
+				description: fields.description || '',
+				float_delivery_fee: fields.float_delivery_fee || 0,
+				float_minimum_order_amount: fields.float_minimum_order_amount || 0,
+				id: shopId,
+				is_premium: fields.is_premium || false,
+				is_new: fields.new || false,
+				latitude: 31.056997,
+				longitude: 121.396113,
+				opening_hours: [opening_hours],
+				phone: fields.phone,
+				promotion_info: fields.promotion_info || "欢迎光临,用餐高峰请提前下单,谢谢",
+				rating: (Math.random()*5).toFixed(1),
+				rating_count: Math.ceil(Math.random()*1000),
+				recent_order_num: Math.ceil(Math.random()*1000),
+				status: Math.round(Math.random()),
+				image_path: fields.image_path,
+				piecewise_agent_fee: {
+					tips: "配送费约¥" + (fields.float_delivery_fee || 0),
+				},
+				activities: [],
+				supports: [],
+				license: {
+					business_license_image: fields.business_license_image || '',
+					catering_service_license_image: fields.catering_service_license_image || '',
+				},
+				identification: {
+					company_name: "",
+					identificate_agency: "",
+					identificate_date: "",
+					legal_person: "",
+					licenses_date: "",
+					licenses_number: "",
+					licenses_scope: "",
+					operation_period: "",
+					registered_address: "",
+					registered_number: "",
+				},
+			}
+			if (fields.delivery_mode) {
+				Object.assign(newShop, {delivery_mode: {
+					color: "57A9FF",
+					id: 1,
+					is_solid: true,
+					text: "蜂鸟专送"
+				}})
+			}
+			fields.activities.forEach((item, index) => {
+				switch(item.icon_name){
+					case '减': 
+						item.icon_color = 'f07373';
+						item.id = index + 1;
+						break;
+					case '特': 
+						item.icon_color = 'EDC123';
+						item.id = index + 1;
+						break;
+					case '新': 
+						item.icon_color = '70bc46';
+						item.id = index + 1;
+						break;
+					case '领': 
+						item.icon_color = 'E3EE0D';
+						item.id = index + 1;
+						break;
+				}
+				newShop.activities.push(item);
+			})
+			if (fields.bao) {
+				newShop.supports.push({
+					description: "已加入“外卖保”计划,食品安全有保障",
+					icon_color: "999999",
+					icon_name: "保",
+					id: 7,
+					name: "外卖保"
+				})
+			}
+			if (fields.zhun) {
+				newShop.supports.push({
+					description: "准时必达,超时秒赔",
+					icon_color: "57A9FF",
+					icon_name: "准",
+					id: 9,
+					name: "准时达"
+				})
+			}
+			if (fields.piao) {
+				newShop.supports.push({
+					description: "该商家支持开发票,请在下单时填写好发票抬头",
+					icon_color: "999999",
+					icon_name: "票",
+					id: 4,
+					name: "开发票"
+				})
+			}
+			console.log(newShop)
+			res.send(newShop)
+			return
+		})
 	}
 }
 

+ 20 - 30
controller/v1/cities.js

@@ -2,10 +2,10 @@
 
 import Cities from '../../models/v1/cities';
 import pinyin from "pinyin";  
-import BaseComponent from '../../prototype/baseComponent'
+import AddressComponent from '../../prototype/addressComponent'
 
 
-class CityHandle extends BaseComponent{
+class CityHandle extends AddressComponent{
 	constructor(){
 		super()
 		this.getCity = this.getCity.bind(this);
@@ -53,35 +53,25 @@ class CityHandle extends BaseComponent{
 			res.send(err);
 		}
 	}
-	getCityName(req){
-		return new Promise(async (resolve, reject) => {
-			let ip = req.headers['x-forwarded-for'] || 
-	 		req.connection.remoteAddress || 
-	 		req.socket.remoteAddress ||
-	 		req.connection.socket.remoteAddress;
-	 		const ipArr = ip.split(':');
-	 		ip = ipArr[ipArr.length -1];
-	 		if (process.env.NODE_ENV == 'development') {
-	 			ip = '116.231.55.195';
-	 		}
-	 		/*
-	 		调用新浪接口,获取ip地址信息
-	 		 */
-			const url = 'http://int.dpool.sina.com.cn/iplookup/iplookup.php';
-			let res = await this.fetch(url , {format: 'js', ip,}, 'GET', 'TEXT');
-			const cityInfo = JSON.parse(res.split('=')[1].toString().replace(';', ''));
-			/*
-			汉字转换成拼音
-			 */
-	        const pinyinArr = pinyin(cityInfo.city, {
-			  	style: pinyin.STYLE_NORMAL,
-			});
-			let cityName = '';
-			pinyinArr.forEach(item => {
-				cityName += item[0];
-			})
-			resolve(cityName)
+	async getCityName(req){
+		let cityInfo;
+		try{
+			cityInfo = await this.guessPosition(req);
+			console.log(cityInfo)
+		}catch(err){
+			console.error()
+		}
+		/*
+		汉字转换成拼音
+		 */
+        const pinyinArr = pinyin(cityInfo.city, {
+		  	style: pinyin.STYLE_NORMAL,
+		});
+		let cityName = '';
+		pinyinArr.forEach(item => {
+			cityName += item[0];
 		})
+		return cityName
 	}
 }
 export default new CityHandle()

+ 6 - 14
controller/v1/search.js

@@ -1,10 +1,10 @@
 'use strict';
 
-import BaseComponent from '../../prototype/baseComponent';
+import AddressComponent from '../../prototype/addressComponent';
 import Cities from '../../models/v1/cities';
 
 
-class SearchPlace extends BaseComponent{
+class SearchPlace extends AddressComponent{
 	constructor(){
 		super()
 		this.search = this.search.bind(this)
@@ -20,18 +20,10 @@ class SearchPlace extends BaseComponent{
 		}
 		try{
 			const cityInfo = await Cities.getCityById(city_id);
-			/*
-			调用腾讯地图api
-			 */
-			const resObj = await this.fetch('http://apis.map.qq.com/ws/place/v1/search', {
-				key: 'RLHBZ-WMPRP-Q3JDS-V2IQA-JNRFH-EJBHL',
-				keyword: encodeURIComponent(keyword),
-				boundary: 'region(' + encodeURIComponent(cityInfo.name) + ',0)',
-				page_size: 10,
-			});
-			const resArr = [];
+			const resObj = await this.searchPlace(keyword, cityInfo.name);
+			const cityList = [];
 			resObj.data.forEach((item, index) => {
-				resArr.push({
+				cityList.push({
 					name: item.title,
 					address: item.address,
 					latitude: item.location.lat,
@@ -39,7 +31,7 @@ class SearchPlace extends BaseComponent{
 					geohash: item.location.lat + ',' + item.location.lng,
 				})
 			});
-			res.send(resArr);
+			res.send(cityList);
 		}catch(err){
 			res.send({
 				name: 'GET_ADDRESS_ERROR',

+ 29 - 0
models/ids.js

@@ -0,0 +1,29 @@
+'use strict';
+
+import mongoose from 'mongoose'
+
+const idsSchema = new mongoose.Schema({
+	shopId: Number,
+	foodId: Number,
+	orderId: Number,
+	userId: Number,
+	addressId: Number,
+	cartId: Number,
+});
+
+const Ids = mongoose.model('Ids', idsSchema);
+
+Ids.findOne((err, data) => {
+	if (!data) {
+		const newIds = new Ids({
+			shopId: 0,
+			foodId: 0,
+			orderId: 0,
+			userId: 0,
+			addressId: 0,
+			cartId: 0,
+		});
+		newIds.save();
+	}
+})
+export default Ids

+ 5 - 5
models/shopping/shop.js

@@ -18,8 +18,8 @@ const shopSchema = new mongoose.Schema({
 		text: String
 	},
 	description: { type: String, default: "" },
-	float_delivery_fee: Number,
-	float_minimum_order_amount: Number,
+	float_delivery_fee: { type: Number, default: 0 },
+	float_minimum_order_amount: { type: Number, default: 0 },
 	id: Number,
 	identification: {
 		company_name: { type: String, default: "" },
@@ -39,14 +39,14 @@ const shopSchema = new mongoose.Schema({
 	latitude: Number,
 	longitude: Number,
 	license: {
-		business_license_image: String,
-		catering_service_license_image: String,
+		business_license_image: { type: String, default: "" },
+		catering_service_license_image: { type: String, default: "" },
 	},
 	name: {
         type: String,
         required: true 
     },
-	opening_hours: Array,
+	opening_hours: { type: Array, default: ["08:30/20:30"] },
 	phone: {
         type: String,
         required: true 

+ 1 - 0
package.json

@@ -31,6 +31,7 @@
     "express-session": "^1.15.2",
     "express-winston": "^2.3.0",
     "formidable": "^1.1.1",
+    "gm": "^1.23.0",
     "marked": "^0.3.6",
     "moment": "^2.18.1",
     "mongodb": "^2.2.25",

+ 65 - 0
prototype/addressComponent.js

@@ -0,0 +1,65 @@
+'use strict';
+
+import BaseComponent from './baseComponent'
+
+/*
+腾讯地图API统一调配组件
+ */
+class AddressComponent extends BaseComponent {
+	constructor(){
+		super();
+		this.key = 'RLHBZ-WMPRP-Q3JDS-V2IQA-JNRFH-EJBHL';
+	}
+	//获取定位地址
+	async guessPosition(req){
+		let ip = req.headers['x-forwarded-for'] || 
+ 		req.connection.remoteAddress || 
+ 		req.socket.remoteAddress ||
+ 		req.connection.socket.remoteAddress;
+ 		const ipArr = ip.split(':');
+ 		ip = ipArr[ipArr.length -1];
+ 		if (process.env.NODE_ENV == 'development') {
+ 			ip = '116.231.55.195';
+ 		}
+ 		try{
+	 		const result = await this.fetch('http://apis.map.qq.com/ws/location/v1/ip', {
+	 			ip,
+	 			key: this.key,
+	 		})
+	 		if (result.status == 0) {
+	 			const cityInfo = {
+	 				lat: result.result.location.lat,
+	 				lng: result.result.location.lng,
+	 				city: result.result.ad_info.city,
+	 			}
+	 			cityInfo.city = cityInfo.city.replace(/市$/, '');
+	 			return cityInfo
+	 		}else{
+	 			throw new Error('定位失败');
+	 		}
+ 			
+ 		}catch(err){
+ 			throw new Error(err);
+ 		}
+	}
+	//搜索地址
+	async searchPlace(keyword, cityName){
+		try{
+			const resObj = await this.fetch('http://apis.map.qq.com/ws/place/v1/search', {
+				key: this.key,
+				keyword: encodeURIComponent(keyword),
+				boundary: 'region(' + encodeURIComponent(cityName) + ',0)',
+				page_size: 10,
+			});
+			if (resObj.status == 0) {
+				return resObj
+			}else{
+				throw new Error('搜索位置信息失败');
+			}
+		}catch(err){
+			throw new Error(err);
+		}
+	}
+}
+
+export default AddressComponent

+ 12 - 1
prototype/baseComponent.js

@@ -1,4 +1,5 @@
 import fetch from 'node-fetch';
+import Ids from '../models/ids'
 
 export default class BaseComponent {
 	constructor(){
@@ -33,7 +34,6 @@ export default class BaseComponent {
 			})
 		}
 		let responseJson;
-		console.log(url)
 		try {
 			const response = await fetch(url, requestConfig);
 			if (resType === 'TEXT') {
@@ -47,4 +47,15 @@ export default class BaseComponent {
 		}
 		return responseJson
 	}
+	//获取id列表
+	async getId(type){
+		try{
+			const idData = await Ids.findOne();
+			idData[type] ++ ;
+			await idData.save();
+			return idData[type]
+		}catch(err){
+			throw new Error(err)
+		}
+	}	
 }

+ 1 - 1
routes/shopping.js

@@ -4,6 +4,6 @@ import express from 'express';
 import Shop from '../controller/shopping/shop'
 const router = express.Router();
 
-router.get('/addshop', Shop.addShop);
+router.post('/addshop', Shop.addShop);
 
 export default router