Commit 0ec38cbef3c2641681a6bb72806f7a945a0f7c2e

Authored by 徐振旌
1 parent 2c62a85d

1、新增前端登陆、新增条件查询

public/config.js
1 const BaseUrl = { 1 const BaseUrl = {
2 - URL: "http://127.0.0.1:8080/" 2 + URL: "http://127.0.0.1:8085/"
3 } 3 }
4 export default BaseUrl; 4 export default BaseUrl;
src/App.vue
1 <script setup> 1 <script setup>
2 import { RouterLink, RouterView } from 'vue-router' 2 import { RouterLink, RouterView } from 'vue-router'
  3 +import {onMounted} from "vue";
3 4
  5 +onMounted(() => {
  6 + window.addEventListener('beforeunload', () => {
  7 + sessionStorage.removeItem('isAuthenticated')
  8 + })
  9 +
  10 +
  11 +})
4 </script> 12 </script>
5 13
6 <template> 14 <template>
@@ -19,25 +27,6 @@ import { RouterLink, RouterView } from &#39;vue-router&#39; @@ -19,25 +27,6 @@ import { RouterLink, RouterView } from &#39;vue-router&#39;
19 </div> 27 </div>
20 </header> --> 28 </header> -->
21 29
22 - <el-menu  
23 - default-active="1"  
24 - class="el-menu-demo"  
25 - mode="horizontal"  
26 - background-color="#545c64"  
27 - text-color="#fff"  
28 - active-text-color="#ffd04b"  
29 -  
30 - >  
31 - <!-- <el-menu-item index="1">  
32 - <RouterLink to="/">主页</RouterLink>  
33 - </el-menu-item> -->  
34 - <!-- <el-menu-item index="2">  
35 - <RouterLink to="/login.html">登录</RouterLink>  
36 - </el-menu-item> -->  
37 -  
38 -  
39 - </el-menu>  
40 -  
41 30
42 <RouterView /> 31 <RouterView />
43 </template> 32 </template>
@@ -45,3 +34,4 @@ import { RouterLink, RouterView } from &#39;vue-router&#39; @@ -45,3 +34,4 @@ import { RouterLink, RouterView } from &#39;vue-router&#39;
45 <style scoped> 34 <style scoped>
46 35
47 </style> 36 </style>
  37 +
src/api/api.js
@@ -16,3 +16,17 @@ export const deleteSNsApi = { @@ -16,3 +16,17 @@ export const deleteSNsApi = {
16 url: baseUrl + '/sn/delete_sn' 16 url: baseUrl + '/sn/delete_sn'
17 } 17 }
18 18
  19 +export const getSNsByConditionApi = {
  20 + method: 'post',
  21 + url: baseUrl + '/sn/get_by_condition_sn'
  22 +}
  23 +
  24 +export const listProjectSelectApi = {
  25 + method: 'post',
  26 + url: baseUrl + '/sn/list_product_select'
  27 +}
  28 +
  29 +export const loginApi = {
  30 + method: 'post',
  31 + url: baseUrl + '/auth/login'
  32 +}
src/main.js
1 // import './assets/main.css' 1 // import './assets/main.css'
2 2
3 -import { createApp } from 'vue' 3 +import {createApp} from 'vue'
4 import App from './App.vue' 4 import App from './App.vue'
5 import router from './router' 5 import router from './router'
6 import ElementPlus from 'element-plus' 6 import ElementPlus from 'element-plus'
src/router/index.js
1 import { createRouter, createWebHistory } from 'vue-router' 1 import { createRouter, createWebHistory } from 'vue-router'
2 import HomeView from '../views/HomeView.vue' 2 import HomeView from '../views/HomeView.vue'
  3 +import Login from "../views/Login.vue";
