From 75e6912a8d93725e1038d1ecd9c1438ec223f2ca Mon Sep 17 00:00:00 2001
From: wujingjing <gersonwu@qq.com>
Date: 星期四, 14 十一月 2024 14:38:10 +0800
Subject: [PATCH] refactor(layout): 重构布局组件并优化登录功能

---
 vite.config.ts                                       |    2 
 src/stores/chatRoom.ts                               |    2 
 src/layout/component/main.vue                        |   13 +
 src/layout/component/sidebar/components/MenuList.vue |  148 --------------------
 src/layout/component/login/Login.vue                 |  253 ++++++++++++++++++++++++++++++++++++
 5 files changed, 267 insertions(+), 151 deletions(-)

diff --git a/src/layout/component/login/Login.vue b/src/layout/component/login/Login.vue
new file mode 100644
index 0000000..89733e9
--- /dev/null
+++ b/src/layout/component/login/Login.vue
@@ -0,0 +1,253 @@
+<template>
+	<div class="pc-login items-center justify-center" style="display: flex" v-show="isShowLogin">
+		<div class="login_box">
+			<div class="sign_in">
+				<i class="ywifont ywicon-guanbi closes" @click="handleClose"></i>
+				<h1><span>鐧诲綍 WI 姘村姟鏅鸿兘</span></h1>
+				<el-tabs v-model="state.activeLoginName" class="mt-[24px]" @tab-change="handleUserClick">
+					<el-tab-pane label="璐︽埛瀵嗙爜鐧诲綍" name="accountUser">
+						<el-form
+							ref="loginFormRef"
+							:model="state.loginForm"
+							:rules="loginRules"
+							class="demo-ruleForm mt-[24px] min-h-[140px]"
+							size="large"
+						>
+							<el-form-item label="璐﹀彿" prop="account">
+								<el-input v-model="state.loginForm.account" clearable />
+							</el-form-item>
+							<el-form-item label="瀵嗙爜" prop="pwd">
+								<el-input v-model="state.loginForm.pwd" type="password" autocomplete="off" clearable />
+							</el-form-item>
+						</el-form>
+					</el-tab-pane>
+					<el-tab-pane label="鎵嬫満鍙风櫥褰�" name="phoneUser">
+						<el-form
+							ref="formPhoneRef"
+							:rules="loginPhoneRules"
+							:model="state.loginPhoneForm"
+							size="large"
+							class="mt-[24px] min-h-[140px]"
+						>
+							<el-form-item label="鎵嬫満鍙�" prop="phoneUser">
+								<el-input v-model="state.loginPhoneForm.phoneUser" placeholder="璇疯緭鍏ユ墜鏈哄彿鐮�" clearable>
+									<template #prepend>+86</template>
+								</el-input>
+							</el-form-item>
+							<el-form-item prop="verifyCode" label="楠岃瘉鐮�">
+								<el-input v-model="state.loginPhoneForm.verifyCode" placeholder="璇疯緭鍏ュ洓浣嶉獙璇佺爜" maxlength="6" clearable>
+									<template #append>
+										<el-button type="primary" @click="handleSendVerifyCode" :disabled="hasSended">{{ sendCodeMsg }}</el-button>
+									</template>
+								</el-input>
+							</el-form-item>
+						</el-form>
+					</el-tab-pane>
+				</el-tabs>
+
+				<div class="mt-[24px]">
+					<el-button type="primary" @click="onSubmit" class="set-login_btn">鐧诲綍</el-button>
+				</div>
+			</div>
+		</div>
+	</div>
+</template>
+<script setup lang="ts">
+import { ElMessage, type FormInstance } from 'element-plus';
+import { computed, reactive, ref } from 'vue';
+import { PostLogin, loginMessageUser, loginVerifyMessage } from '/@/api/ai/user';
+import { isLoginStatus, isShowLogin } from '/@/stores/chatRoom';
+
+import { LoginInfo } from '/@/utils/storage';
+
+const handleClose = () => {
+	isShowLogin.value = false;
+};
+
+//鍒囨崲鐢ㄦ埛鐧诲綍椤甸潰
+const handleUserClick = (item) => {
+	state.activeLoginName = item;
+	// formPhoneRef?.value?.resetFields();
+	// loginFormRef.value.resetFields();
+};
+const state = reactive({
+	activeLoginName: 'accountUser',
+	loginForm: {
+		account: '',
+		pwd: '',
+	},
+	loginPhoneForm: {
+		phoneUser: '',
+		verifyCode: '',
+	},
+});
+const loginRules = reactive({
+	account: [{ required: true, message: '璇疯緭鍏ヨ处鍙�', trigger: 'blur' }],
+	pwd: [{ required: true, message: '璇疯緭鍏ュ瘑鐮�', trigger: 'blur' }],
+});
+const loginPhoneRules = {
+	phoneUser: [
+		{ required: true, message: '璇疯緭鍏ユ墜鏈哄彿鐮�', trigger: 'blur' },
+		{ pattern: /^1\d{10}$/, message: '璇疯緭鍏ユ纭殑鎵嬫満鍙风爜', trigger: 'blur' },
+	],
+	verifyCode: [{ required: true, message: '璇疯緭鍏ラ獙璇佺爜', trigger: 'blur' }],
+};
+const LOGIN_CLIENT = 'Web绔�';
+const loginFormRef = ref<FormInstance>(null); //璐︽埛瀵嗙爜鐧诲綍
+const formPhoneRef = ref(); //鎵嬫満鍙风櫥褰�
+const hasSended = computed(() => {
+	return countdown.value !== null;
+});
+const sendCodeMsg = computed(() => {
+	return !hasSended.value ? '鑾峰彇楠岃瘉鐮�' : `${countdown.value} 绉掑悗閲嶈瘯`;
+});
+//鐧诲綍
+const onSubmit = async () => {
+	if (state.activeLoginName === 'accountUser') {
+		//璐︽埛瀵嗙爜鐧诲綍
+		const isValid = await loginFormRef.value.validate().catch(() => {});
+		if (!isValid) return;
+		const res = await PostLogin({
+			user: state.loginForm.account,
+			pass: state.loginForm.pwd,
+			client: LOGIN_CLIENT,
+		});
+		if (!res.json_ok) {
+			return ElMessage.error(res.json_msg);
+		}
+
+		LoginInfo.set(res.hswatersession, state.loginForm.account);
+	} else if (state.activeLoginName === 'phoneUser') {
+		//鎵嬫満鐧诲綍
+		const isValid = await formPhoneRef.value.validate().catch(() => {});
+		if (!isValid) return;
+		const res = await loginMessageUser({
+			phone: state.loginPhoneForm.phoneUser,
+			code: state.loginPhoneForm.verifyCode,
+			client: LOGIN_CLIENT,
+		});
+		if (!res.json_ok) {
+			return ElMessage.error(res.json_msg);
+		}
+		LoginInfo.set(res.hswatersession, state.loginPhoneForm.phoneUser);
+	}
+
+	isShowLogin.value = false;
+	isLoginStatus.value = true;
+	window.location.reload();
+};
+const countdown = ref(null);
+
+//鑾峰彇楠岃瘉鐮�
+const handleSendVerifyCode = async () => {
+	formPhoneRef.value.validateField('phoneUser', async (valid: boolean) => {
+		if (valid) {
+			const res = await loginVerifyMessage({
+				phone: state.loginPhoneForm.phoneUser,
+			});
+			if (res.json_ok) {
+				countdown.value = 60; //寮�鍚�掕鏃�
+				// 鍊掕鏃堕�昏緫
+				const intervalId = setInterval(() => {
+					if (countdown.value > 0) {
+						countdown.value--;
+					} else {
+						clearInterval(intervalId);
+					}
+				}, 1000);
+			}
+		}
+	});
+};
+</script>
+
+<style lang="scss" scoped>
+.pc-login {
+	position: fixed;
+	top: 0;
+	left: 0;
+	width: 100vw;
+	height: 100vh;
+	z-index: 2000;
+	background-color: rgba(0, 0, 0, 0.6);
+	.login_box {
+		position: relative;
+		width: 450px;
+		margin: 15vh auto;
+		.sign_in {
+			padding: 39px;
+			position: relative;
+			width: 100%;
+			height: 100%;
+			border-radius: 12px;
+			-webkit-box-sizing: border-box;
+			box-sizing: border-box;
+			display: flex;
+			-webkit-box-orient: vertical;
+			-webkit-box-direction: normal;
+			-ms-flex-direction: column;
+			flex-direction: column;
+			-webkit-box-align: center;
+			-ms-flex-align: center;
+			align-items: center;
+			background-color: #fff;
+			-webkit-box-shadow: 0 0 16px 0 rgba(20, 29, 53, 0.21);
+			box-shadow: 0 0 16px 0 rgba(20, 29, 53, 0.21);
+			.closes {
+				position: absolute;
+				top: -28px;
+				right: -38px;
+				font-size: 30px;
+				cursor: pointer;
+				color: #eee;
+				-o-transition: color 0.1s;
+				transition: color 0.1s;
+			}
+			h1 {
+				box-sizing: content-box;
+				width: 100%;
+				font-size: 30px;
+				font-weight: 500;
+				color: #1c153a;
+				text-align: left !important;
+			}
+			.demo-ruleForm {
+				:deep(.el-input__wrapper) {
+					position: relative;
+					margin-bottom: 12px;
+					display: flex;
+					-webkit-box-align: center;
+					-ms-flex-align: center;
+					align-items: center;
+					width: 346px;
+					// height: 44px;
+					background-color: #fff;
+					border-radius: 5px;
+				}
+				:deep(.el-form-item--large .el-form-item__error) {
+					padding: unset !important;
+				}
+			}
+			.set-pwd {
+				text-align: right;
+				font-size: 14px;
+				font-weight: 300;
+				color: #999;
+				width: 100%;
+				padding: 0px 32px;
+			}
+			.set-login_btn {
+				width: 366px;
+				height: 44px;
+				font-size: 16px;
+				font-weight: 500;
+				color: #fff;
+				background: #0a58ed;
+				border-radius: 12px;
+				-webkit-box-shadow: 4px 6px 15px rgba(10, 88, 237, 0.2);
+				box-shadow: 4px 6px 15px rgba(10, 88, 237, 0.2);
+			}
+		}
+	}
+}
+</style>
diff --git a/src/layout/component/main.vue b/src/layout/component/main.vue
index ae57df5..c497846 100644
--- a/src/layout/component/main.vue
+++ b/src/layout/component/main.vue
@@ -9,7 +9,7 @@
 			wrap-class="layout-main-scroll  flex"
 			view-class="layout-main-scroll bg-[#1c1e1d]  flex h100 w-full"
 		>
