家谱现有接口调试50%
This commit is contained in:
@@ -0,0 +1,261 @@
|
||||
(function (root, factory) {
|
||||
// 验证码适配层同时支持浏览器运行和 Node 单元测试。
|
||||
if (typeof module === 'object' && module.exports) {
|
||||
module.exports = factory(root);
|
||||
return;
|
||||
}
|
||||
|
||||
root.CaptchaPages = factory(root);
|
||||
})(typeof globalThis !== 'undefined' ? globalThis : window, function (root) {
|
||||
'use strict';
|
||||
|
||||
var DEFAULT_SCENE_CODE = 'WEB_H5_LOGIN';
|
||||
|
||||
function getApi() {
|
||||
return root.GenealogyApi && root.GenealogyApi.defaultClient;
|
||||
}
|
||||
|
||||
function query(selector, rootNode) {
|
||||
return (rootNode || root.document).querySelector(selector);
|
||||
}
|
||||
|
||||
function showMessage(message) {
|
||||
if (root.MessageUtil && root.MessageUtil.show) {
|
||||
root.MessageUtil.show(message);
|
||||
return;
|
||||
}
|
||||
|
||||
if (root.console && root.console.warn) root.console.warn(message);
|
||||
}
|
||||
|
||||
function buildChallengeBody(options, api) {
|
||||
// 请求体字段严格对应 PC YAML 的 VerificationChallengeBody。
|
||||
var settings = options || {};
|
||||
|
||||
return {
|
||||
tenantId: settings.tenantId || api.tenantId,
|
||||
clientId: settings.clientId || api.clientId,
|
||||
sceneCode: settings.sceneCode || DEFAULT_SCENE_CODE,
|
||||
subject: settings.subject || ''
|
||||
};
|
||||
}
|
||||
|
||||
function normalizeChallengeData(data) {
|
||||
// TAC 需要 data.type、data.id 和图片字段;接口文档返回 captchaType、challengeId、payload。
|
||||
var source = data || {};
|
||||
var payload = source.payload || {};
|
||||
|
||||
return Object.assign({}, payload, {
|
||||
type: source.captchaType || payload.type || 'SLIDER',
|
||||
id: payload.id || source.challengeId,
|
||||
challengeId: source.challengeId,
|
||||
providerCode: source.providerCode || 'tianai',
|
||||
captchaType: source.captchaType || payload.type || 'SLIDER'
|
||||
});
|
||||
}
|
||||
|
||||
function adaptChallengeResponse(response) {
|
||||
var payload = response || {};
|
||||
|
||||
if (Number(payload.code) !== 200 || !payload.data) return payload;
|
||||
|
||||
return Object.assign({}, payload, {
|
||||
data: normalizeChallengeData(payload.data)
|
||||
});
|
||||
}
|
||||
|
||||
function buildVerifyBody(requestData, context, api) {
|
||||
// requestData 是 TAC 拖动完成后的轨迹数据;context 保存本次挑战的接口字段。
|
||||
var settings = context || {};
|
||||
var source = requestData || {};
|
||||
|
||||
return {
|
||||
tenantId: settings.tenantId || api.tenantId,
|
||||
clientId: settings.clientId || api.clientId,
|
||||
sceneCode: settings.sceneCode || DEFAULT_SCENE_CODE,
|
||||
subject: settings.subject || '',
|
||||
challengeId: settings.challengeId || source.challengeId || source.id,
|
||||
providerCode: settings.providerCode || 'tianai',
|
||||
captchaType: settings.captchaType || 'SLIDER',
|
||||
payload: {
|
||||
id: source.id,
|
||||
data: source.data || {}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function normalizeVerifyResponse(response) {
|
||||
// TAC 只看 code 是否为 200;接口通过 passed 表示业务验证结果。
|
||||
var payload = response || {};
|
||||
|
||||
if (Number(payload.code) === 200 && payload.data && payload.data.passed === false) {
|
||||
return Object.assign({}, payload, {
|
||||
code: 4001,
|
||||
msg: payload.data.message || payload.msg || '验证失败'
|
||||
});
|
||||
}
|
||||
|
||||
return payload;
|
||||
}
|
||||
|
||||
function extractValidToken(response) {
|
||||
var payload = response || {};
|
||||
var data = payload.data || {};
|
||||
|
||||
if (Number(payload.code) !== 200) return '';
|
||||
if (data.passed === false) return '';
|
||||
return data.validToken || payload.validToken || '';
|
||||
}
|
||||
|
||||
function getTokenField(form) {
|
||||
return query('input[name="validToken"]', form);
|
||||
}
|
||||
|
||||
function getCaptchaBox(form) {
|
||||
// 优先使用页面级弹窗挂载点,避免 TAC 验证码挤占表单布局。
|
||||
return query('.auth-captcha-modal[data-captcha-box]')
|
||||
|| query('[data-captcha-box]', form)
|
||||
|| query('[data-captcha-box]');
|
||||
}
|
||||
|
||||
function writeValidToken(form, token) {
|
||||
var field = getTokenField(form);
|
||||
|
||||
if (field) field.value = token || '';
|
||||
}
|
||||
|
||||
function shouldRequireCaptcha(result) {
|
||||
// /captcha/require 返回 required=false 时允许直接继续业务请求。
|
||||
if (!result) return true;
|
||||
return result.required !== false;
|
||||
}
|
||||
|
||||
function createTac(form, options, api, resolve, reject) {
|
||||
var settings = options || {};
|
||||
var box = getCaptchaBox(form);
|
||||
var context = buildChallengeBody(settings, api);
|
||||
var lastChallenge = {};
|
||||
var captcha;
|
||||
var config;
|
||||
|
||||
if (!root.TAC || !root.CaptchaConfig) {
|
||||
reject(new Error('滑动验证组件未加载'));
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!box) {
|
||||
reject(new Error('缺少滑动验证容器'));
|
||||
return null;
|
||||
}
|
||||
|
||||
config = new root.CaptchaConfig({
|
||||
bindEl: box,
|
||||
requestCaptchaDataUrl: api.buildApiUrl('/captcha/challenge'),
|
||||
validCaptchaUrl: api.buildApiUrl('/captcha/verify'),
|
||||
requestHeaders: {
|
||||
clientid: api.clientId
|
||||
},
|
||||
validSuccess: function (response, captchaControl, captchaInstance) {
|
||||
var token = extractValidToken(response);
|
||||
|
||||
if (!token) {
|
||||
reject(new Error('滑动验证未返回有效票据'));
|
||||
return;
|
||||
}
|
||||
|
||||
writeValidToken(form, token);
|
||||
if (captchaInstance && captchaInstance.destroyWindow) captchaInstance.destroyWindow();
|
||||
resolve(token);
|
||||
},
|
||||
validFail: function (response, captchaControl, captchaInstance) {
|
||||
if (captchaInstance && captchaInstance.reloadCaptcha) captchaInstance.reloadCaptcha();
|
||||
showMessage((response && (response.msg || response.message)) || '滑动验证失败,请重试');
|
||||
},
|
||||
btnCloseFun: function (event, captchaInstance) {
|
||||
if (captchaInstance) captchaInstance.destroyWindow();
|
||||
reject(new Error('已取消滑动验证'));
|
||||
}
|
||||
});
|
||||
|
||||
config.addRequestChain({
|
||||
preRequest: function (type, request) {
|
||||
if (type === 'requestCaptchaData') {
|
||||
request.data = buildChallengeBody(settings, api);
|
||||
}
|
||||
|
||||
if (type === 'validCaptcha') {
|
||||
request.data = buildVerifyBody(request.data, Object.assign({}, context, lastChallenge), api);
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
postRequest: function (type, request, response) {
|
||||
if (type === 'requestCaptchaData') {
|
||||
var adapted = adaptChallengeResponse(response);
|
||||
|
||||
lastChallenge = {
|
||||
challengeId: adapted.data && adapted.data.challengeId,
|
||||
providerCode: adapted.data && adapted.data.providerCode,
|
||||
captchaType: adapted.data && adapted.data.captchaType
|
||||
};
|
||||
|
||||
Object.keys(response || {}).forEach(function (key) {
|
||||
delete response[key];
|
||||
});
|
||||
Object.assign(response, adapted);
|
||||
}
|
||||
|
||||
if (type === 'validCaptcha') {
|
||||
Object.assign(response, normalizeVerifyResponse(response));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
captcha = new root.TAC(config, {
|
||||
bgUrl: 'public/tac/images/dun.jpeg',
|
||||
logoUrl: null
|
||||
});
|
||||
captcha.init();
|
||||
return captcha;
|
||||
}
|
||||
|
||||
async function ensureToken(form, options) {
|
||||
// 认证页提交前调用:已有 validToken 直接通过,否则按验证中心策略弹出 TAC。
|
||||
var api = getApi();
|
||||
var field = getTokenField(form);
|
||||
var settings = options || {};
|
||||
var requirement;
|
||||
|
||||
if (!api) return '';
|
||||
if (field && field.value) return field.value;
|
||||
if (!settings.sceneCode) return '';
|
||||
|
||||
try {
|
||||
requirement = await api.captchaRequirement(buildChallengeBody(settings, api));
|
||||
if (!shouldRequireCaptcha(requirement)) return 'CAPTCHA_NOT_REQUIRED';
|
||||
} catch (error) {
|
||||
// 查询策略失败时仍尝试直接拉起验证,避免认证接口缺少 validToken。
|
||||
requirement = null;
|
||||
}
|
||||
|
||||
return new Promise(function (resolve, reject) {
|
||||
createTac(form, settings, api, resolve, reject);
|
||||
}).catch(function (error) {
|
||||
showMessage(error.message || '请先完成滑动验证');
|
||||
return '';
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
buildChallengeBody: buildChallengeBody,
|
||||
adaptChallengeResponse: adaptChallengeResponse,
|
||||
buildVerifyBody: buildVerifyBody,
|
||||
getCaptchaBox: getCaptchaBox,
|
||||
extractValidToken: extractValidToken,
|
||||
normalizeVerifyResponse: normalizeVerifyResponse,
|
||||
shouldRequireCaptcha: shouldRequireCaptcha,
|
||||
ensureToken: ensureToken
|
||||
};
|
||||
});
|
||||
Reference in New Issue
Block a user