对接接口 登录

main
JayChou 3 weeks ago
parent 18a5adc925
commit e054022c55
  1. 4
      .env.development
  2. 1
      package.json
  3. 3
      pnpm-lock.yaml
  4. 12
      src/api/index.ts
  5. 8
      src/layout/index.vue
  6. 481
      src/layout/loginPage.vue
  7. 2
      src/main.ts
  8. 23
      src/permissions.ts
  9. 25
      src/store/modules/user.ts
  10. 2
      src/utils/auth.ts
  11. 41
      src/utils/request.ts
  12. 2
      src/views/largeDataScreen/home.vue
  13. 2
      src/views/program/components/yibiao.vue
  14. 24
      src/views/program/index.vue

@ -1,4 +1,4 @@
# 变量必须以 VITE_ 为前缀才能暴露给外部读取
NODE_ENV = 'development'
VITE_APP_TITLE = '大屏数据'
VITE_APP_BASE_API = 'http://10.115.6.28:18083/'
VITE_APP_TITLE = '实验仿真'
VITE_APP_BASE_API = '//localhost:16066/jeecg-boot'

@ -18,6 +18,7 @@
"@antv/x6-plugin-stencil": "^2.1.5",
"@antv/x6-plugin-transform": "^2.1.8",
"@antv/x6-vue-shape": "^2.1.2",
"@element-plus/icons-vue": "^2.3.1",
"@kjgl77/datav-vue3": "^1.7.3",
"axios": "^1.7.2",
"echarts": "^5.6.0",

@ -35,6 +35,9 @@ importers:
'@antv/x6-vue-shape':
specifier: ^2.1.2
version: 2.1.2(@antv/x6@2.18.1)(vue@3.4.29(typescript@5.2.2))
'@element-plus/icons-vue':
specifier: ^2.3.1
version: 2.3.1(vue@3.4.29(typescript@5.2.2))
'@kjgl77/datav-vue3':
specifier: ^1.7.3
version: 1.7.3(vue@3.4.29(typescript@5.2.2))

@ -1,2 +1,14 @@
import request from '@/utils/request'
export const login = (data: any) => {
return request({
url: '/sys/login',
method: 'post',
data
})
}
export const getCode = (time: any) => {
return request({
url: '/sys/randomImage/' + time,
})
}