-			<SideBar v-if="!isSharePage && sidebarIsShow" :isShow="sidebarIsShow" @toggleSidebar="toggleSidebar"/>
+			<SideBar v-if="!isSharePage && sidebarIsShow" :isShow="sidebarIsShow" @toggleSidebar="toggleSidebar" />
 			<div
 				class="flex-auto flex-col flex right-container"
 				:class="{
@@ -19,10 +19,11 @@
 					'bg-[#f7f8fa]': isSharePage,
 				}"
 			>
-				<Header v-if="!isSharePage" class="flex-0" @toggleSidebar="toggleSidebar" :sidebarIsShow="sidebarIsShow"/>
+				<Header v-if="!isSharePage" class="flex-0" @toggleSidebar="toggleSidebar" :sidebarIsShow="sidebarIsShow" />
 				<ShareHeader v-else class="flex-0"></ShareHeader>
 				<LayoutParentView class="flex-auto" />
 			</div>
+			<Login v-show="isShowLogin" />
 		</el-scrollbar>
 		<el-backtop :target="setBacktopClass" />
 	</el-main>
@@ -36,12 +37,12 @@
 import ShareHeader from './header/ShareHeader.vue';
 
 import SideBar from './sidebar/Sidebar.vue';
+import { isSharePage, isShowLogin } from '/@/stores/chatRoom';
 import { useTagsViewRoutes } from '/@/stores/tagsViewRoutes';
 import { useThemeConfig } from '/@/stores/themeConfig';
 import { NextLoading } from '/@/utils/loading';
