From 4cc94884993f4f1fc6e0f50651c8e9c03a0e1ff0 Mon Sep 17 00:00:00 2001 From: 13121765685 Date: Fri, 9 Jan 2026 11:49:16 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=9D=E5=A7=8B=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitea/workflows/docker.yaml | 55 + ...nt Phone Verification Code Login Toggle.md | 49 + .trae/documents/修改手机号登录逻辑.md | 386 ++++ apps/frontend/index.html | 2 +- .../src/components/AddModal/index.vue | 834 ++++++++ apps/frontend/src/components/IPCard/shu.vue | 434 +++- .../src/components/auth/PhoneLoginForm.vue | 261 ++- .../src/components/layout/AppSidebar.vue | 5 +- .../src/components/layout/MainLayout.vue | 5 +- apps/frontend/src/locales/index.js | 224 +- apps/frontend/src/main.js | 5 + apps/frontend/src/router/index.js | 17 +- apps/frontend/src/stores/auth.js | 68 +- apps/frontend/src/styles/theme.css | 8 + apps/frontend/src/views/Login/Login.vue | 40 +- apps/frontend/src/views/Login/PhoneLogin.vue | 36 +- apps/frontend/src/views/Login/login.js | 171 +- .../src/views/ModernHome/ModernHome.vue | 3 +- .../src/views/Project/CreateProject.vue | 1 - .../CreateProjectShu/CreateProjectShu.vue | 811 +++++++- apps/frontend/src/views/home/index copy 2.vue | 820 ++++++++ apps/frontend/src/views/home/index copy.vue | 1805 ++++++++++++++--- apps/frontend/src/views/home/index.vue | 60 +- apps/frontend/src/views/kefuReduce.vue | 2 +- apps/frontend/src/views/user/index.vue | 28 +- dockerfile | 10 + hosts | 26 + packages/utils/src/api/frontend/login.js | 6 + 28 files changed, 5526 insertions(+), 646 deletions(-) create mode 100644 .gitea/workflows/docker.yaml create mode 100644 .trae/documents/Implement Phone Verification Code Login Toggle.md create mode 100644 .trae/documents/修改手机号登录逻辑.md create mode 100644 apps/frontend/src/components/AddModal/index.vue create mode 100644 apps/frontend/src/views/home/index copy 2.vue create mode 100644 dockerfile create mode 100644 hosts diff --git a/.gitea/workflows/docker.yaml b/.gitea/workflows/docker.yaml new file mode 100644 index 0000000..8c1fc8f --- /dev/null +++ b/.gitea/workflows/docker.yaml @@ -0,0 +1,55 @@ +name: CI/CD + + + +on: + push: + branches: + - main + - dev + + +jobs: + build: + runs-on: ubuntu-latest + + # container: docker.gitea.com/runner-images:ubuntu-latest + container: + image: docker.gitea.com/runner-images:ubuntu-latest + options: --add-host=my_gitea:host-gateway + + + steps: + + + # - name: Add host entry for Gitea + # run: | + # echo "${{ vars.GITEAHOST }} my_gitea" | tee -a /etc/hosts + + - name: Test access to Gitea + run: | + curl -v http://host.docker.internal:3000 + curl -v http://my_gitea:3000 + + - name: Checkout code + uses: actions/checkout@v3 + + - name: Build Docker image + run: docker build -t vue-app . + + - name: Create container and extract dist + run: | + docker rm --force vue-container || true; + + rm -rf /docker/front/apps/* + mkdir -p /docker/front/apps + + # 创建容器但不运行 + docker run --name vue-container vue-app + # -v 卷挂载是直接映射整个目录,而 docker cp 会保留源路径的目录结构。 + docker cp vue-container:build/apps/. /docker/front/apps/ + + chmod -R 777 /docker/front/apps + # -v 卷挂载是直接映射整个目录,而 docker cp 会保留源路径的目录结构。 + docker cp /docker/front/apps/frontend/dist/. my_caddy:/docker/front/www/ + docker cp /docker/front/apps/frontendDesigner/dist/. my_caddy:/docker/front/admin/ \ No newline at end of file diff --git a/.trae/documents/Implement Phone Verification Code Login Toggle.md b/.trae/documents/Implement Phone Verification Code Login Toggle.md new file mode 100644 index 0000000..3b14c1e --- /dev/null +++ b/.trae/documents/Implement Phone Verification Code Login Toggle.md @@ -0,0 +1,49 @@ +## 实施计划 + +### 1. 分析当前代码结构 + +- **PhoneLogin.vue**:手机号登录页面主组件,包含登录卡片和子组件调用 +- **PhoneLoginForm.vue**:登录表单组件,包含登录方式切换和表单字段 +- **login.js**:包含登录相关的API调用方法,如`sendPhoneCode`和`phoneLoginCode` + +### 2. 修改PhoneLoginForm.vue组件 + +#### 模板部分修改 +- **更新登录模式切换**:将现有的三种模式(密码登录、注册、重置密码)改为仅保留登录相关的模式 +- **添加密码/验证码登录切换**:在登录模式下,添加一个新的切换开关,允许用户在密码登录和验证码登录之间切换 +- **调整表单字段显示**:根据选择的登录方式显示相应的表单字段 + +#### 脚本部分修改 +- **添加登录方式状态**:添加`loginMethod` ref,用于跟踪用户选择的是密码登录还是验证码登录 +- **设置默认登录方式**:将默认登录方式设置为验证码登录 +- **更新表单验证逻辑**:根据选择的登录方式调整验证规则 +- **更新发送验证码逻辑**:发送登录验证码时传递`purpose: 'login'` +- **更新表单提交逻辑**:验证码登录时调用`phoneLoginCode`函数 + +### 3. 修改PhoneLogin.vue组件 + +- **更新handleLogin方法**:确保根据登录方式调用正确的登录函数 + +### 4. 实施细节 + +#### PhoneLoginForm.vue修改点 +- **第155行**:将默认`loginMode`改为'code' +- **第38-70行**:添加密码/验证码登录切换按钮 +- **第256-285行**:更新`handleSendCode`方法,确保发送验证码时传递正确的purpose +- **第288-316行**:更新`handleSubmit`方法,处理验证码登录逻辑 + +#### PhoneLogin.vue修改点 +- **第79-81行**:更新`handleLogin`方法,根据登录方式调用正确的登录函数 + +### 5. 预期行为 + +- 用户默认看到验证码登录界面 +- 用户可以在密码登录和验证码登录之间切换 +- 发送登录验证码时,传递`purpose: 'login'` +- 验证码登录调用`phoneLoginCode`函数 +- 密码登录保持原有功能不变 + +### 6. 需要修改的文件 + +- `d:\work\Aiproject\DeotalandAi\apps\frontend\src\components\auth\PhoneLoginForm.vue` +- `d:\work\Aiproject\DeotalandAi\apps\frontend\src\views\Login\PhoneLogin.vue` \ No newline at end of file diff --git a/.trae/documents/修改手机号登录逻辑.md b/.trae/documents/修改手机号登录逻辑.md new file mode 100644 index 0000000..59e3393 --- /dev/null +++ b/.trae/documents/修改手机号登录逻辑.md @@ -0,0 +1,386 @@ +# 实现竖屏移动端卡片展示组件 + +## 组件设计目标 + +* 适配竖屏移动端的卡片展示组件 + +* 包含图片展示、加载蒙层、预览功能 + +* 底部功能按钮(修改、编辑、场景图、下载、删除) + +* 向父组件抛出事件 + +## 实现步骤 + +### 1. 实现 `shu.vue` 组件 + +* 设计组件结构:主容器、图片区域、功能按钮区域 + +* 实现响应式布局,适配竖屏移动端 + +* 使用 Scoped CSS + CSS 变量实现样式隔离与主题定制 + +### 2. 图片展示与加载效果 + +* 使用 `el-image` 组件实现图片展示 + +* 添加加载状态管理,显示加载蒙层 + +* 实现图片加载完成后的过渡效果 + +### 3. 图片预览功能 + +* 集成图片预览功能,适配 H5 移动端 + +* 点击图片触发预览,支持手势操作 + +### 4. 底部功能按钮 + +* 实现修改、编辑、场景图、下载、删除按钮 + +* 每个按钮向父组件抛出对应的事件 + +* 按钮样式设计符合 UI/UX 要求 + +### 5. 与父组件交互 + +* 在 `CreateProjectShu.vue` 中引入并使用 `shu.vue` 组件 + +* 实现事件处理逻辑,接收并处理子组件抛出的事件 + +## 代码实现 + +### `shu.vue` 组件 + +```vue + + + + + +``` + +### 2. 集成到父组件 `CreateProjectShu.vue` + +* 在父组件中引入 `shu.vue` 组件 + +* 实现事件处理逻辑,接收子组件抛出的事件 + +* 在模板中使用新组件展示卡片 + +## 设计规范 + +* 主色调:深紫色(#6B46C1)、浅紫色(#A78BFA) + +* 辅助色:深灰色(#1F2937)、浅灰色(#F3F4F6) + +* 按钮样式:圆角设计(8px半径)、微妙阴影、悬停效果 + +* 字体排版:Inter字体系列、16px基础大小、响应式缩放 + +* 布局风格:基于卡片的设计、统一间距(8px网格系统) + +* 动画效果:平滑过渡(200ms缓入缓出)、加载蒙层 + +## 测试与验证 + +* 确保组件在竖屏移动端正常显示 + +* 测试图片加载、预览功能 + +* 验证按钮事件正确抛出 + +* 检查响应式布局适配情况 + diff --git a/apps/frontend/index.html b/apps/frontend/index.html index eb2eb5f..e9c8da4 100644 --- a/apps/frontend/index.html +++ b/apps/frontend/index.html @@ -3,7 +3,7 @@ - + diff --git a/apps/frontend/src/components/AddModal/index.vue b/apps/frontend/src/components/AddModal/index.vue new file mode 100644 index 0000000..4b39086 --- /dev/null +++ b/apps/frontend/src/components/AddModal/index.vue @@ -0,0 +1,834 @@ + + + + + \ No newline at end of file diff --git a/apps/frontend/src/components/IPCard/shu.vue b/apps/frontend/src/components/IPCard/shu.vue index 91fcd2b..4910fc0 100644 --- a/apps/frontend/src/components/IPCard/shu.vue +++ b/apps/frontend/src/components/IPCard/shu.vue @@ -3,7 +3,7 @@
+ + + +
- - - -
diff --git a/apps/frontend/src/views/home/index copy 2.vue b/apps/frontend/src/views/home/index copy 2.vue new file mode 100644 index 0000000..dc2a123 --- /dev/null +++ b/apps/frontend/src/views/home/index copy 2.vue @@ -0,0 +1,820 @@ + + + + + diff --git a/apps/frontend/src/views/home/index copy.vue b/apps/frontend/src/views/home/index copy.vue index 959c646..4842d09 100644 --- a/apps/frontend/src/views/home/index copy.vue +++ b/apps/frontend/src/views/home/index copy.vue @@ -1,41 +1,63 @@ diff --git a/apps/frontend/src/views/home/index.vue b/apps/frontend/src/views/home/index.vue index a8bfd91..dc2a123 100644 --- a/apps/frontend/src/views/home/index.vue +++ b/apps/frontend/src/views/home/index.vue @@ -10,8 +10,9 @@
@@ -131,7 +132,7 @@
-
+
@@ -218,7 +219,8 @@
{{ t('hero.explore') }} @@ -255,7 +257,9 @@ -
+
@@ -551,8 +555,7 @@ import MotionCom from './motion.vue' import spline from './spline.vue'; import { ref, onMounted, onUnmounted, computed } from 'vue'; import Bg from './bg.vue' -// import dog from '@/assets/home/dog.webp' -// import qdog from '@/assets/home/qdog.webp' + const center = 'https://draft-user.s3.us-east-2.amazonaws.com/images/c175585a-20c2-48b3-8939-32bbdb25814b.webp' const center1 = 'https://draft-user.s3.us-east-2.amazonaws.com/images/ecf39871-52c5-45ad-9f9e-6eafd838ce54.webp' const center2 = 'https://draft-user.s3.us-east-2.amazonaws.com/images/f7c4454e-1781-448e-9c70-b087b64f380e.webp' @@ -563,18 +566,25 @@ const center6 = 'https://draft-user.s3.us-east-2.amazonaws.com/images/de3cc66c-9 const center7 = 'https://draft-user.s3.us-east-2.amazonaws.com/images/bc62a209-9a54-4d1e-926a-b3ef66fdbd29.webp' const center8 = 'https://draft-user.s3.us-east-2.amazonaws.com/images/9e012193-5576-4a9e-9f38-eecb8705d8a4.webp' const center9 = 'https://draft-user.s3.us-east-2.amazonaws.com/images/65bb1613-0ff9-43c4-a5b9-978c2507ca91.webp' -// Window size reactive state -const getResponsiveWidthStyle = () => { - const isMobile = window.innerWidth < 768; - return { - position: 'fixed', - width: isMobile ? '300vw' : '100vw', - left: '50%', - top: '50%', - transform: 'translate(-50%, -50%)' - }; -}; + +const viewportHeight = ref(window.innerHeight); const isMobile = ref(window.innerWidth < 768); + +const supportsSticky = ref(true); +const supportsBackdropFilter = ref(true); + +const checkStickySupport = () => { + const testEl = document.createElement('div'); + testEl.style.position = 'sticky'; + testEl.style.top = '0'; + supportsSticky.value = testEl.style.position === 'sticky'; +}; + +const checkBackdropFilterSupport = () => { + const testEl = document.createElement('div'); + testEl.style.backdropFilter = 'blur(10px)'; + supportsBackdropFilter.value = testEl.style.backdropFilter !== ''; +}; // 中英文库 const i18n = { en: { @@ -729,17 +739,14 @@ const scrollYProgress = ref(0); // Scroll event handler const handleScroll = () => { - // isScrolled.value = window.scrollY > 50; - isScrolled.value = false; + isScrolled.value = window.scrollY > 50; - // Calculate scroll progress for hero section if (containerRef.value) { const viewportHeight = window.innerHeight; const scrollPosition = window.scrollY; const containerTop = containerRef.value.offsetTop; const containerHeight = containerRef.value.offsetHeight; - // Calculate progress from 0 to 1 as we scroll through the container const progress = Math.max(0, Math.min(1, (scrollPosition - containerTop + viewportHeight) / (containerHeight + viewportHeight) @@ -749,6 +756,12 @@ const handleScroll = () => { } }; +// Handle window resize +const handleResize = () => { + viewportHeight.value = window.innerHeight; + isMobile.value = window.innerWidth < 768; +}; + // Scroll to top function const scrollToTop = () => { window.scrollTo({ top: 0, behavior: 'smooth' }); @@ -789,13 +802,16 @@ const logos = [ // Mount and unmount scroll event onMounted(() => { + checkStickySupport(); + checkBackdropFilterSupport(); window.addEventListener('scroll', handleScroll); - // Initial call to set initial state + window.addEventListener('resize', handleResize); handleScroll(); }); onUnmounted(() => { window.removeEventListener('scroll', handleScroll); + window.removeEventListener('resize', handleResize); }); diff --git a/apps/frontend/src/views/kefuReduce.vue b/apps/frontend/src/views/kefuReduce.vue index 96d67c5..80d30ae 100644 --- a/apps/frontend/src/views/kefuReduce.vue +++ b/apps/frontend/src/views/kefuReduce.vue @@ -54,7 +54,7 @@ const detectEnvironment = async () => { }) environmentInfo.value = result isDetecting.value = false - if (result.isDomestic) { + if (result.isDomestic) {//如果是国内环境 handleDomesticRedirect() } else { handleInternationalRedirect() diff --git a/apps/frontend/src/views/user/index.vue b/apps/frontend/src/views/user/index.vue index 4f58879..064324e 100644 --- a/apps/frontend/src/views/user/index.vue +++ b/apps/frontend/src/views/user/index.vue @@ -50,7 +50,6 @@

