feat(user-center): redesign sidebar and wallet tips
This commit is contained in:
@@ -149,8 +149,12 @@ export const pageSchema = {
|
||||
{ key: 'post_copyright_enabled', label: '版权信息', type: 'switch', default: true },
|
||||
{ key: 'post_copyright_text', label: '版权默认文案', type: 'textarea', default: '', help: '留空则自动生成"本文由 XX 原创发布"' },
|
||||
{ key: 'post_button_toptext', label: '按钮上方文案', type: 'input', default: '喜欢就支持一下吧', help: '显示在点赞/打赏/分享按钮上方' },
|
||||
{ key: 'post_rewards_s', label: '用户打赏', type: 'switch', default: false, help: '开启后用户可配置微信/支付宝收款码;无码则不显示按钮。' },
|
||||
{ key: 'post_rewards_s', label: '用户打赏', type: 'switch', default: false, help: '开启后,登录用户可使用站内余额赞赏作者,金额直接进入作者余额。' },
|
||||
{ key: 'post_rewards_text', label: '打赏按钮文案', type: 'input', default: '赞赏', dependsOn: { key: 'post_rewards_s', value: true } },
|
||||
{ key: 'post_rewards_amounts', label: '快捷金额', type: 'input', default: '5,10,20,50,100', help: '使用英文逗号分隔', dependsOn: { key: 'post_rewards_s', value: true } },
|
||||
{ key: 'post_rewards_custom', label: '允许自定义金额', type: 'switch', default: true, dependsOn: { key: 'post_rewards_s', value: true } },
|
||||
{ key: 'post_rewards_min', label: '最低金额', type: 'number', default: 1, min: 0.01, max: 1000, step: 0.01, dependsOn: { key: 'post_rewards_s', value: true } },
|
||||
{ key: 'post_rewards_max', label: '最高金额', type: 'number', default: 1000, min: 1, max: 100000, step: 0.01, dependsOn: { key: 'post_rewards_s', value: true } },
|
||||
{ key: 'article_maxheight_kg', label: '正文限高', type: 'switch', default: false, help: '开启后长文默认折叠,可展开全文' },
|
||||
{ key: 'article_maxheight', label: '限高像素', type: 'number', default: 1000, min: 200, max: 5000, dependsOn: { key: 'article_maxheight_kg', value: true } },
|
||||
],
|
||||
|
||||
@@ -197,3 +197,64 @@
|
||||
background: var(--surface-3, #ECEEF1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
.reward-modal__content > p {
|
||||
margin: -4px 0 18px;
|
||||
}
|
||||
|
||||
.reward-amounts {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||
gap: 10px;
|
||||
margin: 18px 0;
|
||||
}
|
||||
|
||||
.reward-amount {
|
||||
min-height: 42px;
|
||||
border: 1px solid var(--color-line-soft, rgba(15, 23, 42, 0.1));
|
||||
border-radius: 10px;
|
||||
background: var(--surface-2);
|
||||
color: var(--color-ink-2);
|
||||
cursor: pointer;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.reward-amount.is-active {
|
||||
border-color: var(--color-primary);
|
||||
background: var(--color-primary-soft);
|
||||
color: var(--color-primary);
|
||||
}
|
||||
|
||||
.reward-custom {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 12px;
|
||||
margin-bottom: 16px;
|
||||
color: var(--color-ink-3);
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.reward-custom input {
|
||||
width: 140px;
|
||||
min-height: 40px;
|
||||
border: 1px solid var(--color-line-soft, rgba(15, 23, 42, 0.1));
|
||||
border-radius: 9px;
|
||||
background: var(--surface-1);
|
||||
color: var(--color-ink);
|
||||
padding: 0 12px;
|
||||
}
|
||||
|
||||
.reward-modal__submit {
|
||||
width: 100%;
|
||||
min-height: 42px;
|
||||
}
|
||||
|
||||
.reward-modal__message {
|
||||
min-height: 20px;
|
||||
margin-top: 10px;
|
||||
color: var(--color-primary);
|
||||
font-size: 12px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
@@ -380,3 +380,261 @@ body.aksrt-user-center .uc-content,
|
||||
padding-top: 18px;
|
||||
border-top: 1px solid var(--color-line-soft, rgba(0,0,0,0.06));
|
||||
}
|
||||
|
||||
|
||||
/* ==================== 侧栏账户仪表盘 ==================== */
|
||||
.uc-sidebar__section--stats {
|
||||
padding: 8px 10px;
|
||||
}
|
||||
|
||||
.uc-sidebar__heading {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 12px;
|
||||
margin-bottom: 14px;
|
||||
color: var(--color-ink, #172033);
|
||||
font-size: 14px;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.uc-sidebar__heading > a {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 5px;
|
||||
color: var(--color-ink-4);
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.uc-sidebar__heading > a:hover {
|
||||
color: var(--color-primary);
|
||||
}
|
||||
|
||||
.uc-stats {
|
||||
grid-template-columns: repeat(4, minmax(0, 1fr));
|
||||
gap: 0;
|
||||
}
|
||||
|
||||
.uc-stats__item {
|
||||
position: relative;
|
||||
gap: 2px;
|
||||
padding: 8px 2px;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.uc-stats__item + .uc-stats__item::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 12px;
|
||||
bottom: 12px;
|
||||
left: 0;
|
||||
width: 1px;
|
||||
background: var(--color-line-soft, rgba(15, 23, 42, 0.07));
|
||||
}
|
||||
|
||||
.uc-stats__item:hover {
|
||||
background: var(--surface-2);
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.uc-stats__value {
|
||||
color: var(--color-ink, #172033);
|
||||
font-size: 17px;
|
||||
letter-spacing: -0.02em;
|
||||
}
|
||||
|
||||
.uc-stats__label {
|
||||
margin: 0;
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
.uc-order-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(5, minmax(0, 1fr));
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.uc-order-grid__item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 7px;
|
||||
min-width: 0;
|
||||
padding: 5px 0 2px;
|
||||
color: var(--color-ink-3);
|
||||
font-size: 11px;
|
||||
text-align: center;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.uc-order-grid__item:hover {
|
||||
color: var(--color-primary);
|
||||
}
|
||||
|
||||
.uc-order-grid__icon {
|
||||
position: relative;
|
||||
display: grid;
|
||||
place-items: center;
|
||||
width: 38px;
|
||||
height: 38px;
|
||||
border-radius: 13px;
|
||||
background: color-mix(in srgb, var(--color-primary) 9%, var(--surface-2));
|
||||
color: var(--color-primary);
|
||||
font-size: 16px;
|
||||
transition: transform 0.2s ease, background-color 0.2s ease;
|
||||
}
|
||||
|
||||
.uc-order-grid__item:nth-child(2) .uc-order-grid__icon { color: #a56b10; background: rgba(245, 158, 11, 0.12); }
|
||||
.uc-order-grid__item:nth-child(3) .uc-order-grid__icon { color: #15806c; background: rgba(16, 185, 129, 0.12); }
|
||||
.uc-order-grid__item:nth-child(4) .uc-order-grid__icon { color: #7c4ed8; background: rgba(139, 92, 246, 0.12); }
|
||||
.uc-order-grid__item:nth-child(5) .uc-order-grid__icon { color: #d04b65; background: rgba(244, 63, 94, 0.11); }
|
||||
|
||||
.uc-order-grid__item:hover .uc-order-grid__icon {
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
.uc-order-grid__icon small,
|
||||
.uc-service-grid__icon small {
|
||||
position: absolute;
|
||||
top: -5px;
|
||||
right: -7px;
|
||||
display: grid;
|
||||
place-items: center;
|
||||
min-width: 17px;
|
||||
height: 17px;
|
||||
padding: 0 4px;
|
||||
border: 2px solid var(--surface-1);
|
||||
border-radius: 99px;
|
||||
background: var(--color-error, #ef4444);
|
||||
color: #fff;
|
||||
font-size: 9px;
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.uc-sidebar__pair {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.uc-summary-card,
|
||||
.uc-center-card {
|
||||
min-width: 0;
|
||||
border: 1px solid var(--color-line-soft, rgba(15, 23, 42, 0.06));
|
||||
border-radius: var(--main-radius, var(--radius, 8px));
|
||||
background: var(--surface-1);
|
||||
box-shadow: 0 1px 4px rgba(15, 23, 42, 0.04);
|
||||
color: var(--color-ink-2);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.uc-summary-card {
|
||||
padding: 14px;
|
||||
}
|
||||
|
||||
.uc-summary-card__head,
|
||||
.uc-summary-card__body {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.uc-summary-card__head {
|
||||
margin-bottom: 10px;
|
||||
color: var(--color-ink-4);
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.uc-summary-card__body strong {
|
||||
overflow: hidden;
|
||||
font-size: 18px;
|
||||
font-variant-numeric: tabular-nums;
|
||||
letter-spacing: -0.02em;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.uc-summary-card__body > i {
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.uc-summary-card--wallet .uc-summary-card__body { color: #3978d6; }
|
||||
.uc-summary-card--points .uc-summary-card__body { color: #ba7a0a; }
|
||||
|
||||
.uc-center-card {
|
||||
display: grid;
|
||||
grid-template-columns: auto minmax(0, 1fr) auto;
|
||||
align-items: center;
|
||||
gap: 9px;
|
||||
padding: 13px 12px;
|
||||
}
|
||||
|
||||
.uc-center-card__icon {
|
||||
display: grid;
|
||||
place-items: center;
|
||||
width: 34px;
|
||||
height: 34px;
|
||||
border-radius: 12px;
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
.uc-center-card strong,
|
||||
.uc-center-card small {
|
||||
display: block;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.uc-center-card strong { font-size: 13px; }
|
||||
.uc-center-card small { margin-top: 3px; color: var(--color-ink-4); font-size: 10px; }
|
||||
.uc-center-card > i { color: var(--color-ink-4); font-size: 11px; }
|
||||
.uc-center-card--creation .uc-center-card__icon { color: #6650c7; background: rgba(124, 92, 220, 0.12); }
|
||||
.uc-center-card--promotion .uc-center-card__icon { color: #ce6b35; background: rgba(234, 112, 55, 0.12); }
|
||||
|
||||
.uc-service-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.uc-service-grid__item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 7px;
|
||||
min-width: 0;
|
||||
padding: 4px 2px;
|
||||
color: var(--color-ink-3);
|
||||
font-size: 11px;
|
||||
text-align: center;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.uc-service-grid__icon {
|
||||
position: relative;
|
||||
display: grid;
|
||||
place-items: center;
|
||||
width: 38px;
|
||||
height: 38px;
|
||||
border-radius: 14px;
|
||||
background: var(--surface-2);
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.uc-service-grid__item--cart .uc-service-grid__icon { color: #dd6941; background: rgba(238, 109, 61, 0.12); }
|
||||
.uc-service-grid__item--level .uc-service-grid__icon { color: #9b6b0a; background: rgba(234, 179, 8, 0.13); }
|
||||
.uc-service-grid__item--auth .uc-service-grid__icon { color: #287bc4; background: rgba(14, 165, 233, 0.12); }
|
||||
.uc-service-grid__item--notice .uc-service-grid__icon { color: #d04b65; background: rgba(244, 63, 94, 0.11); }
|
||||
.uc-service-grid__item--profile .uc-service-grid__icon { color: #6550c7; background: rgba(124, 92, 220, 0.12); }
|
||||
.uc-service-grid__item--security .uc-service-grid__icon { color: #16816c; background: rgba(16, 185, 129, 0.12); }
|
||||
|
||||
.uc-service-grid__item:hover {
|
||||
color: var(--color-primary);
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.uc-order-grid__icon { transition: none; }
|
||||
}
|
||||
|
||||
+82
-23
@@ -1,55 +1,114 @@
|
||||
/**
|
||||
* Reward (打赏) — per-user QR modal openers.
|
||||
* On-site wallet tipping modal.
|
||||
*
|
||||
* @package AKSRT
|
||||
*/
|
||||
;(function () {
|
||||
'use strict';
|
||||
|
||||
var cfg = window.aksrtData || {};
|
||||
|
||||
function initReward() {
|
||||
var activeTrigger = null;
|
||||
|
||||
function closeAll() {
|
||||
document.querySelectorAll('.reward-modal.is-open').forEach(function (m) {
|
||||
m.classList.remove('is-open');
|
||||
m.setAttribute('aria-hidden', 'true');
|
||||
document.querySelectorAll('.reward-modal.is-open').forEach(function (modal) {
|
||||
modal.classList.remove('is-open');
|
||||
modal.setAttribute('aria-hidden', 'true');
|
||||
});
|
||||
document.body.style.overflow = '';
|
||||
if (activeTrigger) activeTrigger.focus();
|
||||
activeTrigger = null;
|
||||
}
|
||||
|
||||
function openForUser(userId) {
|
||||
var id = String(userId || '');
|
||||
var modal = id
|
||||
? document.getElementById('reward-modal-' + id)
|
||||
: document.querySelector('.reward-modal');
|
||||
function open(trigger) {
|
||||
var userId = trigger.getAttribute('data-user-id') || '';
|
||||
var modal = document.getElementById('reward-modal-' + userId);
|
||||
if (!modal) return;
|
||||
closeAll();
|
||||
activeTrigger = trigger;
|
||||
modal.dataset.postId = trigger.getAttribute('data-post-id') || modal.dataset.postId || '0';
|
||||
modal.classList.add('is-open');
|
||||
modal.setAttribute('aria-hidden', 'false');
|
||||
document.body.style.overflow = 'hidden';
|
||||
var first = modal.querySelector('[data-reward-amount], [data-aksrt-reward-custom]');
|
||||
if (first) first.focus();
|
||||
}
|
||||
|
||||
document.querySelectorAll('[data-aksrt-reward-open]').forEach(function (el) {
|
||||
el.addEventListener('click', function (e) {
|
||||
e.preventDefault();
|
||||
openForUser(el.getAttribute('data-user-id') || '');
|
||||
});
|
||||
});
|
||||
document.addEventListener('click', function (event) {
|
||||
var opener = event.target.closest('[data-aksrt-reward-open]');
|
||||
if (opener) {
|
||||
event.preventDefault();
|
||||
open(opener);
|
||||
return;
|
||||
}
|
||||
|
||||
document.querySelectorAll('[data-aksrt-reward-close]').forEach(function (el) {
|
||||
el.addEventListener('click', function (e) {
|
||||
e.preventDefault();
|
||||
if (event.target.closest('[data-aksrt-reward-close]')) {
|
||||
event.preventDefault();
|
||||
closeAll();
|
||||
return;
|
||||
}
|
||||
|
||||
var amountButton = event.target.closest('[data-reward-amount]');
|
||||
if (amountButton) {
|
||||
var modal = amountButton.closest('.reward-modal');
|
||||
modal.querySelectorAll('[data-reward-amount]').forEach(function (button) {
|
||||
button.classList.toggle('is-active', button === amountButton);
|
||||
});
|
||||
var custom = modal.querySelector('[data-aksrt-reward-custom]');
|
||||
if (custom) custom.value = '';
|
||||
return;
|
||||
}
|
||||
|
||||
var submit = event.target.closest('[data-aksrt-reward-submit]');
|
||||
if (!submit || submit.disabled) return;
|
||||
var tipModal = submit.closest('.reward-modal');
|
||||
var message = tipModal.querySelector('[data-aksrt-reward-message]');
|
||||
var customInput = tipModal.querySelector('[data-aksrt-reward-custom]');
|
||||
var selected = tipModal.querySelector('[data-reward-amount].is-active');
|
||||
var amount = customInput && customInput.value ? customInput.value : (selected ? selected.dataset.rewardAmount : '');
|
||||
|
||||
submit.disabled = true;
|
||||
submit.textContent = '赞赏中…';
|
||||
if (message) message.textContent = '';
|
||||
|
||||
var body = new URLSearchParams();
|
||||
body.set('action', 'aksrt_submit_tip');
|
||||
body.set('nonce', cfg.nonce || '');
|
||||
body.set('recipient_id', tipModal.dataset.userId || '');
|
||||
body.set('post_id', tipModal.dataset.postId || '0');
|
||||
body.set('amount', amount);
|
||||
|
||||
fetch(cfg.ajaxUrl || '/wp-admin/admin-ajax.php', {
|
||||
method: 'POST',
|
||||
credentials: 'same-origin',
|
||||
headers: { 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8' },
|
||||
body: body.toString()
|
||||
}).then(function (response) {
|
||||
return response.json();
|
||||
}).then(function (response) {
|
||||
var text = response && response.data && response.data.message ? response.data.message : '赞赏失败';
|
||||
if (response && response.success) {
|
||||
if (message) message.textContent = text;
|
||||
setTimeout(closeAll, 900);
|
||||
} else if (message) {
|
||||
message.textContent = text;
|
||||
}
|
||||
}).catch(function () {
|
||||
if (message) message.textContent = '网络错误,请稍后重试';
|
||||
}).finally(function () {
|
||||
submit.disabled = false;
|
||||
submit.textContent = '余额赞赏';
|
||||
});
|
||||
});
|
||||
|
||||
document.addEventListener('keydown', function (e) {
|
||||
if (e.key === 'Escape') closeAll();
|
||||
document.addEventListener('keydown', function (event) {
|
||||
if (event.key === 'Escape') closeAll();
|
||||
});
|
||||
}
|
||||
|
||||
if (window.AksrtFrontend && typeof window.AksrtFrontend.register === 'function') {
|
||||
window.AksrtFrontend.register('aksrt-reward', function () {
|
||||
initReward();
|
||||
});
|
||||
window.AksrtFrontend.register('aksrt-reward', initReward);
|
||||
} else if (document.readyState === 'loading') {
|
||||
document.addEventListener('DOMContentLoaded', initReward);
|
||||
} else {
|
||||
|
||||
@@ -121,80 +121,6 @@
|
||||
|
||||
/* ==================== 个人信息保存 ==================== */
|
||||
|
||||
/* ==================== 打赏收款码上传 ==================== */
|
||||
function initRewardQrUpload() {
|
||||
var form = document.getElementById('profile-form');
|
||||
if (!form) return;
|
||||
var nonceInput = form.querySelector('input[name="_profile_nonce"]');
|
||||
var nonce = nonceInput ? nonceInput.value : '';
|
||||
|
||||
function setPreview(kind, url) {
|
||||
var box = form.querySelector('[data-reward-preview="' + kind + '"]');
|
||||
if (!box) return;
|
||||
if (url) {
|
||||
box.innerHTML = '<img src="' + url + '" alt="" />';
|
||||
} else {
|
||||
box.innerHTML = '<span class="muted-2-color em09">未上传</span>';
|
||||
}
|
||||
}
|
||||
|
||||
form.querySelectorAll('[data-reward-upload]').forEach(function (btn) {
|
||||
btn.addEventListener('click', function () {
|
||||
var kind = btn.getAttribute('data-reward-upload');
|
||||
var fileInput = form.querySelector('input[data-reward-kind="' + kind + '"]');
|
||||
if (fileInput) fileInput.click();
|
||||
});
|
||||
});
|
||||
|
||||
form.querySelectorAll('[data-reward-clear]').forEach(function (btn) {
|
||||
btn.addEventListener('click', function () {
|
||||
var kind = btn.getAttribute('data-reward-clear');
|
||||
var hidden = form.querySelector('#rewards-' + kind);
|
||||
var fileInput = form.querySelector('input[data-reward-kind="' + kind + '"]');
|
||||
if (hidden) hidden.value = '';
|
||||
if (fileInput) fileInput.value = '';
|
||||
setPreview(kind, '');
|
||||
});
|
||||
});
|
||||
|
||||
form.querySelectorAll('input[data-reward-kind]').forEach(function (input) {
|
||||
input.addEventListener('change', function () {
|
||||
var kind = input.getAttribute('data-reward-kind');
|
||||
var file = input.files && input.files[0];
|
||||
if (!file || !kind) return;
|
||||
if (file.size > 2 * 1024 * 1024) {
|
||||
showToast('图片不能超过 2MB');
|
||||
input.value = '';
|
||||
return;
|
||||
}
|
||||
var body = new FormData();
|
||||
body.append('action', 'aksrt_upload_reward_qr');
|
||||
body.append('_profile_nonce', nonce);
|
||||
body.append('kind', kind);
|
||||
body.append('file', file);
|
||||
showToast(i18n.saving || '上传中…');
|
||||
fetch(ajaxUrl, { method: 'POST', body: body, credentials: 'same-origin' })
|
||||
.then(function (r) { return r.json(); })
|
||||
.then(function (res) {
|
||||
if (res && res.success && res.data) {
|
||||
var hidden = form.querySelector('#rewards-' + kind);
|
||||
if (hidden) hidden.value = String(res.data.id || '');
|
||||
setPreview(kind, res.data.url || '');
|
||||
showToast(res.data.message || '上传成功');
|
||||
} else {
|
||||
showToast((res && res.data && res.data.message) || '上传失败');
|
||||
}
|
||||
})
|
||||
.catch(function () {
|
||||
showToast(i18n.networkError || '网络错误');
|
||||
})
|
||||
.finally(function () {
|
||||
input.value = '';
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function initProfileForm() {
|
||||
var form = document.getElementById('profile-form');
|
||||
@@ -752,7 +678,6 @@
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
initDashboardNavigation();
|
||||
initProfileForm();
|
||||
initRewardQrUpload();
|
||||
initUnfavorite();
|
||||
initNotifications();
|
||||
initSettings();
|
||||
@@ -760,7 +685,6 @@
|
||||
} else {
|
||||
initDashboardNavigation();
|
||||
initProfileForm();
|
||||
initRewardQrUpload();
|
||||
initUnfavorite();
|
||||
initNotifications();
|
||||
initSettings();
|
||||
|
||||
@@ -91,9 +91,12 @@ if (!function_exists('aksrt_resolve_single_post_display_settings')) :
|
||||
'authordesc' => true,
|
||||
'hide_time' => false,
|
||||
'rewards_enabled' => false,
|
||||
'rewards_image' => '',
|
||||
'rewards_text' => '',
|
||||
'rewards_btn_text' => '赞赏',
|
||||
'rewards_amounts' => [5, 10, 20, 50, 100],
|
||||
'rewards_custom' => true,
|
||||
'rewards_min' => 1,
|
||||
'rewards_max' => 1000,
|
||||
'maxheight_enabled' => false,
|
||||
'maxheight' => 1000,
|
||||
'copyright_enabled' => true,
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
<?php
|
||||
/**
|
||||
* Per-user tip (打赏) helpers — Zibll post_rewards_s + user QR parity.
|
||||
*
|
||||
* Meta: aksrt_rewards_weixin, aksrt_rewards_alipay (attachment id or URL).
|
||||
* On-site wallet tipping helpers.
|
||||
*
|
||||
* @package AKSRT
|
||||
*/
|
||||
@@ -11,103 +9,125 @@ defined('ABSPATH') || exit;
|
||||
|
||||
if (!function_exists('aksrt_rewards_enabled')) {
|
||||
function aksrt_rewards_enabled(): bool {
|
||||
if (!class_exists('\AKSRT\Settings\Settings') || !method_exists('\AKSRT\Settings\Settings', 'get_post_page_settings')) {
|
||||
if (!class_exists('\AKSRT\Settings\Settings')) {
|
||||
return false;
|
||||
}
|
||||
$s = \AKSRT\Settings\Settings::get_post_page_settings();
|
||||
return !empty($s['rewards_enabled']) || !empty($s['post_rewards_s']);
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('aksrt_get_user_rewards_img_urls')) {
|
||||
/**
|
||||
* @return array{weixin:string,alipay:string}
|
||||
*/
|
||||
function aksrt_get_user_rewards_img_urls(int $user_id): array {
|
||||
$out = ['weixin' => '', 'alipay' => ''];
|
||||
if ($user_id <= 0) {
|
||||
return $out;
|
||||
}
|
||||
foreach (['weixin' => 'aksrt_rewards_weixin', 'alipay' => 'aksrt_rewards_alipay'] as $key => $meta) {
|
||||
$raw = get_user_meta($user_id, $meta, true);
|
||||
if (is_numeric($raw) && (int) $raw > 0) {
|
||||
$url = wp_get_attachment_image_url((int) $raw, 'full');
|
||||
$out[$key] = is_string($url) ? $url : '';
|
||||
} else {
|
||||
$out[$key] = esc_url_raw((string) $raw);
|
||||
}
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('aksrt_user_has_rewards_qr')) {
|
||||
function aksrt_user_has_rewards_qr(int $user_id): bool {
|
||||
$urls = aksrt_get_user_rewards_img_urls($user_id);
|
||||
return $urls['weixin'] !== '' || $urls['alipay'] !== '';
|
||||
$settings = \AKSRT\Settings\Settings::get_post_page_settings();
|
||||
return !empty($settings['rewards_enabled']);
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('aksrt_get_rewards_button')) {
|
||||
function aksrt_get_rewards_button(int $user_id, string $class = 'but jb-blue ml10 pw-1em'): string {
|
||||
if ($user_id <= 0 || !aksrt_rewards_enabled() || !aksrt_user_has_rewards_qr($user_id)) {
|
||||
function aksrt_get_rewards_button(int $user_id, string $class = 'but jb-blue ml10 pw-1em', int $post_id = 0): string {
|
||||
if ($user_id <= 0 || !aksrt_rewards_enabled()) {
|
||||
return '';
|
||||
}
|
||||
$label = '赞赏';
|
||||
if (class_exists('\AKSRT\Settings\Settings') && method_exists('\AKSRT\Settings\Settings', 'get_post_page_settings')) {
|
||||
$s = \AKSRT\Settings\Settings::get_post_page_settings();
|
||||
$label = (string) ($s['rewards_btn_text'] ?? $s['rewards_text'] ?? $label);
|
||||
if ($label === '') {
|
||||
$label = '赞赏';
|
||||
}
|
||||
}
|
||||
return '<button type="button" class="' . esc_attr($class) . ' aksrt-reward-open" data-aksrt-reward-open data-user-id="' . (int) $user_id . '"><i class="fa fa-gift em09" aria-hidden="true"></i> ' . esc_html($label) . '</button>';
|
||||
$settings = \AKSRT\Settings\Settings::get_post_page_settings();
|
||||
$label = (string) ($settings['rewards_btn_text'] ?? __('赞赏', 'aksrt'));
|
||||
return sprintf(
|
||||
'<button type="button" class="%1$s aksrt-reward-open" data-aksrt-reward-open data-user-id="%2$d" data-post-id="%3$d"><i class="fa fa-gift em09" aria-hidden="true"></i> <span class="action-btn__label">%4$s</span></button>',
|
||||
esc_attr($class),
|
||||
$user_id,
|
||||
$post_id,
|
||||
esc_html($label)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('aksrt_render_rewards_modal_for_user')) {
|
||||
function aksrt_render_rewards_modal_for_user(int $user_id): void {
|
||||
function aksrt_render_rewards_modal_for_user(int $user_id, int $post_id = 0): void {
|
||||
static $done = [];
|
||||
if ($user_id <= 0 || isset($done[$user_id])) {
|
||||
$key = $user_id . ':' . $post_id;
|
||||
if ($user_id <= 0 || isset($done[$key]) || !aksrt_rewards_enabled()) {
|
||||
return;
|
||||
}
|
||||
if (!aksrt_rewards_enabled() || !aksrt_user_has_rewards_qr($user_id)) {
|
||||
return;
|
||||
}
|
||||
$done[$user_id] = true;
|
||||
$urls = aksrt_get_user_rewards_img_urls($user_id);
|
||||
$label = '赞赏';
|
||||
if (class_exists('\AKSRT\Settings\Settings') && method_exists('\AKSRT\Settings\Settings', 'get_post_page_settings')) {
|
||||
$s = \AKSRT\Settings\Settings::get_post_page_settings();
|
||||
$label = (string) ($s['rewards_text'] ?? $label);
|
||||
if ($label === '') {
|
||||
$label = __('赞赏', 'aksrt');
|
||||
}
|
||||
}
|
||||
$done[$key] = true;
|
||||
$settings = \AKSRT\Settings\Settings::get_post_page_settings();
|
||||
$amounts = (array) ($settings['rewards_amounts'] ?? [5, 10, 20, 50, 100]);
|
||||
$recipient = get_userdata($user_id);
|
||||
?>
|
||||
<div class="reward-modal" id="reward-modal-<?php echo (int) $user_id; ?>" data-user-id="<?php echo (int) $user_id; ?>" aria-hidden="true">
|
||||
<div class="reward-modal" id="reward-modal-<?php echo (int) $user_id; ?>" data-user-id="<?php echo (int) $user_id; ?>" data-post-id="<?php echo (int) $post_id; ?>" aria-hidden="true">
|
||||
<div class="reward-modal__overlay" data-aksrt-reward-close></div>
|
||||
<div class="reward-modal__dialog" role="dialog" aria-modal="true">
|
||||
<div class="reward-modal__dialog" role="dialog" aria-modal="true" aria-labelledby="reward-title-<?php echo (int) $user_id; ?>">
|
||||
<button type="button" class="reward-modal__close" data-aksrt-reward-close aria-label="<?php esc_attr_e('关闭', 'aksrt'); ?>"><i class="fas fa-times" aria-hidden="true"></i></button>
|
||||
<div class="reward-modal__content">
|
||||
<h3><?php echo esc_html($label); ?></h3>
|
||||
<div class="reward-modal__qrcodes flex jc ac hh">
|
||||
<?php if ($urls['weixin'] !== '') : ?>
|
||||
<div class="reward-modal__qrcode text-center mr10">
|
||||
<img src="<?php echo esc_url($urls['weixin']); ?>" alt="<?php esc_attr_e('微信收款码', 'aksrt'); ?>" loading="lazy" decoding="async" />
|
||||
<div class="em09 muted-2-color mt6"><?php esc_html_e('微信', 'aksrt'); ?></div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<?php if ($urls['alipay'] !== '') : ?>
|
||||
<div class="reward-modal__qrcode text-center">
|
||||
<img src="<?php echo esc_url($urls['alipay']); ?>" alt="<?php esc_attr_e('支付宝收款码', 'aksrt'); ?>" loading="lazy" decoding="async" />
|
||||
<div class="em09 muted-2-color mt6"><?php esc_html_e('支付宝', 'aksrt'); ?></div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<h3 id="reward-title-<?php echo (int) $user_id; ?>"><?php echo esc_html((string) ($settings['rewards_text'] ?? __('赞赏', 'aksrt'))); ?></h3>
|
||||
<p class="muted-2-color em09"><?php printf(esc_html__('赞赏将直接进入 %s 的站内余额', 'aksrt'), esc_html($recipient ? $recipient->display_name : __('作者', 'aksrt'))); ?></p>
|
||||
<div class="reward-amounts" data-aksrt-reward-amounts>
|
||||
<?php foreach ($amounts as $index => $amount) : ?>
|
||||
<button type="button" class="reward-amount<?php echo $index === 0 ? ' is-active' : ''; ?>" data-reward-amount="<?php echo esc_attr(number_format((float) $amount, 2, '.', '')); ?>">¥<?php echo esc_html(number_format_i18n((float) $amount, 2)); ?></button>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php if (!empty($settings['rewards_custom'])) : ?>
|
||||
<label class="reward-custom"><span><?php esc_html_e('自定义金额', 'aksrt'); ?></span><input type="number" min="<?php echo esc_attr((string) ($settings['rewards_min'] ?? 1)); ?>" max="<?php echo esc_attr((string) ($settings['rewards_max'] ?? 1000)); ?>" step="0.01" data-aksrt-reward-custom placeholder="<?php esc_attr_e('输入金额', 'aksrt'); ?>"></label>
|
||||
<?php endif; ?>
|
||||
<button type="button" class="btn-primary reward-modal__submit" data-aksrt-reward-submit><?php esc_html_e('余额赞赏', 'aksrt'); ?></button>
|
||||
<div class="reward-modal__message" data-aksrt-reward-message role="status"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
|
||||
add_action('wp_ajax_aksrt_submit_tip', function (): void {
|
||||
check_ajax_referer('aksrt_public_nonce', 'nonce');
|
||||
if (!is_user_logged_in()) {
|
||||
wp_send_json_error(['message' => __('请先登录后赞赏', 'aksrt')], 401);
|
||||
}
|
||||
if (!aksrt_rewards_enabled() || !class_exists('\AKSRT\Credits\Balance') || !\AKSRT\Credits\Balance::enabled()) {
|
||||
wp_send_json_error(['message' => __('赞赏功能当前不可用', 'aksrt')], 400);
|
||||
}
|
||||
|
||||
$sender_id = get_current_user_id();
|
||||
$post_id = isset($_POST['post_id']) ? absint($_POST['post_id']) : 0;
|
||||
$recipient_id = isset($_POST['recipient_id']) ? absint($_POST['recipient_id']) : 0;
|
||||
if ($post_id > 0) {
|
||||
$post = get_post($post_id);
|
||||
if (!$post instanceof WP_Post || $post->post_status !== 'publish') {
|
||||
wp_send_json_error(['message' => __('赞赏内容不存在', 'aksrt')], 404);
|
||||
}
|
||||
$recipient_id = (int) $post->post_author;
|
||||
}
|
||||
if ($recipient_id <= 0 || !get_userdata($recipient_id) || $recipient_id === $sender_id) {
|
||||
wp_send_json_error(['message' => __('不能赞赏该用户', 'aksrt')], 400);
|
||||
}
|
||||
|
||||
$settings = \AKSRT\Settings\Settings::get_post_page_settings();
|
||||
$amount = isset($_POST['amount']) ? round((float) wp_unslash($_POST['amount']), 2) : 0.0;
|
||||
$minimum = (float) ($settings['rewards_min'] ?? 1);
|
||||
$maximum = (float) ($settings['rewards_max'] ?? 1000);
|
||||
if (!is_finite($amount) || $amount < $minimum || $amount > $maximum) {
|
||||
wp_send_json_error(['message' => sprintf(__('赞赏金额需在 ¥%1$s 至 ¥%2$s 之间', 'aksrt'), number_format_i18n($minimum, 2), number_format_i18n($maximum, 2))], 400);
|
||||
}
|
||||
if (empty($settings['rewards_custom'])) {
|
||||
$allowed_amounts = array_map(static fn($value): float => round((float) $value, 2), (array) ($settings['rewards_amounts'] ?? []));
|
||||
if (!in_array($amount, $allowed_amounts, true)) {
|
||||
wp_send_json_error(['message' => __('请选择预设的赞赏金额', 'aksrt')], 400);
|
||||
}
|
||||
}
|
||||
|
||||
$rate_key = 'aksrt_tip_rate_' . $sender_id;
|
||||
if (get_transient($rate_key)) {
|
||||
wp_send_json_error(['message' => __('操作太频繁,请稍后再试', 'aksrt')], 429);
|
||||
}
|
||||
set_transient($rate_key, 1, 3);
|
||||
|
||||
$result = \AKSRT\Credits\Balance::transfer(
|
||||
$sender_id,
|
||||
$recipient_id,
|
||||
$amount,
|
||||
'tip_sent',
|
||||
'tip_received',
|
||||
['type' => 'tip', 'id' => $post_id],
|
||||
$post_id > 0 ? sprintf(__('赞赏文章 #%d', 'aksrt'), $post_id) : __('用户赞赏', 'aksrt')
|
||||
);
|
||||
if (is_wp_error($result)) {
|
||||
wp_send_json_error(['message' => $result->get_error_message()], 400);
|
||||
}
|
||||
|
||||
wp_send_json_success([
|
||||
'message' => __('赞赏成功,金额已进入对方余额', 'aksrt'),
|
||||
'balance' => \AKSRT\Credits\Balance::format((float) $result['sender_balance']),
|
||||
]);
|
||||
});
|
||||
|
||||
@@ -251,26 +251,14 @@ if (!function_exists('aksrt_single_render_actions')) :
|
||||
|
||||
<?php
|
||||
$reward_author = (int) get_the_author_meta('ID');
|
||||
$reward_btn = ($reward_author > 0 && function_exists('aksrt_get_rewards_button'))
|
||||
? aksrt_get_rewards_button($reward_author, 'action action-rewards')
|
||||
$reward_btn = ($reward_author > 0 && !empty($settings['rewards_enabled']) && function_exists('aksrt_get_rewards_button'))
|
||||
? aksrt_get_rewards_button($reward_author, 'action action-rewards', $post_id)
|
||||
: '';
|
||||
if ($reward_btn === '' && !empty($settings['rewards_enabled']) && function_exists('aksrt_user_has_rewards_qr') && $reward_author > 0 && aksrt_user_has_rewards_qr($reward_author)) {
|
||||
$label = esc_html((string) ($settings['rewards_btn_text'] ?? __('赞赏', 'aksrt')));
|
||||
$reward_btn = '<button type="button" class="action action-rewards" data-aksrt-reward-open data-user-id="' . (int) $reward_author . '"><i class="fas fa-gift" aria-hidden="true"></i><span class="action-btn__label">' . $label . '</span></button>';
|
||||
}
|
||||
if ($reward_btn !== '') :
|
||||
if ($reward_btn !== '') {
|
||||
echo $reward_btn; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
if (function_exists('aksrt_render_rewards_modal_for_user')) {
|
||||
aksrt_render_rewards_modal_for_user($reward_author);
|
||||
}
|
||||
endif;
|
||||
// legacy placeholder to keep structure; actual button echoed above
|
||||
if (false) : ?>
|
||||
<button type="button" class="action action-rewards" id="action-reward">
|
||||
<i class="fas fa-gift" aria-hidden="true"></i>
|
||||
<span class="action-btn__label"><?php echo esc_html($settings['rewards_btn_text'] ?? __('赞赏', 'aksrt')); ?></span>
|
||||
</button>
|
||||
<?php endif; ?>
|
||||
aksrt_render_rewards_modal_for_user($reward_author, $post_id);
|
||||
}
|
||||
?>
|
||||
|
||||
<?php if (!empty($settings['share_enabled'])) : ?>
|
||||
<button type="button" class="action action-share" id="action-share-trigger" aria-haspopup="true" aria-expanded="false">
|
||||
@@ -293,20 +281,6 @@ if (!function_exists('aksrt_single_render_actions')) :
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<?php if (!empty($settings['rewards_enabled']) && !empty($settings['rewards_image'])) : ?>
|
||||
<div class="reward-modal" id="reward-modal" aria-hidden="true">
|
||||
<div class="reward-modal__overlay"></div>
|
||||
<div class="reward-modal__dialog">
|
||||
<button type="button" class="reward-modal__close" aria-label="<?php esc_attr_e('关闭', 'aksrt'); ?>"><i class="fas fa-times" aria-hidden="true"></i></button>
|
||||
<div class="reward-modal__content">
|
||||
<h3><?php echo esc_html((string) ($settings['rewards_text'] ?? '')); ?></h3>
|
||||
<div class="reward-modal__qrcode">
|
||||
<img src="<?php echo esc_url((string) $settings['rewards_image']); ?>" alt="<?php esc_attr_e('打赏二维码', 'aksrt'); ?>">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<?php
|
||||
}
|
||||
endif;
|
||||
@@ -484,11 +458,11 @@ if (!function_exists('aksrt_single_render_author_card')) :
|
||||
</a>
|
||||
<?php endif; ?>
|
||||
<?php
|
||||
$tip = function_exists('aksrt_get_rewards_button') ? aksrt_get_rewards_button($author_id, 'but pw-1em mr6 c-yellow') : '';
|
||||
$tip = function_exists('aksrt_get_rewards_button') ? aksrt_get_rewards_button($author_id, 'but pw-1em mr6 c-yellow', get_the_ID()) : '';
|
||||
if ($tip !== '') {
|
||||
echo $tip; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
if (function_exists('aksrt_render_rewards_modal_for_user')) {
|
||||
aksrt_render_rewards_modal_for_user($author_id);
|
||||
aksrt_render_rewards_modal_for_user($author_id, get_the_ID());
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
||||
@@ -92,30 +92,6 @@ if (!function_exists('aksrt_save_user_center_profile')) {
|
||||
|
||||
update_user_meta($user_id, 'aksrt_user_contacts', aksrt_normalize_user_contacts($input['contacts'] ?? []));
|
||||
|
||||
// Tip QR images (attachment id or URL). Empty clears.
|
||||
if (array_key_exists('rewards_weixin', $input) || array_key_exists('rewards_alipay', $input)) {
|
||||
foreach (['rewards_weixin' => 'aksrt_rewards_weixin', 'rewards_alipay' => 'aksrt_rewards_alipay'] as $field => $meta) {
|
||||
if (!array_key_exists($field, $input)) {
|
||||
continue;
|
||||
}
|
||||
$raw = is_string($input[$field]) ? trim(wp_unslash($input[$field])) : '';
|
||||
if ($raw === '' || $raw === '0') {
|
||||
delete_user_meta($user_id, $meta);
|
||||
continue;
|
||||
}
|
||||
if (ctype_digit($raw)) {
|
||||
$att = (int) $raw;
|
||||
if ($att > 0 && wp_attachment_is_image($att)) {
|
||||
update_user_meta($user_id, $meta, $att);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
$url = esc_url_raw($raw);
|
||||
if ($url !== '') {
|
||||
update_user_meta($user_id, $meta, $url);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -479,6 +455,9 @@ if (!function_exists('aksrt_get_user_center_render_context')) {
|
||||
$allow_avatar_upload = !empty($user_center_settings['avatar_upload']);
|
||||
$allow_bg_upload = !empty($user_center_settings['cover_upload']) && class_exists('\AKSRT\Settings\Settings') && aksrt_get_setting('allow_background_upload', false);
|
||||
$messages_enabled = !class_exists('\AKSRT\Settings\Settings') || \AKSRT\Settings\Settings::message_enabled();
|
||||
$follower_count = class_exists('\AKSRT\User\Follow')
|
||||
? \AKSRT\User\Follow::get_instance()->get_follower_count($user_id)
|
||||
: 0;
|
||||
|
||||
$post_status_filter = isset($_GET['post_status']) ? sanitize_key(wp_unslash($_GET['post_status'])) : 'publish';
|
||||
if (!in_array($post_status_filter, ['all', 'publish', 'draft', 'pending', 'private'], true)) {
|
||||
@@ -531,6 +510,7 @@ if (!function_exists('aksrt_get_user_center_render_context')) {
|
||||
'comment_count' => $comment_count,
|
||||
'favorite_post_ids' => $favorite_post_ids,
|
||||
'favorite_count' => $favorite_count,
|
||||
'follower_count' => $follower_count,
|
||||
'user_contacts' => $user_contacts,
|
||||
'profile_signals' => $dashboard['profile_signals'] ?? [],
|
||||
'user_background_url' => $user_background_url,
|
||||
|
||||
@@ -32,55 +32,6 @@ extract($context, EXTR_SKIP); // phpcs:ignore WordPress.PHP.DontExtract.extract_
|
||||
|
||||
<?php require __DIR__ . '/form-contacts.php'; ?>
|
||||
|
||||
<?php
|
||||
$rewards_on = function_exists('aksrt_rewards_enabled') ? aksrt_rewards_enabled() : false;
|
||||
$rw = (string) get_user_meta((int) $user_id, 'aksrt_rewards_weixin', true);
|
||||
$ra = (string) get_user_meta((int) $user_id, 'aksrt_rewards_alipay', true);
|
||||
$rw_url = '';
|
||||
$ra_url = '';
|
||||
if (function_exists('aksrt_get_user_rewards_img_urls')) {
|
||||
$urls = aksrt_get_user_rewards_img_urls((int) $user_id);
|
||||
$rw_url = (string) ($urls['weixin'] ?? '');
|
||||
$ra_url = (string) ($urls['alipay'] ?? '');
|
||||
}
|
||||
?>
|
||||
<?php if ($rewards_on) : ?>
|
||||
<div class="widget-card">
|
||||
<h3 class="widget-title"><?php esc_html_e('打赏收款码', 'aksrt'); ?></h3>
|
||||
<p class="profile-hint"><?php esc_html_e('上传微信/支付宝收款码后,读者可在文章与作者卡赞赏你。留空则不显示赞赏按钮。', 'aksrt'); ?></p>
|
||||
<div class="aksrt-reward-upload-grid">
|
||||
<div class="aksrt-reward-upload">
|
||||
<label class="aksrt-reward-upload__label"><?php esc_html_e('微信收款码', 'aksrt'); ?></label>
|
||||
<div class="aksrt-reward-upload__preview" data-reward-preview="weixin">
|
||||
<?php if ($rw_url !== '') : ?>
|
||||
<img src="<?php echo esc_url($rw_url); ?>" alt="" />
|
||||
<?php else : ?>
|
||||
<span class="muted-2-color em09"><?php esc_html_e('未上传', 'aksrt'); ?></span>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<input type="hidden" name="rewards_weixin" id="rewards-weixin" value="<?php echo esc_attr($rw); ?>" />
|
||||
<input type="file" id="rewards-weixin-file" accept="image/*" class="aksrt-reward-upload__file" data-reward-kind="weixin" />
|
||||
<button type="button" class="btn-primary btn-sm" data-reward-upload="weixin"><?php esc_html_e('选择图片', 'aksrt'); ?></button>
|
||||
<button type="button" class="btn-sm" data-reward-clear="weixin"><?php esc_html_e('清除', 'aksrt'); ?></button>
|
||||
</div>
|
||||
<div class="aksrt-reward-upload">
|
||||
<label class="aksrt-reward-upload__label"><?php esc_html_e('支付宝收款码', 'aksrt'); ?></label>
|
||||
<div class="aksrt-reward-upload__preview" data-reward-preview="alipay">
|
||||
<?php if ($ra_url !== '') : ?>
|
||||
<img src="<?php echo esc_url($ra_url); ?>" alt="" />
|
||||
<?php else : ?>
|
||||
<span class="muted-2-color em09"><?php esc_html_e('未上传', 'aksrt'); ?></span>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<input type="hidden" name="rewards_alipay" id="rewards-alipay" value="<?php echo esc_attr($ra); ?>" />
|
||||
<input type="file" id="rewards-alipay-file" accept="image/*" class="aksrt-reward-upload__file" data-reward-kind="alipay" />
|
||||
<button type="button" class="btn-primary btn-sm" data-reward-upload="alipay"><?php esc_html_e('选择图片', 'aksrt'); ?></button>
|
||||
<button type="button" class="btn-sm" data-reward-clear="alipay"><?php esc_html_e('清除', 'aksrt'); ?></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
|
||||
<div class="profile-form__submit">
|
||||
<button type="submit" class="btn-primary btn-lg" id="profile-save-btn">
|
||||
|
||||
@@ -25,27 +25,20 @@ $section = sanitize_key((string) ($_GET['section'] ?? ''));
|
||||
if ($tab === '' && isset($_GET['tab']) && sanitize_key((string) $_GET['tab']) !== 'orders') {
|
||||
// When rendered as standalone legacy include, outer tab may be status.
|
||||
$maybe = sanitize_key((string) $_GET['tab']);
|
||||
if (in_array($maybe, ['pending', 'shipped', 'received', 'review', 'after', 'wait-pay', 'wait-shipped', 'wait-receive', 'wait-evaluate', 'after-sale', 'all'], true)) {
|
||||
if (in_array($maybe, ['pending', 'to-ship', 'shipped', 'received', 'review', 'after'], true)) {
|
||||
$tab = $maybe;
|
||||
}
|
||||
}
|
||||
|
||||
$tab_aliases = [
|
||||
'wait-pay' => 'pending',
|
||||
'wait-shipped' => 'shipped',
|
||||
'wait-receive' => 'shipped',
|
||||
'wait-evaluate' => 'review',
|
||||
'after-sale' => 'after',
|
||||
'all' => '',
|
||||
];
|
||||
$tab_aliases = [];
|
||||
if (isset($tab_aliases[$tab])) {
|
||||
$tab = $tab_aliases[$tab];
|
||||
}
|
||||
|
||||
$tab_status_map = [
|
||||
'pending' => \AKSRT\Payment\Order::STATUS_PENDING,
|
||||
'to-ship' => \AKSRT\Payment\Order::STATUS_PAID,
|
||||
'shipped' => \AKSRT\Payment\Order::STATUS_DELIVERED,
|
||||
'received' => \AKSRT\Payment\Order::STATUS_COMPLETED,
|
||||
'review' => \AKSRT\Payment\Order::STATUS_PENDING_REVIEW,
|
||||
'after' => \AKSRT\Payment\Order::STATUS_REFUNDING,
|
||||
];
|
||||
@@ -70,6 +63,7 @@ $shop = class_exists('\AKSRT\Shop\Shop') ? \AKSRT\Shop\Shop::get_instance() : nu
|
||||
$tabs = [
|
||||
'' => __('全部', 'aksrt'),
|
||||
'pending' => __('待支付', 'aksrt'),
|
||||
'to-ship' => __('待发货', 'aksrt'),
|
||||
'shipped' => __('待收货', 'aksrt'),
|
||||
'review' => __('待评价', 'aksrt'),
|
||||
'after' => __('售后', 'aksrt'),
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
/**
|
||||
* User center profile sidebar part (orchestrator).
|
||||
* User center profile sidebar orchestrator.
|
||||
*
|
||||
* @package AKSRT
|
||||
*/
|
||||
@@ -11,10 +11,11 @@ $context = is_array($args['context'] ?? null) ? $args['context'] : [];
|
||||
extract($context, EXTR_SKIP); // phpcs:ignore WordPress.PHP.DontExtract.extract_extract
|
||||
|
||||
require __DIR__ . '/sidebar-stats.php';
|
||||
require __DIR__ . '/sidebar-nav.php';
|
||||
require __DIR__ . '/sidebar-creator.php';
|
||||
require __DIR__ . '/sidebar-orders.php';
|
||||
require __DIR__ . '/sidebar-commerce.php';
|
||||
require __DIR__ . '/sidebar-creator.php';
|
||||
require __DIR__ . '/sidebar-nav.php';
|
||||
?>
|
||||
<button type="button" class="uc-sidebar__drawer-trigger" id="uc-drawer-trigger" aria-label="<?php esc_attr_e('打开导航', 'aksrt'); ?>">
|
||||
<i class="fas fa-bars" aria-hidden="true"></i>
|
||||
<i class="fas fa-th-large" aria-hidden="true"></i>
|
||||
</button>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
/**
|
||||
* User center sidebar: Zibll dual asset mini cards + commerce shortcuts.
|
||||
* User center sidebar: balance and points pair.
|
||||
*
|
||||
* @package AKSRT
|
||||
*/
|
||||
@@ -8,73 +8,32 @@
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
$show_wallet = !empty($balance_enabled);
|
||||
$show_credits = !empty($show_credit_tabs) || !empty($credits_enabled);
|
||||
$wallet = (float) ($wallet_balance ?? 0.0);
|
||||
$points = (float) ($credit_balance ?? 0.0);
|
||||
$currency = (string) ($currency_name ?? __('积分', 'aksrt'));
|
||||
|
||||
if ($show_wallet || $show_credits) :
|
||||
$assets_url = function_exists('aksrt_get_user_center_tab_url')
|
||||
? aksrt_get_user_center_tab_url('credits')
|
||||
: '#';
|
||||
?>
|
||||
<div class="uc-sidebar__section">
|
||||
<div class="uc-sidebar__title"><?php esc_html_e('我的资产', 'aksrt'); ?></div>
|
||||
<div class="uc-asset-mini flex ab jsb col-ml6">
|
||||
<?php if ($show_wallet) : ?>
|
||||
<a class="uc-asset-mini__card flex1" href="<?php echo esc_url($assets_url); ?>">
|
||||
<div class="uc-asset-mini__label muted-2-color em09"><?php esc_html_e('余额', 'aksrt'); ?><i class="ml6 fa fa-angle-right em12" aria-hidden="true"></i></div>
|
||||
<div class="flex jsb ac">
|
||||
<span class="font-bold c-blue-2"><?php echo esc_html(class_exists('\AKSRT\Credits\Balance') ? \AKSRT\Credits\Balance::format($wallet) : number_format_i18n($wallet, 2)); ?></span>
|
||||
<i class="fas fa-wallet em14 c-blue-2" aria-hidden="true"></i>
|
||||
</div>
|
||||
</a>
|
||||
<?php endif; ?>
|
||||
<?php if ($show_credits) : ?>
|
||||
<a class="uc-asset-mini__card flex1" href="<?php echo esc_url($assets_url); ?>">
|
||||
<div class="uc-asset-mini__label muted-2-color em09"><?php echo esc_html($currency); ?><i class="ml6 fa fa-angle-right em12" aria-hidden="true"></i></div>
|
||||
<div class="flex jsb ac">
|
||||
<span class="font-bold c-yellow"><?php echo esc_html(function_exists('aksrt_format_credits') ? aksrt_format_credits((int) $points) : (string) (int) $points); ?></span>
|
||||
<i class="fas fa-coins em14 c-yellow" aria-hidden="true"></i>
|
||||
</div>
|
||||
</a>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
endif;
|
||||
|
||||
if (empty($orders_url) && empty($show_vip) && empty($show_credit_tabs) && empty($balance_enabled) && empty($affiliate_enabled)) {
|
||||
$show_credits = !empty($credits_enabled) || !empty($show_credit_tabs);
|
||||
if (!$show_wallet && !$show_credits) {
|
||||
return;
|
||||
}
|
||||
|
||||
$assets_url = aksrt_get_user_center_tab_url('credits');
|
||||
$wallet = (float) ($wallet_balance ?? 0);
|
||||
$points = (float) ($credit_balance ?? 0);
|
||||
?>
|
||||
<div class="uc-sidebar__section">
|
||||
<div class="uc-sidebar__title"><?php esc_html_e('权益与消费', 'aksrt'); ?></div>
|
||||
<div class="uc-sidebar__buttons">
|
||||
<?php $revenue_url = function_exists('aksrt_get_revenue_page_url') ? aksrt_get_revenue_page_url() : ''; ?>
|
||||
<?php
|
||||
$orders_href = !empty($orders_url)
|
||||
? (string) $orders_url
|
||||
: (function_exists('aksrt_get_user_center_tab_url') ? aksrt_get_user_center_tab_url('orders') : '');
|
||||
if ($orders_href !== '') :
|
||||
$orders_active = !empty($active_tab) && $active_tab === 'orders';
|
||||
?>
|
||||
<a href="<?php echo esc_url($orders_href); ?>" class="uc-sidebar__btn<?php echo $orders_active ? ' is-active' : ''; ?>" data-tab="orders">
|
||||
<i class="fas fa-receipt" aria-hidden="true"></i>
|
||||
<span><?php esc_html_e('我的订单', 'aksrt'); ?></span>
|
||||
</a>
|
||||
<?php endif; ?>
|
||||
<?php if (!empty($show_vip)) : ?>
|
||||
<a class="uc-sidebar__btn payvip-icon<?php echo (!empty($active_tab) && $active_tab === 'vip') ? ' is-active' : ''; ?>" href="<?php echo esc_url(aksrt_get_user_center_tab_url('vip')); ?>" data-tab="vip">
|
||||
<i class="fas fa-crown" aria-hidden="true"></i>
|
||||
<span><?php esc_html_e('VIP 会员', 'aksrt'); ?></span>
|
||||
</a>
|
||||
<?php endif; ?>
|
||||
<?php if (!empty($affiliate_enabled) && $revenue_url) : ?>
|
||||
<a href="<?php echo esc_url($revenue_url); ?>" class="uc-sidebar__btn">
|
||||
<i class="fas fa-share-alt" aria-hidden="true"></i>
|
||||
<span><?php esc_html_e('推广返佣', 'aksrt'); ?></span>
|
||||
</a>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<div class="uc-sidebar__pair uc-sidebar__pair--assets">
|
||||
<?php if ($show_wallet) : ?>
|
||||
<a class="uc-summary-card uc-summary-card--wallet" href="<?php echo esc_url($assets_url); ?>">
|
||||
<span class="uc-summary-card__head"><?php esc_html_e('账户余额', 'aksrt'); ?><i class="fas fa-angle-right" aria-hidden="true"></i></span>
|
||||
<span class="uc-summary-card__body">
|
||||
<strong><?php echo esc_html(class_exists('\AKSRT\Credits\Balance') ? \AKSRT\Credits\Balance::format($wallet) : number_format_i18n($wallet, 2)); ?></strong>
|
||||
<i class="fas fa-wallet" aria-hidden="true"></i>
|
||||
</span>
|
||||
</a>
|
||||
<?php endif; ?>
|
||||
<?php if ($show_credits) : ?>
|
||||
<a class="uc-summary-card uc-summary-card--points" href="<?php echo esc_url(add_query_arg('asset_tab', 'points', $assets_url)); ?>">
|
||||
<span class="uc-summary-card__head"><?php echo esc_html((string) ($currency_name ?? __('积分', 'aksrt'))); ?><i class="fas fa-angle-right" aria-hidden="true"></i></span>
|
||||
<span class="uc-summary-card__body">
|
||||
<strong><?php echo esc_html(function_exists('aksrt_format_credits') ? aksrt_format_credits((int) $points) : number_format_i18n((int) $points)); ?></strong>
|
||||
<i class="fas fa-coins" aria-hidden="true"></i>
|
||||
</span>
|
||||
</a>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
@@ -1,47 +1,35 @@
|
||||
<?php
|
||||
/**
|
||||
* User center sidebar: creator and community shortcuts.
|
||||
* User center sidebar: creation and promotion center pair.
|
||||
*
|
||||
* @package AKSRT
|
||||
*/
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
$creator_links = array_filter([
|
||||
[
|
||||
'url' => (string) ($new_post_url ?? ''),
|
||||
'icon' => 'pen',
|
||||
'label' => __('发布文章', 'aksrt'),
|
||||
],
|
||||
[
|
||||
'url' => (string) ($new_product_url ?? ''),
|
||||
'icon' => 'store',
|
||||
'label' => __('发布商品', 'aksrt'),
|
||||
],
|
||||
[
|
||||
'url' => (string) ($forum_compose_url ?? ''),
|
||||
'icon' => 'comments',
|
||||
'label' => __('论坛发帖', 'aksrt'),
|
||||
],
|
||||
[
|
||||
'url' => (string) ($revenue_url ?? ''),
|
||||
'icon' => 'chart-line',
|
||||
'label' => __('创作收益', 'aksrt'),
|
||||
],
|
||||
], static fn(array $item): bool => $item['url'] !== '');
|
||||
$creation_url = (string) ($new_post_url ?? '');
|
||||
if ($creation_url === '') {
|
||||
$creation_url = isset($dashboard_tabs['posts']) ? aksrt_get_user_center_tab_url('posts') : '';
|
||||
}
|
||||
$promotion_url = (string) ($revenue_url ?? '');
|
||||
|
||||
if (!$creator_links) {
|
||||
return;
|
||||
if ($creation_url === '' && $promotion_url === '') {
|
||||
return;
|
||||
}
|
||||
?>
|
||||
<div class="uc-sidebar__section">
|
||||
<div class="uc-sidebar__title"><?php esc_html_e('创作服务', 'aksrt'); ?></div>
|
||||
<div class="uc-sidebar__buttons">
|
||||
<?php foreach ($creator_links as $item) : ?>
|
||||
<a class="uc-sidebar__btn" href="<?php echo esc_url($item['url']); ?>">
|
||||
<i class="fas fa-<?php echo esc_attr($item['icon']); ?>" aria-hidden="true"></i>
|
||||
<span><?php echo esc_html($item['label']); ?></span>
|
||||
</a>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<div class="uc-sidebar__pair uc-sidebar__pair--centers">
|
||||
<?php if ($creation_url !== '') : ?>
|
||||
<a class="uc-center-card uc-center-card--creation" href="<?php echo esc_url($creation_url); ?>">
|
||||
<span class="uc-center-card__icon"><i class="fas fa-feather-alt" aria-hidden="true"></i></span>
|
||||
<span><strong><?php esc_html_e('创作中心', 'aksrt'); ?></strong><small><?php esc_html_e('发布与管理内容', 'aksrt'); ?></small></span>
|
||||
<i class="fas fa-angle-right" aria-hidden="true"></i>
|
||||
</a>
|
||||
<?php endif; ?>
|
||||
<?php if ($promotion_url !== '') : ?>
|
||||
<a class="uc-center-card uc-center-card--promotion" href="<?php echo esc_url($promotion_url); ?>">
|
||||
<span class="uc-center-card__icon"><i class="fas fa-bullhorn" aria-hidden="true"></i></span>
|
||||
<span><strong><?php esc_html_e('推广中心', 'aksrt'); ?></strong><small><?php esc_html_e('返佣与收益', 'aksrt'); ?></small></span>
|
||||
<i class="fas fa-angle-right" aria-hidden="true"></i>
|
||||
</a>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
@@ -1,36 +1,89 @@
|
||||
<?php
|
||||
/**
|
||||
* User center sidebar: main service navigation.
|
||||
*
|
||||
* Expects extracted $context vars.
|
||||
* User center sidebar: services and account settings.
|
||||
*
|
||||
* @package AKSRT
|
||||
*/
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
?>
|
||||
<div class="uc-sidebar__section">
|
||||
<div class="uc-sidebar__title"><?php esc_html_e('我的服务', 'aksrt'); ?></div>
|
||||
<div class="uc-sidebar__buttons">
|
||||
<?php foreach ($dashboard_tabs as $tab_key => $tab) :
|
||||
// VIP / 订单 only under 权益与消费 (sidebar-commerce), not duplicated here.
|
||||
if (in_array((string) $tab_key, ['vip', 'orders'], true)) {
|
||||
continue;
|
||||
}
|
||||
?>
|
||||
<a class="uc-sidebar__btn<?php echo $active_tab === $tab_key ? ' is-active' : ''; ?>" href="<?php echo esc_url(aksrt_get_user_center_tab_url($tab_key)); ?>" data-tab="<?php echo esc_attr($tab_key); ?>">
|
||||
<i class="fas fa-<?php echo esc_attr($tab['icon']); ?>" aria-hidden="true"></i>
|
||||
<span><?php echo esc_html($tab['label']); ?></span>
|
||||
|
||||
$cart_url = function_exists('aksrt_get_cart_page_url') ? aksrt_get_cart_page_url() : '';
|
||||
$level_url = isset($dashboard_tabs['credits'])
|
||||
? add_query_arg('asset_tab', 'points', aksrt_get_user_center_tab_url('credits'))
|
||||
: '';
|
||||
$auth_url = function_exists('aksrt_get_page_url_by_template')
|
||||
? aksrt_get_page_url_by_template('templates/pages/page-user-auth.php')
|
||||
: '';
|
||||
|
||||
$services = array_values(array_filter([
|
||||
[
|
||||
'label' => __('购物车', 'aksrt'),
|
||||
'icon' => 'shopping-cart',
|
||||
'tone' => 'cart',
|
||||
'url' => $cart_url,
|
||||
],
|
||||
[
|
||||
'label' => __('我的等级', 'aksrt'),
|
||||
'icon' => 'chart-line',
|
||||
'tone' => 'level',
|
||||
'url' => $level_url,
|
||||
],
|
||||
[
|
||||
'label' => __('官方认证', 'aksrt'),
|
||||
'icon' => 'id-badge',
|
||||
'tone' => 'auth',
|
||||
'url' => $auth_url,
|
||||
],
|
||||
], static fn(array $item): bool => (string) $item['url'] !== ''));
|
||||
|
||||
$settings = array_values(array_filter([
|
||||
[
|
||||
'label' => __('消息通知', 'aksrt'),
|
||||
'icon' => 'bell',
|
||||
'tone' => 'notice',
|
||||
'url' => (string) ($messages_url ?? ''),
|
||||
'count' => (int) ($notification_unread_count ?? 0),
|
||||
],
|
||||
[
|
||||
'label' => __('个人资料', 'aksrt'),
|
||||
'icon' => 'user-edit',
|
||||
'tone' => 'profile',
|
||||
'url' => isset($dashboard_tabs['profile']) ? aksrt_get_user_center_tab_url('profile') : '',
|
||||
],
|
||||
[
|
||||
'label' => __('账户安全', 'aksrt'),
|
||||
'icon' => 'shield-alt',
|
||||
'tone' => 'security',
|
||||
'url' => isset($dashboard_tabs['settings']) ? aksrt_get_user_center_tab_url('settings') : '',
|
||||
],
|
||||
], static fn(array $item): bool => (string) $item['url'] !== ''));
|
||||
|
||||
$render_grid = static function (array $items): void {
|
||||
?>
|
||||
<div class="uc-service-grid">
|
||||
<?php foreach ($items as $item) : ?>
|
||||
<a class="uc-service-grid__item uc-service-grid__item--<?php echo esc_attr((string) $item['tone']); ?>" href="<?php echo esc_url((string) $item['url']); ?>">
|
||||
<span class="uc-service-grid__icon">
|
||||
<i class="fas fa-<?php echo esc_attr((string) $item['icon']); ?>" aria-hidden="true"></i>
|
||||
<?php if (!empty($item['count'])) : ?><small><?php echo esc_html((string) $item['count']); ?></small><?php endif; ?>
|
||||
</span>
|
||||
<span><?php echo esc_html((string) $item['label']); ?></span>
|
||||
</a>
|
||||
<?php endforeach; ?>
|
||||
<?php if (!empty($messages_url)) : ?>
|
||||
<a href="<?php echo esc_url($messages_url); ?>" class="uc-sidebar__btn">
|
||||
<i class="fas fa-bell" aria-hidden="true"></i>
|
||||
<span><?php esc_html_e('消息通知', 'aksrt'); ?></span>
|
||||
<?php if ($notification_unread_count > 0) : ?>
|
||||
<span class="uc-sidebar__badge"><?php echo esc_html((string) $notification_unread_count); ?></span>
|
||||
<?php endif; ?>
|
||||
</a>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php
|
||||
};
|
||||
?>
|
||||
<?php if ($services) : ?>
|
||||
<div class="uc-sidebar__section">
|
||||
<div class="uc-sidebar__heading"><span><?php esc_html_e('我的服务', 'aksrt'); ?></span></div>
|
||||
<?php $render_grid($services); ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ($settings) : ?>
|
||||
<div class="uc-sidebar__section">
|
||||
<div class="uc-sidebar__heading"><span><?php esc_html_e('功能设置', 'aksrt'); ?></span></div>
|
||||
<?php $render_grid($settings); ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
<?php
|
||||
/**
|
||||
* User center sidebar: task-oriented order shortcuts.
|
||||
*
|
||||
* @package AKSRT
|
||||
*/
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
$orders_base_url = (string) ($orders_url ?? '');
|
||||
if ($orders_base_url === '') {
|
||||
return;
|
||||
}
|
||||
|
||||
$order_stats = class_exists('\AKSRT\Payment\Order')
|
||||
? \AKSRT\Payment\Order::get_instance()->get_stats((int) ($user_id ?? 0))
|
||||
: [];
|
||||
$order_items = [
|
||||
[
|
||||
'label' => __('待支付', 'aksrt'),
|
||||
'icon' => 'wallet',
|
||||
'tab' => 'pending',
|
||||
'count' => (int) ($order_stats['pending'] ?? 0),
|
||||
],
|
||||
[
|
||||
'label' => __('待发货', 'aksrt'),
|
||||
'icon' => 'gift',
|
||||
'tab' => 'to-ship',
|
||||
'count' => (int) ($order_stats['paid'] ?? 0),
|
||||
],
|
||||
[
|
||||
'label' => __('待收货', 'aksrt'),
|
||||
'icon' => 'truck',
|
||||
'tab' => 'shipped',
|
||||
'count' => (int) ($order_stats['delivered'] ?? 0),
|
||||
],
|
||||
[
|
||||
'label' => __('待评价', 'aksrt'),
|
||||
'icon' => 'comment-dots',
|
||||
'tab' => 'review',
|
||||
'count' => (int) ($order_stats['pending_review'] ?? 0),
|
||||
],
|
||||
[
|
||||
'label' => __('售后', 'aksrt'),
|
||||
'icon' => 'undo-alt',
|
||||
'tab' => 'after',
|
||||
'count' => (int) ($order_stats['refunding'] ?? 0),
|
||||
],
|
||||
];
|
||||
?>
|
||||
<div class="uc-sidebar__section uc-order-card">
|
||||
<div class="uc-sidebar__heading">
|
||||
<span><?php esc_html_e('我的订单', 'aksrt'); ?></span>
|
||||
<a href="<?php echo esc_url($orders_base_url); ?>">
|
||||
<?php esc_html_e('全部', 'aksrt'); ?><i class="fas fa-angle-right" aria-hidden="true"></i>
|
||||
</a>
|
||||
</div>
|
||||
<div class="uc-order-grid">
|
||||
<?php foreach ($order_items as $item) :
|
||||
$item_url = add_query_arg('order_tab', $item['tab'], $orders_base_url);
|
||||
?>
|
||||
<a class="uc-order-grid__item" href="<?php echo esc_url($item_url); ?>">
|
||||
<span class="uc-order-grid__icon">
|
||||
<i class="fas fa-<?php echo esc_attr((string) $item['icon']); ?>" aria-hidden="true"></i>
|
||||
<?php if ($item['count'] > 0) : ?>
|
||||
<small><?php echo esc_html($item['count'] > 99 ? '99+' : (string) $item['count']); ?></small>
|
||||
<?php endif; ?>
|
||||
</span>
|
||||
<span><?php echo esc_html((string) $item['label']); ?></span>
|
||||
</a>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,34 +1,43 @@
|
||||
<?php
|
||||
/**
|
||||
* User center sidebar: stats section.
|
||||
*
|
||||
* Expects extracted $context vars.
|
||||
* User center sidebar: one-line account statistics.
|
||||
*
|
||||
* @package AKSRT
|
||||
*/
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
$public_home_url = function_exists('aksrt_get_user_home_url') ? aksrt_get_user_home_url($target_user ?? null) : '';
|
||||
$stats = [
|
||||
[
|
||||
'label' => __('文章', 'aksrt'),
|
||||
'value' => (int) ($post_count ?? 0),
|
||||
'url' => isset($dashboard_tabs['posts']) ? aksrt_get_user_center_tab_url('posts') : $public_home_url,
|
||||
],
|
||||
[
|
||||
'label' => __('评论', 'aksrt'),
|
||||
'value' => (int) ($comment_count ?? 0),
|
||||
'url' => isset($dashboard_tabs['comments']) ? aksrt_get_user_center_tab_url('comments') : $public_home_url,
|
||||
],
|
||||
[
|
||||
'label' => __('收藏', 'aksrt'),
|
||||
'value' => (int) ($favorite_count ?? 0),
|
||||
'url' => isset($dashboard_tabs['favorites']) ? aksrt_get_user_center_tab_url('favorites') : $public_home_url,
|
||||
],
|
||||
[
|
||||
'label' => __('粉丝', 'aksrt'),
|
||||
'value' => (int) ($follower_count ?? 0),
|
||||
'url' => $public_home_url !== '' ? add_query_arg(['tab' => 'follow', 'follow_sub' => 'followers'], $public_home_url) : '',
|
||||
],
|
||||
];
|
||||
?>
|
||||
<div class="uc-sidebar__section">
|
||||
<div class="uc-sidebar__title"><?php esc_html_e('数据统计', 'aksrt'); ?></div>
|
||||
<div class="uc-sidebar__section uc-sidebar__section--stats" aria-label="<?php esc_attr_e('账号统计', 'aksrt'); ?>">
|
||||
<div class="uc-stats">
|
||||
<?php foreach (['posts', 'comments', 'favorites'] as $stat_tab) : ?>
|
||||
<?php if (!isset($dashboard_tabs[$stat_tab])) { continue; } ?>
|
||||
<?php
|
||||
$stat_count = 'posts' === $stat_tab
|
||||
? $post_count
|
||||
: ('comments' === $stat_tab ? $comment_count : $favorite_count);
|
||||
?>
|
||||
<a class="uc-stats__item" href="<?php echo esc_url(add_query_arg('tab', $stat_tab, remove_query_arg('tab'))); ?>">
|
||||
<span class="uc-stats__value"><?php echo esc_html((string) $stat_count); ?></span>
|
||||
<span class="uc-stats__label"><?php echo esc_html($dashboard_tabs[$stat_tab]['label']); ?></span>
|
||||
<?php foreach ($stats as $stat) : ?>
|
||||
<a class="uc-stats__item" href="<?php echo esc_url((string) $stat['url']); ?>">
|
||||
<span class="uc-stats__value"><?php echo esc_html(number_format_i18n((int) $stat['value'])); ?></span>
|
||||
<span class="uc-stats__label"><?php echo esc_html((string) $stat['label']); ?></span>
|
||||
</a>
|
||||
<?php endforeach; ?>
|
||||
<?php if (!empty($messages_url)) : ?>
|
||||
<a class="uc-stats__item" href="<?php echo esc_url($messages_url); ?>">
|
||||
<span class="uc-stats__value"><?php echo esc_html((string) $notification_unread_count); ?></span>
|
||||
<span class="uc-stats__label"><?php esc_html_e('通知', 'aksrt'); ?></span>
|
||||
</a>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -25,59 +25,6 @@ add_action('wp_ajax_aksrt_save_profile', function () {
|
||||
wp_send_json_success(['message' => __('保存成功!', 'aksrt')]);
|
||||
});
|
||||
|
||||
// ============================================================
|
||||
// AJAX: 上传打赏收款码
|
||||
// ============================================================
|
||||
add_action('wp_ajax_aksrt_upload_reward_qr', function () {
|
||||
if (!isset($_POST['_profile_nonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['_profile_nonce'])), 'aksrt_profile_save')) {
|
||||
wp_send_json_error(['message' => __('安全验证失败,请刷新页面重试', 'aksrt')]);
|
||||
}
|
||||
$user_id = get_current_user_id();
|
||||
if ($user_id <= 0) {
|
||||
wp_send_json_error(['message' => __('请先登录', 'aksrt')]);
|
||||
}
|
||||
if (function_exists('aksrt_rewards_enabled') && !aksrt_rewards_enabled()) {
|
||||
wp_send_json_error(['message' => __('打赏功能未启用', 'aksrt')]);
|
||||
}
|
||||
$kind = isset($_POST['kind']) ? sanitize_key((string) $_POST['kind']) : '';
|
||||
if (!in_array($kind, ['weixin', 'alipay'], true)) {
|
||||
wp_send_json_error(['message' => __('无效类型', 'aksrt')]);
|
||||
}
|
||||
if (empty($_FILES['file']['name'])) {
|
||||
wp_send_json_error(['message' => __('请选择图片', 'aksrt')]);
|
||||
}
|
||||
|
||||
require_once ABSPATH . 'wp-admin/includes/file.php';
|
||||
require_once ABSPATH . 'wp-admin/includes/media.php';
|
||||
require_once ABSPATH . 'wp-admin/includes/image.php';
|
||||
|
||||
$file = $_FILES['file'];
|
||||
$check = wp_check_filetype_and_ext($file['tmp_name'], $file['name']);
|
||||
$allowed = ['image/jpeg', 'image/png', 'image/gif', 'image/webp'];
|
||||
$mime = (string) ($check['type'] ?? $file['type'] ?? '');
|
||||
if ($mime === '' || !in_array($mime, $allowed, true)) {
|
||||
wp_send_json_error(['message' => __('仅支持 JPG/PNG/GIF/WebP 图片', 'aksrt')]);
|
||||
}
|
||||
if (!empty($file['size']) && (int) $file['size'] > 2 * 1024 * 1024) {
|
||||
wp_send_json_error(['message' => __('图片不能超过 2MB', 'aksrt')]);
|
||||
}
|
||||
|
||||
$attachment_id = media_handle_upload('file', 0);
|
||||
if (is_wp_error($attachment_id)) {
|
||||
wp_send_json_error(['message' => $attachment_id->get_error_message()]);
|
||||
}
|
||||
$meta = $kind === 'weixin' ? 'aksrt_rewards_weixin' : 'aksrt_rewards_alipay';
|
||||
update_user_meta($user_id, $meta, (int) $attachment_id);
|
||||
$url = wp_get_attachment_image_url((int) $attachment_id, 'full');
|
||||
wp_send_json_success([
|
||||
'message' => __('上传成功', 'aksrt'),
|
||||
'id' => (int) $attachment_id,
|
||||
'url' => is_string($url) ? $url : '',
|
||||
'kind' => $kind,
|
||||
]);
|
||||
});
|
||||
|
||||
|
||||
// ============================================================
|
||||
// AJAX: 发送邮箱验证码(修改密码/更改邮箱通用)
|
||||
// ============================================================
|
||||
|
||||
@@ -140,6 +140,10 @@ class SchemaPostList {
|
||||
['key' => 'post_wechat_share', 'label' => '微信分享', 'type' => 'switch', 'default' => false],
|
||||
['key' => 'post_rewards_s', 'label' => '用户打赏', 'type' => 'switch', 'default' => false],
|
||||
['key' => 'post_rewards_text', 'label' => '打赏按钮文案', 'type' => 'input', 'default' => '赞赏'],
|
||||
['key' => 'post_rewards_amounts', 'label' => '快捷金额', 'type' => 'input', 'default' => '5,10,20,50,100', 'description' => '英文逗号分隔,赞赏直接进入作者站内余额'],
|
||||
['key' => 'post_rewards_custom', 'label' => '允许自定义金额', 'type' => 'switch', 'default' => true],
|
||||
['key' => 'post_rewards_min', 'label' => '最低金额', 'type' => 'number', 'default' => 1, 'min' => 0.01, 'max' => 1000, 'step' => 0.01],
|
||||
['key' => 'post_rewards_max', 'label' => '最高金额', 'type' => 'number', 'default' => 1000, 'min' => 1, 'max' => 100000, 'step' => 0.01],
|
||||
['key' => 'post_button_toptext', 'label' => '按钮上方文案', 'type' => 'input', 'default' => '喜欢就支持一下吧'],
|
||||
]],
|
||||
['key' => 'content', 'title' => '内容处理', 'fields' => [
|
||||
|
||||
@@ -585,14 +585,7 @@ class SchemaUsers {
|
||||
['key' => 'user_privacy_ip', 'label' => '隐藏IP归属地', 'type' => 'switch', 'default' => false],
|
||||
['key' => 'user_privacy_location', 'label' => '隐藏位置', 'type' => 'switch', 'default' => false],
|
||||
]],
|
||||
['key' => 'rewards', 'title' => '打赏设置', 'fields' => [
|
||||
['key' => 'post_rewards_s', 'label' => '启用文章打赏', 'type' => 'switch', 'default' => true],
|
||||
['key' => 'post_rewards_text', 'label' => '打赏文案', 'type' => 'input', 'default' => ''],
|
||||
['key' => 'post_rewards_img', 'label' => '打赏二维码', 'type' => 'media', 'default' => ''],
|
||||
['key' => 'post_rewards_btn_text', 'label' => '打赏按钮文案', 'type' => 'input', 'default' => '赞赏'],
|
||||
['key' => 'post_rewards_amounts', 'label' => '打赏金额', 'type' => 'input', 'default' => '5,10,20,50,100'],
|
||||
['key' => 'post_rewards_custom', 'label' => '自定义金额', 'type' => 'switch', 'default' => true],
|
||||
]],
|
||||
|
||||
],
|
||||
],
|
||||
'verify' => [
|
||||
|
||||
@@ -244,6 +244,105 @@ class Balance {
|
||||
return !empty(\AKSRT\Settings\Settings::get_all()['pay_balance_s']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Atomically transfer cash balance between two users.
|
||||
*
|
||||
* @param array<string,mixed> $ref
|
||||
* @return array{sender_balance:float,recipient_balance:float}|\WP_Error
|
||||
*/
|
||||
public static function transfer(int $sender_id, int $recipient_id, float $amount, string $reason_out = 'tip_sent', string $reason_in = 'tip_received', array $ref = [], string $remark = '') {
|
||||
global $wpdb;
|
||||
|
||||
$amount = round($amount, 2);
|
||||
if ($sender_id <= 0 || $recipient_id <= 0 || $sender_id === $recipient_id) {
|
||||
return new \WP_Error('aksrt_balance_transfer_user', __('转账用户无效', 'aksrt'));
|
||||
}
|
||||
if ($amount <= 0) {
|
||||
return new \WP_Error('aksrt_balance_transfer_amount', __('转账金额必须大于零', 'aksrt'));
|
||||
}
|
||||
if (!class_exists('\AKSRT\Core\DBMigrator')) {
|
||||
return new \WP_Error('aksrt_balance_transfer_unavailable', __('余额服务不可用', 'aksrt'));
|
||||
}
|
||||
|
||||
foreach ([$sender_id, $recipient_id] as $user_id) {
|
||||
if (!metadata_exists('user', $user_id, self::META_KEY)) {
|
||||
add_user_meta($user_id, self::META_KEY, '0', true);
|
||||
}
|
||||
}
|
||||
|
||||
$meta_table = $wpdb->usermeta;
|
||||
$log_table = \AKSRT\Core\DBMigrator::table('balance_log');
|
||||
$locked_ids = [$sender_id, $recipient_id];
|
||||
sort($locked_ids, SORT_NUMERIC);
|
||||
|
||||
$wpdb->query('START TRANSACTION');
|
||||
try {
|
||||
foreach ($locked_ids as $user_id) {
|
||||
$wpdb->get_var($wpdb->prepare(
|
||||
"SELECT umeta_id FROM {$meta_table} WHERE user_id = %d AND meta_key = %s FOR UPDATE",
|
||||
$user_id,
|
||||
self::META_KEY
|
||||
));
|
||||
}
|
||||
|
||||
$sender_before = (float) $wpdb->get_var($wpdb->prepare(
|
||||
"SELECT meta_value FROM {$meta_table} WHERE user_id = %d AND meta_key = %s LIMIT 1",
|
||||
$sender_id,
|
||||
self::META_KEY
|
||||
));
|
||||
if ($sender_before < $amount) {
|
||||
$wpdb->query('ROLLBACK');
|
||||
return new \WP_Error('aksrt_balance_insufficient', __('余额不足', 'aksrt'));
|
||||
}
|
||||
|
||||
$sender_after = round($sender_before - $amount, 2);
|
||||
$recipient_before = (float) $wpdb->get_var($wpdb->prepare(
|
||||
"SELECT meta_value FROM {$meta_table} WHERE user_id = %d AND meta_key = %s LIMIT 1",
|
||||
$recipient_id,
|
||||
self::META_KEY
|
||||
));
|
||||
$recipient_after = round($recipient_before + $amount, 2);
|
||||
|
||||
$sender_updated = $wpdb->update($meta_table, ['meta_value' => (string) $sender_after], ['user_id' => $sender_id, 'meta_key' => self::META_KEY], ['%s'], ['%d', '%s']);
|
||||
$recipient_updated = $wpdb->update($meta_table, ['meta_value' => (string) $recipient_after], ['user_id' => $recipient_id, 'meta_key' => self::META_KEY], ['%s'], ['%d', '%s']);
|
||||
if ($sender_updated !== 1 || $recipient_updated !== 1) {
|
||||
throw new \RuntimeException('balance_update_failed');
|
||||
}
|
||||
|
||||
$ref_type = isset($ref['type']) ? sanitize_key((string) $ref['type']) : 'tip';
|
||||
$ref_id = isset($ref['id']) ? (int) $ref['id'] : null;
|
||||
$created_at = current_time('mysql', true);
|
||||
$log_rows = [
|
||||
[$sender_id, -$amount, $sender_after, $reason_out],
|
||||
[$recipient_id, $amount, $recipient_after, $reason_in],
|
||||
];
|
||||
foreach ($log_rows as [$user_id, $delta, $balance_after, $reason]) {
|
||||
$inserted = $wpdb->insert($log_table, [
|
||||
'user_id' => $user_id,
|
||||
'delta' => $delta,
|
||||
'balance_after' => $balance_after,
|
||||
'reason' => sanitize_key($reason),
|
||||
'remark' => $remark !== '' ? sanitize_text_field(substr($remark, 0, 255)) : null,
|
||||
'ref_type' => $ref_type,
|
||||
'ref_id' => $ref_id,
|
||||
'created_at' => $created_at,
|
||||
], ['%d', '%f', '%f', '%s', '%s', '%s', '%d', '%s']);
|
||||
if ($inserted !== 1) {
|
||||
throw new \RuntimeException('balance_log_failed');
|
||||
}
|
||||
}
|
||||
|
||||
$wpdb->query('COMMIT');
|
||||
wp_cache_delete($sender_id, 'user_meta');
|
||||
wp_cache_delete($recipient_id, 'user_meta');
|
||||
do_action('aksrt_balance_transferred', $sender_id, $recipient_id, $amount, $ref);
|
||||
return ['sender_balance' => $sender_after, 'recipient_balance' => $recipient_after];
|
||||
} catch (\Throwable $e) {
|
||||
$wpdb->query('ROLLBACK');
|
||||
return new \WP_Error('aksrt_balance_transfer_failed', __('打赏入账失败,请稍后重试', 'aksrt'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Format yuan for display.
|
||||
*/
|
||||
@@ -262,6 +361,8 @@ class Balance {
|
||||
'recharge' => __('余额充值', 'aksrt'),
|
||||
'transfer_in' => __('转入', 'aksrt'),
|
||||
'transfer_out' => __('转出', 'aksrt'),
|
||||
'tip_sent' => __('打赏支出', 'aksrt'),
|
||||
'tip_received' => __('收到打赏', 'aksrt'),
|
||||
'admin' => __('管理员调整', 'aksrt'),
|
||||
'exchange_from_credits' => __('积分兑换', 'aksrt'),
|
||||
'withdraw_hold' => __('提现冻结', 'aksrt'),
|
||||
|
||||
@@ -391,9 +391,11 @@ trait OrderRepositoryCore {
|
||||
SUM(CASE WHEN status = 'paid' THEN 1 ELSE 0 END) as paid,
|
||||
SUM(CASE WHEN status = 'delivered' THEN 1 ELSE 0 END) as delivered,
|
||||
SUM(CASE WHEN status = 'completed' THEN 1 ELSE 0 END) as completed,
|
||||
SUM(CASE WHEN status = 'pending_review' THEN 1 ELSE 0 END) as pending_review,
|
||||
SUM(CASE WHEN status = 'refunding' THEN 1 ELSE 0 END) as refunding,
|
||||
SUM(CASE WHEN status = 'cancelled' THEN 1 ELSE 0 END) as cancelled,
|
||||
SUM(CASE WHEN status = 'refunded' THEN 1 ELSE 0 END) as refunded,
|
||||
SUM(CASE WHEN status IN ('paid','delivered','completed') THEN amount ELSE 0 END) as revenue
|
||||
SUM(CASE WHEN status IN ('paid','delivered','completed','pending_review') THEN amount ELSE 0 END) as revenue
|
||||
FROM {$this->table()} {$where}";
|
||||
|
||||
if (!empty($params)) {
|
||||
@@ -406,9 +408,11 @@ trait OrderRepositoryCore {
|
||||
'total' => (int) ($row['total'] ?? 0),
|
||||
'pending' => (int) ($row['pending'] ?? 0),
|
||||
'paid' => (int) ($row['paid'] ?? 0),
|
||||
'delivered' => (int) ($row['delivered'] ?? 0),
|
||||
'completed' => (int) ($row['completed'] ?? 0),
|
||||
'cancelled' => (int) ($row['cancelled'] ?? 0),
|
||||
'delivered' => (int) ($row['delivered'] ?? 0),
|
||||
'completed' => (int) ($row['completed'] ?? 0),
|
||||
'pending_review' => (int) ($row['pending_review'] ?? 0),
|
||||
'refunding' => (int) ($row['refunding'] ?? 0),
|
||||
'cancelled' => (int) ($row['cancelled'] ?? 0),
|
||||
'refunded' => (int) ($row['refunded'] ?? 0),
|
||||
'revenue' => (float) ($row['revenue'] ?? 0),
|
||||
];
|
||||
|
||||
@@ -237,11 +237,19 @@ class PostDisplay {
|
||||
$authordesc = !isset($settings['post_authordesc_s']) || !empty($settings['post_authordesc_s']);
|
||||
$hide_time = !empty($settings['post_single_hide_time_s']);
|
||||
$share_enabled = !isset($settings['share_s']) || !empty($settings['share_s']);
|
||||
$rewards_enabled = !empty($settings['post_rewards_s']) || !empty($settings['post_rewards_enabled']);
|
||||
$rewards_enabled = !empty($settings['post_rewards_s']);
|
||||
$rewards_text = sanitize_text_field((string) ($settings['post_rewards_text'] ?? ''));
|
||||
if ($rewards_text === '') {
|
||||
$rewards_text = '赞赏';
|
||||
}
|
||||
$rewards_amounts = array_values(array_filter(array_map(static function ($value): float {
|
||||
return round((float) $value, 2);
|
||||
}, explode(',', (string) ($settings['post_rewards_amounts'] ?? '5,10,20,50,100'))), static fn(float $value): bool => $value > 0));
|
||||
if ($rewards_amounts === []) {
|
||||
$rewards_amounts = [5, 10, 20, 50, 100];
|
||||
}
|
||||
$rewards_min = max(0.01, round((float) ($settings['post_rewards_min'] ?? 1), 2));
|
||||
$rewards_max = max($rewards_min, round((float) ($settings['post_rewards_max'] ?? 1000), 2));
|
||||
$author_card_limit = max(0, min(12, (int) ($settings['post_author_card_limit'] ?? 6)));
|
||||
$author_card_orderby = sanitize_key((string) ($settings['post_author_card_orderby'] ?? 'views'));
|
||||
if (!in_array($author_card_orderby, ['views', 'date', 'modified', 'comment_count'], true)) {
|
||||
@@ -332,11 +340,15 @@ class PostDisplay {
|
||||
'author_card_limit' => $author_card_limit,
|
||||
'author_card_orderby' => $author_card_orderby,
|
||||
'author_card_style' => $author_card_style,
|
||||
// Rewards (Zibll post_rewards_s) — per-user QR only.
|
||||
// On-site wallet tipping.
|
||||
'rewards_enabled' => $rewards_enabled,
|
||||
'post_rewards_s' => $rewards_enabled,
|
||||
'rewards_text' => $rewards_text,
|
||||
'rewards_btn_text' => $rewards_text,
|
||||
'rewards_amounts' => $rewards_amounts,
|
||||
'rewards_custom' => !isset($settings['post_rewards_custom']) || !empty($settings['post_rewards_custom']),
|
||||
'rewards_min' => $rewards_min,
|
||||
'rewards_max' => $rewards_max,
|
||||
// Content max height (Zibll article_maxheight_kg / article_maxheight).
|
||||
'maxheight_enabled' => $maxheight_enabled,
|
||||
'maxheight' => $maxheight,
|
||||
|
||||
@@ -122,21 +122,16 @@ $is_self = is_user_logged_in() && get_current_user_id() === $author_id;
|
||||
<a href="<?php echo esc_url(add_query_arg('msg_type', 'conversation', $aksrt_msg_url)); ?>" class="ml6 but c-blue px12-sm">
|
||||
<i class="fa fa-comment em09" aria-hidden="true"></i> <?php esc_html_e('私信', 'aksrt'); ?>
|
||||
</a>
|
||||
<?php else : ?>
|
||||
<?php
|
||||
$aksrt_post_settings = class_exists('\AKSRT\Settings\Settings') && method_exists('\AKSRT\Settings\Settings', 'get_post_page_settings')
|
||||
? \AKSRT\Settings\Settings::get_post_page_settings()
|
||||
: [];
|
||||
$rewards_on = !empty($aksrt_post_settings['rewards_enabled'])
|
||||
|| !empty($aksrt_post_settings['post_rewards_enabled'])
|
||||
|| !empty($aksrt_post_settings['post_rewards_s']);
|
||||
?>
|
||||
<?php if ($rewards_on) : ?>
|
||||
<button type="button" class="ml6 but c-yellow px12-sm" data-aksrt-reward-open>
|
||||
<i class="fa fa-gift em09" aria-hidden="true"></i> <?php esc_html_e('赞赏', 'aksrt'); ?>
|
||||
</button>
|
||||
<?php endif; ?>
|
||||
<?php endif; ?>
|
||||
<?php
|
||||
$reward_button = function_exists('aksrt_get_rewards_button')
|
||||
? aksrt_get_rewards_button($author_id, 'ml6 but c-yellow px12-sm', get_the_ID())
|
||||
: '';
|
||||
if ($reward_button !== '') {
|
||||
echo $reward_button; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
aksrt_render_rewards_modal_for_user($author_id, get_the_ID());
|
||||
}
|
||||
?>
|
||||
<?php else : ?>
|
||||
<a href="<?php echo esc_url($login_url); ?>" class="px12-sm ml10 follow but c-red">
|
||||
<i class="fa fa-heart em09" aria-hidden="true"></i> <?php esc_html_e('关注', 'aksrt'); ?>
|
||||
|
||||
Reference in New Issue
Block a user