-import { isSharePage } from '/@/stores/chatRoom';
 import { Local } from '/@/utils/storage';
-
+import Login from './login/Login.vue';
 // 寮曞叆缁勪欢
 const LayoutParentView = defineAsyncComponent(() => import('/@/layout/routerView/parent.vue'));
 const LayoutFooter = defineAsyncComponent(() => import('/@/layout/footer/index.vue'));
@@ -52,7 +53,7 @@
 const storesThemeConfig = useThemeConfig();
 const { themeConfig } = storeToRefs(storesThemeConfig);
 const { isTagsViewCurrenFull } = storeToRefs(storesTagsViewRoutes);
-
+;
 // 璁剧疆 footer 鏄剧ず/闅愯棌
 const isFooter = computed(() => {
 	return themeConfig.value.isFooter && !route.meta.isIframe;
@@ -87,7 +88,7 @@
 const sidebarIsShow = ref(!!Local.get('sidebarIsShow'));
 const toggleSidebar = (val) => {
 	sidebarIsShow.value = val;
-	Local.set('sidebarIsShow',val)
+	Local.set('sidebarIsShow', val);
 };
 //#endregion
 </script>
diff --git a/src/layout/component/sidebar/components/MenuList.vue b/src/layout/component/sidebar/components/MenuList.vue
index 579cdb5..2bbf11c 100644
--- a/src/layout/component/sidebar/components/MenuList.vue
+++ b/src/layout/component/sidebar/components/MenuList.vue
@@ -37,76 +37,19 @@
 			</div>
 		</div>
 	</div>
-	<div class="pc-login items-center justify-center" style="display: flex" v-show="isShowLogin">
-		<div class="login_box">
-			<div class="sign_in">
-				<i class="ywifont ywicon-guanbi closes" @click="handleClose"></i>
-				<h1><span>鐧诲綍 WI 姘村姟鏅鸿兘</span></h1>
-				<el-tabs v-model="state.activeLoginName" class="mt-[24px]" @tab-change="handleUserClick">
-					<el-tab-pane label="璐︽埛瀵嗙爜鐧诲綍" name="accountUser">
-						<el-form
-							ref="loginFormRef"
-							:model="state.loginForm"
-							:rules="loginRules"
-							class="demo-ruleForm mt-[24px] min-h-[140px]"
-							size="large"
-						>
-							<el-form-item label="璐﹀彿" prop="account">
-								<el-input v-model="state.loginForm.account" clearable />
-							</el-form-item>
-							<el-form-item label="瀵嗙爜" prop="pwd">
-								<el-input v-model="state.loginForm.pwd" type="password" autocomplete="off" clearable />
-							</el-form-item>
-						</el-form>
-					</el-tab-pane>
-					<el-tab-pane label="鎵嬫満鍙风櫥褰�" name="phoneUser">
-						<el-form
-							ref="formPhoneRef"
-							:rules="loginPhoneRules"
-							:model="state.loginPhoneForm"
-							size="large"
-							class="mt-[24px] min-h-[140px]"
-						>
-							<el-form-item label="鎵嬫満鍙�" prop="phoneUser">
-								<el-input v-model="state.loginPhoneForm.phoneUser" placeholder="璇疯緭鍏ユ墜鏈哄彿鐮�" clearable>
-									<template #prepend>+86</template>
-								</el-input>
-							</el-form-item>
-							<el-form-item prop="verifyCode" label="楠岃瘉鐮�">
-								<el-input v-model="state.loginPhoneForm.verifyCode" placeholder="璇疯緭鍏ュ洓浣嶉獙璇佺爜" maxlength="6" clearable>
-									<template #append>
-										<el-button type="primary" @click="handleSendVerifyCode" :disabled="hasSended">{{ sendCodeMsg }}</el-button>
-									</template>
-								</el-input>
-							</el-form-item>
-						</el-form>
-					</el-tab-pane>
-				</el-tabs>
-
-				<div class="mt-[24px]">
-					<el-button type="primary" @click="onSubmit" class="set-login_btn">鐧诲綍</el-button>
-				</div>
-			</div>
-		</div>
-	</div>
 </template>
 
 <script setup lang="ts">
-import { ElMessage, type FormInstance } from 'element-plus';
 import { computed, onMounted, reactive, ref, watchEffect } from 'vue';
-import { PostLogin, loginMessageUser, loginVerifyMessage } from '/@/api/ai/user';
 import router from '/@/router';
-import { isSharePage, isShowLogin } from '/@/stores/chatRoom';
-import emitter from '/@/utils/mitt';
+import { isLoginStatus, isSharePage, isShowLogin } from '/@/stores/chatRoom';
 import { accessSessionKey, userNameKey } from '/@/utils/request';
 import { gotoRoute } from '/@/utils/route';
 import { Local, LoginInfo } from '/@/utils/storage';
-const loginFormRef = ref<FormInstance>(null); //璐︽埛瀵嗙爜鐧诲綍
-const formPhoneRef = ref(); //鎵嬫満鍙风櫥褰�
-const isLoginStatus = ref(!!Local.get(accessSessionKey));
+import emitter from '/@/utils/mitt';
 const userName = ref('');
-const countdown = ref(null);
 const firstUserCharacter = computed(() => userName.value?.[0]?.toUpperCase());
+isLoginStatus.value = !!Local.get(accessSessionKey);
 watchEffect(() => {
 	if (!isLoginStatus.value) return;
 	userName.value = Local.get(userNameKey);
@@ -148,72 +91,16 @@
 	},
 	activeLoginName: 'accountUser',
 });
-const loginRules = reactive({
-	account: [{ required: true, message: '璇疯緭鍏ヨ处鍙�', trigger: 'blur' }],
-	pwd: [{ required: true, message: '璇疯緭鍏ュ瘑鐮�', trigger: 'blur' }],
-});
-const loginPhoneRules = {
-	phoneUser: [
-		{ required: true, message: '璇疯緭鍏ユ墜鏈哄彿鐮�', trigger: 'blur' },
-		{ pattern: /^1\d{10}$/, message: '璇疯緭鍏ユ纭殑鎵嬫満鍙风爜', trigger: 'blur' },
-	],
-	verifyCode: [{ required: true, message: '璇疯緭鍏ラ獙璇佺爜', trigger: 'blur' }],
-};
 const handleClick = (item) => {
 	if (!item.routerName) return;
 	gotoRoute({ name: item.routerName });
 };
-const LOGIN_CLIENT = 'Web绔�';
 
 //鐧诲綍
 const openLoginDlg = async () => {
 	// 鍒嗕韩椤典笉闇�瑕�
 	if (isSharePage.value) return;
 	isShowLogin.value = true;
-};
-const handleClose = () => {
-	isShowLogin.value = false;
-};
-const hasSended = computed(() => {
-	return countdown.value !== null;
-});
-const sendCodeMsg = computed(() => {
-	return !hasSended.value ? '鑾峰彇楠岃瘉鐮�' : `${countdown.value} 绉掑悗閲嶈瘯`;
-});
-//鐧诲綍
-const onSubmit = async () => {
-	if (state.activeLoginName === 'accountUser') {
-		//璐︽埛瀵嗙爜鐧诲綍
-		const isValid = await loginFormRef.value.validate().catch(() => {});
-		if (!isValid) return;
-		const res = await PostLogin({
-			user: state.loginForm.account,
-			pass: state.loginForm.pwd,
-			client: LOGIN_CLIENT,
-		});
-		if (!res.json_ok) {
-			return ElMessage.error(res.json_msg);
-		}
-
-		LoginInfo.set(res.hswatersession, state.loginForm.account);
-	} else if (state.activeLoginName === 'phoneUser') {
-		//鎵嬫満鐧诲綍
-		const isValid = await formPhoneRef.value.validate().catch(() => {});
-		if (!isValid) return;
-		const res = await loginMessageUser({
-			phone: state.loginPhoneForm.phoneUser,
-			code: state.loginPhoneForm.verifyCode,
-			client: LOGIN_CLIENT,
-		});
-		if (!res.json_ok) {
-			return ElMessage.error(res.json_msg);
-		}
-		LoginInfo.set(res.hswatersession, state.loginPhoneForm.phoneUser);
-	}
-
-	isShowLogin.value = false;
-	isLoginStatus.value = true;
-	window.location.reload();
 };
 
 const currentRoute = router.currentRoute;
@@ -235,33 +122,7 @@
 		state.isShowExitLogin = false;
 	}
 };
