Explorar el Código

feat(zfgl): 添加退据管理功能

- 实现了退据列表的查询、搜索、重置、批量删除等功能
- 添加了金额和日期的格式化显示
- 实现了附件下载功能
- 优化了表格和分页的样式
nahida hace 10 meses
padre
commit
8880b926f4
Se han modificado 1 ficheros con 357 adiciones y 0 borrados
  1. 357 0
      src/views/zfgl/zftjgl.vue

+ 357 - 0
src/views/zfgl/zftjgl.vue

@@ -0,0 +1,357 @@
+<script setup lang="ts">
+import { onMounted, reactive, ref } from 'vue'
+import { ElMessage, ElMessageBox } from 'element-plus'
+import { Download, RefreshCw, Search, Trash2 } from 'lucide-vue-next'
+import { clientGet, clientPost } from '@/utils/request.ts'
+
+// 退据信息接口定义
+interface ARefund {
+  id: string // 主键
+  contractId?: string // 合同id
+  unit?: string // 单位
+  tenant?: string // 租户
+  deposit?: number // 押金
+  rent?: number // 租金
+  propertyFee?: number // 物业费
+  totalAmount?: number // 合计
+  generationDate?: string // 生成日期
+  attachmentUrl?: string // 附件url
+  createTime?: string // 创建时间
+  updateTime?: string // 更新时间
+}
+
+// 退据响应数据接口
+interface ARefundResponse extends BaseResponse {
+  data: PageType<ARefund>
+}
+
+// 响应式数据
+const loading = ref(false)
+const tableData = ref<ARefund[]>([])
+const selectedRows = ref<ARefund[]>([])
+const total = ref(0)
+
+// MinIO文件服务基础地址
+const MINIO_URL = import.meta.env.VITE_MINIO_BASE_URL
+
+// 搜索表单数据
+const searchForm = reactive({
+  tenant: '',
+  unit: '',
+  pageNum: 1,
+  pageSize: 10,
+})
+
+// 获取退据列表数据
+const getList = async () => {
+  loading.value = true
+  try {
+    const res = await clientGet<
+      {
+        tenant: string
+        unit: string
+      },
+      ARefundResponse
+    >('/arefund/findByPage', {
+      params: {
+        pageNum: searchForm.pageNum,
+        pageSize: searchForm.pageSize,
+        tenant: searchForm.tenant,
+        unit: searchForm.unit,
+      },
+    })
+
+    if (res.code !== 200) {
+      ElMessage.error(res.msg)
+      return
+    }
+
+    tableData.value = res.data.records
+    total.value = res.data.total
+  } catch (error) {
+    console.error('获取退据列表失败:', error)
+    ElMessage.error('获取数据失败,请稍后重试')
+  } finally {
+    loading.value = false
+  }
+}
+
+// 搜索处理
+const handleSearch = () => {
+  searchForm.pageNum = 1
+  getList()
+}
+
+// 重置搜索条件
+const handleReset = () => {
+  searchForm.tenant = ''
+  searchForm.unit = ''
+  searchForm.pageNum = 1
+  getList()
+}
+
+// 批量删除退据
+const handleBatchDelete = async () => {
+  if (selectedRows.value.length === 0) {
+    ElMessage.warning('请选择要删除的退据记录')
+    return
+  }
+
+  try {
+    await ElMessageBox.confirm(
+      `确定要删除选中的 ${selectedRows.value.length} 条退据记录吗?`,
+      '确认删除',
+      {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning',
+      },
+    )
+
+    const ids = selectedRows.value.map((row) => row.id).filter(Boolean)
+    const res = await clientPost<string[], BaseResponse>('/arefund/deleteBatch', ids)
+
+    if (res.code !== 200) {
+      ElMessage.error(res.msg)
+      return
+    }
+
+    ElMessage.success(res.msg)
+    selectedRows.value = []
+    getList()
+  } catch (error) {
+    console.error('删除退据失败:', error)
+    // 用户取消删除时不做处理
+  }
+}
+
+// 表格选择项变化
+const handleSelectionChange = (selection: ARefund[]) => {
+  selectedRows.value = selection
+}
+
+// 分页页码变化
+const handlePageChange = (page: number) => {
+  searchForm.pageNum = page
+  getList()
+}
+
+// 每页条数变化
+const handleSizeChange = (size: number) => {
+  searchForm.pageSize = size
+  searchForm.pageNum = 1
+  getList()
+}
+
+// 格式化金额显示
+const formatAmount = (amount: number | undefined) => {
+  return amount ? `¥${amount.toLocaleString()}` : '-'
+}
+
+// 格式化日期显示
+const formatDate = (date: string | undefined) => {
+  return date ? new Date(date).toLocaleDateString() : '-'
+}
+
+// 下载附件
+const handleDownloadAttachment = async (row: ARefund) => {
+  if (!row.attachmentUrl) {
+    ElMessage.warning('该退据记录没有附件')
+    return
+  }
+
+  try {
+    // 处理完整URL和相对路径两种情况
+    const url = row.attachmentUrl.startsWith('http')
+      ? row.attachmentUrl
+      : `${MINIO_URL}${row.attachmentUrl}`
+
+    // 创建临时下载链接
+    const link = document.createElement('a')
+    link.href = url
+    link.download = `退据附件_${row.id}.${getFileExtension(url)}`
+    link.target = '_blank'
+    document.body.appendChild(link)
+    link.click()
+    document.body.removeChild(link)
+    ElMessage.success('附件下载已开始')
+  } catch (error) {
+    console.error('附件下载失败:', error)
+    ElMessage.error('附件下载失败,请稍后重试')
+  }
+}
+
+// 获取文件扩展名
+const getFileExtension = (url: string): string => {
+  const parts = url.split('.')
+  return parts.length > 1 ? parts[parts.length - 1] : 'pdf'
+}
+
+// 页面挂载时加载数据
+onMounted(() => {
+  getList()
+})
+</script>
+
+<template>
+  <div class="p-6 bg-gray-50 min-h-screen">
+    <div class="bg-white rounded-lg shadow-sm">
+      <!-- 页面标题 -->
+      <div class="px-6 py-4 border-b border-gray-200">
+        <h1 class="text-xl font-semibold text-gray-900">租房退据管理</h1>
+      </div>
+
+      <!-- 搜索表单区域 -->
+      <div class="p-6 border-b border-gray-200">
+        <el-form :model="searchForm" inline class="search-form">
+          <el-form-item label="租户名称">
+            <el-input
+              v-model="searchForm.tenant"
+              placeholder="请输入租户名称"
+              clearable
+              class="w-48"
+              @keyup.enter="handleSearch"
+            />
+          </el-form-item>
+
+          <el-form-item label="所属单位">
+            <el-input
+              v-model="searchForm.unit"
+              placeholder="请输入所属单位"
+              clearable
+              class="w-48"
+              @keyup.enter="handleSearch"
+            />
+          </el-form-item>
+
+          <el-form-item>
+            <el-button type="primary" @click="handleSearch" :loading="loading">
+              <Search class="w-4 h-4 mr-1" v-if="!loading" />
+              搜索
+            </el-button>
+            <el-button @click="handleReset">
+              <RefreshCw class="w-4 h-4 mr-1" />
+              重置
+            </el-button>
+          </el-form-item>
+        </el-form>
+      </div>
+
+      <!-- 操作按钮区域 -->
+      <div class="px-6 py-4 border-b border-gray-200">
+        <div class="flex justify-between items-center">
+          <div class="flex gap-2">
+            <el-button
+              type="danger"
+              :disabled="selectedRows.length === 0"
+              @click="handleBatchDelete"
+            >
+              <Trash2 class="w-4 h-4 mr-1" />
+              批量删除 ({{ selectedRows.length }})
+            </el-button>
+          </div>
+
+          <div class="text-sm text-gray-500">共 {{ total }} 条记录</div>
+        </div>
+      </div>
+
+      <!-- 数据表格区域 -->
+      <div class="px-6">
+        <el-table
+          :data="tableData"
+          v-loading="loading"
+          @selection-change="handleSelectionChange"
+          stripe
+          class="w-full"
+        >
+          <el-table-column type="selection" width="55" />
+
+          <!--          <el-table-column prop="id" label="退据ID" width="240" />-->
+
+          <!--          <el-table-column prop="contractId" label="合同ID" width="280" />-->
+
+          <el-table-column prop="unit" label="所属单位" />
+
+          <el-table-column prop="tenant" label="租户名称" />
+
+          <el-table-column prop="deposit" label="押金" align="right">
+            <template #default="{ row }">
+              {{ formatAmount(row.deposit) }}
+            </template>
+          </el-table-column>
+
+          <el-table-column prop="rent" label="租金" align="right">
+            <template #default="{ row }">
+              {{ formatAmount(row.rent) }}
+            </template>
+          </el-table-column>
+
+          <el-table-column prop="propertyFee" label="物业费" align="right">
+            <template #default="{ row }">
+              {{ formatAmount(row.propertyFee) }}
+            </template>
+          </el-table-column>
+
+          <el-table-column prop="totalAmount" label="合计金额" align="right">
+            <template #default="{ row }">
+              <span class="font-medium text-green-600">
+                {{ formatAmount(row.totalAmount) }}
+              </span>
+            </template>
+          </el-table-column>
+
+          <el-table-column prop="generationDate" label="生成日期">
+            <template #default="{ row }">
+              {{ formatDate(row.generationDate) }}
+            </template>
+          </el-table-column>
+
+          <el-table-column label="操作" width="120" fixed="right">
+            <template #default="{ row }">
+              <el-button
+                type="primary"
+                size="small"
+                link
+                v-if="row.attachmentUrl"
+                @click="handleDownloadAttachment(row)"
+              >
+                <Download class="w-3 h-3 mr-1" />
+                下载附件
+              </el-button>
+              <span v-else class="text-gray-400 text-xs">无附件</span>
+            </template>
+          </el-table-column>
+        </el-table>
+      </div>
+
+      <!-- 分页控件区域 -->
+      <div class="px-6 py-4 border-t border-gray-200">
+        <el-pagination
+          v-model:current-page="searchForm.pageNum"
+          v-model:page-size="searchForm.pageSize"
+          :page-sizes="[10, 20, 50, 100]"
+          :total="total"
+          layout="total, sizes, prev, pager, next, jumper"
+          @size-change="handleSizeChange"
+          @current-change="handlePageChange"
+          class="justify-end"
+        />
+      </div>
+    </div>
+  </div>
+</template>
+
+<style scoped>
+:deep(.el-table) {
+  font-size: 14px;
+  margin-bottom: 16px;
+}
+
+:deep(.el-pagination) {
+  justify-content: flex-end;
+}
+
+:deep(.search-form .el-form-item) {
+  margin-bottom: 16px;
+}
+</style>