新增HPOS兼容性支持,重构支付网关类以兼容高性能订单存储系统 添加结账页面编辑器功能,支持多种布局预览和自定义样式 更新配置文件以支持开发环境域名设置 添加CHANGELOG.md和README.md文档 优化区块管理器和通知处理类的代码结构
357 lines
No EOL
13 KiB
JavaScript
357 lines
No EOL
13 KiB
JavaScript
/**
|
||
* EasyPay Checkout Editor JavaScript
|
||
*
|
||
* Handles checkout page block editing functionality
|
||
*
|
||
* @package WenPaiEPay
|
||
* @since 1.0.1
|
||
*/
|
||
|
||
(function($) {
|
||
'use strict';
|
||
|
||
// 确保WordPress区块编辑器API可用
|
||
if (typeof wp === 'undefined' || !wp.blocks) {
|
||
return;
|
||
}
|
||
|
||
const { registerBlockType } = wp.blocks;
|
||
const { createElement: el, Fragment } = wp.element;
|
||
const { InspectorControls } = wp.blockEditor;
|
||
const { PanelBody, SelectControl, ToggleControl, TextControl, Button } = wp.components;
|
||
const { __ } = wp.i18n;
|
||
|
||
/**
|
||
* EasyPay Checkout Layout Editor Component
|
||
*/
|
||
const EasyPayCheckoutEditor = {
|
||
|
||
/**
|
||
* Initialize the editor
|
||
*/
|
||
init: function() {
|
||
this.registerLayoutBlock();
|
||
this.bindEvents();
|
||
},
|
||
|
||
/**
|
||
* Register the layout configuration block
|
||
*/
|
||
registerLayoutBlock: function() {
|
||
registerBlockType('easypay/checkout-layout', {
|
||
title: easypayEditor.strings.layoutSettings,
|
||
icon: 'admin-settings',
|
||
category: 'woocommerce',
|
||
attributes: {
|
||
layout: {
|
||
type: 'string',
|
||
default: easypayEditor.currentLayout || 'default'
|
||
},
|
||
showIcons: {
|
||
type: 'boolean',
|
||
default: true
|
||
},
|
||
enableAnimations: {
|
||
type: 'boolean',
|
||
default: true
|
||
},
|
||
customClass: {
|
||
type: 'string',
|
||
default: ''
|
||
}
|
||
},
|
||
|
||
edit: function(props) {
|
||
const { attributes, setAttributes } = props;
|
||
const { layout, showIcons, enableAnimations, customClass } = attributes;
|
||
|
||
return el(Fragment, {},
|
||
// Inspector Controls (侧边栏设置)
|
||
el(InspectorControls, {},
|
||
el(PanelBody, {
|
||
title: easypayEditor.strings.layoutSettings,
|
||
initialOpen: true
|
||
},
|
||
el(SelectControl, {
|
||
label: easypayEditor.strings.selectLayout,
|
||
value: layout,
|
||
options: Object.keys(easypayEditor.layouts).map(key => ({
|
||
label: easypayEditor.layouts[key],
|
||
value: key
|
||
})),
|
||
onChange: function(newLayout) {
|
||
setAttributes({ layout: newLayout });
|
||
EasyPayCheckoutEditor.previewLayout(newLayout);
|
||
}
|
||
}),
|
||
|
||
el(ToggleControl, {
|
||
label: '显示支付图标',
|
||
checked: showIcons,
|
||
onChange: function(value) {
|
||
setAttributes({ showIcons: value });
|
||
}
|
||
}),
|
||
|
||
el(ToggleControl, {
|
||
label: '启用动画效果',
|
||
checked: enableAnimations,
|
||
onChange: function(value) {
|
||
setAttributes({ enableAnimations: value });
|
||
}
|
||
}),
|
||
|
||
el(TextControl, {
|
||
label: '自定义CSS类',
|
||
value: customClass,
|
||
onChange: function(value) {
|
||
setAttributes({ customClass: value });
|
||
},
|
||
help: '为结账表单添加自定义CSS类'
|
||
}),
|
||
|
||
el(Button, {
|
||
isPrimary: true,
|
||
onClick: function() {
|
||
EasyPayCheckoutEditor.saveSettings(attributes);
|
||
}
|
||
}, easypayEditor.strings.saveSettings)
|
||
)
|
||
),
|
||
|
||
// Block Content (编辑器中显示的内容)
|
||
el('div', {
|
||
className: 'easypay-checkout-editor-block'
|
||
},
|
||
el('h3', {}, easypayEditor.strings.layoutSettings),
|
||
el('p', {}, '当前布局: ' + easypayEditor.layouts[layout]),
|
||
el('div', {
|
||
id: 'easypay-layout-preview',
|
||
className: 'easypay-layout-preview'
|
||
}, '加载预览中...')
|
||
)
|
||
);
|
||
},
|
||
|
||
save: function() {
|
||
// 这个区块不在前端渲染,返回null
|
||
return null;
|
||
}
|
||
});
|
||
},
|
||
|
||
/**
|
||
* Bind events
|
||
*/
|
||
bindEvents: function() {
|
||
// 当页面加载完成时初始化预览
|
||
$(document).ready(function() {
|
||
EasyPayCheckoutEditor.previewLayout(easypayEditor.currentLayout);
|
||
});
|
||
},
|
||
|
||
/**
|
||
* Preview layout
|
||
*
|
||
* @param {string} layout Layout type
|
||
*/
|
||
previewLayout: function(layout) {
|
||
const $preview = $('#easypay-layout-preview');
|
||
|
||
if ($preview.length === 0) {
|
||
return;
|
||
}
|
||
|
||
$preview.html('<div class="easypay-loading">加载预览中...</div>');
|
||
|
||
$.ajax({
|
||
url: easypayEditor.ajaxUrl,
|
||
type: 'POST',
|
||
data: {
|
||
action: 'easypay_preview_layout',
|
||
layout: layout,
|
||
nonce: easypayEditor.nonce
|
||
},
|
||
success: function(response) {
|
||
if (response.success) {
|
||
$preview.html(response.data.html);
|
||
EasyPayCheckoutEditor.animatePreview($preview);
|
||
} else {
|
||
$preview.html('<div class="easypay-error">预览加载失败: ' + response.data + '</div>');
|
||
}
|
||
},
|
||
error: function() {
|
||
$preview.html('<div class="easypay-error">预览加载失败,请检查网络连接</div>');
|
||
}
|
||
});
|
||
},
|
||
|
||
/**
|
||
* Animate preview
|
||
*
|
||
* @param {jQuery} $preview Preview element
|
||
*/
|
||
animatePreview: function($preview) {
|
||
$preview.hide().fadeIn(300);
|
||
},
|
||
|
||
/**
|
||
* Save settings
|
||
*
|
||
* @param {Object} attributes Block attributes
|
||
*/
|
||
saveSettings: function(attributes) {
|
||
const $button = $('.components-button.is-primary');
|
||
const originalText = $button.text();
|
||
|
||
$button.text('保存中...').prop('disabled', true);
|
||
|
||
$.ajax({
|
||
url: easypayEditor.ajaxUrl,
|
||
type: 'POST',
|
||
data: {
|
||
action: 'easypay_save_layout_settings',
|
||
layout: attributes.layout,
|
||
showIcons: attributes.showIcons,
|
||
enableAnimations: attributes.enableAnimations,
|
||
customClass: attributes.customClass,
|
||
nonce: easypayEditor.nonce
|
||
},
|
||
success: function(response) {
|
||
if (response.success) {
|
||
$button.text('已保存').removeClass('is-primary').addClass('is-secondary');
|
||
setTimeout(function() {
|
||
$button.text(originalText).removeClass('is-secondary').addClass('is-primary').prop('disabled', false);
|
||
}, 2000);
|
||
} else {
|
||
alert('保存失败: ' + response.data);
|
||
$button.text(originalText).prop('disabled', false);
|
||
}
|
||
},
|
||
error: function() {
|
||
alert('保存失败,请检查网络连接');
|
||
$button.text(originalText).prop('disabled', false);
|
||
}
|
||
});
|
||
}
|
||
};
|
||
|
||
/**
|
||
* Layout Preview Manager
|
||
*/
|
||
const LayoutPreviewManager = {
|
||
|
||
/**
|
||
* Initialize preview manager
|
||
*/
|
||
init: function() {
|
||
this.bindLayoutSwitcher();
|
||
this.initResponsivePreview();
|
||
},
|
||
|
||
/**
|
||
* Bind layout switcher
|
||
*/
|
||
bindLayoutSwitcher: function() {
|
||
$(document).on('change', '.easypay-layout-switcher', function() {
|
||
const layout = $(this).val();
|
||
EasyPayCheckoutEditor.previewLayout(layout);
|
||
});
|
||
},
|
||
|
||
/**
|
||
* Initialize responsive preview
|
||
*/
|
||
initResponsivePreview: function() {
|
||
const $preview = $('.easypay-layout-preview');
|
||
|
||
if ($preview.length === 0) {
|
||
return;
|
||
}
|
||
|
||
// 添加响应式预览按钮
|
||
const responsiveButtons = `
|
||
<div class="easypay-responsive-controls">
|
||
<button class="easypay-preview-desktop active" data-width="100%">桌面</button>
|
||
<button class="easypay-preview-tablet" data-width="768px">平板</button>
|
||
<button class="easypay-preview-mobile" data-width="375px">手机</button>
|
||
</div>
|
||
`;
|
||
|
||
$preview.before(responsiveButtons);
|
||
|
||
// 绑定响应式预览事件
|
||
$(document).on('click', '.easypay-responsive-controls button', function() {
|
||
const $this = $(this);
|
||
const width = $this.data('width');
|
||
|
||
$this.addClass('active').siblings().removeClass('active');
|
||
|
||
$preview.css({
|
||
'max-width': width,
|
||
'margin': '0 auto',
|
||
'border': width !== '100%' ? '1px solid #ddd' : 'none',
|
||
'transition': 'all 0.3s ease'
|
||
});
|
||
});
|
||
}
|
||
};
|
||
|
||
/**
|
||
* Accessibility Enhancements
|
||
*/
|
||
const AccessibilityEnhancements = {
|
||
|
||
/**
|
||
* Initialize accessibility features
|
||
*/
|
||
init: function() {
|
||
this.addKeyboardNavigation();
|
||
this.addAriaLabels();
|
||
this.addFocusManagement();
|
||
},
|
||
|
||
/**
|
||
* Add keyboard navigation
|
||
*/
|
||
addKeyboardNavigation: function() {
|
||
$(document).on('keydown', '.easypay-layout-preview', function(e) {
|
||
if (e.key === 'Enter' || e.key === ' ') {
|
||
e.preventDefault();
|
||
$(this).find('.wc-block-components-radio-control-accordion-option:first').click();
|
||
}
|
||
});
|
||
},
|
||
|
||
/**
|
||
* Add ARIA labels
|
||
*/
|
||
addAriaLabels: function() {
|
||
$('.easypay-layout-preview').attr({
|
||
'role': 'region',
|
||
'aria-label': '支付方法布局预览'
|
||
});
|
||
|
||
$('.easypay-responsive-controls button').each(function() {
|
||
$(this).attr('aria-label', '切换到' + $(this).text() + '预览模式');
|
||
});
|
||
},
|
||
|
||
/**
|
||
* Add focus management
|
||
*/
|
||
addFocusManagement: function() {
|
||
$(document).on('click', '.easypay-responsive-controls button', function() {
|
||
$(this).focus();
|
||
});
|
||
}
|
||
};
|
||
|
||
// 初始化所有组件
|
||
$(document).ready(function() {
|
||
EasyPayCheckoutEditor.init();
|
||
LayoutPreviewManager.init();
|
||
AccessibilityEnhancements.init();
|
||
});
|
||
|
||
})(jQuery); |