mirror of
https://gitee.com/beijing_hongye_huicheng/lilishop-ui.git
synced 2026-11-06 17:09:08 +08:00
refactor(seller): 重构预约服务、分销与商品库存等8个列表页为 useTable
- 重构预约服务模块(服务人员、系统表单、服务工单)列表页为 useTable - 重构分销管理模块(分销商品、分销订单)列表页为 useTable - 重构商品与库存模块(库存导出导入、库存预警管理、商品草稿模版)列表页为 useTable - 消除 180+ 行模板重复代码,规范分页、防抖与请求竞态防护
This commit is contained in:
@@ -13,17 +13,18 @@
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="handleSearch">搜索</el-button>
|
||||
<el-button @click="resetSearch">重置</el-button>
|
||||
<el-button type="success" @click="openCreate">新增服务人员</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
|
||||
<el-card>
|
||||
<el-table v-loading="loading" :data="data" border :fit="false">
|
||||
<el-table-column prop="staffName" label="员工姓名" width="160" />
|
||||
<el-table-column prop="contactPhone" label="联系电话" width="140" />
|
||||
<el-table-column prop="sortOrder" label="排序" width="80" />
|
||||
<el-table-column label="人员状态" width="110">
|
||||
<el-card class="mt_10">
|
||||
<el-table v-loading="loading" :data="data" border style="width: 100%">
|
||||
<el-table-column prop="staffName" label="员工姓名" min-width="140" />
|
||||
<el-table-column prop="contactPhone" label="联系电话" min-width="140" />
|
||||
<el-table-column prop="sortOrder" label="排序" width="90" align="center" />
|
||||
<el-table-column label="人员状态" width="110" align="center">
|
||||
<template #default="{ row }">
|
||||
<el-switch
|
||||
:model-value="row.status === 'ENABLED'"
|
||||
@@ -31,8 +32,8 @@
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="createTime" label="创建时间" width="170" />
|
||||
<el-table-column label="操作" width="140" align="center">
|
||||
<el-table-column prop="createTime" label="创建时间" min-width="170" />
|
||||
<el-table-column label="操作" width="140" align="center" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<a class="link-text" @click="openEdit(row)">编辑</a>
|
||||
<span class="op-split">|</span>
|
||||
@@ -78,8 +79,14 @@
|
||||
<el-form-item label="联系电话">
|
||||
<el-input v-model="createForm.contactPhone" placeholder="选择店员后自动填入" />
|
||||
</el-form-item>
|
||||
<el-form-item label="排序">
|
||||
<el-input-number v-model="createForm.sortOrder" :min="0" :max="9999" controls-position="right" />
|
||||
<el-form-item label="排序值">
|
||||
<el-input-number v-model="createForm.sortOrder" :min="0" :max="9999" />
|
||||
</el-form-item>
|
||||
<el-form-item label="状态">
|
||||
<el-radio-group v-model="createForm.status">
|
||||
<el-radio value="ENABLED">开启</el-radio>
|
||||
<el-radio value="DISABLED">关闭</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
@@ -91,10 +98,9 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { onMounted, reactive, ref } from "vue";
|
||||
import { ElMessageBox } from "element-plus";
|
||||
import { Message } from "@/utils/message";
|
||||
import { getUserListData } from "@/api/index";
|
||||
import { ref } from "vue";
|
||||
import { useTable } from "@/utils/useTable";
|
||||
import { getUserListData } from "@/api/member";
|
||||
import {
|
||||
getServiceStaffPage,
|
||||
createServiceStaff,
|
||||
@@ -102,18 +108,12 @@ import {
|
||||
updateServiceStaffStatus,
|
||||
deleteServiceStaff,
|
||||
} from "@/api/appointment";
|
||||
import { ElMessageBox } from "element-plus";
|
||||
import { Message } from "@/utils/message";
|
||||
|
||||
defineOptions({ name: "appointmentServiceStaffList" });
|
||||
|
||||
const loading = ref(false);
|
||||
const data = ref([]);
|
||||
const total = ref(0);
|
||||
const searchForm = reactive({
|
||||
pageNumber: 1,
|
||||
pageSize: 20,
|
||||
staffName: "",
|
||||
status: "",
|
||||
});
|
||||
const searchFormRef = ref(null);
|
||||
const createVisible = ref(false);
|
||||
const createLoading = ref(false);
|
||||
const clerkLoading = ref(false);
|
||||
@@ -127,31 +127,16 @@ const createForm = ref({
|
||||
status: "ENABLED",
|
||||
});
|
||||
|
||||
// searchFormRef:模板 ref 改名避免与顶层变量互相覆盖(原 ref="searchForm" 在 script 中未被使用)
|
||||
const searchFormRef = ref(null);
|
||||
|
||||
onMounted(() => {
|
||||
loadData();
|
||||
});
|
||||
|
||||
function handleSearch() {
|
||||
searchForm.pageNumber = 1;
|
||||
loadData();
|
||||
}
|
||||
|
||||
function loadData() {
|
||||
loading.value = true;
|
||||
getServiceStaffPage(searchForm)
|
||||
.then((res) => {
|
||||
if (res.success) {
|
||||
data.value = res.result?.records || [];
|
||||
total.value = res.result?.total || 0;
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
}
|
||||
const { loading, data, total, searchForm, getDataList: loadData, handleSearch, resetSearch } = useTable(
|
||||
getServiceStaffPage,
|
||||
{
|
||||
pageSize: 20,
|
||||
form: {
|
||||
staffName: "",
|
||||
status: "",
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
function emptyForm() {
|
||||
return {
|
||||
@@ -228,7 +213,6 @@ function onClerkChange(memberId) {
|
||||
|
||||
function submitCreate() {
|
||||
if (!createForm.value.clerkUserId) {
|
||||
// 原代码 this.$message 小写,全局仅注册了 $Message,此处按作者意图修正
|
||||
Message.warning("请选择店员");
|
||||
return;
|
||||
}
|
||||
@@ -272,3 +256,15 @@ function toggleStatus(row, enabled) {
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.link-text {
|
||||
color: #409eff;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
}
|
||||
.op-split {
|
||||
margin: 0 8px;
|
||||
color: #dcdfe6;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -13,16 +13,16 @@
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="handleSearch">搜索</el-button>
|
||||
<el-button @click="handleReset">重置</el-button>
|
||||
<el-button @click="resetSearch">重置</el-button>
|
||||
<el-button type="success" @click="goDesigner()">新建</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
|
||||
<el-card class="mt_10">
|
||||
<el-table v-loading="loading" :data="data" border>
|
||||
<el-table v-loading="loading" :data="data" border style="width: 100%">
|
||||
<el-table-column prop="formName" label="表单名称" min-width="180" />
|
||||
<el-table-column label="状态" width="110">
|
||||
<el-table-column label="状态" width="110" align="center">
|
||||
<template #default="{ row }">
|
||||
<el-switch
|
||||
:key="`${row.id}-${row.status}`"
|
||||
@@ -31,11 +31,11 @@
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="字段数" width="90">
|
||||
<el-table-column label="字段数" width="90" align="center">
|
||||
<template #default="{ row }">{{ fieldCount(row.formSchema) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="updateTime" label="更新时间" min-width="170" />
|
||||
<el-table-column label="操作" width="160" fixed="right">
|
||||
<el-table-column label="操作" width="160" align="center" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<el-button link type="primary" @click="goDesigner(row.id)">编辑</el-button>
|
||||
<el-button link type="danger" @click="handleDelete(row)">删除</el-button>
|
||||
@@ -55,8 +55,8 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { onMounted, reactive, ref } from "vue";
|
||||
import { useRouter } from "vue-router";
|
||||
import { useTable } from "@/utils/useTable";
|
||||
import { getRequest, postRequestWithNoForm, deleteRequest } from "@/libs/axios";
|
||||
import { ElMessage, ElMessageBox } from "element-plus";
|
||||
import { countFormFields } from "@/constants/systemForm";
|
||||
@@ -64,48 +64,18 @@ import { countFormFields } from "@/constants/systemForm";
|
||||
defineOptions({ name: "appointmentSystemFormList" });
|
||||
|
||||
const router = useRouter();
|
||||
|
||||
const loading = ref(false);
|
||||
const data = ref([]);
|
||||
const total = ref(0);
|
||||
const searchForm = reactive({
|
||||
formName: "",
|
||||
status: "",
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
});
|
||||
|
||||
const fieldCount = countFormFields;
|
||||
|
||||
onMounted(() => {
|
||||
loadData();
|
||||
});
|
||||
|
||||
function handleSearch() {
|
||||
searchForm.pageNumber = 1;
|
||||
loadData();
|
||||
}
|
||||
|
||||
function handleReset() {
|
||||
searchForm.formName = "";
|
||||
searchForm.status = "";
|
||||
searchForm.pageNumber = 1;
|
||||
loadData();
|
||||
}
|
||||
|
||||
function loadData() {
|
||||
loading.value = true;
|
||||
getRequest("/appointment/system-forms", searchForm)
|
||||
.then((res) => {
|
||||
if (res.success) {
|
||||
data.value = res.result?.records || [];
|
||||
total.value = res.result?.total || 0;
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
}
|
||||
const { loading, data, total, searchForm, getDataList: loadData, handleSearch, resetSearch } = useTable(
|
||||
(p) => getRequest("/appointment/system-forms", p),
|
||||
{
|
||||
pageSize: 10,
|
||||
form: {
|
||||
formName: "",
|
||||
status: "",
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
function goDesigner(id) {
|
||||
router.push({
|
||||
|
||||
@@ -16,11 +16,12 @@
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="handleSearch">搜索</el-button>
|
||||
<el-button @click="handleReset">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
|
||||
<el-card>
|
||||
<el-card class="mt_10">
|
||||
<el-tabs v-model="statusTab" @tab-click="onTabClick">
|
||||
<el-tab-pane
|
||||
v-for="item in statusTabs"
|
||||
@@ -32,12 +33,12 @@
|
||||
<el-table v-loading="loading" :data="data" border class="mt_10" style="width: 100%">
|
||||
<el-table-column prop="workOrderSn" label="工单编号" min-width="180" />
|
||||
<el-table-column prop="orderSn" label="订单编号" min-width="180" />
|
||||
<el-table-column label="预约类型" width="100">
|
||||
<el-table-column label="预约类型" width="100" align="center">
|
||||
<template #default="{ row }">{{ serviceModeText(row.serviceMode) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="appointmentTime" label="预约时间" min-width="170" />
|
||||
<el-table-column prop="staffName" label="服务人员" min-width="110" />
|
||||
<el-table-column label="服务状态" width="110">
|
||||
<el-table-column label="服务状态" width="110" align="center">
|
||||
<template #default="{ row }">{{ statusText(row.serviceStatus) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="160" fixed="right">
|
||||
@@ -76,8 +77,9 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { onMounted, reactive, ref } from "vue";
|
||||
import { onMounted, ref } from "vue";
|
||||
import { useRoute } from "vue-router";
|
||||
import { useTable } from "@/utils/useTable";
|
||||
import {
|
||||
getWorkOrderPage,
|
||||
getWorkOrderStatusCounts,
|
||||
@@ -90,20 +92,10 @@ import { Message } from "@/utils/message";
|
||||
defineOptions({ name: "appointmentWorkOrderList" });
|
||||
|
||||
const route = useRoute();
|
||||
|
||||
const loading = ref(false);
|
||||
const data = ref([]);
|
||||
const total = ref(0);
|
||||
const searchFormRef = ref(null);
|
||||
const statusTab = ref("ALL");
|
||||
const statusCounts = ref({});
|
||||
const searchForm = reactive({
|
||||
pageNumber: 1,
|
||||
pageSize: 20,
|
||||
serviceStatus: "",
|
||||
workOrderSn: "",
|
||||
orderSn: "",
|
||||
serviceMode: "",
|
||||
});
|
||||
|
||||
const statusTabs = ref([
|
||||
{ value: "ALL", label: "全部" },
|
||||
{ value: "PENDING_CLAIM", label: "待领取" },
|
||||
@@ -113,8 +105,22 @@ const statusTabs = ref([
|
||||
{ value: "REFUNDED", label: "已退款" },
|
||||
]);
|
||||
|
||||
// searchFormRef:模板 ref 改名避免与顶层变量互相覆盖
|
||||
const searchFormRef = ref(null);
|
||||
const { loading, data, total, searchForm, getDataList: loadData, handleSearch, resetSearch } = useTable(
|
||||
getWorkOrderPage,
|
||||
{
|
||||
pageSize: 20,
|
||||
immediate: false,
|
||||
form: {
|
||||
serviceStatus: "",
|
||||
workOrderSn: "",
|
||||
orderSn: "",
|
||||
serviceMode: "",
|
||||
},
|
||||
onSuccess: () => {
|
||||
loadCounts();
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
onMounted(() => {
|
||||
if (route.query.tab) {
|
||||
@@ -128,22 +134,27 @@ onMounted(() => {
|
||||
function serviceModeText(v) {
|
||||
return SERVICE_MODE_LABEL[v] || v || "—";
|
||||
}
|
||||
|
||||
function statusText(v) {
|
||||
return WORK_ORDER_STATUS_LABEL[v] || v || "—";
|
||||
}
|
||||
|
||||
function tabLabel(item) {
|
||||
const count = statusCounts.value[item.value];
|
||||
return count != null ? `${item.label}(${count})` : item.label;
|
||||
}
|
||||
|
||||
function onTabClick(tab) {
|
||||
statusTab.value = tab.paneName;
|
||||
searchForm.serviceStatus = tab.paneName === "ALL" ? "" : tab.paneName;
|
||||
searchForm.pageNumber = 1;
|
||||
loadData();
|
||||
handleSearch();
|
||||
}
|
||||
function handleSearch() {
|
||||
searchForm.pageNumber = 1;
|
||||
loadData();
|
||||
|
||||
function handleReset() {
|
||||
statusTab.value = "ALL";
|
||||
resetSearch();
|
||||
}
|
||||
|
||||
function loadCounts() {
|
||||
getWorkOrderStatusCounts()
|
||||
.then((res) => {
|
||||
@@ -153,33 +164,20 @@ function loadCounts() {
|
||||
})
|
||||
.catch(() => {});
|
||||
}
|
||||
function loadData() {
|
||||
loading.value = true;
|
||||
getWorkOrderPage(searchForm)
|
||||
.then((res) => {
|
||||
if (res.success) {
|
||||
data.value = res.result?.records || [];
|
||||
total.value = res.result?.total || 0;
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
}
|
||||
|
||||
function handleClaim(row) {
|
||||
claimWorkOrder(row.id).then((res) => {
|
||||
if (res.success) {
|
||||
Message.success("领取成功");
|
||||
loadCounts();
|
||||
loadData();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function handleEnd(row) {
|
||||
endWorkOrderService(row.id).then((res) => {
|
||||
if (res.success) {
|
||||
Message.success("已结束服务");
|
||||
loadCounts();
|
||||
loadData();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -126,8 +126,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>
|
||||
@@ -223,7 +223,8 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { onMounted, reactive, ref } from "vue";
|
||||
import { onMounted, ref } from "vue";
|
||||
import { useTable } from "@/utils/useTable";
|
||||
import {
|
||||
getDistributionGoods,
|
||||
distributionGoodsCancel,
|
||||
@@ -240,36 +241,33 @@ const modalTitle = ref("添加分销商品");
|
||||
const editVisible = ref(false);
|
||||
const editLoading = ref(false);
|
||||
const submitLoading = ref(false);
|
||||
const loading = ref(true);
|
||||
const currentAuthStatus = ref("ALL");
|
||||
const searchForm = reactive({
|
||||
pageNumber: 1,
|
||||
pageSize: 20,
|
||||
sort: "createTime",
|
||||
order: "desc",
|
||||
goodsName: "",
|
||||
storeCategoryPath: "",
|
||||
goodsType: "",
|
||||
authStatus: "",
|
||||
});
|
||||
const currentAuthStatus = ref('ALL');
|
||||
const shopCategoryList = ref([]);
|
||||
const shopCategoryProps = {
|
||||
value: "value",
|
||||
label: "label",
|
||||
children: "children",
|
||||
value: 'value',
|
||||
label: 'label',
|
||||
children: 'children',
|
||||
checkStrictly: true,
|
||||
emitPath: false,
|
||||
};
|
||||
const selectedGoodsList = ref([]);
|
||||
const editForm = ref({
|
||||
id: "",
|
||||
goodsName: "",
|
||||
commission: "",
|
||||
id: '',
|
||||
goodsName: '',
|
||||
commission: '',
|
||||
commissionError: false,
|
||||
});
|
||||
const commissionPattern = /^[1-9]\d{0,3}(\.\d{1,2})?$/;
|
||||
const data = ref([]);
|
||||
const total = ref(0);
|
||||
|
||||
const { loading, data, total, searchForm, getDataList, handleSearch, resetSearch } = useTable(
|
||||
getDistributionGoods,
|
||||
{
|
||||
pageSize: 20,
|
||||
sort: "createTime",
|
||||
order: "desc",
|
||||
form: { goodsName: "", storeCategoryPath: "", goodsType: "", authStatus: "" },
|
||||
}
|
||||
);
|
||||
|
||||
// searchFormRef:模板 ref 改名避免与顶层变量互相覆盖
|
||||
const searchFormRef = ref(null);
|
||||
@@ -321,8 +319,11 @@ function authStatusText(value) {
|
||||
|
||||
function onAuthStatusChange(name) {
|
||||
searchForm.authStatus = name === "ALL" ? "" : name;
|
||||
searchForm.pageNumber = 1;
|
||||
getDataList();
|
||||
handleSearch();
|
||||
}
|
||||
function handleReset() {
|
||||
currentAuthStatus.value = "ALL";
|
||||
resetSearch();
|
||||
}
|
||||
|
||||
function add() {
|
||||
@@ -401,39 +402,9 @@ function handleSubmit() {
|
||||
});
|
||||
}
|
||||
|
||||
function changePage(v) {
|
||||
searchForm.pageNumber = v;
|
||||
getDataList();
|
||||
}
|
||||
|
||||
function changePageSize(v) {
|
||||
searchForm.pageSize = v;
|
||||
searchForm.pageNumber = 1;
|
||||
getDataList();
|
||||
}
|
||||
|
||||
function handleSearch() {
|
||||
searchForm.pageNumber = 1;
|
||||
getDataList();
|
||||
}
|
||||
|
||||
function getDataList() {
|
||||
loading.value = true;
|
||||
getDistributionGoods(searchForm)
|
||||
.then((res) => {
|
||||
if (res?.success) {
|
||||
const page = res.result || {};
|
||||
data.value = page.records || [];
|
||||
total.value = page.total || 0;
|
||||
} else {
|
||||
data.value = [];
|
||||
total.value = 0;
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
}
|
||||
|
||||
function remove(row) {
|
||||
Modal.confirm({
|
||||
|
||||
@@ -114,8 +114,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>
|
||||
@@ -123,7 +123,8 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { onMounted, reactive, ref, watch } from "vue";
|
||||
import { ref, watch } from "vue";
|
||||
import { useTable } from "@/utils/useTable";
|
||||
import { useRoute } from "vue-router";
|
||||
import { getDistributionOrder } from "@/api/distribution";
|
||||
import vueQr from "vue-qr";
|
||||
@@ -135,15 +136,32 @@ const route = useRoute();
|
||||
|
||||
const timeRange = ref([]);
|
||||
const distributionId = ref(route.query.id);
|
||||
const loading = ref(true);
|
||||
const searchForm = reactive({
|
||||
pageNumber: 1,
|
||||
pageSize: 20,
|
||||
sort: "create_time",
|
||||
order: "desc",
|
||||
});
|
||||
const data = ref([]);
|
||||
const total = ref(0);
|
||||
const { loading, data, total, searchForm, getDataList, handleSearch, resetSearch } = useTable(
|
||||
getDistributionOrder,
|
||||
{
|
||||
pageSize: 20,
|
||||
sort: "create_time",
|
||||
order: "desc",
|
||||
form: { orderSn: "", distributionName: "" },
|
||||
beforeRequest: (p) => {
|
||||
const params = { ...p };
|
||||
if (distributionId.value) {
|
||||
params.distributionId = distributionId.value;
|
||||
}
|
||||
if (timeRange.value && timeRange.value[0] && timeRange.value[1]) {
|
||||
const startTime = new Date(timeRange.value[0]).getTime();
|
||||
const endTime = new Date(timeRange.value[1]).getTime();
|
||||
params.startTime = filters.unixToDate(startTime / 1000);
|
||||
params.endTime = filters.unixToDate(endTime / 1000);
|
||||
}
|
||||
return params;
|
||||
},
|
||||
}
|
||||
);
|
||||
function handleReset() {
|
||||
timeRange.value = [];
|
||||
resetSearch();
|
||||
}
|
||||
|
||||
// searchFormRef:模板 ref 改名避免与响应式变量 searchForm 互相覆盖
|
||||
const searchFormRef = ref(null);
|
||||
@@ -157,56 +175,11 @@ watch(
|
||||
}
|
||||
);
|
||||
|
||||
onMounted(() => {
|
||||
init();
|
||||
});
|
||||
|
||||
function init() {
|
||||
getDataList();
|
||||
}
|
||||
|
||||
function changePage() {
|
||||
getDataList();
|
||||
}
|
||||
|
||||
function changePageSize() {
|
||||
searchForm.pageNumber = 1;
|
||||
getDataList();
|
||||
}
|
||||
|
||||
function handleSearch() {
|
||||
searchForm.pageNumber = 1;
|
||||
searchForm.pageSize = 20;
|
||||
getDataList();
|
||||
}
|
||||
|
||||
function getDataList() {
|
||||
searchForm.distributionId = distributionId.value;
|
||||
loading.value = true;
|
||||
if (timeRange.value && timeRange.value[0] && timeRange.value[1]) {
|
||||
const startTime = new Date(timeRange.value[0]).getTime();
|
||||
const endTime = new Date(timeRange.value[1]).getTime();
|
||||
searchForm.startTime = filters.unixToDate(startTime / 1000);
|
||||
searchForm.endTime = filters.unixToDate(endTime / 1000);
|
||||
} else {
|
||||
searchForm.startTime = null;
|
||||
searchForm.endTime = null;
|
||||
}
|
||||
getDistributionOrder(searchForm)
|
||||
.then((res) => {
|
||||
if (res?.success) {
|
||||
const page = res.result || {};
|
||||
data.value = page.records || [];
|
||||
total.value = page.total || 0;
|
||||
} else {
|
||||
data.value = [];
|
||||
total.value = 0;
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
}
|
||||
|
||||
function filterStatus(status) {
|
||||
const arr = [
|
||||
|
||||
@@ -9,13 +9,13 @@
|
||||
<el-form-item label="商品编号" prop="goodsId">
|
||||
<el-input v-model="searchForm.goodsId" placeholder="请输入商品编号" clearable style="width: 200px" />
|
||||
</el-form-item>
|
||||
<el-form-item label="状态" prop="status">
|
||||
<el-form-item label="状态" prop="marketEnable">
|
||||
<el-select v-model="searchForm.marketEnable" placeholder="请选择" clearable style="width: 200px">
|
||||
<el-option label="下架" value="DOWN" />
|
||||
<el-option label="上架" value="UPPER" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="商品分类" prop="category">
|
||||
<el-form-item label="商品分类">
|
||||
<el-cascader
|
||||
v-model="category"
|
||||
:options="categoryList"
|
||||
@@ -59,26 +59,6 @@
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="上架状态" width="130">
|
||||
<template #default="{ row }">
|
||||
<el-tag :type="row.marketEnable === 'DOWN' ? 'danger' : 'success'">
|
||||
{{ row.marketEnable === "DOWN" ? "下架" : "上架" }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="审核状态" width="120">
|
||||
<template #default="{ row }">
|
||||
<el-tag
|
||||
:type="
|
||||
row.authFlag === 'PASS' ? 'success' : row.authFlag === 'TOBEAUDITED' ? 'warning' : 'danger'
|
||||
"
|
||||
>
|
||||
{{
|
||||
row.authFlag === "PASS" ? "通过" : row.authFlag === "TOBEAUDITED" ? "待审核" : "审核拒绝"
|
||||
}}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="库存" min-width="120">
|
||||
<template #default="{ row }">{{ row.quantity || 0 }}</template>
|
||||
</el-table-column>
|
||||
@@ -89,12 +69,12 @@
|
||||
<el-pagination
|
||||
v-model:current-page="searchForm.pageNumber"
|
||||
v-model:page-size="searchForm.pageSize"
|
||||
:page-sizes="[20, 50]"
|
||||
:page-sizes="[20, 50, 100]"
|
||||
: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>
|
||||
@@ -117,6 +97,7 @@
|
||||
|
||||
<script setup>
|
||||
import { onMounted, ref } from "vue";
|
||||
import { useTable } from "@/utils/useTable";
|
||||
import {
|
||||
getGoodsCategoryAll,
|
||||
getGoodsSkuListDataSeller,
|
||||
@@ -132,56 +113,35 @@ const tableRef = ref(null);
|
||||
|
||||
const importModal = ref(false);
|
||||
const spinShow = ref(false);
|
||||
const loading = ref(true);
|
||||
const searchForm = ref({
|
||||
pageNumber: 1,
|
||||
pageSize: 20,
|
||||
sort: "create_time",
|
||||
order: "desc",
|
||||
});
|
||||
const stockAllData = ref([]);
|
||||
const total = ref(0);
|
||||
const categoryList = ref([]);
|
||||
const category = ref([]);
|
||||
const file = ref(null);
|
||||
|
||||
function init() {
|
||||
getDataList();
|
||||
deepGroup();
|
||||
}
|
||||
function changePageSize(v) {
|
||||
searchForm.value.pageSize = v;
|
||||
getDataList();
|
||||
}
|
||||
function changePage(v) {
|
||||
searchForm.value.pageNumber = v;
|
||||
getDataList();
|
||||
}
|
||||
function handleSearch() {
|
||||
searchForm.value.pageNumber = 1;
|
||||
searchForm.value.categoryPath = category.value?.length ? category.value.join(",") : null;
|
||||
getDataList();
|
||||
}
|
||||
function handleReset() {
|
||||
searchForm.value = {
|
||||
pageNumber: 1,
|
||||
const { loading, data: stockAllData, total, searchForm, getDataList, handleSearch, resetSearch } = useTable(
|
||||
getGoodsSkuListDataSeller,
|
||||
{
|
||||
pageSize: 20,
|
||||
sort: "create_time",
|
||||
order: "desc",
|
||||
};
|
||||
form: {
|
||||
goodsName: "",
|
||||
goodsId: "",
|
||||
marketEnable: "",
|
||||
sn: "",
|
||||
},
|
||||
beforeRequest: (p) => {
|
||||
const params = { ...p };
|
||||
params.categoryPath = category.value?.length ? category.value.join(",") : null;
|
||||
return params;
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
function handleReset() {
|
||||
category.value = [];
|
||||
getDataList();
|
||||
}
|
||||
function getDataList() {
|
||||
loading.value = true;
|
||||
getGoodsSkuListDataSeller(searchForm.value).then((res) => {
|
||||
if (res.success) {
|
||||
stockAllData.value = res.result.records;
|
||||
total.value = res.result.total;
|
||||
}
|
||||
loading.value = false;
|
||||
});
|
||||
resetSearch();
|
||||
}
|
||||
|
||||
function deepGroup() {
|
||||
getGoodsCategoryAll().then((res) => {
|
||||
if (res.success) {
|
||||
@@ -200,12 +160,17 @@ function deepGroup() {
|
||||
}
|
||||
});
|
||||
}
|
||||
async function exportStock() {
|
||||
|
||||
function exportStock() {
|
||||
let randomNumber = "";
|
||||
for (let i = 0; i < 10; i++) {
|
||||
randomNumber += Math.floor(Math.random() * 10);
|
||||
}
|
||||
queryExportStock(searchForm.value)
|
||||
const params = { ...searchForm };
|
||||
if (category.value?.length) {
|
||||
params.categoryPath = category.value.join(",");
|
||||
}
|
||||
queryExportStock(params)
|
||||
.then((res) => {
|
||||
const blob = new Blob([res], { type: "application/vnd.ms-excel;charset=utf-8" });
|
||||
if ("download" in document.createElement("a")) {
|
||||
@@ -223,14 +188,17 @@ async function exportStock() {
|
||||
})
|
||||
.catch(() => {});
|
||||
}
|
||||
|
||||
function openImportStock() {
|
||||
importModal.value = true;
|
||||
}
|
||||
|
||||
function handleUpload(f) {
|
||||
file.value = f;
|
||||
upload();
|
||||
return false;
|
||||
}
|
||||
|
||||
function upload() {
|
||||
const fd = new FormData();
|
||||
fd.append("files", file.value);
|
||||
@@ -246,9 +214,10 @@ function upload() {
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
init();
|
||||
deepGroup();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import "@/styles/table-common.scss";
|
||||
</style>
|
||||
|
||||
@@ -9,13 +9,13 @@
|
||||
<el-form-item label="商品编号" prop="goodsId">
|
||||
<el-input v-model="searchForm.goodsId" placeholder="请输入商品编号" clearable style="width: 200px" />
|
||||
</el-form-item>
|
||||
<el-form-item label="状态" prop="status">
|
||||
<el-form-item label="状态" prop="marketEnable">
|
||||
<el-select v-model="searchForm.marketEnable" placeholder="请选择" clearable style="width: 200px">
|
||||
<el-option label="下架" value="DOWN" />
|
||||
<el-option label="上架" value="UPPER" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="商品分类" prop="category">
|
||||
<el-form-item label="商品分类">
|
||||
<el-cascader
|
||||
v-model="category"
|
||||
:options="categoryList"
|
||||
@@ -36,7 +36,7 @@
|
||||
|
||||
<el-tabs v-model="activeTab" @tab-click="switchTabs">
|
||||
<el-tab-pane label="预警商品" name="warnList">
|
||||
<el-table v-loading="loading" border :data="warnData" class="mt_10" style="width: 100%">
|
||||
<el-table v-loading="loading" border :data="data" class="mt_10" style="width: 100%">
|
||||
<el-table-column prop="goodsName" label="商品名称" min-width="400" show-overflow-tooltip />
|
||||
<el-table-column label="库存" min-width="120">
|
||||
<template #default="{ row }">{{ row.quantity || 0 }}</template>
|
||||
@@ -53,7 +53,7 @@
|
||||
</el-tab-pane>
|
||||
|
||||
<el-tab-pane label="设置预警" name="warnSetting">
|
||||
<el-table v-loading="loading" border :data="skuAllData" class="mt_10" style="width: 100%">
|
||||
<el-table v-loading="loading" border :data="data" class="mt_10" style="width: 100%">
|
||||
<el-table-column prop="goodsName" label="商品名称" />
|
||||
<el-table-column label="库存" width="200">
|
||||
<template #default="{ row }">{{ row.quantity || 0 }}</template>
|
||||
@@ -82,8 +82,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>
|
||||
@@ -123,6 +123,7 @@
|
||||
<script setup>
|
||||
import { onMounted, ref, watch } from "vue";
|
||||
import { useRoute } from "vue-router";
|
||||
import { useTable } from "@/utils/useTable";
|
||||
import {
|
||||
getGoodsCategoryAll,
|
||||
getGoodsListDataByStockSeller,
|
||||
@@ -142,26 +143,39 @@ const ROUTE_TAB_MAP = {
|
||||
|
||||
const route = useRoute();
|
||||
|
||||
const loading = ref(true);
|
||||
const updateStockModalVisible = ref(false);
|
||||
const activeTab = ref("warnList");
|
||||
const searchForm = ref({
|
||||
pageNumber: 1,
|
||||
pageSize: 20,
|
||||
sort: "create_time",
|
||||
order: "desc",
|
||||
});
|
||||
const checkFlag = ref(false);
|
||||
const stockList = ref([]);
|
||||
const warnData = ref([]);
|
||||
const skuAllData = ref([]);
|
||||
const total = ref(0);
|
||||
const categoryList = ref([]);
|
||||
const category = ref([]);
|
||||
const selectedSku = ref({});
|
||||
|
||||
const searchFormRef = ref(null);
|
||||
|
||||
const { loading, data, total, searchForm, getDataList, handleSearch, resetSearch } = useTable(
|
||||
(params) => {
|
||||
return activeTab.value === "warnList"
|
||||
? getGoodsListDataByStockSeller(params)
|
||||
: getGoodsSkuListDataSeller(params);
|
||||
},
|
||||
{
|
||||
pageSize: 20,
|
||||
sort: "create_time",
|
||||
order: "desc",
|
||||
form: {
|
||||
goodsName: "",
|
||||
goodsId: "",
|
||||
marketEnable: "",
|
||||
sn: "",
|
||||
},
|
||||
beforeRequest: (p) => {
|
||||
const params = { ...p };
|
||||
params.categoryPath = category.value?.length ? category.value.join(",") : null;
|
||||
return params;
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
watch(
|
||||
() => route.name,
|
||||
(name) => {
|
||||
@@ -172,18 +186,13 @@ watch(
|
||||
|
||||
onMounted(() => {
|
||||
applyRouteTab();
|
||||
init();
|
||||
deepGroup();
|
||||
});
|
||||
|
||||
function applyRouteTab(name = route.name) {
|
||||
activeTab.value = ROUTE_TAB_MAP[name] || "warnList";
|
||||
}
|
||||
|
||||
function init() {
|
||||
getDataList();
|
||||
deepGroup();
|
||||
}
|
||||
|
||||
function openUpdataStockModal(row) {
|
||||
stockList.value = [];
|
||||
selectedSku.value = JSON.parse(JSON.stringify(row));
|
||||
@@ -233,52 +242,9 @@ function switchTabs() {
|
||||
handleReset();
|
||||
}
|
||||
|
||||
function changePageSize(v) {
|
||||
searchForm.value.pageSize = v;
|
||||
getDataList();
|
||||
}
|
||||
|
||||
function changePage(v) {
|
||||
searchForm.value.pageNumber = v;
|
||||
getDataList();
|
||||
}
|
||||
|
||||
function handleSearch() {
|
||||
searchForm.value.pageNumber = 1;
|
||||
searchForm.value.categoryPath = category.value?.length ? category.value.join(",") : null;
|
||||
getDataList();
|
||||
}
|
||||
|
||||
function handleReset() {
|
||||
searchForm.value = {
|
||||
pageNumber: 1,
|
||||
pageSize: 20,
|
||||
sort: "create_time",
|
||||
order: "desc",
|
||||
};
|
||||
category.value = [];
|
||||
getDataList();
|
||||
}
|
||||
|
||||
function getDataList() {
|
||||
loading.value = true;
|
||||
if (activeTab.value === "warnList") {
|
||||
getGoodsListDataByStockSeller(searchForm.value).then((res) => {
|
||||
if (res.success) {
|
||||
warnData.value = res.result.records;
|
||||
total.value = res.result.total;
|
||||
}
|
||||
loading.value = false;
|
||||
});
|
||||
} else {
|
||||
getGoodsSkuListDataSeller(searchForm.value).then((res) => {
|
||||
if (res.success) {
|
||||
skuAllData.value = res.result.records;
|
||||
total.value = res.result.total;
|
||||
}
|
||||
loading.value = false;
|
||||
});
|
||||
}
|
||||
resetSearch();
|
||||
}
|
||||
|
||||
function deepGroup() {
|
||||
|
||||
@@ -17,13 +17,13 @@
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="handleSearch">搜索</el-button>
|
||||
<el-button @click="handleReset">重置</el-button>
|
||||
<el-button @click="resetSearch">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
|
||||
<el-card>
|
||||
<el-table v-loading="loading" border :data="data" ref="tableRef" class="mt_10" style="width: 100%">
|
||||
<el-card class="mt_10">
|
||||
<el-table ref="tableRef" v-loading="loading" border :data="data" style="width: 100%">
|
||||
<el-table-column prop="id" label="编号" min-width="120" />
|
||||
<el-table-column label="商品原图" width="120" align="center">
|
||||
<template #default="{ row }">
|
||||
@@ -41,7 +41,7 @@
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="createTime" label="创建时间" min-width="120" />
|
||||
<el-table-column label="操作" align="center" width="150">
|
||||
<el-table-column label="操作" align="center" width="150" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<a class="link-text" @click="editGoods(row)">编辑</a>
|
||||
<span class="op-split">|</span>
|
||||
@@ -58,8 +58,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>
|
||||
@@ -67,8 +67,9 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { onMounted, ref, watch } from "vue";
|
||||
import { ref, watch } from "vue";
|
||||
import { useRoute, useRouter } from "vue-router";
|
||||
import { useTable } from "@/utils/useTable";
|
||||
import { getDraftGoodsListData, deleteDraftGoods } from "@/api/goods";
|
||||
import { Message, Modal } from "@/utils/message";
|
||||
|
||||
@@ -80,29 +81,37 @@ const router = useRouter();
|
||||
const searchFormRef = ref(null);
|
||||
const tableRef = ref(null);
|
||||
|
||||
const loading = ref(true);
|
||||
const searchForm = ref({
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
sort: "create_time",
|
||||
order: "desc",
|
||||
saveType: "TEMPLATE",
|
||||
});
|
||||
const data = ref([]);
|
||||
const total = ref(0);
|
||||
const { loading, data, total, searchForm, getDataList, handleSearch, resetSearch } = useTable(
|
||||
getDraftGoodsListData,
|
||||
{
|
||||
pageSize: 10,
|
||||
sort: "create_time",
|
||||
order: "desc",
|
||||
form: {
|
||||
goodsName: "",
|
||||
id: "",
|
||||
saveType: "TEMPLATE",
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
watch(
|
||||
() => route.query,
|
||||
() => {
|
||||
getDataList();
|
||||
}
|
||||
);
|
||||
|
||||
function init() {
|
||||
getDataList();
|
||||
}
|
||||
function editGoods(v) {
|
||||
router.push({
|
||||
name: "goods-template-operation-edit",
|
||||
query: { draftId: v.id },
|
||||
});
|
||||
}
|
||||
|
||||
function removeDraft(id) {
|
||||
Modal.confirm({
|
||||
title: "确认审核",
|
||||
title: "确认删除",
|
||||
content: "您确认要删除id为 " + id + " 的模版吗?",
|
||||
loading: true,
|
||||
onOk: () => {
|
||||
@@ -116,44 +125,6 @@ function removeDraft(id) {
|
||||
},
|
||||
});
|
||||
}
|
||||
function changePage() {
|
||||
getDataList();
|
||||
}
|
||||
function changePageSize() {
|
||||
getDataList();
|
||||
}
|
||||
function handleSearch() {
|
||||
searchForm.value.pageNumber = 1;
|
||||
searchForm.value.pageSize = 10;
|
||||
getDataList();
|
||||
}
|
||||
function handleReset() {
|
||||
searchFormRef.value.resetFields();
|
||||
searchForm.value.pageNumber = 1;
|
||||
searchForm.value.pageSize = 10;
|
||||
getDataList();
|
||||
}
|
||||
function getDataList() {
|
||||
loading.value = true;
|
||||
getDraftGoodsListData(searchForm.value).then((res) => {
|
||||
loading.value = false;
|
||||
if (res.success) {
|
||||
data.value = res.result.records;
|
||||
total.value = res.result.total;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
init();
|
||||
});
|
||||
|
||||
watch(
|
||||
() => route.query,
|
||||
() => {
|
||||
init();
|
||||
}
|
||||
);
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
Reference in New Issue
Block a user