-//鍒囨崲鐢ㄦ埛鐧诲綍椤甸潰
-const handleUserClick = (item) => {
-	state.activeLoginName = item;
-	// formPhoneRef?.value?.resetFields();
-	// loginFormRef.value.resetFields();
-};
-//鑾峰彇楠岃瘉鐮�
-const handleSendVerifyCode = async () => {
-	formPhoneRef.value.validateField('phoneUser', async (valid: boolean) => {
-		if (valid) {
-			const res = await loginVerifyMessage({
-				phone: state.loginPhoneForm.phoneUser,
-			});
-			if (res.json_ok) {
-				countdown.value = 60; //寮�鍚�掕鏃�
-				// 鍊掕鏃堕�昏緫
-				const intervalId = setInterval(() => {
-					if (countdown.value > 0) {
-						countdown.value--;
-					} else {
-						clearInterval(intervalId);
-					}
-				}, 1000);
-			}
-		}
-	});
-};
+
 onMounted(() => {
 	emitter.on('openLoginDlg', () => {
 		if (isShowLogin.value || isLoginStatus.value) return;
@@ -271,7 +132,6 @@
 	emitter.on('logout', () => {
 		logoutClick();
 	});
-
 	document.addEventListener('click', listenClickOtherExit);
 });
 </script>
diff --git a/src/stores/chatRoom.ts b/src/stores/chatRoom.ts
index 2246114..f3040be 100644
--- a/src/stores/chatRoom.ts
+++ b/src/stores/chatRoom.ts
@@ -70,6 +70,8 @@
  */
 export const sectionAList = ref([]);
 export const isShowLogin = ref(false);
+export const isLoginStatus = ref(false);
+
 //#region ====================== 鍏ㄥ眬浣跨敤鏁版嵁 ======================
 // group 鍒楄〃
 export const sceneGroupList = ref([]);
diff --git a/vite.config.ts b/vite.config.ts
index 0b2943c..8721d31 100644
--- a/vite.config.ts
+++ b/vite.config.ts
@@ -41,7 +41,7 @@
 			host: '0.0.0.0',
 			port: env.VITE_PORT as unknown as number,
 			open: JSON.parse(env.VITE_OPEN),
-			hmr: true,
+			hmr: false,
 		},
 		build: {
 			// outDir: 'dist/' + mode.mode,

--
Gitblit v1.9.3