Kaynağa Gözat

提现、退款新增

zuypeng 1 yıl önce
ebeveyn
işleme
cf0198b4a3

+ 30 - 0
admin-web/src/router/route.ts

@@ -211,6 +211,36 @@ export const adminRoutes: Array<RouteRecordRaw> = [
                     perm: "recharge.list",
                 },
             },
+            {
+                path: '/refund',
+                name: 'adminFinanceRefund',
+                component: () => import('/@/views/admin/finance/refund.vue'),
+                meta: {
+                    title: '退款清单',
+                    isLink: '',
+                    isHide: false,
+                    isKeepAlive: true,
+                    isAffix: false,
+                    isIframe: false,
+                    icon: 'ele-Wallet',
+                    perm: "refundLog.list",
+                },
+            },
+            {
+                path: '/withdraw',
+                name: 'adminFinanceWithdraw',
+                component: () => import('/@/views/admin/finance/withdraw.vue'),
+                meta: {
+                    title: '提现记录',
+                    isLink: '',
+                    isHide: false,
+                    isKeepAlive: true,
+                    isAffix: false,
+                    isIframe: false,
+                    icon: 'ele-Wallet',
+                    perm: "withdrawnRecord.list",
+                },
+            },
             {
                 path: '/financeSR',
                 name: 'adminSplitRecord',

+ 2 - 0
admin-web/src/utils/message.ts

@@ -41,6 +41,8 @@ export const Msg = {
             cancelButtonText: '取消',
             inputPattern: options?.pattern,
             inputErrorMessage: options?.error,
+            buttonSize:'small',
+            draggable:true
         })
     },
     showLoading(text: string = '加载中') {

+ 32 - 4
admin-web/src/views/admin/account/index.vue

@@ -20,7 +20,7 @@
 }
 
 .page-pager {
-  background-color: #fff;
+  background-color: var(--el-color-white);
   height: 24px;
 }
 </style>
@@ -119,6 +119,9 @@
                 <span>  <el-button link type="primary" @click="handleGotoRefund(row)">{{row[field.prop]}} <SvgIcon name="ele-Link" class="hc"></SvgIcon></el-button></span>
               </div>
             </template>
+            <template v-else-if="'action'===field.prop">
+             <el-text type="primary" @click="handleUserRefundApply(row)">申请退款</el-text>
+            </template>
             <template v-else>
               <div>{{ row[field.prop] }}</div>
             </template>
@@ -183,9 +186,9 @@ const state = reactive({
       {label: '实付总额', width: 100, prop: 'amountReceived', resizable: true},
       {label: '优惠总额', width: 100, prop: 'discountAmount', resizable: true},
       {label: '退款扣除优惠', width: 125, prop: 'refundDiscountAmount', resizable: true},
-      // {
-      //   label: '操作', prop: 'action', width: 180, align: 'center', fixed: 'right',
-      // }
+      {
+        label: '操作', prop: 'action', width: 180, align: 'center', fixed: 'right',
+      }
     ],
   },
 })
@@ -287,6 +290,31 @@ const handleTableSortChange = (column, prop, order) => {
 }
 
 
+const handleUserRefundApply = (row:any) => {
+  Msg.prompt(`请输入退款申请原因`, '退款申请',
+      {
+        draggable: true,
+        type: 'primary',
+      }
+  ).then((res: any) => {
+    let {value, action} = res;
+    if (action === 'confirm') {
+      if(!value){
+        Msg.message("请明确退款原因,否则无法发起本操作",'error')
+        return
+      }
+      Msg.showLoading(`请等待`);
+      $body(`finance/applyRefund`,{userId:row.userId,reason:value}).then(()=>{
+        Msg.message("退款已发起")
+        Msg.hideLoading()
+      }).catch(e=>{
+        Msg.hideLoading()
+      })
+    }
+  })
+
+}
+
 //endregion
 
 

+ 1 - 1
admin-web/src/views/admin/banner/index.vue

@@ -20,7 +20,7 @@
 }
 
 .page-pager {
-  background-color: #fff;
+  background-color: var(--el-color-white);
   height: 24px;
 }
 </style>

+ 1 - 1
admin-web/src/views/admin/dict/index.vue

