20 changed files with 3876 additions and 1863 deletions
File diff suppressed because it is too large
@ -0,0 +1,47 @@ |
|||
import request from '@/utils/http.ts' |
|||
/** |
|||
* 获取组织树 |
|||
* @param params deptName |
|||
* |
|||
* @returns |
|||
*/ |
|||
export const getAgencyList = (params: object) => { |
|||
return request.get('/system/dept/listForH5', params) |
|||
} |
|||
/** |
|||
* 获取房型 |
|||
* @param params apartmentId |
|||
* |
|||
* @returns |
|||
*/ |
|||
export const getHouseTypeList = (params: object) => { |
|||
return request.get('/asdh5/chooseRoom/getHouseTypeListForH5', params) |
|||
} |
|||
/** |
|||
* 地图右侧列表 |
|||
* @param params apartmentId |
|||
* |
|||
* @returns |
|||
*/ |
|||
export const getHouseTypeMap = (params: object) => { |
|||
return request.get('/mz/choose/list-house-type-with-count', params) |
|||
} |
|||
/** |
|||
* 地图点位 |
|||
* @param params apartmentId |
|||
* |
|||
* @returns |
|||
*/ |
|||
export const getMapPoint = (params: object) => { |
|||
return request.get('/mz/choose/list-house-with-count', params) |
|||
} |
|||
/** |
|||
* 地图点位 |
|||
* @param params apartmentId |
|||
* |
|||
* @returns |
|||
*/ |
|||
export const getDict = (params: object) => { |
|||
return request.get('/system/dict/data/getDict', params) |
|||
} |
|||
|
@ -0,0 +1,138 @@ |
|||
<template> |
|||
<div class="map-container" ref="mapContainer"></div> |
|||
</template> |
|||
|
|||
<script setup> |
|||
import { ref, onMounted, watch } from "vue"; // 添加watch |
|||
import AMapLoader from "@amap/amap-jsapi-loader"; |
|||
|
|||
const props = defineProps({ |
|||
center: { |
|||
type: Array, |
|||
default: () => [120.287882, 36.178786], |
|||
}, |
|||
zoom: { |
|||
type: Number, |
|||
default: 10.5, |
|||
}, |
|||
//地图点位 |
|||
markers: { |
|||
type: Array, |
|||
default: () => [], |
|||
}, |
|||
}); |
|||
|
|||
const mapContainer = ref(null); |
|||
let map = null; |
|||
|
|||
let markers = []; // 存储当前地图上的marker实例 |
|||
|
|||
// 清除所有点位 |
|||
const clearMarkers = () => { |
|||
if (map) { |
|||
map.remove(markers); |
|||
markers = []; |
|||
} |
|||
}; |
|||
|
|||
// 添加点位 |
|||
const emit = defineEmits(['marker-click']) // 添加事件发射器 |
|||
|
|||
const addMarkers = () => { |
|||
clearMarkers(); |
|||
props.markers.forEach((marker, index) => { |
|||
const content = ` |
|||
<div style=" |
|||
background: ${marker.color || "#3388FF"}; |
|||
color: white; |
|||
display: inline-flex; |
|||
align-items: center; |
|||
justify-content: center; |
|||
font-size: 12px; |
|||
box-shadow: 0 2px 4px rgba(0,0,0,0.3); |
|||
padding: 8px; |
|||
border-radius: 15px; |
|||
white-space: nowrap; |
|||
"> |
|||
${marker.name || ""} |
|||
<span style=" |
|||
background: #ffffff; |
|||
color: ${marker.color || "#3388FF"}; |
|||
border-radius: 10px; |
|||
min-width: 20px; |
|||
height: 20px; |
|||
display: inline-flex; |
|||
align-items: center; |
|||
justify-content: center; |
|||
font-size: 10px; |
|||
padding: 0 4px; |
|||
margin-left: 4px; |
|||
box-sizing: border-box; |
|||
font-weight: bold; |
|||
">${marker.total || ''}间</span> |
|||
</div> |
|||
`; |
|||
|
|||
const amarker = new AMap.Marker({ |
|||
position: [marker.longitude, marker.latitude], |
|||
content: content, |
|||
offset: new AMap.Pixel(-15, -15), |
|||
}); |
|||
|
|||
// 添加点击事件 |
|||
amarker.on('click', () => { |
|||
emit('marker-click', { |
|||
marker, |
|||
index, |
|||
position: [marker.longitude, marker.latitude] |
|||
}) |
|||
map.setCenter([marker.longitude, marker.latitude]); |
|||
map.setZoom(12); |
|||
}); |
|||
markers.push(amarker); |
|||
map.add(amarker); |
|||
}); |
|||
}; |
|||
|
|||
onMounted(async () => { |
|||
try { |
|||
const AMap = await AMapLoader.load({ |
|||
key: import.meta.env.VITE_AMAP_KEY, |
|||
version: "2.0", |
|||
plugins: ["AMap.ToolBar", "AMap.Scale", "AMap.Marker"], // 添加Marker插件 |
|||
}); |
|||
|
|||
map = new AMap.Map(mapContainer.value, { |
|||
viewMode: "2D", |
|||
zoom: props.zoom, |
|||
center: props.center, |
|||
}); |
|||
|
|||
// 添加控件 |
|||
map.addControl(new AMap.ToolBar()); |
|||
map.addControl(new AMap.Scale()); |
|||
|
|||
// 初始添加点位 |
|||
addMarkers(); |
|||
|
|||
// 监听markers变化 |
|||
watch( |
|||
() => props.markers, |
|||
() => { |
|||
addMarkers(); |
|||
}, |
|||
{ deep: true } |
|||
); |
|||
} catch (error) { |
|||
console.error("地图加载失败:", error); |
|||
} |
|||
}); |
|||
</script> |
|||
|
|||
<style scoped> |
|||
.map-container { |
|||
width: 100%; |
|||
height: 100vh; |
|||
min-height: 400px; |
|||
} |
|||
</style> |
@ -1,36 +0,0 @@ |
|||
<template> |
|||
<div class="bg-syGreyBg overflow-hidden"> |
|||
<div class="md:w-[1200px] m-auto md:mt-[66px] w-[390px] mt-2"> |
|||
<div class="w-[350px] m-auto md:w-[1200px]"> |
|||
<div |
|||
class="md:w-[86px] mt-8 md:h-[50px] w-[75px] h-[38px] rounded-3xl border border-gray-200 flex justify-center items-center"> |
|||
<span class="text-secondary md:text-[18px] text-[14px] font-normal">FAQs</span> |
|||
</div> |
|||
<div |
|||
class="mt-4 md:w-[629px] md:h-[54px] md:text-5xl font-medium md:whitespace-nowrap w-[350px] h-[80px] text-3xl"> |
|||
Frequently Asked Questions |
|||
</div> |
|||
<div class="mt-4 w-full md:text-lg font-normal text-base"> |
|||
We understand that you may have some questions about insurance. We have compiled a list of frequently asked |
|||
questions to help you get the information you need. If you have any other questions, please do not hesitate to |
|||
contact us. |
|||
</div> |
|||
</div> |
|||
<Faqs :type="2" /> |
|||
</div> |
|||
<!-- footer背景 --> |
|||
<FooterBg /> |
|||
</div> |
|||
</template> |
|||
<script setup lang="ts"> |
|||
import { useUserStore } from '@/stores/user' |
|||
import { getCardList } from '@/api/test' |
|||
const store = useUserStore() |
|||
const getInfo = async () => { |
|||
const res = await getCardList() |
|||
console.log(res, store) |
|||
} |
|||
getInfo() |
|||
</script> |
|||
|
|||
<style scoped></style> |
@ -0,0 +1,141 @@ |
|||
<template> |
|||
<div class="flex items-center gap-5"> |
|||
<el-dropdown trigger="click"> |
|||
<span class="el-dropdown-link"> |
|||
{{ cityName }}<el-icon class="el-icon--right"><arrow-down /></el-icon> |
|||
</span> |
|||
<template #dropdown> |
|||
<el-dropdown-menu> |
|||
<el-dropdown-item |
|||
@click="handleCity(item.deptId, item.deptName)" |
|||
v-for="(item, index) in cityList" |
|||
:label="item.deptName" |
|||
:value="item.deptId" |
|||
:key="index" |
|||
>{{ item.deptName }}</el-dropdown-item |
|||
> |
|||
</el-dropdown-menu> |
|||
</template> |
|||
</el-dropdown> |
|||
<el-dropdown trigger="click"> |
|||
<span class="el-dropdown-link"> |
|||
{{ apartmentName |
|||
}}<el-icon class="el-icon--right"><arrow-down /></el-icon> |
|||
</span> |
|||
<template #dropdown> |
|||
<el-dropdown-menu> |
|||
<el-dropdown-item |
|||
v-for="(item, index) in apartmentList" |
|||
:label="item.deptName" |
|||
:value="item.deptId" |
|||
:key="index" |
|||
@click="handleApartment(item.deptId, item.deptName)" |
|||
>{{ item.deptName }}</el-dropdown-item |
|||
> |
|||
</el-dropdown-menu> |
|||
</template> |
|||
</el-dropdown> |
|||
<el-dropdown trigger="click"> |
|||
<span class="el-dropdown-link"> |
|||
{{ houseTypeName |
|||
}}<el-icon class="el-icon--right"><arrow-down /></el-icon> |
|||
</span> |
|||
<template #dropdown> |
|||
<el-dropdown-menu> |
|||
<el-dropdown-item |
|||
v-for="(item, index) in roomTypeList" |
|||
:label="item.typeName" |
|||
:value="item.id" |
|||
:key="index" |
|||
@click="handleHouseType(item.id, item.typeName)" |
|||
>{{ item.typeName }}</el-dropdown-item |
|||
> |
|||
</el-dropdown-menu> |
|||
</template> |
|||
</el-dropdown> |
|||
</div> |
|||
</template> |
|||
<script setup> |
|||
import { ref, reactive, onMounted, onUnmounted } from "vue"; |
|||
import { getAgencyList, getHouseTypeList } from "@/api/index"; |
|||
const emit = defineEmits(["changeAngecy"]); |
|||
const props = defineProps({ |
|||
deptName: { |
|||
// 部门名称 |
|||
type: String, // 类型为字符串 |
|||
default: "", |
|||
}, |
|||
}); |
|||
const list = ref([]); // 定义列表数据 |
|||
const joinIn = reactive({ |
|||
// 定义查询参数 |
|||
deptName: props.deptName || "青岛市", |
|||
}); |
|||
const deptId = ref(""); |
|||
const cityList = ref([]); // 定义列表数据 |
|||
const apartmentList = ref([]); // 定义列表数据 |
|||
const roomTypeList = ref([]); // 定义列表数据 |
|||
const cityName = ref("请选择"); // 定义列表数据 |
|||
const apartmentName = ref("请选择"); // 定义列表数据 |
|||
const houseTypeName = ref("请选择"); // 定义列表数据 |
|||
const getQIngDaoId = async () => { |
|||
// 获取列表数据 |
|||
try { |
|||
const res = await getAgencyList(joinIn); // 调用接口获取数据 |
|||
list.value = res.data; // 赋值给列表数据 |
|||
deptId.value = list.value[0].deptId; |
|||
getDropdownList("city"); |
|||
} catch (err) { |
|||
console.error("获取数据失败:", err); // 处理错误 |
|||
} |
|||
}; |
|||
const getDropdownList = async (type) => { |
|||
// 获取列表数据 |
|||
try { |
|||
const res = await getAgencyList({ parentId: deptId.value }); // 调用接口获取数据 |
|||
if (type === "city") { |
|||
cityList.value = res.data; // 赋值给列表数据 |
|||
console.log(cityList.value); |
|||
} else if (type === "apartment") { |
|||
apartmentList.value = res.data; // 赋值给列表数据 |
|||
} |
|||
} catch (err) { |
|||
console.error("获取数据失败:", err); // 处理错误 |
|||
} |
|||
}; |
|||
const handleCity = (id, name) => { |
|||
deptId.value = id; |
|||
cityName.value = name; |
|||
apartmentList.value = []; // 清空 apartmentList |
|||
roomTypeList.value = []; // 清空 roomTypeList |
|||
apartmentName.value = "请选择"; // 清空 apartmentName |
|||
houseTypeName.value = "请选择"; // 清空 apartmentName |
|||
emit("changeAngecy", { id, type: "city" }); |
|||
getDropdownList("apartment"); |
|||
}; |
|||
const handleApartment = (id, name) => { |
|||
roomTypeList.value = []; // 清空 roomTypeList |
|||
apartmentName.value = name; |
|||
deptId.value = id; |
|||
houseTypeName.value = "请选择"; // 清空 apartmentName |
|||
emit("changeAngecy", { id, type: "apartment" }); |
|||
getHouseType(id); |
|||
}; |
|||
const handleHouseType = (id, name) => { |
|||
houseTypeName.value = name; |
|||
deptId.value = id; |
|||
emit("changeAngecy", { id, type: "houseType" }); |
|||
}; |
|||
const getHouseType = async (id) => { |
|||
try { |
|||
const res = await getHouseTypeList({ apartmentId: id }); // 调用接口获取数据 |
|||
roomTypeList.value = res.data; // 赋值给列表数据 |
|||
} catch (err) { |
|||
console.error("获取数据失败:", err); // 处理错误 |
|||
} |
|||
}; |
|||
onMounted(() => { |
|||
// 组件挂载时获取数据 |
|||
getQIngDaoId(); // 调用获取数据函数 |
|||
}); |
|||
</script> |
@ -0,0 +1,100 @@ |
|||
<template> |
|||
<div class="w-[420px] h-[344px] overflow-y-auto"> |
|||
<div>选择房型</div> |
|||
<el-divider /> |
|||
<div class="flex flex-col"> |
|||
<div class="flex gap-5" v-for="(item, index) in list" :key="index"> |
|||
<img :src="item.coverImg" alt="" class="w-[140px] h-[100px]" /> |
|||
<div class="flex-1 flex flex-col"> |
|||
<div class="font-bold">{{ item.name }}</div> |
|||
<div>共{{ item.total }}间</div> |
|||
<div class="text-gray-400">{{ item.address }}</div> |
|||
<div> |
|||
<div |
|||
v-for="tag in item.labels" |
|||
:key="tag" |
|||
class="mr-1 mb-1 inline-flex items-center px-2 py-1 rounded text-xs font-medium" |
|||
:class="tag === '1' ? 'bule' : tag === '2' ? 'green' : 'yellow'" |
|||
> |
|||
{{ getLabel(tag) }} |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
<script setup> |
|||
import { ref, reactive, onMounted, onUnmounted, watch } from "vue"; |
|||
import { getHouseTypeMap, getDict } from "@/api/index"; |
|||
const props = defineProps({ |
|||
selfObj: { |
|||
type: Object, |
|||
default: () => { |
|||
return {}; |
|||
}, |
|||
}, |
|||
}); // 定义props对象,用于接收外部传入的参数 |
|||
const list = ref([]); |
|||
const dict = ref({}); |
|||
const joinIn = reactive({ |
|||
pageNum: 1, |
|||
pageSize: 200, |
|||
regionCode: "", // 区域 |
|||
apartmentId: "", // 公寓 |
|||
houseTypeId: "", // 户型 |
|||
}); |
|||
const getDictList = async () => { |
|||
const res = await getDict({ dictType: "apartment_label" }); |
|||
try { |
|||
dict.value = res.rows[0]; |
|||
} catch (error) {} |
|||
}; |
|||
const getList = async () => { |
|||
const res = await getHouseTypeMap(joinIn); |
|||
list.value = res.rows; |
|||
}; |
|||
|
|||
getDictList(); |
|||
watch( |
|||
() => props.selfObj, |
|||
(newVal, oldVal) => { |
|||
if (newVal.type === "city") { |
|||
joinIn.regionCode = newVal.id; |
|||
} else if (newVal.type === "apartment") { |
|||
joinIn.apartmentId = newVal.id; |
|||
} else if (newVal.type === "houseType") { |
|||
joinIn.houseTypeId = newVal.id; |
|||
} |
|||
|
|||
getList(); |
|||
}, |
|||
{ deep: true } |
|||
); |
|||
getList(); |
|||
const getLabel = (tag) => { |
|||
// 如果dict.value是对象,需要先转换为数组 |
|||
const dictArray = Array.isArray(dict.value) |
|||
? dict.value |
|||
: Object.values(dict.value); |
|||
return dictArray.find((item) => item.dictValue === tag)?.dictLabel || tag; |
|||
}; |
|||
</script> |
|||
<style scoped> |
|||
.bule{ |
|||
color: #99bbfe; |
|||
border:1px solid #99bbfe; |
|||
padding: 0 5px; |
|||
|
|||
} |
|||
.green{ |
|||
color: #3bcccd; |
|||
border:1px solid #3bcccd; |
|||
padding: 0 5px; |
|||
} |
|||
.yellow{ |
|||
color: #efca3f; |
|||
border:1px solid #efca3f; |
|||
padding: 0 5px; |
|||
} |
|||
</style> |
@ -0,0 +1,69 @@ |
|||
<template> |
|||
<div class="bg-syGreyBg overflow-hidden"> |
|||
<div class="bg-white absolute top-20 left-24 z-20 py-4 px-6 rounded-md"> |
|||
<Agency :deptName="deptName" @changeAngecy="changeAngecy" /> |
|||
</div> |
|||
<Amap :markers="markers" @marker-click="handleMarkerClick" /> |
|||
<div class="bg-white absolute bottom-32 right-24 z-20 py-4 px-6 rounded-md"> |
|||
<HouseList :selfObj="selfObj" /> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
<script setup lang="ts"> |
|||
import { ref, reactive, onMounted, onUnmounted } from "vue"; |
|||
import Amap from "@/components/AMap.vue"; |
|||
import Agency from "./components/Agency.vue"; |
|||
import HouseList from "./components/HouseList.vue"; |
|||
import { getMapPoint } from "@/api/index"; |
|||
const deptName = ref(""); |
|||
let selfObj = ref({}); |
|||
// 定义标记点数据 |
|||
const markers = ref([]); |
|||
const deptId = ref(""); |
|||
const handleMarkerClick = (event) => { |
|||
console.log("点击了标记点:", event); |
|||
selfObj.value = { type: "apartment", id: event.marker.id }; |
|||
// 先将所有点位恢复默认颜色 |
|||
markers.value = markers.value.map((marker) => ({ |
|||
...marker, |
|||
color: "#3388FF", // 默认颜色 |
|||
})); |
|||
|
|||
// 然后设置当前点击的点位为高亮颜色 |
|||
markers.value[event.index].color = "#ff9f00"; |
|||
}; |
|||
|
|||
const getMarkers = async (event) => { |
|||
try { |
|||
let pamrs = { |
|||
pageSize: 200, |
|||
pageNum: 1, |
|||
regionCode: '', // 区域 |
|||
apartmentId: "", // 公寓 |
|||
houseTypeId: "", // 户型 |
|||
}; |
|||
|
|||
if (event) { |
|||
if (event.type === "city") { |
|||
pamrs.regionCode = event.id; |
|||
} else if (event.type === "apartment") { |
|||
pamrs.apartmentId = event.id; |
|||
} else if (event.type === "houseType") { |
|||
pamrs.houseTypeId = event.id; |
|||
} |
|||
} |
|||
const res = await getMapPoint(pamrs); |
|||
markers.value = res.rows; |
|||
console.log(markers, "seeeee"); |
|||
} catch (error) { |
|||
console.log(error); |
|||
} |
|||
}; |
|||
const changeAngecy = (event) => { |
|||
selfObj.value = { type: event.type, id: event.id }; |
|||
getMarkers(event); |
|||
}; |
|||
getMarkers(); |
|||
</script> |
|||
|
|||
<style scoped></style> |
File diff suppressed because it is too large
Loading…
Reference in new issue