Explorar o código

新增用户资金流水查询

skyline hai 1 semana
pai
achega
dee261e67e

+ 5 - 0
admin-web-new/src/api/finance.ts

@@ -29,3 +29,8 @@ export const getSettlementList = (data?: object) => {
 export const triggerSettlement = () => {
   return http.request<any>("post", "/finance/triggerSettlement");
 };
+
+/** 用户资金流水列表 */
+export const getWalletDetailList = (data?: object) => {
+  return http.request<any>("get", "/finance/walletDetails", { params: data });
+};

+ 9 - 0
admin-web-new/src/router/modules/admin.ts

@@ -95,6 +95,15 @@ export default {
             title: "充值记录"
           }
         },
+        {
+          path: "/admin/finance/wallet-flow",
+          name: "AdminFinanceWalletFlow",
+          component: () => import("@/views/admin/finance/wallet-flow.vue"),
+          meta: {
+            icon: "ri:exchange-funds-line",
+            title: "用户资金流"
+          }
+        },
         {
           path: "/admin/finance/refund",
           name: "AdminFinanceRefund",

+ 313 - 0
admin-web-new/src/views/admin/finance/wallet-flow.vue

@@ -0,0 +1,313 @@
+<script setup lang="ts">
+import { reactive, onMounted, ref, nextTick } from "vue";
+import { getWalletDetailList } from "@/api/finance";
+import { useRenderIcon } from "@/components/ReIcon/src/hooks";
+import { ElMessage } from "element-plus";
+
+defineOptions({
+  name: "AdminFinanceWalletFlow"
+});
+
+const queryRef = ref();
+const tableRef = ref();
+
+const typeOptions = [
+  { value: undefined, label: "全部" },
+  { value: 1, label: "充值" },
+  { value: 2, label: "提现" },
+  { value: 3, label: "消费" }
+];
+
+const statusOptions = [
+  { value: undefined, label: "全部" },
+  { value: 0, label: "待确认" },
+  { value: 1, label: "已确认" },
+  { value: 2, label: "已取消" }
+];
+
+const typeTagMap: Record<number, { text: string; type: string }> = {
+  1: { text: "充值", type: "success" },
+  2: { text: "提现", type: "warning" },
+  3: { text: "消费", type: "danger" }
+};
+
+const statusTagMap: Record<number, { text: string; type: string }> = {
+  0: { text: "待确认", type: "info" },
+  1: { text: "已确认", type: "success" },
+  2: { text: "已取消", type: "danger" }
+};
+
+const state = reactive({
+  formQuery: {
+    mobilePhone: "",
+    type: undefined as number | undefined,
+    status: undefined as number | undefined,
+    startDate: "",
+    endDate: ""
+  },
+  pageQuery: {
+    pageNum: 1,
+    pageSize: 10,
+    total: 0
+  },
+  tableData: {
+    height: 500,
+    data: [] as Array<any>,
+    loading: false,
+    columns: [
+      { label: "用户ID", prop: "userId", width: 120 },
+      { label: "用户手机号", prop: "mobilePhone", width: 140 },
+      { label: "交易类型", prop: "type", width: 100 },
+      { label: "订单号", prop: "orderNo", width: 200 },
+      { label: "金额", prop: "amount", width: 110 },
+      { label: "赠款金额", prop: "grantsAmount", width: 110 },
+      { label: "手续费", prop: "commission", width: 100 },
+      { label: "交易前余额", prop: "beforeBalance", width: 120 },
+      { label: "交易后余额", prop: "afterBalance", width: 120 },
+      { label: "交易前赠款", prop: "beforeGrantsBalance", width: 120 },
+      { label: "交易后赠款", prop: "afterGrantsBalance", width: 120 },
+      { label: "状态", prop: "status", width: 100 },
+      { label: "交易时间", prop: "transactionTime", width: 170 },
+      { label: "备注", prop: "remark", minWidth: 150 }
+    ]
+  }
+});
+
+onMounted(() => {
+  loadData();
+  nextTick(() => {
+    const bodyHeight = document.body.clientHeight;
+    const queryHeight = queryRef.value?.$el?.clientHeight || 0;
+    state.tableData.height = bodyHeight - queryHeight - 280;
+  });
+});
+
+const buildParams = () => {
+  const params: any = { ...state.formQuery, ...state.pageQuery };
+  if (!params.type) delete params.type;
+  if (params.status === undefined || params.status === null) delete params.status;
+  if (!params.startDate) delete params.startDate;
+  if (!params.endDate) delete params.endDate;
+  return params;
+};
+
+const loadData = (refresh: boolean = false) => {
+  if (refresh) {
+    state.pageQuery.pageNum = 1;
+  }
+  state.tableData.loading = true;
+  getWalletDetailList(buildParams())
+    .then((res: any) => {
+      const { list, total } = res || {};
+      state.tableData.data = list || [];
+      state.pageQuery.total = total || 0;
+    })
+    .catch(() => {
+      state.tableData.data = [];
+      ElMessage.error("加载资金流水记录失败");
+    })
+    .finally(() => {
+      state.tableData.loading = false;
+    });
+};
+
+const handleSizeChange = (size: number) => {
+  state.pageQuery.pageSize = size;
+  loadData(true);
+};
+
+const handleCurrentChange = (page: number) => {
+  state.pageQuery.pageNum = page;
+  loadData();
+};
+
+const handleSearch = () => {
+  loadData(true);
+};
+
+const handleReset = () => {
+  state.formQuery = {
+    mobilePhone: "",
+    type: undefined,
+    status: undefined,
+    startDate: "",
+    endDate: ""
+  };
+  loadData(true);
+};
+
+const formatMoney = (value: number) => {
+  if (value === null || value === undefined) return "-";
+  return `${(value / 100).toFixed(2)}`;
+};
+
+const getTypeTag = (type: number) => {
+  return typeTagMap[type] || { text: "未知", type: "info" };
+};
+
+const getStatusTag = (status: number) => {
+  return statusTagMap[status] || { text: "未知", type: "info" };
+};
+</script>
+
+<template>
+  <div class="page-container">
+    <el-card shadow="hover">
+      <template #header>
+        <span class="card-header">用户资金流</span>
+      </template>
+      <el-form
+        ref="queryRef"
+        :model="state.formQuery"
+        inline
+        class="search-form"
+      >
+        <el-form-item label="用户手机号">
+          <el-input
+            v-model="state.formQuery.mobilePhone"
+            placeholder="请输入手机号"
+            clearable
+            style="width: 160px"
+            @keyup.enter="handleSearch"
+          />
+        </el-form-item>
+        <el-form-item label="交易类型">
+          <el-select
+            v-model="state.formQuery.type"
+            placeholder="全部"
+            style="width: 120px"
+            clearable
+          >
+            <el-option
+              v-for="opt in typeOptions"
+              :key="opt.value"
+              :label="opt.label"
+              :value="opt.value"
+            />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="状态">
+          <el-select
+            v-model="state.formQuery.status"
+            placeholder="全部"
+            style="width: 120px"
+            clearable
+          >
+            <el-option
+              v-for="opt in statusOptions"
+              :key="opt.value"
+              :label="opt.label"
+              :value="opt.value"
+            />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="交易时间">
+          <el-date-picker
+            v-model="state.formQuery.startDate"
+            type="date"
+            placeholder="开始日期"
+            value-format="YYYY-MM-DD"
+            style="width: 150px"
+          />
+          <span style="margin: 0 8px; color: #999">至</span>
+          <el-date-picker
+            v-model="state.formQuery.endDate"
+            type="date"
+            placeholder="结束日期"
+            value-format="YYYY-MM-DD"
+            style="width: 150px"
+          />
+        </el-form-item>
+        <el-form-item>
+          <el-button
+            type="primary"
+            :icon="useRenderIcon('ri/search-line')"
+            @click="handleSearch"
+          >
+            查询
+          </el-button>
+          <el-button
+            :icon="useRenderIcon('ri/refresh-line')"
+            @click="handleReset"
+          >
+            重置
+          </el-button>
+        </el-form-item>
+      </el-form>
+
+      <el-table
+        ref="tableRef"
+        v-loading="state.tableData.loading"
+        :data="state.tableData.data"
+        :height="state.tableData.height"
+        border
+        stripe
+      >
+        <template #empty>
+          <el-empty description="暂无资金流水记录" />
+        </template>
+        <el-table-column
+          v-for="col in state.tableData.columns"
+          :key="col.prop"
+          :prop="col.prop"
+          :label="col.label"
+          :width="col.width"
+          :min-width="col.minWidth"
+          show-overflow-tooltip
+        >
+          <template #default="{ row }">
+            <template v-if="col.prop === 'type'">
+              <el-tag :type="getTypeTag(row.type).type" size="small" effect="plain">
+                {{ getTypeTag(row.type).text }}
+              </el-tag>
+            </template>
+            <template v-else-if="col.prop === 'status'">
+              <el-tag :type="getStatusTag(row.status).type" size="small" effect="plain">
+                {{ getStatusTag(row.status).text }}
+              </el-tag>
+            </template>
+            <template v-else-if="['amount', 'grantsAmount', 'commission', 'beforeBalance', 'afterBalance', 'beforeGrantsBalance', 'afterGrantsBalance'].includes(col.prop)">
+              {{ formatMoney(row[col.prop]) }}
+            </template>
+            <template v-else>
+              {{ row[col.prop] }}
+            </template>
+          </template>
+        </el-table-column>
+      </el-table>
+
+      <div class="pagination-container">
+        <el-pagination
+          v-model:current-page="state.pageQuery.pageNum"
+          v-model:page-size="state.pageQuery.pageSize"
+          :total="state.pageQuery.total"
+          :page-sizes="[10, 20, 50, 100]"
+          layout="total, sizes, prev, pager, next, jumper"
+          @size-change="handleSizeChange"
+          @current-change="handleCurrentChange"
+        />
+      </div>
+    </el-card>
+  </div>
+</template>
+
+<style scoped lang="scss">
+.page-container {
+  padding: 20px;
+}
+
+.card-header {
+  font-size: 16px;
+  font-weight: 600;
+}
+
+.search-form {
+  margin-bottom: 16px;
+}
+
+.pagination-container {
+  display: flex;
+  justify-content: flex-end;
+  margin-top: 20px;
+}
+</style>

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

@@ -211,6 +211,21 @@ export const adminRoutes: Array<RouteRecordRaw> = [
                     perm: "recharge.list",
                 },
             },
