yzb
yzb 7 months ago
parent 87e7f2841a
commit 31834424d3

24
admin/.gitignore vendored

@ -1,24 +0,0 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
node_modules
dist
dist-ssr
*.local
# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?

@ -1,3 +0,0 @@
{
"recommendations": ["Vue.volar"]
}

@ -1,5 +0,0 @@
# Vue 3 + Vite
This template should help get you started developing with Vue 3 in Vite. The template uses Vue 3 `<script setup>` SFCs, check out the [script setup docs](https://v3.vuejs.org/api/sfc-script-setup.html#sfc-script-setup) to learn more.
Learn more about IDE Support for Vue in the [Vue Docs Scaling up Guide](https://vuejs.org/guide/scaling-up/tooling.html#ide-support).

@ -3,8 +3,8 @@
<el-main style="height: 500px;">
<div>
<el-carousel indicator-position="none" height="450px" autoplay>
<el-carousel-item v-for="item in items" :key="item.id">
<el-carousel indicator-position="none" height="500px" autoplay>
<el-carousel-item v-for="item in items" :key="item.id" style="height: 500px;">
<img :src="item.src" alt="image" style="width: 100%; height: 100%; object-fit: cover;" />
</el-carousel-item>
</el-carousel>
@ -24,7 +24,7 @@
</el-main>
<el-footer>
<div class="news-section">
<!-- <div class="news-section">
<div class="foot">
<h2>用户建议</h2>
<button class="view-all-btn" @click="goToInformation"></button>
@ -38,7 +38,7 @@
</div>
</div>
</div>
</div>
</div> -->
</el-footer>
</el-container>
</template>
@ -73,24 +73,7 @@ const items = [
{ id: 3, src: "/3.png" }
];
const newsList = ref([
{
title: "建议建议建议建议建议建议建议建议...",
image: "f1.png",
},
{
title: "建议建议建议建议建议建议建议建议...",
image: "f1.png",
},
{
title: "建议建议建议建议建议建议建议建议...",
image: "f1.png",
},
{
title: "建议建议建议建议建议建议建议建议...",
image: "f1.png",
},
]);
function goToInformation() {
router.push({ name: 'Information' }); // Use named route
@ -193,4 +176,7 @@ function goToInformation() {
padding: 10px 20px;
font-size: 16px;
}
::-webkit-scrollbar {
display: none;
}
</style>

@ -1,13 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite + Vue</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.js"></script>
</body>
</html>

@ -0,0 +1,201 @@
<template>
<div class="common-layout">
<el-container>
<el-header>
<el-row type="flex" justify="space-between" align="middle" style="min-width: 1440px;">
<div class="title">
<el-menu default-active="1" class="el-menu-horizontal">
<el-text class="logo">ExamSphere</el-text>
</el-menu>
</div>
<div class="user-info">
<img :src="userStore.user.avatar?userStore.user.avatar:user.avatar" v-if="user.avatar||userStore.user.avatar" style="width: 40px;height: 40px;border-radius: 40px;margin-right:10px ;"/>
<el-text class="user-name">{{userStore.user.username?userStore.user.username:user.username}}</el-text>
<button @click="logout" class="exit">退出</button>
</div>
</el-row>
</el-header>
<el-container>
<el-aside width="200px" class="el-aside">
<el-row class="tac">
<el-col>
<el-menu default-active="2" class="el-menu-vertical-demo">
<el-sub-menu index="1">
<template #title>
<el-menu-item class="menu-item-hover">
<el-icon>
<House />
</el-icon>
<span style="color: #cdd1d3;">首页和通知</span>
</el-menu-item>
</template>
<el-menu-item-group style="background-color: #2d2e36;">
<router-link to='/admin/firstpage'>
<el-menu-item index="2-1">首页</el-menu-item>
</router-link>
<router-link to='/admin/notice'>
<el-menu-item index="2-2-1">通知管理</el-menu-item>
</router-link>
</el-menu-item-group>
</el-sub-menu>
<el-sub-menu index="2">
<template #title>
<el-menu-item class="menu-item-hover">
<el-icon>
<location />
</el-icon>
<span style="color: #cdd1d3;">用户管理 </span>
</el-menu-item>
</template>
<el-menu-item-group style="background-color: #2d2e36;">
<router-link to="/admin/student-info">
<el-menu-item index="1-1" style="color: #cdd1d3;">学生管理</el-menu-item>
</router-link>
<router-link to="/admin/teacher-info">
<el-menu-item index="1-2" style="color: #cdd1d3;">教师管理</el-menu-item>
</router-link>
</el-menu-item-group>
</el-sub-menu>
<router-link to="/admin/myinfo">
<el-menu-item index="3">
<el-icon>
<document />
</el-icon>
<span style="color: #cdd1d3;">我的资料</span>
</el-menu-item>
</router-link>
<router-link to="/admin/information">
<el-menu-item index="4">
<el-icon><icon-menu /></el-icon>
<span style="color: #cdd1d3;">用户反馈与建议</span>
</el-menu-item>
</router-link>
</el-menu>
</el-col>
</el-row>
</el-aside>
<el-main>
<router-view></router-view>
</el-main>
</el-container>
</el-container>
</div>
</template>
<script setup>
import { ElMessage } from 'element-plus';
import { onMounted, reactive,ref,watch } from 'vue';
import { useRouter } from 'vue-router';
import request from '../../request';
import { useUserStore } from '../../stores/user.ts';
const userStore = useUserStore();
const router=useRouter();
const user = reactive(localStorage.getItem("user") ? JSON.parse(localStorage.getItem("user")) : null);
const logout=()=>{
router.push("/login")
localStorage.removeItem("user")
ElMessage.success("退出成功")
}
</script>
<style scoped>
.common-layout {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
background-color: #cdd1d3;
}
.el-container {
height: 100%;
}
.el-header,
.el-footer {
background-color: #47484c;
color: #fff;
text-align: center;
line-height: 60px;
}
.el-aside {
background-color: #2d2e36;
color: #fff;
text-align: center;
}
.el-main {
height: 100%;
background: url("../../assets/背景2.jpg") no-repeat center center;
background-size: cover;
}
.el-menu {
background-color: #2d2e36;
}
.el-menu-item {
color: #cdd1d3;
transition: background-color 0.3s ease, color 0.3s ease;
}
.el-menu-item:hover {
background-color: #fba414;
color: #fff;
}
.menu-item-hover:hover {
background-color: #eef5fe;
color: #333 !important;
}
.el-menu-item[disabled] {
color: #6c757d;
pointer-events: none;
}
.el-header {
padding: 0 20px;
display: flex;
flex-direction: row;
justify-content: center;
}
.el-menu-horizontal {
background-color: transparent;
display: flex;
align-items: center;
border: none;
}
.logo {
font-size: 30px;
color: white;
margin-right: 20px;
}
.title,
.user-info {
display: flex;
align-items: center;
border: 0px;
}
.user-name {
font-size: 16px;
color: white;
}
.exit {
margin-left: 15px;
}
</style>

@ -1,9 +1,8 @@
<template>
<el-row class="page">
<el-row class="block-view">
<el-row class="top">
<el-col><h3 class="title">用户反馈与建议</h3></el-col>
</el-row>
<el-row class="feedback-list">
<el-table :data="feedbacks" :stripe="true" :border="true" style="width: 100%">
@ -61,9 +60,7 @@ const feedbacks = ref([
}
.top {
display: flex;
flex-direction: row;
justify-content: flex-start;
padding-bottom: 15px; /* 下方间距 */
background-color: #cdd1d3;
@ -74,6 +71,7 @@ const feedbacks = ref([
font-weight: bold; /* 加粗 */
color: #333; /* 调整标题颜色 */
background-color: #cdd1d3;
text-align: center;
}
.feedback-list {

@ -0,0 +1,213 @@
<template>
<el-row class="top" justify="space-between">
<h2>个人信息</h2>
<el-col :span="6">
<el-button type="danger" @click="handleLogout"></el-button>
</el-col>
</el-row>
<el-row class="body">
<el-upload class="avatar-uploader" action="http://localhost:8080/file/upload" :show-file-list="false"
:on-success="handleAvatarSuccess" :before-upload="beforeAvatarUpload">
<img v-if="formData.avatar" width="100px" height="100px" :src="formData.avatar" class="avatar">
<el-icon v-else class="avatar-uploader-icon">
<Plus />
</el-icon>
</el-upload>
<el-text class="phone">{{ formData.username }}</el-text>
<el-form label-width="auto" style="max-width: 600px">
<el-form-item label="性别">
<el-radio-group v-model="formData.gender">
<el-radio label="男"></el-radio>
<el-radio label="女"></el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="地区">
<el-cascader :options="pcaTextArr" v-model="formData.address" placeholder="请选择地区"
:props="{ checkStrictly: true }" />
</el-form-item>
<el-form-item label="绑定手机">
<el-input v-model="formData.mobile" placeholder="请输入手机号" />
</el-form-item>
<el-form-item label="绑定邮箱">
<el-input v-model="formData.email" placeholder="请输入邮箱" />
</el-form-item>
<el-form-item style="margin-top: 30px;">
<el-button @click="handleChanges" style="margin-left: 100px;">保存信息</el-button>
</el-form-item>
</el-form>
<el-dialog v-model="isDialogVisible" title="确认注销" width="500px" :custom-class="'custom-dialog'">
<span>确定要注销账号吗</span>
<template #footer>
<el-button @click="isDialogVisible = false">取消</el-button>
<el-button type="danger" @click="confirmLogout"></el-button>
</template>
</el-dialog>
<el-dialog v-model="isDialogVisibleSave" title="确认保存" width="500px">
<span>信息已修改是否保存更改</span>
<template #footer>
<el-button @click="isDialogVisibleSave=false"></el-button>
<el-button type="primary" @click="confirmChanges"></el-button>
</template>
</el-dialog>
</el-row>
</template>
<script lang="ts" setup>
import { ref, reactive } from 'vue';
import { useRouter } from 'vue-router';
import { ElMessage } from 'element-plus';
import { pcaTextArr } from 'element-china-area-data';
import request from '../../request.js';
import { useUserStore } from '../../stores/user';
const userStore = useUserStore();
const router = useRouter();
const isDialogVisible = ref(false);
const isDialogVisibleSave = ref(false);
const formData = reactive({
username: '',
gender: '',
address: [],
mobile: '',
avatar: '',
email:''
});
//
request.get('http://localhost:8080/user/info').then(res=> {
if (res.data.code == '200') {
const userInfo = res.data.data;
formData.username = userInfo.username;
formData.gender = userInfo.gender;
formData.address = userInfo.address ? userInfo.address.split(' ') : [];
formData.mobile = userInfo.mobile;
formData.avatar = userInfo.avatar;
formData.email = userInfo.email;
}
})
.catch((error) => {
console.error('请求用户信息失败:', error);
ElMessage.error('请求用户信息失败,请检查网络连接或联系管理员。');
});
const handleChanges = () => {
isDialogVisibleSave.value = true;
};
const confirmChanges = () => {
request.post('http://localhost:8080/user', {
username:formData.username,
gender: formData.gender,
address: formData.address.join(' '),
mobile: formData.mobile,
email: formData.email,
avatar: formData.avatar
})
.then((res) => {
if (res.data.code == '200') {
let user = JSON.parse(localStorage.getItem("user") || '{}');
user.avatar = formData.avatar;
userStore.setUser(formData);
ElMessage.success('个人信息保存成功');
} else {
ElMessage.error('个人信息保存失败');
}
})
.catch((error) => {
console.error('保存信息失败:', error);
ElMessage.error('保存信息失败,请稍后再试');
});
isDialogVisibleSave.value = false;
};
const handleLogout = () => {
isDialogVisible.value = true;
};
const confirmLogout = () => {
router.push('/login');
localStorage.removeItem('user');
ElMessage.success('退出成功');
};
const handleAvatarSuccess = (response) => {
if (response && response.data) {
formData.avatar = response.data; //
ElMessage.success("头像上传成功");
} else {
ElMessage.error("上传失败,请联系管理员");
}
};
const beforeAvatarUpload = (file) => {
const isJPGorPNG = file.type === 'image/jpeg' || file.type === 'image/png';
const isLt2M = file.size / 1024 / 1024 < 2;
if (!isJPGorPNG) {
ElMessage.error("上传头像图片只能是 JPG/PNG 格式!");
}
if (!isLt2M) {
ElMessage.error("上传头像图片大小不能超过 2MB!");
}
return isJPGorPNG && isLt2M;
};
</script>
<style>
.top {
background-color: white;
height: 50px;
flex-wrap: nowrap;
justify-content: space-between;
align-items: center;
border-radius: 5px;
margin-bottom: 15px;
padding-left: 15px;
}
.body {
background-color: white;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
line-height: 0px;
height: 90vh;
}
.phone {
margin-top: 20px;
font-size: 14px;
margin-bottom: 20px;
}
.avatar-uploader .el-upload {
border: 1px dashed var(--el-border-color);
border-radius: 6px;
cursor: pointer;
position: relative;
overflow: hidden;
transition: var(--el-transition-duration-fast);
}
.avatar-uploader .el-upload:hover {
border-color: var(--el-color-primary);
}
.avatar-uploader .avatar {
width: 100px;
height: 100px;
display: block;
}
.el-icon.avatar-uploader-icon {
font-size: 28px;
color: #8c939d;
width: 100px;
height: 100px;
text-align: center;
}
</style>

@ -9,27 +9,34 @@
<!-- 发布通知 -->
<el-card class="publish" shadow="hover">
<el-row gutter={20}>
<el-col :span="12">
<el-input
<el-row gutter={20} style="display: flex;">
<el-col :span="20" class="center-col">
<el-input
placeholder="请输入通知标题"
v-model="newNotification.title"
clearable
size="medium"
class="notification-input"
/>
</el-col>
<el-col :span="12">
<el-col></el-col>
<el-col :span="24" class="center-col">
<el-input
type="textarea"
placeholder="请输入通知内容"
v-model="newNotification.content"
clearable
size="medium"
size="large"
class="notification-input"
/>
</el-col>
</el-row>
<el-button
type="primary"
@click="isEditing ? updateNotification() : addNotification()"
@ -226,4 +233,16 @@ const resetForm = () => {
.el-alert {
margin-top: 20px;
}
.center-col {
display: flex;
justify-content: center; /* 确保水平居中 */
align-items: center;
height: 70px;
width: 100%;
}
</style>

@ -1,726 +0,0 @@
{
"name": "yzb",
"version": "0.0.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "yzb",
"version": "0.0.0",
"dependencies": {
"element-plus": "^2.8.7",
"vue": "^3.4.37"
},
"devDependencies": {
"@vitejs/plugin-vue": "^5.1.2",
"vite": "^5.4.1"
}
},
"node_modules/@babel/helper-string-parser": {
"version": "7.24.8",
"resolved": "https://registry.npmmirror.com/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz",
"integrity": "sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==",
"license": "MIT",
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-validator-identifier": {
"version": "7.24.7",
"resolved": "https://registry.npmmirror.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz",
"integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==",
"license": "MIT",
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/parser": {
"version": "7.25.4",
"resolved": "https://registry.npmmirror.com/@babel/parser/-/parser-7.25.4.tgz",
"integrity": "sha512-nq+eWrOgdtu3jG5Os4TQP3x3cLA8hR8TvJNjD8vnPa20WGycimcparWnLK4jJhElTK6SDyuJo1weMKO/5LpmLA==",
"license": "MIT",
"dependencies": {
"@babel/types": "^7.25.4"
},
"bin": {
"parser": "bin/babel-parser.js"
},
"engines": {
"node": ">=6.0.0"
}
},
"node_modules/@babel/types": {
"version": "7.25.4",
"resolved": "https://registry.npmmirror.com/@babel/types/-/types-7.25.4.tgz",
"integrity": "sha512-zQ1ijeeCXVEh+aNL0RlmkPkG8HUiDcU2pzQQFjtbntgAczRASFzj4H+6+bV+dy1ntKR14I/DypeuRG1uma98iQ==",
"license": "MIT",
"dependencies": {
"@babel/helper-string-parser": "^7.24.8",
"@babel/helper-validator-identifier": "^7.24.7",
"to-fast-properties": "^2.0.0"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@ctrl/tinycolor": {
"version": "3.6.1",
"resolved": "https://registry.npmjs.org/@ctrl/tinycolor/-/tinycolor-3.6.1.tgz",
"integrity": "sha512-SITSV6aIXsuVNV3f3O0f2n/cgyEDWoSqtZMYiAmcsYHydcKrOz3gUxB/iXd/Qf08+IZX4KpgNbvUdMBmWz+kcA==",
"license": "MIT",
"engines": {
"node": ">=10"
}
},
"node_modules/@element-plus/icons-vue": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/@element-plus/icons-vue/-/icons-vue-2.3.1.tgz",
"integrity": "sha512-XxVUZv48RZAd87ucGS48jPf6pKu0yV5UCg9f4FFwtrYxXOwWuVJo6wOvSLKEoMQKjv8GsX/mhP6UsC1lRwbUWg==",
"license": "MIT",
"peerDependencies": {
"vue": "^3.2.0"
}
},
"node_modules/@esbuild/win32-x64": {
"version": "0.21.5",
"resolved": "https://registry.npmmirror.com/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz",
"integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@floating-ui/core": {
"version": "1.6.8",
"resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.8.tgz",
"integrity": "sha512-7XJ9cPU+yI2QeLS+FCSlqNFZJq8arvswefkZrYI1yQBbftw6FyrZOxYSh+9S7z7TpeWlRt9zJ5IhM1WIL334jA==",
"license": "MIT",
"dependencies": {
"@floating-ui/utils": "^0.2.8"
}
},
"node_modules/@floating-ui/dom": {
"version": "1.6.12",
"resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.12.tgz",
"integrity": "sha512-NP83c0HjokcGVEMeoStg317VD9W7eDlGK7457dMBANbKA6GJZdc7rjujdgqzTaz93jkGgc5P/jeWbaCHnMNc+w==",
"license": "MIT",
"dependencies": {
"@floating-ui/core": "^1.6.0",
"@floating-ui/utils": "^0.2.8"
}
},
"node_modules/@floating-ui/utils": {
"version": "0.2.8",
"resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.8.tgz",
"integrity": "sha512-kym7SodPp8/wloecOpcmSnWJsK7M0E5Wg8UcFA+uO4B9s5d0ywXOEro/8HM9x0rW+TljRzul/14UYz3TleT3ig==",
"license": "MIT"
},
"node_modules/@jridgewell/sourcemap-codec": {
"version": "1.5.0",
"resolved": "https://registry.npmmirror.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz",
"integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==",
"license": "MIT"
},
"node_modules/@popperjs/core": {
"name": "@sxzz/popperjs-es",
"version": "2.11.7",
"resolved": "https://registry.npmjs.org/@sxzz/popperjs-es/-/popperjs-es-2.11.7.tgz",
"integrity": "sha512-Ccy0NlLkzr0Ex2FKvh2X+OyERHXJ88XJ1MXtsI9y9fGexlaXaVTPzBCRBwIxFkORuOb+uBqeu+RqnpgYTEZRUQ==",
"license": "MIT",
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/popperjs"
}
},
"node_modules/@rollup/rollup-win32-x64-msvc": {
"version": "4.21.1",
"resolved": "https://registry.npmmirror.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.21.1.tgz",
"integrity": "sha512-xGiIH95H1zU7naUyTKEyOA/I0aexNMUdO9qRv0bLKN3qu25bBdrxZHqA3PTJ24YNN/GdMzG4xkDcd/GvjuhfLg==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"win32"
]
},
"node_modules/@types/estree": {
"version": "1.0.5",
"resolved": "https://registry.npmmirror.com/@types/estree/-/estree-1.0.5.tgz",
"integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==",
"dev": true,
"license": "MIT"
},
"node_modules/@types/lodash": {
"version": "4.17.13",
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.13.tgz",
"integrity": "sha512-lfx+dftrEZcdBPczf9d0Qv0x+j/rfNCMuC6OcfXmO8gkfeNAY88PgKUbvG56whcN23gc27yenwF6oJZXGFpYxg==",
"license": "MIT"
},
"node_modules/@types/lodash-es": {
"version": "4.17.12",
"resolved": "https://registry.npmjs.org/@types/lodash-es/-/lodash-es-4.17.12.tgz",
"integrity": "sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ==",
"license": "MIT",
"dependencies": {
"@types/lodash": "*"
}
},
"node_modules/@types/web-bluetooth": {
"version": "0.0.16",
"resolved": "https://registry.npmjs.org/@types/web-bluetooth/-/web-bluetooth-0.0.16.tgz",
"integrity": "sha512-oh8q2Zc32S6gd/j50GowEjKLoOVOwHP/bWVjKJInBwQqdOYMdPrf1oVlelTlyfFK3CKxL1uahMDAr+vy8T7yMQ==",
"license": "MIT"
},
"node_modules/@vitejs/plugin-vue": {
"version": "5.1.2",
"resolved": "https://registry.npmmirror.com/@vitejs/plugin-vue/-/plugin-vue-5.1.2.tgz",
"integrity": "sha512-nY9IwH12qeiJqumTCLJLE7IiNx7HZ39cbHaysEUd+Myvbz9KAqd2yq+U01Kab1R/H1BmiyM2ShTYlNH32Fzo3A==",
"dev": true,
"license": "MIT",
"engines": {
"node": "^18.0.0 || >=20.0.0"
},
"peerDependencies": {
"vite": "^5.0.0",
"vue": "^3.2.25"
}
},
"node_modules/@vue/compiler-core": {
"version": "3.4.38",
"resolved": "https://registry.npmmirror.com/@vue/compiler-core/-/compiler-core-3.4.38.tgz",
"integrity": "sha512-8IQOTCWnLFqfHzOGm9+P8OPSEDukgg3Huc92qSG49if/xI2SAwLHQO2qaPQbjCWPBcQoO1WYfXfTACUrWV3c5A==",
"license": "MIT",
"dependencies": {
"@babel/parser": "^7.24.7",
"@vue/shared": "3.4.38",
"entities": "^4.5.0",
"estree-walker": "^2.0.2",
"source-map-js": "^1.2.0"
}
},
"node_modules/@vue/compiler-dom": {
"version": "3.4.38",
"resolved": "https://registry.npmmirror.com/@vue/compiler-dom/-/compiler-dom-3.4.38.tgz",
"integrity": "sha512-Osc/c7ABsHXTsETLgykcOwIxFktHfGSUDkb05V61rocEfsFDcjDLH/IHJSNJP+/Sv9KeN2Lx1V6McZzlSb9EhQ==",
"license": "MIT",
"dependencies": {
"@vue/compiler-core": "3.4.38",
"@vue/shared": "3.4.38"
}
},
"node_modules/@vue/compiler-sfc": {
"version": "3.4.38",
"resolved": "https://registry.npmmirror.com/@vue/compiler-sfc/-/compiler-sfc-3.4.38.tgz",
"integrity": "sha512-s5QfZ+9PzPh3T5H4hsQDJtI8x7zdJaew/dCGgqZ2630XdzaZ3AD8xGZfBqpT8oaD/p2eedd+pL8tD5vvt5ZYJQ==",
"license": "MIT",
"dependencies": {
"@babel/parser": "^7.24.7",
"@vue/compiler-core": "3.4.38",
"@vue/compiler-dom": "3.4.38",
"@vue/compiler-ssr": "3.4.38",
"@vue/shared": "3.4.38",
"estree-walker": "^2.0.2",
"magic-string": "^0.30.10",
"postcss": "^8.4.40",
"source-map-js": "^1.2.0"
}
},
"node_modules/@vue/compiler-ssr": {
"version": "3.4.38",
"resolved": "https://registry.npmmirror.com/@vue/compiler-ssr/-/compiler-ssr-3.4.38.tgz",
"integrity": "sha512-YXznKFQ8dxYpAz9zLuVvfcXhc31FSPFDcqr0kyujbOwNhlmaNvL2QfIy+RZeJgSn5Fk54CWoEUeW+NVBAogGaw==",
"license": "MIT",
"dependencies": {
"@vue/compiler-dom": "3.4.38",
"@vue/shared": "3.4.38"
}
},
"node_modules/@vue/reactivity": {
"version": "3.4.38",
"resolved": "https://registry.npmmirror.com/@vue/reactivity/-/reactivity-3.4.38.tgz",
"integrity": "sha512-4vl4wMMVniLsSYYeldAKzbk72+D3hUnkw9z8lDeJacTxAkXeDAP1uE9xr2+aKIN0ipOL8EG2GPouVTH6yF7Gnw==",
"license": "MIT",
"dependencies": {
"@vue/shared": "3.4.38"
}
},
"node_modules/@vue/runtime-core": {
"version": "3.4.38",
"resolved": "https://registry.npmmirror.com/@vue/runtime-core/-/runtime-core-3.4.38.tgz",
"integrity": "sha512-21z3wA99EABtuf+O3IhdxP0iHgkBs1vuoCAsCKLVJPEjpVqvblwBnTj42vzHRlWDCyxu9ptDm7sI2ZMcWrQqlA==",
"license": "MIT",
"dependencies": {
"@vue/reactivity": "3.4.38",
"@vue/shared": "3.4.38"
}
},
"node_modules/@vue/runtime-dom": {
"version": "3.4.38",
"resolved": "https://registry.npmmirror.com/@vue/runtime-dom/-/runtime-dom-3.4.38.tgz",
"integrity": "sha512-afZzmUreU7vKwKsV17H1NDThEEmdYI+GCAK/KY1U957Ig2NATPVjCROv61R19fjZNzMmiU03n79OMnXyJVN0UA==",
"license": "MIT",
"dependencies": {
"@vue/reactivity": "3.4.38",
"@vue/runtime-core": "3.4.38",
"@vue/shared": "3.4.38",
"csstype": "^3.1.3"
}
},
"node_modules/@vue/server-renderer": {
"version": "3.4.38",
"resolved": "https://registry.npmmirror.com/@vue/server-renderer/-/server-renderer-3.4.38.tgz",
"integrity": "sha512-NggOTr82FbPEkkUvBm4fTGcwUY8UuTsnWC/L2YZBmvaQ4C4Jl/Ao4HHTB+l7WnFCt5M/dN3l0XLuyjzswGYVCA==",
"license": "MIT",
"dependencies": {
"@vue/compiler-ssr": "3.4.38",
"@vue/shared": "3.4.38"
},
"peerDependencies": {
"vue": "3.4.38"
}
},
"node_modules/@vue/shared": {
"version": "3.4.38",
"resolved": "https://registry.npmmirror.com/@vue/shared/-/shared-3.4.38.tgz",
"integrity": "sha512-q0xCiLkuWWQLzVrecPb0RMsNWyxICOjPrcrwxTUEHb1fsnvni4dcuyG7RT/Ie7VPTvnjzIaWzRMUBsrqNj/hhw==",
"license": "MIT"
},
"node_modules/@vueuse/core": {
"version": "9.13.0",
"resolved": "https://registry.npmjs.org/@vueuse/core/-/core-9.13.0.tgz",
"integrity": "sha512-pujnclbeHWxxPRqXWmdkKV5OX4Wk4YeK7wusHqRwU0Q7EFusHoqNA/aPhB6KCh9hEqJkLAJo7bb0Lh9b+OIVzw==",
"license": "MIT",
"dependencies": {
"@types/web-bluetooth": "^0.0.16",
"@vueuse/metadata": "9.13.0",
"@vueuse/shared": "9.13.0",
"vue-demi": "*"
},
"funding": {
"url": "https://github.com/sponsors/antfu"
}
},
"node_modules/@vueuse/core/node_modules/vue-demi": {
"version": "0.14.10",
"resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.10.tgz",
"integrity": "sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==",
"hasInstallScript": true,
"license": "MIT",
"bin": {
"vue-demi-fix": "bin/vue-demi-fix.js",
"vue-demi-switch": "bin/vue-demi-switch.js"
},
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/antfu"
},
"peerDependencies": {
"@vue/composition-api": "^1.0.0-rc.1",
"vue": "^3.0.0-0 || ^2.6.0"
},
"peerDependenciesMeta": {
"@vue/composition-api": {
"optional": true
}
}
},
"node_modules/@vueuse/metadata": {
"version": "9.13.0",
"resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-9.13.0.tgz",
"integrity": "sha512-gdU7TKNAUVlXXLbaF+ZCfte8BjRJQWPCa2J55+7/h+yDtzw3vOoGQDRXzI6pyKyo6bXFT5/QoPE4hAknExjRLQ==",
"license": "MIT",
"funding": {
"url": "https://github.com/sponsors/antfu"
}
},
"node_modules/@vueuse/shared": {
"version": "9.13.0",
"resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-9.13.0.tgz",
"integrity": "sha512-UrnhU+Cnufu4S6JLCPZnkWh0WwZGUp72ktOF2DFptMlOs3TOdVv8xJN53zhHGARmVOsz5KqOls09+J1NR6sBKw==",
"license": "MIT",
"dependencies": {
"vue-demi": "*"
},
"funding": {
"url": "https://github.com/sponsors/antfu"
}
},
"node_modules/@vueuse/shared/node_modules/vue-demi": {
"version": "0.14.10",
"resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.10.tgz",
"integrity": "sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==",
"hasInstallScript": true,
"license": "MIT",
"bin": {
"vue-demi-fix": "bin/vue-demi-fix.js",
"vue-demi-switch": "bin/vue-demi-switch.js"
},
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/antfu"
},
"peerDependencies": {
"@vue/composition-api": "^1.0.0-rc.1",
"vue": "^3.0.0-0 || ^2.6.0"
},
"peerDependenciesMeta": {
"@vue/composition-api": {
"optional": true
}
}
},
"node_modules/async-validator": {
"version": "4.2.5",
"resolved": "https://registry.npmjs.org/async-validator/-/async-validator-4.2.5.tgz",
"integrity": "sha512-7HhHjtERjqlNbZtqNqy2rckN/SpOOlmDliet+lP7k+eKZEjPk3DgyeU9lIXLdeLz0uBbbVp+9Qdow9wJWgwwfg==",
"license": "MIT"
},
"node_modules/csstype": {
"version": "3.1.3",
"resolved": "https://registry.npmmirror.com/csstype/-/csstype-3.1.3.tgz",
"integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
"license": "MIT"
},
"node_modules/dayjs": {
"version": "1.11.13",
"resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.13.tgz",
"integrity": "sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==",
"license": "MIT"
},
"node_modules/element-plus": {
"version": "2.8.7",
"resolved": "https://registry.npmjs.org/element-plus/-/element-plus-2.8.7.tgz",
"integrity": "sha512-oGQyFRufFOgjd872tZc+T4xQAYLlX4hj6d3ixeY13L4fFNUuc1N49JHAqJGPda0tdx3qCnjceZoh1kqqj2+tXQ==",
"license": "MIT",
"dependencies": {
"@ctrl/tinycolor": "^3.4.1",
"@element-plus/icons-vue": "^2.3.1",
"@floating-ui/dom": "^1.0.1",
"@popperjs/core": "npm:@sxzz/popperjs-es@^2.11.7",
"@types/lodash": "^4.14.182",
"@types/lodash-es": "^4.17.6",
"@vueuse/core": "^9.1.0",
"async-validator": "^4.2.5",
"dayjs": "^1.11.3",
"escape-html": "^1.0.3",
"lodash": "^4.17.21",
"lodash-es": "^4.17.21",
"lodash-unified": "^1.0.2",
"memoize-one": "^6.0.0",
"normalize-wheel-es": "^1.2.0"
},
"peerDependencies": {
"vue": "^3.2.0"
}
},
"node_modules/entities": {
"version": "4.5.0",
"resolved": "https://registry.npmmirror.com/entities/-/entities-4.5.0.tgz",
"integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
"license": "BSD-2-Clause",
"engines": {
"node": ">=0.12"
},
"funding": {
"url": "https://github.com/fb55/entities?sponsor=1"
}
},
"node_modules/esbuild": {
"version": "0.21.5",
"resolved": "https://registry.npmmirror.com/esbuild/-/esbuild-0.21.5.tgz",
"integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==",
"dev": true,
"hasInstallScript": true,
"license": "MIT",
"bin": {
"esbuild": "bin/esbuild"
},
"engines": {
"node": ">=12"
},
"optionalDependencies": {
"@esbuild/aix-ppc64": "0.21.5",
"@esbuild/android-arm": "0.21.5",
"@esbuild/android-arm64": "0.21.5",
"@esbuild/android-x64": "0.21.5",
"@esbuild/darwin-arm64": "0.21.5",
"@esbuild/darwin-x64": "0.21.5",
"@esbuild/freebsd-arm64": "0.21.5",
"@esbuild/freebsd-x64": "0.21.5",
"@esbuild/linux-arm": "0.21.5",
"@esbuild/linux-arm64": "0.21.5",
"@esbuild/linux-ia32": "0.21.5",
"@esbuild/linux-loong64": "0.21.5",
"@esbuild/linux-mips64el": "0.21.5",
"@esbuild/linux-ppc64": "0.21.5",
"@esbuild/linux-riscv64": "0.21.5",
"@esbuild/linux-s390x": "0.21.5",
"@esbuild/linux-x64": "0.21.5",
"@esbuild/netbsd-x64": "0.21.5",
"@esbuild/openbsd-x64": "0.21.5",
"@esbuild/sunos-x64": "0.21.5",
"@esbuild/win32-arm64": "0.21.5",
"@esbuild/win32-ia32": "0.21.5",
"@esbuild/win32-x64": "0.21.5"
}
},
"node_modules/escape-html": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
"integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==",
"license": "MIT"
},
"node_modules/estree-walker": {
"version": "2.0.2",
"resolved": "https://registry.npmmirror.com/estree-walker/-/estree-walker-2.0.2.tgz",
"integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
"license": "MIT"
},
"node_modules/lodash": {
"version": "4.17.21",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
"license": "MIT"
},
"node_modules/lodash-es": {
"version": "4.17.21",
"resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz",
"integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==",
"license": "MIT"
},
"node_modules/lodash-unified": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/lodash-unified/-/lodash-unified-1.0.3.tgz",
"integrity": "sha512-WK9qSozxXOD7ZJQlpSqOT+om2ZfcT4yO+03FuzAHD0wF6S0l0090LRPDx3vhTTLZ8cFKpBn+IOcVXK6qOcIlfQ==",
"license": "MIT",
"peerDependencies": {
"@types/lodash-es": "*",
"lodash": "*",
"lodash-es": "*"
}
},
"node_modules/magic-string": {
"version": "0.30.11",
"resolved": "https://registry.npmmirror.com/magic-string/-/magic-string-0.30.11.tgz",
"integrity": "sha512-+Wri9p0QHMy+545hKww7YAu5NyzF8iomPL/RQazugQ9+Ez4Ic3mERMd8ZTX5rfK944j+560ZJi8iAwgak1Ac7A==",
"license": "MIT",
"dependencies": {
"@jridgewell/sourcemap-codec": "^1.5.0"
}
},
"node_modules/memoize-one": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-6.0.0.tgz",
"integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==",
"license": "MIT"
},
"node_modules/nanoid": {
"version": "3.3.7",
"resolved": "https://registry.npmmirror.com/nanoid/-/nanoid-3.3.7.tgz",
"integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/ai"
}
],
"license": "MIT",
"bin": {
"nanoid": "bin/nanoid.cjs"
},
"engines": {
"node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
}
},
"node_modules/normalize-wheel-es": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/normalize-wheel-es/-/normalize-wheel-es-1.2.0.tgz",
"integrity": "sha512-Wj7+EJQ8mSuXr2iWfnujrimU35R2W4FAErEyTmJoJ7ucwTn2hOUSsRehMb5RSYkxXGTM7Y9QpvPmp++w5ftoJw==",
"license": "BSD-3-Clause"
},
"node_modules/picocolors": {
"version": "1.0.1",
"resolved": "https://registry.npmmirror.com/picocolors/-/picocolors-1.0.1.tgz",
"integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==",
"license": "ISC"
},
"node_modules/postcss": {
"version": "8.4.41",
"resolved": "https://registry.npmmirror.com/postcss/-/postcss-8.4.41.tgz",
"integrity": "sha512-TesUflQ0WKZqAvg52PWL6kHgLKP6xB6heTOdoYM0Wt2UHyxNa4K25EZZMgKns3BH1RLVbZCREPpLY0rhnNoHVQ==",
"funding": [
{
"type": "opencollective",
"url": "https://opencollective.com/postcss/"
},
{
"type": "tidelift",
"url": "https://tidelift.com/funding/github/npm/postcss"
},
{
"type": "github",
"url": "https://github.com/sponsors/ai"
}
],
"license": "MIT",
"dependencies": {
"nanoid": "^3.3.7",
"picocolors": "^1.0.1",
"source-map-js": "^1.2.0"
},
"engines": {
"node": "^10 || ^12 || >=14"
}
},
"node_modules/rollup": {
"version": "4.21.1",
"resolved": "https://registry.npmmirror.com/rollup/-/rollup-4.21.1.tgz",
"integrity": "sha512-ZnYyKvscThhgd3M5+Qt3pmhO4jIRR5RGzaSovB6Q7rGNrK5cUncrtLmcTTJVSdcKXyZjW8X8MB0JMSuH9bcAJg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@types/estree": "1.0.5"
},
"bin": {
"rollup": "dist/bin/rollup"
},
"engines": {
"node": ">=18.0.0",
"npm": ">=8.0.0"
},
"optionalDependencies": {
"@rollup/rollup-android-arm-eabi": "4.21.1",
"@rollup/rollup-android-arm64": "4.21.1",
"@rollup/rollup-darwin-arm64": "4.21.1",
"@rollup/rollup-darwin-x64": "4.21.1",
"@rollup/rollup-linux-arm-gnueabihf": "4.21.1",
"@rollup/rollup-linux-arm-musleabihf": "4.21.1",
"@rollup/rollup-linux-arm64-gnu": "4.21.1",
"@rollup/rollup-linux-arm64-musl": "4.21.1",
"@rollup/rollup-linux-powerpc64le-gnu": "4.21.1",
"@rollup/rollup-linux-riscv64-gnu": "4.21.1",
"@rollup/rollup-linux-s390x-gnu": "4.21.1",
"@rollup/rollup-linux-x64-gnu": "4.21.1",
"@rollup/rollup-linux-x64-musl": "4.21.1",
"@rollup/rollup-win32-arm64-msvc": "4.21.1",
"@rollup/rollup-win32-ia32-msvc": "4.21.1",
"@rollup/rollup-win32-x64-msvc": "4.21.1",
"fsevents": "~2.3.2"
}
},
"node_modules/source-map-js": {
"version": "1.2.0",
"resolved": "https://registry.npmmirror.com/source-map-js/-/source-map-js-1.2.0.tgz",
"integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==",
"license": "BSD-3-Clause",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/to-fast-properties": {
"version": "2.0.0",
"resolved": "https://registry.npmmirror.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
"integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==",
"license": "MIT",
"engines": {
"node": ">=4"
}
},
"node_modules/vite": {
"version": "5.4.2",
"resolved": "https://registry.npmmirror.com/vite/-/vite-5.4.2.tgz",
"integrity": "sha512-dDrQTRHp5C1fTFzcSaMxjk6vdpKvT+2/mIdE07Gw2ykehT49O0z/VHS3zZ8iV/Gh8BJJKHWOe5RjaNrW5xf/GA==",
"dev": true,
"license": "MIT",
"dependencies": {
"esbuild": "^0.21.3",
"postcss": "^8.4.41",
"rollup": "^4.20.0"
},
"bin": {
"vite": "bin/vite.js"
},
"engines": {
"node": "^18.0.0 || >=20.0.0"
},
"funding": {
"url": "https://github.com/vitejs/vite?sponsor=1"
},
"optionalDependencies": {
"fsevents": "~2.3.3"
},
"peerDependencies": {
"@types/node": "^18.0.0 || >=20.0.0",
"less": "*",
"lightningcss": "^1.21.0",
"sass": "*",
"sass-embedded": "*",
"stylus": "*",
"sugarss": "*",
"terser": "^5.4.0"
},
"peerDependenciesMeta": {
"@types/node": {
"optional": true
},
"less": {
"optional": true
},
"lightningcss": {
"optional": true
},
"sass": {
"optional": true
},
"sass-embedded": {
"optional": true
},
"stylus": {
"optional": true
},
"sugarss": {
"optional": true
},
"terser": {
"optional": true
}
}
},
"node_modules/vue": {
"version": "3.4.38",
"resolved": "https://registry.npmmirror.com/vue/-/vue-3.4.38.tgz",
"integrity": "sha512-f0ZgN+mZ5KFgVv9wz0f4OgVKukoXtS3nwET4c2vLBGQR50aI8G0cqbFtLlX9Yiyg3LFGBitruPHt2PxwTduJEw==",
"license": "MIT",
"dependencies": {
"@vue/compiler-dom": "3.4.38",
"@vue/compiler-sfc": "3.4.38",
"@vue/runtime-dom": "3.4.38",
"@vue/server-renderer": "3.4.38",
"@vue/shared": "3.4.38"
},
"peerDependencies": {
"typescript": "*"
},
"peerDependenciesMeta": {
"typescript": {
"optional": true
}
}
}
}
}

