Commit 8db442670a565b54143b23f22864f8725513a2ef

Authored by wuxw
1 parent bc37d685

开始开发报表功能

src/api/report/reportProficientApi.js 0 → 100644
  1 +import request from '@/utils/request'
  2 +import { getCommunityId } from '@/api/community/communityApi'
  3 +
  4 +/**
  5 + * 查询费用台账数据
  6 + * @param {Object} params 查询参数
  7 + * @returns {Promise}
  8 + */
  9 +export function queryReportFeeYear(params) {
  10 + return new Promise((resolve, reject) => {
  11 + const communityId = getCommunityId()
  12 + request({
  13 + url: '/reportFeeYearCollection/queryReportFeeYear',
  14 + method: 'get',
  15 + params: {
  16 + ...params,
  17 + communityId
  18 + }
  19 + }).then(response => {
  20 + const res = response.data
  21 + resolve(res)
  22 + }).catch(error => {
  23 + reject(error)
  24 + })
  25 + })
  26 +}
  27 +
  28 +/**
  29 + * 查询费用详情
  30 + * @param {Object} params 查询参数
  31 + * @returns {Promise}
  32 + */
  33 +export function queryFeeDetail(params) {
  34 + return new Promise((resolve, reject) => {
  35 + const communityId = getCommunityId()
  36 + request({
  37 + url: '/fee.queryFeeDetail',
  38 + method: 'get',
  39 + params: {
  40 + ...params,
  41 + communityId
  42 + }
  43 + }).then(response => {
  44 + const res = response.data
  45 + resolve(res)
  46 + }).catch(error => {
  47 + reject(error)
  48 + })
  49 + })
  50 +}
  51 +
  52 +/**
  53 + * 获取收费项列表
  54 + * @param {Object} params 查询参数
  55 + * @returns {Promise}
  56 + */
  57 +export function getFeeConfigList(params) {
  58 + return new Promise((resolve, reject) => {
  59 + const communityId = getCommunityId()
  60 + request({
  61 + url: '/feeConfig.listFeeConfigs',
  62 + method: 'get',
  63 + params: {
  64 + ...params,
  65 + communityId
  66 + }
  67 + }).then(response => {
  68 + const res = response.data
  69 + resolve(res)
  70 + }).catch(error => {
  71 + reject(error)
  72 + })
  73 + })
  74 +}
  75 +
  76 +/**
  77 + * 导出报表数据
  78 + * @param {Object} params 导出参数
  79 + * @returns {Promise}
  80 + */
  81 +export function exportReportFee(params) {
  82 + return new Promise((resolve, reject) => {
  83 + const communityId = getCommunityId()
  84 + request({
  85 + url: '/export.exportData',
  86 + method: 'get',
  87 + params: {
  88 + ...params,
  89 + communityId
  90 + }
  91 + }).then(response => {
  92 + const res = response.data
  93 + resolve(res)
  94 + }).catch(error => {
  95 + reject(error)
  96 + })
  97 + })
  98 +}