+            {
+                path: '/walletFlow',
+                name: 'adminFinanceWalletFlow',
+                component: () => import('/@/views/admin/finance/wallet-flow.vue'),
+                meta: {
+                    title: '用户资金流',
+                    isLink: '',
+                    isHide: false,
+                    isKeepAlive: true,
+                    isAffix: false,
+                    isIframe: false,
+                    icon: 'ele-Money',
+                    perm: "",
+                },
+            },
             {
                 path: '/refund',
                 name: 'adminFinanceRefund',

+ 254 - 0
admin-web/src/views/admin/finance/wallet-flow.vue

@@ -0,0 +1,254 @@
+<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;
+}
+
+.wd120 {
+  width: 120px;
+}
+
+.wd150 {
+  width: 150px;
+}
+</style>
+<template>
+  <div class="system-container layout-padding">
+    <el-card shadow="hover" class="layout-padding-auto">
+
+      <el-form
+          :model="state.formQuery"
+          ref="queryRef"
+          size="default" label-width="0px" class="mt5 mb5">
+        <el-input
+            v-model="state.formQuery.mobilePhone"
+            placeholder="用户手机号"
+            clearable
+            @blur="loadData(true)"
+            class="wd150 mr10">
+        </el-input>
+        <el-select
+            v-model="state.formQuery.type"
+            placeholder="交易类型"
+            clearable
+            class="wd120 mr10"
+            @change="loadData(true)">
+          <el-option label="全部" :value="undefined" />
+          <el-option label="充值" :value="1" />
+          <el-option label="提现" :value="2" />
+          <el-option label="消费" :value="3" />
+        </el-select>
+        <el-select
+            v-model="state.formQuery.status"
+            placeholder="状态"
+            clearable
+            class="wd120 mr10"
+            @change="loadData(true)">
+          <el-option label="全部" :value="undefined" />
+          <el-option label="待确认" :value="0" />
+          <el-option label="已确认" :value="1" />
+          <el-option label="已取消" :value="2" />
+        </el-select>
+        <el-date-picker
+            v-model="state.formQuery.startDate"
+            type="date"
+            placeholder="开始日期"
+            value-format="YYYY-MM-DD"
+            class="wd150 mr10"
+            @change="loadData(true)">
+        </el-date-picker>
+        <el-date-picker
+            v-model="state.formQuery.endDate"
+            type="date"
+            placeholder="结束日期"
+            value-format="YYYY-MM-DD"
+            class="wd150 mr10"
+            @change="loadData(true)">
+        </el-date-picker>
+
+        <el-button class="ml10" plain size="default" type="success" @click="loadData(true)">
+          <SvgIcon name="ele-Search"/>
+          查询
+        </el-button>
+      </el-form>
+
+      <el-table
+          border
+          stripe="stripe"
+          :height="state.tableData.height"
+          highlight-current-row
+          current-row-key="id"
+          row-key="id"
+          :data="state.tableData.data"
+          v-loading="state.tableData.loading"
+          @selection-change="handleTableSelectionChange"
+          @sort-change="handleTableSortChange">
+        <template #empty>
+          <el-empty description="暂无资金流水记录"></el-empty>
+        </template>
+        <el-table-column
+            v-for="field in state.tableData.columns"
+            :key="field.prop"
+            :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==='type'">
+              <el-tag :type="getTypeTag(row.type).type" size="small" effect="plain">
+                {{ getTypeTag(row.type).text }}
+              </el-tag>
+            </template>
+            <template v-else-if="field.prop==='status'">
+              <el-tag :type="getStatusTag(row.status).type" size="small" effect="plain">
+                {{ getStatusTag(row.status).text }}
+              </el-tag>
+            </template>
+            <template v-else-if="['amount','grantsAmount','commission','beforeBalance','afterBalance','beforeGrantsBalance','afterGrantsBalance'].includes(field.prop)">
+              {{ u.fmt.fmtMoney(row[field.prop]) }}
+            </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="adminFinanceWalletFlow">
+import {nextTick, onMounted, reactive, ref} from 'vue';
+import {$get} from "/@/utils/request";
+import u from "/@/utils/u"
+
+import ExtPage from '/@/components/form/ExtPage.vue'
+
+const typeTagMap: Record<number, { text: string; type: string }> = {
+  1: { text: "充值", type: "success" },
+  2: { text: "提现", type: "warning" },
+  3: { text: "消费", type: "danger" }
+};
+
+const statusTagMap: Record<number, { text: string; type: string }> = {
+  0: { text: "待确认", type: "info" },
+  1: { text: "已确认", type: "success" },
+  2: { text: "已取消", type: "danger" }
+};
+
+const getTypeTag = (type: number) => {
+  return typeTagMap[type] || { text: "未知", type: "info" };
+};
+
+const getStatusTag = (status: number) => {
+  return statusTagMap[status] || { text: "未知", type: "info" };
+};
+
+//定义引用
+const queryRef = ref();
+
+//定义变量
+const state = reactive({
+  formQuery: {
+    mobilePhone: "",
+    type: undefined as number | undefined,
+    status: undefined as number | undefined,
+    startDate: "",
+    endDate: ""
+  },
+  pageQuery: {
+    pageNum: 1,
+    pageSize: 10,
+    total: 0
+  },
+  tableData: {
+    height: 500,
+    data: [] as Array<any>,
+    loading: false,
+    columns: [
+      {label: '用户ID', prop: 'userId', width: 120, resizable: true, fixed: 'left'},
+      {label: '用户手机号', prop: 'mobilePhone', width: 140, resizable: true, fixed: 'left'},
+      {label: '交易类型', prop: 'type', width: 100, resizable: true},
+      {label: '订单号', prop: 'orderNo', width: 200, resizable: true},
+      {label: '金额', prop: 'amount', width: 110, resizable: true},
+      {label: '赠款金额', prop: 'grantsAmount', width: 110, resizable: true},
+      {label: '手续费', prop: 'commission', width: 100, resizable: true},
+      {label: '交易前余额', prop: 'beforeBalance', width: 120, resizable: true},
+      {label: '交易后余额', prop: 'afterBalance', width: 120, resizable: true},
+      {label: '交易前赠款', prop: 'beforeGrantsBalance', width: 120, resizable: true},
+      {label: '交易后赠款', prop: 'afterGrantsBalance', width: 120, resizable: true},
+      {label: '状态', prop: 'status', width: 100, resizable: true},
+      {label: '交易时间', prop: 'transactionTime', width: 170, resizable: true, fixed: 'right'},
+      {label: '备注', prop: 'remark', minWidth: 150, resizable: true},
+    ],
+  },
+})
+
+onMounted(() => {
+  loadData();
+
+  nextTick(() => {
+    let bodyHeight = document.body.clientHeight;
+    let queryHeight = queryRef.value.$el.clientHeight;
+    state.tableData.height = bodyHeight - queryHeight - 320
+  })
+});
+
+const buildParams = () => {
+  const params: any = { ...state.formQuery, ...state.pageQuery };
+  if (params.type === undefined || params.type === null) delete params.type;
+  if (params.status === undefined || params.status === null) delete params.status;
+  if (!params.startDate) delete params.startDate;
+  if (!params.endDate) delete params.endDate;
+  return params;
+};
+
+// 初始化表格数据
+const loadData = (refresh: boolean = false) => {
+  if (refresh) {
+    state.pageQuery.pageNum = 1;
+  }
+  state.tableData.loading = true;
+  $get(`/finance/walletDetails`, buildParams()).then((res: any) => {
+    let {list, total} = res;
+    state.tableData.data = list;
+    state.pageQuery.total = total;
+    state.tableData.loading = false;
+  }).catch(e => {
+    state.tableData.loading = false;
+  })
+};
+
+const handleTableSelectionChange = (selection: any) => {
+}
+
+const handleTableSortChange = (column: any, prop: string, order: string) => {
+}
+</script>

