Browse Source

登录界面设计编写

master
xing 5 months ago
parent
commit
f4a11bac3c
  1. BIN
      ConsoleApplication3/.vs/ConsoleApplication3/FileContentIndex/575a4d9f-7826-4be6-8d0b-26c9f4eed15b.vsidx
  2. BIN
      ConsoleApplication3/.vs/ConsoleApplication3/FileContentIndex/b230173a-a5c7-46f1-875a-cdf583bfb0c2.vsidx
  3. BIN
      ConsoleApplication3/.vs/ConsoleApplication3/FileContentIndex/b2a6f643-3e40-4172-8b83-d37eee529738.vsidx
  4. BIN
      ConsoleApplication3/.vs/ConsoleApplication3/FileContentIndex/f860067b-3463-4c23-ac88-5b3ebd0f8d25.vsidx
  5. BIN
      ConsoleApplication3/.vs/ConsoleApplication3/v17/.suo
  6. BIN
      ConsoleApplication3/.vs/ConsoleApplication3/v17/Browse.VC.db
  7. 24
      ConsoleApplication3/.vs/ConsoleApplication3/v17/DocumentLayout.backup.json
  8. 24
      ConsoleApplication3/.vs/ConsoleApplication3/v17/DocumentLayout.json
  9. BIN
      ConsoleApplication3/.vs/ConsoleApplication3/v17/fileList.bin
  10. BIN
      ConsoleApplication3/.vs/ConsoleApplication3/v17/ipch/AutoPCH/5717d974202c24cd/CONNMYSQL.ipch
  11. BIN
      ConsoleApplication3/.vs/ConsoleApplication3/v17/ipch/AutoPCH/81627db9d2113038/MAIN.ipch
  12. 3
      ConsoleApplication3/ConsoleApplication3.vcxproj
  13. BIN
      ConsoleApplication3/bin/x64/Debug/ConsoleApplication3.out
  14. 1
      ConsoleApplication3/connMysql.cpp
  15. 84
      ConsoleApplication3/main.cpp
  16. 3
      ConsoleApplication3/obj/x64/Debug/1622921215.CompileUpToDateFile.tlog
  17. 3
      ConsoleApplication3/obj/x64/Debug/1622921215.CopySourcesUpToDateFile.tlog
  18. 2
      ConsoleApplication3/obj/x64/Debug/1622921215.LinkUpToDateFile.tlog
  19. 3
      ConsoleApplication3/obj/x64/Debug/1622921215.Local_Remote_PathMapping.tlog
  20. 1
      ConsoleApplication3/obj/x64/Debug/ConsoleA.cca6b3fc.tlog/Cl.items.tlog
  21. BIN
      ConsoleApplication3/obj/x64/Debug/ConsoleA.cca6b3fc.tlog/compile.read.1.tlog
  22. BIN
      ConsoleApplication3/obj/x64/Debug/ConsoleA.cca6b3fc.tlog/compile.write.1.tlog
  23. BIN
      ConsoleApplication3/obj/x64/Debug/ConsoleA.cca6b3fc.tlog/link.write.1.tlog
  24. 1
      ConsoleApplication3/obj/x64/Debug/ConsoleApplication3.log
  25. 2
      talking_web_page/src/App.vue
  26. BIN
      talking_web_page/src/assets/1.webp
  27. BIN
      talking_web_page/src/assets/login.png
  28. BIN
      talking_web_page/src/assets/logo.png
  29. BIN
      talking_web_page/src/assets/register.jpg
  30. 10
      talking_web_page/src/main.js
  31. 14
      talking_web_page/src/router/index.js
  32. 379
      talking_web_page/src/views/AuthView.vue
  33. 85
      talking_web_page/src/views/DashboardView.vue
  34. 60
      talking_web_page/src/views/SuccessView.vue

BIN
ConsoleApplication3/.vs/ConsoleApplication3/FileContentIndex/575a4d9f-7826-4be6-8d0b-26c9f4eed15b.vsidx

Binary file not shown.

BIN
ConsoleApplication3/.vs/ConsoleApplication3/FileContentIndex/b230173a-a5c7-46f1-875a-cdf583bfb0c2.vsidx

Binary file not shown.

