Commit 1a0bdbe025604dd113bb78e2838f6d6556abaa12

Authored by wuxw
1 parent 0f149ba1

优化缴费页面

src/api/fee/payFeeOrderApi.js 0 → 100644
  1 +import request from '@/utils/request'
  2 +import { getCommunityId } from '@/api/community/communityApi'
  3 +
  4 +// 查询费用对象信息
  5 +export function listFeeObj(params) {
  6 + return new Promise( (resolve, reject) => {
  7 + try {
  8 + const communityId = getCommunityId()
  9 + const response = request({
  10 + url: '/feeApi/listFeeObj',
  11 + method: 'get',
  12 + params: {
  13 + ...params,
  14 + communityId
  15 + }
  16 + })
  17 + resolve(response.data)
  18 + } catch (error) {
  19 + reject(error)
  20 + }
  21 + })
  22 +}
  23 +
  24 +// 计算费用折扣
  25 +export function computeFeeDiscount(params) {
  26 + return new Promise( (resolve, reject) => {
  27 + try {
  28 + const communityId = getCommunityId()
  29 + const response = request({
  30 + url: '/feeDiscount/computeFeeDiscount',
  31 + method: 'get',
  32 + params: {
  33 + ...params,
  34 + communityId
  35 + }
  36 + })
  37 + resolve(response.data)
  38 + } catch (error) {
  39 + reject(error)
  40 + }
  41 + })
  42 +}
  43 +
  44 +// 计算缴费优惠券
  45 +export function computePayFeeCoupon(params) {
  46 + return new Promise( (resolve, reject) => {
  47 + try {
  48 + const communityId = getCommunityId()
  49 + const response = request({
  50 + url: '/coupon.computePayFeeCoupon',
  51 + method: 'get',
  52 + params: {
  53 + ...params,
  54 + communityId
  55 + }
  56 + })
  57 + resolve(response.data)
  58 + } catch (error) {
  59 + reject(error)
  60 + }
  61 + })
  62 +}
  63 +
  64 +// 查询用户账户
  65 +export function queryCommunityOwnerAccount(params) {
  66 + return new Promise( (resolve, reject) => {
  67 + try {
  68 + const communityId = getCommunityId()
  69 + const response = request({
  70 + url: '/account.queryCommunityOwnerAccount',
  71 + method: 'get',
  72 + params: {
  73 + ...params,
  74 + communityId
  75 + }
  76 + })
  77 + resolve(response.data)
  78 + } catch (error) {
  79 + reject(error)
  80 + }
  81 + })
  82 +}
  83 +
  84 +// 查询押金信息
  85 +export function queryFeeDeposit(params) {
  86 + return new Promise( (resolve, reject) => {
  87 + try {
  88 + const communityId = getCommunityId()
  89 + const response = request({
  90 + url: '/fee.queryFeeDeposit',
  91 + method: 'get',
  92 + params: {
  93 + ...params,
  94 + communityId,
  95 + state: '1400'
  96 + }
  97 + })
  98 + resolve(response.data)
  99 + } catch (error) {
  100 + reject(error)
  101 + }
  102 + })
  103 +}
  104 +
  105 +// 退押金
  106 +export function refundFeeDeposit(data) {
  107 + return new Promise( (resolve, reject) => {
  108 + try {
  109 + data.communityId = getCommunityId()
  110 + const response = request({
  111 + url: '/fee.refundFeeDeposit',
  112 + method: 'post',
  113 + data
  114 + })
  115 + resolve(response.data)
  116 + } catch (error) {
  117 + reject(error)
  118 + }
  119 + })
  120 +}
  121 +
  122 +// 缴费
  123 +export function payFee(data) {
  124 + return new Promise( (resolve, reject) => {
  125 + try {
  126 + data.communityId = getCommunityId()
  127 + const response = request({
  128 + url: '/fee.payFee',
  129 + method: 'post',
  130 + data
  131 + })
  132 + resolve(response.data)
  133 + } catch (error) {
  134 + reject(error)
  135 + }
  136 + })
  137 +}
  138 +
  139 +// 扫码支付
  140 +export function qrCodePayment(data) {
  141 + return new Promise( (resolve, reject) => {
  142 + try {
  143 + data.communityId = getCommunityId()
  144 + data.subServiceCode = 'fee.payFee'
  145 + const response = request({
  146 + url: '/payment.qrCodePayment',
  147 + method: 'post',
  148 + data
  149 + })
  150 + resolve(response.data)
  151 + } catch (error) {
  152 + reject(error)
  153 + }
  154 + })
  155 +}
  156 +
  157 +// 检查支付状态
  158 +export function checkPayFinish(data) {
  159 + return new Promise( (resolve, reject) => {
  160 + try {
  161 + data.communityId = getCommunityId()
  162 + data.subServiceCode = 'fee.payFee'
  163 + const response = request({
  164 + url: '/payment.checkPayFinish',
  165 + method: 'post',
  166 + data
  167 + })
  168 + resolve(response.data)
  169 + } catch (error) {
  170 + reject(error)
  171 + }
  172 + })
  173 +}
  174 +
  175 +// 查询收据
  176 +export function queryFeeReceipt(params) {
  177 + return new Promise( (resolve, reject) => {
  178 + try {
  179 + const communityId = getCommunityId()
  180 + const response = request({
  181 + url: '/feeReceipt/queryFeeReceipt',
  182 + method: 'get',
  183 + params: {
  184 + ...params,
  185 + communityId
  186 + }
  187 + })
  188 + resolve(response.data)
  189 + } catch (error) {
  190 + reject(error)
  191 + }
  192 + })
  193 +}
  194 +
  195 +// 查询打印页面
  196 +export function listFeePrintPages(params) {
  197 + return new Promise( (resolve, reject) => {
  198 + try {
  199 + const communityId = getCommunityId()
  200 + const response = request({
  201 + url: '/feePrintPage.listFeePrintPage',
  202 + method: 'get',
  203 + params: {
  204 + ...params,
  205 + communityId,
  206 + state: 'T'
  207 + }
  208 + })
  209 + resolve(response.data)
  210 + } catch (error) {
  211 + reject(error)
  212 + }
  213 + })
  214 +}
  215 +
  216 +// 业主预存账户
  217 +export function ownerPrestoreAccount(data) {
  218 + return new Promise( (resolve, reject) => {
  219 + try {
  220 + data.communityId = getCommunityId()
  221 + const response = request({
  222 + url: '/account.ownerPrestoreAccount',
  223 + method: 'post',
  224 + data
  225 + })
  226 + resolve(response.data)
  227 + } catch (error) {
  228 + reject(error)
  229 + }
  230 + })
  231 +}
  232 +
  233 +// 查询房间信息
  234 +export function queryRooms(params) {
  235 + return new Promise( (resolve, reject) => {
  236 + try {
  237 + const communityId = getCommunityId()
  238 + const response = request({
  239 + url: '/room.queryRooms',
  240 + method: 'get',
  241 + params: {
  242 + ...params,
  243 + communityId
  244 + }
  245 + })
  246 + resolve(response.data)
  247 + } catch (error) {
  248 + reject(error)
  249 + }
  250 + })
  251 +}
  252 +
  253 +// 查询费用信息
  254 +export function listFee(params) {
  255 + return new Promise( (resolve, reject) => {
  256 + try {
  257 + const communityId = getCommunityId()
  258 + const response = request({
  259 + url: '/fee.listFee',
  260 + method: 'get',
  261 + params: {
  262 + ...params,
  263 + communityId
  264 + }
  265 + })
  266 + resolve(response.data)
  267 + } catch (error) {
  268 + reject(error)
  269 + }
  270 + })
  271 +}
  272 +
  273 +// 查询费用配置
  274 +export function listFeeConfigs(params) {
  275 + return new Promise( (resolve, reject) => {
  276 + try {
  277 + const communityId = getCommunityId()
  278 + const response = request({
  279 + url: '/feeConfig.listFeeConfigs',
  280 + method: 'get',
  281 + params: {
  282 + ...params,
  283 + communityId
  284 + }
  285 + })
  286 + resolve(response.data)
  287 + } catch (error) {
  288 + reject(error)
  289 + }
  290 + })
  291 +}
  292 +
  293 +// 计算缴费积分
  294 +export function computePayFeeIntegral(params) {
  295 + return new Promise( (resolve, reject) => {
  296 + try {
  297 + const communityId = getCommunityId()
  298 + const response = request({
  299 + url: '/integral.computePayFeeIntegral',
  300 + method: 'get',
  301 + params: {
  302 + ...params,
  303 + communityId
  304 + }
  305 + })
  306 + resolve(response.data)
  307 + } catch (error) {
  308 + reject(error)
  309 + }
  310 + })
  311 +}
0 312 \ No newline at end of file
... ...
src/components/fee/payFeeCoupon.vue 0 → 100644
  1 +<template>
  2 + <el-dialog
  3 + :title="$t('payFeeCoupon.title')"
  4 + :visible.sync="dialogVisible"
  5 + width="70%"
  6 + @close="handleClose"
  7 + >
  8 + <el-card v-if="feeCoupons.length > 0">
  9 + <div slot="header" class="clearfix">
  10 + <span>{{ $t('payFeeCoupon.couponInfo') }}</span>
  11 + </div>
  12 +
  13 + <el-table
  14 + :data="feeCoupons"
  15 + border
  16 + style="width: 100%"
  17 + >
  18 + <el-table-column
  19 + prop="ruleName"
  20 + align="center"
  21 + :label="$t('payFeeCoupon.ruleName')"
  22 + />
  23 + <el-table-column
  24 + prop="couponName"
  25 + align="center"
  26 + :label="$t('payFeeCoupon.couponName')"
  27 + />
  28 + <el-table-column
  29 + prop="quantity"
  30 + align="center"
  31 + :label="$t('payFeeCoupon.quantity')"
  32 + >
  33 + <template slot-scope="scope">
  34 + {{ scope.row.quantity }}{{ $t('payFeeCoupon.unit') }}
  35 + </template>
  36 + </el-table-column>
  37 + <el-table-column
  38 + prop="toTypeName"
  39 + align="center"
  40 + :label="$t('payFeeCoupon.purpose')"
  41 + />
  42 + </el-table>
  43 + </el-card>
  44 + </el-dialog>
  45 +</template>
  46 +
  47 +<script>
  48 +import { getCommunityId } from '@/api/community/communityApi'
  49 +
  50 +export default {
  51 + name: 'PayFeeCoupon',
  52 + data() {
  53 + return {
  54 + dialogVisible: false,
  55 + feeCoupons: [],
  56 + feeId: '',
  57 + communityId: '',
  58 + cycles: 1,
  59 + endTime: ''
  60 + }
  61 + },
  62 + methods: {
  63 + open(params) {
  64 + this.feeId = params.feeId
  65 + this.cycles = params.cycles || 1
  66 + this.endTime = params.endTime || ''
  67 + this.listFeeCoupons()
  68 + this.dialogVisible = true
  69 + },
  70 + close() {
  71 + this.dialogVisible = false
  72 + },
  73 + async listFeeCoupons() {
  74 + try {
  75 + this.communityId = await getCommunityId()
  76 + const params = {
  77 + page: 1,
  78 + row: 20,
  79 + feeId: this.feeId,
  80 + communityId: this.communityId,
  81 + cycles: this.cycles,
  82 + endTime: this.endTime
  83 + }
  84 +
  85 + const response = await this.$http.get('/coupon.computePayFeeCoupon', { params })
  86 + this.feeCoupons = response.data.data || []
  87 + } catch (error) {
  88 + console.error('查询优惠券信息失败:', error)
  89 + }
  90 + },
  91 + handleClose() {
  92 + this.feeCoupons = []
  93 + }
  94 + }
  95 +}
  96 +</script>
  97 +
  98 +<style scoped>
  99 +.el-table {
  100 + margin-top: 20px;
  101 +}
  102 +</style>
0 103 \ No newline at end of file
... ...
src/components/fee/payFeeDeposit.vue
1 1 <template>
2   - <el-card v-if="payFeeDepositInfo.fees.length > 0" class="deposit-card">
3   - <div slot="header" class="clearfix">
4   - <span>{{ $t('payFeeDeposit.title') }}</span>
5   - <el-button type="primary" size="small" class="float-right" @click="_queryPayFeeDeposit">
6   - <i class="el-icon-refresh"></i>
7   - {{ $t('common.refresh') }}
8   - </el-button>
9   - </div>
  2 + <el-dialog :title="$t('payFeeDeposit.title')" :visible.sync="dialogVisible" width="80%" @close="handleClose">
  3 + <el-card v-if="fees.length > 0">
  4 + <div slot="header" class="clearfix">
  5 + <span>{{ $t('payFeeDeposit.depositInfo') }}</span>
  6 + <el-button type="primary" size="small" style="float: right;" @click="queryPayFeeDeposit">
  7 + <i class="el-icon-refresh"></i>
  8 + {{ $t('payFeeDeposit.refresh') }}
  9 + </el-button>
  10 + </div>
10 11  
11   - <el-table :data="payFeeDepositInfo.fees" border style="width: 100%" v-loading="loading">
12   - <el-table-column prop="payerObjName" :label="$t('payFeeDeposit.payerObj')" align="center"></el-table-column>
13   - <el-table-column prop="feeName" :label="$t('payFeeDeposit.feeItem')" align="center"></el-table-column>
14   - <el-table-column :label="$t('payFeeDeposit.timePeriod')" align="center" width="220">
15   - <template slot-scope="scope">
16   - {{ scope.row.startTime }} ~ {{ scope.row.endTime }}
17   - </template>
18   - </el-table-column>
19   - <el-table-column prop="receivedAmount" :label="$t('payFeeDeposit.amount')" align="center"></el-table-column>
20   - <el-table-column prop="createTime" :label="$t('payFeeDeposit.payTime')" align="center"
21   - width="180"></el-table-column>
22   - <el-table-column :label="$t('common.operation')" align="center" width="120">
23   - <template slot-scope="scope">
24   - <el-button type="primary" size="mini" @click="_openRefundDeposit(scope.row)">
25   - {{ $t('payFeeDeposit.refund') }}
26   - </el-button>
27   - </template>
28   - </el-table-column>
29   - </el-table>
  12 + <el-table :data="fees" border style="width: 100%">
  13 + <el-table-column prop="payerObjName" align="center" :label="$t('payFeeDeposit.payerObj')" />
  14 + <el-table-column prop="feeName" align="center" :label="$t('payFeeDeposit.feeName')" />
  15 + <el-table-column align="center" :label="$t('payFeeDeposit.timeRange')">
  16 + <template slot-scope="scope">
  17 + {{ scope.row.startTime }}~{{ scope.row.endTime }}
  18 + </template>
  19 + </el-table-column>
  20 + <el-table-column prop="receivedAmount" align="center" :label="$t('payFeeDeposit.amount')" />
  21 + <el-table-column prop="createTime" align="center" :label="$t('payFeeDeposit.paymentTime')" />
  22 + <el-table-column align="center" :label="$t('payFeeDeposit.operation')" width="120">
  23 + <template slot-scope="scope">
  24 + <el-button type="primary" size="mini" @click="openRefundDeposit(scope.row)">
  25 + {{ $t('payFeeDeposit.refund') }}
  26 + </el-button>
  27 + </template>
  28 + </el-table-column>
  29 + </el-table>
  30 + </el-card>
30 31  
31 32 <refund-deposit-fee ref="refundDepositFee"></refund-deposit-fee>
32   - </el-card>
  33 + </el-dialog>
