Files
vueadmin/src/pages/system/area/index.vue
2026-01-21 22:53:25 +08:00

276 lines
6.5 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.
<template>
<div class="pages system-area">
<sc-table ref="tableRef" :columns="columns" :data-source="dataSource" :loading="loading"
:pagination="pagination" @refresh="loadData" @change="handleTableChange" :row-selection="rowSelection"
:show-action="true" :actions="actions" :show-index="true" :show-striped="true">
<!-- 工具栏左侧 -->
<template #toolLeft>
<a-button type="primary" @click="handleAdd">
<template #icon>
<PlusOutlined />
</template>
{{ $t('common.add') }}
</a-button>
<a-button danger @click="handleBatchDelete" :disabled="!selectedRowKeys.length">
<template #icon>
<DeleteOutlined />
</template>
{{ $t('common.batchDelete') }}
</a-button>
</template>
<!-- 状态列自定义 -->
<template #status="{ text }">
<a-tag :color="text === 1 ? 'green' : 'red'">
{{ text === 1 ? $t('common.enabled') : $t('common.disabled') }}
</a-tag>
</template>
<!-- 级别列自定义 -->
<template #level="{ text }">
<a-tag color="blue">{{ getLevelText(text) }}</a-tag>
</template>
</sc-table>
<!-- 添加/编辑弹窗 -->
<AreaModal v-model:visible="modalVisible" :is-edit="isEdit" :initial-data="currentData"
@confirm="handleModalConfirm" />
</div>
</template>
<script setup>
import { ref, reactive, onMounted, computed } from 'vue'
import { message, Modal } from 'ant-design-vue'
import { PlusOutlined, DeleteOutlined } from '@ant-design/icons-vue'
import { useI18n } from 'vue-i18n'
import systemApi from '@/api/system'
import ScTable from '@/components/scTable/index.vue'
import AreaModal from './components/AreaModal.vue'
// 定义组件名称
defineOptions({
name: 'SystemArea',
})
const { t } = useI18n()
const tableRef = ref(null)
// 数据源
const dataSource = ref([])
const loading = ref(false)
// 分页
const pagination = reactive(false)
// 选中的行
const selectedRowKeys = ref([])
// 弹窗相关
const modalVisible = ref(false)
const isEdit = ref(false)
const currentData = ref({})
// 行选择配置
const rowSelection = computed(() => ({
selectedRowKeys: selectedRowKeys.value,
onChange: (selectedKeys) => {
selectedRowKeys.value = selectedKeys
},
}))
// 操作列配置
const actions = computed(() => [
{
label: t('common.edit'),
onClick: handleEdit,
},
{
label: t('common.delete'),
onClick: handleDelete,
},
])
// 添加
const handleAdd = () => {
isEdit.value = false
currentData.value = {}
modalVisible.value = true
}
// 获取级别文本
const getLevelText = (level) => {
const levelMap = {
1: t('common.province'),
2: t('common.city'),
3: t('common.district'),
4: t('common.street'),
}
return levelMap[level] || t('common.unknown')
}
// 列配置
const columns = ref([
{
title: t('common.areaName'),
dataIndex: 'title',
key: 'title',
width: 200,
},
{
title: t('common.areaCode'),
dataIndex: 'code',
key: 'code',
width: 150,
},
{
title: t('common.areaLevel'),
dataIndex: 'level',
key: 'level',
width: 100,
slot: 'level',
},
{
title: t('common.parentArea'),
dataIndex: 'parent_code',
key: 'parent_code',
width: 150,
},
{
title: t('common.status'),
dataIndex: 'status',
key: 'status',
width: 100,
slot: 'status',
},
{
title: t('common.createTime'),
dataIndex: 'created_at',
key: 'created_at',
width: 180,
},
])
// 加载数据
const loadData = async () => {
try {
loading.value = true
const params = {
is_tree: 1,
}
const res = await systemApi.area.list.get(params)
if (res.code === 1) {
dataSource.value = res.data.list || res.data || []
}
} catch (error) {
message.error(t('common.fetchDataFailed'))
console.error('获取地区列表失败:', error)
} finally {
loading.value = false
}
}
// 表格变化处理
const handleTableChange = ({ pagination: newPagination }) => {
if (newPagination.current) pagination.current = newPagination.current
if (newPagination.pageSize) pagination.pageSize = newPagination.pageSize
loadData()
}
// 编辑
const handleEdit = (record) => {
isEdit.value = true
currentData.value = { ...record }
modalVisible.value = true
}
// 删除
const handleDelete = (record) => {
Modal.confirm({
title: t('common.confirmDelete'),
content: `${t('common.deleteConfirm')}: ${record.title}?`,
okText: t('common.confirm'),
cancelText: t('common.cancel'),
onOk: async () => {
try {
// 注意API 中没有删除接口,这里模拟删除成功
// 如果后端有删除接口,请取消注释以下代码
// const res = await systemApi.area.delete.post({ id: record.id })
// if (res.code === 200 || res.code === 1) {
message.success(t('common.deleteSuccess'))
loadData()
selectedRowKeys.value = [] // 清除选择
// }
} catch (error) {
message.error(t('common.deleteFailed'))
console.error('删除地区失败:', error)
}
},
})
}
// 批量删除
const handleBatchDelete = () => {
if (selectedRowKeys.value.length === 0) {
message.warning(t('common.selectDataFirst'))
return
}
Modal.confirm({
title: t('common.confirmBatchDelete'),
content: `${t('common.batchDeleteConfirm')}: ${selectedRowKeys.value.length} ${t('common.items')}?`,
okText: t('common.confirm'),
cancelText: t('common.cancel'),
onOk: async () => {
try {
// 注意API 中没有批量删除接口,这里模拟删除成功
// 如果后端有批量删除接口,请取消注释以下代码
// const res = await systemApi.area.batchDelete.post({ ids: selectedRowKeys.value })
// if (res.code === 200 || res.code === 1) {
message.success(t('common.deleteSuccess'))
selectedRowKeys.value = []
loadData()
// }
} catch (error) {
message.error(t('common.deleteFailed'))
console.error('批量删除失败:', error)
}
},
})
}
// 弹窗确认
const handleModalConfirm = async (values) => {
try {
let res
if (isEdit.value) {
// 编辑
res = await systemApi.area.edit.post(values)
if (res.code === 200 || res.code === 1) {
message.success(t('common.editSuccess'))
modalVisible.value = false
loadData()
}
} else {
// 添加
res = await systemApi.area.add.post(values)
if (res.code === 200 || res.code === 1) {
message.success(t('common.addSuccess'))
modalVisible.value = false
loadData()
}
}
} catch (error) {
if (error.errorFields) {
return // 表单验证错误
}
message.error(isEdit.value ? t('common.editFailed') : t('common.addFailed'))
console.error(isEdit.value ? '编辑地区失败:' : '添加地区失败:', error)
}
}
// 初始化加载数据
onMounted(() => {
loadData()
})
</script>