0 \ No newline at end of file 99 \ No newline at end of file
src/components/report/reportProficientCarFee.vue 0 → 100644
  1 +<template>
  2 + <div class="report-proficient-car-fee">
  3 + <el-row :gutter="20">
  4 + <el-col :span="12">
  5 + <el-table :data="reportProficientCarFeeInfo.fees" border style="width: 100%" height="500">
  6 + <el-table-column prop="ownerName" :label="$t('reportProficientCarFee.name')" align="center">
  7 + </el-table-column>
  8 + <el-table-column prop="objName" :label="$t('reportProficientCarFee.carNumber')" align="center">
  9 + </el-table-column>
  10 + <el-table-column prop="ownerLink" :label="$t('reportProficientCarFee.phone')" align="center">
  11 + </el-table-column>
  12 + <el-table-column prop="feeTypeCdName" :label="$t('reportProficientCarFee.feeType')" align="center">
  13 + </el-table-column>
  14 + <el-table-column prop="feeName" :label="$t('reportProficientCarFee.feeName')" align="center">
  15 + </el-table-column>
  16 + </el-table>
  17 + </el-col>
  18 + <el-col :span="12">
  19 + <div class="table-wrapper">
  20 + <el-table :data="reportProficientCarFeeInfo.fees" border style="width: 100%" height="500">
  21 + <el-table-column v-for="(item, index) in reportProficientCarFeeInfo.listColumns" :key="index"
  22 + :label="item + $t('reportProficientCarFee.year')" align="center" width="120">
  23 + <template slot-scope="scope">
  24 + <el-link type="primary" @click="_showCarFeeDetail(scope.row, item)">
  25 + {{ _getProficientCarFeeValue(scope.row.reportFeeYearCollectionDetailDtos, item) }}
  26 + </el-link>
  27 + </template>
  28 + </el-table-column>
  29 + </el-table>
  30 + </div>
  31 + </el-col>
  32 + </el-row>
  33 +
  34 + <el-row :gutter="20" class="margin-top">
  35 + <el-col :span="12">
  36 + <div class="tip-text">
  37 + {{ $t('reportProficientCarFee.tip') }}
  38 + </div>
  39 + </el-col>
  40 + <el-col :span="12">
  41 + <el-pagination :current-page.sync="pagination.current" :page-sizes="[10, 20, 30, 50]" :page-size="pagination.size"
  42 + :total="pagination.total" layout="total, sizes, prev, pager, next, jumper" @size-change="handleSizeChange"
  43 + @current-change="handleCurrentChange">
  44 + </el-pagination>
  45 + </el-col>
  46 + </el-row>
  47 + </div>
  48 +</template>
  49 +
  50 +<script>
  51 +import { queryReportFeeYear } from '@/api/report/reportProficientApi'
  52 +
  53 +export default {
  54 + name: 'ReportProficientCarFee',
  55 + props: {
  56 + conditions: {
  57 + type: Object,
  58 + default: () => ({})
  59 + }
  60 + },
  61 + data() {
  62 + return {
  63 + reportProficientCarFeeInfo: {
  64 + fees: [],
  65 + listColumns: [2023]
  66 + },
  67 + pagination: {
  68 + current: 1,
  69 + size: 10,
  70 + total: 0
  71 + }
  72 + }
  73 + },
  74 + created() {
  75 + this.$bus.$on('reportProficientCarFee-switch', this.handleSwitch)
  76 + this.$bus.$on('reportProficientCarFee-notify', this.listReportProficientCarFee)
  77 + },
  78 + beforeDestroy() {
  79 + this.$bus.$off('reportProficientCarFee-switch', this.handleSwitch)
  80 + this.$bus.$off('reportProficientCarFee-notify', this.listReportProficientCarFee)
  81 + },
  82 + methods: {
  83 + handleSwitch(params) {
  84 + console.log(params)
  85 + this.clearReportProficientCarFeeInfo()
  86 + this.listReportProficientCarFee()
  87 + },
  88 + async listReportProficientCarFee() {
  89 + try {
  90 + const params = {
  91 + ...this.conditions,
  92 + page: this.pagination.current,
  93 + row: this.pagination.size,
  94 + objType: '6666'
  95 + }
  96 + const { data, records } = await queryReportFeeYear(params)
  97 +
  98 + this.reportProficientCarFeeInfo.fees = data
  99 + this.pagination.total = records
  100 +
  101 + if (data && data.length > 0) {
  102 + this.reportProficientCarFeeInfo.listColumns = []
  103 + let maxColumns = data[0].reportFeeYearCollectionDetailDtos
  104 +
  105 + data.forEach(item => {
  106 + if (item.reportFeeYearCollectionDetailDtos.length > maxColumns.length) {
  107 + maxColumns = item.reportFeeYearCollectionDetailDtos
  108 + }
  109 + })
  110 +
  111 + maxColumns.forEach(item => {
  112 + this.reportProficientCarFeeInfo.listColumns.push(item.collectionYear)
  113 + })
  114 + }
  115 + } catch (error) {
  116 + console.error('获取车辆费台账失败:', error)
  117 + }
  118 + },
  119 + _getProficientCarFeeValue(reportFeeYearCollectionDetailDtos, year) {
  120 + const item = reportFeeYearCollectionDetailDtos.find(d => d.collectionYear === year)
  121 + return item ? item.receivedAmount : '0.00'
  122 + },
  123 + clearReportProficientCarFeeInfo() {
  124 + this.reportProficientCarFeeInfo = {
  125 + fees: [],
  126 + listColumns: [2023]
  127 + }
  128 + },
  129 + _showCarFeeDetail(fee, year) {
  130 + this.$refs.viewFeeDetail.open({
  131 + roomName: fee.objName,
  132 + feeId: fee.feeId,
  133 + configId: fee.configId,
  134 + payerObjId: fee.objId,
  135 + curYear: year
  136 + })
  137 + },
  138 + handleSizeChange(val) {
  139 + this.pagination.size = val
  140 + this.listReportProficientCarFee()
  141 + },
  142 + handleCurrentChange(val) {
  143 + this.pagination.current = val
  144 + this.listReportProficientCarFee()
  145 + }
  146 + }
  147 +}
  148 +</script>
  149 +
  150 +<style lang="scss" scoped>
  151 +.report-proficient-car-fee {
  152 + .table-wrapper {
  153 + overflow-x: auto;
  154 + }
  155 +
  156 + .margin-top {
  157 + margin-top: 20px;
  158 + }
  159 +
  160 + .tip-text {
  161 + padding: 10px;
  162 + color: #999;
  163 + font-size: 12px;
  164 + }
  165 +}
  166 +</style>