33 34 </template>
34 35  
35 36 <script>
36 37 import { getCommunityId } from '@/api/community/communityApi'
37   -import { queryFeeDeposit } from '@/api/fee/batchPayFeeOrderApi'
38 38 import RefundDepositFee from './refundDepositFee'
39 39  
40 40 export default {
... ... @@ -44,68 +44,63 @@ export default {
44 44 },
45 45 data() {
46 46 return {
47   - loading: false,
48   - payFeeDepositInfo: {
49   - fees: [],
50   - payerObjId: '',
51   - payerObjType: '',
52   - ownerId: '',
53   - communityId: ''
54   - }
  47 + dialogVisible: false,
  48 + fees: [],
  49 + payerObjId: '',
  50 + payerObjType: '',
  51 + ownerId: '',
  52 + communityId: ''
55 53 }
56 54 },
57   - created() {
58   - this.payFeeDepositInfo.communityId = getCommunityId()
59   - },
60 55 methods: {
61   - async _listFeeDeposit(page = 1, rows = 20) {
62   - this.loading = true
  56 + open(params) {
  57 + this.payerObjId = params.payerObjId
  58 + this.payerObjType = params.payerObjType
  59 + this.ownerId = params.ownerId || ''
  60 + this.listFeeDeposit()
  61 + this.dialogVisible = true
  62 + },
  63 + close() {
  64 + this.dialogVisible = false
  65 + },
  66 + async listFeeDeposit() {
63 67 try {
  68 + this.communityId = await getCommunityId()
64 69 const params = {
65   - page,
66   - row: rows,
67   - payerObjId: this.payFeeDepositInfo.payerObjId,
68   - ownerId: this.payFeeDepositInfo.ownerId,
69   - communityId: this.payFeeDepositInfo.communityId,
  70 + page: 1,
  71 + row: 20,
  72 + payerObjId: this.payerObjId,
  73 + ownerId: this.ownerId,
  74 + communityId: this.communityId,
70 75 state: '1400'
71 76 }
72 77  
73   - const res = await queryFeeDeposit(params)
74   - if (res.code === 0) {
75   - this.payFeeDepositInfo.fees = res.data || []
  78 + const response = await this.$http.get('/fee.queryFeeDeposit', { params })
  79 + if (response.data.code === 0) {
  80 + this.fees = response.data.data || []
76 81 }
77 82 } catch (error) {
78   - console.error('请求失败:', error)
79   - } finally {
80   - this.loading = false
  83 + console.error('查询押金信息失败:', error)
81 84 }
82 85 },
83   -
84   - _queryPayFeeDeposit() {
85   - this._listFeeDeposit()
  86 + queryPayFeeDeposit() {
  87 + this.listFeeDeposit()
86 88 },
87   -
88   - _openRefundDeposit(fee) {
  89 + openRefundDeposit(fee) {
89 90 this.$refs.refundDepositFee.open(fee)
90 91 },
91   -
92   - open(params) {
93   - this.payFeeDepositInfo = {
94   - ...this.payFeeDepositInfo,
95   - ...params
96   - }
97   - this._listFeeDeposit()
98   - },
99   -
100   - refresh() {
101   - this._listFeeDeposit()
  92 + handleClose() {
  93 + this.fees = []
  94 + this.payerObjId = ''
  95 + this.payerObjType = ''
  96 + this.ownerId = ''
102 97 }
103 98 }
104 99 }
105 100 </script>
106 101  
107   -<style lang="scss" scoped>
108   -.deposit-card {
109   - margin-bottom: 20px;
  102 +<style scoped>
  103 +.el-table {
  104 + margin-top: 20px;
110 105 }
111 106 </style>
112 107 \ No newline at end of file
... ...
src/components/fee/payFeeDiscount.vue 0 → 100644
  1 +<template>
  2 + <el-dialog
  3 + :title="$t('payFeeDiscount.title')"
  4 + :visible.sync="dialogVisible"
  5 + width="80%"
  6 + @close="handleClose"
  7 + >
  8 + <el-card v-if="shouldShowDiscounts">
  9 + <div slot="header" class="clearfix">
  10 + <span>{{ $t('payFeeDiscount.discountInfo') }}</span>
  11 + </div>
  12 +
  13 + <el-table
  14 + :data="feeDiscounts"
  15 + border
  16 + style="width: 100%"
  17 + >
  18 + <el-table-column
  19 + align="center"
  20 + width="60"
  21 + >
  22 + <template slot-scope="scope">
  23 + <el-checkbox
  24 + v-model="selectDiscountIds"
  25 + :label="scope.row.discountId"
  26 + @change="computeFeeDiscount"
  27 + ></el-checkbox>
  28 + </template>
  29 + </el-table-column>
  30 + <el-table-column
  31 + prop="discountType"
  32 + align="center"
  33 + :label="$t('payFeeDiscount.discountType')"
  34 + >
  35 + <template slot-scope="scope">
  36 + {{ getDiscountTypeName(scope.row.discountType) }}
  37 + </template>
  38 + </el-table-column>
  39 + <el-table-column
  40 + prop="discountName"
  41 + align="center"
  42 + :label="$t('payFeeDiscount.discountName')"
  43 + />
  44 + <el-table-column
  45 + prop="ruleName"
  46 + align="center"
  47 + :label="$t('payFeeDiscount.ruleName')"
  48 + />
  49 + <el-table-column
  50 + align="center"
  51 + :label="$t('payFeeDiscount.rule')"
  52 + >
  53 + <template slot-scope="scope">
  54 + <div v-for="(item,index) in scope.row.feeDiscountSpecs" :key="index">
  55 + {{ item.specName }}:{{ item.specValue }}
  56 + </div>
  57 + </template>
  58 + </el-table-column>
  59 + <el-table-column
  60 + align="center"
  61 + :label="$t('payFeeDiscount.discountAmount')"
  62 + >
  63 + <template slot="header">
  64 + <span>{{ $t('payFeeDiscount.discountAmount') }}</span>
  65 + <el-tooltip
  66 + effect="dark"
  67 + :content="$t('payFeeDiscount.discountTooltip')"
  68 + placement="top"
  69 + >
  70 + <i class="el-icon-info" style="margin-left:5px"></i>
  71 + </el-tooltip>
  72 + </template>
  73 + <template slot-scope="scope">
  74 + {{ formatDiscountPrice(scope.row) }}
  75 + <span>{{ $t('payFeeDiscount.yuan') }}</span>
  76 + </template>
  77 + </el-table-column>
  78 + </el-table>
  79 + </el-card>
  80 + </el-dialog>
  81 +</template>
  82 +
  83 +<script>
  84 +import { getCommunityId } from '@/api/community/communityApi'
  85 +import {dateAdd} from '@/utils/dateUtil'
  86 +
  87 +export default {
  88 + name: 'PayFeeDiscount',
  89 + data() {
  90 + return {
  91 + dialogVisible: false,
  92 + feeDiscounts: [],
  93 + feeId: '',
  94 + payerObjId: '',
  95 + payerObjType: '',
  96 + endTime: '',
  97 + custEndTime: '',
  98 + communityId: '',
  99 + cycles: 1,
  100 + selectDiscountIds: [],
  101 + totalDiscountMoney: 0.0
  102 + }
  103 + },
  104 + computed: {
  105 + shouldShowDiscounts() {
  106 + return (this.feeDiscounts.length > 0) ||
  107 + (this.selectDiscountIds.length === 0 && this.feeDiscounts.length !== 0) ||
  108 + (this.selectDiscountIds.length !== this.feeDiscounts.length && this.totalDiscountMoney === 0)
  109 + }
  110 + },
  111 + methods: {
  112 + open(params) {
  113 + this.feeId = params.feeId
  114 + this.payerObjId = params.payerObjId
  115 + this.payerObjType = params.payerObjType
  116 + this.endTime = params.endTime
  117 + this.custEndTime = params.custEndTime
  118 + this.cycles = params.cycles || 1
  119 + this.listFeeDiscounts()
  120 + this.dialogVisible = true
  121 + },
  122 + close() {
  123 + this.dialogVisible = false
  124 + },
  125 + async listFeeDiscounts() {
  126 + try {
  127 + this.communityId = await getCommunityId()
  128 + let cycles = this.cycles
  129 +
  130 + const params = {
  131 + page: 1,
  132 + row: 20,
  133 + feeId: this.feeId,
  134 + communityId: this.communityId,
  135 + cycles,
  136 + payerObjId: this.payerObjId,
  137 + payerObjType: this.payerObjType,
  138 + endTime: this.endTime,
  139 + custEndTime: this.custEndTime ? dateAdd(this.custEndTime) : ''
  140 + }
  141 +
  142 + const response = await this.$http.get('/feeDiscount/computeFeeDiscount', { params })
  143 + this.feeDiscounts = response.data.data || []
  144 + this.selectDiscountIds = this.feeDiscounts.map(item => item.discountId)
  145 + this.computeFeeDiscount()
  146 + } catch (error) {
  147 + console.error('查询折扣信息失败:', error)
  148 + }
  149 + },
  150 + getDiscountTypeName(type) {
  151 + const types = {
  152 + '1001': this.$t('payFeeDiscount.discount'),
  153 + '2002': this.$t('payFeeDiscount.penalty'),
  154 + '3003': this.$t('payFeeDiscount.specialDiscount')
  155 + }
  156 + return types[type] || type
  157 + },
  158 + formatDiscountPrice(row) {
  159 + if (row.discountType === '1001' || row.discountType === '3003') {
  160 + return row.discountPrice < 0 ? row.discountPrice : row.discountPrice * -1
  161 + } else if (row.discountType === '2002') {
  162 + return row.discountPrice > 0 ? row.discountPrice : row.discountPrice * -1
  163 + }
  164 + return row.discountPrice
  165 + },
  166 + computeFeeDiscount() {
  167 + let totalDiscountMoney = 0.0
  168 + let selectDiscount = []
  169 +
  170 + this.selectDiscountIds.forEach(item => {
  171 + this.feeDiscounts.forEach(disItem => {
  172 + if (disItem.feeDiscountSpecs && disItem.feeDiscountSpecs.length > 0) {
  173 + let specValue = ""
  174 + disItem.feeDiscountSpecs.forEach(feeItem => {
  175 + if (feeItem.specName === this.$t('payFeeDiscount.monthSpec')) {
  176 + specValue = feeItem.specValue
  177 + }
  178 + })
  179 + if ((disItem.discountType === '1001' || disItem.discountType === '3003') &&
  180 + parseFloat(this.cycles) < parseFloat(specValue)) {
  181 + return
  182 + }
  183 + }
  184 +
  185 + if (item === disItem.discountId && disItem.discountPrice !== 0 && disItem.ruleId !== "102020008") {
  186 + if (disItem.feeDiscountSpecs && disItem.feeDiscountSpecs.length > 0) {
  187 + let specValue = ""
  188 + disItem.feeDiscountSpecs.forEach(feeItem => {
  189 + if (feeItem.specName === this.$t('payFeeDiscount.monthSpec')) {
  190 + specValue = feeItem.specValue
  191 + }
  192 + })
  193 + if (specValue && parseFloat(this.cycles) >= parseFloat(specValue)) {
  194 + totalDiscountMoney += parseFloat(disItem.discountPrice)
  195 + selectDiscount.push(disItem)
  196 + }
  197 +
  198 + specValue = ""
  199 + disItem.feeDiscountSpecs.forEach(feeItem => {
  200 + if (feeItem.specName === this.$t('payFeeDiscount.penaltySpec')) {
  201 + specValue = feeItem.specValue
  202 + }
  203 + })
  204 + if (specValue) {
  205 + totalDiscountMoney += parseFloat(disItem.discountPrice)
  206 + selectDiscount.push(disItem)
  207 + }
  208 + }
  209 + } else if (item === disItem.discountId && disItem.ruleId === "102020008") {
  210 + if (disItem.feeDiscountSpecs != null && disItem.feeDiscountSpecs != undefined &&
  211 + disItem.feeDiscountSpecs.length > 0) {
  212 + let specValue = ""
  213 + disItem.feeDiscountSpecs.forEach(feeItem => {
  214 + if (feeItem.specName === this.$t('payFeeDiscount.monthSpec')) {
  215 + specValue = feeItem.specValue
  216 + }
  217 + })
  218 + if (specValue !== "" && parseFloat(this.cycles) >= parseFloat(specValue)) {
  219 + selectDiscount.push(disItem)
  220 + }
  221 + }
  222 + }
  223 + })
  224 + })
  225 +
  226 + this.totalDiscountMoney = totalDiscountMoney
  227 + this.$emit('changeDiscountPrice', {
  228 + totalDiscountMoney,
  229 + selectDiscount
  230 + })
  231 + },
  232 + handleClose() {
  233 + this.feeDiscounts = []
  234 + this.selectDiscountIds = []
  235 + this.totalDiscountMoney = 0.0
  236 + }
  237 + }
  238 +}
  239 +</script>
  240 +
  241 +<style scoped>
  242 +.el-table {
  243 + margin-top: 20px;
  244 +}
  245 +</style>
0 246 \ No newline at end of file
... ...
src/components/fee/payFeeOrderConfirm.vue 0 → 100644
  1 +<template>
  2 + <el-dialog :title="$t('payFeeOrderConfirm.title')" :visible.sync="dialogVisible" width="50%" @close="handleClose"
  3 + :close-on-click-modal="false">
  4 + <el-form label-width="120px">
  5 + <el-form-item :label="$t('payFeeOrderConfirm.payerObj')">
  6 + <span>{{ formData.payerObjName }}</span>
  7 + </el-form-item>
  8 +
  9 + <el-form-item v-if="formData.feeFlag != '2006012' && formData.showEndTime != ''"
  10 + :label="$t('payFeeOrderConfirm.timeRange')">
  11 + <span>
  12 + {{ dateFormat(formData.endTime) }} 至
  13 + {{ dateFormat(formData.showEndTime) }}
  14 + </span>
  15 + </el-form-item>
  16 +
  17 + <el-form-item v-else-if="formData.feeFlag != '2006012' && formData.custEndTime != ''"
  18 + :label="$t('payFeeOrderConfirm.timeRange')">
  19 + <span>
  20 + {{ dateFormat(formData.endTime) }} 至
  21 + {{ formData.custEndTime }}
  22 + </span>
  23 + </el-form-item>
  24 +
  25 + <el-form-item :label="$t('payFeeOrderConfirm.receivable')">
  26 + <span>{{ formData.totalFeePrice }}</span>
  27 + </el-form-item>
  28 +
  29 + <el-form-item :label="$t('payFeeOrderConfirm.discountAmount')">
  30 + <el-tooltip effect="dark" :content="$t('payFeeOrderConfirm.discountTooltip')" placement="top">
  31 + <span>
  32 + {{ formData.totalDiscountMoney.toFixed(2) }}
  33 + </span>
  34 + </el-tooltip>
  35 + </el-form-item>
  36 +
  37 + <el-form-item :label="$t('payFeeOrderConfirm.actualAmount')">
  38 + <span v-if="formData.flag != null && formData.flag != '' && formData.flag == 'true'">
  39 + {{ formData.receivedAmountNumber }}
  40 + </span>
  41 + <span v-else>{{ formData.receivedAmount }}</span>
  42 + </el-form-item>
  43 +
  44 + <el-form-item :label="$t('payFeeOrderConfirm.deductionAmount')">
  45 + <span>
  46 + {{ formData.accountAmount >= formData.receivedAmount ?
  47 + formData.receivedAmount : formData.accountAmount.toFixed(2) }}
  48 + </span>
  49 + </el-form-item>
  50 +
  51 + <el-form-item :label="$t('payFeeOrderConfirm.amountPayable')">
  52 + <span>
  53 + {{ formData.accountAmount >= formData.receivedAmount ?
  54 + '0.00' : (formData.receivedAmount - formData.accountAmount).toFixed(2) }}
  55 + </span>
  56 + </el-form-item>
  57 +
  58 + <el-form-item v-if="formData.integralAmount != null && formData.integralAmount != ''"
  59 + :label="$t('payFeeOrderConfirm.integralDeduction')">
  60 + <span>{{ formData.integralAmount }}</span>
  61 + </el-form-item>
  62 +
  63 + <el-form-item v-if="formData.cashAmount != null && formData.cashAmount != ''"
  64 + :label="$t('payFeeOrderConfirm.cashDeduction')">
  65 + <span>{{ formData.cashAmount }}</span>
  66 + </el-form-item>
  67 +
  68 + <el-form-item :label="$t('payFeeOrderConfirm.remark')">
  69 + <span>{{ formData.remark }}</span>
  70 + </el-form-item>
  71 +
  72 + <el-form-item v-if="formData.payType == 'qrCode'" :label="$t('payFeeOrderConfirm.authCode')">
  73 + <el-input v-model="formData.authCode" :placeholder="$t('payFeeOrderConfirm.authCodePlaceholder')"
  74 + @keyup.enter.native="qrCodePayFee"></el-input>
  75 + </el-form-item>
  76 + </el-form>
  77 +
  78 + <div slot="footer" class="dialog-footer">
  79 + <el-button @click="closeDoPayFeeModal">{{ $t('payFeeOrderConfirm.close') }}</el-button>
  80 + <el-button v-if="formData.payType == 'common'" type="primary" @click="payFee">
  81 + {{ $t('payFeeOrderConfirm.confirm') }}
  82 + </el-button>
  83 + </div>
  84 + </el-dialog>
  85 +</template>
  86 +
  87 +<script>
  88 +import { qrCodePayment, checkPayFinish } from '@/api/fee/payFeeOrderApi'
  89 +import { dateFormat } from '@/utils/dateUtil'
  90 +export default {
  91 + name: 'PayFeeOrderConfirm',
  92 + data() {
  93 + return {
  94 + dialogVisible: false,
  95 + formData: {
  96 + totalDiscountMoney: 0.0,
  97 + accountAmount: 0.0,
  98 + payType: ''
  99 + }
  100 + }
  101 + },
  102 + methods: {
  103 + dateFormat,
  104 + open(params) {
  105 + this.formData = { ...params }
  106 + this.dialogVisible = true
  107 + if (this.formData.payType !== 'common') {
  108 + setTimeout(() => {
  109 + document.getElementById('authCode').focus()
  110 + }, 1000)
  111 + }
  112 + },
  113 + close() {
  114 + this.dialogVisible = false
  115 + },
  116 + closeDoPayFeeModal() {
  117 + this.close()
  118 + },
  119 + async qrCodePayFee() {
  120 + try {
  121 + // const printFees = [{
  122 + // feeId: this.formData.feeId,
  123 + // squarePrice: this.formData.squarePrice,
  124 + // additionalAmount: this.formData.additionalAmount,
  125 + // feeName: this.formData.feeName,
  126 + // amount: this.formData.receivedAmount,
  127 + // authCode: this.formData.authCode
  128 + // }]
  129 +
  130 + this.formData.subServiceCode = 'fee.payFee'
  131 +
  132 + const response = await qrCodePayment(this.formData)
  133 + const data = response.data
  134 +
  135 + if (data.code === 404) {
  136 + this.$message.error(data.msg)
  137 + if (data.data && data.data.orderId) {
  138 + this.formData.orderId = data.data.orderId
  139 + this.formData.paymentPoolId = data.data.paymentPoolId
  140 + setTimeout(() => {
  141 + this.qrCodeCheckPayFinish()
  142 + }, 5000)
  143 + }
  144 + return
  145 + }
  146 +
  147 + this.close()
  148 + this.$emit('success', data)
  149 + } catch (error) {
  150 + console.error('扫码支付失败:', error)
  151 + }
  152 + },
  153 + async qrCodeCheckPayFinish() {
  154 + try {
  155 + // const printFees = [{
  156 + // feeId: this.formData.feeId,
  157 + // squarePrice: this.formData.squarePrice,
  158 + // additionalAmount: this.formData.additionalAmount,
  159 + // feeName: this.formData.feeName,
  160 + // amount: this.formData.receivedAmount,
  161 + // authCode: this.formData.authCode,
  162 + // orderId: this.formData.orderId
  163 + // }]
  164 +
  165 + this.formData.subServiceCode = 'fee.payFee'
  166 +
  167 + const response = await checkPayFinish(this.formData)
  168 + const data = response.data
  169 +
  170 + if (data.code === 404) {
  171 + this.$message.error(data.msg)
  172 + return
  173 + } else if (data.code === 41) {
  174 + setTimeout(() => {
  175 + this.qrCodeCheckPayFinish()
  176 + }, 5000)
  177 + return
  178 + }
  179 +
  180 + this.close()
  181 + this.$emit('success', data.data)
  182 + } catch (error) {
  183 + console.error('检查支付状态失败:', error)
  184 + }
  185 + },
  186 + async payFee() {
  187 + try {
  188 + const response = await this.$http.post('/fee.payFee', this.formData)
  189 + const data = response.data
  190 +
  191 + if (data.code === 0) {
  192 + this.close()
  193 + this.$emit('success', data.data)
  194 + } else {
  195 + this.$message.error(data.msg)
  196 + }
  197 + } catch (error) {
  198 + console.error('缴费失败:', error)
  199 + }
  200 + },
  201 + handleClose() {
  202 + this.formData = {
  203 + totalDiscountMoney: 0.0,
  204 + accountAmount: 0.0,
  205 + payType: ''
  206 + }
  207 + }
  208 + }
  209 +}
  210 +</script>
  211 +
  212 +<style scoped>
  213 +.dialog-footer {
  214 + text-align: right;
  215 +}
  216 +</style>
0 217 \ No newline at end of file
... ...
src/components/fee/payFeeOrderResult.vue 0 → 100644
  1 +<template>
  2 + <el-dialog
  3 + :title="$t('payFeeOrderResult.title')"
  4 + :visible.sync="dialogVisible"
  5 + width="40%"
  6 + @close="handleClose"
  7 + :close-on-click-modal="false"
  8 + >
  9 + <div class="result-content">
  10 + <p>{{ $t('payFeeOrderResult.success') }}</p>
  11 + <p v-if="!receiptId">{{ $t('payFeeOrderResult.receiptTip') }}</p>
  12 + </div>
  13 +
  14 + <div slot="footer" class="dialog-footer">
  15 + <el-button @click="back">{{ $t('payFeeOrderResult.back') }}</el-button>
  16 + <el-button
  17 + v-if="receiptId"
  18 + type="primary"
  19 + @click="printSmallAndBack"
  20 + >
  21 + {{ $t('payFeeOrderResult.printSmall') }}
  22 + </el-button>
  23 + <el-button
  24 + v-if="receiptId"
  25 + type="primary"
  26 + @click="printAndBack('ON')"
  27 + >
  28 + {{ $t('payFeeOrderResult.mergePrint') }}
  29 + </el-button>
  30 + <el-button
  31 + v-if="receiptId"
  32 + type="primary"
  33 + @click="printAndBack('OFF')"
  34 + >
  35 + {{ $t('payFeeOrderResult.printReceipt') }}
  36 + </el-button>
  37 + </div>
  38 + </el-dialog>
  39 +</template>
  40 +
  41 +<script>
  42 +import { getCommunityId } from '@/api/community/communityApi'
  43 +
  44 +export default {
  45 + name: 'PayFeeOrderResult',
  46 + data() {
  47 + return {
  48 + dialogVisible: false,
  49 + receiptId: '',
  50 + printUrl: '/print.html#/pages/property/printPayFee'
  51 + }
  52 + },
  53 + created() {
  54 + this.listFeePrintPages()
  55 + },
  56 + methods: {
  57 + open(params) {
  58 + if (!params) {
  59 + this.dialogVisible = true
  60 + return
  61 + }
  62 + this.queryPayFeeReceiptId(params)
  63 + },
  64 + close() {
  65 + this.dialogVisible = false
  66 + },
  67 + async queryPayFeeReceiptId(params) {
  68 + try {
  69 + const communityId = await getCommunityId()
  70 + const response = await this.$http.get('/feeReceipt/queryFeeReceipt', {
  71 + params: {
  72 + detailIds: params.detailId,
  73 + communityId,
  74 + page: 1,
  75 + row: 1
  76 + }
  77 + })
  78 +
  79 + if (response.data.code === 0 && response.data.data && response.data.data.length > 0) {
  80 + this.receiptId = response.data.data[0].receiptId
  81 + }
  82 + this.dialogVisible = true
  83 + } catch (error) {
  84 + console.error('查询收据ID失败:', error)
  85 + }
  86 + },
  87 + async listFeePrintPages() {
  88 + try {
  89 + const communityId = await getCommunityId()
  90 + const response = await this.$http.get('/feePrintPage.listFeePrintPage', {
  91 + params: {
  92 + page: 1,
  93 + row: 1,
  94 + state: 'T',
  95 + communityId
  96 + }
  97 + })
  98 +
  99 + if (response.data.data && response.data.data.length > 0) {
  100 + this.printUrl = response.data.data[0].url
  101 + }
  102 + } catch (error) {
  103 + console.error('获取打印页面失败:', error)
  104 + }
  105 + },
  106 + printAndBack(merge) {
  107 + window.open(`${this.printUrl}?receiptId=${this.receiptId}&merge=${merge}`)
  108 + },
  109 + printSmallAndBack() {
  110 + window.open(`/smallPrint.html#/pages/property/printSmallPayFee?receiptId=${this.receiptId}`)
  111 + },
  112 + back() {
  113 + this.close()
  114 + this.$emit('back')
  115 + },
  116 + handleClose() {
  117 + this.receiptId = ''
  118 + }
  119 + }
  120 +}
  121 +</script>
  122 +
  123 +<style scoped>
  124 +.result-content {
  125 + text-align: center;
  126 + padding: 20px;
  127 +}
  128 +.dialog-footer {
  129 + text-align: center;
  130 +}
  131 +</style>
0 132 \ No newline at end of file
... ...
src/components/fee/payFeeUserAccount.vue
1 1 <template>
2   - <el-card v-if="payFeeUserAccountInfo.accountList.length > 0" class="account-card">
3   - <div slot="header" class="flex justify-between">
4   - <span>{{ $t('payFeeUserAccount.title') }}</span>
5   - <el-button type="primary" size="small" class="float-right" @click="_queryPayFeeUserAccount">
6   - <i class="el-icon-refresh"></i>
7   - {{ $t('common.refresh') }}
8   - </el-button>
9   - </div>
  2 + <el-dialog
  3 + :title="$t('payFeeUserAccount.title')"
  4 + :visible.sync="dialogVisible"
  5 + width="70%"
  6 + @close="handleClose"
  7 + >
  8 + <el-card v-if="accountList.length > 0">
  9 + <div slot="header" class="clearfix">
  10 + <span>{{ $t('payFeeUserAccount.accountInfo') }}</span>
  11 + <el-button
  12 + type="primary"
  13 + size="small"
  14 + style="float: right;"
  15 + @click="queryPayFeeUserAccount"
  16 + >
  17 + <i class="el-icon-refresh"></i>
  18 + {{ $t('payFeeUserAccount.refresh') }}
  19 + </el-button>
  20 + </div>
10 21  
11   - <el-table :data="payFeeUserAccountInfo.accountList" border style="width: 100%" v-loading="loading">
12   - <el-table-column width="55" align="center">
13   - <template slot-scope="scope">
14   - <el-radio v-model="payFeeUserAccountInfo.selectAccountIds" :label="scope.row.acctId"
15   - @change="_computeFeeUserAmount(scope.row)"></el-radio>
16   - </template>
17   - </el-table-column>
18   - <el-table-column prop="acctTypeName" :label="$t('payFeeUserAccount.accountType')"
19   - align="center"></el-table-column>
20   - <el-table-column prop="acctName" :label="$t('payFeeUserAccount.accountName')" align="center"></el-table-column>
21   - <el-table-column :label="$t('payFeeUserAccount.accountAmount')" align="center">
22   - <template slot-scope="scope">
23   - {{ scope.row.amount }} {{ $t('payFeeUserAccount.yuan') }}
24   - </template>
25   - </el-table-column>
26   - <el-table-column :label="$t('common.operation')" align="center" width="150">
27   - <template slot-scope="scope">
28   - <el-button type="primary" size="mini" @click="_openAddUserAmountModal(scope.row)">
29   - <i class="el-icon-plus"></i>
30   - {{ $t('payFeeUserAccount.preSave') }}
31   - </el-button>
32   - </template>
33   - </el-table-column>
34   - </el-table>
35   - </el-card>
  22 + <el-table
  23 + :data="accountList"
  24 + border
  25 + style="width: 100%"
  26 + >
  27 + <el-table-column
  28 + align="center"
  29 + :label="$t('payFeeUserAccount.select')"
  30 + width="80"
  31 + >
  32 + <template slot-scope="scope">
  33 + <el-radio
  34 + v-model="selectedAccount"
  35 + :label="scope.row.acctId"
  36 + @change="computeFeeUserAmount(scope.row.acctId)"
  37 + ></el-radio>
  38 + </template>
  39 + </el-table-column>
  40 + <el-table-column
  41 + prop="acctTypeName"
  42 + align="center"
  43 + :label="$t('payFeeUserAccount.accountType')"
  44 + />
  45 + <el-table-column
  46 + prop="acctName"
  47 + align="center"
  48 + :label="$t('payFeeUserAccount.accountName')"
  49 + />
  50 + <el-table-column
  51 + prop="amount"
  52 + align="center"
  53 + :label="$t('payFeeUserAccount.accountAmount')"
  54 + >
  55 + <template slot-scope="scope">
  56 + {{ scope.row.amount }} {{ $t('payFeeUserAccount.yuan') }}
  57 + </template>
  58 + </el-table-column>
  59 + <el-table-column
  60 + align="center"
  61 + :label="$t('payFeeUserAccount.operation')"
  62 + width="150"
  63 + >
  64 + <template slot-scope="scope">
  65 + <el-button
  66 + type="primary"
  67 + size="mini"
  68 + @click="openAddUserAmountModal(scope.row)"
  69 + >
  70 + <i class="el-icon-plus"></i>
  71 + {{ $t('payFeeUserAccount.prestore') }}
  72 + </el-button>
  73 + </template>
  74 + </el-table-column>
  75 + </el-table>
  76 + </el-card>
  77 + </el-dialog>
36 78 </template>
37 79  
38 80 <script>
39 81 import { getCommunityId } from '@/api/community/communityApi'
40   -import { queryCommunityOwnerAccount } from '@/api/fee/batchPayFeeOrderApi'
41 82  
42 83 export default {
43 84 name: 'PayFeeUserAccount',
44 85 data() {
45 86 return {
46   - loading: false,
47   - payFeeUserAccountInfo: {
48   - accountList: [],
49   - feeId: '',
50   - ownerId: '',
51   - communityId: '',
52   - quanAccount: false,
53   - selectAccountIds: [],
54   - integralAmount: '',
55   - cashAmount: '',
56   - couponAmount: ''
57   - }
  87 + dialogVisible: false,
  88 + accountList: [],
  89 + feeId: '',
  90 + ownerId: '',
  91 + communityId: '',
  92 + selectedAccount: null
58 93 }
59 94 },
60   - created() {
61   - this.payFeeUserAccountInfo.communityId = getCommunityId()
62   - },
63 95 methods: {
64   - async _listUserAccount(page = 1, rows = 20) {
65   - this.loading = true
  96 + open(params) {
  97 + this.feeId = params.feeId
  98 + this.ownerId = params.ownerId || ''
  99 + this.listUserAccount()
  100 + this.dialogVisible = true
  101 + },
  102 + close() {
  103 + this.dialogVisible = false
  104 + },
  105 + async listUserAccount() {
66 106 try {
  107 + this.communityId = await getCommunityId()
67 108 const params = {
68   - page,
69   - row: rows,
70   - feeId: this.payFeeUserAccountInfo.feeId,
71   - ownerId: this.payFeeUserAccountInfo.ownerId,
72   - communityId: this.payFeeUserAccountInfo.communityId
  109 + page: 1,
  110 + row: 20,
  111 + feeId: this.feeId,
  112 + ownerId: this.ownerId,
  113 + communityId: this.communityId
73 114 }
74 115  
75   - const res = await queryCommunityOwnerAccount(params)
76   - if (res.code === 0) {
77   - this.payFeeUserAccountInfo.accountList = res.data || []
78   - }
  116 + const response = await this.$http.get('/account.queryCommunityOwnerAccount', { params })
  117 + this.accountList = response.data.data || []
79 118 } catch (error) {
80   - console.error('请求失败:', error)
81   - } finally {
82   - this.loading = false
  119 + console.error('查询用户账户失败:', error)
83 120 }
84 121 },
85   -
86   - _queryPayFeeUserAccount() {
87   - this._listUserAccount()
  122 + queryPayFeeUserAccount() {
  123 + this.listUserAccount()
88 124 },
89   -
90   - _openAddUserAmountModal(userAccount) {
  125 + openAddUserAmountModal(userAccount) {
91 126 window.open(`/#/pages/owner/ownerDetail?ownerId=${userAccount.objId}&currentTab=ownerDetailAccount`)
92 127 },
93   -
94   - _computeFeeUserAmount(acct) {
95   - let _totalUserAmount = 0.0
96   - let _selectAccount = []
97   -
98   - this.payFeeUserAccountInfo.accountList.forEach(item => {
99   - if (acct.acctId === item.acctId && item.amount != 0) {
100   - _totalUserAmount += parseFloat(item.amount)
101   - _selectAccount.push(item)
102   - this.payFeeUserAccountInfo.cashAmount = item.amount
  128 + computeFeeUserAmount(acctId) {
  129 + let totalUserAmount = 0.0
  130 + let selectAccount = []
  131 +
  132 + this.accountList.forEach(item => {
  133 + if (acctId === item.acctId && item.amount != 0) {
  134 + totalUserAmount += parseFloat(item.amount)
  135 + selectAccount.push(item)
103 136 }
104 137 })
105 138  
106 139 this.$emit('changeUserAmountPrice', {
107   - totalUserAmount: _totalUserAmount,
108   - accountList: this.payFeeUserAccountInfo.accountList,
  140 + totalUserAmount,
  141 + accountList: this.accountList,
109 142 integralAmount: 0,
110   - cashAmount: this.payFeeUserAccountInfo.cashAmount,
  143 + cashAmount: totalUserAmount,
111 144 couponAmount: 0,
112   - selectAccount: _selectAccount
  145 + selectAccount
113 146 })
114 147 },
115   -
116   - open(params) {
117   - this.payFeeUserAccountInfo = {
118   - ...this.payFeeUserAccountInfo,
119   - ...params
120   - }
121   - this._listUserAccount()
122   - },
123   -
124   - refresh() {
125   - this._listUserAccount()
126   - },
127   -
128   - refreshAndChoose() {
129   - this.payFeeUserAccountInfo.accountList = []
130   - this.payFeeUserAccountInfo.selectAccountIds = []
131   - this._listUserAccount()
132   - setTimeout(() => {
133   - this.payFeeUserAccountInfo.accountList.forEach(item => {
134   - if (item.acctType === '2003') {
135   - this.payFeeUserAccountInfo.selectAccountIds.push(item.acctId)
136   - }
137   - })
138   - }, 2000)
139   - },
140   -
141   - clear() {
142   - this.payFeeUserAccountInfo.accountList = []
143   - this.payFeeUserAccountInfo.selectAccountIds = []
  148 + handleClose() {
  149 + this.accountList = []
  150 + this.selectedAccount = null
  151 + this.feeId = ''
  152 + this.ownerId = ''
144 153 }
145 154 }
146 155 }
147 156 </script>
148 157  
149   -<style lang="scss" scoped>
150   -.account-card {
151   - margin-bottom: 20px;
  158 +<style scoped>
  159 +.el-table {
  160 + margin-top: 20px;
152 161 }
153 162 </style>
154 163 \ No newline at end of file
... ...
src/components/fee/prestoreAccount2.vue 0 → 100644
  1 +<template>
  2 + <el-dialog
  3 + :title="$t('prestoreAccount2.title')"
  4 + :visible.sync="dialogVisible"
  5 + width="50%"
  6 + @close="handleClose"
  7 + >
  8 + <el-form :model="formData" :rules="rules" ref="form" label-width="120px">
  9 + <el-form-item :label="$t('prestoreAccount2.receivable')">
  10 + <el-input v-model="formData.totalAmount" disabled></el-input>
  11 + </el-form-item>
  12 +
  13 + <el-form-item :label="$t('prestoreAccount2.actualReceipt')">
  14 + <el-input
  15 + v-model="formData.receivedAmount"
  16 + @change="computedAmount"
  17 + ></el-input>
  18 + </el-form-item>
  19 +
  20 + <el-form-item :label="$t('prestoreAccount2.prestoreAmount')" prop="amount">
  21 + <el-input
  22 + v-model="formData.amount"
  23 + :placeholder="$t('prestoreAccount2.amountPlaceholder')"
  24 + ></el-input>
  25 + </el-form-item>
  26 +
  27 + <el-form-item :label="$t('prestoreAccount2.remark')" prop="remark">
  28 + <el-input
  29 + type="textarea"
  30 + v-model="formData.remark"
  31 + :placeholder="$t('prestoreAccount2.remarkPlaceholder')"
  32 + ></el-input>
  33 + </el-form-item>
  34 + </el-form>
  35 +
  36 + <div slot="footer" class="dialog-footer">
  37 + <el-button @click="dialogVisible = false">{{ $t('prestoreAccount2.cancel') }}</el-button>
  38 + <el-button type="primary" @click="savePrestoreAccount2Info">{{ $t('prestoreAccount2.save') }}</el-button>
  39 + </div>
  40 + </el-dialog>
  41 +</template>
  42 +
  43 +<script>
  44 +import { getCommunityId } from '@/api/community/communityApi'
  45 +
  46 +export default {
  47 + name: 'PrestoreAccount2',
  48 + data() {
  49 + return {
  50 + dialogVisible: false,
  51 + formData: {
  52 + tel: '',
  53 + ownerId: '',
  54 + owners: [],
  55 + amount: '',
  56 + remark: '',
  57 + receivedAmount: '',
  58 + redepositAmount: '',
  59 + totalAmount: '',
  60 + acctType: ''
  61 + },
  62 + rules: {
  63 + amount: [
  64 + { required: true, message: this.$t('prestoreAccount2.amountRequired'), trigger: 'blur' },
  65 + { pattern: /^\d+(\.\d{1,2})?$/, message: this.$t('prestoreAccount2.amountFormat'), trigger: 'blur' }
  66 + ],
  67 + remark: [
  68 + { max: 200, message: this.$t('prestoreAccount2.remarkMaxLength'), trigger: 'blur' }
  69 + ]
  70 + }
  71 + }
  72 + },
  73 + methods: {
  74 + open(params) {
  75 + this.formData = {
  76 + ...this.formData,
  77 + acctType: params.acctType,
  78 + amount: params.redepositAmount,
  79 + redepositAmount: params.redepositAmount,
  80 + receivedAmount: params.receivedAmount,
  81 + totalAmount: (parseFloat(params.receivedAmount) - parseFloat(params.redepositAmount)).toFixed(2),
  82 + ownerId: params.objId
  83 + }
  84 + this.dialogVisible = true
  85 + },
  86 + close() {
  87 + this.dialogVisible = false
  88 + },
  89 + computedAmount() {
  90 + let amount = parseFloat(this.formData.receivedAmount) - parseFloat(this.formData.totalAmount)
  91 + amount = amount.toFixed(2)
  92 + this.formData.amount = amount < 0 ? 0 : amount
  93 + },
  94 + async savePrestoreAccount2Info() {
  95 + try {
  96 + const valid = await this.$refs.form.validate()
  97 + if (!valid) return
  98 +
  99 + this.formData.communityId = await getCommunityId()
  100 +
  101 + const response = await this.$http.post('/account.ownerPrestoreAccount', this.formData)
  102 + if (response.data.code === 0) {
  103 + this.$message.success(this.$t('prestoreAccount2.saveSuccess'))
  104 + this.close()
  105 + this.$emit('success')
  106 + this.$emit('refresh')
  107 + } else {
  108 + this.$message.error(response.data.msg)
  109 + }
  110 + } catch (error) {
  111 + console.error('预存账户失败:', error)
  112 + this.$message.error(this.$t('prestoreAccount2.saveError'))
  113 + }
  114 + },
  115 + handleClose() {
  116 + this.$refs.form.resetFields()
  117 + this.formData = {
  118 + tel: '',
  119 + ownerId: '',
  120 + owners: [],
  121 + amount: '',
  122 + remark: '',
  123 + receivedAmount: '',
  124 + redepositAmount: '',
  125 + totalAmount: '',
  126 + acctType: ''
  127 + }
  128 + }
  129 + }
  130 +}
  131 +</script>
  132 +
  133 +<style scoped>
  134 +.dialog-footer {
  135 + text-align: right;
  136 +}
  137 +</style>
0 138 \ No newline at end of file
... ...
src/components/fee/refundDepositFee.vue
1 1 <template>
2 2 <el-dialog
3 3 :title="$t('refundDepositFee.title')"
4   - :visible.sync="visible"
5   - width="500px"
6   - :before-close="handleClose"
  4 + :visible.sync="dialogVisible"
  5 + width="30%"
  6 + @close="handleClose"
7 7 >
8   - <div class="dialog-content">
9   - <p>{{ $t('refundDepositFee.confirmText') }}</p>
  8 + <el-alert
  9 + :title="$t('refundDepositFee.alertText')"
  10 + type="warning"
  11 + :closable="false"
  12 + ></el-alert>
  13 +
  14 + <div slot="footer" class="dialog-footer">
  15 + <el-button @click="dialogVisible = false">{{ $t('refundDepositFee.cancel') }}</el-button>
  16 + <el-button type="primary" @click="refundDepositFee">{{ $t('refundDepositFee.confirm') }}</el-button>
10 17 </div>
11   - <span slot="footer" class="dialog-footer">
12   - <el-button @click="handleClose">{{ $t('common.cancel') }}</el-button>
13   - <el-button type="primary" @click="refundDepositFee">{{ $t('common.confirm') }}</el-button>
14   - </span>
15 18 </el-dialog>
16 19 </template>
17 20  
18 21 <script>
19 22 import { getCommunityId } from '@/api/community/communityApi'
20   -import { refundFeeDeposit } from '@/api/fee/batchPayFeeOrderApi'
21 23  
22 24 export default {
23 25 name: 'RefundDepositFee',
24 26 data() {
25 27 return {
26   - visible: false,
27   - refundDepositFeeInfo: {}
  28 + dialogVisible: false,
  29 + refundData: {}
28 30 }
29 31 },
30 32 methods: {
31   - open(fee) {
32   - this.refundDepositFeeInfo = { ...fee }
33   - this.visible = true
  33 + open(params) {
  34 + this.refundData = { ...params }
  35 + this.dialogVisible = true
34 36 },
35   -
36   - handleClose() {
37   - this.visible = false
  37 + close() {
  38 + this.dialogVisible = false
38 39 },
39   -
40 40 async refundDepositFee() {
41 41 try {
42   - const params = {
43   - ...this.refundDepositFeeInfo,
44   - communityId: getCommunityId()
45   - }
46   -
47   - const res = await refundFeeDeposit(params)
48   - if (res.code === 0) {
49   - this.$message.success('退押金成功')
50   - this.visible = false
  42 + this.refundData.communityId = await getCommunityId()
  43 +
  44 + const response = await this.$http.post('/fee.refundFeeDeposit', this.refundData)
  45 + if (response.data.code === 0) {
  46 + this.$message.success(this.$t('refundDepositFee.success'))
51 47 this.$emit('success')
52   - this.$emit('refresh')
  48 + this.dialogVisible = false
53 49 } else {
54   - this.$message.error(res.msg)
  50 + this.$message.error(response.data.msg)
55 51 }
56 52 } catch (error) {
57   - console.error('请求失败:', error)
58   - this.$message.error('退押金失败')
  53 + console.error('退押金失败:', error)
  54 + this.$message.error(this.$t('refundDepositFee.error'))
59 55 }
  56 + },
  57 + handleClose() {
  58 + this.refundData = {}
60 59 }
61 60 }
62 61 }
63 62 </script>
64 63  
65   -<style lang="scss" scoped>
66   -.dialog-content {
67   - padding: 20px;
68   - text-align: center;
69   - font-size: 16px;
70   - line-height: 1.6;
  64 +<style scoped>
  65 +.el-alert {
  66 + margin-bottom: 20px;
  67 +}
  68 +.dialog-footer {
  69 + text-align: right;
71 70 }
72 71 </style>
73 72 \ No newline at end of file
... ...
src/components/fee/simplifyRoomFee.vue
... ... @@ -432,7 +432,7 @@ export default {
432 432 fee.roomName = this.simplifyRoomFeeInfo.roomName
433 433 fee.builtUpArea = this.simplifyRoomFeeInfo.builtUpArea
434 434 this.$router.push({
435   - path: '/property/payFeeOrder',
  435 + path: '/views/fee/payFeeOrder',
436 436 query: { feeId: fee.feeId }
437 437 })
438 438 },
... ...
src/components/fee/viewFeeConfigData.vue
1 1 <template>
2   - <el-tooltip effect="dark" content="查看详情" placement="top">
3   - <i class="el-icon-info hand" @click="open"></i>
4   - </el-tooltip>
  2 + <el-dialog
  3 + :title="title"
  4 + :visible.sync="dialogVisible"
  5 + width="50%"
  6 + @close="handleClose"
  7 + >
  8 + <el-table
  9 + :data="tableData"
  10 + border
  11 + style="width: 100%"
  12 + >
  13 + <el-table-column
  14 + prop="label"
  15 + :label="$t('viewFeeConfigData.label')"
  16 + width="180"
  17 + />
  18 + <el-table-column
  19 + prop="value"
  20 + :label="$t('viewFeeConfigData.value')"
  21 + />
  22 + </el-table>
  23 + </el-dialog>
5 24 </template>
6 25  
7 26 <script>
8 27 import { getCommunityId } from '@/api/community/communityApi'
9   -import { listFeeConfigs } from '@/api/fee/propertyFeeApi'
10 28  
11 29 export default {
12 30 name: 'ViewFeeConfigData',
13 31 data() {
14 32 return {
15   - configId: '',
16   - communityId: ''
  33 + dialogVisible: false,
  34 + title: '',
  35 + tableData: [],
  36 + configId: ''
17 37 }
18 38 },
19   - created() {
20   - this.communityId = getCommunityId()
21   - },
22 39 methods: {
23 40 open(params) {
24 41 this.configId = params.configId
25   - this._loadFeeConfigData()
  42 + this.loadFeeConfigData()
  43 + this.dialogVisible = true
  44 + },
  45 + close() {
  46 + this.dialogVisible = false
26 47 },
27   - async _loadFeeConfigData() {
  48 + async loadFeeConfigData() {
28 49 try {
29   - const res = await listFeeConfigs({
  50 + const communityId = await getCommunityId()
  51 + const params = {
30 52 page: 1,
31 53 row: 1,
32   - communityId: this.communityId,
  54 + communityId,
33 55 configId: this.configId
34   - })
35   -
36   - if (res.data && res.data.length > 0) {
37   - const feeConfig = res.data[0]
38   - const configData = {
39   - "费用项ID": feeConfig.configId,
40   - "费用类型": feeConfig.feeTypeCdName,
41   - "收费项目": feeConfig.feeName,
42   - "费用标识": feeConfig.feeFlagName,
43   - "催缴类型": feeConfig.billTypeName,
44   - "付费类型": feeConfig.paymentCd === '1200' ? this.$t('viewFeeConfigData.prepaid') : this.$t('viewFeeConfigData.postpaid'),
45   - "缴费周期": feeConfig.paymentCycle,
46   - "计费起始时间": feeConfig.startTime,
47   - "计费终止时间": feeConfig.endTime,
48   - "公式": feeConfig.computingFormulaName,
49   - "计费单价": feeConfig.computingFormula === '2002' ? '-' : feeConfig.squarePrice,
50   - "附加/固定费用": feeConfig.additionalAmount
51   - }
52   -
53   - this.$emit('openViewDataModal', {
54   - title: `${feeConfig.feeName} ${this.$t('viewFeeConfigData.feeItem')}`,
55   - data: configData
56   - })
57 56 }
  57 +
  58 + const response = await this.$http.get('/feeConfig.listFeeConfigs', { params })
  59 + const feeConfig = response.data.feeConfigs[0]
  60 +
  61 + this.title = `${feeConfig.feeName} ${this.$t('viewFeeConfigData.feeItem')}`
  62 +
  63 + this.tableData = [
  64 + { label: this.$t('viewFeeConfigData.configId'), value: feeConfig.configId },
  65 + { label: this.$t('viewFeeConfigData.feeType'), value: feeConfig.feeTypeCdName },
  66 + { label: this.$t('viewFeeConfigData.feeName'), value: feeConfig.feeName },
  67 + { label: this.$t('viewFeeConfigData.feeFlag'), value: feeConfig.feeFlagName },
  68 + { label: this.$t('viewFeeConfigData.billType'), value: feeConfig.billTypeName },
  69 + { label: this.$t('viewFeeConfigData.paymentType'), value: feeConfig.paymentCd === '1200' ? this.$t('viewFeeConfigData.prepay') : this.$t('viewFeeConfigData.postpay') },
  70 + { label: this.$t('viewFeeConfigData.paymentCycle'), value: feeConfig.paymentCycle },
  71 + { label: this.$t('viewFeeConfigData.billingStartTime'), value: feeConfig.startTime },
  72 + { label: this.$t('viewFeeConfigData.billingEndTime'), value: feeConfig.endTime },
  73 + { label: this.$t('viewFeeConfigData.formula'), value: feeConfig.computingFormulaName },
  74 + { label: this.$t('viewFeeConfigData.unitPrice'), value: feeConfig.computingFormula === '2002' ? '-' : feeConfig.squarePrice },
  75 + { label: this.$t('viewFeeConfigData.additionalFee'), value: feeConfig.additionalAmount }
  76 + ]
58 77 } catch (error) {
59 78 console.error('加载费用配置数据失败:', error)
60 79 }
  80 + },
  81 + handleClose() {
  82 + this.tableData = []
  83 + this.title = ''
  84 + this.configId = ''
61 85 }
62 86 }
63 87 }
64   -</script>
65   -
66   -<style scoped>
67   -.hand {
68   - cursor: pointer;
69   - color: #409EFF;
70   - margin-left: 5px;
71   -}
72   -</style>
73 88 \ No newline at end of file
  89 +</script>
74 90 \ No newline at end of file
... ...
src/components/fee/viewFeeData.vue 0 → 100644
  1 +<template>
  2 + <el-dialog
  3 + :title="title"
  4 + :visible.sync="dialogVisible"
  5 + width="50%"
  6 + @close="handleClose"
  7 + >
  8 + <el-table
  9 + :data="tableData"
  10 + border
  11 + style="width: 100%"
  12 + >
  13 + <el-table-column
  14 + prop="label"
  15 + :label="$t('viewFeeData.label')"
  16 + width="180"
  17 + />
  18 + <el-table-column
  19 + prop="value"
  20 + :label="$t('viewFeeData.value')"
  21 + />
  22 + </el-table>
  23 + </el-dialog>
  24 +</template>
  25 +
  26 +<script>
  27 +import { getCommunityId } from '@/api/community/communityApi'
  28 +import { dateFormat } from '@/utils/dateUtil'
  29 +
  30 +export default {
  31 + name: 'ViewFeeData',
  32 + data() {
  33 + return {
  34 + dialogVisible: false,
  35 + title: '',
  36 + tableData: [],
  37 + feeId: ''
  38 + }
  39 + },
  40 + methods: {
  41 + open(params) {
  42 + this.feeId = params.feeId
  43 + this.loadViewFeeData()
  44 + this.dialogVisible = true
  45 + },
  46 + close() {
  47 + this.dialogVisible = false
  48 + },
  49 + async loadViewFeeData() {
  50 + try {
  51 + const communityId = await getCommunityId()
  52 + const params = {
  53 + page: 1,
  54 + row: 1,
  55 + communityId,
  56 + feeId: this.feeId
  57 + }
  58 +
  59 + const response = await this.$http.get('/fee.listFee', { params })
  60 + const fee = response.data.fees[0]
  61 +
  62 + this.title = `${fee.feeName} ${this.$t('viewFeeData.details')}`
  63 +
  64 + const data = {
  65 + [this.$t('viewFeeData.feeId')]: fee.feeId,
  66 + [this.$t('viewFeeData.feeFlag')]: fee.feeFlagName,
  67 + [this.$t('viewFeeData.feeType')]: fee.feeTypeCdName,
  68 + [this.$t('viewFeeData.payerObj')]: fee.payerObjName,
  69 + [this.$t('viewFeeData.feeName')]: fee.feeName,
  70 + [this.$t('viewFeeData.state')]: fee.stateName,
  71 + [this.$t('viewFeeData.createTime')]: fee.startTime,
  72 + [this.$t('viewFeeData.billingStartTime')]: this.getViewFeeDataEndTime(fee),
  73 + [this.$t('viewFeeData.billingEndTime')]: this.getViewFeeDataDeadlineTime(fee),
  74 + [this.$t('viewFeeData.batch')]: fee.batchId
  75 + }
  76 +
  77 + if (fee.feeAttrs) {
  78 + fee.feeAttrs.forEach(attr => {
  79 + data[attr.specCdName] = attr.value
  80 + })
  81 + }
  82 +
  83 + this.tableData = Object.keys(data).map(key => ({
  84 + label: key,
  85 + value: data[key]
  86 + }))
  87 + } catch (error) {
  88 + console.error('加载费用数据失败:', error)
  89 + }
  90 + },
  91 + getViewFeeDataDeadlineTime(fee) {
  92 + if (fee.amountOwed == 0 && fee.endTime == fee.deadlineTime) {
  93 + return "-"
  94 + }
  95 + if (fee.state == '2009001') {
  96 + return "-"
  97 + }
  98 + return dateFormat(fee.deadlineTime)
  99 + },
  100 + getViewFeeDataEndTime(fee) {
  101 + if (fee.state == '2009001') {
  102 + return "-"
  103 + }
  104 + return dateFormat(fee.endTime)
  105 + },
  106 + handleClose() {
  107 + this.tableData = []
  108 + this.title = ''
  109 + this.feeId = ''
  110 + }
  111 + }
  112 +}
  113 +</script>
0 114 \ No newline at end of file
... ...
src/components/fee/viewRoomData.vue
1 1 <template>
2   - <el-tooltip effect="dark" content="查看详情" placement="top">
3   - <i class="el-icon-info hand" @click="open"></i>
4   - </el-tooltip>
  2 + <el-dialog
  3 + :title="title"
  4 + :visible.sync="dialogVisible"
  5 + width="50%"
  6 + @close="handleClose"
  7 + >
  8 + <el-table
  9 + :data="tableData"
  10 + border
  11 + style="width: 100%"
  12 + >
  13 + <el-table-column
  14 + prop="label"
  15 + :label="$t('viewRoomData.label')"
  16 + width="180"
  17 + />
  18 + <el-table-column
  19 + prop="value"
  20 + :label="$t('viewRoomData.value')"
  21 + />
  22 + </el-table>
  23 + </el-dialog>
5 24 </template>
6 25  
7 26 <script>
8 27 import { getCommunityId } from '@/api/community/communityApi'
9   -import { queryRooms } from '@/api/fee/propertyFeeApi'
10 28  
11 29 export default {
12 30 name: 'ViewRoomData',
13 31 data() {
14 32 return {
15   - roomId: '',
16   - communityId: ''
  33 + dialogVisible: false,
  34 + title: '',
  35 + tableData: [],
  36 + roomId: ''
17 37 }
18 38 },
19   - created() {
20   - this.communityId = getCommunityId()
21   - },
22 39 methods: {
23 40 open(params) {
24 41 this.roomId = params.roomId
25   - this._loadViewRoomData()
  42 + this.loadViewRoomData()
  43 + this.dialogVisible = true
  44 + },
  45 + close() {
  46 + this.dialogVisible = false
26 47 },
27   - async _loadViewRoomData() {
  48 + async loadViewRoomData() {
28 49 try {
29   - const res = await queryRooms({
  50 + const communityId = await getCommunityId()
  51 + const params = {
30 52 page: 1,
31 53 row: 1,
32   - communityId: this.communityId,
  54 + communityId,
33 55 roomId: this.roomId
34   - })
  56 + }
  57 +
  58 + const response = await this.$http.get('/room.queryRooms', { params })
  59 + const room = response.data.rooms[0]
  60 +
  61 + this.title = `${room.floorNum}-${room.unitNum}-${room.roomNum} ${this.$t('viewRoomData.details')}`
35 62  
36   - if (res.data && res.data.length > 0) {
37   - const room = res.data[0]
38   - const roomData = {
39   - "房屋": `${room.floorNum}-${room.unitNum}-${room.roomNum}`,
40   - "楼层": room.layer,
41   - "业主": room.ownerName || '-',
42   - "电话": room.link || '-',
43   - "类型": room.roomSubTypeName,
44   - "建筑面积": room.builtUpArea,
45   - "室内面积": room.roomArea,
46   - "租金": room.roomRent,
47   - "房屋状态": room.stateName,
48   - "入住时间": room.startTime
49   - }
50   -
51   - if (room.roomAttrDto) {
52   - room.roomAttrDto.forEach(attr => {
53   - roomData[attr.specName] = attr.valueName
54   - })
55   - }
56   -
57   - this.$emit('openViewDataModal', {
58   - title: `${room.floorNum}-${room.unitNum}-${room.roomNum} 详情`,
59   - data: roomData
  63 + const data = {
  64 + [this.$t('viewRoomData.room')]: `${room.floorNum}-${room.unitNum}-${room.roomNum}`,
  65 + [this.$t('viewRoomData.floor')]: room.layer,
  66 + [this.$t('viewRoomData.owner')]: room.ownerName,
  67 + [this.$t('viewRoomData.phone')]: room.link,
  68 + [this.$t('viewRoomData.type')]: room.roomSubTypeName,
  69 + [this.$t('viewRoomData.builtUpArea')]: room.builtUpArea,
  70 + [this.$t('viewRoomData.roomArea')]: room.roomArea,
  71 + [this.$t('viewRoomData.rent')]: room.roomRent,
  72 + [this.$t('viewRoomData.state')]: room.stateName,
  73 + [this.$t('viewRoomData.moveInTime')]: room.startTime
  74 + }
  75 +
  76 + if (room.roomAttrDto) {
  77 + room.roomAttrDto.forEach(attr => {
  78 + data[attr.specName] = attr.valueName
60 79 })
61 80 }
  81 +
  82 + this.tableData = Object.keys(data).map(key => ({
  83 + label: key,
  84 + value: data[key]
  85 + }))
62 86 } catch (error) {
63 87 console.error('加载房间数据失败:', error)
64 88 }
  89 + },
  90 + handleClose() {
  91 + this.tableData = []
  92 + this.title = ''
  93 + this.roomId = ''
65 94 }
66 95 }
67 96 }
68   -</script>
69   -
70   -<style scoped>
71   -.hand {
72   - cursor: pointer;
73   - color: #409EFF;
74   - margin-left: 5px;
75   -}
76   -</style>
77 97 \ No newline at end of file
  98 +</script>
78 99 \ No newline at end of file
... ...
src/components/index/index-property.vue
... ... @@ -57,6 +57,7 @@ export default {
57 57 <style lang="scss" scoped>
58 58 .property-index-container {
59 59  
  60 + padding: 0 10px; // 添加左右内边距
60 61  
61 62 .vc-index-nav {
62 63 padding: 10px;
... ... @@ -82,6 +83,8 @@ export default {
82 83  
83 84 .vc-index-1 {
84 85 margin-bottom: 20px;
  86 + // 修复 Element UI 栅格系统的 gutter 问题
  87 +
85 88  
86 89 .index-1-left,
87 90 .index-1-right {
... ...
src/components/owner/ownerDetailRoomFee.vue
... ... @@ -221,7 +221,7 @@ export default {
221 221 })
222 222 },
223 223 _payRoomFee(fee) {
224   - this.$router.push(`/property/payFeeOrder?feeId=${fee.feeId}`)
  224 + this.$router.push(`/views/fee/payFeeOrder?feeId=${fee.feeId}`)
225 225 },
226 226 _editRoomFee(fee) {
227 227 this.$emit('editFee', fee)
... ...
src/components/simplify/simplifyCarFee.vue
... ... @@ -262,7 +262,7 @@ export default {
262 262 return `${this.$t('simplifyCarFee.owner')}:${ownerName},${this.$t('simplifyCarFee.phone')}:${ownerLink}`
263 263 },
264 264 _simplifyCarPayFee(fee) {
265   - this.$router.push(`/pages/property/payFeeOrder?feeId=${fee.feeId}`)
  265 + this.$router.push(`/views/fee/payFeeOrderfeeId=${fee.feeId}`)
266 266 },
267 267 _simplifyCarPayFeeHis(fee) {
268 268 this.$router.push(`/pages/property/propertyFee?${this.objToGetParam(fee)}`)
... ...
src/i18n/feeI18n.js
... ... @@ -27,6 +27,7 @@ import { messages as roomCreateFeeMessages } from &#39;../views/fee/roomCreateFeeLan
27 27 import { messages as propertyFeeMessages } from '../views/fee/propertyFeeLang'
28 28 import { messages as batchPayFeeOrderMessages } from '../views/fee/batchPayFeeOrderLang'
29 29 import { messages as simplifyAcceptanceMessages } from '../views/simplify/simplifyAcceptanceLang.js'
  30 +import { messages as payFeeOrderMessages } from '../views/fee/payFeeOrderLang'
30 31  
31 32 export const messages = {
32 33 en: {
... ... @@ -59,6 +60,7 @@ export const messages = {
59 60 ...propertyFeeMessages.en,
60 61 ...batchPayFeeOrderMessages.en,
61 62 ...simplifyAcceptanceMessages.en,
  63 + ...payFeeOrderMessages.en,
62 64 },
63 65 zh: {
64 66 ...contractCreateFeeMessages.zh,
... ... @@ -90,5 +92,6 @@ export const messages = {
90 92 ...propertyFeeMessages.zh,
91 93 ...batchPayFeeOrderMessages.zh,
92 94 ...simplifyAcceptanceMessages.zh,
  95 + ...payFeeOrderMessages.zh,
93 96 }
94 97 }
95 98 \ No newline at end of file
... ...
src/i18n/index.js
... ... @@ -436,7 +436,7 @@ const messages = {
436 436  
437 437 // 创建 i18n 实例
438 438 const i18n = new VueI18n({
439   - locale: 'zh-CN',
  439 + locale: 'zh',
440 440 messages
441 441 })
442 442  
... ...
src/main.js
... ... @@ -7,11 +7,6 @@ import i18n from &#39;./i18n&#39;
7 7 import {getCommunityName,getCommunityId} from '@/api/community/communityApi'
8 8  
9 9 // 验证全局脚本是否正确加载
10   -console.log('检查全局脚本加载状态:')
11   -console.log('Qs 库:', typeof window.Qs !== 'undefined' ? '已加载' : '未加载')
12   -if (typeof window.Qs !== 'undefined') {
13   - console.log('Qs 版本:', window.Qs.VERSION || '未知版本')
14   -}
15 10  
16 11 Vue.prototype.getCommunityId = function(){
17 12 return getCommunityId()
... ...
src/router/feeRouter.js
... ... @@ -129,4 +129,9 @@ export default [
129 129 name: '/pages/property/simplifyAcceptance',
130 130 component: () => import('@/views/simplify/simplifyAcceptanceList.vue')
131 131 },
  132 + {
  133 + path:'/views/fee/payFeeOrder',
  134 + name:'/views/fee/payFeeOrder',
  135 + component: () => import('@/views/fee/payFeeOrderList.vue')
  136 + },
132 137 ]
133 138 \ No newline at end of file
... ...
src/views/fee/listCarFeeList.vue
... ... @@ -188,7 +188,7 @@ export default {
188 188 },
189 189 _payFee(fee) {
190 190 fee.roomName = this.listCarFeeInfo.carNum
191   - this.$router.push({ path: '/fee/payFeeOrder', query: { feeId: fee.feeId } })
  191 + this.$router.push({ path: '/views/fee/payFeeOrder', query: { feeId: fee.feeId } })
192 192 },
193 193 _payFeeHis(fee) {
194 194 this.$router.push({ path: '/property/propertyFee', query: fee })
... ...
src/views/fee/payFeeOrderLang.js 0 → 100644
  1 +export const messages = {
  2 + en: {
  3 + payFeeOrder: {
  4 + title: 'Order Payment',
  5 + back: 'Back',
  6 + feeId: 'Fee ID:',
  7 + feeName: 'Fee Item:',
  8 + feeType: 'Fee Type:',
  9 + billingStartTime: 'Billing Start Time:',
  10 + area: 'Area:',
  11 + unitPrice: 'Unit Price:',
  12 + additionalFee: 'Additional Fee:',
  13 + fixedFee: 'Fixed Fee:',
  14 + ownerAccount: 'Owner Account:',
  15 + giftPoints: 'Gift Points:',
  16 + receivable: 'Receivable:',
  17 + amountPayable: 'Amount Payable:',
  18 + paymentTime: 'Payment Time:',
  19 + paymentTimePlaceholder: 'Required, please fill in the payment time',
  20 + paymentCycle: 'Payment Cycle:',
  21 + selectPaymentCycle: 'Please select payment cycle',
  22 + month: 'months',
  23 + customCycle: 'Custom Cycle',
  24 + customAmount: 'Custom Amount',
  25 + customEndTime: 'Custom End Time',
  26 + customTimeRange: 'Custom Time Range',
  27 + actualCycle: 'Actual Cycle:',
  28 + inputActualCycle: 'Please enter actual cycle',
  29 + endTime: 'End Time:',
  30 + selectEndTime: 'Please select payment end time',
  31 + paymentPeriod: 'Payment Period:',
  32 + selectStartTime: 'Please select payment start time',
  33 + paymentMethod: 'Payment Method:',
  34 + selectPaymentMethod: 'Required, please select payment method',
  35 + actualReceipt: 'Actual Receipt:',
  36 + inputActualAmount: 'Please enter actual receipt amount',
  37 + remark: 'Remark:',
  38 + inputRemark: 'Optional, please fill in the remark',
  39 + scanPayment: 'Scan Payment',
  40 + submitPayment: 'Submit Payment'
  41 + },
  42 + viewRoomData: {
  43 + details: 'Details',
  44 + label: 'Item',
  45 + value: 'Value',
  46 + room: 'Room',
  47 + floor: 'Floor',
  48 + owner: 'Owner',
  49 + phone: 'Phone',
  50 + type: 'Type',
  51 + builtUpArea: 'Built-up Area',
  52 + roomArea: 'Room Area',
  53 + rent: 'Rent',
  54 + state: 'State',
  55 + moveInTime: 'Move-in Time'
  56 + },
  57 + viewFeeData: {
  58 + details: 'Details',
  59 + label: 'Item',
  60 + value: 'Value',
  61 + feeId: 'Fee ID',
  62 + feeFlag: 'Fee Flag',
  63 + feeType: 'Fee Type',
  64 + payerObj: 'Payer Object',
  65 + feeName: 'Fee Name',
  66 + state: 'State',
  67 + createTime: 'Create Time',
  68 + billingStartTime: 'Billing Start Time',
  69 + billingEndTime: 'Billing End Time',
  70 + batch: 'Batch'
  71 + },
  72 + viewFeeConfigData: {
  73 + feeItem: 'Fee Item',
  74 + label: 'Item',
  75 + value: 'Value',
  76 + configId: 'Config ID',
  77 + feeType: 'Fee Type',
  78 + feeName: 'Fee Name',
  79 + feeFlag: 'Fee Flag',
  80 + billType: 'Bill Type',
  81 + paymentType: 'Payment Type',
  82 + prepay: 'Prepay',
  83 + postpay: 'Postpay',
  84 + paymentCycle: 'Payment Cycle',
  85 + billingStartTime: 'Billing Start Time',
  86 + billingEndTime: 'Billing End Time',
  87 + formula: 'Formula',
  88 + unitPrice: 'Unit Price',
  89 + additionalFee: 'Additional/Fixed Fee'
  90 + },
  91 + payFeeUserAccount: {
  92 + title: 'Account Information',
  93 + accountInfo: 'Account Information',
  94 + refresh: 'Refresh',
  95 + select: 'Select',
  96 + accountType: 'Account Type',
  97 + accountName: 'Account Name',
  98 + accountAmount: 'Account Amount',
  99 + operation: 'Operation',
  100 + yuan: 'yuan',
  101 + prestore: 'Prestore'
  102 + },
  103 + payFeeDeposit: {
  104 + title: 'Deposit Information',
  105 + depositInfo: 'Deposit Information',
  106 + refresh: 'Refresh',
  107 + payerObj: 'Payer Object',
  108 + feeName: 'Fee Item',
  109 + timeRange: 'Time Range',
  110 + amount: 'Amount',
  111 + paymentTime: 'Payment Time',
  112 + operation: 'Operation',
  113 + refund: 'Refund'
  114 + },
  115 + refundDepositFee: {
  116 + title: 'Please confirm your operation!',
  117 + alertText: 'After the deposit is refunded, it will be automatically deposited into the account. You can choose to pay from the account. If you refund cash to the owner, please go to the business home page to refund the deposit!',
  118 + cancel: 'Cancel',
  119 + confirm: 'Confirm',
  120 + success: 'Refund deposit successfully',
  121 + error: 'Refund deposit failed'
  122 + },
  123 + payFeeOrderResult: {
  124 + title: 'Payment Prompt',
  125 + success: 'Payment successful',
  126 + receiptTip: 'Please go to the business acceptance page to reprint the receipt',
  127 + back: 'Back',
  128 + printSmall: 'Print Small Ticket',
  129 + mergePrint: 'Merge Print',
  130 + printReceipt: 'Print Receipt'
  131 + },
  132 + payFeeOrderConfirm: {
  133 + title: 'Payment Confirmation',
  134 + payerObj: 'Payer Object:',
  135 + timeRange: 'Payment Period:',
  136 + receivable: 'Receivable Amount:',
  137 + discountAmount: 'Discount Amount:',
  138 + discountTooltip: 'Positive: discounted amount; Negative: additional late fee',
  139 + actualAmount: 'Actual Receipt:',
  140 + deductionAmount: 'Deduction Amount:',
  141 + amountPayable: 'Amount Payable:',
  142 + integralDeduction: 'Integral Account Deduction:',
  143 + cashDeduction: 'Cash Account Deduction:',
  144 + remark: 'Remark:',
  145 + authCode: 'Auth Code:',
  146 + authCodePlaceholder: 'Please scan with scanner',
  147 + close: 'Close',
  148 + confirm: 'Confirm Payment'
  149 + },
  150 + payFeeDiscount: {
  151 + title: 'Discount Information',
  152 + discountInfo: 'Discount Information',
  153 + discountType: 'Discount Type',
  154 + discountName: 'Discount Name',
  155 + ruleName: 'Rule Name',
  156 + rule: 'Rule',
  157 + discountAmount: 'Discount Amount',
  158 + discountTooltip: 'Negative: discounted amount; Positive: additional late fee',
  159 + yuan: 'yuan',
  160 + discount: 'Discount',
  161 + penalty: 'Penalty',
  162 + specialDiscount: 'Special Discount',
  163 + monthSpec: 'Month',
  164 + penaltySpec: 'Penalty'
  165 + },
  166 + payFeeCoupon: {
  167 + title: 'Gift Coupon',
  168 + couponInfo: 'Gift Coupon Information',
  169 + ruleName: 'Rule Name',
  170 + couponName: 'Coupon Name',
  171 + quantity: 'Quantity',
  172 + unit: 'pcs',
  173 + purpose: 'Purpose'
  174 + },
  175 + prestoreAccount2: {
  176 + title: 'Prestore',
  177 + receivable: 'Receivable:',
  178 + actualReceipt: 'Actual Receipt:',
  179 + prestoreAmount: 'Prestore Amount:',
  180 + amountPlaceholder: 'Required, please fill in the prestore amount',
  181 + remark: 'Remark:',
  182 + remarkPlaceholder: 'Optional, please fill in the remark',
  183 + cancel: 'Cancel',
  184 + save: 'Save',
  185 + amountRequired: 'Amount cannot be empty',
  186 + amountFormat: 'Amount format error',
  187 + remarkMaxLength: 'Remark cannot exceed 200 characters',
  188 + saveSuccess: 'Prestore successfully',
  189 + saveError: 'Prestore failed'
  190 + }
  191 + },
  192 + zh: {
  193 + payFeeOrder: {
  194 + title: '订单收费',
  195 + back: '返回',
  196 + feeId: '费用ID:',
  197 + feeName: '费用项目:',
  198 + feeType: '费用类型:',
  199 + billingStartTime: '计费起始时间:',
  200 + area: '面积:',
  201 + unitPrice: '单价:',
  202 + additionalFee: '附加费:',
  203 + fixedFee: '固定费:',
  204 + ownerAccount: '业主账户:',
  205 + giftPoints: '赠送积分:',
  206 + receivable: '应收款:',
  207 + amountPayable: '应缴金额:',
  208 + paymentTime: '缴费时间:',
  209 + paymentTimePlaceholder: '必填,请填写缴费时间',
  210 + paymentCycle: '缴费周期:',
  211 + selectPaymentCycle: '请选择缴费周期',
  212 + month: '个月',
  213 + customCycle: '自定义周期',
  214 + customAmount: '自定义金额',
  215 + customEndTime: '自定义结束时间',
  216 + customTimeRange: '自定义时间段',
  217 + actualCycle: '实际周期:',
  218 + inputActualCycle: '请输入实际周期',
  219 + endTime: '结束时间:',
  220 + selectEndTime: '请选择缴费结束时间',
  221 + paymentPeriod: '缴费时间段:',
  222 + selectStartTime: '请选择缴费开始时间',
  223 + paymentMethod: '支付方式:',
  224 + selectPaymentMethod: '必填,请选择支付方式',
  225 + actualReceipt: '实收款:',
  226 + inputActualAmount: '请输入实际收款金额',
  227 + remark: '备注:',
  228 + inputRemark: '可填,请填写备注',
  229 + scanPayment: '扫码收费',
  230 + submitPayment: '提交收费'
  231 + },
  232 + viewRoomData: {
  233 + details: '详情',
  234 + label: '项目',
  235 + value: '值',
  236 + room: '房屋',
  237 + floor: '楼层',
  238 + owner: '业主',
  239 + phone: '电话',
  240 + type: '类型',
  241 + builtUpArea: '建筑面积',
  242 + roomArea: '室内面积',
  243 + rent: '租金',
  244 + state: '房屋状态',
  245 + moveInTime: '入住时间'
  246 + },
  247 + viewFeeData: {
  248 + details: '详情',
  249 + label: '项目',
  250 + value: '值',
  251 + feeId: '费用ID',
  252 + feeFlag: '费用标识',
  253 + feeType: '费用类型',
  254 + payerObj: '付费对象',
  255 + feeName: '费用项',
  256 + state: '费用状态',
  257 + createTime: '建账时间',
  258 + billingStartTime: '计费开始时间',
  259 + billingEndTime: '计费结束时间',
  260 + batch: '批次'
  261 + },
  262 + viewFeeConfigData: {
  263 + feeItem: '费用项',
  264 + label: '项目',
  265 + value: '值',
  266 + configId: '费用项ID',
  267 + feeType: '费用类型',
  268 + feeName: '收费项目',
  269 + feeFlag: '费用标识',
  270 + billType: '催缴类型',
  271 + paymentType: '付费类型',
  272 + prepay: '预付费',
  273 + postpay: '后付费',
  274 + paymentCycle: '缴费周期',
  275 + billingStartTime: '计费起始时间',
  276 + billingEndTime: '计费终止时间',
  277 + formula: '公式',
  278 + unitPrice: '计费单价',
  279 + additionalFee: '附加/固定费用'
  280 + },
  281 + payFeeUserAccount: {
  282 + title: '账户信息',
  283 + accountInfo: '账户信息',
  284 + refresh: '刷新',
  285 + select: '选择',
  286 + accountType: '账户类型',
  287 + accountName: '账户名',
  288 + accountAmount: '账户金额',
  289 + operation: '操作',
  290 + yuan: '元',
  291 + prestore: '预存'
  292 + },
  293 + payFeeDeposit: {
  294 + title: '押金信息',
  295 + depositInfo: '押金信息',
  296 + refresh: '刷新',
  297 + payerObj: '收费对象',
  298 + feeName: '费用项',
  299 + timeRange: '时间段',
  300 + amount: '金额',
  301 + paymentTime: '缴费时间',
  302 + operation: '操作',
  303 + refund: '退押金'
  304 + },
  305 + refundDepositFee: {
  306 + title: '请确认您的操作!',
  307 + alertText: '押金退款后自动存到账户中,您可以从账户中选择缴费,如果退现金给业主,请到业务首页面退押金!',
  308 + cancel: '点错了',
  309 + confirm: '确认',
  310 + success: '退押金成功',
  311 + error: '退押金失败'
  312 + },
  313 + payFeeOrderResult: {
  314 + title: '缴费提示',
  315 + success: '缴费成功',
  316 + receiptTip: '请到业务受理页面补打收据',
  317 + back: '返回',
  318 + printSmall: '打印小票',
  319 + mergePrint: '合并打印',
  320 + printReceipt: '打印收据'
  321 + },
  322 + payFeeOrderConfirm: {
  323 + title: '收费确认',
  324 + payerObj: '付费对象:',
  325 + timeRange: '缴费时间段:',
  326 + receivable: '应收金额:',
  327 + discountAmount: '优惠金额:',
  328 + discountTooltip: '正数:打折减免的金额;负数:需额外缴纳的滞纳金',
  329 + actualAmount: '实收金额:',
  330 + deductionAmount: '抵扣金额:',
  331 + amountPayable: '应缴金额:',
  332 + integralDeduction: '积分账户抵扣金额:',
  333 + cashDeduction: '现金账户抵扣金额:',
  334 + remark: '备注:',
  335 + authCode: '授权码:',
  336 + authCodePlaceholder: '请用扫码枪扫码',
  337 + close: '关闭',
  338 + confirm: '确定收费'
  339 + },
  340 + payFeeDiscount: {
  341 + title: '折扣信息',
  342 + discountInfo: '折扣信息',
  343 + discountType: '折扣类型',
  344 + discountName: '折扣名称',
  345 + ruleName: '规则名称',
  346 + rule: '规则',
  347 + discountAmount: '折扣金额',
  348 + discountTooltip: '负数:打折减免的金额;正数:需额外缴纳的滞纳金',
  349 + yuan: '元',
  350 + discount: '优惠',
  351 + penalty: '违约',
  352 + specialDiscount: '优惠(需要申请)',
  353 + monthSpec: '月份',
  354 + penaltySpec: '滞纳金'
  355 + },
  356 + payFeeCoupon: {
  357 + title: '赠送优惠券',
  358 + couponInfo: '赠送优惠券',
  359 + ruleName: '赠送规则',
  360 + couponName: '优惠券名称',
  361 + quantity: '数量',
  362 + unit: '张',
  363 + purpose: '用途'
  364 + },
  365 + prestoreAccount2: {
  366 + title: '预存',
  367 + receivable: '应收:',
  368 + actualReceipt: '实收:',
  369 + prestoreAmount: '预存金额:',
  370 + amountPlaceholder: '必填,请填写预存金额',
  371 + remark: '备注:',
  372 + remarkPlaceholder: '可填,请填写备注',
  373 + cancel: '取消',
  374 + save: '保存',
  375 + amountRequired: '金额不能为空',
  376 + amountFormat: '金额格式错误',
  377 + remarkMaxLength: '备注长度不能超过200位',
  378 + saveSuccess: '预存成功',
  379 + saveError: '预存失败'
  380 + }
  381 + }
  382 +}
0 383 \ No newline at end of file
... ...
src/views/fee/payFeeOrderList.vue 0 → 100644
  1 +<template>
  2 + <div class="pay-fee-order-container">
  3 + <el-card class="box-card">
  4 + <div slot="header" class="clearfix">
  5 + <span>{{ $t('payFeeOrder.title') }}</span>
  6 + <el-button type="primary" size="small" style="float: right;" @click="goBack">
  7 + <i class="el-icon-close"></i>
  8 + {{ $t('payFeeOrder.back') }}
  9 + </el-button>
  10 + </div>
  11 +
  12 + <el-row :gutter="20">
  13 + <el-col :span="14" style="border-right: 1px solid #f4f4f4; padding-left: 30px;">
  14 + <el-form label-width="120px">
  15 + <el-row>
  16 + <el-col :span="12">
  17 + <el-form-item :label="$t('payFeeOrder.feeId')">
  18 + <el-link type="primary" @click="viewFee">
  19 + {{ payFeeOrderInfo.feeId }}
  20 + </el-link>
  21 + </el-form-item>
  22 + </el-col>
  23 + <el-col :span="12">
  24 + <el-form-item :label="$t('payFeeOrder.feeName')">
  25 + <el-link type="primary" @click="viewFeeConfig">
  26 + {{ payFeeOrderInfo.feeName }}
  27 + </el-link>
  28 + </el-form-item>
  29 + </el-col>
  30 + </el-row>
  31 +
  32 + <el-row>
  33 + <el-col :span="12">
  34 + <el-form-item :label="$t('payFeeOrder.feeType')">
  35 + <span>{{ payFeeOrderInfo.feeTypeCdName }}</span>
  36 + </el-form-item>
  37 + </el-col>
  38 + <el-col :span="12">
  39 + <el-form-item :label="$t('payFeeOrder.billingStartTime')">
  40 + <span>{{ payFeeOrderInfo.endTime }}</span>
  41 + </el-form-item>
  42 + </el-col>
  43 + </el-row>
  44 +
  45 + <el-row v-if="payFeeOrderInfo.builtUpArea">
  46 + <el-col :span="12">
  47 + <el-form-item :label="$t('payFeeOrder.area')">
  48 + <span>{{ payFeeOrderInfo.builtUpArea }}</span>
  49 + </el-form-item>
  50 + </el-col>
  51 + <el-col :span="12">
  52 + <el-form-item :label="$t('payFeeOrder.unitPrice')">
  53 + <span>{{ payFeeOrderInfo.squarePrice }}</span>
  54 + </el-form-item>
  55 + </el-col>
  56 + </el-row>
  57 +
  58 + <el-row v-if="payFeeOrderInfo.builtUpArea">
  59 + <el-col :span="12">
  60 + <el-form-item :label="$t('payFeeOrder.additionalFee')">
  61 + <span>{{ payFeeOrderInfo.additionalAmount }}</span>
  62 + </el-form-item>
  63 + </el-col>
  64 + </el-row>
  65 + <el-row v-else>
  66 + <el-col :span="12">
  67 + <el-form-item :label="$t('payFeeOrder.fixedFee')">
  68 + <span>{{ payFeeOrderInfo.additionalAmount }}</span>
  69 + </el-form-item>
  70 + </el-col>
  71 + </el-row>
  72 +
  73 + <el-row>
  74 + <el-col :span="12">
  75 + <el-form-item :label="$t('payFeeOrder.ownerAccount')">
  76 + <el-checkbox v-model="useAccount" @change="handleAccountChange"></el-checkbox>
  77 + </el-form-item>
  78 + </el-col>
  79 + <el-col :span="12">
  80 + <el-form-item :label="$t('payFeeOrder.giftPoints')">
  81 + <span>{{ payFeeOrderInfo.integralQuantity }}</span>
  82 + </el-form-item>
  83 + </el-col>
  84 + </el-row>
  85 +
  86 + <el-row>
  87 + <el-col :span="12">
  88 + <el-form-item :label="$t('payFeeOrder.receivable')" style="line-height: 50px;">
  89 + <span style="font-size: 30px; color: red;">¥{{ payFeeOrderInfo.totalFeePrice }}</span>
  90 + </el-form-item>
  91 + </el-col>
  92 + <el-col :span="12">
  93 + <el-form-item :label="$t('payFeeOrder.amountPayable')" style="line-height: 50px;">
  94 + <span style="font-size: 30px; color: red;">
  95 + ¥{{ payFeeOrderInfo.accountAmount >= payFeeOrderInfo.receivedAmount ? '0.00' :
  96 + (payFeeOrderInfo.receivedAmount - payFeeOrderInfo.accountAmount).toFixed(2) }}
  97 + </span>
  98 + </el-form-item>
  99 + </el-col>
  100 + </el-row>
  101 + </el-form>
  102 + </el-col>
  103 +
  104 + <el-col :span="7" style="padding-left: 30px;">
  105 + <el-form label-width="100px">
  106 + <el-form-item :label="$t('payFeeOrder.paymentTime')">
  107 + <el-date-picker v-model="payFeeOrderInfo.createTime" type="datetime"
  108 + :placeholder="$t('payFeeOrder.paymentTimePlaceholder')" style="width: 100%;" readonly>
  109 + </el-date-picker>
  110 + </el-form-item>
  111 +
  112 + <el-form-item v-if="payFeeOrderInfo.feeFlag != '2006012'" :label="$t('payFeeOrder.paymentCycle')">
  113 + <el-select v-model="payFeeOrderInfo.tempCycles" :placeholder="$t('payFeeOrder.selectPaymentCycle')"
  114 + style="width: 100%;" @change="changeMonth">
  115 + <el-option v-for="item in payFeeOrderInfo.paymentCycles" :key="item"
  116 + :label="item + $t('payFeeOrder.month')" :value="item">
  117 + </el-option>
  118 + <el-option :value="-102" :label="$t('payFeeOrder.customCycle')"></el-option>
  119 + <el-option :value="-101" :label="$t('payFeeOrder.customAmount')"></el-option>
  120 + <el-option :value="-103" :label="$t('payFeeOrder.customEndTime')"></el-option>
  121 + <el-option :value="-105" :label="$t('payFeeOrder.customTimeRange')"></el-option>
  122 + </el-select>
  123 + </el-form-item>
  124 +
  125 + <el-form-item v-if="payFeeOrderInfo.tempCycles == '-102'" :label="$t('payFeeOrder.actualCycle')">
  126 + <el-input v-model="payFeeOrderInfo.cycles" :placeholder="$t('payFeeOrder.inputActualCycle')"
  127 + @change="changeCycle">
  128 + </el-input>
  129 + </el-form-item>
  130 +
  131 + <el-form-item v-show="payFeeOrderInfo.tempCycles == '-103'" :label="$t('payFeeOrder.endTime')">
  132 + <el-date-picker v-model="payFeeOrderInfo.custEndTime" type="date"
  133 + :placeholder="$t('payFeeOrder.selectEndTime')" style="width: 100%;">
  134 + </el-date-picker>
  135 + </el-form-item>
  136 +
  137 + <el-form-item v-show="payFeeOrderInfo.tempCycles == '-105'" :label="$t('payFeeOrder.paymentPeriod')">
  138 + <el-date-picker v-model="payFeeOrderInfo.customStartTime" type="date"
  139 + :placeholder="$t('payFeeOrder.selectStartTime')" style="width: 100%; margin-bottom: 10px;">
  140 + </el-date-picker>
  141 + <el-date-picker v-model="payFeeOrderInfo.customEndTime" type="date"
  142 + :placeholder="$t('payFeeOrder.selectEndTime')" style="width: 100%;">
  143 + </el-date-picker>
  144 + </el-form-item>
  145 +
  146 + <el-form-item :label="$t('payFeeOrder.paymentMethod')">
  147 + <el-select v-model="payFeeOrderInfo.primeRate" :placeholder="$t('payFeeOrder.selectPaymentMethod')"
  148 + style="width: 100%;">
  149 + <template v-for="(item, index) in payFeeOrderInfo.primeRates">
  150 + <el-option v-if="item.statusCd != '5' && item.statusCd != '6' && item.statusCd != '8'" :key="index"
  151 + :label="item.name" :value="item.statusCd">
  152 + </el-option>
  153 + </template>
  154 + </el-select>
  155 + </el-form-item>
  156 +
  157 + <el-form-item :label="$t('payFeeOrder.actualReceipt')">
  158 + <el-input v-if="payFeeOrderInfo.receivedAmountSwitch == '1'" v-model="payFeeOrderInfo.receivedAmount"
  159 + :placeholder="$t('payFeeOrder.inputActualAmount')">
  160 + </el-input>
  161 + <span v-if="payFeeOrderInfo.receivedAmountSwitch == '2'" style="font-size: 15px;">
  162 + ¥{{ payFeeOrderInfo.receivedAmount }}
  163 + </span>
  164 + </el-form-item>
  165 +
  166 + <el-form-item :label="$t('payFeeOrder.remark')">
  167 + <el-input type="textarea" v-model="payFeeOrderInfo.remark" :placeholder="$t('payFeeOrder.inputRemark')">
  168 + </el-input>
  169 + </el-form-item>
  170 +
  171 + <el-row style="margin-top: 30px;">
  172 + <el-col :span="10" :offset="1">
  173 + <el-button v-if="payFeeOrderInfo.primeRate == '3' || payFeeOrderInfo.primeRate == '4'" type="success"
  174 + size="medium" style="width: 100%;" @click="openPayFee('qrCode')">
  175 + {{ $t('payFeeOrder.scanPayment') }}
  176 + </el-button>
  177 + </el-col>
  178 + <el-col :span="10" :offset="2">
  179 + <el-button v-if="payFeeOrderInfo.offlinePayFeeSwitch != '2'" type="primary" size="medium"
  180 + style="width: 100%;" @click="openPayFee('common')">
  181 + {{ $t('payFeeOrder.submitPayment') }}
  182 + </el-button>
  183 + </el-col>
  184 + </el-row>
  185 + </el-form>
  186 + </el-col>
  187 + </el-row>
  188 + </el-card>
  189 +
  190 + <pay-fee-user-account ref="payFeeUserAccount"></pay-fee-user-account>
  191 + <pay-fee-deposit ref="payFeeDeposit"></pay-fee-deposit>
  192 + <pay-fee-order-result ref="payFeeOrderResult"></pay-fee-order-result>
  193 + <pay-fee-order-confirm ref="payFeeOrderConfirm"></pay-fee-order-confirm>
  194 + <pay-fee-discount ref="payFeeDiscount"></pay-fee-discount>
  195 + <pay-fee-coupon ref="payFeeCoupon"></pay-fee-coupon>
  196 + <prestore-account2 ref="prestoreAccount2"></prestore-account2>
  197 + <view-room-data ref="viewRoomData"></view-room-data>
  198 + <view-fee-data ref="viewFeeData"></view-fee-data>
  199 + <view-fee-config-data ref="viewFeeConfigData"></view-fee-config-data>
  200 + </div>
  201 +</template>
  202 +
  203 +<script>
  204 +import { getDict } from '@/api/community/communityApi'
  205 +import { getCommunityId } from '@/api/community/communityApi'
  206 +import PayFeeUserAccount from '@/components/fee/payFeeUserAccount'
  207 +import PayFeeDeposit from '@/components/fee/payFeeDeposit'
  208 +import PayFeeOrderResult from '@/components/fee/payFeeOrderResult'
  209 +import PayFeeOrderConfirm from '@/components/fee/payFeeOrderConfirm'
  210 +import PayFeeDiscount from '@/components/fee/payFeeDiscount'
  211 +import PayFeeCoupon from '@/components/fee/payFeeCoupon'
  212 +import PrestoreAccount2 from '@/components/fee/prestoreAccount2'
  213 +import ViewRoomData from '@/components/fee/viewRoomData'
  214 +import ViewFeeData from '@/components/fee/viewFeeData'
  215 +import ViewFeeConfigData from '@/components/fee/viewFeeConfigData'
  216 +import { listFeeObj } from '@/api/fee/payFeeOrderApi'
  217 +import { dateAdd, dateSub } from '@/utils/dateUtil'
  218 +
  219 +export default {
  220 + name: 'PayFeeOrderList',
  221 + components: {
  222 + PayFeeUserAccount,
  223 + PayFeeDeposit,
  224 + PayFeeOrderResult,
  225 + PayFeeOrderConfirm,
  226 + PayFeeDiscount,
  227 + PayFeeCoupon,
  228 + PrestoreAccount2,
  229 + ViewRoomData,
  230 + ViewFeeData,
  231 + ViewFeeConfigData
  232 + },
  233 + data() {
  234 + return {
  235 + payFeeOrderInfo: {
  236 + feeId: '',
  237 + feeName: '',
  238 + feeTypeCdName: '',
  239 + feeTypeCd: '',
  240 + primeRates: [],
  241 + primeRate: '',
  242 + endTime: '',
  243 + feeFlag: '',
  244 + feePrice: 0.00,
  245 + tempCycles: '',
  246 + cycles: '',
  247 + paymentCycles: [],
  248 + totalFeePrice: 0.00,
  249 + receivedAmount: '',
  250 + receivedAmountNumber: '',
  251 + communityId: '',
  252 + payerObjName: '',
  253 + payerObjId: '',
  254 + payerObjType: '',
  255 + remark: '',
  256 + builtUpArea: 0.0,
  257 + squarePrice: 0.0,
  258 + additionalAmount: 0.0,
  259 + receiptId: '',
  260 + showEndTime: '',
  261 + accountList: [],
  262 + integralAmount: '',
  263 + cashAmount: '',
  264 + couponAmount: '',
  265 + selectDiscount: [],
  266 + totalDiscountMoney: 0.0,
  267 + scale: 1,
  268 + decimalPlace: 2,
  269 + receivedAmountSwitch: '1',
  270 + createTime: new Date(),
  271 + accountAmount: 0.0,
  272 + viewAccountAmount: 0.0,
  273 + deductionAmount: 0.0,
  274 + redepositAmount: 0.0,
  275 + selectUserAccount: [],
  276 + authCode: '',
  277 + orderId: '',
  278 + offlinePayFeeSwitch: '1',
  279 + flag: '',
  280 + custEndTime: '',
  281 + configId: '',
  282 + roomName: '',
  283 + sign: 1,
  284 + integralQuantity: 0,
  285 + customStartTime: '',
  286 + customEndTime: ''
  287 + },
  288 + useAccount: true,
  289 + loading: false
  290 + }
  291 + },
  292 + created() {
  293 + this.initData()
  294 + },
  295 + methods: {
  296 + async initData() {
  297 + try {
  298 + this.payFeeOrderInfo.communityId = await getCommunityId()
  299 + this.payFeeOrderInfo.feeId = this.$route.query.feeId || ''
  300 + this.listAndComputeFeeInfo()
  301 + this.getDictData()
  302 + } catch (error) {
  303 + console.error('初始化数据失败:', error)
  304 + }
  305 + },
  306 + async getDictData() {
  307 + try {
  308 + const data = await getDict('pay_fee_detail', 'prime_rate')
  309 + this.payFeeOrderInfo.primeRates = data
  310 + } catch (error) {
  311 + console.error('获取字典数据失败:', error)
  312 + }
  313 + },
  314 + goBack() {
  315 + this.$router.go(-1)
  316 + },
  317 + viewFee() {
  318 + this.$refs.viewFeeData.open({
  319 + feeId: this.payFeeOrderInfo.feeId
  320 + })
  321 + },
  322 + viewFeeConfig() {
  323 + this.$refs.viewFeeConfigData.open({
  324 + configId: this.payFeeOrderInfo.configId
  325 + })
  326 + },
  327 + viewRoomData() {
  328 + this.$refs.viewRoomData.open({
  329 + roomId: this.payFeeOrderInfo.payerObjId
  330 + })
  331 + },
  332 + handleAccountChange(val) {
  333 + if (val) {
  334 + this.$refs.payFeeUserAccount.open({
  335 + feeId: this.payFeeOrderInfo.feeId
  336 + })
  337 + } else {
  338 + this.$refs.payFeeUserAccount.close()
  339 + }
  340 + },
  341 + openPayFee(type) {
  342 + this.$refs.payFeeOrderConfirm.open({
  343 + ...this.payFeeOrderInfo,
  344 + payType: type
  345 + })
  346 + },
  347 + changeMonth(cycles) {
  348 + // 实现周期变更逻辑
  349 + console.log(cycles)
  350 + },
  351 + changeCycle(cycles) {
  352 + // 实现周期变更逻辑
  353 + console.log(cycles)
  354 + },
  355 + async listAndComputeFeeInfo(_cycles) {
  356 + // 实现费用计算逻辑
  357 + if (!_cycles) {
  358 + _cycles = 1;
  359 + }
  360 +
  361 + let param = {
  362 + communityId: getCommunityId(),
  363 + feeId: this.payFeeOrderInfo.feeId,
  364 + page: 1,
  365 + row: 1,
  366 + cycle: _cycles
  367 +
  368 + };
  369 + if (_cycles && _cycles == 103) {
  370 + let _custEndTime = dateAdd(this.payFeeOrderInfo.custEndTime);
  371 + //前端选择会默认 少一天 所以 加上一天
  372 + param.params.custEndTime = _custEndTime;
  373 + }
  374 + if (_cycles && _cycles == 105) {
  375 + let _customEndTime = dateAdd(this.payFeeOrderInfo.customEndTime);
  376 + //前端选择会默认 少一天 所以 加上一天
  377 + param.params.customEndTime = _customEndTime;
  378 + param.params.customStartTime = this.payFeeOrderInfo.customStartTime
  379 + }
  380 + const listRoomData = await listFeeObj(param)
  381 + //发送get请求
  382 +
  383 + if (Object.prototype.hasOwnProperty.call(listRoomData.data, 'custEndTime')) {
  384 + delete listRoomData.data.custEndTime
  385 + }
  386 + if (Object.prototype.hasOwnProperty.call(listRoomData.data, 'customEndTime')) {
  387 + delete listRoomData.data.customEndTime
  388 + }
  389 + this.payFeeOrderInfo = { ...this.payFeeOrderInfo, ...listRoomData.data }
  390 + // 由于返回的键与档期那页面自定义的键不一致,单独赋值toFiexedSign
  391 + //vc.emit('payFeeOrder', 'initData', listRoomData.data);
  392 + this.payFeeOrderInfo.totalFeePrice = listRoomData.data.feeTotalPrice;
  393 + this.payFeeOrderInfo.receivedAmount = listRoomData.data.feeTotalPrice;
  394 + let _deadlineTime = new Date(listRoomData.data.deadlineTime);
  395 + let _maxEndTime = new Date(listRoomData.data.maxEndTime);
  396 + if (_deadlineTime.getTime() > _maxEndTime.getTime()) {
  397 + this.$message.warning('超过最大计费结束时间,' + dateSub(listRoomData.data.maxEndTime, listRoomData.data.feeFlag) + ",请用更小缴费周期或者自定义结束时间缴费");
  398 + return;
  399 + }
  400 + // vc.emit('payFeeDiscount', 'computeFeeDiscount', {
  401 + // feeId: this.payFeeOrderInfo.feeId,
  402 + // cycles: _cycles,
  403 + // payerObjId: this.payFeeOrderInfo.payerObjId,
  404 + // payerObjType: this.payFeeOrderInfo.payerObjType,
  405 + // endTime: this.payFeeOrderInfo.endTime,
  406 + // custEndTime: this.payFeeOrderInfo.custEndTime
  407 + // });
  408 + // vc.emit('payFeeCoupon', 'computeFeeCoupon', {
  409 + // feeId: this.payFeeOrderInfo.feeId,
  410 + // cycles: _cycles,
  411 + // payerObjId: this.payFeeOrderInfo.payerObjId,
  412 + // payerObjType: this.payFeeOrderInfo.payerObjType,
  413 + // endTime: this.payFeeOrderInfo.endTime
  414 + // });
  415 + // vc.emit('payFeeDeposit', 'computeFeeDeposit', {
  416 + // payerObjId: this.payFeeOrderInfo.payerObjId,
  417 + // payerObjType: this.payFeeOrderInfo.payerObjType,
  418 + // });
  419 + this._listFeeIntegral(_cycles);
  420 +
  421 +
  422 + },
  423 + async _listFeeIntegral(_cycles) {
  424 + // 实现积分计算逻辑
  425 + console.log(_cycles)
  426 + }
  427 + }
  428 +}
  429 +</script>
  430 +
  431 +<style lang="scss" scoped>
  432 +.pay-fee-order-container {
  433 + padding: 20px;
  434 +
  435 + .box-card {
  436 + margin-bottom: 20px;
  437 + }
  438 +
  439 + .el-form-item {
  440 + margin-bottom: 15px;
  441 + }
  442 +
  443 + .el-date-editor,
  444 + .el-select,
  445 + .el-input {
  446 + width: 100%;
  447 + }
  448 +}
  449 +</style>
0 450 \ No newline at end of file
... ...
src/views/fee/printPayFeeBangTaiList.vue
... ... @@ -111,6 +111,7 @@
111 111 import { queryFeeReceipt, queryFeeReceiptDetail, queryFeePrintSpec } from '@/api/fee/printPayFeeBangTaiApi'
112 112 import { getCommunityId } from '@/api/community/communityApi'
113 113 import { getUserId,getUserName } from '@/api/user/userApi'
  114 +import { dateFormat } from '@/utils/dateUtil'
114 115  
115 116 export default {
116 117 name: 'PrintPayFeeBangTaiList',
... ... @@ -246,7 +247,7 @@ export default {
246 247 },
247 248 formatDate(date) {
248 249 if (!date) return ''
249   - return this.$moment(date).format('YYYY-MM-DD')
  250 + return dateFormat(date)
250 251 },
251 252 changeNumMoneyToChinese(num) {
252 253 // 这里实现数字转中文大写金额的逻辑
... ...
src/views/fee/printPayFeeList.vue
... ... @@ -113,6 +113,7 @@
113 113 import { getCommunityId } from '@/api/community/communityApi'
114 114 import { queryFeeReceipt, queryFeeReceiptDetail, queryFeePrintSpec } from '@/api/fee/printPayFeeApi'
115 115 import { getUserId,getUserName } from '@/api/user/userApi'
  116 +import { dateFormat } from '@/utils/dateUtil'
116 117  
117 118 export default {
118 119 name: 'PrintPayFeeList',
... ... @@ -240,7 +241,7 @@ export default {
240 241 },
241 242 dateFormat(date) {
242 243 if (!date) return ''
243   - return this.$moment(date).format('YYYY-MM-DD')
  244 + return dateFormat(date)
244 245 },
245 246 changeNumMoneyToChinese(num) {
246 247 // 这里实现数字转中文大写金额的逻辑
... ...
src/views/fee/propertyFeeList.vue
... ... @@ -134,6 +134,7 @@ import { queryFeeDetail } from &#39;@/api/fee/propertyFeeApi&#39;
134 134 import ViewMainFee from '@/components/fee/viewMainFee'
135 135 import ReturnPayFee from '@/components/fee/returnPayFee'
136 136 import ViewFeeDetailDiscount from '@/components/fee/viewFeeDetailDiscount'
  137 +import { dateFormat } from '@/utils/dateUtil'
137 138  
138 139 export default {
139 140 name: 'PropertyFeeList',
... ... @@ -166,7 +167,7 @@ export default {
166 167 methods: {
167 168 dateFormat(date) {
168 169 if (!date) return ''
169   - return this.$moment(date).format('YYYY-MM-DD')
  170 + return dateFormat(date)
170 171 },
171 172 async listFeeDetail(page = 1, row = 10) {
172 173 try {
... ...
src/views/layout/layout.vue
... ... @@ -268,7 +268,12 @@ export default {
268 268 }
269 269 console.log(_href, _tabName)
270 270  
271   - this.$router.push(_href)
  271 + this.$router.push(_href).catch(err => {
  272 + // 忽略重复导航错误
  273 + if (err.name !== 'NavigationDuplicated') {
  274 + throw err
  275 + }
  276 + })
272 277 },
273 278 }
274 279 }
... ...
src/views/oa/staffAttendanceManageList.vue
... ... @@ -84,6 +84,7 @@ import {
84 84 queryAttendanceClassesTask,
85 85  
86 86 } from '@/api/oa/staffAttendanceManageApi'
  87 +import { dateFormat } from '@/utils/dateUtil'
87 88  
88 89 export default {
89 90 name: 'StaffAttendanceManageList',
... ... @@ -221,7 +222,7 @@ export default {
221 222  
222 223 formatTime(time) {
223 224 if (!time) return ''
224   - return this.$moment(time).format('HH:mm:ss')
  225 + return dateFormat(time)
225 226 },
226 227  
227 228 checkInLog(day) {
... ...
src/views/simplify/simplifyAcceptanceList.vue
... ... @@ -266,9 +266,9 @@
266 266 <car-create-fee-add ref="carCreateFeeAdd"></car-create-fee-add>
267 267 <add-meter-water ref="addMeterWater"></add-meter-water>
268 268 <add-proxy-fee ref="addProxyFee"></add-proxy-fee>
269   - <search-room ref="searchRoom" emit-choose-room="simplifyAcceptance" emit-load-data="list" :room-flag="1"
270   - :show-search-condition="false"></search-room>
271 269 <edit-machine-translate ref="editMachineTranslate"></edit-machine-translate>
  270 + <room-tree ref="roomTree" @selectRoom="selectRoom" />
  271 +
272 272 </div>
273 273 </template>
274 274  
... ... @@ -297,7 +297,7 @@ import RoomCreateFeeAdd from &#39;@/components/fee/roomCreateFeeAdd&#39;
297 297 import CarCreateFeeAdd from '@/components/fee/carCreateFeeAdd'
298 298 import AddMeterWater from '@/components/fee/addMeterWater'
299 299 import AddProxyFee from '@/components/fee/addProxyFee'
300   -import SearchRoom from '@/components/room/searchRoom'
  300 +import roomTree from '@/components/room/roomTree'
301 301 import EditMachineTranslate from '@/components/machine/editMachineTranslate'
302 302 import InputSearchOwner from '@/components/report/InputSearchOwner'
303 303 import InputSearchRoom from '@/components/fee/inputSearchRoom'
... ... @@ -328,7 +328,7 @@ export default {
328 328 CarCreateFeeAdd,
329 329 AddMeterWater,
330 330 AddProxyFee,
331   - SearchRoom,
  331 + roomTree,
332 332 EditMachineTranslate,
333 333 InputSearchOwner,
334 334 InputSearchRoom,
... ... @@ -478,8 +478,7 @@ export default {
478 478 Object.assign(this.simplifyAcceptanceInfo, _rooms[0])
479 479 this.simplifyAcceptanceInfo.roomRemark = _rooms[0].remark
480 480 this.simplifyAcceptanceInfo.roomName = _rooms[0].floorNum + '栋' + _rooms[0].unitNum + '单元' + _rooms[0].roomNum + '室'
481   - this.$refs.simplifyRoomFee.$emit('switch', this.simplifyAcceptanceInfo)
482   -
  481 + this.changeTab('simplifyRoomFee')
483 482 // 计算押金
484 483 this.computeDeposit()
485 484 } catch (error) {
... ... @@ -568,10 +567,14 @@ export default {
568 567 }
569 568 this.changeTab('simplifyRoomFee')
570 569 },
  570 + selectRoom(room) {
  571 + this.simplifyAcceptanceInfo.roomId = room.roomId
  572 + this.simplifyAcceptanceInfo.roomName = room.roomName
  573 + this.simplifyAcceptanceInfo.searchValue = room.roomName
  574 + this._doSearch()
  575 + },
571 576 _simplifyAcceptanceChooseRoom() {
572   - this.$refs.searchRoom.$emit('openRoomTree', {
573   - callName: 'simplifyAcceptance'
574   - })
  577 + this.$refs.roomTree.open()
575 578 },
576 579 _handover() {
577 580 this.$router.push('/pages/property/handover')
... ...