feat(shop-dashboard): 优化系统信息展示及状态显示

- 使用骨架屏组件优化系统名称、版本号、创建时间、系统运行天数等信息加载体验
- 引入发布状态映射,使用标签显示应用运行状态,提升状态直观性
- 分离系统信息数据源,区分身份信息和时间线数据来源
- 实现系统运行天数计算,支持基于订阅起始时间动态展示
- shopOrder组件调整支付凭证图片尺寸及位置,优化界面布局
- shopDealerWithdrawEdit组件新增paymentVoucher字段,支持支付凭证信息录入
This commit is contained in:
2026-07-15 16:37:55 +08:00
parent 071a3bf110
commit 00346d96d8
3 changed files with 58 additions and 32 deletions

View File

@@ -159,16 +159,25 @@
<div style="padding: 16px 18px;"> <div style="padding: 16px 18px;">
<a-descriptions :column="1" size="small"> <a-descriptions :column="1" size="small">
<a-descriptions-item label="系统名称"> <a-descriptions-item label="系统名称">
{{ systemInfo.name }} <template v-if="subscriptionLoading">
<a-skeleton-input :active="true" size="small" style="width: 160px" />
</template>
<template v-else>{{ currentProduct?.productName || '-' }}</template>
</a-descriptions-item> </a-descriptions-item>
<a-descriptions-item label="版本号"> <a-descriptions-item label="版本号">
{{ systemInfo.version }} <template v-if="subscriptionLoading">
<a-skeleton-input :active="true" size="small" style="width: 80px" />
</template>
<template v-else>{{ currentProduct?.version || '-' }}</template>
</a-descriptions-item> </a-descriptions-item>
<a-descriptions-item label="运行状态"> <a-descriptions-item label="运行状态">
{{ siteStore.statusText || '正常' }} <a-tag :color="productStatusText.color">{{ productStatusText.text }}</a-tag>
</a-descriptions-item> </a-descriptions-item>
<a-descriptions-item label="创建时间"> <a-descriptions-item label="创建时间">
{{ tenantStore.company?.createTime || '-' }} <template v-if="subscriptionLoading">
<a-skeleton-input :active="true" size="small" style="width: 160px" />
</template>
<template v-else>{{ formatDateTime(currentSubscription?.startTime) }}</template>
</a-descriptions-item> </a-descriptions-item>
<a-descriptions-item label="到期时间"> <a-descriptions-item label="到期时间">
<template v-if="subscriptionLoading"> <template v-if="subscriptionLoading">
@@ -194,7 +203,14 @@
</template> </template>
</a-descriptions-item> </a-descriptions-item>
<a-descriptions-item label="系统运行"> <a-descriptions-item label="系统运行">
{{ runDays }} <template v-if="subscriptionLoading">
<a-skeleton-input :active="true" size="small" style="width: 60px" />
</template>
<template v-else>
<a-tooltip title="自您首次开通小程序商城起">
<span>{{ runDays }} </span>
</a-tooltip>
</template>
</a-descriptions-item> </a-descriptions-item>
</a-descriptions> </a-descriptions>
</div> </div>
@@ -323,7 +339,7 @@
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { reactive, ref, computed, onMounted, onUnmounted } from 'vue'; import { ref, computed, onMounted, onUnmounted } from 'vue';
import { useRouter } from 'vue-router'; import { useRouter } from 'vue-router';
import { useOrderNotify } from '@/views/shop/shopOrder/useOrderNotify'; import { useOrderNotify } from '@/views/shop/shopOrder/useOrderNotify';
import { import {
@@ -367,21 +383,30 @@ const router = useRouter();
const { loading: siteLoading } = storeToRefs(siteStore); const { loading: siteLoading } = storeToRefs(siteStore);
const { loading: statisticsLoading } = storeToRefs(statisticsStore); const { loading: statisticsLoading } = storeToRefs(statisticsStore);
// 系统信息
const systemInfo = reactive({
name: '小程序商城',
version: '2.0.0',
environment: '生产环境',
database: 'MySQL 8.0',
server: 'Linux CentOS 7.9',
});
// ============================================================ // ============================================================
// 应用订阅相关数据来源websopy app_subscription 表) // 基本信息:数据来源拆分
// productId 通过 当前登录用户租户ID 查询 app_product 获得 // - 身份信息(系统名称/版本号/运行状态)来自 app_product (productId=65)
// - 时间线(创建时间/到期时间/系统运行天数)来自 app_subscription
// · 创建时间 = subscription.startTime订阅生效时间
// · 到期时间 = subscription.expireTime
// · 系统运行天数 = 自 subscription.createTime 起累计
// ============================================================ // ============================================================
// 当前应用产品(按租户ID查询) // 当前应用产品(按固定 productId=65 查询)
const currentProduct = ref<AppProduct | null>(null); const currentProduct = ref<AppProduct | null>(null);
// 应用发布状态映射(运行状态)
const productStatusText = computed(() => {
const map: Record<string, { text: string; color: string }> = {
published: { text: '已发布', color: 'green' },
pending_review: { text: '审核中', color: 'orange' },
developing: { text: '开发中', color: 'blue' },
rejected: { text: '已驳回', color: 'red' },
deprecated: { text: '已下架', color: 'red' },
};
const status = currentProduct.value?.publishStatus;
if (!status) return { text: '-', color: 'default' };
return map[status] || { text: status, color: 'default' };
});
// 当前应用的有效订阅 // 当前应用的有效订阅
const currentSubscription = ref<AppSubscription | null>(null); const currentSubscription = ref<AppSubscription | null>(null);
// 订阅信息加载中 // 订阅信息加载中
@@ -595,8 +620,12 @@ const onPayModalClose = () => {
// 计算属性 // 计算属性
const now = ref(Date.now()); const now = ref(Date.now());
let runDaysTimer: ReturnType<typeof setInterval>; let runDaysTimer: ReturnType<typeof setInterval>;
// 系统运行天数:自首次开通订阅起累计
// 注意:若后端续费为新增订阅记录,此处取的是 expireTime 最新的 active 订阅,
// createTime 可能是该续费订单的创建时间runDays 会从续费日重新计数。
// 如需"累计运行天数",应改用最早的 active 订阅 createTime 或后端额外提供字段。
const runDays = computed(() => { const runDays = computed(() => {
const createTime = tenantStore.company?.createTime; const createTime = currentSubscription.value?.createTime;
if (!createTime) return 0; if (!createTime) return 0;
return Math.floor((now.value - new Date(createTime).getTime()) / (24 * 60 * 60 * 1000)); return Math.floor((now.value - new Date(createTime).getTime()) / (24 * 60 * 60 * 1000));
}); });

View File

@@ -588,6 +588,7 @@
userId: undefined, userId: undefined,
money: undefined, money: undefined,
payType: undefined, payType: undefined,
paymentVoucher: '',
wechatAccount: '', wechatAccount: '',
wechatName: '', wechatName: '',
alipayName: '', alipayName: '',

View File

@@ -202,19 +202,6 @@
</template> </template>
</a-tooltip> </a-tooltip>
</a-descriptions-item> </a-descriptions-item>
<a-descriptions-item
v-if="form.paymentVoucher"
label="支付凭证"
:span="3"
:labelStyle="{ width: '90px', color: '#808080' }"
>
<a-image
:width="120"
:src="getCompressedImageUrl(form.paymentVoucher, { width: 750 })"
:preview-src-list="[ensureFullUrl(form.paymentVoucher)]"
style="cursor: pointer"
/>
</a-descriptions-item>
<a-descriptions-item <a-descriptions-item
label="开票状态" label="开票状态"
:labelStyle="{ width: '90px', color: '#808080' }" :labelStyle="{ width: '90px', color: '#808080' }"
@@ -230,6 +217,15 @@
> >
{{ form.buyerRemarks }} {{ form.buyerRemarks }}
</a-descriptions-item> </a-descriptions-item>
<a-descriptions-item v-if="form.paymentVoucher" label="支付凭证" :labelStyle="{ width: '90px', color: '#808080' }">
<a-image
:width="70"
:src="getCompressedImageUrl(form.paymentVoucher, { width: 750 })"
:preview-src-list="[ensureFullUrl(form.paymentVoucher)]"
style="cursor: pointer"
/>
</a-descriptions-item>
<!-- <a-descriptions-item--> <!-- <a-descriptions-item-->
<!-- label="结算状态"--> <!-- label="结算状态"-->
<!-- :labelStyle="{ width: '90px', color: '#808080' }"--> <!-- :labelStyle="{ width: '90px', color: '#808080' }"-->