+ 13 - 1
car-wash-admin/src/main/java/com/kym/admin/controller/FinanceController.java

@@ -3,6 +3,7 @@ package com.kym.admin.controller;
 import com.kym.common.R;
 import com.kym.common.annotation.SysLog;
 import com.kym.entity.queryParams.*;
+import com.kym.entity.queryParams.WalletDetailQueryParam;
 import com.kym.service.*;
 import com.kym.service.wechat.WxPayService;
 import jakarta.validation.Valid;
@@ -26,11 +27,13 @@ public class FinanceController {
     private final RefundLogService refundLogService;
     private final PlatformAccountService platformAccountService;
     private final PlatformRevenueRecordService platformRevenueRecordService;
+    private final WalletDetailService walletDetailService;
 
     public FinanceController(SplitRecordService splitRecordService, StationAccountService stationAccountService,
                              WithdrawnRecordService withdrawnRecordService, SettlementService settlementService,
                              WxPayService wxPayService, RefundLogService refundLogService,
-                             PlatformAccountService platformAccountService, PlatformRevenueRecordService platformRevenueRecordService) {
+                             PlatformAccountService platformAccountService, PlatformRevenueRecordService platformRevenueRecordService,
+                             WalletDetailService walletDetailService) {
         this.splitRecordService = splitRecordService;
         this.stationAccountService = stationAccountService;
         this.withdrawnRecordService = withdrawnRecordService;
@@ -39,6 +42,7 @@ public class FinanceController {
         this.refundLogService = refundLogService;
         this.platformAccountService = platformAccountService;
         this.platformRevenueRecordService = platformRevenueRecordService;
+        this.walletDetailService = walletDetailService;
     }
 
     /**
@@ -185,4 +189,12 @@ public class FinanceController {
         return R.success(platformRevenueRecordService.listRevenueRecords(params));
     }
 
+    /**
+     * 用户资金流水列表
+     */
+    @GetMapping("/walletDetails")
+    public R<?> walletDetails(@ModelAttribute WalletDetailQueryParam params) {
+        return R.success(walletDetailService.listAdminWalletDetail(params));
+    }
+
 }

+ 38 - 0
car-wash-entity/src/main/java/com/kym/entity/queryParams/WalletDetailQueryParam.java

@@ -0,0 +1,38 @@
+package com.kym.entity.queryParams;
+
+import com.kym.entity.common.PageParams;
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+
+@Data
+@Accessors(chain = true)
+public class WalletDetailQueryParam extends PageParams {
+
+    private Long userId;
+
+    private String mobilePhone;
+
+    private Integer type;
+
+    private Integer status;
+
+    public void setStartDate(String startDate) {
+        if (startDate != null && !startDate.isEmpty()) {
+            this.startDate = LocalDateTime.of(LocalDate.parse(startDate), LocalTime.MIN);
+        }
+    }
+
+    private LocalDateTime startDate;
+
+    public void setEndDate(String endDate) {
+        if (endDate != null && !endDate.isEmpty()) {
+            this.endDate = LocalDateTime.of(LocalDate.parse(endDate), LocalTime.MAX);
+        }
+    }
+
+    private LocalDateTime endDate;
+}

+ 29 - 0
car-wash-entity/src/main/java/com/kym/entity/vo/WalletDetailVo.java

@@ -0,0 +1,29 @@
+package com.kym.entity.vo;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+@Data
+public class WalletDetailVo {
+    private Long userId;
+    private String mobilePhone;
+    private Integer type;
+    private String currency;
+    private String orderNo;
+    private Integer amount;
+    private Integer grantsAmount;
+    private Integer commission;
+    private Integer beforeBalance;
+    private Integer afterBalance;
+    private Integer beforeGrantsBalance;
+    private Integer afterGrantsBalance;
+    private String transactionId;
+    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private LocalDateTime transactionTime;
+    private Integer status;
+    private String remark;
+    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private LocalDateTime createTime;
+}

+ 6 - 0
car-wash-mapper/src/main/java/com/kym/mapper/WalletDetailMapper.java

@@ -2,6 +2,10 @@ package com.kym.mapper;
 
 import com.github.yulichang.base.MPJBaseMapper;
 import com.kym.entity.WalletDetail;
+import com.kym.entity.queryParams.WalletDetailQueryParam;
+import com.kym.entity.vo.WalletDetailVo;
+
+import java.util.List;
 
 /**
  * <p>
@@ -13,4 +17,6 @@ import com.kym.entity.WalletDetail;
  */
 public interface WalletDetailMapper extends MPJBaseMapper<WalletDetail> {
 
+    List<WalletDetailVo> listAdminWalletDetail(WalletDetailQueryParam params);
+
 }

+ 63 - 0
car-wash-mapper/src/main/resources/mappers/WalletDetailMapper.xml

@@ -26,6 +26,69 @@
         id, company_id,user_id, type, currency, order_no, amount, commission, transaction_id, transaction_time, status, remark, create_time, update_time
     </sql>
 
+    <resultMap id="AdminWalletDetailMap" type="com.kym.entity.vo.WalletDetailVo">
+        <result column="user_id" property="userId"/>
+        <result column="mobile_phone" property="mobilePhone"/>
+        <result column="type" property="type"/>
+        <result column="currency" property="currency"/>
+        <result column="order_no" property="orderNo"/>
+        <result column="amount" property="amount"/>
+        <result column="grants_amount" property="grantsAmount"/>
+        <result column="commission" property="commission"/>
+        <result column="before_balance" property="beforeBalance"/>
+        <result column="after_balance" property="afterBalance"/>
+        <result column="before_grants_balance" property="beforeGrantsBalance"/>
+        <result column="after_grants_balance" property="afterGrantsBalance"/>
+        <result column="transaction_id" property="transactionId"/>
+        <result column="transaction_time" property="transactionTime"/>
+        <result column="status" property="status"/>
+        <result column="remark" property="remark"/>
+        <result column="create_time" property="createTime"/>
+    </resultMap>
 
+    <select id="listAdminWalletDetail" parameterType="com.kym.entity.queryParams.WalletDetailQueryParam"
+            resultMap="AdminWalletDetailMap">
+        SELECT
+            t1.user_id,
+            t2.mobile_phone,
+            t1.type,
+            t1.currency,
+            t1.order_no,
+            t1.amount,
+            t1.grants_amount,
+            t1.commission,
+            t1.before_balance,
+            t1.after_balance,
+            t1.before_grants_balance,
+            t1.after_grants_balance,
+            t1.transaction_id,
+            t1.transaction_time,
+            t1.status,
+            t1.remark,
+            t1.create_time
+        FROM t_wallet_detail t1
+        LEFT JOIN t_user t2 ON t1.user_id = t2.id
+        <where>
+            <if test="userId != null">
+                AND t1.user_id = #{userId}
+            </if>
+            <if test="mobilePhone != null and mobilePhone != ''">
+                AND t2.mobile_phone = #{mobilePhone}
+            </if>
+            <if test="type != null">
+                AND t1.type = #{type}
+            </if>
+            <if test="status != null">
+                AND t1.status = #{status}
+            </if>
+            <if test="startDate != null">
+                AND t1.transaction_time &gt;= #{startDate}
+            </if>
+            <if test="endDate != null">
+                AND t1.transaction_time &lt;= #{endDate}
+            </if>
+        </where>
+        ORDER BY t1.id DESC
+    </select>
 
 </mapper>

+ 5 - 0
car-wash-service/src/main/java/com/kym/service/WalletDetailService.java

@@ -2,6 +2,9 @@ package com.kym.service;
 
 import com.github.yulichang.base.MPJBaseService;
 import com.kym.entity.WalletDetail;
+import com.kym.entity.common.PageBean;
+import com.kym.entity.queryParams.WalletDetailQueryParam;
+import com.kym.entity.vo.WalletDetailVo;
 
 import java.util.List;
 
@@ -19,4 +22,6 @@ public interface WalletDetailService extends MPJBaseService<WalletDetail> {
 
     List<WalletDetail> listWalletDetail(int type);
 
+    PageBean<WalletDetailVo> listAdminWalletDetail(WalletDetailQueryParam params);
+
 }

+ 11 - 0
car-wash-service/src/main/java/com/kym/service/impl/WalletDetailServiceImpl.java

@@ -2,8 +2,12 @@ package com.kym.service.impl;
 
 import cn.dev33.satoken.stp.StpUtil;
 
+import com.github.pagehelper.PageHelper;
 import com.github.yulichang.base.MPJBaseServiceImpl;
 import com.kym.entity.WalletDetail;
+import com.kym.entity.common.PageBean;
+import com.kym.entity.queryParams.WalletDetailQueryParam;
+import com.kym.entity.vo.WalletDetailVo;
 import com.kym.mapper.WalletDetailMapper;
 import com.kym.service.WalletDetailService;
 import org.springframework.stereotype.Service;
@@ -38,4 +42,11 @@ public class WalletDetailServiceImpl extends MPJBaseServiceImpl<WalletDetailMapp
 
     }
 
+    @Override
+    public PageBean<WalletDetailVo> listAdminWalletDetail(WalletDetailQueryParam params) {
+        PageHelper.startPage(params.getPageNum(), params.getPageSize());
+        List<WalletDetailVo> list = baseMapper.listAdminWalletDetail(params);
+        return new PageBean<>(list);
+    }
+
 }