Files
wordpress-theme-aksrt/assets/js/routes/user-center-auth.js
T
kate522andClaude Opus 5 35bb96e82f refactor: rename the theme brand and every identifier from AKSRT to Jio
Full-project rename. `git grep -i aksrt` is now empty apart from the
DBMigrator 3.3.0 changelog note that documents the rename itself.

Code identifiers
- PHP namespace AKSRT\ -> Jio\ (composer PSR-4 + 378 declarations)
- global constants AKSRT_* -> JIO_* (VERSION/DIR/URI, PAY_TYPE_*, CAPTCHA_*)
- procedural functions, hooks, options, meta keys, table names,
  cookies, query vars, ajax actions and nonces: aksrt_ -> jio_
- text domain aksrt -> jio; Theme Name -> Jio
- JS globals: aksrtData/aksrtAdminData/... -> jioData/jioAdminData/...,
  window.AKSRTCaptcha & friends -> window.JioCaptcha, Aksrt* -> Jio*
- Vue components Aks*.vue -> Jio*.vue (15 files renamed + imports)
- CSS classes/data-attrs/custom properties: aksrt- -> jio-
- REST namespace aksrt/v1 -> jio/v1 (incl. payment gateway callbacks)

Storage layer
- DB tables {prefix}aksrt_* -> {prefix}jio_*; SCHEMA_VERSION 3.2.0 -> 3.3.0
  so dbDelta creates the new names on install
- widget id_base aksrt_widget_* -> jio_widget_*
- uninstall.php drop list rebuilt from the actual migrator tables
  (dropped 3 stale entries, added the 17 missing ones)

Removed
- hardcoded https://api.aksrt.com/version.json default update endpoint;
  get_endpoint() now reads the 「更新端点」 setting and do_check() no-ops
  when it is empty

Files renamed: inc/helpers/aksrt-*.php -> jio-*.php (54),
assets/admin/src/components/form/Aks*.vue -> Jio*.vue (15).
Build artifacts regenerated: assets/css/build, assets/js/runtime,
assets/admin/build.

Verified: audit-psr4-paths errors=0, audit-admin-contracts errors=0
(warnings=56, unchanged baseline), 813/813 widget-system tests,
44/44 phpunit, php -l clean across all PHP.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-11-01 20:05:04 +08:00

