feat:优化店铺管理相关功能并进行界面改造

This commit is contained in:
pikachu1995@126.com
2026-07-22 17:52:11 +08:00
parent c83d715234
commit 6ee49ce9ac
14 changed files with 820 additions and 481 deletions

View File

@@ -24,7 +24,7 @@ export const getSellerFlow = (id, params) => {
// 商家核对结算单 // 商家核对结算单
export const reconciliation = (id, params) => { export const reconciliation = (id, params) => {
return putRequest(`/order/bill/check/${id}/`, params) return putRequest(`/order/bill/check/${id}`, params)
} }
//根据id获取店铺信息 //根据id获取店铺信息
export const downloadBill = (id) => { export const downloadBill = (id) => {

View File

@@ -6,6 +6,10 @@ import config from "@/config/index";
let util = {}; let util = {};
/** 店铺主页一级菜单 */
export const HOME_NAV_NAME = "home";
export const HOME_NAV_ITEM = { name: HOME_NAV_NAME, title: "主页" };
/** 静态路由名,禁止被动态路由清理误删 */ /** 静态路由名,禁止被动态路由清理误删 */
const STATIC_ROUTE_NAMES = new Set([ const STATIC_ROUTE_NAMES = new Set([
"home_index", "home_index",
@@ -437,7 +441,7 @@ util.initAllMenuData = function (constRoutes, data) {
util.initMenuData = function (vm, data) { util.initMenuData = function (vm, data) {
const menuRoutes = []; const menuRoutes = [];
let menuData = data; let menuData = data;
let navList = []; let navList = [HOME_NAV_ITEM];
menuData.forEach((e) => { menuData.forEach((e) => {
navList.push({ name: e.name, title: e.title }); navList.push({ name: e.name, title: e.title });
}); });
@@ -454,10 +458,16 @@ util.initMenuData = function (vm, data) {
} }
} }
} else { } else {
currNav = navList[0].name; currNav = HOME_NAV_NAME;
vm.$store.commit("setCurrNavTitle", navList[0].title); vm.$store.commit("setCurrNavTitle", HOME_NAV_ITEM.title);
} }
vm.$store.commit("setCurrNav", currNav); vm.$store.commit("setCurrNav", currNav);
if (currNav === HOME_NAV_NAME) {
vm.$store.commit("updateMenulist", []);
return;
}
for (let item of menuData) { for (let item of menuData) {
if (item.name == currNav) { if (item.name == currNav) {
menuData = item.children; menuData = item.children;
@@ -519,4 +529,31 @@ util.initRouterNode = function (routers, data) {
} }
}; };
util.getFirstRouterName = function (routeName) {
if (!routeName) {
return null;
}
const raw = window.localStorage.getItem("menuData");
if (!raw) {
return null;
}
try {
const menuData = JSON.parse(raw);
for (const top of menuData) {
const level1 = top.children || [];
for (const mid of level1) {
const leaves = mid.children || [];
for (const leaf of leaves) {
if (leaf.name === routeName) {
return leaf.firstRouterName || top.name;
}
}
}
}
} catch (e) {
console.warn("[util] getFirstRouterName failed", e);
}
return null;
};
export default util; export default util;

View File

@@ -198,6 +198,12 @@ export const otherRouter = {
meta: { title: "商品销售汇总报表" }, meta: { title: "商品销售汇总报表" },
component: () => import("@/views/statistics/goods-sales-summary.vue") component: () => import("@/views/statistics/goods-sales-summary.vue")
}, },
{
path: "procurement/purchase-order/list",
title: "采购单",
name: "procurementPurchaseOrderList",
component: () => import("@/views/procurement/purchase-order/list.vue")
},
{ {
path: "procurement/purchase-order/operation", path: "procurement/purchase-order/operation",
title: "采购单", title: "采购单",
@@ -233,6 +239,37 @@ export const otherRouter = {
title: "设置预警", title: "设置预警",
name: "alertQuantityWarnSetting", name: "alertQuantityWarnSetting",
component: () => import("@/views/goods/goods-seller/alertQuantityWarn.vue") component: () => import("@/views/goods/goods-seller/alertQuantityWarn.vue")
},
{
path: "order/returnMoneyOrder",
title: "退款管理",
name: "returnMoneyOrder",
component: () => import("@/views/order/after-order/returnMoneyOrder.vue")
},
{
path: "order/returnGoodsOrder",
title: "退货管理",
name: "returnGoodsOrder",
component: () => import("@/views/order/after-order/returnGoodsOrder.vue")
},
{
path: "order/memberComment",
title: "评价管理",
name: "memberComment",
component: () => import("@/views/member/memberComment.vue")
},
{
path: "bill/accountStatementBill",
title: "财务对账",
name: "accountStatementBill",
component: () => import("@/views/shop/bill/accountStatementBill.vue")
},
{
path: "bill/storeBill",
title: "店铺结算",
name: "storeBill",
meta: { firstRouterName: "bill" },
component: () => import("@/views/shop/bill/storeBill.vue")
} }
] ]
}; };

View File

@@ -3,7 +3,7 @@
</style> </style>
<template> <template>
<div class="main"> <div class="main" :class="{ 'menu-collapsed': !showSubMenu }">
<div class="sidebar-menu-con menu-bar"> <div class="sidebar-menu-con menu-bar">
<div class="logo-con"> <div class="logo-con">
<img :src="storeSideLogo" key="max-logo" /> <img :src="storeSideLogo" key="max-logo" />
@@ -121,6 +121,9 @@ export default {
pageTagsList() { pageTagsList() {
return this.$store.state.app.storeOpenedList; return this.$store.state.app.storeOpenedList;
}, },
showSubMenu() {
return this.$store.state.app.menuList.length > 0;
},
lang() { lang() {
return this.$store.state.app.lang; return this.$store.state.app.lang;
}, },

View File

@@ -449,6 +449,11 @@ export default {
}, },
}, },
mounted() { mounted() {
const goodsStatus = this.$route.query.goodsStatus;
if (goodsStatus) {
this.currentStatus = goodsStatus;
this.searchForm.goodsStatus = goodsStatus;
}
this.init(); this.init();
}, },
}; };

