From 848df4c873718da7352b185066834b435a4ea171 Mon Sep 17 00:00:00 2001 From: xiaoquan <838115837@qq.com> Date: Fri, 15 May 2026 19:06:32 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E8=BF=AD=E4=BB=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .claude/settings.local.json | 3 +- apps/merchant-admin/src/pages/Login.css | 319 +++++++++ apps/merchant-admin/src/pages/Login.tsx | 127 +++- apps/miniapp/src/api/seller/room-calendar.ts | 2 +- apps/miniapp/src/api/user/auth.ts | 4 + apps/miniapp/src/api/user/order.ts | 6 +- apps/miniapp/src/api/user/room.ts | 4 +- apps/miniapp/src/pages/login/index.vue | 616 ++++++++++++------ .../src/pages/merchant-detail/index.vue | 16 +- apps/miniapp/src/pages/order-create/index.vue | 64 +- apps/miniapp/src/pages/room-detail/index.vue | 78 ++- apps/miniapp/src/pages/seller/room-form.vue | 34 +- apps/platform-admin/src/pages/Login.css | 267 ++++++++ apps/platform-admin/src/pages/Login.tsx | 101 ++- apps/server/.env.example | 4 +- .../src/modules/app/auth/auth.controller.ts | 7 + .../src/modules/app/auth/auth.service.ts | 104 ++- .../src/modules/app/auth/dto/auth.dto.ts | 14 + .../src/modules/app/order/order.service.ts | 17 +- .../src/modules/app/room/room.controller.ts | 10 + .../src/modules/app/room/room.service.ts | 91 ++- .../modules/shared/coupon/dto/coupon.dto.ts | 12 + 22 files changed, 1545 insertions(+), 355 deletions(-) create mode 100644 apps/merchant-admin/src/pages/Login.css create mode 100644 apps/platform-admin/src/pages/Login.css diff --git a/.claude/settings.local.json b/.claude/settings.local.json index 286eaa8..073414c 100644 --- a/.claude/settings.local.json +++ b/.claude/settings.local.json @@ -51,7 +51,8 @@ "Bash(curl -X GET \"http://localhost:3000/api/admin/finance/reports/weekly\" -H \"Content-Type: application/json\")", "Bash(xargs grep -l \"room\" -i)", "Bash(mysql -h localhost -u root -p123456 -D rent -e \"DESCRIBE user_coupons;\")", - "Bash(docker exec *)" + "Bash(docker exec *)", + "Bash(mysql -h localhost -P 3306 -u root -pquan131735 rent_platform -e \"DESC guests;\")" ] } } diff --git a/apps/merchant-admin/src/pages/Login.css b/apps/merchant-admin/src/pages/Login.css new file mode 100644 index 0000000..edb67a4 --- /dev/null +++ b/apps/merchant-admin/src/pages/Login.css @@ -0,0 +1,319 @@ +/* 商家后台 - 居中卡片布局 */ +.merchant-login-container { + min-height: 100vh; + display: flex; + align-items: center; + justify-content: center; + background: linear-gradient(135deg, #fff5f0 0%, #ffe8dc 100%); + position: relative; + overflow: hidden; + padding: 40px 20px; +} + +/* 背景装饰 */ +.merchant-login-bg { + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + overflow: hidden; + z-index: 0; +} + +.bg-decoration { + position: absolute; + width: 100%; + height: 100%; +} + +.bg-circle { + position: absolute; + border-radius: 50%; + background: linear-gradient(135deg, rgba(255, 107, 107, 0.1) 0%, rgba(254, 202, 87, 0.1) 100%); + animation: bgFloat 25s infinite ease-in-out; +} + +.bg-circle.circle-1 { + width: 600px; + height: 600px; + top: -200px; + right: -200px; + animation-delay: 0s; +} + +.bg-circle.circle-2 { + width: 450px; + height: 450px; + bottom: -150px; + left: -150px; + animation-delay: 8s; +} + +.bg-circle.circle-3 { + width: 350px; + height: 350px; + top: 40%; + left: 50%; + animation-delay: 16s; +} + +@keyframes bgFloat { + 0%, 100% { + transform: translate(0, 0) scale(1); + } + 33% { + transform: translate(30px, -30px) scale(1.05); + } + 66% { + transform: translate(-30px, 30px) scale(0.95); + } +} + +/* 中央登录卡片 */ +.merchant-login-card { + position: relative; + z-index: 1; + width: 100%; + max-width: 480px; + background: #fff; + border-radius: 24px; + box-shadow: 0 20px 60px rgba(255, 107, 107, 0.15); + padding: 48px 40px; + animation: cardSlideUp 0.6s ease-out; +} + +@keyframes cardSlideUp { + from { + opacity: 0; + transform: translateY(30px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +/* 品牌区域 */ +.merchant-brand { + text-align: center; + margin-bottom: 40px; +} + +.merchant-brand-icon { + width: 100px; + height: 100px; + background: linear-gradient(135deg, rgba(255, 107, 107, 0.1) 0%, rgba(254, 202, 87, 0.1) 100%); + border-radius: 24px; + display: flex; + align-items: center; + justify-content: center; + margin: 0 auto 24px; + border: 2px solid rgba(255, 107, 107, 0.2); +} + +.merchant-brand-title { + font-size: 28px; + font-weight: 800; + color: #2d3436; + margin: 0 0 8px; + letter-spacing: 0.5px; +} + +.merchant-brand-subtitle { + font-size: 15px; + color: #636e72; + margin: 0; + font-weight: 500; +} + +/* 表单区域 */ +.merchant-form-section { + margin-bottom: 32px; +} + +.merchant-form { + margin: 0; +} + +.merchant-input { + height: 50px; + border-radius: 12px; + font-size: 15px; + border: 2px solid #f0f0f0; + transition: all 0.3s; + background: #fafafa; +} + +.merchant-input:hover { + border-color: #ff6b6b; + background: #fff; +} + +.merchant-input:focus, +.merchant-input.ant-input-focused { + border-color: #ff6b6b; + background: #fff; + box-shadow: 0 0 0 4px rgba(255, 107, 107, 0.1); +} + +.merchant-input input { + height: 100%; + background: transparent; +} + +.merchant-input-icon { + color: #ff6b6b; + font-size: 18px; +} + +.merchant-code-wrapper { + display: flex; + gap: 12px; +} + +.merchant-code-input { + flex: 1; +} + +.merchant-code-button { + height: 50px; + border-radius: 12px; + font-size: 14px; + font-weight: 600; + padding: 0 24px; + white-space: nowrap; + border: 2px solid #f0f0f0; + background: #fafafa; + transition: all 0.3s; + color: #ff6b6b; +} + +.merchant-code-button:hover:not(:disabled) { + color: #fff; + background: #ff6b6b; + border-color: #ff6b6b; + transform: translateY(-2px); + box-shadow: 0 4px 12px rgba(255, 107, 107, 0.3); +} + +.merchant-code-button:disabled { + color: #bbb; + background: #f5f5f5; + border-color: #e8e8e8; + cursor: not-allowed; +} + +.merchant-login-button { + height: 50px; + border-radius: 12px; + font-size: 16px; + font-weight: 700; + background: linear-gradient(135deg, #ff6b6b 0%, #feca57 100%); + border: none; + box-shadow: 0 6px 20px rgba(255, 107, 107, 0.35); + transition: all 0.3s; + letter-spacing: 0.5px; +} + +.merchant-login-button:hover { + transform: translateY(-3px); + box-shadow: 0 8px 24px rgba(255, 107, 107, 0.45); +} + +.merchant-login-button:active { + transform: translateY(-1px); +} + +.merchant-dev-tip { + text-align: center; + margin-top: 16px; +} + +.merchant-dev-tip p { + font-size: 13px; + color: #999; + margin: 0; + padding: 10px 18px; + background: #fff5f0; + border-radius: 10px; + display: inline-block; + border: 1px solid #ffe8dc; +} + +/* 特性展示 */ +.merchant-features { + display: flex; + justify-content: space-around; + padding: 24px 0; + margin-bottom: 24px; + border-top: 1px solid #f0f0f0; + border-bottom: 1px solid #f0f0f0; +} + +.merchant-feature-item { + display: flex; + flex-direction: column; + align-items: center; + gap: 8px; +} + +.merchant-feature-icon { + font-size: 32px; +} + +.merchant-feature-text { + font-size: 13px; + color: #636e72; + font-weight: 500; +} + +/* 底部 */ +.merchant-footer { + text-align: center; +} + +.merchant-footer p { + font-size: 13px; + color: #999; + margin: 0; +} + +/* 响应式设计 */ +@media (max-width: 640px) { + .merchant-login-card { + padding: 36px 28px; + } + + .merchant-brand-title { + font-size: 24px; + } + + .merchant-code-wrapper { + flex-direction: column; + } + + .merchant-code-button { + width: 100%; + } + + .merchant-features { + flex-direction: column; + gap: 16px; + } + + .bg-circle.circle-1 { + width: 400px; + height: 400px; + } + + .bg-circle.circle-2 { + width: 300px; + height: 300px; + } + + .bg-circle.circle-3 { + width: 250px; + height: 250px; + } +} diff --git a/apps/merchant-admin/src/pages/Login.tsx b/apps/merchant-admin/src/pages/Login.tsx index 76c3dd4..6912c18 100644 --- a/apps/merchant-admin/src/pages/Login.tsx +++ b/apps/merchant-admin/src/pages/Login.tsx @@ -1,9 +1,10 @@ import React, { useState } from 'react'; import { useNavigate } from 'react-router-dom'; -import { Form, Input, Button, Card, message } from 'antd'; -import { MobileOutlined, SafetyOutlined } from '@ant-design/icons'; +import { Form, Input, Button, message } from 'antd'; +import { MobileOutlined, SafetyOutlined, ShopOutlined } from '@ant-design/icons'; import { loginByCode, sendSellerCode } from '@/api/auth'; import { useAuthStore } from '@/store/auth'; +import './Login.css'; const Login: React.FC = () => { const [loading, setLoading] = useState(false); @@ -55,34 +56,106 @@ const Login: React.FC = () => { }; return ( -