map更新

This commit is contained in:
aiShuiJiaoDeXioShou 2024-09-02 19:55:55 +08:00
parent 44cd1efde2
commit 13938e14cd
15 changed files with 391 additions and 187 deletions

4
acdr-ui/env/.env vendored
View File

@ -7,8 +7,8 @@ VITE_WX_APPID = 'wxf2c6d4b7361366b4'
# h5部署网站的base配置到 manifest.config.ts 里的 h5.router.base
VITE_APP_PUBLIC_BASE=/acdr/
VITE_SERVER_BASEURL = 'http://127.0.0.1:28184/api'
VITE_UPLOAD_BASEURL = 'http://127.0.0.1:28184'
VITE_SERVER_BASEURL = 'http://47.99.70.12:28184/api'
VITE_UPLOAD_BASEURL = 'http://47.99.70.12:28184'
VITE_OSS_BASEURL = 'http://116.204.119.171:9000/linghe'
# h5是否需要配置代理

View File

@ -123,7 +123,12 @@ export default defineManifestConfig({
setting: {
urlCheck: false,
},
requiredPrivateInfos: ["getLocation"],
requiredPrivateInfos: ["getLocation","chooseLocation"],
permission: {
"scope.userLocation": {
"desc": "你的位置信息将用于定位效果展示"
}
},
usingComponents: true,
lazyCodeLoading: 'requiredComponents',
// __usePrivacyCheck__: true,

View File

@ -3,7 +3,7 @@
layout: "default",
style: {
navigationBarTitleText: "地图组件",
// ;
//
navigationStyle: "custom",
},
}
@ -18,56 +18,41 @@
</u-row>
<u-row class="myInfoRow">
<u-col span="12">
<textarea
v-show="geocode"
disabled="true"
:value="position"
placeholder="未加载出位置信息"
></textarea>
<textarea v-show="geocode" disabled="true" :value="position" placeholder="未加载出位置信息"></textarea>
</u-col>
</u-row>
<u-row>
<u-col span="6">
<u-button type="success" shape="square" @click="changePosition"
>刷新当前位置</u-button
>
<u-button type="success" shape="square" @click="changePosition">刷新当前位置</u-button>
</u-col>
<u-col span="6">
<u-button type="success" shape="square" @click="returnPosition"
>返回定位位置</u-button
>
<u-button type="success" shape="square" @click="returnPosition">返回定位位置</u-button>
</u-col>
</u-row>
<br />
<u-row>
<!-- style内嵌标签的写法才能让app端地图全屏展示 -->
<u-col span="12">
<map
id="myMap"
ref="myMap"
:longitude="longitude"
:latitude="latitude"
:scale="scale"
@tap="clickmap"
:markers="covers"
style="width: 100%; height: 100vh"
></map>
<map id="myMap" ref="myMap" :longitude="longitude" :latitude="latitude" :scale="scale" @tap="clickmap"
:markers="covers" style="width: 100vw; height: 100vh"></map>
</u-col>
</u-row>
</view>
</template>
<script setup>
import { ref, reactive, onMounted } from "vue";
import { toast } from "@/utils/commUtils"
import { ref, reactive, onMounted } from "vue"
const longitude = ref(0); //
const latitude = ref(0);
const originalLongitude = ref(0); //
const originalLatitude = ref(0);
const scale = ref("16");
const geocode = ref(true);
const position = ref(""); //
const originalPosition = ref(""); //
const longitude = ref(0) //
const latitude = ref(0)
const originalLongitude = ref(0) //
const originalLatitude = ref(0)
const scale = ref("16")
const geocode = ref(true)
const position = ref("") //
const originalPosition = ref("") //
const covers = reactive([
{
@ -82,91 +67,96 @@ const covers = reactive([
color: "#FB3109",
},
},
]);
])
const clickmap = () => {
uni.chooseLocation({
success: (res) => {
position.value = "位置名称:" + res.name + " 详细地址:" + res.address;
longitude.value = res.longitude;
latitude.value = res.latitude;
covers[0].longitude = res.longitude;
covers[0].latitude = res.latitude;
position.value = "位置名称:" + res.name + " 详细地址:" + res.address
longitude.value = res.longitude
latitude.value = res.latitude
covers[0].longitude = res.longitude
covers[0].latitude = res.latitude
},
fail: (err) => {
uni.showToast({
title: "获取位置失败",
});
console.log(err)
toast("获取位置失败")
},
});
};
})
}
const returnPosition = () => {
position.value = originalPosition.value;
longitude.value = originalLongitude.value;
latitude.value = originalLatitude.value;
covers[0].longitude = originalLongitude.value;
covers[0].latitude = originalLatitude.value;
};
position.value = originalPosition.value
longitude.value = originalLongitude.value
latitude.value = originalLatitude.value
covers[0].longitude = originalLongitude.value
covers[0].latitude = originalLatitude.value
}
const changePosition = () => {
console.log("坐标刷新成功");
console.log("坐标刷新成功")
uni.showToast({
title: "坐标刷新成功",
});
};
})
}
const getLocation = () => {
uni.showLoading({
title: "正在获取定位",
});
})
uni.getLocation({
type: "gcj02",
timeout: 1000,
geocode: geocode.value,
success: (res) => {
console.log("@@@@", res);
uni.hideLoading();
longitude.value = res.longitude;
latitude.value = res.latitude;
originalLongitude.value = res.longitude;
originalLatitude.value = res.latitude;
covers[0].longitude = res.longitude;
covers[0].latitude = res.latitude;
uni.hideLoading()
longitude.value = res.longitude
latitude.value = res.latitude
originalLongitude.value = res.longitude
originalLatitude.value = res.latitude
covers[0].longitude = res.longitude
covers[0].latitude = res.latitude
const { address } = res;
const { country, province, city, district, street, streetNum, poiName } = address;
const myPosition = `${country}-${province}-${city}-${district}-${street}-${streetNum}-${poiName}`;
position.value = myPosition;
originalPosition.value = myPosition;
// const { address } = res
// const { country, province, city, district, street, streetNum, poiName } = address
// const myPosition = `${country}-${province}-${city}-${district}-${street}-${streetNum}-${poiName}`
// position.value = myPosition
// originalPosition.value = myPosition
},
fail: (err) => {
console.log(err);
uni.hideLoading();
console.log(err)
uni.hideLoading()
uni.showModal({
title: "提示",
content: "位置信息获取失败(请确定定位功能是否打开)",
showCancel: false,
});
})
},
});
};
})
}
onMounted(() => {
getLocation();
});
getLocation()
})
</script>
<style lang="scss" scoped>
#myMap {
width: 750rpx;
.objView {
width: 100% height: 100%
}
#myMap {
width: 100%
}
/* 信息栏高度 */
.myInfoRow {
height: 50px;
height: 50px
}
/* 让地址栏通栏展示 */
textarea {
width: 100%;
width: 100%
}
</style>

