(function (root, factory) { if (typeof module === 'object' && module.exports) { module.exports = factory(root); return; } root.GenealogyApi = factory(root); })(typeof globalThis !== 'undefined' ? globalThis : window, function (root) { 'use strict'; var DEFAULT_CLIENT_ID = 'ced7e5f0498645c6ec642dcf450b036f'; var DEFAULT_TENANT_ID = '000000'; var DEFAULT_TOKEN_KEY = 'genealogy_auth_token'; function loadNodeModule(path) { if (typeof require !== 'function') return null; try { return require(path); } catch (error) { return null; } } function getConfigApi() { var configFactory; if (root.GenealogyConfig) return root.GenealogyConfig; configFactory = loadNodeModule('../config.js'); return configFactory ? configFactory(root) : null; } function getStorageUtil() { return root.StorageUtil || loadNodeModule('./StorageUtil.js'); } function getAxiosRequestUtil() { return root.AxiosRequestUtil || loadNodeModule('./AxiosRequestUtil.js'); } function getStorage(store) { if (store) return store; try { return root.localStorage; } catch (error) { return null; } } function getTokenFromResponse(data) { return data && (data.token || data.accessToken || data.access_token || data.tokenValue) || ''; } function createFormData(fileOrFormData) { var FormDataCtor = root.FormData; if (FormDataCtor && fileOrFormData instanceof FormDataCtor) return fileOrFormData; if (!FormDataCtor) throw new Error('当前环境不支持文件上传'); var formData = new FormDataCtor(); formData.append('file', fileOrFormData); return formData; } function buildApiUrl(baseUrl, path, query) { var url = String(baseUrl || '').replace(/\/+$/, '') + '/' + String(path || '').replace(/^\/+/, ''); var params = new URLSearchParams(); Object.keys(query || {}).forEach(function (key) { var value = query[key]; if (value !== undefined && value !== null && value !== '') params.append(key, value); }); return params.toString() ? url + '?' + params.toString() : url; } function createClient(options) { var settings = options || {}; var configApi = getConfigApi(); var config = configApi && configApi.getConfig ? configApi.getConfig() : {}; var storageUtil = getStorageUtil(); var axiosRequestUtil = getAxiosRequestUtil(); var store = getStorage(settings.tokenStore || settings.storage); var clientId = settings.clientId || config.clientId || DEFAULT_CLIENT_ID; var tenantId = settings.tenantId || config.tenantId || DEFAULT_TENANT_ID; var tokenKey = settings.tokenKey || config.tokenKey || DEFAULT_TOKEN_KEY; var baseUrl = settings.baseUrl || config.apiBaseUrl; var requester; if (!axiosRequestUtil || !axiosRequestUtil.createRequester) throw new Error('缺少 AxiosRequestUtil.createRequester'); if (!baseUrl) throw new Error('缺少接口基础地址'); function getToken() { return storageUtil && storageUtil.read ? storageUtil.read(store, tokenKey) || '' : ''; } function setToken(token) { if (token && storageUtil && storageUtil.write) storageUtil.write(store, tokenKey, token); } function clearToken() { if (storageUtil && storageUtil.remove) storageUtil.remove(store, tokenKey); } requester = axiosRequestUtil.createRequester({ baseUrl: baseUrl, clientId: clientId, getToken: getToken, axiosInstance: settings.axiosInstance || root.axios }); function request(method, path, requestOptions) { // 请求函数保持私有,页面只能调用下方已在接口文档中定义的业务方法。 return requester(method, path, requestOptions || {}); } function withTenant(body) { return Object.assign({ tenantId: tenantId, clientId: clientId }, body || {}); } function toRequiredPathId(value, label) { var text = String(value === undefined || value === null ? '' : value).trim(); if (!text) throw new Error('缺少' + label); return encodeURIComponent(text); } function buildFeedPath(genealogyId, suffix) { // 家族圈接口统一由家谱编号定位,避免页面拼接出未定义的请求路径。 return '/genealogy/pc/genealogies/' + toRequiredPathId(genealogyId, '家谱编号') + '/feeds' + (suffix || ''); } function buildFeedDetailPath(genealogyId, feedId, suffix) { return buildFeedPath(genealogyId, '/' + toRequiredPathId(feedId, '动态编号') + (suffix || '')); } function buildFeedCommentPath(genealogyId, feedId, commentId) { var path = buildFeedDetailPath(genealogyId, feedId, '/comments'); return commentId === undefined || commentId === null || commentId === '' ? path : path + '/' + toRequiredPathId(commentId, '评论编号'); } async function login(body) { var data = await request('POST', '/genealogy/pc/auth/login', { auth: false, body: Object.assign({ grantType: 'password' }, withTenant(body)) }); var token = getTokenFromResponse(data); if (!token) throw new Error('登录响应缺少 token'); setToken(token); return data; } async function loginBySms(body) { var data = await request('POST', '/genealogy/pc/auth/login/sms', { auth: false, body: Object.assign({ grantType: 'sms' }, withTenant(body)) }); var token = getTokenFromResponse(data); if (!token) throw new Error('登录响应缺少 token'); setToken(token); return data; } async function deactivateAccount(body) { var data = await request('POST', '/genealogy/pc/auth/account/deactivate', { body: body }); clearToken(); return data; } async function logout() { try { return await request('DELETE', '/genealogy/pc/auth/logout'); } finally { clearToken(); } } return { clientId: clientId, tenantId: tenantId, tokenKey: tokenKey, getToken: getToken, setToken: setToken, clearToken: clearToken, buildApiUrl: function (path, query) { return buildApiUrl(baseUrl, path, query); }, register: function (body) { return request('POST', '/genealogy/pc/auth/register', { auth: false, body: Object.assign({ grantType: 'password', registerSource: 'PC' }, withTenant(body)) }); }, login: login, loginBySms: loginBySms, sendSmsCode: function (body) { return request('POST', '/genealogy/pc/auth/sms/code', { auth: false, // 最新接口文档要求短信发送场景携带 grantType 与验证码票据。 body: Object.assign({ grantType: 'sms' }, withTenant(body)) }); }, currentProfile: function () { return request('GET', '/genealogy/pc/auth/profile'); }, updateProfile: function (body) { return request('PUT', '/genealogy/pc/auth/profile', { body: body }); }, changePassword: function (body) { return request('PUT', '/genealogy/pc/auth/password', { body: body }); }, resetPassword: function (body) { return request('PUT', '/genealogy/pc/auth/password/reset', { auth: false, body: Object.assign({ tenantId: tenantId }, body || {}) }); }, changePhone: function (body) { return request('PUT', '/genealogy/pc/auth/phone', { body: body }); }, deactivateAccount: deactivateAccount, logout: logout, uploadFile: function (fileOrFormData) { return request('POST', '/genealogy/pc/files/upload', { body: createFormData(fileOrFormData) }); }, captchaRequirement: function (body) { var source = body || {}; return request('GET', '/captcha/require', { auth: false, query: { tenantId: source.tenantId || tenantId, clientId: source.clientId || clientId, sceneCode: source.sceneCode, subject: source.subject } }); }, captchaChallenge: function (body) { return request('POST', '/captcha/challenge', { auth: false, body: withTenant(body) }); }, captchaVerify: function (body) { return request('POST', '/captcha/verify', { auth: false, body: withTenant(body) }); }, regionChildren: function (parentCode) { return request('GET', '/genealogy/region/children', { auth: false, query: { parentCode: parentCode } }); }, regionPath: function (regionCode) { return request('GET', '/genealogy/region/path/' + encodeURIComponent(regionCode), { auth: false }); }, regionSearch: function (query) { return request('GET', '/genealogy/region/search', { auth: false, query: query }); }, regionDetail: function (regionCode) { return request('GET', '/genealogy/region/' + encodeURIComponent(regionCode), { auth: false }); }, feeds: function (genealogyId) { return request('GET', buildFeedPath(genealogyId)); }, feedsPage: function (genealogyId, query) { return request('GET', buildFeedPath(genealogyId, '/page'), { query: query }); }, feedDetail: function (genealogyId, feedId) { return request('GET', buildFeedDetailPath(genealogyId, feedId)); }, createFeed: function (genealogyId, body) { return request('POST', buildFeedPath(genealogyId), { body: body }); }, updateFeed: function (genealogyId, feedId, body) { return request('PUT', buildFeedDetailPath(genealogyId, feedId), { body: body }); }, deleteFeed: function (genealogyId, feedId) { return request('DELETE', buildFeedDetailPath(genealogyId, feedId)); }, likeFeed: function (genealogyId, feedId) { return request('POST', buildFeedDetailPath(genealogyId, feedId, '/likes')); }, unlikeFeed: function (genealogyId, feedId) { return request('DELETE', buildFeedDetailPath(genealogyId, feedId, '/likes')); }, feedComments: function (genealogyId, feedId) { return request('GET', buildFeedCommentPath(genealogyId, feedId)); }, feedCommentsPage: function (genealogyId, feedId, query) { return request('GET', buildFeedCommentPath(genealogyId, feedId) + '/page', { query: query }); }, createFeedComment: function (genealogyId, feedId, body) { return request('POST', buildFeedCommentPath(genealogyId, feedId), { body: body }); }, deleteFeedComment: function (genealogyId, feedId, commentId) { return request('DELETE', buildFeedCommentPath(genealogyId, feedId, commentId)); } }; } function createDefaultClient() { try { return createClient(); } catch (error) { return null; } } return { DEFAULT_CLIENT_ID: DEFAULT_CLIENT_ID, DEFAULT_TENANT_ID: DEFAULT_TENANT_ID, TOKEN_KEY: DEFAULT_TOKEN_KEY, createClient: createClient, defaultClient: createDefaultClient() }; });