index.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359
  1. <template>
  2. <ContentWrap>
  3. <el-form
  4. class="-mb-15px"
  5. :model="queryParams"
  6. ref="queryFormRef"
  7. :inline="true"
  8. label-width="120px"
  9. >
  10. <el-form-item label="所属商户" prop="merchantId">
  11. <el-select
  12. v-model="queryParams.merchantId"
  13. clearable
  14. @clear="
  15. () => {
  16. queryParams.merchantId = null
  17. }
  18. "
  19. filterable
  20. remote
  21. reserve-keyword
  22. placeholder="请选择所属商户"
  23. @change="handleGetAppListByMerchantId"
  24. :remote-method="handleGetMerchantListByName"
  25. :loading="merchantLoading"
  26. >
  27. <el-option
  28. v-for="item in merchantList"
  29. :key="item.id"
  30. :label="item.name"
  31. :value="item.id"
  32. />
  33. </el-select>
  34. </el-form-item>
  35. <el-form-item label="应用编号" prop="appId">
  36. <el-select clearable v-model="queryParams.appId" filterable placeholder="请选择应用信息">
  37. <el-option v-for="item in appList" :key="item.id" :label="item.name" :value="item.id" />
  38. </el-select>
  39. </el-form-item>
  40. <el-form-item label="渠道编码" prop="channelCode">
  41. <el-select
  42. v-model="queryParams.channelCode"
  43. placeholder="请输入渠道编码"
  44. clearable
  45. @clear="
  46. () => {
  47. queryParams.channelCode = null
  48. }
  49. "
  50. >
  51. <el-option
  52. v-for="dict in getDictOptions(DICT_TYPE.PAY_CHANNEL_CODE_TYPE)"
  53. :key="dict.value"
  54. :label="dict.label"
  55. :value="dict.value"
  56. />
  57. </el-select>
  58. </el-form-item>
  59. <el-form-item label="商户订单编号" prop="merchantOrderId">
  60. <el-input
  61. v-model="queryParams.merchantOrderId"
  62. placeholder="请输入商户订单编号"
  63. clearable
  64. @keyup.enter="handleQuery"
  65. />
  66. </el-form-item>
  67. <el-form-item label="渠道订单号" prop="channelOrderNo">
  68. <el-input
  69. v-model="queryParams.channelOrderNo"
  70. placeholder="请输入渠道订单号"
  71. clearable
  72. @keyup.enter="handleQuery"
  73. />
  74. </el-form-item>
  75. <el-form-item label="支付状态" prop="status">
  76. <el-select v-model="queryParams.status" placeholder="请选择支付状态" clearable size="small">
  77. <el-option
  78. v-for="dict in getDictOptions(DICT_TYPE.PAY_ORDER_STATUS)"
  79. :key="parseInt(dict.value)"
  80. :label="dict.label"
  81. :value="parseInt(dict.value)"
  82. />
  83. </el-select>
  84. </el-form-item>
  85. <el-form-item label="退款状态" prop="refundStatus">
  86. <el-select v-model="queryParams.refundStatus" placeholder="请选择退款状态" clearable>
  87. <el-option
  88. v-for="dict in getDictOptions(DICT_TYPE.PAY_ORDER_REFUND_STATUS)"
  89. :key="parseInt(dict.value)"
  90. :label="dict.label"
  91. :value="parseInt(dict.value)"
  92. />
  93. </el-select>
  94. </el-form-item>
  95. <el-form-item label="回调商户状态" prop="notifyStatus">
  96. <el-select
  97. v-model="queryParams.notifyStatus"
  98. placeholder="请选择订单回调商户状态"
  99. clearable
  100. >
  101. <el-option
  102. v-for="dict in getDictOptions(DICT_TYPE.PAY_ORDER_NOTIFY_STATUS)"
  103. :key="parseInt(dict.value)"
  104. :label="dict.label"
  105. :value="parseInt(dict.value)"
  106. />
  107. </el-select>
  108. </el-form-item>
  109. <el-form-item label="创建时间" prop="createTime">
  110. <el-date-picker
  111. v-model="queryParams.createTime"
  112. value-format="YYYY-MM-DD HH:mm:ss"
  113. type="daterange"
  114. start-placeholder="开始日期"
  115. end-placeholder="结束日期"
  116. :default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
  117. class="!w-240px"
  118. />
  119. </el-form-item>
  120. <el-form-item>
  121. <el-button @click="handleQuery">
  122. <Icon icon="ep:search" class="mr-5px" />
  123. 搜索
  124. </el-button>
  125. <el-button @click="resetQuery">
  126. <Icon icon="ep:refresh" class="mr-5px" />
  127. 重置
  128. </el-button>
  129. <el-button
  130. type="success"
  131. plain
  132. @click="handleExport"
  133. :loading="exportLoading"
  134. v-hasPermi="['system:tenant:export']"
  135. >
  136. <Icon icon="ep:download" class="mr-5px" />
  137. 导出
  138. </el-button>
  139. </el-form-item>
  140. </el-form>
  141. </ContentWrap>
  142. <content-wrap>
  143. <el-table v-loading="loading" :data="list">
  144. <el-table-column label="订单编号" align="center" prop="id" />
  145. <el-table-column label="商户名称" align="center" prop="merchantName" width="120" />
  146. <el-table-column label="应用名称" align="center" prop="appName" width="120" />
  147. <el-table-column label="渠道名称" align="center" prop="channelCodeName" width="120" />
  148. <el-table-column label="渠道订单号" align="center" prop="merchantOrderId" width="120" />
  149. <el-table-column label="商品标题" align="center" prop="subject" width="250" />
  150. <el-table-column label="商品描述" align="center" prop="body" width="250" />
  151. <el-table-column label="异步通知地址" align="center" prop="notifyUrl" width="250" />
  152. <el-table-column label="回调状态" align="center" prop="notifyStatus">
  153. <template #default="scope">
  154. <dict-tag :type="DICT_TYPE.COMMON_STATUS" :value="scope.row.status" />
  155. </template>
  156. </el-table-column>
  157. <el-table-column label="支付订单" align="left">
  158. <template #default="scope">
  159. <p class="order-font">
  160. <el-tag size="small">商户</el-tag>
  161. {{ scope.row.merchantOrderId }}
  162. </p>
  163. <p class="order-font">
  164. <el-tag size="small" type="warning">支付</el-tag>
  165. {{ scope.row.channelOrderNo }}
  166. </p>
  167. </template>
  168. </el-table-column>
  169. <el-table-column label="支付金额" align="center" prop="amount">
  170. <template #default="scope">
  171. ¥{{ parseFloat(scope.row.amount / 100).toFixed(2) }}
  172. </template>
  173. </el-table-column>
  174. <el-table-column label="手续金额" align="center" prop="channelFeeAmount">
  175. <template #default="scope">
  176. ¥{{ parseFloat(scope.row.channelFeeAmount / 100).toFixed(2) }}
  177. </template>
  178. </el-table-column>
  179. <el-table-column label="退款金额" align="center" prop="refundAmount">
  180. <template #default="scope">
  181. ¥{{ parseFloat(scope.row.refundAmount / 100).toFixed(2) }}
  182. </template>
  183. </el-table-column>
  184. <el-table-column label="支付状态" align="center" prop="status">
  185. <template #default="scope">
  186. <dict-tag :type="DICT_TYPE.PAY_ORDER_STATUS" :value="scope.row.status" />
  187. </template>
  188. </el-table-column>
  189. <el-table-column label="回调状态" align="center" prop="notifyStatus">
  190. <template #default="scope">
  191. <dict-tag :type="DICT_TYPE.PAY_ORDER_NOTIFY_STATUS" :value="scope.row.notifyStatus" />
  192. </template>
  193. </el-table-column>
  194. <el-table-column
  195. label="创建时间"
  196. align="center"
  197. prop="createTime"
  198. width="100"
  199. :formatter="dateFormatter"
  200. />
  201. <el-table-column
  202. label="支付时间"
  203. align="center"
  204. prop="successTime"
  205. width="100"
  206. :formatter="dateFormatter"
  207. />
  208. <el-table-column
  209. label="操作"
  210. align="center"
  211. fixed="right"
  212. class-name="small-padding fixed-width"
  213. >
  214. <template #default="scope">
  215. <el-button
  216. size="small"
  217. type="text"
  218. icon="el-icon-search"
  219. @click="openForm(scope.row.id)"
  220. v-hasPermi="['pay:order:query']"
  221. >查看详情
  222. </el-button>
  223. </template>
  224. </el-table-column>
  225. </el-table>
  226. <!-- 分页组件 -->
  227. <!-- 分页 -->
  228. <Pagination
  229. :total="total"
  230. v-model:page="queryParams.pageNo"
  231. v-model:limit="queryParams.pageSize"
  232. @pagination="getList"
  233. />
  234. </content-wrap>
  235. <!-- 表单弹窗:预览 -->
  236. <OrderForm ref="formRef" @success="getList" />
  237. </template>
  238. <script setup lang="ts" name="Order">
  239. import { DICT_TYPE, getDictOptions } from '@/utils/dict'
  240. import ContentWrap from '@/components/ContentWrap/src/ContentWrap.vue'
  241. import * as MerchantApi from '@/api/pay/merchant'
  242. import * as OrderApi from '@/api/pay/order'
  243. import download from '@/utils/download'
  244. import * as AppApi from '@/api/pay/app'
  245. import { dateFormatter } from '@/utils/formatTime'
  246. import OrderForm from '@/views/pay/order/orderForm.vue'
  247. const message = useMessage() // 消息弹窗
  248. // const { t } = useI18n() // 国际化
  249. const queryFormRef = ref() // 搜索的表单
  250. const merchantList = ref([]) // 商户列表
  251. const merchantLoading = ref(false) // 商户加载遮罩层
  252. const appList = ref([]) // 支付应用列表集合
  253. const loading = ref(false) // 列表的加载中
  254. const exportLoading = ref(false) // 导出等待
  255. const total = ref(0) // 列表的总页数
  256. const list = ref([]) // 列表的数据
  257. const queryParams = reactive({
  258. pageNo: 1,
  259. pageSize: 10,
  260. merchantId: undefined,
  261. appId: undefined,
  262. channelId: undefined,
  263. channelCode: undefined,
  264. merchantOrderId: undefined,
  265. subject: undefined,
  266. body: undefined,
  267. notifyUrl: undefined,
  268. notifyStatus: undefined,
  269. amount: undefined,
  270. channelFeeRate: undefined,
  271. channelFeeAmount: undefined,
  272. status: undefined,
  273. userIp: undefined,
  274. successExtensionId: undefined,
  275. refundStatus: undefined,
  276. refundTimes: undefined,
  277. refundAmount: undefined,
  278. channelUserId: undefined,
  279. channelOrderNo: undefined,
  280. expireTime: [],
  281. successTime: [],
  282. notifyTime: [],
  283. createTime: []
  284. })
  285. /**
  286. * 根据商户名称模糊匹配商户信息
  287. * @param name 商户名称
  288. */
  289. const handleGetMerchantListByName = async (name) => {
  290. merchantList.value = await MerchantApi.getMerchantListByName(name)
  291. }
  292. /**
  293. * 根据商户 ID 查询支付应用信息
  294. */
  295. const handleGetAppListByMerchantId = () => {
  296. queryParams.appId = undefined
  297. if (queryParams.merchantId) {
  298. AppApi.getAppListByMerchantId(queryParams.merchantId).then((response) => {
  299. appList.value = response.data
  300. })
  301. }
  302. }
  303. /** 搜索按钮操作 */
  304. const handleQuery = () => {
  305. queryParams.pageNo = 1
  306. getList()
  307. }
  308. /** 查询列表 */
  309. const getList = async () => {
  310. loading.value = true
  311. try {
  312. const data = await OrderApi.getOrderPage(queryParams)
  313. list.value = data.list
  314. total.value = data.total
  315. } finally {
  316. loading.value = false
  317. }
  318. }
  319. /** 重置按钮操作 */
  320. const resetQuery = () => {
  321. queryFormRef.value.resetFields()
  322. handleQuery()
  323. }
  324. /** 导出按钮操作 */
  325. const handleExport = async () => {
  326. // 处理查询参数
  327. // 导出的二次确认
  328. await message.exportConfirm()
  329. // 发起导出
  330. exportLoading.value = true
  331. const data = await OrderApi.exportOrder(queryParams)
  332. download.excel(data, '支付订单.xls')
  333. }
  334. /** 预览详情 */
  335. const formRef = ref()
  336. const openForm = (id?: number) => {
  337. formRef.value.open(id)
  338. }
  339. /** 初始化 **/
  340. onMounted(async () => {
  341. await getList()
  342. })
  343. </script>
  344. <style>
  345. .order-font {
  346. font-size: 12px;
  347. padding: 2px 0;
  348. }
  349. </style>