View File

@ -89,8 +89,14 @@
},
"usingComponents": true,
"requiredPrivateInfos": [
"getLocation"
"getLocation",
"chooseLocation"
],
"permission": {
"scope.userLocation": {
"desc": "你的位置信息将用于定位效果展示"
}
},
"lazyCodeLoading": "requiredComponents"
},
"mp-alipay": {

View File

@ -17,4 +17,8 @@
import Map from '@/components/Map.vue';
</script>
<style lang="scss" scoped></style>
<style lang="scss" scoped>
.root {
width: 100%;
}
</style>

View File

@ -10,24 +10,14 @@
<template>
<view class="my-page-container">
<view
class="background"
:style="{ backgroundImage: `url(${imgUrl('@/static/my/my-bg.png')})` }"
></view>
<view class="background" :style="{ backgroundImage: `url(${imgUrl('@/static/my/my-bg.png')})` }"></view>
<image :src="imgUrl('@/static/my/cat-dog.png')" class="cat-dog"></image>
<view class="bg"></view>
<view class="my-avatar">
<wd-img
:width="100"
:height="100"
round
mode="aspectFill"
:src="
userInfo.avatar == ''
<wd-img :width="100" :height="100" round mode="aspectFill" :src="userInfo.avatar == ''
? imgUrl('@/static/my/avatar.jpg')
: baseUrl + userInfo.avatar
"
></wd-img>
"></wd-img>
<view class="info">
<view class="name">{{ userInfo.nickname }}</view>
<view class="description">爱猫猫爱狗狗</view>
@ -42,27 +32,11 @@
</view>
<view class="services-container card">
<view
class="service-item"
v-for="(service, index) in services"
@click="toPath(service.path)"
:key="index"
>
<view class="service-item" v-for="(service, index) in services" @click="toPath(service.path)" :key="index">
<view class="service-box">
<wd-img
v-if="service.label == '我的服务'"
:width="42"
:height="40"
:src="imgUrl(service.icon)"
class="service-icon"
/>
<wd-img
v-else
:width="38"
:height="40"
:src="imgUrl(service.icon)"
class="service-icon"
/>
<wd-img v-if="service.label == '我的服务'" :width="42" :height="40" :src="imgUrl(service.icon)"
class="service-icon" />
<wd-img v-else :width="38" :height="40" :src="imgUrl(service.icon)" class="service-icon" />
</view>
<view class="service-label">{{ service.label }}</view>
</view>
@ -78,12 +52,7 @@
<view class="pets-container card">
<view class="pets-title">我的宠物</view>
<view class="pets-list scroll-x overflow-x-auto" scroll-x>
<view
class="pet-item"
v-for="(pet, index) in pets"
@click="editPet(pet)"
:key="index"
>
<view class="pet-item" v-for="(pet, index) in pets" @click="editPet(pet)" :key="index">
<wd-img :width="60" :height="60" round :src="pet.icon" class="pet-avatar" />
<view class="pet-label">{{ pet.name }}</view>
</view>
@ -98,12 +67,7 @@
<view class="settings-container card">
<view class="list">
<view
class="list-item"
v-for="(item, index) in items"
@click="toPath(item.to)"
:key="index"
>
<view class="list-item" v-for="(item, index) in items" @click="toPath(item.to)" :key="index">
<view class="icon">
<image :src="imgUrl(item.icon)" class="item-icon" />
</view>
@ -118,52 +82,74 @@
</template>
<script setup>
import { ref } from "vue";
import { useUserStore } from "@/store/user";
import { baseUrl, imgUrl } from "@/utils/commUtils";
import { httpGet } from "@/utils/http"; //
import { ref } from "vue"
import { useUserStore } from "@/store/user"
import { baseUrl, imgUrl, toast } from "@/utils/commUtils"
import { httpGet } from "@/utils/http" //
const userStore = useUserStore();
const userStore = useUserStore()
const userInfo = userStore.userInfo;
const userInfo = userStore.userInfo
const stats = [
const stats = ref(
[
{ number: 0, label: "粉丝" },
{ number: 0, label: "关注" },
{ number: 0, label: "收藏" },
{ number: 0, label: "获赞" },
];
]
)
const services = [
{ icon: "@/static/my/order.png", label: "我的订单", path: "/pages/order/index" },
{ icon: "@/static/my/pet.png", label: "我的服务", path: "/pages/service/my-service" },
{ icon: "@/static/my/wash.png", label: "我的评价", path: "/pages/order/index" },
{ icon: "@/static/my/service.png", label: "售后服务", path: "/pages/order/index" },
];
]
const pets = ref([]);
const pets = ref([])
onShow(() => {
fetchPets();
});
onShow(async () => {
await fetchActivities()
await fetchPets()
})
//
const fetchActivities = async () => {
try {
const response = await httpGet("/posts/community")
if (response.code == 200) {
let index = 0
for (const key in response.data) {
if (response.data[key]) {
stats.value[index] = { number: response.data[key], label: key }
}
}
} else {
console.log(response)
}
} catch (error) {
console.log(error)
}
}
const fetchPets = async () => {
try {
const response = await httpGet("/petInfo/select", { userId: userStore.userInfo.id });
const response = await httpGet("/petInfo/select", { userId: userStore.userInfo.id })
pets.value = response.records.map((pet) => ({
...pet,
icon: baseUrl + pet.profileUrl,
}));
}))
} catch (error) {
uni.showToast({ title: "网络错误,请重试", icon: "error" });
uni.showToast({ title: "网络错误,请重试", icon: "error" })
}
};
}
const editPet = (pet) => {
uni.navigateTo({
url: `/pages/pet/pet-add-page?id=${pet.id}&name=${pet.name}&icon=${pet.icon}&breed=${pet.breed}&color=${pet.color}&birthday=${pet.birthday}&gender=${pet.gender}&userId=${pet.userId}`,
});
};
})
}
const items = [
{ icon: "@/static/my/send.png", label: "我的发布", to: "/pages/publish/index" },
@ -185,13 +171,13 @@ const items = [
{ icon: "@/static/my/address.png", label: "我的地址", to: "/pages/address/index" },
{ icon: "@/static/my/settings.png", label: "设置", to: "/pages/settings/index" },
{ icon: "@/static/my/address.png", label: "地址", to: "/pages/map/index" },
];
]
const toPath = (path) => {
uni.navigateTo({
url: path,
});
};
})
}
</script>
<style lang="scss" scoped>

