Files
leaser_front/src/views/business/project/index.vue
T

252 lines
8.0 KiB
Vue
Raw Normal View History

2025-06-22 23:55:55 +08:00
<template>
<div class="business_project_wrap">
<Breadcrumb :items="['menu.business', 'menu.business.project']" />
2025-07-31 23:43:28 +08:00
<a-card class="general-card full_height">
<template #title>
<div class="card-title_between">
2025-07-06 00:12:32 +08:00
<p class="title">{{ t('menu.business.project') }}</p>
<div class="flex_center_between">
<a-space>
<a-input-search
v-model="queryParams.keyword"
:style="{ width: '320px' }"
2025-07-06 00:12:32 +08:00
:placeholder="t('please.enter', { placeholder: t('content') })"
@search="handleSearch"
/>
2025-08-11 23:28:10 +08:00
<a-button @click="handleFilter">
<template #icon>
<icon-filter />
2025-06-24 01:24:43 +08:00
</template>
2025-07-06 00:12:32 +08:00
{{ t('table.filter') }}
</a-button>
<a-button>
<template #icon>
<icon-download />
2025-06-24 01:24:43 +08:00
</template>
2025-07-06 00:12:32 +08:00
{{ t('table.export') }}
</a-button>
<a-button type="primary" @click="handleAddProject">
<template #icon>
<icon-plus />
2025-06-24 01:24:43 +08:00
</template>
2025-07-06 00:12:32 +08:00
{{ t('add-project') }}
</a-button>
</a-space>
</div>
</div>
</template>
2025-07-06 00:12:32 +08:00
<!-- 使用新的 DataTable 组件 -->
<DataTable
:data="renderData"
2025-07-06 00:12:32 +08:00
:columns="projectColumn"
:loading="loading"
:total="total"
:current="current"
:page-size="pageSize"
@page-change="onPageChange"
2025-07-06 00:12:32 +08:00
@page-size-change="onPageSizeChange"
>
<template #type="{ record }">
<a-tag checkable :color="getProjectTypeColor(record.type)">
{{ record.typeName }}
</a-tag>
</template>
<template #rate="{ record }">
<a-progress
:percent="Number(record.rentRate)"
color="green"
:style="{ width: '100px' }"
/>
</template>
<template #operate="{ record }">
<a-space>
2025-08-11 23:28:10 +08:00
<a-button
:loading="isLoadingDetail"
@click="handleDetail(record.id)"
>查看</a-button
>
<a-button
:loading="isLoadingEdit"
type="primary"
@click="handleEditProject(record.id)"
>编辑</a-button
>
2025-08-11 23:28:10 +08:00
<a-popover trigger="click" position="bottom">
<a-button>{{ $t('more') }}</a-button>
<template #content>
<a-space direction="vertical">
<a-button @click="handleWatchHouse(record.id)">
查看房源
</a-button>
<a-button status="danger" @click="handleDel(record.id)">
删除项目
</a-button>
</a-space>
</template>
</a-popover>
</a-space>
</template>
2025-07-06 00:12:32 +08:00
</DataTable>
</a-card>
<projectFormDrawer
v-model:visible="showDrawer"
:is-edit="isEdit"
:record="currentProjectInfo"
2025-08-11 23:28:10 +08:00
@submitted="getProjectListData"
/>
<projectInfoDrawer
v-model:visible="showProjectInfoDrawer"
:project-id="currentProjectId"
:detail-info="currentProjectInfo"
/>
<projectListFilterDrawer
v-model:visible="showListFilterDrawer"
@confirm="handleFilterConfirm"
/>
</div>
2025-06-22 23:55:55 +08:00
</template>
2025-06-24 01:24:43 +08:00
<script lang="ts" setup>
2025-07-31 23:43:28 +08:00
import { ref, onMounted } from 'vue';
import useLoading from '@/hooks/loading';
2025-07-06 00:12:32 +08:00
import { useI18n } from 'vue-i18n';
import type { TableColumnData } from '@arco-design/web-vue';
import useDataTable from '@/composables/useDataTable';
2025-08-11 23:28:10 +08:00
import { ProjectItem } from '@/types/business';
import { getProjectList, getProjectDetail } from '@/api/business';
import { ProjectPaginationParams, ProjectType } from '@/types/comm';
import projectFormDrawer from './drawer/project-form-drawer.vue';
2025-08-11 23:28:10 +08:00
import projectInfoDrawer from './drawer/project-info-drawer.vue';
import projectListFilterDrawer from './drawer/project-list-filter-drawer.vue';
2025-07-06 00:12:32 +08:00
const { t } = useI18n();
const { loading } = useLoading(false);
const showDrawer = ref<boolean>(false);
2025-08-11 23:28:10 +08:00
const showProjectInfoDrawer = ref<boolean>(false);
const showListFilterDrawer = ref<boolean>(false);
const currentProjectId = ref<number | null>(null);
const isLoadingEdit = ref<boolean>(false);
2025-08-11 23:28:10 +08:00
const isLoadingDetail = ref<boolean>(false);
const isEdit = ref<boolean>(false);
2025-08-11 23:28:10 +08:00
const currentProjectInfo = ref<ProjectItem | null>(null);
2025-07-31 23:43:28 +08:00
const projectList = ref<ProjectItem[]>([]);
2025-07-06 00:12:32 +08:00
const {
data: renderData,
columns: projectColumn,
total,
current,
pageSize,
setData,
setColumns,
setTotal,
setCurrent,
setPageSize,
2025-07-31 23:43:28 +08:00
setLoading,
2025-07-06 00:12:32 +08:00
} = useDataTable({
initialPage: 1,
initialPageSize: 10,
pageSizeOptions: [10, 20, 50, 100],
});
// 列配置
const columns: TableColumnData[] = [
{ title: '项目信息', dataIndex: 'name', key: 'name' },
{ title: '项目类型', dataIndex: 'type', key: 'type', slotName: 'type' },
{ title: '管理面积', dataIndex: 'RentAreaStr', key: 'RentAreaStr' },
{ title: '可租面积', dataIndex: 'RoomAreaStr', key: 'RoomAreaStr' },
{
title: '出租率',
dataIndex: 'RentRateStr',
key: 'RentRateStr',
slotName: 'rate',
},
{ title: '房源数量', dataIndex: 'roomNum', key: 'roomNum' },
{ title: '创建时间', dataIndex: 'createdAt', key: 'createdAt' },
2025-07-06 00:12:32 +08:00
{ title: '操作', key: 'operate', slotName: 'operate', width: 200 },
];
const queryParams = ref<ProjectPaginationParams>({
page: current.value,
page_size: pageSize.value,
keyword: '',
type: null,
province_ids: null,
rent_rate_min: null,
rent_rate_max: null,
});
2025-07-31 23:43:28 +08:00
const getProjectListData = async () => {
setLoading(true);
const { code, data } = await getProjectList(queryParams.value);
2025-07-31 23:43:28 +08:00
if (code === 200 && data) {
const { projectsList, page } = data;
projectList.value = Array.isArray(projectsList) ? projectsList : [];
setData(projectList.value);
2025-07-31 23:43:28 +08:00
setTotal(page?.total ? page.total : 0);
}
setLoading(false);
};
2025-08-11 23:28:10 +08:00
const getProjectDetailData = async (id: number, edit: boolean) => {
if (currentProjectInfo.value && currentProjectInfo.value?.id === id) return;
edit ? (isLoadingEdit.value = true) : (isLoadingDetail.value = true);
const { code, data } = await getProjectDetail(id);
if (code === 200 && data) {
currentProjectInfo.value = data.project;
}
isLoadingEdit.value = false;
2025-08-11 23:28:10 +08:00
isLoadingDetail.value = false;
};
const handleWatchHouse = async (id: number) => {
try {
console.log(id, 'is id');
} catch (error) {
// 处理错误
}
};
const handleFilterConfirm = ({ typeIds, cityIds, rentRate }) => {
queryParams.value.type = typeIds;
queryParams.value.province_ids = cityIds;
queryParams.value.rent_rate_min = rentRate[0];
queryParams.value.rent_rate_max = rentRate[1];
getProjectListData();
};
const handleDel = (id: number) => {
console.log(id, 'iiii');
};
2025-07-06 00:12:32 +08:00
// 分页事件处理
const onPageChange = (page: number) => {
setCurrent(page);
2025-07-31 23:43:28 +08:00
current.value = page;
};
2025-07-31 23:43:28 +08:00
const onPageSizeChange = (size: number) => {
setPageSize(size);
pageSize.value = size;
};
const handleAddProject = () => {
isEdit.value = false;
currentProjectInfo.value = null;
showDrawer.value = true;
};
const handleEditProject = async (id: number) => {
isEdit.value = true;
2025-08-11 23:28:10 +08:00
await getProjectDetailData(id, true);
showDrawer.value = true;
};
2025-08-11 23:28:10 +08:00
const handleDetail = async (id: number) => {
await getProjectDetailData(id, false);
showProjectInfoDrawer.value = true;
};
const handleSearch = () => {
getProjectListData();
};
2025-08-11 23:28:10 +08:00
const handleFilter = () => {
showListFilterDrawer.value = true;
};
const getProjectTypeColor = (type: ProjectType) => {
const typeMap = { 1: 'green', 2: 'red', 3: 'orange' };
return typeMap[type];
};
2025-07-31 23:43:28 +08:00
onMounted(() => {
setColumns(columns);
getProjectListData();
});
</script>