View File

@@ -57,60 +57,61 @@ h4 {
justify-content: flex-start; justify-content: flex-start;
} }
.notice-title { .notice-title {
margin: 10px 0; margin: 8px 0;
font-weight: bold; font-size: 14px;
} line-height: 1.5;
.detail-list {
display: flex;
flex-wrap: wrap;
}
.detail-title {
flex: 0 0 100%;
width: 100%;
order: -1;
align-self: flex-start;
margin-bottom: 8px;
padding-left: 4px;
opacity: 1;
color: #000;
font-size: 20px;
font-weight: normal;
text-decoration: initial;
transition: 0.35s;
}
.detail-item { a {
display: block;
color: #333;
font-weight: normal;
text-decoration: none;
cursor: pointer; cursor: pointer;
transition: 0.35s; overflow: hidden;
position: relative; text-overflow: ellipsis;
font-weight: bold; white-space: nowrap;
width: 286px; transition: color 0.2s;
display: flex;
flex-wrap: wrap; &:hover {
align-items: flex-end;
justify-content: center;
:deep(span) {
color: $theme_color; color: $theme_color;
font-size: 18px;
} }
padding: 16px 12px 20px; }
background: #eee; }
border-radius: 0.4em; .todo-group-list {
margin: 10px;
> div:not(.detail-title) {
flex: 1;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 12px;
}
.todo-group {
display: flex;
align-items: stretch;
background: #eee;
border-radius: 0.4em;
overflow: hidden;
}
.todo-item {
cursor: pointer;
flex: 1;
box-sizing: border-box;
padding: 14px 16px;
display: flex;
flex-direction: column;
align-items: flex-start;
justify-content: center; justify-content: center;
align-items: center; text-align: left;
margin: 0 8px;
.todo-item-label {
font-size: 13px;
color: #666;
margin-bottom: 6px;
} }
}
.detail-item:hover { span {
box-shadow: 3px 5px 12px rgba(0, 0, 0, 0.2); color: $theme_color;
transform: translateY(-4px); font-size: 18px;
> .detail-title { font-weight: bold;
opacity: 1;
} }
} }
@@ -121,19 +122,6 @@ h4 {
border: 3px solid #ededed; border: 3px solid #ededed;
box-sizing: border-box; box-sizing: border-box;
} }
.count-item,
.todo-item {
height: 84px;
display: flex;
cursor: pointer;
justify-content: center;
align-items: center;
color: #fff;
border-radius: 0.4em;
flex: 1;
font-weight: bold;
margin-right: 20px;
}
.card { .card {
box-shadow: 1px 3px 12px rgba($color: #e7e7e7, $alpha: 0.3); box-shadow: 1px 3px 12px rgba($color: #e7e7e7, $alpha: 0.3);
@@ -147,25 +135,68 @@ h4 {
.box-right { .box-right {
flex: 2; flex: 2;
margin-left: 20px; margin-left: 20px;
h4 {
font-size: 16px;
margin: 16px 0 12px;
}
} }
.count-item:nth-of-type(1) { .overview-list {
background-image: linear-gradient(109.6deg, rgba($color: #ff9a76, $alpha: 0.6) 11.2%, #ff9a76 100.2%); flex-wrap: wrap;
gap: 16px;
box-shadow: 1px 3px 12px rgba($color: #ff9a76, $alpha: 0.3);
} }
.count-item:nth-of-type(2) {
background-image: linear-gradient(109.6deg, rgba($color: #4e89ae, $alpha: 0.6) 11.2%, #4e89ae 100.2%);
box-shadow: 1px 3px 12px rgba($color: #4e89ae, $alpha: 0.3); .overview-item {
} flex: 1;
.count-item:nth-of-type(3) { min-width: 180px;
background-image: linear-gradient(109.6deg, rgba($color: #679b9b, $alpha: 0.6) 11.2%, #679b9b 100.2%); padding: 16px 20px;
background: #f8f9fb;
border-radius: 0.4em;
cursor: pointer;
transition: 0.3s;
box-shadow: 1px 3px 12px rgba($color: #679b9b, $alpha: 0.3); &:hover {
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
transform: translateY(-2px);
}
} }
.count-item:nth-of-type(4) {
background-image: linear-gradient(109.6deg, rgba($color: #637373, $alpha: 0.6) 11.2%, #637373 100.2%);
box-shadow: 1px 3px 12px rgba($color: #637373, $alpha: 0.3); .overview-label {
font-size: 14px;
color: #666;
margin-bottom: 8px;
}
.overview-value {
font-size: 24px;
font-weight: bold;
color: $theme_color;
margin-bottom: 6px;
}
.overview-sub {
font-size: 12px;
color: #999;
}
.compare-up {
color: #67c23a;
margin-left: 4px;
}
.compare-down {
color: #f56c6c;
margin-left: 4px;
}
.compare-flat {
color: #999;
margin-left: 4px;
}
.rank-tip {
font-size: 12px;
color: #999;
margin: -10px 0 16px;
} }

View File

@@ -73,71 +73,60 @@
</div> </div>
<div class="card"> <div class="card">
<h4>待办事项</h4> <h4>待办事项</h4>
<div class="todo-group-list">
<div class="detail-list"> <div class="todo-group">
<div class="detail-item" @click="navigateTo('orderList')"> <div class="todo-item" @click="navigateTo('orderList', { orderStatus: 'UNPAID' })">
<div> <div class="todo-item-label">待付款订单</div>
<span>{{ homeData.unPaidOrder || 0 }}</span> <span>{{ homeData.unPaidOrder || 0 }}</span>
<div>待付款</div>
</div> </div>
<div class="detail-title">交易前</div> <div class="todo-item" @click="navigateTo('orderList', { orderStatus: 'UNDELIVERED' })">
</div> <div class="todo-item-label">待发货订单</div>
<div class="detail-item" @click="navigateTo('orderList')">
<div>
<span>{{ homeData.unDeliveredOrder || 0 }}</span> <span>{{ homeData.unDeliveredOrder || 0 }}</span>
<div>待发货</div>
</div> </div>
<div> <div class="todo-item" @click="navigateTo('orderList', { orderStatus: 'DELIVERED' })">
<div class="todo-item-label">待收货订单</div>
<span>{{ homeData.deliveredOrder || 0 }}</span> <span>{{ homeData.deliveredOrder || 0 }}</span>
<div>待收货</div>
</div> </div>
<div class="detail-title">交易中</div> <div class="todo-item" @click="navigateTo('orderList', { orderStatus: 'TAKE' })">
<div class="todo-item-label">待核验订单</div>
<span>{{ homeData.waitCheckOrder || 0 }}</span>
</div> </div>
<div class="detail-item">
<div @click="navigateTo('returnMoneyOrder')">
<span>{{ homeData.returnMoney || 0 }}</span>
<div>退款</div>
</div> </div>
<div @click="navigateTo('returnGoodsOrder')"> <div class="todo-group">
<span>{{ homeData.returnGoods || 0 }}</span> <div class="todo-item" @click="navigateAfterSale('APPLY')">
<div>退货</div> <div class="todo-item-label">待审核退单</div>
<span>{{ afterSaleNumData.applyNum || 0 }}</span>
</div> </div>
<div @click="navigateTo('memberComment')"> <div class="todo-item" @click="navigateAfterSale('PASS')">
<span>{{ homeData.memberEvaluation || 0 }}</span> <div class="todo-item-label">待填写物流退单</div>
<div>待评价</div> <span>{{ afterSaleNumData.passNum || 0 }}</span>
</div> </div>
<div class="detail-title">交易后</div> <div class="todo-item" @click="navigateAfterSale('BUYER_RETURN')">
<div class="todo-item-label">待收货退单</div>
<span>{{ afterSaleNumData.buyerReturnNum || 0 }}</span>
</div> </div>
<div class="detail-item" @click="navigateTo('orderComplaint')"> <div class="todo-item" @click="navigateAfterSale('WAIT_REFUND')">
<div> <div class="todo-item-label">待退款退单</div>
<span>{{ homeData.complaint || 0 }}</span> <span>{{ afterSaleNumData.waitRefundNum || 0 }}</span>
<div>待处理</div>
</div> </div>
<div class="detail-title">投诉</div>
</div> </div>
<div class="detail-item"> <div class="todo-group">
<div @click="navigateTo('alert-goods-quantity')"> <div class="todo-item" @click="navigateTo('alertQuantityWarnList')">
<div class="todo-item-label">库存预警商品</div>
<span>{{ homeData.alertQuantityNum || 0 }}</span> <span>{{ homeData.alertQuantityNum || 0 }}</span>
<div>库存预警</div>
</div> </div>
<div @click="navigateTo('goods')"> <div class="todo-item" @click="navigateToProcurementAudit()">
<div class="todo-item-label">待审核采购单</div>
<span>{{ procurementStatusCount.SUBMITTED || 0 }}</span>
</div>
<div class="todo-item" @click="navigateTo('goods', { goodsStatus: 'TOBEAUDITED' })">
<div class="todo-item-label">待审核商品</div>
<span>{{ homeData.waitAuth || 0 }}</span> <span>{{ homeData.waitAuth || 0 }}</span>
<div>审核中</div>
</div> </div>
<div class="detail-title">商品</div> <div class="todo-item" @click="navigateTo('storeBill', { billStatus: 'OUT' })">
</div> <div class="todo-item-label">待结算账单</div>
<div class="detail-item">
<div @click="navigateTo('seckill')">
<span>{{ homeData.seckillNum || 0 }}</span>
<div>秒杀活动</div>
</div>
<div @click="navigateTo('accountStatementBill')">
<span>{{ homeData.waitPayBill || 0 }}</span> <span>{{ homeData.waitPayBill || 0 }}</span>
<div>等待对账</div>
</div> </div>
<div class="detail-title">其他</div>
</div> </div>
</div> </div>
</div> </div>
@@ -153,73 +142,113 @@
</div> </div>
<div class="card"> <div class="card">
<h4>统计数据</h4> <h4>经营概览</h4>
<div class="count-list flex"> <div class="overview-list flex">
<div class="count-item" @click="navigateTo('goods')"> <div class="overview-item" @click="navigateTo('orderStatistics')">
<div> <div class="overview-label">今日销售额</div>
<el-icon class="icon" :size="31"><Picture /></el-icon> <div class="overview-value">
{{ $filters.unitPrice(overviewToday.paymentAmount || 0, "¥") }}
</div> </div>
<div> <div class="overview-sub">
<div class="counts">{{ homeData.goodsNum || 0 }}</div> 昨日 {{ $filters.unitPrice(overviewYesterday.paymentAmount || 0, "¥") }}
<div>上架商品数量</div> <span :class="compareClass(overviewToday.paymentAmount, overviewYesterday.paymentAmount)">
{{ compareText(overviewToday.paymentAmount, overviewYesterday.paymentAmount) }}
</span>
</div> </div>
</div> </div>
<div class="count-item" @click="navigateTo('orderStatistics')"> <div class="overview-item" @click="navigateTo('orderList')">
<div> <div class="overview-label">今日订单量</div>
<el-icon class="icon" :size="31"><CreditCard /></el-icon> <div class="overview-value">{{ overviewToday.orderNum || 0 }}</div>
</div> <div class="overview-sub">
<div> 昨日 {{ overviewYesterday.orderNum || 0 }}
<div class="counts"> <span :class="compareClass(overviewToday.orderNum, overviewYesterday.orderNum)">
{{ $filters.unitPrice(homeData.orderPrice || 0, "¥") }} {{ compareText(overviewToday.orderNum, overviewYesterday.orderNum) }}
</div> </span>
<div>今日订单总额</div>
</div> </div>
</div> </div>
<div class="count-item" @click="navigateTo('orderList')"> <div class="overview-item" @click="navigateTo('trafficStatistics')">
<div> <div class="overview-label">今日访客数</div>
<el-icon class="icon" :size="31"><List /></el-icon> <div class="overview-value">{{ overviewToday.uvNum || 0 }}</div>
</div> <div class="overview-sub">
<div> 昨日 {{ overviewYesterday.uvNum || 0 }}
<div class="counts">{{ homeData.orderNum || 0 }}</div> <span :class="compareClass(overviewToday.uvNum, overviewYesterday.uvNum)">
<div>今日订单数量</div> {{ compareText(overviewToday.uvNum, overviewYesterday.uvNum) }}
</span>
</div> </div>
</div> </div>
<div class="count-item" @click="navigateTo('trafficStatistics')"> <div class="overview-item" @click="navigateTo('goods')">
<div> <div class="overview-label">在售商品</div>
<el-icon class="icon" :size="31"><User /></el-icon> <div class="overview-value">{{ homeData.goodsNum || 0 }}</div>
</div> </div>
<div> <div class="overview-item" @click="navigateTo('goods', { goodsStatus: 'TOBEAUDITED' })">
<div class="counts">{{ homeData.storeUV || 0 }}</div> <div class="overview-label">待审核商品</div>
<div>今日访客数量</div> <div class="overview-value">{{ homeData.waitAuth || 0 }}</div>
</div> </div>
</div> </div>
</div> </div>
<div class="card">
<h4>商品销售排行 TOP10</h4>
<div class="rank-tip">统计区间近7天</div>
<el-table stripe :data="topGoodsData" style="width: 100%">
<el-table-column type="index" label="排名" width="80" align="center" />
<el-table-column prop="goodsName" label="商品名称" min-width="200" show-overflow-tooltip />
<el-table-column prop="goodsId" label="商品编码" min-width="160" show-overflow-tooltip />
<el-table-column prop="orderNum" label="下单笔数" width="120" align="center" />
<el-table-column label="下单金额" width="140" align="right">
<template #default="{ row }">
<span :style="{ color: $mainColor }">
{{ $filters.unitPrice(row.price || 0, "¥") }}
</span>
</template>
</el-table-column>
</el-table>
</div> </div>
</div> </div>
</template> </template>
<script> <script>
import defaultLogo from "@/assets/logo1.png"; import defaultLogo from "@/assets/logo1.png";
import { Picture, CreditCard, List, User } from "@element-plus/icons-vue";
import { getSellerHomeData, getHomeNotice } from "@/api/index"; import { getSellerHomeData, getHomeNotice } from "@/api/index";
import { getOrderOverView, goodsStatistics } from "@/api/goods";
import { getAfterSaleNumVO } from "@/api/order";
import { getProcurementOrderStatusCount } from "@/api/procurement";
import { getIMDetail } from "@/api/common"; import { getIMDetail } from "@/api/common";
import { seeArticle } from "@/api/pages"; import { seeArticle } from "@/api/pages";
import Cookies from "js-cookie"; import Cookies from "js-cookie";
import { userMsg } from "@/api/index"; import { userMsg } from "@/api/index";
const HOME_ROUTE_TARGETS = {
orderList: { name: "orderList", path: "/order/orderList" },
returnMoneyOrder: { name: "returnMoneyOrder", path: "/order/returnMoneyOrder" },
returnGoodsOrder: { name: "returnGoodsOrder", path: "/order/returnGoodsOrder" },
memberComment: { name: "memberComment", path: "/order/memberComment" },
goods: { name: "goods", path: "/goods" },
alertQuantityWarnList: { name: "alertQuantityWarnList", path: "/alertQuantityWarnList" },
orderStatistics: { name: "orderStatistics", path: "/statistics/orderStatistics" },
trafficStatistics: { name: "trafficStatistics", path: "/statistics/trafficStatistics" },
accountStatementBill: { name: "accountStatementBill", path: "/bill/accountStatementBill" },
storeBill: { name: "storeBill", path: "/bill/storeBill" },
procurementPurchaseOrderList: {
name: "procurementPurchaseOrderList",
path: "/procurement/purchase-order/list",
},
};
const AFTER_SALE_RETURN_GOODS_STATUSES = ["PASS", "BUYER_RETURN"];
export default { export default {
name: "home", name: "home",
components: {
Picture,
CreditCard,
List,
User,
},
data() { data() {
return { return {
defaultLogo, defaultLogo,
noticeFlage: false, noticeFlage: false,
homeData: {}, homeData: {},
overviewToday: {},
overviewYesterday: {},
topGoodsData: [],
afterSaleNumData: {},
procurementStatusCount: {},
userData: "", userData: "",
notices: "", notices: "",
noticesDetail: { noticesDetail: {
@@ -230,8 +259,47 @@ export default {
}; };
}, },
methods: { methods: {
navigateTo(name) { navigateAfterSale(serviceStatus) {
this.$router.push({ name }); const routeKey = AFTER_SALE_RETURN_GOODS_STATUSES.includes(serviceStatus)
? "returnGoodsOrder"
: "returnMoneyOrder";
this.navigateTo(routeKey, { serviceStatus });
},
navigateToProcurementAudit() {
this.navigateTo("procurementPurchaseOrderList", { status: "SUBMITTED" });
},
navigateTo(key, query) {
const target = HOME_ROUTE_TARGETS[key] || { name: key };
if (target.name && this.$router.hasRoute(target.name)) {
this.$router.push({ name: target.name, query });
return;
}
if (target.path) {
const resolved = this.$router.resolve({ path: target.path, query });
if (resolved.matched.length > 0) {
this.$router.push({ path: target.path, query });
return;
}
}
this.$Message.warning("暂无权限访问该页面");
},
compareText(today, yesterday) {
const t = Number(today) || 0;
const y = Number(yesterday) || 0;
if (y === 0) {
return t > 0 ? "↑ --" : "—";
}
const rate = (((t - y) / y) * 100).toFixed(1);
if (t > y) return `${rate}%`;
if (t < y) return `${Math.abs(rate)}%`;
return "—";
},
compareClass(today, yesterday) {
const t = Number(today) || 0;
const y = Number(yesterday) || 0;
if (t > y) return "compare-up";
if (t < y) return "compare-down";
return "compare-flat";
}, },
async init() { async init() {
const userInfo = JSON.parse(Cookies.get("userInfoSeller")); const userInfo = JSON.parse(Cookies.get("userInfoSeller"));
@@ -273,10 +341,50 @@ export default {
this.homeData = res.result; this.homeData = res.result;
} }
}, },
async loadOverview() {
const year = new Date().getFullYear();
const [todayRes, yesterdayRes] = await Promise.all([
getOrderOverView({ searchType: "TODAY", year }),
getOrderOverView({ searchType: "YESTERDAY", year }),
]);
if (todayRes.success) {
this.overviewToday = todayRes.result || {};
}
if (yesterdayRes.success) {
this.overviewYesterday = yesterdayRes.result || {};
}
},
async loadSalesRank() {
const year = new Date().getFullYear();
const res = await goodsStatistics({
searchType: "LAST_SEVEN",
year,
type: "NUM",
});
if (res.success && res.result) {
this.topGoodsData = res.result.slice(0, 10);
}
},
async loadAfterSaleNum() {
const res = await getAfterSaleNumVO({});
if (res.success) {
this.afterSaleNumData = res.result || {};
}
},
async loadProcurementStatusCount() {
const res = await getProcurementOrderStatusCount({});
if (res.success) {
this.procurementStatusCount = res.result || {};
}
},
}, },
mounted() { mounted() {
this.init(); this.init();
this.getHomeData(); this.getHomeData();
this.loadOverview();
this.loadSalesRank();
this.loadAfterSaleNum();
this.loadProcurementStatusCount();
}, },
}; };
</script> </script>
@@ -284,6 +392,10 @@ export default {
<style lang="scss" scoped> <style lang="scss" scoped>
@import "./home.scss"; @import "./home.scss";
.noticesDetail { .noticesDetail {
font-size: 14px;
line-height: 1.6;
color: #333;
:deep(img) { :deep(img) {
max-width: 100%; max-width: 100%;
max-height: 200px; max-height: 200px;

View File

@@ -1,5 +1,5 @@
<template> <template>
<div class="shrinkable-menu"> <div class="shrinkable-menu" :class="{ 'no-sub-menu': !menuList.length }">
<el-menu <el-menu
ref="sideMenu" ref="sideMenu"
class="nav-menu-dark" class="nav-menu-dark"
@@ -11,6 +11,7 @@
</el-menu-item> </el-menu-item>
</el-menu> </el-menu>
<el-menu <el-menu
v-if="menuList.length"
ref="childrenMenu" ref="childrenMenu"
:key="currNav" :key="currNav"
class="sub-menu" class="sub-menu"
@@ -33,7 +34,7 @@
</template> </template>
<script> <script>
import util from "@/libs/util.js"; import util, { HOME_NAV_NAME, HOME_NAV_ITEM } from "@/libs/util.js";
export default { export default {
name: "shrinkableMenu", name: "shrinkableMenu",
@@ -50,15 +51,30 @@ export default {
}, },
watch: { watch: {
$route(val) { $route(val) {
if ( this.syncRouteMenu(val);
val.meta.firstRouterName &&
val.meta.firstRouterName !== this.currNav
) {
this.selectNav(val.meta.firstRouterName);
}
}, },
}, },
methods: { methods: {
syncRouteMenu(route) {
if (!route?.name) {
return;
}
if (route.name === "home_index") {
this.activateHomeNav();
return;
}
const firstRouterName =
route.meta?.firstRouterName || util.getFirstRouterName(route.name);
if (firstRouterName && firstRouterName !== this.currNav) {
this.selectNav(firstRouterName);
}
},
activateHomeNav() {
this.$store.commit("setCurrNav", HOME_NAV_NAME);
this.$store.commit("setCurrNavTitle", HOME_NAV_ITEM.title);
this.setStore("currNav", HOME_NAV_NAME);
this.$store.commit("updateMenulist", []);
},
changeMenu(name) { changeMenu(name) {
if (!name) return; if (!name) return;
this.$router.push({ name }); this.$router.push({ name });
@@ -67,9 +83,20 @@ export default {
this.$store.commit("childrenMenu", this.$refs.childrenMenu); this.$store.commit("childrenMenu", this.$refs.childrenMenu);
this.$store.commit("setCurrNav", name); this.$store.commit("setCurrNav", name);
this.setStore("currNav", name); this.setStore("currNav", name);
if (name === HOME_NAV_NAME) {
this.$store.commit("updateMenulist", []);
this.$store.commit("setCurrNavTitle", HOME_NAV_ITEM.title);
if (this.$route.name !== "home_index") {
this.$router.push({ name: "home_index" });
}
return;
}
util.initRouter(this); util.initRouter(this);
}, },
}, },
mounted() {
this.syncRouteMenu(this.$route);
},
}; };
</script> </script>
@@ -78,6 +105,11 @@ export default {
height: calc(100% - 60px); height: calc(100% - 60px);
width: 180px; width: 180px;
display: flex; display: flex;
transition: width 0.3s;
&.no-sub-menu {
width: 80px;
}
} }
.nav-menu-dark { .nav-menu-dark {

View File

@@ -29,6 +29,7 @@
top: 0; top: 0;
left: 0; left: 0;
z-index: 21; z-index: 21;
width: 180px;
transition: width 0.3s; // background: rgb(73, 80, 96) transition: width 0.3s; // background: rgb(73, 80, 96)
background: #fff; background: #fff;
box-shadow: rgba(0, 21, 41, 0.35) 2px 0px 6px; box-shadow: rgba(0, 21, 41, 0.35) 2px 0px 6px;
@@ -236,7 +237,7 @@
overflow: auto; overflow: auto;
background-color: #f0f0f0; background-color: #f0f0f0;
z-index: 1; z-index: 1;
transition: left 0.3s; transition: left 0.3s, width 0.3s;
.single-page { .single-page {
position: relative; position: relative;
@@ -244,6 +245,21 @@
} }
} }
&.menu-collapsed {
.sidebar-menu-con {
width: 80px;
}
.main-header-con {
padding-left: 80px;
}
.single-page-con {
left: 80px;
width: calc(100% - 80px);
}
}
&-copy { &-copy {
text-align: center; text-align: center;
padding: 10px 0 20px; padding: 10px 0 20px;

View File

@@ -321,6 +321,11 @@ export default {
}, },
}, },
mounted() { mounted() {
const status = this.$route.query.serviceStatus;
if (status) {
this.currentStatus = status;
this.searchForm.serviceStatus = status;
}
this.init(); this.init();
}, },
}; };

View File

@@ -315,6 +315,11 @@ export default {
}, },
}, },
mounted() { mounted() {
const status = this.$route.query.serviceStatus;
if (status) {
this.currentStatus = status;
this.searchForm.serviceStatus = status;
}
this.init(); this.init();
}, },
}; };

View File

@@ -393,6 +393,11 @@ export default {
}, },
}, },
mounted() { mounted() {
const orderStatus = this.$route.query.orderStatus;
if (orderStatus) {
this.currentStatus = orderStatus;
this.searchForm.orderStatus = orderStatus;
}
this.init(); this.init();
}, },
}; };

View File

@@ -145,6 +145,11 @@ export default {
}, },
}, },
mounted() { mounted() {
const status = this.$route.query.status;
if (status) {
this.currentStatus = status;
this.searchForm.status = status;
}
this.init(); this.init();
}, },
methods: { methods: {

View File

@@ -1,5 +1,5 @@
<template> <template>
<div class="store-bill"> <div class="search">
<el-card> <el-card>
<el-form <el-form
ref="searchForm" ref="searchForm"
@@ -29,13 +29,6 @@
style="width: 240px" style="width: 240px"
/> />
</el-form-item> </el-form-item>
<el-form-item label="状态" prop="billStatus">
<el-select v-model="searchForm.billStatus" placeholder="请选择" clearable style="width: 240px">
<el-option label="已出账" value="OUT" />
<el-option label="已对账" value="CHECK" />
<el-option label="已完成" value="COMPLETE" />
</el-select>
</el-form-item>
<el-form-item> <el-form-item>
<el-button type="primary" class="search-btn" @click="handleSearch">搜索</el-button> <el-button type="primary" class="search-btn" @click="handleSearch">搜索</el-button>
<el-button class="search-btn" @click="handleReset">重置</el-button> <el-button class="search-btn" @click="handleReset">重置</el-button>
@@ -45,6 +38,17 @@
</el-card> </el-card>
<el-card> <el-card>
<div class="bill-tab">
<el-tabs v-model="currentStatus" @tab-click="onStatusTabClick">
<el-tab-pane
v-for="(item, index) in billStatusTabs"
:key="index"
:label="item.title"
:name="item.value"
/>
</el-tabs>
</div>
<el-table v-loading="loading" border :data="data" ref="table" class="mt_10" style="width: 100%"> <el-table v-loading="loading" border :data="data" ref="table" class="mt_10" style="width: 100%">
<el-table-column prop="sn" label="账单号" min-width="250" show-overflow-tooltip /> <el-table-column prop="sn" label="账单号" min-width="250" show-overflow-tooltip />
<el-table-column prop="createTime" label="生成时间" min-width="120" /> <el-table-column prop="createTime" label="生成时间" min-width="120" />
@@ -106,9 +110,34 @@ export default {
}, },
data: [], data: [],
total: 0, total: 0,
currentStatus: "ALL",
}; };
}, },
computed: {
billStatusTabs() {
return [
{ title: "全部", value: "ALL" },
{ title: "已出账", value: "OUT" },
{ title: "已对账", value: "CHECK" },
{ title: "已完成", value: "COMPLETE" },
];
},
},
methods: { methods: {
onStatusTabClick(tab) {
this.billStatusClick(tab.paneName);
},
billStatusClick(name) {
if (name === "ALL" || name === "" || name === undefined || name === null) {
delete this.searchForm.billStatus;
this.currentStatus = "ALL";
} else {
this.searchForm.billStatus = name;
this.currentStatus = name;
}
this.searchForm.pageNumber = 1;
this.getDataList();
},
init() { init() {
this.getDataList(); this.getDataList();
}, },
@@ -125,6 +154,7 @@ export default {
this.getDataList(); this.getDataList();
}, },
handleReset() { handleReset() {
const { billStatus } = this.searchForm;
this.searchForm = { this.searchForm = {
pageNumber: 1, pageNumber: 1,
pageSize: 10, pageSize: 10,
@@ -133,6 +163,9 @@ export default {
startDate: "", startDate: "",
endDate: "", endDate: "",
}; };
if (this.currentStatus !== "ALL") {
this.searchForm.billStatus = billStatus;
}
this.getDataList(); this.getDataList();
}, },
getDataList() { getDataList() {
@@ -159,6 +192,11 @@ export default {
}, },
}, },
mounted() { mounted() {
const billStatus = this.$route.query.billStatus;
if (billStatus) {
this.currentStatus = billStatus;
this.searchForm.billStatus = billStatus;
}
this.init(); this.init();
}, },
beforeRouteLeave(to, from, next) { beforeRouteLeave(to, from, next) {
@@ -170,6 +208,14 @@ export default {
<style lang="scss" scoped> <style lang="scss" scoped>
@import "@/styles/table-common.scss"; @import "@/styles/table-common.scss";
.search > .el-card + .el-card {
margin-top: 16px;
}
.bill-tab {
:deep(.el-tabs__item) {
font-size: 14px;
}
}
.link-text { .link-text {
color: #409eff; color: #409eff;
cursor: pointer; cursor: pointer;