0 \ No newline at end of file 167 \ No newline at end of file
src/components/report/reportProficientRoomFee.vue 0 → 100644
  1 +<template>
  2 + <div class="report-proficient-room-fee">
  3 + <el-row :gutter="20">
  4 + <el-col :span="12">
  5 + <el-table :data="reportProficientRoomFeeInfo.fees" border style="width: 100%" height="500">
  6 + <el-table-column prop="ownerName" :label="$t('reportProficientRoomFee.name')" align="center">
  7 + </el-table-column>
  8 + <el-table-column prop="objName" :label="$t('reportProficientRoomFee.roomNumber')" align="center">
  9 + </el-table-column>
  10 + <el-table-column prop="ownerLink" :label="$t('reportProficientRoomFee.phone')" align="center">
  11 + </el-table-column>
  12 + <el-table-column prop="builtUpArea" :label="$t('reportProficientRoomFee.area')" align="center">
  13 + </el-table-column>
  14 + <el-table-column prop="feeTypeCdName" :label="$t('reportProficientRoomFee.feeType')" align="center">
  15 + </el-table-column>
  16 + <el-table-column prop="feeName" :label="$t('reportProficientRoomFee.feeName')" align="center">
  17 + </el-table-column>
  18 + </el-table>
  19 + </el-col>
  20 + <el-col :span="12">
  21 + <div class="table-wrapper">
  22 + <el-table :data="reportProficientRoomFeeInfo.fees" border style="width: 100%" height="500">
  23 + <el-table-column v-for="(item, index) in reportProficientRoomFeeInfo.listColumns" :key="index"
  24 + :label="item + $t('reportProficientRoomFee.year')" align="center" width="120">
  25 + <template slot-scope="scope">
  26 + <el-link type="primary" @click="_showFeeDetail(scope.row, item)">
  27 + {{ _getProficientRoomFeeValue(scope.row.reportFeeYearCollectionDetailDtos, item) }}
  28 + </el-link>
  29 + </template>
  30 + </el-table-column>
  31 + </el-table>
  32 + </div>
  33 + </el-col>
  34 + </el-row>
  35 +
  36 + <el-row :gutter="20" class="margin-top">
  37 + <el-col :span="12">
  38 + <div class="tip-text">
  39 + {{ $t('reportProficientRoomFee.tip') }}
  40 + </div>
  41 + </el-col>
  42 + <el-col :span="12">
  43 + <el-pagination :current-page.sync="pagination.current" :page-sizes="[10, 20, 30, 50]" :page-size="pagination.size"
  44 + :total="pagination.total" layout="total, sizes, prev, pager, next, jumper" @size-change="handleSizeChange"
  45 + @current-change="handleCurrentChange">
  46 + </el-pagination>
  47 + </el-col>
  48 + </el-row>
  49 + </div>
  50 +</template>
  51 +
  52 +<script>
  53 +import { queryReportFeeYear } from '@/api/report/reportProficientApi'
  54 +
  55 +export default {
  56 + name: 'ReportProficientRoomFee',
  57 + props: {
  58 + conditions: {
  59 + type: Object,
  60 + default: () => ({})
  61 + }
  62 + },
  63 + data() {
  64 + return {
  65 + reportProficientRoomFeeInfo: {
  66 + fees: [],
  67 + listColumns: [2023]
  68 + },
  69 + pagination: {
  70 + current: 1,
  71 + size: 10,
  72 + total: 0
  73 + }
  74 + }
  75 + },
  76 + created() {
  77 + this.$bus.$on('reportProficientRoomFee-switch', this.handleSwitch)
  78 + this.$bus.$on('reportProficientRoomFee-notify', this.listReportProficientRoomFee)
  79 + },
  80 + beforeDestroy() {
  81 + this.$bus.$off('reportProficientRoomFee-switch', this.handleSwitch)
  82 + this.$bus.$off('reportProficientRoomFee-notify', this.listReportProficientRoomFee)
  83 + },
  84 + methods: {
  85 + handleSwitch(params) {
  86 + console.log(params)
  87 + this.clearReportProficientRoomFeeInfo()
  88 + this.listReportProficientRoomFee()
  89 + },
  90 + async listReportProficientRoomFee() {
  91 + try {
  92 + const params = {
  93 + ...this.conditions,
  94 + page: this.pagination.current,
  95 + row: this.pagination.size,
  96 + objType: '3333'
  97 + }
  98 + const { data, records } = await queryReportFeeYear(params)
  99 +
  100 + this.reportProficientRoomFeeInfo.fees = data
  101 + this.pagination.total = records
  102 +
  103 + if (data && data.length > 0) {
  104 + this.reportProficientRoomFeeInfo.listColumns = []
  105 + let maxColumns = data[0].reportFeeYearCollectionDetailDtos
  106 +
  107 + data.forEach(item => {
  108 + if (item.reportFeeYearCollectionDetailDtos.length > maxColumns.length) {
  109 + maxColumns = item.reportFeeYearCollectionDetailDtos
  110 + }
  111 + })
  112 +
  113 + maxColumns.forEach(item => {
  114 + this.reportProficientRoomFeeInfo.listColumns.push(item.collectionYear)
  115 + })
  116 + }
  117 + } catch (error) {
  118 + console.error('获取房屋费台账失败:', error)
  119 + }
  120 + },
  121 + _getProficientRoomFeeValue(reportFeeYearCollectionDetailDtos, year) {
  122 + const item = reportFeeYearCollectionDetailDtos.find(d => d.collectionYear === year)
  123 + return item ? item.receivedAmount : '0.00'
  124 + },
  125 + clearReportProficientRoomFeeInfo() {
  126 + this.reportProficientRoomFeeInfo = {
  127 + fees: [],
  128 + listColumns: [2023]
  129 + }
  130 + },
  131 + _showFeeDetail(fee, year) {
  132 + this.$refs.viewFeeDetail.open({
  133 + roomName: fee.objName,
  134 + feeId: fee.feeId,
  135 + configId: fee.configId,
  136 + payerObjId: fee.objId,
  137 + curYear: year
  138 + })
  139 + },
  140 + handleSizeChange(val) {
  141 + this.pagination.size = val
  142 + this.listReportProficientRoomFee()
  143 + },
  144 + handleCurrentChange(val) {
  145 + this.pagination.current = val
  146 + this.listReportProficientRoomFee()
  147 + }
  148 + }
  149 +}
  150 +</script>
  151 +
  152 +<style lang="scss" scoped>
  153 +.report-proficient-room-fee {
  154 + .table-wrapper {
  155 + overflow-x: auto;
  156 + }
  157 +
  158 + .margin-top {
  159 + margin-top: 20px;
  160 + }
  161 +
  162 + .tip-text {
  163 + padding: 10px;
  164 + color: #999;
  165 + font-size: 12px;
  166 + }
  167 +}
  168 +</style>