View File

@ -0,0 +1,60 @@
import { toast } from "@/utils/commUtils";
import { httpGet } from "@/utils/http";
// 通过高德地图api获取详细位置
const getReverseGeocoding = async (longitude, latitude) => {
try {
const res = await uni.request({
url: `https://restapi.amap.com/v3/geocode/regeo?location=${longitude},${latitude}&key=${config.AMapKey}`
});
if (res[1].data.status === "1" && res[1].data.regeocode) {
const address = res[1].data.regeocode.formatted_address;
return address; // 返回详细地址信息
} else {
throw new Error("无法获取详细地址");
}
} catch (err) {
console.error("逆地理编码请求失败:", err);
throw err; // 抛出错误以便调用者处理
}
}
// 通过后端服务器获取详细位置
const getMapDetailAddress = async (longitude, latitude) => {
try {
const res = await httpGet("/map/detail", {
longitude,
latitude
})
if (res.code == 200) {
return res.data;
}
return null
} catch (err) {
console.error("获取详细地址信息失败:", err);
throw err;
}
}
// 获取当前经纬度信息
const getLocation = async () => {
try {
const res = await new Promise((resolve, reject) => {
uni.chooseLocation({
success: (res) => {
resolve(res); // 成功时返回结果
},
fail: (err) => {
reject(err); // 失败时抛出错误
},
});
});
return res; // 返回获取到的地理位置信息
} catch (err) {
console.log(err);
toast("获取位置失败");
throw err; // 抛出错误,供调用者处理
}
}

