feat: 问题修复

This commit is contained in:
duanshuwen
2025-09-24 18:05:39 +08:00
parent bf83e95b7b
commit ceab08825a
6 changed files with 108 additions and 145 deletions

View File

@@ -1,7 +1,6 @@
import { resolve } from 'path' import { resolve } from 'path'
import { defineConfig, externalizeDepsPlugin, bytecodePlugin } from 'electron-vite' import { defineConfig, externalizeDepsPlugin, bytecodePlugin } from 'electron-vite'
import vue from '@vitejs/plugin-vue' import vue from '@vitejs/plugin-vue'
import tailwindcss from 'tailwindcss'
export default defineConfig({ export default defineConfig({
main: { main: {
@@ -28,11 +27,6 @@ export default defineConfig({
} }
} }
}, },
plugins: [vue()], plugins: [vue()]
css: {
postcss: {
plugins: [tailwindcss]
}
}
} }
}) })

4
package-lock.json generated
View File

@@ -2852,7 +2852,7 @@
}, },
"node_modules/@tailwindcss/postcss": { "node_modules/@tailwindcss/postcss": {
"version": "4.1.13", "version": "4.1.13",
"resolved": "https://registry.npmmirror.com/@tailwindcss/postcss/-/postcss-4.1.13.tgz", "resolved": "https://registry.npmjs.org/@tailwindcss/postcss/-/postcss-4.1.13.tgz",
"integrity": "sha512-HLgx6YSFKJT7rJqh9oJs/TkBFhxuMOfUKSBEPYwV+t78POOBsdQ7crhZLzwcH3T0UyUuOzU/GK5pk5eKr3wCiQ==", "integrity": "sha512-HLgx6YSFKJT7rJqh9oJs/TkBFhxuMOfUKSBEPYwV+t78POOBsdQ7crhZLzwcH3T0UyUuOzU/GK5pk5eKr3wCiQ==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
@@ -4013,7 +4013,7 @@
}, },
"node_modules/autoprefixer": { "node_modules/autoprefixer": {
"version": "10.4.21", "version": "10.4.21",
"resolved": "https://registry.npmmirror.com/autoprefixer/-/autoprefixer-10.4.21.tgz", "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.21.tgz",
"integrity": "sha512-O+A6LWV5LDHSJD3LjHYoNi4VLsj/Whi7k6zG12xTYaU4cQ8oxQGckXNX8cRHK5yOZ/ppVHe0ZBXGzSV9jXdVbQ==", "integrity": "sha512-O+A6LWV5LDHSJD3LjHYoNi4VLsj/Whi7k6zG12xTYaU4cQ8oxQGckXNX8cRHK5yOZ/ppVHe0ZBXGzSV9jXdVbQ==",
"dev": true, "dev": true,
"funding": [ "funding": [

View File

@@ -1,6 +1,6 @@
module.exports = { module.exports = {
plugins: { plugins: {
'@tailwindcss/postcss': {}, '@tailwindcss/postcss': {},
autoprefixer: {} autoprefixer: {},
} },
} }

View File

@@ -1,67 +0,0 @@
:root {
--ev-c-white: #ffffff;
--ev-c-white-soft: #f8f8f8;
--ev-c-white-mute: #f2f2f2;
--ev-c-black: #1b1b1f;
--ev-c-black-soft: #222222;
--ev-c-black-mute: #282828;
--ev-c-gray-1: #515c67;
--ev-c-gray-2: #414853;
--ev-c-gray-3: #32363f;
--ev-c-text-1: rgba(255, 255, 245, 0.86);
--ev-c-text-2: rgba(235, 235, 245, 0.6);
--ev-c-text-3: rgba(235, 235, 245, 0.38);
--ev-button-alt-border: transparent;
--ev-button-alt-text: var(--ev-c-text-1);
--ev-button-alt-bg: var(--ev-c-gray-3);
--ev-button-alt-hover-border: transparent;
--ev-button-alt-hover-text: var(--ev-c-text-1);
--ev-button-alt-hover-bg: var(--ev-c-gray-2);
}
:root {
--color-background: var(--ev-c-black);
--color-background-soft: var(--ev-c-black-soft);
--color-background-mute: var(--ev-c-black-mute);
--color-text: var(--ev-c-text-1);
}
*,
*::before,
*::after {
box-sizing: border-box;
margin: 0;
font-weight: normal;
}
ul {
list-style: none;
}
body {
min-height: 100vh;
color: var(--color-text);
background: var(--color-background);
line-height: 1.6;
font-family:
Inter,
-apple-system,
BlinkMacSystemFont,
'Segoe UI',
Roboto,
Oxygen,
Ubuntu,
Cantarell,
'Fira Sans',
'Droid Sans',
'Helvetica Neue',
sans-serif;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}

View File

@@ -1,12 +1,11 @@
@import './base.css';
body { body {
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
overflow: hidden; overflow: hidden;
background-image: url('./wavy-lines.svg'); background-color: #fff;
background-size: cover; /* background-image: url('./wavy-lines.svg');
background-size: cover; */
user-select: none; user-select: none;
} }
@@ -169,3 +168,15 @@ code {
display: none; display: none;
} }
} }
.fz-14 {
font-size: 14px;
}
.fz-22 {
font-size: 22px;
}
.mb-20 {
margin-bottom: 20px;
}

View File

@@ -1,13 +1,13 @@
<template> <template>
<div class="min-h-screen bg-gradient-to-br from-blue-50 to-indigo-100 flex items-center justify-center p-4"> <div
class="min-h-screen bg-gradient-to-br from-blue-50 to-indigo-100 flex items-center justify-center p-4"
>
<div class="w-full max-w-md"> <div class="w-full max-w-md">
<!-- 登录卡片 --> <!-- 登录卡片 -->
<div class="bg-white rounded-lg shadow-xl p-8"> <div class="bg-white rounded-lg shadow-xl p-8">
<!-- Logo和标题 --> <!-- Logo和标题 -->
<div class="text-center mb-8"> <div class="text-center mb-8">
<h1 class="text-2xl font-bold text-gray-900 mb-2"> <h1 class="text-2xl font-bold text-gray-900 mb-2">China Fellou Plus</h1>
China Fellou Plus
</h1>
<div class="text-sm text-gray-600"> <div class="text-sm text-gray-600">
您的隐私对我们很重要我们确保您的数据是安全和保密的 您的隐私对我们很重要我们确保您的数据是安全和保密的
</div> </div>
@@ -17,7 +17,7 @@
<!-- 二维码登录 --> <!-- 二维码登录 -->
<div class="left text-center"> <div class="left text-center">
<div class="bg-gray-100 rounded-lg p-8 mb-4"> <div class="bg-gray-100 rounded-lg p-8 mb-4">
<div class="fz-22">手机扫码登录</div> <div class="fz-22 mb-20">手机扫码登录</div>
<div class="w-48 h-48 bg-white rounded-lg mx-auto flex items-center justify-center"> <div class="w-48 h-48 bg-white rounded-lg mx-auto flex items-center justify-center">
<div class="qr text-center mt-20"> <div class="qr text-center mt-20">
<vue-qrcode value="https://www.1stg.me" width="195" margin="3" /> <vue-qrcode value="https://www.1stg.me" width="195" margin="3" />
@@ -30,19 +30,28 @@
</div> </div>
</div> </div>
</div> </div>
<p class="fz-14"> <p class="fz-14">打开<el-text type="success">微信</el-text>扫一扫登录</p>
打开<el-text type="success">微信</el-text>扫一扫登录
</p>
</div> </div>
<!-- 账号密码登录 --> <!-- 账号密码登录 -->
<div class="right text-center"> <div class="right text-center">
<div class="fz-22">密码登录</div> <div class="fz-22 mb-20">密码登录</div>
<el-form class="mt-20" ref="loginFormRef" :model="loginForm" :rules="loginRules" @keyup.enter="handleLogin"> <el-form
class="mt-20"
ref="loginFormRef"
:model="loginForm"
:rules="loginRules"
@keyup.enter="handleLogin"
>
<!-- 用户名/邮箱/手机号 --> <!-- 用户名/邮箱/手机号 -->
<el-form-item prop="username"> <el-form-item prop="username">
<el-input v-model="loginForm.username" placeholder="请输入手机号" size="large" clearable> <el-input
v-model="loginForm.username"
placeholder="请输入手机号"
size="large"
clearable
>
<template #prefix> <template #prefix>
<el-icon> <el-icon>
<User /> <User />
@@ -53,8 +62,14 @@
<!-- 密码 --> <!-- 密码 -->
<el-form-item prop="password"> <el-form-item prop="password">
<el-input v-model="loginForm.password" type="password" placeholder="请输入密码" size="large" show-password <el-input
clearable> v-model="loginForm.password"
type="password"
placeholder="请输入密码"
size="large"
show-password
clearable
>
<template #prefix> <template #prefix>
<el-icon> <el-icon>
<Lock /> <Lock />
@@ -66,15 +81,22 @@
<!-- 图形验证码 --> <!-- 图形验证码 -->
<el-form-item v-if="showCaptcha" prop="captcha"> <el-form-item v-if="showCaptcha" prop="captcha">
<div class="flex space-x-2"> <div class="flex space-x-2">
<el-input v-model="loginForm.captcha" placeholder="请输入验证码" size="large" clearable> <el-input
v-model="loginForm.captcha"
placeholder="请输入验证码"
size="large"
clearable
>
<template #prefix> <template #prefix>
<el-icon> <el-icon>
<Key /> <Key />
</el-icon> </el-icon>
</template> </template>
</el-input> </el-input>
<div class="w-24 h-10 bg-gray-200 rounded flex items-center justify-center cursor-pointer" <div
@click="refreshCaptcha"> class="w-24 h-10 bg-gray-200 rounded flex items-center justify-center cursor-pointer"
@click="refreshCaptcha"
>
<span class="text-sm font-mono">{{ captchaCode }}</span> <span class="text-sm font-mono">{{ captchaCode }}</span>
</div> </div>
</div> </div>
@@ -90,7 +112,13 @@
<!-- 登录按钮 --> <!-- 登录按钮 -->
<el-form-item> <el-form-item>
<el-button type="primary" size="large" class="w-full" :loading="loading" @click="handleLogin"> <el-button
type="primary"
size="large"
class="w-full"
:loading="loading"
@click="handleLogin"
>
登录 登录
</el-button> </el-button>
</el-form-item> </el-form-item>
@@ -113,93 +141,89 @@
</template> </template>
<script setup ts> <script setup ts>
import { ref, reactive, onMounted } from "vue"; import { ref, reactive, onMounted } from 'vue'
import { ElMessage } from "element-plus"; import { ElMessage } from 'element-plus'
import { User, Lock, Key } from "@element-plus/icons-vue"; import { User, Lock, Key } from '@element-plus/icons-vue'
import VueQrcode from "vue-qrcode"; import VueQrcode from 'vue-qrcode'
// 登录表单 // 登录表单
const loginFormRef = ref(); const loginFormRef = ref()
const loginForm = reactive({ const loginForm = reactive({
username: "", username: '',
password: "", password: '',
captcha: "", captcha: '',
remember: false, remember: false
}); })
// 登录规则(必填验证) // 登录规则(必填验证)
const loginRules = { const loginRules = {
username: [ username: [{ required: true, message: '请输入用户名/邮箱/手机号', trigger: 'blur' }],
{ required: true, message: "请输入用户名/邮箱/手机号", trigger: "blur" },
],
password: [ password: [
{ required: true, message: "请输入密码", trigger: "blur" }, { required: true, message: '请输入密码', trigger: 'blur' },
{ min: 6, message: "密码长度不能少于6位", trigger: "blur" }, { min: 6, message: '密码长度不能少于6位', trigger: 'blur' }
], ],
captcha: [{ required: true, message: "请输入验证码", trigger: "blur" }], captcha: [{ required: true, message: '请输入验证码', trigger: 'blur' }]
}; }
// 加载状态 // 加载状态
const loading = ref(false); const loading = ref(false)
// 验证码相关 // 验证码相关
const showCaptcha = ref(false); const showCaptcha = ref(false)
const captchaCode = ref("8K9M"); const captchaCode = ref('8K9M')
const loginAttempts = ref(0); const loginAttempts = ref(0)
// 生成二维码 // 生成二维码
const qrCodeUrl = ref(""); const qrCodeUrl = ref('')
// 刷新验证码 // 刷新验证码
const refreshCaptcha = () => { const refreshCaptcha = () => {
const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
let code = ""; let code = ''
for (let i = 0; i < 4; i++) { for (let i = 0; i < 4; i++) {
code += chars.charAt(Math.floor(Math.random() * chars.length)); code += chars.charAt(Math.floor(Math.random() * chars.length))
}
captchaCode.value = code
} }
captchaCode.value = code;
};
// 处理登录 // 处理登录
const handleLogin = async () => { const handleLogin = async () => {
try { try {
await loginFormRef.value.validate(); await loginFormRef.value.validate()
loading.value = true; loading.value = true
// 模拟登录请求 // 模拟登录请求
setTimeout(() => { setTimeout(() => {
loading.value = false; loading.value = false
loginAttempts.value++; loginAttempts.value++
// 模拟登录失败,显示验证码 // 模拟登录失败,显示验证码
if (loginAttempts.value >= 1) { if (loginAttempts.value >= 1) {
showCaptcha.value = true; showCaptcha.value = true
ElMessage.error("用户名或密码错误"); ElMessage.error('用户名或密码错误')
refreshCaptcha(); refreshCaptcha()
} else { } else {
ElMessage.success("登录成功"); ElMessage.success('登录成功')
} }
}, 1500); }, 1500)
} catch (error) { } catch (error) {
console.error("验证失败:", error); console.error('验证失败:', error)
}
} }
};
// 处理忘记密码 // 处理忘记密码
const handleForgotPassword = () => { const handleForgotPassword = () => {
ElMessage.info("忘记密码功能开发中..."); ElMessage.info('忘记密码功能开发中...')
}; }
// 页面加载时聚焦到用户名输入框 // 页面加载时聚焦到用户名输入框
onMounted(() => { onMounted(() => {
const usernameInput = document.querySelector( const usernameInput = document.querySelector('input[placeholder="请输入用户名/邮箱/手机号"]')
'input[placeholder="请输入用户名/邮箱/手机号"]'
);
if (usernameInput) { if (usernameInput) {
usernameInput.focus(); usernameInput.focus()
} }
}); })
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
@@ -224,6 +248,7 @@ onMounted(() => {
box-shadow: none; box-shadow: none;
background-color: #fff; background-color: #fff;
position: relative; position: relative;
overflow: hidden;
} }
.qrcode-error { .qrcode-error {