0 \ No newline at end of file 169 \ No newline at end of file
src/components/report/viewFeeDetail.vue 0 → 100644
  1 +<template>
  2 + <el-dialog :title="`${viewFeeDetailInfo.curYear}${$t('viewFeeDetail.yearFeeHistory')}(${viewFeeDetailInfo.roomName})`"
  3 + :visible.sync="dialogVisible" width="80%" top="5vh">
  4 + <el-table :data="viewFeeDetailInfo.feeDetails" border style="width: 100%" height="500">
  5 + <el-table-column prop="cycles" :label="$t('viewFeeDetail.cycle')" align="center">
  6 + </el-table-column>
  7 + <el-table-column prop="receivableAmount" :label="$t('viewFeeDetail.receivableAmount')" align="center">
  8 + </el-table-column>
  9 + <el-table-column prop="receivedAmount" :label="$t('viewFeeDetail.receivedAmount')" align="center">
  10 + </el-table-column>
  11 + <el-table-column prop="createTime" :label="$t('viewFeeDetail.paymentTime')" align="center">
  12 + </el-table-column>
  13 + <el-table-column prop="startTime" :label="$t('viewFeeDetail.startTime')" align="center">
  14 + <template slot-scope="scope">
  15 + {{ $moment(scope.row.startTime).format('YYYY-MM-DD') }}
  16 + </template>
  17 + </el-table-column>
  18 + <el-table-column prop="endTime" :label="$t('viewFeeDetail.endTime')" align="center">
  19 + <template slot-scope="scope">
  20 + {{ $moment(scope.row.endTime).format('YYYY-MM-DD') }}
  21 + </template>
  22 + </el-table-column>
  23 + <el-table-column prop="stateName" :label="$t('viewFeeDetail.status')" align="center">
  24 + </el-table-column>
  25 + <el-table-column prop="remark" :label="$t('viewFeeDetail.remark')" align="center">
  26 + </el-table-column>
  27 + </el-table>
  28 +
  29 + <el-pagination :current-page.sync="pagination.current" :page-sizes="[10, 20, 30, 50]" :page-size="pagination.size"
  30 + :total="pagination.total" layout="total, sizes, prev, pager, next, jumper" @size-change="handleSizeChange"
  31 + @current-change="handleCurrentChange">
  32 + </el-pagination>
  33 + </el-dialog>
  34 +</template>
  35 +
  36 +<script>
  37 +import { queryFeeDetail } from '@/api/report/reportProficientApi'
  38 +
  39 +export default {
  40 + name: 'ViewFeeDetail',
  41 + data() {
  42 + return {
  43 + dialogVisible: false,
  44 + viewFeeDetailInfo: {
  45 + feeDetails: [],
  46 + curYear: '',
  47 + roomName: '',
  48 + feeId: '',
  49 + configId: '',
  50 + payerObjId: ''
  51 + },
  52 + pagination: {
  53 + current: 1,
  54 + size: 10,
  55 + total: 0
  56 + }
  57 + }
  58 + },
  59 + methods: {
  60 + open(params) {
  61 + this.viewFeeDetailInfo = {
  62 + ...this.viewFeeDetailInfo,
  63 + ...params
  64 + }
  65 + this.dialogVisible = true
  66 + this.listFeeDetail()
  67 + },
  68 + async listFeeDetail() {
  69 + try {
  70 + const params = {
  71 + page: this.pagination.current,
  72 + row: this.pagination.size,
  73 + curYear: this.viewFeeDetailInfo.curYear,
  74 + configId: this.viewFeeDetailInfo.configId,
  75 + payerObjId: this.viewFeeDetailInfo.payerObjId
  76 + }
  77 + const { data, records } = await queryFeeDetail(params)
  78 +
  79 + this.viewFeeDetailInfo.feeDetails = data
  80 + this.pagination.total = records
  81 + } catch (error) {
  82 + console.error('获取费用详情失败:', error)
  83 + }
  84 + },
  85 + handleSizeChange(val) {
  86 + this.pagination.size = val
  87 + this.listFeeDetail()
  88 + },
  89 + handleCurrentChange(val) {
  90 + this.pagination.current = val
  91 + this.listFeeDetail()
  92 + }
  93 + }
  94 +}
  95 +</script>
  96 +
  97 +<style lang="scss" scoped>
  98 +::v-deep .el-dialog__body {
  99 + padding: 20px;
  100 +}
  101 +</style>
