From d941a16d28dd20ff0ab32665557647a6803d41e1 Mon Sep 17 00:00:00 2001 From: xcbyy <2578898740@qq.com> Date: Thu, 22 Oct 2026 09:25:27 +0800 Subject: [PATCH] =?UTF-8?q?fix(miniapp):=20=E6=B8=85=E7=90=86=E5=89=A9?= =?UTF-8?q?=E4=BD=99=E8=BA=AB=E4=BB=BD=E5=85=9C=E5=BA=95=E5=B9=B6=E4=BF=AE?= =?UTF-8?q?=E6=AD=A3=E5=BE=85=E6=8E=A5=E5=8D=95=E7=8A=B6=E6=80=81/?= =?UTF-8?q?=E5=AE=A2=E6=9C=8D=E5=85=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 修复 user/index 使用 normalizeUserId 未导入(分享按钮会报错) - 待接单独立为 PENDING_ACCEPT:新增待接单 tab/状态色/取消订单与联系客服操作,不再显示为进行中 - 移除 hall/bill-records/reports/settings/favorites/order-create/activity-create/activity-detail/apply 的 1001/2006 身份兜底 - 线下订单(含指定大神)必须填写碰面地点;再次预约不再兜底到 101 号大神;评价不预选标签 - 接单大厅去掉「已实名认证/信誉积分100」等伪造信任文案;客服按钮统一为「联系客服」 - 114 套件/745 用例全绿 --- pwuniapp/common/api.js | 2 +- pwuniapp/pages/activity/create.vue | 4 ++-- pwuniapp/pages/activity/detail.vue | 6 +++++- pwuniapp/pages/community/detail.vue | 13 ++++++------ pwuniapp/pages/community/index.vue | 8 ++++---- pwuniapp/pages/expert/apply.vue | 5 +++-- pwuniapp/pages/expert/hall.vue | 22 +++++++++++++------- pwuniapp/pages/expert/workspace.vue | 2 +- pwuniapp/pages/order/create.vue | 8 ++++++-- pwuniapp/pages/order/list.vue | 26 +++++++++++++++++++----- pwuniapp/pages/user/bill-records.vue | 4 ++-- pwuniapp/pages/user/favorites.vue | 6 +++--- pwuniapp/pages/user/index.vue | 12 +++++------ pwuniapp/pages/user/reports.vue | 4 ++-- pwuniapp/pages/user/settings.vue | 4 ++-- server/tests/order-chat-realtime.spec.ts | 19 +++++++++++++++++ 16 files changed, 99 insertions(+), 46 deletions(-) diff --git a/pwuniapp/common/api.js b/pwuniapp/common/api.js index fbba9df..b35fd7e 100644 --- a/pwuniapp/common/api.js +++ b/pwuniapp/common/api.js @@ -251,8 +251,8 @@ export function formatOrderData(raw) { let statusKey = raw.status || 'IN_SERVICE'; if (statusKey === '待支付' || statusKey === '待付款') statusKey = 'PENDING_PAY'; + else if (statusKey === '待接单') statusKey = 'PENDING_ACCEPT'; else if ( - statusKey === '待接单' || statusKey === '已接单' || statusKey === '已到场核销' || statusKey === '履约中' || diff --git a/pwuniapp/pages/activity/create.vue b/pwuniapp/pages/activity/create.vue index a96de57..08c5141 100644 --- a/pwuniapp/pages/activity/create.vue +++ b/pwuniapp/pages/activity/create.vue @@ -658,7 +658,7 @@ const submitDispatch = async (title, startTime, location) => { latitude: form.value.latitude, longitude: form.value.longitude, expenseBurden: 'AA制各自付', - remark: title, + remark: startTime ? `${title}|期望:${startTime}` : title, }); } catch (err) { uni.hideLoading(); @@ -765,7 +765,7 @@ const handleSubmit = async () => { uni.showToast({ title: '账号已被封禁,无法发起组局', icon: 'none' }); return; } - const currentUserId = Number(uni.getStorageSync('userId')) || Number(cachedUser.id) || 1001; + const currentUserId = normalizeUserId(); const newActivityPayload = { creatorId: currentUserId, game: form.value.game, diff --git a/pwuniapp/pages/activity/detail.vue b/pwuniapp/pages/activity/detail.vue index f1da63c..906fe40 100644 --- a/pwuniapp/pages/activity/detail.vue +++ b/pwuniapp/pages/activity/detail.vue @@ -691,7 +691,11 @@ const copyLocation = () => { }; const openHostProfile = () => { - const hostId = activity.value.creatorId || 1001; + const hostId = Number(activity.value.creatorId) || 0; + if (!hostId) { + uni.showToast({ title: '发起人信息不完整', icon: 'none' }); + return; + } const hostName = activity.value.creatorNickname || '同城用户'; const hostAvatar = activity.value.creatorAvatar || 'https://images.unsplash.com/photo-1534528741775-53994a69daeb?w=150'; const hostSnapshot = { diff --git a/pwuniapp/pages/community/detail.vue b/pwuniapp/pages/community/detail.vue index 7959318..9773fd4 100644 --- a/pwuniapp/pages/community/detail.vue +++ b/pwuniapp/pages/community/detail.vue @@ -182,7 +182,8 @@ import { applyPostParty, getPostApplies, handlePostApply, - getUserProfile + getUserProfile, + normalizeUserId } from '@/common/api.js'; const DEFAULT_USER_AVATAR = 'https://images.unsplash.com/photo-1535713875002-d1d0cf377fde?w=120'; @@ -199,7 +200,7 @@ const currentUserProfile = ref({}); const readCachedUserInfo = () => { const pwInfo = uni.getStorageSync('PW_USER_INFO') || {}; const uInfo = uni.getStorageSync('userInfo') || {}; - const uid = Number(uni.getStorageSync('userId')) || Number(pwInfo.id) || Number(uInfo.id) || 1001; + const uid = normalizeUserId(); const rawName = pwInfo.nickname || uInfo.nickname || ''; const nickname = (rawName && !['点击登录 / 注册', '电竞玩家 (我)'].includes(rawName)) ? rawName : ''; const avatar = pwInfo.avatar || uInfo.avatar || ''; @@ -239,7 +240,7 @@ const normalizeCommentItem = (item) => { if (!item) return item; const cur = currentUserProfile.value.nickname ? currentUserProfile.value : readCachedUserInfo(); const isMyComment = - (item.userId && Number(item.userId) === Number(cur.id || 1001)) || + (item.userId && Number(item.userId) === Number(cur.id || 0)) || item.author === '电竞玩家 (我)'; return { ...item, @@ -275,7 +276,7 @@ const getPostCategoryName = (catKey) => { const isPostOwner = (target) => { const cur = currentUserProfile.value.nickname ? currentUserProfile.value : readCachedUserInfo(); return target && ( - Number(target.userId) === Number(cur.id || 1001) || + Number(target.userId) === Number(cur.id || 0) || target.author === '电竞玩家 (我)' || (cur.nickname && target.author === cur.nickname) || target.isMine === true @@ -466,7 +467,7 @@ const sendComment = async () => { const profile = currentUserProfile.value.nickname ? currentUserProfile.value : await syncCurrentUserProfile(); - const uid = Number(profile.id || uni.getStorageSync('userId')) || 1001; + const uid = normalizeUserId(); const authorName = profile.nickname || '同城用户'; const authorAvatar = profile.avatar || DEFAULT_USER_AVATAR; @@ -522,7 +523,7 @@ const handleJoinParty = () => { const profile = currentUserProfile.value.nickname ? currentUserProfile.value : await syncCurrentUserProfile(); - const uid = Number(profile.id || uni.getStorageSync('userId')) || 1001; + const uid = normalizeUserId(); const applicantName = profile.nickname || '同城用户'; const applicantAvatar = profile.avatar || DEFAULT_USER_AVATAR; try { diff --git a/pwuniapp/pages/community/index.vue b/pwuniapp/pages/community/index.vue index af30561..f5f3819 100644 --- a/pwuniapp/pages/community/index.vue +++ b/pwuniapp/pages/community/index.vue @@ -414,7 +414,7 @@ const currentUserProfile = ref({}); const readCachedUserInfo = () => { const pwInfo = uni.getStorageSync('PW_USER_INFO') || {}; const uInfo = uni.getStorageSync('userInfo') || {}; - const uid = Number(uni.getStorageSync('userId')) || Number(pwInfo.id) || Number(uInfo.id) || 1001; + const uid = normalizeUserId(); const rawName = pwInfo.nickname || uInfo.nickname || ''; const nickname = (rawName && !['点击登录 / 注册', '电竞玩家 (我)'].includes(rawName)) ? rawName : ''; const avatar = pwInfo.avatar || uInfo.avatar || ''; @@ -788,7 +788,7 @@ const sendComment = async () => { const profile = currentUserProfile.value.nickname ? currentUserProfile.value : await syncCurrentUserProfile(); - const uid = Number(profile.id || uni.getStorageSync('userId')) || 1001; + const uid = normalizeUserId(); const authorName = profile.nickname || '同城用户'; const authorAvatar = profile.avatar || DEFAULT_USER_AVATAR; @@ -824,7 +824,7 @@ const sendComment = async () => { const isPostOwner = (post) => { const cur = currentUserProfile.value.nickname ? currentUserProfile.value : readCachedUserInfo(); return post && ( - Number(post.userId) === Number(cur.id || 1001) || + Number(post.userId) === Number(cur.id || 0) || post.author === '电竞玩家 (我)' || (cur.nickname && post.author === cur.nickname) || post.isMine === true @@ -932,7 +932,7 @@ const handleJoinParty = (post) => { const profile = currentUserProfile.value.nickname ? currentUserProfile.value : await syncCurrentUserProfile(); - const uid = Number(profile.id || uni.getStorageSync('userId')) || 1001; + const uid = normalizeUserId(); const applicantName = profile.nickname || '同城用户'; const applicantAvatar = profile.avatar || DEFAULT_USER_AVATAR; try { diff --git a/pwuniapp/pages/expert/apply.vue b/pwuniapp/pages/expert/apply.vue index 40832bf..6c41ce6 100644 --- a/pwuniapp/pages/expert/apply.vue +++ b/pwuniapp/pages/expert/apply.vue @@ -454,7 +454,7 @@ const submitApply = async () => { uni.showLoading({ title: '正在提交入驻材料...' }); // 身份与登录态保持一致:有 token 时由服务端按 token 识别(缺失 userId 传 0) const uid = normalizeUserId(); - const profileUid = uid || 1001; + const profileUid = uid; try { let avatarUrl = ''; @@ -555,7 +555,8 @@ const rejectReason = ref(''); const syncRemoteCertStatus = async () => { try { const cachedUser = uni.getStorageSync('PW_USER_INFO') || {}; - const uid = Number(cachedUser.id) || 1001; + const uid = normalizeUserId(); + if (!uid) return; const profile = await getUserProfile(uid); if (profile && profile.certStatus !== undefined) { const remoteCert = Number(profile.certStatus); diff --git a/pwuniapp/pages/expert/hall.vue b/pwuniapp/pages/expert/hall.vue index aa4d8ae..776733c 100644 --- a/pwuniapp/pages/expert/hall.vue +++ b/pwuniapp/pages/expert/hall.vue @@ -218,9 +218,9 @@ {{ selectedOrder.userName }} - 已实名认证买家 + 平台注册买家 - 信誉积分 100 · 资金全额托管 + 资金由平台担保托管 @@ -251,7 +251,7 @@ import AppTabBar from '@/components/CustomTabBar.vue'; import { ICONS } from '@/common/icons.js'; import { getCurrentThemeKey, applyThemeToNativeUI } from '@/common/theme.js'; import { isExpertCertified } from '@/common/role.js'; -import { claimOrder, getOrdersPool, getExpertStats, updateCompanionProfile, getUserProfile, getActivities } from '@/common/api.js'; +import { claimOrder, getOrdersPool, getExpertStats, updateCompanionProfile, getUserProfile, getActivities, normalizeUserId } from '@/common/api.js'; import { getUserLocation } from '@/common/location.js'; import { getNavBarInfo } from '@/common/nav.js'; @@ -316,8 +316,11 @@ let isHallLoading = false; const loadHallData = async () => { if (isHallLoading) return; isHallLoading = true; - let uid = uni.getStorageSync('userId') || expert.value.id || 2006; - if (uid == 101) uid = 2006; + let uid = normalizeUserId(); + if (!uid) { + isHallLoading = false; + return; + } expert.value.id = uid; // 1. 同步最新在线接单状态 @@ -469,8 +472,13 @@ const filteredOrders = computed(() => { const toggleOnlineStatus = async () => { isOnline.value = !isOnline.value; uni.setStorageSync('EXPERT_RECEIVING_STATUS', isOnline.value ? '1' : '0'); + const eid = Number(expert.value.id) || normalizeUserId(); + if (!eid) { + uni.showToast({ title: '请先登录后再操作', icon: 'none' }); + return; + } try { - await updateCompanionProfile(expert.value.id || 2006, { + await updateCompanionProfile(eid, { status: isOnline.value ? '接单中' : '休息中' }); } catch (_) {} @@ -493,7 +501,7 @@ const handleGrabOrder = (order) => { uni.showLoading({ title: '正在锁定订单...' }); try { await claimOrder(order.id, { - expertId: expert.value.id || 2006, + expertId: expert.value.id || 0, companionName: expert.value.nickname || '接单大神', expertAvatar: expert.value.avatar || DEFAULT_EXPERT_AVATAR }); diff --git a/pwuniapp/pages/expert/workspace.vue b/pwuniapp/pages/expert/workspace.vue index aa88a7b..66de315 100644 --- a/pwuniapp/pages/expert/workspace.vue +++ b/pwuniapp/pages/expert/workspace.vue @@ -360,7 +360,7 @@ 状态:{{ order.statusText }} - + diff --git a/pwuniapp/pages/order/create.vue b/pwuniapp/pages/order/create.vue index 5c9f756..71ab081 100644 --- a/pwuniapp/pages/order/create.vue +++ b/pwuniapp/pages/order/create.vue @@ -285,7 +285,7 @@ import { getCurrentThemeKey, applyThemeToNativeUI } from '@/common/theme.js'; import { ensureLoginOrRedirect } from '@/common/role.js'; const currentThemeKey = ref(getCurrentThemeKey()); -const currentUserId = ref(Number(uni.getStorageSync('userId') || 1001)); +const currentUserId = ref(normalizeUserId()); const currentUserName = ref((uni.getStorageSync('userInfo') && uni.getStorageSync('userInfo').nickname) || '同城用户'); const userBalance = ref('0.00'); const payMethod = ref('WECHAT'); // 'WECHAT' | 'BALANCE' @@ -324,7 +324,7 @@ const stopPropagation = (e) => { const loadUserWallet = async () => { try { - const uid = Number(uni.getStorageSync('userId') || 1001); + const uid = normalizeUserId(); currentUserId.value = uid; const cachedInfo = uni.getStorageSync('userInfo'); if (cachedInfo && cachedInfo.nickname) { @@ -567,6 +567,10 @@ const handlePay = async () => { uni.showToast({ title: '该大神暂未配置服务包,无法下单', icon: 'none' }); return; } + if (isOffline.value && !String(meetVenue.value || '').trim()) { + uni.showToast({ title: '请填写或选择碰面地点', icon: 'none' }); + return; + } // 平台派单校验:品类预算与碰面地点 if (isPlatformMode.value) { if (!(Number(platformBudget.value) > 0)) { diff --git a/pwuniapp/pages/order/list.vue b/pwuniapp/pages/order/list.vue index 694d1f6..cd14a40 100644 --- a/pwuniapp/pages/order/list.vue +++ b/pwuniapp/pages/order/list.vue @@ -86,14 +86,19 @@ + +