Commit 51f9221ae8a527018890dcec79f18f1979bedfb1
1 parent
31c24e26
加入报表功能
Showing
31 changed files
with
4850 additions
and
0 deletions
src/api/report/dataReportApi.js
0 → 100644
| 1 | +import request from '@/utils/request' | |
| 2 | + | |
| 3 | +// 查询费用统计数据 | |
| 4 | +export function queryFeeDataReport(params) { | |
| 5 | + return new Promise((resolve, reject) => { | |
| 6 | + request({ | |
| 7 | + url: '/dataReport.queryFeeDataReport', | |
| 8 | + method: 'get', | |
| 9 | + params | |
| 10 | + }).then(response => { | |
| 11 | + const res = response.data | |
| 12 | + resolve(res) | |
| 13 | + }).catch(error => { | |
| 14 | + reject(error) | |
| 15 | + }) | |
| 16 | + }) | |
| 17 | +} | |
| 18 | + | |
| 19 | +// 查询工单统计数据 | |
| 20 | +export function queryOrderDataReport(params) { | |
| 21 | + return new Promise((resolve, reject) => { | |
| 22 | + request({ | |
| 23 | + url: '/dataReport.queryOrderDataReport', | |
| 24 | + method: 'get', | |
| 25 | + params | |
| 26 | + }).then(response => { | |
| 27 | + const res = response.data | |
| 28 | + resolve(res) | |
| 29 | + }).catch(error => { | |
| 30 | + reject(error) | |
| 31 | + }) | |
| 32 | + }) | |
| 33 | +} | |
| 34 | + | |
| 35 | +// 查询出入统计数据 | |
| 36 | +export function queryInoutDataReport(params) { | |
| 37 | + return new Promise((resolve, reject) => { | |
| 38 | + request({ | |
| 39 | + url: '/dataReport.queryInoutDataReport', | |
| 40 | + method: 'get', | |
| 41 | + params | |
| 42 | + }).then(response => { | |
| 43 | + const res = response.data | |
| 44 | + resolve(res) | |
| 45 | + }).catch(error => { | |
| 46 | + reject(error) | |
| 47 | + }) | |
| 48 | + }) | |
| 49 | +} | |
| 50 | + | |
| 51 | +// 查询其他统计数据 | |
| 52 | +export function queryOthersDataReport(params) { | |
| 53 | + return new Promise((resolve, reject) => { | |
| 54 | + request({ | |
| 55 | + url: '/dataReport.queryOthersDataReport', | |
| 56 | + method: 'get', | |
| 57 | + params | |
| 58 | + }).then(response => { | |
| 59 | + const res = response.data | |
| 60 | + resolve(res) | |
| 61 | + }).catch(error => { | |
| 62 | + reject(error) | |
| 63 | + }) | |
| 64 | + }) | |
| 65 | +} | |
| 66 | + | |
| 67 | +// 查询实收统计数据 | |
| 68 | +export function queryReceivedStatistics(params) { | |
| 69 | + return new Promise((resolve, reject) => { | |
| 70 | + request({ | |
| 71 | + url: '/dataReport.queryReceivedStatistics', | |
| 72 | + method: 'get', | |
| 73 | + params | |
| 74 | + }).then(response => { | |
| 75 | + const res = response.data | |
| 76 | + resolve(res) | |
| 77 | + }).catch(error => { | |
| 78 | + reject(error) | |
| 79 | + }) | |
| 80 | + }) | |
| 81 | +} | |
| 82 | + | |
| 83 | +// 查询实收明细统计数据 | |
| 84 | +export function queryReceivedDetailStatistics(params) { | |
| 85 | + return new Promise((resolve, reject) => { | |
| 86 | + request({ | |
| 87 | + url: '/dataReport.queryReceivedDetailStatistics', | |
| 88 | + method: 'get', | |
| 89 | + params | |
| 90 | + }).then(response => { | |
| 91 | + const res = response.data | |
| 92 | + resolve(res) | |
| 93 | + }).catch(error => { | |
| 94 | + reject(error) | |
| 95 | + }) | |
| 96 | + }) | |
| 97 | +} | |
| 98 | + | |
| 99 | +// 查询收款方式统计数据 | |
| 100 | +export function queryReceivedWayStatistics(params) { | |
| 101 | + return new Promise((resolve, reject) => { | |
| 102 | + request({ | |
| 103 | + url: '/dataReport.queryReceivedWayStatistics', | |
| 104 | + method: 'get', | |
| 105 | + params | |
| 106 | + }).then(response => { | |
| 107 | + const res = response.data | |
| 108 | + resolve(res) | |
| 109 | + }).catch(error => { | |
| 110 | + reject(error) | |
| 111 | + }) | |
| 112 | + }) | |
| 113 | +} | |
| 114 | + | |
| 115 | +// 查询欠费统计数据 | |
| 116 | +export function queryOweStatistics(params) { | |
| 117 | + return new Promise((resolve, reject) => { | |
| 118 | + request({ | |
| 119 | + url: '/dataReport.queryOweStatistics', | |
| 120 | + method: 'get', | |
| 121 | + params | |
| 122 | + }).then(response => { | |
| 123 | + const res = response.data | |
| 124 | + resolve(res) | |
| 125 | + }).catch(error => { | |
| 126 | + reject(error) | |
| 127 | + }) | |
| 128 | + }) | |
| 129 | +} | |
| 130 | + | |
| 131 | +// 查询欠费明细统计数据 | |
| 132 | +export function queryOweDetailStatistics(params) { | |
| 133 | + return new Promise((resolve, reject) => { | |
| 134 | + request({ | |
| 135 | + url: '/dataReport.queryOweDetailStatistics', | |
| 136 | + method: 'get', | |
| 137 | + params | |
| 138 | + }).then(response => { | |
| 139 | + const res = response.data | |
| 140 | + resolve(res) | |
| 141 | + }).catch(error => { | |
| 142 | + reject(error) | |
| 143 | + }) | |
| 144 | + }) | |
| 145 | +} | |
| 146 | + | |
| 147 | +// 查询收缴情况统计数据 | |
| 148 | +export function queryDataReportFeeStatistics(params) { | |
| 149 | + return new Promise((resolve, reject) => { | |
| 150 | + request({ | |
| 151 | + url: '/dataReport.queryDataReportFeeStatistics', | |
| 152 | + method: 'get', | |
| 153 | + params | |
| 154 | + }).then(response => { | |
| 155 | + const res = response.data | |
| 156 | + resolve(res) | |
| 157 | + }).catch(error => { | |
| 158 | + reject(error) | |
| 159 | + }) | |
| 160 | + }) | |
| 161 | +} | |
| 162 | + | |
| 163 | +// 查询月实收明细数据 | |
| 164 | +export function queryMonthReceivedDetail(params) { | |
| 165 | + return new Promise((resolve, reject) => { | |
| 166 | + request({ | |
| 167 | + url: '/dataReport.queryMonthReceivedDetail', | |
| 168 | + method: 'get', | |
| 169 | + params | |
| 170 | + }).then(response => { | |
| 171 | + const res = response.data | |
| 172 | + resolve(res) | |
| 173 | + }).catch(error => { | |
| 174 | + reject(error) | |
| 175 | + }) | |
| 176 | + }) | |
| 177 | +} | |
| 178 | + | |
| 179 | +// 查询月欠费明细数据 | |
| 180 | +export function queryMonthOweDetail(params) { | |
| 181 | + return new Promise((resolve, reject) => { | |
| 182 | + request({ | |
| 183 | + url: '/dataReport.queryMonthOweDetail', | |
| 184 | + method: 'get', | |
| 185 | + params | |
| 186 | + }).then(response => { | |
| 187 | + const res = response.data | |
| 188 | + resolve(res) | |
| 189 | + }).catch(error => { | |
| 190 | + reject(error) | |
| 191 | + }) | |
| 192 | + }) | |
| 193 | +} | |
| 194 | + | |
| 195 | +// 查询楼栋列表 | |
| 196 | +export function queryFloors(params) { | |
| 197 | + return new Promise((resolve, reject) => { | |
| 198 | + request({ | |
| 199 | + url: '/floor.queryFloors', | |
| 200 | + method: 'get', | |
| 201 | + params | |
| 202 | + }).then(response => { | |
| 203 | + const res = response.data | |
| 204 | + resolve(res) | |
| 205 | + }).catch(error => { | |
| 206 | + reject(error) | |
| 207 | + }) | |
| 208 | + }) | |
| 209 | +} | |
| 210 | + | |
| 211 | +// 查询我入驻的小区列表 | |
| 212 | +export function listMyEnteredCommunitys(params) { | |
| 213 | + return new Promise((resolve, reject) => { | |
| 214 | + request({ | |
| 215 | + url: '/community.listMyEnteredCommunitys', | |
| 216 | + method: 'get', | |
| 217 | + params | |
| 218 | + }).then(response => { | |
| 219 | + const res = response.data | |
| 220 | + resolve(res) | |
| 221 | + }).catch(error => { | |
| 222 | + reject(error) | |
| 223 | + }) | |
| 224 | + }) | |
| 225 | +} | |
| 226 | + | |
| 227 | +// 导出数据 | |
| 228 | +export function exportData(params) { | |
| 229 | + return new Promise((resolve, reject) => { | |
| 230 | + request({ | |
| 231 | + url: '/export.exportData', | |
| 232 | + method: 'get', | |
| 233 | + params | |
| 234 | + }).then(response => { | |
| 235 | + const res = response.data | |
| 236 | + resolve(res) | |
| 237 | + }).catch(error => { | |
| 238 | + reject(error) | |
| 239 | + }) | |
| 240 | + }) | |
| 241 | +} | |
| 0 | 242 | \ No newline at end of file | ... | ... |
src/api/report/feeRemindApi.js
0 → 100644
| 1 | +import request from '@/utils/request' | |
| 2 | + | |
| 3 | +// 查询预缴费提醒列表 | |
| 4 | +export function queryPrePayment(params) { | |
| 5 | + return new Promise((resolve, reject) => { | |
| 6 | + request({ | |
| 7 | + url: '/reportFeeMonthStatistics.queryPrePayment', | |
| 8 | + method: 'get', | |
| 9 | + params | |
| 10 | + }).then(response => { | |
| 11 | + const res = response.data | |
| 12 | + resolve(res) | |
| 13 | + }).catch(error => { | |
| 14 | + reject(error) | |
| 15 | + }) | |
| 16 | + }) | |
| 17 | +} | |
| 18 | + | |
| 19 | +// 查询到期提醒列表 | |
| 20 | +export function queryDeadlineFee(params) { | |
| 21 | + return new Promise((resolve, reject) => { | |
| 22 | + request({ | |
| 23 | + url: '/reportFeeMonthStatistics.queryDeadlineFee', | |
| 24 | + method: 'get', | |
| 25 | + params | |
| 26 | + }).then(response => { | |
| 27 | + const res = response.data | |
| 28 | + resolve(res) | |
| 29 | + }).catch(error => { | |
| 30 | + reject(error) | |
| 31 | + }) | |
| 32 | + }) | |
| 33 | +} | |
| 34 | + | |
| 35 | +// 导出数据 | |
| 36 | +export function exportData(params) { | |
| 37 | + return new Promise((resolve, reject) => { | |
| 38 | + request({ | |
| 39 | + url: '/export.exportData', | |
| 40 | + method: 'get', | |
| 41 | + params | |
| 42 | + }).then(response => { | |
| 43 | + const res = response.data | |
| 44 | + resolve(res) | |
| 45 | + }).catch(error => { | |
| 46 | + reject(error) | |
| 47 | + }) | |
| 48 | + }) | |
| 49 | +} | |
| 50 | + | |
| 51 | +// 查询费用项列表 | |
| 52 | +export function listFeeConfigs(params) { | |
| 53 | + return new Promise((resolve, reject) => { | |
| 54 | + request({ | |
| 55 | + url: '/feeConfig.listFeeConfigs', | |
| 56 | + method: 'get', | |
| 57 | + params | |
| 58 | + }).then(response => { | |
| 59 | + const res = response.data | |
| 60 | + resolve(res) | |
| 61 | + }).catch(error => { | |
| 62 | + reject(error) | |
| 63 | + }) | |
| 64 | + }) | |
| 65 | +} | |
| 66 | + | |
| 67 | +// 查询已入驻小区列表 | |
| 68 | +export function listMyEnteredCommunitys(params) { | |
| 69 | + return new Promise((resolve, reject) => { | |
| 70 | + request({ | |
| 71 | + url: '/community.listMyEnteredCommunitys', | |
| 72 | + method: 'get', | |
| 73 | + params | |
| 74 | + }).then(response => { | |
| 75 | + const res = response.data | |
| 76 | + resolve(res) | |
| 77 | + }).catch(error => { | |
| 78 | + reject(error) | |
| 79 | + }) | |
| 80 | + }) | |
| 81 | +} | |
| 0 | 82 | \ No newline at end of file | ... | ... |
src/api/report/reportFeeDetailApi.js
0 → 100644
| 1 | +import request from '@/utils/request' | |
| 2 | + | |
| 3 | +// 查询房屋费用明细 | |
| 4 | +export function queryReportFeeDetailRoom(params) { | |
| 5 | + return new Promise((resolve, reject) => { | |
| 6 | + request({ | |
| 7 | + url: '/reportFeeMonthStatistics.queryReportFeeDetailRoom', | |
| 8 | + method: 'get', | |
| 9 | + params | |
| 10 | + }).then(response => { | |
| 11 | + const res = response.data | |
| 12 | + resolve({ | |
| 13 | + data: res.data, | |
| 14 | + total: res.total | |
| 15 | + }) | |
| 16 | + }).catch(error => { | |
| 17 | + reject(error) | |
| 18 | + }) | |
| 19 | + }) | |
| 20 | +} | |
| 21 | + | |
| 22 | +// 查询业主费用明细 | |
| 23 | +export function queryReportFeeDetailOwner(params) { | |
| 24 | + return new Promise((resolve, reject) => { | |
| 25 | + request({ | |
| 26 | + url: '/reportFeeMonthStatistics.queryReportFeeDetailOwner', | |
| 27 | + method: 'get', | |
| 28 | + params | |
| 29 | + }).then(response => { | |
| 30 | + const res = response.data | |
| 31 | + resolve({ | |
| 32 | + data: res.data, | |
| 33 | + total: res.total | |
| 34 | + }) | |
| 35 | + }).catch(error => { | |
| 36 | + reject(error) | |
| 37 | + }) | |
| 38 | + }) | |
| 39 | +} | |
| 40 | + | |
| 41 | +// 查询合同费用明细 | |
| 42 | +export function queryReportFeeDetailContract(params) { | |
| 43 | + return new Promise((resolve, reject) => { | |
| 44 | + request({ | |
| 45 | + url: '/reportFeeMonthStatistics.queryReportFeeDetailContract', | |
| 46 | + method: 'get', | |
| 47 | + params | |
| 48 | + }).then(response => { | |
| 49 | + const res = response.data | |
| 50 | + resolve({ | |
| 51 | + data: res.data, | |
| 52 | + total: res.total | |
| 53 | + }) | |
| 54 | + }).catch(error => { | |
| 55 | + reject(error) | |
| 56 | + }) | |
| 57 | + }) | |
| 58 | +} | |
| 59 | + | |
| 60 | +// 查询车辆费用明细 | |
| 61 | +export function queryReportFeeDetailCar(params) { | |
| 62 | + return new Promise((resolve, reject) => { | |
| 63 | + request({ | |
| 64 | + url: '/reportFeeMonthStatistics.queryReportFeeDetailCar', | |
| 65 | + method: 'get', | |
| 66 | + params | |
| 67 | + }).then(response => { | |
| 68 | + const res = response.data | |
| 69 | + resolve({ | |
| 70 | + data: res.data, | |
| 71 | + total: res.total | |
| 72 | + }) | |
| 73 | + }).catch(error => { | |
| 74 | + reject(error) | |
| 75 | + }) | |
| 76 | + }) | |
| 77 | +} | |
| 78 | + | |
| 79 | +// 导出房屋费用明细 | |
| 80 | +export function exportReportFeeDetailRoom(params) { | |
| 81 | + return new Promise((resolve, reject) => { | |
| 82 | + request({ | |
| 83 | + url: '/export.exportData', | |
| 84 | + method: 'get', | |
| 85 | + params | |
| 86 | + }).then(response => { | |
| 87 | + const res = response.data | |
| 88 | + resolve(res) | |
| 89 | + }).catch(error => { | |
| 90 | + reject(error) | |
| 91 | + }) | |
| 92 | + }) | |
| 93 | +} | |
| 94 | + | |
| 95 | +// 导出业主费用明细 | |
| 96 | +export function exportReportFeeDetailOwner(params) { | |
| 97 | + return new Promise((resolve, reject) => { | |
| 98 | + request({ | |
| 99 | + url: '/export.exportData', | |
| 100 | + method: 'get', | |
| 101 | + params | |
| 102 | + }).then(response => { | |
| 103 | + const res = response.data | |
| 104 | + resolve(res) | |
| 105 | + }).catch(error => { | |
| 106 | + reject(error) | |
| 107 | + }) | |
| 108 | + }) | |
| 109 | +} | |
| 110 | + | |
| 111 | +// 导出合同费用明细 | |
| 112 | +export function exportReportFeeDetailContract(params) { | |
| 113 | + return new Promise((resolve, reject) => { | |
| 114 | + request({ | |
| 115 | + url: '/export.exportData', | |
| 116 | + method: 'get', | |
| 117 | + params | |
| 118 | + }).then(response => { | |
| 119 | + const res = response.data | |
| 120 | + resolve(res) | |
| 121 | + }).catch(error => { | |
| 122 | + reject(error) | |
| 123 | + }) | |
| 124 | + }) | |
| 125 | +} | |
| 126 | + | |
| 127 | +// 导出车辆费用明细 | |
| 128 | +export function exportReportFeeDetailCar(params) { | |
| 129 | + return new Promise((resolve, reject) => { | |
| 130 | + request({ | |
| 131 | + url: '/export.exportData', | |
| 132 | + method: 'get', | |
| 133 | + params | |
| 134 | + }).then(response => { | |
| 135 | + const res = response.data | |
| 136 | + resolve(res) | |
| 137 | + }).catch(error => { | |
| 138 | + reject(error) | |
| 139 | + }) | |
| 140 | + }) | |
| 141 | +} | |
| 142 | + | |
| 143 | +export function loadStaffCommunitys(params) { | |
| 144 | + return new Promise((resolve, reject) => { | |
| 145 | + request({ | |
| 146 | + url: '/community.listMyEnteredCommunitys', | |
| 147 | + method: 'get', | |
| 148 | + params | |
| 149 | + }).then(response => { | |
| 150 | + const res = response.data | |
| 151 | + resolve(res) | |
| 152 | + }).catch(error => { | |
| 153 | + reject(error) | |
| 154 | + }) | |
| 155 | + }) | |
| 156 | +} | |
| 0 | 157 | \ No newline at end of file | ... | ... |
src/api/report/reportFeeSummaryApi.js
0 → 100644
| 1 | +import request from '@/utils/request' | |
| 2 | + | |
| 3 | +/** | |
| 4 | + * 查询费用汇总数据 | |
| 5 | + * @param {Object} params 查询参数 | |
| 6 | + */ | |
| 7 | +export function queryReportFeeSummary(params) { | |
| 8 | + return new Promise((resolve, reject) => { | |
| 9 | + request({ | |
| 10 | + url: '/reportFeeMonthStatistics.queryReportFeeSummary', | |
| 11 | + method: 'get', | |
| 12 | + params | |
| 13 | + }).then(response => { | |
| 14 | + const res = response.data | |
| 15 | + resolve(res) | |
| 16 | + }).catch(error => { | |
| 17 | + reject(error) | |
| 18 | + }) | |
| 19 | + }) | |
| 20 | +} | |
| 21 | + | |
| 22 | +/** | |
| 23 | + * 查询楼栋费用汇总数据 | |
| 24 | + * @param {Object} params 查询参数 | |
| 25 | + */ | |
| 26 | +export function queryReportFloorFeeSummary(params) { | |
| 27 | + return new Promise((resolve, reject) => { | |
| 28 | + request({ | |
| 29 | + url: '/reportFeeMonthStatistics.queryReportFloorFeeSummary', | |
| 30 | + method: 'get', | |
| 31 | + params | |
| 32 | + }).then(response => { | |
| 33 | + const res = response.data | |
| 34 | + resolve(res) | |
| 35 | + }).catch(error => { | |
| 36 | + reject(error) | |
| 37 | + }) | |
| 38 | + }) | |
| 39 | +} | |
| 40 | + | |
| 41 | +/** | |
| 42 | + * 查询费用项汇总数据 | |
| 43 | + * @param {Object} params 查询参数 | |
| 44 | + */ | |
| 45 | +export function queryReportConfigFeeSummary(params) { | |
| 46 | + return new Promise((resolve, reject) => { | |
| 47 | + request({ | |
| 48 | + url: '/reportFeeMonthStatistics.queryReportConfigFeeSummary', | |
| 49 | + method: 'get', | |
| 50 | + params | |
| 51 | + }).then(response => { | |
| 52 | + const res = response.data | |
| 53 | + resolve(res) | |
| 54 | + }).catch(error => { | |
| 55 | + reject(error) | |
| 56 | + }) | |
| 57 | + }) | |
| 58 | +} | |
| 59 | + | |
| 60 | +/** | |
| 61 | + * 导出数据 | |
| 62 | + * @param {Object} params 导出参数 | |
| 63 | + */ | |
| 64 | +export function exportData(params) { | |
| 65 | + return new Promise((resolve, reject) => { | |
| 66 | + request({ | |
| 67 | + url: '/export.exportData', | |
| 68 | + method: 'get', | |
| 69 | + params | |
| 70 | + }).then(response => { | |
| 71 | + const res = response.data | |
| 72 | + resolve(res) | |
| 73 | + }).catch(error => { | |
| 74 | + reject(error) | |
| 75 | + }) | |
| 76 | + }) | |
| 77 | +} | |
| 78 | + | |
| 79 | +/** | |
| 80 | + * 查询楼栋列表 | |
| 81 | + * @param {Object} params 查询参数 | |
| 82 | + */ | |
| 83 | +export function queryFloors(params) { | |
| 84 | + return new Promise((resolve, reject) => { | |
| 85 | + request({ | |
| 86 | + url: '/floor.queryFloors', | |
| 87 | + method: 'get', | |
| 88 | + params | |
| 89 | + }).then(response => { | |
| 90 | + const res = response.data | |
| 91 | + resolve(res) | |
| 92 | + }).catch(error => { | |
| 93 | + reject(error) | |
| 94 | + }) | |
| 95 | + }) | |
| 96 | +} | |
| 97 | + | |
| 98 | +/** | |
| 99 | + * 查询费用配置列表 | |
| 100 | + * @param {Object} params 查询参数 | |
| 101 | + */ | |
| 102 | +export function queryFeeConfigs(params) { | |
| 103 | + return new Promise((resolve, reject) => { | |
| 104 | + request({ | |
| 105 | + url: '/feeConfig.listFeeConfigs', | |
| 106 | + method: 'get', | |
| 107 | + params | |
| 108 | + }).then(response => { | |
| 109 | + const res = response.data | |
| 110 | + resolve(res) | |
| 111 | + }).catch(error => { | |
| 112 | + reject(error) | |
| 113 | + }) | |
| 114 | + }) | |
| 115 | +} | |
| 116 | + | |
| 117 | +/** | |
| 118 | + * 查询用户关联的小区列表 | |
| 119 | + */ | |
| 120 | +export function queryCommunitys() { | |
| 121 | + return new Promise((resolve, reject) => { | |
| 122 | + request({ | |
| 123 | + url: '/community.listMyEnteredCommunitys', | |
| 124 | + method: 'get', | |
| 125 | + params: { | |
| 126 | + _uid: '123mlkdinkldldijdhuudjdjkkd', | |
| 127 | + page: 1, | |
| 128 | + row: 100 | |
| 129 | + } | |
| 130 | + }).then(response => { | |
| 131 | + const res = response.data | |
| 132 | + resolve(res) | |
| 133 | + }).catch(error => { | |
| 134 | + reject(error) | |
| 135 | + }) | |
| 136 | + }) | |
| 137 | +} | |
| 0 | 138 | \ No newline at end of file | ... | ... |
src/components/report/DataMonthOweStatistics.vue
0 → 100644
| 1 | +<template> | |
| 2 | + <div class="margin-top"> | |
| 3 | + <el-row> | |
| 4 | + <el-col :span="3" class="padding-r-0"> | |
| 5 | + <el-card class="border-radius"> | |
| 6 | + <div class="treeview attendance-staff" style="height: 650px;"> | |
| 7 | + <ul class="list-group text-center border-radius"> | |
| 8 | + <li v-for="(item, index) in dataMonthOweStatisticsInfo.feeTypeCds" :key="index" | |
| 9 | + class="list-group-item node-orgTree" | |
| 10 | + :class="{ 'vc-node-selected': dataMonthOweStatisticsInfo.feeTypeCd === item.statusCd }" | |
| 11 | + @click="_switchMonthOweStatisticsFeeTypeCd(item.statusCd)"> | |
| 12 | + {{ item.name }} | |
| 13 | + </li> | |
| 14 | + </ul> | |
| 15 | + </div> | |
| 16 | + </el-card> | |
| 17 | + </el-col> | |
| 18 | + <el-col :span="21"> | |
| 19 | + <el-row> | |
| 20 | + <el-col :span="4"> | |
| 21 | + <el-select v-model="dataMonthOweStatisticsInfo.floorId" :placeholder="$t('dataReport.selectBuilding')" | |
| 22 | + clearable style="width: 100%"> | |
| 23 | + <el-option v-for="(item, index) in dataMonthOweStatisticsInfo.floors" :key="index" :label="item.floorNum" | |
| 24 | + :value="item.floorId" /> | |
| 25 | + </el-select> | |
| 26 | + </el-col> | |
| 27 | + <el-col :span="4"> | |
| 28 | + <el-date-picker v-model="dataMonthOweStatisticsInfo.feeStartDate" type="date" | |
| 29 | + :placeholder="$t('dataReport.feeStartDate')" style="width: 100%" /> | |
| 30 | + </el-col> | |
| 31 | + <el-col :span="4"> | |
| 32 | + <el-date-picker v-model="dataMonthOweStatisticsInfo.feeEndDate" type="date" | |
| 33 | + :placeholder="$t('dataReport.feeEndDate')" style="width: 100%" /> | |
| 34 | + </el-col> | |
| 35 | + <el-col :span="4"> | |
| 36 | + <el-button type="primary" size="small" @click="_qureyDataMonthOweStatistics"> | |
| 37 | + <i class="el-icon-search"></i> | |
| 38 | + {{ $t('dataReport.search') }} | |
| 39 | + </el-button> | |
| 40 | + </el-col> | |
| 41 | + <el-col :span="8" class="text-right"> | |
| 42 | + <el-button type="primary" size="small" @click="_exportReportMonthOweFeeExcel"> | |
| 43 | + <i class="el-icon-download"></i> | |
| 44 | + <span>{{ $t('dataReport.export') }}</span> | |
| 45 | + </el-button> | |
| 46 | + </el-col> | |
| 47 | + </el-row> | |
| 48 | + | |
| 49 | + <div class="margin-top"> | |
| 50 | + <el-table :data="dataMonthOweStatisticsInfo.fees" border style="width: 100%"> | |
| 51 | + <el-table-column prop="objName" :label="$t('dataReport.room')" align="center" /> | |
| 52 | + <el-table-column :label="$t('dataReport.owner')" align="center"> | |
| 53 | + <template slot-scope="scope"> | |
| 54 | + {{ scope.row.ownerName }}({{ scope.row.link }}) | |
| 55 | + </template> | |
| 56 | + </el-table-column> | |
| 57 | + <el-table-column prop="feeName" :label="$t('dataReport.feeName')" align="center" /> | |
| 58 | + <el-table-column prop="curYearMonth" :label="$t('dataReport.owePeriod')" align="center" /> | |
| 59 | + <el-table-column prop="receivableAmount" :label="$t('dataReport.oweAmount')" align="center"> | |
| 60 | + <template slot-scope="scope"> | |
| 61 | + {{ scope.row.receivableAmount || 0 }} | |
| 62 | + </template> | |
| 63 | + </el-table-column> | |
| 64 | + </el-table> | |
| 65 | + | |
| 66 | + <el-row class="margin-top"> | |
| 67 | + <el-col :span="8"> | |
| 68 | + <span>{{ $t('dataReport.totalOwe') }}:</span> | |
| 69 | + <span>{{ dataMonthOweStatisticsInfo.feeAmount }}</span> | |
| 70 | + </el-col> | |
| 71 | + <el-col :span="16" class="text-right"> | |
| 72 | + <el-pagination :current-page.sync="page.current" :page-sizes="[10, 20, 30, 50]" :page-size="page.size" | |
| 73 | + :total="page.total" layout="total, sizes, prev, pager, next, jumper" @size-change="handleSizeChange" | |
| 74 | + @current-change="handleCurrentChange" /> | |
| 75 | + </el-col> | |
| 76 | + </el-row> | |
| 77 | + </div> | |
| 78 | + </el-col> | |
| 79 | + </el-row> | |
| 80 | + </div> | |
| 81 | +</template> | |
| 82 | + | |
| 83 | +<script> | |
| 84 | +import { getDict } from '@/api/community/communityApi' | |
| 85 | +import { queryMonthOweDetail, exportData, queryFloors } from '@/api/report/dataReportApi' | |
| 86 | + | |
| 87 | +export default { | |
| 88 | + name: 'DataMonthOweStatistics', | |
| 89 | + | |
| 90 | + data() { | |
| 91 | + return { | |
| 92 | + dataMonthOweStatisticsInfo: { | |
| 93 | + fees: [], | |
| 94 | + feeTypeCds: [], | |
| 95 | + floors: [], | |
| 96 | + floorId: '', | |
| 97 | + feeStartDate: '', | |
| 98 | + feeEndDate: '', | |
| 99 | + feeTypeCd: '', | |
| 100 | + feeAmount: '0' | |
| 101 | + }, | |
| 102 | + startDate: '', | |
| 103 | + endDate: '', | |
| 104 | + communityId: '', | |
| 105 | + page: { | |
| 106 | + current: 1, | |
| 107 | + size: 10, | |
| 108 | + total: 0 | |
| 109 | + } | |
| 110 | + } | |
| 111 | + }, | |
| 112 | + created() { | |
| 113 | + this._initMethod() | |
| 114 | + }, | |
| 115 | + methods: { | |
| 116 | + open(param){ | |
| 117 | + this.startDate = param.startDate | |
| 118 | + this.endDate = param.endDate | |
| 119 | + this.communityId = param.communityId | |
| 120 | + this._loadMonthOweFloors() | |
| 121 | + }, | |
| 122 | + async _initMethod() { | |
| 123 | + try { | |
| 124 | + const data = await getDict('pay_fee_config', 'fee_type_cd_show') | |
| 125 | + this.dataMonthOweStatisticsInfo.feeTypeCds = data | |
| 126 | + this.dataMonthOweStatisticsInfo.feeTypeCd = data[0].statusCd | |
| 127 | + this.dataMonthOweStatisticsInfo.feeStartDate = this.startDate | |
| 128 | + this.dataMonthOweStatisticsInfo.feeEndDate = this.endDate | |
| 129 | + } catch (error) { | |
| 130 | + console.error('Failed to load dictionary:', error) | |
| 131 | + } | |
| 132 | + }, | |
| 133 | + async _loadMonthOweFloors() { | |
| 134 | + try { | |
| 135 | + const params = { | |
| 136 | + page: 1, | |
| 137 | + row: 100, | |
| 138 | + communityId: this.communityId | |
| 139 | + } | |
| 140 | + const { apiFloorDataVoList } = await queryFloors(params) | |
| 141 | + this.dataMonthOweStatisticsInfo.floors = apiFloorDataVoList | |
| 142 | + } catch (error) { | |
| 143 | + console.error('Failed to load floors:', error) | |
| 144 | + } | |
| 145 | + }, | |
| 146 | + async _loadDataMonthOweStatisticsData() { | |
| 147 | + try { | |
| 148 | + const params = { | |
| 149 | + page: this.page.current, | |
| 150 | + row: this.page.size, | |
| 151 | + communityId: this.communityId, | |
| 152 | + feeStartDate: this.dataMonthOweStatisticsInfo.feeStartDate, | |
| 153 | + feeEndDate: this.dataMonthOweStatisticsInfo.feeEndDate, | |
| 154 | + feeTypeCd: this.dataMonthOweStatisticsInfo.feeTypeCd, | |
| 155 | + floorId: this.dataMonthOweStatisticsInfo.floorId | |
| 156 | + } | |
| 157 | + const { data, records, sumTotal } = await queryMonthOweDetail(params) | |
| 158 | + this.dataMonthOweStatisticsInfo.fees = data | |
| 159 | + this.page.total = records | |
| 160 | + this.dataMonthOweStatisticsInfo.feeAmount = sumTotal | |
| 161 | + } catch (error) { | |
| 162 | + console.error('Failed to load data:', error) | |
| 163 | + } | |
| 164 | + }, | |
| 165 | + async _exportReportMonthOweFeeExcel() { | |
| 166 | + try { | |
| 167 | + const params = { | |
| 168 | + communityId: this.communityId, | |
| 169 | + feeStartDate: this.dataMonthOweStatisticsInfo.feeStartDate, | |
| 170 | + feeEndDate: this.dataMonthOweStatisticsInfo.feeEndDate, | |
| 171 | + feeTypeCd: this.dataMonthOweStatisticsInfo.feeTypeCd, | |
| 172 | + floorId: this.dataMonthOweStatisticsInfo.floorId, | |
| 173 | + pagePath: 'dataMonthOweStatistics' | |
| 174 | + } | |
| 175 | + const res = await exportData(params) | |
| 176 | + this.$message.success(res.msg) | |
| 177 | + if (res.code === 0) { | |
| 178 | + this.$router.push('/pages/property/downloadTempFile?tab=下载中心') | |
| 179 | + } | |
| 180 | + } catch (error) { | |
| 181 | + console.error('Export failed:', error) | |
| 182 | + } | |
| 183 | + }, | |
| 184 | + _qureyDataMonthOweStatistics() { | |
| 185 | + this.page.current = 1 | |
| 186 | + this._loadDataMonthOweStatisticsData() | |
| 187 | + }, | |
| 188 | + _switchMonthOweStatisticsFeeTypeCd(_feeTypeCd) { | |
| 189 | + this.dataMonthOweStatisticsInfo.feeTypeCd = _feeTypeCd | |
| 190 | + this._loadDataMonthOweStatisticsData() | |
| 191 | + }, | |
| 192 | + handleSizeChange(val) { | |
| 193 | + this.page.size = val | |
| 194 | + this._loadDataMonthOweStatisticsData() | |
| 195 | + }, | |
| 196 | + handleCurrentChange(val) { | |
| 197 | + this.page.current = val | |
| 198 | + this._loadDataMonthOweStatisticsData() | |
| 199 | + } | |
| 200 | + } | |
| 201 | +} | |
| 202 | +</script> | |
| 203 | + | |
| 204 | +<style scoped> | |
| 205 | +.margin-top { | |
| 206 | + margin-top: 20px; | |
| 207 | +} | |
| 208 | + | |
| 209 | +.text-right { | |
| 210 | + text-align: right; | |
| 211 | +} | |
| 212 | + | |
| 213 | +.padding-r-0 { | |
| 214 | + padding-right: 0; | |
| 215 | +} | |
| 216 | + | |
| 217 | +.border-radius { | |
| 218 | + border-radius: 4px; | |
| 219 | +} | |
| 220 | + | |
| 221 | +.list-group { | |
| 222 | + list-style: none; | |
| 223 | + padding: 0; | |
| 224 | + margin: 0; | |
| 225 | +} | |
| 226 | + | |
| 227 | +.list-group-item { | |
| 228 | + padding: 10px; | |
| 229 | + cursor: pointer; | |
| 230 | + border-bottom: 1px solid #eee; | |
| 231 | +} | |
| 232 | + | |
| 233 | +.list-group-item:hover { | |
| 234 | + background-color: #f5f5f5; | |
| 235 | +} | |
| 236 | + | |
| 237 | +.vc-node-selected { | |
| 238 | + background-color: #409EFF; | |
| 239 | + color: white; | |
| 240 | +} | |
| 241 | + | |
| 242 | +.treeview { | |
| 243 | + overflow-y: auto; | |
| 244 | +} | |
| 245 | +</style> | |
| 0 | 246 | \ No newline at end of file | ... | ... |
src/components/report/DataMonthReceivedStatistics.vue
0 → 100644
| 1 | +<template> | |
| 2 | + <div class="margin-top"> | |
| 3 | + <el-row> | |
| 4 | + <el-col :span="3" class="padding-r-0"> | |
| 5 | + <el-card class="border-radius"> | |
| 6 | + <div class="treeview attendance-staff" style="height: 650px;"> | |
| 7 | + <ul class="list-group text-center border-radius"> | |
| 8 | + <li v-for="(item, index) in dataMonthReceivedStatisticsInfo.feeTypeCds" :key="index" | |
| 9 | + class="list-group-item node-orgTree" | |
| 10 | + :class="{ 'vc-node-selected': dataMonthReceivedStatisticsInfo.feeTypeCd === item.statusCd }" | |
| 11 | + @click="switchMonthReceivedStatisticsFeeTypeCd(item.statusCd)"> | |
| 12 | + {{ item.name }} | |
| 13 | + </li> | |
| 14 | + </ul> | |
| 15 | + </div> | |
| 16 | + </el-card> | |
| 17 | + </el-col> | |
| 18 | + <el-col :span="21"> | |
| 19 | + <el-row> | |
| 20 | + <el-col :span="4"> | |
| 21 | + <el-select v-model="dataMonthReceivedStatisticsInfo.floorId" :placeholder="$t('dataReport.selectBuilding')" | |
| 22 | + clearable style="width: 100%"> | |
| 23 | + <el-option v-for="(item, index) in dataMonthReceivedStatisticsInfo.floors" :key="index" | |
| 24 | + :label="item.floorNum" :value="item.floorId" /> | |
| 25 | + </el-select> | |
| 26 | + </el-col> | |
| 27 | + <el-col :span="4"> | |
| 28 | + <el-date-picker v-model="dataMonthReceivedStatisticsInfo.feeStartDate" type="date" | |
| 29 | + :placeholder="$t('dataReport.feeStartDate')" style="width: 100%" /> | |
| 30 | + </el-col> | |
| 31 | + <el-col :span="4"> | |
| 32 | + <el-date-picker v-model="dataMonthReceivedStatisticsInfo.feeEndDate" type="date" | |
| 33 | + :placeholder="$t('dataReport.feeEndDate')" style="width: 100%" /> | |
| 34 | + </el-col> | |
| 35 | + <el-col :span="4"> | |
| 36 | + <el-button type="primary" size="small" @click="_qureyDataMonthReceivedStatistics"> | |
| 37 | + <i class="el-icon-search"></i> | |
| 38 | + {{ $t('dataReport.search') }} | |
| 39 | + </el-button> | |
| 40 | + </el-col> | |
| 41 | + <el-col :span="8" class="text-right"> | |
| 42 | + <el-button type="primary" size="small" @click="_exportReportMonthReceivedFeeExcel"> | |
| 43 | + <i class="el-icon-download"></i> | |
| 44 | + <span>{{ $t('dataReport.export') }}</span> | |
| 45 | + </el-button> | |
| 46 | + </el-col> | |
| 47 | + </el-row> | |
| 48 | + | |
| 49 | + <div class="margin-top"> | |
| 50 | + <el-table :data="dataMonthReceivedStatisticsInfo.fees" border style="width: 100%"> | |
| 51 | + <el-table-column prop="objName" :label="$t('dataReport.room')" align="center" /> | |
| 52 | + <el-table-column :label="$t('dataReport.owner')" align="center"> | |
| 53 | + <template slot-scope="scope"> | |
| 54 | + {{ scope.row.ownerName }}({{ scope.row.link }}) | |
| 55 | + </template> | |
| 56 | + </el-table-column> | |
| 57 | + <el-table-column prop="receivedAmount" :label="$t('dataReport.receivedAmount')" align="center"> | |
| 58 | + <template slot-scope="scope"> | |
| 59 | + {{ scope.row.receivedAmount || 0 }} | |
| 60 | + </template> | |
| 61 | + </el-table-column> | |
| 62 | + <el-table-column prop="feeName" :label="$t('dataReport.feeName')" align="center" /> | |
| 63 | + <el-table-column prop="curYearMonth" :label="$t('dataReport.receivedPeriod')" align="center" /> | |
| 64 | + <el-table-column prop="cashierName" :label="$t('dataReport.cashier')" align="center" /> | |
| 65 | + <el-table-column prop="createTime" :label="$t('dataReport.paymentTime')" align="center" /> | |
| 66 | + </el-table> | |
| 67 | + | |
| 68 | + <el-row class="margin-top"> | |
| 69 | + <el-col :span="8"> | |
| 70 | + <span>{{ $t('dataReport.totalReceived') }}:</span> | |
| 71 | + <span>{{ dataMonthReceivedStatisticsInfo.feeAmount }}</span> | |
| 72 | + </el-col> | |
| 73 | + <el-col :span="16" class="text-right"> | |
| 74 | + <el-pagination :current-page.sync="page.current" :page-sizes="[10, 20, 30, 50]" :page-size="page.size" | |
| 75 | + :total="page.total" layout="total, sizes, prev, pager, next, jumper" @size-change="handleSizeChange" | |
| 76 | + @current-change="handleCurrentChange" /> | |
| 77 | + </el-col> | |
| 78 | + </el-row> | |
| 79 | + </div> | |
| 80 | + </el-col> | |
| 81 | + </el-row> | |
| 82 | + </div> | |
| 83 | +</template> | |
| 84 | + | |
| 85 | +<script> | |
| 86 | +import { getDict } from '@/api/community/communityApi' | |
| 87 | +import { queryMonthReceivedDetail, exportData, queryFloors } from '@/api/report/dataReportApi' | |
| 88 | + | |
| 89 | +export default { | |
| 90 | + name: 'DataMonthReceivedStatistics', | |
| 91 | + | |
| 92 | + data() { | |
| 93 | + return { | |
| 94 | + dataMonthReceivedStatisticsInfo: { | |
| 95 | + fees: [], | |
| 96 | + feeTypeCds: [], | |
| 97 | + floors: [], | |
| 98 | + floorId: '', | |
| 99 | + feeStartDate: '', | |
| 100 | + feeEndDate: '', | |
| 101 | + feeTypeCd: '', | |
| 102 | + feeAmount: '0' | |
| 103 | + }, | |
| 104 | + startDate: '', | |
| 105 | + endDate: '', | |
| 106 | + communityId: '', | |
| 107 | + page: { | |
| 108 | + current: 1, | |
| 109 | + size: 10, | |
| 110 | + total: 0 | |
| 111 | + } | |
| 112 | + } | |
| 113 | + }, | |
| 114 | + created() { | |
| 115 | + this._initMethod() | |
| 116 | + }, | |
| 117 | + methods: { | |
| 118 | + open(param){ | |
| 119 | + this.startDate = param.startDate | |
| 120 | + this.endDate = param.endDate | |
| 121 | + this.communityId = param.communityId | |
| 122 | + this._loadMonthReceivedFloors() | |
| 123 | + }, | |
| 124 | + async _initMethod() { | |
| 125 | + try { | |
| 126 | + const data = await getDict('pay_fee_config', 'fee_type_cd_show') | |
| 127 | + this.dataMonthReceivedStatisticsInfo.feeTypeCds = data | |
| 128 | + this.dataMonthReceivedStatisticsInfo.feeTypeCd = data[0].statusCd | |
| 129 | + this.dataMonthReceivedStatisticsInfo.feeStartDate = this.startDate | |
| 130 | + this.dataMonthReceivedStatisticsInfo.feeEndDate = this.endDate | |
| 131 | + } catch (error) { | |
| 132 | + console.error('Failed to load dictionary:', error) | |
| 133 | + } | |
| 134 | + }, | |
| 135 | + async _loadMonthReceivedFloors() { | |
| 136 | + try { | |
| 137 | + const params = { | |
| 138 | + page: 1, | |
| 139 | + row: 100, | |
| 140 | + communityId: this.communityId | |
| 141 | + } | |
| 142 | + const { apiFloorDataVoList } = await queryFloors(params) | |
| 143 | + this.dataMonthReceivedStatisticsInfo.floors = apiFloorDataVoList | |
| 144 | + } catch (error) { | |
| 145 | + console.error('Failed to load floors:', error) | |
| 146 | + } | |
| 147 | + }, | |
| 148 | + async _loadDataMonthReceivedStatisticsData() { | |
| 149 | + try { | |
| 150 | + const params = { | |
| 151 | + page: this.page.current, | |
| 152 | + row: this.page.size, | |
| 153 | + communityId: this.communityId, | |
| 154 | + feeStartDate: this.dataMonthReceivedStatisticsInfo.feeStartDate, | |
| 155 | + feeEndDate: this.dataMonthReceivedStatisticsInfo.feeEndDate, | |
| 156 | + feeTypeCd: this.dataMonthReceivedStatisticsInfo.feeTypeCd, | |
| 157 | + floorId: this.dataMonthReceivedStatisticsInfo.floorId | |
| 158 | + } | |
| 159 | + const { data, records, sumTotal } = await queryMonthReceivedDetail(params) | |
| 160 | + this.dataMonthReceivedStatisticsInfo.fees = data | |
| 161 | + this.page.total = records | |
| 162 | + this.dataMonthReceivedStatisticsInfo.feeAmount = sumTotal | |
| 163 | + } catch (error) { | |
| 164 | + console.error('Failed to load data:', error) | |
| 165 | + } | |
| 166 | + }, | |
| 167 | + async _exportReportMonthReceivedFeeExcel() { | |
| 168 | + try { | |
| 169 | + const params = { | |
| 170 | + communityId: this.communityId, | |
| 171 | + feeStartDate: this.dataMonthReceivedStatisticsInfo.feeStartDate, | |
| 172 | + feeEndDate: this.dataMonthReceivedStatisticsInfo.feeEndDate, | |
| 173 | + feeTypeCd: this.dataMonthReceivedStatisticsInfo.feeTypeCd, | |
| 174 | + floorId: this.dataMonthReceivedStatisticsInfo.floorId, | |
| 175 | + pagePath: 'dataMonthReceivedStatistics' | |
| 176 | + } | |
| 177 | + const res = await exportData(params) | |
| 178 | + this.$message.success(res.msg) | |
| 179 | + if (res.code === 0) { | |
| 180 | + this.$router.push('/pages/property/downloadTempFile?tab=下载中心') | |
| 181 | + } | |
| 182 | + } catch (error) { | |
| 183 | + console.error('Export failed:', error) | |
| 184 | + } | |
| 185 | + }, | |
| 186 | + _qureyDataMonthReceivedStatistics() { | |
| 187 | + this.page.current = 1 | |
| 188 | + this._loadDataMonthReceivedStatisticsData() | |
| 189 | + }, | |
| 190 | + switchMonthReceivedStatisticsFeeTypeCd(_feeTypeCd) { | |
| 191 | + this.dataMonthReceivedStatisticsInfo.feeTypeCd = _feeTypeCd | |
| 192 | + this._loadDataMonthReceivedStatisticsData() | |
| 193 | + }, | |
| 194 | + handleSizeChange(val) { | |
| 195 | + this.page.size = val | |
| 196 | + this._loadDataMonthReceivedStatisticsData() | |
| 197 | + }, | |
| 198 | + handleCurrentChange(val) { | |
| 199 | + this.page.current = val | |
| 200 | + this._loadDataMonthReceivedStatisticsData() | |
| 201 | + } | |
| 202 | + } | |
| 203 | +} | |
| 204 | +</script> | |
| 205 | + | |
| 206 | +<style scoped> | |
| 207 | +.margin-top { | |
| 208 | + margin-top: 20px; | |
| 209 | +} | |
| 210 | + | |
| 211 | +.text-right { | |
| 212 | + text-align: right; | |
| 213 | +} | |
| 214 | + | |
| 215 | +.padding-r-0 { | |
| 216 | + padding-right: 0; | |
| 217 | +} | |
| 218 | + | |
| 219 | +.border-radius { | |
| 220 | + border-radius: 4px; | |
| 221 | +} | |
| 222 | + | |
| 223 | +.list-group { | |
| 224 | + list-style: none; | |
| 225 | + padding: 0; | |
| 226 | + margin: 0; | |
| 227 | +} | |
| 228 | + | |
| 229 | +.list-group-item { | |
| 230 | + padding: 10px; | |
| 231 | + cursor: pointer; | |
| 232 | + border-bottom: 1px solid #eee; | |
| 233 | +} | |
| 234 | + | |
| 235 | +.list-group-item:hover { | |
| 236 | + background-color: #f5f5f5; | |
| 237 | +} | |
| 238 | + | |
| 239 | +.vc-node-selected { | |
| 240 | + background-color: #409EFF; | |
| 241 | + color: white; | |
| 242 | +} | |
| 243 | + | |
| 244 | +.treeview { | |
| 245 | + overflow-y: auto; | |
| 246 | +} | |
| 247 | +</style> | |
| 0 | 248 | \ No newline at end of file | ... | ... |
src/components/report/DataReportEarnedDetailStatistics.vue
0 → 100644
| 1 | +<template> | |
| 2 | + <div class="margin-top"> | |
| 3 | + <el-row class="margin-top-lg"> | |
| 4 | + <el-col :span="4"> | |
| 5 | + <el-input v-model="dataReportEarnedDetailStatisticsInfo.objName" :placeholder="$t('dataReport.roomNumber')" | |
| 6 | + clearable /> | |
| 7 | + </el-col> | |
| 8 | + <el-col :span="4"> | |
| 9 | + <el-input v-model="dataReportEarnedDetailStatisticsInfo.ownerName" :placeholder="$t('dataReport.ownerName')" | |
| 10 | + clearable /> | |
| 11 | + </el-col> | |
| 12 | + <el-col :span="4"> | |
| 13 | + <el-input v-model="dataReportEarnedDetailStatisticsInfo.link" :placeholder="$t('dataReport.phoneNumber')" | |
| 14 | + clearable /> | |
| 15 | + </el-col> | |
| 16 | + <el-col :span="4"> | |
| 17 | + <el-button type="primary" size="small" @click="_qureyDataReportEarnedDetailStatistics"> | |
| 18 | + <i class="el-icon-search"></i> | |
| 19 | + {{ $t('dataReport.search') }} | |
| 20 | + </el-button> | |
| 21 | + </el-col> | |
| 22 | + <el-col :span="8" class="text-right"> | |
| 23 | + <el-button type="primary" size="small" @click="_exportReportEarnedDetailExcel"> | |
| 24 | + <i class="el-icon-download"></i> | |
| 25 | + <span>{{ $t('dataReport.export') }}</span> | |
| 26 | + </el-button> | |
| 27 | + </el-col> | |
| 28 | + </el-row> | |
| 29 | + | |
| 30 | + <div class="margin-top"> | |
| 31 | + <el-table :data="dataReportEarnedDetailStatisticsInfo.fees" border style="width: 100%"> | |
| 32 | + <el-table-column prop="roomName" :label="$t('dataReport.room')" align="center" /> | |
| 33 | + <el-table-column :label="$t('dataReport.owner')" align="center"> | |
| 34 | + <template slot-scope="scope"> | |
| 35 | + {{ scope.row.ownerName }}({{ scope.row.link }}) | |
| 36 | + </template> | |
| 37 | + </el-table-column> | |
| 38 | + <el-table-column :label="$t('dataReport.receivedFee')" align="center"> | |
| 39 | + <template slot-scope="scope"> | |
| 40 | + {{ scope.row.receivedFee || 0 }} | |
| 41 | + </template> | |
| 42 | + </el-table-column> | |
| 43 | + <el-table-column v-for="(item, index) in dataReportEarnedDetailStatisticsInfo.feeTypeCds" :key="index" | |
| 44 | + :label="item.name" align="center"> | |
| 45 | + <template slot-scope="scope"> | |
| 46 | + <div v-if="scope.row['receivedFee' + item.statusCd]"> | |
| 47 | + <div v-for="(feeItem, fIndex) in scope.row['receivedFee' + item.statusCd]" :key="fIndex"> | |
| 48 | + {{ feeItem.feeName }}({{ feeItem.startTime }}~{{ feeItem.endTime }})={{ feeItem.receivedAmount }} | |
| 49 | + </div> | |
| 50 | + </div> | |
| 51 | + <div v-else> | |
| 52 | + 0 | |
| 53 | + </div> | |
| 54 | + </template> | |
| 55 | + </el-table-column> | |
| 56 | + </el-table> | |
| 57 | + | |
| 58 | + <el-row class="margin-top"> | |
| 59 | + <el-col :span="24" class="text-right"> | |
| 60 | + <el-pagination :current-page.sync="page.current" :page-sizes="[10, 20, 30, 50]" :page-size="page.size" | |
| 61 | + layout="total, sizes, prev, pager, next, jumper" @size-change="handleSizeChange" | |
| 62 | + @current-change="handleCurrentChange" /> | |
| 63 | + </el-col> | |
| 64 | + </el-row> | |
| 65 | + </div> | |
| 66 | + </div> | |
| 67 | +</template> | |
| 68 | + | |
| 69 | +<script> | |
| 70 | +import { getDict } from '@/api/community/communityApi' | |
| 71 | +import { queryReceivedDetailStatistics, exportData } from '@/api/report/dataReportApi' | |
| 72 | + | |
| 73 | +export default { | |
| 74 | + name: 'DataReportEarnedDetailStatistics', | |
| 75 | + | |
| 76 | + data() { | |
| 77 | + return { | |
| 78 | + dataReportEarnedDetailStatisticsInfo: { | |
| 79 | + fees: [], | |
| 80 | + feeTypeCds: [], | |
| 81 | + objName: '', | |
| 82 | + ownerName: '', | |
| 83 | + link: '', | |
| 84 | + feeAmount: '0' | |
| 85 | + }, | |
| 86 | + startDate: '', | |
| 87 | + endDate: '', | |
| 88 | + communityId: '', | |
| 89 | + page: { | |
| 90 | + current: 1, | |
| 91 | + size: 10, | |
| 92 | + total: 0 | |
| 93 | + } | |
| 94 | + } | |
| 95 | + }, | |
| 96 | + created() { | |
| 97 | + this._initMethod() | |
| 98 | + }, | |
| 99 | + methods: { | |
| 100 | + open(_param) { | |
| 101 | + this.startDate = _param.startDate | |
| 102 | + this.endDate = _param.endDate | |
| 103 | + this.communityId = _param.communityId | |
| 104 | + this._loadDataReportEarnedDetailStatisticsData(this.page.current, this.page.size) | |
| 105 | + }, | |
| 106 | + async _initMethod() { | |
| 107 | + try { | |
| 108 | + const data = await getDict('pay_fee_config', 'fee_type_cd_show') | |
| 109 | + this.dataReportEarnedDetailStatisticsInfo.feeTypeCds = data | |
| 110 | + } catch (error) { | |
| 111 | + console.error('Failed to load dictionary:', error) | |
| 112 | + } | |
| 113 | + }, | |
| 114 | + async _loadDataReportEarnedDetailStatisticsData(_page, _row) { | |
| 115 | + try { | |
| 116 | + const params = { | |
| 117 | + communityId: this.communityId, | |
| 118 | + startDate: this.startDate, | |
| 119 | + endDate: this.endDate, | |
| 120 | + objName: this.dataReportEarnedDetailStatisticsInfo.objName, | |
| 121 | + ownerName: this.dataReportEarnedDetailStatisticsInfo.ownerName, | |
| 122 | + link: this.dataReportEarnedDetailStatisticsInfo.link, | |
| 123 | + page: _page, | |
| 124 | + row: _row | |
| 125 | + } | |
| 126 | + const { data, records } = await queryReceivedDetailStatistics(params) | |
| 127 | + this.dataReportEarnedDetailStatisticsInfo.fees = data | |
| 128 | + this.page.total = records | |
| 129 | + } catch (error) { | |
| 130 | + console.error('Failed to load data:', error) | |
| 131 | + } | |
| 132 | + }, | |
| 133 | + async _exportReportEarnedDetailExcel() { | |
| 134 | + try { | |
| 135 | + const params = { | |
| 136 | + communityId: this.communityId, | |
| 137 | + startDate: this.startDate, | |
| 138 | + endDate: this.endDate, | |
| 139 | + objName: this.dataReportEarnedDetailStatisticsInfo.objName, | |
| 140 | + ownerName: this.dataReportEarnedDetailStatisticsInfo.ownerName, | |
| 141 | + link: this.dataReportEarnedDetailStatisticsInfo.link, | |
| 142 | + pagePath: 'dataReportEarnedDetailStatistics' | |
| 143 | + } | |
| 144 | + const res = await exportData(params) | |
| 145 | + this.$message.success(res.msg) | |
| 146 | + if (res.code === 0) { | |
| 147 | + this.$router.push('/pages/property/downloadTempFile?tab=下载中心') | |
| 148 | + } | |
| 149 | + } catch (error) { | |
| 150 | + console.error('Export failed:', error) | |
| 151 | + } | |
| 152 | + }, | |
| 153 | + _qureyDataReportEarnedDetailStatistics() { | |
| 154 | + this.page.current = 1 | |
| 155 | + this._loadDataReportEarnedDetailStatisticsData(this.page.current, this.page.size) | |
| 156 | + }, | |
| 157 | + handleSizeChange(val) { | |
| 158 | + this.page.size = val | |
| 159 | + this._loadDataReportEarnedDetailStatisticsData(this.page.current, val) | |
| 160 | + }, | |
| 161 | + handleCurrentChange(val) { | |
| 162 | + this.page.current = val | |
| 163 | + this._loadDataReportEarnedDetailStatisticsData(val, this.page.size) | |
| 164 | + } | |
| 165 | + } | |
| 166 | +} | |
| 167 | +</script> | |
| 168 | + | |
| 169 | +<style scoped> | |
| 170 | +.margin-top { | |
| 171 | + margin-top: 20px; | |
| 172 | +} | |
| 173 | + | |
| 174 | +.margin-top-lg { | |
| 175 | + margin-top: 30px; | |
| 176 | +} | |
| 177 | + | |
| 178 | +.text-right { | |
| 179 | + text-align: right; | |
| 180 | +} | |
| 181 | +</style> | |
| 0 | 182 | \ No newline at end of file | ... | ... |
src/components/report/DataReportEarnedStatistics.vue
0 → 100644
| 1 | +<template> | |
| 2 | + <div class="margin-top"> | |
| 3 | + <div class="text-right"> | |
| 4 | + <el-button type="primary" size="small" @click="_exportReportEarnedExcel"> | |
| 5 | + <i class="el-icon-download"></i> | |
| 6 | + <span>{{ $t('dataReport.export') }}</span> | |
| 7 | + </el-button> | |
| 8 | + </div> | |
| 9 | + <div class="margin-top"> | |
| 10 | + <el-table :data="dataReportEarnedStatisticsInfo.fees" border style="width: 100%"> | |
| 11 | + <el-table-column prop="floorNum" :label="$t('dataReport.building')" align="center" /> | |
| 12 | + <el-table-column prop="roomCount" :label="$t('dataReport.roomCount')" align="center" /> | |
| 13 | + <el-table-column prop="feeRoomCount" :label="$t('dataReport.feeRoomCount')" align="center" /> | |
| 14 | + <el-table-column prop="receivedFee" :label="$t('dataReport.receivedFee')" align="center" /> | |
| 15 | + <el-table-column v-for="(item, index) in dataReportEarnedStatisticsInfo.feeTypeCds" :key="index" | |
| 16 | + :label="item.name" align="center"> | |
| 17 | + <template slot-scope="scope"> | |
| 18 | + {{ scope.row['receivedFee' + item.statusCd] || 0 }} | |
| 19 | + </template> | |
| 20 | + </el-table-column> | |
| 21 | + </el-table> | |
| 22 | + | |
| 23 | + <el-row class="margin-top"> | |
| 24 | + <el-col :span="8"> | |
| 25 | + <span>{{ $t('dataReport.totalReceived') }}:</span> | |
| 26 | + <span>{{ dataReportEarnedStatisticsInfo.feeAmount }}</span> | |
| 27 | + </el-col> | |
| 28 | + <el-col :span="16" class="text-right"> | |
| 29 | + <el-pagination :current-page.sync="page.current" :page-sizes="[10, 20, 30, 50]" :page-size="page.size" | |
| 30 | + layout="total, sizes, prev, pager, next, jumper" @size-change="handleSizeChange" | |
| 31 | + @current-change="handleCurrentChange" /> | |
| 32 | + </el-col> | |
| 33 | + </el-row> | |
| 34 | + </div> | |
| 35 | + </div> | |
| 36 | +</template> | |
| 37 | + | |
| 38 | +<script> | |
| 39 | +import { getDict } from '@/api/community/communityApi' | |
| 40 | +import { queryReceivedStatistics, exportData } from '@/api/report/dataReportApi' | |
| 41 | + | |
| 42 | +export default { | |
| 43 | + name: 'DataReportEarnedStatistics', | |
| 44 | + data() { | |
| 45 | + return { | |
| 46 | + dataReportEarnedStatisticsInfo: { | |
| 47 | + fees: [], | |
| 48 | + feeTypeCds: [], | |
| 49 | + feeAmount: '0' | |
| 50 | + }, | |
| 51 | + startDate: '', | |
| 52 | + endDate: '', | |
| 53 | + communityId: '', | |
| 54 | + page: { | |
| 55 | + current: 1, | |
| 56 | + size: 10, | |
| 57 | + total: 0 | |
| 58 | + } | |
| 59 | + } | |
| 60 | + }, | |
| 61 | + created() { | |
| 62 | + this._initMethod() | |
| 63 | + }, | |
| 64 | + methods: { | |
| 65 | + open(_param) { | |
| 66 | + this.startDate = _param.startDate | |
| 67 | + this.endDate = _param.endDate | |
| 68 | + this.communityId = _param.communityId | |
| 69 | + this._loadDataReportEarnedStatisticsData(this.page.current, this.page.size) | |
| 70 | + }, | |
| 71 | + async _initMethod() { | |
| 72 | + try { | |
| 73 | + const data = await getDict('pay_fee_config', 'fee_type_cd_show') | |
| 74 | + this.dataReportEarnedStatisticsInfo.feeTypeCds = data | |
| 75 | + } catch (error) { | |
| 76 | + console.error('Failed to load dictionary:', error) | |
| 77 | + } | |
| 78 | + }, | |
| 79 | + async _loadDataReportEarnedStatisticsData(_page, _row) { | |
| 80 | + try { | |
| 81 | + const params = { | |
| 82 | + communityId: this.communityId, | |
| 83 | + startDate: this.startDate, | |
| 84 | + endDate: this.endDate, | |
| 85 | + page: _page, | |
| 86 | + row: _row | |
| 87 | + } | |
| 88 | + const { data, records } = await queryReceivedStatistics(params) | |
| 89 | + this.dataReportEarnedStatisticsInfo.fees = data | |
| 90 | + this.page.total = records | |
| 91 | + | |
| 92 | + let _feeAmount = 0.0 | |
| 93 | + if (data && data.length > 0) { | |
| 94 | + data.forEach(item => { | |
| 95 | + _feeAmount += parseFloat(item.receivedFee) | |
| 96 | + }) | |
| 97 | + } | |
| 98 | + this.dataReportEarnedStatisticsInfo.feeAmount = _feeAmount.toFixed(2) | |
| 99 | + } catch (error) { | |
| 100 | + console.error('Failed to load data:', error) | |
| 101 | + } | |
| 102 | + }, | |
| 103 | + async _exportReportEarnedExcel() { | |
| 104 | + try { | |
| 105 | + const params = { | |
| 106 | + communityId: this.communityId, | |
| 107 | + startDate: this.startDate, | |
| 108 | + endDate: this.endDate, | |
| 109 | + pagePath: 'dataReportEarnedStatistics' | |
| 110 | + } | |
| 111 | + const res = await exportData(params) | |
| 112 | + this.$message.success(res.msg) | |
| 113 | + if (res.code === 0) { | |
| 114 | + this.$router.push('/pages/property/downloadTempFile?tab=下载中心') | |
| 115 | + } | |
| 116 | + } catch (error) { | |
| 117 | + console.error('Export failed:', error) | |
| 118 | + } | |
| 119 | + }, | |
| 120 | + handleSizeChange(val) { | |
| 121 | + this.page.size = val | |
| 122 | + this._loadDataReportEarnedStatisticsData(this.page.current, val) | |
| 123 | + }, | |
| 124 | + handleCurrentChange(val) { | |
| 125 | + this.page.current = val | |
| 126 | + this._loadDataReportEarnedStatisticsData(val, this.page.size) | |
| 127 | + } | |
| 128 | + } | |
| 129 | +} | |
| 130 | +</script> | |
| 131 | + | |
| 132 | +<style scoped> | |
| 133 | +.margin-top { | |
| 134 | + margin-top: 20px; | |
| 135 | +} | |
| 136 | + | |
| 137 | +.text-right { | |
| 138 | + text-align: right; | |
| 139 | +} | |
| 140 | +</style> | |
| 0 | 141 | \ No newline at end of file | ... | ... |
src/components/report/DataReportEarnedWayStatistics.vue
0 → 100644
| 1 | +<template> | |
| 2 | + <div class="margin-top"> | |
| 3 | + <div class="text-right"> | |
| 4 | + <el-button type="primary" size="small" @click="_exportReportEarnedWayExcel"> | |
| 5 | + <i class="el-icon-download"></i> | |
| 6 | + <span>{{ $t('dataReport.export') }}</span> | |
| 7 | + </el-button> | |
| 8 | + </div> | |
| 9 | + <div class="margin-top"> | |
| 10 | + <el-table :data="[dataReportEarnedWayStatisticsInfo.fees]" border style="width: 100%"> | |
| 11 | + <el-table-column v-for="(item, index) in dataReportEarnedWayStatisticsInfo.fees" :key="index" :label="item.name" | |
| 12 | + align="center"> | |
| 13 | + <template> | |
| 14 | + {{ item.receivedAmount || 0 }} | |
| 15 | + </template> | |
| 16 | + </el-table-column> | |
| 17 | + </el-table> | |
| 18 | + </div> | |
| 19 | + </div> | |
| 20 | +</template> | |
| 21 | + | |
| 22 | +<script> | |
| 23 | +import { queryReceivedWayStatistics, exportData } from '@/api/report/dataReportApi' | |
| 24 | + | |
| 25 | +export default { | |
| 26 | + name: 'DataReportEarnedWayStatistics', | |
| 27 | + | |
| 28 | + data() { | |
| 29 | + return { | |
| 30 | + dataReportEarnedWayStatisticsInfo: { | |
| 31 | + fees: [] | |
| 32 | + }, | |
| 33 | + startDate: '', | |
| 34 | + endDate: '', | |
| 35 | + communityId: '' | |
| 36 | + } | |
| 37 | + }, | |
| 38 | + created() { | |
| 39 | + }, | |
| 40 | + methods: { | |
| 41 | + open(_param) { | |
| 42 | + this.startDate = _param.startDate | |
| 43 | + this.endDate = _param.endDate | |
| 44 | + this.communityId = _param.communityId | |
| 45 | + this._loadDataReportEarnedWayStatisticsData() | |
| 46 | + }, | |
| 47 | + async _loadDataReportEarnedWayStatisticsData() { | |
| 48 | + try { | |
| 49 | + const params = { | |
| 50 | + communityId: this.communityId, | |
| 51 | + startDate: this.startDate, | |
| 52 | + endDate: this.endDate | |
| 53 | + } | |
| 54 | + const { data } = await queryReceivedWayStatistics(params) | |
| 55 | + this.dataReportEarnedWayStatisticsInfo.fees = data | |
| 56 | + } catch (error) { | |
| 57 | + console.error('Failed to load data:', error) | |
| 58 | + } | |
| 59 | + }, | |
| 60 | + async _exportReportEarnedWayExcel() { | |
| 61 | + try { | |
| 62 | + const params = { | |
| 63 | + communityId: this.communityId, | |
| 64 | + startDate: this.startDate, | |
| 65 | + endDate: this.endDate, | |
| 66 | + pagePath: 'dataReportEarnedWayStatistics' | |
| 67 | + } | |
| 68 | + const res = await exportData(params) | |
| 69 | + this.$message.success(res.msg) | |
| 70 | + if (res.code === 0) { | |
| 71 | + this.$router.push('/pages/property/downloadTempFile?tab=下载中心') | |
| 72 | + } | |
| 73 | + } catch (error) { | |
| 74 | + console.error('Export failed:', error) | |
| 75 | + } | |
| 76 | + } | |
| 77 | + } | |
| 78 | +} | |
| 79 | +</script> | |
| 80 | + | |
| 81 | +<style scoped> | |
| 82 | +.margin-top { | |
| 83 | + margin-top: 20px; | |
| 84 | +} | |
| 85 | + | |
| 86 | +.text-right { | |
| 87 | + text-align: right; | |
| 88 | +} | |
| 89 | +</style> | |
| 0 | 90 | \ No newline at end of file | ... | ... |
src/components/report/DataReportFeeStatistics.vue
0 → 100644
| 1 | +<template> | |
| 2 | + <div class="margin-top"> | |
| 3 | + <el-row> | |
| 4 | + <el-col :span="3" class="padding-r-0"> | |
| 5 | + <el-card class="border-radius"> | |
| 6 | + <div class="treeview attendance-staff" style="height: 650px;"> | |
| 7 | + <ul class="list-group text-center border-radius"> | |
| 8 | + <li v-for="(item, index) in dataReportFeeStatisticsInfo.feeTypeCds" :key="index" | |
| 9 | + class="list-group-item node-orgTree" | |
| 10 | + :class="{ 'vc-node-selected': dataReportFeeStatisticsInfo.feeTypeCd === item.statusCd }" | |
| 11 | + @click="swatchFeeStatisticsFeeTypeCd(item.statusCd)"> | |
| 12 | + {{ item.name }} | |
| 13 | + </li> | |
| 14 | + </ul> | |
| 15 | + </div> | |
| 16 | + </el-card> | |
| 17 | + </el-col> | |
| 18 | + <el-col :span="21"> | |
| 19 | + <el-row> | |
| 20 | + <el-col :span="24" class="text-right"> | |
| 21 | + <el-button type="primary" size="small" @click="_exportReportFeeExcel"> | |
| 22 | + <i class="el-icon-download"></i> | |
| 23 | + <span>{{ $t('dataReport.export') }}</span> | |
| 24 | + </el-button> | |
| 25 | + </el-col> | |
| 26 | + </el-row> | |
| 27 | + <div class="margin-top"> | |
| 28 | + <el-table :data="dataReportFeeStatisticsInfo.fees" border style="width: 100%"> | |
| 29 | + <el-table-column prop="floorNum" :label="$t('dataReport.building')" align="center" /> | |
| 30 | + <el-table-column prop="roomCount" :label="$t('dataReport.roomCount')" align="center" /> | |
| 31 | + <el-table-column prop="feeRoomCount" :label="$t('dataReport.feeRoomCount')" align="center" /> | |
| 32 | + <el-table-column prop="hisMonthOweFee" :label="$t('dataReport.historyOwe')" align="center" /> | |
| 33 | + <el-table-column prop="oweFee" :label="$t('dataReport.totalOwe')" align="center" /> | |
| 34 | + <el-table-column prop="todayReceivedRoomCount" :label="$t('dataReport.todayPaidCount')" align="center" /> | |
| 35 | + <el-table-column prop="todayReceivedRoomAmount" :label="$t('dataReport.todayPaidAmount')" align="center" /> | |
| 36 | + <el-table-column prop="hisOweReceivedRoomCount" :label="$t('dataReport.historyPaidCount')" align="center" /> | |
| 37 | + <el-table-column prop="hisOweReceivedRoomAmount" :label="$t('dataReport.historyPaidAmount')" align="center" /> | |
| 38 | + <el-table-column prop="monthReceivedRoomCount" :label="$t('dataReport.monthPaidCount')" align="center" /> | |
| 39 | + <el-table-column :label="$t('dataReport.remainingCount')" align="center"> | |
| 40 | + <template slot-scope="scope"> | |
| 41 | + {{ (scope.row.feeRoomCount - scope.row.monthReceivedRoomCount).toFixed(0) }} | |
| 42 | + </template> | |
| 43 | + </el-table-column> | |
| 44 | + <el-table-column :label="$t('dataReport.paidRatio')" align="center"> | |
| 45 | + <template slot-scope="scope"> | |
| 46 | + {{ scope.row.feeRoomCount > 0 ? | |
| 47 | + ((scope.row.monthReceivedRoomCount) / (scope.row.feeRoomCount) * 100).toFixed(2) + '%' : '0%' }} | |
| 48 | + </template> | |
| 49 | + </el-table-column> | |
| 50 | + <el-table-column prop="monthReceivedRoomAmount" :label="$t('dataReport.monthPaidAmount')" align="center" /> | |
| 51 | + <el-table-column prop="curMonthOweFee" :label="$t('dataReport.monthRemaining')" align="center" /> | |
| 52 | + <el-table-column :label="$t('dataReport.collectionRate')" align="center"> | |
| 53 | + <template slot-scope="scope"> | |
| 54 | + {{ scope.row.curReceivableFee > 0 ? | |
| 55 | + ((scope.row.monthReceivedRoomAmount) / (scope.row.curReceivableFee) * 100).toFixed(2) + '%' : '0%' }} | |
| 56 | + </template> | |
| 57 | + </el-table-column> | |
| 58 | + </el-table> | |
| 59 | + </div> | |
| 60 | + </el-col> | |
| 61 | + </el-row> | |
| 62 | + </div> | |
| 63 | +</template> | |
| 64 | + | |
| 65 | +<script> | |
| 66 | +import { getDict } from '@/api/community/communityApi' | |
| 67 | +import { queryDataReportFeeStatistics, exportData, queryFloors } from '@/api/report/dataReportApi' | |
| 68 | + | |
| 69 | +export default { | |
| 70 | + name: 'DataReportFeeStatistics', | |
| 71 | + | |
| 72 | + data() { | |
| 73 | + return { | |
| 74 | + dataReportFeeStatisticsInfo: { | |
| 75 | + fees: [], | |
| 76 | + feeTypeCds: [], | |
| 77 | + floors: [], | |
| 78 | + feeTypeCd: '' | |
| 79 | + }, | |
| 80 | + startDate: '', | |
| 81 | + endDate: '', | |
| 82 | + communityId: '', | |
| 83 | + } | |
| 84 | + }, | |
| 85 | + created() { | |
| 86 | + }, | |
| 87 | + methods: { | |
| 88 | + open(param){ | |
| 89 | + this.startDate = param.startDate | |
| 90 | + this.endDate = param.endDate | |
| 91 | + this.communityId = param.communityId | |
| 92 | + this._initMethod() | |
| 93 | + }, | |
| 94 | + async _initMethod() { | |
| 95 | + try { | |
| 96 | + const data = await getDict('pay_fee_config', 'fee_type_cd_show') | |
| 97 | + this.dataReportFeeStatisticsInfo.feeTypeCds = data | |
| 98 | + this.dataReportFeeStatisticsInfo.feeTypeCd = data[0].statusCd | |
| 99 | + this._loadFloors() | |
| 100 | + } catch (error) { | |
| 101 | + console.error('Failed to load dictionary:', error) | |
| 102 | + } | |
| 103 | + }, | |
| 104 | + async _loadFloors() { | |
| 105 | + try { | |
| 106 | + const params = { | |
| 107 | + page: 1, | |
| 108 | + row: 100, | |
| 109 | + communityId: this.communityId | |
| 110 | + } | |
| 111 | + const { apiFloorDataVoList } = await queryFloors(params) | |
| 112 | + this.dataReportFeeStatisticsInfo.floors = apiFloorDataVoList | |
| 113 | + this.dataReportFeeStatisticsInfo.fees = [] | |
| 114 | + | |
| 115 | + const _floorIds = [] | |
| 116 | + for (let i = 0; i < apiFloorDataVoList.length; i++) { | |
| 117 | + _floorIds.push(apiFloorDataVoList[i].floorId) | |
| 118 | + if (_floorIds.length >= 5) { | |
| 119 | + await this._loadDataReportFeeStatisticsData(_floorIds.join(',')) | |
| 120 | + _floorIds.length = 0 | |
| 121 | + } | |
| 122 | + } | |
| 123 | + | |
| 124 | + if (_floorIds.length > 0) { | |
| 125 | + await this._loadDataReportFeeStatisticsData(_floorIds.join(',')) | |
| 126 | + } | |
| 127 | + } catch (error) { | |
| 128 | + console.error('Failed to load floors:', error) | |
| 129 | + } | |
| 130 | + }, | |
| 131 | + async _loadDataReportFeeStatisticsData(_floorIds) { | |
| 132 | + try { | |
| 133 | + const params = { | |
| 134 | + communityId: this.communityId, | |
| 135 | + startDate: this.startDate, | |
| 136 | + endDate: this.endDate, | |
| 137 | + feeTypeCd: this.dataReportFeeStatisticsInfo.feeTypeCd, | |
| 138 | + floorIds: _floorIds | |
| 139 | + } | |
| 140 | + const { data } = await queryDataReportFeeStatistics(params) | |
| 141 | + data.forEach(item => { | |
| 142 | + this.dataReportFeeStatisticsInfo.fees.push(item) | |
| 143 | + }) | |
| 144 | + } catch (error) { | |
| 145 | + console.error('Failed to load data:', error) | |
| 146 | + } | |
| 147 | + }, | |
| 148 | + async _exportReportFeeExcel() { | |
| 149 | + try { | |
| 150 | + const _floorIds = this.dataReportFeeStatisticsInfo.floors.map(item => item.floorId) | |
| 151 | + if (!_floorIds || _floorIds.length < 1) { | |
| 152 | + this.$message.warning(this.$t('dataReport.noExportData')) | |
| 153 | + return | |
| 154 | + } | |
| 155 | + | |
| 156 | + const params = { | |
| 157 | + communityId: this.communityId, | |
| 158 | + startDate: this.startDate, | |
| 159 | + endDate: this.endDate, | |
| 160 | + feeTypeCd: this.dataReportFeeStatisticsInfo.feeTypeCd, | |
| 161 | + floorIds: _floorIds.join(','), | |
| 162 | + pagePath: 'dataReportFeeStatistics' | |
| 163 | + } | |
| 164 | + const res = await exportData(params) | |
| 165 | + this.$message.success(res.msg) | |
| 166 | + if (res.code === 0) { | |
| 167 | + this.$router.push('/pages/property/downloadTempFile?tab=下载中心') | |
| 168 | + } | |
| 169 | + } catch (error) { | |
| 170 | + console.error('Export failed:', error) | |
| 171 | + } | |
| 172 | + }, | |
| 173 | + swatchFeeStatisticsFeeTypeCd(_feeTypeCd) { | |
| 174 | + this.dataReportFeeStatisticsInfo.feeTypeCd = _feeTypeCd | |
| 175 | + this._loadFloors() | |
| 176 | + } | |
| 177 | + } | |
| 178 | +} | |
| 179 | +</script> | |
| 180 | + | |
| 181 | +<style scoped> | |
| 182 | +.margin-top { | |
| 183 | + margin-top: 20px; | |
| 184 | +} | |
| 185 | + | |
| 186 | +.text-right { | |
| 187 | + text-align: right; | |
| 188 | +} | |
| 189 | + | |
| 190 | +.padding-r-0 { | |
| 191 | + padding-right: 0; | |
| 192 | +} | |
| 193 | + | |
| 194 | +.border-radius { | |
| 195 | + border-radius: 4px; | |
| 196 | +} | |
| 197 | + | |
| 198 | +.list-group { | |
| 199 | + list-style: none; | |
| 200 | + padding: 0; | |
| 201 | + margin: 0; | |
| 202 | +} | |
| 203 | + | |
| 204 | +.list-group-item { | |
| 205 | + padding: 10px; | |
| 206 | + cursor: pointer; | |
| 207 | + border-bottom: 1px solid #eee; | |
| 208 | +} | |
| 209 | + | |
| 210 | +.list-group-item:hover { | |
| 211 | + background-color: #f5f5f5; | |
| 212 | +} | |
| 213 | + | |
| 214 | +.vc-node-selected { | |
| 215 | + background-color: #409EFF; | |
| 216 | + color: white; | |
| 217 | +} | |
| 218 | + | |
| 219 | +.treeview { | |
| 220 | + overflow-y: auto; | |
| 221 | +}</style> | |
| 0 | 222 | \ No newline at end of file | ... | ... |
src/components/report/DataReportOweDetailStatistics.vue
0 → 100644
| 1 | +<template> | |
| 2 | + <div class="margin-top"> | |
| 3 | + <el-row class="margin-top-lg"> | |
| 4 | + <el-col :span="4"> | |
| 5 | + <el-input v-model="dataReportOweDetailStatisticsInfo.objName" :placeholder="$t('dataReport.roomNumber')" | |
| 6 | + clearable /> | |
| 7 | + </el-col> | |
| 8 | + <el-col :span="4"> | |
| 9 | + <el-input v-model="dataReportOweDetailStatisticsInfo.ownerName" :placeholder="$t('dataReport.ownerName')" | |
| 10 | + clearable /> | |
| 11 | + </el-col> | |
| 12 | + <el-col :span="4"> | |
| 13 | + <el-input v-model="dataReportOweDetailStatisticsInfo.link" :placeholder="$t('dataReport.phoneNumber')" | |
| 14 | + clearable /> | |
| 15 | + </el-col> | |
| 16 | + <el-col :span="4"> | |
| 17 | + <el-button type="primary" size="small" @click="_qureyDataReportOweDetailStatistics"> | |
| 18 | + <i class="el-icon-search"></i> | |
| 19 | + {{ $t('dataReport.search') }} | |
| 20 | + </el-button> | |
| 21 | + <el-button type="default" size="small" @click="_resetDataReportOweDetailStatistics"> | |
| 22 | + <i class="el-icon-refresh"></i> | |
| 23 | + {{ $t('dataReport.reset') }} | |
| 24 | + </el-button> | |
| 25 | + </el-col> | |
| 26 | + <el-col :span="8" class="text-right"> | |
| 27 | + <el-button type="primary" size="small" @click="_exportReportOweDetailExcel"> | |
| 28 | + <i class="el-icon-download"></i> | |
| 29 | + <span>{{ $t('dataReport.export') }}</span> | |
| 30 | + </el-button> | |
| 31 | + </el-col> | |
| 32 | + </el-row> | |
| 33 | + | |
| 34 | + <div class="margin-top"> | |
| 35 | + <el-table :data="dataReportOweDetailStatisticsInfo.fees" border style="width: 100%"> | |
| 36 | + <el-table-column prop="roomName" :label="$t('dataReport.room')" align="center" /> | |
| 37 | + <el-table-column prop="ownerName" :label="$t('dataReport.owner')" align="center" /> | |
| 38 | + <el-table-column prop="oweFee" :label="$t('dataReport.oweFee')" align="center" /> | |
| 39 | + <el-table-column v-for="(item, index) in dataReportOweDetailStatisticsInfo.feeTypeCds" :key="index" | |
| 40 | + :label="item.name" align="center"> | |
| 41 | + <template slot-scope="scope"> | |
| 42 | + <div v-if="scope.row['oweFee' + item.statusCd]"> | |
| 43 | + <div v-for="(feeItem, fIndex) in scope.row['oweFee' + item.statusCd]" :key="fIndex"> | |
| 44 | + {{ feeItem.feeName }}({{ feeItem.endTime }}~{{ feeItem.deadlineTime }})={{ feeItem.amountOwed }} | |
| 45 | + </div> | |
| 46 | + </div> | |
| 47 | + <div v-else> | |
| 48 | + 0 | |
| 49 | + </div> | |
| 50 | + </template> | |
| 51 | + </el-table-column> | |
| 52 | + </el-table> | |
| 53 | + | |
| 54 | + <el-row class="margin-top"> | |
| 55 | + <el-col :span="24" class="text-right"> | |
| 56 | + <el-pagination :current-page.sync="page.current" :page-sizes="[10, 20, 30, 50]" :page-size="page.size" | |
| 57 | + layout="total, sizes, prev, pager, next, jumper" @size-change="handleSizeChange" | |
| 58 | + @current-change="handleCurrentChange" /> | |
| 59 | + </el-col> | |
| 60 | + </el-row> | |
| 61 | + </div> | |
| 62 | + </div> | |
| 63 | +</template> | |
| 64 | + | |
| 65 | +<script> | |
| 66 | +import { getDict } from '@/api/community/communityApi' | |
| 67 | +import { queryOweDetailStatistics, exportData } from '@/api/report/dataReportApi' | |
| 68 | + | |
| 69 | +export default { | |
| 70 | + name: 'DataReportOweDetailStatistics', | |
| 71 | + | |
| 72 | + data() { | |
| 73 | + return { | |
| 74 | + dataReportOweDetailStatisticsInfo: { | |
| 75 | + fees: [], | |
| 76 | + feeTypeCds: [], | |
| 77 | + objName: '', | |
| 78 | + ownerName: '', | |
| 79 | + link: '', | |
| 80 | + feeAmount: '0' | |
| 81 | + }, | |
| 82 | + startDate: '', | |
| 83 | + endDate: '', | |
| 84 | + communityId: '', | |
| 85 | + page: { | |
| 86 | + current: 1, | |
| 87 | + size: 10, | |
| 88 | + total: 0 | |
| 89 | + } | |
| 90 | + } | |
| 91 | + }, | |
| 92 | + created() { | |
| 93 | + this._initMethod() | |
| 94 | + }, | |
| 95 | + methods: { | |
| 96 | + open(param){ | |
| 97 | + this.startDate = param.startDate | |
| 98 | + this.endDate = param.endDate | |
| 99 | + this.communityId = param.communityId | |
| 100 | + this._loadDataReportOweDetailStatisticsData(this.page.current, this.page.size) | |
| 101 | + }, | |
| 102 | + async _initMethod() { | |
| 103 | + try { | |
| 104 | + const data = await getDict('pay_fee_config', 'fee_type_cd_show') | |
| 105 | + this.dataReportOweDetailStatisticsInfo.feeTypeCds = data | |
| 106 | + } catch (error) { | |
| 107 | + console.error('Failed to load dictionary:', error) | |
| 108 | + } | |
| 109 | + }, | |
| 110 | + async _loadDataReportOweDetailStatisticsData(_page, _row) { | |
| 111 | + try { | |
| 112 | + const params = { | |
| 113 | + communityId: this.communityId, | |
| 114 | + startDate: this.startDate, | |
| 115 | + endDate: this.endDate, | |
| 116 | + objName: this.dataReportOweDetailStatisticsInfo.objName, | |
| 117 | + ownerName: this.dataReportOweDetailStatisticsInfo.ownerName, | |
| 118 | + link: this.dataReportOweDetailStatisticsInfo.link, | |
| 119 | + page: _page, | |
| 120 | + row: _row | |
| 121 | + } | |
| 122 | + const { data, records } = await queryOweDetailStatistics(params) | |
| 123 | + this.dataReportOweDetailStatisticsInfo.fees = data | |
| 124 | + this.page.total = records | |
| 125 | + | |
| 126 | + let _feeAmount = 0.0 | |
| 127 | + if (data && data.length > 0) { | |
| 128 | + data.forEach(item => { | |
| 129 | + _feeAmount += parseFloat(item.oweFee) | |
| 130 | + }) | |
| 131 | + } | |
| 132 | + this.dataReportOweDetailStatisticsInfo.feeAmount = _feeAmount.toFixed(2) | |
| 133 | + } catch (error) { | |
| 134 | + console.error('Failed to load data:', error) | |
| 135 | + } | |
| 136 | + }, | |
| 137 | + async _exportReportOweDetailExcel() { | |
| 138 | + try { | |
| 139 | + const params = { | |
| 140 | + communityId: this.communityId, | |
| 141 | + startDate: this.startDate, | |
| 142 | + endDate: this.endDate, | |
| 143 | + objName: this.dataReportOweDetailStatisticsInfo.objName, | |
| 144 | + ownerName: this.dataReportOweDetailStatisticsInfo.ownerName, | |
| 145 | + link: this.dataReportOweDetailStatisticsInfo.link, | |
| 146 | + pagePath: 'dataReportOweDetailStatistics' | |
| 147 | + } | |
| 148 | + const res = await exportData(params) | |
| 149 | + this.$message.success(res.msg) | |
| 150 | + if (res.code === 0) { | |
| 151 | + this.$router.push('/pages/property/downloadTempFile?tab=下载中心') | |
| 152 | + } | |
| 153 | + } catch (error) { | |
| 154 | + console.error('Export failed:', error) | |
| 155 | + } | |
| 156 | + }, | |
| 157 | + _qureyDataReportOweDetailStatistics() { | |
| 158 | + this.page.current = 1 | |
| 159 | + this._loadDataReportOweDetailStatisticsData(this.page.current, this.page.size) | |
| 160 | + }, | |
| 161 | + _resetDataReportOweDetailStatistics() { | |
| 162 | + this.dataReportOweDetailStatisticsInfo.objName = '' | |
| 163 | + this.dataReportOweDetailStatisticsInfo.ownerName = '' | |
| 164 | + this.dataReportOweDetailStatisticsInfo.link = '' | |
| 165 | + this._qureyDataReportOweDetailStatistics() | |
| 166 | + }, | |
| 167 | + handleSizeChange(val) { | |
| 168 | + this.page.size = val | |
| 169 | + this._loadDataReportOweDetailStatisticsData(this.page.current, val) | |
| 170 | + }, | |
| 171 | + handleCurrentChange(val) { | |
| 172 | + this.page.current = val | |
| 173 | + this._loadDataReportOweDetailStatisticsData(val, this.page.size) | |
| 174 | + } | |
| 175 | + } | |
| 176 | +} | |
| 177 | +</script> | |
| 178 | + | |
| 179 | +<style scoped> | |
| 180 | +.margin-top { | |
| 181 | + margin-top: 20px; | |
| 182 | +} | |
| 183 | + | |
| 184 | +.margin-top-lg { | |
| 185 | + margin-top: 30px; | |
| 186 | +} | |
| 187 | + | |
| 188 | +.text-right { | |
| 189 | + text-align: right; | |
| 190 | +} | |
| 191 | +</style> | |
| 0 | 192 | \ No newline at end of file | ... | ... |
src/components/report/DataReportOweStatistics.vue
0 → 100644
| 1 | +<template> | |
| 2 | + <div class="margin-top"> | |
| 3 | + <div class="text-right"> | |
| 4 | + <el-button type="primary" size="small" @click="_exportReportOweExcel"> | |
| 5 | + <i class="el-icon-download"></i> | |
| 6 | + <span>{{ $t('dataReport.export') }}</span> | |
| 7 | + </el-button> | |
| 8 | + </div> | |
| 9 | + <div class="margin-top"> | |
| 10 | + <el-table :data="dataReportOweStatisticsInfo.fees" border style="width: 100%"> | |
| 11 | + <el-table-column prop="floorNum" :label="$t('dataReport.building')" align="center" /> | |
| 12 | + <el-table-column prop="oweFee" :label="$t('dataReport.oweFee')" align="center" /> | |
| 13 | + <el-table-column v-for="(item, index) in dataReportOweStatisticsInfo.feeTypeCds" :key="index" :label="item.name" | |
| 14 | + align="center"> | |
| 15 | + <template slot-scope="scope"> | |
| 16 | + {{ scope.row['oweFee' + item.statusCd] || 0 }} | |
| 17 | + </template> | |
| 18 | + </el-table-column> | |
| 19 | + </el-table> | |
| 20 | + | |
| 21 | + <el-row class="margin-top"> | |
| 22 | + <el-col :span="8"> | |
| 23 | + <span>{{ $t('dataReport.totalOwe') }}:</span> | |
| 24 | + <span>{{ dataReportOweStatisticsInfo.feeAmount }}</span> | |
| 25 | + </el-col> | |
| 26 | + <el-col :span="16" class="text-right"> | |
| 27 | + <el-pagination :current-page.sync="page.current" :page-sizes="[10, 20, 30, 50]" :page-size="page.size" | |
| 28 | + layout="total, sizes, prev, pager, next, jumper" @size-change="handleSizeChange" | |
| 29 | + @current-change="handleCurrentChange" /> | |
| 30 | + </el-col> | |
| 31 | + </el-row> | |
| 32 | + </div> | |
| 33 | + </div> | |
| 34 | +</template> | |
| 35 | + | |
| 36 | +<script> | |
| 37 | +import { getDict } from '@/api/community/communityApi' | |
| 38 | +import { queryOweStatistics, exportData } from '@/api/report/dataReportApi' | |
| 39 | + | |
| 40 | +export default { | |
| 41 | + name: 'DataReportOweStatistics', | |
| 42 | + | |
| 43 | + data() { | |
| 44 | + return { | |
| 45 | + dataReportOweStatisticsInfo: { | |
| 46 | + fees: [], | |
| 47 | + feeTypeCds: [], | |
| 48 | + feeAmount: '0' | |
| 49 | + }, | |
| 50 | + startDate: '', | |
| 51 | + endDate: '', | |
| 52 | + communityId: '', | |
| 53 | + page: { | |
| 54 | + current: 1, | |
| 55 | + size: 10, | |
| 56 | + total: 0 | |
| 57 | + } | |
| 58 | + } | |
| 59 | + }, | |
| 60 | + created() { | |
| 61 | + this._initMethod() | |
| 62 | + }, | |
| 63 | + methods: { | |
| 64 | + open(param){ | |
| 65 | + this.startDate = param.startDate | |
| 66 | + this.endDate = param.endDate | |
| 67 | + this.communityId = param.communityId | |
| 68 | + this._loadDataReportOweStatisticsData(this.page.current, this.page.size) | |
| 69 | + }, | |
| 70 | + async _initMethod() { | |
| 71 | + try { | |
| 72 | + const data = await getDict('pay_fee_config', 'fee_type_cd_show') | |
| 73 | + this.dataReportOweStatisticsInfo.feeTypeCds = data | |
| 74 | + } catch (error) { | |
| 75 | + console.error('Failed to load dictionary:', error) | |
| 76 | + } | |
| 77 | + }, | |
| 78 | + async _loadDataReportOweStatisticsData(_page, _row) { | |
| 79 | + try { | |
| 80 | + const params = { | |
| 81 | + communityId: this.communityId, | |
| 82 | + startDate: this.startDate, | |
| 83 | + endDate: this.endDate, | |
| 84 | + page: _page, | |
| 85 | + row: _row | |
| 86 | + } | |
| 87 | + const { data, records } = await queryOweStatistics(params) | |
| 88 | + this.dataReportOweStatisticsInfo.fees = data | |
| 89 | + this.page.total = records | |
| 90 | + | |
| 91 | + let _feeAmount = 0.0 | |
| 92 | + if (data && data.length > 0) { | |
| 93 | + data.forEach(item => { | |
| 94 | + _feeAmount += parseFloat(item.oweFee) | |
| 95 | + }) | |
| 96 | + } | |
| 97 | + this.dataReportOweStatisticsInfo.feeAmount = _feeAmount.toFixed(2) | |
| 98 | + } catch (error) { | |
| 99 | + console.error('Failed to load data:', error) | |
| 100 | + } | |
| 101 | + }, | |
| 102 | + async _exportReportOweExcel() { | |
| 103 | + try { | |
| 104 | + const params = { | |
| 105 | + communityId: this.communityId, | |
| 106 | + startDate: this.startDate, | |
| 107 | + endDate: this.endDate, | |
| 108 | + pagePath: 'dataReportOweStatistics' | |
| 109 | + } | |
| 110 | + const res = await exportData(params) | |
| 111 | + this.$message.success(res.msg) | |
| 112 | + if (res.code === 0) { | |
| 113 | + this.$router.push('/pages/property/downloadTempFile?tab=下载中心') | |
| 114 | + } | |
| 115 | + } catch (error) { | |
| 116 | + console.error('Export failed:', error) | |
| 117 | + } | |
| 118 | + }, | |
| 119 | + handleSizeChange(val) { | |
| 120 | + this.page.size = val | |
| 121 | + this._loadDataReportOweStatisticsData(this.page.current, val) | |
| 122 | + }, | |
| 123 | + handleCurrentChange(val) { | |
| 124 | + this.page.current = val | |
| 125 | + this._loadDataReportOweStatisticsData(val, this.page.size) | |
| 126 | + } | |
| 127 | + } | |
| 128 | +} | |
| 129 | +</script> | |
| 130 | + | |
| 131 | +<style scoped> | |
| 132 | +.margin-top { | |
| 133 | + margin-top: 20px; | |
| 134 | +} | |
| 135 | + | |
| 136 | +.text-right { | |
| 137 | + text-align: right; | |
| 138 | +} | |
| 139 | +</style> | |
| 0 | 140 | \ No newline at end of file | ... | ... |
src/components/report/configFeeSummary.vue
0 → 100644
| 1 | +<template> | |
| 2 | + <el-card class="config-fee-summary-container"> | |
| 3 | + <div slot="header"> | |
| 4 | + <span>{{ $t('reportFeeSummary.configFeeSummary') }}</span> | |
| 5 | + </div> | |
| 6 | + <div id="configFeeSummary" style="height:300px;width:100%;"></div> | |
| 7 | + </el-card> | |
| 8 | +</template> | |
| 9 | + | |
| 10 | +<script> | |
| 11 | +import * as echarts from 'echarts' | |
| 12 | +import { queryReportConfigFeeSummary } from '@/api/report/reportFeeSummaryApi' | |
| 13 | + | |
| 14 | +export default { | |
| 15 | + name: 'ConfigFeeSummary', | |
| 16 | + data() { | |
| 17 | + return { | |
| 18 | + chart: null, | |
| 19 | + conditions: {} | |
| 20 | + } | |
| 21 | + }, | |
| 22 | + mounted() { | |
| 23 | + this.initChart() | |
| 24 | + window.addEventListener('resize', this.handleResize) | |
| 25 | + }, | |
| 26 | + beforeDestroy() { | |
| 27 | + window.removeEventListener('resize', this.handleResize) | |
| 28 | + if (this.chart) { | |
| 29 | + this.chart.dispose() | |
| 30 | + } | |
| 31 | + }, | |
| 32 | + methods: { | |
| 33 | + notify(params) { | |
| 34 | + this.conditions = params | |
| 35 | + this.loadConfigFeeSummaryRate() | |
| 36 | + }, | |
| 37 | + initChart() { | |
| 38 | + this.chart = echarts.init(document.getElementById('configFeeSummary')) | |
| 39 | + this.setDefaultOption() | |
| 40 | + }, | |
| 41 | + setDefaultOption() { | |
| 42 | + const option = { | |
| 43 | + legend: {}, | |
| 44 | + tooltip: {}, | |
| 45 | + title: { | |
| 46 | + show: true, | |
| 47 | + text: this.$t('reportFeeSummary.configFeeRateStatistics') | |
| 48 | + }, | |
| 49 | + color: ['#FFDAB9', '#66CDAA'], | |
| 50 | + dataset: { | |
| 51 | + source: [ | |
| 52 | + ['product', this.$t('reportFeeSummary.roomChargeRate'), this.$t('reportFeeSummary.chargeRate')] | |
| 53 | + ] | |
| 54 | + }, | |
| 55 | + xAxis: { type: 'category' }, | |
| 56 | + yAxis: {}, | |
| 57 | + series: [ | |
| 58 | + { type: 'bar' }, | |
| 59 | + { type: 'bar' } | |
| 60 | + ] | |
| 61 | + } | |
| 62 | + this.chart.setOption(option) | |
| 63 | + }, | |
| 64 | + async loadConfigFeeSummaryRate() { | |
| 65 | + try { | |
| 66 | + const { data } = await queryReportConfigFeeSummary(this.conditions ) | |
| 67 | + this.initConfigFeeSummaryChart(data) | |
| 68 | + } catch (error) { | |
| 69 | + console.error('Failed to load config fee summary:', error) | |
| 70 | + } | |
| 71 | + }, | |
| 72 | + initConfigFeeSummaryChart(data) { | |
| 73 | + if (!this.chart) { | |
| 74 | + this.initChart() | |
| 75 | + } | |
| 76 | + | |
| 77 | + const source = [ | |
| 78 | + ['product', this.$t('reportFeeSummary.roomChargeRate'), this.$t('reportFeeSummary.chargeRate')] | |
| 79 | + ] | |
| 80 | + | |
| 81 | + data.forEach(item => { | |
| 82 | + source.push([ | |
| 83 | + item.name, | |
| 84 | + item.feeRoomRate, | |
| 85 | + item.feeRate | |
| 86 | + ]) | |
| 87 | + }) | |
| 88 | + | |
| 89 | + this.chart.setOption({ | |
| 90 | + dataset: { | |
| 91 | + source | |
| 92 | + } | |
| 93 | + }) | |
| 94 | + }, | |
| 95 | + handleResize() { | |
| 96 | + if (this.chart) { | |
| 97 | + this.chart.resize() | |
| 98 | + } | |
| 99 | + } | |
| 100 | + } | |
| 101 | +} | |
| 102 | +</script> | |
| 103 | + | |
| 104 | +<style lang="scss" scoped> | |
| 105 | +.config-fee-summary-container { | |
| 106 | + margin-bottom: 20px; | |
| 107 | +} | |
| 108 | +</style> | |
| 0 | 109 | \ No newline at end of file | ... | ... |
src/components/report/floorFeeSummary.vue
0 → 100644
| 1 | +<template> | |
| 2 | + <el-card class="floor-fee-summary-container"> | |
| 3 | + <div slot="header"> | |
| 4 | + <span>{{ $t('reportFeeSummary.floorFeeSummary') }}</span> | |
| 5 | + </div> | |
| 6 | + <div id="floorFeeSummary" style="height:300px;width:100%;"></div> | |
| 7 | + </el-card> | |
| 8 | +</template> | |
| 9 | + | |
| 10 | +<script> | |
| 11 | +import * as echarts from 'echarts' | |
| 12 | +import { queryReportFloorFeeSummary } from '@/api/report/reportFeeSummaryApi' | |
| 13 | + | |
| 14 | +export default { | |
| 15 | + name: 'FloorFeeSummary', | |
| 16 | + data() { | |
| 17 | + return { | |
| 18 | + chart: null, | |
| 19 | + conditions: {} | |
| 20 | + } | |
| 21 | + }, | |
| 22 | + mounted() { | |
| 23 | + this.initChart() | |
| 24 | + window.addEventListener('resize', this.handleResize) | |
| 25 | + }, | |
| 26 | + beforeDestroy() { | |
| 27 | + window.removeEventListener('resize', this.handleResize) | |
| 28 | + if (this.chart) { | |
| 29 | + this.chart.dispose() | |
| 30 | + } | |
| 31 | + }, | |
| 32 | + methods: { | |
| 33 | + notify(params) { | |
| 34 | + this.conditions = params | |
| 35 | + this.loadFloorFeeSummaryRate() | |
| 36 | + }, | |
| 37 | + initChart() { | |
| 38 | + this.chart = echarts.init(document.getElementById('floorFeeSummary')) | |
| 39 | + this.setDefaultOption() | |
| 40 | + }, | |
| 41 | + setDefaultOption() { | |
| 42 | + const option = { | |
| 43 | + legend: {}, | |
| 44 | + tooltip: {}, | |
| 45 | + title: { | |
| 46 | + show: true, | |
| 47 | + text: this.$t('reportFeeSummary.floorFeeRateStatistics') | |
| 48 | + }, | |
| 49 | + color: ['#FFDAB9', '#66CDAA'], | |
| 50 | + dataset: { | |
| 51 | + source: [ | |
| 52 | + ['product', this.$t('reportFeeSummary.roomChargeRate'), this.$t('reportFeeSummary.chargeRate')] | |
| 53 | + ] | |
| 54 | + }, | |
| 55 | + xAxis: { type: 'category' }, | |
| 56 | + yAxis: {}, | |
| 57 | + series: [ | |
| 58 | + { type: 'bar' }, | |
| 59 | + { type: 'bar' } | |
| 60 | + ] | |
| 61 | + } | |
| 62 | + this.chart.setOption(option) | |
| 63 | + }, | |
| 64 | + async loadFloorFeeSummaryRate() { | |
| 65 | + try { | |
| 66 | + const { data } = await queryReportFloorFeeSummary( this.conditions ) | |
| 67 | + this.initFloorFeeSummaryChart(data) | |
| 68 | + } catch (error) { | |
| 69 | + console.error('Failed to load floor fee summary:', error) | |
| 70 | + } | |
| 71 | + }, | |
| 72 | + initFloorFeeSummaryChart(data) { | |
| 73 | + if (!this.chart) { | |
| 74 | + this.initChart() | |
| 75 | + } | |
| 76 | + | |
| 77 | + const source = [ | |
| 78 | + ['product', this.$t('reportFeeSummary.roomChargeRate'), this.$t('reportFeeSummary.chargeRate')] | |
| 79 | + ] | |
| 80 | + | |
| 81 | + data.forEach(item => { | |
| 82 | + source.push([ | |
| 83 | + item.floorName, | |
| 84 | + item.feeRoomRate, | |
| 85 | + item.feeRate | |
| 86 | + ]) | |
| 87 | + }) | |
| 88 | + | |
| 89 | + this.chart.setOption({ | |
| 90 | + dataset: { | |
| 91 | + source | |
| 92 | + } | |
| 93 | + }) | |
| 94 | + }, | |
| 95 | + handleResize() { | |
| 96 | + if (this.chart) { | |
| 97 | + this.chart.resize() | |
| 98 | + } | |
| 99 | + } | |
| 100 | + } | |
| 101 | +} | |
| 102 | +</script> | |
| 103 | + | |
| 104 | +<style lang="scss" scoped> | |
| 105 | +.floor-fee-summary-container { | |
| 106 | + margin-bottom: 20px; | |
| 107 | +} | |
| 108 | +</style> | |
| 0 | 109 | \ No newline at end of file | ... | ... |
src/components/report/reportDeadlineFee.vue
0 → 100644
| 1 | +<template> | |
| 2 | + <div class="report-deadline-fee"> | |
| 3 | + <div class="text-right"> | |
| 4 | + <el-button | |
| 5 | + type="primary" | |
| 6 | + size="small" | |
| 7 | + @click="_exportExcel" | |
| 8 | + > | |
| 9 | + <i class="el-icon-download"></i> | |
| 10 | + {{ $t('reportDeadlineFee.export') }} | |
| 11 | + </el-button> | |
| 12 | + </div> | |
| 13 | + | |
| 14 | + <el-table | |
| 15 | + :data="reportDeadlineFeeInfo.fees" | |
| 16 | + border | |
| 17 | + style="width: 100%" | |
| 18 | + class="margin-top" | |
| 19 | + > | |
| 20 | + <el-table-column | |
| 21 | + prop="index" | |
| 22 | + :label="$t('reportDeadlineFee.feeId')" | |
| 23 | + align="center" | |
| 24 | + > | |
| 25 | + <template slot-scope="scope"> | |
| 26 | + {{ scope.$index + 1 }} | |
| 27 | + </template> | |
| 28 | + </el-table-column> | |
| 29 | + <el-table-column | |
| 30 | + prop="objName" | |
| 31 | + :label="$t('reportDeadlineFee.objName')" | |
| 32 | + align="center" | |
| 33 | + /> | |
| 34 | + <el-table-column | |
| 35 | + prop="feeName" | |
| 36 | + :label="$t('reportDeadlineFee.feeName')" | |
| 37 | + align="center" | |
| 38 | + /> | |
| 39 | + <el-table-column | |
| 40 | + prop="deadlineTime" | |
| 41 | + :label="$t('reportDeadlineFee.deadlineTime')" | |
| 42 | + align="center" | |
| 43 | + /> | |
| 44 | + <el-table-column | |
| 45 | + prop="oweDay" | |
| 46 | + :label="$t('reportDeadlineFee.oweDay')" | |
| 47 | + align="center" | |
| 48 | + /> | |
| 49 | + </el-table> | |
| 50 | + | |
| 51 | + <el-row class="margin-top"> | |
| 52 | + <el-col :span="18"> | |
| 53 | + <div class="tip-text"> | |
| 54 | + {{ $t('reportDeadlineFee.tip') }} | |
| 55 | + </div> | |
| 56 | + </el-col> | |
| 57 | + <el-col :span="6" class="text-right"> | |
| 58 | + <el-pagination | |
| 59 | + :current-page.sync="pagination.current" | |
| 60 | + :page-sizes="[10, 20, 30, 50]" | |
| 61 | + :page-size="pagination.size" | |
| 62 | + :total="pagination.total" | |
| 63 | + layout="total, sizes, prev, pager, next, jumper" | |
| 64 | + @size-change="handleSizeChange" | |
| 65 | + @current-change="handleCurrentChange" | |
| 66 | + /> | |
| 67 | + </el-col> | |
| 68 | + </el-row> | |
| 69 | + </div> | |
| 70 | +</template> | |
| 71 | + | |
| 72 | +<script> | |
| 73 | +import { getCommunityId } from '@/api/community/communityApi' | |
| 74 | +import { queryDeadlineFee, exportData } from '@/api/report/feeRemindApi' | |
| 75 | + | |
| 76 | +export default { | |
| 77 | + name: 'ReportDeadlineFee', | |
| 78 | + data() { | |
| 79 | + return { | |
| 80 | + reportDeadlineFeeInfo: { | |
| 81 | + fees: [], | |
| 82 | + conditions: {} | |
| 83 | + }, | |
| 84 | + pagination: { | |
| 85 | + current: 1, | |
| 86 | + size: 10, | |
| 87 | + total: 0 | |
| 88 | + } | |
| 89 | + } | |
| 90 | + }, | |
| 91 | + methods: { | |
| 92 | + async loadData(conditions) { | |
| 93 | + this.reportDeadlineFeeInfo.conditions = { ...conditions } | |
| 94 | + await this._listDeadlineFees(this.pagination.current, this.pagination.size) | |
| 95 | + }, | |
| 96 | + async _listDeadlineFees(page, size) { | |
| 97 | + try { | |
| 98 | + const params = { | |
| 99 | + ...this.reportDeadlineFeeInfo.conditions, | |
| 100 | + page, | |
| 101 | + row: size | |
| 102 | + } | |
| 103 | + const { data, total } = await queryDeadlineFee(params) | |
| 104 | + this.reportDeadlineFeeInfo.fees = data | |
| 105 | + this.pagination.total = total | |
| 106 | + } catch (error) { | |
| 107 | + console.error('Failed to load deadline fees:', error) | |
| 108 | + } | |
| 109 | + }, | |
| 110 | + async _exportExcel() { | |
| 111 | + try { | |
| 112 | + const params = { | |
| 113 | + ...this.reportDeadlineFeeInfo.conditions, | |
| 114 | + communityId: getCommunityId(), | |
| 115 | + pagePath: 'reportDeadlineFee' | |
| 116 | + } | |
| 117 | + const { code, msg } = await exportData(params) | |
| 118 | + this.$message.success(msg) | |
| 119 | + if (code === 0) { | |
| 120 | + this.$router.push('/pages/property/downloadTempFile?tab=downloadCenter') | |
| 121 | + } | |
| 122 | + } catch (error) { | |
| 123 | + console.error('Failed to export:', error) | |
| 124 | + } | |
| 125 | + }, | |
| 126 | + handleSizeChange(val) { | |
| 127 | + this.pagination.size = val | |
| 128 | + this._listDeadlineFees(this.pagination.current, val) | |
| 129 | + }, | |
| 130 | + handleCurrentChange(val) { | |
| 131 | + this.pagination.current = val | |
| 132 | + this._listDeadlineFees(val, this.pagination.size) | |
| 133 | + } | |
| 134 | + } | |
| 135 | +} | |
| 136 | +</script> | |
| 137 | + | |
| 138 | +<style lang="scss" scoped> | |
| 139 | +.report-deadline-fee { | |
| 140 | + .margin-top { | |
| 141 | + margin-top: 15px; | |
| 142 | + } | |
| 143 | + | |
| 144 | + .text-right { | |
| 145 | + text-align: right; | |
| 146 | + } | |
| 147 | + | |
| 148 | + .tip-text { | |
| 149 | + color: #999; | |
| 150 | + font-size: 12px; | |
| 151 | + padding: 5px 0; | |
| 152 | + } | |
| 153 | +} | |
| 154 | +</style> | |
| 0 | 155 | \ No newline at end of file | ... | ... |
src/components/report/reportFeeDetailCar.vue
0 → 100644
| 1 | +<template> | |
| 2 | + <div class="report-fee-detail-car"> | |
| 3 | + <div class="operation-bar"> | |
| 4 | + <el-button | |
| 5 | + type="primary" | |
| 6 | + size="small" | |
| 7 | + @click="exportReportFeeDetailCarExcel"> | |
| 8 | + <i class="el-icon-download"></i> | |
| 9 | + {{ $t('common.export') }} | |
| 10 | + </el-button> | |
| 11 | + </div> | |
| 12 | + | |
| 13 | + <el-table | |
| 14 | + :data="reportFeeDetailCarInfo.fees" | |
| 15 | + border | |
| 16 | + style="width: 100%" | |
| 17 | + v-loading="loading"> | |
| 18 | + <el-table-column | |
| 19 | + prop="carNum" | |
| 20 | + :label="$t('reportFeeDetailCar.car')" | |
| 21 | + align="center"> | |
| 22 | + </el-table-column> | |
| 23 | + <el-table-column | |
| 24 | + prop="ownerName" | |
| 25 | + :label="$t('reportFeeDetailCar.owner')" | |
| 26 | + align="center"> | |
| 27 | + <template slot-scope="scope"> | |
| 28 | + {{ scope.row.ownerName }}({{ scope.row.link }}) | |
| 29 | + </template> | |
| 30 | + </el-table-column> | |
| 31 | + <el-table-column | |
| 32 | + prop="oweFee" | |
| 33 | + :label="$t('reportFeeDetailCar.oweFee')" | |
| 34 | + align="center"> | |
| 35 | + <template slot-scope="scope"> | |
| 36 | + {{ scope.row.oweFee || '0' }} | |
| 37 | + </template> | |
| 38 | + </el-table-column> | |
| 39 | + <el-table-column | |
| 40 | + prop="receivedFee" | |
| 41 | + :label="$t('reportFeeDetailCar.receivedFee')" | |
| 42 | + align="center"> | |
| 43 | + <template slot-scope="scope"> | |
| 44 | + {{ scope.row.receivedFee || '0' }} | |
| 45 | + </template> | |
| 46 | + </el-table-column> | |
| 47 | + <template v-for="(item,index) in reportFeeDetailCarInfo.feeTypeCds"> | |
| 48 | + <el-table-column | |
| 49 | + :key="index+'owe'" | |
| 50 | + :label="item.name + $t('reportFeeDetailCar.owe')" | |
| 51 | + align="center"> | |
| 52 | + <template slot-scope="scope"> | |
| 53 | + {{ scope.row['oweFee'+item.statusCd] || '0' }} | |
| 54 | + </template> | |
| 55 | + </el-table-column> | |
| 56 | + <el-table-column | |
| 57 | + :key="index+'received'" | |
| 58 | + :label="item.name + $t('reportFeeDetailCar.received')" | |
| 59 | + align="center"> | |
| 60 | + <template slot-scope="scope"> | |
| 61 | + {{ scope.row['receivedFee'+item.statusCd] || '0' }} | |
| 62 | + </template> | |
| 63 | + </el-table-column> | |
| 64 | + </template> | |
| 65 | + </el-table> | |
| 66 | + | |
| 67 | + <el-pagination | |
| 68 | + @size-change="handleSizeChange" | |
| 69 | + @current-change="handleCurrentChange" | |
| 70 | + :current-page="pagination.current" | |
| 71 | + :page-sizes="[10, 20, 30, 50]" | |
| 72 | + :page-size="pagination.size" | |
| 73 | + layout="total, sizes, prev, pager, next, jumper" | |
| 74 | + :total="pagination.total"> | |
| 75 | + </el-pagination> | |
| 76 | + </div> | |
| 77 | +</template> | |
| 78 | + | |
| 79 | +<script> | |
| 80 | +import { getDict } from '@/api/community/communityApi' | |
| 81 | +import { queryReportFeeDetailCar, exportReportFeeDetailCar } from '@/api/report/reportFeeDetailApi' | |
| 82 | + | |
| 83 | +export default { | |
| 84 | + name: 'ReportFeeDetailCar', | |
| 85 | + data() { | |
| 86 | + return { | |
| 87 | + reportFeeDetailCarInfo: { | |
| 88 | + fees: [], | |
| 89 | + feeTypeCds: [], | |
| 90 | + conditions: {} | |
| 91 | + }, | |
| 92 | + loading: false, | |
| 93 | + pagination: { | |
| 94 | + current: 1, | |
| 95 | + size: 10, | |
| 96 | + total: 0 | |
| 97 | + } | |
| 98 | + } | |
| 99 | + }, | |
| 100 | + created() { | |
| 101 | + this.getDictData() | |
| 102 | + }, | |
| 103 | + methods: { | |
| 104 | + async getDictData() { | |
| 105 | + try { | |
| 106 | + const data = await getDict('pay_fee_config', 'fee_type_cd_show') | |
| 107 | + this.reportFeeDetailCarInfo.feeTypeCds = data | |
| 108 | + } catch (error) { | |
| 109 | + console.error('获取字典数据失败:', error) | |
| 110 | + } | |
| 111 | + }, | |
| 112 | + async open(conditions) { | |
| 113 | + this.reportFeeDetailCarInfo.conditions = conditions | |
| 114 | + this.listReportFeeDetailCars() | |
| 115 | + }, | |
| 116 | + async listReportFeeDetailCars() { | |
| 117 | + try { | |
| 118 | + this.loading = true | |
| 119 | + const params = { | |
| 120 | + ...this.reportFeeDetailCarInfo.conditions, | |
| 121 | + page: this.pagination.current, | |
| 122 | + row: this.pagination.size | |
| 123 | + } | |
| 124 | + const { data, total } = await queryReportFeeDetailCar(params) | |
| 125 | + this.reportFeeDetailCarInfo.fees = data | |
| 126 | + this.pagination.total = total | |
| 127 | + } catch (error) { | |
| 128 | + console.error('获取车辆费用明细失败:', error) | |
| 129 | + } finally { | |
| 130 | + this.loading = false | |
| 131 | + } | |
| 132 | + }, | |
| 133 | + async exportReportFeeDetailCarExcel() { | |
| 134 | + try { | |
| 135 | + const params = { | |
| 136 | + ...this.reportFeeDetailCarInfo.conditions, | |
| 137 | + pagePath: 'reportFeeDetailCar' | |
| 138 | + } | |
| 139 | + await exportReportFeeDetailCar(params) | |
| 140 | + this.$message.success(this.$t('common.exportSuccess')) | |
| 141 | + } catch (error) { | |
| 142 | + console.error('导出失败:', error) | |
| 143 | + this.$message.error(this.$t('common.exportFailed')) | |
| 144 | + } | |
| 145 | + }, | |
| 146 | + handleSizeChange(val) { | |
| 147 | + this.pagination.size = val | |
| 148 | + this.listReportFeeDetailCars() | |
| 149 | + }, | |
| 150 | + handleCurrentChange(val) { | |
| 151 | + this.pagination.current = val | |
| 152 | + this.listReportFeeDetailCars() | |
| 153 | + } | |
| 154 | + } | |
| 155 | +} | |
| 156 | +</script> | |
| 157 | + | |
| 158 | +<style lang="scss" scoped> | |
| 159 | +.report-fee-detail-car { | |
| 160 | + .operation-bar { | |
| 161 | + margin-bottom: 20px; | |
| 162 | + text-align: right; | |
| 163 | + } | |
| 164 | + | |
| 165 | + .el-pagination { | |
| 166 | + margin-top: 20px; | |
| 167 | + text-align: right; | |
| 168 | + } | |
| 169 | +} | |
| 170 | +</style> | |
| 0 | 171 | \ No newline at end of file | ... | ... |
src/components/report/reportFeeDetailContract.vue
0 → 100644
| 1 | +<template> | |
| 2 | + <div class="report-fee-detail-contract"> | |
| 3 | + <div class="operation-bar"> | |
| 4 | + <el-button | |
| 5 | + type="primary" | |
| 6 | + size="small" | |
| 7 | + @click="exportReportFeeDetailContractExcel"> | |
| 8 | + <i class="el-icon-download"></i> | |
| 9 | + {{ $t('common.export') }} | |
| 10 | + </el-button> | |
| 11 | + </div> | |
| 12 | + | |
| 13 | + <el-table | |
| 14 | + :data="reportFeeDetailContractInfo.fees" | |
| 15 | + border | |
| 16 | + style="width: 100%" | |
| 17 | + v-loading="loading"> | |
| 18 | + <el-table-column | |
| 19 | + prop="contractName" | |
| 20 | + :label="$t('reportFeeDetailContract.contract')" | |
| 21 | + align="center"> | |
| 22 | + </el-table-column> | |
| 23 | + <el-table-column | |
| 24 | + prop="ownerName" | |
| 25 | + :label="$t('reportFeeDetailContract.owner')" | |
| 26 | + align="center"> | |
| 27 | + <template slot-scope="scope"> | |
| 28 | + {{ scope.row.ownerName }}({{ scope.row.link }}) | |
| 29 | + </template> | |
| 30 | + </el-table-column> | |
| 31 | + <el-table-column | |
| 32 | + prop="oweFee" | |
| 33 | + :label="$t('reportFeeDetailContract.oweFee')" | |
| 34 | + align="center"> | |
| 35 | + <template slot-scope="scope"> | |
| 36 | + {{ scope.row.oweFee || '0' }} | |
| 37 | + </template> | |
| 38 | + </el-table-column> | |
| 39 | + <el-table-column | |
| 40 | + prop="receivedFee" | |
| 41 | + :label="$t('reportFeeDetailContract.receivedFee')" | |
| 42 | + align="center"> | |
| 43 | + <template slot-scope="scope"> | |
| 44 | + {{ scope.row.receivedFee || '0' }} | |
| 45 | + </template> | |
| 46 | + </el-table-column> | |
| 47 | + <template v-for="(item,index) in reportFeeDetailContractInfo.feeTypeCds"> | |
| 48 | + <el-table-column | |
| 49 | + :key="index+'owe'" | |
| 50 | + :label="item.name + $t('reportFeeDetailContract.owe')" | |
| 51 | + align="center"> | |
| 52 | + <template slot-scope="scope"> | |
| 53 | + {{ scope.row['oweFee'+item.statusCd] || '0' }} | |
| 54 | + </template> | |
| 55 | + </el-table-column> | |
| 56 | + <el-table-column | |
| 57 | + :key="index+'received'" | |
| 58 | + :label="item.name + $t('reportFeeDetailContract.received')" | |
| 59 | + align="center"> | |
| 60 | + <template slot-scope="scope"> | |
| 61 | + {{ scope.row['receivedFee'+item.statusCd] || '0' }} | |
| 62 | + </template> | |
| 63 | + </el-table-column> | |
| 64 | + </template> | |
| 65 | + </el-table> | |
| 66 | + | |
| 67 | + <el-pagination | |
| 68 | + @size-change="handleSizeChange" | |
| 69 | + @current-change="handleCurrentChange" | |
| 70 | + :current-page="pagination.current" | |
| 71 | + :page-sizes="[10, 20, 30, 50]" | |
| 72 | + :page-size="pagination.size" | |
| 73 | + layout="total, sizes, prev, pager, next, jumper" | |
| 74 | + :total="pagination.total"> | |
| 75 | + </el-pagination> | |
| 76 | + </div> | |
| 77 | +</template> | |
| 78 | + | |
| 79 | +<script> | |
| 80 | +import { getDict } from '@/api/community/communityApi' | |
| 81 | +import { queryReportFeeDetailContract, exportReportFeeDetailContract } from '@/api/report/reportFeeDetailApi' | |
| 82 | + | |
| 83 | +export default { | |
| 84 | + name: 'ReportFeeDetailContract', | |
| 85 | + data() { | |
| 86 | + return { | |
| 87 | + reportFeeDetailContractInfo: { | |
| 88 | + fees: [], | |
| 89 | + feeTypeCds: [], | |
| 90 | + conditions: {} | |
| 91 | + }, | |
| 92 | + loading: false, | |
| 93 | + pagination: { | |
| 94 | + current: 1, | |
| 95 | + size: 10, | |
| 96 | + total: 0 | |
| 97 | + } | |
| 98 | + } | |
| 99 | + }, | |
| 100 | + created() { | |
| 101 | + this.getDictData() | |
| 102 | + }, | |
| 103 | + methods: { | |
| 104 | + async getDictData() { | |
| 105 | + try { | |
| 106 | + const data = await getDict('pay_fee_config', 'fee_type_cd_show') | |
| 107 | + this.reportFeeDetailContractInfo.feeTypeCds = data | |
| 108 | + } catch (error) { | |
| 109 | + console.error('获取字典数据失败:', error) | |
| 110 | + } | |
| 111 | + }, | |
| 112 | + async open(conditions) { | |
| 113 | + this.reportFeeDetailContractInfo.conditions = conditions | |
| 114 | + this.listReportFeeDetailContracts() | |
| 115 | + }, | |
| 116 | + async listReportFeeDetailContracts() { | |
| 117 | + try { | |
| 118 | + this.loading = true | |
| 119 | + const params = { | |
| 120 | + ...this.reportFeeDetailContractInfo.conditions, | |
| 121 | + page: this.pagination.current, | |
| 122 | + row: this.pagination.size | |
| 123 | + } | |
| 124 | + const { data, total } = await queryReportFeeDetailContract(params) | |
| 125 | + this.reportFeeDetailContractInfo.fees = data | |
| 126 | + this.pagination.total = total | |
| 127 | + } catch (error) { | |
| 128 | + console.error('获取合同费用明细失败:', error) | |
| 129 | + } finally { | |
| 130 | + this.loading = false | |
| 131 | + } | |
| 132 | + }, | |
| 133 | + async exportReportFeeDetailContractExcel() { | |
| 134 | + try { | |
| 135 | + const params = { | |
| 136 | + ...this.reportFeeDetailContractInfo.conditions, | |
| 137 | + pagePath: 'reportFeeDetailContract' | |
| 138 | + } | |
| 139 | + await exportReportFeeDetailContract(params) | |
| 140 | + this.$message.success(this.$t('common.exportSuccess')) | |
| 141 | + } catch (error) { | |
| 142 | + console.error('导出失败:', error) | |
| 143 | + this.$message.error(this.$t('common.exportFailed')) | |
| 144 | + } | |
| 145 | + }, | |
| 146 | + handleSizeChange(val) { | |
| 147 | + this.pagination.size = val | |
| 148 | + this.listReportFeeDetailContracts() | |
| 149 | + }, | |
| 150 | + handleCurrentChange(val) { | |
| 151 | + this.pagination.current = val | |
| 152 | + this.listReportFeeDetailContracts() | |
| 153 | + } | |
| 154 | + } | |
| 155 | +} | |
| 156 | +</script> | |
| 157 | + | |
| 158 | +<style lang="scss" scoped> | |
| 159 | +.report-fee-detail-contract { | |
| 160 | + .operation-bar { | |
| 161 | + margin-bottom: 20px; | |
| 162 | + text-align: right; | |
| 163 | + } | |
| 164 | + | |
| 165 | + .el-pagination { | |
| 166 | + margin-top: 20px; | |
| 167 | + text-align: right; | |
| 168 | + } | |
| 169 | +} | |
| 170 | +</style> | |
| 0 | 171 | \ No newline at end of file | ... | ... |
src/components/report/reportFeeDetailOwner.vue
0 → 100644
| 1 | +<template> | |
| 2 | + <div class="report-fee-detail-owner"> | |
| 3 | + <div class="operation-bar"> | |
| 4 | + <el-button | |
| 5 | + type="primary" | |
| 6 | + size="small" | |
| 7 | + @click="exportReportFeeDetailOwnerExcel"> | |
| 8 | + <i class="el-icon-download"></i> | |
| 9 | + {{ $t('common.export') }} | |
| 10 | + </el-button> | |
| 11 | + </div> | |
| 12 | + | |
| 13 | + <el-table | |
| 14 | + :data="reportFeeDetailOwnerInfo.fees" | |
| 15 | + border | |
| 16 | + style="width: 100%" | |
| 17 | + v-loading="loading"> | |
| 18 | + <el-table-column | |
| 19 | + prop="ownerName" | |
| 20 | + :label="$t('reportFeeDetailOwner.owner')" | |
| 21 | + align="center"> | |
| 22 | + <template slot-scope="scope"> | |
| 23 | + {{ scope.row.ownerName }}({{ scope.row.link }}) | |
| 24 | + </template> | |
| 25 | + </el-table-column> | |
| 26 | + <el-table-column | |
| 27 | + prop="objName" | |
| 28 | + :label="$t('reportFeeDetailOwner.room')" | |
| 29 | + align="center"> | |
| 30 | + <template slot-scope="scope"> | |
| 31 | + <div style="max-width: 200px;">{{ scope.row.objName }}</div> | |
| 32 | + </template> | |
| 33 | + </el-table-column> | |
| 34 | + <el-table-column | |
| 35 | + prop="oweFee" | |
| 36 | + :label="$t('reportFeeDetailOwner.oweFee')" | |
| 37 | + align="center"> | |
| 38 | + <template slot-scope="scope"> | |
| 39 | + {{ scope.row.oweFee || '0' }} | |
| 40 | + </template> | |
| 41 | + </el-table-column> | |
| 42 | + <el-table-column | |
| 43 | + prop="receivedFee" | |
| 44 | + :label="$t('reportFeeDetailOwner.receivedFee')" | |
| 45 | + align="center"> | |
| 46 | + <template slot-scope="scope"> | |
| 47 | + {{ scope.row.receivedFee || '0' }} | |
| 48 | + </template> | |
| 49 | + </el-table-column> | |
| 50 | + <template v-for="(item,index) in reportFeeDetailOwnerInfo.feeTypeCds"> | |
| 51 | + <el-table-column | |
| 52 | + :key="index+'owe'" | |
| 53 | + :label="item.name + $t('reportFeeDetailOwner.owe')" | |
| 54 | + align="center"> | |
| 55 | + <template slot-scope="scope"> | |
| 56 | + {{ scope.row['oweFee'+item.statusCd] || '0' }} | |
| 57 | + </template> | |
| 58 | + </el-table-column> | |
| 59 | + <el-table-column | |
| 60 | + :key="index+'received'" | |
| 61 | + :label="item.name + $t('reportFeeDetailOwner.received')" | |
| 62 | + align="center"> | |
| 63 | + <template slot-scope="scope"> | |
| 64 | + {{ scope.row['receivedFee'+item.statusCd] || '0' }} | |
| 65 | + </template> | |
| 66 | + </el-table-column> | |
| 67 | + </template> | |
| 68 | + </el-table> | |
| 69 | + | |
| 70 | + <el-pagination | |
| 71 | + @size-change="handleSizeChange" | |
| 72 | + @current-change="handleCurrentChange" | |
| 73 | + :current-page="pagination.current" | |
| 74 | + :page-sizes="[10, 20, 30, 50]" | |
| 75 | + :page-size="pagination.size" | |
| 76 | + layout="total, sizes, prev, pager, next, jumper" | |
| 77 | + :total="pagination.total"> | |
| 78 | + </el-pagination> | |
| 79 | + </div> | |
| 80 | +</template> | |
| 81 | + | |
| 82 | +<script> | |
| 83 | +import { getDict } from '@/api/community/communityApi' | |
| 84 | +import { queryReportFeeDetailOwner, exportReportFeeDetailOwner } from '@/api/report/reportFeeDetailApi' | |
| 85 | + | |
| 86 | +export default { | |
| 87 | + name: 'ReportFeeDetailOwner', | |
| 88 | + data() { | |
| 89 | + return { | |
| 90 | + reportFeeDetailOwnerInfo: { | |
| 91 | + fees: [], | |
| 92 | + feeTypeCds: [], | |
| 93 | + conditions: {} | |
| 94 | + }, | |
| 95 | + loading: false, | |
| 96 | + pagination: { | |
| 97 | + current: 1, | |
| 98 | + size: 10, | |
| 99 | + total: 0 | |
| 100 | + } | |
| 101 | + } | |
| 102 | + }, | |
| 103 | + created() { | |
| 104 | + this.getDictData() | |
| 105 | + }, | |
| 106 | + methods: { | |
| 107 | + async getDictData() { | |
| 108 | + try { | |
| 109 | + const data = await getDict('pay_fee_config', 'fee_type_cd_show') | |
| 110 | + this.reportFeeDetailOwnerInfo.feeTypeCds = data | |
| 111 | + } catch (error) { | |
| 112 | + console.error('获取字典数据失败:', error) | |
| 113 | + } | |
| 114 | + }, | |
| 115 | + async open(conditions) { | |
| 116 | + this.reportFeeDetailOwnerInfo.conditions = conditions | |
| 117 | + this.listReportFeeDetailOwners() | |
| 118 | + }, | |
| 119 | + async listReportFeeDetailOwners() { | |
| 120 | + try { | |
| 121 | + this.loading = true | |
| 122 | + const params = { | |
| 123 | + ...this.reportFeeDetailOwnerInfo.conditions, | |
| 124 | + page: this.pagination.current, | |
| 125 | + row: this.pagination.size | |
| 126 | + } | |
| 127 | + const { data, total } = await queryReportFeeDetailOwner(params) | |
| 128 | + this.reportFeeDetailOwnerInfo.fees = data | |
| 129 | + this.pagination.total = total | |
| 130 | + } catch (error) { | |
| 131 | + console.error('获取业主费用明细失败:', error) | |
| 132 | + } finally { | |
| 133 | + this.loading = false | |
| 134 | + } | |
| 135 | + }, | |
| 136 | + async exportReportFeeDetailOwnerExcel() { | |
| 137 | + try { | |
| 138 | + const params = { | |
| 139 | + ...this.reportFeeDetailOwnerInfo.conditions, | |
| 140 | + pagePath: 'reportFeeDetailOwner' | |
| 141 | + } | |
| 142 | + await exportReportFeeDetailOwner(params) | |
| 143 | + this.$message.success(this.$t('common.exportSuccess')) | |
| 144 | + } catch (error) { | |
| 145 | + console.error('导出失败:', error) | |
| 146 | + this.$message.error(this.$t('common.exportFailed')) | |
| 147 | + } | |
| 148 | + }, | |
| 149 | + handleSizeChange(val) { | |
| 150 | + this.pagination.size = val | |
| 151 | + this.listReportFeeDetailOwners() | |
| 152 | + }, | |
| 153 | + handleCurrentChange(val) { | |
| 154 | + this.pagination.current = val | |
| 155 | + this.listReportFeeDetailOwners() | |
| 156 | + } | |
| 157 | + } | |
| 158 | +} | |
| 159 | +</script> | |
| 160 | + | |
| 161 | +<style lang="scss" scoped> | |
| 162 | +.report-fee-detail-owner { | |
| 163 | + .operation-bar { | |
| 164 | + margin-bottom: 20px; | |
| 165 | + text-align: right; | |
| 166 | + } | |
| 167 | + | |
| 168 | + .el-pagination { | |
| 169 | + margin-top: 20px; | |
| 170 | + text-align: right; | |
| 171 | + } | |
| 172 | +} | |
| 173 | +</style> | |
| 0 | 174 | \ No newline at end of file | ... | ... |
src/components/report/reportFeeDetailRoom.vue
0 → 100644
| 1 | +<template> | |
| 2 | + <div class="report-fee-detail-room"> | |
| 3 | + <el-row :gutter="20"> | |
| 4 | + <el-col :span="4"> | |
| 5 | + <el-card class="floor-tree"> | |
| 6 | + <el-scrollbar style="height: 650px;"> | |
| 7 | + <el-menu> | |
| 8 | + <el-menu-item @click="swatchFloor('')" :class="{ 'is-active': reportFeeDetailRoomInfo.floorId === '' }"> | |
| 9 | + {{ $t('reportFeeDetailRoom.all') }} | |
| 10 | + </el-menu-item> | |
| 11 | + <el-menu-item v-for="(item, index) in reportFeeDetailRoomInfo.floors" :key="index" | |
| 12 | + @click="swatchFloor(item.floorId)" | |
| 13 | + :class="{ 'is-active': reportFeeDetailRoomInfo.floorId === item.floorId }"> | |
| 14 | + {{ item.floorName }} | |
| 15 | + </el-menu-item> | |
| 16 | + </el-menu> | |
| 17 | + </el-scrollbar> | |
| 18 | + </el-card> | |
| 19 | + </el-col> | |
| 20 | + <el-col :span="20"> | |
| 21 | + <div class="operation-bar"> | |
| 22 | + <el-button type="primary" size="small" @click="exportReportFeeDetailRoomExcel"> | |
| 23 | + <i class="el-icon-download"></i> | |
| 24 | + {{ $t('common.export') }} | |
| 25 | + </el-button> | |
| 26 | + </div> | |
| 27 | + | |
| 28 | + <el-table :data="reportFeeDetailRoomInfo.fees" border style="width: 100%" v-loading="loading"> | |
| 29 | + <el-table-column prop="roomName" :label="$t('reportFeeDetailRoom.room')" align="center"> | |
| 30 | + </el-table-column> | |
| 31 | + <el-table-column prop="ownerName" :label="$t('reportFeeDetailRoom.owner')" align="center"> | |
| 32 | + <template slot-scope="scope"> | |
| 33 | + {{ scope.row.ownerName }}({{ scope.row.link }}) | |
| 34 | + </template> | |
| 35 | + </el-table-column> | |
| 36 | + <el-table-column prop="oweFee" :label="$t('reportFeeDetailRoom.oweFee')" align="center"> | |
| 37 | + <template slot-scope="scope"> | |
| 38 | + {{ scope.row.oweFee || '0' }} | |
| 39 | + </template> | |
| 40 | + </el-table-column> | |
| 41 | + <el-table-column prop="receivedFee" :label="$t('reportFeeDetailRoom.receivedFee')" align="center"> | |
| 42 | + <template slot-scope="scope"> | |
| 43 | + {{ scope.row.receivedFee || '0' }} | |
| 44 | + </template> | |
| 45 | + </el-table-column> | |
| 46 | + <template v-for="(item, index) in reportFeeDetailRoomInfo.feeTypeCds" > | |
| 47 | + <el-table-column :key="index" :label="item.name + $t('reportFeeDetailRoom.owe')" align="center"> | |
| 48 | + <template slot-scope="scope"> | |
| 49 | + {{ scope.row['oweFee' + item.statusCd] || '0' }} | |
| 50 | + </template> | |
| 51 | + </el-table-column> | |
| 52 | + <el-table-column :key="index+'received'" :label="item.name + $t('reportFeeDetailRoom.received')" | |
| 53 | + align="center"> | |
| 54 | + <template slot-scope="scope"> | |
| 55 | + {{ scope.row['receivedFee' + item.statusCd] || '0' }} | |
| 56 | + </template> | |
| 57 | + </el-table-column> | |
| 58 | + </template> | |
| 59 | + </el-table> | |
| 60 | + | |
| 61 | + <el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange" | |
| 62 | + :current-page="pagination.current" :page-sizes="[10, 20, 30, 50]" :page-size="pagination.size" | |
| 63 | + layout="total, sizes, prev, pager, next, jumper" :total="pagination.total"> | |
| 64 | + </el-pagination> | |
| 65 | + </el-col> | |
| 66 | + </el-row> | |
| 67 | + </div> | |
| 68 | +</template> | |
| 69 | + | |
| 70 | +<script> | |
| 71 | +import { getDict } from '@/api/community/communityApi' | |
| 72 | +import { queryReportFeeDetailRoom, exportReportFeeDetailRoom } from '@/api/report/reportFeeDetailApi' | |
| 73 | +import {queryFloors} from '@/api/report/reportFeeSummaryApi' | |
| 74 | + | |
| 75 | +export default { | |
| 76 | + name: 'ReportFeeDetailRoom', | |
| 77 | + data() { | |
| 78 | + return { | |
| 79 | + reportFeeDetailRoomInfo: { | |
| 80 | + fees: [], | |
| 81 | + floors: [], | |
| 82 | + floorId: '', | |
| 83 | + feeTypeCds: [], | |
| 84 | + conditions: {} | |
| 85 | + }, | |
| 86 | + loading: false, | |
| 87 | + pagination: { | |
| 88 | + current: 1, | |
| 89 | + size: 10, | |
| 90 | + total: 0 | |
| 91 | + } | |
| 92 | + } | |
| 93 | + }, | |
| 94 | + created() { | |
| 95 | + this.getDictData() | |
| 96 | + }, | |
| 97 | + methods: { | |
| 98 | + async getDictData() { | |
| 99 | + try { | |
| 100 | + const data = await getDict('pay_fee_config', 'fee_type_cd_show') | |
| 101 | + this.reportFeeDetailRoomInfo.feeTypeCds = data | |
| 102 | + } catch (error) { | |
| 103 | + console.error('获取字典数据失败:', error) | |
| 104 | + } | |
| 105 | + }, | |
| 106 | + async open(conditions) { | |
| 107 | + this.reportFeeDetailRoomInfo.conditions = conditions | |
| 108 | + await this.listReportFeeDetailRoomFloors() | |
| 109 | + this.listReportFeeDetailRooms() | |
| 110 | + }, | |
| 111 | + async listReportFeeDetailRoomFloors() { | |
| 112 | + try { | |
| 113 | + const params = { | |
| 114 | + page: 1, | |
| 115 | + row: 100, | |
| 116 | + communityId: this.reportFeeDetailRoomInfo.conditions.communityId | |
| 117 | + } | |
| 118 | + | |
| 119 | + const data = await queryFloors(params) | |
| 120 | + this.reportFeeDetailRoomInfo.floors = data.apiFloorDataVoList | |
| 121 | + } catch (error) { | |
| 122 | + console.error('获取楼层列表失败:', error) | |
| 123 | + } | |
| 124 | + }, | |
| 125 | + swatchFloor(floorId) { | |
| 126 | + this.reportFeeDetailRoomInfo.floorId = floorId | |
| 127 | + this.listReportFeeDetailRooms() | |
| 128 | + }, | |
| 129 | + async listReportFeeDetailRooms() { | |
| 130 | + try { | |
| 131 | + this.loading = true | |
| 132 | + const params = { | |
| 133 | + ...this.reportFeeDetailRoomInfo.conditions, | |
| 134 | + page: this.pagination.current, | |
| 135 | + row: this.pagination.size, | |
| 136 | + floorId: this.reportFeeDetailRoomInfo.floorId | |
| 137 | + } | |
| 138 | + const { data, total } = await queryReportFeeDetailRoom(params) | |
| 139 | + this.reportFeeDetailRoomInfo.fees = data | |
| 140 | + this.pagination.total = total | |
| 141 | + } catch (error) { | |
| 142 | + console.error('获取房屋费用明细失败:', error) | |
| 143 | + } finally { | |
| 144 | + this.loading = false | |
| 145 | + } | |
| 146 | + }, | |
| 147 | + async exportReportFeeDetailRoomExcel() { | |
| 148 | + try { | |
| 149 | + const params = { | |
| 150 | + ...this.reportFeeDetailRoomInfo.conditions, | |
| 151 | + pagePath: 'reportFeeDetailRoom' | |
| 152 | + } | |
| 153 | + await exportReportFeeDetailRoom(params) | |
| 154 | + this.$message.success(this.$t('common.exportSuccess')) | |
| 155 | + } catch (error) { | |
| 156 | + console.error('导出失败:', error) | |
| 157 | + this.$message.error(this.$t('common.exportFailed')) | |
| 158 | + } | |
| 159 | + }, | |
| 160 | + handleSizeChange(val) { | |
| 161 | + this.pagination.size = val | |
| 162 | + this.listReportFeeDetailRooms() | |
| 163 | + }, | |
| 164 | + handleCurrentChange(val) { | |
| 165 | + this.pagination.current = val | |
| 166 | + this.listReportFeeDetailRooms() | |
| 167 | + } | |
| 168 | + } | |
| 169 | +} | |
| 170 | +</script> | |
| 171 | + | |
| 172 | +<style lang="scss" scoped> | |
| 173 | +.report-fee-detail-room { | |
| 174 | + .floor-tree { | |
| 175 | + height: 700px; | |
| 176 | + | |
| 177 | + .el-menu { | |
| 178 | + border-right: none; | |
| 179 | + } | |
| 180 | + | |
| 181 | + .is-active { | |
| 182 | + color: #409EFF; | |
| 183 | + background-color: #ecf5ff; | |
| 184 | + } | |
| 185 | + } | |
| 186 | + | |
| 187 | + .operation-bar { | |
| 188 | + margin-bottom: 20px; | |
| 189 | + text-align: right; | |
| 190 | + } | |
| 191 | + | |
| 192 | + .el-pagination { | |
| 193 | + margin-top: 20px; | |
| 194 | + text-align: right; | |
| 195 | + } | |
| 196 | +} | |
| 197 | +</style> | |
| 0 | 198 | \ No newline at end of file | ... | ... |
src/components/report/reportPrePaymentFee.vue
0 → 100644
| 1 | +<template> | |
| 2 | + <div class="report-pre-payment-fee"> | |
| 3 | + <div class="text-right"> | |
| 4 | + <el-button type="primary" size="small" @click="_exportExcel"> | |
| 5 | + <i class="el-icon-download"></i> | |
| 6 | + {{ $t('reportPrePaymentFee.export') }} | |
| 7 | + </el-button> | |
| 8 | + </div> | |
| 9 | + | |
| 10 | + <el-table :data="reportPrePaymentFeeInfo.fees" border style="width: 100%" class="margin-top"> | |
| 11 | + <el-table-column prop="index" :label="$t('reportPrePaymentFee.feeId')" align="center"> | |
| 12 | + <template slot-scope="scope"> | |
| 13 | + {{ scope.$index + 1 }} | |
| 14 | + </template> | |
| 15 | + </el-table-column> | |
| 16 | + <el-table-column prop="objName" :label="$t('reportPrePaymentFee.objName')" align="center" /> | |
| 17 | + <el-table-column prop="feeName" :label="$t('reportPrePaymentFee.feeName')" align="center" /> | |
| 18 | + <el-table-column prop="endTime" :label="$t('reportPrePaymentFee.startTime')" align="center" /> | |
| 19 | + <el-table-column prop="oweDay" :label="$t('reportPrePaymentFee.oweDay')" align="center" /> | |
| 20 | + </el-table> | |
| 21 | + | |
| 22 | + <el-row class="margin-top"> | |
| 23 | + <el-col :span="18"> | |
| 24 | + <div class="tip-text"> | |
| 25 | + {{ $t('reportPrePaymentFee.tip') }} | |
| 26 | + </div> | |
| 27 | + </el-col> | |
| 28 | + <el-col :span="6" class="text-right"> | |
| 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-col> | |
| 33 | + </el-row> | |
| 34 | + </div> | |
| 35 | +</template> | |
| 36 | + | |
| 37 | +<script> | |
| 38 | +import { getCommunityId } from '@/api/community/communityApi' | |
| 39 | +import { queryPrePayment, exportData } from '@/api/report/feeRemindApi' | |
| 40 | + | |
| 41 | +export default { | |
| 42 | + name: 'ReportPrePaymentFee', | |
| 43 | + data() { | |
| 44 | + return { | |
| 45 | + reportPrePaymentFeeInfo: { | |
| 46 | + fees: [], | |
| 47 | + conditions: {} | |
| 48 | + }, | |
| 49 | + pagination: { | |
| 50 | + current: 1, | |
| 51 | + size: 10, | |
| 52 | + total: 0 | |
| 53 | + } | |
| 54 | + } | |
| 55 | + }, | |
| 56 | + methods: { | |
| 57 | + async loadData(conditions) { | |
| 58 | + this.reportPrePaymentFeeInfo.conditions = { ...conditions } | |
| 59 | + await this._listPreFees(this.pagination.current, this.pagination.size) | |
| 60 | + }, | |
| 61 | + async _listPreFees(page, size) { | |
| 62 | + try { | |
| 63 | + const params = { | |
| 64 | + ...this.reportPrePaymentFeeInfo.conditions, | |
| 65 | + page, | |
| 66 | + row: size | |
| 67 | + } | |
| 68 | + const { data, total } = await queryPrePayment(params) | |
| 69 | + this.reportPrePaymentFeeInfo.fees = data | |
| 70 | + this.pagination.total = total | |
| 71 | + } catch (error) { | |
| 72 | + console.error('Failed to load pre payment fees:', error) | |
| 73 | + } | |
| 74 | + }, | |
| 75 | + async _exportExcel() { | |
| 76 | + try { | |
| 77 | + const params = { | |
| 78 | + ...this.reportPrePaymentFeeInfo.conditions, | |
| 79 | + communityId: getCommunityId(), | |
| 80 | + pagePath: 'reportPrePaymentFee' | |
| 81 | + } | |
| 82 | + const { code, msg } = await exportData(params) | |
| 83 | + this.$message.success(msg) | |
| 84 | + if (code === 0) { | |
| 85 | + this.$router.push('/pages/property/downloadTempFile?tab=downloadCenter') | |
| 86 | + } | |
| 87 | + } catch (error) { | |
| 88 | + console.error('Failed to export:', error) | |
| 89 | + } | |
| 90 | + }, | |
| 91 | + handleSizeChange(val) { | |
| 92 | + this.pagination.size = val | |
| 93 | + this._listPreFees(this.pagination.current, val) | |
| 94 | + }, | |
| 95 | + handleCurrentChange(val) { | |
| 96 | + this.pagination.current = val | |
| 97 | + this._listPreFees(val, this.pagination.size) | |
| 98 | + } | |
| 99 | + } | |
| 100 | +} | |
| 101 | +</script> | |
| 102 | + | |
| 103 | +<style lang="scss" scoped> | |
| 104 | +.report-pre-payment-fee { | |
| 105 | + .margin-top { | |
| 106 | + margin-top: 15px; | |
| 107 | + } | |
| 108 | + | |
| 109 | + .text-right { | |
| 110 | + text-align: right; | |
| 111 | + } | |
| 112 | + | |
| 113 | + .tip-text { | |
| 114 | + color: #999; | |
| 115 | + font-size: 12px; | |
| 116 | + padding: 5px 0; | |
| 117 | + } | |
| 118 | +} | |
| 119 | +</style> | |
| 0 | 120 | \ No newline at end of file | ... | ... |
src/components/report/selectCommunityFloor.vue
0 → 100644
| 1 | +<template> | |
| 2 | + <div class="select-community-floor-container"> | |
| 3 | + <div class="border-radius"> | |
| 4 | + <div class="margin-xs-r treeview attendance-staff" style="height: 650px;"> | |
| 5 | + <ul class="list-group text-center border-radius"> | |
| 6 | + <li v-for="(item, index) in floors" :key="index" class="list-group-item node-orgTree" | |
| 7 | + :class="{ 'vc-node-selected': selectedFloorId === item.floorId }" @click="handleSelectFloor(item)"> | |
| 8 | + {{ item.floorNum }} | |
| 9 | + </li> | |
| 10 | + </ul> | |
| 11 | + </div> | |
| 12 | + </div> | |
| 13 | + </div> | |
| 14 | +</template> | |
| 15 | + | |
| 16 | +<script> | |
| 17 | +import { getCommunityId } from '@/api/community/communityApi' | |
| 18 | +import { queryFloors } from '@/api/report/reportFeeSummaryApi' | |
| 19 | + | |
| 20 | +export default { | |
| 21 | + name: 'SelectCommunityFloor', | |
| 22 | + data() { | |
| 23 | + return { | |
| 24 | + floors: [], | |
| 25 | + selectedFloorId: '', | |
| 26 | + callBack: null | |
| 27 | + } | |
| 28 | + }, | |
| 29 | + methods: { | |
| 30 | + open(params) { | |
| 31 | + this.callBack = params.callBack | |
| 32 | + this.loadCommunityFloors() | |
| 33 | + }, | |
| 34 | + async loadCommunityFloors() { | |
| 35 | + try { | |
| 36 | + const communityId = await getCommunityId() | |
| 37 | + const params = { | |
| 38 | + _uid: '123mlkdinkldldijdhuudjdjkkd', | |
| 39 | + page: 1, | |
| 40 | + row: 100, | |
| 41 | + communityId | |
| 42 | + } | |
| 43 | + | |
| 44 | + const defaultFloor = { | |
| 45 | + floorNum: this.$t('common.all'), | |
| 46 | + floorId: '' | |
| 47 | + } | |
| 48 | + | |
| 49 | + const data = await queryFloors(params) | |
| 50 | + this.floors = [defaultFloor, ...data.apiFloorDataVoList] | |
| 51 | + this.handleSelectFloor(defaultFloor) | |
| 52 | + } catch (error) { | |
| 53 | + console.error('Failed to load floors:', error) | |
| 54 | + } | |
| 55 | + }, | |
| 56 | + handleSelectFloor(floor) { | |
| 57 | + this.selectedFloorId = floor.floorId | |
| 58 | + if (this.callBack) { | |
| 59 | + this.callBack(floor) | |
| 60 | + } | |
| 61 | + } | |
| 62 | + } | |
| 63 | +} | |
| 64 | +</script> | |
| 65 | + | |
| 66 | +<style lang="scss" scoped> | |
| 67 | +.select-community-floor-container { | |
| 68 | + .border-radius { | |
| 69 | + border-radius: 4px; | |
| 70 | + } | |
| 71 | + | |
| 72 | + .margin-xs-r { | |
| 73 | + margin-right: 5px; | |
| 74 | + } | |
| 75 | + | |
| 76 | + .treeview { | |
| 77 | + overflow-y: auto; | |
| 78 | + } | |
| 79 | + | |
| 80 | + .attendance-staff { | |
| 81 | + background-color: #fff; | |
| 82 | + border: 1px solid #ebeef5; | |
| 83 | + } | |
| 84 | + | |
| 85 | + .list-group { | |
| 86 | + padding-left: 0; | |
| 87 | + margin-bottom: 0; | |
| 88 | + list-style: none; | |
| 89 | + } | |
| 90 | + | |
| 91 | + .list-group-item { | |
| 92 | + position: relative; | |
| 93 | + display: block; | |
| 94 | + padding: 10px 15px; | |
| 95 | + margin-bottom: -1px; | |
| 96 | + background-color: #fff; | |
| 97 | + border: 1px solid #ebeef5; | |
| 98 | + cursor: pointer; | |
| 99 | + | |
| 100 | + &:hover { | |
| 101 | + background-color: #f5f7fa; | |
| 102 | + } | |
| 103 | + } | |
| 104 | + | |
| 105 | + .vc-node-selected { | |
| 106 | + background-color: #ecf5ff; | |
| 107 | + color: #409eff; | |
| 108 | + } | |
| 109 | + | |
| 110 | + .text-center { | |
| 111 | + text-align: center; | |
| 112 | + } | |
| 113 | +} | |
| 114 | +</style> | |
| 0 | 115 | \ No newline at end of file | ... | ... |
src/i18n/reportI18n.js
| ... | ... | @@ -5,6 +5,12 @@ import { messages as reportCustomComponentManageMessages } from '../views/report |
| 5 | 5 | import { messages as reportCustomComponentRelManageMessages } from '../views/report/reportCustomComponentRelManageLang' |
| 6 | 6 | import { messages as componentConditionManageMessages } from '../views/report/componentConditionManageLang' |
| 7 | 7 | import { messages as reportCustomComponentFooterManageMessages } from '../views/report/reportCustomComponentFooterManageLang' |
| 8 | + | |
| 9 | +import { messages as reportFeeSummaryMessages } from '../views/report/reportFeeSummaryLang' | |
| 10 | +import { messages as reportFeeDetailMessages } from '../views/report/reportFeeDetailLang' | |
| 11 | +import { messages as feeRemindMessages } from '../views/report/feeRemindLang' | |
| 12 | +import { messages as dataReportMessages } from '../views/report/dataReportLang' | |
| 13 | + | |
| 8 | 14 | export const messages = { |
| 9 | 15 | en: { |
| 10 | 16 | |
| ... | ... | @@ -14,6 +20,10 @@ export const messages = { |
| 14 | 20 | ...reportCustomManageMessages.en, |
| 15 | 21 | ...reportCustomComponentManageMessages.en, |
| 16 | 22 | ...reportProficientMessages.en, |
| 23 | + ...reportFeeSummaryMessages.en, | |
| 24 | + ...reportFeeDetailMessages.en, | |
| 25 | + ...feeRemindMessages.en, | |
| 26 | + ...dataReportMessages.en, | |
| 17 | 27 | }, |
| 18 | 28 | zh: { |
| 19 | 29 | ...reportCustomComponentRelManageMessages.zh, |
| ... | ... | @@ -22,5 +32,9 @@ export const messages = { |
| 22 | 32 | ...reportCustomManageMessages.zh, |
| 23 | 33 | ...reportCustomComponentManageMessages.zh, |
| 24 | 34 | ...reportProficientMessages.zh, |
| 35 | + ...reportFeeSummaryMessages.zh, | |
| 36 | + ...reportFeeDetailMessages.zh, | |
| 37 | + ...feeRemindMessages.zh, | |
| 38 | + ...dataReportMessages.zh, | |
| 25 | 39 | } |
| 26 | 40 | } |
| 27 | 41 | \ No newline at end of file | ... | ... |
src/router/reportRouter.js
| ... | ... | @@ -4,5 +4,25 @@ export default [ |
| 4 | 4 | name: '/pages/property/reportProficient', |
| 5 | 5 | component: () => import('@/views/report/reportProficientList.vue') |
| 6 | 6 | }, |
| 7 | + { | |
| 8 | + path: '/pages/property/reportFeeSummary', | |
| 9 | + name: '/pages/property/reportFeeSummary', | |
| 10 | + component: () => import('@/views/report/reportFeeSummaryList.vue') | |
| 11 | + }, | |
| 12 | + { | |
| 13 | + path: '/pages/property/reportFeeDetail', | |
| 14 | + name: '/pages/property/reportFeeDetail', | |
| 15 | + component: () => import('@/views/report/reportFeeDetailList.vue') | |
| 16 | + }, | |
| 17 | + { | |
| 18 | + path: '/pages/report/feeRemind', | |
| 19 | + name: '/pages/report/feeRemind', | |
| 20 | + component: () => import('@/views/report/feeRemindList.vue') | |
| 21 | + }, | |
| 22 | + { | |
| 23 | + path:'/pages/report/dataReport', | |
| 24 | + name:'/pages/report/dataReport', | |
| 25 | + component: () => import('@/views/report/dataReportList.vue') | |
| 26 | + }, | |
| 7 | 27 | |
| 8 | 28 | ] |
| 9 | 29 | \ No newline at end of file | ... | ... |
src/views/report/dataReportLang.js
0 → 100644
| 1 | +export const messages = { | |
| 2 | + en: { | |
| 3 | + dataReport: { | |
| 4 | + timeRange: 'Time Range', | |
| 5 | + startDate: 'Start Date', | |
| 6 | + endDate: 'End Date', | |
| 7 | + to: 'to', | |
| 8 | + selectCommunity: 'Select Community', | |
| 9 | + today: 'Today', | |
| 10 | + yesterday: 'Yesterday', | |
| 11 | + last7Days: 'Last 7 Days', | |
| 12 | + last30Days: 'Last 30 Days', | |
| 13 | + feeStatistics: 'Fee Statistics', | |
| 14 | + orderStatistics: 'Order Statistics', | |
| 15 | + inoutStatistics: 'In/Out Statistics', | |
| 16 | + otherStatistics: 'Other Statistics', | |
| 17 | + building: 'Building', | |
| 18 | + roomCount: 'Room Count', | |
| 19 | + feeRoomCount: 'Fee Room Count', | |
| 20 | + receivedFee: 'Received Fee', | |
| 21 | + totalReceived: 'Total Received', | |
| 22 | + export: 'Export', | |
| 23 | + roomNumber: 'Room Number', | |
| 24 | + ownerName: 'Owner Name', | |
| 25 | + phoneNumber: 'Phone Number', | |
| 26 | + search: 'Search', | |
| 27 | + reset: 'Reset', | |
| 28 | + room: 'Room', | |
| 29 | + owner: 'Owner', | |
| 30 | + oweFee: 'Owe Fee', | |
| 31 | + totalOwe: 'Total Owe', | |
| 32 | + historyOwe: 'History Owe', | |
| 33 | + todayPaidCount: 'Today Paid Count', | |
| 34 | + todayPaidAmount: 'Today Paid Amount', | |
| 35 | + historyPaidCount: 'History Paid Count', | |
| 36 | + historyPaidAmount: 'History Paid Amount', | |
| 37 | + monthPaidCount: 'Month Paid Count', | |
| 38 | + remainingCount: 'Remaining Count', | |
| 39 | + paidRatio: 'Paid Ratio', | |
| 40 | + monthPaidAmount: 'Month Paid Amount', | |
| 41 | + monthRemaining: 'Month Remaining', | |
| 42 | + collectionRate: 'Collection Rate', | |
| 43 | + feeName: 'Fee Name', | |
| 44 | + receivedPeriod: 'Received Period', | |
| 45 | + cashier: 'Cashier', | |
| 46 | + paymentTime: 'Payment Time', | |
| 47 | + owePeriod: 'Owe Period', | |
| 48 | + oweAmount: 'Owe Amount', | |
| 49 | + receivedAmount: 'Received Amount', | |
| 50 | + selectBuilding: 'Select Building', | |
| 51 | + feeStartDate: 'Fee Start Date', | |
| 52 | + feeEndDate: 'Fee End Date', | |
| 53 | + noExportData: 'No data to export' | |
| 54 | + } | |
| 55 | + }, | |
| 56 | + zh: { | |
| 57 | + dataReport: { | |
| 58 | + timeRange: '统计时间', | |
| 59 | + startDate: '开始日期', | |
| 60 | + endDate: '结束日期', | |
| 61 | + to: '至', | |
| 62 | + selectCommunity: '请选择小区', | |
| 63 | + today: '今日', | |
| 64 | + yesterday: '昨日', | |
| 65 | + last7Days: '近7日', | |
| 66 | + last30Days: '近30日', | |
| 67 | + feeStatistics: '费用类统计', | |
| 68 | + orderStatistics: '工单类统计', | |
| 69 | + inoutStatistics: '出入统计', | |
| 70 | + otherStatistics: '其他统计', | |
| 71 | + building: '楼栋', | |
| 72 | + roomCount: '户数', | |
| 73 | + feeRoomCount: '收费户数', | |
| 74 | + receivedFee: '实收', | |
| 75 | + totalReceived: '总实收', | |
| 76 | + export: '导出', | |
| 77 | + roomNumber: '房屋编号', | |
| 78 | + ownerName: '业主名称', | |
| 79 | + phoneNumber: '手机号', | |
| 80 | + search: '查询', | |
| 81 | + reset: '重置', | |
| 82 | + room: '房屋', | |
| 83 | + owner: '业主', | |
| 84 | + oweFee: '欠费', | |
| 85 | + totalOwe: '总欠费', | |
| 86 | + historyOwe: '历史欠费', | |
| 87 | + todayPaidCount: '本日已交户数', | |
| 88 | + todayPaidAmount: '本日已交金额', | |
| 89 | + historyPaidCount: '历史欠费清缴户', | |
| 90 | + historyPaidAmount: '历史欠费清缴金额', | |
| 91 | + monthPaidCount: '本月已收户数', | |
| 92 | + remainingCount: '剩余户数', | |
| 93 | + paidRatio: '已收户占比', | |
| 94 | + monthPaidAmount: '当月已收金额', | |
| 95 | + monthRemaining: '当月剩余未收', | |
| 96 | + collectionRate: '收费率', | |
| 97 | + feeName: '费用名称', | |
| 98 | + receivedPeriod: '实收时间段', | |
| 99 | + cashier: '收银员', | |
| 100 | + paymentTime: '交费时间', | |
| 101 | + owePeriod: '欠费时间段', | |
| 102 | + oweAmount: '欠费金额', | |
| 103 | + receivedAmount: '实收', | |
| 104 | + selectBuilding: '请选择楼栋', | |
| 105 | + feeStartDate: '费用开始时间', | |
| 106 | + feeEndDate: '费用结束时间', | |
| 107 | + noExportData: '没有可以导出的数据' | |
| 108 | + } | |
| 109 | + } | |
| 110 | +} | |
| 0 | 111 | \ No newline at end of file | ... | ... |
src/views/report/dataReportList.vue
0 → 100644
| 1 | +<template> | |
| 2 | + <div class="data-report-container"> | |
| 3 | + <div class="box-card"> | |
| 4 | + <div class="flex justify-between padding"> | |
| 5 | + <div class="flex justify-start"> | |
| 6 | + <div> | |
| 7 | + <span>{{ $t('dataReport.timeRange') }}:</span> | |
| 8 | + <el-date-picker v-model="dataReportInfo.conditions.startDate" type="date" | |
| 9 | + :placeholder="$t('dataReport.startDate')" style="width: 150px" @change="_changeDate" /> | |
| 10 | + <span>{{ $t('dataReport.to') }}:</span> | |
| 11 | + <el-date-picker v-model="dataReportInfo.conditions.endDate" type="date" | |
| 12 | + :placeholder="$t('dataReport.endDate')" style="width: 150px" @change="_changeDate" /> | |
| 13 | + </div> | |
| 14 | + <div v-if="dataReportInfo.communitys.length > 1" style="margin-left: 20px"> | |
| 15 | + <el-select v-model="dataReportInfo.conditions.communityId" :placeholder="$t('dataReport.selectCommunity')" | |
| 16 | + style="width: 200px" @change="_changCommunity"> | |
| 17 | + <el-option v-for="(item, index) in dataReportInfo.communitys" :key="index" :label="item.name" | |
| 18 | + :value="item.communityId" /> | |
| 19 | + </el-select> | |
| 20 | + </div> | |
| 21 | + </div> | |
| 22 | + <div> | |
| 23 | + <el-button :type="dataReportInfo.curDay === 'today' ? 'primary' : ''" @click="_changeDate('today')">{{ | |
| 24 | + $t('dataReport.today') }}</el-button> | |
| 25 | + <el-button :type="dataReportInfo.curDay === 'yesterday' ? 'primary' : ''" @click="_changeDate('yesterday')">{{ | |
| 26 | + $t('dataReport.yesterday') }}</el-button> | |
| 27 | + <el-button :type="dataReportInfo.curDay === 'seven' ? 'primary' : ''" @click="_changeDate('seven')">{{ | |
| 28 | + $t('dataReport.last7Days') }}</el-button> | |
| 29 | + <el-button :type="dataReportInfo.curDay === 'thirty' ? 'primary' : ''" @click="_changeDate('thirty')">{{ | |
| 30 | + $t('dataReport.last30Days') }}</el-button> | |
| 31 | + </div> | |
| 32 | + </div> | |
| 33 | + | |
| 34 | + <div class="flex justify-between "> | |
| 35 | + <el-card class="data-report-item"> | |
| 36 | + <div class="data-report-title">{{ $t('dataReport.feeStatistics') }}</div> | |
| 37 | + <div class="flex flex-wrap"> | |
| 38 | + <div v-for="(item, index) in dataReportInfo.fees" :key="index" class="data-report-card"> | |
| 39 | + <div class="data-report-card-title">{{ item.name }}</div> | |
| 40 | + <div class="data-report-card-value">{{ item.value }}</div> | |
| 41 | + </div> | |
| 42 | + </div> | |
| 43 | + </el-card> | |
| 44 | + | |
| 45 | + <el-card class="data-report-item"> | |
| 46 | + <div class="data-report-title">{{ $t('dataReport.orderStatistics') }}</div> | |
| 47 | + <div class="flex flex-wrap"> | |
| 48 | + <div v-for="(item, index) in dataReportInfo.orders" :key="index" class="data-report-card"> | |
| 49 | + <div class="data-report-card-title">{{ item.name }}</div> | |
| 50 | + <div class="data-report-card-value">{{ item.value }}</div> | |
| 51 | + </div> | |
| 52 | + </div> | |
| 53 | + </el-card> | |
| 54 | + | |
| 55 | + <el-card class="data-report-item"> | |
| 56 | + <div class="data-report-title">{{ $t('dataReport.inoutStatistics') }}</div> | |
| 57 | + <div class="flex flex-wrap"> | |
| 58 | + <div v-for="(item, index) in dataReportInfo.inouts" :key="index" class="data-report-card"> | |
| 59 | + <div class="data-report-card-title">{{ item.name }}</div> | |
| 60 | + <div class="data-report-card-value">{{ item.value }}</div> | |
| 61 | + </div> | |
| 62 | + </div> | |
| 63 | + </el-card> | |
| 64 | + | |
| 65 | + <el-card class="data-report-item"> | |
| 66 | + <div class="data-report-title">{{ $t('dataReport.otherStatistics') }}</div> | |
| 67 | + <div class="flex flex-wrap"> | |
| 68 | + <div v-for="(item, index) in dataReportInfo.others" :key="index" class="data-report-card"> | |
| 69 | + <div class="data-report-card-title">{{ item.name }}</div> | |
| 70 | + <div class="data-report-card-value">{{ item.value }}</div> | |
| 71 | + </div> | |
| 72 | + </div> | |
| 73 | + </el-card> | |
| 74 | + </div> | |
| 75 | + | |
| 76 | + <el-card> | |
| 77 | + <el-tabs v-model="dataReportInfo._currentTab" @tab-click="changeTab(dataReportInfo._currentTab)"> | |
| 78 | + <el-tab-pane label="实收统计" name="dataReportEarnedStatistics" /> | |
| 79 | + <el-tab-pane label="实收明细" name="dataReportEarnedDetailStatistics" /> | |
| 80 | + <el-tab-pane label="收款方式统计" name="dataReportEarnedWayStatistics" /> | |
| 81 | + <el-tab-pane label="欠费统计" name="dataReportOweStatistics" /> | |
| 82 | + <el-tab-pane label="欠费明细" name="dataReportOweDetailStatistics" /> | |
| 83 | + <el-tab-pane label="收缴情况" name="dataReportFeeStatistics" /> | |
| 84 | + <el-tab-pane label="月实收明细" name="dataMonthReceivedStatistics" /> | |
| 85 | + <el-tab-pane label="月欠费明细" name="dataMonthOweStatistics" /> | |
| 86 | + </el-tabs> | |
| 87 | + | |
| 88 | + <component :is="dataReportInfo._currentTab" :ref="dataReportInfo._currentTab"/> | |
| 89 | + </el-card> | |
| 90 | + </div> | |
| 91 | + </div> | |
| 92 | +</template> | |
| 93 | + | |
| 94 | +<script> | |
| 95 | +import { getCommunityId } from '@/api/community/communityApi' | |
| 96 | +import { | |
| 97 | + queryFeeDataReport, | |
| 98 | + queryOrderDataReport, | |
| 99 | + queryInoutDataReport, | |
| 100 | + queryOthersDataReport, | |
| 101 | + listMyEnteredCommunitys | |
| 102 | +} from '@/api/report/dataReportApi' | |
| 103 | +import DataReportEarnedStatistics from '@/components/report/DataReportEarnedStatistics' | |
| 104 | +import DataReportEarnedDetailStatistics from '@/components/report/DataReportEarnedDetailStatistics' | |
| 105 | +import DataReportEarnedWayStatistics from '@/components/report/DataReportEarnedWayStatistics' | |
| 106 | +import DataReportOweStatistics from '@/components/report/DataReportOweStatistics' | |
| 107 | +import DataReportOweDetailStatistics from '@/components/report/DataReportOweDetailStatistics' | |
| 108 | +import DataReportFeeStatistics from '@/components/report/DataReportFeeStatistics' | |
| 109 | +import DataMonthReceivedStatistics from '@/components/report/DataMonthReceivedStatistics' | |
| 110 | +import DataMonthOweStatistics from '@/components/report/DataMonthOweStatistics' | |
| 111 | + | |
| 112 | +export default { | |
| 113 | + name: 'DataReportList', | |
| 114 | + components: { | |
| 115 | + DataReportEarnedStatistics, | |
| 116 | + DataReportEarnedDetailStatistics, | |
| 117 | + DataReportEarnedWayStatistics, | |
| 118 | + DataReportOweStatistics, | |
| 119 | + DataReportOweDetailStatistics, | |
| 120 | + DataReportFeeStatistics, | |
| 121 | + DataMonthReceivedStatistics, | |
| 122 | + DataMonthOweStatistics | |
| 123 | + }, | |
| 124 | + data() { | |
| 125 | + return { | |
| 126 | + dataReportInfo: { | |
| 127 | + curDay: 'thirty', | |
| 128 | + _currentTab: 'dataReportEarnedStatistics', | |
| 129 | + fees: [], | |
| 130 | + orders: [], | |
| 131 | + inouts: [], | |
| 132 | + others: [], | |
| 133 | + communitys: [], | |
| 134 | + conditions: { | |
| 135 | + startDate: '', | |
| 136 | + endDate: '', | |
| 137 | + communityId: '' | |
| 138 | + } | |
| 139 | + } | |
| 140 | + } | |
| 141 | + }, | |
| 142 | + created() { | |
| 143 | + this._initDate() | |
| 144 | + this.dataReportInfo.conditions.communityId = getCommunityId() | |
| 145 | + this._loadStaffCommunitys() | |
| 146 | + this._loadDataReportFee() | |
| 147 | + this._loadDataReportOrder() | |
| 148 | + this._loadDataReportInout() | |
| 149 | + this._loadDataReportOthers() | |
| 150 | + }, | |
| 151 | + methods: { | |
| 152 | + _initDate() { | |
| 153 | + const _data = new Date() | |
| 154 | + let _month = _data.getMonth() + 1 | |
| 155 | + let _newDate = '' | |
| 156 | + if (_month < 10) { | |
| 157 | + _newDate = _data.getFullYear() + '-0' + _month + '-01' | |
| 158 | + } else { | |
| 159 | + _newDate = _data.getFullYear() + '-' + _month + '-01' | |
| 160 | + } | |
| 161 | + this.dataReportInfo.conditions.startDate = _newDate | |
| 162 | + _data.setMonth(_data.getMonth() + 1) | |
| 163 | + _month = _data.getMonth() + 1 | |
| 164 | + if (_month < 10) { | |
| 165 | + _newDate = _data.getFullYear() + '-0' + _month + '-01' | |
| 166 | + } else { | |
| 167 | + _newDate = _data.getFullYear() + '-' + _month + '-01' | |
| 168 | + } | |
| 169 | + this.dataReportInfo.conditions.endDate = _newDate | |
| 170 | + }, | |
| 171 | + _changeDate(_day) { | |
| 172 | + this.dataReportInfo.curDay = _day | |
| 173 | + const _endDate = new Date() | |
| 174 | + if (_day === 'today') { | |
| 175 | + this.dataReportInfo.conditions.endDate = _endDate.getFullYear() + '-' + (_endDate.getMonth() + 1) + '-' + _endDate.getDate() | |
| 176 | + this.dataReportInfo.conditions.startDate = _endDate.getFullYear() + '-' + (_endDate.getMonth() + 1) + '-' + _endDate.getDate() | |
| 177 | + } else if (_day === 'yesterday') { | |
| 178 | + _endDate.setDate(_endDate.getDate() - 1) | |
| 179 | + this.dataReportInfo.conditions.endDate = _endDate.getFullYear() + '-' + (_endDate.getMonth() + 1) + '-' + _endDate.getDate() | |
| 180 | + this.dataReportInfo.conditions.startDate = _endDate.getFullYear() + '-' + (_endDate.getMonth() + 1) + '-' + _endDate.getDate() | |
| 181 | + } else if (_day === 'seven') { | |
| 182 | + this.dataReportInfo.conditions.endDate = _endDate.getFullYear() + '-' + (_endDate.getMonth() + 1) + '-' + _endDate.getDate() | |
| 183 | + _endDate.setDate(_endDate.getDate() - 7) | |
| 184 | + this.dataReportInfo.conditions.startDate = _endDate.getFullYear() + '-' + (_endDate.getMonth() + 1) + '-' + _endDate.getDate() | |
| 185 | + } else if (_day === 'thirty') { | |
| 186 | + this.dataReportInfo.conditions.endDate = _endDate.getFullYear() + '-' + (_endDate.getMonth() + 1) + '-' + _endDate.getDate() | |
| 187 | + _endDate.setDate(_endDate.getDate() - 30) | |
| 188 | + this.dataReportInfo.conditions.startDate = _endDate.getFullYear() + '-' + (_endDate.getMonth() + 1) + '-' + _endDate.getDate() | |
| 189 | + } | |
| 190 | + this._loadDataReportFee() | |
| 191 | + this._loadDataReportOrder() | |
| 192 | + this._loadDataReportInout() | |
| 193 | + this._loadDataReportOthers() | |
| 194 | + this.changeTab(this.dataReportInfo._currentTab) | |
| 195 | + }, | |
| 196 | + async _loadDataReportFee() { | |
| 197 | + try { | |
| 198 | + const { data } = await queryFeeDataReport(this.dataReportInfo.conditions) | |
| 199 | + this.dataReportInfo.fees = data | |
| 200 | + } catch (error) { | |
| 201 | + console.error('Failed to load fee data:', error) | |
| 202 | + } | |
| 203 | + }, | |
| 204 | + async _loadDataReportOrder() { | |
| 205 | + try { | |
| 206 | + const { data } = await queryOrderDataReport(this.dataReportInfo.conditions) | |
| 207 | + this.dataReportInfo.orders = data | |
| 208 | + } catch (error) { | |
| 209 | + console.error('Failed to load order data:', error) | |
| 210 | + } | |
| 211 | + }, | |
| 212 | + async _loadDataReportInout() { | |
| 213 | + try { | |
| 214 | + const { data } = await queryInoutDataReport(this.dataReportInfo.conditions) | |
| 215 | + this.dataReportInfo.inouts = data | |
| 216 | + } catch (error) { | |
| 217 | + console.error('Failed to load inout data:', error) | |
| 218 | + } | |
| 219 | + }, | |
| 220 | + async _loadDataReportOthers() { | |
| 221 | + try { | |
| 222 | + const { data } = await queryOthersDataReport(this.dataReportInfo.conditions) | |
| 223 | + this.dataReportInfo.others = data | |
| 224 | + } catch (error) { | |
| 225 | + console.error('Failed to load other data:', error) | |
| 226 | + } | |
| 227 | + }, | |
| 228 | + changeTab(_tab) { | |
| 229 | + this.dataReportInfo._currentTab = _tab | |
| 230 | + setTimeout(() => { | |
| 231 | + this.$refs[_tab].open(this.dataReportInfo.conditions) | |
| 232 | + },500) | |
| 233 | + }, | |
| 234 | + async _loadStaffCommunitys() { | |
| 235 | + try { | |
| 236 | + const { communitys } = await listMyEnteredCommunitys({ | |
| 237 | + _uid: '123mlkdinkldldijdhuudjdjkkd', | |
| 238 | + page: 1, | |
| 239 | + row: 100 | |
| 240 | + }) | |
| 241 | + this.dataReportInfo.communitys = communitys | |
| 242 | + } catch (error) { | |
| 243 | + console.error('Failed to load communities:', error) | |
| 244 | + } | |
| 245 | + }, | |
| 246 | + _changCommunity() { | |
| 247 | + this.changeTab(this.dataReportInfo._currentTab) | |
| 248 | + this._loadDataReportFee() | |
| 249 | + this._loadDataReportOrder() | |
| 250 | + this._loadDataReportInout() | |
| 251 | + this._loadDataReportOthers() | |
| 252 | + } | |
| 253 | + } | |
| 254 | +} | |
| 255 | +</script> | |
| 256 | + | |
| 257 | +<style lang="scss" scoped> | |
| 258 | +.data-report-container { | |
| 259 | + padding: 20px; | |
| 260 | + | |
| 261 | + .data-report-item { | |
| 262 | + width: 24%; | |
| 263 | + margin-bottom: 20px; | |
| 264 | + | |
| 265 | + .data-report-title { | |
| 266 | + font-weight: bold; | |
| 267 | + margin-bottom: 15px; | |
| 268 | + font-size: 16px; | |
| 269 | + } | |
| 270 | + | |
| 271 | + .data-report-card { | |
| 272 | + width: 25%; | |
| 273 | + margin: 5px; | |
| 274 | + padding: 10px; | |
| 275 | + border: 1px solid #4297E5; | |
| 276 | + border-radius: 4px; | |
| 277 | + | |
| 278 | + .data-report-card-title { | |
| 279 | + font-size: 12px; | |
| 280 | + color: #666; | |
| 281 | + } | |
| 282 | + | |
| 283 | + .data-report-card-value { | |
| 284 | + font-size: 18px; | |
| 285 | + font-weight: bold; | |
| 286 | + margin-top: 5px; | |
| 287 | + } | |
| 288 | + } | |
| 289 | + } | |
| 290 | + | |
| 291 | + .margin-bottom { | |
| 292 | + margin-bottom: 20px; | |
| 293 | + } | |
| 294 | + | |
| 295 | + .padding { | |
| 296 | + padding: 10px 0; | |
| 297 | + } | |
| 298 | + | |
| 299 | + .flex { | |
| 300 | + display: flex; | |
| 301 | + } | |
| 302 | + | |
| 303 | + .justify-between { | |
| 304 | + justify-content: space-between; | |
| 305 | + } | |
| 306 | + | |
| 307 | + .justify-start { | |
| 308 | + justify-content: flex-start; | |
| 309 | + } | |
| 310 | + | |
| 311 | + .flex-wrap { | |
| 312 | + flex-wrap: wrap; | |
| 313 | + } | |
| 314 | +} | |
| 315 | +</style> | |
| 0 | 316 | \ No newline at end of file | ... | ... |
src/views/report/feeRemindLang.js
0 → 100644
| 1 | +export const messages = { | |
| 2 | + en: { | |
| 3 | + feeRemind: { | |
| 4 | + queryCondition: 'Query Conditions', | |
| 5 | + hide: 'Hide', | |
| 6 | + more: 'More', | |
| 7 | + objNamePlaceholder: 'Please enter room number/contract name/license plate', | |
| 8 | + ownerNamePlaceholder: 'Please enter owner name', | |
| 9 | + linkPlaceholder: 'Please enter owner phone', | |
| 10 | + feeConfigPlaceholder: 'Please select fee item', | |
| 11 | + communityPlaceholder: 'Please select community', | |
| 12 | + query: 'Query', | |
| 13 | + reset: 'Reset', | |
| 14 | + prePaymentRemind: 'Pre-payment Reminder', | |
| 15 | + deadlineRemind: 'Expiration Reminder' | |
| 16 | + }, | |
| 17 | + reportPrePaymentFee: { | |
| 18 | + export: 'Export', | |
| 19 | + feeId: 'Fee ID', | |
| 20 | + objName: 'Room/Vehicle/Contract', | |
| 21 | + feeName: 'Fee Item', | |
| 22 | + startTime: 'Fee Start Time', | |
| 23 | + oweDay: 'Days Until Start', | |
| 24 | + tip: 'Note: This table shows fees starting within 7 days' | |
| 25 | + }, | |
| 26 | + reportDeadlineFee: { | |
| 27 | + export: 'Export', | |
| 28 | + feeId: 'Fee ID', | |
| 29 | + objName: 'Room/Vehicle/Contract', | |
| 30 | + feeName: 'Fee Item', | |
| 31 | + deadlineTime: 'Fee End Time', | |
| 32 | + oweDay: 'Days Until End', | |
| 33 | + tip: 'Note: This table shows fees ending within 7 days' | |
| 34 | + } | |
| 35 | + }, | |
| 36 | + zh: { | |
| 37 | + feeRemind: { | |
| 38 | + queryCondition: '查询条件', | |
| 39 | + hide: '隐藏', | |
| 40 | + more: '更多', | |
| 41 | + objNamePlaceholder: '请填写房屋编号/合同名称/车牌号', | |
| 42 | + ownerNamePlaceholder: '请填写业主名称', | |
| 43 | + linkPlaceholder: '请填写业主手机号', | |
| 44 | + feeConfigPlaceholder: '请选择费用项', | |
| 45 | + communityPlaceholder: '请选择小区', | |
| 46 | + query: '查询', | |
| 47 | + reset: '重置', | |
| 48 | + prePaymentRemind: '预缴费提醒', | |
| 49 | + deadlineRemind: '到期提醒' | |
| 50 | + }, | |
| 51 | + reportPrePaymentFee: { | |
| 52 | + export: '导出', | |
| 53 | + feeId: '费用编号', | |
| 54 | + objName: '房号/车辆/合同', | |
| 55 | + feeName: '费用项', | |
| 56 | + startTime: '费用开始时间', | |
| 57 | + oweDay: '距离开始时间(天)', | |
| 58 | + tip: '温馨提示:此表反馈7天内开始缴费的费用' | |
| 59 | + }, | |
| 60 | + reportDeadlineFee: { | |
| 61 | + export: '导出', | |
| 62 | + feeId: '费用编号', | |
| 63 | + objName: '房号/车辆/合同', | |
| 64 | + feeName: '费用项', | |
| 65 | + deadlineTime: '费用结束时间', | |
| 66 | + oweDay: '距离结束时间(天)', | |
| 67 | + tip: '温馨提示:此表反馈7天内缴费结束的费用' | |
| 68 | + } | |
| 69 | + } | |
| 70 | +} | |
| 0 | 71 | \ No newline at end of file | ... | ... |
src/views/report/feeRemindList.vue
0 → 100644
| 1 | +<template> | |
| 2 | + <div class="fee-remind-container"> | |
| 3 | + <el-card class="box-card"> | |
| 4 | + <div slot="header" class="flex justify-between"> | |
| 5 | + <span>{{ $t('feeRemind.queryCondition') }}</span> | |
| 6 | + <el-button type="text" style="float: right; padding: 3px 0" @click="_moreCondition()"> | |
| 7 | + {{ feeRemindInfo.moreCondition ? $t('feeRemind.hide') : $t('feeRemind.more') }} | |
| 8 | + </el-button> | |
| 9 | + </div> | |
| 10 | + <el-row :gutter="20"> | |
| 11 | + <el-col :span="4"> | |
| 12 | + <el-input v-model.trim="feeRemindInfo.conditions.objName" :placeholder="$t('feeRemind.objNamePlaceholder')" | |
| 13 | + clearable /> | |
| 14 | + </el-col> | |
| 15 | + <el-col :span="4"> | |
| 16 | + <el-input v-model.trim="feeRemindInfo.conditions.ownerName" :placeholder="$t('feeRemind.ownerNamePlaceholder')" | |
| 17 | + clearable /> | |
| 18 | + </el-col> | |
| 19 | + <el-col :span="4"> | |
| 20 | + <el-input v-model.trim="feeRemindInfo.conditions.link" :placeholder="$t('feeRemind.linkPlaceholder')" | |
| 21 | + clearable /> | |
| 22 | + </el-col> | |
| 23 | + <el-col :span="4"> | |
| 24 | + <el-select v-model="feeRemindInfo.conditions.configId" :placeholder="$t('feeRemind.feeConfigPlaceholder')" | |
| 25 | + style="width:100%" clearable> | |
| 26 | + <el-option v-for="item in feeRemindInfo.feeConfigs" :key="item.configId" :label="item.feeName" | |
| 27 | + :value="item.configId" /> | |
| 28 | + </el-select> | |
| 29 | + </el-col> | |
| 30 | + <el-col v-if="feeRemindInfo.communitys.length > 1" :span="4"> | |
| 31 | + <el-select v-model="feeRemindInfo.conditions.communityId" :placeholder="$t('feeRemind.communityPlaceholder')" | |
| 32 | + style="width:100%" @change="_changCommunity" clearable> | |
| 33 | + <el-option v-for="item in feeRemindInfo.communitys" :key="item.communityId" :label="item.name" | |
| 34 | + :value="item.communityId" /> | |
| 35 | + </el-select> | |
| 36 | + </el-col> | |
| 37 | + <el-col :span="4"> | |
| 38 | + <el-button type="primary" @click="_queryMethod"> | |
| 39 | + <i class="el-icon-search"></i> | |
| 40 | + {{ $t('feeRemind.query') }} | |
| 41 | + </el-button> | |
| 42 | + <el-button @click="_resetMethod"> | |
| 43 | + <i class="el-icon-refresh"></i> | |
| 44 | + {{ $t('feeRemind.reset') }} | |
| 45 | + </el-button> | |
| 46 | + </el-col> | |
| 47 | + </el-row> | |
| 48 | + </el-card> | |
| 49 | + | |
| 50 | + <el-card class="box-card margin-top"> | |
| 51 | + <el-tabs v-model="feeRemindInfo._currentTab" @tab-click="changeTab"> | |
| 52 | + <el-tab-pane :label="$t('feeRemind.prePaymentRemind')" name="reportPrePaymentFee"> | |
| 53 | + <report-pre-payment-fee v-if="feeRemindInfo._currentTab === 'reportPrePaymentFee'" ref="prePaymentFee" /> | |
| 54 | + </el-tab-pane> | |
| 55 | + <el-tab-pane :label="$t('feeRemind.deadlineRemind')" name="reportDeadlineFee"> | |
| 56 | + <report-deadline-fee v-if="feeRemindInfo._currentTab === 'reportDeadlineFee'" ref="deadlineFee" /> | |
| 57 | + </el-tab-pane> | |
| 58 | + </el-tabs> | |
| 59 | + </el-card> | |
| 60 | + </div> | |
| 61 | +</template> | |
| 62 | + | |
| 63 | +<script> | |
| 64 | +import { getCommunityId } from '@/api/community/communityApi' | |
| 65 | +import ReportPrePaymentFee from '@/components/report/reportPrePaymentFee' | |
| 66 | +import ReportDeadlineFee from '@/components/report/reportDeadlineFee' | |
| 67 | +import { | |
| 68 | + listFeeConfigs, | |
| 69 | + listMyEnteredCommunitys | |
| 70 | +} from '@/api/report/feeRemindApi' | |
| 71 | + | |
| 72 | +export default { | |
| 73 | + name: 'FeeRemindList', | |
| 74 | + components: { | |
| 75 | + ReportPrePaymentFee, | |
| 76 | + ReportDeadlineFee | |
| 77 | + }, | |
| 78 | + data() { | |
| 79 | + return { | |
| 80 | + feeRemindInfo: { | |
| 81 | + _currentTab: 'reportPrePaymentFee', | |
| 82 | + feeConfigs: [], | |
| 83 | + moreCondition: false, | |
| 84 | + communitys: [], | |
| 85 | + conditions: { | |
| 86 | + objName: '', | |
| 87 | + configId: '', | |
| 88 | + ownerName: '', | |
| 89 | + link: '', | |
| 90 | + communityId: '' | |
| 91 | + } | |
| 92 | + } | |
| 93 | + } | |
| 94 | + }, | |
| 95 | + created() { | |
| 96 | + this.feeRemindInfo.conditions.communityId = getCommunityId() | |
| 97 | + this._loadStaffCommunitys() | |
| 98 | + this._listFeeConfigs() | |
| 99 | + }, | |
| 100 | + methods: { | |
| 101 | + changeTab(tab) { | |
| 102 | + this.feeRemindInfo._currentTab = tab.name || tab | |
| 103 | + setTimeout(() => { | |
| 104 | + if (tab.name === 'reportPrePaymentFee') { | |
| 105 | + this.$refs.prePaymentFee && this.$refs.prePaymentFee.loadData(this.feeRemindInfo.conditions) | |
| 106 | + } else { | |
| 107 | + this.$refs.deadlineFee && this.$refs.deadlineFee.loadData(this.feeRemindInfo.conditions) | |
| 108 | + } | |
| 109 | + }, 500) | |
| 110 | + | |
| 111 | + }, | |
| 112 | + _queryMethod() { | |
| 113 | + this.changeTab(this.feeRemindInfo._currentTab) | |
| 114 | + }, | |
| 115 | + _resetMethod() { | |
| 116 | + this.feeRemindInfo.conditions = { | |
| 117 | + objName: '', | |
| 118 | + configId: '', | |
| 119 | + ownerName: '', | |
| 120 | + link: '', | |
| 121 | + communityId: getCommunityId() | |
| 122 | + } | |
| 123 | + this.changeTab(this.feeRemindInfo._currentTab) | |
| 124 | + }, | |
| 125 | + async _listFeeConfigs() { | |
| 126 | + try { | |
| 127 | + const params = { | |
| 128 | + page: 1, | |
| 129 | + row: 100, | |
| 130 | + communityId: this.feeRemindInfo.conditions.communityId, | |
| 131 | + isDefault: 'F' | |
| 132 | + } | |
| 133 | + const data = await listFeeConfigs(params) | |
| 134 | + this.feeRemindInfo.feeConfigs = data.feeConfigs | |
| 135 | + } catch (error) { | |
| 136 | + console.error('Failed to load fee configs:', error) | |
| 137 | + } | |
| 138 | + }, | |
| 139 | + _moreCondition() { | |
| 140 | + this.feeRemindInfo.moreCondition = !this.feeRemindInfo.moreCondition | |
| 141 | + }, | |
| 142 | + async _loadStaffCommunitys() { | |
| 143 | + try { | |
| 144 | + const params = { | |
| 145 | + _uid: '123mlkdinkldldijdhuudjdjkkd', | |
| 146 | + page: 1, | |
| 147 | + row: 100 | |
| 148 | + } | |
| 149 | + const data = await listMyEnteredCommunitys(params) | |
| 150 | + this.feeRemindInfo.communitys = data.communitys | |
| 151 | + } catch (error) { | |
| 152 | + console.error('Failed to load communities:', error) | |
| 153 | + } | |
| 154 | + }, | |
| 155 | + _changCommunity() { | |
| 156 | + this._listFeeConfigs() | |
| 157 | + this.changeTab(this.feeRemindInfo._currentTab) | |
| 158 | + } | |
| 159 | + } | |
| 160 | +} | |
| 161 | +</script> | |
| 162 | + | |
| 163 | +<style lang="scss" scoped> | |
| 164 | +.fee-remind-container { | |
| 165 | + padding: 20px; | |
| 166 | + | |
| 167 | + .box-card { | |
| 168 | + margin-bottom: 20px; | |
| 169 | + } | |
| 170 | + | |
| 171 | + .margin-top { | |
| 172 | + margin-top: 20px; | |
| 173 | + } | |
| 174 | + | |
| 175 | + .el-col { | |
| 176 | + margin-bottom: 10px; | |
| 177 | + } | |
| 178 | + | |
| 179 | + .el-button+.el-button { | |
| 180 | + margin-left: 10px; | |
| 181 | + } | |
| 182 | +} | |
| 183 | +</style> | |
| 0 | 184 | \ No newline at end of file | ... | ... |
src/views/report/reportFeeDetailLang.js
0 → 100644
| 1 | +export const messages = { | |
| 2 | + en: { | |
| 3 | + reportFeeDetail: { | |
| 4 | + search: { | |
| 5 | + title: 'Search Conditions', | |
| 6 | + startDate: 'Start Date', | |
| 7 | + endDate: 'End Date', | |
| 8 | + objName: 'Room No/Contract/Car No', | |
| 9 | + ownerName: 'Owner Name', | |
| 10 | + link: 'Owner Phone', | |
| 11 | + community: 'Community' | |
| 12 | + }, | |
| 13 | + placeholder: { | |
| 14 | + startDate: 'Please select start date', | |
| 15 | + endDate: 'Please select end date', | |
| 16 | + objName: 'Please enter room no/contract name/car no', | |
| 17 | + ownerName: 'Please enter owner name', | |
| 18 | + link: 'Please enter owner phone', | |
| 19 | + community: 'Please select community' | |
| 20 | + }, | |
| 21 | + hide: 'Hide', | |
| 22 | + more: 'More', | |
| 23 | + tabs: { | |
| 24 | + room: 'Room Fee Details', | |
| 25 | + owner: 'Owner Fee Details', | |
| 26 | + contract: 'Contract Fee Details', | |
| 27 | + car: 'Car Fee Details' | |
| 28 | + } | |
| 29 | + }, | |
| 30 | + reportFeeDetailRoom: { | |
| 31 | + all: 'All', | |
| 32 | + room: 'Room', | |
| 33 | + owner: 'Owner', | |
| 34 | + oweFee: 'Owe Fee', | |
| 35 | + receivedFee: 'Received Fee', | |
| 36 | + owe: ' (Owe)', | |
| 37 | + received: ' (Received)' | |
| 38 | + }, | |
| 39 | + reportFeeDetailOwner: { | |
| 40 | + owner: 'Owner', | |
| 41 | + room: 'Room', | |
| 42 | + oweFee: 'Owe Fee', | |
| 43 | + receivedFee: 'Received Fee', | |
| 44 | + owe: ' (Owe)', | |
| 45 | + received: ' (Received)' | |
| 46 | + }, | |
| 47 | + reportFeeDetailContract: { | |
| 48 | + contract: 'Contract', | |
| 49 | + owner: 'Owner', | |
| 50 | + oweFee: 'Owe Fee', | |
| 51 | + receivedFee: 'Received Fee', | |
| 52 | + owe: ' (Owe)', | |
| 53 | + received: ' (Received)' | |
| 54 | + }, | |
| 55 | + reportFeeDetailCar: { | |
| 56 | + car: 'Car', | |
| 57 | + owner: 'Owner', | |
| 58 | + oweFee: 'Owe Fee', | |
| 59 | + receivedFee: 'Received Fee', | |
| 60 | + owe: ' (Owe)', | |
| 61 | + received: ' (Received)' | |
| 62 | + } | |
| 63 | + }, | |
| 64 | + zh: { | |
| 65 | + reportFeeDetail: { | |
| 66 | + search: { | |
| 67 | + title: '查询条件', | |
| 68 | + startDate: '开始日期', | |
| 69 | + endDate: '结束日期', | |
| 70 | + objName: '房屋编号/合同/车牌号', | |
| 71 | + ownerName: '业主名称', | |
| 72 | + link: '业主手机号', | |
| 73 | + community: '小区' | |
| 74 | + }, | |
| 75 | + placeholder: { | |
| 76 | + startDate: '请选择开始日期', | |
| 77 | + endDate: '请选择结束日期', | |
| 78 | + objName: '请输入房屋编号/合同名称/车牌号', | |
| 79 | + ownerName: '请输入业主名称', | |
| 80 | + link: '请输入业主手机号', | |
| 81 | + community: '请选择小区' | |
| 82 | + }, | |
| 83 | + hide: '隐藏', | |
| 84 | + more: '更多', | |
| 85 | + tabs: { | |
| 86 | + room: '房屋费用明细', | |
| 87 | + owner: '业主费用明细', | |
| 88 | + contract: '合同费用明细', | |
| 89 | + car: '车辆费用明细' | |
| 90 | + } | |
| 91 | + }, | |
| 92 | + reportFeeDetailRoom: { | |
| 93 | + all: '全部', | |
| 94 | + room: '房屋', | |
| 95 | + owner: '业主', | |
| 96 | + oweFee: '欠费', | |
| 97 | + receivedFee: '实收', | |
| 98 | + owe: ' (欠费)', | |
| 99 | + received: ' (实收)' | |
| 100 | + }, | |
| 101 | + reportFeeDetailOwner: { | |
| 102 | + owner: '业主', | |
| 103 | + room: '房屋', | |
| 104 | + oweFee: '欠费', | |
| 105 | + receivedFee: '实收', | |
| 106 | + owe: ' (欠费)', | |
| 107 | + received: ' (实收)' | |
| 108 | + }, | |
| 109 | + reportFeeDetailContract: { | |
| 110 | + contract: '合同', | |
| 111 | + owner: '业主', | |
| 112 | + oweFee: '欠费', | |
| 113 | + receivedFee: '实收', | |
| 114 | + owe: ' (欠费)', | |
| 115 | + received: ' (实收)' | |
| 116 | + }, | |
| 117 | + reportFeeDetailCar: { | |
| 118 | + car: '车辆', | |
| 119 | + owner: '业主', | |
| 120 | + oweFee: '欠费', | |
| 121 | + receivedFee: '实收', | |
| 122 | + owe: ' (欠费)', | |
| 123 | + received: ' (实收)' | |
| 124 | + } | |
| 125 | + } | |
| 126 | +} | |
| 0 | 127 | \ No newline at end of file | ... | ... |
src/views/report/reportFeeDetailList.vue
0 → 100644
| 1 | +<template> | |
| 2 | + <div class="report-fee-detail-container"> | |
| 3 | + <!-- 查询条件 --> | |
| 4 | + <el-card class="search-card"> | |
| 5 | + <div slot="header" class="flex justify-between"> | |
| 6 | + <span>{{ $t('reportFeeDetail.search.title') }}</span> | |
| 7 | + <div class="header-tools"> | |
| 8 | + <el-button type="text" @click="toggleMoreCondition" style="margin-right:10px;"> | |
| 9 | + {{ reportFeeDetailInfo.moreCondition ? $t('reportFeeDetail.hide') : $t('reportFeeDetail.more') }} | |
| 10 | + </el-button> | |
| 11 | + </div> | |
| 12 | + </div> | |
| 13 | + <el-row :gutter="20"> | |
| 14 | + <el-col :span="6"> | |
| 15 | + <el-date-picker v-model="reportFeeDetailInfo.conditions.startDate" type="date" | |
| 16 | + :placeholder="$t('reportFeeDetail.placeholder.startDate')" style="width:100%"> | |
| 17 | + </el-date-picker> | |
| 18 | + </el-col> | |
| 19 | + <el-col :span="6"> | |
| 20 | + <el-date-picker v-model="reportFeeDetailInfo.conditions.endDate" type="date" | |
| 21 | + :placeholder="$t('reportFeeDetail.placeholder.endDate')" style="width:100%"> | |
| 22 | + </el-date-picker> | |
| 23 | + </el-col> | |
| 24 | + <el-col :span="6"> | |
| 25 | + <el-input v-model.trim="reportFeeDetailInfo.conditions.objName" | |
| 26 | + :placeholder="$t('reportFeeDetail.placeholder.objName')"> | |
| 27 | + </el-input> | |
| 28 | + </el-col> | |
| 29 | + <el-col :span="6"> | |
| 30 | + <el-button type="primary" @click="queryMethod"> | |
| 31 | + <i class="el-icon-search"></i> | |
| 32 | + {{ $t('common.search') }} | |
| 33 | + </el-button> | |
| 34 | + <el-button @click="resetMethod"> | |
| 35 | + <i class="el-icon-refresh"></i> | |
| 36 | + {{ $t('common.reset') }} | |
| 37 | + </el-button> | |
| 38 | + </el-col> | |
| 39 | + </el-row> | |
| 40 | + <el-row :gutter="20" v-show="reportFeeDetailInfo.moreCondition"> | |
| 41 | + <el-col :span="6"> | |
| 42 | + <el-input v-model.trim="reportFeeDetailInfo.conditions.ownerName" | |
| 43 | + :placeholder="$t('reportFeeDetail.placeholder.ownerName')"> | |
| 44 | + </el-input> | |
| 45 | + </el-col> | |
| 46 | + <el-col :span="6"> | |
| 47 | + <el-input v-model.trim="reportFeeDetailInfo.conditions.link" | |
| 48 | + :placeholder="$t('reportFeeDetail.placeholder.link')"> | |
| 49 | + </el-input> | |
| 50 | + </el-col> | |
| 51 | + <el-col :span="6" v-if="reportFeeDetailInfo.communitys.length > 1"> | |
| 52 | + <el-select v-model="reportFeeDetailInfo.conditions.communityId" @change="changCommunity" style="width:100%"> | |
| 53 | + <el-option disabled :value="''" :label="$t('reportFeeDetail.placeholder.community')"> | |
| 54 | + </el-option> | |
| 55 | + <el-option v-for="(item, index) in reportFeeDetailInfo.communitys" :key="index" :label="item.name" | |
| 56 | + :value="item.communityId"> | |
| 57 | + </el-option> | |
| 58 | + </el-select> | |
| 59 | + </el-col> | |
| 60 | + </el-row> | |
| 61 | + </el-card> | |
| 62 | + | |
| 63 | + <!-- 内容区域 --> | |
| 64 | + <el-card class="content-card"> | |
| 65 | + <el-tabs v-model="reportFeeDetailInfo._currentTab" @tab-click="changeTab"> | |
| 66 | + <el-tab-pane label="房屋费用明细" name="reportFeeDetailRoom"> | |
| 67 | + <report-fee-detail-room v-if="reportFeeDetailInfo._currentTab === 'reportFeeDetailRoom'" | |
| 68 | + ref="reportFeeDetailRoom"> | |
| 69 | + </report-fee-detail-room> | |
| 70 | + </el-tab-pane> | |
| 71 | + <el-tab-pane label="业主费用明细" name="reportFeeDetailOwner"> | |
| 72 | + <report-fee-detail-owner v-if="reportFeeDetailInfo._currentTab === 'reportFeeDetailOwner'" | |
| 73 | + ref="reportFeeDetailOwner"> | |
| 74 | + </report-fee-detail-owner> | |
| 75 | + </el-tab-pane> | |
| 76 | + <el-tab-pane label="合同费用明细" name="reportFeeDetailContract"> | |
| 77 | + <report-fee-detail-contract v-if="reportFeeDetailInfo._currentTab === 'reportFeeDetailContract'" | |
| 78 | + ref="reportFeeDetailContract"> | |
| 79 | + </report-fee-detail-contract> | |
| 80 | + </el-tab-pane> | |
| 81 | + <el-tab-pane label="车辆费用明细" name="reportFeeDetailCar"> | |
| 82 | + <report-fee-detail-car v-if="reportFeeDetailInfo._currentTab === 'reportFeeDetailCar'" ref="reportFeeDetailCar"> | |
| 83 | + </report-fee-detail-car> | |
| 84 | + </el-tab-pane> | |
| 85 | + </el-tabs> | |
| 86 | + </el-card> | |
| 87 | + </div> | |
| 88 | +</template> | |
| 89 | + | |
| 90 | +<script> | |
| 91 | +import { getCommunityId } from '@/api/community/communityApi' | |
| 92 | +import ReportFeeDetailRoom from '@/components/report/reportFeeDetailRoom' | |
| 93 | +import ReportFeeDetailOwner from '@/components/report/reportFeeDetailOwner' | |
| 94 | +import ReportFeeDetailContract from '@/components/report/reportFeeDetailContract' | |
| 95 | +import ReportFeeDetailCar from '@/components/report/reportFeeDetailCar' | |
| 96 | +import { loadStaffCommunitys } from '@/api/report/reportFeeDetailApi' | |
| 97 | + | |
| 98 | +export default { | |
| 99 | + name: 'ReportFeeDetailList', | |
| 100 | + components: { | |
| 101 | + ReportFeeDetailRoom, | |
| 102 | + ReportFeeDetailOwner, | |
| 103 | + ReportFeeDetailContract, | |
| 104 | + ReportFeeDetailCar | |
| 105 | + }, | |
| 106 | + data() { | |
| 107 | + return { | |
| 108 | + reportFeeDetailInfo: { | |
| 109 | + _currentTab: 'reportFeeDetailRoom', | |
| 110 | + floors: [], | |
| 111 | + moreCondition: false, | |
| 112 | + communitys: [], | |
| 113 | + conditions: { | |
| 114 | + floorId: '', | |
| 115 | + objName: '', | |
| 116 | + startDate: '', | |
| 117 | + endDate: '', | |
| 118 | + configId: '', | |
| 119 | + feeTypeCd: '', | |
| 120 | + ownerName: '', | |
| 121 | + link: '', | |
| 122 | + communityId: '' | |
| 123 | + } | |
| 124 | + } | |
| 125 | + } | |
| 126 | + }, | |
| 127 | + created() { | |
| 128 | + this.initDate() | |
| 129 | + this.loadStaffCommunitys() | |
| 130 | + this.reportFeeDetailInfo.conditions.communityId = getCommunityId() | |
| 131 | + this.changeTab(this.reportFeeDetailInfo._currentTab) | |
| 132 | + }, | |
| 133 | + methods: { | |
| 134 | + initDate() { | |
| 135 | + const now = new Date() | |
| 136 | + const year = now.getFullYear() | |
| 137 | + let month = now.getMonth() + 1 | |
| 138 | + month = month < 10 ? `0${month}` : month | |
| 139 | + | |
| 140 | + this.reportFeeDetailInfo.conditions.startDate = `${year}-${month}-01` | |
| 141 | + | |
| 142 | + const nextMonth = new Date(year, month, 1) | |
| 143 | + const nextYear = nextMonth.getFullYear() | |
| 144 | + let nextMonthNum = nextMonth.getMonth() + 1 | |
| 145 | + nextMonthNum = nextMonthNum < 10 ? `0${nextMonthNum}` : nextMonthNum | |
| 146 | + | |
| 147 | + this.reportFeeDetailInfo.conditions.endDate = `${nextYear}-${nextMonthNum}-01` | |
| 148 | + }, | |
| 149 | + async loadStaffCommunitys() { | |
| 150 | + try { | |
| 151 | + const params = { | |
| 152 | + _uid: '123mlkdinkldldijdhuudjdjkkd', | |
| 153 | + page: 1, | |
| 154 | + row: 100 | |
| 155 | + } | |
| 156 | + const data = await loadStaffCommunitys(params) | |
| 157 | + this.reportFeeDetailInfo.communitys = data.communitys | |
| 158 | + } catch (error) { | |
| 159 | + console.error('加载小区列表失败:', error) | |
| 160 | + } | |
| 161 | + }, | |
| 162 | + changeTab(tab) { | |
| 163 | + this.reportFeeDetailInfo._currentTab = tab.name || tab | |
| 164 | + setTimeout(() => { | |
| 165 | + this.$refs[tab.name || tab].open(this.reportFeeDetailInfo.conditions) | |
| 166 | + },500) | |
| 167 | + | |
| 168 | + }, | |
| 169 | + queryMethod() { | |
| 170 | + this.changeTab(this.reportFeeDetailInfo._currentTab) | |
| 171 | + }, | |
| 172 | + resetMethod() { | |
| 173 | + this.reportFeeDetailInfo.conditions = { | |
| 174 | + floorId: '', | |
| 175 | + objName: '', | |
| 176 | + startDate: '', | |
| 177 | + endDate: '', | |
| 178 | + configId: '', | |
| 179 | + feeTypeCd: '', | |
| 180 | + ownerName: '', | |
| 181 | + link: '', | |
| 182 | + communityId: getCommunityId() | |
| 183 | + } | |
| 184 | + this.initDate() | |
| 185 | + this.changeTab(this.reportFeeDetailInfo._currentTab) | |
| 186 | + }, | |
| 187 | + changCommunity() { | |
| 188 | + this.changeTab(this.reportFeeDetailInfo._currentTab) | |
| 189 | + }, | |
| 190 | + toggleMoreCondition() { | |
| 191 | + this.reportFeeDetailInfo.moreCondition = !this.reportFeeDetailInfo.moreCondition | |
| 192 | + } | |
| 193 | + } | |
| 194 | +} | |
| 195 | +</script> | |
| 196 | + | |
| 197 | +<style lang="scss" scoped> | |
| 198 | +.report-fee-detail-container { | |
| 199 | + padding: 20px; | |
| 200 | + | |
| 201 | + .search-card { | |
| 202 | + margin-bottom: 20px; | |
| 203 | + | |
| 204 | + .header-tools { | |
| 205 | + float: right; | |
| 206 | + } | |
| 207 | + } | |
| 208 | + | |
| 209 | + .content-card { | |
| 210 | + width: 100%; | |
| 211 | + } | |
| 212 | +} | |
| 213 | +</style> | |
| 0 | 214 | \ No newline at end of file | ... | ... |
src/views/report/reportFeeSummaryLang.js
0 → 100644
| 1 | +export const messages = { | |
| 2 | + en: { | |
| 3 | + reportFeeSummary: { | |
| 4 | + queryCondition: 'Query Conditions', | |
| 5 | + selectStartDate: 'Select start date', | |
| 6 | + selectEndDate: 'Select end date', | |
| 7 | + inputRoomNumber: 'Input room number', | |
| 8 | + inputOwnerName: 'Input owner name', | |
| 9 | + inputOwnerPhone: 'Input owner phone', | |
| 10 | + selectFeeType: 'Select fee type', | |
| 11 | + selectCommunity: 'Select community', | |
| 12 | + feeSummaryTable: 'Fee Summary Table', | |
| 13 | + updateDaily: 'Updated daily', | |
| 14 | + totalRooms: 'Total Rooms', | |
| 15 | + chargeRooms: 'Charge Rooms', | |
| 16 | + arrearsRooms: 'Arrears Rooms', | |
| 17 | + arrearsFormula: 'History Arrears + Current Arrears = Total Arrears', | |
| 18 | + historyArrears: 'History Arrears', | |
| 19 | + currentArrears: 'Current Arrears', | |
| 20 | + totalArrears: 'Total Arrears', | |
| 21 | + actualPaymentFormula: 'Arrears Recovery + Current Partial + Advance = Actual Payment', | |
| 22 | + arrearsRecovery: 'Arrears Recovery', | |
| 23 | + currentPartial: 'Current Partial', | |
| 24 | + advancePayment: 'Advance Payment', | |
| 25 | + actualPayment: 'Actual Payment', | |
| 26 | + currentReceivable: 'Current Receivable', | |
| 27 | + currentActual: 'Current Actual', | |
| 28 | + roomChargeRate: 'Room Charge Rate', | |
| 29 | + chargeRate: 'Charge Rate', | |
| 30 | + clearanceRate: 'Clearance Rate', | |
| 31 | + floorFeeSummary: 'Floor Fee Summary', | |
| 32 | + configFeeSummary: 'Config Fee Summary', | |
| 33 | + floorFeeRateStatistics: 'Floor Charge Rate Statistics', | |
| 34 | + configFeeRateStatistics: 'Config Charge Rate Statistics', | |
| 35 | + dateError: 'Start date must be earlier than end date', | |
| 36 | + exportSuccess: 'Export success', | |
| 37 | + exportFailed: 'Export failed' | |
| 38 | + } | |
| 39 | + }, | |
| 40 | + zh: { | |
| 41 | + reportFeeSummary: { | |
| 42 | + queryCondition: '查询条件', | |
| 43 | + selectStartDate: '请选择开始日期', | |
| 44 | + selectEndDate: '请选择结束日期', | |
| 45 | + inputRoomNumber: '请填写房屋编号', | |
| 46 | + inputOwnerName: '请填写业主名称', | |
| 47 | + inputOwnerPhone: '请填写业主手机号', | |
| 48 | + selectFeeType: '请选择费用大类', | |
| 49 | + selectCommunity: '请选择小区', | |
| 50 | + feeSummaryTable: '费用汇总表', | |
| 51 | + updateDaily: '按天更新', | |
| 52 | + totalRooms: '总户数', | |
| 53 | + chargeRooms: '收费户', | |
| 54 | + arrearsRooms: '欠费户', | |
| 55 | + arrearsFormula: '历史欠费+当期欠费=欠费', | |
| 56 | + historyArrears: '历史欠费', | |
| 57 | + currentArrears: '当期欠费', | |
| 58 | + totalArrears: '总欠费', | |
| 59 | + actualPaymentFormula: '欠费追回+当期部分+预交=实缴', | |
| 60 | + arrearsRecovery: '欠费追回', | |
| 61 | + currentPartial: '当期部分', | |
| 62 | + advancePayment: '预交', | |
| 63 | + actualPayment: '实缴', | |
| 64 | + currentReceivable: '当期应收', | |
| 65 | + currentActual: '当期实收', | |
| 66 | + roomChargeRate: '户收费率', | |
| 67 | + chargeRate: '收费率', | |
| 68 | + clearanceRate: '清缴率', | |
| 69 | + floorFeeSummary: '楼栋费用汇总', | |
| 70 | + configFeeSummary: '费用项汇总', | |
| 71 | + floorFeeRateStatistics: '楼栋收费率统计', | |
| 72 | + configFeeRateStatistics: '费用项收费率统计', | |
| 73 | + dateError: '开始日期必须早于结束日期', | |
| 74 | + exportSuccess: '导出成功', | |
| 75 | + exportFailed: '导出失败' | |
| 76 | + } | |
| 77 | + } | |
| 78 | +} | |
| 0 | 79 | \ No newline at end of file | ... | ... |
src/views/report/reportFeeSummaryList.vue
0 → 100644
| 1 | +<template> | |
| 2 | + <div class="report-fee-summary-container animated fadeInRight"> | |
| 3 | + <el-row class="flex justify-start"> | |
| 4 | + <el-col :span="2" class="padding-r-0"> | |
| 5 | + <select-community-floor ref="selectCommunityFloor" /> | |
| 6 | + </el-col> | |
| 7 | + <el-col :span="22"> | |
| 8 | + <el-card class="box-card"> | |
| 9 | + <div slot="header" class="flex justify-between"> | |
| 10 | + <span>{{ $t('reportFeeSummary.queryCondition') }}</span> | |
| 11 | + </div> | |
| 12 | + <div class="text item"> | |
| 13 | + <el-row :gutter="20"> | |
| 14 | + <el-col :span="4"> | |
| 15 | + <el-date-picker v-model="reportFeeSummaryInfo.conditions.startDate" type="date" | |
| 16 | + :placeholder="$t('reportFeeSummary.selectStartDate')" style="width: 100%" @change="handleDateChange" /> | |
| 17 | + </el-col> | |
| 18 | + <el-col :span="4"> | |
| 19 | + <el-date-picker v-model="reportFeeSummaryInfo.conditions.endDate" type="date" | |
| 20 | + :placeholder="$t('reportFeeSummary.selectEndDate')" style="width: 100%" @change="handleDateChange" /> | |
| 21 | + </el-col> | |
| 22 | + <el-col :span="4"> | |
| 23 | + <el-input v-model.trim="reportFeeSummaryInfo.conditions.objName" | |
| 24 | + :placeholder="$t('reportFeeSummary.inputRoomNumber')" clearable /> | |
| 25 | + </el-col> | |
| 26 | + <el-col :span="4"> | |
| 27 | + <el-input v-model.trim="reportFeeSummaryInfo.conditions.ownerName" | |
| 28 | + :placeholder="$t('reportFeeSummary.inputOwnerName')" clearable /> | |
| 29 | + </el-col> | |
| 30 | + <el-col :span="4"> | |
| 31 | + <el-input v-model.trim="reportFeeSummaryInfo.conditions.link" | |
| 32 | + :placeholder="$t('reportFeeSummary.inputOwnerPhone')" clearable /> | |
| 33 | + </el-col> | |
| 34 | + <el-col :span="4"> | |
| 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"> | |
| 40 | + <i class="el-icon-refresh"></i> | |
| 41 | + {{ $t('common.reset') }} | |
| 42 | + </el-button> | |
| 43 | + </el-col> | |
| 44 | + </el-row> | |
| 45 | + | |
| 46 | + <el-row :gutter="20" class="margin-top"> | |
| 47 | + <el-col :span="4"> | |
| 48 | + <el-select v-model="reportFeeSummaryInfo.conditions.feeTypeCd" | |
| 49 | + :placeholder="$t('reportFeeSummary.selectFeeType')" style="width: 100%" clearable> | |
| 50 | + <el-option v-for="(item, index) in reportFeeSummaryInfo.feeTypeCds" :key="index" :label="item.name" | |
| 51 | + :value="item.statusCd" /> | |
| 52 | + </el-select> | |
| 53 | + </el-col> | |
| 54 | + <el-col v-if="reportFeeSummaryInfo.communitys.length > 1" :span="4"> | |
| 55 | + <el-select v-model="reportFeeSummaryInfo.conditions.communityId" | |
| 56 | + :placeholder="$t('reportFeeSummary.selectCommunity')" style="width: 100%" @change="_changCommunity"> | |
| 57 | + <el-option v-for="(item, index) in reportFeeSummaryInfo.communitys" :key="index" :label="item.name" | |
| 58 | + :value="item.communityId" /> | |
| 59 | + </el-select> | |
| 60 | + </el-col> | |
| 61 | + </el-row> | |
| 62 | + | |
| 63 | + <el-row v-show="reportFeeSummaryInfo.moreCondition" class="margin-top"> | |
| 64 | + <el-col :span="24"> | |
| 65 | + <el-checkbox-group v-model="reportFeeSummaryInfo.configIds"> | |
| 66 | + <el-checkbox v-for="(item, index) in reportFeeSummaryInfo.feeConfigs" :key="index" | |
| 67 | + :label="item.configId"> | |
| 68 | + {{ item.feeName }} | |
| 69 | + </el-checkbox> | |
| 70 | + </el-checkbox-group> | |
| 71 | + </el-col> | |
| 72 | + </el-row> | |
| 73 | + </div> | |
| 74 | + </el-card> | |
| 75 | + | |
| 76 | + <el-card class="box-card margin-top"> | |
| 77 | + <div slot="header" class="flex justify-between"> | |
| 78 | + <div> | |
| 79 | + <span>{{ $t('reportFeeSummary.feeSummaryTable') }}</span> | |
| 80 | + <span class="el-icon-info popover-show" style="cursor: pointer;"></span> | |
| 81 | + <span>({{ $t('reportFeeSummary.updateDaily') }})</span> | |
| 82 | + </div> | |
| 83 | + <div style="float: right;"> | |
| 84 | + <el-button type="primary" size="small" @click="_exportExcel"> | |
| 85 | + <i class="el-icon-download"></i> | |
| 86 | + {{ $t('common.export') }} | |
| 87 | + </el-button> | |
| 88 | + </div> | |
| 89 | + </div> | |
| 90 | + <div class="text item"> | |
| 91 | + <el-table :data="reportFeeSummaryInfo.fees" border style="width: 100%"> | |
| 92 | + <el-table-column prop="roomCount" :label="$t('reportFeeSummary.totalRooms')" align="center" /> | |
| 93 | + <el-table-column prop="feeRoomCount" :label="$t('reportFeeSummary.chargeRooms')" align="center" /> | |
| 94 | + <el-table-column prop="oweRoomCount" :label="$t('reportFeeSummary.arrearsRooms')" align="center" /> | |
| 95 | + <el-table-column :label="$t('reportFeeSummary.arrearsFormula')" align="center" colspan="3"> | |
| 96 | + <el-table-column prop="hisOweFee" :label="$t('reportFeeSummary.historyArrears')" align="center" /> | |
| 97 | + <el-table-column prop="curOweFee" :label="$t('reportFeeSummary.currentArrears')" align="center" /> | |
| 98 | + <el-table-column :label="$t('reportFeeSummary.totalArrears')" align="center"> | |
| 99 | + <template slot-scope="scope"> | |
| 100 | + {{ (scope.row.curOweFee + scope.row.hisOweFee).toFixed(2) }} | |
| 101 | + </template> | |
| 102 | + </el-table-column> | |
| 103 | + </el-table-column> | |
| 104 | + <el-table-column :label="$t('reportFeeSummary.actualPaymentFormula')" align="center" colspan="4"> | |
| 105 | + <el-table-column prop="hisReceivedFee" :label="$t('reportFeeSummary.arrearsRecovery')" align="center" /> | |
| 106 | + <el-table-column :label="$t('reportFeeSummary.currentPartial')" align="center"> | |
| 107 | + <template slot-scope="scope"> | |
| 108 | + {{ (scope.row.receivedFee - scope.row.hisReceivedFee - scope.row.preReceivedFee).toFixed(2) }} | |
| 109 | + </template> | |
| 110 | + </el-table-column> | |
| 111 | + <el-table-column prop="preReceivedFee" :label="$t('reportFeeSummary.advancePayment')" align="center" /> | |
| 112 | + <el-table-column prop="receivedFee" :label="$t('reportFeeSummary.actualPayment')" align="center" /> | |
| 113 | + </el-table-column> | |
| 114 | + <el-table-column prop="curReceivableFee" :label="$t('reportFeeSummary.currentReceivable')" align="center" /> | |
| 115 | + <el-table-column :label="$t('reportFeeSummary.currentActual')" align="center"> | |
| 116 | + <template slot-scope="scope"> | |
| 117 | + {{ (scope.row.curReceivableFee - scope.row.curOweFee).toFixed(2) }} | |
| 118 | + </template> | |
| 119 | + </el-table-column> | |
| 120 | + <el-table-column :label="$t('reportFeeSummary.roomChargeRate')" align="center"> | |
| 121 | + <template slot-scope="scope"> | |
| 122 | + {{ scope.row.feeRoomCount > 0 ? (((scope.row.feeRoomCount - scope.row.oweRoomCount) / | |
| 123 | + scope.row.feeRoomCount * 100).toFixed(2) + '%') : '0%' }} | |
| 124 | + </template> | |
| 125 | + </el-table-column> | |
| 126 | + <el-table-column :label="$t('reportFeeSummary.chargeRate')" align="center"> | |
| 127 | + <template slot-scope="scope"> | |
| 128 | + {{ scope.row.curReceivableFee > 0 ? (((scope.row.curReceivableFee - scope.row.curOweFee) / | |
| 129 | + scope.row.curReceivableFee * 100).toFixed(2) + '%') : '0%' }} | |
| 130 | + </template> | |
| 131 | + </el-table-column> | |
| 132 | + <el-table-column :label="$t('reportFeeSummary.clearanceRate')" align="center"> | |
| 133 | + <template slot-scope="scope"> | |
| 134 | + {{ (scope.row.hisReceivedFee + scope.row.hisOweFee) > 0 ? ((scope.row.hisReceivedFee / | |
| 135 | + (scope.row.hisReceivedFee + scope.row.hisOweFee) * 100).toFixed(2) + '%') : '0%' }} | |
| 136 | + </template> | |
| 137 | + </el-table-column> | |
| 138 | + </el-table> | |
| 139 | + </div> | |
| 140 | + </el-card> | |
| 141 | + | |
| 142 | + <div class="margin-top"> | |
| 143 | + <floor-fee-summary ref="floorFeeSummary" /> | |
| 144 | + </div> | |
| 145 | + <div class="margin-top"> | |
| 146 | + <config-fee-summary ref="configFeeSummary" /> | |
| 147 | + </div> | |
| 148 | + </el-col> | |
| 149 | + </el-row> | |
| 150 | + </div> | |
| 151 | +</template> | |
| 152 | + | |
| 153 | +<script> | |
| 154 | +import { getDict, getCommunityId } from '@/api/community/communityApi' | |
| 155 | +import { queryReportFeeSummary, exportData, queryCommunitys, queryFeeConfigs } from '@/api/report/reportFeeSummaryApi' | |
| 156 | +import SelectCommunityFloor from '@/components/report/selectCommunityFloor' | |
| 157 | +import FloorFeeSummary from '@/components/report/floorFeeSummary' | |
| 158 | +import ConfigFeeSummary from '@/components/report/configFeeSummary' | |
| 159 | + | |
| 160 | +export default { | |
| 161 | + name: 'ReportFeeSummaryList', | |
| 162 | + components: { | |
| 163 | + SelectCommunityFloor, | |
| 164 | + FloorFeeSummary, | |
| 165 | + ConfigFeeSummary | |
| 166 | + }, | |
| 167 | + data() { | |
| 168 | + return { | |
| 169 | + reportFeeSummaryInfo: { | |
| 170 | + fees: [], | |
| 171 | + feeConfigs: [], | |
| 172 | + floors: [], | |
| 173 | + configIds: [], | |
| 174 | + feeTypeCds: [], | |
| 175 | + communitys: [], | |
| 176 | + moreCondition: false, | |
| 177 | + conditions: { | |
| 178 | + floorId: '', | |
| 179 | + objName: '', | |
| 180 | + startDate: '', | |
| 181 | + endDate: '', | |
| 182 | + configId: '', | |
| 183 | + feeTypeCd: '', | |
| 184 | + ownerName: '', | |
| 185 | + link: '', | |
| 186 | + communityId: '' | |
| 187 | + } | |
| 188 | + } | |
| 189 | + } | |
| 190 | + }, | |
| 191 | + created() { | |
| 192 | + this.initData() | |
| 193 | + }, | |
| 194 | + methods: { | |
| 195 | + async initData() { | |
| 196 | + this.reportFeeSummaryInfo.conditions.communityId = await getCommunityId() | |
| 197 | + this._initDate() | |
| 198 | + this._loadStaffCommunitys() | |
| 199 | + this._listFeeConfigs() | |
| 200 | + this.getFeeTypeDict() | |
| 201 | + this.$refs.selectCommunityFloor.open({ | |
| 202 | + callBack: (floor) => { | |
| 203 | + this.reportFeeSummaryInfo.conditions.floorId = floor.floorId | |
| 204 | + this._listFees() | |
| 205 | + } | |
| 206 | + }) | |
| 207 | + this._listFees() | |
| 208 | + }, | |
| 209 | + _initDate() { | |
| 210 | + const now = new Date() | |
| 211 | + const year = now.getFullYear() | |
| 212 | + const month = now.getMonth() + 1 | |
| 213 | + const lastDay = new Date(year, month, 0).getDate() | |
| 214 | + | |
| 215 | + this.reportFeeSummaryInfo.conditions.startDate = `${year}-${month.toString().padStart(2, '0')}-01` | |
| 216 | + this.reportFeeSummaryInfo.conditions.endDate = `${year}-${month.toString().padStart(2, '0')}-${lastDay}` | |
| 217 | + }, | |
| 218 | + handleDateChange() { | |
| 219 | + if (this.reportFeeSummaryInfo.conditions.startDate && this.reportFeeSummaryInfo.conditions.endDate) { | |
| 220 | + const start = new Date(this.reportFeeSummaryInfo.conditions.startDate) | |
| 221 | + const end = new Date(this.reportFeeSummaryInfo.conditions.endDate) | |
| 222 | + | |
| 223 | + if (start > end) { | |
| 224 | + this.$message.error(this.$t('reportFeeSummary.dateError')) | |
| 225 | + this.reportFeeSummaryInfo.conditions.endDate = '' | |
| 226 | + } | |
| 227 | + } | |
| 228 | + }, | |
| 229 | + async getFeeTypeDict() { | |
| 230 | + try { | |
| 231 | + this.reportFeeSummaryInfo.feeTypeCds = await getDict('pay_fee_config', 'fee_type_cd') | |
| 232 | + } catch (error) { | |
| 233 | + console.error('Failed to get fee type dict:', error) | |
| 234 | + } | |
| 235 | + }, | |
| 236 | + async _listFees() { | |
| 237 | + try { | |
| 238 | + const params = { | |
| 239 | + page: 1, | |
| 240 | + row: 100, | |
| 241 | + ...this.reportFeeSummaryInfo.conditions, | |
| 242 | + configIds: this.reportFeeSummaryInfo.configIds.join(',') | |
| 243 | + } | |
| 244 | + | |
| 245 | + const { data } = await queryReportFeeSummary(params) | |
| 246 | + this.reportFeeSummaryInfo.fees = data | |
| 247 | + | |
| 248 | + // Notify child components | |
| 249 | + this.$refs.floorFeeSummary.notify(params) | |
| 250 | + this.$refs.configFeeSummary.notify(params) | |
| 251 | + } catch (error) { | |
| 252 | + console.error('Failed to query fee summary:', error) | |
| 253 | + } | |
| 254 | + }, | |
| 255 | + async _loadStaffCommunitys() { | |
| 256 | + try { | |
| 257 | + const { data } = await queryCommunitys() | |
| 258 | + this.reportFeeSummaryInfo.communitys = data.communitys | |
| 259 | + } catch (error) { | |
| 260 | + console.error('Failed to load communities:', error) | |
| 261 | + } | |
| 262 | + }, | |
| 263 | + async _listFeeConfigs() { | |
| 264 | + try { | |
| 265 | + const params = { | |
| 266 | + page: 1, | |
| 267 | + row: 100, | |
| 268 | + communityId: this.reportFeeSummaryInfo.conditions.communityId, | |
| 269 | + isDefault: 'F' | |
| 270 | + } | |
| 271 | + | |
| 272 | + const { data } = await queryFeeConfigs(params) | |
| 273 | + this.reportFeeSummaryInfo.feeConfigs = data.feeConfigs | |
| 274 | + } catch (error) { | |
| 275 | + console.error('Failed to list fee configs:', error) | |
| 276 | + } | |
| 277 | + }, | |
| 278 | + _queryMethod() { | |
| 279 | + this._listFees() | |
| 280 | + }, | |
| 281 | + _resetMethod() { | |
| 282 | + this.reportFeeSummaryInfo.conditions = { | |
| 283 | + ...this.reportFeeSummaryInfo.conditions, | |
| 284 | + roomNum: '', | |
| 285 | + ownerName: '', | |
| 286 | + link: '', | |
| 287 | + feeTypeCd: '', | |
| 288 | + floorName: '', | |
| 289 | + floorId: '', | |
| 290 | + unitId: '', | |
| 291 | + configId: '' | |
| 292 | + } | |
| 293 | + this.reportFeeSummaryInfo.configIds = [] | |
| 294 | + this._listFees() | |
| 295 | + }, | |
| 296 | + async _exportExcel() { | |
| 297 | + try { | |
| 298 | + const params = { | |
| 299 | + ...this.reportFeeSummaryInfo.conditions, | |
| 300 | + pagePath: 'reportFeeSummary' | |
| 301 | + } | |
| 302 | + | |
| 303 | + await exportData(params) | |
| 304 | + this.$message.success(this.$t('reportFeeSummary.exportSuccess')) | |
| 305 | + this.$router.push('/pages/property/downloadTempFile?tab=下载中心') | |
| 306 | + } catch (error) { | |
| 307 | + console.error('Failed to export:', error) | |
| 308 | + this.$message.error(this.$t('reportFeeSummary.exportFailed')) | |
| 309 | + } | |
| 310 | + }, | |
| 311 | + _changCommunity() { | |
| 312 | + this._listFeeConfigs() | |
| 313 | + this._listFees() | |
| 314 | + } | |
| 315 | + } | |
| 316 | +} | |
| 317 | +</script> | |
| 318 | + | |
| 319 | +<style lang="scss" scoped> | |
| 320 | +.report-fee-summary-container { | |
| 321 | + padding: 20px; | |
| 322 | + | |
| 323 | + .margin-top { | |
| 324 | + margin-top: 20px; | |
| 325 | + } | |
| 326 | + | |
| 327 | + .padding-r-0 { | |
| 328 | + padding-right: 0; | |
| 329 | + } | |
| 330 | + | |
| 331 | + .popover-show { | |
| 332 | + margin-left: 10px; | |
| 333 | + color: #409EFF; | |
| 334 | + } | |
| 335 | + | |
| 336 | + .el-checkbox { | |
| 337 | + margin-right: 15px; | |
| 338 | + } | |
| 339 | +} | |
| 340 | +</style> | |
| 0 | 341 | \ No newline at end of file | ... | ... |