{{ $t('userCenter.points.title') }}

-
@@ -121,33 +120,10 @@
-
+

{{ $t('userCenter.voucher.title') }}

- - - - -
+
diff --git a/dockerfile b/dockerfile new file mode 100644 index 0000000..21795a0 --- /dev/null +++ b/dockerfile @@ -0,0 +1,10 @@ +# Dockerfile.simple +FROM node:20-alpine + +WORKDIR /dist + +COPY . . +RUN npm install && npm run build + +# 挂载点提示 +CMD ["echo", "Dist files are ready in /build/dist"] \ No newline at end of file diff --git a/hosts b/hosts new file mode 100644 index 0000000..dc865e4 --- /dev/null +++ b/hosts @@ -0,0 +1,26 @@ +# Copyright (c) 1993-2009 Microsoft Corp. +# +# This is a sample HOSTS file used by Microsoft TCP/IP for Windows. +# +# This file contains the mappings of IP addresses to host names. Each +# entry should be kept on an individual line. The IP address should +# be placed in the first column followed by the corresponding host name. +# The IP address and the host name should be separated by at least one +# space. +# +# Additionally, comments (such as these) may be inserted on individual +# lines or following the machine name denoted by a '#' symbol. +# +# For example: +# +# 102.54.94.97 rhino.acme.com # source server +# 38.25.63.10 x.acme.com # x client host + +# localhost name resolution is handled within DNS itself. +# 127.0.0.1 localhost +# ::1 localhost + +192.168.0.190 admin.deotaland.local +192.168.0.190 www.deotaland.local +192.168.0.190 api.deotaland.local +192.168.0.190 git.deotaland.local \ No newline at end of file diff --git a/packages/utils/src/api/frontend/login.js b/packages/utils/src/api/frontend/login.js index 10decb0..9585afe 100644 --- a/packages/utils/src/api/frontend/login.js +++ b/packages/utils/src/api/frontend/login.js @@ -6,5 +6,11 @@ const login = { OAUTH_GOOGLE:{url:'/api-base/user/oauth/google',method:'POST',isLoading:true},// google弹窗授权 FORGOT_PASSWORD:{url:'/api-base/user/forgot-password',method:'POST',isLoading:true},// 修改密码 REFRESH_TOKEN:{url:'/api-base/user/oauth/google/refresh',method:'POST'},// googleRefreshToken刷新 + SEND_SMS_CODE:{url:'/api-base/user/send-sms-code',method:'POST'},// 发送短信验证码 + REGISTER_PHONE:{url:'/api-base/user/register-phone',method:'POST'},// 使用手机号和短信验证码注册新账号 + LOGIN_PHONE:{url:'/api-base/user/login-phone',method:'POST'},// 使用手机号和密码登录 + RESET_PASSWORD_PHONE:{url:'/api-base/user/reset-password-phone',method:'POST'},// 使用手机号和短信验证码重置密码 + LOGIN_PHONE_CODE:{url:'/api-base/user/login-phone-code',method:'POST'},// 使用手机号和短信验证码登录 + } export default login;