1、修改左上角背景图颜色修改
2、左下角文字变大 3、默认账户名字修改 4、右下角联系我们修改位置跟可以移动
This commit is contained in:
@@ -253,6 +253,7 @@ async def get_me(
|
|||||||
current_user: User = Depends(get_current_user_allow_password_pending),
|
current_user: User = Depends(get_current_user_allow_password_pending),
|
||||||
db: AsyncSession = Depends(get_db),
|
db: AsyncSession = Depends(get_db),
|
||||||
):
|
):
|
||||||
|
current_user.username = "用户"+current_user.username[-4:] if current_user.username == current_user.phone else current_user.username
|
||||||
current_user.credits = round(current_user.credits, 2)
|
current_user.credits = round(current_user.credits, 2)
|
||||||
resource_capacity = await get_user_resource_capacity_usage(db, current_user.id)
|
resource_capacity = await get_user_resource_capacity_usage(db, current_user.id)
|
||||||
return UserOut.model_validate(current_user).model_copy(
|
return UserOut.model_validate(current_user).model_copy(
|
||||||
|
|||||||
+41
-41
File diff suppressed because one or more lines are too long
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+2
-2
@@ -28,8 +28,8 @@
|
|||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
</script>
|
</script>
|
||||||
<script type="module" crossorigin src="/assets/index-C9YKdZ8m.js"></script>
|
<script type="module" crossorigin src="/assets/index-D1wOjhOn.js"></script>
|
||||||
<link rel="stylesheet" crossorigin href="/assets/index-DgpxHlJ1.css">
|
<link rel="stylesheet" crossorigin href="/assets/index-D3IaMBsq.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="root"></div>
|
<div id="root"></div>
|
||||||
|
|||||||
@@ -85,8 +85,9 @@
|
|||||||
.contact-button-wrapper {
|
.contact-button-wrapper {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
right: 24px;
|
right: 24px;
|
||||||
bottom: 24px;
|
bottom: 25%;
|
||||||
z-index: 1000;
|
z-index: 1000;
|
||||||
|
cursor: move;
|
||||||
}
|
}
|
||||||
|
|
||||||
.contact-tooltip {
|
.contact-tooltip {
|
||||||
@@ -94,7 +95,7 @@
|
|||||||
right: 64px;
|
right: 64px;
|
||||||
bottom: 8px;
|
bottom: 8px;
|
||||||
padding: 8px 16px;
|
padding: 8px 16px;
|
||||||
background: #1e293b;
|
background: rgba(30, 41, 59, 0.9);
|
||||||
color: #ffffff;
|
color: #ffffff;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
@@ -108,19 +109,26 @@
|
|||||||
height: 40px;
|
height: 40px;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
border: none;
|
border: none;
|
||||||
background: linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%);
|
background: linear-gradient(135deg, rgba(99, 102, 241, 0.8) 0%, rgba(139, 92, 246, 0.8) 100%);
|
||||||
color: #ffffff;
|
color: #ffffff;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
box-shadow: 0 4px 20px rgba(99, 102, 241, 0.4);
|
box-shadow: 0 4px 20px rgba(99, 102, 241, 0.3);
|
||||||
transition: all 0.3s ease;
|
transition: all 0.3s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
.contact-button:hover {
|
.contact-button:hover {
|
||||||
transform: scale(1.05);
|
transform: scale(1.05);
|
||||||
box-shadow: 0 6px 24px rgba(99, 102, 241, 0.5);
|
background: linear-gradient(135deg, rgba(99, 102, 241, 0.95) 0%, rgba(139, 92, 246, 0.95) 100%);
|
||||||
|
box-shadow: 0 6px 24px rgba(99, 102, 241, 0.4);
|
||||||
|
}
|
||||||
|
|
||||||
|
.contact-button.dragging {
|
||||||
|
cursor: grabbing;
|
||||||
|
transform: scale(1.1);
|
||||||
|
box-shadow: 0 8px 30px rgba(99, 102, 241, 0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 767px) {
|
@media (max-width: 767px) {
|
||||||
|
|||||||
@@ -136,12 +136,19 @@ const AppLayout: React.FC = () => {
|
|||||||
const { user, logout } = useAuthStore();
|
const { user, logout } = useAuthStore();
|
||||||
const [pwdModalOpen, setPwdModalOpen] = useState(false);
|
const [pwdModalOpen, setPwdModalOpen] = useState(false);
|
||||||
const [rechargeModalOpen, setRechargeModalOpen] = useState(false);
|
const [rechargeModalOpen, setRechargeModalOpen] = useState(false);
|
||||||
|
const [contactModalOpen, setContactModalOpen] = useState(false);
|
||||||
const [pwdForm] = Form.useForm();
|
const [pwdForm] = Form.useForm();
|
||||||
const [selectedPlan, setSelectedPlan] = useState<number | null>(null);
|
const [selectedPlan, setSelectedPlan] = useState<number | null>(null);
|
||||||
const [menuItems, setMenuItems] = useState<MenuConfig[]>([]);
|
const [menuItems, setMenuItems] = useState<MenuConfig[]>([]);
|
||||||
const [rechargeOptions, setRechargeOptions] = useState<any[]>([]);
|
const [rechargeOptions, setRechargeOptions] = useState<any[]>([]);
|
||||||
const [unreadCount, setUnreadCount] = useState(0);
|
const [unreadCount, setUnreadCount] = useState(0);
|
||||||
const [mobileMenuOpen, setMobileMenuOpen] = useState(false);
|
const [mobileMenuOpen, setMobileMenuOpen] = useState(false);
|
||||||
|
const [contactHovered, setContactHovered] = useState(false);
|
||||||
|
const [contactForm] = Form.useForm();
|
||||||
|
const [submittingContact, setSubmittingContact] = useState(false);
|
||||||
|
const [contactPosition, setContactPosition] = useState<{ x: number; y: number | string }>({ x: 24, y: '25%' });
|
||||||
|
const [isDragging, setIsDragging] = useState(false);
|
||||||
|
const [dragStart, setDragStart] = useState({ x: 0, y: 0 });
|
||||||
const [mobileExpandedMenus, setMobileExpandedMenus] = useState<Record<string, boolean>>({});
|
const [mobileExpandedMenus, setMobileExpandedMenus] = useState<Record<string, boolean>>({});
|
||||||
const [siteName, setSiteName] = useState(() => {
|
const [siteName, setSiteName] = useState(() => {
|
||||||
const cached = localStorage.getItem('siteInfo');
|
const cached = localStorage.getItem('siteInfo');
|
||||||
@@ -174,10 +181,6 @@ const AppLayout: React.FC = () => {
|
|||||||
const countdownTimerRef = useRef<ReturnType<typeof setInterval> | null>(null);
|
const countdownTimerRef = useRef<ReturnType<typeof setInterval> | null>(null);
|
||||||
const currentOrderNoRef = useRef<string | null>(null);
|
const currentOrderNoRef = useRef<string | null>(null);
|
||||||
const [enabledMethods, setEnabledMethods] = useState<{ alipay: boolean; wechat: boolean }>({ alipay: false, wechat: false });
|
const [enabledMethods, setEnabledMethods] = useState<{ alipay: boolean; wechat: boolean }>({ alipay: false, wechat: false });
|
||||||
const [contactModalOpen, setContactModalOpen] = useState(false);
|
|
||||||
const [contactForm] = Form.useForm();
|
|
||||||
const [contactHovered, setContactHovered] = useState(false);
|
|
||||||
const [submittingContact, setSubmittingContact] = useState(false);
|
|
||||||
|
|
||||||
const PENDING_ORDER_KEY = 'pending_payment_order';
|
const PENDING_ORDER_KEY = 'pending_payment_order';
|
||||||
|
|
||||||
@@ -207,6 +210,40 @@ const AppLayout: React.FC = () => {
|
|||||||
}).catch(() => { });
|
}).catch(() => { });
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
const handleContactMouseDown = (e: React.MouseEvent) => {
|
||||||
|
if (e.button === 0) {
|
||||||
|
setIsDragging(true);
|
||||||
|
setDragStart({
|
||||||
|
x: e.clientX - contactPosition.x,
|
||||||
|
y: typeof contactPosition.y === 'string' ? e.clientY - (window.innerHeight * parseInt(contactPosition.y) / 100) : e.clientY - contactPosition.y,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleContactMouseMove = (e: MouseEvent) => {
|
||||||
|
if (!isDragging) return;
|
||||||
|
|
||||||
|
const newX = Math.max(16, Math.min(window.innerWidth - 70, e.clientX - dragStart.x));
|
||||||
|
const newY = Math.max(60, Math.min(window.innerHeight - 60, e.clientY - dragStart.y));
|
||||||
|
|
||||||
|
setContactPosition({ x: newX, y: newY });
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleContactMouseUp = () => {
|
||||||
|
setIsDragging(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (isDragging) {
|
||||||
|
document.addEventListener('mousemove', handleContactMouseMove);
|
||||||
|
document.addEventListener('mouseup', handleContactMouseUp);
|
||||||
|
return () => {
|
||||||
|
document.removeEventListener('mousemove', handleContactMouseMove);
|
||||||
|
document.removeEventListener('mouseup', handleContactMouseUp);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}, [isDragging, dragStart]);
|
||||||
|
|
||||||
const loadUnreadCount = () => {
|
const loadUnreadCount = () => {
|
||||||
getUnreadCount().then(count => {
|
getUnreadCount().then(count => {
|
||||||
setUnreadCount(count);
|
setUnreadCount(count);
|
||||||
@@ -520,7 +557,7 @@ const AppLayout: React.FC = () => {
|
|||||||
}}>
|
}}>
|
||||||
<div style={{
|
<div style={{
|
||||||
width: 42, height: 42, borderRadius: 14, flexShrink: 0,
|
width: 42, height: 42, borderRadius: 14, flexShrink: 0,
|
||||||
background: 'linear-gradient(135deg, #6366f1 0%, #8b5cf6 50%, #a78bfa 100%)',
|
//background: 'linear-gradient(135deg, #6366f1 0%, #8b5cf6 50%, #a78bfa 100%)',
|
||||||
display: 'flex', alignItems: 'center', justifyContent: 'center',
|
display: 'flex', alignItems: 'center', justifyContent: 'center',
|
||||||
boxShadow: '0 4px 16px rgba(99, 102, 241, 0.35)',
|
boxShadow: '0 4px 16px rgba(99, 102, 241, 0.35)',
|
||||||
overflow: 'hidden',
|
overflow: 'hidden',
|
||||||
@@ -604,12 +641,12 @@ const AppLayout: React.FC = () => {
|
|||||||
boxShadow: '0 4px 12px rgba(99, 102, 241, 0.3)',
|
boxShadow: '0 4px 12px rgba(99, 102, 241, 0.3)',
|
||||||
}} />
|
}} />
|
||||||
<div style={{ flex: 1, minWidth: 0 }}>
|
<div style={{ flex: 1, minWidth: 0 }}>
|
||||||
<div style={{ color: '#1e293b', fontSize: 14, fontWeight: 600, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap', letterSpacing: -0.01 }}>
|
<div style={{ color: '#1e293b', fontSize: 16, fontWeight: 600, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap', letterSpacing: -0.01 }}>
|
||||||
{user?.username}
|
{user?.username}
|
||||||
</div>
|
</div>
|
||||||
<div style={{
|
<div style={{
|
||||||
color: '#6366f1',
|
color: '#6366f1',
|
||||||
fontSize: 12,
|
fontSize: 16,
|
||||||
fontWeight: 500,
|
fontWeight: 500,
|
||||||
letterSpacing: 0,
|
letterSpacing: 0,
|
||||||
background: 'rgba(99, 102, 241, 0.08)',
|
background: 'rgba(99, 102, 241, 0.08)',
|
||||||
@@ -917,8 +954,16 @@ const AppLayout: React.FC = () => {
|
|||||||
gap: 8,
|
gap: 8,
|
||||||
}}>
|
}}>
|
||||||
<InfoOutlined style={{ color: '#6366f1', fontSize: 14 }} />
|
<InfoOutlined style={{ color: '#6366f1', fontSize: 14 }} />
|
||||||
<Typography.Text style={{ color: '#ff0000ff', fontSize: 13 }}>
|
<Typography.Text style={{ color: '#64748b', fontSize: 13 }}>
|
||||||
当前平台仅支持支付宝/微信扫码充值,如需转账支付请联系我们
|
当前平台仅支持支付宝/微信扫码充值,如需转账支付请
|
||||||
|
<Typography.Text
|
||||||
|
style={{
|
||||||
|
color: '#6366f1',
|
||||||
|
cursor: 'pointer',
|
||||||
|
textDecoration: 'underline',
|
||||||
|
}}
|
||||||
|
onClick={() => { setRechargeModalOpen(false); setContactModalOpen(true); }}
|
||||||
|
>联系我们</Typography.Text>
|
||||||
</Typography.Text>
|
</Typography.Text>
|
||||||
</div>
|
</div>
|
||||||
<div style={{ display: 'flex', gap: 12, flexWrap: 'wrap' }}>
|
<div style={{ display: 'flex', gap: 12, flexWrap: 'wrap' }}>
|
||||||
@@ -1193,7 +1238,13 @@ const AppLayout: React.FC = () => {
|
|||||||
|
|
||||||
<NotificationPopup />
|
<NotificationPopup />
|
||||||
|
|
||||||
<div className="contact-button-wrapper">
|
<div
|
||||||
|
className="contact-button-wrapper"
|
||||||
|
style={{
|
||||||
|
right: `${contactPosition.x}px`,
|
||||||
|
bottom: typeof contactPosition.y === 'string' ? contactPosition.y : `${window.innerHeight - contactPosition.y}px`,
|
||||||
|
}}
|
||||||
|
>
|
||||||
<div style={{
|
<div style={{
|
||||||
position: 'relative',
|
position: 'relative',
|
||||||
}}>
|
}}>
|
||||||
@@ -1206,10 +1257,11 @@ const AppLayout: React.FC = () => {
|
|||||||
联系我们
|
联系我们
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
onClick={() => setContactModalOpen(true)}
|
onClick={() => !isDragging && setContactModalOpen(true)}
|
||||||
className="contact-button"
|
className={`contact-button ${isDragging ? 'dragging' : ''}`}
|
||||||
onMouseEnter={() => setContactHovered(true)}
|
onMouseEnter={() => setContactHovered(true)}
|
||||||
onMouseLeave={() => setContactHovered(false)}
|
onMouseLeave={() => setContactHovered(false)}
|
||||||
|
onMouseDown={handleContactMouseDown}
|
||||||
>
|
>
|
||||||
<MessageOutlined style={{ fontSize: 20 }} />
|
<MessageOutlined style={{ fontSize: 20 }} />
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
Reference in New Issue
Block a user