@@ -314,7 +314,7 @@ const handleSaveDict = () => {
 }
 
 .page-pager {
-  background-color: #fff;
+  background-color: var(--el-color-white);
   height: 24px;
 }
 </style>

+ 1 - 1
admin-web/src/views/admin/faq/index.vue

@@ -20,7 +20,7 @@
 }
 
 .page-pager {
-  background-color: #fff;
+  background-color: var(--el-color-white);
   height: 24px;
 }
 </style>

+ 1 - 1
admin-web/src/views/admin/feedback/index.vue

@@ -20,7 +20,7 @@
 }
 
 .page-pager {
-  background-color: #fff;
+  background-color: var(--el-color-white);
   height: 24px;
 }
 </style>

+ 1 - 1
admin-web/src/views/admin/finance/index.vue

@@ -20,7 +20,7 @@
 }
 
 .page-pager {
-  background-color: #fff;
+  background-color: var(--el-color-white);
   height: 24px;
 }
 </style>

+ 261 - 0
admin-web/src/views/admin/finance/refund.vue

@@ -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>

+ 1 - 1
admin-web/src/views/admin/finance/splitRecord.vue

@@ -20,7 +20,7 @@
 }
 
 .page-pager {
-  background-color: #fff;
+  background-color: var(--el-color-white);
   height: 24px;
 }
 </style>

+ 250 - 0
admin-web/src/views/admin/finance/withdraw.vue

