feat: 添加微信视频号管理模块和商品定时上下架功能

- 新增微信视频号管理页面,包含概况、订单、退单、商品、分类和设置六个标签页
- 实现微信视频号相关API接口,包括类目、商品、订单、退单和概况数据查询
- 在商品管理页面添加批量定时上下架功能,支持选择状态和触发时间
- 优化批量操作下拉菜单,整合上架、下架、定时上下架、物流模板设置和删除功能
- 改进设置页面样式,增强按钮布局的响应式设计
This commit is contained in:
pikachu1995@126.com
2026-03-15 17:34:50 +08:00
parent 40dc2b5d2f
commit 03ccdf2d43
11 changed files with 1151 additions and 5 deletions

View File

@@ -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) => {

View File

@@ -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{

View File

@@ -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>

View 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>

View 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>

View File

@@ -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>

View 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>

View 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>

View 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>