修复:弹窗额度4列布局+确认按钮背景色
1. 4列布局:x-show 与 display:grid 分离到两层 div, 避免 Alpine x-show 显示时把 display:grid 覆盖为 block 2. 确认按钮::style 改为始终返回 opacity 值而非空字符串, 避免 Alpine :style 绑定空值时清除静态 style 的 background, 按钮现为橙红渐变(#ea580c→#dc2626)+红色投影, 禁用状态 opacity:0.45 降亮+cursor:not-allowed
This commit is contained in:
@@ -877,89 +877,91 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{-- ═══════════ 奖励金币独立弹窗 ═══════════ --}}
|
{{-- ═══════════ 奖励金币独立弹窗 ═══════════ --}}
|
||||||
<div id="reward-modal-container"
|
<div id="reward-modal-container" x-data="{
|
||||||
x-data="{
|
show: false,
|
||||||
show: false,
|
targetUsername: '',
|
||||||
targetUsername: '',
|
amount: '',
|
||||||
amount: '',
|
sending: false,
|
||||||
sending: false,
|
loading: false,
|
||||||
loading: false,
|
quota: { max_once: null, daily_limit: null, today_sent: 0, daily_remaining: null, recent_rewards: [] },
|
||||||
quota: { max_once: null, daily_limit: null, today_sent: 0, daily_remaining: null, recent_rewards: [] },
|
|
||||||
|
|
||||||
fmt(v) {
|
fmt(v) {
|
||||||
if (v === null) return '不限';
|
if (v === null) return '不限';
|
||||||
if (v === 0) return '—';
|
if (v === 0) return '—';
|
||||||
return v.toLocaleString() + ' 金币';
|
return v.toLocaleString() + ' 金币';
|
||||||
},
|
},
|
||||||
|
|
||||||
async open(username) {
|
async open(username) {
|
||||||
this.targetUsername = username;
|
this.targetUsername = username;
|
||||||
this.amount = '';
|
this.amount = '';
|
||||||
this.sending = false;
|
this.sending = false;
|
||||||
this.loading = true;
|
this.loading = true;
|
||||||
this.show = true;
|
this.show = true;
|
||||||
try {
|
try {
|
||||||
const res = await fetch(window.chatContext.rewardQuotaUrl, {
|
const res = await fetch(window.chatContext.rewardQuotaUrl, {
|
||||||
headers: { 'Accept': 'application/json' }
|
headers: { 'Accept': 'application/json' }
|
||||||
});
|
});
|
||||||
this.quota = await res.json();
|
this.quota = await res.json();
|
||||||
if (!this.quota.recent_rewards) this.quota.recent_rewards = [];
|
if (!this.quota.recent_rewards) this.quota.recent_rewards = [];
|
||||||
} catch { this.quota = { max_once: null, daily_limit: null, today_sent: 0, daily_remaining: null, recent_rewards: [] }; }
|
} catch { this.quota = { max_once: null, daily_limit: null, today_sent: 0, daily_remaining: null, recent_rewards: [] }; }
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
},
|
},
|
||||||
|
|
||||||
async send() {
|
async send() {
|
||||||
if (this.sending) return;
|
if (this.sending) return;
|
||||||
const amt = parseInt(this.amount, 10);
|
const amt = parseInt(this.amount, 10);
|
||||||
if (!amt || amt <= 0) { alert('请输入有效金额'); return; }
|
if (!amt || amt <= 0) { alert('请输入有效金额'); return; }
|
||||||
const maxOnce = window.chatContext?.myMaxReward;
|
const maxOnce = window.chatContext?.myMaxReward;
|
||||||
if (maxOnce === 0) { alert('你的职务没有奖励发放权限'); return; }
|
if (maxOnce === 0) { alert('你的职务没有奖励发放权限'); return; }
|
||||||
if (maxOnce > 0 && amt > maxOnce) { alert('超出单次上限 ' + maxOnce + ' 金币'); return; }
|
if (maxOnce > 0 && amt > maxOnce) { alert('超出单次上限 ' + maxOnce + ' 金币'); return; }
|
||||||
this.sending = true;
|
this.sending = true;
|
||||||
try {
|
try {
|
||||||
const res = await fetch(window.chatContext.rewardUrl, {
|
const res = await fetch(window.chatContext.rewardUrl, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
'X-CSRF-TOKEN': document.querySelector('meta[name=csrf-token]')?.content || '',
|
'X-CSRF-TOKEN': document.querySelector('meta[name=csrf-token]')?.content || '',
|
||||||
'Accept': 'application/json',
|
'Accept': 'application/json',
|
||||||
},
|
},
|
||||||
body: JSON.stringify({ username: this.targetUsername, room_id: window.chatContext.roomId, amount: amt }),
|
body: JSON.stringify({ username: this.targetUsername, room_id: window.chatContext.roomId, amount: amt }),
|
||||||
});
|
});
|
||||||
const data = await res.json();
|
const data = await res.json();
|
||||||
if (data.status === 'success') {
|
if (data.status === 'success') {
|
||||||
this.quota.today_sent += amt;
|
this.quota.today_sent += amt;
|
||||||
if (this.quota.daily_remaining !== null) {
|
if (this.quota.daily_remaining !== null) {
|
||||||
this.quota.daily_remaining = Math.max(0, this.quota.daily_remaining - amt);
|
this.quota.daily_remaining = Math.max(0, this.quota.daily_remaining - amt);
|
||||||
}
|
|
||||||
// 在历史记录头部插入
|
|
||||||
const now = new Date();
|
|
||||||
const mm = String(now.getMonth()+1).padStart(2,'0');
|
|
||||||
const dd = String(now.getDate()).padStart(2,'0');
|
|
||||||
const hh = String(now.getHours()).padStart(2,'0');
|
|
||||||
const mi = String(now.getMinutes()).padStart(2,'0');
|
|
||||||
this.quota.recent_rewards.unshift({ target: this.targetUsername, amount: amt, created_at: mm+'-'+dd+' '+hh+':'+mi });
|
|
||||||
if (this.quota.recent_rewards.length > 10) this.quota.recent_rewards.pop();
|
|
||||||
this.amount = '';
|
|
||||||
alert(data.message);
|
|
||||||
} else {
|
|
||||||
alert(data.message || '发放失败');
|
|
||||||
}
|
}
|
||||||
} catch { alert('网络异常,请稍后重试'); }
|
// 在历史记录头部插入
|
||||||
this.sending = false;
|
const now = new Date();
|
||||||
}
|
const mm = String(now.getMonth() + 1).padStart(2, '0');
|
||||||
}">
|
const dd = String(now.getDate()).padStart(2, '0');
|
||||||
<div x-show="show" style="display:none; position:fixed; inset:0; background:rgba(0,0,0,.55); z-index:9900;" x-on:click.self="show = false">
|
const hh = String(now.getHours()).padStart(2, '0');
|
||||||
|
const mi = String(now.getMinutes()).padStart(2, '0');
|
||||||
|
this.quota.recent_rewards.unshift({ target: this.targetUsername, amount: amt, created_at: mm + '-' + dd + ' ' + hh + ':' + mi });
|
||||||
|
if (this.quota.recent_rewards.length > 10) this.quota.recent_rewards.pop();
|
||||||
|
this.amount = '';
|
||||||
|
alert(data.message);
|
||||||
|
} else {
|
||||||
|
alert(data.message || '发放失败');
|
||||||
|
}
|
||||||
|
} catch { alert('网络异常,请稍后重试'); }
|
||||||
|
this.sending = false;
|
||||||
|
}
|
||||||
|
}">
|
||||||
|
<div x-show="show" style="display:none; position:fixed; inset:0; background:rgba(0,0,0,.55); z-index:9900;"
|
||||||
|
x-on:click.self="show = false">
|
||||||
<div x-show="show"
|
<div x-show="show"
|
||||||
style="position:absolute; top:50%; left:50%; transform:translate(-50%,-50%);
|
style="position:absolute; top:50%; left:50%; transform:translate(-50%,-50%);
|
||||||
width:520px; max-width:95vw; background:#fff; border-radius:16px;
|
width:520px; max-width:95vw; background:#fff; border-radius:16px;
|
||||||
box-shadow:0 20px 60px rgba(0,0,0,.25); overflow:hidden;">
|
box-shadow:0 20px 60px rgba(0,0,0,.25); overflow:hidden;">
|
||||||
{{-- 标题栏 --}}
|
{{-- 标题栏 --}}
|
||||||
<div style="background:linear-gradient(135deg,#f59e0b,#d97706); padding:14px 20px;
|
<div
|
||||||
|
style="background:linear-gradient(135deg,#f59e0b,#d97706); padding:14px 20px;
|
||||||
display:flex; align-items:center; justify-content:space-between;">
|
display:flex; align-items:center; justify-content:space-between;">
|
||||||
<div>
|
<div>
|
||||||
<div style="color:#fff; font-weight:bold; font-size:16px;">🪙 发放奖励金币</div>
|
<div style="color:#fff; font-weight:bold; font-size:16px;">🪙 发放奖励金币</div>
|
||||||
<div style="color:rgba(255,255,255,.9); font-size:12px; margin-top:2px;" x-text="'发给:' + targetUsername"></div>
|
<div style="color:rgba(255,255,255,.9); font-size:12px; margin-top:2px;"
|
||||||
|
x-text="'发给:' + targetUsername"></div>
|
||||||
</div>
|
</div>
|
||||||
<button x-on:click="show = false"
|
<button x-on:click="show = false"
|
||||||
style="background:rgba(255,255,255,.25); border:none; color:#fff; width:30px; height:30px;
|
style="background:rgba(255,255,255,.25); border:none; color:#fff; width:30px; height:30px;
|
||||||
@@ -967,23 +969,35 @@
|
|||||||
</div>
|
</div>
|
||||||
{{-- 额度四格(一行4列) --}}
|
{{-- 额度四格(一行4列) --}}
|
||||||
<div style="padding:16px 20px 0;">
|
<div style="padding:16px 20px 0;">
|
||||||
<div x-show="loading" style="text-align:center; color:#b45309; font-size:13px; padding:12px 0;">加载额度信息…</div>
|
<div x-show="loading" style="text-align:center; color:#b45309; font-size:13px; padding:12px 0;">
|
||||||
<div x-show="!loading" style="display:grid; grid-template-columns:repeat(4,1fr); gap:8px;">
|
加载额度信息…</div>
|
||||||
<div style="background:#fffbeb; border:1px solid #fde68a; border-radius:8px; padding:10px; text-align:center;">
|
{{-- 注意:x-show 与 display:grid 必须分离,否则 x-show 显示时会把 display:grid 覆盖为 block --}}
|
||||||
<div style="font-size:10px; color:#b45309; margin-bottom:4px;">单次上限</div>
|
<div x-show="!loading">
|
||||||
<div style="font-size:13px; font-weight:bold; color:#92400e;" x-text="fmt(quota.max_once)"></div>
|
<div style="display:grid; grid-template-columns:repeat(4,1fr); gap:8px;">
|
||||||
</div>
|
<div
|
||||||
<div style="background:#fffbeb; border:1px solid #fde68a; border-radius:8px; padding:10px; text-align:center;">
|
style="background:#fffbeb; border:1px solid #fde68a; border-radius:8px; padding:10px; text-align:center;">
|
||||||
<div style="font-size:10px; color:#b45309; margin-bottom:4px;">单日上限</div>
|
<div style="font-size:10px; color:#b45309; margin-bottom:4px;">单次上限</div>
|
||||||
<div style="font-size:13px; font-weight:bold; color:#92400e;" x-text="fmt(quota.daily_limit)"></div>
|
<div style="font-size:13px; font-weight:bold; color:#92400e;"
|
||||||
</div>
|
x-text="fmt(quota.max_once)"></div>
|
||||||
<div style="background:#f0fdf4; border:1px solid #bbf7d0; border-radius:8px; padding:10px; text-align:center;">
|
</div>
|
||||||
<div style="font-size:10px; color:#166534; margin-bottom:4px;">今日已发</div>
|
<div
|
||||||
<div style="font-size:13px; font-weight:bold; color:#15803d;" x-text="quota.today_sent.toLocaleString() + ' 金币'"></div>
|
style="background:#fffbeb; border:1px solid #fde68a; border-radius:8px; padding:10px; text-align:center;">
|
||||||
</div>
|
<div style="font-size:10px; color:#b45309; margin-bottom:4px;">单日上限</div>
|
||||||
<div style="background:#f0fdf4; border:1px solid #bbf7d0; border-radius:8px; padding:10px; text-align:center;">
|
<div style="font-size:13px; font-weight:bold; color:#92400e;"
|
||||||
<div style="font-size:10px; color:#166534; margin-bottom:4px;">剩余额度</div>
|
x-text="fmt(quota.daily_limit)"></div>
|
||||||
<div style="font-size:13px; font-weight:bold; color:#15803d;" x-text="fmt(quota.daily_remaining)"></div>
|
</div>
|
||||||
|
<div
|
||||||
|
style="background:#f0fdf4; border:1px solid #bbf7d0; border-radius:8px; padding:10px; text-align:center;">
|
||||||
|
<div style="font-size:10px; color:#166534; margin-bottom:4px;">今日已发</div>
|
||||||
|
<div style="font-size:13px; font-weight:bold; color:#15803d;"
|
||||||
|
x-text="quota.today_sent.toLocaleString() + ' 金币'"></div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
style="background:#f0fdf4; border:1px solid #bbf7d0; border-radius:8px; padding:10px; text-align:center;">
|
||||||
|
<div style="font-size:10px; color:#166534; margin-bottom:4px;">剩余额度</div>
|
||||||
|
<div style="font-size:13px; font-weight:bold; color:#15803d;"
|
||||||
|
x-text="fmt(quota.daily_remaining)"></div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -992,16 +1006,16 @@
|
|||||||
<div style="display:flex; gap:8px; align-items:center;">
|
<div style="display:flex; gap:8px; align-items:center;">
|
||||||
<input type="number" x-model.number="amount"
|
<input type="number" x-model.number="amount"
|
||||||
:placeholder="quota.max_once ? '最多 ' + quota.max_once + ' 金币' : '请输入发放金额'"
|
:placeholder="quota.max_once ? '最多 ' + quota.max_once + ' 金币' : '请输入发放金额'"
|
||||||
:max="quota.max_once || 999999" min="1"
|
:max="quota.max_once || 999999" min="1" x-on:keydown.enter="send()"
|
||||||
x-on:keydown.enter="send()"
|
|
||||||
style="flex:1; height:44px; padding:0 14px; border:2px solid #fcd34d;
|
style="flex:1; height:44px; padding:0 14px; border:2px solid #fcd34d;
|
||||||
border-radius:10px; font-size:15px; color:#92400e; outline:none; box-sizing:border-box;">
|
border-radius:10px; font-size:15px; color:#92400e; outline:none; box-sizing:border-box;">
|
||||||
<button x-on:click="send()" :disabled="sending || !amount"
|
<button x-on:click="send()" :disabled="sending || !amount"
|
||||||
style="height:44px; padding:0 24px; border:none; border-radius:10px; font-size:14px;
|
style="height:44px; padding:0 24px; border:none; border-radius:10px; font-size:14px;
|
||||||
font-weight:bold; cursor:pointer; white-space:nowrap;
|
font-weight:bold; cursor:pointer; white-space:nowrap;
|
||||||
background:linear-gradient(135deg,#ea580c,#dc2626);
|
background:linear-gradient(135deg,#ea580c,#dc2626);
|
||||||
color:#fff; box-shadow:0 4px 12px rgba(234,88,12,.4);"
|
color:#fff; box-shadow:0 4px 14px rgba(220,38,38,.45);
|
||||||
:style="(sending || !amount) ? 'opacity:.5; cursor:not-allowed; box-shadow:none;' : ''">
|
transition:opacity .15s;"
|
||||||
|
:style="(sending || !amount) ? 'opacity:.45; cursor:not-allowed;' : 'opacity:1;'">
|
||||||
<span x-text="sending ? '发放中…' : '🎉 确认发放'"></span>
|
<span x-text="sending ? '发放中…' : '🎉 确认发放'"></span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@@ -1011,7 +1025,8 @@
|
|||||||
</div>
|
</div>
|
||||||
{{-- 最近 10 条记录 --}}
|
{{-- 最近 10 条记录 --}}
|
||||||
<div style="padding:12px 20px 16px;">
|
<div style="padding:12px 20px 16px;">
|
||||||
<div style="font-size:11px; color:#78716c; font-weight:bold; margin-bottom:6px; border-top:1px solid #f5f5f4; padding-top:10px;">
|
<div
|
||||||
|
style="font-size:11px; color:#78716c; font-weight:bold; margin-bottom:6px; border-top:1px solid #f5f5f4; padding-top:10px;">
|
||||||
📋 最近发放记录
|
📋 最近发放记录
|
||||||
</div>
|
</div>
|
||||||
<div x-show="loading" style="font-size:11px; color:#aaa; text-align:center; padding:4px 0;">加载中…</div>
|
<div x-show="loading" style="font-size:11px; color:#aaa; text-align:center; padding:4px 0;">加载中…</div>
|
||||||
@@ -1025,7 +1040,8 @@
|
|||||||
<span style="color:#57534e;">
|
<span style="color:#57534e;">
|
||||||
<span style="color:#92400e; font-weight:bold;" x-text="r.target"></span>
|
<span style="color:#92400e; font-weight:bold;" x-text="r.target"></span>
|
||||||
</span>
|
</span>
|
||||||
<span style="color:#059669; font-weight:bold;" x-text="'+' + r.amount.toLocaleString() + ' 金币'"></span>
|
<span style="color:#059669; font-weight:bold;"
|
||||||
|
x-text="'+' + r.amount.toLocaleString() + ' 金币'"></span>
|
||||||
<span style="color:#a8a29e;" x-text="r.created_at"></span>
|
<span style="color:#a8a29e;" x-text="r.created_at"></span>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -1048,4 +1064,3 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user