Parcourir la source

飞行学院 后台

husky il y a 5 mois
Parent
commit
daec5492d5

+ 4 - 2
.env.development

@@ -5,9 +5,11 @@ NODE_ENV = development
 VITE_TITLE = 飞行学院
 
 # 接口地址
-VITE_API_BASEURL = http://192.168.1.245:9003
+VITE_API_BASEURL = http://192.168.207.179:9003
+VITE_FILEURL = http://192.168.207.179:10005/education/
+#VITE_API_BASEURL = http://192.168.1.245:9003
 # VITE_API_BASEURL = http://192.168.31.81:19003
-VITE_FILEURL = http://192.168.1.245:10005/education/
+#VITE_FILEURL = http://192.168.1.245:10005/education/
 # VITE_API_BASEURL = http://192.168.31.14:9003
 # VITE_API_BASEURL = http://192.168.31.6:9003
 

+ 4 - 4
.env.production

@@ -5,12 +5,12 @@ NODE_ENV = production
 VITE_TITLE = 飞行学院
 
 # 接口地址
-VITE_API_BASEURL = http://192.168.1.245:19003
-VITE_FILEURL = http://192.168.1.245:10005/education/
+#VITE_API_BASEURL = http://192.168.1.245:19003
+#VITE_FILEURL = http://192.168.1.245:10005/education/
 
 # 22地址
-# VITE_API_BASEURL = http://22.120.128.109:19003
-# VITE_FILEURL = http://22.120.128.108:10005/education/
+ VITE_API_BASEURL = http://22.120.128.109:19003
+ VITE_FILEURL = http://22.120.128.108:10005/education/
 
 
 # 本地端口

+ 64 - 55
src/views/auth/login/login.vue

@@ -29,68 +29,70 @@
 						</div>
 						<!--<h2>{{ $t('login.signInTitle') }}</h2>-->
 					</div>
-					<a-tabs v-model:activeKey="activeKey">
-						<a-tab-pane key="userAccount" :tab="$t('login.accountPassword')">
-							<a-form ref="loginForm" :model="ruleForm" :rules="rules">
-								<a-form-item name="account">
+					<a-form ref="loginForm" v-show="activeKey == 'userAccount'" :model="ruleForm" :rules="rules">
+						<a-form-item name="account">
+							<a-input
+								v-model:value="ruleForm.account"
+								:placeholder="$t('login.accountPlaceholder')"
+								size="large"
+								@keyup.enter="login"
+							>
+								<template #prefix>
+									<UserOutlined class="login-icon-gray" />
+								</template>
+							</a-input>
+						</a-form-item>
+						<a-form-item name="password">
+							<a-input-password
+								v-model:value="ruleForm.password"
+								:placeholder="$t('login.PWPlaceholder')"
+								size="large"
+								autocomplete="off"
+								@keyup.enter="login"
+							>
+								<template #prefix>
+									<LockOutlined class="login-icon-gray" />
+								</template>
+							</a-input-password>
+						</a-form-item>
+						<a-form-item name="validCode" v-if="captchaOpen === 'true'">
+							<a-row :gutter="8">
+								<a-col :span="17">
 									<a-input
-										v-model:value="ruleForm.account"
-										:placeholder="$t('login.accountPlaceholder')"
+										v-model:value="ruleForm.validCode"
+										:placeholder="$t('login.validLaceholder')"
 										size="large"
 										@keyup.enter="login"
 									>
 										<template #prefix>
-											<UserOutlined class="login-icon-gray" />
+											<verified-outlined class="login-icon-gray" />
 										</template>
 									</a-input>
-								</a-form-item>
-								<a-form-item name="password">
-									<a-input-password
-										v-model:value="ruleForm.password"
-										:placeholder="$t('login.PWPlaceholder')"
-										size="large"
-										autocomplete="off"
-										@keyup.enter="login"
-									>
-										<template #prefix>
-											<LockOutlined class="login-icon-gray" />
-										</template>
-									</a-input-password>
-								</a-form-item>
-								<a-form-item name="validCode" v-if="captchaOpen === 'true'">
-									<a-row :gutter="8">
-										<a-col :span="17">
-											<a-input
-												v-model:value="ruleForm.validCode"
-												:placeholder="$t('login.validLaceholder')"
-												size="large"
-												@keyup.enter="login"
-											>
-												<template #prefix>
-													<verified-outlined class="login-icon-gray" />
-												</template>
-											</a-input>
-										</a-col>
-										<a-col :span="7">
-											<img :src="validCodeBase64" class="login-validCode-img" @click="loginCaptcha" />
-										</a-col>
-									</a-row>
-								</a-form-item>
+								</a-col>
+								<a-col :span="7">
+									<img :src="validCodeBase64" class="login-validCode-img" @click="loginCaptcha" />
+								</a-col>
+							</a-row>
+						</a-form-item>
 
