import { GUIDE_LOGIN_KEY, guideProfile, scenics } from '../constants/mock' import { request, resolveApiAssetUrl, uploadFile } from '../utils/request' const PHONE_CHANGE_STATE_KEY = 'mingdao_guide_phone_change_state' function normalizeGuide(user = {}, fallback = {}) { return { ...fallback, ...user, name: user.realName || user.name || user.username || fallback.name || '', phone: user.mobile || user.phone || fallback.phone || '', avatar: resolveApiAssetUrl(user.avatar || fallback.avatar || ''), orderCount: Number(user.acceptedOrderCount ?? user.orderCount ?? fallback.orderCount ?? 0), rating: Number(user.rating ?? fallback.rating ?? 0), groupName: user.teamName || fallback.groupName || (user.teamType === '个人' ? '个人导游' : '') } } function syncGuideState(user) { const login = uni.getStorageSync(GUIDE_LOGIN_KEY) const guide = normalizeGuide(user, (login && login.guide) || guideProfile) if (login) { login.guide = guide uni.setStorageSync(GUIDE_LOGIN_KEY, login) } return guide } function normalizeCoordinate(value) { const number = Number(value) return Number.isFinite(number) ? number : 0 } function flattenMeetingPoints() { return scenics.reduce((rows, scenic) => { const meetingPoints = (scenic.meetingPoints || []).map((point) => ({ scenicId: scenic.id, scenicName: scenic.name, city: scenic.city, ...point })) return rows.concat(meetingPoints) }, []) } export function resolveMeetingPoint(payload = {}) { const scenic = scenics.find((item) => item.id === payload.scenicId || item.name === payload.scenicName) const scopedMeetingPoints = scenic ? scenic.meetingPoints || [] : flattenMeetingPoints() const matched = scopedMeetingPoints.find((item) => item.id === payload.meetingPointId) || scopedMeetingPoints.find((item) => item.name === payload.meetingPointName) || flattenMeetingPoints().find((item) => item.id === payload.meetingPointId || item.name === payload.meetingPointName) const latitude = normalizeCoordinate( payload.meetingPointLatitude || payload.latitude || (matched && matched.latitude) ) const longitude = normalizeCoordinate( payload.meetingPointLongitude || payload.longitude || (matched && matched.longitude) ) if (!matched && (!latitude || !longitude)) { return null } return { scenicId: payload.scenicId || (scenic && scenic.id) || (matched && matched.scenicId) || '', scenicName: payload.scenicName || (scenic && scenic.name) || (matched && matched.scenicName) || '', city: (matched && matched.city) || (scenic && scenic.city) || '', id: payload.meetingPointId || (matched && matched.id) || '', name: payload.meetingPointName || (matched && matched.name) || '汇合点', address: payload.meetingPointAddress || payload.address || (matched && matched.address) || '', guideCount: (matched && matched.guideCount) || 0, latitude, longitude } } export function getGuideProfile() { return request({ url: '/guide/profile' }).then(syncGuideState) } export function updateGuideProfile(patch = {}) { const login = uni.getStorageSync(GUIDE_LOGIN_KEY) const current = (login && login.guide) || guideProfile return request({ url: '/guide/profile', method: 'PUT', data: { realName: patch.name || patch.realName || current.name, avatar: patch.avatar === undefined ? current.avatar : patch.avatar, certificateNo: patch.certificateNo === undefined ? current.certificateNo : patch.certificateNo } }).then(syncGuideState) } export function uploadGuideAvatar(filePath) { return uploadFile({ url: '/guide/profile/avatar', filePath }).then(syncGuideState) } export function sendOldPhoneCode(phone) { return request({ url: '/guide/profile/phone-change/old-code', method: 'POST', data: { phone } }) } export function verifyOldPhone(phone, code) { return request({ url: '/guide/profile/phone-change/verify-old', method: 'POST', data: { phone, code } }).then((result) => { uni.setStorageSync(PHONE_CHANGE_STATE_KEY, result) return result }) } export function sendNewPhoneCode(newPhone) { const state = uni.getStorageSync(PHONE_CHANGE_STATE_KEY) if (!state || !state.changeToken) { return Promise.reject(new Error('旧手机号验证已失效,请重新验证')) } return request({ url: '/guide/profile/phone-change/new-code', method: 'POST', data: { changeToken: state.changeToken, newPhone } }) } export function changeGuidePhone(newPhone, code) { const state = uni.getStorageSync(PHONE_CHANGE_STATE_KEY) if (!state || !state.changeToken) { return Promise.reject(new Error('旧手机号验证已失效,请重新验证')) } return request({ url: '/guide/profile/phone', method: 'PUT', data: { changeToken: state.changeToken, newPhone, code } }).then((user) => { uni.removeStorageSync(PHONE_CHANGE_STATE_KEY) return syncGuideState(user) }) } function syncGuideOnlineStatus(status, receivingConfig = {}) { const login = uni.getStorageSync(GUIDE_LOGIN_KEY) if (login && login.guide) { login.guide.onlineStatus = status if (status === 'online' || status === 'serving') { login.guide.receivingConfig = receivingConfig } if (status === 'offline') { login.guide.receivingConfig = null } uni.setStorageSync(GUIDE_LOGIN_KEY, login) } return status } export function updateGuideOnlineStatus(status, receivingConfig = {}) { let action = Promise.resolve(status) if (status === 'online') { action = request({ url: '/guide/receiving/start', method: 'POST', data: receivingConfig }) } else if (status === 'offline') { action = request({ url: '/guide/receiving/stop', method: 'PUT' }) } return action.then(() => syncGuideOnlineStatus(status, receivingConfig)) } export function finishGuideLecture() { return request({ url: '/guide/receiving/finish', method: 'PUT' }).then(() => { return syncGuideOnlineStatus('offline') }) } export function getScenics() { return getGuideReceivingOptions().then((result) => result.scenics) } export function getGuideReceivingOptions() { return request({ url: '/guide/receiving/options' }) } export function getCurrentGuideReceivingSession() { return request({ url: '/guide/receiving/current' }) } export function submitCertification(form) { const login = uni.getStorageSync(GUIDE_LOGIN_KEY) if (login && login.guide) { login.guide.auditStatus = 'pending' uni.setStorageSync(GUIDE_LOGIN_KEY, login) } return Promise.resolve({ ...form, auditStatus: 'pending' }) } export function resubmitCertification(form) { return request({ url: '/guide/application/resubmit', method: 'PUT', data: { realName: form.name, idCardNo: form.idNo, certificateNo: form.certificateNo || '', idCardFrontUrl: form.idFront, idCardBackUrl: form.idBack, certificateUrl: form.guideLicense } }) }