3 4
4 const router = createRouter({ 5 const router = createRouter({
5 history: createWebHistory(import.meta.env.BASE_URL), 6 history: createWebHistory(import.meta.env.BASE_URL),
@@ -9,17 +10,44 @@ const router = createRouter({ @@ -9,17 +10,44 @@ const router = createRouter({
9 name: 'home', 10 name: 'home',
10 component: HomeView, 11 component: HomeView,
11 meta: { 12 meta: {
12 - title: 'SN管理' 13 + title: 'SN管理',
  14 + requiresAuth: true // 添加这行,标记该路由需要认证
  15 + }
  16 +
  17 + },
  18 + {
  19 + path: '/login',
  20 + name: 'Login',
  21 + component: Login,
  22 + meta: {
  23 + requiresAuth: false // 明确表示登录页不需要认证
13 } 24 }
14 } 25 }
15 ] 26 ]
16 }) 27 })
17 28
18 -router.beforeEach((to,from,next)=>{//beforeEach是router的钩子函数,在进入路由前执行  
19 - if(to.meta.title){//判断是否有标题  
20 - document.title = to.meta.title 29 +// 路由守卫
  30 +router.beforeEach((to, from, next) => {
  31 + const isAuthenticated = sessionStorage.getItem('isAuthenticated')
  32 +
  33 + if (to.path === '/login' && !isAuthenticated) {
  34 + return next('/login')
  35 + }
  36 +
  37 + // 需要认证但未登录 → 跳转登录页
  38 + if (to.meta.requiresAuth && !isAuthenticated) {
  39 + return next('/login')
21 } 40 }
22 - next() //执行进入路由,如果不写就不会进入目标页 41 +
  42 + // 已登录但访问登录页 → 跳转首页
  43 + if (to.path === '/login' && isAuthenticated) {
  44 + return next('/')
  45 + }
  46 +
  47 +
  48 +
  49 + next()
23 }) 50 })
24 51
  52 +
25 export default router 53 export default router
src/views/HomeView.vue
@@ -3,39 +3,108 @@ @@ -3,39 +3,108 @@
3 // import { FormInstance } from 'element-plus' 3 // import { FormInstance } from 'element-plus'
4 import axios from 'axios'; 4 import axios from 'axios';
5 import { ElMessage } from 'element-plus' 5 import { ElMessage } from 'element-plus'
6 - import { addSNsApi, getSNsApi, deleteSNsApi } from '../api/api'; 6 + import {addSNsApi, getSNsApi, deleteSNsApi, getSNsByConditionApi , listProjectSelectApi} from '../api/api';
7 7
8 const addFormRef = ref() 8 const addFormRef = ref()
9 const deleteFormRef = ref() 9 const deleteFormRef = ref()
  10 + const conditionFormRef = ref()
10 11
11 //获取的SN内容 12 //获取的SN内容
12 - const SNsContent = ref('...') 13 + const SNsContent = ref('')
13 14
14 //当前显示的表单 1-添加SN 2-获取SN 3-删除SN 15 //当前显示的表单 1-添加SN 2-获取SN 3-删除SN
15 const currForm = ref('1'); 16 const currForm = ref('1');
  17 +
  18 + // 条件查询表单
  19 + const conditionForm = reactive({
  20 + projectName: '',
  21 + sns: ''
  22 + })
  23 +
