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 ( -
- 商家管理后台
}> -
- - } placeholder="手机号" maxLength={11} /> - - - } - placeholder="验证码" - maxLength={6} - addonAfter={ - - } - /> - - - - -
- 开发环境验证码: 123456 +
+ + + + + + +
+

开发环境验证码: 123456

+
+
+ + + {/* 特性展示 */} +
+
+
📦
+
房源管理
- - +
+
📋
+
订单处理
+
+
+
💰
+
财务结算
+
+
+ + {/* 底部 */} +
+

© 2026 品住会. All rights reserved.

+
+ ); }; diff --git a/apps/miniapp/src/api/seller/room-calendar.ts b/apps/miniapp/src/api/seller/room-calendar.ts index cbcb76b..9fd025f 100644 --- a/apps/miniapp/src/api/seller/room-calendar.ts +++ b/apps/miniapp/src/api/seller/room-calendar.ts @@ -2,7 +2,7 @@ import { request } from '@/utils/request'; export function getRoomCalendar(roomId: number, startDate: string, endDate: string) { return request({ - url: `/seller/room-calendar/${roomId}`, + url: `/api/merchant/room-calendar/${roomId}`, method: 'GET', data: { startDate, endDate }, useSellerToken: true, diff --git a/apps/miniapp/src/api/user/auth.ts b/apps/miniapp/src/api/user/auth.ts index 96078af..3a6428d 100644 --- a/apps/miniapp/src/api/user/auth.ts +++ b/apps/miniapp/src/api/user/auth.ts @@ -16,6 +16,10 @@ export function loginByWechat(code: string, nickname?: string, avatar?: string) return post('/api/app/auth/login/wechat', { code, nickname, avatar }); } +export function loginByWechatPhone(code: string, encryptedData: string, iv: string) { + return post('/api/app/auth/login/wechat-phone', { code, encryptedData, iv }); +} + export function register(data: { phone: string; code: string; password?: string; nickname?: string }) { return post('/api/app/auth/register', data); } diff --git a/apps/miniapp/src/api/user/order.ts b/apps/miniapp/src/api/user/order.ts index 030285a..0d992dd 100644 --- a/apps/miniapp/src/api/user/order.ts +++ b/apps/miniapp/src/api/user/order.ts @@ -21,15 +21,15 @@ export function getOrderList(params: { page?: number; pageSize?: number; status? } export function getOrderDetail(id: number) { - return get(`/api/user/orders/${id}`); + return get(`/api/app/orders/${id}`); } export function cancelOrder(id: number, reason: string) { - return put(`/api/user/orders/${id}/cancel`, { reason }); + return put(`/api/app/orders/${id}/cancel`, { reason }); } export function refundOrder(id: number, reason: string) { - return put(`/api/user/orders/${id}/refund`, { reason }); + return put(`/api/app/orders/${id}/refund`, { reason }); } export function payOrder(orderId: number, paymentMethod: 'wechat' | 'alipay' | 'balance' = 'wechat') { diff --git a/apps/miniapp/src/api/user/room.ts b/apps/miniapp/src/api/user/room.ts index 79d6fbb..3211d11 100644 --- a/apps/miniapp/src/api/user/room.ts +++ b/apps/miniapp/src/api/user/room.ts @@ -20,9 +20,9 @@ export function getRoomList(params: { } export function getRoomDetail(id: number) { - return get(`/api/public/rooms/${id}`); + return get(`/api/app/rooms/${id}`); } export function getRoomCalendar(id: number, startDate: string, endDate: string) { - return get(`/api/public/rooms/${id}/calendar`, { startDate, endDate }); + return get(`/api/app/rooms/${id}/calendar`, { startDate, endDate }); } diff --git a/apps/miniapp/src/pages/login/index.vue b/apps/miniapp/src/pages/login/index.vue index f65a4c1..575e452 100644 --- a/apps/miniapp/src/pages/login/index.vue +++ b/apps/miniapp/src/pages/login/index.vue @@ -15,18 +15,34 @@ 舒适住宿,温馨服务 - - + + 欢迎使用 - 使用微信授权快速登录 + 选择登录方式 - - - + + + + + + + @@ -35,86 +51,93 @@ - 登录即表示同意 - 《用户协议》 + 我已阅读并同意 + 《用户协议》 和 - 《隐私政策》 + 《隐私政策》 - - 首次登录将自动创建账号 - - - 欢迎登录 - - - - - +86 - + + + + + 服务协议及隐私保护 - - - - - - - - {{ countdown > 0 ? `${countdown}s` : '获取验证码' }} + + + 为了更好的保障您的合法权益,请您阅读并同意以下协议 + 《用户协议》 + 和 + 《隐私政策》 + + + + + - - - - - - - - - + + + + + 手机号安全登录 + + + + + + + + + +86 + - - 登录即表示同意 - 《用户协议》 - 和 - 《隐私政策》 - + + + + + + + {{ countdown > 0 ? `${countdown}s` : '获取验证码' }} + + + + + + - - - 未注册手机号验证后将自动注册