0 \ No newline at end of file 102 \ No newline at end of file
src/i18n/index.js
@@ -208,6 +208,7 @@ import {messages as inspectioni18n} from &#39;./inspectionI18n&#39; @@ -208,6 +208,7 @@ import {messages as inspectioni18n} from &#39;./inspectionI18n&#39;
208 import {messages as machineI18n} from './machineI18n' 208 import {messages as machineI18n} from './machineI18n'
209 import {messages as oaI18n} from './oaI18n' 209 import {messages as oaI18n} from './oaI18n'
210 import {messages as contractI18n} from './contractI18n' 210 import {messages as contractI18n} from './contractI18n'
  211 +import {messages as reportI18n} from './reportI18n'
211 212
212 Vue.use(VueI18n) 213 Vue.use(VueI18n)
213 214
@@ -420,6 +421,7 @@ const messages = { @@ -420,6 +421,7 @@ const messages = {
420 ...machineI18n.en, 421 ...machineI18n.en,
421 ...oaI18n.en, 422 ...oaI18n.en,
422 ...contractI18n.en, 423 ...contractI18n.en,
  424 + ...reportI18n.en,
423 }, 425 },
424 zh: { 426 zh: {
425 ...loginMessages.zh, 427 ...loginMessages.zh,
@@ -628,6 +630,7 @@ const messages = { @@ -628,6 +630,7 @@ const messages = {
628 ...machineI18n.zh, 630 ...machineI18n.zh,
629 ...oaI18n.zh, 631 ...oaI18n.zh,
630 ...contractI18n.zh, 632 ...contractI18n.zh,
  633 + ...reportI18n.zh,
631 } 634 }
632 } 635 }
633 636
src/i18n/reportI18n.js 0 → 100644
  1 +import { messages as reportProficientMessages } from '../views/report/reportProficientLang'
  2 +export const messages ={
  3 + en:{
  4 + ...reportProficientMessages.en,
  5 + },
  6 + zh:{
  7 + ...reportProficientMessages.zh,
  8 + }
  9 +}