245 lines
11 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
(function (window, document) {
'use strict';
function configFor(root) {
try { return JSON.parse(root.getAttribute('data-identity-config') || '{}'); } catch (_) { return {}; }
}
function parseResponse(response) {
var payload = response && (response.data !== undefined ? response.data : response.json);
return payload && payload.data !== undefined ? payload.data : payload;
}
function errorMessage(error, fallback) {
if (error && error.json) return error.json.message || fallback;
return error && error.message ? error.message : fallback;
}
function toast(message, type, time, id) {
if (message && typeof window.notyf === 'function') window.notyf(message, type || 'success', time, id);
}
function init(root) {
if (!root || root.dataset.identityBound === '1') return;
root.dataset.identityBound = '1';
var config = configFor(root);
var template = root.querySelector('[data-auth-modal-template]');
var runtime = window.JioModalRuntime;
if (!template || !runtime || !window.JioRequest) return;
function open() {
runtime.open({
html: template.innerHTML,
height: 320,
kind: 'identity',
className: 'jio-identity-modal-shell',
mobileBottom: true,
onContent: function (_, session) {
var shell = session && session.shell;
var form = shell && shell.querySelector('[data-auth-create]');
var input = form && form.querySelector('[data-auth-evidence]');
var preview = form && form.querySelector('[data-auth-preview]');
if (!form || !input || !preview) return;
shell.setAttribute('aria-labelledby', 'uc-auth-modal-title');
var selectedFiles = [];
function renderPreview() {
preview.replaceChildren();
selectedFiles.forEach(function (entry, index) {
var item = document.createElement('div');
item.className = 'preview-item';
var image = document.createElement('img');
image.className = 'fit-cover';
image.src = entry.url;
image.alt = entry.file.name;
var remove = document.createElement('button');
remove.type = 'button';
remove.className = 'uc-auth-preview-remove';
remove.dataset.authRemove = String(index);
remove.setAttribute('aria-label', '移除 ' + entry.file.name);
remove.textContent = '×';
item.appendChild(image);
item.appendChild(remove);
preview.appendChild(item);
});
if (selectedFiles.length < 3) {
var add = document.createElement('button');
add.type = 'button';
add.className = 'add';
add.dataset.authFilePicker = '';
add.setAttribute('aria-label', '选择证明材料图片');
preview.appendChild(add);
}
}
function releasePreviewUrls() {
selectedFiles.forEach(function (entry) { window.URL.revokeObjectURL(entry.url); });
selectedFiles = [];
}
function onModalClose(event) {
if (!event.detail || event.detail.shell !== shell) return;
document.removeEventListener('jio:modal:close', onModalClose);
releasePreviewUrls();
}
document.addEventListener('jio:modal:close', onModalClose);
preview.addEventListener('click', function (event) {
var remove = event.target.closest('[data-auth-remove]');
if (remove) {
var index = Number(remove.dataset.authRemove);
var entry = selectedFiles[index];
if (entry) window.URL.revokeObjectURL(entry.url);
selectedFiles.splice(index, 1);
renderPreview();
return;
}
if (event.target.closest('[data-auth-file-picker]')) input.click();
});
input.addEventListener('change', function () {
var files = Array.prototype.slice.call(input.files || []);
input.value = '';
if (!files.length) return;
var unsupported = files.some(function (file) { return !/^image\/(gif|jpe?g|png|webp)$/i.test(file.type); });
if (unsupported) {
toast('证明材料仅支持 JPG、PNG、GIF 或 WebP 图片', 'danger');
return;
}
if (files.some(function (file) { return file.size > 2 * 1024 * 1024; })) {
toast('单张证明材料不能超过 2MB', 'danger');
return;
}
var uniqueFiles = files.filter(function (file, index) {
var key = [file.name, file.size, file.lastModified].join(':');
return !selectedFiles.some(function (entry) { return entry.key === key; }) &&
files.findIndex(function (candidate) {
return [candidate.name, candidate.size, candidate.lastModified].join(':') === key;
}) === index;
});
if (selectedFiles.length + uniqueFiles.length > 3) {
toast('证明材料最多上传 3 张', 'danger');
return;
}
uniqueFiles.forEach(function (file) {
selectedFiles.push({
file: file,
key: [file.name, file.size, file.lastModified].join(':'),
url: window.URL.createObjectURL(file),
});
});
renderPreview();
});
var header = shell.querySelector('.uc-auth-modal__header');
if (header) {
var touchStartY = null;
header.addEventListener('touchstart', function (event) {
touchStartY = event.touches.length ? event.touches[0].clientY : null;
}, { passive: true });
header.addEventListener('touchend', function (event) {
var touchEndY = event.changedTouches.length ? event.changedTouches[0].clientY : null;
if (touchStartY !== null && touchEndY !== null && touchEndY - touchStartY > 60 &&
runtime.getActive && runtime.getActive() === shell) {
runtime.close('swipe');
}
touchStartY = null;
}, { passive: true });
}
form.addEventListener('submit', function (event) {
event.preventDefault();
var invalidField = form.querySelector(':invalid');
if (!form.checkValidity()) {
toast((invalidField && invalidField.validationMessage) || '请检查申请信息是否填写完整', 'danger');
if (invalidField && typeof invalidField.focus === 'function') invalidField.focus();
return;
}
var button = form.querySelector('[type="submit"]');
var formData = new FormData(form);
selectedFiles.forEach(function (entry) {
formData.append('evidence[]', entry.file, entry.file.name);
});
var submitLabel = button ? button.innerHTML : '';
if (button) {
button.disabled = true;
button.innerHTML = '<i class="fa fas fa-spinner fa-spin mr6" aria-hidden="true"></i>正在提交…';
}
toast('正在提交申请…', 'load', '', 'jio_identity_submit');
window.JioRequest.request(config.restBase, {
method: 'POST',
credentials: 'same-origin',
headers: { 'X-WP-Nonce': config.nonce || '' },
body: formData,
}).then(function (response) {
var result = parseResponse(response);
if (!result || result.success === false) throw new Error((result && result.message) || '申请提交失败,请稍后重试');
toast('申请已提交,请耐心等待管理员审核。', 'success', '', 'jio_identity_submit');
var summary = root.querySelector('[data-auth-summary]');
if (summary) {
summary.replaceChildren();
var pending = document.createElement('div');
pending.className = 'c-red mb10';
pending.textContent = '您的申请正在审核中,请耐心等待';
var name = document.createElement('div');
name.textContent = result.name || '';
summary.appendChild(pending);
summary.appendChild(name);
if (result.description) {
var description = document.createElement('div');
description.className = 'muted-2-color mt10';
description.textContent = result.description;
summary.appendChild(description);
}
if (result.message) {
var applicationMessage = document.createElement('div');
applicationMessage.className = 'muted-2-color mt10';
applicationMessage.textContent = '申请说明:' + result.message;
summary.appendChild(applicationMessage);
}
(Array.isArray(result.evidence) ? result.evidence : []).forEach(function (item) {
if (!item || !item.url || !item.thumbnail_url) return;
var link = document.createElement('a');
link.href = item.url;
link.target = '_blank';
link.rel = 'noopener noreferrer';
var image = document.createElement('img');
image.src = item.thumbnail_url;
image.alt = '身份认证证明材料';
image.width = 64;
image.height = 64;
image.style.objectFit = 'cover';
image.style.borderRadius = '4px';
link.appendChild(image);
summary.appendChild(link);
});
}
if (runtime.getActive && runtime.getActive() === shell) runtime.close('submit');
}).catch(function (error) {
toast(errorMessage(error, '申请提交失败,请稍后重试'), 'danger', '', 'jio_identity_submit');
}).finally(function () {
if (button) {
button.disabled = false;
button.innerHTML = submitLabel;
}
});
});
},
});
}
root.querySelectorAll('[data-auth-modal-open]').forEach(function (button) {
button.addEventListener('click', function (event) {
event.preventDefault();
open();
});
});
}
window.JioUserCenterAuth = { init: init };
})(window, document);