index.vue 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. <template>
  2. <div class="page-container">
  3. <PageTitle title="对账单管理" />
  4. <SearchBar :form="searchForm" :filters="filters" placeholder="对账编号" />
  5. <el-table v-loading="loading" :data="tableData" border style="width: 100%">
  6. <el-table-column prop="billNo" label="对账编号" min-width="130" align="center" />
  7. <el-table-column prop="billDate" label="对账日期" min-width="110" align="center">
  8. <template #default="{ row }">{{ parseTime(row.billDate, '{y}-{m}-{d}') }}</template>
  9. </el-table-column>
  10. <el-table-column prop="amount" label="对账单金额" min-width="110" align="center">
  11. <template #default="{ row }">¥{{ row.amount.toFixed(2) }}</template>
  12. </el-table-column>
  13. <el-table-column prop="billStatus" label="对账状态" min-width="90" align="center">
  14. <template #default="{ row }">
  15. {{ getDictLabel(statement_status, row.billStatus) }}
  16. </template>
  17. </el-table-column>
  18. <el-table-column prop="invoiceStatus" label="开票状态" min-width="90" align="center">
  19. <template #default="{ row }">
  20. <span :style="{ color: row.invoiceStatus === '0' ? '#e60012' : '' }">
  21. {{ getDictLabel(invoice_issuance_status, row.invoiceStatus) }}
  22. </span>
  23. </template>
  24. </el-table-column>
  25. <el-table-column prop="payStatus" label="支付状态" min-width="90" align="center">
  26. <template #default="{ row }">
  27. {{ getDictLabel(payment_status, row.payStatus) }}
  28. </template>
  29. </el-table-column>
  30. <el-table-column label="操作" width="100" align="center">
  31. <template #default="{ row }">
  32. <el-button type="primary" link size="small" @click="handleView(row)">查看</el-button>
  33. <el-button type="danger" link size="small" @click="handleConfirm(row)" :disabled="row.billStatus !== '1'">确认</el-button>
  34. </template>
  35. </el-table-column>
  36. </el-table>
  37. <div class="pagination-wrapper">
  38. <TablePagination v-model:page="pagination.page" v-model:pageSize="pagination.pageSize" :total="pagination.total" />
  39. </div>
  40. <!-- 详情弹窗 -->
  41. <DetailDialog ref="detailDialogRef" />
  42. </div>
  43. </template>
  44. <script setup lang="ts">
  45. import { reactive, ref, onMounted, watch } from 'vue';
  46. import { ElMessage, ElMessageBox } from 'element-plus';
  47. import { PageTitle, SearchBar, TablePagination } from '@/components';
  48. import { getStatementList, getStatementInfo, confirmStatement } from '@/api/pc/enterprise/statement';
  49. import type { StatementOrder } from '@/api/pc/enterprise/statementTypes';
  50. import DetailDialog from './detail.vue';
  51. const detailDialogRef = ref<InstanceType<typeof DetailDialog>>();
  52. const { proxy } = getCurrentInstance() as ComponentInternalInstance;
  53. const { invoice_issuance_status, statement_status, payment_status } = toRefs<any>(
  54. proxy?.useDict('invoice_issuance_status', 'statement_status', 'payment_status')
  55. );
  56. const searchForm = reactive({
  57. keyword: '', // 对账编号
  58. dateRange: [],
  59. billStatus: '',
  60. invoiceStatus: '',
  61. payStatus: ''
  62. });
  63. const billStatusOptions = ref([{ label: '全部', value: '' }]);
  64. const invoiceStatusOptions = ref([{ label: '全部', value: '' }]);
  65. const payStatusOptions = ref([{ label: '全部', value: '' }]);
  66. // 状态值到文本的映射
  67. const billStatusMap = ref<Record<string, string>>({});
  68. const invoiceStatusMap = ref<Record<string, string>>({});
  69. const payStatusMap = ref<Record<string, string>>({});
  70. const filters = ref([
  71. { field: 'billStatus', label: '对账状态', options: billStatusOptions.value },
  72. { field: 'invoiceStatus', label: '开票状态', options: invoiceStatusOptions.value },
  73. { field: 'payStatus', label: '支付状态', options: payStatusOptions.value }
  74. ]);
  75. const pagination = reactive({ page: 1, pageSize: 5, total: 0 });
  76. const tableData = ref<any[]>([]);
  77. const loading = ref(false);
  78. // 加载对账单列表
  79. const loadStatementList = async () => {
  80. try {
  81. loading.value = true;
  82. const res = await getStatementList({
  83. pageNum: pagination.page,
  84. pageSize: pagination.pageSize,
  85. statementOrderNo: searchForm.keyword,
  86. statementStatus: searchForm.billStatus,
  87. isInvoiceStatus: searchForm.invoiceStatus,
  88. isPaymentStatus: searchForm.payStatus
  89. });
  90. if (res.code === 200 && res.rows) {
  91. tableData.value = res.rows.map((item: StatementOrder) => ({
  92. id: item.id,
  93. billNo: item.statementOrderNo,
  94. billDate: item.statementDate,
  95. amount: parseFloat(item.amount as any) || 0,
  96. billStatus: item.statementStatus,
  97. invoiceStatus: item.isInvoiceStatus,
  98. payStatus: item.isPaymentStatus
  99. }));
  100. pagination.total = res.total || 0;
  101. }
  102. } catch (error) {
  103. console.error('加载对账单列表失败:', error);
  104. ElMessage.error('加载对账单列表失败');
  105. } finally {
  106. loading.value = false;
  107. }
  108. };
  109. // 监听分页变化
  110. watch(
  111. () => [pagination.page, pagination.pageSize],
  112. () => {
  113. loadStatementList();
  114. }
  115. );
  116. // 监听搜索条件变化
  117. watch(
  118. () => [searchForm.keyword, searchForm.billStatus, searchForm.invoiceStatus, searchForm.payStatus],
  119. () => {
  120. pagination.page = 1;
  121. loadStatementList();
  122. }
  123. );
  124. const getDictLabel = (dictOptions: any[], value: string) => {
  125. if (!dictOptions || !value) return value;
  126. const dict = dictOptions.find((item) => item.value === value);
  127. return dict ? dict.label : value;
  128. };
  129. // 加载字典数据
  130. // 页面加载时获取数据
  131. onMounted(() => {
  132. loadStatementList();
  133. });
  134. const handleView = (row: any) => {
  135. if (detailDialogRef.value) {
  136. detailDialogRef.value.open(row.id);
  137. }
  138. };
  139. const handleConfirm = async (row: any) => {
  140. try {
  141. await ElMessageBox.confirm(`确定要确认对账单"${row.billNo}"吗?`, '提示', {
  142. confirmButtonText: '确定',
  143. cancelButtonText: '取消',
  144. type: 'warning'
  145. });
  146. await confirmStatement({ id: row.id });
  147. row.billStatus = '2';
  148. ElMessage.success('确认成功');
  149. loadStatementList();
  150. } catch (error) {
  151. if (error !== 'cancel') {
  152. console.error('确认对账单失败:', error);
  153. ElMessage.error('确认对账单失败');
  154. }
  155. }
  156. };
  157. </script>
  158. <style scoped>
  159. .pagination-wrapper {
  160. margin-top: 16px;
  161. display: flex;
  162. justify-content: flex-end;
  163. }
  164. </style>