feat(appSubscription): 新增应用订阅模块及商城欢迎横幅Logo支持

- 新增 useAppSubscriptionStore,封装 websopy 特殊接口的应用订阅功能
- 实现订阅列表分页查询、详情获取、支付状态查询、订阅管理等接口调用
- 适配不同支付方式,支持余额支付、微信支付及小程序支付预支付流程
- 在商城 Dashboard 欢迎横幅左侧新增商城 Logo 显示,读取商城设置的 shopLogo 字段
- 使用图像压缩接口处理 Logo 大小和质量,优化加载体验
- 优化 Dashboard 待处理事项展示,恢复退款和优惠券使用项
- 统一订阅接口调用地址为独立域名,复用请求工具共享认证和错误处理
This commit is contained in:
2026-07-15 12:49:05 +08:00
parent e2dd8dbc18
commit 9e65007e65
5 changed files with 909 additions and 6 deletions

View File

@@ -2,9 +2,18 @@
<div class="shop-dashboard">
<!-- 欢迎横幅 -->
<div class="welcome-banner">
<div class="welcome-left">
<h2 class="welcome-title">🏸 {{ userStore.info?.tenantName }}</h2>
<p class="welcome-sub">欢迎回来管理员今日数据已更新</p>
<div class="welcome-left flex flex-row gap-2 items-center">
<a-avatar
v-if="shopLogoUrl"
:src="shopLogoUrl"
:size="64"
shape="square"
class="welcome-logo"
/>
<div>
<h2 class="welcome-title">{{ userStore.info?.tenantName }}</h2>
<p class="welcome-sub">欢迎回来管理员今日数据已更新</p>
</div>
</div>
<div class="welcome-right">
<div class="welcome-actions">
@@ -159,7 +168,7 @@
{{ tenantStore.company?.createTime || '-' }}
</a-descriptions-item>
<a-descriptions-item label="到期时间">
{{ siteInfo?.expirationTime }}
{{ siteInfo?.expirationTime || '-' }}
</a-descriptions-item>
<a-descriptions-item label="系统运行">
{{ runDays }}
@@ -239,6 +248,8 @@ import { useStatisticsStore } from '@/store/modules/statistics';
import { useUserStore } from '@/store/modules/user';
import { useTenantStore } from '@/store/modules/tenant';
import { pageShopOrder } from '@/api/shop/shopOrder';
import { getShopSettingCategoryValues } from '@/api/shop/shopSetting';
import { getCompressedImageUrl } from '@/utils/image';
import { storeToRefs } from 'pinia';
import { removeSiteInfoCache } from '@/api/cms/cmsWebsite';
@@ -294,12 +305,18 @@ const pendingShipmentCount = ref(0);
const pendingRefundCount = ref(0);
const couponUsedCount = computed(() => statisticsStore.safeCouponUsedCount);
// 商城Logo
const shopLogo = ref('');
const shopLogoUrl = computed(() =>
shopLogo.value ? getCompressedImageUrl(shopLogo.value, { width: 200, quality: 90 }) : ''
);
// 待处理事项使用computed确保响应式更新
const todoItems = computed(() => [
{ label: '待付款订单', value: pendingPaymentCount.value, to: '/shop/shopOrder?tab=unpaid', tagColor: 'gold', dotColor: 'dot-gold', urgent: pendingPaymentCount.value > 0 },
{ label: '待发货订单', value: pendingShipmentCount.value, to: '/shop/shopOrder?tab=undelivered', tagColor: 'blue', dotColor: 'dot-blue', urgent: pendingShipmentCount.value > 0 },
// { label: '退款申请', value: pendingRefundCount.value, to: '/shop/shopOrder?tab=refunded', tagColor: 'orange', dotColor: 'dot-orange', urgent: pendingRefundCount.value > 0 },
// { label: '优惠券使用', value: couponUsedCount.value, to: '/market/coupon', tagColor: 'cyan', dotColor: 'dot-cyan', urgent: false },
{ label: '退款申请', value: pendingRefundCount.value, to: '/shop/shopOrder?tab=refunded', tagColor: 'orange', dotColor: 'dot-orange', urgent: pendingRefundCount.value > 0 },
{ label: '优惠券使用', value: couponUsedCount.value, to: '/market/coupon', tagColor: 'cyan', dotColor: 'dot-cyan', urgent: false },
]);
// 今日统计使用computed确保响应式更新
@@ -367,6 +384,15 @@ const loadData = async () => {
console.warn('获取租户信息失败:', e);
});
// 独立请求商城Logo不受其他请求失败影响
getShopSettingCategoryValues('basic')
.then((values) => {
shopLogo.value = values?.shopLogo || '';
})
.catch((e) => {
console.warn('获取商城设置失败:', e);
});
try {
await Promise.all([
siteStore.fetchSiteInfo(),
@@ -458,6 +484,11 @@ onUnmounted(() => {
flex-wrap: wrap;
gap: 12px;
}
.welcome-logo {
flex-shrink: 0;
border: 2px solid rgba(255,255,255,0.2);
background: rgba(255,255,255,0.1);
}
.welcome-title { font-size: 20px; font-weight: 700; color: #fff; margin: 0 0 6px; }
.welcome-sub { font-size: 14px; color: rgba(255,255,255,0.7); margin: 0; }