index.vue 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. <template>
  2. <div class="app-container">
  3. <!-- 搜索栏 -->
  4. <el-card shadow="never" class="mb16 filter-card">
  5. <el-form :model="queryParams" ref="queryForm" :inline="true" size="small">
  6. <el-form-item label="租户名称" prop="tenantId">
  7. <inline-tenant-selector @change="handleTenantChange" />
  8. </el-form-item>
  9. <el-form-item>
  10. <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">查询</el-button>
  11. <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
  12. </el-form-item>
  13. </el-form>
  14. </el-card>
  15. <!-- 操作栏 -->
  16. <el-row :gutter="10" class="mb8">
  17. <el-col :span="1.5">
  18. <el-button type="warning" plain icon="el-icon-download" size="mini" :loading="exportLoading" @click="handleExport">导出</el-button>
  19. </el-col>
  20. <right-toolbar :showSearch.sync="showSearch" @queryTable="getList" />
  21. </el-row>
  22. <!-- 表格 -->
  23. <el-table v-loading="loading" :data="orderList" border size="small" style="width:100%">
  24. <el-table-column label="订单ID" align="center" prop="orderId" min-width="70" />
  25. <el-table-column label="所属租户" align="center" prop="companyName" min-width="120" />
  26. <el-table-column label="套餐名称" align="center" prop="packageName" min-width="120" />
  27. <el-table-column label="购买条数" align="center" prop="smsCount" min-width="90">
  28. <template slot-scope="scope">
  29. <span style="font-weight:bold">{{ scope.row.smsCount || 0 }}</span>
  30. </template>
  31. </el-table-column>
  32. <el-table-column label="金额" align="center" prop="amount" min-width="100">
  33. <template slot-scope="scope">
  34. <span style="color:#fa8c16;font-weight:bold">¥{{ scope.row.amount ? Number(scope.row.amount).toFixed(2) : '0.00' }}</span>
  35. </template>
  36. </el-table-column>
  37. <el-table-column label="购买时间" align="center" prop="createTime" min-width="150" />
  38. <el-table-column label="状态" align="center" min-width="85">
  39. <template slot-scope="scope">
  40. <el-tag v-if="scope.row.status === '0' || scope.row.status === 0" type="success" size="mini">成功</el-tag>
  41. <el-tag v-else-if="scope.row.status === '1' || scope.row.status === 1" type="warning" size="mini">待支付</el-tag>
  42. <el-tag v-else-if="scope.row.status === '2' || scope.row.status === 2" type="danger" size="mini">已取消</el-tag>
  43. <el-tag v-else type="info" size="mini">{{ scope.row.status }}</el-tag>
  44. </template>
  45. </el-table-column>
  46. </el-table>
  47. <pagination v-show="total>0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" @pagination="getList" />
  48. <!-- 详情弹窗 -->
  49. <el-dialog title="订单详情" :visible.sync="detailVisible" width="550px" append-to-body>
  50. <el-descriptions :column="2" border size="small">
  51. <el-descriptions-item label="订单ID">{{ detail.orderId }}</el-descriptions-item>
  52. <el-descriptions-item label="所属租户">{{ detail.companyName || '-' }}</el-descriptions-item>
  53. <el-descriptions-item label="套餐名称">{{ detail.packageName || '-' }}</el-descriptions-item>
  54. <el-descriptions-item label="购买条数">
  55. <span style="font-weight:bold">{{ detail.smsCount || 0 }}</span>
  56. </el-descriptions-item>
  57. <el-descriptions-item label="金额">
  58. <span style="color:#fa8c16;font-weight:bold">¥{{ detail.amount ? Number(detail.amount).toFixed(2) : '0.00' }}</span>
  59. </el-descriptions-item>
  60. <el-descriptions-item label="状态">
  61. <el-tag v-if="detail.status === '0' || detail.status === 0" type="success" size="mini">成功</el-tag>
  62. <el-tag v-else-if="detail.status === '1' || detail.status === 1" type="warning" size="mini">待支付</el-tag>
  63. <el-tag v-else-if="detail.status === '2' || detail.status === 2" type="danger" size="mini">已取消</el-tag>
  64. <el-tag v-else type="info" size="mini">{{ detail.status }}</el-tag>
  65. </el-descriptions-item>
  66. <el-descriptions-item label="购买时间">{{ detail.createTime || '-' }}</el-descriptions-item>
  67. <el-descriptions-item label="支付方式">{{ detail.payMethod || '-' }}</el-descriptions-item>
  68. <el-descriptions-item label="交易流水号" :span="2">{{ detail.txnNo || '-' }}</el-descriptions-item>
  69. <el-descriptions-item label="备注" :span="2">{{ detail.remark || '-' }}</el-descriptions-item>
  70. </el-descriptions>
  71. </el-dialog>
  72. </div>
  73. </template>
  74. <script>
  75. import request from '@/utils/request'
  76. import InlineTenantSelector from '@/components/InlineTenantSelector'
  77. export default {
  78. name: 'AdminSmsOrder',
  79. components: { InlineTenantSelector },
  80. data() {
  81. return {
  82. loading: false,
  83. exportLoading: false,
  84. showSearch: true,
  85. total: 0,
  86. orderList: [],
  87. queryParams: {
  88. pageNum: 1,
  89. pageSize: 10,
  90. tenantId: null
  91. },
  92. detailVisible: false,
  93. detail: {}
  94. }
  95. },
  96. created() {
  97. this.getList()
  98. },
  99. methods: {
  100. getList() {
  101. if (!this.queryParams.tenantId) {
  102. this.orderList = []
  103. this.total = 0
  104. this.loading = false
  105. return
  106. }
  107. this.loading = true
  108. request({
  109. url: '/admin/sms-order/list',
  110. method: 'get',
  111. params: this.queryParams
  112. }).then(res => {
  113. this.orderList = res.rows || []
  114. this.total = res.total || 0
  115. this.loading = false
  116. }).catch(() => { this.loading = false })
  117. },
  118. handleQuery() {
  119. if (!this.queryParams.tenantId) {
  120. this.$message.warning('请先选择租户')
  121. return
  122. }
  123. this.queryParams.pageNum = 1
  124. this.getList()
  125. },
  126. handleTenantChange(val) {
  127. this.queryParams.tenantId = val || null
  128. this.handleQuery()
  129. },
  130. resetQuery() {
  131. this.resetForm('queryForm')
  132. this.queryParams.tenantId = null
  133. this.handleQuery()
  134. },
  135. handleDetail(row) {
  136. request({
  137. url: '/admin/sms-order/' + row.orderId,
  138. method: 'get'
  139. }).then(res => {
  140. this.detail = res.data || {}
  141. this.detailVisible = true
  142. })
  143. },
  144. handleExport() {
  145. this.exportLoading = true
  146. request({
  147. url: '/admin/sms-order/export',
  148. method: 'get',
  149. params: this.queryParams,
  150. responseType: 'blob'
  151. }).then(res => {
  152. const blob = new Blob([res], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' })
  153. const link = document.createElement('a')
  154. link.href = URL.createObjectURL(blob)
  155. link.download = '短信订单.xlsx'
  156. link.click()
  157. URL.revokeObjectURL(link.href)
  158. }).catch(() => {
  159. this.$message.error('导出失败')
  160. }).finally(() => { this.exportLoading = false })
  161. }
  162. }
  163. }
  164. </script>
  165. <style scoped>
  166. .mb8 { margin-bottom: 8px; }
  167. .mb16 { margin-bottom: 16px; }
  168. .filter-card { padding-bottom: 0; }
  169. </style>