index.vue 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. <template>
  2. <div class="invoice-manage-container">
  3. <div class="page-title"><i class="title-bar"></i><span>发票管理</span></div>
  4. <!-- 搜索栏 -->
  5. <div class="search-bar">
  6. <el-input v-model="queryParams.keyword" placeholder="搜索" style="width: 200px" clearable>
  7. <template #prefix><el-icon><Search /></el-icon></template>
  8. </el-input>
  9. <el-select v-model="queryParams.searchType" placeholder="账户名称" style="width: 120px">
  10. <el-option label="账户名称" value="accountName" />
  11. <el-option label="发票抬头" value="invoiceTitle" />
  12. <el-option label="纳税人识别号" value="taxNo" />
  13. </el-select>
  14. <div class="search-right"><el-button type="danger" @click="handleAdd">新增开票信息</el-button></div>
  15. </div>
  16. <!-- 表格 -->
  17. <el-table :data="tableData" border style="width: 100%" :resizable="false">
  18. <el-table-column prop="bankName" label="开户银行" width="140" show-overflow-tooltip :resizable="false" />
  19. <el-table-column prop="bankAccount" label="开户账户" width="140" :resizable="false" />
  20. <el-table-column prop="taxId" label="纳税人识别号" width="160" :resizable="false" />
  21. <el-table-column prop="address" label="地址" min-width="140" show-overflow-tooltip :resizable="false" />
  22. <el-table-column prop="phone" label="电话" width="120" :resizable="false" />
  23. <el-table-column label="操作" width="120" fixed="right" :resizable="false">
  24. <template #default="{ row }">
  25. <div style="display: flex; gap: 8px; justify-content: center;">
  26. <el-button type="primary" link @click="handleEdit(row)">修改</el-button>
  27. <el-button type="danger" link @click="handleDelete(row)">删除</el-button>
  28. </div>
  29. </template>
  30. </el-table-column>
  31. </el-table>
  32. <!-- 分页 -->
  33. <div class="pagination-wrap">
  34. <span class="total-text">共计 {{ total }} 条</span>
  35. <el-pagination v-model:current-page="queryParams.pageNum" v-model:page-size="queryParams.pageSize"
  36. :page-sizes="[10, 20, 50]" :total="total" layout="prev, pager, next, sizes, jumper"
  37. @size-change="handleQuery" @current-change="handleQuery" />
  38. </div>
  39. <!-- 新增/编辑弹窗 -->
  40. <el-dialog v-model="dialogVisible" :title="dialogTitle" width="550px">
  41. <el-form ref="formRef" :model="form" :rules="rules" label-width="120px">
  42. <el-form-item label="发票抬头" prop="invoiceTitle"><el-input v-model="form.invoiceTitle" placeholder="请输入发票抬头" /></el-form-item>
  43. <el-form-item label="纳税人识别号" prop="taxNo"><el-input v-model="form.taxNo" placeholder="请输入纳税人识别号" /></el-form-item>
  44. <el-form-item label="开户银行" prop="bankName"><el-input v-model="form.bankName" placeholder="请输入开户银行" /></el-form-item>
  45. <el-form-item label="开户账户" prop="bankAccount"><el-input v-model="form.bankAccount" placeholder="请输入开户账户" /></el-form-item>
  46. <el-form-item label="地址" prop="address"><el-input v-model="form.address" placeholder="请输入地址" /></el-form-item>
  47. <el-form-item label="电话" prop="phone"><el-input v-model="form.phone" placeholder="请输入电话" /></el-form-item>
  48. </el-form>
  49. <template #footer>
  50. <el-button @click="dialogVisible = false">取消</el-button>
  51. <el-button type="danger" @click="handleSave">确定</el-button>
  52. </template>
  53. </el-dialog>
  54. </div>
  55. </template>
  56. <script setup lang="ts">
  57. import { ref, reactive, onMounted } from 'vue'
  58. import { Search } from '@element-plus/icons-vue'
  59. import { ElMessage, ElMessageBox } from 'element-plus'
  60. import { getInvoiceList, addInvoice, updateInvoice, deleteInvoice } from '@/api/pc/enterprise'
  61. const dialogVisible = ref(false)
  62. const dialogTitle = ref('新增开票信息')
  63. const formRef = ref()
  64. const editingId = ref<number | null>(null)
  65. const total = ref(0)
  66. const queryParams = reactive({ pageNum: 1, pageSize: 10, keyword: '', searchType: 'accountName' })
  67. const form = reactive({ invoiceTitle: '', taxNo: '', bankName: '', bankAccount: '', address: '', phone: '', bankId: null, bankCode: '' })
  68. const rules = {
  69. invoiceTitle: [{ required: true, message: '请输入发票抬头', trigger: 'blur' }],
  70. taxNo: [{ required: true, message: '请输入纳税人识别号', trigger: 'blur' }],
  71. bankName: [{ required: true, message: '请输入开户银行', trigger: 'blur' }],
  72. bankAccount: [{ required: true, message: '请输入开户账户', trigger: 'blur' }]
  73. }
  74. const tableData = ref([])
  75. // 加载发票列表
  76. const loadInvoiceList = async () => {
  77. try {
  78. const res = await getInvoiceList(queryParams)
  79. if (res.code === 200) {
  80. tableData.value = res.rows || []
  81. total.value = res.total || 0
  82. }
  83. } catch (error) {
  84. console.error('加载发票列表失败:', error)
  85. ElMessage.error('加载发票列表失败')
  86. }
  87. }
  88. onMounted(() => { loadInvoiceList() })
  89. const handleQuery = () => { loadInvoiceList() }
  90. const resetForm = () => { form.invoiceTitle = ''; form.taxNo = ''; form.bankName = ''; form.bankAccount = ''; form.address = ''; form.phone = ''; form.bankId = null; form.bankCode = ''; editingId.value = null }
  91. const handleAdd = () => { resetForm(); dialogTitle.value = '新增开票信息'; dialogVisible.value = true }
  92. const handleEdit = (row: any) => { editingId.value = row.id; form.invoiceTitle = row.invoiceTitle || ''; form.taxNo = row.taxId; form.bankName = row.bankName; form.bankAccount = row.bankAccount; form.address = row.address; form.phone = row.phone; form.bankId = row.bankId; form.bankCode = row.bankCode || ''; dialogTitle.value = '编辑开票信息'; dialogVisible.value = true }
  93. const handleSave = async () => {
  94. const valid = await formRef.value?.validate();
  95. if (!valid) return;
  96. try {
  97. const data: any = {
  98. taxId: form.taxNo,
  99. bankName: form.bankName,
  100. bankAccount: form.bankAccount,
  101. address: form.address,
  102. phone: form.phone,
  103. bankId: form.bankId || 0,
  104. bankCode: form.bankCode || 'DEFAULT'
  105. }
  106. console.log('发送的数据:', data)
  107. if (editingId.value) {
  108. data.id = editingId.value
  109. await updateInvoice(data)
  110. } else {
  111. await addInvoice(data)
  112. }
  113. ElMessage.success(editingId.value ? '修改成功' : '新增成功')
  114. dialogVisible.value = false
  115. loadInvoiceList()
  116. } catch (error) {
  117. console.error('保存失败:', error)
  118. ElMessage.error('操作失败')
  119. }
  120. }
  121. const handleDelete = (row: any) => {
  122. ElMessageBox.confirm('确定要删除该开票信息吗?', '提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' }).then(async () => {
  123. try {
  124. await deleteInvoice([row.id])
  125. ElMessage.success('删除成功')
  126. loadInvoiceList()
  127. } catch (error) {
  128. ElMessage.error('删除失败')
  129. }
  130. })
  131. }
  132. </script>
  133. <style scoped lang="scss">
  134. .invoice-manage-container { padding: 20px; background: #fff; min-height: 100%; }
  135. .page-title { font-size: 16px; font-weight: bold; display: flex; align-items: center; gap: 8px; margin-bottom: 20px; }
  136. .title-bar { display: inline-block; width: 3px; height: 16px; background: #e60012; border-radius: 2px; }
  137. .search-bar { display: flex; align-items: center; gap: 10px; margin-bottom: 20px; .search-right { flex: 1; display: flex; justify-content: flex-end; } }
  138. .pagination-wrap { display: flex; justify-content: space-between; align-items: center; margin-top: 20px; .total-text { font-size: 14px; color: #666; } }
  139. </style>