16 const changeForm = (tab, event) => { 24 const changeForm = (tab, event) => {
17 currForm.value = tab.props.name; 25 currForm.value = tab.props.name;
18 - //把SN数据查出来  
19 - if (currForm.value == 3) {  
20 - axios({  
21 - method: getSNsApi.method,  
22 - url: getSNsApi.url  
23 - }).then(response => {  
24 - if (response.data.code == 200) {  
25 - SNsContent.value = response.data.data; 26 + if (currForm.value === '3') {
  27 + fetchProjectOptions()
  28 + }
  29 + // //把SN数据查出来
  30 + // if (currForm.value == 3) {
  31 + // axios({
  32 + // method: getSNsApi.method,
  33 + // url: getSNsApi.url
  34 + // }).then(response => {
  35 + // if (response.data.code == 200) {
  36 + // SNsContent.value = response.data.data;
  37 + //
  38 + // } else {
  39 + // ElMessage({
  40 + // message: response.data.message,
  41 + // type: 'error',
  42 + // })
  43 + // }
  44 + //
  45 + // }).catch(err => {
  46 + // ElMessage.error(err)
  47 + // })
  48 + // }
  49 + //
  50 + }
26 51
27 - } else {  
28 - ElMessage({  
29 - message: response.data.message,  
30 - type: 'error',  
31 - })  
32 - } 52 + // 项目名称下拉选项
  53 + const projectOptions = ref([])
  54 + const loadingProjects = ref(false)
33 55
34 - }).catch(err => {  
35 - ElMessage.error(err) 56 + // 获取项目名称下拉列表
  57 + const fetchProjectOptions = async () => {
  58 + try {
  59 + loadingProjects.value = true
  60 + const response = await axios({
  61 + method: listProjectSelectApi.method,
  62 + url: listProjectSelectApi.url
36 }) 63 })
  64 + if (response.data.code === 200) {
  65 + projectOptions.value = response.data.data || []
  66 + }
  67 + } catch (err) {
  68 + ElMessage.error('获取项目列表失败')
  69 + } finally {
  70 + loadingProjects.value = false
37 } 71 }
38 - 72 + }
  73 +
  74 +
  75 + // 提交条件查询
  76 + const submitConditionForm = async (formInstance) => {
  77 + if (!formInstance) return
  78 +
  79 + try {
  80 + await formInstance.validate()
  81 + const response = await axios({
  82 + method: getSNsByConditionApi.method,
  83 + url: getSNsByConditionApi.url,
  84 + data: {
  85 + projectName: conditionForm.projectName,
  86 + sns: conditionForm.sns
  87 + }
  88 + })
  89 +
  90 + if (response.data.code === 200) {
  91 + SNsContent.value = response.data.data
  92 + ElMessage.success('查询成功')
  93 + } else {
  94 + ElMessage.error(response.data.message || '查询失败')
  95 + }
  96 + } catch (err) {
  97 + if (err.name !== 'Error') { // 不是表单验证错误
  98 + ElMessage.error(err.message || '查询异常')
  99 + }
  100 + }
  101 + }
  102 +
  103 + // 重置条件表单
  104 + const resetConditionForm = (formInstance) => {
  105 + if (!formInstance) return
  106 + formInstance.resetFields()
  107 + SNsContent.value = '...'
39 } 108 }
40 109
41 110
@@ -272,14 +341,70 @@ @@ -272,14 +341,70 @@
272 </el-form-item> 341 </el-form-item>
273 </el-form> 342 </el-form>
274 343
275 - <el-text class="mx-1" v-show="currForm == 3? true : false">  
276 - {{ SNsContent }}  
277 - </el-text>  
278 -  
279 - 344 +<!-- <el-text class="mx-1" v-show="currForm == 3? true : false">-->
  345 +<!-- {{ SNsContent }}-->
  346 +<!-- </el-text>-->
  347 +
  348 + <!-- 条件查询表单 -->
  349 + <el-form
  350 + ref="conditionFormRef"
  351 + style="max-width: 600px"
  352 + :model="conditionForm"
  353 + label-width="auto"
  354 + class="demo-dynamic"
  355 + v-show="currForm == 3"
  356 + >
  357 + <el-form-item
  358 + prop="projectName"
  359 + label="项目名称"
  360 + >
  361 + <el-select
  362 + v-model="conditionForm.projectName"
  363 + filterable
  364 + clearable
  365 + placeholder="请选择或输入项目名称"
  366 + :loading="loadingProjects"
  367 + style="width: 100%"
  368 + >
  369 + <el-option
  370 + v-for="item in projectOptions"
  371 + :key="item"
  372 + :label="item"
  373 + :value="item"
  374 + />
  375 + </el-select>
  376 + </el-form-item>
  377 +
  378 + <el-form-item
  379 + prop="sns"
  380 + label="设备码"
  381 + >
  382 + <el-input v-model="conditionForm.sns" placeholder="输入设备码" />
  383 + </el-form-item>
  384 +
  385 + <el-form-item>
  386 + <el-button type="primary" @click="submitConditionForm(conditionFormRef)">查询</el-button>
  387 + <el-button @click="resetConditionForm(conditionFormRef)">重置</el-button>
  388 + </el-form-item>
  389 + </el-form>
  390 +
  391 + <!-- 查询结果显示 -->
  392 + <div v-show="currForm == 3" style="margin-top: 20px;">
  393 + <el-card>
  394 + <template #header>
  395 + <div class="card-header">
  396 + <span>查询结果</span>
  397 + </div>
  398 + </template>
  399 + <el-text class="mx-1">
  400 + <pre>{{ SNsContent }}</pre>
  401 + </el-text>
  402 + </el-card>
  403 + </div>
  404 +
