Commit 5b7a4e00 authored by shilei's avatar shilei

Merge branch 'dev' of http://101.201.78.203/cfld-front/liyeyun into dev

parents fdc02019 7528e110
NODE_ENV=development
# VITE_BASE_URL=http://test.api.liyeyun.com
VITE_BASE_URL=/API
VITE_BASE_USER_URL=/userAPI
NODE_ENV=production
VITE_BASE_URL=http://test.api.liyeyun.com
# VITE_BASE_URL=/API
VITE_BASE_USER_URL=http://test.user.liyeyun.com
......@@ -16,7 +16,6 @@
"element-plus": "^2.4.3",
"jsencrypt": "^3.3.2",
"lodash-es": "^4.17.21",
"moment": "^2.29.4",
"pinia": "^2.1.7",
"qrcode": "^1.5.3",
"swiper": "^11.0.5",
......@@ -8025,14 +8024,6 @@
"ufo": "^1.3.0"
}
},
"node_modules/moment": {
"version": "2.29.4",
"resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz",
"integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==",
"engines": {
"node": "*"
}
},
"node_modules/ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
......@@ -17311,11 +17302,6 @@
"ufo": "^1.3.0"
}
},
"moment": {
"version": "2.29.4",
"resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz",
"integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w=="
},
"ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
......
......@@ -4,8 +4,8 @@
"private": true,
"scripts": {
"dev": "vite",
"build:prod": "npm run build-only",
"build:test": "npm run build-only",
"build:prod": "npm run build-only -- -m development",
"build:test": "npm run build-only -- -m test",
"preview": "vite preview",
"test:unit": "vitest",
"build-only": "vite build",
......@@ -22,7 +22,6 @@
"element-plus": "^2.4.3",
"jsencrypt": "^3.3.2",
"lodash-es": "^4.17.21",
"moment": "^2.29.4",
"pinia": "^2.1.7",
"qrcode": "^1.5.3",
"swiper": "^11.0.5",
......
......@@ -62,8 +62,12 @@ const menuList = computed(() => {
* 当前菜单path
*/
const currentPath = computed(() => {
if (`#${route.path}` === window.location.hash) {
return route.path;
const { menuRouteName } = route.meta;
const { fullPath, path } = route;
if (menuRouteName) {
return router.resolve({ name: menuRouteName }).path;
} else if (router.resolve(fullPath).href === window.location.hash) {
return path;
} else {
return '';
}
......
This diff is collapsed.
......@@ -139,7 +139,7 @@
import type { HeaderMenuItem } from '@/types/common.ts';
import { useLoginModal } from '@/components/login/login.ts';
import { useAppStore } from '@/stores/app.ts';
import { computed, ref, onMounted } from 'vue';
import { computed, ref, onMounted, watch } from 'vue';
import { useJump } from '@/composable/useJump.ts';
import { RouteName } from '@/router/router.ts';
import { useRoute } from 'vue-router';
......@@ -147,6 +147,7 @@ import { useRoute } from 'vue-router';
import { useCity } from '@/composable/useCity.ts';
import type { DropdownInstance } from 'element-plus';
import type { RouteLocationRaw } from 'vue-router';
import { useSearchParamsStore } from '@/stores/searchParams.ts';
const props = withDefaults(
defineProps<{
......@@ -159,6 +160,7 @@ const props = withDefaults(
const appStore = useAppStore();
const { router, open: openPage } = useJump();
const route = useRoute();
const searchParamsStore = useSearchParamsStore();
const userInfo = computed(() => {
return appStore.userInfo;
......@@ -249,19 +251,27 @@ const changeCityStatus = (status: number) => {
}
};
/** 用于搜索条件的省名 */
const cityInFilter = computed(() => {
return provinceList.find((item) => {
return item.name.replace(/\s+/g, '').indexOf(currentCity.value) > -1;
});
});
watch(cityInFilter, (val) => {
searchParamsStore.changeGlobalProvinceName(val?.name || '');
});
const handleCityClick = (cityName: string) => {
currentCity.value = cityName;
const cityInFilter = provinceList.filter((item) => {
return item.name.replace(/\s+/g, '').indexOf(cityName) > -1;
});
const jump = (params: RouteLocationRaw) => {
router.replace(params);
};
if (cityInFilter.length) {
if (cityInFilter.value) {
jump({
name: route.name!,
query: {
city: cityInFilter[0].name,
city: cityInFilter.value.name,
c: cityName,
},
});
......@@ -291,14 +301,20 @@ const handleLogout = () => {
};
const handleMenuChange = (menu: HeaderMenuItem) => {
const { city } = route.query;
const searchParams = city ? JSON.stringify({ provinceName: city }) : undefined;
openPage({
const menuRoute = router.resolve(menu.path);
const searchParams =
cityInFilter.value && menuRoute.name !== RouteName.home
? JSON.stringify({ provinceName: cityInFilter.value.name })
: undefined;
openPage(
{
path: menu.path,
query: {
searchParams,
},
});
},
menuRoute.name === RouteName.industryCategory,
);
};
</script>
<style lang="scss" scoped>
......
<template>
<div class="flex h-12 items-center justify-between">
<div class="flex h-[50px] items-center justify-between">
<div class="flex h-full items-center">
<div>
<img class="h-10 w-auto" src="@/assets/images/logo-head.png" alt="立业云" />
</div>
<div
class="ml-4 flex h-8 items-center px-4 font-yahei text-base text-[#C0322B] outline outline-1 outline-[#C0322B]"
>
{{ typeName }}
<img class="h-[50px]" :src="titleIcon" alt="立业云" />
</div>
</div>
<div v-if="showSearch" class="h-full">
......@@ -32,8 +27,16 @@
</div>
</template>
<script setup lang="ts">
import { onUnmounted, ref, watchEffect } from 'vue';
import { computed, onUnmounted, ref, watchEffect } from 'vue';
import { useSearchParamsStore } from '@/stores/searchParams.ts';
import { useRoute } from 'vue-router';
import parkIcon from '@/assets/images/title-icon__park.png';
import categoryIcon from '@/assets/images/title-icon__category.png';
import developIcon from '@/assets/images/title-icon__develop.png';
import landIcon from '@/assets/images/title-icon__land.png';
import policyIcon from '@/assets/images/title-icon__policy.png';
import carrierIcon from '@/assets/images/title-icon__carrier.png';
import { TitleIconType } from '@/types/enum.ts';
withDefaults(
defineProps<{
......@@ -50,8 +53,27 @@ const emit = defineEmits(['search']);
const searchParamsStore = useSearchParamsStore();
const route = useRoute();
const parkName = ref('');
const titleIcon = computed(() => {
const config: Record<TitleIconType, string> = {
[TitleIconType.carrier]: carrierIcon,
[TitleIconType.land]: landIcon,
[TitleIconType.park]: parkIcon,
[TitleIconType.category]: categoryIcon,
[TitleIconType.policy]: policyIcon,
[TitleIconType.develop]: developIcon,
[TitleIconType.user]: developIcon,
[TitleIconType.about]: developIcon,
[TitleIconType.contact]: developIcon,
};
const { iconType } = route.meta || {};
return config[iconType!];
});
watchEffect(() => {
parkName.value = searchParamsStore.searchName?.trim() || '';
});
......
<template>
<div v-if="infos.length > 0" class="text-[0px]">
<div v-for="(line, index) of infos" :key="index" class="min-h-10 inline-flex w-full">
<div v-for="col in line" :key="col.name" class="flex flex-1 text-xs text-[#1A1A1A]">
<div v-for="col in line" :key="col.name" class="flex flex-1 text-sm text-[#1A1A1A]">
<div
class="flex w-[200px] flex-none bg-[#FAFAFC] px-[30px] py-[10px] leading-5"
:class="{ '!w-[160px] !px-5': col.smallMode }"
......@@ -17,7 +17,7 @@
<a
:download="col.fileName"
:href="col.value as string"
class="font-yahei text-xs leading-5 text-[#2C68FF]"
class="font-yahei text-sm leading-5 text-[#2C68FF]"
>
{{ col.fileName }}
</a>
......
......@@ -27,7 +27,7 @@
<div v-if="titleCenter" class="title-bottom-bg h-1 w-[102px] rounded-[30px]"></div>
<div
v-if="toListText"
class="absolute right-0 flex cursor-pointer items-center justify-end text-xs text-[#4D4D4D]"
class="absolute right-0 flex cursor-pointer items-center justify-end text-sm text-[#4D4D4D]"
@click="handleToList"
>
{{ toListText }}
......@@ -43,7 +43,7 @@
@click="changeContentExpand(!isContentExpand)"
>
<div class="flex h-full items-center px-4">
<div class="text-xs leading-[14px] text-[#4D4D4D]">
<div class="text-sm leading-[14px] text-[#4D4D4D]">
{{ isContentExpand ? '收起' : '展示全部' }}
</div>
<div class="ml-1">
......
......@@ -23,11 +23,6 @@
{{ currentStatusTag.name }}
</div>
</div>
<div v-if="superTag" class="ml-2">
<div :class="['status-tag', superTag.className]">
{{ superTag.name }}
</div>
</div>
</div>
<!-- main content -->
<div class="mt-4 flex">
......@@ -41,14 +36,14 @@
</div>
<div class="mt-3">
<div v-if="detail.investmentDetails.length" class="flex">
<div class="flex h-[38px] items-center font-yahei text-xs leading-5 text-[#4D4D4D]">
<div class="flex h-[38px] items-center font-yahei text-sm leading-5 text-[#4D4D4D]">
{{ isLand ? '产业方向' : '招商方向' }}
</div>
<div class="ml-[30px] flex flex-1 flex-wrap gap-[10px]">
<div
v-for="invest of formatedInvestmentDetails"
:key="invest.codeName"
class="flex h-[38px] items-center rounded-sm bg-[#4F4F4F14] px-3 text-xs leading-[18px] text-[#4F4F4F]"
class="flex h-[38px] items-center rounded-sm bg-[#4F4F4F14] px-3 text-sm leading-[18px] text-[#4F4F4F]"
>
{{ invest.codeName }}
</div>
......@@ -56,19 +51,19 @@
</div>
<div v-if="area" class="mt-[13px] flex items-center">
<div
class="flex h-[38px] flex-none items-center font-yahei text-xs leading-5 text-[#4D4D4D]"
class="flex h-[38px] flex-none items-center font-yahei text-sm leading-5 text-[#4D4D4D]"
>
所属地区
</div>
<div class="ml-[30px] font-yahei text-xs leading-5 text-[#1A1A1A]">{{ area }}</div>
<div class="ml-[30px] font-yahei text-sm leading-5 text-[#1A1A1A]">{{ area }}</div>
</div>
<div v-if="detail.address" class="mt-2 flex items-center">
<div
class="flex h-[38px] flex-none items-center font-yahei text-xs leading-5 text-[#4D4D4D]"
class="flex h-[38px] flex-none items-center font-yahei text-sm leading-5 text-[#4D4D4D]"
>
详细地址
</div>
<div class="ml-[30px] font-yahei text-xs leading-5 text-[#1A1A1A]">
<div class="ml-[30px] font-yahei text-sm leading-5 text-[#1A1A1A]">
{{ detail.address }}
</div>
</div>
......@@ -140,7 +135,7 @@ const props = withDefaults(
{},
);
const { currentStatusTag, superTag } = useItemStatus(props.detail);
const { currentStatusTag } = useItemStatus(props.detail);
const { open } = useJump();
const isLand = computed(() => {
......
......@@ -4,8 +4,8 @@
v-if="value"
class="flex h-[80px] w-[164px] flex-col items-center justify-center bg-[#FAFAFC]"
>
<div class="text-base font-semibold leading-5 text-[#1A1A1A]">{{ value + unit }}</div>
<div class="mt-1 text-xs leading-5 text-[#4D4D4D]">{{ name }}</div>
<div class="text-lg font-semibold leading-5 text-[#1A1A1A]">{{ value + unit }}</div>
<div class="mt-1 text-sm leading-5 text-[#4D4D4D]">{{ name }}</div>
</div>
</template>
......
......@@ -10,7 +10,7 @@
>
{{ detail.name }}
</div>
<div class="mt-1 font-yahei text-xs text-[#4D4D4D]">
<div class="mt-1 font-yahei text-sm text-[#4D4D4D]">
{{ detail.info }}
</div>
</div>
......
<!-- 星级开发区展示 -->
<template>
<div class="h-[558px]">
<div class="header-bg absolute inset-x-0 flex h-[558px] w-full items-center justify-center">
<div class="header-bg__img main-width h-[455px]">
<div class="flex justify-between">
<div>
<div
class="header-bg__content ml-[56px] mt-[75px] font-yahei text-[40px] font-semibold leading-[56px] tracking-[2px] text-[#C0322B]"
>
立业{{ developName }} | 共赢发展未来
<div class="star-detail h-[600px]">
<div class="star-bg absolute inset-x-0 flex h-[600px] w-full items-center justify-center">
<div class="main-width">
<div class="flex">
<div class="mt-[159px] font-yahei font-bold text-white">
<div class="main-title h-[86px] w-[638px] text-[58px]">
立业{{ developName }}丨共赢发展未来
</div>
<div>
<img
class="ml-[162px] mt-[68px] h-[182px] w-[228px]"
src="@/assets/images/home-header-right.png"
/>
<div class="sub-title mt-[13px] h-[37px] w-[637px] whitespace-nowrap text-[28px]">
链上合肥、对接大上海、融入长三角
</div>
</div>
<div class="mt-[48px] pb-[47px]">
<div class="my-[120px] ml-[70px]">
<VideoList
:video-urls="detail.videoUrlList"
:image-urls="detail.imgUrlList"
......@@ -63,7 +58,7 @@
>
<div
class="flex items-center space-x-[23px]"
:class="{ 'space-x-9 overflow-x-auto': index === 1 }"
:class="{ 'space-x-9 overflow-x-auto pb-5': index === 1 }"
>
<StarInfoCell
v-for="item of info.value"
......@@ -204,9 +199,13 @@ const handleShowDesc = () => {
height: 262px;
padding: 20px 16px;
overflow: hidden;
position: relative;
.star-info-img {
width: 100%;
height: 181.5px;
img {
transition: all 0.3s ease-in-out;
}
}
.star-info-content {
position: static;
......@@ -214,14 +213,50 @@ const handleShowDesc = () => {
height: 30px;
margin-top: 12px;
padding-top: 0;
.content-title {
transition: all 0.3s ease-in-out;
}
}
&:hover {
.star-info-img {
transform: scale(1.2);
overflow: hidden;
img {
transform: scale(1.5);
}
}
.star-info-content {
height: 30px;
.content-title {
color: #c0322b;
}
}
&::after {
content: '';
display: block;
right: 16px;
bottom: 25px;
width: 20px;
height: 20px;
position: absolute;
background: url('@/assets/images/icon-red-right.png') no-repeat;
background-size: contain;
}
}
}
.star-detail {
.star-bg {
background: url('@/assets/images/star-bg.png') no-repeat;
background-size: cover;
background-position-y: -100px;
}
.main-title {
text-shadow: 0px 4px 5px rgba(0, 0, 0, 0.15);
line-height: 86px;
}
.sub-title {
letter-spacing: 12px;
line-height: 33px;
text-shadow: 0px 8px 20px rgba(90, 0, 0, 0.1);
}
}
</style>
......@@ -3,17 +3,17 @@
<div
class="star-info-cell star-info-shadow relative h-[357px] w-[370px] cursor-pointer rounded-sm px-[21px] py-[27px]"
>
<div>
<div class="text-[0px]">
<CommonImage
class="star-info-img h-[245px] w-[327px] transition-all duration-200"
:src="img || null"
/>
</div>
<div class="star-info-content absolute">
<div class="font-yahei text-lg font-semibold leading-[41px] text-[#1A1A1A]">
<div class="content-title font-yahei text-lg font-semibold leading-[30px] text-[#1A1A1A]">
{{ title }}
</div>
<div class="overflow-hidden break-all text-xs leading-5">
<div class="mt-3 overflow-hidden break-all text-sm leading-5">
{{ content }}
</div>
</div>
......@@ -41,7 +41,7 @@ withDefaults(
height: 58px;
bottom: 27px;
overflow: hidden;
padding-top: 17px;
padding-top: 12px;
background-color: #fff;
transition: all 0.3s;
width: 327px;
......
......@@ -30,7 +30,7 @@
</SwiperSlide>
</Swiper>
<div
class="absolute bottom-[14px] right-[14px] z-10 flex h-[26px] cursor-pointer rounded-[50px] bg-[#808080] font-yahei text-xs leading-[18px] text-white"
class="absolute bottom-[14px] right-[14px] z-10 flex h-[26px] cursor-pointer rounded-[50px] bg-[#808080] font-yahei text-sm leading-[18px] text-white"
>
<div
class="flex w-[45px] items-center justify-center rounded-[50px]"
......@@ -50,7 +50,7 @@
</div>
</div>
<div>
<div class="flex bg-white p-[10px] font-yahei text-xs leading-5 text-[#4D4D4D]">
<div class="flex bg-white p-[10px] font-yahei text-sm leading-5 text-[#4D4D4D]">
<div ref="descriptionRef" class="ell2">
{{ description }}
</div>
......@@ -59,7 +59,7 @@
class="flex flex-none cursor-pointer items-center self-end"
@click="showDesc"
>
<div class="text-xs font-semibold leading-5 text-[#C0322B]">展开</div>
<div class="text-sm font-semibold leading-5 text-[#C0322B]">展开</div>
<div class="ml-1 h-[5px] w-2">
<img src="@/assets/images/icon-arrow_down.png" />
</div>
......
......@@ -454,7 +454,7 @@ watch(
height: 22px;
color: #fff;
margin-left: 8px;
font-size: 12px;
font-size: 14px;
border-radius: 2px;
}
.selected-item {
......
<template>
<div class="form-modal content w-[258px] px-[29px] py-[30px]">
<div class="form-modal content h-[372px] w-[300px] px-5 py-10 outline outline-[#000000]/[.08]">
<div>
<p class="mb-5 text-base font-semibold text-[#1A1A1A]">选址需求</p>
<ElInput v-model="formData.address" class="w-[200px]" placeholder="*输入选址区域"></ElInput>
<ElInput
v-model="formData.address"
class="h-[38px] w-[260px]"
placeholder="*输入选址区域"
></ElInput>
<ElSelect
v-model="formData.needType"
clearable
class="mt-3 w-[200px]"
class="mt-3 w-[260px]"
placeholder="*请选择您的需求类型"
>
<ElOption v-for="item in options" :key="item.label" :label="item.label" :value="item.value" />
<ElOption
v-for="item in options"
:key="item.label"
:label="item.label"
:value="item.value"
/>
</ElSelect>
<ElInputNumber
v-model="formData.phone"
:controls="false"
class="form-modal__input-number mt-3 !w-[200px] !px-0"
class="form-modal__input-number mt-3 h-[38px] !w-[260px] !px-0"
placeholder="*请填写您的联系方式"
></ElInputNumber>
<ElInput
v-model="formData.remark"
class="mt-3 w-[200px]"
class="mt-3 w-[260px]"
type="textarea"
placeholder="具体描述"
></ElInput>
<div class="btn-default mt-5" @click="commit">提交</div>
<div class="btn-default mt-5 font-yahei" @click="commit">提交选址需求</div>
</div>
</div>
</template>
<script lang="ts" setup>
......@@ -114,11 +125,12 @@ const commit = debounce(
.btn-default {
background: #c0322b;
color: #fff;
line-height: 30px;
line-height: 40px;
text-align: center;
border-radius: 2px 2px 2px 2px;
font-size: 12px;
font-weight: 500;
font-size: 14px;
font-weight: 600;
height: 40px;
cursor: pointer;
}
&__input-number {
......@@ -130,5 +142,8 @@ const commit = debounce(
}
}
}
.el-input__wrapper {
height: 38px;
}
}
</style>
......@@ -18,8 +18,8 @@ export default defineComponent({
return (
<>
{pre}
{pre ? <div class="text-xs leading-[18px]">|</div> : ''}
<div class="font-yahei text-xs leading-5">{info}</div>
{pre ? <div class="text-sm leading-[18px]">|</div> : ''}
<div class="font-yahei text-sm leading-5">{info}</div>
</>
);
}, '')}
......
<template>
<div v-if="item">
<div class="flex min-h-[156px]">
<div @click="handleDetail">
<div class="relative" @click="handleDetail">
<CommonImage
class="h-[156px] w-[208px] cursor-pointer rounded-sm"
:src="item.imgUrl"
:alt="isDevelop ? '开发区' : '产业园'"
/>
<div
v-if="item.isSuper"
class="absolute left-0 top-0 z-10 flex h-[26px] w-[94px] items-center justify-center rounded-br-sm rounded-tl-sm bg-[#C0322B] text-sm font-semibold text-white"
>
星级开发区
</div>
</div>
<div class="ml-4 max-w-[576px] py-2">
<div class="flex items-center">
......@@ -21,19 +27,14 @@
{{ currentStatusTag.name }}
</div>
</div>
<div v-if="superTag" class="ml-2 flex-none">
<div :class="['status-tag', superTag.className]">
{{ superTag.name }}
</div>
</div>
</div>
<div class="mt-[17px] flex items-center font-yahei text-xs leading-5 text-[#4d4d4d]">
<div class="mt-[17px] flex items-center font-yahei text-sm leading-5 text-[#4d4d4d]">
<img class="mr-1 h-4 w-4" src="@/assets/images/icon-local.png" alt="" />
<div>
{{ filterAddress(item) }}
</div>
</div>
<div class="mt-4">
<div class="mt-4 pl-5">
<ListInfo :infos="infos"></ListInfo>
</div>
<div class="mt-[17px] flex flex-wrap gap-[13px]">
......@@ -68,7 +69,7 @@ const emit = defineEmits<{
'to-detail': [];
}>();
const { currentStatusTag, superTag } = useItemStatus(props.item);
const { currentStatusTag } = useItemStatus(props.item);
/** 最大展示招商方向数量 */
const MAX_DIRECTION_COUNT = 3;
......
......@@ -4,7 +4,7 @@
<CommonImage class="h-[156px] w-[208px]" :src="detail.imgUrl" alt="" />
</div>
<div
class="media-right relative flex w-[576px] flex-col justify-between pt-2 text-xs leading-[20px] text-[#4d4d4d]"
class="media-right relative flex w-[576px] flex-col justify-between pt-2 text-sm leading-[20px] text-[#4d4d4d]"
>
<p
class="ell2 mb-[7px] cursor-pointer text-xl font-semibold text-[#1a1a1a]"
......
......@@ -4,7 +4,7 @@
<CommonImage class="h-[156px] w-[208px]" :src="detail.imgUrl" alt="" />
</div>
<div
class="media-right relative flex w-[576px] flex-col justify-between pt-2 text-xs leading-[20px] text-[#4d4d4d]"
class="media-right relative flex w-[576px] flex-col justify-between pt-2 text-sm leading-[20px] text-[#4d4d4d]"
>
<p
class="ell2 mb-[7px] cursor-pointer text-xl font-semibold text-[#1a1a1a]"
......
......@@ -9,7 +9,7 @@
<span
v-for="item in detail.industryList.split(',')"
:key="item"
class="mb-2 mr-[13px] bg-[rgba(44,104,255,0.08)] px-3 text-xs leading-[22px] text-[#2C68FF]"
class="mb-2 mr-[13px] bg-[rgba(44,104,255,0.08)] px-3 text-sm leading-[22px] text-[#2C68FF]"
>
{{ item }}
</span>
......
......@@ -36,9 +36,9 @@
</div>
</div>
<div v-if="errorMsg" class="error-msg">{{ errorMsg }}</div>
<div class="mt-5 flex h-5 items-center justify-between leading-[20px] text-black/[.65]">
<!-- <div class="mt-5 flex h-5 items-center justify-between leading-[20px] text-black/[.65]">
<ElCheckbox v-model="saveLogin" :label="1">七天内免登录</ElCheckbox>
</div>
</div> -->
<div class="my-2.5 py-3">
<button class="btn-default" @click="login">登录</button>
</div>
......@@ -77,8 +77,8 @@
</div>
</div>
<div v-if="errorMsg" class="error-msg">{{ errorMsg }}</div>
<div class="mt-5 flex h-5 items-center justify-between leading-[20px] text-black/[.65]">
<ElCheckbox v-model="saveLogin" :label="1">七天内免登录</ElCheckbox>
<div class="mt-5 flex h-5 items-center justify-end leading-[20px] text-black/[.65]">
<!-- <ElCheckbox v-model="saveLogin" :label="1">七天内免登录</ElCheckbox> -->
<span class="cursor-pointer text-[#C0322B]" @click="changeModalType('resetPassWord')">
忘记密码
</span>
......@@ -215,7 +215,7 @@ const verifyCode = ref<number | null>();
const errorMsg = ref<string | null>();
const password = ref<string | null>(null);
const modalType = ref<string>('loginByPhone');
const saveLogin = ref<number[]>([1]);
// const saveLogin = ref<number[]>([1]);
const agree = ref<number[]>([]);
const interval = ref<number>(0);
const { message } = useMessage();
......@@ -313,14 +313,14 @@ const login = debounce(
modalType.value === 'loginByAccount' ? RequestUrl.loginByAccount : RequestUrl.loginByPhone;
request(url);
/** 记住token */
const isRememberToken = !!saveLogin.value.length;
// /** 记住token */
// const isRememberToken = !!saveLogin.value.length;
const { success, msg, data } = await requestFn({
code: verifyCode.value || undefined,
phone: phoneNum.value,
password: password.value || undefined,
status: isRememberToken,
// status: isRememberToken,
});
if (success) {
console.log(data);
......@@ -349,7 +349,7 @@ const sendMessage = debounce(
const sendType: any = {
register: 1,
loginByPhone: 2,
resetPassWord: 4,
resetPassWord: 3,
};
request(RequestUrl.sendMessage);
const { success, msg, data } = await requestFn({
......
......@@ -13,7 +13,7 @@
<div id="panel"></div>
<div class="map-table">
<div class="table-search">
<ul>
<ul class="space-x-[1px] font-yahei">
<li
search="highway"
class="table-li"
......@@ -22,7 +22,6 @@
>
高速
</li>
<div class="table-li-line"></div>
<li
search="port"
class="table-li"
......@@ -31,7 +30,6 @@
>
港口
</li>
<div class="table-li-line"></div>
<li
search="airport"
class="table-li"
......@@ -40,7 +38,6 @@
>
机场
</li>
<div class="table-li-line"></div>
<li
search="station"
class="table-li"
......@@ -49,7 +46,6 @@
>
物流
</li>
<div class="table-li-line"></div>
<li
search="region"
class="table-li table-li-last"
......@@ -64,23 +60,23 @@
<div
v-for="(item, index) in infoList"
:key="index + item.name"
class="flex h-[34px] justify-between font-yahei leading-[34px]"
class="flex h-[50px] justify-between font-yahei leading-[50px]"
>
<p
class="position-item font-semibold"
<div
class="position-item flex items-center text-sm leading-[18px] text-[#1A1A1A]"
@mousemove="showInfoWindow(item)"
@mouseout="hideInfoWindow"
>
{{ item.name }}
</p>
<div class="flex items-center text-xs text-[#4d4d4d]">
<div class="ell flex-1">{{ item.name }}</div>
</div>
<div class="flex items-center text-sm text-[#4d4d4d]">
<img class="mr-1 h-3 w-3" src="@/assets/images/icon-map_nav.png" />
<span>{{ item.distance }}</span>
</div>
</div>
<div
v-if="infoList.length === 0"
class="flex h-full items-center justify-center text-xs text-[#4d4d4d]"
class="flex h-full items-center justify-center text-sm text-[#4d4d4d]"
>
<span>暂无内容</span>
</div>
......@@ -244,8 +240,8 @@ onUnmounted(() => {
}
.map-table {
position: absolute;
top: 26px;
right: 59px;
top: 57px;
right: 57px;
z-index: 99;
}
.table-search {
......@@ -254,14 +250,16 @@ onUnmounted(() => {
box-shadow: 0px 1px 10px 0px rgba(31, 108, 221, 0.11);
border-radius: 2px;
overflow: hidden;
font-size: 12px;
font-size: 14px;
color: #666666;
}
.table-li {
float: left;
padding: 0 12px;
display: flex;
align-items: center;
justify-content: center;
height: 38px;
line-height: 38px;
width: 58px;
border-bottom: 2px solid #fff;
cursor: pointer;
}
......@@ -277,21 +275,18 @@ onUnmounted(() => {
margin-top: 8px;
}
.map-search-info {
width: 244px;
height: 210px;
width: 296px;
height: 270px;
padding: 0 10px;
overflow-y: scroll;
overflow-y: auto;
background: #ffffff;
box-shadow: 0px 1px 10px 0px rgba(31, 108, 221, 0.11);
border-radius: 2px;
}
.position-item {
font-size: 12px;
font-size: 14px;
color: #4d4d4d;
width: 141px;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
// width: 170px;
cursor: pointer;
......@@ -306,7 +301,7 @@ onUnmounted(() => {
background: #ffffff;
padding: 10px;
text-align: center;
font-size: 12px;
font-size: 14px;
}
.input-item {
text-overflow: ellipsis;
......
......@@ -38,7 +38,6 @@
separator="至"
:confirm="false"
:clearable="true"
:shortcuts="ranges"
:disabled-date="notAfterToday"
confirm-text="确认"
format="YYYY-MM-DD"
......@@ -59,13 +58,13 @@
</div>
<div class="ml-[10px] flex flex-none items-center">
<div
class="flex h-[30px] w-[56px] cursor-pointer items-center justify-center rounded-sm bg-[#C0322B] text-xs leading-[22px] text-white"
class="flex h-[30px] w-[56px] cursor-pointer items-center justify-center rounded-sm bg-[#C0322B] text-sm leading-[22px] text-white"
@click="handleSearch"
>
搜索
</div>
<div
class="ml-2.5 flex h-[30px] w-[56px] cursor-pointer items-center justify-center rounded-sm text-xs leading-[22px] outline outline-1 outline-[black]/[.08]"
class="ml-2.5 flex h-[30px] w-[56px] cursor-pointer items-center justify-center rounded-sm text-sm leading-[22px] outline outline-1 outline-[black]/[.08]"
@click="handleReset"
>
重置
......@@ -124,8 +123,7 @@ import { useDict } from '@/composable/useDict.ts';
import type { Dict } from '@/types/common';
import DatePicker from 'vue-datepicker-next';
import 'vue-datepicker-next/index.css';
import 'vue-datepicker-next/locale/zh-cn';
import moment from 'moment';
import 'vue-datepicker-next/locale/zh-cn.es';
const props = withDefaults(
defineProps<{
......@@ -227,46 +225,6 @@ const handleReset = () => {
params.value.time = '';
searchParams.value = '' as any;
};
// // 日期选择
const ranges = [
{
text: '今天',
onClick() {
const date = moment().toDate();
return [date, date];
},
},
{
text: '昨天',
onClick() {
return [moment().subtract(1, 'day').toDate(), moment().subtract(1, 'day').toDate()];
},
},
{
text: '近一周',
onClick() {
return [moment().subtract(7, 'day').toDate(), moment().toDate()];
},
},
{
text: '近一个月',
onClick() {
return [moment().subtract(1, 'month').toDate(), moment().toDate()];
},
},
{
text: '近三个月',
onClick() {
return [moment().subtract(3, 'month').toDate(), moment().toDate()];
},
},
{
text: '近一年',
onClick() {
return [moment().subtract(1, 'year').toDate(), moment().toDate()];
},
},
];
const notAfterToday = (date: any) => {
return date > new Date(new Date().setHours(23, 59, 59, 0));
};
......
......@@ -20,28 +20,13 @@ export function useItemStatus(item: {
className: 'text-[#0EBD92] bg-[#0EBD9214]',
},
};
/** 星级园区配置 */
const superStarConfig = {
className: 'text-[#ffb540] bg-[#ffb54014]',
};
/** 当前状态标签 */
const currentStatusTag = computed(() => {
return item.status ? { ...statusConfig[item.status], name: item.statusName } : null;
});
/** 星级开发区标签 */
const superTag = computed(() => {
return item.isSuper === 1
? {
...superStarConfig,
name: item.isSuperName || '星级开发区',
}
: null;
});
return {
currentStatusTag,
superTag,
};
}
......@@ -6,7 +6,6 @@ import { RouteName } from '@/router/router.ts';
import { useRoute, onBeforeRouteLeave } from 'vue-router';
import { useSearchParamsStore } from '@/stores/searchParams.ts';
import { cloneDeep, isEmpty } from 'lodash-es';
import { handleNoAuth } from '@/utils/tools.ts';
import { useRequest } from './useRequest.ts';
import { useJump } from './useJump.ts';
......@@ -78,10 +77,9 @@ export function useListView<
const callQuery = async () => {
try {
changeIsRequesting(true);
const { data, code } = await queryList(currentParams.value, getCurrentUrl());
const { data } = await queryList(currentParams.value, getCurrentUrl());
handleUrlClear();
datas.value = data.records;
handleNoAuth(code);
} catch (error) {
console.log(error);
} finally {
......
......@@ -2,6 +2,7 @@ import { createRouter, createWebHashHistory } from 'vue-router';
import type { RouteRecordRaw } from 'vue-router';
/** 首页 */
import HomeView from '@/views/home/HomeView.vue';
import { TitleIconType } from '@/types/enum.ts';
/** 产业园 */
const IndustrialParkList = () => import('@/views/industrial-park/IndustrialParkList.vue');
......@@ -116,6 +117,7 @@ const routes: readonly RouteRecordRaw[] = [
component: DevelopZoneList,
meta: {
menuName: '开发区',
iconType: TitleIconType.develop,
},
},
{
......@@ -124,6 +126,7 @@ const routes: readonly RouteRecordRaw[] = [
component: IndustrialParkList,
meta: {
menuName: '产业园',
iconType: TitleIconType.park,
},
},
{
......@@ -131,6 +134,7 @@ const routes: readonly RouteRecordRaw[] = [
component: CarrierList,
meta: {
menuName: '载体',
iconType: TitleIconType.carrier,
},
},
{
......@@ -138,6 +142,7 @@ const routes: readonly RouteRecordRaw[] = [
component: LandList,
meta: {
menuName: '土地',
iconType: TitleIconType.land,
},
},
{
......@@ -146,6 +151,7 @@ const routes: readonly RouteRecordRaw[] = [
component: IndustryCategory,
meta: {
menuName: '产业分类',
iconType: TitleIconType.category,
},
},
{
......@@ -154,12 +160,17 @@ const routes: readonly RouteRecordRaw[] = [
component: IndustryPolicy,
meta: {
menuName: '产业政策',
iconType: TitleIconType.policy,
},
},
{
// 产业政策详情
...gen(RouteName.industryPolicyDetail),
component: IndustryPolicyDetail,
meta: {
menuRouteName: RouteName.industryPolicy,
iconType: TitleIconType.policy,
},
},
{
// 地图选址
......@@ -170,11 +181,17 @@ const routes: readonly RouteRecordRaw[] = [
// 关于立业云
...gen(RouteName.aboutUs),
component: AboutUs,
meta: {
iconType: TitleIconType.about,
},
},
{
// 关于立业云
// 联系我们
...gen(RouteName.contactUs),
component: ContactUs,
meta: {
iconType: TitleIconType.contact,
},
},
{
// 合伙人招募
......@@ -185,21 +202,37 @@ const routes: readonly RouteRecordRaw[] = [
// 产业园详情
...gen(RouteName.industrialParkDetail),
component: IndustrialParkDetail,
meta: {
menuRouteName: RouteName.industrialParkList,
iconType: TitleIconType.park,
},
},
{
// 开发区详情
...gen(RouteName.developZoneDetail),
component: DevelopZoneDetail,
meta: {
menuRouteName: RouteName.developZoneList,
iconType: TitleIconType.develop,
},
},
{
// 开发区详情
// 土地详情
...gen(RouteName.landDetail),
component: LandDetail,
meta: {
menuRouteName: RouteName.landList,
iconType: TitleIconType.land,
},
},
{
// 开发区详情
// 载体详情
...gen(RouteName.carrierDetail),
component: CarrierDetail,
meta: {
menuRouteName: RouteName.carrierList,
iconType: TitleIconType.carrier,
},
},
{
// 用户中心
......@@ -211,21 +244,37 @@ const routes: readonly RouteRecordRaw[] = [
// 我的园区
...gen(RouteName.myPark),
component: MyPark,
meta: {
isAuth: true,
iconType: TitleIconType.user,
},
},
{
// 产业园详情
...gen(RouteName.myIndustrialDetail),
component: MyIndustrialDetail,
meta: {
isAuth: true,
iconType: TitleIconType.user,
},
},
{
// 开发区详情
...gen(RouteName.myDevelopDetail),
component: MyDevelopDetail,
meta: {
isAuth: true,
iconType: TitleIconType.user,
},
},
{
// 修改密码
...gen(RouteName.changePassword),
component: ChangePassword,
meta: {
isAuth: true,
iconType: TitleIconType.user,
},
},
],
},
......
import { defineStore } from 'pinia';
import { computed, ref, watch } from 'vue';
import { computed, ref, watch, watchEffect } from 'vue';
import type { UserInfo } from '@/types/common.ts';
import { useRequest } from '@/composable/useRequest.ts';
import { RequestUrl } from '@/types/api.ts';
import { useRouter, useRoute, type RouteRecordRaw } from 'vue-router';
import { RouteName } from '@/router/router.ts';
/**
* 应用信息
......@@ -12,6 +14,8 @@ export const useAppStore = defineStore('user', () => {
method: 'POST',
baseURL: import.meta.env.VITE_BASE_USER_URL,
});
const route = useRoute();
const router = useRouter();
const getTokenFromStorage = () => {
const item = localStorage.getItem('token');
......@@ -44,9 +48,31 @@ export const useAppStore = defineStore('user', () => {
changeToken('');
};
watch(token, (val) => {
if (!val) {
userInfo.value = null;
/** 处理登录失效跳转逻辑 */
const handleBack = () => {
const isBackHome = router.options.routes.some((current) => {
const { children = [] } = current;
const judge = (item: RouteRecordRaw) => {
const { isAuth } = item.meta || {};
return isAuth && route.name === item.name;
};
if (children.length > 0) {
return children.some((i) => judge(i));
} else {
return judge(current);
}
});
if (isBackHome) {
router.push({
name: RouteName.home,
});
}
};
watchEffect(() => {
if (!token.value) {
handleBack();
}
});
......
import { defineStore } from 'pinia';
import { computed, ref } from 'vue';
import { computed, ref, watch } from 'vue';
import { useRoute } from 'vue-router';
import { isEmpty } from 'lodash-es';
/**
* 搜索参数
......@@ -14,6 +15,18 @@ export const useSearchParamsStore = defineStore('searchParams', () => {
/** url传递的搜索参数 */
const urlSearchParams = ref(routeSearchParams.value);
const searchName = ref(urlSearchParams.value.name || '');
/** 首页选择省名 */
const globalProvinceName = ref('');
watch(
() => routeSearchParams.value,
(val) => {
if (!isEmpty(val)) {
urlSearchParams.value = val;
searchName.value = val?.name || '';
}
},
);
const changeSearchName = (name: string) => {
searchName.value = name;
......@@ -23,10 +36,16 @@ export const useSearchParamsStore = defineStore('searchParams', () => {
urlSearchParams.value = {};
};
const changeGlobalProvinceName = (name: string) => {
globalProvinceName.value = name;
};
return {
urlSearchParams,
searchName,
globalProvinceName,
changeSearchName,
changeGlobalProvinceName,
clearUrlSearchParams,
};
});
......@@ -118,3 +118,25 @@ export enum TabMessage {
/** 登录 */
login = 'login',
}
/** 标题icon类型 */
export enum TitleIconType {
/** 载体 */
carrier = 'carrier',
/** 产业园 */
park = 'park',
/** 开发区 */
develop = 'develop',
/** 产业分类 */
category = 'category',
/** 土地 */
land = 'land',
/** 产业政策 */
policy = 'policy',
/** 用户中心 */
user = 'user',
/** 关于我们 */
about = 'about',
/** 联系我们 */
contact = 'contact',
}
import 'vue-router';
import { RouteName } from '@/router/router.ts';
import { TitleIconType } from '@/types/enum.ts';
declare module 'vue-router' {
interface RouteMeta {
menuName?: string;
parentMenuName?: string;
menuRouteName?: RouteName;
isAuth?: boolean;
iconType?: TitleIconType;
}
}
import router, { RouteName } from '@/router/router.ts';
export const heightLight = (str: string, key: string) => {
const reg = new RegExp(key, 'ig');
return str.replace(reg, (val) => {
return `<span style="color: #C0322B;line-height: 25px;background: rgba(192,50,43,0.06);display: inline-block;">${val}</span>`;
});
};
export const handleNoAuth = (code: number) => {
if (code === 401) {
router.replace({
name: RouteName.home,
});
}
};
<!-- 载体 -->
<template>
<div v-if="detail" class="main-width mx-auto py-5">
<div class="space-y-4">
<div class="space-y-[44px]">
<DetailInfoCell>
<DetailMain
:type="DetailType.carrier"
......
......@@ -2,7 +2,7 @@
<template>
<div v-if="detail" class="relative">
<div class="main-width mx-auto py-5">
<div class="space-y-4">
<div class="space-y-[44px]">
<DetailInfoCell>
<DetailMain
:type="isStar ? DetailType.startDevelop : DetailType.develop"
......@@ -21,7 +21,7 @@
<StarDetail :detail="detail"></StarDetail>
</template>
<DetailInfoCell v-if="!isStar && detail.description" title="开发区简介">
<div class="font-yahei text-xs leading-5 text-[#1A1A1A]">
<div class="font-yahei text-sm leading-5 text-[#1A1A1A]">
{{ detail.description }}
</div>
</DetailInfoCell>
......@@ -184,7 +184,7 @@ const { industryBase } = useIndustryBase(detail);
const baseInfo = computed(() => {
if (detail.value) {
const { levelName, type, planArea, primaryIndustry } = detail.value;
const { levelName, type, planArea } = detail.value;
const result: Infos = [
[
{
......@@ -202,10 +202,6 @@ const baseInfo = computed(() => {
value: formatNumber(planArea),
unit: '平方公里',
},
{
name: '主导产业',
value: primaryIndustry,
},
],
];
......
......@@ -301,8 +301,10 @@ import type { HeaderMenuItem } from '@/types/common';
import { filterAddress, formatNumber } from '@/utils/filters.ts';
import ListInfo from '@/components/list/ListInfo.vue';
import { useMessage } from '@/composable/useMessage.ts';
import { useSearchParamsStore } from '@/stores/searchParams.ts';
const { open } = useJump();
const searchParamsStore = useSearchParamsStore();
const activeTab = ref<string>('develop');
const activeDataList = ref<any[]>([]);
const changeTab = (tabName: string, dataList: any[] = []) => {
......@@ -330,12 +332,11 @@ type PageData = {
};
const homePageData = ref<PageData>();
const route = useRoute();
const router = useRouter();
/** 选中的区域 */
const selectedCity = computed(() => {
return route.query.city;
return searchParamsStore.globalProvinceName;
});
const toList = (type:string = 'search') => {
......
<!-- 产业园详情 -->
<template>
<div v-if="detail" class="main-width mx-auto py-5">
<div class="space-y-4">
<div class="space-y-[44px]">
<DetailInfoCell>
<DetailMain :type="DetailType.industrial" :detail="detail">
<DetailMainInfo :value="detail.levelName" name="产业园级别"></DetailMainInfo>
......@@ -13,7 +13,7 @@
</DetailMain>
</DetailInfoCell>
<DetailInfoCell v-if="detail.description" title="产业园简介">
<div class="font-yahei text-xs leading-5 text-[#1A1A1A]">
<div class="font-yahei text-sm leading-5 text-[#1A1A1A]">
{{ detail.description }}
</div>
</DetailInfoCell>
......
......@@ -244,7 +244,7 @@ watch(
<style lang="scss" scoped>
.container-left p {
color: rgba(0, 0, 0, 0.45);
font-size: 12px;
font-size: 14px;
line-height: 25px;
margin-bottom: 10px;
margin-right: 16px;
......@@ -268,7 +268,7 @@ watch(
.el-input__wrapper {
box-shadow: none;
padding: 0;
font-size: 12px;
font-size: 14px;
&:hover {
box-shadow: none;
}
......
......@@ -20,7 +20,7 @@
<span
v-for="item in detail.industryList.split(',')"
:key="item"
class="mb-2 mr-[13px] flex-wrap bg-[rgba(44,104,255,0.08)] px-3 text-xs leading-[22px] text-[#2C68FF]"
class="mb-2 mr-[13px] flex-wrap bg-[rgba(44,104,255,0.08)] px-3 text-sm leading-[22px] text-[#2C68FF]"
>
{{ item }}
</span>
......
<!-- 土地详情 -->
<template>
<div v-if="detail" class="main-width mx-auto py-5">
<div class="space-y-4">
<div class="space-y-[44px]">
<DetailInfoCell>
<DetailMain
:type="DetailType.land"
......@@ -24,7 +24,7 @@
</DetailMain>
</DetailInfoCell>
<DetailInfoCell v-if="detail.landStatus" title="土地现状">
<div class="font-yahei text-xs leading-5 text-[#1A1A1A]">
<div class="font-yahei text-sm leading-5 text-[#1A1A1A]">
{{ detail.landStatus }}
</div>
</DetailInfoCell>
......
......@@ -7,10 +7,11 @@
:model="formData"
:rules="rule"
label-width="72px"
label-position="left"
class="font-yahei"
>
<div class="mb-[8px] flex h-[40px] items-center">
<span class="w-[72px] pr-3 text-right font-yahei text-sm text-[#4d4d4d]">手机号</span>
<span class="w-[72px] pr-3 text-left font-yahei text-sm text-[#4d4d4d]">手机号</span>
<p class="font-yahei text-sm text-[#1a1a1a]">{{ userInfo?.phone }}</p>
</div>
<ElFormItem prop="code" label="验证码">
......
......@@ -136,7 +136,6 @@ import { filterAddress, formatNumber } from '@/utils/filters.ts';
import { useJump } from '@/composable/useJump.ts';
import { RouteName } from '@/router/router.ts';
import { useIndustryBase } from '@/composable/useIndustryBase.ts';
import { handleNoAuth } from '@/utils/tools.ts';
import { identity } from 'lodash-es';
const { detail, initDetail } = useDetail<MyParkDevelopDetailResp>(RequestUrl.myParkDevelopDetail);
......@@ -539,7 +538,5 @@ const handleBack = () => {
});
};
initDetail().then(({ code }) => {
handleNoAuth(code);
});
initDetail();
</script>
......@@ -138,7 +138,6 @@ import { filterAddress, formatNumber } from '@/utils/filters.ts';
import { useJump } from '@/composable/useJump.ts';
import { RouteName } from '@/router/router.ts';
import { useIndustryBase } from '@/composable/useIndustryBase.ts';
import { handleNoAuth } from '@/utils/tools.ts';
import { identity } from 'lodash-es';
const { detail, initDetail } = useDetail<MyParkIndustrialDetailResp>(
......@@ -507,7 +506,5 @@ const handleBack = () => {
});
};
initDetail().then(({ code }) => {
handleNoAuth(code);
});
initDetail();
</script>
......@@ -12,7 +12,7 @@
<div class="p-[5px]">
<img class="h-[50px] w-[50px]" src="@/assets/images/icon-avatar.png" />
</div>
<div class="mt-[7px] text-xs font-medium leading-[22px] text-[#1A1A1A]">
<div class="mt-[7px] text-sm font-medium leading-[22px] text-[#1A1A1A]">
{{ userInfo?.phone }}
</div>
</div>
......
......@@ -25,7 +25,7 @@ export default defineConfig({
Components({
resolvers: [ElementPlusResolver()],
}),
legacy(),
// legacy(),
splitVendorChunkPlugin(),
],
resolve: {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment