完成距离预校验
This commit is contained in:
@@ -45,7 +45,8 @@ import { onLoad } from '@dcloudio/uni-app'
|
||||
import ServicePageScaffold from '@/components/homeService/ServicePageScaffold.uvue'
|
||||
import ServicePanel from '@/components/homeService/ServicePanel.uvue'
|
||||
import type { DeliveryLocationType, DeliveryOrderType } from '@/types/delivery.uts'
|
||||
import { checkinOrder, getDeliveryOrderDetail } from '@/services/deliveryService.uts'
|
||||
import supa from '@/components/supadb/aksupainstance.uts'
|
||||
import { getDeliveryOrderDetail } from '@/services/deliveryService.uts'
|
||||
import { requireDeliveryAuth } from '@/utils/deliveryAuth.uts'
|
||||
import { getCurrentUserId } from '@/utils/store.uts'
|
||||
import { getDeliveryRouteParam } from '@/utils/deliveryRoute.uts'
|
||||
@@ -54,7 +55,7 @@ import {
|
||||
checkinPrecheck,
|
||||
getReasonText
|
||||
} from '@/utils/homecareAuth.uts'
|
||||
import { debugCurrentUser } from '@/utils/akUserMapping.uts'
|
||||
import { debugCurrentUser, getCurrentAkUserId } from '@/utils/akUserMapping.uts'
|
||||
|
||||
const orderId = ref('')
|
||||
const order = ref<DeliveryOrderType | null>(null)
|
||||
@@ -62,6 +63,7 @@ const currentLocation = ref<DeliveryLocationType | null>(null)
|
||||
const locationText = ref('未获取')
|
||||
const accuracyText = ref('未知')
|
||||
const photos = ref([] as Array<string>)
|
||||
const evidenceFileIds = ref([] as Array<string>)
|
||||
const note = ref('')
|
||||
const submitting = ref(false)
|
||||
|
||||
@@ -77,19 +79,29 @@ const allowedRadiusText = ref('未校验')
|
||||
const precheckStatusText = ref('未校验')
|
||||
const reasonText = ref('')
|
||||
|
||||
function updateHomecareLoginStatus(): void {
|
||||
console.warn('[CHECKIN DEBUG] updateHomecareLoginStatus: called')
|
||||
// 改用 Supabase 当前用户判断是否已登录(homecare 专属 token 已废弃,从未被写入)
|
||||
const userId = getCurrentUserId()
|
||||
console.warn('[CHECKIN DEBUG] updateHomecareLoginStatus: token length:', userId.length)
|
||||
if (userId !== '') {
|
||||
async function updateHomecareLoginStatus(): Promise<void> {
|
||||
console.warn('[CHECKIN AUTH] ========== 登录状态检查 START ==========')
|
||||
|
||||
// 打印认证相关日志
|
||||
const authUserId = getCurrentUserId()
|
||||
const akUserId = await getCurrentAkUserId()
|
||||
const storageAkUserId = uni.getStorageSync('ak_user_id')
|
||||
const storageCurrentAkUser = uni.getStorageSync('current_ak_user')
|
||||
|
||||
console.warn('[CHECKIN AUTH] getCurrentUserId =', authUserId)
|
||||
console.warn('[CHECKIN AUTH] getCurrentAkUserId =', akUserId)
|
||||
console.warn('[CHECKIN AUTH] storage ak_user_id =', storageAkUserId)
|
||||
console.warn('[CHECKIN AUTH] current_ak_user =', storageCurrentAkUser)
|
||||
console.warn('[CHECKIN AUTH] ========== 登录状态检查 END ==========')
|
||||
|
||||
if (akUserId !== '') {
|
||||
isHomecareLoggedIn.value = true
|
||||
homecareUserEmail.value = '已登录 (uid: ' + userId.substring(0, 8) + '...)'
|
||||
console.warn('[CHECKIN DEBUG] updateHomecareLoginStatus: logged in as', homecareUserEmail.value)
|
||||
homecareUserEmail.value = '已登录 (uid: ' + akUserId.substring(0, 8) + '...)'
|
||||
console.warn('[CHECKIN AUTH] 居家服务认证通过')
|
||||
} else {
|
||||
isHomecareLoggedIn.value = false
|
||||
homecareUserEmail.value = ''
|
||||
console.warn('[CHECKIN DEBUG] updateHomecareLoginStatus: not logged in')
|
||||
console.warn('[CHECKIN AUTH] 居家服务认证失败:akUserId 为空')
|
||||
}
|
||||
}
|
||||
|
||||
@@ -239,6 +251,72 @@ async function choosePhoto() {
|
||||
try {
|
||||
const selected = await wrapChooseImage()
|
||||
photos.value = selected
|
||||
|
||||
// 上传现场图片并创建 hc_evidence_files 记录
|
||||
if (selected.length > 0 && orderId.value != '') {
|
||||
const akUserId = await getCurrentAkUserId()
|
||||
console.warn('[CHOOSE PHOTO] akUserId:', akUserId)
|
||||
|
||||
if (akUserId == '') {
|
||||
uni.showToast({ title: '未获取到业务用户 ID', icon: 'none' })
|
||||
return
|
||||
}
|
||||
|
||||
// 上传每张照片
|
||||
for (let i = 0; i < selected.length; i++) {
|
||||
const tempPath = selected[i]
|
||||
try {
|
||||
// 上传到 Supabase Storage
|
||||
const { data: uploadData, error: uploadError } = await supa.storage
|
||||
.from('evidence')
|
||||
.upload('checkin/' + orderId.value + '/' + Date.now() + '_' + i + '.jpg', {
|
||||
base64: tempPath,
|
||||
contentType: 'image/jpeg'
|
||||
})
|
||||
|
||||
if (uploadError == null && uploadData != null) {
|
||||
// 获取公开 URL
|
||||
const { data: urlData } = supa.storage
|
||||
.from('evidence')
|
||||
.getPublicUrl(uploadData.path)
|
||||
|
||||
if (urlData != null) {
|
||||
const fileUrl = urlData.publicUrl
|
||||
|
||||
// 创建 hc_evidence_files 记录
|
||||
const { data: evidenceRecord, error: evidenceError } = await supa
|
||||
.from('hc_evidence_files')
|
||||
.insert({
|
||||
work_order_id: orderId.value,
|
||||
uploader_id: akUserId,
|
||||
file_url: fileUrl,
|
||||
upload_status: 'UPLOADED',
|
||||
file_type: 'image',
|
||||
created_at: new Date().toISOString()
|
||||
})
|
||||
.select('id')
|
||||
.single()
|
||||
|
||||
if (evidenceError == null && evidenceRecord != null) {
|
||||
const evidenceId = evidenceRecord.getString('id') ?? ''
|
||||
if (evidenceId != '') {
|
||||
evidenceFileIds.value.push(evidenceId)
|
||||
console.warn('[CHOOSE PHOTO] 证据记录创建成功, evidenceId:', evidenceId)
|
||||
}
|
||||
} else {
|
||||
console.warn('[CHOOSE PHOTO] 证据记录创建失败:', evidenceError)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
console.warn('[CHOOSE PHOTO] 图片上传失败:', uploadError)
|
||||
}
|
||||
} catch (uploadErr) {
|
||||
console.warn('[CHOOSE PHOTO] 上传异常:', uploadErr)
|
||||
}
|
||||
}
|
||||
|
||||
console.warn('[CHOOSE PHOTO] 当前 evidenceFileIds:', evidenceFileIds.value)
|
||||
}
|
||||
} catch (error) {
|
||||
uni.showToast({ title: '拍照失败,请重试', icon: 'none' })
|
||||
}
|
||||
@@ -259,6 +337,39 @@ async function handlePrecheck(): Promise<void> {
|
||||
return
|
||||
}
|
||||
|
||||
// 预校验前打印认证日志
|
||||
const authUserId = getCurrentUserId()
|
||||
let akUserId = await getCurrentAkUserId()
|
||||
const storageAkUserId = uni.getStorageSync('ak_user_id')
|
||||
const storageCurrentAkUser = uni.getStorageSync('current_ak_user')
|
||||
|
||||
console.warn('[CHECKIN AUTH] getCurrentUserId =', authUserId)
|
||||
console.warn('[CHECKIN AUTH] getCurrentAkUserId =', akUserId)
|
||||
console.warn('[CHECKIN AUTH] storage ak_user_id =', storageAkUserId)
|
||||
console.warn('[CHECKIN AUTH] current_ak_user =', storageCurrentAkUser)
|
||||
|
||||
// 兜底逻辑:如果 akUserId 为空但 authUserId 非空,尝试写入缓存
|
||||
if ((akUserId == '' || akUserId == null) && authUserId != null && String(authUserId).length > 0) {
|
||||
console.warn('[CHECKIN AUTH] 兜底:akUserId 为空但 authUserId 非空,尝试写入缓存')
|
||||
console.warn('[CHECKIN AUTH] authUserId =', authUserId)
|
||||
|
||||
// 直接写入 authUserId 作为 ak_user_id
|
||||
uni.setStorageSync('ak_user_id', authUserId)
|
||||
uni.setStorageSync('current_ak_user', JSON.stringify({ id: authUserId }))
|
||||
console.warn('[CHECKIN AUTH] 已写入缓存: ak_user_id =', authUserId)
|
||||
|
||||
// 重新读取
|
||||
akUserId = await getCurrentAkUserId()
|
||||
console.warn('[CHECKIN AUTH] 重新读取 akUserId =', akUserId)
|
||||
}
|
||||
|
||||
// 如果 akUserId 仍然为空,提示重新登录
|
||||
if (akUserId == '' || akUserId == null) {
|
||||
uni.showToast({ title: '业务账号未初始化,请重新登录', icon: 'none' })
|
||||
console.warn('[CHECKIN AUTH] akUserId 仍为空,阻止预校验')
|
||||
return
|
||||
}
|
||||
|
||||
console.warn('[CHECKIN PAGE] 开始预校验流程')
|
||||
|
||||
// 调试:打印当前 ak_user 信息
|
||||
@@ -356,31 +467,41 @@ async function submitCheckin() {
|
||||
return
|
||||
}
|
||||
|
||||
// RPC 预校验已经做了距离判断,这里直接提交
|
||||
// 保留坐标检查作为兜底,防止跳过预校验直接提交
|
||||
if (order.value.latitude == 0 && order.value.longitude == 0) {
|
||||
console.warn('[CHECKIN DEBUG] submitCheckin: order has no valid coordinates (lat=0, lng=0)')
|
||||
uni.showToast({ title: '订单缺少服务地址坐标', icon: 'none' })
|
||||
return
|
||||
}
|
||||
// 服务坐标以后端 precheck 返回为准,不再以前端 order.latitude/order.longitude 为准
|
||||
// 删除了之前的坐标检查
|
||||
|
||||
const distance = calculateDistance(currentLocation.value.latitude, currentLocation.value.longitude, order.value.latitude, order.value.longitude)
|
||||
console.warn('[CHECKIN DEBUG] submitCheckin: calculated distance:', distance, 'meters, allowedRadius:', order.value.allowCheckinRadiusMeters)
|
||||
|
||||
console.warn('[CHECKIN DEBUG] submitCheckin: proceeding with checkin, photos count:', photos.value.length)
|
||||
console.warn('[CHECKIN DEBUG] submitCheckin: proceeding with checkin, photos count:', photos.value.length, ' evidenceFileIds:', evidenceFileIds.value)
|
||||
doCheckin()
|
||||
}
|
||||
|
||||
async function doCheckin() {
|
||||
submitting.value = true
|
||||
try {
|
||||
await checkinOrder(orderId.value, {
|
||||
location: currentLocation.value as DeliveryLocationType,
|
||||
note: note.value,
|
||||
photos: photos.value,
|
||||
checkinMode: 'gps'
|
||||
})
|
||||
console.warn('[CHECKIN DEBUG] submitCheckin: checkinOrder succeeded')
|
||||
// 获取 akUserId
|
||||
const akUserId = await getCurrentAkUserId()
|
||||
console.warn('[CHECKIN RPC] akUserId:', akUserId)
|
||||
|
||||
if (akUserId == '') {
|
||||
uni.showToast({ title: '未获取到业务用户 ID,请重新登录', icon: 'none' })
|
||||
return
|
||||
}
|
||||
|
||||
// 调用居家服务正式签到 RPC:rpc_homecare_checkin_submit
|
||||
const { submitHomecareCheckin } = await import('@/api/delivery.uts')
|
||||
const result = await submitHomecareCheckin(
|
||||
orderId.value,
|
||||
akUserId,
|
||||
currentLocation.value!.latitude,
|
||||
currentLocation.value!.longitude,
|
||||
'gcj02',
|
||||
parseFloat(accuracyText.value) || 0,
|
||||
new Date().toISOString(),
|
||||
evidenceFileIds.value,
|
||||
null,
|
||||
'worker_arrived'
|
||||
)
|
||||
|
||||
console.warn('[CHECKIN RPC] result:', result)
|
||||
|
||||
// 签到成功后显示等待消费者确认
|
||||
uni.showModal({
|
||||
@@ -388,7 +509,7 @@ async function doCheckin() {
|
||||
content: '已提交到达签到,等待消费者确认',
|
||||
showCancel: false,
|
||||
success: () => {
|
||||
// 返回订单列表或详情页
|
||||
// 返回订单列表
|
||||
uni.navigateBack()
|
||||
}
|
||||
})
|
||||
|
||||
@@ -501,11 +501,69 @@ const handleLogin = async () => {
|
||||
saveDeliverySession(result.token, result.userInfo, result.deliveryInfo)
|
||||
|
||||
// 加载 ak_users 映射(Supabase Auth ID -> 业务用户 ID)
|
||||
// 优先从 result.userInfo.id 获取业务用户 ID,直接写入缓存
|
||||
// 只有 userInfo.id 不存在时,才调用 loadCurrentAkUser
|
||||
let akUserIdFromLogin = ''
|
||||
try {
|
||||
await loadCurrentAkUser()
|
||||
console.log('[Login] ak_users 映射加载成功')
|
||||
} catch (akErr) {
|
||||
console.warn('[Login] ⚠️ ak_users 映射加载失败(不影响登录):', akErr)
|
||||
// 尝试从 userInfo.id 获取业务用户 ID
|
||||
if (result.userInfo != null && result.userInfo.id != null && String(result.userInfo.id).length > 0) {
|
||||
const candidateId = String(result.userInfo.id)
|
||||
console.log('[Login] 从 result.userInfo.id 获取到 ID:', candidateId)
|
||||
|
||||
// 判断是否是 Supabase Auth ID(通过长度和格式判断)
|
||||
// Supabase Auth ID 通常是 UUID 格式,业务用户 ID 也是 UUID 格式
|
||||
// 最可靠的方式是尝试写入后验证
|
||||
akUserIdFromLogin = candidateId
|
||||
|
||||
// 写入缓存
|
||||
uni.setStorageSync('ak_user_id', akUserIdFromLogin)
|
||||
uni.setStorageSync('user_id', akUserIdFromLogin)
|
||||
uni.setStorageSync('current_ak_user', JSON.stringify({
|
||||
id: akUserIdFromLogin,
|
||||
auth_id: result.userInfo.auth_id ?? '',
|
||||
username: result.userInfo.username ?? '',
|
||||
email: result.userInfo.email ?? '',
|
||||
role: result.userInfo.role ?? ''
|
||||
}))
|
||||
console.log('[Login] 从 userInfo.id 写入 ak_user_id 成功:', akUserIdFromLogin)
|
||||
}
|
||||
} catch (extractErr) {
|
||||
console.warn('[Login] 从 userInfo.id 提取失败:', extractErr)
|
||||
}
|
||||
|
||||
// 如果 userInfo.id 没有有效 ID,才调用 loadCurrentAkUser
|
||||
if (akUserIdFromLogin == null || String(akUserIdFromLogin).length == 0) {
|
||||
try {
|
||||
const profile = await loadCurrentAkUser()
|
||||
akUserIdFromLogin = profile.id
|
||||
console.log('[Login] ak_users 映射加载成功,akUserId:', profile.id)
|
||||
console.log('[Login] 缓存已写入: ak_user_id =', profile.id)
|
||||
} catch (akErr) {
|
||||
console.warn('[Login] ⚠️ ak_users 映射加载失败:', akErr)
|
||||
// 如果 user_id 已有缓存,尝试用它兜底
|
||||
const cachedUserId = uni.getStorageSync('user_id')
|
||||
if (cachedUserId != null && String(cachedUserId).length > 0) {
|
||||
console.log('[Login] 使用 user_id 缓存兜底:', cachedUserId)
|
||||
uni.setStorageSync('ak_user_id', cachedUserId)
|
||||
uni.setStorageSync('current_ak_user', JSON.stringify({ id: cachedUserId }))
|
||||
akUserIdFromLogin = String(cachedUserId)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 最终验证 ak_user_id 必须有值
|
||||
const finalAkUserId = uni.getStorageSync('ak_user_id')
|
||||
console.log('[Login] 最终 ak_user_id:', finalAkUserId)
|
||||
console.log('[Login] 最终 current_ak_user:', uni.getStorageSync('current_ak_user'))
|
||||
|
||||
if (finalAkUserId == null || String(finalAkUserId).length == 0) {
|
||||
console.error('[Login] ❌ ak_user_id 最终为空,输出详细调试信息')
|
||||
console.error('[Login] result.userInfo:', JSON.stringify(result.userInfo))
|
||||
console.error('[Login] result.deliveryInfo:', JSON.stringify(result.deliveryInfo))
|
||||
console.error('[Login] user_id 缓存:', uni.getStorageSync('user_id'))
|
||||
console.error('[Login] auth_user_id 缓存:', uni.getStorageSync('auth_user_id'))
|
||||
console.error('[Login] user_info 缓存:', uni.getStorageSync('user_info'))
|
||||
throw new Error('业务账号映射加载失败,请联系管理员')
|
||||
}
|
||||
|
||||
const authResult = await requireDeliveryAuth({ redirectOnFail: false, toastOnFail: false })
|
||||
|
||||
Reference in New Issue
Block a user