diff --git a/achievement/index.html b/achievement/index.html index bfacde9..6d75a57 100644 --- a/achievement/index.html +++ b/achievement/index.html @@ -560,6 +560,7 @@ new URLSearchParams(window.location.search).get( 'tab' ) || 'honors', + targetUserID: normalizedQueryUserID(), loading: false, toastTimer: 0, profile: null, @@ -596,6 +597,30 @@ function validTab(value) { return tabs[value] ? value : 'honors'; } + function normalizedQueryUserID() { + var value = String( + new URLSearchParams(window.location.search).get( + 'user_id' + ) || '' + ).trim(); + return /^\d+$/.test(value) && Number(value) > 0 + ? value + : ''; + } + function hasAccessToken() { + return !!( + window.HyAppAPI && + window.HyAppAPI.getAccessToken && + window.HyAppAPI.getAccessToken() + ); + } + function canLoadAchievements() { + return !!( + window.HyAppAPI && + window.HyAppAPI.achievement && + (state.targetUserID || hasAccessToken()) + ); + } function showToast(message) { var toast = byId('toast'); toast.textContent = message; @@ -947,18 +972,22 @@ } function achievementQuery(name, page) { var cfg = tabs[name] || tabs.honors; - return { + var query = { collection_type: cfg.collection_type, collection_id: cfg.collection_id || '', page: page, page_size: 60, }; + if (state.targetUserID) query.user_id = state.targetUserID; + return query; } function fetchAchievementList(name, page, acc) { var nextPage = page || 1; var items = acc || []; return window.HyAppAPI.achievement - .list(achievementQuery(name, nextPage)) + .list(achievementQuery(name, nextPage), { + skipAuth: !!state.targetUserID, + }) .then(function (data) { var current = normalizeAchievements(data); var merged = items.concat(current); @@ -985,11 +1014,7 @@ } render(); if (state.loaded[state.tab]) return Promise.resolve(); - if ( - !window.HyAppAPI || - !window.HyAppAPI.achievement || - !window.HyAppAPI.getAccessToken() - ) { + if (!canLoadAchievements()) { state.loaded[state.tab] = true; render(); return Promise.resolve(); @@ -1016,11 +1041,51 @@ } function loadUserProfile() { var tasks = []; - var hasToken = + var hasToken = hasAccessToken(); + if ( + state.targetUserID && window.HyAppAPI && - window.HyAppAPI.getAccessToken && - window.HyAppAPI.getAccessToken(); - if (window.HyAppParams && window.HyAppParams.loadUser) { + window.HyAppAPI.user + ) { + if (window.HyAppAPI.user.profile) { + tasks.push( + window.HyAppAPI.user + .profile(state.targetUserID, { + skipAuth: true, + }) + .then(function (data) { + state.profile = profileSource(data); + renderHeader(); + return data; + }) + .catch(function () { + return null; + }) + ); + } + if (window.HyAppAPI.user.appearance) { + tasks.push( + window.HyAppAPI.user + .appearance(state.targetUserID, { + skipAuth: true, + }) + .then(function (data) { + state.appearance = + normalizeAppearance(data); + renderHeader(); + return data; + }) + .catch(function () { + state.appearance = {}; + renderHeader(); + return null; + }) + ); + } + } else if ( + window.HyAppParams && + window.HyAppParams.loadUser + ) { tasks.push( window.HyAppParams.loadUser() .then(function (current) { @@ -1034,6 +1099,7 @@ ); } if ( + !state.targetUserID && hasToken && window.HyAppAPI.user && window.HyAppAPI.user.appearance @@ -1064,11 +1130,7 @@ var active = state.tab; var other = active === 'honors' ? 'event' : 'honors'; if (state.loaded[other]) return Promise.resolve(); - if ( - !window.HyAppAPI || - !window.HyAppAPI.achievement || - !window.HyAppAPI.getAccessToken() - ) { + if (!canLoadAchievements()) { state.loaded[other] = true; renderHeader(); return Promise.resolve(); diff --git a/common/api.js b/common/api.js index 65132f2..6402289 100644 --- a/common/api.js +++ b/common/api.js @@ -453,7 +453,7 @@ var default_api = 'https://api.global-interaction.com/'; ); var token = getAccessToken(); var url = buildURL(path, opts.query); - if (token) headers.Authorization = 'Bearer ' + token; + if (token && !opts.skipAuth) headers.Authorization = 'Bearer ' + token; headers['X-App-Code'] = requestAppCode(); if (!shouldPersist() && isSameOriginURL(url)) headers['Cache-Control'] = 'no-cache'; @@ -501,8 +501,29 @@ var default_api = 'https://api.global-interaction.com/'; overview: function () { return request('/api/v1/users/me/overview', { method: 'GET' }); }, - appearance: function () { - return request('/api/v1/users/me/appearance', { method: 'GET' }); + profile: function (userID, options) { + var id = String(userID || '').trim(); + var opts = options || {}; + if (!id) return Promise.reject(new Error('user_id is required')); + return request( + '/api/v1/users/by-id/' + encodeURIComponent(id) + '/profile', + { + method: 'GET', + skipAuth: !!opts.skipAuth, + } + ); + }, + appearance: function (userID, options) { + var id = String(userID || '').trim(); + var opts = options || {}; + return request( + id + ? '/api/v1/users/by-id/' + + encodeURIComponent(id) + + '/appearance' + : '/api/v1/users/me/appearance', + { method: 'GET', skipAuth: !!opts.skipAuth } + ); }, hostIdentity: function () { return request('/api/v1/users/me/host-identity', { @@ -1060,14 +1081,18 @@ var default_api = 'https://api.global-interaction.com/'; }, options: function (displayUserID, extra) { if (isConfiguredWebPay()) { - var query = Object.assign(aslanUserQuery(displayUserID, extra), { - payCountryId: - extra && (extra.pay_country_id || extra.payCountryId), - countryCode: - extra && (extra.country_code || extra.countryCode), - regionId: extra && (extra.region_id || extra.regionId), - userId: extra && (extra.user_id || extra.userId), - }); + var query = Object.assign( + aslanUserQuery(displayUserID, extra), + { + payCountryId: + extra && + (extra.pay_country_id || extra.payCountryId), + countryCode: + extra && (extra.country_code || extra.countryCode), + regionId: extra && (extra.region_id || extra.regionId), + userId: extra && (extra.user_id || extra.userId), + } + ); return request( appEndpoint('options', '/order/web/pay/h5/options'), { @@ -1496,10 +1521,12 @@ var default_api = 'https://api.global-interaction.com/'; // 成就页只读当前用户的 App 成就和徽章展示资料;认证、app_code、env、错误 envelope 仍由 request 统一处理。 // collection_type 由页面按 tab 传入,避免 H5 自己拼接不同业务集合导致后端筛选语义漂移。 var achievementAPI = { - list: function (query) { + list: function (query, options) { + var opts = options || {}; return request('/api/v1/achievements', { method: 'GET', query: query || {}, + skipAuth: !!opts.skipAuth, }); }, badges: function () {