1069 lines
24 KiB
HTML
Executable File
1069 lines
24 KiB
HTML
Executable File
{% extends "base.html" %}
|
||
|
||
{% block head %}
|
||
<!-- 引入 QRCode.js -->
|
||
<script src="https://cdn.jsdelivr.net/npm/qrcodejs@1.0.0/qrcode.min.js"></script>
|
||
{% endblock %}
|
||
|
||
{% block content %}
|
||
<div class="coming-apps-page">
|
||
<div class="header">
|
||
<a href="{{ url_for('more') }}" class="back-link" title="返回">
|
||
<i class="fas fa-arrow-left"></i>
|
||
</a>
|
||
<h1>心愿单</h1>
|
||
<button class="add-btn" onclick="showAddDialog()">
|
||
<i class="fas fa-plus"></i>
|
||
</button>
|
||
</div>
|
||
|
||
<!-- 添加提示消息 -->
|
||
<div id="toast" class="developing-tip">
|
||
<span id="toastMessage"></span>
|
||
</div>
|
||
|
||
<div class="wishlist-container">
|
||
<!-- 添加排行榜链接 -->
|
||
<div class="leaderboard-section">
|
||
<a href="{{ url_for('invite_leaderboard') }}" class="leaderboard-link">
|
||
<i class="fas fa-trophy"></i>
|
||
邀请排行榜
|
||
</a>
|
||
</div>
|
||
|
||
<!-- 添加邮件通知提示 -->
|
||
<div class="notification-tip">
|
||
<div class="tip-content">
|
||
<i class="fas fa-envelope"></i>
|
||
<span>
|
||
{% if session.huawei_user.email %}
|
||
应用上架后将通过邮箱 {{ session.huawei_user.email }} 通知您
|
||
{% else %}
|
||
绑定邮箱后可以收到应用上架通知
|
||
<button class="bind-email-btn" onclick="window.location.href='{{ url_for('user_profile') }}'">
|
||
去绑定
|
||
</button>
|
||
{% endif %}
|
||
</span>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 添加邀请提示 -->
|
||
<div class="notification-tip invite-tip">
|
||
<div class="tip-content">
|
||
<i class="fas fa-gift"></i>
|
||
<span>
|
||
{% if session.huawei_user.unlocked_features %}
|
||
您已成功邀请3位好友,已解锁20个心愿单名额
|
||
{% else %}
|
||
邀请3位好友使用,即可解锁20个心愿单名额(已邀请 <span id="inviteCount">0</span>/3 位)
|
||
{% endif %}
|
||
<button class="invite-btn" onclick="showInviteDialog()">
|
||
立即邀请
|
||
</button>
|
||
</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div id="wishlist-items">
|
||
<!-- 这里会通过 JavaScript 动态加载心愿单内容 -->
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 添加应用弹窗 -->
|
||
<div id="addDialog" class="modal">
|
||
<div class="modal-content">
|
||
<div class="modal-header">
|
||
<h3>添加心愿应用</h3>
|
||
<button class="close-btn" onclick="closeDialog()">
|
||
<i class="fas fa-times"></i>
|
||
</button>
|
||
</div>
|
||
<div class="modal-tip">
|
||
<i class="fas fa-exclamation-circle"></i>
|
||
<span>请正确输入应用名称,否则无法收到上架通知</span>
|
||
</div>
|
||
<input type="text"
|
||
id="appName"
|
||
class="app-input"
|
||
placeholder="输入应用名称"
|
||
maxlength="50">
|
||
<div class="modal-actions">
|
||
<button class="cancel-btn" onclick="closeDialog()">取消</button>
|
||
<button class="confirm-btn" onclick="addToWishlist()">添加</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 添加邀请弹窗 -->
|
||
<div id="inviteDialog" class="modal">
|
||
<div class="modal-content">
|
||
<div class="modal-header">
|
||
<h3>邀请好友</h3>
|
||
<button class="close-btn" onclick="closeInviteDialog()">
|
||
<i class="fas fa-times"></i>
|
||
</button>
|
||
</div>
|
||
<div class="invite-info">
|
||
<p>已邀请 <span id="inviteCount">0</span> 位好友</p>
|
||
<p>邀请链接:</p>
|
||
<div class="invite-link">
|
||
<input type="text" id="inviteUrl" readonly>
|
||
<button onclick="copyInviteUrl()">复制</button>
|
||
</div>
|
||
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<style>
|
||
/* 使用与 coming 页面相同的 header 样式 */
|
||
.coming-apps-page {
|
||
max-width: 1200px;
|
||
margin: 0 auto;
|
||
padding: 20px 15px;
|
||
}
|
||
|
||
.header {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 15px;
|
||
margin-bottom: 30px;
|
||
background: white;
|
||
padding: 10px 15px;
|
||
border-radius: 12px;
|
||
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
|
||
position: fixed;
|
||
top: 0;
|
||
left: 0;
|
||
right: 0;
|
||
z-index: 100;
|
||
}
|
||
|
||
.back-link {
|
||
color: #666;
|
||
text-decoration: none;
|
||
padding: 8px;
|
||
border-radius: 50%;
|
||
background: #f5f5f7;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
width: 32px;
|
||
height: 32px;
|
||
}
|
||
|
||
.back-link:hover {
|
||
background: #e5e5e7;
|
||
color: #333;
|
||
}
|
||
|
||
.header h1 {
|
||
margin: 0;
|
||
font-size: 20px;
|
||
color: #333;
|
||
font-weight: 500;
|
||
flex: 1;
|
||
}
|
||
|
||
.add-btn {
|
||
padding: 8px;
|
||
border: none;
|
||
border-radius: 50%;
|
||
background: #f5f5f7;
|
||
color: #666;
|
||
cursor: pointer;
|
||
width: 32px;
|
||
height: 32px;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
transition: all 0.3s ease;
|
||
}
|
||
|
||
.add-btn:hover {
|
||
background: #e5e5e7;
|
||
color: #333;
|
||
}
|
||
|
||
.wishlist-container {
|
||
margin-top: 50px;
|
||
}
|
||
|
||
.wishlist-item {
|
||
background: white;
|
||
border-radius: 12px;
|
||
padding: 15px;
|
||
margin-bottom: 10px;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
|
||
}
|
||
|
||
.wishlist-item-name {
|
||
font-size: 16px;
|
||
color: #333;
|
||
}
|
||
|
||
.delete-btn {
|
||
padding: 8px;
|
||
border: none;
|
||
background: transparent;
|
||
color: #ff4d4f;
|
||
cursor: pointer;
|
||
opacity: 1;
|
||
transition: opacity 0.3s ease;
|
||
border-radius: 50%;
|
||
}
|
||
|
||
.delete-btn:hover {
|
||
background: rgba(255, 77, 79, 0.1);
|
||
}
|
||
|
||
.empty-tip {
|
||
text-align: center;
|
||
color: #999;
|
||
padding: 30px;
|
||
background: white;
|
||
border-radius: 12px;
|
||
margin-top: 20px;
|
||
}
|
||
|
||
/* 暗色模式适配 */
|
||
[data-theme="dark"] .header {
|
||
background: #242424;
|
||
}
|
||
|
||
[data-theme="dark"] .header h1 {
|
||
color: #fff;
|
||
}
|
||
|
||
[data-theme="dark"] .back-link,
|
||
[data-theme="dark"] .add-btn {
|
||
background: #333;
|
||
color: #ccc;
|
||
}
|
||
|
||
[data-theme="dark"] .back-link:hover,
|
||
[data-theme="dark"] .add-btn:hover {
|
||
background: #444;
|
||
color: #fff;
|
||
}
|
||
|
||
[data-theme="dark"] .wishlist-item {
|
||
background: #242424;
|
||
}
|
||
|
||
[data-theme="dark"] .wishlist-item-name {
|
||
color: #fff;
|
||
}
|
||
|
||
[data-theme="dark"] .empty-tip {
|
||
background: #242424;
|
||
color: #666;
|
||
}
|
||
|
||
|
||
footer,
|
||
.footer {
|
||
display: none !important;
|
||
}
|
||
|
||
/* 弹窗样式优化 */
|
||
.modal {
|
||
display: none;
|
||
position: fixed;
|
||
top: 0;
|
||
left: 0;
|
||
right: 0;
|
||
bottom: 0;
|
||
background: rgba(0, 0, 0, 0.5);
|
||
z-index: 1000;
|
||
align-items: center;
|
||
justify-content: center;
|
||
animation: modalFadeIn 0.3s ease;
|
||
}
|
||
|
||
.modal-content {
|
||
background: white;
|
||
border-radius: 16px;
|
||
padding: 20px;
|
||
max-width: 400px;
|
||
width: 90%;
|
||
position: relative;
|
||
}
|
||
|
||
.modal-header {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
margin-bottom: 15px;
|
||
}
|
||
|
||
.modal-header h3 {
|
||
margin: 0;
|
||
font-size: 18px;
|
||
font-weight: 500;
|
||
color: #333;
|
||
}
|
||
|
||
.close-btn {
|
||
padding: 8px;
|
||
border: none;
|
||
background: transparent;
|
||
color: #999;
|
||
cursor: pointer;
|
||
border-radius: 50%;
|
||
width: 32px;
|
||
height: 32px;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
transition: all 0.3s ease;
|
||
}
|
||
|
||
.close-btn:hover {
|
||
background: #f5f5f5;
|
||
color: #666;
|
||
}
|
||
|
||
.app-input {
|
||
width: 100%;
|
||
padding: 12px;
|
||
border: 1px solid #ddd;
|
||
border-radius: 8px;
|
||
margin-bottom: 20px;
|
||
font-size: 14px;
|
||
transition: all 0.3s ease;
|
||
}
|
||
|
||
.app-input:focus {
|
||
border-color: #1890ff;
|
||
box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.1);
|
||
outline: none;
|
||
}
|
||
|
||
.modal-actions {
|
||
display: flex;
|
||
justify-content: flex-end;
|
||
gap: 12px;
|
||
}
|
||
|
||
.cancel-btn,
|
||
.confirm-btn {
|
||
padding: 8px 20px;
|
||
border: none;
|
||
border-radius: 6px;
|
||
font-size: 14px;
|
||
cursor: pointer;
|
||
transition: all 0.3s ease;
|
||
}
|
||
|
||
.cancel-btn {
|
||
background: #f5f5f5;
|
||
color: #666;
|
||
}
|
||
|
||
.cancel-btn:hover {
|
||
background: #e8e8e8;
|
||
}
|
||
|
||
.confirm-btn {
|
||
background: #1890ff;
|
||
color: white;
|
||
}
|
||
|
||
.confirm-btn:hover {
|
||
background: #40a9ff;
|
||
}
|
||
|
||
@keyframes modalFadeIn {
|
||
from {
|
||
opacity: 0;
|
||
}
|
||
to {
|
||
opacity: 1;
|
||
}
|
||
}
|
||
|
||
@keyframes modalSlideIn {
|
||
from {
|
||
opacity: 0;
|
||
transform: translateY(-20px);
|
||
}
|
||
to {
|
||
opacity: 1;
|
||
transform: translateY(0);
|
||
}
|
||
}
|
||
|
||
/* 暗色模式适配 */
|
||
[data-theme="dark"] .modal-content {
|
||
background: #242424;
|
||
border: 1px solid #333;
|
||
}
|
||
|
||
[data-theme="dark"] .modal-header {
|
||
border-bottom-color: #333;
|
||
}
|
||
|
||
[data-theme="dark"] .modal-header h3 {
|
||
color: #fff;
|
||
}
|
||
|
||
[data-theme="dark"] .invite-info {
|
||
color: #ccc;
|
||
}
|
||
|
||
[data-theme="dark"] .invite-link {
|
||
background: #1a1a1a;
|
||
border-color: #333;
|
||
}
|
||
|
||
[data-theme="dark"] .invite-link input {
|
||
background: #1a1a1a;
|
||
color: #fff;
|
||
border-color: #333;
|
||
}
|
||
|
||
[data-theme="dark"] .invite-link button {
|
||
background: #333;
|
||
color: #fff;
|
||
border-color: #444;
|
||
}
|
||
|
||
[data-theme="dark"] .invite-link button:hover {
|
||
background: #444;
|
||
}
|
||
|
||
[data-theme="dark"] .invite-qrcode {
|
||
background: #1a1a1a;
|
||
border: 1px solid #333;
|
||
padding: 10px;
|
||
border-radius: 8px;
|
||
}
|
||
|
||
.invite-info {
|
||
text-align: center;
|
||
}
|
||
|
||
.invite-info p {
|
||
margin: 12px 0;
|
||
color: #666;
|
||
font-size: 14px;
|
||
}
|
||
|
||
.invite-link {
|
||
display: flex;
|
||
gap: 8px;
|
||
margin: 16px 0;
|
||
padding: 8px;
|
||
background: #f5f5f7;
|
||
border-radius: 8px;
|
||
border: 1px solid #eee;
|
||
}
|
||
|
||
.invite-link input {
|
||
flex: 1;
|
||
border: none;
|
||
background: transparent;
|
||
padding: 4px 8px;
|
||
font-size: 14px;
|
||
}
|
||
|
||
.invite-link button {
|
||
padding: 4px 12px;
|
||
border-radius: 4px;
|
||
border: 1px solid #ddd;
|
||
background: white;
|
||
color: #666;
|
||
cursor: pointer;
|
||
transition: all 0.3s ease;
|
||
}
|
||
|
||
.invite-link button:hover {
|
||
background: #f5f5f7;
|
||
color: #333;
|
||
}
|
||
|
||
.invite-qrcode {
|
||
width: 148px;
|
||
height: 148px;
|
||
margin: 20px auto;
|
||
background: white;
|
||
padding: 10px;
|
||
border-radius: 8px;
|
||
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
|
||
}
|
||
|
||
.invite-qrcode img {
|
||
width: 100%;
|
||
height: 100%;
|
||
}
|
||
|
||
/* 邮件通知提示样式 */
|
||
.notification-tip {
|
||
background: rgba(24, 144, 255, 0.1);
|
||
border-radius: 12px;
|
||
padding: 15px;
|
||
margin-bottom: 20px;
|
||
}
|
||
|
||
.tip-content {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 12px;
|
||
color: #1890ff;
|
||
font-size: 14px;
|
||
}
|
||
|
||
.tip-content i {
|
||
font-size: 18px;
|
||
}
|
||
|
||
.bind-email-btn {
|
||
border: none;
|
||
background: #1890ff;
|
||
color: white;
|
||
padding: 4px 12px;
|
||
border-radius: 4px;
|
||
margin-left: 8px;
|
||
cursor: pointer;
|
||
font-size: 12px;
|
||
transition: all 0.3s ease;
|
||
}
|
||
|
||
.bind-email-btn:hover {
|
||
background: #40a9ff;
|
||
}
|
||
|
||
/* 暗色模式适配 */
|
||
[data-theme="dark"] .notification-tip {
|
||
background: rgba(24, 144, 255, 0.1);
|
||
}
|
||
|
||
[data-theme="dark"] .tip-content {
|
||
color: #40a9ff;
|
||
}
|
||
|
||
[data-theme="dark"] .bind-email-btn {
|
||
background: #1890ff;
|
||
}
|
||
|
||
[data-theme="dark"] .bind-email-btn:hover {
|
||
background: #40a9ff;
|
||
}
|
||
|
||
.modal-tip {
|
||
margin: 0 0 15px;
|
||
padding: 12px 15px;
|
||
background: #fff2f0;
|
||
border-radius: 8px;
|
||
color: #ff4d4f;
|
||
font-size: 14px;
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 10px;
|
||
line-height: 1.4;
|
||
}
|
||
|
||
.modal-tip i {
|
||
font-size: 16px;
|
||
flex-shrink: 0;
|
||
}
|
||
|
||
/* 暗色模式适配 */
|
||
[data-theme="dark"] .modal-tip {
|
||
background: rgba(255, 77, 79, 0.1);
|
||
color: #ff7875;
|
||
}
|
||
/* 提示消息样式 */
|
||
.developing-tip {
|
||
position: fixed;
|
||
bottom: 100px;
|
||
left: 50%;
|
||
transform: translateX(-50%);
|
||
background: rgba(0, 0, 0, 0.8);
|
||
color: white;
|
||
padding: 10px 20px;
|
||
border-radius: 25px;
|
||
font-size: 14px;
|
||
z-index: 1000;
|
||
opacity: 0;
|
||
transition: opacity 0.3s ease, transform 0.3s ease;
|
||
pointer-events: none;
|
||
transform: translate(-50%, 20px);
|
||
}
|
||
|
||
[data-theme="dark"] .developing-tip {
|
||
background: rgba(255, 255, 255, 0.9);
|
||
color: black;
|
||
}
|
||
|
||
.developing-tip.show {
|
||
opacity: 1;
|
||
transform: translate(-50%, 0);
|
||
}
|
||
|
||
/* 添加动画效果 */
|
||
@keyframes tipAppear {
|
||
0% {
|
||
opacity: 0;
|
||
transform: translate(-50%, 20px);
|
||
}
|
||
20% {
|
||
opacity: 1;
|
||
transform: translate(-50%, 0);
|
||
}
|
||
80% {
|
||
opacity: 1;
|
||
transform: translate(-50%, 0);
|
||
}
|
||
100% {
|
||
opacity: 0;
|
||
transform: translate(-50%, -20px);
|
||
}
|
||
}
|
||
|
||
.developing-tip.show {
|
||
animation: tipAppear 2s ease forwards;
|
||
}
|
||
|
||
.item-actions {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 12px;
|
||
}
|
||
|
||
.notified-tag {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 4px;
|
||
padding: 4px 8px;
|
||
background: rgba(82, 196, 26, 0.1);
|
||
color: #52c41a;
|
||
border-radius: 4px;
|
||
font-size: 12px;
|
||
}
|
||
|
||
.notified-tag i {
|
||
font-size: 12px;
|
||
}
|
||
|
||
/* 暗色模式适配 */
|
||
[data-theme="dark"] .notified-tag {
|
||
background: rgba(82, 196, 26, 0.1);
|
||
color: #73d13d;
|
||
}
|
||
|
||
/* 添加最大数量限制提示样式 */
|
||
.limit-tip {
|
||
text-align: center;
|
||
color: #ff4d4f;
|
||
padding: 12px;
|
||
background: rgba(255, 77, 79, 0.1);
|
||
border-radius: 8px;
|
||
margin-top: 15px;
|
||
font-size: 14px;
|
||
}
|
||
|
||
/* 暗色模式适配 */
|
||
[data-theme="dark"] .limit-tip {
|
||
background: rgba(255, 77, 79, 0.1);
|
||
color: #ff7875;
|
||
}
|
||
|
||
/* 添加邀请相关样式 */
|
||
.invite-tip {
|
||
background: rgba(82, 196, 26, 0.1);
|
||
margin-top: 10px;
|
||
}
|
||
|
||
.invite-tip .tip-content {
|
||
color: #52c41a;
|
||
}
|
||
|
||
.invite-btn {
|
||
border: none;
|
||
background: #52c41a;
|
||
color: white;
|
||
padding: 4px 12px;
|
||
border-radius: 4px;
|
||
margin-left: 8px;
|
||
cursor: pointer;
|
||
font-size: 12px;
|
||
transition: all 0.3s ease;
|
||
}
|
||
|
||
.invite-btn:hover {
|
||
background: #73d13d;
|
||
}
|
||
|
||
.invite-info {
|
||
padding: 20px;
|
||
text-align: center;
|
||
}
|
||
|
||
.invite-link {
|
||
display: flex;
|
||
gap: 10px;
|
||
margin: 15px 0;
|
||
}
|
||
|
||
.invite-link input {
|
||
flex: 1;
|
||
padding: 8px;
|
||
border: 1px solid #ddd;
|
||
border-radius: 4px;
|
||
}
|
||
|
||
.invite-link button {
|
||
padding: 8px 16px;
|
||
background: #1890ff;
|
||
color: white;
|
||
border: none;
|
||
border-radius: 4px;
|
||
cursor: pointer;
|
||
}
|
||
|
||
.invite-qrcode {
|
||
margin-top: 20px;
|
||
}
|
||
|
||
/* 暗色模式适配 */
|
||
[data-theme="dark"] .invite-tip {
|
||
background: rgba(82, 196, 26, 0.1);
|
||
}
|
||
|
||
[data-theme="dark"] .invite-tip .tip-content {
|
||
color: #73d13d;
|
||
}
|
||
|
||
[data-theme="dark"] .invite-link input {
|
||
background: #333;
|
||
border-color: #444;
|
||
color: #fff;
|
||
}
|
||
|
||
.leaderboard-link {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
gap: 4px;
|
||
color: #52c41a;
|
||
text-decoration: none;
|
||
padding: 4px 12px;
|
||
border-radius: 4px;
|
||
background: rgba(82, 196, 26, 0.1);
|
||
transition: all 0.3s ease;
|
||
}
|
||
|
||
.leaderboard-link:hover {
|
||
background: rgba(82, 196, 26, 0.2);
|
||
}
|
||
|
||
[data-theme="dark"] .leaderboard-link {
|
||
color: #73d13d;
|
||
background: rgba(82, 196, 26, 0.2);
|
||
}
|
||
|
||
[data-theme="dark"] .leaderboard-link:hover {
|
||
background: rgba(82, 196, 26, 0.3);
|
||
}
|
||
|
||
/* 排行榜区域样式 */
|
||
.leaderboard-section {
|
||
margin-bottom: 15px;
|
||
background: white;
|
||
border-radius: 12px;
|
||
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
|
||
overflow: hidden;
|
||
}
|
||
|
||
.leaderboard-section .leaderboard-link {
|
||
width: 100%;
|
||
display: inline-flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
gap: 6px;
|
||
color: #6366f1;
|
||
text-decoration: none;
|
||
padding: 8px 16px;
|
||
border-radius: 8px;
|
||
background: rgba(99, 102, 241, 0.1);
|
||
transition: all 0.3s ease;
|
||
font-size: 14px;
|
||
box-sizing: border-box;
|
||
}
|
||
|
||
.leaderboard-section .leaderboard-link:hover {
|
||
background: rgba(99, 102, 241, 0.2);
|
||
}
|
||
|
||
[data-theme="dark"] .leaderboard-section .leaderboard-link {
|
||
color: #818cf8;
|
||
background: rgba(99, 102, 241, 0.2);
|
||
}
|
||
|
||
[data-theme="dark"] .leaderboard-section .leaderboard-link:hover {
|
||
background: rgba(99, 102, 241, 0.3);
|
||
}
|
||
</style>
|
||
|
||
<script>
|
||
// Toast 提示函数
|
||
function showToast(message) {
|
||
const toast = document.getElementById('toast');
|
||
const toastMessage = document.getElementById('toastMessage');
|
||
toastMessage.textContent = message;
|
||
toast.classList.add('show');
|
||
|
||
setTimeout(() => {
|
||
toast.classList.remove('show');
|
||
}, 2000);
|
||
}
|
||
|
||
// 加载心愿单
|
||
function loadWishlist() {
|
||
fetch('/user/wishlist/list')
|
||
.then(response => response.json())
|
||
.then(data => {
|
||
const container = document.getElementById('wishlist-items');
|
||
if (data.success) {
|
||
if (data.items.length === 0) {
|
||
container.innerHTML = `
|
||
<div class="empty-tip">
|
||
<i class="fas fa-inbox"></i>
|
||
<p>还没有添加任何应用</p>
|
||
</div>
|
||
`;
|
||
} else {
|
||
container.innerHTML = data.items.map(item => `
|
||
<div class="wishlist-item">
|
||
<div class="wishlist-item-name">${item.app_name}</div>
|
||
<div class="item-actions">
|
||
${item.notified ? `
|
||
<div class="notified-tag">
|
||
<i class="fas fa-check"></i>
|
||
已上架
|
||
</div>
|
||
` : ''}
|
||
<button class="delete-btn" onclick="deleteItem(${item.id})" title="删除">
|
||
<i class="fas fa-trash"></i>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
`).join('');
|
||
}
|
||
} else {
|
||
container.innerHTML = `
|
||
<div class="error-tip">
|
||
加载失败,请稍后重试
|
||
</div>
|
||
`;
|
||
}
|
||
})
|
||
.catch(error => {
|
||
console.error('Load wishlist failed:', error);
|
||
document.getElementById('wishlist-items').innerHTML = `
|
||
<div class="error-tip">
|
||
加载失败,请稍后重试
|
||
</div>
|
||
`;
|
||
});
|
||
}
|
||
|
||
// 显示添加弹窗
|
||
function showAddDialog() {
|
||
// 检查当前心愿单数量和限制
|
||
fetch('/user/wishlist/list')
|
||
.then(response => response.json())
|
||
.then(data => {
|
||
if (data.success) {
|
||
const limit = data.unlocked ? 20 : 5;
|
||
if (data.items.length >= limit) {
|
||
if (limit === 5) {
|
||
showToast('当前最多添加5个应用,邀请3位好友可提升至20个');
|
||
} else {
|
||
showToast('已达到心愿单上限(20个)');
|
||
}
|
||
return;
|
||
}
|
||
// 显示添加弹窗
|
||
const dialog = document.getElementById('addDialog');
|
||
const input = document.getElementById('appName');
|
||
dialog.style.display = 'flex';
|
||
input.value = '';
|
||
input.focus();
|
||
} else {
|
||
showToast(data.error || '加载失败');
|
||
}
|
||
})
|
||
.catch(error => {
|
||
console.error('Load wishlist failed:', error);
|
||
showToast('加载失败,请稍后重试');
|
||
});
|
||
}
|
||
|
||
// 关闭弹窗
|
||
function closeDialog() {
|
||
const dialog = document.getElementById('addDialog');
|
||
dialog.style.display = 'none';
|
||
}
|
||
|
||
// 添加到心愿单
|
||
function addToWishlist() {
|
||
const input = document.getElementById('appName');
|
||
const appName = input.value.trim();
|
||
|
||
if (!appName) {
|
||
showToast('请输入应用名称');
|
||
return;
|
||
}
|
||
|
||
// 检查应用名称长度
|
||
if (appName.length > 50) {
|
||
showToast('应用名称过长');
|
||
return;
|
||
}
|
||
|
||
fetch('/user/wishlist/add', {
|
||
method: 'POST',
|
||
headers: {
|
||
'Content-Type': 'application/json'
|
||
},
|
||
body: JSON.stringify({
|
||
app_name: appName
|
||
})
|
||
})
|
||
.then(response => response.json())
|
||
.then(data => {
|
||
if (data.success) {
|
||
closeDialog();
|
||
loadWishlist();
|
||
showToast('添加成功');
|
||
} else {
|
||
// 如果是限制相关的错误,显示更友好的提示
|
||
if (data.error.includes('邀请3位好友')) {
|
||
showToast('当前最多添加5个应用,邀请3位好友可提升至20个');
|
||
} else if (data.error.includes('已达到心愿单上限')) {
|
||
showToast('已达到心愿单上限(20个)');
|
||
} else {
|
||
showToast(data.error || '添加失败');
|
||
}
|
||
}
|
||
})
|
||
.catch(error => {
|
||
console.error('Add to wishlist failed:', error);
|
||
showToast('添加失败,请稍后重试');
|
||
});
|
||
}
|
||
|
||
// 删除心愿单项目
|
||
function deleteItem(id) {
|
||
if (!confirm('确定要删除这个应用吗?')) return;
|
||
|
||
fetch(`/user/wishlist/delete/${id}`, {
|
||
method: 'POST'
|
||
})
|
||
.then(response => response.json())
|
||
.then(data => {
|
||
if (data.success) {
|
||
loadWishlist();
|
||
showToast('删除成功');
|
||
} else {
|
||
showToast(data.error || '删除失败');
|
||
}
|
||
})
|
||
.catch(error => {
|
||
console.error('Delete wishlist item failed:', error);
|
||
showToast('删除失败,请稍后重试');
|
||
});
|
||
}
|
||
|
||
// 添加键盘事件处理
|
||
document.addEventListener('keydown', function(e) {
|
||
if (e.key === 'Escape') {
|
||
closeDialog();
|
||
}
|
||
|
||
if (e.key === 'Enter' && document.getElementById('addDialog').style.display === 'flex') {
|
||
addToWishlist();
|
||
}
|
||
});
|
||
|
||
// 点击遮罩层关闭弹窗
|
||
document.getElementById('addDialog').addEventListener('click', function(e) {
|
||
if (e.target === this) {
|
||
closeDialog();
|
||
}
|
||
});
|
||
|
||
// 页面加载时获取心愿单
|
||
document.addEventListener('DOMContentLoaded', loadWishlist);
|
||
|
||
// 获取邀请信息
|
||
function loadInviteInfo() {
|
||
fetch('/user/invite_code')
|
||
.then(response => response.json())
|
||
.then(data => {
|
||
if (data.success) {
|
||
document.getElementById('inviteCount').textContent = data.invite_count;
|
||
document.getElementById('inviteUrl').value = data.invite_url;
|
||
|
||
// 更新邀请提示文本
|
||
const tipContent = document.querySelector('.invite-tip .tip-content span');
|
||
if (data.unlocked) {
|
||
tipContent.innerHTML = `
|
||
您已成功邀请3位好友,已解锁20个心愿单名额
|
||
<button class="invite-btn" onclick="showInviteDialog()">
|
||
立即邀请
|
||
</button>
|
||
`;
|
||
} else {
|
||
tipContent.innerHTML = `
|
||
邀请3位好友使用,即可解锁20个心愿单名额(已邀请 ${data.invite_count}/3 位)
|
||
<button class="invite-btn" onclick="showInviteDialog()">
|
||
立即邀请
|
||
</button>
|
||
`;
|
||
}
|
||
|
||
// 生成二维码
|
||
new QRCode(document.getElementById('inviteQrcode'), {
|
||
text: data.invite_url,
|
||
width: 128,
|
||
height: 128
|
||
});
|
||
}
|
||
});
|
||
}
|
||
|
||
function showInviteDialog() {
|
||
const dialog = document.getElementById('inviteDialog');
|
||
dialog.style.display = 'flex';
|
||
loadInviteInfo();
|
||
}
|
||
|
||
function closeInviteDialog() {
|
||
document.getElementById('inviteDialog').style.display = 'none';
|
||
}
|
||
|
||
function copyInviteUrl() {
|
||
const input = document.getElementById('inviteUrl');
|
||
input.select();
|
||
document.execCommand('copy');
|
||
showToast('邀请链接已复制');
|
||
}
|
||
|
||
// 页面加载时获取心愿单和邀请信息
|
||
document.addEventListener('DOMContentLoaded', () => {
|
||
loadWishlist();
|
||
loadInviteInfo();
|
||
});
|
||
</script>
|
||
|
||
{% endblock %}
|
||
|
||
{% block footer %}{% endblock %} |