280 </el-tabs> 405 </el-tabs>
281 406
282 - 407 +
283 408
284 </div> 409 </div>
285 410
@@ -291,6 +416,15 @@ @@ -291,6 +416,15 @@
291 margin: 0px auto; 416 margin: 0px auto;
292 } 417 }
293 418
  419 + .card-header {
  420 + font-weight: bold;
  421 + }
  422 +
  423 + pre {
  424 + white-space: pre-wrap;
  425 + word-wrap: break-word;
  426 + }
  427 +
294 </style> 428 </style>
295 429
296 430
src/views/Login.vue 0 → 100644
  1 +<script setup>
  2 +import { ref, reactive } from 'vue'
  3 +import { useRouter } from 'vue-router'
  4 +import axios from 'axios'
  5 +import { ElMessage } from 'element-plus'
  6 +import { loginApi } from '../api/api'
  7 +
  8 +const router = useRouter()
  9 +
  10 +const loginFormRef = ref()
  11 +const loading = ref(false)
  12 +
  13 +const loginForm = reactive({
  14 + username: '',
  15 + password: ''
  16 +})
  17 +
  18 +const rules = reactive({
  19 + username: [{ required: true, message: '请输入用户名', trigger: 'blur' }],
  20 + password: [{ required: true, message: '请输入密码', trigger: 'blur' }]
  21 +})
  22 +
  23 +const submitLogin = async () => {
  24 + try {
  25 + loading.value = true
  26 + await loginFormRef.value.validate()
  27 +
  28 + const response = await axios({
  29 + method: loginApi.method,
  30 + url: loginApi.url,
  31 + data: {
  32 + username: loginForm.username,
  33 + password: loginForm.password
  34 + }
  35 + })
  36 +
  37 + if (response.data.code === 200) {
  38 + ElMessage.success('登录成功')
  39 + // 存储登录状态
  40 + sessionStorage.setItem('isAuthenticated', 'true')
  41 + // 跳转到首页
  42 + router.push('/')
  43 + } else {
  44 + ElMessage.error(response.data.message || '登录失败')
  45 + }
  46 + } catch (error) {
  47 + ElMessage.error(error.message || '登录异常')
  48 + } finally {
  49 + loading.value = false
  50 + }
  51 +}
  52 +</script>
  53 +
  54 +<template>
  55 + <div class="login-container">
  56 + <el-card class="login-card">
  57 + <h2 class="login-title">SN系统登陆</h2>
  58 + <el-form
  59 + ref="loginFormRef"
  60 + :model="loginForm"
  61 + :rules="rules"
  62 + label-width="80px"
  63 + label-position="top"
  64 + >
  65 + <el-form-item label="用户名" prop="username">
  66 + <el-input v-model="loginForm.username" placeholder="" />
  67 + </el-form-item>
  68 + <el-form-item label="密码" prop="password">
  69 + <el-input
  70 + v-model="loginForm.password"
  71 + type="password"
  72 + placeholder=""
  73 + show-password
  74 + />
  75 + </el-form-item>
  76 + <el-form-item>
  77 + <el-button
  78 + type="primary"
  79 + @click="submitLogin"
  80 + :loading="loading"
  81 + style="width: 100%"
  82 + >
  83 + 登录
  84 + </el-button>
  85 + </el-form-item>
  86 + </el-form>
  87 + </el-card>
  88 + </div>
  89 +</template>
  90 +
  91 +<style scoped>
  92 +.login-container {
  93 + display: flex;
  94 + justify-content: center;
  95 + align-items: center;
  96 + height: 100vh;
  97 + background-color: #f0f2f5;
  98 +}
  99 +
  100 +.login-card {
  101 + width: 400px;
  102 + padding: 20px;
  103 + border-radius: 8px;
  104 + box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
  105 +}
  106 +
  107 +.login-title {
  108 + text-align: center;
  109 + margin-bottom: 20px;
  110 + color: #333;
  111 +}
  112 +</style>
0 \ No newline at end of file 113 \ No newline at end of file