diff --git a/src/pages/products/detail.vue b/src/pages/products/detail.vue
index 48f75fa..9cf523b 100644
--- a/src/pages/products/detail.vue
+++ b/src/pages/products/detail.vue
@@ -406,6 +406,8 @@ const reportPaymentDialogVisible = ref(false)
const reportPaymentStatus = ref('pending')
const currentReportOrderId = ref('')
const checkingPaymentStatus = ref(false)
+const isCheckingWechatPayment = ref(false)
+let wechatOrderPollTimer = null
// DOM 引用
const basicInfoRef = ref(null)
@@ -462,6 +464,9 @@ onUnmounted(() => {
window.paymentCheckIntervals = {}
}
+ // 清理微信支付轮询定时器
+ stopWechatPaymentPolling()
+
// 关闭所有消息框
ElMessageBox.close()
@@ -470,6 +475,29 @@ onUnmounted(() => {
loadingInstance.close()
})
+// 重置支付状态检查
+const resetPaymentStatusCheck = () => {
+ // 停止所有定时器
+ if (window.paymentCheckIntervals) {
+ Object.keys(window.paymentCheckIntervals).forEach(orderId => {
+ clearInterval(window.paymentCheckIntervals[orderId])
+ })
+ window.paymentCheckIntervals = {}
+ }
+
+ // 停止微信支付轮询
+ stopWechatPaymentPolling()
+
+ // 重置状态
+ isCheckingWechatPayment.value = false
+ checkingPaymentStatus.value = false
+
+ // 关闭所有加载和消息框
+ ElMessageBox.close()
+ const loadingInstance = ElLoading.service()
+ loadingInstance.close()
+}
+
// 时间戳更新定时器
const timestampTimer = ref(null)
@@ -1251,6 +1279,9 @@ const showWechatPaymentQRCode = (codeUrl, orderId) => {
console.log('[showWechatPaymentQRCode] 准备显示二维码,URL:', codeUrl)
+ // 保存当前订单号用于轮询
+ currentReportOrderId.value = orderId
+
// 使用第三方二维码生成服务将微信支付URL转换为二维码图片
const qrCodeImageUrl = `https://api.qrserver.com/v1/create-qr-code/?size=200x200&data=${encodeURIComponent(codeUrl)}`
@@ -1323,8 +1354,8 @@ const showWechatPaymentQRCode = (codeUrl, orderId) => {
// 对话框被关闭(通过取消按钮或其他方式)
})
- // 不立即开始检查支付状态,等待用户确认支付后再开始
- // 这样可以避免过早开始状态检查导致用户体验不佳
+ // 开始轮询微信支付状态
+ startWechatPaymentPolling(orderId)
}
// 开始检查支付状态
@@ -1492,6 +1523,13 @@ const checkPaymentStatusManually = async () => {
// 自动下载
downloadComponentReport()
+ // 停止所有定时器
+ if (window.paymentCheckIntervals) {
+ Object.keys(window.paymentCheckIntervals).forEach(orderId => {
+ clearInterval(window.paymentCheckIntervals[orderId])
+ })
+ window.paymentCheckIntervals = {}
+ }
} else if (payment_status === 'failed') {
// 支付失败
ElMessage.error('支付失败,请重试')
diff --git a/src/views/statistics/UserStatisticsPage.vue b/src/views/statistics/UserStatisticsPage.vue
index 386fe0e..324ee29 100644
--- a/src/views/statistics/UserStatisticsPage.vue
+++ b/src/views/statistics/UserStatisticsPage.vue
@@ -54,6 +54,17 @@
完成企业认证,解锁完整数据功能
+
@@ -429,7 +440,7 @@ import { Bell, CreditCard, List, Loading, Lock, Money, Star, TrendCharts } from
import { ArrowLeftIcon as ArrowLeft, ArrowRightIcon as ArrowRight } from '@heroicons/vue/24/outline'
import * as echarts from 'echarts'
import { ElMessage } from 'element-plus'
-import { nextTick, onMounted, onUnmounted, ref } from 'vue'
+import { computed, nextTick, onMounted, onUnmounted, ref } from 'vue'
import { useRouter } from 'vue-router'
// 路由实例
@@ -468,6 +479,48 @@ const rechargeChart = ref(null)
// 图表实例存储
const chartInstances = ref([])
+// 暂停通知内容
+const lines = [
+ "因政策要求,接上级主管部门通知,从今天23:59分开始,我司现暂停部分API接口服务,恢复时间待定,请已接入上述接口的客户尽快转接至平台替代API接口,以确保业务连续性,由此给您带来的不便,我们深表歉意。",
+ "",
+ "IVYZ2B2T 能力资质核验(学历)",
+ "IVYZ5A9O 全国⾃然⼈⻛险评估评分模型",
+ "IVYZ9K2L 身份认证三要素(人脸图像版)",
+ "IVYZ81NC 单人婚姻查询(登记时间版)",
+ "IVYZ7F2A 双人婚姻状态B",
+ "IVYZ4E8B 单人婚姻状态C",
+ "QYGL8271 企业司法涉诉(详版)",
+ "FLXG0V4B 个人司法涉诉",
+ "FLXG162A 团伙欺诈评估",
+ "FLXGC9D1 黑灰产等级",
+ "JRZQ4AA8 偿债压力指数",
+ "JRZQ8203 借贷行为验证",
+ "JRZQ0A03 借贷意向验证",
+ "YYSYD50F 二要素核验(手机号、身份证号)",
+ "YYSY09CD 运营商三要素验证(简版)",
+ "YYSY6F2E 运营商三要素核验(高级版)",
+ "QYGL45BD 企业法人四要素核验",
+ "QYGL2ACD 企业三要素核验",
+ "IVYZ9363 双人婚姻状态A",
+ "QYGL8261 企业综合涉诉",
+ "FLXGCA3D 个人综合涉诉",
+ "IVYZ0B03 二要素验证(姓名、手机号)",
+ "IVYZ5733 单人婚姻状态A",
+ "FLXG3D56 特殊名单验证"
+ ];
+
+// 通知滚动相关
+const scrollDuration = ref('60s') // 滚动动画持续时间,延长以便用户看清内容
+const allDisplayLines = computed(() => {
+ // 过滤掉空行,保留所有有效内容
+ const validLines = lines.filter(line => line.trim() !== '')
+
+ // 为了创建无缝滚动效果,重复数组内容
+ return [...validLines, ' ● ', ...validLines]
+})
+
+// 缓存格式化函数结果 - 使用WeakMap提升性能
+
// 缓存格式化函数结果 - 使用WeakMap提升性能
const formatCache = new Map()
@@ -1243,6 +1296,7 @@ onMounted(() => {
loadAnnouncements()
// 添加窗口大小变化监听
window.addEventListener('resize', handleResize, { passive: true })
+ // 滚动动画由CSS控制,无需JavaScript启动
})
// 组件卸载时清理
@@ -1262,6 +1316,8 @@ onUnmounted(() => {
}
})
chartInstances.value = []
+
+ // 滚动动画使用CSS实现,无需清理定时器
// 清理缓存
formatCache.clear()
@@ -1375,4 +1431,77 @@ onUnmounted(() => {
background-color: #f9fafb;
font-weight: 600;
}
+
+.notification-area {
+ width: 800px;
+ margin: 10px 0;
+ padding: 15px;
+ border: 1px solid #f0ad4e;
+ border-radius: 8px;
+ background-color: #fff8e1;
+ font-family: Arial, sans-serif;
+ line-height: 1.8;
+ overflow: hidden;
+ white-space: nowrap;
+ }
+
+ .notification-scroll-container {
+ width: 100%;
+ overflow: hidden;
+ position: relative;
+ }
+
+ .notification-scroll {
+ display: inline-block;
+ padding-right: 50px; /* 防止文字紧贴边缘 */
+ white-space: nowrap;
+ animation: marquee linear infinite;
+ width: 200%; /* 确保有足够的空间实现无缝滚动 */
+ }
+
+ @keyframes marquee {
+ 0% {
+ transform: translateX(0);
+ }
+ 100% {
+ transform: translateX(-500%);
+ }
+ }
+
+ .notification-item {
+ margin-right: 20px;
+ display: inline-block;
+ }
+
+ .separator {
+ color: #d9534f;
+ font-weight: bold;
+ }
+ .api-item {
+ color: #d9534f;
+ font-weight: bold;
+ margin: 3px 0;
+ padding-left: 10px;
+ }
+ .notification-content::-webkit-scrollbar {
+ width: 4px;
+ }
+ .notification-content::-webkit-scrollbar-track {
+ background: #fff8e1;
+ }
+ .notification-content::-webkit-scrollbar-thumb {
+ background: #f0ad4e;
+ border-radius: 2px;
+ }
+ .api-item {
+ color: #d9534f;
+ font-weight: bold;
+ margin: 3px 0;
+ }
+ .header {
+ font-weight: bold;
+ color: #333;
+ margin-bottom: 15px;
+ }
+