refactor(manager): 重构商品/审核/品牌/分词/分销提现与等级等7个核心列表页为 useTable

- 重构商品管理(商品总览、商品审核)列表页为 useTable

- 重构商品维护(品牌管理、评价管理)列表页为 useTable

- 重构分销管理(分销提现、等级变动历史)与自定义分词列表页为 useTable

- 消除 150+ 行重复样板代码,统一竞态防护与分页查询规范
This commit is contained in:
pikachu1995@126.com
2026-10-20 14:56:06 +08:00
parent cba624f480
commit 5e74e356e0
7 changed files with 347 additions and 503 deletions

View File

@@ -209,8 +209,8 @@
:total="total"
layout="total, sizes, prev, pager, next, jumper"
size="small"
@current-change="changePage"
@size-change="changePageSize"
@current-change="getDataList"
@size-change="() => { searchForm.pageNumber = 1; getDataList(); }"
/>
</div>
</el-card>
@@ -300,6 +300,7 @@
<script setup>
import { computed, nextTick, onMounted, reactive, ref } from "vue";
import { useTable } from "@/utils/useTable";
import {
getGoodsListData,
getGoodsNumerData,
@@ -322,32 +323,50 @@ const auditForm = ref(null);
const batchAuditFormRef = ref(null);
const goodsGroupFormRef = ref(null);
const id = ref(""); //要操作的id
const loading = ref(true); // 表单加载状态
const modalVisible = ref(false); // 添加或编辑显示
const searchForm = reactive({
// 搜索框初始化对象
pageNumber: 1, // 当前页数
pageSize: 20, // 页面大小
sort: "create_time", // 默认排序字段
order: "desc", // 默认排序方式
groupId: "",
});
const underForm = reactive({
// 下架原因
reason: "",
});
const goodsAuditForm = reactive({
// 商品审核表单
auth_flag: 1,
});
const auditModalVisible = ref(false); // 审核弹框显示状态
const id = ref("");
const modalVisible = ref(false);
const underForm = reactive({ reason: "" });
const goodsAuditForm = reactive({ auth_flag: 1 });
const auditModalVisible = ref(false);
const auditSubmitLoading = ref(false);
const currentAuditGoods = ref(null); // 当前审核的商品
const submitLoading = ref(false); // 添加或编辑提交状态
const data = ref([]); // 表单数据
const total = ref(0); // 表单数据总数
const currentAuditGoods = ref(null);
const submitLoading = ref(false);
const currentStatus = ref("ALL");
const { loading, data, total, searchForm, getDataList, handleSearch, resetSearch } = useTable(
getGoodsListData,
{
pageSize: 20,
sort: "create_time",
order: "desc",
immediate: false,
form: {
goodsName: "",
id: "",
storeName: "",
salesModel: "",
goodsType: "",
groupId: "",
},
beforeRequest: (p) => {
const params = { ...p };
if (currentStatus.value && currentStatus.value !== "ALL") {
params.goodsStatus = currentStatus.value;
} else {
delete params.goodsStatus;
}
return params;
},
onSuccess: () => {
getNumberData();
},
}
);
function handleReset() {
currentStatus.value = "ALL";
resetSearch();
}
const goodsNumerData = ref({});
const selectedRows = ref([]); // 选中的行数据
const selectAll = ref(false); // 全选状态
@@ -414,33 +433,9 @@ function init() {
loadGoodsGroupList();
}
// 分页 改变页码
function changePage(v) {
searchForm.pageNumber = v;
getDataList();
}
// 分页 改变页数
function changePageSize(v) {
searchForm.pageSize = v;
getDataList();
}
// 搜索
function handleSearch() {
searchForm.pageNumber = 1;
searchForm.pageSize = 20;
getDataList();
getNumberData();
}
// 获取数据
function getDataList() {
loading.value = true;
getGoodsListData(searchForm).then((res) => {
loading.value = false;
if (res.success) {
data.value = res.result.records;
total.value = res.result.total;
}
});
}
function getNumberData() {
// 创建一个不包含goodsStatus字段的搜索参数
const { goodsStatus, ...searchParams } = searchForm;

View File

@@ -27,12 +27,13 @@
</el-form-item>
<el-form-item>
<el-button type="primary" class="search-btn" @click="handleSearch">搜索</el-button>
<el-button @click="resetSearch">重置</el-button>
</el-form-item>
</el-form>
</el-card>
<el-card>
<el-table v-loading="loading" :data="data" ref="table" class="mt_10" style="width: 100%">
<el-card class="mt_10">
<el-table v-loading="loading" :data="data" ref="table" style="width: 100%">
<el-table-column label="商品名称" min-width="220" class-name="goods-name-column">
<template #default="{ row }">
<div v-if="row" class="goods-name-cell">
@@ -60,13 +61,13 @@
<el-table-column prop="storeName" label="店铺名称" min-width="120" show-overflow-tooltip />
<el-table-column label="操作" width="200" align="center" fixed="right">
<template #default="{ row }">
<template v-if="row">
<div v-if="row">
<a class="link-text" @click="examine(row, 1)">通过</a>
<span class="op-split">|</span>
<a class="link-text" @click="examine(row, 2)">拒绝</a>
<span class="op-split">|</span>
<a class="link-text" @click="showDetail(row)">查看</a>
</template>
</div>
</template>
</el-table-column>
</el-table>
@@ -79,8 +80,8 @@
:total="total"
layout="total, sizes, prev, pager, next, jumper"
size="small"
@current-change="changePage"
@size-change="changePageSize"
@current-change="getDataList"
@size-change="() => { searchForm.pageNumber = 1; getDataList(); }"
/>
</div>
</el-card>
@@ -88,29 +89,30 @@
</template>
<script setup>
import { onMounted, ref } from "vue";
import { ref } from "vue";
import { useTable } from "@/utils/useTable";
import { authGoods, getAuthGoodsListData } from "@/api/goods";
import { ElMessage, ElMessageBox } from "element-plus";
import { unitPrice, customRouterPush } from "@/utils/filters";
defineOptions({ name: "goodsApply" });
// 模板中 el-form 的 ref 与数据 searchForm 同名,避免相互覆盖改名
const searchFormRef = ref(null);
const table = ref(null);
const loading = ref(true);
const searchForm = ref({
pageNumber: 1,
pageSize: 20,
sort: "create_time",
order: "desc",
});
const goodsAuditForm = ref({
auth_flag: 1,
});
const data = ref([]);
const total = ref(0);
const { loading, data, total, searchForm, getDataList, handleSearch, resetSearch } = useTable(
getAuthGoodsListData,
{
pageSize: 20,
sort: "create_time",
order: "desc",
form: {
goodsName: "",
id: "",
authFlag: 0,
},
}
);
function authFlagText(v) {
const map = {
@@ -120,6 +122,7 @@ function authFlagText(v) {
};
return map[v] || v || "-";
}
function authFlagTagType(v) {
const map = {
TOBEAUDITED: "warning",
@@ -128,44 +131,14 @@ function authFlagTagType(v) {
};
return map[v] || "info";
}
function init() {
getDataList();
}
function changePage(v) {
searchForm.value.pageNumber = v;
getDataList();
}
function changePageSize(v) {
searchForm.value.pageSize = v;
getDataList();
}
function handleSearch() {
searchForm.value.pageNumber = 1;
searchForm.value.pageSize = 20;
getDataList();
}
function getDataList() {
loading.value = true;
searchForm.value.authFlag = 0;
getAuthGoodsListData(searchForm.value)
.then((res) => {
loading.value = false;
if (res.success) {
data.value = res.result.records;
total.value = res.result.total;
}
})
.catch(() => {
loading.value = false;
});
}
function examine(v, authFlag) {
const examine = authFlag === 1 ? "通过" : "拒绝";
goodsAuditForm.value.authFlag = authFlag === 1 ? "PASS" : "REFUSE";
ElMessageBox.confirm(`您确认要审核${examine} ${v.goodsName} ?`, "确认审核", { type: "warning" }).then(() => {
const examineText = authFlag === 1 ? "通过" : "拒绝";
const authStatus = authFlag === 1 ? "PASS" : "REFUSE";
ElMessageBox.confirm(`您确认要审核${examineText} ${v.goodsName} ?`, "确认审核", { type: "warning" }).then(() => {
const formData = new FormData();
formData.append("goodsIds", v.id);
formData.append("authFlag", goodsAuditForm.value.authFlag);
formData.append("authFlag", authStatus);
return authGoods(formData).then((res) => {
if (res.success) {
ElMessage.success("审核成功");
@@ -174,16 +147,13 @@ function examine(v, authFlag) {
});
}).catch(() => {});
}
function showDetail(v) {
customRouterPush({
name: "goods-detail",
query: { id: v.id },
});
}
onMounted(() => {
init();
});
</script>
<style scoped>