|
|
@@ -0,0 +1,261 @@
|
|
|
+<style scoped lang="scss">
|
|
|
+.system-container {
|
|
|
+
|
|
|
+ :deep(.el-card__body) {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ justify-content: space-between;
|
|
|
+ flex: 1;
|
|
|
+ overflow: auto;
|
|
|
+
|
|
|
+ .el-table {
|
|
|
+ flex: 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.page-content {
|
|
|
+ margin-bottom: 20px;
|
|
|
+}
|
|
|
+
|
|
|
+.page-pager {
|
|
|
+ background-color: var(--el-color-white);
|
|
|
+ height: 24px;
|
|
|
+}
|
|
|
+</style>
|
|
|
+<template>
|
|
|
+ <div class="system-container layout-padding">
|
|
|
+ <el-card shadow="hover" class="layout-padding-auto">
|
|
|
+ <ext-query-form
|
|
|
+ class="page-search"
|
|
|
+ ref="queryRef"
|
|
|
+ v-model="state.formQuery"
|
|
|
+ :columns="state.columns"
|
|
|
+ :import-config="state.importConfig"
|
|
|
+ :export-config="state.exportConfig"
|
|
|
+ @on-change="loadData(true)"
|
|
|
+ @imported="loadData(true)">
|
|
|
+ <!-- <template #extraQuery></template>
|
|
|
+ <template #extraLeft></template>
|
|
|
+ <template #extraRight></template>-->
|
|
|
+ <template #extQuery>
|
|
|
+ </template>
|
|
|
+ </ext-query-form>
|
|
|
+
|
|
|
+ <el-table
|
|
|
+ border
|
|
|
+ stripe="stripe"
|
|
|
+ :height="state.tableData.height"
|
|
|
+ highlight-current-row
|
|
|
+ current-row-key="id"
|
|
|
+ row-key="id"
|
|
|
+ @on-row-click="handleRowClick('view',$event)"
|
|
|
+ :data="state.tableData.data"
|
|
|
+ v-loading="state.tableData.loading">
|
|
|
+ <template #empty>
|
|
|
+ <el-empty></el-empty>
|
|
|
+ </template>
|
|
|
+ <el-table-column
|
|
|
+ v-for="field in state.columns"
|
|
|
+ :key="field.prop"
|
|
|
+ :type="field.type"
|
|
|
+ :label="field.label"
|
|
|
+ :column-key="field.prop"
|
|
|
+ :width="field.width"
|
|
|
+ :min-width="field.minWidth"
|
|
|
+ :fixed="field.fixed"
|
|
|
+ :sortable="field.sortable"
|
|
|
+ :show-overflow-tooltip="!field.fixed&&field.width>150">
|
|
|
+
|
|
|
+ <template #default="{row}">
|
|
|
+ <template v-if="field.prop==='name'">
|
|
|
+ <div class="cursor-pointer" style="color:var(--el-color-primary-light-1)"
|
|
|
+ @click="handleRowClick('view', row)">
|
|
|
+ {{ row[field.prop] }}
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ <template v-else-if="field.prop==='fundsAccount'">
|
|
|
+ <ext-d-label type="RefundLog.fundsAccount" :model-value="row[field.prop]"></ext-d-label>
|
|
|
+ </template>
|
|
|
+ <template v-else-if="field.prop==='status'">
|
|
|
+ <ext-d-label type="RefundLog.status" :model-value="row[field.prop]"></ext-d-label>
|
|
|
+ </template>
|
|
|
+ <template v-else-if="['total','refund','discountAmount'].includes(field.prop)">
|
|
|
+ {{ u.fmt.fmtMoney(row[field.prop]) }}
|
|
|
+ </template>
|
|
|
+ <template v-else-if="['createTime','updateTime'].includes(field.prop)">
|
|
|
+ {{ u.fmt.fmtDateTime(row[field.prop]) }}
|
|
|
+ </template>
|
|
|
+ <template v-else-if="field.prop==='action'">
|
|
|
+ <el-button v-if="row.status==='NEW'" v-auth="'refundLog.modify'" type="warning" size="small" text @click="handleRefundDealClick(row)"> 退款处理</el-button>
|
|
|
+ </template>
|
|
|
+ <template v-else>
|
|
|
+ <div>{{ row[field.prop] }}</div>
|
|
|
+ </template>
|
|
|
+
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ </el-table>
|
|
|
+
|
|
|
+ <ext-page class="page-pager" v-model:value="state.pageQuery" @change="loadData(false)"/>
|
|
|
+ </el-card>
|
|
|
+ </div>
|
|
|
+ <!-- <RefundLogDialog ref="refundLogDialogRef" @refresh="loadData(true)"/>-->
|
|
|
+</template>
|
|
|
+
|
|
|
+<script setup lang="ts" name="RefundLogList">
|
|
|
+import {defineAsyncComponent, reactive, onMounted, onBeforeMount, ref, getCurrentInstance, nextTick, onBeforeUnmount} from 'vue';
|
|
|
+import {$body, $get} from "/@/utils/request";
|
|
|
+import u from '/@/utils/u'
|
|
|
+import {Msg} from "/@/utils/message";
|
|
|
+import {Session} from "/@/utils/storage";
|
|
|
+
|
|
|
+
|
|
|
+import ExtPage from '/@/components/form/ExtPage.vue'
|
|
|
+import ExtQueryForm from "/@/components/form/ExtQueryForm.vue";
|
|
|
+import ExtTable from "/@/components/form/ExtTable.vue";
|
|
|
+
|
|
|
+import mittBus from '/@/utils/mitt';
|
|
|
+
|
|
|
+import {ElButton} from 'element-plus'
|
|
|
+import ExtDLabel from "/@/components/form/ExtDLabel.vue";
|
|
|
+
|
|
|
+
|
|
|
+// const RefundLogDialog = defineAsyncComponent(() => import("/@/views/page/RefundLogDialog.vue"));
|
|
|
+
|
|
|
+//定义引用
|
|
|
+const queryRef = ref();
|
|
|
+const refundLogDialogRef = ref();
|
|
|
+
|
|
|
+//定义变量
|
|
|
+const state = reactive({
|
|
|
+ formQuery: {},
|
|
|
+ pageQuery: {
|
|
|
+ pageNum: 1,
|
|
|
+ pageSize: 10,
|
|
|
+ total: 0
|
|
|
+ },
|
|
|
+ tableData: {
|
|
|
+ height: 500,
|
|
|
+ data: [] as Array<any>,
|
|
|
+ loading: false
|
|
|
+ },
|
|
|
+ importConfig: {},
|
|
|
+ exportConfig: {},
|
|
|
+ columns: [
|
|
|
+ {label: '微信支付退款单号', width: 180, prop: 'refundId', query: true, type: 'text', resizable: true},
|
|
|
+ {label: '商户退款单号', width: 180, prop: 'outRefundNo', query: true, type: 'text', resizable: true},
|
|
|
+ {label: '微信支付订单号', width: 180, prop: 'transactionId', query: true, type: 'text', resizable: true},
|
|
|
+ {label: '商户订单号', width: 180, prop: 'outTradeNo', query: true, type: 'text', resizable: true},
|
|
|
+ {label: '退款渠道', width: 180, prop: 'channel', query: true, type: 'text', resizable: true},
|
|
|
+ {label: '退款入账账户', width: 180, prop: 'userReceivedAccount', query: false, type: 'text', resizable: true},
|
|
|
+ {label: '退款成功时间', width: 180, prop: 'successTime', query: true, sortable: 'custom', type: 'datetime', resizable: true, conf: {format: (val: any) => u.fmt.fmtDateTime(val)}},
|
|
|
+ {
|
|
|
+ label: '退款状态',
|
|
|
+ width: 180,
|
|
|
+ prop: 'status',
|
|
|
+ query: true,
|
|
|
+ type: 'dict',
|
|
|
+ resizable: true,
|
|
|
+ conf: {dict: 'RefundLog.status'}
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: '资金账户',
|
|
|
+ width: 180,
|
|
|
+ prop: 'fundsAccount',
|
|
|
+ query: true,
|
|
|
+ type: 'dict',
|
|
|
+ resizable: true,
|
|
|
+ conf: {dict: 'RefundLog.fundsAccount'}
|
|
|
+ },
|
|
|
+ {label: '订单金额', width: 180, prop: 'total', query: false, type: 'number', resizable: true},
|
|
|
+ {label: '退款金额', width: 180, prop: 'refund', query: false, type: 'number', resizable: true},
|
|
|
+ {label: '不可退优惠金额', width: 180, prop: 'discountAmount', query: false, type: 'number', resizable: true},
|
|
|
+ {label: '用户支付币种', width: 180, prop: 'currency', query: false, type: 'text', resizable: true},
|
|
|
+ {label: '退款原因', width: 180, prop: 'reason', query: true, type: 'text', resizable: true},
|
|
|
+ {label: '退款人', width: 180, prop: 'adminUsername', query: true, type: 'text', resizable: true},
|
|
|
+ {label: '退款创建(受理)时间', width: 180, prop: 'createTime', query: true, sortable: 'custom', type: 'datetime', resizable: true, conf: {format: (val: any) => u.fmt.fmtDateTime(val)}},
|
|
|
+ {label: '更新时间', width: 180, prop: 'updateTime', query: false, sortable: 'custom', type: 'datetime', resizable: true, conf: {format: (val: any) => u.fmt.fmtDateTime(val)}},
|
|
|
+ {
|
|
|
+ label: '操作', prop: 'action', type: 'render', width: 180, align: 'center', fixed: 'right',
|
|
|
+ }
|
|
|
+ ],
|
|
|
+})
|
|
|
+
|
|
|
+
|
|
|
+// 监听双向绑定 modelValue 的变化
|
|
|
+// watch(
|
|
|
+// () => state.pageIndex,
|
|
|
+// () => {
|
|
|
+//
|
|
|
+// }
|
|
|
+// );
|
|
|
+
|
|
|
+//生命周期钩子
|
|
|
+onBeforeMount(() => {
|
|
|
+
|
|
|
+})
|
|
|
+
|
|
|
+onMounted(() => {
|
|
|
+ loadData();
|
|
|
+
|
|
|
+ nextTick(() => {
|
|
|
+ let bodyHeight = document.body.clientHeight;
|
|
|
+ let queryHeight = queryRef.value.$el.clientHeight;
|
|
|
+ state.tableData.height = bodyHeight - queryHeight - 220
|
|
|
+ })
|
|
|
+
|
|
|
+});
|
|
|
+
|
|
|
+onBeforeUnmount(() => {
|
|
|
+})
|
|
|
+
|
|
|
+
|
|
|
+//region 方法区
|
|
|
+// 初始化表格数据
|
|
|
+const loadData = (refresh: boolean = false) => {
|
|
|
+ if (refresh) {
|
|
|
+ state.pageQuery.pageNum = 1;
|
|
|
+ }
|
|
|
+ state.tableData.loading = true;
|
|
|
+ $get(`/finance/listRefundLog`, {...state.formQuery, ...state.pageQuery}).then((res: any) => {
|
|
|
+ let {list, total} = res;
|
|
|
+ state.tableData.data = list;
|
|
|
+ state.pageQuery.total = total;
|
|
|
+ state.tableData.loading = false;
|
|
|
+ }).catch(e => {
|
|
|
+ console.error(e)
|
|
|
+ state.tableData.loading = false;
|
|
|
+ })
|
|
|
+};
|
|
|
+
|
|
|
+// 退款处理
|
|
|
+const handleRefundDealClick = (row: any) => {
|
|
|
+ Msg.showLoading("退款处理中")
|
|
|
+ $get(`finance/customWxRefund/${row.id}`).then(res => {
|
|
|
+ Msg.message('退款系统处理中,请稍后查看结果')
|
|
|
+ loadData(true)
|
|
|
+ }).catch(e => {
|
|
|
+ Msg.message(`退款处理错误,请联系管理员`, 'error')
|
|
|
+ })
|
|
|
+};
|
|
|
+// 删除点击
|
|
|
+const handleRowDelete = (row: any) => {
|
|
|
+ Msg.confirm(`此操作将永久删除:『${row.name}』,是否继续?`).then(() => {
|
|
|
+ $get(`/refundLog/delete/${row.id}`).then(() => {
|
|
|
+ Msg.message("删除成功", 'success')
|
|
|
+ }).catch(() => {
|
|
|
+ Msg.message("删除失败", 'error')
|
|
|
+ })
|
|
|
+ });
|
|
|
+};
|
|
|
+
|
|
|
+//endregion
|
|
|
+
|
|
|
+
|
|
|
+// 暴露变量
|
|
|
+// defineExpose({
|
|
|
+// loadData,
|
|
|
+// });
|
|
|
+</script>
|