@@ -0,0 +1,250 @@
+<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==='type'">
+              <ext-d-label type="Object.type" :model-value="row[field.prop]"></ext-d-label>
+            </template>
+            <template v-else-if="['withdrawnAmount','amount','amountReceivable','amountReceived','cardBalance','coinMoney','discountAmount','discountMoney'].includes(field.prop)">
+              {{ u.fmt.fmtMoney(row[field.prop]) }}
+            </template>
+            <template v-else-if="field.prop==='idleRemainTime'||field.prop==='operationRemainTime'">
+              {{ u.fmt.fmtDuration(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-auth="'withdrawnRecord.modify'" type="warning" size="small" text @click="handleWithdrawAudit(row)"> 提现审核</el-button>
+              <el-button v-auth="'withdrawnRecord.modify'" type="danger" size="small" text @click="handleWithdrawConfirm(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>
+</template>
+
+<script setup lang="ts" name="WithdrawnRecordList">
+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'
+
+
+//定义引用
+const queryRef = ref();
+const withdrawnRecordDialogRef = ref();
+
+//定义变量
+const state = reactive({
+  formQuery: {},
+  pageQuery: {
+    pageIndex: 1,
+    pageSize: 10,
+    total: 0
+  },
+  tableData: {
+    height: 500,
+    data: [] as Array<any>,
+    loading: false
+  },
+  importConfig: {},
+  exportConfig: {},
+  columns: [
+    {label: '站点id', width: 180, prop: 'stationId', query: true, type: 'select', resizable: true,conf:{url:'washStation/list',valueKey:'stationId',labelKey:'stationName'}},
+    {label: '提现金额', width: 180, prop: 'withdrawnAmount', query: true, type: 'number', resizable: true},
+    {
+      label: '状态', prop: 'status', sortable: 'custom', align: 'center', query: true,
+      type: 'dict', conf: {dict: 'WithdrawnRecord.status'}
+    },
+    {label: '打款状态', width: 180, prop: 'paymentStatus', query: true,
+      type: 'dict', conf: {dict: 'WithdrawnRecord.paymentStatus'}},
+    {label: '审核人', width: 180, prop: 'reviewer', query: true, type: 'text', resizable: true},
+    {label: '审核时间', width: 180, prop: 'reviewTime', query: true, sortable: 'custom', type: 'datetime', resizable: true, conf: {format: (val: any) => u.fmt.fmtDate(val)}},
+    {label: '打款人', width: 180, prop: 'payer', query: true, type: 'text', resizable: true},
+    {label: '打款时间', width: 180, prop: 'paymentTime', query: true, sortable: 'custom', type: 'datetime', resizable: true, conf: {format: (val: any) => u.fmt.fmtDate(val)}},
+    {label: '备注', width: 180, prop: 'remark', query: false, type: 'text', resizable: true},
+    {label: '申请时间', width: 180, prop: 'createTime', query: false, sortable: 'custom', type: 'datetime', resizable: true, conf: {format: (val: any) => u.fmt.fmtDate(val)}},
+    {label: '更新时间', width: 180, prop: 'updateTime', query: false, sortable: 'custom', type: 'datetime', resizable: true, conf: {format: (val: any) => u.fmt.fmtDate(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.pageIndex = 1;
+  }
+  state.tableData.loading = true;
+  $body(`/finance/withdrawnRecords`, {...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 handleRowClick = (type: string, row: any) => {
+  withdrawnRecordDialogRef.value.open(type, row);
+};
+// 删除点击
+const handleRowDelete = (row: any) => {
+  Msg.confirm(`此操作将永久删除:『${row.name}』,是否继续?`).then(() => {
+    $get(`/withdrawnRecord/delete/${row.id}`).then(() => {
+      Msg.message("删除成功", 'success')
+    }).catch(() => {
+      Msg.message("删除失败", 'error')
+    })
+  });
+};
+
+
+const handleWithdrawAudit = (withdraw:any) => {
+  $body(`finance/reviewWithdrawn`,{id:withdraw.id,status:1}).then(res=>{
+    Msg.message(`提现审核通过`)
+    loadData(true)
+  })
+}
+
+const handleWithdrawConfirm = (withdraw:any) => {
+  $body(`finance/confirmWithdrawnPayment`,withdraw).then(res=>{
+    Msg.message(`提现审核通过`)
+    loadData(true)
+  })
+}
+
+
+//endregion
+
+
+// 暴露变量
+// defineExpose({
+//     loadData,
+// });
+</script>

+ 1 - 1
admin-web/src/views/admin/investor/index.vue

@@ -20,7 +20,7 @@
 }
 
 .page-pager {
-  background-color: #fff;
+  background-color: var(--el-color-white);
   height: 24px;
 }
 </style>

+ 1 - 1
admin-web/src/views/admin/ordering/index.vue

@@ -20,7 +20,7 @@
 }
 
 .page-pager {
-  background-color: #fff;
+  background-color: var(--el-color-white);
   height: 24px;
 }
 

+ 1 - 1
admin-web/src/views/admin/platform/deviceConfig/index.vue

@@ -20,7 +20,7 @@
 }
 
 .page-pager {
-  background-color: #fff;
+  background-color: var(--el-color-white);
   height: 24px;
 }
 </style>

+ 1 - 1
admin-web/src/views/admin/platform/rate/index.vue

@@ -20,7 +20,7 @@
 }
 
 .page-pager {
-  background-color: #fff;
+  background-color: var(--el-color-white);
   height: 24px;
 }
 </style>

+ 30 - 2
admin-web/src/views/admin/station/account/index.vue

@@ -20,7 +20,7 @@
 }
 
 .page-pager {
-  background-color: #fff;
+  background-color: var(--el-color-white);
   height: 24px;
 }
 </style>
@@ -103,6 +103,9 @@
             <template v-else-if="['createTime','updateTime'].includes(field.prop)">
               {{ u.fmt.fmtDateTime(row[field.prop]) }}
             </template>
+            <template v-else-if="field.prop=='action'">
+             <el-text type="primary" @click="handleWithdrawApplyClick(row)">提现申请</el-text>
+            </template>
             <template v-else>
               <div>{{ row[field.prop] }}</div>
             </template>
@@ -164,6 +167,9 @@ const state = reactive({
     {label: '提现中金额(元)', width: 200, prop: 'withdrawnFrozenAmount', query: true, type: '', resizable: true},
     {label: '创建时间', width: 180, prop: 'createTime', query: true, sortable: 'custom', type: 'datetime', resizable: true, conf: {format: (val: any) => u.fmt.fmtDate(val)}},
     {label: '更新时间', width: 180, prop: 'updateTime', query: true, sortable: 'custom', type: 'datetime', resizable: true, conf: {format: (val: any) => u.fmt.fmtDate(val)}},
+    {
+      label: '操作', prop: 'action', type: 'render', width: 180, align: 'center', fixed: 'right',
+    }
   ],
 })
 
@@ -223,8 +229,30 @@ const loadData = (refresh: boolean = false) => {
 };
 
 // 打开详情页弹窗
-const handleRowClick = (type: string, row: any) => {
+const handleWithdrawApplyClick = ( row: any) => {
   // stationAccountDialogRef.value.open(type, row);
+  Msg.prompt(`请输入提现金额(单位分)`, '提现申请',
+      {
+        draggable: true,
+        type: 'primary',
+      }
+  ).then((res: any) => {
+    let {value, action} = res;
+    if (action === 'confirm') {
+      if(!value|| !Number.isInteger(value)){
+        Msg.message("请输入有效的提现金额,否则无法发起本操作",'error')
+        return
+      }
+      Msg.showLoading(`请等待`);
+      $body(`finance/applyWithdrawn`,{stationId:row.stationId,amount:Number(value)}).then(()=>{
+        Msg.message("提现已发起")
+        Msg.hideLoading()
+        loadData(true)
+      }).catch(e=>{
+        Msg.hideLoading()
+      })
+    }
+  })
 };
 // 删除点击
 const handleRowDelete = (row: any) => {

+ 1 - 1
admin-web/src/views/admin/station/device/index.vue

@@ -20,7 +20,7 @@
 }
 
 .page-pager {
-  background-color: #fff;
+  background-color: var(--el-color-white);
   height: 24px;
 }
 </style>

+ 1 - 1
admin-web/src/views/admin/station/list/index.vue

@@ -20,7 +20,7 @@
 }
 
 .page-pager {
-  background-color: #fff;
+  background-color: var(--el-color-white);
   height: 24px;
 }
 </style>

+ 1 - 1
admin-web/src/views/admin/user/index.vue

@@ -20,7 +20,7 @@
 }
 
 .page-pager {
-  background-color: #fff;
+  background-color: var(--el-color-white);
   height: 24px;
 }
 </style>

+ 12 - 10
car-wash-service/src/main/java/com/kym/service/wechat/impl/WxPayServiceImpl.java

@@ -18,7 +18,9 @@ import com.kym.entity.*;
 import com.kym.service.*;
 import com.kym.service.wechat.WxPayService;
 import com.wechat.pay.java.core.Config;
+import com.wechat.pay.java.core.RSAAutoCertificateConfig;
 import com.wechat.pay.java.core.exception.ValidationException;
+import com.wechat.pay.java.core.http.DefaultHttpClientBuilder;
 import com.wechat.pay.java.core.http.okhttp.OkHttpClientAdapter;
 import com.wechat.pay.java.core.notification.NotificationConfig;
 import com.wechat.pay.java.core.notification.NotificationParser;
@@ -142,16 +144,16 @@ public class WxPayServiceImpl implements WxPayService {
             ClassPathResource resource = new ClassPathResource(conf.getKeyPath());
             privateKey = IoUtil.read(resource.getInputStream(), StandardCharsets.UTF_8);
         }
-//        config = new RSAAutoCertificateConfig.Builder()
-//                .merchantId(conf.getMchid()) // 商户号
-//                .privateKey(privateKey)//商户API私钥路径
-//                .merchantSerialNumber(conf.getMchsn()) // 商户证书序列号
-//                .apiV3Key(conf.getV3key()) // 商户APIV3密钥
-//                .build();
-//        jsapiService = new JsapiService.Builder().config(config).build();
-//        refundService = new RefundService.Builder().config(config).build();
-//
-//        wxHttpClient = (OkHttpClientAdapter) new DefaultHttpClientBuilder().newInstance().config(config).build();
+        config = new RSAAutoCertificateConfig.Builder()
+                .merchantId(conf.getMchid()) // 商户号
+                .privateKey(privateKey)//商户API私钥路径
+                .merchantSerialNumber(conf.getMchsn()) // 商户证书序列号
+                .apiV3Key(conf.getV3key()) // 商户APIV3密钥
+                .build();
+        jsapiService = new JsapiService.Builder().config(config).build();
+        refundService = new RefundService.Builder().config(config).build();
+
+        wxHttpClient = (OkHttpClientAdapter) new DefaultHttpClientBuilder().newInstance().config(config).build();
 
 //        // 初始化微信电子发票开发配置,主要是回调地址 todo 区块链电子发票开通后放开
 //         devConfig();