开发环境:maven3.3+eclipse4.5+jdk1.7+mysql5.7
框架:springvc+spring+mybatis+jsp+jquery+js
选择省市区使用mobileSelect.js-master.zip插件,
该插件及省市区数据下载地址:http://download.csdn.net/download/u014079773/9952084
jsp页面引入css和js文件如:
<link rel="stylesheet" href="${basePath}/css/mobileSelect.css"/>
<script src="${basePath}/js/mobileSelect.js"></script>
jsp页面:
<!--选择店铺-->
<div class="ctChooseShop overlay-slidedown">
<#--存储当前定位店铺数据-->
<input type="hidden" id="locaStoreId" value="${storeId!''}"/>
<input type="hidden" id="locaStoreName" value="${storeName!''}"/>
<input type="hidden" id="locaStoreImage" value="${storeImage!''}"/>
<input type="hidden" id="locaStoreArea" value="${storeArea!''}"/>
<i class="closeChooseShop"></i>
<!--定位-->
<div class="ctLocation positionStore" style="display:block;">
<h3>当前定位店铺</h3>
<div class="shop">
<i><img width="180px;" height="180px;" src=""/></i>
<div>
<h6></h6>
<p></p>
<span><b class="nowStore">当前店铺</b><a href="javascript:;" class="goLocationShop">进入此店铺</a></span>
</div>
</div>
</div>
<!--GPS定位-->
<div class="ctGps ctLocation gpsStore" style="display:block;">
<h3>GPS定位店铺</h3>
<div class="noStore" style="display:block;">
<i class="positioning"><img src="${basePath}/images/bgy/dingwei1.png" alt=""/></i>
<p class="positionText">正在定位中...</p>
<a class="positionBtn" href="javascript:void(0)" onclick="showLocation()" style="display:none;">重新定位</a>
</div>
<div class="shop" style="display:none;">
<i><img width="180px;" height="180px;" src=""/></i>
<div>
<h6></h6>
<p></p>
<span><a href="javascript:;" class="goGpsShop">进入此店铺</a></span>
</div>
</div>
</div>
<!--手动选择-->
<div class="ctChooseByHand">
<h3>手动选择店铺 <a href="javascript:void(0)" onclick="cleanShop();">清空</a></h3>
<div class="item">
<a href="javascript:void(0)" id="ctCity">
<span>请选择所在城市</span>
</a>
</div>
<div class="item">
<a href="javascript:;" id="ctVillage">
<span>请选择小区</span>
</a>
</div>
</div>
<div class="noStoreTips">
<p>本小区尚未开设凤凰优选门店,系统给您推荐了以下门店:</p>
</div>
<ul class="ctHandChooseShop">
<#--无小区显示定位距离最近5个店铺-->
</ul>
</div>
js业务逻辑操作:
/**
* 首页操作
*/
/**
* 首页初始化
*/
//请求路径常量
var basePath=$("#basePath").val();
$(function () {
//判断是否是手机
if(isMobile()){//是手机,执行定位方法
//gps定位选择店铺
getLocation();
}
//locationResult();//用于本地测试
//店铺名称
var storeName=$("#locaStoreName").val();
console.log("storeName:"+storeName);
//给首页左上角店铺名称赋值
$(".selectAero .shopName").html(storeName);
});
/**
* 判断是否为手机
* @returns {Boolean}
*/
function isMobile(){
var sUserAgent= navigator.userAgent.toLowerCase(),
bIsIpad= sUserAgent.match(/ipad/i) == "ipad",
bIsIphoneOs= sUserAgent.match(/iphone os/i) == "iphone os",
bIsMidp= sUserAgent.match(/midp/i) == "midp",
bIsUc7= sUserAgent.match(/rv:1.2.3.4/i) == "rv:1.2.3.4",
bIsUc= sUserAgent.match(/ucweb/i) == "ucweb",
bIsAndroid= sUserAgent.match(/android/i) == "android",
bIsCE= sUserAgent.match(/windows ce/i) == "windows ce",
bIsWM= sUserAgent.match(/windows mobile/i) == "windows mobile",
bIsWebview = sUserAgent.match(/webview/i) == "webview";
return (bIsIpad || bIsIphoneOs || bIsMidp || bIsUc7 || bIsUc || bIsAndroid || bIsCE || bIsWM);
}
/**
* js调用客户端gps定位,该方法是调用h5定位,ios开发人员提供的
*/
function getLocation(){
window.location='biguiyuan|location';
}
//定义全部变量,gps定位信息
var msg;
//获取定位数据callback
function locationResult(base64) {
//str1用于本地测试
// var str1='ewogICJlcnJvckluZm8iIDogIiIsCiAgInByb3ZpbmNlIiA6ICLlub/kuJznnIEiLAogICJsb25naXR1ZGUiIDogIjExMy4yNjg3NTciLAogICJzdHJlZXQiIDogIuWdpOa0suS6jOihlyIsCiAgImxhdGl0dWRlIiA6ICIyMi45MjQ1MzMiLAogICJjaXR5Q29kZSIgOiAiMDc1NyIsCiAgImFkZHJlc3MiIDogIuW5v@S4nOecgeS9m@WxseW4gumhuuW@t@WMuuWMl@a7mOmVh@eip@ahguWbreaAu@mDqCIsCiAgImNpdHkiIDogIuS9m@WxseW4giIsCiAgIm51bWJlciIgOiAiMjjlj7ciLAogICJkaXN0cmljdCIgOiAi6aG65b635Yy6IiwKICAicG9pTmFtZSIgOiAi56Kn5qGC5Zut5oC76YOoIiwKICAiZXJyb3JDb2RlIiA6ICIiLAogICJjb3VudHJ5IiA6ICLkuK3lm70iLAogICJhZENvZGUiIDogIjQ0MDYwNiIsCiAgInRvd25zaGlwIiA6ICLljJfmu5jplYciCn0=';
// msg=str1;
// loadLonAndLat(str1);
//判断gps是否定位到数据
//alert("gps2:"+base64);
//正式环境
msg = base64;
loadLonAndLat(msg);
}
/**
* 加载gps定位得到的经纬度信息
* @param msg gps定位得到的经纬度信息
*/
var gpsStoreId;
function loadLonAndLat(msg){
$.ajax({
type: 'post',
url:basePath+'/chooseShop.htm',
async:false,//同步
cache:false,//清空缓存
data:{"msg":msg,"type":"2"},
dataType:"json",
success: function(data) {
if(data!=null && data.length>0){
for(var i=0;i<data.length;i++){
var type=data[i].type;
console.log("type:"+type);
//alert("type2:"+type);
if(type=="2"){
//店铺id
var storeId=data[i].storeId;
//小区id
var villageId=data[i].villageId;
//店铺名称
var storeName=data[i].storeName;
//店铺图片
var storeImage=data[i].storeImage;
//店铺所在的省市区
var storeArea=data[i].storeArea;
//给当前店铺赋值
$(".ctLocation .shop img").attr("src",storeImage);
$(".ctLocation .shop h6").text(storeName);
$(".ctLocation .shop p").text(storeArea);
//存储gps定位到的店铺id
gpsStoreId=storeId;
//定位成功后显示GPS定位店铺
$(".gpsStore .shop").show();
//隐藏重新定位
$(".gpsStore .noStore").hide();
}else{
//定位不到,手动选择
//隐藏GPS定位店铺
$(".gpsStore .shop").hide();
//显示重新定位
$(".gpsStore .noStore").show();
$(".positionText").html("未定位到店铺,请确认手机已开启GPS");
$(".positionBtn").show();
$(".positioning").addClass("noAnimation");
}
}
}else{
//定位不到,手动选择
//隐藏GPS定位店铺
$(".gpsStore .shop").hide();
//显示重新定位
$(".gpsStore .noStore").show();
$(".positionText").html("未定位到店铺,请确认手机已开启GPS");
$(".positionBtn").show();
$(".positioning").addClass("noAnimation");
}
}
});
}
/**
* 根据gps定位,查询距离最近的5个店铺
* @param msg gps定位得到的经纬度信息
*/
function findNearestDistancByGps(msg){
//判断是否有店铺
var isStroe=false;
$.ajax({
type: 'post',
url:basePath+'/findNearestDistancByGps.htm',
async:false,//同步
cache:false,//清空缓存
data:{"msg":msg},
dataType:"json",
success: function(data) {
//清空拼接数据
$(".ctHandChooseShop").html("");
var html="";
if(data!=null && data.length>0){
for(var i=0;i<data.length;i++){
html+="<li>";
html+="<i><img width='180px;' height='180px;' src=\""+data[i].storeImage+"\" /></i>";
html+="<div>";
html+="<h6>"+data[i].storeName+"</h6>";
html+="<p>"+data[i].storeArea+"</p>";
html+="<span><a href='javascript:;' onclick='goShop("+data[i].storeId+")'>进入此店铺</a></span>";
html+="</div>";
html+="</li>";
}
//拼接距离最近5个店铺
$(".ctHandChooseShop").append(html);
isStroe=true;
}
}
});
return isStroe;
}
/**
* 若gps定位不到,或者gps关闭的情况下
* 推荐5家数据库里创建时间最早且是开店状态的店铺
*/
function findStoreEarliest(){
$.ajax({
type: 'post',
url:basePath+'/findStoreEarliest.htm',
async:false,//同步
cache:false,//清空缓存
success: function(data) {
//清空拼接数据
$(".ctHandChooseShop").html("");
var html="";
if(data!=null && data.length>0){
for(var i=0;i<data.length;i++){
html+="<li>";
html+="<i><img width='180px;' height='180px;' src=\""+data[i].storeImage+"\" /></i>";
html+="<div>";
html+="<h6>"+data[i].storeName+"</h6>";
html+="<p>"+data[i].storeArea+"</p>";
html+="<span><a href='javascript:;' onclick='goShop("+data[i].storeId+")'>进入此店铺</a></span>";
html+="</div>";
html+="</li>";
}
//拼接数据库里创建时间最早且是开店状态的店铺
$(".ctHandChooseShop").append(html);
}
}
});
}
//gps进入店铺
$(".goGpsShop").click(function(){
//exclusionsType=1表示过滤拦截器
window.location.href=basePath+"/initMain.htm?exclusionsType=1&storeId="+gpsStoreId;
});
/**
* 进入此店铺
* @param storeId 店铺id
*/
function goShop(storeId){
//exclusionsType=1表示过滤拦截器
window.location.href=basePath+"/initMain.htm?exclusionsType=1&storeId="+storeId;
}
/**
* 清除选择的店铺
*/
function cleanShop(){
var ctCity = document.getElementById("ctCity");
ctCity.innerHTML="请选择所在城市";
var ctVillage = document.getElementById("ctVillage");
ctVillage.innerHTML="请选择小区";
$(".ctHandChooseShop").hide();
$(".noStoreTips").hide();
}
//gps未定位到重新定位
function showLocation(){
$(".positionText").html("正在定位中...");
$(".positionBtn").css("display","none");
$(".positioning").removeClass("noAnimation");
//调用客户端gps定位
getLocation();
}
//手动选择地区
$("#ctCity").click(function(){
$(".ctChooseShop .ctGps").slideUp();
$(".ctChooseShop .ctLocation").slideUp();
});
//选择店铺
var locationStoreId;//全局变量存储当前定位店铺id
$(".selectAero").click(function(){
$(".ctChooseShop").addClass("open");
$("body").css("overflow","hidden");
//读取本地省市区json文件数据
$.ajax({
url:basePath+'/json/city.json',
async:false,//同步
cache:false,//清空缓存
success: function(data) {
UplinkData=data;
}
});
//选择小区
mobileSelect2 = new MobileSelect({
trigger: '#ctVillage',
wheels: [
{data: villageData}
],
callback:function(indexArr, data){
var _this = indexArr[0];
var _thisId = villageDataId[_this].id;
if(ctVillage.innerHTML!="暂无小区"){
//选中的小区id
var villageId=_thisId;
//根据选中的小区id查询店铺
var isStore=findStoreByVillageId(villageId);
console.log("isStore:"+isStore);
//alert("isStore:"+isStore);
if(isStore==true){//小区下面有店铺
//alert("小区下面有店铺");
//显示店铺
$(".ctHandChooseShop").show();
//隐藏无店铺提示信息
$(".noStoreTips").hide();
return ;
}else{//小区下面无店铺,现在定位距离最近的5个店铺
//gps查询最近5个店铺
var isGpsStore=findNearestDistancByGps(msg);
console.log("isGpsStore:"+isGpsStore);
//alert("isGpsStore:"+isGpsStore);
if(isGpsStore==true){
//alert("小区下面无店铺,现在定位距离最近的5个店铺");
//清空原来的,展示gps定位最近的5个
//显示无店铺提示信息
$(".noStoreTips").show();
//显示店铺
$(".ctHandChooseShop").show();
return ;
}else{//gps定位不到或者gps关闭则显示数据库创建最早且是开通的5个店铺
//alert("显示数据库创建最早且是开通的5个店铺");
//清空原来的,展示数据库创建最早且是开通的5个店铺
findStoreEarliest();
$(".noStoreTips").show();
//显示店铺
$(".ctHandChooseShop").show();
return ;
}
}
}
}
});
//选择省市区
mobileSelect1 = new MobileSelect({
trigger: '#ctCity',
wheels: [
{data: UplinkData}
],
callback:function(indexArr, data){
//显示清除
$(".ctChooseByHand h3 a").show();
//选中的地区id
var districtId=data[2].id;
//根据选中的区县编号查询小区
chooseVillage(districtId);
}
});
//测试用
// alert("id:"+$("#locaStoreId").val());
// alert("img:"+$("#locaStoreImage").val());
// alert("name:"+$("#locaStoreName").val());
// alert("area:"+$("#locaStoreArea").val());
//给当前定位店铺赋值
$(".positionStore .shop img").attr("src",$("#locaStoreImage").val());
$(".positionStore .shop h6").text($("#locaStoreName").val());
$(".positionStore .shop p").text($("#locaStoreArea").val());
locationStoreId=$("#locaStoreId").val();
});
//当前定位店铺进入店铺
$(".goLocationShop").click(function(){
//exclusionsType=1表示过滤拦截器
window.location.href=basePath+"/initMain.htm?exclusionsType=1&storeId="+locationStoreId;
});
//关闭选择店铺
$(".closeChooseShop").click(function(){
$(".ctChooseShop").removeClass("open");
$("body").removeAttr("style");
$(".positionStore").show();
$(".gpsStore").show();
//隐藏清除
$(".ctChooseByHand h3 a").hide();
})
//手动选择省市区,小区
//省级联动
var UplinkData;//省市区数据
var mobileSelect1;//选择省市区
var mobileSelect2;//选择小区
var villageData=['暂无小区'];//存储选中的小区名称
var villageDataId=[];//存储选中的小区id值
var ctVillage = document.getElementById("ctVillage");
/**
* 根据选中的区县编号查询小区
* @param districtId 区县id
*/
function chooseVillage(districtId){
$.ajax({
type: 'post',
url:basePath+'/getAllCountryByDid.htm',
async:false,//同步
cache:false,//清空缓存
data:{"districtId":districtId},
dataType:"json",
success: function(data) {
villageData=[];
if(data!=null && data.length>0){
for(var i=0;i<data.length;i++){
villageData.push(data[i].value);
villageDataId.push({id:data[i].id,value:data[i].value});
}
ctVillage.innerHTML = "请选择小区";
$(".noStoreTips").hide();
$(".ctHandChooseShop").hide();
}else{
villageData=['暂无小区'];
ctVillage.innerHTML = "暂无小区";
//清空原来的,展示gps定位最近的5个
var isGpsStore=findNearestDistancByGps(msg);
console.log("isGpsStore1:"+isGpsStore);
//alert("isGpsStore1:"+isGpsStore);
if(isGpsStore==true){//定位到gps定位最近的5个
//alert("定位到gps定位最近的5个");
//显示无店铺提示信息
$(".noStoreTips").show();
//显示店铺
$(".ctHandChooseShop").show();
return ;
}else{//gps定位不到或者gps关闭则显示数据库创建最早且是开通的5个店铺
//alert("显示数据库创建最早且是开通的5个店铺");
//清空原来的,展示数据库创建最早且是开通的5个店铺
findStoreEarliest();
//显示无店铺提示信息
$(".noStoreTips").show();
//显示店铺
$(".ctHandChooseShop").show();
return ;
}
}
mobileSelect2.updateWheel(0,villageData);
}
});
}
/**
* 根据小区id查询店铺信息
* @param villageId 小区id
*/
function findStoreByVillageId(villageId){
//判断是否有店铺
var isStroe=false;
$.ajax({
type: 'post',
url:basePath+'/findStoreByVillageId.htm',
async:false,//同步
cache:false,//清空缓存
data:{"villageId":villageId},
dataType:"json",
success: function(data) {
$(".ctHandChooseShop").html("");
var html="";
if(data!=null && data.length>0){
for(var i=0;i<data.length;i++){
html+="<li>";
html+="<i><img width='180px;' height='180px;' src=\""+data[i].storeImage+"\" /></i>";
html+="<div>";
html+="<h6>"+data[i].storeName+"</h6>";
html+="<p>"+data[i].storeArea+"</p>";
html+="<span><a href='javascript:;' onclick='goShop("+data[i].storeId+")'>进入此店铺</a></span>";
html+="</div>";
html+="</li>";
}
$(".ctHandChooseShop").append(html);
isStroe=true;
}
}
});
return isStroe;
}
java后台代码:controller层:
/**
* 用户未登录跳转店铺选择页面
* 初始化选择店铺页面
* @param req
* @param resp
* @return
*/
@RequestMapping("/initChooseShop")
public ModelAndView initChooseShop(HttpServletRequest req,HttpServletResponse resp){
ModelAndView mav=new ModelAndView();
try {
//返回页面
mav.setViewName("mobileNew/chooseShop");
} catch (Exception e) {
e.printStackTrace();
LOGGER.error("初始化选择店铺失败"+e.getMessage(),e);
}
return mav;
}
/**
* 公共方法:
* gps定位选择店铺
* @param req
* @param resp
* @param msg gps定位信息
* @param type 店铺类型 type=1当前定位type=2gps定位
* @return
*/
@RequestMapping(value="/chooseShop",produces="application/json;charset=UTF-8")
@ResponseBody
public String chooseShop(HttpServletRequest req,HttpServletResponse resp,String msg,String type){
//封装结果集
JSONArray result=new JSONArray();
//存储当前定位信息
Map<String, Object> locaMap=new HashMap<String, Object>();
//存储gps定位信息
Map<String, Object> gpsMap=new HashMap<String, Object>();
try {
//店铺id
String storeId=null;
//首先从cookie中取存储的店铺id(上一次浏览的记录)
Cookie[] cookies=req.getCookies();
if(cookies!=null){
for(Cookie cookie:cookies){
if(cookie!=null && "storeId".equals(cookie.getName())){
storeId=cookie.getValue();
break;
}
}
}
//此方法给用户未登录使用
//从cookie中取到店铺id
if(StringUtils.isNotEmpty(storeId)){
//从cookie中获得店铺信息(上一次浏览记录)
locaMap=positionStore.getStoreInfoFromCookie(storeId);
}else{
//js调用客户端定位,遍历获得的json数据
gpsMap=positionStore.getStoreInfoFromGPS(resp, msg);
}
//给首页,频道,分类定位gps选择店铺
//js调用客户端定位,遍历获得的json数据
if("2".equals(type)){
gpsMap=positionStore.getStoreInfoFromGPS(resp, msg);
}
result.add(locaMap);
result.add(gpsMap);
LOGGER.info("定位选择店铺result:"+result.toJSONString());
} catch (Exception e) {
e.printStackTrace();
LOGGER.error("定位选择店铺失败"+e.getMessage(),e);
}
return result.toJSONString();
}
/**
* 公共方法:
* 根据区县编号查询所有城市小区
* springmvc返回数据乱码解决:在requestMapping中添加produces="application/json;charset=UTF-8"
* @param districtId 区县编号
* @return
*/
@RequestMapping(value="/getAllCountryByDid",produces="application/json;charset=UTF-8")
@ResponseBody
public String getAllCountryByDid(Long districtId){
StringBuilder sb=new StringBuilder("[");
try {
//查询数据
List<VillageBean> villageList=customerServiceMapper.getAllCountryByDid(districtId);
//对数据重新封装
if(villageList!=null && !villageList.isEmpty()){
for(int i=0;i<villageList.size();i++){
sb=sb.append("{\"id\":\""+villageList.get(i).getVillageId()+"\",")
.append("\"value\":").append("\"" +villageList.get(i).getVillageName()+"\"}");
if(i!=villageList.size()-1){
sb.append(",");
}
}
}
sb.append("]");
} catch (Exception e) {
e.printStackTrace();
LOGGER.error("根据区县编号查询所有城市小区失败"+e.getMessage(),e);
}
return sb.toString();
}
/**
* 公共方法:
* 根据小区id查询店铺信息
* @param villageId 小区id
* @return
*/
@RequestMapping(value="/findStoreByVillageId",produces="application/json;charset=UTF-8")
@ResponseBody
public List<Map<String, Object>> findStoreByVillageId(Long villageId){
List<Map<String, Object>> resultMap=new ArrayList<Map<String,Object>>();
try {
//查询数据
List<StoreInfo> storeInfoList=storeService.findStoreByVillageId(villageId);
//重新组装数据
if(storeInfoList!=null && !storeInfoList.isEmpty()){
for(int i=0;i<storeInfoList.size();i++){
//店铺id
Long storeId=storeInfoList.get(i).getStoreId();
//店铺名称
String storeName=storeInfoList.get(i).getStoreName();
//店铺图片
String storeImage=storeInfoList.get(i).getStoreImage();
//获得店铺地区id
Long dId=storeInfoList.get(0).getStoreCounty();
//根据区县ID查询所属的城市和省份名称
AddressUtil addressUtil = districtService.queryAddressNameByDistrictId(dId);
//店铺所在的省市区
String storeArea=addressUtil.getProvinceName() + addressUtil.getCityName() + addressUtil.getDistrictName();
Map<String, Object> paramMap=new HashMap<String, Object>();
paramMap.put("storeId", storeId);
paramMap.put("villageId", villageId);
paramMap.put("storeName", storeName);
paramMap.put("storeImage", storeImage);
paramMap.put("storeArea", storeArea);
resultMap.add(paramMap);
}
}
} catch (Exception e) {
e.printStackTrace();
LOGGER.error("根据小区id查询店铺信息失败"+e.getMessage(),e);
}
return resultMap;
}
/***
* 公共方法:
* 根据gps定位,查询距离最近的5个店铺
* @param req
* @param resp
* @param msg gps定位信息
* @return
*/
@RequestMapping(value="/findNearestDistancByGps",produces="application/json;charset=UTF-8")
@ResponseBody
public List<Map<String, Object>> findNearestDistancByGps(HttpServletRequest req,HttpServletResponse resp,String msg){
List<Map<String, Object>> list=new ArrayList<Map<String,Object>>();
try {
//js调用客户端定位,遍历获得的json数据
if(StringUtils.isNotEmpty(msg)){
//将获得的定位信息特殊字符替换掉
msg=msg.replaceAll("@","\\+");
//解密定位信息
msg=Base64Util.decode(msg);
//将获得的msg转换为json数据
JSONObject obj=JSONObject.parseObject(msg);
//经度
String longitude=obj.getString("longitude");
//纬度
String latitude=obj.getString("latitude");
Map<String, Object> paramMap=new HashMap<String, Object>();
paramMap.put("longitudeDou", longitude);
paramMap.put("latitudeDou", latitude);
paramMap.put("distance", ConstantUtil.DISTANCE_RANG);
//根据指定经纬度与数据库多条经纬度计算距离,取距离最近的
List<StoreInfo> storeInfoList=storeService.findStoreDistance(paramMap);
if(storeInfoList!=null && !storeInfoList.isEmpty()){
for(int i=0;i<storeInfoList.size();i++){
//店铺id
Long storeId=storeInfoList.get(i).getStoreId();
//小区id
Long villageId=storeInfoList.get(i).getStoreVillage();
//店铺名称
String storeName=storeInfoList.get(i).getStoreName();
//店铺图片
String storeImage=storeInfoList.get(i).getStoreImage();
//店铺区县
Long dId=storeInfoList.get(i).getStoreCounty();
//根据区县ID查询所属的城市和省份名称
AddressUtil addressUtil = districtService.queryAddressNameByDistrictId(dId);
//店铺所在的省市区
String storeArea=addressUtil.getProvinceName() + addressUtil.getCityName() + addressUtil.getDistrictName();
Map<String, Object> resultMap=new HashMap<String, Object>();
resultMap.put("storeId", storeId);
resultMap.put("villageId", villageId);
resultMap.put("storeName", storeName);
resultMap.put("storeImage", storeImage);
resultMap.put("storeArea", storeArea);
list.add(resultMap);
}
}
}
} catch (Exception e) {
e.printStackTrace();
LOGGER.error("根据gps定位距离最近的5个店铺失败"+e.getMessage(),e);
}
return list;
}
/**
* 推荐5家数据库里创建时间最早且是开店状态的店铺
* @param req
* @param resp
* @return
*/
@RequestMapping(value="/findStoreEarliest",produces="application/json;charset=UTF-8")
@ResponseBody
public List<Map<String, Object>> findStoreEarliest(HttpServletRequest req,HttpServletResponse resp){
List<Map<String, Object>> list=new ArrayList<Map<String,Object>>();
try {
//查询数据
List<StoreInfo> storeInfoList=storeService.findStoreEarliest();
//重新组装数据
if(storeInfoList!=null && !storeInfoList.isEmpty()){
for(int i=0;i<storeInfoList.size();i++){
//店铺id
Long storeId=storeInfoList.get(i).getStoreId();
//小区id
Long villageId=storeInfoList.get(i).getStoreVillage();
//店铺名称
String storeName=storeInfoList.get(i).getStoreName();
//店铺图片
String storeImage=storeInfoList.get(i).getStoreImage();
//店铺区县
Long dId=storeInfoList.get(i).getStoreCounty();
//根据区县ID查询所属的城市和省份名称
AddressUtil addressUtil = districtService.queryAddressNameByDistrictId(dId);
//店铺所在的省市区
String storeArea=addressUtil.getProvinceName() + addressUtil.getCityName() + addressUtil.getDistrictName();
Map<String, Object> resultMap=new HashMap<String, Object>();
resultMap.put("storeId", storeId);
resultMap.put("villageId", villageId);
resultMap.put("storeName", storeName);
resultMap.put("storeImage", storeImage);
resultMap.put("storeArea", storeArea);
list.add(resultMap);
}
}
} catch (Exception e) {
e.printStackTrace();
LOGGER.error("数据库查询最早且是开通的店铺失败"+e.getMessage(),e);
}
return list;
}
公共方法PositionStoreImpl:
package com.qianjiang.m.common.service.impl;
import java.net.URLEncoder;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.annotation.Resource;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.qianjiang.common.util.ConstantUtil;
import com.qianjiang.customer.dao.CustomerAddressMapper;
import com.qianjiang.customer.service.CustomerServiceMapper;
import com.qianjiang.m.common.service.PositionStore;
import com.qianjiang.system.service.DistrictService;
import com.qianjiang.system.util.AddressUtil;
import com.qianjiang.thirdaudit.bean.StoreInfo;
import com.qianjiang.thirdaudit.service.StoreService;
import com.qianjiang.util.Base64Util;
import com.qianjiang.util.MyLogger;
/**
* 公共方法定位选择店铺
* @author somnus
*
*/
@Service("positionStore")
public class PositionStoreImpl implements PositionStore{
/** 记录日志对象 */
private static final MyLogger LOGGER = new MyLogger(PositionStoreImpl.class);
//店铺业务层
@Resource(name = "storeService")
private StoreService storeService;
//省市区业务层
@Resource(name = "DistrictService")
private DistrictService districtService;
//用户业务层
@Resource(name = "customerServiceMapper")
private CustomerServiceMapper customerServiceMapper;
//用户收获地址
@Resource(name = "customerAddressMapper")
private CustomerAddressMapper addressMapper;
// 店铺列表
private static Map<String, StoreInfo> storeInfos = new HashMap<String, StoreInfo>();
// 最后更新时间
private static Map<String, Date> lastUpdate = new HashMap<String, Date>();
// 一小时更新一次
private static long INTERVAR_TIME = 60 * 60 * 1000;
/**
* 公共方法:
* 从cookie中获得店铺信息
* @param storeId 店铺id
* @return
*/
public Map<String, Object> getStoreInfoFromCookie(String storeId) {
Map<String, Object> resultMap=new HashMap<String, Object>();
try {
StoreInfo storeInfo = null;
if (storeInfos.get(storeId) != null)
{
Date date = lastUpdate.get(storeId);
if (date != null && ((new Date()).getTime() - date.getTime() < INTERVAR_TIME))
{
storeInfo = storeInfos.get(storeId);
}
}
if (storeInfo == null)
{
//根据店铺id关联查询店铺跟小区信息,店铺状态开启
storeInfo = storeService.findStoreAndVillageById(Long.parseLong(storeId));
storeInfos.put(storeId, storeInfo);
lastUpdate.put(storeId, new Date());
}
if(storeInfo != null){
//店铺id
Long storeIds=storeInfo.getStoreId();
//小区id
Long villageId=storeInfo.getStoreVillage();
//店铺名称
String storeName=storeInfo.getStoreName();
//店铺图片
String storeImage=storeInfo.getStoreImage();
//店铺电话
String storeTel=storeInfo.getStoreTel();
//获取区县id
Long dId=storeInfo.getStoreCounty();
//获取QQ
String serviceQq=storeInfo.getServiceQq();
//根据区县ID查询所属的城市和省份名称
AddressUtil addressUtil = districtService.queryAddressNameByDistrictId(dId);
//店铺所在的省市区
String storeArea=addressUtil.getProvinceName() + addressUtil.getCityName() + addressUtil.getDistrictName();
//将查询结果封装到返回结果中
resultMap.put("storeId", storeIds);
resultMap.put("villageId", villageId);
resultMap.put("storeName", storeName);
resultMap.put("storeImage", storeImage);
resultMap.put("storeTel", storeTel);
resultMap.put("storeArea", storeArea);
resultMap.put("serviceQq", serviceQq);
//表示上一次浏览记录
resultMap.put("type", "1");
}
} catch (Exception e) {
e.printStackTrace();
LOGGER.error("从cookie中获得店铺信息失败"+e.getMessage(),e);
}
return resultMap;
}
/**
* 公共方法:
* 从gps定位信息中获得店铺信息
* @param resp 响应
* @param msg gps定位信息
* @return
*/
public Map<String, Object> getStoreInfoFromGPS(HttpServletResponse resp, String msg) {
Map<String, Object> resultMap=new HashMap<String, Object>();
try {
//js调用客户端定位,遍历获得的json数据
if(StringUtils.isNotEmpty(msg)){
//将获得的定位信息特殊字符替换掉
msg=msg.replaceAll("@","\\+");
//解密定位信息
msg=Base64Util.decode(msg);
//将获得的msg转换为json数据
JSONObject obj=JSONObject.parseObject(msg);
//经度
String longitude=obj.getString("longitude");
LOGGER.info("gps经度:"+longitude);
//纬度
String latitude=obj.getString("latitude");
LOGGER.info("gps纬度"+latitude);
Map<String, Object> paramMap=new HashMap<String, Object>();
paramMap.put("longitudeDou", longitude);
paramMap.put("latitudeDou", latitude);
// paramMap.put("distance", ConstantUtil.DISTANCE_RANG);
//根据指定经纬度与数据库多条经纬度计算距离,取距离最近的
List<StoreInfo> storeInfoList = storeService.findStoreDistance(paramMap);
if(storeInfoList!=null && !storeInfoList.isEmpty()){
//店铺id
String storeId=String.valueOf(storeInfoList.get(0).getStoreId());
//小区id
String villageId=String.valueOf(storeInfoList.get(0).getStoreVillage());
//店铺名称
String storeName=storeInfoList.get(0).getStoreName();
//店铺图片
String storeImage=storeInfoList.get(0).getStoreImage();
//店铺电话
String storeTel=storeInfoList.get(0).getStoreTel();
//店铺区县
Long dId = storeInfoList.get(0).getStoreCounty();
//根据区县ID查询所属的城市和省份名称
AddressUtil addressUtil = districtService.queryAddressNameByDistrictId(dId);
//店铺所在的省市区
String storeArea=addressUtil.getProvinceName() + addressUtil.getCityName() + addressUtil.getDistrictName();
//将查询结果封装到返回结果中
resultMap.put("storeId", storeId);
resultMap.put("villageId", villageId);
resultMap.put("storeName", storeName);
resultMap.put("storeImage", storeImage);
resultMap.put("storeArea", storeArea);
resultMap.put("storeTel", storeTel);
//表示gps定位数据
resultMap.put("type", "2");
}
}
} catch (Exception e) {
e.printStackTrace();
LOGGER.error("从gps定位信息中获得店铺信息失败"+e.getMessage(),e);
}
return resultMap;
}
/**
* 公共方法:
* 根据小区id查询店铺信息,店铺状态为开启
* @param storeInfoList 店铺信息
* @return
*/
public Map<String, Object> getStoreInfoFromVillageId(List<StoreInfo> storeInfoList) {
Map<String, Object> resultMap=new HashMap<String, Object>();
try {
//获得店铺id
Long storeId=storeInfoList.get(0).getStoreId();
//小区id
Long villageId=storeInfoList.get(0).getStoreVillage();
//获得店铺名称
String storeName=storeInfoList.get(0).getStoreName();
//店铺图片
String storeImage=storeInfoList.get(0).getStoreImage();
//获得店铺地区id
Long dId=storeInfoList.get(0).getStoreCounty();
//根据区县ID查询所属的城市和省份名称
AddressUtil addressUtil = districtService.queryAddressNameByDistrictId(dId);
//店铺所在的省市区
String storeArea=addressUtil.getProvinceName() + addressUtil.getCityName() + addressUtil.getDistrictName();
//将查询结果封装到返回结果中
resultMap.put("storeId", storeId);
resultMap.put("villageId", villageId);
resultMap.put("storeName", storeName);
resultMap.put("storeImage", storeImage);
resultMap.put("storeArea", storeArea);
resultMap.put("storeTel", storeInfoList.get(0).getStoreTel());
} catch (Exception e) {
e.printStackTrace();
LOGGER.error("根据小区id查询店铺信息失败"+e.getMessage(),e);
}
return resultMap;
}
//测试
public static void main(String[] args) {
Map<String, Object> resultMap=new HashMap<String, Object>();
resultMap.put("storeId", 3301);
resultMap.put("villageId", 1005);
resultMap.put("type", 1);
Map<String, Object> resultMap2=new HashMap<String, Object>();
resultMap2.put("storeId", 3302);
resultMap2.put("villageId", 1006);
resultMap2.put("type", 2);
System.out.println("type1:"+resultMap.toString());
System.out.println("type2:"+resultMap2.toString());
JSONArray array=new JSONArray();
array.add(resultMap);
array.add(resultMap2);
System.out.println("array:"+array.toJSONString());
System.out.println("array:"+array.toString());
}
}
xml文件获得数据:
<!-- 根据小区id查询店铺信息,店铺状态为开启 -->
<select id="findStoreByVillageId" parameterType="long" resultMap="BaseResultMap">
select
<include refid="Base_New_Column"/>
from t_supplier_store_info ts,t_village tv
where ts.store_village=tv.id
and (ts.is_bind='0' or ts.is_bind='1')
and ts.store_status='1'
and tv.id=#{villageId}
</select>
<!-- 根据店铺id关联查询店铺跟小区信息,店铺状态开启 -->
<select id="findStoreAndVillageById" parameterType="long" resultMap="BaseResultMap">
select ts.service_qq,
<include refid="Base_New_Column"/>
from t_supplier_store_info ts,t_village tv
where ts.store_village=tv.id
and (ts.is_bind='0' or ts.is_bind='1')
and ts.store_status='1'
and ts.store_id=#{storeId}
</select>
<!-- 根据指定经纬度与数据库多条经纬度计算距离,店铺状态开启 -->
<select id="findStoreDistance" parameterType="map" resultMap="BaseResultMap">
select
<include refid="Base_New_Column"/>,
ROUND(6378.138*2*ASIN(SQRT(POW(SIN((#{latitudeDou}*PI()/180-latitude*PI()/180)/2),2)+COS(#{latitudeDou}*PI()/180)*COS(latitude*PI()/180)*POW(SIN((#{longitudeDou}*PI()/180-longitude*PI()/180)/2),2)))*1000)
AS distance
from t_supplier_store_info ts,t_village tv
where ts.store_village=tv.id
and (ts.is_bind='0' or ts.is_bind='1')
and ts.store_status='1'
<!-- <![CDATA[ GROUP BY ts.store_id having distance <= #{distance}]]> -->
ORDER BY distance
LIMIT 5
</select>
<!-- 推荐5家数据库里创建时间最早且是开店状态的店铺 -->
<select id="findStoreEarliest" resultMap="BaseResultMap">
select
<include refid="Base_New_Column"/>
from t_supplier_store_info ts,t_village tv
where ts.store_village=tv.id
and (ts.is_bind='0' or ts.is_bind='1')
and ts.store_status='1'
ORDER BY ts.create_time
LIMIT 5
</select>
总结:
js调用客户端定位选择店铺,ios开发人员提供接口:
/**
* js调用客户端gps定位
*/
function getLocation(){
window.location='biguiyuan|location';
}
/**
* 返回回调数据:
*/
function locationResult(base64) {
//base64是编码定位数据
var str=base64
alert("str:"+str);
}
例如str:
ewogICJlcnJvckluZm8iIDogIiIsCiAgInByb3ZpbmNlIiA6ICLlub/kuJznnIEiLAogICJsb25naXR1ZGUiIDogIjExMy4yNjg3NTciLAogICJzdHJlZXQiIDogIuWdpOa0suS6jOihlyIsCiAgImxhdGl0dWRlIiA6ICIyMi45MjQ1MzMiLAogICJjaXR5Q29kZSIgOiAiMDc1NyIsCiAgImFkZHJlc3MiIDogIuW5v@S4nOecgeS9m@WxseW4gumhuuW@t@WMuuWMl@a7mOmVh@eip@ahguWbreaAu@mDqCIsCiAgImNpdHkiIDogIuS9m@WxseW4giIsCiAgIm51bWJlciIgOiAiMjjlj7ciLAogICJkaXN0cmljdCIgOiAi6aG65b635Yy6IiwKICAicG9pTmFtZSIgOiAi56Kn5qGC5Zut5oC76YOoIiwKICAiZXJyb3JDb2RlIiA6ICIiLAogICJjb3VudHJ5IiA6ICLkuK3lm70iLAogICJhZENvZGUiIDogIjQ0MDYwNiIsCiAgInRvd25zaGlwIiA6ICLljJfmu5jplYciCn0=
java后台接受前台传递的定位数据msg:
//返回数据格式:
{
"adCode": "440606",
"address": "广东省佛山市顺德区南平路靠近碧桂园总部",
"city": "佛山市",
"cityCode": "0757",
"country": "中国",
"district": "顺德区",
"errorCode": "0",
"errorInfo": "success",
"latitude": "22.924662",
"longitude": "113.26852",
"number": "28号",
"poiName": "碧桂园总部",
"province": "广东省",
"street": "坤洲二街",
"township": "北滘镇"
}
该案例数据库是mysql,故Mysql 拿指定经纬度与数据库多条经纬度进行距离计算,如下是项目中实际运用:
1.首先重前台获得传递的经纬度:
//将获得的定位信息特殊字符替换掉
msg=msg.replaceAll("@","\\+");
//解密定位信息
msg=Base64Util.decode(msg);
//将获得的msg转换为json数据
JSONObject obj=JSONObject.parseObject(msg);
//经度
String longitude=obj.getString("longitude");
LOGGER.info("gps经度:"+longitude);
//纬度
String latitude=obj.getString("latitude");
LOGGER.info("gps纬度"+latitude);
Map<String, Object> paramMap=new HashMap<String, Object>();
paramMap.put("longitudeDou", longitude);
paramMap.put("latitudeDou", latitude);
//根据指定经纬度与数据库多条经纬度计算距离,取距离最近的
List<StoreInfo> storeInfoList = storeService.findStoreDistance(paramMap);
2.调用xml文件获得数据:
<!-- 根据指定经纬度与数据库多条经纬度计算距离,店铺状态开启 -->
<select id="findStoreDistance" parameterType="map" resultMap="BaseResultMap">
select
<include refid="Base_New_Column"/>,
ROUND(6378.138*2*ASIN(SQRT(POW(SIN((#{latitudeDou}*PI()/180-latitude*PI()/180)/2),2)+COS(#{latitudeDou}*PI()/180)*COS(latitude*PI()/180)*POW(SIN((#{longitudeDou}*PI()/180-longitude*PI()/180)/2),2)))*1000)
AS distance
from t_supplier_store_info ts,t_village tv
where ts.store_village=tv.id
and (ts.is_bind='0' or ts.is_bind='1')
and ts.store_status='1'
ORDER BY distance
LIMIT 5
</select>
mysql执行案例:
/**mobile端首页定位选择店铺**/
/**
一般地图上显示的坐标顺序为:纬度在前(范围-90~90),经度在后(范围-180~180)
如:39.929101,116.443938
longitude 经度
latitude 纬度
以下计算公式单位米
当前经度:113.26852
当前纬度:22.924662
*/
/**mysql根据给定的经纬度与数据库多条经纬度计算距离*/
select ts.store_id, ts.customerId, ts.store_name,ts.store_tel,ts.store_status,ts.check_status,ts.billing_cycle,
ts.company_contact_name,ts.company_contact_tel,
ts.store_province,ts.store_city,ts.store_county,ts.store_village,
ts.longitude,ts.latitude,ts.store_address,ts.is_default_store,ts.store_image,ts.is_bind,
ts.create_time,ts.mod_time,ts.start_businesshour,ts.end_businesshour,
tv.name as "village_name",tv.code as "village_code",
ROUND(6378.138*2*ASIN(SQRT(POW(SIN((22.924662*PI()/180-latitude*PI()/180)/2),2)+COS(22.924662*PI()/180)*COS(latitude*PI()/180)*POW(SIN((113.26852*PI()/180-longitude*PI()/180)/2),2)))*1000)
AS distance
from t_supplier_store_info ts,t_village tv
where ts.store_village=tv.id
and (ts.is_bind='0' or ts.is_bind='1')
and ts.store_status='1'
ORDER BY distance
LIMIT 5
mysql执行结果:
数据库设计注意经纬度):
CREATE TABLE `t_supplier_store_info` (
`store_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '店铺ID',
`longitude` varchar(255) DEFAULT NULL COMMENT '经度',
`latitude` varchar(255) DEFAULT NULL COMMENT '纬度',
PRIMARY KEY (`store_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1151 DEFAULT CHARSET=utf8 COMMENT='店铺基本信息表';
Mysql 拿指定经纬度与数据库多条经纬度进行距离计算,计算公式:
公式如下,单位米:
第一点经纬度:lng1 lat1
第二点经纬度:lng2 lat2
round(6378.138*2*asin(sqrt(pow(sin(
(lat1*pi()/180-lat2*pi()/180)/2),2)+cos(lat1*pi()/180)*cos(lat2*pi()/180)*
pow(sin( (lng1*pi()/180-lng2*pi()/180)/2),2)))*1000)
log1是已知经度,lat1是已知纬度,lng2是 数据库定义字段经度, lat2是数据库定义字段纬度