-								<!-- <a-form-item>
-									<a href="/findpwd" style="color: #0d84ff">{{ $t('login.forgetPassword') }}?</a>
-								</a-form-item> -->
-								<a-form-item>
-									<a-button type="primary" class="w-full" :loading="loading" round size="large" @click="login"
-										>{{ $t('login.signIn') }}
-									</a-button>
-								</a-form-item>
-							</a-form>
-						</a-tab-pane>
-						<!-- <a-tab-pane key="userSms" :tab="$t('login.phoneSms')" force-render>
-							<phone-login-form />
-						</a-tab-pane> -->
-					</a-tabs>
+						<!-- <a-form-item>
+							<a href="/findpwd" style="color: #0d84ff">{{ $t('login.forgetPassword') }}?</a>
+						</a-form-item> -->
+						<a-form-item>
+							<a-button type="primary" class="w-full" :loading="loading" round size="large" @click="login"
+							>{{ $t('login.signIn') }}
+							</a-button>
+						</a-form-item>
+					</a-form>
+					<Restlogin ref="restlogin" v-show="activeKey == 'restPass'"/>
+<!--					<a-tabs v-model:activeKey="activeKey">-->
+<!--						<a-tab-pane key="userAccount" :tab="$t('login.accountPassword')">-->
+<!--							-->
+<!--						</a-tab-pane>-->
+<!--						&lt;!&ndash; <a-tab-pane key="userSms" :tab="$t('login.phoneSms')" force-render>-->
+<!--							<phone-login-form />-->
+<!--						</a-tab-pane> &ndash;&gt;-->
+<!--					</a-tabs>-->
 					<!-- <three-login /> -->
 				</a-card>
 			</div>
@@ -100,6 +102,7 @@
 
 <script>
 	import loginApi from '@/api/auth/loginApi'
+	import Restlogin from './restlogin.vue'
 	import phoneLoginForm from './phoneLoginForm.vue'
 	// import threeLogin from './threeLogin.vue'
 	import smCrypto from '@/utils/smCrypto'