View File

@ -32,6 +32,10 @@
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>

View File

@ -0,0 +1,66 @@
package com.yskj.acdr.master.address.controller;
import com.alibaba.fastjson2.JSONObject;
import com.yskj.acdr.common.response.GlobalResponse;
import com.yskj.acdr.master.address.service.ServiceAddressService;
import jakarta.annotation.Resource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
@Controller("/map")
public class ServiceAddressController {
private static final Logger log = LoggerFactory.getLogger(ServiceAddressController.class);
@Resource
private ServiceAddressService addressService;
/**
* @param longitude 经度
* @param latitude 纬度
* @return {
* "addressComponent": {
* "city": "深圳市",
* "province": "广东省",
* "adcode": "440304",
* "district": "福田区",
* "towncode": "440304008000",
* "streetNumber": {
* "number": "218号",
* "location": "114.059260,22.542982",
* "direction": "西",
* "distance": "33.663",
* "street": "福中路"
* },
* "country": "中国",
* "township": "莲花街道",
* "businessAreas": [
* []
* ],
* "building": {
* "name": [],
* "type": []
* },
* "neighborhood": {
* "name": [],
* "type": []
* },
* "citycode": "0755"
* },
* "formatted_address": "广东省深圳市福田区莲花街道福中三路深圳市民中心"
* }
*/
@GetMapping("/detail")
public GlobalResponse<JSONObject> mapDetail(double longitude, double latitude) {
try {
return GlobalResponse.success(addressService.getReverseGeocoding(longitude, latitude));
} catch (Exception e) {
log.error(e.getMessage());
return GlobalResponse.failure("获取地址失败!");
}
}
}

View File

