mirror of
https://gitee.com/beijing_hongye_huicheng/lilishop-ui.git
synced 2026-03-21 21:44:50 +08:00
feat: 添加微信视频号管理模块和商品定时上下架功能
- 新增微信视频号管理页面,包含概况、订单、退单、商品、分类和设置六个标签页 - 实现微信视频号相关API接口,包括类目、商品、订单、退单和概况数据查询 - 在商品管理页面添加批量定时上下架功能,支持选择状态和触发时间 - 优化批量操作下拉菜单,整合上架、下架、定时上下架、物流模板设置和删除功能 - 改进设置页面样式,增强按钮布局的响应式设计
This commit is contained in:
@@ -368,6 +368,31 @@ export const setSetting = (key, params) => {
|
||||
return putRequestWithNoForm(`/setting/setting/put/${key}`, params);
|
||||
};
|
||||
|
||||
// 微信视频号小店类目(三级)
|
||||
export const getWxChannelsThirdCategory = (params) => {
|
||||
return getRequest(`/wxchannels/category/third`, params);
|
||||
};
|
||||
|
||||
// 微信视频号商品分页
|
||||
export const getWxChannelsGoodsPage = (params) => {
|
||||
return getRequest(`/wxchannels/goods`, params);
|
||||
};
|
||||
|
||||
// 微信视频号订单分页
|
||||
export const getWxChannelsOrderPage = (params) => {
|
||||
return getRequest(`/wxchannels/order`, params);
|
||||
};
|
||||
|
||||
// 微信视频号概况
|
||||
export const getWxChannelsOverviewSummary = (params) => {
|
||||
return getRequest(`/wxchannels/overview/summary`, params);
|
||||
};
|
||||
|
||||
// 微信视频号退单分页
|
||||
export const getWxChannelsRefundPage = (params) => {
|
||||
return getRequest(`/wxchannels/refund`, params);
|
||||
};
|
||||
|
||||
// 分页查询敏感词
|
||||
|
||||
export const getSensitiveWordsPage = (params) => {
|
||||
|
||||
@@ -4,6 +4,24 @@
|
||||
|
||||
.label-btns{
|
||||
margin-left: 150px;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.es-buttons{
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
::v-deep .label-btns > .ivu-btn{
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
::v-deep .es-buttons .ivu-btn{
|
||||
margin-right: 10px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.ivu-form-item{
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
<template>
|
||||
<div class="wx-channel-category">
|
||||
<div class="toolbar">
|
||||
<i-switch v-model="forceRefresh" size="large">
|
||||
<span slot="open">强刷</span>
|
||||
<span slot="close">缓存</span>
|
||||
</i-switch>
|
||||
<Button
|
||||
type="primary"
|
||||
@click="loadThirdCategories"
|
||||
:loading="loading"
|
||||
style="margin-left: 10px"
|
||||
>刷新</Button
|
||||
>
|
||||
</div>
|
||||
<Table border :loading="loading" :columns="columns" :data="data"></Table>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getWxChannelsThirdCategory } from "@/api/index";
|
||||
|
||||
export default {
|
||||
name: "WxChannelsCategoryTab",
|
||||
data() {
|
||||
return {
|
||||
forceRefresh: false,
|
||||
loading: false,
|
||||
data: [],
|
||||
columns: [
|
||||
{ title: "一级类目", key: "firstCatName", minWidth: 150, tooltip: true },
|
||||
{ title: "二级类目", key: "secondCatName", minWidth: 150, tooltip: true },
|
||||
{ title: "三级类目", key: "thirdCatName", minWidth: 200, tooltip: true },
|
||||
{ title: "三级类目ID", key: "thirdCatId", width: 120 },
|
||||
{ title: "类目资质", key: "qualification", minWidth: 220, tooltip: true },
|
||||
{
|
||||
title: "类目资质类型",
|
||||
key: "qualificationType",
|
||||
width: 120,
|
||||
render: (h, params) => {
|
||||
const val = params.row.qualificationType;
|
||||
const map = { 0: "不需要", 1: "必填", 2: "选填" };
|
||||
return h(
|
||||
"Tag",
|
||||
{ props: { color: val === 1 ? "red" : val === 2 ? "orange" : "green" } },
|
||||
map[val] || "-"
|
||||
);
|
||||
},
|
||||
},
|
||||
{ title: "商品资质", key: "productQualification", minWidth: 220, tooltip: true },
|
||||
{
|
||||
title: "商品资质类型",
|
||||
key: "productQualificationType",
|
||||
width: 120,
|
||||
render: (h, params) => {
|
||||
const val = params.row.productQualificationType;
|
||||
const map = { 0: "不需要", 1: "必填", 2: "选填" };
|
||||
return h(
|
||||
"Tag",
|
||||
{ props: { color: val === 1 ? "red" : val === 2 ? "orange" : "green" } },
|
||||
map[val] || "-"
|
||||
);
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.loadThirdCategories();
|
||||
},
|
||||
methods: {
|
||||
loadThirdCategories() {
|
||||
this.loading = true;
|
||||
getWxChannelsThirdCategory({ forceRefresh: !!this.forceRefresh })
|
||||
.then((res) => {
|
||||
if (res && res.success) {
|
||||
this.data = Array.isArray(res.result) ? res.result : [];
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.toolbar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
</style>
|
||||
143
manager/src/views/wx-channel/components/WxChannelsGoodsTab.vue
Normal file
143
manager/src/views/wx-channel/components/WxChannelsGoodsTab.vue
Normal file
@@ -0,0 +1,143 @@
|
||||
<template>
|
||||
<div class="wx-channel-goods">
|
||||
<Row>
|
||||
<Form :model="searchForm" inline :label-width="70" class="search-form">
|
||||
<FormItem label="商品名称" prop="goodsName">
|
||||
<Input
|
||||
v-model="searchForm.goodsName"
|
||||
placeholder="请输入商品名称"
|
||||
clearable
|
||||
style="width: 220px"
|
||||
/>
|
||||
</FormItem>
|
||||
<FormItem label="状态" prop="status">
|
||||
<Select v-model="searchForm.status" clearable style="width: 180px" placeholder="全部">
|
||||
<Option v-for="item in statusList" :key="item.value" :value="item.value">{{ item.label }}</Option>
|
||||
</Select>
|
||||
</FormItem>
|
||||
<Button
|
||||
@click="handleSearch"
|
||||
type="primary"
|
||||
icon="ios-search"
|
||||
class="search-btn"
|
||||
:loading="loading"
|
||||
>搜索</Button
|
||||
>
|
||||
</Form>
|
||||
</Row>
|
||||
|
||||
<Table :loading="loading" border :columns="columns" :data="data" class="mt_10"></Table>
|
||||
<Row type="flex" justify="end" class="mt_10" style="margin-top: 10px">
|
||||
<Page
|
||||
:current="searchForm.pageNumber"
|
||||
:total="total"
|
||||
:page-size="searchForm.pageSize"
|
||||
@on-change="changePage"
|
||||
@on-page-size-change="changePageSize"
|
||||
:page-size-opts="[20, 50, 100]"
|
||||
size="small"
|
||||
show-total
|
||||
show-elevator
|
||||
show-sizer
|
||||
></Page>
|
||||
</Row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getWxChannelsGoodsPage } from "@/api/index";
|
||||
|
||||
export default {
|
||||
name: "WxChannelsGoodsTab",
|
||||
data() {
|
||||
return {
|
||||
statusList: [
|
||||
{ label: "已通过", value: "APPROVED" },
|
||||
{ label: "审核中", value: "PENDING" },
|
||||
{ label: "已拒绝", value: "REJECTED" },
|
||||
],
|
||||
loading: false,
|
||||
total: 0,
|
||||
data: [],
|
||||
searchForm: {
|
||||
goodsName: "",
|
||||
status: "",
|
||||
pageNumber: 1,
|
||||
pageSize: 20,
|
||||
},
|
||||
columns: [
|
||||
{
|
||||
title: "商品图片",
|
||||
key: "goodsImage",
|
||||
width: 90,
|
||||
align: "center",
|
||||
render: (h, params) => {
|
||||
return h("img", {
|
||||
attrs: { src: params.row.goodsImage || "", alt: "加载图片失败" },
|
||||
style: {
|
||||
width: "50px",
|
||||
height: "50px",
|
||||
objectFit: "cover",
|
||||
borderRadius: "4px",
|
||||
},
|
||||
});
|
||||
},
|
||||
},
|
||||
{ title: "商品名称", key: "goodsName", minWidth: 220, tooltip: true },
|
||||
{ title: "店铺", key: "storeName", minWidth: 160, tooltip: true },
|
||||
{ title: "分类", key: "categoryName", minWidth: 160, tooltip: true },
|
||||
{ title: "销售价", key: "costPrice", width: 100 },
|
||||
{ title: "视频号价", key: "channelPrice", width: 100 },
|
||||
{ title: "库存", key: "stock", width: 90 },
|
||||
{
|
||||
title: "状态",
|
||||
key: "status",
|
||||
width: 110,
|
||||
render: (h, params) => {
|
||||
const val = params.row.status;
|
||||
const map = {
|
||||
APPROVED: { label: "已通过", color: "green" },
|
||||
PENDING: { label: "审核中", color: "orange" },
|
||||
REJECTED: { label: "已拒绝", color: "red" },
|
||||
};
|
||||
const item = map[val] || { label: val || "-", color: "default" };
|
||||
return h("Tag", { props: { color: item.color } }, item.label);
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.loadPage();
|
||||
},
|
||||
methods: {
|
||||
handleSearch() {
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.loadPage();
|
||||
},
|
||||
changePage(pageNumber) {
|
||||
this.searchForm.pageNumber = pageNumber;
|
||||
this.loadPage();
|
||||
},
|
||||
changePageSize(pageSize) {
|
||||
this.searchForm.pageSize = pageSize;
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.loadPage();
|
||||
},
|
||||
loadPage() {
|
||||
this.loading = true;
|
||||
getWxChannelsGoodsPage({ ...this.searchForm })
|
||||
.then((res) => {
|
||||
if (res && res.success) {
|
||||
const page = res.result || {};
|
||||
this.data = Array.isArray(page.records) ? page.records : [];
|
||||
this.total = Number(page.total || 0);
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
172
manager/src/views/wx-channel/components/WxChannelsOrderTab.vue
Normal file
172
manager/src/views/wx-channel/components/WxChannelsOrderTab.vue
Normal file
@@ -0,0 +1,172 @@
|
||||
<template>
|
||||
<div class="wx-channel-order">
|
||||
<Row>
|
||||
<Form :model="searchForm" inline :label-width="70" class="search-form">
|
||||
<FormItem label="订单编号" prop="channelOrderSn">
|
||||
<Input
|
||||
v-model="searchForm.channelOrderSn"
|
||||
placeholder="视频号订单编号"
|
||||
clearable
|
||||
style="width: 220px"
|
||||
/>
|
||||
</FormItem>
|
||||
<FormItem label="会员昵称" prop="memberNickName">
|
||||
<Input v-model="searchForm.memberNickName" placeholder="请输入会员昵称" clearable style="width: 180px" />
|
||||
</FormItem>
|
||||
<FormItem label="商品名称" prop="goodsName">
|
||||
<Input v-model="searchForm.goodsName" placeholder="请输入商品名称" clearable style="width: 200px" />
|
||||
</FormItem>
|
||||
<FormItem label="状态" prop="status">
|
||||
<Input v-model="searchForm.status" placeholder="订单状态" clearable style="width: 140px" />
|
||||
</FormItem>
|
||||
<FormItem label="场景" prop="scene">
|
||||
<Select v-model="searchForm.scene" clearable style="width: 140px" placeholder="全部">
|
||||
<Option v-for="item in sceneList" :key="item.value" :value="item.value">{{ item.label }}</Option>
|
||||
</Select>
|
||||
</FormItem>
|
||||
<FormItem label="下单时间">
|
||||
<DatePicker
|
||||
type="daterange"
|
||||
v-model="selectDate"
|
||||
format="yyyy-MM-dd"
|
||||
clearable
|
||||
@on-change="selectDateRange"
|
||||
placeholder="选择起始时间"
|
||||
style="width: 240px"
|
||||
></DatePicker>
|
||||
</FormItem>
|
||||
<Button @click="handleSearch" type="primary" icon="ios-search" class="search-btn" :loading="loading"
|
||||
>搜索</Button
|
||||
>
|
||||
</Form>
|
||||
</Row>
|
||||
|
||||
<Table :loading="loading" border :columns="columns" :data="data" class="mt_10"></Table>
|
||||
<Row type="flex" justify="end" class="mt_10" style="margin-top: 10px">
|
||||
<Page
|
||||
:current="searchForm.pageNumber"
|
||||
:total="total"
|
||||
:page-size="searchForm.pageSize"
|
||||
@on-change="changePage"
|
||||
@on-page-size-change="changePageSize"
|
||||
:page-size-opts="[20, 50, 100]"
|
||||
size="small"
|
||||
show-total
|
||||
show-elevator
|
||||
show-sizer
|
||||
></Page>
|
||||
</Row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getWxChannelsOrderPage } from "@/api/index";
|
||||
|
||||
export default {
|
||||
name: "WxChannelsOrderTab",
|
||||
data() {
|
||||
return {
|
||||
sceneList: [
|
||||
{ label: "直播", value: "LIVE" },
|
||||
{ label: "橱窗", value: "WINDOW" },
|
||||
],
|
||||
loading: false,
|
||||
total: 0,
|
||||
data: [],
|
||||
selectDate: null,
|
||||
searchForm: {
|
||||
channelOrderSn: "",
|
||||
memberNickName: "",
|
||||
goodsName: "",
|
||||
status: "",
|
||||
scene: "",
|
||||
startTime: null,
|
||||
endTime: null,
|
||||
pageNumber: 1,
|
||||
pageSize: 20,
|
||||
},
|
||||
columns: [
|
||||
{ title: "视频号订单编号", key: "channelOrderSn", minWidth: 200, tooltip: true },
|
||||
{ title: "平台订单编号", key: "orderSn", minWidth: 200, tooltip: true },
|
||||
{ title: "会员昵称", key: "memberNickName", minWidth: 140, tooltip: true },
|
||||
{ title: "订单金额", key: "amount", width: 110 },
|
||||
{
|
||||
title: "订单状态",
|
||||
key: "status",
|
||||
width: 130,
|
||||
render: (h, params) => {
|
||||
const val = params.row.status;
|
||||
if (!val) return h("span", "-");
|
||||
return h("Tag", { props: { color: "blue" } }, val);
|
||||
},
|
||||
},
|
||||
{ title: "带货视频号", key: "channelName", minWidth: 160, tooltip: true },
|
||||
{
|
||||
title: "下单场景",
|
||||
key: "scene",
|
||||
width: 110,
|
||||
render: (h, params) => {
|
||||
const val = params.row.scene;
|
||||
const map = {
|
||||
LIVE: { label: "直播", color: "orange" },
|
||||
WINDOW: { label: "橱窗", color: "purple" },
|
||||
};
|
||||
const item = map[val] || { label: val || "-", color: "default" };
|
||||
return h("Tag", { props: { color: item.color } }, item.label);
|
||||
},
|
||||
},
|
||||
{ title: "创建时间", key: "createTime", minWidth: 160, tooltip: true },
|
||||
],
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.loadPage();
|
||||
},
|
||||
methods: {
|
||||
selectDateRange(v) {
|
||||
if (!v || v.length !== 2) {
|
||||
this.searchForm.startTime = null;
|
||||
this.searchForm.endTime = null;
|
||||
return;
|
||||
}
|
||||
const startStr = v[0];
|
||||
const endStr = v[1];
|
||||
const start = startStr ? new Date(`${startStr}T00:00:00`).getTime() : null;
|
||||
const end = endStr ? new Date(`${endStr}T23:59:59`).getTime() : null;
|
||||
this.searchForm.startTime = Number.isFinite(start) ? start : null;
|
||||
this.searchForm.endTime = Number.isFinite(end) ? end : null;
|
||||
},
|
||||
handleSearch() {
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.loadPage();
|
||||
},
|
||||
changePage(pageNumber) {
|
||||
this.searchForm.pageNumber = pageNumber;
|
||||
this.loadPage();
|
||||
},
|
||||
changePageSize(pageSize) {
|
||||
this.searchForm.pageSize = pageSize;
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.loadPage();
|
||||
},
|
||||
loadPage() {
|
||||
this.loading = true;
|
||||
const params = { ...this.searchForm };
|
||||
Object.keys(params).forEach((k) => {
|
||||
if (params[k] === null || params[k] === "" || params[k] === undefined) delete params[k];
|
||||
});
|
||||
getWxChannelsOrderPage(params)
|
||||
.then((res) => {
|
||||
if (res && res.success) {
|
||||
const page = res.result || {};
|
||||
this.data = Array.isArray(page.records) ? page.records : [];
|
||||
this.total = Number(page.total || 0);
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
@@ -0,0 +1,155 @@
|
||||
<template>
|
||||
<div class="wx-channel-overview">
|
||||
<Row>
|
||||
<Form :model="searchForm" inline :label-width="70" class="search-form">
|
||||
<FormItem label="统计时间">
|
||||
<DatePicker
|
||||
type="daterange"
|
||||
v-model="selectDate"
|
||||
format="yyyy-MM-dd"
|
||||
clearable
|
||||
@on-change="selectDateRange"
|
||||
placeholder="选择起始时间"
|
||||
style="width: 240px"
|
||||
></DatePicker>
|
||||
</FormItem>
|
||||
<Button @click="handleSearch" type="primary" icon="ios-search" class="search-btn" :loading="loading"
|
||||
>查询</Button
|
||||
>
|
||||
</Form>
|
||||
</Row>
|
||||
|
||||
<Row :gutter="16" style="margin-top: 12px">
|
||||
<Col :xs="24" :sm="12" :md="8">
|
||||
<Card dis-hover>
|
||||
<div class="overview-card">
|
||||
<div class="label">视频号总销售额</div>
|
||||
<div class="value">{{ summary.totalSales || 0 }}</div>
|
||||
</div>
|
||||
</Card>
|
||||
</Col>
|
||||
<Col :xs="24" :sm="12" :md="8">
|
||||
<Card dis-hover>
|
||||
<div class="overview-card">
|
||||
<div class="label">直播间销售额</div>
|
||||
<div class="value">{{ summary.liveSales || 0 }}</div>
|
||||
</div>
|
||||
</Card>
|
||||
</Col>
|
||||
<Col :xs="24" :sm="12" :md="8">
|
||||
<Card dis-hover>
|
||||
<div class="overview-card">
|
||||
<div class="label">橱窗销售额</div>
|
||||
<div class="value">{{ summary.windowSales || 0 }}</div>
|
||||
</div>
|
||||
</Card>
|
||||
</Col>
|
||||
</Row>
|
||||
<Row :gutter="16" style="margin-top: 16px">
|
||||
<Col :xs="24" :sm="12" :md="8">
|
||||
<Card dis-hover>
|
||||
<div class="overview-card">
|
||||
<div class="label">视频号退款总金额</div>
|
||||
<div class="value">{{ summary.totalRefund || 0 }}</div>
|
||||
</div>
|
||||
</Card>
|
||||
</Col>
|
||||
<Col :xs="24" :sm="12" :md="8">
|
||||
<Card dis-hover>
|
||||
<div class="overview-card">
|
||||
<div class="label">直播间退款金额</div>
|
||||
<div class="value">{{ summary.liveRefund || 0 }}</div>
|
||||
</div>
|
||||
</Card>
|
||||
</Col>
|
||||
<Col :xs="24" :sm="12" :md="8">
|
||||
<Card dis-hover>
|
||||
<div class="overview-card">
|
||||
<div class="label">橱窗退款金额</div>
|
||||
<div class="value">{{ summary.windowRefund || 0 }}</div>
|
||||
</div>
|
||||
</Card>
|
||||
</Col>
|
||||
</Row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getWxChannelsOverviewSummary } from "@/api/index";
|
||||
|
||||
export default {
|
||||
name: "WxChannelsOverviewTab",
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
selectDate: null,
|
||||
searchForm: {
|
||||
startTime: null,
|
||||
endTime: null,
|
||||
},
|
||||
summary: {
|
||||
totalSales: 0,
|
||||
liveSales: 0,
|
||||
windowSales: 0,
|
||||
totalRefund: 0,
|
||||
liveRefund: 0,
|
||||
windowRefund: 0,
|
||||
},
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.loadSummary();
|
||||
},
|
||||
methods: {
|
||||
selectDateRange(v) {
|
||||
if (!v || v.length !== 2) {
|
||||
this.searchForm.startTime = null;
|
||||
this.searchForm.endTime = null;
|
||||
return;
|
||||
}
|
||||
const startStr = v[0];
|
||||
const endStr = v[1];
|
||||
const start = startStr ? new Date(`${startStr}T00:00:00`).getTime() : null;
|
||||
const end = endStr ? new Date(`${endStr}T23:59:59`).getTime() : null;
|
||||
this.searchForm.startTime = Number.isFinite(start) ? start : null;
|
||||
this.searchForm.endTime = Number.isFinite(end) ? end : null;
|
||||
},
|
||||
handleSearch() {
|
||||
this.loadSummary();
|
||||
},
|
||||
loadSummary() {
|
||||
this.loading = true;
|
||||
const params = { ...this.searchForm };
|
||||
Object.keys(params).forEach((k) => {
|
||||
if (params[k] === null || params[k] === "" || params[k] === undefined) delete params[k];
|
||||
});
|
||||
getWxChannelsOverviewSummary(params)
|
||||
.then((res) => {
|
||||
if (res && res.success) {
|
||||
this.summary = { ...this.summary, ...(res.result || {}) };
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.overview-card {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.overview-card .label {
|
||||
color: #666;
|
||||
font-size: 13px;
|
||||
}
|
||||
.overview-card .value {
|
||||
margin-top: 8px;
|
||||
font-size: 22px;
|
||||
font-weight: 600;
|
||||
color: #17233d;
|
||||
}
|
||||
</style>
|
||||
180
manager/src/views/wx-channel/components/WxChannelsRefundTab.vue
Normal file
180
manager/src/views/wx-channel/components/WxChannelsRefundTab.vue
Normal file
@@ -0,0 +1,180 @@
|
||||
<template>
|
||||
<div class="wx-channel-refund">
|
||||
<Row>
|
||||
<Form :model="searchForm" inline :label-width="70" class="search-form">
|
||||
<FormItem label="退单编号" prop="channelRefundSn">
|
||||
<Input
|
||||
v-model="searchForm.channelRefundSn"
|
||||
placeholder="视频号退单编号"
|
||||
clearable
|
||||
style="width: 220px"
|
||||
/>
|
||||
</FormItem>
|
||||
<FormItem label="订单编号" prop="channelOrderSn">
|
||||
<Input
|
||||
v-model="searchForm.channelOrderSn"
|
||||
placeholder="视频号订单编号"
|
||||
clearable
|
||||
style="width: 220px"
|
||||
/>
|
||||
</FormItem>
|
||||
<FormItem label="会员昵称" prop="memberNickName">
|
||||
<Input v-model="searchForm.memberNickName" placeholder="请输入会员昵称" clearable style="width: 180px" />
|
||||
</FormItem>
|
||||
<FormItem label="商品名称" prop="goodsName">
|
||||
<Input v-model="searchForm.goodsName" placeholder="请输入商品名称" clearable style="width: 200px" />
|
||||
</FormItem>
|
||||
<FormItem label="状态" prop="status">
|
||||
<Input v-model="searchForm.status" placeholder="退单状态" clearable style="width: 140px" />
|
||||
</FormItem>
|
||||
<FormItem label="场景" prop="scene">
|
||||
<Select v-model="searchForm.scene" clearable style="width: 140px" placeholder="全部">
|
||||
<Option v-for="item in sceneList" :key="item.value" :value="item.value">{{ item.label }}</Option>
|
||||
</Select>
|
||||
</FormItem>
|
||||
<FormItem label="时间">
|
||||
<DatePicker
|
||||
type="daterange"
|
||||
v-model="selectDate"
|
||||
format="yyyy-MM-dd"
|
||||
clearable
|
||||
@on-change="selectDateRange"
|
||||
placeholder="选择起始时间"
|
||||
style="width: 240px"
|
||||
></DatePicker>
|
||||
</FormItem>
|
||||
<Button @click="handleSearch" type="primary" icon="ios-search" class="search-btn" :loading="loading"
|
||||
>搜索</Button
|
||||
>
|
||||
</Form>
|
||||
</Row>
|
||||
|
||||
<Table :loading="loading" border :columns="columns" :data="data" class="mt_10"></Table>
|
||||
<Row type="flex" justify="end" class="mt_10" style="margin-top: 10px">
|
||||
<Page
|
||||
:current="searchForm.pageNumber"
|
||||
:total="total"
|
||||
:page-size="searchForm.pageSize"
|
||||
@on-change="changePage"
|
||||
@on-page-size-change="changePageSize"
|
||||
:page-size-opts="[20, 50, 100]"
|
||||
size="small"
|
||||
show-total
|
||||
show-elevator
|
||||
show-sizer
|
||||
></Page>
|
||||
</Row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getWxChannelsRefundPage } from "@/api/index";
|
||||
|
||||
export default {
|
||||
name: "WxChannelsRefundTab",
|
||||
data() {
|
||||
return {
|
||||
sceneList: [
|
||||
{ label: "直播", value: "LIVE" },
|
||||
{ label: "橱窗", value: "WINDOW" },
|
||||
],
|
||||
loading: false,
|
||||
total: 0,
|
||||
data: [],
|
||||
selectDate: null,
|
||||
searchForm: {
|
||||
channelRefundSn: "",
|
||||
channelOrderSn: "",
|
||||
memberNickName: "",
|
||||
goodsName: "",
|
||||
status: "",
|
||||
scene: "",
|
||||
startTime: null,
|
||||
endTime: null,
|
||||
pageNumber: 1,
|
||||
pageSize: 20,
|
||||
},
|
||||
columns: [
|
||||
{ title: "视频号退单编号", key: "channelRefundSn", minWidth: 200, tooltip: true },
|
||||
{ title: "视频号订单编号", key: "channelOrderSn", minWidth: 200, tooltip: true },
|
||||
{ title: "会员昵称", key: "memberNickName", minWidth: 140, tooltip: true },
|
||||
{ title: "退款金额", key: "amount", width: 110 },
|
||||
{
|
||||
title: "退单状态",
|
||||
key: "status",
|
||||
width: 130,
|
||||
render: (h, params) => {
|
||||
const val = params.row.status;
|
||||
if (!val) return h("span", "-");
|
||||
return h("Tag", { props: { color: "blue" } }, val);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "下单场景",
|
||||
key: "scene",
|
||||
width: 110,
|
||||
render: (h, params) => {
|
||||
const val = params.row.scene;
|
||||
const map = {
|
||||
LIVE: { label: "直播", color: "orange" },
|
||||
WINDOW: { label: "橱窗", color: "purple" },
|
||||
};
|
||||
const item = map[val] || { label: val || "-", color: "default" };
|
||||
return h("Tag", { props: { color: item.color } }, item.label);
|
||||
},
|
||||
},
|
||||
{ title: "创建时间", key: "createTime", minWidth: 160, tooltip: true },
|
||||
],
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.loadPage();
|
||||
},
|
||||
methods: {
|
||||
selectDateRange(v) {
|
||||
if (!v || v.length !== 2) {
|
||||
this.searchForm.startTime = null;
|
||||
this.searchForm.endTime = null;
|
||||
return;
|
||||
}
|
||||
const startStr = v[0];
|
||||
const endStr = v[1];
|
||||
const start = startStr ? new Date(`${startStr}T00:00:00`).getTime() : null;
|
||||
const end = endStr ? new Date(`${endStr}T23:59:59`).getTime() : null;
|
||||
this.searchForm.startTime = Number.isFinite(start) ? start : null;
|
||||
this.searchForm.endTime = Number.isFinite(end) ? end : null;
|
||||
},
|
||||
handleSearch() {
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.loadPage();
|
||||
},
|
||||
changePage(pageNumber) {
|
||||
this.searchForm.pageNumber = pageNumber;
|
||||
this.loadPage();
|
||||
},
|
||||
changePageSize(pageSize) {
|
||||
this.searchForm.pageSize = pageSize;
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.loadPage();
|
||||
},
|
||||
loadPage() {
|
||||
this.loading = true;
|
||||
const params = { ...this.searchForm };
|
||||
Object.keys(params).forEach((k) => {
|
||||
if (params[k] === null || params[k] === "" || params[k] === undefined) delete params[k];
|
||||
});
|
||||
getWxChannelsRefundPage(params)
|
||||
.then((res) => {
|
||||
if (res && res.success) {
|
||||
const page = res.result || {};
|
||||
this.data = Array.isArray(page.records) ? page.records : [];
|
||||
this.total = Number(page.total || 0);
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
114
manager/src/views/wx-channel/components/WxChannelsSettingTab.vue
Normal file
114
manager/src/views/wx-channel/components/WxChannelsSettingTab.vue
Normal file
@@ -0,0 +1,114 @@
|
||||
<template>
|
||||
<div class="wx-channel-setting">
|
||||
<Form :label-width="160" label-position="right" :model="configObject">
|
||||
<FormItem label="AppId">
|
||||
<Input v-model="configObject.appId" style="width: 360px" />
|
||||
</FormItem>
|
||||
<FormItem label="AppSecret">
|
||||
<Input v-model="configObject.appSecret" style="width: 360px" />
|
||||
</FormItem>
|
||||
<FormItem label="接口基础地址">
|
||||
<Input
|
||||
v-model="configObject.apiBase"
|
||||
style="width: 360px"
|
||||
placeholder="https://api.weixin.qq.com/minishop"
|
||||
/>
|
||||
</FormItem>
|
||||
<FormItem label="Token地址">
|
||||
<Input
|
||||
v-model="configObject.tokenUrl"
|
||||
style="width: 360px"
|
||||
placeholder="https://api.weixin.qq.com/cgi-bin/token"
|
||||
/>
|
||||
</FormItem>
|
||||
<div class="actions">
|
||||
<Button type="primary" @click="submit" :loading="submitLoading">保存</Button>
|
||||
</div>
|
||||
</Form>
|
||||
<Spin size="large" fix v-if="loading"></Spin>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getSetting, setSetting } from "@/api/index";
|
||||
|
||||
const defaultConfig = () => ({
|
||||
appId: "",
|
||||
appSecret: "",
|
||||
apiBase: "",
|
||||
tokenUrl: "",
|
||||
});
|
||||
|
||||
export default {
|
||||
name: "WxChannelsSettingTab",
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
submitLoading: false,
|
||||
configObject: defaultConfig(),
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.reloadConfig();
|
||||
},
|
||||
methods: {
|
||||
normalizeConfig(val) {
|
||||
if (!val) return {};
|
||||
if (typeof val === "string") {
|
||||
try {
|
||||
return JSON.parse(val);
|
||||
} catch (e) {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
if (typeof val === "object") return val;
|
||||
return {};
|
||||
},
|
||||
pickConfigFields(val) {
|
||||
const next = defaultConfig();
|
||||
if (!val || typeof val !== "object") return next;
|
||||
Object.keys(next).forEach((k) => {
|
||||
if (val[k] !== undefined && val[k] !== null) {
|
||||
next[k] = val[k];
|
||||
}
|
||||
});
|
||||
return next;
|
||||
},
|
||||
reloadConfig() {
|
||||
this.loading = true;
|
||||
getSetting("WX_CHANNELS")
|
||||
.then((res) => {
|
||||
if (res && res.success) {
|
||||
const base = this.normalizeConfig(res.result);
|
||||
this.configObject = this.pickConfigFields(base);
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
submit() {
|
||||
const payload = { ...this.configObject };
|
||||
this.submitLoading = true;
|
||||
setSetting("WX_CHANNELS", payload)
|
||||
.then((res) => {
|
||||
if (res && res.success) {
|
||||
this.$Message.success("保存成功");
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
this.submitLoading = false;
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.actions {
|
||||
margin-left: 160px;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
}
|
||||
</style>
|
||||
50
manager/src/views/wx-channel/wxChannel.vue
Normal file
50
manager/src/views/wx-channel/wxChannel.vue
Normal file
@@ -0,0 +1,50 @@
|
||||
<template>
|
||||
<Card>
|
||||
<Tabs v-model="selectedTab">
|
||||
<TabPane label="视频号概括" name="WX_CHANNELS_OVERVIEW">
|
||||
<WxChannelsOverviewTab v-if="selectedTab === 'WX_CHANNELS_OVERVIEW'" />
|
||||
</TabPane>
|
||||
<TabPane label="视频号订单" name="WX_CHANNELS_ORDER">
|
||||
<WxChannelsOrderTab v-if="selectedTab === 'WX_CHANNELS_ORDER'" />
|
||||
</TabPane>
|
||||
<TabPane label="视频号退单" name="WX_CHANNELS_REFUND">
|
||||
<WxChannelsRefundTab v-if="selectedTab === 'WX_CHANNELS_REFUND'" />
|
||||
</TabPane>
|
||||
<TabPane label="视频号商品" name="WX_CHANNELS_GOODS">
|
||||
<WxChannelsGoodsTab v-if="selectedTab === 'WX_CHANNELS_GOODS'" />
|
||||
</TabPane>
|
||||
<TabPane label="视频号分类列表" name="WX_CHANNELS_CATEGORY">
|
||||
<WxChannelsCategoryTab v-if="selectedTab === 'WX_CHANNELS_CATEGORY'" />
|
||||
</TabPane>
|
||||
<TabPane label="视频号设置" name="WX_CHANNELS">
|
||||
<WxChannelsSettingTab v-if="selectedTab === 'WX_CHANNELS'" />
|
||||
</TabPane>
|
||||
</Tabs>
|
||||
</Card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import WxChannelsSettingTab from "./components/WxChannelsSettingTab.vue";
|
||||
import WxChannelsCategoryTab from "./components/WxChannelsCategoryTab.vue";
|
||||
import WxChannelsGoodsTab from "./components/WxChannelsGoodsTab.vue";
|
||||
import WxChannelsOrderTab from "./components/WxChannelsOrderTab.vue";
|
||||
import WxChannelsOverviewTab from "./components/WxChannelsOverviewTab.vue";
|
||||
import WxChannelsRefundTab from "./components/WxChannelsRefundTab.vue";
|
||||
|
||||
export default {
|
||||
name: "wx-channel",
|
||||
components: {
|
||||
WxChannelsSettingTab,
|
||||
WxChannelsCategoryTab,
|
||||
WxChannelsGoodsTab,
|
||||
WxChannelsOrderTab,
|
||||
WxChannelsOverviewTab,
|
||||
WxChannelsRefundTab,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
selectedTab: "WX_CHANNELS",
|
||||
};
|
||||
},
|
||||
};
|
||||
</script>
|
||||
@@ -268,6 +268,13 @@ export const lowGoods = params => {
|
||||
return putRequest(`/goods/goods/under`, params);
|
||||
};
|
||||
|
||||
// 定时上下架商品
|
||||
export const scheduleGoodsMarket = params => {
|
||||
return postRequest(`/goods/goods/schedule/market`, params, {
|
||||
"Content-Type": "application/json"
|
||||
});
|
||||
};
|
||||
|
||||
// 获取商品单位列表
|
||||
export const getGoodsUnitList = params => {
|
||||
return getRequest(`/goods/goodsUnit`,params);
|
||||
|
||||
@@ -78,10 +78,19 @@
|
||||
<Row class="operation padding-row">
|
||||
<Button @click="addGoods" type="info">添加商品</Button>
|
||||
<Button @click="openImportGoods" >导入商品</Button>
|
||||
<Button @click="uppers" >批量上架</Button>
|
||||
<Button @click="lowers" >批量下架</Button>
|
||||
<Button @click="deleteAll" >批量删除</Button>
|
||||
<Button @click="batchShipTemplate" >批量设置物流模板</Button>
|
||||
<Dropdown @on-click="handleDropdown">
|
||||
<Button>
|
||||
批量修改
|
||||
<Icon type="ios-arrow-down"></Icon>
|
||||
</Button>
|
||||
<DropdownMenu slot="list">
|
||||
<DropdownItem name="uppers">批量上架</DropdownItem>
|
||||
<DropdownItem name="lowers">批量下架</DropdownItem>
|
||||
<DropdownItem name="scheduleMarket">批量定时上下架</DropdownItem>
|
||||
<DropdownItem name="batchShipTemplate">批量设置物流模板</DropdownItem>
|
||||
<DropdownItem name="deleteAll">批量删除</DropdownItem>
|
||||
</DropdownMenu>
|
||||
</Dropdown>
|
||||
</Row>
|
||||
|
||||
<Table
|
||||
@@ -173,6 +182,55 @@
|
||||
<Button type="primary" @click="saveShipTemplate">更新</Button>
|
||||
</div>
|
||||
</Modal>
|
||||
|
||||
<Modal
|
||||
title="批量定时上下架"
|
||||
v-model="scheduleMarketModal"
|
||||
:mask-closable="false"
|
||||
:width="520"
|
||||
>
|
||||
<Form
|
||||
ref="scheduleMarketFormRef"
|
||||
:model="scheduleMarketForm"
|
||||
:label-width="120"
|
||||
>
|
||||
<FormItem label="状态" prop="status">
|
||||
<Select v-model="scheduleMarketForm.status" style="width: 200px">
|
||||
<Option value="UPPER">上架</Option>
|
||||
<Option value="DOWN">下架</Option>
|
||||
</Select>
|
||||
</FormItem>
|
||||
<FormItem label="触发时间" prop="triggerTime">
|
||||
<DatePicker
|
||||
v-model="scheduleMarketForm.triggerTime"
|
||||
type="datetime"
|
||||
format="yyyy-MM-dd HH:mm:ss"
|
||||
:options="scheduleMarketDatePickerOptions"
|
||||
:time-picker-options="scheduleMarketTimePickerOptions"
|
||||
@on-change="handleScheduleMarketTimeChange"
|
||||
placeholder="请选择"
|
||||
clearable
|
||||
style="width: 240px"
|
||||
></DatePicker>
|
||||
</FormItem>
|
||||
<FormItem label="原因" prop="reason">
|
||||
<Input
|
||||
v-model="scheduleMarketForm.reason"
|
||||
type="textarea"
|
||||
:rows="3"
|
||||
placeholder="可选"
|
||||
/>
|
||||
</FormItem>
|
||||
</Form>
|
||||
<div slot="footer">
|
||||
<Button type="text" @click="scheduleMarketModal = false">取消</Button>
|
||||
<Button
|
||||
type="primary"
|
||||
:loading="scheduleMarketLoading"
|
||||
@click="submitScheduleMarket"
|
||||
>确定</Button>
|
||||
</div>
|
||||
</Modal>
|
||||
<Modal title="导入商品信息" v-model="importModal" :mask-closable="false">
|
||||
<div style="text-align: center">
|
||||
<Upload :before-upload="handleUpload" name="files" accept="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel"
|
||||
@@ -202,7 +260,8 @@ import {
|
||||
deleteGoods,
|
||||
batchShipTemplate,
|
||||
downLoadGoods,
|
||||
getGoodsNumerData
|
||||
getGoodsNumerData,
|
||||
scheduleGoodsMarket
|
||||
} from "@/api/goods";
|
||||
import { baseUrl } from "@/libs/axios.js";
|
||||
import * as API_Shop from "@/api/shops";
|
||||
@@ -224,6 +283,13 @@ export default {
|
||||
logisticsTemplate: [], // 物流列表
|
||||
updateStockModalVisible: false, // 更新库存模态框显隐
|
||||
stockAllUpdate: undefined, // 更新库存数量
|
||||
scheduleMarketModal: false,
|
||||
scheduleMarketLoading: false,
|
||||
scheduleMarketForm: {
|
||||
status: "UPPER",
|
||||
triggerTime: null,
|
||||
reason: ""
|
||||
},
|
||||
selectList: [], // 选中的商品列表
|
||||
selectCount: 0, // 选中的商品数量
|
||||
searchForm: {
|
||||
@@ -538,6 +604,46 @@ export default {
|
||||
{title: `待审核${this.goodsNumerData.auditGoodsNum ? '(' + this.goodsNumerData.auditGoodsNum + ')' : ''}`, value: 'TOBEAUDITED'},
|
||||
{title: `审核未通过${this.goodsNumerData.refuseGoodsNum ? '(' + this.goodsNumerData.refuseGoodsNum + ')' : ''}`, value: 'REFUSE'}
|
||||
];
|
||||
},
|
||||
scheduleMarketDatePickerOptions() {
|
||||
const todayStart = new Date();
|
||||
todayStart.setHours(0, 0, 0, 0);
|
||||
const todayStartMs = todayStart.getTime();
|
||||
return {
|
||||
disabledDate(date) {
|
||||
if (!date) return false;
|
||||
return date.getTime() < todayStartMs;
|
||||
}
|
||||
};
|
||||
},
|
||||
scheduleMarketTimePickerOptions() {
|
||||
const now = new Date();
|
||||
const selected = this.scheduleMarketForm && this.scheduleMarketForm.triggerTime
|
||||
? (this.scheduleMarketForm.triggerTime instanceof Date
|
||||
? this.scheduleMarketForm.triggerTime
|
||||
: new Date(this.scheduleMarketForm.triggerTime))
|
||||
: null;
|
||||
|
||||
const isToday = selected
|
||||
? selected.getFullYear() === now.getFullYear() &&
|
||||
selected.getMonth() === now.getMonth() &&
|
||||
selected.getDate() === now.getDate()
|
||||
: true;
|
||||
|
||||
if (!isToday) {
|
||||
return {};
|
||||
}
|
||||
|
||||
const nowH = now.getHours();
|
||||
const nowM = now.getMinutes();
|
||||
const nowS = now.getSeconds();
|
||||
|
||||
return {
|
||||
disabledHours: () => Array.from({ length: nowH }, (_, i) => i),
|
||||
disabledMinutes: (hour) => (hour === nowH ? Array.from({ length: nowM }, (_, i) => i) : []),
|
||||
disabledSeconds: (hour, minute) =>
|
||||
hour === nowH && minute === nowM ? Array.from({ length: nowS + 1 }, (_, i) => i) : []
|
||||
};
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
@@ -569,6 +675,10 @@ export default {
|
||||
if (v == "lowers") {
|
||||
this.lowers();
|
||||
}
|
||||
//批量定时上下架
|
||||
if (v == "scheduleMarket") {
|
||||
this.openScheduleMarketModal();
|
||||
}
|
||||
//批量删除商品
|
||||
if (v == "deleteAll") {
|
||||
this.deleteAll();
|
||||
@@ -733,6 +843,84 @@ export default {
|
||||
this.shipTemplateForm.goodsId = data;
|
||||
this.shipTemplateModal = true;
|
||||
},
|
||||
openScheduleMarketModal() {
|
||||
if (this.selectCount <= 0) {
|
||||
this.$Message.warning("您还未选择要定时上下架的商品");
|
||||
return;
|
||||
}
|
||||
this.scheduleMarketForm = {
|
||||
status: "UPPER",
|
||||
triggerTime: null,
|
||||
reason: ""
|
||||
};
|
||||
this.scheduleMarketModal = true;
|
||||
},
|
||||
handleScheduleMarketTimeChange() {
|
||||
if (!this.scheduleMarketForm || !this.scheduleMarketForm.triggerTime) return;
|
||||
const selected =
|
||||
this.scheduleMarketForm.triggerTime instanceof Date
|
||||
? this.scheduleMarketForm.triggerTime
|
||||
: new Date(this.scheduleMarketForm.triggerTime);
|
||||
|
||||
const selectedMs = selected.getTime();
|
||||
if (!Number.isFinite(selectedMs)) return;
|
||||
if (selectedMs <= Date.now()) {
|
||||
this.$Message.warning("触发时间只能选择当前时间之后");
|
||||
this.scheduleMarketForm.triggerTime = new Date(Date.now() + 60 * 1000);
|
||||
}
|
||||
},
|
||||
submitScheduleMarket() {
|
||||
if (this.selectCount <= 0) {
|
||||
this.$Message.warning("您还未选择要定时上下架的商品");
|
||||
return;
|
||||
}
|
||||
if (!this.scheduleMarketForm.status) {
|
||||
this.$Message.warning("请选择状态");
|
||||
return;
|
||||
}
|
||||
if (!this.scheduleMarketForm.triggerTime) {
|
||||
this.$Message.warning("请选择触发时间");
|
||||
return;
|
||||
}
|
||||
|
||||
const triggerTime =
|
||||
this.scheduleMarketForm.triggerTime instanceof Date
|
||||
? this.scheduleMarketForm.triggerTime.getTime()
|
||||
: new Date(this.scheduleMarketForm.triggerTime).getTime();
|
||||
|
||||
if (!Number.isFinite(triggerTime)) {
|
||||
this.$Message.error("触发时间格式不正确");
|
||||
return;
|
||||
}
|
||||
if (triggerTime <= Date.now()) {
|
||||
this.$Message.warning("触发时间需大于当前时间");
|
||||
return;
|
||||
}
|
||||
|
||||
const goodsIds = this.selectList.map((i) => i.id);
|
||||
|
||||
const payload = {
|
||||
goodsIds,
|
||||
status: this.scheduleMarketForm.status,
|
||||
triggerTime,
|
||||
reason: this.scheduleMarketForm.reason || undefined
|
||||
};
|
||||
|
||||
this.scheduleMarketLoading = true;
|
||||
scheduleGoodsMarket(payload)
|
||||
.then((res) => {
|
||||
if (res && res.success) {
|
||||
this.$Message.success("设置成功");
|
||||
this.scheduleMarketModal = false;
|
||||
this.clearSelectAll();
|
||||
this.getDataList();
|
||||
this.getNumberData();
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
this.scheduleMarketLoading = false;
|
||||
});
|
||||
},
|
||||
// 获取商品列表数据
|
||||
getDataList() {
|
||||
this.loading = true;
|
||||
|
||||
Reference in New Issue
Block a user