@@ -116,6 +119,7 @@
 		components: {
 			// phoneLoginForm
 			// threeLogin
+			Restlogin
 		},
 		data() {
 			return {
@@ -219,7 +223,12 @@
 					// 获取token
 					try {
 						const loginToken = await loginApi.login(loginData)
-						afterLogin(loginToken)
+						afterLogin(loginToken,()=>{
+							this.activeKey = 'restPass'
+							this.$nextTick(() => {
+								this.$refs.restlogin.setData(loginToken)
+							})
+						})
 					} catch (err) {
 						this.loading = false
 						this.loginCaptcha()

+ 210 - 0
src/views/auth/login/restlogin.vue

@@ -0,0 +1,210 @@
+<template>
+	<div >
+		<a-form ref="loginForm" :model="ruleForm" :rules="rules">
+<!--			<a-form-item name="account">-->
+<!--				<a-input-->
+<!--					v-model:value="ruleForm.account"-->
+<!--					:placeholder="$t('login.accountPlaceholder')"-->
+<!--					size="large"-->
+<!--					@keyup.enter="login"-->
+<!--				>-->
+<!--					<template #prefix>-->
+<!--						<UserOutlined class="login-icon-gray" />-->
+<!--					</template>-->
+<!--				</a-input>-->
+<!--			</a-form-item>-->
+			<span style="margin-bottom: 20px;  color: red">密码已过期请输入新密码</span>
+			<a-form-item name="password">
+				<a-input-password
+					v-model:value="ruleForm.password"
+					placeholder="请输入新密码"
+					size="large"
+					autocomplete="off"
+					@keyup.enter="login"
+				>
+					<template #prefix>
+						<LockOutlined class="login-icon-gray" />
+					</template>
+				</a-input-password>
+			</a-form-item>
+			<a-form-item name="newPassword">
+				<a-input-password
+					v-model:value="ruleForm.newPassword"
+					placeholder="请再次输入新密码"
+					size="large"
+					autocomplete="off"
+					@keyup.enter="login"
+				>
+					<template #prefix>
+						<LockOutlined class="login-icon-gray" />
+					</template>
+				</a-input-password>
+			</a-form-item>
+
+
+			<a-form-item>
+				<a-button type="primary" class="w-full" :loading="loading" round size="large" @click="login"
+				>{{ $t('login.signIn') }}
+				</a-button>
+			</a-form-item>
+		</a-form>
+	</div>
+</template>
+
+<script>
+	import loginApi from '@/api/auth/loginApi'
+	import phoneLoginForm from './phoneLoginForm.vue'
+	import threeLogin from './threeLogin.vue'
+	import smCrypto from '@/utils/smCrypto'
+	import { required } from '@/utils/formRules'
+	import { afterLogin } from './util'
+	import config from '@/config'
+	import configApi from '@/api/dev/configApi'
+	import tool from '@/utils/tool'
+	import { globalStore, iframeStore, keepAliveStore, viewTagsStore } from '@/store'
+	import { mapActions, mapState } from 'pinia'
+	import {message} from "ant-design-vue";
+	import userCenterApi from '@/api/sys/userCenterApi'
+
+	export default {
+		name: 'Login',
+		components: {
+			phoneLoginForm,
+			threeLogin
+		},
+		data() {
+			return {
+				token : '',
+				activeKey: 'userAccount',
+				captchaOpen: config.SYS_BASE_CONFIG.SNOWY_SYS_DEFAULT_CAPTCHA_OPEN,
+				validCodeBase64: '',
+				ruleForm: {
+					account: '',
+					password: '',
+					newPassword: '',
+					validCode: '',
+					validCodeReqNo: '',
+					autologin: false,
+					eduIdentity: '0'
+				},
+				rules: {
+					// account: [required(this.$t('login.accountError'), 'blur')],
+					password: [required(this.$t('login.PWError'), 'blur')],
+					reestpassword: [required(this.$t('login.PWError'), 'blur')]
+				},
+				loading: false,
+				config: {
+					lang: tool.data.get('APP_LANG') || this.$CONFIG.LANG,
+					theme: tool.data.get('APP_THEME') || 'default'
+				},
+				lang: [
+					{
+						name: '简体中文',
+						value: 'zh-cn'
+					},
+					{
+						name: 'English',
+						value: 'en'
+					}
+				]
+			}
+		},
+		computed: {
+			...mapState(globalStore, ['sysBaseConfig']),
+		},
+		watch: {
+			'config.theme': function (val) {
+				document.body.setAttribute('data-theme', val)
+			},
+			'config.lang': function (val) {
+				this.$i18n.locale = val
+				tool.data.set('APP_LANG', val)
+			}
+		},
+		created() {
+			this.clearViewTags()
+			this.clearKeepLive()
+			this.clearIframeList()
+		},
+		mounted() {
+			let formData = ref(config.SYS_BASE_CONFIG)
+			configApi.configSysBaseList().then((data) => {
+				if (data) {
+					data.forEach((item) => {
+						formData.value[item.configKey] = item.configValue
+					})
+					this.captchaOpen = formData.value.SNOWY_SYS_DEFAULT_CAPTCHA_OPEN
+					tool.data.set('SNOWY_SYS_BASE_CONFIG', formData.value)
+					this.setSysBaseConfig(formData.value)
+					this.refreshSwitch()
+				}
+			})
+		},
+		methods: {
+			...mapActions(keepAliveStore, ['clearKeepLive']),
+			...mapActions(viewTagsStore, ['clearViewTags']),
+			...mapActions(iframeStore, ['clearIframeList']),
+			...mapActions(globalStore, ['setSysBaseConfig']),
+			// 通过开关加载内容
+			refreshSwitch() {
+				// 判断是否开启验证码
+				if (this.captchaOpen === 'true') {
+					// 加载验证码
+					this.loginCaptcha()
+					// 加入校验
+					this.rules.validCode = [required(this.$t('login.validError'), 'blur')]
+				}
+			},
+			// 获取验证码
+			loginCaptcha() {
+				loginApi.getPicCaptcha().then((data) => {
+					this.validCodeBase64 = data.validCodeBase64
+					this.ruleForm.validCodeReqNo = data.validCodeReqNo
+				})
+			},
+			// 用户名密码登录
+			async login() {
+				this.$refs.loginForm.validate().then(async () => {
+					this.loading = true
+					const loginData = {
+						// account: this.ruleForm.account,
+						// 密码进行SM2加密,传输过程中看到的只有密文,后端存储使用hash
+						password: this.ruleForm.password,
+						newPassword: this.ruleForm.newPassword,
+						// validCode: this.ruleForm.validCode,
+						// validCodeReqNo: this.ruleForm.validCodeReqNo,
+						// eduIdentity: this.ruleForm.eduIdentity
+					}
+					if(loginData.password != loginData.newPassword){
+						message.error('两个密码不一致');
+						return
+					}
+					tool.data.set('TOKEN', this.token)
+					tool.cookie.set('Token', this.token)
+					let res = await userCenterApi.userUpdatePassword(loginData)
+					console.log('修改你密码',res)
+					afterLogin(this.token)
+					this.loading = false
+					// // 获取token
+					// try {
+					// 	const loginToken = await loginApi.login(loginData)
+					// 	afterLogin(loginToken)
+					// } catch (err) {
+					// 	this.loading = false
+					// 	this.loginCaptcha()
+					// }
+				})
+			},
+			configLang(key) {
+				this.config.lang = key
+			},
+			setData(token){
+				this.token = token
+			}
+		}
+	}
+</script>
+
+<style lang="less">
+	@import 'login';
+</style>

+ 44 - 33
src/views/auth/login/util.js

@@ -7,7 +7,7 @@ import { message } from 'ant-design-vue'
 import { useGlobalStore, useMyResourceStore } from '@/store'
 import routerUtil from '@/utils/routerUtil'
 
-export const afterLogin = async (loginToken) => {
+export const afterLogin = async (loginToken,callBack) => {
 	tool.data.set('TOKEN', loginToken)
 	//cookie里添加 token
 	tool.cookie.set('Token', loginToken)
@@ -15,41 +15,52 @@ export const afterLogin = async (loginToken) => {
 	const loginUser = await loginApi.getLoginUser()
 	const globalStore = useGlobalStore()
 	const myResourceStore = useMyResourceStore()
-	globalStore.setUserInfo(loginUser)
-	myResourceStore.getUserInfo()
-	tool.data.set('USER_INFO', loginUser)
 
-	// 获取用户的菜单
-	const menu = await userCenterApi.userLoginMenu()
-	let indexMenu = routerUtil.getIndexMenu(menu).path
-	tool.data.set('MENU', menu)
-	// 重置系统默认应用
-	tool.data.set('SNOWY_MENU_MODULE_ID', menu[0].id)
-	message.success('登录成功')
-	if (!!tool.data.get('LAST_VIEWS_PATH')) {
-		// 如果有缓存,将其登录跳转到最后访问的路由
-		indexMenu = tool.data.get('LAST_VIEWS_PATH')
-	}
-	// 如果存在退出后换新账号登录,进行重新匹配,匹配无果则默认首页
-	if (menu) {
-		let routerTag = 0
-		menu.forEach((item) => {
-			if (item.children) {
-				if (JSON.stringify(item.children).indexOf(indexMenu) > -1) {
-					routerTag++
+	if(loginUser.expired == 1 && callBack){
+		tool.data.remove('TOKEN', loginToken)
+		tool.cookie.remove('Token', loginToken)
+		message.error('密码已过期')
+		callBack()
+	}else{
+
+		globalStore.setUserInfo(loginUser)
+		myResourceStore.getUserInfo()
+		tool.data.set('USER_INFO', loginUser)
+
+		// 获取用户的菜单
+		const menu = await userCenterApi.userLoginMenu()
+		let indexMenu = routerUtil.getIndexMenu(menu).path
+		tool.data.set('MENU', menu)
+		// 重置系统默认应用
+		tool.data.set('SNOWY_MENU_MODULE_ID', menu[0].id)
+		message.success('登录成功')
+		if (!!tool.data.get('LAST_VIEWS_PATH')) {
+			// 如果有缓存,将其登录跳转到最后访问的路由
+			indexMenu = tool.data.get('LAST_VIEWS_PATH')
+		}
+		// 如果存在退出后换新账号登录,进行重新匹配,匹配无果则默认首页
+		if (menu) {
+			let routerTag = 0
+			menu.forEach((item) => {
+				if (item.children) {
+					if (JSON.stringify(item.children).indexOf(indexMenu) > -1) {
+						routerTag++
+					}
 				}
+			})
+			if (routerTag === 0) {
+				// 取首页
+				indexMenu = routerUtil.getIndexMenu(menu).path
 			}
-		})
-		if (routerTag === 0) {
-			// 取首页
-			indexMenu = routerUtil.getIndexMenu(menu).path
 		}
+		dictApi.dictTree().then((data) => {
+			// 设置字典到store中
+			tool.data.set('DICT_TYPE_TREE_DATA', data)
+		})
+		await router.replace({
+			path: indexMenu
+		})
 	}
-	dictApi.dictTree().then((data) => {
-		// 设置字典到store中
-		tool.data.set('DICT_TYPE_TREE_DATA', data)
-	})
-	await router.replace({
-		path: indexMenu
-	})
 }
+
+

+ 1 - 1
src/views/statisticalAnalysis/analysisLearningBehaviors/index.vue

@@ -73,7 +73,7 @@
 					<div class="stat-label">总观看时长</div>
 					<div class="stat-number">{{ collegeStats.avgStayTime }}</div>
 					<div class="stat-label">平均时长</div>
-					<div class="stat-number">{{ collegeStats.peakWatchUserCount ? peakWatchUserCount.toLocaleString() : '0' }}</div>
+					<div class="stat-number">{{ collegeStats.peakWatchUserCount ? collegeStats.peakWatchUserCount : '0' }}</div>
 					<div class="stat-label">峰值观看人数</div>
 				</div>
 			</div>