feat(登录): 完善登录逻辑和用户信息处理

refactor(文章): 重构文章创建和分类选择功能

style(布局): 调整主布局样式和响应式设计

fix(状态管理): 修正全局状态存储和清除逻辑

feat(登出): 添加登出功能按钮和逻辑

docs(类型): 扩展文章类型定义字段
This commit is contained in:
qingfeng1121
2025-11-03 16:14:55 +08:00
parent 6d90b5842f
commit a927ad5a4d
9 changed files with 487 additions and 70 deletions

View File

@@ -52,19 +52,21 @@
<h1 class="typewriter">{{ heroText }}</h1> <h1 class="typewriter">{{ heroText }}</h1>
</div> </div>
<!-- 主内容区域 --> <!-- 提示区域 -->
<div id="content-section" :class="{ 'visible': isconts }"> <div id="content-section" :class="{ 'visible': isconts }">
<div class="nonsensetitle" v-if="classnonsenset"> <div class="nonsensetitle" v-if="classnonsenset">
<div class="nonsensetitleconst"> <div class="nonsensetitleconst">
<h1>发癫中QAQ</h1> <h1>{{Cardtitle}}</h1>
</div> </div>
</div> </div>
<!-- 左侧模块 --> <!-- 左侧模块 -->
<div class="leftmodluecontainer" v-if="isleftmodluecontainer">
<LeftModule class="leftmodluepage" :class="{ 'nonsensetmargintop': classnonsenset }" v-if="windowwidth" /> <LeftModule class="leftmodluepage" :class="{ 'nonsensetmargintop': classnonsenset }" v-if="windowwidth" />
</div>
<!-- 内容模块 --> <!-- 内容模块 -->
<RouterView class="RouterViewpage" :class="{ 'nonsensetmargintop': classnonsenset }" /> <RouterView class="RouterViewpage" :class="{'forbidwidth': !isleftmodluecontainer, 'nonsensetmargintop': classnonsenset }" />
</div> </div>
<!-- 分页区域 --> <!-- 分页区域 -->
@@ -84,10 +86,13 @@ const router = useRouter();
const route = useRoute(); const route = useRoute();
// 全局状态管理 // 全局状态管理
import { useGlobalStore } from '@/store/globalStore' import { useGlobalStore } from '@/store/globalStore'
import { Card } from 'ant-design-vue';
const globalStore = useGlobalStore() const globalStore = useGlobalStore()
const Login = computed(() => globalStore.Login) const Login = computed(() => globalStore.Login)
// 响应式状态 // 响应式状态
const Cardtitle = ref('');
const isleftmodluecontainer = ref(true);
const classhero = ref(false); const classhero = ref(false);
const isconts = ref(false); const isconts = ref(false);
const isScrollingleftmodlue = ref(false); const isScrollingleftmodlue = ref(false);
@@ -97,7 +102,7 @@ const windowwidth = ref(true);
const activeIndex = ref('home'); const activeIndex = ref('home');
const localhome= 'home'; const localhome= 'home';
let rpsliturl = route.path.split('/')[1]; let rpsliturl = route.path.split('/');
// 搜索相关状态 // 搜索相关状态
const isSearchBoxOpen = ref(false); const isSearchBoxOpen = ref(false);
@@ -105,7 +110,7 @@ const searchKeyword = ref('');
let searchCloseTimer: number | undefined; let searchCloseTimer: number | undefined;
// 打字机效果相关 // 打字机效果相关
let fullHeroText = '测试打字机效果'; let fullHeroText = '清疯不颠';
const heroText = ref(''); const heroText = ref('');
let heroIndex = 0; let heroIndex = 0;
let heroTimer: number | undefined; let heroTimer: number | undefined;
@@ -218,7 +223,7 @@ const handleResize = () => {
windowwidth.value = window.innerWidth > 768; windowwidth.value = window.innerWidth > 768;
// 根据屏幕大小调整内容区可见性 // 根据屏幕大小调整内容区可见性
if (rpsliturl === localhome) { if (rpsliturl[1] === localhome) {
isconts.value = window.innerWidth <= 768 ? true : false; isconts.value = window.innerWidth <= 768 ? true : false;
} }
}; };
@@ -241,7 +246,7 @@ const handleScroll = () => {
} }
// 首页内容区滚动动画 // 首页内容区滚动动画
if (rpsliturl === localhome) { if (rpsliturl[1] === localhome) {
isconts.value = window.scrollY > 200; isconts.value = window.scrollY > 200;
isScrollingleftmodlue.value = window.scrollY > 600; isScrollingleftmodlue.value = window.scrollY > 600;
} }
@@ -250,30 +255,34 @@ const handleScroll = () => {
/** /**
* 监听路由变化 * 监听路由变化
*/ */
watch(() => route.path, (newPath) => { watch(() => route.path, () => {
rpsliturl = route.path.split('/')[1]; rpsliturl = route.path.split('/');
updatePageState(rpsliturl); updatePageState(rpsliturl[1]);
setActiveIndex(rpsliturl); setActiveIndex(rpsliturl[1]);
const localname = route.path.split('/')[2]; console.log(rpsliturl[1])
let articledata; let articledata;
// 优先使用attributeId参数新接口 // 优先使用attributeId参数新接口
if (localname==='aericletype') { if (rpsliturl[2]==='aericletype') {
articledata = globalStore.getValue('attribute') articledata = globalStore.getValue('attribute')
} }
// 搜索标题 // 搜索标题
if (localname==='aericletitle') { if (rpsliturl[2]==='aericletitle') {
articledata = globalStore.getValue('title') articledata = globalStore.getValue('title')
} }
if (rpsliturl[1]==='nonsense') {
articledata = "疯言疯语"
}
// hero 标题 // hero 标题
if (articledata) { if (articledata) {
fullHeroText = articledata.name Cardtitle.value = articledata.name
classhero.value = true;
} }
// 跳转后回到顶部 // 跳转后回到顶部
window.scrollTo({ top: 0, behavior: 'smooth' }); window.scrollTo({ top: 0, behavior: 'smooth' });
// 首页内容区滚动动画仅大屏下生效 // 首页内容区滚动动画仅大屏下生效
if (newPath.split('/')[1] === localhome) { if (rpsliturl[1] === localhome && rpsliturl[2] == '') {
isconts.value = window.innerWidth <= 768 ? true : false; // isconts.value = window.innerWidth <= 768 ? true : false;
// 首页时启动打字机效果 // 首页时启动打字机效果
startTypewriter(); startTypewriter();
} else { } else {
@@ -281,6 +290,12 @@ watch(() => route.path, (newPath) => {
heroText.value =fullHeroText; heroText.value =fullHeroText;
if (heroTimer) clearInterval(heroTimer); if (heroTimer) clearInterval(heroTimer);
} }
// 非首页时关闭左侧状态栏
if (rpsliturl[1] == "articlesave") {
isleftmodluecontainer.value = false;
} else {
isleftmodluecontainer.value = true;
}
}, { immediate: true }); }, { immediate: true });
/** /**

View File

@@ -19,7 +19,7 @@
<script setup> <script setup>
import { ref, onMounted, onBeforeUnmount } from 'vue' import { ref, onMounted, onBeforeUnmount } from 'vue'
import { useRouter } from 'vue-router'; import { useRouter } from 'vue-router';
import { articleService, messageService, categoryAttributeService } from '@/services' import { articleService, messageService, categoryAttributeService ,loginService} from '@/services'
// 全局状态管理 // 全局状态管理
import { useGlobalStore } from '@/store/globalStore' import { useGlobalStore } from '@/store/globalStore'
const globalStore = useGlobalStore() const globalStore = useGlobalStore()
@@ -32,7 +32,8 @@ const buttons = [
{ id: 1, label: '新建文章', icon: 'icon-add-article' }, { id: 1, label: '新建文章', icon: 'icon-add-article' },
{ id: 2, label: '新建分类', icon: 'icon-create-category' }, { id: 2, label: '新建分类', icon: 'icon-create-category' },
{ id: 3, label: '疯言疯语', icon: 'icon-upload-file' }, { id: 3, label: '疯言疯语', icon: 'icon-upload-file' },
{ id: 4, label: '新建标签', icon: 'icon-new-tag' } { id: 4, label: '新建标签', icon: 'icon-new-tag' },
{ id: 5, label: '登出', icon: 'icon-logout' }
] ]
const buttonsave = [ const buttonsave = [
{ id: 1, label: '修改文章', icon: 'icon-add-article' }, { id: 1, label: '修改文章', icon: 'icon-add-article' },
@@ -98,6 +99,24 @@ const handleButtonClick = (button) => {
// 取消删除 // 取消删除
}) })
} }
if (button.label == '登出') {
// 调用登出接口
loginService.logout().then(response => {
if (response.code == 200) {
ElMessage.success('登出成功')
// 清空全局状态
globalStore.clearAll()
// 清除localStorage中的token
localStorage.removeItem('token')
// 跳转首页
router.push({ path: '/' })
} else {
ElMessage.error(response.message || '登出失败')
}
}).catch(err => {
ElMessage.error(err.message || '登出失败')
})
}
isExpanded.value = false // 点击后收起 isExpanded.value = false // 点击后收起
} }
@@ -235,6 +254,11 @@ onBeforeUnmount(() => {
margin-left: 0; margin-left: 0;
opacity: 1; opacity: 1;
} }
.action-button.show:nth-child(5) {
transition: all 0.2s ease-in-out;
margin-left: 0;
opacity: 1;
}
/* 确保按钮按顺序关闭,形成卷帘效果 */ /* 确保按钮按顺序关闭,形成卷帘效果 */
.action-button:nth-child(1) { .action-button:nth-child(1) {
@@ -261,7 +285,11 @@ onBeforeUnmount(() => {
opacity: 1; opacity: 1;
} }
.action-button:nth-child(5) {
transition: all 1.1s ease-in-out;
margin-left: 150px;
opacity: 1;
}
/* 响应式调整 */ /* 响应式调整 */
@media (max-width: 768px) { @media (max-width: 768px) {
.establish-container { .establish-container {

View File

@@ -54,8 +54,8 @@ class ArticleService {
* @param {import('../types').ArticleDto} articleData - 文章数据 * @param {import('../types').ArticleDto} articleData - 文章数据
* @returns {Promise<import('../types').ApiResponse<import('../types').Article>>} * @returns {Promise<import('../types').ApiResponse<import('../types').Article>>}
*/ */
createArticle(Article) { createArticle(articleData) {
return api.post('/articles', Article) return api.post('/articles', articleData)
} }
/** /**

View File

@@ -27,7 +27,9 @@ class LoginService {
* 登出 * 登出
*/ */
logout() { logout() {
return api.post("/auth/logout"); return api.post("/auth/logout");
} }
/** /**

View File

@@ -22,7 +22,7 @@ export const useGlobalStore = defineStore('global', {
// 全局数据对象,存储所有需要共享的数据 // 全局数据对象,存储所有需要共享的数据
globalData: initialGlobalData, globalData: initialGlobalData,
// 特定状态属性从localStorage读取初始值 // 特定状态属性从localStorage读取初始值
user: initialSpecificData.user || null, username: initialSpecificData.username || null,
Login: initialSpecificData.Login || false, Login: initialSpecificData.Login || false,
notifications: initialSpecificData.notifications || [] notifications: initialSpecificData.notifications || []
} }
@@ -80,7 +80,7 @@ export const useGlobalStore = defineStore('global', {
localStorage.setItem('globalStoreData', JSON.stringify(this.globalData)) localStorage.setItem('globalStoreData', JSON.stringify(this.globalData))
// 持久化特定状态属性 // 持久化特定状态属性
localStorage.setItem('globalStoreSpecificData', JSON.stringify({ localStorage.setItem('globalStoreSpecificData', JSON.stringify({
user: this.user, username: this.username,
Login: this.Login, Login: this.Login,
notifications: this.notifications notifications: this.notifications
})) }))
@@ -118,13 +118,13 @@ export const useGlobalStore = defineStore('global', {
*/ */
clearAll() { clearAll() {
this.globalData = {} this.globalData = {}
this.user = null this.username = null
this.Login = false this.Login = false
this.notifications = [] this.notifications = []
// 清除localStorage中的数据 // 清除localStorage中的数据
try { try {
localStorage.removeItem('globalStoreData') localStorage.removeItem('globalStoreData')
// localStorage.removeItem('globalStoreSpecificData') localStorage.removeItem('globalStoreSpecificData')
} catch (error) { } catch (error) {
console.error('Failed to clear data from localStorage:', error) console.error('Failed to clear data from localStorage:', error)
} }
@@ -134,8 +134,8 @@ export const useGlobalStore = defineStore('global', {
* 设置用户信息 * 设置用户信息
* @param {Object} userInfo - 用户信息对象 * @param {Object} userInfo - 用户信息对象
*/ */
setUser(userInfo) { setUsername(username) {
this.user = userInfo this.username = username
// 持久化到localStorage // 持久化到localStorage
this._persistData() this._persistData()
}, },

View File

@@ -240,6 +240,9 @@ p {
margin: var(--content-margin); margin: var(--content-margin);
} }
.RouterViewpage.forbidwidth {
width: 100%;
}
/* 分页区样式 */ /* 分页区样式 */
.Pagination { .Pagination {
align-self: center; align-self: center;
@@ -247,7 +250,7 @@ p {
} }
/* 左侧状态栏样式 */ /* 左侧状态栏样式 */
.leftmodluepage { .leftmodluecontainer {
width: var(--leftmodlue-width); width: var(--leftmodlue-width);
} }

View File

@@ -28,6 +28,10 @@ export interface ArticleDto {
attributeid: number attributeid: number
img?: string img?: string
status?: number status?: number
viewCount?: number
likes?: number
markdownscontent: string
} }
/** /**

View File

@@ -1,25 +1,40 @@
<template> <template>
<div id="allstyle"> <div id="allstyle">
<div class="article-header-section"> <div class="article-header-section">
<h1 class="article-main-title">{{ Articleform.title }}11</h1> <div style="text-align: center;">
<div class="article-meta-info"> <input type="text" v-model="Articleform.title" class="article-main-title" placeholder="请输入标题"
@focus="($event.target as HTMLInputElement).placeholder = ''"
@blur="($event.target as HTMLInputElement).placeholder = '请输入标题'"
style="border: none; outline: none; background: transparent; width: 100%; font-size: 2.5rem; font-weight: 700; line-height: 1.2; text-align: center;" />
</div>
<div class="article-meta-info" style="text-align: center;">
<span class="meta-item"> <span class="meta-item">
<i class="el-icon-date"></i>
<!-- {{ formatDate(Articleform.createdAt) }} -->
22 <i class="el-icon-document"></i>
<span> {{ new Date().toLocaleDateString() }} </span>
</span>
<span class="meta-item">
<i class="el-icon-document"></i>
<el-select v-model="Articleform.status" placeholder="请选择状态">
<el-option v-for="item in statusoptions" :key="item.value" :label="item.label" :value="item.value">
</el-option>
</el-select>
</span> </span>
<span class="meta-item"> <span class="meta-item">
<i class="el-icon-folder"></i> <i class="el-icon-folder"></i>
{{ Articleform.categoryName || '未分类' }}33 <el-cascader :options="categorieoptions" v-model="selectedValues" @change="handleCascaderChange"
</span> placeholder="选择分类和属性">
<span class="meta-item"> <template #default="{ node, data }">
<i class="el-icon-view"></i> <span>{{ data.label }}</span>
{{ Articleform.viewCount || 0 }} 阅读 <span v-if="!node.isLeaf"> ({{ data.children.length }}) </span>
</template>
</el-cascader>
</span> </span>
</div> </div>
</div> </div>
<div> <div>
<MdEditor v-model="Articleform.markdownscontent" htmlPreview preview={false} class="markdown-editor" @on-save="handleSave" /> <MdEditor v-model="Articleform.markdownscontent" class="markdown-editor" @on-save="handleSave" />
</div> </div>
</div> </div>
</template> </template>
@@ -28,8 +43,9 @@
import { ref } from 'vue'; import { ref } from 'vue';
import { MdEditor } from 'md-editor-v3'; import { MdEditor } from 'md-editor-v3';
import 'md-editor-v3/lib/style.css'; import 'md-editor-v3/lib/style.css';
import { articleService } from '@/services'; import { categoryService, categoryAttributeService, articleService } from '@/services';
import type { Article } from '@/types/index.ts'; import type { Article } from '@/types/index.ts';
import { ElMessage } from 'element-plus';
const Articleform = ref<Article>({ const Articleform = ref<Article>({
articleid: 0, articleid: 0,
title: '', title: '',
@@ -41,28 +57,373 @@ const Articleform = ref<Article>({
markdownscontent: '' markdownscontent: ''
}) })
// 用于级联选择器的值绑定
const selectedValues = ref([]);
const categorieoptions = ref([]);
const statusoptions = ref([
{
label: '未发布',
value: '0'
},
{
label: '发布',
value: '1'
}
]);
const categories = ref([]);
// 初始化加载分类和属性构建级联选择器的options
const loadCategories = async () => {
try {
const response = await categoryService.getAllCategories();
if (response.code === 200) {
categories.value = response.data;
// 为每个分类加载对应的属性并构建options格式
const optionsData = await Promise.all(
categories.value.map(async (category) => {
try {
const attrResponse = await categoryAttributeService.getAttributesByCategory(category.typeid);
const children = attrResponse.code === 200 && attrResponse.data ?
attrResponse.data.map(attr => ({
label: attr.attributename,
value: attr.attributeid.toString()
})) : [];
return {
label: category.typename,
value: category.typeid.toString(),
children
};
} catch (error) {
console.error(`加载分类 ${category.typename} 的属性失败:`, error);
return {
label: category.typename,
value: category.typeid.toString(),
children: []
};
}
})
);
categorieoptions.value = optionsData;
console.log(optionsData);
}
} catch (error) {
console.error('加载分类失败:', error);
}
};
// 处理级联选择变化
const handleCascaderChange = (values) => {
if (values && values.length > 0) {
// 最后一个值是属性ID
Articleform.value.attributeid = Number(values[values.length - 1]);
} else {
Articleform.value.attributeid = 0;
}
};
// 组件挂载时加载分类和属性
loadCategories();
const handleSave = (markdown) => { const handleSave = (markdown) => {
console.log(Articleform.value);
Articleform.value.markdownscontent = markdown; Articleform.value.markdownscontent = markdown;
// 这里可以添加保存逻辑,比如发送到服务器
articleService.createArticle({ // 验证必填字段
if (!Articleform.value.title || !Articleform.value.attributeid) {
ElMessage.warning('请填写必填字段:标题和分类属性');
return;
}
// 构建请求数据
const articleData = {
title: Articleform.value.title, title: Articleform.value.title,
content: Articleform.value.content, content: Articleform.value.content,
attributeid: Articleform.value.attributeid, attributeid: Number(Articleform.value.attributeid),
categoryName: Articleform.value.categoryName, status: Number(Articleform.value.status),
viewCount: 0,
likes: 0,
markdownscontent: Articleform.value.markdownscontent markdownscontent: Articleform.value.markdownscontent
}).then(res => { };
console.log('发送文章数据:', articleData);
console.log('当前认证token是否存在:', !!localStorage.getItem('token'));
// 保存文章
articleService.createArticle(articleData)
.then(res => {
console.log('API响应:', res);
if (res.code === 200) { if (res.code === 200) {
ElMessage.success('文章保存成功') ElMessage.success('文章保存成功')
} else { } else {
ElMessage.error(res.msg || '文章保存失败') ElMessage.error(res.message || '文章保存失败')
} }
}).catch(err => { })
.catch(err => {
console.error('保存失败错误详情:', err);
// 更详细的错误信息
if (err.response) {
console.error('错误状态码:', err.response.status);
console.error('错误响应数据:', err.response.data);
if (err.response.status === 401) {
ElMessage.error('未授权访问,请先登录');
} else if (err.response.status === 403) {
ElMessage.error('没有权限创建文章,请检查账号权限');
} else if (err.response.status === 400) {
ElMessage.error('数据验证失败: ' + (err.response.data?.message || '请检查输入'));
} else {
ElMessage.error('请求被拒绝,错误代码: ' + err.response.status);
}
} else {
ElMessage.error(err.message || '文章保存失败') ElMessage.error(err.message || '文章保存失败')
}
}) })
}; };
</script> </script>
<style scoped>
<style scoped>
.error-state-container .el-button {
margin-top: 16px;
}
/* 文章头部区域 */
.article-header-section {
margin-bottom: 32px;
padding-bottom: 24px;
border-bottom: 2px solid #ecf0f1;
}
/* 文章标题 */
.article-main-title {
font-size: 2rem;
color: #2c3e50;
line-height: 1.4;
margin-bottom: 20px;
font-weight: 600;
margin-top: 20px;
}
/* 文章元信息 */
.article-meta-info {
display: flex;
flex-wrap: wrap;
gap: 20px;
color: #7f8c8d;
font-size: 0.95rem;
}
/* 元信息项 */
.meta-item {
display: flex;
align-items: center;
gap: 6px;
font-weight: 500;
}
/* 文章内容区域 */
.article-content-area {
font-size: 1.05rem;
line-height: 1.8;
color: #34495e;
margin-bottom: 32px;
}
/* 文章内容中的段落 */
.article-content-area p {
margin-bottom: 16px;
text-align: justify;
}
/* 文章内容中的二级标题 */
.article-content-area h2 {
color: #2c3e50;
font-size: 1.5rem;
margin: 32px 0 16px 0;
padding-bottom: 8px;
border-bottom: 1px solid #ecf0f1;
font-weight: 600;
}
/* 文章内容中的三级标题 */
.article-content-area h3 {
color: #34495e;
font-size: 1.3rem;
margin: 24px 0 12px 0;
font-weight: 600;
}
/* 文章内容中的图片 */
.article-content-area img {
max-width: 100%;
height: auto;
border-radius: 8px;
margin: 20px auto;
display: block;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
/* 文章内容中的引用 */
.article-content-area blockquote {
border-left: 4px solid #3498db;
padding-left: 16px;
color: #7f8c8d;
margin: 16px 0;
font-style: italic;
}
/* 文章底部区域 */
.article-footer-section {
padding-top: 24px;
border-top: 2px solid #ecf0f1;
margin-bottom: 32px;
}
/* 标签列表 */
.article-tag-list {
margin-bottom: 24px;
display: flex;
flex-wrap: wrap;
gap: 10px;
}
/* 文章操作按钮组 */
.article-actions-group {
display: flex;
justify-content: flex-start;
}
/* 相关文章区域 */
.related-articles-section {
padding-top: 32px;
border-top: 2px solid #ecf0f1;
}
/* 相关文章标题 */
.related-articles-section h3 {
font-size: 1.3rem;
color: #2c3e50;
margin-bottom: 16px;
font-weight: 600;
}
/* 相关文章列表容器 */
.related-articles-list {
display: flex;
flex-direction: column;
gap: 12px;
}
/* 相关文章卡片 */
.related-article-card {
display: flex;
align-items: center;
gap: 10px;
padding: 12px;
background-color: #f8f9fa;
border-radius: 8px;
cursor: pointer;
transition: all 0.3s ease;
border: 1px solid transparent;
}
/* 相关文章卡片悬停效果 */
.related-article-card:hover {
background-color: #e9ecef;
transform: translateX(5px);
border-color: #3498db;
}
.related-article-card i {
color: #3498db;
}
.related-article-card span {
font-size: 1rem;
color: #495057;
transition: color 0.3s ease;
}
.related-article-card:hover span {
color: #3498db;
}
/* 评论区样式 */
.comment-section {
margin-top: 32px;
}
/* 响应式设计 - 平板和手机 */
@media (max-width: 768px) {
#article-detail-page {
padding: 20px 0;
}
.article-detail-wrapper,
.loading-state-container,
.error-state-container,
.empty-state-container {
padding: 20px;
margin: 0 15px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
.article-main-title {
font-size: 1.5rem;
line-height: 1.5;
}
.article-meta-info {
flex-direction: column;
align-items: flex-start;
gap: 8px;
font-size: 0.9rem;
}
.article-content-area {
font-size: 1rem;
line-height: 1.7;
}
.article-content-area h2 {
font-size: 1.3rem;
margin: 24px 0 12px 0;
}
.article-content-area h3 {
font-size: 1.2rem;
margin: 20px 0 10px 0;
}
.related-articles-section h3 {
font-size: 1.2rem;
}
.related-article-card {
padding: 10px;
gap: 8px;
}
.related-article-card span {
font-size: 0.95rem;
}
}
/* 响应式设计 - 小屏幕手机 */
@media (max-width: 480px) {
.article-detail-wrapper {
padding: 16px;
}
.article-main-title {
font-size: 1.35rem;
}
.article-meta-info {
font-size: 0.85rem;
}
}
</style> </style>

View File

@@ -144,24 +144,28 @@ const handleLogin = async () => {
} }
try { try {
// 模拟登录请求 // 模拟登录请求
let user = await loginService.login(loginForm) let user = await (await loginService.login(loginForm)).data
if (!user) { if (!user) {
ElMessage.error('登录失败,请检查用户名和密码') ElMessage.error('登录失败,请检查用户名和密码')
return return
} }
console.log('登录成功', user)
// 这里应该是实际的登录API调用 // 这里应该是实际的登录API调用
// console.log('登录请求数据:', loginForm) // console.log('登录请求数据:', loginForm)
// 模拟登录成功 // 模拟登录成功
ElMessage.success('登录成功') ElMessage.success('登录成功')
// 登录成功后,设置全局状态为已登录 // 登录成功后,设置全局状态为已登录
globalStore.setLoginStatus(user.success) globalStore.setLoginStatus(true)
globalStore.setLoading(user.success)
console.log('globalStore.Login', globalStore.Login) console.log('globalStore.Login', globalStore.Login)
// 保存登录状态 // 保存登录状态token
// if (loginForm.rememberMe) { if (user.token) {
// localStorage.setItem('username', loginForm.username) localStorage.setItem('token', user.token)
// } }
if (user.username) {
// 记住用户名
globalStore.setUsername(user.username)
}
// 跳转到首页 // 跳转到首页
router.push('/') router.push('/')
} catch (error) { } catch (error) {