BIN
ConsoleApplication3/.vs/ConsoleApplication3/FileContentIndex/b2a6f643-3e40-4172-8b83-d37eee529738.vsidx

Binary file not shown.

BIN
ConsoleApplication3/.vs/ConsoleApplication3/FileContentIndex/f860067b-3463-4c23-ac88-5b3ebd0f8d25.vsidx

Binary file not shown.

BIN
ConsoleApplication3/.vs/ConsoleApplication3/v17/.suo

Binary file not shown.

BIN
ConsoleApplication3/.vs/ConsoleApplication3/v17/Browse.VC.db

Binary file not shown.

24
ConsoleApplication3/.vs/ConsoleApplication3/v17/DocumentLayout.backup.json

@ -5,6 +5,10 @@
{
"AbsoluteMoniker": "D:0:0:{CCA6B3FC-0982-4E23-9318-78BFD3A93243}|ConsoleApplication3.vcxproj|E:\\DataFile\\ProjectX\\TalkingWeb\\ConsoleApplication3\\main.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}",
"RelativeMoniker": "D:0:0:{CCA6B3FC-0982-4E23-9318-78BFD3A93243}|ConsoleApplication3.vcxproj|solutionrelative:main.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}"
},
{
"AbsoluteMoniker": "D:0:0:{CCA6B3FC-0982-4E23-9318-78BFD3A93243}|ConsoleApplication3.vcxproj|E:\\DataFile\\ProjectX\\TalkingWeb\\ConsoleApplication3\\connMysql.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}",
"RelativeMoniker": "D:0:0:{CCA6B3FC-0982-4E23-9318-78BFD3A93243}|ConsoleApplication3.vcxproj|solutionrelative:connMysql.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}"
}
],
"DocumentGroupContainers": [
@ -14,8 +18,24 @@
"DocumentGroups": [
{
"DockedWidth": 200,
"SelectedChildIndex": 0,
"SelectedChildIndex": 2,
"Children": [
{
"$type": "Bookmark",
"Name": "ST:0:0:{aa2115a1-9712-457b-9047-dbb71ca2cdd2}"
},
{
"$type": "Document",
"DocumentIndex": 1,
"Title": "connMysql.cpp",
"DocumentMoniker": "E:\\DataFile\\ProjectX\\TalkingWeb\\ConsoleApplication3\\connMysql.cpp",
"RelativeDocumentMoniker": "connMysql.cpp",
"ToolTip": "E:\\DataFile\\ProjectX\\TalkingWeb\\ConsoleApplication3\\connMysql.cpp",
"RelativeToolTip": "connMysql.cpp",
"ViewState": "AgIAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000677|",
"WhenOpened": "2025-02-17T04:47:25.019Z"
},
{
"$type": "Document",
"DocumentIndex": 0,
@ -24,7 +44,7 @@
"RelativeDocumentMoniker": "main.cpp",
"ToolTip": "E:\\DataFile\\ProjectX\\TalkingWeb\\ConsoleApplication3\\main.cpp",
"RelativeToolTip": "main.cpp",
"ViewState": "AgIAAAAAAAAAAAAAAAAAAA8AAAABAAAAAAAAAA==",
"ViewState": "AgIAABgAAAAAAAAAAAAAAC8AAAABAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000677|",
"WhenOpened": "2025-02-16T16:03:02.248Z",
"EditorCaption": ""

24
ConsoleApplication3/.vs/ConsoleApplication3/v17/DocumentLayout.json

@ -5,6 +5,10 @@
{
"AbsoluteMoniker": "D:0:0:{CCA6B3FC-0982-4E23-9318-78BFD3A93243}|ConsoleApplication3.vcxproj|E:\\DataFile\\ProjectX\\TalkingWeb\\ConsoleApplication3\\main.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}",
"RelativeMoniker": "D:0:0:{CCA6B3FC-0982-4E23-9318-78BFD3A93243}|ConsoleApplication3.vcxproj|solutionrelative:main.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}"
},
{
"AbsoluteMoniker": "D:0:0:{CCA6B3FC-0982-4E23-9318-78BFD3A93243}|ConsoleApplication3.vcxproj|E:\\DataFile\\ProjectX\\TalkingWeb\\ConsoleApplication3\\connMysql.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}",
"RelativeMoniker": "D:0:0:{CCA6B3FC-0982-4E23-9318-78BFD3A93243}|ConsoleApplication3.vcxproj|solutionrelative:connMysql.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}"
}
],
"DocumentGroupContainers": [
@ -14,8 +18,24 @@
"DocumentGroups": [
{
"DockedWidth": 200,
"SelectedChildIndex": 0,
"SelectedChildIndex": 2,
"Children": [
{
"$type": "Bookmark",
"Name": "ST:0:0:{aa2115a1-9712-457b-9047-dbb71ca2cdd2}"
},
{
"$type": "Document",
"DocumentIndex": 1,
"Title": "connMysql.cpp",
"DocumentMoniker": "E:\\DataFile\\ProjectX\\TalkingWeb\\ConsoleApplication3\\connMysql.cpp",
"RelativeDocumentMoniker": "connMysql.cpp",
"ToolTip": "E:\\DataFile\\ProjectX\\TalkingWeb\\ConsoleApplication3\\connMysql.cpp",
"RelativeToolTip": "connMysql.cpp",
"ViewState": "AgIAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000677|",
"WhenOpened": "2025-02-17T04:47:25.019Z"
},
{
"$type": "Document",
"DocumentIndex": 0,
@ -24,7 +44,7 @@
"RelativeDocumentMoniker": "main.cpp",
"ToolTip": "E:\\DataFile\\ProjectX\\TalkingWeb\\ConsoleApplication3\\main.cpp",
"RelativeToolTip": "main.cpp",
"ViewState": "AgIAADAAAAAAAAAAAAAAADkAAAABAAAAAAAAAA==",
"ViewState": "AgIAAAAAAAAAAAAAAAAAABkAAAAFAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000677|",
"WhenOpened": "2025-02-16T16:03:02.248Z",
"EditorCaption": ""

BIN
ConsoleApplication3/.vs/ConsoleApplication3/v17/fileList.bin

Binary file not shown.

BIN
ConsoleApplication3/.vs/ConsoleApplication3/v17/ipch/AutoPCH/5717d974202c24cd/CONNMYSQL.ipch

Binary file not shown.

BIN
ConsoleApplication3/.vs/ConsoleApplication3/v17/ipch/AutoPCH/81627db9d2113038/MAIN.ipch

Binary file not shown.

3
ConsoleApplication3/ConsoleApplication3.vcxproj

@ -77,13 +77,14 @@
<ImportGroup Label="PropertySheets" />
<PropertyGroup Label="UserMacros" />
<ItemGroup>
<ClCompile Include="connMysql.cpp" />
<ClCompile Include="main.cpp" />
</ItemGroup>
<ItemGroup>
</ItemGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<AdditionalIncludeDirectories>/usr/include;/usr/include/websocketpp;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>/usr/include;/usr/include/websocketpp;/usr/include/nlohmann;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<AdditionalLibraryDirectories>/usr/lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>

BIN
ConsoleApplication3/bin/x64/Debug/ConsoleApplication3.out

Binary file not shown.

1
ConsoleApplication3/connMysql.cpp

@ -0,0 +1 @@

84
ConsoleApplication3/main.cpp

@ -1,58 +1,48 @@
#include <cstdio>
#include <iostream>
#include <iostream>
#include <string>
#include <websocketpp/config/asio_no_tls.hpp>
#include <websocketpp/server.hpp>
// 0.定义server_t类型
typedef websocketpp::server<websocketpp::config::asio> server_t;
void OnOpen(websocketpp::connection_hdl hdl)
{
std::cout << "Websocket长连接建立成功" << std::endl;
}
void OnClose(websocketpp::connection_hdl hdl)
{
std::cout << "Websocket长连接断开" << std::endl;
}
void OnMessage(server_t* svr, websocketpp::connection_hdl hdl, server_t::message_ptr msg)
{
std::string body = msg->get_payload();
std::cout << "Get Msg: " << body << std::endl;
auto conn = svr->get_con_from_hdl(hdl);
conn->send(body + "-Response", websocketpp::frame::opcode::value::text);
#include <nlohmann/json.hpp>
using json = nlohmann::json;
using websocketpp::lib::placeholders::_1;
using websocketpp::lib::placeholders::_2;
using websocketpp::lib::bind;
typedef websocketpp::server<websocketpp::config::asio> server;
// 消息处理回调函数
void on_message(server* s, websocketpp::connection_hdl hdl, server::message_ptr msg) {
std::string payload = msg->get_payload();
std::cout << "Received JSON string: " << payload << std::endl;
// 解析JSON字符串
try {
json j = json::parse(payload);
std::cout << "Parsed JSON: " << j.dump(4) << std::endl; // 使用dump(4)美化输出
}
catch (json::parse_error& e) {
std::cerr << "Failed to parse JSON: " << e.what() << std::endl;
}
}
int main()
{
// 1.实例化服务器对象
server_t svr;
// 2.初始化日志输出 --> 关闭日志输出
svr.set_access_channels(websocketpp::log::alevel::none);
int main() {
server ws_server;
// 3.初始化ASIO框架
svr.init_asio();
// 初始化服务器
ws_server.init_asio();
// 4.设置消息处理/连接握手成功/连接关闭回调函数
svr.set_open_handler(OnOpen);
svr.set_close_handler(OnClose);
auto msg_handler = std::bind(OnMessage, &svr, std::placeholders::_1,
std::placeholders::_2);
svr.set_message_handler(msg_handler);
// 设置消息处理回调
ws_server.set_message_handler(bind(&on_message, &ws_server, ::_1, ::_2));
// 5.启用地址重用
svr.set_reuse_addr(true);
// 监听端口
ws_server.listen(8081);
// 6.设置监听端口
svr.listen(8081);
// 启动服务器
ws_server.start_accept();
// 7.开始监听
svr.start_accept();
// 运行服务器
ws_server.run();
// 8.启动服务器
svr.run();
return 0;
}

3
ConsoleApplication3/obj/x64/Debug/1622921215.CompileUpToDateFile.tlog

@ -1 +1,2 @@
E:\DataFile\ProjectX\TalkingWeb\ConsoleApplication3\main.cpp|638753491610634226|/root/ProjectCpp/root/ProjectCpp/ConsoleApplication3/||g++ -c -x c++ /root/ProjectCpp/root/ProjectCpp/ConsoleApplication3/main.cpp -I /usr/include -g2 -gdwarf-2 -o "/root/ProjectCpp/root/ProjectCpp/ConsoleApplication3/obj/x64/Debug/main.o" -Wall -Wswitch -W"no-deprecated-declarations" -W"empty-body" -Wconversion -W"return-type" -Wparentheses -W"no-format" -Wuninitialized -W"unreachable-code" -W"unused-function" -W"unused-value" -W"unused-variable" -O0 -fno-strict-aliasing -fno-omit-frame-pointer -fthreadsafe-statics -fexceptions -frtti -std=c++11
E:\DataFile\ProjectX\TalkingWeb\ConsoleApplication3\connMysql.cpp|638753935932534154|/root/ProjectCpp/root/ProjectCpp/ConsoleApplication3/||g++ -c -x c++ /root/ProjectCpp/root/ProjectCpp/ConsoleApplication3/connMysql.cpp -I /usr/include -I /usr/include/websocketpp -I /usr/include/nlohmann -g2 -gdwarf-2 -o "/root/ProjectCpp/root/ProjectCpp/ConsoleApplication3/obj/x64/Debug/connMysql.o" -Wall -Wswitch -W"no-deprecated-declarations" -W"empty-body" -Wconversion -W"return-type" -Wparentheses -W"no-format" -Wuninitialized -W"unreachable-code" -W"unused-function" -W"unused-value" -W"unused-variable" -O0 -fno-strict-aliasing -fno-omit-frame-pointer -fthreadsafe-statics -fexceptions -frtti -std=c++11
E:\DataFile\ProjectX\TalkingWeb\ConsoleApplication3\main.cpp|638753951995795770|/root/ProjectCpp/root/ProjectCpp/ConsoleApplication3/||g++ -c -x c++ /root/ProjectCpp/root/ProjectCpp/ConsoleApplication3/main.cpp -I /usr/include -I /usr/include/websocketpp -I /usr/include/nlohmann -g2 -gdwarf-2 -o "/root/ProjectCpp/root/ProjectCpp/ConsoleApplication3/obj/x64/Debug/main.o" -Wall -Wswitch -W"no-deprecated-declarations" -W"empty-body" -Wconversion -W"return-type" -Wparentheses -W"no-format" -Wuninitialized -W"unreachable-code" -W"unused-function" -W"unused-value" -W"unused-variable" -O0 -fno-strict-aliasing -fno-omit-frame-pointer -fthreadsafe-statics -fexceptions -frtti -std=c++11

3
ConsoleApplication3/obj/x64/Debug/1622921215.CopySourcesUpToDateFile.tlog

@ -1 +1,2 @@
E:\DataFile\ProjectX\TalkingWeb\ConsoleApplication3\main.cpp|638753491610634226|/root/ProjectCpp//root/ProjectCpp/ConsoleApplication3/|
E:\DataFile\ProjectX\TalkingWeb\ConsoleApplication3\connMysql.cpp|638753935932534154|/root/ProjectCpp//root/ProjectCpp/ConsoleApplication3/|
E:\DataFile\ProjectX\TalkingWeb\ConsoleApplication3\main.cpp|638753951995795770|/root/ProjectCpp//root/ProjectCpp/ConsoleApplication3/|

2
ConsoleApplication3/obj/x64/Debug/1622921215.LinkUpToDateFile.tlog

@ -1 +1 @@
cd /root/ProjectCpp/root/ProjectCpp/ConsoleApplication3/; g++ -o "/root/ProjectCpp/root/ProjectCpp/ConsoleApplication3/bin/x64/Debug/ConsoleApplication3.out" -Wl,--no-undefined -Wl,-L/usr/lib -Wl,-z,relro -Wl,-z,now -Wl,-z,noexecstack /root/ProjectCpp/root/ProjectCpp/ConsoleApplication3/obj/x64/Debug/main.o
cd /root/ProjectCpp/root/ProjectCpp/ConsoleApplication3/; g++ -o "/root/ProjectCpp/root/ProjectCpp/ConsoleApplication3/bin/x64/Debug/ConsoleApplication3.out" -Wl,--no-undefined -Wl,-L/usr/lib -Wl,-z,relro -Wl,-z,now -Wl,-z,noexecstack /root/ProjectCpp/root/ProjectCpp/ConsoleApplication3/obj/x64/Debug/connMysql.o /root/ProjectCpp/root/ProjectCpp/ConsoleApplication3/obj/x64/Debug/main.o

3
ConsoleApplication3/obj/x64/Debug/1622921215.Local_Remote_PathMapping.tlog

@ -1,4 +1,5 @@
E:\DataFile\ProjectX\TalkingWeb\ConsoleApplication3\main.cpp|/root/ProjectCpp/root/ProjectCpp/ConsoleApplication3/main.cpp
E:\DataFile\ProjectX\TalkingWeb\ConsoleApplication3\connMysql.cpp|/root/ProjectCpp/root/ProjectCpp/ConsoleApplication3/connMysql.cpp
E:\DataFile\ProjectX\TalkingWeb\ConsoleApplication3|/root/ProjectCpp/root/ProjectCpp/ConsoleApplication3
@E:\DataFile\ProjectX\TalkingWeb\ConsoleApplication3|@/root/ProjectCpp/root/ProjectCpp/ConsoleApplication3
E:\DataFile\ProjectX\TalkingWeb\ConsoleApplication3\main.cpp|/root/ProjectCpp/root/ProjectCpp/ConsoleApplication3/main.cpp
E:\DataFile\ProjectX\TalkingWeb\ConsoleApplication3\|/root/ProjectCpp/root/ProjectCpp/ConsoleApplication3/

1
ConsoleApplication3/obj/x64/Debug/ConsoleA.cca6b3fc.tlog/Cl.items.tlog

@ -1 +1,2 @@
E:\DataFile\ProjectX\TalkingWeb\ConsoleApplication3\connMysql.cpp;E:\DataFile\ProjectX\TalkingWeb\ConsoleApplication3\obj\x64\Debug\connMysql.o
E:\DataFile\ProjectX\TalkingWeb\ConsoleApplication3\main.cpp;E:\DataFile\ProjectX\TalkingWeb\ConsoleApplication3\obj\x64\Debug\main.o

BIN
ConsoleApplication3/obj/x64/Debug/ConsoleA.cca6b3fc.tlog/compile.read.1.tlog

Binary file not shown.

BIN
ConsoleApplication3/obj/x64/Debug/ConsoleA.cca6b3fc.tlog/compile.write.1.tlog

Binary file not shown.

BIN
ConsoleApplication3/obj/x64/Debug/ConsoleA.cca6b3fc.tlog/link.write.1.tlog

Binary file not shown.

1
ConsoleApplication3/obj/x64/Debug/ConsoleApplication3.log

@ -4,6 +4,7 @@
正在验证体系结构
正在启动远程生成
正在编译源:
connMysql.cpp
main.cpp
正在链接对象
ConsoleApplication3.vcxproj -> E:\DataFile\ProjectX\TalkingWeb\ConsoleApplication3\bin\x64\Debug\ConsoleApplication3.out

2
talking_web_page/src/App.vue

@ -17,6 +17,6 @@ export default {
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
margin-top: 0px;
}
</style>

BIN
talking_web_page/src/assets/1.webp

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

BIN
talking_web_page/src/assets/login.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 MiB

BIN
talking_web_page/src/assets/logo.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.7 KiB

BIN
talking_web_page/src/assets/register.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 MiB

10
talking_web_page/src/main.js

@ -1,4 +1,12 @@
import { createApp } from 'vue'
import App from './App.vue'
import router from './router/index.js'
createApp(App).use(router).mount('#app')
const app = createApp(App)
// 初始化 WebSocket 并挂载到 Vue 实例
const ws = new WebSocket('ws://localhost:8081')
app.config.globalProperties.$ws = ws
app.use(router)
app.mount('#app')

14
talking_web_page/src/router/index.js

@ -1,19 +1,17 @@
import { createRouter, createWebHistory } from 'vue-router'
import AuthView from '../views/AuthView.vue'
import SuccessView from '../views/SuccessView.vue'
const AuthView =() =>import('../views/AuthView.vue')
const routes = [
{
path: '/',
name: 'auth',
name: 'AuthView',
component: AuthView
},
{
path: '/dashboard',
name: 'dashboard',
component: () => import('../views/DashboardView.vue'),
meta: { requiresAuth: true }
path: '/success',
name: 'SuccessView',
component: SuccessView
}
]

379
talking_web_page/src/views/AuthView.vue

@ -1,245 +1,158 @@
<template>
<div class="auth-container">
<div class="auth-card">
<div class="tabs">
<button
:class="['tab', { active: isLogin }]"
@click="toggleForm(true)"
>
登录
</button>
<button
:class="['tab', { active: !isLogin }]"
@click="toggleForm(false)"
>
注册
</button>
</div>
<div class="auth-container">
<div class="auth-box">
<div class="image-container" @click="toggleForm">
<transition name="fade" mode="out-in">
<img :key="currentImage" :src="currentImage" alt="Auth Image" />
</transition>
</div>
<div class="form-container">
<transition name="fade" mode="out-in">
<h2 :key="isLogin ? '登录' : '注册'">{{ isLogin ? '登录' : '注册' }}</h2>
</transition>
<form @submit.prevent="handleSubmit">
<div class="form-group">
<label>用户名</label>
<input
v-model="form.username"
type="text"
required
placeholder="请输入用户名"
>
<span class="error" v-if="errors.username">{{ errors.username }}</span>
<label for="username">账号</label>
<input type="text" id="username" v-model="username" required />
</div>
<div class="form-group">
<label>密码</label>
<input
v-model="form.password"
type="password"
required
placeholder="请输入密码"
>
<span class="error" v-if="errors.password">{{ errors.password }}</span>
<label for="password">密码</label>
<input type="password" id="password" v-model="password" required />
</div>
<div v-if="!isLogin" class="form-group">
<label>确认密码</label>
<input
v-model="form.confirmPassword"
type="password"
required
placeholder="请再次输入密码"
>
<span class="error" v-if="errors.confirmPassword">{{ errors.confirmPassword }}</span>
<div class="button-group">
<button type="submit" v-if="isLogin" class="login-button">登录</button>
<button type="submit" v-else class="register-button">注册</button>
</div>
<button type="submit" class="submit-btn">
{{ isLogin ? '登录' : '注册' }}
<span v-if="loading" class="loader"></span>
</button>
</form>
</div>
</div>
</template>
<script setup>
import { ref, reactive } from 'vue'
import { useRouter } from 'vue-router'
import axios from 'axios'
const router = useRouter()
const isLogin = ref(true)
const loading = ref(false)
const form = reactive({
username: '',
password: '',
confirmPassword: ''
})
const errors = reactive({
username: '',
password: '',
confirmPassword: ''
})
const validateForm = () => {
let isValid = true
if (!form.username) {
errors.username = '用户名不能为空'
isValid = false
} else {
errors.username = ''
}
if (!form.password) {
errors.password = '密码不能为空'
isValid = false
} else if (form.password.length < 6) {
errors.password = '密码至少6位'
isValid = false
} else {
errors.password = ''
}
if (!isLogin.value) {
if (form.password !== form.confirmPassword) {
errors.confirmPassword = '两次密码不一致'
isValid = false
} else {
errors.confirmPassword = ''
}
</div>
</template>
<script>
export default {
data() {
return {
username: '',
password: '',
isLogin: true,
loginImage: require('@/assets/login.png'),
registerImage: require('@/assets/register.jpg'),
};
},
computed: {
currentImage() {
return this.isLogin ? this.loginImage : this.registerImage;
}
return isValid
}
const handleSubmit = async () => {
if (!validateForm()) return
loading.value = true
try {
const url = isLogin.value ? '/api/login' : '/api/register'
const response = await axios.post(url, {
username: form.username,
password: form.password
})
localStorage.setItem('authToken', response.data.token)
router.push('/dashboard')
} catch (error) {
alert(error.response?.data?.message || '请求失败')
} finally {
loading.value = false
},
methods: {
handleSubmit() {
const data = {
username: this.username,
password: this.password,
action: this.isLogin ? 'login' : 'register',
};
// WebSocket
this.$ws.send(JSON.stringify(data));
//
this.$router.push({ name: 'SuccessView' });
},
toggleForm() {
this.isLogin = !this.isLogin;
this.username = '';
this.password = '';
}
}
const toggleForm = (login) => {
isLogin.value = login
Object.keys(form).forEach(key => form[key] = '')
Object.keys(errors).forEach(key => errors[key] = '')
}
</script>
<style scoped>
.auth-container {
min-height: 100vh;
display: flex;
justify-content: center;
align-items: center;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
}
.auth-card {
background: white;
padding: 2rem;
border-radius: 15px;
box-shadow: 0 10px 30px rgba(0,0,0,0.1);
width: 100%;
max-width: 400px;
}
.tabs {
display: flex;
margin-bottom: 2rem;
border-bottom: 2px solid #eee;
}
.tab {
flex: 1;
padding: 1rem;
border: none;
background: none;
cursor: pointer;
font-size: 1.1rem;
transition: all 0.3s ease;
}
.tab.active {
color: #6366f1;
border-bottom: 3px solid #6366f1;
}
.form-group {
margin-bottom: 1.5rem;
}
label {
display: block;
margin-bottom: 0.5rem;
color: #666;
}
input {
width: 100%;
padding: 0.8rem;
border: 1px solid #ddd;
border-radius: 8px;
font-size: 1rem;
transition: border-color 0.3s ease;
}
input:focus {
outline: none;
border-color: #6366f1;
box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.2);
}
.error {
color: #ef4444;
font-size: 0.875rem;
margin-top: 0.25rem;
display: block;
}
.submit-btn {
width: 100%;
padding: 1rem;
background: #6366f1;
color: white;
border: none;
border-radius: 8px;
font-size: 1rem;
cursor: pointer;
transition: background 0.3s ease;
position: relative;
}
.submit-btn:hover {
background: #4f46e5;
}
.loader {
display: inline-block;
width: 20px;
height: 20px;
border: 3px solid rgba(255,255,255,0.3);
border-radius: 50%;
border-top-color: #fff;
animation: spin 1s ease-in-out infinite;
position: absolute;
right: 1rem;
}
@keyframes spin {
to { transform: rotate(360deg); }
}
</style>
},
};
</script>
<style scoped>
.auth-container {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
width: 100%;
background: linear-gradient(135deg, #a6c0fe, #f68084);
}
.auth-box {
display: flex;
background: white;
padding: 2rem;
border-radius: 8px;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
width: 800px;
height: 400px;
overflow: hidden;
position: relative;
}
.image-container {
flex: 1;
position: relative;
cursor: pointer;
overflow: hidden;
}
.image-container img {
width: 100%;
height: 100%;
object-fit: cover;
}
.form-container {
flex: 1;
padding: 1rem;
}
h2 {
text-align: center;
margin-bottom: 1.5rem;
}
.form-group {
margin-bottom: 1rem;
}
label {
display: block;
margin-bottom: 0.5rem;
}
input {
width: 100%;
padding: 0.5rem;
border: 1px solid #ccc;
border-radius: 4px;
}
.button-group {
display: flex;
justify-content: center;
margin-top: 1rem;
}
.login-button, .register-button {
width: 45%;
padding: 0.75rem;
border: none;
border-radius: 4px;
background: #2575fc;
color: white;
cursor: pointer;
transition: background-color 0.3s ease;
}
.login-button:hover, .register-button:hover {
background: #1a5bbf;
}
.fade-enter-active, .fade-leave-active {
transition: opacity 0.5s ease;
}
.fade-enter-from, .fade-leave-to {
opacity: 0;
}
</style>

85
talking_web_page/src/views/DashboardView.vue

@ -1,85 +0,0 @@
<template>
<div class="dashboard">
<h1>欢迎回来, {{ userInfo.username }}!</h1>
<div class="user-info">
<p>注册时间: {{ formatDate(userInfo.createdAt) }}</p>
<button @click="handleLogout" class="logout-btn">退出登录</button>
</div>
</div>
</template>
<script setup>
import { ref, onMounted } from 'vue'
import { useRouter } from 'vue-router'
import axios from 'axios'
const router = useRouter()
const userInfo = ref({
username: '',
createdAt: ''
})
const formatDate = (dateString) => {
return new Date(dateString).toLocaleDateString()
}
const fetchUserData = async () => {
try {
const response = await axios.get('/api/user')
userInfo.value = response.data
} catch (error) {
alert('获取用户信息失败')
router.push('/')
}
}
const handleLogout = () => {
localStorage.removeItem('authToken')
router.push('/')
}
onMounted(() => {
if (!localStorage.getItem('authToken')) {
router.push('/')
} else {
fetchUserData()
}
})
</script>
<style scoped>
.dashboard {
max-width: 800px;
margin: 2rem auto;
padding: 2rem;
background: white;
border-radius: 15px;
box-shadow: 0 4px 6px rgba(0,0,0,0.1);
}
h1 {
color: #6366f1;
margin-bottom: 1.5rem;
}
.user-info {
padding: 1.5rem;
background: #f8f9fa;
border-radius: 10px;
}
.logout-btn {
margin-top: 1rem;
padding: 0.5rem 1.5rem;
background: #ef4444;
color: white;
border: none;
border-radius: 6px;
cursor: pointer;
transition: background 0.3s ease;
}
.logout-btn:hover {
background: #dc2626;
}
</style>

60
talking_web_page/src/views/SuccessView.vue

@ -0,0 +1,60 @@
<template>
<div class="success-container">
<div class="success-box">
<h2>操作成功</h2>
<p>您已成功登录/注册</p>
<button @click="goBack">返回首页</button>
</div>
</div>
</template>
<script>
export default {
methods: {
goBack() {
this.$router.push({ name: 'AuthView' });
}
}
};
</script>
<style scoped>
.success-container {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
width: 100%;
background: linear-gradient(135deg, #a6c0fe, #f68084);
}
.success-box {
background: white;
padding: 2rem;
border-radius: 8px;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
width: 300px;
text-align: center;
}
h2 {
margin-bottom: 1rem;
}
p {
margin-bottom: 1.5rem;
}
button {
padding: 0.5rem 1rem;
border: none;
border-radius: 4px;
background: #2575fc;
color: white;
cursor: pointer;
}
button:hover {
background: #1a5bbf;
}
</style>
Loading…
Cancel
Save