Commit 9b01bbd3b49b65c684120ac159c6f3b1381fd66b
1 parent
20e526fa
开发完成发票相关功能
Showing
25 changed files
with
2925 additions
and
2 deletions
src/api/fee/addOwnerInvoiceApi.js
0 → 100644
| 1 | +import request from '@/utils/request' | ||
| 2 | + | ||
| 3 | +// 保存业主发票信息 | ||
| 4 | +export function saveOwnerInvoice(data) { | ||
| 5 | + return new Promise((resolve, reject) => { | ||
| 6 | + request({ | ||
| 7 | + url: '/invoice.saveOwnerInvoice', | ||
| 8 | + method: 'post', | ||
| 9 | + data | ||
| 10 | + }).then(response => { | ||
| 11 | + const res = response.data | ||
| 12 | + if (res.code === 0) { | ||
| 13 | + resolve(res) | ||
| 14 | + } else { | ||
| 15 | + reject(new Error(res.msg || '保存发票信息失败')) | ||
| 16 | + } | ||
| 17 | + }).catch(error => { | ||
| 18 | + reject(error) | ||
| 19 | + }) | ||
| 20 | + }) | ||
| 21 | +} | ||
| 22 | + | ||
| 23 | +// 查询业主列表 | ||
| 24 | +export function queryOwners(params) { | ||
| 25 | + return new Promise((resolve, reject) => { | ||
| 26 | + request({ | ||
| 27 | + url: '/owner.queryOwners', | ||
| 28 | + method: 'get', | ||
| 29 | + params | ||
| 30 | + }).then(response => { | ||
| 31 | + const res = response.data | ||
| 32 | + if (res.code === 0) { | ||
| 33 | + resolve({ | ||
| 34 | + data: res.data, | ||
| 35 | + total: res.records | ||
| 36 | + }) | ||
| 37 | + } else { | ||
| 38 | + reject(new Error(res.msg || '查询业主失败')) | ||
| 39 | + } | ||
| 40 | + }).catch(error => { | ||
| 41 | + reject(error) | ||
| 42 | + }) | ||
| 43 | + }) | ||
| 44 | +} | ||
| 0 | \ No newline at end of file | 45 | \ No newline at end of file |
src/api/fee/invoiceApplyApi.js
0 → 100644
| 1 | +import request from '@/utils/request' | ||
| 2 | +import { getCommunityId } from '@/api/community/communityApi' | ||
| 3 | + | ||
| 4 | +// 获取发票申请列表 | ||
| 5 | +export function listInvoiceApply(params) { | ||
| 6 | + return new Promise((resolve, reject) => { | ||
| 7 | + const communityId = getCommunityId() | ||
| 8 | + request({ | ||
| 9 | + url: '/invoice.listInvoiceApply', | ||
| 10 | + method: 'get', | ||
| 11 | + params: { | ||
| 12 | + ...params, | ||
| 13 | + communityId | ||
| 14 | + } | ||
| 15 | + }).then(response => { | ||
| 16 | + const res = response.data | ||
| 17 | + if (res.code === 0) { | ||
| 18 | + resolve(res) | ||
| 19 | + } else { | ||
| 20 | + reject(new Error(res.msg || '获取发票申请列表失败')) | ||
| 21 | + } | ||
| 22 | + }).catch(error => { | ||
| 23 | + reject(error) | ||
| 24 | + }) | ||
| 25 | + }) | ||
| 26 | +} | ||
| 27 | + | ||
| 28 | +// 审核发票申请 | ||
| 29 | +export function auditInvoiceApply(data) { | ||
| 30 | + return new Promise((resolve, reject) => { | ||
| 31 | + const communityId = getCommunityId() | ||
| 32 | + request({ | ||
| 33 | + url: '/invoice.auditInvoiceApply', | ||
| 34 | + method: 'post', | ||
| 35 | + data: { | ||
| 36 | + ...data, | ||
| 37 | + communityId | ||
| 38 | + } | ||
| 39 | + }).then(response => { | ||
| 40 | + const res = response.data | ||
| 41 | + if (res.code === 0) { | ||
| 42 | + resolve(res) | ||
| 43 | + } else { | ||
| 44 | + reject(new Error(res.msg || '审核发票申请失败')) | ||
| 45 | + } | ||
| 46 | + }).catch(error => { | ||
| 47 | + reject(error) | ||
| 48 | + }) | ||
| 49 | + }) | ||
| 50 | +} | ||
| 51 | + | ||
| 52 | +// 删除发票申请 | ||
| 53 | +export function deleteInvoiceApply(data) { | ||
| 54 | + return new Promise((resolve, reject) => { | ||
| 55 | + const communityId = getCommunityId() | ||
| 56 | + request({ | ||
| 57 | + url: '/invoice.deleteInvoiceApply', | ||
| 58 | + method: 'post', | ||
| 59 | + data: { | ||
| 60 | + ...data, | ||
| 61 | + communityId | ||
| 62 | + } | ||
| 63 | + }).then(response => { | ||
| 64 | + const res = response.data | ||
| 65 | + if (res.code === 0) { | ||
| 66 | + resolve(res) | ||
| 67 | + } else { | ||
| 68 | + reject(new Error(res.msg || '删除发票申请失败')) | ||
| 69 | + } | ||
| 70 | + }).catch(error => { | ||
| 71 | + reject(error) | ||
| 72 | + }) | ||
| 73 | + }) | ||
| 74 | +} | ||
| 75 | + | ||
| 76 | +// 上传发票照片 | ||
| 77 | +export function uploadInvoicePhoto(data) { | ||
| 78 | + return new Promise((resolve, reject) => { | ||
| 79 | + const communityId = getCommunityId() | ||
| 80 | + request({ | ||
| 81 | + url: '/invoice.uploadInvoicePhoto', | ||
| 82 | + method: 'post', | ||
| 83 | + data: { | ||
| 84 | + ...data, | ||
| 85 | + communityId | ||
| 86 | + } | ||
| 87 | + }).then(response => { | ||
| 88 | + const res = response.data | ||
| 89 | + if (res.code === 0) { | ||
| 90 | + resolve(res) | ||
| 91 | + } else { | ||
| 92 | + reject(new Error(res.msg || '上传发票照片失败')) | ||
| 93 | + } | ||
| 94 | + }).catch(error => { | ||
| 95 | + reject(error) | ||
| 96 | + }) | ||
| 97 | + }) | ||
| 98 | +} | ||
| 99 | + | ||
| 100 | +// 写入发票事件 | ||
| 101 | +export function writeInvoiceEvent(data) { | ||
| 102 | + return new Promise((resolve, reject) => { | ||
| 103 | + const communityId = getCommunityId() | ||
| 104 | + request({ | ||
| 105 | + url: '/invoice.writeInvoiceApply', | ||
| 106 | + method: 'post', | ||
| 107 | + data: { | ||
| 108 | + ...data, | ||
| 109 | + communityId | ||
| 110 | + } | ||
| 111 | + }).then(response => { | ||
| 112 | + const res = response.data | ||
| 113 | + if (res.code === 0) { | ||
| 114 | + resolve(res) | ||
| 115 | + } else { | ||
| 116 | + reject(new Error(res.msg || '写入发票事件失败')) | ||
| 117 | + } | ||
| 118 | + }).catch(error => { | ||
| 119 | + reject(error) | ||
| 120 | + }) | ||
| 121 | + }) | ||
| 122 | +} | ||
| 123 | + | ||
| 124 | +// 上传图片 | ||
| 125 | +export function uploadImage(formData) { | ||
| 126 | + return new Promise((resolve, reject) => { | ||
| 127 | + const communityId = getCommunityId() | ||
| 128 | + formData.append('communityId', communityId) | ||
| 129 | + | ||
| 130 | + request({ | ||
| 131 | + url: 'uploadFile/uploadImage', | ||
| 132 | + method: 'post', | ||
| 133 | + data: formData, | ||
| 134 | + headers: { | ||
| 135 | + 'Content-Type': 'multipart/form-data' | ||
| 136 | + } | ||
| 137 | + }).then(response => { | ||
| 138 | + const res = response.data | ||
| 139 | + if (res.code === 0) { | ||
| 140 | + resolve(res.data) | ||
| 141 | + } else { | ||
| 142 | + reject(new Error(res.msg || '上传图片失败')) | ||
| 143 | + } | ||
| 144 | + }).catch(error => { | ||
| 145 | + reject(error) | ||
| 146 | + }) | ||
| 147 | + }) | ||
| 148 | +} | ||
| 0 | \ No newline at end of file | 149 | \ No newline at end of file |
src/api/fee/invoiceApplyDetailApi.js
0 → 100644
| 1 | +import request from '@/utils/request' | ||
| 2 | +import { getCommunityId } from '@/api/community/communityApi' | ||
| 3 | + | ||
| 4 | +/** | ||
| 5 | + * 获取发票申请详情 | ||
| 6 | + * @param {Object} params | ||
| 7 | + * @returns | ||
| 8 | + */ | ||
| 9 | +export function getInvoiceApplyDetail(params) { | ||
| 10 | + return new Promise((resolve, reject) => { | ||
| 11 | + params.communityId = getCommunityId() | ||
| 12 | + request({ | ||
| 13 | + url: '/invoice.listInvoiceApply', | ||
| 14 | + method: 'get', | ||
| 15 | + params | ||
| 16 | + }).then(response => { | ||
| 17 | + const res = response.data | ||
| 18 | + if (res.code === 0) { | ||
| 19 | + resolve(res) | ||
| 20 | + } else { | ||
| 21 | + reject(new Error(res.msg || '获取发票申请详情失败')) | ||
| 22 | + } | ||
| 23 | + }).catch(error => { | ||
| 24 | + reject(error) | ||
| 25 | + }) | ||
| 26 | + }) | ||
| 27 | +} | ||
| 28 | + | ||
| 29 | +/** | ||
| 30 | + * 获取发票申请费用明细 | ||
| 31 | + * @param {Object} params | ||
| 32 | + * @returns | ||
| 33 | + */ | ||
| 34 | +export function getInvoiceApplyItemList(params) { | ||
| 35 | + return new Promise((resolve, reject) => { | ||
| 36 | + params.communityId = getCommunityId() | ||
| 37 | + request({ | ||
| 38 | + url: '/invoice.listInvoiceApplyItem', | ||
| 39 | + method: 'get', | ||
| 40 | + params | ||
| 41 | + }).then(response => { | ||
| 42 | + const res = response.data | ||
| 43 | + if (res.code === 0) { | ||
| 44 | + resolve(res) | ||
| 45 | + } else { | ||
| 46 | + reject(new Error(res.msg || '获取发票申请费用明细失败')) | ||
| 47 | + } | ||
| 48 | + }).catch(error => { | ||
| 49 | + reject(error) | ||
| 50 | + }) | ||
| 51 | + }) | ||
| 52 | +} | ||
| 53 | + | ||
| 54 | +/** | ||
| 55 | + * 获取发票申请审核记录 | ||
| 56 | + * @param {Object} params | ||
| 57 | + * @returns | ||
| 58 | + */ | ||
| 59 | +export function getInvoiceEventList(params) { | ||
| 60 | + return new Promise((resolve, reject) => { | ||
| 61 | + params.communityId = getCommunityId() | ||
| 62 | + request({ | ||
| 63 | + url: '/invoice.listInvoiceEvent', | ||
| 64 | + method: 'get', | ||
| 65 | + params | ||
| 66 | + }).then(response => { | ||
| 67 | + const res = response.data | ||
| 68 | + if (res.code === 0) { | ||
| 69 | + resolve(res) | ||
| 70 | + } else { | ||
| 71 | + reject(new Error(res.msg || '获取发票申请审核记录失败')) | ||
| 72 | + } | ||
| 73 | + }).catch(error => { | ||
| 74 | + reject(error) | ||
| 75 | + }) | ||
| 76 | + }) | ||
| 77 | +} | ||
| 0 | \ No newline at end of file | 78 | \ No newline at end of file |
src/api/fee/ownerApplyInvoiceApi.js
0 → 100644
| 1 | +import request from '@/utils/request' | ||
| 2 | +import { getCommunityId } from '@/api/community/communityApi' | ||
| 3 | + | ||
| 4 | +// 获取业主发票信息列表 | ||
| 5 | +export function listOwnerInvoice(params) { | ||
| 6 | + return new Promise((resolve, reject) => { | ||
| 7 | + const communityId = getCommunityId() | ||
| 8 | + request({ | ||
| 9 | + url: '/invoice.listOwnerInvoice', | ||
| 10 | + method: 'get', | ||
| 11 | + params: { | ||
| 12 | + ...params, | ||
| 13 | + communityId | ||
| 14 | + } | ||
| 15 | + }).then(response => { | ||
| 16 | + const res = response.data | ||
| 17 | + | ||
| 18 | + resolve(res) | ||
| 19 | + }).catch(error => { | ||
| 20 | + reject(error) | ||
| 21 | + }) | ||
| 22 | + }) | ||
| 23 | +} | ||
| 24 | + | ||
| 25 | +// 查询费用明细 | ||
| 26 | +export function queryFeeDetail(params) { | ||
| 27 | + return new Promise((resolve, reject) => { | ||
| 28 | + const communityId = getCommunityId() | ||
| 29 | + request({ | ||
| 30 | + url: '/fee.queryFeeDetail', | ||
| 31 | + method: 'get', | ||
| 32 | + params: { | ||
| 33 | + ...params, | ||
| 34 | + communityId | ||
| 35 | + } | ||
| 36 | + }).then(response => { | ||
| 37 | + const res = response.data | ||
| 38 | + | ||
| 39 | + resolve(res) | ||
| 40 | + }).catch(error => { | ||
| 41 | + reject(error) | ||
| 42 | + }) | ||
| 43 | + }) | ||
| 44 | +} | ||
| 45 | + | ||
| 46 | +// 查询账户预存明细 | ||
| 47 | +export function listAccountReceipt(params) { | ||
| 48 | + return new Promise((resolve, reject) => { | ||
| 49 | + const communityId = getCommunityId() | ||
| 50 | + request({ | ||
| 51 | + url: '/receipt.listAccountReceipt', | ||
| 52 | + method: 'get', | ||
| 53 | + params: { | ||
| 54 | + ...params, | ||
| 55 | + communityId | ||
| 56 | + } | ||
| 57 | + }).then(response => { | ||
| 58 | + const res = response.data | ||
| 59 | + | ||
| 60 | + resolve(res) | ||
| 61 | + }).catch(error => { | ||
| 62 | + reject(error) | ||
| 63 | + }) | ||
| 64 | + }) | ||
| 65 | +} | ||
| 66 | + | ||
| 67 | +// 保存发票申请 | ||
| 68 | +export function saveInvoiceApply(data) { | ||
| 69 | + return new Promise((resolve, reject) => { | ||
| 70 | + const communityId = getCommunityId() | ||
| 71 | + request({ | ||
| 72 | + url: '/invoice.saveInvoiceApply', | ||
| 73 | + method: 'post', | ||
| 74 | + data: { | ||
| 75 | + ...data, | ||
| 76 | + communityId | ||
| 77 | + } | ||
| 78 | + }).then(response => { | ||
| 79 | + const res = response.data | ||
| 80 | + if (res.code === 0) { | ||
| 81 | + resolve(res) | ||
| 82 | + } else { | ||
| 83 | + reject(new Error(res.msg || '保存发票申请失败')) | ||
| 84 | + } | ||
| 85 | + }).catch(error => { | ||
| 86 | + reject(error) | ||
| 87 | + }) | ||
| 88 | + }) | ||
| 89 | +} | ||
| 0 | \ No newline at end of file | 90 | \ No newline at end of file |
src/api/fee/ownerInvoiceApi.js
0 → 100644
| 1 | +import request from '@/utils/request' | ||
| 2 | +import { getCommunityId } from '@/api/community/communityApi' | ||
| 3 | + | ||
| 4 | +// 查询业主发票列表 | ||
| 5 | +export function listOwnerInvoice(params) { | ||
| 6 | + return new Promise((resolve, reject) => { | ||
| 7 | + params.communityId = getCommunityId() | ||
| 8 | + request({ | ||
| 9 | + url: '/invoice.listOwnerInvoice', | ||
| 10 | + method: 'get', | ||
| 11 | + params | ||
| 12 | + }).then(response => { | ||
| 13 | + const res = response.data | ||
| 14 | + if (res.code === 0) { | ||
| 15 | + resolve(res) | ||
| 16 | + } else { | ||
| 17 | + reject(new Error(res.msg || '获取发票列表失败')) | ||
| 18 | + } | ||
| 19 | + }).catch(error => { | ||
| 20 | + reject(error) | ||
| 21 | + }) | ||
| 22 | + }) | ||
| 23 | +} | ||
| 24 | + | ||
| 25 | +// 更新业主发票 | ||
| 26 | +export function updateOwnerInvoice(data) { | ||
| 27 | + return new Promise((resolve, reject) => { | ||
| 28 | + data.communityId = getCommunityId() | ||
| 29 | + request({ | ||
| 30 | + url: '/invoice.updateOwnerInvoice', | ||
| 31 | + method: 'post', | ||
| 32 | + data | ||
| 33 | + }).then(response => { | ||
| 34 | + const res = response.data | ||
| 35 | + if (res.code === 0) { | ||
| 36 | + resolve(res) | ||
| 37 | + } else { | ||
| 38 | + reject(new Error(res.msg || '更新发票失败')) | ||
| 39 | + } | ||
| 40 | + }).catch(error => { | ||
| 41 | + reject(error) | ||
| 42 | + }) | ||
| 43 | + }) | ||
| 44 | +} | ||
| 45 | + | ||
| 46 | +// 删除业主发票 | ||
| 47 | +export function deleteOwnerInvoice(data) { | ||
| 48 | + return new Promise((resolve, reject) => { | ||
| 49 | + data.communityId = getCommunityId() | ||
| 50 | + request({ | ||
| 51 | + url: '/invoice.deleteOwnerInvoice', | ||
| 52 | + method: 'post', | ||
| 53 | + data | ||
| 54 | + }).then(response => { | ||
| 55 | + const res = response.data | ||
| 56 | + if (res.code === 0) { | ||
| 57 | + resolve(res) | ||
| 58 | + } else { | ||
| 59 | + reject(new Error(res.msg || '删除发票失败')) | ||
| 60 | + } | ||
| 61 | + }).catch(error => { | ||
| 62 | + reject(error) | ||
| 63 | + }) | ||
| 64 | + }) | ||
| 65 | +} | ||
| 0 | \ No newline at end of file | 66 | \ No newline at end of file |
src/components/fee/audit.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <el-dialog | ||
| 3 | + :title="$t('audit.title')" | ||
| 4 | + :visible.sync="visible" | ||
| 5 | + width="50%" | ||
| 6 | + @close="closeDialog" | ||
| 7 | + > | ||
| 8 | + <el-form label-width="120px"> | ||
| 9 | + <el-form-item :label="$t('audit.status')"> | ||
| 10 | + <el-select | ||
| 11 | + v-model="form.state" | ||
| 12 | + :placeholder="$t('audit.statusRequired')" | ||
| 13 | + style="width: 100%" | ||
| 14 | + > | ||
| 15 | + <el-option | ||
| 16 | + :label="$t('audit.approve')" | ||
| 17 | + value="1100" | ||
| 18 | + /> | ||
| 19 | + <el-option | ||
| 20 | + :label="$t('audit.reject')" | ||
| 21 | + value="1200" | ||
| 22 | + /> | ||
| 23 | + </el-select> | ||
| 24 | + </el-form-item> | ||
| 25 | + <el-form-item :label="$t('audit.reason')"> | ||
| 26 | + <el-input | ||
| 27 | + v-model="form.remark" | ||
| 28 | + type="textarea" | ||
| 29 | + :rows="3" | ||
| 30 | + :placeholder="$t('audit.reasonRequired')" | ||
| 31 | + /> | ||
| 32 | + </el-form-item> | ||
| 33 | + </el-form> | ||
| 34 | + <div slot="footer"> | ||
| 35 | + <el-button @click="closeDialog">{{ $t('common.cancel') }}</el-button> | ||
| 36 | + <el-button | ||
| 37 | + type="primary" | ||
| 38 | + @click="submitAudit" | ||
| 39 | + >{{ $t('common.submit') }}</el-button> | ||
| 40 | + </div> | ||
| 41 | + </el-dialog> | ||
| 42 | +</template> | ||
| 43 | + | ||
| 44 | +<script> | ||
| 45 | +export default { | ||
| 46 | + name: 'AuditDialog', | ||
| 47 | + data() { | ||
| 48 | + return { | ||
| 49 | + visible: false, | ||
| 50 | + form: { | ||
| 51 | + state: '', | ||
| 52 | + remark: '' | ||
| 53 | + } | ||
| 54 | + } | ||
| 55 | + }, | ||
| 56 | + watch: { | ||
| 57 | + 'form.state'(val) { | ||
| 58 | + if (val === '1100') { | ||
| 59 | + this.form.remark = this.$t('audit.approve') | ||
| 60 | + } else if (val === '1200') { | ||
| 61 | + this.form.remark = this.$t('audit.reject') + ': ' | ||
| 62 | + } | ||
| 63 | + } | ||
| 64 | + }, | ||
| 65 | + methods: { | ||
| 66 | + open() { | ||
| 67 | + this.form = { | ||
| 68 | + state: '', | ||
| 69 | + remark: '' | ||
| 70 | + } | ||
| 71 | + this.visible = true | ||
| 72 | + }, | ||
| 73 | + closeDialog() { | ||
| 74 | + this.visible = false | ||
| 75 | + }, | ||
| 76 | + submitAudit() { | ||
| 77 | + if (!this.form.state) { | ||
| 78 | + this.$message.warning(this.$t('audit.statusRequired')) | ||
| 79 | + return | ||
| 80 | + } | ||
| 81 | + if (!this.form.remark) { | ||
| 82 | + this.$message.warning(this.$t('audit.reasonRequired')) | ||
| 83 | + return | ||
| 84 | + } | ||
| 85 | + this.$emit('success', this.form) | ||
| 86 | + this.closeDialog() | ||
| 87 | + } | ||
| 88 | + } | ||
| 89 | +} | ||
| 90 | +</script> | ||
| 0 | \ No newline at end of file | 91 | \ No newline at end of file |
src/components/fee/deleteInvoiceApply.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <el-dialog | ||
| 3 | + :title="$t('deleteInvoiceApply.title')" | ||
| 4 | + :visible.sync="visible" | ||
| 5 | + width="30%" | ||
| 6 | + @close="closeDialog" | ||
| 7 | + > | ||
| 8 | + <div align="center"> | ||
| 9 | + <p>{{ $t('deleteInvoiceApply.confirmMessage') }}</p> | ||
| 10 | + </div> | ||
| 11 | + <div slot="footer"> | ||
| 12 | + <el-button @click="closeDialog">{{ $t('common.cancel') }}</el-button> | ||
| 13 | + <el-button | ||
| 14 | + type="primary" | ||
| 15 | + @click="deleteInvoiceApply" | ||
| 16 | + >{{ $t('common.confirmDelete') }}</el-button> | ||
| 17 | + </div> | ||
| 18 | + </el-dialog> | ||
| 19 | +</template> | ||
| 20 | + | ||
| 21 | +<script> | ||
| 22 | +import { deleteInvoiceApply as deleteApi } from '@/api/fee/invoiceApplyApi' | ||
| 23 | +import { getCommunityId } from '@/api/community/communityApi' | ||
| 24 | + | ||
| 25 | +export default { | ||
| 26 | + name: 'DeleteInvoiceApply', | ||
| 27 | + data() { | ||
| 28 | + return { | ||
| 29 | + visible: false, | ||
| 30 | + applyData: {} | ||
| 31 | + } | ||
| 32 | + }, | ||
| 33 | + methods: { | ||
| 34 | + open(row) { | ||
| 35 | + this.applyData = { ...row } | ||
| 36 | + this.visible = true | ||
| 37 | + }, | ||
| 38 | + closeDialog() { | ||
| 39 | + this.visible = false | ||
| 40 | + }, | ||
| 41 | + async deleteInvoiceApply() { | ||
| 42 | + try { | ||
| 43 | + const params = { | ||
| 44 | + ...this.applyData, | ||
| 45 | + communityId: getCommunityId() | ||
| 46 | + } | ||
| 47 | + await deleteApi(params) | ||
| 48 | + this.$emit('success') | ||
| 49 | + this.$message.success(this.$t('common.deleteSuccess')) | ||
| 50 | + this.closeDialog() | ||
| 51 | + } catch (error) { | ||
| 52 | + this.$message.error(error.message) | ||
| 53 | + } | ||
| 54 | + } | ||
| 55 | + } | ||
| 56 | +} | ||
| 57 | +</script> | ||
| 0 | \ No newline at end of file | 58 | \ No newline at end of file |
src/components/fee/deleteOwnerInvoice.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <el-dialog | ||
| 3 | + :title="$t('confirmDeleteTitle')" | ||
| 4 | + :visible.sync="visible" | ||
| 5 | + width="30%" | ||
| 6 | + > | ||
| 7 | + <p>{{ $t('confirmDeleteContent') }}</p> | ||
| 8 | + <div slot="footer"> | ||
| 9 | + <el-button @click="visible = false">{{ $t('cancel') }}</el-button> | ||
| 10 | + <el-button type="danger" @click="handleDelete">{{ $t('confirmDelete') }}</el-button> | ||
| 11 | + </div> | ||
| 12 | + </el-dialog> | ||
| 13 | +</template> | ||
| 14 | + | ||
| 15 | +<script> | ||
| 16 | +import { deleteOwnerInvoice } from '@/api/fee/ownerInvoiceApi' | ||
| 17 | + | ||
| 18 | +export default { | ||
| 19 | + name: 'DeleteOwnerInvoice', | ||
| 20 | + data() { | ||
| 21 | + return { | ||
| 22 | + visible: false, | ||
| 23 | + currentData: null | ||
| 24 | + } | ||
| 25 | + }, | ||
| 26 | + methods: { | ||
| 27 | + open(data) { | ||
| 28 | + this.currentData = data | ||
| 29 | + this.visible = true | ||
| 30 | + }, | ||
| 31 | + async handleDelete() { | ||
| 32 | + try { | ||
| 33 | + await deleteOwnerInvoice({ oiId: this.currentData.oiId }) | ||
| 34 | + this.$message.success(this.$t('common.deleteSuccess')) | ||
| 35 | + this.visible = false | ||
| 36 | + this.$emit('success') | ||
| 37 | + } catch (error) { | ||
| 38 | + this.$message.error(error.message || this.$t('common.deleteFailed')) | ||
| 39 | + } | ||
| 40 | + } | ||
| 41 | + } | ||
| 42 | +} | ||
| 43 | +</script> | ||
| 0 | \ No newline at end of file | 44 | \ No newline at end of file |
src/components/fee/editOwnerInvoice.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <el-dialog | ||
| 3 | + :title="$t('editTitle')" | ||
| 4 | + :visible.sync="visible" | ||
| 5 | + width="50%" | ||
| 6 | + @close="resetForm" | ||
| 7 | + > | ||
| 8 | + <el-form ref="form" :model="formData" label-width="150px"> | ||
| 9 | + <el-form-item :label="$t('invoiceType')" prop="invoiceType" required> | ||
| 10 | + <el-select | ||
| 11 | + v-model="formData.invoiceType" | ||
| 12 | + :placeholder="$t('requiredInvoiceType')" | ||
| 13 | + style="width: 100%" | ||
| 14 | + > | ||
| 15 | + <el-option value="1001" :label="$t('personal')" /> | ||
| 16 | + <el-option value="2002" :label="$t('enterprise')" /> | ||
| 17 | + </el-select> | ||
| 18 | + </el-form-item> | ||
| 19 | + | ||
| 20 | + <el-form-item :label="$t('invoiceHeader')" prop="invoiceName" required> | ||
| 21 | + <el-input | ||
| 22 | + v-model="formData.invoiceName" | ||
| 23 | + :placeholder="$t('requiredInvoiceHeader')" | ||
| 24 | + /> | ||
| 25 | + </el-form-item> | ||
| 26 | + | ||
| 27 | + <el-form-item :label="$t('taxpayerId')" prop="invoiceNum" required> | ||
| 28 | + <el-input | ||
| 29 | + v-model="formData.invoiceNum" | ||
| 30 | + :placeholder="$t('requiredTaxpayerId')" | ||
| 31 | + /> | ||
| 32 | + </el-form-item> | ||
| 33 | + | ||
| 34 | + <el-form-item :label="$t('address')" prop="invoiceAddress" required> | ||
| 35 | + <el-input | ||
| 36 | + v-model="formData.invoiceAddress" | ||
| 37 | + :placeholder="$t('requiredAddress')" | ||
| 38 | + /> | ||
| 39 | + </el-form-item> | ||
| 40 | + | ||
| 41 | + <el-form-item :label="$t('phone')" prop="invoiceLink" required> | ||
| 42 | + <el-input | ||
| 43 | + v-model="formData.invoiceLink" | ||
| 44 | + :placeholder="$t('requiredPhone')" | ||
| 45 | + /> | ||
| 46 | + </el-form-item> | ||
| 47 | + | ||
| 48 | + <el-form-item :label="$t('bankAccount')" prop="invoiceAccount" required> | ||
| 49 | + <el-input | ||
| 50 | + v-model="formData.invoiceAccount" | ||
| 51 | + :placeholder="$t('requiredBankAccount')" | ||
| 52 | + /> | ||
| 53 | + </el-form-item> | ||
| 54 | + | ||
| 55 | + <el-form-item :label="$t('remark')" prop="remark"> | ||
| 56 | + <el-input | ||
| 57 | + v-model="formData.remark" | ||
| 58 | + type="textarea" | ||
| 59 | + :placeholder="$t('optionalRemark')" | ||
| 60 | + /> | ||
| 61 | + </el-form-item> | ||
| 62 | + </el-form> | ||
| 63 | + | ||
| 64 | + <div slot="footer"> | ||
| 65 | + <el-button @click="visible = false">{{ $t('cancel') }}</el-button> | ||
| 66 | + <el-button type="primary" @click="handleSave">{{ $t('save') }}</el-button> | ||
| 67 | + </div> | ||
| 68 | + </el-dialog> | ||
| 69 | +</template> | ||
| 70 | + | ||
| 71 | +<script> | ||
| 72 | +import { updateOwnerInvoice } from '@/api/fee/ownerInvoiceApi' | ||
| 73 | + | ||
| 74 | +export default { | ||
| 75 | + name: 'EditOwnerInvoice', | ||
| 76 | + data() { | ||
| 77 | + return { | ||
| 78 | + visible: false, | ||
| 79 | + formData: { | ||
| 80 | + oiId: '', | ||
| 81 | + ownerId: '', | ||
| 82 | + ownerName: '', | ||
| 83 | + invoiceType: '', | ||
| 84 | + invoiceName: '', | ||
| 85 | + invoiceNum: '', | ||
| 86 | + invoiceAddress: '', | ||
| 87 | + invoiceLink: '', | ||
| 88 | + invoiceAccount: '', | ||
| 89 | + remark: '' | ||
| 90 | + } | ||
| 91 | + } | ||
| 92 | + }, | ||
| 93 | + methods: { | ||
| 94 | + open(data) { | ||
| 95 | + Object.assign(this.formData, data) | ||
| 96 | + this.visible = true | ||
| 97 | + }, | ||
| 98 | + resetForm() { | ||
| 99 | + this.$refs.form.resetFields() | ||
| 100 | + Object.keys(this.formData).forEach(key => { | ||
| 101 | + this.formData[key] = '' | ||
| 102 | + }) | ||
| 103 | + }, | ||
| 104 | + async handleSave() { | ||
| 105 | + try { | ||
| 106 | + await updateOwnerInvoice(this.formData) | ||
| 107 | + this.$message.success(this.$t('common.saveSuccess')) | ||
| 108 | + this.visible = false | ||
| 109 | + this.$emit('success') | ||
| 110 | + } catch (error) { | ||
| 111 | + this.$message.error(error.message || this.$t('common.saveFailed')) | ||
| 112 | + } | ||
| 113 | + } | ||
| 114 | + } | ||
| 115 | +} | ||
| 116 | +</script> | ||
| 0 | \ No newline at end of file | 117 | \ No newline at end of file |
src/components/fee/invoiceApplyDetailEvent.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <div class="invoice-apply-detail-event"> | ||
| 3 | + <el-table :data="events" border style="width: 100%"> | ||
| 4 | + <el-table-column prop="eventTypeName" :label="$t('invoiceApplyDetailEvent.type')" align="center"></el-table-column> | ||
| 5 | + <el-table-column prop="createUserName" :label="$t('invoiceApplyDetailEvent.operator')" align="center"></el-table-column> | ||
| 6 | + <el-table-column prop="remark" :label="$t('invoiceApplyDetailEvent.remark')" align="center"></el-table-column> | ||
| 7 | + <el-table-column prop="createTime" :label="$t('invoiceApplyDetailEvent.time')" align="center"></el-table-column> | ||
| 8 | + </el-table> | ||
| 9 | + | ||
| 10 | + <el-pagination | ||
| 11 | + @size-change="handleSizeChange" | ||
| 12 | + @current-change="handleCurrentChange" | ||
| 13 | + :current-page="page.current" | ||
| 14 | + :page-sizes="[10, 20, 30, 50]" | ||
| 15 | + :page-size="page.size" | ||
| 16 | + layout="total, sizes, prev, pager, next, jumper" | ||
| 17 | + :total="page.total"> | ||
| 18 | + </el-pagination> | ||
| 19 | + </div> | ||
| 20 | +</template> | ||
| 21 | + | ||
| 22 | +<script> | ||
| 23 | +import { getInvoiceEventList } from '@/api/fee/invoiceApplyDetailApi' | ||
| 24 | + | ||
| 25 | +export default { | ||
| 26 | + name: 'InvoiceApplyDetailEvent', | ||
| 27 | + props: { | ||
| 28 | + applyId: { | ||
| 29 | + type: String, | ||
| 30 | + required: true | ||
| 31 | + } | ||
| 32 | + }, | ||
| 33 | + data() { | ||
| 34 | + return { | ||
| 35 | + events: [], | ||
| 36 | + page: { | ||
| 37 | + current: 1, | ||
| 38 | + size: 10, | ||
| 39 | + total: 0 | ||
| 40 | + } | ||
| 41 | + } | ||
| 42 | + }, | ||
| 43 | + watch: { | ||
| 44 | + applyId: { | ||
| 45 | + immediate: true, | ||
| 46 | + handler() { | ||
| 47 | + if (this.applyId) { | ||
| 48 | + this.loadData() | ||
| 49 | + } | ||
| 50 | + } | ||
| 51 | + } | ||
| 52 | + }, | ||
| 53 | + methods: { | ||
| 54 | + async loadData() { | ||
| 55 | + try { | ||
| 56 | + const params = { | ||
| 57 | + page: this.page.current, | ||
| 58 | + row: this.page.size, | ||
| 59 | + applyId: this.applyId | ||
| 60 | + } | ||
| 61 | + const res = await getInvoiceEventList(params) | ||
| 62 | + if (res.code === 0) { | ||
| 63 | + this.events = res.data | ||
| 64 | + this.page.total = res.total | ||
| 65 | + } | ||
| 66 | + } catch (error) { | ||
| 67 | + this.$message.error(this.$t('invoiceApplyDetailEvent.fetchError')) | ||
| 68 | + } | ||
| 69 | + }, | ||
| 70 | + handleSizeChange(val) { | ||
| 71 | + this.page.size = val | ||
| 72 | + this.loadData() | ||
| 73 | + }, | ||
| 74 | + handleCurrentChange(val) { | ||
| 75 | + this.page.current = val | ||
| 76 | + this.loadData() | ||
| 77 | + } | ||
| 78 | + } | ||
| 79 | +} | ||
| 80 | +</script> | ||
| 81 | + | ||
| 82 | +<style scoped> | ||
| 83 | +.invoice-apply-detail-event { | ||
| 84 | + margin-top: 20px; | ||
| 85 | +} | ||
| 86 | +</style> | ||
| 0 | \ No newline at end of file | 87 | \ No newline at end of file |
src/components/fee/invoiceApplyDetailFee.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <div class="invoice-apply-detail-fee"> | ||
| 3 | + <el-table :data="fees" border style="width: 100%"> | ||
| 4 | + <el-table-column prop="itemTypeName" :label="$t('invoiceApplyDetailFee.type')" align="center"></el-table-column> | ||
| 5 | + <el-table-column prop="itemName" :label="$t('invoiceApplyDetailFee.name')" align="center"></el-table-column> | ||
| 6 | + <el-table-column prop="itemAmount" :label="$t('invoiceApplyDetailFee.amount')" align="center"></el-table-column> | ||
| 7 | + <el-table-column prop="payTime" :label="$t('invoiceApplyDetailFee.payTime')" align="center"></el-table-column> | ||
| 8 | + <el-table-column prop="remark" :label="$t('invoiceApplyDetailFee.remark')" align="center"></el-table-column> | ||
| 9 | + <el-table-column :label="$t('invoiceApplyDetailFee.paymentId')" align="center"> | ||
| 10 | + <template slot-scope="scope"> | ||
| 11 | + {{ scope.row.itemObjId }} | ||
| 12 | + (<a href="javascript:void(0)" v-if="scope.row.itemType === '2002'" @click="viewFeeDetail(scope.row)">{{ $t('common.view') }}</a> | ||
| 13 | + <a href="javascript:void(0)" v-else @click="viewAcctDetail(scope.row)">{{ $t('common.view') }}</a>) | ||
| 14 | + </template> | ||
| 15 | + </el-table-column> | ||
| 16 | + </el-table> | ||
| 17 | + | ||
| 18 | + <el-pagination | ||
| 19 | + @size-change="handleSizeChange" | ||
| 20 | + @current-change="handleCurrentChange" | ||
| 21 | + :current-page="page.current" | ||
| 22 | + :page-sizes="[10, 20, 30, 50]" | ||
| 23 | + :page-size="page.size" | ||
| 24 | + layout="total, sizes, prev, pager, next, jumper" | ||
| 25 | + :total="page.total"> | ||
| 26 | + </el-pagination> | ||
| 27 | + </div> | ||
| 28 | +</template> | ||
| 29 | + | ||
| 30 | +<script> | ||
| 31 | +import { getInvoiceApplyItemList } from '@/api/fee/invoiceApplyDetailApi' | ||
| 32 | + | ||
| 33 | +export default { | ||
| 34 | + name: 'InvoiceApplyDetailFee', | ||
| 35 | + props: { | ||
| 36 | + applyId: { | ||
| 37 | + type: String, | ||
| 38 | + required: true | ||
| 39 | + }, | ||
| 40 | + ownerId: { | ||
| 41 | + type: String, | ||
| 42 | + default: '' | ||
| 43 | + } | ||
| 44 | + }, | ||
| 45 | + data() { | ||
| 46 | + return { | ||
| 47 | + fees: [], | ||
| 48 | + page: { | ||
| 49 | + current: 1, | ||
| 50 | + size: 10, | ||
| 51 | + total: 0 | ||
| 52 | + } | ||
| 53 | + } | ||
| 54 | + }, | ||
| 55 | + watch: { | ||
| 56 | + applyId: { | ||
| 57 | + immediate: true, | ||
| 58 | + handler() { | ||
| 59 | + if (this.applyId) { | ||
| 60 | + this.loadData() | ||
| 61 | + } | ||
| 62 | + } | ||
| 63 | + } | ||
| 64 | + }, | ||
| 65 | + methods: { | ||
| 66 | + async loadData() { | ||
| 67 | + try { | ||
| 68 | + const params = { | ||
| 69 | + page: this.page.current, | ||
| 70 | + row: this.page.size, | ||
| 71 | + applyId: this.applyId | ||
| 72 | + } | ||
| 73 | + const res = await getInvoiceApplyItemList(params) | ||
| 74 | + if (res.code === 0) { | ||
| 75 | + this.fees = res.data.map(item => ({ | ||
| 76 | + ...item, | ||
| 77 | + itemTypeName: item.itemType === '2002' ? this.$t('invoiceApplyDetailFee.feeType') : this.$t('invoiceApplyDetailFee.accountType') | ||
| 78 | + })) | ||
| 79 | + this.page.total = res.total | ||
| 80 | + } | ||
| 81 | + } catch (error) { | ||
| 82 | + this.$message.error(this.$t('invoiceApplyDetailFee.fetchError')) | ||
| 83 | + } | ||
| 84 | + }, | ||
| 85 | + handleSizeChange(val) { | ||
| 86 | + this.page.size = val | ||
| 87 | + this.loadData() | ||
| 88 | + }, | ||
| 89 | + handleCurrentChange(val) { | ||
| 90 | + this.page.current = val | ||
| 91 | + this.loadData() | ||
| 92 | + }, | ||
| 93 | + viewFeeDetail(fee) { | ||
| 94 | + this.$router.push({ path: '/fee/feeDetail', query: { detailId: fee.itemObjId }}) | ||
| 95 | + }, | ||
| 96 | + viewAcctDetail(fee) { | ||
| 97 | + this.$router.push({ path: '/owner/ownerDetail', query: { ownerId: fee.ownerId, currentTab: 'ownerDetailAccountReceipt' }}) | ||
| 98 | + } | ||
| 99 | + } | ||
| 100 | +} | ||
| 101 | +</script> | ||
| 102 | + | ||
| 103 | +<style scoped> | ||
| 104 | +.invoice-apply-detail-fee { | ||
| 105 | + margin-top: 20px; | ||
| 106 | +} | ||
| 107 | +</style> | ||
| 0 | \ No newline at end of file | 108 | \ No newline at end of file |
src/components/fee/searchOwnerInvoice.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <el-dialog :title="$t('searchOwnerInvoice.title')" :visible.sync="visible" width="80%" @close="handleClose"> | ||
| 3 | + <div> | ||
| 4 | + <el-row :gutter="20"> | ||
| 5 | + <el-col :span="9"> | ||
| 6 | + <el-input v-model="searchForm.roomName" :placeholder="$t('searchOwnerInvoice.placeholderRoom')" clearable | ||
| 7 | + @keyup.enter.native="handleSearch" /> | ||
| 8 | + </el-col> | ||
| 9 | + <el-col :span="9"> | ||
| 10 | + <el-input v-model="searchForm.ownerNameLike" :placeholder="$t('searchOwnerInvoice.placeholderOwner')" clearable | ||
| 11 | + @keyup.enter.native="handleSearch" /> | ||
| 12 | + </el-col> | ||
| 13 | + <el-col :span="6"> | ||
| 14 | + <el-button type="primary" @click="handleSearch"> | ||
| 15 | + {{ $t('searchOwnerInvoice.search') }} | ||
| 16 | + </el-button> | ||
| 17 | + </el-col> | ||
| 18 | + </el-row> | ||
| 19 | + | ||
| 20 | + <el-table v-loading="loading" :data="ownerInvoices" border style="width: 100%; margin-top: 20px"> | ||
| 21 | + <el-table-column prop="ownerName" :label="$t('searchOwnerInvoice.ownerName')" align="center" /> | ||
| 22 | + <el-table-column prop="invoiceType" :label="$t('searchOwnerInvoice.invoiceType')" align="center"> | ||
| 23 | + <template slot-scope="scope"> | ||
| 24 | + {{ scope.row.invoiceType === '1001' ? $t('searchOwnerInvoice.personal') : $t('searchOwnerInvoice.company') }} | ||
| 25 | + </template> | ||
| 26 | + </el-table-column> | ||
| 27 | + <el-table-column prop="invoiceName" :label="$t('searchOwnerInvoice.invoiceTitle')" align="center" /> | ||
| 28 | + <el-table-column prop="invoiceNum" :label="$t('searchOwnerInvoice.taxpayerId')" align="center" /> | ||
| 29 | + <el-table-column prop="invoiceAddress" :label="$t('searchOwnerInvoice.addressPhone')" align="center" /> | ||
| 30 | + <el-table-column :label="$t('searchOwnerInvoice.operation')" align="center"> | ||
| 31 | + <template slot-scope="scope"> | ||
| 32 | + <el-button type="primary" size="small" @click="handleSelect(scope.row)"> | ||
| 33 | + {{ $t('searchOwnerInvoice.select') }} | ||
| 34 | + </el-button> | ||
| 35 | + </template> | ||
| 36 | + </el-table-column> | ||
| 37 | + </el-table> | ||
| 38 | + | ||
| 39 | + <el-pagination :current-page="pagination.current" :page-sizes="[10, 20, 30, 50]" :page-size="pagination.size" | ||
| 40 | + layout="total, sizes, prev, pager, next" :total="pagination.total" @size-change="handleSizeChange" | ||
| 41 | + @current-change="handlePageChange" /> | ||
| 42 | + </div> | ||
| 43 | + </el-dialog> | ||
| 44 | +</template> | ||
| 45 | + | ||
| 46 | +<script> | ||
| 47 | +import { listOwnerInvoice } from '@/api/fee/ownerApplyInvoiceApi' | ||
| 48 | + | ||
| 49 | +export default { | ||
| 50 | + name: 'SearchOwnerInvoice', | ||
| 51 | + props: { | ||
| 52 | + visible: { | ||
| 53 | + type: Boolean, | ||
| 54 | + default: false | ||
| 55 | + } | ||
| 56 | + }, | ||
| 57 | + data() { | ||
| 58 | + return { | ||
| 59 | + loading: false, | ||
| 60 | + searchForm: { | ||
| 61 | + roomName: '', | ||
| 62 | + ownerNameLike: '' | ||
| 63 | + }, | ||
| 64 | + ownerInvoices: [], | ||
| 65 | + pagination: { | ||
| 66 | + current: 1, | ||
| 67 | + size: 10, | ||
| 68 | + total: 0 | ||
| 69 | + } | ||
| 70 | + } | ||
| 71 | + }, | ||
| 72 | + methods: { | ||
| 73 | + open() { | ||
| 74 | + this.visible = true | ||
| 75 | + this.loadData() | ||
| 76 | + }, | ||
| 77 | + handleClose() { | ||
| 78 | + this.$emit('update:visible', false) | ||
| 79 | + }, | ||
| 80 | + async loadData() { | ||
| 81 | + this.loading = true | ||
| 82 | + try { | ||
| 83 | + const params = { | ||
| 84 | + page: this.pagination.current, | ||
| 85 | + row: this.pagination.size, | ||
| 86 | + ownerNameLike: this.searchForm.ownerNameLike, | ||
| 87 | + roomName: this.searchForm.roomName | ||
| 88 | + } | ||
| 89 | + | ||
| 90 | + const res = await listOwnerInvoice(params) | ||
| 91 | + this.ownerInvoices = res.data | ||
| 92 | + this.pagination.total = res.records | ||
| 93 | + } catch (error) { | ||
| 94 | + console.error('Failed to load owner invoices:', error) | ||
| 95 | + this.$message.error(this.$t('common.loadFailed')) | ||
| 96 | + } finally { | ||
| 97 | + this.loading = false | ||
| 98 | + } | ||
| 99 | + }, | ||
| 100 | + handleSearch() { | ||
| 101 | + this.pagination.current = 1 | ||
| 102 | + this.loadData() | ||
| 103 | + }, | ||
| 104 | + handleSizeChange(size) { | ||
| 105 | + this.pagination.size = size | ||
| 106 | + this.loadData() | ||
| 107 | + }, | ||
| 108 | + handlePageChange(page) { | ||
| 109 | + this.pagination.current = page | ||
| 110 | + this.loadData() | ||
| 111 | + }, | ||
| 112 | + handleSelect(owner) { | ||
| 113 | + this.$emit('select', owner) | ||
| 114 | + this.handleClose() | ||
| 115 | + } | ||
| 116 | + } | ||
| 117 | +} | ||
| 118 | +</script> | ||
| 119 | + | ||
| 120 | +<style scoped> | ||
| 121 | +.el-row { | ||
| 122 | + margin-bottom: 20px; | ||
| 123 | +} | ||
| 124 | +</style> | ||
| 0 | \ No newline at end of file | 125 | \ No newline at end of file |
src/components/fee/uploadInvoicePhoto.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <el-dialog | ||
| 3 | + :title="$t('uploadInvoicePhoto.title')" | ||
| 4 | + :visible.sync="visible" | ||
| 5 | + width="50%" | ||
| 6 | + @close="closeDialog" | ||
| 7 | + > | ||
| 8 | + <el-form label-width="120px"> | ||
| 9 | + <el-form-item :label="$t('uploadInvoicePhoto.invoiceCode')"> | ||
| 10 | + <el-input | ||
| 11 | + v-model="form.invoiceCode" | ||
| 12 | + :placeholder="$t('uploadInvoicePhoto.codeRequired')" | ||
| 13 | + /> | ||
| 14 | + </el-form-item> | ||
| 15 | + <el-form-item :label="$t('uploadInvoicePhoto.invoice')"> | ||
| 16 | + <upload-image-url | ||
| 17 | + ref="uploadImage" | ||
| 18 | + @notifyUploadCoverImage="handleImageUpload" | ||
| 19 | + /> | ||
| 20 | + </el-form-item> | ||
| 21 | + </el-form> | ||
| 22 | + <div slot="footer"> | ||
| 23 | + <el-button @click="closeDialog">{{ $t('common.cancel') }}</el-button> | ||
| 24 | + <el-button | ||
| 25 | + type="primary" | ||
| 26 | + @click="saveUploadInvoicePhoto" | ||
| 27 | + >{{ $t('common.save') }}</el-button> | ||
| 28 | + </div> | ||
| 29 | + </el-dialog> | ||
| 30 | +</template> | ||
| 31 | + | ||
| 32 | +<script> | ||
| 33 | +import { uploadInvoicePhoto } from '@/api/fee/invoiceApplyApi' | ||
| 34 | +import { getCommunityId } from '@/api/community/communityApi' | ||
| 35 | +import UploadImageUrl from '@/components/upload/UploadImageUrl' | ||
| 36 | + | ||
| 37 | +export default { | ||
| 38 | + name: 'UploadInvoicePhoto', | ||
| 39 | + components: { | ||
| 40 | + UploadImageUrl | ||
| 41 | + }, | ||
| 42 | + data() { | ||
| 43 | + return { | ||
| 44 | + visible: false, | ||
| 45 | + form: { | ||
| 46 | + applyId: '', | ||
| 47 | + invoiceCode: '', | ||
| 48 | + photos: [] | ||
| 49 | + } | ||
| 50 | + } | ||
| 51 | + }, | ||
| 52 | + methods: { | ||
| 53 | + open(row) { | ||
| 54 | + this.form = { | ||
| 55 | + applyId: row.applyId, | ||
| 56 | + invoiceCode: '', | ||
| 57 | + photos: [] | ||
| 58 | + } | ||
| 59 | + this.$refs.uploadImage.clearImages() | ||
| 60 | + this.visible = true | ||
| 61 | + }, | ||
| 62 | + closeDialog() { | ||
| 63 | + this.visible = false | ||
| 64 | + }, | ||
| 65 | + handleImageUpload(photos) { | ||
| 66 | + this.form.photos = photos | ||
| 67 | + }, | ||
| 68 | + async saveUploadInvoicePhoto() { | ||
| 69 | + if (!this.form.invoiceCode) { | ||
| 70 | + this.$message.warning(this.$t('uploadInvoicePhoto.codeRequired')) | ||
| 71 | + return | ||
| 72 | + } | ||
| 73 | + if (this.form.photos.length === 0) { | ||
| 74 | + this.$message.warning(this.$t('uploadInvoicePhoto.photoRequired')) | ||
| 75 | + return | ||
| 76 | + } | ||
| 77 | + | ||
| 78 | + try { | ||
| 79 | + const params = { | ||
| 80 | + ...this.form, | ||
| 81 | + communityId: getCommunityId() | ||
| 82 | + } | ||
| 83 | + await uploadInvoicePhoto(params) | ||
| 84 | + this.$emit('success') | ||
| 85 | + this.$message.success(this.$t('common.saveSuccess')) | ||
| 86 | + this.closeDialog() | ||
| 87 | + } catch (error) { | ||
| 88 | + this.$message.error(error.message) | ||
| 89 | + } | ||
| 90 | + } | ||
| 91 | + } | ||
| 92 | +} | ||
| 93 | +</script> | ||
| 0 | \ No newline at end of file | 94 | \ No newline at end of file |
src/components/fee/wirteInvoiceEvent.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <el-dialog | ||
| 3 | + :title="$t('wirteInvoiceEvent.title')" | ||
| 4 | + :visible.sync="visible" | ||
| 5 | + width="50%" | ||
| 6 | + @close="closeDialog" | ||
| 7 | + > | ||
| 8 | + <el-form label-width="120px"> | ||
| 9 | + <el-form-item :label="$t('wirteInvoiceEvent.type')"> | ||
| 10 | + <el-select | ||
| 11 | + v-model="form.eventType" | ||
| 12 | + :placeholder="$t('wirteInvoiceEvent.typeRequired')" | ||
| 13 | + style="width: 100%" | ||
| 14 | + > | ||
| 15 | + <el-option | ||
| 16 | + :label="$t('wirteInvoiceEvent.receive')" | ||
| 17 | + value="4004" | ||
| 18 | + /> | ||
| 19 | + <el-option | ||
| 20 | + :label="$t('wirteInvoiceEvent.register')" | ||
| 21 | + value="5005" | ||
| 22 | + /> | ||
| 23 | + </el-select> | ||
| 24 | + </el-form-item> | ||
| 25 | + <el-form-item :label="$t('wirteInvoiceEvent.remark')"> | ||
| 26 | + <el-input | ||
| 27 | + v-model="form.remark" | ||
| 28 | + type="textarea" | ||
| 29 | + :rows="3" | ||
| 30 | + :placeholder="$t('wirteInvoiceEvent.remarkRequired')" | ||
| 31 | + /> | ||
| 32 | + </el-form-item> | ||
| 33 | + </el-form> | ||
| 34 | + <div slot="footer"> | ||
| 35 | + <el-button @click="closeDialog">{{ $t('common.cancel') }}</el-button> | ||
| 36 | + <el-button | ||
| 37 | + type="primary" | ||
| 38 | + @click="saveEvent" | ||
| 39 | + >{{ $t('common.save') }}</el-button> | ||
| 40 | + </div> | ||
| 41 | + </el-dialog> | ||
| 42 | +</template> | ||
| 43 | + | ||
| 44 | +<script> | ||
| 45 | +import { writeInvoiceEvent } from '@/api/fee/invoiceApplyApi' | ||
| 46 | +import { getCommunityId } from '@/api/community/communityApi' | ||
| 47 | + | ||
| 48 | +export default { | ||
| 49 | + name: 'WirteInvoiceEvent', | ||
| 50 | + data() { | ||
| 51 | + return { | ||
| 52 | + visible: false, | ||
| 53 | + form: { | ||
| 54 | + applyId: '', | ||
| 55 | + eventType: '', | ||
| 56 | + remark: '' | ||
| 57 | + } | ||
| 58 | + } | ||
| 59 | + }, | ||
| 60 | + methods: { | ||
| 61 | + open(row) { | ||
| 62 | + this.form = { | ||
| 63 | + applyId: row.applyId, | ||
| 64 | + eventType: '', | ||
| 65 | + remark: '' | ||
| 66 | + } | ||
| 67 | + this.visible = true | ||
| 68 | + }, | ||
| 69 | + closeDialog() { | ||
| 70 | + this.visible = false | ||
| 71 | + }, | ||
| 72 | + async saveEvent() { | ||
| 73 | + if (!this.form.eventType) { | ||
| 74 | + this.$message.warning(this.$t('wirteInvoiceEvent.typeRequired')) | ||
| 75 | + return | ||
| 76 | + } | ||
| 77 | + if (!this.form.remark) { | ||
| 78 | + this.$message.warning(this.$t('wirteInvoiceEvent.remarkRequired')) | ||
| 79 | + return | ||
| 80 | + } | ||
| 81 | + | ||
| 82 | + try { | ||
| 83 | + const params = { | ||
| 84 | + ...this.form, | ||
| 85 | + communityId: getCommunityId() | ||
| 86 | + } | ||
| 87 | + await writeInvoiceEvent(params) | ||
| 88 | + this.$emit('success') | ||
| 89 | + this.$message.success(this.$t('common.saveSuccess')) | ||
| 90 | + this.closeDialog() | ||
| 91 | + } catch (error) { | ||
| 92 | + this.$message.error(error.message) | ||
| 93 | + } | ||
| 94 | + } | ||
| 95 | + } | ||
| 96 | +} | ||
| 97 | +</script> | ||
| 0 | \ No newline at end of file | 98 | \ No newline at end of file |
src/i18n/index.js
| @@ -139,6 +139,10 @@ import { messages as ownerCommitteeManageMessages } from '../views/owner/ownerCo | @@ -139,6 +139,10 @@ import { messages as ownerCommitteeManageMessages } from '../views/owner/ownerCo | ||
| 139 | import { messages as addOwnerCommitteeMessages } from '../views/owner/addOwnerCommitteeLang' | 139 | import { messages as addOwnerCommitteeMessages } from '../views/owner/addOwnerCommitteeLang' |
| 140 | import { messages as editOwnerCommitteeMessages } from '../views/owner/editOwnerCommitteeLang' | 140 | import { messages as editOwnerCommitteeMessages } from '../views/owner/editOwnerCommitteeLang' |
| 141 | import { messages as ownerCommitteeDetailMessages } from '../views/owner/ownerCommitteeDetailLang' | 141 | import { messages as ownerCommitteeDetailMessages } from '../views/owner/ownerCommitteeDetailLang' |
| 142 | +import { messages as ownerInvoiceMessages } from '../views/fee/ownerInvoiceLang' | ||
| 143 | +import { messages as invoiceApplyMessages } from '../views/fee/invoiceApplyLang' | ||
| 144 | +import { messages as ownerApplyInvoiceMessages } from '../views/fee/ownerApplyInvoiceLang' | ||
| 145 | +import { messages as invoiceApplyDetailMessages } from '../views/fee/invoiceApplyDetailLang' | ||
| 142 | 146 | ||
| 143 | Vue.use(VueI18n) | 147 | Vue.use(VueI18n) |
| 144 | 148 | ||
| @@ -282,6 +286,10 @@ const messages = { | @@ -282,6 +286,10 @@ const messages = { | ||
| 282 | ...addOwnerCommitteeMessages.en, | 286 | ...addOwnerCommitteeMessages.en, |
| 283 | ...editOwnerCommitteeMessages.en, | 287 | ...editOwnerCommitteeMessages.en, |
| 284 | ...ownerCommitteeDetailMessages.en, | 288 | ...ownerCommitteeDetailMessages.en, |
| 289 | + ...ownerInvoiceMessages.en, | ||
| 290 | + ...invoiceApplyMessages.en, | ||
| 291 | + ...ownerApplyInvoiceMessages.en, | ||
| 292 | + ...invoiceApplyDetailMessages.en, | ||
| 285 | }, | 293 | }, |
| 286 | zh: { | 294 | zh: { |
| 287 | ...loginMessages.zh, | 295 | ...loginMessages.zh, |
| @@ -421,6 +429,10 @@ const messages = { | @@ -421,6 +429,10 @@ const messages = { | ||
| 421 | ...addOwnerCommitteeMessages.zh, | 429 | ...addOwnerCommitteeMessages.zh, |
| 422 | ...editOwnerCommitteeMessages.zh, | 430 | ...editOwnerCommitteeMessages.zh, |
| 423 | ...ownerCommitteeDetailMessages.zh, | 431 | ...ownerCommitteeDetailMessages.zh, |
| 432 | + ...ownerInvoiceMessages.zh, | ||
| 433 | + ...invoiceApplyMessages.zh, | ||
| 434 | + ...ownerApplyInvoiceMessages.zh, | ||
| 435 | + ...invoiceApplyDetailMessages.zh, | ||
| 424 | } | 436 | } |
| 425 | } | 437 | } |
| 426 | 438 |
src/router/index.js
| @@ -682,10 +682,35 @@ const routes = [ | @@ -682,10 +682,35 @@ const routes = [ | ||
| 682 | component: () => import('@/views/owner/editOwnerCommitteeList.vue') | 682 | component: () => import('@/views/owner/editOwnerCommitteeList.vue') |
| 683 | }, | 683 | }, |
| 684 | { | 684 | { |
| 685 | - path:'/views/owner/ownerCommitteeDetail', | ||
| 686 | - name:'/views/owner/ownerCommitteeDetail', | 685 | + path: '/views/owner/ownerCommitteeDetail', |
| 686 | + name: '/views/owner/ownerCommitteeDetail', | ||
| 687 | component: () => import('@/views/owner/ownerCommitteeDetailList.vue') | 687 | component: () => import('@/views/owner/ownerCommitteeDetailList.vue') |
| 688 | + }, | ||
| 689 | + { | ||
| 690 | + path: '/pages/fee/ownerInvoice', | ||
| 691 | + name: '/pages/fee/ownerInvoice', | ||
| 692 | + component: () => import('@/views/fee/ownerInvoiceList.vue') | ||
| 693 | + }, | ||
| 694 | + { | ||
| 695 | + path: '/views/fee/addOwnerInvoice', | ||
| 696 | + name: '/views/fee/addOwnerInvoice', | ||
| 697 | + component: () => import('@/views/fee/addOwnerInvoiceList.vue') | ||
| 698 | + }, | ||
| 699 | + { | ||
| 700 | + path:'/pages/fee/invoiceApply', | ||
| 701 | + name:'/pages/fee/invoiceApply', | ||
| 702 | + component: () => import('@/views/fee/invoiceApplyList.vue') | ||
| 688 | }, | 703 | }, |
| 704 | + { | ||
| 705 | + path:'/views/fee/ownerApplyInvoice', | ||
| 706 | + name:'/views/fee/ownerApplyInvoice', | ||
| 707 | + component: () => import('@/views/fee/ownerApplyInvoiceList.vue') | ||
| 708 | + }, | ||
| 709 | + { | ||
| 710 | + path:'/views/fee/invoiceApplyDetail', | ||
| 711 | + name:'/views/fee/invoiceApplyDetail', | ||
| 712 | + component: () => import('@/views/fee/invoiceApplyDetailList.vue') | ||
| 713 | + }, | ||
| 689 | // 其他子路由可以在这里添加 | 714 | // 其他子路由可以在这里添加 |
| 690 | ] | 715 | ] |
| 691 | }, | 716 | }, |
src/views/fee/addOwnerInvoiceList.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <div class="app-container"> | ||
| 3 | + <el-card shadow="never"> | ||
| 4 | + <div slot="header" class="clearfix"> | ||
| 5 | + <span>{{ $t('addOwnerInvoice.title') }}</span> | ||
| 6 | + <el-button class="float-right" type="text" @click="$router.go(-1)"> | ||
| 7 | + {{ $t('addOwnerInvoice.back') }} | ||
| 8 | + </el-button> | ||
| 9 | + </div> | ||
| 10 | + | ||
| 11 | + <el-form ref="form" :model="formData" :rules="rules" label-width="150px" label-position="right"> | ||
| 12 | + <el-form-item :label="$t('addOwnerInvoice.owner')" prop="ownerName"> | ||
| 13 | + <el-input v-model="formData.ownerName" :placeholder="$t('addOwnerInvoice.placeholder.owner')" disabled | ||
| 14 | + style="width: 70%" /> | ||
| 15 | + <el-button type="primary" style="margin-left: 10px" @click="openOwnerDialog"> | ||
| 16 | + {{ $t('addOwnerInvoice.selectOwner') }} | ||
| 17 | + </el-button> | ||
| 18 | + </el-form-item> | ||
| 19 | + | ||
| 20 | + <el-form-item :label="$t('addOwnerInvoice.invoiceType')" prop="invoiceType"> | ||
| 21 | + <el-select v-model="formData.invoiceType" :placeholder="$t('addOwnerInvoice.placeholder.invoiceType')" | ||
| 22 | + style="width: 100%"> | ||
| 23 | + <el-option v-for="item in invoiceTypes" :key="item.value" :label="item.label" :value="item.value" /> | ||
| 24 | + </el-select> | ||
| 25 | + </el-form-item> | ||
| 26 | + | ||
| 27 | + <el-form-item :label="$t('addOwnerInvoice.invoiceTitle')" prop="invoiceName"> | ||
| 28 | + <el-input v-model="formData.invoiceName" :placeholder="$t('addOwnerInvoice.placeholder.invoiceTitle')" | ||
| 29 | + style="width: 100%" /> | ||
| 30 | + </el-form-item> | ||
| 31 | + | ||
| 32 | + <el-form-item :label="$t('addOwnerInvoice.taxNumber')" prop="invoiceNum"> | ||
| 33 | + <el-input v-model="formData.invoiceNum" :placeholder="$t('addOwnerInvoice.placeholder.taxNumber')" | ||
| 34 | + style="width: 100%" /> | ||
| 35 | + </el-form-item> | ||
| 36 | + | ||
| 37 | + <el-form-item :label="$t('addOwnerInvoice.address')" prop="invoiceAddress"> | ||
| 38 | + <el-input v-model="formData.invoiceAddress" :placeholder="$t('addOwnerInvoice.placeholder.address')" | ||
| 39 | + style="width: 100%" /> | ||
| 40 | + </el-form-item> | ||
| 41 | + | ||
| 42 | + <el-form-item :label="$t('addOwnerInvoice.phone')" prop="invoiceLink"> | ||
| 43 | + <el-input v-model="formData.invoiceLink" :placeholder="$t('addOwnerInvoice.placeholder.phone')" | ||
| 44 | + style="width: 100%" /> | ||
| 45 | + </el-form-item> | ||
| 46 | + | ||
| 47 | + <el-form-item :label="$t('addOwnerInvoice.bankAccount')" prop="invoiceAccount"> | ||
| 48 | + <el-input v-model="formData.invoiceAccount" :placeholder="$t('addOwnerInvoice.placeholder.bankAccount')" | ||
| 49 | + style="width: 100%" /> | ||
| 50 | + </el-form-item> | ||
| 51 | + | ||
| 52 | + <el-form-item :label="$t('addOwnerInvoice.remarks')"> | ||
| 53 | + <el-input v-model="formData.remark" type="textarea" :rows="3" | ||
| 54 | + :placeholder="$t('addOwnerInvoice.placeholder.remarks')" style="width: 100%" /> | ||
| 55 | + </el-form-item> | ||
| 56 | + | ||
| 57 | + <el-form-item> | ||
| 58 | + <el-button type="primary" @click="submitForm"> | ||
| 59 | + {{ $t('addOwnerInvoice.save') }} | ||
| 60 | + </el-button> | ||
| 61 | + </el-form-item> | ||
| 62 | + </el-form> | ||
| 63 | + </el-card> | ||
| 64 | + | ||
| 65 | + <search-owner ref="searchOwner" :visible.sync="showOwnerDialog" @chooseOwner="handleOwnerSelect" /> | ||
| 66 | + </div> | ||
| 67 | +</template> | ||
| 68 | + | ||
| 69 | +<script> | ||
| 70 | +import { saveOwnerInvoice } from '@/api/fee/addOwnerInvoiceApi' | ||
| 71 | +import SearchOwner from '@/components/owner/SearchOwner' | ||
| 72 | + | ||
| 73 | +export default { | ||
| 74 | + name: 'AddOwnerInvoice', | ||
| 75 | + components: { SearchOwner }, | ||
| 76 | + data() { | ||
| 77 | + return { | ||
| 78 | + showOwnerDialog: false, | ||
| 79 | + formData: { | ||
| 80 | + oiId: '', | ||
| 81 | + ownerId: '', | ||
| 82 | + ownerName: '', | ||
| 83 | + invoiceType: '', | ||
| 84 | + invoiceName: '', | ||
| 85 | + invoiceNum: '', | ||
| 86 | + invoiceAddress: '', | ||
| 87 | + invoiceLink: '', | ||
| 88 | + invoiceAccount: '', | ||
| 89 | + remark: '' | ||
| 90 | + }, | ||
| 91 | + invoiceTypes: [ | ||
| 92 | + { value: '1001', label: this.$t('addOwnerInvoice.personal') }, | ||
| 93 | + { value: '2002', label: this.$t('addOwnerInvoice.enterprise') } | ||
| 94 | + ], | ||
| 95 | + rules: { | ||
| 96 | + ownerName: [ | ||
| 97 | + { required: true, message: this.$t('addOwnerInvoice.validation.ownerRequired'), trigger: 'blur' } | ||
| 98 | + ], | ||
| 99 | + invoiceType: [ | ||
| 100 | + { required: true, message: this.$t('addOwnerInvoice.validation.typeRequired'), trigger: 'change' } | ||
| 101 | + ], | ||
| 102 | + invoiceName: [ | ||
| 103 | + { required: true, message: this.$t('addOwnerInvoice.validation.titleRequired'), trigger: 'blur' } | ||
| 104 | + ], | ||
| 105 | + invoiceNum: [ | ||
| 106 | + { required: true, message: this.$t('addOwnerInvoice.validation.taxNumberRequired'), trigger: 'blur' } | ||
| 107 | + ], | ||
| 108 | + invoiceAddress: [ | ||
| 109 | + { required: true, message: this.$t('addOwnerInvoice.validation.addressRequired'), trigger: 'blur' } | ||
| 110 | + ], | ||
| 111 | + invoiceLink: [ | ||
| 112 | + { required: true, message: this.$t('addOwnerInvoice.validation.phoneRequired'), trigger: 'blur' } | ||
| 113 | + ], | ||
| 114 | + invoiceAccount: [ | ||
| 115 | + { required: true, message: this.$t('addOwnerInvoice.validation.bankAccountRequired'), trigger: 'blur' } | ||
| 116 | + ] | ||
| 117 | + } | ||
| 118 | + } | ||
| 119 | + }, | ||
| 120 | + methods: { | ||
| 121 | + openOwnerDialog() { | ||
| 122 | + this.$refs.searchOwner.open() | ||
| 123 | + }, | ||
| 124 | + handleOwnerSelect(owner) { | ||
| 125 | + this.formData.ownerId = owner.ownerId | ||
| 126 | + this.formData.ownerName = owner.name | ||
| 127 | + }, | ||
| 128 | + submitForm() { | ||
| 129 | + this.$refs.form.validate(async valid => { | ||
| 130 | + if (valid) { | ||
| 131 | + try { | ||
| 132 | + const payload = { | ||
| 133 | + ...this.formData, | ||
| 134 | + communityId: this.getCommunityId() | ||
| 135 | + } | ||
| 136 | + | ||
| 137 | + await saveOwnerInvoice(payload) | ||
| 138 | + this.$message.success(this.$t('common.saveSuccess')) | ||
| 139 | + this.$router.go(-1) | ||
| 140 | + } catch (error) { | ||
| 141 | + console.error('保存失败:', error) | ||
| 142 | + this.$message.error(error.message || this.$t('common.saveFailed')) | ||
| 143 | + } | ||
| 144 | + } | ||
| 145 | + }) | ||
| 146 | + } | ||
| 147 | + } | ||
| 148 | +} | ||
| 149 | +</script> | ||
| 150 | + | ||
| 151 | +<style lang="scss" scoped> | ||
| 152 | +.app-container { | ||
| 153 | + padding: 20px; | ||
| 154 | +} | ||
| 155 | + | ||
| 156 | +.float-right { | ||
| 157 | + float: right; | ||
| 158 | +} | ||
| 159 | + | ||
| 160 | +.el-form { | ||
| 161 | + max-width: 800px; | ||
| 162 | + margin: 0 auto; | ||
| 163 | +} | ||
| 164 | + | ||
| 165 | +.el-select, | ||
| 166 | +.el-input { | ||
| 167 | + width: 100%; | ||
| 168 | +} | ||
| 169 | +</style> | ||
| 0 | \ No newline at end of file | 170 | \ No newline at end of file |
src/views/fee/invoiceApplyDetailLang.js
0 → 100644
| 1 | +export const messages = { | ||
| 2 | + en: { | ||
| 3 | + invoiceApplyDetail: { | ||
| 4 | + title: 'Invoice Details', | ||
| 5 | + back: 'Back', | ||
| 6 | + applyId: 'Apply ID:', | ||
| 7 | + invoiceType: 'Invoice Type:', | ||
| 8 | + personal: 'Personal', | ||
| 9 | + company: 'Company', | ||
| 10 | + ownerName: 'Owner Name:', | ||
| 11 | + createUserName: 'Applicant:', | ||
| 12 | + invoiceName: 'Invoice Title:', | ||
| 13 | + invoiceNum: 'Taxpayer ID:', | ||
| 14 | + invoiceAddress: 'Address/Phone:', | ||
| 15 | + invoiceAmount: 'Apply Amount:', | ||
| 16 | + stateName: 'Status:', | ||
| 17 | + createTime: 'Apply Time:', | ||
| 18 | + invoiceCode: 'Invoice Code:', | ||
| 19 | + feeTab: 'Fee Details', | ||
| 20 | + eventTab: 'Audit Records', | ||
| 21 | + imageTab: 'View Invoice', | ||
| 22 | + notUploaded: 'Not uploaded', | ||
| 23 | + noInvoice: 'No Invoice', | ||
| 24 | + downloadInvoice: 'Download Invoice', | ||
| 25 | + fetchError: 'Failed to fetch invoice details' | ||
| 26 | + }, | ||
| 27 | + invoiceApplyDetailFee: { | ||
| 28 | + type: 'Type', | ||
| 29 | + name: 'Name', | ||
| 30 | + amount: 'Amount', | ||
| 31 | + payTime: 'Pay Time', | ||
| 32 | + remark: 'Remark', | ||
| 33 | + paymentId: 'Payment ID', | ||
| 34 | + feeType: 'Fee', | ||
| 35 | + accountType: 'Account', | ||
| 36 | + fetchError: 'Failed to fetch fee details' | ||
| 37 | + }, | ||
| 38 | + invoiceApplyDetailEvent: { | ||
| 39 | + type: 'Type', | ||
| 40 | + operator: 'Operator', | ||
| 41 | + remark: 'Remark', | ||
| 42 | + time: 'Time', | ||
| 43 | + fetchError: 'Failed to fetch audit records' | ||
| 44 | + }, | ||
| 45 | + }, | ||
| 46 | + zh: { | ||
| 47 | + invoiceApplyDetail: { | ||
| 48 | + title: '发票详情', | ||
| 49 | + back: '返回', | ||
| 50 | + applyId: '编号:', | ||
| 51 | + invoiceType: '发票类型:', | ||
| 52 | + personal: '个人', | ||
| 53 | + company: '企业', | ||
| 54 | + ownerName: '业主名称:', | ||
| 55 | + createUserName: '申请人:', | ||
| 56 | + invoiceName: '发票名头:', | ||
| 57 | + invoiceNum: '纳税人识别号:', | ||
| 58 | + invoiceAddress: '地址、电话:', | ||
| 59 | + invoiceAmount: '申请金额:', | ||
| 60 | + stateName: '审核状态:', | ||
| 61 | + createTime: '申请时间:', | ||
| 62 | + invoiceCode: '发票编号:', | ||
| 63 | + feeTab: '开票明细', | ||
| 64 | + eventTab: '审核记录', | ||
| 65 | + imageTab: '查看发票', | ||
| 66 | + notUploaded: '未上传', | ||
| 67 | + noInvoice: '没有发票', | ||
| 68 | + downloadInvoice: '下载发票', | ||
| 69 | + fetchError: '获取发票详情失败' | ||
| 70 | + }, | ||
| 71 | + invoiceApplyDetailFee: { | ||
| 72 | + type: '类型', | ||
| 73 | + name: '名称', | ||
| 74 | + amount: '金额', | ||
| 75 | + payTime: '缴费时间', | ||
| 76 | + remark: '备注', | ||
| 77 | + paymentId: '缴费ID', | ||
| 78 | + feeType: '费用', | ||
| 79 | + accountType: '账户', | ||
| 80 | + fetchError: '获取费用明细失败' | ||
| 81 | + }, | ||
| 82 | + invoiceApplyDetailEvent: { | ||
| 83 | + type: '类型', | ||
| 84 | + operator: '操作人', | ||
| 85 | + remark: '说明', | ||
| 86 | + time: '时间', | ||
| 87 | + fetchError: '获取审核记录失败' | ||
| 88 | + }, | ||
| 89 | + } | ||
| 90 | +} | ||
| 0 | \ No newline at end of file | 91 | \ No newline at end of file |
src/views/fee/invoiceApplyDetailList.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <div class="invoice-apply-detail"> | ||
| 3 | + <el-card class="box-card"> | ||
| 4 | + <div class="card-header"> | ||
| 5 | + <div class="text-title">{{ $t('invoiceApplyDetail.title') }}</div> | ||
| 6 | + <div> | ||
| 7 | + <el-button type="primary" size="small" style="margin-left:10px" @click="goBack"> | ||
| 8 | + {{ $t('invoiceApplyDetail.back') }} | ||
| 9 | + </el-button> | ||
| 10 | + </div> | ||
| 11 | + </div> | ||
| 12 | + | ||
| 13 | + <!-- 业主信息 --> | ||
| 14 | + <div class="margin-top"> | ||
| 15 | + <el-row :gutter="20"> | ||
| 16 | + <el-col :span="24"> | ||
| 17 | + <el-row :gutter="20"> | ||
| 18 | + <el-col :span="6"> | ||
| 19 | + <div class="form-group"> | ||
| 20 | + <label class="col-form-label">{{ $t('invoiceApplyDetail.applyId') }}</label> | ||
| 21 | + <label>{{ invoiceApplyDetailInfo.applyId }}</label> | ||
| 22 | + </div> | ||
| 23 | + </el-col> | ||
| 24 | + <el-col :span="6"> | ||
| 25 | + <div class="form-group"> | ||
| 26 | + <label class="col-form-label">{{ $t('invoiceApplyDetail.invoiceType') }}</label> | ||
| 27 | + <label>{{ invoiceApplyDetailInfo.invoiceType === '1001' ? $t('invoiceApplyDetail.personal') : | ||
| 28 | + $t('invoiceApplyDetail.company') }}</label> | ||
| 29 | + </div> | ||
| 30 | + </el-col> | ||
| 31 | + <el-col :span="6"> | ||
| 32 | + <div class="form-group"> | ||
| 33 | + <label class="col-form-label">{{ $t('invoiceApplyDetail.ownerName') }}</label> | ||
| 34 | + <label>{{ invoiceApplyDetailInfo.ownerName }}</label> | ||
| 35 | + </div> | ||
| 36 | + </el-col> | ||
| 37 | + <el-col :span="6"> | ||
| 38 | + <div class="form-group"> | ||
| 39 | + <label class="col-form-label">{{ $t('invoiceApplyDetail.createUserName') }}</label> | ||
| 40 | + <label>{{ invoiceApplyDetailInfo.createUserName }}({{ invoiceApplyDetailInfo.applyTel }})</label> | ||
| 41 | + </div> | ||
| 42 | + </el-col> | ||
| 43 | + </el-row> | ||
| 44 | + <el-row :gutter="20"> | ||
| 45 | + <el-col :span="6"> | ||
| 46 | + <div class="form-group"> | ||
| 47 | + <label class="col-form-label">{{ $t('invoiceApplyDetail.invoiceName') }}</label> | ||
| 48 | + <label>{{ invoiceApplyDetailInfo.invoiceName }}</label> | ||
| 49 | + </div> | ||
| 50 | + </el-col> | ||
| 51 | + <el-col :span="6"> | ||
| 52 | + <div class="form-group"> | ||
| 53 | + <label class="col-form-label">{{ $t('invoiceApplyDetail.invoiceNum') }}</label> | ||
| 54 | + <label>{{ invoiceApplyDetailInfo.invoiceNum }}</label> | ||
| 55 | + </div> | ||
| 56 | + </el-col> | ||
| 57 | + <el-col :span="6"> | ||
| 58 | + <div class="form-group"> | ||
| 59 | + <label class="col-form-label">{{ $t('invoiceApplyDetail.invoiceAddress') }}</label> | ||
| 60 | + <label>{{ invoiceApplyDetailInfo.invoiceAddress }}</label> | ||
| 61 | + </div> | ||
| 62 | + </el-col> | ||
| 63 | + <el-col :span="6"> | ||
| 64 | + <div class="form-group"> | ||
| 65 | + <label class="col-form-label">{{ $t('invoiceApplyDetail.invoiceAmount') }}</label> | ||
| 66 | + <label>{{ invoiceApplyDetailInfo.invoiceAmount }}</label> | ||
| 67 | + </div> | ||
| 68 | + </el-col> | ||
| 69 | + </el-row> | ||
| 70 | + <el-row :gutter="20"> | ||
| 71 | + <el-col :span="6"> | ||
| 72 | + <div class="form-group"> | ||
| 73 | + <label class="col-form-label">{{ $t('invoiceApplyDetail.stateName') }}</label> | ||
| 74 | + <label>{{ invoiceApplyDetailInfo.stateName }}</label> | ||
| 75 | + </div> | ||
| 76 | + </el-col> | ||
| 77 | + <el-col :span="6"> | ||
| 78 | + <div class="form-group"> | ||
| 79 | + <label class="col-form-label">{{ $t('invoiceApplyDetail.createTime') }}</label> | ||
| 80 | + <label>{{ invoiceApplyDetailInfo.createTime }}</label> | ||
| 81 | + </div> | ||
| 82 | + </el-col> | ||
| 83 | + <el-col :span="6"> | ||
| 84 | + <div class="form-group"> | ||
| 85 | + <label class="col-form-label">{{ $t('invoiceApplyDetail.invoiceCode') }}</label> | ||
| 86 | + <label>{{ invoiceApplyDetailInfo.invoiceCode || $t('invoiceApplyDetail.notUploaded') }}</label> | ||
| 87 | + </div> | ||
| 88 | + </el-col> | ||
| 89 | + </el-row> | ||
| 90 | + </el-col> | ||
| 91 | + </el-row> | ||
| 92 | + </div> | ||
| 93 | + <el-divider></el-divider> | ||
| 94 | + | ||
| 95 | + <el-tabs v-model="invoiceApplyDetailInfo._currentTab" @tab-click="handleTabClick"> | ||
| 96 | + <el-tab-pane :label="$t('invoiceApplyDetail.feeTab')" name="invoiceApplyDetailFee"> | ||
| 97 | + <invoice-apply-detail-fee v-if="invoiceApplyDetailInfo._currentTab === 'invoiceApplyDetailFee'" | ||
| 98 | + :apply-id="invoiceApplyDetailInfo.applyId" | ||
| 99 | + :owner-id="invoiceApplyDetailInfo.ownerId"></invoice-apply-detail-fee> | ||
| 100 | + </el-tab-pane> | ||
| 101 | + <el-tab-pane :label="$t('invoiceApplyDetail.eventTab')" name="invoiceApplyDetailEvent"> | ||
| 102 | + <invoice-apply-detail-event v-if="invoiceApplyDetailInfo._currentTab === 'invoiceApplyDetailEvent'" | ||
| 103 | + :apply-id="invoiceApplyDetailInfo.applyId"></invoice-apply-detail-event> | ||
| 104 | + </el-tab-pane> | ||
| 105 | + <el-tab-pane :label="$t('invoiceApplyDetail.imageTab')" name="invoiceApplyDetailJpg"> | ||
| 106 | + <div v-if="invoiceApplyDetailInfo.urls && invoiceApplyDetailInfo.urls.length > 0"> | ||
| 107 | + <div v-for="(item, index) in invoiceApplyDetailInfo.urls" :key="index"> | ||
| 108 | + <a target="_blank" :href="item">{{ $t('invoiceApplyDetail.downloadInvoice') }}</a> | ||
| 109 | + </div> | ||
| 110 | + </div> | ||
| 111 | + <div class="padding" v-else> | ||
| 112 | + {{ $t('invoiceApplyDetail.noInvoice') }} | ||
| 113 | + </div> | ||
| 114 | + </el-tab-pane> | ||
| 115 | + </el-tabs> | ||
| 116 | + </el-card> | ||
| 117 | + </div> | ||
| 118 | +</template> | ||
| 119 | + | ||
| 120 | +<script> | ||
| 121 | +import { getInvoiceApplyDetail } from '@/api/fee/invoiceApplyDetailApi' | ||
| 122 | +import InvoiceApplyDetailFee from '@/components/fee/invoiceApplyDetailFee' | ||
| 123 | +import InvoiceApplyDetailEvent from '@/components/fee/invoiceApplyDetailEvent' | ||
| 124 | + | ||
| 125 | +export default { | ||
| 126 | + name: 'InvoiceApplyDetailList', | ||
| 127 | + components: { | ||
| 128 | + InvoiceApplyDetailFee, | ||
| 129 | + InvoiceApplyDetailEvent | ||
| 130 | + }, | ||
| 131 | + data() { | ||
| 132 | + return { | ||
| 133 | + invoiceApplyDetailInfo: { | ||
| 134 | + applyId: '', | ||
| 135 | + invoiceType: '', | ||
| 136 | + ownerName: '', | ||
| 137 | + createUserName: '', | ||
| 138 | + invoiceName: '', | ||
| 139 | + invoiceNum: '', | ||
| 140 | + invoiceAddress: '', | ||
| 141 | + invoiceAmount: '', | ||
| 142 | + stateName: '', | ||
| 143 | + createTime: '', | ||
| 144 | + invoiceCode: '', | ||
| 145 | + urls: [], | ||
| 146 | + _currentTab: 'invoiceApplyDetailFee' | ||
| 147 | + } | ||
| 148 | + } | ||
| 149 | + }, | ||
| 150 | + created() { | ||
| 151 | + this.invoiceApplyDetailInfo.applyId = this.$route.query.applyId | ||
| 152 | + if (this.invoiceApplyDetailInfo.applyId) { | ||
| 153 | + this.loadInvoiceApplyInfo() | ||
| 154 | + } | ||
| 155 | + }, | ||
| 156 | + methods: { | ||
| 157 | + async loadInvoiceApplyInfo() { | ||
| 158 | + try { | ||
| 159 | + const params = { | ||
| 160 | + page: 1, | ||
| 161 | + row: 1, | ||
| 162 | + applyId: this.invoiceApplyDetailInfo.applyId | ||
| 163 | + } | ||
| 164 | + const res = await getInvoiceApplyDetail(params) | ||
| 165 | + if (res.code === 0 && res.data && res.data.length > 0) { | ||
| 166 | + Object.assign(this.invoiceApplyDetailInfo, res.data[0]) | ||
| 167 | + } | ||
| 168 | + } catch (error) { | ||
| 169 | + this.$message.error(this.$t('invoiceApplyDetail.fetchError')) | ||
| 170 | + } | ||
| 171 | + }, | ||
| 172 | + handleTabClick(tab) { | ||
| 173 | + this.invoiceApplyDetailInfo._currentTab = tab.name | ||
| 174 | + }, | ||
| 175 | + goBack() { | ||
| 176 | + this.$router.go(-1) | ||
| 177 | + } | ||
| 178 | + } | ||
| 179 | +} | ||
| 180 | +</script> | ||
| 181 | + | ||
| 182 | +<style scoped> | ||
| 183 | +.invoice-apply-detail { | ||
| 184 | + padding: 20px; | ||
| 185 | +} | ||
| 186 | + | ||
| 187 | +.card-header { | ||
| 188 | + display: flex; | ||
| 189 | + justify-content: space-between; | ||
| 190 | + align-items: center; | ||
| 191 | +} | ||
| 192 | + | ||
| 193 | +.text-title { | ||
| 194 | + font-size: 18px; | ||
| 195 | + font-weight: bold; | ||
| 196 | +} | ||
| 197 | + | ||
| 198 | +.margin-top { | ||
| 199 | + margin-top: 20px; | ||
| 200 | +} | ||
| 201 | + | ||
| 202 | +.padding { | ||
| 203 | + padding: 20px; | ||
| 204 | +} | ||
| 205 | + | ||
| 206 | +.form-group { | ||
| 207 | + margin-bottom: 15px; | ||
| 208 | +} | ||
| 209 | + | ||
| 210 | +.col-form-label { | ||
| 211 | + margin-right: 10px; | ||
| 212 | +}</style> | ||
| 0 | \ No newline at end of file | 213 | \ No newline at end of file |
src/views/fee/invoiceApplyLang.js
0 → 100644
| 1 | +export const messages = { | ||
| 2 | + en: { | ||
| 3 | + invoiceApply: { | ||
| 4 | + searchTitle: 'Search Conditions', | ||
| 5 | + title: 'Invoice Application', | ||
| 6 | + apply: 'Apply', | ||
| 7 | + table: { | ||
| 8 | + id: 'ID', | ||
| 9 | + invoiceType: 'Invoice Type', | ||
| 10 | + ownerName: 'Owner Name', | ||
| 11 | + applicant: 'Applicant', | ||
| 12 | + invoiceName: 'Invoice Title', | ||
| 13 | + taxNumber: 'Taxpayer ID', | ||
| 14 | + addressPhone: 'Address & Phone', | ||
| 15 | + amount: 'Amount', | ||
| 16 | + invoiceCode: 'Invoice Code', | ||
| 17 | + status: 'Status', | ||
| 18 | + applyTime: 'Apply Time' | ||
| 19 | + }, | ||
| 20 | + states: { | ||
| 21 | + all: 'All', | ||
| 22 | + pendingReview: 'Pending Review', | ||
| 23 | + pendingUpload: 'Pending Upload', | ||
| 24 | + reviewFailed: 'Review Failed', | ||
| 25 | + pendingReceive: 'Pending Receive', | ||
| 26 | + received: 'Received' | ||
| 27 | + }, | ||
| 28 | + personal: 'Personal', | ||
| 29 | + company: 'Company', | ||
| 30 | + notUploaded: 'Not Uploaded', | ||
| 31 | + openInvoice: 'Open Invoice', | ||
| 32 | + uploadInvoice: 'Upload Invoice', | ||
| 33 | + reUpload: 'Re-upload', | ||
| 34 | + verify: 'Verify', | ||
| 35 | + register: 'Register', | ||
| 36 | + auditSuccess: 'Audit successful', | ||
| 37 | + invoiceCodePlaceholder: 'Please enter invoice number', | ||
| 38 | + invoiceTypePlaceholder: 'Please select invoice type', | ||
| 39 | + ownerNamePlaceholder: 'Please enter owner name', | ||
| 40 | + applicantPlaceholder: 'Please enter applicant', | ||
| 41 | + phonePlaceholder: 'Please enter applicant phone' | ||
| 42 | + }, | ||
| 43 | + deleteInvoiceApply: { | ||
| 44 | + title: 'Confirm Operation', | ||
| 45 | + confirmMessage: 'Confirm to delete this invoice application?' | ||
| 46 | + }, | ||
| 47 | + uploadInvoicePhoto: { | ||
| 48 | + title: 'Upload Invoice', | ||
| 49 | + invoiceCode: 'Invoice Code', | ||
| 50 | + invoice: 'Invoice', | ||
| 51 | + codeRequired: 'Required, please enter invoice code', | ||
| 52 | + photoRequired: 'Please select invoice photo' | ||
| 53 | + }, | ||
| 54 | + wirteInvoiceEvent: { | ||
| 55 | + title: 'Register/Verify', | ||
| 56 | + type: 'Type', | ||
| 57 | + remark: 'Remark', | ||
| 58 | + typeRequired: 'Required, please select type', | ||
| 59 | + remarkRequired: 'Required, please enter remark', | ||
| 60 | + receive: 'Receive', | ||
| 61 | + register: 'Register' | ||
| 62 | + }, | ||
| 63 | + audit: { | ||
| 64 | + title: 'Audit Information', | ||
| 65 | + status: 'Audit Status', | ||
| 66 | + reason: 'Reason', | ||
| 67 | + statusRequired: 'Please select audit status', | ||
| 68 | + reasonRequired: 'Required, please enter reason', | ||
| 69 | + approve: 'Approve', | ||
| 70 | + reject: 'Reject' | ||
| 71 | + }, | ||
| 72 | + uploadImage: { | ||
| 73 | + sizeLimit: 'Image size cannot exceed 2MB' | ||
| 74 | + } | ||
| 75 | + }, | ||
| 76 | + zh: { | ||
| 77 | + invoiceApply: { | ||
| 78 | + searchTitle: '查询条件', | ||
| 79 | + title: '申请发票', | ||
| 80 | + apply: '申请', | ||
| 81 | + table: { | ||
| 82 | + id: '编号', | ||
| 83 | + invoiceType: '发票类型', | ||
| 84 | + ownerName: '业主名称', | ||
| 85 | + applicant: '申请人', | ||
| 86 | + invoiceName: '发票名头', | ||
| 87 | + taxNumber: '纳税人识别号', | ||
| 88 | + addressPhone: '地址、电话', | ||
| 89 | + amount: '申请金额', | ||
| 90 | + invoiceCode: '发票号', | ||
| 91 | + status: '审核状态', | ||
| 92 | + applyTime: '申请时间' | ||
| 93 | + }, | ||
| 94 | + states: { | ||
| 95 | + all: '全部', | ||
| 96 | + pendingReview: '待审核', | ||
| 97 | + pendingUpload: '待上传', | ||
| 98 | + reviewFailed: '审核失败', | ||
| 99 | + pendingReceive: '带领用', | ||
| 100 | + received: '已领用' | ||
| 101 | + }, | ||
| 102 | + personal: '个人', | ||
| 103 | + company: '企业', | ||
| 104 | + notUploaded: '未上传', | ||
| 105 | + openInvoice: '开票', | ||
| 106 | + uploadInvoice: '上传发票', | ||
| 107 | + reUpload: '重新上传', | ||
| 108 | + verify: '核销', | ||
| 109 | + register: '登记', | ||
| 110 | + auditSuccess: '审核成功', | ||
| 111 | + invoiceCodePlaceholder: '请填写发票号', | ||
| 112 | + invoiceTypePlaceholder: '请选择发票类型', | ||
| 113 | + ownerNamePlaceholder: '请填写业主名称', | ||
| 114 | + applicantPlaceholder: '请填写申请人', | ||
| 115 | + phonePlaceholder: '请填写申请人电话' | ||
| 116 | + }, | ||
| 117 | + deleteInvoiceApply: { | ||
| 118 | + title: '请确认您的操作', | ||
| 119 | + confirmMessage: '确定删除申请发票' | ||
| 120 | + }, | ||
| 121 | + uploadInvoicePhoto: { | ||
| 122 | + title: '上传发票', | ||
| 123 | + invoiceCode: '发票编号', | ||
| 124 | + invoice: '发票', | ||
| 125 | + codeRequired: '必填,请填写发票编号', | ||
| 126 | + photoRequired: '请选择发票' | ||
| 127 | + }, | ||
| 128 | + wirteInvoiceEvent: { | ||
| 129 | + title: '登记核销', | ||
| 130 | + type: '类型', | ||
| 131 | + remark: '说明', | ||
| 132 | + typeRequired: '必填,请选择类型', | ||
| 133 | + remarkRequired: '必填,请填写说明', | ||
| 134 | + receive: '领用', | ||
| 135 | + register: '登记' | ||
| 136 | + }, | ||
| 137 | + audit: { | ||
| 138 | + title: '审核信息', | ||
| 139 | + status: '审核状态', | ||
| 140 | + reason: '原因', | ||
| 141 | + statusRequired: '请审核', | ||
| 142 | + reasonRequired: '必填,请填写原因', | ||
| 143 | + approve: '同意', | ||
| 144 | + reject: '拒绝' | ||
| 145 | + }, | ||
| 146 | + uploadImage: { | ||
| 147 | + sizeLimit: '图片大小不能超过 2MB' | ||
| 148 | + } | ||
| 149 | + } | ||
| 150 | +} | ||
| 0 | \ No newline at end of file | 151 | \ No newline at end of file |
src/views/fee/invoiceApplyList.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <div> | ||
| 3 | + <el-row :gutter="20"> | ||
| 4 | + <el-col :span="4"> | ||
| 5 | + <el-card class="border-radius"> | ||
| 6 | + <div class="treeview attendance-staff"> | ||
| 7 | + <ul class="list-group text-center border-radius"> | ||
| 8 | + <li v-for="(item, index) in states" :key="index" @click="swatchState(item)" :class="{ | ||
| 9 | + 'vc-node-selected': conditions.state === item.state | ||
| 10 | + }" class="list-group-item node-orgTree"> | ||
| 11 | + {{ $t(`invoiceApply.states.${item.stateName}`) }} | ||
| 12 | + </li> | ||
| 13 | + </ul> | ||
| 14 | + </div> | ||
| 15 | + </el-card> | ||
| 16 | + </el-col> | ||
| 17 | + <el-col :span="20"> | ||
| 18 | + <el-row> | ||
| 19 | + <el-col :span="24"> | ||
| 20 | + <el-card> | ||
| 21 | + <div slot="header" class="text-left"> | ||
| 22 | + <span>{{ $t('invoiceApply.searchTitle') }}</span> | ||
| 23 | + </div> | ||
| 24 | + <el-row :gutter="20"> | ||
| 25 | + <el-col :span="4"> | ||
| 26 | + <el-input v-model="conditions.invoiceCode" :placeholder="$t('invoiceApply.invoiceCodePlaceholder')" /> | ||
| 27 | + </el-col> | ||
| 28 | + <el-col :span="4"> | ||
| 29 | + <el-select v-model="conditions.invoiceType" :placeholder="$t('invoiceApply.invoiceTypePlaceholder')"> | ||
| 30 | + <el-option label="请选择发票类型" value="" /> | ||
| 31 | + <el-option label="个人" value="1001" /> | ||
| 32 | + <el-option label="企业" value="2002" /> | ||
| 33 | + </el-select> | ||
| 34 | + </el-col> | ||
| 35 | + <el-col :span="4"> | ||
| 36 | + <el-input v-model="conditions.ownerName" :placeholder="$t('invoiceApply.ownerNamePlaceholder')" /> | ||
| 37 | + </el-col> | ||
| 38 | + <el-col :span="4"> | ||
| 39 | + <el-input v-model="conditions.createUserName" :placeholder="$t('invoiceApply.applicantPlaceholder')" /> | ||
| 40 | + </el-col> | ||
| 41 | + <el-col :span="4"> | ||
| 42 | + <el-input v-model="conditions.applyTel" :placeholder="$t('invoiceApply.phonePlaceholder')" /> | ||
| 43 | + </el-col> | ||
| 44 | + <el-col :span="4"> | ||
| 45 | + <el-button type="primary" @click="_queryInvoiceApplyMethod"> | ||
| 46 | + <i class="el-icon-search" /> | ||
| 47 | + <span>{{ $t('common.search') }}</span> | ||
| 48 | + </el-button> | ||
| 49 | + </el-col> | ||
| 50 | + </el-row> | ||
| 51 | + </el-card> | ||
| 52 | + </el-col> | ||
| 53 | + </el-row> | ||
| 54 | + <el-row> | ||
| 55 | + <el-col :span="24"> | ||
| 56 | + <el-card> | ||
| 57 | + <div slot="header" class="flex justify-between"> | ||
| 58 | + <span>{{ $t('invoiceApply.title') }}</span> | ||
| 59 | + <el-button type="primary" size="small" class="float-right" @click="_invoiceApply"> | ||
| 60 | + {{ $t('invoiceApply.apply') }} | ||
| 61 | + </el-button> | ||
| 62 | + </div> | ||
| 63 | + <el-table :data="invoiceApplys" border style="width: 100%"> | ||
| 64 | + <el-table-column prop="applyId" :label="$t('invoiceApply.table.id')" align="center" /> | ||
| 65 | + <el-table-column prop="invoiceType" :label="$t('invoiceApply.table.invoiceType')" align="center"> | ||
| 66 | + <template slot-scope="scope"> | ||
| 67 | + {{ scope.row.invoiceType === '1001' ? $t('invoiceApply.personal') : $t('invoiceApply.company') }} | ||
| 68 | + </template> | ||
| 69 | + </el-table-column> | ||
| 70 | + <el-table-column prop="ownerName" :label="$t('invoiceApply.table.ownerName')" align="center" /> | ||
| 71 | + <el-table-column :label="$t('invoiceApply.table.applicant')" align="center"> | ||
| 72 | + <template slot-scope="scope"> | ||
| 73 | + {{ scope.row.createUserName }}({{ scope.row.applyTel }}) | ||
| 74 | + </template> | ||
| 75 | + </el-table-column> | ||
| 76 | + <el-table-column prop="invoiceName" :label="$t('invoiceApply.table.invoiceName')" align="center" /> | ||
| 77 | + <el-table-column prop="invoiceNum" :label="$t('invoiceApply.table.taxNumber')" align="center" /> | ||
| 78 | + <el-table-column prop="invoiceAddress" :label="$t('invoiceApply.table.addressPhone')" align="center" /> | ||
| 79 | + <el-table-column prop="invoiceAmount" :label="$t('invoiceApply.table.amount')" align="center" /> | ||
| 80 | + <el-table-column prop="invoiceCode" :label="$t('invoiceApply.table.invoiceCode')" align="center"> | ||
| 81 | + <template slot-scope="scope"> | ||
| 82 | + {{ scope.row.invoiceCode || $t('invoiceApply.notUploaded') }} | ||
| 83 | + </template> | ||
| 84 | + </el-table-column> | ||
| 85 | + <el-table-column prop="stateName" :label="$t('invoiceApply.table.status')" align="center" /> | ||
| 86 | + <el-table-column prop="createTime" :label="$t('invoiceApply.table.applyTime')" align="center" /> | ||
| 87 | + <el-table-column :label="$t('common.operation')" align="center" width="220"> | ||
| 88 | + <template slot-scope="scope"> | ||
| 89 | + <el-button v-if="scope.row.state === 'W'" size="mini" @click="_openInvoiceAuditModel(scope.row)"> | ||
| 90 | + {{ $t('common.audit') }} | ||
| 91 | + </el-button> | ||
| 92 | + <template v-else> | ||
| 93 | + <el-button v-if="hasPlugin('invoice') && scope.row.state !== 'W'" size="mini" | ||
| 94 | + @click="_toOpenInvoicePlugin(scope.row)"> | ||
| 95 | + {{ $t('invoiceApply.openInvoice') }} | ||
| 96 | + </el-button> | ||
| 97 | + <div v-else> | ||
| 98 | + <el-button v-if="['U', 'G', 'C'].includes(scope.row.state)" size="mini" | ||
| 99 | + @click="_openUploadInvoicePhoto(scope.row)"> | ||
| 100 | + {{ scope.row.state === 'U' ? $t('invoiceApply.uploadInvoice') : $t('invoiceApply.reUpload') }} | ||
| 101 | + </el-button> | ||
| 102 | + <el-button v-if="['U', 'G', 'C'].includes(scope.row.state)" size="mini" | ||
| 103 | + @click="_openUserGetInvoice(scope.row)"> | ||
| 104 | + {{ scope.row.state === 'G' ? $t('invoiceApply.verify') : $t('invoiceApply.register') }} | ||
| 105 | + </el-button> | ||
| 106 | + </div> | ||
| 107 | + </template> | ||
| 108 | + <el-button size="mini" type="danger" @click="_openDeleteInvoiceApplyModel(scope.row)"> | ||
| 109 | + {{ $t('common.delete') }} | ||
| 110 | + </el-button> | ||
| 111 | + <el-button size="mini" @click="_openInvoiceApplyDetail(scope.row)"> | ||
| 112 | + {{ $t('common.detail') }} | ||
| 113 | + </el-button> | ||
| 114 | + </template> | ||
| 115 | + </el-table-column> | ||
| 116 | + </el-table> | ||
| 117 | + <el-pagination :current-page="page.current" :page-sizes="[10, 20, 30, 50]" :page-size="page.size" | ||
| 118 | + :total="page.total" layout="total, sizes, prev, pager, next, jumper" @size-change="handleSizeChange" | ||
| 119 | + @current-change="handleCurrentChange" /> | ||
| 120 | + </el-card> | ||
| 121 | + </el-col> | ||
| 122 | + </el-row> | ||
| 123 | + </el-col> | ||
| 124 | + </el-row> | ||
| 125 | + | ||
| 126 | + <delete-invoice-apply ref="deleteDialog" @success="listInvoiceApplys" /> | ||
| 127 | + <upload-invoice-photo ref="uploadPhotoDialog" @success="listInvoiceApplys" /> | ||
| 128 | + <wirte-invoice-event ref="writeEventDialog" @success="listInvoiceApplys" /> | ||
| 129 | + <audit-dialog ref="auditDialog" @success="notifyAuditInfo" /> | ||
| 130 | + </div> | ||
| 131 | +</template> | ||
| 132 | + | ||
| 133 | +<script> | ||
| 134 | +import { listInvoiceApply, auditInvoiceApply } from '@/api/fee/invoiceApplyApi' | ||
| 135 | +import { getCommunityId } from '@/api/community/communityApi' | ||
| 136 | +import DeleteInvoiceApply from '@/components/fee/deleteInvoiceApply' | ||
| 137 | +import UploadInvoicePhoto from '@/components/fee/uploadInvoicePhoto' | ||
| 138 | +import WirteInvoiceEvent from '@/components/fee/wirteInvoiceEvent' | ||
| 139 | +import AuditDialog from '@/components/fee/audit' | ||
| 140 | + | ||
| 141 | +export default { | ||
| 142 | + name: 'InvoiceApplyList', | ||
| 143 | + components: { | ||
| 144 | + DeleteInvoiceApply, | ||
| 145 | + UploadInvoicePhoto, | ||
| 146 | + WirteInvoiceEvent, | ||
| 147 | + AuditDialog | ||
| 148 | + }, | ||
| 149 | + data() { | ||
| 150 | + return { | ||
| 151 | + states: [ | ||
| 152 | + { stateName: 'all', state: '' }, | ||
| 153 | + { stateName: 'pendingReview', state: 'W' }, | ||
| 154 | + { stateName: 'pendingUpload', state: 'U' }, | ||
| 155 | + { stateName: 'reviewFailed', state: 'F' }, | ||
| 156 | + { stateName: 'pendingReceive', state: 'G' }, | ||
| 157 | + { stateName: 'received', state: 'C' } | ||
| 158 | + ], | ||
| 159 | + conditions: { | ||
| 160 | + invoiceCode: '', | ||
| 161 | + invoiceType: '', | ||
| 162 | + ownerName: '', | ||
| 163 | + applyTel: '', | ||
| 164 | + createUserName: '', | ||
| 165 | + state: '' | ||
| 166 | + }, | ||
| 167 | + invoiceApplys: [], | ||
| 168 | + page: { | ||
| 169 | + current: 1, | ||
| 170 | + size: 10, | ||
| 171 | + total: 0 | ||
| 172 | + }, | ||
| 173 | + auditData: {} | ||
| 174 | + } | ||
| 175 | + }, | ||
| 176 | + created() { | ||
| 177 | + this.communityId = getCommunityId() | ||
| 178 | + this.listInvoiceApplys() | ||
| 179 | + }, | ||
| 180 | + methods: { | ||
| 181 | + async listInvoiceApplys() { | ||
| 182 | + try { | ||
| 183 | + const params = { | ||
| 184 | + ...this.conditions, | ||
| 185 | + page: this.page.current, | ||
| 186 | + row: this.page.size, | ||
| 187 | + communityId: this.communityId | ||
| 188 | + } | ||
| 189 | + const res = await listInvoiceApply(params) | ||
| 190 | + this.invoiceApplys = res.data | ||
| 191 | + this.page.total = res.total | ||
| 192 | + } catch (error) { | ||
| 193 | + this.$message.error(this.$t('common.fetchError')) | ||
| 194 | + } | ||
| 195 | + }, | ||
| 196 | + handleSizeChange(size) { | ||
| 197 | + this.page.size = size | ||
| 198 | + this.listInvoiceApplys() | ||
| 199 | + }, | ||
| 200 | + handleCurrentChange(current) { | ||
| 201 | + this.page.current = current | ||
| 202 | + this.listInvoiceApplys() | ||
| 203 | + }, | ||
| 204 | + swatchState(item) { | ||
| 205 | + this.conditions.state = item.state | ||
| 206 | + this.listInvoiceApplys() | ||
| 207 | + }, | ||
| 208 | + _queryInvoiceApplyMethod() { | ||
| 209 | + this.page.current = 1 | ||
| 210 | + this.listInvoiceApplys() | ||
| 211 | + }, | ||
| 212 | + _invoiceApply() { | ||
| 213 | + this.$router.push('/views/fee/ownerApplyInvoice') | ||
| 214 | + }, | ||
| 215 | + _openInvoiceApplyDetail(row) { | ||
| 216 | + this.$router.push(`/views/fee/invoiceApplyDetail?applyId=${row.applyId}`) | ||
| 217 | + }, | ||
| 218 | + _openInvoiceAuditModel(row) { | ||
| 219 | + this.auditData = { ...row } | ||
| 220 | + this.$refs.auditDialog.open() | ||
| 221 | + }, | ||
| 222 | + async notifyAuditInfo(auditInfo) { | ||
| 223 | + try { | ||
| 224 | + const params = { | ||
| 225 | + ...this.auditData, | ||
| 226 | + state: auditInfo.state, | ||
| 227 | + remark: auditInfo.remark, | ||
| 228 | + communityId: this.communityId | ||
| 229 | + } | ||
| 230 | + await auditInvoiceApply(params) | ||
| 231 | + this.$message.success(this.$t('invoiceApply.auditSuccess')) | ||
| 232 | + this.listInvoiceApplys() | ||
| 233 | + } catch (error) { | ||
| 234 | + this.$message.error(error.message) | ||
| 235 | + } | ||
| 236 | + }, | ||
| 237 | + _openUploadInvoicePhoto(row) { | ||
| 238 | + this.$refs.uploadPhotoDialog.open(row) | ||
| 239 | + }, | ||
| 240 | + _openUserGetInvoice(row) { | ||
| 241 | + this.$refs.writeEventDialog.open(row) | ||
| 242 | + }, | ||
| 243 | + _toOpenInvoicePlugin(row) { | ||
| 244 | + const userInfo = this.$store.getters.userInfo | ||
| 245 | + this.$router.push({ | ||
| 246 | + path: '/plugin', | ||
| 247 | + query: { | ||
| 248 | + pluginType: 'invoice', | ||
| 249 | + orderNo: row.applyId, | ||
| 250 | + staffName: userInfo.name, | ||
| 251 | + communityId: this.communityId | ||
| 252 | + } | ||
| 253 | + }) | ||
| 254 | + }, | ||
| 255 | + _openDeleteInvoiceApplyModel(row) { | ||
| 256 | + this.$refs.deleteDialog.open(row) | ||
| 257 | + }, | ||
| 258 | + hasPlugin(pluginName) { | ||
| 259 | + // 实际项目中需要根据业务逻辑实现 | ||
| 260 | + console.log(pluginName) | ||
| 261 | + return true | ||
| 262 | + } | ||
| 263 | + } | ||
| 264 | +} | ||
| 265 | +</script> | ||
| 266 | + | ||
| 267 | +<style scoped> | ||
| 268 | +.border-radius { | ||
| 269 | + border-radius: 4px; | ||
| 270 | +} | ||
| 271 | + | ||
| 272 | +.list-group { | ||
| 273 | + padding: 0; | ||
| 274 | + margin: 0; | ||
| 275 | + list-style: none; | ||
| 276 | +} | ||
| 277 | + | ||
| 278 | +.list-group-item { | ||
| 279 | + padding: 10px 15px; | ||
| 280 | + margin-bottom: -1px; | ||
| 281 | + background-color: #fff; | ||
| 282 | + border: 1px solid #ddd; | ||
| 283 | + cursor: pointer; | ||
| 284 | +} | ||
| 285 | + | ||
| 286 | +.list-group-item:hover, | ||
| 287 | +.vc-node-selected { | ||
| 288 | + background-color: #f5f7fa; | ||
| 289 | + color: #409EFF; | ||
| 290 | +} | ||
| 291 | + | ||
| 292 | +.float-right { | ||
| 293 | + float: right; | ||
| 294 | +} | ||
| 295 | +</style> | ||
| 0 | \ No newline at end of file | 296 | \ No newline at end of file |
src/views/fee/ownerApplyInvoiceLang.js
0 → 100644
| 1 | +export const messages = { | ||
| 2 | + en: { | ||
| 3 | + ownerApplyInvoice: { | ||
| 4 | + title: 'Invoice Application', | ||
| 5 | + invoiceTitle: 'Invoice Title', | ||
| 6 | + taxpayerId: 'Taxpayer ID', | ||
| 7 | + invoiceType: 'Invoice Type', | ||
| 8 | + addressPhone: 'Address & Phone', | ||
| 9 | + owner: 'Owner', | ||
| 10 | + content: 'Content', | ||
| 11 | + personal: 'Personal', | ||
| 12 | + enterprise: 'Enterprise', | ||
| 13 | + paidFees: 'Paid Fees', | ||
| 14 | + accountDeposit: 'Account Deposit', | ||
| 15 | + feeName: 'Fee Item', | ||
| 16 | + payer: 'Payer', | ||
| 17 | + receivablePaid: 'Receivable/Paid', | ||
| 18 | + paymentMethod: 'Payment Method', | ||
| 19 | + paymentPeriod: 'Payment Period', | ||
| 20 | + paymentTime: 'Payment Time', | ||
| 21 | + cashier: 'Cashier', | ||
| 22 | + status: 'Status', | ||
| 23 | + remark: 'Remark', | ||
| 24 | + accountName: 'Account Name', | ||
| 25 | + accountType: 'Account Type', | ||
| 26 | + depositAmount: 'Deposit Amount', | ||
| 27 | + depositMethod: 'Deposit Method', | ||
| 28 | + totalAmount: 'Total Amount', | ||
| 29 | + depositTime: 'Deposit Time', | ||
| 30 | + back: 'Back', | ||
| 31 | + select: 'Select', | ||
| 32 | + submit: 'Submit', | ||
| 33 | + required: 'Required', | ||
| 34 | + chooseInvoiceTitle: 'Please select invoice title', | ||
| 35 | + chooseTaxId: 'Please select taxpayer ID', | ||
| 36 | + chooseInvoiceType: 'Please select invoice type', | ||
| 37 | + chooseAddressPhone: 'Please enter address and phone', | ||
| 38 | + chooseContent: 'Please select content', | ||
| 39 | + noFeeSelected: 'No paid fees selected', | ||
| 40 | + noDepositSelected: 'No account deposit selected' | ||
| 41 | + }, | ||
| 42 | + searchOwnerInvoice: { | ||
| 43 | + title: 'Select Owner', | ||
| 44 | + ownerName: 'Owner Name', | ||
| 45 | + invoiceType: 'Invoice Type', | ||
| 46 | + invoiceTitle: 'Invoice Title', | ||
| 47 | + taxpayerId: 'Taxpayer ID', | ||
| 48 | + addressPhone: 'Address & Phone', | ||
| 49 | + operation: 'Operation', | ||
| 50 | + search: 'Search', | ||
| 51 | + placeholderRoom: 'Enter room number (building-unit-room)', | ||
| 52 | + placeholderOwner: 'Enter owner name', | ||
| 53 | + select: 'Select', | ||
| 54 | + personal: 'Personal', | ||
| 55 | + company: 'Company' | ||
| 56 | + } | ||
| 57 | + }, | ||
| 58 | + zh: { | ||
| 59 | + ownerApplyInvoice: { | ||
| 60 | + title: '发票申请', | ||
| 61 | + invoiceTitle: '发票抬头', | ||
| 62 | + taxpayerId: '纳税人识别号', | ||
| 63 | + invoiceType: '发票类型', | ||
| 64 | + addressPhone: '地址、电话', | ||
| 65 | + owner: '业主', | ||
| 66 | + content: '开票内容', | ||
| 67 | + personal: '个人', | ||
| 68 | + enterprise: '企业', | ||
| 69 | + paidFees: '已缴费费用', | ||
| 70 | + accountDeposit: '账户预存', | ||
| 71 | + feeName: '费用项', | ||
| 72 | + payer: '收费对象', | ||
| 73 | + receivablePaid: '应收/实收', | ||
| 74 | + paymentMethod: '缴费方式', | ||
| 75 | + paymentPeriod: '缴费起始段', | ||
| 76 | + paymentTime: '缴费时间', | ||
| 77 | + cashier: '收银员', | ||
| 78 | + status: '状态', | ||
| 79 | + remark: '备注', | ||
| 80 | + accountName: '账户名称', | ||
| 81 | + accountType: '账户类型', | ||
| 82 | + depositAmount: '预存金额', | ||
| 83 | + depositMethod: '预存方式', | ||
| 84 | + totalAmount: '总金额', | ||
| 85 | + depositTime: '预存时间', | ||
| 86 | + back: '返回', | ||
| 87 | + select: '选择', | ||
| 88 | + submit: '提交', | ||
| 89 | + required: '必填', | ||
| 90 | + chooseInvoiceTitle: '请选择发票抬头', | ||
| 91 | + chooseTaxId: '请选择纳税人识别号', | ||
| 92 | + chooseInvoiceType: '请选择发票类型', | ||
| 93 | + chooseAddressPhone: '请输入地址、电话', | ||
| 94 | + chooseContent: '请选择开票内容', | ||
| 95 | + noFeeSelected: '未选择已缴费费用', | ||
| 96 | + noDepositSelected: '未选择账户预存' | ||
| 97 | + }, | ||
| 98 | + searchOwnerInvoice: { | ||
| 99 | + title: '选择业主', | ||
| 100 | + ownerName: '业主名称', | ||
| 101 | + invoiceType: '发票类型', | ||
| 102 | + invoiceTitle: '发票名头', | ||
| 103 | + taxpayerId: '纳税人识别号', | ||
| 104 | + addressPhone: '地址、电话', | ||
| 105 | + operation: '操作', | ||
| 106 | + search: '查询', | ||
| 107 | + placeholderRoom: '输入房屋编号楼栋-单元-房屋', | ||
| 108 | + placeholderOwner: '输入业主名称', | ||
| 109 | + select: '选择', | ||
| 110 | + personal: '个人', | ||
| 111 | + company: '公司' | ||
| 112 | + } | ||
| 113 | + } | ||
| 114 | +} | ||
| 0 | \ No newline at end of file | 115 | \ No newline at end of file |
src/views/fee/ownerApplyInvoiceList.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <div class="owner-apply-invoice-container"> | ||
| 3 | + <el-card> | ||
| 4 | + <div slot="header" class="clearfix flex justify-between"> | ||
| 5 | + <h3>{{ $t('ownerApplyInvoice.title') }}</h3> | ||
| 6 | + <div class="header-actions"> | ||
| 7 | + <el-button type="primary" size="small" @click="goBack"> | ||
| 8 | + {{ $t('ownerApplyInvoice.back') }} | ||
| 9 | + </el-button> | ||
| 10 | + </div> | ||
| 11 | + </div> | ||
| 12 | + | ||
| 13 | + <el-form ref="form" :model="formData" label-width="150px"> | ||
| 14 | + <el-row :gutter="20"> | ||
| 15 | + <el-col :span="8"> | ||
| 16 | + <el-form-item :label="$t('ownerApplyInvoice.invoiceTitle')" required> | ||
| 17 | + <el-input v-model="formData.invoiceName" :placeholder="$t('ownerApplyInvoice.chooseInvoiceTitle')" | ||
| 18 | + disabled /> | ||
| 19 | + </el-form-item> | ||
| 20 | + </el-col> | ||
| 21 | + <el-col :span="4" class="text-left"> | ||
| 22 | + <el-button type="primary" size="small" style="margin-left: 150px; margin-bottom: 20px" | ||
| 23 | + @click="openSelectOwner"> | ||
| 24 | + {{ $t('ownerApplyInvoice.select') }} | ||
| 25 | + </el-button></el-col> | ||
| 26 | + <el-col :span="12"> | ||
| 27 | + <el-form-item :label="$t('ownerApplyInvoice.taxpayerId')" required> | ||
| 28 | + <el-input v-model="formData.invoiceNum" :placeholder="$t('ownerApplyInvoice.chooseTaxId')" disabled /> | ||
| 29 | + </el-form-item> | ||
| 30 | + </el-col> | ||
| 31 | + </el-row> | ||
| 32 | + | ||
| 33 | + <el-row :gutter="20"> | ||
| 34 | + <el-col :span="12"> | ||
| 35 | + <el-form-item :label="$t('ownerApplyInvoice.invoiceType')" required> | ||
| 36 | + <el-select v-model="formData.invoiceType" :placeholder="$t('ownerApplyInvoice.chooseInvoiceType')" | ||
| 37 | + style="width:100%"> | ||
| 38 | + <el-option :label="$t('ownerApplyInvoice.personal')" value="1001" /> | ||
| 39 | + <el-option :label="$t('ownerApplyInvoice.enterprise')" value="2002" /> | ||
| 40 | + </el-select> | ||
| 41 | + </el-form-item> | ||
| 42 | + </el-col> | ||
| 43 | + <el-col :span="12"> | ||
| 44 | + <el-form-item :label="$t('ownerApplyInvoice.addressPhone')" required> | ||
| 45 | + <el-input v-model="formData.invoiceAddress" :placeholder="$t('ownerApplyInvoice.chooseAddressPhone')" /> | ||
| 46 | + </el-form-item> | ||
| 47 | + </el-col> | ||
| 48 | + </el-row> | ||
| 49 | + | ||
| 50 | + <el-row :gutter="20"> | ||
| 51 | + <el-col :span="12"> | ||
| 52 | + <el-form-item :label="$t('ownerApplyInvoice.owner')" required> | ||
| 53 | + <el-input v-model="formData.ownerName" :placeholder="$t('ownerApplyInvoice.chooseContent')" disabled /> | ||
| 54 | + </el-form-item> | ||
| 55 | + </el-col> | ||
| 56 | + <el-col :span="12"> | ||
| 57 | + <el-form-item :label="$t('ownerApplyInvoice.content')" required> | ||
| 58 | + <el-select v-model="formData.invoiceFlag" :placeholder="$t('ownerApplyInvoice.chooseContent')" | ||
| 59 | + style="width:100%" @change="handleContentChange"> | ||
| 60 | + <el-option :label="$t('ownerApplyInvoice.paidFees')" value="FEE" /> | ||
| 61 | + <el-option :label="$t('ownerApplyInvoice.accountDeposit')" value="ACCT" /> | ||
| 62 | + </el-select> | ||
| 63 | + </el-form-item> | ||
| 64 | + </el-col> | ||
| 65 | + </el-row> | ||
| 66 | + </el-form> | ||
| 67 | + | ||
| 68 | + | ||
| 69 | + </el-card> | ||
| 70 | + | ||
| 71 | + <!-- 已缴费费用 --> | ||
| 72 | + <el-card v-if="formData.invoiceFlag === 'FEE'" class="mt-20"> | ||
| 73 | + <div slot="header" class="flex justify-between"> | ||
| 74 | + <h3>{{ $t('ownerApplyInvoice.paidFees') }}</h3> | ||
| 75 | + </div> | ||
| 76 | + | ||
| 77 | + <el-table :data="feeDetails" border style="width: 100%"> | ||
| 78 | + <el-table-column type="selection" width="55" align="center" @select-all="handleFeeSelectAll" /> | ||
| 79 | + <el-table-column prop="feeName" :label="$t('ownerApplyInvoice.feeName')" align="center" /> | ||
| 80 | + <el-table-column prop="payerObjName" :label="$t('ownerApplyInvoice.payer')" align="center" /> | ||
| 81 | + <el-table-column :label="$t('ownerApplyInvoice.receivablePaid')" align="center"> | ||
| 82 | + <template slot-scope="scope"> | ||
| 83 | + {{ scope.row.receivableAmount }}/{{ scope.row.receivedAmount }} | ||
| 84 | + </template> | ||
| 85 | + </el-table-column> | ||
| 86 | + <el-table-column prop="primeRateName" :label="$t('ownerApplyInvoice.paymentMethod')" align="center" /> | ||
| 87 | + <el-table-column :label="$t('ownerApplyInvoice.paymentPeriod')" align="center"> | ||
| 88 | + <template slot-scope="scope"> | ||
| 89 | + {{ formatDate(scope.row.startTime) }}~<br> | ||
| 90 | + {{ formatDate(scope.row.endTime) }} | ||
| 91 | + </template> | ||
| 92 | + </el-table-column> | ||
| 93 | + <el-table-column prop="createTime" :label="$t('ownerApplyInvoice.paymentTime')" align="center" /> | ||
| 94 | + <el-table-column prop="cashierName" :label="$t('ownerApplyInvoice.cashier')" align="center"> | ||
| 95 | + <template slot-scope="scope"> | ||
| 96 | + {{ scope.row.cashierName || '-' }} | ||
| 97 | + </template> | ||
| 98 | + </el-table-column> | ||
| 99 | + <el-table-column prop="stateName" :label="$t('ownerApplyInvoice.status')" align="center" /> | ||
| 100 | + <el-table-column prop="remark" :label="$t('ownerApplyInvoice.remark')" align="center" /> | ||
| 101 | + </el-table> | ||
| 102 | + </el-card> | ||
| 103 | + | ||
| 104 | + <!-- 账户预存 --> | ||
| 105 | + <el-card v-if="formData.invoiceFlag === 'ACCT'" class="mt-20"> | ||
| 106 | + <div slot="" class="flex justify-between"> | ||
| 107 | + <h3>{{ $t('ownerApplyInvoice.accountDeposit') }}</h3> | ||
| 108 | + </div> | ||
| 109 | + | ||
| 110 | + <el-table :data="acctDetails" border style="width: 100%"> | ||
| 111 | + <el-table-column type="selection" width="55" align="center" @select-all="handleAcctSelectAll" /> | ||
| 112 | + <el-table-column prop="acctName" :label="$t('ownerApplyInvoice.accountName')" align="center" /> | ||
| 113 | + <el-table-column prop="acctTypeName" :label="$t('ownerApplyInvoice.accountType')" align="center" /> | ||
| 114 | + <el-table-column prop="ownerName" :label="$t('ownerApplyInvoice.owner')" align="center" /> | ||
| 115 | + <el-table-column prop="receivedAmount" :label="$t('ownerApplyInvoice.depositAmount')" align="center" /> | ||
| 116 | + <el-table-column prop="primeRateName" :label="$t('ownerApplyInvoice.depositMethod')" align="center" /> | ||
| 117 | + <el-table-column prop="amount" :label="$t('ownerApplyInvoice.totalAmount')" align="center" /> | ||
| 118 | + <el-table-column prop="createTime" :label="$t('ownerApplyInvoice.depositTime')" align="center" /> | ||
| 119 | + </el-table> | ||
| 120 | + </el-card> | ||
| 121 | + | ||
| 122 | + <div class="mt-20 text-right"> | ||
| 123 | + <el-button type="primary" @click="handleSubmit"> | ||
| 124 | + {{ $t('ownerApplyInvoice.submit') }} | ||
| 125 | + </el-button> | ||
| 126 | + </div> | ||
| 127 | + | ||
| 128 | + <search-owner-invoice ref="searchOwnerInvoice" :visible.sync="showSearchDialog" @select="handleOwnerSelect" /> | ||
| 129 | + </div> | ||
| 130 | +</template> | ||
| 131 | + | ||
| 132 | +<script> | ||
| 133 | +import { queryFeeDetail, listAccountReceipt, saveInvoiceApply } from '@/api/fee/ownerApplyInvoiceApi' | ||
| 134 | +import SearchOwnerInvoice from '@/components/fee/searchOwnerInvoice' | ||
| 135 | +import { formatDate } from '@/utils/dateUtil' | ||
| 136 | + | ||
| 137 | +export default { | ||
| 138 | + name: 'OwnerApplyInvoiceList', | ||
| 139 | + components: { | ||
| 140 | + SearchOwnerInvoice | ||
| 141 | + }, | ||
| 142 | + data() { | ||
| 143 | + return { | ||
| 144 | + showSearchDialog: false, | ||
| 145 | + formData: { | ||
| 146 | + oiId: '', | ||
| 147 | + ownerId: '', | ||
| 148 | + ownerName: '', | ||
| 149 | + invoiceType: '', | ||
| 150 | + invoiceName: '', | ||
| 151 | + invoiceAddress: '', | ||
| 152 | + invoiceNum: '', | ||
| 153 | + detailIds: [], | ||
| 154 | + feeDetails: [], | ||
| 155 | + invoiceFlag: 'FEE', | ||
| 156 | + arIds: [], | ||
| 157 | + acctDetails: [] | ||
| 158 | + }, | ||
| 159 | + feeDetails: [], | ||
| 160 | + acctDetails: [] | ||
| 161 | + } | ||
| 162 | + }, | ||
| 163 | + methods: { | ||
| 164 | + formatDate, | ||
| 165 | + goBack() { | ||
| 166 | + this.$router.go(-1) | ||
| 167 | + }, | ||
| 168 | + openSelectOwner() { | ||
| 169 | + this.showSearchDialog = true | ||
| 170 | + this.$nextTick(() => { | ||
| 171 | + this.$refs.searchOwnerInvoice.open() | ||
| 172 | + }) | ||
| 173 | + }, | ||
| 174 | + handleOwnerSelect(owner) { | ||
| 175 | + Object.assign(this.formData, owner) | ||
| 176 | + this.formData.detailIds = [] | ||
| 177 | + this.formData.arIds = [] | ||
| 178 | + | ||
| 179 | + if (this.formData.invoiceFlag === 'FEE') { | ||
| 180 | + this.loadFeeDetails() | ||
| 181 | + } else { | ||
| 182 | + this.loadAcctDetails() | ||
| 183 | + } | ||
| 184 | + }, | ||
| 185 | + async loadFeeDetails() { | ||
| 186 | + try { | ||
| 187 | + const params = { | ||
| 188 | + page: 1, | ||
| 189 | + row: 50, | ||
| 190 | + ownerId: this.formData.ownerId, | ||
| 191 | + openInvoice: 'N' | ||
| 192 | + } | ||
| 193 | + | ||
| 194 | + const res = await queryFeeDetail(params) | ||
| 195 | + this.feeDetails = res.feeDetails || [] | ||
| 196 | + | ||
| 197 | + // 默认全选 | ||
| 198 | + this.formData.detailIds = this.feeDetails.map(item => item.detailId) | ||
| 199 | + } catch (error) { | ||
| 200 | + console.error('Failed to load fee details:', error) | ||
| 201 | + this.$message.error(this.$t('common.loadFailed')) | ||
| 202 | + } | ||
| 203 | + }, | ||
| 204 | + async loadAcctDetails() { | ||
| 205 | + try { | ||
| 206 | + const params = { | ||
| 207 | + page: 1, | ||
| 208 | + row: 50, | ||
| 209 | + ownerId: this.formData.ownerId | ||
| 210 | + } | ||
| 211 | + | ||
| 212 | + const res = await listAccountReceipt(params) | ||
| 213 | + this.acctDetails = res.data || [] | ||
| 214 | + | ||
| 215 | + // 默认全选 | ||
| 216 | + this.formData.arIds = this.acctDetails.map(item => item.arId) | ||
| 217 | + } catch (error) { | ||
| 218 | + console.error('Failed to load account details:', error) | ||
| 219 | + this.$message.error(this.$t('common.loadFailed')) | ||
| 220 | + } | ||
| 221 | + }, | ||
| 222 | + handleContentChange() { | ||
| 223 | + if (!this.formData.ownerId) return | ||
| 224 | + | ||
| 225 | + this.formData.detailIds = [] | ||
| 226 | + this.formData.arIds = [] | ||
| 227 | + | ||
| 228 | + if (this.formData.invoiceFlag === 'FEE') { | ||
| 229 | + this.loadFeeDetails() | ||
| 230 | + } else { | ||
| 231 | + this.loadAcctDetails() | ||
| 232 | + } | ||
| 233 | + }, | ||
| 234 | + handleFeeSelectAll(selection) { | ||
| 235 | + this.formData.detailIds = selection.length | ||
| 236 | + ? this.feeDetails.map(item => item.detailId) | ||
| 237 | + : [] | ||
| 238 | + }, | ||
| 239 | + handleAcctSelectAll(selection) { | ||
| 240 | + this.formData.arIds = selection.length | ||
| 241 | + ? this.acctDetails.map(item => item.arId) | ||
| 242 | + : [] | ||
| 243 | + }, | ||
| 244 | + async handleSubmit() { | ||
| 245 | + try { | ||
| 246 | + // 验证表单 | ||
| 247 | + if (!this.formData.ownerId) { | ||
| 248 | + this.$message.warning(this.$t('ownerApplyInvoice.chooseContent')) | ||
| 249 | + return | ||
| 250 | + } | ||
| 251 | + | ||
| 252 | + if (this.formData.invoiceFlag === 'FEE' && !this.formData.detailIds.length) { | ||
| 253 | + this.$message.warning(this.$t('ownerApplyInvoice.noFeeSelected')) | ||
| 254 | + return | ||
| 255 | + } | ||
| 256 | + | ||
| 257 | + if (this.formData.invoiceFlag === 'ACCT' && !this.formData.arIds.length) { | ||
| 258 | + this.$message.warning(this.$t('ownerApplyInvoice.noDepositSelected')) | ||
| 259 | + return | ||
| 260 | + } | ||
| 261 | + | ||
| 262 | + // 准备提交数据 | ||
| 263 | + const submitData = { | ||
| 264 | + ...this.formData, | ||
| 265 | + detailIds: this.formData.invoiceFlag === 'FEE' ? this.formData.detailIds : [], | ||
| 266 | + arIds: this.formData.invoiceFlag === 'ACCT' ? this.formData.arIds : [] | ||
| 267 | + } | ||
| 268 | + | ||
| 269 | + // 调用API | ||
| 270 | + await saveInvoiceApply(submitData) | ||
| 271 | + this.$message.success(this.$t('common.submitSuccess')) | ||
| 272 | + this.goBack() | ||
| 273 | + } catch (error) { | ||
| 274 | + console.error('Failed to submit invoice application:', error) | ||
| 275 | + this.$message.error(error.message || this.$t('common.submitFailed')) | ||
| 276 | + } | ||
| 277 | + } | ||
| 278 | + } | ||
| 279 | +} | ||
| 280 | +</script> | ||
| 281 | + | ||
| 282 | +<style scoped> | ||
| 283 | +.owner-apply-invoice-container { | ||
| 284 | + padding: 20px; | ||
| 285 | +} | ||
| 286 | + | ||
| 287 | +.mt-20 { | ||
| 288 | + margin-top: 20px; | ||
| 289 | +} | ||
| 290 | + | ||
| 291 | +.text-right { | ||
| 292 | + text-align: right; | ||
| 293 | +} | ||
| 294 | + | ||
| 295 | +.header-actions {} | ||
| 296 | +</style> | ||
| 0 | \ No newline at end of file | 297 | \ No newline at end of file |
src/views/fee/ownerInvoiceLang.js
0 → 100644
| 1 | +export const messages = { | ||
| 2 | + en: { | ||
| 3 | + searchCondition: 'Search Conditions', | ||
| 4 | + ownerNamePlaceholder: 'Enter owner name', | ||
| 5 | + invoiceTypePlaceholder: 'Select invoice type', | ||
| 6 | + personal: 'Personal', | ||
| 7 | + enterprise: 'Enterprise', | ||
| 8 | + invoiceHeaderPlaceholder: 'Enter invoice header', | ||
| 9 | + search: 'Search', | ||
| 10 | + invoiceHeader: 'Invoice Header', | ||
| 11 | + add: 'Add', | ||
| 12 | + serialNumber: 'Serial Number', | ||
| 13 | + ownerName: 'Owner Name', | ||
| 14 | + invoiceType: 'Invoice Type', | ||
| 15 | + taxpayerId: 'Taxpayer ID', | ||
| 16 | + address: 'Address', | ||
| 17 | + phone: 'Phone', | ||
| 18 | + bankAccount: 'Bank Account', | ||
| 19 | + remark: 'Remark', | ||
| 20 | + operation: 'Operation', | ||
| 21 | + modify: 'Modify', | ||
| 22 | + delete: 'Delete', | ||
| 23 | + confirmDeleteTitle: 'Confirm Deletion', | ||
| 24 | + confirmDeleteContent: 'Are you sure to delete this invoice header?', | ||
| 25 | + cancel: 'Cancel', | ||
| 26 | + confirmDelete: 'Confirm Delete', | ||
| 27 | + editTitle: 'Edit', | ||
| 28 | + requiredInvoiceType: 'Invoice type is required', | ||
| 29 | + requiredInvoiceHeader: 'Invoice header is required', | ||
| 30 | + requiredTaxpayerId: 'Taxpayer ID is required', | ||
| 31 | + requiredAddress: 'Address is required', | ||
| 32 | + requiredPhone: 'Phone is required', | ||
| 33 | + requiredBankAccount: 'Bank account is required', | ||
| 34 | + optionalRemark: 'Remark (optional)', | ||
| 35 | + save: 'Save', | ||
| 36 | + addOwnerInvoice: { | ||
| 37 | + title: 'Add Invoice', | ||
| 38 | + back: 'Back', | ||
| 39 | + owner: 'Owner', | ||
| 40 | + selectOwner: 'Select Owner', | ||
| 41 | + invoiceType: 'Invoice Type', | ||
| 42 | + invoiceTitle: 'Invoice Title', | ||
| 43 | + taxNumber: 'Taxpayer ID', | ||
| 44 | + address: 'Address', | ||
| 45 | + phone: 'Phone', | ||
| 46 | + bankAccount: 'Bank Account', | ||
| 47 | + remarks: 'Remarks', | ||
| 48 | + save: 'Save', | ||
| 49 | + required: 'Required', | ||
| 50 | + personal: 'Personal', | ||
| 51 | + enterprise: 'Enterprise', | ||
| 52 | + placeholder: { | ||
| 53 | + owner: 'Please select owner', | ||
| 54 | + invoiceType: 'Please select invoice type', | ||
| 55 | + invoiceTitle: 'Please enter invoice title', | ||
| 56 | + taxNumber: 'Please enter taxpayer ID', | ||
| 57 | + address: 'Please enter address', | ||
| 58 | + phone: 'Please enter phone number', | ||
| 59 | + bankAccount: 'Please enter bank account', | ||
| 60 | + remarks: 'Optional remarks' | ||
| 61 | + }, | ||
| 62 | + validation: { | ||
| 63 | + ownerRequired: 'Owner is required', | ||
| 64 | + typeRequired: 'Invoice type is required', | ||
| 65 | + titleRequired: 'Invoice title is required', | ||
| 66 | + taxNumberRequired: 'Taxpayer ID is required', | ||
| 67 | + addressRequired: 'Address is required', | ||
| 68 | + phoneRequired: 'Phone is required', | ||
| 69 | + bankAccountRequired: 'Bank account is required' | ||
| 70 | + } | ||
| 71 | + }, | ||
| 72 | + }, | ||
| 73 | + zh: { | ||
| 74 | + searchCondition: '查询条件', | ||
| 75 | + ownerNamePlaceholder: '请输入业主名称', | ||
| 76 | + invoiceTypePlaceholder: '请选择发票类型', | ||
| 77 | + personal: '个人', | ||
| 78 | + enterprise: '企业', | ||
| 79 | + invoiceHeaderPlaceholder: '请输入发票名头', | ||
| 80 | + search: '查询', | ||
| 81 | + invoiceHeader: '发票抬头', | ||
| 82 | + add: '添加', | ||
| 83 | + serialNumber: '编号', | ||
| 84 | + ownerName: '业主名称', | ||
| 85 | + invoiceType: '发票类型', | ||
| 86 | + taxpayerId: '纳税人识别号', | ||
| 87 | + address: '地址', | ||
| 88 | + phone: '电话', | ||
| 89 | + bankAccount: '开户行及账号', | ||
| 90 | + remark: '备注', | ||
| 91 | + operation: '操作', | ||
| 92 | + modify: '修改', | ||
| 93 | + delete: '删除', | ||
| 94 | + confirmDeleteTitle: '请确认您的操作', | ||
| 95 | + confirmDeleteContent: '确定删除发票抬头', | ||
| 96 | + cancel: '点错了', | ||
| 97 | + confirmDelete: '确认删除', | ||
| 98 | + editTitle: '修改', | ||
| 99 | + requiredInvoiceType: '必填,请选择发票类型', | ||
| 100 | + requiredInvoiceHeader: '必填,请填写发票名头', | ||
| 101 | + requiredTaxpayerId: '必填,请填写纳税人识别号', | ||
| 102 | + requiredAddress: '必填,请填写地址', | ||
| 103 | + requiredPhone: '必填,请填写电话', | ||
| 104 | + requiredBankAccount: '必填,请填写开户行及账号', | ||
| 105 | + optionalRemark: '选填,请填写备注', | ||
| 106 | + save: '保存', | ||
| 107 | + addOwnerInvoice: { | ||
| 108 | + title: '添加发票抬头', | ||
| 109 | + back: '返回', | ||
| 110 | + owner: '业主', | ||
| 111 | + selectOwner: '选择业主', | ||
| 112 | + invoiceType: '发票类型', | ||
| 113 | + invoiceTitle: '发票名头', | ||
| 114 | + taxNumber: '纳税人识别号', | ||
| 115 | + address: '地址', | ||
| 116 | + phone: '电话', | ||
| 117 | + bankAccount: '开户行及账号', | ||
| 118 | + remarks: '备注', | ||
| 119 | + save: '保存', | ||
| 120 | + required: '必填', | ||
| 121 | + personal: '个人', | ||
| 122 | + enterprise: '企业', | ||
| 123 | + placeholder: { | ||
| 124 | + owner: '请选择业主', | ||
| 125 | + invoiceType: '请选择发票类型', | ||
| 126 | + invoiceTitle: '请填写发票名头', | ||
| 127 | + taxNumber: '请填写纳税人识别号', | ||
| 128 | + address: '请填写地址', | ||
| 129 | + phone: '请填写电话', | ||
| 130 | + bankAccount: '请填写开户行及账号', | ||
| 131 | + remarks: '选填备注' | ||
| 132 | + }, | ||
| 133 | + validation: { | ||
| 134 | + ownerRequired: '业主不能为空', | ||
| 135 | + typeRequired: '发票类型不能为空', | ||
| 136 | + titleRequired: '发票名头不能为空', | ||
| 137 | + taxNumberRequired: '纳税人识别号不能为空', | ||
| 138 | + addressRequired: '地址不能为空', | ||
| 139 | + phoneRequired: '电话不能为空', | ||
| 140 | + bankAccountRequired: '开户行及账号不能为空' | ||
| 141 | + } | ||
| 142 | + }, | ||
| 143 | + } | ||
| 144 | +} | ||
| 0 | \ No newline at end of file | 145 | \ No newline at end of file |
src/views/fee/ownerInvoiceList.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <div class="owner-invoice-container"> | ||
| 3 | + <!-- 查询条件 --> | ||
| 4 | + <el-card class="search-card"> | ||
| 5 | + <div slot="header" class="clearfix"> | ||
| 6 | + <span>{{ $t('searchCondition') }}</span> | ||
| 7 | + </div> | ||
| 8 | + | ||
| 9 | + <el-row :gutter="20"> | ||
| 10 | + <el-col :span="6"> | ||
| 11 | + <el-input v-model="searchForm.ownerName" :placeholder="$t('ownerNamePlaceholder')" /> | ||
| 12 | + </el-col> | ||
| 13 | + | ||
| 14 | + <el-col :span="6"> | ||
| 15 | + <el-select v-model="searchForm.invoiceType" :placeholder="$t('invoiceTypePlaceholder')" style="width: 100%"> | ||
| 16 | + <el-option value="" :label="$t('invoiceTypePlaceholder')" /> | ||
| 17 | + <el-option value="1001" :label="$t('personal')" /> | ||
| 18 | + <el-option value="2002" :label="$t('enterprise')" /> | ||
| 19 | + </el-select> | ||
| 20 | + </el-col> | ||
| 21 | + | ||
| 22 | + <el-col :span="6"> | ||
| 23 | + <el-input v-model="searchForm.invoiceName" :placeholder="$t('invoiceHeaderPlaceholder')" /> | ||
| 24 | + </el-col> | ||
| 25 | + | ||
| 26 | + <el-col :span="6"> | ||
| 27 | + <el-button type="primary" @click="fetchData">{{ $t('search') }}</el-button> | ||
| 28 | + </el-col> | ||
| 29 | + </el-row> | ||
| 30 | + </el-card> | ||
| 31 | + | ||
| 32 | + <!-- 发票抬头列表 --> | ||
| 33 | + <el-card class="list-card"> | ||
| 34 | + <div slot="header" class="clearfix"> | ||
| 35 | + <span>{{ $t('invoiceHeader') }}</span> | ||
| 36 | + <el-button type="primary" size="small" style="float: right" @click="handleAdd"> | ||
| 37 | + {{ $t('add') }} | ||
| 38 | + </el-button> | ||
| 39 | + </div> | ||
| 40 | + | ||
| 41 | + <el-table :data="tableData" border style="width: 100%" v-loading="loading"> | ||
| 42 | + <el-table-column prop="oiId" :label="$t('serialNumber')" align="center" min-width="80" /> | ||
| 43 | + | ||
| 44 | + <el-table-column prop="ownerName" :label="$t('ownerName')" align="center" min-width="120" /> | ||
| 45 | + | ||
| 46 | + <el-table-column prop="invoiceType" :label="$t('invoiceType')" align="center" min-width="100"> | ||
| 47 | + <template slot-scope="scope"> | ||
| 48 | + {{ scope.row.invoiceType === '1001' ? $t('personal') : $t('enterprise') }} | ||
| 49 | + </template> | ||
| 50 | + </el-table-column> | ||
| 51 | + | ||
| 52 | + <el-table-column prop="invoiceName" :label="$t('invoiceHeader')" align="center" min-width="150" /> | ||
| 53 | + | ||
| 54 | + <el-table-column prop="invoiceNum" :label="$t('taxpayerId')" align="center" min-width="150" /> | ||
| 55 | + | ||
| 56 | + <el-table-column prop="invoiceAddress" :label="$t('address')" align="center" min-width="150" /> | ||
| 57 | + | ||
| 58 | + <el-table-column prop="invoiceLink" :label="$t('phone')" align="center" min-width="120" /> | ||
| 59 | + | ||
| 60 | + <el-table-column prop="invoiceAccount" :label="$t('bankAccount')" align="center" min-width="200" /> | ||
| 61 | + | ||
| 62 | + <el-table-column prop="remark" :label="$t('remark')" align="center" min-width="150" /> | ||
| 63 | + | ||
| 64 | + <el-table-column :label="$t('operation')" align="center" fixed="right" width="180"> | ||
| 65 | + <template slot-scope="scope"> | ||
| 66 | + <el-button size="mini" type="primary" @click="handleEdit(scope.row)"> | ||
| 67 | + {{ $t('modify') }} | ||
| 68 | + </el-button> | ||
| 69 | + <el-button size="mini" type="danger" @click="handleDelete(scope.row)"> | ||
| 70 | + {{ $t('delete') }} | ||
| 71 | + </el-button> | ||
| 72 | + </template> | ||
| 73 | + </el-table-column> | ||
| 74 | + </el-table> | ||
| 75 | + | ||
| 76 | + <!-- 分页 --> | ||
| 77 | + <el-pagination background layout="total, sizes, prev, pager, next" :current-page="pagination.current" | ||
| 78 | + :page-size="pagination.size" :total="pagination.total" @size-change="handleSizeChange" | ||
| 79 | + @current-change="handlePageChange" style="margin-top: 20px; text-align: right;" /> | ||
| 80 | + </el-card> | ||
| 81 | + | ||
| 82 | + <!-- 编辑组件 --> | ||
| 83 | + <edit-owner-invoice ref="editDialog" @success="fetchData" /> | ||
| 84 | + | ||
| 85 | + <!-- 删除组件 --> | ||
| 86 | + <delete-owner-invoice ref="deleteDialog" @success="fetchData" /> | ||
| 87 | + </div> | ||
| 88 | +</template> | ||
| 89 | + | ||
| 90 | +<script> | ||
| 91 | +import { listOwnerInvoice } from '@/api/fee/ownerInvoiceApi' | ||
| 92 | +import EditOwnerInvoice from '@/components/fee/editOwnerInvoice' | ||
| 93 | +import DeleteOwnerInvoice from '@/components/fee/deleteOwnerInvoice' | ||
| 94 | + | ||
| 95 | +export default { | ||
| 96 | + name: 'OwnerInvoiceList', | ||
| 97 | + components: { | ||
| 98 | + EditOwnerInvoice, | ||
| 99 | + DeleteOwnerInvoice | ||
| 100 | + }, | ||
| 101 | + data() { | ||
| 102 | + return { | ||
| 103 | + loading: false, | ||
| 104 | + searchForm: { | ||
| 105 | + ownerName: '', | ||
| 106 | + invoiceType: '', | ||
| 107 | + invoiceName: '' | ||
| 108 | + }, | ||
| 109 | + tableData: [], | ||
| 110 | + pagination: { | ||
| 111 | + current: 1, | ||
| 112 | + size: 10, | ||
| 113 | + total: 0 | ||
| 114 | + } | ||
| 115 | + } | ||
| 116 | + }, | ||
| 117 | + created() { | ||
| 118 | + this.fetchData() | ||
| 119 | + }, | ||
| 120 | + methods: { | ||
| 121 | + async fetchData() { | ||
| 122 | + this.loading = true | ||
| 123 | + try { | ||
| 124 | + const params = { | ||
| 125 | + ...this.searchForm, | ||
| 126 | + page: this.pagination.current, | ||
| 127 | + row: this.pagination.size | ||
| 128 | + } | ||
| 129 | + | ||
| 130 | + const response = await listOwnerInvoice(params) | ||
| 131 | + this.tableData = response.data | ||
| 132 | + this.pagination.total = response.total | ||
| 133 | + } catch (error) { | ||
| 134 | + this.$message.error(error.message || this.$t('common.fetchError')) | ||
| 135 | + } finally { | ||
| 136 | + this.loading = false | ||
| 137 | + } | ||
| 138 | + }, | ||
| 139 | + | ||
| 140 | + handleAdd() { | ||
| 141 | + this.$router.push('/views/fee/addOwnerInvoice') | ||
| 142 | + }, | ||
| 143 | + | ||
| 144 | + handleEdit(row) { | ||
| 145 | + this.$refs.editDialog.open({ ...row }) | ||
| 146 | + }, | ||
| 147 | + | ||
| 148 | + handleDelete(row) { | ||
| 149 | + this.$refs.deleteDialog.open(row) | ||
| 150 | + }, | ||
| 151 | + | ||
| 152 | + handlePageChange(page) { | ||
| 153 | + this.pagination.current = page | ||
| 154 | + this.fetchData() | ||
| 155 | + }, | ||
| 156 | + | ||
| 157 | + handleSizeChange(size) { | ||
| 158 | + this.pagination.size = size | ||
| 159 | + this.fetchData() | ||
| 160 | + } | ||
| 161 | + } | ||
| 162 | +} | ||
| 163 | +</script> | ||
| 164 | + | ||
| 165 | +<style lang="scss" scoped> | ||
| 166 | +.owner-invoice-container { | ||
| 167 | + padding: 20px; | ||
| 168 | + | ||
| 169 | + .search-card, | ||
| 170 | + .list-card { | ||
| 171 | + margin-bottom: 20px; | ||
| 172 | + } | ||
| 173 | + | ||
| 174 | + .clearfix { | ||
| 175 | + display: flex; | ||
| 176 | + justify-content: space-between; | ||
| 177 | + align-items: center; | ||
| 178 | + } | ||
| 179 | +} | ||
| 180 | +</style> | ||
| 0 | \ No newline at end of file | 181 | \ No newline at end of file |