Commit f99ceb4fd18352b5bea8fce2ae96b1d295819c57
1 parent
43eaaadb
收据优化完成
Showing
24 changed files
with
2465 additions
and
140 deletions
src/api/fee/feeReceiptApi.js
0 → 100644
| 1 | +import request from '@/utils/request' | ||
| 2 | +import { getCommunityId } from '@/api/community/communityApi' | ||
| 3 | + | ||
| 4 | +// 查询收据列表 | ||
| 5 | +export function queryFeeReceipt(params) { | ||
| 6 | + return new Promise((resolve, reject) => { | ||
| 7 | + request({ | ||
| 8 | + url: '/feeReceipt/queryFeeReceipt', | ||
| 9 | + method: 'get', | ||
| 10 | + params: { | ||
| 11 | + ...params, | ||
| 12 | + communityId: getCommunityId() | ||
| 13 | + } | ||
| 14 | + }).then(response => { | ||
| 15 | + const res = response.data | ||
| 16 | + resolve(res) | ||
| 17 | + }).catch(error => { | ||
| 18 | + reject(error) | ||
| 19 | + }) | ||
| 20 | + }) | ||
| 21 | +} | ||
| 22 | + | ||
| 23 | +// 查询打印页面配置 | ||
| 24 | +export function listFeePrintPage(params) { | ||
| 25 | + return new Promise((resolve, reject) => { | ||
| 26 | + request({ | ||
| 27 | + url: '/feePrintPage.listFeePrintPage', | ||
| 28 | + method: 'get', | ||
| 29 | + params: { | ||
| 30 | + ...params, | ||
| 31 | + communityId: getCommunityId() | ||
| 32 | + } | ||
| 33 | + }).then(response => { | ||
| 34 | + const res = response.data | ||
| 35 | + resolve(res) | ||
| 36 | + }).catch(error => { | ||
| 37 | + reject(error) | ||
| 38 | + }) | ||
| 39 | + }) | ||
| 40 | +} | ||
| 0 | \ No newline at end of file | 41 | \ No newline at end of file |
src/api/fee/listApplyRoomDiscountRecordApi.js
0 → 100644
| 1 | +import request from '@/utils/request' | ||
| 2 | +import { getCommunityId } from '@/api/community/communityApi' | ||
| 3 | + | ||
| 4 | +// 查询验房跟踪记录列表 | ||
| 5 | +export function queryApplyRoomDiscountRecord(params) { | ||
| 6 | + return new Promise((resolve, reject) => { | ||
| 7 | + request({ | ||
| 8 | + url: '/applyRoomDiscountRecord/queryApplyRoomDiscountRecord', | ||
| 9 | + method: 'get', | ||
| 10 | + params: { | ||
| 11 | + ...params, | ||
| 12 | + communityId: getCommunityId() | ||
| 13 | + } | ||
| 14 | + }).then(response => { | ||
| 15 | + const res = response.data | ||
| 16 | + resolve(res) | ||
| 17 | + }).catch(error => { | ||
| 18 | + reject(error) | ||
| 19 | + }) | ||
| 20 | + }) | ||
| 21 | +} | ||
| 22 | + | ||
| 23 | +// 添加验房跟踪记录 | ||
| 24 | +export function addApplyRoomDiscountRecord(data) { | ||
| 25 | + return new Promise((resolve, reject) => { | ||
| 26 | + request({ | ||
| 27 | + url: '/applyRoomDiscountRecord/addApplyRoomDiscountRecord', | ||
| 28 | + method: 'post', | ||
| 29 | + data: { | ||
| 30 | + ...data, | ||
| 31 | + communityId: getCommunityId() | ||
| 32 | + } | ||
| 33 | + }).then(response => { | ||
| 34 | + const res = response.data | ||
| 35 | + resolve(res) | ||
| 36 | + }).catch(error => { | ||
| 37 | + reject(error) | ||
| 38 | + }) | ||
| 39 | + }) | ||
| 40 | +} | ||
| 41 | + | ||
| 42 | +// 删除验房跟踪记录 | ||
| 43 | +export function cutApplyRoomDiscountRecord(params) { | ||
| 44 | + return new Promise((resolve, reject) => { | ||
| 45 | + request({ | ||
| 46 | + url: '/applyRoomDiscountRecord/cutApplyRoomDiscountRecord', | ||
| 47 | + method: 'post', | ||
| 48 | + data: { | ||
| 49 | + ...params, | ||
| 50 | + communityId: getCommunityId() | ||
| 51 | + } | ||
| 52 | + }).then(response => { | ||
| 53 | + const res = response.data | ||
| 54 | + resolve(res) | ||
| 55 | + }).catch(error => { | ||
| 56 | + reject(error) | ||
| 57 | + }) | ||
| 58 | + }) | ||
| 59 | +} | ||
| 60 | + | ||
| 61 | +// 上传图片 | ||
| 62 | +export function uploadImage(data) { | ||
| 63 | + return new Promise((resolve, reject) => { | ||
| 64 | + request({ | ||
| 65 | + url: '/uploadImage', | ||
| 66 | + method: 'post', | ||
| 67 | + headers: { | ||
| 68 | + 'Content-Type': 'multipart/form-data' | ||
| 69 | + }, | ||
| 70 | + data | ||
| 71 | + }).then(response => { | ||
| 72 | + const res = response.data | ||
| 73 | + resolve(res) | ||
| 74 | + }).catch(error => { | ||
| 75 | + reject(error) | ||
| 76 | + }) | ||
| 77 | + }) | ||
| 78 | +} | ||
| 79 | + | ||
| 80 | +// 上传视频 | ||
| 81 | +export function uploadVedio(data, config) { | ||
| 82 | + return new Promise((resolve, reject) => { | ||
| 83 | + request({ | ||
| 84 | + url: '/uploadVedio', | ||
| 85 | + method: 'post', | ||
| 86 | + headers: { | ||
| 87 | + 'Content-Type': 'multipart/form-data' | ||
| 88 | + }, | ||
| 89 | + data, | ||
| 90 | + ...config | ||
| 91 | + }).then(response => { | ||
| 92 | + const res = response.data | ||
| 93 | + resolve(res) | ||
| 94 | + }).catch(error => { | ||
| 95 | + reject(error) | ||
| 96 | + }) | ||
| 97 | + }) | ||
| 98 | +} | ||
| 0 | \ No newline at end of file | 99 | \ No newline at end of file |
src/api/fee/printPayFeeApi.js
0 → 100644
| 1 | +import request from '@/utils/request' | ||
| 2 | +import { getCommunityId } from '@/api/community/communityApi' | ||
| 3 | + | ||
| 4 | +// 查询收费单据 | ||
| 5 | +export function queryFeeReceipt(params) { | ||
| 6 | + return new Promise((resolve, reject) => { | ||
| 7 | + request({ | ||
| 8 | + url: '/feeReceipt/queryFeeReceipt', | ||
| 9 | + method: 'get', | ||
| 10 | + params: { | ||
| 11 | + ...params, | ||
| 12 | + communityId: getCommunityId() | ||
| 13 | + } | ||
| 14 | + }).then(response => { | ||
| 15 | + resolve(response.data) | ||
| 16 | + }).catch(error => { | ||
| 17 | + reject(error) | ||
| 18 | + }) | ||
| 19 | + }) | ||
| 20 | +} | ||
| 21 | + | ||
| 22 | +// 查询收费单据详情 | ||
| 23 | +export function queryFeeReceiptDetail(params) { | ||
| 24 | + return new Promise((resolve, reject) => { | ||
| 25 | + request({ | ||
| 26 | + url: '/feeReceipt/queryFeeReceiptDetail', | ||
| 27 | + method: 'get', | ||
| 28 | + params: { | ||
| 29 | + ...params, | ||
| 30 | + communityId: getCommunityId() | ||
| 31 | + } | ||
| 32 | + }).then(response => { | ||
| 33 | + resolve(response.data) | ||
| 34 | + }).catch(error => { | ||
| 35 | + reject(error) | ||
| 36 | + }) | ||
| 37 | + }) | ||
| 38 | +} | ||
| 39 | + | ||
| 40 | +// 查询打印规范 | ||
| 41 | +export function queryFeePrintSpec(params) { | ||
| 42 | + return new Promise((resolve, reject) => { | ||
| 43 | + request({ | ||
| 44 | + url: '/feePrintSpec/queryFeePrintSpec', | ||
| 45 | + method: 'get', | ||
| 46 | + params: { | ||
| 47 | + ...params, | ||
| 48 | + communityId: getCommunityId() | ||
| 49 | + } | ||
| 50 | + }).then(response => { | ||
| 51 | + resolve(response.data) | ||
| 52 | + }).catch(error => { | ||
| 53 | + reject(error) | ||
| 54 | + }) | ||
| 55 | + }) | ||
| 56 | +} | ||
| 0 | \ No newline at end of file | 57 | \ No newline at end of file |
src/api/fee/printPayFeeBangTaiApi.js
0 → 100644
| 1 | +import request from '@/utils/request' | ||
| 2 | + | ||
| 3 | +// 查询缴费收据 | ||
| 4 | +export function queryFeeReceipt(params) { | ||
| 5 | + return new Promise((resolve, reject) => { | ||
| 6 | + request({ | ||
| 7 | + url: '/feeReceipt/queryFeeReceipt', | ||
| 8 | + method: 'get', | ||
| 9 | + params | ||
| 10 | + }).then(response => { | ||
| 11 | + const res = response.data | ||
| 12 | + resolve(res) | ||
| 13 | + }).catch(error => { | ||
| 14 | + reject(error) | ||
| 15 | + }) | ||
| 16 | + }) | ||
| 17 | +} | ||
| 18 | + | ||
| 19 | +// 查询缴费收据详情 | ||
| 20 | +export function queryFeeReceiptDetail(params) { | ||
| 21 | + return new Promise((resolve, reject) => { | ||
| 22 | + request({ | ||
| 23 | + url: '/feeReceipt/queryFeeReceiptDetail', | ||
| 24 | + method: 'get', | ||
| 25 | + params | ||
| 26 | + }).then(response => { | ||
| 27 | + const res = response.data | ||
| 28 | + resolve(res) | ||
| 29 | + }).catch(error => { | ||
| 30 | + reject(error) | ||
| 31 | + }) | ||
| 32 | + }) | ||
| 33 | +} | ||
| 34 | + | ||
| 35 | +// 查询打印规范 | ||
| 36 | +export function queryFeePrintSpec(params) { | ||
| 37 | + return new Promise((resolve, reject) => { | ||
| 38 | + request({ | ||
| 39 | + url: '/feePrintSpec/queryFeePrintSpec', | ||
| 40 | + method: 'get', | ||
| 41 | + params | ||
| 42 | + }).then(response => { | ||
| 43 | + const res = response.data | ||
| 44 | + resolve(res) | ||
| 45 | + }).catch(error => { | ||
| 46 | + reject(error) | ||
| 47 | + }) | ||
| 48 | + }) | ||
| 49 | +} | ||
| 0 | \ No newline at end of file | 50 | \ No newline at end of file |
src/api/fee/printSmallPayFeeApi.js
0 → 100644
| 1 | +import request from '@/utils/request' | ||
| 2 | +import { getCommunityId } from '@/api/community/communityApi' | ||
| 3 | + | ||
| 4 | +// 查询收据信息 | ||
| 5 | +export function queryFeeReceipt(params) { | ||
| 6 | + return new Promise((resolve, reject) => { | ||
| 7 | + request({ | ||
| 8 | + url: '/feeReceipt/queryFeeReceipt', | ||
| 9 | + method: 'get', | ||
| 10 | + params: { | ||
| 11 | + ...params, | ||
| 12 | + communityId: getCommunityId() | ||
| 13 | + } | ||
| 14 | + }).then(response => { | ||
| 15 | + resolve(response.data) | ||
| 16 | + }).catch(error => { | ||
| 17 | + reject(error) | ||
| 18 | + }) | ||
| 19 | + }) | ||
| 20 | +} | ||
| 21 | + | ||
| 22 | +// 查询收据详情 | ||
| 23 | +export function queryFeeReceiptDetail(params) { | ||
| 24 | + return new Promise((resolve, reject) => { | ||
| 25 | + request({ | ||
| 26 | + url: '/feeReceipt/queryFeeReceiptDetail', | ||
| 27 | + method: 'get', | ||
| 28 | + params: { | ||
| 29 | + ...params, | ||
| 30 | + communityId: getCommunityId() | ||
| 31 | + } | ||
| 32 | + }).then(response => { | ||
| 33 | + resolve(response.data) | ||
| 34 | + }).catch(error => { | ||
| 35 | + reject(error) | ||
| 36 | + }) | ||
| 37 | + }) | ||
| 38 | +} | ||
| 39 | + | ||
| 40 | +// 查询打印规格 | ||
| 41 | +export function queryFeePrintSpec(params) { | ||
| 42 | + return new Promise((resolve, reject) => { | ||
| 43 | + request({ | ||
| 44 | + url: '/feePrintSpec/queryFeePrintSpec', | ||
| 45 | + method: 'get', | ||
| 46 | + params: { | ||
| 47 | + ...params, | ||
| 48 | + communityId: getCommunityId() | ||
| 49 | + } | ||
| 50 | + }).then(response => { | ||
| 51 | + resolve(response.data) | ||
| 52 | + }).catch(error => { | ||
| 53 | + reject(error) | ||
| 54 | + }) | ||
| 55 | + }) | ||
| 56 | +} | ||
| 57 | + | ||
| 58 | +// 查询打印机列表 | ||
| 59 | +export function listMachinePrinter(params) { | ||
| 60 | + return new Promise((resolve, reject) => { | ||
| 61 | + request({ | ||
| 62 | + url: '/printer/listMachinePrinter', | ||
| 63 | + method: 'get', | ||
| 64 | + params: { | ||
| 65 | + ...params, | ||
| 66 | + communityId: getCommunityId() | ||
| 67 | + } | ||
| 68 | + }).then(response => { | ||
| 69 | + resolve(response.data) | ||
| 70 | + }).catch(error => { | ||
| 71 | + reject(error) | ||
| 72 | + }) | ||
| 73 | + }) | ||
| 74 | +} | ||
| 75 | + | ||
| 76 | +// 提交云打印 | ||
| 77 | +export function printPayFeeDetail(data) { | ||
| 78 | + return new Promise((resolve, reject) => { | ||
| 79 | + request({ | ||
| 80 | + url: '/print/printPayFeeDetail', | ||
| 81 | + method: 'post', | ||
| 82 | + data: { | ||
| 83 | + ...data, | ||
| 84 | + communityId: getCommunityId() | ||
| 85 | + } | ||
| 86 | + }).then(response => { | ||
| 87 | + resolve(response.data) | ||
| 88 | + }).catch(error => { | ||
| 89 | + reject(error) | ||
| 90 | + }) | ||
| 91 | + }) | ||
| 92 | +} | ||
| 0 | \ No newline at end of file | 93 | \ No newline at end of file |
src/components/fee/applyRoomDiscountRecord.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <el-dialog :title="$t('applyRoomDiscountRecord.title')" :visible.sync="visible" width="60%" | ||
| 3 | + :before-close="handleClose"> | ||
| 4 | + <el-form :model="form" label-width="120px" label-position="left"> | ||
| 5 | + <el-form-item :label="$t('applyRoomDiscountRecord.room')"> | ||
| 6 | + <el-input v-model="form.roomName" disabled></el-input> | ||
| 7 | + </el-form-item> | ||
| 8 | + <el-form-item :label="$t('applyRoomDiscountRecord.status')"> | ||
| 9 | + <el-input v-model="form.stateName" disabled></el-input> | ||
| 10 | + </el-form-item> | ||
| 11 | + <el-form-item :label="$t('applyRoomDiscountRecord.isViolation')" prop="isTrue" required> | ||
| 12 | + <el-select v-model="form.isTrue" style="width:100%"> | ||
| 13 | + <el-option :value="null" :label="$t('applyRoomDiscountRecord.selectViolation')" disabled></el-option> | ||
| 14 | + <el-option :value="true" :label="$t('common.yes')"></el-option> | ||
| 15 | + <el-option :value="false" :label="$t('common.no')"></el-option> | ||
| 16 | + </el-select> | ||
| 17 | + </el-form-item> | ||
| 18 | + <el-form-item :label="$t('applyRoomDiscountRecord.remark')" prop="remark" required> | ||
| 19 | + <el-input type="textarea" v-model="form.remark" | ||
| 20 | + :placeholder="$t('applyRoomDiscountRecord.remarkPlaceholder')"></el-input> | ||
| 21 | + </el-form-item> | ||
| 22 | + <el-form-item :label="$t('applyRoomDiscountRecord.uploadImages')"> | ||
| 23 | + <upload-image-url ref="uploadImageUrl" /> | ||
| 24 | + </el-form-item> | ||
| 25 | + <el-form-item :label="$t('applyRoomDiscountRecord.uploadVideo')"> | ||
| 26 | + <upload-vedio ref="uploadVedio" /> | ||
| 27 | + </el-form-item> | ||
| 28 | + </el-form> | ||
| 29 | + <span slot="footer" class="dialog-footer"> | ||
| 30 | + <el-button @click="handleClose">{{ $t('common.cancel') }}</el-button> | ||
| 31 | + <el-button type="primary" @click="saveApplyRoomDiscountRecordInfo">{{ $t('common.save') }}</el-button> | ||
| 32 | + </span> | ||
| 33 | + </el-dialog> | ||
| 34 | +</template> | ||
| 35 | + | ||
| 36 | +<script> | ||
| 37 | +import { addApplyRoomDiscountRecord } from '@/api/fee/listApplyRoomDiscountRecordApi' | ||
| 38 | +import UploadImageUrl from '@/components/upload/UploadImageUrl' | ||
| 39 | +import UploadVedio from './uploadVedio' | ||
| 40 | +import { getCommunityId } from '@/api/community/communityApi' | ||
| 41 | + | ||
| 42 | +export default { | ||
| 43 | + name: 'ApplyRoomDiscountRecord', | ||
| 44 | + components: { | ||
| 45 | + UploadImageUrl, | ||
| 46 | + UploadVedio | ||
| 47 | + }, | ||
| 48 | + props: { | ||
| 49 | + callBackFunction: { | ||
| 50 | + type: String, | ||
| 51 | + default: '' | ||
| 52 | + } | ||
| 53 | + }, | ||
| 54 | + data() { | ||
| 55 | + return { | ||
| 56 | + visible: false, | ||
| 57 | + form: { | ||
| 58 | + ardId: '', | ||
| 59 | + roomName: '', | ||
| 60 | + state: '', | ||
| 61 | + stateName: '', | ||
| 62 | + remark: '', | ||
| 63 | + roomId: '', | ||
| 64 | + photos: [], | ||
| 65 | + videoName: '', | ||
| 66 | + url: '', | ||
| 67 | + detailType: '1001', | ||
| 68 | + isTrue: null, | ||
| 69 | + communityId: '' | ||
| 70 | + } | ||
| 71 | + } | ||
| 72 | + }, | ||
| 73 | + methods: { | ||
| 74 | + open(params) { | ||
| 75 | + this.resetForm() | ||
| 76 | + this.form.ardId = params[0] | ||
| 77 | + this.form.state = params[1] | ||
| 78 | + this.form.stateName = params[2] | ||
| 79 | + this.form.roomId = params[3] | ||
| 80 | + this.form.roomName = params[4] | ||
| 81 | + this.form.communityId = getCommunityId() | ||
| 82 | + this.visible = true | ||
| 83 | + }, | ||
| 84 | + resetForm() { | ||
| 85 | + this.form = { | ||
| 86 | + ardId: '', | ||
| 87 | + roomName: '', | ||
| 88 | + state: '', | ||
| 89 | + stateName: '', | ||
| 90 | + remark: '', | ||
| 91 | + roomId: '', | ||
| 92 | + photos: [], | ||
| 93 | + videoName: '', | ||
| 94 | + url: '', | ||
| 95 | + detailType: '1001', | ||
| 96 | + isTrue: null, | ||
| 97 | + communityId: '' | ||
| 98 | + } | ||
| 99 | + this.$refs.uploadImageUrl.clear() | ||
| 100 | + this.$refs.uploadVedio.clear() | ||
| 101 | + }, | ||
| 102 | + handleClose() { | ||
| 103 | + this.visible = false | ||
| 104 | + }, | ||
| 105 | + validateForm() { | ||
| 106 | + if (this.form.isTrue === null) { | ||
| 107 | + this.$message.error(this.$t('applyRoomDiscountRecord.violationRequired')) | ||
| 108 | + return false | ||
| 109 | + } | ||
| 110 | + if (!this.form.remark) { | ||
| 111 | + this.$message.error(this.$t('applyRoomDiscountRecord.remarkRequired')) | ||
| 112 | + return false | ||
| 113 | + } | ||
| 114 | + return true | ||
| 115 | + }, | ||
| 116 | + async saveApplyRoomDiscountRecordInfo() { | ||
| 117 | + if (!this.validateForm()) return | ||
| 118 | + | ||
| 119 | + try { | ||
| 120 | + this.form.photos = this.$refs.uploadImageUrl.getPhotos() | ||
| 121 | + this.form.videoName = this.$refs.uploadVedio.getVideoName() | ||
| 122 | + | ||
| 123 | + const res = await addApplyRoomDiscountRecord(this.form) | ||
| 124 | + if (res.code === 0) { | ||
| 125 | + this.$message.success(this.$t('common.saveSuccess')) | ||
| 126 | + this.handleClose() | ||
| 127 | + this.$emit('success') | ||
| 128 | + } else { | ||
| 129 | + this.$message.error(res.msg) | ||
| 130 | + } | ||
| 131 | + } catch (error) { | ||
| 132 | + this.$message.error(this.$t('common.saveFailed')) | ||
| 133 | + } | ||
| 134 | + } | ||
| 135 | + } | ||
| 136 | +} | ||
| 137 | +</script> | ||
| 0 | \ No newline at end of file | 138 | \ No newline at end of file |
src/components/fee/deleteApplyRoomDiscountRecord.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <el-dialog | ||
| 3 | + :title="$t('deleteApplyRoomDiscountRecord.title')" | ||
| 4 | + :visible.sync="visible" | ||
| 5 | + width="30%" | ||
| 6 | + :before-close="handleClose" | ||
| 7 | + > | ||
| 8 | + <div class="delete-content"> | ||
| 9 | + <i class="el-icon-warning" style="color: #e6a23c; font-size: 24px;"></i> | ||
| 10 | + <span style="margin-left: 10px;">{{ $t('deleteApplyRoomDiscountRecord.confirmText') }}</span> | ||
| 11 | + </div> | ||
| 12 | + <span slot="footer" class="dialog-footer"> | ||
| 13 | + <el-button @click="handleClose">{{ $t('common.cancel') }}</el-button> | ||
| 14 | + <el-button type="primary" @click="confirmDelete" :loading="loading">{{ $t('common.confirm') }}</el-button> | ||
| 15 | + </span> | ||
| 16 | + </el-dialog> | ||
| 17 | +</template> | ||
| 18 | + | ||
| 19 | +<script> | ||
| 20 | +import { cutApplyRoomDiscountRecord } from '@/api/fee/listApplyRoomDiscountRecordApi' | ||
| 21 | +import { getCommunityId } from '@/api/community/communityApi' | ||
| 22 | + | ||
| 23 | +export default { | ||
| 24 | + name: 'DeleteApplyRoomDiscountRecord', | ||
| 25 | + data() { | ||
| 26 | + return { | ||
| 27 | + visible: false, | ||
| 28 | + loading: false, | ||
| 29 | + record: null | ||
| 30 | + } | ||
| 31 | + }, | ||
| 32 | + methods: { | ||
| 33 | + open(record) { | ||
| 34 | + this.record = record | ||
| 35 | + this.visible = true | ||
| 36 | + }, | ||
| 37 | + handleClose() { | ||
| 38 | + this.visible = false | ||
| 39 | + }, | ||
| 40 | + async confirmDelete() { | ||
| 41 | + if (!this.record) return | ||
| 42 | + | ||
| 43 | + this.loading = true | ||
| 44 | + try { | ||
| 45 | + const params = { | ||
| 46 | + ardrId: this.record.ardrId, | ||
| 47 | + communityId: getCommunityId() | ||
| 48 | + } | ||
| 49 | + | ||
| 50 | + const res = await cutApplyRoomDiscountRecord(params) | ||
| 51 | + if (res.code === 0) { | ||
| 52 | + this.$message.success(this.$t('common.deleteSuccess')) | ||
| 53 | + this.handleClose() | ||
| 54 | + this.$emit('success') | ||
| 55 | + } else { | ||
| 56 | + this.$message.error(res.msg) | ||
| 57 | + } | ||
| 58 | + } catch (error) { | ||
| 59 | + this.$message.error(this.$t('common.deleteFailed')) | ||
| 60 | + } finally { | ||
| 61 | + this.loading = false | ||
| 62 | + } | ||
| 63 | + } | ||
| 64 | + } | ||
| 65 | +} | ||
| 66 | +</script> | ||
| 67 | + | ||
| 68 | +<style lang="scss" scoped> | ||
| 69 | +.delete-content { | ||
| 70 | + display: flex; | ||
| 71 | + align-items: center; | ||
| 72 | + justify-content: center; | ||
| 73 | + padding: 20px 0; | ||
| 74 | +} | ||
| 75 | +</style> | ||
| 0 | \ No newline at end of file | 76 | \ No newline at end of file |
src/components/fee/uploadImageUrl.vue
| 1 | <template> | 1 | <template> |
| 2 | <div class="upload-image-container"> | 2 | <div class="upload-image-container"> |
| 3 | - <div v-for="(image, index) in photos" :key="index" class="image-item"> | ||
| 4 | - <img :src="getImageUrl(image)" @error="handleImageError" /> | ||
| 5 | - <span class="remove-icon" @click="removeImage(index)"> | ||
| 6 | - <i class="el-icon-delete"></i> | ||
| 7 | - </span> | 3 | + <div class="image-preview"> |
| 4 | + <div v-for="(image, index) in photos" :key="index" class="image-item"> | ||
| 5 | + <el-image | ||
| 6 | + :src="image.url" | ||
| 7 | + fit="cover" | ||
| 8 | + :preview-src-list="previewList" | ||
| 9 | + style="width: 100px; height: 100px" | ||
| 10 | + ></el-image> | ||
| 11 | + <i class="el-icon-delete delete-icon" @click="removeImage(index)"></i> | ||
| 12 | + </div> | ||
| 13 | + <div v-if="photos.length < maxCount" class="upload-btn" @click="triggerUpload"> | ||
| 14 | + <i class="el-icon-plus"></i> | ||
| 15 | + </div> | ||
| 8 | </div> | 16 | </div> |
| 9 | - | ||
| 10 | - <div v-if="photos.length < imageCount" class="upload-btn" @click="triggerUpload"> | ||
| 11 | - <i class="el-icon-plus"></i> | ||
| 12 | - </div> | ||
| 13 | - | ||
| 14 | - <input | 17 | + <input |
| 18 | + type="file" | ||
| 15 | ref="fileInput" | 19 | ref="fileInput" |
| 16 | - type="file" | ||
| 17 | - accept="image/*" | ||
| 18 | - style="display: none" | 20 | + accept="image/*" |
| 21 | + style="display: none" | ||
| 19 | @change="handleFileChange" | 22 | @change="handleFileChange" |
| 23 | + multiple | ||
| 20 | /> | 24 | /> |
| 21 | </div> | 25 | </div> |
| 22 | </template> | 26 | </template> |
| 23 | 27 | ||
| 24 | <script> | 28 | <script> |
| 25 | -import { uploadFile } from '@/api/common' | 29 | +import { uploadImage } from '@/api/fee/listApplyRoomDiscountRecordApi' |
| 30 | +import { getCommunityId } from '@/api/community/communityApi' | ||
| 26 | 31 | ||
| 27 | export default { | 32 | export default { |
| 28 | name: 'UploadImageUrl', | 33 | name: 'UploadImageUrl', |
| 29 | props: { | 34 | props: { |
| 30 | - imageCount: { | 35 | + maxCount: { |
| 31 | type: Number, | 36 | type: Number, |
| 32 | default: 99 | 37 | default: 99 |
| 33 | } | 38 | } |
| 34 | }, | 39 | }, |
| 35 | data() { | 40 | data() { |
| 36 | return { | 41 | return { |
| 37 | - photos: [], // 用于显示的图片数组 | ||
| 38 | - photosUrl: [] // 实际存储的图片信息数组 | 42 | + photos: [], |
| 43 | + previewList: [] | ||
| 39 | } | 44 | } |
| 40 | }, | 45 | }, |
| 41 | methods: { | 46 | methods: { |
| @@ -46,66 +51,47 @@ export default { | @@ -46,66 +51,47 @@ export default { | ||
| 46 | const files = event.target.files | 51 | const files = event.target.files |
| 47 | if (!files || files.length === 0) return | 52 | if (!files || files.length === 0) return |
| 48 | 53 | ||
| 49 | - const file = files[0] | ||
| 50 | - if (file.size > 2 * 1024 * 1024) { | ||
| 51 | - this.$message.error(this.$t('uploadImage.validate.sizeLimit')) | 54 | + if (files.length + this.photos.length > this.maxCount) { |
| 55 | + this.$message.error(this.$t('uploadImage.maxCountError', { count: this.maxCount })) | ||
| 52 | return | 56 | return |
| 53 | } | 57 | } |
| 54 | 58 | ||
| 55 | - try { | ||
| 56 | - // 显示本地预览 | ||
| 57 | - const reader = new FileReader() | ||
| 58 | - reader.onload = (e) => { | ||
| 59 | - this.photos.push(e.target.result) | 59 | + for (let i = 0; i < files.length; i++) { |
| 60 | + const file = files[i] | ||
| 61 | + if (file.size > 2 * 1024 * 1024) { | ||
| 62 | + this.$message.error(this.$t('uploadImage.sizeError'))) | ||
| 63 | + continue | ||
| 60 | } | 64 | } |
| 61 | - reader.readAsDataURL(file) | ||
| 62 | 65 | ||
| 63 | - // 上传到服务器 | ||
| 64 | - const formData = new FormData() | ||
| 65 | - formData.append('uploadFile', file) | ||
| 66 | - formData.append('communityId', this.$store.getters.communityId) | 66 | + try { |
| 67 | + const formData = new FormData() | ||
| 68 | + formData.append('uploadFile', file) | ||
| 69 | + formData.append('communityId', getCommunityId()) | ||
| 67 | 70 | ||
| 68 | - const { data } = await uploadFile(formData) | ||
| 69 | - this.photosUrl.push(data) | ||
| 70 | - this.$emit('change', this.photosUrl) | ||
| 71 | - } catch (error) { | ||
| 72 | - this.$message.error(this.$t('uploadImage.message.uploadFailed')) | ||
| 73 | - } finally { | ||
| 74 | - event.target.value = null | 71 | + const res = await uploadImage(formData) |
| 72 | + if (res.code === 0) { | ||
| 73 | + this.photos.push({ | ||
| 74 | + fileId: res.data.fileId, | ||
| 75 | + url: res.data.url | ||
| 76 | + }) | ||
| 77 | + this.previewList.push(res.data.url) | ||
| 78 | + } | ||
| 79 | + } catch (error) { | ||
| 80 | + this.$message.error(this.$t('uploadImage.uploadFailed'))) | ||
| 81 | + } | ||
| 75 | } | 82 | } |
| 83 | + event.target.value = null | ||
| 76 | }, | 84 | }, |
| 77 | removeImage(index) { | 85 | removeImage(index) { |
| 78 | this.photos.splice(index, 1) | 86 | this.photos.splice(index, 1) |
| 79 | - this.photosUrl.splice(index, 1) | ||
| 80 | - this.$emit('change', this.photosUrl) | 87 | + this.previewList.splice(index, 1) |
| 81 | }, | 88 | }, |
| 82 | - handleImageError(e) { | ||
| 83 | - e.target.src = '/img/noPhoto.jpg' | ||
| 84 | - }, | ||
| 85 | - getImageUrl(image) { | ||
| 86 | - if (typeof image === 'string') { | ||
| 87 | - if (image.startsWith('http') || image.startsWith('https') || image.startsWith('data:')) { | ||
| 88 | - return image | ||
| 89 | - } | ||
| 90 | - return `/callComponent/download/getFile/file?fileId=${image}&communityId=-1&time=${new Date().getTime()}` | ||
| 91 | - } | ||
| 92 | - return image.url || '/img/noPhoto.jpg' | 89 | + getPhotos() { |
| 90 | + return this.photos.map(item => item.fileId) | ||
| 93 | }, | 91 | }, |
| 94 | clear() { | 92 | clear() { |
| 95 | this.photos = [] | 93 | this.photos = [] |
| 96 | - this.photosUrl = [] | ||
| 97 | - }, | ||
| 98 | - setImages(images) { | ||
| 99 | - this.photos = [] | ||
| 100 | - this.photosUrl = [] | ||
| 101 | - images.forEach(image => { | ||
| 102 | - if (image.startsWith('data:')) { | ||
| 103 | - this.photos.push(image) | ||
| 104 | - return | ||
| 105 | - } | ||
| 106 | - this.photosUrl.push({ fileId: image, url: image }) | ||
| 107 | - this.photos.push(this.getImageUrl(image)) | ||
| 108 | - }) | 94 | + this.previewList = [] |
| 109 | } | 95 | } |
| 110 | } | 96 | } |
| 111 | } | 97 | } |
| @@ -113,57 +99,45 @@ export default { | @@ -113,57 +99,45 @@ export default { | ||
| 113 | 99 | ||
| 114 | <style lang="scss" scoped> | 100 | <style lang="scss" scoped> |
| 115 | .upload-image-container { | 101 | .upload-image-container { |
| 116 | - display: flex; | ||
| 117 | - flex-wrap: wrap; | ||
| 118 | - gap: 10px; | 102 | + .image-preview { |
| 103 | + display: flex; | ||
| 104 | + flex-wrap: wrap; | ||
| 105 | + gap: 10px; | ||
| 119 | 106 | ||
| 120 | - .image-item { | ||
| 121 | - position: relative; | ||
| 122 | - width: 100px; | ||
| 123 | - height: 100px; | ||
| 124 | - border: 1px dashed #dcdfe6; | ||
| 125 | - border-radius: 4px; | ||
| 126 | - overflow: hidden; | 107 | + .image-item { |
| 108 | + position: relative; | ||
| 109 | + width: 100px; | ||
| 110 | + height: 100px; | ||
| 127 | 111 | ||
| 128 | - img { | ||
| 129 | - width: 100%; | ||
| 130 | - height: 100%; | ||
| 131 | - object-fit: cover; | 112 | + .delete-icon { |
| 113 | + position: absolute; | ||
| 114 | + top: -10px; | ||
| 115 | + right: -10px; | ||
| 116 | + color: #f56c6c; | ||
| 117 | + cursor: pointer; | ||
| 118 | + font-size: 16px; | ||
| 119 | + background: white; | ||
| 120 | + border-radius: 50%; | ||
| 121 | + padding: 2px; | ||
| 122 | + } | ||
| 132 | } | 123 | } |
| 133 | 124 | ||
| 134 | - .remove-icon { | ||
| 135 | - position: absolute; | ||
| 136 | - top: 0; | ||
| 137 | - right: 0; | ||
| 138 | - color: #f56c6c; | ||
| 139 | - background: rgba(255, 255, 255, 0.7); | ||
| 140 | - padding: 4px; | 125 | + .upload-btn { |
| 126 | + width: 100px; | ||
| 127 | + height: 100px; | ||
| 128 | + border: 1px dashed #dcdfe6; | ||
| 129 | + display: flex; | ||
| 130 | + justify-content: center; | ||
| 131 | + align-items: center; | ||
| 141 | cursor: pointer; | 132 | cursor: pointer; |
| 142 | - font-size: 16px; | 133 | + color: #909399; |
| 134 | + font-size: 24px; | ||
| 143 | 135 | ||
| 144 | &:hover { | 136 | &:hover { |
| 145 | - color: #f78989; | 137 | + border-color: #409eff; |
| 138 | + color: #409eff; | ||
| 146 | } | 139 | } |
| 147 | } | 140 | } |
| 148 | } | 141 | } |
| 149 | - | ||
| 150 | - .upload-btn { | ||
| 151 | - width: 100px; | ||
| 152 | - height: 100px; | ||
| 153 | - border: 1px dashed #dcdfe6; | ||
| 154 | - border-radius: 4px; | ||
| 155 | - display: flex; | ||
| 156 | - justify-content: center; | ||
| 157 | - align-items: center; | ||
| 158 | - cursor: pointer; | ||
| 159 | - color: #8c939d; | ||
| 160 | - font-size: 28px; | ||
| 161 | - background-color: #f5f7fa; | ||
| 162 | - | ||
| 163 | - &:hover { | ||
| 164 | - border-color: #409eff; | ||
| 165 | - color: #409eff; | ||
| 166 | - } | ||
| 167 | - } | ||
| 168 | } | 142 | } |
| 169 | </style> | 143 | </style> |
| 170 | \ No newline at end of file | 144 | \ No newline at end of file |
src/components/fee/uploadVedio.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <div class="upload-vedio-container"> | ||
| 3 | + <div v-if="progress > 0" class="progress-container"> | ||
| 4 | + <el-progress :percentage="progress" :stroke-width="2"></el-progress> | ||
| 5 | + <div class="file-name">{{ fileName }}</div> | ||
| 6 | + </div> | ||
| 7 | + | ||
| 8 | + <el-button | ||
| 9 | + type="primary" | ||
| 10 | + size="small" | ||
| 11 | + @click="triggerUpload" | ||
| 12 | + :disabled="uploading" | ||
| 13 | + > | ||
| 14 | + <i class="el-icon-upload"></i> | ||
| 15 | + {{ $t('uploadVedio.uploadButton') }} | ||
| 16 | + </el-button> | ||
| 17 | + <input | ||
| 18 | + type="file" | ||
| 19 | + ref="fileInput" | ||
| 20 | + accept="video/*" | ||
| 21 | + style="display: none" | ||
| 22 | + @change="handleFileChange" | ||
| 23 | + /> | ||
| 24 | + </div> | ||
| 25 | +</template> | ||
| 26 | + | ||
| 27 | +<script> | ||
| 28 | +import { uploadVedio } from '@/api/fee/listApplyRoomDiscountRecordApi' | ||
| 29 | +import { getCommunityId } from '@/api/community/communityApi' | ||
| 30 | + | ||
| 31 | +export default { | ||
| 32 | + name: 'UploadVedio', | ||
| 33 | + data() { | ||
| 34 | + return { | ||
| 35 | + fileName: '', | ||
| 36 | + realFileName: '', | ||
| 37 | + progress: 0, | ||
| 38 | + uploading: false | ||
| 39 | + } | ||
| 40 | + }, | ||
| 41 | + methods: { | ||
| 42 | + triggerUpload() { | ||
| 43 | + this.$refs.fileInput.click() | ||
| 44 | + }, | ||
| 45 | + async handleFileChange(event) { | ||
| 46 | + const file = event.target.files[0] | ||
| 47 | + if (!file) return | ||
| 48 | + | ||
| 49 | + if (file.size > 500 * 1024 * 1024) { | ||
| 50 | + this.$message.error(this.$t('uploadVedio.sizeError')) | ||
| 51 | + return | ||
| 52 | + } | ||
| 53 | + | ||
| 54 | + this.fileName = file.name | ||
| 55 | + this.uploading = true | ||
| 56 | + this.progress = 0 | ||
| 57 | + | ||
| 58 | + try { | ||
| 59 | + const formData = new FormData() | ||
| 60 | + formData.append('uploadFile', file) | ||
| 61 | + formData.append('communityId', getCommunityId()) | ||
| 62 | + | ||
| 63 | + const res = await uploadVedio(formData, { | ||
| 64 | + onUploadProgress: (progressEvent) => { | ||
| 65 | + this.progress = Math.round((progressEvent.loaded * 90) / progressEvent.total) | ||
| 66 | + } | ||
| 67 | + }) | ||
| 68 | + | ||
| 69 | + if (res.code === 0) { | ||
| 70 | + this.progress = 100 | ||
| 71 | + this.realFileName = res.data.realFileName | ||
| 72 | + this.$message.success(this.$t('uploadVedio.uploadSuccess')) | ||
| 73 | + } | ||
| 74 | + } catch (error) { | ||
| 75 | + this.$message.error(this.$t('uploadVedio.uploadFailed')) | ||
| 76 | + } finally { | ||
| 77 | + this.uploading = false | ||
| 78 | + event.target.value = null | ||
| 79 | + } | ||
| 80 | + }, | ||
| 81 | + getVideoName() { | ||
| 82 | + return this.realFileName | ||
| 83 | + }, | ||
| 84 | + clear() { | ||
| 85 | + this.fileName = '' | ||
| 86 | + this.realFileName = '' | ||
| 87 | + this.progress = 0 | ||
| 88 | + this.uploading = false | ||
| 89 | + } | ||
| 90 | + } | ||
| 91 | +} | ||
| 92 | +</script> | ||
| 93 | + | ||
| 94 | +<style lang="scss" scoped> | ||
| 95 | +.upload-vedio-container { | ||
| 96 | + .progress-container { | ||
| 97 | + margin-bottom: 10px; | ||
| 98 | + | ||
| 99 | + .file-name { | ||
| 100 | + font-size: 12px; | ||
| 101 | + color: #606266; | ||
| 102 | + margin-top: 5px; | ||
| 103 | + word-break: break-all; | ||
| 104 | + } | ||
| 105 | + } | ||
| 106 | +} | ||
| 107 | +</style> | ||
| 0 | \ No newline at end of file | 108 | \ No newline at end of file |
src/i18n/feeI18n.js
| @@ -5,6 +5,11 @@ import { messages as returnPayFeeManageMessages } from '../views/fee/returnPayFe | @@ -5,6 +5,11 @@ import { messages as returnPayFeeManageMessages } from '../views/fee/returnPayFe | ||
| 5 | import { messages as feeDiscountManageMessages } from '../views/fee/feeDiscountManageLang' | 5 | import { messages as feeDiscountManageMessages } from '../views/fee/feeDiscountManageLang' |
| 6 | import { messages as applyRoomDiscountManageMessages } from '../views/fee/applyRoomDiscountManageLang' | 6 | import { messages as applyRoomDiscountManageMessages } from '../views/fee/applyRoomDiscountManageLang' |
| 7 | import { messages as discountTypeMessages } from '../views/fee/discountTypeLang' | 7 | import { messages as discountTypeMessages } from '../views/fee/discountTypeLang' |
| 8 | +import { messages as listApplyRoomDiscountRecordMessages } from '../views/fee/listApplyRoomDiscountRecordLang' | ||
| 9 | +import { messages as feeReceiptMessages } from '../views/fee/feeReceiptLang' | ||
| 10 | +import { messages as printPayFeeMessages } from '../views/fee/printPayFeeLang' | ||
| 11 | +import { messages as printPayFeeBangTaiMessages } from '../views/fee/printPayFeeBangTaiLang' | ||
| 12 | +import { messages as printSmallPayFeeMessages } from '../views/fee/printSmallPayFeeLang' | ||
| 8 | 13 | ||
| 9 | export const messages = { | 14 | export const messages = { |
| 10 | en: { | 15 | en: { |
| @@ -15,6 +20,11 @@ export const messages = { | @@ -15,6 +20,11 @@ export const messages = { | ||
| 15 | ...feeDiscountManageMessages.en, | 20 | ...feeDiscountManageMessages.en, |
| 16 | ...applyRoomDiscountManageMessages.en, | 21 | ...applyRoomDiscountManageMessages.en, |
| 17 | ...discountTypeMessages.en, | 22 | ...discountTypeMessages.en, |
| 23 | + ...listApplyRoomDiscountRecordMessages.en, | ||
| 24 | + ...feeReceiptMessages.en, | ||
| 25 | + ...printPayFeeMessages.en, | ||
| 26 | + ...printPayFeeBangTaiMessages.en, | ||
| 27 | + ...printSmallPayFeeMessages.en, | ||
| 18 | }, | 28 | }, |
| 19 | zh: { | 29 | zh: { |
| 20 | ...contractCreateFeeMessages.zh, | 30 | ...contractCreateFeeMessages.zh, |
| @@ -24,5 +34,10 @@ export const messages = { | @@ -24,5 +34,10 @@ export const messages = { | ||
| 24 | ...feeDiscountManageMessages.zh, | 34 | ...feeDiscountManageMessages.zh, |
| 25 | ...applyRoomDiscountManageMessages.zh, | 35 | ...applyRoomDiscountManageMessages.zh, |
| 26 | ...discountTypeMessages.zh, | 36 | ...discountTypeMessages.zh, |
| 37 | + ...listApplyRoomDiscountRecordMessages.zh, | ||
| 38 | + ...feeReceiptMessages.zh, | ||
| 39 | + ...printPayFeeMessages.zh, | ||
| 40 | + ...printPayFeeBangTaiMessages.zh, | ||
| 41 | + ...printSmallPayFeeMessages.zh, | ||
| 27 | } | 42 | } |
| 28 | } | 43 | } |
| 29 | \ No newline at end of file | 44 | \ No newline at end of file |
src/router/feeRouter.js
| @@ -30,8 +30,19 @@ export default [ | @@ -30,8 +30,19 @@ export default [ | ||
| 30 | component: () => import('@/views/fee/applyRoomDiscountManageList.vue') | 30 | component: () => import('@/views/fee/applyRoomDiscountManageList.vue') |
| 31 | }, | 31 | }, |
| 32 | { | 32 | { |
| 33 | - path:'/views/fee/discountType', | ||
| 34 | - name:'/views/fee/discountType', | 33 | + path: '/views/fee/discountType', |
| 34 | + name: '/views/fee/discountType', | ||
| 35 | component: () => import('@/views/fee/discountTypeList.vue') | 35 | component: () => import('@/views/fee/discountTypeList.vue') |
| 36 | - }, | 36 | + }, |
| 37 | + { | ||
| 38 | + path: '/views/fee/listApplyRoomDiscountRecord', | ||
| 39 | + name: '/views/fee/listApplyRoomDiscountRecord', | ||
| 40 | + component: () => import('@/views/fee/listApplyRoomDiscountRecordList.vue') | ||
| 41 | + }, | ||
| 42 | + { | ||
| 43 | + path: '/pages/property/feeReceipt', | ||
| 44 | + name: '/pages/property/feeReceipt', | ||
| 45 | + component: () => import('@/views/fee/feeReceiptList.vue') | ||
| 46 | + }, | ||
| 47 | + | ||
| 37 | ] | 48 | ] |
| 38 | \ No newline at end of file | 49 | \ No newline at end of file |
src/router/index.js
| @@ -15,7 +15,7 @@ import scmRouter from './scmRouter' | @@ -15,7 +15,7 @@ import scmRouter from './scmRouter' | ||
| 15 | import userRouter from './userRouter' | 15 | import userRouter from './userRouter' |
| 16 | import systemRouter from './systemRouter' | 16 | import systemRouter from './systemRouter' |
| 17 | import communityRouter from './communityRouter' | 17 | import communityRouter from './communityRouter' |
| 18 | -import workRouter from './workRouter' | 18 | +import workRouter from './workRouter' |
| 19 | import feeRouter from './feeRouter' | 19 | import feeRouter from './feeRouter' |
| 20 | 20 | ||
| 21 | Vue.use(VueRouter) | 21 | Vue.use(VueRouter) |
| @@ -31,13 +31,13 @@ const routes = [ | @@ -31,13 +31,13 @@ const routes = [ | ||
| 31 | name: '/views/index/index', | 31 | name: '/views/index/index', |
| 32 | component: () => import('@/views/index/index.vue') | 32 | component: () => import('@/views/index/index.vue') |
| 33 | }, | 33 | }, |
| 34 | - | 34 | + |
| 35 | { | 35 | { |
| 36 | path: '/pages/frame/changeStaffPwd', | 36 | path: '/pages/frame/changeStaffPwd', |
| 37 | name: '/pages/frame/changeStaffPwd', | 37 | name: '/pages/frame/changeStaffPwd', |
| 38 | component: () => import('@/views/user/login/updatePwd.vue') | 38 | component: () => import('@/views/user/login/updatePwd.vue') |
| 39 | }, | 39 | }, |
| 40 | - | 40 | + |
| 41 | { | 41 | { |
| 42 | 42 | ||
| 43 | path: '/pages/frame/orgManage', | 43 | path: '/pages/frame/orgManage', |
| @@ -68,7 +68,7 @@ const routes = [ | @@ -68,7 +68,7 @@ const routes = [ | ||
| 68 | component: () => import('@/views/staff/staffDetailList.vue') | 68 | component: () => import('@/views/staff/staffDetailList.vue') |
| 69 | }, | 69 | }, |
| 70 | 70 | ||
| 71 | - | 71 | + |
| 72 | { | 72 | { |
| 73 | path: '/pages/log/mqttLog', | 73 | path: '/pages/log/mqttLog', |
| 74 | name: '/pages/log/mqttLog', | 74 | name: '/pages/log/mqttLog', |
| @@ -84,7 +84,7 @@ const routes = [ | @@ -84,7 +84,7 @@ const routes = [ | ||
| 84 | name: '/pages/frame/registerProtocol', | 84 | name: '/pages/frame/registerProtocol', |
| 85 | component: () => import('@/views/system/registerProtocolList.vue') | 85 | component: () => import('@/views/system/registerProtocolList.vue') |
| 86 | }, | 86 | }, |
| 87 | - | 87 | + |
| 88 | { | 88 | { |
| 89 | path: '/views/report/reportCustomComponentRelManage', | 89 | path: '/views/report/reportCustomComponentRelManage', |
| 90 | name: '/views/report/reportCustomComponentRelManage', | 90 | name: '/views/report/reportCustomComponentRelManage', |
| @@ -100,7 +100,7 @@ const routes = [ | @@ -100,7 +100,7 @@ const routes = [ | ||
| 100 | name: '/views/report/reportCustomComponentFooterManage', | 100 | name: '/views/report/reportCustomComponentFooterManage', |
| 101 | component: () => import('@/views/report/reportCustomComponentFooterManageList.vue') | 101 | component: () => import('@/views/report/reportCustomComponentFooterManageList.vue') |
| 102 | }, | 102 | }, |
| 103 | - | 103 | + |
| 104 | { | 104 | { |
| 105 | path: '/pages/common/communityManage', | 105 | path: '/pages/common/communityManage', |
| 106 | name: '/pages/common/communityManage', | 106 | name: '/pages/common/communityManage', |
| @@ -166,7 +166,7 @@ const routes = [ | @@ -166,7 +166,7 @@ const routes = [ | ||
| 166 | name: '/pages/owner/adminOwner', | 166 | name: '/pages/owner/adminOwner', |
| 167 | component: () => import('@/views/owner/adminOwnerList.vue') | 167 | component: () => import('@/views/owner/adminOwnerList.vue') |
| 168 | }, | 168 | }, |
| 169 | - | 169 | + |
| 170 | { | 170 | { |
| 171 | path: '/pages/owner/adminAuthOwner', | 171 | path: '/pages/owner/adminAuthOwner', |
| 172 | name: '/pages/owner/adminAuthOwner', | 172 | name: '/pages/owner/adminAuthOwner', |
| @@ -187,7 +187,7 @@ const routes = [ | @@ -187,7 +187,7 @@ const routes = [ | ||
| 187 | name: '/pages/fee/adminFeeConfig', | 187 | name: '/pages/fee/adminFeeConfig', |
| 188 | component: () => import('@/views/fee/adminFeeConfigList.vue') | 188 | component: () => import('@/views/fee/adminFeeConfigList.vue') |
| 189 | }, | 189 | }, |
| 190 | - | 190 | + |
| 191 | { | 191 | { |
| 192 | path: '/pages/fee/adminRoomFee', | 192 | path: '/pages/fee/adminRoomFee', |
| 193 | name: '/pages/fee/adminRoomFee', | 193 | name: '/pages/fee/adminRoomFee', |
| @@ -566,7 +566,7 @@ const routes = [ | @@ -566,7 +566,7 @@ const routes = [ | ||
| 566 | name: '/views/fee/feeConfigDetail', | 566 | name: '/views/fee/feeConfigDetail', |
| 567 | component: () => import('@/views/fee/feeConfigDetailList.vue') | 567 | component: () => import('@/views/fee/feeConfigDetailList.vue') |
| 568 | }, | 568 | }, |
| 569 | - | 569 | + |
| 570 | { | 570 | { |
| 571 | path: '/pages/property/carCreateFee', | 571 | path: '/pages/property/carCreateFee', |
| 572 | name: '/pages/property/carCreateFee', | 572 | name: '/pages/property/carCreateFee', |
| @@ -621,7 +621,7 @@ const routes = [ | @@ -621,7 +621,7 @@ const routes = [ | ||
| 621 | path: '/pages/property/repairForceFinishManage', | 621 | path: '/pages/property/repairForceFinishManage', |
| 622 | name: '/pages/property/repairForceFinishManage', | 622 | name: '/pages/property/repairForceFinishManage', |
| 623 | component: () => import('@/views/work/repairForceFinishManageList.vue') | 623 | component: () => import('@/views/work/repairForceFinishManageList.vue') |
| 624 | - }, | 624 | + }, |
| 625 | { | 625 | { |
| 626 | path: '/pages/property/locationManage', | 626 | path: '/pages/property/locationManage', |
| 627 | name: '/pages/property/locationManage', | 627 | name: '/pages/property/locationManage', |
| @@ -679,6 +679,21 @@ const routes = [ | @@ -679,6 +679,21 @@ const routes = [ | ||
| 679 | name: '/views/contract/printContract', | 679 | name: '/views/contract/printContract', |
| 680 | component: () => import('@/views/contract/printContractList.vue') | 680 | component: () => import('@/views/contract/printContractList.vue') |
| 681 | }, | 681 | }, |
| 682 | + { | ||
| 683 | + path: '/pages/property/printPayFee', | ||
| 684 | + name: '/pages/property/printPayFee', | ||
| 685 | + component: () => import('@/views/fee/printPayFeeList.vue') | ||
| 686 | + }, | ||
| 687 | + { | ||
| 688 | + path: '/pages/property/printPayFeeBangTai', | ||
| 689 | + name: '/pages/property/printPayFeeBangTai', | ||
| 690 | + component: () => import('@/views/fee/printPayFeeBangTaiList.vue') | ||
| 691 | + }, | ||
| 692 | + { | ||
| 693 | + path:'/pages/property/printSmallPayFee', | ||
| 694 | + name:'/pages/property/printSmallPayFee', | ||
| 695 | + component: () => import('@/views/fee/printSmallPayFeeList.vue') | ||
| 696 | + }, | ||
| 682 | ] | 697 | ] |
| 683 | 698 | ||
| 684 | const router = new VueRouter({ | 699 | const router = new VueRouter({ |
src/views/fee/applyRoomDiscountManageList.vue
| @@ -231,7 +231,7 @@ export default { | @@ -231,7 +231,7 @@ export default { | ||
| 231 | }, | 231 | }, |
| 232 | handleOpenRecord(row) { | 232 | handleOpenRecord(row) { |
| 233 | this.$router.push({ | 233 | this.$router.push({ |
| 234 | - path: '/pages/property/listApplyRoomDiscountRecord', | 234 | + path: '/views/fee/listApplyRoomDiscountRecord', |
| 235 | query: { | 235 | query: { |
| 236 | ardId: row.ardId, | 236 | ardId: row.ardId, |
| 237 | roomId: row.roomId, | 237 | roomId: row.roomId, |
src/views/fee/discountTypeLang.js
| @@ -43,16 +43,6 @@ export const messages = { | @@ -43,16 +43,6 @@ export const messages = { | ||
| 43 | }, | 43 | }, |
| 44 | fetchError: 'Failed to fetch discount types' | 44 | fetchError: 'Failed to fetch discount types' |
| 45 | }, | 45 | }, |
| 46 | - common: { | ||
| 47 | - search: 'Search', | ||
| 48 | - add: 'Add', | ||
| 49 | - edit: 'Edit', | ||
| 50 | - delete: 'Delete', | ||
| 51 | - back: 'Back', | ||
| 52 | - cancel: 'Cancel', | ||
| 53 | - confirm: 'Confirm', | ||
| 54 | - operation: 'Operation' | ||
| 55 | - } | ||
| 56 | }, | 46 | }, |
| 57 | zh: { | 47 | zh: { |
| 58 | discountType: { | 48 | discountType: { |
| @@ -98,15 +88,5 @@ export const messages = { | @@ -98,15 +88,5 @@ export const messages = { | ||
| 98 | }, | 88 | }, |
| 99 | fetchError: '获取优惠类型失败' | 89 | fetchError: '获取优惠类型失败' |
| 100 | }, | 90 | }, |
| 101 | - common: { | ||
| 102 | - search: '查询', | ||
| 103 | - add: '添加', | ||
| 104 | - edit: '修改', | ||
| 105 | - delete: '删除', | ||
| 106 | - back: '返回', | ||
| 107 | - cancel: '取消', | ||
| 108 | - confirm: '确认', | ||
| 109 | - operation: '操作' | ||
| 110 | - } | ||
| 111 | } | 91 | } |
| 112 | } | 92 | } |
| 113 | \ No newline at end of file | 93 | \ No newline at end of file |
src/views/fee/feeReceiptLang.js
0 → 100644
| 1 | +export const messages = { | ||
| 2 | + en: { | ||
| 3 | + feeReceipt: { | ||
| 4 | + search: { | ||
| 5 | + title: 'Search Conditions', | ||
| 6 | + receiptId: 'Please enter receipt ID', | ||
| 7 | + roomId: 'Please enter room/carport info, format: building-unit-room, e.g. 1-1-1', | ||
| 8 | + objType: 'Please select fee type', | ||
| 9 | + all: 'All', | ||
| 10 | + houseFee: 'House Fee', | ||
| 11 | + parkingFee: 'Parking Fee', | ||
| 12 | + startTime: 'Please select start time', | ||
| 13 | + endTime: 'Please select end time' | ||
| 14 | + }, | ||
| 15 | + list: { | ||
| 16 | + title: 'Receipt Information' | ||
| 17 | + }, | ||
| 18 | + table: { | ||
| 19 | + receiptId: 'Receipt ID', | ||
| 20 | + receiptCode: 'Receipt Code', | ||
| 21 | + objType: 'Fee Type', | ||
| 22 | + feeName: 'Fee Item', | ||
| 23 | + roomName: 'Room', | ||
| 24 | + payObjName: 'Owner', | ||
| 25 | + carNum: 'Carport', | ||
| 26 | + amount: 'Total Amount(¥)', | ||
| 27 | + createTime: 'Payment Time' | ||
| 28 | + }, | ||
| 29 | + button: { | ||
| 30 | + reprint: 'Reprint Receipt', | ||
| 31 | + reprintSmall: 'Reprint Small Receipt' | ||
| 32 | + }, | ||
| 33 | + fetchError: 'Failed to fetch receipt data' | ||
| 34 | + } | ||
| 35 | + }, | ||
| 36 | + zh: { | ||
| 37 | + feeReceipt: { | ||
| 38 | + search: { | ||
| 39 | + title: '查询条件', | ||
| 40 | + receiptId: '请输入收据ID', | ||
| 41 | + roomId: '请输入房屋或车位信息,格式为楼栋-单元-房屋,如1-1-1', | ||
| 42 | + objType: '请选择收费类型', | ||
| 43 | + all: '全部', | ||
| 44 | + houseFee: '房屋费', | ||
| 45 | + parkingFee: '车位费', | ||
| 46 | + startTime: '请选择开始时间', | ||
| 47 | + endTime: '请选择结束时间' | ||
| 48 | + }, | ||
| 49 | + list: { | ||
| 50 | + title: '收据信息' | ||
| 51 | + }, | ||
| 52 | + table: { | ||
| 53 | + receiptId: '收据ID', | ||
| 54 | + receiptCode: '收据编号', | ||
| 55 | + objType: '费用类型', | ||
| 56 | + feeName: '费用项', | ||
| 57 | + roomName: '房屋', | ||
| 58 | + payObjName: '业主', | ||
| 59 | + carNum: '车位', | ||
| 60 | + amount: '总金额(单位:元)', | ||
| 61 | + createTime: '缴费时间' | ||
| 62 | + }, | ||
| 63 | + button: { | ||
| 64 | + reprint: '补打收据', | ||
| 65 | + reprintSmall: '补打小票' | ||
| 66 | + }, | ||
| 67 | + fetchError: '获取收据数据失败' | ||
| 68 | + } | ||
| 69 | + } | ||
| 70 | +} | ||
| 0 | \ No newline at end of file | 71 | \ No newline at end of file |
src/views/fee/feeReceiptList.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <div class="fee-receipt-container"> | ||
| 3 | + <!-- 查询条件 --> | ||
| 4 | + <el-card class="search-wrapper"> | ||
| 5 | + <div slot="header" class="flex justify-between"> | ||
| 6 | + <span>{{ $t('feeReceipt.search.title') }}</span> | ||
| 7 | + <el-button type="text" style="float: right; padding: 3px 0" @click="_moreCondition"> | ||
| 8 | + {{ feeReceiptManageInfo.moreCondition ? $t('common.hide') : $t('common.more') }} | ||
| 9 | + </el-button> | ||
| 10 | + </div> | ||
| 11 | + <el-row :gutter="20"> | ||
| 12 | + <el-col :span="6"> | ||
| 13 | + <el-input v-model="feeReceiptManageInfo.conditions.receiptId" :placeholder="$t('feeReceipt.search.receiptId')" | ||
| 14 | + clearable /> | ||
| 15 | + </el-col> | ||
| 16 | + <el-col :span="8"> | ||
| 17 | + <el-input v-model="feeReceiptManageInfo.conditions.roomId" :placeholder="$t('feeReceipt.search.roomId')" | ||
| 18 | + clearable /> | ||
| 19 | + </el-col> | ||
| 20 | + <el-col :span="6"> | ||
| 21 | + <el-select v-model="feeReceiptManageInfo.conditions.objType" :placeholder="$t('feeReceipt.search.objType')" | ||
| 22 | + style="width:100%"> | ||
| 23 | + <el-option :label="$t('feeReceipt.search.all')" value="" /> | ||
| 24 | + <el-option :label="$t('feeReceipt.search.houseFee')" value="3333" /> | ||
| 25 | + <el-option :label="$t('feeReceipt.search.parkingFee')" value="6666" /> | ||
| 26 | + </el-select> | ||
| 27 | + </el-col> | ||
| 28 | + <el-col :span="4"> | ||
| 29 | + <el-button type="primary" @click="_queryFeeReceiptMethod"> | ||
| 30 | + <i class="el-icon-search"></i> | ||
| 31 | + {{ $t('common.search') }} | ||
| 32 | + </el-button> | ||
| 33 | + <el-button @click="_resetFeeReceiptMethod"> | ||
| 34 | + <i class="el-icon-refresh"></i> | ||
| 35 | + {{ $t('common.reset') }} | ||
| 36 | + </el-button> | ||
| 37 | + </el-col> | ||
| 38 | + </el-row> | ||
| 39 | + | ||
| 40 | + <el-row v-show="feeReceiptManageInfo.moreCondition" :gutter="20" style="margin-top:20px"> | ||
| 41 | + <el-col :span="6"> | ||
| 42 | + <el-date-picker v-model="feeReceiptManageInfo.conditions.qstartTime" type="date" | ||
| 43 | + :placeholder="$t('feeReceipt.search.startTime')" style="width:100%" /> | ||
| 44 | + </el-col> | ||
| 45 | + <el-col :span="6"> | ||
| 46 | + <el-date-picker v-model="feeReceiptManageInfo.conditions.qendTime" type="date" | ||
| 47 | + :placeholder="$t('feeReceipt.search.endTime')" style="width:100%" /> | ||
| 48 | + </el-col> | ||
| 49 | + </el-row> | ||
| 50 | + </el-card> | ||
| 51 | + | ||
| 52 | + <!-- 收据信息 --> | ||
| 53 | + <el-card class="list-wrapper"> | ||
| 54 | + <div slot="header" class="flex justify-between"> | ||
| 55 | + <span>{{ $t('feeReceipt.list.title') }}</span> | ||
| 56 | + </div> | ||
| 57 | + | ||
| 58 | + <el-table v-loading="loading" :data="feeReceiptManageInfo.feeReceipts" border style="width: 100%"> | ||
| 59 | + <el-table-column prop="receiptId" :label="$t('feeReceipt.table.receiptId')" align="center" /> | ||
| 60 | + <el-table-column prop="receiptCode" :label="$t('feeReceipt.table.receiptCode')" align="center"> | ||
| 61 | + <template slot-scope="scope"> | ||
| 62 | + {{ scope.row.receiptCode || '-' }} | ||
| 63 | + </template> | ||
| 64 | + </el-table-column> | ||
| 65 | + <el-table-column prop="objType" :label="$t('feeReceipt.table.objType')" align="center"> | ||
| 66 | + <template slot-scope="scope"> | ||
| 67 | + {{ scope.row.objType === '3333' ? $t('feeReceipt.search.houseFee') : $t('feeReceipt.search.parkingFee') }} | ||
| 68 | + </template> | ||
| 69 | + </el-table-column> | ||
| 70 | + <el-table-column prop="feeName" :label="$t('feeReceipt.table.feeName')" align="center" /> | ||
| 71 | + <el-table-column prop="roomName" :label="$t('feeReceipt.table.roomName')" align="center" /> | ||
| 72 | + <el-table-column prop="payObjName" :label="$t('feeReceipt.table.payObjName')" align="center" /> | ||
| 73 | + <el-table-column prop="carNum" :label="$t('feeReceipt.table.carNum')" align="center" /> | ||
| 74 | + <el-table-column prop="amount" :label="$t('feeReceipt.table.amount')" align="center" /> | ||
| 75 | + <el-table-column prop="createTime" :label="$t('feeReceipt.table.createTime')" align="center" /> | ||
| 76 | + <el-table-column :label="$t('common.operation')" align="center" width="200"> | ||
| 77 | + <template slot-scope="scope"> | ||
| 78 | + <el-button size="mini" type="primary" @click="_printFeeReceipt(scope.row)"> | ||
| 79 | + {{ $t('feeReceipt.button.reprint') }} | ||
| 80 | + </el-button> | ||
| 81 | + <el-button size="mini" type="success" @click="_printFeeSmallReceipt(scope.row)"> | ||
| 82 | + {{ $t('feeReceipt.button.reprintSmall') }} | ||
| 83 | + </el-button> | ||
| 84 | + </template> | ||
| 85 | + </el-table-column> | ||
| 86 | + </el-table> | ||
| 87 | + | ||
| 88 | + <el-pagination :current-page.sync="page.current" :page-sizes="[10, 20, 30, 50]" :page-size="page.size" | ||
| 89 | + :total="page.total" layout="total, sizes, prev, pager, next, jumper" @size-change="handleSizeChange" | ||
| 90 | + @current-change="handleCurrentChange" /> | ||
| 91 | + </el-card> | ||
| 92 | + </div> | ||
| 93 | +</template> | ||
| 94 | + | ||
| 95 | +<script> | ||
| 96 | +import { queryFeeReceipt, listFeePrintPage } from '@/api/fee/feeReceiptApi' | ||
| 97 | +import { getCommunityId } from '@/api/community/communityApi' | ||
| 98 | + | ||
| 99 | +export default { | ||
| 100 | + name: 'FeeReceiptList', | ||
| 101 | + data() { | ||
| 102 | + return { | ||
| 103 | + loading: false, | ||
| 104 | + feeReceiptManageInfo: { | ||
| 105 | + feeReceipts: [], | ||
| 106 | + moreCondition: false, | ||
| 107 | + printUrl: '/print.html#/pages/property/printPayFee', | ||
| 108 | + conditions: { | ||
| 109 | + objType: '', | ||
| 110 | + storeName: '', | ||
| 111 | + objId: '', | ||
| 112 | + month: '', | ||
| 113 | + qstartTime: '', | ||
| 114 | + qendTime: '', | ||
| 115 | + type: '', | ||
| 116 | + roomId: '', | ||
| 117 | + communityId: getCommunityId(), | ||
| 118 | + receiptId: '', | ||
| 119 | + page: 1, | ||
| 120 | + row: 10 | ||
| 121 | + } | ||
| 122 | + }, | ||
| 123 | + page: { | ||
| 124 | + current: 1, | ||
| 125 | + size: 10, | ||
| 126 | + total: 0 | ||
| 127 | + } | ||
| 128 | + } | ||
| 129 | + }, | ||
| 130 | + created() { | ||
| 131 | + this._listFeeReceipts() | ||
| 132 | + this._listFeePrintPages() | ||
| 133 | + }, | ||
| 134 | + methods: { | ||
| 135 | + async _listFeeReceipts() { | ||
| 136 | + try { | ||
| 137 | + this.loading = true | ||
| 138 | + const params = { | ||
| 139 | + ...this.feeReceiptManageInfo.conditions, | ||
| 140 | + page: this.page.current, | ||
| 141 | + row: this.page.size | ||
| 142 | + } | ||
| 143 | + const { data, total } = await queryFeeReceipt(params) | ||
| 144 | + this.feeReceiptManageInfo.feeReceipts = data | ||
| 145 | + this.page.total = total | ||
| 146 | + } catch (error) { | ||
| 147 | + this.$message.error(this.$t('feeReceipt.fetchError')) | ||
| 148 | + } finally { | ||
| 149 | + this.loading = false | ||
| 150 | + } | ||
| 151 | + }, | ||
| 152 | + async _listFeePrintPages() { | ||
| 153 | + try { | ||
| 154 | + const params = { | ||
| 155 | + page: 1, | ||
| 156 | + row: 1, | ||
| 157 | + state: 'T', | ||
| 158 | + communityId: getCommunityId() | ||
| 159 | + } | ||
| 160 | + const { data } = await listFeePrintPage(params) | ||
| 161 | + if (data && data.length > 0) { | ||
| 162 | + this.feeReceiptManageInfo.printUrl = data[0].url | ||
| 163 | + } | ||
| 164 | + } catch (error) { | ||
| 165 | + console.error('请求失败:', error) | ||
| 166 | + } | ||
| 167 | + }, | ||
| 168 | + _queryFeeReceiptMethod() { | ||
| 169 | + this.page.current = 1 | ||
| 170 | + this._listFeeReceipts() | ||
| 171 | + }, | ||
| 172 | + _resetFeeReceiptMethod() { | ||
| 173 | + this.feeReceiptManageInfo.conditions = { | ||
| 174 | + ...this.feeReceiptManageInfo.conditions, | ||
| 175 | + objType: '', | ||
| 176 | + roomId: '', | ||
| 177 | + receiptId: '', | ||
| 178 | + qstartTime: '', | ||
| 179 | + qendTime: '' | ||
| 180 | + } | ||
| 181 | + this._listFeeReceipts() | ||
| 182 | + }, | ||
| 183 | + _printFeeReceipt(receipt) { | ||
| 184 | + window.open(`${this.feeReceiptManageInfo.printUrl}?receiptId=${receipt.receiptId}`) | ||
| 185 | + }, | ||
| 186 | + _printFeeSmallReceipt(receipt) { | ||
| 187 | + window.open(`/smallPrint.html#/pages/property/printSmallPayFee?receiptIds=${receipt.receiptId}`) | ||
| 188 | + }, | ||
| 189 | + _moreCondition() { | ||
| 190 | + this.feeReceiptManageInfo.moreCondition = !this.feeReceiptManageInfo.moreCondition | ||
| 191 | + }, | ||
| 192 | + handleSizeChange(val) { | ||
| 193 | + this.page.size = val | ||
| 194 | + this._listFeeReceipts() | ||
| 195 | + }, | ||
| 196 | + handleCurrentChange(val) { | ||
| 197 | + this.page.current = val | ||
| 198 | + this._listFeeReceipts() | ||
| 199 | + } | ||
| 200 | + } | ||
| 201 | +} | ||
| 202 | +</script> | ||
| 203 | + | ||
| 204 | +<style lang="scss" scoped> | ||
| 205 | +.fee-receipt-container { | ||
| 206 | + padding: 20px; | ||
| 207 | + | ||
| 208 | + .search-wrapper { | ||
| 209 | + margin-bottom: 20px; | ||
| 210 | + | ||
| 211 | + .el-row { | ||
| 212 | + margin-bottom: 20px; | ||
| 213 | + } | ||
| 214 | + } | ||
| 215 | + | ||
| 216 | + .list-wrapper { | ||
| 217 | + .el-pagination { | ||
| 218 | + margin-top: 20px; | ||
| 219 | + text-align: right; | ||
| 220 | + } | ||
| 221 | + } | ||
| 222 | +} | ||
| 223 | +</style> | ||
| 0 | \ No newline at end of file | 224 | \ No newline at end of file |
src/views/fee/listApplyRoomDiscountRecordLang.js
0 → 100644
| 1 | +export const messages = { | ||
| 2 | + en: { | ||
| 3 | + listApplyRoomDiscountRecord: { | ||
| 4 | + title: 'Decoration Tracking Record', | ||
| 5 | + id: 'ID', | ||
| 6 | + room: 'Room', | ||
| 7 | + operator: 'Operator', | ||
| 8 | + createTime: 'Create Time', | ||
| 9 | + status: 'Status', | ||
| 10 | + isViolation: 'Is Violation', | ||
| 11 | + remark: 'Remark', | ||
| 12 | + fetchError: 'Failed to fetch records' | ||
| 13 | + }, | ||
| 14 | + applyRoomDiscountRecord: { | ||
| 15 | + title: 'Inspection Tracking', | ||
| 16 | + room: 'Room', | ||
| 17 | + status: 'Status', | ||
| 18 | + isViolation: 'Is Violation', | ||
| 19 | + selectViolation: 'Please select violation status', | ||
| 20 | + remark: 'Remark', | ||
| 21 | + remarkPlaceholder: 'Please enter remarks', | ||
| 22 | + uploadImages: 'Upload Images', | ||
| 23 | + uploadVideo: 'Upload Video', | ||
| 24 | + violationRequired: 'Violation status is required', | ||
| 25 | + remarkRequired: 'Remark is required' | ||
| 26 | + }, | ||
| 27 | + deleteApplyRoomDiscountRecord: { | ||
| 28 | + title: 'Confirm Operation', | ||
| 29 | + confirmText: 'Are you sure to delete this inspection record?' | ||
| 30 | + }, | ||
| 31 | + uploadImage: { | ||
| 32 | + maxCountError: 'Maximum {count} images can be uploaded', | ||
| 33 | + sizeError: 'Image size cannot exceed 2MB', | ||
| 34 | + uploadFailed: 'Image upload failed' | ||
| 35 | + }, | ||
| 36 | + uploadVedio: { | ||
| 37 | + uploadButton: 'Upload Video', | ||
| 38 | + sizeError: 'Video size cannot exceed 500MB', | ||
| 39 | + uploadSuccess: 'Video uploaded successfully', | ||
| 40 | + uploadFailed: 'Video upload failed' | ||
| 41 | + } | ||
| 42 | + }, | ||
| 43 | + zh: { | ||
| 44 | + listApplyRoomDiscountRecord: { | ||
| 45 | + title: '装修跟踪记录', | ||
| 46 | + id: 'ID', | ||
| 47 | + room: '房屋', | ||
| 48 | + operator: '操作人员', | ||
| 49 | + createTime: '创建时间', | ||
| 50 | + status: '状态', | ||
| 51 | + isViolation: '是否违规', | ||
| 52 | + remark: '备注', | ||
| 53 | + fetchError: '获取记录失败' | ||
| 54 | + }, | ||
| 55 | + applyRoomDiscountRecord: { | ||
| 56 | + title: '验房跟踪', | ||
| 57 | + room: '房屋', | ||
| 58 | + status: '状态', | ||
| 59 | + isViolation: '是否违规', | ||
| 60 | + selectViolation: '请选择是否违规', | ||
| 61 | + remark: '备注', | ||
| 62 | + remarkPlaceholder: '请填写备注', | ||
| 63 | + uploadImages: '上传图片', | ||
| 64 | + uploadVideo: '上传视频', | ||
| 65 | + violationRequired: '是否违规不能为空', | ||
| 66 | + remarkRequired: '备注不能为空' | ||
| 67 | + }, | ||
| 68 | + deleteApplyRoomDiscountRecord: { | ||
| 69 | + title: '请确认您的操作', | ||
| 70 | + confirmText: '确定删除验房记录吗?' | ||
| 71 | + }, | ||
| 72 | + uploadImage: { | ||
| 73 | + maxCountError: '最多只能上传{count}张图片', | ||
| 74 | + sizeError: '图片大小不能超过2MB', | ||
| 75 | + uploadFailed: '图片上传失败' | ||
| 76 | + }, | ||
| 77 | + uploadVedio: { | ||
| 78 | + uploadButton: '上传视频', | ||
| 79 | + sizeError: '视频大小不能超过500MB', | ||
| 80 | + uploadSuccess: '视频上传成功', | ||
| 81 | + uploadFailed: '视频上传失败' | ||
| 82 | + } | ||
| 83 | + } | ||
| 84 | +} | ||
| 0 | \ No newline at end of file | 85 | \ No newline at end of file |
src/views/fee/listApplyRoomDiscountRecordList.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <div class="list-apply-room-discount-record-container"> | ||
| 3 | + <el-card class="box-card"> | ||
| 4 | + <div slot="header" class="clearfix"> | ||
| 5 | + <div class="card-header"> | ||
| 6 | + <span>{{ listApplyRoomDiscountRecordsInfo.conditions.roomName }}</span> | ||
| 7 | + <span class="header-title">{{ $t('listApplyRoomDiscountRecord.title') }}</span> | ||
| 8 | + <div class="header-tools"> | ||
| 9 | + <el-button type="primary" size="small" @click="_openAddModal(listApplyRoomDiscountRecordsInfo.applyRoomDiscount)"> | ||
| 10 | + <i class="el-icon-plus"></i> | ||
| 11 | + {{ $t('common.add') }} | ||
| 12 | + </el-button> | ||
| 13 | + <el-button type="primary" size="small" style="margin-left:10px" @click="_goBack()"> | ||
| 14 | + <i class="el-icon-close"></i> | ||
| 15 | + {{ $t('common.back') }} | ||
| 16 | + </el-button> | ||
| 17 | + </div> | ||
| 18 | + </div> | ||
| 19 | + </div> | ||
| 20 | + | ||
| 21 | + <el-table | ||
| 22 | + :data="listApplyRoomDiscountRecordsInfo.listApplyRoomDiscountRecords" | ||
| 23 | + border | ||
| 24 | + style="width: 100%" | ||
| 25 | + v-loading="loading" | ||
| 26 | + > | ||
| 27 | + <el-table-column prop="ardrId" :label="$t('listApplyRoomDiscountRecord.id')" align="center" /> | ||
| 28 | + <el-table-column prop="roomName" :label="$t('listApplyRoomDiscountRecord.room')" align="center" /> | ||
| 29 | + <el-table-column prop="createUserName" :label="$t('listApplyRoomDiscountRecord.operator')" align="center" /> | ||
| 30 | + <el-table-column prop="createTime" :label="$t('listApplyRoomDiscountRecord.createTime')" align="center" /> | ||
| 31 | + <el-table-column prop="stateName" :label="$t('listApplyRoomDiscountRecord.status')" align="center" /> | ||
| 32 | + <el-table-column prop="isTrueName" :label="$t('listApplyRoomDiscountRecord.isViolation')" align="center" /> | ||
| 33 | + <el-table-column prop="remark" :label="$t('listApplyRoomDiscountRecord.remark')" align="center" /> | ||
| 34 | + <el-table-column :label="$t('common.operation')" align="center" width="200"> | ||
| 35 | + <template slot-scope="scope"> | ||
| 36 | + <el-button-group> | ||
| 37 | + <el-button size="mini" @click="_openApplyRoomDiscountRecordDetailsModel(scope.row)"> | ||
| 38 | + {{ $t('common.viewDetails') }} | ||
| 39 | + </el-button> | ||
| 40 | + <el-button size="mini" type="danger" @click="_openDeleteApplyRoomDiscountRecordModel(scope.row)"> | ||
| 41 | + {{ $t('common.delete') }} | ||
| 42 | + </el-button> | ||
| 43 | + </el-button-group> | ||
| 44 | + </template> | ||
| 45 | + </el-table-column> | ||
| 46 | + </el-table> | ||
| 47 | + | ||
| 48 | + <el-pagination | ||
| 49 | + @size-change="handleSizeChange" | ||
| 50 | + @current-change="handleCurrentChange" | ||
| 51 | + :current-page="page.current" | ||
| 52 | + :page-sizes="[10, 20, 30, 50]" | ||
| 53 | + :page-size="page.size" | ||
| 54 | + layout="total, sizes, prev, pager, next, jumper" | ||
| 55 | + :total="listApplyRoomDiscountRecordsInfo.total" | ||
| 56 | + class="pagination" | ||
| 57 | + > | ||
| 58 | + </el-pagination> | ||
| 59 | + </el-card> | ||
| 60 | + | ||
| 61 | + <apply-room-discount-record ref="applyRoomDiscountRecord" @success="handleSuccess" /> | ||
| 62 | + <delete-apply-room-discount-record ref="deleteApplyRoomDiscountRecord" @success="handleSuccess" /> | ||
| 63 | + </div> | ||
| 64 | +</template> | ||
| 65 | + | ||
| 66 | +<script> | ||
| 67 | +import { queryApplyRoomDiscountRecord } from '@/api/fee/listApplyRoomDiscountRecordApi' | ||
| 68 | +import ApplyRoomDiscountRecord from '@/components/fee/applyRoomDiscountRecord' | ||
| 69 | +import DeleteApplyRoomDiscountRecord from '@/components/fee/deleteApplyRoomDiscountRecord' | ||
| 70 | +import { getCommunityId } from '@/api/community/communityApi' | ||
| 71 | + | ||
| 72 | +export default { | ||
| 73 | + name: 'ListApplyRoomDiscountRecord', | ||
| 74 | + components: { | ||
| 75 | + ApplyRoomDiscountRecord, | ||
| 76 | + DeleteApplyRoomDiscountRecord | ||
| 77 | + }, | ||
| 78 | + data() { | ||
| 79 | + return { | ||
| 80 | + loading: false, | ||
| 81 | + listApplyRoomDiscountRecordsInfo: { | ||
| 82 | + listApplyRoomDiscountRecords: [], | ||
| 83 | + applyRoomDiscount: [], | ||
| 84 | + total: 0, | ||
| 85 | + records: 1, | ||
| 86 | + conditions: { | ||
| 87 | + ardId: '', | ||
| 88 | + roomId: '', | ||
| 89 | + roomName: '', | ||
| 90 | + stateName: '', | ||
| 91 | + state: '', | ||
| 92 | + communityId: '' | ||
| 93 | + } | ||
| 94 | + }, | ||
| 95 | + page: { | ||
| 96 | + current: 1, | ||
| 97 | + size: 10 | ||
| 98 | + } | ||
| 99 | + } | ||
| 100 | + }, | ||
| 101 | + created() { | ||
| 102 | + this.listApplyRoomDiscountRecordsInfo.conditions.communityId = getCommunityId() | ||
| 103 | + this.listApplyRoomDiscountRecordsInfo.conditions.ardId = this.$route.query.ardId | ||
| 104 | + this.listApplyRoomDiscountRecordsInfo.conditions.state = this.$route.query.state | ||
| 105 | + this.listApplyRoomDiscountRecordsInfo.conditions.stateName = this.$route.query.stateName | ||
| 106 | + this.listApplyRoomDiscountRecordsInfo.conditions.roomId = this.$route.query.roomId | ||
| 107 | + this.listApplyRoomDiscountRecordsInfo.conditions.roomName = this.$route.query.roomName | ||
| 108 | + this._listApplyRoomDiscountRecords(this.page.current, this.page.size) | ||
| 109 | + }, | ||
| 110 | + methods: { | ||
| 111 | + async _listApplyRoomDiscountRecords(page, size) { | ||
| 112 | + try { | ||
| 113 | + this.loading = true | ||
| 114 | + const params = { | ||
| 115 | + page: page, | ||
| 116 | + row: size, | ||
| 117 | + ...this.listApplyRoomDiscountRecordsInfo.conditions | ||
| 118 | + } | ||
| 119 | + const { data, total } = await queryApplyRoomDiscountRecord(params) | ||
| 120 | + this.listApplyRoomDiscountRecordsInfo.listApplyRoomDiscountRecords = data | ||
| 121 | + this.listApplyRoomDiscountRecordsInfo.total = total | ||
| 122 | + } catch (error) { | ||
| 123 | + this.$message.error(this.$t('listApplyRoomDiscountRecord.fetchError')) | ||
| 124 | + } finally { | ||
| 125 | + this.loading = false | ||
| 126 | + } | ||
| 127 | + }, | ||
| 128 | + _openAddModal(applyRoomDiscount) { | ||
| 129 | + applyRoomDiscount.push(this.listApplyRoomDiscountRecordsInfo.conditions.ardId) | ||
| 130 | + applyRoomDiscount.push(this.listApplyRoomDiscountRecordsInfo.conditions.state) | ||
| 131 | + applyRoomDiscount.push(this.listApplyRoomDiscountRecordsInfo.conditions.stateName) | ||
| 132 | + applyRoomDiscount.push(this.listApplyRoomDiscountRecordsInfo.conditions.roomId) | ||
| 133 | + applyRoomDiscount.push(this.listApplyRoomDiscountRecordsInfo.conditions.roomName) | ||
| 134 | + this.$refs.applyRoomDiscountRecord.open(applyRoomDiscount) | ||
| 135 | + }, | ||
| 136 | + _openDeleteApplyRoomDiscountRecordModel(applyRoomDiscountRecord) { | ||
| 137 | + this.$refs.deleteApplyRoomDiscountRecord.open(applyRoomDiscountRecord) | ||
| 138 | + }, | ||
| 139 | + _openApplyRoomDiscountRecordDetailsModel(applyRoomDiscountRecord) { | ||
| 140 | + this.$router.push({ | ||
| 141 | + path: '/views/fee/listApplyRoomDiscountRecordDetails', | ||
| 142 | + query: { | ||
| 143 | + ardrId: applyRoomDiscountRecord.ardrId, | ||
| 144 | + roomName: applyRoomDiscountRecord.roomName, | ||
| 145 | + state: applyRoomDiscountRecord.state | ||
| 146 | + } | ||
| 147 | + }) | ||
| 148 | + }, | ||
| 149 | + handleSuccess() { | ||
| 150 | + this._listApplyRoomDiscountRecords(this.page.current, this.page.size) | ||
| 151 | + }, | ||
| 152 | + handleSizeChange(val) { | ||
| 153 | + this.page.size = val | ||
| 154 | + this._listApplyRoomDiscountRecords(this.page.current, val) | ||
| 155 | + }, | ||
| 156 | + handleCurrentChange(val) { | ||
| 157 | + this.page.current = val | ||
| 158 | + this._listApplyRoomDiscountRecords(val, this.page.size) | ||
| 159 | + }, | ||
| 160 | + _goBack() { | ||
| 161 | + this.$router.go(-1) | ||
| 162 | + } | ||
| 163 | + } | ||
| 164 | +} | ||
| 165 | +</script> | ||
| 166 | + | ||
| 167 | +<style lang="scss" scoped> | ||
| 168 | +.list-apply-room-discount-record-container { | ||
| 169 | + padding: 20px; | ||
| 170 | + | ||
| 171 | + .box-card { | ||
| 172 | + margin-bottom: 20px; | ||
| 173 | + | ||
| 174 | + .card-header { | ||
| 175 | + display: flex; | ||
| 176 | + align-items: center; | ||
| 177 | + justify-content: space-between; | ||
| 178 | + | ||
| 179 | + .header-title { | ||
| 180 | + margin-left: 10px; | ||
| 181 | + font-weight: bold; | ||
| 182 | + } | ||
| 183 | + | ||
| 184 | + .header-tools { | ||
| 185 | + display: flex; | ||
| 186 | + align-items: center; | ||
| 187 | + } | ||
| 188 | + } | ||
| 189 | + } | ||
| 190 | + | ||
| 191 | + .pagination { | ||
| 192 | + margin-top: 20px; | ||
| 193 | + text-align: right; | ||
| 194 | + } | ||
| 195 | +} | ||
| 196 | +</style> | ||
| 0 | \ No newline at end of file | 197 | \ No newline at end of file |
src/views/fee/printPayFeeBangTaiLang.js
0 → 100644
| 1 | +export const messages = { | ||
| 2 | + en: { | ||
| 3 | + printPayFeeBangTai: { | ||
| 4 | + applyForm: 'Application Form', | ||
| 5 | + receiptForm: 'Receipt Form', | ||
| 6 | + receiptNum: 'Receipt No.', | ||
| 7 | + owner: 'Owner: ', | ||
| 8 | + paymentTime: 'Payment Time: ', | ||
| 9 | + serialNum: 'No.', | ||
| 10 | + feeItem: 'Fee Item', | ||
| 11 | + houseCar: 'House/Car', | ||
| 12 | + feeRange: 'Fee Range', | ||
| 13 | + cycle: 'Cycle', | ||
| 14 | + unitPrice: 'Unit Price/Fixed Fee', | ||
| 15 | + areaUsage: 'Area/Usage', | ||
| 16 | + paymentMethod: 'Payment Method', | ||
| 17 | + amount: 'Amount', | ||
| 18 | + discountAmount: 'Discount Amount', | ||
| 19 | + remark: 'Remark', | ||
| 20 | + to: ' to ', | ||
| 21 | + none: 'None', | ||
| 22 | + capitalRMB: 'Capital RMB', | ||
| 23 | + departmentHead: 'Department Head', | ||
| 24 | + handler: 'Handler', | ||
| 25 | + financialCollection: 'Financial Collection', | ||
| 26 | + customerConfirmation: 'Customer Confirmation', | ||
| 27 | + print: 'Print', | ||
| 28 | + cancel: 'Cancel' | ||
| 29 | + } | ||
| 30 | + }, | ||
| 31 | + zh: { | ||
| 32 | + printPayFeeBangTai: { | ||
| 33 | + applyForm: '申请单', | ||
| 34 | + receiptForm: '收据单', | ||
| 35 | + receiptNum: '单号', | ||
| 36 | + owner: '业主:', | ||
| 37 | + paymentTime: '缴费时间:', | ||
| 38 | + serialNum: '编号', | ||
| 39 | + feeItem: '收费项目', | ||
| 40 | + houseCar: '房屋/车辆', | ||
| 41 | + feeRange: '收费范围', | ||
| 42 | + cycle: '周期', | ||
| 43 | + unitPrice: '单价/固定费', | ||
| 44 | + areaUsage: '面积/用量', | ||
| 45 | + paymentMethod: '支付方式', | ||
| 46 | + amount: '金额', | ||
| 47 | + discountAmount: '优惠金额', | ||
| 48 | + remark: '备注', | ||
| 49 | + to: '至', | ||
| 50 | + none: '无', | ||
| 51 | + capitalRMB: '大写人民币', | ||
| 52 | + departmentHead: '部门负责人', | ||
| 53 | + handler: '经办人', | ||
| 54 | + financialCollection: '财务收款', | ||
| 55 | + customerConfirmation: '客户确认', | ||
| 56 | + print: '打印', | ||
| 57 | + cancel: '取消' | ||
| 58 | + } | ||
| 59 | + } | ||
| 60 | +} | ||
| 0 | \ No newline at end of file | 61 | \ No newline at end of file |
src/views/fee/printPayFeeBangTaiList.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <div class="print-pay-fee-container"> | ||
| 3 | + <el-row> | ||
| 4 | + <el-col :span="24"> | ||
| 5 | + <div class="text-center"> | ||
| 6 | + <div style="color:#000;font-size:36px">{{ printPayFeeInfo.communityName }} {{ printPayFeeInfo.apply == | ||
| 7 | + 'Y' ? $t('printPayFeeBangTai.applyForm') : $t('printPayFeeBangTai.receiptForm')}}</div> | ||
| 8 | + <span style="color:#000;font-size:20px"> | ||
| 9 | + <span>{{ $t('printPayFeeBangTai.receiptNum') }}</span>:{{ printPayFeeInfo.receiptNum }} | ||
| 10 | + </span> | ||
| 11 | + </div> | ||
| 12 | + <div style="color:#000;font-size:20px;margin-left:20px"> | ||
| 13 | + <div class="float-left"> | ||
| 14 | + <span>{{ $t('printPayFeeBangTai.owner') }}</span>{{ printPayFeeInfo.payObjName }} | ||
| 15 | + </div> | ||
| 16 | + <div class="float-right text-right"> | ||
| 17 | + <span>{{ $t('printPayFeeBangTai.paymentTime') }}</span>{{ printPayFeeInfo.feeTime }} | ||
| 18 | + </div> | ||
| 19 | + </div> | ||
| 20 | + <table class="table vc-table-border" style="color:#000;font-size:20px"> | ||
| 21 | + <thead> | ||
| 22 | + <tr> | ||
| 23 | + <th scope="col" class="text-center" width="80px">{{ $t('printPayFeeBangTai.serialNum') }}</th> | ||
| 24 | + <th scope="col" class="text-center">{{ $t('printPayFeeBangTai.feeItem') }}</th> | ||
| 25 | + <th scope="col" class="text-center">{{ $t('printPayFeeBangTai.houseCar') }}</th> | ||
| 26 | + <th scope="col" class="text-center">{{ $t('printPayFeeBangTai.feeRange') }}</th> | ||
| 27 | + <th scope="col" class="text-center">{{ $t('printPayFeeBangTai.cycle') }}</th> | ||
| 28 | + <th scope="col" class="text-center">{{ $t('printPayFeeBangTai.unitPrice') }}</th> | ||
| 29 | + <th scope="col" class="text-center">{{ $t('printPayFeeBangTai.areaUsage') }}</th> | ||
| 30 | + <th scope="col" class="text-center">{{ $t('printPayFeeBangTai.paymentMethod') }}</th> | ||
| 31 | + <th scope="col" class="text-center">{{ $t('printPayFeeBangTai.amount') }}</th> | ||
| 32 | + <th scope="col" class="text-center">{{ $t('printPayFeeBangTai.discountAmount') }}</th> | ||
| 33 | + <th scope="col" class="text-center">{{ $t('printPayFeeBangTai.remark') }}</th> | ||
| 34 | + </tr> | ||
| 35 | + </thead> | ||
| 36 | + <tbody class="vc-table-border" style="color:#000;font-size:20px"> | ||
| 37 | + <tr v-for="(item, index) in printPayFeeInfo.fees" class="vc-table-border" :key="index"> | ||
| 38 | + <th scope="row" class="text-center">{{ index + 1 }}</th> | ||
| 39 | + <td class="text-center">{{ item.feeName }}</td> | ||
| 40 | + <td class="text-center">{{ item.objName }}</td> | ||
| 41 | + <td class="text-center" v-if="item.preDegrees"> | ||
| 42 | + {{ formatDate(item.startTime) }}<span>{{ $t('printPayFeeBangTai.to') }}</span>{{ formatDate(item.endTime) }}<br> | ||
| 43 | + {{ item.preDegrees }} {{ $t('printPayFeeBangTai.to') }} {{ item.curDegrees }} | ||
| 44 | + </td> | ||
| 45 | + <td class="text-center" v-else-if="item.feeTypeCd == '888800010006'"> | ||
| 46 | + {{ $t('printPayFeeBangTai.none') }} | ||
| 47 | + </td> | ||
| 48 | + <td class="text-center" v-else> | ||
| 49 | + {{ formatDate(item.startTime) }}<span>{{ $t('printPayFeeBangTai.to') }}</span>{{ formatDate(item.endTime) }} | ||
| 50 | + </td> | ||
| 51 | + <td class="text-center">{{ item.cycle }}</td> | ||
| 52 | + <td class="text-center">{{ item.squarePrice }}</td> | ||
| 53 | + <td class="text-center">{{ item.area }}</td> | ||
| 54 | + <td class="text-center">{{ item.primeRate }}</td> | ||
| 55 | + <td class="text-center">{{ item.amount }}</td> | ||
| 56 | + <td class="text-center">{{ item.discountPrice }}</td> | ||
| 57 | + <td class="text-center" width="200px">{{ item.remark }}</td> | ||
| 58 | + </tr> | ||
| 59 | + <tr> | ||
| 60 | + <td colspan="3" class="text-center"> | ||
| 61 | + <span>{{ $t('printPayFeeBangTai.capitalRMB') }}</span>(元) | ||
| 62 | + </td> | ||
| 63 | + <td colspan="4" class="text-center">{{ changeNumMoneyToChinese(printPayFeeInfo.amount) }}</td> | ||
| 64 | + <td colspan="1" class="text-center">{{ computeSumArea() }}</td> | ||
| 65 | + <td colspan="3" class="text-center">{{ printPayFeeInfo.amount }}</td> | ||
| 66 | + </tr> | ||
| 67 | + <tr height="60px"> | ||
| 68 | + <td colspan="6"> | ||
| 69 | + <div style="max-width: 600px;"> | ||
| 70 | + <div v-html="printPayFeeInfo.content"></div> | ||
| 71 | + </div> | ||
| 72 | + </td> | ||
| 73 | + <td colspan="5"> | ||
| 74 | + <img :src="printPayFeeInfo.qrImg" width="100px" height="100px"> | ||
| 75 | + </td> | ||
| 76 | + </tr> | ||
| 77 | + </tbody> | ||
| 78 | + </table> | ||
| 79 | + </el-col> | ||
| 80 | + </el-row> | ||
| 81 | + <el-row> | ||
| 82 | + <el-col :span="20"> | ||
| 83 | + <div class="row" style="color:#000;font-size:20px;margin-left: 10px;"> | ||
| 84 | + <div class="float-left" style="width: 20%;"> | ||
| 85 | + <span>{{ $t('printPayFeeBangTai.departmentHead') }}</span>: | ||
| 86 | + </div> | ||
| 87 | + <div class="float-left" style="width: 20%;"> | ||
| 88 | + <span>{{ $t('printPayFeeBangTai.handler') }}</span>:{{ userInfo.name }} | ||
| 89 | + </div> | ||
| 90 | + <div class="float-left" style="width: 20%;"> | ||
| 91 | + <span>{{ $t('printPayFeeBangTai.financialCollection') }}</span>: | ||
| 92 | + </div> | ||
| 93 | + <div class="float-left" style="width: 20%;"> | ||
| 94 | + <span>{{ $t('printPayFeeBangTai.customerConfirmation') }}</span>: | ||
| 95 | + </div> | ||
| 96 | + </div> | ||
| 97 | + </el-col> | ||
| 98 | + <el-col :span="4" id="print-btn"> | ||
| 99 | + <el-button type="primary" class="float-right" @click="printPurchaseApplyDiv"> | ||
| 100 | + <i class="el-icon-printer"></i> {{ $t('printPayFeeBangTai.print') }} | ||
| 101 | + </el-button> | ||
| 102 | + <el-button type="warning" class="float-right" style="margin-right:20px;" @click="closePage"> | ||
| 103 | + {{ $t('printPayFeeBangTai.cancel') }} | ||
| 104 | + </el-button> | ||
| 105 | + </el-col> | ||
| 106 | + </el-row> | ||
| 107 | + </div> | ||
| 108 | +</template> | ||
| 109 | + | ||
| 110 | +<script> | ||
| 111 | +import { queryFeeReceipt, queryFeeReceiptDetail, queryFeePrintSpec } from '@/api/fee/printPayFeeBangTaiApi' | ||
| 112 | +import { getCommunityId } from '@/api/community/communityApi' | ||
| 113 | +import { getUserId,getUserName } from '@/api/user/userApi' | ||
| 114 | + | ||
| 115 | +export default { | ||
| 116 | + name: 'PrintPayFeeBangTaiList', | ||
| 117 | + data() { | ||
| 118 | + return { | ||
| 119 | + printPayFeeInfo: { | ||
| 120 | + communityName: '', | ||
| 121 | + receiptId: '', | ||
| 122 | + receiptIds: '', | ||
| 123 | + roomName: '', | ||
| 124 | + amount: 0.00, | ||
| 125 | + fees: [], | ||
| 126 | + feeTime: '', | ||
| 127 | + wechatName: '', | ||
| 128 | + content: '', | ||
| 129 | + qrImg: '', | ||
| 130 | + payObjName: '', | ||
| 131 | + feeReceipt: [], | ||
| 132 | + apply: 'N', | ||
| 133 | + receiptNum: '', | ||
| 134 | + merge: '' | ||
| 135 | + }, | ||
| 136 | + printFlag: '0', | ||
| 137 | + userInfo: {}, | ||
| 138 | + communityId: '' | ||
| 139 | + } | ||
| 140 | + }, | ||
| 141 | + created() { | ||
| 142 | + this.initData() | ||
| 143 | + this.loadData() | ||
| 144 | + }, | ||
| 145 | + methods: { | ||
| 146 | + initData() { | ||
| 147 | + this.printPayFeeInfo.receiptId = this.$route.query.receiptId | ||
| 148 | + this.printPayFeeInfo.receiptIds = this.$route.query.receiptIds | ||
| 149 | + this.printPayFeeInfo.apply = this.$route.query.apply || 'N' | ||
| 150 | + this.printPayFeeInfo.merge = this.$route.query.merge | ||
| 151 | + this.communityId = getCommunityId() | ||
| 152 | + this.userInfo = { | ||
| 153 | + userId: getUserId(), | ||
| 154 | + name: getUserName() | ||
| 155 | + } | ||
| 156 | + }, | ||
| 157 | + async loadData() { | ||
| 158 | + this.printPayFeeInfo.communityName = this.$store.getters.currentCommunity.name | ||
| 159 | + await this.loadReceipt() | ||
| 160 | + await this.loadPrintSpec() | ||
| 161 | + }, | ||
| 162 | + async loadReceipt() { | ||
| 163 | + try { | ||
| 164 | + const params = { | ||
| 165 | + page: 1, | ||
| 166 | + row: 30, | ||
| 167 | + receiptId: this.printPayFeeInfo.receiptId, | ||
| 168 | + receiptIds: this.printPayFeeInfo.receiptIds, | ||
| 169 | + communityId: this.communityId | ||
| 170 | + } | ||
| 171 | + const { data } = await queryFeeReceipt(params) | ||
| 172 | + const _feeReceipt = data | ||
| 173 | + let _amount = 0 | ||
| 174 | + _feeReceipt.forEach(item => { | ||
| 175 | + _amount += parseFloat(item.amount) | ||
| 176 | + }) | ||
| 177 | + | ||
| 178 | + this.printPayFeeInfo.amount = _amount.toFixed(2) | ||
| 179 | + this.printPayFeeInfo.roomName = _feeReceipt[0].objName | ||
| 180 | + this.printPayFeeInfo.feeTime = _feeReceipt[0].createTime | ||
| 181 | + this.printPayFeeInfo.payObjName = _feeReceipt[0].payObjName | ||
| 182 | + this.printPayFeeInfo.feeReceipt = _feeReceipt | ||
| 183 | + this.printPayFeeInfo.receiptNum = _feeReceipt[0].receiptCode | ||
| 184 | + await this.loadReceiptDetail() | ||
| 185 | + } catch (error) { | ||
| 186 | + console.error('Failed to load receipt:', error) | ||
| 187 | + } | ||
| 188 | + }, | ||
| 189 | + async loadReceiptDetail() { | ||
| 190 | + try { | ||
| 191 | + const params = { | ||
| 192 | + page: 1, | ||
| 193 | + row: 100, | ||
| 194 | + receiptId: this.printPayFeeInfo.receiptId, | ||
| 195 | + receiptIds: this.printPayFeeInfo.receiptIds, | ||
| 196 | + communityId: this.communityId, | ||
| 197 | + mergeFee: this.printPayFeeInfo.merge | ||
| 198 | + } | ||
| 199 | + const { data } = await queryFeeReceiptDetail(params) | ||
| 200 | + const _feeReceiptDetails = data | ||
| 201 | + this.printPayFeeInfo.receiptNum = this.printPayFeeInfo.receiptNum + "(" + _feeReceiptDetails[0].payOrderId + ")" | ||
| 202 | + _feeReceiptDetails.forEach(item => { | ||
| 203 | + this.printPayFeeInfo.feeReceipt.forEach(im => { | ||
| 204 | + if (item.receiptId == im.receiptId) { | ||
| 205 | + item.objName = im.objName | ||
| 206 | + item.feeTypeCd = im.feeTypeCd | ||
| 207 | + } | ||
| 208 | + }) | ||
| 209 | + }) | ||
| 210 | + this.printPayFeeInfo.fees = _feeReceiptDetails | ||
| 211 | + } catch (error) { | ||
| 212 | + console.error('Failed to load receipt detail:', error) | ||
| 213 | + } | ||
| 214 | + }, | ||
| 215 | + async loadPrintSpec() { | ||
| 216 | + try { | ||
| 217 | + const params = { | ||
| 218 | + page: 1, | ||
| 219 | + row: 1, | ||
| 220 | + specCd: 2020, | ||
| 221 | + communityId: this.communityId | ||
| 222 | + } | ||
| 223 | + const { data } = await queryFeePrintSpec(params) | ||
| 224 | + if (data.length > 0) { | ||
| 225 | + this.printPayFeeInfo.content = data[0].content | ||
| 226 | + this.printPayFeeInfo.qrImg = data[0].qrImg | ||
| 227 | + if (data[0].printName) { | ||
| 228 | + this.printPayFeeInfo.communityName = data[0].printName | ||
| 229 | + } | ||
| 230 | + } | ||
| 231 | + } catch (error) { | ||
| 232 | + console.error('Failed to load print spec:', error) | ||
| 233 | + } | ||
| 234 | + }, | ||
| 235 | + computeSumArea() { | ||
| 236 | + let _sum = 0.00 | ||
| 237 | + this.printPayFeeInfo.fees.forEach(item => { | ||
| 238 | + if (item.area && this.isNumber(item.area)) { | ||
| 239 | + _sum += parseFloat(item.area) | ||
| 240 | + } | ||
| 241 | + }) | ||
| 242 | + return _sum.toFixed(2) | ||
| 243 | + }, | ||
| 244 | + isNumber(value) { | ||
| 245 | + return !isNaN(parseFloat(value)) && isFinite(value) | ||
| 246 | + }, | ||
| 247 | + formatDate(date) { | ||
| 248 | + if (!date) return '' | ||
| 249 | + return this.$moment(date).format('YYYY-MM-DD') | ||
| 250 | + }, | ||
| 251 | + changeNumMoneyToChinese(num) { | ||
| 252 | + // 这里实现数字转中文大写金额的逻辑 | ||
| 253 | + // 由于实现较复杂,建议使用第三方库或自行实现 | ||
| 254 | + return num // 暂时返回原值 | ||
| 255 | + }, | ||
| 256 | + printPurchaseApplyDiv() { | ||
| 257 | + this.printFlag = '1' | ||
| 258 | + document.getElementById("print-btn").style.display = "none" | ||
| 259 | + window.print() | ||
| 260 | + window.opener = null | ||
| 261 | + window.close() | ||
| 262 | + }, | ||
| 263 | + closePage() { | ||
| 264 | + window.opener = null | ||
| 265 | + window.close() | ||
| 266 | + } | ||
| 267 | + } | ||
| 268 | +} | ||
| 269 | +</script> | ||
| 270 | + | ||
| 271 | +<style scoped> | ||
| 272 | +.print-pay-fee-container { | ||
| 273 | + padding: 20px; | ||
| 274 | +} | ||
| 275 | + | ||
| 276 | +.text-center { | ||
| 277 | + text-align: center; | ||
| 278 | +} | ||
| 279 | + | ||
| 280 | +.float-left { | ||
| 281 | + float: left; | ||
| 282 | +} | ||
| 283 | + | ||
| 284 | +.float-right { | ||
| 285 | + float: right; | ||
| 286 | +} | ||
| 287 | + | ||
| 288 | +.vc-table-border { | ||
| 289 | + border: 1px solid #000; | ||
| 290 | + border-collapse: collapse; | ||
| 291 | +} | ||
| 292 | + | ||
| 293 | +.vc-table-border th, | ||
| 294 | +.vc-table-border td { | ||
| 295 | + border: 1px solid #000; | ||
| 296 | + padding: 5px; | ||
| 297 | +} | ||
| 298 | + | ||
| 299 | +#print-btn { | ||
| 300 | + text-align: right; | ||
| 301 | + margin-top: 20px; | ||
| 302 | +} | ||
| 303 | +</style> | ||
| 0 | \ No newline at end of file | 304 | \ No newline at end of file |
src/views/fee/printPayFeeLang.js
0 → 100644
| 1 | +export const messages = { | ||
| 2 | + en: { | ||
| 3 | + printPayFee: { | ||
| 4 | + apply: 'Application', | ||
| 5 | + receipt: 'Receipt', | ||
| 6 | + refund: 'Refund', | ||
| 7 | + owner: 'Owner', | ||
| 8 | + receiptNum: 'Receipt No.', | ||
| 9 | + payTime: 'Payment Time', | ||
| 10 | + serialNumber: 'No.', | ||
| 11 | + feeItem: 'Fee Item', | ||
| 12 | + houseCar: 'House/Vehicle', | ||
| 13 | + feeRange: 'Fee Range', | ||
| 14 | + to: 'to', | ||
| 15 | + none: 'None', | ||
| 16 | + unitPrice: 'Unit Price', | ||
| 17 | + areaUsage: 'Area/Usage', | ||
| 18 | + paymentMethod: 'Payment Method', | ||
| 19 | + receivableActual: 'Receivable/Actual', | ||
| 20 | + yuan: 'yuan', | ||
| 21 | + discountAmount: 'Discount Amount', | ||
| 22 | + remark: 'Remark', | ||
| 23 | + capitalRMB: 'Capital RMB', | ||
| 24 | + accountDeduction: 'Account Deduction', | ||
| 25 | + departmentHead: 'Department Head:', | ||
| 26 | + operator: 'Operator', | ||
| 27 | + financeReceipt: 'Finance Receipt:', | ||
| 28 | + customerConfirm: 'Customer Confirm:' | ||
| 29 | + } | ||
| 30 | + }, | ||
| 31 | + zh: { | ||
| 32 | + printPayFee: { | ||
| 33 | + apply: '申请单', | ||
| 34 | + receipt: '收据单', | ||
| 35 | + refund: '退款单', | ||
| 36 | + owner: '业主', | ||
| 37 | + receiptNum: '单号', | ||
| 38 | + payTime: '缴费时间', | ||
| 39 | + serialNumber: '编号', | ||
| 40 | + feeItem: '收费项目', | ||
| 41 | + houseCar: '房屋/车辆', | ||
| 42 | + feeRange: '收费范围', | ||
| 43 | + to: '至', | ||
| 44 | + none: '无', | ||
| 45 | + unitPrice: '单价', | ||
| 46 | + areaUsage: '面积/用量', | ||
| 47 | + paymentMethod: '支付方式', | ||
| 48 | + receivableActual: '应收/实收', | ||
| 49 | + yuan: '元', | ||
| 50 | + discountAmount: '优惠金额', | ||
| 51 | + remark: '备注', | ||
| 52 | + capitalRMB: '大写人民币(元)', | ||
| 53 | + accountDeduction: '账户扣款', | ||
| 54 | + departmentHead: '部门负责人:', | ||
| 55 | + operator: '经办人:', | ||
| 56 | + financeReceipt: '财务收款:', | ||
| 57 | + customerConfirm: '客户确认:' | ||
| 58 | + } | ||
| 59 | + } | ||
| 60 | +} | ||
| 0 | \ No newline at end of file | 61 | \ No newline at end of file |
src/views/fee/printPayFeeList.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <div class="print-pay-fee-container"> | ||
| 3 | + <el-card class="box-card"> | ||
| 4 | + <div class="text-center"> | ||
| 5 | + <div style="color:#000;font-size:26px">{{ printPayFeeInfo.communityName }} | ||
| 6 | + <span v-if="printPayFeeInfo.apply === 'Y'">{{ $t('printPayFee.apply') }}</span> | ||
| 7 | + <span v-if="printPayFeeInfo.apply === 'N'">{{ $t('printPayFee.receipt') }}</span> | ||
| 8 | + <span v-if="printPayFeeInfo.apply === 'R'">{{ $t('printPayFee.refund') }}</span> | ||
| 9 | + </div> | ||
| 10 | + </div> | ||
| 11 | + <div style="color:#000;font-size:18px;margin-left:20px"> | ||
| 12 | + <div class="float-left"> | ||
| 13 | + {{ $t('printPayFee.owner') }}:{{ printPayFeeInfo.payObjName }} | ||
| 14 | + </div> | ||
| 15 | + <div class="float-right text-right"> | ||
| 16 | + <span>{{ $t('printPayFee.receiptNum') }}{{ printPayFeeInfo.receiptNum }}</span> | ||
| 17 | + <br /> | ||
| 18 | + <span>{{ $t('printPayFee.payTime') }}:{{ printPayFeeInfo.feeTime }}</span> | ||
| 19 | + </div> | ||
| 20 | + </div> | ||
| 21 | + <el-table :data="printPayFeeInfo.fees" border style="width: 100%;color:#000;font-size:20px"> | ||
| 22 | + <el-table-column prop="index" :label="$t('printPayFee.serialNumber')" width="80" align="center"> | ||
| 23 | + <template slot-scope="scope"> | ||
| 24 | + {{ scope.$index + 1 }} | ||
| 25 | + </template> | ||
| 26 | + </el-table-column> | ||
| 27 | + <el-table-column prop="feeName" :label="$t('printPayFee.feeItem')" align="center"></el-table-column> | ||
| 28 | + <el-table-column prop="objName" :label="$t('printPayFee.houseCar')" align="center"></el-table-column> | ||
| 29 | + <el-table-column :label="$t('printPayFee.feeRange')" align="center"> | ||
| 30 | + <template slot-scope="scope"> | ||
| 31 | + <div v-if="scope.row.preDegrees"> | ||
| 32 | + {{ dateFormat(scope.row.startTime) }} | ||
| 33 | + <span>{{ $t('printPayFee.to') }}</span> | ||
| 34 | + {{ dateFormat(scope.row.endTime) }}<br /> | ||
| 35 | + {{ scope.row.preDegrees }} {{ $t('printPayFee.to') }} {{ scope.row.curDegrees }} | ||
| 36 | + </div> | ||
| 37 | + <div v-else-if="scope.row.feeTypeCd === '888800010006'"> | ||
| 38 | + {{ $t('printPayFee.none') }} | ||
| 39 | + </div> | ||
| 40 | + <div v-else> | ||
| 41 | + {{ dateFormat(scope.row.startTime) }}{{ $t('printPayFee.to') }}{{ dateFormat(scope.row.endTime) }} | ||
| 42 | + </div> | ||
| 43 | + </template> | ||
| 44 | + </el-table-column> | ||
| 45 | + <el-table-column :label="$t('printPayFee.unitPrice')" align="center"> | ||
| 46 | + <template slot-scope="scope"> | ||
| 47 | + {{ scope.row.squarePrice }}<br />{{ scope.row.units }} | ||
| 48 | + </template> | ||
| 49 | + </el-table-column> | ||
| 50 | + <el-table-column prop="area" :label="$t('printPayFee.areaUsage')" align="center"></el-table-column> | ||
| 51 | + <el-table-column prop="primeRate" :label="$t('printPayFee.paymentMethod')" align="center"></el-table-column> | ||
| 52 | + <el-table-column :label="$t('printPayFee.receivableActual')" align="center"> | ||
| 53 | + <template slot-scope="scope"> | ||
| 54 | + {{ scope.row.receivableAmount }}/{{ scope.row.amount }}{{ $t('printPayFee.yuan') }} | ||
| 55 | + <span v-if="scope.row.amount < 0">({{ $t('printPayFee.refund') }})</span> | ||
| 56 | + </template> | ||
| 57 | + </el-table-column> | ||
| 58 | + <el-table-column prop="discountPrice" :label="$t('printPayFee.discountAmount')" align="center"> | ||
| 59 | + <template slot-scope="scope"> | ||
| 60 | + {{ scope.row.discountPrice || 0 }} | ||
| 61 | + </template> | ||
| 62 | + </el-table-column> | ||
| 63 | + <el-table-column prop="remark" :label="$t('printPayFee.remark')" width="200" align="center"></el-table-column> | ||
| 64 | + </el-table> | ||
| 65 | + | ||
| 66 | + <el-row> | ||
| 67 | + <el-col :span="3" class="text-center">{{ $t('printPayFee.capitalRMB') }}</el-col> | ||
| 68 | + <el-col :span="2" class="text-center">{{ changeNumMoneyToChinese(printPayFeeInfo.amount) }}</el-col> | ||
| 69 | + <el-col :span="1" class="text-center">{{ printPayFeeInfo.amount }}</el-col> | ||
| 70 | + <el-col :span="2" class="text-center">{{ $t('printPayFee.accountDeduction') }}</el-col> | ||
| 71 | + <el-col :span="2" class="text-center">{{ printPayFeeInfo.acctAmount }}</el-col> | ||
| 72 | + </el-row> | ||
| 73 | + | ||
| 74 | + <el-row v-if="printPayFeeInfo.content || printPayFeeInfo.qrImg"> | ||
| 75 | + <el-col :span="6"> | ||
| 76 | + <div style="max-width: 600px;" v-html="printPayFeeInfo.content"></div> | ||
| 77 | + </el-col> | ||
| 78 | + <el-col :span="4"> | ||
| 79 | + <img v-if="printPayFeeInfo.qrImg" :src="printPayFeeInfo.qrImg" width="100px" height="100px"> | ||
| 80 | + </el-col> | ||
| 81 | + </el-row> | ||
| 82 | + | ||
| 83 | + <el-row style="color:#000;font-size:18px;margin-left: 10px;"> | ||
| 84 | + <el-col :span="6"> | ||
| 85 | + {{ $t('printPayFee.departmentHead') }} | ||
| 86 | + </el-col> | ||
| 87 | + <el-col :span="6"> | ||
| 88 | + {{ $t('printPayFee.operator') }}:{{ userInfo.name }} | ||
| 89 | + </el-col> | ||
| 90 | + <el-col :span="6"> | ||
| 91 | + {{ $t('printPayFee.financeReceipt') }} | ||
| 92 | + </el-col> | ||
| 93 | + <el-col :span="6"> | ||
| 94 | + {{ $t('printPayFee.customerConfirm') }} | ||
| 95 | + </el-col> | ||
| 96 | + </el-row> | ||
| 97 | + | ||
| 98 | + <el-row id="print-btn"> | ||
| 99 | + <el-col :span="24"> | ||
| 100 | + <el-button type="primary" class="float-right" @click="handlePrint"> | ||
| 101 | + <i class="el-icon-printer"></i> {{ $t('common.print') }} | ||
| 102 | + </el-button> | ||
| 103 | + <el-button type="warning" class="float-right" style="margin-right:20px;" @click="handleClose"> | ||
| 104 | + {{ $t('common.cancel') }} | ||
| 105 | + </el-button> | ||
| 106 | + </el-col> | ||
| 107 | + </el-row> | ||
| 108 | + </el-card> | ||
| 109 | + </div> | ||
| 110 | +</template> | ||
| 111 | + | ||
| 112 | +<script> | ||
| 113 | +import { getCommunityId } from '@/api/community/communityApi' | ||
| 114 | +import { queryFeeReceipt, queryFeeReceiptDetail, queryFeePrintSpec } from '@/api/fee/printPayFeeApi' | ||
| 115 | +import { getUserId,getUserName } from '@/api/user/userApi' | ||
| 116 | + | ||
| 117 | +export default { | ||
| 118 | + name: 'PrintPayFeeList', | ||
| 119 | + data() { | ||
| 120 | + return { | ||
| 121 | + printPayFeeInfo: { | ||
| 122 | + communityName: '', | ||
| 123 | + receiptId: '', | ||
| 124 | + receiptIds: '', | ||
| 125 | + detailIds: '', | ||
| 126 | + roomName: '', | ||
| 127 | + amount: 0.00, | ||
| 128 | + fees: [], | ||
| 129 | + feeTime: '', | ||
| 130 | + wechatName: '', | ||
| 131 | + content: '', | ||
| 132 | + qrImg: '', | ||
| 133 | + payObjName: '', | ||
| 134 | + feeReceipt: [], | ||
| 135 | + apply: 'N', | ||
| 136 | + receiptNum: '', | ||
| 137 | + acctAmount: 0 | ||
| 138 | + }, | ||
| 139 | + userInfo: {}, | ||
| 140 | + printFlag: '0', | ||
| 141 | + communityId: '' | ||
| 142 | + } | ||
| 143 | + }, | ||
| 144 | + created() { | ||
| 145 | + this.communityId = getCommunityId() | ||
| 146 | + this.userInfo = { | ||
| 147 | + userId: getUserId(), | ||
| 148 | + name: getUserName() | ||
| 149 | + } | ||
| 150 | + this.initData() | ||
| 151 | + }, | ||
| 152 | + methods: { | ||
| 153 | + initData() { | ||
| 154 | + this.printPayFeeInfo.receiptId = this.$route.query.receiptId | ||
| 155 | + this.printPayFeeInfo.receiptIds = this.$route.query.receiptIds | ||
| 156 | + this.printPayFeeInfo.detailIds = this.$route.query.detailIds | ||
| 157 | + this.printPayFeeInfo.apply = this.$route.query.apply | ||
| 158 | + this.printPayFeeInfo.merge = this.$route.query.merge | ||
| 159 | + this.printPayFeeInfo.communityName = this.$route.query.communityName || '' | ||
| 160 | + | ||
| 161 | + this.loadReceipt() | ||
| 162 | + this.loadPrintSpec() | ||
| 163 | + }, | ||
| 164 | + loadReceipt() { | ||
| 165 | + const params = { | ||
| 166 | + page: 1, | ||
| 167 | + row: 30, | ||
| 168 | + receiptId: this.printPayFeeInfo.receiptId, | ||
| 169 | + receiptIds: this.printPayFeeInfo.receiptIds, | ||
| 170 | + detailIds: this.printPayFeeInfo.detailIds, | ||
| 171 | + communityId: this.communityId | ||
| 172 | + } | ||
| 173 | + | ||
| 174 | + queryFeeReceipt(params).then(response => { | ||
| 175 | + const feeReceipt = response.data | ||
| 176 | + let amount = 0 | ||
| 177 | + feeReceipt.forEach(item => { | ||
| 178 | + amount += parseFloat(item.amount) | ||
| 179 | + }) | ||
| 180 | + | ||
| 181 | + this.printPayFeeInfo.amount = amount.toFixed(2) | ||
| 182 | + this.printPayFeeInfo.roomName = feeReceipt[0].objName | ||
| 183 | + this.printPayFeeInfo.feeTime = feeReceipt[0].createTime | ||
| 184 | + this.printPayFeeInfo.payObjName = feeReceipt[0].payObjName | ||
| 185 | + this.printPayFeeInfo.feeReceipt = feeReceipt | ||
| 186 | + this.printPayFeeInfo.receiptNum = feeReceipt[0].receiptCode | ||
| 187 | + | ||
| 188 | + this.loadReceiptDetail() | ||
| 189 | + }) | ||
| 190 | + }, | ||
| 191 | + loadReceiptDetail() { | ||
| 192 | + const params = { | ||
| 193 | + page: 1, | ||
| 194 | + row: 100, | ||
| 195 | + receiptId: this.printPayFeeInfo.receiptId, | ||
| 196 | + receiptIds: this.printPayFeeInfo.receiptIds, | ||
| 197 | + detailIds: this.printPayFeeInfo.detailIds, | ||
| 198 | + communityId: this.communityId, | ||
| 199 | + mergeFee: this.printPayFeeInfo.merge | ||
| 200 | + } | ||
| 201 | + | ||
| 202 | + queryFeeReceiptDetail(params).then(response => { | ||
| 203 | + const feeReceiptDetails = response.data | ||
| 204 | + this.printPayFeeInfo.receiptNum = this.printPayFeeInfo.receiptNum + "(" + feeReceiptDetails[0].payOrderId + ")" | ||
| 205 | + if (feeReceiptDetails[0].amount < 0) { | ||
| 206 | + this.printPayFeeInfo.apply = 'R' | ||
| 207 | + } | ||
| 208 | + let acctAmount = 0.0 | ||
| 209 | + feeReceiptDetails.forEach(item => { | ||
| 210 | + acctAmount = acctAmount + parseFloat(item.acctAmount) | ||
| 211 | + this.printPayFeeInfo.feeReceipt.forEach(im => { | ||
| 212 | + if (item.receiptId == im.receiptId) { | ||
| 213 | + item.objName = im.objName | ||
| 214 | + item.feeTypeCd = im.feeTypeCd | ||
| 215 | + } | ||
| 216 | + }) | ||
| 217 | + }) | ||
| 218 | + this.printPayFeeInfo.fees = feeReceiptDetails | ||
| 219 | + this.printPayFeeInfo.acctAmount = acctAmount.toFixed(2) | ||
| 220 | + }) | ||
| 221 | + }, | ||
| 222 | + loadPrintSpec() { | ||
| 223 | + const params = { | ||
| 224 | + page: 1, | ||
| 225 | + row: 1, | ||
| 226 | + specCd: 2020, | ||
| 227 | + communityId: this.communityId | ||
| 228 | + } | ||
| 229 | + | ||
| 230 | + queryFeePrintSpec(params).then(response => { | ||
| 231 | + const data = response.data | ||
| 232 | + if (data.length > 0) { | ||
| 233 | + this.printPayFeeInfo.content = data[0].content | ||
| 234 | + this.printPayFeeInfo.qrImg = data[0].qrImg | ||
| 235 | + if (data[0].printName) { | ||
| 236 | + this.printPayFeeInfo.communityName = data[0].printName | ||
| 237 | + } | ||
| 238 | + } | ||
| 239 | + }) | ||
| 240 | + }, | ||
| 241 | + dateFormat(date) { | ||
| 242 | + if (!date) return '' | ||
| 243 | + return this.$moment(date).format('YYYY-MM-DD') | ||
| 244 | + }, | ||
| 245 | + changeNumMoneyToChinese(num) { | ||
| 246 | + // 这里实现数字转中文大写金额的逻辑 | ||
| 247 | + // 原vc.changeNumMoneyToChinese的实现 | ||
| 248 | + return num // 实际应该返回转换后的中文大写金额 | ||
| 249 | + }, | ||
| 250 | + handlePrint() { | ||
| 251 | + this.printFlag = '1' | ||
| 252 | + document.getElementById("print-btn").style.display = "none" | ||
| 253 | + window.print() | ||
| 254 | + window.close() | ||
| 255 | + }, | ||
| 256 | + handleClose() { | ||
| 257 | + window.close() | ||
| 258 | + } | ||
| 259 | + } | ||
| 260 | +} | ||
| 261 | +</script> | ||
| 262 | + | ||
| 263 | +<style scoped> | ||
| 264 | +.print-pay-fee-container { | ||
| 265 | + padding: 20px; | ||
| 266 | +} | ||
| 267 | + | ||
| 268 | +.float-left { | ||
| 269 | + float: left; | ||
| 270 | +} | ||
| 271 | + | ||
| 272 | +.float-right { | ||
| 273 | + float: right; | ||
| 274 | +} | ||
| 275 | + | ||
| 276 | +.text-center { | ||
| 277 | + text-align: center; | ||
| 278 | +} | ||
| 279 | + | ||
| 280 | +.text-right { | ||
| 281 | + text-align: right; | ||
| 282 | +} | ||
| 283 | + | ||
| 284 | +.el-row { | ||
| 285 | + width: 100%; | ||
| 286 | + margin-bottom: 20px; | ||
| 287 | +} | ||
| 288 | + | ||
| 289 | +.el-col { | ||
| 290 | + width: 100%; | ||
| 291 | +} | ||
| 292 | +</style> | ||
| 0 | \ No newline at end of file | 293 | \ No newline at end of file |
src/views/fee/printSmallPayFeeLang.js
0 → 100644
| 1 | +export const messages = { | ||
| 2 | + en: { | ||
| 3 | + printSmallPayFee: { | ||
| 4 | + receipt: 'Payment Receipt', | ||
| 5 | + receiptNum: 'Receipt No:', | ||
| 6 | + orderNum: 'Order No:', | ||
| 7 | + roomNum: 'Room No', | ||
| 8 | + owner: 'Owner', | ||
| 9 | + time: 'Time', | ||
| 10 | + feeItem: 'Fee Item', | ||
| 11 | + feeRange: 'Fee Range', | ||
| 12 | + to: 'to', | ||
| 13 | + unitPrice: 'Unit Price/Fixed Fee:', | ||
| 14 | + areaUsage: 'Area/Usage:', | ||
| 15 | + paymentMethod: 'Payment Method:', | ||
| 16 | + meterReading: 'Meter Reading:', | ||
| 17 | + amount: 'Amount:', | ||
| 18 | + refund: '(Refund)', | ||
| 19 | + discount: 'Discount Amount:', | ||
| 20 | + remark: 'Remark', | ||
| 21 | + total: 'Total', | ||
| 22 | + issuer: 'Issuer', | ||
| 23 | + print: 'Print', | ||
| 24 | + cloudPrint: 'Cloud Print', | ||
| 25 | + cancel: 'Cancel', | ||
| 26 | + submit: 'Submit', | ||
| 27 | + printer: 'Printer', | ||
| 28 | + printerRequired: 'Required, please select printer', | ||
| 29 | + quantity: 'Quantity', | ||
| 30 | + quantityRequired: 'Required, please enter quantity', | ||
| 31 | + noFee: 'No fee included', | ||
| 32 | + submitSuccess: 'Submitted successfully', | ||
| 33 | + submitFailed: 'Submission failed' | ||
| 34 | + } | ||
| 35 | + }, | ||
| 36 | + zh: { | ||
| 37 | + printSmallPayFee: { | ||
| 38 | + receipt: '缴费收据单', | ||
| 39 | + receiptNum: '收据号:', | ||
| 40 | + orderNum: '订单号:', | ||
| 41 | + roomNum: '房号', | ||
| 42 | + owner: '业主', | ||
| 43 | + time: '时间', | ||
| 44 | + feeItem: '收费项目', | ||
| 45 | + feeRange: '收费范围', | ||
| 46 | + to: '至', | ||
| 47 | + unitPrice: '单价/固定费:', | ||
| 48 | + areaUsage: '面积/用量:', | ||
| 49 | + paymentMethod: '支付方式:', | ||
| 50 | + meterReading: '表读数:', | ||
| 51 | + amount: '金额:', | ||
| 52 | + refund: '(退费)', | ||
| 53 | + discount: '优惠金额:', | ||
| 54 | + remark: '备注', | ||
| 55 | + total: '总计', | ||
| 56 | + issuer: '开票人', | ||
| 57 | + print: '打印', | ||
| 58 | + cloudPrint: '云打印', | ||
| 59 | + cancel: '取消', | ||
| 60 | + submit: '提交', | ||
| 61 | + printer: '打印机', | ||
| 62 | + printerRequired: '必填,请选择打印机', | ||
| 63 | + quantity: '数量', | ||
| 64 | + quantityRequired: '必填,请填写数量', | ||
| 65 | + noFee: '未包含费用', | ||
| 66 | + submitSuccess: '提交成功', | ||
| 67 | + submitFailed: '提交失败' | ||
| 68 | + } | ||
| 69 | + } | ||
| 70 | +} | ||
| 0 | \ No newline at end of file | 71 | \ No newline at end of file |
src/views/fee/printSmallPayFeeList.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <div class="printSmallPayFee-container"> | ||
| 3 | + | ||
| 4 | + <div class="print_container"> | ||
| 5 | + <div style="color:#000;font-size:32px" class="text-center"> | ||
| 6 | + <span>{{ $t('printSmallPayFee.receipt') }}</span> | ||
| 7 | + </div> | ||
| 8 | + <span>**************************</span> | ||
| 9 | + <div class="section2" style="font-size: 12px; margin-left: 5px;"> | ||
| 10 | + <div> | ||
| 11 | + <span>{{ $t('printSmallPayFee.receiptNum') }}</span>{{ printSmallPayFeeInfo.receiptNum }} | ||
| 12 | + </div> | ||
| 13 | + <div> | ||
| 14 | + <span>{{ $t('printSmallPayFee.orderNum') }}</span>{{ printSmallPayFeeInfo.payOrderId }} | ||
| 15 | + </div> | ||
| 16 | + <div> | ||
| 17 | + <span>{{ $t('printSmallPayFee.roomNum') }}</span>: {{ printSmallPayFeeInfo.roomName }} | ||
| 18 | + </div> | ||
| 19 | + <div> | ||
| 20 | + <span>{{ $t('printSmallPayFee.owner') }}</span>: {{ printSmallPayFeeInfo.payObjName }} | ||
| 21 | + </div> | ||
| 22 | + <div> | ||
| 23 | + <span>{{ $t('printSmallPayFee.time') }}</span>: {{ printSmallPayFeeInfo.feeTime }} | ||
| 24 | + </div> | ||
| 25 | + </div> | ||
| 26 | + <span>**************************</span> | ||
| 27 | + <div class="section2" style="font-size: 12px; margin-left: 5px;" | ||
| 28 | + v-for="(item, index) in printSmallPayFeeInfo.fees" :key="index"> | ||
| 29 | + <div> | ||
| 30 | + <span>{{ $t('printSmallPayFee.feeItem') }}</span>: {{ item.feeName }} | ||
| 31 | + </div> | ||
| 32 | + <div> | ||
| 33 | + <span>{{ $t('printSmallPayFee.feeRange') }}</span>: {{ formatDate(item.startTime) }} | ||
| 34 | + <span>{{ $t('printSmallPayFee.to') }}</span>{{ formatDate(item.endTime) }} | ||
| 35 | + </div> | ||
| 36 | + <div> | ||
| 37 | + <span>{{ $t('printSmallPayFee.unitPrice') }}</span>{{ item.squarePrice }} | ||
| 38 | + </div> | ||
| 39 | + <div> | ||
| 40 | + <span>{{ $t('printSmallPayFee.areaUsage') }}</span>{{ item.area }} | ||
| 41 | + </div> | ||
| 42 | + <div> | ||
| 43 | + <span>{{ $t('printSmallPayFee.paymentMethod') }}</span>{{ item.primeRate }} | ||
| 44 | + </div> | ||
| 45 | + <div v-if="item.preDegrees"> | ||
| 46 | + <span>{{ $t('printSmallPayFee.meterReading') }}</span>{{ item.preDegrees }} {{ $t('printSmallPayFee.to') }} | ||
| 47 | + {{ item.curDegrees }} | ||
| 48 | + </div> | ||
| 49 | + <div> | ||
| 50 | + <span>{{ $t('printSmallPayFee.amount') }}</span> | ||
| 51 | + <span>{{ formatAmount(item.amount) }}</span> | ||
| 52 | + </div> | ||
| 53 | + <div> | ||
| 54 | + <span>{{ $t('printSmallPayFee.discount') }}</span> {{ item.discountPrice || 0 }} | ||
| 55 | + </div> | ||
| 56 | + <div> | ||
| 57 | + <span>{{ $t('printSmallPayFee.remark') }}</span>: {{ item.remark }} | ||
| 58 | + </div> | ||
| 59 | + <span>**************************</span> | ||
| 60 | + </div> | ||
| 61 | + <div class="section5" style="font-size: 12px; margin-left: 5px;"> | ||
| 62 | + <div> | ||
| 63 | + <span>{{ $t('printSmallPayFee.total') }}</span>: {{ printSmallPayFeeInfo.amount }} | ||
| 64 | + </div> | ||
| 65 | + <div> | ||
| 66 | + <span>{{ $t('printSmallPayFee.issuer') }}</span>: {{ userInfo.name }} | ||
| 67 | + </div> | ||
| 68 | + <div v-html="printSmallPayFeeInfo.content"></div> | ||
| 69 | + <div><img :src="printSmallPayFeeInfo.qrImg" width="100px" height="100px"></div> | ||
| 70 | + </div> | ||
| 71 | + <span>**************************</span> | ||
| 72 | + </div> | ||
| 73 | + | ||
| 74 | + <div id="print-btn" class="action-buttons"> | ||
| 75 | + <el-button type="primary" class="float-right" @click="handlePrint"> | ||
| 76 | + <i class="el-icon-printer"></i> {{ $t('printSmallPayFee.print') }} | ||
| 77 | + </el-button> | ||
| 78 | + <el-button class="float-right margin-right" @click="handleCloudPrint"> | ||
| 79 | + <i class="el-icon-cloudy"></i> {{ $t('printSmallPayFee.cloudPrint') }} | ||
| 80 | + </el-button> | ||
| 81 | + <el-button class="float-right margin-right" @click="handleClose"> | ||
| 82 | + <span>{{ $t('printSmallPayFee.cancel') }}</span> | ||
| 83 | + </el-button> | ||
| 84 | + </div> | ||
| 85 | + | ||
| 86 | + | ||
| 87 | + <el-dialog :title="$t('printSmallPayFee.cloudPrint')" :visible.sync="cloudPrintVisible" width="50%"> | ||
| 88 | + <div class="cloud-print-content"> | ||
| 89 | + <el-form label-width="120px"> | ||
| 90 | + <el-form-item :label="$t('printSmallPayFee.printer')"> | ||
| 91 | + <el-select v-model="printSmallPayFeeInfo.machineId" style="width:100%" | ||
| 92 | + :placeholder="$t('printSmallPayFee.printerRequired')"> | ||
| 93 | + <el-option v-for="(item, index) in printSmallPayFeeInfo.machines" :key="index" | ||
| 94 | + :label="`${item.machineName}(${item.machineCode})`" :value="item.machineId" /> | ||
| 95 | + </el-select> | ||
| 96 | + </el-form-item> | ||
| 97 | + <el-form-item :label="$t('printSmallPayFee.quantity')"> | ||
| 98 | + <el-input v-model="printSmallPayFeeInfo.quantity" type="number" | ||
| 99 | + :placeholder="$t('printSmallPayFee.quantityRequired')" /> | ||
| 100 | + </el-form-item> | ||
| 101 | + </el-form> | ||
| 102 | + </div> | ||
| 103 | + <span slot="footer" class="dialog-footer"> | ||
| 104 | + <el-button @click="cloudPrintVisible = false">{{ $t('printSmallPayFee.cancel') }}</el-button> | ||
| 105 | + <el-button type="primary" @click="handleSubmitCloudPrint">{{ $t('printSmallPayFee.submit') }}</el-button> | ||
| 106 | + </span> | ||
| 107 | + </el-dialog> | ||
| 108 | + </div> | ||
| 109 | +</template> | ||
| 110 | + | ||
| 111 | +<script> | ||
| 112 | +import { | ||
| 113 | + queryFeeReceipt, | ||
| 114 | + queryFeeReceiptDetail, | ||
| 115 | + queryFeePrintSpec, | ||
| 116 | + listMachinePrinter, | ||
| 117 | + printPayFeeDetail | ||
| 118 | +} from '@/api/fee/printSmallPayFeeApi' | ||
| 119 | +import { getCommunityId } from '@/api/community/communityApi' | ||
| 120 | +import { getUserId,getUserName } from '@/api/user/userApi' | ||
| 121 | + | ||
| 122 | +export default { | ||
| 123 | + name: 'PrintSmallPayFeeList', | ||
| 124 | + data() { | ||
| 125 | + return { | ||
| 126 | + printSmallPayFeeInfo: { | ||
| 127 | + communityName: '', | ||
| 128 | + receiptId: '', | ||
| 129 | + receiptIds: '', | ||
| 130 | + receiptNum: '', | ||
| 131 | + payOrderId: '', | ||
| 132 | + roomName: '', | ||
| 133 | + amount: 0.00, | ||
| 134 | + fees: [], | ||
| 135 | + feeTime: '', | ||
| 136 | + wechatName: '', | ||
| 137 | + content: '', | ||
| 138 | + qrImg: '', | ||
| 139 | + payObjName: '', | ||
| 140 | + machineId: '', | ||
| 141 | + quantity: '1', | ||
| 142 | + machines: [] | ||
| 143 | + }, | ||
| 144 | + cloudPrintVisible: false, | ||
| 145 | + userInfo: {} | ||
| 146 | + } | ||
| 147 | + }, | ||
| 148 | + created() { | ||
| 149 | + this.printSmallPayFeeInfo.receiptId = this.$route.query.receiptId | ||
| 150 | + this.printSmallPayFeeInfo.receiptIds = this.$route.query.receiptIds | ||
| 151 | + this.printSmallPayFeeInfo.communityName = getCommunityId().name | ||
| 152 | + this.loadData() | ||
| 153 | + this.userInfo = { | ||
| 154 | + userId: getUserId(), | ||
| 155 | + name: getUserName() | ||
| 156 | + } | ||
| 157 | + }, | ||
| 158 | + methods: { | ||
| 159 | + async loadData() { | ||
| 160 | + await this.loadReceipt() | ||
| 161 | + await this.loadReceiptDetail() | ||
| 162 | + await this.loadPrintSpec() | ||
| 163 | + }, | ||
| 164 | + async loadReceipt() { | ||
| 165 | + try { | ||
| 166 | + const params = { | ||
| 167 | + page: 1, | ||
| 168 | + row: 30, | ||
| 169 | + receiptId: this.printSmallPayFeeInfo.receiptId, | ||
| 170 | + receiptIds: this.printSmallPayFeeInfo.receiptIds, | ||
| 171 | + communityId: getCommunityId() | ||
| 172 | + } | ||
| 173 | + const { data } = await queryFeeReceipt(params) | ||
| 174 | + const _feeReceipt = data | ||
| 175 | + let _amount = 0 | ||
| 176 | + _feeReceipt.forEach(item => { | ||
| 177 | + _amount += parseFloat(item.amount) | ||
| 178 | + }) | ||
| 179 | + this.printSmallPayFeeInfo.amount = _amount.toFixed(2) | ||
| 180 | + this.printSmallPayFeeInfo.roomName = _feeReceipt[0].objName | ||
| 181 | + this.printSmallPayFeeInfo.feeTime = _feeReceipt[0].createTime | ||
| 182 | + this.printSmallPayFeeInfo.payObjName = _feeReceipt[0].payObjName | ||
| 183 | + this.printSmallPayFeeInfo.receiptNum = _feeReceipt[0].receiptCode | ||
| 184 | + } catch (error) { | ||
| 185 | + console.error('Failed to load receipt:', error) | ||
| 186 | + } | ||
| 187 | + }, | ||
| 188 | + async loadReceiptDetail() { | ||
| 189 | + try { | ||
| 190 | + const params = { | ||
| 191 | + page: 1, | ||
| 192 | + row: 100, | ||
| 193 | + receiptId: this.printSmallPayFeeInfo.receiptId, | ||
| 194 | + receiptIds: this.printSmallPayFeeInfo.receiptIds, | ||
| 195 | + communityId: getCommunityId(), | ||
| 196 | + orderBy: 'start_time' | ||
| 197 | + } | ||
| 198 | + const { data } = await queryFeeReceiptDetail(params) | ||
| 199 | + this.printSmallPayFeeInfo.payOrderId = data[0].payOrderId | ||
| 200 | + this.printSmallPayFeeInfo.fees = data | ||
| 201 | + } catch (error) { | ||
| 202 | + console.error('Failed to load receipt detail:', error) | ||
| 203 | + } | ||
| 204 | + }, | ||
| 205 | + async loadPrintSpec() { | ||
| 206 | + try { | ||
| 207 | + const params = { | ||
| 208 | + page: 1, | ||
| 209 | + row: 1, | ||
| 210 | + specCd: 2020, | ||
| 211 | + communityId: getCommunityId() | ||
| 212 | + } | ||
| 213 | + const { data } = await queryFeePrintSpec(params) | ||
| 214 | + if (data.length > 0) { | ||
| 215 | + this.printSmallPayFeeInfo.content = data[0].content | ||
| 216 | + this.printSmallPayFeeInfo.qrImg = data[0].qrImg | ||
| 217 | + } | ||
| 218 | + } catch (error) { | ||
| 219 | + console.error('Failed to load print spec:', error) | ||
| 220 | + } | ||
| 221 | + }, | ||
| 222 | + formatDate(date) { | ||
| 223 | + if (!date) return '' | ||
| 224 | + return new Date(date).toLocaleDateString() | ||
| 225 | + }, | ||
| 226 | + formatAmount(amount) { | ||
| 227 | + if (amount < 0) { | ||
| 228 | + return amount + this.$t('printSmallPayFee.refund') | ||
| 229 | + } | ||
| 230 | + return amount | ||
| 231 | + }, | ||
| 232 | + handlePrint() { | ||
| 233 | + window.print() | ||
| 234 | + }, | ||
| 235 | + handleCloudPrint() { | ||
| 236 | + this.listMachinePrinter() | ||
| 237 | + this.cloudPrintVisible = true | ||
| 238 | + }, | ||
| 239 | + async listMachinePrinter() { | ||
| 240 | + try { | ||
| 241 | + const params = { | ||
| 242 | + page: 1, | ||
| 243 | + row: 100, | ||
| 244 | + communityId: getCommunityId() | ||
| 245 | + } | ||
| 246 | + const { data } = await listMachinePrinter(params) | ||
| 247 | + this.printSmallPayFeeInfo.machines = data | ||
| 248 | + if (this.printSmallPayFeeInfo.machines && this.printSmallPayFeeInfo.machines.length > 0) { | ||
| 249 | + this.printSmallPayFeeInfo.machineId = this.printSmallPayFeeInfo.machines[0].machineId | ||
| 250 | + } | ||
| 251 | + } catch (error) { | ||
| 252 | + console.error('Failed to list machine printer:', error) | ||
| 253 | + } | ||
| 254 | + }, | ||
| 255 | + async handleSubmitCloudPrint() { | ||
| 256 | + try { | ||
| 257 | + const detailIds = this.printSmallPayFeeInfo.fees.map(item => item.detailId) | ||
| 258 | + if (detailIds.length < 1) { | ||
| 259 | + this.$message.error(this.$t('printSmallPayFee.noFee')) | ||
| 260 | + return | ||
| 261 | + } | ||
| 262 | + const data = { | ||
| 263 | + communityId: getCommunityId(), | ||
| 264 | + machineId: this.printSmallPayFeeInfo.machineId, | ||
| 265 | + quantity: this.printSmallPayFeeInfo.quantity, | ||
| 266 | + detailId: detailIds.join(',') | ||
| 267 | + } | ||
| 268 | + await printPayFeeDetail(data) | ||
| 269 | + this.cloudPrintVisible = false | ||
| 270 | + this.$message.success(this.$t('printSmallPayFee.submitSuccess')) | ||
| 271 | + } catch (error) { | ||
| 272 | + console.error('Failed to submit cloud print:', error) | ||
| 273 | + this.$message.error(error.message || this.$t('printSmallPayFee.submitFailed')) | ||
| 274 | + } | ||
| 275 | + }, | ||
| 276 | + handleClose() { | ||
| 277 | + this.$router.go(-1) | ||
| 278 | + } | ||
| 279 | + } | ||
| 280 | +} | ||
| 281 | +</script> | ||
| 282 | + | ||
| 283 | +<style scoped> | ||
| 284 | +.printSmallPayFee-container { | ||
| 285 | + padding: 20px; | ||
| 286 | +} | ||
| 287 | + | ||
| 288 | +.print_container { | ||
| 289 | + padding: 20px; | ||
| 290 | + background: #fff; | ||
| 291 | +} | ||
| 292 | + | ||
| 293 | +.text-center { | ||
| 294 | + text-align: center; | ||
| 295 | +} | ||
| 296 | + | ||
| 297 | +.section2, | ||
| 298 | +.section5 { | ||
| 299 | + margin-bottom: 15px; | ||
| 300 | +} | ||
| 301 | + | ||
| 302 | +.action-buttons { | ||
| 303 | + margin-top: 20px; | ||
| 304 | + text-align: right; | ||
| 305 | +} | ||
| 306 | + | ||
| 307 | +.float-right { | ||
| 308 | + float: right; | ||
| 309 | +} | ||
| 310 | + | ||
| 311 | +.margin-right { | ||
| 312 | + margin-right: 10px; | ||
| 313 | +} | ||
| 314 | + | ||
| 315 | +.cloud-print-content { | ||
| 316 | + padding: 20px; | ||
| 317 | +} | ||
| 318 | +</style> | ||
| 0 | \ No newline at end of file | 319 | \ No newline at end of file |