feat(欢迎页): 添加商家信息展示和二维码功能

- 新增商家信息展示区域,包含商家图片和名称
- 添加商家二维码展示功能,支持扫码进入小程序
- 实现商店列表获取和当前商店选择逻辑
- 调整欢迎页布局结构,优化视觉呈现
This commit is contained in:
dzq 2025-11-22 10:50:10 +08:00
parent c13187b996
commit f1382e945e
2 changed files with 199 additions and 1 deletions

BIN
src/assets/qrcode.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 91 KiB

View File

@ -1,10 +1,12 @@
<script setup lang="ts">
import { Goods, Shop, Document, Money } from '@element-plus/icons-vue';
import { getStats, TodayLatestOrderGoodsDTO, TopGoodsDTO } from '@/api/shop/stats';
import { getShopListApi, ShopDTO, getModeText } from '@/api/shop/shop';
import { markRaw, onMounted, ref } from 'vue';
import { useWxStore } from '@/store/modules/wx';
import { ElDialog, ElForm, ElFormItem, ElInput, ElMessage } from 'element-plus';
import { bindQyUserApi } from '@/api/ab98/user';
import qrcode from '@/assets/qrcode.png';
defineOptions({
name: "Welcome"
@ -12,6 +14,10 @@ defineOptions({
const wxStore = useWxStore();
const shopList = ref<ShopDTO[]>([]);
const currentShop = ref<ShopDTO | null>(null);
const selectedShopId = ref<number | null>(null);
const shopData = ref<{
name: string;
icon: any; // Element Plus
@ -62,7 +68,62 @@ const handleSubmit = async () => {
}
};
const handleShopChange = (shopId: number) => {
const selectedShop = shopList.value.find(shop => shop.shopId === shopId);
if (selectedShop) {
currentShop.value = selectedShop;
//
fetchShopStats();
}
};
const fetchShopStats = async () => {
if (!currentShop.value) return;
try {
const { data } = await getStats(wxStore.corpid);
shopData.value = [
{ name: '商店', icon: markRaw(Shop), value: data.shopCount },
{ name: '商品总数量', icon: markRaw(Goods), value: data.goodsCount },
{ name: '商品总订单', icon: markRaw(Document), value: data.orderCount },
{ name: '商品总金额', icon: markRaw(Money), value: data.goodsTotalAmount }
];
unReturnedData.value = [
{ name: '未还商品', value: data.unReturnedGoodsCount },
{ name: '未还订单', value: data.unReturnedOrderCount },
{ name: '未还金额', value: data.unReturnedAmount }
];
deviceData.value = [
{ name: '总柜子', value: data.cabinetCount },
{ name: '总格口', value: data.cellCount },
{ name: '已关联', value: data.linkedCellCount },
{ name: '未关联', value: data.unmanagedCellCount },
{ name: '网关', value: data.gatewayCount }
];
topGoods.value = data.topGoods;
todayLatestOrderGoods.value = data.todayLatestOrderGoods;
maxOccurrenceCount.value = Math.max(...data.topGoods.map(item => item.occurrenceCount), 1);
} catch (error) {
console.error('获取统计数据失败:', error);
}
};
const fetchShopList = async () => {
try {
const { data } = await getShopListApi({ corpid: wxStore.corpid });
shopList.value = data;
if (data.length > 0) {
currentShop.value = data[0];
selectedShopId.value = data[0].shopId;
}
} catch (error) {
console.error('获取商店列表失败:', error);
}
};
onMounted(async () => {
await fetchShopList();
try {
const { data } = await getStats(wxStore.corpid);
shopData.value = [
@ -101,6 +162,50 @@ onMounted(async () => {
<div class="welcome-container">
<el-row :gutter="12">
<el-col :span="17">
<!-- 商店选择容器 -->
<div class="section-container shop-selection-container" v-if="currentShop">
<div class="section-title">
<div class="title-bar"></div>
<div class="title-text">商家信息</div>
</div>
<div class="shop-content">
<div class="shop-info">
<el-image
:src="currentShop.coverImg || '/src/assets/login/login-bg.png'"
fit="cover"
class="shop-image"
/>
<div class="shop-details">
<div class="shop-name-container">
<h3 class="shop-name">{{ currentShop.shopName }}</h3>
<!-- <el-select
v-model="selectedShopId"
placeholder="选择商店"
class="shop-selector"
@change="handleShopChange"
>
<el-option
v-for="shop in shopList"
:key="shop.shopId"
:label="shop.shopName"
:value="shop.shopId"
/>
</el-select> -->
</div>
<!-- <p class="shop-mode">{{ getModeText(currentShop.mode) }}</p> -->
</div>
</div>
<div class="shop-qrcode">
<el-image
:src="qrcode"
fit="contain"
class="qrcode-image"
/>
<p class="qrcode-text">扫码进入小程序</p>
</div>
</div>
</div>
<!-- 待办事项 -->
<div class="section-container todo-container">
<div class="section-title">
@ -123,7 +228,6 @@ onMounted(async () => {
</div>
<el-row :gutter="12">
<!-- 数据统计 -->
<el-col :span="12">
<div class="section-container shop-container">
<div class="section-title">
@ -169,6 +273,7 @@ onMounted(async () => {
<el-row :gutter="12">
<!-- 今日最新订单 -->
<!--
<el-col :span="12">
<div class="section-container order-container">
<div class="section-title">
@ -194,6 +299,7 @@ onMounted(async () => {
</div>
</div>
</el-col>
-->
</el-row>
</el-col>
<!-- 热门商品 -->
@ -424,5 +530,97 @@ onMounted(async () => {
width: 60px;
}
}
.shop-selection-container {
padding: 20px;
margin-bottom: 12px;
.shop-content {
display: flex;
justify-content: space-between;
align-items: center;
}
.shop-info {
display: flex;
align-items: flex-start;
flex: 1;
.shop-image {
width: 240px;
height: 160px;
border-radius: 8px;
margin-left: 16px;
margin-right: 26px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
.shop-details {
padding-top: 16px;
.shop-name-container {
display: flex;
align-items: center;
gap: 12px;
margin-bottom: 8px;
.shop-name {
font-size: 20px;
font-weight: bold;
color: var(--el-text-color-primary);
margin: 0;
white-space: nowrap;
}
.shop-selector {
min-width: 200px;
:deep(.el-input__wrapper) {
border-radius: 4px;
border: 1px solid var(--el-border-color);
box-shadow: none;
&:hover {
border-color: var(--el-color-primary);
}
&.is-focus {
border-color: var(--el-color-primary);
box-shadow: 0 0 0 1px var(--el-color-primary);
}
}
}
}
.shop-mode {
font-size: 14px;
color: var(--el-text-color-secondary);
margin: 0;
}
}
}
.shop-qrcode {
display: flex;
flex-direction: column;
align-items: center;
margin-right: 20px;
.qrcode-image {
width: 160px;
height: 160px;
border-radius: 4px;
margin-bottom: 8px;
}
.qrcode-text {
font-size: 14px;
font-weight: bold;
color: var(--el-text-color-secondary);
margin: 0;
text-align: center;
}
}
}
}
</style>