0 \ No newline at end of file 10 \ No newline at end of file
src/router/index.js
@@ -7,6 +7,7 @@ import inspectionRouter from &#39;./inspectionRouter&#39; @@ -7,6 +7,7 @@ import inspectionRouter from &#39;./inspectionRouter&#39;
7 import machineRouter from './machineRouter' 7 import machineRouter from './machineRouter'
8 import oaRouter from './oaRouter' 8 import oaRouter from './oaRouter'
9 import contractRouter from './contractRouter' 9 import contractRouter from './contractRouter'
  10 +import reportRouter from './reportRouter'
10 11
11 Vue.use(VueRouter) 12 Vue.use(VueRouter)
12 13
@@ -930,6 +931,7 @@ const routes = [ @@ -930,6 +931,7 @@ const routes = [
930 ...machineRouter, 931 ...machineRouter,
931 ...oaRouter, 932 ...oaRouter,
932 ...contractRouter, 933 ...contractRouter,
  934 + ...reportRouter,
933 // 其他子路由可以在这里添加 935 // 其他子路由可以在这里添加
934 ] 936 ]
935 }, 937 },
src/router/reportRouter.js 0 → 100644
  1 +export default [
  2 + {
  3 + path: '/pages/property/reportProficient',
  4 + name: '/pages/property/reportProficient',
  5 + component: () => import('@/views/report/reportProficientList.vue')
  6 + },
  7 +
  8 +]
0 \ No newline at end of file 9 \ No newline at end of file
src/views/report/reportProficientLang.js 0 → 100644
  1 +export const messages = {
  2 + en: {
  3 + reportProficient: {
  4 + search: {
  5 + title: 'Search Conditions',
  6 + roomPlaceholder: 'Please enter room number',
  7 + carPlaceholder: 'Please enter license plate number'
  8 + },
  9 + export: 'Export',
  10 + reset: 'Reset',
  11 + roomFee: 'Room Fee Ledger',
  12 + carFee: 'Car Fee Ledger'
  13 + },
  14 + reportProficientRoomFee: {
  15 + name: 'Name',
  16 + roomNumber: 'Room Number',
  17 + phone: 'Phone',
  18 + area: 'Area',
  19 + feeType: 'Fee Type',
  20 + feeName: 'Fee Name',
  21 + year: ' Year',
  22 + tip: 'Make sure the scheduled task is enabled when there is no data'
  23 + },
  24 + reportProficientCarFee: {
  25 + name: 'Name',
  26 + carNumber: 'License Plate',
  27 + phone: 'Phone',
  28 + feeType: 'Fee Type',
  29 + feeName: 'Fee Name',
  30 + year: ' Year',
  31 + tip: ' '
  32 + },
  33 + viewFeeDetail: {
  34 + yearFeeHistory: ' Year Payment History',
  35 + cycle: 'Cycle(Month)',
  36 + receivableAmount: 'Receivable Amount(Yuan)',
  37 + receivedAmount: 'Received Amount(Yuan)',
  38 + paymentTime: 'Payment Time',
  39 + startTime: 'Start Time',
  40 + endTime: 'End Time',
  41 + status: 'Status',
  42 + remark: 'Remark'
  43 + }
  44 + },
  45 + zh: {
  46 + reportProficient: {
  47 + search: {
  48 + title: '查询条件',
  49 + roomPlaceholder: '请填写房屋编号',
  50 + carPlaceholder: '请填写车牌号'
  51 + },
  52 + export: '导出',
  53 + reset: '重置',
  54 + roomFee: '房屋费台账',
  55 + carFee: '车辆费台账'
  56 + },
  57 + reportProficientRoomFee: {
  58 + name: '姓名',
  59 + roomNumber: '房号',
  60 + phone: '联系电话',
  61 + area: '面积',
  62 + feeType: '收费类型',
  63 + feeName: '费用名称',
  64 + year: '年',
  65 + tip: '没有数据时,确保开启了定时任务'
  66 + },
  67 + reportProficientCarFee: {
  68 + name: '姓名',
  69 + carNumber: '车牌号',
  70 + phone: '联系电话',
  71 + feeType: '收费类型',
  72 + feeName: '费用名称',
  73 + year: '年',
  74 + tip: ' '
  75 + },
  76 + viewFeeDetail: {
  77 + yearFeeHistory: '年缴费历史',
  78 + cycle: '周期(单位:月)',
  79 + receivableAmount: '应收金额(单位:元)',
  80 + receivedAmount: '实收金额(单位:元)',
  81 + paymentTime: '缴费时间',
  82 + startTime: '缴费起始时间',
  83 + endTime: '缴费结束时间',
  84 + status: '状态',
  85 + remark: '备注'
  86 + }
  87 + }
  88 +}
