admin.xpcool.com/apps/web-tdesign/src/views/house/community/index.vue
夏犀麟 7dc9bc6c2a fix: 修复工作台快捷入口错误路由 + 打通 Drawer 重构遗留的编译错误
- workbench 快捷入口「操作日志/登录日志」指向不存在的 /system/log/*,
  按后端菜单真实路由改为 /log/operation 与 /log/login
- 6 个页面(admin/role/menu/community/listing/push)Drawer 重构误用
  内部包路径 @vben-core/popup-ui(app 未直接依赖),改从 @vben/common-ui
  导入 useVbenDrawer 并合并同源 import
- 清理未使用变量:push 页 ref、preferences.vue loadLocaleMessages、
  user-dropdown.vue ref
- preferences 默认配置补缺失字段 languageToggleButtonPosition:'none'
- menu 页 submit 改三元、log 页嵌套三元抽 methodTheme 辅助函数
- vue-tsc 与全部 lint 钩子通过
2026-08-27 12:24:43 +08:00

267 lines
7.0 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<script lang="ts" setup>
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
import type { CommunityItem } from '#/api/house';
import { h, reactive, ref } from 'vue';
import { useAccess } from '@vben/access';
import { Page, useVbenDrawer, VbenTableAction } from '@vben/common-ui';
import { DialogPlugin, MessagePlugin } from 'tdesign-vue-next';
import { useVbenVxeGrid } from '#/adapter/vxe-table';
import {
createCommunity,
deleteCommunity,
getCommunityList,
updateCommunity,
} from '#/api/house';
// 小区管理:列表 + 新增/编辑抽屉 + 删除(软删除)
const { hasAccessByCodes } = useAccess();
const editing = ref<CommunityItem | null>(null);
// 新增/编辑小区抽屉vben 封装抽屉组件)
const [Drawer, drawerApi] = useVbenDrawer({
title: '新增小区',
onConfirm: submit,
});
const regionOptions = [
'云岩区',
'南明区',
'观山湖区',
'花溪区',
'乌当区',
'白云区',
'清镇市',
'修文县',
'开阳县',
'息烽县',
].map((r) => ({ label: r, value: r }));
// 筛选条件(分页由 grid 自动管理)
const query = reactive({ keyword: '', region: '' });
const form = reactive({
name: '',
region: '',
businessDistrict: '',
address: '',
lng: 0,
lat: 0,
buildYear: 0,
households: 0,
plotRatio: 0,
greenRate: 0,
propertyCompany: '',
propertyFee: 0,
developer: '',
});
function openCreate() {
editing.value = null;
Object.assign(form, {
name: '',
region: '',
businessDistrict: '',
address: '',
lng: 0,
lat: 0,
buildYear: 0,
households: 0,
plotRatio: 0,
greenRate: 0,
propertyCompany: '',
propertyFee: 0,
developer: '',
});
drawerApi.setState({ title: '新增小区' });
drawerApi.open();
}
function openEdit(row: CommunityItem) {
editing.value = row;
Object.assign(form, { ...row });
drawerApi.setState({ title: '编辑小区' });
drawerApi.open();
}
async function submit() {
// 编辑走更新、新增走创建
editing.value
? await updateCommunity(editing.value.id, form)
: await createCommunity(form);
MessagePlugin.success('保存成功');
drawerApi.close();
gridApi.query();
}
/** 删除小区(保留原确认弹窗行为) */
function onDelete(row: CommunityItem) {
const d = DialogPlugin.confirm({
header: `确认删除「${row.name}」?`,
onConfirm: async () => {
await deleteCommunity(row.id);
MessagePlugin.success('删除成功');
gridApi.query();
d.destroy();
},
});
}
const gridOptions: VxeTableGridOptions = {
columns: [
{ type: 'seq', width: 50, title: '#' },
{ field: 'id', title: 'ID', width: 70 },
{ field: 'name', title: '小区名称', width: 180 },
{ field: 'region', title: '区县', width: 100 },
{ field: 'businessDistrict', title: '板块', width: 120 },
{ field: 'address', title: '地址', showOverflow: 'tooltip' },
{ field: 'buildYear', title: '建成年份', width: 90 },
{ field: 'propertyCompany', title: '物业', width: 140 },
{
field: 'op',
title: '操作',
width: 160,
fixed: 'right',
slots: {
default: ({ row }: { row: CommunityItem }) =>
h(VbenTableAction, {
actions: [
// 编辑:按权限码显隐
{
text: '编辑',
onClick: () => openEdit(row),
auth: ['house:community:update'],
},
// 删除(危险操作标红)
{
text: '删除',
danger: true,
onClick: () => onDelete(row),
auth: ['house:community:delete'],
},
],
}),
},
},
],
pagerConfig: { pageSize: 10 },
proxyConfig: {
ajax: {
query: async ({
page,
}: {
page: { currentPage: number; pageSize: number };
}) => {
const data = await getCommunityList({
page: page.currentPage,
size: page.pageSize,
keyword: query.keyword || undefined,
region: query.region || undefined,
});
return { items: data.list ?? [], total: data.total ?? 0 };
},
},
},
};
const [Grid, gridApi] = useVbenVxeGrid({ gridOptions });
/** 触发查询(保留分页条件,因 grid 自动管理分页) */
function search() {
gridApi.query();
}
/** 重置筛选并回到第一页重新查询 */
function reset() {
query.keyword = '';
query.region = '';
gridApi.reload();
}
</script>
<template>
<Page auto-content-height>
<div class="flex items-center justify-between">
<div class="flex items-center gap-2">
<t-input
v-model="query.keyword"
clearable
placeholder="小区名称"
style="width: 200px"
@enter="search"
/>
<t-select
v-model="query.region"
clearable
:options="regionOptions"
placeholder="区县"
style="width: 140px"
/>
<t-button theme="primary" @click="search">查询</t-button>
<t-button variant="outline" @click="reset">重置</t-button>
</div>
<t-button
v-if="hasAccessByCodes(['house:community:create'])"
theme="primary"
@click="openCreate"
>
新增小区
</t-button>
</div>
<!-- 小区列表Vben Vxe Table + TableAction -->
<Grid />
<!-- 新增/编辑小区抽屉vben 封装抽屉组件) -->
<Drawer class="w-160">
<t-form label-align="right" label-width="90px">
<div class="grid grid-cols-2 gap-x-4">
<t-form-item label="小区名称" required>
<t-input v-model="form.name" placeholder="如:中天未来方舟" />
</t-form-item>
<t-form-item label="区县">
<t-select
v-model="form.region"
clearable
:options="regionOptions"
/>
</t-form-item>
<t-form-item label="板块">
<t-input v-model="form.businessDistrict" placeholder="如:会展城" />
</t-form-item>
<t-form-item label="建成年份">
<t-input-number v-model="form.buildYear" theme="normal" :min="0" />
</t-form-item>
<t-form-item label="物业公司">
<t-input v-model="form.propertyCompany" />
</t-form-item>
<t-form-item label="开发商">
<t-input v-model="form.developer" />
</t-form-item>
<t-form-item label="地址" class="col-span-2">
<t-input v-model="form.address" />
</t-form-item>
<t-form-item label="经度">
<t-input-number
v-model="form.lng"
theme="normal"
:decimal-places="6"
/>
</t-form-item>
<t-form-item label="纬度">
<t-input-number
v-model="form.lat"
theme="normal"
:decimal-places="6"
/>
</t-form-item>
</div>
</t-form>
</Drawer>
</Page>
</template>