Commit e349f6bb authored by shilei's avatar shilei

feat: 列表筛选

parent 6e714dbc
......@@ -34,11 +34,12 @@ module.exports = {
'no-debugger': 'off',
'no-plusplus': 'off',
'no-shadow': 'off',
'no-param-reassign': ['error', { props: false }],
'@typescript-eslint/no-shadow': 'error',
'no-unused-vars': 'off',
'no-else-return': 'off',
'@typescript-eslint/no-unused-vars': 'error',
'vue-scoped-css/enforce-style-type': ['error', { allows: ['plain', 'scoped'] }],
'vue-scoped-css/enforce-style-type': ['error', { allows: ['plain', 'scoped', 'module'] }],
'vue/block-order': [
'error',
{
......
......@@ -8,6 +8,7 @@ export {}
declare module 'vue' {
export interface GlobalComponents {
CommonHeader: typeof import('./src/components/common/CommonHeader.vue')['default']
copy: typeof import('./src/components/list/list-land-item copy.vue')['default']
DetailInfoCell: typeof import('./src/components/detail/DetailInfoCell.vue')['default']
DetailMain: typeof import('./src/components/detail/DetailMain.vue')['default']
ElButton: typeof import('element-plus/es')['ElButton']
......@@ -20,6 +21,7 @@ declare module 'vue' {
ElForm: typeof import('element-plus/es')['ElForm']
ElFormItem: typeof import('element-plus/es')['ElFormItem']
ElHeader: typeof import('element-plus/es')['ElHeader']
ElIcon: typeof import('element-plus/es')['ElIcon']
ElInput: typeof import('element-plus/es')['ElInput']
ElMain: typeof import('element-plus/es')['ElMain']
ElMenu: typeof import('element-plus/es')['ElMenu']
......@@ -32,8 +34,12 @@ declare module 'vue' {
ElSubMenu: typeof import('element-plus/es')['ElSubMenu']
ElSwitch: typeof import('element-plus/es')['ElSwitch']
ElTimePicker: typeof import('element-plus/es')['ElTimePicker']
Filter: typeof import('./src/components/filter/filter.vue')['default']
FilterView: typeof import('./src/components/filter/filter-view.vue')['default']
ListCarrierItem: typeof import('./src/components/list/list-carrier-item.vue')['default']
ListIndustryCategory: typeof import('./src/components/list/list-industryCategory.vue')['default']
ListLand: typeof import('./src/components/list/list-land.vue')['default']
ListLandItem: typeof import('./src/components/list/list-land-item.vue')['default']
ListPagination: typeof import('./src/components/list/list-pagination.vue')['default']
RouterLink: typeof import('vue-router')['RouterLink']
RouterView: typeof import('vue-router')['RouterView']
......
This diff is collapsed.
@tailwind base;
@tailwind components;
@tailwind utilities;
/* 单行文字溢出虚点显 示*/
.ell {
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
}
/* 两行文字溢出虚点显 示*/
.ell2 {
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}
@import './base';
@import './reset';
html,body {
font-family: -apple-system,BlinkMacSystemFont,PingFang SC,Microsoft YaHei,Helvetica Neue,Source Han Sans SC,Noto Sans CJK SC,WenQuanYi Micro Hei,sans-serif;
html,
body {
font-family:
-apple-system,
BlinkMacSystemFont,
PingFang SC,
Microsoft YaHei,
Helvetica Neue,
Source Han Sans SC,
Noto Sans CJK SC,
WenQuanYi Micro Hei,
sans-serif;
}
#app {
.el-checkbox {
margin-right: 20px;
}
.el-checkbox__input.is-checked .el-checkbox__inner {
background-color: #c0322b;
border-color: #c0322b;
}
.el-checkbox__input.is-checked + .el-checkbox__label {
color: rgba(0, 0, 0, 0.65);
}
.el-checkbox__label {
font-size: 12px;
font-weight: 400;
color: rgba(0, 0, 0, 0.45);
}
.el-input__inner::-webkit-outer-spin-button,
.el-input__inner::-webkit-inner-spin-button {
-webkit-appearance: none;
}
.el-input__inner[type='number'] {
-moz-appearance: textfield;
}
}
<template>
<div class="flex items-center justify-between pt-[12px] pl-[40px] header-view">
<div class="header-view flex items-center justify-between pl-[40px] pt-[12px]">
<!-- <div>logo</div> -->
<div class="flex flex-1 justify-start">
<ElMenu
......
export const defaultFiltersConfig = {
// 产业园级别
park_level: {
type: 'select',
label: '产业园级别',
key: 'levelName',
},
// 招商方向
park_direction: {
type: 'select',
label: '招商方向',
key: 'investmentDirection',
},
// 产业园面积
park_area: {
type: 'select',
label: '产业园面积',
key: 'coverArea',
plugins: {
type: 'section',
unit: '亩',
},
},
// 产业资源
park_resources: {
type: 'select',
label: '产业资源',
key: 'parkResourcesList',
multiple: true,
},
// 产业政策
industry_policy: {
type: 'select',
label: '产业政策',
key: 'industryPolicyList',
multiple: true,
},
// 开发区级别
development_level: {
type: 'select',
label: '开发区级别',
key: 'levelName',
multiple: false,
},
// 开发区类型
development_type: {
type: 'select',
label: '开发区类型',
key: 'type',
multiple: false,
},
// 招商方向
development_direction: {
type: 'select',
label: '招商方向',
key: 'investmentDirection',
multiple: false,
},
// 开发区面积
development_area: {
type: 'select',
label: '开发区面积',
key: 'planArea',
multiple: false,
plugins: {
type: 'section',
unit: '平方公里',
},
},
// 土地价格
land_price: {
type: 'select',
label: '土地价格',
key: 'price',
multiple: false,
plugins: {
type: 'section',
unit: '万元/亩',
},
},
// 土地类型
land_type: {
type: 'select',
label: '土地类型',
key: 'landType',
multiple: false,
},
// 土地面积
land_area: {
type: 'select',
label: '土地面积',
key: 'area',
multiple: false,
plugins: {
type: 'section',
unit: '亩',
},
},
// 载体面积
carrier_area: {
type: 'select',
label: '载体面积',
key: 'carrierArea',
multiple: false,
plugins: {
type: 'section',
unit: '㎡',
},
},
// 载体类型
carrier_type: {
type: 'select',
label: '载体类型',
key: 'typeInfo',
multiple: false,
},
// 建筑结构
carrier_construction: {
type: 'select',
label: '建筑结构',
key: 'carrierConstruction',
multiple: false,
},
// 标准层高
floor_height: {
type: 'select',
label: '标准层高',
key: 'floorHeight',
multiple: false,
plugins: {
type: 'section',
unit: 'm',
},
},
// 标准承重
load_bearing: {
type: 'select',
label: '标准承重',
key: 'loadBearing',
multiple: false,
plugins: {
type: 'section',
unit: 'kg/㎡',
},
},
// 柱距
pillar_distance: {
type: 'select',
label: '柱距',
key: 'pillarDistance',
multiple: false,
plugins: {
type: 'section',
unit: 'm',
},
},
};
<template>
<div class="filter-view">
<div v-if="selected.length" class="flex text-xs text-black/[.65]">
<span class="w-[100px] shrink-0 leading-9 text-black/[.65]">已选条件</span>
<div class="flex w-[701px] flex-wrap pt-1.5">
<span
v-for="(item, index) in selected"
:key="index"
class="selected-item mb-1 mr-2.5 flex items-center px-2 py-1 leading-none"
>
{{ item.label }}{{
Array.isArray(item.value) ? item.value.join(' | ') : item.valueLabel
}}
<img
class="ml-2.5 h-3 w-3 cursor-pointer"
src="@/assets/images/icon-close.png"
alt=""
@click="removeSelected(item)"
/>
</span>
</div>
<div
class="ml-[15px] flex h-[25px] w-[104px] cursor-pointer items-center justify-center"
@click="removeAll"
>
<img class="h-3 w-3" src="@/assets/images/icon-del.png" alt="" />
<span>清空所有条件</span>
</div>
</div>
<div v-for="(filter, index) in filterList" :key="index" class="flex flex-wrap">
<div class="w-[100px] shrink-0 text-xs leading-9 text-black/[.65]">
<span>{{ filter.label }}</span>
</div>
<div>
<div v-if="!filter.multiple" class="flex pt-1.5 text-xs">
<div
class="shrink-0"
@click="
filter.value = '';
filter.valueLabel = '';
"
>
<span
class="block cursor-pointer px-2 py-1 text-black/[0.45]"
:class="{ selected: !filter.value }"
>
全部
</span>
</div>
<div class="flex">
<div v-for="(item, idx) in filter.list" :key="idx" class="Filter--keysWrap">
<div
class="Filter-ListWrap cursor-pointer px-2 py-1 text-black/[.45]"
:class="{ selected: filter.value === item.dictValue }"
@click="handleFilterClick(item, filter)"
>
<span>
{{ item.dictLabel }}
</span>
</div>
</div>
</div>
<div v-if="filter.plugins" class="ml-2 flex items-center">
<template v-if="filter.plugins.type === 'section'">
<ElInput
v-model="filter.plugins.value1"
class="section-input"
type="number"
placeholder=""
></ElInput>
<span class="mx-1">-</span>
<ElInput
v-model="filter.plugins.value2"
class="section-input"
type="number"
placeholder=""
></ElInput>
<span class="ml-1 text-black/[0.45]">{{ filter.plugins.unit }}</span>
<button class="btn-default" @click="handleEnter(filter)">确定</button>
</template>
</div>
</div>
<div v-else>
<ElCheckboxGroup v-model="filter.value">
<ElCheckbox v-for="(item, idx) in filter.list" :key="idx" :label="item.dictLabel">
{{ item.dictLabel }}
</ElCheckbox>
</ElCheckboxGroup>
</div>
</div>
<div class="Filter--operateWrap" style="width: 100px"></div>
</div>
</div>
</template>
<script setup lang="ts">
import { ref, onMounted, computed, watch } from 'vue';
import { FilterListItem } from '@/types/common.ts';
import { filterStore } from '@/stores/filterEnum.ts';
import { defaultFiltersConfig } from '@/components/filter/config.ts';
import { isEmpty } from 'lodash-es';
const props = defineProps<{
filterKeyList: string[];
}>();
function handleFilterClick<T>(select: Ref<T>, filters: Ref<T>) {
console.log(select, filters);
filters.value = select.dictValue;
filters.valueLabel = select.dictLabel;
console.log(filters);
}
const filterList = ref<FilterListItem[]>([]);
onMounted(async () => {
const store = filterStore();
const filterEnum = await store.getFilterEnum();
console.log(props);
props.filterKeyList.forEach((item) => {
const list = filterEnum[item];
filterList.value.push({ ...defaultFiltersConfig[item], list });
});
});
// 处理输入
function handleEnter<T>(arg: Ref<T>) {
if (!isEmpty(arg.plugins.value1) || !isEmpty(arg.plugins.value2)) {
if (isEmpty(arg.plugins.value2)) {
arg.valueLabel = `≥${arg.plugins.value1}${arg.plugins.unit}`;
arg.value = `${arg.plugins.value1}-`;
} else if (isEmpty(arg.plugins.value1)) {
arg.valueLabel = `≤${arg.plugins.value2}${arg.plugins.unit}`;
arg.value = `0-${arg.plugins.value2}`;
} else {
if (Number(arg.plugins.value1) > Number(arg.plugins.value2)) {
const temp = arg.plugins.value1;
arg.plugins.value1 = arg.plugins.value2;
arg.plugins.value2 = temp;
}
arg.valueLabel = `${arg.plugins.value1}-${arg.plugins.value2}${arg.plugins.unit}`;
arg.value = `${arg.plugins.value1}-${arg.plugins.value2}`;
}
}
}
// 删除已选筛选项
function removeSelected(select: any) {
filterList.value.forEach((item) => {
if (item.label === select.label) {
item.value = Array.isArray(item.value) ? [] : '';
if (item.plugins) {
item.plugins.value1 = '';
item.plugins.value2 = '';
}
}
});
}
// 已选项
const selected = computed(() => {
let temp = [];
temp = filterList.value.filter((item) => {
return !isEmpty(item.value);
});
return temp || [];
});
// 删除所有已选筛选项
function removeAll() {
console.log(selected.value);
for (const i of selected.value) {
removeSelected(i);
}
}
// 选项改变事件传递
const emit = defineEmits(['change']);
watch(
selected,
(newVal) => {
console.log(newVal);
emit('change', selected);
},
{
immediate: false,
},
);
</script>
<style lang="scss" scoped>
.filter-view {
background: #fbfbfb;
padding-top: 10px;
padding-left: 20px;
width: 926px;
}
.selected {
background: rgba(192, 50, 43, 0.06);
color: #c0322b;
}
.section-input {
width: 52px;
::v-deep {
.el-input__wrapper {
border-radius: 2px;
padding: 4px 8px;
}
.el-input__inner {
height: 17px;
}
}
}
.btn-default {
background: #c0322b;
width: 44px;
height: 22px;
color: #fff;
margin-left: 8px;
font-size: 12px;
border-radius: 2px;
}
.selected-item {
background: #f2f2f2;
border: 1px solid rgba(0, 0, 0, 0.15);
height: 25px;
line-height: 15px;
}
</style>
<template>
<div class="flex">
<div class="media-left mr-[16px]">
<img class="h-[156px] w-[208px]" :src="detail.imgUrl" alt="" />
</div>
<div
class="media-right relative flex w-[408px] flex-col justify-between pt-[8px] text-[12px] leading-[20px] text-[#4d4d4d]"
>
<p class="ell2 mb-[7px] text-[20px] font-semibold leading-[20px] text-[#1a1a1a]">
{{ detail.provinceName?.replace('省', '').replace('市', '')
}}{{ detail.cityName?.replace('市', '') }}{{ detail.regionName }}{{ detail.area }}{{
detail.type
}}
</p>
<div>
<div class="mb-[8px] flex items-center">
<img class="info-icon" src="@/assets/images/icon-local.png" alt="" />
<p>所在地区:{{ detail.provinceName }}-{{ detail.cityName }}-{{ detail.regionName }}</p>
</div>
<div class="mb-[8px] flex items-center">
<img class="info-icon" src="@/assets/images/icon-map.png" alt="" />
<p>建筑面积:{{ detail.area }}</p>
</div>
<div class="mb-[8px] flex items-center">
<img class="info-icon" src="@/assets/images/icon-draw.png" alt="" />
<p>载体类型:{{ detail.type }}</p>
</div>
</div>
</div>
</div>
</template>
<script lang="ts" setup>
import type { CarrierListItem } from '@/types/api/carrierList';
withDefaults(
defineProps<{
detail: CarrierListItem;
}>(),
{},
);
</script>
<style lang="scss" scoped>
.info-icon {
width: 16px;
height: 16px;
margin-right: 4px;
}
</style>
<template>
<div class="flex">
<div class="media-left mr-[16px]">
<img class="h-[156px] w-[208px]" :src="detail.imgUrl" alt="" />
</div>
<div
class="media-right relative flex w-[408px] flex-col justify-between pt-[8px] text-[12px] leading-[20px] text-[#4d4d4d]"
>
<p class="ell2 mb-[7px] text-[20px] font-semibold leading-[20px] text-[#1a1a1a]">
{{ detail.provinceName?.replace('省', '').replace('市', '')
}}{{ detail.cityName?.replace('市', '') }}{{ detail.regionName }}{{ detail.area }}{{
detail.landType
}}
</p>
<div>
<div class="mb-[8px] flex items-center">
<img class="info-icon" src="@/assets/images/icon-local.png" alt="" />
<p>所在地区:{{ detail.provinceName }}-{{ detail.cityName }}-{{ detail.regionName }}</p>
</div>
<div class="mb-[8px] flex items-center">
<img class="info-icon" src="@/assets/images/icon-map.png" alt="" />
<p>占地面积:{{ detail.area }}</p>
</div>
<div class="mb-[8px] flex items-center">
<img class="info-icon" src="@/assets/images/icon-draw.png" alt="" />
<p>土地属性:{{ detail.landType }}</p>
</div>
</div>
<div class="absolute bottom-[8px] right-0 text-[20px] font-semibold text-[#C0322B]">
{{ detail.price }}元/亩
</div>
</div>
</div>
</template>
<script lang="ts" setup>
import type { LandListItem } from '@/types/api/landList';
withDefaults(
defineProps<{
detail: LandListItem;
}>(),
{},
);
</script>
<style lang="scss" scoped>
.info-icon {
width: 16px;
height: 16px;
margin-right: 4px;
}
</style>
......@@ -9,7 +9,7 @@ import { useRequest } from './useRequest.ts';
export function useListView<
T extends { id: number; [index: string]: any },
C extends Record<any, any>,
>(url: RequestUrl) {
>(url: RequestUrl, searchParams: any = {}) {
const router = useRouter();
const { request: requestList } = useRequest<CommonListResp<T>, CommonListParams<C>>(url, {
method: 'POST',
......@@ -18,11 +18,11 @@ export function useListView<
const { pageNum, pageSize, totalCount, queryList } = useQueryList<T, C>(requestList);
const datas = ref([]) as Ref<T[]>;
const searchParams = ref({}) as Ref<C>;
// const searchParams = ref({}) as Ref<C>;
watchEffect(async () => {
try {
const { data } = await queryList(searchParams.value);
const { data } = await queryList(searchParams);
datas.value = data.records;
} catch (error) {
console.log(error);
......
......@@ -26,7 +26,7 @@ export function useQueryList<T, C>(queryFn: QueryFn<T, CommonListParams<C>>) {
};
const changePageNum = (page: number) => {
pageSize.value = page;
pageNum.value = page;
};
const changeTotalCount = (total: number) => {
......
import { ref } from 'vue';
import { defineStore } from 'pinia';
import { useRequest } from '@/composable/useRequest.ts';
import { RequestUrl } from '@/types/api.ts';
import type { FilterListItem } from '@/types/common.ts';
import type { Ref } from 'vue';
export const filterStore = defineStore('filterEnum', () => {
const filterEnum: any = ref<FilterListItem[]>([]);
async function getFilterEnum(): Promise<Ref<FilterListItem> | Error> {
if (filterEnum.value.length) {
return filterEnum;
} else {
try {
const queryStr =
'park_level,park_direction,park_area,park_resources,land_price,industry_policy,development_level,development_type,development_direction,development_area,industry_policy,land_type,land_area,carrier_area,carrier_type,carrier_construction,floor_height,load_bearing,pillar_distance';
const { request: getFilterList } = useRequest(RequestUrl.getFiltersList, {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
});
const data = await getFilterList({ code: queryStr });
filterEnum.value = data;
return filterEnum.value;
} catch (error: any) {
return new Error(error);
}
}
}
return { filterEnum, getFilterEnum };
});
......@@ -15,4 +15,10 @@ export enum RequestUrl {
landList = '/lyy/api/land/v1.0/page',
/** 土地详情 */
landDetail = '/lyy/api/land/v1.0/detail',
/** 载体列表 */
carrierList = '/lyy/api/carrier/v1.0/page',
/** 载体详情 */
carrierDetail = '/lyy/api/carrier/v1.0/detail',
/** 筛选项查询 */
getFiltersList = '/lyy/api/sysDictData/listByCodes',
}
/**
* 载体列表请求条件参数
*/
export interface CarrierListCondition {
/** 面积 */
carrierArea: string;
/** */
cityCode: string;
/** */
cityName: string;
/** 建筑结构 */
carrierConstruction: string;
/** 载体名称 */
name: string;
/** */
provinceCode: string;
/** */
provinceName: string;
/** */
regionCode: string;
/** */
regionName: string;
/** 标准层高 */
floorHeight?: string;
/** 标准承重 */
loadBearing?: string;
/** 柱距 */
pillarDistance?: string;
/** 载体类型 */
typeInfo?: string;
}
/**
* 载体列表项
*/
export interface CarrierListItem {
/** 面积(亩) */
area: number;
/** */
cityCode: string;
/** */
cityName: string;
/** */
id: number;
/** 首屏图片 */
imgUrl: string;
/** 载体类型 */
type: number;
/** 地块名称 */
name: string;
/** */
provinceCode: string;
/** */
provinceName: string;
/** */
regionCode: string;
/** */
regionName: string;
}
......@@ -45,3 +45,21 @@ export interface CommonListParams<T> {
property?: string;
}[];
}
/** *
* 筛选项
*/
export type FilterListItem = {
label: string;
key: string;
list: any[];
type: string;
multiple?: boolean;
value?: string | string[];
plugin?: {
type: string;
unit: string;
value1?: number | string;
value2?: number | string;
};
};
......@@ -18608,4 +18608,4 @@
"name": "澳 门",
"children": []
}
]
\ No newline at end of file
]
......@@ -53,8 +53,8 @@
</div>
<div class="map-search-info">
<p
class="position-item"
v-for="item in infoList"
class="position-item"
@mousemove="showInfoWindow(item)"
@mouseout="hideInfoWindow"
>
......@@ -79,7 +79,7 @@ interface Window {
};
let placeSearch: any = null;
let infoWindow: any = null;
let markers: any = [];
const markers: any = [];
let AMapRoot: any = null;
onMounted(() => {
AMapLoader.load({
......@@ -123,7 +123,7 @@ onMounted(() => {
});
});
let infoList = ref<any[]>([]);
const infoList = ref<any[]>([]);
const handleSearch = (keyWords: String, radius: Number, type: String) => {
map1.remove(markers);
placeSearch.setType(type);
......@@ -136,7 +136,7 @@ const handleSearch = (keyWords: String, radius: Number, type: String) => {
console.log('searchNearBy', status, results);
if (status === 'complete') {
infoList.value = results.poiList.pois;
for (let item of results.poiList.pois) {
for (const item of results.poiList.pois) {
const marker = new AMapRoot.Marker({
map: map1,
position: [item.location.lng, item.location.lat],
......@@ -146,13 +146,13 @@ const handleSearch = (keyWords: String, radius: Number, type: String) => {
marker.on('mouseover', () => {
console.log('mouseover', item.name);
let info = [];
const info = [];
info.push("<div class='input-card'>");
info.push(`<p class='input-item'>${item.name}</p>`);
info.push(`<p class='input-item'>${item.distance}米</p></div>`);
infoWindow = new AMapRoot.InfoWindow({
content: info.join(''), //使用默认信息窗体框样式,显示信息内容
content: info.join(''), // 使用默认信息窗体框样式,显示信息内容
isCustom: true,
autoMove: false,
offset: new AMapRoot.Pixel(0, -35),
......@@ -174,12 +174,12 @@ const handleSearch = (keyWords: String, radius: Number, type: String) => {
};
const showInfoWindow = (info: any) => {
let infoContent = [];
const infoContent = [];
infoContent.push("<div class='input-card'>");
infoContent.push(`<p class='input-item'>${info.name}</p>`);
infoContent.push(`<p class='input-item'>${info.distance}米</p></div>`);
infoWindow = new AMapRoot.InfoWindow({
content: infoContent.join(''), //使用默认信息窗体框样式,显示信息内容
content: infoContent.join(''), // 使用默认信息窗体框样式,显示信息内容
isCustom: true,
autoMove: false,
offset: new AMapRoot.Pixel(0, -35),
......
<!-- 载体 -->
<template>
<div>载体</div>
<div class="container">
<FilterView
class="mb-6"
:filter-key-list="filterKeyList"
@change="handleFilterChange"
></FilterView>
<div>
<!-- 载体列表 -->
<p>
搜索到
<span>{{ totalCount }}</span>
个相关载体
</p>
<div>
<div
v-for="item in datas"
:key="item.id"
class="mb-5"
@click="handleDetail(RouteName.landDetail, item)"
>
<CarrierListItemView :detail="item"></CarrierListItemView>
</div>
<ListPagination
v-model:current-page="pageNum"
v-model:page-size="pageSize"
:total="totalCount"
></ListPagination>
</div>
</div>
</div>
</template>
<script lang="ts" setup></script>
<script lang="ts" setup>
import { useListView } from '@/composable/useListView.ts';
import { RouteName } from '@/router/router.ts';
import { RequestUrl } from '@/types/api.ts';
import ListPagination from '@/components/list/list-pagination.vue';
import CarrierListItemView from '@/components/list/list-carrier-item.vue';
import FilterView from '@/components/filter/filter-view.vue';
import type { CarrierListCondition, CarrierListItem } from '@/types/api/carrierList';
import { ref } from 'vue';
const { pageNum, pageSize, totalCount, datas, handleDetail, queryList } = useListView<
CarrierListItem,
CarrierListCondition
>(RequestUrl.carrierList);
// 筛选项
const filterKeyList = ref([
'carrier_area',
'carrier_type',
'carrier_construction',
'floor_height',
'load_bearing',
'pillar_distance',
]);
// 处理筛选条件
const handleFilterChange = async function (selectList) {
const temp: any = {};
for (const item of selectList.value) {
temp[item.key] = item.value;
}
pageNum.value = 1;
const { data } = await queryList(temp);
datas.value = data.records;
};
</script>
<style lang="scss" scoped>
.container {
width: 926px;
margin: 0 auto;
}
</style>
<!-- 土地列表 -->
<template>
<div>
<div class="container">
<div>
<div v-for="item in datas" :key="item.id" @click="handleDetail(RouteName.landDetail, item)">
<div>{{ item.name }}</div>
<FilterView
:filter-key-list="filterKeyList"
class="mb-6"
@change="handleFilterChange"
></FilterView>
<div
v-for="item in datas"
:key="item.id"
class="mb-5"
@click="handleDetail(RouteName.landDetail, item)"
>
<LandListItemView :detail="item"></LandListItemView>
</div>
<ListPagination
......@@ -20,10 +30,30 @@ import { useListView } from '@/composable/useListView.ts';
import { RouteName } from '@/router/router.ts';
import { RequestUrl } from '@/types/api.ts';
import ListPagination from '@/components/list/list-pagination.vue';
import LandListItemView from '@/components/list/list-land-item.vue';
import FilterView from '@/components/filter/filter-view.vue';
import type { LandListCondition, LandListItem } from '@/types/api/landList';
import { onMounted, ref } from 'vue';
const { pageNum, pageSize, totalCount, datas, handleDetail } = useListView<
LandListItem,
LandListCondition
>(RequestUrl.landList);
const Response = useListView<LandListItem, LandListCondition>(RequestUrl.landList);
const { datas, pageNum, totalCount, pageSize, handleDetail, queryList } = Response;
const filterKeyList = ref(['land_price', 'land_type', 'land_area']);
onMounted(() => {});
// 处理筛选条件
const handleFilterChange = async function (selectList) {
const temp: any = {};
for (const item of selectList.value) {
temp[item.key] = item.value;
}
pageNum.value = 1;
const { data } = await queryList(temp);
datas.value = data.records;
};
</script>
<style scoped>
.container {
width: 926px;
margin: 0 auto;
}
</style>
module.exports = {
lintOnSave: false
}
devServer: {
overlay: {
warnings: false,
errors: false,
},
lintOnSave: false,
},
};
This diff is collapsed.
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