feat(approvalCenter): 添加审批中心列表页功能及搜索过滤
- 在接口定义中添加handleStatus和searchStr字段支持搜索过滤 - 实现审批列表的数据加载、分页和搜索功能 - 添加表格展示及状态标签显示 - 实现不同菜单下的数据切换和加载
This commit is contained in:
parent
52f8cbff4a
commit
80dc7ecd58
|
@ -18,6 +18,18 @@ export interface SearchReturnApprovalQuery extends BasePageQuery {
|
|||
* 0为借还柜 1为固资通
|
||||
*/
|
||||
approvalType: number;
|
||||
/**
|
||||
* 处理状态
|
||||
* @remarks
|
||||
* 0:待处理 1:已处理
|
||||
*/
|
||||
handleStatus?: number;
|
||||
/**
|
||||
* 搜索字符串
|
||||
* @remarks
|
||||
* 搜索商品名称、申请人
|
||||
*/
|
||||
searchStr?: string;
|
||||
}
|
||||
|
||||
/** 退货审批DTO */
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
<script setup lang="ts">
|
||||
import { ref, computed, markRaw } from 'vue';
|
||||
import { ref, computed, markRaw, watch, onMounted } from 'vue';
|
||||
import { ElMessage, ElMessageBox } from 'element-plus';
|
||||
import { PureTableBar } from "@/components/RePureTableBar";
|
||||
import { useRenderIcon } from "@/components/ReIcon/src/hooks";
|
||||
import {
|
||||
Calendar,
|
||||
Briefcase,
|
||||
|
@ -20,7 +23,11 @@ import {
|
|||
RefreshRight,
|
||||
Wallet,
|
||||
CreditCard,
|
||||
Search,
|
||||
Refresh
|
||||
} from '@element-plus/icons-vue';
|
||||
import { getReturnApprovalListApi } from '@/api/shop/approval';
|
||||
import { debounce } from "@pureadmin/utils";
|
||||
|
||||
defineOptions({
|
||||
name: "approvalCenter"
|
||||
|
@ -33,7 +40,23 @@ const activeMenu = ref('apply');
|
|||
const activeTab = ref('all');
|
||||
|
||||
// 搜索关键词
|
||||
const searchKey = ref('');
|
||||
const searchFormParams = ref({
|
||||
status: null,
|
||||
searchStr: null
|
||||
});
|
||||
// 分页参数
|
||||
const pagination = ref({
|
||||
pageSize: 5,
|
||||
currentPage: 1,
|
||||
total: 0
|
||||
});
|
||||
// 列表数据
|
||||
const pendingList = ref([]);
|
||||
const processedList = ref([]);
|
||||
const ccList = ref([]);
|
||||
const submittedList = ref([]);
|
||||
const loading = ref(false);
|
||||
const multipleSelection = ref([]);
|
||||
|
||||
// 申请类型数据(按标签栏分类)
|
||||
const applicationData = ref({
|
||||
|
@ -51,18 +74,12 @@ const applicationData = ref({
|
|||
{ icon: markRaw(Wallet), name: '退款', color: '#795548' }
|
||||
],
|
||||
});
|
||||
applicationData.value.all = [...applicationData.value.shop, ...applicationData.value.other];
|
||||
|
||||
// 计算属性:合并“全部”类型数据
|
||||
applicationData.value.all = [
|
||||
...applicationData.value.shop,
|
||||
...applicationData.value.other,
|
||||
];
|
||||
|
||||
// 计算属性:根据当前标签栏和搜索关键词过滤申请类型
|
||||
// 计算属性:过滤申请类型
|
||||
const filteredApplications = computed(() => {
|
||||
const data = applicationData.value[activeTab.value] || [];
|
||||
if (!searchKey.value) return data;
|
||||
return data.filter(item => item.name.includes(searchKey.value));
|
||||
return data;
|
||||
});
|
||||
|
||||
// 处理左侧菜单选中
|
||||
|
@ -75,15 +92,105 @@ const handleTabChange = (tab: any) => {
|
|||
activeTab.value = tab.name;
|
||||
};
|
||||
|
||||
// 处理搜索(可扩展为接口请求)
|
||||
const handleSearch = () => {
|
||||
console.log('搜索关键词:', searchKey.value);
|
||||
// 搜索
|
||||
const onSearch = () => {
|
||||
pagination.value.currentPage = 1;
|
||||
loadData();
|
||||
};
|
||||
|
||||
// 防抖搜索
|
||||
const debouncedSearch = debounce(onSearch, 500);
|
||||
|
||||
// 监听搜索关键词变化
|
||||
watch(
|
||||
() => searchFormParams.value.searchStr,
|
||||
(newVal) => {
|
||||
debouncedSearch();
|
||||
}
|
||||
);
|
||||
|
||||
// 重置
|
||||
const resetForm = () => {
|
||||
Object.assign(searchFormParams.value, {
|
||||
approvalId: null,
|
||||
orderId: null,
|
||||
goodsId: null,
|
||||
status: null,
|
||||
approvalTime: null,
|
||||
paymentMethod: null
|
||||
});
|
||||
onSearch();
|
||||
};
|
||||
|
||||
// 分页变化
|
||||
const handlePaginationChange = () => loadData();
|
||||
|
||||
// 加载列表数据
|
||||
const loadData = async () => {
|
||||
if (activeMenu.value !== 'received-pending' && activeMenu.value !== 'received-processed') {
|
||||
return;
|
||||
}
|
||||
loading.value = true;
|
||||
try {
|
||||
const params = {
|
||||
...searchFormParams.value,
|
||||
approvalType: 0,
|
||||
pageSize: pagination.value.pageSize,
|
||||
pageNum: pagination.value.currentPage,
|
||||
handleStatus: activeMenu.value === 'received-pending' ? 0 : activeMenu.value === 'received-processed' ? 1 : undefined
|
||||
};
|
||||
const { data } = await getReturnApprovalListApi(params);
|
||||
const formattedData = data.rows.map(item => ({
|
||||
...item,
|
||||
statusStr: { 1: '待审核', 2: '已通过', 3: '已驳回' }[item.status],
|
||||
paymentMethodStr: { wechat: '微信支付', balance: '余额支付' }[item.paymentMethod] || item.paymentMethod
|
||||
}));
|
||||
switch (activeMenu.value) {
|
||||
case 'received-pending': pendingList.value = formattedData; break;
|
||||
case 'received-processed': processedList.value = formattedData; break;
|
||||
}
|
||||
pagination.value.total = data.total;
|
||||
} catch (error) {
|
||||
console.error('加载数据失败', error);
|
||||
ElMessage.error('加载数据失败');
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
// 监听菜单变化加载数据
|
||||
watch(activeMenu, () => {
|
||||
if (['received-pending', 'received-processed', 'cc', 'submitted-sent'].includes(activeMenu.value)) {
|
||||
loadData();
|
||||
}
|
||||
});
|
||||
|
||||
// 获取当前列表数据
|
||||
const currentList = computed(() => {
|
||||
switch (activeMenu.value) {
|
||||
case 'received-pending': return pendingList.value;
|
||||
case 'received-processed': return processedList.value;
|
||||
case 'cc': return ccList.value;
|
||||
case 'submitted-sent': return submittedList.value;
|
||||
default: return [];
|
||||
}
|
||||
});
|
||||
|
||||
// 处理申请卡片点击(可扩展为跳转申请页面)
|
||||
const handleCardClick = (item: any) => {
|
||||
console.log('点击申请类型:', item.name);
|
||||
};
|
||||
|
||||
// 处理选择变化
|
||||
const handleSelectionChange = (val) => {
|
||||
multipleSelection.value = val;
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
if (['received-pending', 'received-processed', 'cc', 'submitted-sent'].includes(activeMenu.value)) {
|
||||
loadData();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
|
@ -92,38 +199,21 @@ const handleCardClick = (item: any) => {
|
|||
<!-- 左侧导航栏 -->
|
||||
<div class="sidebar">
|
||||
<div class="custom-menu">
|
||||
<!-- 发起申请(无子类) -->
|
||||
<div class="menu-item" :class="{ 'active': activeMenu === 'apply' }" @click="handleMenuSelect('apply')">
|
||||
发起申请
|
||||
</div>
|
||||
|
||||
<!-- 我收到的(有子类) -->
|
||||
<div class="sub-menu">
|
||||
<div class="sub-menu-title"><span>我收到的</span></div>
|
||||
<div class="sub-menu-items">
|
||||
<div class="menu-item child" :class="{ 'active': activeMenu === 'received-pending' }"
|
||||
@click="handleMenuSelect('received-pending')">
|
||||
待处理
|
||||
</div>
|
||||
<div class="menu-item child" :class="{ 'active': activeMenu === 'received-processed' }"
|
||||
@click="handleMenuSelect('received-processed')">
|
||||
已处理
|
||||
</div>
|
||||
<div class="menu-item child" :class="{ 'active': activeMenu === 'cc' }"
|
||||
@click="handleMenuSelect('cc')">
|
||||
已处理
|
||||
<div class="menu-item child" :class="{ 'active': activeMenu === 'received-pending' }" @click="handleMenuSelect('received-pending')">待处理</div>
|
||||
<div class="menu-item child" :class="{ 'active': activeMenu === 'received-processed' }" @click="handleMenuSelect('received-processed')">已处理</div>
|
||||
<div class="menu-item child" :class="{ 'active': activeMenu === 'cc' }" @click="handleMenuSelect('cc')">抄送我的</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 我提交的(有子类) -->
|
||||
<div class="sub-menu">
|
||||
<div class="sub-menu-title"><span>我提交的</span></div>
|
||||
<div class="sub-menu-items">
|
||||
<div class="menu-item child" :class="{ 'active': activeMenu === 'submitted-sent' }"
|
||||
@click="handleMenuSelect('submitted-sent')">
|
||||
已提交
|
||||
</div>
|
||||
<div class="menu-item child" :class="{ 'active': activeMenu === 'submitted-sent' }" @click="handleMenuSelect('submitted-sent')">已提交</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -132,25 +222,88 @@ const handleCardClick = (item: any) => {
|
|||
<!-- 右侧内容区域 -->
|
||||
<div class="content">
|
||||
<!-- 顶部导航(标签栏+搜索) -->
|
||||
<div class="content-header">
|
||||
<div class="content-header" v-if="activeMenu === 'apply'">
|
||||
<el-tabs v-model="activeTab" type="card" @tab-click="handleTabChange">
|
||||
<el-tab-pane label="全部" name="all"></el-tab-pane>
|
||||
<el-tab-pane label="借还审批" name="shop"></el-tab-pane>
|
||||
<el-tab-pane label="其他" name="other"></el-tab-pane>
|
||||
</el-tabs>
|
||||
|
||||
<el-input v-model="searchKey" placeholder="搜索" prefix-icon="ep:search" class="search-input"
|
||||
@keydown.enter.prevent="handleSearch" />
|
||||
</div>
|
||||
|
||||
<!-- 申请类型列表(根据标签栏切换) -->
|
||||
<div class="application-list">
|
||||
<!-- 搜索表单 -->
|
||||
<el-form v-if="activeMenu !== 'apply'" :inline="true" :model="searchFormParams" class="search-form bg-bg_color flex w-[99/100]">
|
||||
<el-form-item prop="approvalId">
|
||||
<el-input @keydown.enter.prevent="onSearch" v-model.number="searchFormParams.searchStr" placeholder="请输入申请人/商品" clearable class="!w-[250px]" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<!-- 列表视图 -->
|
||||
<div v-if="activeMenu !== 'apply'" class="approval-list">
|
||||
<el-table
|
||||
:data="currentList"
|
||||
v-loading="loading"
|
||||
border
|
||||
style="width: 100%"
|
||||
@selection-change="handleSelectionChange"
|
||||
row-key="approvalId"
|
||||
>
|
||||
<el-table-column type="selection" width="55"></el-table-column>
|
||||
<el-table-column prop="approvalId" label="审批ID" width="100"></el-table-column>
|
||||
<el-table-column prop="name" label="用户姓名" width="100"></el-table-column>
|
||||
<el-table-column prop="mobile" label="手机号" width="120"></el-table-column>
|
||||
<el-table-column prop="goodsName" label="商品名称"></el-table-column>
|
||||
<el-table-column label="商品封面" width="120">
|
||||
<template #default="{ row }">
|
||||
<div v-if="row.coverImg" class="flex gap-2">
|
||||
<el-image v-for="(img, index) in row.coverImg.split(',')" :key="index" :src="img" :preview-src-list="row.coverImg.split(',')" :z-index="9999" :preview-teleported="true" :hide-on-click-modal="true" fit="cover" class="rounded" width="40" height="40" />
|
||||
</div>
|
||||
<span v-else>-</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="goodsPrice" label="商品价格" width="100">
|
||||
<template #default="{ row }">{{ row.goodsPrice }}元</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="paymentMethodStr" label="支付方式" width="100"></el-table-column>
|
||||
<el-table-column prop="returnQuantity" label="归还数量" width="100"></el-table-column>
|
||||
<el-table-column prop="returnAmount" label="退款金额" width="100">
|
||||
<template #default="{ row }">{{ row.returnAmount }}元</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="createTime" label="提交时间" width="180">
|
||||
<template #default="{ row }">{{ row.createTime ? new Date(row.createTime).toLocaleString() : '-' }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="statusStr" label="状态" width="100">
|
||||
<template #default="{ row }">
|
||||
<el-tag :type="{ 1: 'warning', 2: 'success', 3: 'danger' }[row.status]">{{ row.statusStr }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="approvalTime" label="审批时间" width="180">
|
||||
<template #default="{ row }">{{ row.approvalTime ? new Date(row.approvalTime).toLocaleString() : '-' }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="180" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button size="small" type="text">查看</el-button>
|
||||
<el-button size="small" type="text" v-if="activeMenu === 'received-pending'">处理</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<el-pagination
|
||||
v-model:current-page="pagination.currentPage"
|
||||
v-model:page-size="pagination.pageSize"
|
||||
:page-sizes="[5, 10, 20, 50]"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
:total="pagination.total"
|
||||
@size-change="handlePaginationChange"
|
||||
@current-change="handlePaginationChange"
|
||||
class="pagination mt-4"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- 申请类型列表 -->
|
||||
<div class="application-list" v-if="activeMenu === 'apply'">
|
||||
<el-row :gutter="16">
|
||||
<el-col v-for="(item, index) in filteredApplications" :key="index" :xs="24" :sm="12" :md="8" :lg="6" :xl="4">
|
||||
<div class="application-card" @click="handleCardClick(item)">
|
||||
<el-icon class="card-icon" :style="{ color: item.color }">
|
||||
<component :is="item.icon" />
|
||||
</el-icon>
|
||||
<el-icon class="card-icon" :style="{ color: item.color }"><component :is="item.icon" /></el-icon>
|
||||
<div class="card-name">{{ item.name }}</div>
|
||||
</div>
|
||||
</el-col>
|
||||
|
@ -303,5 +456,26 @@ const handleCardClick = (item: any) => {
|
|||
color: #333;
|
||||
}
|
||||
}
|
||||
|
||||
/* 审批列表样式 */
|
||||
.approval-list {
|
||||
|
||||
.el-table {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.el-table__header th {
|
||||
background-color: #f8f9fa;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.el-button--text {
|
||||
color: #409eff;
|
||||
|
||||
&:hover {
|
||||
color: #66b1ff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
Loading…
Reference in New Issue