Compare commits
4 Commits
f944dd680c
...
cddbba0e0f
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cddbba0e0f | ||
|
|
781a3137a6 | ||
|
|
d977da5c38 | ||
|
|
e06bd84f29 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -89,6 +89,7 @@ typings/
|
|||||||
|
|
||||||
# Vite
|
# Vite
|
||||||
.vite/
|
.vite/
|
||||||
|
*.timestamp-*.mjs
|
||||||
|
|
||||||
# Electron-Forge
|
# Electron-Forge
|
||||||
out/
|
out/
|
||||||
|
|||||||
@@ -105,6 +105,7 @@ const menus = ref([
|
|||||||
{ name: '知识空间', index: '/knowledge', icon: 'book' },
|
{ name: '知识空间', index: '/knowledge', icon: 'book' },
|
||||||
{ name: 'opencode对话', index: '/chat', icon: 'bot' },
|
{ name: 'opencode对话', index: '/chat', icon: 'bot' },
|
||||||
{ name: '发现设备', index: '/bonjour', icon: 'server' },
|
{ name: '发现设备', index: '/bonjour', icon: 'server' },
|
||||||
|
{ name: '测试页', index: '/test', icon: 'flask-conical' },
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// 处理菜单点击
|
// 处理菜单点击
|
||||||
|
|||||||
125
src/renderer/components/LoginDialog.vue
Normal file
125
src/renderer/components/LoginDialog.vue
Normal file
@@ -0,0 +1,125 @@
|
|||||||
|
<template>
|
||||||
|
<el-dialog v-model="visible" :show-close="false" width="680px" border-radius="16px" :close-on-click-modal="true" class="login-dialog">
|
||||||
|
<div class="flex h-[420px] rounded-2xl overflow-hidden">
|
||||||
|
<!-- 左侧表单区 -->
|
||||||
|
<div class="flex flex-col items-center justify-center w-1/2 px-10 py-8 bg-white">
|
||||||
|
<!-- Logo 占位,后续替换为真实图片 -->
|
||||||
|
<div class="mb-4">
|
||||||
|
<div class="w-14 h-14 rounded-full bg-green-100 flex items-center justify-center text-2xl">🤖</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p class="text-base font-semibold text-gray-700 mb-6">登录后体验更多功能</p>
|
||||||
|
|
||||||
|
<el-form :model="form" :rules="rules" ref="formRef" class="w-full" @submit.prevent="handleLogin">
|
||||||
|
<el-form-item prop="username">
|
||||||
|
<el-input v-model="form.username" placeholder="请输入账号" :prefix-icon="User" size="large" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item prop="password">
|
||||||
|
<el-input v-model="form.password" type="password" placeholder="请输入密码" show-password size="large" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
|
||||||
|
<div class="w-full flex justify-end mb-4">
|
||||||
|
<span class="text-xs text-gray-400 cursor-pointer hover:text-green-500">忘记密码?</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
size="large"
|
||||||
|
class="w-full !bg-black !border-black !rounded-full !text-white font-semibold"
|
||||||
|
:loading="loading"
|
||||||
|
@click="handleLogin"
|
||||||
|
>
|
||||||
|
登录
|
||||||
|
</el-button>
|
||||||
|
|
||||||
|
<div class="mt-4 flex items-center gap-2 text-xs text-gray-400">
|
||||||
|
<el-checkbox v-model="agreed" size="small" />
|
||||||
|
<span>请先阅读<a href="#" class="text-green-500">用户协议与隐私政策</a></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 右侧品牌区 -->
|
||||||
|
<div class="flex flex-col items-center justify-between w-1/2 bg-[#5DC98A] px-8 py-8 rounded-r-2xl">
|
||||||
|
<div class="self-end text-white text-2xl font-bold tracking-widest">玄鉴</div>
|
||||||
|
<div class="flex flex-col items-center gap-3 text-white text-center">
|
||||||
|
<p class="text-xl font-semibold">我是AI工作助手</p>
|
||||||
|
<p class="text-sm opacity-80">能独立思考、自主执行的工作伙伴</p>
|
||||||
|
</div>
|
||||||
|
<div></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, watch } from 'vue';
|
||||||
|
import { User } from '@element-plus/icons-vue';
|
||||||
|
import { ElMessage } from 'element-plus';
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
modelValue: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const emit = defineEmits(['update:modelValue', 'login-success']);
|
||||||
|
|
||||||
|
const visible = ref(props.modelValue);
|
||||||
|
watch(
|
||||||
|
() => props.modelValue,
|
||||||
|
(val) => (visible.value = val)
|
||||||
|
);
|
||||||
|
watch(visible, (val) => emit('update:modelValue', val));
|
||||||
|
|
||||||
|
const formRef = ref(null);
|
||||||
|
const loading = ref(false);
|
||||||
|
const agreed = ref(false);
|
||||||
|
|
||||||
|
const form = ref({
|
||||||
|
username: '',
|
||||||
|
password: '',
|
||||||
|
});
|
||||||
|
|
||||||
|
const rules = {
|
||||||
|
username: [{ required: true, message: '请输入账号', trigger: 'blur' }],
|
||||||
|
password: [{ required: true, message: '请输入密码', trigger: 'blur' }],
|
||||||
|
};
|
||||||
|
|
||||||
|
async function handleLogin() {
|
||||||
|
if (!agreed.value) {
|
||||||
|
ElMessage.warning('请先阅读并同意用户协议与隐私政策');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
await formRef.value?.validate(async (valid) => {
|
||||||
|
if (!valid) return;
|
||||||
|
loading.value = true;
|
||||||
|
try {
|
||||||
|
// TODO: 替换为真实登录接口
|
||||||
|
await new Promise((r) => setTimeout(r, 800));
|
||||||
|
ElMessage.success('登录成功');
|
||||||
|
emit('login-success', { username: form.value.username });
|
||||||
|
visible.value = false;
|
||||||
|
} catch (err) {
|
||||||
|
ElMessage.error('登录失败,请重试');
|
||||||
|
} finally {
|
||||||
|
loading.value = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
:deep(.el-dialog) {
|
||||||
|
border-radius: 16px;
|
||||||
|
padding: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
:deep(.el-dialog__header) {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
:deep(.el-dialog__body) {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -19,6 +19,12 @@ const routes = [
|
|||||||
component: () => import('@/views/bonjour/BonjourView.vue'),
|
component: () => import('@/views/bonjour/BonjourView.vue'),
|
||||||
meta: { title: '发现设备' },
|
meta: { title: '发现设备' },
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: '/test',
|
||||||
|
name: 'Test',
|
||||||
|
component: () => import('@/views/test/TestView.vue'),
|
||||||
|
meta: { title: '测试页' },
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const router = createRouter({
|
const router = createRouter({
|
||||||
|
|||||||
17
src/renderer/views/test/TestView.vue
Normal file
17
src/renderer/views/test/TestView.vue
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
<template>
|
||||||
|
<div class="flex items-center justify-center h-full">
|
||||||
|
<el-button type="primary" size="large" @click="showLogin = true">打开登录弹窗</el-button>
|
||||||
|
<LoginDialog v-model="showLogin" @login-success="onLoginSuccess" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref } from 'vue';
|
||||||
|
import LoginDialog from '@/components/LoginDialog.vue';
|
||||||
|
|
||||||
|
const showLogin = ref(false);
|
||||||
|
|
||||||
|
function onLoginSuccess(user) {
|
||||||
|
console.log('登录成功:', user);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
Reference in New Issue
Block a user