| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779 |
- <script setup lang="ts">
- import { onMounted, reactive, ref } from 'vue'
- import { clientDownloadExcel, clientGet, clientPost } from '@/utils/request.ts'
- import type { FormInstance, UploadProps } from 'element-plus'
- import { ElLoading, ElMessage, ElMessageBox } from 'element-plus'
- import { Delete, Download, Edit, Plus, Refresh, Search, Upload } from '@element-plus/icons-vue'
- interface BaseResponse {
- code: number
- msg: string
- }
- interface PageType<T> {
- records: T[]
- total: number
- size: number
- current: number
- pages: number
- }
- interface Property {
- id: string
- enterpriseName?: string
- unifiedSocialCreditCode?: string
- waterUserInfo?: string
- openingDate?: string
- userAddress?: string
- prepaidAmount?: number
- arrearsAmount?: number
- isOneHouseholdTable?: string
- waterFeeDetails?: string
- avgWaterUsageLast3Months?: number
- avgWaterUsageLast6Months?: number
- isArrearsNow?: string
- paymentPeriod?: string
- statisticsDate?: string
- statisticsBaselineDate?: string
- remarks?: string
- administrativeRegionCode?: string
- createTime?: string
- }
- interface PropertyOneResponse extends BaseResponse {
- data: Property
- }
- interface PropertyListResponse extends BaseResponse {
- data: PageType<Property>
- }
- interface AddProperty {
- enterpriseName?: string
- unifiedSocialCreditCode?: string
- waterUserInfo?: string
- openingDate?: string
- userAddress?: string
- prepaidAmount?: number
- arrearsAmount?: number
- isOneHouseholdTable?: string
- waterFeeDetails?: string
- avgWaterUsageLast3Months?: number
- avgWaterUsageLast6Months?: number
- isArrearsNow?: string
- paymentPeriod?: string
- statisticsDate?: string
- statisticsBaselineDate?: string
- remarks?: string
- administrativeRegionCode?: string
- }
- interface UpdateProperty {
- id?: string
- enterpriseName?: string
- unifiedSocialCreditCode?: string
- waterUserInfo?: string
- openingDate?: string
- userAddress?: string
- prepaidAmount?: number
- arrearsAmount?: number
- isOneHouseholdTable?: string
- waterFeeDetails?: string
- avgWaterUsageLast3Months?: number
- avgWaterUsageLast6Months?: number
- isArrearsNow?: string
- paymentPeriod?: string
- statisticsDate?: string
- statisticsBaselineDate?: string
- remarks?: string
- administrativeRegionCode?: string
- }
- // 搜索表单
- const searchForm = reactive({
- isOneHouseholdTable: '',
- isArrearsNow: '',
- administrativeRegionCode: '',
- })
- // 分页参数
- const pagination = reactive({
- current: 1,
- size: 10,
- total: 0,
- })
- // 表格数据
- const tableData = ref<Property[]>([])
- const tableLoading = ref(false)
- const selectedIds = ref<string[]>([])
- // 对话框
- const dialogVisible = ref(false)
- const dialogTitle = ref('新增用水客户')
- const formRef = ref<FormInstance>()
- const formData = reactive<AddProperty | UpdateProperty>({
- enterpriseName: '',
- unifiedSocialCreditCode: '',
- waterUserInfo: '',
- openingDate: '',
- userAddress: '',
- prepaidAmount: undefined,
- arrearsAmount: undefined,
- isOneHouseholdTable: '',
- waterFeeDetails: '',
- avgWaterUsageLast3Months: undefined,
- avgWaterUsageLast6Months: undefined,
- isArrearsNow: '',
- paymentPeriod: '',
- statisticsDate: '',
- statisticsBaselineDate: '',
- remarks: '',
- administrativeRegionCode: '',
- })
- // 表单验证规则
- const formRules = {
- enterpriseName: [{ required: true, message: '请输入企业名称', trigger: 'blur' }],
- unifiedSocialCreditCode: [{ required: true, message: '请输入统一社会信用代码', trigger: 'blur' }],
- waterUserInfo: [{ required: true, message: '请输入用水信息', trigger: 'blur' }],
- isOneHouseholdTable: [{ required: true, message: '请选择是否一户一表', trigger: 'change' }],
- isArrearsNow: [{ required: true, message: '请选择当前是否欠费', trigger: 'change' }],
- }
- // 获取列表数据
- const getList = async () => {
- tableLoading.value = true
- try {
- const params: any = {
- pageNum: pagination.current,
- pageSize: pagination.size,
- }
- if (searchForm.isOneHouseholdTable) params.isOneHouseholdTable = searchForm.isOneHouseholdTable
- if (searchForm.isArrearsNow) params.isArrearsNow = searchForm.isArrearsNow
- if (searchForm.administrativeRegionCode)
- params.administrativeRegionCode = searchForm.administrativeRegionCode
- const res = await clientGet<any, PropertyListResponse>('/eWaterCustomer/findByPage', { params })
- if (res.code !== 200) {
- ElMessage.error(res.msg)
- return
- }
- tableData.value = res.data.records
- pagination.total = res.data.total
- } finally {
- tableLoading.value = false
- }
- }
- // 搜索
- const handleSearch = () => {
- pagination.current = 1
- getList()
- }
- // 重置搜索
- const handleReset = () => {
- searchForm.isOneHouseholdTable = ''
- searchForm.isArrearsNow = ''
- searchForm.administrativeRegionCode = ''
- handleSearch()
- }
- // 分页变化
- const handlePageChange = (page: number) => {
- pagination.current = page
- getList()
- }
- const handleSizeChange = (size: number) => {
- pagination.size = size
- pagination.current = 1
- getList()
- }
- // 表格选择
- const handleSelectionChange = (selection: Property[]) => {
- selectedIds.value = selection.map((item) => item.id)
- }
- // 打开新增对话框
- const handleAdd = () => {
- dialogTitle.value = '新增用水客户'
- dialogVisible.value = true
- resetForm()
- }
- // 打开编辑对话框
- const handleEdit = async (row: Property) => {
- dialogTitle.value = '编辑用水客户'
- const data = await getById(row.id)
- if (data) {
- Object.assign(formData, data)
- dialogVisible.value = true
- }
- }
- // 根据id获取数据
- const getById = async (id: string) => {
- const res = await clientGet<null, PropertyOneResponse>('/eWaterCustomer/getById/' + id)
- if (res.code !== 200) {
- ElMessage.error(res.msg)
- return null
- }
- return res.data
- }
- // 删除单个
- const handleDelete = (row: Property) => {
- ElMessageBox.confirm('确定要删除该用水客户吗?', '提示', {
- confirmButtonText: '确定',
- cancelButtonText: '取消',
- type: 'warning',
- }).then(async () => {
- const success = await delBatch([row.id])
- if (success) {
- getList()
- }
- })
- }
- // 批量删除
- const handleBatchDelete = () => {
- if (selectedIds.value.length === 0) {
- ElMessage.warning('请选择要删除的数据')
- return
- }
- ElMessageBox.confirm(`确定要删除选中的 ${selectedIds.value.length} 条数据吗?`, '提示', {
- confirmButtonText: '确定',
- cancelButtonText: '取消',
- type: 'warning',
- }).then(async () => {
- const success = await delBatch(selectedIds.value)
- if (success) {
- getList()
- }
- })
- }
- // 删除接口
- const delBatch = async (ids: string[]) => {
- const res = await clientPost<string[], BaseResponse>('/eWaterCustomer/deleteBatch', ids)
- if (res.code !== 200) {
- ElMessage.error(res.msg)
- return false
- }
- ElMessage.success(res.msg)
- return true
- }
- // 提交表单
- const handleSubmit = async () => {
- if (!formRef.value) return
- await formRef.value.validate(async (valid) => {
- if (valid) {
- let success = false
- if ((formData as UpdateProperty).id) {
- success = await update(formData as UpdateProperty)
- } else {
- success = await add(formData as AddProperty)
- }
- if (success) {
- dialogVisible.value = false
- getList()
- }
- }
- })
- }
- // 新增接口
- const add = async (data: AddProperty) => {
- const res = await clientPost<AddProperty, BaseResponse>('/eWaterCustomer/save', data)
- if (res.code !== 200) {
- ElMessage.error(res.msg)
- return false
- }
- ElMessage.success(res.msg)
- return true
- }
- // 修改接口
- const update = async (data: UpdateProperty) => {
- const res = await clientPost<UpdateProperty, BaseResponse>('/eWaterCustomer/update', data)
- if (res.code !== 200) {
- ElMessage.error(res.msg)
- return false
- }
- ElMessage.success(res.msg)
- return true
- }
- // 重置表单
- const resetForm = () => {
- Object.assign(formData, {
- id: undefined,
- enterpriseName: '',
- unifiedSocialCreditCode: '',
- waterUserInfo: '',
- openingDate: '',
- userAddress: '',
- prepaidAmount: undefined,
- arrearsAmount: undefined,
- isOneHouseholdTable: '',
- waterFeeDetails: '',
- avgWaterUsageLast3Months: undefined,
- avgWaterUsageLast6Months: undefined,
- isArrearsNow: '',
- paymentPeriod: '',
- statisticsDate: '',
- statisticsBaselineDate: '',
- remarks: '',
- administrativeRegionCode: '',
- })
- formRef.value?.clearValidate()
- }
- // 导出Excel
- const handleExport = async () => {
- const loading = ElLoading.service({
- lock: true,
- text: '导出中,请稍候...',
- background: 'rgba(0, 0, 0, 0.1)',
- fullscreen: true,
- })
- try {
- await clientDownloadExcel('/eWaterCustomer/exportData')
- ElMessage.success('导出成功')
- } catch (error) {
- console.error('导出失败:', error)
- ElMessage.error('导出失败')
- } finally {
- loading.close()
- }
- }
- // 导入Excel
- const handleImport: UploadProps['onChange'] = async (uploadFile) => {
- const file = uploadFile.raw
- if (!file) return
- // 验证文件类型
- const isExcel =
- file.type === 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' ||
- file.type === 'application/vnd.ms-excel'
- if (!isExcel) {
- ElMessage.error('只能上传 Excel 文件!')
- return
- }
- // 验证文件大小(10MB)
- const isLt10M = file.size / 1024 / 1024 < 10
- if (!isLt10M) {
- ElMessage.error('文件大小不能超过 10MB!')
- return
- }
- const formData = new FormData()
- formData.append('file', file)
- const loading = ElLoading.service({
- lock: true,
- text: '导入中,请稍候...',
- background: 'rgba(0, 0, 0, 0.1)',
- fullscreen: true,
- })
- try {
- const res = await clientPost<FormData, BaseResponse>('/eWaterCustomer/importData', formData, {
- headers: {
- 'Content-Type': 'multipart/form-data',
- },
- })
- if (res.code !== 200) {
- ElMessage.error(res.msg)
- return
- }
- ElMessage.success(res.msg)
- getList()
- } catch (error) {
- console.error('导入失败:', error)
- ElMessage.error('导入失败')
- } finally {
- loading.close()
- }
- }
- onMounted(() => {
- getList()
- })
- </script>
- <template>
- <div class="p-4">
- <!-- 搜索表单 -->
- <el-card class="mb-4">
- <el-form :model="searchForm" inline>
- <el-form-item>
- <template #label>
- <span class="font-size-4.5">是否一户一表:</span>
- </template>
- <el-select
- size="default"
- v-model="searchForm.isOneHouseholdTable"
- placeholder="请选择"
- clearable
- class="w-180px"
- >
- <el-option label="是" value="是" />
- <el-option label="否" value="否" />
- </el-select>
- </el-form-item>
- <el-form-item>
- <template #label>
- <span class="font-size-4.5">当前是否欠费:</span>
- </template>
- <el-select
- size="default"
- v-model="searchForm.isArrearsNow"
- placeholder="请选择"
- clearable
- class="w-180px"
- >
- <el-option label="是" value="是" />
- <el-option label="否" value="否" />
- </el-select>
- </el-form-item>
- <el-form-item>
- <template #label>
- <span class="font-size-4.5">行政区域代码:</span>
- </template>
- <el-input
- size="default"
- v-model="searchForm.administrativeRegionCode"
- placeholder="请输入行政区域代码"
- clearable
- class="w-180px"
- />
- </el-form-item>
- <el-form-item>
- <el-button size="default" type="primary" :icon="Search" @click="handleSearch"
- >搜索</el-button
- >
- <el-button size="default" :icon="Refresh" @click="handleReset">重置</el-button>
- </el-form-item>
- </el-form>
- </el-card>
- <!-- 操作按钮 -->
- <el-card class="mb-4">
- <div class="flex justify-between items-center">
- <div class="flex gap-2">
- <el-button size="default" type="primary" :icon="Plus" @click="handleAdd">新增</el-button>
- <el-button
- size="default"
- type="danger"
- :icon="Delete"
- @click="handleBatchDelete"
- :disabled="selectedIds.length === 0"
- >批量删除</el-button
- >
- <el-button size="default" type="success" :icon="Download" @click="handleExport"
- >导出</el-button
- >
- <el-upload
- :show-file-list="false"
- :on-change="handleImport"
- :auto-upload="false"
- accept=".xlsx,.xls"
- class="inline-block ml-2"
- >
- <el-button size="default" type="warning" :icon="Upload">导入</el-button>
- </el-upload>
- </div>
- </div>
- </el-card>
- <!-- 数据表格 -->
- <el-card>
- <el-table
- :data="tableData"
- :loading="tableLoading"
- border
- stripe
- @selection-change="handleSelectionChange"
- >
- <el-table-column type="selection" width="55" align="center" />
- <el-table-column
- prop="enterpriseName"
- label="企业名称"
- min-width="150"
- show-overflow-tooltip
- />
- <el-table-column
- prop="unifiedSocialCreditCode"
- label="统一社会信用代码"
- min-width="180"
- show-overflow-tooltip
- />
- <el-table-column
- prop="waterUserInfo"
- label="用水信息"
- min-width="150"
- show-overflow-tooltip
- />
- <el-table-column prop="openingDate" label="开户日期" width="120" />
- <el-table-column
- prop="userAddress"
- label="用户地址"
- min-width="200"
- show-overflow-tooltip
- />
- <el-table-column prop="prepaidAmount" label="预交金额" width="120" align="right">
- <template #default="{ row }">
- {{ row.prepaidAmount ? `¥${row.prepaidAmount.toFixed(2)}` : '-' }}
- </template>
- </el-table-column>
- <el-table-column prop="arrearsAmount" label="欠费金额" width="120" align="right">
- <template #default="{ row }">
- {{ row.arrearsAmount ? `¥${row.arrearsAmount.toFixed(2)}` : '-' }}
- </template>
- </el-table-column>
- <el-table-column prop="isOneHouseholdTable" label="是否一户一表" width="120" align="center">
- <template #default="{ row }">
- <el-tag :type="row.isOneHouseholdTable === '是' ? 'success' : 'info'">
- {{ row.isOneHouseholdTable || '-' }}
- </el-tag>
- </template>
- </el-table-column>
- <el-table-column
- prop="avgWaterUsageLast3Months"
- label="近3月月均用水量"
- width="150"
- align="right"
- >
- <template #default="{ row }">
- {{ row.avgWaterUsageLast3Months ? `${row.avgWaterUsageLast3Months} m³` : '-' }}
- </template>
- </el-table-column>
- <el-table-column
- prop="avgWaterUsageLast6Months"
- label="近6月月均用水量"
- width="150"
- align="right"
- >
- <template #default="{ row }">
- {{ row.avgWaterUsageLast6Months ? `${row.avgWaterUsageLast6Months} m³` : '-' }}
- </template>
- </el-table-column>
- <el-table-column prop="isArrearsNow" label="当前是否欠费" width="120" align="center">
- <template #default="{ row }">
- <el-tag :type="row.isArrearsNow === '是' ? 'danger' : 'success'">
- {{ row.isArrearsNow || '-' }}
- </el-tag>
- </template>
- </el-table-column>
- <el-table-column prop="paymentPeriod" label="缴费所属期" width="120" />
- <el-table-column prop="statisticsDate" label="统计日期" width="120" />
- <el-table-column prop="administrativeRegionCode" label="行政区域代码" width="130" />
- <el-table-column prop="remarks" label="备注" min-width="150" show-overflow-tooltip />
- <el-table-column label="操作" width="150" fixed="right" align="center">
- <template #default="{ row }">
- <el-button link type="primary" :icon="Edit" @click="handleEdit(row)">编辑</el-button>
- <el-button link type="danger" :icon="Delete" @click="handleDelete(row)">删除</el-button>
- </template>
- </el-table-column>
- </el-table>
- <!-- 分页 -->
- <div class="flex justify-end mt-4">
- <el-pagination
- v-model:current-page="pagination.current"
- v-model:page-size="pagination.size"
- :page-sizes="[10, 20, 50, 100]"
- :total="pagination.total"
- layout="total, sizes, prev, pager, next, jumper"
- @size-change="handleSizeChange"
- @current-change="handlePageChange"
- />
- </div>
- </el-card>
- <!-- 新增/编辑对话框 -->
- <el-dialog
- v-model="dialogVisible"
- :title="dialogTitle"
- width="800px"
- :close-on-click-modal="false"
- >
- <el-form ref="formRef" :model="formData" :rules="formRules" label-width="140px">
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="企业名称" prop="enterpriseName">
- <el-input v-model="formData.enterpriseName" placeholder="请输入企业名称" />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="统一社会信用代码" prop="unifiedSocialCreditCode">
- <el-input
- v-model="formData.unifiedSocialCreditCode"
- placeholder="请输入统一社会信用代码"
- />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="用水信息" prop="waterUserInfo">
- <el-input v-model="formData.waterUserInfo" placeholder="请输入用水信息(户名户号)" />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="开户日期" prop="openingDate">
- <el-date-picker
- v-model="formData.openingDate"
- type="date"
- placeholder="请选择开户日期"
- value-format="YYYY-MM-DD"
- class="w-full"
- />
- </el-form-item>
- </el-col>
- <el-col :span="24">
- <el-form-item label="用户地址" prop="userAddress">
- <el-input v-model="formData.userAddress" placeholder="请输入用户地址" />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="预交金额" prop="prepaidAmount">
- <el-input-number
- v-model="formData.prepaidAmount"
- :precision="2"
- :min="0"
- class="w-full"
- />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="欠费金额" prop="arrearsAmount">
- <el-input-number
- v-model="formData.arrearsAmount"
- :precision="2"
- :min="0"
- class="w-full"
- />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="是否一户一表" prop="isOneHouseholdTable">
- <el-select v-model="formData.isOneHouseholdTable" placeholder="请选择" class="w-full">
- <el-option label="是" value="是" />
- <el-option label="否" value="否" />
- </el-select>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="当前是否欠费" prop="isArrearsNow">
- <el-select v-model="formData.isArrearsNow" placeholder="请选择" class="w-full">
- <el-option label="是" value="是" />
- <el-option label="否" value="否" />
- </el-select>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="近3月月均用水量" prop="avgWaterUsageLast3Months">
- <el-input-number
- v-model="formData.avgWaterUsageLast3Months"
- :precision="2"
- :min="0"
- class="w-full"
- />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="近6月月均用水量" prop="avgWaterUsageLast6Months">
- <el-input-number
- v-model="formData.avgWaterUsageLast6Months"
- :precision="2"
- :min="0"
- class="w-full"
- />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="缴费所属期" prop="paymentPeriod">
- <el-input v-model="formData.paymentPeriod" placeholder="请输入缴费所属期" />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="统计日期" prop="statisticsDate">
- <el-date-picker
- v-model="formData.statisticsDate"
- type="date"
- placeholder="请选择统计日期"
- value-format="YYYY-MM-DD"
- class="w-full"
- />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="统计基准日期" prop="statisticsBaselineDate">
- <el-date-picker
- v-model="formData.statisticsBaselineDate"
- type="date"
- placeholder="请选择统计基准日期"
- value-format="YYYY-MM-DD"
- class="w-full"
- />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="行政区域代码" prop="administrativeRegionCode">
- <el-input
- v-model="formData.administrativeRegionCode"
- placeholder="请输入行政区域代码"
- />
- </el-form-item>
- </el-col>
- <el-col :span="24">
- <el-form-item label="缴纳水费明细" prop="waterFeeDetails">
- <el-input
- v-model="formData.waterFeeDetails"
- type="textarea"
- :rows="3"
- placeholder="请输入缴纳水费明细"
- />
- </el-form-item>
- </el-col>
- <el-col :span="24">
- <el-form-item label="备注" prop="remarks">
- <el-input
- v-model="formData.remarks"
- type="textarea"
- :rows="3"
- placeholder="请输入备注"
- />
- </el-form-item>
- </el-col>
- </el-row>
- </el-form>
- <template #footer>
- <el-button @click="dialogVisible = false">取消</el-button>
- <el-button type="primary" @click="handleSubmit">确定</el-button>
- </template>
- </el-dialog>
- </div>
- </template>
- <style scoped>
- .w-180px {
- width: 180px;
- }
- </style>
|