0 \ No newline at end of file 89 \ No newline at end of file
src/views/report/reportProficientList.vue 0 → 100644
  1 +<template>
  2 + <div class="report-proficient-container">
  3 + <!-- 查询条件 -->
  4 + <el-card class="search-wrapper">
  5 + <div slot="header" class="clearfix">
  6 + <span>{{ $t('reportProficient.search.title') }}</span>
  7 + <div class="header-tools">
  8 + <el-button type="primary" size="small" @click="_exportFee">
  9 + <i class="el-icon-upload"></i>
  10 + {{ $t('reportProficient.export') }}
  11 + </el-button>
  12 + </div>
  13 + </div>
  14 + <el-row :gutter="20">
  15 + <el-col :span="6">
  16 + <el-select v-model="reportProficientInfo.conditions.feeTypeCd" @change="_changeReporficientFeeTypeCd"
  17 + placeholder="请选择收费类型" style="width:100%">
  18 + <el-option v-for="(item, index) in reportProficientInfo.feeTypeCds" :key="index" :label="item.name"
  19 + :value="item.statusCd">
  20 + </el-option>
  21 + </el-select>
  22 + </el-col>
  23 + <el-col :span="6">
  24 + <el-select v-model="reportProficientInfo.conditions.configId" placeholder="请选择收费项" style="width:100%">
  25 + <el-option v-for="(item, index) in reportProficientInfo.feeConfigDtos" :key="index" :label="item.feeName"
  26 + :value="item.configId">
  27 + </el-option>
  28 + </el-select>
  29 + </el-col>
  30 + <el-col :span="6">
  31 + <el-input :placeholder="_getReportProficientRoomName()" v-model="reportProficientInfo.conditions.objName">
  32 + </el-input>
  33 + </el-col>
  34 + <el-col :span="6">
  35 + <el-button type="primary" @click="_queryMethod">
  36 + <i class="el-icon-search"></i>
  37 + {{ $t('common.search') }}
  38 + </el-button>
  39 + <el-button @click="_resetMethod" style="margin-left: 10px;">
  40 + <i class="el-icon-refresh"></i>
  41 + {{ $t('common.reset') }}
  42 + </el-button>
  43 + </el-col>
  44 + </el-row>
  45 + </el-card>
  46 +
  47 + <!-- 内容区域 -->
  48 + <el-card class="content-wrapper">
  49 + <el-tabs v-model="reportProficientInfo._currentTab" @tab-click="changeTab">
  50 + <el-tab-pane :label="$t('reportProficient.roomFee')" name="reportProficientRoomFee">
  51 + <report-proficient-room-fee ref="reportProficientRoomFee" v-if="reportProficientInfo._currentTab === 'reportProficientRoomFee'"
  52 + :conditions="reportProficientInfo.conditions">
  53 + </report-proficient-room-fee>
  54 + </el-tab-pane>
  55 + <el-tab-pane :label="$t('reportProficient.carFee')" name="reportProficientCarFee">
  56 + <report-proficient-car-fee ref="reportProficientCarFee" v-if="reportProficientInfo._currentTab === 'reportProficientCarFee'"
  57 + :conditions="reportProficientInfo.conditions">
  58 + </report-proficient-car-fee>
  59 + </el-tab-pane>
  60 + </el-tabs>
  61 + </el-card>
  62 +
  63 + <!-- 费用详情弹窗 -->
  64 + <view-fee-detail ref="viewFeeDetail"></view-fee-detail>
  65 + </div>
  66 +</template>
  67 +
  68 +<script>
  69 +import { getDict } from '@/api/community/communityApi'
  70 +import { getFeeConfigList, exportReportFee } from '@/api/report/reportProficientApi'
  71 +import ReportProficientRoomFee from '@/components/report/reportProficientRoomFee'
  72 +import ReportProficientCarFee from '@/components/report/reportProficientCarFee'
  73 +import ViewFeeDetail from '@/components/report/viewFeeDetail'
  74 +
  75 +export default {
  76 + name: 'ReportProficientList',
  77 + components: {
  78 + ReportProficientRoomFee,
  79 + ReportProficientCarFee,
  80 + ViewFeeDetail
  81 + },
  82 + data() {
  83 + return {
  84 + reportProficientInfo: {
  85 + _currentTab: 'reportProficientRoomFee',
  86 + feeTypeCds: [],
  87 + feeConfigDtos: [],
  88 + conditions: {
  89 + configId: '',
  90 + feeTypeCd: '',
  91 + objName: '',
  92 + objType: ''
  93 + }
  94 + }
  95 + }
  96 + },
  97 + created() {
  98 + this._initData()
  99 + },
  100 + methods: {
  101 + async _initData() {
  102 + // 获取费用类型字典
  103 + try {
  104 + const data = await getDict('pay_fee_config', 'fee_type_cd')
  105 + this.reportProficientInfo.feeTypeCds = data
  106 + } catch (error) {
  107 + console.error('获取费用类型失败:', error)
  108 + }
  109 + },
  110 + async _changeReporficientFeeTypeCd() {
  111 + try {
  112 + const params = {
  113 + page: 1,
  114 + row: 50,
  115 + feeTypeCd: this.reportProficientInfo.conditions.feeTypeCd,
  116 + valid: '1'
  117 + }
  118 + const { data } = await getFeeConfigList(params)
  119 + this.reportProficientInfo.feeConfigDtos = data
  120 + } catch (error) {
  121 + console.error('获取收费项失败:', error)
  122 + }
  123 + },
  124 + changeTab(tab) {
  125 + this.reportProficientInfo._currentTab = tab.name || tab
  126 + this._queryMethod()
  127 + },
  128 + _queryMethod() {
  129 + setTimeout(() => {
  130 + this.$refs[`${this.reportProficientInfo._currentTab}`].handleSwitch()
  131 + },500)
  132 + },
  133 + _resetMethod() {
  134 + this.reportProficientInfo.conditions = {
  135 + configId: '',
  136 + feeTypeCd: '',
  137 + objName: '',
  138 + objType: ''
  139 + }
  140 + this._queryMethod()
  141 + },
  142 + _getReportProficientRoomName() {
  143 + if (this.reportProficientInfo._currentTab === 'reportProficientRoomFee') {
  144 + return this.$t('reportProficient.roomPlaceholder')
  145 + }
  146 + return this.$t('reportProficient.carPlaceholder')
  147 + },
  148 + async _exportFee() {
  149 + try {
  150 + const objType = this.reportProficientInfo._currentTab === 'reportProficientRoomFee' ? '3333' : '6666'
  151 + const params = {
  152 + ...this.reportProficientInfo.conditions,
  153 + objType,
  154 + pagePath: 'reportProficient'
  155 + }
  156 + const res = await exportReportFee(params)
  157 + this.$message.success(res.msg)
  158 + if (res.code === 0) {
  159 + this.$router.push('/pages/property/downloadTempFile?tab=下载中心')
  160 + }
  161 + } catch (error) {
  162 + console.error('导出失败:', error)
  163 + }
  164 + }
  165 + }
  166 +}
  167 +</script>
  168 +
  169 +<style lang="scss" scoped>
  170 +.report-proficient-container {
  171 + padding: 20px;
  172 +
  173 + .search-wrapper {
  174 + margin-bottom: 20px;
  175 +
  176 + .header-tools {
  177 + float: right;
  178 + }
  179 + }
  180 +
  181 + .content-wrapper {
  182 + margin-top: 20px;
  183 + }
  184 +}
  185 +</style>
0 \ No newline at end of file 186 \ No newline at end of file