@ -1,22 +0,0 @@
{
"name": "yzb",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview"
},
"dependencies": {
"axios": "1.2.1",
"element-plus": "^2.8.7",
"pinia": "2.0.27",
"vue": "^3.4.37",
"vue-router": "4"
},
"devDependencies": {
"@vitejs/plugin-vue": "^5.1.2",
"vite": "^5.4.1"
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 89 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 71 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 832 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 205 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 178 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 170 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 170 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 178 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 82 KiB

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>

Before

Width:  |  Height:  |  Size: 1.5 KiB

@ -1,24 +0,0 @@
<script setup>
</script>
<template>
<div>
<router-view></router-view>
</div>
</template>
<style scoped>
.logo {
height: 6em;
padding: 1.5em;
will-change: filter;
transition: filter 300ms;
}
.logo:hover {
filter: drop-shadow(0 0 2em #646cffaa);
}
.logo.vue:hover {
filter: drop-shadow(0 0 2em #42b883aa);
}
</style>

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="37.07" height="36" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 198"><path fill="#41B883" d="M204.8 0H256L128 220.8L0 0h97.92L128 51.2L157.44 0h47.36Z"></path><path fill="#41B883" d="m0 0l128 220.8L256 0h-51.2L128 132.48L50.56 0H0Z"></path><path fill="#35495E" d="M50.56 0L128 133.12L204.8 0h-47.36L128 51.2L97.92 0H50.56Z"></path></svg>

Before

Width:  |  Height:  |  Size: 496 B

@ -1,73 +0,0 @@
<template>
<div class="cold-transport">
<div class="card">
<img src="/11.jpg" alt="通知" class="card-image" />
<div class="card-content">
<h3>通知</h3>
<p>
通知通知通知通知通知通知通知通知通知通知通知通知通知
</p>
</div>
</div>
<div class="card">
<img src="/12.png" alt="通知" class="card-image" />
<div class="card-content">
<h3>通知</h3>
<p>
通知通知通知通知通知通知通知通知通知通知通知通知通知
</p>
</div>
</div>
</div>
</template>
<script>
export default {
name: "ColdTransport",
};
</script>
<style scoped>
.cold-transport {
display: flex;
justify-content: space-between;
gap: 16px;
padding: 20px;
}
.card {
width: 48%;
border: 1px solid #ddd;
border-radius: 8px;
overflow: hidden;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
background: #fff;
transition: transform 0.3s ease;
}
.card:hover {
transform: translateY(-5px);
}
.card-image {
width: 100%;
height: 180px;
object-fit: cover;
}
.card-content {
padding: 16px;
}
.card-content h3 {
font-size: 18px;
margin-bottom: 8px;
color: #333;
}
.card-content p {
font-size: 14px;
color: #666;
line-height: 1.6;
}
</style>

@ -1,73 +0,0 @@
<template>
<div class="cold-transport">
<div class="card">
<img src="/21.png" alt="通知" class="card-image" />
<div class="card-content">
<h3>通知</h3>
<p>
通知通知通知通知通知通知通知通知通知通知通知通知通知通知通知通知通知
</p>
</div>
</div>
<div class="card">
<img src="/22.png" alt="通知" class="card-image" />
<div class="card-content">
<h3>通知</h3>
<p>
通知通知通知通知通知通知通知通知通知通知通知通知通知通知通知通知通知
</p>
</div>
</div>
</div>
</template>
<script>
export default {
name: "ColdTransport",
};
</script>
<style scoped>
.cold-transport {
display: flex;
justify-content: space-between;
gap: 16px;
padding: 20px;
}
.card {
width: 48%;
border: 1px solid #ddd;
border-radius: 8px;
overflow: hidden;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
background: #fff;
transition: transform 0.3s ease;
}
.card:hover {
transform: translateY(-5px);
}
.card-image {
width: 100%;
height: 180px;
object-fit: cover;
}
.card-content {
padding: 16px;
}
.card-content h3 {
font-size: 18px;
margin-bottom: 8px;
color: #333;
}
.card-content p {
font-size: 14px;
color: #666;
line-height: 1.6;
}
</style>

@ -1,73 +0,0 @@
<template>
<div class="cold-transport">
<div class="card">
<img src="/31.jpg" alt="通知" class="card-image" />
<div class="card-content">
<h3>通知</h3>
<p>
通知通知通知通知通知通知通知通知通知通知通知通知通知通知通知通知
</p>
</div>
</div>
<div class="card">
<img src="/32.png" alt="通知" class="card-image" />
<div class="card-content">
<h3>通知</h3>
<p>
通知通知通知通知通知通知通知通知通知通知通知通知通知通知通知通知
</p>
</div>
</div>
</div>
</template>
<script>
export default {
name: "ColdTransport",
};
</script>
<style scoped>
.cold-transport {
display: flex;
justify-content: space-between;
gap: 16px;
padding: 20px;
}
.card {
width: 48%;
border: 1px solid #ddd;
border-radius: 8px;
overflow: hidden;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
background: #fff;
transition: transform 0.3s ease;
}
.card:hover {
transform: translateY(-5px);
}
.card-image {
width: 100%;
height: 180px;
object-fit: cover;
}
.card-content {
padding: 16px;
}
.card-content h3 {
font-size: 18px;
margin-bottom: 8px;
color: #333;
}
.card-content p {
font-size: 14px;
color: #666;
line-height: 1.6;
}
</style>

@ -1,73 +0,0 @@
<template>
<div class="cold-transport">
<div class="card">
<img src="/41.png" alt="通知" class="card-image" />
<div class="card-content">
<h3>通知</h3>
<p>
通知通知通知通知通知通知通知通知通知通知通知通知通知通知通知通知通知通知通知通知
</p>
</div>
</div>
<div class="card">
<img src="/42.jpg" alt="通知" class="card-image" />
<div class="card-content">
<h3>通知</h3>
<p>
通知通知通知通知通知通知通知通知通知通知通知通知通知通知通知通知通知通知通知通知
</p>
</div>
</div>
</div>
</template>
<script>
export default {
name: "ColdTransport",
};
</script>
<style scoped>
.cold-transport {
display: flex;
justify-content: space-between;
gap: 16px;
padding: 20px;
}
.card {
width: 48%;
border: 1px solid #ddd;
border-radius: 8px;
overflow: hidden;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
background: #fff;
transition: transform 0.3s ease;
}
.card:hover {
transform: translateY(-5px);
}
.card-image {
width: 100%;
height: 180px;
object-fit: cover;
}
.card-content {
padding: 16px;
}
.card-content h3 {
font-size: 18px;
margin-bottom: 8px;
color: #333;
}
.card-content p {
font-size: 14px;
color: #666;
line-height: 1.6;
}
</style>

@ -1,19 +0,0 @@
import { createApp } from 'vue'; // 导入 Vue
//import App from './App.vue'; // 导入主 App 组件
import ElementPlus from 'element-plus'; // 导入 Element Plus
import 'element-plus/dist/index.css'; // 正确导入 Element Plus 样式
//import App from './view/user/teacher.vue'
import App from './App.vue'
import router from './router.js'
import './style.css'
import {createPinia} from 'pinia'
// 创建 Vue 应用实例
const app = createApp(App);
// 使用 Element Plus 插件
app.use(ElementPlus);
app.use(router)
const pinia=createPinia()
app.use(pinia)
// 挂载应用到 DOM 中
app.mount('#app');

@ -1,5 +0,0 @@
import axios from "axios"
const request = axios.create({
timeout:2000
})
export default request

@ -1,76 +0,0 @@
import { createRouter, createWebHashHistory } from "vue-router";
import { userStore } from "./store";
import { storeToRefs } from "pinia";
const router = createRouter({
history: createWebHashHistory(),
routes: [
{
path:'/',
redirect:{name:'admin'}
},
{
path: "/admin",
name: 'admin',
component: () => import('./view/user/index.vue'),
redirect: { name: 'FirstPage' }, // Default redirect to firstpage route by name
children: [
{
path: 'student',
name: 'Student',
component: () => import('./view/user/student.vue'),
},
{
path: 'teacher',
name: 'Teacher',
component: () => import('./view/user/teacher.vue'),
},
{
path: 'information',
name: 'Information',
component: () => import('./view/user/information.vue'),
},
{
path: 'myinfo',
name: 'MyInfo',
component: () => import('./view/user/myinfo.vue'),
},
{
path: 'firstpage',
name: 'FirstPage',
component: () => import('./view/user/firstpage.vue'),
redirect: { name: 'FirstPage1' },
children: [
{
path: '1',
name: 'FirstPage1',
component: () => import('./components/1.vue'),
},
{
path: '2',
name: 'FirstPage2',
component: () => import('./components/2.vue'),
},
{
path: '3',
name: 'FirstPage3',
component: () => import('./components/3.vue'),
},
{
path: '4',
name: 'FirstPage4',
component: () => import('./components/4.vue'),
}
]
},
{
path: 'notice',
name: 'Notice',
component: () => import('./view/user/notice.vue'),
}
]
}
]
});
export default router;

@ -1,15 +0,0 @@
import {defineStore} from "pinia";
export const userStore=defineStore('storeId',{
state:()=>{
return{
loginState:false
}
},
getters:{},
actions:{
setLoginState(state){
this.loginState=state
}
}
})

@ -1,79 +0,0 @@
:root {
font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
line-height: 1.5;
font-weight: 400;
color-scheme: light dark;
color: rgba(255, 255, 255, 0.87);
background-color: #242424;
font-synthesis: none;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
a {
font-weight: 500;
color: #646cff;
text-decoration: inherit;
}
a:hover {
color: #535bf2;
}
body {
margin: 0;
display: flex;
place-items: center;
min-width: 320px;
min-height: 100vh;
}
h1 {
font-size: 3.2em;
line-height: 1.1;
}
button {
border-radius: 8px;
border: 1px solid transparent;
padding: 0.6em 1.2em;
font-size: 1em;
font-weight: 500;
font-family: inherit;
background-color: #1a1a1a;
cursor: pointer;
transition: border-color 0.25s;
}
button:hover {
border-color: #646cff;
}
button:focus,
button:focus-visible {
outline: 4px auto -webkit-focus-ring-color;
}
.card {
padding: 2em;
}
#app {
max-width: 1280px;
margin: 0 auto;
padding: 2rem;
text-align: center;
}
@media (prefers-color-scheme: light) {
:root {
color: #213547;
background-color: #ffffff;
}
a:hover {
color: #747bff;
}
button {
background-color: #f9f9f9;
}
}

@ -1,63 +0,0 @@
<template>
<div class="auth-container">
<el-form :model="form" status-icon>
<el-form-item label="账号">
<el-input v-model="form.username" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="密码">
<el-input type="password" v-model="form.password" autocomplete="off"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="login"></el-button>
<el-button type="default" @click="register"></el-button>
</el-form-item>
</el-form>
<el-alert v-if="loginError" title="登录失败" type="error" description="用户名或密码错误" show-icon></el-alert>
</div>
</template>
<script>
import { reactive, ref } from 'vue';
import { ElMessage } from 'element-plus';
import { useRouter } from 'vue-router';
export default {
setup() {
const form = reactive({
username: '',
password: '',
});
const loginError = ref(false);
const router = useRouter();
const login = () => {
//
if (form.username === 'admin' && form.password === 'admin') {
ElMessage.success('登录成功!');
loginError.value = false;
router.push({ name: "admin" }); //
} else {
loginError.value = true;
}
};
const register = () => {
router.push({ name: "Register" });
ElMessage.success('注册');
};
return { form, login, register, loginError };
},
};
</script>
<style scoped>
.auth-container {
max-width: 400px;
margin: auto;
background-color: black; /* 设置背景颜色为黑色 */
color: white; /* 设置文本颜色为白色以便于阅读 */
padding: 20px; /* 添加一些内边距 */
border-radius: 8px; /* 使容器边角圆滑 */
}
</style>

@ -1,139 +0,0 @@
<template>
<el-form
ref="ruleFormRef"
style="max-width: 600px"
:model="ruleForm"
status-icon
:rules="rules"
label-width="auto"
class="demo-ruleForm"
>
<el-form-item label="账号" prop="username">
<el-input v-model="ruleForm.username" autocomplete="off" />
</el-form-item>
<el-form-item label="密码" prop="pass">
<el-input v-model="ruleForm.pass" type="password" autocomplete="off" />
</el-form-item>
<el-form-item label="确认密码" prop="checkPass">
<el-input
v-model="ruleForm.checkPass"
type="password"
autocomplete="off"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="submitForm(ruleFormRef)">
提交
</el-button>
<el-button @click="resetForm(ruleFormRef)"></el-button>
</el-form-item>
</el-form>
</template>
<script lang="ts" setup>
import { reactive, ref } from 'vue'
import type { FormInstance, FormRules } from 'element-plus'
import { useRouter } from 'vue-router';
//
const ruleFormRef = ref<FormInstance>()
const router = useRouter();
//
const validateUsername = (rule: any, value: any, callback: any) => {
const usernameRegex = /^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d]{8,}$/; // 8
if (!value) {
callback(new Error('请输入账号'))
} else if (!usernameRegex.test(value)) {
callback(new Error('账号必须至少8个字符并包含字母和数字'))
} else {
callback()
}
}
//
const validatePass = (rule: any, value: any, callback: any) => {
if (value === '') {
callback(new Error('请输入密码'))
} else {
if (ruleForm.checkPass !== '') {
if (!ruleFormRef.value) return
ruleFormRef.value.validateField('checkPass') //
}
callback()
}
}
//
const validatePass2 = (rule: any, value: any, callback: any) => {
if (value === '') {
callback(new Error('请再次输入密码'))
} else if (value !== ruleForm.pass) {
callback(new Error('两次输入的密码不一致'))
} else {
callback()
}
}
//
const ruleForm = reactive({
username: '',
pass: '',
checkPass: '',
})
//
const rules = reactive<FormRules<typeof ruleForm>>({
username: [{ validator: validateUsername, trigger: 'blur' }],
pass: [{ validator: validatePass, trigger: 'blur' }],
checkPass: [{ validator: validatePass2, trigger: 'blur' }],
})
//
const submitForm = (formEl: FormInstance | undefined) => {
if (!formEl) return
formEl.validate((valid) => {
if (valid) {
router.push({name:"Login"})
alert('提交成功!')
} else {
alert('提交失败!')
}
})
}
//
const resetForm = (formEl: FormInstance | undefined) => {
if (!formEl) return
formEl.resetFields()
}
</script>
<style>
.body-view{
border: 1px solid black;
width: 500px;
height: 435px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.mx-1{
font-size: 25px;
margin-bottom: 20px;
}
.ipt{
border: 1.5px solid black;
height: 50px;
}
.btn-view{
margin-left: 10px;
}
.btn{
background-color: #0f63fe;
width: 90px;
height: 40px;
}
.cancel-btn{
margin-left: 70px !important;
}
</style>

@ -1 +0,0 @@
Subproject commit b0fa7ac2b5a0478e5f12babf6889dd70b5cfeb21

@ -1,185 +0,0 @@
<template>
<div class="common-layout">
<el-container>
<el-header>
<el-row type="flex" justify="space-between" align="middle">
<!-- 菜单部分 -->
<el-col :span="18">
<el-menu
:default-active="activeIndex2"
class="el-menu-demo"
mode="horizontal"
@select="handleSelect"
background-color="#545c64"
text-color="#fff"
active-text-color="#ffd04b"
>
<el-menu-item index="1">处理中心</el-menu-item>
<el-submenu index="2">
<el-submenu index="2-4">
<template #title>信息</template>
<el-menu-item index="2-4-1">选项1</el-menu-item>
<el-menu-item index="2-4-2">选项2</el-menu-item>
<el-menu-item index="2-4-3">选项3</el-menu-item>
</el-submenu>
</el-submenu>
<el-menu-item index="3" disabled>消息中心</el-menu-item>
<el-menu-item index="4">管理</el-menu-item>
</el-menu>
</el-col>
<!-- 头像部分放在右侧 -->
<el-col :span="3" class="header-avatar">
<img src="/public/adminHead.jpg" alt="头像" class="avatar" />
</el-col>
</el-row>
</el-header>
<el-container>
<el-aside width="200px" class="el-aside">
<el-row class="tac">
<el-col>
<el-menu default-active="2" class="el-menu-vertical-demo">
<el-sub-menu index="1">
<template #title>
<el-icon>
<location />
</el-icon>
<span style="color: #cdd1d3;">编辑用户</span>
</template>
<el-menu-item-group>
<router-link to="/admin/student">
<el-menu-item index="1-1">学生</el-menu-item>
</router-link>
<router-link to="/admin/teacher">
<el-menu-item index="1-2">教师</el-menu-item>
</router-link>
</el-menu-item-group>
</el-sub-menu>
<el-sub-menu index="2">
<template #title>
<el-icon></el-icon>
<span style="color: #cdd1d3;">首页和通知</span>
</template>
<router-link to='/admin/firstpage'>
<el-menu-item index="2-1">首页</el-menu-item>
</router-link>
<el-sub-menu index="2-2">
<template #title>
<span style="color: #cdd1d3;">通知</span>
</template>
<router-link to='/admin/notice'>
<el-menu-item index="2-2-1">通知管理</el-menu-item>
</router-link>
</el-sub-menu>
</el-sub-menu>
<router-link to="/admin/myinfo">
<el-menu-item index="3">
<el-icon>
<document />
</el-icon>
<span>我的资料</span>
</el-menu-item>
</router-link>
<router-link to="/admin/information">
<el-menu-item index="4">
<el-icon><icon-menu /></el-icon>
<span>用户反馈与建议</span>
</el-menu-item>
</router-link>
</el-menu>
</el-col>
</el-row>
</el-aside>
<el-main>
<router-view></router-view>
</el-main>
</el-container>
</el-container>
</div>
</template>
<script setup>
import { ref } from 'vue'
// API
const activeIndex2 = ref('1') //
//
const handleSelect = (index) => {
console.log('选中的菜单项是:', index)
activeIndex2.value = index
}
</script>
<style>
.common-layout {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
background-color: #eff1f4;
}
.el-container {
height: 100%;
}
.el-header,
.el-footer {
background-color: #47484c;
color: #fff;
text-align: center;
line-height: 60px;
}
.header-avatar {
display: flex;
justify-content: flex-end;
align-items: center;
padding-right: 20px;
}
.avatar {
width: 40px;
height: 40px;
border-radius: 50%;
object-fit: cover;
}
.el-aside {
background-color: #2d2e36;
color: #fff;
text-align: center;
}
.el-main {
color: #333;
text-align: center;
line-height: 160px;
background-color: #cdd1d3;
}
.el-menu {
background-color: #2d2e36;
}
.el-menu-item {
color: #cdd1d3;
transition: background-color 0.3s ease, color 0.3s ease;
}
.el-menu-item:hover {
background-color: #fba414;
color: #fff;
}
.el-menu-item[disabled] {
color: #6c757d;
pointer-events: none;
}
</style>

@ -1,111 +0,0 @@
<template>
<el-row class="page">
<el-row class="block-view">
<el-row class="top">
<el-col>
<el-text class="header">个人信息</el-text>
</el-col>
</el-row>
<el-row class="express-view">
<el-row class="express-no-view" v-for="(value, label) in adminInfo" :key="label">
<el-text class="label">{{ label }}:</el-text>
<el-text class="info">{{ value }}</el-text>
</el-row>
</el-row>
</el-row>
</el-row>
</template>
<script setup>
import { ref } from 'vue';
const adminInfo = ref({
姓名: 'yyy',
账号: '123',
邮箱: 'admin@example.com',
签名: '666'
});
</script>
<style scoped>
.page {
display: flex;
flex-direction: column;
align-items: center; /* 水平居中 */
width: 100%;
min-height: 100vh; /* 保持页面高度填满视口 */
background: linear-gradient(135deg, #f4f6f9, #e9ecf3); /* 渐变背景 */
line-height: 1.8; /* 增加行高 */
padding: 30px; /* 增加内边距 */
box-sizing: border-box;
}
.block-view {
width: 100%;
max-width: 800px; /* 限制内容宽度 */
display: flex;
flex-direction: column;
padding: 30px; /* 增加内边距 */
margin: 20px 0; /* 增加上下间距 */
border-radius: 12px; /* 更大的圆角效果 */
box-shadow: 0 6px 15px rgba(0, 0, 0, 0.1); /* 更深的阴影效果 */
background-color: #fff;
}
.top {
display: flex;
flex-direction: row;
justify-content: center; /* 标题居中显示 */
padding-bottom: 15px; /* 与内容分隔 */
border-bottom: 2px solid #f0f0f0; /* 底部分隔线 */
}
.header {
font-size: 28px; /* 标题字体大小 */
font-weight: bold; /* 加粗 */
color: #333; /* 标题颜色 */
letter-spacing: 1px; /* 增加字间距 */
}
.express-view {
display: flex;
flex-direction: column;
width: 100%;
}
.express-no-view {
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between; /* 左右内容对齐 */
margin: 15px 0; /* 增加上下间距 */
padding: 15px 10px; /* 增加内边距 */
border-bottom: 1px solid #ececec; /* 底部分隔线 */
transition: all 0.3s ease; /* 添加过渡效果 */
}
.express-no-view:hover {
background-color: #f9fafc; /* 悬停时背景颜色变化 */
transform: translateY(-2px); /* 微微上移 */
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
.label {
font-weight: bold;
font-size: 18px; /* 调整字体大小 */
color: #666; /* 标签颜色 */
}
.info {
font-size: 18px; /* 调整字体大小 */
color: #333; /* 信息颜色 */
font-weight: 500; /* 字体加权 */
}
.info:hover {
color: #409eff; /* 鼠标悬停时字体颜色变化 */
text-decoration: underline; /* 悬停时增加下划线 */
}
</style>

@ -1,193 +0,0 @@
<template>
<el-row class="page">
<el-card class="block-view">
<!-- 顶部标题 -->
<el-row class="top">
<el-text><h2>学生账号管理</h2></el-text>
</el-row>
<!-- 搜索框和添加按钮 -->
<el-row class="toolbar" justify="space-between">
<el-col :span="8">
<el-input
v-model="searchQuery"
placeholder="请输入搜索的用户名"
clearable
size="medium"
@input="searchStudent"
>
<template #append>
<el-button @click="searchStudent"></el-button>
</template>
</el-input>
</el-col>
<el-button type="primary" @click="showAddDialog = true">添加用户</el-button>
<!-- 添加用户弹窗 -->
<el-dialog title="添加新用户" v-model="showAddDialog" width="500px" center>
<el-form :model="newStudent" :rules="rules" ref="studentForm" label-width="80px">
<el-form-item label="姓名" prop="name">
<el-input v-model="newStudent.name" placeholder="请输入姓名" />
</el-form-item>
<el-form-item label="邮箱" prop="email">
<el-input v-model="newStudent.email" placeholder="请输入邮箱" />
</el-form-item>
<el-form-item label="手机" prop="phone">
<el-input v-model="newStudent.phone" placeholder="请输入手机号" />
</el-form-item>
<el-form-item label="角色" prop="role">
<el-input v-model="newStudent.role" placeholder="请输入角色" />
</el-form-item>
<el-form-item label="状态" prop="status">
<el-switch v-model="newStudent.status" />
</el-form-item>
</el-form>
<!-- 弹窗底部按钮 -->
<template #footer>
<span>
<el-button @click="resetForm"></el-button>
<el-button type="primary" @click="saveStudent"></el-button>
</span>
</template>
</el-dialog>
</el-row>
<!-- 表格展示 -->
<el-table :data="filteredStudents" style="width: 100%; margin-top: 20px;" stripe>
<!-- 序号列 -->
<el-table-column type="index" label="#" width="50" align="center" />
<el-table-column prop="name" label="姓名" width="150" />
<el-table-column prop="email" label="邮箱" width="200" />
<el-table-column prop="phone" label="手机" width="180" />
<el-table-column prop="role" label="角色" width="180" />
<!-- 状态列 -->
<el-table-column label="状态" width="120" align="center">
<template #default="scope">
<el-switch
v-model="scope.row.status"
active-color="#13ce66"
inactive-color="#ff4949"
/>
</template>
</el-table-column>
<el-table-column prop="createdAt" label="创建时间" width="160" />
<!-- 操作列 -->
<el-table-column label="操作" width="200" align="center">
<template #default="scope">
<el-button
type="primary"
size="mini"
@click="editStudent(scope.row)"
>编辑</el-button>
<el-button
type="danger"
size="mini"
@click="deleteStudent(scope.row.id)"
>删除</el-button>
</template>
</el-table-column>
</el-table>
<!-- 分页 -->
<el-pagination
background
layout="total, sizes, prev, pager, next, jumper"
:total="students.length"
:page-size="10"
style="margin-top: 20px; text-align: right;"
/>
</el-card>
</el-row>
</template>
<script setup>
import { ref, computed } from 'vue';
import { ElMessage, ElMessageBox } from 'element-plus';
const students = ref([
//
{ id: 1, name: '15285', email: '14755798', phone: '185825695', role: 'ice喵喵3', status: true, createdAt: '2022-01-14' },
{ id: 2, name: 'root', email: '1060368054@qq.com', phone: '18380546544', role: 'ice喵喵3', status: false, createdAt: '2022-01-14' },
]);
const searchQuery = ref('');
const showAddDialog = ref(false); //
const studentForm = ref(); //
const newStudent = ref({ name: '', email: '', phone: '', role: '', status: true }); //
const rules = {
name: [{ required: true, message: '请输入姓名', trigger: 'blur' }],
email: [{ required: true, message: '请输入邮箱', trigger: 'blur' }],
phone: [{ required: true, message: '请输入手机号', trigger: 'blur' }],
role: [{ required: true, message: '请输入角色', trigger: 'blur' }],
};
//
const filteredStudents = computed(() => {
if (!searchQuery.value) return students.value;
return students.value.filter((student) =>
student.name.includes(searchQuery.value) || student.email.includes(searchQuery.value)
);
});
//
const saveStudent = () => {
studentForm.value.validate((valid) => {
if (valid) {
students.value.push({
...newStudent.value,
id: Date.now(),
createdAt: new Date().toISOString().split('T')[0], //
});
ElMessage.success('新用户添加成功!');
resetForm();
showAddDialog.value = false;
} else {
ElMessage.error('请填写完整的信息!');
}
});
};
//
const resetForm = () => {
studentForm.value.resetFields();
newStudent.value = { name: '', email: '', phone: '', role: '', status: true };
};
</script>
<style scoped>
.page {
padding: 20px;
background-color: #f4f6f9;
}
.block-view {
border-radius: 10px;
}
.toolbar {
display: flex;
justify-content: space-between;
margin-bottom: 10px;
}
.el-button {
margin-left: 10px;
}
</style>

@ -1,212 +0,0 @@
<template>
<el-row class="page">
<el-card class="block-view">
<!-- 顶部标题 -->
<el-row class="top">
<el-text><h2>教师账号管理</h2></el-text>
</el-row>
<!-- 搜索框和添加按钮 -->
<el-row class="toolbar" justify="space-between">
<el-col :span="8">
<el-input
v-model="searchQuery"
placeholder="请输入搜索的用户名"
clearable
size="medium"
@input="searchTeacher"
>
<template #append>
<el-button @click="searchTeacher"></el-button>
</template>
</el-input>
</el-col>
<el-button type="primary" @click="showAddDialog = true">添加用户</el-button>
<!-- 添加用户弹窗 -->
<el-dialog title="添加新用户" v-model="showAddDialog" width="500px" center>
<el-form :model="newTeacher" :rules="rules" ref="TeacherForm" label-width="80px">
<el-form-item label="姓名" prop="name">
<el-input v-model="newTeacher.name" placeholder="请输入姓名" />
</el-form-item>
<el-form-item label="邮箱" prop="email">
<el-input v-model="newTeacher.email" placeholder="请输入邮箱" />
</el-form-item>
<el-form-item label="手机" prop="phone">
<el-input v-model="newTeacher.phone" placeholder="请输入手机号" />
</el-form-item>
<el-form-item label="角色" prop="role">
<el-input v-model="newTeacher.role" placeholder="请输入角色" />
</el-form-item>
<el-form-item label="状态" prop="status">
<el-switch v-model="newTeacher.status" />
</el-form-item>
</el-form>
<!-- 弹窗底部按钮 -->
<template #footer>
<span>
<el-button @click="resetForm"></el-button>
<el-button type="primary" @click="saveTeacher"></el-button>
</span>
</template>
</el-dialog>
</el-row>
<!-- 表格展示 -->
<el-table :data="filteredTeacher" style="width: 100%; margin-top: 20px;" stripe>
<!-- 序号列 -->
<el-table-column type="index" label="#" width="50" align="center" />
<el-table-column prop="name" label="姓名" width="150" />
<el-table-column prop="email" label="邮箱" width="200" />
<el-table-column prop="phone" label="手机" width="180" />
<el-table-column prop="role" label="角色" width="180" />
<!-- 状态列 -->
<el-table-column label="状态" width="120" align="center">
<template #default="scope">
<el-switch
v-model="scope.row.status"
active-color="#13ce66"
inactive-color="#ff4949"
/>
</template>
</el-table-column>
<el-table-column prop="createdAt" label="创建时间" width="160" />
<!-- 操作列 -->
<el-table-column label="操作" width="200" align="center">
<template #default="scope">
<el-button
type="primary"
size="mini"
@click="editTeacher(scope.row)"
>编辑</el-button>
<el-button
type="danger"
size="mini"
@click="deleteTeacher(scope.row.id)"
>删除</el-button>
</template>
</el-table-column>
</el-table>
<!-- 分页 -->
<el-pagination
background
layout="total, sizes, prev, pager, next, jumper"
:total="Teacher.length"
:page-size="10"
style="margin-top: 20px; text-align: right;"
/>
</el-card>
</el-row>
</template>
<script setup>
import { ref, computed } from 'vue';
import { ElMessage, ElMessageBox } from 'element-plus';
const Teacher = ref([
//
{ id: 1, name: '15285', email: '14755798', phone: '185825695', role: 'ice喵喵3', status: true, createdAt: '2022-01-14' },
{ id: 2, name: 'root', email: '1060368054@qq.com', phone: '18380546544', role: 'ice喵喵3', status: false, createdAt: '2022-01-14' },
]);
const searchQuery = ref('');
const showAddDialog = ref(false); //
const TeacherForm = ref(); //
const newTeacher = ref({ name: '', email: '', phone: '', role: '', status: true }); //
const currentPage = ref(1);
const pageSize = ref(10);
const rules = {
name: [{ required: true, message: '请输入姓名', trigger: 'blur' }],
email: [{ required: true, message: '请输入邮箱', trigger: 'blur' }],
phone: [{ required: true, message: '请输入手机号', trigger: 'blur' }],
role: [{ required: true, message: '请输入角色', trigger: 'blur' }],
};
//
const filteredTeacher = computed(() => {
if (!searchQuery.value) return Teacher.value;
return Teacher.value.filter((item) =>
item.name.includes(searchQuery.value) || item.email.includes(searchQuery.value)
);
});
//
const saveTeacher = () => {
TeacherForm.value.validate((valid) => {
if (valid) {
Teacher.value.push({
...newTeacher.value,
id: Date.now(),
createdAt: new Date().toISOString().split('T')[0], //
});
ElMessage.success('新用户添加成功!');
resetForm();
showAddDialog.value = false;
} else {
ElMessage.error('请填写完整的信息!');
}
});
};
//
const editTeacher = (teacher) => {
newTeacher.value = { ...teacher }; //
showAddDialog.value = true; //
};
//
const deleteTeacher = (id) => {
ElMessageBox.confirm('确认删除该用户吗?', '提示', {
type: 'warning',
}).then(() => {
Teacher.value = Teacher.value.filter((item) => item.id !== id);
ElMessage.success('用户删除成功!');
});
};
//
const resetForm = () => {
TeacherForm.value.resetFields();
newTeacher.value = { name: '', email: '', phone: '', role: '', status: true };
};
</script>
<style scoped>
.page {
padding: 20px;
background-color: #f4f6f9;
}
.block-view {
border-radius: 10px;
}
.toolbar {
display: flex;
justify-content: space-between;
margin-bottom: 10px;
}
.el-button {
margin-left: 10px;
}
</style>

@ -0,0 +1,382 @@
<template>
<div style="line-height: 4;">
<el-row class="search-bar" justify="start" align="middle" >
<el-input placeholder="请输入关键词进行搜索" clearable v-model="keyword" class="search-input"
@keyup.enter="handleSearch"
suffix-icon="Search"
>
</el-input>
<el-button type="primary" @click="handleSearch"></el-button>
<el-button type="primary" @click="handleAdd">
<el-icon><CirclePlus /></el-icon>
<span>新增</span>
</el-button>
<el-button type="danger" @click="handeleBatchDel">
<el-icon><Delete /></el-icon>
<span>批量删除</span>
</el-button>
</el-row>
<el-table :data="tableData" stripe style="width: 100%" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" />
<el-table-column prop="id" label="ID" width="160" align="center" />
<el-table-column prop="username" label="用户名" width="160" align="center" />
<el-table-column prop="avatar" label="头像" align="center">
<template #default="{ row }">
<img
v-if="row.avatar"
:src="row.avatar"
alt="头像"
class="avatar-img"
/>
<span v-else></span>
</template>
</el-table-column>
<el-table-column prop="gender" label="性别" width="160" align="center" />
<el-table-column prop="email" label="邮箱" width="160" align="center" />
<el-table-column prop="address" label="地区" align="center" />
<el-table-column prop="mobile" label="手机" width="160" align="center" />
<el-table-column prop="role" label="角色" width="160" align="center" />
<el-table-column label="操作" width="160">
<template v-slot="scope">
<el-button type="success" plain @click="handleEdit(scope.row)"></el-button>
<el-button type="danger" plain @click="handleDelete(scope.row)"></el-button>
</template>
</el-table-column>
</el-table>
<div class="demo-pagination-block">
<el-pagination v-model:current-page="pageNum" v-model:page-size="pageSize" :page-sizes="[2, 4, 6, 8]"
layout="total, sizes, prev, pager, next, jumper" :total="total"
@size-change="handleSizeChange(pageSize)" @current-change="handleCurrentChange(pageNum)" />
</div>
<el-dialog v-model="isDialogVisibleAdd" title="添加用户" width="400px">
<el-form label-width="auto">
<el-upload class="avatar-uploader" action="http://localhost:8080/file/upload" :show-file-list="false"
:on-success="handleAvatarSuccess" :before-upload="beforeAvatarUpload">
<img v-if="formData.avatar" width="100px" height="100px" :src="formData.avatar" class="avatar">
<el-icon v-else class="avatar-uploader-icon">
<Plus />
</el-icon>
</el-upload>
<el-form label-width="auto" style="max-width: 600px">
<el-form-item label="用户名">
<el-input v-model="formData.username" placeholder="请输入用户名" />
</el-form-item>
<el-form-item label="密码">
<el-input v-model="formData.password" placeholder="请输入密码" show-password />
</el-form-item>
<el-form-item label="性别">
<el-radio-group v-model="formData.gender">
<el-radio label="男"></el-radio>
<el-radio label="女"></el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="邮箱">
<el-input v-model="formData.email" placeholder="请填写邮箱" />
</el-form-item>
<el-form-item label="地区">
<el-cascader :options="pcaTextArr" v-model="formData.address" placeholder="请选择地区"
:props="{ checkStrictly: true }" />
</el-form-item>
<el-form-item label="绑定手机">
<el-input v-model="formData.mobile" placeholder="请输入手机号" />
</el-form-item>
<el-form-item label="角色">
<el-radio-group v-model="formData.role">
<el-radio label="student">学生</el-radio>
<el-radio label="teacher">教师</el-radio>
</el-radio-group>
</el-form-item>
</el-form>
</el-form>
<template #footer>
<el-button @click="isDialogVisibleAdd = false">取消</el-button>
<el-button type="primary" @click="confirmAdd"></el-button>
</template>
</el-dialog>
<el-dialog v-model="isDialogVisibleEdit" title="编辑用户" width="400px">
<el-form label-width="auto">
<el-upload class="avatar-uploader" action="http://localhost:8080/file/upload" :show-file-list="false"
:on-success="handleAvatarSuccess" :before-upload="beforeAvatarUpload">
<img v-if="formData.avatar" width="100px" height="100px" :src="formData.avatar" class="avatar">
<el-icon v-else class="avatar-uploader-icon">
<Plus />
</el-icon>
</el-upload>
<el-form label-width="auto" style="max-width: 600px">
<el-form-item label="用户名">
<el-input v-model="formData.username" placeholder="请输入用户名" />
</el-form-item>
<el-form-item label="密码">
<el-input v-model="formData.password" placeholder="请输入密码" show-password />
</el-form-item>
<el-form-item label="性别">
<el-radio-group v-model="formData.gender">
<el-radio label="男"></el-radio>
<el-radio label="女"></el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="地区">
<el-cascader :options="pcaTextArr" v-model="formData.address" placeholder="请选择地区"
:props="{ checkStrictly: true }" />
</el-form-item>
<el-form-item label="绑定手机">
<el-input v-model="formData.mobile" placeholder="请输入手机号" />
</el-form-item>
<el-form-item label="角色">
<el-radio-group v-model="formData.role">
<el-radio label="user">用户</el-radio>
<el-radio label="admin">管理员</el-radio>
</el-radio-group>
</el-form-item>
</el-form>
</el-form>
<template #footer>
<el-button @click="isDialogVisibleEdit = false">取消</el-button>
<el-button type="primary" @click="confirmEdit"></el-button>
</template>
</el-dialog>
<el-dialog v-model="isDialogVisibleDelete" title="警告" width="500px" center>
<span>确定删除此用户信息吗</span>
<template #footer>
<div class="dialog-footer">
<el-button @click="isDialogVisibleDelete = false">取消</el-button>
<el-button type="primary" @click="confirmDelete()">
确定
</el-button>
</div>
</template>
</el-dialog>
<el-dialog v-model="isDialogVisibleBatchDel" title="警告" width="500px" center>
<span>确定批量删除这些用户信息吗</span>
<template #footer>
<div class="dialog-footer">
<el-button @click="isDialogVisibleBatchDel=false"></el-button>
<el-button type="primary" @click="confirmBatchDel()">
确定
</el-button>
</div>
</template>
</el-dialog>
</div>
</template>
<script lang="ts" setup>
import { reactive, ref } from 'vue';
import request from '../../request';
import { onMounted } from 'vue';
import { pcaTextArr } from 'element-china-area-data';
import { ElMessage } from 'element-plus';
const isDialogVisibleAdd = ref(false)
const isDialogVisibleEdit = ref(false)
const isDialogVisibleDelete = ref(false)
const isDialogVisibleBatchDel = ref(false)
const multipleSelection = ref([])
const tableData = ref([])
const formData = reactive({
id: '',
username: '',
password: '', gender: '',
email: '',
address: [],
mobile: '',
role: '',
avatar:'',
});
const keyword = ref('');
const pageNum = ref(1)
const pageSize = ref(6)
const total = ref(0)
const handleSearch = () => {
pageNum.value = 1; //
loadPageData();
};
const loadPageData = () => {
request.get("http://localhost:8080/user/student?pageNum=" + pageNum.value + "&pageSize=" + pageSize.value +
"&keyword=" + keyword.value)
.then((res) => {
if (res.data.code == '200') {
tableData.value = res.data.data.records;
total.value = res.data.data.total;
}
})
.catch((err) => console.error(err));
};
const handleSizeChange = (newPageSize) => {
console.log(pageSize)
pageSize.value = newPageSize
loadPageData()
}
const handleCurrentChange = (newPageNum) => {
console.log(pageNum)
pageNum.value = newPageNum
loadPageData()
}
onMounted(() => {
loadPageData();
});
const handleAdd = () => {
formData.id = '';
formData.username = '';
formData.password = '';
formData.gender = '';
formData.email = '';
formData.address = [];
formData.mobile = '';
formData.role = '';
formData.avatar='';
isDialogVisibleAdd.value = true
}
const confirmAdd = () => {
request.post('http://localhost:8080/user', {
username: formData.username,
password: formData.password,
gender:formData.gender,
email: formData.email,
address: formData.address.join(' '),
mobile: formData.mobile,
role: formData.role,
avatar:formData.avatar
})
.then((res) => {
if (res.data.code == '200') {
ElMessage.success('用户信息新增成功');
loadPageData();
} else {
ElMessage.error('用户信息新增失败');
}
})
.catch((error) => {
console.error('用户信息新增失败:', error);
ElMessage.error('用户信息新增失败,请稍后再试');
});
isDialogVisibleAdd.value = false;
}
const handleEdit = (row) => {
const { id, username, password, gender, email, address, mobile, role, avatar } = row;
formData.id = id;
formData.username = username;
formData.password = password; formData.gender = gender;
formData.email = email;
formData.address = address?address.split(' '):''; //
formData.mobile = mobile;
formData.role = role;
formData.avatar=avatar;
isDialogVisibleEdit.value = true
}
const confirmEdit = () => {
request.post("http://localhost:8080/user", {
id: formData.id,
username: formData.username,
password:formData.password,
gender: formData.gender,
email: formData.email,
address: formData.address?formData.address.join(' '):'',
mobile: formData.mobile,
role: formData.role,
avatar:formData.avatar
})
.then((res) => {
if (res.data.code == '200') {
ElMessage.success('用户信息修改成功');
loadPageData();
} else {
ElMessage.error('用户信息修改失败');
}
})
.catch((error) => {
console.error('用户信息修改失败:', error);
ElMessage.error('用户信息修改失败,请稍后再试');
});
isDialogVisibleEdit.value = false;
}
const delId = ref(-1)
const handleDelete = (row) => {
delId.value = row.id
isDialogVisibleDelete.value = true
}
const confirmDelete = () => {
request.delete(`http://localhost:8080/user/${delId.value}`).then(res => {
if (res.data.code == '200') {
ElMessage.success("删除成功")
loadPageData()
} else {
ElMessage.error("删除失败")
}
})
isDialogVisibleDelete.value = false
}
const handleSelectionChange = (val) => {
multipleSelection.value = val
}
const handeleBatchDel = () => {
isDialogVisibleBatchDel.value = true
}
const confirmBatchDel = () => {
let ids = multipleSelection.value.map(v => v.id)
if(ids.length==0){
ElMessage.error("未选择任何用户信息,删除失败")
isDialogVisibleBatchDel.value = false
return;
}
request.post("http://localhost:8080/user/del/batch", ids).then(res => {
if (res.data.code == '200') {
ElMessage.success("批量删除成功")
loadPageData()
} else {
ElMessage.error("批量删除失败")
}
})
isDialogVisibleBatchDel.value = false
}
const handleAvatarSuccess = (response) => {
if (response && response.data) {
formData.avatar = response.data;
ElMessage.success("头像上传成功");
} else {
ElMessage.error("上传失败,请联系管理员");
}
};
const beforeAvatarUpload = (file) => {
const isJPGorPNG = file.type === 'image/jpeg' || file.type === 'image/png';
const isLt2M = file.size / 1024 / 1024 < 2;
if (!isJPGorPNG) {
ElMessage.error("上传头像图片只能是 JPG/PNG 格式!");
}
if (!isLt2M) {
ElMessage.error("上传头像图片大小不能超过 2MB!");
}
return isJPGorPNG && isLt2M;
};
</script>
<style scoped>
.search-bar {
width: 100%;
padding: 20px 30px;
display: flex;
justify-content: flex-start;
align-items: center;
gap: 20px;
}
.search-input {
width: 300px;
}
.demo-pagination-block+.demo-pagination-block {
margin-top: 10px;
}
.avatar-img{
width: 100px;
height: 100px
}
</style>

@ -0,0 +1,382 @@
<template>
<div style="line-height: 4;">
<el-row class="search-bar" justify="start" align="middle" >
<el-input placeholder="请输入关键词进行搜索" clearable v-model="keyword" class="search-input"
@keyup.enter="handleSearch"
suffix-icon="Search"
>
</el-input>
<el-button type="primary" @click="handleSearch"></el-button>
<el-button type="primary" @click="handleAdd">
<el-icon><CirclePlus /></el-icon>
<span>新增</span>
</el-button>
<el-button type="danger" @click="handeleBatchDel">
<el-icon><Delete /></el-icon>
<span>批量删除</span>
</el-button>
</el-row>
<el-table :data="tableData" stripe style="width: 100%" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" />
<el-table-column prop="id" label="ID" width="160" align="center" />
<el-table-column prop="username" label="用户名" width="160" align="center" />
<el-table-column prop="avatar" label="头像" align="center">
<template #default="{ row }">
<img
v-if="row.avatar"
:src="row.avatar"
alt="头像"
class="avatar-img"
/>
<span v-else></span>
</template>
</el-table-column>
<el-table-column prop="gender" label="性别" width="160" align="center" />
<el-table-column prop="email" label="邮箱" width="160" align="center" />
<el-table-column prop="address" label="地区" align="center" />
<el-table-column prop="mobile" label="手机" width="160" align="center" />
<el-table-column prop="role" label="角色" width="160" align="center" />
<el-table-column label="操作" width="160">
<template v-slot="scope">
<el-button type="success" plain @click="handleEdit(scope.row)"></el-button>
<el-button type="danger" plain @click="handleDelete(scope.row)"></el-button>
</template>
</el-table-column>
</el-table>
<div class="demo-pagination-block">
<el-pagination v-model:current-page="pageNum" v-model:page-size="pageSize" :page-sizes="[2, 4, 6, 8]"
layout="total, sizes, prev, pager, next, jumper" :total="total"
@size-change="handleSizeChange(pageSize)" @current-change="handleCurrentChange(pageNum)" />
</div>
<el-dialog v-model="isDialogVisibleAdd" title="添加用户" width="400px">
<el-form label-width="auto">
<el-upload class="avatar-uploader" action="http://localhost:8080/file/upload" :show-file-list="false"
:on-success="handleAvatarSuccess" :before-upload="beforeAvatarUpload">
<img v-if="formData.avatar" width="100px" height="100px" :src="formData.avatar" class="avatar">
<el-icon v-else class="avatar-uploader-icon">
<Plus />
</el-icon>
</el-upload>
<el-form label-width="auto" style="max-width: 600px">
<el-form-item label="用户名">
<el-input v-model="formData.username" placeholder="请输入用户名" />
</el-form-item>
<el-form-item label="密码">
<el-input v-model="formData.password" placeholder="请输入密码" show-password />
</el-form-item>
<el-form-item label="性别">
<el-radio-group v-model="formData.gender">
<el-radio label="男"></el-radio>
<el-radio label="女"></el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="邮箱">
<el-input v-model="formData.email" placeholder="请填写邮箱" />
</el-form-item>
<el-form-item label="地区">
<el-cascader :options="pcaTextArr" v-model="formData.address" placeholder="请选择地区"
:props="{ checkStrictly: true }" />
</el-form-item>
<el-form-item label="绑定手机">
<el-input v-model="formData.mobile" placeholder="请输入手机号" />
</el-form-item>
<el-form-item label="角色">
<el-radio-group v-model="formData.role">
<el-radio label="student">学生</el-radio>
<el-radio label="teacher">教师</el-radio>
</el-radio-group>
</el-form-item>
</el-form>
</el-form>
<template #footer>
<el-button @click="isDialogVisibleAdd = false">取消</el-button>
<el-button type="primary" @click="confirmAdd"></el-button>
</template>
</el-dialog>
<el-dialog v-model="isDialogVisibleEdit" title="编辑用户" width="400px">
<el-form label-width="auto">
<el-upload class="avatar-uploader" action="http://localhost:8080/file/upload" :show-file-list="false"
:on-success="handleAvatarSuccess" :before-upload="beforeAvatarUpload">
<img v-if="formData.avatar" width="100px" height="100px" :src="formData.avatar" class="avatar">
<el-icon v-else class="avatar-uploader-icon">
<Plus />
</el-icon>
</el-upload>
<el-form label-width="auto" style="max-width: 600px">
<el-form-item label="用户名">
<el-input v-model="formData.username" placeholder="请输入用户名" />
</el-form-item>
<el-form-item label="密码">
<el-input v-model="formData.password" placeholder="请输入密码" show-password />
</el-form-item>
<el-form-item label="性别">
<el-radio-group v-model="formData.gender">
<el-radio label="男"></el-radio>
<el-radio label="女"></el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="地区">
<el-cascader :options="pcaTextArr" v-model="formData.address" placeholder="请选择地区"
:props="{ checkStrictly: true }" />
</el-form-item>
<el-form-item label="绑定手机">
<el-input v-model="formData.mobile" placeholder="请输入手机号" />
</el-form-item>
<el-form-item label="角色">
<el-radio-group v-model="formData.role">
<el-radio label="user">用户</el-radio>
<el-radio label="admin">管理员</el-radio>
</el-radio-group>
</el-form-item>
</el-form>
</el-form>
<template #footer>
<el-button @click="isDialogVisibleEdit = false">取消</el-button>
<el-button type="primary" @click="confirmEdit"></el-button>
</template>
</el-dialog>
<el-dialog v-model="isDialogVisibleDelete" title="警告" width="500px" center>
<span>确定删除此用户信息吗</span>
<template #footer>
<div class="dialog-footer">
<el-button @click="isDialogVisibleDelete = false">取消</el-button>
<el-button type="primary" @click="confirmDelete()">
确定
</el-button>
</div>
</template>
</el-dialog>
<el-dialog v-model="isDialogVisibleBatchDel" title="警告" width="500px" center>
<span>确定批量删除这些用户信息吗</span>
<template #footer>
<div class="dialog-footer">
<el-button @click="isDialogVisibleBatchDel=false"></el-button>
<el-button type="primary" @click="confirmBatchDel()">
确定
</el-button>
</div>
</template>
</el-dialog>
</div>
</template>
<script lang="ts" setup>
import { reactive, ref } from 'vue';
import request from '../../request';
import { onMounted } from 'vue';
import { pcaTextArr } from 'element-china-area-data';
import { ElMessage } from 'element-plus';
const isDialogVisibleAdd = ref(false)
const isDialogVisibleEdit = ref(false)
const isDialogVisibleDelete = ref(false)
const isDialogVisibleBatchDel = ref(false)
const multipleSelection = ref([])
const tableData = ref([])
const formData = reactive({
id: '',
username: '',
password: '', gender: '',
email: '',
address: [],
mobile: '',
role: '',
avatar:'',
});
const keyword = ref('');
const pageNum = ref(1)
const pageSize = ref(6)
const total = ref(0)
const handleSearch = () => {
pageNum.value = 1; //
loadPageData();
};
const loadPageData = () => {
request.get("http://localhost:8080/user/teacher?pageNum=" + pageNum.value + "&pageSize=" + pageSize.value +
"&keyword=" + keyword.value)
.then((res) => {
if (res.data.code == '200') {
tableData.value = res.data.data.records;
total.value = res.data.data.total;
}
})
.catch((err) => console.error(err));
};
const handleSizeChange = (newPageSize) => {
console.log(pageSize)
pageSize.value = newPageSize
loadPageData()
}
const handleCurrentChange = (newPageNum) => {
console.log(pageNum)
pageNum.value = newPageNum
loadPageData()
}
onMounted(() => {
loadPageData();
});
const handleAdd = () => {
formData.id = '';
formData.username = '';
formData.password = '';
formData.gender = '';
formData.email = '';
formData.address = [];
formData.mobile = '';
formData.role = '';
formData.avatar='';
isDialogVisibleAdd.value = true
}
const confirmAdd = () => {
request.post('http://localhost:8080/user', {
username: formData.username,
password: formData.password,
gender:formData.gender,
email: formData.email,
address: formData.address.join(' '),
mobile: formData.mobile,
role: formData.role,
avatar:formData.avatar
})
.then((res) => {
if (res.data.code == '200') {
ElMessage.success('用户信息新增成功');
loadPageData();
} else {
ElMessage.error('用户信息新增失败');
}
})
.catch((error) => {
console.error('用户信息新增失败:', error);
ElMessage.error('用户信息新增失败,请稍后再试');
});
isDialogVisibleAdd.value = false;
}
const handleEdit = (row) => {
const { id, username, password, gender, email, address, mobile, role, avatar } = row;
formData.id = id;
formData.username = username;
formData.password = password; formData.gender = gender;
formData.email = email;
formData.address = address?address.split(' '):''; //
formData.mobile = mobile;
formData.role = role;
formData.avatar=avatar;
isDialogVisibleEdit.value = true
}
const confirmEdit = () => {
request.post("http://localhost:8080/user", {
id: formData.id,
username: formData.username,
password:formData.password,
gender: formData.gender,
email: formData.email,
address: formData.address?formData.address.join(' '):'',
mobile: formData.mobile,
role: formData.role,
avatar:formData.avatar
})
.then((res) => {
if (res.data.code == '200') {
ElMessage.success('用户信息修改成功');
loadPageData();
} else {
ElMessage.error('用户信息修改失败');
}
})
.catch((error) => {
console.error('用户信息修改失败:', error);
ElMessage.error('用户信息修改失败,请稍后再试');
});
isDialogVisibleEdit.value = false;
}
const delId = ref(-1)
const handleDelete = (row) => {
delId.value = row.id
isDialogVisibleDelete.value = true
}
const confirmDelete = () => {
request.delete(`http://localhost:8080/user/${delId.value}`).then(res => {
if (res.data.code == '200') {
ElMessage.success("删除成功")
loadPageData()
} else {
ElMessage.error("删除失败")
}
})
isDialogVisibleDelete.value = false
}
const handleSelectionChange = (val) => {
multipleSelection.value = val
}
const handeleBatchDel = () => {
isDialogVisibleBatchDel.value = true
}
const confirmBatchDel = () => {
let ids = multipleSelection.value.map(v => v.id)
if(ids.length==0){
ElMessage.error("未选择任何用户信息,删除失败")
isDialogVisibleBatchDel.value = false
return;
}
request.post("http://localhost:8080/user/del/batch", ids).then(res => {
if (res.data.code == '200') {
ElMessage.success("批量删除成功")
loadPageData()
} else {
ElMessage.error("批量删除失败")
}
})
isDialogVisibleBatchDel.value = false
}
const handleAvatarSuccess = (response) => {
if (response && response.data) {
formData.avatar = response.data; //
ElMessage.success("头像上传成功");
} else {
ElMessage.error("上传失败,请联系管理员");
}
};
const beforeAvatarUpload = (file) => {
const isJPGorPNG = file.type === 'image/jpeg' || file.type === 'image/png';
const isLt2M = file.size / 1024 / 1024 < 2;
if (!isJPGorPNG) {
ElMessage.error("上传头像图片只能是 JPG/PNG 格式!");
}
if (!isLt2M) {
ElMessage.error("上传头像图片大小不能超过 2MB!");
}
return isJPGorPNG && isLt2M;
};
</script>
<style scoped>
.search-bar {
width: 100%;
padding: 20px 30px;
display: flex;
justify-content: flex-start;
align-items: center;
gap: 20px;
}
.search-input {
width: 300px;
}
.demo-pagination-block+.demo-pagination-block {
margin-top: 10px;
}
.avatar-img{
width: 100px;
height: 100px
}
</style>

@ -1,7 +0,0 @@
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [vue()],
})

@ -1,668 +0,0 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1
"@babel/helper-string-parser@^7.24.8":
version "7.24.8"
resolved "https://registry.npmmirror.com/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz"
integrity sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==
"@babel/helper-validator-identifier@^7.24.7":
version "7.24.7"
resolved "https://registry.npmmirror.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz"
integrity sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==
"@babel/parser@^7.24.7":
version "7.25.4"
resolved "https://registry.npmmirror.com/@babel/parser/-/parser-7.25.4.tgz"
integrity sha512-nq+eWrOgdtu3jG5Os4TQP3x3cLA8hR8TvJNjD8vnPa20WGycimcparWnLK4jJhElTK6SDyuJo1weMKO/5LpmLA==
dependencies:
"@babel/types" "^7.25.4"
"@babel/types@^7.25.4":
version "7.25.4"
resolved "https://registry.npmmirror.com/@babel/types/-/types-7.25.4.tgz"
integrity sha512-zQ1ijeeCXVEh+aNL0RlmkPkG8HUiDcU2pzQQFjtbntgAczRASFzj4H+6+bV+dy1ntKR14I/DypeuRG1uma98iQ==
dependencies:
"@babel/helper-string-parser" "^7.24.8"
"@babel/helper-validator-identifier" "^7.24.7"
to-fast-properties "^2.0.0"
"@ctrl/tinycolor@^3.4.1":
version "3.6.1"
resolved "https://registry.npmjs.org/@ctrl/tinycolor/-/tinycolor-3.6.1.tgz"
integrity sha512-SITSV6aIXsuVNV3f3O0f2n/cgyEDWoSqtZMYiAmcsYHydcKrOz3gUxB/iXd/Qf08+IZX4KpgNbvUdMBmWz+kcA==
"@element-plus/icons-vue@^2.3.1":
version "2.3.1"
resolved "https://registry.npmjs.org/@element-plus/icons-vue/-/icons-vue-2.3.1.tgz"
integrity sha512-XxVUZv48RZAd87ucGS48jPf6pKu0yV5UCg9f4FFwtrYxXOwWuVJo6wOvSLKEoMQKjv8GsX/mhP6UsC1lRwbUWg==
"@esbuild/aix-ppc64@0.21.5":
version "0.21.5"
resolved "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz#c7184a326533fcdf1b8ee0733e21c713b975575f"
integrity sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==
"@esbuild/android-arm64@0.21.5":
version "0.21.5"
resolved "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz#09d9b4357780da9ea3a7dfb833a1f1ff439b4052"
integrity sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==
"@esbuild/android-arm@0.21.5":
version "0.21.5"
resolved "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz#9b04384fb771926dfa6d7ad04324ecb2ab9b2e28"
integrity sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==
"@esbuild/android-x64@0.21.5":
version "0.21.5"
resolved "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz#29918ec2db754cedcb6c1b04de8cd6547af6461e"
integrity sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==
"@esbuild/darwin-arm64@0.21.5":
version "0.21.5"
resolved "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz#e495b539660e51690f3928af50a76fb0a6ccff2a"
integrity sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==
"@esbuild/darwin-x64@0.21.5":
version "0.21.5"
resolved "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz#c13838fa57372839abdddc91d71542ceea2e1e22"
integrity sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==
"@esbuild/freebsd-arm64@0.21.5":
version "0.21.5"
resolved "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz#646b989aa20bf89fd071dd5dbfad69a3542e550e"
integrity sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==
"@esbuild/freebsd-x64@0.21.5":
version "0.21.5"
resolved "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz#aa615cfc80af954d3458906e38ca22c18cf5c261"
integrity sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==
"@esbuild/linux-arm64@0.21.5":
version "0.21.5"
resolved "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz#70ac6fa14f5cb7e1f7f887bcffb680ad09922b5b"
integrity sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==
"@esbuild/linux-arm@0.21.5":
version "0.21.5"
resolved "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz#fc6fd11a8aca56c1f6f3894f2bea0479f8f626b9"
integrity sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==
"@esbuild/linux-ia32@0.21.5":
version "0.21.5"
resolved "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz#3271f53b3f93e3d093d518d1649d6d68d346ede2"
integrity sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==
"@esbuild/linux-loong64@0.21.5":
version "0.21.5"
resolved "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz#ed62e04238c57026aea831c5a130b73c0f9f26df"
integrity sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==
"@esbuild/linux-mips64el@0.21.5":
version "0.21.5"
resolved "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz#e79b8eb48bf3b106fadec1ac8240fb97b4e64cbe"
integrity sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==
"@esbuild/linux-ppc64@0.21.5":
version "0.21.5"
resolved "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz#5f2203860a143b9919d383ef7573521fb154c3e4"
integrity sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==
"@esbuild/linux-riscv64@0.21.5":
version "0.21.5"
resolved "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz#07bcafd99322d5af62f618cb9e6a9b7f4bb825dc"
integrity sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==
"@esbuild/linux-s390x@0.21.5":
version "0.21.5"
resolved "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz#b7ccf686751d6a3e44b8627ababc8be3ef62d8de"
integrity sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==
"@esbuild/linux-x64@0.21.5":
version "0.21.5"
resolved "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz#6d8f0c768e070e64309af8004bb94e68ab2bb3b0"
integrity sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==
"@esbuild/netbsd-x64@0.21.5":
version "0.21.5"
resolved "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz#bbe430f60d378ecb88decb219c602667387a6047"
integrity sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==
"@esbuild/openbsd-x64@0.21.5":
version "0.21.5"
resolved "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz#99d1cf2937279560d2104821f5ccce220cb2af70"
integrity sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==
"@esbuild/sunos-x64@0.21.5":
version "0.21.5"
resolved "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz#08741512c10d529566baba837b4fe052c8f3487b"
integrity sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==
"@esbuild/win32-arm64@0.21.5":
version "0.21.5"
resolved "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz#675b7385398411240735016144ab2e99a60fc75d"
integrity sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==
"@esbuild/win32-ia32@0.21.5":
version "0.21.5"
resolved "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz#1bfc3ce98aa6ca9a0969e4d2af72144c59c1193b"
integrity sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==
"@esbuild/win32-x64@0.21.5":
version "0.21.5"
resolved "https://registry.npmmirror.com/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz"
integrity sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==
"@floating-ui/core@^1.6.0":
version "1.6.8"
resolved "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.8.tgz"
integrity sha512-7XJ9cPU+yI2QeLS+FCSlqNFZJq8arvswefkZrYI1yQBbftw6FyrZOxYSh+9S7z7TpeWlRt9zJ5IhM1WIL334jA==
dependencies:
"@floating-ui/utils" "^0.2.8"
"@floating-ui/dom@^1.0.1":
version "1.6.12"
resolved "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.12.tgz"
integrity sha512-NP83c0HjokcGVEMeoStg317VD9W7eDlGK7457dMBANbKA6GJZdc7rjujdgqzTaz93jkGgc5P/jeWbaCHnMNc+w==
dependencies:
"@floating-ui/core" "^1.6.0"
"@floating-ui/utils" "^0.2.8"
"@floating-ui/utils@^0.2.8":
version "0.2.8"
resolved "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.8.tgz"
integrity sha512-kym7SodPp8/wloecOpcmSnWJsK7M0E5Wg8UcFA+uO4B9s5d0ywXOEro/8HM9x0rW+TljRzul/14UYz3TleT3ig==
"@jridgewell/sourcemap-codec@^1.5.0":
version "1.5.0"
resolved "https://registry.npmmirror.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz"
integrity sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==
"@popperjs/core@npm:@sxzz/popperjs-es@^2.11.7":
version "2.11.7"
resolved "https://registry.npmjs.org/@sxzz/popperjs-es/-/popperjs-es-2.11.7.tgz"
integrity sha512-Ccy0NlLkzr0Ex2FKvh2X+OyERHXJ88XJ1MXtsI9y9fGexlaXaVTPzBCRBwIxFkORuOb+uBqeu+RqnpgYTEZRUQ==
"@rollup/rollup-android-arm-eabi@4.21.1":
version "4.21.1"
resolved "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.21.1.tgz#c3a7938551273a2b72820cf5d22e54cf41dc206e"
integrity sha512-2thheikVEuU7ZxFXubPDOtspKn1x0yqaYQwvALVtEcvFhMifPADBrgRPyHV0TF3b+9BgvgjgagVyvA/UqPZHmg==
"@rollup/rollup-android-arm64@4.21.1":
version "4.21.1"
resolved "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.21.1.tgz#fa3693e4674027702c42fcbbb86bbd0c635fd3b9"
integrity sha512-t1lLYn4V9WgnIFHXy1d2Di/7gyzBWS8G5pQSXdZqfrdCGTwi1VasRMSS81DTYb+avDs/Zz4A6dzERki5oRYz1g==
"@rollup/rollup-darwin-arm64@4.21.1":
version "4.21.1"
resolved "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.21.1.tgz#e19922f4ac1e4552a230ff8f49d5688c5c07d284"
integrity sha512-AH/wNWSEEHvs6t4iJ3RANxW5ZCK3fUnmf0gyMxWCesY1AlUj8jY7GC+rQE4wd3gwmZ9XDOpL0kcFnCjtN7FXlA==
"@rollup/rollup-darwin-x64@4.21.1":
version "4.21.1"
resolved "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.21.1.tgz#897f8d47b115ea84692a29cf2366899499d4d915"
integrity sha512-dO0BIz/+5ZdkLZrVgQrDdW7m2RkrLwYTh2YMFG9IpBtlC1x1NPNSXkfczhZieOlOLEqgXOFH3wYHB7PmBtf+Bg==
"@rollup/rollup-linux-arm-gnueabihf@4.21.1":
version "4.21.1"
resolved "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.21.1.tgz#7d1e2a542f3a5744f5c24320067bd5af99ec9d62"
integrity sha512-sWWgdQ1fq+XKrlda8PsMCfut8caFwZBmhYeoehJ05FdI0YZXk6ZyUjWLrIgbR/VgiGycrFKMMgp7eJ69HOF2pQ==
"@rollup/rollup-linux-arm-musleabihf@4.21.1":
version "4.21.1"
resolved "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.21.1.tgz#88bec1c9df85fc5e24d49f783e19934717dd69b5"
integrity sha512-9OIiSuj5EsYQlmwhmFRA0LRO0dRRjdCVZA3hnmZe1rEwRk11Jy3ECGGq3a7RrVEZ0/pCsYWx8jG3IvcrJ6RCew==
"@rollup/rollup-linux-arm64-gnu@4.21.1":
version "4.21.1"
resolved "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.21.1.tgz#6dc60f0fe7bd49ed07a2d4d9eab15e671b3bd59d"
integrity sha512-0kuAkRK4MeIUbzQYu63NrJmfoUVicajoRAL1bpwdYIYRcs57iyIV9NLcuyDyDXE2GiZCL4uhKSYAnyWpjZkWow==
"@rollup/rollup-linux-arm64-musl@4.21.1":
version "4.21.1"
resolved "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.21.1.tgz#a03b78775c129e8333aca9e1e420e8e217ee99b9"
integrity sha512-/6dYC9fZtfEY0vozpc5bx1RP4VrtEOhNQGb0HwvYNwXD1BBbwQ5cKIbUVVU7G2d5WRE90NfB922elN8ASXAJEA==
"@rollup/rollup-linux-powerpc64le-gnu@4.21.1":
version "4.21.1"
resolved "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.21.1.tgz#ee3810647faf2c105a5a4e71260bb90b96bf87bc"
integrity sha512-ltUWy+sHeAh3YZ91NUsV4Xg3uBXAlscQe8ZOXRCVAKLsivGuJsrkawYPUEyCV3DYa9urgJugMLn8Z3Z/6CeyRQ==
"@rollup/rollup-linux-riscv64-gnu@4.21.1":
version "4.21.1"
resolved "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.21.1.tgz#385d76a088c27db8054d9f3f28d64d89294f838e"
integrity sha512-BggMndzI7Tlv4/abrgLwa/dxNEMn2gC61DCLrTzw8LkpSKel4o+O+gtjbnkevZ18SKkeN3ihRGPuBxjaetWzWg==
"@rollup/rollup-linux-s390x-gnu@4.21.1":
version "4.21.1"
resolved "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.21.1.tgz#daa2b62a6e6f737ebef6700a12a93c9764e18583"
integrity sha512-z/9rtlGd/OMv+gb1mNSjElasMf9yXusAxnRDrBaYB+eS1shFm6/4/xDH1SAISO5729fFKUkJ88TkGPRUh8WSAA==
"@rollup/rollup-linux-x64-gnu@4.21.1":
version "4.21.1"
resolved "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.21.1.tgz#790ae96118cc892464e9f10da358c0c8a6b9acdd"
integrity sha512-kXQVcWqDcDKw0S2E0TmhlTLlUgAmMVqPrJZR+KpH/1ZaZhLSl23GZpQVmawBQGVhyP5WXIsIQ/zqbDBBYmxm5w==
"@rollup/rollup-linux-x64-musl@4.21.1":
version "4.21.1"
resolved "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.21.1.tgz#d613147f7ac15fafe2a0b6249e8484e161ca2847"
integrity sha512-CbFv/WMQsSdl+bpX6rVbzR4kAjSSBuDgCqb1l4J68UYsQNalz5wOqLGYj4ZI0thGpyX5kc+LLZ9CL+kpqDovZA==
"@rollup/rollup-win32-arm64-msvc@4.21.1":
version "4.21.1"
resolved "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.21.1.tgz#18349db8250559a5460d59eb3575f9781be4ab98"
integrity sha512-3Q3brDgA86gHXWHklrwdREKIrIbxC0ZgU8lwpj0eEKGBQH+31uPqr0P2v11pn0tSIxHvcdOWxa4j+YvLNx1i6g==
"@rollup/rollup-win32-ia32-msvc@4.21.1":
version "4.21.1"
resolved "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.21.1.tgz#199648b68271f7ab9d023f5c077725d51d12d466"
integrity sha512-tNg+jJcKR3Uwe4L0/wY3Ro0H+u3nrb04+tcq1GSYzBEmKLeOQF2emk1whxlzNqb6MMrQ2JOcQEpuuiPLyRcSIw==
"@rollup/rollup-win32-x64-msvc@4.21.1":
version "4.21.1"
resolved "https://registry.npmmirror.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.21.1.tgz"
integrity sha512-xGiIH95H1zU7naUyTKEyOA/I0aexNMUdO9qRv0bLKN3qu25bBdrxZHqA3PTJ24YNN/GdMzG4xkDcd/GvjuhfLg==
"@types/estree@1.0.5":
version "1.0.5"
resolved "https://registry.npmmirror.com/@types/estree/-/estree-1.0.5.tgz"
integrity sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==
"@types/lodash-es@^4.17.6":
version "4.17.12"
resolved "https://registry.npmjs.org/@types/lodash-es/-/lodash-es-4.17.12.tgz"
integrity sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ==
dependencies:
"@types/lodash" "*"
"@types/lodash@*", "@types/lodash@^4.14.182":
version "4.17.13"
resolved "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.13.tgz"
integrity sha512-lfx+dftrEZcdBPczf9d0Qv0x+j/rfNCMuC6OcfXmO8gkfeNAY88PgKUbvG56whcN23gc27yenwF6oJZXGFpYxg==
"@types/web-bluetooth@^0.0.16":
version "0.0.16"
resolved "https://registry.npmjs.org/@types/web-bluetooth/-/web-bluetooth-0.0.16.tgz"
integrity sha512-oh8q2Zc32S6gd/j50GowEjKLoOVOwHP/bWVjKJInBwQqdOYMdPrf1oVlelTlyfFK3CKxL1uahMDAr+vy8T7yMQ==
"@vitejs/plugin-vue@^5.1.2":
version "5.1.2"
resolved "https://registry.npmmirror.com/@vitejs/plugin-vue/-/plugin-vue-5.1.2.tgz"
integrity sha512-nY9IwH12qeiJqumTCLJLE7IiNx7HZ39cbHaysEUd+Myvbz9KAqd2yq+U01Kab1R/H1BmiyM2ShTYlNH32Fzo3A==
"@vue/compiler-core@3.4.38":
version "3.4.38"
resolved "https://registry.npmmirror.com/@vue/compiler-core/-/compiler-core-3.4.38.tgz"
integrity sha512-8IQOTCWnLFqfHzOGm9+P8OPSEDukgg3Huc92qSG49if/xI2SAwLHQO2qaPQbjCWPBcQoO1WYfXfTACUrWV3c5A==
dependencies:
"@babel/parser" "^7.24.7"
"@vue/shared" "3.4.38"
entities "^4.5.0"
estree-walker "^2.0.2"
source-map-js "^1.2.0"
"@vue/compiler-dom@3.4.38":
version "3.4.38"
resolved "https://registry.npmmirror.com/@vue/compiler-dom/-/compiler-dom-3.4.38.tgz"
integrity sha512-Osc/c7ABsHXTsETLgykcOwIxFktHfGSUDkb05V61rocEfsFDcjDLH/IHJSNJP+/Sv9KeN2Lx1V6McZzlSb9EhQ==
dependencies:
"@vue/compiler-core" "3.4.38"
"@vue/shared" "3.4.38"
"@vue/compiler-sfc@3.4.38":
version "3.4.38"
resolved "https://registry.npmmirror.com/@vue/compiler-sfc/-/compiler-sfc-3.4.38.tgz"
integrity sha512-s5QfZ+9PzPh3T5H4hsQDJtI8x7zdJaew/dCGgqZ2630XdzaZ3AD8xGZfBqpT8oaD/p2eedd+pL8tD5vvt5ZYJQ==
dependencies:
"@babel/parser" "^7.24.7"
"@vue/compiler-core" "3.4.38"
"@vue/compiler-dom" "3.4.38"
"@vue/compiler-ssr" "3.4.38"
"@vue/shared" "3.4.38"
estree-walker "^2.0.2"
magic-string "^0.30.10"
postcss "^8.4.40"
source-map-js "^1.2.0"
"@vue/compiler-ssr@3.4.38":
version "3.4.38"
resolved "https://registry.npmmirror.com/@vue/compiler-ssr/-/compiler-ssr-3.4.38.tgz"
integrity sha512-YXznKFQ8dxYpAz9zLuVvfcXhc31FSPFDcqr0kyujbOwNhlmaNvL2QfIy+RZeJgSn5Fk54CWoEUeW+NVBAogGaw==
dependencies:
"@vue/compiler-dom" "3.4.38"
"@vue/shared" "3.4.38"
"@vue/devtools-api@^6.4.5", "@vue/devtools-api@^6.6.4":
version "6.6.4"
resolved "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.6.4.tgz#cbe97fe0162b365edc1dba80e173f90492535343"
integrity sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==
"@vue/reactivity@3.4.38":
version "3.4.38"
resolved "https://registry.npmmirror.com/@vue/reactivity/-/reactivity-3.4.38.tgz"
integrity sha512-4vl4wMMVniLsSYYeldAKzbk72+D3hUnkw9z8lDeJacTxAkXeDAP1uE9xr2+aKIN0ipOL8EG2GPouVTH6yF7Gnw==
dependencies:
"@vue/shared" "3.4.38"
"@vue/runtime-core@3.4.38":
version "3.4.38"
resolved "https://registry.npmmirror.com/@vue/runtime-core/-/runtime-core-3.4.38.tgz"
integrity sha512-21z3wA99EABtuf+O3IhdxP0iHgkBs1vuoCAsCKLVJPEjpVqvblwBnTj42vzHRlWDCyxu9ptDm7sI2ZMcWrQqlA==
dependencies:
"@vue/reactivity" "3.4.38"
"@vue/shared" "3.4.38"
"@vue/runtime-dom@3.4.38":
version "3.4.38"
resolved "https://registry.npmmirror.com/@vue/runtime-dom/-/runtime-dom-3.4.38.tgz"
integrity sha512-afZzmUreU7vKwKsV17H1NDThEEmdYI+GCAK/KY1U957Ig2NATPVjCROv61R19fjZNzMmiU03n79OMnXyJVN0UA==
dependencies:
"@vue/reactivity" "3.4.38"
"@vue/runtime-core" "3.4.38"
"@vue/shared" "3.4.38"
csstype "^3.1.3"
"@vue/server-renderer@3.4.38":
version "3.4.38"
resolved "https://registry.npmmirror.com/@vue/server-renderer/-/server-renderer-3.4.38.tgz"
integrity sha512-NggOTr82FbPEkkUvBm4fTGcwUY8UuTsnWC/L2YZBmvaQ4C4Jl/Ao4HHTB+l7WnFCt5M/dN3l0XLuyjzswGYVCA==
dependencies:
"@vue/compiler-ssr" "3.4.38"
"@vue/shared" "3.4.38"
"@vue/shared@3.4.38":
version "3.4.38"
resolved "https://registry.npmmirror.com/@vue/shared/-/shared-3.4.38.tgz"
integrity sha512-q0xCiLkuWWQLzVrecPb0RMsNWyxICOjPrcrwxTUEHb1fsnvni4dcuyG7RT/Ie7VPTvnjzIaWzRMUBsrqNj/hhw==
"@vueuse/core@^9.1.0":
version "9.13.0"
resolved "https://registry.npmjs.org/@vueuse/core/-/core-9.13.0.tgz"
integrity sha512-pujnclbeHWxxPRqXWmdkKV5OX4Wk4YeK7wusHqRwU0Q7EFusHoqNA/aPhB6KCh9hEqJkLAJo7bb0Lh9b+OIVzw==
dependencies:
"@types/web-bluetooth" "^0.0.16"
"@vueuse/metadata" "9.13.0"
"@vueuse/shared" "9.13.0"
vue-demi "*"
"@vueuse/metadata@9.13.0":
version "9.13.0"
resolved "https://registry.npmjs.org/@vueuse/metadata/-/metadata-9.13.0.tgz"
integrity sha512-gdU7TKNAUVlXXLbaF+ZCfte8BjRJQWPCa2J55+7/h+yDtzw3vOoGQDRXzI6pyKyo6bXFT5/QoPE4hAknExjRLQ==
"@vueuse/shared@9.13.0":
version "9.13.0"
resolved "https://registry.npmjs.org/@vueuse/shared/-/shared-9.13.0.tgz"
integrity sha512-UrnhU+Cnufu4S6JLCPZnkWh0WwZGUp72ktOF2DFptMlOs3TOdVv8xJN53zhHGARmVOsz5KqOls09+J1NR6sBKw==
dependencies:
vue-demi "*"
async-validator@^4.2.5:
version "4.2.5"
resolved "https://registry.npmjs.org/async-validator/-/async-validator-4.2.5.tgz"
integrity sha512-7HhHjtERjqlNbZtqNqy2rckN/SpOOlmDliet+lP7k+eKZEjPk3DgyeU9lIXLdeLz0uBbbVp+9Qdow9wJWgwwfg==
asynckit@^0.4.0:
version "0.4.0"
resolved "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==
axios@1.2.1:
version "1.2.1"
resolved "https://registry.npmjs.org/axios/-/axios-1.2.1.tgz#44cf04a3c9f0c2252ebd85975361c026cb9f864a"
integrity sha512-I88cFiGu9ryt/tfVEi4kX2SITsvDddTajXTOFmt2uK1ZVA8LytjtdeyefdQWEf5PU8w+4SSJDoYnggflB5tW4A==
dependencies:
follow-redirects "^1.15.0"
form-data "^4.0.0"
proxy-from-env "^1.1.0"
combined-stream@^1.0.8:
version "1.0.8"
resolved "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f"
integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==
dependencies:
delayed-stream "~1.0.0"
csstype@^3.1.3:
version "3.1.3"
resolved "https://registry.npmmirror.com/csstype/-/csstype-3.1.3.tgz"
integrity sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==
dayjs@^1.11.3:
version "1.11.13"
resolved "https://registry.npmjs.org/dayjs/-/dayjs-1.11.13.tgz"
integrity sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==
delayed-stream@~1.0.0:
version "1.0.0"
resolved "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==
element-plus@^2.8.7:
version "2.8.7"
resolved "https://registry.npmjs.org/element-plus/-/element-plus-2.8.7.tgz"
integrity sha512-oGQyFRufFOgjd872tZc+T4xQAYLlX4hj6d3ixeY13L4fFNUuc1N49JHAqJGPda0tdx3qCnjceZoh1kqqj2+tXQ==
dependencies:
"@ctrl/tinycolor" "^3.4.1"
"@element-plus/icons-vue" "^2.3.1"
"@floating-ui/dom" "^1.0.1"
"@popperjs/core" "npm:@sxzz/popperjs-es@^2.11.7"
"@types/lodash" "^4.14.182"
"@types/lodash-es" "^4.17.6"
"@vueuse/core" "^9.1.0"
async-validator "^4.2.5"
dayjs "^1.11.3"
escape-html "^1.0.3"
lodash "^4.17.21"
lodash-es "^4.17.21"
lodash-unified "^1.0.2"
memoize-one "^6.0.0"
normalize-wheel-es "^1.2.0"
entities@^4.5.0:
version "4.5.0"
resolved "https://registry.npmmirror.com/entities/-/entities-4.5.0.tgz"
integrity sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==
esbuild@^0.21.3:
version "0.21.5"
resolved "https://registry.npmmirror.com/esbuild/-/esbuild-0.21.5.tgz"
integrity sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==
optionalDependencies:
"@esbuild/aix-ppc64" "0.21.5"
"@esbuild/android-arm" "0.21.5"
"@esbuild/android-arm64" "0.21.5"
"@esbuild/android-x64" "0.21.5"
"@esbuild/darwin-arm64" "0.21.5"
"@esbuild/darwin-x64" "0.21.5"
"@esbuild/freebsd-arm64" "0.21.5"
"@esbuild/freebsd-x64" "0.21.5"
"@esbuild/linux-arm" "0.21.5"
"@esbuild/linux-arm64" "0.21.5"
"@esbuild/linux-ia32" "0.21.5"
"@esbuild/linux-loong64" "0.21.5"
"@esbuild/linux-mips64el" "0.21.5"
"@esbuild/linux-ppc64" "0.21.5"
"@esbuild/linux-riscv64" "0.21.5"
"@esbuild/linux-s390x" "0.21.5"
"@esbuild/linux-x64" "0.21.5"
"@esbuild/netbsd-x64" "0.21.5"
"@esbuild/openbsd-x64" "0.21.5"
"@esbuild/sunos-x64" "0.21.5"
"@esbuild/win32-arm64" "0.21.5"
"@esbuild/win32-ia32" "0.21.5"
"@esbuild/win32-x64" "0.21.5"
escape-html@^1.0.3:
version "1.0.3"
resolved "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz"
integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==
estree-walker@^2.0.2:
version "2.0.2"
resolved "https://registry.npmmirror.com/estree-walker/-/estree-walker-2.0.2.tgz"
integrity sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==
follow-redirects@^1.15.0:
version "1.15.9"
resolved "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz#a604fa10e443bf98ca94228d9eebcc2e8a2c8ee1"
integrity sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==
form-data@^4.0.0:
version "4.0.1"
resolved "https://registry.npmjs.org/form-data/-/form-data-4.0.1.tgz#ba1076daaaa5bfd7e99c1a6cb02aa0a5cff90d48"
integrity sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==
dependencies:
asynckit "^0.4.0"
combined-stream "^1.0.8"
mime-types "^2.1.12"
fsevents@~2.3.2, fsevents@~2.3.3:
version "2.3.3"
resolved "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6"
integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==
lodash-es@^4.17.21:
version "4.17.21"
resolved "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz"
integrity sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==
lodash-unified@^1.0.2:
version "1.0.3"
resolved "https://registry.npmjs.org/lodash-unified/-/lodash-unified-1.0.3.tgz"
integrity sha512-WK9qSozxXOD7ZJQlpSqOT+om2ZfcT4yO+03FuzAHD0wF6S0l0090LRPDx3vhTTLZ8cFKpBn+IOcVXK6qOcIlfQ==
lodash@^4.17.21:
version "4.17.21"
resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz"
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
magic-string@^0.30.10:
version "0.30.11"
resolved "https://registry.npmmirror.com/magic-string/-/magic-string-0.30.11.tgz"
integrity sha512-+Wri9p0QHMy+545hKww7YAu5NyzF8iomPL/RQazugQ9+Ez4Ic3mERMd8ZTX5rfK944j+560ZJi8iAwgak1Ac7A==
dependencies:
"@jridgewell/sourcemap-codec" "^1.5.0"
memoize-one@^6.0.0:
version "6.0.0"
resolved "https://registry.npmjs.org/memoize-one/-/memoize-one-6.0.0.tgz"
integrity sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==
mime-db@1.52.0:
version "1.52.0"
resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70"
integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==
mime-types@^2.1.12:
version "2.1.35"
resolved "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a"
integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==
dependencies:
mime-db "1.52.0"
nanoid@^3.3.7:
version "3.3.7"
resolved "https://registry.npmmirror.com/nanoid/-/nanoid-3.3.7.tgz"
integrity sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==
normalize-wheel-es@^1.2.0:
version "1.2.0"
resolved "https://registry.npmjs.org/normalize-wheel-es/-/normalize-wheel-es-1.2.0.tgz"
integrity sha512-Wj7+EJQ8mSuXr2iWfnujrimU35R2W4FAErEyTmJoJ7ucwTn2hOUSsRehMb5RSYkxXGTM7Y9QpvPmp++w5ftoJw==
picocolors@^1.0.1:
version "1.0.1"
resolved "https://registry.npmmirror.com/picocolors/-/picocolors-1.0.1.tgz"
integrity sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==
pinia@2.0.27:
version "2.0.27"
resolved "https://registry.npmjs.org/pinia/-/pinia-2.0.27.tgz#cf13a8dca2792a613c1d8bb8ef50707756e5a6ef"
integrity sha512-nOnXP0OFeL8R4WjAHsterU+11vptda643gH02xKNtSCDPiRzVfRYodOLihLDoa0gL1KKuQKV+KOzEgdt3YvqEw==
dependencies:
"@vue/devtools-api" "^6.4.5"
vue-demi "*"
postcss@^8.4.40, postcss@^8.4.41:
version "8.4.41"
resolved "https://registry.npmmirror.com/postcss/-/postcss-8.4.41.tgz"
integrity sha512-TesUflQ0WKZqAvg52PWL6kHgLKP6xB6heTOdoYM0Wt2UHyxNa4K25EZZMgKns3BH1RLVbZCREPpLY0rhnNoHVQ==
dependencies:
nanoid "^3.3.7"
picocolors "^1.0.1"
source-map-js "^1.2.0"
proxy-from-env@^1.1.0:
version "1.1.0"
resolved "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2"
integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==
rollup@^4.20.0:
version "4.21.1"
resolved "https://registry.npmmirror.com/rollup/-/rollup-4.21.1.tgz"
integrity sha512-ZnYyKvscThhgd3M5+Qt3pmhO4jIRR5RGzaSovB6Q7rGNrK5cUncrtLmcTTJVSdcKXyZjW8X8MB0JMSuH9bcAJg==
dependencies:
"@types/estree" "1.0.5"
optionalDependencies:
"@rollup/rollup-android-arm-eabi" "4.21.1"
"@rollup/rollup-android-arm64" "4.21.1"
"@rollup/rollup-darwin-arm64" "4.21.1"
"@rollup/rollup-darwin-x64" "4.21.1"
"@rollup/rollup-linux-arm-gnueabihf" "4.21.1"
"@rollup/rollup-linux-arm-musleabihf" "4.21.1"
"@rollup/rollup-linux-arm64-gnu" "4.21.1"
"@rollup/rollup-linux-arm64-musl" "4.21.1"
"@rollup/rollup-linux-powerpc64le-gnu" "4.21.1"
"@rollup/rollup-linux-riscv64-gnu" "4.21.1"
"@rollup/rollup-linux-s390x-gnu" "4.21.1"
"@rollup/rollup-linux-x64-gnu" "4.21.1"
"@rollup/rollup-linux-x64-musl" "4.21.1"
"@rollup/rollup-win32-arm64-msvc" "4.21.1"
"@rollup/rollup-win32-ia32-msvc" "4.21.1"
"@rollup/rollup-win32-x64-msvc" "4.21.1"
fsevents "~2.3.2"
source-map-js@^1.2.0:
version "1.2.0"
resolved "https://registry.npmmirror.com/source-map-js/-/source-map-js-1.2.0.tgz"
integrity sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==
to-fast-properties@^2.0.0:
version "2.0.0"
resolved "https://registry.npmmirror.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz"
integrity sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==
vite@^5.4.1:
version "5.4.2"
resolved "https://registry.npmmirror.com/vite/-/vite-5.4.2.tgz"
integrity sha512-dDrQTRHp5C1fTFzcSaMxjk6vdpKvT+2/mIdE07Gw2ykehT49O0z/VHS3zZ8iV/Gh8BJJKHWOe5RjaNrW5xf/GA==
dependencies:
esbuild "^0.21.3"
postcss "^8.4.41"
rollup "^4.20.0"
optionalDependencies:
fsevents "~2.3.3"
vue-demi@*:
version "0.14.10"
resolved "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.10.tgz"
integrity sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==
vue-router@4:
version "4.4.5"
resolved "https://registry.npmjs.org/vue-router/-/vue-router-4.4.5.tgz#bdf535e4cf32414ebdea6b4b403593efdb541388"
integrity sha512-4fKZygS8cH1yCyuabAXGUAsyi1b2/o/OKgu/RUb+znIYOxPRxdkytJEx+0wGcpBE1pX6vUgh5jwWOKRGvuA/7Q==
dependencies:
"@vue/devtools-api" "^6.6.4"
vue@^3.4.37:
version "3.4.38"
resolved "https://registry.npmmirror.com/vue/-/vue-3.4.38.tgz"
integrity sha512-f0ZgN+mZ5KFgVv9wz0f4OgVKukoXtS3nwET4c2vLBGQR50aI8G0cqbFtLlX9Yiyg3LFGBitruPHt2PxwTduJEw==
dependencies:
"@vue/compiler-dom" "3.4.38"
"@vue/compiler-sfc" "3.4.38"
"@vue/runtime-dom" "3.4.38"
"@vue/server-renderer" "3.4.38"
"@vue/shared" "3.4.38"
Loading…
Cancel
Save