From 5a04e003caa2060d7f27e283e1f1651ca0d8920a Mon Sep 17 00:00:00 2001 From: 18631081161 <2088094923@qq.com> Date: Wed, 1 Apr 2026 21:26:13 +0800 Subject: [PATCH] =?UTF-8?q?=E8=81=8A=E5=A4=A9,=E9=87=91=E9=A2=9D,UI?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- admin/src/views/Certifications.vue | 11 ++- admin/src/views/ChatRecords.vue | 17 ++-- admin/src/views/Config.vue | 37 ++++++++- admin/src/views/Notifications.vue | 7 +- admin/src/views/Orders.vue | 32 ++++++-- admin/src/views/Reviews.vue | 3 +- admin/src/views/Runners.vue | 7 +- admin/src/views/Users.vue | 4 +- miniapp/manifest.json | 2 +- miniapp/pages/config/agreement.vue | 2 + miniapp/pages/delivery/delivery.vue | 2 +- miniapp/pages/food/food-order-detail.vue | 4 + miniapp/pages/food/food-order.vue | 15 ++++ miniapp/pages/help/help.vue | 4 +- miniapp/pages/message/chat.vue | 100 ++++++++++++++++++----- miniapp/pages/mine/earnings.vue | 26 +++--- miniapp/pages/order-hall/order-hall.vue | 16 ++-- miniapp/pages/order/complete-order.vue | 12 +++ miniapp/pages/order/my-orders.vue | 4 + miniapp/pages/pickup/pickup.vue | 2 +- miniapp/pages/purchase/purchase.vue | 4 +- miniapp/utils/api.js | 5 ++ miniapp/utils/im.js | 22 ++++- miniapp/utils/request.js | 4 +- server/Endpoints/AdminEndpoints.cs | 35 +++++--- server/Endpoints/ConfigEndpoints.cs | 14 +++- server/Endpoints/EarningEndpoints.cs | 11 ++- 27 files changed, 319 insertions(+), 83 deletions(-) diff --git a/admin/src/views/Certifications.vue b/admin/src/views/Certifications.vue index f6b5ec4..fa9f048 100644 --- a/admin/src/views/Certifications.vue +++ b/admin/src/views/Certifications.vue @@ -11,7 +11,9 @@ - + + + @@ -47,7 +49,12 @@ const statusFilter = ref('') const statusLabel = (s) => ({ Pending: '待审核', Approved: '已通过', Rejected: '已拒绝' }[s] || s) const statusTagType = (s) => ({ Pending: 'warning', Approved: 'success', Rejected: 'danger' }[s] || 'info') -const formatTime = (t) => t ? new Date(t).toLocaleString('zh-CN') : '' +const formatTime = (t) => { + if (!t) return '' + const d = new Date(typeof t === 'string' && !t.endsWith('Z') ? t + 'Z' : t) + const pad = n => String(n).padStart(2, '0') + return `${d.getFullYear()}-${pad(d.getMonth()+1)}-${pad(d.getDate())} ${pad(d.getHours())}:${pad(d.getMinutes())}:${pad(d.getSeconds())}` +} async function fetchList() { loading.value = true diff --git a/admin/src/views/ChatRecords.vue b/admin/src/views/ChatRecords.vue index 9d8d3ee..dd8691a 100644 --- a/admin/src/views/ChatRecords.vue +++ b/admin/src/views/ChatRecords.vue @@ -25,23 +25,23 @@ {{ statusLabel(row.status) }} - + - + @@ -109,7 +109,12 @@ const previewUrl = ref('') const typeLabel = (t) => ({ Pickup: '代取', Delivery: '代送', Help: '万能帮', Purchase: '代购', Food: '美食街' }[t] || t) const statusLabel = (s) => ({ Pending: '待接单', InProgress: '进行中', WaitConfirm: '待确认', Completed: '已完成', Cancelled: '已取消', Appealing: '申诉中' }[s] || s) const statusTagType = (s) => ({ Pending: 'info', InProgress: 'primary', WaitConfirm: 'warning', Completed: 'success', Cancelled: 'danger', Appealing: '' }[s] || 'info') -const formatTime = (t) => t ? new Date(t).toLocaleString('zh-CN') : '' +const formatTime = (t) => { + if (!t) return '' + const d = new Date(typeof t === 'string' && !t.endsWith('Z') ? t + 'Z' : t) + const pad = n => String(n).padStart(2, '0') + return `${d.getFullYear()}-${pad(d.getMonth()+1)}-${pad(d.getDate())} ${pad(d.getHours())}:${pad(d.getMinutes())}:${pad(d.getSeconds())}` +} const filteredList = computed(() => { let data = list.value @@ -178,7 +183,7 @@ function parseIMMessages(imResponse, orderInfo) { const showTime = timestamp - lastTime > 300000 let timeLabel = '' if (showTime && timestamp) { - timeLabel = new Date(timestamp).toLocaleString('zh-CN') + timeLabel = formatTime(timestamp / 1000 > 1e12 ? timestamp : timestamp * 1000) lastTime = timestamp } diff --git a/admin/src/views/Config.vue b/admin/src/views/Config.vue index 245fd59..acbc9ca 100644 --- a/admin/src/views/Config.vue +++ b/admin/src/views/Config.vue @@ -140,6 +140,22 @@ + + + + + + + + + 小程序提现页的最低提现金额,修改后提示文字自动更新 + + + 保存 + + + + @@ -201,6 +217,7 @@ const commissionRules = ref([]) const configs = reactive({ qrcode: '', agreement: '', privacy: '', runner_agreement: '', withdrawal_guide: '' }) const freezeDays = ref(1) const minCommission = ref(1.0) +const minWithdrawal = ref(1.0) // 页面顶图配置 const pageBannerList = [ @@ -260,7 +277,7 @@ async function saveConfig(key) { async function fetchFreezeDays() { try { const res = await request.get('/admin/config/freeze_days') - freezeDays.value = parseInt(res.value) || 1 + freezeDays.value = res?.value !== undefined && res.value !== '' ? parseInt(res.value) : 1 } catch { /* 忽略 */ } } @@ -291,6 +308,23 @@ async function saveMinCommission() { } } +async function fetchMinWithdrawal() { + try { + const res = await request.get('/admin/config/min_withdrawal') + if (res?.value) minWithdrawal.value = parseFloat(res.value) || 1.0 + } catch (e) {} +} + +async function saveMinWithdrawal() { + saving.value = true + try { + await request.put('/admin/config/min_withdrawal', { value: String(minWithdrawal.value) }) + ElMessage.success('最低提现金额保存成功') + } finally { + saving.value = false + } +} + async function fetchPageBanners() { for (const item of pageBannerList) { try { @@ -322,6 +356,7 @@ onMounted(async () => { fetchConfig('withdrawal_guide'), fetchFreezeDays(), fetchMinCommission(), + fetchMinWithdrawal(), fetchPageBanners() ]) }) diff --git a/admin/src/views/Notifications.vue b/admin/src/views/Notifications.vue index e2985d7..f8ac3b2 100644 --- a/admin/src/views/Notifications.vue +++ b/admin/src/views/Notifications.vue @@ -98,7 +98,12 @@ const rules = { const targetLabel = (t) => ({ All: '全部', OrderUser: '下单用户', RunnerUser: '跑腿用户', Specific: '指定用户' }[t] || t) const targetTagType = (t) => ({ All: '', OrderUser: 'success', RunnerUser: 'warning', Specific: 'info' }[t] || '') -const formatTime = (t) => t ? new Date(t).toLocaleString('zh-CN') : '' +const formatTime = (t) => { + if (!t) return '' + const d = new Date(typeof t === 'string' && !t.endsWith('Z') ? t + 'Z' : t) + const pad = n => String(n).padStart(2, '0') + return `${d.getFullYear()}-${pad(d.getMonth()+1)}-${pad(d.getDate())} ${pad(d.getHours())}:${pad(d.getMinutes())}:${pad(d.getSeconds())}` +} async function handleSubmit() { const valid = await formRef.value.validate().catch(() => false) diff --git a/admin/src/views/Orders.vue b/admin/src/views/Orders.vue index c334a06..1c6d393 100644 --- a/admin/src/views/Orders.vue +++ b/admin/src/views/Orders.vue @@ -22,7 +22,7 @@ - + @@ -31,10 +31,25 @@ {{ statusLabel(row.status) }} - - - - + + + + + + + + + + @@ -117,7 +132,12 @@ const cancelReason = ref('') const typeLabel = (t) => ({ Pickup: '代取', Delivery: '代送', Help: '万能帮', Purchase: '代购', Food: '美食街' }[t] || t) const statusLabel = (s) => ({ Pending: '待接单', InProgress: '进行中', WaitConfirm: '待确认', Completed: '已完成', Cancelled: '已取消', Appealing: '申诉中' }[s] || s) const statusTagType = (s) => ({ Pending: 'info', InProgress: 'primary', WaitConfirm: 'warning', Completed: 'success', Cancelled: 'danger', Appealing: '' }[s] || 'info') -const formatTime = (t) => t ? new Date(t).toLocaleString('zh-CN') : '' +const formatTime = (t) => { + if (!t) return '' + const d = new Date(typeof t === 'string' && !t.endsWith('Z') ? t + 'Z' : t) + const pad = n => String(n).padStart(2, '0') + return `${d.getFullYear()}-${pad(d.getMonth()+1)}-${pad(d.getDate())} ${pad(d.getHours())}:${pad(d.getMinutes())}:${pad(d.getSeconds())}` +} async function fetchList() { loading.value = true diff --git a/admin/src/views/Reviews.vue b/admin/src/views/Reviews.vue index e40d80f..f608a2c 100644 --- a/admin/src/views/Reviews.vue +++ b/admin/src/views/Reviews.vue @@ -148,7 +148,8 @@ function getScoreColor(score) { function formatTime(str) { if (!str) return '-' - const d = new Date(str) + // 确保 UTC 时间正确解析 + const d = new Date(typeof str === 'string' && !str.endsWith('Z') ? str + 'Z' : str) const pad = n => String(n).padStart(2, '0') return `${d.getFullYear()}-${pad(d.getMonth()+1)}-${pad(d.getDate())} ${pad(d.getHours())}:${pad(d.getMinutes())}` } diff --git a/admin/src/views/Runners.vue b/admin/src/views/Runners.vue index 3a38dea..5869347 100644 --- a/admin/src/views/Runners.vue +++ b/admin/src/views/Runners.vue @@ -12,7 +12,9 @@ - + + + @@ -123,7 +125,8 @@ const searchUid = ref('') const filteredList = computed(() => { if (!searchUid.value) return list.value - return list.value.filter(r => String(r.id).includes(searchUid.value.trim())) + const kw = searchUid.value.trim() + return list.value.filter(r => String(r.uid || r.id).includes(kw) || String(r.id).includes(kw)) }) const reviewDialogVisible = ref(false) const reviewLoading = ref(false) diff --git a/admin/src/views/Users.vue b/admin/src/views/Users.vue index 10778da..febd82e 100644 --- a/admin/src/views/Users.vue +++ b/admin/src/views/Users.vue @@ -20,7 +20,9 @@ - + + +