@ -2,7 +2,7 @@
<div class="container-bgc">
<div class="top">
<div class="loginBtn">
<p @click="loginFn">登录/注册</p>
<p @click="loginFn">{{user.token?'已登录':'登录/注册'}}</p>
</div>
<div class="title">{{ setting.title }}</div>
</div>
@ -18,10 +18,13 @@
<script lang="ts" setup>
import { useRouter } from 'vue-router'
const router = useRouter()
// import { onMounted, reactive, ref, toRefs, watch } from "vue";
import settingStore from "@/store/modules/setting";
import userStore from '@/store/modules/user';
const user = userStore();
const setting = settingStore();
const router = useRouter()
console.log(setting.title);
const loginFn=()=>{
router.push('/login')
@ -67,6 +70,7 @@ const loginFn=()=>{
line-height: 37px;
background: linear-gradient(to bottom, #08B9C1, #0758B8);
transform: skew(-30deg);
cursor: pointer;
/* 在X轴方向倾斜 -35 度 */
border-radius: 5%;
p{

@ -1,217 +1,340 @@
<template>
<div class="login_container">
<div class="top">
<div class="title">{{ setting.title }}</div>
</div>
<div class="main-content">
<el-row style="display: flex; justify-content: center;">
<el-col>
<el-form :rules="rules" :model="formModel" ref="formRef" size="large" autocomplete="off"
v-if="isRegister">
<el-form-item prop="username">
<el-input v-model="formModel.username" :prefix-icon="User" placeholder="请输入账号"></el-input>
</el-form-item>
<el-form-item prop="studentNumb">
<el-input v-model="formModel.studentNumb" :prefix-icon="Avatar"
placeholder="请输入学号"></el-input>
</el-form-item>
<el-form-item prop="name">
<el-input v-model="formModel.name" :prefix-icon="Stamp" placeholder="请输入姓名"></el-input>
</el-form-item>
<el-form-item prop="password">
<el-input v-model="formModel.password" :prefix-icon="Lock" type="password"
placeholder="请输入密码"></el-input>
</el-form-item>
<el-form-item prop="repassword">
<el-input v-model="formModel.repassword" :prefix-icon="Lock" type="password"
placeholder="请输入再次密码"></el-input>
</el-form-item>
<el-form-item>
<el-button style="color: #3ad7e2; background-color: #0e2e5e; width: 150px;" class="button"
type="primary" auto-insert-space @click="register">
注册
</el-button>
<el-button style="color: #3ad7e2;background-color: #0e2e5e;width: 150px;" class="button"
type="primary" auto-insert-space @click="isRegister = false">
返回到登录页
</el-button>
</el-form-item>
<el-form-item>
</el-form-item>
<!-- <el-form-item class="flex">
<div class="login_container">
<div class="top">
<div class="title">{{ setting.title }}</div>
</div>
<div class="main-content">
<el-row style="display: flex; justify-content: center">
<el-col>
<el-form
:rules="rules"
:model="formModel"
ref="formRef"
size="large"
autocomplete="off"
v-if="isRegister"
>
<el-form-item prop="username">
<el-input
v-model="formModel.username"
:prefix-icon="User"
placeholder="请输入账号"
></el-input>
</el-form-item>
<el-form-item prop="studentNumb">
<el-input
v-model="formModel.studentNumb"
:prefix-icon="Avatar"
placeholder="请输入学号"
></el-input>
</el-form-item>
<el-form-item prop="name">
<el-input
v-model="formModel.name"
:prefix-icon="Stamp"
placeholder="请输入姓名"
></el-input>
</el-form-item>
<el-form-item prop="password">
<el-input
v-model="formModel.password"
:prefix-icon="Lock"
type="password"
placeholder="请输入密码"
></el-input>
</el-form-item>
<el-form-item prop="repassword">
<el-input
v-model="formModel.repassword"
:prefix-icon="Lock"
type="password"
placeholder="请输入再次密码"
></el-input>
</el-form-item>
<el-form-item>
<el-button
style="color: #3ad7e2; background-color: #0e2e5e; width: 150px"
class="button"
type="primary"
auto-insert-space
@click="register"
>
注册
</el-button>
<el-button
style="color: #3ad7e2; background-color: #0e2e5e; width: 150px"
class="button"
type="primary"
auto-insert-space
@click="isRegister = false"
>
返回到登录页
</el-button>
</el-form-item>
<el-form-item> </el-form-item>
<!-- <el-form-item class="flex">
<el-link type="info" :underline="false" @click="isRegister = false">
返回
</el-link>
</el-form-item> -->
</el-form>
<el-form :model="formModel" :rules="rules" ref="formRef" size="large" autocomplete="off" v-else
class="custom-form">
<el-form-item prop="username">
<div style="display: flex;align-items: center;color: pink; ">
<div class="left" style="display: flex;align-items: center;">
<div style="padding-right: 10px;color: #1084c1;"><el-icon class="bold-icon">
<user />
</el-icon></div>
<div style="padding-right: 10px; color: #2592a1;">用户名</div>
</div>
<div class="right">
<el-input v-model="formModel.username"
style="border-color: #20bec8; background-color: pink;"
placeholder="请输入用户名"></el-input>
</div>
</div>
</el-form-item>
<el-form-item label="学号" prop="studentNumb">
<el-input v-model="formModel.studentNumb" :prefix-icon="Avatar" placeholder="请输入学号"></el-input>
</el-form-item>
<el-form-item label="密码" prop="password">
<el-input name="password" :prefix-icon="Lock" type="password"
placeholder="请输入密码" v-model="formModel.password"></el-input>
</el-form-item>
<el-form-item>
<el-button class="hexagon-button" type="primary" auto-insert-space>登录</el-button>
<el-button class="hexagon-button" type="primary" auto-insert-space
@click="isRegister = true">去注册</el-button>
</el-form-item>
</el-form>
</el-col>
<el-col :span="12" :xs="0"></el-col>
</el-row>
</div>
</el-form>
<el-form
:model="formModel"
:rules="rules"
ref="formRef"
size="large"
autocomplete="off"
v-else
class="custom-form"
>
<el-form-item prop="username">
<div style="display: flex; align-items: center; color: pink">
<div class="left" style="display: flex; align-items: center">
<div style="padding-right: 10px; color: #1084c1">
<el-icon class="bold-icon">
<user />
</el-icon>
</div>
<div style="padding-right: 10px; color: #2592a1">用户名</div>
</div>
<div class="right">
<el-input
v-model="formModel.username"
style="border-color: #20bec8; background-color: pink"
placeholder="请输入用户名"
></el-input>
</div>
</div>
</el-form-item>
<el-form-item label="学号" prop="studentNumb">
<el-input
v-model="formModel.studentNumb"
:prefix-icon="Avatar"
placeholder="请输入学号"
></el-input>
</el-form-item>
<el-form-item label="密码" prop="password">
<el-input
name="password"
:prefix-icon="Lock"
type="password"
placeholder="请输入密码"
v-model="formModel.password"
></el-input>
</el-form-item>
<el-form-item label="验证码">
<div class="captcha">
<el-input
v-model="formModel.captcha"
style="height: 0.2344rem"
maxlength="4"
/>
<div class="code" @click="getcodeinfo">
<img :src="codeUrl" alt="" srcset="" />
</div>
</div>
</el-form-item>
<el-form-item>
<el-button
class="hexagon-button"
type="primary"
auto-insert-space
@click="login"
>登录</el-button
>
<el-button
class="hexagon-button"
type="primary"
auto-insert-space
@click="isRegister = true"
>去注册</el-button
>
</el-form-item>
</el-form>
</el-col>
<el-col :span="12" :xs="0"></el-col>
</el-row>
</div>
</div>
</template>
<script setup lang="ts">
// import { ref } from "vue"
// import { onMounted, reactive, ref, toRefs, watch } from "vue";
import settingStore from "@/store/modules/setting";
import { User, Lock, Avatar, Stamp } from '@element-plus/icons-vue'
import { User, Lock, Avatar, Stamp } from "@element-plus/icons-vue";
import { ref } from "vue";
import userStore from "@/store/modules/user";
import { getCode } from "@/api";
import { useRouter } from "vue-router";
const router = useRouter()
const setting = settingStore();
const user = userStore();
console.log(setting.title);
import { ref } from 'vue'
const isRegister = ref(false)
const formRef=ref()
const isRegister = ref(false);
const formRef = ref();
const formModel = ref({
username: '',
studentNumb: '',
name: '',
password: '',
repassword: ''
})
username: "",
studentNumb: "",
name: "",
password: "",
repassword: "",
captcha: "",
});
//
const rules = {
username: [
{ required: true, message: '请输入用户名', trigger: 'blur' },
{ min: 5, max: 30, message: '用户名长度最小五位最大三十位', trigger: ['change', 'blur'] }
],
studentNumb:[
{ required: true, message: '请输入学号', trigger: 'blur' },
{ min: 5, max: 11, message: '学号长度最小五位最大三十位', trigger: ['change', 'blur'] }
],
name: [
{ required: true, message: '请输入姓名', trigger: 'blur' },
],
password: [
{ required: true, message: '请输入密码', trigger: 'blur' },
{
pattern: /^\S{6,15}$/,
message: '密码长度最小六位最大十五位',
trigger: ['change', 'blur']
}
],
repassword: [
{ required: true, message: '请再次输入密码', trigger: 'blur' },
{
max: 15,
min: 6,
pattern: /^\S{6,15}$/,
message: '密码长度最小六位最大十五位',
trigger: ['change', 'blur']
},
{
validator: (rule, value, callback) => {
if (value !== formModel.value.password) {
callback(new Error('两次输入密码不一致!'))
} else {
callback()
}
},
trigger: 'blur'
username: [
{ required: true, message: "请输入用户名", trigger: "blur" },
{
min: 5,
max: 30,
message: "用户名长度最小五位最大三十位",
trigger: ["change", "blur"],
},
],
studentNumb: [
{ required: true, message: "请输入学号", trigger: "blur" },
{
min: 5,
max: 11,
message: "学号长度最小五位最大三十位",
trigger: ["change", "blur"],
},
],
name: [{ required: true, message: "请输入姓名", trigger: "blur" }],
password: [
{ required: true, message: "请输入密码", trigger: "blur" },
{
pattern: /^\S{6,15}$/,
message: "密码长度最小六位最大十五位",
trigger: ["change", "blur"],
},
],
repassword: [
{ required: true, message: "请再次输入密码", trigger: "blur" },
{
max: 15,
min: 6,
pattern: /^\S{6,15}$/,
message: "密码长度最小六位最大十五位",
trigger: ["change", "blur"],
},
{
validator: (rule, value, callback) => {
if (value !== formModel.value.password) {
callback(new Error("两次输入密码不一致!"));
} else {
callback();
}
],
}
const register=async()=>{
await formRef.value.validate()
console.log('开始注册i请求');
}
},
trigger: "blur",
},
],
};
const register = async () => {
await formRef.value.validate();
console.log("开始注册i请求");
};
const codeUrl = ref("");
const getcodeinfo = async () => {
const res: any = await getCode(1629428467008);
codeUrl.value = res.result;
console.log(codeUrl.value);
};
getcodeinfo();
// import { useRouter } from 'vue-router'
// const router = useRouter()
// const goToPage=()=>{
// router.push('/')
// }
//
const login = async () => {
await formRef.value.validate();
let data = {
captcha: formModel.value.captcha,
checkKey: 1629428467008,
password: formModel.value.password,
username: formModel.value.username,
};
const res = await user.logIn(data);
if(res){
router.push('/')
}
};
</script>
<style lang="less" scoped>
.login_container {
position: relative;
position: relative;
width: 100%;
// height: 1080px;
min-height: 100vh;
background-color: #091d22;
background: url("../assets//images/bg2.png") no-repeat;
background-size: cover;
.top {
width: 100%;
// height: 1080px;
min-height: 100vh;
background-color: #091d22;
background: url("../assets//images/bg2.png") no-repeat;
// height: 75px;
text-align: center;
font-size: 42px;
line-height: 75px;
font-style: italic;
background: url("../assets/images/topbgc.png") no-repeat;
// background-position: center bottom -10px;
background-size: cover;
.top {
width: 100%;
// height: 75px;
text-align: center;
font-size: 42px;
line-height: 75px;
font-style: italic;
background: url("../assets/images/topbgc.png") no-repeat;
// background-position: center bottom -10px;
background-size: cover;
.title {
color: #fff;
}
.title {
color: #fff;
}
}
.main-content {
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
margin: 0;
background: url("../assets/images/login.png") no-repeat;
background-position: center;
}
.main-content {
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
margin: 0;
background: url("../assets/images/login.png") no-repeat;
background-position: center;
}
.captcha {
width: 100%;
height: 100%;
position: relative;
.code {
width: 100%;
height: 100%;
position: absolute;
top: 0;
right: 0;
width: 105px;
height: 100%;
// background-color: pink;
display: flex;
align-items: center;
img {
width: 100%;
height: 100%;
}
}}
}
.hexagon-button {
margin-top: 30px;
/* 应用clip-path属性来创建六边形形状 */
width: 180px;
height: 50px;
/* 使用clip-path定义按钮形状 */
clip-path: polygon(15% 0, 85% 0, 100% 50%, 85% 100%, 15% 100%, 0 50%);
/* 模拟边框效果 */
box-shadow: 0 0 0 2px cyan;
background-color: #14213d;
color: #3ad7e2;
background-color: #0e2e5e;
font-size: 18px;
margin-top: 30px;
/* 应用clip-path属性来创建六边形形状 */
width: 180px;
height: 50px;
/* 使用clip-path定义按钮形状 */
clip-path: polygon(15% 0, 85% 0, 100% 50%, 85% 100%, 15% 100%, 0 50%);
/* 模拟边框效果 */
box-shadow: 0 0 0 2px cyan;
background-color: #14213d;
color: #3ad7e2;
background-color: #0e2e5e;
font-size: 18px;
}
// .custom-form .el-form-item__label {
@ -224,7 +347,7 @@ const register=async()=>{
// stroke-width: 9;
// /* */
// }
.el-form-item__label{
color: #0e2e5e;
.el-form-item__label {
color: #0e2e5e;
}
</style>

@ -1,6 +1,6 @@
import { createApp } from 'vue'
import App from './App.vue'
import router from '@/router'
import router from './permissions'
import '@/styles/index.scss'
import ElementPlus from 'element-plus';
import 'element-plus/dist/index.css'; // 引入 Element Plus 的样式文件

@ -0,0 +1,23 @@
import router from "./router";
import userStore from "./store/modules/user";
import { getToken } from "./utils/auth";
import pinia from "./store";
const store = userStore(pinia);
router.beforeEach((to: any, from: any, next: any) => {
if (to.path === "/login") {
if (store.token) {
next("/");
} else {
next();
}
// next();
} else {
const token = getToken();
if (token) {
next();
} else {
next("/login");
}
}
});
export default router;

@ -1,14 +1,31 @@
import { defineStore } from "pinia";
import { getToken } from "@/utils/auth";
import { getToken,setToken } from "@/utils/auth";
import { login } from "@/api";
import { ElMessage } from "element-plus";
const userStore = defineStore("userStore", {
state: () => ({
token: getToken(),
userInfo: {},
}),
actions: {
async logIn(){
}
async logIn(form: any) {
console.log(form);
const res: any = await login(form);
// if(res.code === 500) return ElMessage.error(res.msg)
if(res.code !== 200) {
ElMessage.error(res.msg)
return false
}
this.token = res.result.token;
this.userInfo = res.result.userInfo;
setToken(this.token);
console.log(res);
return true
},
clearStatus() {
this.token = "";
this.userInfo = {};
},
},
});
export default userStore;

@ -4,7 +4,7 @@ const setToken = (token: string): void => {
};
const getToken = () => localStorage.getItem(TOKEN_KEY) || "";
const removeToken = () => localStorage.removeItem(TOKEN_KEY);
export default {
export {
setToken,
getToken,
removeToken,

@ -1,23 +1,38 @@
// 引入第三方请求库axios
import axios from 'axios'
import axios from "axios";
import pinia from "@/store";
import { ElMessage } from "element-plus";
import userStore from "@/store/modules/user";
// 创建axios实例
const server = axios.create({
baseURL:import.meta.env.VITE_APP_BASE_API,
timeout:10000,
})
baseURL: import.meta.env.VITE_APP_BASE_API,
timeout: 30000,
});
// 创建请求拦截器
server.interceptors.request.use((config) => {
return config
const useuserStore = userStore(pinia);
})
config.headers.Authorization = useuserStore.token;
config.headers["x-access-token"] = useuserStore.token;
return config;
});
// 创建相应拦截器
server.interceptors.response.use((response:any) => {
if(response.status === 200){
return response.data
}
// return response
})
server.interceptors.response.use((response) => {
if (response.data.code === 401) {
const useuserStore = userStore(pinia);
// useuserStore.clearStatus();
// return Promise.reject(response);
}
if (response.data.code === 412) {
ElMessage.error(response.data.message);
return Promise.reject(response);
}
return response.data;
});
// 暴露axios实例
export default server
export default server;

@ -291,7 +291,7 @@ const step = ref<Step>(0);
const popover1 = ref<any>(null);
const popover2 = ref<any>(null);
const dialogVisible = ref<Falg>(false);
const Installation = ref<Falg>(true);
const Installation = ref<Falg>(false);
const installationStep = ref<Step>(1);
const checkList = ref<Step[]>([1, 2]);
const unpack = (): void => {

@ -4,7 +4,7 @@
</div>
</template>
<script setup>
<script setup lang="ts">
import { onMounted, watch } from "vue";
import * as echarts from "echarts";
import settingStore from "@/store/modules/setting";

@ -89,7 +89,7 @@ const falg = ref(false);
let graph: any = null;
const nodeName = ref("");
const csedNode = ref(null);
const csedNode = ref<any>(null);
const operations = [];
onMounted(() => {
preWork();
@ -220,7 +220,7 @@ onMounted(() => {
// ]);
});
graph.on("node:added", ({ node }) => {
graph.on("node:added", ({ node }:any) => {
const data = {
type: "add",
node: node.toJSON(),
@ -229,7 +229,7 @@ onMounted(() => {
saveToLocalStorage(data);
});
graph.on("node:removed", ({ node }) => {
graph.on("node:removed", ({ node }:any) => {
const data = {
type: "remove",
id: node.id,
@ -1029,7 +1029,7 @@ onMounted(() => {
const drawerVisible = ref(false);
//
const selectedNodeData = ref({
const selectedNodeData = ref<any>({
label: "",
width: 0,
height: 0,
@ -1138,7 +1138,7 @@ const onUndo = () => {
const onRedo = () => {
graph.redo();
};
const sdsz = ref(null);
const sdsz = ref<any>(null);
const onSave = () => {
// console.log(graph.toJSON());
graph.toJSON().cells.forEach((item: any) => {
@ -1213,15 +1213,15 @@ const onSave = () => {
};
function hasExactNames(arr: any, names: any) {
// name
const nameList = arr.map((obj) => obj.shape);
const nameList = arr.map((obj:any) => obj.shape);
console.log(
nameList,
names,
names.every((name) => nameList.filter((n) => n === name).length === 1)
names.every((name:any) => nameList.filter((n:any) => n === name).length === 1)
);
// names nameList
return names.every((name) => nameList.filter((n) => n === name).length === 1);
return names.every((name:any) => nameList.filter((n:any) => n === name).length === 1);
}
watch(
() => useSettingStore.qw,
@ -1236,14 +1236,14 @@ watch(
);
const SESSION_KEY = "graph_operations";
function saveToLocalStorage(data) {
const operations = JSON.parse(localStorage.getItem(SESSION_KEY)) || [];
function saveToLocalStorage(data:any) {
const operations = JSON.parse(localStorage.getItem(SESSION_KEY) as string) || [];
operations.push(data);
localStorage.setItem(SESSION_KEY, JSON.stringify(operations));
}
function loadFromLocalStorage() {
return JSON.parse(localStorage.getItem(SESSION_KEY)) || [];
return JSON.parse(localStorage.getItem(SESSION_KEY) as string) || [];
}
function clearLocalStorage() {
@ -1253,7 +1253,7 @@ function clearLocalStorage() {
function restoreGraph() {
const operations = loadFromLocalStorage();
operations.forEach((op) => {
operations.forEach((op:any) => {
if (op.type === "add") {
graph.addNode(op.node);
} else if (op.type === "remove") {

Loading…
Cancel
Save