@ -0,0 +1,35 @@
package com.yskj.acdr.master.address.service;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson2.JSONObject;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
@Service
public class ServiceAddressService {
@Value("${map.amapkey}")
private String amap;
public JSONObject getReverseGeocoding(double longitude, double latitude) throws Exception {
String url = String.format("https://restapi.amap.com/v3/geocode/regeo?location=%f,%f&key=%s", longitude, latitude, amap);
// 发送HTTP请求
HttpResponse response = HttpUtil.createGet(url).execute();
// 解析返回的JSON数据
JSONObject jsonObject = JSONObject.parseObject(response.body());
String status = jsonObject.getString("status");
if ("1".equals(status)) {
JSONObject regeocode = jsonObject.getJSONObject("regeocode");
if (regeocode != null) {
return regeocode; // 返回详细地址信息
}
}
throw new Exception("无法获取详细地址");
}
}

View File

@ -532,5 +532,42 @@ public class CommunityController {
return GlobalResponse.success(result);
}
// 获取用户的社交信息
@GetMapping("/community")
public GlobalResponse<Map<Object, Object>> social() {
long userId = StpUtil.getLoginIdAsLong();
// 获取被关注的信息
Long fans = followsMapper.selectCount(
new LambdaQueryWrapper<Follows>()
.eq(Follows::getFollowingId, userId)
);
// 关注已关注的信息
Long follow = followsMapper.selectCount(
new LambdaQueryWrapper<Follows>()
.eq(Follows::getFollowerId, userId)
);
// 获取收藏的信息数量
Long collection = favoritesMapper.selectCount(
new LambdaQueryWrapper<Favorites>()
.eq(Favorites::getUserId, userId)
);
// 获取被点赞的信息数量
Long likes = likesMapper.selectCount(
new LambdaQueryWrapper<Likes>()
.eq(Likes::getUserId, userId)
);
return GlobalResponse.success(
MapUtil.builder()
.put("粉丝",fans)
.put("关注",follow)
.put("收藏",collection)
.put("获赞",likes).map()
);
}
}

View File

@ -1,34 +1,30 @@
package com.yskj.acdr.master.community.entity;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import java.time.LocalDateTime;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import lombok.experimental.Accessors;
import com.baomidou.mybatisplus.annotation.*;
import io.swagger.annotations.ApiModel;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* <p>
* <p>
*
* </p>
*
* @author 林河
* @since 2024-08-12
*/
@Getter
@Setter
@ToString
@Accessors(chain = true)
@TableName("acdr_favorites")
@ApiModel(value = "Favorites对象", description = "")
public class Favorites implements Serializable {
*
* @author 林河
* @since 2024-08-12
*/
@Getter
@Setter
@ToString
@Accessors(chain = true)
@TableName("acdr_favorites")
@ApiModel(value = "Favorites对象", description = "")
public class Favorites implements Serializable {
private static final long serialVersionUID = 1L;

View File

@ -14,6 +14,7 @@ import jakarta.annotation.Resource;
import jakarta.validation.constraints.NotBlank;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
@ -35,6 +36,9 @@ public class UserController {
@Autowired
private GlobalRedisCache<String> redisCache;
@Value("${is-starter-shop:false}")
private Boolean isStarterShop;
/**
* 获取验证码
@ -66,7 +70,7 @@ public class UserController {
GlobalResponse<String> login = usersService.login(phone, code);
String userShop;
UserShopInfo userShopInfo = null;
if (StrUtil.isNotBlank(login.getData())) {
if (StrUtil.isNotBlank(login.getData()) && isStarterShop) {
// 登录商城账户
userShop = usersService.loginShop(phone);
userShopInfo = JSONUtil.parse(userShop).toBean(UserShopInfo.class);

View File

@ -104,6 +104,8 @@ management:
exposure:
include: '*'
is-starter-shop: false
# 自定义配置
path:
home: D:\system\acdr\

View File

@ -2,6 +2,7 @@ package com.yskj.acdr;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import com.yskj.acdr.master.address.service.ServiceAddressService;
import com.yskj.acdr.master.user.entity.AuthenticationResponse;
import com.yskj.acdr.master.user.service.AuthenticationService;
import lombok.extern.slf4j.Slf4j;
@ -18,6 +19,9 @@ public class AcdrTest {
@Autowired
private AuthenticationService service;
@Autowired
ServiceAddressService addressService;
// 测试实名认证
@Test
void TestAuthenticationService() {
@ -62,4 +66,9 @@ public class AcdrTest {
log.info(post);
}
@Test
void map() throws Exception {
System.out.println(addressService.getReverseGeocoding(114.05956, 22.54286));
}
}